Bug 1177943 - Part 1. Add LookUpDictionary method to widget. r?masayuki draft
authorMakoto Kato <m_kato@ga2.so-net.ne.jp>
Fri, 01 Apr 2016 15:01:18 +0900
changeset 346483 cbf56661d3afa01a22adb90855aacf3976a884d9
parent 346302 bccb11375f2af838cda714d42fd8cef78f5c7bf1
child 346484 b31eb0fc715e822150ce4fa24b702d08209d3c5f
push id14395
push userm_kato@ga2.so-net.ne.jp
push dateFri, 01 Apr 2016 06:23:11 +0000
reviewersmasayuki
bugs1177943
milestone48.0a1
Bug 1177943 - Part 1. Add LookUpDictionary method to widget. r?masayuki I would like to 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/nsBaseWidget.h
widget/nsIWidget.h
--- a/widget/cocoa/TextInputHandler.mm
+++ b/widget/cocoa/TextInputHandler.mm
@@ -3318,37 +3318,20 @@ 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);
   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,
+                                               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 nsString& 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
@@ -2850,16 +2850,49 @@ nsChildView::DispatchAPZWheelInputEvent(
       MOZ_CRASH("unexpected event type");
       return;
   }
   if (event.mMessage == eWheel && (event.deltaX != 0 || event.deltaY != 0)) {
     DispatchEvent(&event, status);
   }
 }
 
+void
+nsChildView::LookUpDictionary(
+               const nsString& aText,
+               const nsTArray<mozilla::FontRange>& aFontRangeArray,
+               const bool aIsVertical,
+               const LayoutDeviceIntPoint& aPoint)
+{
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
+
+  NSMutableAttributedString* attrStr =
+    nsCocoaUtils::GetNSMutableAttributedString(aText, aFontRangeArray,
+                                               BackingScaleFactor());
+  NSPoint pt =
+    nsCocoaUtils::DevPixelsToCocoaPoints(aPoint, BackingScaleFactor());
+  NSDictionary* attributes = [attrStr attributesAtIndex:0 effectiveRange:nil];
+  if (aIsVertical) {
+    [attrStr addAttribute:NSVerticalGlyphFormAttributeName
+                    value:[NSNumber numberWithInt: 1]
+                    range:NSMakeRange(0, [attrStr length])];
+  }
+  NSFont* font = [attributes objectForKey:NSFontAttributeName];
+  if (font) {
+    if (aIsVertical) {
+      pt.x -= [font decender];
+    } 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
@@ -367,11 +367,19 @@ 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 nsString& aText,
+           const nsTArray<mozilla::FontRange>& aFontRanges,
+           const CGFloat aBackingScaleFactor);
 };
 
 #endif // nsCocoaUtils_h_
--- a/widget/cocoa/nsCocoaUtils.mm
+++ b/widget/cocoa/nsCocoaUtils.mm
@@ -975,8 +975,42 @@ 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 nsString& aText,
+                const nsTArray<mozilla::FontRange>& aFontRanges,
+                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;
+  }
+  return attrStr;
+
+  NS_OBJC_END_TRY_ABORT_BLOCK_NIL
+}
--- a/widget/nsBaseWidget.h
+++ b/widget/nsBaseWidget.h
@@ -440,16 +440,23 @@ protected:
   { return NS_ERROR_NOT_IMPLEMENTED; }
 
   /**
    * GetPseudoIMEContext() returns pseudo IME context when TextEventDispatcher
    * has non-native input transaction.  Otherwise, returns nullptr.
    */
   void* GetPseudoIMEContext();
 
+  virtual void LookUpDictionary(
+                 const nsString& aText,
+                 const nsTArray<mozilla::FontRange>& aFontRangeArray,
+                 const bool aIsVertical,
+                 const LayoutDeviceIntPoint& aPoint) override
+               { }
+
 protected:
   // Utility to check if an array of clip rects is equal to our
   // internally stored clip rect array mClipRects.
   bool IsWindowClipRegionEqual(const nsTArray<LayoutDeviceIntRect>& aRects);
 
   // Stores the clip rectangles in aRects into mClipRects.
   void StoreWindowClipRegion(const nsTArray<LayoutDeviceIntRect>& aRects);
 
--- a/widget/nsIWidget.h
+++ b/widget/nsIWidget.h
@@ -2060,16 +2060,22 @@ public:
     NS_IMETHOD_(TextEventDispatcherListener*)
       GetNativeTextEventDispatcherListener() = 0;
 
     virtual void ZoomToRect(const uint32_t& aPresShellId,
                             const FrameMetrics::ViewID& aViewId,
                             const CSSRect& aRect,
                             const uint32_t& aFlags) = 0;
 
+    virtual void LookUpDictionary(
+                   const nsString& aText,
+                   const nsTArray<mozilla::FontRange>& aFontRangeArray,
+                   const bool aIsVertical,
+                   const LayoutDeviceIntPoint& aPoint) = 0;
+
 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.