vcl/headless/CairoCommon.cxx     |  124 +++++++++++++++++++++++++++++++++++
 vcl/headless/svpgdi.cxx          |  136 ---------------------------------------
 vcl/inc/headless/CairoCommon.hxx |   27 +++++++
 3 files changed, 151 insertions(+), 136 deletions(-)

New commits:
commit eee703970581545b56f3b2faa5b5911923ec28ea
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Tue Dec 28 14:21:03 2021 +0900
Commit:     Tomaž Vajngerl <qui...@gmail.com>
CommitDate: Tue Jan 4 15:16:30 2022 +0100

    vcl: move SurfaceHelper class to CairoCommon
    
    Intermediate step beore moving bitmap related members.
    
    Change-Id: Icf2d4cfb787dfb029f299cba4b4ffabae563bf6d
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/127923
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <qui...@gmail.com>

diff --git a/vcl/headless/CairoCommon.cxx b/vcl/headless/CairoCommon.cxx
index 6194d976ab7b..94ca2c3158be 100644
--- a/vcl/headless/CairoCommon.cxx
+++ b/vcl/headless/CairoCommon.cxx
@@ -1173,4 +1173,128 @@ void Toggle1BitTransparency(const BitmapBuffer& rBuf)
     }
 }
 
+namespace
+{
+// check for env var that decides for using downscale pattern
+const char* pDisableDownScale(getenv("SAL_DISABLE_CAIRO_DOWNSCALE"));
+bool bDisableDownScale(nullptr != pDisableDownScale);
+}
+
+cairo_surface_t* SurfaceHelper::implCreateOrReuseDownscale(unsigned long 
nTargetWidth,
+                                                           unsigned long 
nTargetHeight)
+{
+    const unsigned long nSourceWidth(cairo_image_surface_get_width(pSurface));
+    const unsigned long 
nSourceHeight(cairo_image_surface_get_height(pSurface));
+
+    // zoomed in, need to stretch at paint, no pre-scale useful
+    if (nTargetWidth >= nSourceWidth || nTargetHeight >= nSourceHeight)
+    {
+        return pSurface;
+    }
+
+    // calculate downscale factor
+    unsigned long nWFactor(1);
+    unsigned long nW((nSourceWidth + 1) / 2);
+    unsigned long nHFactor(1);
+    unsigned long nH((nSourceHeight + 1) / 2);
+
+    while (nW > nTargetWidth && nW > 1)
+    {
+        nW = (nW + 1) / 2;
+        nWFactor *= 2;
+    }
+
+    while (nH > nTargetHeight && nH > 1)
+    {
+        nH = (nH + 1) / 2;
+        nHFactor *= 2;
+    }
+
+    if (1 == nWFactor && 1 == nHFactor)
+    {
+        // original size *is* best binary size, use it
+        return pSurface;
+    }
+
+    // go up one scale again - look for no change
+    nW = (1 == nWFactor) ? nTargetWidth : nW * 2;
+    nH = (1 == nHFactor) ? nTargetHeight : nH * 2;
+
+    // check if we have a downscaled version of required size
+    // bail out if the multiplication for the key would overflow
+    if (nW >= SAL_MAX_UINT32 || nH >= SAL_MAX_UINT32)
+        return pSurface;
+    const sal_uInt64 key((nW * static_cast<sal_uInt64>(SAL_MAX_UINT32)) + nH);
+    auto isHit(maDownscaled.find(key));
+
+    if (isHit != maDownscaled.end())
+    {
+        return isHit->second;
+    }
+
+    // create new surface in the targeted size
+    cairo_surface_t* pSurfaceTarget
+        = cairo_surface_create_similar(pSurface, 
cairo_surface_get_content(pSurface), nW, nH);
+
+    // made a version to scale self first that worked well, but would've
+    // been hard to support CAIRO_FORMAT_A1 including bit shifting, so
+    // I decided to go with cairo itself - use CAIRO_FILTER_FAST or
+    // CAIRO_FILTER_GOOD though. Please modify as needed for
+    // performance/quality
+    cairo_t* cr = cairo_create(pSurfaceTarget);
+    const double fScaleX(static_cast<double>(nW) / 
static_cast<double>(nSourceWidth));
+    const double fScaleY(static_cast<double>(nH) / 
static_cast<double>(nSourceHeight));
+    cairo_scale(cr, fScaleX, fScaleY);
+    cairo_set_source_surface(cr, pSurface, 0.0, 0.0);
+    cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_GOOD);
+    cairo_paint(cr);
+    cairo_destroy(cr);
+
+    // need to set device_scale for downscale surfaces to get
+    // them handled correctly
+    cairo_surface_set_device_scale(pSurfaceTarget, fScaleX, fScaleY);
+
+    // add entry to cached entries
+    maDownscaled[key] = pSurfaceTarget;
+
+    return pSurfaceTarget;
+}
+
+bool SurfaceHelper::isTrivial() const
+{
+    constexpr unsigned long nMinimalSquareSizeToBuffer(64 * 64);
+    const unsigned long nSourceWidth(cairo_image_surface_get_width(pSurface));
+    const unsigned long 
nSourceHeight(cairo_image_surface_get_height(pSurface));
+
+    return nSourceWidth * nSourceHeight < nMinimalSquareSizeToBuffer;
+}
+
+SurfaceHelper::SurfaceHelper()
+    : pSurface(nullptr)
+{
+}
+
+SurfaceHelper::~SurfaceHelper()
+{
+    cairo_surface_destroy(pSurface);
+    for (auto& candidate : maDownscaled)
+    {
+        cairo_surface_destroy(candidate.second);
+    }
+}
+
+cairo_surface_t* SurfaceHelper::getSurface(unsigned long nTargetWidth,
+                                           unsigned long nTargetHeight) const
+{
+    if (bDisableDownScale || 0 == nTargetWidth || 0 == nTargetHeight || 
!pSurface || isTrivial())
+    {
+        // caller asks for original or disabled or trivial (smaller then a 
minimal square size)
+        // also excludes zero cases for width/height after this point if need 
to prescale
+        return pSurface;
+    }
+
+    return 
const_cast<SurfaceHelper*>(this)->implCreateOrReuseDownscale(nTargetWidth,
+                                                                        
nTargetHeight);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/headless/svpgdi.cxx b/vcl/headless/svpgdi.cxx
index 92c0cbe39fbb..c894ebbcb38f 100644
--- a/vcl/headless/svpgdi.cxx
+++ b/vcl/headless/svpgdi.cxx
@@ -63,142 +63,6 @@ namespace
     const char* pDisableDownScale(getenv("SAL_DISABLE_CAIRO_DOWNSCALE"));
     bool bDisableDownScale(nullptr != pDisableDownScale);
 
