LayoutDeviceIntRect ContentCache::TextRectArray::GetUnionRect(uint32_t aOffset, uint32_t aLength) const { LayoutDeviceIntRect rect; if (!InRange(aOffset, aLength)) { return rect; } for (uint32_t i = 0; i < aLength; i++) { rect = rect.Union(mRects[aOffset - mStart + i]); } return rect; }
LayoutDeviceIntRect ContentCache::TextRectArray::GetUnionRectAsFarAsPossible( uint32_t aOffset, uint32_t aLength) const { LayoutDeviceIntRect rect; if (!IsOverlappingWith(aOffset, aLength)) { return rect; } uint32_t startOffset = std::max(aOffset, mStart); uint32_t endOffset = std::min(aOffset + aLength, EndOffset()); for (uint32_t i = 0; i < endOffset - startOffset; i++) { rect = rect.Union(mRects[startOffset - mStart + i]); } return rect; }
bool ContentCacheInParent::GetUnionTextRects( uint32_t aOffset, uint32_t aLength, LayoutDeviceIntRect& aUnionTextRect) const { MOZ_LOG(sContentCacheLog, LogLevel::Info, ("ContentCacheInParent: 0x%p GetUnionTextRects(aOffset=%u, " "aLength=%u), mTextRectArray={ mStart=%u, mRects.Length()=%u }, " "mSelection={ mAnchor=%u, mFocus=%u }", this, aOffset, aLength, mTextRectArray.mStart, mTextRectArray.mRects.Length(), mSelection.mAnchor, mSelection.mFocus)); CheckedInt<uint32_t> endOffset = CheckedInt<uint32_t>(aOffset) + aLength; if (!endOffset.isValid()) { return false; } if (!mSelection.Collapsed() && aOffset == mSelection.StartOffset() && aLength == mSelection.Length()) { NS_WARN_IF(mSelection.mRect.IsEmpty()); aUnionTextRect = mSelection.mRect; return !aUnionTextRect.IsEmpty(); } if (aLength == 1) { if (!aOffset) { NS_WARN_IF(mFirstCharRect.IsEmpty()); aUnionTextRect = mFirstCharRect; return !aUnionTextRect.IsEmpty(); } if (aOffset == mSelection.mAnchor) { NS_WARN_IF(mSelection.mAnchorCharRect.IsEmpty()); aUnionTextRect = mSelection.mAnchorCharRect; return !aUnionTextRect.IsEmpty(); } if (aOffset == mSelection.mFocus) { NS_WARN_IF(mSelection.mFocusCharRect.IsEmpty()); aUnionTextRect = mSelection.mFocusCharRect; return !aUnionTextRect.IsEmpty(); } } // Even if some text rects are not cached of the queried range, // we should return union rect when the first character's rect is cached // since the first character rect is important and the others are not so // in most cases. if (!aOffset && aOffset != mSelection.mAnchor && aOffset != mSelection.mFocus && !mTextRectArray.InRange(aOffset)) { // The first character rect isn't cached. return false; } if (mTextRectArray.IsOverlappingWith(aOffset, aLength)) { aUnionTextRect = mTextRectArray.GetUnionRectAsFarAsPossible(aOffset, aLength); } else { aUnionTextRect.SetEmpty(); } if (!aOffset) { aUnionTextRect = aUnionTextRect.Union(mFirstCharRect); } if (aOffset <= mSelection.mAnchor && mSelection.mAnchor < endOffset.value()) { aUnionTextRect = aUnionTextRect.Union(mSelection.mAnchorCharRect); } if (aOffset <= mSelection.mFocus && mSelection.mFocus < endOffset.value()) { aUnionTextRect = aUnionTextRect.Union(mSelection.mFocusCharRect); } return !aUnionTextRect.IsEmpty(); }