sw/qa/core/text/data/floattable-anchor-left-margin.docx |binary
 sw/qa/core/text/itrform2.cxx                            |   23 ++++++++
 sw/source/core/layout/frmtool.cxx                       |   36 ------------
 sw/source/core/text/itrform2.cxx                        |   45 +++++++++++-----
 4 files changed, 55 insertions(+), 49 deletions(-)

New commits:
commit e4a2c77d2229cfcc8c8f5f6e8f306525ccb9d6e3
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Thu Oct 19 13:44:24 2023 +0200
Commit:     Caolán McNamara <caolan.mcnam...@collabora.com>
CommitDate: Fri Oct 20 09:48:25 2023 +0200

    tdf#157573 sw floattable: add missing testcase
    
    Fails with commit 626fe9ab5ebebc4ef36e35f4aa597c03a3564d22 (tdf#157573
    sw floattable: fix incorrect lack of left margin after table,
    2023-10-18) reverted.
    
    (cherry picked from commit 65f508b44ecbc20c8bd5172d1656639f686730ff)
    
    Change-Id: I6a3bd69dc109e6df195d00c33118218eeaa00ce5
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/158225
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>

diff --git a/sw/qa/core/text/data/floattable-anchor-left-margin.docx 
b/sw/qa/core/text/data/floattable-anchor-left-margin.docx
new file mode 100644
index 000000000000..aa55a0ce3001
Binary files /dev/null and 
b/sw/qa/core/text/data/floattable-anchor-left-margin.docx differ
diff --git a/sw/qa/core/text/itrform2.cxx b/sw/qa/core/text/itrform2.cxx
index 187eb9ab678e..2d9166b12390 100644
--- a/sw/qa/core/text/itrform2.cxx
+++ b/sw/qa/core/text/itrform2.cxx
@@ -15,6 +15,7 @@
 #include <rootfrm.hxx>
 #include <sortedobjs.hxx>
 #include <pagefrm.hxx>
+#include <cntfrm.hxx>
 
 namespace
 {
@@ -139,6 +140,28 @@ CPPUNIT_TEST_FIXTURE(Test, 
testContentControlHeaderPDFExport)
     // i.e. not all of header, heading and body text was there on page 2, 
content was lost.
     CPPUNIT_ASSERT_EQUAL(3, nTextCount);
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testSplitFlyAnchorLeftMargin)
+{
+    // Given a document with a floating table, anchor para is followed by an 
other para with a left
+    // margin:
+    createSwDoc("floattable-anchor-left-margin.docx");
+
+    // When laying out that document:
+    calcLayout();
+
+    // Then make sure that the left margin of this last paragraph is not lost:
+    SwDoc* pDoc = getSwDoc();
+    SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+    auto pPage = dynamic_cast<SwPageFrame*>(pLayout->Lower());
+    CPPUNIT_ASSERT(pPage);
+    SwContentFrame* pLastPara = pPage->FindLastBodyContent();
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 6480
+    // - Actual  : 0
+    // i.e. the left margin was lost.
+    CPPUNIT_ASSERT_EQUAL(static_cast<SwTwips>(6480), 
pLastPara->getFramePrintArea().Left());
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 2109fa3648beefdedbee4827e113f5a92606f75c
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Wed Oct 18 08:52:44 2023 +0200
Commit:     Caolán McNamara <caolan.mcnam...@collabora.com>
CommitDate: Fri Oct 20 09:48:15 2023 +0200

    tdf#157573 sw floattable: fix incorrect lack of left margin after table
    
    Regression from d477fa8ac1b0d3ee81427217bbb5950278ab16db (sw floattable:
    unconditionally map <w:tblpPr> to SwFormatFlySplit, 2023-03-17), the
    paragraph after the anchor of the floating table in the document lost
    its left paragraph margin at a layout level.
    
    Turns out the problem was there earlier, but it was hidden for this
    specific document, because we used to map DOCX floating tables to Writer
    inline tables in some cases before. The real problem was introduced
    earlier, in my 50a1df360c907d8419ce49f098b6bc87a37a9956 (n#775899 sw:
    add FloattableNomargins compat flag, 2012-08-23), even a TODO was added
    to point out this will be problematic. The old bugdoc wants to get rid
    of margins, because the floating table is already shifting text towards
    the right, the new bugdoc wants to keep the original margin as the
    paragraph after the anchor is not wrapping.
    
    Fix the problem by reverting the older fix and re-fix the old document
    differently. Don't do changes to the paragraph margin: that's not a good
    idea. If there is enough anchor text, it'll lead to a visibly bad
    paragraph margin anyway. Instead of reducing the paragraph margin,
    reduce the width of the fly portion in the paragraphs that intersect
    with the floating table. That's reasonly straightforward to do, because
    SwTextFormatter::CalcFlyWidth() already has a case when we know we're
    intersecting with a floating table and we also know that the floating
    table is aligned to the left. In this case we can simply reduce the fly
    portion width with the paragraph margin. This keeps the old bugdoc fixed
    and fixes the new bugdoc.
    
    It also means that DocumentSettingId::FLOATTABLE_NOMARGINS is now
    effectively unused, but that's not yet removed in this change.
    
    (cherry picked from commit 626fe9ab5ebebc4ef36e35f4aa597c03a3564d22)
    
    Conflicts:
            sw/source/core/layout/frmtool.cxx
            sw/source/core/text/itrform2.cxx
    
    Change-Id: Ibaccc4807fd8c11bd45955b76e96cd4a5e55976f
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/158178
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>

diff --git a/sw/source/core/layout/frmtool.cxx 
b/sw/source/core/layout/frmtool.cxx
index abf365493592..4fc6286d32e4 100644
--- a/sw/source/core/layout/frmtool.cxx
+++ b/sw/source/core/layout/frmtool.cxx
@@ -2349,25 +2349,6 @@ tools::Long SwBorderAttrs::CalcRight( const SwFrame* 
pCaller ) const
     return nRight;
 }
 
