1 /////////////////////////////////////////////////////////////////////////////
3 // Author: Robert Roebling
5 // Copyright: 2000 (c) Robert Roebling
6 // Licence: wxWindows Licence
7 /////////////////////////////////////////////////////////////////////////////
10 #pragma implementation "canvas.cpp"
13 // For compilers that support precompilation, includes "wx/wx.h".
14 #include "wx/wxprec.h"
20 #include "wx/canvas/canvas.h"
24 #include <gdk/gdkrgb.h>
25 #include "wx/gtk/win_gtk.h"
28 #ifndef wxUSE_FREETYPE
29 #define wxUSE_FREETYPE 1
33 #include <freetype/freetype.h>
36 //----------------------------------------------------------------------------
38 //----------------------------------------------------------------------------
41 FT_Library g_freetypeLibrary
;
44 //----------------------------------------------------------------------------
46 //----------------------------------------------------------------------------
48 wxCanvasObject::wxCanvasObject()
60 void wxCanvasObject::SetArea( int x
, int y
, int width
, int height
)
65 m_area
.height
= height
;
68 void wxCanvasObject::SetArea( wxRect rect
)
72 m_area
.width
= rect
.width
;
73 m_area
.height
= rect
.height
;
76 void wxCanvasObject::Move( int x
, int y
)
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
);
93 bool wxCanvasObject::IsHit( int x
, int y
, int margin
)
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
));
101 void wxCanvasObject::CaptureMouse()
103 m_owner
->SetCaptureMouse( this );
106 void wxCanvasObject::ReleaseMouse()
108 m_owner
->SetCaptureMouse( NULL
);
111 bool wxCanvasObject::IsCapturedMouse()
113 return m_owner
->m_captureMouse
==this;
117 void wxCanvasObject::Render(int xabs
, int yabs
, int clip_x
, int clip_y
, int clip_width
, int clip_height
)
121 void wxCanvasObject::Recreate()
125 void wxCanvasObject::WriteSVG( wxTextOutputStream
&stream
)
129 //----------------------------------------------------------------------------
130 // wxCanvasObjectGroup
131 //----------------------------------------------------------------------------
133 wxCanvasObjectGroup::wxCanvasObjectGroup()
135 m_validbounds
= FALSE
;
138 wxCanvasObjectGroup::~wxCanvasObjectGroup()
142 void wxCanvasObjectGroup::SetOwner(wxCanvas
* canvas
)
145 wxNode
*node
= m_objects
.First();
148 wxCanvasObject
*obj
= (wxCanvasObject
*) node
->Data();
150 obj
->SetOwner(canvas
);
156 void wxCanvasObjectGroup::ExtendArea(double x
, double y
)
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
;
167 m_validbounds
= TRUE
;
176 void wxCanvasObjectGroup::DeleteContents( bool flag
)
178 m_objects
.DeleteContents( flag
);
179 m_validbounds
= FALSE
;
182 void wxCanvasObjectGroup::Prepend( wxCanvasObject
* obj
)
184 m_objects
.Insert( obj
);
185 m_validbounds
= FALSE
;
188 void wxCanvasObjectGroup::Append( wxCanvasObject
* obj
)
190 m_objects
.Append( obj
);
191 m_validbounds
= FALSE
;
194 void wxCanvasObjectGroup::Insert( size_t before
, wxCanvasObject
* obj
)
196 m_objects
.Insert( before
, obj
);
197 m_validbounds
= FALSE
;
200 void wxCanvasObjectGroup::Remove( wxCanvasObject
* obj
)
202 m_objects
.DeleteObject( obj
);
203 m_validbounds
= FALSE
;
206 void wxCanvasObjectGroup::Recreate()
208 m_validbounds
= FALSE
;
209 wxNode
*node
= m_objects
.First();
212 wxCanvasObject
*obj
= (wxCanvasObject
*) node
->Data();
215 ExtendArea(obj
->GetX(),obj
->GetY());
216 ExtendArea(obj
->GetX()+obj
->GetWidth(),obj
->GetY()+obj
->GetHeight());
222 void wxCanvasObjectGroup::Render(int xabs
, int yabs
, int x
, int y
, int width
, int height
)
224 // cycle through all objects
225 wxNode
*node
= m_objects
.First();
228 wxCanvasObject
*obj
= (wxCanvasObject
*) node
->Data();
230 if (!obj
->IsControl())
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();
239 clip_width
-= x
-clip_x
;
244 if (clip_x
+ clip_width
> x
+ width
)
245 clip_width
= x
+width
-clip_x
;
249 int clip_y
= yabs
+ obj
->GetY();
250 int clip_height
= obj
->GetHeight();
253 clip_height
-= y
-clip_y
;
258 if (clip_y
+ clip_height
> y
+ height
)
259 clip_height
= y
+height
-clip_y
;
262 obj
->Render(xabs
,yabs
, clip_x
, clip_y
, clip_width
, clip_height
);
272 void wxCanvasObjectGroup::WriteSVG( wxTextOutputStream
&stream
)
276 bool wxCanvasObjectGroup::IsHit( int x
, int y
, int margin
)
278 wxNode
*node
= m_objects
.Last();
281 wxCanvasObject
*obj
= (wxCanvasObject
*) node
->Data();
283 if (!obj
->IsControl())
285 if (obj
->IsHit(x
,y
,margin
))
290 node
= node
->Previous();
295 wxCanvasObject
* wxCanvasObjectGroup::IsHitObject( int x
, int y
, int margin
)
297 wxCanvasObject
*obj
=0;
298 wxNode
*node
= m_objects
.Last();
301 obj
=(wxCanvasObject
*) node
->Data();
303 if (!obj
->IsControl())
305 if (obj
->IsHit(x
,y
,margin
))
310 node
= node
->Previous();
313 return (wxCanvasObject
*) NULL
;
316 //----------------------------------------------------------------------------
317 // wxCanvasObjectGroupRef
318 //----------------------------------------------------------------------------
320 wxCanvasObjectGroupRef::wxCanvasObjectGroupRef(double x
, double y
, wxCanvasObjectGroup
* group
)
325 m_validbounds
= FALSE
;
329 void wxCanvasObjectGroupRef::SetOwner(wxCanvas
* canvas
)
332 m_group
->SetOwner(canvas
);
335 void wxCanvasObjectGroupRef::ExtendArea(double x
, double y
)
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
;
346 m_validbounds
= TRUE
;
355 void wxCanvasObjectGroupRef::Recreate()
357 m_validbounds
= FALSE
;
359 ExtendArea(m_group
->GetXMin(),m_group
->GetYMin());
360 ExtendArea(m_group
->GetXMax(),m_group
->GetYMax());
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
) );
369 void wxCanvasObjectGroupRef::Render(int xabs
, int yabs
, int x
, int y
, int width
, int height
)
374 int clip_x
= xabs
+ m_group
->GetXMin();
375 int clip_width
= m_group
->GetXMax()-m_group
->GetXMin();
378 clip_width
-= x
-clip_x
;
383 if (clip_x
+ clip_width
> x
+ width
)
384 clip_width
= x
+width
-clip_x
;
388 int clip_y
= yabs
+ m_group
->GetYMin();
389 int clip_height
= m_group
->GetYMax()-m_group
->GetYMin();
392 clip_height
-= y
-clip_y
;
397 if (clip_y
+ clip_height
> y
+ height
)
398 clip_height
= y
+height
-clip_y
;
401 m_group
->Render(xabs
,yabs
, clip_x
, clip_y
, clip_width
, clip_height
);
407 void wxCanvasObjectGroupRef::WriteSVG( wxTextOutputStream
&stream
)
411 bool wxCanvasObjectGroupRef::IsHit( int x
, int y
, int margin
)
413 return m_group
->IsHit(x
-GetPosX(),y
-GetPosY(),margin
);
416 wxCanvasObject
* wxCanvasObjectGroupRef::IsHitObject( int x
, int y
, int margin
)
418 return m_group
->IsHitObject(x
-GetPosX(),y
-GetPosY(),margin
);
421 void wxCanvasObjectGroupRef::Move( int x
, int y
)
426 int old_area_x
= m_area
.x
;
427 int old_area_y
= m_area
.y
;
429 m_area
.x
=m_owner
->GetDeviceX( m_x
+ m_minx
);
430 m_area
.y
=m_owner
->GetDeviceY( m_y
+ m_miny
);
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
) ;
438 if ( rightu
- leftu
< 2*m_area
.width
&& bottomu
- topu
< 2*m_area
.height
)
440 m_owner
->Update(leftu
,topu
,rightu
- leftu
,bottomu
- topu
);
444 m_owner
->Update(old_area_x
, old_area_y
, m_area
.width
, m_area
.height
);
445 m_owner
->Update( m_area
.x
, m_area
.y
, m_area
.width
, m_area
.height
);
449 //----------------------------------------------------------------------------
451 //----------------------------------------------------------------------------
453 wxCanvasPolyline::wxCanvasPolyline( int n
, wxPoint2DDouble points
[])
458 m_pen
= *wxBLACK_PEN
;
461 wxCanvasPolyline::~wxCanvasPolyline()
466 void wxCanvasPolyline::ExtendArea(double x
, double y
)
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
;
477 m_validbounds
= TRUE
;
486 void wxCanvasPolyline::Recreate()
491 for (i
=0; i
< m_n
;i
++)
493 ExtendArea(m_points
[i
].m_x
,m_points
[i
].m_y
);
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);
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
) );
507 void wxCanvasPolyline::Render(int xabs
, int yabs
, int clip_x
, int clip_y
, int clip_width
, int clip_height
)
509 int buffer_x
= m_owner
->GetBufferX();
510 int buffer_y
= m_owner
->GetBufferY();
512 int start_y
= clip_y
- buffer_y
;
513 int end_y
= clip_y
+clip_height
- buffer_y
;
515 int start_x
= clip_x
- buffer_x
;
516 int end_x
= clip_x
+clip_width
- buffer_x
;
520 wxPoint
*cpoints
= new wxPoint
[m_n
];
522 for (i
= 0; i
< m_n
; i
++)
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
);
527 wxMemoryDC
*dc
= m_owner
->GetDC();
528 dc
->SetClippingRegion(start_x
,start_y
,end_x
-start_x
,end_y
-start_y
);
530 dc
->DrawLines(m_n
, cpoints
, 0,0);
532 dc
->SetPen(wxNullPen
);
533 dc
->DestroyClippingRegion();
537 void wxCanvasPolyline::WriteSVG( wxTextOutputStream
&stream
)
541 //----------------------------------------------------------------------------
543 //----------------------------------------------------------------------------
545 wxCanvasPolygon::wxCanvasPolygon( int n
, wxPoint2DDouble points
[])
550 m_brush
= *wxBLACK_BRUSH
;
551 m_pen
= *wxTRANSPARENT_PEN
;
554 wxCanvasPolygon::~wxCanvasPolygon()
559 void wxCanvasPolygon::ExtendArea(double x
, double y
)
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
;
570 m_validbounds
= TRUE
;
579 void wxCanvasPolygon::Recreate()
584 for (i
=0; i
< m_n
;i
++)
586 ExtendArea(m_points
[i
].m_x
,m_points
[i
].m_y
);
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);
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
) );
600 void wxCanvasPolygon::Render(int xabs
, int yabs
, int clip_x
, int clip_y
, int clip_width
, int clip_height
)
602 int buffer_x
= m_owner
->GetBufferX();
603 int buffer_y
= m_owner
->GetBufferY();
605 int start_y
= clip_y
- buffer_y
;
606 int end_y
= clip_y
+clip_height
- buffer_y
;
608 int start_x
= clip_x
- buffer_x
;
609 int end_x
= clip_x
+clip_width
- buffer_x
;
613 wxPoint
*cpoints
= new wxPoint
[m_n
];
615 for (i
= 0; i
< m_n
; i
++)
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
);
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
);
624 dc
->DrawPolygon(m_n
, cpoints
, 0,0,wxWINDING_RULE
);
626 dc
->SetBrush(wxNullBrush
);
627 dc
->SetPen(wxNullPen
);
628 dc
->DestroyClippingRegion();
632 void wxCanvasPolygon::WriteSVG( wxTextOutputStream
&stream
)
638 //----------------------------------------------------------------------------
640 //----------------------------------------------------------------------------
642 wxCanvasRect::wxCanvasRect( double x
, double y
, double w
, double h
)
650 m_brush
= *wxBLACK_BRUSH
;
651 m_pen
= *wxTRANSPARENT_PEN
;
654 void wxCanvasRect::Recreate()
656 SetArea( m_owner
->GetDeviceX( m_x
),
657 m_owner
->GetDeviceY( m_y
),
658 m_owner
->GetDeviceWidth( m_width
),
659 m_owner
->GetDeviceHeight( m_height
) );
662 void wxCanvasRect::Render(int xabs
, int yabs
, int clip_x
, int clip_y
, int clip_width
, int clip_height
)
664 int buffer_x
= m_owner
->GetBufferX();
665 int buffer_y
= m_owner
->GetBufferY();
668 wxImage
*image
= m_owner
->GetBuffer();
670 int start_y
= clip_y
- buffer_y
;
671 int end_y
= clip_y
+clip_height
- buffer_y
;
673 int start_x
= clip_x
- buffer_x
;
674 int end_x
= clip_x
+clip_width
- buffer_x
;
677 for (int y
= start_y
; y
< end_y
; y
++)
678 for (int x
= start_x
; x
< end_x
; x
++)
679 image
->SetRGB( x
, y
, m_red
, m_green
, m_blue
);
681 wxMemoryDC
*dc
= m_owner
->GetDC();
683 dc
->SetBrush( m_brush
);
684 dc
->DrawRectangle( clip_x
-buffer_x
, clip_y
-buffer_y
, clip_width
, clip_height
);
688 void wxCanvasRect::WriteSVG( wxTextOutputStream
&stream
)
692 //----------------------------------------------------------------------------
694 //----------------------------------------------------------------------------
696 wxCanvasLine::wxCanvasLine( double x1
, double y1
, double x2
, double y2
)
704 m_pen
= *wxBLACK_PEN
;
707 void wxCanvasLine::Recreate()
709 int x1
= m_owner
->GetDeviceX( m_x1
);
710 int y1
= m_owner
->GetDeviceY( m_y1
);
711 int x2
= m_owner
->GetDeviceX( m_x2
);
712 int y2
= m_owner
->GetDeviceY( m_y2
);
725 SetArea( x1
, y1
, x2
-x1
+1, y2
-y1
+1 );
728 void wxCanvasLine::Render(int xabs
, int yabs
, int clip_x
, int clip_y
, int clip_width
, int clip_height
)
730 int buffer_x
= m_owner
->GetBufferX();
731 int buffer_y
= m_owner
->GetBufferY();
733 int x1
= xabs
+ m_owner
->GetDeviceX( m_x1
);
734 int y1
= yabs
+ m_owner
->GetDeviceY( m_y1
);
735 int x2
= xabs
+ m_owner
->GetDeviceX( m_x2
);
736 int y2
= yabs
+ m_owner
->GetDeviceY( m_y2
);
739 wxImage
*image
= m_owner
->GetBuffer();
740 if ((m_area
.width
== 0) && (m_area
.height
== 0))
742 image
->SetRGB( m_area
.x
-buffer_x
, m_area
.y
-buffer_y
, m_red
, m_green
, m_blue
);
746 wxInt32 d
, ii
, jj
, di
, ai
, si
, dj
, aj
, sj
;
749 si
= (di
< 0)? -1 : 1;
752 sj
= (dj
< 0)? -1 : 1;
764 if ((ii
>= clip_x
) && (ii
< clip_x
+clip_width
) &&
765 (jj
>= clip_y
) && (jj
< clip_y
+clip_height
))
767 image
->SetRGB( ii
-buffer_x
, jj
-buffer_y
, m_red
, m_blue
, m_green
);
785 if ((ii
>= clip_x
) && (ii
< clip_x
+clip_width
) &&
786 (jj
>= clip_y
) && (jj
< clip_y
+clip_height
))
788 image
->SetRGB( ii
-buffer_x
, jj
-buffer_y
, m_red
, m_blue
, m_green
);
801 wxMemoryDC
*dc
= m_owner
->GetDC();
802 dc
->SetClippingRegion( clip_x
-buffer_x
, clip_y
-buffer_y
, clip_width
, clip_height
);
804 dc
->DrawLine( x1
-buffer_x
, y1
-buffer_y
, x2
-buffer_x
, y2
-buffer_y
);
806 dc
->DestroyClippingRegion();
810 void wxCanvasLine::WriteSVG( wxTextOutputStream
&stream
)
815 //----------------------------------------------------------------------------
817 //----------------------------------------------------------------------------
819 wxCanvasImage::wxCanvasImage( const wxImage
&image
, double x
, double y
, double w
, double h
)
831 void wxCanvasImage::Recreate()
833 SetArea( m_owner
->GetDeviceX( m_x
),
834 m_owner
->GetDeviceY( m_y
),
835 m_owner
->GetDeviceWidth( m_width
),
836 m_owner
->GetDeviceHeight( m_height
) );
839 if ((m_area
.width
== m_image
.GetWidth()) &&
840 (m_area
.width
== m_image
.GetWidth()))
846 m_tmp
= m_image
.Scale( m_area
.width
, m_area
.height
);
849 if ((m_area
.width
== m_image
.GetWidth()) &&
850 (m_area
.width
== m_image
.GetWidth()))
852 m_tmp
= m_image
.ConvertToBitmap();
856 wxImage
tmp( m_image
.Scale( m_area
.width
, m_area
.height
) );
857 m_tmp
= tmp
.ConvertToBitmap();
862 void wxCanvasImage::Render(int xabs
, int yabs
, int clip_x
, int clip_y
, int clip_width
, int clip_height
)
864 int buffer_x
= m_owner
->GetBufferX();
865 int buffer_y
= m_owner
->GetBufferY();
868 if ((clip_x
== xabs
+ m_area
.x
) &&
869 (clip_y
== yabs
+ m_area
.y
) &&
870 (clip_width
== m_area
.width
) &&
871 (clip_height
== m_area
.height
))
873 m_owner
->GetBuffer()->Paste( m_tmp
, clip_x
-buffer_x
, clip_y
-buffer_y
);
878 int start_x
= clip_x
- (xabs
+ m_area
.x
);
879 int start_y
= clip_y
- (yabs
+ m_area
.y
);
881 wxRect
rect( start_x
, start_y
, clip_width
, clip_height
);
882 wxImage
sub_image( m_tmp
.GetSubImage( rect
) );
883 m_owner
->GetBuffer()->Paste( sub_image
, clip_x
-buffer_x
, clip_y
-buffer_y
);
886 wxMemoryDC
*dc
= m_owner
->GetDC();
888 if ((clip_x
== xabs
+ m_area
.x
) &&
889 (clip_y
== yabs
+ m_area
.y
) &&
890 (clip_width
== m_area
.width
) &&
891 (clip_height
== m_area
.height
))
893 dc
->DrawBitmap( m_tmp
, clip_x
-buffer_x
, clip_y
-buffer_y
, TRUE
);
898 int start_x
= clip_x
- (xabs
+ m_area
.x
);
899 int start_y
= clip_y
- (yabs
+ m_area
.y
);
901 // Clipping region faster ?
902 wxRect
rect( start_x
, start_y
, clip_width
, clip_height
);
903 wxBitmap
sub_bitmap( m_tmp
.GetSubBitmap( rect
) );
904 dc
->DrawBitmap( sub_bitmap
, clip_x
-buffer_x
, clip_y
-buffer_y
, TRUE
);
909 void wxCanvasImage::WriteSVG( wxTextOutputStream
&stream
)
914 //----------------------------------------------------------------------------
916 //----------------------------------------------------------------------------
918 wxCanvasControl::wxCanvasControl( wxWindow
*control
)
925 wxCanvasControl::~wxCanvasControl()
927 m_control
->Destroy();
930 void wxCanvasControl::Recreate()
932 m_control
->GetSize( &m_area
.width
, &m_area
.height
);
933 m_control
->GetPosition( &m_area
.x
, &m_area
.y
);
936 void wxCanvasControl::Move( int x
, int y
)
938 m_control
->Move( x
, y
);
941 //----------------------------------------------------------------------------
943 //----------------------------------------------------------------------------
955 wxCanvasText::wxCanvasText( const wxString
&text
, double x
, double y
, const wxString
&fontFile
, int size
)
959 m_fontFileName
= fontFile
;
972 wxFaceData
*data
= new wxFaceData
;
975 int error
= FT_New_Face( g_freetypeLibrary
,
980 error
= FT_Set_Char_Size( data
->m_face
,
988 wxCanvasText::~wxCanvasText()
991 wxFaceData
*data
= (wxFaceData
*) m_faceData
;
995 if (m_alpha
) delete [] m_alpha
;
998 void wxCanvasText::SetRGB( unsigned char red
, unsigned char green
, unsigned char blue
)
1005 void wxCanvasText::SetFlag( int flag
)
1010 void wxCanvasText::Render(int xabs
, int yabs
, int clip_x
, int clip_y
, int clip_width
, int clip_height
)
1012 if (!m_alpha
) return;
1014 int buffer_x
= m_owner
->GetBufferX();
1015 int buffer_y
= m_owner
->GetBufferY();
1018 wxImage
*image
= m_owner
->GetBuffer();
1020 // local coordinates
1021 int start_x
= clip_x
- m_area
.x
;
1022 int end_x
= clip_width
+ start_x
;
1023 int start_y
= clip_y
- m_area
.y
;
1024 int end_y
= clip_height
+ start_y
;
1026 for (int y
= start_y
; y
< end_y
; y
++)
1027 for (int x
= start_x
; x
< end_x
; x
++)
1029 int alpha
= m_alpha
[y
*m_area
.width
+ x
];
1032 int image_x
= m_area
.x
+x
- buffer_x
;
1033 int image_y
= m_area
.y
+y
- buffer_y
;
1036 image
->SetRGB( image_x
, image_y
, m_red
, m_green
, m_blue
);
1039 int red1
= (m_red
* alpha
) / 255;
1040 int green1
= (m_green
* alpha
) / 255;
1041 int blue1
= (m_blue
* alpha
) / 255;
1044 int red2
= image
->GetRed( image_x
, image_y
);
1045 int green2
= image
->GetGreen( image_x
, image_y
);
1046 int blue2
= image
->GetBlue( image_x
, image_y
);
1047 red2
= (red2
* alpha
) / 255;
1048 green2
= (green2
* alpha
) / 255;
1049 blue2
= (blue2
* alpha
) / 255;
1051 image
->SetRGB( image_x
, image_y
, red1
+red2
, green1
+green2
, blue1
+blue2
);
1055 wxBitmap
*bitmap
= m_owner
->GetBuffer();
1056 wxRect
sub_rect( clip_x
-buffer_x
, clip_y
-buffer_y
, clip_width
, clip_height
);
1057 wxBitmap
sub_bitmap( bitmap
->GetSubBitmap( sub_rect
) );
1059 wxImage
image( sub_bitmap
);
1061 // local coordinates
1062 int start_x
= clip_x
- m_area
.x
;
1063 int end_x
= clip_width
+ start_x
;
1064 int start_y
= clip_y
- m_area
.y
;
1065 int end_y
= clip_height
+ start_y
;
1067 for (int y
= start_y
; y
< end_y
; y
++)
1068 for (int x
= start_x
; x
< end_x
; x
++)
1070 int alpha
= m_alpha
[y
*m_area
.width
+ x
];
1073 int image_x
= x
- start_x
;
1074 int image_y
= y
- start_y
;
1077 image
.SetRGB( image_x
, image_y
, m_red
, m_green
, m_blue
);
1080 int red1
= (m_red
* alpha
) / 255;
1081 int green1
= (m_green
* alpha
) / 255;
1082 int blue1
= (m_blue
* alpha
) / 255;
1085 int red2
= image
.GetRed( image_x
, image_y
);
1086 int green2
= image
.GetGreen( image_x
, image_y
);
1087 int blue2
= image
.GetBlue( image_x
, image_y
);
1088 red2
= (red2
* alpha
) / 255;
1089 green2
= (green2
* alpha
) / 255;
1090 blue2
= (blue2
* alpha
) / 255;
1092 image
.SetRGB( image_x
, image_y
, red1
+red2
, green1
+green2
, blue1
+blue2
);
1096 sub_bitmap
= image
.ConvertToBitmap();
1098 wxMemoryDC
*dc
= m_owner
->GetDC();
1099 dc
->DrawBitmap( sub_bitmap
, clip_x
-buffer_x
, clip_y
-buffer_y
);
1103 void wxCanvasText::WriteSVG( wxTextOutputStream
&stream
)
1107 void wxCanvasText::Recreate()
1109 if (m_alpha
) delete [] m_alpha
;
1111 m_area
.x
= m_owner
->GetDeviceX( m_x
);
1112 m_area
.y
= m_owner
->GetDeviceY( m_y
);
1114 m_area
.width
= 100; // TODO calculate length
1115 m_area
.height
= m_size
+ (m_size
/2); // TODO space for sub-baseline (pgypq)
1116 m_alpha
= new unsigned char[m_area
.width
*m_area
.height
];
1117 memset( m_alpha
, 0, m_area
.width
*m_area
.height
);
1120 FT_Face face
= ((wxFaceData
*)m_faceData
)->m_face
;
1121 FT_GlyphSlot slot
= face
->glyph
;
1125 for (int n
= 0; n
< (int)m_text
.Len(); n
++)
1127 FT_UInt index
= FT_Get_Char_Index( face
, m_text
[n
] );
1129 int error
= FT_Load_Glyph( face
, index
, FT_LOAD_DEFAULT
);
1130 if (error
) continue;
1132 error
= FT_Render_Glyph( face
->glyph
, ft_render_mode_normal
);
1133 if (error
) continue;
1135 FT_Bitmap
*bitmap
= &slot
->bitmap
;
1136 unsigned char* buffer
= bitmap
->buffer
;
1137 for (int y
= 0; y
< bitmap
->rows
; y
++)
1138 for (int x
= 0; x
< bitmap
->width
; x
++)
1140 unsigned char alpha
= buffer
[ y
*bitmap
->pitch
+ x
];
1141 if (alpha
== 0) continue;
1143 int xx
= pen_x
+ slot
->bitmap_left
+ x
;
1144 int yy
= pen_y
- slot
->bitmap_top
+ y
;
1145 m_alpha
[ yy
* m_area
.width
+ xx
] = alpha
;
1148 pen_x
+= slot
->advance
.x
>> 6;
1149 pen_y
+= slot
->advance
.y
>> 6;
1154 //----------------------------------------------------------------------------
1156 //----------------------------------------------------------------------------
1158 IMPLEMENT_CLASS(wxCanvas
,wxScrolledWindow
)
1160 BEGIN_EVENT_TABLE(wxCanvas
,wxScrolledWindow
)
1161 EVT_CHAR( wxCanvas::OnChar
)
1162 EVT_PAINT( wxCanvas::OnPaint
)
1163 EVT_SIZE( wxCanvas::OnSize
)
1164 EVT_IDLE( wxCanvas::OnIdle
)
1165 EVT_MOUSE_EVENTS( wxCanvas::OnMouse
)
1166 EVT_SET_FOCUS( wxCanvas::OnSetFocus
)
1167 EVT_KILL_FOCUS( wxCanvas::OnKillFocus
)
1168 EVT_ERASE_BACKGROUND( wxCanvas::OnEraseBackground
)
1171 wxCanvas::wxCanvas( wxWindow
*parent
, wxWindowID id
,
1172 const wxPoint
&position
, const wxSize
& size
, long style
) :
1173 wxScrolledWindow( parent
, id
, position
, size
, style
)
1177 m_needUpdate
= FALSE
;
1181 m_lastMouse
= (wxCanvasObject
*)NULL
;
1182 m_captureMouse
= (wxCanvasObject
*)NULL
;
1187 //root group always at 0,0
1188 m_root
= new wxCanvasObjectGroup();
1189 m_root
->DeleteContents( TRUE
);
1190 m_root
->SetOwner(this);
1193 wxCanvas::~wxCanvas()
1195 wxNode
*node
= m_updateRects
.First();
1198 wxRect
*rect
= (wxRect
*) node
->Data();
1200 m_updateRects
.DeleteNode( node
);
1201 node
= m_updateRects
.First();
1205 void wxCanvas::SetArea( int width
, int height
)
1207 SetScrollbars( 10, 10, width
/10, height
/10 );
1210 void wxCanvas::SetColour( unsigned char red
, unsigned char green
, unsigned char blue
)
1216 SetBackgroundColour( wxColour( red
, green
, blue
) );
1218 if (m_frozen
) return;
1221 unsigned char *data
= m_buffer
.GetData();
1223 for (int y
= 0; y
< m_buffer
.GetHeight(); y
++)
1224 for (int x
= 0; x
< m_buffer
.GetWidth(); x
++)
1235 dc
.SelectObject( m_buffer
);
1236 dc
.SetPen( *wxTRANSPARENT_PEN
);
1237 wxBrush
brush( wxColour( red
,green
,blue
), wxSOLID
);
1238 dc
.SetBrush( brush
);
1239 dc
.DrawRectangle( 0, 0, m_buffer
.GetWidth(), m_buffer
.GetHeight() );
1240 dc
.SelectObject( wxNullBitmap
);
1244 void wxCanvas::SetCaptureMouse( wxCanvasObject
*obj
)
1248 wxWindow::CaptureMouse();
1249 m_captureMouse
= obj
;
1253 wxWindow::ReleaseMouse();
1254 m_captureMouse
= NULL
;
1258 void wxCanvas::Freeze()
1263 void wxCanvas::Thaw()
1265 wxNode
*node
= m_updateRects
.First();
1268 wxRect
*rect
= (wxRect
*) node
->Data();
1270 m_updateRects
.DeleteNode( node
);
1271 node
= m_updateRects
.First();
1277 Update( m_bufferX
, m_bufferY
, m_buffer
.GetWidth(), m_buffer
.GetHeight() );
1280 void wxCanvas::Update( int x
, int y
, int width
, int height
, bool blit
)
1282 CalcScrolledPosition( 0, 0, &m_oldDeviceX
, &m_oldDeviceY
);
1284 if (m_frozen
) return;
1289 width
-= m_bufferX
-x
;
1292 if (width
<= 0) return;
1296 height
-= m_bufferY
-y
;
1299 if (height
<= 0) return;
1301 if (x
+width
> m_bufferX
+m_buffer
.GetWidth())
1303 width
= m_bufferX
+m_buffer
.GetWidth() - x
;
1305 if (width
<= 0) return;
1307 if (y
+height
> m_bufferY
+m_buffer
.GetHeight())
1309 height
= m_bufferY
+m_buffer
.GetHeight() - y
;
1311 if (height
<= 0) return;
1313 // update is within the buffer
1314 m_needUpdate
= TRUE
;
1316 // has to be blitted to screen later
1319 m_updateRects
.Append(
1320 (wxObject
*) new wxRect( x
,y
,width
,height
) );
1324 // speed up with direct access, maybe add wxImage::Clear(x,y,w,h,r,g,b)
1325 int start_y
= y
- m_bufferY
;
1326 int end_y
= y
+height
- m_bufferY
;
1327 int start_x
= x
- m_bufferX
;
1328 int end_x
= x
+width
- m_bufferX
;
1329 for (int yy
= start_y
; yy
< end_y
; yy
++)
1330 for (int xx
= start_x
; xx
< end_x
; xx
++)
1331 m_buffer
.SetRGB( xx
, yy
, m_red
, m_green
, m_blue
);
1333 m_root
->Render(0,0, x
, y
, width
, height
);
1336 dc
.SelectObject( m_buffer
);
1337 dc
.SetPen( *wxTRANSPARENT_PEN
);
1338 wxBrush
brush( wxColour( m_red
,m_green
,m_blue
), wxSOLID
);
1339 dc
.SetBrush( brush
);
1340 dc
.DrawRectangle( x
-m_bufferX
, y
-m_bufferY
, width
, height
);
1343 m_root
->Render(0,0, x
, y
, width
, height
);
1345 dc
.SelectObject( wxNullBitmap
);
1349 void wxCanvas::BlitBuffer( wxDC
&dc
)
1351 wxNode
*node
= m_updateRects
.First();
1354 wxRect
*rect
= (wxRect
*) node
->Data();
1356 wxRect
sub_rect( *rect
);
1357 sub_rect
.x
-= m_bufferX
;
1358 sub_rect
.y
-= m_bufferY
;
1362 wxImage
sub_image( m_buffer
.GetSubImage( sub_rect
) );
1364 int bpp
= wxDisplayDepth();
1367 // the init code is doubled in wxImage
1368 static bool s_hasInitialized
= FALSE
;
1370 if (!s_hasInitialized
)
1373 s_hasInitialized
= TRUE
;
1376 gdk_draw_rgb_image( GTK_PIZZA(m_wxwindow
)->bin_window
,
1377 m_wxwindow
->style
->black_gc
,
1378 sub_rect
.x
, sub_rect
.y
,
1379 sub_image
.GetWidth(), sub_image
.GetHeight(),
1380 GDK_RGB_DITHER_NONE
,
1381 sub_image
.GetData(),
1382 sub_image
.GetWidth()*3 );
1386 wxBitmap
bitmap( sub_image
.ConvertToBitmap() );
1387 dc
.DrawBitmap( bitmap
, rect
->x
, rect
->y
);
1390 wxBitmap
bitmap( sub_image
.ConvertToBitmap() );
1391 dc
.DrawBitmap( bitmap
, rect
->x
, rect
->y
);
1394 #else // IMAGE_CANVAS
1396 // Maybe clipping use SetClipping() is faster than
1397 // getting the subrect first and drawing it then?
1398 wxBitmap
sub_bitmap( m_buffer
.GetSubBitmap( sub_rect
) );
1399 dc
.DrawBitmap( sub_bitmap
, rect
->x
, rect
->y
);
1403 m_updateRects
.DeleteNode( node
);
1404 node
= m_updateRects
.First();
1407 m_needUpdate
= FALSE
;
1410 void wxCanvas::UpdateNow()
1412 if (m_frozen
) return;
1414 if (!m_needUpdate
) return;
1416 wxClientDC
dc( this );
1422 int wxCanvas::GetDeviceX( double x
)
1427 int wxCanvas::GetDeviceY( double y
)
1432 int wxCanvas::GetDeviceWidth( double width
)
1437 int wxCanvas::GetDeviceHeight( double height
)
1439 return (int) height
;
1442 void wxCanvas::Recreate()
1447 void wxCanvas::Prepend( wxCanvasObject
* obj
)
1449 m_root
->Prepend( obj
);
1450 obj
->SetOwner(this);
1454 if (!obj
->IsControl())
1455 Update( obj
->GetX(), obj
->GetY(), obj
->GetWidth(), obj
->GetHeight() );
1458 void wxCanvas::Append( wxCanvasObject
* obj
)
1460 m_root
->Append( obj
);
1461 obj
->SetOwner(this);
1465 if (!obj
->IsControl())
1466 Update( obj
->GetX(), obj
->GetY(), obj
->GetWidth(), obj
->GetHeight() );
1469 void wxCanvas::Insert( size_t before
, wxCanvasObject
* obj
)
1471 m_root
->Insert( before
, obj
);
1472 obj
->SetOwner(this);
1476 if (!obj
->IsControl())
1477 Update( obj
->GetX(), obj
->GetY(), obj
->GetWidth(), obj
->GetHeight() );
1480 void wxCanvas::Remove( wxCanvasObject
* obj
)
1482 int x
= obj
->GetX();
1483 int y
= obj
->GetY();
1484 int w
= obj
->GetWidth();
1485 int h
= obj
->GetHeight();
1486 bool ic
= obj
->IsControl();
1488 m_root
->Remove( obj
);
1491 Update( x
, y
, w
, h
);
1494 void wxCanvas::OnPaint(wxPaintEvent
&event
)
1499 if (!m_buffer
.Ok()) return;
1501 if (m_frozen
) return;
1503 m_needUpdate
= TRUE
;
1505 wxRegionIterator
it( GetUpdateRegion() );
1511 int w
= it
.GetWidth();
1512 int h
= it
.GetHeight();
1514 if (x
+w
> m_buffer
.GetWidth())
1515 w
= m_buffer
.GetWidth() - x
;
1516 if (y
+h
> m_buffer
.GetHeight())
1517 h
= m_buffer
.GetHeight() - y
;
1519 if ((w
> 0) && (h
> 0))
1521 CalcUnscrolledPosition( x
, y
, &x
, &y
);
1522 m_updateRects
.Append( (wxObject
*) new wxRect( x
, y
, w
, h
) );
1531 void wxCanvas::ScrollWindow( int dx
, int dy
, const wxRect
* rect
)
1533 // If any updates are pending, do them now since they will
1534 // expect the previous m_bufferX and m_bufferY as well as
1535 // the previous device origin values.
1536 wxClientDC
dc( this );
1537 dc
.SetDeviceOrigin( m_oldDeviceX
, m_oldDeviceY
);
1540 // The buffer always starts at the top left corner of the
1541 // client area. Indeed, it is the client area.
1542 CalcUnscrolledPosition( 0, 0, &m_bufferX
, &m_bufferY
);
1545 unsigned char* data
= m_buffer
.GetData();
1551 unsigned char *source
= data
;
1552 unsigned char *dest
= data
+ (dy
* m_buffer
.GetWidth() * 3);
1553 size_t count
= (size_t) (m_buffer
.GetWidth() * 3 * (m_buffer
.GetHeight()-dy
));
1554 memmove( dest
, source
, count
);
1556 // We update the new buffer area, but there is no need to
1557 // blit (last param FALSE) since the ensuing paint event will
1559 Update( m_bufferX
, m_bufferY
, m_buffer
.GetWidth(), dy
, FALSE
);
1563 unsigned char *dest
= data
;
1564 unsigned char *source
= data
+ (-dy
* m_buffer
.GetWidth() * 3);
1565 size_t count
= (size_t) (m_buffer
.GetWidth() * 3 * (m_buffer
.GetHeight()+dy
));
1566 memmove( dest
, source
, count
);
1568 // We update the new buffer area, but there is no need to
1569 // blit (last param FALSE) since the ensuing paint event will
1571 Update( m_bufferX
, m_bufferY
+m_buffer
.GetHeight()+dy
, m_buffer
.GetWidth(), -dy
, FALSE
);
1579 unsigned char *source
= data
;
1580 for (int y
= 0; y
< m_buffer
.GetHeight(); y
++)
1582 unsigned char *dest
= source
+ dx
*3;
1583 memmove( dest
, source
, (m_buffer
.GetWidth()-dx
) * 3 );
1584 source
+= m_buffer
.GetWidth()*3;
1587 // We update the new buffer area, but there is no need to
1588 // blit (last param FALSE) since the ensuing paint event will
1590 Update( m_bufferX
, m_bufferY
, dx
, m_buffer
.GetHeight(), FALSE
);
1594 unsigned char *dest
= data
;
1595 for (int y
= 0; y
< m_buffer
.GetHeight(); y
++)
1597 unsigned char *source
= dest
- dx
*3;
1598 memmove( dest
, source
, (m_buffer
.GetWidth()+dx
) * 3 );
1599 dest
+= m_buffer
.GetWidth()*3;
1602 // We update the new buffer area, but there is no need to
1603 // blit (last param FALSE) since the ensuing paint event will
1605 Update( m_bufferX
+m_buffer
.GetWidth()+dx
, m_bufferY
, -dx
, m_buffer
.GetHeight(), FALSE
);
1609 // Update everything, TODO: scrolling
1610 Update( m_bufferX
, m_bufferY
, m_buffer
.GetWidth(), m_buffer
.GetHeight(), FALSE
);
1613 wxWindow::ScrollWindow( dx
, dy
, rect
);
1616 void wxCanvas::OnMouse(wxMouseEvent
&event
)
1618 int x
= event
.GetX();
1619 int y
= event
.GetY();
1620 CalcUnscrolledPosition( x
, y
, &x
, &y
);
1622 if (event
.GetEventType() == wxEVT_MOTION
)
1624 if (m_captureMouse
) //no matter what go to this one
1626 wxMouseEvent
child_event( wxEVT_MOTION
);
1627 child_event
.SetEventObject(m_captureMouse
);
1628 child_event
.m_x
= x
- m_captureMouse
->GetX();
1629 child_event
.m_y
= y
- m_captureMouse
->GetY();
1630 child_event
.m_leftDown
= event
.m_leftDown
;
1631 child_event
.m_rightDown
= event
.m_rightDown
;
1632 child_event
.m_middleDown
= event
.m_middleDown
;
1633 child_event
.m_controlDown
= event
.m_controlDown
;
1634 child_event
.m_shiftDown
= event
.m_shiftDown
;
1635 child_event
.m_altDown
= event
.m_altDown
;
1636 child_event
.m_metaDown
= event
.m_metaDown
;
1638 m_captureMouse
->ProcessEvent( child_event
);
1643 wxCanvasObject
*obj
= m_root
->IsHitObject(x
,y
,0);
1645 if (obj
&& !obj
->IsControl())
1647 wxMouseEvent
child_event( wxEVT_MOTION
);
1648 child_event
.SetEventObject( obj
);
1649 child_event
.m_x
= x
- obj
->GetX();
1650 child_event
.m_y
= y
- obj
->GetY();
1651 child_event
.m_leftDown
= event
.m_leftDown
;
1652 child_event
.m_rightDown
= event
.m_rightDown
;
1653 child_event
.m_middleDown
= event
.m_middleDown
;
1654 child_event
.m_controlDown
= event
.m_controlDown
;
1655 child_event
.m_shiftDown
= event
.m_shiftDown
;
1656 child_event
.m_altDown
= event
.m_altDown
;
1657 child_event
.m_metaDown
= event
.m_metaDown
;
1659 if ((obj
!= m_lastMouse
) && (m_lastMouse
!= NULL
))
1661 child_event
.SetEventType( wxEVT_LEAVE_WINDOW
);
1662 child_event
.SetEventObject( m_lastMouse
);
1663 child_event
.m_x
= x
- m_lastMouse
->GetX();
1664 child_event
.m_y
= y
- m_lastMouse
->GetY();
1665 m_lastMouse
->ProcessEvent( child_event
);
1668 child_event
.SetEventType( wxEVT_ENTER_WINDOW
);
1669 child_event
.SetEventObject( m_lastMouse
);
1670 child_event
.m_x
= x
- m_lastMouse
->GetX();
1671 child_event
.m_y
= y
- m_lastMouse
->GetY();
1672 m_lastMouse
->ProcessEvent( child_event
);
1674 child_event
.SetEventType( wxEVT_MOTION
);
1675 child_event
.SetEventObject( obj
);
1678 obj
->ProcessEvent( child_event
);
1684 wxMouseEvent
child_event( wxEVT_LEAVE_WINDOW
);
1685 child_event
.SetEventObject( m_lastMouse
);
1686 child_event
.m_x
= x
- m_lastMouse
->GetX();
1687 child_event
.m_y
= y
- m_lastMouse
->GetY();
1688 child_event
.m_leftDown
= event
.m_leftDown
;
1689 child_event
.m_rightDown
= event
.m_rightDown
;
1690 child_event
.m_middleDown
= event
.m_middleDown
;
1691 child_event
.m_controlDown
= event
.m_controlDown
;
1692 child_event
.m_shiftDown
= event
.m_shiftDown
;
1693 child_event
.m_altDown
= event
.m_altDown
;
1694 child_event
.m_metaDown
= event
.m_metaDown
;
1695 m_lastMouse
->ProcessEvent( child_event
);
1697 m_lastMouse
= (wxCanvasObject
*) NULL
;
1703 if (m_captureMouse
) //no matter what go to this one
1705 wxMouseEvent
child_event( event
.GetEventType() );
1706 child_event
.SetEventObject(m_captureMouse
);
1707 child_event
.m_x
= x
- m_captureMouse
->GetX();
1708 child_event
.m_y
= y
- m_captureMouse
->GetY();
1709 child_event
.m_leftDown
= event
.m_leftDown
;
1710 child_event
.m_rightDown
= event
.m_rightDown
;
1711 child_event
.m_middleDown
= event
.m_middleDown
;
1712 child_event
.m_controlDown
= event
.m_controlDown
;
1713 child_event
.m_shiftDown
= event
.m_shiftDown
;
1714 child_event
.m_altDown
= event
.m_altDown
;
1715 child_event
.m_metaDown
= event
.m_metaDown
;
1716 m_captureMouse
->ProcessEvent( child_event
);
1720 wxCanvasObject
*obj
= m_root
->IsHitObject(x
,y
,0);
1722 if (obj
&& !obj
->IsControl())
1724 wxMouseEvent
child_event( event
.GetEventType() );
1725 child_event
.SetEventObject( obj
);
1726 child_event
.m_x
= x
- obj
->GetX();
1727 child_event
.m_y
= y
- obj
->GetY();
1728 child_event
.m_leftDown
= event
.m_leftDown
;
1729 child_event
.m_rightDown
= event
.m_rightDown
;
1730 child_event
.m_middleDown
= event
.m_middleDown
;
1731 child_event
.m_controlDown
= event
.m_controlDown
;
1732 child_event
.m_shiftDown
= event
.m_shiftDown
;
1733 child_event
.m_altDown
= event
.m_altDown
;
1734 child_event
.m_metaDown
= event
.m_metaDown
;
1736 obj
->ProcessEvent( child_event
);
1745 void wxCanvas::OnSize(wxSizeEvent
&event
)
1748 GetClientSize( &w
, &h
);
1750 m_buffer
= wxImage( w
, h
);
1752 m_buffer
= wxBitmap( w
, h
);
1755 CalcUnscrolledPosition( 0, 0, &m_bufferX
, &m_bufferY
);
1757 wxNode
*node
= m_updateRects
.First();
1760 wxRect
*rect
= (wxRect
*) node
->Data();
1762 m_updateRects
.DeleteNode( node
);
1763 node
= m_updateRects
.First();
1768 Update( m_bufferX
, m_bufferY
, m_buffer
.GetWidth(), m_buffer
.GetHeight(), FALSE
);
1773 void wxCanvas::OnIdle(wxIdleEvent
&event
)
1779 void wxCanvas::OnSetFocus(wxFocusEvent
&event
)
1783 void wxCanvas::OnKillFocus(wxFocusEvent
&event
)
1787 void wxCanvas::OnChar(wxKeyEvent
&event
)
1792 void wxCanvas::OnEraseBackground(wxEraseEvent
&event
)
1796 //--------------------------------------------------------------------
1798 //--------------------------------------------------------------------
1800 class wxCanvasModule
: public wxModule
1803 virtual bool OnInit();
1804 virtual void OnExit();
1807 DECLARE_DYNAMIC_CLASS(wxCanvasModule
)
1810 IMPLEMENT_DYNAMIC_CLASS(wxCanvasModule
, wxModule
)
1812 bool wxCanvasModule::OnInit()
1815 int error
= FT_Init_FreeType( &g_freetypeLibrary
);
1816 if (error
) return FALSE
;
1822 void wxCanvasModule::OnExit()
1825 FT_Done_FreeType( g_freetypeLibrary
);