sw/source/core/text/EnhancedPDFExportHelper.cxx | 16 ++- vcl/qa/cppunit/pdfexport/data/tdf159900_figurePlacement.odt |binary vcl/qa/cppunit/pdfexport/pdfexport.cxx | 51 ++++++++++++ 3 files changed, 63 insertions(+), 4 deletions(-)
New commits: commit 0b97823b58c7bbdef34ed1e654290d72967c32f1 Author: Tibor Nagy <tibor.nagy.ext...@allotropia.de> AuthorDate: Fri Jul 5 14:40:11 2024 +0200 Commit: Xisco Fauli <xiscofa...@libreoffice.org> CommitDate: Wed Jul 24 19:21:13 2024 +0200 tdf#159900 sw: fix Figure tag placement attribute when exporting to PDF Paragraph tag is a possible parent element for the Figure tag. Figure tag and (any structure element) may have a value of “inline” as a placement attribute and thus, may be a child of a Paragraph tag. Change-Id: Ie1e0221976dbcfbae9ff01b1c9b76dd2d2e7edcb Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170015 Tested-by: Jenkins Reviewed-by: Nagy Tibor <tibor.nagy.ext...@allotropia.de> (cherry picked from commit 611dc34f19deab7f13d00a4058f6a6ac6b50edb2) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170117 Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> diff --git a/sw/source/core/text/EnhancedPDFExportHelper.cxx b/sw/source/core/text/EnhancedPDFExportHelper.cxx index 2fb51c70becd..acaa18350073 100644 --- a/sw/source/core/text/EnhancedPDFExportHelper.cxx +++ b/sw/source/core/text/EnhancedPDFExportHelper.cxx @@ -765,10 +765,18 @@ void SwTaggedPDFHelper::SetAttributes( vcl::PDFWriter::StructElement eType ) if ( bPlacement ) { - eVal = vcl::PDFWriter::TableHeader == eType || - vcl::PDFWriter::TableData == eType ? - vcl::PDFWriter::Inline : - vcl::PDFWriter::Block; + bool bIsFigureInline = false; + if (vcl::PDFWriter::Figure == eType) + { + const SwFrame* pKeyFrame = static_cast<const SwFlyFrame&>(*pFrame).GetAnchorFrame(); + if (pKeyFrame->GetUpper()->GetType() == SwFrameType::Body) + bIsFigureInline = true; + } + + eVal = vcl::PDFWriter::TableHeader == eType || vcl::PDFWriter::TableData == eType + || bIsFigureInline + ? vcl::PDFWriter::Inline + : vcl::PDFWriter::Block; mpPDFExtOutDevData->SetStructureAttribute( vcl::PDFWriter::Placement, eVal ); } diff --git a/vcl/qa/cppunit/pdfexport/data/tdf159900_figurePlacement.odt b/vcl/qa/cppunit/pdfexport/data/tdf159900_figurePlacement.odt new file mode 100644 index 000000000000..0ebe292ce160 Binary files /dev/null and b/vcl/qa/cppunit/pdfexport/data/tdf159900_figurePlacement.odt differ diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx b/vcl/qa/cppunit/pdfexport/pdfexport.cxx index 24e7b0daf609..ef2ab904f94a 100644 --- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx +++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx @@ -70,6 +70,57 @@ void PdfExportTest::load(std::u16string_view rFile, vcl::filter::PDFDocument& rD CPPUNIT_ASSERT(rDocument.Read(aStream)); } +CPPUNIT_TEST_FIXTURE(PdfExportTest, testFigurePlacement) +{ + aMediaDescriptor[u"FilterName"_ustr] <<= u"impress_pdf_Export"_ustr; + + uno::Sequence<beans::PropertyValue> aFilterData( + comphelper::InitPropertySequence({ { "UseTaggedPDF", uno::Any(true) } })); + aMediaDescriptor[u"FilterData"_ustr] <<= aFilterData; + saveAsPDF(u"tdf159900_figurePlacement.odt"); + + // Parse the export result. + 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()); + + for (const auto& aElement : aDocument.GetElements()) + { + auto pObject = dynamic_cast<vcl::filter::PDFObjectElement*>(aElement.get()); + if (!pObject) + continue; + auto pType = dynamic_cast<vcl::filter::PDFNameElement*>(pObject->Lookup("Type"_ostr)); + if (pType && pType->GetValue() == "StructElem") + { + auto pS = dynamic_cast<vcl::filter::PDFNameElement*>(pObject->Lookup("S"_ostr)); + if (pS && pS->GetValue() == "Figure") + { + auto pAttrDict + = dynamic_cast<vcl::filter::PDFDictionaryElement*>(pObject->Lookup("A"_ostr)); + CPPUNIT_ASSERT(pAttrDict); + auto pOwner = dynamic_cast<vcl::filter::PDFNameElement*>( + pAttrDict->LookupElement("O"_ostr)); + CPPUNIT_ASSERT(pOwner); + if (pOwner->GetValue() == "Layout") + { + auto pPlacement = dynamic_cast<vcl::filter::PDFNameElement*>( + pAttrDict->LookupElement("Placement"_ostr)); + CPPUNIT_ASSERT(pPlacement); + + // Without the fix in place, this test would have failed with + // Expected: Inline + // Actual: Block + CPPUNIT_ASSERT_EQUAL("Inline"_ostr, pPlacement->GetValue()); + } + } + } + } +} + /// Tests that a pdf image is roundtripped back to PDF as a vector format. CPPUNIT_TEST_FIXTURE(PdfExportTest, testTdf106059) {