summaryrefslogtreecommitdiff
path: root/vcl/source/gdi
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2017-03-29 17:25:55 +0200
committerMiklos Vajna <vmiklos@collabora.co.uk>2017-03-30 07:18:04 +0000
commit92ddc0409c8d3276183afdee543d28e1c307c2c7 (patch)
tree666d382ac6db4842a8edbadcd8fd34621b568a10 /vcl/source/gdi
parent90305526ee48c855f9a2b3b4d730ea0bfb079119 (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/source/gdi')
-rw-r--r--vcl/source/gdi/pdfwriter_impl.cxx21
-rw-r--r--vcl/source/gdi/pdfwriter_impl.hxx4
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 */