drawinglayer/source/primitive2d/structuretagprimitive2d.cxx  |    4 
 drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx   |   10 +
 include/drawinglayer/primitive2d/structuretagprimitive2d.hxx |    4 
 sc/qa/extras/scpdfexport.cxx                                 |   62 +++++++++++
 sc/qa/extras/testdocuments/tdf159067.ods                     |binary
 svx/source/sdr/contact/viewobjectcontact.cxx                 |    2 
 svx/source/table/viewcontactoftableobj.cxx                   |    2 
 7 files changed, 80 insertions(+), 4 deletions(-)

New commits:
commit 01e41414847bcc3670df9537bbcba6a98ebd5190
Author:     Tibor Nagy <[email protected]>
AuthorDate: Fri Jan 19 03:19:41 2024 +0100
Commit:     Nagy Tibor <[email protected]>
CommitDate: Fri Jan 19 11:55:12 2024 +0100

    tdf#159067 drawinglayer: fix untagged form control (PDF/UA export)
    
    If the form object is marked as decorative, the form control should be 
exported as "Artifact"
    
    Change-Id: I615d308ae966bf3d0f156899a0b4fad2d5a7c492
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162268
    Tested-by: Jenkins
    Reviewed-by: Nagy Tibor <[email protected]>

diff --git a/drawinglayer/source/primitive2d/structuretagprimitive2d.cxx 
b/drawinglayer/source/primitive2d/structuretagprimitive2d.cxx
index 47af55ab9b57..783a54a4c409 100644
--- a/drawinglayer/source/primitive2d/structuretagprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/structuretagprimitive2d.cxx
@@ -30,13 +30,15 @@ namespace drawinglayer::primitive2d
             const vcl::PDFWriter::StructElement& rStructureElement,
             bool bBackground,
             bool bIsImage,
+            bool bIsDecorative,
             Primitive2DContainer&& aChildren,
             void const*const pAnchorStructureElementKey,
             ::std::vector<sal_Int32> const*const pAnnotIds)
         :   GroupPrimitive2D(std::move(aChildren)),
             maStructureElement(rStructureElement),
             mbBackground(bBackground),
