diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2017-03-29 17:25:55 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2017-03-30 07:18:04 +0000 |
commit | 92ddc0409c8d3276183afdee543d28e1c307c2c7 (patch) | |
tree | 666d382ac6db4842a8edbadcd8fd34621b568a10 /vcl | |
parent | 90305526ee48c855f9a2b3b4d730ea0bfb079119 (diff) |
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@collabora.co.uk>
Tested-by: Jenkins <ci@libreoffice.org>
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/source/gdi/pdfwriter_impl.cxx | 21 | ||||
-rw-r--r-- | vcl/source/gdi/pdfwriter_impl.hxx | 4 |
2 files changed, 17 insertions, 8 deletions
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 */ |