summaryrefslogtreecommitdiff
path: root/vcl/qa
diff options
context:
space:
mode:
authorMichael Stahl <michael.stahl@allotropia.de>2023-03-16 19:48:31 +0100
committerMichael Stahl <michael.stahl@allotropia.de>2023-03-22 11:53:38 +0000
commite84b310b59825fd572d79def98c3d21566aac603 (patch)
tree615a52cbf4ad57a5099bbcbfcf825a71edd6c287 /vcl/qa
parent7f4b53b1c7c192ecfef35913133239b670070062 (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.odtbin0 -> 110887 bytes
-rw-r--r--vcl/qa/cppunit/pdfexport/pdfexport.cxx130
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
new file mode 100644
index 000000000000..730358e261fa
--- /dev/null
+++ b/vcl/qa/cppunit/pdfexport/data/vid.odt
Binary files differ
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");