[Libreoffice-commits] core.git: Branch 'feature/cib_contract139' - 71 commits - basic/source bin/lo-xlate-lang configure.ac connectivity/source cui/source dbaccess/source desktop/source dictionaries download.lst drawinglayer/source embeddedobj/source extensions/inc extensions/uiconfig external/hsqldb external/lcms2 external/libxml2 external/poppler external/python3 filter/source fpicker/Library_fps.mk fpicker/source icon-themes/breeze icon-themes/breeze_dark icon-themes/breeze_svg icon-themes/colibre icon-themes/colibre_svg icon-themes/elementary icon-themes/elementary_svg icon-themes/karasa_jaga icon-themes/tango include/drawinglayer include/svl include/svtools include/ucbhelper include/vcl officecfg/registry oox/source readlicense_oo/license sc/source sdext/source sd/source sfx2/source solenv/flatpak-manifest.in svl/source svtools/source svx/source sw/inc sw/qa sw/source toolkit/source translations ucbhelper/source ucb/source vcl/inc vcl/Library_vcl.mk vcl/osx vcl/source vcl/unx vcl/win writerf ilter/source xmloff/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Mon Jan 21 13:59:45 UTC 2019


Rebased ref, commits from common ancestor:
commit 2f5c61ce217c5db20059b16f681d65580a7577c7
Author:     Katarina Behrens <Katarina.Behrens at cib.de>
AuthorDate: Tue Jan 15 14:11:49 2019 +0100
Commit:     Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Mon Jan 21 14:58:25 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

diff --git a/svx/source/svdraw/svdotextdecomposition.cxx b/svx/source/svdraw/svdotextdecomposition.cxx
index 05490ba7960d..ff83f15c4274 100644
--- a/svx/source/svdraw/svdotextdecomposition.cxx
+++ b/svx/source/svdraw/svdotextdecomposition.cxx
@@ -500,15 +500,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 ca9a911f8cb4feaab04253635dede0dc9f69d6eb
Author:     Thorsten Behrens <Thorsten.Behrens at CIB.de>
AuthorDate: Fri Dec 21 00:57:37 2018 +0100
Commit:     Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Mon Jan 21 14:53:29 2019 +0100

    fix crash
    
    Change-Id: Ia0332b62daad878dd3af939a15a9947562b8ed0d

diff --git a/sw/source/core/doc/notxtfrm.cxx b/sw/source/core/doc/notxtfrm.cxx
index 24e4b03f39f0..64fee22b4020 100644
--- a/sw/source/core/doc/notxtfrm.cxx
+++ b/sw/source/core/doc/notxtfrm.cxx
@@ -1245,7 +1245,7 @@ void SwNoTextFrame::PaintPicture( vcl::RenderContext* pOut, const SwRect &rGrfAr
                     aTempGraphicObject,
                     aGrfAttr,
                     aGraphicTransform,
-                    nullptr == pGrfNd->GetFlyFormat() ? OUString() : pGrfNd->GetFlyFormat()->GetName(),
+                    OUString(),
                     rNoTNd.GetTitle(),
                     rNoTNd.GetDescription());
 
commit 70e0cbe6ab2803e3c9c3f8dd2dc800fbad06bd9d
Author:     Noel Grandin <noel.grandin at collabora.co.uk>
AuthorDate: Thu Jul 26 14:36:38 2018 +0200
Commit:     Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Mon Jan 21 14:53:28 2019 +0100

    loplugin:returnconstant in svl,svtools
    
    Change-Id: Id297a513f3313e10531f0ccd99a16277e4e37fa1
    Reviewed-on: https://gerrit.libreoffice.org/58111
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.grandin at collabora.co.uk>
    (cherry picked from commit 928dfebe109794eb079469a46f549e25b3b1e89d)

diff --git a/include/svl/filenotation.hxx b/include/svl/filenotation.hxx
index e5cf1c78a320..d33e442b9396 100644
--- a/include/svl/filenotation.hxx
+++ b/include/svl/filenotation.hxx
@@ -47,7 +47,7 @@ namespace svt
     private:
         SVL_DLLPRIVATE void construct( const OUString& _rUrlOrPath );
         SVL_DLLPRIVATE bool    implInitWithSystemNotation( const OUString& _rSystemPath );
-        SVL_DLLPRIVATE bool    implInitWithURLNotation( const OUString& _rURL );
+        SVL_DLLPRIVATE void    implInitWithURLNotation( const OUString& _rURL );
 
         OUString     m_sSystem;
         OUString     m_sFileURL;
diff --git a/include/svtools/colorcfg.hxx b/include/svtools/colorcfg.hxx
index 450eed0e82c0..381ef70570c4 100644
--- a/include/svtools/colorcfg.hxx
+++ b/include/svtools/colorcfg.hxx
@@ -121,7 +121,7 @@ public:
     css::uno::Sequence< OUString >  GetSchemeNames() const;
     void                        DeleteScheme(const OUString& rScheme );
     void                        AddScheme(const OUString& rScheme );
-    bool                        LoadScheme(const OUString& rScheme );
+    void                        LoadScheme(const OUString& rScheme );
     const OUString&             GetCurrentSchemeName() const;
     void                        SetCurrentSchemeName(const OUString& rScheme);
 
diff --git a/include/svtools/extcolorcfg.hxx b/include/svtools/extcolorcfg.hxx
index 17e885661371..752784c92390 100644
--- a/include/svtools/extcolorcfg.hxx
+++ b/include/svtools/extcolorcfg.hxx
@@ -87,7 +87,7 @@ public:
 
     void                        DeleteScheme(const OUString& rScheme );
     void                        AddScheme(const OUString& rScheme );
-    bool                        LoadScheme(const OUString& rScheme );
+    void                        LoadScheme(const OUString& rScheme );
     void                        SetCurrentSchemeName(const OUString& rScheme);
 
     sal_Int32                   GetComponentCount() const;
diff --git a/include/svtools/imap.hxx b/include/svtools/imap.hxx
index 232248d20039..af094cbab817 100644
--- a/include/svtools/imap.hxx
+++ b/include/svtools/imap.hxx
@@ -46,8 +46,8 @@ private:
     // Import/Export
     void                ImpWriteCERN( SvStream& rOStm ) const;
     void                ImpWriteNCSA( SvStream& rOStm ) const;
-    sal_uLong           ImpReadCERN( SvStream& rOStm );
-    sal_uLong           ImpReadNCSA( SvStream& rOStm );
+    void                ImpReadCERN( SvStream& rOStm );
+    void                ImpReadNCSA( SvStream& rOStm );
 
     void                ImpReadCERNLine( const OString& rLine );
     static Point        ImpReadCERNCoords( const char** ppStr );
diff --git a/include/svtools/svlbitm.hxx b/include/svtools/svlbitm.hxx
index a6ca61dceef0..3b603f47bbcf 100644
--- a/include/svtools/svlbitm.hxx
+++ b/include/svtools/svlbitm.hxx
@@ -154,7 +154,7 @@ public:
                               SvViewDataItem* pViewData = nullptr) override;
 
     virtual SvLBoxItemType GetType() const override;
-    bool ClickHdl( SvTreeListEntry* );
+    void ClickHdl( SvTreeListEntry* );
 
     virtual void Paint(const Point& rPos,
                        SvTreeListBox& rOutDev,
diff --git a/svl/source/fsstor/fsstorage.cxx b/svl/source/fsstor/fsstorage.cxx
index c1350f86270a..049e70db5689 100644
--- a/svl/source/fsstor/fsstorage.cxx
+++ b/svl/source/fsstor/fsstorage.cxx
@@ -702,11 +702,10 @@ void SAL_CALL FSStorage::renameElement( const OUString& aElementName, const OUSt
         uno::Reference< ucb::XCommandEnvironment > xDummyEnv;
         ::ucbhelper::Content aSourceContent( aOldURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), xDummyEnv, comphelper::getProcessComponentContext() );
 
-        if ( !GetContent()->transferContent( aSourceContent,
+        GetContent()->transferContent( aSourceContent,
                                             ::ucbhelper::InsertOperation::Move,
                                             aNewName,
-                                            ucb::NameClash::ERROR ) )
-            throw io::IOException(); // TODO: error handling
+                                            ucb::NameClash::ERROR );
     }
     catch( embed::InvalidStorageException& )
     {
diff --git a/svl/source/misc/filenotation.cxx b/svl/source/misc/filenotation.cxx
index bc3f5ccf946c..c4337708bc8b 100644
--- a/svl/source/misc/filenotation.cxx
+++ b/svl/source/misc/filenotation.cxx
@@ -70,11 +70,10 @@ namespace svt
         return bSuccess;
     }
 
