Blame SOURCES/0001-tdf-99460-sw-layout-don-t-split-table-before-fly.patch

f325b2
From ac0400203d643242d5d4363590668ad5c667faba Mon Sep 17 00:00:00 2001
f325b2
From: Michael Stahl <mstahl@redhat.com>
f325b2
Date: Fri, 22 Apr 2016 18:09:39 +0200
f325b2
Subject: [PATCH] tdf#99460 sw: layout: don't split table before fly
f325b2
f325b2
First the table is formatted properly and then the following paragraph
f325b2
is formatted, along with its anchored objects.
f325b2
The Fly frame is aligned to the bottom of the page by
f325b2
SwAnchoredObjectPosition::_AdjustVerRelPos() without checking for any
f325b2
overlap, and thus overlaps the table.
f325b2
Then SwFlyNotify and Notify_Background() invalidate the table's PrtArea,
f325b2
and the table responds by splitting numerous times, until finally there
f325b2
is a page where the table does not overlap with the fly any more.
f325b2
Instead of the table splitting, the paragraph with the Fly anchored to
f325b2
it should move to the next page; suppressing the table invalidation in
f325b2
Notify_Background() appears to achieve that.
f325b2
f325b2
Change-Id: If65879f1756856bda344e0ef8fbffbc33e80f3ec
f325b2
Reviewed-on: https://gerrit.libreoffice.org/24307
f325b2
Tested-by: Jenkins <ci@libreoffice.org>
f325b2
Reviewed-by: Michael Stahl <mstahl@redhat.com>
f325b2
---
f325b2
 sw/source/core/layout/frmtool.cxx | 51 ++++++++++++++++++++++++++++-----------
f325b2
 1 file changed, 37 insertions(+), 14 deletions(-)
f325b2
f325b2
diff --git a/sw/source/core/layout/frmtool.cxx b/sw/source/core/layout/frmtool.cxx
f325b2
index 72bfaef..f73402d 100644
f325b2
--- a/sw/source/core/layout/frmtool.cxx
f325b2
+++ b/sw/source/core/layout/frmtool.cxx
f325b2
@@ -2962,37 +2962,60 @@ void Notify_Background( const SdrObject* pObj,
f325b2
     }
f325b2
     SwFrm *pLastTab = 0;
f325b2
 
f325b2
+    bool isValidTableBeforeAnchor(false);
f325b2
     while ( pCnt && pArea && pArea->IsAnLower( pCnt ) )
f325b2
     {
f325b2
         ::lcl_NotifyContent( pObj, pCnt, rRect, eHint );
f325b2
         if ( pCnt->IsInTab() )
f325b2
         {
f325b2
-            SwLayoutFrm* pCell = pCnt->GetUpper();
f325b2
-            // #i40606# - use <GetLastBoundRect()>
f325b2
-            // instead of <GetCurrentBoundRect()>, because a recalculation
f325b2
-            // of the bounding rectangle isn't intended here.
f325b2
-            if ( pCell->IsCellFrm() &&
f325b2
-                 ( pCell->Frm().IsOver( pObj->GetLastBoundRect() ) ||
f325b2
-                   pCell->Frm().IsOver( rRect ) ) )
f325b2
-            {
f325b2
-                const SwFormatVertOrient &rOri = pCell->GetFormat()->GetVertOrient();
f325b2
-                if ( text::VertOrientation::NONE != rOri.GetVertOrient() )
f325b2
-                    pCell->InvalidatePrt();
f325b2
-            }
f325b2
             SwTabFrm *pTab = pCnt->FindTabFrm();
f325b2
             if ( pTab != pLastTab )
f325b2
             {
f325b2
                 pLastTab = pTab;
f325b2
+                isValidTableBeforeAnchor = false;
f325b2
+                if (PREP_FLY_ARRIVE == eHint
f325b2
+                    && pFlyFrm // TODO: do it for draw objects too?
f325b2
+                    && pTab->IsFollow() // table starts on previous page?
f325b2
+                    // "through" means they will actually overlap anyway
f325b2
+                    && SURROUND_THROUGHT != pFlyFrm->GetFormat()->GetSurround().GetSurround()
f325b2
+                    // if it's anchored in footer it can't move to other page
f325b2
+                    && !pAnchor->FindFooterOrHeader())
f325b2
+                {
f325b2
+                    SwFrm * pTmp(pAnchor->GetPrev());
f325b2
+                    while (pTmp)
f325b2
+                    {
f325b2
+                        if (pTmp == pTab)
f325b2
+                        {
f325b2
+                            // tdf#99460 the table shouldn't be moved by the fly
f325b2
+                            isValidTableBeforeAnchor = true;
f325b2
+                            break;
f325b2
+                        }
f325b2
+                        pTmp = pTmp->GetPrev();
f325b2
+                    }
f325b2
+                }
f325b2
                 // #i40606# - use <GetLastBoundRect()>
f325b2
                 // instead of <GetCurrentBoundRect()>, because a recalculation
f325b2
                 // of the bounding rectangle isn't intended here.
f325b2
-                if ( pTab->Frm().IsOver( pObj->GetLastBoundRect() ) ||
f325b2
-                     pTab->Frm().IsOver( rRect ) )
f325b2
+                if (!isValidTableBeforeAnchor
f325b2
+                    && (pTab->Frm().IsOver(pObj->GetLastBoundRect()) ||
f325b2
+                        pTab->Frm().IsOver(rRect)))
f325b2
                 {
f325b2
                     if ( !pFlyFrm || !pFlyFrm->IsLowerOf( pTab ) )
f325b2
                         pTab->InvalidatePrt();
f325b2
                 }
f325b2
             }
f325b2
+            SwLayoutFrm* pCell = pCnt->GetUpper();
f325b2
+            // #i40606# - use <GetLastBoundRect()>
f325b2
+            // instead of <GetCurrentBoundRect()>, because a recalculation
f325b2
+            // of the bounding rectangle isn't intended here.
f325b2
+            if (!isValidTableBeforeAnchor && pCell->IsCellFrm() &&
f325b2
+                 ( pCell->Frm().IsOver( pObj->GetLastBoundRect() ) ||
f325b2
+                   pCell->Frm().IsOver( rRect ) ) )
f325b2
+            {
f325b2
+                const SwFormatVertOrient &rOri = pCell->GetFormat()->GetVertOrient();
f325b2
+                if ( text::VertOrientation::NONE != rOri.GetVertOrient() )
f325b2
+                    pCell->InvalidatePrt();
f325b2
+            }
f325b2
         }
f325b2
         pCnt = pCnt->GetNextContentFrm();
f325b2
     }
f325b2
-- 
f325b2
2.7.3
f325b2