vcl/headless/CairoCommon.cxx        |   94 +++++++++++++++++++++++++++++-
 vcl/headless/SvpGraphicsBackend.cxx |   26 +++++++-
 vcl/headless/svpgdi.cxx             |  112 +-----------------------------------
 vcl/inc/headless/CairoCommon.hxx    |   10 +++
 vcl/inc/headless/svpgdi.hxx         |   17 +----
 5 files changed, 133 insertions(+), 126 deletions(-)

New commits:
commit 52c903c6a48d62d6ed7841ba2d1021300c8189b3
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Tue Dec 28 10:17:53 2021 +0900
Commit:     Tomaž Vajngerl <qui...@gmail.com>
CommitDate: Tue Jan 4 05:21:33 2022 +0100

    vcl: copyArea and copyBits to SvpGraphicsBackend
    
    Also move the used (sub)functions to the CarioCommon:
    copyBitsCairo, copySource, copyWithOperator, renderSource and
    renderWithOperator. Also use these functions in some calls
    needed by drawBitmap & co.
    
    Change-Id: I51395953545827951b6f255a9833e828aec7ea60
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/127842
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <qui...@gmail.com>

diff --git a/vcl/headless/CairoCommon.cxx b/vcl/headless/CairoCommon.cxx
index 79baec8ff497..234bfe29fcce 100644
--- a/vcl/headless/CairoCommon.cxx
+++ b/vcl/headless/CairoCommon.cxx
@@ -834,6 +834,98 @@ bool CairoCommon::drawPolyLine(cairo_t* cr, 
basegfx::B2DRange* pExtents, const C
     return true;
 }
 
+namespace
+{
+basegfx::B2DRange renderWithOperator(cairo_t* cr, const SalTwoRect& rTR, 
cairo_surface_t* source,
+                                     cairo_operator_t eOperator = 
CAIRO_OPERATOR_SOURCE)
+{
+    cairo_rectangle(cr, rTR.mnDestX, rTR.mnDestY, rTR.mnDestWidth, 
rTR.mnDestHeight);
+
+    basegfx::B2DRange extents = getClippedFillDamage(cr);
+
+    cairo_clip(cr);
+
+    cairo_translate(cr, rTR.mnDestX, rTR.mnDestY);
+    double fXScale = 1.0f;
+    double fYScale = 1.0f;
+    if (rTR.mnSrcWidth != 0 && rTR.mnSrcHeight != 0)
+    {
+        fXScale = static_cast<double>(rTR.mnDestWidth) / rTR.mnSrcWidth;
+        fYScale = static_cast<double>(rTR.mnDestHeight) / rTR.mnSrcHeight;
+        cairo_scale(cr, fXScale, fYScale);
+    }
+
+    cairo_save(cr);
+    cairo_set_source_surface(cr, source, -rTR.mnSrcX, -rTR.mnSrcY);
+    if ((fXScale != 1.0 && rTR.mnSrcWidth == 1) || (fYScale != 1.0 && 
rTR.mnSrcHeight == 1))
+    {
+        cairo_pattern_t* sourcepattern = cairo_get_source(cr);
+        cairo_pattern_set_extend(sourcepattern, CAIRO_EXTEND_REPEAT);
+        cairo_pattern_set_filter(sourcepattern, CAIRO_FILTER_NEAREST);
+    }
+    cairo_set_operator(cr, eOperator);
+    cairo_paint(cr);
+    cairo_restore(cr);
+
+    return extents;
+}
+
+} // end anonymous ns
+
+basegfx::B2DRange CairoCommon::renderSource(cairo_t* cr, const SalTwoRect& rTR,
+                                            cairo_surface_t* source)
+{
+    return renderWithOperator(cr, rTR, source, CAIRO_OPERATOR_SOURCE);
+}
+
+void CairoCommon::copyWithOperator(const SalTwoRect& rTR, cairo_surface_t* 
source,
+                                   cairo_operator_t eOp, bool bAntiAlias)
+{
+    cairo_t* cr = getCairoContext(false, bAntiAlias);
+    clipRegion(cr);
+
+    basegfx::B2DRange extents = renderWithOperator(cr, rTR, source, eOp);
+
+    releaseCairoContext(cr, false, extents);
+}
+
+void CairoCommon::copySource(const SalTwoRect& rTR, cairo_surface_t* source, 
bool bAntiAlias)
+{
+    copyWithOperator(rTR, source, CAIRO_OPERATOR_SOURCE, bAntiAlias);
+}
+
+void CairoCommon::copyBitsCairo(const SalTwoRect& rTR, cairo_surface_t* 
pSourceSurface,
+                                bool bAntiAlias)
+{
+    SalTwoRect aTR(rTR);
+
+    cairo_surface_t* pCopy = nullptr;
+
+    if (pSourceSurface == getSurface())
+    {
+        //self copy is a problem, so dup source in that case
+        pCopy
+            = cairo_surface_create_similar(pSourceSurface, 
cairo_surface_get_content(getSurface()),
+                                           aTR.mnSrcWidth * m_fScale, 
aTR.mnSrcHeight * m_fScale);
+        dl_cairo_surface_set_device_scale(pCopy, m_fScale, m_fScale);
+        cairo_t* cr = cairo_create(pCopy);
+        cairo_set_source_surface(cr, pSourceSurface, -aTR.mnSrcX, -aTR.mnSrcY);
+        cairo_rectangle(cr, 0, 0, aTR.mnSrcWidth, aTR.mnSrcHeight);
+        cairo_fill(cr);
+        cairo_destroy(cr);
+
+        pSourceSurface = pCopy;
+
+        aTR.mnSrcX = 0;
+        aTR.mnSrcY = 0;
+    }
+
+    copySource(aTR, pSourceSurface, bAntiAlias);
+
+    if (pCopy)
+        cairo_surface_destroy(pCopy);
+}
+
 namespace
 {
 cairo_pattern_t* create_stipple()
@@ -847,7 +939,7 @@ cairo_pattern_t* create_stipple()
     cairo_pattern_set_filter(pattern, CAIRO_FILTER_NEAREST);
     return pattern;
 }
