diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2017-04-05 17:31:47 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2017-04-05 20:05:14 +0000 |
commit | 4443d7be61a9ae45630183d856a566cecd06ad95 (patch) | |
tree | c59595e63f39e248db0037c4b22fd49b458ee9bd /vcl | |
parent | dbcb866e46b3f964deb77b62b52bec1bb2b009ea (diff) |
Related: tdf#106972 vcl PDF export, PDF images: ignore PDF >= 1.5
When copying their page steam into ours, we need to make sure their
syntax is <= 1.4; so when checking if the image has PDF data, ignore the
case when it has, but it's >= 1.5 (at least in the default case when not
using reference XObjects).
Change-Id: I6bd77803b92fe16bdd327e5e7c3d2b42adeacca4
Reviewed-on: https://gerrit.libreoffice.org/36161
Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
Tested-by: Jenkins <ci@libreoffice.org>
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/qa/cppunit/pdfexport/data/tdf106972-pdf17.odt | bin | 0 -> 21561 bytes | |||
-rw-r--r-- | vcl/qa/cppunit/pdfexport/pdfexport.cxx | 38 | ||||
-rw-r--r-- | vcl/source/gdi/pdfwriter_impl.cxx | 30 |
3 files changed, 66 insertions, 2 deletions
diff --git a/vcl/qa/cppunit/pdfexport/data/tdf106972-pdf17.odt b/vcl/qa/cppunit/pdfexport/data/tdf106972-pdf17.odt Binary files differnew file mode 100644 index 000000000000..d46c93dffb5f --- /dev/null +++ b/vcl/qa/cppunit/pdfexport/data/tdf106972-pdf17.odt diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx b/vcl/qa/cppunit/pdfexport/pdfexport.cxx index 2bbb9f3c9f01..566495f38edf 100644 --- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx +++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx @@ -50,6 +50,7 @@ public: /// Tests export of PDF images without reference XObjects. void testTdf106693(); void testTdf106972(); + void testTdf106972Pdf17(); #endif CPPUNIT_TEST_SUITE(PdfExportTest); @@ -60,6 +61,7 @@ public: CPPUNIT_TEST(testTdf106206); CPPUNIT_TEST(testTdf106693); CPPUNIT_TEST(testTdf106972); + CPPUNIT_TEST(testTdf106972Pdf17); #endif CPPUNIT_TEST_SUITE_END(); }; @@ -365,6 +367,42 @@ void PdfExportTest::testTdf106972() // This failed: the PDF image had no Font resource. CPPUNIT_ASSERT(pImageResources->LookupElement("Font")); } + +void PdfExportTest::testTdf106972Pdf17() +{ + // Import the bugdoc and export as PDF. + OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf106972-pdf17.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)); + + // Get access to the only image on the only page. + std::vector<vcl::filter::PDFObjectElement*> aPages = aDocument.GetPages(); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aPages.size()); + 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); + + // This failed, the "image" had resources; that typically means we tried to + // preserve the original PDF markup here; which is not OK till our default + // output is PDF 1.4, and this bugdoc has PDF 1.7 data. + CPPUNIT_ASSERT(!pXObject->Lookup("Resources")); +} #endif CPPUNIT_TEST_SUITE_REGISTRATION(PdfExportTest); diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx index 698fdab61d6b..490f5d3b4768 100644 --- a/vcl/source/gdi/pdfwriter_impl.cxx +++ b/vcl/source/gdi/pdfwriter_impl.cxx @@ -676,6 +676,32 @@ static void appendDestinationName( const OUString& rString, OStringBuffer& rBuff } } +/// Decide if rGraphic has PDF data that is possible to embed in our output. +static bool hasPdfData(const Graphic& rGraphic, bool bUseReferenceXObject) +{ + const css::uno::Sequence<sal_Int8>& rData = rGraphic.getPdfData(); + + if (rData.getLength() < 8) + return false; + + if (rData[0] != '%' || rData[1] != 'P' || rData[2] != 'D' || rData[3] != 'F' || rData[4] != '-') + // Unexpected header. + return false; + + if (bUseReferenceXObject) + // This is possible for all versions. + return true; + + sal_Int32 nMajor = OString(rData[5]).toInt32(); + sal_Int32 nMinor = OString(rData[7]).toInt32(); + + if (nMajor > 1 || (nMajor == 1 && nMinor > 4)) + // This is PDF-1.5 or newer, can't embed into PDF-1.4. + return false; + + return true; +} + void PDFWriter::AppendUnicodeTextString(const OUString& rString, OStringBuffer& rBuffer) { rBuffer.append( "FEFF" ); @@ -11574,7 +11600,7 @@ void PDFWriterImpl::createEmbeddedFile(const Graphic& rGraphic, ReferenceXObject // no pdf data. rEmit.m_nBitmapObject = nBitmapObject; - if (!rGraphic.getPdfData().hasElements()) + if (!hasPdfData(rGraphic, m_aContext.UseReferenceXObject)) return; if (m_aContext.UseReferenceXObject) @@ -11754,7 +11780,7 @@ const PDFWriterImpl::BitmapEmit& PDFWriterImpl::createBitmapEmit( const BitmapEx m_aBitmaps.push_front( BitmapEmit() ); m_aBitmaps.front().m_aID = aID; m_aBitmaps.front().m_aBitmap = aBitmap; - if (!rGraphic.getPdfData().hasElements() || m_aContext.UseReferenceXObject) + if (!hasPdfData(rGraphic, m_aContext.UseReferenceXObject) || m_aContext.UseReferenceXObject) m_aBitmaps.front().m_nObject = createObject(); createEmbeddedFile(rGraphic, m_aBitmaps.front().m_aReferenceXObject, m_aBitmaps.front().m_nObject); it = m_aBitmaps.begin(); |