sw/inc/anchoredobject.hxx                |    1 
 sw/source/core/doc/docdraw.cxx           |   17 ++-
 sw/source/core/draw/dview.cxx            |   19 ++--
 sw/source/core/frmedt/feshview.cxx       |   36 ++++---
 sw/source/core/layout/anchoredobject.cxx |  134 ++++++++++++++++-------------
 sw/source/core/layout/flylay.cxx         |  113 ++++++++++++------------
 sw/source/core/layout/frmtool.cxx        |    6 -
 sw/source/core/layout/sortedobjs.cxx     |    4 
 sw/source/core/text/txtfly.cxx           |  143 ++++++++++++++++---------------
 sw/source/uibase/docvw/edtwin.cxx        |   28 +++---
 sw/source/uibase/shells/drwbassh.cxx     |   16 ++-
 11 files changed, 288 insertions(+), 229 deletions(-)

New commits:
commit 19062c98da5b2e9edc7a99068fa06a83c7578826
Author:     Matt K <matt...@gmail.com>
AuthorDate: Thu Jan 11 20:37:01 2024 -0600
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Sat Jan 13 18:21:02 2024 +0100

    tdf#132810 Prevent crashes with gallery objects
    
    The problem is the formats for the gallery objects
    may be non-existent but the code attempts to use
    them anyway, causing crashes.  The fix is to check
    for the existence of the proper format objects
    before using them, so as to prevent the crashes.
    I tested creating/deleting multiple objects with
    multiple rounds of undo/redo and believe this change
    to cover all the crashes that can occur (there were
    several).
    
    Change-Id: I9d5d704eaa381be861ac1758ad58269706437a27
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161950
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>

diff --git a/sw/inc/anchoredobject.hxx b/sw/inc/anchoredobject.hxx
index 19cd2e75802b..9af198425714 100644
--- a/sw/inc/anchoredobject.hxx
+++ b/sw/inc/anchoredobject.hxx
@@ -318,6 +318,7 @@ class SW_DLLPUBLIC SwAnchoredObject
         void SetCurrRelPos( Point _aRelPos );
 
         // accessors to the format
+        bool HasFrameFormat() const;
         virtual SwFrameFormat& GetFrameFormat() = 0;
         virtual const SwFrameFormat& GetFrameFormat() const = 0;
 
diff --git a/sw/source/core/doc/docdraw.cxx b/sw/source/core/doc/docdraw.cxx
index aecbe2ac824f..521ca2b0ba15 100644
--- a/sw/source/core/doc/docdraw.cxx
+++ b/sw/source/core/doc/docdraw.cxx
@@ -463,14 +463,17 @@ bool SwDoc::DeleteSelection( SwDrawView& rDrawView )
             SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
             if( dynamic_cast<const SwVirtFlyDrawObj*>( pObj) ==  nullptr )
             {
-                SwDrawContact *pC = 
static_cast<SwDrawContact*>(GetUserCall(pObj));
-                SwDrawFrameFormat *pFrameFormat = 
static_cast<SwDrawFrameFormat*>(pC->GetFormat());
-                if( pFrameFormat &&
-                    RndStdIds::FLY_AS_CHAR == 
pFrameFormat->GetAnchor().GetAnchorId() )
+                if (SwDrawContact* pC = 
static_cast<SwDrawContact*>(GetUserCall(pObj)))
                 {
-                    rDrawView.MarkObj( pObj, rDrawView.Imp().GetPageView(), 
true );
-                    --i;
-                    getIDocumentLayoutAccess().DelLayoutFormat( pFrameFormat );
+                    SwDrawFrameFormat* pFrameFormat
+                        = static_cast<SwDrawFrameFormat*>(pC->GetFormat());
+                    if (pFrameFormat
+                        && RndStdIds::FLY_AS_CHAR == 
pFrameFormat->GetAnchor().GetAnchorId())
+                    {
+                        rDrawView.MarkObj(pObj, rDrawView.Imp().GetPageView(), 
true);
+                        --i;
+                        
getIDocumentLayoutAccess().DelLayoutFormat(pFrameFormat);
+                    }
                 }
             }
         }
diff --git a/sw/source/core/draw/dview.cxx b/sw/source/core/draw/dview.cxx
index f7ab7cda9fbd..98c0014b1a17 100644
--- a/sw/source/core/draw/dview.cxx
+++ b/sw/source/core/draw/dview.cxx
@@ -979,16 +979,19 @@ void SwDrawView::DeleteMarked()
     {
         SdrObject *pObject = rMarkList.GetMark(i)->GetMarkedSdrObj();
         SwContact* pContact = GetUserCall(pObject);
-        SwFrameFormat* pFormat = pContact->GetFormat();
-        if (pObject->getChildrenOfSdrObject())
+        if (pContact)
         {
-            auto pChildTextBoxes = SwTextBoxHelper::CollectTextBoxes(pObject, 
pFormat);
-            for (auto& rChildTextBox : pChildTextBoxes)
-                aTextBoxesToDelete.push_back(rChildTextBox);
-        }
-        else
-            if (SwFrameFormat* pTextBox = 
SwTextBoxHelper::getOtherTextBoxFormat(pFormat, RES_DRAWFRMFMT))
+            SwFrameFormat* pFormat = pContact->GetFormat();
+            if (pObject->getChildrenOfSdrObject())
+            {
+                auto pChildTextBoxes = 
SwTextBoxHelper::CollectTextBoxes(pObject, pFormat);
+                for (auto& rChildTextBox : pChildTextBoxes)
+                    aTextBoxesToDelete.push_back(rChildTextBox);
+            }
+            else if (SwFrameFormat* pTextBox
+                     = SwTextBoxHelper::getOtherTextBoxFormat(pFormat, 
RES_DRAWFRMFMT))
                 aTextBoxesToDelete.push_back(pTextBox);
+        }
     }
 
     if ( pDoc->DeleteSelection( *this ) )
diff --git a/sw/source/core/frmedt/feshview.cxx 
b/sw/source/core/frmedt/feshview.cxx
index 9a18e7934c03..30e448dec8e3 100644
--- a/sw/source/core/frmedt/feshview.cxx
+++ b/sw/source/core/frmedt/feshview.cxx
@@ -2221,14 +2221,16 @@ RndStdIds SwFEShell::GetAnchorId() const
                 nRet = RndStdIds::UNKNOWN;
                 break;
             }
-            SwDrawContact *pContact = 
static_cast<SwDrawContact*>(GetUserCall(pObj));
-            RndStdIds nId = pContact->GetFormat()->GetAnchor().GetAnchorId();
-            if ( nRet == RndStdIds(SHRT_MAX) )
-                nRet = nId;
-            else if ( nRet != nId )
+            if (SwDrawContact* pContact = 
static_cast<SwDrawContact*>(GetUserCall(pObj)))
             {
-                nRet = RndStdIds::UNKNOWN;
-                break;
+                RndStdIds nId = 
pContact->GetFormat()->GetAnchor().GetAnchorId();
+                if (nRet == RndStdIds(SHRT_MAX))
+                    nRet = nId;
+                else if (nRet != nId)
+                {
+                    nRet = RndStdIds::UNKNOWN;
+                    break;
+                }
             }
         }
     }
