/* -*- 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/.
*/
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", "PDFObjectCopier::copyExternalResource: " << rObject.GetObjectValue()
<< " -> " << nObject);
// If the object has a number element outside a dictionary or array, copy that. if (filter::PDFNumberElement* pNumber = rObject.GetNumberElement())
{
pNumber->writeString(aLine);
aLine.append("\n");
} // If the object has a name element outside a dictionary or array, copy that. elseif (filter::PDFNameElement* pName = rObject.GetNameElement())
{ // currently just handle the exact case seen in the real world if (pName->GetValue() == "DeviceRGB")
{
pName->writeString(aLine);
aLine.append("\n");
} else
{
SAL_INFO("vcl.pdfwriter", "PDFObjectCopier::copyExternalResource: skipping: " << pName->GetValue());
}
}
// We have the whole object, now write it to the output. if (!m_rContainer.updateObject(nObject)) return -1; if (!m_rContainer.writeBuffer(aLine)) return -1;
aLine.setLength(0);
if (pStream)
{
SvMemoryStream& rStream = pStream->GetMemory();
m_rContainer.checkAndEnableStreamEncryption(nObject);
aLine.append(static_cast<constchar*>(rStream.GetData()), rStream.GetSize()); if (!m_rContainer.writeBuffer(aLine)) return -1;
aLine.setLength(0);
m_rContainer.disableStreamEncryption();
aLine.append("\nendstream\n"); if (!m_rContainer.writeBuffer(aLine)) return -1;
aLine.setLength(0);
}
aLine.append("endobj\n\n"); if (!m_rContainer.writeBuffer(aLine)) 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;
filter::PDFObjectElement* pKindObject = nullptr; if (auto pResources
= dynamic_cast<filter::PDFDictionaryElement*>(rPage.Lookup("Resources"_ostr)))
{ // 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();
} elseif (auto pReference = dynamic_cast<filter::PDFReferenceElement*>(pLookup))
{ // rKind refers to a dictionary.
filter::PDFObjectElement* pReferenced = pReference->LookupObject(); if (!pReferenced)
{ return {};
}
pKindObject = pReferenced;
aItems = pReferenced->GetDictionaryItems();
}
} elseif (filter::PDFObjectElement* pPageResources = rPage.LookupObject("Resources"_ostr))
{ // 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();
} elseif (filter::PDFObjectElement* pObject = pPageResources->LookupObject(rKind))
{ // Kind is an indirect object.
aItems = pObject->GetDictionaryItems();
pKindObject = pObject;
}
} if (aItems.empty()) return {};
for (constauto& 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)
{ if (pKindObject && dynamic_cast<filter::PDFDictionaryElement*>(rItem.second))
{
bHasDictValue = true; break;
}
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;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.