зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1166436 part.4 mozilla::ContentCache should store text rects and caret rect and TabParent should use them r=m_kato
This commit is contained in:
Родитель
cbee1c5997
Коммит
afe24ee3a4
|
@ -262,7 +262,6 @@ TabParent::TabParent(nsIContentParent* aManager,
|
|||
: TabContext(aContext)
|
||||
, mFrameElement(nullptr)
|
||||
, mWritingMode()
|
||||
, mIMECompositionRectOffset(0)
|
||||
, mRect(0, 0, 0, 0)
|
||||
, mDimensions(0, 0)
|
||||
, mOrientation(0)
|
||||
|
@ -1939,11 +1938,12 @@ TabParent::RecvNotifyIMESelectedCompositionRect(
|
|||
const uint32_t& aCaretOffset,
|
||||
const LayoutDeviceIntRect& aCaretRect)
|
||||
{
|
||||
// add rect to cache for another query
|
||||
mIMECompositionRectOffset = aOffset;
|
||||
mIMECompositionRects = aRects;
|
||||
mIMECaretOffset = aCaretOffset;
|
||||
mIMECaretRect = aCaretRect;
|
||||
if (!mContentCache.InitTextRectArray(aOffset, aRects)) {
|
||||
NS_WARNING("Failed to set text rect array");
|
||||
}
|
||||
if (!mContentCache.InitCaretRect(aCaretOffset, aCaretRect)) {
|
||||
NS_WARNING("Failed to set caret rect");
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget();
|
||||
if (!widget) {
|
||||
|
@ -2020,8 +2020,8 @@ TabParent::RecvNotifyIMEPositionChange(
|
|||
const LayoutDeviceIntRect& aCaretRect)
|
||||
{
|
||||
mIMEEditorRect = aEditorRect;
|
||||
mIMECompositionRects = aCompositionRects;
|
||||
mIMECaretRect = aCaretRect;
|
||||
mContentCache.UpdateTextRectArray(aCompositionRects);
|
||||
mContentCache.UpdateCaretRect(aCaretRect);
|
||||
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget();
|
||||
if (!widget) {
|
||||
|
@ -2250,21 +2250,12 @@ TabParent::HandleQueryContentEvent(WidgetQueryContentEvent& aEvent)
|
|||
break;
|
||||
case NS_QUERY_TEXT_RECT:
|
||||
{
|
||||
if (aEvent.mInput.mOffset < mIMECompositionRectOffset ||
|
||||
(aEvent.mInput.mOffset + aEvent.mInput.mLength >
|
||||
mIMECompositionRectOffset + mIMECompositionRects.Length())) {
|
||||
// XXX
|
||||
// we doesn't have cache for this request.
|
||||
if (!mContentCache.GetUnionTextRects(aEvent.mInput.mOffset,
|
||||
aEvent.mInput.mLength,
|
||||
aEvent.mReply.mRect)) {
|
||||
// XXX We don't have cache for this request.
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t baseOffset = aEvent.mInput.mOffset - mIMECompositionRectOffset;
|
||||
uint32_t endOffset = baseOffset + aEvent.mInput.mLength;
|
||||
aEvent.mReply.mRect.SetEmpty();
|
||||
for (uint32_t i = baseOffset; i < endOffset; i++) {
|
||||
aEvent.mReply.mRect =
|
||||
aEvent.mReply.mRect.Union(mIMECompositionRects[i]);
|
||||
}
|
||||
if (aEvent.mInput.mOffset < mContentCache.TextLength()) {
|
||||
aEvent.mReply.mString =
|
||||
Substring(mContentCache.Text(), aEvent.mInput.mOffset,
|
||||
|
@ -2274,19 +2265,20 @@ TabParent::HandleQueryContentEvent(WidgetQueryContentEvent& aEvent)
|
|||
aEvent.mReply.mString.Truncate();
|
||||
}
|
||||
aEvent.mReply.mOffset = aEvent.mInput.mOffset;
|
||||
aEvent.mReply.mRect = aEvent.mReply.mRect - GetChildProcessOffset();
|
||||
aEvent.mReply.mRect -= GetChildProcessOffset();
|
||||
aEvent.mReply.mWritingMode = mWritingMode;
|
||||
aEvent.mSucceeded = true;
|
||||
}
|
||||
break;
|
||||
case NS_QUERY_CARET_RECT:
|
||||
{
|
||||
if (aEvent.mInput.mOffset != mIMECaretOffset) {
|
||||
if (!mContentCache.GetCaretRect(aEvent.mInput.mOffset,
|
||||
aEvent.mReply.mRect)) {
|
||||
break;
|
||||
}
|
||||
|
||||
aEvent.mReply.mOffset = mIMECaretOffset;
|
||||
aEvent.mReply.mRect = mIMECaretRect - GetChildProcessOffset();
|
||||
aEvent.mReply.mOffset = aEvent.mInput.mOffset;
|
||||
aEvent.mReply.mRect -= GetChildProcessOffset();
|
||||
aEvent.mSucceeded = true;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -480,10 +480,6 @@ protected:
|
|||
ContentCache mContentCache;
|
||||
mozilla::WritingMode mWritingMode;
|
||||
|
||||
uint32_t mIMECompositionRectOffset;
|
||||
InfallibleTArray<LayoutDeviceIntRect> mIMECompositionRects;
|
||||
uint32_t mIMECaretOffset;
|
||||
LayoutDeviceIntRect mIMECaretRect;
|
||||
LayoutDeviceIntRect mIMEEditorRect;
|
||||
|
||||
nsIntRect mRect;
|
||||
|
|
|
@ -13,6 +13,10 @@ namespace mozilla {
|
|||
|
||||
using namespace widget;
|
||||
|
||||
/*****************************************************************************
|
||||
* mozilla::ContentCache
|
||||
*****************************************************************************/
|
||||
|
||||
ContentCache::ContentCache()
|
||||
: mCompositionStart(UINT32_MAX)
|
||||
, mCompositionEventsDuringRequest(0)
|
||||
|
@ -40,6 +44,68 @@ ContentCache::SetSelection(uint32_t aAnchorOffset, uint32_t aFocusOffset)
|
|||
mSelection.mFocus = aFocusOffset;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentCache::InitTextRectArray(uint32_t aOffset,
|
||||
const RectArray& aTextRectArray)
|
||||
{
|
||||
if (NS_WARN_IF(aOffset >= TextLength()) ||
|
||||
NS_WARN_IF(aOffset + aTextRectArray.Length() > TextLength())) {
|
||||
return false;
|
||||
}
|
||||
mTextRectArray.mStart = aOffset;
|
||||
mTextRectArray.mRects = aTextRectArray;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentCache::GetTextRect(uint32_t aOffset,
|
||||
LayoutDeviceIntRect& aTextRect) const
|
||||
{
|
||||
if (NS_WARN_IF(!mTextRectArray.InRange(aOffset))) {
|
||||
aTextRect.SetEmpty();
|
||||
return false;
|
||||
}
|
||||
aTextRect = mTextRectArray.GetRect(aOffset);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentCache::GetUnionTextRects(uint32_t aOffset,
|
||||
uint32_t aLength,
|
||||
LayoutDeviceIntRect& aUnionTextRect) const
|
||||
{
|
||||
if (NS_WARN_IF(!mTextRectArray.InRange(aOffset, aLength))) {
|
||||
aUnionTextRect.SetEmpty();
|
||||
return false;
|
||||
}
|
||||
aUnionTextRect = mTextRectArray.GetUnionRect(aOffset, aLength);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentCache::InitCaretRect(uint32_t aOffset,
|
||||
const LayoutDeviceIntRect& aCaretRect)
|
||||
{
|
||||
if (NS_WARN_IF(aOffset > TextLength())) {
|
||||
return false;
|
||||
}
|
||||
mCaret.mOffset = aOffset;
|
||||
mCaret.mRect = aCaretRect;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentCache::GetCaretRect(uint32_t aOffset,
|
||||
LayoutDeviceIntRect& aCaretRect) const
|
||||
{
|
||||
if (mCaret.mOffset != aOffset) {
|
||||
aCaretRect.SetEmpty();
|
||||
return false;
|
||||
}
|
||||
aCaretRect = mCaret.mRect;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentCache::OnCompositionEvent(const WidgetCompositionEvent& aEvent)
|
||||
{
|
||||
|
@ -101,4 +167,32 @@ ContentCache::RequestToCommitComposition(nsIWidget* aWidget,
|
|||
return mCompositionEventsDuringRequest;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* mozilla::ContentCache::TextRectArray
|
||||
*****************************************************************************/
|
||||
|
||||
LayoutDeviceIntRect
|
||||
ContentCache::TextRectArray::GetRect(uint32_t aOffset) const
|
||||
{
|
||||
LayoutDeviceIntRect rect;
|
||||
if (InRange(aOffset)) {
|
||||
rect = mRects[aOffset - mStart];
|
||||
}
|
||||
return rect;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/EventForwards.h"
|
||||
#include "nsString.h"
|
||||
#include "nsTArray.h"
|
||||
#include "Units.h"
|
||||
|
||||
class nsIWidget;
|
||||
|
||||
|
@ -27,6 +29,8 @@ namespace mozilla {
|
|||
class ContentCache final
|
||||
{
|
||||
public:
|
||||
typedef InfallibleTArray<LayoutDeviceIntRect> RectArray;
|
||||
|
||||
ContentCache();
|
||||
|
||||
void Clear();
|
||||
|
@ -75,6 +79,25 @@ public:
|
|||
uint32_t SelectionEnd() const { return mSelection.EndOffset(); }
|
||||
uint32_t SelectionLength() const { return mSelection.Length(); }
|
||||
|
||||
bool UpdateTextRectArray(const RectArray& aTextRectArray)
|
||||
{
|
||||
return InitTextRectArray(mTextRectArray.mStart, aTextRectArray);
|
||||
}
|
||||
bool InitTextRectArray(uint32_t aOffset, const RectArray& aTextRectArray);
|
||||
bool GetTextRect(uint32_t aOffset,
|
||||
LayoutDeviceIntRect& aTextRect) const;
|
||||
bool GetUnionTextRects(uint32_t aOffset,
|
||||
uint32_t aLength,
|
||||
LayoutDeviceIntRect& aUnionTextRect) const;
|
||||
|
||||
bool UpdateCaretRect(const LayoutDeviceIntRect& aCaretRect)
|
||||
{
|
||||
return InitCaretRect(mCaret.mOffset, aCaretRect);
|
||||
}
|
||||
bool InitCaretRect(uint32_t aOffset, const LayoutDeviceIntRect& aCaretRect);
|
||||
uint32_t CaretOffset() const { return mCaret.mOffset; }
|
||||
bool GetCaretRect(uint32_t aOffset, LayoutDeviceIntRect& aCaretRect) const;
|
||||
|
||||
private:
|
||||
// Whole text in the target
|
||||
nsString mText;
|
||||
|
@ -108,6 +131,63 @@ private:
|
|||
}
|
||||
} mSelection;
|
||||
|
||||
struct Caret final
|
||||
{
|
||||
uint32_t mOffset;
|
||||
LayoutDeviceIntRect mRect;
|
||||
|
||||
Caret()
|
||||
: mOffset(UINT32_MAX)
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t Offset() const
|
||||
{
|
||||
NS_WARN_IF(mOffset == UINT32_MAX);
|
||||
return mOffset;
|
||||
}
|
||||
} mCaret;
|
||||
|
||||
struct TextRectArray final
|
||||
{
|
||||
uint32_t mStart;
|
||||
RectArray mRects;
|
||||
|
||||
TextRectArray()
|
||||
: mStart(UINT32_MAX)
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t StartOffset() const
|
||||
{
|
||||
NS_WARN_IF(mStart == UINT32_MAX);
|
||||
return mStart;
|
||||
}
|
||||
uint32_t EndOffset() const
|
||||
{
|
||||
if (NS_WARN_IF(mStart == UINT32_MAX) ||
|
||||
NS_WARN_IF(static_cast<uint64_t>(mStart) + mRects.Length() >
|
||||
UINT32_MAX)) {
|
||||
return UINT32_MAX;
|
||||
}
|
||||
return mStart + mRects.Length();
|
||||
}
|
||||
bool InRange(uint32_t aOffset) const
|
||||
{
|
||||
return mStart != UINT32_MAX &&
|
||||
StartOffset() <= aOffset && aOffset < EndOffset();
|
||||
}
|
||||
bool InRange(uint32_t aOffset, uint32_t aLength) const
|
||||
{
|
||||
if (NS_WARN_IF(static_cast<uint64_t>(aOffset) + aLength > UINT32_MAX)) {
|
||||
return false;
|
||||
}
|
||||
return InRange(aOffset) && aOffset + aLength <= EndOffset();
|
||||
}
|
||||
LayoutDeviceIntRect GetRect(uint32_t aOffset) const;
|
||||
LayoutDeviceIntRect GetUnionRect(uint32_t aOffset, uint32_t aLength) const;
|
||||
} mTextRectArray;
|
||||
|
||||
bool mIsComposing;
|
||||
bool mRequestedToCommitOrCancelComposition;
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче