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