@@ -409,15 +409,16 @@ struct TextRenderedRun {
409409
410410
411411
412- TextRenderedRun (nsTextFrame* aFrame, const gfxPoint& aPosition ,
413- float aLengthAdjustScaleFactor , double aRotate,
412+ TextRenderedRun (nsTextFrame* aFrame, SVGTextFrame* aSVGTextFrame ,
413+ const gfxPoint& aPosition , double aRotate,
414414 float aFontSizeScaleFactor, nscoord aBaseline,
415415 uint32_t aTextFrameContentOffset,
416416 uint32_t aTextFrameContentLength,
417417 uint32_t aTextElementCharIndex)
418418 : mFrame (aFrame),
419+ mRoot (aSVGTextFrame),
419420 mPosition(aPosition),
420- mLengthAdjustScaleFactor(aLengthAdjustScaleFactor ),
421+ mLengthAdjustScaleFactor(mRoot -> mLengthAdjustScaleFactor ),
421422 mRotate(static_cast <float >(aRotate)),
422423 mFontSizeScaleFactor(aFontSizeScaleFactor),
423424 mBaseline(aBaseline),
@@ -664,6 +665,11 @@ struct TextRenderedRun {
664665
665666
666667
668+ SVGTextFrame* mRoot ;
669+
670+
671+
672+
667673
668674
669675
@@ -964,13 +970,61 @@ void TextRenderedRun::GetClipEdges(nscoord& aVisIStartEdge,
964970
965971
966972
967- nscoord startEdge = textRun->GetAdvanceWidth (
968- Range (frameRange.start , runRange.start ), &provider);
973+ auto MeasureUsingCache = [&](SVGTextFrame::CachedMeasuredRange& aCachedRange,
974+ const Range& aRange) -> nscoord {
975+ if (aRange.Intersects (aCachedRange.mRange )) {
976+
977+
978+ Range startDelta, endDelta;
979+ int startSign = 0 , endSign = 0 ;
980+ if (aRange.start < aCachedRange.mRange .start ) {
981+
982+ startSign = 1 ;
983+ startDelta = Range (aRange.start , aCachedRange.mRange .start );
984+ } else if (aRange.start > aCachedRange.mRange .start ) {
985+
986+ startSign = -1 ;
987+ startDelta = Range (aCachedRange.mRange .start , aRange.start );
988+ }
989+ if (aRange.end > aCachedRange.mRange .end ) {
990+
991+ endSign = 1 ;
992+ endDelta = Range (aCachedRange.mRange .end , aRange.end );
993+ } else if (aRange.end < aCachedRange.mRange .end ) {
994+
995+ endSign = -1 ;
996+ endDelta = Range (aRange.end , aCachedRange.mRange .end );
997+ }
998+
999+
1000+
1001+ if (startDelta.Length () + endDelta.Length () < aRange.Length ()) {
1002+ if (startSign) {
1003+ aCachedRange.mAdvance +=
1004+ startSign * textRun->GetAdvanceWidth (startDelta, &provider);
1005+ }
1006+ if (endSign) {
1007+ aCachedRange.mAdvance +=
1008+ endSign * textRun->GetAdvanceWidth (endDelta, &provider);
1009+ }
1010+ } else {
1011+ aCachedRange.mAdvance = textRun->GetAdvanceWidth (aRange, &provider);
1012+ }
1013+ } else {
1014+
1015+ aCachedRange.mAdvance = textRun->GetAdvanceWidth (aRange, &provider);
1016+ }
1017+ aCachedRange.mRange = aRange;
1018+ return aCachedRange.mAdvance ;
1019+ };
9691020
970-
971-
1021+ mRoot ->SetCurrentFrameForCaching (mFrame );
1022+ nscoord startEdge =
1023+ MeasureUsingCache (mRoot ->CachedRange (SVGTextFrame::WhichRange::Before),
1024+ Range (frameRange.start , runRange.start ));
9721025 nscoord endEdge =
973- textRun->GetAdvanceWidth (Range (runRange.end , frameRange.end ), &provider);
1026+ MeasureUsingCache (mRoot ->CachedRange (SVGTextFrame::WhichRange::After),
1027+ Range (runRange.end , frameRange.end ));
9741028
9751029 if (textRun->IsRightToLeft ()) {
9761030 aVisIStartEdge = endEdge;
@@ -1900,9 +1954,8 @@ TextRenderedRun TextRenderedRunIterator::Next() {
19001954 }
19011955 }
19021956
1903- mCurrent = TextRenderedRun (frame, pt, Root ()->mLengthAdjustScaleFactor ,
1904- rotate, mFontSizeScaleFactor , baseline, offset,
1905- length, charIndex);
1957+ mCurrent = TextRenderedRun (frame, Root (), pt, rotate, mFontSizeScaleFactor ,
1958+ baseline, offset, length, charIndex);
19061959 return mCurrent ;
19071960}
19081961
@@ -5108,6 +5161,9 @@ void SVGTextFrame::DoReflow() {
51085161 RemoveStateBits (NS_FRAME_IS_DIRTY | NS_FRAME_HAS_DIRTY_CHILDREN);
51095162 }
51105163
5164+
5165+ mFrameForCachedRanges = nullptr ;
5166+
51115167 nsPresContext* presContext = PresContext ();
51125168 nsIFrame* kid = PrincipalChildList ().FirstChild ();
51135169 if (!kid) {
0 commit comments