Bug 1177943 - Part 1. Add LookUpDictionary method to widget. r=masayuki draft
authorMakoto Kato <m_kato@ga2.so-net.ne.jp>
Mon, 04 Apr 2016 17:14:36 +0900
changeset 368215 0b92c9a7159a793ba8eb65545ac4970bf44cfcf6
parent 367997 f3f2fa1d7eed5a8262f6401ef18ff8117a3ce43e
child 368216 3976d86ec5dbc005399f7171eafdd1c15d0619f6
push id18471
push userm_kato@ga2.so-net.ne.jp
push dateWed, 18 May 2016 11:49:22 +0000
reviewersmasayuki
bugs1177943
milestone49.0a1
Bug 1177943 - Part 1. Add LookUpDictionary method to widget. r=masayuki I would like to add new method to look up dictionary. MozReview-Commit-ID: Jqk0OelezVF
widget/cocoa/TextInputHandler.mm
widget/cocoa/nsChildView.h
widget/cocoa/nsChildView.mm
widget/cocoa/nsCocoaUtils.h
widget/cocoa/nsCocoaUtils.mm
widget/nsIWidget.h
--- a/widget/cocoa/TextInputHandler.mm
+++ b/widget/cocoa/TextInputHandler.mm
@@ -3318,37 +3318,23 @@ IMEInputHandler::GetAttributedSubstringF
      this, TrueOrFalse(textContent.mSucceeded),
      NS_ConvertUTF16toUTF8(textContent.mReply.mString).get(),
      textContent.mReply.mOffset));
 
   if (!textContent.mSucceeded) {
     return nil;
   }
 
-  NSString* nsstr = nsCocoaUtils::ToNSString(textContent.mReply.mString);
+  // We don't set vertical information at this point.  If required,
+  // OS will calls drawsVerticallyForCharacterAtIndex.
   NSMutableAttributedString* result =
-    [[[NSMutableAttributedString alloc] initWithString:nsstr
-                                            attributes:nil] autorelease];
-  const nsTArray<FontRange>& fontRanges = textContent.mReply.mFontRanges;
-  int32_t lastOffset = textContent.mReply.mString.Length();
-  for (auto i = fontRanges.Length(); i > 0; --i) {
-    const FontRange& fontRange = fontRanges[i - 1];
-    NSString* fontName = nsCocoaUtils::ToNSString(fontRange.mFontName);
-    CGFloat fontSize = fontRange.mFontSize / mWidget->BackingScaleFactor();
-    NSFont* font = [NSFont fontWithName:fontName size:fontSize];
-    if (!font) {
-      font = [NSFont systemFontOfSize:fontSize];
-    }
-
-    NSDictionary* attrs = @{ NSFontAttributeName: font };
-    NSRange range = NSMakeRange(fontRange.mStartOffset,
-                                lastOffset - fontRange.mStartOffset);
-    [result setAttributes:attrs range:range];
-    lastOffset = fontRange.mStartOffset;
-  }
+    nsCocoaUtils::GetNSMutableAttributedString(textContent.mReply.mString,
+                                               textContent.mReply.mFontRanges,
+                                               false,
+                                               mWidget->BackingScaleFactor());
   if (aActualRange) {
     aActualRange->location = textContent.mReply.mOffset;
     aActualRange->length = textContent.mReply.mString.Length();
   }
   return result;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
 }
--- a/widget/cocoa/nsChildView.h
+++ b/widget/cocoa/nsChildView.h
@@ -498,16 +498,22 @@ public:
 
   virtual void UpdateThemeGeometries(const nsTArray<ThemeGeometry>& aThemeGeometries) override;
 
   virtual void UpdateWindowDraggingRegion(const LayoutDeviceIntRegion& aRegion) override;
   const LayoutDeviceIntRegion& GetDraggableRegion() { return mDraggableRegion; }
 
   virtual void ReportSwipeStarted(uint64_t aInputBlockId, bool aStartSwipe) override;
 
+  virtual void LookUpDictionary(
+                 const nsAString& aText,
+                 const nsTArray<mozilla::FontRange>& aFontRangeArray,
+                 const bool aIsVertical,
+                 const LayoutDeviceIntPoint& aPoint) override;
+
   void              ResetParent();
 
   static bool DoHasPendingInputEvent();
   static uint32_t GetCurrentInputEventCount();
   static void UpdateCurrentInputEventCount();
 
   NSView<mozView>* GetEditorView();
 
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -2861,16 +2861,45 @@ nsChildView::DispatchAPZWheelInputEvent(
       return;
   }
   if (event.mMessage == eWheel &&
       (event.mDeltaX != 0 || event.mDeltaY != 0)) {
     DispatchEvent(&event, status);
   }
 }
 
