From 5a0e1504b3fe10737b75780c23a74fda303a0f05 Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Wed, 31 Jul 2013 10:39:04 +1000 Subject: [PATCH] Bug 897887 - Avoid calling ScheduleReflowSVGNonDisplayText when constructing frames during reflow. r=jwatt --- layout/generic/nsFrame.cpp | 6 +++--- layout/svg/nsSVGTextFrame2.cpp | 7 +++++++ layout/svg/nsSVGUtils.h | 2 ++ 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index a445e310f4d7..acdcba7c86c0 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -704,8 +704,7 @@ nsFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext) nsIFrame* anonBlock = svgTextFrame->GetFirstPrincipalChild(); // Just as in nsSVGTextFrame2::DidSetStyleContext, we need to ensure that // any non-display nsSVGTextFrame2s get reflowed when a child text frame - // gets new style. We don't need to do this when the frame has not yet - // been reflowed, since that will happen soon anyway. + // gets new style. // // Note that we must check NS_FRAME_FIRST_REFLOW on our nsSVGTextFrame2's // anonymous block frame rather than our self, since NS_FRAME_FIRST_REFLOW @@ -713,7 +712,8 @@ nsFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext) // document's first reflow. (In which case this DidSetStyleContext call may // be happening under frame construction under a Reflow() call.) if (anonBlock && !(anonBlock->GetStateBits() & NS_FRAME_FIRST_REFLOW) && - (svgTextFrame->GetStateBits() & NS_FRAME_IS_NONDISPLAY)) { + (svgTextFrame->GetStateBits() & NS_FRAME_IS_NONDISPLAY) && + !(svgTextFrame->GetStateBits() & NS_STATE_SVG_TEXT_IN_REFLOW)) { svgTextFrame->ScheduleReflowSVGNonDisplayText(); } } diff --git a/layout/svg/nsSVGTextFrame2.cpp b/layout/svg/nsSVGTextFrame2.cpp index eaff904adc29..d11a9b516420 100644 --- a/layout/svg/nsSVGTextFrame2.cpp +++ b/layout/svg/nsSVGTextFrame2.cpp @@ -3170,6 +3170,9 @@ nsSVGTextFrame2::ScheduleReflowSVGNonDisplayText() MOZ_ASSERT(!nsSVGUtils::OuterSVGIsCallingReflowSVG(this), "do not call ScheduleReflowSVGNonDisplayText when the outer SVG " "frame is under ReflowSVG"); + MOZ_ASSERT(!(mState & NS_STATE_SVG_TEXT_IN_REFLOW), + "do not call ScheduleReflowSVGNonDisplayText while reflowing the " + "anonymous block child"); // We need to find an ancestor frame that we can call FrameNeedsReflow // on that will cause the document to be marked as needing relayout, @@ -5044,6 +5047,8 @@ nsSVGTextFrame2::DoReflow() kid->MarkIntrinsicWidthsDirty(); } + mState |= NS_STATE_SVG_TEXT_IN_REFLOW; + nscoord width = kid->GetPrefWidth(renderingContext); nsHTMLReflowState reflowState(presContext, kid, renderingContext, @@ -5061,6 +5066,8 @@ nsSVGTextFrame2::DoReflow() kid->DidReflow(presContext, &reflowState, nsDidReflowStatus::FINISHED); kid->SetSize(nsSize(desiredSize.width, desiredSize.height)); + mState &= ~NS_STATE_SVG_TEXT_IN_REFLOW; + TextNodeCorrespondenceRecorder::RecordCorrespondence(this); } diff --git a/layout/svg/nsSVGUtils.h b/layout/svg/nsSVGUtils.h index 1300bb8dceeb..dc37aa5f874b 100644 --- a/layout/svg/nsSVGUtils.h +++ b/layout/svg/nsSVGUtils.h @@ -103,6 +103,8 @@ class Element; */ #define NS_STATE_SVG_POSITIONING_MAY_USE_PERCENTAGES NS_FRAME_STATE_BIT(23) +#define NS_STATE_SVG_TEXT_IN_REFLOW NS_FRAME_STATE_BIT(24) + /** * Byte offsets of channels in a native packed gfxColor or cairo image surface. */