-    class SurfaceHelper
-    {
-    private:
-        cairo_surface_t* pSurface;
-        std::unordered_map<sal_uInt64, cairo_surface_t*> maDownscaled;
-
-        SurfaceHelper(const SurfaceHelper&) = delete;
-        SurfaceHelper& operator=(const SurfaceHelper&) = delete;
-
-        cairo_surface_t* implCreateOrReuseDownscale(
-            unsigned long nTargetWidth,
-            unsigned long nTargetHeight)
-        {
-            const unsigned long 
nSourceWidth(cairo_image_surface_get_width(pSurface));
-            const unsigned long 
nSourceHeight(cairo_image_surface_get_height(pSurface));
-
-            // zoomed in, need to stretch at paint, no pre-scale useful
-            if(nTargetWidth >= nSourceWidth || nTargetHeight >= nSourceHeight)
-            {
-                return pSurface;
-            }
-
-            // calculate downscale factor
-            unsigned long nWFactor(1);
-            unsigned long nW((nSourceWidth + 1) / 2);
-            unsigned long nHFactor(1);
-            unsigned long nH((nSourceHeight + 1) / 2);
-
-            while(nW > nTargetWidth && nW > 1)
-            {
-                nW = (nW + 1) / 2;
-                nWFactor *= 2;
-            }
-
-            while(nH > nTargetHeight && nH > 1)
-            {
-                nH = (nH + 1) / 2;
-                nHFactor *= 2;
-            }
-
-            if(1 == nWFactor && 1 == nHFactor)
-            {
-                // original size *is* best binary size, use it
-                return pSurface;
-            }
-
-            // go up one scale again - look for no change
-            nW  = (1 == nWFactor) ? nTargetWidth : nW * 2;
-            nH  = (1 == nHFactor) ? nTargetHeight : nH * 2;
-
-            // check if we have a downscaled version of required size
-            // bail out if the multiplication for the key would overflow
-            if( nW >= SAL_MAX_UINT32 || nH >= SAL_MAX_UINT32 )
-                return pSurface;
-            const sal_uInt64 key((nW * 
static_cast<sal_uInt64>(SAL_MAX_UINT32)) + nH);
-            auto isHit(maDownscaled.find(key));
-
-            if(isHit != maDownscaled.end())
-            {
-                return isHit->second;
-            }
-
-            // create new surface in the targeted size
-            cairo_surface_t* pSurfaceTarget = cairo_surface_create_similar(
-                pSurface,
-                cairo_surface_get_content(pSurface),
-                nW,
-                nH);
-
-            // made a version to scale self first that worked well, but 
would've
-            // been hard to support CAIRO_FORMAT_A1 including bit shifting, so
-            // I decided to go with cairo itself - use CAIRO_FILTER_FAST or
-            // CAIRO_FILTER_GOOD though. Please modify as needed for
-            // performance/quality
-            cairo_t* cr = cairo_create(pSurfaceTarget);
-            const double 
fScaleX(static_cast<double>(nW)/static_cast<double>(nSourceWidth));
-            const double 
fScaleY(static_cast<double>(nH)/static_cast<double>(nSourceHeight));
-            cairo_scale(cr, fScaleX, fScaleY);
-            cairo_set_source_surface(cr, pSurface, 0.0, 0.0);
-            cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_GOOD);
-            cairo_paint(cr);
-            cairo_destroy(cr);
-
-            // need to set device_scale for downscale surfaces to get
-            // them handled correctly
-            cairo_surface_set_device_scale(pSurfaceTarget, fScaleX, fScaleY);
-
-            // add entry to cached entries
-            maDownscaled[key] = pSurfaceTarget;
-
-            return pSurfaceTarget;
-        }
-
-    protected:
-        cairo_surface_t* implGetSurface() const { return pSurface; }
-        void implSetSurface(cairo_surface_t* pNew) { pSurface = pNew; }
-
-        bool isTrivial() const
-        {
-            constexpr unsigned long nMinimalSquareSizeToBuffer(64*64);
-            const unsigned long 
nSourceWidth(cairo_image_surface_get_width(pSurface));
-            const unsigned long 
nSourceHeight(cairo_image_surface_get_height(pSurface));
-
-            return nSourceWidth * nSourceHeight < nMinimalSquareSizeToBuffer;
-        }
-
-    public:
-        explicit SurfaceHelper()
-        :   pSurface(nullptr)
-        {
-        }
-        ~SurfaceHelper()
-        {
-            cairo_surface_destroy(pSurface);
-            for(auto& candidate : maDownscaled)
-            {
-                cairo_surface_destroy(candidate.second);
-            }
-        }
-        cairo_surface_t* getSurface(
-            unsigned long nTargetWidth = 0,
-            unsigned long nTargetHeight = 0) const
-        {
-            if (bDisableDownScale || 0 == nTargetWidth || 0 == nTargetHeight 
|| !pSurface || isTrivial())
-            {
-                // caller asks for original or disabled or trivial (smaller 
then a minimal square size)
-                // also excludes zero cases for width/height after this point 
if need to prescale
-                return pSurface;
-            }
-
-            return 
const_cast<SurfaceHelper*>(this)->implCreateOrReuseDownscale(
-                nTargetWidth,
-                nTargetHeight);
-        }
-    };
-
     class BitmapHelper : public SurfaceHelper
     {
     private:
diff --git a/vcl/inc/headless/CairoCommon.hxx b/vcl/inc/headless/CairoCommon.hxx
index b1f6a8198a60..159714c558d8 100644
--- a/vcl/inc/headless/CairoCommon.hxx
+++ b/vcl/inc/headless/CairoCommon.hxx
@@ -38,6 +38,8 @@
 #include <basegfx/polygon/b2dpolypolygon.hxx>
 #include <basegfx/polygon/b2dpolygon.hxx>
 
+#include <unordered_map>
+
 //Using formats that match cairo's formats. For android we patch cairo,
 //which is internal in that case, to swap the rgb components so that
 //cairo then matches the OpenGL GL_RGBA format so we can use it there
@@ -199,4 +201,29 @@ struct VCL_DLLPUBLIC CairoCommon
     static cairo_surface_t* createCairoSurface(const BitmapBuffer* pBuffer);
 };
 
+class SurfaceHelper
+{
+private:
+    cairo_surface_t* pSurface;
+    std::unordered_map<sal_uInt64, cairo_surface_t*> maDownscaled;
+
+    SurfaceHelper(const SurfaceHelper&) = delete;
+    SurfaceHelper& operator=(const SurfaceHelper&) = delete;
+
+    cairo_surface_t* implCreateOrReuseDownscale(unsigned long nTargetWidth,
+                                                unsigned long nTargetHeight);
+
+protected:
+    cairo_surface_t* implGetSurface() const { return pSurface; }
+    void implSetSurface(cairo_surface_t* pNew) { pSurface = pNew; }
+
+    bool isTrivial() const;
+
+public:
+    explicit SurfaceHelper();
+    ~SurfaceHelper();
+
+    cairo_surface_t* getSurface(unsigned long nTargetWidth = 0,
+                                unsigned long nTargetHeight = 0) const;
+};
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Reply via email to