summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorMichael Stahl <michael.stahl@allotropia.de>2023-08-01 19:45:58 +0200
committerMichael Stahl <michael.stahl@allotropia.de>2023-08-02 11:35:50 +0200
commit06bbcee6e367d1bc319c1f9cb0e749168e4d890c (patch)
treee5ce9639b2bca0319364fc50924c36e2a53ed94e /sw
parentf8c6be45b5862eb073eba0b8c327e38e3ac0c33c (diff)
tdf#152307 sw: layout: invalidate more frames when footer grows
While on page 12: SwTabFrame::MakeAll() is called on 523 while it's on page 12; there is one invalid pos text frame 492 with a fly somewhere before it; PrepareMake() of 523 formats prevs 492 then 493 which MoveFwd() taking 523 with it. While on page 13: TabFrame 523 is valid, and the footer 6651 never formatted (0 height). Formatting the footer in SwHeadFootFrame::FormatSize() invalidates the body 1031, immediately calls Calc() from SwFrame::MakePos(), where ~SwLayNotify() -> SwLayoutFrame::ChgLowersProp() invalidates SectionFrame 1034. Then SectionFrame 1034 is formatted, which via SwSectionFrame::CheckClipping() -> SwLayoutFrame::ChgLowersProp() invalidates only the last lower frame, because it checks the position of the frame and this frame still has a position on a previous page (it moved from page 12) and isn't even invalid yet. So in case there are invalid frames, the positions of the frames following these cannot be trusted to be used to optimize invalidations in SwLayoutFrame::ChgLowersProp(). (aside: it seems odd to format the body text before the footer text, but in this case doing it differently wouldn't have helped because the problem was already caused on a previous page) (regression from commit b9ef71476fd70bc13f50ebe80390e0730d1b7afb) Change-Id: I23b35c09af3a373d0913d931a2ba59d45fadf2c0 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155196 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
Diffstat (limited to 'sw')
-rw-r--r--sw/source/core/layout/wsfrm.cxx26
1 files changed, 24 insertions, 2 deletions
diff --git a/sw/source/core/layout/wsfrm.cxx b/sw/source/core/layout/wsfrm.cxx
index caaed34e8b70..992c81325e88 100644
--- a/sw/source/core/layout/wsfrm.cxx
+++ b/sw/source/core/layout/wsfrm.cxx
@@ -3156,26 +3156,48 @@ void SwLayoutFrame::ChgLowersProp( const Size& rOldSize )
}
else
{
+ SwFrame const* pFirstInvalid(nullptr);
+ for (SwFrame const* pLow = Lower();
+ pLow && pLow != pLowerFrame; pLow = pLow->GetNext())
+ {
+ if (!pLow->isFrameAreaDefinitionValid())
+ {
+ pFirstInvalid = pLow;
+ break;
+ }
+ }
// variable size of body|section frame has shrunk. Thus,
// invalidate all lowers not matching the new body|section size
// and the dedicated new last lower.
if( aRectFnSet.IsVert() )
{
SwTwips nBot = getFrameArea().Left() + getFramePrintArea().Left();
- while ( pLowerFrame && pLowerFrame->GetPrev() && pLowerFrame->getFrameArea().Left() < nBot )
+ while (pLowerFrame && pLowerFrame->GetPrev()
+ && (pFirstInvalid != nullptr // tdf#152307 trust nothing after invalid frame
+ || pLowerFrame->getFrameArea().Left() < nBot))
{
pLowerFrame->InvalidateAll_();
pLowerFrame->InvalidatePage( pPage );
+ if (pLowerFrame == pFirstInvalid)
+ {
+ pFirstInvalid = nullptr; // continue checking nBot
+ }
pLowerFrame = pLowerFrame->GetPrev();
}
}
else
{
SwTwips nBot = getFrameArea().Top() + getFramePrintArea().Bottom();
- while ( pLowerFrame && pLowerFrame->GetPrev() && pLowerFrame->getFrameArea().Top() > nBot )
+ while (pLowerFrame && pLowerFrame->GetPrev()
+ && (pFirstInvalid != nullptr // tdf#152307 trust nothing after invalid frame
+ || nBot < pLowerFrame->getFrameArea().Top()))
{
pLowerFrame->InvalidateAll_();
pLowerFrame->InvalidatePage( pPage );
+ if (pLowerFrame == pFirstInvalid)
+ {
+ pFirstInvalid = nullptr; // continue checking nBot
+ }
pLowerFrame = pLowerFrame->GetPrev();
}
}