]> git.saurik.com Git - wxWidgets.git/blame - src/html/m_image.cpp
Highly experimental, unstable code (for determining the
[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
VS
16#include "wx/defs.h"
17#if wxUSE_HTML
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;
76 while ((i = x.Find( ',' )) != -1) {
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{
01325161
VS
85 switch (type) {
86 case RECT:
87 {
edbd0635 88 int l, t, r, b;
01325161
VS
89
90 l = coords[ 0 ];
91 t = coords[ 1 ];
92 r = coords[ 2 ];
93 b = coords[ 3 ];
94 if (x >= l && x <= r && y >= t && y <= b) {
95 return m_Link;
96 }
97 break;
98 }
99 case CIRCLE:
100 {
edbd0635
VS
101 int l, t, r;
102 double d;
01325161
VS
103
104 l = coords[ 0 ];
105 t = coords[ 1 ];
106 r = coords[ 2 ];
107 d = sqrt( (double) (((x - l) * (x - l)) + ((y - t) * (y - t))) );
108 if (d < (double)r) {
109 return m_Link;
110 }
111 }
112 break;
113 case POLY:
114 {
115 if (coords.GetCount() >= 6) {
edbd0635
VS
116 int intersects = 0;
117 int wherex = x;
118 int wherey = y;
119 int totalv = coords.GetCount() / 2;
120 int totalc = totalv * 2;
121 int xval = coords[totalc - 2];
122 int yval = coords[totalc - 1];
123 int end = totalc;
124 int pointer = 1;
01325161
VS
125
126 if ((yval >= wherey) != (coords[pointer] >= wherey)) {
127 if ((xval >= wherex) == (coords[0] >= wherex)) {
128 intersects += (xval >= wherex) ? 1 : 0;
129 } else {
130 intersects += ((xval - (yval - wherey) *
131 (coords[0] - xval) /
132 (coords[pointer] - yval)) >= wherex) ? 1 : 0;
133 }
134 }
135
136 while (pointer < end) {
137 yval = coords[pointer];
138 pointer += 2;
139 if (yval >= wherey) {
140 while ((pointer < end) && (coords[pointer] >= wherey)) {
141 pointer += 2;
142 }
143 if (pointer >= end) {
144 break;
145 }
146 if ((coords[pointer - 3] >= wherex) ==
147 (coords[pointer - 1] >= wherex)) {
148 intersects += (coords[pointer - 3] >= wherex) ? 1 : 0;
149 } else {
150 intersects +=
151 ((coords[pointer - 3] - (coords[pointer - 2] - wherey) *
152 (coords[pointer - 1] - coords[pointer - 3]) /
153 (coords[pointer] - coords[pointer - 2])) >= wherex) ? 1 : 0;
154 }
155 } else {
156 while ((pointer < end) && (coords[pointer] < wherey)) {
157 pointer += 2;
158 }
159 if (pointer >= end) {
160 break;
161 }
162 if ((coords[pointer - 3] >= wherex) ==
163 (coords[pointer - 1] >= wherex)) {
164 intersects += (coords[pointer - 3] >= wherex) ? 1 : 0;
165 } else {
166 intersects +=
167 ((coords[pointer - 3] - (coords[pointer - 2] - wherey) *
168 (coords[pointer - 1] - coords[pointer - 3]) /
169 (coords[pointer] - coords[pointer - 2])) >= wherex) ? 1 : 0;
170 }
171 }
172 }
173 if ((intersects & 1) != 0) {
174 return m_Link;
175 }
176 }
177 }
178 break;
179 }
180 if (m_Next) {
edbd0635 181 wxHtmlImageMapAreaCell *a = (wxHtmlImageMapAreaCell*)m_Next;
01325161
VS
182 return a->GetLink( x, y );
183 }
846914d1 184 return NULL;
25082126
VS
185}
186
187
188
189
190
191
192
193
194//--------------------------------------------------------------------------------
195// wxHtmlImageMapCell
196// 0-width, 0-height cell that represents map from imagemaps
197// it is always placed before wxHtmlImageMapAreaCells
efba2b89 198// It responds to Find(wxHTML_COND_ISIMAGEMAP)
25082126
VS
199//--------------------------------------------------------------------------------
200
201
202class wxHtmlImageMapCell : public wxHtmlCell
203{
01325161
VS
204 public:
205 wxHtmlImageMapCell( wxString &name );
206 protected:
207 wxString m_Name;
208 public:
846914d1 209 virtual wxHtmlLinkInfo *GetLink( int x = 0, int y = 0 ) const;
01325161 210 virtual const wxHtmlCell *Find( int cond, const void *param ) const;
25082126
VS
211};
212
213
214wxHtmlImageMapCell::wxHtmlImageMapCell( wxString &name )
215{
01325161 216 m_Name = name ;
25082126
VS
217}
218
846914d1 219wxHtmlLinkInfo *wxHtmlImageMapCell::GetLink( int x, int y ) const
25082126 220{
edbd0635 221 wxHtmlImageMapAreaCell *a = (wxHtmlImageMapAreaCell*)m_Next;
01325161
VS
222 if (a)
223 return a->GetLink( x, y );
224 return wxHtmlCell::GetLink( x, y );
25082126
VS
225}
226
227const wxHtmlCell *wxHtmlImageMapCell::Find( int cond, const void *param ) const
228{
01325161
VS
229 if (cond == wxHTML_COND_ISIMAGEMAP) {
230 if (m_Name == *((wxString*)(param)))
231 return this;
232 }
233 return wxHtmlCell::Find(cond, param);
25082126
VS
234}
235
236
237
238
239
5526e819
VS
240//--------------------------------------------------------------------------------
241// wxHtmlImageCell
242// Image/bitmap
243//--------------------------------------------------------------------------------
244
245class wxHtmlImageCell : public wxHtmlCell
246{
247 public:
248 wxBitmap *m_Image;
01325161
VS
249 wxHtmlImageMapCell *m_ImageMap;
250 wxString m_MapName;
5526e819 251
37a1f3f6 252 wxHtmlImageCell(wxFSFile *input, int w = -1, int h = -1, double scale = 1.0, int align = wxHTML_ALIGN_BOTTOM, wxString mapname = wxEmptyString);
01325161 253 ~wxHtmlImageCell() {if (m_Image) delete m_Image; }
5526e819 254 void Draw(wxDC& dc, int x, int y, int view_y1, int view_y2);
846914d1 255 virtual wxHtmlLinkInfo *GetLink( int x = 0, int y = 0 ) const;
5526e819
VS
256};
257
258
259
25082126 260
5526e819
VS
261//--------------------------------------------------------------------------------
262// wxHtmlImageCell
263//--------------------------------------------------------------------------------
264
37a1f3f6 265wxHtmlImageCell::wxHtmlImageCell(wxFSFile *input, int w, int h, double scale, int align, wxString mapname) : wxHtmlCell()
5526e819
VS
266{
267 wxImage *img;
268 int ww, hh;
5526e819
VS
269 wxInputStream *s = input -> GetStream();
270
72aa4a98 271 img = new wxImage(*s, wxBITMAP_TYPE_ANY);
5526e819
VS
272
273 m_Image = NULL;
274 if (img && (img -> Ok())) {
275 ww = img -> GetWidth();
276 hh = img -> GetHeight();
277 if (w != -1) m_Width = w; else m_Width = ww;
278 if (h != -1) m_Height = h; else m_Height = hh;
37a1f3f6 279
418d9d62
VS
280 m_Width = (int)(scale * (double)m_Width);
281 m_Height = (int)(scale * (double)m_Height);
37a1f3f6 282
5526e819
VS
283 if ((m_Width != ww) || (m_Height != hh)) {
284 wxImage img2 = img -> Scale(m_Width, m_Height);
285 m_Image = new wxBitmap(img2.ConvertToBitmap());
01325161 286 } else
5526e819
VS
287 m_Image = new wxBitmap(img -> ConvertToBitmap());
288 delete img;
289 }
290 switch (align) {
efba2b89 291 case wxHTML_ALIGN_TOP :
01325161
VS
292 m_Descent = m_Height;
293 break;
efba2b89 294 case wxHTML_ALIGN_CENTER :
01325161
VS
295 m_Descent = m_Height / 2;
296 break;
297 case wxHTML_ALIGN_BOTTOM :
298 default :
299 m_Descent = 0;
300 break;
5526e819 301 }
25082126
VS
302
303 m_ImageMap = NULL;
304 m_MapName = mapname;
db98870d 305 SetCanLiveOnPagebreak(FALSE);
5526e819
VS
306}
307
308
309
310void wxHtmlImageCell::Draw(wxDC& dc, int x, int y, int view_y1, int view_y2)
311{
312 if (m_Image)
34153050
VS
313// dc.DrawBitmap(*m_Image, x + m_PosX, y + m_PosY, (m_Image->GetMask() != (wxMask*) 0));
314 dc.DrawBitmap(*m_Image, x + m_PosX, y + m_PosY, TRUE);
5526e819
VS
315 wxHtmlCell::Draw(dc, x, y, view_y1, view_y2);
316}
317
846914d1 318wxHtmlLinkInfo *wxHtmlImageCell::GetLink( int x, int y ) const
25082126 319{
01325161
VS
320 if (m_MapName.IsEmpty())
321 return wxHtmlCell::GetLink( x, y );
322 if (!m_ImageMap) {
edbd0635 323 wxHtmlContainerCell *p, *op;
01325161
VS
324 op = p = GetParent();
325 while (p) {
326 op = p;
327 p = p->GetParent();
328 }
329 p = op;
330 wxHtmlCell *cell = (wxHtmlCell*)p->Find( wxHTML_COND_ISIMAGEMAP, (const void*)(&m_MapName));
331 if (!cell) {
332 ((wxString&)m_MapName).Clear();
333 return wxHtmlCell::GetLink( x, y );
334 }
25082126 335 { // dirty hack, ask Joel why he fills m_ImageMap in this place
01325161 336 // THE problem is that we're in const method and we can't modify m_ImageMap
25082126 337 wxHtmlImageMapCell **cx = (wxHtmlImageMapCell**)(&m_ImageMap);
01325161 338 *cx = (wxHtmlImageMapCell*)cell;
25082126 339 }
01325161
VS
340 }
341 return m_ImageMap->GetLink( x, y );
25082126 342}
5526e819
VS
343
344
345
346//--------------------------------------------------------------------------------
347// tag handler
348//--------------------------------------------------------------------------------
349
01325161 350TAG_HANDLER_BEGIN(IMG, "IMG,MAP,AREA")
5526e819
VS
351
352 TAG_HANDLER_PROC(tag)
353 {
0413cec5
OK
354 if (tag.GetName() == wxT("IMG")) {
355 if (tag.HasParam(wxT("SRC"))) {
01325161
VS
356 int w = -1, h = -1;
357 int al;
358 wxFSFile *str;
0413cec5 359 wxString tmp = tag.GetParam(wxT("SRC"));
01325161
VS
360 wxString mn = wxEmptyString;
361
362 str = m_WParser -> GetFS() -> OpenFile(tmp);
363 if (tag.HasParam(wxT("WIDTH"))) tag.ScanParam(wxT("WIDTH"), wxT("%i"), &w);
364 if (tag.HasParam(wxT("HEIGHT"))) tag.ScanParam(wxT("HEIGHT"), wxT("%i"), &h);
365 al = wxHTML_ALIGN_BOTTOM;
0413cec5
OK
366 if (tag.HasParam(wxT("ALIGN"))) {
367 wxString alstr = tag.GetParam(wxT("ALIGN"));
01325161 368 alstr.MakeUpper(); // for the case alignment was in ".."
0413cec5
OK
369 if (alstr == wxT("TEXTTOP")) al = wxHTML_ALIGN_TOP;
370 else if ((alstr == wxT("CENTER")) || (alstr == wxT("ABSCENTER"))) al = wxHTML_ALIGN_CENTER;
01325161 371 }
0413cec5
OK
372 if (tag.HasParam(wxT("USEMAP"))) {
373 mn = tag.GetParam( wxT("USEMAP") );
374 if (mn[ (unsigned int) 0 ] == wxT('#')) {
01325161
VS
375 mn = mn.Mid( 1 );
376 }
377 }
378 wxHtmlImageCell *cel = NULL;
379 if (str) {
37a1f3f6 380 cel = new wxHtmlImageCell(str, w, h, m_WParser -> GetPixelScale(), al, mn);
01325161
VS
381 cel -> SetLink(m_WParser -> GetLink());
382 m_WParser -> GetContainer() -> InsertCell(cel);
383 delete str;
384 }
385 }
386 }
0413cec5 387 if (tag.GetName() == wxT("MAP")) {
01325161
VS
388 m_WParser->CloseContainer();
389 m_WParser->OpenContainer();
0413cec5
OK
390 if (tag.HasParam(wxT("NAME"))) {
391 wxString tmp = tag.GetParam(wxT("NAME"));
01325161
VS
392 wxHtmlImageMapCell *cel = new wxHtmlImageMapCell( tmp );
393 m_WParser->GetContainer()->InsertCell( cel );
394 }
395 ParseInner( tag );
396 m_WParser->CloseContainer();
397 m_WParser->OpenContainer();
398 }
0413cec5
OK
399 if (tag.GetName() == wxT("AREA")) {
400 if (tag.HasParam(wxT("SHAPE"))) {
401 wxString tmp = tag.GetParam(wxT("SHAPE"));
edbd0635 402 wxString coords = wxEmptyString;
01325161
VS
403 tmp.MakeUpper();
404 wxHtmlImageMapAreaCell *cel = NULL;
0413cec5
OK
405 if (tag.HasParam(wxT("COORDS"))) {
406 coords = tag.GetParam(wxT("COORDS"));
01325161 407 }
0413cec5 408 if (tmp == wxT("POLY")) {
edbd0635 409 cel = new wxHtmlImageMapAreaCell( wxHtmlImageMapAreaCell::POLY, coords, m_WParser -> GetPixelScale() );
0413cec5 410 } else if (tmp == wxT("CIRCLE")) {
edbd0635 411 cel = new wxHtmlImageMapAreaCell( wxHtmlImageMapAreaCell::CIRCLE, coords, m_WParser -> GetPixelScale() );
0413cec5 412 } else if (tmp == wxT("RECT")) {
edbd0635 413 cel = new wxHtmlImageMapAreaCell( wxHtmlImageMapAreaCell::RECT, coords, m_WParser -> GetPixelScale() );
01325161 414 }
0413cec5
OK
415 if (cel != NULL && tag.HasParam(wxT("HREF"))) {
416 wxString tmp = tag.GetParam(wxT("HREF"));
846914d1 417 wxString target = wxEmptyString;
0413cec5 418 if (tag.HasParam(wxT("TARGET"))) target = tag.GetParam(wxT("TARGET"));
846914d1 419 cel->SetLink( wxHtmlLinkInfo(tmp, target));
01325161
VS
420 }
421 if (cel != NULL) m_WParser->GetContainer()->InsertCell( cel );
422 }
423 }
5526e819
VS
424
425 return FALSE;
426 }
427
01325161 428TAG_HANDLER_END(IMG)
5526e819
VS
429
430
431
432TAGS_MODULE_BEGIN(Image)
433
434 TAGS_MODULE_ADD(IMG)
435
436TAGS_MODULE_END(Image)
437
438
3364ab79 439#endif