]>
Commit | Line | Data |
---|---|---|
6a2c1874 RR |
1 | ///////////////////////////////////////////////////////////////////////////// |
2 | // Name: canvas.cpp | |
3 | // Author: Robert Roebling | |
4 | // Created: XX/XX/XX | |
5 | // Copyright: 2000 (c) Robert Roebling | |
6 | // Licence: wxWindows Licence | |
7 | ///////////////////////////////////////////////////////////////////////////// | |
8 | ||
9 | #ifdef __GNUG__ | |
10 | #pragma implementation "canvas.cpp" | |
11 | #endif | |
12 | ||
13 | // For compilers that support precompilation, includes "wx/wx.h". | |
14 | #include "wx/wxprec.h" | |
15 | ||
16 | #ifdef __BORLANDC__ | |
17 | #pragma hdrstop | |
18 | #endif | |
19 | ||
20 | #include "wx/canvas/canvas.h" | |
21 | ||
22 | #ifdef __WXGTK__ | |
23 | #include <gtk/gtk.h> | |
24 | #include <gdk/gdkrgb.h> | |
25 | #include "wx/gtk/win_gtk.h" | |
26 | #endif | |
27 | ||
1e1af41e RR |
28 | #ifndef wxUSE_FREETYPE |
29 | #define wxUSE_FREETYPE 1 | |
30 | #endif | |
d1f9b206 | 31 | |
1e1af41e RR |
32 | #if wxUSE_FREETYPE |
33 | #include <freetype/freetype.h> | |
d1f9b206 RR |
34 | #endif |
35 | ||
36 | //---------------------------------------------------------------------------- | |
37 | // globals | |
38 | //---------------------------------------------------------------------------- | |
39 | ||
1e1af41e | 40 | #if wxUSE_FREETYPE |
d1f9b206 RR |
41 | FT_Library g_freetypeLibrary; |
42 | #endif | |
6a2c1874 RR |
43 | |
44 | //---------------------------------------------------------------------------- | |
45 | // wxCanvasObject | |
46 | //---------------------------------------------------------------------------- | |
47 | ||
4dbd4ee6 | 48 | wxCanvasObject::wxCanvasObject() |
6a2c1874 RR |
49 | { |
50 | m_owner = NULL; | |
4dbd4ee6 RR |
51 | m_area.x = -1; |
52 | m_area.y = -1; | |
53 | m_area.width = -1; | |
54 | m_area.height = -1; | |
55 | m_isControl = FALSE; | |
56 | m_isVector = FALSE; | |
57 | m_isImage = FALSE; | |
58 | } | |
59 | ||
60 | void wxCanvasObject::SetArea( int x, int y, int width, int height ) | |
61 | { | |
6a2c1874 RR |
62 | m_area.x = x; |
63 | m_area.y = y; | |
64 | m_area.width = width; | |
65 | m_area.height = height; | |
4dbd4ee6 RR |
66 | } |
67 | ||
68 | void wxCanvasObject::SetArea( wxRect rect ) | |
69 | { | |
70 | m_area.x = rect.x; | |
71 | m_area.y = rect.y; | |
72 | m_area.width = rect.width; | |
73 | m_area.height = rect.height; | |
6a2c1874 RR |
74 | } |
75 | ||
76 | void wxCanvasObject::Move( int x, int y ) | |
77 | { | |
78 | int old_x = m_area.x; | |
79 | int old_y = m_area.y; | |
5143c96b | 80 | |
6a2c1874 RR |
81 | m_area.x = x; |
82 | m_area.y = y; | |
dc16900b | 83 | |
6a2c1874 RR |
84 | if (!m_isControl) |
85 | { | |
86 | // TODO: sometimes faster to merge into 1 Update or | |
87 | // to break up into four | |
88 | m_owner->Update( old_x, old_y, m_area.width, m_area.height ); | |
89 | m_owner->Update( x, y, m_area.width, m_area.height ); | |
90 | } | |
91 | } | |
92 | ||
239c1f50 RR |
93 | bool wxCanvasObject::IsHit( int x, int y, int margin ) |
94 | { | |
95 | return ((x >= m_area.x-margin) && | |
96 | (x <= m_area.x+m_area.width+margin) && | |
97 | (y >= m_area.y-margin) && | |
98 | (y <= m_area.y+m_area.height+margin)); | |
99 | } | |
100 | ||
dc16900b KH |
101 | void wxCanvasObject::CaptureMouse() |
102 | { | |
103 | m_owner->SetCaptureMouse( this ); | |
104 | } | |
105 | ||
106 | void wxCanvasObject::ReleaseMouse() | |
107 | { | |
108 | m_owner->SetCaptureMouse( NULL ); | |
109 | } | |
110 | ||
111 | bool wxCanvasObject::IsCapturedMouse() | |
112 | { | |
113 | return m_owner->m_captureMouse==this; | |
114 | } | |
115 | ||
116 | ||
fcbb6b37 | 117 | void wxCanvasObject::Render(int xabs, int yabs, int clip_x, int clip_y, int clip_width, int clip_height ) |
6a2c1874 RR |
118 | { |
119 | } | |
120 | ||
4dbd4ee6 | 121 | void wxCanvasObject::Recreate() |
1e1af41e RR |
122 | { |
123 | } | |
124 | ||
125 | void wxCanvasObject::WriteSVG( wxTextOutputStream &stream ) | |
6a2c1874 RR |
126 | { |
127 | } | |
128 | ||
fcbb6b37 KH |
129 | //---------------------------------------------------------------------------- |
130 | // wxCanvasObjectGroup | |
131 | //---------------------------------------------------------------------------- | |
132 | ||
133 | wxCanvasObjectGroup::wxCanvasObjectGroup() | |
134 | { | |
21840a6c RR |
135 | m_validbounds = FALSE; |
136 | } | |
137 | ||
138 | wxCanvasObjectGroup::~wxCanvasObjectGroup() | |
139 | { | |
fcbb6b37 KH |
140 | } |
141 | ||
142 | void wxCanvasObjectGroup::SetOwner(wxCanvas* canvas) | |
143 | { | |
144 | m_owner=canvas; | |
145 | wxNode *node = m_objects.First(); | |
146 | while (node) | |
147 | { | |
148 | wxCanvasObject *obj = (wxCanvasObject*) node->Data(); | |
149 | ||
150 | obj->SetOwner(canvas); | |
151 | ||
152 | node = node->Next(); | |
153 | } | |
154 | } | |
155 | ||
5143c96b | 156 | void wxCanvasObjectGroup::ExtendArea(double x, double y) |
fcbb6b37 | 157 | { |
21840a6c RR |
158 | if (m_validbounds) |
159 | { | |
160 | if (x < m_minx) m_minx = x; | |
161 | if (y < m_miny) m_miny = y; | |
162 | if (x > m_maxx) m_maxx = x; | |
163 | if (y > m_maxy) m_maxy = y; | |
164 | } | |
165 | else | |
166 | { | |
167 | m_validbounds = TRUE; | |
fcbb6b37 | 168 | |
21840a6c RR |
169 | m_minx = x; |
170 | m_miny = y; | |
171 | m_maxx = x; | |
172 | m_maxy = y; | |
173 | } | |
fcbb6b37 KH |
174 | } |
175 | ||
fcbb6b37 KH |
176 | void wxCanvasObjectGroup::DeleteContents( bool flag) |
177 | { | |
178 | m_objects.DeleteContents( flag ); | |
21840a6c | 179 | m_validbounds = FALSE; |
fcbb6b37 KH |
180 | } |
181 | ||
fcbb6b37 KH |
182 | void wxCanvasObjectGroup::Prepend( wxCanvasObject* obj ) |
183 | { | |
184 | m_objects.Insert( obj ); | |
21840a6c | 185 | m_validbounds = FALSE; |
fcbb6b37 KH |
186 | } |
187 | ||
188 | void wxCanvasObjectGroup::Append( wxCanvasObject* obj ) | |
189 | { | |
190 | m_objects.Append( obj ); | |
21840a6c | 191 | m_validbounds = FALSE; |
fcbb6b37 KH |
192 | } |
193 | ||
194 | void wxCanvasObjectGroup::Insert( size_t before, wxCanvasObject* obj ) | |
195 | { | |
196 | m_objects.Insert( before, obj ); | |
21840a6c | 197 | m_validbounds = FALSE; |
fcbb6b37 KH |
198 | } |
199 | ||
200 | void wxCanvasObjectGroup::Remove( wxCanvasObject* obj ) | |
201 | { | |
202 | m_objects.DeleteObject( obj ); | |
21840a6c | 203 | m_validbounds = FALSE; |
fcbb6b37 KH |
204 | } |
205 | ||
206 | void wxCanvasObjectGroup::Recreate() | |
207 | { | |
21840a6c | 208 | m_validbounds = FALSE; |
fcbb6b37 KH |
209 | wxNode *node = m_objects.First(); |
210 | while (node) | |
211 | { | |
212 | wxCanvasObject *obj = (wxCanvasObject*) node->Data(); | |
213 | ||
214 | obj->Recreate(); | |
215 | ExtendArea(obj->GetX(),obj->GetY()); | |
216 | ExtendArea(obj->GetX()+obj->GetWidth(),obj->GetY()+obj->GetHeight()); | |
217 | ||
218 | node = node->Next(); | |
219 | } | |
220 | } | |
221 | ||
222 | void wxCanvasObjectGroup::Render(int xabs, int yabs, int x, int y, int width, int height ) | |
223 | { | |
fcbb6b37 KH |
224 | // cycle through all objects |
225 | wxNode *node = m_objects.First(); | |
226 | while (node) | |
227 | { | |
228 | wxCanvasObject *obj = (wxCanvasObject*) node->Data(); | |
229 | ||
230 | if (!obj->IsControl()) | |
231 | { | |
232 | // If we have 10.000 objects, we will go through | |
233 | // this 10.000 times for each update, so we have | |
234 | // to optimise carefully. | |
235 | int clip_x = xabs + obj->GetX(); | |
236 | int clip_width = obj->GetWidth(); | |
237 | if (clip_x < x) | |
238 | { | |
239 | clip_width -= x-clip_x; | |
240 | clip_x = x; | |
241 | } | |
242 | if (clip_width > 0) | |
243 | { | |
244 | if (clip_x + clip_width > x + width) | |
245 | clip_width = x+width-clip_x; | |
246 | ||
247 | if (clip_width > 0) | |
248 | { | |
249 | int clip_y = yabs + obj->GetY(); | |
250 | int clip_height = obj->GetHeight(); | |
251 | if (clip_y < y) | |
252 | { | |
253 | clip_height -= y-clip_y; | |
254 | clip_y = y; | |
255 | } | |
256 | if (clip_height > 0) | |
257 | { | |
258 | if (clip_y + clip_height > y + height) | |
259 | clip_height = y+height-clip_y; | |
260 | ||
261 | if (clip_height > 0) | |
262 | obj->Render(xabs,yabs, clip_x, clip_y, clip_width, clip_height ); | |
263 | } | |
264 | } | |
265 | } | |
266 | } | |
267 | ||
268 | node = node->Next(); | |
269 | } | |
270 | } | |
271 | ||
272 | void wxCanvasObjectGroup::WriteSVG( wxTextOutputStream &stream ) | |
273 | { | |
274 | } | |
275 | ||
276 | bool wxCanvasObjectGroup::IsHit( int x, int y, int margin ) | |
277 | { | |
278 | wxNode *node = m_objects.Last(); | |
279 | while (node) | |
280 | { | |
281 | wxCanvasObject *obj = (wxCanvasObject*) node->Data(); | |
282 | ||
283 | if (!obj->IsControl()) | |
284 | { | |
285 | if (obj->IsHit(x,y,margin)) | |
286 | { | |
33ebcd80 | 287 | return TRUE; |
fcbb6b37 KH |
288 | } |
289 | } | |
290 | node = node->Previous(); | |
291 | } | |
33ebcd80 | 292 | return FALSE; |
fcbb6b37 KH |
293 | } |
294 | ||
295 | wxCanvasObject* wxCanvasObjectGroup::IsHitObject( int x, int y, int margin ) | |
296 | { | |
297 | wxCanvasObject *obj=0; | |
298 | wxNode *node = m_objects.Last(); | |
299 | while (node) | |
300 | { | |
301 | obj=(wxCanvasObject*) node->Data(); | |
302 | ||
303 | if (!obj->IsControl()) | |
304 | { | |
305 | if (obj->IsHit(x,y,margin)) | |
306 | { | |
307 | return obj; | |
308 | } | |
309 | } | |
310 | node = node->Previous(); | |
311 | } | |
5143c96b | 312 | |
21840a6c | 313 | return (wxCanvasObject*) NULL; |
fcbb6b37 KH |
314 | } |
315 | ||
316 | //---------------------------------------------------------------------------- | |
317 | // wxCanvasObjectGroupRef | |
318 | //---------------------------------------------------------------------------- | |
319 | ||
320 | wxCanvasObjectGroupRef::wxCanvasObjectGroupRef(double x, double y, wxCanvasObjectGroup* group) | |
321 | : wxCanvasObject() | |
322 | { | |
323 | m_x = x; | |
324 | m_y = y; | |
33ebcd80 RR |
325 | m_validbounds = FALSE; |
326 | m_group = group; | |
fcbb6b37 KH |
327 | } |
328 | ||
329 | void wxCanvasObjectGroupRef::SetOwner(wxCanvas* canvas) | |
330 | { | |
33ebcd80 | 331 | m_owner = canvas; |
fcbb6b37 KH |
332 | m_group->SetOwner(canvas); |
333 | } | |
334 | ||
5143c96b | 335 | void wxCanvasObjectGroupRef::ExtendArea(double x, double y) |
fcbb6b37 | 336 | { |
33ebcd80 RR |
337 | if (m_validbounds) |
338 | { | |
339 | if (x < m_minx) m_minx = x; | |
340 | if (y < m_miny) m_miny = y; | |
341 | if (x > m_maxx) m_maxx = x; | |
342 | if (y > m_maxy) m_maxy = y; | |
343 | } | |
344 | else | |
345 | { | |
346 | m_validbounds = TRUE; | |
fcbb6b37 | 347 | |
33ebcd80 RR |
348 | m_minx = x; |
349 | m_miny = y; | |
350 | m_maxx = x; | |
351 | m_maxy = y; | |
352 | } | |
fcbb6b37 KH |
353 | } |
354 | ||
355 | void wxCanvasObjectGroupRef::Recreate() | |
356 | { | |
33ebcd80 | 357 | m_validbounds = FALSE; |
fcbb6b37 KH |
358 | m_group->Recreate(); |
359 | ExtendArea(m_group->GetXMin(),m_group->GetYMin()); | |
360 | ExtendArea(m_group->GetXMax(),m_group->GetYMax()); | |
361 | ||
362 | //set the area in pixels relative to the parent | |
363 | SetArea( m_owner->GetDeviceX( m_x + m_minx ), | |
364 | m_owner->GetDeviceY( m_y + m_miny ), | |
365 | m_owner->GetDeviceWidth( m_maxx-m_minx ), | |
366 | m_owner->GetDeviceHeight( m_maxy-m_miny ) ); | |
367 | } | |
368 | ||
369 | void wxCanvasObjectGroupRef::Render(int xabs, int yabs, int x, int y, int width, int height ) | |
370 | { | |
5143c96b KH |
371 | xabs += m_owner->GetDeviceX(m_x); |
372 | yabs += m_owner->GetDeviceY(m_y); | |
fcbb6b37 KH |
373 | |
374 | int clip_x = xabs + m_group->GetXMin(); | |
375 | int clip_width = m_group->GetXMax()-m_group->GetXMin(); | |
376 | if (clip_x < x) | |
377 | { | |
378 | clip_width -= x-clip_x; | |
379 | clip_x = x; | |
380 | } | |
381 | if (clip_width > 0) | |
382 | { | |
383 | if (clip_x + clip_width > x + width) | |
384 | clip_width = x+width-clip_x; | |
385 | ||
386 | if (clip_width > 0) | |
387 | { | |
388 | int clip_y = yabs + m_group->GetYMin(); | |
389 | int clip_height = m_group->GetYMax()-m_group->GetYMin(); | |
390 | if (clip_y < y) | |
391 | { | |
392 | clip_height -= y-clip_y; | |
393 | clip_y = y; | |
394 | } | |
395 | if (clip_height > 0) | |
396 | { | |
397 | if (clip_y + clip_height > y + height) | |
398 | clip_height = y+height-clip_y; | |
399 | ||
400 | if (clip_height > 0) | |
401 | m_group->Render(xabs,yabs, clip_x, clip_y, clip_width, clip_height ); | |
402 | } | |
403 | } | |
404 | } | |
405 | } | |
406 | ||
407 | void wxCanvasObjectGroupRef::WriteSVG( wxTextOutputStream &stream ) | |
408 | { | |
409 | } | |
410 | ||
411 | bool wxCanvasObjectGroupRef::IsHit( int x, int y, int margin ) | |
412 | { | |
413 | return m_group->IsHit(x-GetPosX(),y-GetPosY(),margin); | |
414 | } | |
415 | ||
416 | wxCanvasObject* wxCanvasObjectGroupRef::IsHitObject( int x, int y, int margin ) | |
417 | { | |
418 | return m_group->IsHitObject(x-GetPosX(),y-GetPosY(),margin); | |
419 | } | |
420 | ||
421 | void wxCanvasObjectGroupRef::Move( int x, int y ) | |
422 | { | |
fcbb6b37 KH |
423 | m_x = x; |
424 | m_y = y; | |
425 | ||
5143c96b KH |
426 | int old_area_x = m_area.x; |
427 | int old_area_y = m_area.y; | |
428 | ||
429 | m_area.x=m_owner->GetDeviceX( m_x + m_minx ); | |
430 | m_area.y=m_owner->GetDeviceY( m_y + m_miny ); | |
431 | ||
432 | int leftu,rightu,bottomu,topu ; | |
433 | leftu = wxMin (m_area.x, old_area_x ) ; | |
434 | rightu = wxMax (old_area_x + m_area.width, m_area.x + m_area.width) ; | |
435 | topu = wxMin (m_area.y,old_area_y) ; | |
436 | bottomu = wxMax (old_area_y + m_area.height, m_area.y + m_area.height) ; | |
437 | ||
438 | if ( rightu - leftu < 2*m_area.width && bottomu - topu < 2*m_area.height ) | |
fcbb6b37 | 439 | { |
5143c96b KH |
440 | m_owner->Update(leftu,topu,rightu - leftu,bottomu - topu); |
441 | } | |
442 | else | |
443 | { | |
444 | m_owner->Update(old_area_x, old_area_y, m_area.width, m_area.height ); | |
fcbb6b37 KH |
445 | m_owner->Update( m_area.x, m_area.y, m_area.width, m_area.height ); |
446 | } | |
447 | } | |
448 | ||
5143c96b KH |
449 | //---------------------------------------------------------------------------- |
450 | // wxCanvasPolyline | |
451 | //---------------------------------------------------------------------------- | |
452 | ||
453 | wxCanvasPolyline::wxCanvasPolyline( int n, wxPoint2DDouble points[]) | |
454 | : wxCanvasObject() | |
455 | { | |
456 | m_n = n; | |
457 | m_points = points; | |
458 | m_pen = wxPen(wxColour(0,0,0),1,wxSOLID); | |
459 | } | |
460 | ||
461 | wxCanvasPolyline::~wxCanvasPolyline() | |
462 | { | |
463 | delete m_points; | |
464 | } | |
465 | ||
466 | void wxCanvasPolyline::ExtendArea(double x, double y) | |
467 | { | |
468 | if (m_validbounds) | |
469 | { | |
470 | if (x < m_minx) m_minx = x; | |
471 | if (y < m_miny) m_miny = y; | |
472 | if (x > m_maxx) m_maxx = x; | |
473 | if (y > m_maxy) m_maxy = y; | |
474 | } | |
475 | else | |
476 | { | |
477 | m_validbounds = TRUE; | |
478 | ||
479 | m_minx = x; | |
480 | m_miny = y; | |
481 | m_maxx = x; | |
482 | m_maxy = y; | |
483 | } | |
484 | } | |
485 | ||
486 | void wxCanvasPolyline::Recreate() | |
487 | { | |
488 | ||
489 | m_validbounds=FALSE; | |
490 | int i; | |
491 | for (i=0; i < m_n;i++) | |
492 | { | |
493 | ExtendArea(m_points[i].m_x,m_points[i].m_y); | |
494 | } | |
495 | ||
496 | //include the pen width also | |
497 | ExtendArea(m_minx -m_pen.GetWidth(),m_miny-m_pen.GetWidth()); | |
498 | ExtendArea(m_maxx+m_pen.GetWidth()*2,m_maxy+m_pen.GetWidth()*2); | |
499 | ||
500 | //set the area in pixels relative to the parent | |
501 | SetArea( m_owner->GetDeviceX(m_minx ), | |
502 | m_owner->GetDeviceY(m_miny ), | |
503 | m_owner->GetDeviceWidth( m_maxx-m_minx ), | |
504 | m_owner->GetDeviceHeight( m_maxy-m_miny ) ); | |
505 | } | |
506 | ||
507 | void wxCanvasPolyline::Render(int xabs, int yabs, int clip_x, int clip_y, int clip_width, int clip_height ) | |
508 | { | |
509 | int buffer_x = m_owner->GetBufferX(); | |
510 | int buffer_y = m_owner->GetBufferY(); | |
511 | ||
512 | int start_y = clip_y - buffer_y; | |
513 | int end_y = clip_y+clip_height - buffer_y; | |
514 | ||
515 | int start_x = clip_x - buffer_x; | |
516 | int end_x = clip_x+clip_width - buffer_x; | |
517 | ||
518 | #if IMAGE_CANVAS | |
519 | #else | |
520 | wxPoint *cpoints = new wxPoint[m_n]; | |
521 | int i; | |
522 | for (i = 0; i < m_n; i++) | |
523 | { | |
524 | cpoints[i].x = m_owner->GetDeviceX(m_points[i].m_x+xabs); | |
525 | cpoints[i].y = m_owner->GetDeviceY(m_points[i].m_y+yabs); | |
526 | } | |
527 | wxMemoryDC *dc = m_owner->GetDC(); | |
528 | dc->SetClippingRegion(start_x,start_y,end_x-start_x,end_y-start_y); | |
529 | dc->SetPen(m_pen); | |
530 | dc->DrawLines(m_n, cpoints, 0,0); | |
531 | delete [] cpoints; | |
532 | dc->SetPen(wxNullPen); | |
533 | dc->DestroyClippingRegion(); | |
534 | #endif | |
535 | } | |
536 | ||
537 | void wxCanvasPolyline::WriteSVG( wxTextOutputStream &stream ) | |
538 | { | |
539 | } | |
540 | ||
541 | //---------------------------------------------------------------------------- | |
542 | // wxCanvasPolygon | |
543 | //---------------------------------------------------------------------------- | |
544 | ||
545 | wxCanvasPolygon::wxCanvasPolygon( int n, wxPoint2DDouble points[]) | |
546 | : wxCanvasObject() | |
547 | { | |
548 | m_n = n; | |
549 | m_points = points; | |
550 | m_brush = wxBrush(wxColour(0,0,0),wxSOLID); | |
551 | m_pen = wxPen(wxColour(0,0,0),1,wxSOLID); | |
552 | } | |
553 | ||
554 | wxCanvasPolygon::~wxCanvasPolygon() | |
555 | { | |
556 | delete m_points; | |
557 | } | |
558 | ||
559 | void wxCanvasPolygon::ExtendArea(double x, double y) | |
560 | { | |
561 | if (m_validbounds) | |
562 | { | |
563 | if (x < m_minx) m_minx = x; | |
564 | if (y < m_miny) m_miny = y; | |
565 | if (x > m_maxx) m_maxx = x; | |
566 | if (y > m_maxy) m_maxy = y; | |
567 | } | |
568 | else | |
569 | { | |
570 | m_validbounds = TRUE; | |
571 | ||
572 | m_minx = x; | |
573 | m_miny = y; | |
574 | m_maxx = x; | |
575 | m_maxy = y; | |
576 | } | |
577 | } | |
578 | ||
579 | void wxCanvasPolygon::Recreate() | |
580 | { | |
581 | ||
582 | m_validbounds=FALSE; | |
583 | int i; | |
584 | for (i=0; i < m_n;i++) | |
585 | { | |
586 | ExtendArea(m_points[i].m_x,m_points[i].m_y); | |
587 | } | |
588 | ||
589 | //include the pen width also | |
590 | ExtendArea(m_minx -m_pen.GetWidth(),m_miny-m_pen.GetWidth()); | |
591 | ExtendArea(m_maxx+m_pen.GetWidth()*2,m_maxy+m_pen.GetWidth()*2); | |
592 | ||
593 | //set the area in pixels relative to the parent | |
594 | SetArea( m_owner->GetDeviceX( m_minx ), | |
595 | m_owner->GetDeviceY( m_miny ), | |
596 | m_owner->GetDeviceWidth( m_maxx-m_minx ), | |
597 | m_owner->GetDeviceHeight( m_maxy-m_miny ) ); | |
598 | } | |
599 | ||
600 | void wxCanvasPolygon::Render(int xabs, int yabs, int clip_x, int clip_y, int clip_width, int clip_height ) | |
601 | { | |
602 | int buffer_x = m_owner->GetBufferX(); | |
603 | int buffer_y = m_owner->GetBufferY(); | |
604 | ||
605 | int start_y = clip_y - buffer_y; | |
606 | int end_y = clip_y+clip_height - buffer_y; | |
607 | ||
608 | int start_x = clip_x - buffer_x; | |
609 | int end_x = clip_x+clip_width - buffer_x; | |
610 | ||
611 | #if IMAGE_CANVAS | |
612 | #else | |
613 | wxPoint *cpoints = new wxPoint[m_n]; | |
614 | int i; | |
615 | for (i = 0; i < m_n; i++) | |
616 | { | |
617 | cpoints[i].x = m_owner->GetDeviceX(m_points[i].m_x+xabs); | |
618 | cpoints[i].y = m_owner->GetDeviceY(m_points[i].m_y+yabs); | |
619 | } | |
620 | wxMemoryDC *dc = m_owner->GetDC(); | |
621 | dc->SetClippingRegion(start_x,start_y,end_x-start_x,end_y-start_y); | |
622 | dc->SetBrush(m_brush); | |
623 | dc->SetPen(m_pen); | |
624 | dc->DrawPolygon(m_n, cpoints, 0,0,wxWINDING_RULE); | |
625 | delete [] cpoints; | |
626 | dc->SetBrush(wxNullBrush); | |
627 | dc->SetPen(wxNullPen); | |
628 | dc->DestroyClippingRegion(); | |
629 | #endif | |
630 | } | |
631 | ||
632 | void wxCanvasPolygon::WriteSVG( wxTextOutputStream &stream ) | |
633 | { | |
634 | } | |
635 | ||
636 | ||
fcbb6b37 | 637 | |
21544859 RR |
638 | //---------------------------------------------------------------------------- |
639 | // wxCanvasRect | |
640 | //---------------------------------------------------------------------------- | |
641 | ||
dc16900b | 642 | wxCanvasRect::wxCanvasRect( double x, double y, double w, double h, |
4dbd4ee6 RR |
643 | unsigned char red, unsigned char green, unsigned char blue ) |
644 | : wxCanvasObject() | |
21544859 | 645 | { |
4dbd4ee6 RR |
646 | m_x = x; |
647 | m_y = y; | |
648 | m_width = w; | |
649 | m_height = h; | |
dc16900b | 650 | |
21544859 RR |
651 | m_red = red; |
652 | m_green = green; | |
653 | m_blue = blue; | |
654 | } | |
655 | ||
4dbd4ee6 RR |
656 | void wxCanvasRect::Recreate() |
657 | { | |
658 | SetArea( m_owner->GetDeviceX( m_x ), | |
659 | m_owner->GetDeviceY( m_y ), | |
660 | m_owner->GetDeviceWidth( m_width ), | |
661 | m_owner->GetDeviceHeight( m_height ) ); | |
662 | } | |
663 | ||
fcbb6b37 | 664 | void wxCanvasRect::Render(int xabs, int yabs, int clip_x, int clip_y, int clip_width, int clip_height ) |
21544859 | 665 | { |
41328253 RR |
666 | int buffer_x = m_owner->GetBufferX(); |
667 | int buffer_y = m_owner->GetBufferY(); | |
fcbb6b37 | 668 | |
33ebcd80 RR |
669 | #if IMAGE_CANVAS |
670 | wxImage *image = m_owner->GetBuffer(); | |
671 | ||
41328253 RR |
672 | int start_y = clip_y - buffer_y; |
673 | int end_y = clip_y+clip_height - buffer_y; | |
fcbb6b37 | 674 | |
41328253 RR |
675 | int start_x = clip_x - buffer_x; |
676 | int end_x = clip_x+clip_width - buffer_x; | |
fcbb6b37 | 677 | |
21544859 | 678 | // speed up later |
41328253 RR |
679 | for (int y = start_y; y < end_y; y++) |
680 | for (int x = start_x; x < end_x; x++) | |
21544859 | 681 | image->SetRGB( x, y, m_red, m_green, m_blue ); |
33ebcd80 RR |
682 | #else |
683 | wxMemoryDC *dc = m_owner->GetDC(); | |
684 | dc->SetPen( *wxTRANSPARENT_PEN ); | |
685 | wxBrush brush( wxColour( m_red,m_green,m_blue), wxSOLID ); | |
686 | dc->SetBrush( brush ); | |
5143c96b | 687 | |
33ebcd80 RR |
688 | dc->DrawRectangle( clip_x-buffer_x, clip_y-buffer_y, clip_width, clip_height ); |
689 | #endif | |
21544859 RR |
690 | } |
691 | ||
692 | void wxCanvasRect::WriteSVG( wxTextOutputStream &stream ) | |
693 | { | |
694 | } | |
695 | ||
239c1f50 RR |
696 | //---------------------------------------------------------------------------- |
697 | // wxCanvasLine | |
698 | //---------------------------------------------------------------------------- | |
699 | ||
4dbd4ee6 RR |
700 | wxCanvasLine::wxCanvasLine( double x1, double y1, double x2, double y2, |
701 | unsigned char red, unsigned char green, unsigned char blue ) | |
702 | : wxCanvasObject() | |
239c1f50 | 703 | { |
4dbd4ee6 RR |
704 | m_x1 = x1; |
705 | m_y1 = y1; | |
706 | m_x2 = x2; | |
707 | m_y2 = y2; | |
708 | ||
239c1f50 RR |
709 | m_red = red; |
710 | m_green = green; | |
711 | m_blue = blue; | |
712 | } | |
713 | ||
4dbd4ee6 RR |
714 | void wxCanvasLine::Recreate() |
715 | { | |
716 | int x1 = m_owner->GetDeviceX( m_x1 ); | |
717 | int y1 = m_owner->GetDeviceY( m_y1 ); | |
718 | int x2 = m_owner->GetDeviceX( m_x2 ); | |
719 | int y2 = m_owner->GetDeviceY( m_y2 ); | |
720 | if (x1 > x2) | |
721 | { | |
722 | int tmp = x1; | |
723 | x1 = x2; | |
724 | x2 = tmp; | |
725 | } | |
726 | if (y1 > y2) | |
727 | { | |
728 | int tmp = y1; | |
729 | y1 = y2; | |
730 | y2 = tmp; | |
731 | } | |
732 | SetArea( x1, y1, x2-x1+1, y2-y1+1 ); | |
733 | } | |
734 | ||
fcbb6b37 | 735 | void wxCanvasLine::Render(int xabs, int yabs, int clip_x, int clip_y, int clip_width, int clip_height ) |
239c1f50 | 736 | { |
41328253 RR |
737 | int buffer_x = m_owner->GetBufferX(); |
738 | int buffer_y = m_owner->GetBufferY(); | |
fcbb6b37 | 739 | |
33ebcd80 RR |
740 | int x1 = xabs + m_owner->GetDeviceX( m_x1 ); |
741 | int y1 = yabs + m_owner->GetDeviceY( m_y1 ); | |
742 | int x2 = xabs + m_owner->GetDeviceX( m_x2 ); | |
743 | int y2 = yabs + m_owner->GetDeviceY( m_y2 ); | |
5143c96b | 744 | |
33ebcd80 RR |
745 | #if IMAGE_CANVAS |
746 | wxImage *image = m_owner->GetBuffer(); | |
239c1f50 RR |
747 | if ((m_area.width == 0) && (m_area.height == 0)) |
748 | { | |
41328253 | 749 | image->SetRGB( m_area.x-buffer_x, m_area.y-buffer_y, m_red, m_green, m_blue ); |
239c1f50 RR |
750 | } |
751 | else | |
752 | { | |
239c1f50 RR |
753 | wxInt32 d, ii, jj, di, ai, si, dj, aj, sj; |
754 | di = x1 - x2; | |
755 | ai = abs(di) << 1; | |
756 | si = (di < 0)? -1 : 1; | |
757 | dj = y1 - y2; | |
758 | aj = abs(dj) << 1; | |
759 | sj = (dj < 0)? -1 : 1; | |
760 | ||
761 | ii = x2; | |
762 | jj = y2; | |
dc16900b | 763 | |
239c1f50 RR |
764 | if (ai > aj) |
765 | { | |
766 | // iterate over i | |
dc16900b KH |
767 | d = aj - (ai >> 1); |
768 | ||
239c1f50 RR |
769 | while (ii != x1) |
770 | { | |
61b64bd9 RR |
771 | if ((ii >= clip_x) && (ii < clip_x+clip_width) && |
772 | (jj >= clip_y) && (jj < clip_y+clip_height)) | |
239c1f50 | 773 | { |
41328253 | 774 | image->SetRGB( ii-buffer_x, jj-buffer_y, m_red, m_blue, m_green ); |
239c1f50 RR |
775 | } |
776 | if (d >= 0) | |
777 | { | |
778 | jj += sj; | |
dc16900b | 779 | d -= ai; |
239c1f50 RR |
780 | } |
781 | ii += si; | |
782 | d += aj; | |
783 | } | |
784 | } | |
785 | else | |
786 | { | |
787 | // iterate over j | |
788 | d = ai - (aj >> 1); | |
789 | ||
790 | while (jj != y1) | |
791 | { | |
61b64bd9 RR |
792 | if ((ii >= clip_x) && (ii < clip_x+clip_width) && |
793 | (jj >= clip_y) && (jj < clip_y+clip_height)) | |
239c1f50 | 794 | { |
41328253 | 795 | image->SetRGB( ii-buffer_x, jj-buffer_y, m_red, m_blue, m_green ); |
239c1f50 RR |
796 | } |
797 | if (d >= 0) | |
798 | { | |
799 | ii += si; | |
dc16900b | 800 | d -= aj; |
239c1f50 RR |
801 | } |
802 | jj += sj; | |
803 | d += ai; | |
804 | } | |
805 | } | |
806 | } | |
33ebcd80 RR |
807 | #else |
808 | wxMemoryDC *dc = m_owner->GetDC(); | |
809 | dc->SetClippingRegion( clip_x-buffer_x, clip_y-buffer_y, clip_width, clip_height ); | |
5143c96b | 810 | |
33ebcd80 RR |
811 | wxPen pen( wxColour(m_red,m_green,m_blue), 0, wxSOLID ); |
812 | dc->SetPen( pen ); | |
813 | dc->DrawLine( x1-buffer_x, y1-buffer_y, x2-buffer_x, y2-buffer_y ); | |
5143c96b | 814 | |
33ebcd80 RR |
815 | dc->DestroyClippingRegion(); |
816 | #endif | |
239c1f50 RR |
817 | } |
818 | ||
819 | void wxCanvasLine::WriteSVG( wxTextOutputStream &stream ) | |
820 | { | |
1e1af41e | 821 | // no idea |
239c1f50 RR |
822 | } |
823 | ||
6a2c1874 RR |
824 | //---------------------------------------------------------------------------- |
825 | // wxCanvasImage | |
826 | //---------------------------------------------------------------------------- | |
827 | ||
4dbd4ee6 RR |
828 | wxCanvasImage::wxCanvasImage( const wxImage &image, double x, double y, double w, double h ) |
829 | : wxCanvasObject() | |
6a2c1874 | 830 | { |
4dbd4ee6 RR |
831 | m_x = x; |
832 | m_y = y; | |
833 | m_width = w; | |
834 | m_height = h; | |
dc16900b | 835 | |
6a2c1874 RR |
836 | m_image = image; |
837 | m_isImage = TRUE; | |
838 | } | |
839 | ||
4dbd4ee6 RR |
840 | void wxCanvasImage::Recreate() |
841 | { | |
842 | SetArea( m_owner->GetDeviceX( m_x ), | |
843 | m_owner->GetDeviceY( m_y ), | |
844 | m_owner->GetDeviceWidth( m_width ), | |
845 | m_owner->GetDeviceHeight( m_height ) ); | |
dc16900b | 846 | |
33ebcd80 | 847 | #if IMAGE_CANVAS |
4dbd4ee6 RR |
848 | if ((m_area.width == m_image.GetWidth()) && |
849 | (m_area.width == m_image.GetWidth())) | |
33ebcd80 | 850 | { |
4dbd4ee6 | 851 | m_tmp = m_image; |
33ebcd80 | 852 | } |
4dbd4ee6 | 853 | else |
33ebcd80 | 854 | { |
4dbd4ee6 | 855 | m_tmp = m_image.Scale( m_area.width, m_area.height ); |
33ebcd80 RR |
856 | } |
857 | #else | |
858 | if ((m_area.width == m_image.GetWidth()) && | |
859 | (m_area.width == m_image.GetWidth())) | |
860 | { | |
861 | m_tmp = m_image.ConvertToBitmap(); | |
862 | } | |
863 | else | |
864 | { | |
865 | wxImage tmp( m_image.Scale( m_area.width, m_area.height ) ); | |
866 | m_tmp = tmp.ConvertToBitmap(); | |
867 | } | |
868 | #endif | |
4dbd4ee6 RR |
869 | } |
870 | ||
fcbb6b37 | 871 | void wxCanvasImage::Render(int xabs, int yabs, int clip_x, int clip_y, int clip_width, int clip_height ) |
6a2c1874 | 872 | { |
41328253 RR |
873 | int buffer_x = m_owner->GetBufferX(); |
874 | int buffer_y = m_owner->GetBufferY(); | |
fcbb6b37 | 875 | |
33ebcd80 | 876 | #if IMAGE_CANVAS |
fcbb6b37 KH |
877 | if ((clip_x == xabs + m_area.x) && |
878 | (clip_y == yabs + m_area.y) && | |
21544859 RR |
879 | (clip_width == m_area.width) && |
880 | (clip_height == m_area.height)) | |
d1f9b206 | 881 | { |
41328253 | 882 | m_owner->GetBuffer()->Paste( m_tmp, clip_x-buffer_x, clip_y-buffer_y ); |
d1f9b206 RR |
883 | } |
884 | else | |
885 | { | |
21544859 | 886 | // local coordinates |
fcbb6b37 KH |
887 | int start_x = clip_x - (xabs + m_area.x); |
888 | int start_y = clip_y - (yabs + m_area.y); | |
dc16900b | 889 | |
21544859 | 890 | wxRect rect( start_x, start_y, clip_width, clip_height ); |
4dbd4ee6 | 891 | wxImage sub_image( m_tmp.GetSubImage( rect ) ); |
41328253 | 892 | m_owner->GetBuffer()->Paste( sub_image, clip_x-buffer_x, clip_y-buffer_y ); |
d1f9b206 | 893 | } |
33ebcd80 RR |
894 | #else |
895 | wxMemoryDC *dc = m_owner->GetDC(); | |
5143c96b | 896 | |
33ebcd80 RR |
897 | if ((clip_x == xabs + m_area.x) && |
898 | (clip_y == yabs + m_area.y) && | |
899 | (clip_width == m_area.width) && | |
900 | (clip_height == m_area.height)) | |
901 | { | |
902 | dc->DrawBitmap( m_tmp, clip_x-buffer_x, clip_y-buffer_y, TRUE ); | |
903 | } | |
904 | else | |
905 | { | |
906 | // local coordinates | |
907 | int start_x = clip_x - (xabs + m_area.x); | |
908 | int start_y = clip_y - (yabs + m_area.y); | |
5143c96b | 909 | |
33ebcd80 RR |
910 | // Clipping region faster ? |
911 | wxRect rect( start_x, start_y, clip_width, clip_height ); | |
912 | wxBitmap sub_bitmap( m_tmp.GetSubBitmap( rect ) ); | |
913 | dc->DrawBitmap( sub_bitmap, clip_x-buffer_x, clip_y-buffer_y, TRUE ); | |
914 | } | |
915 | #endif | |
6a2c1874 RR |
916 | } |
917 | ||
918 | void wxCanvasImage::WriteSVG( wxTextOutputStream &stream ) | |
919 | { | |
920 | // no idea | |
921 | } | |
922 | ||
3b111dbe RR |
923 | //---------------------------------------------------------------------------- |
924 | // wxCanvasCtrl | |
925 | //---------------------------------------------------------------------------- | |
926 | ||
927 | wxCanvasControl::wxCanvasControl( wxWindow *control ) | |
4dbd4ee6 | 928 | : wxCanvasObject() |
3b111dbe | 929 | { |
21544859 | 930 | m_isControl = TRUE; |
3b111dbe | 931 | m_control = control; |
3b111dbe RR |
932 | } |
933 | ||
934 | wxCanvasControl::~wxCanvasControl() | |
935 | { | |
936 | m_control->Destroy(); | |
937 | } | |
938 | ||
4dbd4ee6 | 939 | void wxCanvasControl::Recreate() |
3b111dbe | 940 | { |
4dbd4ee6 RR |
941 | m_control->GetSize( &m_area.width, &m_area.height ); |
942 | m_control->GetPosition( &m_area.x, &m_area.y ); | |
3b111dbe RR |
943 | } |
944 | ||
4dbd4ee6 | 945 | void wxCanvasControl::Move( int x, int y ) |
3b111dbe | 946 | { |
4dbd4ee6 | 947 | m_control->Move( x, y ); |
3b111dbe RR |
948 | } |
949 | ||
d1f9b206 RR |
950 | //---------------------------------------------------------------------------- |
951 | // wxCanvasText | |
952 | //---------------------------------------------------------------------------- | |
953 | ||
954 | class wxFaceData | |
955 | { | |
956 | public: | |
1e1af41e | 957 | #if wxUSE_FREETYPE |
d1f9b206 RR |
958 | FT_Face m_face; |
959 | #else | |
960 | void *m_dummy; | |
dc16900b | 961 | #endif |
d1f9b206 RR |
962 | }; |
963 | ||
4dbd4ee6 RR |
964 | wxCanvasText::wxCanvasText( const wxString &text, double x, double y, const wxString &fontFile, int size ) |
965 | : wxCanvasObject() | |
d1f9b206 RR |
966 | { |
967 | m_text = text; | |
cb281cfc RR |
968 | m_fontFileName = fontFile; |
969 | m_size = size; | |
dc16900b | 970 | |
cb281cfc | 971 | m_red = 0; |
d1f9b206 RR |
972 | m_green = 0; |
973 | m_blue = 0; | |
dc16900b | 974 | |
4dbd4ee6 | 975 | m_alpha = NULL; |
dc16900b | 976 | |
4dbd4ee6 RR |
977 | m_x = x; |
978 | m_y = y; | |
dc16900b KH |
979 | |
980 | #if wxUSE_FREETYPE | |
d1f9b206 RR |
981 | wxFaceData *data = new wxFaceData; |
982 | m_faceData = data; | |
dc16900b | 983 | |
d1f9b206 | 984 | int error = FT_New_Face( g_freetypeLibrary, |
cb281cfc | 985 | m_fontFileName, |
d1f9b206 RR |
986 | 0, |
987 | &(data->m_face) ); | |
5143c96b | 988 | |
d1f9b206 RR |
989 | error = FT_Set_Char_Size( data->m_face, |
990 | 0, | |
cb281cfc RR |
991 | m_size*64, |
992 | 96, // screen dpi | |
d1f9b206 RR |
993 | 96 ); |
994 | #endif | |
995 | } | |
996 | ||
997 | wxCanvasText::~wxCanvasText() | |
998 | { | |
fcbb6b37 | 999 | #if wxUSE_FREETYPE |
d1f9b206 RR |
1000 | wxFaceData *data = (wxFaceData*) m_faceData; |
1001 | delete data; | |
1002 | #endif | |
1003 | ||
1004 | if (m_alpha) delete [] m_alpha; | |
1005 | } | |
1006 | ||
1007 | void wxCanvasText::SetRGB( unsigned char red, unsigned char green, unsigned char blue ) | |
1008 | { | |
1009 | m_red = red; | |
1010 | m_green = green; | |
1011 | m_blue = blue; | |
1012 | } | |
1013 | ||
1014 | void wxCanvasText::SetFlag( int flag ) | |
1015 | { | |
1016 | m_flag = flag; | |
1017 | } | |
1018 | ||
fcbb6b37 | 1019 | void wxCanvasText::Render(int xabs, int yabs, int clip_x, int clip_y, int clip_width, int clip_height ) |
d1f9b206 RR |
1020 | { |
1021 | if (!m_alpha) return; | |
fcbb6b37 | 1022 | |
33ebcd80 | 1023 | #if IMAGE_CANVAS |
d1f9b206 | 1024 | wxImage *image = m_owner->GetBuffer(); |
41328253 RR |
1025 | int buffer_x = m_owner->GetBufferX(); |
1026 | int buffer_y = m_owner->GetBufferY(); | |
d1f9b206 | 1027 | |
21544859 RR |
1028 | // local coordinates |
1029 | int start_x = clip_x - m_area.x; | |
1030 | int end_x = clip_width + start_x; | |
1031 | int start_y = clip_y - m_area.y; | |
1032 | int end_y = clip_height + start_y; | |
fcbb6b37 | 1033 | |
d1f9b206 RR |
1034 | for (int y = start_y; y < end_y; y++) |
1035 | for (int x = start_x; x < end_x; x++) | |
1036 | { | |
1037 | int alpha = m_alpha[y*m_area.width + x]; | |
1038 | if (alpha) | |
1039 | { | |
41328253 RR |
1040 | int image_x = m_area.x+x - buffer_x; |
1041 | int image_y = m_area.y+y - buffer_y; | |
cb281cfc | 1042 | if (alpha == 255) |
d1f9b206 RR |
1043 | { |
1044 | image->SetRGB( image_x, image_y, m_red, m_green, m_blue ); | |
1045 | continue; | |
1046 | } | |
cb281cfc RR |
1047 | int red1 = (m_red * alpha) / 255; |
1048 | int green1 = (m_green * alpha) / 255; | |
1049 | int blue1 = (m_blue * alpha) / 255; | |
dc16900b | 1050 | |
cb281cfc | 1051 | alpha = 255-alpha; |
d1f9b206 RR |
1052 | int red2 = image->GetRed( image_x, image_y ); |
1053 | int green2 = image->GetGreen( image_x, image_y ); | |
1054 | int blue2 = image->GetBlue( image_x, image_y ); | |
cb281cfc RR |
1055 | red2 = (red2 * alpha) / 255; |
1056 | green2 = (green2 * alpha) / 255; | |
1057 | blue2 = (blue2 * alpha) / 255; | |
fcbb6b37 | 1058 | |
d1f9b206 RR |
1059 | image->SetRGB( image_x, image_y, red1+red2, green1+green2, blue1+blue2 ); |
1060 | } | |
1061 | } | |
33ebcd80 | 1062 | #endif |
d1f9b206 RR |
1063 | } |
1064 | ||
1065 | void wxCanvasText::WriteSVG( wxTextOutputStream &stream ) | |
1066 | { | |
1067 | } | |
1068 | ||
4dbd4ee6 | 1069 | void wxCanvasText::Recreate() |
d1f9b206 | 1070 | { |
4dbd4ee6 | 1071 | if (m_alpha) delete [] m_alpha; |
dc16900b | 1072 | |
4dbd4ee6 RR |
1073 | m_area.x = m_owner->GetDeviceX( m_x ); |
1074 | m_area.y = m_owner->GetDeviceY( m_y ); | |
dc16900b | 1075 | |
4dbd4ee6 RR |
1076 | m_area.width = 100; // TODO, calculate length |
1077 | m_area.height = m_size; | |
1078 | m_alpha = new unsigned char[100*m_size]; | |
1079 | memset( m_alpha, 0, m_area.width*m_area.height ); | |
fcbb6b37 KH |
1080 | |
1081 | #if wxUSE_FREETYPE | |
d1f9b206 RR |
1082 | FT_Face face = ((wxFaceData*)m_faceData)->m_face; |
1083 | FT_GlyphSlot slot = face->glyph; | |
1084 | int pen_x = 0; | |
cb281cfc | 1085 | int pen_y = m_size; |
fcbb6b37 | 1086 | |
cb281cfc | 1087 | for (int n = 0; n < (int)m_text.Len(); n++) |
d1f9b206 RR |
1088 | { |
1089 | FT_UInt index = FT_Get_Char_Index( face, m_text[n] ); | |
dc16900b | 1090 | |
d1f9b206 RR |
1091 | int error = FT_Load_Glyph( face, index, FT_LOAD_DEFAULT ); |
1092 | if (error) continue; | |
fcbb6b37 | 1093 | |
cb281cfc | 1094 | error = FT_Render_Glyph( face->glyph, ft_render_mode_normal ); |
d1f9b206 | 1095 | if (error) continue; |
fcbb6b37 | 1096 | |
cb281cfc RR |
1097 | FT_Bitmap *bitmap = &slot->bitmap; |
1098 | unsigned char* buffer = bitmap->buffer; | |
1099 | for (int y = 0; y < bitmap->rows; y++) | |
1100 | for (int x = 0; x < bitmap->width; x++) | |
1101 | { | |
1102 | unsigned char alpha = buffer[ y*bitmap->pitch + x ]; | |
1103 | if (alpha == 0) continue; | |
dc16900b | 1104 | |
cb281cfc RR |
1105 | int xx = pen_x + slot->bitmap_left + x; |
1106 | int yy = pen_y - slot->bitmap_top + y; | |
1107 | m_alpha[ yy * m_area.width + xx ] = alpha; | |
1108 | } | |
fcbb6b37 | 1109 | |
d1f9b206 RR |
1110 | pen_x += slot->advance.x >> 6; |
1111 | pen_y += slot->advance.y >> 6; | |
fcbb6b37 | 1112 | } |
d1f9b206 RR |
1113 | #endif |
1114 | } | |
1115 | ||
6a2c1874 RR |
1116 | //---------------------------------------------------------------------------- |
1117 | // wxCanvas | |
1118 | //---------------------------------------------------------------------------- | |
1119 | ||
1120 | IMPLEMENT_CLASS(wxCanvas,wxScrolledWindow) | |
1121 | ||
1122 | BEGIN_EVENT_TABLE(wxCanvas,wxScrolledWindow) | |
1123 | EVT_CHAR( wxCanvas::OnChar ) | |
1124 | EVT_PAINT( wxCanvas::OnPaint ) | |
1125 | EVT_SIZE( wxCanvas::OnSize ) | |
1126 | EVT_IDLE( wxCanvas::OnIdle ) | |
1127 | EVT_MOUSE_EVENTS( wxCanvas::OnMouse ) | |
1128 | EVT_SET_FOCUS( wxCanvas::OnSetFocus ) | |
1129 | EVT_KILL_FOCUS( wxCanvas::OnKillFocus ) | |
61b64bd9 | 1130 | EVT_ERASE_BACKGROUND( wxCanvas::OnEraseBackground ) |
6a2c1874 RR |
1131 | END_EVENT_TABLE() |
1132 | ||
1133 | wxCanvas::wxCanvas( wxWindow *parent, wxWindowID id, | |
1134 | const wxPoint &position, const wxSize& size, long style ) : | |
1135 | wxScrolledWindow( parent, id, position, size, style ) | |
1136 | { | |
41328253 RR |
1137 | m_bufferX = 0; |
1138 | m_bufferY = 0; | |
6a2c1874 | 1139 | m_needUpdate = FALSE; |
cb281cfc RR |
1140 | m_red = 0; |
1141 | m_green = 0; | |
1142 | m_blue = 0; | |
239c1f50 | 1143 | m_lastMouse = (wxCanvasObject*)NULL; |
4dbd4ee6 | 1144 | m_captureMouse = (wxCanvasObject*)NULL; |
41328253 | 1145 | m_frozen = TRUE; |
fcbb6b37 KH |
1146 | |
1147 | //root group always at 0,0 | |
1148 | m_root = new wxCanvasObjectGroup(); | |
1149 | m_root->DeleteContents( TRUE ); | |
1150 | m_root->SetOwner(this); | |
6a2c1874 RR |
1151 | } |
1152 | ||
1153 | wxCanvas::~wxCanvas() | |
1154 | { | |
1155 | wxNode *node = m_updateRects.First(); | |
1156 | while (node) | |
1157 | { | |
1158 | wxRect *rect = (wxRect*) node->Data(); | |
1159 | delete rect; | |
1160 | m_updateRects.DeleteNode( node ); | |
1161 | node = m_updateRects.First(); | |
1162 | } | |
1163 | } | |
1164 | ||
1165 | void wxCanvas::SetArea( int width, int height ) | |
1166 | { | |
6a2c1874 RR |
1167 | SetScrollbars( 10, 10, width/10, height/10 ); |
1168 | } | |
1169 | ||
cb281cfc RR |
1170 | void wxCanvas::SetColour( unsigned char red, unsigned char green, unsigned char blue ) |
1171 | { | |
1172 | m_red = red; | |
1173 | m_green = green; | |
1174 | m_blue = blue; | |
dc16900b | 1175 | |
61b64bd9 RR |
1176 | SetBackgroundColour( wxColour( red, green, blue ) ); |
1177 | ||
239c1f50 | 1178 | if (m_frozen) return; |
dc16900b | 1179 | |
33ebcd80 | 1180 | #if IMAGE_CANVAS |
cb281cfc | 1181 | unsigned char *data = m_buffer.GetData(); |
dc16900b | 1182 | |
cb281cfc RR |
1183 | for (int y = 0; y < m_buffer.GetHeight(); y++) |
1184 | for (int x = 0; x < m_buffer.GetWidth(); x++) | |
1185 | { | |
1186 | data[0] = red; | |
1187 | data++; | |
1188 | data[0] = green; | |
1189 | data++; | |
1190 | data[0] = blue; | |
1191 | data++; | |
1192 | } | |
33ebcd80 RR |
1193 | #else |
1194 | wxMemoryDC dc; | |
1195 | dc.SelectObject( m_buffer ); | |
1196 | dc.SetPen( *wxTRANSPARENT_PEN ); | |
1197 | wxBrush brush( wxColour( red,green,blue), wxSOLID ); | |
1198 | dc.SetBrush( brush ); | |
1199 | dc.DrawRectangle( 0, 0, m_buffer.GetWidth(), m_buffer.GetHeight() ); | |
1200 | dc.SelectObject( wxNullBitmap ); | |
1201 | #endif | |
cb281cfc RR |
1202 | } |
1203 | ||
dc16900b | 1204 | void wxCanvas::SetCaptureMouse( wxCanvasObject *obj ) |
4dbd4ee6 | 1205 | { |
dc16900b KH |
1206 | if (obj) |
1207 | { | |
1208 | wxWindow::CaptureMouse(); | |
1209 | m_captureMouse = obj; | |
1210 | } | |
1211 | else | |
1212 | { | |
1213 | wxWindow::ReleaseMouse(); | |
1214 | m_captureMouse = NULL; | |
1215 | } | |
4dbd4ee6 RR |
1216 | } |
1217 | ||
239c1f50 RR |
1218 | void wxCanvas::Freeze() |
1219 | { | |
1220 | m_frozen = TRUE; | |
1221 | } | |
1222 | ||
1223 | void wxCanvas::Thaw() | |
1224 | { | |
1225 | wxNode *node = m_updateRects.First(); | |
1226 | while (node) | |
1227 | { | |
1228 | wxRect *rect = (wxRect*) node->Data(); | |
1229 | delete rect; | |
1230 | m_updateRects.DeleteNode( node ); | |
1231 | node = m_updateRects.First(); | |
1232 | } | |
dc16900b | 1233 | |
239c1f50 | 1234 | m_frozen = FALSE; |
dc16900b | 1235 | |
41328253 RR |
1236 | if (m_buffer.Ok()) |
1237 | Update( m_bufferX, m_bufferY, m_buffer.GetWidth(), m_buffer.GetHeight() ); | |
239c1f50 RR |
1238 | } |
1239 | ||
41328253 | 1240 | void wxCanvas::Update( int x, int y, int width, int height, bool blit ) |
6a2c1874 | 1241 | { |
239c1f50 | 1242 | if (m_frozen) return; |
fcbb6b37 | 1243 | |
21544859 | 1244 | // clip to buffer |
41328253 | 1245 | if (x < m_bufferX) |
21544859 | 1246 | { |
41328253 RR |
1247 | width -= m_bufferX-x; |
1248 | x = m_bufferX; | |
21544859 | 1249 | } |
33ebcd80 | 1250 | if (width <= 0) return; |
dc16900b | 1251 | |
41328253 | 1252 | if (y < m_bufferY) |
21544859 | 1253 | { |
41328253 RR |
1254 | height -= m_bufferY-y; |
1255 | y = m_bufferY; | |
21544859 | 1256 | } |
33ebcd80 | 1257 | if (height <= 0) return; |
dc16900b | 1258 | |
41328253 | 1259 | if (x+width > m_bufferX+m_buffer.GetWidth()) |
21544859 | 1260 | { |
41328253 | 1261 | width = m_bufferX+m_buffer.GetWidth() - x; |
21544859 | 1262 | } |
33ebcd80 | 1263 | if (width <= 0) return; |
dc16900b | 1264 | |
41328253 | 1265 | if (y+height > m_bufferY+m_buffer.GetHeight()) |
21544859 | 1266 | { |
41328253 | 1267 | height = m_bufferY+m_buffer.GetHeight() - y; |
21544859 | 1268 | } |
33ebcd80 | 1269 | if (height <= 0) return; |
dc16900b | 1270 | |
21544859 | 1271 | // update is within the buffer |
6a2c1874 | 1272 | m_needUpdate = TRUE; |
dc16900b | 1273 | |
21544859 | 1274 | // has to be blitted to screen later |
41328253 RR |
1275 | if (blit) |
1276 | { | |
1277 | m_updateRects.Append( | |
1278 | (wxObject*) new wxRect( x,y,width,height ) ); | |
1279 | } | |
dc16900b | 1280 | |
33ebcd80 | 1281 | #if IMAGE_CANVAS |
21544859 | 1282 | // speed up with direct access, maybe add wxImage::Clear(x,y,w,h,r,g,b) |
41328253 RR |
1283 | int start_y = y - m_bufferY; |
1284 | int end_y = y+height - m_bufferY; | |
1285 | int start_x = x - m_bufferX; | |
1286 | int end_x = x+width - m_bufferX; | |
1287 | for (int yy = start_y; yy < end_y; yy++) | |
1288 | for (int xx = start_x; xx < end_x; xx++) | |
cb281cfc | 1289 | m_buffer.SetRGB( xx, yy, m_red, m_green, m_blue ); |
5143c96b | 1290 | |
fcbb6b37 | 1291 | m_root->Render(0,0, x, y, width, height ); |
33ebcd80 RR |
1292 | #else |
1293 | wxMemoryDC dc; | |
1294 | dc.SelectObject( m_buffer ); | |
1295 | dc.SetPen( *wxTRANSPARENT_PEN ); | |
1296 | wxBrush brush( wxColour( m_red,m_green,m_blue), wxSOLID ); | |
1297 | dc.SetBrush( brush ); | |
1298 | dc.DrawRectangle( x-m_bufferX, y-m_bufferY, width, height ); | |
1299 | ||
1300 | m_renderDC = &dc; | |
1301 | m_root->Render(0,0, x, y, width, height ); | |
5143c96b | 1302 | |
33ebcd80 RR |
1303 | dc.SelectObject( wxNullBitmap ); |
1304 | #endif | |
6a2c1874 RR |
1305 | } |
1306 | ||
3b111dbe | 1307 | void wxCanvas::BlitBuffer( wxDC &dc ) |
6a2c1874 | 1308 | { |
6a2c1874 RR |
1309 | wxNode *node = m_updateRects.First(); |
1310 | while (node) | |
1311 | { | |
1312 | wxRect *rect = (wxRect*) node->Data(); | |
6a2c1874 | 1313 | |
41328253 RR |
1314 | wxRect sub_rect( *rect ); |
1315 | sub_rect.x -= m_bufferX; | |
1316 | sub_rect.y -= m_bufferY; | |
fcbb6b37 | 1317 | |
33ebcd80 | 1318 | #if IMAGE_CANVAS |
6a2c1874 | 1319 | |
33ebcd80 | 1320 | wxImage sub_image( m_buffer.GetSubImage( sub_rect ) ); |
6a2c1874 | 1321 | #ifdef __WXGTK__ |
dc16900b | 1322 | int bpp = wxDisplayDepth(); |
6a2c1874 RR |
1323 | if (bpp > 8) |
1324 | { | |
1325 | // the init code is doubled in wxImage | |
1326 | static bool s_hasInitialized = FALSE; | |
1327 | ||
1328 | if (!s_hasInitialized) | |
1329 | { | |
1330 | gdk_rgb_init(); | |
1331 | s_hasInitialized = TRUE; | |
1332 | } | |
dc16900b | 1333 | |
6a2c1874 RR |
1334 | gdk_draw_rgb_image( GTK_PIZZA(m_wxwindow)->bin_window, |
1335 | m_wxwindow->style->black_gc, | |
41328253 | 1336 | sub_rect.x, sub_rect.y, |
6a2c1874 RR |
1337 | sub_image.GetWidth(), sub_image.GetHeight(), |
1338 | GDK_RGB_DITHER_NONE, | |
1339 | sub_image.GetData(), | |
1340 | sub_image.GetWidth()*3 ); | |
1341 | } | |
1342 | else | |
1343 | { | |
1344 | wxBitmap bitmap( sub_image.ConvertToBitmap() ); | |
1345 | dc.DrawBitmap( bitmap, rect->x, rect->y ); | |
1346 | } | |
33ebcd80 | 1347 | #else |
6a2c1874 RR |
1348 | wxBitmap bitmap( sub_image.ConvertToBitmap() ); |
1349 | dc.DrawBitmap( bitmap, rect->x, rect->y ); | |
1350 | #endif | |
dc16900b | 1351 | |
33ebcd80 RR |
1352 | #else // IMAGE_CANVAS |
1353 | ||
1354 | // Maybe clipping use SetClipping() is faster than | |
1355 | // getting the subrect first and drawing it then? | |
1356 | wxBitmap sub_bitmap( m_buffer.GetSubBitmap( sub_rect ) ); | |
1357 | dc.DrawBitmap( sub_bitmap, rect->x, rect->y ); | |
5143c96b | 1358 | |
33ebcd80 | 1359 | #endif |
6a2c1874 RR |
1360 | delete rect; |
1361 | m_updateRects.DeleteNode( node ); | |
1362 | node = m_updateRects.First(); | |
1363 | } | |
dc16900b | 1364 | |
3b111dbe RR |
1365 | m_needUpdate = FALSE; |
1366 | } | |
1367 | ||
1368 | void wxCanvas::UpdateNow() | |
1369 | { | |
61b64bd9 RR |
1370 | if (m_frozen) return; |
1371 | ||
3b111dbe | 1372 | if (!m_needUpdate) return; |
dc16900b | 1373 | |
3b111dbe RR |
1374 | wxClientDC dc( this ); |
1375 | PrepareDC( dc ); | |
dc16900b | 1376 | |
3b111dbe | 1377 | BlitBuffer( dc ); |
6a2c1874 RR |
1378 | } |
1379 | ||
4dbd4ee6 RR |
1380 | int wxCanvas::GetDeviceX( double x ) |
1381 | { | |
1382 | return (int) x; | |
1383 | } | |
1384 | ||
1385 | int wxCanvas::GetDeviceY( double y ) | |
1386 | { | |
1387 | return (int) y; | |
1388 | } | |
1389 | ||
1390 | int wxCanvas::GetDeviceWidth( double width ) | |
1391 | { | |
1392 | return (int) width; | |
1393 | } | |
1394 | ||
1395 | int wxCanvas::GetDeviceHeight( double height ) | |
1396 | { | |
1397 | return (int) height; | |
1398 | } | |
1399 | ||
1400 | void wxCanvas::Recreate() | |
1401 | { | |
fcbb6b37 | 1402 | m_root->Recreate(); |
4dbd4ee6 RR |
1403 | } |
1404 | ||
6a2c1874 RR |
1405 | void wxCanvas::Prepend( wxCanvasObject* obj ) |
1406 | { | |
fcbb6b37 KH |
1407 | m_root->Prepend( obj ); |
1408 | obj->SetOwner(this); | |
dc16900b | 1409 | |
fcbb6b37 | 1410 | m_root->Recreate(); |
dc16900b | 1411 | |
6a2c1874 RR |
1412 | if (!obj->IsControl()) |
1413 | Update( obj->GetX(), obj->GetY(), obj->GetWidth(), obj->GetHeight() ); | |
1414 | } | |
1415 | ||
1416 | void wxCanvas::Append( wxCanvasObject* obj ) | |
1417 | { | |
fcbb6b37 KH |
1418 | m_root->Append( obj ); |
1419 | obj->SetOwner(this); | |
dc16900b | 1420 | |
fcbb6b37 | 1421 | m_root->Recreate(); |
dc16900b | 1422 | |
6a2c1874 RR |
1423 | if (!obj->IsControl()) |
1424 | Update( obj->GetX(), obj->GetY(), obj->GetWidth(), obj->GetHeight() ); | |
1425 | } | |
1426 | ||
1427 | void wxCanvas::Insert( size_t before, wxCanvasObject* obj ) | |
1428 | { | |
fcbb6b37 KH |
1429 | m_root->Insert( before, obj ); |
1430 | obj->SetOwner(this); | |
dc16900b | 1431 | |
fcbb6b37 | 1432 | m_root->Recreate(); |
dc16900b | 1433 | |
6a2c1874 RR |
1434 | if (!obj->IsControl()) |
1435 | Update( obj->GetX(), obj->GetY(), obj->GetWidth(), obj->GetHeight() ); | |
1436 | } | |
1437 | ||
1438 | void wxCanvas::Remove( wxCanvasObject* obj ) | |
1439 | { | |
1440 | int x = obj->GetX(); | |
1441 | int y = obj->GetY(); | |
1442 | int w = obj->GetWidth(); | |
1443 | int h = obj->GetHeight(); | |
1444 | bool ic = obj->IsControl(); | |
dc16900b | 1445 | |
fcbb6b37 | 1446 | m_root->Remove( obj ); |
dc16900b | 1447 | |
6a2c1874 RR |
1448 | if (!ic) |
1449 | Update( x, y, w, h ); | |
1450 | } | |
1451 | ||
1452 | void wxCanvas::OnPaint(wxPaintEvent &event) | |
1453 | { | |
6a2c1874 | 1454 | wxPaintDC dc(this); |
3b111dbe | 1455 | PrepareDC( dc ); |
dc16900b | 1456 | |
41328253 | 1457 | if (!m_buffer.Ok()) return; |
fcbb6b37 | 1458 | |
b85cfb6f | 1459 | if (m_frozen) return; |
41328253 | 1460 | |
6a2c1874 RR |
1461 | m_needUpdate = TRUE; |
1462 | ||
1463 | wxRegionIterator it( GetUpdateRegion() ); | |
1464 | while (it) | |
1465 | { | |
1466 | int x = it.GetX(); | |
1467 | int y = it.GetY(); | |
dc16900b | 1468 | |
6a2c1874 RR |
1469 | int w = it.GetWidth(); |
1470 | int h = it.GetHeight(); | |
dc16900b | 1471 | |
21544859 RR |
1472 | if (x+w > m_buffer.GetWidth()) |
1473 | w = m_buffer.GetWidth() - x; | |
1474 | if (y+h > m_buffer.GetHeight()) | |
1475 | h = m_buffer.GetHeight() - y; | |
dc16900b | 1476 | |
21544859 | 1477 | if ((w > 0) && (h > 0)) |
41328253 RR |
1478 | { |
1479 | CalcUnscrolledPosition( x, y, &x, &y ); | |
21544859 | 1480 | m_updateRects.Append( (wxObject*) new wxRect( x, y, w, h ) ); |
41328253 | 1481 | } |
dc16900b | 1482 | |
6a2c1874 RR |
1483 | it++; |
1484 | } | |
dc16900b | 1485 | |
3b111dbe | 1486 | BlitBuffer( dc ); |
6a2c1874 RR |
1487 | } |
1488 | ||
41328253 RR |
1489 | void wxCanvas::ScrollWindow( int dx, int dy, const wxRect* rect ) |
1490 | { | |
61b64bd9 RR |
1491 | // If any updates are pending, do them now since they will |
1492 | // expect the previous m_bufferX and m_bufferY values. | |
41328253 RR |
1493 | UpdateNow(); |
1494 | ||
61b64bd9 RR |
1495 | // The buffer always starts at the top left corner of the |
1496 | // client area. Indeed, it is the client area. | |
41328253 RR |
1497 | CalcUnscrolledPosition( 0, 0, &m_bufferX, &m_bufferY ); |
1498 | ||
33ebcd80 | 1499 | #if IMAGE_CANVAS |
41328253 | 1500 | unsigned char* data = m_buffer.GetData(); |
fcbb6b37 | 1501 | |
41328253 RR |
1502 | if (dy != 0) |
1503 | { | |
1504 | if (dy > 0) | |
1505 | { | |
1506 | unsigned char *source = data; | |
1507 | unsigned char *dest = data + (dy * m_buffer.GetWidth() * 3); | |
1508 | size_t count = (size_t) (m_buffer.GetWidth() * 3 * (m_buffer.GetHeight()-dy)); | |
1509 | memmove( dest, source, count ); | |
fcbb6b37 | 1510 | |
61b64bd9 RR |
1511 | // We update the new buffer area, but there is no need to |
1512 | // blit (last param FALSE) since the ensuing paint event will | |
1513 | // do that anyway. | |
41328253 RR |
1514 | Update( m_bufferX, m_bufferY, m_buffer.GetWidth(), dy, FALSE ); |
1515 | } | |
1516 | else | |
1517 | { | |
1518 | unsigned char *dest = data; | |
1519 | unsigned char *source = data + (-dy * m_buffer.GetWidth() * 3); | |
1520 | size_t count = (size_t) (m_buffer.GetWidth() * 3 * (m_buffer.GetHeight()+dy)); | |
1521 | memmove( dest, source, count ); | |
fcbb6b37 | 1522 | |
61b64bd9 RR |
1523 | // We update the new buffer area, but there is no need to |
1524 | // blit (last param FALSE) since the ensuing paint event will | |
1525 | // do that anyway. | |
41328253 RR |
1526 | Update( m_bufferX, m_bufferY+m_buffer.GetHeight()+dy, m_buffer.GetWidth(), -dy, FALSE ); |
1527 | } | |
1528 | } | |
fcbb6b37 | 1529 | |
41328253 RR |
1530 | if (dx != 0) |
1531 | { | |
61b64bd9 RR |
1532 | if (dx > 0) |
1533 | { | |
1534 | unsigned char *source = data; | |
1535 | for (int y = 0; y < m_buffer.GetHeight(); y++) | |
1536 | { | |
1537 | unsigned char *dest = source + dx*3; | |
1538 | memmove( dest, source, (m_buffer.GetWidth()-dx) * 3 ); | |
1539 | source += m_buffer.GetWidth()*3; | |
1540 | } | |
fcbb6b37 | 1541 | |
61b64bd9 RR |
1542 | // We update the new buffer area, but there is no need to |
1543 | // blit (last param FALSE) since the ensuing paint event will | |
1544 | // do that anyway. | |
1545 | Update( m_bufferX, m_bufferY, dx, m_buffer.GetHeight(), FALSE ); | |
1546 | } | |
1547 | else | |
1548 | { | |
1549 | unsigned char *dest = data; | |
1550 | for (int y = 0; y < m_buffer.GetHeight(); y++) | |
1551 | { | |
1552 | unsigned char *source = dest - dx*3; | |
1553 | memmove( dest, source, (m_buffer.GetWidth()+dx) * 3 ); | |
1554 | dest += m_buffer.GetWidth()*3; | |
1555 | } | |
fcbb6b37 | 1556 | |
61b64bd9 RR |
1557 | // We update the new buffer area, but there is no need to |
1558 | // blit (last param FALSE) since the ensuing paint event will | |
1559 | // do that anyway. | |
1560 | Update( m_bufferX+m_buffer.GetWidth()+dx, m_bufferY, -dx, m_buffer.GetHeight(), FALSE ); | |
1561 | } | |
41328253 | 1562 | } |
33ebcd80 RR |
1563 | #else |
1564 | // Update everything, TODO: scrolling | |
1565 | Update( m_bufferX, m_bufferY, m_buffer.GetWidth(), m_buffer.GetHeight(), FALSE ); | |
1566 | #endif | |
41328253 RR |
1567 | |
1568 | wxWindow::ScrollWindow( dx, dy, rect ); | |
1569 | } | |
1570 | ||
6a2c1874 RR |
1571 | void wxCanvas::OnMouse(wxMouseEvent &event) |
1572 | { | |
239c1f50 RR |
1573 | int x = event.GetX(); |
1574 | int y = event.GetY(); | |
1575 | CalcUnscrolledPosition( x, y, &x, &y ); | |
dc16900b | 1576 | |
239c1f50 RR |
1577 | if (event.GetEventType() == wxEVT_MOTION) |
1578 | { | |
dc16900b | 1579 | if (m_captureMouse) //no matter what go to this one |
239c1f50 | 1580 | { |
dc16900b KH |
1581 | wxMouseEvent child_event( wxEVT_MOTION ); |
1582 | child_event.SetEventObject(m_captureMouse); | |
1583 | child_event.m_x = x - m_captureMouse->GetX(); | |
1584 | child_event.m_y = y - m_captureMouse->GetY(); | |
1585 | child_event.m_leftDown = event.m_leftDown; | |
1586 | child_event.m_rightDown = event.m_rightDown; | |
1587 | child_event.m_middleDown = event.m_middleDown; | |
1588 | child_event.m_controlDown = event.m_controlDown; | |
1589 | child_event.m_shiftDown = event.m_shiftDown; | |
1590 | child_event.m_altDown = event.m_altDown; | |
1591 | child_event.m_metaDown = event.m_metaDown; | |
872f1044 | 1592 | |
dc16900b | 1593 | m_captureMouse->ProcessEvent( child_event ); |
872f1044 | 1594 | return; |
dc16900b KH |
1595 | } |
1596 | else | |
1597 | { | |
fcbb6b37 | 1598 | wxCanvasObject *obj = m_root->IsHitObject(x,y,0); |
dc16900b | 1599 | |
fcbb6b37 KH |
1600 | if (obj && !obj->IsControl()) |
1601 | { | |
1602 | wxMouseEvent child_event( wxEVT_MOTION ); | |
1603 | child_event.SetEventObject( obj ); | |
1604 | child_event.m_x = x - obj->GetX(); | |
1605 | child_event.m_y = y - obj->GetY(); | |
1606 | child_event.m_leftDown = event.m_leftDown; | |
1607 | child_event.m_rightDown = event.m_rightDown; | |
1608 | child_event.m_middleDown = event.m_middleDown; | |
1609 | child_event.m_controlDown = event.m_controlDown; | |
1610 | child_event.m_shiftDown = event.m_shiftDown; | |
1611 | child_event.m_altDown = event.m_altDown; | |
1612 | child_event.m_metaDown = event.m_metaDown; | |
1613 | ||
1614 | if ((obj != m_lastMouse) && (m_lastMouse != NULL)) | |
239c1f50 | 1615 | { |
fcbb6b37 KH |
1616 | child_event.SetEventType( wxEVT_LEAVE_WINDOW ); |
1617 | child_event.SetEventObject( m_lastMouse ); | |
1618 | child_event.m_x = x - m_lastMouse->GetX(); | |
1619 | child_event.m_y = y - m_lastMouse->GetY(); | |
1620 | m_lastMouse->ProcessEvent( child_event ); | |
1621 | ||
1622 | m_lastMouse = obj; | |
1623 | child_event.SetEventType( wxEVT_ENTER_WINDOW ); | |
1624 | child_event.SetEventObject( m_lastMouse ); | |
1625 | child_event.m_x = x - m_lastMouse->GetX(); | |
1626 | child_event.m_y = y - m_lastMouse->GetY(); | |
1627 | m_lastMouse->ProcessEvent( child_event ); | |
1628 | ||
1629 | child_event.SetEventType( wxEVT_MOTION ); | |
1630 | child_event.SetEventObject( obj ); | |
239c1f50 | 1631 | } |
872f1044 | 1632 | |
fcbb6b37 KH |
1633 | obj->ProcessEvent( child_event ); |
1634 | return; | |
239c1f50 | 1635 | } |
239c1f50 RR |
1636 | } |
1637 | if (m_lastMouse) | |
1638 | { | |
1639 | wxMouseEvent child_event( wxEVT_LEAVE_WINDOW ); | |
1640 | child_event.SetEventObject( m_lastMouse ); | |
1e1af41e RR |
1641 | child_event.m_x = x - m_lastMouse->GetX(); |
1642 | child_event.m_y = y - m_lastMouse->GetY(); | |
239c1f50 RR |
1643 | child_event.m_leftDown = event.m_leftDown; |
1644 | child_event.m_rightDown = event.m_rightDown; | |
1645 | child_event.m_middleDown = event.m_middleDown; | |
1646 | child_event.m_controlDown = event.m_controlDown; | |
1647 | child_event.m_shiftDown = event.m_shiftDown; | |
1648 | child_event.m_altDown = event.m_altDown; | |
1649 | child_event.m_metaDown = event.m_metaDown; | |
1650 | m_lastMouse->ProcessEvent( child_event ); | |
dc16900b | 1651 | |
239c1f50 RR |
1652 | m_lastMouse = (wxCanvasObject*) NULL; |
1653 | return; | |
1654 | } | |
1655 | } | |
872f1044 RR |
1656 | else |
1657 | { | |
1658 | if (m_captureMouse) //no matter what go to this one | |
1659 | { | |
1660 | wxMouseEvent child_event( event.GetEventType() ); | |
1661 | child_event.SetEventObject(m_captureMouse); | |
1662 | child_event.m_x = x - m_captureMouse->GetX(); | |
1663 | child_event.m_y = y - m_captureMouse->GetY(); | |
1664 | child_event.m_leftDown = event.m_leftDown; | |
1665 | child_event.m_rightDown = event.m_rightDown; | |
1666 | child_event.m_middleDown = event.m_middleDown; | |
1667 | child_event.m_controlDown = event.m_controlDown; | |
1668 | child_event.m_shiftDown = event.m_shiftDown; | |
1669 | child_event.m_altDown = event.m_altDown; | |
1670 | child_event.m_metaDown = event.m_metaDown; | |
1671 | m_captureMouse->ProcessEvent( child_event ); | |
1672 | } | |
1673 | else | |
1674 | { | |
1675 | wxCanvasObject *obj = m_root->IsHitObject(x,y,0); | |
1676 | ||
1677 | if (obj && !obj->IsControl()) | |
1678 | { | |
1679 | wxMouseEvent child_event( event.GetEventType() ); | |
1680 | child_event.SetEventObject( obj ); | |
1681 | child_event.m_x = x - obj->GetX(); | |
1682 | child_event.m_y = y - obj->GetY(); | |
1683 | child_event.m_leftDown = event.m_leftDown; | |
1684 | child_event.m_rightDown = event.m_rightDown; | |
1685 | child_event.m_middleDown = event.m_middleDown; | |
1686 | child_event.m_controlDown = event.m_controlDown; | |
1687 | child_event.m_shiftDown = event.m_shiftDown; | |
1688 | child_event.m_altDown = event.m_altDown; | |
1689 | child_event.m_metaDown = event.m_metaDown; | |
1690 | ||
1691 | obj->ProcessEvent( child_event ); | |
1692 | return; | |
1693 | } | |
1694 | } | |
1695 | } | |
fcbb6b37 | 1696 | |
239c1f50 | 1697 | event.Skip(); |
6a2c1874 RR |
1698 | } |
1699 | ||
1700 | void wxCanvas::OnSize(wxSizeEvent &event) | |
1701 | { | |
b85cfb6f RR |
1702 | int w,h; |
1703 | GetClientSize( &w, &h ); | |
33ebcd80 | 1704 | #if IMAGE_CANVAS |
b85cfb6f | 1705 | m_buffer = wxImage( w, h ); |
33ebcd80 RR |
1706 | #else |
1707 | m_buffer = wxBitmap( w, h ); | |
1708 | #endif | |
fcbb6b37 | 1709 | |
b85cfb6f | 1710 | CalcUnscrolledPosition( 0, 0, &m_bufferX, &m_bufferY ); |
fcbb6b37 | 1711 | |
b85cfb6f RR |
1712 | wxNode *node = m_updateRects.First(); |
1713 | while (node) | |
1714 | { | |
1715 | wxRect *rect = (wxRect*) node->Data(); | |
1716 | delete rect; | |
1717 | m_updateRects.DeleteNode( node ); | |
1718 | node = m_updateRects.First(); | |
1719 | } | |
1720 | ||
1721 | m_frozen = FALSE; | |
1722 | ||
1723 | Update( m_bufferX, m_bufferY, m_buffer.GetWidth(), m_buffer.GetHeight(), FALSE ); | |
41328253 | 1724 | |
6a2c1874 RR |
1725 | event.Skip(); |
1726 | } | |
1727 | ||
1728 | void wxCanvas::OnIdle(wxIdleEvent &event) | |
1729 | { | |
1730 | UpdateNow(); | |
1731 | event.Skip(); | |
1732 | } | |
1733 | ||
1734 | void wxCanvas::OnSetFocus(wxFocusEvent &event) | |
1735 | { | |
1736 | } | |
1737 | ||
1738 | void wxCanvas::OnKillFocus(wxFocusEvent &event) | |
1739 | { | |
1740 | } | |
1741 | ||
1742 | void wxCanvas::OnChar(wxKeyEvent &event) | |
1743 | { | |
1744 | event.Skip(); | |
1745 | } | |
1746 | ||
61b64bd9 RR |
1747 | void wxCanvas::OnEraseBackground(wxEraseEvent &event) |
1748 | { | |
1749 | } | |
1750 | ||
d1f9b206 RR |
1751 | //-------------------------------------------------------------------- |
1752 | // wxCanvasModule | |
1753 | //-------------------------------------------------------------------- | |
1754 | ||
1755 | class wxCanvasModule : public wxModule | |
1756 | { | |
1757 | public: | |
1758 | virtual bool OnInit(); | |
1759 | virtual void OnExit(); | |
1760 | ||
1761 | private: | |
1762 | DECLARE_DYNAMIC_CLASS(wxCanvasModule) | |
1763 | }; | |
1764 | ||
1765 | IMPLEMENT_DYNAMIC_CLASS(wxCanvasModule, wxModule) | |
6a2c1874 | 1766 | |
d1f9b206 RR |
1767 | bool wxCanvasModule::OnInit() |
1768 | { | |
1e1af41e | 1769 | #if wxUSE_FREETYPE |
d1f9b206 RR |
1770 | int error = FT_Init_FreeType( &g_freetypeLibrary ); |
1771 | if (error) return FALSE; | |
1772 | #endif | |
1773 | ||
1774 | return TRUE; | |
1775 | } | |
1776 | ||
1777 | void wxCanvasModule::OnExit() | |
1778 | { | |
1e1af41e | 1779 | #if wxUSE_FREETYPE |
cb281cfc | 1780 | FT_Done_FreeType( g_freetypeLibrary ); |
d1f9b206 RR |
1781 | #endif |
1782 | } |