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) &&