[Libreoffice-commits] core.git: Branch 'libreoffice-5-1' - sw/source

Michael Stahl mstahl at redhat.com
Thu Apr 28 06:48:14 UTC 2016


 sw/source/core/layout/frmtool.cxx |   51 +++++++++++++++++++++++++++-----------
 1 file changed, 37 insertions(+), 14 deletions(-)

New commits:
commit ec1a2322b862468621ce45500d74dac252bf1714
Author: Michael Stahl <mstahl at redhat.com>
Date:   Fri Apr 22 18:09:39 2016 +0200

    tdf#99460 sw: layout: don't split table before fly
    
    First the table is formatted properly and then the following paragraph
    is formatted, along with its anchored objects.
    The Fly frame is aligned to the bottom of the page by
    SwAnchoredObjectPosition::_AdjustVerRelPos() without checking for any
    overlap, and thus overlaps the table.
    Then SwFlyNotify and Notify_Background() invalidate the table's PrtArea,
    and the table responds by splitting numerous times, until finally there
    is a page where the table does not overlap with the fly any more.
    Instead of the table splitting, the paragraph with the Fly anchored to
    it should move to the next page; suppressing the table invalidation in
    Notify_Background() appears to achieve that.
    
    Change-Id: If65879f1756856bda344e0ef8fbffbc33e80f3ec
    Reviewed-on: https://gerrit.libreoffice.org/24307
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Michael Stahl <mstahl at redhat.com>
    (cherry picked from commit e1fc96df40cb758399ca3b6e74660f381ef16916)
    Reviewed-on: https://gerrit.libreoffice.org/24441
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>

diff --git a/sw/source/core/layout/frmtool.cxx b/sw/source/core/layout/frmtool.cxx
index 34b6af6..8033f04 100644
--- a/sw/source/core/layout/frmtool.cxx
+++ b/sw/source/core/layout/frmtool.cxx
@@ -2960,37 +2960,60 @@ void Notify_Background( const SdrObject* pObj,
     }
     SwFrame *pLastTab = nullptr;
 
+    bool isValidTableBeforeAnchor(false);
     while ( pCnt && pArea && pArea->IsAnLower( pCnt ) )
     {
         ::lcl_NotifyContent( pObj, pCnt, rRect, eHint );
         if ( pCnt->IsInTab() )
         {
-            SwLayoutFrame* pCell = pCnt->GetUpper();
-            // #i40606# - use <GetLastBoundRect()>
-            // instead of <GetCurrentBoundRect()>, because a recalculation
-            // of the bounding rectangle isn't intended here.
-            if ( pCell->IsCellFrame() &&
-                 ( pCell->Frame().IsOver( pObj->GetLastBoundRect() ) ||
-                   pCell->Frame().IsOver( rRect ) ) )
-            {
-                const SwFormatVertOrient &rOri = pCell->GetFormat()->GetVertOrient();
-                if ( text::VertOrientation::NONE != rOri.GetVertOrient() )
-                    pCell->InvalidatePrt();
-            }
             SwTabFrame *pTab = pCnt->FindTabFrame();
             if ( pTab != pLastTab )
             {
                 pLastTab = pTab;
+                isValidTableBeforeAnchor = false;
+                if (PREP_FLY_ARRIVE == eHint
+                    && pFlyFrame // TODO: do it for draw objects too?
+                    && pTab->IsFollow() // table starts on previous page?
+                    // "through" means they will actually overlap anyway
+                    && SURROUND_THROUGHT != pFlyFrame->GetFormat()->GetSurround().GetSurround()
+                    // if it's anchored in footer it can't move to other page
+                    && !pAnchor->FindFooterOrHeader())
+                {
+                    SwFrame * pTmp(pAnchor->GetPrev());
+                    while (pTmp)
+                    {
+                        if (pTmp == pTab)
+                        {
+                            // tdf#99460 the table shouldn't be moved by the fly
+                            isValidTableBeforeAnchor = true;
+                            break;
+                        }
+                        pTmp = pTmp->GetPrev();
+                    }
+                }
                 // #i40606# - use <GetLastBoundRect()>
                 // instead of <GetCurrentBoundRect()>, because a recalculation
                 // of the bounding rectangle isn't intended here.
-                if ( pTab->Frame().IsOver( pObj->GetLastBoundRect() ) ||
-                     pTab->Frame().IsOver( rRect ) )
+                if (!isValidTableBeforeAnchor
+                    && (pTab->Frame().IsOver(pObj->GetLastBoundRect()) ||
+                        pTab->Frame().IsOver(rRect)))
                 {
                     if ( !pFlyFrame || !pFlyFrame->IsLowerOf( pTab ) )
                         pTab->InvalidatePrt();
                 }
             }
+            SwLayoutFrame* pCell = pCnt->GetUpper();
+            // #i40606# - use <GetLastBoundRect()>
+            // instead of <GetCurrentBoundRect()>, because a recalculation
+            // of the bounding rectangle isn't intended here.
+            if (!isValidTableBeforeAnchor && pCell->IsCellFrame() &&
+                 ( pCell->Frame().IsOver( pObj->GetLastBoundRect() ) ||
+                   pCell->Frame().IsOver( rRect ) ) )
+            {
+                const SwFormatVertOrient &rOri = pCell->GetFormat()->GetVertOrient();
+                if ( text::VertOrientation::NONE != rOri.GetVertOrient() )
+                    pCell->InvalidatePrt();
+            }
         }
         pCnt = pCnt->GetNextContentFrame();
     }


More information about the Libreoffice-commits mailing list