sw/CppunitTest_sw_core_layout.mk               |    1 
 sw/qa/core/layout/data/table-missing-join.docx |binary
 sw/qa/core/layout/tabfrm.cxx                   |   50 +++++++++++++++++++++++++
 sw/source/core/layout/tabfrm.cxx               |    9 ++++
 4 files changed, 60 insertions(+)

New commits:
commit 0fcd3fdd1a5899b11da42ee32bd1db0476dab31a
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Mon Sep 25 08:38:28 2023 +0200
Commit:     Caolán McNamara <caolan.mcnam...@collabora.com>
CommitDate: Tue Sep 26 15:04:20 2023 +0200

    tdf#157263 sw floattable: prefer join over split after moving fwd
    
    Regression from commit a4af5432753408c4eea8a8d56c2f48202160c5fe
    (tdf#120262 sw floattable, legacy: fix text wrap around fly when no
    content fits, 2023-07-17), the bugdoc was of 3 pages in both Word and
    Writer, but is now of 4 pages in Writer.
    
    The above commit fixed the layout, so the first row of the table around
    the page 1 -> page 2 boundary goes to the start of page 2 instead of to
    the end of page 1. This matches the Word layout, so a wanted change on
    its own, but it regressed the page acount. The reason for this is that
    the table has a single row on page 2 and its follow on page 3 is not
    joined, even if there would be still space on page 2. A reduced bugdoc
    appears to reproduce this problem even without floating tables, also
    with old versions, so it's not a new problem, but it's now more visible.
    
    Fix the problem by tweaking what to do in the next iteration in the loop
    of SwTabFrame::MakeAll() after moving forward. Moving forward is
    followed by a next iteration in that function, but it does both a
    MakePos() and a Format(), so it'll be the last iteration in the "is the
    postion / size of this tab frame valid" loop. We used to hit the "bSplit
    == true" case, there we found that there is enough remaining space, so
    no need to split and we quit the loop. This is now changed, so in case
    we moved the table forward and there is still enough space for the
    follow to be next to us, then the last iteration will try to join
    instead of trying to split.
    
    Note that probably split almost never makes sense after moving forward
    in the !HasNext() && HasFollow() case, but let's stay on the safe side
    and only do this when the follow definitely fits, which is enough for
    our needs here.
    
    (cherry picked from commit b8521d969ab5be4fc947e467d4afe969f9d3b563)
    
    Conflicts:
            sw/qa/core/layout/tabfrm.cxx
    
    Change-Id: I64b0a7d257b0ab01353741506969a287b361c5ff
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/157266
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>

diff --git a/sw/CppunitTest_sw_core_layout.mk b/sw/CppunitTest_sw_core_layout.mk
index 4bbfd23e0887..82f7dc87e695 100644
--- a/sw/CppunitTest_sw_core_layout.mk
+++ b/sw/CppunitTest_sw_core_layout.mk
@@ -19,6 +19,7 @@ $(eval $(call 
gb_CppunitTest_add_exception_objects,sw_core_layout, \
     sw/qa/core/layout/layact \
     sw/qa/core/layout/layout \
     sw/qa/core/layout/paintfrm \
+    sw/qa/core/layout/tabfrm \
 ))
 
 $(eval $(call gb_CppunitTest_use_libraries,sw_core_layout, \
diff --git a/sw/qa/core/layout/data/table-missing-join.docx 
b/sw/qa/core/layout/data/table-missing-join.docx
new file mode 100644
index 000000000000..1fabb9e5b27c
Binary files /dev/null and b/sw/qa/core/layout/data/table-missing-join.docx 
differ
diff --git a/sw/qa/core/layout/tabfrm.cxx b/sw/qa/core/layout/tabfrm.cxx
new file mode 100644
index 000000000000..d7df701a3351
--- /dev/null
+++ b/sw/qa/core/layout/tabfrm.cxx
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <swmodeltestbase.hxx>
+
+#include <IDocumentLayoutAccess.hxx>
+#include <rootfrm.hxx>
+#include <pagefrm.hxx>
+#include <tabfrm.hxx>
+
+namespace
+{
+/// Covers sw/source/core/layout/tabfrm.cxx fixes.
+class Test : public SwModelTestBase
+{
+public:
+    Test()
+        : SwModelTestBase("/sw/qa/core/layout/data/")
+    {
+    }
+};
+
+CPPUNIT_TEST_FIXTURE(Test, testTableMissingJoin)
+{
+    // Given a document with a table on page 2:
+    // When laying out that document:
+    createSwDoc("table-missing-join.docx");
+
+    // Then make sure that the table fits page 2:
+    SwDoc* pDoc = getSwDoc();
+    SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+    auto pPage1 = pLayout->Lower()->DynCastPageFrame();
+    CPPUNIT_ASSERT(pPage1);
+    auto pPage2 = pPage1->GetNext()->DynCastPageFrame();
+    CPPUNIT_ASSERT(pPage2);
+    SwFrame* pBody = pPage2->FindBodyCont();
+    auto pTab = pBody->GetLower()->DynCastTabFrame();
+    // Without the accompanying fix in place, this test would have failed, the 
table continued on
+    // page 3.
+    CPPUNIT_ASSERT(!pTab->HasFollow());
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx
index d63b96fa71c2..34e8f5470c4e 100644
--- a/sw/source/core/layout/tabfrm.cxx
+++ b/sw/source/core/layout/tabfrm.cxx
@@ -2825,6 +2825,15 @@ void SwTabFrame::MakeAll(vcl::RenderContext* 
pRenderContext)
             if ( GetFollow() )
                 Join();
         }
+        else if (!GetNext() && !HasFollowFlowLine() && GetFollow()
+                 && (getFrameArea().Bottom() + 
GetFollow()->getFrameArea().Height())
+                        < GetUpper()->getFrameArea().Bottom())
+        {
+            // We're the last lower of the upper, no split row and we have a 
follow.  That follow
+            // fits our upper, still.  Prefer joining that follow in the next 
iteration, instead of
+            // trying to split the current table.
+            bSplit = false;
+        }
 
         if ( bMovedBwd && GetUpper() )
         {

Reply via email to