-}
+} // end anonymous ns
 
 void CairoCommon::invert(const basegfx::B2DPolygon& rPoly, SalInvert nFlags, 
bool bAntiAlias)
 {
diff --git a/vcl/headless/SvpGraphicsBackend.cxx 
b/vcl/headless/SvpGraphicsBackend.cxx
index 6a50ca17353c..460d869766c7 100644
--- a/vcl/headless/SvpGraphicsBackend.cxx
+++ b/vcl/headless/SvpGraphicsBackend.cxx
@@ -353,14 +353,32 @@ bool 
SvpGraphicsBackend::drawPolyPolygonBezier(sal_uInt32, const sal_uInt32*, co
     return false;
 }
 
-void SvpGraphicsBackend::copyArea(tools::Long /*nDestX*/, tools::Long 
/*nDestY*/,
-                                  tools::Long /*nSrcX*/, tools::Long /*nSrcY*/,
-                                  tools::Long /*nSrcWidth*/, tools::Long 
/*nSrcHeight*/,
+void SvpGraphicsBackend::copyArea(tools::Long nDestX, tools::Long nDestY, 
tools::Long nSrcX,
+                                  tools::Long nSrcY, tools::Long nSrcWidth, 
tools::Long nSrcHeight,
                                   bool /*bWindowInvalidate*/)
 {
+    SalTwoRect aTR(nSrcX, nSrcY, nSrcWidth, nSrcHeight, nDestX, nDestY, 
nSrcWidth, nSrcHeight);
+
+    cairo_surface_t* source = m_rCairoCommon.m_pSurface;
+    m_rCairoCommon.copyBitsCairo(aTR, source, getAntiAlias());
 }
 
-void SvpGraphicsBackend::copyBits(const SalTwoRect& /*rTR*/, SalGraphics* 
/*pSrcGraphics*/) {}
+void SvpGraphicsBackend::copyBits(const SalTwoRect& rTR, SalGraphics* 
pSrcGraphics)
+{
+    cairo_surface_t* source = nullptr;
+
+    if (pSrcGraphics)
+    {
+        SvpGraphicsBackend* pSrc = 
static_cast<SvpGraphicsBackend*>(pSrcGraphics->GetImpl());
+        source = pSrc->m_rCairoCommon.m_pSurface;
+    }
+    else
+    {
+        source = m_rCairoCommon.m_pSurface;
+    }
+
+    m_rCairoCommon.copyBitsCairo(rTR, source, getAntiAlias());
+}
 
 void SvpGraphicsBackend::drawBitmap(const SalTwoRect& /*rPosAry*/, const 
SalBitmap& /*rSalBitmap*/)
 {
diff --git a/vcl/headless/svpgdi.cxx b/vcl/headless/svpgdi.cxx
index 642382ed57b2..4ec12998a163 100644
--- a/vcl/headless/svpgdi.cxx
+++ b/vcl/headless/svpgdi.cxx
@@ -852,110 +852,6 @@ void SvpSalGraphics::GetResolution( sal_Int32& rDPIX, 
sal_Int32& rDPIY )
     rDPIX = rDPIY = 96;
 }
 
-void SvpSalGraphics::copyArea( tools::Long nDestX,
-                               tools::Long nDestY,
-                               tools::Long nSrcX,
-                               tools::Long nSrcY,
-                               tools::Long nSrcWidth,
-                               tools::Long nSrcHeight,
-                               bool /*bWindowInvalidate*/ )
-{
-    SalTwoRect aTR(nSrcX, nSrcY, nSrcWidth, nSrcHeight, nDestX, nDestY, 
nSrcWidth, nSrcHeight);
-    copyBits(aTR, this);
-}
-
-static basegfx::B2DRange renderWithOperator(cairo_t* cr, const SalTwoRect& rTR,
-                                          cairo_surface_t* source, 
cairo_operator_t eOperator = CAIRO_OPERATOR_SOURCE)
-{
-    cairo_rectangle(cr, rTR.mnDestX, rTR.mnDestY, rTR.mnDestWidth, 
rTR.mnDestHeight);
-
-    basegfx::B2DRange extents = getClippedFillDamage(cr);
-
-    cairo_clip(cr);
-
-    cairo_translate(cr, rTR.mnDestX, rTR.mnDestY);
-    double fXScale = 1.0f;
-    double fYScale = 1.0f;
-    if (rTR.mnSrcWidth != 0 && rTR.mnSrcHeight != 0) {
-        fXScale = static_cast<double>(rTR.mnDestWidth)/rTR.mnSrcWidth;
-        fYScale = static_cast<double>(rTR.mnDestHeight)/rTR.mnSrcHeight;
-        cairo_scale(cr, fXScale, fYScale);
-    }
-
-    cairo_save(cr);
-    cairo_set_source_surface(cr, source, -rTR.mnSrcX, -rTR.mnSrcY);
-    if ((fXScale != 1.0 && rTR.mnSrcWidth == 1) || (fYScale != 1.0 && 
rTR.mnSrcHeight == 1))
-    {
-        cairo_pattern_t* sourcepattern = cairo_get_source(cr);
-        cairo_pattern_set_extend(sourcepattern, CAIRO_EXTEND_REPEAT);
-        cairo_pattern_set_filter(sourcepattern, CAIRO_FILTER_NEAREST);
-    }
-    cairo_set_operator(cr, eOperator);
-    cairo_paint(cr);
-    cairo_restore(cr);
-
-    return extents;
-}
-
-static basegfx::B2DRange renderSource(cairo_t* cr, const SalTwoRect& rTR,
-                                          cairo_surface_t* source)
-{
-    return renderWithOperator(cr, rTR, source, CAIRO_OPERATOR_SOURCE);
-}
-
-void SvpSalGraphics::copyWithOperator( const SalTwoRect& rTR, cairo_surface_t* 
source,
-                                 cairo_operator_t eOp )
-{
-    cairo_t* cr = m_aCairoCommon.getCairoContext(false, getAntiAlias());
-    clipRegion(cr);
-
-    basegfx::B2DRange extents = renderWithOperator(cr, rTR, source, eOp);
-
-    m_aCairoCommon.releaseCairoContext(cr, false, extents);
-}
-
-void SvpSalGraphics::copySource( const SalTwoRect& rTR, cairo_surface_t* 
source )
-{
-   copyWithOperator(rTR, source, CAIRO_OPERATOR_SOURCE);
-}
-
-void SvpSalGraphics::copyBits( const SalTwoRect& rTR,
-                               SalGraphics*      pSrcGraphics )
-{
-    SalTwoRect aTR(rTR);
-
-    SvpSalGraphics* pSrc = pSrcGraphics ?
-        static_cast<SvpSalGraphics*>(pSrcGraphics) : this;
-
-    cairo_surface_t* source = pSrc->m_aCairoCommon.m_pSurface;
-
-    cairo_surface_t *pCopy = nullptr;
-    if (pSrc == this)
-    {
-        //self copy is a problem, so dup source in that case
-        pCopy = cairo_surface_create_similar(source,
-                                            
cairo_surface_get_content(m_aCairoCommon.m_pSurface),
-                                            aTR.mnSrcWidth * 
m_aCairoCommon.m_fScale,
-                                            aTR.mnSrcHeight * 
m_aCairoCommon.m_fScale);
-        dl_cairo_surface_set_device_scale(pCopy, m_aCairoCommon.m_fScale, 
m_aCairoCommon.m_fScale);
-        cairo_t* cr = cairo_create(pCopy);
-        cairo_set_source_surface(cr, source, -aTR.mnSrcX, -aTR.mnSrcY);
-        cairo_rectangle(cr, 0, 0, aTR.mnSrcWidth, aTR.mnSrcHeight);
-        cairo_fill(cr);
-        cairo_destroy(cr);
-
-        source = pCopy;
-
-        aTR.mnSrcX = 0;
-        aTR.mnSrcY = 0;
-    }
-
-    copySource(aTR, source);
-
-    if (pCopy)
-        cairo_surface_destroy(pCopy);
-}
-
 void SvpSalGraphics::drawBitmap(const SalTwoRect& rTR, const SalBitmap& 
rSourceBitmap)
 {
     // MM02 try to access buffered BitmapHelper
@@ -973,16 +869,16 @@ void SvpSalGraphics::drawBitmap(const SalTwoRect& rTR, 
const SalBitmap& rSourceB
 
 #if 0 // LO code is not yet bitmap32-ready.
       // if m_bSupportsBitmap32 becomes true for Svp revisit this
-    copyWithOperator(rTR, source, CAIRO_OPERATOR_OVER);
+    m_aCairoCommon.copyWithOperator(rTR, source, CAIRO_OPERATOR_OVER, 
getAntiAlias());
 #else
-    copyWithOperator(rTR, source, CAIRO_OPERATOR_SOURCE);
+    m_aCairoCommon.copyWithOperator(rTR, source, CAIRO_OPERATOR_SOURCE, 
getAntiAlias());
 #endif
 }
 
 void SvpSalGraphics::drawBitmap(const SalTwoRect& rTR, const BitmapBuffer* 
pBuffer, cairo_operator_t eOp)
 {
     cairo_surface_t* source = createCairoSurface( pBuffer );
-    copyWithOperator(rTR, source, eOp);
+    m_aCairoCommon.copyWithOperator(rTR, source, eOp, getAntiAlias());
     cairo_surface_destroy(source);
 }
 
@@ -1098,7 +994,7 @@ std::shared_ptr<SalBitmap> SvpSalGraphics::getBitmap( 
tools::Long nX, tools::Lon
     cairo_t* cr = cairo_create(target);
 
     SalTwoRect aTR(nX, nY, nWidth, nHeight, 0, 0, nWidth, nHeight);
-    renderSource(cr, aTR, m_aCairoCommon.m_pSurface);
+    CairoCommon::renderSource(cr, aTR, m_aCairoCommon.m_pSurface);
 
     cairo_destroy(cr);
     cairo_surface_destroy(target);
diff --git a/vcl/inc/headless/CairoCommon.hxx b/vcl/inc/headless/CairoCommon.hxx
index fb7526377801..cdf66c012cde 100644
--- a/vcl/inc/headless/CairoCommon.hxx
+++ b/vcl/inc/headless/CairoCommon.hxx
@@ -176,6 +176,16 @@ struct VCL_DLLPUBLIC CairoCommon
                              basegfx::B2DLineJoin eLineJoin, 
css::drawing::LineCap eLineCap,
                              double fMiterMinimumAngle, bool 
bPixelSnapHairline);
 
+    void copyWithOperator(const SalTwoRect& rTR, cairo_surface_t* source, 
cairo_operator_t eOp,
+                          bool bAntiAlias);
+
+    void copySource(const SalTwoRect& rTR, cairo_surface_t* source, bool 
bAntiAlias);
+
+    static basegfx::B2DRange renderSource(cairo_t* cr, const SalTwoRect& rTR,
+                                          cairo_surface_t* source);
+
+    void copyBitsCairo(const SalTwoRect& rTR, cairo_surface_t* pSourceSurface, 
bool bAntiAlias);
+
     void invert(const basegfx::B2DPolygon& rPoly, SalInvert nFlags, bool 
bAntiAlias);
 };
 
diff --git a/vcl/inc/headless/svpgdi.hxx b/vcl/inc/headless/svpgdi.hxx
index 9db0f86cc65b..04c507f2d3f9 100644
--- a/vcl/inc/headless/svpgdi.hxx
+++ b/vcl/inc/headless/svpgdi.hxx
@@ -54,10 +54,6 @@ public:
         return CairoCommon::getDamageKey();
     }
 
-    void copySource(const SalTwoRect& rTR, cairo_surface_t* source);
-    void copyWithOperator(const SalTwoRect& rTR, cairo_surface_t* source,
-                          cairo_operator_t eOp = CAIRO_OPERATOR_SOURCE);
-
 protected:
     SvpCairoTextRender                  m_aTextRenderImpl;
     std::unique_ptr<SvpGraphicsBackend> m_pBackend;
@@ -116,15 +112,6 @@ public:
     virtual void            DrawTextLayout( const GenericSalLayout& ) override;
     virtual bool            supportsOperation( OutDevSupportType ) const 
override;
 
-    virtual void            copyArea( tools::Long nDestX,
-                                      tools::Long nDestY,
-                                      tools::Long nSrcX,
-                                      tools::Long nSrcY,
-                                      tools::Long nSrcWidth,
-                                      tools::Long nSrcHeight,
-                                      bool bWindowInvalidate) override;
-    virtual void            copyBits( const SalTwoRect& rPosAry,
-                                      SalGraphics* pSrcGraphics ) override;
     virtual void            drawBitmap( const SalTwoRect& rPosAry,
                                         const SalBitmap& rSalBitmap ) override;
     void                    drawBitmap( const SalTwoRect& rPosAry,
@@ -163,6 +150,10 @@ public:
     {
         m_aCairoCommon.clipRegion(cr);
     }
+    void copySource(const SalTwoRect& rTR, cairo_surface_t* source)
+    {
+        m_aCairoCommon.copySource(rTR, source, getAntiAlias());
+    }
 };
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Reply via email to