[Libreoffice-commits] core.git: Branch 'feature/OperationSmiley' - 33 commits - bridges/source configure.ac cui/source distro-configs/LibreOfficeFlatpak.conf extensions/source filter/source forms/source helpcontent2 i18npool/source include/filter include/oox include/svx include/vcl ios/LibreOfficeLight libreofficekit/qa oox/source sc/inc sc/qa sc/source sd/inc sd/source solenv/flatpak-manifest.in svx/inc svx/source sw/inc sw/qa sw/source sw/uiconfig unodevtools/source vcl/backendtest vcl/CppunitTest_vcl_jpeg_read_write_test.mk vcl/inc vcl/qa vcl/source vcl/unx vcl/workben writerfilter/source xmloff/source

Armin Le Grand (CIB) Armin.Le.Grand at cib.de
Thu Mar 15 23:03:34 UTC 2018


Rebased ref, commits from common ancestor:
commit 642864b0e0cd479dcf95bca6893f19b2ae998616
Author: Armin Le Grand <Armin.Le.Grand at cib.de (CIB)>
Date:   Thu Mar 15 11:32:00 2018 +0100

    OperationSmiley: Secured quite some places using CustomShape
    
    Changed quite some places of SdrObjCustomShape usage to use
    references instead of pointers, thus forcing to more secure
    handling. Changed some test and change methods, even found a
    memory leak by doing so.
    Added some incudes/predefines for linux builds.
    
    Change-Id: Iba76037a3c54af50bb05e6bd63d7ad04624665a7

diff --git a/include/svx/EnhancedCustomShape2d.hxx b/include/svx/EnhancedCustomShape2d.hxx
index 8eb5021b3bad..5f8567a19c38 100644
--- a/include/svx/EnhancedCustomShape2d.hxx
+++ b/include/svx/EnhancedCustomShape2d.hxx
@@ -42,6 +42,7 @@
 class Color;
 class SdrObject;
 class SdrPathObj;
