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