sw/qa/core/text/data/fly-minimal-wrap.docx |binary sw/qa/core/text/itrform2.cxx | 30 +++++++++++++++++++++++++++++ sw/qa/core/text/text.cxx | 4 +-- sw/source/core/text/itrform2.cxx | 23 ++++++++++++++++++++-- 4 files changed, 53 insertions(+), 4 deletions(-)
New commits: commit f3ff9c42de8e37fef48e841eeff9732ef01bd460 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Tue Oct 10 08:23:14 2023 +0200 Commit: Xisco Fauli <xiscofa...@libreoffice.org> CommitDate: Tue Oct 10 11:02:01 2023 +0200 tdf#157571 sw floattable: fix incorrect blank space after table-in-shape Regression from a4af5432753408c4eea8a8d56c2f48202160c5fe (tdf#120262 sw floattable, legacy: fix text wrap around fly when no content fits, 2023-07-17), the bugdoc has a shape which contains a table, and lots of empty paragraphs next to it wrap around the shape. Writer didn't wrap these empty paragraphs, so some of the page 1 content was shifted to page 2. What happened here is that in case there is a really small space for the wrapping text around a floating object, then Word has some minimal limit. If the available horizontal space is smaller than the limit, we don't even try to wrap, even if the content (an empty paragraph) would fit. It was assumed that this limit is the shape for normal anchored objects and floating tables, but the two bugdocs show that there are two different limits here. Fix the problem by going back to MINLAY as the default limit where we start wrapping, and only increase that to TEXT_MIN_SMALL when wrapping around floating tables. That fixes the bugdoc and keeps the older floating table use-case working as well. This also allows reverting changes to testParaUpperMarginFlyIntersect, to assert the non-floating-table case again. Change-Id: I8f8a776c6ad5bdfa0ee4f197b600463fef6431f0 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/157743 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins (cherry picked from commit 4a5fb05d5e2448453477ce14862a8cf9846ecb49) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/157717 Reviewed-by: Michael Stahl <michael.st...@allotropia.de> diff --git a/sw/qa/core/text/data/fly-minimal-wrap.docx b/sw/qa/core/text/data/fly-minimal-wrap.docx new file mode 100644 index 000000000000..f5955d29d0ed Binary files /dev/null and b/sw/qa/core/text/data/fly-minimal-wrap.docx differ diff --git a/sw/qa/core/text/itrform2.cxx b/sw/qa/core/text/itrform2.cxx index e190bed46f33..637396a01c2e 100644 --- a/sw/qa/core/text/itrform2.cxx +++ b/sw/qa/core/text/itrform2.cxx @@ -82,6 +82,36 @@ CPPUNIT_TEST_FIXTURE(Test, testFloattableLegacyWrapEmptyParagraph) const SwSortedObjs& rPageObjs2 = *pPage2->GetSortedObjs(); CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rPageObjs2.size()); } + +CPPUNIT_TEST_FIXTURE(Test, testFlyMinimalWrap) +{ + // Given a document with a first page that has a shape and a table in it (not floating table), + // some empty paragraphs wrapping around the shape: + createSwDoc("fly-minimal-wrap.docx"); + + // When calculating the layout: + calcLayout(); + + // Then make sure the wrap happens, so the 2nd page only has 2 paragraphs: + SwDoc* pDoc = getSwDoc(); + SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout(); + auto pPage = dynamic_cast<SwPageFrame*>(pLayout->Lower()); + CPPUNIT_ASSERT(pPage); + CPPUNIT_ASSERT(pPage->GetSortedObjs()); + const SwSortedObjs& rPageObjs = *pPage->GetSortedObjs(); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), rPageObjs.size()); + auto pPage2 = dynamic_cast<SwPageFrame*>(pPage->GetNext()); + CPPUNIT_ASSERT(pPage2); + CPPUNIT_ASSERT(!pPage2->GetSortedObjs()); + SwLayoutFrame* pBody2 = pPage2->FindBodyCont(); + SwFrame* pPage2Para1 = pBody2->GetLower(); + CPPUNIT_ASSERT(pPage2Para1); + SwFrame* pPage2Para2 = pPage2Para1->GetNext(); + CPPUNIT_ASSERT(pPage2Para2); + // Without the accompanying fix in place, this test would have failed, the second page had 19 + // text frames in the body frame, not 2. + CPPUNIT_ASSERT(!pPage2Para2->GetNext()); +} } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/qa/core/text/text.cxx b/sw/qa/core/text/text.cxx index eec7292b6b68..790f2f32415f 100644 --- a/sw/qa/core/text/text.cxx +++ b/sw/qa/core/text/text.cxx @@ -1286,10 +1286,10 @@ CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testParaUpperMarginFlyIntersect) nHeight += getXPath(pXmlDoc, xPath, "height").toInt32(); } // Without the accompanying fix in place, this test would have failed with: - // - Expected: 542 (~500) + // - Expected: 521 (~500) // - Actual : 857 (~1000) // I.e. both upper and lower margin was taken into account. - CPPUNIT_ASSERT_EQUAL(542, nHeight); + CPPUNIT_ASSERT_EQUAL(521, nHeight); } CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testTdf129810) diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx index 10a7671279da..3aaab7a9f258 100644 --- a/sw/source/core/text/itrform2.cxx +++ b/sw/source/core/text/itrform2.cxx @@ -2806,8 +2806,27 @@ void SwTextFormatter::CalcFlyWidth( SwTextFormatInfo &rInf ) { // Word style: if there is minimal space remaining, then handle that similar to a full line // and put the actual empty paragraph below the fly. - bFullLine = std::abs(aLine.Left() - aInter.Left()) < TEXT_MIN_SMALL - && std::abs(aLine.Right() - aInter.Right()) < TEXT_MIN_SMALL; + SwTwips nLimit = MINLAY; + for (const auto& pObj : *rTextFly.GetAnchoredObjList()) + { + auto pFlyFrame = pObj->DynCastFlyFrame(); + if (!pFlyFrame) + { + continue; + } + + if (!pFlyFrame->IsFlySplitAllowed()) + { + continue; + } + + // We wrap around a floating table, that has a larger minimal wrap distance. + nLimit = TEXT_MIN_SMALL; + break; + } + + bFullLine = std::abs(aLine.Left() - aInter.Left()) < nLimit + && std::abs(aLine.Right() - aInter.Right()) < nLimit; } // Although no text is left, we need to format another line,