From 53d5b3119feff3fe6653a38d13e21e6674055211 Mon Sep 17 00:00:00 2001 From: "Dr. David Alan Gilbert" Date: Thu, 22 Aug 2024 01:03:57 +0100 Subject: [PATCH] tdf#148526 sdext,pdfimport: Expand path to contour Poppler's 'ClipToStroke' call wants to clip to a paths rendered shape, i.e. with line thickness and possibly other attributes. Use get2DDecomposition to do that. Change-Id: I3ca54621dcb859520504e5c7d6cd41106f5c34d1 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/172924 Reviewed-by: David Gilbert Tested-by: Jenkins --- sdext/CppunitTest_sdext_pdfimport.mk | 3 ++ sdext/Executable_pdf2xml.mk | 3 ++ sdext/Executable_pdfunzip.mk | 3 ++ sdext/Library_pdfimport.mk | 3 ++ sdext/source/pdfimport/tree/pdfiprocessor.cxx | 40 +++++++++++++++++-- 5 files changed, 49 insertions(+), 3 deletions(-) diff --git a/sdext/CppunitTest_sdext_pdfimport.mk b/sdext/CppunitTest_sdext_pdfimport.mk index a16e1726bae9..5dd27bb05dd8 100644 --- a/sdext/CppunitTest_sdext_pdfimport.mk +++ b/sdext/CppunitTest_sdext_pdfimport.mk @@ -29,7 +29,10 @@ $(eval $(call gb_CppunitTest_use_libraries,sdext_pdfimport,\ comphelper \ cppu \ cppuhelper \ + drawinglayercore \ + drawinglayer \ sal \ + salhelper \ test \ unotest \ tl \ diff --git a/sdext/Executable_pdf2xml.mk b/sdext/Executable_pdf2xml.mk index 81e00eca11c0..d98ee3ea2a34 100644 --- a/sdext/Executable_pdf2xml.mk +++ b/sdext/Executable_pdf2xml.mk @@ -27,9 +27,12 @@ $(eval $(call gb_Executable_use_libraries,pdf2xml,\ vcl \ comphelper \ cppu \ + drawinglayercore \ + drawinglayer \ unotest \ cppuhelper \ sal \ + salhelper \ tl \ xo \ i18nutil \ diff --git a/sdext/Executable_pdfunzip.mk b/sdext/Executable_pdfunzip.mk index 10c179336048..30473dec70ce 100644 --- a/sdext/Executable_pdfunzip.mk +++ b/sdext/Executable_pdfunzip.mk @@ -26,7 +26,10 @@ $(eval $(call gb_Executable_use_libraries,pdfunzip,\ comphelper \ cppu \ cppuhelper \ + drawinglayercore \ + drawinglayer \ sal \ + salhelper \ vcl \ tl \ xo \ diff --git a/sdext/Library_pdfimport.mk b/sdext/Library_pdfimport.mk index dc1290cd0eb1..a1d4d0b5aceb 100644 --- a/sdext/Library_pdfimport.mk +++ b/sdext/Library_pdfimport.mk @@ -23,10 +23,13 @@ $(eval $(call gb_Library_set_include,pdfimport,\ $(eval $(call gb_Library_use_libraries,pdfimport,\ basegfx \ comphelper \ + drawinglayercore \ + drawinglayer \ vcl \ cppu \ cppuhelper \ sal \ + salhelper \ tl \ xo \ i18nutil \ diff --git a/sdext/source/pdfimport/tree/pdfiprocessor.cxx b/sdext/source/pdfimport/tree/pdfiprocessor.cxx index d798a49ae032..cb225560071f 100644 --- a/sdext/source/pdfimport/tree/pdfiprocessor.cxx +++ b/sdext/source/pdfimport/tree/pdfiprocessor.cxx @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -40,6 +41,10 @@ using namespace com::sun::star; +#include +#include + +#include namespace pdfi { @@ -530,11 +535,40 @@ void PDFIProcessor::intersectEoClip(const uno::Reference< rendering::XPolyPolygo void PDFIProcessor::intersectClipToStroke(const uno::Reference< rendering::XPolyPolygon2D >& rPath) { - // TODO! Expand the path to the outline of the stroked path // TODO(F3): interpret fill mode basegfx::B2DPolyPolygon aNewClip = basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(rPath); - aNewClip.transform(getCurrentContext().Transformation); - basegfx::B2DPolyPolygon aCurClip = getCurrentContext().Clip; + const GraphicsContext& rGC(getCurrentContext()); + aNewClip.transform(rGC.Transformation); + basegfx::B2DPolyPolygon aCurClip = rGC.Clip; + double nScale = GetAverageTransformationScale(rGC.Transformation); + + + // We need to get a path that corresponds to a 'stroked path' - i.e. with whatever line + // thickness etc is set. PolyPolygonStrokePrimitive2D::create2DDecomposition does most + // of the work. + const basegfx::BColor aBlack(0.0, 0.0, 0.0); + drawinglayer::attribute::LineAttribute aLineAttribute(aBlack, rGC.LineWidth * nScale /*, aJoin */); + rtl::Reference aStrokePrimitive( + new drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D(aNewClip, aLineAttribute)); + drawinglayer::primitive2d::Primitive2DContainer aPrimitiveContainer; + const drawinglayer::geometry::ViewInformation2D aViewInformation2D; + aStrokePrimitive->get2DDecomposition(aPrimitiveContainer, aViewInformation2D); + + // Based on extractLineContourFromPrimitive2DSequence and ImpConvertToContourObj + drawinglayer::processor2d::LineGeometryExtractor2D aExtractor(aViewInformation2D); + aExtractor.process(aPrimitiveContainer); + + basegfx::B2DPolygonVector aHairlines = aExtractor.getExtractedHairlines(); + auto aFills = aExtractor.getExtractedLineFills(); + + basegfx::B2DPolyPolygon aTmpClip = basegfx::utils::mergeToSinglePolyPolygon(std::move(aFills)); + + for (const basegfx::B2DPolygon & rExtractedHairline : aHairlines) + { + aTmpClip.append(rExtractedHairline); + } + + aNewClip = aTmpClip; if( aCurClip.count() ) // #i92985# adapted API from (..., false, false) to (..., true, false) aNewClip = basegfx::utils::clipPolyPolygonOnPolyPolygon( aCurClip, aNewClip, true, false );