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

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