@@ -3152,17 +3154,19 @@ Color SwFEShell::GetShapeBackground() const
             OSL_ENSURE( dynamic_cast<const SwVirtFlyDrawObj*>( pSdrObj) ==  
nullptr, "wrong usage of SwFEShell::GetShapeBackground - selected object is not 
a drawing object!");
             if ( dynamic_cast<const SwVirtFlyDrawObj*>( pSdrObj) ==  nullptr )
             {
-                // determine page frame of the frame the shape is anchored.
-                const SwFrame* pAnchorFrame =
-                        
static_cast<SwDrawContact*>(GetUserCall(pSdrObj))->GetAnchorFrame( pSdrObj );
-                OSL_ENSURE( pAnchorFrame, "inconsistent model - no anchor at 
shape!");
-                if ( pAnchorFrame )
+                if (SwDrawContact* pDrawContact = 
static_cast<SwDrawContact*>(GetUserCall(pSdrObj)))
                 {
-                    const SwPageFrame* pPageFrame = 
pAnchorFrame->FindPageFrame();
-                    OSL_ENSURE( pPageFrame, "inconsistent model - no page!");
-                    if ( pPageFrame )
+                    // determine page frame of the frame the shape is anchored.
+                    const SwFrame * pAnchorFrame = 
pDrawContact->GetAnchorFrame(pSdrObj);
+                    OSL_ENSURE(pAnchorFrame, "inconsistent model - no anchor 
at shape!");
+                    if (pAnchorFrame)
                     {
-                        aRetColor = pPageFrame->GetDrawBackgroundColor();
+                        const SwPageFrame* pPageFrame = 
pAnchorFrame->FindPageFrame();
+                        OSL_ENSURE(pPageFrame, "inconsistent model - no 
page!");
+                        if (pPageFrame)
+                        {
+                            aRetColor = pPageFrame->GetDrawBackgroundColor();
+                        }
                     }
                 }
             }
diff --git a/sw/source/core/layout/anchoredobject.cxx 
b/sw/source/core/layout/anchoredobject.cxx
index 42e7dd39fcd2..fe959a688723 100644
--- a/sw/source/core/layout/anchoredobject.cxx
+++ b/sw/source/core/layout/anchoredobject.cxx
@@ -32,6 +32,7 @@
 #include <layouter.hxx>
 #include <osl/diagnose.h>
 #include <flyfrms.hxx>
+#include <dcontact.hxx>
 
 using namespace ::com::sun::star;
 
@@ -98,6 +99,8 @@ void SwAnchoredObject::ClearVertPosOrientFrame()
     }
 }
 
+bool SwAnchoredObject::HasFrameFormat() const { return 
GetUserCall(GetDrawObj()); }
+
 SwAnchoredObject::~SwAnchoredObject()
 {
     ClearVertPosOrientFrame();
@@ -408,29 +411,33 @@ bool SwAnchoredObject::ConsiderObjWrapInfluenceOnObjPos() 
const
 {
     bool bRet( false );
 
-    const SwFrameFormat& rObjFormat = GetFrameFormat();
-
-    // --> #i3317# - add condition <IsTmpConsiderWrapInfluence()>
-    // --> #i55204#
-    // - correction: wrapping style influence has been considered, if condition
-    //   <IsTmpConsiderWrapInfluence()> is hold, regardless of its anchor type
-    //   or its wrapping style.
-    if ( IsTmpConsiderWrapInfluence() )
+    if (HasFrameFormat())
     {
-        bRet = true;
-    }
-    else if ( 
rObjFormat.getIDocumentSettingAccess().get(DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION)
 )
-    {
-        const SwFormatAnchor& rAnchor = rObjFormat.GetAnchor();
-        if ( ((rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR) ||
-              (rAnchor.GetAnchorId() == RndStdIds::FLY_AT_PARA)) &&
-             rObjFormat.GetSurround().GetSurround() != 
css::text::WrapTextMode_THROUGH )
+        const SwFrameFormat& rObjFormat = GetFrameFormat();
+
+        // --> #i3317# - add condition <IsTmpConsiderWrapInfluence()>
+        // --> #i55204#
+        // - correction: wrapping style influence has been considered, if 
condition
+        //   <IsTmpConsiderWrapInfluence()> is hold, regardless of its anchor 
type
+        //   or its wrapping style.
+        if (IsTmpConsiderWrapInfluence())
         {
-            // --> #i34520# - text also wraps around anchored
-            // objects in the layer Hell - see the text formatting.
-            // Thus, it hasn't to be checked here.
             bRet = true;
         }
+        else if (rObjFormat.getIDocumentSettingAccess().get(
+                     DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION))
+        {
+            const SwFormatAnchor& rAnchor = rObjFormat.GetAnchor();
+            if (((rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR)
+                 || (rAnchor.GetAnchorId() == RndStdIds::FLY_AT_PARA))
+                && rObjFormat.GetSurround().GetSurround() != 
css::text::WrapTextMode_THROUGH)
+            {
+                // --> #i34520# - text also wraps around anchored
+                // objects in the layer Hell - see the text formatting.
+                // Thus, it hasn't to be checked here.
+                bRet = true;
+            }
+        }
     }
 
     return bRet;
@@ -567,18 +574,23 @@ const SwRect& SwAnchoredObject::GetObjRectWithSpaces() 
const
     if ( !mbObjRectWithSpacesValid )
     {
         maObjRectWithSpaces = GetObjBoundRect();
-        const SwFrameFormat& rFormat = GetFrameFormat();
-        const SvxULSpaceItem& rUL = rFormat.GetULSpace();
-        const SvxLRSpaceItem& rLR = rFormat.GetLRSpace();
+        if (HasFrameFormat())
         {
-            maObjRectWithSpaces.Top ( std::max( maObjRectWithSpaces.Top() - 
tools::Long(rUL.GetUpper()), tools::Long(0) ));
-            maObjRectWithSpaces.Left( std::max( maObjRectWithSpaces.Left()- 
rLR.GetLeft(),  tools::Long(0) ));
-            maObjRectWithSpaces.AddHeight(rUL.GetLower() );
-            maObjRectWithSpaces.AddWidth(rLR.GetRight() );
-        }
+            const SwFrameFormat& rFormat = GetFrameFormat();
+            const SvxULSpaceItem& rUL = rFormat.GetULSpace();
+            const SvxLRSpaceItem& rLR = rFormat.GetLRSpace();
+            {
+                maObjRectWithSpaces.Top(std::max(
+                    maObjRectWithSpaces.Top() - tools::Long(rUL.GetUpper()), 
tools::Long(0)));
+                maObjRectWithSpaces.Left(
+                    std::max(maObjRectWithSpaces.Left() - rLR.GetLeft(), 
tools::Long(0)));
+                maObjRectWithSpaces.AddHeight(rUL.GetLower());
+                maObjRectWithSpaces.AddWidth(rLR.GetRight());
+            }
 
-        mbObjRectWithSpacesValid = true;
-        maLastObjRect = GetObjRect();
+            mbObjRectWithSpacesValid = true;
+            maLastObjRect = GetObjRect();
+        }
     }
 
     return maObjRectWithSpaces;
@@ -709,39 +721,43 @@ SwTextFrame* SwAnchoredObject::FindAnchorCharFrame()
     // --> #i44339# - check, if anchor frame exists.
     if ( mpAnchorFrame )
     {
-        const SwFormatAnchor& rAnch = GetFrameFormat().GetAnchor();
-        if ((rAnch.GetAnchorId() == RndStdIds::FLY_AT_CHAR) ||
-            (rAnch.GetAnchorId() == RndStdIds::FLY_AS_CHAR))
+        if (HasFrameFormat())
         {
-            SwTextFrame *const 
pFrame(static_cast<SwTextFrame*>(AnchorFrame()));
-            TextFrameIndex const 
nOffset(pFrame->MapModelToViewPos(*rAnch.GetContentAnchor()));
-            pAnchorCharFrame = &pFrame->GetFrameAtOfst(nOffset);
-        }
-        else if (SwFlyFrame* pFlyFrame = DynCastFlyFrame())
-        {
-            // See if this fly is split. If so, then the anchor is also split. 
All anchors are
-            // empty, except the last follow.
-            if (pFlyFrame->IsFlySplitAllowed())
+            const SwFormatAnchor& rAnch = GetFrameFormat().GetAnchor();
+            if ((rAnch.GetAnchorId() == RndStdIds::FLY_AT_CHAR)
+                || (rAnch.GetAnchorId() == RndStdIds::FLY_AS_CHAR))
             {
-                auto pFlyAtContentFrame = 
static_cast<SwFlyAtContentFrame*>(pFlyFrame);
-                SwFlyAtContentFrame* pFly = pFlyAtContentFrame;
-                SwTextFrame* pAnchor = 
static_cast<SwTextFrame*>(AnchorFrame());
-                // If we have to jump back N frames to find the master fly, 
then we have to step N
-                // frames from the master anchor to reach the correct follow 
anchor.
-                while (pFly->GetPrecede())
+                SwTextFrame* const 
pFrame(static_cast<SwTextFrame*>(AnchorFrame()));
+                TextFrameIndex const 
nOffset(pFrame->MapModelToViewPos(*rAnch.GetContentAnchor()));
+                pAnchorCharFrame = &pFrame->GetFrameAtOfst(nOffset);
+            }
+            else if (SwFlyFrame* pFlyFrame = DynCastFlyFrame())
+            {
+                // See if this fly is split. If so, then the anchor is also 
split. All anchors are
+                // empty, except the last follow.
+                if (pFlyFrame->IsFlySplitAllowed())
                 {
-                    pFly = pFly->GetPrecede();
-                    if (!pAnchor)
+                    auto pFlyAtContentFrame = 
static_cast<SwFlyAtContentFrame*>(pFlyFrame);
+                    SwFlyAtContentFrame* pFly = pFlyAtContentFrame;
+                    SwTextFrame* pAnchor = 
static_cast<SwTextFrame*>(AnchorFrame());
+                    // If we have to jump back N frames to find the master 
fly, then we have to step N
+                    // frames from the master anchor to reach the correct 
follow anchor.
+                    while (pFly->GetPrecede())
                     {
-                        SAL_WARN("sw.layout", 
"SwAnchoredObject::FindAnchorCharFrame: fly chain "
-                                              "length is longer then anchor 
chain length");
-                        break;
+                        pFly = pFly->GetPrecede();
+                        if (!pAnchor)
+                        {
+                            SAL_WARN("sw.layout",
+                                     "SwAnchoredObject::FindAnchorCharFrame: 
fly chain "
+                                     "length is longer then anchor chain 
length");
+                            break;
+                        }
+                        pAnchor = pAnchor->GetFollow();
+                    }
+                    if (pAnchor)
+                    {
+                        pAnchorCharFrame = pAnchor;
                     }
-                    pAnchor = pAnchor->GetFollow();
-                }
-                if (pAnchor)
-                {
-                    pAnchorCharFrame = pAnchor;
                 }
             }
         }
@@ -758,7 +774,9 @@ SwTextFrame* SwAnchoredObject::FindAnchorCharFrame()
 */
 bool SwAnchoredObject::IsFormatPossible() const
 {
-    return 
GetFrameFormat().GetDoc()->getIDocumentDrawModelAccess().IsVisibleLayerId( 
GetDrawObj()->GetLayer() );
+    if (HasFrameFormat())
+        return 
GetFrameFormat().GetDoc()->getIDocumentDrawModelAccess().IsVisibleLayerId( 
GetDrawObj()->GetLayer() );
+    return false;
 }
 
 bool SwAnchoredObject::IsDraggingOffPageAllowed(const SwFrameFormat* 
pFrameFormat)
diff --git a/sw/source/core/layout/flylay.cxx b/sw/source/core/layout/flylay.cxx
index 457a0d41bbf3..66e27adb8f47 100644
--- a/sw/source/core/layout/flylay.cxx
+++ b/sw/source/core/layout/flylay.cxx
@@ -1140,8 +1140,9 @@ void SwPageFrame::RemoveDrawObjFromPage( 
SwAnchoredObject& _rToRemoveObj )
         }
         if ( GetUpper() )
         {
-            if (RndStdIds::FLY_AS_CHAR !=
-                    _rToRemoveObj.GetFrameFormat().GetAnchor().GetAnchorId())
+            if (_rToRemoveObj.HasFrameFormat()
+                && RndStdIds::FLY_AS_CHAR
+                       != 
_rToRemoveObj.GetFrameFormat().GetAnchor().GetAnchorId())
             {
                 static_cast<SwRootFrame*>(GetUpper())->SetSuperfluous();
                 InvalidatePage();
@@ -1454,63 +1455,67 @@ bool CalcClipRect( const SdrObject *pSdrObj, SwRect 
&rRect, bool bMove )
     }
     else
     {
-        const SwDrawContact *pC = static_cast<const 
SwDrawContact*>(GetUserCall(pSdrObj));
-        const SwFrameFormat  *pFormat = pC->GetFormat();
-        const SwFormatAnchor &rAnch = pFormat->GetAnchor();
-        if ( RndStdIds::FLY_AS_CHAR == rAnch.GetAnchorId() )
+        if (const SwDrawContact* pC = static_cast<const 
SwDrawContact*>(GetUserCall(pSdrObj)))
         {
-            const SwFrame* pAnchorFrame = pC->GetAnchorFrame( pSdrObj );
-            if( !pAnchorFrame )
+            const SwFrameFormat* pFormat = pC->GetFormat();
+            const SwFormatAnchor& rAnch = pFormat->GetAnchor();
+            if (RndStdIds::FLY_AS_CHAR == rAnch.GetAnchorId())
             {
-                OSL_FAIL( "<::CalcClipRect(..)> - missing anchor frame." );
-                const_cast<SwDrawContact*>(pC)->ConnectToLayout();
-                pAnchorFrame = pC->GetAnchorFrame();
-            }
-            const SwFrame* pUp = pAnchorFrame->GetUpper();
-            rRect = pUp->getFramePrintArea();
-            rRect += pUp->getFrameArea().Pos();
-            SwRectFnSet aRectFnSet(pAnchorFrame);
-            tools::Long nHeight = (9*aRectFnSet.GetHeight(rRect))/10;
-            tools::Long nTop;
-            const SvxULSpaceItem &rUL = pFormat->GetULSpace();
-            SwRect aSnapRect( pSdrObj->GetSnapRect() );
-            tools::Long nTmpH = 0;
-            if( bMove )
-            {
-                nTop = aRectFnSet.YInc( aRectFnSet.IsVert() ? 
pSdrObj->GetAnchorPos().X() :
-                                       pSdrObj->GetAnchorPos().Y(), -nHeight );
-                tools::Long nWidth = aRectFnSet.GetWidth(aSnapRect);
-                aRectFnSet.SetLeftAndWidth( rRect, aRectFnSet.IsVert() ?
-                            pSdrObj->GetAnchorPos().Y() :
-                            pSdrObj->GetAnchorPos().X(), nWidth );
-            }
-            else
-            {
-                // #i26791# - value of <nTmpH> is needed to
-                // calculate value of <nTop>.
-                nTmpH = aRectFnSet.IsVert() ? 
pSdrObj->GetCurrentBoundRect().GetWidth() :
-                                       
pSdrObj->GetCurrentBoundRect().GetHeight();
-                nTop = aRectFnSet.YInc( aRectFnSet.GetTop(aSnapRect),
-                                          rUL.GetLower() + nTmpH - nHeight );
-            }
-            nHeight = 2*nHeight - nTmpH - rUL.GetLower() - rUL.GetUpper();
-            aRectFnSet.SetTopAndHeight( rRect, nTop, nHeight );
-        }
-        else
-        {
-            // restrict clip rectangle for drawing
-            // objects in header/footer to the page frame.
-            // #i26791#
-            const SwFrame* pAnchorFrame = pC->GetAnchorFrame( pSdrObj );
-            if ( pAnchorFrame && pAnchorFrame->FindFooterOrHeader() )
-            {
-                // clip frame is the page frame the header/footer is on.
-                const SwFrame* pClipFrame = pAnchorFrame->FindPageFrame();
-                rRect = pClipFrame->getFrameArea();
+                const SwFrame* pAnchorFrame = pC->GetAnchorFrame(pSdrObj);
+                if (!pAnchorFrame)
+                {
+                    OSL_FAIL("<::CalcClipRect(..)> - missing anchor frame.");
+                    const_cast<SwDrawContact*>(pC)->ConnectToLayout();
+                    pAnchorFrame = pC->GetAnchorFrame();
+                }
+                const SwFrame* pUp = pAnchorFrame->GetUpper();
+                rRect = pUp->getFramePrintArea();
+                rRect += pUp->getFrameArea().Pos();
+                SwRectFnSet aRectFnSet(pAnchorFrame);
+                tools::Long nHeight = (9 * aRectFnSet.GetHeight(rRect)) / 10;
+                tools::Long nTop;
+                const SvxULSpaceItem& rUL = pFormat->GetULSpace();
+                SwRect aSnapRect(pSdrObj->GetSnapRect());
+                tools::Long nTmpH = 0;
+                if (bMove)
+                {
+                    nTop = aRectFnSet.YInc(aRectFnSet.IsVert() ? 
pSdrObj->GetAnchorPos().X()
+                                                               : 
pSdrObj->GetAnchorPos().Y(),
+                                           -nHeight);
+                    tools::Long nWidth = aRectFnSet.GetWidth(aSnapRect);
+                    aRectFnSet.SetLeftAndWidth(rRect,
+                                               aRectFnSet.IsVert() ? 
pSdrObj->GetAnchorPos().Y()
+                                                                   : 
pSdrObj->GetAnchorPos().X(),
+                                               nWidth);
+                }
+                else
+                {
+                    // #i26791# - value of <nTmpH> is needed to
+                    // calculate value of <nTop>.
+                    nTmpH = aRectFnSet.IsVert() ? 
pSdrObj->GetCurrentBoundRect().GetWidth()
+                                                : 
pSdrObj->GetCurrentBoundRect().GetHeight();
+                    nTop = aRectFnSet.YInc(aRectFnSet.GetTop(aSnapRect),
+                                           rUL.GetLower() + nTmpH - nHeight);
+                }
+                nHeight = 2 * nHeight - nTmpH - rUL.GetLower() - 
rUL.GetUpper();
+                aRectFnSet.SetTopAndHeight(rRect, nTop, nHeight);
             }
             else
             {
-                bRet = false;
+                // restrict clip rectangle for drawing
+                // objects in header/footer to the page frame.
+                // #i26791#
+                const SwFrame* pAnchorFrame = pC->GetAnchorFrame(pSdrObj);
+                if (pAnchorFrame && pAnchorFrame->FindFooterOrHeader())
+                {
+                    // clip frame is the page frame the header/footer is on.
+                    const SwFrame* pClipFrame = pAnchorFrame->FindPageFrame();
+                    rRect = pClipFrame->getFrameArea();
+                }
+                else
+                {
+                    bRet = false;
+                }
             }
         }
     }
diff --git a/sw/source/core/layout/frmtool.cxx 
b/sw/source/core/layout/frmtool.cxx
index c3fa35fcdc7b..c4dbb28f0073 100644
--- a/sw/source/core/layout/frmtool.cxx
+++ b/sw/source/core/layout/frmtool.cxx
@@ -3404,8 +3404,10 @@ void Notify_Background( const SdrObject* pObj,
     else
     {
         pFlyFrame = nullptr;
-        pAnchor = const_cast<SwFrame*>(
-                    GetUserCall(pObj)->GetAnchoredObj( pObj 
)->GetAnchorFrame() );
+        if (SwDrawContact* pC = static_cast<SwDrawContact*>(GetUserCall(pObj)))
+            pAnchor = 
const_cast<SwFrame*>(pC->GetAnchoredObj(pObj)->GetAnchorFrame());
+        else
+            return;
     }
     if( PrepareHint::FlyFrameLeave != eHint && pAnchor->IsInFly() )
         pArea = pAnchor->FindFlyFrame();
diff --git a/sw/source/core/layout/sortedobjs.cxx 
b/sw/source/core/layout/sortedobjs.cxx
index ce581bb663ef..1e5f1aa293be 100644
--- a/sw/source/core/layout/sortedobjs.cxx
+++ b/sw/source/core/layout/sortedobjs.cxx
@@ -78,10 +78,14 @@ struct ObjAnchorOrder
                      const SwAnchoredObject* _pNewAnchoredObj )
     {
         // get attributes of listed object
+        if (!_pListedAnchoredObj->HasFrameFormat())
+            return false;
         const SwFrameFormat& rFormatListed = 
_pListedAnchoredObj->GetFrameFormat();
         const SwFormatAnchor* pAnchorListed = &(rFormatListed.GetAnchor());
 
         // get attributes of new object
+        if (!_pNewAnchoredObj->HasFrameFormat())
+            return false;
         const SwFrameFormat& rFormatNew = _pNewAnchoredObj->GetFrameFormat();
         const SwFormatAnchor* pAnchorNew = &(rFormatNew.GetAnchor());
 
diff --git a/sw/source/core/text/txtfly.cxx b/sw/source/core/text/txtfly.cxx
index ff5566f537ac..6d25e4c96581 100644
--- a/sw/source/core/text/txtfly.cxx
+++ b/sw/source/core/text/txtfly.cxx
@@ -768,78 +768,85 @@ bool SwTextFly::GetTop( const SwAnchoredObject* 
_pAnchoredObj,
         if ( bEvade )
         {
             // #i26945#
-            const SwFormatAnchor& rNewA = 
_pAnchoredObj->GetFrameFormat().GetAnchor();
-            OSL_ENSURE( RndStdIds::FLY_AS_CHAR != rNewA.GetAnchorId(),
-                    "Don't call GetTop with a FlyInContentFrame" );
-            if (RndStdIds::FLY_AT_PAGE == rNewA.GetAnchorId())
-                return true;  // We always avoid page anchored ones
-
-            // If Flys anchored at paragraph are caught in a FlyCnt, then
-            // their influence ends at the borders of the FlyCnt!
-            // If we are currently formatting the text of the FlyCnt, then
-            // it has to get out of the way of the Frame anchored at paragraph!
-            // m_pCurrFrame is the anchor of pNew?
-            // #i26945#
-            const SwFrame* pTmp = _pAnchoredObj->GetAnchorFrame();
-            if (pTmp == m_pCurrFrame)
-                return true;
-            if( pTmp->IsTextFrame() && ( pTmp->IsInFly() || 
pTmp->IsInFootnote() ) )
+            if (_pAnchoredObj->HasFrameFormat())
             {
+                const SwFormatAnchor& rNewA = 
_pAnchoredObj->GetFrameFormat().GetAnchor();
+                OSL_ENSURE(RndStdIds::FLY_AS_CHAR != rNewA.GetAnchorId(),
+                           "Don't call GetTop with a FlyInContentFrame");
+                if (RndStdIds::FLY_AT_PAGE == rNewA.GetAnchorId())
+                    return true; // We always avoid page anchored ones
+
+                // If Flys anchored at paragraph are caught in a FlyCnt, then
+                // their influence ends at the borders of the FlyCnt!
+                // If we are currently formatting the text of the FlyCnt, then
+                // it has to get out of the way of the Frame anchored at 
paragraph!
+                // m_pCurrFrame is the anchor of pNew?
                 // #i26945#
-                Point aPos = _pAnchoredObj->GetObjRect().Pos();
-                pTmp = GetVirtualUpper( pTmp, aPos );
-            }
-            // #i26945#
-            // If <pTmp> is a text frame inside a table, take the upper
-            // of the anchor frame, which contains the anchor position.
-            else if ( pTmp->IsTextFrame() && pTmp->IsInTab() )
-            {
-                pTmp = const_cast<SwAnchoredObject*>(_pAnchoredObj)
-                                
->GetAnchorFrameContainingAnchPos()->GetUpper();
-            }
-            // #i28701# - consider all objects in same context,
-            // if wrapping style is considered on object positioning.
-            // Thus, text will wrap around negative positioned objects.
-            // #i3317# - remove condition on checking,
-            // if wrappings style is considered on object positioning.
-            // Thus, text is wrapping around negative positioned objects.
-            // #i35640# - no consideration of negative
-            // positioned objects, if wrapping style isn't considered on
-            // object position and former text wrapping is applied.
-            // This condition is typically for documents imported from the
-            // OpenOffice.org file format.
-            const IDocumentSettingAccess* pIDSA = 
&m_pCurrFrame->GetDoc().getIDocumentSettingAccess();
-            if ( (  
pIDSA->get(DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION) ||
-                   !pIDSA->get(DocumentSettingId::USE_FORMER_TEXT_WRAPPING) ) 
&&
-                 ::FindContext( pTmp, SwFrameType::None ) == 
::FindContext(m_pCurrFrame, SwFrameType::None))
-            {
-                return true;
-            }
-
-            const SwFrame* pHeader = nullptr;
-            if (m_pCurrFrame->GetNext() != pTmp &&
-                 (IsFrameInSameContext( pTmp, m_pCurrFrame ) ||
-                   // #i13832#, #i24135# wrap around objects in page header
-                   ( !pIDSA->get(DocumentSettingId::USE_FORMER_TEXT_WRAPPING) 
&&
-                     nullptr != ( pHeader = pTmp->FindFooterOrHeader() ) &&
-                     m_pCurrFrame->IsInDocBody())))
-            {
-                if( pHeader || RndStdIds::FLY_AT_FLY == rNewA.GetAnchorId() )
+                const SwFrame* pTmp = _pAnchoredObj->GetAnchorFrame();
+                if (pTmp == m_pCurrFrame)
                     return true;
-
-                // Compare indices:
-                // The Index of the other is retrieved from the anchor attr.
-                SwNodeOffset nTmpIndex = rNewA.GetAnchorNode()->GetIndex();
-                // Now check whether the current paragraph is before the anchor
-                // of the displaced object in the text, then we don't have to
-                // get out of its way.
-                // If possible determine Index via SwFormatAnchor because
-                // otherwise it's quite expensive.
-                if (NODE_OFFSET_MAX == m_nCurrFrameNodeIndex)
-                    m_nCurrFrameNodeIndex = 
m_pCurrFrame->GetTextNodeFirst()->GetIndex();
-
-                if (FrameContainsNode(*m_pCurrFrame, nTmpIndex) || nTmpIndex < 
m_nCurrFrameNodeIndex)
+                if (pTmp->IsTextFrame() && (pTmp->IsInFly() || 
pTmp->IsInFootnote()))
+                {
+                    // #i26945#
+                    Point aPos = _pAnchoredObj->GetObjRect().Pos();
+                    pTmp = GetVirtualUpper(pTmp, aPos);
+                }
+                // #i26945#
+                // If <pTmp> is a text frame inside a table, take the upper
+                // of the anchor frame, which contains the anchor position.
+                else if (pTmp->IsTextFrame() && pTmp->IsInTab())
+                {
+                    pTmp = const_cast<SwAnchoredObject*>(_pAnchoredObj)
+                               ->GetAnchorFrameContainingAnchPos()
+                               ->GetUpper();
+                }
+                // #i28701# - consider all objects in same context,
+                // if wrapping style is considered on object positioning.
+                // Thus, text will wrap around negative positioned objects.
+                // #i3317# - remove condition on checking,
+                // if wrappings style is considered on object positioning.
+                // Thus, text is wrapping around negative positioned objects.
+                // #i35640# - no consideration of negative
+                // positioned objects, if wrapping style isn't considered on
+                // object position and former text wrapping is applied.
+                // This condition is typically for documents imported from the
+                // OpenOffice.org file format.
+                const IDocumentSettingAccess* pIDSA
+                    = &m_pCurrFrame->GetDoc().getIDocumentSettingAccess();
+                if 
((pIDSA->get(DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION)
+                     || 
!pIDSA->get(DocumentSettingId::USE_FORMER_TEXT_WRAPPING))
+                    && ::FindContext(pTmp, SwFrameType::None)
+                           == ::FindContext(m_pCurrFrame, SwFrameType::None))
+                {
                     return true;
+                }
+
+                const SwFrame* pHeader = nullptr;
+                if (m_pCurrFrame->GetNext() != pTmp
+                    && (IsFrameInSameContext(pTmp, m_pCurrFrame) ||
+                        // #i13832#, #i24135# wrap around objects in page 
header
+                        
(!pIDSA->get(DocumentSettingId::USE_FORMER_TEXT_WRAPPING)
+                         && nullptr != (pHeader = pTmp->FindFooterOrHeader())
+                         && m_pCurrFrame->IsInDocBody())))
+                {
+                    if (pHeader || RndStdIds::FLY_AT_FLY == 
rNewA.GetAnchorId())
+                        return true;
+
+                    // Compare indices:
+                    // The Index of the other is retrieved from the anchor 
attr.
+                    SwNodeOffset nTmpIndex = rNewA.GetAnchorNode()->GetIndex();
+                    // Now check whether the current paragraph is before the 
anchor
+                    // of the displaced object in the text, then we don't have 
to
+                    // get out of its way.
+                    // If possible determine Index via SwFormatAnchor because
+                    // otherwise it's quite expensive.
+                    if (NODE_OFFSET_MAX == m_nCurrFrameNodeIndex)
+                        m_nCurrFrameNodeIndex = 
m_pCurrFrame->GetTextNodeFirst()->GetIndex();
+
+                    if (FrameContainsNode(*m_pCurrFrame, nTmpIndex)
+                        || nTmpIndex < m_nCurrFrameNodeIndex)
+                        return true;
+                }
             }
         }
     }
diff --git a/sw/source/uibase/docvw/edtwin.cxx 
b/sw/source/uibase/docvw/edtwin.cxx
index e89614319903..f01cf9256c74 100644
--- a/sw/source/uibase/docvw/edtwin.cxx
+++ b/sw/source/uibase/docvw/edtwin.cxx
@@ -4662,19 +4662,23 @@ void SwEditWin::MouseButtonUp(const MouseEvent& rMEvt)
             SdrObject* pObj = pSdrView ? pSdrView->PickObj(aDocPos, 
pSdrView->getHitTolLog(), pPV, SdrSearchOptions::ALSOONMASTER) : nullptr;
             if (pObj)
             {
-                SwFrameFormat* pFormat = GetUserCall(pObj)->GetFormat();
-                SwFrameFormat* pShapeFormat = 
SwTextBoxHelper::getOtherTextBoxFormat(pFormat, RES_FLYFRMFMT);
-                if (!pShapeFormat)
+                if (SwDrawContact* pContact = 
static_cast<SwDrawContact*>(GetUserCall(pObj)))
                 {
-                    pSdrView->UnmarkAllObj();
-                    pSdrView->MarkObj(pObj,pPV);
-                }
-                else
-                {
-                    // If the fly frame is a textbox of a shape, then select 
the shape instead.
-                    SdrObject* pShape = pShapeFormat->FindSdrObject();
-                    pSdrView->UnmarkAllObj();
-                    pSdrView->MarkObj(pShape, pPV);
+                    SwFrameFormat* pFormat = pContact->GetFormat();
+                    SwFrameFormat* pShapeFormat
+                        = SwTextBoxHelper::getOtherTextBoxFormat(pFormat, 
RES_FLYFRMFMT);
+                    if (!pShapeFormat)
+                    {
+                        pSdrView->UnmarkAllObj();
+                        pSdrView->MarkObj(pObj, pPV);
+                    }
+                    else
+                    {
+                        // If the fly frame is a textbox of a shape, then 
select the shape instead.
+                        SdrObject* pShape = pShapeFormat->FindSdrObject();
+                        pSdrView->UnmarkAllObj();
+                        pSdrView->MarkObj(pShape, pPV);
+                    }
                 }
             }
         }
diff --git a/sw/source/uibase/shells/drwbassh.cxx 
b/sw/source/uibase/shells/drwbassh.cxx
index a5a63a66343d..d5eec2132093 100644
--- a/sw/source/uibase/shells/drwbassh.cxx
+++ b/sw/source/uibase/shells/drwbassh.cxx
@@ -836,8 +836,12 @@ void SwDrawBaseShell::GetState(SfxItemSet& rSet)
 
                         SdrObject* pObj = 
rMarkList.GetMark(0)->GetMarkedSdrObj();
                         SwFrameFormat* pFrameFormat = FindFrameFormat(pObj);
-                        SwFormatHoriOrient 
aHOrient(pFrameFormat->GetFormatAttr(RES_HORI_ORIENT));
-                        rSet.Put(SfxBoolItem(nWhich, aHOrient.GetHoriOrient() 
== nHoriOrient));
+                        if (pFrameFormat)
+                        {
+                            SwFormatHoriOrient aHOrient(
+                                pFrameFormat->GetFormatAttr(RES_HORI_ORIENT));
+                            rSet.Put(SfxBoolItem(nWhich, 
aHOrient.GetHoriOrient() == nHoriOrient));
+                        }
                     }
 
                     if (bVert && !bDisableThis && rMarkList.GetMarkCount() == 
1)
@@ -860,8 +864,12 @@ void SwDrawBaseShell::GetState(SfxItemSet& rSet)
 
                         SdrObject* pObj = 
rMarkList.GetMark(0)->GetMarkedSdrObj();
                         SwFrameFormat* pFrameFormat = FindFrameFormat(pObj);
-                        SwFormatVertOrient 
aVOrient(pFrameFormat->GetFormatAttr(RES_VERT_ORIENT));
-                        rSet.Put(SfxBoolItem(nWhich, aVOrient.GetVertOrient() 
== nVertOrient));
+                        if (pFrameFormat)
+                        {
+                            SwFormatVertOrient aVOrient(
+                                pFrameFormat->GetFormatAttr(RES_VERT_ORIENT));
+                            rSet.Put(SfxBoolItem(nWhich, 
aVOrient.GetVertOrient() == nVertOrient));
+                        }
                     }
                 }
                 break;

Reply via email to