path: root/sw/source
diff options
authorMiklos Vajna <>2018-09-14 17:38:32 +0200
committerMichael Stahl <>2018-09-18 11:16:36 +0200
commit5b767f5528724474b68340a50daa3038e4401169 (patch)
tree141bac7745676adbd9627efecae96fc704d43cc2 /sw/source
parentca34dd89e38911f8a1fc7b6ce6afa3b39580fa21 (diff)
tdf#119875 sw: fix invalid pos of frame after 0-sized section with laycache
The interesting part of the layout of page 2 is: - frame #40 is a section frame with a text frame which is in a list ("A") - frame #48 is a section frame after that, with the same top=19213 Given that frame #40 has height > 0, they overlap when the page is rendered. What happens is: - frame #40 grows - there are other section frames between #40 and #48 in-between, but they don't have an SwSection - these frames are skipped - then the position of #48 is invalidated So the next time we calculate the position of #48, we look the last skipped (previous) section frame (which still has top=19213, since its position was not invalidated above), and since its height is 0, we conclude that our current top=19213 is valid after all. This is like this since commit 84a3db80b4fd66c6854b3135b5f69b61fd828e62 (initial import, 2000-09-18), so leave the code there that invalidates not only the next frame, but all the way down to the first non-SwSection-less-SwSectionFrame. But instead of just invalidating the last frame, invalidate the in-between SwSection-less-SwSectionFrames as well. In practice this did not cause a problem in case the document has no layout cache. If it does, then the frames are created on pages hinted by the cache, then later moved to their final place. In practice this bug was visible only in this later case. (I.e. such a layout cache can be only created if the machine that saved the document last time does not have the fonts needed by the document installed; and then the document is opened on an other machine which has those fonts.) (cherry picked from commit b5937112d4035fb9ffb472e1bf36567d9c78c820) Conflicts: sw/qa/extras/layout/layout.cxx Change-Id: I02ae9f63d0b4b5e9d014df53ed2cf21a04b15090 Reviewed-on: Tested-by: Jenkins Reviewed-by: Michael Stahl <>
Diffstat (limited to 'sw/source')
1 files changed, 24 insertions, 4 deletions
diff --git a/sw/source/core/layout/sectfrm.cxx b/sw/source/core/layout/sectfrm.cxx
index 7f8009a5cc44..e085f98a262c 100644
--- a/sw/source/core/layout/sectfrm.cxx
+++ b/sw/source/core/layout/sectfrm.cxx
@@ -45,6 +45,21 @@
#include <sortedobjs.hxx>
#include <hints.hxx>
+ * Performs the correct type of position invalidation depending on if we're in
+ * CalcContent().
+ */
+void InvalidateFramePos(SwFrame* pFrame, bool bInCalcContent)
+ if (bInCalcContent)
+ pFrame->InvalidatePos_();
+ else
+ pFrame->InvalidatePos();
SwSectionFrame::SwSectionFrame( SwSection &rSect, SwFrame* pSib )
: SwLayoutFrame( rSect.GetFormat(), pSib )
, SwFlowFrame( static_cast<SwFrame&>(*this) )
@@ -2212,15 +2227,20 @@ SwTwips SwSectionFrame::Grow_( SwTwips nDist, bool bTst )
if( GetNext() )
+ // Own height changed, need to invalidate the position of
+ // next frames.
SwFrame *pFrame = GetNext();
while( pFrame && pFrame->IsSctFrame() && !static_cast<SwSectionFrame*>(pFrame)->GetSection() )
+ {
+ // Invalidate all in-between frames, otherwise position
+ // calculation (which only looks back to one relative
+ // frame) will have an incorrect result.
+ InvalidateFramePos(pFrame, bInCalcContent);
pFrame = pFrame->GetNext();
+ }
if( pFrame )
- if( bInCalcContent )
- pFrame->InvalidatePos_();
- else
- pFrame->InvalidatePos();
+ InvalidateFramePos(pFrame, bInCalcContent);
// #i28701# - Due to the new object positioning