diff options
author | Michael Stahl <michael.stahl@allotropia.de> | 2023-03-16 19:48:31 +0100 |
---|---|---|
committer | Michael Stahl <michael.stahl@allotropia.de> | 2023-03-22 11:53:38 +0000 |
commit | e84b310b59825fd572d79def98c3d21566aac603 (patch) | |
tree | 615a52cbf4ad57a5099bbcbfcf825a71edd6c287 /vcl/qa | |
parent | 7f4b53b1c7c192ecfef35913133239b670070062 (diff) |
vcl,drawinglayer,svx,sw,sd: PDF/UA export: Annot StructElem for SdrMediaObj
veraPDF complains:
Specification: ISO 14289-1:2014, Clause: 7.18.1, Test number: 1
An annotation, excluding annotations of subtype Widget, Popup or
Link, shall be nested within an Annot tag
This is very similar to Link annotations, that is to say, extremely
complicated to get it thought the convoluted PDF export code, with
additional complication that the StructElem is produced by drawinglayer
and the page annotation by sw.
Put another map into PDFExtOutDevData where sw code puts stuff for the
SdrObject that drawinglayer can find.
The test had the problem that PDFObjectParser::parse() could not handle:
<</Nums[
0 [ 6 0 R ]
1 6 0 R
]>>
Fix dropping the "1".
Change-Id: If5bf7c552e26ebb7e631030b8aaecd4281e77acc
(cherry picked from commit c78e90bd28cc4d6d3bde473535107784b12d9c0d)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149008
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
Diffstat (limited to 'vcl/qa')
-rw-r--r-- | vcl/qa/cppunit/pdfexport/data/vid.odt | bin | 0 -> 110887 bytes | |||
-rw-r--r-- | vcl/qa/cppunit/pdfexport/pdfexport.cxx | 130 |
2 files changed, 130 insertions, 0 deletions
diff --git a/vcl/qa/cppunit/pdfexport/data/vid.odt b/vcl/qa/cppunit/pdfexport/data/vid.odt Binary files differnew file mode 100644 index 000000000000..730358e261fa --- /dev/null +++ b/vcl/qa/cppunit/pdfexport/data/vid.odt diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx b/vcl/qa/cppunit/pdfexport/pdfexport.cxx index d04f3e98f75f..4304846c9834 100644 --- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx +++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx @@ -3567,6 +3567,136 @@ CPPUNIT_TEST_FIXTURE(PdfExportTest, testTdf135192) CPPUNIT_ASSERT_EQUAL(int(1), nTable); } +CPPUNIT_TEST_FIXTURE(PdfExportTest, testMediaShapeAnnot) +{ + aMediaDescriptor["FilterName"] <<= OUString("writer_pdf_Export"); + + // Enable PDF/UA + uno::Sequence<beans::PropertyValue> aFilterData( + comphelper::InitPropertySequence({ { "PDFUACompliance", uno::Any(true) } })); + aMediaDescriptor["FilterData"] <<= aFilterData; + + saveAsPDF(u"vid.odt"); + + vcl::filter::PDFDocument aDocument; + SvFileStream aStream(maTempFile.GetURL(), StreamMode::READ); + CPPUNIT_ASSERT(aDocument.Read(aStream)); + + // The document has one page. + std::vector<vcl::filter::PDFObjectElement*> aPages = aDocument.GetPages(); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aPages.size()); + + auto pAnnots = dynamic_cast<vcl::filter::PDFArrayElement*>(aPages[0]->Lookup("Annots")); + CPPUNIT_ASSERT(pAnnots); + + // There should be one annotation + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pAnnots->GetElements().size()); + auto pAnnotReference + = dynamic_cast<vcl::filter::PDFReferenceElement*>(pAnnots->GetElements()[0]); + CPPUNIT_ASSERT(pAnnotReference); + // check /Annot - produced by sw + vcl::filter::PDFObjectElement* pAnnot = pAnnotReference->LookupObject(); + CPPUNIT_ASSERT(pAnnot); + CPPUNIT_ASSERT_EQUAL( + OString("Annot"), + static_cast<vcl::filter::PDFNameElement*>(pAnnot->Lookup("Type"))->GetValue()); + CPPUNIT_ASSERT_EQUAL( + OString("Screen"), + static_cast<vcl::filter::PDFNameElement*>(pAnnot->Lookup("Subtype"))->GetValue()); + + auto pA = dynamic_cast<vcl::filter::PDFDictionaryElement*>(pAnnot->Lookup("A")); + CPPUNIT_ASSERT(pA); + auto pR = dynamic_cast<vcl::filter::PDFDictionaryElement*>(pA->LookupElement("R")); + CPPUNIT_ASSERT(pR); + auto pC = dynamic_cast<vcl::filter::PDFDictionaryElement*>(pR->LookupElement("C")); + CPPUNIT_ASSERT(pC); + auto pAlt = dynamic_cast<vcl::filter::PDFArrayElement*>(pC->LookupElement("Alt")); + CPPUNIT_ASSERT(pAlt); + auto pLang = dynamic_cast<vcl::filter::PDFLiteralStringElement*>(pAlt->GetElement(0)); + CPPUNIT_ASSERT_EQUAL(OString(""), pLang->GetValue()); + auto pAltText = dynamic_cast<vcl::filter::PDFLiteralStringElement*>(pAlt->GetElement(1)); + CPPUNIT_ASSERT_EQUAL(OString("alternativloser text\\nand some description"), + pAltText->GetValue()); + + auto pStructParent + = dynamic_cast<vcl::filter::PDFNumberElement*>(pAnnot->Lookup("StructParent")); + CPPUNIT_ASSERT(pStructParent); + + vcl::filter::PDFReferenceElement* pStructElemRef(nullptr); + + // check ParentTree to find StructElem + auto nRoots(0); + for (const auto& rDocElement : aDocument.GetElements()) + { + auto pObject1 = dynamic_cast<vcl::filter::PDFObjectElement*>(rDocElement.get()); + if (!pObject1) + continue; + auto pType1 = dynamic_cast<vcl::filter::PDFNameElement*>(pObject1->Lookup("Type")); + if (pType1 && pType1->GetValue() == "StructTreeRoot") + { + ++nRoots; + auto pParentTree + = dynamic_cast<vcl::filter::PDFReferenceElement*>(pObject1->Lookup("ParentTree")); + CPPUNIT_ASSERT(pParentTree); + auto pNumTree = pParentTree->LookupObject(); + CPPUNIT_ASSERT(pNumTree); + auto pNums = dynamic_cast<vcl::filter::PDFArrayElement*>(pNumTree->Lookup("Nums")); + CPPUNIT_ASSERT(pNums); + auto nFound(0); + for (size_t i = 0; i < pNums->GetElements().size(); i += 2) + { + auto pI = dynamic_cast<vcl::filter::PDFNumberElement*>(pNums->GetElement(i)); + if (pI->GetValue() == pStructParent->GetValue()) + { + ++nFound; + CPPUNIT_ASSERT(i < pNums->GetElements().size() - 1); + pStructElemRef + = dynamic_cast<vcl::filter::PDFReferenceElement*>(pNums->GetElement(i + 1)); + CPPUNIT_ASSERT(pStructElemRef); + } + } + CPPUNIT_ASSERT_EQUAL(static_cast<decltype(nFound)>(1), nFound); + } + } + CPPUNIT_ASSERT_EQUAL(static_cast<decltype(nRoots)>(1), nRoots); + + // check /StructElem - produced by drawinglayer + CPPUNIT_ASSERT(pStructElemRef); + auto pStructElem(pStructElemRef->LookupObject()); + CPPUNIT_ASSERT(pStructElem); + + auto pType = dynamic_cast<vcl::filter::PDFNameElement*>(pStructElem->Lookup("Type")); + CPPUNIT_ASSERT_EQUAL(OString("StructElem"), pType->GetValue()); + auto pS = dynamic_cast<vcl::filter::PDFNameElement*>(pStructElem->Lookup("S")); + CPPUNIT_ASSERT_EQUAL(OString("Annot"), pS->GetValue()); + auto pSEAlt = dynamic_cast<vcl::filter::PDFHexStringElement*>(pStructElem->Lookup("Alt")); + CPPUNIT_ASSERT_EQUAL(OUString("alternativloser text - and some description"), + ::vcl::filter::PDFDocument::DecodeHexStringUTF16BE(*pSEAlt)); + auto pKids = dynamic_cast<vcl::filter::PDFArrayElement*>(pStructElem->Lookup("K")); + auto nMCID(0); + auto nRef(0); + for (size_t i = 0; i < pKids->GetElements().size(); ++i) + { + auto pNum = dynamic_cast<vcl::filter::PDFNumberElement*>(pKids->GetElement(i)); + auto pRef = dynamic_cast<vcl::filter::PDFReferenceElement*>(pKids->GetElement(i)); + if (pNum) + { + ++nMCID; + } + if (pRef) + { + ++nRef; + auto pObjR = pRef->LookupObject(); + auto pOType = dynamic_cast<vcl::filter::PDFNameElement*>(pObjR->Lookup("Type")); + CPPUNIT_ASSERT_EQUAL(OString("OBJR"), pOType->GetValue()); + auto pAnnotRef = dynamic_cast<vcl::filter::PDFReferenceElement*>(pObjR->Lookup("Obj")); + CPPUNIT_ASSERT_EQUAL(pAnnot, pAnnotRef->LookupObject()); + } + } + CPPUNIT_ASSERT_EQUAL(static_cast<decltype(nMCID)>(1), nMCID); + CPPUNIT_ASSERT_EQUAL(static_cast<decltype(nRef)>(1), nRef); +} + CPPUNIT_TEST_FIXTURE(PdfExportTest, testTdf142129) { loadFromURL(u"master.odm"); |