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