[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.4' - vcl/inc vcl/source

Tomaž Vajngerl (via logerrit) logerrit at kemper.freedesktop.org
Fri Nov 13 10:08:44 UTC 2020


 vcl/inc/pdf/objectcopier.hxx       |    5 +
 vcl/source/gdi/pdfobjectcopier.cxx |  162 +++++++++++++------------------------
 2 files changed, 63 insertions(+), 104 deletions(-)

New commits:
commit e979b4ff044a0325157f24c8bb235dd4df78c9ba
Author:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Mon Nov 9 19:16:27 2020 +0100
Commit:     Andras Timar <andras.timar at collabora.com>
CommitDate: Fri Nov 13 11:08:00 2020 +0100

    pdf: improve PDFObjectCopier, copy arrays/dicts recursively
    
    Change-Id: Ia2f8d86ae012b530f3e9c39842bb75ef8ca27718
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/105779
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
    Reviewed-by: Andras Timar <andras.timar at collabora.com>

diff --git a/vcl/inc/pdf/objectcopier.hxx b/vcl/inc/pdf/objectcopier.hxx
index 487d03186682..50c123eeaf42 100644
--- a/vcl/inc/pdf/objectcopier.hxx
+++ b/vcl/inc/pdf/objectcopier.hxx
@@ -25,6 +25,7 @@ class PDFObjectContainer;
 namespace filter
 {
 class PDFObjectElement;
+class PDFElement;
 }
 
 /// Copies objects from one PDF file into an other one.
@@ -32,6 +33,10 @@ class VCL_DLLPUBLIC PDFObjectCopier
 {
     PDFObjectContainer& m_rContainer;
 
+    void copyRecursively(OStringBuffer& rLine, filter::PDFElement* pInputElement,
+                         SvMemoryStream& rDocBuffer,
+                         std::map<sal_Int32, sal_Int32>& rCopiedResources);
+
 public:
     PDFObjectCopier(PDFObjectContainer& rContainer);
 
diff --git a/vcl/source/gdi/pdfobjectcopier.cxx b/vcl/source/gdi/pdfobjectcopier.cxx
index 129a4c8bda35..4e5575c25952 100644
--- a/vcl/source/gdi/pdfobjectcopier.cxx
+++ b/vcl/source/gdi/pdfobjectcopier.cxx
@@ -26,6 +26,52 @@ PDFObjectCopier::PDFObjectCopier(PDFObjectContainer& rContainer)
 {
 }
 
+void PDFObjectCopier::copyRecursively(OStringBuffer& rLine, filter::PDFElement* pInputElement,
+                                      SvMemoryStream& rDocBuffer,
+                                      std::map<sal_Int32, sal_Int32>& rCopiedResources)
+{
+    if (auto pReference = dynamic_cast<filter::PDFReferenceElement*>(pInputElement))
+    {
+        filter::PDFObjectElement* pReferenced = pReference->LookupObject();
+        if (pReferenced)
+        {
+            // Copy the referenced object.
+            sal_Int32 nRef = copyExternalResource(rDocBuffer, *pReferenced, rCopiedResources);
+
+            // Write the updated reference.
+            rLine.append(nRef);
+            rLine.append(" 0 R");
+        }
+    }
+    else if (auto pInputArray = dynamic_cast<filter::PDFArrayElement*>(pInputElement))
+    {
+        rLine.append("[ ");
+        for (auto pElement : pInputArray->GetElements())
+        {
+            copyRecursively(rLine, pElement, rDocBuffer, rCopiedResources);
+            rLine.append(" ");
+        }
+        rLine.append("] ");
+    }
+    else if (auto pInputDictionary = dynamic_cast<filter::PDFDictionaryElement*>(pInputElement))
+    {
+        rLine.append("<< ");
+        for (auto pPair : pInputDictionary->GetItems())
+        {
+            rLine.append("/");
+            rLine.append(pPair.first);
+            rLine.append(" ");
+            copyRecursively(rLine, pPair.second, rDocBuffer, rCopiedResources);
+            rLine.append(" ");
+        }
+        rLine.append(">> ");
+    }
+    else
+    {
+        pInputElement->writeString(rLine);
+    }
+}
+
 sal_Int32 PDFObjectCopier::copyExternalResource(SvMemoryStream& rDocBuffer,
                                                 filter::PDFObjectElement& rObject,
                                                 std::map<sal_Int32, sal_Int32>& rCopiedResources)
@@ -50,63 +96,20 @@ sal_Int32 PDFObjectCopier::copyExternalResource(SvMemoryStream& rDocBuffer,
     OStringBuffer aLine;
     aLine.append(nObject);
     aLine.append(" 0 obj\n");
+
     if (rObject.GetDictionary())
     {
-        aLine.append("<<");
+        aLine.append("<< ");
 
-        // Complex case: can't copy the dictionary byte array as is, as it may contain references.
-        bool bDone = false;
-        sal_uInt64 nCopyStart = 0;
-        for (auto pReference : rObject.GetDictionaryReferences())
+        for (auto const& rPair : rObject.GetDictionaryItems())
         {
-            if (pReference)
-            {
-                filter::PDFObjectElement* pReferenced = pReference->LookupObject();
-                if (pReferenced)
-                {
-                    // Copy the referenced object.
-                    sal_Int32 nRef
-                        = copyExternalResource(rDocBuffer, *pReferenced, rCopiedResources);
-
-                    sal_uInt64 nReferenceStart = pReference->GetObjectElement().GetLocation();
-                    sal_uInt64 nReferenceEnd = pReference->GetOffset();
-                    sal_uInt64 nOffset = 0;
-                    if (nCopyStart == 0)
-                        // Dict start -> reference start.
-                        nOffset = rObject.GetDictionaryOffset();
-                    else
-                        // Previous reference end -> reference start.
-                        nOffset = nCopyStart;
-                    aLine.append(static_cast<const char*>(pObjectStream->GetData()) + nOffset,
-                                 nReferenceStart - nOffset);
-                    // Write the updated reference.
-                    aLine.append(" ");
-                    aLine.append(nRef);
-                    aLine.append(" 0 R");
-                    // Start copying here next time.
-                    nCopyStart = nReferenceEnd;
-
-                    bDone = true;
-                }
-            }
+            aLine.append("/");
+            aLine.append(rPair.first);
+            aLine.append(" ");
+            copyRecursively(aLine, rPair.second, rDocBuffer, rCopiedResources);
+            aLine.append(" ");
         }
 
-        if (bDone)
-        {
-            // Copy the last part here, in the complex case.
-            sal_uInt64 nDictEnd = rObject.GetDictionaryOffset() + rObject.GetDictionaryLength();
-            const sal_Int32 nLen = nDictEnd - nCopyStart;
-            if (nLen < 0)
-                SAL_WARN("vcl.pdfwriter", "copyExternalResource() failed");
-            else
-                aLine.append(static_cast<const char*>(pObjectStream->GetData()) + nCopyStart, nLen);
-        }
-        else
-            // Can copy it as-is.
-            aLine.append(static_cast<const char*>(pObjectStream->GetData())
-                             + rObject.GetDictionaryOffset(),
-                         rObject.GetDictionaryLength());
-
         aLine.append(">>\n");
     }
 
@@ -120,64 +123,15 @@ sal_Int32 PDFObjectCopier::copyExternalResource(SvMemoryStream& rDocBuffer,
 
     if (filter::PDFArrayElement* pArray = rObject.GetArray())
     {
-        aLine.append("[");
+        aLine.append("[ ");
 
         const std::vector<filter::PDFElement*>& rElements = pArray->GetElements();
-        bool bDone = false;
-        // Complex case: can't copy the array byte array as is, as it may contain references.
-        sal_uInt64 nCopyStart = 0;
-        for (const auto pElement : rElements)
-        {
-            auto pReference = dynamic_cast<filter::PDFReferenceElement*>(pElement);
-            if (pReference)
-            {
-                filter::PDFObjectElement* pReferenced = pReference->LookupObject();
-                if (pReferenced)
-                {
-                    // Copy the referenced object.
-                    sal_Int32 nRef
-                        = copyExternalResource(rDocBuffer, *pReferenced, rCopiedResources);
-
-                    sal_uInt64 nReferenceStart = pReference->GetObjectElement().GetLocation();
-                    sal_uInt64 nReferenceEnd = pReference->GetOffset();
-                    sal_uInt64 nOffset = 0;
-                    if (nCopyStart == 0)
-                        // Array start -> reference start.
-                        nOffset = rObject.GetArrayOffset();
-                    else
-                        // Previous reference end -> reference start.
-                        nOffset = nCopyStart;
-                    aLine.append(static_cast<const char*>(pObjectStream->GetData()) + nOffset,
-                                 nReferenceStart - nOffset);
-
-                    // Write the updated reference.
-                    aLine.append(" ");
-                    aLine.append(nRef);
-                    aLine.append(" 0 R");
-                    // Start copying here next time.
-                    nCopyStart = nReferenceEnd;
-
-                    bDone = true;
-                }
-            }
-        }
 
-        if (bDone)
+        for (auto const& pElement : rElements)
         {
-            // Copy the last part here, in the complex case.
-            sal_uInt64 nArrEnd = rObject.GetArrayOffset() + rObject.GetArrayLength();
-            const sal_Int32 nLen = nArrEnd - nCopyStart;
-            if (nLen < 0)
-                SAL_WARN("vcl.pdfwriter", "copyExternalResource() failed");
-            else
-                aLine.append(static_cast<const char*>(pObjectStream->GetData()) + nCopyStart, nLen);
+            copyRecursively(aLine, pElement, rDocBuffer, rCopiedResources);
+            aLine.append(" ");
         }
-        else
-            // Can copy it as-is.
-            aLine.append(static_cast<const char*>(pObjectStream->GetData())
-                             + rObject.GetArrayOffset(),
-                         rObject.GetArrayLength());
-
         aLine.append("]\n");
     }
 


More information about the Libreoffice-commits mailing list