sw/qa/core/text/data/floattable-avoid-manip-ofst.docx |binary sw/qa/core/text/frmform.cxx | 20 ++++++++++++++++++ sw/source/core/text/frmform.cxx | 8 +++++++ 3 files changed, 28 insertions(+)
New commits: commit 389637212194adc6206295f4952d395211cda4d2 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Wed Jul 12 14:00:20 2023 +0200 Commit: Mike Kaganski <mike.kagan...@collabora.com> CommitDate: Mon Jul 17 14:23:23 2023 +0200 cool#6857 sw floattable: try harder to keep anchor text in the last follow The bugdoc has a single floating table, spanning over 6 pages. Loading results in a layout loop, SwFrame::GetNextFlyLeaf() never finishes as the last follow fly has no anchor, which should never happen. The root of the problem seems to be already on page 3. The 6 fly frames are meant to have 6 matching anchor frames, where the offset of these text frames is all 0, i.e. the anchor frame's text goes to the last follow, since commit 73bada774ef37efd5a4498ccc083b1358314557d (sw floattable, crashtesting: fix PDF export of fdo72790-1.docx, part 3, 2023-04-26). Fix the problem by improving SwTextFrame::FormatAdjust(), so it never sets the offset of a follow anchor frame to non-zero when the current frame has a non-last split fly. All the negative fly frame heights and the final layout loop was a result of this. Note that there are still calls to ManipOfst() on the follow frame after this, but all such calls are from SwTextFrame::RemoveFootnote(), and that always just sets a non-zero offset + restores it, so that is not a problem for us. (cherry picked from commit d59704b6b8c7e5395c0606fa01f37392afc4b2cd) Change-Id: If62a1e2690cffed2de0be047ffb741d524532dea Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154377 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> diff --git a/sw/qa/core/text/data/floattable-avoid-manip-ofst.docx b/sw/qa/core/text/data/floattable-avoid-manip-ofst.docx new file mode 100644 index 000000000000..b4d85b5f8ac4 Binary files /dev/null and b/sw/qa/core/text/data/floattable-avoid-manip-ofst.docx differ diff --git a/sw/qa/core/text/frmform.cxx b/sw/qa/core/text/frmform.cxx index 3c1a16a99444..d23611a7eb05 100644 --- a/sw/qa/core/text/frmform.cxx +++ b/sw/qa/core/text/frmform.cxx @@ -16,6 +16,7 @@ #include <sortedobjs.hxx> #include <anchoredobject.hxx> #include <pagefrm.hxx> +#include <txtfrm.hxx> namespace { @@ -59,6 +60,25 @@ CPPUNIT_TEST_FIXTURE(Test, testFloattableNegativeVertOffset) // 2nd paragraph. CPPUNIT_ASSERT_LESS(pPara2->getFrameArea().Top(), rFlyRect.Bottom()); } + +CPPUNIT_TEST_FIXTURE(Test, testFloattableAvoidManipOfst) +{ + // Given a document with a 6-page floating table and some anchor text: + createSwDoc("floattable-avoid-manip-ofst.docx"); + + // When laying out that document: + calcLayout(); + + // Then make sure all anchor text is on the last page: + SwDoc* pDoc = getSwDoc(); + SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout(); + SwPageFrame* pLastPage = pLayout->GetLastPage(); + SwLayoutFrame* pBodyFrame = pLastPage->FindBodyCont(); + SwTextFrame* pAnchor = pBodyFrame->GetLower()->DynCastTextFrame(); + // If this is not 0, that means some of the anchor text is shifted to a previous page, while + // anchors of non-last split fly frames should contain no text. + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), pAnchor->GetOffset().get()); +} } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/text/frmform.cxx b/sw/source/core/text/frmform.cxx index 231825ff89e6..131f138ea683 100644 --- a/sw/source/core/text/frmform.cxx +++ b/sw/source/core/text/frmform.cxx @@ -1190,6 +1190,14 @@ void SwTextFrame::FormatAdjust( SwTextFormatter &rLine, RemoveFootnote(nOld, nEnd - nOld); } ChangeOffset( GetFollow(), nEnd ); + + if (HasNonLastSplitFlyDrawObj()) + { + // Make sure content from the last floating table anchor is not shifted to previous + // anchors. + nEnd = TextFrameIndex(0); + } + GetFollow()->ManipOfst( nEnd ); } else