diff options
-rw-r--r-- | include/vcl/pdfextoutdevdata.hxx | 4 | ||||
-rw-r--r-- | vcl/qa/cppunit/pdfexport/data/tdf109143.odt | bin | 0 -> 68155 bytes | |||
-rw-r--r-- | vcl/qa/cppunit/pdfexport/pdfexport.cxx | 42 | ||||
-rw-r--r-- | vcl/source/gdi/pdfextoutdevdata.cxx | 12 |
4 files changed, 54 insertions, 4 deletions
diff --git a/include/vcl/pdfextoutdevdata.hxx b/include/vcl/pdfextoutdevdata.hxx index e9a2ad04fb04..c260f8461fa7 100644 --- a/include/vcl/pdfextoutdevdata.hxx +++ b/include/vcl/pdfextoutdevdata.hxx @@ -183,7 +183,9 @@ public: const tools::Rectangle& rVisibleOutputRect ); /// Detect if stream is compressed enough to avoid de-compress / scale & re-compress - bool HasAdequateCompression( const Graphic &rGraphic ) const; + bool HasAdequateCompression( const Graphic &rGraphic, + const tools::Rectangle &rOutputRect, + const tools::Rectangle &rVisibleOutputRect ) const; //--->i56629 /** Create a new named destination to be used in a link to this document from another PDF document diff --git a/vcl/qa/cppunit/pdfexport/data/tdf109143.odt b/vcl/qa/cppunit/pdfexport/data/tdf109143.odt Binary files differnew file mode 100644 index 000000000000..7d9afa3789e5 --- /dev/null +++ b/vcl/qa/cppunit/pdfexport/data/tdf109143.odt diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx b/vcl/qa/cppunit/pdfexport/pdfexport.cxx index 1f527239dea7..62e1713a14cf 100644 --- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx +++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx @@ -85,6 +85,7 @@ public: void testTdf66597_3(); #endif #endif + void testTdf109143(); CPPUNIT_TEST_SUITE(PdfExportTest); #if HAVE_FEATURE_PDFIUM @@ -112,6 +113,7 @@ public: CPPUNIT_TEST(testTdf66597_3); #endif #endif + CPPUNIT_TEST(testTdf109143); CPPUNIT_TEST_SUITE_END(); }; @@ -436,6 +438,46 @@ void PdfExportTest::testTdf106206() CPPUNIT_ASSERT(bool(it == pEnd)); } +void PdfExportTest::testTdf109143() +{ + // Import the bugdoc and export as PDF. + OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf109143.odt"; + mxComponent = loadFromDesktop(aURL); + CPPUNIT_ASSERT(mxComponent.is()); + + uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY); + utl::TempFile aTempFile; + aTempFile.EnableKillingFile(); + utl::MediaDescriptor aMediaDescriptor; + aMediaDescriptor["FilterName"] <<= OUString("writer_pdf_Export"); + xStorable->storeToURL(aTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList()); + + // Parse the export result. + vcl::filter::PDFDocument aDocument; + SvFileStream aStream(aTempFile.GetURL(), StreamMode::READ); + CPPUNIT_ASSERT(aDocument.Read(aStream)); + + // The document has one page. + std::vector<vcl::filter::PDFObjectElement*> aPages = aDocument.GetPages(); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aPages.size()); + + // Get access to the only image on the only page. + vcl::filter::PDFObjectElement* pResources = aPages[0]->LookupObject("Resources"); + CPPUNIT_ASSERT(pResources); + auto pXObjects = dynamic_cast<vcl::filter::PDFDictionaryElement*>(pResources->Lookup("XObject")); + CPPUNIT_ASSERT(pXObjects); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pXObjects->GetItems().size()); + vcl::filter::PDFObjectElement* pXObject = pXObjects->LookupObject(pXObjects->GetItems().begin()->first); + CPPUNIT_ASSERT(pXObject); + + // Make sure it's re-compressed. + auto pLength = dynamic_cast<vcl::filter::PDFNumberElement*>(pXObject->Lookup("Length")); + int nLength = pLength->GetValue(); + // This failed: cropped TIFF-in-JPEG wasn't re-compressed, so crop was + // lost. Size was 59416, now is 11827. + CPPUNIT_ASSERT(nLength < 50000); +} + void PdfExportTest::testTdf106972() { // Import the bugdoc and export as PDF. diff --git a/vcl/source/gdi/pdfextoutdevdata.cxx b/vcl/source/gdi/pdfextoutdevdata.cxx index 013cca964441..2a7e7b1f0774 100644 --- a/vcl/source/gdi/pdfextoutdevdata.cxx +++ b/vcl/source/gdi/pdfextoutdevdata.cxx @@ -403,13 +403,13 @@ bool PageSyncData::PlaySyncPageAct( PDFWriter& rWriter, sal_uInt32& rCurGDIMtfAc GfxLinkType eType = rGraphic.GetGfxLink().GetType(); if ( eType == GfxLinkType::NativeJpg ) { - mbGroupIgnoreGDIMtfActions = rOutDevData.HasAdequateCompression(rGraphic); + mbGroupIgnoreGDIMtfActions = rOutDevData.HasAdequateCompression(rGraphic, mParaRects[0], mParaRects[1]); if ( !mbGroupIgnoreGDIMtfActions ) mCurrentGraphic = rGraphic; } else if ( eType == GfxLinkType::NativePng || eType == GfxLinkType::NativePdf ) { - if ( eType == GfxLinkType::NativePdf || rOutDevData.HasAdequateCompression(rGraphic) ) + if ( eType == GfxLinkType::NativePdf || rOutDevData.HasAdequateCompression(rGraphic, mParaRects[0], mParaRects[1]) ) mCurrentGraphic = rGraphic; } } @@ -799,13 +799,19 @@ void PDFExtOutDevData::EndGroup( const Graphic& rGraphic, } // Avoids expensive de-compression and re-compression of large images. -bool PDFExtOutDevData::HasAdequateCompression( const Graphic &rGraphic ) const +bool PDFExtOutDevData::HasAdequateCompression( const Graphic &rGraphic, + const tools::Rectangle & rOutputRect, + const tools::Rectangle & rVisibleOutputRect ) const { assert(rGraphic.IsGfxLink() && (rGraphic.GetGfxLink().GetType() == GfxLinkType::NativeJpg || rGraphic.GetGfxLink().GetType() == GfxLinkType::NativePng || rGraphic.GetGfxLink().GetType() == GfxLinkType::NativePdf)); + if (rOutputRect != rVisibleOutputRect) + // rOutputRect is the crop rectangle, re-compress cropped image. + return false; + if (rGraphic.GetGfxLink().GetDataSize() == 0) return false; |