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.

Reply via email to