sw/qa/core/layout/flycnt.cxx | 5 +++++ sw/source/core/layout/tabfrm.cxx | 29 ++++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-)
New commits: commit 913b71dbe06c33773c4d779e00c6ec4b6a4af59f Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Fri Mar 10 09:44:41 2023 +0100 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Fri Mar 10 09:39:57 2023 +0000 sw floattable: ignore height of masters in lcl_CalcMinRowHeight() The problem was that the bugdoc has a split row and the minimum row height was only enforced for the master row, not the follow one. It seems this behavior started with commit 6f5024de2e1a5cc533527e45b33d9a415467c48d (tdf#104425 sw: split rows w/large min height (fix layout loop), 2016-12-08), because that had a case where the minimum row height didn't fit a page, but moving to the next page didn't help, so we hit a loop. The trouble is that when we do have enough space in the body frame, then not enforcing a minimal row height for each part of a split row leads to bad layout, since the row height will be smaller, so content after the table moves up. Fix this by checking if the body frame has enough space and not consider the height of the master + previous follows in that case. This is just for floating tables at the moment, doing this in general may need more work. With this, orig-nocompat.docx from tdf#61594 renders correctly with SW_FORCE_FLY_SPLIT=1. Change-Id: I922434db8455aba03ebeab9eae845003935f1d77 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/148595 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins diff --git a/sw/qa/core/layout/flycnt.cxx b/sw/qa/core/layout/flycnt.cxx index ee3f38537aca..d76a3447b938 100644 --- a/sw/qa/core/layout/flycnt.cxx +++ b/sw/qa/core/layout/flycnt.cxx @@ -465,6 +465,11 @@ CPPUNIT_TEST_FIXTURE(Test, testSplitFlyWidow) CPPUNIT_ASSERT(pPage2Fly); SwFrame* pTab2 = pPage2Fly->GetLower(); SwFrame* pRow2 = pTab2->GetLower(); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 1014 + // - Actual : 553 + // i.e. <w:trHeight w:val="1014"> from the file was ignored. + CPPUNIT_ASSERT_EQUAL(static_cast<tools::Long>(1014), pRow2->getFrameArea().Height()); SwFrame* pCell2 = pRow2->GetLower(); auto pText2 = dynamic_cast<SwTextFrame*>(pCell2->GetLower()); // And then similarly this was 1, not 2. diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx index cf773326fc9a..8bba0deab8e1 100644 --- a/sw/source/core/layout/tabfrm.cxx +++ b/sw/source/core/layout/tabfrm.cxx @@ -4277,7 +4277,34 @@ static SwTwips lcl_CalcMinRowHeight( const SwRowFrame* _pRow, // this frame's minimal height, because the rest will go to follow frame. else if ( !_pRow->IsInSplit() && rSz.GetHeightSizeType() == SwFrameSize::Minimum ) { - nHeight = rSz.GetHeight() - lcl_calcHeightOfRowBeforeThisFrame(*_pRow); + bool bSplitFly = false; + if (_pRow->IsInFly()) + { + // See if we're in a split fly that is anchored on a page that has enough space to + // host this row with its minimum row height. + const SwFlyFrame* pFly = _pRow->FindFlyFrame(); + if (pFly->IsFlySplitAllowed()) + { + SwFrame* pAnchor = const_cast<SwFlyFrame*>(pFly)->FindAnchorCharFrame(); + if (pAnchor) + { + if (pAnchor->FindPageFrame()->getFramePrintArea().Height() > rSz.GetHeight()) + { + bSplitFly = true; + } + } + } + } + + if (bSplitFly) + { + // Split fly: enforce minimum row height for the master and follows. + nHeight = rSz.GetHeight(); + } + else + { + nHeight = rSz.GetHeight() - lcl_calcHeightOfRowBeforeThisFrame(*_pRow); + } } }