[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