]> git.saurik.com Git - wxWidgets.git/blob - src/html/m_image.cpp
No changes, just move mouse capturing bookkeeping data out of wxWindow.
[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 // Copyright: (c) 1999 Vaclav Slavik, Joel Lucsy
6 // Licence: wxWindows licence
7 /////////////////////////////////////////////////////////////////////////////
8
9 #include "wx/wxprec.h"
10
11 #ifdef __BORLANDC__
12 #pragma hdrstop
13 #endif
14
15 #if wxUSE_HTML && wxUSE_STREAMS
16
17 #ifndef WX_PRECOMP
18 #include "wx/dynarray.h"
19 #include "wx/dc.h"
20 #include "wx/scrolwin.h"
21 #include "wx/timer.h"
22 #include "wx/dcmemory.h"
23 #include "wx/log.h"
24 #include "wx/math.h"
25 #include "wx/image.h"
26 #include "wx/wxcrtvararg.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 if ( coords.GetCount() == 4 )
98 {
99 int l, t, r, b;
100
101 l = coords[ 0 ];
102 t = coords[ 1 ];
103 r = coords[ 2 ];
104 b = coords[ 3 ];
105 if (x >= l && x <= r && y >= t && y <= b)
106 {
107 return m_Link;
108 }
109 }
110 break;
111 case CIRCLE:
112 if ( coords.GetCount() == 3 )
113 {
114 int l, t, r;
115 double d;
116
117 l = coords[ 0 ];
118 t = coords[ 1 ];
119 r = coords[ 2 ];
120 d = sqrt( (double) (((x - l) * (x - l)) + ((y - t) * (y - t))) );
121 if (d < (double)r)
122 {
123 return m_Link;
124 }
125 }
126 break;
127 case POLY:
128 if (coords.GetCount() >= 6)
129 {
130 int intersects = 0;
131 int wherex = x;
132 int wherey = y;
133 int totalv = coords.GetCount() / 2;
134 int totalc = totalv * 2;
135 int xval = coords[totalc - 2];
136 int yval = coords[totalc - 1];
137 int end = totalc;
138 int pointer = 1;
139
140 if ((yval >= wherey) != (coords[pointer] >= wherey))
141 {
142 if ((xval >= wherex) == (coords[0] >= wherex))
143 {
144 intersects += (xval >= wherex) ? 1 : 0;
145 }
146 else
147 {
148 intersects += ((xval - (yval - wherey) *
149 (coords[0] - xval) /
150 (coords[pointer] - yval)) >= wherex) ? 1 : 0;
151 }
152 }
153
154 while (pointer < end)
155 {
156 yval = coords[pointer];
157 pointer += 2;
158 if (yval >= wherey)
159 {
160 while ((pointer < end) && (coords[pointer] >= wherey))
161 {
162 pointer += 2;
163 }
164 if (pointer >= end)
165 {
166 break;
167 }
168 if ((coords[pointer - 3] >= wherex) ==
169 (coords[pointer - 1] >= wherex)) {
170 intersects += (coords[pointer - 3] >= wherex) ? 1 : 0;
171 }
172 else
173 {
174 intersects +=
175 ((coords[pointer - 3] - (coords[pointer - 2] - wherey) *
176 (coords[pointer - 1] - coords[pointer - 3]) /
177 (coords[pointer] - coords[pointer - 2])) >= wherex) ? 1 : 0;
178 }
179 }
180 else
181 {
182 while ((pointer < end) && (coords[pointer] < wherey))
183 {
184 pointer += 2;
185 }
186 if (pointer >= end)
187 {
188 break;
189 }
190 if ((coords[pointer - 3] >= wherex) ==
191 (coords[pointer - 1] >= wherex))
192 {
193 intersects += (coords[pointer - 3] >= wherex) ? 1 : 0;
194 }
195 else
196 {
197 intersects +=
198 ((coords[pointer - 3] - (coords[pointer - 2] - wherey) *
199 (coords[pointer - 1] - coords[pointer - 3]) /
200 (coords[pointer] - coords[pointer - 2])) >= wherex) ? 1 : 0;
201 }
202 }
203 }
204 if ((intersects & 1) != 0)
205 {
206 return m_Link;
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
301 // If "alt" text is set, it will be used when converting this cell to text.
302 void SetAlt(const wxString& alt);
303 virtual wxString ConvertToText(wxHtmlSelection *sel) const;
304
305 #if wxUSE_GIF && wxUSE_TIMER
306 void AdvanceAnimation(wxTimer *timer);
307 virtual void Layout(int w);
308 #endif
309
310 private:
311 wxBitmap *m_bitmap;
312 int m_align;
313 int m_bmpW, m_bmpH;
314 bool m_bmpWpercent:1;
315 bool m_bmpHpresent:1;
316 bool m_showFrame:1;
317 wxHtmlWindowInterface *m_windowIface;
318 #if wxUSE_GIF && wxUSE_TIMER
319 wxGIFDecoder *m_gifDecoder;
320 wxTimer *m_gifTimer;
321 int m_physX, m_physY;
322 size_t m_nCurrFrame;
323 #endif
324 double m_scale;
325 wxHtmlImageMapCell *m_imageMap;
326 wxString m_mapName;
327 wxString m_alt;
328
329 wxDECLARE_NO_COPY_CLASS(wxHtmlImageCell);
330 };
331
332 #if wxUSE_GIF && wxUSE_TIMER
333 class wxGIFTimer : public wxTimer
334 {
335 public:
336 wxGIFTimer(wxHtmlImageCell *cell) : m_cell(cell) {}
337 virtual void Notify()
338 {
339 m_cell->AdvanceAnimation(this);
340 }
341
342 private:
343 wxHtmlImageCell *m_cell;
344
345 wxDECLARE_NO_COPY_CLASS(wxGIFTimer);
346 };
347 #endif
348
349
350 //----------------------------------------------------------------------------
351 // wxHtmlImageCell
352 //----------------------------------------------------------------------------
353
354
355 wxHtmlImageCell::wxHtmlImageCell(wxHtmlWindowInterface *windowIface,
356 wxFSFile *input,
357 int w, bool wpercent, int h, bool hpresent, double scale, int align,
358 const wxString& mapname) : wxHtmlCell()
359 {
360 m_windowIface = windowIface;
361 m_scale = scale;
362 m_showFrame = false;
363 m_bitmap = NULL;
364 m_bmpW = w;
365 m_bmpH = h;
366 m_align = align;
367 m_bmpWpercent = wpercent;
368 m_bmpHpresent = hpresent;
369 m_imageMap = NULL;
370 m_mapName = mapname;
371 SetCanLiveOnPagebreak(false);
372 #if wxUSE_GIF && wxUSE_TIMER
373 m_gifDecoder = NULL;
374 m_gifTimer = NULL;
375 m_physX = m_physY = wxDefaultCoord;
376 m_nCurrFrame = 0;
377 #endif
378
379 if ( m_bmpW && m_bmpH )
380 {
381 if ( input )
382 {
383 wxInputStream *s = input->GetStream();
384
385 if ( s )
386 {
387 #if wxUSE_GIF && wxUSE_TIMER
388 bool readImg = true;
389 if ( m_windowIface &&
390 (input->GetLocation().Matches(wxT("*.gif")) ||
391 input->GetLocation().Matches(wxT("*.GIF"))) )
392 {
393 m_gifDecoder = new wxGIFDecoder();
394 if ( m_gifDecoder->LoadGIF(*s) == wxGIF_OK )
395 {
396 wxImage img;
397 if ( m_gifDecoder->ConvertToImage(0, &img) )
398 SetImage(img);
399
400 readImg = false;
401
402 if ( m_gifDecoder->IsAnimation() )
403 {
404 m_gifTimer = new wxGIFTimer(this);
405 long delay = m_gifDecoder->GetDelay(0);
406 if ( delay == 0 )
407 delay = 1;
408 m_gifTimer->Start(delay, true);
409 }
410 else
411 {
412 wxDELETE(m_gifDecoder);
413 }
414 }
415 else
416 {
417 wxDELETE(m_gifDecoder);
418 }
419 }
420
421 if ( readImg )
422 #endif // wxUSE_GIF && wxUSE_TIMER
423 {
424 wxImage image(*s, wxBITMAP_TYPE_ANY);
425 if ( image.IsOk() )
426 SetImage(image);
427 }
428 }
429 }
430 else // input==NULL, use "broken image" bitmap
431 {
432 if ( m_bmpW == wxDefaultCoord && m_bmpH == wxDefaultCoord )
433 {
434 m_bmpW = 29;
435 m_bmpH = 31;
436 }
437 else
438 {
439 m_showFrame = true;
440 if ( m_bmpW == wxDefaultCoord ) m_bmpW = 31;
441 if ( m_bmpH == wxDefaultCoord ) m_bmpH = 33;
442 }
443 m_bitmap =
444 new wxBitmap(wxArtProvider::GetBitmap(wxART_MISSING_IMAGE));
445 }
446 }
447 //else: ignore the 0-sized images used sometimes on the Web pages
448
449 }
450
451 void wxHtmlImageCell::SetImage(const wxImage& img)
452 {
453 #if !defined(__WXMSW__) || wxUSE_WXDIB
454 if ( img.IsOk() )
455 {
456 delete m_bitmap;
457
458 int ww, hh;
459 ww = img.GetWidth();
460 hh = img.GetHeight();
461
462 if ( m_bmpW == wxDefaultCoord)
463 m_bmpW = ww;
464 if ( m_bmpH == wxDefaultCoord)
465 m_bmpH = hh;
466
467 // Only scale the bitmap at the rendering stage,
468 // so we don't lose quality twice
469 /*
470 if ((m_bmpW != ww) || (m_bmpH != hh))
471 {
472 wxImage img2 = img.Scale(m_bmpW, m_bmpH);
473 m_bitmap = new wxBitmap(img2);
474 }
475 else
476 */
477 m_bitmap = new wxBitmap(img);
478 }
479 #endif
480 }
481
482 void wxHtmlImageCell::SetAlt(const wxString& alt)
483 {
484 m_alt = alt;
485 }
486
487 wxString wxHtmlImageCell::ConvertToText(wxHtmlSelection* WXUNUSED(sel)) const
488 {
489 return m_alt;
490 }
491
492 #if wxUSE_GIF && wxUSE_TIMER
493 void wxHtmlImageCell::AdvanceAnimation(wxTimer *timer)
494 {
495 wxImage img;
496
497 // advance current frame
498 m_nCurrFrame++;
499 if (m_nCurrFrame == m_gifDecoder->GetFrameCount())
500 m_nCurrFrame = 0;
501
502 if ( m_physX == wxDefaultCoord )
503 {
504 m_physX = m_physY = 0;
505 for (wxHtmlCell *cell = this; cell; cell = cell->GetParent())
506 {
507 m_physX += cell->GetPosX();
508 m_physY += cell->GetPosY();
509 }
510 }
511
512 wxWindow *win = m_windowIface->GetHTMLWindow();
513 wxPoint pos =
514 m_windowIface->HTMLCoordsToWindow(this, wxPoint(m_physX, m_physY));
515 wxRect rect(pos, wxSize(m_Width, m_Height));
516
517 if ( win->GetClientRect().Intersects(rect) &&
518 m_gifDecoder->ConvertToImage(m_nCurrFrame, &img) )
519 {
520 #if !defined(__WXMSW__) || wxUSE_WXDIB
521 if ( m_gifDecoder->GetFrameSize(m_nCurrFrame) != wxSize(m_Width, m_Height) ||
522 m_gifDecoder->GetFramePosition(m_nCurrFrame) != wxPoint(0, 0) )
523 {
524 wxBitmap bmp(img);
525 wxMemoryDC dc;
526 dc.SelectObject(*m_bitmap);
527 dc.DrawBitmap(bmp, m_gifDecoder->GetFramePosition(m_nCurrFrame),
528 true /* use mask */);
529 }
530 else
531 #endif
532 SetImage(img);
533 win->Refresh(img.HasMask(), &rect);
534 }
535
536 long delay = m_gifDecoder->GetDelay(m_nCurrFrame);
537 if ( delay == 0 )
538 delay = 1;
539 timer->Start(delay, true);
540 }
541
542 void wxHtmlImageCell::Layout(int w)
543 {
544 if (m_bmpWpercent)
545 {
546
547 m_Width = w*m_bmpW/100;
548
549 if (!m_bmpHpresent && m_bitmap != NULL)
550 m_Height = m_bitmap->GetHeight()*m_Width/m_bitmap->GetWidth();
551 else
552 m_Height = static_cast<int>(m_scale*m_bmpH);
553 } else
554 {
555 m_Width = static_cast<int>(m_scale*m_bmpW);
556 m_Height = static_cast<int>(m_scale*m_bmpH);
557 }
558
559 switch (m_align)
560 {
561 case wxHTML_ALIGN_TOP :
562 m_Descent = m_Height;
563 break;
564 case wxHTML_ALIGN_CENTER :
565 m_Descent = m_Height / 2;
566 break;
567 case wxHTML_ALIGN_BOTTOM :
568 default :
569 m_Descent = 0;
570 break;
571 }
572
573 wxHtmlCell::Layout(w);
574 m_physX = m_physY = wxDefaultCoord;
575 }
576
577 #endif
578
579 wxHtmlImageCell::~wxHtmlImageCell()
580 {
581 delete m_bitmap;
582 #if wxUSE_GIF && wxUSE_TIMER
583 delete m_gifTimer;
584 delete m_gifDecoder;
585 #endif
586 }
587
588
589 void wxHtmlImageCell::Draw(wxDC& dc, int x, int y,
590 int WXUNUSED(view_y1), int WXUNUSED(view_y2),
591 wxHtmlRenderingInfo& WXUNUSED(info))
592 {
593 if ( m_showFrame )
594 {
595 dc.SetBrush(*wxTRANSPARENT_BRUSH);
596 dc.SetPen(*wxBLACK_PEN);
597 dc.DrawRectangle(x + m_PosX, y + m_PosY, m_Width, m_Height);
598 x++, y++;
599 }
600 if ( m_bitmap )
601 {
602 // We add in the scaling from the desired bitmap width
603 // and height, so we only do the scaling once.
604 double imageScaleX = 1.0;
605 double imageScaleY = 1.0;
606 if (m_Width != m_bitmap->GetWidth())
607 imageScaleX = (double) m_Width / (double) m_bitmap->GetWidth();
608 if (m_Height != m_bitmap->GetHeight())
609 imageScaleY = (double) m_Height / (double) m_bitmap->GetHeight();
610
611 double us_x, us_y;
612 dc.GetUserScale(&us_x, &us_y);
613 dc.SetUserScale(us_x * imageScaleX, us_y * imageScaleY);
614
615 dc.DrawBitmap(*m_bitmap, (int) ((x + m_PosX) / (imageScaleX)),
616 (int) ((y + m_PosY) / (imageScaleY)), true);
617 dc.SetUserScale(us_x, us_y);
618 }
619 }
620
621 wxHtmlLinkInfo *wxHtmlImageCell::GetLink( int x, int y ) const
622 {
623 if (m_mapName.empty())
624 return wxHtmlCell::GetLink( x, y );
625 if (!m_imageMap)
626 {
627 wxHtmlContainerCell *p, *op;
628 op = p = GetParent();
629 while (p)
630 {
631 op = p;
632 p = p->GetParent();
633 }
634 p = op;
635 wxHtmlCell *cell = (wxHtmlCell*)p->Find(wxHTML_COND_ISIMAGEMAP,
636 (const void*)(&m_mapName));
637 if (!cell)
638 {
639 ((wxString&)m_mapName).Clear();
640 return wxHtmlCell::GetLink( x, y );
641 }
642 { // dirty hack, ask Joel why he fills m_ImageMap in this place
643 // THE problem is that we're in const method and we can't modify m_ImageMap
644 wxHtmlImageMapCell **cx = (wxHtmlImageMapCell**)(&m_imageMap);
645 *cx = (wxHtmlImageMapCell*)cell;
646 }
647 }
648 return m_imageMap->GetLink(x, y);
649 }
650
651
652
653 //--------------------------------------------------------------------------------
654 // tag handler
655 //--------------------------------------------------------------------------------
656
657 TAG_HANDLER_BEGIN(IMG, "IMG,MAP,AREA")
658 TAG_HANDLER_CONSTR(IMG) { }
659
660 TAG_HANDLER_PROC(tag)
661 {
662 if (tag.GetName() == wxT("IMG"))
663 {
664 if (tag.HasParam(wxT("SRC")))
665 {
666 int w = wxDefaultCoord, h = wxDefaultCoord;
667 bool wpercent = false;
668 bool hpresent = false;
669 int al;
670 wxFSFile *str;
671 wxString tmp = tag.GetParam(wxT("SRC"));
672 wxString mn = wxEmptyString;
673
674 str = m_WParser->OpenURL(wxHTML_URL_IMAGE, tmp);
675
676 if (tag.HasParam(wxT("WIDTH")))
677 {
678 if (tag.GetParamAsIntOrPercent(wxT("WIDTH"), &w, wpercent))
679 {
680 if (wpercent)
681 {
682 if (w < 0)
683 w = 0;
684 else if (w > 100)
685 w = 100;
686 }
687 }
688 }
689
690 if (tag.HasParam(wxT("HEIGHT")))
691 {
692 tag.GetParamAsInt(wxT("HEIGHT"), &h);
693 hpresent = true;
694 }
695
696 al = wxHTML_ALIGN_BOTTOM;
697 if (tag.HasParam(wxT("ALIGN")))
698 {
699 wxString alstr = tag.GetParam(wxT("ALIGN"));
700 alstr.MakeUpper(); // for the case alignment was in ".."
701 if (alstr == wxT("TEXTTOP"))
702 al = wxHTML_ALIGN_TOP;
703 else if ((alstr == wxT("CENTER")) || (alstr == wxT("ABSCENTER")))
704 al = wxHTML_ALIGN_CENTER;
705 }
706 if (tag.HasParam(wxT("USEMAP")))
707 {
708 mn = tag.GetParam( wxT("USEMAP") );
709 if ( !mn.empty() && *mn.begin() == '#' )
710 {
711 mn = mn.Mid( 1 );
712 }
713 }
714 wxHtmlImageCell *cel = new wxHtmlImageCell(
715 m_WParser->GetWindowInterface(),
716 str, w, wpercent, h, hpresent,
717 m_WParser->GetPixelScale(),
718 al, mn);
719 m_WParser->ApplyStateToCell(cel);
720 m_WParser->StopCollapsingSpaces();
721 cel->SetId(tag.GetParam(wxT("id"))); // may be empty
722 cel->SetAlt(tag.GetParam(wxT("alt")));
723 m_WParser->GetContainer()->InsertCell(cel);
724 if (str)
725 delete str;
726 }
727 }
728 if (tag.GetName() == wxT("MAP"))
729 {
730 m_WParser->CloseContainer();
731 m_WParser->OpenContainer();
732 if (tag.HasParam(wxT("NAME")))
733 {
734 wxString tmp = tag.GetParam(wxT("NAME"));
735 wxHtmlImageMapCell *cel = new wxHtmlImageMapCell( tmp );
736 m_WParser->GetContainer()->InsertCell( cel );
737 }
738 ParseInner( tag );
739 m_WParser->CloseContainer();
740 m_WParser->OpenContainer();
741 }
742 if (tag.GetName() == wxT("AREA"))
743 {
744 if (tag.HasParam(wxT("SHAPE")))
745 {
746 wxString tmp = tag.GetParam(wxT("SHAPE"));
747 wxString coords = wxEmptyString;
748 tmp.MakeUpper();
749 wxHtmlImageMapAreaCell *cel = NULL;
750 if (tag.HasParam(wxT("COORDS")))
751 {
752 coords = tag.GetParam(wxT("COORDS"));
753 }
754 if (tmp == wxT("POLY"))
755 {
756 cel = new wxHtmlImageMapAreaCell( wxHtmlImageMapAreaCell::POLY, coords, m_WParser->GetPixelScale() );
757 }
758 else if (tmp == wxT("CIRCLE"))
759 {
760 cel = new wxHtmlImageMapAreaCell( wxHtmlImageMapAreaCell::CIRCLE, coords, m_WParser->GetPixelScale() );
761 }
762 else if (tmp == wxT("RECT"))
763 {
764 cel = new wxHtmlImageMapAreaCell( wxHtmlImageMapAreaCell::RECT, coords, m_WParser->GetPixelScale() );
765 }
766 if (cel != NULL && tag.HasParam(wxT("HREF")))
767 {
768 wxString target;
769 if (tag.HasParam(wxT("TARGET")))
770 target = tag.GetParam(wxT("TARGET"));
771 cel->SetLink(wxHtmlLinkInfo(tag.GetParam(wxT("HREF")), target));
772 }
773 if (cel != NULL)
774 m_WParser->GetContainer()->InsertCell( cel );
775 }
776 }
777
778 return false;
779 }
780
781 TAG_HANDLER_END(IMG)
782
783
784
785 TAGS_MODULE_BEGIN(Image)
786
787 TAGS_MODULE_ADD(IMG)
788
789 TAGS_MODULE_END(Image)
790
791
792 #endif