From ff065c3a99f002a825eb6cfc7d5592c65eced868 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sun, 31 Jul 2016 17:08:56 -0700 Subject: [PATCH] Bug 1288938: Allow passing different reasons to dirty a non display SVG text frame. r=heycam Otherwise, when a glyph changes, we might end up doing too much work, destroying the text-run and the observer that dirtied the frame, causing an assertion when trying to delete it from the observer set. MozReview-Commit-ID: LMQVr6pYFVM --- layout/generic/nsFrame.cpp | 2 +- layout/generic/nsTextFrame.cpp | 2 +- layout/svg/SVGTextFrame.cpp | 9 ++++----- layout/svg/SVGTextFrame.h | 10 ++++++---- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 772d66a75ba5..3978f1c05f93 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -843,7 +843,7 @@ nsFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext) if (anonBlock && !(anonBlock->GetStateBits() & NS_FRAME_FIRST_REFLOW) && (svgTextFrame->GetStateBits() & NS_FRAME_IS_NONDISPLAY) && !(svgTextFrame->GetStateBits() & NS_STATE_SVG_TEXT_IN_REFLOW)) { - svgTextFrame->ScheduleReflowSVGNonDisplayText(); + svgTextFrame->ScheduleReflowSVGNonDisplayText(nsIPresShell::eStyleChange); } } diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp index 4c242c9345f3..38c44ca6c840 100644 --- a/layout/generic/nsTextFrame.cpp +++ b/layout/generic/nsTextFrame.cpp @@ -655,7 +655,7 @@ InvalidateFrameDueToGlyphsChanged(nsIFrame* aFrame) auto svgTextFrame = static_cast( nsLayoutUtils::GetClosestFrameOfType(f, nsGkAtoms::svgTextFrame)); - svgTextFrame->ScheduleReflowSVGNonDisplayText(); + svgTextFrame->ScheduleReflowSVGNonDisplayText(nsIPresShell::eResize); } else { // Theoretically we could just update overflow areas, perhaps using // OverflowChangedTracker, but that would do a bunch of work eagerly that diff --git a/layout/svg/SVGTextFrame.cpp b/layout/svg/SVGTextFrame.cpp index 975692fe7afc..d754c0d5f597 100644 --- a/layout/svg/SVGTextFrame.cpp +++ b/layout/svg/SVGTextFrame.cpp @@ -3322,7 +3322,7 @@ SVGTextFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext) // child to be reflowed when it is next painted, and (b) not cause the // to be repainted anyway since the user of the would not // know it needs to be repainted. - ScheduleReflowSVGNonDisplayText(); + ScheduleReflowSVGNonDisplayText(nsIPresShell::eStyleChange); } } @@ -3356,7 +3356,7 @@ SVGTextFrame::ReflowSVGNonDisplayText() } void -SVGTextFrame::ScheduleReflowSVGNonDisplayText() +SVGTextFrame::ScheduleReflowSVGNonDisplayText(nsIPresShell::IntrinsicDirty aReason) { MOZ_ASSERT(!nsSVGUtils::OuterSVGIsCallingReflowSVG(this), "do not call ScheduleReflowSVGNonDisplayText when the outer SVG " @@ -3394,8 +3394,7 @@ SVGTextFrame::ScheduleReflowSVGNonDisplayText() MOZ_ASSERT(f, "should have found an ancestor frame to reflow"); - PresContext()->PresShell()->FrameNeedsReflow( - f, nsIPresShell::eStyleChange, NS_FRAME_IS_DIRTY); + PresContext()->PresShell()->FrameNeedsReflow(f, aReason, NS_FRAME_IS_DIRTY); } NS_IMPL_ISUPPORTS(SVGTextFrame::MutationObserver, nsIMutationObserver) @@ -5296,7 +5295,7 @@ void SVGTextFrame::ScheduleReflowSVG() { if (mState & NS_FRAME_IS_NONDISPLAY) { - ScheduleReflowSVGNonDisplayText(); + ScheduleReflowSVGNonDisplayText(nsIPresShell::eStyleChange); } else { nsSVGUtils::ScheduleReflowSVG(this); } diff --git a/layout/svg/SVGTextFrame.h b/layout/svg/SVGTextFrame.h index 28272595913d..8d9147d4a751 100644 --- a/layout/svg/SVGTextFrame.h +++ b/layout/svg/SVGTextFrame.h @@ -399,11 +399,13 @@ public: * nsSVGDisplayContainerFrame::ReflowSVG will call ReflowSVGNonDisplayText on * it. * - * The only case where we have to do this is in response to a style change on - * a non-display . It is done in response to glyphs changes on - * non-display (i.e., animated SVG-in-OpenType glyphs). + * We have to do this in two cases: in response to a style change on a + * non-display , where aReason will be eStyleChange (the common case), + * and also in response to glyphs changes on non-display (i.e., + * animated SVG-in-OpenType glyphs), in which case aReason will be eResize, + * since layout doesn't need to be recomputed. */ - void ScheduleReflowSVGNonDisplayText(); + void ScheduleReflowSVGNonDisplayText(nsIPresShell::IntrinsicDirty aReason); /** * Updates the mFontSizeScaleFactor value by looking at the range of