summaryrefslogtreecommitdiffstats
path: root/basegfx/source
diff options
context:
space:
mode:
authorArmin.Le.Grand (CIB) <Armin.Le.Grand@me.com>2020-03-03 11:34:45 +0100
committerThorsten Behrens <thorsten.behrens@allotropia.de>2021-04-09 23:21:27 +0200
commit1a9ef8b0e3fb77944dcd7223f90345645c7e7410 (patch)
tree5567044a35317d3405e69183afc2c83a79998ff9 /basegfx/source
parentAllow opt-out from document events check (diff)
downloadcore-1a9ef8b0e3fb77944dcd7223f90345645c7e7410.tar.gz
core-1a9ef8b0e3fb77944dcd7223f90345645c7e7410.zip
tdf#130150 Improve clipping in PDF export
For more info and discusson please have a look at the task. It reverts the change from tdf#99680 which did a wrong paradigm change in how clip in Region(s) is defined and tries to fix the underlying error in a more correct way. This includes problems noted in tdf#44388 and tdf#113449. This is a decent improvement, but - due to dealing with numerical problems - not yet the whole healing. Still thinking about how to solve this for good. Adapted PdfExportTest::testTdf99680() and PdfExportTest::testTdf99680_2() as needed, empty clip regions are allowed again. Added comments, too. Had to change solvePolygonOperationAnd to work on ranges if both inputs *are* ranges. The AND-case is then completely solvable. Also increased geometry for transformations of clip geometries - may help later. Change-Id: I2370447597faa6efb81d58ee31c63654e304262e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/89874 Tested-by: Jenkins Reviewed-by: Thorsten Behrens <Thorsten.Behrens@CIB.de>
Diffstat (limited to 'basegfx/source')
-rw-r--r--basegfx/source/polygon/b2dpolygontools.cxx15
-rw-r--r--basegfx/source/polygon/b2dpolypolygoncutter.cxx36
2 files changed, 44 insertions, 7 deletions
diff --git a/basegfx/source/polygon/b2dpolygontools.cxx b/basegfx/source/polygon/b2dpolygontools.cxx
index 4ac68958eaa2..cbc18ee74203 100644
--- a/basegfx/source/polygon/b2dpolygontools.cxx
+++ b/basegfx/source/polygon/b2dpolygontools.cxx
@@ -333,15 +333,15 @@ namespace basegfx
const B2DPoint aPreviousPoint(aCurrentPoint);
aCurrentPoint = aCandidate.getB2DPoint(a);
- // cross-over in Y?
- const bool bCompYA(fTools::more(aPreviousPoint.getY(), rPoint.getY()));
- const bool bCompYB(fTools::more(aCurrentPoint.getY(), rPoint.getY()));
+ // cross-over in Y? tdf#130150 use full precision, no need for epsilon
+ const bool bCompYA(aPreviousPoint.getY() > rPoint.getY());
+ const bool bCompYB(aCurrentPoint.getY() > rPoint.getY());
if(bCompYA != bCompYB)
{
- // cross-over in X?
- const bool bCompXA(fTools::more(aPreviousPoint.getX(), rPoint.getX()));
- const bool bCompXB(fTools::more(aCurrentPoint.getX(), rPoint.getX()));
+ // cross-over in X? tdf#130150 use full precision, no need for epsilon
+ const bool bCompXA(aPreviousPoint.getX() > rPoint.getX());
+ const bool bCompXB(aCurrentPoint.getX() > rPoint.getX());
if(bCompXA == bCompXB)
{
@@ -357,7 +357,8 @@ namespace basegfx
(aPreviousPoint.getX() - aCurrentPoint.getX()) /
(aPreviousPoint.getY() - aCurrentPoint.getY()));
- if(fTools::more(fCompare, rPoint.getX()))
+ // tdf#130150 use full precision, no need for epsilon
+ if(fCompare > rPoint.getX())
{
bRetval = !bRetval;
}
diff --git a/basegfx/source/polygon/b2dpolypolygoncutter.cxx b/basegfx/source/polygon/b2dpolypolygoncutter.cxx
index beb0136912fd..74d25d18ed25 100644
--- a/basegfx/source/polygon/b2dpolypolygoncutter.cxx
+++ b/basegfx/source/polygon/b2dpolypolygoncutter.cxx
@@ -986,6 +986,42 @@ namespace basegfx
}
else
{
+ // tdf#130150 shortcut & precision: If both are simple ranges,
+ // solve based on ranges
+ if(basegfx::utils::isRectangle(rCandidateA) && basegfx::utils::isRectangle(rCandidateB))
+ {
+ // *if* both are ranges, AND always can be solved
+ const basegfx::B2DRange aRangeA(rCandidateA.getB2DRange());
+ const basegfx::B2DRange aRangeB(rCandidateB.getB2DRange());
+
+ if(aRangeA.isInside(aRangeB))
+ {
+ // 2nd completely inside 1st -> 2nd is result of AND
+ return rCandidateB;
+ }
+
+ if(aRangeB.isInside(aRangeA))
+ {
+ // 2nd completely inside 1st -> 2nd is result of AND
+ return rCandidateA;
+ }
+
+ // solve by intersection
+ basegfx::B2DRange aIntersect(aRangeA);
+ aIntersect.intersect(aRangeB);
+
+ if(aIntersect.isEmpty())
+ {
+ // no overlap -> empty polygon as result of AND
+ return B2DPolyPolygon();
+ }
+
+ // create polygon result
+ return B2DPolyPolygon(
+ basegfx::utils::createPolygonFromRect(
+ aIntersect));
+ }
+
// concatenate polygons, solve crossovers and throw away all sub-polygons
// with a depth of < 1. This means to keep all polygons where at least two
// polygons do overlap.