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,

Reply via email to