vcl/headless/CairoCommon.cxx        |  207 +++++++++++++++++++++++++++++
 vcl/headless/SvpGraphicsBackend.cxx |   31 ++++
 vcl/headless/svpgdi.cxx             |  250 ------------------------------------
 vcl/inc/headless/CairoCommon.hxx    |   12 +
 vcl/inc/headless/svpgdi.hxx         |    1 
 5 files changed, 248 insertions(+), 253 deletions(-)

New commits:
commit f1cbb458e158c8f62c9c47917f8ab0ef76ba0ced
Author:     Tomaž Vajngerl <[email protected]>
AuthorDate: Fri Nov 26 19:53:59 2021 +0100
Commit:     Tomaž Vajngerl <[email protected]>
CommitDate: Thu Dec 30 16:20:39 2021 +0100

    vcl: move drawLine to SvpGraphicsBackend
    
    Also move getClippedStrokeDamage, AddPolygonToPath, impPixelSnap
    to CairoCommon, as it is needed by the move.
    
    Change-Id: I002f0094935e5f5d4836bb973f7cf7bea0218ff2
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/127710
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <[email protected]>

diff --git a/vcl/headless/CairoCommon.cxx b/vcl/headless/CairoCommon.cxx
index 5ba1ebb0edf1..e79a6b2d6a9b 100644
--- a/vcl/headless/CairoCommon.cxx
+++ b/vcl/headless/CairoCommon.cxx
@@ -91,6 +91,213 @@ basegfx::B2DRange getClippedFillDamage(cairo_t* cr)
     return aDamageRect;
 }
 
