sw/qa/core/layout/data/floattable-compat14-nosplit.docx |binary sw/qa/core/layout/flycnt.cxx | 42 ++++++++++++++++ sw/source/core/layout/fly.cxx | 10 +++ 3 files changed, 51 insertions(+), 1 deletion(-)
New commits: commit ee843f87d3c3e0624789dc80043a6e69df841920 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Thu Mar 16 08:17:43 2023 +0100 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Fri Mar 17 10:06:34 2023 +0000 sw floattable, legacy: restrict height when using bottom margin area The bugdoc was 1 page in Writer, but 2 pages in Word. There the entire 3rd row went to the next page. The problem seems to be that the legacy mode in Word seems to allow going to the bottom margin only in case the height of the floating table still fits the body frame height, while we simply allowed the usage of the bottom margin area unconditionally. Fix this by extending GetFlyAnchorBottom() to explicitly check for the body frame height. Note that this doesn't solve cases where the current height fits the body frame, but the new bottom won't; that still needs fixing in a follow-up commit. (cherry picked from commit ee8e9b993595e728f827a5fe6ab1ae5fb1f6aaae) Change-Id: Ic55b93e7b53fc45a837c3245c0091f2c93d028aa Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149041 Tested-by: Miklos Vajna <vmik...@collabora.com> Reviewed-by: Miklos Vajna <vmik...@collabora.com> diff --git a/sw/qa/core/layout/data/floattable-compat14-nosplit.docx b/sw/qa/core/layout/data/floattable-compat14-nosplit.docx new file mode 100644 index 000000000000..7d24d95aa92f Binary files /dev/null and b/sw/qa/core/layout/data/floattable-compat14-nosplit.docx differ diff --git a/sw/qa/core/layout/flycnt.cxx b/sw/qa/core/layout/flycnt.cxx index 5df8d7fc5c73..07aaf5deba3b 100644 --- a/sw/qa/core/layout/flycnt.cxx +++ b/sw/qa/core/layout/flycnt.cxx @@ -524,6 +524,48 @@ CPPUNIT_TEST_FIXTURE(Test, testSplitFlyCompat14) // but not in Word. CPPUNIT_ASSERT(!pCell2->GetPreviousCell()); } + +CPPUNIT_TEST_FIXTURE(Test, testSplitFlyCompat14Nosplit) +{ + // Given a Word 2010 document with 2 pages, 2 rows on page 1, 1 row on page 2: + std::shared_ptr<comphelper::ConfigurationChanges> pChanges( + comphelper::ConfigurationChanges::create()); + officecfg::Office::Writer::Filter::Import::DOCX::ImportFloatingTableAsSplitFly::set(true, + pChanges); + pChanges->commit(); + comphelper::ScopeGuard g([pChanges] { + officecfg::Office::Writer::Filter::Import::DOCX::ImportFloatingTableAsSplitFly::set( + false, pChanges); + pChanges->commit(); + }); + createSwDoc("floattable-compat14-nosplit.docx"); + + // When laying out that document: + calcLayout(); + + // Then make sure that the last row is on a separate page: + SwDoc* pDoc = getSwDoc(); + SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout(); + auto pPage1 = dynamic_cast<SwPageFrame*>(pLayout->Lower()); + CPPUNIT_ASSERT(pPage1); + const SwSortedObjs& rPage1Objs = *pPage1->GetSortedObjs(); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rPage1Objs.size()); + auto pPage1Fly = dynamic_cast<SwFlyAtContentFrame*>(rPage1Objs[0]); + CPPUNIT_ASSERT(pPage1Fly); + SwFrame* pTab1 = pPage1Fly->GetLower(); + SwFrame* pRow1 = pTab1->GetLower(); + CPPUNIT_ASSERT(pRow1->GetNext()); + auto pPage2 = dynamic_cast<SwPageFrame*>(pPage1->GetNext()); + // Without the accompanying fix in place, this test would have failed, all rows were on page 1. + CPPUNIT_ASSERT(pPage2); + const SwSortedObjs& rPage2Objs = *pPage2->GetSortedObjs(); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rPage2Objs.size()); + auto pPage2Fly = dynamic_cast<SwFlyAtContentFrame*>(rPage2Objs[0]); + CPPUNIT_ASSERT(pPage2Fly); + SwFrame* pTab2 = pPage2Fly->GetLower(); + SwFrame* pRow2 = pTab2->GetLower(); + CPPUNIT_ASSERT(!pRow2->GetNext()); +} } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/layout/fly.cxx b/sw/source/core/layout/fly.cxx index 65dad61a23f0..9ffb1a480c96 100644 --- a/sw/source/core/layout/fly.cxx +++ b/sw/source/core/layout/fly.cxx @@ -97,7 +97,15 @@ SwTwips GetFlyAnchorBottom(SwFlyFrame* pFly, const SwFrame& rAnchor) return 0; } - return aRectFnSet.GetBottom(pAnchorUpper->getFrameArea()); + // See if the fly height would still fit the body frame and the overlap would happen just + // because of a vertical offset. + SwTwips nFlyHeight = aRectFnSet.GetHeight(pFly->getFrameArea()); + SwTwips nAnchorUpperHeight = aRectFnSet.GetHeight(pAnchorUpper->getFramePrintArea()); + if (nFlyHeight <= nAnchorUpperHeight) + { + // Yes, it would fit: allow overlap. + return aRectFnSet.GetBottom(pAnchorUpper->getFrameArea()); + } } // Word >= 2013 style: the fly has to stay inside the body frame.