[Libreoffice-commits] core.git: Branch 'libreoffice-6-3' - sw/source

Michael Stahl (via logerrit) logerrit at kemper.freedesktop.org
Wed Jun 5 11:48:46 UTC 2019


 sw/source/core/layout/tabfrm.cxx |   35 ++++++++++++++++++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)

New commits:
commit b9089b1be5ad1df8949527d28b9ce5840a892d0b
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Tue Jun 4 18:01:24 2019 +0200
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Wed Jun 5 13:48:02 2019 +0200

    tdf#125685 sw: disregard footnotes in follow table on table split
    
    The first problem here is that the table isn't fully formatted; it fails
    with:
    
    warn:legacy.osl:22975:22975:sw/source/core/layout/tabfrm.cxx:2639: debug assertion: <SwTabFrame::MakeAll()> - format of table lowers suppressed by fix i44910
    
    The situation is that there is a big table split across pages; the first
    line of the table would fit onto the previous page so its follow frame
    moves backward and then the table frame tries to split again.
    
    During SwTabFrame::Split(), all the frames in the table are formatted,
    and at that point a footnote that was on the next page is moved to this
    page.
    
    A nested table frame also splits, such that it fits inside the page...
    but then the split of the outer table fails by 5 twips, because the
    moved footnote has reduced the space available for the outer table.
    
    The footnote is anchored in the inner table's follow frame, which would
    be moved to the next page anyway, taking the footnote with it.
    
    Fix this in lcl_RecalcSplitLine() by checking for footnotes that are
    anchored in the follow frame of the top-level table being split, and
    adding their height to the available space on the page.
    
    Fixing the first problem avoids the crash as well; the crash happens
    since 18765b9fa739337d2d891513f6e2fb7c3ce23b50 and it's rather hard to
    avoid it in a situation where formatting starts at the end and recurses
    into an unformatted table preceding it, which isn't supposed to happen.
    
    Change-Id: I85286583c1c4930468a1c283afc98504cd35bb71
    Reviewed-on: https://gerrit.libreoffice.org/73465
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <Michael.Stahl at cib.de>
    (cherry picked from commit e37ffdd118da2d21c5e78e8c7b67252d0d1adc8c)
    Reviewed-on: https://gerrit.libreoffice.org/73535

diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx
index 7188751e5b5d..4f9e0880ff50 100644
--- a/sw/source/core/layout/tabfrm.cxx
+++ b/sw/source/core/layout/tabfrm.cxx
@@ -47,6 +47,7 @@
 #include <cellfrm.hxx>
 #include <flyfrms.hxx>
 #include <txtfrm.hxx>
+#include <ftnfrm.hxx>
 #include <notxtfrm.hxx>
 #include <htmltbl.hxx>
 #include <sectfrm.hxx>
@@ -715,7 +716,39 @@ static bool lcl_RecalcSplitLine( SwRowFrame& rLastLine, SwRowFrame& rFollowLine,
     // #i26945# - include check, if objects fit
     const SwTwips nDistanceToUpperPrtBottom =
         aRectFnSet.BottomDist(rTab.getFrameArea(), aRectFnSet.GetPrtBottom(*rTab.GetUpper()));
-    if ( nDistanceToUpperPrtBottom < 0 || !rTab.DoesObjsFit() )
+    // tdf#125685 ignore footnotes that are anchored in follow-table of this
+    // table - if split is successful they move to the next page/column anyway
+    assert(rTab.GetFollow() == rFollowLine.GetUpper());
+    SwTwips nFollowFootnotes(0);
+    // actually there should always be a boss frame, except if "this" isn't
+    // connected to a page yet; not sure if that can happen
+    if (SwFootnoteBossFrame const*const pBoss = rTab.FindFootnoteBossFrame())
+    {
+        if (SwFootnoteContFrame const*const pCont = pBoss->FindFootnoteCont())
+        {
+            for (SwFootnoteFrame const* pFootnote = static_cast<SwFootnoteFrame const*>(pCont->Lower());
+                 pFootnote != nullptr;
+                 pFootnote = static_cast<SwFootnoteFrame const*>(pFootnote->GetNext()))
+            {
+                SwContentFrame const*const pAnchor = pFootnote->GetRef();
+                SwTabFrame const* pTab = pAnchor->FindTabFrame();
+                if (pTab)
+                {
+                    while (pTab->GetUpper()->IsInTab())
+                    {
+                        pTab = pTab->GetUpper()->FindTabFrame();
+                    }
+                    // TODO currently do this only for top-level tables?
+                    // otherwise would need to check rTab's follow and any upper table's follow?
+                    if (pTab == rTab.GetFollow())
+                    {
+                        nFollowFootnotes += aRectFnSet.GetHeight(pFootnote->getFrameArea());
+                    }
+                }
+            }
+        }
+    }
+    if (nDistanceToUpperPrtBottom + nFollowFootnotes < 0 || !rTab.DoesObjsFit())
         bRet = false;
 
     // 2. Check if each cell in the last line has at least one content frame.


More information about the Libreoffice-commits mailing list