+class SdrObjCustomShape;
 
 enum class HandleFlags
 {
diff --git a/svx/source/customshapes/EnhancedCustomShape3d.hxx b/svx/source/customshapes/EnhancedCustomShape3d.hxx
index 1c8290846b12..ba7c8dd3a9cd 100644
--- a/svx/source/customshapes/EnhancedCustomShape3d.hxx
+++ b/svx/source/customshapes/EnhancedCustomShape3d.hxx
@@ -28,6 +28,7 @@
 #include <tools/gen.hxx>
 
 class SdrObject;
+class SdrObjCustomShape;
 
 class EnhancedCustomShape3d final
 {
diff --git a/svx/source/customshapes/EnhancedCustomShapeFontWork.hxx b/svx/source/customshapes/EnhancedCustomShapeFontWork.hxx
index 9fd954cd7034..335701be4125 100644
--- a/svx/source/customshapes/EnhancedCustomShapeFontWork.hxx
+++ b/svx/source/customshapes/EnhancedCustomShapeFontWork.hxx
@@ -23,6 +23,8 @@
 #include <com/sun/star/i18n/XBreakIterator.hpp>
 
 class SdrObject;
+class SdrObjCustomShape;
+
 class EnhancedCustomShapeFontWork
 {
         static css::uno::Reference < css::i18n::XBreakIterator > mxBreakIterator;
diff --git a/svx/source/customshapes/EnhancedCustomShapeHandle.cxx b/svx/source/customshapes/EnhancedCustomShapeHandle.cxx
index d4975c41f4db..ee7143459b9c 100644
--- a/svx/source/customshapes/EnhancedCustomShapeHandle.cxx
+++ b/svx/source/customshapes/EnhancedCustomShapeHandle.cxx
@@ -20,6 +20,7 @@
 #include "EnhancedCustomShapeHandle.hxx"
 #include <svx/EnhancedCustomShape2d.hxx>
 #include <svx/unoapi.hxx>
+#include <svx/svdoashp.hxx>
 
 
 EnhancedCustomShapeHandle::EnhancedCustomShapeHandle( css::uno::Reference< css::drawing::XShape > const & xCustomShape, sal_uInt32 nIndex ) :
diff --git a/svx/source/sdr/contact/viewcontactofsdrpathobj.cxx b/svx/source/sdr/contact/viewcontactofsdrpathobj.cxx
index c3033bf71337..3c7598115363 100644
--- a/svx/source/sdr/contact/viewcontactofsdrpathobj.cxx
+++ b/svx/source/sdr/contact/viewcontactofsdrpathobj.cxx
@@ -26,7 +26,7 @@
 #include <basegfx/polygon/b2dpolygonclipper.hxx>
 #include <sdr/primitive2d/sdrpathprimitive2d.hxx>
 #include <basegfx/matrix/b2dhommatrixtools.hxx>
-
+#include <basegfx/polygon/b2dpolygontools.hxx>
 
 namespace sdr
 {
commit 2855ffab23949360be549804090e947ebd5c5edc
Author: Armin Le Grand <Armin.Le.Grand at cib.de (CIB)>
Date:   Thu Mar 15 11:32:00 2018 +0100

    OperationSmiley: Secured quite some places using CustomShape
    
    Changed quite some places of SdrObjCustomShape usage to use
    references instead of pointers, thus forcing to more secure
    handling. Changed some test and change methods, even found a
    memory leak by doing so.
    
    Change-Id: Iba76037a3c54af50bb05e6bd63d7ad04624665a7

diff --git a/cui/source/tabpages/transfrm.cxx b/cui/source/tabpages/transfrm.cxx
index 7ce63c79aa0d..bb95a7ca5153 100644
--- a/cui/source/tabpages/transfrm.cxx
+++ b/cui/source/tabpages/transfrm.cxx
@@ -24,6 +24,7 @@
 #include <svx/svdobj.hxx>
 #include <svx/svdpagv.hxx>
 #include <svx/svdotext.hxx>
+#include <svx/svdoashp.hxx>
 #include <svx/sderitm.hxx>
 #include <svx/dialogs.hrc>
 #include <svx/transfrmhelper.hxx>
@@ -530,42 +531,80 @@ bool SvxSlantTabPage::FillItemSet(SfxItemSet* rAttrs)
     if (!bControlPointsChanged)
         return bModified;
 
-    SdrObject* pObj = pView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj();
-    SdrModel* pModel = pObj->GetModel();
-    SdrUndoAction* pUndo = pModel->IsUndoEnabled() ?
-                pModel->GetSdrUndoFactory().CreateUndoAttrObject(*pObj) :
-                nullptr;
+    bool bSelectionIsSdrObjCustomShape(false);
 
-    if (pUndo)
-        pModel->BegUndo(pUndo->GetComment());
+    while(true)
+    {
+        if(nullptr == pView)
+        {
+            break;
+        }
+
+        if(0 == pView->GetMarkedObjectList().GetMarkCount())
+        {
+            break;
+        }
 
-    EnhancedCustomShape2d aShape(pObj);
-    ::tools::Rectangle aLogicRect = aShape.GetLogicRect();
+        SdrObject* pCandidate(pView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj());
 
-    for (int i = 0; i < 2; ++i)
+        if(nullptr == pCandidate)
+        {
+            break;
+        }
+
+        if(nullptr == dynamic_cast< SdrObjCustomShape* >(pCandidate))
+        {
+            break;
+        }
+
+        bSelectionIsSdrObjCustomShape = true;
+        break;
+    }
+
+    if(bSelectionIsSdrObjCustomShape)
     {
-        if (m_aControlX[i]->IsValueChangedFromSaved() || m_aControlY[i]->IsValueChangedFromSaved())
+        SdrObjCustomShape& rSdrObjCustomShape(
+            static_cast< SdrObjCustomShape& >(
+                *pView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj()));
+        SdrModel* pModel(rSdrObjCustomShape.GetModel());
+        SdrUndoAction* pUndo(
+            pModel->IsUndoEnabled()
+                ? pModel->GetSdrUndoFactory().CreateUndoAttrObject(rSdrObjCustomShape)
+                : nullptr);
+
+        if(pUndo)
         {
-            Point aNewPosition(GetCoreValue(*m_aControlX[i], ePoolUnit),
-                               GetCoreValue(*m_aControlY[i], ePoolUnit));
-            aNewPosition.Move(aLogicRect.Left(), aLogicRect.Top());
+            pModel->BegUndo(pUndo->GetComment());
+        }
 
-            css::awt::Point aPosition;
-            aPosition.X = aNewPosition.X();
-            aPosition.Y = aNewPosition.Y();
+        EnhancedCustomShape2d aShape(rSdrObjCustomShape);
+        ::tools::Rectangle aLogicRect = aShape.GetLogicRect();
 
-            aShape.SetHandleControllerPosition(i, aPosition);
+        for (int i = 0; i < 2; ++i)
+        {
+            if (m_aControlX[i]->IsValueChangedFromSaved() || m_aControlY[i]->IsValueChangedFromSaved())
+            {
+                Point aNewPosition(GetCoreValue(*m_aControlX[i], ePoolUnit),
+                                GetCoreValue(*m_aControlY[i], ePoolUnit));
+                aNewPosition.Move(aLogicRect.Left(), aLogicRect.Top());
+
+                css::awt::Point aPosition;
+                aPosition.X = aNewPosition.X();
+                aPosition.Y = aNewPosition.Y();
+
+                aShape.SetHandleControllerPosition(i, aPosition);
+            }
         }
-    }
 
-    pObj->SetChanged();
-    pObj->BroadcastObjectChange();
-    bModified = true;
+        rSdrObjCustomShape.SetChanged();
+        rSdrObjCustomShape.BroadcastObjectChange();
+        bModified = true;
 
-    if (pUndo)
-    {
-        pModel->AddUndo(pUndo);
-        pModel->EndUndo();
+        if (pUndo)
+        {
+            pModel->AddUndo(pUndo);
+            pModel->EndUndo();
+        }
     }
 
     return bModified;
@@ -622,67 +661,94 @@ void SvxSlantTabPage::Reset(const SfxItemSet* rAttrs)
 
     m_pMtrAngle->SaveValue();
 
-    const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
-    if (rMarkList.GetMarkCount() == 1)
+    bool bSelectionIsSdrObjCustomShape(false);
+
+    while(true)
     {
-        SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
-        SdrObjKind eKind = static_cast<SdrObjKind>(pObj->GetObjIdentifier());
-        if (eKind == OBJ_CUSTOMSHAPE)
+        if(nullptr == pView)
+        {
+            break;
+        }
+
+        if(1 != pView->GetMarkedObjectList().GetMarkCount())
         {
-            //save geometry
-            SdrCustomShapeGeometryItem aInitialGeometry =
-                pObj->GetMergedItem(SDRATTR_CUSTOMSHAPE_GEOMETRY);
+            break;
+        }
 
-            EnhancedCustomShape2d aShape(pObj);
+        SdrObject* pCandidate(pView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj());
 
-            for (int i = 0; i < 2; ++i)
-            {
-                Point aInitialPosition;
-                if (!aShape.GetHandlePosition(i, aInitialPosition))
-                    break;
-                m_aControlGroups[i]->Enable();
-                css::awt::Point aPosition;
+        if(nullptr == pCandidate)
+        {
+            break;
+        }
 
-                aPosition.X = SAL_MAX_INT32/2;
-                aPosition.Y = SAL_MAX_INT32/2;
-                aShape.SetHandleControllerPosition(i, aPosition);
-                Point aMaxPosition;
-                aShape.GetHandlePosition(i, aMaxPosition);
+        if(nullptr == dynamic_cast< SdrObjCustomShape* >(pCandidate))
+        {
+            break;
+        }
 
-                aPosition.X = SAL_MIN_INT32/2;
-                aPosition.Y = SAL_MIN_INT32/2;
-                aShape.SetHandleControllerPosition(i, aPosition);
-                Point aMinPosition;
-                aShape.GetHandlePosition(i, aMinPosition);
+        bSelectionIsSdrObjCustomShape = true;
+        break;
+    }
 
-                ::tools::Rectangle aLogicRect = aShape.GetLogicRect();
-                aInitialPosition.Move(-aLogicRect.Left(), -aLogicRect.Top());
-                aMaxPosition.Move(-aLogicRect.Left(), -aLogicRect.Top());
-                aMinPosition.Move(-aLogicRect.Left(), -aLogicRect.Top());
+    if(bSelectionIsSdrObjCustomShape)
+    {
+        SdrObjCustomShape& rSdrObjCustomShape(
+            static_cast< SdrObjCustomShape& >(
+                *pView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj()));
 
-                SetMetricValue(*m_aControlX[i], aInitialPosition.X(), ePoolUnit);
-                SetMetricValue(*m_aControlY[i], aInitialPosition.Y(), ePoolUnit);
+        //save geometry
+        SdrCustomShapeGeometryItem aInitialGeometry(rSdrObjCustomShape.GetMergedItem(SDRATTR_CUSTOMSHAPE_GEOMETRY));
+        EnhancedCustomShape2d aShape(rSdrObjCustomShape);
 
-                if (aMaxPosition.X() == aMinPosition.X())
-                    m_aControlGroupX[i]->Disable();
-                else
-                {
-                    m_aControlX[i]->SetMin(aMinPosition.X(), FUNIT_MM);
-                    m_aControlX[i]->SetMax(aMaxPosition.X(), FUNIT_MM);
-                }
-                if (aMaxPosition.Y() == aMinPosition.Y())
-                    m_aControlGroupY[i]->Disable();
-                else
-                {
-                    m_aControlY[i]->SetMin(aMinPosition.Y(), FUNIT_MM);
-                    m_aControlY[i]->SetMax(aMaxPosition.Y(), FUNIT_MM);
-                }
-            }
+        for (int i = 0; i < 2; ++i)
+        {
+            Point aInitialPosition;
+            if (!aShape.GetHandlePosition(i, aInitialPosition))
+                break;
+            m_aControlGroups[i]->Enable();
+            css::awt::Point aPosition;
+
+            aPosition.X = SAL_MAX_INT32/2;
+            aPosition.Y = SAL_MAX_INT32/2;
+            aShape.SetHandleControllerPosition(i, aPosition);
+            Point aMaxPosition;
+            aShape.GetHandlePosition(i, aMaxPosition);
+
+            aPosition.X = SAL_MIN_INT32/2;
+            aPosition.Y = SAL_MIN_INT32/2;
+            aShape.SetHandleControllerPosition(i, aPosition);
+            Point aMinPosition;
+            aShape.GetHandlePosition(i, aMinPosition);
+
+            ::tools::Rectangle aLogicRect = aShape.GetLogicRect();
+            aInitialPosition.Move(-aLogicRect.Left(), -aLogicRect.Top());
+            aMaxPosition.Move(-aLogicRect.Left(), -aLogicRect.Top());
+            aMinPosition.Move(-aLogicRect.Left(), -aLogicRect.Top());
 
-            //restore geometry
-            pObj->SetMergedItem(aInitialGeometry);
+            SetMetricValue(*m_aControlX[i], aInitialPosition.X(), ePoolUnit);
+            SetMetricValue(*m_aControlY[i], aInitialPosition.Y(), ePoolUnit);
+
+            if (aMaxPosition.X() == aMinPosition.X())
+                m_aControlGroupX[i]->Disable();
+            else
+            {
+                m_aControlX[i]->SetMin(aMinPosition.X(), FUNIT_MM);
+                m_aControlX[i]->SetMax(aMaxPosition.X(), FUNIT_MM);
+            }
+            if (aMaxPosition.Y() == aMinPosition.Y())
+                m_aControlGroupY[i]->Disable();
+            else
+            {
+                m_aControlY[i]->SetMin(aMinPosition.Y(), FUNIT_MM);
+                m_aControlY[i]->SetMax(aMaxPosition.Y(), FUNIT_MM);
+            }
         }
+
+        //restore geometry
+        rSdrObjCustomShape.SetMergedItem(aInitialGeometry);
     }
+
     for (int i = 0; i < 2; ++i)
     {
         m_aControlX[i]->SaveValue();
diff --git a/filter/source/msfilter/escherex.cxx b/filter/source/msfilter/escherex.cxx
index 9c7c01c5f0e6..228172a933c1 100644
--- a/filter/source/msfilter/escherex.cxx
+++ b/filter/source/msfilter/escherex.cxx
@@ -2400,109 +2400,109 @@ bool GetValueForEnhancedCustomShapeHandleParameter( sal_Int32& nRetValue, const
     return bSpecial;
 }
 
-void ConvertEnhancedCustomShapeEquation( SdrObjCustomShape* pCustoShape,
-        std::vector< EnhancedCustomShapeEquation >& rEquations, std::vector< sal_Int32 >& rEquationOrder )
+void ConvertEnhancedCustomShapeEquation(
+    const SdrObjCustomShape& rSdrObjCustomShape,
+    std::vector< EnhancedCustomShapeEquation >& rEquations,
+    std::vector< sal_Int32 >& rEquationOrder )
 {
-    if ( pCustoShape )
+    uno::Sequence< OUString > sEquationSource;
+    const SdrCustomShapeGeometryItem& rGeometryItem =
+        rSdrObjCustomShape.GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
+    const uno::Any* pAny = rGeometryItem.GetPropertyValueByName( "Equations" );
+    if ( pAny )
+        *pAny >>= sEquationSource;
+    sal_Int32 nEquationSourceCount = sEquationSource.getLength();
+    if ( nEquationSourceCount && (nEquationSourceCount <= 128) )
     {
-        uno::Sequence< OUString > sEquationSource;
-        const SdrCustomShapeGeometryItem& rGeometryItem =
-            pCustoShape->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
-        const uno::Any* pAny = rGeometryItem.GetPropertyValueByName( "Equations" );
-        if ( pAny )
-            *pAny >>= sEquationSource;
-        sal_Int32 nEquationSourceCount = sEquationSource.getLength();
-        if ( nEquationSourceCount && (nEquationSourceCount <= 128) )
+        sal_Int32 i;
+        for ( i = 0; i < nEquationSourceCount; i++ )
         {
-            sal_Int32 i;
-            for ( i = 0; i < nEquationSourceCount; i++ )
+            try
             {
-                EnhancedCustomShape2d aCustoShape2d( pCustoShape );
-                try
+                std::shared_ptr< EnhancedCustomShape::ExpressionNode > aExpressNode(
+                    EnhancedCustomShape::FunctionParser::parseFunction(
+                        sEquationSource[ i ],
+                        const_cast< SdrObjCustomShape& >(rSdrObjCustomShape)));
+                drawing::EnhancedCustomShapeParameter aPara( aExpressNode->fillNode( rEquations, nullptr, 0 ) );
+                if ( aPara.Type != drawing::EnhancedCustomShapeParameterType::EQUATION )
                 {
-                    std::shared_ptr< EnhancedCustomShape::ExpressionNode > aExpressNode(
-                        EnhancedCustomShape::FunctionParser::parseFunction( sEquationSource[ i ], aCustoShape2d ) );
-                    drawing::EnhancedCustomShapeParameter aPara( aExpressNode->fillNode( rEquations, nullptr, 0 ) );
-                    if ( aPara.Type != drawing::EnhancedCustomShapeParameterType::EQUATION )
-                    {
-                        EnhancedCustomShapeEquation aEquation;
-                        aEquation.nOperation = 0;
-                        EnhancedCustomShape::FillEquationParameter( aPara, 0, aEquation );
-                        rEquations.push_back( aEquation );
-                    }
-                }
-                catch ( const EnhancedCustomShape::ParseError& )
-                {
-                    EnhancedCustomShapeEquation aEquation;      // ups, we should not be here,
-                    aEquation.nOperation = 0;                   // creating a default equation with value 1
-                    aEquation.nPara[ 0 ] = 1;                   // hoping that this will not break anything
+                    EnhancedCustomShapeEquation aEquation;
+                    aEquation.nOperation = 0;
+                    EnhancedCustomShape::FillEquationParameter( aPara, 0, aEquation );
                     rEquations.push_back( aEquation );
                 }
-                catch ( ... )
-                {
-                    EnhancedCustomShapeEquation aEquation;      // #i112309# EnhancedCustomShape::Parse error
-                    aEquation.nOperation = 0;                   // not caught on linux platform
-                    aEquation.nPara[ 0 ] = 1;
-                    rEquations.push_back( aEquation );
-                }
-                rEquationOrder.push_back( rEquations.size() - 1 );
             }
-            // now updating our old equation indices, they are marked with a bit in the hiword of nOperation
-            for (auto & equation : rEquations)
+            catch ( const EnhancedCustomShape::ParseError& )
+            {
+                EnhancedCustomShapeEquation aEquation;      // ups, we should not be here,
+                aEquation.nOperation = 0;                   // creating a default equation with value 1
+                aEquation.nPara[ 0 ] = 1;                   // hoping that this will not break anything
+                rEquations.push_back( aEquation );
+            }
+            catch ( ... )
             {
-                sal_uInt32 nMask = 0x20000000;
-                for( i = 0; i < 3; i++ )
+                EnhancedCustomShapeEquation aEquation;      // #i112309# EnhancedCustomShape::Parse error
+                aEquation.nOperation = 0;                   // not caught on linux platform
+                aEquation.nPara[ 0 ] = 1;
+                rEquations.push_back( aEquation );
+            }
+            rEquationOrder.push_back( rEquations.size() - 1 );
+        }
+        // now updating our old equation indices, they are marked with a bit in the hiword of nOperation
+        for (auto & equation : rEquations)
+        {
+            sal_uInt32 nMask = 0x20000000;
+            for( i = 0; i < 3; i++ )
+            {
+                if ( equation.nOperation & nMask )
                 {
-                    if ( equation.nOperation & nMask )
-                    {
-                        equation.nOperation ^= nMask;
-                        const size_t nIndex(equation.nPara[ i ] & 0x3ff);
+                    equation.nOperation ^= nMask;
+                    const size_t nIndex(equation.nPara[ i ] & 0x3ff);
 
-                        // #i124661# check index access, there are cases where this is out of bound leading
-                        // to errors up to crashes when executed
-                        if(nIndex < rEquationOrder.size())
-                        {
-                            equation.nPara[ i ] = rEquationOrder[ nIndex ] | 0x400;
-                        }
-                        else
-                        {
-                            OSL_ENSURE(false, "Attempted out of bound access to rEquationOrder of CustomShape (!)");
-                        }
+                    // #i124661# check index access, there are cases where this is out of bound leading
+                    // to errors up to crashes when executed
+                    if(nIndex < rEquationOrder.size())
+                    {
+                        equation.nPara[ i ] = rEquationOrder[ nIndex ] | 0x400;
+                    }
+                    else
+                    {
+                        OSL_ENSURE(false, "Attempted out of bound access to rEquationOrder of CustomShape (!)");
                     }
-                    nMask <<= 1;
                 }
+                nMask <<= 1;
             }
         }
     }
 }
 
-bool EscherPropertyContainer::IsDefaultObject( SdrObjCustomShape const * pCustoShape , const MSO_SPT eShapeType )
+bool EscherPropertyContainer::IsDefaultObject(
+    const SdrObjCustomShape& rSdrObjCustomShape,
+    const MSO_SPT eShapeType)
 {
-    bool bIsDefaultObject = false;
     switch(eShapeType)
     {
         // if the custom shape is not default shape of ppt, return sal_Fasle;
         case mso_sptTearDrop:
-            return bIsDefaultObject;
+            return false;
 
         default:
             break;
     }
 
-    if ( pCustoShape )
+    if(rSdrObjCustomShape.IsDefaultGeometry( SdrObjCustomShape::DefaultType::Equations )
+        && rSdrObjCustomShape.IsDefaultGeometry( SdrObjCustomShape::DefaultType::Viewbox )
+        && rSdrObjCustomShape.IsDefaultGeometry( SdrObjCustomShape::DefaultType::Path )
+        && rSdrObjCustomShape.IsDefaultGeometry( SdrObjCustomShape::DefaultType::Gluepoints )
+        && rSdrObjCustomShape.IsDefaultGeometry( SdrObjCustomShape::DefaultType::Segments )
+        && rSdrObjCustomShape.IsDefaultGeometry( SdrObjCustomShape::DefaultType::StretchX )
+        && rSdrObjCustomShape.IsDefaultGeometry( SdrObjCustomShape::DefaultType::StretchY )
+        && rSdrObjCustomShape.IsDefaultGeometry( SdrObjCustomShape::DefaultType::TextFrames ) )
     {
-    if (   pCustoShape->IsDefaultGeometry( SdrObjCustomShape::DefaultType::Equations )
-           && pCustoShape->IsDefaultGeometry( SdrObjCustomShape::DefaultType::Viewbox )
-           && pCustoShape->IsDefaultGeometry( SdrObjCustomShape::DefaultType::Path )
-           && pCustoShape->IsDefaultGeometry( SdrObjCustomShape::DefaultType::Gluepoints )
-           && pCustoShape->IsDefaultGeometry( SdrObjCustomShape::DefaultType::Segments )
-           && pCustoShape->IsDefaultGeometry( SdrObjCustomShape::DefaultType::StretchX )
-           && pCustoShape->IsDefaultGeometry( SdrObjCustomShape::DefaultType::StretchY )
-           && pCustoShape->IsDefaultGeometry( SdrObjCustomShape::DefaultType::TextFrames ) )
-        bIsDefaultObject = true;
+        return true;
     }
 
-    return bIsDefaultObject;
+    return false;
 }
 
 void EscherPropertyContainer::LookForPolarHandles( const MSO_SPT eShapeType, sal_Int32& nAdjustmentsWhichNeedsToBeConverted )
@@ -2552,8 +2552,12 @@ void EscherPropertyContainer::CreateCustomShapeProperties( const MSO_SPT eShapeT
     uno::Reference< beans::XPropertySet > aXPropSet( rXShape, uno::UNO_QUERY );
     if ( aXPropSet.is() )
     {
-        SdrObjCustomShape* pCustoShape = static_cast<SdrObjCustomShape*>(GetSdrObjectFromXShape( rXShape ));
-        if ( !pCustoShape ) return;
+        if(nullptr == dynamic_cast< SdrObjCustomShape* >(GetSdrObjectFromXShape(rXShape)))
+        {
+            return;
+        }
+
+        SdrObjCustomShape& rSdrObjCustomShape(static_cast< SdrObjCustomShape& >(*GetSdrObjectFromXShape(rXShape)));
         const OUString sCustomShapeGeometry( "CustomShapeGeometry"  );
         uno::Any aGeoPropSet = aXPropSet->getPropertyValue( sCustomShapeGeometry );
         uno::Sequence< beans::PropertyValue > aGeoPropSeq;
@@ -2576,12 +2580,18 @@ void EscherPropertyContainer::CreateCustomShapeProperties( const MSO_SPT eShapeT
             sal_Int32 nAdjustmentsWhichNeedsToBeConverted = 0;
             uno::Sequence< beans::PropertyValues > aHandlesPropSeq;
             bool bPredefinedHandlesUsed = true;
-            bool bIsDefaultObject = IsDefaultObject( pCustoShape , eShapeType);
+            const bool bIsDefaultObject(
+                IsDefaultObject(
+                    rSdrObjCustomShape,
+                    eShapeType));
 
             // convert property "Equations" into std::vector< EnhancedCustomShapeEquationEquation >
             std::vector< EnhancedCustomShapeEquation >  aEquations;
             std::vector< sal_Int32 >                    aEquationOrder;
-            ConvertEnhancedCustomShapeEquation( pCustoShape, aEquations, aEquationOrder );
+            ConvertEnhancedCustomShapeEquation(
+                rSdrObjCustomShape,
+                aEquations,
+                aEquationOrder);
 
             sal_Int32 i, nCount = aGeoPropSeq.getLength();
             for ( i = 0; i < nCount; i++ )
@@ -3421,7 +3431,7 @@ void EscherPropertyContainer::CreateCustomShapeProperties( const MSO_SPT eShapeT
                                 case drawing::TextHorizontalAdjust_BLOCK:
                                     {
                                         drawing::TextFitToSizeType const eFTS(
-                                            pCustoShape->GetMergedItem( SDRATTR_TEXT_FITTOSIZE ).GetValue() );
+                                            rSdrObjCustomShape.GetMergedItem( SDRATTR_TEXT_FITTOSIZE ).GetValue() );
                                         if (eFTS == drawing::TextFitToSizeType_ALLLINES ||
                                             eFTS == drawing::TextFitToSizeType_PROPORTIONAL)
                                         {
@@ -3441,7 +3451,7 @@ void EscherPropertyContainer::CreateCustomShapeProperties( const MSO_SPT eShapeT
                         }
                         if((nTextPathFlags & 0x4000) != 0)  // Is Font work
                         {
-                            OutlinerParaObject* pOutlinerParaObject = pCustoShape->GetOutlinerParaObject();
+                            OutlinerParaObject* pOutlinerParaObject(rSdrObjCustomShape.GetOutlinerParaObject());
                             if ( pOutlinerParaObject && pOutlinerParaObject->IsVertical() )
                                 nTextPathFlags |= 0x2000;
                         }
@@ -4538,11 +4548,13 @@ sal_uInt32 EscherConnectorListEntry::GetConnectorRule( bool bFirst )
 
         if (aType == "drawing.Custom")
         {
-            SdrObject* pCustoShape(GetSdrObjectFromXShape(aXShape));
-            if (dynamic_cast<const SdrObjCustomShape*>(pCustoShape) !=  nullptr)
+            const bool bIsSdrObjCustomShape(nullptr != dynamic_cast< SdrObjCustomShape* >(GetSdrObjectFromXShape(aXShape)));
+
+            if(bIsSdrObjCustomShape)
             {
+                SdrObjCustomShape& rSdrObjCustomShape(static_cast< SdrObjCustomShape& >(*GetSdrObjectFromXShape(aXShape)));
                 const SdrCustomShapeGeometryItem& rGeometryItem =
-                    pCustoShape->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
+                    rSdrObjCustomShape.GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
 
                 const OUString sPath( "Path"  );
                 const OUString sType( "Type"  );
@@ -4563,7 +4575,7 @@ sal_uInt32 EscherConnectorListEntry::GetConnectorRule( bool bFirst )
 
                 if ( nGluePointType == drawing::EnhancedCustomShapeGluePointType::CUSTOM )
                 {
-                    const SdrGluePointList* pList = pCustoShape->GetGluePointList();
+                    const SdrGluePointList* pList = rSdrObjCustomShape.GetGluePointList();
                     if ( pList )
                     {
                         tools::Polygon aPoly;
@@ -4573,7 +4585,7 @@ sal_uInt32 EscherConnectorListEntry::GetConnectorRule( bool bFirst )
                             for ( nNum = 0; nNum < nCnt; nNum++ )
                             {
                                 const SdrGluePoint& rGP = (*pList)[ nNum ];
-                                Point aPt( rGP.GetAbsolutePos( *pCustoShape ) );
+                                Point aPt(rGP.GetAbsolutePos(rSdrObjCustomShape));
                                 aPoly.Insert( POLY_APPEND, aPt );
                             }
                             nRule = GetClosestPoint( aPoly, aRefPoint );
@@ -4583,15 +4595,25 @@ sal_uInt32 EscherConnectorListEntry::GetConnectorRule( bool bFirst )
                 }
                 else if ( nGluePointType == drawing::EnhancedCustomShapeGluePointType::SEGMENTS )
                 {
-                    SdrObject* pObject = pCustoShape->DoConvertToPolyObj(true, true);
-                    if (auto pSdrPathObj = dynamic_cast<const SdrPathObj*>(pObject))
-                    {
-                        sal_Int16 a, b, nIndex = 0;
-                        sal_uInt32 nDistance = 0xffffffff;
+                    tools::PolyPolygon aPolyPoly;
+                    SdrObject* pTemporyryConvertResultObject(rSdrObjCustomShape.DoConvertToPolyObj(true, true));
+                    SdrPathObj* pSdrPathObj(dynamic_cast< SdrPathObj* >(pTemporyryConvertResultObject));
 
+                    if(pSdrPathObj)
+                    {
                         // #i74631# use explicit constructor here. Also XPolyPolygon is not necessary,
                         // reducing to PolyPolygon
-                        const tools::PolyPolygon aPolyPoly(pSdrPathObj->GetPathPoly());
+                        aPolyPoly = tools::PolyPolygon(pSdrPathObj->GetPathPoly());
+                    }
+
+                    // do *not* forget to delete the temporary used SdrObject - possible memory leak (!)
+                    SdrObject::Free(pTemporyryConvertResultObject);
+                    pSdrPathObj = nullptr;
+
+                    if(0 != aPolyPoly.Count())
+                    {
+                        sal_Int16 a, b, nIndex = 0;
+                        sal_uInt32 nDistance = 0xffffffff;
 
                         for ( a = 0; a < aPolyPoly.Count(); a++ )
                         {
@@ -4610,6 +4632,7 @@ sal_uInt32 EscherConnectorListEntry::GetConnectorRule( bool bFirst )
                                 nIndex++;
                             }
                         }
+
                         if ( nDistance != 0xffffffff )
                             bRectangularConnection = false;
                     }
diff --git a/filter/source/msfilter/msdffimp.cxx b/filter/source/msfilter/msdffimp.cxx
index 960fa7f1ed2d..3bb84733aedf 100644
--- a/filter/source/msfilter/msdffimp.cxx
+++ b/filter/source/msfilter/msdffimp.cxx
@@ -4709,7 +4709,7 @@ SdrObject* SvxMSDffManager::ImportShape( const DffRecordHeader& rHd, SvStream& r
                         static_cast<SdrObjCustomShape*>(pRet)->MergeDefaultAttributes();
 
                     pRet->SetSnapRect( aObjData.aBoundRect );
-                    EnhancedCustomShape2d aCustomShape2d( pRet );
+                    EnhancedCustomShape2d aCustomShape2d(static_cast<SdrObjCustomShape&>(*pRet));
                     aTextRect = aCustomShape2d.GetTextRect();
 
                     if( bIsConnector )
diff --git a/include/filter/msfilter/escherex.hxx b/include/filter/msfilter/escherex.hxx
index d9f83294b5a7..58d492402ac2 100644
--- a/include/filter/msfilter/escherex.hxx
+++ b/include/filter/msfilter/escherex.hxx
@@ -848,7 +848,11 @@ public:
                             sal_Int32& rnArrowLength,
                             sal_Int32& rnArrowWidth
                         );
-    static bool         IsDefaultObject( SdrObjCustomShape const * pCustoShape, const MSO_SPT eShapeType );
+
+    static bool IsDefaultObject(
+        const SdrObjCustomShape& rSdrObjCustomShape,
+        const MSO_SPT eShapeType);
+
     static void         LookForPolarHandles(
                             const MSO_SPT eShapeType,
                             sal_Int32& nAdjustmentsWhichNeedsToBeConverted
diff --git a/include/oox/export/drawingml.hxx b/include/oox/export/drawingml.hxx
index aa99c95c82e3..597874778bde 100644
--- a/include/oox/export/drawingml.hxx
+++ b/include/oox/export/drawingml.hxx
@@ -235,9 +235,15 @@ public:
     void WritePresetShape( const char* pShape , std::vector< std::pair<sal_Int32,sal_Int32>> & rAvList );
     void WritePresetShape( const char* pShape );
     void WritePresetShape( const char* pShape, MSO_SPT eShapeType, bool bPredefinedHandlesUsed, sal_Int32 nAdjustmentsWhichNeedsToBeConverted, const css::beans::PropertyValue& rProp );
-    bool WriteCustomGeometry( const css::uno::Reference<css::drawing::XShape>& rXShape, const SdrObjCustomShape* pShape );
-    void WriteCustomGeometryPoint(const css::drawing::EnhancedCustomShapeParameterPair& rParamPair, const SdrObjCustomShape* pShape);
-    static sal_Int32 GetCustomGeometryPointValue(const css::drawing::EnhancedCustomShapeParameter& rParam, const SdrObjCustomShape* pShape);
+    bool WriteCustomGeometry(
+        const css::uno::Reference<css::drawing::XShape>& rXShape,
+        const SdrObjCustomShape& rSdrObjCustomShape);
+    void WriteCustomGeometryPoint(
+        const css::drawing::EnhancedCustomShapeParameterPair& rParamPair,
+        const SdrObjCustomShape& rSdrObjCustomShape);
+    static sal_Int32 GetCustomGeometryPointValue(
+        const css::drawing::EnhancedCustomShapeParameter& rParam,
+        const SdrObjCustomShape& rSdrObjCustomShape);
     void WritePolyPolygon( const tools::PolyPolygon& rPolyPolygon );
     void WriteFill( const css::uno::Reference< css::beans::XPropertySet >& xPropSet );
     void WriteShapeStyle( const css::uno::Reference< css::beans::XPropertySet >& rXPropSet );
diff --git a/include/svx/EnhancedCustomShape2d.hxx b/include/svx/EnhancedCustomShape2d.hxx
index 074ecfa0a124..8eb5021b3bad 100644
--- a/include/svx/EnhancedCustomShape2d.hxx
+++ b/include/svx/EnhancedCustomShape2d.hxx
@@ -72,7 +72,7 @@ namespace o3tl
 
 class SVX_DLLPUBLIC EnhancedCustomShape2d : public SfxItemSet
 {
-        SdrObject*                  pCustomShapeObj;
+        SdrObjCustomShape&          mrSdrObjCustomShape;
         MSO_SPT                     eSpType;
 
         sal_Int32                   nCoordLeft;
@@ -189,7 +189,7 @@ class SVX_DLLPUBLIC EnhancedCustomShape2d : public SfxItemSet
         bool                    GetHandlePosition( const sal_uInt32 nIndex, Point& rReturnPosition ) const;
         bool                    SetHandleControllerPosition( const sal_uInt32 nIndex, const css::awt::Point& rPosition );
 
-        EnhancedCustomShape2d( SdrObject* pSdrObjCustomShape );
+        EnhancedCustomShape2d(SdrObjCustomShape& rSdrObjCustomShape);
         virtual ~EnhancedCustomShape2d() override;
 
         SAL_DLLPRIVATE double   GetEnumFunc( const EnhancedCustomShape::ExpressionFunct eVal ) const;
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index 931f77e91a31..bf10bf23febc 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -2601,7 +2601,9 @@ void DrawingML::WritePresetShape( const char* pShape, MSO_SPT eShapeType, bool b
     mpFS->endElementNS(  XML_a, XML_prstGeom );
 }
 
-bool DrawingML::WriteCustomGeometry( const Reference< XShape >& rXShape, const SdrObjCustomShape* pShape )
+bool DrawingML::WriteCustomGeometry(
+    const Reference< XShape >& rXShape,
+    const SdrObjCustomShape& rSdrObjCustomShape)
 {
     uno::Reference< beans::XPropertySet > aXPropSet;
     uno::Any aAny( rXShape->queryInterface(cppu::UnoType<beans::XPropertySet>::get()));
@@ -2701,8 +2703,8 @@ bool DrawingML::WriteCustomGeometry( const Reference< XShape >& rXShape, const S
 
                     for ( int j = 0; j < aPairs.getLength(); ++j )
                     {
-                        sal_Int32 nX = GetCustomGeometryPointValue(aPairs[j].First, pShape);
-                        sal_Int32 nY = GetCustomGeometryPointValue(aPairs[j].Second, pShape);
+                        sal_Int32 nX = GetCustomGeometryPointValue(aPairs[j].First, rSdrObjCustomShape);
+                        sal_Int32 nY = GetCustomGeometryPointValue(aPairs[j].Second, rSdrObjCustomShape);
                         if (nX < nXMin)
                             nXMin = nX;
                         if (nY < nYMin)
@@ -2733,7 +2735,7 @@ bool DrawingML::WriteCustomGeometry( const Reference< XShape >& rXShape, const S
                             case drawing::EnhancedCustomShapeSegmentCommand::MOVETO :
                             {
                                 mpFS->startElementNS( XML_a, XML_moveTo, FSEND );
-                                WriteCustomGeometryPoint(aPairs[nPairIndex], pShape);
+                                WriteCustomGeometryPoint(aPairs[nPairIndex], rSdrObjCustomShape);
                                 mpFS->endElementNS( XML_a, XML_moveTo );
                                 nPairIndex++;
                                 break;
@@ -2741,7 +2743,7 @@ bool DrawingML::WriteCustomGeometry( const Reference< XShape >& rXShape, const S
                             case drawing::EnhancedCustomShapeSegmentCommand::LINETO :
                             {
                                 mpFS->startElementNS( XML_a, XML_lnTo, FSEND );
-                                WriteCustomGeometryPoint(aPairs[nPairIndex], pShape);
+                                WriteCustomGeometryPoint(aPairs[nPairIndex], rSdrObjCustomShape);
                                 mpFS->endElementNS( XML_a, XML_lnTo );
                                 nPairIndex++;
                                 break;
@@ -2751,7 +2753,7 @@ bool DrawingML::WriteCustomGeometry( const Reference< XShape >& rXShape, const S
                                 mpFS->startElementNS( XML_a, XML_cubicBezTo, FSEND );
                                 for( sal_uInt8 l = 0; l <= 2; ++l )
                                 {
-                                    WriteCustomGeometryPoint(aPairs[nPairIndex+l], pShape);
+                                    WriteCustomGeometryPoint(aPairs[nPairIndex+l], rSdrObjCustomShape);
                                 }
                                 mpFS->endElementNS( XML_a, XML_cubicBezTo );
                                 nPairIndex += 3;
@@ -2782,7 +2784,7 @@ bool DrawingML::WriteCustomGeometry( const Reference< XShape >& rXShape, const S
                                 mpFS->startElementNS( XML_a, XML_quadBezTo, FSEND );
                                 for( sal_uInt8 l = 0; l < 2; ++l )
                                 {
-                                    WriteCustomGeometryPoint(aPairs[nPairIndex+l], pShape);
+                                    WriteCustomGeometryPoint(aPairs[nPairIndex+l], rSdrObjCustomShape);
                                 }
                                 mpFS->endElementNS( XML_a, XML_quadBezTo );
                                 nPairIndex += 2;
@@ -2809,10 +2811,12 @@ bool DrawingML::WriteCustomGeometry( const Reference< XShape >& rXShape, const S
     return false;
 }
 
-void DrawingML::WriteCustomGeometryPoint(const drawing::EnhancedCustomShapeParameterPair& rParamPair, const SdrObjCustomShape* pShape)
+void DrawingML::WriteCustomGeometryPoint(
+    const drawing::EnhancedCustomShapeParameterPair& rParamPair,
+    const SdrObjCustomShape& rSdrObjCustomShape)
 {
-    sal_Int32 nX = GetCustomGeometryPointValue(rParamPair.First, pShape);
-    sal_Int32 nY = GetCustomGeometryPointValue(rParamPair.Second, pShape);
+    sal_Int32 nX = GetCustomGeometryPointValue(rParamPair.First, rSdrObjCustomShape);
+    sal_Int32 nY = GetCustomGeometryPointValue(rParamPair.Second, rSdrObjCustomShape);
 
     mpFS->singleElementNS( XML_a, XML_pt,
         XML_x, OString::number(nX).getStr(),
@@ -2820,18 +2824,15 @@ void DrawingML::WriteCustomGeometryPoint(const drawing::EnhancedCustomShapeParam
         FSEND );
 }
 
-sal_Int32 DrawingML::GetCustomGeometryPointValue(const css::drawing::EnhancedCustomShapeParameter& rParam, const SdrObjCustomShape* pShape)
+sal_Int32 DrawingML::GetCustomGeometryPointValue(
+    const css::drawing::EnhancedCustomShapeParameter& rParam,
+    const SdrObjCustomShape& rSdrObjCustomShape)
 {
-    sal_Int32 nValue = 0;
-    if(pShape)
-    {
-        const EnhancedCustomShape2d aCustoShape2d (const_cast<SdrObjCustomShape*>(pShape));
-        double fValue = 0.0;
-        aCustoShape2d.GetParameter(fValue, rParam, false, false);
-        nValue = std::lround(fValue);
-    }
-    else
-        rParam.Value >>= nValue;
+    const EnhancedCustomShape2d aCustoShape2d(const_cast< SdrObjCustomShape& >(rSdrObjCustomShape));
+    double fValue = 0.0;
+    aCustoShape2d.GetParameter(fValue, rParam, false, false);
+    sal_Int32 nValue(std::lround(fValue));
+
     return nValue;
 }
 
diff --git a/oox/source/export/shapes.cxx b/oox/source/export/shapes.cxx
index 97e1368f4368..c52c6a62b3cb 100644
--- a/oox/source/export/shapes.cxx
+++ b/oox/source/export/shapes.cxx
@@ -729,8 +729,12 @@ ShapeExport& ShapeExport::WriteCustomShape( const Reference< XShape >& xShape )
     OUString sShapeType;
     ShapeFlag nMirrorFlags = ShapeFlag::NONE;
     MSO_SPT eShapeType = EscherPropertyContainer::GetCustomShapeType( xShape, nMirrorFlags, sShapeType );
-    SdrObjCustomShape* pShape = static_cast<SdrObjCustomShape*>( GetSdrObjectFromXShape( xShape ) );
-    bool bIsDefaultObject = EscherPropertyContainer::IsDefaultObject( pShape, eShapeType );
+    OSL_ENSURE(nullptr != dynamic_cast< SdrObjCustomShape* >(GetSdrObjectFromXShape(xShape)), "Not a SdrObjCustomShape (!)");
+    SdrObjCustomShape& rSdrObjCustomShape(static_cast< SdrObjCustomShape& >(*GetSdrObjectFromXShape(xShape)));
+    const bool bIsDefaultObject(
+        EscherPropertyContainer::IsDefaultObject(
+            rSdrObjCustomShape,
+            eShapeType));
     const char* sPresetShape = msfilter::util::GetOOXMLPresetGeometry( USS( sShapeType ) );
     SAL_INFO("oox.shape", "custom shape type: " << sShapeType << " ==> " << sPresetShape);
     Sequence< PropertyValue > aGeometrySeq;
@@ -845,10 +849,10 @@ ShapeExport& ShapeExport::WriteCustomShape( const Reference< XShape >& xShape )
     else if( bHasHandles )
         bCustGeom = true;
 
-    if (bHasHandles && bCustGeom && pShape)
+    if (bHasHandles && bCustGeom)
     {
         WriteShapeTransformation( xShape, XML_a, bFlipH, bFlipV, false, true );// do not flip, polypolygon coordinates are flipped already
-        tools::PolyPolygon aPolyPolygon( pShape->GetLineGeometry(true) );
+        tools::PolyPolygon aPolyPolygon( rSdrObjCustomShape.GetLineGeometry(true) );
         sal_Int32 nRotation = 0;
         // The RotateAngle property's value is independent from any flipping, and that's exactly what we need here.
         uno::Reference<beans::XPropertySet> xPropertySet(xShape, uno::UNO_QUERY);
@@ -864,7 +868,7 @@ ShapeExport& ShapeExport::WriteCustomShape( const Reference< XShape >& xShape )
     else if (bCustGeom)
     {
         WriteShapeTransformation( xShape, XML_a, bFlipH, bFlipV );
-        bool bSuccess = WriteCustomGeometry( xShape, pShape );
+        bool bSuccess = WriteCustomGeometry(xShape, rSdrObjCustomShape);
         if (!bSuccess)
             WritePresetShape( sPresetShape );
     }
diff --git a/svx/source/customshapes/EnhancedCustomShape2d.cxx b/svx/source/customshapes/EnhancedCustomShape2d.cxx
index 39d694b112a8..17fe098ff3fe 100644
--- a/svx/source/customshapes/EnhancedCustomShape2d.cxx
+++ b/svx/source/customshapes/EnhancedCustomShape2d.cxx
@@ -690,9 +690,9 @@ void EnhancedCustomShape2d::SetPathSize( sal_Int32 nIndex )
         fYRatio = 1.0;
 }
 
-EnhancedCustomShape2d::EnhancedCustomShape2d( SdrObject* pAObj ) :
-    SfxItemSet          ( pAObj->GetMergedItemSet() ),
-    pCustomShapeObj     ( pAObj ),
+EnhancedCustomShape2d::EnhancedCustomShape2d(SdrObjCustomShape& rSdrObjCustomShape)
+:   SfxItemSet          ( rSdrObjCustomShape.GetMergedItemSet() ),
+    mrSdrObjCustomShape ( rSdrObjCustomShape ),
     eSpType             ( mso_sptNil ),
     nCoordLeft          ( 0 ),
     nCoordTop           ( 0 ),
@@ -702,8 +702,8 @@ EnhancedCustomShape2d::EnhancedCustomShape2d( SdrObject* pAObj ) :
     nXRef               ( 0x80000000 ),
     nYRef               ( 0x80000000 ),
     nColorData          ( 0 ),
-    bFilled             ( pAObj->GetMergedItem( XATTR_FILLSTYLE ).GetValue() != drawing::FillStyle_NONE ),
-    bStroked            ( pAObj->GetMergedItem( XATTR_LINESTYLE ).GetValue() != drawing::LineStyle_NONE ),
+    bFilled             ( rSdrObjCustomShape.GetMergedItem( XATTR_FILLSTYLE ).GetValue() != drawing::FillStyle_NONE ),
+    bStroked            ( rSdrObjCustomShape.GetMergedItem( XATTR_LINESTYLE ).GetValue() != drawing::LineStyle_NONE ),
     bFlipH              ( false ),
     bFlipV              ( false )
 {
@@ -723,14 +723,14 @@ EnhancedCustomShape2d::EnhancedCustomShape2d( SdrObject* pAObj ) :
     // 2D helper shape.
     ClearItem(SDRATTR_SHADOW);
 
-    Point aP( pCustomShapeObj->GetSnapRect().Center() );
-    Size aS( pCustomShapeObj->GetLogicRect().GetSize() );
+    Point aP( mrSdrObjCustomShape.GetSnapRect().Center() );
+    Size aS( mrSdrObjCustomShape.GetLogicRect().GetSize() );
     aP.AdjustX( -(aS.Width() / 2) );
     aP.AdjustY( -(aS.Height() / 2) );
     aLogicRect = tools::Rectangle( aP, aS );
 
     OUString sShapeType;
-    const SdrCustomShapeGeometryItem& rGeometryItem = pCustomShapeObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
+    const SdrCustomShapeGeometryItem& rGeometryItem(mrSdrObjCustomShape.GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ));
     const Any* pAny = rGeometryItem.GetPropertyValueByName( "Type" );
     if ( pAny ) {
         *pAny >>= sShapeType;
@@ -746,10 +746,7 @@ EnhancedCustomShape2d::EnhancedCustomShape2d( SdrObject* pAObj ) :
     if ( pAny )
         *pAny >>= bFlipV;
 
-    if ( dynamic_cast<const SdrObjCustomShape*>( pCustomShapeObj) !=  nullptr )    // should always be a SdrObjCustomShape, but you don't know
-        nRotateAngle = static_cast<sal_Int32>(static_cast<SdrObjCustomShape*>(pCustomShapeObj)->GetObjectRotation() * 100.0);
-    else
-         nRotateAngle = pCustomShapeObj->GetRotateAngle();
+    nRotateAngle = static_cast<sal_Int32>(static_cast< SdrObjCustomShape& >(mrSdrObjCustomShape).GetObjectRotation() * 100.0);
 
     /*const sal_Int32* pDefData =*/ ApplyShapeAttributes( rGeometryItem );
     SetPathSize();
@@ -1170,7 +1167,7 @@ bool EnhancedCustomShape2d::GetHandlePosition( const sal_uInt32 nIndex, Point& r
                 }
                 rReturnPosition = GetPoint( aHandle.aPosition );
             }
-            const GeoStat aGeoStat( static_cast<SdrObjCustomShape*>(pCustomShapeObj)->GetGeoStat() );
+            const GeoStat aGeoStat(mrSdrObjCustomShape.GetGeoStat());
             if ( aGeoStat.nShearAngle )
             {
                 double nTan = aGeoStat.nTan;
@@ -1215,7 +1212,7 @@ bool EnhancedCustomShape2d::SetHandleControllerPosition( const sal_uInt32 nIndex
                 double a = -nRotateAngle * F_PI18000;
                 RotatePoint( aP, Point( aLogicRect.GetWidth() / 2, aLogicRect.GetHeight() / 2 ), sin( a ), cos( a ) );
             }
-            const GeoStat aGeoStat( static_cast<SdrObjCustomShape*>(pCustomShapeObj)->GetGeoStat() );
+            const GeoStat aGeoStat(mrSdrObjCustomShape.GetGeoStat());
             if ( aGeoStat.nShearAngle )
             {
                 double nTan = -aGeoStat.nTan;
@@ -1372,13 +1369,12 @@ bool EnhancedCustomShape2d::SetHandleControllerPosition( const sal_uInt32 nIndex
                 }
             }
             // and writing them back into the GeometryItem
-            SdrCustomShapeGeometryItem aGeometryItem(
-                pCustomShapeObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ));
+            SdrCustomShapeGeometryItem aGeometryItem(mrSdrObjCustomShape.GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ));
             css::beans::PropertyValue aPropVal;
             aPropVal.Name = "AdjustmentValues";
             aPropVal.Value <<= seqAdjustmentValues;
             aGeometryItem.SetPropertyValue( aPropVal );
-            pCustomShapeObj->SetMergedItem( aGeometryItem );
+            mrSdrObjCustomShape.SetMergedItem( aGeometryItem );
             bRetValue = true;
         }
     }
@@ -1610,7 +1606,7 @@ void EnhancedCustomShape2d::CreateSubPath(
                             bIsDefaultPath = true;
 
                         OUString sShpType;
-                        SdrCustomShapeGeometryItem& rGeometryItem = const_cast<SdrCustomShapeGeometryItem&>(pCustomShapeObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ));
+                        SdrCustomShapeGeometryItem& rGeometryItem = const_cast<SdrCustomShapeGeometryItem&>(mrSdrObjCustomShape.GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ));
                         Any* pAny = rGeometryItem.GetPropertyValueByName( "Type" );
                         if ( pAny )
                             *pAny >>= sShpType;
@@ -1642,7 +1638,7 @@ void EnhancedCustomShape2d::CreateSubPath(
                             aPropVal.Name = "ViewBox";
                             aPropVal.Value <<= aViewBox;
                             rGeometryItem.SetPropertyValue( aPropVal );
-                            pCustomShapeObj->SetMergedItem( rGeometryItem );
+                            mrSdrObjCustomShape.SetMergedItem( rGeometryItem );
                         }else{
                             _aCenter = GetPoint( seqCoordinates[ rSrcPt ], true, true );
                             GetParameter( fWidth,  seqCoordinates[ rSrcPt + 1 ].First, true, false);
@@ -2257,7 +2253,7 @@ SdrObject* EnhancedCustomShape2d::CreatePathObj( bool bLineGeometryNeededOnly )
 
     if ( !vObjectList.empty() )
     {
-        const SfxItemSet& rCustomShapeSet(pCustomShapeObj->GetMergedItemSet());
+        const SfxItemSet& rCustomShapeSet(mrSdrObjCustomShape.GetMergedItemSet());
         const sal_uInt32 nColorCount(nColorData >> 28);
         sal_uInt32 nColorIndex(0);
 
@@ -2325,10 +2321,7 @@ SdrObject* EnhancedCustomShape2d::CreatePathObj( bool bLineGeometryNeededOnly )
                     // to define that all helper geometites defined here (SdrObjects currently)
                     // will use the same FillGeometryDefinition (from the referenced SdrObjCustomShape).
                     // This will all same-filled objects look like filled smoothly with the same style.
-                    if(pCustomShapeObj)
-                    {
-                        pObj->setFillGeometryDefiningShape(pCustomShapeObj);
-                    }
+                    pObj->setFillGeometryDefiningShape(&mrSdrObjCustomShape);
                 }
             }
 
diff --git a/svx/source/customshapes/EnhancedCustomShape3d.cxx b/svx/source/customshapes/EnhancedCustomShape3d.cxx
index 820430b83435..60177fc9fbe8 100644
--- a/svx/source/customshapes/EnhancedCustomShape3d.cxx
+++ b/svx/source/customshapes/EnhancedCustomShape3d.cxx
@@ -175,8 +175,10 @@ drawing::Direction3D GetDirection3D( const SdrCustomShapeGeometryItem& rItem, co
 
 }
 
-EnhancedCustomShape3d::Transformation2D::Transformation2D( const SdrObject* pCustomShape, const double *pM )
-    : aCenter( pCustomShape->GetSnapRect().Center() )
+EnhancedCustomShape3d::Transformation2D::Transformation2D(
+    const SdrObjCustomShape& rSdrObjCustomShape,
+    const double *pM)
+:   aCenter(rSdrObjCustomShape.GetSnapRect().Center())
     , eProjectionMode( drawing::ProjectionMode_PARALLEL )
     , fSkewAngle(0.0)
     , fSkew(0.0)
@@ -185,7 +187,7 @@ EnhancedCustomShape3d::Transformation2D::Transformation2D( const SdrObject* pCus
     , fOriginY(0.0)
     , pMap( pM )
 {
-    const SdrCustomShapeGeometryItem& rGeometryItem = pCustomShape->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
+    const SdrCustomShapeGeometryItem& rGeometryItem(rSdrObjCustomShape.GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ));
     const Any* pAny = rGeometryItem.GetPropertyValueByName( "Extrusion", "ProjectionMode" );
     if ( pAny )
         *pAny >>= eProjectionMode;
@@ -195,8 +197,8 @@ EnhancedCustomShape3d::Transformation2D::Transformation2D( const SdrObject* pCus
     else
     {
         GetOrigin( rGeometryItem, fOriginX, fOriginY );
-        fOriginX = fOriginX * pCustomShape->GetLogicRect().GetWidth();
-        fOriginY = fOriginY * pCustomShape->GetLogicRect().GetHeight();
+        fOriginX = fOriginX * rSdrObjCustomShape.GetLogicRect().GetWidth();
+        fOriginY = fOriginY * rSdrObjCustomShape.GetLogicRect().GetHeight();
 
         drawing::Position3D aViewPointDefault( 3472, -3472, 25000 );
         drawing::Position3D aViewPoint( GetPosition3D( rGeometryItem, "ViewPoint", aViewPointDefault, pMap ) );
@@ -249,11 +251,13 @@ bool EnhancedCustomShape3d::Transformation2D::IsParallel() const
     return eProjectionMode == css::drawing::ProjectionMode_PARALLEL;
 }
 
-SdrObject* EnhancedCustomShape3d::Create3DObject( const SdrObject* pShape2d, const SdrObject* pCustomShape )
+SdrObject* EnhancedCustomShape3d::Create3DObject(
+    const SdrObject* pShape2d,
+    const SdrObjCustomShape& rSdrObjCustomShape)
 {
     SdrObject*  pRet = nullptr;
-    SdrModel*   pModel = pCustomShape->GetModel();
-    const SdrCustomShapeGeometryItem& rGeometryItem = pCustomShape->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
+    SdrModel*   pModel = rSdrObjCustomShape.GetModel();
+    const SdrCustomShapeGeometryItem& rGeometryItem = rSdrObjCustomShape.GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
 
     double      fMap, *pMap = nullptr;
     if ( pModel )
@@ -274,17 +278,17 @@ SdrObject* EnhancedCustomShape3d::Create3DObject( const SdrObject* pShape2d, con
     }
     if ( GetBool( rGeometryItem, "Extrusion", false ) )
     {
-        bool bIsMirroredX = static_cast<const SdrObjCustomShape*>(pCustomShape)->IsMirroredX();
-        bool bIsMirroredY = static_cast<const SdrObjCustomShape*>(pCustomShape)->IsMirroredY();
-        tools::Rectangle aSnapRect( pCustomShape->GetLogicRect() );
-        long nObjectRotation = pCustomShape->GetRotateAngle();
+        bool bIsMirroredX(rSdrObjCustomShape.IsMirroredX());
+        bool bIsMirroredY(rSdrObjCustomShape.IsMirroredY());
+        tools::Rectangle aSnapRect(rSdrObjCustomShape.GetLogicRect());
+        long nObjectRotation(rSdrObjCustomShape.GetRotateAngle());
         if ( nObjectRotation )
         {
             double a = ( 36000 - nObjectRotation ) * nPi180;
             long dx = aSnapRect.Right() - aSnapRect.Left();
             long dy = aSnapRect.Bottom()- aSnapRect.Top();
             Point aP( aSnapRect.TopLeft() );
-            RotatePoint( aP, pCustomShape->GetSnapRect().Center(), sin( a ), cos( a ) );
+            RotatePoint( aP, rSdrObjCustomShape.GetSnapRect().Center(), sin( a ), cos( a ) );
             aSnapRect.SetLeft( aP.X() );
             aSnapRect.SetTop( aP.Y() );
             aSnapRect.SetRight( aSnapRect.Left() + dx );
@@ -292,7 +296,7 @@ SdrObject* EnhancedCustomShape3d::Create3DObject( const SdrObject* pShape2d, con
         }
         Point aCenter( aSnapRect.Center() );
 
-        SfxItemSet aSet( pCustomShape->GetMergedItemSet() );
+        SfxItemSet aSet( rSdrObjCustomShape.GetMergedItemSet() );
 
         //SJ: vertical writing is not required, by removing this item no outliner is created
         aSet.ClearItem( SDRATTR_TEXTDIRECTION );
@@ -530,7 +534,7 @@ SdrObject* EnhancedCustomShape3d::Create3DObject( const SdrObject* pShape2d, con
                     p3DObj->NbcSetLayer( pShape2d->GetLayer() );
                     p3DObj->SetMergedItemSet( aLocalSet );
                     if ( bUseExtrusionColor )
-                        p3DObj->SetMergedItem( XFillColorItem( "", pCustomShape->GetMergedItem( XATTR_SECONDARYFILLCOLOR ).GetColorValue() ) );
+                        p3DObj->SetMergedItem( XFillColorItem( "", rSdrObjCustomShape.GetMergedItem( XATTR_SECONDARYFILLCOLOR ).GetColorValue() ) );
                     p3DObj->SetMergedItem( XFillStyleItem( drawing::FillStyle_SOLID ) );
                     p3DObj->SetMergedItem( Svx3DCloseFrontItem( false ) );
                     p3DObj->SetMergedItem( Svx3DCloseBackItem( false ) );
@@ -599,7 +603,7 @@ SdrObject* EnhancedCustomShape3d::Create3DObject( const SdrObject* pShape2d, con
 
             double fXRotate, fYRotate;
             GetRotateAngle( rGeometryItem, fXRotate, fYRotate );
-            double fZRotate = static_cast<const SdrObjCustomShape*>(pCustomShape)->GetObjectRotation() * F_PI180;
+            double fZRotate(rSdrObjCustomShape.GetObjectRotation() * F_PI180);
             if ( fZRotate != 0.0 )
                 aNewTransform.rotate( 0.0, 0.0, fZRotate );
             if ( bIsMirroredX )
@@ -717,7 +721,12 @@ SdrObject* EnhancedCustomShape3d::Create3DObject( const SdrObject* pShape2d, con
             pScene->GetProperties().SetObjectItem( makeSvx3DMaterialSpecularItem( aSpecularCol ) );
             pScene->GetProperties().SetObjectItem( makeSvx3DMaterialSpecularIntensityItem( static_cast<sal_uInt16>(nIntensity) ) );
 
-            pScene->SetLogicRect( CalculateNewSnapRect( pCustomShape, aSnapRect, aBoundRect2d, pMap ) );
+            pScene->SetLogicRect(
+                CalculateNewSnapRect(
+                    rSdrObjCustomShape,
+                    aSnapRect,
+                    aBoundRect2d,
+                    pMap));
 
             // removing placeholder objects
             for (std::vector< E3dCompoundObject* >::iterator aObjectListIter( aPlaceholderObjectList.begin() ); aObjectListIter != aPlaceholderObjectList.end(); )
@@ -732,9 +741,13 @@ SdrObject* EnhancedCustomShape3d::Create3DObject( const SdrObject* pShape2d, con
     return pRet;
 }
 
-tools::Rectangle EnhancedCustomShape3d::CalculateNewSnapRect( const SdrObject* pCustomShape, const tools::Rectangle& rSnapRect, const tools::Rectangle& rBoundRect, const double* pMap )
+tools::Rectangle EnhancedCustomShape3d::CalculateNewSnapRect(
+    const SdrObjCustomShape& rSdrObjCustomShape,
+    const tools::Rectangle& rSnapRect,
+    const tools::Rectangle& rBoundRect,
+    const double* pMap)
 {
-    const SdrCustomShapeGeometryItem& rGeometryItem = pCustomShape->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
+    const SdrCustomShapeGeometryItem& rGeometryItem(rSdrObjCustomShape.GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ));
     const Point aCenter( rSnapRect.Center() );
     double fExtrusionBackward, fExtrusionForward;
     GetExtrusionDepth( rGeometryItem, pMap, fExtrusionBackward, fExtrusionForward );
@@ -759,16 +772,16 @@ tools::Rectangle EnhancedCustomShape3d::CalculateNewSnapRect( const SdrObject* p
 
     double fXRotate, fYRotate;
     GetRotateAngle( rGeometryItem, fXRotate, fYRotate );
-    double fZRotate = - static_cast<const SdrObjCustomShape*>(pCustomShape)->GetObjectRotation() * F_PI180;
+    double fZRotate(rSdrObjCustomShape.GetObjectRotation() * F_PI180);
 
     // rotating bound volume
     basegfx::B3DHomMatrix aMatrix;
     aMatrix.translate(-aRotationCenter.DirectionX, -aRotationCenter.DirectionY, -aRotationCenter.DirectionZ);
     if ( fZRotate != 0.0 )
         aMatrix.rotate( 0.0, 0.0, fZRotate );
-    if ( static_cast<const SdrObjCustomShape*>(pCustomShape)->IsMirroredX() )
+    if (rSdrObjCustomShape.IsMirroredX())
         aMatrix.scale( -1.0, 1, 1 );
-    if ( static_cast<const SdrObjCustomShape*>(pCustomShape)->IsMirroredY() )
+    if (rSdrObjCustomShape.IsMirroredY())
         aMatrix.scale( 1, -1.0, 1 );
     if( fYRotate != 0.0 )
         aMatrix.rotate( 0.0, fYRotate, 0.0 );
@@ -777,7 +790,10 @@ tools::Rectangle EnhancedCustomShape3d::CalculateNewSnapRect( const SdrObject* p
     aMatrix.translate(aRotationCenter.DirectionX, aRotationCenter.DirectionY, aRotationCenter.DirectionZ);
     aBoundVolume.transform(aMatrix);
 
-    Transformation2D aTransformation2D( pCustomShape, pMap );
+    Transformation2D aTransformation2D(
+        rSdrObjCustomShape,
+        pMap);
+
     if ( aTransformation2D.IsParallel() )
         aBoundVolume = aTransformation2D.ApplySkewSettings( aBoundVolume );
 
diff --git a/svx/source/customshapes/EnhancedCustomShape3d.hxx b/svx/source/customshapes/EnhancedCustomShape3d.hxx
index 011d92ccc639..1c8290846b12 100644
--- a/svx/source/customshapes/EnhancedCustomShape3d.hxx
+++ b/svx/source/customshapes/EnhancedCustomShape3d.hxx
@@ -49,8 +49,9 @@ class EnhancedCustomShape3d final
         const double* pMap;
 
         public:
-
-                        Transformation2D( const SdrObject* pCustomShape, const double* pMap );
+            Transformation2D(
+                const SdrObjCustomShape& rSdrObjCustomShape,
+                const double* pMap);
 
             basegfx::B3DPolygon ApplySkewSettings( const basegfx::B3DPolygon& rPolygon3D ) const;
             Point       Transform2D( const basegfx::B3DPoint& rPoint ) const;
@@ -59,10 +60,16 @@ class EnhancedCustomShape3d final
 
     friend class Transformation2D;
 
-    static tools::Rectangle CalculateNewSnapRect( const SdrObject* pCustomShape, const tools::Rectangle& rSnapRect, const tools::Rectangle& rBoundRect, const double* pMap );
+    static tools::Rectangle CalculateNewSnapRect(
+        const SdrObjCustomShape& rSdrObjCustomShape,
+        const tools::Rectangle& rSnapRect,
+        const tools::Rectangle& rBoundRect,
+        const double* pMap);
 
 public:
-    static SdrObject* Create3DObject( const SdrObject* pShape2d, const SdrObject* pCustomShape );
+    static SdrObject* Create3DObject(
+        const SdrObject* pShape2d,
+        const SdrObjCustomShape& rSdrObjCustomShape);
 };
 
 #endif
diff --git a/svx/source/customshapes/EnhancedCustomShapeEngine.cxx b/svx/source/customshapes/EnhancedCustomShapeEngine.cxx
index 30e7be880d3e..899ea6e03c26 100644
--- a/svx/source/customshapes/EnhancedCustomShapeEngine.cxx
+++ b/svx/source/customshapes/EnhancedCustomShapeEngine.cxx
@@ -72,7 +72,9 @@ class EnhancedCustomShapeEngine : public cppu::WeakImplHelper
     css::uno::Reference< css::drawing::XShape >      mxShape;
     bool                                    mbForceGroupWithText;
 
-    SdrObject* ImplForceGroupWithText( const SdrObjCustomShape* pCustoObj, SdrObject* pRenderedShape );
+    SdrObject* ImplForceGroupWithText(
+        const SdrObjCustomShape& rSdrObjCustomShape,
+        SdrObject* pRenderedShape);
 
 public:
                             EnhancedCustomShapeEngine();
@@ -147,13 +149,17 @@ Sequence< OUString > SAL_CALL EnhancedCustomShapeEngine::getSupportedServiceName
 }
 
 // XCustomShapeEngine
-SdrObject* EnhancedCustomShapeEngine::ImplForceGroupWithText( const SdrObjCustomShape* pCustoObj, SdrObject* pRenderedShape )
+SdrObject* EnhancedCustomShapeEngine::ImplForceGroupWithText(
+    const SdrObjCustomShape& rSdrObjCustomShape,
+    SdrObject* pRenderedShape)
 {
-    bool bHasText = pCustoObj->HasText();
+    const bool bHasText(rSdrObjCustomShape.HasText());
+
     if ( pRenderedShape || bHasText )
     {
         // applying shadow
-        const SdrObject* pShadowGeometry = pCustoObj->GetSdrObjectShadowFromCustomShape();
+        const SdrObject* pShadowGeometry(rSdrObjCustomShape.GetSdrObjectShadowFromCustomShape());
+
         if ( pShadowGeometry )
         {
             if ( pRenderedShape )
@@ -175,37 +181,48 @@ SdrObject* EnhancedCustomShapeEngine::ImplForceGroupWithText( const SdrObjCustom
         {
             // #i37011# also create a text object and add at rPos + 1
             SdrObject* pTextObj = SdrObjFactory::MakeNewObject(
-                pCustoObj->GetObjInventor(), OBJ_TEXT, nullptr, pCustoObj->GetModel());
+                rSdrObjCustomShape.GetObjInventor(),
+                OBJ_TEXT,
+                nullptr,
+                rSdrObjCustomShape.GetModel());
 
             // Copy text content
-            OutlinerParaObject* pParaObj = pCustoObj->GetOutlinerParaObject();
+            OutlinerParaObject* pParaObj(rSdrObjCustomShape.GetOutlinerParaObject());
+
             if( pParaObj )
                 pTextObj->NbcSetOutlinerParaObject( new OutlinerParaObject(*pParaObj) );
 
             // copy all attributes
-            SfxItemSet aTargetItemSet( pCustoObj->GetMergedItemSet() );
+            SfxItemSet aTargetItemSet(rSdrObjCustomShape.GetMergedItemSet());
 
             // clear fill and line style
             aTargetItemSet.Put(XLineStyleItem(drawing::LineStyle_NONE));
             aTargetItemSet.Put(XFillStyleItem(drawing::FillStyle_NONE));
 
             // get the text bounds and set at text object
-            tools::Rectangle aTextBounds = pCustoObj->GetSnapRect();
-            SdrObject* pSdrObjCustomShape( GetSdrObjectFromXShape( mxShape ) );
-            if ( pSdrObjCustomShape )
+            tools::Rectangle aTextBounds(rSdrObjCustomShape.GetSnapRect());
+            const bool bIsSdrObjCustomShape(nullptr != dynamic_cast< SdrObjCustomShape* >(GetSdrObjectFromXShape(mxShape)));
+
+            if(bIsSdrObjCustomShape)
             {
-                EnhancedCustomShape2d aCustomShape2d( pSdrObjCustomShape );
+                SdrObjCustomShape& rSdrObjCustomShape(
+                    static_cast< SdrObjCustomShape& >(
+                        *GetSdrObjectFromXShape(mxShape)));
+                EnhancedCustomShape2d aCustomShape2d(rSdrObjCustomShape);
                 aTextBounds = aCustomShape2d.GetTextRect();
             }
+
             pTextObj->SetSnapRect( aTextBounds );
 
             // if rotated, copy GeoStat, too.
-            const GeoStat& rSourceGeo = pCustoObj->GetGeoStat();
+            const GeoStat& rSourceGeo(rSdrObjCustomShape.GetGeoStat());
             if ( rSourceGeo.nRotationAngle )
             {
                 pTextObj->NbcRotate(
-                    pCustoObj->GetSnapRect().Center(), rSourceGeo.nRotationAngle,
-                    rSourceGeo.nSin, rSourceGeo.nCos);
+                    rSdrObjCustomShape.GetSnapRect().Center(),
+                    rSourceGeo.nRotationAngle,
+                    rSourceGeo.nSin,
+                    rSourceGeo.nCos);
             }
 
             // set modified ItemSet at text object
@@ -234,10 +251,12 @@ SdrObject* EnhancedCustomShapeEngine::ImplForceGroupWithText( const SdrObjCustom
                 pRenderedShape = new SdrObjGroup();
                 static_cast<SdrObjGroup*>(pRenderedShape)->GetSubList()->NbcInsertObject( pTmp );
             }
-            pRenderedShape->SetPage( pCustoObj->GetPage() );
-            pRenderedShape->SetModel( pCustoObj->GetModel() );
+
+            pRenderedShape->SetPage(rSdrObjCustomShape.GetPage());
+            pRenderedShape->SetModel(rSdrObjCustomShape.GetModel());
         }
     }
+
     return pRenderedShape;
 }
 
@@ -253,104 +272,130 @@ void SetTemporary( uno::Reference< drawing::XShape > const & xShape )
 
 Reference< drawing::XShape > SAL_CALL EnhancedCustomShapeEngine::render()
 {
-    Reference< drawing::XShape > xShape;
-    SdrObject* pSdrObjCustomShape( dynamic_cast<SdrObjCustomShape*>( GetSdrObjectFromXShape( mxShape ) )  );
-    if ( pSdrObjCustomShape )
+    const bool bIsSdrObjCustomShape(nullptr != dynamic_cast< SdrObjCustomShape* >(GetSdrObjectFromXShape(mxShape)));
+
+    if(!bIsSdrObjCustomShape)
     {
-        // retrieving the TextPath property to check if feature is enabled
-        const SdrCustomShapeGeometryItem& rGeometryItem =
-            pSdrObjCustomShape->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
-        bool bTextPathOn = false;
-        const uno::Any* pAny = rGeometryItem.GetPropertyValueByName( "TextPath", "TextPath" );
-        if ( pAny )
-            *pAny >>= bTextPathOn;
-
-        EnhancedCustomShape2d aCustomShape2d( pSdrObjCustomShape );
-        sal_Int32 nRotateAngle = aCustomShape2d.GetRotateAngle();
-
-        bool bFlipV = aCustomShape2d.IsFlipVert();
-        bool bFlipH = aCustomShape2d.IsFlipHorz();
-        bool bLineGeometryNeededOnly = bTextPathOn;
-
-        SdrObject* pRenderedShape = aCustomShape2d.CreateObject( bLineGeometryNeededOnly );
-        if ( pRenderedShape )
+        return Reference< drawing::XShape >();
+    }
+
+    SdrObjCustomShape& rSdrObjCustomShape(
+        static_cast< SdrObjCustomShape& >(
+            *GetSdrObjectFromXShape(mxShape)));
+
+    // retrieving the TextPath property to check if feature is enabled
+    const SdrCustomShapeGeometryItem& rGeometryItem(rSdrObjCustomShape.GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ));
+    bool bTextPathOn = false;
+    const uno::Any* pAny = rGeometryItem.GetPropertyValueByName( "TextPath", "TextPath" );
+    if ( pAny )
+        *pAny >>= bTextPathOn;
+
+    EnhancedCustomShape2d aCustomShape2d(rSdrObjCustomShape);
+    sal_Int32 nRotateAngle = aCustomShape2d.GetRotateAngle();
+
+    bool bFlipV = aCustomShape2d.IsFlipVert();
+    bool bFlipH = aCustomShape2d.IsFlipHorz();
+    bool bLineGeometryNeededOnly = bTextPathOn;
+
+    SdrObject* pRenderedShape = aCustomShape2d.CreateObject( bLineGeometryNeededOnly );
+    if ( pRenderedShape )
+    {
+        if ( bTextPathOn )
         {
-            if ( bTextPathOn )
-            {
-                SdrObject* pRenderedFontWork = EnhancedCustomShapeFontWork::CreateFontWork( pRenderedShape, pSdrObjCustomShape );
-                if ( pRenderedFontWork )
-                {
-                    SdrObject::Free( pRenderedShape );
-                    pRenderedShape = pRenderedFontWork;
-                }
-            }
-            SdrObject* pRenderedShape3d = EnhancedCustomShape3d::Create3DObject( pRenderedShape, pSdrObjCustomShape );
-            if ( pRenderedShape3d )
+            SdrObject* pRenderedFontWork(
+                EnhancedCustomShapeFontWork::CreateFontWork(
+                    pRenderedShape,
+                    rSdrObjCustomShape));
+
+            if ( pRenderedFontWork )
             {
-                bFlipV = bFlipH = false;
-                nRotateAngle = 0;
                 SdrObject::Free( pRenderedShape );
-                pRenderedShape = pRenderedShape3d;
+                pRenderedShape = pRenderedFontWork;
             }
-            tools::Rectangle aRect( pSdrObjCustomShape->GetSnapRect() );
+        }
+        SdrObject* pRenderedShape3d = EnhancedCustomShape3d::Create3DObject(pRenderedShape, rSdrObjCustomShape);
+        if ( pRenderedShape3d )
+        {
+            bFlipV = bFlipH = false;
+            nRotateAngle = 0;
+            SdrObject::Free( pRenderedShape );
+            pRenderedShape = pRenderedShape3d;
+        }
 
-            const GeoStat& rGeoStat = static_cast<SdrObjCustomShape*>(pSdrObjCustomShape)->GetGeoStat();
-            if ( rGeoStat.nShearAngle )
-            {
-                long nShearAngle = rGeoStat.nShearAngle;
-                double nTan = rGeoStat.nTan;
-                if ((bFlipV&&!bFlipH )||(bFlipH&&!bFlipV))
-                {
-                    nShearAngle = -nShearAngle;
-                    nTan = -nTan;
-                }
-                pRenderedShape->Shear( pSdrObjCustomShape->GetSnapRect().Center(), nShearAngle, nTan, false);
-            }
-            if(nRotateAngle )
-            {
-                double a = nRotateAngle * F_PI18000;
-                pRenderedShape->NbcRotate( pSdrObjCustomShape->GetSnapRect().Center(), nRotateAngle, sin( a ), cos( a ) );
-            }
-            if ( bFlipV )
+        tools::Rectangle aRect(rSdrObjCustomShape.GetSnapRect());
+        const GeoStat& rGeoStat(rSdrObjCustomShape.GetGeoStat());
+
+        if ( rGeoStat.nShearAngle )
+        {
+            long nShearAngle = rGeoStat.nShearAngle;
+            double nTan = rGeoStat.nTan;
+            if ((bFlipV&&!bFlipH )||(bFlipH&&!bFlipV))
             {
-                Point aLeft( aRect.Left(), ( aRect.Top() + aRect.Bottom() ) >> 1 );
-                Point aRight( aLeft.X() + 1000, aLeft.Y() );
-                pRenderedShape->NbcMirror( aLeft, aRight );
+                nShearAngle = -nShearAngle;
+                nTan = -nTan;
             }
-            if ( bFlipH )
-            {
-                Point aTop( ( aRect.Left() + aRect.Right() ) >> 1, aRect.Top() );
-                Point aBottom( aTop.X(), aTop.Y() + 1000 );
-                pRenderedShape->NbcMirror( aTop, aBottom );
-            }
-            pRenderedShape->NbcSetStyleSheet( pSdrObjCustomShape->GetStyleSheet(), true );
-            pRenderedShape->RecalcSnapRect();
-        }
 
-        if ( mbForceGroupWithText )
-            pRenderedShape = ImplForceGroupWithText( static_cast<SdrObjCustomShape*>(pSdrObjCustomShape), pRenderedShape );
+            pRenderedShape->Shear(rSdrObjCustomShape.GetSnapRect().Center(), nShearAngle, nTan, false);
+        }
+        if(nRotateAngle )
+        {
+            double a = nRotateAngle * F_PI18000;
 
-        if ( pRenderedShape )
+            pRenderedShape->NbcRotate(rSdrObjCustomShape.GetSnapRect().Center(), nRotateAngle, sin( a ), cos( a ));
+        }
+        if ( bFlipV )
+        {
+            Point aLeft( aRect.Left(), ( aRect.Top() + aRect.Bottom() ) >> 1 );
+            Point aRight( aLeft.X() + 1000, aLeft.Y() );
+            pRenderedShape->NbcMirror( aLeft, aRight );
+        }
+        if ( bFlipH )
         {
-            aCustomShape2d.ApplyGluePoints( pRenderedShape );
-            xShape = SvxDrawPage::CreateShapeByTypeAndInventor( pRenderedShape->GetObjIdentifier(),
-                pRenderedShape->GetObjInventor(), pRenderedShape );
+            Point aTop( ( aRect.Left() + aRect.Right() ) >> 1, aRect.Top() );
+            Point aBottom( aTop.X(), aTop.Y() + 1000 );
+            pRenderedShape->NbcMirror( aTop, aBottom );
         }
-        SetTemporary( xShape );
+
+        pRenderedShape->NbcSetStyleSheet(rSdrObjCustomShape.GetStyleSheet(), true);
+        pRenderedShape->RecalcSnapRect();
     }
+
+    if ( mbForceGroupWithText )
+    {
+        pRenderedShape = ImplForceGroupWithText(
+            rSdrObjCustomShape,
+            pRenderedShape);
+    }
+
+    Reference< drawing::XShape > xShape;
+
+    if ( pRenderedShape )
+    {
+        aCustomShape2d.ApplyGluePoints( pRenderedShape );
+        xShape = SvxDrawPage::CreateShapeByTypeAndInventor( pRenderedShape->GetObjIdentifier(),
+            pRenderedShape->GetObjInventor(), pRenderedShape );
+    }
+
+    SetTemporary( xShape );
+
     return xShape;
 }
 
 awt::Rectangle SAL_CALL EnhancedCustomShapeEngine::getTextBounds()
 {
     awt::Rectangle aTextRect;
-    SdrObject* pSdrObjCustomShape( GetSdrObjectFromXShape( mxShape ) );
-    uno::Reference< document::XActionLockable > xLockable( mxShape, uno::UNO_QUERY );
-    if ( pSdrObjCustomShape && pSdrObjCustomShape->GetModel() && xLockable.is() && !xLockable->isActionLocked() )
+    const bool bIsSdrObjCustomShape(nullptr != dynamic_cast< SdrObjCustomShape* >(GetSdrObjectFromXShape(mxShape)));
+
+    if(bIsSdrObjCustomShape)
     {
-        if ( pSdrObjCustomShape )
+        SdrObjCustomShape& rSdrObjCustomShape(static_cast< SdrObjCustomShape& >(*GetSdrObjectFromXShape(mxShape)));
+        uno::Reference< document::XActionLockable > xLockable( mxShape, uno::UNO_QUERY );
+
+        if(rSdrObjCustomShape.GetModel()
+            && xLockable.is()
+            && !xLockable->isActionLocked())
         {
-            EnhancedCustomShape2d aCustomShape2d( pSdrObjCustomShape );
+            EnhancedCustomShape2d aCustomShape2d(rSdrObjCustomShape);
             tools::Rectangle aRect( aCustomShape2d.GetTextRect() );
             aTextRect.X = aRect.Left();
             aTextRect.Y = aRect.Top();
@@ -358,24 +403,30 @@ awt::Rectangle SAL_CALL EnhancedCustomShapeEngine::getTextBounds()
             aTextRect.Height = aRect.GetHeight();
         }
     }
+
     return aTextRect;
 }
 
 drawing::PolyPolygonBezierCoords SAL_CALL EnhancedCustomShapeEngine::getLineGeometry()
 {
     drawing::PolyPolygonBezierCoords aPolyPolygonBezierCoords;
-    SdrObject* pSdrObjCustomShape( GetSdrObjectFromXShape( mxShape ) );
-    if ( pSdrObjCustomShape )
+    const bool bIsSdrObjCustomShape(nullptr != dynamic_cast< SdrObjCustomShape* >(GetSdrObjectFromXShape(mxShape)));
+
+    if(bIsSdrObjCustomShape)
     {
-        EnhancedCustomShape2d aCustomShape2d( pSdrObjCustomShape );
+        SdrObjCustomShape& rSdrObjCustomShape(
+            static_cast< SdrObjCustomShape& >(
+                *GetSdrObjectFromXShape(mxShape)));
+        EnhancedCustomShape2d aCustomShape2d(rSdrObjCustomShape);
         SdrObject* pObj = aCustomShape2d.CreateLineGeometry();
+
         if ( pObj )
         {
-            tools::Rectangle aRect( pSdrObjCustomShape->GetSnapRect() );
+            tools::Rectangle aRect(rSdrObjCustomShape.GetSnapRect());
             bool bFlipV = aCustomShape2d.IsFlipVert();
             bool bFlipH = aCustomShape2d.IsFlipHorz();
+            const GeoStat& rGeoStat(rSdrObjCustomShape.GetGeoStat());
 
-            const GeoStat& rGeoStat = static_cast<SdrObjCustomShape*>(pSdrObjCustomShape)->GetGeoStat();
             if ( rGeoStat.nShearAngle )
             {
                 long nShearAngle = rGeoStat.nShearAngle;
@@ -444,13 +495,19 @@ drawing::PolyPolygonBezierCoords SAL_CALL EnhancedCustomShapeEngine::getLineGeom
 Sequence< Reference< drawing::XCustomShapeHandle > > SAL_CALL EnhancedCustomShapeEngine::getInteraction()
 {
     sal_uInt32 i, nHdlCount = 0;
-    SdrObject* pSdrObjCustomShape = GetSdrObjectFromXShape( mxShape );
-    if ( pSdrObjCustomShape )
+    const bool bIsSdrObjCustomShape(nullptr != dynamic_cast< SdrObjCustomShape* >(GetSdrObjectFromXShape(mxShape)));
+
+    if(bIsSdrObjCustomShape)
     {
-        EnhancedCustomShape2d aCustomShape2d( pSdrObjCustomShape );
+        SdrObjCustomShape& rSdrObjCustomShape(
+            static_cast< SdrObjCustomShape& >(
+                *GetSdrObjectFromXShape(mxShape)));
+        EnhancedCustomShape2d aCustomShape2d(rSdrObjCustomShape);
         nHdlCount = aCustomShape2d.GetHdlCount();
     }
+
     Sequence< Reference< drawing::XCustomShapeHandle > > aSeq( nHdlCount );
+
     for ( i = 0; i < nHdlCount; i++ )
         aSeq[ i ] = new EnhancedCustomShapeHandle( mxShape, i );
     return aSeq;
diff --git a/svx/source/customshapes/EnhancedCustomShapeFontWork.cxx b/svx/source/customshapes/EnhancedCustomShapeFontWork.cxx
index c6d45574a9e4..71dc441f1727 100644
--- a/svx/source/customshapes/EnhancedCustomShapeFontWork.cxx
+++ b/svx/source/customshapes/EnhancedCustomShapeFontWork.cxx
@@ -85,7 +85,10 @@ struct FWData                           // representing the whole text
 };
 
 
-static bool InitializeFontWorkData( const SdrObject* pCustomShape, const sal_uInt16 nOutlinesCount2d, FWData& rFWData )
+static bool InitializeFontWorkData(
+    const SdrObjCustomShape& rSdrObjCustomShape,
+    const sal_uInt16 nOutlinesCount2d,
+    FWData& rFWData)
 {
     bool bNoErr = false;
     bool bSingleLineMode = false;
@@ -100,7 +103,8 @@ static bool InitializeFontWorkData( const SdrObject* pCustomShape, const sal_uIn
         rFWData.bSingleLineMode = bSingleLineMode;
 
         // setting the strings
-        OutlinerParaObject* pParaObj = static_cast<const SdrObjCustomShape*>(pCustomShape)->GetOutlinerParaObject();
+        OutlinerParaObject* pParaObj(rSdrObjCustomShape.GetOutlinerParaObject());
+
         if ( pParaObj )
         {
             const EditTextObject& rTextObj = pParaObj->GetTextObject();
@@ -146,8 +150,10 @@ double GetLength( const tools::Polygon& rPolygon )
 
 /* CalculateHorizontalScalingFactor returns the horizontal scaling factor for
 the whole text object, so that each text will match its corresponding 2d Outline */
-void CalculateHorizontalScalingFactor( const SdrObject* pCustomShape,
-                                        FWData& rFWData, const tools::PolyPolygon& rOutline2d )
+void CalculateHorizontalScalingFactor(
+    const SdrObjCustomShape& rSdrObjCustomShape,
+    FWData& rFWData,
+    const tools::PolyPolygon& rOutline2d)
 {
     double fScalingFactor = 1.0;
     bool bScalingFactorDefined = false;
@@ -157,8 +163,8 @@ void CalculateHorizontalScalingFactor( const SdrObject* pCustomShape,
     sal_uInt16 nOutlinesCount2d = rOutline2d.Count();
 
     vcl::Font aFont;
-    const SvxFontItem& rFontItem = pCustomShape->GetMergedItem( EE_CHAR_FONTINFO );
-    aFont.SetFontHeight( pCustomShape->GetLogicRect().GetHeight() / rFWData.nMaxParagraphsPerTextArea );
+    const SvxFontItem& rFontItem(rSdrObjCustomShape.GetMergedItem( EE_CHAR_FONTINFO ));
+    aFont.SetFontHeight(rSdrObjCustomShape.GetLogicRect().GetHeight() / rFWData.nMaxParagraphsPerTextArea);
     aFont.SetAlignment( ALIGN_TOP );
     aFont.SetFamilyName( rFontItem.GetFamilyName() );
     aFont.SetFamily( rFontItem.GetFamily() );
@@ -210,9 +216,13 @@ void CalculateHorizontalScalingFactor( const SdrObject* pCustomShape,
     rFWData.fHorizontalTextScaling = fScalingFactor;
 }
 
-void GetTextAreaOutline( const FWData& rFWData, const SdrObject* pCustomShape, FWTextArea& rTextArea, bool bSameLetterHeights )
+void GetTextAreaOutline(
+    const FWData& rFWData,
+    const SdrObjCustomShape& rSdrObjCustomShape,
+    FWTextArea& rTextArea,
+    bool bSameLetterHeights)
 {
-    bool bIsVertical = static_cast<const SdrObjCustomShape*>(pCustomShape)->IsVerticalWriting();
+    bool bIsVertical(rSdrObjCustomShape.IsVerticalWriting());
     sal_Int32 nVerticalOffset = rFWData.nMaxParagraphsPerTextArea > rTextArea.vParagraphs.size()
                                     ? rFWData.nSingleLineHeight / 2 : 0;
 
@@ -243,7 +253,7 @@ void GetTextAreaOutline( const FWData& rFWData, const SdrObject* pCustomShape, F
                 nFntItm = EE_CHAR_FONTINFO_CTL;
             else if ( nScriptType == i18n::ScriptType::ASIAN )
                 nFntItm = EE_CHAR_FONTINFO_CJK;
-            const SvxFontItem& rFontItem = static_cast<const SvxFontItem&>(pCustomShape->GetMergedItem( nFntItm ));
+            const SvxFontItem& rFontItem = static_cast<const SvxFontItem&>(rSdrObjCustomShape.GetMergedItem( nFntItm ));
             vcl::Font aFont;
             aFont.SetFontHeight( rFWData.nSingleLineHeight );
             aFont.SetAlignment( ALIGN_TOP );
@@ -253,10 +263,10 @@ void GetTextAreaOutline( const FWData& rFWData, const SdrObject* pCustomShape, F
             aFont.SetStyleName( rFontItem.GetStyleName() );
             aFont.SetOrientation( 0 );
 
-            const SvxPostureItem& rPostureItem = pCustomShape->GetMergedItem( EE_CHAR_ITALIC );
+            const SvxPostureItem& rPostureItem = rSdrObjCustomShape.GetMergedItem( EE_CHAR_ITALIC );
             aFont.SetItalic( rPostureItem.GetPosture() );
 
-            const SvxWeightItem& rWeightItem = pCustomShape->GetMergedItem( EE_CHAR_WEIGHT );
+            const SvxWeightItem& rWeightItem = rSdrObjCustomShape.GetMergedItem( EE_CHAR_WEIGHT );
             aFont.SetWeight( rWeightItem.GetWeight() );
 
             // initializing virtual device
@@ -267,7 +277,7 @@ void GetTextAreaOutline( const FWData& rFWData, const SdrObject* pCustomShape, F
             if ( aParagraphIter->nFrameDirection == SvxFrameDirection::Horizontal_RL_TB )
                 pVirDev->SetLayoutMode( ComplexTextLayoutFlags::BiDiRtl );
 
-            const SvxCharScaleWidthItem& rCharScaleWidthItem = pCustomShape->GetMergedItem( EE_CHAR_FONTWIDTH );
+            const SvxCharScaleWidthItem& rCharScaleWidthItem = rSdrObjCustomShape.GetMergedItem( EE_CHAR_FONTWIDTH );
             sal_uInt16 nCharScaleWidth = rCharScaleWidthItem.GetValue();
             std::unique_ptr<long[]> pDXArry;
             sal_Int32 nWidth = 0;
@@ -413,29 +423,36 @@ void GetTextAreaOutline( const FWData& rFWData, const SdrObject* pCustomShape, F
     }
 }
 
-bool GetFontWorkOutline(FWData& rFWData, const SdrObject* pCustomShape)
+bool GetFontWorkOutline(
+    FWData& rFWData,
+    const SdrObjCustomShape& rSdrObjCustomShape)
 {
-    SdrTextHorzAdjust eHorzAdjust( pCustomShape->GetMergedItem( SDRATTR_TEXT_HORZADJUST ).GetValue() );
-    drawing::TextFitToSizeType const eFTS( pCustomShape->GetMergedItem( SDRATTR_TEXT_FITTOSIZE ).GetValue() );
+    SdrTextHorzAdjust eHorzAdjust(rSdrObjCustomShape.GetMergedItem( SDRATTR_TEXT_HORZADJUST ).GetValue());
+    drawing::TextFitToSizeType const eFTS(rSdrObjCustomShape.GetMergedItem( SDRATTR_TEXT_FITTOSIZE ).GetValue());
 
     std::vector< FWTextArea >::iterator aTextAreaIter = rFWData.vTextAreas.begin();
     std::vector< FWTextArea >::const_iterator aTextAreaIEnd = rFWData.vTextAreas.end();
 
-    rFWData.nSingleLineHeight = static_cast<sal_Int32>( ( static_cast<double>(pCustomShape->GetLogicRect().GetHeight())
+    rFWData.nSingleLineHeight = static_cast<sal_Int32>( ( static_cast<double>(rSdrObjCustomShape.GetLogicRect().GetHeight())
                                                 / rFWData.nMaxParagraphsPerTextArea ) * rFWData.fHorizontalTextScaling );
 
     if (rFWData.nSingleLineHeight == SAL_MIN_INT32)
         return false;
 
     bool bSameLetterHeights = false;
-    const SdrCustomShapeGeometryItem& rGeometryItem = pCustomShape->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
+    const SdrCustomShapeGeometryItem& rGeometryItem(rSdrObjCustomShape.GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ));
     const css::uno::Any* pAny = rGeometryItem.GetPropertyValueByName( "TextPath", "SameLetterHeights" );
     if ( pAny )
         *pAny >>= bSameLetterHeights;
 
     while ( aTextAreaIter != aTextAreaIEnd )
     {
-        GetTextAreaOutline( rFWData, pCustomShape, *aTextAreaIter, bSameLetterHeights );
+        GetTextAreaOutline(
+            rFWData,
+            rSdrObjCustomShape,
+            *aTextAreaIter,
+            bSameLetterHeights);
+
         if (eFTS == drawing::TextFitToSizeType_ALLLINES ||
             // tdf#97630 interpret PROPORTIONAL same as ALLLINES so we don't
             // need another ODF attribute!
@@ -802,7 +819,9 @@ void FitTextOutlinesToShapeOutlines( const tools::PolyPolygon& aOutlines2d, FWDa
     }
 }
 
-SdrObject* CreateSdrObjectFromParagraphOutlines( const FWData& rFWData, const SdrObject* pCustomShape )
+SdrObject* CreateSdrObjectFromParagraphOutlines(
+    const FWData& rFWData,
+    const SdrObjCustomShape& rSdrObjCustomShape)
 {
     SdrObject* pRet = nullptr;
     basegfx::B2DPolyPolygon aPolyPoly;
@@ -836,7 +855,7 @@ SdrObject* CreateSdrObjectFromParagraphOutlines( const FWData& rFWData, const Sd
 
         pRet = new SdrPathObj( OBJ_POLY, aPolyPoly );
 
-        SfxItemSet aSet( pCustomShape->GetMergedItemSet() );
+        SfxItemSet aSet(rSdrObjCustomShape.GetMergedItemSet());
         aSet.ClearItem( SDRATTR_TEXTDIRECTION );    //SJ: vertical writing is not required, by removing this item no outliner is created
         aSet.Put(makeSdrShadowItem(false)); // #i37011# NO shadow for FontWork geometry
         pRet->SetMergedItemSet( aSet );             // * otherwise we would crash, because the outliner tries to create a Paraobject, but there is no model
@@ -856,7 +875,9 @@ Reference < i18n::XBreakIterator > const & EnhancedCustomShapeFontWork::GetBreak
     return mxBreakIterator;
 }
 
-SdrObject* EnhancedCustomShapeFontWork::CreateFontWork( const SdrObject* pShape2d, const SdrObject* pCustomShape )
+SdrObject* EnhancedCustomShapeFontWork::CreateFontWork(
+    const SdrObject* pShape2d,
+    const SdrObjCustomShape& rSdrObjCustomShape)
 {
     SdrObject* pRet = nullptr;
 
@@ -865,19 +886,29 @@ SdrObject* EnhancedCustomShapeFontWork::CreateFontWork( const SdrObject* pShape2
     if ( nOutlinesCount2d )
     {
         FWData aFWData;
-        if ( InitializeFontWorkData( pCustomShape, nOutlinesCount2d, aFWData ) )
+
+        if(InitializeFontWorkData(rSdrObjCustomShape, nOutlinesCount2d, aFWData))
         {
             /* retrieves the horizontal scaling factor that has to be used
             to fit each paragraph text into its corresponding 2d outline */
-            CalculateHorizontalScalingFactor( pCustomShape, aFWData, aOutlines2d );
+            CalculateHorizontalScalingFactor(
+                rSdrObjCustomShape,
+                aFWData,
+                aOutlines2d);
 
             /* retrieving the Outlines for the each Paragraph. */
-            if (!GetFontWorkOutline(aFWData, pCustomShape))
+            if(!GetFontWorkOutline(
+                aFWData,
+                rSdrObjCustomShape))
+            {
                 return nullptr;
+            }
 
             FitTextOutlinesToShapeOutlines( aOutlines2d, aFWData );
 
-            pRet = CreateSdrObjectFromParagraphOutlines( aFWData, pCustomShape );
+            pRet = CreateSdrObjectFromParagraphOutlines(
+                aFWData,
+                rSdrObjCustomShape);
         }
     }
     return pRet;
diff --git a/svx/source/customshapes/EnhancedCustomShapeFontWork.hxx b/svx/source/customshapes/EnhancedCustomShapeFontWork.hxx
index d86388cb75fc..9fd954cd7034 100644
--- a/svx/source/customshapes/EnhancedCustomShapeFontWork.hxx
+++ b/svx/source/customshapes/EnhancedCustomShapeFontWork.hxx
@@ -30,7 +30,9 @@ class EnhancedCustomShapeFontWork
     public:
 
         static css::uno::Reference < css::i18n::XBreakIterator > const & GetBreakIterator();
-        static SdrObject* CreateFontWork( const SdrObject* pShape2d, const SdrObject* pCustomShape );
+        static SdrObject* CreateFontWork(
+            const SdrObject* pShape2d,
+            const SdrObjCustomShape& rSdrObjCustomShape);
 };
 
 #endif
diff --git a/svx/source/customshapes/EnhancedCustomShapeHandle.cxx b/svx/source/customshapes/EnhancedCustomShapeHandle.cxx
index b541eb410978..d4975c41f4db 100644
--- a/svx/source/customshapes/EnhancedCustomShapeHandle.cxx
+++ b/svx/source/customshapes/EnhancedCustomShapeHandle.cxx
@@ -48,26 +48,41 @@ void SAL_CALL EnhancedCustomShapeHandle::release() throw()
 // XCustomShapeHandle
 css::awt::Point SAL_CALL EnhancedCustomShapeHandle::getPosition()
 {
-    SdrObject* pSdrObjCustomShape( GetSdrObjectFromXShape( mxCustomShape ) );
-    if ( !pSdrObjCustomShape )
+    const bool bIsSdrObjCustomShape(nullptr != dynamic_cast< SdrObjCustomShape* >(GetSdrObjectFromXShape(mxCustomShape)));
+
+    if(!bIsSdrObjCustomShape)
+    {
         throw css::uno::RuntimeException();
+    }
 
+    SdrObjCustomShape& rSdrObjCustomShape(static_cast< SdrObjCustomShape& >(*GetSdrObjectFromXShape(mxCustomShape)));
     Point aPosition;
-    EnhancedCustomShape2d aCustomShape2d( pSdrObjCustomShape );
-    if ( !aCustomShape2d.GetHandlePosition( mnIndex, aPosition ) )
+    EnhancedCustomShape2d aCustomShape2d(rSdrObjCustomShape);
+
+    if(!aCustomShape2d.GetHandlePosition(mnIndex, aPosition))
+    {
         throw css::uno::RuntimeException();
+    }
+
     return css::awt::Point( aPosition.X(), aPosition.Y() );
 }
 
 void SAL_CALL EnhancedCustomShapeHandle::setControllerPosition( const css::awt::Point& aPnt )
 {
-    SdrObject* pSdrObjCustomShape( GetSdrObjectFromXShape( mxCustomShape ) );
-    if ( !pSdrObjCustomShape )
+    const bool bIsSdrObjCustomShape(nullptr != dynamic_cast< SdrObjCustomShape* >(GetSdrObjectFromXShape(mxCustomShape)));
+
+    if(!bIsSdrObjCustomShape)
+    {
         throw css::uno::RuntimeException();
+    }
+
+    SdrObjCustomShape& rSdrObjCustomShape(static_cast< SdrObjCustomShape& >(*GetSdrObjectFromXShape(mxCustomShape)));
+    EnhancedCustomShape2d aCustomShape2d(rSdrObjCustomShape);
 
-    EnhancedCustomShape2d aCustomShape2d( pSdrObjCustomShape );
-    if ( !aCustomShape2d.SetHandleControllerPosition( mnIndex, aPnt ) )
+    if(!aCustomShape2d.SetHandleControllerPosition(mnIndex, aPnt))
+    {
         throw css::uno::RuntimeException();
+    }
 }
 
 // XInitialization
commit 66383e64197384aa67c452a343ad81274093bfac
Author: Armin Le Grand <Armin.Le.Grand at cib.de (CIB)>
Date:   Fri Feb 23 16:57:41 2018 +0100

    OperationSmiley: Added support for using same FillGeometry
    
    It is now possible to use a single FillGeometry to fill objects that
    are made of multiple filled objects (e.g. CustomShapes) so that
    they look as using a single fill. This is used for CustomShapes,
    but may later be 'extended' to be used for more cases. The basic
    functionality was already in the primitives, but had to be added
    to SDrObject due to these being used for CustomShapeVisualization
    (currently - would be better to change this to primitives, too).
    
    Change-Id: I1d9fb158191a9ec663e46f3911213be2f3d88986

diff --git a/include/svx/svdobj.hxx b/include/svx/svdobj.hxx
index 3e97a472084f..7bd547f20d71 100644
--- a/include/svx/svdobj.hxx
+++ b/include/svx/svdobj.hxx
@@ -270,11 +270,32 @@ public:
 class SvxShape;
 class SVX_DLLPUBLIC SdrObject: public SfxListener, public virtual tools::WeakBase
 {
+private:
     friend class                SdrObjListIter;
     friend class                SdrVirtObj;
     friend class                SdrRectObj;
     friend class                SdrDelayBroadcastObjectChange;
 
+    // OperationSmiley: Allow at each SdrObject to set a FillGeometryDefiningShape,
+    // so that for SdrObjects where this is set, the definition of a defined FillStyle
+    // will use this, but the local geometry will be filled. This allows to fill
+    // multiple shapes with a unified fill, e.g think about CustomShapes.
+    // Currently this is *only* used for CustomShapes, but may be developed to get a
+    // common mechanism - usages for it are easy to be found. The current limitation
+    // to CustomShapes allows to to think about these SdrObjects to 'vanish' during the
+    // lifetime of 'this' - the SdrObjects without SdrPage and SdrModel are used as helper
+    // objects for SdrObjCustomShape and thus their lifetime is limited to the lifetime
+    // of this local object. For unifying this mechanism, some weak reference of
+    // SdrObjects would have to be thought about (not easy with the current implementation).
+    // So - allow *only* EnhancedCustomShape2d (which creates the visualizations for
+    // SdrObjCustomShape) to set this. Already allow unified read to use it - thus already
+    // allowing to implement as standard case for all kinds of SdrObjects.
+    friend class EnhancedCustomShape2d;
+    const SdrObject*            mpFillGeometryDefiningShape;
+    void setFillGeometryDefiningShape(const SdrObject* pNew) { mpFillGeometryDefiningShape = pNew; }
+public:
+    const SdrObject* getFillGeometryDefiningShape() const { return mpFillGeometryDefiningShape; }
+
 public:
     SdrObject();
 
diff --git a/svx/inc/sdr/primitive2d/sdrpathprimitive2d.hxx b/svx/inc/sdr/primitive2d/sdrpathprimitive2d.hxx
index b60e9b3df565..e165344b26c1 100644
--- a/svx/inc/sdr/primitive2d/sdrpathprimitive2d.hxx
+++ b/svx/inc/sdr/primitive2d/sdrpathprimitive2d.hxx
@@ -40,20 +40,36 @@ namespace drawinglayer
             attribute::SdrLineFillShadowTextAttribute   maSdrLFSTAttribute;
             basegfx::B2DPolyPolygon                     maUnitPolyPolygon;
 
+            // OperationSmiley: Added to be able to define a FillGeometry different from local
+            // geometry. It is ignored when empty and/or equal to UnitPolyPolygon.
+            // If used and there is a fill, object's geomery (maUnitPolyPolygon) will be filled,
+            // but UnitDefinitionPolyPolygon will be used to define the FillStyle. Thus when
+            // using the 'same' UnitDefinitionPolyPolygon for multiple definitions,
+            // all filled stuff using it will fit seamless together.
+            // 'same' is in quotes since it is a UnitPolygon, so being relative to the
+            // unit polygon of the local geometry (UnitPolyPolygon). The definition is complete
+            // when applying the also given transfomation (maTransform)
+            basegfx::B2DPolyPolygon                     maUnitDefinitionPolyPolygon;
+
         protected:
             // local decomposition.
             virtual void create2DDecomposition(Primitive2DContainer& rContainer, const geometry::ViewInformation2D& aViewInformation) const override;
 
         public:
+            // OperationSmiley: Extended to UnitDefinitionPolyPolygon, but when needed
+            // a 2nd version without can be defined that just does not set the
+            // maUnitDefinitionPolyPolygon or set equal to UnitPolyPolygon
             SdrPathPrimitive2D(
                 const basegfx::B2DHomMatrix& rTransform,
                 const attribute::SdrLineFillShadowTextAttribute& rSdrLFSTAttribute,
-                const basegfx::B2DPolyPolygon& rUnitPolyPolygon);
+                const basegfx::B2DPolyPolygon& rUnitPolyPolygon,
+                const basegfx::B2DPolyPolygon& rUnitDefinitionPolyPolygon);
 
             // data access
             const basegfx::B2DHomMatrix& getTransform() const { return maTransform; }
             const attribute::SdrLineFillShadowTextAttribute& getSdrLFSTAttribute() const { return maSdrLFSTAttribute; }
             const basegfx::B2DPolyPolygon& getUnitPolyPolygon() const { return maUnitPolyPolygon; }
+            const basegfx::B2DPolyPolygon& getUnitDefinitionPolyPolygon() const { return maUnitDefinitionPolyPolygon; }
 
             // compare operator
             virtual bool operator==(const BasePrimitive2D& rPrimitive) const override;
diff --git a/svx/source/customshapes/EnhancedCustomShape2d.cxx b/svx/source/customshapes/EnhancedCustomShape2d.cxx
index b50836fd138f..39d694b112a8 100644
--- a/svx/source/customshapes/EnhancedCustomShape2d.cxx
+++ b/svx/source/customshapes/EnhancedCustomShape2d.cxx
@@ -1963,22 +1963,6 @@ void EnhancedCustomShape2d::CreateSubPath(
 
     if(aNewB2DPolyPolygon.count())
     {
-        if( !bLineGeometryNeededOnly )
-        {
-            // hack aNewB2DPolyPolygon to fill logic rect - this is
-            // needed to produce gradient fills that look like mso
-            aNewB2DPolygon.clear();
-            aNewB2DPolygon.append(basegfx::B2DPoint(0,0));
-            aNewB2DPolygon.setClosed(true);
-            aNewB2DPolyPolygon.append(aNewB2DPolygon);
-
-            aNewB2DPolygon.clear();
-            aNewB2DPolygon.append(basegfx::B2DPoint(aLogicRect.GetWidth(),
-                                                    aLogicRect.GetHeight()));
-            aNewB2DPolygon.setClosed(true);
-            aNewB2DPolyPolygon.append(aNewB2DPolygon);
-        }
-
         // #i37011#
         bool bForceCreateTwoObjects(false);
 
@@ -2335,6 +2319,16 @@ SdrObject* EnhancedCustomShape2d::CreatePathObj( bool bLineGeometryNeededOnly )
                         rCustomShapeSet,
                         nColorIndex,
                         nColorCount);
+
+                    // OperationSmiley: when we have access to the SdrObjCustomShape and the
+                    // CustomShape is built with more than a single filled Geometry, use it
+                    // to define that all helper geometites defined here (SdrObjects currently)
+                    // will use the same FillGeometryDefinition (from the referenced SdrObjCustomShape).
+                    // This will all same-filled objects look like filled smoothly with the same style.
+                    if(pCustomShapeObj)
+                    {
+                        pObj->setFillGeometryDefiningShape(pCustomShapeObj);
+                    }
                 }
             }
 
diff --git a/svx/source/sdr/contact/viewcontactofsdrpathobj.cxx b/svx/source/sdr/contact/viewcontactofsdrpathobj.cxx
index 2f203971ad4f..c3033bf71337 100644
--- a/svx/source/sdr/contact/viewcontactofsdrpathobj.cxx
+++ b/svx/source/sdr/contact/viewcontactofsdrpathobj.cxx
@@ -83,6 +83,7 @@ namespace sdr
 
             // prepare object transformation and unit polygon (direct model data)
             basegfx::B2DHomMatrix aObjectMatrix;
+            basegfx::B2DPolyPolygon aUnitDefinitionPolyPolygon;
             bool bIsLine(
                 !aUnitPolyPolygon.areControlPointsUsed()
                 && 1 == nPolyCount
@@ -166,6 +167,30 @@ namespace sdr
                 basegfx::B2DHomMatrix aInverse(aObjectMatrix);
                 aInverse.invert();
                 aUnitPolyPolygon.transform(aInverse);
+
+                // OperationSmiley: Check if a FillGeometryDefiningShape is set
+                const SdrObject* pFillGeometryDefiningShape(GetPathObj().getFillGeometryDefiningShape());
+
+                if(nullptr != pFillGeometryDefiningShape)
+                {
+                    // If yes, get it's BoundRange and use as defining Geometry for the FillStyle.

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list