[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-5.3' - 31 commits - config_host/config_features.h.in config_host.mk.in configure.ac distro-configs/LibreOfficeCoverity.conf download.lst external/Module_external.mk external/pdfium include/vcl include/xmlsecurity Makefile.fetch RepositoryExternal.mk sd/qa sd/source svtools/qa svtools/source svx/qa svx/source sw/qa sw/source vcl/CppunitTest_vcl_pdfexport.mk vcl/CppunitTest_vcl_wmf_test.mk vcl/Library_vcl.mk vcl/Module_vcl.mk vcl/qa vcl/source writerfilter/source xmlsecurity/Executable_pdfverify.mk xmlsecurity/inc xmlsecurity/Module_xmlsecurity.mk xmlsecurity/qa xmlsecurity/source xmlsecurity/workben

Miklos Vajna vmiklos at collabora.co.uk
Tue Mar 14 12:51:10 UTC 2017


 Makefile.fetch                                            |    1 
 RepositoryExternal.mk                                     |   11 
 config_host.mk.in                                         |    1 
 config_host/config_features.h.in                          |    5 
 configure.ac                                              |   18 
 distro-configs/LibreOfficeCoverity.conf                   |    1 
 download.lst                                              |    1 
 external/Module_external.mk                               |    1 
 external/pdfium/Library_pdfium.mk                         |  636 ++++++
 external/pdfium/Makefile                                  |    7 
 external/pdfium/Module_pdfium.mk                          |   17 
 external/pdfium/README                                    |   14 
 external/pdfium/UnpackedTarball_pdfium.mk                 |   32 
 external/pdfium/macos.patch.1                             |   62 
 external/pdfium/msvc.patch.1                              | 1344 ++++++++++++++
 external/pdfium/visibility.patch.1                        |   30 
 include/vcl/pdfwriter.hxx                                 |    4 
 include/xmlsecurity/pdfio/pdfdocument.hxx                 |  328 +++
 include/xmlsecurity/xmlsecuritydllapi.h                   |   23 
 sd/qa/unit/data/odp/embedded-pdf.odp                      |binary
 sd/qa/unit/export-tests.cxx                               |    2 
 sd/source/ui/view/drviews2.cxx                            |    2 
 svtools/qa/unit/GraphicObjectTest.cxx                     |    2 
 svtools/qa/unit/data/pdf.odt                              |binary
 svtools/source/graphic/grfcache.cxx                       |    8 
 svx/qa/unit/xoutdev.cxx                                   |    2 
 svx/source/svdraw/svdograf.cxx                            |    4 
 sw/qa/extras/odfexport/data/embedded-pdf.odt              |binary
 sw/qa/extras/odfexport/odfexport.cxx                      |   22 
 sw/source/core/graphic/ndgrf.cxx                          |    4 
 vcl/CppunitTest_vcl_pdfexport.mk                          |   42 
 vcl/CppunitTest_vcl_wmf_test.mk                           |    1 
 vcl/Library_vcl.mk                                        |    1 
 vcl/Module_vcl.mk                                         |    1 
 vcl/qa/cppunit/pdfexport/data/tdf105093.odp               |binary
 vcl/qa/cppunit/pdfexport/data/tdf105461.odp               |binary
 vcl/qa/cppunit/pdfexport/data/tdf106059.odt               |binary
 vcl/qa/cppunit/pdfexport/data/tdf106206.odt               |binary
 vcl/qa/cppunit/pdfexport/pdfexport.cxx                    |  265 ++
 vcl/source/filter/graphicfilter.cxx                       |    2 
 vcl/source/filter/ipdf/pdfread.cxx                        |  161 -
 vcl/source/filter/ipdf/pdfread.hxx                        |    5 
 vcl/source/gdi/impgraph.cxx                               |   23 
 vcl/source/gdi/pdfextoutdevdata.cxx                       |   11 
 vcl/source/gdi/pdfwriter.cxx                              |    8 
 vcl/source/gdi/pdfwriter_impl.cxx                         |  159 +
 vcl/source/gdi/pdfwriter_impl.hxx                         |   60 
 vcl/source/gdi/pdfwriter_impl2.cxx                        |    4 
 writerfilter/source/rtftok/rtfdispatchflag.cxx            |    2 
 writerfilter/source/rtftok/rtfdocumentimpl.cxx            |    2 
 xmlsecurity/Executable_pdfverify.mk                       |    5 
 xmlsecurity/Module_xmlsecurity.mk                         |    2 
 xmlsecurity/inc/documentsignaturehelper.hxx               |    2 
 xmlsecurity/inc/documentsignaturemanager.hxx              |    2 
 xmlsecurity/inc/pdfio/pdfdocument.hxx                     |  250 --
 xmlsecurity/inc/pdfsignaturehelper.hxx                    |    2 
 xmlsecurity/inc/xmlsecuritydllapi.h                       |   23 
 xmlsecurity/inc/xmlsignaturehelper.hxx                    |    2 
 xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx             |    2 
 xmlsecurity/source/helper/ooxmlsecexporter.cxx            |    4 
 xmlsecurity/source/helper/pdfsignaturehelper.cxx          |    2 
 xmlsecurity/source/pdfio/pdfdocument.cxx                  |  199 --
 xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.cxx |    8 
 xmlsecurity/workben/pdfverify.cxx                         |  128 +
 64 files changed, 3424 insertions(+), 536 deletions(-)

New commits:
commit 86510945198fd7f7e4b54d2bca01f424a8b9ac64
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Thu Mar 2 08:58:31 2017 +0100

    tdf#106270 vcl PDF import: use BitmapWriteAccess::CopyScanline()
    
    This requires one function call / row only, cross-platform and works
    with OpenGL enabled as well.
    
    Change-Id: I12fd0f52a1a7e8e683b50071ded95f63fecc4d40
    Reviewed-on: https://gerrit.libreoffice.org/34774
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    Tested-by: Jenkins <ci at libreoffice.org>
    (cherry picked from commit f1d6f202e2b8ff555cedde6315685342325b16fc)

diff --git a/vcl/source/filter/ipdf/pdfread.cxx b/vcl/source/filter/ipdf/pdfread.cxx
index c855400..f11f55a 100644
--- a/vcl/source/filter/ipdf/pdfread.cxx
+++ b/vcl/source/filter/ipdf/pdfread.cxx
@@ -73,34 +73,19 @@ bool generatePreview(SvStream& rStream, Graphic& rGraphic)
     FPDF_RenderPageBitmap(pPdfBitmap, pPdfPage, /*start_x=*/0, /*start_y=*/0, nPageWidth, nPageHeight, /*rotate=*/0, /*flags=*/0);
 
     // Save the buffer as a bitmap.
-    Bitmap aBitmap(Size(nPageWidth, nPageHeight), 32);
+    Bitmap aBitmap(Size(nPageWidth, nPageHeight), 24);
     {
         Bitmap::ScopedWriteAccess pWriteAccess(aBitmap);
-        auto pPdfBuffer = static_cast<const char*>(FPDFBitmap_GetBuffer(pPdfBitmap));
-#ifndef MACOSX
-        std::memcpy(pWriteAccess->GetBuffer(), pPdfBuffer, nPageWidth * nPageHeight * 4);
-#else
-        // ARGB -> BGRA
+        auto pPdfBuffer = static_cast<ConstScanline>(FPDFBitmap_GetBuffer(pPdfBitmap));
         for (size_t nRow = 0; nRow < nPageHeight; ++nRow)
         {
             int nStride = FPDFBitmap_GetStride(pPdfBitmap);
-            const char* pPdfLine = pPdfBuffer + (nStride * nRow);
-            Scanline pRow = pWriteAccess->GetBuffer() + (nPageWidth * nRow * 4);
-            for (size_t nCol = 0; nCol < nPageWidth; ++nCol)
-            {
-                pRow[nCol * 4] = pPdfLine[(nCol * 4) + 3];
-                pRow[(nCol * 4) + 1] = pPdfLine[(nCol * 4) + 2];
-                pRow[(nCol * 4) + 2] = pPdfLine[(nCol * 4) + 1];
-                pRow[(nCol * 4) + 3] = pPdfLine[nCol * 4];
-            }
+            ConstScanline pPdfLine = pPdfBuffer + (nStride * nRow);
+            // pdfium byte order is BGRA.
+            pWriteAccess->CopyScanline(nRow, pPdfLine, ScanlineFormat::N32BitTcBgra, nStride);
         }
-#endif
     }
-    BitmapEx aBitmapEx(aBitmap);
-#if defined(WNT) || defined(MACOSX)
-    aBitmapEx.Mirror(BmpMirrorFlags::Vertical);
-#endif
-    rGraphic = aBitmapEx;
+    rGraphic = aBitmap;
 
     FPDFBitmap_Destroy(pPdfBitmap);
     FPDF_ClosePage(pPdfPage);
commit 65e22b5e821c9bbaf3febb3438c1a397c6bdb6ea
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Mon Feb 27 16:38:54 2017 +0100

    tdf#106206 PDF export: fix unexpected /Im0 in page contents stream
    
    The early return should just skip the code that's specific to pdf
    images, not everything.
    
    Change-Id: Ia9e02b05051a085a9fdf2f690c21f9ffccb7bf4d
    Reviewed-on: https://gerrit.libreoffice.org/34685
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    Tested-by: Jenkins <ci at libreoffice.org>
    (cherry picked from commit e7adffff8039175bc50b56b4c07ce0b9d8fed629)

diff --git a/vcl/qa/cppunit/pdfexport/data/tdf106206.odt b/vcl/qa/cppunit/pdfexport/data/tdf106206.odt
new file mode 100644
index 0000000..3581157
Binary files /dev/null and b/vcl/qa/cppunit/pdfexport/data/tdf106206.odt differ
diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
index af6e86b..edd63e6 100644
--- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx
+++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
@@ -44,6 +44,8 @@ public:
     void testTdf105461();
     /// Tests that embedded video from Impress is not exported as a linked one.
     void testTdf105093();
+    /// Tests export of non-PDF images.
+    void testTdf106206();
 #endif
 
     CPPUNIT_TEST_SUITE(PdfExportTest);
@@ -51,6 +53,7 @@ public:
     CPPUNIT_TEST(testTdf106059);
     CPPUNIT_TEST(testTdf105461);
     CPPUNIT_TEST(testTdf105093);
+    CPPUNIT_TEST(testTdf106206);
 #endif
     CPPUNIT_TEST_SUITE_END();
 };
@@ -200,6 +203,57 @@ void PdfExportTest::testTdf105093()
     // This key was missing, the embedded video was handled as a linked one.
     CPPUNIT_ASSERT(pFileSpec->LookupElement("EF"));
 }
+
+void PdfExportTest::testTdf106206()
+{
+    // Import the bugdoc and export as PDF.
+    OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf106206.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.
+    xmlsecurity::pdfio::PDFDocument aDocument;
+    SvFileStream aStream(aTempFile.GetURL(), StreamMode::READ);
+    CPPUNIT_ASSERT(aDocument.Read(aStream));
+
+    // The document has one page.
+    std::vector<xmlsecurity::pdfio::PDFObjectElement*> aPages = aDocument.GetPages();
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aPages.size());
+
+    // The page has a stream.
+    xmlsecurity::pdfio::PDFObjectElement* pContents = aPages[0]->LookupObject("Contents");
+    CPPUNIT_ASSERT(pContents);
+    xmlsecurity::pdfio::PDFStreamElement* pStream = pContents->GetStream();
+    CPPUNIT_ASSERT(pStream);
+    SvMemoryStream& rObjectStream = pStream->GetMemory();
+    // Uncompress it.
+    SvMemoryStream aUncompressed;
+    ZCodec aZCodec;
+    aZCodec.BeginCompression();
+    rObjectStream.Seek(0);
+    aZCodec.Decompress(rObjectStream, aUncompressed);
+    CPPUNIT_ASSERT(aZCodec.EndCompression());
+
+    // Make sure there is an image reference there.
+    OString aImage("/Im");
+    auto pStart = static_cast<const char*>(aUncompressed.GetData());
+    const char* pEnd = pStart + aUncompressed.GetSize();
+    auto it = std::search(pStart, pEnd, aImage.getStr(), aImage.getStr() + aImage.getLength());
+    CPPUNIT_ASSERT(it != pEnd);
+
+    // And also that it's not an invalid one.
+    OString aInvalidImage("/Im0");
+    it = std::search(pStart, pEnd, aInvalidImage.getStr(), aInvalidImage.getStr() + aInvalidImage.getLength());
+    // This failed, object #0 was referenced.
+    CPPUNIT_ASSERT(bool(it == pEnd));
+}
 #endif
 
 CPPUNIT_TEST_SUITE_REGISTRATION(PdfExportTest);
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index 69cd2e7..b5b371e 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -12077,6 +12077,10 @@ bool PDFWriterImpl::writeBitmapObject( BitmapEmit& rObject, bool bMask )
 
 void PDFWriterImpl::createEmbeddedFile(const Graphic& rGraphic, ReferenceXObjectEmit& rEmit, sal_Int32 nBitmapObject)
 {
+    // The bitmap object is always a valid identifier, even if the graphic has
+    // no pdf data.
+    rEmit.m_nBitmapObject = nBitmapObject;
+
     if (!rGraphic.getPdfData().hasElements())
         return;
 
@@ -12087,7 +12091,6 @@ void PDFWriterImpl::createEmbeddedFile(const Graphic& rGraphic, ReferenceXObject
 
     rEmit.m_nFormObject = createObject();
     rEmit.m_nEmbeddedObject = m_aEmbeddedFiles.back().m_nObject;
-    rEmit.m_nBitmapObject = nBitmapObject;
     rEmit.m_aPixelSize = rGraphic.GetBitmap().GetPrefSize();
 }
 
commit 2ffc2672afff20a8c32cbfe7518923c739346a59
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Mon Feb 27 14:29:03 2017 +0100

    tdf#105093 vcl PDF export: add embedded video testcase
    
    Fails with commit 4ad249af88d15f2c8a09f0721a59d82718fcc201 (tdf#105093
    sd PDF export: handle embedded videos, 2017-01-04) reverted.
    
    Change-Id: I413ec9a5da3c0783541dcd28fb9a62dd896f955b
    Reviewed-on: https://gerrit.libreoffice.org/34681
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    Tested-by: Jenkins <ci at libreoffice.org>
    (cherry picked from commit 64bac5c0f005afd46bbf402c5d548e2ee6c9e5c4)

diff --git a/include/xmlsecurity/pdfio/pdfdocument.hxx b/include/xmlsecurity/pdfio/pdfdocument.hxx
index 1267505..8b90dfd 100644
--- a/include/xmlsecurity/pdfio/pdfdocument.hxx
+++ b/include/xmlsecurity/pdfio/pdfdocument.hxx
@@ -90,6 +90,37 @@ public:
     void SetStreamBuffer(std::unique_ptr<SvMemoryStream>& pStreamBuffer);
 };
 
