[Libreoffice-commits] core.git: Branch 'feature/taggedPDF' - 5 commits - drawinglayer/source include/drawinglayer include/oox oox/source sd/qa sd/source svx/source sw/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Mon Feb 4 12:32:54 UTC 2019


Rebased ref, commits from common ancestor:
commit bf48032e99ad255c1b66036ef2c919093b2fd859
Author:     Katarina Behrens <Katarina.Behrens at cib.de>
AuthorDate: Mon Feb 4 11:54:27 2019 +0100
Commit:     Katarina Behrens <Katarina.Behrens at cib.de>
CommitDate: Mon Feb 4 13:24:14 2019 +0100

    PPTX import of shape description
    
    (cherry picked from commit dc1d26e5a3f0b75e729b58d5848493a48cb532bd)
    
    Change-Id: I7fcd5608a8cdbeea9ea15c9c9aa32c9020154750

diff --git a/include/oox/drawingml/shape.hxx b/include/oox/drawingml/shape.hxx
index 9dd643b34ae8..28a5e2907494 100644
--- a/include/oox/drawingml/shape.hxx
+++ b/include/oox/drawingml/shape.hxx
@@ -148,6 +148,7 @@ public:
     const OUString&                 getInternalName() const { return msInternalName; }
     void                            setId( const OUString& rId ) { msId = rId; }
     const OUString&                 getId() { return msId; }
+    void                            setDescription( const OUString& rDescr ) { msDescription = rDescr; }
     void                            setHidden( bool bHidden ) { mbHidden = bHidden; }
     void                            setHiddenMasterShape( bool bHiddenMasterShape ) { mbHiddenMasterShape = bHiddenMasterShape; }
     void                            setSubType( sal_Int32 nSubType ) { mnSubType = nSubType; }
@@ -291,6 +292,7 @@ protected:
     OUString                    msName;
     OUString                    msInternalName; // used by diagram; not displayed in UI
     OUString                    msId;
+    OUString                    msDescription;
     sal_Int32                   mnSubType;      // if this type is not zero, then the shape is a placeholder
     OptValue< sal_Int32 >       moSubTypeIndex;
 
diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx
index 09f828e8bfa8..b935bec0de96 100644
--- a/oox/source/drawingml/shape.cxx
+++ b/oox/source/drawingml/shape.cxx
@@ -832,6 +832,11 @@ Reference< XShape > const & Shape::createAndInsert(
             if( xNamed.is() )
                 xNamed->setName( msName );
         }
+        if( !msDescription.isEmpty() )
+        {
+            const OUString sDescription( "Description" );
+            xSet->setPropertyValue( sDescription, Any( msDescription ) );
+        }
         if (aServiceName != "com.sun.star.text.TextFrame")
             rxShapes->add( mxShape );
 
diff --git a/oox/source/drawingml/shapecontext.cxx b/oox/source/drawingml/shapecontext.cxx
index eae01bfe5a6c..60feae99f656 100644
--- a/oox/source/drawingml/shapecontext.cxx
+++ b/oox/source/drawingml/shapecontext.cxx
@@ -74,6 +74,7 @@ ContextHandlerRef ShapeContext::onCreateContext( sal_Int32 aElementToken, const
         mpShapePtr->setHidden( rAttribs.getBool( XML_hidden, false ) );
         mpShapePtr->setId( rAttribs.getString( XML_id ).get() );
         mpShapePtr->setName( rAttribs.getString( XML_name ).get() );
+        mpShapePtr->setDescription( rAttribs.getString( XML_descr ).get() );
         break;
     }
     case XML_hlinkMouseOver:
diff --git a/sd/qa/unit/data/pptx/altdescription.pptx b/sd/qa/unit/data/pptx/altdescription.pptx
new file mode 100644
index 000000000000..5398f7a72d6d
Binary files /dev/null and b/sd/qa/unit/data/pptx/altdescription.pptx differ
diff --git a/sd/qa/unit/import-tests.cxx b/sd/qa/unit/import-tests.cxx
index 4a60ca586719..aba1002055ec 100644
--- a/sd/qa/unit/import-tests.cxx
+++ b/sd/qa/unit/import-tests.cxx
@@ -194,6 +194,7 @@ public:
     void testTdf120028b();
     void testTdf94238();
     void testTdf44223();
+    void testDescriptionImport();
 
     CPPUNIT_TEST_SUITE(SdImportTest);
 
@@ -279,6 +280,7 @@ public:
     CPPUNIT_TEST(testTdf120028b);
     CPPUNIT_TEST(testTdf94238);
     CPPUNIT_TEST(testTdf44223);
+    CPPUNIT_TEST(testDescriptionImport);
 
     CPPUNIT_TEST_SUITE_END();
 };
@@ -2648,6 +2650,22 @@ void SdImportTest::testTdf44223()
     CPPUNIT_ASSERT(xNameAccess_2->hasByName("audio2.wav"));
 
     xDocShRef->DoClose();
+
+void SdImportTest::testDescriptionImport()
+{
+    sd::DrawDocShellRef xDocShRef
+        = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/altdescription.pptx"), PPTX);
+
+    uno::Reference<beans::XPropertySet> xPropertySet(
+        getShapeFromPage(/*nShape=*/2, /*nPage=*/0, xDocShRef));
+    OUString sDesc;
+
+    xPropertySet->getPropertyValue("Description") >>= sDesc;
+
+    CPPUNIT_ASSERT_EQUAL(OUString("We Can Do It!"), sDesc);
+
+    xDocShRef->DoClose();
+
 }
 
 CPPUNIT_TEST_SUITE_REGISTRATION(SdImportTest);
commit 18ac44e213e77e8c8eaba3f9bd32098b0a36692c
Author:     Katarina Behrens <Katarina.Behrens at cib.de>
AuthorDate: Thu Jan 31 17:18:36 2019 +0100
Commit:     Katarina Behrens <Katarina.Behrens at cib.de>
CommitDate: Mon Feb 4 13:24:13 2019 +0100

    Export background images provided by master page as artifacts
    
    so that screenreaders don't announce them. To make this happen,
    pass them as NonStructElement to PDF writer
    
    Change-Id: I94d52ee0207cd6362edabfb9b891faa7fe341543
    (cherry picked from commit bf978a527fb0bba27cd2c83443e70ad86a63d819)

