sw/source/core/layout/paintfrm.cxx              |   15 ++--
 sw/source/core/text/EnhancedPDFExportHelper.cxx |    8 +-
 vcl/qa/cppunit/pdfexport/data/tdf139736-1.odt   |binary
 vcl/qa/cppunit/pdfexport/pdfexport.cxx          |   86 ++++++++++++++++++++++++
 4 files changed, 101 insertions(+), 8 deletions(-)

New commits:
commit f91da6e6063e0494559a015a0ec6ea38fcb30baa
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Wed Oct 19 16:38:02 2022 +0200
Commit:     Caolán McNamara <caol...@redhat.com>
CommitDate: Mon Oct 24 21:03:50 2022 +0200

    tdf#139736 sw: PDF/UA export: flys in header/footer are Artifacts
    
    * flys anchored in header/footer cannot simply be ignored, they need to
      get NonStructElement tag which is translated to "/Artifact"
    * borders of flys need to get "/Artifact" tag as well; this is also the
      case if they're anchored in the body as veraPDF complains
    
    Change-Id: Id69f0d80c59c3ade295da46c4413a5f0e8d96d54
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/141534
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>
    (cherry picked from commit 72b69b422d33308809070e98a6ea8daad93e16d2)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/141734
    Reviewed-by: Caolán McNamara <caol...@redhat.com>

diff --git a/sw/source/core/layout/paintfrm.cxx 
b/sw/source/core/layout/paintfrm.cxx
index d470b1ae030f..7cae991210d7 100644
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -4287,12 +4287,15 @@ void SwFlyFrame::PaintSwFrame(vcl::RenderContext& 
rRenderContext, SwRect const&
 
     Validate();
 
-    // first paint lines added by fly frame paint
-    // and then unlock other lines.
-    gProp.pSLines->PaintLines( &rRenderContext, gProp );
-    gProp.pSLines->LockLines( false );
-    // have to paint frame borders added in heaven layer here...
-    ProcessPrimitives(gProp.pBLines->GetBorderLines_Clear());
+    {
+        SwTaggedPDFHelper tag(nullptr, nullptr, nullptr, *pShell->GetOut());
+        // first paint lines added by fly frame paint
+        // and then unlock other lines.
+        gProp.pSLines->PaintLines( &rRenderContext, gProp );
+        gProp.pSLines->LockLines( false );
+        // have to paint frame borders added in heaven layer here...
+        ProcessPrimitives(gProp.pBLines->GetBorderLines_Clear());
+    }
 
     PaintDecorators();
 
diff --git a/sw/source/core/text/EnhancedPDFExportHelper.cxx 
b/sw/source/core/text/EnhancedPDFExportHelper.cxx
index 30c1db446868..ccec950bb954 100644
--- a/sw/source/core/text/EnhancedPDFExportHelper.cxx
+++ b/sw/source/core/text/EnhancedPDFExportHelper.cxx
@@ -969,7 +969,7 @@ void SwTaggedPDFHelper::BeginBlockStructureElements()
 
     // Lowers of NonStructureElements should not be considered:
 
-    if ( lcl_IsInNonStructEnv( *pFrame ) )
+    if (lcl_IsInNonStructEnv(*pFrame) && !pFrame->IsFlyFrame())
         return;
 
     // Check if we have to reopen an existing structure element.
@@ -1258,7 +1258,11 @@ void SwTaggedPDFHelper::BeginBlockStructureElements()
             // fly in content or fly at page
             {
                 const SwFlyFrame* pFly = static_cast<const 
SwFlyFrame*>(pFrame);
-                if ( pFly->Lower() && pFly->Lower()->IsNoTextFrame() )
+                if (pFly->GetAnchorFrame()->FindFooterOrHeader() != nullptr)
+                {
+                    nPDFType = vcl::PDFWriter::NonStructElement;
+                }
+                else if (pFly->Lower() && pFly->Lower()->IsNoTextFrame())
                 {
                     bool bFormula = false;
 
diff --git a/vcl/qa/cppunit/pdfexport/data/tdf139736-1.odt 
b/vcl/qa/cppunit/pdfexport/data/tdf139736-1.odt
new file mode 100644
index 000000000000..f17f6037885c
Binary files /dev/null and b/vcl/qa/cppunit/pdfexport/data/tdf139736-1.odt 
differ
diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx 
b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
index fb821a7777e4..51d5e93b9529 100644
--- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx
+++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
@@ -2987,6 +2987,92 @@ CPPUNIT_TEST_FIXTURE(PdfExportTest, testPdfUaMetadata)
     CPPUNIT_ASSERT_EQUAL(OString("1"), aPdfUaPart);
 }
 
+CPPUNIT_TEST_FIXTURE(PdfExportTest, testTdf139736)
+{
+    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"tdf139736-1.odt");
+
+    vcl::filter::PDFDocument aDocument;
+    SvFileStream aStream(maTempFile.GetURL(), StreamMode::READ);
+    CPPUNIT_ASSERT(aDocument.Read(aStream));
+
+    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");
+    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();
+
+    enum
+    {
+        Default,
+        Artifact,
+        Tagged
+    } state
+        = Default;
+
+    auto nLine(0);
+    auto nTagged(0);
+    auto nArtifacts(0);
+    while (true)
+    {
+        ++nLine;
+        auto const pLine = ::std::find(pStart, pEnd, '\n');
+        if (pLine == pEnd)
+        {
+            break;
+        }
+        std::string_view const line(pStart, pLine - pStart);
+        pStart = pLine + 1;
+        if (!line.empty() && line[0] != '%')
+        {
+            ::std::cerr << nLine << ": " << line << "\n";
+            if (line == "/Artifact BMC")
+            {
+                CPPUNIT_ASSERT_EQUAL_MESSAGE("unexpected nesting", Default, 
state);
+                state = Artifact;
+                ++nArtifacts;
+            }
+            else if (line == "/Standard<</MCID 0>>BDC")
+            {
+                CPPUNIT_ASSERT_EQUAL_MESSAGE("unexpected nesting", Default, 
state);
+                state = Tagged;
+                ++nTagged;
+            }
+            else if (line == "EMC")
+            {
+                CPPUNIT_ASSERT_MESSAGE("unexpected end", state != Default);
+                state = Default;
+            }
+            else if (nLine > 1) // first line is expected "0.1 w"
+            {
+                CPPUNIT_ASSERT_MESSAGE("unexpected content outside MCS", state 
!= Default);
+            }
+        }
+    }
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("unclosed MCS", Default, state);
+    CPPUNIT_ASSERT_EQUAL(static_cast<decltype(nTagged)>(1), nTagged); // text 
in body
+    // 1 image and 1 frame and 1 header text; arbitrary number of aux stuff 
like borders
+    CPPUNIT_ASSERT(nArtifacts >= 3);
+}
+
 CPPUNIT_TEST_FIXTURE(PdfExportTest, testTdf142129)
 {
     OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "master.odm";

Reply via email to