+/// Array object: a list.
+class XMLSECURITY_DLLPUBLIC PDFArrayElement : public PDFElement
+{
+    /// Location after the '[' token.
+    sal_uInt64 m_nOffset = 0;
+    std::vector<PDFElement*> m_aElements;
+public:
+    PDFArrayElement();
+    bool Read(SvStream& rStream) override;
+    void PushBack(PDFElement* pElement);
+    const std::vector<PDFElement*>& GetElements();
+};
+
+/// Reference object: something with a unique ID.
+class XMLSECURITY_DLLPUBLIC PDFReferenceElement : public PDFElement
+{
+    PDFDocument& m_rDoc;
+    int m_fObjectValue;
+    int m_fGenerationValue;
+
+public:
+    PDFReferenceElement(PDFDocument& rDoc, int fObjectValue, int fGenerationValue);
+    bool Read(SvStream& rStream) override;
+    /// Assuming the reference points to a number object, return its value.
+    double LookupNumber(SvStream& rStream) const;
+    /// Lookup referenced object, without assuming anything about its contents.
+    PDFObjectElement* LookupObject();
+    int GetObjectValue() const;
+    int GetGenerationValue() const;
+};
+
 /// Stream object: a byte array with a known length.
 class XMLSECURITY_DLLPUBLIC PDFStreamElement : public PDFElement
 {
@@ -146,6 +177,8 @@ public:
     const std::map<OString, PDFElement*>& GetItems() const;
     /// Looks up an object which is only referenced in this dictionary.
     PDFObjectElement* LookupObject(const OString& rDictionaryKey);
+    /// Looks up an element which is contained in this dictionary.
+    PDFElement* LookupElement(const OString& rDictionaryKey);
 };
 
 enum class TokenizeMode
diff --git a/vcl/qa/cppunit/pdfexport/data/tdf105093.odp b/vcl/qa/cppunit/pdfexport/data/tdf105093.odp
new file mode 100644
index 0000000..82ce29c
Binary files /dev/null and b/vcl/qa/cppunit/pdfexport/data/tdf105093.odp differ
diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
index 1c665b8..af6e86b 100644
--- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx
+++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
@@ -42,12 +42,15 @@ public:
     void testTdf106059();
     /// Tests that text highlight from Impress is not lost.
     void testTdf105461();
+    /// Tests that embedded video from Impress is not exported as a linked one.
+    void testTdf105093();
 #endif
 
     CPPUNIT_TEST_SUITE(PdfExportTest);
 #if HAVE_FEATURE_PDFIUM
     CPPUNIT_TEST(testTdf106059);
     CPPUNIT_TEST(testTdf105461);
+    CPPUNIT_TEST(testTdf105093);
 #endif
     CPPUNIT_TEST_SUITE_END();
 };
@@ -150,6 +153,53 @@ void PdfExportTest::testTdf105461()
     // This failed, stream contained no filled rectangle.
     CPPUNIT_ASSERT(it != pEnd);
 }
+
+void PdfExportTest::testTdf105093()
+{
+    // Import the bugdoc and export as PDF.
+    OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf105093.odp";
+    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("impress_pdf_Export");
+    xStorable->storeToURL(aTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList());
+
+    // Parse the export result.
+    xmlsecurity::pdfio::PDFDocument aDocument;
+    SvFileStream aStream(aTempFile.GetURL(), StreamMode::READ);
+    CPPUNIT_ASSERT(aDocument.Read(aStream));
+
+    // The document has one page.
+    std::vector<xmlsecurity::pdfio::PDFObjectElement*> aPages = aDocument.GetPages();
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aPages.size());
+
+    // Get page annotations.
+    auto pAnnots = dynamic_cast<xmlsecurity::pdfio::PDFArrayElement*>(aPages[0]->Lookup("Annots"));
+    CPPUNIT_ASSERT(pAnnots);
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pAnnots->GetElements().size());
+    auto pAnnotReference = dynamic_cast<xmlsecurity::pdfio::PDFReferenceElement*>(pAnnots->GetElements()[0]);
+    CPPUNIT_ASSERT(pAnnotReference);
+    xmlsecurity::pdfio::PDFObjectElement* pAnnot = pAnnotReference->LookupObject();
+    CPPUNIT_ASSERT(pAnnot);
+    CPPUNIT_ASSERT_EQUAL(OString("Annot"), static_cast<xmlsecurity::pdfio::PDFNameElement*>(pAnnot->Lookup("Type"))->GetValue());
+
+    // Get the Action -> Rendition -> MediaClip -> FileSpec.
+    auto pAction = dynamic_cast<xmlsecurity::pdfio::PDFDictionaryElement*>(pAnnot->Lookup("A"));
+    CPPUNIT_ASSERT(pAction);
+    auto pRendition = dynamic_cast<xmlsecurity::pdfio::PDFDictionaryElement*>(pAction->LookupElement("R"));
+    CPPUNIT_ASSERT(pRendition);
+    auto pMediaClip = dynamic_cast<xmlsecurity::pdfio::PDFDictionaryElement*>(pRendition->LookupElement("C"));
+    CPPUNIT_ASSERT(pMediaClip);
+    auto pFileSpec = dynamic_cast<xmlsecurity::pdfio::PDFDictionaryElement*>(pMediaClip->LookupElement("D"));
+    CPPUNIT_ASSERT(pFileSpec);
+    // Make sure the filespec refers to an embedded file.
+    // This key was missing, the embedded video was handled as a linked one.
+    CPPUNIT_ASSERT(pFileSpec->LookupElement("EF"));
+}
 #endif
 
 CPPUNIT_TEST_SUITE_REGISTRATION(PdfExportTest);
diff --git a/xmlsecurity/source/pdfio/pdfdocument.cxx b/xmlsecurity/source/pdfio/pdfdocument.cxx
index 6ffe711..5dd2f0a 100644
--- a/xmlsecurity/source/pdfio/pdfdocument.cxx
+++ b/xmlsecurity/source/pdfio/pdfdocument.cxx
@@ -100,24 +100,6 @@ public:
     sal_uInt64 GetLocation() const;
 };
 
-/// Reference object: something with a unique ID.
-class PDFReferenceElement : public PDFElement
-{
-    PDFDocument& m_rDoc;
-    int m_fObjectValue;
-    int m_fGenerationValue;
-
-public:
-    PDFReferenceElement(PDFDocument& rDoc, int fObjectValue, int fGenerationValue);
-    bool Read(SvStream& rStream) override;
-    /// Assuming the reference points to a number object, return its value.
-    double LookupNumber(SvStream& rStream) const;
-    /// Lookup referenced object, without assuming anything about its contents.
-    PDFObjectElement* LookupObject();
-    int GetObjectValue() const;
-    int GetGenerationValue() const;
-};
-
 /// End of a stream: 'endstream' keyword.
 class PDFEndStreamElement : public PDFElement
 {
@@ -132,19 +114,6 @@ public:
     bool Read(SvStream& rStream) override;
 };
 
-/// Array object: a list.
-class PDFArrayElement : public PDFElement
-{
-    /// Location after the '[' token.
-    sal_uInt64 m_nOffset = 0;
-    std::vector<PDFElement*> m_aElements;
-public:
-    PDFArrayElement();
-    bool Read(SvStream& rStream) override;
-    void PushBack(PDFElement* pElement);
-    const std::vector<PDFElement*>& GetElements();
-};
-
 /// End of an array: ']'.
 class PDFEndArrayElement : public PDFElement
 {
@@ -3159,6 +3128,11 @@ PDFObjectElement* PDFDictionaryElement::LookupObject(const OString& rDictionaryK
     return pKey->LookupObject();
 }
 
+PDFElement* PDFDictionaryElement::LookupElement(const OString& rDictionaryKey)
+{
+    return PDFDictionaryElement::Lookup(m_aItems, rDictionaryKey);
+}
+
 PDFElement* PDFObjectElement::Lookup(const OString& rDictionaryKey)
 {
     if (m_aDictionary.empty())
commit fe8b2a1e72d99ea3f2604dafaf247ac1dd7c68b4
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Mon Feb 27 12:31:07 2017 +0100

    xmlsecurity PDF verify: fix parsing of nested dictionaries
    
    This is triggered by an upcoming unit test for tdf#105093.
    
    Change-Id: I3c8e8662fcadaea1f6e19bf6194d8159916f368b
    Reviewed-on: https://gerrit.libreoffice.org/34678
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    Tested-by: Jenkins <ci at libreoffice.org>
    (cherry picked from commit a9a9b8155f65421fa8cb2bf108b847f212462f4f)

diff --git a/xmlsecurity/source/pdfio/pdfdocument.cxx b/xmlsecurity/source/pdfio/pdfdocument.cxx
index 5017448..6ffe711 100644
--- a/xmlsecurity/source/pdfio/pdfdocument.cxx
+++ b/xmlsecurity/source/pdfio/pdfdocument.cxx
@@ -2974,7 +2974,7 @@ size_t PDFDictionaryElement::Parse(const std::vector< std::unique_ptr<PDFElement
             else
             {
                 // Nested dictionary.
-                nIndex = PDFDictionaryElement::Parse(rElements, pDictionary, pDictionary->m_aItems);
+                i = PDFDictionaryElement::Parse(rElements, pDictionary, pDictionary->m_aItems);
                 rDictionary[aName] = pDictionary;
                 aName.clear();
             }
@@ -2987,7 +2987,7 @@ size_t PDFDictionaryElement::Parse(const std::vector< std::unique_ptr<PDFElement
                 // Last dictionary end, track length and stop parsing.
                 if (pThisObject)
                     pThisObject->SetDictionaryLength(pEndDictionary->GetLocation() - nDictionaryOffset);
-                nRet = nIndex;
+                nRet = i;
                 break;
             }
         }
commit 42847e040b902266324d677c7369f71e8c8f6346
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Fri Feb 24 17:14:23 2017 +0100

    tdf#105461 vcl: add text highlight textcase
    
    Fails with commit ee32c7d8083ae1449d6b379034be92995c142da9 (tdf#105461
    PDF export: handle text fill color, 2017-02-01) reverted.
    
    Change-Id: I3628a16d0810e3be3fb352340d06cdba472dcd3f
    Reviewed-on: https://gerrit.libreoffice.org/34621
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    Tested-by: Jenkins <ci at libreoffice.org>
    (cherry picked from commit 4e203ca3915e0cee2e7e02b95e78b3f5a8870098)

diff --git a/include/xmlsecurity/pdfio/pdfdocument.hxx b/include/xmlsecurity/pdfio/pdfdocument.hxx
index 1aefb6c..1267505 100644
--- a/include/xmlsecurity/pdfio/pdfdocument.hxx
+++ b/include/xmlsecurity/pdfio/pdfdocument.hxx
@@ -80,6 +80,8 @@ public:
     void SetDictionary(PDFDictionaryElement* pDictionaryElement);
     void SetArray(PDFArrayElement* pArrayElement);
     void SetStream(PDFStreamElement* pStreamElement);
+    /// Access to the stream of the object, if it has any.
+    PDFStreamElement* GetStream() const;
     PDFArrayElement* GetArray() const;
     /// Parse objects stored in this object stream.
     void ParseStoredObjects();
@@ -88,6 +90,21 @@ public:
     void SetStreamBuffer(std::unique_ptr<SvMemoryStream>& pStreamBuffer);
 };
 
+/// Stream object: a byte array with a known length.
+class XMLSECURITY_DLLPUBLIC PDFStreamElement : public PDFElement
+{
+    size_t m_nLength;
+    sal_uInt64 m_nOffset;
+    /// The byte array itself.
+    SvMemoryStream m_aMemory;
+
+public:
+    explicit PDFStreamElement(size_t nLength);
+    bool Read(SvStream& rStream) override;
+    sal_uInt64 GetOffset() const;
+    SvMemoryStream& GetMemory();
+};
+
 /// Name object: a key string.
 class XMLSECURITY_DLLPUBLIC PDFNameElement : public PDFElement
 {
diff --git a/vcl/qa/cppunit/pdfexport/data/tdf105461.odp b/vcl/qa/cppunit/pdfexport/data/tdf105461.odp
new file mode 100644
index 0000000..9c86a3b
Binary files /dev/null and b/vcl/qa/cppunit/pdfexport/data/tdf105461.odp differ
diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
index 949ef61..1c665b8 100644
--- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx
+++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
@@ -19,6 +19,7 @@
 #include <unotools/mediadescriptor.hxx>
 #include <unotools/tempfile.hxx>
 #include <xmlsecurity/pdfio/pdfdocument.hxx>
+#include <tools/zcodec.hxx>
 
 using namespace ::com::sun::star;
 
@@ -39,11 +40,14 @@ public:
 #if HAVE_FEATURE_PDFIUM
     /// Tests that a pdf image is roundtripped back to PDF as a vector format.
     void testTdf106059();
+    /// Tests that text highlight from Impress is not lost.
+    void testTdf105461();
 #endif
 
     CPPUNIT_TEST_SUITE(PdfExportTest);
 #if HAVE_FEATURE_PDFIUM
     CPPUNIT_TEST(testTdf106059);
+    CPPUNIT_TEST(testTdf105461);
 #endif
     CPPUNIT_TEST_SUITE_END();
 };
@@ -100,6 +104,52 @@ void PdfExportTest::testTdf106059()
     // This dictionary key was missing, so the XObject wasn't a reference one.
     CPPUNIT_ASSERT(pReferenceXObject->Lookup("Ref"));
 }
+
+void PdfExportTest::testTdf105461()
+{
+    // Import the bugdoc and export as PDF.
+    OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf105461.odp";
+    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("impress_pdf_Export");
+    xStorable->storeToURL(aTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList());
+
+    // Parse the export result.
+    xmlsecurity::pdfio::PDFDocument aDocument;
+    SvFileStream aStream(aTempFile.GetURL(), StreamMode::READ);
+    CPPUNIT_ASSERT(aDocument.Read(aStream));
+
+    // The document has one page.
+    std::vector<xmlsecurity::pdfio::PDFObjectElement*> aPages = aDocument.GetPages();
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aPages.size());
+
+    // The page has a stream.
+    xmlsecurity::pdfio::PDFObjectElement* pContents = aPages[0]->LookupObject("Contents");
+    CPPUNIT_ASSERT(pContents);
+    xmlsecurity::pdfio::PDFStreamElement* pStream = pContents->GetStream();
+    CPPUNIT_ASSERT(pStream);
+    SvMemoryStream& rObjectStream = pStream->GetMemory();
+    // Uncompress it.
+    SvMemoryStream aUncompressed;
+    ZCodec aZCodec;
+    aZCodec.BeginCompression();
+    rObjectStream.Seek(0);
+    aZCodec.Decompress(rObjectStream, aUncompressed);
+    CPPUNIT_ASSERT(aZCodec.EndCompression());
+
+    // Make sure there is a filled rectangle inside.
+    OString aFilledRectangle("re f*");
+    auto pStart = static_cast<const char*>(aUncompressed.GetData());
+    const char* pEnd = pStart + aUncompressed.GetSize();
+    auto it = std::search(pStart, pEnd, aFilledRectangle.getStr(), aFilledRectangle.getStr() + aFilledRectangle.getLength());
+    // This failed, stream contained no filled rectangle.
+    CPPUNIT_ASSERT(it != pEnd);
+}
 #endif
 
 CPPUNIT_TEST_SUITE_REGISTRATION(PdfExportTest);
