Loading layout/generic/nsBlockFrame.cpp +8 −0 Original line number Diff line number Diff line Loading @@ -5268,6 +5268,14 @@ nsBlockFrame::AppendFrames(ChildListID aListID, printf("\n"); #endif if (nsSVGUtils::IsInSVGTextSubtree(this)) { MOZ_ASSERT(GetParent()->IsSVGTextFrame(), "unexpected block frame in SVG text"); // Workaround for bug 1399425 in case this bit has been removed from the // SVGTextFrame just before the parser adds more descendant nodes. GetParent()->AddStateBits(NS_STATE_SVG_TEXT_CORRESPONDENCE_DIRTY); } AddFrames(aFrameList, lastKid); if (aListID != kNoReflowPrincipalList) { PresContext()->PresShell()-> Loading layout/generic/nsFrameStateBits.h +4 −0 Original line number Diff line number Diff line Loading @@ -390,6 +390,10 @@ FRAME_STATE_BIT(SVG, 23, NS_STATE_SVG_POSITIONING_MAY_USE_PERCENTAGES) FRAME_STATE_BIT(SVG, 24, NS_STATE_SVG_TEXT_IN_REFLOW) // Set on SVGTextFrame frames when they need a // TextNodeCorrespondenceRecorder::RecordCorrespondence call // to update the cached nsTextNode indexes that they correspond to. FRAME_STATE_BIT(SVG, 25, NS_STATE_SVG_TEXT_CORRESPONDENCE_DIRTY) // == Frame state bits that apply to text frames ============================== Loading layout/svg/SVGTextFrame.cpp +32 −11 Original line number Diff line number Diff line Loading @@ -1392,8 +1392,13 @@ private: /* static */ void TextNodeCorrespondenceRecorder::RecordCorrespondence(SVGTextFrame* aRoot) { if (aRoot->GetStateBits() & NS_STATE_SVG_TEXT_CORRESPONDENCE_DIRTY) { // Resolve bidi so that continuation frames are created if necessary: aRoot->MaybeResolveBidiForAnonymousBlockChild(); TextNodeCorrespondenceRecorder recorder(aRoot); recorder.Record(aRoot); aRoot->RemoveStateBits(NS_STATE_SVG_TEXT_CORRESPONDENCE_DIRTY); } } void Loading Loading @@ -1728,9 +1733,9 @@ private: uint32_t TextFrameIterator::UndisplayedCharacters() const { MOZ_ASSERT(!(mRootFrame->PrincipalChildList().FirstChild() && NS_SUBTREE_DIRTY(mRootFrame->PrincipalChildList().FirstChild())), "should have already reflowed the anonymous block child"); MOZ_ASSERT(!(mRootFrame->GetStateBits() & NS_STATE_SVG_TEXT_CORRESPONDENCE_DIRTY), "Text correspondence must be up to date"); if (!mCurrentFrame) { return mRootFrame->mTrailingUndisplayedCharacters; Loading Loading @@ -2431,7 +2436,7 @@ CharIterator::CharIterator(SVGTextFrame* aSVGTextFrame, nsIContent* aSubtree, bool aPostReflow) : mFilter(aFilter), mFrameIterator(FrameIfAnonymousChildReflowed(aSVGTextFrame), aSubtree), mFrameIterator(aSVGTextFrame, aSubtree), mFrameForTrimCheck(nullptr), mTrimmedOffset(0), mTrimmedLength(0), Loading Loading @@ -3779,7 +3784,9 @@ SVGTextFrame::ReflowSVG() "ReflowSVG mechanism not designed for this"); if (!nsSVGUtils::NeedsReflowSVG(this)) { NS_ASSERTION(!(mState & NS_STATE_SVG_POSITIONING_DIRTY), "How did this happen?"); MOZ_ASSERT(!HasAnyStateBits(NS_STATE_SVG_TEXT_CORRESPONDENCE_DIRTY | NS_STATE_SVG_POSITIONING_DIRTY), "How did this happen?"); return; } Loading Loading @@ -5036,6 +5043,10 @@ SVGTextFrame::DoGlyphPositioning() return; } // Since we can be called directly via GetBBoxContribution, our correspondence // may not be up to date. TextNodeCorrespondenceRecorder::RecordCorrespondence(this); // Determine the positions of each character in app units. nsTArray<nsPoint> charPositions; DetermineCharPositions(charPositions); Loading Loading @@ -5222,7 +5233,11 @@ SVGTextFrame::ScheduleReflowSVG() void SVGTextFrame::NotifyGlyphMetricsChange() { AddStateBits(NS_STATE_SVG_POSITIONING_DIRTY); // TODO: perf - adding NS_STATE_SVG_TEXT_CORRESPONDENCE_DIRTY is overly // aggressive here. Ideally we would only set that bit when our descendant // frame tree changes (i.e. after frame construction). AddStateBits(NS_STATE_SVG_TEXT_CORRESPONDENCE_DIRTY | NS_STATE_SVG_POSITIONING_DIRTY); nsLayoutUtils::PostRestyleEvent( mContent->AsElement(), nsRestyleHint(0), nsChangeHint_InvalidateRenderingObservers); Loading Loading @@ -5274,6 +5289,9 @@ SVGTextFrame::MaybeReflowAnonymousBlockChild() // by nsSVGDisplayContainerFrame::ReflowSVG.) kid->AddStateBits(NS_FRAME_IS_DIRTY); } TextNodeCorrespondenceRecorder::RecordCorrespondence(this); MOZ_ASSERT(nsSVGUtils::AnyOuterSVGIsCallingReflowSVG(this), "should be under ReflowSVG"); nsPresContext::InterruptPreventer noInterrupts(PresContext()); Loading @@ -5286,7 +5304,12 @@ SVGTextFrame::DoReflow() { // Since we are going to reflow the anonymous block frame, we will // need to update mPositions. AddStateBits(NS_STATE_SVG_POSITIONING_DIRTY); // We also mark our text correspondence as dirty since we can end up needing // reflow in ways that do not set NS_STATE_SVG_TEXT_CORRESPONDENCE_DIRTY. // (We'd then fail the "expected a TextNodeCorrespondenceProperty" assertion // when UpdateGlyphPositioning() is called after we return.) AddStateBits(NS_STATE_SVG_TEXT_CORRESPONDENCE_DIRTY | NS_STATE_SVG_POSITIONING_DIRTY); if (mState & NS_FRAME_IS_NONDISPLAY) { // Normally, these dirty flags would be cleared in ReflowSVG(), but that Loading Loading @@ -5336,8 +5359,6 @@ SVGTextFrame::DoReflow() kid->SetSize(wm, desiredSize.Size(wm)); RemoveStateBits(NS_STATE_SVG_TEXT_IN_REFLOW); TextNodeCorrespondenceRecorder::RecordCorrespondence(this); } // Usable font size range in devpixels / user-units Loading layout/svg/SVGTextFrame.h +2 −1 Original line number Diff line number Diff line Loading @@ -203,7 +203,8 @@ protected: , mLastContextScale(1.0f) , mLengthAdjustScaleFactor(1.0f) { AddStateBits(NS_STATE_SVG_POSITIONING_DIRTY); AddStateBits(NS_STATE_SVG_TEXT_CORRESPONDENCE_DIRTY | NS_STATE_SVG_POSITIONING_DIRTY); } ~SVGTextFrame() {} Loading Loading
layout/generic/nsBlockFrame.cpp +8 −0 Original line number Diff line number Diff line Loading @@ -5268,6 +5268,14 @@ nsBlockFrame::AppendFrames(ChildListID aListID, printf("\n"); #endif if (nsSVGUtils::IsInSVGTextSubtree(this)) { MOZ_ASSERT(GetParent()->IsSVGTextFrame(), "unexpected block frame in SVG text"); // Workaround for bug 1399425 in case this bit has been removed from the // SVGTextFrame just before the parser adds more descendant nodes. GetParent()->AddStateBits(NS_STATE_SVG_TEXT_CORRESPONDENCE_DIRTY); } AddFrames(aFrameList, lastKid); if (aListID != kNoReflowPrincipalList) { PresContext()->PresShell()-> Loading
layout/generic/nsFrameStateBits.h +4 −0 Original line number Diff line number Diff line Loading @@ -390,6 +390,10 @@ FRAME_STATE_BIT(SVG, 23, NS_STATE_SVG_POSITIONING_MAY_USE_PERCENTAGES) FRAME_STATE_BIT(SVG, 24, NS_STATE_SVG_TEXT_IN_REFLOW) // Set on SVGTextFrame frames when they need a // TextNodeCorrespondenceRecorder::RecordCorrespondence call // to update the cached nsTextNode indexes that they correspond to. FRAME_STATE_BIT(SVG, 25, NS_STATE_SVG_TEXT_CORRESPONDENCE_DIRTY) // == Frame state bits that apply to text frames ============================== Loading
layout/svg/SVGTextFrame.cpp +32 −11 Original line number Diff line number Diff line Loading @@ -1392,8 +1392,13 @@ private: /* static */ void TextNodeCorrespondenceRecorder::RecordCorrespondence(SVGTextFrame* aRoot) { if (aRoot->GetStateBits() & NS_STATE_SVG_TEXT_CORRESPONDENCE_DIRTY) { // Resolve bidi so that continuation frames are created if necessary: aRoot->MaybeResolveBidiForAnonymousBlockChild(); TextNodeCorrespondenceRecorder recorder(aRoot); recorder.Record(aRoot); aRoot->RemoveStateBits(NS_STATE_SVG_TEXT_CORRESPONDENCE_DIRTY); } } void Loading Loading @@ -1728,9 +1733,9 @@ private: uint32_t TextFrameIterator::UndisplayedCharacters() const { MOZ_ASSERT(!(mRootFrame->PrincipalChildList().FirstChild() && NS_SUBTREE_DIRTY(mRootFrame->PrincipalChildList().FirstChild())), "should have already reflowed the anonymous block child"); MOZ_ASSERT(!(mRootFrame->GetStateBits() & NS_STATE_SVG_TEXT_CORRESPONDENCE_DIRTY), "Text correspondence must be up to date"); if (!mCurrentFrame) { return mRootFrame->mTrailingUndisplayedCharacters; Loading Loading @@ -2431,7 +2436,7 @@ CharIterator::CharIterator(SVGTextFrame* aSVGTextFrame, nsIContent* aSubtree, bool aPostReflow) : mFilter(aFilter), mFrameIterator(FrameIfAnonymousChildReflowed(aSVGTextFrame), aSubtree), mFrameIterator(aSVGTextFrame, aSubtree), mFrameForTrimCheck(nullptr), mTrimmedOffset(0), mTrimmedLength(0), Loading Loading @@ -3779,7 +3784,9 @@ SVGTextFrame::ReflowSVG() "ReflowSVG mechanism not designed for this"); if (!nsSVGUtils::NeedsReflowSVG(this)) { NS_ASSERTION(!(mState & NS_STATE_SVG_POSITIONING_DIRTY), "How did this happen?"); MOZ_ASSERT(!HasAnyStateBits(NS_STATE_SVG_TEXT_CORRESPONDENCE_DIRTY | NS_STATE_SVG_POSITIONING_DIRTY), "How did this happen?"); return; } Loading Loading @@ -5036,6 +5043,10 @@ SVGTextFrame::DoGlyphPositioning() return; } // Since we can be called directly via GetBBoxContribution, our correspondence // may not be up to date. TextNodeCorrespondenceRecorder::RecordCorrespondence(this); // Determine the positions of each character in app units. nsTArray<nsPoint> charPositions; DetermineCharPositions(charPositions); Loading Loading @@ -5222,7 +5233,11 @@ SVGTextFrame::ScheduleReflowSVG() void SVGTextFrame::NotifyGlyphMetricsChange() { AddStateBits(NS_STATE_SVG_POSITIONING_DIRTY); // TODO: perf - adding NS_STATE_SVG_TEXT_CORRESPONDENCE_DIRTY is overly // aggressive here. Ideally we would only set that bit when our descendant // frame tree changes (i.e. after frame construction). AddStateBits(NS_STATE_SVG_TEXT_CORRESPONDENCE_DIRTY | NS_STATE_SVG_POSITIONING_DIRTY); nsLayoutUtils::PostRestyleEvent( mContent->AsElement(), nsRestyleHint(0), nsChangeHint_InvalidateRenderingObservers); Loading Loading @@ -5274,6 +5289,9 @@ SVGTextFrame::MaybeReflowAnonymousBlockChild() // by nsSVGDisplayContainerFrame::ReflowSVG.) kid->AddStateBits(NS_FRAME_IS_DIRTY); } TextNodeCorrespondenceRecorder::RecordCorrespondence(this); MOZ_ASSERT(nsSVGUtils::AnyOuterSVGIsCallingReflowSVG(this), "should be under ReflowSVG"); nsPresContext::InterruptPreventer noInterrupts(PresContext()); Loading @@ -5286,7 +5304,12 @@ SVGTextFrame::DoReflow() { // Since we are going to reflow the anonymous block frame, we will // need to update mPositions. AddStateBits(NS_STATE_SVG_POSITIONING_DIRTY); // We also mark our text correspondence as dirty since we can end up needing // reflow in ways that do not set NS_STATE_SVG_TEXT_CORRESPONDENCE_DIRTY. // (We'd then fail the "expected a TextNodeCorrespondenceProperty" assertion // when UpdateGlyphPositioning() is called after we return.) AddStateBits(NS_STATE_SVG_TEXT_CORRESPONDENCE_DIRTY | NS_STATE_SVG_POSITIONING_DIRTY); if (mState & NS_FRAME_IS_NONDISPLAY) { // Normally, these dirty flags would be cleared in ReflowSVG(), but that Loading Loading @@ -5336,8 +5359,6 @@ SVGTextFrame::DoReflow() kid->SetSize(wm, desiredSize.Size(wm)); RemoveStateBits(NS_STATE_SVG_TEXT_IN_REFLOW); TextNodeCorrespondenceRecorder::RecordCorrespondence(this); } // Usable font size range in devpixels / user-units Loading
layout/svg/SVGTextFrame.h +2 −1 Original line number Diff line number Diff line Loading @@ -203,7 +203,8 @@ protected: , mLastContextScale(1.0f) , mLengthAdjustScaleFactor(1.0f) { AddStateBits(NS_STATE_SVG_POSITIONING_DIRTY); AddStateBits(NS_STATE_SVG_TEXT_CORRESPONDENCE_DIRTY | NS_STATE_SVG_POSITIONING_DIRTY); } ~SVGTextFrame() {} Loading