-/// Tries to detect if this paragraph has a floating table attached.
-static bool lcl_hasTabFrame(const SwTextFrame* pTextFrame)
-{
-    if (pTextFrame->GetDrawObjs())
-    {
-        const SwSortedObjs* pSortedObjs = pTextFrame->GetDrawObjs();
-        if (pSortedObjs->size() > 0)
-        {
-            SwAnchoredObject* pObject = (*pSortedObjs)[0];
-            if (auto pFly = pObject->DynCastFlyFrame())
-            {
-                if (pFly->Lower() && pFly->Lower()->IsTabFrame())
-                    return true;
-            }
-        }
-    }
-    return false;
-}
-
 tools::Long SwBorderAttrs::CalcLeft( const SwFrame *pCaller ) const
 {
     tools::Long nLeft=0;
@@ -2387,22 +2368,7 @@ tools::Long SwBorderAttrs::CalcLeft( const SwFrame 
*pCaller ) const
         nLeft += m_xLR->GetRight();
     else
     {
-        bool bIgnoreMargin = false;
-        if (pCaller->IsTextFrame())
-        {
-            const SwTextFrame* pTextFrame = static_cast<const 
SwTextFrame*>(pCaller);
-            if 
(pTextFrame->GetDoc().GetDocumentSettingManager().get(DocumentSettingId::FLOATTABLE_NOMARGINS))
-            {
-                // If this is explicitly requested, ignore the margins next to 
the floating table.
-                if (lcl_hasTabFrame(pTextFrame))
-                    bIgnoreMargin = true;
-                // TODO here we only handle the first two paragraphs, would be 
nice to generalize this.
-                else if (pTextFrame->FindPrev() && 
pTextFrame->FindPrev()->IsTextFrame() && lcl_hasTabFrame(static_cast<const 
SwTextFrame*>(pTextFrame->FindPrev())))
-                    bIgnoreMargin = true;
-            }
-        }
-        if (!bIgnoreMargin)
-            nLeft += m_xLR->GetLeft();
+        nLeft += m_xLR->GetLeft();
     }
 
     // correction: do not retrieve left margin for numbering in R2L-layout
diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx
index acaf066807f3..934cce312891 100644
--- a/sw/source/core/text/itrform2.cxx
+++ b/sw/source/core/text/itrform2.cxx
@@ -2760,13 +2760,42 @@ void SwTextFormatter::CalcFlyWidth( SwTextFormatInfo 
&rInf )
 
     aLine.Left( rInf.X() + nLeftMar );
     bool bForced = false;
+    bool bSplitFly = false;
+    for (const auto& pObj : *rTextFly.GetAnchoredObjList())
+    {
+        auto pFlyFrame = pObj->DynCastFlyFrame();
+        if (!pFlyFrame)
+        {
+            continue;
+        }
+
+        if (!pFlyFrame->IsFlySplitAllowed())
+        {
+            continue;
+        }
+
+        bSplitFly = true;
+        break;
+    }
     if( aInter.Left() <= nLeftMin )
     {
         SwTwips nFrameLeft = GetTextFrame()->getFrameArea().Left();
-        if( GetTextFrame()->getFramePrintArea().Left() < 0 )
+        SwTwips nFramePrintAreaLeft = 
GetTextFrame()->getFramePrintArea().Left();
+        if( nFramePrintAreaLeft < 0 )
             nFrameLeft += GetTextFrame()->getFramePrintArea().Left();
         if( aInter.Left() < nFrameLeft )
+        {
             aInter.Left( nFrameLeft );
+            if (bSplitFly && nFramePrintAreaLeft > 0 && nFramePrintAreaLeft < 
aInter.Width())
+            {
+                // We wrap around a split fly, the fly portion is on the
+                // left of the paragraph and we have a positive
+                // paragraph margin. Don't take space twice in this case
+                // (margin, fly portion), decrease the width of the fly
+                // portion accordingly.
+                aInter.Right(aInter.Right() - nFramePrintAreaLeft);
+            }
+        }
 
         tools::Long nAddMar = 0;
         if ( m_pFrame->IsRightToLeft() )
@@ -2796,22 +2825,10 @@ void SwTextFormatter::CalcFlyWidth( SwTextFormatInfo 
&rInf )
         // Word style: if there is minimal space remaining, then handle that 
similar to a full line
         // and put the actual empty paragraph below the fly.
         SwTwips nLimit = MINLAY;
-        for (const auto& pObj : *rTextFly.GetAnchoredObjList())
+        if (bSplitFly)
         {
-            auto pFlyFrame = pObj->DynCastFlyFrame();
-            if (!pFlyFrame)
-            {
-                continue;
-            }
-
-            if (!pFlyFrame->IsFlySplitAllowed())
-            {
-                continue;
-            }
-
             // We wrap around a floating table, that has a larger minimal wrap 
distance.
             nLimit = TEXT_MIN_SMALL;
-            break;
         }
 
         bFullLine = std::abs(aLine.Left() - aInter.Left()) < nLimit

Reply via email to