+basegfx::B2DRange getStrokeDamage(cairo_t* cr)
+{
+    double x1, y1, x2, y2;
+
+    // less accurate, but much faster
+    cairo_path_extents(cr, &x1, &y1, &x2, &y2);
+
+    // support B2DRange::isEmpty()
+    if (0.0 != x1 || 0.0 != y1 || 0.0 != x2 || 0.0 != y2)
+    {
+        return basegfx::B2DRange(x1, y1, x2, y2);
+    }
+
+    return basegfx::B2DRange();
+}
+
+basegfx::B2DRange getClippedStrokeDamage(cairo_t* cr)
+{
+    basegfx::B2DRange aDamageRect(getStrokeDamage(cr));
+    aDamageRect.intersect(getClipBox(cr));
+    return aDamageRect;
+}
+
+// Remove bClosePath: Checked that the already used mechanism for Win using
+// Gdiplus already relies on rPolygon.isClosed(), so should be safe to replace
+// this.
+// For PixelSnap we need the ObjectToDevice transformation here now. This is a
+// special case relative to the also executed LineDraw-Offset of (0.5, 0.5) in
+// DeviceCoordinates: The LineDraw-Offset is applied *after* the snap, so we
+// need the ObjectToDevice transformation *without* that offset here to do the
+// same. The LineDraw-Offset will be applied by the callers using a linear
+// transformation for Cairo now
+// For support of PixelSnapHairline we also need the ObjectToDevice 
transformation
+// and a method (same as in gdiimpl.cxx for Win and Gdiplus). This is needed 
e.g.
+// for Chart-content visualization. CAUTION: It's not the same as PixelSnap (!)
+// tdf#129845 add reply value to allow counting a point/byte/size measurement 
to
+// be included
+size_t AddPolygonToPath(cairo_t* cr, const basegfx::B2DPolygon& rPolygon,
+                        const basegfx::B2DHomMatrix& rObjectToDevice, bool 
bPixelSnap,
+                        bool bPixelSnapHairline)
+{
+    // short circuit if there is nothing to do
+    const sal_uInt32 nPointCount(rPolygon.count());
+    size_t nSizeMeasure(0);
+
+    if (0 == nPointCount)
+    {
+        return nSizeMeasure;
+    }
+
+    const bool bHasCurves(rPolygon.areControlPointsUsed());
+    const bool bClosePath(rPolygon.isClosed());
+    const bool bObjectToDeviceUsed(!rObjectToDevice.isIdentity());
+    basegfx::B2DHomMatrix aObjectToDeviceInv;
+    basegfx::B2DPoint aLast;
+
+    for (sal_uInt32 nPointIdx = 0, nPrevIdx = 0;; nPrevIdx = nPointIdx++)
+    {
+        int nClosedIdx = nPointIdx;
+        if (nPointIdx >= nPointCount)
+        {
+            // prepare to close last curve segment if needed
+            if (bClosePath && (nPointIdx == nPointCount))
+            {
+                nClosedIdx = 0;
+            }
+            else
+            {
+                break;
+            }
+        }
+
+        basegfx::B2DPoint aPoint(rPolygon.getB2DPoint(nClosedIdx));
+
+        if (bPixelSnap)
+        {
+            // snap device coordinates to full pixels
+            if (bObjectToDeviceUsed)
+            {
+                // go to DeviceCoordinates
+                aPoint *= rObjectToDevice;
+            }
+
+            // snap by rounding
+            aPoint.setX(basegfx::fround(aPoint.getX()));
+            aPoint.setY(basegfx::fround(aPoint.getY()));
+
+            if (bObjectToDeviceUsed)
+            {
+                if (aObjectToDeviceInv.isIdentity())
+                {
+                    aObjectToDeviceInv = rObjectToDevice;
+                    aObjectToDeviceInv.invert();
+                }
+
+                // go back to ObjectCoordinates
+                aPoint *= aObjectToDeviceInv;
+            }
+        }
+
+        if (bPixelSnapHairline)
+        {
+            // snap horizontal and vertical lines (mainly used in Chart for
+            // 'nicer' AAing)
+            aPoint = impPixelSnap(rPolygon, rObjectToDevice, 
aObjectToDeviceInv, nClosedIdx);
+        }
+
+        if (!nPointIdx)
+        {
+            // first point => just move there
+            cairo_move_to(cr, aPoint.getX(), aPoint.getY());
+            aLast = aPoint;
+            continue;
+        }
+
+        bool bPendingCurve(false);
+
+        if (bHasCurves)
+        {
+            bPendingCurve = rPolygon.isNextControlPointUsed(nPrevIdx);
+            bPendingCurve |= rPolygon.isPrevControlPointUsed(nClosedIdx);
+        }
+
+        if (!bPendingCurve) // line segment
+        {
+            cairo_line_to(cr, aPoint.getX(), aPoint.getY());
+            nSizeMeasure++;
+        }
+        else // cubic bezier segment
+        {
+            basegfx::B2DPoint aCP1 = rPolygon.getNextControlPoint(nPrevIdx);
+            basegfx::B2DPoint aCP2 = rPolygon.getPrevControlPoint(nClosedIdx);
+
+            // tdf#99165 if the control points are 'empty', create the 
mathematical
+            // correct replacement ones to avoid problems with the graphical 
sub-system
+            // tdf#101026 The 1st attempt to create a mathematically correct 
replacement control
+            // vector was wrong. Best alternative is one as close as possible 
which means short.
+            if (aCP1.equal(aLast))
+            {
+                aCP1 = aLast + ((aCP2 - aLast) * 0.0005);
+            }
+
+            if (aCP2.equal(aPoint))
+            {
+                aCP2 = aPoint + ((aCP1 - aPoint) * 0.0005);
+            }
+
+            cairo_curve_to(cr, aCP1.getX(), aCP1.getY(), aCP2.getX(), 
aCP2.getY(), aPoint.getX(),
+                           aPoint.getY());
+            // take some bigger measure for curve segments - too expensive to 
subdivide
+            // here and that precision not needed, but four (2 points, 2 
control-points)
+            // would be a too low weight
+            nSizeMeasure += 10;
+        }
+
+        aLast = aPoint;
+    }
+
+    if (bClosePath)
+    {
+        cairo_close_path(cr);
+    }
+
+    return nSizeMeasure;
+}
+
+basegfx::B2DPoint impPixelSnap(const basegfx::B2DPolygon& rPolygon,
+                               const basegfx::B2DHomMatrix& rObjectToDevice,
+                               basegfx::B2DHomMatrix& rObjectToDeviceInv, 
sal_uInt32 nIndex)
+{
+    const sal_uInt32 nCount(rPolygon.count());
+
+    // get the data
+    const basegfx::B2ITuple aPrevTuple(
+        basegfx::fround(rObjectToDevice * rPolygon.getB2DPoint((nIndex + 
nCount - 1) % nCount)));
+    const basegfx::B2DPoint aCurrPoint(rObjectToDevice * 
rPolygon.getB2DPoint(nIndex));
+    const basegfx::B2ITuple aCurrTuple(basegfx::fround(aCurrPoint));
+    const basegfx::B2ITuple aNextTuple(
+        basegfx::fround(rObjectToDevice * rPolygon.getB2DPoint((nIndex + 1) % 
nCount)));
+
+    // get the states
+    const bool bPrevVertical(aPrevTuple.getX() == aCurrTuple.getX());
+    const bool bNextVertical(aNextTuple.getX() == aCurrTuple.getX());
+    const bool bPrevHorizontal(aPrevTuple.getY() == aCurrTuple.getY());
+    const bool bNextHorizontal(aNextTuple.getY() == aCurrTuple.getY());
+    const bool bSnapX(bPrevVertical || bNextVertical);
+    const bool bSnapY(bPrevHorizontal || bNextHorizontal);
+
+    if (bSnapX || bSnapY)
+    {
+        basegfx::B2DPoint aSnappedPoint(bSnapX ? aCurrTuple.getX() : 
aCurrPoint.getX(),
+                                        bSnapY ? aCurrTuple.getY() : 
aCurrPoint.getY());
+
+        if (rObjectToDeviceInv.isIdentity())
+        {
+            rObjectToDeviceInv = rObjectToDevice;
+            rObjectToDeviceInv.invert();
+        }
+
+        aSnappedPoint *= rObjectToDeviceInv;
+
+        return aSnappedPoint;
+    }
+
+    return rPolygon.getB2DPoint(nIndex);
+}
+
 cairo_user_data_key_t* CairoCommon::getDamageKey()
 {
     static cairo_user_data_key_t aDamageKey;
diff --git a/vcl/headless/SvpGraphicsBackend.cxx 
b/vcl/headless/SvpGraphicsBackend.cxx
index c4bfe42d4844..d3a53fefe3f1 100644
--- a/vcl/headless/SvpGraphicsBackend.cxx
+++ b/vcl/headless/SvpGraphicsBackend.cxx
@@ -119,9 +119,36 @@ void SvpGraphicsBackend::drawPixel(tools::Long nX, 
tools::Long nY, Color aColor)
     m_rCairoCommon.releaseCairoContext(cr, true, extents);
 }
 