-    bool OFileNotation::implInitWithURLNotation( const OUString& _rURL )
+    void OFileNotation::implInitWithURLNotation( const OUString& _rURL )
     {
         m_sFileURL = _rURL;
         osl_getSystemPathFromFileURL( _rURL.pData, &m_sSystem.pData );
-        return true;
     }
 
     void OFileNotation::construct( const OUString& _rUrlOrPath )
@@ -86,7 +85,8 @@ namespace svt
         {
             case INetProtocol::File:
                 // file URL
-                bSuccess = implInitWithURLNotation( _rUrlOrPath );
+                implInitWithURLNotation( _rUrlOrPath );
+                bSuccess = true;
                 break;
 
             case INetProtocol::NotValid:
diff --git a/svtools/source/config/colorcfg.cxx b/svtools/source/config/colorcfg.cxx
index 580c28034f47..378f046a3714 100644
--- a/svtools/source/config/colorcfg.cxx
+++ b/svtools/source/config/colorcfg.cxx
@@ -540,7 +540,7 @@ void EditableColorConfig::AddScheme(const OUString& rScheme )
     m_pImpl->AddScheme(rScheme);
 }
 
-bool EditableColorConfig::LoadScheme(const OUString& rScheme )
+void EditableColorConfig::LoadScheme(const OUString& rScheme )
 {
     if(m_bModified)
         m_pImpl->SetModified();
@@ -550,7 +550,6 @@ bool EditableColorConfig::LoadScheme(const OUString& rScheme )
     m_pImpl->Load(rScheme);
     //the name of the loaded scheme has to be committed separately
     m_pImpl->CommitCurrentSchemeName();
-    return true;
 }
 
 const OUString& EditableColorConfig::GetCurrentSchemeName()const
diff --git a/svtools/source/config/extcolorcfg.cxx b/svtools/source/config/extcolorcfg.cxx
index 76c4c6ac5343..8e09110ca02f 100644
--- a/svtools/source/config/extcolorcfg.cxx
+++ b/svtools/source/config/extcolorcfg.cxx
@@ -596,7 +596,7 @@ void EditableExtendedColorConfig::AddScheme(const OUString& rScheme )
     m_pImpl->AddScheme(rScheme);
 }
 
-bool EditableExtendedColorConfig::LoadScheme(const OUString& rScheme )
+void EditableExtendedColorConfig::LoadScheme(const OUString& rScheme )
 {
     if(m_bModified)
         m_pImpl->SetModified();
@@ -606,7 +606,6 @@ bool EditableExtendedColorConfig::LoadScheme(const OUString& rScheme )
     m_pImpl->Load(rScheme);
     //the name of the loaded scheme has to be committed separately
     m_pImpl->CommitCurrentSchemeName();
-    return true;
 }
 
 // Changes the name of the current scheme but doesn't load it!
diff --git a/svtools/source/contnr/svlbitm.cxx b/svtools/source/contnr/svlbitm.cxx
index f12c2911673f..11eeb0165f5e 100644
--- a/svtools/source/contnr/svlbitm.cxx
+++ b/svtools/source/contnr/svlbitm.cxx
@@ -248,7 +248,7 @@ SvLBoxItemType SvLBoxButton::GetType() const
     return SvLBoxItemType::Button;
 }
 
-bool SvLBoxButton::ClickHdl( SvTreeListEntry* pEntry )
+void SvLBoxButton::ClickHdl( SvTreeListEntry* pEntry )
 {
     if ( CheckModification() )
     {
@@ -259,7 +259,6 @@ bool SvLBoxButton::ClickHdl( SvTreeListEntry* pEntry )
         pData->StoreButtonState( pEntry );
         pData->CallLink();
     }
-    return false;
 }
 
 void SvLBoxButton::Paint(
diff --git a/svtools/source/misc/imap2.cxx b/svtools/source/misc/imap2.cxx
index e1424f5d47b4..99fc73b4bf70 100644
--- a/svtools/source/misc/imap2.cxx
+++ b/svtools/source/misc/imap2.cxx
@@ -219,8 +219,8 @@ sal_uLong ImageMap::Read( SvStream& rIStm, sal_uLong nFormat  )
     switch ( nFormat )
     {
         case IMAP_FORMAT_BIN    : Read( rIStm ); break;
-        case IMAP_FORMAT_CERN   : nRet = ImpReadCERN( rIStm ); break;
-        case IMAP_FORMAT_NCSA   : nRet = ImpReadNCSA( rIStm ); break;
+        case IMAP_FORMAT_CERN   : ImpReadCERN( rIStm ); break;
+        case IMAP_FORMAT_NCSA   : ImpReadNCSA( rIStm ); break;
 
         default:
         break;
@@ -232,7 +232,7 @@ sal_uLong ImageMap::Read( SvStream& rIStm, sal_uLong nFormat  )
     return nRet;
 }
 
-sal_uLong ImageMap::ImpReadCERN( SvStream& rIStm )
+void ImageMap::ImpReadCERN( SvStream& rIStm )
 {
     // delete old content
     ClearImageMap();
@@ -240,8 +240,6 @@ sal_uLong ImageMap::ImpReadCERN( SvStream& rIStm )
     OString aStr;
     while ( rIStm.ReadLine( aStr ) )
         ImpReadCERNLine( aStr );
-
-    return IMAP_ERR_OK;
 }
 
 void ImageMap::ImpReadCERNLine( const OString& rLine  )
@@ -370,7 +368,7 @@ OUString ImageMap::ImpReadCERNURL( const char** ppStr )
     return INetURLObject::GetAbsURL( "", aStr );
 }
 
-sal_uLong ImageMap::ImpReadNCSA( SvStream& rIStm )
+void ImageMap::ImpReadNCSA( SvStream& rIStm )
 {
     // delete old content
     ClearImageMap();
@@ -378,8 +376,6 @@ sal_uLong ImageMap::ImpReadNCSA( SvStream& rIStm )
     OString aStr;
     while ( rIStm.ReadLine( aStr ) )
         ImpReadNCSALine( aStr );
-
-    return IMAP_ERR_OK;
 }
 
 void ImageMap::ImpReadNCSALine( const OString& rLine )
diff --git a/svtools/source/uno/unoimap.cxx b/svtools/source/uno/unoimap.cxx
index 65757ccbda15..4c337df681d3 100644
--- a/svtools/source/uno/unoimap.cxx
+++ b/svtools/source/uno/unoimap.cxx
@@ -508,7 +508,7 @@ public:
     explicit SvUnoImageMap();
     SvUnoImageMap( const ImageMap& rMap, const SvEventDescription* pSupportedMacroItems );
 
-    bool fillImageMap( ImageMap& rMap ) const;
+    void fillImageMap( ImageMap& rMap ) const;
     /// @throws IllegalArgumentException
     static SvUnoImageMapObject* getObject( const Any& aElement );
 
@@ -667,7 +667,7 @@ Sequence< OUString > SAL_CALL SvUnoImageMap::getSupportedServiceNames(  )
     return Sequence< OUString >( &aSN, 1 );
 }
 
-bool SvUnoImageMap::fillImageMap( ImageMap& rMap ) const
+void SvUnoImageMap::fillImageMap( ImageMap& rMap ) const
 {
     rMap.ClearImageMap();
 
@@ -679,8 +679,6 @@ bool SvUnoImageMap::fillImageMap( ImageMap& rMap ) const
         rMap.InsertIMapObject( *pNewMapObject );
         delete pNewMapObject;
     }
-
-    return true;
 }
 
 
