From 3b9797671ce49f53b2c583c9201c348b55b10c96 Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Tue, 21 Jan 2020 16:55:08 +0100 Subject: PDF export: don't ignore FilterData specified by UNO clients The data was given to the PDF filter, but then we stopped iterating right after finding our output stream. Seems this was always like this, ever since commit 4111b430a0a7954416ff95794a8ffb8fbc4472e3 (#101570#: added pdf filter, 2002-08-13). Change-Id: If26661935c22a7b7959fda5f92b4d50b15f13a35 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/87152 Reviewed-by: Miklos Vajna Tested-by: Jenkins --- filter/source/pdf/pdffilter.cxx | 2 +- vcl/qa/cppunit/pdfexport/data/reduce-image.fodt | 29 ++++++++++++ vcl/qa/cppunit/pdfexport/pdfexport.cxx | 61 +++++++++++++++++++++++++ 3 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 vcl/qa/cppunit/pdfexport/data/reduce-image.fodt diff --git a/filter/source/pdf/pdffilter.cxx b/filter/source/pdf/pdffilter.cxx index 5a7e5fbaedf0..1bb919805b79 100644 --- a/filter/source/pdf/pdffilter.cxx +++ b/filter/source/pdf/pdffilter.cxx @@ -55,7 +55,7 @@ bool PDFFilter::implExport( const Sequence< PropertyValue >& rDescriptor ) Reference< task::XStatusIndicator > xStatusIndicator; Reference< task::XInteractionHandler > xIH; - for (sal_Int32 i = 0 ; ( i < nLength ) && !xOStm.is(); ++i) + for (sal_Int32 i = 0; i < nLength; ++i) { if ( pValue[ i ].Name == "OutputStream" ) pValue[ i ].Value >>= xOStm; diff --git a/vcl/qa/cppunit/pdfexport/data/reduce-image.fodt b/vcl/qa/cppunit/pdfexport/data/reduce-image.fodt new file mode 100644 index 000000000000..b5737ae27ec1 --- /dev/null +++ b/vcl/qa/cppunit/pdfexport/data/reduce-image.fodt @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + iVBORw0KGgoAAAANSUhEUgAAAKAAAACgCAYAAACLz2ctAAAABmJLR0QA/wD/AP+gvaeTAAAA + CXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH5AEVDCUTfvEVdAAAAYhJREFUeNrt3bEJwzAQ + htFckjLreP8Bso5bc2lTpBDG4kfkvQUE5uNUGEnV3TdIufsECBABggARIAgQAYIAESAIEAGC + ABEgCBABggARIAgQAYIAESAIEAGCABEgCBABggARIHx7phZ+vF9D13Id217WXW9dExBbMAgQ + AYIAESAIEAGCABEgCBABIkAQIAIEASJAECAChKnq6hfTR88gsKarz46YgNiCESAIEAGCABEg + CBABwlSx27FStzHxW+oPlgmILRgBggARIAgQAYIAESAIEAGCABEgCBABggARIAgQAYIAESAI + EAGCABEgCBABggARIAgQAYIAESACBAEiQBAgAgQBIkAQIAIEASJAECACBAEiQBAgi4u9mJ56 + oRsTEASIAEGACBABggARIAiQP1LdmR8So39Cjm0v6663rgmILRgEiABBgAgQBIgAQYAIEASI + ABEgCBABggARIAgQAcJUsTMhYAIiQAQIAkSAIEAECAJEgCBABAgCRIAgQAQIAkSAIEAECKd9 + AEYENxB/sygQAAAAAElFTkSuQmCC + + + + diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx b/vcl/qa/cppunit/pdfexport/pdfexport.cxx index d3cdcce90ea4..c13b2ab80c09 100644 --- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx +++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx @@ -22,6 +22,9 @@ #include #include #include +#include +#include +#include #include #include @@ -37,6 +40,7 @@ #include #include #include +#include using namespace ::com::sun::star; @@ -138,6 +142,7 @@ public: void testTocLink(); void testPdfImageResourceInlineXObjectRef(); void testReduceSmallImage(); + void testReduceImage(); CPPUNIT_TEST_SUITE(PdfExportTest); CPPUNIT_TEST(testTdf106059); @@ -176,6 +181,7 @@ public: CPPUNIT_TEST(testTocLink); CPPUNIT_TEST(testPdfImageResourceInlineXObjectRef); CPPUNIT_TEST(testReduceSmallImage); + CPPUNIT_TEST(testReduceImage); CPPUNIT_TEST_SUITE_END(); }; @@ -1899,6 +1905,61 @@ void PdfExportTest::testReduceSmallImage() CPPUNIT_ASSERT_EQUAL(16, nHeight); } +void PdfExportTest::testReduceImage() +{ + // Load the Writer document. + OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "reduce-image.fodt"; + mxComponent = loadFromDesktop(aURL); + + // Save as PDF. + uno::Reference xFactory = getMultiServiceFactory(); + uno::Reference xFilter( + xFactory->createInstance("com.sun.star.document.PDFFilter"), uno::UNO_QUERY); + uno::Reference xExporter(xFilter, uno::UNO_QUERY); + xExporter->setSourceDocument(mxComponent); + + SvFileStream aOutputStream(maTempFile.GetURL(), StreamMode::WRITE); + uno::Reference xOutputStream(new utl::OStreamWrapper(aOutputStream)); + + uno::Sequence aFilterData( + comphelper::InitPropertySequence({ { "ReduceImageResolution", uno::Any(false) } })); + + // This is intentionally in an "unlucky" order, output stream comes before filter data. + uno::Sequence aDescriptor(comphelper::InitPropertySequence({ + { "FilterName", uno::Any(OUString("writer_pdf_Export")) }, + { "OutputStream", uno::Any(xOutputStream) }, + { "FilterData", uno::Any(aFilterData) }, + })); + xFilter->filter(aDescriptor); + aOutputStream.Close(); + + // Parse the PDF: get the image. + SvFileStream aFile(maTempFile.GetURL(), StreamMode::READ); + maMemory.WriteStream(aFile); + DocumentHolder pPdfDocument( + FPDF_LoadMemDocument(maMemory.GetData(), maMemory.GetSize(), /*password=*/nullptr)); + CPPUNIT_ASSERT(pPdfDocument.get()); + CPPUNIT_ASSERT_EQUAL(1, FPDF_GetPageCount(pPdfDocument.get())); + PageHolder pPdfPage(FPDF_LoadPage(pPdfDocument.get(), /*page_index=*/0)); + CPPUNIT_ASSERT(pPdfPage.get()); + CPPUNIT_ASSERT_EQUAL(1, FPDFPage_CountObjects(pPdfPage.get())); + FPDF_PAGEOBJECT pPageObject = FPDFPage_GetObject(pPdfPage.get(), 0); + CPPUNIT_ASSERT_EQUAL(FPDF_PAGEOBJ_IMAGE, FPDFPageObj_GetType(pPageObject)); + + // Make sure we don't scale down a bitmap. + FPDF_BITMAP pBitmap = FPDFImageObj_GetBitmap(pPageObject); + CPPUNIT_ASSERT(pBitmap); + int nWidth = FPDFBitmap_GetWidth(pBitmap); + int nHeight = FPDFBitmap_GetHeight(pBitmap); + FPDFBitmap_Destroy(pBitmap); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 160 + // - Actual : 6 + // i.e. the image was scaled down even with ReduceImageResolution=false. + CPPUNIT_ASSERT_EQUAL(160, nWidth); + CPPUNIT_ASSERT_EQUAL(160, nHeight); +} + void PdfExportTest::testPdfImageResourceInlineXObjectRef() { // Create an empty document. -- cgit