diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2020-06-19 09:51:58 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2020-06-19 10:48:46 +0200 |
commit | 3bb145bd4665a871491b08f75057223bab798d45 (patch) | |
tree | f7e6e80155a45981c9de38927a9b892cad1fca83 /vcl | |
parent | 17f47b3972301273716466656e775f3f09d681d8 (diff) |
sd signature line: extract page resource / content copy code
So the "sign existing pdf" code can reuse it.
Change-Id: I63a811f0c6f2bc2eeb29507aff9bc35e92a081cd
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/96617
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/inc/pdf/objectcopier.hxx | 9 | ||||
-rw-r--r-- | vcl/source/gdi/pdfobjectcopier.cxx | 68 | ||||
-rw-r--r-- | vcl/source/gdi/pdfwriter_impl.cxx | 54 |
3 files changed, 78 insertions, 53 deletions
diff --git a/vcl/inc/pdf/objectcopier.hxx b/vcl/inc/pdf/objectcopier.hxx index 5372019a6fe9..364fffbf1548 100644 --- a/vcl/inc/pdf/objectcopier.hxx +++ b/vcl/inc/pdf/objectcopier.hxx @@ -10,7 +10,9 @@ #pragma once #include <map> +#include <vector> +#include <rtl/strbuf.hxx> #include <rtl/string.hxx> #include <sal/types.h> #include <vcl/dllapi.h> @@ -42,6 +44,13 @@ public: /// object ID in our document. sal_Int32 copyExternalResource(SvMemoryStream& rDocBuffer, filter::PDFObjectElement& rObject, std::map<sal_Int32, sal_Int32>& rCopiedResources); + + /// Copies resources of pPage into rLine. + void copyPageResources(filter::PDFObjectElement* pPage, OStringBuffer& rLine); + + /// Copies page one or more page streams from rContentStreams into rStream. + static sal_Int32 copyPageStreams(std::vector<filter::PDFObjectElement*>& rContentStreams, + SvMemoryStream& rStream, bool& rCompressed); }; } diff --git a/vcl/source/gdi/pdfobjectcopier.cxx b/vcl/source/gdi/pdfobjectcopier.cxx index c5ff2eecab19..5e54ee68c289 100644 --- a/vcl/source/gdi/pdfobjectcopier.cxx +++ b/vcl/source/gdi/pdfobjectcopier.cxx @@ -13,9 +13,12 @@ #include <sal/log.hxx> #include <sal/types.h> #include <tools/stream.hxx> +#include <tools/zcodec.hxx> #include <vcl/filter/pdfdocument.hxx> #include <vcl/filter/pdfobjectcontainer.hxx> +#include "pdfwriter_impl.hxx" + namespace vcl { PDFObjectCopier::PDFObjectCopier(PDFObjectContainer& rContainer) @@ -35,8 +38,8 @@ sal_Int32 PDFObjectCopier::copyExternalResource(SvMemoryStream& rDocBuffer, sal_Int32 nObject = m_rContainer.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); + SAL_INFO("vcl.pdfwriter", "PDFObjectCopier::copyExternalResource: " << rObject.GetObjectValue() + << " -> " << nObject); OStringBuffer aLine; aLine.append(nObject); @@ -267,6 +270,67 @@ OString PDFObjectCopier::copyExternalResources(filter::PDFObjectElement& rPage, return sRet.makeStringAndClear(); } + +void PDFObjectCopier::copyPageResources(filter::PDFObjectElement* pPage, OStringBuffer& rLine) +{ + // Maps from source object id (PDF image) to target object id (export result). + std::map<sal_Int32, sal_Int32> aCopiedResources; + + rLine.append(" /Resources <<"); + static const std::initializer_list<OString> aKeys + = { "ColorSpace", "ExtGState", "Font", "XObject", "Shading" }; + for (const auto& rKey : aKeys) + { + rLine.append(copyExternalResources(*pPage, rKey, aCopiedResources)); + } + rLine.append(">>"); +} + +sal_Int32 PDFObjectCopier::copyPageStreams(std::vector<filter::PDFObjectElement*>& rContentStreams, + SvMemoryStream& rStream, bool& rCompressed) +{ + for (auto pContent : rContentStreams) + { + filter::PDFStreamElement* pPageStream = pContent->GetStream(); + if (!pPageStream) + { + SAL_WARN("vcl.pdfwriter", "PDFObjectCopier::copyPageStreams: contents has no stream"); + continue; + } + + SvMemoryStream& rPageStream = pPageStream->GetMemory(); + + auto pFilter = dynamic_cast<filter::PDFNameElement*>(pContent->Lookup("Filter")); + if (pFilter) + { + if (pFilter->GetValue() != "FlateDecode") + { + continue; + } + + SvMemoryStream aMemoryStream; + ZCodec aZCodec; + rPageStream.Seek(0); + aZCodec.BeginCompression(); + aZCodec.Decompress(rPageStream, aMemoryStream); + if (!aZCodec.EndCompression()) + { + SAL_WARN("vcl.pdfwriter", "PDFObjectCopier::copyPageStreams: decompression failed"); + continue; + } + + rStream.WriteBytes(aMemoryStream.GetData(), aMemoryStream.GetSize()); + } + else + { + rStream.WriteBytes(rPageStream.GetData(), rPageStream.GetSize()); + } + } + + rCompressed = PDFWriterImpl::compressStream(&rStream); + + return rStream.Tell(); +} } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx index 44c21afb2214..47a697785564 100644 --- a/vcl/source/gdi/pdfwriter_impl.cxx +++ b/vcl/source/gdi/pdfwriter_impl.cxx @@ -8417,9 +8417,6 @@ void PDFWriterImpl::writeReferenceXObject(ReferenceXObjectEmit& rEmit) return; } - // Maps from source object id (PDF image) to target object id (export result). - std::map<sal_Int32, sal_Int32> aCopiedResources; - nWrappedFormObject = createObject(); // Write the form XObject wrapped below. This is a separate object from // the wrapper, this way there is no need to alter the stream contents. @@ -8457,19 +8454,8 @@ void PDFWriterImpl::writeReferenceXObject(ReferenceXObjectEmit& rEmit) } } - aLine.append(" /Resources <<"); - static const std::initializer_list<OString> aKeys = - { - "ColorSpace", - "ExtGState", - "Font", - "XObject", - "Shading" - }; PDFObjectCopier aCopier(*this); - for (const auto& rKey : aKeys) - aLine.append(aCopier.copyExternalResources(*pPage, rKey, aCopiedResources)); - aLine.append(">>"); + aCopier.copyPageResources(pPage, aLine); aLine.append(" /BBox [ 0 0 "); aLine.append(nWidth); aLine.append(" "); @@ -8481,42 +8467,8 @@ void PDFWriterImpl::writeReferenceXObject(ReferenceXObjectEmit& rEmit) aLine.append(" /Length "); SvMemoryStream aStream; - for (auto pContent : aContentStreams) - { - filter::PDFStreamElement* pPageStream = pContent->GetStream(); - if (!pPageStream) - { - SAL_WARN("vcl.pdfwriter", "PDFWriterImpl::writeReferenceXObject: contents has no stream"); - continue; - } - - SvMemoryStream& rPageStream = pPageStream->GetMemory(); - - auto pFilter = dynamic_cast<filter::PDFNameElement*>(pContent->Lookup("Filter")); - if (pFilter) - { - if (pFilter->GetValue() != "FlateDecode") - continue; - - SvMemoryStream aMemoryStream; - ZCodec aZCodec; - rPageStream.Seek(0); - aZCodec.BeginCompression(); - aZCodec.Decompress(rPageStream, aMemoryStream); - if (!aZCodec.EndCompression()) - { - SAL_WARN("vcl.pdfwriter", "PDFWriterImpl::writeReferenceXObject: decompression failed"); - continue; - } - - aStream.WriteBytes(aMemoryStream.GetData(), aMemoryStream.GetSize()); - } - else - aStream.WriteBytes(rPageStream.GetData(), rPageStream.GetSize()); - } - - compressStream(&aStream); - sal_Int32 nLength = aStream.Tell(); + bool bCompressed = false; + sal_Int32 nLength = PDFObjectCopier::copyPageStreams(aContentStreams, aStream, bCompressed); aLine.append(nLength); aLine.append(">>\nstream\n"); |