@@ -718,7 +716,8 @@ bool SvUnoImageMap_fillImageMap( const Reference< XInterface >& xImageMap, Image
     if( nullptr == pUnoImageMap )
         return false;
 
-    return pUnoImageMap->fillImageMap( rMap );
+    pUnoImageMap->fillImageMap( rMap );
+    return true;
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 487e0632487379a5bcc30ec0227ffa56d5f2d6dd
Author:     Fridrich Štrba <fridrich.strba at bluewin.ch>
AuthorDate: Thu Jul 12 11:57:07 2018 +0200
Commit:     Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Mon Jan 21 14:53:28 2019 +0100

    call System.runFinalizersOnExit by reflection, since it was removed in jdk11
    
    Change-Id: I542c87bc1de21727a035cc6ac3b3e20c0ccfb5f7
    (cherry picked from commit 983035cc974faf9a2dcc1ecdf01391e618970a7f)

diff --git a/external/hsqldb/UnpackedTarball_hsqldb.mk b/external/hsqldb/UnpackedTarball_hsqldb.mk
index fc6c18f77c23..cbba770f19a0 100644
--- a/external/hsqldb/UnpackedTarball_hsqldb.mk
+++ b/external/hsqldb/UnpackedTarball_hsqldb.mk
@@ -24,6 +24,7 @@ $(eval $(call gb_UnpackedTarball_add_patches,hsqldb,\
 	external/hsqldb/patches/i104901.patch \
 	external/hsqldb/patches/fdo36824.patch \
 	external/hsqldb/patches/limit_as_table_alias.patch \
+	external/hsqldb/patches/hsqldb-runFinalizersOnExit.patch \
 	$(if $(HSQLDB_USE_JDBC_4_1),\
 		external/hsqldb/patches/jdbc-4.1.patch \
 		external/hsqldb/patches/multipleResultSets.patch \
diff --git a/external/hsqldb/patches/hsqldb-runFinalizersOnExit.patch b/external/hsqldb/patches/hsqldb-runFinalizersOnExit.patch
new file mode 100644
index 000000000000..214dc2c2b2e1
--- /dev/null
+++ b/external/hsqldb/patches/hsqldb-runFinalizersOnExit.patch
@@ -0,0 +1,14 @@
+--- misc/hsqldb/src/org/hsqldb/lib/java/JavaSystem.java	2008-03-16 23:51:35.000000000 +0100
++++ misc/build/hsqldb/src/org/hsqldb/lib/java/JavaSystem.java	2018-07-12 11:46:57.997837180 +0200
+@@ -160,8 +160,9 @@
+     public static void runFinalizers() {
+ 
+ //#ifdef JAVA2FULL
+-        System.runFinalizersOnExit(true);
+-
++        try {
++            System.class.getMethod("runFinalizersOnExit", boolean.class).invoke(null, true);
++        } catch (Exception e) {}
+ //#endif
+     }
+ 
commit b1245b227021c3dee75a4c420c5db320ea6e1afb
Author:     Armin Le Grand <Armin.Le.Grand at cib.de>
AuthorDate: Thu Dec 20 17:31:32 2018 +0100
Commit:     Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Mon Jan 21 14:53:27 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.
    
    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 d862fabf9fce..bbc7d80361a7 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.
@@ -561,7 +564,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
@@ -900,6 +904,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
@@ -993,10 +1002,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 += OUString(" - ");
+                        }
+
+                        aAlternateDescription += getObjectInfoPrimitive2D()->getTitle();
+                    }
+
+                    if(!getObjectInfoPrimitive2D()->getDesc().isEmpty())
+                    {
+                        if(!aAlternateDescription.isEmpty())
+                        {
+                            aAlternateDescription += OUString(" - ");
+                        }
+
+                        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);
@@ -1195,22 +1242,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)
@@ -2163,12 +2273,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 65007b487727..a897d17ddfff 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 df0b95b7cdec..caa481182032 100644
--- a/drawinglayer/source/processor2d/vclprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclprocessor2d.cxx
@@ -61,6 +61,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
@@ -1200,6 +1203,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());
@@ -1426,7 +1442,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 416e936c20bc..b8cd7d7b4691 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 750a5b827364..05490ba7960d 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);
 
@@ -498,12 +498,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();
     }
 
@@ -518,7 +527,7 @@ namespace
 
         if(rInfo.mbEndOfParagraph)
         {
-            impFlushLinePrimitivesToParagraphPrimitives();
+            impFlushLinePrimitivesToParagraphPrimitives(rInfo.mnPara);
         }
     }
 
@@ -653,7 +662,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 6dd910fab9ee..24e4b03f39f0 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;
 
@@ -932,7 +933,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
@@ -996,6 +1000,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);
 
@@ -1138,7 +1153,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
@@ -1226,7 +1244,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 0ffe4a75c0f6..5ecdc3bfc5d0 100644
--- a/sw/source/core/inc/frmtool.hxx
+++ b/sw/source/core/inc/frmtool.hxx
@@ -77,7 +77,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 b684232ba78d..ee707b0e41dd 100644
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -1676,7 +1676,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 d171a5fbef80..2f40cd796fc6 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 )
         {
commit 93b1c342e09b3173370998a67335d9f54f995827
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Tue Jul 31 15:33:43 2018 +0100
Commit:     Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Mon Jan 21 14:53:26 2019 +0100

    crashtesting: stack exhaustion exporting moz1253590-2.svg to odg
    
    happens on the crashtesting box, but not locally, comparing the stack frames its clear
    that the stack used on the crashtester for VclPixelProcessor2D::processBasePrimitive2D is
    over double that used locally...
    
    comparison on
    > objdump -S workdir/CxxObject/drawinglayer/source/processor2d/vclmetafileprocessor2d.o |less
    gives...
    void VclMetafileProcessor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate)
    gcc-4.8.2-3.2.mga4 has...       sub    $0x5b0,%rsp
    vs...
    gcc-8.1.1-5.fc28.x86_64 has...  sub    $0x2e0,%rsp
    
    lets split up this method
    
    Change-Id: I6d84f555a01b5c58f530adb9b9b8cb8803c985bf
    Reviewed-on: https://gerrit.libreoffice.org/58364
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>
    (cherry picked from commit aa2e694e8d9e22de94dbf21f81883f9af0e34ce9)

diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
index aae85f6d0e06..bc234adc8337 100644
--- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
@@ -285,113 +285,28 @@ namespace drawinglayer
             {
                 case PRIMITIVE2D_ID_WRONGSPELLPRIMITIVE2D :
                 {
-                    // directdraw of wrong spell primitive; added test possibility to check wrong spell decompose
-                    static bool bHandleWrongSpellDirectly(true);
-
-                    if(bHandleWrongSpellDirectly)
-                    {
-                        const primitive2d::WrongSpellPrimitive2D& rWrongSpellPrimitive = static_cast< const primitive2d::WrongSpellPrimitive2D& >(rCandidate);
-
-                        if(!renderWrongSpellPrimitive2D(
-                            rWrongSpellPrimitive,
-                            *mpOutputDevice,
-                            maCurrentTransformation,
-                            maBColorModifierStack))
-                        {
-                            // fallback to decomposition (MetaFile)
-                            process(rWrongSpellPrimitive);
-                        }
-                    }
-                    else
-                    {
-                        process(rCandidate);
-                    }
+                    processWrongSpellPrimitive2D(static_cast<const primitive2d::WrongSpellPrimitive2D&>(rCandidate));
                     break;
                 }
                 case PRIMITIVE2D_ID_TEXTSIMPLEPORTIONPRIMITIVE2D :
                 {
-                    // directdraw of text simple portion; added test possibility to check text decompose
-                    static bool bForceSimpleTextDecomposition(false);
-
-                    // Adapt evtl. used special DrawMode
-                    const DrawModeFlags nOriginalDrawMode(mpOutputDevice->GetDrawMode());
-                    adaptTextToFillDrawMode();
-
-                    if(!bForceSimpleTextDecomposition && getOptionsDrawinglayer().IsRenderSimpleTextDirect())
-                    {
-                        RenderTextSimpleOrDecoratedPortionPrimitive2D(static_cast< const primitive2d::TextSimplePortionPrimitive2D& >(rCandidate));
-                    }
-                    else
-                    {
-                        process(rCandidate);
-                    }
-
-                    // restore DrawMode
-                    mpOutputDevice->SetDrawMode(nOriginalDrawMode);
-
+                    processTextSimplePortionPrimitive2D(static_cast<const primitive2d::TextSimplePortionPrimitive2D&>(rCandidate));
                     break;
                 }
                 case PRIMITIVE2D_ID_TEXTDECORATEDPORTIONPRIMITIVE2D :
                 {
-                    // directdraw of decorated text portion; added test possibility to check text decompose
-                    static bool bForceComplexTextDecomposition(false);
-
-                    // Adapt evtl. used special DrawMode
-                    const DrawModeFlags nOriginalDrawMode(mpOutputDevice->GetDrawMode());
-                    adaptTextToFillDrawMode();
-
-                    if(!bForceComplexTextDecomposition && getOptionsDrawinglayer().IsRenderDecoratedTextDirect())
-                    {
-                        RenderTextSimpleOrDecoratedPortionPrimitive2D(static_cast< const primitive2d::TextSimplePortionPrimitive2D& >(rCandidate));
-                    }
-                    else
-                    {
-                        process(rCandidate);
-                    }
-
-                    // restore DrawMode
-                    mpOutputDevice->SetDrawMode(nOriginalDrawMode);
-
+                    processTextDecoratedPortionPrimitive2D(static_cast<const primitive2d::TextSimplePortionPrimitive2D&>(rCandidate));
                     break;
                 }
                 case PRIMITIVE2D_ID_POLYGONHAIRLINEPRIMITIVE2D :
                 {
-                    // try to use directly
-                    const primitive2d::PolygonHairlinePrimitive2D& rPolygonHairlinePrimitive2D = static_cast< const primitive2d::PolygonHairlinePrimitive2D& >(rCandidate);
-                    static bool bAllowed(true);
-
-                    if(bAllowed && tryDrawPolygonHairlinePrimitive2DDirect(rPolygonHairlinePrimitive2D, 0.0))
-                    {
-                        break;
-                    }
-
-                    // direct draw of hairline
-                    RenderPolygonHairlinePrimitive2D(rPolygonHairlinePrimitive2D, true);
+                    processPolygonHairlinePrimitive2D(static_cast<const primitive2d::PolygonHairlinePrimitive2D&>(rCandidate));
                     break;
                 }
                 case PRIMITIVE2D_ID_BITMAPPRIMITIVE2D :
                 {
                     // direct draw of transformed BitmapEx primitive
-                    const primitive2d::BitmapPrimitive2D& rBitmapCandidate = static_cast< const primitive2d::BitmapPrimitive2D& >(rCandidate);
-
-                    // check if graphic content is inside discrete local ViewPort
-                    const basegfx::B2DRange& rDiscreteViewPort(getViewInformation2D().getDiscreteViewport());
-                    const basegfx::B2DHomMatrix aLocalTransform(maCurrentTransformation * rBitmapCandidate.getTransform());
-
-                    if(!rDiscreteViewPort.isEmpty())
-                    {
-                        basegfx::B2DRange aUnitRange(0.0, 0.0, 1.0, 1.0);
-
-                        aUnitRange.transform(aLocalTransform);
-
-                        if(!aUnitRange.overlaps(rDiscreteViewPort))
-                        {
-                            // content is outside discrete local ViewPort
-                            break;
-                        }
-                    }
-
-                    RenderBitmapPrimitive2D(static_cast< const primitive2d::BitmapPrimitive2D& >(rCandidate));
+                    processBitmapPrimitive2D(static_cast<const primitive2d::BitmapPrimitive2D&>(rCandidate));
                     break;
                 }
                 case PRIMITIVE2D_ID_FILLGRAPHICPRIMITIVE2D :
@@ -402,30 +317,7 @@ namespace drawinglayer
                 }
                 case PRIMITIVE2D_ID_POLYPOLYGONGRADIENTPRIMITIVE2D :
                 {
-                    // direct draw of gradient
-                    const primitive2d::PolyPolygonGradientPrimitive2D& rPolygonCandidate = static_cast< const primitive2d::PolyPolygonGradientPrimitive2D& >(rCandidate);
-                    const attribute::FillGradientAttribute& rGradient(rPolygonCandidate.getFillGradient());
-                    basegfx::BColor aStartColor(maBColorModifierStack.getModifiedColor(rGradient.getStartColor()));
-                    basegfx::BColor aEndColor(maBColorModifierStack.getModifiedColor(rGradient.getEndColor()));
-                    basegfx::B2DPolyPolygon aLocalPolyPolygon(rPolygonCandidate.getB2DPolyPolygon());
-
-                    if(aLocalPolyPolygon.count())
-                    {
-                        aLocalPolyPolygon.transform(maCurrentTransformation);
-
-                        if(aStartColor == aEndColor)
-                        {
-                            // no gradient at all, draw as polygon in AA and non-AA case
-                            mpOutputDevice->SetLineColor();
-                            mpOutputDevice->SetFillColor(Color(aStartColor));
-                            mpOutputDevice->DrawPolyPolygon(aLocalPolyPolygon);
-                        }
-                        else
-                        {
-                            // use the primitive decomposition of the metafile
-                            process(rPolygonCandidate);
-                        }
-                    }
+                    processPolyPolygonGradientPrimitive2D(static_cast<const primitive2d::PolyPolygonGradientPrimitive2D&>(rCandidate));
                     break;
                 }
                 case PRIMITIVE2D_ID_POLYPOLYGONGRAPHICPRIMITIVE2D :
@@ -436,74 +328,12 @@ namespace drawinglayer
                 }
                 case PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D :
                 {
-                    // try to use directly
-                    const primitive2d::PolyPolygonColorPrimitive2D& rPolyPolygonColorPrimitive2D = static_cast< const primitive2d::PolyPolygonColorPrimitive2D& >(rCandidate);
-                    basegfx::B2DPolyPolygon aLocalPolyPolygon;
-                    static bool bAllowed(true);
-
-                    if(bAllowed)
-                    {
-                        tryDrawPolyPolygonColorPrimitive2DDirect(rPolyPolygonColorPrimitive2D, 0.0);
-                        // okay, done. In this case no gaps should have to be repaired, too
-                    }
-                    else
-                    {
-                        // direct draw of tools::PolyPolygon with color
-                        const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(rPolyPolygonColorPrimitive2D.getBColor()));
-
-                        mpOutputDevice->SetFillColor(Color(aPolygonColor));
-                        mpOutputDevice->SetLineColor();
-                        aLocalPolyPolygon = rPolyPolygonColorPrimitive2D.getB2DPolyPolygon();
-                        aLocalPolyPolygon.transform(maCurrentTransformation);
-                        mpOutputDevice->DrawPolyPolygon(aLocalPolyPolygon);
-                    }
-
-                    // when AA is on and this filled polygons are the result of stroked line geometry,
-                    // draw the geometry once extra as lines to avoid AA 'gaps' between partial polygons
-                    // Caution: This is needed in both cases (!)
-                    if(mnPolygonStrokePrimitive2D
-                        && getOptionsDrawinglayer().IsAntiAliasing()
-                        && (mpOutputDevice->GetAntialiasing() & AntialiasingFlags::EnableB2dDraw))
-                    {
-                        const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(rPolyPolygonColorPrimitive2D.getBColor()));
-                        sal_uInt32 nCount(aLocalPolyPolygon.count());
-
-                        if(!nCount)
-                        {
-                            aLocalPolyPolygon = rPolyPolygonColorPrimitive2D.getB2DPolyPolygon();
-                            aLocalPolyPolygon.transform(maCurrentTransformation);
-                            nCount = aLocalPolyPolygon.count();
-                        }
-
-                        mpOutputDevice->SetFillColor();
-                        mpOutputDevice->SetLineColor(Color(aPolygonColor));
-
-                        for(sal_uInt32 a(0); a < nCount; a++)
-                        {
-                            mpOutputDevice->DrawPolyLine(aLocalPolyPolygon.getB2DPolygon(a), 0.0);
-                        }
-                    }
-
+                    processPolyPolygonColorPrimitive2D(static_cast<const primitive2d::PolyPolygonColorPrimitive2D&>(rCandidate));
                     break;
                 }
                 case PRIMITIVE2D_ID_METAFILEPRIMITIVE2D :
                 {
-                    // #i98289#
-                    const bool bForceLineSnap(getOptionsDrawinglayer().IsAntiAliasing() && getOptionsDrawinglayer().IsSnapHorVerLinesToDiscrete());
-                    const AntialiasingFlags nOldAntiAliase(mpOutputDevice->GetAntialiasing());
-
-                    if(bForceLineSnap)
-                    {
-                        mpOutputDevice->SetAntialiasing(nOldAntiAliase | AntialiasingFlags::PixelSnapHairline);
-                    }
-
-                    process(rCandidate);
-
-                    if(bForceLineSnap)
-                    {
-                        mpOutputDevice->SetAntialiasing(nOldAntiAliase);
-                    }
-
+                    processMetaFilePrimitive2D(rCandidate);
                     break;
                 }
                 case PRIMITIVE2D_ID_MASKPRIMITIVE2D :
