]> git.saurik.com Git - wxWidgets.git/blame - contrib/src/canvas/canvas.cpp
attempt to fix crash in tree ctrl
[wxWidgets.git] / contrib / src / canvas / canvas.cpp
CommitLineData
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
41FT_Library g_freetypeLibrary;
42#endif
6a2c1874
RR
43
44//----------------------------------------------------------------------------
45// wxCanvasObject
46//----------------------------------------------------------------------------
47
4dbd4ee6 48wxCanvasObject::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
60void 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
68void 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
76void wxCanvasObject::Move( int x, int y )
77{
78 int old_x = m_area.x;
79 int old_y = m_area.y;
21840a6c 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
93bool 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
101void wxCanvasObject::CaptureMouse()
102{
103 m_owner->SetCaptureMouse( this );
104}
105
106void wxCanvasObject::ReleaseMouse()
107{
108 m_owner->SetCaptureMouse( NULL );
109}
110
111bool wxCanvasObject::IsCapturedMouse()
112{
113 return m_owner->m_captureMouse==this;
114}
115
116
fcbb6b37 117void wxCanvasObject::Render(int xabs, int yabs, int clip_x, int clip_y, int clip_width, int clip_height )
6a2c1874
RR
118{
119}
120
4dbd4ee6 121void wxCanvasObject::Recreate()
1e1af41e
RR
122{
123}
124
125void wxCanvasObject::WriteSVG( wxTextOutputStream &stream )
6a2c1874
RR
126{
127}
128
fcbb6b37
KH
129//----------------------------------------------------------------------------
130// wxCanvasObjectGroup
131//----------------------------------------------------------------------------
132
133wxCanvasObjectGroup::wxCanvasObjectGroup()
134{
21840a6c
RR
135 m_validbounds = FALSE;
136}
137
138wxCanvasObjectGroup::~wxCanvasObjectGroup()
139{
fcbb6b37
KH
140}
141
142void 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
156void wxCanvasObjectGroup::ExtendArea(int x, int y)
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
176void wxCanvasObjectGroup::DeleteContents( bool flag)
177{
178 m_objects.DeleteContents( flag );
21840a6c 179 m_validbounds = FALSE;
fcbb6b37
KH
180}
181
fcbb6b37
KH
182void wxCanvasObjectGroup::Prepend( wxCanvasObject* obj )
183{
184 m_objects.Insert( obj );
21840a6c 185 m_validbounds = FALSE;
fcbb6b37
KH
186}
187
188void wxCanvasObjectGroup::Append( wxCanvasObject* obj )
189{
190 m_objects.Append( obj );
21840a6c 191 m_validbounds = FALSE;
fcbb6b37
KH
192}
193
194void wxCanvasObjectGroup::Insert( size_t before, wxCanvasObject* obj )
195{
196 m_objects.Insert( before, obj );
21840a6c 197 m_validbounds = FALSE;
fcbb6b37
KH
198}
199
200void wxCanvasObjectGroup::Remove( wxCanvasObject* obj )
201{
202 m_objects.DeleteObject( obj );
21840a6c 203 m_validbounds = FALSE;
fcbb6b37
KH
204}
205
206void 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
222void 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
272void wxCanvasObjectGroup::WriteSVG( wxTextOutputStream &stream )
273{
274}
275
276bool 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 {
287 return true;
288 }
289 }
290 node = node->Previous();
291 }
292 return false;
293}
294
295wxCanvasObject* 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 }
21840a6c
RR
312
313 return (wxCanvasObject*) NULL;
fcbb6b37
KH
314}
315
316//----------------------------------------------------------------------------
317// wxCanvasObjectGroupRef
318//----------------------------------------------------------------------------
319
320wxCanvasObjectGroupRef::wxCanvasObjectGroupRef(double x, double y, wxCanvasObjectGroup* group)
321 : wxCanvasObject()
322{
323 m_x = x;
324 m_y = y;
325 m_validbounds=false;
326 m_group=group;
327}
328
329void wxCanvasObjectGroupRef::SetOwner(wxCanvas* canvas)
330{
331 m_owner=canvas;
332 m_group->SetOwner(canvas);
333}
334
335void wxCanvasObjectGroupRef::ExtendArea(int x, int y)
336{
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;
347
348 m_minx = x;
349 m_miny = y;
350 m_maxx = x;
351 m_maxy = y;
352 }
353
354}
355
356void wxCanvasObjectGroupRef::Recreate()
357{
358 m_validbounds=false;
359 m_group->Recreate();
360 ExtendArea(m_group->GetXMin(),m_group->GetYMin());
361 ExtendArea(m_group->GetXMax(),m_group->GetYMax());
362
363 //set the area in pixels relative to the parent
364 SetArea( m_owner->GetDeviceX( m_x + m_minx ),
365 m_owner->GetDeviceY( m_y + m_miny ),
366 m_owner->GetDeviceWidth( m_maxx-m_minx ),
367 m_owner->GetDeviceHeight( m_maxy-m_miny ) );
368}
369
370void wxCanvasObjectGroupRef::Render(int xabs, int yabs, int x, int y, int width, int height )
371{
21840a6c
RR
372 xabs += m_owner->GetDeviceX(GetPosX());
373 yabs += m_owner->GetDeviceY(GetPosY());
fcbb6b37
KH
374
375 int clip_x = xabs + m_group->GetXMin();
376 int clip_width = m_group->GetXMax()-m_group->GetXMin();
377 if (clip_x < x)
378 {
379 clip_width -= x-clip_x;
380 clip_x = x;
381 }
382 if (clip_width > 0)
383 {
384 if (clip_x + clip_width > x + width)
385 clip_width = x+width-clip_x;
386
387 if (clip_width > 0)
388 {
389 int clip_y = yabs + m_group->GetYMin();
390 int clip_height = m_group->GetYMax()-m_group->GetYMin();
391 if (clip_y < y)
392 {
393 clip_height -= y-clip_y;
394 clip_y = y;
395 }
396 if (clip_height > 0)
397 {
398 if (clip_y + clip_height > y + height)
399 clip_height = y+height-clip_y;
400
401 if (clip_height > 0)
402 m_group->Render(xabs,yabs, clip_x, clip_y, clip_width, clip_height );
403 }
404 }
405 }
406}
407
408void wxCanvasObjectGroupRef::WriteSVG( wxTextOutputStream &stream )
409{
410}
411
412bool wxCanvasObjectGroupRef::IsHit( int x, int y, int margin )
413{
414 return m_group->IsHit(x-GetPosX(),y-GetPosY(),margin);
415}
416
417wxCanvasObject* wxCanvasObjectGroupRef::IsHitObject( int x, int y, int margin )
418{
419 return m_group->IsHitObject(x-GetPosX(),y-GetPosY(),margin);
420}
421
422void wxCanvasObjectGroupRef::Move( int x, int y )
423{
fcbb6b37
KH
424 m_x = x;
425 m_y = y;
426
427 if (!m_isControl)
428 {
429 // TODO: sometimes faster to merge into 1 Update or
430 // to break up into four
431 m_owner->Update(m_area.x, m_area.y, m_area.width, m_area.height );
432 //calculate the new area in pixels relative to the parent
433 SetArea( m_owner->GetDeviceX( m_x + m_minx ),
434 m_owner->GetDeviceY( m_y + m_miny ),
435 m_owner->GetDeviceWidth( m_maxx-m_minx ),
436 m_owner->GetDeviceHeight( m_maxy-m_miny ) );
437 m_owner->Update( m_area.x, m_area.y, m_area.width, m_area.height );
438 }
439}
440
441
21544859
RR
442//----------------------------------------------------------------------------
443// wxCanvasRect
444//----------------------------------------------------------------------------
445
dc16900b 446wxCanvasRect::wxCanvasRect( double x, double y, double w, double h,
4dbd4ee6
RR
447 unsigned char red, unsigned char green, unsigned char blue )
448 : wxCanvasObject()
21544859 449{
4dbd4ee6
RR
450 m_x = x;
451 m_y = y;
452 m_width = w;
453 m_height = h;
dc16900b 454
21544859
RR
455 m_red = red;
456 m_green = green;
457 m_blue = blue;
458}
459
4dbd4ee6
RR
460void wxCanvasRect::Recreate()
461{
462 SetArea( m_owner->GetDeviceX( m_x ),
463 m_owner->GetDeviceY( m_y ),
464 m_owner->GetDeviceWidth( m_width ),
465 m_owner->GetDeviceHeight( m_height ) );
466}
467
fcbb6b37 468void wxCanvasRect::Render(int xabs, int yabs, int clip_x, int clip_y, int clip_width, int clip_height )
21544859
RR
469{
470 wxImage *image = m_owner->GetBuffer();
41328253
RR
471 int buffer_x = m_owner->GetBufferX();
472 int buffer_y = m_owner->GetBufferY();
fcbb6b37 473
41328253
RR
474 int start_y = clip_y - buffer_y;
475 int end_y = clip_y+clip_height - buffer_y;
fcbb6b37 476
41328253
RR
477 int start_x = clip_x - buffer_x;
478 int end_x = clip_x+clip_width - buffer_x;
fcbb6b37 479
21544859 480 // speed up later
41328253
RR
481 for (int y = start_y; y < end_y; y++)
482 for (int x = start_x; x < end_x; x++)
21544859
RR
483 image->SetRGB( x, y, m_red, m_green, m_blue );
484}
485
486void wxCanvasRect::WriteSVG( wxTextOutputStream &stream )
487{
488}
489
239c1f50
RR
490//----------------------------------------------------------------------------
491// wxCanvasLine
492//----------------------------------------------------------------------------
493
4dbd4ee6
RR
494wxCanvasLine::wxCanvasLine( double x1, double y1, double x2, double y2,
495 unsigned char red, unsigned char green, unsigned char blue )
496 : wxCanvasObject()
239c1f50 497{
4dbd4ee6
RR
498 m_x1 = x1;
499 m_y1 = y1;
500 m_x2 = x2;
501 m_y2 = y2;
502
239c1f50
RR
503 m_red = red;
504 m_green = green;
505 m_blue = blue;
506}
507
4dbd4ee6
RR
508void wxCanvasLine::Recreate()
509{
510 int x1 = m_owner->GetDeviceX( m_x1 );
511 int y1 = m_owner->GetDeviceY( m_y1 );
512 int x2 = m_owner->GetDeviceX( m_x2 );
513 int y2 = m_owner->GetDeviceY( m_y2 );
514 if (x1 > x2)
515 {
516 int tmp = x1;
517 x1 = x2;
518 x2 = tmp;
519 }
520 if (y1 > y2)
521 {
522 int tmp = y1;
523 y1 = y2;
524 y2 = tmp;
525 }
526 SetArea( x1, y1, x2-x1+1, y2-y1+1 );
527}
528
fcbb6b37 529void wxCanvasLine::Render(int xabs, int yabs, int clip_x, int clip_y, int clip_width, int clip_height )
239c1f50
RR
530{
531 wxImage *image = m_owner->GetBuffer();
41328253
RR
532 int buffer_x = m_owner->GetBufferX();
533 int buffer_y = m_owner->GetBufferY();
fcbb6b37 534
239c1f50
RR
535 if ((m_area.width == 0) && (m_area.height == 0))
536 {
41328253 537 image->SetRGB( m_area.x-buffer_x, m_area.y-buffer_y, m_red, m_green, m_blue );
239c1f50
RR
538 }
539 else
540 {
fcbb6b37
KH
541 int x1 = xabs + m_owner->GetDeviceX( m_x1 );
542 int y1 = yabs + m_owner->GetDeviceY( m_y1 );
543 int x2 = xabs + m_owner->GetDeviceX( m_x2 );
544 int y2 = yabs + m_owner->GetDeviceY( m_y2 );
239c1f50
RR
545
546 wxInt32 d, ii, jj, di, ai, si, dj, aj, sj;
547 di = x1 - x2;
548 ai = abs(di) << 1;
549 si = (di < 0)? -1 : 1;
550 dj = y1 - y2;
551 aj = abs(dj) << 1;
552 sj = (dj < 0)? -1 : 1;
553
554 ii = x2;
555 jj = y2;
dc16900b 556
239c1f50
RR
557 if (ai > aj)
558 {
559 // iterate over i
dc16900b
KH
560 d = aj - (ai >> 1);
561
239c1f50
RR
562 while (ii != x1)
563 {
61b64bd9
RR
564 if ((ii >= clip_x) && (ii < clip_x+clip_width) &&
565 (jj >= clip_y) && (jj < clip_y+clip_height))
239c1f50 566 {
41328253 567 image->SetRGB( ii-buffer_x, jj-buffer_y, m_red, m_blue, m_green );
239c1f50
RR
568 }
569 if (d >= 0)
570 {
571 jj += sj;
dc16900b 572 d -= ai;
239c1f50
RR
573 }
574 ii += si;
575 d += aj;
576 }
577 }
578 else
579 {
580 // iterate over j
581 d = ai - (aj >> 1);
582
583 while (jj != y1)
584 {
61b64bd9
RR
585 if ((ii >= clip_x) && (ii < clip_x+clip_width) &&
586 (jj >= clip_y) && (jj < clip_y+clip_height))
239c1f50 587 {
41328253 588 image->SetRGB( ii-buffer_x, jj-buffer_y, m_red, m_blue, m_green );
239c1f50
RR
589 }
590 if (d >= 0)
591 {
592 ii += si;
dc16900b 593 d -= aj;
239c1f50
RR
594 }
595 jj += sj;
596 d += ai;
597 }
598 }
599 }
600}
601
602void wxCanvasLine::WriteSVG( wxTextOutputStream &stream )
603{
1e1af41e 604 // no idea
239c1f50
RR
605}
606
6a2c1874
RR
607//----------------------------------------------------------------------------
608// wxCanvasImage
609//----------------------------------------------------------------------------
610
4dbd4ee6
RR
611wxCanvasImage::wxCanvasImage( const wxImage &image, double x, double y, double w, double h )
612 : wxCanvasObject()
6a2c1874 613{
4dbd4ee6
RR
614 m_x = x;
615 m_y = y;
616 m_width = w;
617 m_height = h;
dc16900b 618
6a2c1874
RR
619 m_image = image;
620 m_isImage = TRUE;
621}
622
4dbd4ee6
RR
623void wxCanvasImage::Recreate()
624{
625 SetArea( m_owner->GetDeviceX( m_x ),
626 m_owner->GetDeviceY( m_y ),
627 m_owner->GetDeviceWidth( m_width ),
628 m_owner->GetDeviceHeight( m_height ) );
dc16900b 629
4dbd4ee6
RR
630 if ((m_area.width == m_image.GetWidth()) &&
631 (m_area.width == m_image.GetWidth()))
632 m_tmp = m_image;
633 else
634 m_tmp = m_image.Scale( m_area.width, m_area.height );
635}
636
fcbb6b37 637void wxCanvasImage::Render(int xabs, int yabs, int clip_x, int clip_y, int clip_width, int clip_height )
6a2c1874 638{
41328253
RR
639 int buffer_x = m_owner->GetBufferX();
640 int buffer_y = m_owner->GetBufferY();
fcbb6b37
KH
641
642 if ((clip_x == xabs + m_area.x) &&
643 (clip_y == yabs + m_area.y) &&
21544859
RR
644 (clip_width == m_area.width) &&
645 (clip_height == m_area.height))
d1f9b206 646 {
41328253 647 m_owner->GetBuffer()->Paste( m_tmp, clip_x-buffer_x, clip_y-buffer_y );
d1f9b206
RR
648 }
649 else
650 {
21544859 651 // local coordinates
fcbb6b37
KH
652 int start_x = clip_x - (xabs + m_area.x);
653 int start_y = clip_y - (yabs + m_area.y);
dc16900b 654
21544859 655 wxRect rect( start_x, start_y, clip_width, clip_height );
4dbd4ee6 656 wxImage sub_image( m_tmp.GetSubImage( rect ) );
41328253 657 m_owner->GetBuffer()->Paste( sub_image, clip_x-buffer_x, clip_y-buffer_y );
d1f9b206 658 }
6a2c1874
RR
659}
660
661void wxCanvasImage::WriteSVG( wxTextOutputStream &stream )
662{
663 // no idea
664}
665
3b111dbe
RR
666//----------------------------------------------------------------------------
667// wxCanvasCtrl
668//----------------------------------------------------------------------------
669
670wxCanvasControl::wxCanvasControl( wxWindow *control )
4dbd4ee6 671 : wxCanvasObject()
3b111dbe 672{
21544859 673 m_isControl = TRUE;
3b111dbe 674 m_control = control;
3b111dbe
RR
675}
676
677wxCanvasControl::~wxCanvasControl()
678{
679 m_control->Destroy();
680}
681
4dbd4ee6 682void wxCanvasControl::Recreate()
3b111dbe 683{
4dbd4ee6
RR
684 m_control->GetSize( &m_area.width, &m_area.height );
685 m_control->GetPosition( &m_area.x, &m_area.y );
3b111dbe
RR
686}
687
4dbd4ee6 688void wxCanvasControl::Move( int x, int y )
3b111dbe 689{
4dbd4ee6 690 m_control->Move( x, y );
3b111dbe
RR
691}
692
d1f9b206
RR
693//----------------------------------------------------------------------------
694// wxCanvasText
695//----------------------------------------------------------------------------
696
697class wxFaceData
698{
699public:
1e1af41e 700#if wxUSE_FREETYPE
d1f9b206
RR
701 FT_Face m_face;
702#else
703 void *m_dummy;
dc16900b 704#endif
d1f9b206
RR
705};
706
4dbd4ee6
RR
707wxCanvasText::wxCanvasText( const wxString &text, double x, double y, const wxString &fontFile, int size )
708 : wxCanvasObject()
d1f9b206
RR
709{
710 m_text = text;
cb281cfc
RR
711 m_fontFileName = fontFile;
712 m_size = size;
dc16900b 713
cb281cfc 714 m_red = 0;
d1f9b206
RR
715 m_green = 0;
716 m_blue = 0;
dc16900b 717
4dbd4ee6 718 m_alpha = NULL;
dc16900b 719
4dbd4ee6
RR
720 m_x = x;
721 m_y = y;
dc16900b
KH
722
723#if wxUSE_FREETYPE
d1f9b206
RR
724 wxFaceData *data = new wxFaceData;
725 m_faceData = data;
dc16900b 726
d1f9b206 727 int error = FT_New_Face( g_freetypeLibrary,
cb281cfc 728 m_fontFileName,
d1f9b206
RR
729 0,
730 &(data->m_face) );
731
732 error = FT_Set_Char_Size( data->m_face,
733 0,
cb281cfc
RR
734 m_size*64,
735 96, // screen dpi
d1f9b206
RR
736 96 );
737#endif
738}
739
740wxCanvasText::~wxCanvasText()
741{
fcbb6b37 742#if wxUSE_FREETYPE
d1f9b206
RR
743 wxFaceData *data = (wxFaceData*) m_faceData;
744 delete data;
745#endif
746
747 if (m_alpha) delete [] m_alpha;
748}
749
750void wxCanvasText::SetRGB( unsigned char red, unsigned char green, unsigned char blue )
751{
752 m_red = red;
753 m_green = green;
754 m_blue = blue;
755}
756
757void wxCanvasText::SetFlag( int flag )
758{
759 m_flag = flag;
760}
761
fcbb6b37 762void wxCanvasText::Render(int xabs, int yabs, int clip_x, int clip_y, int clip_width, int clip_height )
d1f9b206
RR
763{
764 if (!m_alpha) return;
fcbb6b37 765
d1f9b206 766 wxImage *image = m_owner->GetBuffer();
41328253
RR
767 int buffer_x = m_owner->GetBufferX();
768 int buffer_y = m_owner->GetBufferY();
d1f9b206 769
21544859
RR
770 // local coordinates
771 int start_x = clip_x - m_area.x;
772 int end_x = clip_width + start_x;
773 int start_y = clip_y - m_area.y;
774 int end_y = clip_height + start_y;
fcbb6b37 775
d1f9b206
RR
776 for (int y = start_y; y < end_y; y++)
777 for (int x = start_x; x < end_x; x++)
778 {
779 int alpha = m_alpha[y*m_area.width + x];
780 if (alpha)
781 {
41328253
RR
782 int image_x = m_area.x+x - buffer_x;
783 int image_y = m_area.y+y - buffer_y;
cb281cfc 784 if (alpha == 255)
d1f9b206
RR
785 {
786 image->SetRGB( image_x, image_y, m_red, m_green, m_blue );
787 continue;
788 }
cb281cfc
RR
789 int red1 = (m_red * alpha) / 255;
790 int green1 = (m_green * alpha) / 255;
791 int blue1 = (m_blue * alpha) / 255;
dc16900b 792
cb281cfc 793 alpha = 255-alpha;
d1f9b206
RR
794 int red2 = image->GetRed( image_x, image_y );
795 int green2 = image->GetGreen( image_x, image_y );
796 int blue2 = image->GetBlue( image_x, image_y );
cb281cfc
RR
797 red2 = (red2 * alpha) / 255;
798 green2 = (green2 * alpha) / 255;
799 blue2 = (blue2 * alpha) / 255;
fcbb6b37 800
d1f9b206
RR
801 image->SetRGB( image_x, image_y, red1+red2, green1+green2, blue1+blue2 );
802 }
803 }
804}
805
806void wxCanvasText::WriteSVG( wxTextOutputStream &stream )
807{
808}
809
4dbd4ee6 810void wxCanvasText::Recreate()
d1f9b206 811{
4dbd4ee6 812 if (m_alpha) delete [] m_alpha;
dc16900b 813
4dbd4ee6
RR
814 m_area.x = m_owner->GetDeviceX( m_x );
815 m_area.y = m_owner->GetDeviceY( m_y );
dc16900b 816
4dbd4ee6
RR
817 m_area.width = 100; // TODO, calculate length
818 m_area.height = m_size;
819 m_alpha = new unsigned char[100*m_size];
820 memset( m_alpha, 0, m_area.width*m_area.height );
fcbb6b37
KH
821
822#if wxUSE_FREETYPE
d1f9b206
RR
823 FT_Face face = ((wxFaceData*)m_faceData)->m_face;
824 FT_GlyphSlot slot = face->glyph;
825 int pen_x = 0;
cb281cfc 826 int pen_y = m_size;
fcbb6b37 827
cb281cfc 828 for (int n = 0; n < (int)m_text.Len(); n++)
d1f9b206
RR
829 {
830 FT_UInt index = FT_Get_Char_Index( face, m_text[n] );
dc16900b 831
d1f9b206
RR
832 int error = FT_Load_Glyph( face, index, FT_LOAD_DEFAULT );
833 if (error) continue;
fcbb6b37 834
cb281cfc 835 error = FT_Render_Glyph( face->glyph, ft_render_mode_normal );
d1f9b206 836 if (error) continue;
fcbb6b37 837
cb281cfc
RR
838 FT_Bitmap *bitmap = &slot->bitmap;
839 unsigned char* buffer = bitmap->buffer;
840 for (int y = 0; y < bitmap->rows; y++)
841 for (int x = 0; x < bitmap->width; x++)
842 {
843 unsigned char alpha = buffer[ y*bitmap->pitch + x ];
844 if (alpha == 0) continue;
dc16900b 845
cb281cfc
RR
846 int xx = pen_x + slot->bitmap_left + x;
847 int yy = pen_y - slot->bitmap_top + y;
848 m_alpha[ yy * m_area.width + xx ] = alpha;
849 }
fcbb6b37 850
d1f9b206
RR
851 pen_x += slot->advance.x >> 6;
852 pen_y += slot->advance.y >> 6;
fcbb6b37 853 }
d1f9b206
RR
854#endif
855}
856
6a2c1874
RR
857//----------------------------------------------------------------------------
858// wxCanvas
859//----------------------------------------------------------------------------
860
861IMPLEMENT_CLASS(wxCanvas,wxScrolledWindow)
862
863BEGIN_EVENT_TABLE(wxCanvas,wxScrolledWindow)
864 EVT_CHAR( wxCanvas::OnChar )
865 EVT_PAINT( wxCanvas::OnPaint )
866 EVT_SIZE( wxCanvas::OnSize )
867 EVT_IDLE( wxCanvas::OnIdle )
868 EVT_MOUSE_EVENTS( wxCanvas::OnMouse )
869 EVT_SET_FOCUS( wxCanvas::OnSetFocus )
870 EVT_KILL_FOCUS( wxCanvas::OnKillFocus )
61b64bd9 871 EVT_ERASE_BACKGROUND( wxCanvas::OnEraseBackground )
6a2c1874
RR
872END_EVENT_TABLE()
873
874wxCanvas::wxCanvas( wxWindow *parent, wxWindowID id,
875 const wxPoint &position, const wxSize& size, long style ) :
876 wxScrolledWindow( parent, id, position, size, style )
877{
41328253
RR
878 m_bufferX = 0;
879 m_bufferY = 0;
6a2c1874 880 m_needUpdate = FALSE;
cb281cfc
RR
881 m_red = 0;
882 m_green = 0;
883 m_blue = 0;
239c1f50 884 m_lastMouse = (wxCanvasObject*)NULL;
4dbd4ee6 885 m_captureMouse = (wxCanvasObject*)NULL;
41328253
RR
886 m_frozen = TRUE;
887 m_requestNewBuffer = TRUE;
fcbb6b37
KH
888
889 //root group always at 0,0
890 m_root = new wxCanvasObjectGroup();
891 m_root->DeleteContents( TRUE );
892 m_root->SetOwner(this);
6a2c1874
RR
893}
894
895wxCanvas::~wxCanvas()
896{
897 wxNode *node = m_updateRects.First();
898 while (node)
899 {
900 wxRect *rect = (wxRect*) node->Data();
901 delete rect;
902 m_updateRects.DeleteNode( node );
903 node = m_updateRects.First();
904 }
905}
906
907void wxCanvas::SetArea( int width, int height )
908{
6a2c1874
RR
909 SetScrollbars( 10, 10, width/10, height/10 );
910}
911
cb281cfc
RR
912void wxCanvas::SetColour( unsigned char red, unsigned char green, unsigned char blue )
913{
914 m_red = red;
915 m_green = green;
916 m_blue = blue;
dc16900b 917
61b64bd9
RR
918 SetBackgroundColour( wxColour( red, green, blue ) );
919
239c1f50 920 if (m_frozen) return;
dc16900b 921
cb281cfc 922 unsigned char *data = m_buffer.GetData();
dc16900b 923
cb281cfc
RR
924 for (int y = 0; y < m_buffer.GetHeight(); y++)
925 for (int x = 0; x < m_buffer.GetWidth(); x++)
926 {
927 data[0] = red;
928 data++;
929 data[0] = green;
930 data++;
931 data[0] = blue;
932 data++;
933 }
934}
935
dc16900b 936void wxCanvas::SetCaptureMouse( wxCanvasObject *obj )
4dbd4ee6 937{
dc16900b
KH
938 if (obj)
939 {
940 wxWindow::CaptureMouse();
941 m_captureMouse = obj;
942 }
943 else
944 {
945 wxWindow::ReleaseMouse();
946 m_captureMouse = NULL;
947 }
4dbd4ee6
RR
948}
949
239c1f50
RR
950void wxCanvas::Freeze()
951{
952 m_frozen = TRUE;
953}
954
955void wxCanvas::Thaw()
956{
957 wxNode *node = m_updateRects.First();
958 while (node)
959 {
960 wxRect *rect = (wxRect*) node->Data();
961 delete rect;
962 m_updateRects.DeleteNode( node );
963 node = m_updateRects.First();
964 }
dc16900b 965
239c1f50 966 m_frozen = FALSE;
dc16900b 967
41328253
RR
968 if (m_buffer.Ok())
969 Update( m_bufferX, m_bufferY, m_buffer.GetWidth(), m_buffer.GetHeight() );
239c1f50
RR
970}
971
41328253 972void wxCanvas::Update( int x, int y, int width, int height, bool blit )
6a2c1874 973{
239c1f50 974 if (m_frozen) return;
fcbb6b37 975
21544859 976 // clip to buffer
41328253 977 if (x < m_bufferX)
21544859 978 {
41328253
RR
979 width -= m_bufferX-x;
980 x = m_bufferX;
21544859
RR
981 }
982 if (width < 0) return;
dc16900b 983
41328253 984 if (y < m_bufferY)
21544859 985 {
41328253
RR
986 height -= m_bufferY-y;
987 y = m_bufferY;
21544859
RR
988 }
989 if (height < 0) return;
dc16900b 990
41328253 991 if (x+width > m_bufferX+m_buffer.GetWidth())
21544859 992 {
41328253 993 width = m_bufferX+m_buffer.GetWidth() - x;
21544859
RR
994 }
995 if (width < 0) return;
dc16900b 996
41328253 997 if (y+height > m_bufferY+m_buffer.GetHeight())
21544859 998 {
41328253 999 height = m_bufferY+m_buffer.GetHeight() - y;
21544859
RR
1000 }
1001 if (height < 0) return;
dc16900b 1002
21544859 1003 // update is within the buffer
6a2c1874 1004 m_needUpdate = TRUE;
dc16900b 1005
21544859 1006 // has to be blitted to screen later
41328253
RR
1007 if (blit)
1008 {
1009 m_updateRects.Append(
1010 (wxObject*) new wxRect( x,y,width,height ) );
1011 }
dc16900b 1012
21544859 1013 // speed up with direct access, maybe add wxImage::Clear(x,y,w,h,r,g,b)
41328253
RR
1014 int start_y = y - m_bufferY;
1015 int end_y = y+height - m_bufferY;
1016 int start_x = x - m_bufferX;
1017 int end_x = x+width - m_bufferX;
1018 for (int yy = start_y; yy < end_y; yy++)
1019 for (int xx = start_x; xx < end_x; xx++)
cb281cfc 1020 m_buffer.SetRGB( xx, yy, m_red, m_green, m_blue );
6a2c1874 1021
fcbb6b37 1022 m_root->Render(0,0, x, y, width, height );
dc16900b 1023
6a2c1874
RR
1024}
1025
3b111dbe 1026void wxCanvas::BlitBuffer( wxDC &dc )
6a2c1874 1027{
6a2c1874
RR
1028 wxNode *node = m_updateRects.First();
1029 while (node)
1030 {
1031 wxRect *rect = (wxRect*) node->Data();
6a2c1874 1032
41328253
RR
1033 wxRect sub_rect( *rect );
1034 sub_rect.x -= m_bufferX;
1035 sub_rect.y -= m_bufferY;
fcbb6b37 1036
41328253 1037 wxImage sub_image( m_buffer.GetSubImage( sub_rect ) );
6a2c1874
RR
1038
1039#ifdef __WXGTK__
dc16900b 1040 int bpp = wxDisplayDepth();
6a2c1874
RR
1041 if (bpp > 8)
1042 {
1043 // the init code is doubled in wxImage
1044 static bool s_hasInitialized = FALSE;
1045
1046 if (!s_hasInitialized)
1047 {
1048 gdk_rgb_init();
1049 s_hasInitialized = TRUE;
1050 }
dc16900b 1051
6a2c1874
RR
1052 gdk_draw_rgb_image( GTK_PIZZA(m_wxwindow)->bin_window,
1053 m_wxwindow->style->black_gc,
41328253 1054 sub_rect.x, sub_rect.y,
6a2c1874
RR
1055 sub_image.GetWidth(), sub_image.GetHeight(),
1056 GDK_RGB_DITHER_NONE,
1057 sub_image.GetData(),
1058 sub_image.GetWidth()*3 );
1059 }
1060 else
1061 {
1062 wxBitmap bitmap( sub_image.ConvertToBitmap() );
1063 dc.DrawBitmap( bitmap, rect->x, rect->y );
1064 }
1065#endif
1066
1067#ifndef __WXGTK__
1068 wxBitmap bitmap( sub_image.ConvertToBitmap() );
1069 dc.DrawBitmap( bitmap, rect->x, rect->y );
1070#endif
dc16900b 1071
6a2c1874
RR
1072 delete rect;
1073 m_updateRects.DeleteNode( node );
1074 node = m_updateRects.First();
1075 }
dc16900b 1076
3b111dbe
RR
1077 m_needUpdate = FALSE;
1078}
1079
1080void wxCanvas::UpdateNow()
1081{
61b64bd9
RR
1082 if (m_frozen) return;
1083
3b111dbe 1084 if (!m_needUpdate) return;
dc16900b 1085
3b111dbe
RR
1086 wxClientDC dc( this );
1087 PrepareDC( dc );
dc16900b 1088
3b111dbe 1089 BlitBuffer( dc );
6a2c1874
RR
1090}
1091
4dbd4ee6
RR
1092int wxCanvas::GetDeviceX( double x )
1093{
1094 return (int) x;
1095}
1096
1097int wxCanvas::GetDeviceY( double y )
1098{
1099 return (int) y;
1100}
1101
1102int wxCanvas::GetDeviceWidth( double width )
1103{
1104 return (int) width;
1105}
1106
1107int wxCanvas::GetDeviceHeight( double height )
1108{
1109 return (int) height;
1110}
1111
1112void wxCanvas::Recreate()
1113{
fcbb6b37 1114 m_root->Recreate();
4dbd4ee6
RR
1115}
1116
6a2c1874
RR
1117void wxCanvas::Prepend( wxCanvasObject* obj )
1118{
fcbb6b37
KH
1119 m_root->Prepend( obj );
1120 obj->SetOwner(this);
dc16900b 1121
fcbb6b37 1122 m_root->Recreate();
dc16900b 1123
6a2c1874
RR
1124 if (!obj->IsControl())
1125 Update( obj->GetX(), obj->GetY(), obj->GetWidth(), obj->GetHeight() );
1126}
1127
1128void wxCanvas::Append( wxCanvasObject* obj )
1129{
fcbb6b37
KH
1130 m_root->Append( obj );
1131 obj->SetOwner(this);
dc16900b 1132
fcbb6b37 1133 m_root->Recreate();
dc16900b 1134
6a2c1874
RR
1135 if (!obj->IsControl())
1136 Update( obj->GetX(), obj->GetY(), obj->GetWidth(), obj->GetHeight() );
1137}
1138
1139void wxCanvas::Insert( size_t before, wxCanvasObject* obj )
1140{
fcbb6b37
KH
1141 m_root->Insert( before, obj );
1142 obj->SetOwner(this);
dc16900b 1143
fcbb6b37 1144 m_root->Recreate();
dc16900b 1145
6a2c1874
RR
1146 if (!obj->IsControl())
1147 Update( obj->GetX(), obj->GetY(), obj->GetWidth(), obj->GetHeight() );
1148}
1149
1150void wxCanvas::Remove( wxCanvasObject* obj )
1151{
1152 int x = obj->GetX();
1153 int y = obj->GetY();
1154 int w = obj->GetWidth();
1155 int h = obj->GetHeight();
1156 bool ic = obj->IsControl();
dc16900b 1157
fcbb6b37 1158 m_root->Remove( obj );
dc16900b 1159
6a2c1874
RR
1160 if (!ic)
1161 Update( x, y, w, h );
1162}
1163
1164void wxCanvas::OnPaint(wxPaintEvent &event)
1165{
6a2c1874 1166 wxPaintDC dc(this);
3b111dbe 1167 PrepareDC( dc );
dc16900b 1168
41328253 1169 if (!m_buffer.Ok()) return;
fcbb6b37 1170
b85cfb6f 1171 if (m_frozen) return;
41328253 1172
6a2c1874
RR
1173 m_needUpdate = TRUE;
1174
1175 wxRegionIterator it( GetUpdateRegion() );
1176 while (it)
1177 {
1178 int x = it.GetX();
1179 int y = it.GetY();
dc16900b 1180
6a2c1874
RR
1181 int w = it.GetWidth();
1182 int h = it.GetHeight();
dc16900b 1183
21544859
RR
1184 if (x+w > m_buffer.GetWidth())
1185 w = m_buffer.GetWidth() - x;
1186 if (y+h > m_buffer.GetHeight())
1187 h = m_buffer.GetHeight() - y;
dc16900b 1188
21544859 1189 if ((w > 0) && (h > 0))
41328253
RR
1190 {
1191 CalcUnscrolledPosition( x, y, &x, &y );
21544859 1192 m_updateRects.Append( (wxObject*) new wxRect( x, y, w, h ) );
41328253 1193 }
dc16900b 1194
6a2c1874
RR
1195 it++;
1196 }
dc16900b 1197
3b111dbe 1198 BlitBuffer( dc );
6a2c1874
RR
1199}
1200
41328253
RR
1201void wxCanvas::ScrollWindow( int dx, int dy, const wxRect* rect )
1202{
61b64bd9
RR
1203 // If any updates are pending, do them now since they will
1204 // expect the previous m_bufferX and m_bufferY values.
41328253
RR
1205 UpdateNow();
1206
61b64bd9
RR
1207 // The buffer always starts at the top left corner of the
1208 // client area. Indeed, it is the client area.
41328253
RR
1209 CalcUnscrolledPosition( 0, 0, &m_bufferX, &m_bufferY );
1210
1211 unsigned char* data = m_buffer.GetData();
fcbb6b37 1212
41328253
RR
1213 if (dy != 0)
1214 {
1215 if (dy > 0)
1216 {
1217 unsigned char *source = data;
1218 unsigned char *dest = data + (dy * m_buffer.GetWidth() * 3);
1219 size_t count = (size_t) (m_buffer.GetWidth() * 3 * (m_buffer.GetHeight()-dy));
1220 memmove( dest, source, count );
fcbb6b37 1221
61b64bd9
RR
1222 // We update the new buffer area, but there is no need to
1223 // blit (last param FALSE) since the ensuing paint event will
1224 // do that anyway.
41328253
RR
1225 Update( m_bufferX, m_bufferY, m_buffer.GetWidth(), dy, FALSE );
1226 }
1227 else
1228 {
1229 unsigned char *dest = data;
1230 unsigned char *source = data + (-dy * m_buffer.GetWidth() * 3);
1231 size_t count = (size_t) (m_buffer.GetWidth() * 3 * (m_buffer.GetHeight()+dy));
1232 memmove( dest, source, count );
fcbb6b37 1233
61b64bd9
RR
1234 // We update the new buffer area, but there is no need to
1235 // blit (last param FALSE) since the ensuing paint event will
1236 // do that anyway.
41328253
RR
1237 Update( m_bufferX, m_bufferY+m_buffer.GetHeight()+dy, m_buffer.GetWidth(), -dy, FALSE );
1238 }
1239 }
fcbb6b37 1240
41328253
RR
1241 if (dx != 0)
1242 {
61b64bd9
RR
1243 if (dx > 0)
1244 {
1245 unsigned char *source = data;
1246 for (int y = 0; y < m_buffer.GetHeight(); y++)
1247 {
1248 unsigned char *dest = source + dx*3;
1249 memmove( dest, source, (m_buffer.GetWidth()-dx) * 3 );
1250 source += m_buffer.GetWidth()*3;
1251 }
fcbb6b37 1252
61b64bd9
RR
1253 // We update the new buffer area, but there is no need to
1254 // blit (last param FALSE) since the ensuing paint event will
1255 // do that anyway.
1256 Update( m_bufferX, m_bufferY, dx, m_buffer.GetHeight(), FALSE );
1257 }
1258 else
1259 {
1260 unsigned char *dest = data;
1261 for (int y = 0; y < m_buffer.GetHeight(); y++)
1262 {
1263 unsigned char *source = dest - dx*3;
1264 memmove( dest, source, (m_buffer.GetWidth()+dx) * 3 );
1265 dest += m_buffer.GetWidth()*3;
1266 }
fcbb6b37 1267
61b64bd9
RR
1268 // We update the new buffer area, but there is no need to
1269 // blit (last param FALSE) since the ensuing paint event will
1270 // do that anyway.
1271 Update( m_bufferX+m_buffer.GetWidth()+dx, m_bufferY, -dx, m_buffer.GetHeight(), FALSE );
1272 }
41328253
RR
1273 }
1274
1275 wxWindow::ScrollWindow( dx, dy, rect );
1276}
1277
6a2c1874
RR
1278void wxCanvas::OnMouse(wxMouseEvent &event)
1279{
239c1f50
RR
1280 int x = event.GetX();
1281 int y = event.GetY();
1282 CalcUnscrolledPosition( x, y, &x, &y );
dc16900b 1283
239c1f50
RR
1284 if (event.GetEventType() == wxEVT_MOTION)
1285 {
dc16900b 1286 if (m_captureMouse) //no matter what go to this one
239c1f50 1287 {
dc16900b
KH
1288 wxMouseEvent child_event( wxEVT_MOTION );
1289 child_event.SetEventObject(m_captureMouse);
1290 child_event.m_x = x - m_captureMouse->GetX();
1291 child_event.m_y = y - m_captureMouse->GetY();
1292 child_event.m_leftDown = event.m_leftDown;
1293 child_event.m_rightDown = event.m_rightDown;
1294 child_event.m_middleDown = event.m_middleDown;
1295 child_event.m_controlDown = event.m_controlDown;
1296 child_event.m_shiftDown = event.m_shiftDown;
1297 child_event.m_altDown = event.m_altDown;
1298 child_event.m_metaDown = event.m_metaDown;
872f1044 1299
dc16900b 1300 m_captureMouse->ProcessEvent( child_event );
872f1044 1301 return;
dc16900b
KH
1302 }
1303 else
1304 {
fcbb6b37 1305 wxCanvasObject *obj = m_root->IsHitObject(x,y,0);
dc16900b 1306
fcbb6b37
KH
1307 if (obj && !obj->IsControl())
1308 {
1309 wxMouseEvent child_event( wxEVT_MOTION );
1310 child_event.SetEventObject( obj );
1311 child_event.m_x = x - obj->GetX();
1312 child_event.m_y = y - obj->GetY();
1313 child_event.m_leftDown = event.m_leftDown;
1314 child_event.m_rightDown = event.m_rightDown;
1315 child_event.m_middleDown = event.m_middleDown;
1316 child_event.m_controlDown = event.m_controlDown;
1317 child_event.m_shiftDown = event.m_shiftDown;
1318 child_event.m_altDown = event.m_altDown;
1319 child_event.m_metaDown = event.m_metaDown;
1320
1321 if ((obj != m_lastMouse) && (m_lastMouse != NULL))
239c1f50 1322 {
fcbb6b37
KH
1323 child_event.SetEventType( wxEVT_LEAVE_WINDOW );
1324 child_event.SetEventObject( m_lastMouse );
1325 child_event.m_x = x - m_lastMouse->GetX();
1326 child_event.m_y = y - m_lastMouse->GetY();
1327 m_lastMouse->ProcessEvent( child_event );
1328
1329 m_lastMouse = obj;
1330 child_event.SetEventType( wxEVT_ENTER_WINDOW );
1331 child_event.SetEventObject( m_lastMouse );
1332 child_event.m_x = x - m_lastMouse->GetX();
1333 child_event.m_y = y - m_lastMouse->GetY();
1334 m_lastMouse->ProcessEvent( child_event );
1335
1336 child_event.SetEventType( wxEVT_MOTION );
1337 child_event.SetEventObject( obj );
239c1f50 1338 }
872f1044 1339
fcbb6b37
KH
1340 obj->ProcessEvent( child_event );
1341 return;
239c1f50 1342 }
239c1f50
RR
1343 }
1344 if (m_lastMouse)
1345 {
1346 wxMouseEvent child_event( wxEVT_LEAVE_WINDOW );
1347 child_event.SetEventObject( m_lastMouse );
1e1af41e
RR
1348 child_event.m_x = x - m_lastMouse->GetX();
1349 child_event.m_y = y - m_lastMouse->GetY();
239c1f50
RR
1350 child_event.m_leftDown = event.m_leftDown;
1351 child_event.m_rightDown = event.m_rightDown;
1352 child_event.m_middleDown = event.m_middleDown;
1353 child_event.m_controlDown = event.m_controlDown;
1354 child_event.m_shiftDown = event.m_shiftDown;
1355 child_event.m_altDown = event.m_altDown;
1356 child_event.m_metaDown = event.m_metaDown;
1357 m_lastMouse->ProcessEvent( child_event );
dc16900b 1358
239c1f50
RR
1359 m_lastMouse = (wxCanvasObject*) NULL;
1360 return;
1361 }
1362 }
872f1044
RR
1363 else
1364 {
1365 if (m_captureMouse) //no matter what go to this one
1366 {
1367 wxMouseEvent child_event( event.GetEventType() );
1368 child_event.SetEventObject(m_captureMouse);
1369 child_event.m_x = x - m_captureMouse->GetX();
1370 child_event.m_y = y - m_captureMouse->GetY();
1371 child_event.m_leftDown = event.m_leftDown;
1372 child_event.m_rightDown = event.m_rightDown;
1373 child_event.m_middleDown = event.m_middleDown;
1374 child_event.m_controlDown = event.m_controlDown;
1375 child_event.m_shiftDown = event.m_shiftDown;
1376 child_event.m_altDown = event.m_altDown;
1377 child_event.m_metaDown = event.m_metaDown;
1378 m_captureMouse->ProcessEvent( child_event );
1379 }
1380 else
1381 {
1382 wxCanvasObject *obj = m_root->IsHitObject(x,y,0);
1383
1384 if (obj && !obj->IsControl())
1385 {
1386 wxMouseEvent child_event( event.GetEventType() );
1387 child_event.SetEventObject( obj );
1388 child_event.m_x = x - obj->GetX();
1389 child_event.m_y = y - obj->GetY();
1390 child_event.m_leftDown = event.m_leftDown;
1391 child_event.m_rightDown = event.m_rightDown;
1392 child_event.m_middleDown = event.m_middleDown;
1393 child_event.m_controlDown = event.m_controlDown;
1394 child_event.m_shiftDown = event.m_shiftDown;
1395 child_event.m_altDown = event.m_altDown;
1396 child_event.m_metaDown = event.m_metaDown;
1397
1398 obj->ProcessEvent( child_event );
1399 return;
1400 }
1401 }
1402 }
fcbb6b37 1403
239c1f50 1404 event.Skip();
6a2c1874
RR
1405}
1406
1407void wxCanvas::OnSize(wxSizeEvent &event)
1408{
b85cfb6f
RR
1409 int w,h;
1410 GetClientSize( &w, &h );
1411 m_buffer = wxImage( w, h );
fcbb6b37 1412
b85cfb6f 1413 CalcUnscrolledPosition( 0, 0, &m_bufferX, &m_bufferY );
fcbb6b37 1414
b85cfb6f
RR
1415 wxNode *node = m_updateRects.First();
1416 while (node)
1417 {
1418 wxRect *rect = (wxRect*) node->Data();
1419 delete rect;
1420 m_updateRects.DeleteNode( node );
1421 node = m_updateRects.First();
1422 }
1423
1424 m_frozen = FALSE;
1425
1426 Update( m_bufferX, m_bufferY, m_buffer.GetWidth(), m_buffer.GetHeight(), FALSE );
41328253 1427
6a2c1874
RR
1428 event.Skip();
1429}
1430
1431void wxCanvas::OnIdle(wxIdleEvent &event)
1432{
1433 UpdateNow();
1434 event.Skip();
1435}
1436
1437void wxCanvas::OnSetFocus(wxFocusEvent &event)
1438{
1439}
1440
1441void wxCanvas::OnKillFocus(wxFocusEvent &event)
1442{
1443}
1444
1445void wxCanvas::OnChar(wxKeyEvent &event)
1446{
1447 event.Skip();
1448}
1449
61b64bd9
RR
1450void wxCanvas::OnEraseBackground(wxEraseEvent &event)
1451{
1452}
1453
d1f9b206
RR
1454//--------------------------------------------------------------------
1455// wxCanvasModule
1456//--------------------------------------------------------------------
1457
1458class wxCanvasModule : public wxModule
1459{
1460public:
1461 virtual bool OnInit();
1462 virtual void OnExit();
1463
1464private:
1465 DECLARE_DYNAMIC_CLASS(wxCanvasModule)
1466};
1467
1468IMPLEMENT_DYNAMIC_CLASS(wxCanvasModule, wxModule)
6a2c1874 1469
d1f9b206
RR
1470bool wxCanvasModule::OnInit()
1471{
1e1af41e 1472#if wxUSE_FREETYPE
d1f9b206
RR
1473 int error = FT_Init_FreeType( &g_freetypeLibrary );
1474 if (error) return FALSE;
1475#endif
1476
1477 return TRUE;
1478}
1479
1480void wxCanvasModule::OnExit()
1481{
1e1af41e 1482#if wxUSE_FREETYPE
cb281cfc 1483 FT_Done_FreeType( g_freetypeLibrary );
d1f9b206
RR
1484#endif
1485}