vcl/inc/skia/win/gdiimpl.hxx          |   38 ++++++++++++++++++++---
 vcl/inc/win/salgdi.h                  |   45 ---------------------------
 vcl/inc/win/wingdiimpl.hxx            |    5 +--
 vcl/skia/win/gdiimpl.cxx              |   45 +++++++++++++++++++++------
 vcl/win/gdi/salgdi.cxx                |   56 ----------------------------------
 vcl/win/gdi/salnativewidgets-luna.cxx |   32 ++++++++++++-------
 6 files changed, 94 insertions(+), 127 deletions(-)

New commits:
commit 4a4d388e17ae7490ed36f4bb0dd21fbefcdda124
Author:     Noel Grandin <noelgran...@gmail.com>
AuthorDate: Wed May 7 01:58:16 2025 +0200
Commit:     Noel Grandin <noelgran...@gmail.com>
CommitDate: Wed May 7 08:40:48 2025 +0200

    simplify CompatibleDC
    
    This class is only really used by the skia case. The non-skia
    (i.e. GDI) case completely bypasses it.
    So we can remove the hierarchy and just make it into a skia focused
    class, simplifying the code structure in the process.
    
    Change-Id: I97f8160126bc5f823c882f3b338c0b2bec2160cb
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/185005
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>

diff --git a/vcl/inc/skia/win/gdiimpl.hxx b/vcl/inc/skia/win/gdiimpl.hxx
index d8428d395029..1dcb33fb693c 100644
--- a/vcl/inc/skia/win/gdiimpl.hxx
+++ b/vcl/inc/skia/win/gdiimpl.hxx
@@ -29,10 +29,39 @@
 class SkTypeface;
 class ControlCacheKey;
 
-class SkiaCompatibleDC : public CompatibleDC
+/** Class that creates (and destroys) a compatible Device Context.
+
+This is to be used for GDI drawing into a DIB that we later use for a different
+drawing method, such as a texture for OpenGL drawing or surface for Skia 
drawing.
+*/
+class SkiaCompatibleDC
 {
+    /// The compatible DC that we create for our purposes.
+    HDC mhCompatibleDC;
+
+    /// Mapping between the GDI position and OpenGL, to use for OpenGL drawing.
+    SalTwoRect maRects;
+
+    /// DIBSection that we use for the GDI drawing, and later obtain.
+    HBITMAP mhBitmap;
+
+    /// Return the previous bitmap to undo the SelectObject.
+    HBITMAP mhOrigBitmap;
+
+    /// DIBSection data.
+    sal_uInt32* mpData;
+
+    /// The SalGraphicsImpl where we will draw.  If null, we ignore the 
drawing, it means it happened directly to the DC...
+    WinSalGraphicsImplBase* mpImpl;
+
 public:
-    SkiaCompatibleDC(SalGraphics& rGraphics, int x, int y, int width, int 
height);
+    SkiaCompatibleDC(WinSalGraphics& rGraphics, int x, int y, int width, int 
height);
+    ~SkiaCompatibleDC();
+
+    HDC getCompatibleHDC() const { return mhCompatibleDC; }
+
+    /// Reset the DC with the defined color.
+    void fill(sal_uInt32 color);
 
     sk_sp<SkImage> getAsImageDiff(const SkiaCompatibleDC& white) const;
 };
@@ -48,8 +77,9 @@ public:
     virtual bool UseRenderNativeControl() const override { return true; }
     virtual bool TryRenderCachedNativeControl(ControlCacheKey const& 
rControlCacheKey, int nX,
                                               int nY) override;
-    virtual bool RenderAndCacheNativeControl(CompatibleDC& rWhite, 
CompatibleDC& rBlack, int nX,
-                                             int nY, ControlCacheKey& 
aControlCacheKey) override;
+    virtual bool RenderAndCacheNativeControl(SkiaCompatibleDC& rWhite, 
SkiaCompatibleDC& rBlack,
+                                             int nX, int nY,
+                                             ControlCacheKey& 
aControlCacheKey) override;
 
     virtual bool DrawTextLayout(const GenericSalLayout& layout) override;
     virtual void ClearDevFontCache() override;
diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h
index c80f78e20569..65988c2867d4 100644
--- a/vcl/inc/win/salgdi.h
+++ b/vcl/inc/win/salgdi.h
@@ -85,51 +85,6 @@ private:
     mutable sal::systools::COMReference<IDWriteFontFace> mxDWFontFace;
 };
 
