]> git.saurik.com Git - wxWidgets.git/blame - src/html/m_image.cpp
Some work on tabbing and menu accels,
[wxWidgets.git] / src / html / m_image.cpp
CommitLineData
5526e819
VS
1/////////////////////////////////////////////////////////////////////////////
2// Name: mod_image.cpp
3// Purpose: wxHtml module for displaying images
4// Author: Vaclav Slavik
69941f05 5// RCS-ID: $Id$
25082126 6// Copyright: (c) 1999 Vaclav Slavik, Joel Lucsy
5526e819
VS
7// Licence: wxWindows Licence
8/////////////////////////////////////////////////////////////////////////////
9
3364ab79
RS
10#ifdef __GNUG__
11#pragma implementation
12#endif
13
25082126 14#include "wx/wxprec.h"
3364ab79 15
5526e819
VS
16#include "wx/defs.h"
17#if wxUSE_HTML
18
3364ab79
RS
19#ifdef __BORDLANDC__
20#pragma hdrstop
21#endif
22
23#ifndef WXPRECOMP
25082126 24#include "wx/wx.h"
3364ab79
RS
25#endif
26
69941f05
VS
27#include "wx/html/forcelnk.h"
28#include "wx/html/m_templ.h"
5526e819 29
f42b1601 30
25082126
VS
31#include "wx/image.h"
32#include "wx/dynarray.h"
33
34#include <math.h>
35#include <float.h>
5526e819
VS
36
37FORCE_LINK_ME(mod_image)
38
39
25082126
VS
40
41
42WX_DECLARE_OBJARRAY(int, CoordArray);
43#include <wx/arrimpl.cpp> // this is a magic incantation which must be done!
44WX_DEFINE_OBJARRAY(CoordArray);
45
46
47//--------------------------------------------------------------------------------
48// wxHtmlImageMapAreaCell
49// 0-width, 0-height cell that represents single area in imagemap
50// (it's GetLink is called from wxHtmlImageCell's)
51//--------------------------------------------------------------------------------
52
53class wxHtmlImageMapAreaCell : public wxHtmlCell
54{
55public:
56 enum celltype{ CIRCLE, RECT, POLY };
57protected:
58 CoordArray coords;
59 celltype type;
60 int radius;
61public:
62 wxHtmlImageMapAreaCell( celltype t, wxString &coords );
63 virtual wxString GetLink( int x = 0, int y = 0 ) const;
64};
65
66
67
68
69
70wxHtmlImageMapAreaCell::wxHtmlImageMapAreaCell( wxHtmlImageMapAreaCell::celltype t, wxString &incoords )
71{
72 int i;
73 wxString x = incoords, y;
74
75 type = t;
76 while ((i = x.Find( ',' )) != -1)
77 {
66a77a74 78 coords.Add( wxAtoi( x.Left( i ).c_str() ) );
25082126
VS
79 x = x.Mid( i + 1 );
80 }
66a77a74 81 coords.Add( wxAtoi( x.c_str() ) );
25082126
VS
82}
83
84wxString wxHtmlImageMapAreaCell::GetLink( int x, int y ) const
85{
86 switch (type)
87 {
88 case RECT:
89 {
90 int l, t, r, b;
91
92 l = coords[ 0 ];
93 t = coords[ 1 ];
94 r = coords[ 2 ];
95 b = coords[ 3 ];
96 if (x >= l && x <= r && y >= t && y <= b)
97 {
98 return m_Link;
99 }
100 break;
101 }
102 case CIRCLE:
103 {
104 int l, t, r;
105 double d;
106
107 l = coords[ 0 ];
108 t = coords[ 1 ];
109 r = coords[ 2 ];
de87c353 110 d = sqrt( (double) (((x - l) * (x - l)) + ((y - t) * (y - t))) );
25082126
VS
111 if (d < (double)r)
112 {
113 return m_Link;
114 }
115 }
116 break;
117 case POLY:
118 {
119 if (coords.GetCount() >= 6)
120 {
121 int intersects = 0;
122 int wherex = x;
123 int wherey = y;
124 int totalv = coords.GetCount() / 2;
125 int totalc = totalv * 2;
126 int xval = coords[totalc - 2];
127 int yval = coords[totalc - 1];
128 int end = totalc;
129 int pointer = 1;
130
131 if ((yval >= wherey) != (coords[pointer] >= wherey))
132 {
133 if ((xval >= wherex) == (coords[0] >= wherex))
134 {
135 intersects += (xval >= wherex) ? 1 : 0;
136 }
137 else
138 {
139 intersects += ((xval - (yval - wherey) *
140 (coords[0] - xval) /
141 (coords[pointer] - yval)) >= wherex) ? 1 : 0;
142 }
143 }
f42b1601
RD
144
145 while (pointer < end)
25082126
VS
146 {
147 yval = coords[pointer];
148 pointer += 2;
f42b1601 149 if (yval >= wherey)
25082126
VS
150 {
151 while((pointer < end) && (coords[pointer] >= wherey))
152 {
153 pointer+=2;
154 }
155 if (pointer >= end)
156 {
157 break;
158 }
159 if ((coords[pointer-3] >= wherex) ==
160 (coords[pointer-1] >= wherex))
161 {
162 intersects += (coords[pointer-3] >= wherex) ? 1 : 0;
163 }
164 else
165 {
166 intersects +=
167 ((coords[pointer-3] - (coords[pointer-2] - wherey) *
168 (coords[pointer-1] - coords[pointer-3]) /
169 (coords[pointer] - coords[pointer - 2])) >= wherex) ? 1:0;
170 }
171 }
172 else
173 {
174 while((pointer < end) && (coords[pointer] < wherey))
175 {
176 pointer+=2;
177 }
178 if (pointer >= end)
179 {
180 break;
181 }
182 if ((coords[pointer-3] >= wherex) ==
183 (coords[pointer-1] >= wherex))
184 {
185 intersects += (coords[pointer-3] >= wherex) ? 1:0;
186 }
187 else
188 {
189 intersects +=
190 ((coords[pointer-3] - (coords[pointer-2] - wherey) *
191 (coords[pointer-1] - coords[pointer-3]) /
192 (coords[pointer] - coords[pointer - 2])) >= wherex) ? 1:0;
193 }
194 }
195 }
196 if ((intersects & 1) != 0)
197 {
198 return m_Link;
199 }
200 }
201 }
202 break;
203 }
204 if (m_Next)
205 {
206 wxHtmlImageMapAreaCell *a = (wxHtmlImageMapAreaCell*)m_Next;
207 return a->GetLink( x, y );
208 }
209 return wxEmptyString;
210}
211
212
213
214
215
216
217
218
219//--------------------------------------------------------------------------------
220// wxHtmlImageMapCell
221// 0-width, 0-height cell that represents map from imagemaps
222// it is always placed before wxHtmlImageMapAreaCells
efba2b89 223// It responds to Find(wxHTML_COND_ISIMAGEMAP)
25082126
VS
224//--------------------------------------------------------------------------------
225
226
227class wxHtmlImageMapCell : public wxHtmlCell
228{
229public:
230 wxHtmlImageMapCell( wxString &name );
231protected:
232 wxString m_Name;
233public:
234 virtual wxString GetLink( int x = 0, int y = 0 ) const;
235 virtual const wxHtmlCell *Find( int cond, const void *param ) const;
236};
237
238
239wxHtmlImageMapCell::wxHtmlImageMapCell( wxString &name )
240{
241 m_Name = name ;
242}
243
244wxString wxHtmlImageMapCell::GetLink( int x, int y ) const
245{
246 wxHtmlImageMapAreaCell *a = (wxHtmlImageMapAreaCell*)m_Next;
247 if (a)
248 return a->GetLink( x, y );
249 return wxHtmlCell::GetLink( x, y );
250}
251
252const wxHtmlCell *wxHtmlImageMapCell::Find( int cond, const void *param ) const
253{
efba2b89 254 if (cond == wxHTML_COND_ISIMAGEMAP)
25082126
VS
255 {
256 if (m_Name == *((wxString*)(param)))
257 return this;
258 }
259 return wxHtmlCell::Find(cond, param);
260}
261
262
263
264
265
5526e819
VS
266//--------------------------------------------------------------------------------
267// wxHtmlImageCell
268// Image/bitmap
269//--------------------------------------------------------------------------------
270
271class wxHtmlImageCell : public wxHtmlCell
272{
273 public:
274 wxBitmap *m_Image;
25082126
VS
275 wxHtmlImageMapCell *m_ImageMap;
276 wxString m_MapName;
5526e819 277
efba2b89 278 wxHtmlImageCell(wxFSFile *input, int w = -1, int h = -1, int align = wxHTML_ALIGN_BOTTOM, wxString mapname = wxEmptyString);
5526e819
VS
279 ~wxHtmlImageCell() {if (m_Image) delete m_Image;}
280 void Draw(wxDC& dc, int x, int y, int view_y1, int view_y2);
25082126 281 virtual wxString GetLink( int x = 0, int y = 0 ) const;
5526e819
VS
282};
283
284
285
25082126 286
5526e819
VS
287//--------------------------------------------------------------------------------
288// wxHtmlImageCell
289//--------------------------------------------------------------------------------
290
25082126 291wxHtmlImageCell::wxHtmlImageCell(wxFSFile *input, int w, int h, int align, wxString mapname) : wxHtmlCell()
5526e819
VS
292{
293 wxImage *img;
294 int ww, hh;
5526e819
VS
295 wxInputStream *s = input -> GetStream();
296
72aa4a98 297 img = new wxImage(*s, wxBITMAP_TYPE_ANY);
5526e819
VS
298
299 m_Image = NULL;
300 if (img && (img -> Ok())) {
301 ww = img -> GetWidth();
302 hh = img -> GetHeight();
303 if (w != -1) m_Width = w; else m_Width = ww;
304 if (h != -1) m_Height = h; else m_Height = hh;
305 if ((m_Width != ww) || (m_Height != hh)) {
306 wxImage img2 = img -> Scale(m_Width, m_Height);
307 m_Image = new wxBitmap(img2.ConvertToBitmap());
308 }
309 else
310 m_Image = new wxBitmap(img -> ConvertToBitmap());
311 delete img;
312 }
313 switch (align) {
efba2b89 314 case wxHTML_ALIGN_TOP :
5526e819 315 m_Descent = m_Height; break;
efba2b89 316 case wxHTML_ALIGN_CENTER :
5526e819 317 m_Descent = m_Height / 2; break;
efba2b89 318 case wxHTML_ALIGN_BOTTOM : default :
5526e819
VS
319 m_Descent = 0; break;
320 }
25082126
VS
321
322 m_ImageMap = NULL;
323 m_MapName = mapname;
db98870d 324 SetCanLiveOnPagebreak(FALSE);
5526e819
VS
325}
326
327
328
329void wxHtmlImageCell::Draw(wxDC& dc, int x, int y, int view_y1, int view_y2)
330{
331 if (m_Image)
332 dc.DrawBitmap(*m_Image, x + m_PosX, y + m_PosY, TRUE);
333 wxHtmlCell::Draw(dc, x, y, view_y1, view_y2);
334}
335
25082126
VS
336wxString wxHtmlImageCell::GetLink( int x, int y ) const
337{
338 if (m_MapName.IsEmpty())
339 return wxHtmlCell::GetLink( x, y );
340 if (!m_ImageMap)
341 {
342 wxHtmlContainerCell *p, *op;
343 op = p = GetParent();
344 while (p)
345 {
346 op = p;
347 p = p->GetParent();
348 }
349 p = op;
efba2b89 350 wxHtmlCell *cell = (wxHtmlCell*)p->Find( wxHTML_COND_ISIMAGEMAP, (const void*)(&m_MapName));
25082126
VS
351 if (!cell)
352 {
353 ((wxString&)m_MapName).Clear();
354 return wxHtmlCell::GetLink( x, y );
355 }
356 { // dirty hack, ask Joel why he fills m_ImageMap in this place
357 // THE problem is that we're in const method and we can't modify m_ImageMap
358 wxHtmlImageMapCell **cx = (wxHtmlImageMapCell**)(&m_ImageMap);
359 *cx = (wxHtmlImageMapCell*)cell;
360 }
361 }
362 return m_ImageMap->GetLink( x, y );
363}
5526e819
VS
364
365
366
367//--------------------------------------------------------------------------------
368// tag handler
369//--------------------------------------------------------------------------------
370
25082126 371TAG_HANDLER_BEGIN(IMG, "IMG, MAP, AREA")
5526e819
VS
372
373 TAG_HANDLER_PROC(tag)
374 {
25082126
VS
375 if (tag.GetName() == "IMG")
376 {
377 if (tag.HasParam("SRC")) {
378 int w = -1, h = -1;
379 int al;
380 wxFSFile *str;
381 wxString tmp = tag.GetParam("SRC");
382 wxString mn = wxEmptyString;
383
384 str = m_WParser -> GetFS() -> OpenFile(tmp);
66a77a74
OK
385 if (tag.HasParam(wxT("WIDTH"))) tag.ScanParam(wxT("WIDTH"), wxT("%i"), &w);
386 if (tag.HasParam(wxT("HEIGHT"))) tag.ScanParam(wxT("HEIGHT"), wxT("%i"), &h);
efba2b89 387 al = wxHTML_ALIGN_BOTTOM;
25082126
VS
388 if (tag.HasParam("ALIGN")) {
389 wxString alstr = tag.GetParam("ALIGN");
390 alstr.MakeUpper(); // for the case alignment was in ".."
efba2b89
VS
391 if (alstr == "TEXTTOP") al = wxHTML_ALIGN_TOP;
392 else if ((alstr == "CENTER") || (alstr == "ABSCENTER")) al = wxHTML_ALIGN_CENTER;
25082126
VS
393 }
394 if (tag.HasParam("USEMAP"))
395 {
396 mn = tag.GetParam( "USEMAP" );
397 if (mn[ 0 ] == '#')
398 {
399 mn = mn.Mid( 1 );
400 }
401 }
402 wxHtmlImageCell *cel = NULL;
403 if (str) {
404 cel = new wxHtmlImageCell(str, w, h, al, mn);
405 cel -> SetLink(m_WParser -> GetLink());
406 m_WParser -> GetContainer() -> InsertCell(cel);
407 delete str;
408 }
409 }
410 }
411 if (tag.GetName() == "MAP")
412 {
413 m_WParser->CloseContainer();
414 m_WParser->OpenContainer();
415 if (tag.HasParam("NAME"))
416 {
417 wxString tmp = tag.GetParam("NAME");
418 wxHtmlImageMapCell *cel = new wxHtmlImageMapCell( tmp );
419 m_WParser->GetContainer()->InsertCell( cel );
420 }
421 ParseInner( tag );
422 m_WParser->CloseContainer();
423 m_WParser->OpenContainer();
424 }
425 if (tag.GetName() == "AREA")
426 {
427 if (tag.HasParam("SHAPE"))
428 {
429 wxString tmp = tag.GetParam("SHAPE");
430 wxString coords;
431 tmp.MakeUpper();
432 wxHtmlImageMapAreaCell *cel = NULL;
433 if (tag.HasParam("COORDS"))
434 {
435 coords = tag.GetParam("COORDS");
436 }
437 if (tmp == "POLY")
438 {
439 cel = new wxHtmlImageMapAreaCell( wxHtmlImageMapAreaCell::POLY, coords );
440 }
441 else if (tmp == "CIRCLE")
442 {
443 cel = new wxHtmlImageMapAreaCell( wxHtmlImageMapAreaCell::CIRCLE, coords );
444 }
9b64e798 445 else if (tmp == "RECT")
25082126
VS
446 {
447 cel = new wxHtmlImageMapAreaCell( wxHtmlImageMapAreaCell::RECT, coords );
448 }
44174280 449 if (cel != NULL && tag.HasParam("HREF"))
25082126
VS
450 {
451 wxString tmp = tag.GetParam("HREF");
452 cel->SetLink( tmp );
453 }
44174280 454 if (cel != NULL) m_WParser->GetContainer()->InsertCell( cel );
25082126
VS
455 }
456 }
5526e819
VS
457
458 return FALSE;
459 }
460
461TAG_HANDLER_END(IMAGE)
462
463
464
465TAGS_MODULE_BEGIN(Image)
466
467 TAGS_MODULE_ADD(IMG)
468
469TAGS_MODULE_END(Image)
470
471
3364ab79 472#endif