[Libreoffice-commits] core.git: vcl/qa vcl/source

Miklos Vajna vmiklos at collabora.co.uk
Wed Apr 5 20:05:40 UTC 2017


 vcl/qa/cppunit/pdfexport/data/tdf106972-pdf17.odt |binary
 vcl/qa/cppunit/pdfexport/pdfexport.cxx            |   38 ++++++++++++++++++++++
 vcl/source/gdi/pdfwriter_impl.cxx                 |   30 ++++++++++++++++-
 3 files changed, 66 insertions(+), 2 deletions(-)

New commits:
commit 4443d7be61a9ae45630183d856a566cecd06ad95
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Wed Apr 5 17:31:47 2017 +0200

    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 at collabora.co.uk>
    Tested-by: Jenkins <ci at libreoffice.org>

diff --git a/vcl/qa/cppunit/pdfexport/data/tdf106972-pdf17.odt b/vcl/qa/cppunit/pdfexport/data/tdf106972-pdf17.odt
new file mode 100644
index 000000000000..d46c93dffb5f
Binary files /dev/null and b/vcl/qa/cppunit/pdfexport/data/tdf106972-pdf17.odt differ
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();


More information about the Libreoffice-commits mailing list