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/inc/txtfly.hxx              |    2 +
 sw/source/core/text/itrform2.cxx           |   23 ++++++++++++++++++++--
 5 files changed, 55 insertions(+), 4 deletions(-)

New commits:
commit c6f35df06214a330ff50bbba4b0809c8aabf0e7e
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Tue Oct 10 08:23:14 2023 +0200
Commit:     Caolán McNamara <caolan.mcnam...@collabora.com>
CommitDate: Wed Oct 11 12:13:46 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.
    
    (cherry picked from commit 4a5fb05d5e2448453477ce14862a8cf9846ecb49)
    
    [ Backport note: GetAnchoredObjList() is already public in master since
    commit b0e2b60fa45f236f6a993cc1295a7afddabb5098 (tdf#148897 tdf#143239
    sw: move flys off the page in SwTextFrame::Format(), 2023-05-24), pick
    just that part of the commit here to fix the build error. ]
    
    Change-Id: I8f8a776c6ad5bdfa0ee4f197b600463fef6431f0
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/157805
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>

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 a3435238ddba..f5b8c9253ea4 100644
--- a/sw/qa/core/text/text.cxx
+++ b/sw/qa/core/text/text.cxx
@@ -1011,10 +1011,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_PLUGIN_IMPLEMENT();
diff --git a/sw/source/core/inc/txtfly.hxx b/sw/source/core/inc/txtfly.hxx
index 3a3af9183e99..a0d3eb9b3f30 100644
--- a/sw/source/core/inc/txtfly.hxx
+++ b/sw/source/core/inc/txtfly.hxx
@@ -155,7 +155,9 @@ class SwTextFly
 
     SwAnchoredObjList* InitAnchoredObjList();
 
+public:
     SwAnchoredObjList* GetAnchoredObjList() const;
+private:
 
     /**
         Look for the first object which overlaps with the rectangle.
diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx
index bb0886b6981b..2e7d49144328 100644
--- a/sw/source/core/text/itrform2.cxx
+++ b/sw/source/core/text/itrform2.cxx
@@ -2787,8 +2787,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