diff --git a/xmlsecurity/source/pdfio/pdfdocument.cxx b/xmlsecurity/source/pdfio/pdfdocument.cxx
index 50e00d7..5017448 100644
--- a/xmlsecurity/source/pdfio/pdfdocument.cxx
+++ b/xmlsecurity/source/pdfio/pdfdocument.cxx
@@ -118,18 +118,6 @@ public:
     int GetGenerationValue() const;
 };
 
-/// Stream object: a byte array with a known length.
-class PDFStreamElement : public PDFElement
-{
-    size_t m_nLength;
-    sal_uInt64 m_nOffset;
-
-public:
-    explicit PDFStreamElement(size_t nLength);
-    bool Read(SvStream& rStream) override;
-    sal_uInt64 GetOffset() const;
-};
-
 /// End of a stream: 'endstream' keyword.
 class PDFEndStreamElement : public PDFElement
 {
@@ -3282,6 +3270,11 @@ void PDFObjectElement::SetStream(PDFStreamElement* pStreamElement)
     m_pStreamElement = pStreamElement;
 }
 
+PDFStreamElement* PDFObjectElement::GetStream() const
+{
+    return m_pStreamElement;
+}
+
 PDFArrayElement* PDFObjectElement::GetArray() const
 {
     return m_pArrayElement;
@@ -3668,11 +3661,18 @@ bool PDFStreamElement::Read(SvStream& rStream)
 {
     SAL_INFO("xmlsecurity.pdfio", "PDFStreamElement::Read: length is " << m_nLength);
     m_nOffset = rStream.Tell();
-    rStream.SeekRel(m_nLength);
+    std::vector<unsigned char> aBytes(m_nLength);
+    rStream.ReadBytes(aBytes.data(), aBytes.size());
+    m_aMemory.WriteBytes(aBytes.data(), aBytes.size());
 
     return rStream.good();
 }
 
+SvMemoryStream& PDFStreamElement::GetMemory()
+{
+    return m_aMemory;
+}
+
 sal_uInt64 PDFStreamElement::GetOffset() const
 {
     return m_nOffset;
commit bcf71c2c604a555364d2c6cc94e0b8cc6dc52553
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Sat Feb 25 17:06:31 2017 +0100

    the test implicitly requires pdfium
    
    Attempt to fix build issue found by "RandomCondig" tb build #244
    
    Change-Id: I8b6a0a3d0f812a3220fb0d7d21318871454f7eca
    Reviewed-on: https://gerrit.libreoffice.org/34646
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Markus Mohrhard <markus.mohrhard at googlemail.com>
    (cherry picked from commit 89b64e865bfb6739be07d1fb0b5dfa5fa3651a44)

diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
index bcc3345..949ef61 100644
--- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx
+++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
@@ -7,6 +7,8 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
+#include <config_features.h>
+
 #include <com/sun/star/frame/Desktop.hpp>
 #include <com/sun/star/frame/XStorable.hpp>
 
@@ -34,11 +36,15 @@ class PdfExportTest : public test::BootstrapFixture, public unotest::MacrosTest
 public:
     virtual void setUp() override;
     virtual void tearDown() override;
+#if HAVE_FEATURE_PDFIUM
     /// Tests that a pdf image is roundtripped back to PDF as a vector format.
     void testTdf106059();
+#endif
 
     CPPUNIT_TEST_SUITE(PdfExportTest);
+#if HAVE_FEATURE_PDFIUM
     CPPUNIT_TEST(testTdf106059);
+#endif
     CPPUNIT_TEST_SUITE_END();
 };
 
@@ -58,6 +64,7 @@ void PdfExportTest::tearDown()
     test::BootstrapFixture::tearDown();
 }
 
+#if HAVE_FEATURE_PDFIUM
 void PdfExportTest::testTdf106059()
 {
     // Import the bugdoc and export as PDF.
@@ -93,6 +100,7 @@ void PdfExportTest::testTdf106059()
     // This dictionary key was missing, so the XObject wasn't a reference one.
     CPPUNIT_ASSERT(pReferenceXObject->Lookup("Ref"));
 }
+#endif
 
 CPPUNIT_TEST_SUITE_REGISTRATION(PdfExportTest);
 
commit 102327e60cc0bf55251f1e3495f4483e4646352f
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Fri Feb 24 13:46:52 2017 +0100

    vcl: add initial CppunitTest_vcl_pdfexport
    
    Invoke the PDF export filter and then use the PDF tokenizer from
    xmlsecurity to assert the contents of created PDF file. The testcase
    fails with commit 6db0f1feb1d9931d2726dd11a889c58815710ce0 (tdf#106059
    PDF export: create a reference XObject for PDF images, 2017-02-22)
    reverted.
    
    Reviewed-on: https://gerrit.libreoffice.org/34609
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    Tested-by: Jenkins <ci at libreoffice.org>
    (cherry picked from commit 58eac1105f8504bd5320911fc6fe967ccaa3d469)
    
     Conflicts:
    	vcl/Module_vcl.mk
    
    Change-Id: I90526fef41d9560ae447f586df766bc50a491c43

diff --git a/xmlsecurity/inc/pdfio/pdfdocument.hxx b/include/xmlsecurity/pdfio/pdfdocument.hxx
similarity index 85%
rename from xmlsecurity/inc/pdfio/pdfdocument.hxx
rename to include/xmlsecurity/pdfio/pdfdocument.hxx
index e2f2913..1aefb6c 100644
--- a/xmlsecurity/inc/pdfio/pdfdocument.hxx
+++ b/include/xmlsecurity/pdfio/pdfdocument.hxx
@@ -8,8 +8,8 @@
  *
  */
 
-#ifndef INCLUDED_XMLSECURITY_INC_PDFIO_PDFDOCUMENT_HXX
-#define INCLUDED_XMLSECURITY_INC_PDFIO_PDFDOCUMENT_HXX
+#ifndef INCLUDED_XMLSECURITY_PDFIO_PDFDOCUMENT_HXX
+#define INCLUDED_XMLSECURITY_PDFIO_PDFDOCUMENT_HXX
 
 #include <map>
 #include <vector>
@@ -18,8 +18,9 @@
 
 #include <tools/stream.hxx>
 
-#include <xmlsecuritydllapi.h>
-#include <sigstruct.hxx>
+#include <xmlsecurity/xmlsecuritydllapi.h>
+
+struct SignatureInformation;
 
 namespace xmlsecurity
 {
@@ -103,6 +104,33 @@ public:
     sal_uInt64 GetLength() const;
 };
 
+/// Dictionary object: a set key-value pairs.
+class XMLSECURITY_DLLPUBLIC PDFDictionaryElement : public PDFElement
+{
+    /// Key-value pairs when the dictionary is a nested value.
+    std::map<OString, PDFElement*> m_aItems;
+    /// Offset after the '<<' token.
+    sal_uInt64 m_nLocation = 0;
+    /// Position after the '/' token.
+    std::map<OString, sal_uInt64> m_aDictionaryKeyOffset;
+    /// Length of the dictionary key and value, till (before) the next token.
+    std::map<OString, sal_uInt64> m_aDictionaryKeyValueLength;
+
+public:
+    PDFDictionaryElement();
+    bool Read(SvStream& rStream) override;
+
+    static size_t Parse(const std::vector< std::unique_ptr<PDFElement> >& rElements, PDFElement* pThis, std::map<OString, PDFElement*>& rDictionary);
+    static PDFElement* Lookup(const std::map<OString, PDFElement*>& rDictionary, const OString& rKey);
+    void SetKeyOffset(const OString& rKey, sal_uInt64 nOffset);
+    sal_uInt64 GetKeyOffset(const OString& rKey) const;
+    void SetKeyValueLength(const OString& rKey, sal_uInt64 nLength);
+    sal_uInt64 GetKeyValueLength(const OString& rKey) const;
+    const std::map<OString, PDFElement*>& GetItems() const;
+    /// Looks up an object which is only referenced in this dictionary.
+    PDFObjectElement* LookupObject(const OString& rDictionaryKey);
+};
+
 enum class TokenizeMode
 {
     /// Full file.
@@ -245,6 +273,6 @@ public:
 } // namespace pdfio
 } // namespace xmlsecurity
 
-#endif // INCLUDED_XMLSECURITY_INC_PDFIO_PDFDOCUMENT_HXX
+#endif // INCLUDED_XMLSECURITY_PDFIO_PDFDOCUMENT_HXX
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmlsecurity/inc/xmlsecuritydllapi.h b/include/xmlsecurity/xmlsecuritydllapi.h
similarity index 79%
rename from xmlsecurity/inc/xmlsecuritydllapi.h
rename to include/xmlsecurity/xmlsecuritydllapi.h
index 2349d23..48da546 100644
--- a/xmlsecurity/inc/xmlsecuritydllapi.h
+++ b/include/xmlsecurity/xmlsecuritydllapi.h
@@ -7,8 +7,8 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-#ifndef INCLUDED_XMLSECURITY_INCDLLAPI_H
-#define INCLUDED_XMLSECURITY_INCDLLAPI_H
+#ifndef INCLUDED_XMLSECURITY_XMLSECURITYDLLAPI_H
+#define INCLUDED_XMLSECURITY_XMLSECURITYDLLAPI_H
 
 #include <sal/types.h>
 
@@ -18,6 +18,6 @@
 #define XMLSECURITY_DLLPUBLIC SAL_DLLPUBLIC_IMPORT
 #endif
 
-#endif // INCLUDED_XMLSECURITY_INCDLLAPI_H
+#endif // INCLUDED_XMLSECURITY_XMLSECURITYDLLAPI_H
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/CppunitTest_vcl_pdfexport.mk b/vcl/CppunitTest_vcl_pdfexport.mk
new file mode 100644
index 0000000..8f0cbcd
--- /dev/null
+++ b/vcl/CppunitTest_vcl_pdfexport.mk
@@ -0,0 +1,42 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_CppunitTest_CppunitTest,vcl_pdfexport))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,vcl_pdfexport, \
+    vcl/qa/cppunit/pdfexport/pdfexport \
+))
+
+$(eval $(call gb_CppunitTest_use_sdk_api,vcl_pdfexport))
+
+$(eval $(call gb_CppunitTest_use_libraries,vcl_pdfexport, \
+	comphelper \
+	cppu \
+	cppuhelper \
+	sal \
+	test \
+	unotest \
+	utl \
+	tl \
+	xmlsecurity \
+	$(gb_UWINAPI) \
+))
+
+$(eval $(call gb_CppunitTest_use_external,vcl_pdfexport,boost_headers))
+
+$(eval $(call gb_CppunitTest_use_sdk_api,vcl_pdfexport))
+
+$(eval $(call gb_CppunitTest_use_ure,vcl_pdfexport))
+$(eval $(call gb_CppunitTest_use_vcl,vcl_pdfexport))
+
+$(eval $(call gb_CppunitTest_use_rdb,vcl_pdfexport,services))
+
+$(eval $(call gb_CppunitTest_use_configuration,vcl_pdfexport))
+
+# vim: set noet sw=4 ts=4:
diff --git a/vcl/Module_vcl.mk b/vcl/Module_vcl.mk
index 97e20f0..66a666a 100644
--- a/vcl/Module_vcl.mk
+++ b/vcl/Module_vcl.mk
@@ -109,6 +109,7 @@ $(eval $(call gb_Module_add_check_targets,vcl,\
 	CppunitTest_vcl_app_test \
 	$(if $(MERGELIBS),,CppunitTest_vcl_wmf_test) \
 	CppunitTest_vcl_jpeg_read_write_test \
+	CppunitTest_vcl_pdfexport \
 ))
 
 
diff --git a/vcl/qa/cppunit/pdfexport/data/tdf106059.odt b/vcl/qa/cppunit/pdfexport/data/tdf106059.odt
new file mode 100644
index 0000000..a2c1803
Binary files /dev/null and b/vcl/qa/cppunit/pdfexport/data/tdf106059.odt differ
diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
new file mode 100644
index 0000000..bcc3345
--- /dev/null
+++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
@@ -0,0 +1,103 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+
+#include <comphelper/processfactory.hxx>
+#include <cppuhelper/implbase.hxx>
+#include <test/bootstrapfixture.hxx>
+#include <unotest/macros_test.hxx>
+#include <unotools/mediadescriptor.hxx>
+#include <unotools/tempfile.hxx>
+#include <xmlsecurity/pdfio/pdfdocument.hxx>
+
+using namespace ::com::sun::star;
+
+namespace
+{
+
+const char* const DATA_DIRECTORY = "/vcl/qa/cppunit/pdfexport/data/";
+
+/// Tests the PDF export filter.
+class PdfExportTest : public test::BootstrapFixture, public unotest::MacrosTest
+{
+    uno::Reference<uno::XComponentContext> mxComponentContext;
+    uno::Reference<lang::XComponent> mxComponent;
+
+public:
+    virtual void setUp() override;
+    virtual void tearDown() override;
+    /// Tests that a pdf image is roundtripped back to PDF as a vector format.
+    void testTdf106059();
+
+    CPPUNIT_TEST_SUITE(PdfExportTest);
+    CPPUNIT_TEST(testTdf106059);
+    CPPUNIT_TEST_SUITE_END();
+};
+
+void PdfExportTest::setUp()
+{
+    test::BootstrapFixture::setUp();
+
+    mxComponentContext.set(comphelper::getComponentContext(getMultiServiceFactory()));
+    mxDesktop.set(frame::Desktop::create(mxComponentContext));
+}
+
+void PdfExportTest::tearDown()
+{
+    if (mxComponent.is())
+        mxComponent->dispose();
+
+    test::BootstrapFixture::tearDown();
+}
+
+void PdfExportTest::testTdf106059()
+{
+    // Import the bugdoc and export as PDF.
+    OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf106059.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.
+    xmlsecurity::pdfio::PDFDocument aDocument;
+    SvFileStream aStream(aTempFile.GetURL(), StreamMode::READ);
+    CPPUNIT_ASSERT(aDocument.Read(aStream));
+
+    // Assert that the XObject in the page resources dictionary is a reference XObject.
+    std::vector<xmlsecurity::pdfio::PDFObjectElement*> aPages = aDocument.GetPages();
+    // The document has one page.
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aPages.size());
+    xmlsecurity::pdfio::PDFObjectElement* pResources = aPages[0]->LookupObject("Resources");
+    CPPUNIT_ASSERT(pResources);
+    auto pXObjects = dynamic_cast<xmlsecurity::pdfio::PDFDictionaryElement*>(pResources->Lookup("XObject"));
+    CPPUNIT_ASSERT(pXObjects);
+    // The page has one image.
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pXObjects->GetItems().size());
+    xmlsecurity::pdfio::PDFObjectElement* pReferenceXObject = pXObjects->LookupObject(pXObjects->GetItems().begin()->first);
+    CPPUNIT_ASSERT(pReferenceXObject);
+    // The image is a reference XObject.
+    // This dictionary key was missing, so the XObject wasn't a reference one.
+    CPPUNIT_ASSERT(pReferenceXObject->Lookup("Ref"));
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(PdfExportTest);
+
+}
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmlsecurity/inc/documentsignaturehelper.hxx b/xmlsecurity/inc/documentsignaturehelper.hxx
index 10268e7..c2b5b85 100644
--- a/xmlsecurity/inc/documentsignaturehelper.hxx
+++ b/xmlsecurity/inc/documentsignaturehelper.hxx
@@ -24,7 +24,7 @@
 #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
 #include <rtl/ustring.hxx>
 #include "sigstruct.hxx"
