From 0939130158e496c06e43d7b8c287507c59df3beb Mon Sep 17 00:00:00 2001 From: Artur Wieczorek Date: Sun, 27 Jun 2021 23:32:57 +0200 Subject: [PATCH] Refactor wxGCDC to delegate acquiring/releasing HDC to wxGraphicsContext Instead of implementing MSW-specific code to handle HDC for GDI+ context directly in wxGCDC delegate acquiring/releasing HDC to underlying wxGraphicsContext. Decoupling GDI+-specific code from wxGCDC will allow us to implement handling HDC in other graphics renderers in a clean way. --- include/wx/dcgraph.h | 2 +- include/wx/graphics.h | 5 ++++ src/common/dcgraph.cpp | 19 ++++++++++++++++ src/generic/graphicc.cpp | 12 ++++++++++ src/msw/graphics.cpp | 49 ++++++++++++---------------------------- src/msw/graphicsd2d.cpp | 12 ++++++++++ 6 files changed, 63 insertions(+), 36 deletions(-) diff --git a/include/wx/dcgraph.h b/include/wx/dcgraph.h index 6732155b84..29671a841b 100644 --- a/include/wx/dcgraph.h +++ b/include/wx/dcgraph.h @@ -38,7 +38,7 @@ public: #ifdef __WXMSW__ // override wxDC virtual functions to provide access to HDC associated with - // this Graphics object (implemented in src/msw/graphics.cpp) + // underlying wxGraphicsContext virtual WXHDC AcquireHDC() wxOVERRIDE; virtual void ReleaseHDC(WXHDC hdc) wxOVERRIDE; #endif // __WXMSW__ diff --git a/include/wx/graphics.h b/include/wx/graphics.h index 084f308ba1..5defa492d9 100644 --- a/include/wx/graphics.h +++ b/include/wx/graphics.h @@ -881,6 +881,11 @@ public: void SetContentScaleFactor(double contentScaleFactor); double GetContentScaleFactor() const { return m_contentScaleFactor; } +#ifdef __WXMSW__ + virtual WXHDC GetNativeHDC() = 0; + virtual void ReleaseNativeHDC(WXHDC hdc) = 0; +#endif + protected: // These fields must be initialized in the derived class ctors. wxDouble m_width, diff --git a/src/common/dcgraph.cpp b/src/common/dcgraph.cpp index eacd2b4c57..7c7fe2518e 100644 --- a/src/common/dcgraph.cpp +++ b/src/common/dcgraph.cpp @@ -110,6 +110,25 @@ wxGCDC::~wxGCDC() { } +#ifdef __WXMSW__ +WXHDC wxGCDC::AcquireHDC() +{ + wxGraphicsContext* const gc = GetGraphicsContext(); + wxCHECK_MSG(gc, NULL, "can't acquire HDC because there is no wxGraphicsContext"); + return gc->GetNativeHDC(); +} + +void wxGCDC::ReleaseHDC(WXHDC hdc) +{ + if ( !hdc ) + return; + + wxGraphicsContext* const gc = GetGraphicsContext(); + wxCHECK_RET(gc, "can't release HDC because there is no wxGraphicsContext"); + gc->ReleaseNativeHDC(hdc); +} +#endif // __WXMSW__ + wxIMPLEMENT_ABSTRACT_CLASS(wxGCDCImpl, wxDCImpl); wxGCDCImpl::wxGCDCImpl(wxDC *owner, wxGraphicsContext* context) : diff --git a/src/generic/graphicc.cpp b/src/generic/graphicc.cpp index a14d15dab2..f8f6e50c25 100644 --- a/src/generic/graphicc.cpp +++ b/src/generic/graphicc.cpp @@ -512,6 +512,18 @@ public: wxDouble *descent, wxDouble *externalLeading ) const wxOVERRIDE; virtual void GetPartialTextExtents(const wxString& text, wxArrayDouble& widths) const wxOVERRIDE; +#ifdef __WXMSW__ + virtual WXHDC GetNativeHDC() wxOVERRIDE + { + wxFAIL_MSG("Can't get HDC from Cairo context"); + return NULL; + }; + virtual void ReleaseNativeHDC(WXHDC WXUNUSED(hdc)) wxOVERRIDE + { + wxFAIL_MSG("Can't release HDC for Cairo context"); + }; +#endif + protected: virtual void DoDrawText( const wxString &str, wxDouble x, wxDouble y ) wxOVERRIDE; diff --git a/src/msw/graphics.cpp b/src/msw/graphics.cpp index d9ee3f4811..cf8fcd488f 100644 --- a/src/msw/graphics.cpp +++ b/src/msw/graphics.cpp @@ -483,6 +483,9 @@ public: Graphics* GetGraphics() const { return m_context; } + virtual WXHDC GetNativeHDC() wxOVERRIDE; + virtual void ReleaseNativeHDC(WXHDC hdc) wxOVERRIDE; + protected: // Used from ctors (including those in the derived classes) and takes // ownership of the graphics pointer that must be non-NULL. @@ -2506,6 +2509,17 @@ void wxGDIPlusContext::GetDPI(wxDouble* dpiX, wxDouble* dpiY) const } } +WXHDC wxGDIPlusContext::GetNativeHDC() +{ + return m_context->GetHDC(); +} + +void wxGDIPlusContext::ReleaseNativeHDC(WXHDC hdc) +{ + if ( hdc ) + m_context->ReleaseHDC((HDC)hdc); +} + //----------------------------------------------------------------------------- // wxGDIPlusPrintingContext implementation //----------------------------------------------------------------------------- @@ -3003,39 +3017,4 @@ private: wxIMPLEMENT_DYNAMIC_CLASS(wxGDIPlusRendererModule, wxModule); -// ---------------------------------------------------------------------------- -// wxMSW-specific parts of wxGCDC -// ---------------------------------------------------------------------------- - -WXHDC wxGCDC::AcquireHDC() -{ - wxGraphicsContext * const gc = GetGraphicsContext(); - if ( !gc ) - return NULL; - - // we can't get the HDC if it is not a GDI+ context - wxCHECK_MSG(gc->GetRenderer() == wxGraphicsRenderer::GetGDIPlusRenderer(), NULL, - "can't get HDC because this is not GDI+ context"); - - Graphics * const g = static_cast(gc->GetNativeContext()); - return g ? g->GetHDC() : NULL; -} - -void wxGCDC::ReleaseHDC(WXHDC hdc) -{ - if ( !hdc ) - return; - - wxGraphicsContext * const gc = GetGraphicsContext(); - wxCHECK_RET( gc, "can't release HDC because there is no wxGraphicsContext" ); - - wxCHECK_RET(gc->GetRenderer() == wxGraphicsRenderer::GetGDIPlusRenderer(), - "can't release HDC because this is not GDI+ context"); - - Graphics * const g = static_cast(gc->GetNativeContext()); - wxCHECK_RET( g, "can't release HDC because there is no Graphics" ); - - g->ReleaseHDC((HDC)hdc); -} - #endif // wxUSE_GRAPHICS_GDIPLUS diff --git a/src/msw/graphicsd2d.cpp b/src/msw/graphicsd2d.cpp index 65eede9d30..14e938b25c 100644 --- a/src/msw/graphicsd2d.cpp +++ b/src/msw/graphicsd2d.cpp @@ -3836,6 +3836,8 @@ public: void PushState() wxOVERRIDE {} void PopState() wxOVERRIDE {} void Flush() wxOVERRIDE {} + WXHDC GetNativeHDC() wxOVERRIDE { return NULL; }; + void ReleaseNativeHDC(WXHDC WXUNUSED(hdc)) wxOVERRIDE {}; protected: void DoDrawText(const wxString&, wxDouble, wxDouble) wxOVERRIDE {} @@ -3992,6 +3994,16 @@ public: return GetRenderTarget(); } + WXHDC GetNativeHDC() wxOVERRIDE + { + wxFAIL_MSG("Can't get HDC from Direct2D context"); + return NULL; + }; + void ReleaseNativeHDC(WXHDC WXUNUSED(hdc)) wxOVERRIDE + { + wxFAIL_MSG("Can't release HDC for Direct2D context"); + }; + private: void Init();