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