summaryrefslogtreecommitdiff
path: root/vcl/headless/svpgdi.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/headless/svpgdi.cxx')
-rw-r--r--vcl/headless/svpgdi.cxx142
1 files changed, 69 insertions, 73 deletions
diff --git a/vcl/headless/svpgdi.cxx b/vcl/headless/svpgdi.cxx
index 8c76c21f4f9d..0d4a366fc4f1 100644
--- a/vcl/headless/svpgdi.cxx
+++ b/vcl/headless/svpgdi.cxx
@@ -119,18 +119,6 @@ namespace
aDamageRect.intersect(getClipBox(cr));
return aDamageRect;
}
-
- // The caching logic is surprisingly expensive - so avoid it sometimes.
- inline bool isTrivial(const basegfx::B2DPolyPolygon& rPolyPolygon)
- {
- return rPolyPolygon.count() == 1 && rPolyPolygon.begin()->count() <= 4;
- }
-
- // The caching logic is surprisingly expensive - so avoid it sometimes.
- inline bool isTrivial(const basegfx::B2DPolygon& rPolyLine)
- {
- return rPolyLine.count() <= 4;
- }
}
bool SvpSalGraphics::blendBitmap( const SalTwoRect&, const SalBitmap& /*rBitmap*/ )
@@ -894,7 +882,9 @@ static basegfx::B2DPoint impPixelSnap(
// 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 (!)
-static void AddPolygonToPath(
+// 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,
@@ -903,10 +893,11 @@ static void AddPolygonToPath(
{
// short circuit if there is nothing to do
const sal_uInt32 nPointCount(rPolygon.count());
+ size_t nSizeMeasure(0);
if(0 == nPointCount)
{
- return;
+ return nSizeMeasure;
}
const bool bHasCurves(rPolygon.areControlPointsUsed());
@@ -985,6 +976,7 @@ static void AddPolygonToPath(
if( !bPendingCurve ) // line segment
{
cairo_line_to(cr, aPoint.getX(), aPoint.getY());
+ nSizeMeasure++;
}
else // cubic bezier segment
{
@@ -1007,6 +999,10 @@ static void AddPolygonToPath(
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;
@@ -1016,6 +1012,8 @@ static void AddPolygonToPath(
{
cairo_close_path(cr);
}
+
+ return nSizeMeasure;
}
void SvpSalGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 )
@@ -1070,7 +1068,8 @@ private:
public:
SystemDependentData_CairoPath(
basegfx::SystemDependentDataManager& rSystemDependentDataManager,
- cairo_path_t* pCairoPath,
+ size_t nSizeMeasure,
+ cairo_t* cr,
bool bNoJoin,
bool bAntiAliasB2DDraw);
virtual ~SystemDependentData_CairoPath() override;
@@ -1086,14 +1085,21 @@ public:
SystemDependentData_CairoPath::SystemDependentData_CairoPath(
basegfx::SystemDependentDataManager& rSystemDependentDataManager,
- cairo_path_t* pCairoPath,
+ size_t nSizeMeasure,
+ cairo_t* cr,
bool bNoJoin,
bool bAntiAliasB2DDraw)
: basegfx::SystemDependentData(rSystemDependentDataManager),
- mpCairoPath(pCairoPath),
+ mpCairoPath(nullptr),
mbNoJoin(bNoJoin),
mbAntiAliasB2DDraw(bAntiAliasB2DDraw)
{
+ // tdf#129845 only create a copy of the path when nSizeMeasure is
+ // bigger than some decent threshold
+ if(nSizeMeasure > 50)
+ {
+ mpCairoPath = cairo_copy_path(cr);
+ }
}
SystemDependentData_CairoPath::~SystemDependentData_CairoPath()
@@ -1107,6 +1113,9 @@ SystemDependentData_CairoPath::~SystemDependentData_CairoPath()
sal_Int64 SystemDependentData_CairoPath::estimateUsageInBytes() const
{
+ // tdf#129845 by using the default return value of zero when no path
+ // was created, SystemDependentData::calculateCombinedHoldCyclesInSeconds
+ // will do the right thing and not buffer this entry at all
sal_Int64 nRetval(0);
if(nullptr != mpCairoPath)
@@ -1291,43 +1300,37 @@ bool SvpSalGraphics::drawPolyLine(
cairo_set_line_width(cr, aLineWidths.getX());
cairo_set_miter_limit(cr, fMiterLimit);
- bool bDone = false;
- bool bIsTrivial = isTrivial(rPolyLine);
+ // try to access buffered data
+ std::shared_ptr<SystemDependentData_CairoPath> pSystemDependentData_CairoPath(
+ rPolyLine.getSystemDependentData<SystemDependentData_CairoPath>());
- if (!bIsTrivial)
+ if(pSystemDependentData_CairoPath)
{
- // try to access buffered data
- std::shared_ptr<SystemDependentData_CairoPath> pSystemDependentData_CairoPath(
- rPolyLine.getSystemDependentData<SystemDependentData_CairoPath>());
-
- if(pSystemDependentData_CairoPath)
+ // check data validity
+ if(nullptr == pSystemDependentData_CairoPath->getCairoPath()
+ || pSystemDependentData_CairoPath->getNoJoin() != bNoJoin
+ || pSystemDependentData_CairoPath->getAntiAliasB2DDraw() != bAntiAliasB2DDraw
+ || bPixelSnapHairline /*tdf#124700*/ )
{
- // check data validity
- if(nullptr == pSystemDependentData_CairoPath->getCairoPath()
- || pSystemDependentData_CairoPath->getNoJoin() != bNoJoin
- || pSystemDependentData_CairoPath->getAntiAliasB2DDraw() != bAntiAliasB2DDraw
- || bPixelSnapHairline /*tdf#124700*/ )
- {
- // data invalid, forget
- pSystemDependentData_CairoPath.reset();
- }
- }
-
- if(pSystemDependentData_CairoPath)
- {
- // re-use data
- cairo_append_path(cr, pSystemDependentData_CairoPath->getCairoPath());
- bDone = true;
+ // data invalid, forget
+ pSystemDependentData_CairoPath.reset();
}
}
- if (!bDone)
+ if(pSystemDependentData_CairoPath)
+ {
+ // re-use data
+ cairo_append_path(cr, pSystemDependentData_CairoPath->getCairoPath());
+ }
+ else
{
// create data
+ size_t nSizeMeasure(0);
+
if (!bNoJoin)
{
// PixelOffset now reflected in linear transformation used
- AddPolygonToPath(
+ nSizeMeasure += AddPolygonToPath(
cr,
rPolyLine,
rObjectToDevice, // ObjectToDevice *without* LineDraw-Offset
@@ -1351,7 +1354,7 @@ bool SvpSalGraphics::drawPolyLine(
aEdge.setPrevControlPoint(1, rPolyLine.getPrevControlPoint(nNextIndex));
// PixelOffset now reflected in linear transformation used
- AddPolygonToPath(
+ nSizeMeasure += AddPolygonToPath(
cr,
aEdge,
rObjectToDevice, // ObjectToDevice *without* LineDraw-Offset
@@ -1364,11 +1367,12 @@ bool SvpSalGraphics::drawPolyLine(
}
// copy and add to buffering mechanism
- if (!bIsTrivial && !bPixelSnapHairline /*tdf#124700*/)
+ if (!bPixelSnapHairline /*tdf#124700*/)
{
- rPolyLine.addOrReplaceSystemDependentData<SystemDependentData_CairoPath>(
+ pSystemDependentData_CairoPath = rPolyLine.addOrReplaceSystemDependentData<SystemDependentData_CairoPath>(
ImplGetSystemDependentDataManager(),
- cairo_copy_path(cr),
+ nSizeMeasure,
+ cr,
bNoJoin,
bAntiAliasB2DDraw);
}
@@ -1417,31 +1421,25 @@ namespace
{
void add_polygon_path(cairo_t* cr, const basegfx::B2DPolyPolygon& rPolyPolygon, const basegfx::B2DHomMatrix& rObjectToDevice, bool bPixelSnap)
{
- bool bDone = false;
- bool bIsTrivial = isTrivial(rPolyPolygon);
+ // try to access buffered data
+ std::shared_ptr<SystemDependentData_CairoPath> pSystemDependentData_CairoPath(
+ rPolyPolygon.getSystemDependentData<SystemDependentData_CairoPath>());
- if (!bIsTrivial)
+ if(pSystemDependentData_CairoPath)
{
- // try to access buffered data
- std::shared_ptr<SystemDependentData_CairoPath> pSystemDependentData_CairoPath(
- rPolyPolygon.getSystemDependentData<SystemDependentData_CairoPath>());
-
- if(pSystemDependentData_CairoPath)
- {
- // re-use data
- cairo_append_path(cr, pSystemDependentData_CairoPath->getCairoPath());
- bDone = true;
- }
+ // re-use data
+ cairo_append_path(cr, pSystemDependentData_CairoPath->getCairoPath());
}
-
- if (!bDone)
+ else
{
// create data
+ size_t nSizeMeasure(0);
+
for (const auto & rPoly : rPolyPolygon)
{
// PixelOffset used: Was dependent of 'm_aLineColor != SALCOLOR_NONE'
// Adapt setupPolyPolygon-users to set a linear transformation to achieve PixelOffset
- AddPolygonToPath(
+ nSizeMeasure += AddPolygonToPath(
cr,
rPoly,
rObjectToDevice,
@@ -1449,16 +1447,14 @@ namespace
false);
}
- if (!bIsTrivial)
- {
- // copy and add to buffering mechanism
- // for decisions how/what to buffer, see Note in WinSalGraphicsImpl::drawPolyPolygon
- rPolyPolygon.addOrReplaceSystemDependentData<SystemDependentData_CairoPath>(
- ImplGetSystemDependentDataManager(),
- cairo_copy_path(cr),
- false,
- false);
- }
+ // copy and add to buffering mechanism
+ // for decisions how/what to buffer, see Note in WinSalGraphicsImpl::drawPolyPolygon
+ pSystemDependentData_CairoPath = rPolyPolygon.addOrReplaceSystemDependentData<SystemDependentData_CairoPath>(
+ ImplGetSystemDependentDataManager(),
+ nSizeMeasure,
+ cr,
+ false,
+ false);
}
}
}