@@ -520,91 +350,7 @@ namespace drawinglayer
                 }
                 case PRIMITIVE2D_ID_UNIFIEDTRANSPARENCEPRIMITIVE2D :
                 {
-                    // Detect if a single PolyPolygonColorPrimitive2D is contained; in that case,
-                    // use the faster OutputDevice::DrawTransparent method
-                    const primitive2d::UnifiedTransparencePrimitive2D& rUniTransparenceCandidate = static_cast< const primitive2d::UnifiedTransparencePrimitive2D& >(rCandidate);
-                    const primitive2d::Primitive2DContainer& rContent = rUniTransparenceCandidate.getChildren();
-
-                    if(!rContent.empty())
-                    {
-                        if(0.0 == rUniTransparenceCandidate.getTransparence())
-                        {
-                            // not transparent at all, use content
-                            process(rUniTransparenceCandidate.getChildren());
-                        }
-                        else if(rUniTransparenceCandidate.getTransparence() > 0.0 && rUniTransparenceCandidate.getTransparence() < 1.0)
-                        {
-                            bool bDrawTransparentUsed(false);
-
-                            // since DEV300 m33 DrawTransparent is supported in VCL (for some targets
-                            // natively), so i am now enabling this shortcut
-                            static bool bAllowUsingDrawTransparent(true);
-
-                            if(bAllowUsingDrawTransparent && 1 == rContent.size())
-                            {
-                                const primitive2d::Primitive2DReference xReference(rContent[0]);
-                                const primitive2d::BasePrimitive2D* pBasePrimitive = dynamic_cast< const primitive2d::BasePrimitive2D* >(xReference.get());
-
-                                if(pBasePrimitive)
-                                {
-                                    switch(pBasePrimitive->getPrimitive2DID())
-                                    {
-                                        case PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D:
-                                        {
-                                            // single transparent tools::PolyPolygon identified, use directly
-                                            const primitive2d::PolyPolygonColorPrimitive2D* pPoPoColor = static_cast< const primitive2d::PolyPolygonColorPrimitive2D* >(pBasePrimitive);
-                                            OSL_ENSURE(pPoPoColor, "OOps, PrimitiveID and PrimitiveType do not match (!)");
-                                            bDrawTransparentUsed = true;
-                                            tryDrawPolyPolygonColorPrimitive2DDirect(*pPoPoColor, rUniTransparenceCandidate.getTransparence());
-                                            break;
-                                        }
-                                        case PRIMITIVE2D_ID_POLYGONHAIRLINEPRIMITIVE2D:
-                                        {
-                                            // single transparent PolygonHairlinePrimitive2D identified, use directly
-                                            const primitive2d::PolygonHairlinePrimitive2D* pPoHair = static_cast< const primitive2d::PolygonHairlinePrimitive2D* >(pBasePrimitive);
-                                            OSL_ENSURE(pPoHair, "OOps, PrimitiveID and PrimitiveType do not match (!)");
-
-                                            // do no tallow by default - problem is that self-overlapping parts of this geometry will
-                                            // not be in a all-same transparency but will already alpha-cover themselves with blending.
-                                            // This is not what the UnifiedTransparencePrimitive2D defines: It requires all its
-                                            // content to be uniformely transparent.
-                                            // For hairline the effect is pretty minimal, but still not correct.
-                                            static bool bAllowed(false);
-
-                                            bDrawTransparentUsed = bAllowed && tryDrawPolygonHairlinePrimitive2DDirect(*pPoHair, rUniTransparenceCandidate.getTransparence());
-                                            break;
-                                        }
-                                        case PRIMITIVE2D_ID_POLYGONSTROKEPRIMITIVE2D:
-                                        {
-                                            // single transparent PolygonStrokePrimitive2D identified, use directly
-                                            const primitive2d::PolygonStrokePrimitive2D* pPoStroke = static_cast< const primitive2d::PolygonStrokePrimitive2D* >(pBasePrimitive);
-                                            OSL_ENSURE(pPoStroke, "OOps, PrimitiveID and PrimitiveType do not match (!)");
-
-                                            // do no tallow by default - problem is that self-overlapping parts of this geometry will
-                                            // not be in a all-same transparency but will already alpha-cover themselves with blending.
-                                            // This is not what the UnifiedTransparencePrimitive2D defines: It requires all its
-                                            // content to be uniformely transparent.
-                                            // To check, activate and draw a wide transparent self-crossing line/curve
-                                            static bool bAllowed(false);
-
-                                            bDrawTransparentUsed = bAllowed && tryDrawPolygonStrokePrimitive2DDirect(*pPoStroke, rUniTransparenceCandidate.getTransparence());
-                                            break;
-                                        }
-                                    default:
-                                        SAL_INFO("drawinglayer", "default case for " << drawinglayer::primitive2d::idToString(rCandidate.getPrimitive2DID()));
-                                        break;
-                                    }
-                                }
-                            }
-
-                            if(!bDrawTransparentUsed)
-                            {
-                                // unified sub-transparence. Draw to VDev first.
-                                RenderUnifiedTransparencePrimitive2D(rUniTransparenceCandidate);
-                            }
-                        }
-                    }
-
+                    processUnifiedTransparencePrimitive2D(static_cast<const primitive2d::UnifiedTransparencePrimitive2D&>(rCandidate));
                     break;
                 }
                 case PRIMITIVE2D_ID_TRANSPARENCEPRIMITIVE2D :
