From a08b8fa2d01e630ef876b7944c37f0b6de09d407 Mon Sep 17 00:00:00 2001 From: Michael Stahl Date: Fri, 6 Dec 2024 14:20:22 +0100 Subject: [PATCH] sw: layout: ignore Keep-With-Next on hidden frames, part2 SwFrame::PrepareMake(), SwContentFrame::MakeAll(), SwContentFrame::WouldFit_() Change-Id: I2a909ac6d147668dddece97bd99e31fdddcf20eb Reviewed-on: https://gerrit.libreoffice.org/c/core/+/177976 Tested-by: Michael Stahl Reviewed-by: Michael Stahl --- sw/source/core/layout/calcmove.cxx | 49 ++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/sw/source/core/layout/calcmove.cxx b/sw/source/core/layout/calcmove.cxx index 43b3c5d8afda..e05024d7f2b6 100644 --- a/sw/source/core/layout/calcmove.cxx +++ b/sw/source/core/layout/calcmove.cxx @@ -304,9 +304,17 @@ void SwFrame::PrepareMake(vcl::RenderContext* pRenderContext) // There is no format of previous frame, if current frame is a table // frame and its previous frame wants to keep with it. - const bool bFormatPrev = !bTab || - !GetPrev() || - !GetPrev()->GetAttrSet()->GetKeep().GetValue(); + bool bFormatPrev{!bTab}; + if (!bFormatPrev) + { + SwFrame const* pPrev{this}; + do + { + pPrev = pPrev->GetPrev(); + } + while (pPrev && pPrev->IsHiddenNow()); + bFormatPrev = pPrev && !pPrev->GetAttrSet()->GetKeep().GetValue(); + } if ( bFormatPrev ) { SwFrame *pFrame = GetUpper()->Lower(); @@ -1364,7 +1372,7 @@ void SwContentFrame::MakeAll(vcl::RenderContext* /*pRenderContext*/) oNotify->SetBordersJoinedWithPrev(); } - const bool bKeep = IsKeep(rAttrs.GetAttrSet().GetKeep(), GetBreakItem()); + const bool bKeep{!isHiddenNow && IsKeep(rAttrs.GetAttrSet().GetKeep(), GetBreakItem())}; std::unique_ptr pSaveFootnote; if ( bFootnote ) @@ -1780,7 +1788,7 @@ void SwContentFrame::MakeAll(vcl::RenderContext* /*pRenderContext*/) if( nBottomDist >= 0 ) { - if ( bKeep && bMoveable ) + if (bKeep && bMoveable && !isHiddenNow) { // We make sure the successor will be formatted the same. // This way, we keep control until (almost) everything is stable, @@ -2107,8 +2115,18 @@ bool SwContentFrame::WouldFit_( SwTwips nSpace, const SwFrame *pTmpPrev = pNewUpper->Lower(); if( pTmpPrev && pTmpPrev->IsFootnoteFrame() ) pTmpPrev = static_cast(pTmpPrev)->Lower(); - while ( pTmpPrev && pTmpPrev->GetNext() ) - pTmpPrev = pTmpPrev->GetNext(); + { + SwFrame const* pTmpNonHidden{pTmpPrev && pTmpPrev->IsHiddenNow() ? nullptr : pTmpPrev}; + while (pTmpPrev && pTmpPrev->GetNext()) + { + pTmpPrev = pTmpPrev->GetNext(); + if (!pTmpPrev->IsHiddenNow()) + { + pTmpNonHidden = pTmpPrev; + } + } + pTmpPrev = pTmpNonHidden; + } // tdf#156727 if the previous one has keep-with-next, ignore it on this one! bool const isIgnoreKeep(pTmpPrev && pTmpPrev->IsFlowFrame() @@ -2117,6 +2135,14 @@ bool SwContentFrame::WouldFit_( SwTwips nSpace, do { + if (pFrame->IsHiddenNow()) + { // shortcut + assert(pFrame == this); + bRet = true; + pFrame = nullptr; + break; + } + // #i46181# SwTwips nSecondCheck = 0; SwTwips nOldSpace = nSpace; @@ -2282,8 +2308,8 @@ bool SwContentFrame::WouldFit_( SwTwips nSpace, return true; } } - SwFrame *pNxt; - if( nullptr != (pNxt = pFrame->FindNext()) && pNxt->IsContentFrame() && + SwFrame *const pNxt{pFrame->FindNextIgnoreHidden()}; + if (nullptr != pNxt && pNxt->IsContentFrame() && ( !pFootnoteFrame || ( pNxt->IsInFootnote() && pNxt->FindFootnoteFrame()->GetAttr() == pFootnoteFrame->GetAttr() ) ) ) { @@ -2309,10 +2335,7 @@ bool SwContentFrame::WouldFit_( SwTwips nSpace, pTmpPrev = nullptr; else { - if (pFrame->IsHiddenNow()) - pTmpPrev = lcl_NotHiddenPrev( pFrame ); - else - pTmpPrev = pFrame; + pTmpPrev = pFrame; } pFrame = static_cast(pNxt); }