From a4e73390a604cb78d41eacf3e97de48c36aaf8d7 Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Sat, 28 Oct 2006 13:46:46 +0000 Subject: [PATCH 1/1] moving path and matrix to refcounting as well, switching filling rule default to odd-even as dc.h does git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@42566 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/graphics.h | 299 ++++++++++++++++++++++++----------- src/common/dcgraph.cpp | 38 ++--- src/common/graphcmn.cpp | 334 ++++++++++++++++++++++++++++++++-------- src/msw/graphics.cpp | 191 ++++++++++------------- 4 files changed, 586 insertions(+), 276 deletions(-) diff --git a/include/wx/graphics.h b/include/wx/graphics.h index 0ef6bb528a..68eb3ca476 100755 --- a/include/wx/graphics.h +++ b/include/wx/graphics.h @@ -109,13 +109,124 @@ private : extern WXDLLEXPORT_DATA(wxGraphicsFont) wxNullGraphicsFont; -class WXDLLIMPEXP_CORE wxGraphicsPath : public wxGraphicsObject +class WXDLLIMPEXP_CORE wxGraphicsMatrixData : public wxGraphicsObjectRefData { public : - wxGraphicsPath(wxGraphicsRenderer* renderer) : wxGraphicsObject(renderer) {} - virtual ~wxGraphicsPath() {} - - virtual wxGraphicsPath *Clone() const = 0; + wxGraphicsMatrixData( wxGraphicsRenderer* renderer) : + wxGraphicsObjectRefData(renderer) {} + + virtual ~wxGraphicsMatrixData() {} + + // concatenates the matrix + virtual void Concat( const wxGraphicsMatrixData *t ) = 0; + + // sets the matrix to the respective values + virtual void Set(wxDouble a=1.0, wxDouble b=0.0, wxDouble c=0.0, wxDouble d=1.0, + wxDouble tx=0.0, wxDouble ty=0.0) = 0; + + // makes this the inverse matrix + virtual void Invert() = 0; + + // returns true if the elements of the transformation matrix are equal ? + virtual bool IsEqual( const wxGraphicsMatrixData* t) const = 0; + + // return true if this is the identity matrix + virtual bool IsIdentity() const = 0; + + // + // transformation + // + + // add the translation to this matrix + virtual void Translate( wxDouble dx , wxDouble dy ) = 0; + + // add the scale to this matrix + virtual void Scale( wxDouble xScale , wxDouble yScale ) = 0; + + // add the rotation to this matrix (radians) + virtual void Rotate( wxDouble angle ) = 0; + + // + // apply the transforms + // + + // applies that matrix to the point + virtual void TransformPoint( wxDouble *x, wxDouble *y ) const = 0; + + // applies the matrix except for translations + virtual void TransformDistance( wxDouble *dx, wxDouble *dy ) const =0; + + // returns the native representation + virtual void * GetNativeMatrix() const = 0; +} ; + +class WXDLLIMPEXP_CORE wxGraphicsMatrix : public wxGraphicsObject +{ +public : + wxGraphicsMatrix() {} + + virtual ~wxGraphicsMatrix() {} + + // concatenates the matrix + virtual void Concat( const wxGraphicsMatrix *t ); + void Concat( const wxGraphicsMatrix &t ) { Concat( &t ); } + + // sets the matrix to the respective values + virtual void Set(wxDouble a=1.0, wxDouble b=0.0, wxDouble c=0.0, wxDouble d=1.0, + wxDouble tx=0.0, wxDouble ty=0.0); + + // makes this the inverse matrix + virtual void Invert(); + + // returns true if the elements of the transformation matrix are equal ? + virtual bool IsEqual( const wxGraphicsMatrix* t) const; + bool IsEqual( const wxGraphicsMatrix& t) const { return IsEqual( &t ); } + + // return true if this is the identity matrix + virtual bool IsIdentity() const; + + // + // transformation + // + + // add the translation to this matrix + virtual void Translate( wxDouble dx , wxDouble dy ); + + // add the scale to this matrix + virtual void Scale( wxDouble xScale , wxDouble yScale ); + + // add the rotation to this matrix (radians) + virtual void Rotate( wxDouble angle ); + + // + // apply the transforms + // + + // applies that matrix to the point + virtual void TransformPoint( wxDouble *x, wxDouble *y ) const; + + // applies the matrix except for translations + virtual void TransformDistance( wxDouble *dx, wxDouble *dy ) const; + + // returns the native representation + virtual void * GetNativeMatrix() const; + + const wxGraphicsMatrixData* GetMatrixData() const + { return (const wxGraphicsMatrixData*) GetRefData(); } + wxGraphicsMatrixData* GetMatrixData() + { return (wxGraphicsMatrixData*) GetRefData(); } + +private : + DECLARE_DYNAMIC_CLASS(wxGraphicsMatrix) +} ; + +extern WXDLLEXPORT_DATA(wxGraphicsMatrix) wxNullGraphicsMatrix; + +class WXDLLIMPEXP_CORE wxGraphicsPathData : public wxGraphicsObjectRefData +{ +public : + wxGraphicsPathData(wxGraphicsRenderer* renderer) : wxGraphicsObjectRefData(renderer) {} + virtual ~wxGraphicsPathData() {} // // These are the path primitives from which everything else can be constructed @@ -123,29 +234,24 @@ public : // begins a new subpath at (x,y) virtual void MoveToPoint( wxDouble x, wxDouble y ) = 0; - void MoveToPoint( const wxPoint2DDouble& p); // adds a straight line from the current point to (x,y) virtual void AddLineToPoint( wxDouble x, wxDouble y ) = 0; - void AddLineToPoint( const wxPoint2DDouble& p); // adds a cubic Bezier curve from the current point, using two control points and an end point virtual void AddCurveToPoint( wxDouble cx1, wxDouble cy1, wxDouble cx2, wxDouble cy2, wxDouble x, wxDouble y ) = 0; - void AddCurveToPoint( const wxPoint2DDouble& c1, const wxPoint2DDouble& c2, const wxPoint2DDouble& e); - + // adds another path - virtual void AddPath( const wxGraphicsPath* path ) =0; + virtual void AddPath( const wxGraphicsPathData* path ) =0; // closes the current sub-path virtual void CloseSubpath() = 0; // gets the last point of the current path, (0,0) if not yet set - virtual void GetCurrentPoint( wxDouble& x, wxDouble&y) = 0; - wxPoint2DDouble GetCurrentPoint(); + virtual void GetCurrentPoint( wxDouble* x, wxDouble* y) const = 0; // adds an arc of a circle centering at (x,y) with radius (r) from startAngle to endAngle virtual void AddArc( wxDouble x, wxDouble y, wxDouble r, wxDouble startAngle, wxDouble endAngle, bool clockwise ) = 0; - void AddArc( const wxPoint2DDouble& c, wxDouble r, wxDouble startAngle, wxDouble endAngle, bool clockwise); // // These are convenience functions which - if not available natively will be assembled @@ -163,7 +269,7 @@ public : // appends a an arc to two tangents connecting (current) to (x1,y1) and (x1,y1) to (x2,y2), also a straight line from (current) to (x1,y1) virtual void AddArcToPoint( wxDouble x1, wxDouble y1 , wxDouble x2, wxDouble y2, wxDouble r ) ; - + // appends an ellipse virtual void AddEllipse( wxDouble x, wxDouble y, wxDouble w, wxDouble h); @@ -172,85 +278,106 @@ public : // returns the native path virtual void * GetNativePath() const = 0; - + // give the native path returned by GetNativePath() back (there might be some deallocations necessary) - virtual void UnGetNativePath(void *p) = 0; - + virtual void UnGetNativePath(void *p) const= 0; + // transforms each point of this path by the matrix - virtual void Transform( wxGraphicsMatrix* matrix ) =0; - + virtual void Transform( const wxGraphicsMatrixData* matrix ) =0; + // gets the bounding box enclosing all points (possibly including control points) - virtual void GetBox(wxDouble *x, wxDouble *y, wxDouble *w, wxDouble *h) =0; - wxRect2DDouble GetBox(); - - virtual bool Contains( wxDouble x, wxDouble y, int fillStyle = wxWINDING_RULE) =0; - bool Contains( const wxPoint2DDouble& c, int fillStyle = wxWINDING_RULE); - - DECLARE_NO_COPY_CLASS(wxGraphicsPath) - DECLARE_ABSTRACT_CLASS(wxGraphicsPath) + virtual void GetBox(wxDouble *x, wxDouble *y, wxDouble *w, wxDouble *h) const=0; + + virtual bool Contains( wxDouble x, wxDouble y, int fillStyle = wxODDEVEN_RULE) const=0; }; -class WXDLLIMPEXP_CORE wxGraphicsMatrix : public wxGraphicsObject +class WXDLLIMPEXP_CORE wxGraphicsPath : public wxGraphicsObject { public : - wxGraphicsMatrix(wxGraphicsRenderer* renderer) : wxGraphicsObject(renderer) {} - - virtual ~wxGraphicsMatrix() {} + wxGraphicsPath() {} + virtual ~wxGraphicsPath() {} - virtual wxGraphicsMatrix *Clone() const = 0; + // + // These are the path primitives from which everything else can be constructed + // - // concatenates the matrix - virtual void Concat( const wxGraphicsMatrix *t ) = 0; - void Concat( const wxGraphicsMatrix &t ) { Concat( &t ); } - - // copies the passed in matrix - virtual void Copy( const wxGraphicsMatrix *t ) = 0; - void Copy( const wxGraphicsMatrix &t ) { Copy( &t ); } + // begins a new subpath at (x,y) + virtual void MoveToPoint( wxDouble x, wxDouble y ); + void MoveToPoint( const wxPoint2DDouble& p); - // sets the matrix to the respective values - virtual void Set(wxDouble a=1.0, wxDouble b=0.0, wxDouble c=0.0, wxDouble d=1.0, - wxDouble tx=0.0, wxDouble ty=0.0) = 0; + // adds a straight line from the current point to (x,y) + virtual void AddLineToPoint( wxDouble x, wxDouble y ); + void AddLineToPoint( const wxPoint2DDouble& p); - // makes this the inverse matrix - virtual void Invert() = 0; - - // returns true if the elements of the transformation matrix are equal ? - virtual bool IsEqual( const wxGraphicsMatrix* t) const = 0; - bool IsEqual( const wxGraphicsMatrix& t) const { return IsEqual( &t ); } - - // return true if this is the identity matrix - virtual bool IsIdentity() = 0; + // adds a cubic Bezier curve from the current point, using two control points and an end point + virtual void AddCurveToPoint( wxDouble cx1, wxDouble cy1, wxDouble cx2, wxDouble cy2, wxDouble x, wxDouble y ) ; + void AddCurveToPoint( const wxPoint2DDouble& c1, const wxPoint2DDouble& c2, const wxPoint2DDouble& e); + // adds another path + virtual void AddPath( const wxGraphicsPath& path ); + + // closes the current sub-path + virtual void CloseSubpath() ; + + // gets the last point of the current path, (0,0) if not yet set + virtual void GetCurrentPoint( wxDouble* x, wxDouble* y) const; + wxPoint2DDouble GetCurrentPoint() const; + + // adds an arc of a circle centering at (x,y) with radius (r) from startAngle to endAngle + virtual void AddArc( wxDouble x, wxDouble y, wxDouble r, wxDouble startAngle, wxDouble endAngle, bool clockwise ) ; + void AddArc( const wxPoint2DDouble& c, wxDouble r, wxDouble startAngle, wxDouble endAngle, bool clockwise); + // - // transformation + // These are convenience functions which - if not available natively will be assembled + // using the primitives from above // + + // adds a quadratic Bezier curve from the current point, using a control point and an end point + virtual void AddQuadCurveToPoint( wxDouble cx, wxDouble cy, wxDouble x, wxDouble y ); + + // appends a rectangle as a new closed subpath + virtual void AddRectangle( wxDouble x, wxDouble y, wxDouble w, wxDouble h ); + + // appends an ellipsis as a new closed subpath fitting the passed rectangle + virtual void AddCircle( wxDouble x, wxDouble y, wxDouble r ); + + // appends a an arc to two tangents connecting (current) to (x1,y1) and (x1,y1) to (x2,y2), also a straight line from (current) to (x1,y1) + virtual void AddArcToPoint( wxDouble x1, wxDouble y1 , wxDouble x2, wxDouble y2, wxDouble r ) ; - // add the translation to this matrix - virtual void Translate( wxDouble dx , wxDouble dy ) = 0; + // appends an ellipse + virtual void AddEllipse( wxDouble x, wxDouble y, wxDouble w, wxDouble h); - // add the scale to this matrix - virtual void Scale( wxDouble xScale , wxDouble yScale ) = 0; + // appends a rounded rectangle + virtual void AddRoundedRectangle( wxDouble x, wxDouble y, wxDouble w, wxDouble h, wxDouble radius); - // add the rotation to this matrix (radians) - virtual void Rotate( wxDouble angle ) = 0; + // returns the native path + virtual void * GetNativePath() const; - // - // apply the transforms - // + // give the native path returned by GetNativePath() back (there might be some deallocations necessary) + virtual void UnGetNativePath(void *p)const; - // applies that matrix to the point - virtual void TransformPoint( wxDouble *x, wxDouble *y ) = 0; + // transforms each point of this path by the matrix + virtual void Transform( const wxGraphicsMatrix& matrix ); - // applies the matrix except for translations - virtual void TransformDistance( wxDouble *dx, wxDouble *dy ) =0; + // gets the bounding box enclosing all points (possibly including control points) + virtual void GetBox(wxDouble *x, wxDouble *y, wxDouble *w, wxDouble *h)const; + wxRect2DDouble GetBox()const; - // returns the native representation - virtual void * GetNativeMatrix() const = 0; + virtual bool Contains( wxDouble x, wxDouble y, int fillStyle = wxODDEVEN_RULE)const; + bool Contains( const wxPoint2DDouble& c, int fillStyle = wxODDEVEN_RULE)const; - DECLARE_NO_COPY_CLASS(wxGraphicsMatrix) - DECLARE_ABSTRACT_CLASS(wxGraphicsMatrix) + const wxGraphicsPathData* GetPathData() const + { return (const wxGraphicsPathData*) GetRefData(); } + wxGraphicsPathData* GetPathData() + { return (wxGraphicsPathData*) GetRefData(); } + +private : + DECLARE_DYNAMIC_CLASS(wxGraphicsPath) } ; +extern WXDLLEXPORT_DATA(wxGraphicsPath) wxNullGraphicsPath; + + class WXDLLIMPEXP_CORE wxGraphicsContext : public wxGraphicsObject { public: @@ -266,27 +393,27 @@ public: static wxGraphicsContext* Create( wxWindow* window ) ; - wxGraphicsPath * CreatePath(); + wxGraphicsPath CreatePath() const; - virtual wxGraphicsPen CreatePen(const wxPen& pen); + virtual wxGraphicsPen CreatePen(const wxPen& pen) const; - virtual wxGraphicsBrush CreateBrush(const wxBrush& brush ); + virtual wxGraphicsBrush CreateBrush(const wxBrush& brush ) const; // sets the brush to a linear gradient, starting at (x1,y1) with color c1 to (x2,y2) with color c2 virtual wxGraphicsBrush CreateLinearGradientBrush( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2, - const wxColour&c1, const wxColour&c2); + const wxColour&c1, const wxColour&c2) const; // sets the brush to a radial gradient originating at (xo,yc) with color oColor and ends on a circle around (xc,yc) // with radius r and color cColor virtual wxGraphicsBrush CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius, - const wxColour &oColor, const wxColour &cColor); + const wxColour &oColor, const wxColour &cColor) const; // sets the font - virtual wxGraphicsFont CreateFont( const wxFont &font , const wxColour &col = *wxBLACK ); + virtual wxGraphicsFont CreateFont( const wxFont &font , const wxColour &col = *wxBLACK ) const; // create a 'native' matrix corresponding to these values - virtual wxGraphicsMatrix* CreateMatrix( wxDouble a=1.0, wxDouble b=0.0, wxDouble c=0.0, wxDouble d=1.0, - wxDouble tx=0.0, wxDouble ty=0.0); + virtual wxGraphicsMatrix CreateMatrix( wxDouble a=1.0, wxDouble b=0.0, wxDouble c=0.0, wxDouble d=1.0, + wxDouble tx=0.0, wxDouble ty=0.0) const; // push the current state of the context, ie the transformation matrix on a stack virtual void PushState() = 0; @@ -320,13 +447,13 @@ public: virtual void Rotate( wxDouble angle ) = 0; // concatenates this transform with the current transform of this context - virtual void ConcatTransform( const wxGraphicsMatrix* matrix ) = 0; + virtual void ConcatTransform( const wxGraphicsMatrix& matrix ) = 0; // sets the transform of this context - virtual void SetTransform( const wxGraphicsMatrix* matrix ) = 0; + virtual void SetTransform( const wxGraphicsMatrix& matrix ) = 0; // gets the matrix of this context - virtual void GetTransform( wxGraphicsMatrix* matrix ) = 0; + virtual wxGraphicsMatrix GetTransform() const = 0; // // setting the paint // @@ -348,13 +475,13 @@ public: // strokes along a path with the current pen - virtual void StrokePath( const wxGraphicsPath *path ) = 0; + virtual void StrokePath( const wxGraphicsPath& path ) = 0; // fills a path with the current brush - virtual void FillPath( const wxGraphicsPath *path, int fillStyle = wxWINDING_RULE ) = 0; + virtual void FillPath( const wxGraphicsPath& path, int fillStyle = wxODDEVEN_RULE ) = 0; // draws a path by first filling and then stroking - virtual void DrawPath( const wxGraphicsPath *path, int fillStyle = wxWINDING_RULE ); + virtual void DrawPath( const wxGraphicsPath& path, int fillStyle = wxODDEVEN_RULE ); // // text @@ -391,7 +518,7 @@ public: virtual void StrokeLines( size_t n, const wxPoint2DDouble *beginPoints, const wxPoint2DDouble *endPoints); // draws a polygon - virtual void DrawLines( size_t n, const wxPoint2DDouble *points, int fillStyle = wxWINDING_RULE ); + virtual void DrawLines( size_t n, const wxPoint2DDouble *points, int fillStyle = wxODDEVEN_RULE ); // draws a polygon virtual void DrawRectangle( wxDouble x, wxDouble y, wxDouble w, wxDouble h); @@ -480,11 +607,11 @@ public : // Path - virtual wxGraphicsPath * CreatePath() = 0; + virtual wxGraphicsPath CreatePath() = 0; // Matrix - virtual wxGraphicsMatrix * CreateMatrix( wxDouble a=1.0, wxDouble b=0.0, wxDouble c=0.0, wxDouble d=1.0, + virtual wxGraphicsMatrix CreateMatrix( wxDouble a=1.0, wxDouble b=0.0, wxDouble c=0.0, wxDouble d=1.0, wxDouble tx=0.0, wxDouble ty=0.0) = 0; // Paints diff --git a/src/common/dcgraph.cpp b/src/common/dcgraph.cpp index f158b9a874..4234c0ccbe 100644 --- a/src/common/dcgraph.cpp +++ b/src/common/dcgraph.cpp @@ -540,14 +540,13 @@ void wxGCDC::DoDrawArc( wxCoord x1, wxCoord y1, bool fill = m_brush.GetStyle() != wxTRANSPARENT; - wxGraphicsPath* path = m_graphicContext->CreatePath(); + wxGraphicsPath path = m_graphicContext->CreatePath(); if ( fill && ((x1!=x2)||(y1!=y2)) ) - path->MoveToPoint( xxc, yyc ); - path->AddArc( xxc, yyc , rad , DegToRad(sa) , DegToRad(ea), false ); + path.MoveToPoint( xxc, yyc ); + path.AddArc( xxc, yyc , rad , DegToRad(sa) , DegToRad(ea), false ); if ( fill && ((x1!=x2)||(y1!=y2)) ) - path->AddLineToPoint( xxc, yyc ); + path.AddLineToPoint( xxc, yyc ); m_graphicContext->DrawPath(path); - delete path; } void wxGCDC::DoDrawEllipticArc( wxCoord x, wxCoord y, wxCoord w, wxCoord h, @@ -577,21 +576,20 @@ void wxGCDC::DoDrawEllipticArc( wxCoord x, wxCoord y, wxCoord w, wxCoord h, bool fill = m_brush.GetStyle() != wxTRANSPARENT; - wxGraphicsPath* path = m_graphicContext->CreatePath(); + wxGraphicsPath path = m_graphicContext->CreatePath(); m_graphicContext->PushState(); m_graphicContext->Translate(xx+ww/2,yy+hh/2); wxDouble factor = ((wxDouble) ww) / hh; m_graphicContext->Scale( factor , 1.0); if ( fill && (sa!=ea) ) - path->MoveToPoint(0,0); + path.MoveToPoint(0,0); // since these angles (ea,sa) are measured counter-clockwise, we invert them to // get clockwise angles - path->AddArc( 0, 0, hh/2 , DegToRad(-sa) , DegToRad(-ea), sa > ea ); + path.AddArc( 0, 0, hh/2 , DegToRad(-sa) , DegToRad(-ea), sa > ea ); if ( fill && (sa!=ea) ) - path->AddLineToPoint(0,0); + path.AddLineToPoint(0,0); m_graphicContext->DrawPath( path ); m_graphicContext->PopState(); - delete path; } void wxGCDC::DoDrawPoint( wxCoord x, wxCoord y ) @@ -631,7 +629,7 @@ void wxGCDC::DoDrawSpline(wxList *points) if ( m_logicalFunction != wxCOPY ) return; - wxGraphicsPath* path = m_graphicContext->CreatePath(); + wxGraphicsPath path = m_graphicContext->CreatePath(); wxList::compatibility_iterator node = points->GetFirst(); if (node == wxList::compatibility_iterator()) @@ -651,8 +649,8 @@ void wxGCDC::DoDrawSpline(wxList *points) wxCoord cx1 = ( x1 + x2 ) / 2; wxCoord cy1 = ( y1 + y2 ) / 2; - path->MoveToPoint( LogicalToDeviceX( x1 ) , LogicalToDeviceY( y1 ) ); - path->AddLineToPoint( LogicalToDeviceX( cx1 ) , LogicalToDeviceY( cy1 ) ); + path.MoveToPoint( LogicalToDeviceX( x1 ) , LogicalToDeviceY( y1 ) ); + path.AddLineToPoint( LogicalToDeviceX( cx1 ) , LogicalToDeviceY( cy1 ) ); #if !wxUSE_STL while ((node = node->GetNext()) != NULL) @@ -670,7 +668,7 @@ void wxGCDC::DoDrawSpline(wxList *points) wxCoord cx4 = (x1 + x2) / 2; wxCoord cy4 = (y1 + y2) / 2; - path->AddQuadCurveToPoint( + path.AddQuadCurveToPoint( LogicalToDeviceX( x1 ) , LogicalToDeviceY( y1 ) , LogicalToDeviceX( cx4 ) , LogicalToDeviceY( cy4 ) ); @@ -678,10 +676,9 @@ void wxGCDC::DoDrawSpline(wxList *points) cy1 = cy4; } - path->AddLineToPoint( LogicalToDeviceX( x2 ) , LogicalToDeviceY( y2 ) ); + path.AddLineToPoint( LogicalToDeviceX( x2 ) , LogicalToDeviceY( y2 ) ); m_graphicContext->StrokePath( path ); - delete path; } #endif // wxUSE_SPLINES @@ -721,26 +718,25 @@ void wxGCDC::DoDrawPolyPolygon(int n, int fillStyle) { wxASSERT(n > 1); - wxGraphicsPath* path = m_graphicContext->CreatePath(); + wxGraphicsPath path = m_graphicContext->CreatePath(); int i = 0; for ( int j = 0; j < n; ++j) { wxPoint start = points[i]; - path->MoveToPoint(LogicalToDeviceX(start.x+ xoffset), LogicalToDeviceY(start.y+ yoffset)); + path.MoveToPoint(LogicalToDeviceX(start.x+ xoffset), LogicalToDeviceY(start.y+ yoffset)); ++i; int l = count[j]; for ( int k = 1; k < l; ++k) { - path->AddLineToPoint( LogicalToDeviceX(points[i].x+ xoffset), LogicalToDeviceY(points[i].y+ yoffset)); + path.AddLineToPoint( LogicalToDeviceX(points[i].x+ xoffset), LogicalToDeviceY(points[i].y+ yoffset)); ++i; } // close the polygon if ( start != points[i-1]) - path->AddLineToPoint( LogicalToDeviceX(start.x+ xoffset), LogicalToDeviceY(start.y+ yoffset)); + path.AddLineToPoint( LogicalToDeviceX(start.x+ xoffset), LogicalToDeviceY(start.y+ yoffset)); } m_graphicContext->DrawPath( path , fillStyle); - delete path; } void wxGCDC::DoDrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height) diff --git a/src/common/graphcmn.cpp b/src/common/graphcmn.cpp index 3cbc6cb3c4..3d01a387bb 100644 --- a/src/common/graphcmn.cpp +++ b/src/common/graphcmn.cpp @@ -120,18 +120,107 @@ wxObjectRefData* wxGraphicsObject::CloneRefData(const wxObjectRefData* data) con IMPLEMENT_DYNAMIC_CLASS(wxGraphicsPen, wxGraphicsObject) IMPLEMENT_DYNAMIC_CLASS(wxGraphicsBrush, wxGraphicsObject) IMPLEMENT_DYNAMIC_CLASS(wxGraphicsFont, wxGraphicsObject) + WXDLLIMPEXP_DATA_CORE(wxGraphicsPen) wxNullGraphicsPen; WXDLLIMPEXP_DATA_CORE(wxGraphicsBrush) wxNullGraphicsBrush; WXDLLIMPEXP_DATA_CORE(wxGraphicsFont) wxNullGraphicsFont; -IMPLEMENT_ABSTRACT_CLASS(wxGraphicsRenderer, wxObject) -IMPLEMENT_ABSTRACT_CLASS(wxGraphicsMatrix, wxGraphicsObject) -IMPLEMENT_ABSTRACT_CLASS(wxGraphicsPath, wxGraphicsObject) +//----------------------------------------------------------------------------- +// matrix +//----------------------------------------------------------------------------- + +IMPLEMENT_DYNAMIC_CLASS(wxGraphicsMatrix, wxGraphicsObject) +WXDLLIMPEXP_DATA_CORE(wxGraphicsMatrix) wxNullGraphicsMatrix; + +// concatenates the matrix +void wxGraphicsMatrix::Concat( const wxGraphicsMatrix *t ) +{ + AllocExclusive(); + GetMatrixData()->Concat(t->GetMatrixData()); +} + +// sets the matrix to the respective values +void wxGraphicsMatrix::Set(wxDouble a, wxDouble b, wxDouble c, wxDouble d, + wxDouble tx, wxDouble ty) +{ + AllocExclusive(); + GetMatrixData()->Set(a,b,c,d,tx,ty); +} + +// makes this the inverse matrix +void wxGraphicsMatrix::Invert() +{ + AllocExclusive(); + GetMatrixData()->Invert(); +} + +// returns true if the elements of the transformation matrix are equal ? +bool wxGraphicsMatrix::IsEqual( const wxGraphicsMatrix* t) const +{ + return GetMatrixData()->IsEqual(t->GetMatrixData()); +} + +// return true if this is the identity matrix +bool wxGraphicsMatrix::IsIdentity() const +{ + return GetMatrixData()->IsIdentity(); +} + +// add the translation to this matrix +void wxGraphicsMatrix::Translate( wxDouble dx , wxDouble dy ) +{ + AllocExclusive(); + GetMatrixData()->Translate(dx,dy); +} + +// add the scale to this matrix +void wxGraphicsMatrix::Scale( wxDouble xScale , wxDouble yScale ) +{ + AllocExclusive(); + GetMatrixData()->Scale(xScale,yScale); +} + +// add the rotation to this matrix (radians) +void wxGraphicsMatrix::Rotate( wxDouble angle ) +{ + AllocExclusive(); + GetMatrixData()->Rotate(angle); +} + +// +// apply the transforms +// + +// applies that matrix to the point +void wxGraphicsMatrix::TransformPoint( wxDouble *x, wxDouble *y ) const +{ + GetMatrixData()->TransformPoint(x,y); +} + +// applies the matrix except for translations +void wxGraphicsMatrix::TransformDistance( wxDouble *dx, wxDouble *dy ) const +{ + GetMatrixData()->TransformDistance(dx,dy); +} -wxPoint2DDouble wxGraphicsPath::GetCurrentPoint() +// returns the native representation +void * wxGraphicsMatrix::GetNativeMatrix() const +{ + return GetMatrixData()->GetNativeMatrix(); +} + +//----------------------------------------------------------------------------- +// path +//----------------------------------------------------------------------------- + +IMPLEMENT_DYNAMIC_CLASS(wxGraphicsPath, wxGraphicsObject) + +// convenience functions, for using wxPoint2DDouble etc + +wxPoint2DDouble wxGraphicsPath::GetCurrentPoint() const { wxDouble x,y; - GetCurrentPoint(x,y); + GetCurrentPoint(&x,&y); return wxPoint2DDouble(x,y); } @@ -155,29 +244,156 @@ void wxGraphicsPath::AddArc( const wxPoint2DDouble& c, wxDouble r, wxDouble star AddArc(c.m_x, c.m_y, r, startAngle, endAngle, clockwise); } -wxRect2DDouble wxGraphicsPath::GetBox() +wxRect2DDouble wxGraphicsPath::GetBox() const { wxDouble x,y,w,h; GetBox(&x,&y,&w,&h); return wxRect2DDouble( x,y,w,h ); } -bool wxGraphicsPath::Contains( const wxPoint2DDouble& c, int fillStyle ) +bool wxGraphicsPath::Contains( const wxPoint2DDouble& c, int fillStyle ) const { return Contains( c.m_x, c.m_y, fillStyle); } +// true redirections + +// begins a new subpath at (x,y) +void wxGraphicsPath::MoveToPoint( wxDouble x, wxDouble y ) +{ + AllocExclusive(); + GetPathData()->MoveToPoint(x,y); +} + +// adds a straight line from the current point to (x,y) +void wxGraphicsPath::AddLineToPoint( wxDouble x, wxDouble y ) +{ + AllocExclusive(); + GetPathData()->AddLineToPoint(x,y); +} + +// adds a cubic Bezier curve from the current point, using two control points and an end point +void wxGraphicsPath::AddCurveToPoint( wxDouble cx1, wxDouble cy1, wxDouble cx2, wxDouble cy2, wxDouble x, wxDouble y ) +{ + AllocExclusive(); + GetPathData()->AddCurveToPoint(cx1,cy1,cx2,cy2,x,y); +} + +// adds another path +void wxGraphicsPath::AddPath( const wxGraphicsPath& path ) +{ + AllocExclusive(); + GetPathData()->AddPath(path.GetPathData()); +} + +// closes the current sub-path +void wxGraphicsPath::CloseSubpath() +{ + AllocExclusive(); + GetPathData()->CloseSubpath(); +} + +// gets the last point of the current path, (0,0) if not yet set +void wxGraphicsPath::GetCurrentPoint( wxDouble* x, wxDouble* y) const +{ + GetPathData()->GetCurrentPoint(x,y); +} + +// adds an arc of a circle centering at (x,y) with radius (r) from startAngle to endAngle +void wxGraphicsPath::AddArc( wxDouble x, wxDouble y, wxDouble r, wxDouble startAngle, wxDouble endAngle, bool clockwise ) +{ + AllocExclusive(); + GetPathData()->AddArc(x,y,r,startAngle,endAngle,clockwise); +} + // -// Emulations +// These are convenience functions which - if not available natively will be assembled +// using the primitives from above // +// adds a quadratic Bezier curve from the current point, using a control point and an end point void wxGraphicsPath::AddQuadCurveToPoint( wxDouble cx, wxDouble cy, wxDouble x, wxDouble y ) +{ + AllocExclusive(); + GetPathData()->AddQuadCurveToPoint(cx,cy,x,y); +} + +// appends a rectangle as a new closed subpath +void wxGraphicsPath::AddRectangle( wxDouble x, wxDouble y, wxDouble w, wxDouble h ) +{ + AllocExclusive(); + GetPathData()->AddRectangle(x,y,w,h); +} + +// appends an ellipsis as a new closed subpath fitting the passed rectangle +void wxGraphicsPath::AddCircle( wxDouble x, wxDouble y, wxDouble r ) +{ + AllocExclusive(); + GetPathData()->AddCircle(x,y,r); +} + +// appends a an arc to two tangents connecting (current) to (x1,y1) and (x1,y1) to (x2,y2), also a straight line from (current) to (x1,y1) +void wxGraphicsPath::AddArcToPoint( wxDouble x1, wxDouble y1 , wxDouble x2, wxDouble y2, wxDouble r ) +{ + GetPathData()->AddArcToPoint(x1,y1,x2,y2,r); +} + +// appends an ellipse +void wxGraphicsPath::AddEllipse( wxDouble x, wxDouble y, wxDouble w, wxDouble h) +{ + AllocExclusive(); + GetPathData()->AddEllipse(x,y,w,h); +} + +// appends a rounded rectangle +void wxGraphicsPath::AddRoundedRectangle( wxDouble x, wxDouble y, wxDouble w, wxDouble h, wxDouble radius) +{ + AllocExclusive(); + GetPathData()->AddRoundedRectangle(x,y,w,h,radius); +} + +// returns the native path +void * wxGraphicsPath::GetNativePath() const +{ + return GetPathData()->GetNativePath(); +} + +// give the native path returned by GetNativePath() back (there might be some deallocations necessary) +void wxGraphicsPath::UnGetNativePath(void *p)const +{ + GetPathData()->UnGetNativePath(p); +} + +// transforms each point of this path by the matrix +void wxGraphicsPath::Transform( const wxGraphicsMatrix& matrix ) +{ + AllocExclusive(); + GetPathData()->Transform(matrix.GetMatrixData()); +} + +// gets the bounding box enclosing all points (possibly including control points) +void wxGraphicsPath::GetBox(wxDouble *x, wxDouble *y, wxDouble *w, wxDouble *h) const +{ + GetPathData()->GetBox(x,y,w,h); +} + +bool wxGraphicsPath::Contains( wxDouble x, wxDouble y, int fillStyle ) const +{ + return GetPathData()->Contains(x,y,fillStyle); +} + +// +// Emulations, these mus be implemented in the ...Data classes in order to allow for proper overrides +// + +void wxGraphicsPathData::AddQuadCurveToPoint( wxDouble cx, wxDouble cy, wxDouble x, wxDouble y ) { // calculate using degree elevation to a cubic bezier wxPoint2DDouble c1; wxPoint2DDouble c2; - wxPoint2DDouble start = GetCurrentPoint(); + wxPoint2DDouble start; + GetCurrentPoint(&start.m_x,&start.m_y); wxPoint2DDouble end(x,y); wxPoint2DDouble c(cx,cy); c1 = wxDouble(1/3.0) * start + wxDouble(2/3.0) * c; @@ -185,7 +401,7 @@ void wxGraphicsPath::AddQuadCurveToPoint( wxDouble cx, wxDouble cy, wxDouble x, AddCurveToPoint(c1.m_x,c1.m_y,c2.m_x,c2.m_y,x,y); } -void wxGraphicsPath::AddRectangle( wxDouble x, wxDouble y, wxDouble w, wxDouble h ) +void wxGraphicsPathData::AddRectangle( wxDouble x, wxDouble y, wxDouble w, wxDouble h ) { MoveToPoint(x,y); AddLineToPoint(x,y+h); @@ -194,31 +410,29 @@ void wxGraphicsPath::AddRectangle( wxDouble x, wxDouble y, wxDouble w, wxDouble CloseSubpath(); } -void wxGraphicsPath::AddCircle( wxDouble x, wxDouble y, wxDouble r ) +void wxGraphicsPathData::AddCircle( wxDouble x, wxDouble y, wxDouble r ) { MoveToPoint(x+r,y); AddArc( x,y,r,0,2*M_PI,false); CloseSubpath(); } -void wxGraphicsPath::AddEllipse( wxDouble x, wxDouble y, wxDouble w, wxDouble h) +void wxGraphicsPathData::AddEllipse( wxDouble x, wxDouble y, wxDouble w, wxDouble h) { wxDouble rw = w/2; wxDouble rh = h/2; wxDouble xc = x + rw; wxDouble yc = y + rh; - wxGraphicsMatrix* m = GetRenderer()->CreateMatrix(); - m->Translate(xc,yc); - m->Scale(rw/rh,1.0); - wxGraphicsPath* p = GetRenderer()->CreatePath(); - p->AddCircle(0,0,rh); - p->Transform(m); - AddPath(p); - delete p; - delete m; + wxGraphicsMatrix m = GetRenderer()->CreateMatrix(); + m.Translate(xc,yc); + m.Scale(rw/rh,1.0); + wxGraphicsPath p = GetRenderer()->CreatePath(); + p.AddCircle(0,0,rh); + p.Transform(m); + AddPath(p.GetPathData()); } -void wxGraphicsPath::AddRoundedRectangle( wxDouble x, wxDouble y, wxDouble w, wxDouble h, wxDouble radius) +void wxGraphicsPathData::AddRoundedRectangle( wxDouble x, wxDouble y, wxDouble w, wxDouble h, wxDouble radius) { if ( radius == 0 ) AddRectangle(x,y,w,h); @@ -234,9 +448,10 @@ void wxGraphicsPath::AddRoundedRectangle( wxDouble x, wxDouble y, wxDouble w, wx } // draws a an arc to two tangents connecting (current) to (x1,y1) and (x1,y1) to (x2,y2), also a straight line from (current) to (x1,y1) -void wxGraphicsPath::AddArcToPoint( wxDouble x1, wxDouble y1 , wxDouble x2, wxDouble y2, wxDouble r ) +void wxGraphicsPathData::AddArcToPoint( wxDouble x1, wxDouble y1 , wxDouble x2, wxDouble y2, wxDouble r ) { - wxPoint2DDouble current = GetCurrentPoint(); + wxPoint2DDouble current; + GetCurrentPoint(¤t.m_x,¤t.m_y); wxPoint2DDouble p1(x1,y1); wxPoint2DDouble p2(x2,y2); @@ -265,9 +480,9 @@ void wxGraphicsPath::AddArcToPoint( wxDouble x1, wxDouble y1 , wxDouble x2, wxDo wxDouble a1 = v1.GetVectorAngle()+90; wxDouble a2 = v2.GetVectorAngle()-90; - AddLineToPoint(t1); + AddLineToPoint(t1.m_x,t1.m_y); AddArc(c.m_x,c.m_y,r,DegToRad(a1),DegToRad(a2),true); - AddLineToPoint(p2); + AddLineToPoint(p2.m_x,p2.m_y); } //----------------------------------------------------------------------------- @@ -327,7 +542,7 @@ void wxGraphicsContext::SetFont( const wxFont& font, const wxColour& colour ) SetFont( wxNullGraphicsFont ); } -void wxGraphicsContext::DrawPath( const wxGraphicsPath *path, int fillStyle ) +void wxGraphicsContext::DrawPath( const wxGraphicsPath& path, int fillStyle ) { FillPath( path , fillStyle ); StrokePath( path ); @@ -344,97 +559,90 @@ void wxGraphicsContext::DrawText( const wxString &str, wxDouble x, wxDouble y, w void wxGraphicsContext::StrokeLine( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2) { - wxGraphicsPath* path = CreatePath(); - path->MoveToPoint(x1, y1); - path->AddLineToPoint( x2, y2 ); + wxGraphicsPath path = CreatePath(); + path.MoveToPoint(x1, y1); + path.AddLineToPoint( x2, y2 ); StrokePath( path ); - delete path; } void wxGraphicsContext::DrawRectangle( wxDouble x, wxDouble y, wxDouble w, wxDouble h) { - wxGraphicsPath* path = CreatePath(); - path->AddRectangle( x , y , w , h ); + wxGraphicsPath path = CreatePath(); + path.AddRectangle( x , y , w , h ); DrawPath( path ); - delete path; } void wxGraphicsContext::DrawEllipse( wxDouble x, wxDouble y, wxDouble w, wxDouble h) { - wxGraphicsPath* path = CreatePath(); - path->AddEllipse(x,y,w,h); + wxGraphicsPath path = CreatePath(); + path.AddEllipse(x,y,w,h); DrawPath(path); - delete path; } void wxGraphicsContext::DrawRoundedRectangle( wxDouble x, wxDouble y, wxDouble w, wxDouble h, wxDouble radius) { - wxGraphicsPath* path = CreatePath(); - path->AddRoundedRectangle(x,y,w,h,radius); + wxGraphicsPath path = CreatePath(); + path.AddRoundedRectangle(x,y,w,h,radius); DrawPath(path); - delete path; } void wxGraphicsContext::StrokeLines( size_t n, const wxPoint2DDouble *points) { wxASSERT(n > 1); - wxGraphicsPath* path = CreatePath(); - path->MoveToPoint(points[0].m_x, points[0].m_y); + wxGraphicsPath path = CreatePath(); + path.MoveToPoint(points[0].m_x, points[0].m_y); for ( size_t i = 1; i < n; ++i) - path->AddLineToPoint( points[i].m_x, points[i].m_y ); + path.AddLineToPoint( points[i].m_x, points[i].m_y ); StrokePath( path ); - delete path; } void wxGraphicsContext::DrawLines( size_t n, const wxPoint2DDouble *points, int fillStyle) { wxASSERT(n > 1); - wxGraphicsPath* path = CreatePath(); - path->MoveToPoint(points[0].m_x, points[0].m_y); + wxGraphicsPath path = CreatePath(); + path.MoveToPoint(points[0].m_x, points[0].m_y); for ( size_t i = 1; i < n; ++i) - path->AddLineToPoint( points[i].m_x, points[i].m_y ); + path.AddLineToPoint( points[i].m_x, points[i].m_y ); DrawPath( path , fillStyle); - delete path; } void wxGraphicsContext::StrokeLines( size_t n, const wxPoint2DDouble *beginPoints, const wxPoint2DDouble *endPoints) { wxASSERT(n > 0); - wxGraphicsPath* path = CreatePath(); + wxGraphicsPath path = CreatePath(); for ( size_t i = 0; i < n; ++i) { - path->MoveToPoint(beginPoints[i].m_x, beginPoints[i].m_y); - path->AddLineToPoint( endPoints[i].m_x, endPoints[i].m_y ); + path.MoveToPoint(beginPoints[i].m_x, beginPoints[i].m_y); + path.AddLineToPoint( endPoints[i].m_x, endPoints[i].m_y ); } StrokePath( path ); - delete path; } // create a 'native' matrix corresponding to these values -wxGraphicsMatrix* wxGraphicsContext::CreateMatrix( wxDouble a, wxDouble b, wxDouble c, wxDouble d, - wxDouble tx, wxDouble ty) +wxGraphicsMatrix wxGraphicsContext::CreateMatrix( wxDouble a, wxDouble b, wxDouble c, wxDouble d, + wxDouble tx, wxDouble ty) const { return GetRenderer()->CreateMatrix(a,b,c,d,tx,ty); } -wxGraphicsPath * wxGraphicsContext::CreatePath() +wxGraphicsPath wxGraphicsContext::CreatePath() const { return GetRenderer()->CreatePath(); } -wxGraphicsPen wxGraphicsContext::CreatePen(const wxPen& pen) +wxGraphicsPen wxGraphicsContext::CreatePen(const wxPen& pen) const { return GetRenderer()->CreatePen(pen); } -wxGraphicsBrush wxGraphicsContext::CreateBrush(const wxBrush& brush ) +wxGraphicsBrush wxGraphicsContext::CreateBrush(const wxBrush& brush ) const { return GetRenderer()->CreateBrush(brush); } // sets the brush to a linear gradient, starting at (x1,y1) with color c1 to (x2,y2) with color c2 wxGraphicsBrush wxGraphicsContext::CreateLinearGradientBrush( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2, - const wxColour&c1, const wxColour&c2) + const wxColour&c1, const wxColour&c2) const { return GetRenderer()->CreateLinearGradientBrush(x1,y1,x2,y2,c1,c2); } @@ -442,13 +650,13 @@ wxGraphicsBrush wxGraphicsContext::CreateLinearGradientBrush( wxDouble x1, wxDou // sets the brush to a radial gradient originating at (xo,yc) with color oColor and ends on a circle around (xc,yc) // with radius r and color cColor wxGraphicsBrush wxGraphicsContext::CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius, - const wxColour &oColor, const wxColour &cColor) + const wxColour &oColor, const wxColour &cColor) const { return GetRenderer()->CreateRadialGradientBrush(xo,yo,xc,yc,radius,oColor,cColor); } // sets the font -wxGraphicsFont wxGraphicsContext::CreateFont( const wxFont &font , const wxColour &col ) +wxGraphicsFont wxGraphicsContext::CreateFont( const wxFont &font , const wxColour &col ) const { return GetRenderer()->CreateFont(font,col); } @@ -473,4 +681,10 @@ wxGraphicsContext* wxGraphicsContext::Create( wxWindow* window ) return wxGraphicsRenderer::GetDefaultRenderer()->CreateContext(window); } +//----------------------------------------------------------------------------- +// wxGraphicsRenderer +//----------------------------------------------------------------------------- + +IMPLEMENT_ABSTRACT_CLASS(wxGraphicsRenderer, wxObject) + #endif // wxUSE_GRAPHICS_CONTEXT diff --git a/src/msw/graphics.cpp b/src/msw/graphics.cpp index 520da0e709..4e847c1897 100644 --- a/src/msw/graphics.cpp +++ b/src/msw/graphics.cpp @@ -92,14 +92,13 @@ static inline double RadToDeg(double deg) { return (deg * 180.0) / M_PI; } #include "gdiplus.h" using namespace Gdiplus; -class WXDLLIMPEXP_CORE wxGDIPlusPath : public wxGraphicsPath +class WXDLLIMPEXP_CORE wxGDIPlusPathData : public wxGraphicsPathData { public : - wxGDIPlusPath(); - wxGDIPlusPath(wxGraphicsRenderer* renderer, GraphicsPath* path = NULL); - ~wxGDIPlusPath(); + wxGDIPlusPathData(wxGraphicsRenderer* renderer, GraphicsPath* path = NULL); + ~wxGDIPlusPathData(); - virtual wxGraphicsPath *Clone() const; + virtual wxGraphicsObjectRefData *Clone() const; // // These are the path primitives from which everything else can be constructed @@ -119,10 +118,10 @@ public : virtual void AddArc( wxDouble x, wxDouble y, wxDouble r, wxDouble startAngle, wxDouble endAngle, bool clockwise ) ; // gets the last point of the current path, (0,0) if not yet set - virtual void GetCurrentPoint( wxDouble& x, wxDouble&y) ; + virtual void GetCurrentPoint( wxDouble* x, wxDouble* y) const; // adds another path - virtual void AddPath( const wxGraphicsPath* path ); + virtual void AddPath( const wxGraphicsPathData* path ); // closes the current sub-path virtual void CloseSubpath(); @@ -147,36 +146,30 @@ public : virtual void * GetNativePath() const { return m_path; } // give the native path returned by GetNativePath() back (there might be some deallocations necessary) - virtual void UnGetNativePath(void * WXUNUSED(path)) {} + virtual void UnGetNativePath(void * WXUNUSED(path)) const {} // transforms each point of this path by the matrix - virtual void Transform( wxGraphicsMatrix* matrix ) ; + virtual void Transform( const wxGraphicsMatrixData* matrix ) ; // gets the bounding box enclosing all points (possibly including control points) - virtual void GetBox(wxDouble *x, wxDouble *y, wxDouble *w, wxDouble *h) ; + virtual void GetBox(wxDouble *x, wxDouble *y, wxDouble *w, wxDouble *h) const; - virtual bool Contains( wxDouble x, wxDouble y, int fillStyle = wxWINDING_RULE) ; + virtual bool Contains( wxDouble x, wxDouble y, int fillStyle = wxODDEVEN_RULE) const; private : GraphicsPath* m_path; - DECLARE_DYNAMIC_CLASS_NO_COPY(wxGDIPlusPath) }; -class WXDLLIMPEXP_CORE wxGDIPlusMatrix : public wxGraphicsMatrix +class WXDLLIMPEXP_CORE wxGDIPlusMatrixData : public wxGraphicsMatrixData { public : - wxGDIPlusMatrix() ; + wxGDIPlusMatrixData(wxGraphicsRenderer* renderer, Matrix* matrix = NULL) ; + virtual ~wxGDIPlusMatrixData() ; - wxGDIPlusMatrix(wxGraphicsRenderer* renderer, Matrix* matrix = NULL ) ; - virtual ~wxGDIPlusMatrix() ; - - virtual wxGraphicsMatrix *Clone() const ; + virtual wxGraphicsObjectRefData* Clone() const ; // concatenates the matrix - virtual void Concat( const wxGraphicsMatrix *t ); - - // copies the passed in matrix - virtual void Copy( const wxGraphicsMatrix *t ); + virtual void Concat( const wxGraphicsMatrixData *t ); // sets the matrix to the respective values virtual void Set(wxDouble a=1.0, wxDouble b=0.0, wxDouble c=0.0, wxDouble d=1.0, @@ -186,10 +179,10 @@ public : virtual void Invert(); // returns true if the elements of the transformation matrix are equal ? - virtual bool IsEqual( const wxGraphicsMatrix* t) const ; + virtual bool IsEqual( const wxGraphicsMatrixData* t) const ; // return true if this is the identity matrix - virtual bool IsIdentity(); + virtual bool IsIdentity() const; // // transformation @@ -209,17 +202,15 @@ public : // // applies that matrix to the point - virtual void TransformPoint( wxDouble *x, wxDouble *y ); + virtual void TransformPoint( wxDouble *x, wxDouble *y ) const; // applies the matrix except for translations - virtual void TransformDistance( wxDouble *dx, wxDouble *dy ); + virtual void TransformDistance( wxDouble *dx, wxDouble *dy ) const; // returns the native representation virtual void * GetNativeMatrix() const; private: Matrix* m_matrix ; - - DECLARE_DYNAMIC_CLASS_NO_COPY(wxGDIPlusMatrix) } ; class WXDLLIMPEXP_CORE wxGDIPlusPenData : public wxGraphicsObjectRefData @@ -295,21 +286,21 @@ public: virtual void * GetNativeContext(); - virtual void StrokePath( const wxGraphicsPath *p ); - virtual void FillPath( const wxGraphicsPath *p , int fillStyle = wxWINDING_RULE ); + virtual void StrokePath( const wxGraphicsPath& p ); + virtual void FillPath( const wxGraphicsPath& p , int fillStyle = wxODDEVEN_RULE ); virtual void Translate( wxDouble dx , wxDouble dy ); virtual void Scale( wxDouble xScale , wxDouble yScale ); virtual void Rotate( wxDouble angle ); // concatenates this transform with the current transform of this context - virtual void ConcatTransform( const wxGraphicsMatrix* matrix ); + virtual void ConcatTransform( const wxGraphicsMatrix& matrix ); // sets the transform of this context - virtual void SetTransform( const wxGraphicsMatrix* matrix ); + virtual void SetTransform( const wxGraphicsMatrix& matrix ); // gets the matrix of this context - virtual void GetTransform( wxGraphicsMatrix* matrix ); + virtual wxGraphicsMatrix GetTransform() const; virtual void DrawBitmap( const wxBitmap &bmp, wxDouble x, wxDouble y, wxDouble w, wxDouble h ); virtual void DrawIcon( const wxIcon &icon, wxDouble x, wxDouble y, wxDouble w, wxDouble h ); @@ -624,9 +615,7 @@ wxGDIPlusFontData::~wxGDIPlusFontData() // wxGDIPlusPath implementation //----------------------------------------------------------------------------- -IMPLEMENT_DYNAMIC_CLASS(wxGDIPlusPath,wxGraphicsPath) - -wxGDIPlusPath::wxGDIPlusPath(wxGraphicsRenderer* renderer, GraphicsPath* path ) : wxGraphicsPath(renderer) +wxGDIPlusPathData::wxGDIPlusPathData(wxGraphicsRenderer* renderer, GraphicsPath* path ) : wxGraphicsPathData(renderer) { if ( path ) m_path = path; @@ -634,45 +623,37 @@ wxGDIPlusPath::wxGDIPlusPath(wxGraphicsRenderer* renderer, GraphicsPath* path ) m_path = new GraphicsPath(); } -wxGDIPlusPath::wxGDIPlusPath() : wxGraphicsPath(NULL) -{ - wxLogDebug(wxT("Illegal Constructor called")); -} - - -wxGDIPlusPath::~wxGDIPlusPath() +wxGDIPlusPathData::~wxGDIPlusPathData() { delete m_path; } -wxGraphicsPath* wxGDIPlusPath::Clone() const +wxGraphicsObjectRefData* wxGDIPlusPathData::Clone() const { - return new wxGDIPlusPath( GetRenderer() , m_path->Clone()); + return new wxGDIPlusPathData( GetRenderer() , m_path->Clone()); } - - // // The Primitives // -void wxGDIPlusPath::MoveToPoint( wxDouble x , wxDouble y ) +void wxGDIPlusPathData::MoveToPoint( wxDouble x , wxDouble y ) { m_path->StartFigure(); m_path->AddLine((REAL) x,(REAL) y,(REAL) x,(REAL) y); } -void wxGDIPlusPath::AddLineToPoint( wxDouble x , wxDouble y ) +void wxGDIPlusPathData::AddLineToPoint( wxDouble x , wxDouble y ) { m_path->AddLine((REAL) x,(REAL) y,(REAL) x,(REAL) y); } -void wxGDIPlusPath::CloseSubpath() +void wxGDIPlusPathData::CloseSubpath() { m_path->CloseFigure(); } -void wxGDIPlusPath::AddCurveToPoint( wxDouble cx1, wxDouble cy1, wxDouble cx2, wxDouble cy2, wxDouble x, wxDouble y ) +void wxGDIPlusPathData::AddCurveToPoint( wxDouble cx1, wxDouble cy1, wxDouble cx2, wxDouble cy2, wxDouble x, wxDouble y ) { PointF c1(cx1,cy1); PointF c2(cx2,cy2); @@ -683,15 +664,15 @@ void wxGDIPlusPath::AddCurveToPoint( wxDouble cx1, wxDouble cy1, wxDouble cx2, w } // gets the last point of the current path, (0,0) if not yet set -void wxGDIPlusPath::GetCurrentPoint( wxDouble& x, wxDouble&y) +void wxGDIPlusPathData::GetCurrentPoint( wxDouble* x, wxDouble* y) const { PointF start; m_path->GetLastPoint(&start); - x = start.X ; - y = start.Y ; + *x = start.X ; + *y = start.Y ; } -void wxGDIPlusPath::AddArc( wxDouble x, wxDouble y, wxDouble r, double startAngle, double endAngle, bool clockwise ) +void wxGDIPlusPathData::AddArc( wxDouble x, wxDouble y, wxDouble r, double startAngle, double endAngle, bool clockwise ) { double sweepAngle = endAngle - startAngle ; if( abs(sweepAngle) >= 2*M_PI) @@ -715,25 +696,25 @@ void wxGDIPlusPath::AddArc( wxDouble x, wxDouble y, wxDouble r, double startAngl m_path->AddArc((REAL) (x-r),(REAL) (y-r),(REAL) (2*r),(REAL) (2*r),RadToDeg(startAngle),RadToDeg(sweepAngle)); } -void wxGDIPlusPath::AddRectangle( wxDouble x, wxDouble y, wxDouble w, wxDouble h ) +void wxGDIPlusPathData::AddRectangle( wxDouble x, wxDouble y, wxDouble w, wxDouble h ) { m_path->AddRectangle(RectF(x,y,w,h)); } -void wxGDIPlusPath::AddPath( const wxGraphicsPath* path ) +void wxGDIPlusPathData::AddPath( const wxGraphicsPathData* path ) { m_path->AddPath( (GraphicsPath*) path->GetNativePath(), FALSE); } // transforms each point of this path by the matrix -void wxGDIPlusPath::Transform( wxGraphicsMatrix* matrix ) +void wxGDIPlusPathData::Transform( const wxGraphicsMatrixData* matrix ) { m_path->Transform( (Matrix*) matrix->GetNativeMatrix() ); } // gets the bounding box enclosing all points (possibly including control points) -void wxGDIPlusPath::GetBox(wxDouble *x, wxDouble *y, wxDouble *w, wxDouble *h) +void wxGDIPlusPathData::GetBox(wxDouble *x, wxDouble *y, wxDouble *w, wxDouble *h) const { RectF bounds; m_path->GetBounds( &bounds, NULL, NULL) ; @@ -743,25 +724,18 @@ void wxGDIPlusPath::GetBox(wxDouble *x, wxDouble *y, wxDouble *w, wxDouble *h) *h = bounds.Height; } -bool wxGDIPlusPath::Contains( wxDouble x, wxDouble y, int fillStyle ) +bool wxGDIPlusPathData::Contains( wxDouble x, wxDouble y, int fillStyle ) const { m_path->SetFillMode( fillStyle == wxODDEVEN_RULE ? FillModeAlternate : FillModeWinding); return m_path->IsVisible( (FLOAT) x,(FLOAT) y) == TRUE ; } //----------------------------------------------------------------------------- -// wxGDIPlusMatrix implementation +// wxGDIPlusMatrixData implementation //----------------------------------------------------------------------------- -IMPLEMENT_DYNAMIC_CLASS(wxGDIPlusMatrix,wxGraphicsMatrix) - -wxGDIPlusMatrix::wxGDIPlusMatrix() : wxGraphicsMatrix(NULL) -{ - wxLogDebug(wxT("Illegal Constructor called")); -} - -wxGDIPlusMatrix::wxGDIPlusMatrix(wxGraphicsRenderer* renderer, Matrix* matrix ) - : wxGraphicsMatrix(renderer) +wxGDIPlusMatrixData::wxGDIPlusMatrixData(wxGraphicsRenderer* renderer, Matrix* matrix ) + : wxGraphicsMatrixData(renderer) { if ( matrix ) m_matrix = matrix ; @@ -769,50 +743,43 @@ wxGDIPlusMatrix::wxGDIPlusMatrix(wxGraphicsRenderer* renderer, Matrix* matrix ) m_matrix = new Matrix(); } -wxGDIPlusMatrix::~wxGDIPlusMatrix() +wxGDIPlusMatrixData::~wxGDIPlusMatrixData() { delete m_matrix; } -wxGraphicsMatrix *wxGDIPlusMatrix::Clone() const +wxGraphicsObjectRefData *wxGDIPlusMatrixData::Clone() const { - return new wxGDIPlusMatrix( GetRenderer(), m_matrix->Clone()); + return new wxGDIPlusMatrixData( GetRenderer(), m_matrix->Clone()); } // concatenates the matrix -void wxGDIPlusMatrix::Concat( const wxGraphicsMatrix *t ) +void wxGDIPlusMatrixData::Concat( const wxGraphicsMatrixData *t ) { m_matrix->Multiply( (Matrix*) t->GetNativeMatrix()); } -// copies the passed in matrix -void wxGDIPlusMatrix::Copy( const wxGraphicsMatrix *t ) -{ - delete m_matrix; - m_matrix = ((Matrix*) t->GetNativeMatrix())->Clone(); -} - // sets the matrix to the respective values -void wxGDIPlusMatrix::Set(wxDouble a, wxDouble b, wxDouble c, wxDouble d, +void wxGDIPlusMatrixData::Set(wxDouble a, wxDouble b, wxDouble c, wxDouble d, wxDouble tx, wxDouble ty) { m_matrix->SetElements(a,b,c,d,tx,ty); } // makes this the inverse matrix -void wxGDIPlusMatrix::Invert() +void wxGDIPlusMatrixData::Invert() { m_matrix->Invert(); } // returns true if the elements of the transformation matrix are equal ? -bool wxGDIPlusMatrix::IsEqual( const wxGraphicsMatrix* t) const +bool wxGDIPlusMatrixData::IsEqual( const wxGraphicsMatrixData* t) const { return m_matrix->Equals((Matrix*) t->GetNativeMatrix())== TRUE ; } // return true if this is the identity matrix -bool wxGDIPlusMatrix::IsIdentity() +bool wxGDIPlusMatrixData::IsIdentity() const { return m_matrix->IsIdentity() == TRUE ; } @@ -822,19 +789,19 @@ bool wxGDIPlusMatrix::IsIdentity() // // add the translation to this matrix -void wxGDIPlusMatrix::Translate( wxDouble dx , wxDouble dy ) +void wxGDIPlusMatrixData::Translate( wxDouble dx , wxDouble dy ) { m_matrix->Translate(dx,dy); } // add the scale to this matrix -void wxGDIPlusMatrix::Scale( wxDouble xScale , wxDouble yScale ) +void wxGDIPlusMatrixData::Scale( wxDouble xScale , wxDouble yScale ) { m_matrix->Scale(xScale,yScale); } // add the rotation to this matrix (radians) -void wxGDIPlusMatrix::Rotate( wxDouble angle ) +void wxGDIPlusMatrixData::Rotate( wxDouble angle ) { m_matrix->Rotate( angle ); } @@ -844,7 +811,7 @@ void wxGDIPlusMatrix::Rotate( wxDouble angle ) // // applies that matrix to the point -void wxGDIPlusMatrix::TransformPoint( wxDouble *x, wxDouble *y ) +void wxGDIPlusMatrixData::TransformPoint( wxDouble *x, wxDouble *y ) const { PointF pt(*x,*y); m_matrix->TransformPoints(&pt); @@ -853,7 +820,7 @@ void wxGDIPlusMatrix::TransformPoint( wxDouble *x, wxDouble *y ) } // applies the matrix except for translations -void wxGDIPlusMatrix::TransformDistance( wxDouble *dx, wxDouble *dy ) +void wxGDIPlusMatrixData::TransformDistance( wxDouble *dx, wxDouble *dy ) const { PointF pt(*dx,*dy); m_matrix->TransformVectors(&pt); @@ -862,7 +829,7 @@ void wxGDIPlusMatrix::TransformDistance( wxDouble *dx, wxDouble *dy ) } // returns the native representation -void * wxGDIPlusMatrix::GetNativeMatrix() const +void * wxGDIPlusMatrixData::GetNativeMatrix() const { return m_matrix; } @@ -942,21 +909,21 @@ void wxGDIPlusContext::ResetClip() m_context->ResetClip(); } -void wxGDIPlusContext::StrokePath( const wxGraphicsPath *path ) +void wxGDIPlusContext::StrokePath( const wxGraphicsPath& path ) { if ( !m_pen.IsNull() ) { - m_context->DrawPath( ((wxGDIPlusPenData*)m_pen.GetGraphicsData())->GetGDIPlusPen() , (GraphicsPath*) path->GetNativePath() ); + m_context->DrawPath( ((wxGDIPlusPenData*)m_pen.GetGraphicsData())->GetGDIPlusPen() , (GraphicsPath*) path.GetNativePath() ); } } -void wxGDIPlusContext::FillPath( const wxGraphicsPath *path , int fillStyle ) +void wxGDIPlusContext::FillPath( const wxGraphicsPath& path , int fillStyle ) { if ( !m_brush.IsNull() ) { - ((GraphicsPath*) path->GetNativePath())->SetFillMode( fillStyle == wxODDEVEN_RULE ? FillModeAlternate : FillModeWinding); + ((GraphicsPath*) path.GetNativePath())->SetFillMode( fillStyle == wxODDEVEN_RULE ? FillModeAlternate : FillModeWinding); m_context->FillPath( ((wxGDIPlusBrushData*)m_brush.GetRefData())->GetGDIPlusBrush() , - (GraphicsPath*) path->GetNativePath()); + (GraphicsPath*) path.GetNativePath()); } } @@ -1216,21 +1183,23 @@ void* wxGDIPlusContext::GetNativeContext() } // concatenates this transform with the current transform of this context -void wxGDIPlusContext::ConcatTransform( const wxGraphicsMatrix* matrix ) +void wxGDIPlusContext::ConcatTransform( const wxGraphicsMatrix& matrix ) { - m_context->MultiplyTransform((Matrix*) matrix->GetNativeMatrix()); + m_context->MultiplyTransform((Matrix*) matrix.GetNativeMatrix()); } // sets the transform of this context -void wxGDIPlusContext::SetTransform( const wxGraphicsMatrix* matrix ) +void wxGDIPlusContext::SetTransform( const wxGraphicsMatrix& matrix ) { - m_context->SetTransform((Matrix*) matrix->GetNativeMatrix()); + m_context->SetTransform((Matrix*) matrix.GetNativeMatrix()); } // gets the matrix of this context -void wxGDIPlusContext::GetTransform( wxGraphicsMatrix* matrix ) +wxGraphicsMatrix wxGDIPlusContext::GetTransform() const { - m_context->GetTransform((Matrix*) matrix->GetNativeMatrix()); + wxGraphicsMatrix matrix = CreateMatrix(); + m_context->GetTransform((Matrix*) matrix.GetNativeMatrix()); + return matrix; } //----------------------------------------------------------------------------- // wxGDIPlusRenderer declaration @@ -1265,11 +1234,11 @@ public : // Path - virtual wxGraphicsPath * CreatePath(); + virtual wxGraphicsPath CreatePath(); // Matrix - virtual wxGraphicsMatrix * CreateMatrix( wxDouble a=1.0, wxDouble b=0.0, wxDouble c=0.0, wxDouble d=1.0, + virtual wxGraphicsMatrix CreateMatrix( wxDouble a=1.0, wxDouble b=0.0, wxDouble c=0.0, wxDouble d=1.0, wxDouble tx=0.0, wxDouble ty=0.0); @@ -1362,22 +1331,26 @@ wxGraphicsContext * wxGDIPlusRenderer::CreateContext( wxWindow* window ) // Path -wxGraphicsPath * wxGDIPlusRenderer::CreatePath() +wxGraphicsPath wxGDIPlusRenderer::CreatePath() { EnsureIsLoaded(); - return new wxGDIPlusPath( this ); + wxGraphicsPath m; + m.SetRefData( new wxGDIPlusPathData(this)); + return m; } // Matrix -wxGraphicsMatrix * wxGDIPlusRenderer::CreateMatrix( wxDouble a, wxDouble b, wxDouble c, wxDouble d, +wxGraphicsMatrix wxGDIPlusRenderer::CreateMatrix( wxDouble a, wxDouble b, wxDouble c, wxDouble d, wxDouble tx, wxDouble ty) { EnsureIsLoaded(); - wxGDIPlusMatrix* m = new wxGDIPlusMatrix( this ); - m->Set( a,b,c,d,tx,ty ) ; + wxGraphicsMatrix m; + wxGDIPlusMatrixData* data = new wxGDIPlusMatrixData( this ); + data->Set( a,b,c,d,tx,ty ) ; + m.SetRefData(data); return m; } -- 2.45.2