summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stahl <Michael.Stahl@cib.de>2020-02-14 14:08:49 +0100
committerMichael Stahl <michael.stahl@cib.de>2020-02-14 17:19:21 +0100
commit391613785ae6fbb735cf7a86ea2f6a93161a8769 (patch)
tree93f3af21639e20dc47e1778f351fc43e97e2cc47
parent0dc4fddb9c76a3f4682eca4059b42a079e74e735 (diff)
sw: fix splitting text frames wrt. footnotes in follow
When the simplified (thanks Vasily) bugdoc is loaded, it has 2 pages and the last text frame 6 on page 1 has N lines, but after hiding tracked changes and showing them again, page 1 has N-1 lines, the last line starting at offset 1064 moved to the follow frame 7 on page 2, and this is the only difference from the state after loading. Frame 6 is formatted exactly 3 times; the difference between the 1st and the 3rd time is that footnote number 8 (footnote frame 34) doesn't exist yet the 1st time, but is on page 1 at the 3rd time. This reduces the space available in the body frame from 14040 to 13817, and SwTextFrameBreak::IsInside() finds there's not enough space for the last line. Interestingly the sw_redlinehide didn't change anything here; this reproduces in the same way back to OOo 3.3. There's a few obvious ways to try and fix this: a) The footnotes that are anchored beyond the end of the current text frame are moved by RemoveFootnote() called later: 4 in SwTextFrame::RemoveFootnote() at sw/source/core/text/txtftn.cxx:508 5 in SwTextIter::TruncLines(bool) at sw/source/core/text/itrtxt.cxx:375 6 in WidowsAndOrphans::FindBreak(SwTextFrame*, SwTextMargin&, bool) at sw/source/core/text/widorp.cxx:338 This could be done earlier, in IsInside(), which already tries to do 2 other things to get more space, so it seems plausible that footnotes which are known not to be in the frame (including the line that doesn't fit) could be moved off the page. b) An approach similar to commit e37ffdd118da2d21c5e78e8c7b67252d0d1adc8c "tdf#125685 sw: disregard footnotes in follow table on table split" would be to temporarily add the footnotes anchored beyond the current frame to the available space, and leave them to actually be moved later. c) When RemoveFootote() is called and it does move a footnote, invalidate its anchor text frame so that it gets formatted again. This seems to have the highest risk of introducing loops though. Let's try out a) for now and see how it works. Change-Id: I54b59637b79d67f5eca61f11bd575145f244381f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/88714 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.stahl@cib.de>
-rw-r--r--sw/source/core/text/widorp.cxx10
1 files changed, 10 insertions, 0 deletions
diff --git a/sw/source/core/text/widorp.cxx b/sw/source/core/text/widorp.cxx
index 2a6692cef371..c38aab287007 100644
--- a/sw/source/core/text/widorp.cxx
+++ b/sw/source/core/text/widorp.cxx
@@ -135,6 +135,16 @@ bool SwTextFrameBreak::IsInside( SwTextMargin const &rLine ) const
// If everything is inside the existing frame the result is true;
bFit = nDiff >= 0;
+ if (!bFit && rLine.MaybeHasHints() && m_pFrame->GetFollow()
+ // if using same footnote container as the follow, pointless to try?
+ && m_pFrame->FindFootnoteBossFrame() != m_pFrame->GetFollow()->FindFootnoteBossFrame())
+ {
+ // possibly a footnote that is anchored beyond the end of this
+ // (the last) line is in the way, try to remove it and check again
+ m_pFrame->RemoveFootnote(rLine.GetEnd());
+ nHeight = aRectFnSet.YDiff( aRectFnSet.GetPrtBottom(*m_pFrame->GetUpper()), m_nOrigin );
+ bFit = nHeight >= nLineHeight;
+ }
if ( !bFit )
{
if ( rLine.GetNext() &&