From 2c8204062697e1d3c6600bc73c40c97fd29a13dd Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Fri, 27 Oct 2006 14:21:27 +0000 Subject: [PATCH] changing graphics pen, brushes and fonts to be refcounted objects, having no subclasses git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@42528 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/graphics.h | 97 ++++++++++++--------- src/common/graphcmn.cpp | 119 +++++++++++++++++-------- src/msw/graphics.cpp | 186 ++++++++++++++++------------------------ 3 files changed, 216 insertions(+), 186 deletions(-) diff --git a/include/wx/graphics.h b/include/wx/graphics.h index a2d858d11b..0ef6bb528a 100755 --- a/include/wx/graphics.h +++ b/include/wx/graphics.h @@ -37,56 +37,78 @@ class WXDLLIMPEXP_CORE wxGraphicsFont; // Base class of all objects used for drawing in the new graphics API, the always point back to their // originating rendering engine, there is no dynamic unloading of a renderer currently allowed, // these references are not counted + +// +// The data used by objects like graphics pens etc is ref counted, in order to avoid unnecessary expensive +// duplication. Any operation on a shared instance that results in a modified state, uncouples this +// instance from the other instances that were shared - using copy on write semantics +// +class WXDLLIMPEXP_CORE wxGraphicsObjectRefData : public wxObjectRefData +{ +public : + wxGraphicsObjectRefData( wxGraphicsRenderer* renderer ); + wxGraphicsObjectRefData( const wxGraphicsObjectRefData* data ); + wxGraphicsRenderer* GetRenderer() const ; + virtual wxGraphicsObjectRefData* Clone() const ; + +protected : + wxGraphicsRenderer* m_renderer; +} ; + class WXDLLIMPEXP_CORE wxGraphicsObject : public wxObject { public : - wxGraphicsObject( wxGraphicsRenderer* renderer = NULL ) : m_renderer(renderer) {} + wxGraphicsObject() ; + wxGraphicsObject( wxGraphicsRenderer* renderer ) ; + virtual ~wxGraphicsObject() ; - wxGraphicsObject( const wxGraphicsObject& obj ) : m_renderer(obj.GetRenderer()) {} - - virtual ~wxGraphicsObject() {} - - wxGraphicsRenderer* GetRenderer() const { return m_renderer ; } + bool IsNull() const ; + + // returns the renderer that was used to create this instance, or NULL if it has not been initialized yet + wxGraphicsRenderer* GetRenderer() const ; + wxGraphicsObjectRefData* GetGraphicsData() const ; protected : - wxGraphicsRenderer* m_renderer; + virtual wxObjectRefData* CreateRefData() const; + virtual wxObjectRefData* CloneRefData(const wxObjectRefData* data) const; + DECLARE_DYNAMIC_CLASS(wxGraphicsObject); } ; class WXDLLIMPEXP_CORE wxGraphicsPen : public wxGraphicsObject { public : - wxGraphicsPen(wxGraphicsRenderer* renderer) : wxGraphicsObject(renderer) {} + wxGraphicsPen() {} virtual ~wxGraphicsPen() {} - virtual void Apply( wxGraphicsContext* context) = 0; - virtual wxDouble GetWidth() = 0; private : - DECLARE_NO_COPY_CLASS(wxGraphicsPen) - DECLARE_ABSTRACT_CLASS(wxGraphicsPen) + DECLARE_DYNAMIC_CLASS(wxGraphicsPen) } ; +extern WXDLLEXPORT_DATA(wxGraphicsPen) wxNullGraphicsPen; + class WXDLLIMPEXP_CORE wxGraphicsBrush : public wxGraphicsObject { public : - wxGraphicsBrush(wxGraphicsRenderer* renderer) : wxGraphicsObject(renderer) {} + wxGraphicsBrush() {} virtual ~wxGraphicsBrush() {} - virtual void Apply( wxGraphicsContext* context) = 0; private : - DECLARE_NO_COPY_CLASS(wxGraphicsBrush) - DECLARE_ABSTRACT_CLASS(wxGraphicsBrush) + DECLARE_DYNAMIC_CLASS(wxGraphicsBrush) } ; +extern WXDLLEXPORT_DATA(wxGraphicsBrush) wxNullGraphicsBrush; + class WXDLLIMPEXP_CORE wxGraphicsFont : public wxGraphicsObject { public : - wxGraphicsFont(wxGraphicsRenderer* renderer) : wxGraphicsObject(renderer) {} + wxGraphicsFont() {} virtual ~wxGraphicsFont() {} - virtual void Apply( wxGraphicsContext* context) = 0; private : - DECLARE_NO_COPY_CLASS(wxGraphicsFont) - DECLARE_ABSTRACT_CLASS(wxGraphicsFont) + DECLARE_DYNAMIC_CLASS(wxGraphicsFont) } ; +extern WXDLLEXPORT_DATA(wxGraphicsFont) wxNullGraphicsFont; + + class WXDLLIMPEXP_CORE wxGraphicsPath : public wxGraphicsObject { public : @@ -246,21 +268,21 @@ public: wxGraphicsPath * CreatePath(); - virtual wxGraphicsPen* CreatePen(const wxPen& pen); + virtual wxGraphicsPen CreatePen(const wxPen& pen); - virtual wxGraphicsBrush* CreateBrush(const wxBrush& brush ); + virtual wxGraphicsBrush CreateBrush(const wxBrush& brush ); // 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, + virtual wxGraphicsBrush CreateLinearGradientBrush( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2, const wxColour&c1, const wxColour&c2); // 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, + virtual wxGraphicsBrush CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius, const wxColour &oColor, const wxColour &cColor); // sets the font - virtual wxGraphicsFont* CreateFont( const wxFont &font , const wxColour &col = *wxBLACK ); + virtual wxGraphicsFont CreateFont( const wxFont &font , const wxColour &col = *wxBLACK ); // 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, @@ -310,17 +332,17 @@ public: // // sets the pen - virtual void SetPen( wxGraphicsPen* pen , bool release = true ); + virtual void SetPen( const wxGraphicsPen& pen ); void SetPen( const wxPen& pen ); // sets the brush for filling - virtual void SetBrush( wxGraphicsBrush* brush , bool release = true ); + virtual void SetBrush( const wxGraphicsBrush& brush ); void SetBrush( const wxBrush& brush ); // sets the font - virtual void SetFont( wxGraphicsFont* font, bool release = true ); + virtual void SetFont( const wxGraphicsFont& font ); void SetFont( const wxFont& font, const wxColour& colour ); @@ -387,12 +409,9 @@ public: protected : - wxGraphicsPen* m_pen; - bool m_releasePen; - wxGraphicsBrush* m_brush; - bool m_releaseBrush; - wxGraphicsFont* m_font; - bool m_releaseFont; + wxGraphicsPen m_pen; + wxGraphicsBrush m_brush; + wxGraphicsFont m_font; private : DECLARE_NO_COPY_CLASS(wxGraphicsContext) @@ -470,21 +489,21 @@ public : // Paints - virtual wxGraphicsPen* CreatePen(const wxPen& pen) = 0 ; + virtual wxGraphicsPen CreatePen(const wxPen& pen) = 0 ; - virtual wxGraphicsBrush* CreateBrush(const wxBrush& brush ) = 0 ; + virtual wxGraphicsBrush CreateBrush(const wxBrush& brush ) = 0 ; // 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, + virtual wxGraphicsBrush CreateLinearGradientBrush( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2, const wxColour&c1, const wxColour&c2) = 0; // 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, + virtual wxGraphicsBrush CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius, const wxColour &oColor, const wxColour &cColor) = 0; // sets the font - virtual wxGraphicsFont* CreateFont( const wxFont &font , const wxColour &col = *wxBLACK ) = 0; + virtual wxGraphicsFont CreateFont( const wxFont &font , const wxColour &col = *wxBLACK ) = 0; private : DECLARE_NO_COPY_CLASS(wxGraphicsRenderer) diff --git a/src/common/graphcmn.cpp b/src/common/graphcmn.cpp index 36a3d228db..da3504a4b2 100644 --- a/src/common/graphcmn.cpp +++ b/src/common/graphcmn.cpp @@ -48,19 +48,84 @@ static inline double DegToRad(double deg) //----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// wxGraphicsObject +//----------------------------------------------------------------------------- + IMPLEMENT_DYNAMIC_CLASS(wxGraphicsObject, wxObject) -IMPLEMENT_ABSTRACT_CLASS(wxGraphicsRenderer, wxObject) +wxGraphicsObjectRefData::wxGraphicsObjectRefData( wxGraphicsRenderer* renderer ) +{ + m_renderer = renderer; +} +wxGraphicsObjectRefData::wxGraphicsObjectRefData( const wxGraphicsObjectRefData* data ) +{ + m_renderer = data->m_renderer; +} +wxGraphicsRenderer* wxGraphicsObjectRefData::GetRenderer() const +{ + return m_renderer ; +} -IMPLEMENT_ABSTRACT_CLASS(wxGraphicsMatrix, wxGraphicsObject) +wxGraphicsObjectRefData* wxGraphicsObjectRefData::Clone() const +{ + return new wxGraphicsObjectRefData(this); +} -IMPLEMENT_ABSTRACT_CLASS(wxGraphicsPath, wxGraphicsObject) +wxGraphicsObject::wxGraphicsObject() +{ +} -IMPLEMENT_ABSTRACT_CLASS(wxGraphicsPen, wxGraphicsObject) +wxGraphicsObject::wxGraphicsObject( wxGraphicsRenderer* renderer ) +{ + SetRefData( new wxGraphicsObjectRefData(renderer)); +} -IMPLEMENT_ABSTRACT_CLASS(wxGraphicsBrush, wxGraphicsObject) +wxGraphicsObject::~wxGraphicsObject() +{ +} -IMPLEMENT_ABSTRACT_CLASS(wxGraphicsFont, wxGraphicsObject) +bool wxGraphicsObject::IsNull() const +{ + return m_refData == NULL; +} + +wxGraphicsRenderer* wxGraphicsObject::GetRenderer() const +{ + return ( IsNull() ? NULL : GetGraphicsData()->GetRenderer() ); +} + +wxGraphicsObjectRefData* wxGraphicsObject::GetGraphicsData() const +{ + return (wxGraphicsObjectRefData*) m_refData; +} + +wxObjectRefData* wxGraphicsObject::CreateRefData() const +{ + wxLogDebug(wxT("A Null Object cannot be changed")); + return NULL; +} + +wxObjectRefData* wxGraphicsObject::CloneRefData(const wxObjectRefData* data) const +{ + const wxGraphicsObjectRefData* ptr = (const wxGraphicsObjectRefData*) data; + return ptr->Clone(); +} + +//----------------------------------------------------------------------------- +// pens etc. +//----------------------------------------------------------------------------- + +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) wxPoint2DDouble wxGraphicsPath::GetCurrentPoint() { @@ -208,66 +273,52 @@ IMPLEMENT_ABSTRACT_CLASS(wxGraphicsContext, wxObject) wxGraphicsContext::wxGraphicsContext(wxGraphicsRenderer* renderer) : wxGraphicsObject(renderer) { - m_pen = NULL; - m_releasePen = false; - m_brush = NULL; - m_releaseBrush = false; - m_font = NULL; - m_releaseFont = false; } wxGraphicsContext::~wxGraphicsContext() { - wxASSERT_MSG( m_pen == NULL , wxT("No pen should be selected during destruction") ); - wxASSERT_MSG( m_brush == NULL , wxT("No pen should be selected during destruction") ); } // sets the pen -void wxGraphicsContext::SetPen( wxGraphicsPen* pen , bool release ) +void wxGraphicsContext::SetPen( const wxGraphicsPen& pen ) { - if ( m_releasePen ) - delete m_pen; m_pen = pen; - m_releasePen = release; } void wxGraphicsContext::SetPen( const wxPen& pen ) { if ( pen.GetStyle() == wxTRANSPARENT ) - SetPen( NULL ); + SetPen( wxNullGraphicsPen ); else SetPen( CreatePen( pen ) ); } // sets the brush for filling -void wxGraphicsContext::SetBrush( wxGraphicsBrush* brush , bool release ) +void wxGraphicsContext::SetBrush( const wxGraphicsBrush& brush ) { - if ( m_releaseBrush ) - delete m_brush; m_brush = brush; - m_releaseBrush = release; } void wxGraphicsContext::SetBrush( const wxBrush& brush ) { if ( brush.GetStyle() == wxTRANSPARENT ) - SetBrush( NULL ); + SetBrush( wxNullGraphicsBrush ); else SetBrush( CreateBrush( brush ) ); } // sets the brush for filling -void wxGraphicsContext::SetFont( wxGraphicsFont* font , bool release ) +void wxGraphicsContext::SetFont( const wxGraphicsFont& font ) { - if ( m_releaseFont ) - delete m_font; m_font = font; - m_releaseFont = release; } void wxGraphicsContext::SetFont( const wxFont& font, const wxColour& colour ) { - SetFont( CreateFont( font, colour ) ); + if ( font.Ok() ) + SetFont( CreateFont( font, colour ) ); + else + SetFont( wxNullGraphicsFont ); } void wxGraphicsContext::DrawPath( const wxGraphicsPath *path, int fillStyle ) @@ -365,18 +416,18 @@ wxGraphicsPath * wxGraphicsContext::CreatePath() return GetRenderer()->CreatePath(); } -wxGraphicsPen* wxGraphicsContext::CreatePen(const wxPen& pen) +wxGraphicsPen wxGraphicsContext::CreatePen(const wxPen& pen) { return GetRenderer()->CreatePen(pen); } -wxGraphicsBrush* wxGraphicsContext::CreateBrush(const wxBrush& brush ) +wxGraphicsBrush wxGraphicsContext::CreateBrush(const wxBrush& brush ) { 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, +wxGraphicsBrush wxGraphicsContext::CreateLinearGradientBrush( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2, const wxColour&c1, const wxColour&c2) { return GetRenderer()->CreateLinearGradientBrush(x1,y1,x2,y2,c1,c2); @@ -384,14 +435,14 @@ wxGraphicsBrush* wxGraphicsContext::CreateLinearGradientBrush( wxDouble x1, wxDo // 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, +wxGraphicsBrush wxGraphicsContext::CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius, const wxColour &oColor, const wxColour &cColor) { 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 ) { return GetRenderer()->CreateFont(font,col); } diff --git a/src/msw/graphics.cpp b/src/msw/graphics.cpp index acbbcd7593..520da0e709 100644 --- a/src/msw/graphics.cpp +++ b/src/msw/graphics.cpp @@ -222,16 +222,14 @@ private: DECLARE_DYNAMIC_CLASS_NO_COPY(wxGDIPlusMatrix) } ; -class WXDLLIMPEXP_CORE wxGDIPlusPen : public wxGraphicsPen +class WXDLLIMPEXP_CORE wxGDIPlusPenData : public wxGraphicsObjectRefData { public: - wxGDIPlusPen(); - wxGDIPlusPen( wxGraphicsRenderer* renderer, const wxPen &pen ); - ~wxGDIPlusPen(); + wxGDIPlusPenData( wxGraphicsRenderer* renderer, const wxPen &pen ); + ~wxGDIPlusPenData(); void Init(); - virtual void Apply( wxGraphicsContext* context ); virtual wxDouble GetWidth() { return m_width; } virtual Pen* GetGDIPlusPen() { return m_pen; } @@ -241,19 +239,15 @@ protected : Brush* m_penBrush; wxDouble m_width; -private : - DECLARE_DYNAMIC_CLASS_NO_COPY(wxGDIPlusPen) }; -class WXDLLIMPEXP_CORE wxGDIPlusBrush : public wxGraphicsBrush +class WXDLLIMPEXP_CORE wxGDIPlusBrushData : public wxGraphicsObjectRefData { public: - wxGDIPlusBrush(); - wxGDIPlusBrush( wxGraphicsRenderer* renderer ); - wxGDIPlusBrush( wxGraphicsRenderer* renderer, const wxBrush &brush ); - ~wxGDIPlusBrush (); + wxGDIPlusBrushData( wxGraphicsRenderer* renderer ); + wxGDIPlusBrushData( wxGraphicsRenderer* renderer, const wxBrush &brush ); + ~wxGDIPlusBrushData (); - virtual void Apply( wxGraphicsContext* context ); void CreateLinearGradientBrush( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2, const wxColour&c1, const wxColour&c2 ); void CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius, @@ -267,25 +261,19 @@ private : Brush* m_brush; Image* m_brushImage; GraphicsPath* m_brushPath; - - DECLARE_DYNAMIC_CLASS_NO_COPY(wxGDIPlusBrush) }; -class wxGDIPlusFont : public wxGraphicsFont +class WXDLLIMPEXP_CORE wxGDIPlusFontData : public wxGraphicsObjectRefData { public: - wxGDIPlusFont(); - wxGDIPlusFont( wxGraphicsRenderer* renderer, const wxFont &font, const wxColour& col ); - ~wxGDIPlusFont(); + wxGDIPlusFontData( wxGraphicsRenderer* renderer, const wxFont &font, const wxColour& col ); + ~wxGDIPlusFontData(); - virtual void Apply( wxGraphicsContext* context ); virtual Brush* GetGDIPlusBrush() { return m_textBrush; } virtual Font* GetGDIPlusFont() { return m_font; } private : Brush* m_textBrush; Font* m_font; - - DECLARE_DYNAMIC_CLASS_NO_COPY(wxGDIPlusFont) }; class WXDLLIMPEXP_CORE wxGDIPlusContext : public wxGraphicsContext @@ -349,29 +337,22 @@ private: // wxGDIPlusPen implementation //----------------------------------------------------------------------------- -IMPLEMENT_DYNAMIC_CLASS(wxGDIPlusPen,wxGraphicsPen) - -wxGDIPlusPen::wxGDIPlusPen() : wxGraphicsPen(NULL) -{ - wxLogDebug(wxT("Illegal Constructor called")); -} - -wxGDIPlusPen::~wxGDIPlusPen() +wxGDIPlusPenData::~wxGDIPlusPenData() { delete m_pen; delete m_penImage; delete m_penBrush; } -void wxGDIPlusPen::Init() +void wxGDIPlusPenData::Init() { m_pen = NULL ; m_penImage = NULL; m_penBrush = NULL; } -wxGDIPlusPen::wxGDIPlusPen( wxGraphicsRenderer* renderer, const wxPen &pen ) -: wxGraphicsPen(renderer) +wxGDIPlusPenData::wxGDIPlusPenData( wxGraphicsRenderer* renderer, const wxPen &pen ) +: wxGraphicsObjectRefData(renderer) { Init(); m_width = pen.GetWidth(); @@ -512,33 +493,18 @@ wxGDIPlusPen::wxGDIPlusPen( wxGraphicsRenderer* renderer, const wxPen &pen ) m_pen->SetDashStyle(dashStyle); } -void wxGDIPlusPen::Apply( wxGraphicsContext* WXUNUSED(context) ) -{ - // nothing to do here -} - - //----------------------------------------------------------------------------- // wxGDIPlusBrush implementation //----------------------------------------------------------------------------- -IMPLEMENT_DYNAMIC_CLASS(wxGDIPlusBrush,wxGraphicsBrush) - -wxGDIPlusBrush::wxGDIPlusBrush( wxGraphicsRenderer* renderer ) -: wxGraphicsBrush(renderer) +wxGDIPlusBrushData::wxGDIPlusBrushData( wxGraphicsRenderer* renderer ) +: wxGraphicsObjectRefData(renderer) { Init(); } -wxGDIPlusBrush::wxGDIPlusBrush( ) -: wxGraphicsBrush(NULL) -{ - wxLogDebug(wxT("Illegal Constructor called")); -} - - -wxGDIPlusBrush::wxGDIPlusBrush( wxGraphicsRenderer* renderer , const wxBrush &brush ) -: wxGraphicsBrush(renderer) +wxGDIPlusBrushData::wxGDIPlusBrushData( wxGraphicsRenderer* renderer , const wxBrush &brush ) +: wxGraphicsObjectRefData(renderer) { Init(); if ( brush.GetStyle() == wxSOLID) @@ -586,28 +552,28 @@ wxGDIPlusBrush::wxGDIPlusBrush( wxGraphicsRenderer* renderer , const wxBrush &br } } -wxGDIPlusBrush::~wxGDIPlusBrush() +wxGDIPlusBrushData::~wxGDIPlusBrushData() { delete m_brush; delete m_brushImage; delete m_brushPath; }; -void wxGDIPlusBrush::Init() +void wxGDIPlusBrushData::Init() { m_brush = NULL; m_brushImage= NULL; m_brushPath= NULL; } -void wxGDIPlusBrush::CreateLinearGradientBrush( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2, const wxColour&c1, const wxColour&c2) +void wxGDIPlusBrushData::CreateLinearGradientBrush( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2, const wxColour&c1, const wxColour&c2) { m_brush = new LinearGradientBrush( PointF( x1,y1) , PointF( x2,y2), Color( c1.Alpha(), c1.Red(),c1.Green() , c1.Blue() ), Color( c2.Alpha(), c2.Red(),c2.Green() , c2.Blue() )); } -void wxGDIPlusBrush::CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius, +void wxGDIPlusBrushData::CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius, const wxColour &oColor, const wxColour &cColor) { // Create a path that consists of a single circle. @@ -624,24 +590,12 @@ void wxGDIPlusBrush::CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDoub b->SetSurroundColors(colors, &count); } -void wxGDIPlusBrush::Apply( wxGraphicsContext* WXUNUSED(context) ) -{ - // nothing to do here -} - //----------------------------------------------------------------------------- // wxGDIPlusFont implementation //----------------------------------------------------------------------------- -IMPLEMENT_DYNAMIC_CLASS(wxGDIPlusFont,wxGraphicsFont) - -wxGDIPlusFont::wxGDIPlusFont() : wxGraphicsFont( NULL ) -{ - wxLogDebug(wxT("Illegal Constructor called")); -} - -wxGDIPlusFont::wxGDIPlusFont( wxGraphicsRenderer* renderer, const wxFont &font, - const wxColour& col ) : wxGraphicsFont( renderer ) +wxGDIPlusFontData::wxGDIPlusFontData( wxGraphicsRenderer* renderer, const wxFont &font, + const wxColour& col ) : wxGraphicsObjectRefData( renderer ) { m_textBrush = NULL; m_font = NULL; @@ -660,17 +614,12 @@ wxGDIPlusFont::wxGDIPlusFont( wxGraphicsRenderer* renderer, const wxFont &font, col.Green() , col.Blue() )); } -wxGDIPlusFont::~wxGDIPlusFont() +wxGDIPlusFontData::~wxGDIPlusFontData() { delete m_textBrush; delete m_font; } -void wxGDIPlusFont::Apply( wxGraphicsContext* WXUNUSED(context) ) -{ - // nothing to do here -} - //----------------------------------------------------------------------------- // wxGDIPlusPath implementation //----------------------------------------------------------------------------- @@ -969,10 +918,6 @@ void wxGDIPlusContext::SetDefaults() wxGDIPlusContext::~wxGDIPlusContext() { - SetBrush(NULL); - SetFont(NULL); - SetPen(NULL); - if ( m_context ) { m_context->Restore( m_state2 ); @@ -999,18 +944,18 @@ void wxGDIPlusContext::ResetClip() void wxGDIPlusContext::StrokePath( const wxGraphicsPath *path ) { - if ( m_pen ) + if ( !m_pen.IsNull() ) { - m_context->DrawPath( ((wxGDIPlusPen*)m_pen)->GetGDIPlusPen() , (GraphicsPath*) path->GetNativePath() ); + m_context->DrawPath( ((wxGDIPlusPenData*)m_pen.GetGraphicsData())->GetGDIPlusPen() , (GraphicsPath*) path->GetNativePath() ); } } void wxGDIPlusContext::FillPath( const wxGraphicsPath *path , int fillStyle ) { - if ( m_brush ) + if ( !m_brush.IsNull() ) { ((GraphicsPath*) path->GetNativePath())->SetFillMode( fillStyle == wxODDEVEN_RULE ? FillModeAlternate : FillModeWinding); - m_context->FillPath( ((wxGDIPlusBrush*)m_brush)->GetGDIPlusBrush() , + m_context->FillPath( ((wxGDIPlusBrushData*)m_brush.GetRefData())->GetGDIPlusBrush() , (GraphicsPath*) path->GetNativePath()); } } @@ -1173,15 +1118,14 @@ void wxGDIPlusContext::DrawIcon( const wxIcon &icon, wxDouble x, wxDouble y, wxD DeleteObject(iconInfo.hbmMask); } - void wxGDIPlusContext::DrawText( const wxString &str, wxDouble x, wxDouble y ) { - if ( str.IsEmpty()) + if ( m_font.IsNull() || str.IsEmpty()) return ; wxWCharBuffer s = str.wc_str( *wxConvUI ); - m_context->DrawString( s , -1 , ((wxGDIPlusFont*)m_font)->GetGDIPlusFont() , - PointF( x , y ) , ((wxGDIPlusFont*)m_font)->GetGDIPlusBrush() ); + m_context->DrawString( s , -1 , ((wxGDIPlusFontData*)m_font.GetRefData())->GetGDIPlusFont() , + PointF( x , y ) , ((wxGDIPlusFontData*)m_font.GetRefData())->GetGDIPlusBrush() ); // TODO m_backgroundMode == wxSOLID } @@ -1190,7 +1134,7 @@ void wxGDIPlusContext::GetTextExtent( const wxString &str, wxDouble *width, wxDo { wxWCharBuffer s = str.wc_str( *wxConvUI ); FontFamily ffamily ; - Font* f = ((wxGDIPlusFont*)m_font)->GetGDIPlusFont(); + Font* f = ((wxGDIPlusFontData*)m_font.GetRefData())->GetGDIPlusFont(); f->GetFamily(&ffamily) ; @@ -1240,7 +1184,7 @@ void wxGDIPlusContext::GetPartialTextExtents(const wxString& text, wxArrayDouble if (text.empty()) return; - Font* f = ((wxGDIPlusFont*)m_font)->GetGDIPlusFont(); + Font* f = ((wxGDIPlusFontData*)m_font.GetRefData())->GetGDIPlusFont(); wxWCharBuffer ws = text.wc_str( *wxConvUI ); size_t len = wcslen( ws ) ; wxASSERT_MSG(text.length() == len , wxT("GetPartialTextExtents not yet implemented for multichar situations")); @@ -1329,21 +1273,21 @@ public : wxDouble tx=0.0, wxDouble ty=0.0); - virtual wxGraphicsPen* CreatePen(const wxPen& pen) ; + virtual wxGraphicsPen CreatePen(const wxPen& pen) ; - virtual wxGraphicsBrush* CreateBrush(const wxBrush& brush ) ; + virtual wxGraphicsBrush CreateBrush(const wxBrush& brush ) ; // 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, + virtual wxGraphicsBrush CreateLinearGradientBrush( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2, const wxColour&c1, const wxColour&c2) ; // 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, + virtual wxGraphicsBrush CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius, const wxColour &oColor, const wxColour &cColor) ; // sets the font - virtual wxGraphicsFont* CreateFont( const wxFont &font , const wxColour &col = *wxBLACK ) ; + virtual wxGraphicsFont CreateFont( const wxFont &font , const wxColour &col = *wxBLACK ) ; protected : void EnsureIsLoaded(); void Load(); @@ -1437,53 +1381,69 @@ wxGraphicsMatrix * wxGDIPlusRenderer::CreateMatrix( wxDouble a, wxDouble b, wxDo return m; } -wxGraphicsPen* wxGDIPlusRenderer::CreatePen(const wxPen& pen) +wxGraphicsPen wxGDIPlusRenderer::CreatePen(const wxPen& pen) { EnsureIsLoaded(); if ( !pen.Ok() || pen.GetStyle() == wxTRANSPARENT ) - return NULL; + return wxNullGraphicsPen; else - return new wxGDIPlusPen( this, pen ); + { + wxGraphicsPen p; + p.SetRefData(new wxGDIPlusPenData( this, pen )); + return p; + } } -wxGraphicsBrush* wxGDIPlusRenderer::CreateBrush(const wxBrush& brush ) +wxGraphicsBrush wxGDIPlusRenderer::CreateBrush(const wxBrush& brush ) { EnsureIsLoaded(); if ( !brush.Ok() || brush.GetStyle() == wxTRANSPARENT ) - return NULL; + return wxNullGraphicsBrush; else - return new wxGDIPlusBrush( this, brush ); + { + wxGraphicsBrush p; + p.SetRefData(new wxGDIPlusBrushData( this, brush )); + return p; + } } // sets the brush to a linear gradient, starting at (x1,y1) with color c1 to (x2,y2) with color c2 -wxGraphicsBrush* wxGDIPlusRenderer::CreateLinearGradientBrush( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2, +wxGraphicsBrush wxGDIPlusRenderer::CreateLinearGradientBrush( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2, const wxColour&c1, const wxColour&c2) { EnsureIsLoaded(); - wxGDIPlusBrush* brush = new wxGDIPlusBrush(this); - brush->CreateLinearGradientBrush(x1, y1, x2, y2, c1, c2); - return brush; -} + wxGraphicsBrush p; + wxGDIPlusBrushData* d = new wxGDIPlusBrushData( this ); + d->CreateLinearGradientBrush(x1, y1, x2, y2, c1, c2); + p.SetRefData(d); + return p; + } // 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* wxGDIPlusRenderer::CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius, +wxGraphicsBrush wxGDIPlusRenderer::CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius, const wxColour &oColor, const wxColour &cColor) { EnsureIsLoaded(); - wxGDIPlusBrush* brush = new wxGDIPlusBrush(this); - brush->CreateRadialGradientBrush(xo,yo,xc,yc,radius,oColor,cColor); - return brush; + wxGraphicsBrush p; + wxGDIPlusBrushData* d = new wxGDIPlusBrushData( this ); + d->CreateRadialGradientBrush(xo,yo,xc,yc,radius,oColor,cColor); + p.SetRefData(d); + return p; } // sets the font -wxGraphicsFont* wxGDIPlusRenderer::CreateFont( const wxFont &font , const wxColour &col ) +wxGraphicsFont wxGDIPlusRenderer::CreateFont( const wxFont &font , const wxColour &col ) { EnsureIsLoaded(); if ( font.Ok() ) - return new wxGDIPlusFont( this , font, col ); + { + wxGraphicsFont p; + p.SetRefData(new wxGDIPlusFontData( this , font, col )); + return p; + } else - return NULL; + return wxNullGraphicsFont; } #endif // wxUSE_GRAPHICS_CONTEXT -- 2.45.2