@@ -639,199 +385,22 @@ namespace drawinglayer
                 }
                 case PRIMITIVE2D_ID_CONTROLPRIMITIVE2D :
                 {
-                    // control primitive
-                    const primitive2d::ControlPrimitive2D& rControlPrimitive = static_cast< const primitive2d::ControlPrimitive2D& >(rCandidate);
-                    const uno::Reference< awt::XControl >& rXControl(rControlPrimitive.getXControl());
-
-                    try
-                    {
-                        // remember old graphics and create new
-                        uno::Reference< awt::XView > xControlView(rXControl, uno::UNO_QUERY_THROW);
-                        const uno::Reference< awt::XGraphics > xOriginalGraphics(xControlView->getGraphics());
-                        const uno::Reference< awt::XGraphics > xNewGraphics(mpOutputDevice->CreateUnoGraphics());
-
-                        if(xNewGraphics.is())
-                        {
-                            // link graphics and view
-                            xControlView->setGraphics(xNewGraphics);
-
-                            // get position
-                            const basegfx::B2DHomMatrix aObjectToPixel(maCurrentTransformation * rControlPrimitive.getTransform());
-                            const basegfx::B2DPoint aTopLeftPixel(aObjectToPixel * basegfx::B2DPoint(0.0, 0.0));
-
-                            // find out if the control is already visualized as a VCL-ChildWindow. If yes,
-                            // it does not need to be painted at all.
-                            uno::Reference< awt::XWindow2 > xControlWindow(rXControl, uno::UNO_QUERY_THROW);
-                            const bool bControlIsVisibleAsChildWindow(rXControl->getPeer().is() && xControlWindow->isVisible());
-
-                            if(!bControlIsVisibleAsChildWindow)
-                            {
-                                // draw it. Do not forget to use the evtl. offsetted origin of the target device,
-                                // e.g. when used with mask/transparence buffer device
-                                const Point aOrigin(mpOutputDevice->GetMapMode().GetOrigin());
-                                xControlView->draw(
-                                    aOrigin.X() + basegfx::fround(aTopLeftPixel.getX()),
-                                    aOrigin.Y() + basegfx::fround(aTopLeftPixel.getY()));
-                            }
-
-                            // restore original graphics
-                            xControlView->setGraphics(xOriginalGraphics);
-                        }
-                    }
-                    catch(const uno::Exception&)
-                    {
-                        // #i116763# removing since there is a good alternative when the xControlView
-                        // is not found and it is allowed to happen
-                        // DBG_UNHANDLED_EXCEPTION();
-
-                        // process recursively and use the decomposition as Bitmap
-                        process(rCandidate);
-                    }
-
+                    processControlPrimitive2D(static_cast<const primitive2d::ControlPrimitive2D&>(rCandidate));
                     break;
                 }
                 case PRIMITIVE2D_ID_POLYGONSTROKEPRIMITIVE2D:
                 {
-                    // try to use directly
-                    const primitive2d::PolygonStrokePrimitive2D& rPolygonStrokePrimitive2D = static_cast< const primitive2d::PolygonStrokePrimitive2D& >(rCandidate);
-
-                    if(tryDrawPolygonStrokePrimitive2DDirect(rPolygonStrokePrimitive2D, 0.0))
-                    {
-                        break;
-                    }
-
-                    // the stroke primitive may be decomposed to filled polygons. To keep
-                    // evtl. set DrawModes aka DrawModeFlags::BlackLine, DrawModeFlags::GrayLine,
-                    // DrawModeFlags::GhostedLine, DrawModeFlags::WhiteLine or DrawModeFlags::SettingsLine
-                    // working, these need to be copied to the corresponding fill modes
-                    const DrawModeFlags nOriginalDrawMode(mpOutputDevice->GetDrawMode());
-                    adaptLineToFillDrawMode();
-
-                    // polygon stroke primitive
-                    static bool bSuppressFatToHairlineCorrection(false);
-
-                    if(bSuppressFatToHairlineCorrection)
-                    {
-                        // remember that we enter a PolygonStrokePrimitive2D decomposition,
-                        // used for AA thick line drawing
-                        mnPolygonStrokePrimitive2D++;
-
-                        // with AA there is no need to handle thin lines special
-                        process(rCandidate);
-
-                        // leave PolygonStrokePrimitive2D
-                        mnPolygonStrokePrimitive2D--;
-                    }
-                    else
-                    {
-                        // Lines with 1 and 2 pixel width without AA need special treatment since their vsiualisation
-                        // as filled polygons is geometrically correct but looks wrong since polygon filling avoids
-                        // the right and bottom pixels. The used method evaluates that and takes the correct action,
-                        // including calling recursively with decomposition if line is wide enough
-                        RenderPolygonStrokePrimitive2D(rPolygonStrokePrimitive2D);
-                    }
-
-                    // restore DrawMode
-                    mpOutputDevice->SetDrawMode(nOriginalDrawMode);
-
+                    processPolygonStrokePrimitive2D(static_cast<const primitive2d::PolygonStrokePrimitive2D&>(rCandidate));
                     break;
                 }
                 case PRIMITIVE2D_ID_FILLHATCHPRIMITIVE2D :
                 {
-                    static bool bForceIgnoreHatchSmoothing(false);
-
-                    if(bForceIgnoreHatchSmoothing || getOptionsDrawinglayer().IsAntiAliasing())
-                    {
-                        // if AA is used (or ignore smoothing is on), there is no need to smooth
-                        // hatch painting, use decomposition
-                        process(rCandidate);
-                    }
-                    else
-                    {
-                        // without AA, use VCL to draw the hatch. It snaps hatch distances to the next pixel
-                        // and forces hatch distance to be >= 3 pixels to make the hatch display look smoother.
-                        // This is wrong in principle, but looks nicer. This could also be done here directly
-                        // without VCL usage if needed
-                        const primitive2d::FillHatchPrimitive2D& rFillHatchPrimitive = static_cast< const primitive2d::FillHatchPrimitive2D& >(rCandidate);
-                        const attribute::FillHatchAttribute& rFillHatchAttributes = rFillHatchPrimitive.getFillHatch();
-
-                        // create hatch polygon in range size and discrete coordinates
-                        basegfx::B2DRange aHatchRange(rFillHatchPrimitive.getOutputRange());
-                        aHatchRange.transform(maCurrentTransformation);
-                        const basegfx::B2DPolygon aHatchPolygon(basegfx::utils::createPolygonFromRect(aHatchRange));
-
-                        if(rFillHatchAttributes.isFillBackground())
-                        {
-                            // #i111846# background fill is active; draw fill polygon
-                            const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(rFillHatchPrimitive.getBColor()));
-
-                            mpOutputDevice->SetFillColor(Color(aPolygonColor));
-                            mpOutputDevice->SetLineColor();
-                            mpOutputDevice->DrawPolygon(aHatchPolygon);
-                        }
-
-                        // set hatch line color
-                        const basegfx::BColor aHatchColor(maBColorModifierStack.getModifiedColor(rFillHatchPrimitive.getBColor()));
-                        mpOutputDevice->SetFillColor();
-                        mpOutputDevice->SetLineColor(Color(aHatchColor));
-
-                        // get hatch style
-                        HatchStyle eHatchStyle(HatchStyle::Single);
-
-                        switch(rFillHatchAttributes.getStyle())
-                        {
-                            default : // HatchStyle::Single
-                            {
-                                break;
-                            }
-                            case attribute::HatchStyle::Double :
-                            {
-                                eHatchStyle = HatchStyle::Double;
-                                break;
-                            }
-                            case attribute::HatchStyle::Triple :
-                            {
-                                eHatchStyle = HatchStyle::Triple;
-                                break;
-                            }
-                        }
-
-                        // create hatch
-                        const basegfx::B2DVector aDiscreteDistance(maCurrentTransformation * basegfx::B2DVector(rFillHatchAttributes.getDistance(), 0.0));
-                        const sal_uInt32 nDistance(basegfx::fround(aDiscreteDistance.getLength()));
-                        const sal_uInt16 nAngle10(static_cast<sal_uInt16>(basegfx::fround(rFillHatchAttributes.getAngle() / F_PI1800)));
-                        ::Hatch aVCLHatch(eHatchStyle, Color(rFillHatchAttributes.getColor()), nDistance, nAngle10);
-
-                        // draw hatch using VCL
-                        mpOutputDevice->DrawHatch(::tools::PolyPolygon(::tools::Polygon(aHatchPolygon)), aVCLHatch);
-                    }
+                    processFillHatchPrimitive2D(static_cast<const primitive2d::FillHatchPrimitive2D&>(rCandidate));
                     break;
                 }
                 case PRIMITIVE2D_ID_BACKGROUNDCOLORPRIMITIVE2D :
                 {
-                    // #i98404# Handle directly, especially when AA is active
-                    const primitive2d::BackgroundColorPrimitive2D& rPrimitive = static_cast< const primitive2d::BackgroundColorPrimitive2D& >(rCandidate);
-                    const AntialiasingFlags nOriginalAA(mpOutputDevice->GetAntialiasing());
-
-                    // switch AA off in all cases
-                    mpOutputDevice->SetAntialiasing(mpOutputDevice->GetAntialiasing() & ~AntialiasingFlags::EnableB2dDraw);
-
-                    // create color for fill
-                    const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(rPrimitive.getBColor()));
-                    Color aFillColor(aPolygonColor);
-                    aFillColor.SetTransparency(sal_uInt8((rPrimitive.getTransparency() * 255.0) + 0.5));
-                    mpOutputDevice->SetFillColor(aFillColor);
-                    mpOutputDevice->SetLineColor();
-
-                    // create rectangle for fill
-                    const basegfx::B2DRange& aViewport(getViewInformation2D().getDiscreteViewport());
-                    const ::tools::Rectangle aRectangle(
-                        static_cast<sal_Int32>(floor(aViewport.getMinX())), static_cast<sal_Int32>(floor(aViewport.getMinY())),
-                        static_cast<sal_Int32>(ceil(aViewport.getMaxX())), static_cast<sal_Int32>(ceil(aViewport.getMaxY())));
-                    mpOutputDevice->DrawRect(aRectangle);
-
-                    // restore AA setting
-                    mpOutputDevice->SetAntialiasing(nOriginalAA);
+                    processBackgroundColorPrimitive2D(static_cast<const primitive2d::BackgroundColorPrimitive2D&>(rCandidate));
                     break;
                 }
                 case PRIMITIVE2D_ID_TEXTHIERARCHYEDITPRIMITIVE2D :
