sw/qa/core/layout/data/floattable-from-bottom.docx |binary
 sw/qa/core/layout/flycnt.cxx                       |   21 +++++++++++++++++++++
 sw/source/core/layout/fly.cxx                      |   15 ++++++++++++++-
 3 files changed, 35 insertions(+), 1 deletion(-)

New commits:
commit 35a8e22495a4cf756e650e8e4d840da1e8df80af
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Fri Aug 4 10:44:30 2023 +0200
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Tue Aug 8 10:18:15 2023 +0200

    sw floattable, crashtesting: fix PDF export of tdf73201-1.docx
    
    The direct cause is that in in the SwTextFrameBreak ctor, m_pFrame has
    IsInSct() as true, but FindSctFrame() then doesn't find anything, which
    should not happen.
    
    The bigger problem is that currently the fly split code assumes that
    frames grow from (logical) top to bottom, so in case the vertical
    orientation is bottom, and we have to grow from bottom to top, that
    needs re-positioning the fly, but the fly split code has no support for
    that.
    
    Fix the crash by denying this case in SwFlyFrame::IsFlySplitAllowed()
    for now, the document's table is not supposed to split in the first
    place.
    
    In case later there is a real need to split such flys, then more
    research is needed how that re-positioning works in detail for non-split
    flys and then we have to adapt the fly split code accordingly.
    
    Change-Id: I56cf074a3d740ab716f7de232fbd131d17544d9e
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155339
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins
    (cherry picked from commit c545a0729e89ee2e8f14534b77422cc9eb4eb7cf)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155397
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>

diff --git a/sw/qa/core/layout/data/floattable-from-bottom.docx 
b/sw/qa/core/layout/data/floattable-from-bottom.docx
new file mode 100644
index 000000000000..86374a68ba27
Binary files /dev/null and b/sw/qa/core/layout/data/floattable-from-bottom.docx 
differ
diff --git a/sw/qa/core/layout/flycnt.cxx b/sw/qa/core/layout/flycnt.cxx
index a1e4c05c6c1d..6207a956f574 100644
--- a/sw/qa/core/layout/flycnt.cxx
+++ b/sw/qa/core/layout/flycnt.cxx
@@ -975,6 +975,27 @@ CPPUNIT_TEST_FIXTURE(Test, testSplitFlyNoFooterOverlap)
     const SwSortedObjs& rPage2Objs = *pPage2->GetSortedObjs();
     CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rPage2Objs.size());
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testSplitFlyGrowFromBottom)
+{
+    // Given a document with a floating table that grows from the bottom:
+    createSwDoc("floattable-from-bottom.docx");
+
+    // When calculating the layout:
+    calcLayout();
+
+    // Then make sure that such a floating table is not split, matching Word:
+    SwDoc* pDoc = getSwDoc();
+    SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+    auto pPage1 = dynamic_cast<SwPageFrame*>(pLayout->Lower());
+    CPPUNIT_ASSERT(pPage1);
+    CPPUNIT_ASSERT(pPage1->GetSortedObjs());
+    const SwSortedObjs& rPage1Objs = *pPage1->GetSortedObjs();
+    const auto pFly = dynamic_cast<SwFlyAtContentFrame*>(rPage1Objs[0]);
+    // Without the accompanying fix in place, this test would have failed, we 
tried to split the fly
+    // frame on page 1 even when it would fit, and this lead to a crash on 
export later.
+    CPPUNIT_ASSERT(!pFly->GetFollow());
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/fly.cxx b/sw/source/core/layout/fly.cxx
index a365668c4ce2..4022e1995fe8 100644
--- a/sw/source/core/layout/fly.cxx
+++ b/sw/source/core/layout/fly.cxx
@@ -687,7 +687,20 @@ bool SwFlyFrame::IsFlySplitAllowed() const
         return false;
     }
 
-    return GetFormat()->GetFlySplit().GetValue();
+    const SwFlyFrameFormat* pFormat = GetFormat();
+    const SwFormatVertOrient& rVertOrient = pFormat->GetVertOrient();
+    if (rVertOrient.GetVertOrient() == text::VertOrientation::BOTTOM)
+    {
+        // We have to grow from bottom to top, and the fly split code assumes 
that we grow from top
+        // to bottom, so don't split for now.
+        if (rVertOrient.GetRelationOrient() == 
text::RelOrientation::PAGE_PRINT_AREA)
+        {
+            // Growing from the bottom of the body frame.
+            return false;
+        }
+    }
+
+    return pFormat->GetFlySplit().GetValue();
 }
 
 SwFrame *SwFlyFrame::FindLastLower()

Reply via email to