diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2020-06-18 12:12:52 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2020-06-18 14:36:29 +0200 |
commit | 8277073ce3e33788d93b3df490a8f03d1814863b (patch) | |
tree | 51094d52c1a629ddbb6d3e24d9b583ba74e5f042 /vcl | |
parent | a60a5e769a407fa13b087a111123ceff5a96bc03 (diff) |
sd signature line: extract copyExternalResources() from the pdf export code
Because I would like to reuse this in the "sign existing pdf" code, in
vcl::filter::PDFDocument::WriteAppearanceObject().
Change-Id: Ia5e5c1e452bb0d0486bde2a082375b5131eea8c7
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/96595
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/Library_vcl.mk | 1 | ||||
-rw-r--r-- | vcl/inc/pdf/objectcontainer.hxx | 36 | ||||
-rw-r--r-- | vcl/inc/pdf/objectcopier.hxx | 48 | ||||
-rw-r--r-- | vcl/source/gdi/pdfobjectcopier.cxx | 273 | ||||
-rw-r--r-- | vcl/source/gdi/pdfwriter_impl.cxx | 233 | ||||
-rw-r--r-- | vcl/source/gdi/pdfwriter_impl.hxx | 22 |
6 files changed, 368 insertions, 245 deletions
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk index 430cc4d9c0b5..b294042fb90b 100644 --- a/vcl/Library_vcl.mk +++ b/vcl/Library_vcl.mk @@ -297,6 +297,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\ vcl/source/gdi/pdfwriter \ vcl/source/gdi/pdfwriter_impl2 \ vcl/source/gdi/pdfwriter_impl \ + vcl/source/gdi/pdfobjectcopier \ vcl/source/gdi/print2 \ vcl/source/gdi/print3 \ vcl/source/gdi/print \ diff --git a/vcl/inc/pdf/objectcontainer.hxx b/vcl/inc/pdf/objectcontainer.hxx new file mode 100644 index 000000000000..ca4898737e10 --- /dev/null +++ b/vcl/inc/pdf/objectcontainer.hxx @@ -0,0 +1,36 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include <sal/types.h> + +namespace vcl +{ +/// Allows creating, updating and writing PDF objects in a container. +class SAL_NO_VTABLE SAL_DLLPUBLIC_RTTI PDFObjectContainer +{ +public: + /* adds an entry to m_aObjects and returns its index+1, + * sets the offset to ~0 + */ + virtual sal_Int32 createObject() = 0; + /* sets the offset of object n to the current position of output file+1 + */ + virtual bool updateObject(sal_Int32 n) = 0; + + // Write pBuffer to the end of the output. + virtual bool writeBuffer(const void* pBuffer, sal_uInt64 nBytes) = 0; + +protected: + ~PDFObjectContainer() noexcept = default; +}; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/pdf/objectcopier.hxx b/vcl/inc/pdf/objectcopier.hxx new file mode 100644 index 000000000000..b99fbb4886b3 --- /dev/null +++ b/vcl/inc/pdf/objectcopier.hxx @@ -0,0 +1,48 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include <map> + +#include <rtl/string.hxx> +#include <sal/types.h> +#include <vcl/dllapi.h> + +class SvMemoryStream; + +namespace vcl +{ +class PDFObjectContainer; +namespace filter +{ +class PDFObjectElement; +} + +/// Copies objects from one PDF file into an other one. +class VCL_DLLPUBLIC PDFObjectCopier +{ + PDFObjectContainer& m_rContainer; + +public: + PDFObjectCopier(PDFObjectContainer& rContainer); + + /// 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, + 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, + std::map<sal_Int32, sal_Int32>& rCopiedResources); +}; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/gdi/pdfobjectcopier.cxx b/vcl/source/gdi/pdfobjectcopier.cxx new file mode 100644 index 000000000000..4ba93b3a746d --- /dev/null +++ b/vcl/source/gdi/pdfobjectcopier.cxx @@ -0,0 +1,273 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <pdf/objectcopier.hxx> + +#include <rtl/strbuf.hxx> +#include <sal/log.hxx> +#include <sal/types.h> +#include <tools/stream.hxx> +#include <vcl/filter/pdfdocument.hxx> + +#include <pdf/objectcontainer.hxx> + +namespace vcl +{ +PDFObjectCopier::PDFObjectCopier(PDFObjectContainer& rContainer) + : m_rContainer(rContainer) +{ +} + +sal_Int32 PDFObjectCopier::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 = 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); + + OStringBuffer aLine; + aLine.append(nObject); + aLine.append(" 0 obj\n"); + if (rObject.GetDictionary()) + { + 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()) + { + 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*>(rDocBuffer.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) + { + // 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*>(rDocBuffer.GetData()) + nCopyStart, nLen); + } + else + // Can copy it as-is. + aLine.append(static_cast<const char*>(rDocBuffer.GetData()) + + rObject.GetDictionaryOffset(), + rObject.GetDictionaryLength()); + + aLine.append(">>\n"); + } + + if (filter::PDFStreamElement* pStream = rObject.GetStream()) + { + aLine.append("stream\n"); + SvMemoryStream& rStream = pStream->GetMemory(); + aLine.append(static_cast<const char*>(rStream.GetData()), rStream.GetSize()); + aLine.append("\nendstream\n"); + } + + if (filter::PDFArrayElement* pArray = rObject.GetArray()) + { + 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*>(rDocBuffer.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) + { + // 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*>(rDocBuffer.GetData()) + nCopyStart, nLen); + } + else + // Can copy it as-is. + aLine.append(static_cast<const char*>(rDocBuffer.GetData()) + rObject.GetArrayOffset(), + rObject.GetArrayLength()); + + aLine.append("]\n"); + } + + // If the object has a number element outside a dictionary or array, copy that. + if (filter::PDFNumberElement* pNumber = rObject.GetNumberElement()) + { + aLine.append(static_cast<const char*>(rDocBuffer.GetData()) + pNumber->GetLocation(), + pNumber->GetLength()); + aLine.append("\n"); + } + + aLine.append("endobj\n\n"); + + // We have the whole object, now write it to the output. + if (!m_rContainer.updateObject(nObject)) + return -1; + if (!m_rContainer.writeBuffer(aLine.getStr(), aLine.getLength())) + return -1; + + return nObject; +} + +OString PDFObjectCopier::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. + std::map<OString, sal_Int32> aRet; + + // Get the rKind subset of the resource dictionary. + std::map<OString, filter::PDFElement*> aItems; + if (auto pResources = dynamic_cast<filter::PDFDictionaryElement*>(rPage.Lookup("Resources"))) + { + // Resources is a direct dictionary. + filter::PDFElement* pLookup = pResources->LookupElement(rKind); + if (auto pDictionary = dynamic_cast<filter::PDFDictionaryElement*>(pLookup)) + { + // rKind is an inline dictionary. + aItems = pDictionary->GetItems(); + } + else if (auto pReference = dynamic_cast<filter::PDFReferenceElement*>(pLookup)) + { + // rKind refers to a dictionary. + filter::PDFObjectElement* pReferenced = pReference->LookupObject(); + if (!pReferenced) + { + return OString(); + } + + aItems = pReferenced->GetDictionaryItems(); + } + } + else if (filter::PDFObjectElement* pPageResources = rPage.LookupObject("Resources")) + { + // Resources is an indirect object. + filter::PDFElement* pValue = pPageResources->Lookup(rKind); + if (auto pDictionary = dynamic_cast<filter::PDFDictionaryElement*>(pValue)) + // Kind is a direct dictionary. + aItems = pDictionary->GetItems(); + else if (filter::PDFObjectElement* pObject = pPageResources->LookupObject(rKind)) + // Kind is an indirect object. + aItems = pObject->GetDictionaryItems(); + } + if (aItems.empty()) + return OString(); + + SvMemoryStream& rDocBuffer = rPage.GetDocument().GetEditBuffer(); + + for (const auto& rItem : aItems) + { + // For each item copy it over to our output then insert it into aRet. + auto pReference = dynamic_cast<filter::PDFReferenceElement*>(rItem.second); + if (!pReference) + continue; + + filter::PDFObjectElement* pValue = pReference->LookupObject(); + if (!pValue) + continue; + + // Then copying over an object copy its dictionary and its stream. + sal_Int32 nObject = copyExternalResource(rDocBuffer, *pValue, rCopiedResources); + aRet[rItem.first] = nObject; + } + + // Build the dictionary entry string. + OStringBuffer sRet("/" + rKind + "<<"); + for (const auto& rPair : aRet) + { + sRet.append("/") + .append(rPair.first) + .append(" ") + .append(OString::number(rPair.second)) + .append(" 0 R"); + } + sRet.append(">>"); + + return sRet.makeStringAndClear(); +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx index 304ae011ee72..44c21afb2214 100644 --- a/vcl/source/gdi/pdfwriter_impl.cxx +++ b/vcl/source/gdi/pdfwriter_impl.cxx @@ -76,6 +76,7 @@ #include <bitmapwriteaccess.hxx> #include <impglyphitem.hxx> #include <pdf/XmpMetadata.hxx> +#include <pdf/objectcopier.hxx> #include "pdfwriter_impl.hxx" @@ -8344,235 +8345,6 @@ void PDFWriterImpl::writeJPG( JPGEmit& rObject ) writeReferenceXObject(rObject.m_aReferenceXObject); } -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; - aLine.append(nObject); - aLine.append(" 0 obj\n"); - if (rObject.GetDictionary()) - { - 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()) - { - 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*>(rDocBuffer.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) - { - // 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*>(rDocBuffer.GetData()) + nCopyStart, nLen); - } - else - // Can copy it as-is. - aLine.append(static_cast<const char*>(rDocBuffer.GetData()) + rObject.GetDictionaryOffset(), rObject.GetDictionaryLength()); - - aLine.append(">>\n"); - } - - if (filter::PDFStreamElement* pStream = rObject.GetStream()) - { - aLine.append("stream\n"); - SvMemoryStream& rStream = pStream->GetMemory(); - aLine.append(static_cast<const char*>(rStream.GetData()), rStream.GetSize()); - aLine.append("\nendstream\n"); - } - - if (filter::PDFArrayElement* pArray = rObject.GetArray()) - { - 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*>(rDocBuffer.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) - { - // 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*>(rDocBuffer.GetData()) + nCopyStart, nLen); - } - else - // Can copy it as-is. - aLine.append(static_cast<const char*>(rDocBuffer.GetData()) + rObject.GetArrayOffset(), rObject.GetArrayLength()); - - aLine.append("]\n"); - } - - // If the object has a number element outside a dictionary or array, copy that. - if (filter::PDFNumberElement* pNumber = rObject.GetNumberElement()) - { - aLine.append(static_cast<const char*>(rDocBuffer.GetData()) + pNumber->GetLocation(), pNumber->GetLength()); - aLine.append("\n"); - } - - - aLine.append("endobj\n\n"); - - // We have the whole object, now write it to the output. - if (!updateObject(nObject)) - return -1; - if (!writeBuffer(aLine.getStr(), aLine.getLength())) - return -1; - - return nObject; -} - -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. - std::map<OString, sal_Int32> aRet; - - // Get the rKind subset of the resource dictionary. - std::map<OString, filter::PDFElement*> aItems; - if (auto pResources = dynamic_cast<filter::PDFDictionaryElement*>(rPage.Lookup("Resources"))) - { - // Resources is a direct dictionary. - filter::PDFElement* pLookup = pResources->LookupElement(rKind); - if (auto pDictionary = dynamic_cast<filter::PDFDictionaryElement*>(pLookup)) - { - // rKind is an inline dictionary. - aItems = pDictionary->GetItems(); - } - else if (auto pReference = dynamic_cast<filter::PDFReferenceElement*>(pLookup)) - { - // rKind refers to a dictionary. - filter::PDFObjectElement* pReferenced = pReference->LookupObject(); - if (!pReferenced) - { - return OString(); - } - - aItems = pReferenced->GetDictionaryItems(); - } - } - else if (filter::PDFObjectElement* pPageResources = rPage.LookupObject("Resources")) - { - // Resources is an indirect object. - filter::PDFElement* pValue = pPageResources->Lookup(rKind); - if (auto pDictionary = dynamic_cast<filter::PDFDictionaryElement*>(pValue)) - // Kind is a direct dictionary. - aItems = pDictionary->GetItems(); - else if (filter::PDFObjectElement* pObject = pPageResources->LookupObject(rKind)) - // Kind is an indirect object. - aItems = pObject->GetDictionaryItems(); - } - if (aItems.empty()) - return OString(); - - SvMemoryStream& rDocBuffer = rPage.GetDocument().GetEditBuffer(); - - for (const auto& rItem : aItems) - { - // For each item copy it over to our output then insert it into aRet. - auto pReference = dynamic_cast<filter::PDFReferenceElement*>(rItem.second); - if (!pReference) - continue; - - filter::PDFObjectElement* pValue = pReference->LookupObject(); - if (!pValue) - continue; - - // Then copying over an object copy its dictionary and its stream. - sal_Int32 nObject = copyExternalResource(rDocBuffer, *pValue, rCopiedResources); - aRet[rItem.first] = nObject; - } - - // Build the dictionary entry string. - OStringBuffer sRet("/" + rKind + "<<"); - for (const auto& rPair : aRet) - { - sRet.append("/").append(rPair.first).append(" ").append(OString::number(rPair.second)).append(" 0 R"); - } - sRet.append(">>"); - - return sRet.makeStringAndClear(); -} - void PDFWriterImpl::writeReferenceXObject(ReferenceXObjectEmit& rEmit) { if (rEmit.m_nFormObject <= 0) @@ -8694,8 +8466,9 @@ void PDFWriterImpl::writeReferenceXObject(ReferenceXObjectEmit& rEmit) "XObject", "Shading" }; + PDFObjectCopier aCopier(*this); for (const auto& rKey : aKeys) - aLine.append(copyExternalResources(*pPage, rKey, aCopiedResources)); + aLine.append(aCopier.copyExternalResources(*pPage, rKey, aCopiedResources)); aLine.append(">>"); aLine.append(" /BBox [ 0 0 "); aLine.append(nWidth); diff --git a/vcl/source/gdi/pdfwriter_impl.hxx b/vcl/source/gdi/pdfwriter_impl.hxx index 6261a391ba3c..4aaa6c873ce1 100644 --- a/vcl/source/gdi/pdfwriter_impl.hxx +++ b/vcl/source/gdi/pdfwriter_impl.hxx @@ -51,6 +51,7 @@ #include <tools/stream.hxx> #include <outdata.hxx> +#include <pdf/objectcontainer.hxx> #include "pdffontcache.hxx" #include "pdfbuildin_fonts.hxx" @@ -609,7 +610,7 @@ enum class Mode { DEFAULT, NOWRITE }; } -class PDFWriterImpl : public VirtualDevice +class PDFWriterImpl : public VirtualDevice, public PDFObjectContainer { friend class PDFStreamIf; @@ -816,12 +817,6 @@ i12626 void writeJPG( JPGEmit& rEmit ); /// Writes the form XObject proxy for the image. 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, 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, 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 */ @@ -949,15 +944,12 @@ i12626 /* ensure proper escapement and uniqueness of field names */ void createWidgetFieldName( sal_Int32 i_nWidgetsIndex, const PDFWriter::AnyWidget& i_rInWidget ); - /* adds an entry to m_aObjects and returns its index+1, - * sets the offset to ~0 - */ - sal_Int32 createObject(); - /* sets the offset of object n to the current position of output file+1 - */ - bool updateObject( sal_Int32 n ); + /// See vcl::PDFObjectContainer::createObject(). + sal_Int32 createObject() override; + /// See vcl::PDFObjectContainer::updateObject(). + bool updateObject( sal_Int32 n ) override; - bool writeBuffer( const void* pBuffer, sal_uInt64 nBytes ); + bool writeBuffer( const void* pBuffer, sal_uInt64 nBytes ) override; void beginCompression(); void endCompression(); void beginRedirect( SvStream* pStream, const tools::Rectangle& ); |