-            mbIsImage(bIsImage)
+            mbIsImage(bIsImage),
+            mbIsDecorative(bIsDecorative)
         ,   m_pAnchorStructureElementKey(pAnchorStructureElementKey)
         {
             if (pAnnotIds)
diff --git a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx 
b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
index 22f464d70b7f..e4441bbda327 100644
--- a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
@@ -1116,8 +1116,9 @@ void VclMetafileProcessor2D::processControlPrimitive2D(
 
     const bool bPDFExport(mpPDFExtOutDevData && 
mpPDFExtOutDevData->GetIsExportFormFields());
     bool bDoProcessRecursively(true);
+    bool bDecorative = (mpCurrentStructureTag && 
mpCurrentStructureTag->isDecorative());
 
-    if (bPDFExport)
+    if (bPDFExport && !bDecorative)
     {
         // PDF export. Emulate data handling from UnoControlPDFExportContact
         std::unique_ptr<vcl::PDFWriter::AnyWidget> pPDFControl(
@@ -1190,7 +1191,10 @@ void VclMetafileProcessor2D::processControlPrimitive2D(
 
     if (mpPDFExtOutDevData)
     { // no corresponding PDF Form, use Figure instead
-        mpPDFExtOutDevData->WrapBeginStructureElement(vcl::PDFWriter::Figure);
+        if (!bDecorative)
+            
mpPDFExtOutDevData->WrapBeginStructureElement(vcl::PDFWriter::Figure);
+        else
+            
mpPDFExtOutDevData->WrapBeginStructureElement(vcl::PDFWriter::NonStructElement);
         mpPDFExtOutDevData->SetStructureAttribute(vcl::PDFWriter::Placement, 
vcl::PDFWriter::Block);
         auto const 
range(rControlPrimitive.getB2DRange(getViewInformation2D()));
         tools::Rectangle const aLogicRect(
@@ -1198,7 +1202,7 @@ void VclMetafileProcessor2D::processControlPrimitive2D(
             basegfx::fround(range.getMaxX()), 
basegfx::fround(range.getMaxY()));
         mpPDFExtOutDevData->SetStructureBoundingBox(aLogicRect);
         OUString const& rAltText(rControlPrimitive.GetAltText());
-        if (!rAltText.isEmpty())
+        if (!rAltText.isEmpty() && !bDecorative)
         {
             mpPDFExtOutDevData->SetAlternateText(rAltText);
         }
diff --git a/include/drawinglayer/primitive2d/structuretagprimitive2d.hxx 
b/include/drawinglayer/primitive2d/structuretagprimitive2d.hxx
index 0d7e6ba57735..3cc489973c19 100644
--- a/include/drawinglayer/primitive2d/structuretagprimitive2d.hxx
+++ b/include/drawinglayer/primitive2d/structuretagprimitive2d.hxx
@@ -49,6 +49,8 @@ namespace drawinglayer::primitive2d
             bool                                    mbBackground;
             /// flag for image (OBJ_GRAF)
             bool                                    mbIsImage;
+            /// flag for form control object
+            bool                                    mbIsDecorative;
             /// anchor structure element (Writer)
             void const* m_pAnchorStructureElementKey;
             /// for Annot structure element, the ids of the annotations
@@ -60,6 +62,7 @@ namespace drawinglayer::primitive2d
                 const vcl::PDFWriter::StructElement& rStructureElement,
                 bool bBackground,
                 bool bIsImage,
+                bool bIsDecorative,
                 Primitive2DContainer&& aChildren,
                 void const* pAnchorStructureElementKey = nullptr,
                 ::std::vector<sal_Int32> const* pAnnotIds = nullptr);
@@ -68,6 +71,7 @@ namespace drawinglayer::primitive2d
             const vcl::PDFWriter::StructElement& getStructureElement() const { 
return maStructureElement; }
             bool isBackground() const { return mbBackground; }
             bool isImage() const { return mbIsImage; }
+            bool isDecorative() const { return mbIsDecorative; }
             bool isTaggedSdrObject() const;
             void const* GetAnchorStructureElementKey() const { return 
m_pAnchorStructureElementKey; }
             ::std::vector<sal_Int32> GetAnnotIds() const { return m_AnnotIds; }
diff --git a/sc/qa/extras/scpdfexport.cxx b/sc/qa/extras/scpdfexport.cxx
index bd6807e6375f..6cf93f71ed51 100644
--- a/sc/qa/extras/scpdfexport.cxx
+++ b/sc/qa/extras/scpdfexport.cxx
@@ -66,6 +66,7 @@ public:
     void testUnoCommands_Tdf120161();
     void testTdf64703_hiddenPageBreak();
     void testTdf159068();
+    void testTdf159067();
     void testTdf159066();
     void testTdf159065();
     void testTdf123870();
@@ -81,6 +82,7 @@ public:
     CPPUNIT_TEST(testUnoCommands_Tdf120161);
     CPPUNIT_TEST(testTdf64703_hiddenPageBreak);
     CPPUNIT_TEST(testTdf159068);
+    CPPUNIT_TEST(testTdf159067);
     CPPUNIT_TEST(testTdf159066);
     CPPUNIT_TEST(testTdf159065);
     CPPUNIT_TEST(testTdf123870);
@@ -460,6 +462,66 @@ void ScPDFExportTest::testTdf159068()
     CPPUNIT_ASSERT_EQUAL(static_cast<decltype(nArtifact)>(5), nArtifact);
 }
 
+void ScPDFExportTest::testTdf159067()
+{
+    loadFromFile(u"tdf159067.ods");
+    uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
+
+    // A1:B3
+    ScRange range1(0, 0, 0, 1, 2, 0);
+    exportToPDF(xModel, range1);
+
+    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());
+
+    vcl::filter::PDFObjectElement* pContents = 
aPages[0]->LookupObject("Contents"_ostr);
+    CPPUNIT_ASSERT(pContents);
+    vcl::filter::PDFStreamElement* pStream = pContents->GetStream();
+    CPPUNIT_ASSERT(pStream);
+
+    SvMemoryStream& rObjectStream = pStream->GetMemory();
+    // Uncompress it.
+    SvMemoryStream aUncompressed;
+    ZCodec aZCodec;
+    aZCodec.BeginCompression();
+    rObjectStream.Seek(0);
+    aZCodec.Decompress(rObjectStream, aUncompressed);
+    CPPUNIT_ASSERT(aZCodec.EndCompression());
+
+    auto pStart = static_cast<const char*>(aUncompressed.GetData());
+    const char* const pEnd = pStart + aUncompressed.GetSize();
+
+    auto nArtifact(0);
+    auto nLine(0);
+    while (true)
+    {
+        ++nLine;
+        auto const pLine = ::std::find(pStart, pEnd, '
');
+        if (pLine == pEnd)
+        {
+            break;
+        }
+        std::string_view const line(pStart, pLine - pStart);
+        pStart = pLine + 1;
+        if (!line.empty() && line[0] != '%')
+        {
+            ::std::cerr << nLine << ": " << line << "
 ";
+            if (o3tl::starts_with(line, "/Artifact BMC"))
+                nArtifact++;
+        }
+    }
+
+    // Without the fix in place, this test would have failed with
+    // - Expected: 3 (Artifact: Header, Footer, TextBox)
+    // - Actual  : 2 (Artifact: Header, Footer)
+    CPPUNIT_ASSERT_EQUAL(static_cast<decltype(nArtifact)>(3), nArtifact);
+}
+
 void ScPDFExportTest::testTdf159066()
 {
     loadFromFile(u"tdf159066.ods");
diff --git a/sc/qa/extras/testdocuments/tdf159067.ods 
b/sc/qa/extras/testdocuments/tdf159067.ods
new file mode 100644
index 000000000000..a6e268d0d94b
Binary files /dev/null and b/sc/qa/extras/testdocuments/tdf159067.ods differ
diff --git a/svx/source/sdr/contact/viewobjectcontact.cxx 
b/svx/source/sdr/contact/viewobjectcontact.cxx
index 09593f129f4b..c962e77eb33c 100644
--- a/svx/source/sdr/contact/viewobjectcontact.cxx
+++ b/svx/source/sdr/contact/viewobjectcontact.cxx
@@ -422,6 +422,7 @@ void 
ViewObjectContact::createStructureTag(drawinglayer::primitive2d::Primitive2
                                 eElement,
                                 bBackground,
                                 bImage,
+                                false, // Decorative
                                 std::move(rNewPrimitiveSequence),
                                 pAnchorKey,
                                 &annotIds))
@@ -438,6 +439,7 @@ void 
ViewObjectContact::createStructureTag(drawinglayer::primitive2d::Primitive2
                         vcl::PDFWriter::Division,
                         true,
                         true,
+                        true, // Decorative
                         std::move(rNewPrimitiveSequence))
                 };
         }
diff --git a/svx/source/table/viewcontactoftableobj.cxx 
b/svx/source/table/viewcontactoftableobj.cxx
index ac7472c7126c..b0accab93498 100644
--- a/svx/source/table/viewcontactoftableobj.cxx
+++ b/svx/source/table/viewcontactoftableobj.cxx
@@ -384,6 +384,7 @@ namespace sdr::contact
                                         eType,
                                         pPage->IsMasterPage(),
                                         false,
+                                        false,
                                         std::move(cell)) };
                             }
                             row.append(cell);
@@ -396,6 +397,7 @@ namespace sdr::contact
                                     vcl::PDFWriter::TableRow,
                                     pPage->IsMasterPage(),
                                     false,
+                                    false,
                                     std::move(row)) };
                         }
                         aRetval.append(row);

Reply via email to