diff --git a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
index 71a6125e2ff1..60f45740b66a 100644
--- a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
@@ -2217,38 +2217,14 @@ namespace drawinglayer
         {
             // structured tag primitive
             const vcl::PDFWriter::StructElement& rTagElement(rStructureTagCandidate.getStructureElement());
-            bool bTagUsed(vcl::PDFWriter::NonStructElement != rTagElement);
+            const bool bTagUsed(vcl::PDFWriter::NonStructElement != rTagElement);
+            const bool bIsBackground(rStructureTagCandidate.isBackground());
 
-            //Z For now, just do not create StructureTag(s) for hidden/background
-            // (Graphic)Objects - see '/Artifact' comments below
-            if(bTagUsed && rStructureTagCandidate.isBackground())
+            if(mpPDFExtOutDevData && bTagUsed)
             {
-                bTagUsed = false;
-            }
-
-            if(mpPDFExtOutDevData &&  bTagUsed)
-            {
-                // write start tag
-                mpPDFExtOutDevData->BeginStructureElement(rTagElement);
-
-                // if(rStructureTagCandidate.isBackground())
-                // {
-                //     //Z need to somehow apply '/Artifact' information...
-                //     // - Already experimented with adding two BeginStructureElement adding
-                //     //   a 'vcl::PDFWriter::Artifact' -> not really what e.g. PAC3 expects.
-                //     // - May also be adding someting using 'SetStructureAttribute' and
-                //     //   extending vcl::PDFWriter::StructAttribute...
-                //     // - Simple solution for now (see above): Just do not create
-                //     //   StructureTag(s) for hidden/background (Graphic)Objects. That
-                //     //   works, shows all content in PDF renderers, but hides in
-                //     //   TaggedStructure. But: also not visible in PAC3's 'LogicalStructure'
-                //     //   View where there is a tab for 'Artifacts' - I *guess* a correctly
-                //     //   tagged '/Artifact' should appear there.
-                //     // Unfortunately found no real example - there is https://www.w3.org/TR/WCAG20-TECHS/PDF4.html
-                //     // which claims to have an example in
-                //     // https://www.w3.org/WAI/WCAG20/Techniques/working-examples/PDF4/decorative-image.docx
-                //     // but that file has no '/Artifact' entries at all...
-                // }
+                // Write start tag. For background elements use NonStructElement instead of real element type (e.g. Figure)
+                // to guarantee it gets exported as artifact (tagged PDF)
+                mpPDFExtOutDevData->BeginStructureElement(bIsBackground ? vcl::PDFWriter::NonStructElement : rTagElement);
             }
 
             // process children normally
commit a78d4d81827b64cd9e4153863ef252dd9cd931ab
Author:     Katarina Behrens <Katarina.Behrens at cib.de>
AuthorDate: Tue Jan 29 16:20:56 2019 +0100
Commit:     Katarina Behrens <Katarina.Behrens at cib.de>
CommitDate: Mon Feb 4 13:24:12 2019 +0100

    Process entire list item (Lbl + LBody) in tagged PDF-compliant way
    
    implemented as described in
    https://www.adobe.com/content/dam/acom/en/devnet/pdf/pdfs/PDF32000_2008.pdf#G21.1021281
    
    Change-Id: I943c35cb8ee833ff46ff594e6b6c1025450b9ca4
    (cherry picked from commit 98270dafaba733db4660bbd22f2f1f96bf1d6282)

diff --git a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
index ce5c579b5646..71a6125e2ff1 100644
--- a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
@@ -563,7 +563,9 @@ namespace drawinglayer
             mnSvtGraphicStrokeCount(0),
             mfCurrentUnifiedTransparence(0.0),
             mpPDFExtOutDevData(dynamic_cast< vcl::PDFExtOutDevData* >(rOutDev.GetExtOutDevData())),
-            mnCurrentOutlineLevel(-1)
+            mnCurrentOutlineLevel(-1),
+            mbInListItem(false),
+            mbBulletPresent(false)
         {
             OSL_ENSURE(rOutDev.GetConnectMetaFile(), "VclMetafileProcessor2D: Used on OutDev which has no MetaFile Target (!)");
             // draw to logic coordinates, do not initialize maCurrentTransformation to viewTransformation
@@ -1232,9 +1234,19 @@ namespace drawinglayer
             // "XTEXT_EOC" is used, use here, too.
             const OString aCommentString("XTEXT_EOC");
 
+            // this is a part of list item, start LILabel ( = bullet)
+            if(mbInListItem)
+                mpPDFExtOutDevData->BeginStructureElement(vcl::PDFWriter::LILabel);
+
             // process recursively and add MetaFile comment
             process(rBulletPrimitive);
             mpMetaFile->AddAction(new MetaCommentAction(aCommentString));
+
+            if(mbInListItem)
+            {
+                mpPDFExtOutDevData->EndStructureElement(); // end LILabel
+                mbBulletPresent = true;
+            }
         }
 
         void VclMetafileProcessor2D::processTextHierarchyParagraphPrimitive2D(const primitive2d::TextHierarchyParagraphPrimitive2D& rParagraphPrimitive)
@@ -1301,7 +1313,7 @@ namespace drawinglayer
             {
                 // Dump as ListItem
                 mpPDFExtOutDevData->BeginStructureElement( vcl::PDFWriter::ListItem );
-                mpPDFExtOutDevData->BeginStructureElement( vcl::PDFWriter::LIBody );
+                mbInListItem = true;
             }
             else
             {
@@ -1315,7 +1327,8 @@ namespace drawinglayer
 
             if(bDumpAsListItem)
             {
-                mpPDFExtOutDevData->EndStructureElement();
+                mpPDFExtOutDevData->EndStructureElement(); // end ListItem
+                mbInListItem = false;
             }
 
             mpPDFExtOutDevData->EndStructureElement();
@@ -1338,9 +1351,20 @@ namespace drawinglayer
             const DrawModeFlags nOriginalDrawMode(mpOutputDevice->GetDrawMode());
             adaptTextToFillDrawMode();
 
+            // this is a 2nd portion of list item
+            // bullet has been already processed, start LIBody
+            if (mbInListItem && mbBulletPresent)
+                mpPDFExtOutDevData->BeginStructureElement(vcl::PDFWriter::LIBody);
+
             // directdraw of text simple portion; use default processing
             RenderTextSimpleOrDecoratedPortionPrimitive2D(rTextCandidate);
 
+            if (mbInListItem && mbBulletPresent)
+            {
+                mpPDFExtOutDevData->EndStructureElement(); // end LIBody
+                mbBulletPresent = false;
+            }
+
             // restore DrawMode
             mpOutputDevice->SetDrawMode(nOriginalDrawMode);
 
diff --git a/drawinglayer/source/processor2d/vclmetafileprocessor2d.hxx b/drawinglayer/source/processor2d/vclmetafileprocessor2d.hxx
index 410f332cbd76..3806a683b4da 100644
--- a/drawinglayer/source/processor2d/vclmetafileprocessor2d.hxx
+++ b/drawinglayer/source/processor2d/vclmetafileprocessor2d.hxx
@@ -174,6 +174,8 @@ namespace drawinglayer
             // like '/L', '/LI', 'LBody' instead of simple '/P' (Paragraph).
             // The value -1 means 'no OutlineLevel' and values >= 0 express the level.
             sal_Int16                           mnCurrentOutlineLevel;
+            bool mbInListItem;
+            bool mbBulletPresent;
 
         protected:
             /*  the local processor for BasePrimitive2D-Implementation based primitives,
commit 2eb25159564b4733ae2eb839558fcee296976330
Author:     Katarina Behrens <Katarina.Behrens at cib.de>
AuthorDate: Tue Jan 15 14:11:49 2019 +0100
Commit:     Katarina Behrens <Katarina.Behrens at cib.de>
CommitDate: Mon Feb 4 13:24:11 2019 +0100

    Different way to determine if paragraph is within a list
    
    pptx import seems little flaky in this regard, EE_PARA_OUTLLEVEL
    isn't always set (no such problem with odp). Instead, we'll query
    paragraph's depth and visibility of bullets/numbering
    
    Change-Id: Ia8cf6b7bb0e065a1378875442a99d79b006e2d77
    (cherry picked from commit 2f5c61ce217c5db20059b16f681d65580a7577c7)

diff --git a/svx/source/svdraw/svdotextdecomposition.cxx b/svx/source/svdraw/svdotextdecomposition.cxx
index fb02ac86b79a..a4b7163d1977 100644
--- a/svx/source/svdraw/svdotextdecomposition.cxx
+++ b/svx/source/svdraw/svdotextdecomposition.cxx
@@ -484,15 +484,15 @@ namespace
 
     void impTextBreakupHandler::impFlushLinePrimitivesToParagraphPrimitives(sal_Int32 nPara)
     {
+        sal_Int16 nDepth = mrOutliner.GetDepth(nPara);
+        EBulletInfo eInfo = mrOutliner.GetBulletInfo(nPara);
+        // Pass -1 to signal VclMetafileProcessor2D that there is no active
+        // bullets/numbering in this paragraph (i.e. this is normal text)
+        const sal_Int16 nOutlineLevel( eInfo.bVisible ?  nDepth : -1);
+
         // ALWAYS create a paragraph primitive, even when no content was added. This is done to
         // have the correct paragraph count even with empty paragraphs. Those paragraphs will
         // have an empty sub-PrimitiveSequence.
-        const sal_Int16 nOutlineLevel(nPara >= 0 && nPara < mrOutliner.GetParagraphCount()
-            ? mrOutliner.GetParaAttribs(nPara).Get(EE_PARA_OUTLLEVEL).GetValue()
-            : -1);
-
-        //Z This basically makes OutlineLevel information available in VclMetafileProcessor2D,
-        //Z so may be used similar to 'SetAlternateText' in processGraphicPrimitive2D for PDF export
         maParagraphPrimitives.push_back(
             new drawinglayer::primitive2d::TextHierarchyParagraphPrimitive2D(
                 maLinePrimitives,
commit 85804b1a94702d4fc96ecda822eb78138d91cab3
Author:     Armin Le Grand <Armin.Le.Grand at cib.de>
AuthorDate: Thu Dec 20 17:31:32 2018 +0100
Commit:     Katarina Behrens <Katarina.Behrens at cib.de>
CommitDate: Mon Feb 4 13:24:02 2019 +0100

    Enhance TaggedPDF export (accessibility)
    
    The current tagged PDF export does not well support
    quite some internal structures. This includes all
    apps (Draw/Impress/Writer/Calc) and some areas.
    
    Area AlternativeText ('/Alt'):
    
    Only writer currently at least adds Title information,
    but we also have Description (MS does add) and Name.
    Target is to add this information when available to
    content frames.
    Writer did that by manually adding that tag using
    PDFExtOutDevData::SetAlternateText, but only used
    Title so far.
    To make this work as broad as possible, better add
    this to primitives. There is already a primitive called
    ObjectInfoPrimitive2D that encapsulates any content
    adding Name/Title/Description using GroupPrimitive
    functionality.
    Changed Writer to use that way. Draw/Impress already
    uses it, all apps now use graphic paint using primitives,
    so we have a natural target to encapsulate. Add support
    to VclMetafileProcessor2D to interpret it and add
    - if mpPDFExtOutDevData->GetIsExportTaggedPDF() - that
    data using a combination of Name/Title/Description and
    add using mpPDFExtOutDevData->SetAlternateText.
    This works for Draw/Impress/Writer, but not for Calc
    because Calc does not create more complex data structures,
    so SetAlternateText does not work (see
    PDFWriterImpl::setAlternateText for more infos).
    
    Area Tagged ListContent (use 'L', 'LI', 'LBody' PDF tags):
    
    To support this in Draw/Impress, we can also use a similar
    way to support in primitives. For this I evaluated how to
    add needed OutlineLevel information to the existing (and
    already used to write 'P') TextHierarchyParagraphPrimitive2D.
    Added this and now ready to use in VclMetafileProcessor2D
    ::processTextHierarchyParagraphPrimitive2D.
    Added now using the OutlineLevel information at the
    TextHierarchyParagraphPrimitive2D. Made sure there are
    fallbacks to unchanged old behaviour when no PDF export
    or no Tagged-PDF used. Creating now '/L', '/LI' and '/LBody'
    statements as tagged PDF wants us to do.
    Exported PDF still works well while additionally a verifier
    as 'PAC 3' shows the expected and wanted structure.
    This will work now for any text in Draw/Impress and for
    Draw-Objects using Lists in Calc. Need to check for direct
    text in Calc cells and Writer - and guess how big the
    effort would be for these to make it work there, too.
    
    Area '/Artifact':
    
    Target is to avoid too much ScreenReader hassle when
    Impress uses Pictures/FillPatterns etc. in Background
    - what means on MasterPage in Impress.
    Experimented with different possibilities. Decided to use
    existing StructureTagPrimitive2D and extend for info if
    encapsulated data is 'Background' data -> on MasterPage.
    Can be created in ImplRenderPaintProc in method
    createRedirectedPrimitive2DSeque as needed by checking
    for MasterPage member (remember: primitives need to be
    as independent from model data as possible, never include
    e.g. a SdrObject reference in any way).
    Tried different ways to use this in VclMetafileProcessor2D
    processStructureTagPrimitive2D, see comments there. Current
    best solution is to just *not* create StuctureTag information
    for these objects.
    
    (cherry picked from commit b1245b227021c3dee75a4c420c5db320ea6e1afb)
    
    Change-Id: Ib2a578b02c1256758cda6d15ce37799803d8205c

diff --git a/drawinglayer/source/primitive2d/structuretagprimitive2d.cxx b/drawinglayer/source/primitive2d/structuretagprimitive2d.cxx
index e76269788378..41f5577efa16 100644
--- a/drawinglayer/source/primitive2d/structuretagprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/structuretagprimitive2d.cxx
@@ -30,12 +30,26 @@ namespace drawinglayer
     {
         StructureTagPrimitive2D::StructureTagPrimitive2D(
             const vcl::PDFWriter::StructElement& rStructureElement,
+            bool bBackground,
             const Primitive2DContainer& rChildren)
         :   GroupPrimitive2D(rChildren),
-            maStructureElement(rStructureElement)
+            maStructureElement(rStructureElement),
+            mbBackground(bBackground)
         {
         }
 
+        bool StructureTagPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+        {
+            if(GroupPrimitive2D::operator==(rPrimitive))
+            {
+                const StructureTagPrimitive2D& rCompare = static_cast<const StructureTagPrimitive2D&>(rPrimitive);
+
+                return (isBackground() == rCompare.isBackground());
+            }
+
+            return false;
+        }
+
         // provide unique ID
         ImplPrimitive2DIDBlock(StructureTagPrimitive2D, PRIMITIVE2D_ID_STRUCTURETAGPRIMITIVE2D)
 
diff --git a/drawinglayer/source/primitive2d/texthierarchyprimitive2d.cxx b/drawinglayer/source/primitive2d/texthierarchyprimitive2d.cxx
index 45fa8531bee3..cbacb022759c 100644
--- a/drawinglayer/source/primitive2d/texthierarchyprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/texthierarchyprimitive2d.cxx
@@ -44,9 +44,24 @@ namespace drawinglayer
 {
     namespace primitive2d
     {
-        TextHierarchyParagraphPrimitive2D::TextHierarchyParagraphPrimitive2D(const Primitive2DContainer& rChildren)
-        :   GroupPrimitive2D(rChildren)
+        TextHierarchyParagraphPrimitive2D::TextHierarchyParagraphPrimitive2D(
+            const Primitive2DContainer& rChildren,
+            sal_Int16 nOutlineLevel)
+        :   GroupPrimitive2D(rChildren),
+            mnOutlineLevel(nOutlineLevel)
+        {
+        }
+
+        bool TextHierarchyParagraphPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
         {
+            if(GroupPrimitive2D::operator==(rPrimitive))
+            {
+                const TextHierarchyParagraphPrimitive2D& rCompare = static_cast<const TextHierarchyParagraphPrimitive2D&>(rPrimitive);
+
+                return (getOutlineLevel() == rCompare.getOutlineLevel());
+            }
+
+            return false;
         }
 
         // provide unique ID
diff --git a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
index c8cb3734a376..ce5c579b5646 100644
--- a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
@@ -69,6 +69,9 @@
 // for StructureTagPrimitive support in sd's unomodel.cxx
 #include <drawinglayer/primitive2d/structuretagprimitive2d.hxx>
 
+// for support of Title/Description in all apps when embedding pictures
+#include <drawinglayer/primitive2d/objectinfoprimitive2d.hxx>
+
 using namespace com::sun::star;
 
 // #112245# definition for maximum allowed point count due to Metafile target.
@@ -559,7 +562,8 @@ namespace drawinglayer
             mnSvtGraphicFillCount(0),
             mnSvtGraphicStrokeCount(0),
             mfCurrentUnifiedTransparence(0.0),
-            mpPDFExtOutDevData(dynamic_cast< vcl::PDFExtOutDevData* >(rOutDev.GetExtOutDevData()))
+            mpPDFExtOutDevData(dynamic_cast< vcl::PDFExtOutDevData* >(rOutDev.GetExtOutDevData())),
+            mnCurrentOutlineLevel(-1)
         {
             OSL_ENSURE(rOutDev.GetConnectMetaFile(), "VclMetafileProcessor2D: Used on OutDev which has no MetaFile Target (!)");
             // draw to logic coordinates, do not initialize maCurrentTransformation to viewTransformation
@@ -898,6 +902,11 @@ namespace drawinglayer
                     RenderEpsPrimitive2D(static_cast< const primitive2d::EpsPrimitive2D& >(rCandidate));
                     break;
                 }
+                case PRIMITIVE2D_ID_OBJECTINFOPRIMITIVE2D :
+                {
+                    RenderObjectInfoPrimitive2D(static_cast< const primitive2d::ObjectInfoPrimitive2D& >(rCandidate));
+                    break;
+                }
                 default :
                 {
                     // process recursively
@@ -991,10 +1000,48 @@ namespace drawinglayer
                         sal_Int32(ceil(aCropRange.getMaxX())), sal_Int32(ceil(aCropRange.getMaxY())));
                 }
 
+                // Create image alternative description from ObjectInfoPrimitive2D info
+                // for PDF export
+                if(mpPDFExtOutDevData->GetIsExportTaggedPDF() && nullptr != getObjectInfoPrimitive2D())
+                {
+                    OUString aAlternateDescription(getObjectInfoPrimitive2D()->getName());
+
+                    if(!getObjectInfoPrimitive2D()->getTitle().isEmpty())
+                    {
+                        if(!aAlternateDescription.isEmpty())
+                        {
+                            aAlternateDescription += " - ";
+                        }
+
+                        aAlternateDescription += getObjectInfoPrimitive2D()->getTitle();
+                    }
+
+                    if(!getObjectInfoPrimitive2D()->getDesc().isEmpty())
+                    {
+                        if(!aAlternateDescription.isEmpty())
+                        {
+                            aAlternateDescription += " - ";
+                        }
+
+                        aAlternateDescription += getObjectInfoPrimitive2D()->getDesc();
+                    }
+
+                    // Use SetAlternateText to set it. This will work as long as some
+                    // structure is used (see PDFWriterImpl::setAlternateText and
+                    // m_nCurrentStructElement - tagged PDF export works with this in
+                    // Draw/Impress/Writer, but not in Calc due to too less structure...)
+                    //Z maybe add structure to Calc PDF export, may need some BeginGroup/EndGroup stuff ..?
+                    if(!aAlternateDescription.isEmpty())
+                    {
+                        mpPDFExtOutDevData->SetAlternateText(aAlternateDescription);
+                    }
+                }
+
                 // #i123295# 3rd param is uncropped rect, 4th is cropped. The primitive has the cropped
                 // object transformation, thus aCurrentRect *is* the clip region while aCropRect is the expanded,
                 // uncropped region. Thus, correct order is aCropRect, aCurrentRect
-                mpPDFExtOutDevData->EndGroup(rGraphicPrimitive.getGraphicObject().GetGraphic(),
+                mpPDFExtOutDevData->EndGroup(
+                    rGraphicPrimitive.getGraphicObject().GetGraphic(),
                     rAttr.GetTransparency(),
                     aCropRect,
                     aCurrentRect);
@@ -1193,22 +1240,85 @@ namespace drawinglayer
         void VclMetafileProcessor2D::processTextHierarchyParagraphPrimitive2D(const primitive2d::TextHierarchyParagraphPrimitive2D& rParagraphPrimitive)
         {
             const OString aCommentString("XTEXT_EOP");
+            static bool bSuppressPDFExtOutDevDataSupport(false);
 
-            if(mpPDFExtOutDevData)
+            if(nullptr == mpPDFExtOutDevData || bSuppressPDFExtOutDevDataSupport)
             {
-                // emulate data handling from ImpEditEngine::Paint
+                // Non-PDF export behaviour (metafile only).
+                // Process recursively and add MetaFile comment.
+                process(rParagraphPrimitive);
+                mpMetaFile->AddAction(new MetaCommentAction(aCommentString));
+                return;
+            }
+
+            if(!mpPDFExtOutDevData->GetIsExportTaggedPDF())
+            {
+                // No Tagged PDF -> Dump as Paragraph
+                // Emulate data handling from old ImpEditEngine::Paint
                 mpPDFExtOutDevData->BeginStructureElement( vcl::PDFWriter::Paragraph );
+
+                // Process recursively and add MetaFile comment
+                process(rParagraphPrimitive);
+                mpMetaFile->AddAction(new MetaCommentAction(aCommentString));
+
+                // Emulate data handling from ImpEditEngine::Paint
+                mpPDFExtOutDevData->EndStructureElement();
+                return;
             }
 
-            // process recursively and add MetaFile comment
+            // Create Tagged PDF -> deeper tagged data using StructureElements.
+            // Use OutlineLevel from ParagraphPrimitive, ensure not below -1 what
+            // means 'not active'
+            const sal_Int16 nNewOutlineLevel(std::max(static_cast<sal_Int16>(-1), rParagraphPrimitive.getOutlineLevel()));
+
+            // Do we have a change in OutlineLevel compared to the current one?
+            if(nNewOutlineLevel != mnCurrentOutlineLevel)
+            {
+                if(nNewOutlineLevel > mnCurrentOutlineLevel)
+                {
+                    // increase List level
+                    for(sal_Int16 a(mnCurrentOutlineLevel); a != nNewOutlineLevel; a++)
+                    {
+                        mpPDFExtOutDevData->BeginStructureElement( vcl::PDFWriter::List );
+                    }
+                }
+                else // if(nNewOutlineLevel < mnCurrentOutlineLevel)
+                {
+                    // decrease List level
+                    for(sal_Int16 a(mnCurrentOutlineLevel); a != nNewOutlineLevel; a--)
+                    {
+                        mpPDFExtOutDevData->EndStructureElement();
+                    }
+                }
+
+                // Remember new current OutlineLevel
+                mnCurrentOutlineLevel = nNewOutlineLevel;
+            }
+
+            const bool bDumpAsListItem(-1 != mnCurrentOutlineLevel);
+
+            if(bDumpAsListItem)
+            {
+                // Dump as ListItem
+                mpPDFExtOutDevData->BeginStructureElement( vcl::PDFWriter::ListItem );
+                mpPDFExtOutDevData->BeginStructureElement( vcl::PDFWriter::LIBody );
+            }
+            else
+            {
+                // Dump as Paragraph
+                mpPDFExtOutDevData->BeginStructureElement( vcl::PDFWriter::Paragraph );
+            }
+
+            // Process recursively and add MetaFile comment
             process(rParagraphPrimitive);
             mpMetaFile->AddAction(new MetaCommentAction(aCommentString));
 
-            if(mpPDFExtOutDevData)
+            if(bDumpAsListItem)
             {
-                // emulate data handling from ImpEditEngine::Paint
                 mpPDFExtOutDevData->EndStructureElement();
             }
+
+            mpPDFExtOutDevData->EndStructureElement();
         }
 
         void VclMetafileProcessor2D::processTextHierarchyBlockPrimitive2D(const primitive2d::TextHierarchyBlockPrimitive2D& rBlockPrimitive)
@@ -2083,12 +2193,38 @@ namespace drawinglayer
         {
             // structured tag primitive
             const vcl::PDFWriter::StructElement& rTagElement(rStructureTagCandidate.getStructureElement());
-            const bool bTagUsed(vcl::PDFWriter::NonStructElement != rTagElement);
+            bool bTagUsed(vcl::PDFWriter::NonStructElement != rTagElement);
+
+            //Z For now, just do not create StructureTag(s) for hidden/background
+            // (Graphic)Objects - see '/Artifact' comments below
+            if(bTagUsed && rStructureTagCandidate.isBackground())
+            {
+                bTagUsed = false;
+            }
 
             if(mpPDFExtOutDevData &&  bTagUsed)
             {
                 // write start tag
                 mpPDFExtOutDevData->BeginStructureElement(rTagElement);
+
+                // if(rStructureTagCandidate.isBackground())
+                // {
+                //     //Z need to somehow apply '/Artifact' information...
+                //     // - Already experimented with adding two BeginStructureElement adding
+                //     //   a 'vcl::PDFWriter::Artifact' -> not really what e.g. PAC3 expects.
+                //     // - May also be adding someting using 'SetStructureAttribute' and
+                //     //   extending vcl::PDFWriter::StructAttribute...
+                //     // - Simple solution for now (see above): Just do not create
+                //     //   StructureTag(s) for hidden/background (Graphic)Objects. That
+                //     //   works, shows all content in PDF renderers, but hides in
+                //     //   TaggedStructure. But: also not visible in PAC3's 'LogicalStructure'
+                //     //   View where there is a tab for 'Artifacts' - I *guess* a correctly
+                //     //   tagged '/Artifact' should appear there.
+                //     // Unfortunately found no real example - there is https://www.w3.org/TR/WCAG20-TECHS/PDF4.html
+                //     // which claims to have an example in
+                //     // https://www.w3.org/WAI/WCAG20/Techniques/working-examples/PDF4/decorative-image.docx
+                //     // but that file has no '/Artifact' entries at all...
+                // }
             }
 
             // process children normally
diff --git a/drawinglayer/source/processor2d/vclmetafileprocessor2d.hxx b/drawinglayer/source/processor2d/vclmetafileprocessor2d.hxx
index 48e1614ca659..410f332cbd76 100644
--- a/drawinglayer/source/processor2d/vclmetafileprocessor2d.hxx
+++ b/drawinglayer/source/processor2d/vclmetafileprocessor2d.hxx
@@ -169,6 +169,12 @@ namespace drawinglayer
              */
             vcl::PDFExtOutDevData*              mpPDFExtOutDevData;
 
+            // Remember the current OutlineLevel. This is used when tagged PDF export
+            // is used to create/write valid structued list entries using PDF statements
+            // like '/L', '/LI', 'LBody' instead of simple '/P' (Paragraph).
+            // The value -1 means 'no OutlineLevel' and values >= 0 express the level.
+            sal_Int16                           mnCurrentOutlineLevel;
+
         protected:
             /*  the local processor for BasePrimitive2D-Implementation based primitives,
                 called from the common process()-implementation
diff --git a/drawinglayer/source/processor2d/vclprocessor2d.cxx b/drawinglayer/source/processor2d/vclprocessor2d.cxx
index c5ae3c970735..64f73b135efc 100644
--- a/drawinglayer/source/processor2d/vclprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclprocessor2d.cxx
@@ -62,6 +62,9 @@
 #include <basegfx/polygon/b2dpolygonclipper.hxx>
 #include <basegfx/polygon/b2dtrapezoid.hxx>
 
+// for support of Title/Description in all apps when embedding pictures
+#include <drawinglayer/primitive2d/objectinfoprimitive2d.hxx>
+
 using namespace com::sun::star;
 
 namespace
@@ -1201,6 +1204,19 @@ namespace drawinglayer
             }
         }
 
+        void VclProcessor2D::RenderObjectInfoPrimitive2D(const primitive2d::ObjectInfoPrimitive2D& rObjectInfoPrimitive2D)
+        {
+            // remember current ObjectInfoPrimitive2D and set new current one (build a stack - push)
+            const primitive2d::ObjectInfoPrimitive2D* pLast(getObjectInfoPrimitive2D());
+            mpObjectInfoPrimitive2D = &rObjectInfoPrimitive2D;
+
+            // process content
+            process(rObjectInfoPrimitive2D.getChildren());
+
+            // restore current ObjectInfoPrimitive2D (pop)
+            mpObjectInfoPrimitive2D = pLast;
+        }
+
         void VclProcessor2D::RenderSvgLinearAtomPrimitive2D(const primitive2d::SvgLinearAtomPrimitive2D& rCandidate)
         {
             const double fDelta(rCandidate.getOffsetB() - rCandidate.getOffsetA());
@@ -1409,7 +1425,8 @@ namespace drawinglayer
             maBColorModifierStack(),
             maCurrentTransformation(),
             maDrawinglayerOpt(),
-            mnPolygonStrokePrimitive2D(0)
+            mnPolygonStrokePrimitive2D(0),
+            mpObjectInfoPrimitive2D(nullptr)
         {
             // set digit language, derived from SvtCTLOptions to have the correct
             // number display for arabic/hindi numerals
diff --git a/drawinglayer/source/processor2d/vclprocessor2d.hxx b/drawinglayer/source/processor2d/vclprocessor2d.hxx
index beb6146f1535..84e7c524c091 100644
--- a/drawinglayer/source/processor2d/vclprocessor2d.hxx
+++ b/drawinglayer/source/processor2d/vclprocessor2d.hxx
@@ -51,6 +51,7 @@ namespace drawinglayer { namespace primitive2d {
     class ControlPrimitive2D;
     class PagePreviewPrimitive2D;
     class EpsPrimitive2D;
+    class ObjectInfoPrimitive2D;
     class SvgLinearAtomPrimitive2D;
     class SvgRadialAtomPrimitive2D;
 }}
@@ -86,9 +87,10 @@ namespace drawinglayer
             // PolygonStrokePrimitive2D's decompositions (normally only one)
             sal_uInt32                                              mnPolygonStrokePrimitive2D;
 
+            // currently used ObjectInfoPrimitive2D
+            const primitive2d::ObjectInfoPrimitive2D*               mpObjectInfoPrimitive2D;
 
             // common VCL rendering support
-
             void RenderTextSimpleOrDecoratedPortionPrimitive2D(const primitive2d::TextSimplePortionPrimitive2D& rTextCandidate);
             void RenderPolygonHairlinePrimitive2D(const primitive2d::PolygonHairlinePrimitive2D& rPolygonCandidate, bool bPixelBased);
             void RenderBitmapPrimitive2D(const primitive2d::BitmapPrimitive2D& rBitmapCandidate);
@@ -104,6 +106,7 @@ namespace drawinglayer
             void RenderPointArrayPrimitive2D(const primitive2d::PointArrayPrimitive2D& rPointArrayCandidate);
             void RenderPolygonStrokePrimitive2D(const primitive2d::PolygonStrokePrimitive2D& rPolygonStrokeCandidate);
             void RenderEpsPrimitive2D(const primitive2d::EpsPrimitive2D& rEpsPrimitive2D);
+            void RenderObjectInfoPrimitive2D(const primitive2d::ObjectInfoPrimitive2D& rObjectInfoPrimitive2D);
             void RenderSvgLinearAtomPrimitive2D(const primitive2d::SvgLinearAtomPrimitive2D& rCandidate);
             void RenderSvgRadialAtomPrimitive2D(const primitive2d::SvgRadialAtomPrimitive2D& rCandidate);
 
@@ -120,6 +123,9 @@ namespace drawinglayer
 
             // access to Drawinglayer configuration options
             const SvtOptionsDrawinglayer& getOptionsDrawinglayer() const { return maDrawinglayerOpt; }
+
+            // access to currently used ObjectInfoPrimitive2D
+            const primitive2d::ObjectInfoPrimitive2D* getObjectInfoPrimitive2D() const { return mpObjectInfoPrimitive2D; }
         };
     } // end of namespace processor2d
 } // end of namespace drawinglayer
diff --git a/include/drawinglayer/primitive2d/structuretagprimitive2d.hxx b/include/drawinglayer/primitive2d/structuretagprimitive2d.hxx
index 28f6aa86978a..b6e9ad94ede8 100644
--- a/include/drawinglayer/primitive2d/structuretagprimitive2d.hxx
+++ b/include/drawinglayer/primitive2d/structuretagprimitive2d.hxx
@@ -48,14 +48,23 @@ namespace drawinglayer
             /// the PDF structure element this grouping represents
             vcl::PDFWriter::StructElement           maStructureElement;
 
+            ///Z flag for background contenht that may be handled as
+            /// Tagged PDF '/Artifact'
+            bool                                    mbBackground;
+
         public:
             /// constructor
             StructureTagPrimitive2D(
                 const vcl::PDFWriter::StructElement& rStructureElement,
+                bool bBackground,
                 const Primitive2DContainer& rChildren);
 
             /// data read access
             const vcl::PDFWriter::StructElement& getStructureElement() const { return maStructureElement; }
+            bool isBackground() const { return mbBackground; }
+
+            /// compare operator
+            virtual bool operator==(const BasePrimitive2D& rPrimitive) const override;
 
             /// provide unique ID
             DeclPrimitive2DIDBlock()
diff --git a/include/drawinglayer/primitive2d/texthierarchyprimitive2d.hxx b/include/drawinglayer/primitive2d/texthierarchyprimitive2d.hxx
index 5234081584a3..5b08106b6912 100644
--- a/include/drawinglayer/primitive2d/texthierarchyprimitive2d.hxx
+++ b/include/drawinglayer/primitive2d/texthierarchyprimitive2d.hxx
@@ -86,9 +86,21 @@ namespace drawinglayer
         class DRAWINGLAYER_DLLPUBLIC TextHierarchyParagraphPrimitive2D : public GroupPrimitive2D
         {
         private:
+            // outline level of the encapsulated paragraph data.
+            // -1 means no level, >= 0 is the level
+            sal_Int16           mnOutlineLevel;
+
         public:
             /// constructor
-            explicit TextHierarchyParagraphPrimitive2D(const Primitive2DContainer& rChildren);
+            explicit TextHierarchyParagraphPrimitive2D(
+                const Primitive2DContainer& rChildren,
+                sal_Int16 nOutlineLevel = -1);
+
+            /// data read access
+            sal_Int16 getOutlineLevel() const { return mnOutlineLevel; }
+
+            /// compare operator
+            virtual bool operator==(const BasePrimitive2D& rPrimitive) const override;
 
             /// provide unique ID
             DeclPrimitive2DIDBlock()
diff --git a/sd/source/ui/unoidl/unomodel.cxx b/sd/source/ui/unoidl/unomodel.cxx
index 23319a1734c2..678c9d474616 100644
--- a/sd/source/ui/unoidl/unomodel.cxx
+++ b/sd/source/ui/unoidl/unomodel.cxx
@@ -1806,7 +1806,17 @@ drawinglayer::primitive2d::Primitive2DContainer ImplRenderPaintProc::createRedir
                     {
                         // embed Primitive2DSequence in a structure tag element for
                         // exactly this purpose (StructureTagPrimitive2D)
-                        const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::StructureTagPrimitive2D(eElement, xRetval));
+
+                        //Z
+                        const SdrPage* pSdrPage(pObject->getSdrPageFromSdrObject());
+                        const bool bBackground(nullptr != pSdrPage && pSdrPage->IsMasterPage());
+
+                        const drawinglayer::primitive2d::Primitive2DReference xReference(
+                            new drawinglayer::primitive2d::StructureTagPrimitive2D(
+                                eElement,
+                                bBackground,
+                                xRetval));
+
                         xRetval = drawinglayer::primitive2d::Primitive2DContainer { xReference };
                     }
                 }
diff --git a/svx/source/svdraw/svdotextdecomposition.cxx b/svx/source/svdraw/svdotextdecomposition.cxx
index e5e0ee273e11..fb02ac86b79a 100644
--- a/svx/source/svdraw/svdotextdecomposition.cxx
+++ b/svx/source/svdraw/svdotextdecomposition.cxx
@@ -93,7 +93,7 @@ namespace
         void impCreateTextPortionPrimitive(const DrawPortionInfo& rInfo);
         static drawinglayer::primitive2d::BasePrimitive2D* impCheckFieldPrimitive(drawinglayer::primitive2d::BasePrimitive2D* pPrimitive, const DrawPortionInfo& rInfo);
         void impFlushTextPortionPrimitivesToLinePrimitives();
-        void impFlushLinePrimitivesToParagraphPrimitives();
+        void impFlushLinePrimitivesToParagraphPrimitives(sal_Int32 nPara);
         void impHandleDrawPortionInfo(const DrawPortionInfo& rInfo);
         void impHandleDrawBulletInfo(const DrawBulletInfo& rInfo);
 
@@ -482,12 +482,21 @@ namespace
         }
     }
 
-    void impTextBreakupHandler::impFlushLinePrimitivesToParagraphPrimitives()
+    void impTextBreakupHandler::impFlushLinePrimitivesToParagraphPrimitives(sal_Int32 nPara)
     {
         // ALWAYS create a paragraph primitive, even when no content was added. This is done to
         // have the correct paragraph count even with empty paragraphs. Those paragraphs will
         // have an empty sub-PrimitiveSequence.
-        maParagraphPrimitives.push_back(new drawinglayer::primitive2d::TextHierarchyParagraphPrimitive2D(maLinePrimitives));
+        const sal_Int16 nOutlineLevel(nPara >= 0 && nPara < mrOutliner.GetParagraphCount()
+            ? mrOutliner.GetParaAttribs(nPara).Get(EE_PARA_OUTLLEVEL).GetValue()
+            : -1);
+
+        //Z This basically makes OutlineLevel information available in VclMetafileProcessor2D,
+        //Z so may be used similar to 'SetAlternateText' in processGraphicPrimitive2D for PDF export
+        maParagraphPrimitives.push_back(
+            new drawinglayer::primitive2d::TextHierarchyParagraphPrimitive2D(
+                maLinePrimitives,
+                nOutlineLevel));
         maLinePrimitives.clear();
     }
 
@@ -502,7 +511,7 @@ namespace
 
         if(rInfo.mbEndOfParagraph)
         {
-            impFlushLinePrimitivesToParagraphPrimitives();
+            impFlushLinePrimitivesToParagraphPrimitives(rInfo.mnPara);
         }
     }
 
@@ -637,7 +646,7 @@ namespace
         if(!maLinePrimitives.empty())
         {
             // collect non-closed paragraphs
-            impFlushLinePrimitivesToParagraphPrimitives();
+            impFlushLinePrimitivesToParagraphPrimitives(mrOutliner.GetParagraphCount() - 1);
         }
 
         return maParagraphPrimitives;
diff --git a/sw/source/core/doc/notxtfrm.cxx b/sw/source/core/doc/notxtfrm.cxx
index c64c0388b2c1..1bb573450639 100644
--- a/sw/source/core/doc/notxtfrm.cxx
+++ b/sw/source/core/doc/notxtfrm.cxx
@@ -80,6 +80,7 @@
 #include <vcl/pdfextoutdevdata.hxx>
 #include <drawinglayer/primitive2d/maskprimitive2d.hxx>
 #include <basegfx/polygon/b2dpolygontools.hxx>
+#include <drawinglayer/primitive2d/objectinfoprimitive2d.hxx>
 
 using namespace com::sun::star;
 
@@ -928,7 +929,10 @@ void paintGraphicUsingPrimitivesHelper(
     vcl::RenderContext & rOutputDevice,
     GraphicObject const& rGrfObj,
     GraphicAttr const& rGraphicAttr,
-    const basegfx::B2DHomMatrix& rGraphicTransform)
+    const basegfx::B2DHomMatrix& rGraphicTransform,
+    const OUString& rName,
+    const OUString& rTitle,
+    const OUString& rDescription)
 {
     // RotGrfFlyFrame: unify using GraphicPrimitive2D
     // -> the primitive handles all crop and mirror stuff
@@ -988,6 +992,17 @@ void paintGraphicUsingPrimitivesHelper(
         }
     }
 
+    if(!rName.isEmpty() || !rTitle.isEmpty() || !rDescription.isEmpty())
+    {
+        // Embed to ObjectInfoPrimitive2D when we have Name/Title/Description
+        // information available
+        aContent[0] = new drawinglayer::primitive2d::ObjectInfoPrimitive2D(
+            aContent,
+            rName,
+            rTitle,
+            rDescription);
+    }
+
     basegfx::B2DRange aTargetRange(0.0, 0.0, 1.0, 1.0);
     aTargetRange.transform(rGraphicTransform);
 
@@ -1129,7 +1144,10 @@ void SwNoTextFrame::PaintPicture( vcl::RenderContext* pOut, const SwRect &rGrfAr
                         *pOut,
                         rGrfObj,
                         aGrfAttr,
-                        aGraphicTransform);
+                        aGraphicTransform,
+                        nullptr == pGrfNd->GetFlyFormat() ? OUString() : pGrfNd->GetFlyFormat()->GetName(),
+                        rNoTNd.GetTitle(),
+                        rNoTNd.GetDescription());
                 }
             }
             else
@@ -1217,7 +1235,10 @@ void SwNoTextFrame::PaintPicture( vcl::RenderContext* pOut, const SwRect &rGrfAr
                     *pOut,
                     aTempGraphicObject,
                     aGrfAttr,
-                    aGraphicTransform);
+                    aGraphicTransform,
+                    nullptr == pGrfNd->GetFlyFormat() ? OUString() : pGrfNd->GetFlyFormat()->GetName(),
+                    rNoTNd.GetTitle(),
+                    rNoTNd.GetDescription());
 
                 // shade the representation if the object is activated outplace
                 uno::Reference < embed::XEmbeddedObject > xObj = pOLENd->GetOLEObj().GetOleRef();
diff --git a/sw/source/core/inc/frmtool.hxx b/sw/source/core/inc/frmtool.hxx
index bb006d56520e..507dca39313d 100644
--- a/sw/source/core/inc/frmtool.hxx
+++ b/sw/source/core/inc/frmtool.hxx
@@ -92,7 +92,10 @@ void paintGraphicUsingPrimitivesHelper(
     OutputDevice & rOutputDevice,
     GraphicObject const& rGraphicObj,
     GraphicAttr const& rGraphicAttr,
-    const basegfx::B2DHomMatrix& rGraphicTransform);
+    const basegfx::B2DHomMatrix& rGraphicTransform,
+    const OUString& rName,
+    const OUString& rTitle,
+    const OUString& rDescription);
 
 // method to align rectangle.
 // Created declaration here to avoid <extern> declarations
diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx
index dafc00ec4d34..213ce01e7797 100644
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -1675,7 +1675,10 @@ static void lcl_DrawGraphic( const SvxBrushItem& rBrush, vcl::RenderContext *pOu
         *pOut,
         *pGrf,
         pGrf->GetAttr(),
-        aGraphicTransform);
+        aGraphicTransform,
+        OUString(),
+        OUString(),
+        OUString());
 
     if ( bNotInside )
         pOut->Pop();
diff --git a/sw/source/core/text/EnhancedPDFExportHelper.cxx b/sw/source/core/text/EnhancedPDFExportHelper.cxx
index 69395167a38f..290c69867b47 100644
--- a/sw/source/core/text/EnhancedPDFExportHelper.cxx
+++ b/sw/source/core/text/EnhancedPDFExportHelper.cxx
@@ -486,7 +486,6 @@ void SwTaggedPDFHelper::SetAttributes( vcl::PDFWriter::StructElement eType )
         bool bEndIndent = false;
         bool bTextIndent = false;
         bool bTextAlign = false;
-        bool bAlternateText = false;
         bool bWidth = false;
         bool bHeight = false;
         bool bBox = false;
@@ -550,7 +549,6 @@ void SwTaggedPDFHelper::SetAttributes( vcl::PDFWriter::StructElement eType )
             case vcl::PDFWriter::Formula :
             case vcl::PDFWriter::Figure :
                 bPlacement =
-                bAlternateText =
                 bWidth =
                 bHeight =
                 bBox = true;
@@ -640,19 +638,9 @@ void SwTaggedPDFHelper::SetAttributes( vcl::PDFWriter::StructElement eType )
             }
         }
 
-        if ( bAlternateText )
-        {
-            OSL_ENSURE( pFrame->IsFlyFrame(), "Frame type <-> tag attribute mismatch" );
-            const SwFlyFrame* pFly = static_cast<const SwFlyFrame*>(pFrame);
-            if ( pFly->Lower() && pFly->Lower()->IsNoTextFrame() )
-            {
-                const SwNoTextFrame* pNoTextFrame   = static_cast<const SwNoTextFrame*>(pFly->Lower());
-                const SwNoTextNode* pNoTextNode = static_cast<const SwNoTextNode*>(pNoTextFrame->GetNode());
-
-                const OUString aAlternateText( pNoTextNode->GetTitle() );
-                mpPDFExtOutDevData->SetAlternateText( aAlternateText );
-            }
-        }
+        // Formally here bAlternateText was triggered for PDF export, but this
+        // was moved for more general use to primitives and usage in
+        // VclMetafileProcessor2D (see processGraphicPrimitive2D).
 
         if ( bWidth )
         {


More information about the Libreoffice-commits mailing list