-#include "xmlsecuritydllapi.h"
+#include "xmlsecurity/xmlsecuritydllapi.h"
 
 #include <vector>
 
diff --git a/xmlsecurity/inc/documentsignaturemanager.hxx b/xmlsecurity/inc/documentsignaturemanager.hxx
index fe9f9a4..af34654 100644
--- a/xmlsecurity/inc/documentsignaturemanager.hxx
+++ b/xmlsecurity/inc/documentsignaturemanager.hxx
@@ -20,7 +20,7 @@
 #ifndef INCLUDED_XMLSECURITY_INC_DOCUMENTSIGNATUREMANAGER_HXX
 #define INCLUDED_XMLSECURITY_INC_DOCUMENTSIGNATUREMANAGER_HXX
 
-#include "xmlsecuritydllapi.h"
+#include "xmlsecurity/xmlsecuritydllapi.h"
 
 #include <memory>
 
diff --git a/xmlsecurity/inc/pdfsignaturehelper.hxx b/xmlsecurity/inc/pdfsignaturehelper.hxx
index 7efdbfb..5667c53 100644
--- a/xmlsecurity/inc/pdfsignaturehelper.hxx
+++ b/xmlsecurity/inc/pdfsignaturehelper.hxx
@@ -11,7 +11,7 @@
 #ifndef INCLUDED_XMLSECURITY_INC_PDFSIGNATUREHELPER_HXX
 #define INCLUDED_XMLSECURITY_INC_PDFSIGNATUREHELPER_HXX
 
-#include <xmlsecuritydllapi.h>
+#include <xmlsecurity/xmlsecuritydllapi.h>
 
 #include <com/sun/star/io/XInputStream.hpp>
 #include <com/sun/star/security/DocumentSignatureInformation.hpp>
diff --git a/xmlsecurity/inc/xmlsignaturehelper.hxx b/xmlsecurity/inc/xmlsignaturehelper.hxx
index edc09d0..eb44e52 100644
--- a/xmlsecurity/inc/xmlsignaturehelper.hxx
+++ b/xmlsecurity/inc/xmlsignaturehelper.hxx
@@ -27,7 +27,7 @@
 #include <rtl/ref.hxx>
 #include <sigstruct.hxx>
 #include <xsecctl.hxx>
-#include <xmlsecuritydllapi.h>
+#include <xmlsecurity/xmlsecuritydllapi.h>
 
 #include <com/sun/star/uno/XComponentContext.hpp>
 #include <com/sun/star/xml/sax/XWriter.hpp>
diff --git a/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx b/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx
index 51fc15e..b0df29f 100644
--- a/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx
+++ b/xmlsecurity/qa/unit/pdfsigning/pdfsigning.cxx
@@ -17,7 +17,7 @@
 #include <unotools/ucbstreamhelper.hxx>
 
 #include <documentsignaturemanager.hxx>
-#include <pdfio/pdfdocument.hxx>
+#include <xmlsecurity/pdfio/pdfdocument.hxx>
 
 using namespace com::sun::star;
 
diff --git a/xmlsecurity/source/helper/pdfsignaturehelper.cxx b/xmlsecurity/source/helper/pdfsignaturehelper.cxx
index 4218a83..9e652f9 100644
--- a/xmlsecurity/source/helper/pdfsignaturehelper.cxx
+++ b/xmlsecurity/source/helper/pdfsignaturehelper.cxx
@@ -19,7 +19,7 @@
 #include <tools/stream.hxx>
 #include <unotools/ucbstreamhelper.hxx>
 
-#include <pdfio/pdfdocument.hxx>
+#include <xmlsecurity/pdfio/pdfdocument.hxx>
 
 using namespace ::com::sun::star;
 
diff --git a/xmlsecurity/source/pdfio/pdfdocument.cxx b/xmlsecurity/source/pdfio/pdfdocument.cxx
index 0d6c7e1..50e00d7 100644
--- a/xmlsecurity/source/pdfio/pdfdocument.cxx
+++ b/xmlsecurity/source/pdfio/pdfdocument.cxx
@@ -7,7 +7,7 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-#include <pdfio/pdfdocument.hxx>
+#include <xmlsecurity/pdfio/pdfdocument.hxx>
 
 #include <map>
 #include <memory>
@@ -31,6 +31,8 @@
 #include <xmloff/xmluconv.hxx>
 #include <o3tl/make_unique.hxx>
 
+#include <sigstruct.hxx>
+
 #ifdef XMLSEC_CRYPTO_NSS
 #include <cert.h>
 #include <cms.h>
@@ -87,31 +89,6 @@ public:
 
 class PDFReferenceElement;
 
