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

Miklos Vajna vmiklos at collabora.co.uk
Thu Mar 23 13:06:51 UTC 2017


 vcl/source/gdi/pdfwriter_impl.cxx |   63 +++++++++++++++++++++++++++++++++-----
 vcl/source/gdi/pdfwriter_impl.hxx |    2 +
 2 files changed, 58 insertions(+), 7 deletions(-)

New commits:
commit d27818c1f34b01190bf419c34d6a174f3cad7894
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Thu Mar 23 10:35:12 2017 +0100

    tdf#106693 vcl PDF export, norefxobj: copy page stream
    
    This gives correct result in very simple cases when the page stream is
    not compressed and it references no other objects from the original
    file.
    
    Change-Id: I11ed50180a256bdb5c587fd8927d21c925100a4d
    Reviewed-on: https://gerrit.libreoffice.org/35580
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    Tested-by: Jenkins <ci at libreoffice.org>

diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index a3d38b224340..9e40b3fe5539 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -71,6 +71,7 @@
 #include <vcl/strhelper.hxx>
 #include <vcl/svapp.hxx>
 #include <vcl/virdev.hxx>
+#include <vcl/filter/pdfdocument.hxx>
 
 #include "fontsubset.hxx"
 #include "outdev.h"
@@ -10911,13 +10912,59 @@ void PDFWriterImpl::writeReferenceXObject(ReferenceXObjectEmit& rEmit)
 
     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");
+    if (m_aContext.UseReferenceXObject)
+    {
+        // Reference XObject markup is used, just refer to the fallback bitmap
+        // here.
+        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");
+    }
+    else
+    {
+        // No reference XObject, include the original page stream.
+        // Reset line width to the default.
+        aStream.append(" 1 w\n");
+        SvMemoryStream aPDFStream;
+        aPDFStream.WriteBytes(rEmit.m_aPDFData.getArray(), rEmit.m_aPDFData.getLength());
+        aPDFStream.Seek(0);
+        filter::PDFDocument aPDFDocument;
+        if (!aPDFDocument.Read(aPDFStream))
+        {
+            SAL_WARN("vcl.pdfwriter", "PDFWriterImpl::writeReferenceXObject: reading the PDF document failed");
+            return;
+        }
+        std::vector<filter::PDFObjectElement*> aPages = aPDFDocument.GetPages();
+        if (aPages.empty() || !aPages[0])
+        {
+            SAL_WARN("vcl.pdfwriter", "PDFWriterImpl::writeReferenceXObject: no pages");
+            return;
+        }
+
+        filter::PDFObjectElement* pPageContents = aPages[0]->LookupObject("Contents");
+        if (!pPageContents)
+        {
+            SAL_WARN("vcl.pdfwriter", "PDFWriterImpl::writeReferenceXObject: page has no contents");
+            return;
+        }
+
+        filter::PDFStreamElement* pPageStream = pPageContents->GetStream();
+        if (!pPageStream)
+        {
+            SAL_WARN("vcl.pdfwriter", "PDFWriterImpl::writeReferenceXObject: contents has no stream");
+            return;
+        }
+
+        SvMemoryStream& rPageStream = pPageStream->GetMemory();
+
+        // Copy the original page stream to the end of the form XObject stream.
+        aStream.append(static_cast<const sal_Char*>(rPageStream.GetData()), rPageStream.GetSize());
+        aStream.append("\n");
+    }
     aStream.append("Q");
     aLine.append(aStream.getLength());
 
@@ -11263,6 +11310,8 @@ void PDFWriterImpl::createEmbeddedFile(const Graphic& rGraphic, ReferenceXObject
 
         rEmit.m_nEmbeddedObject = m_aEmbeddedFiles.back().m_nObject;
     }
+    else
+        rEmit.m_aPDFData = rGraphic.getPdfData();
 
     rEmit.m_nFormObject = createObject();
     rEmit.m_aPixelSize = rGraphic.GetBitmap().GetPrefSize();
diff --git a/vcl/source/gdi/pdfwriter_impl.hxx b/vcl/source/gdi/pdfwriter_impl.hxx
index 3e50c0bf09a2..b35c44050f46 100644
--- a/vcl/source/gdi/pdfwriter_impl.hxx
+++ b/vcl/source/gdi/pdfwriter_impl.hxx
@@ -219,6 +219,8 @@ public:
         sal_Int32 m_nBitmapObject;
         /// Size of the bitmap replacement, in pixels.
         Size m_aPixelSize;
+        /// PDF data from the graphic object, if not writing a reference XObject.
+        css::uno::Sequence<sal_Int8> m_aPDFData;
 
         ReferenceXObjectEmit()
             : m_nFormObject(0),


More information about the Libreoffice-commits mailing list