wxHTML: Support percentage width in IMG tag.
[wxWidgets.git] / src / html / m_image.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/html/m_image.cpp
3 // Purpose: wxHtml module for displaying images
4 // Author: Vaclav Slavik
5 // RCS-ID: $Id$
6 // Copyright: (c) 1999 Vaclav Slavik, Joel Lucsy
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
9
10 #include "wx/wxprec.h"
11
12 #ifdef __BORLANDC__
13 #pragma hdrstop
14 #endif
15
16 #if wxUSE_HTML && wxUSE_STREAMS
17
18 #ifndef WX_PRECOMP
19 #include "wx/dynarray.h"
20 #include "wx/dc.h"
21 #include "wx/scrolwin.h"
22 #include "wx/timer.h"
23 #include "wx/dcmemory.h"
24 #include "wx/log.h"
25 #include "wx/math.h"
26 #include "wx/image.h"
27 #endif
28
29 #include "wx/html/forcelnk.h"
30 #include "wx/html/m_templ.h"
31 #include "wx/html/htmlwin.h"
32
33 #include "wx/gifdecod.h"
34 #include "wx/artprov.h"
35
36 #include <float.h>
37
38 FORCE_LINK_ME(m_image)
39
40
41
42
43 WX_DECLARE_OBJARRAY(int, CoordArray);
44 #include "wx/arrimpl.cpp" // this is a magic incantation which must be done!
45 WX_DEFINE_OBJARRAY(CoordArray)
46
47
48 // ---------------------------------------------------------------------------
49 // wxHtmlImageMapAreaCell
50 // 0-width, 0-height cell that represents single area in
51 // imagemap (it's GetLink is called from wxHtmlImageCell's)
52 // ---------------------------------------------------------------------------
53
54 class wxHtmlImageMapAreaCell : public wxHtmlCell
55 {
56 public:
57 enum celltype { CIRCLE, RECT, POLY };
58 protected:
59 CoordArray coords;
60 celltype type;
61 int radius;
62 public:
63 wxHtmlImageMapAreaCell( celltype t, wxString &coords, double pixel_scale = 1.0);
64 virtual wxHtmlLinkInfo *GetLink( int x = 0, int y = 0 ) const;
65 void Draw(wxDC& WXUNUSED(dc),
66 int WXUNUSED(x), int WXUNUSED(y),
67 int WXUNUSED(view_y1), int WXUNUSED(view_y2),
68 wxHtmlRenderingInfo& WXUNUSED(info)) {}
69
70
71 wxDECLARE_NO_COPY_CLASS(wxHtmlImageMapAreaCell);
72 };
73
74
75
76
77
78 wxHtmlImageMapAreaCell::wxHtmlImageMapAreaCell( wxHtmlImageMapAreaCell::celltype t, wxString &incoords, double pixel_scale )
79 {
80 int i;
81 wxString x = incoords, y;
82
83 type = t;
84 while ((i = x.Find( ',' )) != wxNOT_FOUND)
85 {
86 coords.Add( (int)(pixel_scale * (double)wxAtoi( x.Left( i ).c_str())) );
87 x = x.Mid( i + 1 );
88 }
89 coords.Add( (int)(pixel_scale * (double)wxAtoi( x.c_str())) );
90 }
91
92 wxHtmlLinkInfo *wxHtmlImageMapAreaCell::GetLink( int x, int y ) const
93 {
94 switch (type)
95 {
96 case RECT:
97 {
98 int l, t, r, b;
99
100 l = coords[ 0 ];
101 t = coords[ 1 ];
102 r = coords[ 2 ];
103 b = coords[ 3 ];
104 if (x >= l && x <= r && y >= t && y <= b)
105 {
106 return m_Link;
107 }
108 break;
109 }
110 case CIRCLE:
111 {
112 int l, t, r;
113 double d;
114
115 l = coords[ 0 ];
116 t = coords[ 1 ];
117 r = coords[ 2 ];
118 d = sqrt( (double) (((x - l) * (x - l)) + ((y - t) * (y - t))) );
119 if (d < (double)r)
120 {
121 return m_Link;
122 }
123 }
124 break;
125 case POLY:
126 {
127 if (coords.GetCount() >= 6)
128 {
129 int intersects = 0;
130 int wherex = x;
131 int wherey = y;
132 int totalv = coords.GetCount() / 2;
133 int totalc = totalv * 2;
134 int xval = coords[totalc - 2];
135 int yval = coords[totalc - 1];
136 int end = totalc;
137 int pointer = 1;
138
139 if ((yval >= wherey) != (coords[pointer] >= wherey))
140 {
141 if ((xval >= wherex) == (coords[0] >= wherex))
142 {
143 intersects += (xval >= wherex) ? 1 : 0;
144 }
145 else
146 {
147 intersects += ((xval - (yval - wherey) *
148 (coords[0] - xval) /
149 (coords[pointer] - yval)) >= wherex) ? 1 : 0;
150 }
151 }
152
153 while (pointer < end)
154 {
155 yval = coords[pointer];
156 pointer += 2;
157 if (yval >= wherey)
158 {
159 while ((pointer < end) && (coords[pointer] >= wherey))
160 {
161 pointer += 2;
162 }
163 if (pointer >= end)
164 {
165 break;
166 }
167 if ((coords[pointer - 3] >= wherex) ==
168 (coords[pointer - 1] >= wherex)) {
169 intersects += (coords[pointer - 3] >= wherex) ? 1 : 0;
170 }
171 else
172 {
173 intersects +=
174 ((coords[pointer - 3] - (coords[pointer - 2] - wherey) *
175 (coords[pointer - 1] - coords[pointer - 3]) /
176 (coords[pointer] - coords[pointer - 2])) >= wherex) ? 1 : 0;
177 }
178 }
179 else
180 {
181 while ((pointer < end) && (coords[pointer] < wherey))
182 {
183 pointer += 2;
184 }
185 if (pointer >= end)
186 {
187 break;
188 }
189 if ((coords[pointer - 3] >= wherex) ==
190 (coords[pointer - 1] >= wherex))
191 {
192 intersects += (coords[pointer - 3] >= wherex) ? 1 : 0;
193 }
194 else
195 {
196 intersects +=
197 ((coords[pointer - 3] - (coords[pointer - 2] - wherey) *
198 (coords[pointer - 1] - coords[pointer - 3]) /
199 (coords[pointer] - coords[pointer - 2])) >= wherex) ? 1 : 0;
200 }
201 }
202 }
203 if ((intersects & 1) != 0)
204 {
205 return m_Link;
206 }
207 }
208 }
209 break;
210 }
211
212 if (m_Next)
213 {
214 wxHtmlImageMapAreaCell *a = (wxHtmlImageMapAreaCell*)m_Next;
215 return a->GetLink( x, y );
216 }
217 return NULL;
218 }
219
220
221
222
223
224
225
226
227 //--------------------------------------------------------------------------------
228 // wxHtmlImageMapCell
229 // 0-width, 0-height cell that represents map from imagemaps
230 // it is always placed before wxHtmlImageMapAreaCells
231 // It responds to Find(wxHTML_COND_ISIMAGEMAP)
232 //--------------------------------------------------------------------------------
233
234
235 class wxHtmlImageMapCell : public wxHtmlCell
236 {
237 public:
238 wxHtmlImageMapCell( wxString &name );
239 protected:
240 wxString m_Name;
241 public:
242 virtual wxHtmlLinkInfo *GetLink( int x = 0, int y = 0 ) const;
243 virtual const wxHtmlCell *Find( int cond, const void *param ) const;
244 void Draw(wxDC& WXUNUSED(dc),
245 int WXUNUSED(x), int WXUNUSED(y),
246 int WXUNUSED(view_y1), int WXUNUSED(view_y2),
247 wxHtmlRenderingInfo& WXUNUSED(info)) {}
248
249 wxDECLARE_NO_COPY_CLASS(wxHtmlImageMapCell);
250 };
251
252
253 wxHtmlImageMapCell::wxHtmlImageMapCell( wxString &name )
254 {
255 m_Name = name ;
256 }
257
258 wxHtmlLinkInfo *wxHtmlImageMapCell::GetLink( int x, int y ) const
259 {
260 wxHtmlImageMapAreaCell *a = (wxHtmlImageMapAreaCell*)m_Next;
261 if (a)
262 return a->GetLink( x, y );
263 return wxHtmlCell::GetLink( x, y );
264 }
265
266 const wxHtmlCell *wxHtmlImageMapCell::Find( int cond, const void *param ) const
267 {
268 if (cond == wxHTML_COND_ISIMAGEMAP)
269 {
270 if (m_Name == *((wxString*)(param)))
271 return this;
272 }
273 return wxHtmlCell::Find(cond, param);
274 }
275
276
277
278
279
280 //--------------------------------------------------------------------------------
281 // wxHtmlImageCell
282 // Image/bitmap
283 //--------------------------------------------------------------------------------
284
285 class wxHtmlImageCell : public wxHtmlCell
286 {
287 public:
288 wxHtmlImageCell(wxHtmlWindowInterface *windowIface,
289 wxFSFile *input,
290 int w = wxDefaultCoord, bool wpercent = false,
291 int h = wxDefaultCoord, bool hpresent = false,
292 double scale = 1.0, int align = wxHTML_ALIGN_BOTTOM,
293 const wxString& mapname = wxEmptyString);
294 virtual ~wxHtmlImageCell();
295 void Draw(wxDC& dc, int x, int y, int view_y1, int view_y2,
296 wxHtmlRenderingInfo& info);
297 virtual wxHtmlLinkInfo *GetLink(int x = 0, int y = 0) const;
298
299 void SetImage(const wxImage& img);
300 #if wxUSE_GIF && wxUSE_TIMER
301 void AdvanceAnimation(wxTimer *timer);
302 virtual void Layout(int w);
303 #endif
304
305 private:
306 wxBitmap *m_bitmap;
307 int m_align;
308 int m_bmpW, m_bmpH;
309 bool m_bmpWpercent:1;
310 bool m_bmpHpresent:1;
311 bool m_showFrame:1;
312 wxHtmlWindowInterface *m_windowIface;
313 #if wxUSE_GIF && wxUSE_TIMER
314 wxGIFDecoder *m_gifDecoder;
315 wxTimer *m_gifTimer;
316 int m_physX, m_physY;
317 size_t m_nCurrFrame;
318 #endif
319 double m_scale;
320 wxHtmlImageMapCell *m_imageMap;
321 wxString m_mapName;
322
323 wxDECLARE_NO_COPY_CLASS(wxHtmlImageCell);
324 };
325
326 #if wxUSE_GIF && wxUSE_TIMER
327 class wxGIFTimer : public wxTimer
328 {
329 public:
330 wxGIFTimer(wxHtmlImageCell *cell) : m_cell(cell) {}
331 virtual void Notify()
332 {
333 m_cell->AdvanceAnimation(this);
334 }
335
336 private:
337 wxHtmlImageCell *m_cell;
338
339 wxDECLARE_NO_COPY_CLASS(wxGIFTimer);
340 };
341 #endif
342
343
344 //----------------------------------------------------------------------------
345 // wxHtmlImageCell
346 //----------------------------------------------------------------------------
347
348
349 wxHtmlImageCell::wxHtmlImageCell(wxHtmlWindowInterface *windowIface,
350 wxFSFile *input,
351 int w, bool wpercent, int h, bool hpresent, double scale, int align,
352 const wxString& mapname) : wxHtmlCell()
353 {
354 m_windowIface = windowIface;
355 m_scale = scale;
356 m_showFrame = false;
357 m_bitmap = NULL;
358 m_bmpW = w;
359 m_bmpH = h;
360 m_align = align;
361 m_bmpWpercent = wpercent;
362 m_bmpHpresent = hpresent;
363 m_imageMap = NULL;
364 m_mapName = mapname;
365 SetCanLiveOnPagebreak(false);
366 #if wxUSE_GIF && wxUSE_TIMER
367 m_gifDecoder = NULL;
368 m_gifTimer = NULL;
369 m_physX = m_physY = wxDefaultCoord;
370 m_nCurrFrame = 0;
371 #endif
372
373 if ( m_bmpW && m_bmpH )
374 {
375 if ( input )
376 {
377 wxInputStream *s = input->GetStream();
378
379 if ( s )
380 {
381 #if wxUSE_GIF && wxUSE_TIMER
382 bool readImg = true;
383 if ( m_windowIface &&
384 (input->GetLocation().Matches(wxT("*.gif")) ||
385 input->GetLocation().Matches(wxT("*.GIF"))) )
386 {
387 m_gifDecoder = new wxGIFDecoder();
388 if ( m_gifDecoder->LoadGIF(*s) == wxGIF_OK )
389 {
390 wxImage img;
391 if ( m_gifDecoder->ConvertToImage(0, &img) )
392 SetImage(img);
393
394 readImg = false;
395
396 if ( m_gifDecoder->IsAnimation() )
397 {
398 m_gifTimer = new wxGIFTimer(this);
399 long delay = m_gifDecoder->GetDelay(0);
400 if ( delay == 0 )
401 delay = 1;
402 m_gifTimer->Start(delay, true);
403 }
404 else
405 {
406 wxDELETE(m_gifDecoder);
407 }
408 }
409 else
410 {
411 wxDELETE(m_gifDecoder);
412 }
413 }
414
415 if ( readImg )
416 #endif // wxUSE_GIF && wxUSE_TIMER
417 {
418 wxImage image(*s, wxBITMAP_TYPE_ANY);
419 if ( image.Ok() )
420 SetImage(image);
421 }
422 }
423 }
424 else // input==NULL, use "broken image" bitmap
425 {
426 if ( m_bmpW == wxDefaultCoord && m_bmpH == wxDefaultCoord )
427 {
428 m_bmpW = 29;
429 m_bmpH = 31;
430 }
431 else
432 {
433 m_showFrame = true;
434 if ( m_bmpW == wxDefaultCoord ) m_bmpW = 31;
435 if ( m_bmpH == wxDefaultCoord ) m_bmpH = 33;
436 }
437 m_bitmap =
438 new wxBitmap(wxArtProvider::GetBitmap(wxART_MISSING_IMAGE));
439 }
440 }
441 //else: ignore the 0-sized images used sometimes on the Web pages
442
443 }
444
445 void wxHtmlImageCell::SetImage(const wxImage& img)
446 {
447 #if !defined(__WXMSW__) || wxUSE_WXDIB
448 if ( img.Ok() )
449 {
450 delete m_bitmap;
451
452 int ww, hh;
453 ww = img.GetWidth();
454 hh = img.GetHeight();
455
456 if ( m_bmpW == wxDefaultCoord)
457 m_bmpW = ww;
458 if ( m_bmpH == wxDefaultCoord)
459 m_bmpH = hh;
460
461 // Only scale the bitmap at the rendering stage,
462 // so we don't lose quality twice
463 /*
464 if ((m_bmpW != ww) || (m_bmpH != hh))
465 {
466 wxImage img2 = img.Scale(m_bmpW, m_bmpH);
467 m_bitmap = new wxBitmap(img2);
468 }
469 else
470 */
471 m_bitmap = new wxBitmap(img);
472 }
473 #endif
474 }
475
476 #if wxUSE_GIF && wxUSE_TIMER
477 void wxHtmlImageCell::AdvanceAnimation(wxTimer *timer)
478 {
479 wxImage img;
480
481 // advance current frame
482 m_nCurrFrame++;
483 if (m_nCurrFrame == m_gifDecoder->GetFrameCount())
484 m_nCurrFrame = 0;
485
486 if ( m_physX == wxDefaultCoord )
487 {
488 m_physX = m_physY = 0;
489 for (wxHtmlCell *cell = this; cell; cell = cell->GetParent())
490 {
491 m_physX += cell->GetPosX();
492 m_physY += cell->GetPosY();
493 }
494 }
495
496 wxWindow *win = m_windowIface->GetHTMLWindow();
497 wxPoint pos =
498 m_windowIface->HTMLCoordsToWindow(this, wxPoint(m_physX, m_physY));
499 wxRect rect(pos, wxSize(m_Width, m_Height));
500
501 if ( win->GetClientRect().Intersects(rect) &&
502 m_gifDecoder->ConvertToImage(m_nCurrFrame, &img) )
503 {
504 #if !defined(__WXMSW__) || wxUSE_WXDIB
505 if ( m_gifDecoder->GetFrameSize(m_nCurrFrame) != wxSize(m_Width, m_Height) ||
506 m_gifDecoder->GetFramePosition(m_nCurrFrame) != wxPoint(0, 0) )
507 {
508 wxBitmap bmp(img);
509 wxMemoryDC dc;
510 dc.SelectObject(*m_bitmap);
511 dc.DrawBitmap(bmp, m_gifDecoder->GetFramePosition(m_nCurrFrame),
512 true /* use mask */);
513 }
514 else
515 #endif
516 SetImage(img);
517 win->Refresh(img.HasMask(), &rect);
518 }
519
520 long delay = m_gifDecoder->GetDelay(m_nCurrFrame);
521 if ( delay == 0 )
522 delay = 1;
523 timer->Start(delay, true);
524 }
525
526 void wxHtmlImageCell::Layout(int w)
527 {
528 if (m_bmpWpercent)
529 {
530
531 m_Width = w*m_bmpW/100;
532
533 if (!m_bmpHpresent && m_bitmap != NULL)
534 m_Height = m_bitmap->GetHeight()*m_Width/m_bitmap->GetWidth();
535 else
536 m_Height = m_scale*m_bmpH;
537 } else
538 {
539 m_Width = m_scale*m_bmpW;
540 m_Height = m_scale*m_bmpH;
541 }
542
543 switch (m_align)
544 {
545 case wxHTML_ALIGN_TOP :
546 m_Descent = m_Height;
547 break;
548 case wxHTML_ALIGN_CENTER :
549 m_Descent = m_Height / 2;
550 break;
551 case wxHTML_ALIGN_BOTTOM :
552 default :
553 m_Descent = 0;
554 break;
555 }
556
557 wxHtmlCell::Layout(w);
558 m_physX = m_physY = wxDefaultCoord;
559 }
560
561 #endif
562
563 wxHtmlImageCell::~wxHtmlImageCell()
564 {
565 delete m_bitmap;
566 #if wxUSE_GIF && wxUSE_TIMER
567 delete m_gifTimer;
568 delete m_gifDecoder;
569 #endif
570 }
571
572
573 void wxHtmlImageCell::Draw(wxDC& dc, int x, int y,
574 int WXUNUSED(view_y1), int WXUNUSED(view_y2),
575 wxHtmlRenderingInfo& WXUNUSED(info))
576 {
577 if ( m_showFrame )
578 {
579 dc.SetBrush(*wxTRANSPARENT_BRUSH);
580 dc.SetPen(*wxBLACK_PEN);
581 dc.DrawRectangle(x + m_PosX, y + m_PosY, m_Width, m_Height);
582 x++, y++;
583 }
584 if ( m_bitmap )
585 {
586 // We add in the scaling from the desired bitmap width
587 // and height, so we only do the scaling once.
588 double imageScaleX = 1.0;
589 double imageScaleY = 1.0;
590 if (m_Width != m_bitmap->GetWidth())
591 imageScaleX = (double) m_Width / (double) m_bitmap->GetWidth();
592 if (m_Height != m_bitmap->GetHeight())
593 imageScaleY = (double) m_Height / (double) m_bitmap->GetHeight();
594
595 double us_x, us_y;
596 dc.GetUserScale(&us_x, &us_y);
597 dc.SetUserScale(us_x * imageScaleX, us_y * imageScaleY);
598
599 dc.DrawBitmap(*m_bitmap, (int) ((x + m_PosX) / (imageScaleX)),
600 (int) ((y + m_PosY) / (imageScaleY)), true);
601 dc.SetUserScale(us_x, us_y);
602 }
603 }
604
605 wxHtmlLinkInfo *wxHtmlImageCell::GetLink( int x, int y ) const
606 {
607 if (m_mapName.empty())
608 return wxHtmlCell::GetLink( x, y );
609 if (!m_imageMap)
610 {
611 wxHtmlContainerCell *p, *op;
612 op = p = GetParent();
613 while (p)
614 {
615 op = p;
616 p = p->GetParent();
617 }
618 p = op;
619 wxHtmlCell *cell = (wxHtmlCell*)p->Find(wxHTML_COND_ISIMAGEMAP,
620 (const void*)(&m_mapName));
621 if (!cell)
622 {
623 ((wxString&)m_mapName).Clear();
624 return wxHtmlCell::GetLink( x, y );
625 }
626 { // dirty hack, ask Joel why he fills m_ImageMap in this place
627 // THE problem is that we're in const method and we can't modify m_ImageMap
628 wxHtmlImageMapCell **cx = (wxHtmlImageMapCell**)(&m_imageMap);
629 *cx = (wxHtmlImageMapCell*)cell;
630 }
631 }
632 return m_imageMap->GetLink(x, y);
633 }
634
635
636
637 //--------------------------------------------------------------------------------
638 // tag handler
639 //--------------------------------------------------------------------------------
640
641 TAG_HANDLER_BEGIN(IMG, "IMG,MAP,AREA")
642 TAG_HANDLER_CONSTR(IMG) { }
643
644 TAG_HANDLER_PROC(tag)
645 {
646 if (tag.GetName() == wxT("IMG"))
647 {
648 if (tag.HasParam(wxT("SRC")))
649 {
650 int w = wxDefaultCoord, h = wxDefaultCoord;
651 bool wpercent = false;
652 bool hpresent = false;
653 int al;
654 wxFSFile *str;
655 wxString tmp = tag.GetParam(wxT("SRC"));
656 wxString mn = wxEmptyString;
657
658 str = m_WParser->OpenURL(wxHTML_URL_IMAGE, tmp);
659
660 if (tag.HasParam(wxT("WIDTH")))
661 {
662 wxString param = tag.GetParam(wxT("WIDTH"));
663 wxSscanf(param.c_str(), wxT("%i"), &w);
664 if (param.EndsWith(wxT("%"))) {
665 if (w < 0)
666 w = 0;
667 else if (w > 100)
668 w = 100;
669 wpercent = true;
670 }
671
672 }
673
674 if (tag.HasParam(wxT("HEIGHT")))
675 {
676 tag.GetParamAsInt(wxT("HEIGHT"), &h);
677 hpresent = true;
678 }
679
680 al = wxHTML_ALIGN_BOTTOM;
681 if (tag.HasParam(wxT("ALIGN")))
682 {
683 wxString alstr = tag.GetParam(wxT("ALIGN"));
684 alstr.MakeUpper(); // for the case alignment was in ".."
685 if (alstr == wxT("TEXTTOP"))
686 al = wxHTML_ALIGN_TOP;
687 else if ((alstr == wxT("CENTER")) || (alstr == wxT("ABSCENTER")))
688 al = wxHTML_ALIGN_CENTER;
689 }
690 if (tag.HasParam(wxT("USEMAP")))
691 {
692 mn = tag.GetParam( wxT("USEMAP") );
693 if ( !mn.empty() && *mn.begin() == '#' )
694 {
695 mn = mn.Mid( 1 );
696 }
697 }
698 wxHtmlImageCell *cel = new wxHtmlImageCell(
699 m_WParser->GetWindowInterface(),
700 str, w, wpercent, h, hpresent,
701 m_WParser->GetPixelScale(),
702 al, mn);
703 m_WParser->ApplyStateToCell(cel);
704 cel->SetId(tag.GetParam(wxT("id"))); // may be empty
705 m_WParser->GetContainer()->InsertCell(cel);
706 if (str)
707 delete str;
708 }
709 }
710 if (tag.GetName() == wxT("MAP"))
711 {
712 m_WParser->CloseContainer();
713 m_WParser->OpenContainer();
714 if (tag.HasParam(wxT("NAME")))
715 {
716 wxString tmp = tag.GetParam(wxT("NAME"));
717 wxHtmlImageMapCell *cel = new wxHtmlImageMapCell( tmp );
718 m_WParser->GetContainer()->InsertCell( cel );
719 }
720 ParseInner( tag );
721 m_WParser->CloseContainer();
722 m_WParser->OpenContainer();
723 }
724 if (tag.GetName() == wxT("AREA"))
725 {
726 if (tag.HasParam(wxT("SHAPE")))
727 {
728 wxString tmp = tag.GetParam(wxT("SHAPE"));
729 wxString coords = wxEmptyString;
730 tmp.MakeUpper();
731 wxHtmlImageMapAreaCell *cel = NULL;
732 if (tag.HasParam(wxT("COORDS")))
733 {
734 coords = tag.GetParam(wxT("COORDS"));
735 }
736 if (tmp == wxT("POLY"))
737 {
738 cel = new wxHtmlImageMapAreaCell( wxHtmlImageMapAreaCell::POLY, coords, m_WParser->GetPixelScale() );
739 }
740 else if (tmp == wxT("CIRCLE"))
741 {
742 cel = new wxHtmlImageMapAreaCell( wxHtmlImageMapAreaCell::CIRCLE, coords, m_WParser->GetPixelScale() );
743 }
744 else if (tmp == wxT("RECT"))
745 {
746 cel = new wxHtmlImageMapAreaCell( wxHtmlImageMapAreaCell::RECT, coords, m_WParser->GetPixelScale() );
747 }
748 if (cel != NULL && tag.HasParam(wxT("HREF")))
749 {
750 wxString target;
751 if (tag.HasParam(wxT("TARGET")))
752 target = tag.GetParam(wxT("TARGET"));
753 cel->SetLink(wxHtmlLinkInfo(tag.GetParam(wxT("HREF")), target));
754 }
755 if (cel != NULL)
756 m_WParser->GetContainer()->InsertCell( cel );
757 }
758 }
759
760 return false;
761 }
762
763 TAG_HANDLER_END(IMG)
764
765
766
767 TAGS_MODULE_BEGIN(Image)
768
769 TAGS_MODULE_ADD(IMG)
770
771 TAGS_MODULE_END(Image)
772
773
774 #endif