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)
 {

Reply via email to