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 16:59:33 +0200 |
commit | d6397d5b1bdfddf3724d0c3e2621f7960674322a (patch) | |
tree | 825619d64021ba483f471186abbf9616d97aa1b1 /vcl | |
parent | 10ec3d39c381547bbdf03f7ec3eebe7005ffdfe7 (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>
(cherry picked from commit 92ddc0409c8d3276183afdee543d28e1c307c2c7)
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 d132b3ff887e..51eed7262bbe 100644 --- a/vcl/source/gdi/pdfwriter_impl.cxx +++ b/vcl/source/gdi/pdfwriter_impl.cxx @@ -11697,9 +11697,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; @@ -11722,7 +11729,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); @@ -11784,7 +11791,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(); @@ -11833,7 +11840,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. @@ -11863,7 +11870,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; } @@ -11947,8 +11954,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 2329cbdec0bb..e1750ab8b73b 100644 --- a/vcl/source/gdi/pdfwriter_impl.hxx +++ b/vcl/source/gdi/pdfwriter_impl.hxx @@ -861,10 +861,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 */ |