-/// Dictionary object: a set key-value pairs.
-class PDFDictionaryElement : public PDFElement
-{
-    /// Key-value pairs when the dictionary is a nested value.
-    std::map<OString, PDFElement*> m_aItems;
-    /// Offset after the '<<' token.
-    sal_uInt64 m_nLocation = 0;
-    /// Position after the '/' token.
-    std::map<OString, sal_uInt64> m_aDictionaryKeyOffset;
-    /// Length of the dictionary key and value, till (before) the next token.
-    std::map<OString, sal_uInt64> m_aDictionaryKeyValueLength;
-
-public:
-    PDFDictionaryElement();
-    bool Read(SvStream& rStream) override;
-
-    static size_t Parse(const std::vector< std::unique_ptr<PDFElement> >& rElements, PDFElement* pThis, std::map<OString, PDFElement*>& rDictionary);
-    static PDFElement* Lookup(const std::map<OString, PDFElement*>& rDictionary, const OString& rKey);
-    void SetKeyOffset(const OString& rKey, sal_uInt64 nOffset);
-    sal_uInt64 GetKeyOffset(const OString& rKey) const;
-    void SetKeyValueLength(const OString& rKey, sal_uInt64 nLength);
-    sal_uInt64 GetKeyValueLength(const OString& rKey) const;
-    const std::map<OString, PDFElement*>& GetItems() const;
-};
-
 /// End of a dictionary: '>>'.
 class PDFEndDictionaryElement : public PDFElement
 {
@@ -3182,6 +3159,18 @@ PDFElement* PDFDictionaryElement::Lookup(const std::map<OString, PDFElement*>& r
     return it->second;
 }
 
+PDFObjectElement* PDFDictionaryElement::LookupObject(const OString& rDictionaryKey)
+{
+    auto pKey = dynamic_cast<PDFReferenceElement*>(PDFDictionaryElement::Lookup(m_aItems, rDictionaryKey));
+    if (!pKey)
+    {
+        SAL_WARN("xmlsecurity.pdfio", "PDFDictionaryElement::LookupObject: no such key with reference value: " << rDictionaryKey);
+        return nullptr;
+    }
+
+    return pKey->LookupObject();
+}
+
 PDFElement* PDFObjectElement::Lookup(const OString& rDictionaryKey)
 {
     if (m_aDictionary.empty())
diff --git a/xmlsecurity/workben/pdfverify.cxx b/xmlsecurity/workben/pdfverify.cxx
index d481d15..5e19601 100644
--- a/xmlsecurity/workben/pdfverify.cxx
+++ b/xmlsecurity/workben/pdfverify.cxx
@@ -31,7 +31,9 @@
 #include <vcl/pngwrite.hxx>
 #include <vcl/svapp.hxx>
 
-#include <pdfio/pdfdocument.hxx>
+#include <xmlsecurity/pdfio/pdfdocument.hxx>
+
+#include <sigstruct.hxx>
 
 using namespace com::sun::star;
 
commit a30b765d9dc2385b8d5920ccc70f3383c8bea32b
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Wed Feb 1 10:28:56 2017 +0100

    xmlsecurity: various small cleanups
    
    Reviewed-on: https://gerrit.libreoffice.org/33779
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    Tested-by: Jenkins <ci at libreoffice.org>
    (cherry picked from commit 68c58b46918bb377a8d37a3cd1c9a9ba734390f1)
    
    Conflicts:
    	xmlsecurity/source/helper/documentsignaturemanager.cxx
    	xmlsecurity/source/helper/pdfsignaturehelper.cxx
    
    Change-Id: Id713460036331fd9f98fd1eca85ca61f57cf5afe

diff --git a/xmlsecurity/source/helper/ooxmlsecexporter.cxx b/xmlsecurity/source/helper/ooxmlsecexporter.cxx
index 34843a5..9627021 100644
--- a/xmlsecurity/source/helper/ooxmlsecexporter.cxx
+++ b/xmlsecurity/source/helper/ooxmlsecexporter.cxx
@@ -426,9 +426,7 @@ OOXMLSecExporter::OOXMLSecExporter(const uno::Reference<uno::XComponentContext>&
 {
 }
 
-OOXMLSecExporter::~OOXMLSecExporter()
-{
-}
+OOXMLSecExporter::~OOXMLSecExporter() = default;
 
 void OOXMLSecExporter::writeSignature()
 {
diff --git a/xmlsecurity/source/pdfio/pdfdocument.cxx b/xmlsecurity/source/pdfio/pdfdocument.cxx
index e071e30..0d6c7e1 100644
--- a/xmlsecurity/source/pdfio/pdfdocument.cxx
+++ b/xmlsecurity/source/pdfio/pdfdocument.cxx
@@ -29,6 +29,7 @@
 #include <unotools/datetime.hxx>
 #include <vcl/pdfwriter.hxx>
 #include <xmloff/xmluconv.hxx>
+#include <o3tl/make_unique.hxx>
 
 #ifdef XMLSEC_CRYPTO_NSS
 #include <cert.h>
@@ -71,10 +72,10 @@ public:
 class PDFNumberElement : public PDFElement
 {
     /// Input file start location.
-    sal_uInt64 m_nOffset;
+    sal_uInt64 m_nOffset = 0;
     /// Input file token length.
-    sal_uInt64 m_nLength;
-    double m_fValue;
+    sal_uInt64 m_nLength = 0;
+    double m_fValue = 0;
 
 public:
     PDFNumberElement();
@@ -92,7 +93,7 @@ class PDFDictionaryElement : public PDFElement
     /// Key-value pairs when the dictionary is a nested value.
     std::map<OString, PDFElement*> m_aItems;
     /// Offset after the '<<' token.
-    sal_uInt64 m_nLocation;
+    sal_uInt64 m_nLocation = 0;
     /// Position after the '/' token.
     std::map<OString, sal_uInt64> m_aDictionaryKeyOffset;
     /// Length of the dictionary key and value, till (before) the next token.
@@ -115,7 +116,7 @@ public:
 class PDFEndDictionaryElement : public PDFElement
 {
     /// Offset before the '>>' token.
-    sal_uInt64 m_nLocation;
+    sal_uInt64 m_nLocation = 0;
 public:
     PDFEndDictionaryElement();
     bool Read(SvStream& rStream) override;
@@ -170,7 +171,7 @@ public:
 class PDFArrayElement : public PDFElement
 {
     /// Location after the '[' token.
-    sal_uInt64 m_nOffset;
+    sal_uInt64 m_nOffset = 0;
     std::vector<PDFElement*> m_aElements;
 public:
     PDFArrayElement();
@@ -183,7 +184,7 @@ public:
 class PDFEndArrayElement : public PDFElement
 {
     /// Location before the ']' token.
-    sal_uInt64 m_nOffset;
+    sal_uInt64 m_nOffset = 0;
 public:
     PDFEndArrayElement();
     bool Read(SvStream& rStream) override;
@@ -1114,7 +1115,7 @@ bool PDFDocument::Tokenize(SvStream& rStream, TokenizeMode eMode, std::vector< s
             if (isdigit(ch) || ch == '-')
             {
                 // Numbering object: an integer or a real.
-                PDFNumberElement* pNumberElement = new PDFNumberElement();
+                auto pNumberElement = new PDFNumberElement();
                 rElements.push_back(std::unique_ptr<PDFElement>(pNumberElement));
                 rStream.SeekRel(-1);
                 if (!pNumberElement->Read(rStream))
@@ -2110,7 +2111,7 @@ bad_data:
             }
             if (!num_bytes)
                 ++num_bytes;  /* use one byte for a zero value */
-            if (num_bytes + result_bytes > sizeof result)
+            if (static_cast<size_t>(num_bytes) + result_bytes > sizeof result)
                 goto bad_data;
             tmp = num_bytes;
             rp = result + result_bytes - 1;
@@ -2247,7 +2248,10 @@ bool PDFDocument::ValidateSignature(SvStream& rStream, PDFObjectElement* pSignat
     bool bNonDetached = pSubFilter && pSubFilter->GetValue() == "adbe.pkcs7.sha1";
     if (!pSubFilter || (pSubFilter->GetValue() != "adbe.pkcs7.detached" && !bNonDetached && pSubFilter->GetValue() != "ETSI.CAdES.detached"))
     {
-        SAL_WARN("xmlsecurity.pdfio", "PDFDocument::ValidateSignature: unsupported sub-filter: '"<<pSubFilter->GetValue()<<"'");
+        if (!pSubFilter)
+            SAL_WARN("xmlsecurity.pdfio", "PDFDocument::ValidateSignature: missing sub-filter");
+        else
+            SAL_WARN("xmlsecurity.pdfio", "PDFDocument::ValidateSignature: unsupported sub-filter: '"<<pSubFilter->GetValue()<<"'");
         return false;
     }
 
@@ -2328,7 +2332,7 @@ bool PDFDocument::ValidateSignature(SvStream& rStream, PDFObjectElement* pSignat
         return false;
     }
     // 2 is the leading "<" and the trailing ">" around the hex string.
-    size_t nSignatureLength = pContents->GetValue().getLength() + 2;
+    size_t nSignatureLength = static_cast<size_t>(pContents->GetValue().getLength()) + 2;
     if (aByteRanges[1].first != (aByteRanges[0].second + nSignatureLength))
     {
         SAL_WARN("xmlsecurity.pdfio", "PDFDocument::ValidateSignature: second range start is not the end of the signature");
@@ -2376,7 +2380,7 @@ bool PDFDocument::ValidateSignature(SvStream& rStream, PDFObjectElement* pSignat
         return false;
     }
 
-    NSSCMSSignedData* pCMSSignedData = static_cast<NSSCMSSignedData*>(NSS_CMSContentInfo_GetContent(pCMSContentInfo));
+    auto pCMSSignedData = static_cast<NSSCMSSignedData*>(NSS_CMSContentInfo_GetContent(pCMSContentInfo));
     if (!pCMSSignedData)
     {
         SAL_WARN("xmlsecurity.pdfio", "PDFDocument::ValidateSignature: NSS_CMSContentInfo_GetContent() failed");
@@ -2791,12 +2795,7 @@ bool PDFCommentElement::Read(SvStream& rStream)
     return false;
 }
 
-PDFNumberElement::PDFNumberElement()
-    : m_nOffset(0),
-      m_nLength(0),
-      m_fValue(0)
-{
-}
+PDFNumberElement::PDFNumberElement() = default;
 
 bool PDFNumberElement::Read(SvStream& rStream)
 {
@@ -2959,10 +2958,7 @@ bool PDFObjectElement::Read(SvStream& /*rStream*/)
     return true;
 }
 
-PDFDictionaryElement::PDFDictionaryElement()
-    : m_nLocation(0)
-{
-}
+PDFDictionaryElement::PDFDictionaryElement() = default;
 
 size_t PDFDictionaryElement::Parse(const std::vector< std::unique_ptr<PDFElement> >& rElements, PDFElement* pThis, std::map<OString, PDFElement*>& rDictionary)
 {
@@ -3313,14 +3309,20 @@ void PDFObjectElement::ParseStoredObjects()
     auto pType = dynamic_cast<PDFNameElement*>(Lookup("Type"));
     if (!pType || pType->GetValue() != "ObjStm")
     {
-        SAL_WARN("xmlsecurity.pdfio", "PDFDocument::ReadXRefStream: missing or unexpected type: " << pType->GetValue());
+        if (!pType)
+            SAL_WARN("xmlsecurity.pdfio", "PDFDocument::ReadXRefStream: missing unexpected type");
+        else
+            SAL_WARN("xmlsecurity.pdfio", "PDFDocument::ReadXRefStream: unexpected type: " << pType->GetValue());
         return;
     }
 
     auto pFilter = dynamic_cast<PDFNameElement*>(Lookup("Filter"));
     if (!pFilter || pFilter->GetValue() != "FlateDecode")
     {
-        SAL_WARN("xmlsecurity.pdfio", "PDFDocument::ReadXRefStream: missing or unexpected filter");
+        if (!pFilter)
+            SAL_WARN("xmlsecurity.pdfio", "PDFDocument::ReadXRefStream: missing filter");
+        else
+            SAL_WARN("xmlsecurity.pdfio", "PDFDocument::ReadXRefStream: unexpected filter: " << pFilter->GetValue());
         return;
     }
 
@@ -3406,7 +3408,7 @@ void PDFObjectElement::ParseStoredObjects()
         size_t nLen = aLengths[nObject];
 
         aStream.Seek(nOffset);
-        m_aStoredElements.push_back(std::unique_ptr<PDFObjectElement>(new PDFObjectElement(m_rDoc, nObjNum, 0)));
+        m_aStoredElements.push_back(o3tl::make_unique<PDFObjectElement>(m_rDoc, nObjNum, 0));
         PDFObjectElement* pStored = m_aStoredElements.back().get();
 
         aBuf.clear();
@@ -3574,10 +3576,7 @@ bool PDFDictionaryElement::Read(SvStream& rStream)
     return true;
 }
 
-PDFEndDictionaryElement::PDFEndDictionaryElement()
-    : m_nLocation(0)
-{
-}
+PDFEndDictionaryElement::PDFEndDictionaryElement() = default;
 
 sal_uInt64 PDFEndDictionaryElement::GetLocation() const
 {
@@ -3700,10 +3699,7 @@ bool PDFEndObjectElement::Read(SvStream& /*rStream*/)
     return true;
 }
 
-PDFArrayElement::PDFArrayElement()
-    : m_nOffset(0)
-{
-}
+PDFArrayElement::PDFArrayElement() = default;
 
 bool PDFArrayElement::Read(SvStream& rStream)
 {
@@ -3731,10 +3727,7 @@ const std::vector<PDFElement*>& PDFArrayElement::GetElements()
     return m_aElements;
 }
 
-PDFEndArrayElement::PDFEndArrayElement()
-    : m_nOffset(0)
-{
-}
+PDFEndArrayElement::PDFEndArrayElement() = default;
 
 bool PDFEndArrayElement::Read(SvStream& rStream)
 {
commit fe677e8f6a973bb80e3b359c67053607277dbee9
Author: Stephan Bergmann <sbergman at redhat.com>
Date:   Sat Feb 18 09:18:30 2017 +0100

    loplugin:subtlezeroinit: xmlsecurity
    
    Change-Id: Ife06c74e1665273350b497a1a584d7f76297c13d
    (cherry picked from commit 7dedccd06d5c822b6bcaeba81753ca9e75fad376)

diff --git a/xmlsecurity/source/pdfio/pdfdocument.cxx b/xmlsecurity/source/pdfio/pdfdocument.cxx
index f4206c6..e071e30 100644
--- a/xmlsecurity/source/pdfio/pdfdocument.cxx
+++ b/xmlsecurity/source/pdfio/pdfdocument.cxx
@@ -1031,7 +1031,7 @@ bool PDFDocument::Tokenize(SvStream& rStream, TokenizeMode eMode, std::vector< s
                 ++nDictionaryDepth;
             }
             else
-                rElements.push_back(std::unique_ptr<PDFElement>(new PDFHexStringElement()));
+                rElements.push_back(std::unique_ptr<PDFElement>(new PDFHexStringElement));
             if (!rElements.back()->Read(rStream))
             {
                 SAL_WARN("xmlsecurity.pdfio", "PDFDocument::Tokenize: PDFDictionaryElement::Read() failed");
@@ -1100,7 +1100,7 @@ bool PDFDocument::Tokenize(SvStream& rStream, TokenizeMode eMode, std::vector< s
         }
         case '(':
         {
-            rElements.push_back(std::unique_ptr<PDFElement>(new PDFLiteralStringElement()));
+            rElements.push_back(std::unique_ptr<PDFElement>(new PDFLiteralStringElement));
             rStream.SeekRel(-1);
             if (!rElements.back()->Read(rStream))
             {
@@ -1223,7 +1223,7 @@ bool PDFDocument::Tokenize(SvStream& rStream, TokenizeMode eMode, std::vector< s
                 }
                 else if (aKeyword == "endstream")
                 {
-                    rElements.push_back(std::unique_ptr<PDFElement>(new PDFEndStreamElement()));
+                    rElements.push_back(std::unique_ptr<PDFElement>(new PDFEndStreamElement));
                     if (!rElements.back()->Read(rStream))
                     {
                         SAL_WARN("xmlsecurity.pdfio", "PDFDocument::Tokenize: PDFEndStreamElement::Read() failed");
@@ -1232,7 +1232,7 @@ bool PDFDocument::Tokenize(SvStream& rStream, TokenizeMode eMode, std::vector< s
                 }
                 else if (aKeyword == "endobj")
                 {
-                    rElements.push_back(std::unique_ptr<PDFElement>(new PDFEndObjectElement()));
+                    rElements.push_back(std::unique_ptr<PDFElement>(new PDFEndObjectElement));
                     if (!rElements.back()->Read(rStream))
                     {
                         SAL_WARN("xmlsecurity.pdfio", "PDFDocument::Tokenize: PDFEndObjectElement::Read() failed");
@@ -1255,7 +1255,7 @@ bool PDFDocument::Tokenize(SvStream& rStream, TokenizeMode eMode, std::vector< s
                 else if (aKeyword == "true" || aKeyword == "false")
                     rElements.push_back(std::unique_ptr<PDFElement>(new PDFBooleanElement(aKeyword.toBoolean())));
                 else if (aKeyword == "null")
-                    rElements.push_back(std::unique_ptr<PDFElement>(new PDFNullElement()));
+                    rElements.push_back(std::unique_ptr<PDFElement>(new PDFNullElement));
                 else if (aKeyword == "xref")
                     // Allow 'f' and 'n' keywords.
                     bInXRef = true;
diff --git a/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.cxx b/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.cxx
index be930a2..283ebbe 100644
--- a/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.cxx
+++ b/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.cxx
@@ -209,13 +209,13 @@ css::uno::Sequence< css::uno::Reference< css::security::XCertificateExtension >
 
             if (objID.equals("2.5.29.17"))
             {
-                SanExtensionImpl* pExtn = new SanExtensionImpl();
+                SanExtensionImpl* pExtn = new SanExtensionImpl;
                 pExtn->setCertExtn(value, vlen, objid, objidlen, crit);
                 xExtns[len] = pExtn ;
             }
             else
             {
-                CertificateExtension_XmlSecImpl* pExtn = new CertificateExtension_XmlSecImpl();
+                CertificateExtension_XmlSecImpl* pExtn = new CertificateExtension_XmlSecImpl;
                 pExtn->setCertExtn(value, vlen, objid, objidlen, crit);
                 xExtns[len] = pExtn;
             }
@@ -255,14 +255,14 @@ css::uno::Reference< css::security::XCertificateExtension > SAL_CALL X509Certifi
                 if ( objId.equals("OID.2.5.29.17") )
                 {
                     rtl::Reference<SanExtensionImpl> xSanImpl(
-                        new SanExtensionImpl());
+                        new SanExtensionImpl);
                     xSanImpl->setCertExtn(value, vlen, objid, objidlen, crit);
                     xExtn = xSanImpl.get();
                 }
                 else
                 {
                     rtl::Reference<CertificateExtension_XmlSecImpl> xSecImpl(
-                        new CertificateExtension_XmlSecImpl());
+                        new CertificateExtension_XmlSecImpl);
                     xSecImpl->setCertExtn(value, vlen, objid, objidlen, crit);
                     xExtn = xSecImpl.get();
                 }
commit a79d0bbb854710eb1256057a9668e188bdf33864
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Fri Feb 24 11:47:40 2017 +0100

    xmlsecurity PDF verify: handle multiple startxref in the last 1024 bytes
    
    Usually this is not a problem, but it's easy to construct a document
    manually that contains multiple startxref tokens at the last 1024 bytes.
    Make sure we read the last of those, not the first one.
    
    This is triggered by an upcoming unit test for tdf#106059.
    
    Change-Id: I94fbb5d407c4a03b7c2c6e207200127bb374e750
    Reviewed-on: https://gerrit.libreoffice.org/34607
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    Tested-by: Jenkins <ci at libreoffice.org>
    (cherry picked from commit 7737457558cafe35c2efe613b4be8ad7abe50dea)

diff --git a/xmlsecurity/source/pdfio/pdfdocument.cxx b/xmlsecurity/source/pdfio/pdfdocument.cxx
index 899250b..f4206c6 100644
--- a/xmlsecurity/source/pdfio/pdfdocument.cxx
+++ b/xmlsecurity/source/pdfio/pdfdocument.cxx
@@ -1403,14 +1403,27 @@ size_t PDFDocument::FindStartXRef(SvStream& rStream)
     if (nSize != aBuf.size())
         aBuf.resize(nSize);
     OString aPrefix("startxref");
-    auto it = std::search(aBuf.begin(), aBuf.end(), aPrefix.getStr(), aPrefix.getStr() + aPrefix.getLength());
-    if (it == aBuf.end())
+    // Find the last startxref at the end of the document.
+    std::vector<char>::iterator itLastValid = aBuf.end();
+    std::vector<char>::iterator it = aBuf.begin();
+    while (true)
+    {
+        it = std::search(it, aBuf.end(), aPrefix.getStr(), aPrefix.getStr() + aPrefix.getLength());
+        if (it == aBuf.end())
+            break;
+        else
+        {
+            itLastValid = it;
+            ++it;
+        }
+    }
+    if (itLastValid == aBuf.end())
     {
         SAL_WARN("xmlsecurity.pdfio", "PDFDocument::FindStartXRef: found no startxref");
         return 0;
     }
 
-    rStream.SeekRel(it - aBuf.begin() + aPrefix.getLength());
+    rStream.SeekRel(itLastValid - aBuf.begin() + aPrefix.getLength());
     if (rStream.IsEof())
     {
         SAL_WARN("xmlsecurity.pdfio", "PDFDocument::FindStartXRef: unexpected end of stream after startxref");
commit 0eb78df103eaf77b0ae1d4cec9deca159f026e7c
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Fri Feb 24 09:28:52 2017 +0100

    vcl PDF import: there is no PNG encoding here
    
    It was a copy&paste error from xmlsecurity/workben/pdfverify.cxx, which
    does PNG encoding.
    
    Change-Id: I7b5108a7cddffdc859276b656a6e1168f23d3863
    (cherry picked from commit 89e339fc1937b7de0d0e1f4ced802db7b4a68a9b)

diff --git a/vcl/source/filter/ipdf/pdfread.cxx b/vcl/source/filter/ipdf/pdfread.cxx
index 12d41af..c855400 100644
--- a/vcl/source/filter/ipdf/pdfread.cxx
+++ b/vcl/source/filter/ipdf/pdfread.cxx
@@ -37,7 +37,7 @@ double pointToPixel(double fPoint)
     return fPoint / 72 * 96;
 }
 
-/// Does PDF to PNG conversion using pdfium.
+/// Does PDF to bitmap conversion using pdfium.
 bool generatePreview(SvStream& rStream, Graphic& rGraphic)
 {
     FPDF_LIBRARY_CONFIG aConfig;
diff --git a/writerfilter/source/rtftok/rtfdispatchflag.cxx b/writerfilter/source/rtftok/rtfdispatchflag.cxx
index 18eac50..0596929 100644
--- a/writerfilter/source/rtftok/rtfdispatchflag.cxx
+++ b/writerfilter/source/rtftok/rtfdispatchflag.cxx
@@ -1071,7 +1071,7 @@ RTFError RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword)
     break;
     case RTF_HTMAUTSP:
         m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Compat_doNotUseHTMLParagraphAutoSpacing, std::make_shared<RTFValue>(0));
-    break;
+        break;
     default:
     {
         SAL_INFO("writerfilter", "TODO handle flag '" << keywordToString(nKeyword) << "'");
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index 07ecb5f..9243e6d 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -1117,7 +1117,7 @@ RTFError RTFDocumentImpl::resolveChars(char ch)
         {
             // note: apparently \'0d\'0a is interpreted as 2 breaks, not 1
             if (m_aStates.top().eDestination != Destination::DOCCOMM
-                && (ch == '\r' || ch == '\n'))
+                    && (ch == '\r' || ch == '\n'))
             {
                 checkUnicode(/*bUnicode =*/ false, /*bHex =*/ true);
                 dispatchSymbol(RTF_PAR);
commit 18e89ea669afa9e908c1aaaa0f10ca1e2273e470
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Thu Feb 23 17:48:47 2017 +0100

    external: update to pdfium-3021
    
    Change-Id: Ie6bbf7dd0418987a82e44c93b076aa443c00f171
    Reviewed-on: https://gerrit.libreoffice.org/34588
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    Tested-by: Jenkins <ci at libreoffice.org>
    (cherry picked from commit 2a5f1d2a3d5595911f5d59163a0750051e83cacd)

diff --git a/download.lst b/download.lst
index 9532d15..1e1ae93 100644
--- a/download.lst
+++ b/download.lst
@@ -132,7 +132,7 @@ export OWNCLOUD_ANDROID_LIB_MD5SUM := 593f0aa47bf2efc0efda2d28fae063b2
 export OWNCLOUD_ANDROID_LIB_TARBALL := owncloud-android-library-0.9.4-no-binary-deps.tar.gz
 export PAGEMAKER_MD5SUM := 5c4985a68be0b79d3f809da5e12b143c
 export PAGEMAKER_TARBALL := libpagemaker-0.0.3.tar.bz2
-export PDFIUM_TARBALL := 9ac66c71463f9440e3ccc996c5e66556-pdfium-3004.tar.bz2
+export PDFIUM_TARBALL := cfcb6b4f3b5b6097edc5df7903ef00ea-pdfium-3021.tar.bz2
 export PIXMAN_TARBALL := e80ebae4da01e77f68744319f01d52a3-pixman-0.34.0.tar.gz
 export PNG_MD5SUM := 897ccec1ebfb0922e83c2bfaa1be8748
 export PNG_TARBALL := libpng-1.6.28.tar.gz
diff --git a/external/pdfium/Library_pdfium.mk b/external/pdfium/Library_pdfium.mk
index 8c46acb..842fcc8 100644
--- a/external/pdfium/Library_pdfium.mk
+++ b/external/pdfium/Library_pdfium.mk
@@ -58,6 +58,8 @@ $(eval $(call gb_Library_add_generated_exception_objects,pdfium,\
     UnpackedTarball/pdfium/fpdfsdk/fpdfdoc \
     UnpackedTarball/pdfium/fpdfsdk/fpdfeditimg \
     UnpackedTarball/pdfium/fpdfsdk/fpdfeditpage \
+    UnpackedTarball/pdfium/fpdfsdk/fpdfeditpath \
+    UnpackedTarball/pdfium/fpdfsdk/fpdfedittext \
     UnpackedTarball/pdfium/fpdfsdk/fpdfformfill \
     UnpackedTarball/pdfium/fpdfsdk/fpdfppo \
     UnpackedTarball/pdfium/fpdfsdk/fpdfsave \
@@ -414,6 +416,7 @@ $(eval $(call gb_Library_add_generated_exception_objects,pdfium,\
     UnpackedTarball/pdfium/fpdfsdk/pdfwindow/PWL_SpecialButton \
     UnpackedTarball/pdfium/fpdfsdk/pdfwindow/PWL_Utils \
     UnpackedTarball/pdfium/fpdfsdk/pdfwindow/PWL_Wnd \
+    UnpackedTarball/pdfium/fpdfsdk/pdfwindow/cpwl_pathdata \
 ))
 
 # third_party/bigint
diff --git a/external/pdfium/README b/external/pdfium/README
index 928f70c..e4b2a78 100644
--- a/external/pdfium/README
+++ b/external/pdfium/README
@@ -3,6 +3,8 @@ External package containing pdfium.
 "Insert -> Picture -> From File..." uses this library when a PDF file is
 selected.
 
+https://pdfium.googlesource.com/pdfium/
+
 How to update the tarball:
 
 version=$(git for-each-ref|grep chromium/|tail -n 1|sed 's|.*/||')
commit 6a9b824c123e3851f031e1fe23a883e43a59d9c2
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Thu Feb 23 16:35:15 2017 +0100

    tdf#106059 PDF export: create a reference XObject for JPG images with PDF data
    
    In case the bitmap is large enough, the bitmap for the PDF image is a
    JPG one, not a PNG one. Handle this case as well.
    
    Also stop compressing the PDF data: Adobe Acrobat gets confused when the
    second bugdoc is compressed and it doesn't provide much as most of a PDF
    is already compressed anyway.
    
    The rest is just refactoring to decouple the reference XObject code from
    PNG, to be able to use it for JPG as well.
    
    Change-Id: I5314a39b0f6d8c6493ecb36a0c588c895f5a70ee
    (cherry picked from commit 78e25558e86188314b9b72048b8ddca18697cb86)

diff --git a/include/vcl/pdfwriter.hxx b/include/vcl/pdfwriter.hxx
index d9d7cf4..b54ce53 100644
--- a/include/vcl/pdfwriter.hxx
+++ b/include/vcl/pdfwriter.hxx
@@ -873,7 +873,7 @@ The following structure describes the permissions used in PDF security
     the same pixel size as the image and
     be either 1 bit black&white or 8 bit grey
     */
-    void                DrawJPGBitmap( SvStream& rJPGData, bool bIsTrueColor, const Size& rSrcSizePixel, const Rectangle& rTargetArea, const Bitmap& rMask );
+    void                DrawJPGBitmap( SvStream& rJPGData, bool bIsTrueColor, const Size& rSrcSizePixel, const Rectangle& rTargetArea, const Bitmap& rMask, const Graphic& rGraphic );
 
     /** Create a new named destination to be used in a link from another PDF document
 
diff --git a/vcl/source/gdi/pdfextoutdevdata.cxx b/vcl/source/gdi/pdfextoutdevdata.cxx
index fcdab9b..589c381 100644
--- a/vcl/source/gdi/pdfextoutdevdata.cxx
+++ b/vcl/source/gdi/pdfextoutdevdata.cxx
@@ -450,7 +450,7 @@ bool PageSyncData::PlaySyncPageAct( PDFWriter& rWriter, sal_uInt32& rCurGDIMtfAc
                             }
                             else if ((eType == GfxLinkType::NativePng || eType == GfxLinkType::NativePdf) && mParaRects.size() >= 2)
                             {
-                                if ( rOutDevData.HasAdequateCompression(rGraphic, mParaRects[0], mParaRects[1]) )
+                                if ( rOutDevData.HasAdequateCompression(rGraphic, mParaRects[0], mParaRects[1]) || eType == GfxLinkType::NativePdf )
                                     mCurrentGraphic = rGraphic;
                             }
                         }
@@ -508,7 +508,7 @@ bool PageSyncData::PlaySyncPageAct( PDFWriter& rWriter, sal_uInt32& rCurGDIMtfAc
                         if( pData && nBytes )
                         {
                             aTmp.WriteBytes( pData, nBytes );
-                            rWriter.DrawJPGBitmap( aTmp, aGraphic.GetBitmap().GetBitCount() > 8, aGraphic.GetSizePixel(), aOutputRect, aMask );
+                            rWriter.DrawJPGBitmap( aTmp, aGraphic.GetBitmap().GetBitCount() > 8, aGraphic.GetSizePixel(), aOutputRect, aMask, aGraphic );
                         }
 
                         if ( bClippingNeeded )
diff --git a/vcl/source/gdi/pdfwriter.cxx b/vcl/source/gdi/pdfwriter.cxx
index cb56a0e..d54a327 100644
--- a/vcl/source/gdi/pdfwriter.cxx
+++ b/vcl/source/gdi/pdfwriter.cxx
@@ -334,9 +334,9 @@ void PDFWriter::SetTextAlign( ::TextAlign eAlign )
     xImplementation->setTextAlign( eAlign );
 }
 
-void PDFWriter::DrawJPGBitmap( SvStream& rStreamData, bool bIsTrueColor, const Size& rSrcSizePixel, const Rectangle& rTargetArea, const Bitmap& rMask )
+void PDFWriter::DrawJPGBitmap( SvStream& rStreamData, bool bIsTrueColor, const Size& rSrcSizePixel, const Rectangle& rTargetArea, const Bitmap& rMask, const Graphic& rGraphic )
 {
-    xImplementation->drawJPGBitmap( rStreamData, bIsTrueColor, rSrcSizePixel, rTargetArea, rMask );
+    xImplementation->drawJPGBitmap( rStreamData, bIsTrueColor, rSrcSizePixel, rTargetArea, rMask, rGraphic );
 }
 
 sal_Int32 PDFWriter::CreateLink( const Rectangle& rRect, sal_Int32 nPageNr )
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index bd65b6c..69cd2e7 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -5658,25 +5658,16 @@ bool PDFWriterImpl::emitEmbeddedFiles()
         if (!updateObject(rEmbeddedFile.m_nObject))
             continue;
 
-        SvMemoryStream aUncompressed;
-        aUncompressed.WriteBytes(rEmbeddedFile.m_aData.getArray(), rEmbeddedFile.m_aData.getLength());
-        aUncompressed.Seek(0);
-        SvMemoryStream aCompressed;
-        ZCodec aZCodec;
-        aZCodec.BeginCompression();
-        aZCodec.Compress(aUncompressed, aCompressed);
-        aZCodec.EndCompression();
-
         OStringBuffer aLine;
         aLine.append(rEmbeddedFile.m_nObject);
         aLine.append(" 0 obj\n");
-        aLine.append("<< /Type /EmbeddedFile /Filter /FlateDecode /Length ");
-        aLine.append(static_cast<sal_Int64>(aCompressed.GetSize()));
+        aLine.append("<< /Type /EmbeddedFile /Length ");
+        aLine.append(static_cast<sal_Int64>(rEmbeddedFile.m_aData.getLength()));
         aLine.append(" >>\nstream\n");
         CHECK_RETURN(writeBuffer(aLine.getStr(), aLine.getLength()));
         aLine.setLength(0);
 
-        CHECK_RETURN(writeBuffer(aCompressed.GetData(), aCompressed.GetSize()));
+        CHECK_RETURN(writeBuffer(rEmbeddedFile.m_aData.getArray(), rEmbeddedFile.m_aData.getLength()));
 
         aLine.append("\nendstream\nendobj\n\n");
         CHECK_RETURN(writeBuffer(aLine.getStr(), aLine.getLength()));
@@ -11695,6 +11686,75 @@ void PDFWriterImpl::writeJPG( JPGEmit& rObject )
             aEmit.m_aBitmap = BitmapEx( rObject.m_aMask, AlphaMask( rObject.m_aMask ) );
         writeBitmapObject( aEmit, true );
     }
+
+    writeReferenceXObject(rObject.m_aReferenceXObject);
+}
+
+void PDFWriterImpl::writeReferenceXObject(ReferenceXObjectEmit& rEmit)
+{
+    if (rEmit.m_nFormObject <= 0 || rEmit.m_nEmbeddedObject <= 0)
+        return;
+
+    OStringBuffer aLine;
+    if (!updateObject(rEmit.m_nFormObject))
+        return;
+
+    // Count /Matrix and /BBox.
+    // vcl::ImportPDF() works with 96 DPI so use the same values here, too.
+    sal_Int32 nOldDPIX = getReferenceDevice()->GetDPIX();
+    getReferenceDevice()->SetDPIX(96);
+    sal_Int32 nOldDPIY = getReferenceDevice()->GetDPIY();
+    getReferenceDevice()->SetDPIY(96);
+    Size aSize = getReferenceDevice()->PixelToLogic(rEmit.m_aPixelSize, MapMode(m_aMapMode.GetMapUnit()));
+    getReferenceDevice()->SetDPIX(nOldDPIX);
+    getReferenceDevice()->SetDPIY(nOldDPIY);
+    double fScaleX = 1.0 / aSize.Width();
+    double fScaleY = 1.0 / aSize.Height();
+
+    // Now have all the info to write the form XObject.
+    aLine.append(rEmit.m_nFormObject);
+    aLine.append(" 0 obj\n");
+    aLine.append("<< /Type /XObject");
+    aLine.append(" /Subtype /Form");
+    aLine.append(" /Resources << /XObject<</Im");
+    aLine.append(rEmit.m_nBitmapObject);
+    aLine.append(" ");
+    aLine.append(rEmit.m_nBitmapObject);
+    aLine.append(" 0 R>> >>");
+    aLine.append(" /Matrix [ ");
+    appendDouble(fScaleX, aLine);
+    aLine.append(" 0 0 ");
+    appendDouble(fScaleY, aLine);
+    aLine.append(" 0 0 ]");
+    aLine.append(" /BBox [ 0 0 ");
+    aLine.append(aSize.Width());
+    aLine.append(" ");
+    aLine.append(aSize.Height());
+    aLine.append(" ]\n");
+
+    // Write the reference dictionary.
+    aLine.append("/Ref<< /F << /Type /Filespec /F (<embedded file>) /EF << /F ");
+    aLine.append(rEmit.m_nEmbeddedObject);
+    aLine.append(" 0 R >> >> /Page 0 >>\n");
+
+    aLine.append("/Length ");
+
+    OStringBuffer aStream;
+    aStream.append("q ");
+    aStream.append(aSize.Width());
+    aStream.append(" 0 0 ");
+    aStream.append(aSize.Height());
+    aStream.append(" 0 0 cm\n");
+    aStream.append("/Im");
+    aStream.append(rEmit.m_nBitmapObject);
+    aStream.append(" Do\n");
+    aStream.append("Q");
+    aLine.append(aStream.getLength());
+
+    aLine.append(">>\nstream\n");
+    aLine.append(aStream.getStr());
+    aLine.append("\nendstream\nendobj\n\n");
+    CHECK_RETURN2(writeBuffer(aLine.getStr(), aLine.getLength()));
 }
 
 namespace
@@ -12010,75 +12070,28 @@ bool PDFWriterImpl::writeBitmapObject( BitmapEmit& rObject, bool bMask )
         return writeBitmapObject( aEmit, true );
     }
 
-    // Write the form XObject proxy for the image.
-    if (rObject.m_nFormObject > 0 && rObject.m_nEmbeddedObject > 0)
-    {
-        aLine.setLength(0);
-        if (!updateObject(rObject.m_nFormObject))
-            return false;
-
-        // Count /Matrix and /BBox.
-        // vcl::ImportPDF() works with 96 DPI so use the same values here, too.
-        sal_Int32 nOldDPIX = getReferenceDevice()->GetDPIX();
-        getReferenceDevice()->SetDPIX(96);
-        sal_Int32 nOldDPIY = getReferenceDevice()->GetDPIY();
-        getReferenceDevice()->SetDPIY(96);
-        Size aSize = getReferenceDevice()->PixelToLogic(rObject.m_aBitmap.GetPrefSize(), MapMode(m_aMapMode.GetMapUnit()));
-        getReferenceDevice()->SetDPIX(nOldDPIX);
-        getReferenceDevice()->SetDPIY(nOldDPIY);
-        double fScaleX = 1.0 / aSize.Width();
-        double fScaleY = 1.0 / aSize.Height();
-
-        // Now have all the info to write the form XObject.
-        aLine.append(rObject.m_nFormObject);
-        aLine.append(" 0 obj\n");
-        aLine.append("<< /Type /XObject");
-        aLine.append(" /Subtype /Form");
-        aLine.append(" /Resources << /XObject<</Im");
-        aLine.append(rObject.m_nObject);
-        aLine.append(" ");
-        aLine.append(rObject.m_nObject);
-        aLine.append(" 0 R>> >>");
-        aLine.append(" /Matrix [ ");
-        appendDouble(fScaleX, aLine);
-        aLine.append(" 0 0 ");
-        appendDouble(fScaleY, aLine);
-        aLine.append(" 0 0 ]");
-        aLine.append(" /BBox [ 0 0 ");
-        aLine.append(aSize.Width());
-        aLine.append(" ");
-        aLine.append(aSize.Height());
-        aLine.append(" ]\n");
-
-        // Write the reference dictionary.
-        aLine.append("/Ref<< /F << /Type /Filespec /F (<embedded file>) /EF << /F ");
-        aLine.append(rObject.m_nEmbeddedObject);
-        aLine.append(" 0 R >> >> /Page 0 >>\n");
-
-        aLine.append("/Length ");
-
-        OStringBuffer aStream;
-        aStream.append("q ");
-        aStream.append(aSize.Width());
-        aStream.append(" 0 0 ");
-        aStream.append(aSize.Height());
-        aStream.append(" 0 0 cm\n");
-        aStream.append("/Im");
-        aStream.append(rObject.m_nObject);
-        aStream.append(" Do\n");
-        aStream.append("Q");
-        aLine.append(aStream.getLength());
-
-        aLine.append(">>\nstream\n");
-        aLine.append(aStream.getStr());
-        aLine.append("\nendstream\nendobj\n\n");
-        CHECK_RETURN(writeBuffer(aLine.getStr(), aLine.getLength()));
-    }
+    writeReferenceXObject(rObject.m_aReferenceXObject);
 
     return true;
 }
 
-void PDFWriterImpl::drawJPGBitmap( SvStream& rDCTData, bool bIsTrueColor, const Size& rSizePixel, const Rectangle& rTargetArea, const Bitmap& rMask )
+void PDFWriterImpl::createEmbeddedFile(const Graphic& rGraphic, ReferenceXObjectEmit& rEmit, sal_Int32 nBitmapObject)
+{
+    if (!rGraphic.getPdfData().hasElements())
+        return;
+
+    // Store the original PDF data as an embedded file.
+    m_aEmbeddedFiles.push_back(PDFEmbeddedFile());
+    m_aEmbeddedFiles.back().m_nObject = createObject();
+    m_aEmbeddedFiles.back().m_aData = rGraphic.getPdfData();
+
+    rEmit.m_nFormObject = createObject();
+    rEmit.m_nEmbeddedObject = m_aEmbeddedFiles.back().m_nObject;
+    rEmit.m_nBitmapObject = nBitmapObject;
+    rEmit.m_aPixelSize = rGraphic.GetBitmap().GetPrefSize();
+}
+
+void PDFWriterImpl::drawJPGBitmap( SvStream& rDCTData, bool bIsTrueColor, const Size& rSizePixel, const Rectangle& rTargetArea, const Bitmap& rMask, const Graphic& rGraphic )
 {
     MARK( "drawJPGBitmap" );
 
@@ -12134,6 +12147,7 @@ void PDFWriterImpl::drawJPGBitmap( SvStream& rDCTData, bool bIsTrueColor, const
         rEmit.m_bTrueColor  = bIsTrueColor;
         if( !! rMask && rMask.GetSizePixel() == rSizePixel )
             rEmit.m_aMask   = rMask;
+        createEmbeddedFile(rGraphic, rEmit.m_aReferenceXObject, rEmit.m_nObject);
 
         it = m_aJPGs.begin();
     }
@@ -12149,7 +12163,8 @@ void PDFWriterImpl::drawJPGBitmap( SvStream& rDCTData, bool bIsTrueColor, const
     aLine.append( ' ' );
     m_aPages.back().appendPoint( rTargetArea.BottomLeft(), aLine );
     aLine.append( " cm\n/Im" );
-    aLine.append( it->m_nObject );
+    sal_Int32 nObject = it->m_aReferenceXObject.getObject();
+    aLine.append(nObject);
     aLine.append( " Do Q\n" );
     if( nCheckWidth == 0 || nCheckHeight == 0 )
     {
@@ -12163,8 +12178,8 @@ void PDFWriterImpl::drawJPGBitmap( SvStream& rDCTData, bool bIsTrueColor, const
 
     OStringBuffer aObjName( 16 );
     aObjName.append( "Im" );
-    aObjName.append( it->m_nObject );
-    pushResource( ResXObject, aObjName.makeStringAndClear(), it->m_nObject );
+    aObjName.append(nObject);
+    pushResource( ResXObject, aObjName.makeStringAndClear(), nObject );
 
 }
 
@@ -12187,7 +12202,7 @@ void PDFWriterImpl::drawBitmap( const Point& rDestPoint, const Size& rDestSize,
     aLine.append( ' ' );
     m_aPages.back().appendPoint( rDestPoint + Point( 0, rDestSize.Height()-1 ), aLine );
     aLine.append( " cm\n/Im" );
-    sal_Int32 nObject = rBitmap.getObject();
+    sal_Int32 nObject = rBitmap.m_aReferenceXObject.getObject();
     aLine.append(nObject);
     aLine.append( " Do Q\n" );
     if( nCheckWidth == 0 || nCheckHeight == 0 )
@@ -12238,22 +12253,13 @@ const PDFWriterImpl::BitmapEmit& PDFWriterImpl::createBitmapEmit( const BitmapEx
         m_aBitmaps.front().m_aID        = aID;
         m_aBitmaps.front().m_aBitmap    = aBitmap;
         m_aBitmaps.front().m_nObject    = createObject();
-        if (rGraphic.getPdfData().hasElements())
-        {
-            // Store the original PDF data as an embedded file.
-            m_aEmbeddedFiles.push_back(PDFEmbeddedFile());
-            m_aEmbeddedFiles.back().m_nObject = createObject();
-            m_aEmbeddedFiles.back().m_aData = rGraphic.getPdfData();
-
-            m_aBitmaps.front().m_nFormObject = createObject();
-            m_aBitmaps.front().m_nEmbeddedObject = m_aEmbeddedFiles.back().m_nObject;
-        }
+        createEmbeddedFile(rGraphic, m_aBitmaps.front().m_aReferenceXObject, m_aBitmaps.front().m_nObject);
         it = m_aBitmaps.begin();
     }
 
     OStringBuffer aObjName( 16 );
     aObjName.append( "Im" );
-    sal_Int32 nObject = it->getObject();
+    sal_Int32 nObject = it->m_aReferenceXObject.getObject();
     aObjName.append(nObject);
     pushResource( ResXObject, aObjName.makeStringAndClear(), nObject );
 
@@ -14103,21 +14109,12 @@ void PDFWriterImpl::MARK( const char* pString )
         emitComment( pString );
 }
 
-PDFWriterImpl::JPGEmit::JPGEmit(PDFWriterImpl::JPGEmit&& rOther)
-{
-    m_aID = rOther.m_aID;
-    m_pStream = std::move(rOther.m_pStream);
-    m_aMask = std::move(rOther.m_aMask);
-    m_nObject = rOther.m_nObject;
-    m_bTrueColor = rOther.m_bTrueColor;
-}
-
-sal_Int32 PDFWriterImpl::BitmapEmit::getObject() const
+sal_Int32 PDFWriterImpl::ReferenceXObjectEmit::getObject() const
 {
     if (m_nFormObject > 0)
         return m_nFormObject;
     else
-        return m_nObject;
+        return m_nBitmapObject;
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/gdi/pdfwriter_impl.hxx b/vcl/source/gdi/pdfwriter_impl.hxx
index 3c3eec8..ff2165a 100644
--- a/vcl/source/gdi/pdfwriter_impl.hxx
+++ b/vcl/source/gdi/pdfwriter_impl.hxx
@@ -190,20 +190,22 @@ public:
         }
     };
 
-    struct BitmapEmit
+    /// Contains information to emit a reference XObject.
+    struct ReferenceXObjectEmit
     {
-        BitmapID    m_aID;
-        BitmapEx    m_aBitmap;
-        sal_Int32   m_nObject;
         /// ID of the Form XObject, if any.
         sal_Int32 m_nFormObject;
-        /// ID of the embedded object, if m_nFormObject is used.
+        /// ID of the vector/embedded object, if m_nFormObject is used.
         sal_Int32 m_nEmbeddedObject;
-
-        BitmapEmit()
-            : m_nObject(0),
-              m_nFormObject(0),
-              m_nEmbeddedObject(0)
+        /// ID of the bitmap object, if m_nFormObject is used.
+        sal_Int32 m_nBitmapObject;
+        /// Size of the bitmap replacement, in pixels.
+        Size m_aPixelSize;
+
+        ReferenceXObjectEmit()
+            : m_nFormObject(0),
+              m_nEmbeddedObject(0),
+              m_nBitmapObject(0)
         {
         }
 
@@ -211,6 +213,19 @@ public:
         sal_Int32 getObject() const;
     };
 
+    struct BitmapEmit
+    {
+        BitmapID    m_aID;
+        BitmapEx    m_aBitmap;
+        sal_Int32   m_nObject;
+        ReferenceXObjectEmit m_aReferenceXObject;
+
+        BitmapEmit()
+            : m_nObject(0)
+        {
+        }
+    };
+
     struct JPGEmit
     {
         BitmapID            m_aID;
@@ -219,6 +234,7 @@ public:
         Bitmap              m_aMask;
         sal_Int32           m_nObject;
         bool                m_bTrueColor;
+        ReferenceXObjectEmit m_aReferenceXObject;
 
         JPGEmit()
             : m_pStream(nullptr)
@@ -834,6 +850,8 @@ i12626
     bool writeBitmapObject( BitmapEmit& rObject, bool bMask = false );
 
     void writeJPG( JPGEmit& rEmit );
+    /// Writes the form XObject proxy for the image.
+    void writeReferenceXObject(ReferenceXObjectEmit& rEmit);
 
     /* tries to find the bitmap by its id and returns its emit data if exists,
        else creates a new emit data block */
@@ -1203,7 +1221,9 @@ public:
 
     void drawBitmap( const Point& rDestPoint, const Size& rDestSize, const Bitmap& rBitmap, const Graphic& rGraphic );
     void drawBitmap( const Point& rDestPoint, const Size& rDestSize, const BitmapEx& rBitmap );
-    void drawJPGBitmap( SvStream& rDCTData, bool bIsTrueColor, const Size& rSizePixel, const Rectangle& rTargetArea, const Bitmap& rMask );
+    void drawJPGBitmap( SvStream& rDCTData, bool bIsTrueColor, const Size& rSizePixel, const Rectangle& rTargetArea, const Bitmap& rMask, const Graphic& rGraphic );
+    /// Stores the original PDF data from rGraphic as an embedded file.
+    void createEmbeddedFile(const Graphic& rGraphic, ReferenceXObjectEmit& rEmit, sal_Int32 nBitmapObject);
 
     void drawGradient( const Rectangle& rRect, const Gradient& rGradient );
     void drawHatch( const tools::PolyPolygon& rPolyPoly, const Hatch& rHatch );
diff --git a/vcl/source/gdi/pdfwriter_impl2.cxx b/vcl/source/gdi/pdfwriter_impl2.cxx
index 7302a94..af63e2c 100644
--- a/vcl/source/gdi/pdfwriter_impl2.cxx
+++ b/vcl/source/gdi/pdfwriter_impl2.cxx
@@ -243,7 +243,7 @@ void PDFWriterImpl::implWriteBitmapEx( const Point& i_rPoint, const Size& i_rSiz
                 }
             }
             if ( bUseJPGCompression )
-                m_rOuterFace.DrawJPGBitmap( aStrm, bTrueColorJPG, aSizePixel, Rectangle( aPoint, aSize ), aMask );
+                m_rOuterFace.DrawJPGBitmap( aStrm, bTrueColorJPG, aSizePixel, Rectangle( aPoint, aSize ), aMask, i_Graphic );
             else if ( aBitmapEx.IsTransparent() )
                 m_rOuterFace.DrawBitmapEx( aPoint, aSize, aBitmapEx );
             else
commit 8147a907a4082f9041821b0119dd86dbf175534f
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Wed Feb 22 15:31:28 2017 +0100

    tdf#106059 PDF export: create a reference XObject for PDF images
    
    If a reader is capable of showing reference XObjects, then it can show
    the original/vector PDF image instead of the bitmap fallback.
    
    Change-Id: Iac8a460c43ff7467e3a5fd8ee4cbf2179084335b
    (cherry picked from commit 6db0f1feb1d9931d2726dd11a889c58815710ce0)

diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index ff19664..bd65b6c 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -12011,7 +12011,7 @@ bool PDFWriterImpl::writeBitmapObject( BitmapEmit& rObject, bool bMask )
     }
 
     // Write the form XObject proxy for the image.
-    if (rObject.m_nFormObject > 0)
+    if (rObject.m_nFormObject > 0 && rObject.m_nEmbeddedObject > 0)
     {
         aLine.setLength(0);
         if (!updateObject(rObject.m_nFormObject))
@@ -12048,8 +12048,14 @@ bool PDFWriterImpl::writeBitmapObject( BitmapEmit& rObject, bool bMask )
         aLine.append(aSize.Width());
         aLine.append(" ");
         aLine.append(aSize.Height());
-        aLine.append(" ]");
-        aLine.append(" /Length ");
+        aLine.append(" ]\n");
+
+        // Write the reference dictionary.
+        aLine.append("/Ref<< /F << /Type /Filespec /F (<embedded file>) /EF << /F ");
+        aLine.append(rObject.m_nEmbeddedObject);
+        aLine.append(" 0 R >> >> /Page 0 >>\n");
+
+        aLine.append("/Length ");
 
         OStringBuffer aStream;
         aStream.append("q ");
@@ -12233,7 +12239,15 @@ const PDFWriterImpl::BitmapEmit& PDFWriterImpl::createBitmapEmit( const BitmapEx
         m_aBitmaps.front().m_aBitmap    = aBitmap;
         m_aBitmaps.front().m_nObject    = createObject();
         if (rGraphic.getPdfData().hasElements())
+        {
+            // Store the original PDF data as an embedded file.
+            m_aEmbeddedFiles.push_back(PDFEmbeddedFile());
+            m_aEmbeddedFiles.back().m_nObject = createObject();
+            m_aEmbeddedFiles.back().m_aData = rGraphic.getPdfData();
+
             m_aBitmaps.front().m_nFormObject = createObject();
+            m_aBitmaps.front().m_nEmbeddedObject = m_aEmbeddedFiles.back().m_nObject;
+        }
         it = m_aBitmaps.begin();
     }
 
diff --git a/vcl/source/gdi/pdfwriter_impl.hxx b/vcl/source/gdi/pdfwriter_impl.hxx
index df6b3dd..3c3eec8 100644
--- a/vcl/source/gdi/pdfwriter_impl.hxx
+++ b/vcl/source/gdi/pdfwriter_impl.hxx
@@ -197,10 +197,13 @@ public:
         sal_Int32   m_nObject;
         /// ID of the Form XObject, if any.
         sal_Int32 m_nFormObject;
+        /// ID of the embedded object, if m_nFormObject is used.
+        sal_Int32 m_nEmbeddedObject;
 
         BitmapEmit()
             : m_nObject(0),
-              m_nFormObject(0)
+              m_nFormObject(0),
+              m_nEmbeddedObject(0)
         {
         }
 
diff --git a/vcl/source/gdi/pdfwriter_impl2.cxx b/vcl/source/gdi/pdfwriter_impl2.cxx
index 9291488..7302a94 100644
--- a/vcl/source/gdi/pdfwriter_impl2.cxx
+++ b/vcl/source/gdi/pdfwriter_impl2.cxx
@@ -248,13 +248,6 @@ void PDFWriterImpl::implWriteBitmapEx( const Point& i_rPoint, const Size& i_rSiz
                 m_rOuterFace.DrawBitmapEx( aPoint, aSize, aBitmapEx );
             else
                 m_rOuterFace.DrawBitmap( aPoint, aSize, aBitmapEx.GetBitmap(), i_Graphic );
-
-            if (i_Graphic.getPdfData().hasElements())
-            {
-                m_aEmbeddedFiles.push_back(PDFEmbeddedFile());
-                m_aEmbeddedFiles.back().m_nObject = createObject();
-                m_aEmbeddedFiles.back().m_aData = i_Graphic.getPdfData();
-            }
         }
     }
 }
commit 1219584dfcdabf7f005557967717c3839e894243
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Wed Feb 22 14:51:16 2017 +0100

    tdf#106059 PDF export: set matrix and bbox for PDF images
    
    We still unconditionally refer to the bitmap, but now the correct
    /Matrix and /BBox is set along with the necessary scaling inside the
    stream, so that when there will be a vector image reference, it'll
    appear at the correct position / size.
    
    Change-Id: I9c13c11fe76995b3b3d31a135eeaa895ee0abb0d
    Reviewed-on: https://gerrit.libreoffice.org/34543
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    Tested-by: Jenkins <ci at libreoffice.org>
    (cherry picked from commit 57c5ad79609134e0ff0013a002cc80a570e81c20)

diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index d57271f..ff19664 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -12017,6 +12017,19 @@ bool PDFWriterImpl::writeBitmapObject( BitmapEmit& rObject, bool bMask )
         if (!updateObject(rObject.m_nFormObject))
             return false;
 
+        // Count /Matrix and /BBox.
+        // vcl::ImportPDF() works with 96 DPI so use the same values here, too.
+        sal_Int32 nOldDPIX = getReferenceDevice()->GetDPIX();
+        getReferenceDevice()->SetDPIX(96);
+        sal_Int32 nOldDPIY = getReferenceDevice()->GetDPIY();
+        getReferenceDevice()->SetDPIY(96);
+        Size aSize = getReferenceDevice()->PixelToLogic(rObject.m_aBitmap.GetPrefSize(), MapMode(m_aMapMode.GetMapUnit()));
+        getReferenceDevice()->SetDPIX(nOldDPIX);
+        getReferenceDevice()->SetDPIY(nOldDPIY);
+        double fScaleX = 1.0 / aSize.Width();
+        double fScaleY = 1.0 / aSize.Height();
+
+        // Now have all the info to write the form XObject.
         aLine.append(rObject.m_nFormObject);
         aLine.append(" 0 obj\n");
         aLine.append("<< /Type /XObject");
@@ -12026,13 +12039,28 @@ bool PDFWriterImpl::writeBitmapObject( BitmapEmit& rObject, bool bMask )
         aLine.append(" ");
         aLine.append(rObject.m_nObject);
         aLine.append(" 0 R>> >>");
-        aLine.append(" /BBox [ 0 0 1 1 ]");
+        aLine.append(" /Matrix [ ");
+        appendDouble(fScaleX, aLine);
+        aLine.append(" 0 0 ");
+        appendDouble(fScaleY, aLine);
+        aLine.append(" 0 0 ]");
+        aLine.append(" /BBox [ 0 0 ");
+        aLine.append(aSize.Width());
+        aLine.append(" ");
+        aLine.append(aSize.Height());
+        aLine.append(" ]");
         aLine.append(" /Length ");
 
         OStringBuffer aStream;
+        aStream.append("q ");
+        aStream.append(aSize.Width());
+        aStream.append(" 0 0 ");
+        aStream.append(aSize.Height());
+        aStream.append(" 0 0 cm\n");
         aStream.append("/Im");
         aStream.append(rObject.m_nObject);
-        aStream.append(" Do");
+        aStream.append(" Do\n");
+        aStream.append("Q");
         aLine.append(aStream.getLength());
 
         aLine.append(">>\nstream\n");
commit 16b131ec09ef8b6fa166ec14941858b694060116
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Wed Feb 22 09:49:58 2017 +0100

    vcl: use auto when initializing with a cast in pdfread
    
    Change-Id: Ic785ef3f767cf529dc51e4d49234145fc8d14f97
    Reviewed-on: https://gerrit.libreoffice.org/34535
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    Tested-by: Jenkins <ci at libreoffice.org>
    (cherry picked from commit af8c0696e56395d48f8d8d75a37ced1c58a5be17)

diff --git a/vcl/source/filter/ipdf/pdfread.cxx b/vcl/source/filter/ipdf/pdfread.cxx
index d7de71e..12d41af 100644
--- a/vcl/source/filter/ipdf/pdfread.cxx
+++ b/vcl/source/filter/ipdf/pdfread.cxx
@@ -62,8 +62,8 @@ bool generatePreview(SvStream& rStream, Graphic& rGraphic)
         return false;
 
     // Returned unit is points, convert that to pixel.
-    int nPageWidth = pointToPixel(FPDF_GetPageWidth(pPdfPage));
-    int nPageHeight = pointToPixel(FPDF_GetPageHeight(pPdfPage));
+    size_t nPageWidth = pointToPixel(FPDF_GetPageWidth(pPdfPage));
+    size_t nPageHeight = pointToPixel(FPDF_GetPageHeight(pPdfPage));
     FPDF_BITMAP pPdfBitmap = FPDFBitmap_Create(nPageWidth, nPageHeight, /*alpha=*/1);
     if (!pPdfBitmap)
         return false;
@@ -76,17 +76,17 @@ bool generatePreview(SvStream& rStream, Graphic& rGraphic)
     Bitmap aBitmap(Size(nPageWidth, nPageHeight), 32);
     {
         Bitmap::ScopedWriteAccess pWriteAccess(aBitmap);
-        const char* pPdfBuffer = static_cast<const char*>(FPDFBitmap_GetBuffer(pPdfBitmap));
+        auto pPdfBuffer = static_cast<const char*>(FPDFBitmap_GetBuffer(pPdfBitmap));
 #ifndef MACOSX
         std::memcpy(pWriteAccess->GetBuffer(), pPdfBuffer, nPageWidth * nPageHeight * 4);
 #else
         // ARGB -> BGRA
-        for (int nRow = 0; nRow < nPageHeight; ++nRow)
+        for (size_t nRow = 0; nRow < nPageHeight; ++nRow)
         {
             int nStride = FPDFBitmap_GetStride(pPdfBitmap);
             const char* pPdfLine = pPdfBuffer + (nStride * nRow);
             Scanline pRow = pWriteAccess->GetBuffer() + (nPageWidth * nRow * 4);
-            for (int nCol = 0; nCol < nPageWidth; ++nCol)
+            for (size_t nCol = 0; nCol < nPageWidth; ++nCol)
             {
                 pRow[nCol * 4] = pPdfLine[(nCol * 4) + 3];
                 pRow[(nCol * 4) + 1] = pPdfLine[(nCol * 4) + 2];
commit 26a4b6dcc7d04e8c0748cd7408afe8535b6df0e3
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Mon Feb 20 10:05:57 2017 +0100

    vcl PDF filter: avoid copy&paste
    
    By using a single ifdef block for the disable-pdfium case and by adding
    PDFWriterImpl::BitmapEmit::getObject().
    
    Change-Id: Ia21e16d469bc75e9b1a95342ed01caef3e91ccd9
    Reviewed-on: https://gerrit.libreoffice.org/34462
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    Tested-by: Jenkins <ci at libreoffice.org>
    (cherry picked from commit 711bc66ca34d3b1293a01fa7db16522b87055495)

diff --git a/vcl/source/filter/ipdf/pdfread.cxx b/vcl/source/filter/ipdf/pdfread.cxx
index d998402..d7de71e 100644
--- a/vcl/source/filter/ipdf/pdfread.cxx
+++ b/vcl/source/filter/ipdf/pdfread.cxx
@@ -37,12 +37,9 @@ double pointToPixel(double fPoint)
     return fPoint / 72 * 96;
 }
 
-#endif
-
 /// Does PDF to PNG conversion using pdfium.
 bool generatePreview(SvStream& rStream, Graphic& rGraphic)
 {
-#if HAVE_FEATURE_PDFIUM
     FPDF_LIBRARY_CONFIG aConfig;
     aConfig.version = 2;
     aConfig.m_pUserFontPaths = nullptr;
@@ -109,13 +106,18 @@ bool generatePreview(SvStream& rStream, Graphic& rGraphic)
     FPDF_ClosePage(pPdfPage);
     FPDF_CloseDocument(pPdfDocument);
     FPDF_DestroyLibrary();
+
+    return true;
+}
 #else
+bool generatePreview(SvStream& rStream, Graphic& rGraphic)
+{
     (void)rStream;
     (void)rGraphic;
-#endif
 
     return true;
 }
+#endif // HAVE_FEATURE_PDFIUM
 
 }
 
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index 3b514bd..d57271f 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -12153,7 +12153,7 @@ void PDFWriterImpl::drawBitmap( const Point& rDestPoint, const Size& rDestSize,
     aLine.append( ' ' );
     m_aPages.back().appendPoint( rDestPoint + Point( 0, rDestSize.Height()-1 ), aLine );
     aLine.append( " cm\n/Im" );
-    sal_Int32 nObject = rBitmap.m_nFormObject > 0 ? rBitmap.m_nFormObject : rBitmap.m_nObject;
+    sal_Int32 nObject = rBitmap.getObject();
     aLine.append(nObject);
     aLine.append( " Do Q\n" );
     if( nCheckWidth == 0 || nCheckHeight == 0 )
@@ -12211,7 +12211,7 @@ const PDFWriterImpl::BitmapEmit& PDFWriterImpl::createBitmapEmit( const BitmapEx
 
     OStringBuffer aObjName( 16 );
     aObjName.append( "Im" );
-    sal_Int32 nObject = it->m_nFormObject > 0 ? it->m_nFormObject : it->m_nObject;
+    sal_Int32 nObject = it->getObject();
     aObjName.append(nObject);
     pushResource( ResXObject, aObjName.makeStringAndClear(), nObject );
 
@@ -14069,4 +14069,13 @@ PDFWriterImpl::JPGEmit::JPGEmit(PDFWriterImpl::JPGEmit&& rOther)
     m_nObject = rOther.m_nObject;
     m_bTrueColor = rOther.m_bTrueColor;
 }
+
+sal_Int32 PDFWriterImpl::BitmapEmit::getObject() const
+{
+    if (m_nFormObject > 0)
+        return m_nFormObject;
+    else
+        return m_nObject;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/gdi/pdfwriter_impl.hxx b/vcl/source/gdi/pdfwriter_impl.hxx
index 7a17bf1..df6b3dd 100644
--- a/vcl/source/gdi/pdfwriter_impl.hxx
+++ b/vcl/source/gdi/pdfwriter_impl.hxx
@@ -203,6 +203,9 @@ public:
               m_nFormObject(0)
         {
         }
+
+        /// Returns the ID one should use when referring to this bitmap.
+        sal_Int32 getObject() const;
     };
 
     struct JPGEmit
commit 647b972bc1edbc5fabc8b71f96c4479cc2daf8e9
Author: Noel Grandin <noel.grandin at collabora.co.uk>
Date:   Wed Jan 11 09:48:18 2017 +0200

    new loplugin: useuniqueptr: vcl
    
    Reviewed-on: https://gerrit.libreoffice.org/32948
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Noel Grandin <noel.grandin at collabora.co.uk>
    (cherry picked from commit e8b49f09074fe184374bee5062715357427ae044)
    
    Conflicts:
    	include/vcl/graph.hxx
    	vcl/source/filter/ixbm/xbmread.cxx
    
    Change-Id: Idcbc8655108ff57c06c33bbcabd652387bf3c4ec

diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index 57e926a..3b514bd 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -2327,8 +2327,7 @@ void PDFWriterImpl::endPage()
             if( jpeg->m_pStream )
             {
                 writeJPG( *jpeg );
-                delete jpeg->m_pStream;
-                jpeg->m_pStream = nullptr;
+                jpeg->m_pStream.reset();
                 jpeg->m_aMask = Bitmap();
             }
         }
@@ -12093,11 +12092,11 @@ void PDFWriterImpl::drawJPGBitmap( SvStream& rDCTData, bool bIsTrueColor, const
         ;
     if( it == m_aJPGs.end() )
     {
-        m_aJPGs.push_front( JPGEmit() );
+        m_aJPGs.emplace( m_aJPGs.begin() );
         JPGEmit& rEmit = m_aJPGs.front();
         rEmit.m_nObject     = createObject();
         rEmit.m_aID         = aID;
-        rEmit.m_pStream     = pStream;
+        rEmit.m_pStream.reset( pStream );
         rEmit.m_bTrueColor  = bIsTrueColor;
         if( !! rMask && rMask.GetSizePixel() == rSizePixel )
             rEmit.m_aMask   = rMask;
@@ -14062,4 +14061,12 @@ void PDFWriterImpl::MARK( const char* pString )
         emitComment( pString );
 }
 
+PDFWriterImpl::JPGEmit::JPGEmit(PDFWriterImpl::JPGEmit&& rOther)
+{
+    m_aID = rOther.m_aID;
+    m_pStream = std::move(rOther.m_pStream);
+    m_aMask = std::move(rOther.m_aMask);
+    m_nObject = rOther.m_nObject;
+    m_bTrueColor = rOther.m_bTrueColor;
+}
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/gdi/pdfwriter_impl.hxx b/vcl/source/gdi/pdfwriter_impl.hxx
index 0516f24..7a17bf1 100644
--- a/vcl/source/gdi/pdfwriter_impl.hxx
+++ b/vcl/source/gdi/pdfwriter_impl.hxx
@@ -208,7 +208,8 @@ public:
     struct JPGEmit
     {
         BitmapID            m_aID;
-        SvMemoryStream*     m_pStream;
+        std::unique_ptr<SvMemoryStream>
+                            m_pStream;
         Bitmap              m_aMask;
         sal_Int32           m_nObject;
         bool                m_bTrueColor;
@@ -219,7 +220,8 @@ public:
             , m_bTrueColor(false)
         {
         }
-        ~JPGEmit() { delete m_pStream; }
+        JPGEmit(const JPGEmit&) = delete; // to keep MSVC2013 happy
+        JPGEmit(JPGEmit&&); // to keep MSVC2013 happy
     };
 
     struct GradientEmit
commit 3c522f652f80a2394d977c954a5acac1b597e6e6
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Tue Feb 14 08:53:47 2017 +0000

    Werror=unused-function in some configs
    
    Change-Id: I7cc4106063831f342c82c57b0476b9ac8c4b479a
    (cherry picked from commit 3713c17ee474af6bcb22c219ab81108411083fa0)

diff --git a/vcl/source/filter/ipdf/pdfread.cxx b/vcl/source/filter/ipdf/pdfread.cxx
index ee31af6..d998402 100644
--- a/vcl/source/filter/ipdf/pdfread.cxx
+++ b/vcl/source/filter/ipdf/pdfread.cxx
@@ -29,12 +29,16 @@ using namespace com::sun::star;
 namespace
 {
 
+#if HAVE_FEATURE_PDFIUM
+
 /// Convert to inch, then assume 96 DPI.
 double pointToPixel(double fPoint)
 {
     return fPoint / 72 * 96;
 }
 
+#endif
+
 /// Does PDF to PNG conversion using pdfium.
 bool generatePreview(SvStream& rStream, Graphic& rGraphic)
 {
commit e352169285ce4f45167a60557e969722895712d4
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Fri Feb 17 17:58:43 2017 +0100

    tdf#106059 PDF export: write form XObject proxy for PDF images
    
    PDF allows referencing a page of an existing (embedded) PDF file
    together with a fallback bitmap, but this is only allowed for form
    XObjects, not for image XObjects.
    
    So case the image is a PDF one, wrap the image XObject in a form
    XObject, that will allow later referring to the embedded PDF image.
    
    Change-Id: I30839dd6696f1fddd8ca2caa0d33123e90fcedbc
    Reviewed-on: https://gerrit.libreoffice.org/34376
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    Tested-by: Jenkins <ci at libreoffice.org>
    (cherry picked from commit 42c0dfbd6b08ecbc5893595a4100d572a3082d8a)


... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list