-/** Class that creates (and destroys) a compatible Device Context.
-
-This is to be used for GDI drawing into a DIB that we later use for a different
-drawing method, such as a texture for OpenGL drawing or surface for Skia 
drawing.
-*/
-class CompatibleDC
-{
-protected:
-    /// The compatible DC that we create for our purposes.
-    HDC mhCompatibleDC;
-
-    /// DIBSection that we use for the GDI drawing, and later obtain.
-    HBITMAP mhBitmap;
-
-    /// Return the previous bitmap to undo the SelectObject.
-    HBITMAP mhOrigBitmap;
-
-    /// DIBSection data.
-    sal_uInt32 *mpData;
-
-    /// Mapping between the GDI position and OpenGL, to use for OpenGL drawing.
-    SalTwoRect maRects;
-
-    /// The SalGraphicsImpl where we will draw.  If null, we ignore the 
drawing, it means it happened directly to the DC...
-    WinSalGraphicsImplBase *mpImpl;
-
-    // If 'disable' is true, this class is a simple wrapper for drawing 
directly. Subclasses should use true.
-    CompatibleDC(SalGraphics &rGraphics, int x, int y, int width, int height, 
bool disable=true);
-
-public:
-    static std::unique_ptr< CompatibleDC > create(SalGraphics &rGraphics, int 
x, int y, int width, int height);
-
-    virtual ~CompatibleDC();
-
-    HDC getCompatibleHDC() { return mhCompatibleDC; }
-
-    SalTwoRect getTwoRect() const { return maRects; }
-
-    tools::Long getBitmapWidth() const { return maRects.mnSrcWidth; }
-    tools::Long getBitmapHeight() const { return maRects.mnSrcHeight; }
-
-    /// Reset the DC with the defined color.
-    void fill(sal_uInt32 color);
-};
-
 /**
  * WinSalGraphics never owns the HDC it uses to draw, because the HDC can have
  * various origins with different ways to correctly free it. And WinSalGraphics
diff --git a/vcl/inc/win/wingdiimpl.hxx b/vcl/inc/win/wingdiimpl.hxx
index 94a1ec8f84f4..e2482606cd1f 100644
--- a/vcl/inc/win/wingdiimpl.hxx
+++ b/vcl/inc/win/wingdiimpl.hxx
@@ -13,6 +13,7 @@
 #include <ControlCacheKey.hxx>
 
 class ControlCacheKey;
+class SkiaCompatibleDC;
 
 // Base class for some functionality that OpenGL/Skia/GDI backends must each 
implement.
 class WinSalGraphicsImplBase
@@ -27,8 +28,8 @@ public:
     {
         abort();
     }
-    virtual bool RenderAndCacheNativeControl(CompatibleDC& /*rWhite*/, 
CompatibleDC& /*rBlack*/,
-                                             int /*nX*/, int /*nY*/,
+    virtual bool RenderAndCacheNativeControl(SkiaCompatibleDC& /*rWhite*/,
+                                             SkiaCompatibleDC& /*rBlack*/, int 
/*nX*/, int /*nY*/,
                                              ControlCacheKey& 
/*aControlCacheKey*/)
     {
         abort();
diff --git a/vcl/skia/win/gdiimpl.cxx b/vcl/skia/win/gdiimpl.cxx
index e315eb0f7234..f26d37fcf491 100644
--- a/vcl/skia/win/gdiimpl.cxx
+++ b/vcl/skia/win/gdiimpl.cxx
@@ -12,6 +12,7 @@
 #include <skia/win/gdiimpl.hxx>
 
 #include <win/saldata.hxx>
+#include <win/salvd.h>
 #include <vcl/skia/SkiaHelper.hxx>
 #include <skia/utils.hxx>
 #include <skia/zone.hxx>
@@ -154,15 +155,11 @@ bool 
WinSkiaSalGraphicsImpl::TryRenderCachedNativeControl(ControlCacheKey const&
     return true;
 }
 
-bool WinSkiaSalGraphicsImpl::RenderAndCacheNativeControl(CompatibleDC& rWhite, 
CompatibleDC& rBlack,
-                                                         int nX, int nY,
+bool WinSkiaSalGraphicsImpl::RenderAndCacheNativeControl(SkiaCompatibleDC& 
rWhite,
+                                                         SkiaCompatibleDC& 
rBlack, int nX, int nY,
                                                          ControlCacheKey& 
aControlCacheKey)
 {
-    assert(dynamic_cast<SkiaCompatibleDC*>(&rWhite));
-    assert(dynamic_cast<SkiaCompatibleDC*>(&rBlack));
-
-    sk_sp<SkImage> image = 
static_cast<SkiaCompatibleDC&>(rBlack).getAsImageDiff(
-        static_cast<SkiaCompatibleDC&>(rWhite));
+    sk_sp<SkImage> image = rBlack.getAsImageDiff(rWhite);
     preDraw();
     SAL_INFO("vcl.skia.trace",
              "renderandcachednativecontrol("
@@ -346,9 +343,39 @@ void WinSkiaSalGraphicsImpl::ClearDevFontCache()
     initFontInfo(); // get font info again, just in case
 }
 
-SkiaCompatibleDC::SkiaCompatibleDC(SalGraphics& rGraphics, int x, int y, int 
width, int height)
-    : CompatibleDC(rGraphics, x, y, width, height, false)
+SkiaCompatibleDC::SkiaCompatibleDC(WinSalGraphics& rGraphics, int x, int y, 
int width, int height)
+    : maRects(0, 0, width, height, x, y, width, height)
+{
+    mpImpl = rGraphics.getWinSalGraphicsImplBase();
+    mhCompatibleDC = CreateCompatibleDC(rGraphics.getHDC());
+
+    // move the origin so that we always paint at 0,0 - to keep the bitmap 
small
+    OffsetViewportOrgEx(mhCompatibleDC, -x, -y, nullptr);
+
+    mhBitmap = WinSalVirtualDevice::ImplCreateVirDevBitmap(mhCompatibleDC, 
width, height, 32,
+                                                           
reinterpret_cast<void**>(&mpData));
+
+    mhOrigBitmap = static_cast<HBITMAP>(SelectObject(mhCompatibleDC, 
mhBitmap));
+}
+
+SkiaCompatibleDC::~SkiaCompatibleDC()
 {
+    if (mpImpl)
+    {
+        SelectObject(mhCompatibleDC, mhOrigBitmap);
+        DeleteObject(mhBitmap);
+        DeleteDC(mhCompatibleDC);
+    }
+}
+
+void SkiaCompatibleDC::fill(sal_uInt32 color)
+{
+    if (!mpData)
+        return;
+
+    sal_uInt32* p = mpData;
+    for (int i = maRects.mnSrcWidth * maRects.mnSrcHeight; i > 0; --i)
+        *p++ = color;
 }
 
 sk_sp<SkImage> SkiaCompatibleDC::getAsImageDiff(const SkiaCompatibleDC& white) 
const
diff --git a/vcl/win/gdi/salgdi.cxx b/vcl/win/gdi/salgdi.cxx
index 31993e7e5957..3bd595699f1b 100644
--- a/vcl/win/gdi/salgdi.cxx
+++ b/vcl/win/gdi/salgdi.cxx
@@ -242,62 +242,6 @@ void ImplClearHDCCache( SalData* pData )
     }
 }
 
-std::unique_ptr< CompatibleDC > CompatibleDC::create(SalGraphics &rGraphics, 
int x, int y, int width, int height)
-{
-#if HAVE_FEATURE_SKIA
-    if (SkiaHelper::isVCLSkiaEnabled())
-        return std::make_unique< SkiaCompatibleDC >( rGraphics, x, y, width, 
height );
-#endif
-    return std::unique_ptr< CompatibleDC >( new CompatibleDC( rGraphics, x, y, 
width, height ));
-}
-
-CompatibleDC::CompatibleDC(SalGraphics &rGraphics, int x, int y, int width, 
int height, bool disable)
-    : mhBitmap(nullptr)
-    , mpData(nullptr)
-    , maRects(0, 0, width, height, x, y, width, height)
-    , mpImpl(nullptr)
-{
-    WinSalGraphics& rWinGraphics = static_cast<WinSalGraphics&>(rGraphics);
-
-    if( disable )
-    {
-        // we avoid the OpenGL drawing, instead we draw directly to the DC
-        mhCompatibleDC = rWinGraphics.getHDC();
-        return;
-    }
-
-    mpImpl = rWinGraphics.getWinSalGraphicsImplBase();
-    mhCompatibleDC = CreateCompatibleDC(rWinGraphics.getHDC());
-
-    // move the origin so that we always paint at 0,0 - to keep the bitmap
-    // small
-    OffsetViewportOrgEx(mhCompatibleDC, -x, -y, nullptr);
-
-    mhBitmap = WinSalVirtualDevice::ImplCreateVirDevBitmap(mhCompatibleDC, 
width, height, 32, reinterpret_cast<void **>(&mpData));
-
-    mhOrigBitmap = static_cast<HBITMAP>(SelectObject(mhCompatibleDC, 
mhBitmap));
-}
-
-CompatibleDC::~CompatibleDC()
-{
-    if (mpImpl)
-    {
-        SelectObject(mhCompatibleDC, mhOrigBitmap);
-        DeleteObject(mhBitmap);
-        DeleteDC(mhCompatibleDC);
-    }
-}
-
-void CompatibleDC::fill(sal_uInt32 color)
-{
-    if (!mpData)
-        return;
-
-    sal_uInt32 *p = mpData;
-    for (int i = maRects.mnSrcWidth * maRects.mnSrcHeight; i > 0; --i)
-        *p++ = color;
-}
-
 WinSalGraphics::WinSalGraphics(WinSalGraphics::Type eType, bool bScreen, HWND 
hWnd, [[maybe_unused]] SalGeometryProvider *pProvider):
     mhLocalDC(nullptr),
     mbPrinter(eType == WinSalGraphics::PRINTER),
diff --git a/vcl/win/gdi/salnativewidgets-luna.cxx 
b/vcl/win/gdi/salnativewidgets-luna.cxx
index 7c442ab8cda3..b375a60b4e69 100644
--- a/vcl/win/gdi/salnativewidgets-luna.cxx
+++ b/vcl/win/gdi/salnativewidgets-luna.cxx
@@ -40,6 +40,7 @@
 #include <vcl/svapp.hxx>
 #include <vcl/settings.hxx>
 #include <vcl/themecolors.hxx>
+#include <vcl/skia/skiahelper.hxx>
 #include <salinst.hxx>
 #include <toolbarvalue.hxx>
 #include <menubarvalue.hxx>
@@ -51,6 +52,7 @@
 #include <win/salinst.h>
 #include <win/scoped_gdi.hxx>
 #include <win/wingdiimpl.hxx>
+#include <skia/win/gdiimpl.hxx>
 
 #include <uxtheme.h>
 #include <vssym32.h>
@@ -1653,23 +1655,31 @@ bool WinSalGraphics::drawNativeControl( ControlType 
nType,
         // restore alignment
         SetTextAlign(getHDC(), ta);
     }
-    else
+#if HAVE_FEATURE_SKIA
+    else if (SkiaHelper::isVCLSkiaEnabled())
     {
-        // We can do OpenGL/Skia
-        std::unique_ptr<CompatibleDC> aBlackDC(CompatibleDC::create(*this, 
cacheRect.Left(), cacheRect.Top(), cacheRect.GetWidth()+1, 
cacheRect.GetHeight()+1));
-        SetTextAlign(aBlackDC->getCompatibleHDC(), 
TA_LEFT|TA_TOP|TA_NOUPDATECP);
-        aBlackDC->fill(RGB(0, 0, 0));
+        // We can do Skia
+        SkiaCompatibleDC aBlackDC( *this, cacheRect.Left(), cacheRect.Top(), 
cacheRect.GetWidth()+1, cacheRect.GetHeight()+1 );
+        SetTextAlign(aBlackDC.getCompatibleHDC(), 
TA_LEFT|TA_TOP|TA_NOUPDATECP);
+        aBlackDC.fill(RGB(0, 0, 0));
 
-        std::unique_ptr<CompatibleDC> aWhiteDC(CompatibleDC::create(*this, 
cacheRect.Left(), cacheRect.Top(), cacheRect.GetWidth()+1, 
cacheRect.GetHeight()+1));
-        SetTextAlign(aWhiteDC->getCompatibleHDC(), 
TA_LEFT|TA_TOP|TA_NOUPDATECP);
-        aWhiteDC->fill(RGB(0xff, 0xff, 0xff));
+        SkiaCompatibleDC aWhiteDC(*this, cacheRect.Left(), cacheRect.Top(), 
cacheRect.GetWidth()+1, cacheRect.GetHeight()+1);
+        SetTextAlign(aWhiteDC.getCompatibleHDC(), 
TA_LEFT|TA_TOP|TA_NOUPDATECP);
+        aWhiteDC.fill(RGB(0xff, 0xff, 0xff));
 
-        if (ImplDrawNativeControl(aBlackDC->getCompatibleHDC(), hTheme, rc, 
nType, nPart, nState, aValue, aCaptionStr, bUseDarkMode) &&
-            ImplDrawNativeControl(aWhiteDC->getCompatibleHDC(), hTheme, rc, 
nType, nPart, nState, aValue, aCaptionStr, bUseDarkMode))
+        if (ImplDrawNativeControl(aBlackDC.getCompatibleHDC(), hTheme, rc, 
nType, nPart, nState, aValue, aCaptionStr, bUseDarkMode) &&
+            ImplDrawNativeControl(aWhiteDC.getCompatibleHDC(), hTheme, rc, 
nType, nPart, nState, aValue, aCaptionStr, bUseDarkMode))
         {
-            bOk = pImpl->RenderAndCacheNativeControl(*aWhiteDC, *aBlackDC, 
cacheRect.Left(), cacheRect.Top(), aControlCacheKey);
+            bOk = pImpl->RenderAndCacheNativeControl(aWhiteDC, aBlackDC, 
cacheRect.Left(), cacheRect.Top(), aControlCacheKey);
         }
     }
+#endif
+    else
+    {
+        // Use normal GDI
+        SetTextAlign(getHDC(), TA_LEFT|TA_TOP|TA_NOUPDATECP);
+        ImplDrawNativeControl(getHDC(), hTheme, rc, nType, nPart, nState, 
aValue, aCaptionStr, bUseDarkMode);
+    }
 
     if (bUseDarkMode)
         SetWindowTheme(mhWnd, nullptr, nullptr);

Reply via email to