Kaydet (Commit) e14056e6 authored tarafından Michael Stahl's avatar Michael Stahl

tdf#119109 sw: fix iteration in SwFrame::PrepareMake()

The problem is that with the change in SwFlowFrame::MoveBwd(), a
SwTextFrame in a table may move backwards during MakeAll(); if the next
frame of the moved frame, and the "this" frame in PrepareMake(), is a
SwTabFrame, then the pFrame->FindNext() will return not this SwTabFrame,
but the first SwTextFrame *inside* the SwTabFrame - hence the iteration
will never meet the "pFrame == this" termination condition and the
SwTabFrame remains unformatted; this warning is printed:

warn:legacy.osl:6874:6874:sw/source/core/layout/calcmove.cxx:296: :-( Layout unstable (this not found).

(regression from 18765b9f)

Change-Id: I68207ba9cf68cd5abe51d647cb757176261eda40
Reviewed-on: https://gerrit.libreoffice.org/72797
Tested-by: Jenkins
Reviewed-by: 's avatarMichael Stahl <Michael.Stahl@cib.de>
üst e3015d70
...@@ -308,12 +308,29 @@ void SwFrame::PrepareMake(vcl::RenderContext* pRenderContext) ...@@ -308,12 +308,29 @@ void SwFrame::PrepareMake(vcl::RenderContext* pRenderContext)
SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow( pThis ) ) SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow( pThis ) )
break; break;
bool const isLast(pFrame->GetNext() == this);
// note: this seems obvious but does *not* hold, a MakeAll()
// could move more than 1 frame backwards!
// that's why FindNext() is used below
// assert(pFrame->GetUpper() == GetUpper());
pFrame->MakeAll(pRenderContext); pFrame->MakeAll(pRenderContext);
if( IsSctFrame() && !static_cast<SwSectionFrame*>(this)->GetSection() ) if( IsSctFrame() && !static_cast<SwSectionFrame*>(this)->GetSection() )
break; break;
if (isLast && pFrame->GetUpper() != GetUpper())
{
assert(GetUpper()->Lower() == this
// tab frame/section frame may split multiple times
|| ( SwFlowFrame::CastFlowFrame(pFrame)
&& SwFlowFrame::CastFlowFrame(GetUpper()->Lower())
&& SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow(
SwFlowFrame::CastFlowFrame(GetUpper()->Lower()))
&& GetUpper()->Lower()->GetNext() == this));
break; // tdf#119109 frame was moved backward, prevent
// FindNext() returning a frame inside this if
} // this is a table!
} }
// With ContentFrames, the chain may be broken while walking through // With ContentFrames, the chain may be broken while walking through
// it. Therefore we have to figure out the follower in a bit more // it. Therefore we have to figure out the next frame in a bit more
// complicated way. However, I'll HAVE to get back to myself // complicated way. However, I'll HAVE to get back to myself
// sometime again. // sometime again.
pFrame = pFrame->FindNext(); pFrame = pFrame->FindNext();
...@@ -422,7 +439,7 @@ void SwFrame::PrepareCursor() ...@@ -422,7 +439,7 @@ void SwFrame::PrepareCursor()
pFrame->MakeAll(getRootFrame()->GetCurrShell()->GetOut()); pFrame->MakeAll(getRootFrame()->GetCurrShell()->GetOut());
} }
// With ContentFrames, the chain may be broken while walking through // With ContentFrames, the chain may be broken while walking through
// it. Therefore we have to figure out the follower in a bit more // it. Therefore we have to figure out the next frame in a bit more
// complicated way. However, I'll HAVE to get back to myself // complicated way. However, I'll HAVE to get back to myself
// sometime again. // sometime again.
pFrame = pFrame->FindNext(); pFrame = pFrame->FindNext();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment