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:
Masayuki Nakano 2015-06-05 18:28:19 +09:00
Родитель cbee1c5997
Коммит afe24ee3a4
4 изменённых файлов: 191 добавлений и 29 удалений

Просмотреть файл

@ -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;
};