+void
+nsChildView::LookUpDictionary(
+               const nsAString& aText,
+               const nsTArray<mozilla::FontRange>& aFontRangeArray,
+               const bool aIsVertical,
+               const LayoutDeviceIntPoint& aPoint)
+{
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
+
+  NSMutableAttributedString* attrStr =
+    nsCocoaUtils::GetNSMutableAttributedString(aText, aFontRangeArray,
+                                               aIsVertical,
+                                               BackingScaleFactor());
+  NSPoint pt =
+    nsCocoaUtils::DevPixelsToCocoaPoints(aPoint, BackingScaleFactor());
+  NSDictionary* attributes = [attrStr attributesAtIndex:0 effectiveRange:nil];
+  NSFont* font = [attributes objectForKey:NSFontAttributeName];
+  if (font) {
+    if (aIsVertical) {
+      pt.x -= [font descender];
+    } else {
+      pt.y += [font ascender];
+    }
+  }
+  [mView showDefinitionForAttributedString:attrStr atPoint:pt];
+
+  NS_OBJC_END_TRY_ABORT_BLOCK;
+}
+
 #ifdef ACCESSIBILITY
 already_AddRefed<a11y::Accessible>
 nsChildView::GetDocumentAccessible()
 {
   if (!mozilla::a11y::ShouldA11yBeEnabled())
     return nullptr;
 
   if (mAccessible) {
--- a/widget/cocoa/nsCocoaUtils.h
+++ b/widget/cocoa/nsCocoaUtils.h
@@ -381,11 +381,20 @@ public:
    */
   static uint32_t ConvertGeckoNameToMacCharCode(const nsAString& aKeyCodeName);
 
   /**
    * Converts a Gecko key code (like NS_VK_HOME) to the corresponding Cocoa
    * Unicode character.
    */
   static uint32_t ConvertGeckoKeyCodeToMacCharCode(uint32_t aKeyCode);
+
+  /**
+   * Convert string with font attribute to NSMutableAttributedString
+   */
+  static NSMutableAttributedString* GetNSMutableAttributedString(
+           const nsAString& aText,
+           const nsTArray<mozilla::FontRange>& aFontRanges,
+           const bool aIsVertical,
+           const CGFloat aBackingScaleFactor);
 };
 
 #endif // nsCocoaUtils_h_
--- a/widget/cocoa/nsCocoaUtils.mm
+++ b/widget/cocoa/nsCocoaUtils.mm
@@ -976,8 +976,50 @@ nsCocoaUtils::ConvertGeckoKeyCodeToMacCh
   for (uint16_t i = 0; i < ArrayLength(gKeyConversions); ++i) {
     if (gKeyConversions[i].geckoKeyCode == aKeyCode) {
       return gKeyConversions[i].charCode;
     }
   }
 
   return 0;
 }
+
+NSMutableAttributedString*
+nsCocoaUtils::GetNSMutableAttributedString(
+                const nsAString& aText,
+                const nsTArray<mozilla::FontRange>& aFontRanges,
+                const bool aIsVertical,
+                const CGFloat aBackingScaleFactor)
+{
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL
+
+  NSString* nsstr = nsCocoaUtils::ToNSString(aText);
+  NSMutableAttributedString* attrStr =
+    [[[NSMutableAttributedString alloc] initWithString:nsstr
+                                            attributes:nil] autorelease];
+
+  int32_t lastOffset = aText.Length();
+  for (auto i = aFontRanges.Length(); i > 0; --i) {
+    const FontRange& fontRange = aFontRanges[i - 1];
+    NSString* fontName = nsCocoaUtils::ToNSString(fontRange.mFontName);
+    CGFloat fontSize = fontRange.mFontSize / aBackingScaleFactor;
+    NSFont* font = [NSFont fontWithName:fontName size:fontSize];
+    if (!font) {
+      font = [NSFont systemFontOfSize:fontSize];
+    }
+
+    NSDictionary* attrs = @{ NSFontAttributeName: font };
+    NSRange range = NSMakeRange(fontRange.mStartOffset,
+                                lastOffset - fontRange.mStartOffset);
+    [attrStr setAttributes:attrs range:range];
+    lastOffset = fontRange.mStartOffset;
+  }
+
+  if (aIsVertical) {
+    [attrStr addAttribute:NSVerticalGlyphFormAttributeName
+                    value:[NSNumber numberWithInt: 1]
+                    range:NSMakeRange(0, [attrStr length])];
+  }
+
+  return attrStr;
+
+  NS_OBJC_END_TRY_ABORT_BLOCK_NIL
+}
--- a/widget/nsIWidget.h
+++ b/widget/nsIWidget.h
@@ -1956,16 +1956,32 @@ public:
      *                          NS_OK if the key event isn't consumed.
      *                          NS_SUCCESS_EVENT_HANDLED_ASYNCHRONOUSLY if the
      *                          key event will be handled asynchronously.
      */
     virtual nsresult OnWindowedPluginKeyEvent(
                        const mozilla::NativeEventData& aKeyEventData,
                        nsIKeyEventInPluginCallback* aCallback);
 
+
+    /**
+     * LookUpDictionary shows the dictionary for the word around current point.
+     *
+     * @param aText            the word to look up dictiorary.
+     * @param aFontRangeArray  text decoration of aText
+     * @param aIsVertical      true if the word is vertical layout
+     * @param aPoint           top-left point of aText
+     */
+    virtual void LookUpDictionary(
+                   const nsAString& aText,
+                   const nsTArray<mozilla::FontRange>& aFontRangeArray,
+                   const bool aIsVertical,
+                   const LayoutDeviceIntPoint& aPoint)
+    { }
+
 protected:
     /**
      * Like GetDefaultScale, but taking into account only the system settings
      * and ignoring Gecko preferences.
      */
     virtual double GetDefaultScaleInternal() { return 1.0; }
 
     // keep the list of children.  We also keep track of our siblings.