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

Miklos Vajna vmiklos at collabora.co.uk
Thu Mar 30 07:18:27 UTC 2017


 vcl/source/gdi/pdfwriter_impl.cxx |   21 +++++++++++++++------
 vcl/source/gdi/pdfwriter_impl.hxx |    4 ++--
 2 files changed, 17 insertions(+), 8 deletions(-)

New commits:
commit 92ddc0409c8d3276183afdee543d28e1c307c2c7
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Wed Mar 29 17:25:55 2017 +0200

    vcl PDF export, norefxobj: copy each object only once
    
    Even if they are referenced multiple times. This is especially important
    as objects can refer to each other, creating a cyclic graph. But it also
    makes the output a tiny bit smaller.
    
    Change-Id: I561ac319683a19a797282fe259cc68f3a4c50c3e
    Reviewed-on: https://gerrit.libreoffice.org/35855
    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 fd44f5d10e1b..50712b80086e 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -10858,9 +10858,16 @@ void PDFWriterImpl::writeJPG( JPGEmit& rObject )
     writeReferenceXObject(rObject.m_aReferenceXObject);
 }
 
-sal_Int32 PDFWriterImpl::copyExternalResource(SvMemoryStream& rDocBuffer, filter::PDFObjectElement& rObject)
+sal_Int32 PDFWriterImpl::copyExternalResource(SvMemoryStream& rDocBuffer, filter::PDFObjectElement& rObject, std::map<sal_Int32, sal_Int32>& rCopiedResources)
 {
+    auto it = rCopiedResources.find(rObject.GetObjectValue());
+    if (it != rCopiedResources.end())
+        // This resource was already copied once, nothing to do.
+        return it->second;
+
     sal_Int32 nObject = createObject();
+    // Remember what is the ID of this object in our output.
+    rCopiedResources[rObject.GetObjectValue()] = nObject;
     SAL_INFO("vcl.pdfwriter", "PDFWriterImpl::copyExternalResource: " << rObject.GetObjectValue() << " -> " << nObject);
 
     OStringBuffer aLine;
@@ -10883,7 +10890,7 @@ sal_Int32 PDFWriterImpl::copyExternalResource(SvMemoryStream& rDocBuffer, filter
                 if (pReferenced)
                 {
                     // Copy the referenced object.
-                    sal_Int32 nRef = copyExternalResource(rDocBuffer, *pReferenced);
+                    sal_Int32 nRef = copyExternalResource(rDocBuffer, *pReferenced, rCopiedResources);
 
                     sal_uInt64 nReferenceStart = pDictionary->GetKeyOffset(rItem.first) + rItem.first.getLength();
                     sal_uInt64 nReferenceEnd = pDictionary->GetKeyOffset(rItem.first) + pDictionary->GetKeyValueLength(rItem.first);
@@ -10945,7 +10952,7 @@ sal_Int32 PDFWriterImpl::copyExternalResource(SvMemoryStream& rDocBuffer, filter
                 if (pReferenced)
                 {
                     // Copy the referenced object.
-                    sal_Int32 nRef = copyExternalResource(rDocBuffer, *pReferenced);
+                    sal_Int32 nRef = copyExternalResource(rDocBuffer, *pReferenced, rCopiedResources);
 
                     sal_uInt64 nReferenceStart = pReference->GetObjectElement().GetLocation();
                     sal_uInt64 nReferenceEnd = pReference->GetOffset();
@@ -10994,7 +11001,7 @@ sal_Int32 PDFWriterImpl::copyExternalResource(SvMemoryStream& rDocBuffer, filter
     return nObject;
 }
 
-OString PDFWriterImpl::copyExternalResources(filter::PDFObjectElement& rPage, const OString& rKind)
+OString PDFWriterImpl::copyExternalResources(filter::PDFObjectElement& rPage, const OString& rKind, std::map<sal_Int32, sal_Int32>& rCopiedResources)
 {
     // A name - object ID map, IDs as they appear in our output, not the
     // original ones.
@@ -11024,7 +11031,7 @@ OString PDFWriterImpl::copyExternalResources(filter::PDFObjectElement& rPage, co
             continue;
 
         // Then copying over an object copy its dictionary and its stream.
-        sal_Int32 nObject = copyExternalResource(rDocBuffer, *pValue);
+        sal_Int32 nObject = copyExternalResource(rDocBuffer, *pValue, rCopiedResources);
         aRet[rItem.first] = nObject;
     }
 
@@ -11108,8 +11115,10 @@ void PDFWriterImpl::writeReferenceXObject(ReferenceXObjectEmit& rEmit)
             "Font",
             "XObject"
         };
+        // Maps from source object id (PDF image) to target object id (export result).
+        std::map<sal_Int32, sal_Int32> aCopiedResources;
         for (const auto& rKey : aKeys)
-            aLine.append(copyExternalResources(*pPage, rKey));
+            aLine.append(copyExternalResources(*pPage, rKey, aCopiedResources));
         aLine.append(">>");
         aLine.append(" /BBox [ 0 0 ");
         aLine.append(aSize.Width());
diff --git a/vcl/source/gdi/pdfwriter_impl.hxx b/vcl/source/gdi/pdfwriter_impl.hxx
index 57d125270caf..fad0d6c5bce0 100644
--- a/vcl/source/gdi/pdfwriter_impl.hxx
+++ b/vcl/source/gdi/pdfwriter_impl.hxx
@@ -854,10 +854,10 @@ i12626
     void writeReferenceXObject(ReferenceXObjectEmit& rEmit);
     /// Copies resources of a given kind from an external page to the output,
     /// returning what has to be included in the new resource dictionary.
-    OString copyExternalResources(filter::PDFObjectElement& rPage, const OString& rKind);
+    OString copyExternalResources(filter::PDFObjectElement& rPage, const OString& rKind, std::map<sal_Int32, sal_Int32>& rCopiedResources);
     /// Copies a single resource from an external document, returns the new
     /// object ID in our document.
-    sal_Int32 copyExternalResource(SvMemoryStream& rDocBuffer, filter::PDFObjectElement& rObject);
+    sal_Int32 copyExternalResource(SvMemoryStream& rDocBuffer, filter::PDFObjectElement& rObject, std::map<sal_Int32, sal_Int32>& rCopiedResources);
 
     /* tries to find the bitmap by its id and returns its emit data if exists,
        else creates a new emit data block */


More information about the Libreoffice-commits mailing list