@@ -847,20 +416,7 @@ namespace drawinglayer
                 }
                 case PRIMITIVE2D_ID_INVERTPRIMITIVE2D :
                 {
-                    // invert primitive (currently only used for HighContrast fallback for selection in SW and SC).
-                    // (Not true, also used at least for the drawing of dragged column and row boundaries in SC.)
-                    // Set OutDev to XOR and switch AA off (XOR does not work with AA)
-                    mpOutputDevice->Push();
-                    mpOutputDevice->SetRasterOp( RasterOp::Xor );
-                    const AntialiasingFlags nAntiAliasing(mpOutputDevice->GetAntialiasing());
-                    mpOutputDevice->SetAntialiasing(nAntiAliasing & ~AntialiasingFlags::EnableB2dDraw);
-
-                    // process content recursively
-                    process(rCandidate);
-
-                    // restore OutDev
-                    mpOutputDevice->Pop();
-                    mpOutputDevice->SetAntialiasing(nAntiAliasing);
+                    processInvertPrimitive2D(rCandidate);
                     break;
                 }
                 case PRIMITIVE2D_ID_EPSPRIMITIVE2D :
@@ -880,26 +436,7 @@ namespace drawinglayer
                 }
                 case PRIMITIVE2D_ID_BORDERLINEPRIMITIVE2D:
                 {
-                    // process recursively, but switch off AntiAliasing for
-                    // horizontal/vertical lines (*not* diagonal lines).
-                    // Checked using AntialiasingFlags::PixelSnapHairline instead,
-                    // but with AntiAliasing on the display really is too 'ghosty' when
-                    // using fine stroking. Correct, but 'ghosty'.
-                    const drawinglayer::primitive2d::BorderLinePrimitive2D& rBorder =
-                        static_cast<const drawinglayer::primitive2d::BorderLinePrimitive2D&>(rCandidate);
-
-                    if (rBorder.isHorizontalOrVertical(getViewInformation2D()))
-                    {
-                        AntialiasingFlags nAntiAliasing = mpOutputDevice->GetAntialiasing();
-                        mpOutputDevice->SetAntialiasing(nAntiAliasing & ~AntialiasingFlags::EnableB2dDraw);
-
-                        process(rCandidate);
-                        mpOutputDevice->SetAntialiasing(nAntiAliasing);
-                    }
-                    else
-                    {
-                        process(rCandidate);
-                    }
+                    processBorderLinePrimitive2D(static_cast<const drawinglayer::primitive2d::BorderLinePrimitive2D&>(rCandidate));
                     break;
                 }
                 default :
@@ -911,6 +448,522 @@ namespace drawinglayer
                 }
             }
         }
