vcl/qa/cppunit/pdfexport/data/ref-to-kids.pdf |binary vcl/qa/cppunit/pdfexport/pdfexport.cxx | 46 ++++++++++++++++++++++++++ vcl/source/gdi/pdfobjectcopier.cxx | 22 ++++++++++++ 3 files changed, 68 insertions(+)
New commits: commit 68540314ecc801ddff06b843ac2e332b02bd7a3b Author: Dennis Francis <dennis.fran...@collabora.com> AuthorDate: Fri Dec 2 13:11:42 2022 +0530 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Tue Jan 3 07:26:25 2023 +0000 vcl: Copy the resource kind object itself if... some of the items in that resource are themselves dictionaries instead of references. Change-Id: I427386b14fe5507dfdfc9745dad27a8fceefd929 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143564 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Miklos Vajna <vmik...@collabora.com> (cherry picked from commit 4cb521b28e8582eda1a63bc4d92061fd111a2e3d) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/144438 Tested-by: Jenkins diff --git a/vcl/qa/cppunit/pdfexport/data/ref-to-kids.pdf b/vcl/qa/cppunit/pdfexport/data/ref-to-kids.pdf index 0390ccad8410..fdda33f78231 100644 Binary files a/vcl/qa/cppunit/pdfexport/data/ref-to-kids.pdf and b/vcl/qa/cppunit/pdfexport/data/ref-to-kids.pdf differ diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx b/vcl/qa/cppunit/pdfexport/pdfexport.cxx index ce070a711911..4cf31e708220 100644 --- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx +++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx @@ -4247,6 +4247,52 @@ CPPUNIT_TEST_FIXTURE(PdfExportTest, testRexportMediaBoxOrigin) } } +CPPUNIT_TEST_FIXTURE(PdfExportTest, testRexportResourceItemReference) +{ + // We need to enable PDFium import (and make sure to disable after the test) + bool bResetEnvVar = false; + if (getenv("LO_IMPORT_USE_PDFIUM") == nullptr) + { + bResetEnvVar = true; + osl_setEnvironment(OUString("LO_IMPORT_USE_PDFIUM").pData, OUString("1").pData); + } + comphelper::ScopeGuard aPDFiumEnvVarGuard([&]() { + if (bResetEnvVar) + osl_clearEnvironment(OUString("LO_IMPORT_USE_PDFIUM").pData); + }); + + // Load the PDF and save as PDF + vcl::filter::PDFDocument aDocument; + load(u"ref-to-kids.pdf", aDocument); + + std::vector<vcl::filter::PDFObjectElement*> aPages = aDocument.GetPages(); + CPPUNIT_ASSERT_EQUAL(size_t(5), aPages.size()); + + // Directly go to the inner XObject Im10 that has reference to Font in page 2. + auto pInnerIm = aDocument.LookupObject(10); + CPPUNIT_ASSERT(pInnerIm); + + auto pResources + = dynamic_cast<vcl::filter::PDFDictionaryElement*>(pInnerIm->Lookup("Resources")); + CPPUNIT_ASSERT(pResources); + auto pFontsReference + = dynamic_cast<vcl::filter::PDFReferenceElement*>(pResources->LookupElement("Font")); + CPPUNIT_ASSERT(pFontsReference); + + auto pFontsObject = pFontsReference->LookupObject(); + CPPUNIT_ASSERT(pFontsObject); + + auto pFontDict + = dynamic_cast<vcl::filter::PDFDictionaryElement*>(pFontsObject->Lookup("FF132")); + CPPUNIT_ASSERT(pFontDict); + + auto pFontDescriptor = pFontDict->LookupObject("FontDescriptor"); + CPPUNIT_ASSERT(pFontDescriptor); + + auto pFontWidths = pFontDict->LookupObject("Widths"); + CPPUNIT_ASSERT(pFontWidths); +} + } // end anonymous namespace CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/vcl/source/gdi/pdfobjectcopier.cxx b/vcl/source/gdi/pdfobjectcopier.cxx index 67f70d10f2a9..2f32cdc27ce1 100644 --- a/vcl/source/gdi/pdfobjectcopier.cxx +++ b/vcl/source/gdi/pdfobjectcopier.cxx @@ -184,6 +184,7 @@ OString PDFObjectCopier::copyExternalResources(filter::PDFObjectElement& rPage, // 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"))) { // Resources is a direct dictionary. @@ -202,6 +203,7 @@ OString PDFObjectCopier::copyExternalResources(filter::PDFObjectElement& rPage, return {}; } + pKindObject = pReferenced; aItems = pReferenced->GetDictionaryItems(); } } @@ -210,23 +212,37 @@ OString PDFObjectCopier::copyExternalResources(filter::PDFObjectElement& rPage, // 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(); + pKindObject = pObject; + } } if (aItems.empty()) return {}; SvMemoryStream& rDocBuffer = rPage.GetDocument().GetEditBuffer(); + bool bHasDictValue = false; 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) + { + if (pKindObject && dynamic_cast<filter::PDFDictionaryElement*>(rItem.second)) + { + bHasDictValue = true; + break; + } + continue; + } filter::PDFObjectElement* pValue = pReference->LookupObject(); if (!pValue) @@ -237,6 +253,12 @@ OString PDFObjectCopier::copyExternalResources(filter::PDFObjectElement& rPage, aRet[rItem.first] = nObject; } + if (bHasDictValue && pKindObject) + { + sal_Int32 nObject = copyExternalResource(rDocBuffer, *pKindObject, rCopiedResources); + return "/" + rKind + " " + OString::number(nObject) + " 0 R"; + } + // Build the dictionary entry string. OStringBuffer sRet("/" + rKind + "<<"); for (const auto& rPair : aRet)