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.stahl@allotropia.de>
(cherry picked from commit 122b4264d23df8b11419839ba700b88c4f936a6c)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143292
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/sw/source/core/text/EnhancedPDFExportHelper.cxx b/sw/source/core/text/EnhancedPDFExportHelper.cxx
index 6afa864..9f0b028 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 0000000..78f05b0
--- /dev/null
+++ b/vcl/qa/cppunit/pdfexport/data/Description PDF Export test .odt
Binary files differ
diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
index 6b0f90a..461bb93 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";