bool ContentCacheInParent::GetCaretRect(uint32_t aOffset, LayoutDeviceIntRect& aCaretRect) const { MOZ_LOG(sContentCacheLog, LogLevel::Info, ("ContentCacheInParent: 0x%p GetCaretRect(aOffset=%u), " "mCaret={ mOffset=%u, mRect=%s, IsValid()=%s }, mTextRectArray={ " "mStart=%u, mRects.Length()=%u }, mSelection={ mAnchor=%u, mFocus=%u, " "mWritingMode=%s, mAnchorCharRect=%s, mFocusCharRect=%s }, " "mFirstCharRect=%s", this, aOffset, mCaret.mOffset, GetRectText(mCaret.mRect).get(), GetBoolName(mCaret.IsValid()), mTextRectArray.mStart, mTextRectArray.mRects.Length(), mSelection.mAnchor, mSelection.mFocus, GetWritingModeName(mSelection.mWritingMode).get(), GetRectText(mSelection.mAnchorCharRect).get(), GetRectText(mSelection.mFocusCharRect).get(), GetRectText(mFirstCharRect).get())); if (mCaret.IsValid() && mCaret.mOffset == aOffset) { aCaretRect = mCaret.mRect; return true; } // Guess caret rect from the text rect if it's stored. if (!GetTextRect(aOffset, aCaretRect)) { // There might be previous character rect in the cache. If so, we can // guess the caret rect with it. if (!aOffset || !GetTextRect(aOffset - 1, aCaretRect)) { aCaretRect.SetEmpty(); return false; } if (mSelection.mWritingMode.IsVertical()) { aCaretRect.y = aCaretRect.YMost(); } else { // XXX bidi-unaware. aCaretRect.x = aCaretRect.XMost(); } } // XXX This is not bidi aware because we don't cache each character's // direction. However, this is usually used by IME, so, assuming the // character is in LRT context must not cause any problem. if (mSelection.mWritingMode.IsVertical()) { aCaretRect.height = mCaret.IsValid() ? mCaret.mRect.height : 1; } else { aCaretRect.width = mCaret.IsValid() ? mCaret.mRect.width : 1; } return true; }