sw/qa/core/layout/data/floattable-not-wrapped-by-table.docx |binary
 sw/qa/core/layout/tabfrm.cxx                                |   22 ++++++++++++
 sw/source/core/layout/tabfrm.cxx                            |   15 ++++++--
 3 files changed, 33 insertions(+), 4 deletions(-)

New commits:
commit 58b60a6b230cd916c6b278a5efe0987b9c23f8a5
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Tue Jan 23 15:34:07 2024 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Tue Feb 27 08:09:39 2024 +0100

    tdf#159017 sw floattable: only shift to the right when needed
    
    Regression from commit 868140fcc1311259b9d5f666637b33d226511a53
    (tdf#60558 sw floattable: allow wrap of table on the right of a
    floattable, 2023-12-05), the document had an inline table, followed by a
    floating table, and we moved the inline table to the right even if the
    left hand side of the floating table already had enough space.
    
    What happens here is that nominally the inline table's original position
    overlaps, but because the table width is small enough, such an overlap
    doesn't actually happen. In this case, it's not needed to shift the
    inline table to the right.
    
    Fix the problem by making the check that decides whether it's necessary
    to increment the left margin of the table more strict: it's not enough
    to have enough space on the right of the fly, it's also needed to *not*
    have enough space on the left side.
    
    This keeps the original "floating table wrapped by inline table on the
    right" use-case working, but restores the ~no left margin for the inline
    table for the new bugdoc.
    
    Conflicts:
            sw/source/core/layout/tabfrm.cxx
    
    Change-Id: Ifb30d90ca6dba7cc4a402d8a4445251120b575ae
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162447
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins
    (cherry picked from commit 6e3ad6ca0ae6cf62056610ddae9097973a887d99)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163953
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>

diff --git a/sw/qa/core/layout/data/floattable-not-wrapped-by-table.docx 
b/sw/qa/core/layout/data/floattable-not-wrapped-by-table.docx
new file mode 100644
index 000000000000..2c255148d351
Binary files /dev/null and 
b/sw/qa/core/layout/data/floattable-not-wrapped-by-table.docx differ
diff --git a/sw/qa/core/layout/tabfrm.cxx b/sw/qa/core/layout/tabfrm.cxx
index 68c0821d46df..82d7b3b996d1 100644
--- a/sw/qa/core/layout/tabfrm.cxx
+++ b/sw/qa/core/layout/tabfrm.cxx
@@ -199,6 +199,28 @@ CPPUNIT_TEST_FIXTURE(Test, testSplitFlyWrappedByTable)
     // i.e. the inline table was under the floating one, not on the right of 
it.
     CPPUNIT_ASSERT_LESS(nFloatingBottom, nInlineTop);
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testInlineTableThenSplitFly)
+{
+    // Given a document with a floating table ("right") and an inline table 
("left"):
+    // When laying out the document:
+    createSwDoc("floattable-not-wrapped-by-table.docx");
+
+    // Then make sure the inline table is on the left (small negative offset):
+    SwDoc* pDoc = getSwDoc();
+    SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+    auto pPage = pLayout->Lower()->DynCastPageFrame();
+    CPPUNIT_ASSERT(pPage);
+    SwFrame* pBody = pPage->FindBodyCont();
+    auto pTab = pBody->GetLower()->GetNext()->DynCastTabFrame();
+    SwTwips nInlineLeft = pTab->getFramePrintArea().Left();
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected less than: 0
+    // - Actual  : 6958
+    // i.e. "left" was on the right, its horizontal margin was not a small 
negative value but a
+    // large positive one.
+    CPPUNIT_ASSERT_LESS(static_cast<SwTwips>(0), nInlineLeft);
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx
index fb0ebaa13425..c6d836cf7642 100644
--- a/sw/source/core/layout/tabfrm.cxx
+++ b/sw/source/core/layout/tabfrm.cxx
@@ -3136,6 +3136,7 @@ bool SwTabFrame::CalcFlyOffsets( SwTwips& rUpper,
 
                     bool bShiftDown = css::text::WrapTextMode_NONE == 
nSurround;
                     bool bSplitFly = pFly->IsFlySplitAllowed();
+                    const SwRect aFlyRectWithoutSpaces = pFly->GetObjRect();
                     if (!bShiftDown && bAddVerticalFlyOffsets)
                     {
                         if (nSurround == text::WrapTextMode_PARALLEL && 
isHoriOrientShiftDown)
@@ -3150,7 +3151,6 @@ bool SwTabFrame::CalcFlyOffsets( SwTwips& rUpper,
 
                             // Ignore spacing when determining the left/right 
edge of the fly, like
                             // Word does.
-                            const SwRect aFlyRectWithoutSpaces = 
pFly->GetObjRect();
                             basegfx::B1DRange 
aFlyRange(aRectFnSet.GetLeft(aFlyRectWithoutSpaces),
                                                         
aRectFnSet.GetRight(aFlyRectWithoutSpaces));
 
@@ -3212,9 +3212,16 @@ bool SwTabFrame::CalcFlyOffsets( SwTwips& rUpper,
                     bool bFlyHoriOrientLeft = text::HoriOrientation::LEFT == 
rHori.GetHoriOrient();
                     if (bSplitFly && !bFlyHoriOrientLeft)
                     {
-                        // If a split fly is oriented "from left", we already 
checked if it has enough space on
-                        // the right, so from-left and left means the same 
here.
-                        bFlyHoriOrientLeft = rHori.GetHoriOrient() == 
text::HoriOrientation::NONE;
+                        // Only shift to the right if we don't have enough 
space on the left.
+                        SwTwips nTabWidth = getFramePrintArea().Width();
+                        SwTwips nWidthDeadline = aFlyRectWithoutSpaces.Left()
+                                                - 
pFly->GetAnchorFrame()->GetUpper()->getFrameArea().Left();
+                        if (nTabWidth > nWidthDeadline)
+                        {
+                            // If a split fly is oriented "from left", we 
already checked if it has enough space on
+                            // the right, so from-left and left means the same 
here.
+                            bFlyHoriOrientLeft = rHori.GetHoriOrient() == 
text::HoriOrientation::NONE;
+                        }
                     }
                     if ((css::text::WrapTextMode_RIGHT == nSurround
                          || css::text::WrapTextMode_PARALLEL == nSurround) &&

Reply via email to