sw/source/core/layout/frmtool.cxx |   35 -----------------------------
 sw/source/core/text/itrform2.cxx  |   45 ++++++++++++++++++++++++++------------
 2 files changed, 32 insertions(+), 48 deletions(-)

New commits:
commit 626fe9ab5ebebc4ef36e35f4aa597c03a3564d22
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Wed Oct 18 08:52:44 2023 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Wed Oct 18 14:20:37 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.
    
    Change-Id: Ibaccc4807fd8c11bd45955b76e96cd4a5e55976f
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/158103
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

diff --git a/sw/source/core/layout/frmtool.cxx 
b/sw/source/core/layout/frmtool.cxx
index f7bfd409322a..c3fa35fcdc7b 100644
--- a/sw/source/core/layout/frmtool.cxx
+++ b/sw/source/core/layout/frmtool.cxx
@@ -2367,25 +2367,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;
@@ -2405,23 +2386,9 @@ tools::Long SwBorderAttrs::CalcLeft( const SwFrame 
*pCaller ) const
         nLeft += m_pRightMargin->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_pTextLeftMargin->GetLeft(*m_pFirstLineIndent);
-            }
+            nLeft += m_pTextLeftMargin->GetLeft(*m_pFirstLineIndent);
         }
         else
             nLeft += m_xLR->GetLeft();
diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx
index 7e4841fdb0c6..14d5d842e604 100644
--- a/sw/source/core/text/itrform2.cxx
+++ b/sw/source/core/text/itrform2.cxx
@@ -2779,13 +2779,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); // both sets left and reduces width
+            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 (GetTextFrame()->IsRightToLeft())
@@ -2815,22 +2844,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