diff options
author | Armin.Le.Grand (CIB) <Armin.Le.Grand@me.com> | 2020-03-03 11:34:45 +0100 |
---|---|---|
committer | Thorsten Behrens <thorsten.behrens@allotropia.de> | 2021-04-09 23:21:27 +0200 |
commit | 1a9ef8b0e3fb77944dcd7223f90345645c7e7410 (patch) | |
tree | 5567044a35317d3405e69183afc2c83a79998ff9 /basegfx/source | |
parent | Allow opt-out from document events check (diff) | |
download | core-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.cxx | 15 | ||||
-rw-r--r-- | basegfx/source/polygon/b2dpolypolygoncutter.cxx | 36 |
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. |