-void SvpGraphicsBackend::drawLine(tools::Long /*nX1*/, tools::Long /*nY1*/, 
tools::Long /*nX2*/,
-                                  tools::Long /*nY2*/)
+void SvpGraphicsBackend::drawLine(tools::Long nX1, tools::Long nY1, 
tools::Long nX2,
+                                  tools::Long nY2)
 {
+    basegfx::B2DPolygon aPoly;
+
+    // PixelOffset used: To not mix with possible PixelSnap, cannot do
+    // directly on coordinates as tried before - despite being already 
'snapped'
+    // due to being integer. If it would be directly added here, it would be
+    // 'snapped' again when !getAntiAlias(), losing the (0.5, 0.5) offset
+    aPoly.append(basegfx::B2DPoint(nX1, nY1));
+    aPoly.append(basegfx::B2DPoint(nX2, nY2));
+
+    cairo_t* cr = m_rCairoCommon.getCairoContext(false, getAntiAlias());
+    m_rCairoCommon.clipRegion(cr);
+
+    // PixelOffset used: Set PixelOffset as linear transformation
+    cairo_matrix_t aMatrix;
+    cairo_matrix_init_translate(&aMatrix, 0.5, 0.5);
+    cairo_set_matrix(cr, &aMatrix);
+
+    AddPolygonToPath(cr, aPoly, basegfx::B2DHomMatrix(), !getAntiAlias(), 
false);
+
+    m_rCairoCommon.applyColor(cr, m_rCairoCommon.m_aLineColor);
+
+    basegfx::B2DRange extents = getClippedStrokeDamage(cr);
+    extents.transform(basegfx::utils::createTranslateB2DHomMatrix(0.5, 0.5));
+
+    cairo_stroke(cr);
+
+    m_rCairoCommon.releaseCairoContext(cr, false, extents);
 }
 
 void SvpGraphicsBackend::drawRect(tools::Long /*nX*/, tools::Long /*nY*/, 
tools::Long /*nWidth*/,
diff --git a/vcl/headless/svpgdi.cxx b/vcl/headless/svpgdi.cxx
index 4c2695b5c999..9e50652928d9 100644
--- a/vcl/headless/svpgdi.cxx
+++ b/vcl/headless/svpgdi.cxx
@@ -57,32 +57,6 @@
 #   endif
 #endif
 
-namespace
-{
-    basegfx::B2DRange getStrokeDamage(cairo_t* cr)
-    {
-        double x1, y1, x2, y2;
-
-        // less accurate, but much faster
-        cairo_path_extents(cr, &x1, &y1, &x2, &y2);
-
-        // support B2DRange::isEmpty()
-        if(0.0 != x1 || 0.0 != y1 || 0.0 != x2 || 0.0 != y2)
-        {
-            return basegfx::B2DRange(x1, y1, x2, y2);
-        }
-
-        return basegfx::B2DRange();
-    }
-
-    basegfx::B2DRange getClippedStrokeDamage(cairo_t* cr)
-    {
-        basegfx::B2DRange aDamageRect(getStrokeDamage(cr));
-        aDamageRect.intersect(getClipBox(cr));
-        return aDamageRect;
-    }
-}
-
 bool SvpSalGraphics::blendBitmap( const SalTwoRect&, const SalBitmap& 
/*rBitmap*/ )
 {
     return false;
@@ -976,230 +950,6 @@ void SvpSalGraphics::drawPolyPolygon(sal_uInt32 nPoly,
         0.0);
 }
 
-static basegfx::B2DPoint impPixelSnap(
-    const basegfx::B2DPolygon& rPolygon,
-    const basegfx::B2DHomMatrix& rObjectToDevice,
-    basegfx::B2DHomMatrix& rObjectToDeviceInv,
-    sal_uInt32 nIndex)
-{
-    const sal_uInt32 nCount(rPolygon.count());
-
-    // get the data
-    const basegfx::B2ITuple aPrevTuple(basegfx::fround(rObjectToDevice * 
rPolygon.getB2DPoint((nIndex + nCount - 1) % nCount)));
-    const basegfx::B2DPoint aCurrPoint(rObjectToDevice * 
rPolygon.getB2DPoint(nIndex));
-    const basegfx::B2ITuple aCurrTuple(basegfx::fround(aCurrPoint));
-    const basegfx::B2ITuple aNextTuple(basegfx::fround(rObjectToDevice * 
rPolygon.getB2DPoint((nIndex + 1) % nCount)));
-
-    // get the states
-    const bool bPrevVertical(aPrevTuple.getX() == aCurrTuple.getX());
-    const bool bNextVertical(aNextTuple.getX() == aCurrTuple.getX());
-    const bool bPrevHorizontal(aPrevTuple.getY() == aCurrTuple.getY());
-    const bool bNextHorizontal(aNextTuple.getY() == aCurrTuple.getY());
-    const bool bSnapX(bPrevVertical || bNextVertical);
-    const bool bSnapY(bPrevHorizontal || bNextHorizontal);
-
-    if(bSnapX || bSnapY)
-    {
-        basegfx::B2DPoint aSnappedPoint(
-            bSnapX ? aCurrTuple.getX() : aCurrPoint.getX(),
-            bSnapY ? aCurrTuple.getY() : aCurrPoint.getY());
-
-        if(rObjectToDeviceInv.isIdentity())
-        {
-            rObjectToDeviceInv = rObjectToDevice;
-            rObjectToDeviceInv.invert();
-        }
-
-        aSnappedPoint *= rObjectToDeviceInv;
-
-        return aSnappedPoint;
-    }
-
-    return rPolygon.getB2DPoint(nIndex);
-}
-
-// Remove bClosePath: Checked that the already used mechanism for Win using
-// Gdiplus already relies on rPolygon.isClosed(), so should be safe to replace
-// this.
-// For PixelSnap we need the ObjectToDevice transformation here now. This is a
-// special case relative to the also executed LineDraw-Offset of (0.5, 0.5) in
-// DeviceCoordinates: The LineDraw-Offset is applied *after* the snap, so we
-// need the ObjectToDevice transformation *without* that offset here to do the
-// same. The LineDraw-Offset will be applied by the callers using a linear
-// transformation for Cairo now
-// For support of PixelSnapHairline we also need the ObjectToDevice 
transformation
-// and a method (same as in gdiimpl.cxx for Win and Gdiplus). This is needed 
e.g.
-// for Chart-content visualization. CAUTION: It's not the same as PixelSnap (!)
-// tdf#129845 add reply value to allow counting a point/byte/size measurement 
to
-// be included
-static size_t AddPolygonToPath(
-    cairo_t* cr,
-    const basegfx::B2DPolygon& rPolygon,
-    const basegfx::B2DHomMatrix& rObjectToDevice,
-    bool bPixelSnap,
-    bool bPixelSnapHairline)
-{
-    // short circuit if there is nothing to do
-    const sal_uInt32 nPointCount(rPolygon.count());
-    size_t nSizeMeasure(0);
-
-    if(0 == nPointCount)
-    {
-        return nSizeMeasure;
-    }
-
-    const bool bHasCurves(rPolygon.areControlPointsUsed());
-    const bool bClosePath(rPolygon.isClosed());
-    const bool bObjectToDeviceUsed(!rObjectToDevice.isIdentity());
-    basegfx::B2DHomMatrix aObjectToDeviceInv;
-    basegfx::B2DPoint aLast;
-
-    for( sal_uInt32 nPointIdx = 0, nPrevIdx = 0;; nPrevIdx = nPointIdx++ )
-    {
-        int nClosedIdx = nPointIdx;
-        if( nPointIdx >= nPointCount )
-        {
-            // prepare to close last curve segment if needed
-            if( bClosePath && (nPointIdx == nPointCount) )
-            {
-                nClosedIdx = 0;
-            }
-            else
-            {
-                break;
-            }
-        }
-
-        basegfx::B2DPoint aPoint(rPolygon.getB2DPoint(nClosedIdx));
-
-        if(bPixelSnap)
-        {
-            // snap device coordinates to full pixels
-            if(bObjectToDeviceUsed)
-            {
-                // go to DeviceCoordinates
-                aPoint *= rObjectToDevice;
-            }
-
-            // snap by rounding
-            aPoint.setX( basegfx::fround( aPoint.getX() ) );
-            aPoint.setY( basegfx::fround( aPoint.getY() ) );
-
-            if(bObjectToDeviceUsed)
-            {
-                if(aObjectToDeviceInv.isIdentity())
-                {
-                    aObjectToDeviceInv = rObjectToDevice;
-                    aObjectToDeviceInv.invert();
-                }
-
-                // go back to ObjectCoordinates
-                aPoint *= aObjectToDeviceInv;
-            }
-        }
-
-        if(bPixelSnapHairline)
-        {
-            // snap horizontal and vertical lines (mainly used in Chart for
-            // 'nicer' AAing)
-            aPoint = impPixelSnap(rPolygon, rObjectToDevice, 
aObjectToDeviceInv, nClosedIdx);
-        }
-
-        if( !nPointIdx )
-        {
-            // first point => just move there
-            cairo_move_to(cr, aPoint.getX(), aPoint.getY());
-            aLast = aPoint;
-            continue;
-        }
-
-        bool bPendingCurve(false);
-
-        if( bHasCurves )
-        {
-            bPendingCurve = rPolygon.isNextControlPointUsed( nPrevIdx );
-            bPendingCurve |= rPolygon.isPrevControlPointUsed( nClosedIdx );
-        }
-
-        if( !bPendingCurve )    // line segment
-        {
-            cairo_line_to(cr, aPoint.getX(), aPoint.getY());
-            nSizeMeasure++;
-        }
-        else                        // cubic bezier segment
-        {
-            basegfx::B2DPoint aCP1 = rPolygon.getNextControlPoint( nPrevIdx );
-            basegfx::B2DPoint aCP2 = rPolygon.getPrevControlPoint( nClosedIdx 
);
-
-            // tdf#99165 if the control points are 'empty', create the 
mathematical
-            // correct replacement ones to avoid problems with the graphical 
sub-system
-            // tdf#101026 The 1st attempt to create a mathematically correct 
replacement control
-            // vector was wrong. Best alternative is one as close as possible 
which means short.
-            if (aCP1.equal(aLast))
-            {
-                aCP1 = aLast + ((aCP2 - aLast) * 0.0005);
-            }
-
-            if(aCP2.equal(aPoint))
-            {
-                aCP2 = aPoint + ((aCP1 - aPoint) * 0.0005);
-            }
-
-            cairo_curve_to(cr, aCP1.getX(), aCP1.getY(), aCP2.getX(), 
aCP2.getY(),
-                               aPoint.getX(), aPoint.getY());
-            // take some bigger measure for curve segments - too expensive to 
subdivide
-            // here and that precision not needed, but four (2 points, 2 
control-points)
-            // would be a too low weight
-            nSizeMeasure += 10;
-        }
-
-        aLast = aPoint;
-    }
-
-    if( bClosePath )
-    {
-        cairo_close_path(cr);
-    }
-
-    return nSizeMeasure;
-}
-
-void SvpSalGraphics::drawLine( tools::Long nX1, tools::Long nY1, tools::Long 
nX2, tools::Long nY2 )
-{
-    basegfx::B2DPolygon aPoly;
-
-    // PixelOffset used: To not mix with possible PixelSnap, cannot do
-    // directly on coordinates as tried before - despite being already 
'snapped'
-    // due to being integer. If it would be directly added here, it would be
-    // 'snapped' again when !getAntiAlias(), losing the (0.5, 0.5) offset
-    aPoly.append(basegfx::B2DPoint(nX1, nY1));
-    aPoly.append(basegfx::B2DPoint(nX2, nY2));
-
-    cairo_t* cr = m_aCairoCommon.getCairoContext(false, getAntiAlias());
-    clipRegion(cr);
-
-    // PixelOffset used: Set PixelOffset as linear transformation
-    cairo_matrix_t aMatrix;
-    cairo_matrix_init_translate(&aMatrix, 0.5, 0.5);
-    cairo_set_matrix(cr, &aMatrix);
-
-    AddPolygonToPath(
-        cr,
-        aPoly,
-        basegfx::B2DHomMatrix(),
-        !getAntiAlias(),
-        false);
-
-    m_aCairoCommon.applyColor(cr, m_aCairoCommon.m_aLineColor);
-
-    basegfx::B2DRange extents = getClippedStrokeDamage(cr);
-    extents.transform(basegfx::utils::createTranslateB2DHomMatrix(0.5, 0.5));
-
-    cairo_stroke(cr);
-
-    m_aCairoCommon.releaseCairoContext(cr, false, extents);
-}
-
 namespace {
 
 class SystemDependentData_CairoPath : public basegfx::SystemDependentData
diff --git a/vcl/inc/headless/CairoCommon.hxx b/vcl/inc/headless/CairoCommon.hxx
index 3642a2361d84..36acef3c659d 100644
--- a/vcl/inc/headless/CairoCommon.hxx
+++ b/vcl/inc/headless/CairoCommon.hxx
@@ -30,6 +30,7 @@
 
 #include <basegfx/range/b2drange.hxx>
 #include <basegfx/range/b2irange.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
 
 //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
@@ -71,6 +72,17 @@ VCL_DLLPUBLIC void 
dl_cairo_surface_get_device_scale(cairo_surface_t* surface, d
 VCL_DLLPUBLIC basegfx::B2DRange getFillDamage(cairo_t* cr);
 VCL_DLLPUBLIC basegfx::B2DRange getClipBox(cairo_t* cr);
 VCL_DLLPUBLIC basegfx::B2DRange getClippedFillDamage(cairo_t* cr);
+VCL_DLLPUBLIC basegfx::B2DRange getClippedStrokeDamage(cairo_t* cr);
+VCL_DLLPUBLIC basegfx::B2DRange getStrokeDamage(cairo_t* cr);
+
+VCL_DLLPUBLIC size_t AddPolygonToPath(cairo_t* cr, const basegfx::B2DPolygon& 
rPolygon,
+                                      const basegfx::B2DHomMatrix& 
rObjectToDevice, bool bPixelSnap,
+                                      bool bPixelSnapHairline);
+
+VCL_DLLPUBLIC basegfx::B2DPoint impPixelSnap(const basegfx::B2DPolygon& 
rPolygon,
+                                             const basegfx::B2DHomMatrix& 
rObjectToDevice,
+                                             basegfx::B2DHomMatrix& 
rObjectToDeviceInv,
+                                             sal_uInt32 nIndex);
 
 enum class PaintMode
 {
diff --git a/vcl/inc/headless/svpgdi.hxx b/vcl/inc/headless/svpgdi.hxx
index dc042c499e76..5f5be07a43a5 100644
--- a/vcl/inc/headless/svpgdi.hxx
+++ b/vcl/inc/headless/svpgdi.hxx
@@ -137,7 +137,6 @@ public:
     virtual void            DrawTextLayout( const GenericSalLayout& ) override;
     virtual bool            supportsOperation( OutDevSupportType ) const 
override;
 
-    virtual void            drawLine( tools::Long nX1, tools::Long nY1, 
tools::Long nX2, tools::Long nY2 ) override;
     virtual void            drawRect( tools::Long nX, tools::Long nY, 
tools::Long nWidth, tools::Long nHeight ) override;
 
     virtual bool            drawPolyPolygon(

Reply via email to