Bug 1171810 ContentCache should store union text rect of whole selected text r=m_kato
authorMasayuki Nakano <masayuki@d-toybox.com>
Mon, 08 Jun 2015 11:46:17 +0900
changeset 247525 806b8b8fdbd69121e07e99f0facd9c9ae2ab5d8d
parent 247524 5a28a5474ba69778532f4f715b5b1213a5d4e5e4
child 247526 edaec128d6ecec869a03fafd3390cd493eb254c5
push id60737
push usermasayuki@d-toybox.com
push dateMon, 08 Jun 2015 02:46:33 +0000
treeherdermozilla-inbound@806b8b8fdbd6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersm_kato
bugs1171810
milestone41.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1171810 ContentCache should store union text rect of whole selected text r=m_kato
widget/ContentCache.cpp
widget/ContentCache.h
widget/nsGUIEventIPC.h
--- a/widget/ContentCache.cpp
+++ b/widget/ContentCache.cpp
@@ -140,24 +140,25 @@ ContentCache::AssignContent(const Conten
   mSelection = aOther.mSelection;
   mCaret = aOther.mCaret;
   mTextRectArray = aOther.mTextRectArray;
   mEditorRect = aOther.mEditorRect;
 
   MOZ_LOG(sContentCacheLog, LogLevel::Info,
     ("ContentCache: 0x%p (mIsChrome=%s) AssignContent(aNotification=%s), "
      "Succeeded, mText.Length()=%u, mSelection={ mAnchor=%u, mFocus=%u, "
-     "mWritingMode=%s, mAnchorCharRect=%s, mFocusCharRect=%s }, "
+     "mWritingMode=%s, mAnchorCharRect=%s, mFocusCharRect=%s, mRect=%s }, "
      "mCaret={ mOffset=%u, mRect=%s }, mTextRectArray={ mStart=%u, "
      "mRects.Length()=%u }, mEditorRect=%s",
      this, GetBoolName(mIsChrome), GetNotificationName(aNotification),
      mText.Length(), mSelection.mAnchor, mSelection.mFocus,
      GetWritingModeName(mSelection.mWritingMode).get(),
      GetRectText(mSelection.mAnchorCharRect).get(),
-     GetRectText(mSelection.mFocusCharRect).get(), mCaret.mOffset,
+     GetRectText(mSelection.mFocusCharRect).get(),
+     GetRectText(mSelection.mRect).get(), mCaret.mOffset,
      GetRectText(mCaret.mRect).get(), mTextRectArray.mStart,
      mTextRectArray.mRects.Length(), GetRectText(mEditorRect).get()));
 }
 
 void
 ContentCache::Clear()
 {
   MOZ_LOG(sContentCacheLog, LogLevel::Info,
@@ -590,16 +591,17 @@ ContentCache::CacheTextRects(nsIWidget* 
   // CacheTextRects() must be called in content process.
   if (NS_WARN_IF(mIsChrome)) {
     return false;
   }
 
   mTextRectArray.Clear();
   mSelection.mAnchorCharRect.SetEmpty();
   mSelection.mFocusCharRect.SetEmpty();
+  mSelection.mRect.SetEmpty();
 
   if (NS_WARN_IF(!mSelection.IsValid())) {
     return false;
   }
 
   // Retrieve text rects in composition string if there is.
   nsRefPtr<TextComposition> textComposition =
     IMEStateManager::GetTextCompositionFor(aWidget);
@@ -648,25 +650,42 @@ ContentCache::CacheTextRects(nsIWidget* 
       MOZ_LOG(sContentCacheLog, LogLevel::Error,
         ("ContentCache: 0x%p (mIsChrome=%s) CacheTextRects(), FAILED, "
          "couldn't retrieve text rect at focus of selection (%u)",
          this, GetBoolName(mIsChrome), mSelection.mFocus));
     }
     mSelection.mFocusCharRect = charRect;
   }
 
+  if (!mSelection.Collapsed()) {
+    nsEventStatus status = nsEventStatus_eIgnore;
+    WidgetQueryContentEvent textRect(true, NS_QUERY_TEXT_RECT, aWidget);
+    textRect.InitForQueryTextRect(mSelection.StartOffset(),
+                                  mSelection.Length());
+    aWidget->DispatchEvent(&textRect, status);
+    if (NS_WARN_IF(!textRect.mSucceeded)) {
+      MOZ_LOG(sContentCacheLog, LogLevel::Error,
+        ("ContentCache: 0x%p (mIsChrome=%s) CacheTextRects(), FAILED, "
+         "couldn't retrieve text rect of whole selected text",
+         this, GetBoolName(mIsChrome)));
+    } else {
+      mSelection.mRect = textRect.mReply.mRect;
+    }
+  }
+
   MOZ_LOG(sContentCacheLog, LogLevel::Info,
     ("ContentCache: 0x%p (mIsChrome=%s) CacheTextRects(), Succeeded, "
      "mText.Length()=%u, mTextRectArray={ mStart=%u, mRects.Length()=%u }, "
      "mSelection={ mAnchor=%u, mAnchorCharRect=%s, mFocus=%u, "
-     "mFocusCharRect=%s }",
+     "mFocusCharRect=%s, mRect=%s }",
      this, GetBoolName(mIsChrome), mText.Length(), mTextRectArray.mStart,
      mTextRectArray.mRects.Length(), mSelection.mAnchor,
      GetRectText(mSelection.mAnchorCharRect).get(), mSelection.mFocus,
-     GetRectText(mSelection.mFocusCharRect).get()));
+     GetRectText(mSelection.mFocusCharRect).get(),
+     GetRectText(mSelection.mRect).get()));
   return true;
 }
 
 void
 ContentCache::SetSelection(nsIWidget* aWidget,
                            uint32_t aStartOffset,
                            uint32_t aLength,
                            bool aReversed,
@@ -736,16 +755,23 @@ ContentCache::GetUnionTextRects(uint32_t
   MOZ_LOG(sContentCacheLog, LogLevel::Info,
     ("ContentCache: 0x%p (mIsChrome=%s) GetUnionTextRects(aOffset=%u, "
      "aLength=%u), mTextRectArray={ mStart=%u, mRects.Length()=%u }, "
      "mSelection={ mAnchor=%u, mFocus=%u }",
      this, GetBoolName(mIsChrome), aOffset, aLength,
      mTextRectArray.mStart, mTextRectArray.mRects.Length(),
      mSelection.mAnchor, mSelection.mFocus));
 
+  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 == mSelection.mAnchor) {
       NS_WARN_IF(mSelection.mAnchorCharRect.IsEmpty());
       aUnionTextRect = mSelection.mAnchorCharRect;
       return !aUnionTextRect.IsEmpty();
     }
     if (aOffset == mSelection.mFocus) {
       NS_WARN_IF(mSelection.mFocusCharRect.IsEmpty());
--- a/widget/ContentCache.h
+++ b/widget/ContentCache.h
@@ -165,28 +165,32 @@ private:
     uint32_t mFocus;
 
     WritingMode mWritingMode;
 
     // Character rects at next character of mAnchor and mFocus.
     LayoutDeviceIntRect mAnchorCharRect;
     LayoutDeviceIntRect mFocusCharRect;
 
+    // Whole rect of selected text. This is empty if the selection is collapsed.
+    LayoutDeviceIntRect mRect;
+
     Selection()
       : mAnchor(UINT32_MAX)
       , mFocus(UINT32_MAX)
     {
     }
 
     void Clear()
     {
       mAnchor = mFocus = UINT32_MAX;
       mWritingMode = WritingMode();
       mAnchorCharRect.SetEmpty();
       mFocusCharRect.SetEmpty();
+      mRect.SetEmpty();
     }
 
     bool IsValid() const
     {
       return mAnchor != UINT32_MAX && mFocus != UINT32_MAX;
     }
     bool Collapsed() const
     {
--- a/widget/nsGUIEventIPC.h
+++ b/widget/nsGUIEventIPC.h
@@ -802,31 +802,33 @@ struct ParamTraits<mozilla::ContentCache
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mText);
     WriteParam(aMsg, aParam.mSelection.mAnchor);
     WriteParam(aMsg, aParam.mSelection.mFocus);
     WriteParam(aMsg, aParam.mSelection.mWritingMode);
     WriteParam(aMsg, aParam.mSelection.mAnchorCharRect);
     WriteParam(aMsg, aParam.mSelection.mFocusCharRect);
+    WriteParam(aMsg, aParam.mSelection.mRect);
     WriteParam(aMsg, aParam.mCaret.mOffset);
     WriteParam(aMsg, aParam.mCaret.mRect);
     WriteParam(aMsg, aParam.mTextRectArray.mStart);
     WriteParam(aMsg, aParam.mTextRectArray.mRects);
     WriteParam(aMsg, aParam.mEditorRect);
   }
 
   static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
   {
     return ReadParam(aMsg, aIter, &aResult->mText) &&
            ReadParam(aMsg, aIter, &aResult->mSelection.mAnchor) &&
            ReadParam(aMsg, aIter, &aResult->mSelection.mFocus) &&
            ReadParam(aMsg, aIter, &aResult->mSelection.mWritingMode) &&
            ReadParam(aMsg, aIter, &aResult->mSelection.mAnchorCharRect) &&
            ReadParam(aMsg, aIter, &aResult->mSelection.mFocusCharRect) &&
+           ReadParam(aMsg, aIter, &aResult->mSelection.mRect) &&
            ReadParam(aMsg, aIter, &aResult->mCaret.mOffset) &&
            ReadParam(aMsg, aIter, &aResult->mCaret.mRect) &&
            ReadParam(aMsg, aIter, &aResult->mTextRectArray.mStart) &&
            ReadParam(aMsg, aIter, &aResult->mTextRectArray.mRects) &&
            ReadParam(aMsg, aIter, &aResult->mEditorRect);
   }
 };