Bug 1257446 part.3 nsTextFrame::GetCharacterRectsInRange() shouldn't call gfxSkipCharsIterator::AdvanceOriginal() before checking if the current offset has already been reached to the end for avoiding assertions r=jfkthame
New eQueryTextRectArray causes a lot of assertions in various automated tests. The cause is that nsTextFrame::GetCharacterRectsInRange() calls gfxSkipCharsIterator::AdvanceOriginal(1) at the end of the |for| loop *without* checking if the iterator has already reached to the end.
MozReview-Commit-ID: 3KFxA11uOUc
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -7448,41 +7448,39 @@ nsTextFrame::GetCharacterRectsInRange(in
gfxSkipCharsIterator iter = EnsureTextRun(nsTextFrame::eInflated);
PropertyProvider properties(this, iter, nsTextFrame::eInflated);
// Don't trim trailing whitespace, we want the caret to appear in the right
// place if it's positioned there
properties.InitializeForDisplay(false);
UpdateIteratorFromOffset(properties, aInOffset, iter);
- for (int32_t i = 0; i < aLength; i++) {
- if (aInOffset > GetContentEnd()) {
- break;
- }
-
+ const int32_t kContentEnd = GetContentEnd();
+ const int32_t kEndOffset = std::min(aInOffset + aLength, kContentEnd + 1);
+ while (aInOffset < kEndOffset) {
if (!iter.IsOriginalCharSkipped() &&
!mTextRun->IsClusterStart(iter.GetSkippedOffset())) {
FindClusterStart(mTextRun,
properties.GetStart().GetOriginalOffset() +
properties.GetOriginalLength(),
&iter);
}
nsPoint point = GetPointFromIterator(iter, properties);
nsRect rect;
rect.x = point.x;
rect.y = point.y;
nscoord iSize = 0;
- gfxSkipCharsIterator nextIter(iter);
- if (aInOffset < GetContentEnd()) {
+ if (aInOffset < kContentEnd) {
+ gfxSkipCharsIterator nextIter(iter);
nextIter.AdvanceOriginal(1);
if (!nextIter.IsOriginalCharSkipped() &&
!mTextRun->IsClusterStart(nextIter.GetSkippedOffset())) {
- FindClusterEnd(mTextRun, GetContentEnd(), &nextIter);
+ FindClusterEnd(mTextRun, kContentEnd, &nextIter);
}
gfxFloat advance =
mTextRun->GetAdvanceWidth(Range(iter.GetSkippedOffset(),
nextIter.GetSkippedOffset()),
&properties);
iSize = NSToCoordCeilClamped(advance);
}
@@ -7494,19 +7492,21 @@ nsTextFrame::GetCharacterRectsInRange(in
rect.width = iSize;
rect.height = mRect.height;
if (StyleContext()->IsTextCombined()) {
rect.width *= GetTextCombineScaleFactor(this);
}
}
aRects.AppendElement(rect);
-
- iter.AdvanceOriginal(1);
aInOffset++;
+ // Don't advance iter if we've reached the end
+ if (aInOffset < kEndOffset) {
+ iter.AdvanceOriginal(1);
+ }
}
return NS_OK;
}
nsresult
nsTextFrame::GetChildFrameContainingOffset(int32_t aContentOffset,
bool aHint,