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