sw/source/core/text/EnhancedPDFExportHelper.cxx | 32 ++- vcl/qa/cppunit/pdfexport/data/Description PDF Export test .odt |binary vcl/qa/cppunit/pdfexport/pdfexport.cxx | 102 ++++++++++ 3 files changed, 131 insertions(+), 3 deletions(-)
New commits: commit 0d59eebe858d0d3e5d2260691f245940757deacd Author: Michael Stahl <michael.st...@allotropia.de> AuthorDate: Thu Nov 24 13:17:56 2022 +0100 Commit: Caolán McNamara <caol...@redhat.com> CommitDate: Sat Dec 3 21:02:13 2022 +0000 tdf#57423 sw: PDF/UA export: Alt texts for SwNoTextNode * Specification: ISO 14289-1:2014, Clause: 7.3, Test number: 1 Figure tags shall include an alternative representation or replacement text that represents the contents marked with the Figure tag as noted in ISO 32000-1:2008, 14.7.2, Table 323 This was broken by the previous commit, which tied ObjectInfoPrimitive2D evaluation to StructureTagPrimitive2D, and is restored now, perhaps less elegantly. * Specification: ISO 14289-1:2014, Clause: 7.7, Test number: 1 All mathematical expressions shall be enclosed within a Formula tag as detailed in ISO 32000-1:2008, 14.8.4.5 and shall have Alt or ActualText attributes Haven't checked but it's possible that this worked before commit 2840352ba56a212d191cc16e08378c87672d7b73 - for SwOLENode embedded objects, no ObjectInfoPrimitive2D is created apparently. Change-Id: Ia0077199601f39f666012d31883f63cff115716f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143247 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.st...@allotropia.de> (cherry picked from commit 122b4264d23df8b11419839ba700b88c4f936a6c) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143292 Reviewed-by: Caolán McNamara <caol...@redhat.com> diff --git a/sw/source/core/text/EnhancedPDFExportHelper.cxx b/sw/source/core/text/EnhancedPDFExportHelper.cxx index 6afa8648947c..9f0b028258f4 100644 --- a/sw/source/core/text/EnhancedPDFExportHelper.cxx +++ b/sw/source/core/text/EnhancedPDFExportHelper.cxx @@ -526,6 +526,7 @@ void SwTaggedPDFHelper::SetAttributes( vcl::PDFWriter::StructElement eType ) bool bHeight = false; bool bBox = false; bool bRowSpan = false; + bool bAltText = false; // Check which attributes to set: @@ -586,11 +587,20 @@ void SwTaggedPDFHelper::SetAttributes( vcl::PDFWriter::StructElement eType ) case vcl::PDFWriter::Formula : case vcl::PDFWriter::Figure : + bAltText = bPlacement = bWidth = bHeight = bBox = true; break; + + case vcl::PDFWriter::Division: + if (pFrame->IsFlyFrame()) // this can be something else too + { + bAltText = true; + } + break; + default : break; } @@ -676,9 +686,25 @@ void SwTaggedPDFHelper::SetAttributes( vcl::PDFWriter::StructElement eType ) } } - // Formerly here bAlternateText was triggered for PDF export, but this - // was moved for more general use to primitives and usage in - // VclMetafileProcessor2D (see processGraphicPrimitive2D). + // ISO 14289-1:2014, Clause: 7.3 + // ISO 14289-1:2014, Clause: 7.7 + // For images (but not embedded objects), an ObjectInfoPrimitive2D is + // created, but it's not evaluated by VclMetafileProcessor2D any more; + // that would require producing StructureTagPrimitive2D here but that + // looks impossible so instead duplicate the code that sets the Alt + // text here again. + if (bAltText) + { + SwFlyFrameFormat const& rFly(*static_cast<SwFlyFrame const*>(pFrame)->GetFormat()); + OUString const sep( + (rFly.GetObjTitle().isEmpty() || rFly.GetObjDescription().isEmpty()) + ? OUString() : OUString(" - ")); + OUString const altText(rFly.GetObjTitle() + sep + rFly.GetObjDescription()); + if (!altText.isEmpty()) + { + mpPDFExtOutDevData->SetAlternateText(altText); + } + } if ( bWidth ) { diff --git a/vcl/qa/cppunit/pdfexport/data/Description PDF Export test .odt b/vcl/qa/cppunit/pdfexport/data/Description PDF Export test .odt new file mode 100644 index 000000000000..78f05b09e9e9 Binary files /dev/null and b/vcl/qa/cppunit/pdfexport/data/Description PDF Export test .odt differ diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx b/vcl/qa/cppunit/pdfexport/pdfexport.cxx index 6b0f90a0581f..461bb937f81d 100644 --- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx +++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx @@ -3241,6 +3241,108 @@ CPPUNIT_TEST_FIXTURE(PdfExportTest, testTdf135638) CPPUNIT_ASSERT_EQUAL(int(2), nFigure); } +CPPUNIT_TEST_FIXTURE(PdfExportTest, testTdf57423) +{ + 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"Description PDF Export test .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()); + + int nFigure(0); + int nFormula(0); + int nDiv(0); + for (const auto& rDocElement : aDocument.GetElements()) + { + auto pObject = dynamic_cast<vcl::filter::PDFObjectElement*>(rDocElement.get()); + if (!pObject) + continue; + auto pType = dynamic_cast<vcl::filter::PDFNameElement*>(pObject->Lookup("Type")); + if (pType && pType->GetValue() == "StructElem") + { + auto pS = dynamic_cast<vcl::filter::PDFNameElement*>(pObject->Lookup("S")); + if (pS && pS->GetValue() == "Figure") + { + switch (nFigure) + { + case 0: + CPPUNIT_ASSERT_EQUAL(OUString(u"QR Code - Tells how to get to Mosegaard"), + ::vcl::filter::PDFDocument::DecodeHexStringUTF16BE( + *dynamic_cast<vcl::filter::PDFHexStringElement*>( + pObject->Lookup("Alt")))); + break; + case 1: + CPPUNIT_ASSERT_EQUAL(OUString(u"Title: Arrows - Description: Explains the " + u"different arrow appearances"), + ::vcl::filter::PDFDocument::DecodeHexStringUTF16BE( + *dynamic_cast<vcl::filter::PDFHexStringElement*>( + pObject->Lookup("Alt")))); + break; + case 2: + CPPUNIT_ASSERT_EQUAL( + OUString(u"My blue triangle - Does not need further description"), + ::vcl::filter::PDFDocument::DecodeHexStringUTF16BE( + *dynamic_cast<vcl::filter::PDFHexStringElement*>( + pObject->Lookup("Alt")))); + break; + } + ++nFigure; + } + if (pS && pS->GetValue() == "Formula") + { + CPPUNIT_ASSERT_EQUAL( + OUString(u"Equation 1 - Now we give the full description of eq 1 here"), + ::vcl::filter::PDFDocument::DecodeHexStringUTF16BE( + *dynamic_cast<vcl::filter::PDFHexStringElement*>(pObject->Lookup("Alt")))); + ++nFormula; + } + if (pS && pS->GetValue() == "Div") + { + switch (nDiv) + { + case 0: + CPPUNIT_ASSERT_EQUAL(OUString(u"This frame has a description"), + ::vcl::filter::PDFDocument::DecodeHexStringUTF16BE( + *dynamic_cast<vcl::filter::PDFHexStringElement*>( + pObject->Lookup("Alt")))); + break; + case 1: + // no properties set on this + CPPUNIT_ASSERT(!pObject->Lookup("Alt")); + break; + case 2: + CPPUNIT_ASSERT_EQUAL(OUString(u"My textbox - Has a light background"), + ::vcl::filter::PDFDocument::DecodeHexStringUTF16BE( + *dynamic_cast<vcl::filter::PDFHexStringElement*>( + pObject->Lookup("Alt")))); + break; + case 3: + CPPUNIT_ASSERT_EQUAL(OUString(u"Hey! There is no alternate text for Frame " + u"// but maybe not needed?"), + ::vcl::filter::PDFDocument::DecodeHexStringUTF16BE( + *dynamic_cast<vcl::filter::PDFHexStringElement*>( + pObject->Lookup("Alt")))); + break; + } + ++nDiv; + } + } + } + CPPUNIT_ASSERT_EQUAL(int(3), nFigure); + CPPUNIT_ASSERT_EQUAL(int(1), nFormula); + CPPUNIT_ASSERT_EQUAL(int(4), nDiv); +} + CPPUNIT_TEST_FIXTURE(PdfExportTest, testTdf142129) { OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "master.odm";