take into account clipping for pdf graphics
at least for graphics that are entirely clipped out. Change-Id: I2e8b15209a8a0e2e6777601b8d853ad323e5828e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/193116 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
This commit is contained in:
Binary file not shown.
@@ -1185,6 +1185,36 @@ CPPUNIT_TEST_FIXTURE(SdExportTest, testExplodedPdfGrayscaleImageUnderInvisibleTe
|
||||
CPPUNIT_ASSERT_MESSAGE("Shape should be Invisible", !bVisible);
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(SdExportTest, testExplodedPdfClippedImages)
|
||||
{
|
||||
auto pPdfium = vcl::pdf::PDFiumLibrary::get();
|
||||
if (!pPdfium)
|
||||
return;
|
||||
UsePdfium aGuard;
|
||||
|
||||
loadFromFile(u"pdf/ClippedImages.pdf");
|
||||
|
||||
setFilterOptions("{\"DecomposePDF\":{\"type\":\"boolean\",\"value\":\"true\"}}");
|
||||
setImportFilterName(u"OpenDocument Drawing Flat XML"_ustr);
|
||||
saveAndReload(u"OpenDocument Drawing Flat XML"_ustr);
|
||||
|
||||
uno::Reference<drawing::XShapes> xGroupShape(getShapeFromPage(0, 0), uno::UNO_QUERY);
|
||||
CPPUNIT_ASSERT(xGroupShape.is());
|
||||
|
||||
uno::Reference<beans::XPropertySet> xGraphicShape1(xGroupShape->getByIndex(0), uno::UNO_QUERY);
|
||||
CPPUNIT_ASSERT(xGraphicShape1.is());
|
||||
bool bVisible(true);
|
||||
xGraphicShape1->getPropertyValue(u"Visible"_ustr) >>= bVisible;
|
||||
CPPUNIT_ASSERT_MESSAGE("1st Graphic should be Visible", bVisible);
|
||||
|
||||
// before the fix the clip for this graphic wasn't taken into account so it was visiblem
|
||||
// not it is detected as entirely clipped out and toggled to invisible
|
||||
uno::Reference<beans::XPropertySet> xGraphicShape2(xGroupShape->getByIndex(1), uno::UNO_QUERY);
|
||||
CPPUNIT_ASSERT(xGraphicShape2.is());
|
||||
xGraphicShape2->getPropertyValue(u"Visible"_ustr) >>= bVisible;
|
||||
CPPUNIT_ASSERT_MESSAGE("2nd Graphic should be Invisible", !bVisible);
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(SdExportTest, testExplodedPdfMissingFontVersion)
|
||||
{
|
||||
auto pPdfium = vcl::pdf::PDFiumLibrary::get();
|
||||
|
||||
@@ -162,6 +162,10 @@ class ImpSdrPdfImport final
|
||||
const std::vector<std::unique_ptr<vcl::pdf::PDFiumPathSegment>>& rPathSegments,
|
||||
const basegfx::B2DHomMatrix& rPathMatrix);
|
||||
|
||||
basegfx::B2DPolyPolygon GetClip(const std::unique_ptr<vcl::pdf::PDFiumClipPath>& rClipPath,
|
||||
const basegfx::B2DHomMatrix& rPathMatrix,
|
||||
const basegfx::B2DHomMatrix& rTransform);
|
||||
|
||||
// #i73407# reformulation to use new B2DPolygon classes
|
||||
bool CheckLastPolyLineAndFillMerge(const basegfx::B2DPolyPolygon& rPolyPolygon);
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <svdpdf.hxx>
|
||||
|
||||
#include <tools/UnitConversion.hxx>
|
||||
#include <vcl/canvastools.hxx>
|
||||
#include <vcl/embeddedfontsmanager.hxx>
|
||||
#include <vcl/graph.hxx>
|
||||
#include <vcl/vectorgraphicdata.hxx>
|
||||
@@ -55,6 +56,7 @@
|
||||
#include <svx/svdetc.hxx>
|
||||
#include <svl/itemset.hxx>
|
||||
#include <basegfx/polygon/b2dpolygon.hxx>
|
||||
#include <basegfx/polygon/b2dpolygontools.hxx>
|
||||
#include <tools/helpers.hxx>
|
||||
#include <basegfx/matrix/b2dhommatrix.hxx>
|
||||
#include <basegfx/matrix/b2dhommatrixtools.hxx>
|
||||
@@ -1950,6 +1952,29 @@ void ImpSdrPdfImport::MapScaling()
|
||||
mnMapScalingOfs = nCount;
|
||||
}
|
||||
|
||||
basegfx::B2DPolyPolygon
|
||||
ImpSdrPdfImport::GetClip(const std::unique_ptr<vcl::pdf::PDFiumClipPath>& pClipPath,
|
||||
const basegfx::B2DHomMatrix& rPathMatrix,
|
||||
const basegfx::B2DHomMatrix& rTransform)
|
||||
{
|
||||
basegfx::B2DPolyPolygon aClipPolyPoly;
|
||||
|
||||
int nClipPathCount = pClipPath->getPathCount();
|
||||
for (int i = 0; i < nClipPathCount; ++i)
|
||||
{
|
||||
std::vector<std::unique_ptr<vcl::pdf::PDFiumPathSegment>> aPathSegments;
|
||||
const int nSegments = pClipPath->getPathSegmentCount(i);
|
||||
for (int nSegmentIndex = 0; nSegmentIndex < nSegments; ++nSegmentIndex)
|
||||
aPathSegments.push_back(pClipPath->getPathSegment(i, nSegmentIndex));
|
||||
|
||||
appendSegmentsToPolyPoly(aClipPolyPoly, aPathSegments, rPathMatrix);
|
||||
}
|
||||
|
||||
aClipPolyPoly.transform(rTransform);
|
||||
|
||||
return aClipPolyPoly;
|
||||
}
|
||||
|
||||
void ImpSdrPdfImport::ImportImage(std::unique_ptr<vcl::pdf::PDFiumPageObject> const& pPageObject,
|
||||
int /*nPageObjectIndex*/)
|
||||
{
|
||||
@@ -1974,6 +1999,34 @@ void ImpSdrPdfImport::ImportImage(std::unique_ptr<vcl::pdf::PDFiumPageObject> co
|
||||
float right = aBounds.getMaxX();
|
||||
// Upside down.
|
||||
float top = aBounds.getMaxY();
|
||||
|
||||
bool bEntirelyClippedOut = false;
|
||||
|
||||
auto aPathMatrix = pPageObject->getMatrix();
|
||||
|
||||
aPathMatrix *= maCurrentMatrix;
|
||||
|
||||
const basegfx::B2DHomMatrix aTransform(
|
||||
basegfx::utils::createScaleTranslateB2DHomMatrix(mfScaleX, mfScaleY, maOfs.X(), maOfs.Y()));
|
||||
|
||||
basegfx::B2DPolyPolygon aClipPolyPoly
|
||||
= GetClip(pPageObject->getClipPath(), aPathMatrix, aTransform);
|
||||
|
||||
if (aClipPolyPoly.count())
|
||||
{
|
||||
// Clip against ClipRegion, use same conversions and transformation on
|
||||
// the graphic bounds as were applied to the clipping polypolygon
|
||||
const tools::Rectangle aRect = PointsToLogic(aBounds.getMinX(), aBounds.getMaxX(),
|
||||
aBounds.getMinY(), aBounds.getMaxY());
|
||||
basegfx::B2DPolyPolygon aGraphicBounds(
|
||||
basegfx::utils::createPolygonFromRect(vcl::unotools::b2DRectangleFromRectangle(aRect)));
|
||||
aGraphicBounds.transform(aTransform);
|
||||
const basegfx::B2DPolyPolygon aClippedBounds(basegfx::utils::clipPolyPolygonOnPolyPolygon(
|
||||
aGraphicBounds, aClipPolyPoly, true, false));
|
||||
// completely clipped out
|
||||
bEntirelyClippedOut = aClippedBounds.getB2DRange().isEmpty();
|
||||
}
|
||||
|
||||
tools::Rectangle aRect = PointsToLogic(left, right, top, bottom);
|
||||
aRect.AdjustRight(1);
|
||||
aRect.AdjustBottom(1);
|
||||
@@ -1984,6 +2037,10 @@ void ImpSdrPdfImport::ImportImage(std::unique_ptr<vcl::pdf::PDFiumPageObject> co
|
||||
// This action is not creating line and fill, set directly, do not use SetAttributes(..)
|
||||
pGraf->SetMergedItem(XLineStyleItem(drawing::LineStyle_NONE));
|
||||
pGraf->SetMergedItem(XFillStyleItem(drawing::FillStyle_NONE));
|
||||
|
||||
if (bEntirelyClippedOut)
|
||||
pGraf->SetVisible(false);
|
||||
|
||||
InsertObj(pGraf.get());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user