+
+        void VclPixelProcessor2D::processWrongSpellPrimitive2D(const primitive2d::WrongSpellPrimitive2D& rWrongSpellPrimitive)
+        {
+            // directdraw of wrong spell primitive; added test possibility to check wrong spell decompose
+            static bool bHandleWrongSpellDirectly(true);
+
+            if(bHandleWrongSpellDirectly)
+            {
+                if(!renderWrongSpellPrimitive2D(
+                    rWrongSpellPrimitive,
+                    *mpOutputDevice,
+                    maCurrentTransformation,
+                    maBColorModifierStack))
+                {
+                    // fallback to decomposition (MetaFile)
+                    process(rWrongSpellPrimitive);
+                }
+            }
+            else
+            {
+                process(rWrongSpellPrimitive);
+            }
+        }
+
+        void VclPixelProcessor2D::processTextSimplePortionPrimitive2D(const primitive2d::TextSimplePortionPrimitive2D& rCandidate)
+        {
+            // directdraw of text simple portion; added test possibility to check text decompose
+            static bool bForceSimpleTextDecomposition(false);
+
+            // Adapt evtl. used special DrawMode
+            const DrawModeFlags nOriginalDrawMode(mpOutputDevice->GetDrawMode());
+            adaptTextToFillDrawMode();
+
+            if(!bForceSimpleTextDecomposition && getOptionsDrawinglayer().IsRenderSimpleTextDirect())
+            {
+                RenderTextSimpleOrDecoratedPortionPrimitive2D(rCandidate);
+            }
+            else
+            {
+                process(rCandidate);
+            }
+
+            // restore DrawMode
+            mpOutputDevice->SetDrawMode(nOriginalDrawMode);
+        }
+
+        void VclPixelProcessor2D::processTextDecoratedPortionPrimitive2D(const primitive2d::TextSimplePortionPrimitive2D& rCandidate)
+        {
+            // directdraw of decorated text portion; added test possibility to check text decompose
+            static bool bForceComplexTextDecomposition(false);
+
+            // Adapt evtl. used special DrawMode
+            const DrawModeFlags nOriginalDrawMode(mpOutputDevice->GetDrawMode());
+            adaptTextToFillDrawMode();
+
+            if(!bForceComplexTextDecomposition && getOptionsDrawinglayer().IsRenderDecoratedTextDirect())
+            {
+                RenderTextSimpleOrDecoratedPortionPrimitive2D(rCandidate);
+            }
+            else
+            {
+                process(rCandidate);
+            }
+
+            // restore DrawMode
+            mpOutputDevice->SetDrawMode(nOriginalDrawMode);
+        }
+
+        void VclPixelProcessor2D::processPolygonHairlinePrimitive2D(const primitive2d::PolygonHairlinePrimitive2D& rPolygonHairlinePrimitive2D)
+        {
+            // try to use directly
+            static bool bAllowed(true);
+
+            if(bAllowed && tryDrawPolygonHairlinePrimitive2DDirect(rPolygonHairlinePrimitive2D, 0.0))
+            {
+                return;
+            }
+
+            // direct draw of hairline
+            RenderPolygonHairlinePrimitive2D(rPolygonHairlinePrimitive2D, true);
+        }
+
+        void VclPixelProcessor2D::processBitmapPrimitive2D(const primitive2d::BitmapPrimitive2D& rBitmapCandidate)
+        {
+            // check if graphic content is inside discrete local ViewPort
+            const basegfx::B2DRange& rDiscreteViewPort(getViewInformation2D().getDiscreteViewport());
+            const basegfx::B2DHomMatrix aLocalTransform(maCurrentTransformation * rBitmapCandidate.getTransform());
+
+            if(!rDiscreteViewPort.isEmpty())
+            {
+                basegfx::B2DRange aUnitRange(0.0, 0.0, 1.0, 1.0);
+
+                aUnitRange.transform(aLocalTransform);
+
+                if(!aUnitRange.overlaps(rDiscreteViewPort))
+                {
+                    // content is outside discrete local ViewPort
+                    return;
+                }
+            }
+
+            RenderBitmapPrimitive2D(rBitmapCandidate);
+        }
+
+        void VclPixelProcessor2D::processPolyPolygonGradientPrimitive2D(const primitive2d::PolyPolygonGradientPrimitive2D& rPolygonCandidate)
+        {
+            // direct draw of gradient
+            const attribute::FillGradientAttribute& rGradient(rPolygonCandidate.getFillGradient());
+            basegfx::BColor aStartColor(maBColorModifierStack.getModifiedColor(rGradient.getStartColor()));
+            basegfx::BColor aEndColor(maBColorModifierStack.getModifiedColor(rGradient.getEndColor()));
+            basegfx::B2DPolyPolygon aLocalPolyPolygon(rPolygonCandidate.getB2DPolyPolygon());
+
+            if(aLocalPolyPolygon.count())
+            {
+                aLocalPolyPolygon.transform(maCurrentTransformation);
+
+                if(aStartColor == aEndColor)
+                {
+                    // no gradient at all, draw as polygon in AA and non-AA case
+                    mpOutputDevice->SetLineColor();
+                    mpOutputDevice->SetFillColor(Color(aStartColor));
+                    mpOutputDevice->DrawPolyPolygon(aLocalPolyPolygon);
+                }
+                else
+                {
+                    // use the primitive decomposition of the metafile
+                    process(rPolygonCandidate);
+                }
+            }
+        }
+
+        void VclPixelProcessor2D::processPolyPolygonColorPrimitive2D(const primitive2d::PolyPolygonColorPrimitive2D& rPolyPolygonColorPrimitive2D)
+        {
+            // try to use directly
+            basegfx::B2DPolyPolygon aLocalPolyPolygon;
+            static bool bAllowed(true);
+
+            if(bAllowed)
+            {
+                tryDrawPolyPolygonColorPrimitive2DDirect(rPolyPolygonColorPrimitive2D, 0.0);
+                // okay, done. In this case no gaps should have to be repaired, too
+            }
+            else
+            {
+                // direct draw of tools::PolyPolygon with color
+                const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(rPolyPolygonColorPrimitive2D.getBColor()));
+
+                mpOutputDevice->SetFillColor(Color(aPolygonColor));
+                mpOutputDevice->SetLineColor();
+                aLocalPolyPolygon = rPolyPolygonColorPrimitive2D.getB2DPolyPolygon();
+                aLocalPolyPolygon.transform(maCurrentTransformation);
+                mpOutputDevice->DrawPolyPolygon(aLocalPolyPolygon);
+            }
+
+            // when AA is on and this filled polygons are the result of stroked line geometry,
+            // draw the geometry once extra as lines to avoid AA 'gaps' between partial polygons
+            // Caution: This is needed in both cases (!)
+            if(mnPolygonStrokePrimitive2D
+                && getOptionsDrawinglayer().IsAntiAliasing()
+                && (mpOutputDevice->GetAntialiasing() & AntialiasingFlags::EnableB2dDraw))
+            {
+                const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(rPolyPolygonColorPrimitive2D.getBColor()));
+                sal_uInt32 nCount(aLocalPolyPolygon.count());
+
+                if(!nCount)
+                {
+                    aLocalPolyPolygon = rPolyPolygonColorPrimitive2D.getB2DPolyPolygon();
+                    aLocalPolyPolygon.transform(maCurrentTransformation);
+                    nCount = aLocalPolyPolygon.count();
+                }
+
+                mpOutputDevice->SetFillColor();
+                mpOutputDevice->SetLineColor(Color(aPolygonColor));
+
+                for(sal_uInt32 a(0); a < nCount; a++)
+                {
+                    mpOutputDevice->DrawPolyLine(aLocalPolyPolygon.getB2DPolygon(a), 0.0);
+                }
+            }
+        }
+
+        void VclPixelProcessor2D::processUnifiedTransparencePrimitive2D(const primitive2d::UnifiedTransparencePrimitive2D& rUniTransparenceCandidate)
+        {
+            // Detect if a single PolyPolygonColorPrimitive2D is contained; in that case,
+            // use the faster OutputDevice::DrawTransparent method
+            const primitive2d::Primitive2DContainer& rContent = rUniTransparenceCandidate.getChildren();
+
+            if(!rContent.empty())
+            {
+                if(0.0 == rUniTransparenceCandidate.getTransparence())
+                {
+                    // not transparent at all, use content
+                    process(rUniTransparenceCandidate.getChildren());
+                }
+                else if(rUniTransparenceCandidate.getTransparence() > 0.0 && rUniTransparenceCandidate.getTransparence() < 1.0)
+                {
+                    bool bDrawTransparentUsed(false);
+
+                    // since DEV300 m33 DrawTransparent is supported in VCL (for some targets
+                    // natively), so i am now enabling this shortcut
+                    static bool bAllowUsingDrawTransparent(true);
+
+                    if(bAllowUsingDrawTransparent && 1 == rContent.size())
+                    {
+                        const primitive2d::Primitive2DReference xReference(rContent[0]);
+                        const primitive2d::BasePrimitive2D* pBasePrimitive = dynamic_cast< const primitive2d::BasePrimitive2D* >(xReference.get());
+
+                        if(pBasePrimitive)
+                        {
+                            switch(pBasePrimitive->getPrimitive2DID())
+                            {
+                                case PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D:
+                                {
+                                    // single transparent tools::PolyPolygon identified, use directly
+                                    const primitive2d::PolyPolygonColorPrimitive2D* pPoPoColor = static_cast< const primitive2d::PolyPolygonColorPrimitive2D* >(pBasePrimitive);
+                                    OSL_ENSURE(pPoPoColor, "OOps, PrimitiveID and PrimitiveType do not match (!)");
+                                    bDrawTransparentUsed = true;
+                                    tryDrawPolyPolygonColorPrimitive2DDirect(*pPoPoColor, rUniTransparenceCandidate.getTransparence());
+                                    break;
+                                }
+                                case PRIMITIVE2D_ID_POLYGONHAIRLINEPRIMITIVE2D:
+                                {
+                                    // single transparent PolygonHairlinePrimitive2D identified, use directly
+                                    const primitive2d::PolygonHairlinePrimitive2D* pPoHair = static_cast< const primitive2d::PolygonHairlinePrimitive2D* >(pBasePrimitive);
+                                    OSL_ENSURE(pPoHair, "OOps, PrimitiveID and PrimitiveType do not match (!)");
+
+                                    // do no tallow by default - problem is that self-overlapping parts of this geometry will
+                                    // not be in a all-same transparency but will already alpha-cover themselves with blending.
+                                    // This is not what the UnifiedTransparencePrimitive2D defines: It requires all its
+                                    // content to be uniformely transparent.
+                                    // For hairline the effect is pretty minimal, but still not correct.
+                                    static bool bAllowed(false);
+
+                                    bDrawTransparentUsed = bAllowed && tryDrawPolygonHairlinePrimitive2DDirect(*pPoHair, rUniTransparenceCandidate.getTransparence());
+                                    break;
+                                }
+                                case PRIMITIVE2D_ID_POLYGONSTROKEPRIMITIVE2D:
+                                {
+                                    // single transparent PolygonStrokePrimitive2D identified, use directly
+                                    const primitive2d::PolygonStrokePrimitive2D* pPoStroke = static_cast< const primitive2d::PolygonStrokePrimitive2D* >(pBasePrimitive);
+                                    OSL_ENSURE(pPoStroke, "OOps, PrimitiveID and PrimitiveType do not match (!)");
+
+                                    // do no tallow by default - problem is that self-overlapping parts of this geometry will
+                                    // not be in a all-same transparency but will already alpha-cover themselves with blending.
+                                    // This is not what the UnifiedTransparencePrimitive2D defines: It requires all its
+                                    // content to be uniformely transparent.
+                                    // To check, activate and draw a wide transparent self-crossing line/curve
+                                    static bool bAllowed(false);
+
+                                    bDrawTransparentUsed = bAllowed && tryDrawPolygonStrokePrimitive2DDirect(*pPoStroke, rUniTransparenceCandidate.getTransparence());
+                                    break;
+                                }
+                            default:
+                                SAL_INFO("drawinglayer", "default case for " << drawinglayer::primitive2d::idToString(rUniTransparenceCandidate.getPrimitive2DID()));
+                                break;
+                            }
+                        }
+                    }
+
+                    if(!bDrawTransparentUsed)
+                    {
+                        // unified sub-transparence. Draw to VDev first.
+                        RenderUnifiedTransparencePrimitive2D(rUniTransparenceCandidate);
+                    }
+                }
+            }
+        }
+

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list