+//----------------------------------------------------------------------------
+// wxCanvasObjectGroup
+//----------------------------------------------------------------------------
+
+wxCanvasObjectGroup::wxCanvasObjectGroup()
+{
+ m_validbounds = FALSE;
+}
+
+wxCanvasObjectGroup::~wxCanvasObjectGroup()
+{
+}
+
+void wxCanvasObjectGroup::SetOwner(wxCanvas* canvas)
+{
+ m_owner=canvas;
+ wxNode *node = m_objects.First();
+ while (node)
+ {
+ wxCanvasObject *obj = (wxCanvasObject*) node->Data();
+
+ obj->SetOwner(canvas);
+
+ node = node->Next();
+ }
+}
+
+void wxCanvasObjectGroup::ExtendArea(double x, double y)
+{
+ if (m_validbounds)
+ {
+ if (x < m_minx) m_minx = x;
+ if (y < m_miny) m_miny = y;
+ if (x > m_maxx) m_maxx = x;
+ if (y > m_maxy) m_maxy = y;
+ }
+ else
+ {
+ m_validbounds = TRUE;
+
+ m_minx = x;
+ m_miny = y;
+ m_maxx = x;
+ m_maxy = y;
+ }
+}
+
+void wxCanvasObjectGroup::DeleteContents( bool flag)
+{
+ m_objects.DeleteContents( flag );
+ m_validbounds = FALSE;
+}
+
+void wxCanvasObjectGroup::Prepend( wxCanvasObject* obj )
+{
+ m_objects.Insert( obj );
+ m_validbounds = FALSE;
+}
+
+void wxCanvasObjectGroup::Append( wxCanvasObject* obj )
+{
+ m_objects.Append( obj );
+ m_validbounds = FALSE;
+}
+
+void wxCanvasObjectGroup::Insert( size_t before, wxCanvasObject* obj )
+{
+ m_objects.Insert( before, obj );
+ m_validbounds = FALSE;
+}
+
+void wxCanvasObjectGroup::Remove( wxCanvasObject* obj )
+{
+ m_objects.DeleteObject( obj );
+ m_validbounds = FALSE;
+}
+
+void wxCanvasObjectGroup::Recreate()
+{
+ m_validbounds = FALSE;
+ wxNode *node = m_objects.First();
+ while (node)
+ {
+ wxCanvasObject *obj = (wxCanvasObject*) node->Data();
+
+ obj->Recreate();
+ ExtendArea(obj->GetX(),obj->GetY());
+ ExtendArea(obj->GetX()+obj->GetWidth(),obj->GetY()+obj->GetHeight());
+
+ node = node->Next();
+ }
+}
+
+void wxCanvasObjectGroup::Render(int xabs, int yabs, int x, int y, int width, int height )
+{
+ // cycle through all objects
+ wxNode *node = m_objects.First();
+ while (node)
+ {
+ wxCanvasObject *obj = (wxCanvasObject*) node->Data();
+
+ if (!obj->IsControl())
+ {
+ // If we have 10.000 objects, we will go through
+ // this 10.000 times for each update, so we have
+ // to optimise carefully.
+ int clip_x = xabs + obj->GetX();
+ int clip_width = obj->GetWidth();
+ if (clip_x < x)
+ {
+ clip_width -= x-clip_x;
+ clip_x = x;
+ }
+ if (clip_width > 0)
+ {
+ if (clip_x + clip_width > x + width)
+ clip_width = x+width-clip_x;
+
+ if (clip_width > 0)
+ {
+ int clip_y = yabs + obj->GetY();
+ int clip_height = obj->GetHeight();
+ if (clip_y < y)
+ {
+ clip_height -= y-clip_y;
+ clip_y = y;
+ }
+ if (clip_height > 0)
+ {
+ if (clip_y + clip_height > y + height)
+ clip_height = y+height-clip_y;
+
+ if (clip_height > 0)
+ obj->Render(xabs,yabs, clip_x, clip_y, clip_width, clip_height );
+ }
+ }
+ }
+ }
+
+ node = node->Next();
+ }
+}
+
+void wxCanvasObjectGroup::WriteSVG( wxTextOutputStream &stream )
+{
+}
+
+bool wxCanvasObjectGroup::IsHit( int x, int y, int margin )
+{
+ wxNode *node = m_objects.Last();
+ while (node)
+ {
+ wxCanvasObject *obj = (wxCanvasObject*) node->Data();
+
+ if (!obj->IsControl())
+ {
+ if (obj->IsHit(x,y,margin))
+ {
+ return TRUE;
+ }
+ }
+ node = node->Previous();
+ }
+ return FALSE;
+}
+
+wxCanvasObject* wxCanvasObjectGroup::IsHitObject( int x, int y, int margin )
+{
+ wxCanvasObject *obj=0;
+ wxNode *node = m_objects.Last();
+ while (node)
+ {
+ obj=(wxCanvasObject*) node->Data();
+
+ if (!obj->IsControl())
+ {
+ if (obj->IsHit(x,y,margin))
+ {
+ return obj;
+ }
+ }
+ node = node->Previous();
+ }
+
+ return (wxCanvasObject*) NULL;
+}
+
+//----------------------------------------------------------------------------
+// wxCanvasObjectGroupRef
+//----------------------------------------------------------------------------
+
+wxCanvasObjectGroupRef::wxCanvasObjectGroupRef(double x, double y, wxCanvasObjectGroup* group)
+ : wxCanvasObject()
+{
+ m_x = x;
+ m_y = y;
+ m_validbounds = FALSE;
+ m_group = group;
+}
+
+void wxCanvasObjectGroupRef::SetOwner(wxCanvas* canvas)
+{
+ m_owner = canvas;
+ m_group->SetOwner(canvas);
+}
+
+void wxCanvasObjectGroupRef::ExtendArea(double x, double y)
+{
+ if (m_validbounds)
+ {
+ if (x < m_minx) m_minx = x;
+ if (y < m_miny) m_miny = y;
+ if (x > m_maxx) m_maxx = x;
+ if (y > m_maxy) m_maxy = y;
+ }
+ else
+ {
+ m_validbounds = TRUE;
+
+ m_minx = x;
+ m_miny = y;
+ m_maxx = x;
+ m_maxy = y;
+ }
+}
+
+void wxCanvasObjectGroupRef::Recreate()
+{
+ m_validbounds = FALSE;
+ m_group->Recreate();
+ ExtendArea(m_group->GetXMin(),m_group->GetYMin());
+ ExtendArea(m_group->GetXMax(),m_group->GetYMax());
+
+ //set the area in pixels relative to the parent
+ SetArea( m_owner->GetDeviceX( m_x + m_minx ),
+ m_owner->GetDeviceY( m_y + m_miny ),
+ m_owner->GetDeviceWidth( m_maxx-m_minx ),
+ m_owner->GetDeviceHeight( m_maxy-m_miny ) );
+}
+
+void wxCanvasObjectGroupRef::Render(int xabs, int yabs, int x, int y, int width, int height )
+{
+ xabs += m_area.x;
+ yabs += m_area.y;
+
+ int clip_x = xabs + m_group->GetXMin();
+ int clip_width = m_group->GetXMax()-m_group->GetXMin();
+ if (clip_x < x)
+ {
+ clip_width -= x-clip_x;
+ clip_x = x;
+ }
+ if (clip_width > 0)
+ {
+ if (clip_x + clip_width > x + width)
+ clip_width = x+width-clip_x;
+
+ if (clip_width > 0)
+ {
+ int clip_y = yabs + m_group->GetYMin();
+ int clip_height = m_group->GetYMax()-m_group->GetYMin();
+ if (clip_y < y)
+ {
+ clip_height -= y-clip_y;
+ clip_y = y;
+ }
+ if (clip_height > 0)
+ {
+ if (clip_y + clip_height > y + height)
+ clip_height = y+height-clip_y;
+
+ if (clip_height > 0)
+ m_group->Render(xabs,yabs, clip_x, clip_y, clip_width, clip_height );
+ }
+ }
+ }
+}
+
+void wxCanvasObjectGroupRef::WriteSVG( wxTextOutputStream &stream )
+{
+}
+
+bool wxCanvasObjectGroupRef::IsHit( int x, int y, int margin )
+{
+ return m_group->IsHit(x-GetPosX(),y-GetPosY(),margin);
+}
+
+wxCanvasObject* wxCanvasObjectGroupRef::IsHitObject( int x, int y, int margin )
+{
+ return m_group->IsHitObject(x-GetPosX(),y-GetPosY(),margin);
+}
+
+void wxCanvasObjectGroupRef::Move( int x, int y )
+{
+ m_x = x;
+ m_y = y;
+
+ int old_area_x = m_area.x;
+ int old_area_y = m_area.y;
+
+ m_area.x=m_owner->GetDeviceX( m_x + m_minx );
+ m_area.y=m_owner->GetDeviceY( m_y + m_miny );
+
+ int leftu,rightu,bottomu,topu ;
+ leftu = wxMin (m_area.x, old_area_x ) ;
+ rightu = wxMax (old_area_x + m_area.width, m_area.x + m_area.width) ;
+ topu = wxMin (m_area.y,old_area_y) ;
+ bottomu = wxMax (old_area_y + m_area.height, m_area.y + m_area.height) ;
+
+ if ( rightu - leftu < 2*m_area.width && bottomu - topu < 2*m_area.height )
+ {
+ m_owner->Update(leftu,topu,rightu - leftu,bottomu - topu);
+ }
+ else
+ {
+ m_owner->Update(old_area_x, old_area_y, m_area.width, m_area.height );
+ m_owner->Update( m_area.x, m_area.y, m_area.width, m_area.height );
+ }
+}
+
+//----------------------------------------------------------------------------
+// wxCanvasPolyline
+//----------------------------------------------------------------------------
+
+wxCanvasPolyline::wxCanvasPolyline( int n, wxPoint2DDouble points[])
+ : wxCanvasObject()
+{
+ m_n = n;
+ m_points = points;
+ m_pen = *wxBLACK_PEN;
+}
+
+wxCanvasPolyline::~wxCanvasPolyline()
+{
+ delete m_points;
+}
+
+void wxCanvasPolyline::ExtendArea(double x, double y)
+{
+ if (m_validbounds)
+ {
+ if (x < m_minx) m_minx = x;
+ if (y < m_miny) m_miny = y;
+ if (x > m_maxx) m_maxx = x;
+ if (y > m_maxy) m_maxy = y;
+ }
+ else
+ {
+ m_validbounds = TRUE;
+
+ m_minx = x;
+ m_miny = y;
+ m_maxx = x;
+ m_maxy = y;
+ }
+}
+
+void wxCanvasPolyline::Recreate()
+{
+
+ m_validbounds=FALSE;
+ int i;
+ for (i=0; i < m_n;i++)
+ {
+ ExtendArea(m_points[i].m_x,m_points[i].m_y);
+ }
+
+ //include the pen width also
+ ExtendArea(m_minx -m_pen.GetWidth(),m_miny-m_pen.GetWidth());
+ ExtendArea(m_maxx+m_pen.GetWidth()*2,m_maxy+m_pen.GetWidth()*2);
+
+ //set the area in pixels relative to the parent
+ SetArea( m_owner->GetDeviceX(m_minx ),
+ m_owner->GetDeviceY(m_miny ),
+ m_owner->GetDeviceWidth( m_maxx-m_minx ),
+ m_owner->GetDeviceHeight( m_maxy-m_miny ) );
+}
+
+void wxCanvasPolyline::Render(int xabs, int yabs, int clip_x, int clip_y, int clip_width, int clip_height )
+{
+ int buffer_x = m_owner->GetBufferX();
+ int buffer_y = m_owner->GetBufferY();
+
+ int start_y = clip_y - buffer_y;
+ int end_y = clip_y+clip_height - buffer_y;
+
+ int start_x = clip_x - buffer_x;
+ int end_x = clip_x+clip_width - buffer_x;
+
+#if IMAGE_CANVAS
+#else
+ wxPoint *cpoints = new wxPoint[m_n];
+ int i;
+ for (i = 0; i < m_n; i++)
+ {
+ cpoints[i].x = m_owner->GetDeviceX(m_points[i].m_x+xabs);
+ cpoints[i].y = m_owner->GetDeviceY(m_points[i].m_y+yabs);
+ }
+ wxMemoryDC *dc = m_owner->GetDC();
+ dc->SetClippingRegion(start_x,start_y,end_x-start_x,end_y-start_y);
+ dc->SetPen(m_pen);
+ dc->DrawLines(m_n, cpoints, 0,0);
+ delete [] cpoints;
+ dc->SetPen(wxNullPen);
+ dc->DestroyClippingRegion();
+#endif
+}
+
+void wxCanvasPolyline::WriteSVG( wxTextOutputStream &stream )
+{
+}
+
+//----------------------------------------------------------------------------
+// wxCanvasPolygon
+//----------------------------------------------------------------------------
+
+wxCanvasPolygon::wxCanvasPolygon( int n, wxPoint2DDouble points[])
+ : wxCanvasObject()
+{
+ m_n = n;
+ m_points = points;
+ m_brush = *wxBLACK_BRUSH;
+ m_pen = *wxTRANSPARENT_PEN;
+}
+
+wxCanvasPolygon::~wxCanvasPolygon()
+{
+ delete m_points;
+}
+
+void wxCanvasPolygon::ExtendArea(double x, double y)
+{
+ if (m_validbounds)
+ {
+ if (x < m_minx) m_minx = x;
+ if (y < m_miny) m_miny = y;
+ if (x > m_maxx) m_maxx = x;
+ if (y > m_maxy) m_maxy = y;
+ }
+ else
+ {
+ m_validbounds = TRUE;
+
+ m_minx = x;
+ m_miny = y;
+ m_maxx = x;
+ m_maxy = y;
+ }
+}
+
+void wxCanvasPolygon::Recreate()
+{
+
+ m_validbounds=FALSE;
+ int i;
+ for (i=0; i < m_n;i++)
+ {
+ ExtendArea(m_points[i].m_x,m_points[i].m_y);
+ }
+
+ //include the pen width also
+ ExtendArea(m_minx -m_pen.GetWidth(),m_miny-m_pen.GetWidth());
+ ExtendArea(m_maxx+m_pen.GetWidth()*2,m_maxy+m_pen.GetWidth()*2);
+
+ //set the area in pixels relative to the parent
+ SetArea( m_owner->GetDeviceX( m_minx ),
+ m_owner->GetDeviceY( m_miny ),
+ m_owner->GetDeviceWidth( m_maxx-m_minx ),
+ m_owner->GetDeviceHeight( m_maxy-m_miny ) );
+}
+
+void wxCanvasPolygon::Render(int xabs, int yabs, int clip_x, int clip_y, int clip_width, int clip_height )
+{
+ int buffer_x = m_owner->GetBufferX();
+ int buffer_y = m_owner->GetBufferY();
+
+ int start_y = clip_y - buffer_y;
+ int end_y = clip_y+clip_height - buffer_y;
+
+ int start_x = clip_x - buffer_x;
+ int end_x = clip_x+clip_width - buffer_x;
+
+#if IMAGE_CANVAS
+#else
+ wxPoint *cpoints = new wxPoint[m_n];
+ int i;
+ for (i = 0; i < m_n; i++)
+ {
+ cpoints[i].x = m_owner->GetDeviceX(m_points[i].m_x+xabs);
+ cpoints[i].y = m_owner->GetDeviceY(m_points[i].m_y+yabs);
+ }
+ wxMemoryDC *dc = m_owner->GetDC();
+ dc->SetClippingRegion(start_x,start_y,end_x-start_x,end_y-start_y);
+ dc->SetBrush(m_brush);
+ dc->SetPen(m_pen);
+ dc->DrawPolygon(m_n, cpoints, 0,0,wxWINDING_RULE);
+ delete [] cpoints;
+ dc->SetBrush(wxNullBrush);
+ dc->SetPen(wxNullPen);
+ dc->DestroyClippingRegion();
+#endif
+}
+
+void wxCanvasPolygon::WriteSVG( wxTextOutputStream &stream )
+{
+}
+
+
+