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 5df7c66193d55af944b3269f11374e60da437c0b
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Tue Jan 23 15:34:07 2024 +0100
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Wed Jan 24 10:14:10 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.
    
    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/+/162464
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>

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 9357fc2df133..61b1a25109f5 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 033f692f47cc..f75782456181 100644
--- a/sw/source/core/layout/tabfrm.cxx
+++ b/sw/source/core/layout/tabfrm.cxx
@@ -3296,6 +3296,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)
@@ -3310,7 +3311,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));
 
@@ -3373,9 +3373,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