Bug 299603 part.1 IMContextWrapper should have a method to initialize a TextRange r=m_kato
authorMasayuki Nakano <masayuki@d-toybox.com>
Wed, 19 Aug 2015 16:37:39 +0900
changeset 280246 1a1992d30ee3ff10c30577f5a9fff8fa97c1272c
parent 280238 7dd543ff5fe1301c3b12d41e57b935a03369c1c2
child 280247 02ab221ff043df27e820b2630a412d796c8f1e8d
push idunknown
push userunknown
push dateunknown
reviewersm_kato
bugs299603
milestone43.0a1
Bug 299603 part.1 IMContextWrapper should have a method to initialize a TextRange r=m_kato
widget/gtk/IMContextWrapper.cpp
widget/gtk/IMContextWrapper.h
--- a/widget/gtk/IMContextWrapper.cpp
+++ b/widget/gtk/IMContextWrapper.cpp
@@ -1429,86 +1429,22 @@ IMContextWrapper::CreateTextRangeArray(G
             ("GTKIM: %p   CreateTextRangeArray(), FAILED, iterator couldn't "
              "be allocated",
              this));
         pango_attr_list_unref(feedback_list);
         g_free(preedit_string);
         return textRangeArray.forget();
     }
 
-    /*
-     * Depend on gtk2's implementation on XIM support.
-     * In aFeedback got from gtk2, there are only three types of data:
-     * PANGO_ATTR_UNDERLINE, PANGO_ATTR_FOREGROUND, PANGO_ATTR_BACKGROUND.
-     * Corresponding to XIMUnderline, XIMReverse.
-     * Don't take PANGO_ATTR_BACKGROUND into account, since
-     * PANGO_ATTR_BACKGROUND and PANGO_ATTR_FOREGROUND are always
-     * a couple.
-     */
     do {
-        PangoAttribute* attrUnderline =
-            pango_attr_iterator_get(iter, PANGO_ATTR_UNDERLINE);
-        PangoAttribute* attrForeground =
-            pango_attr_iterator_get(iter, PANGO_ATTR_FOREGROUND);
-        if (!attrUnderline && !attrForeground) {
+        TextRange range;
+        if (!SetTextRange(iter, preedit_string, range)) {
             continue;
         }
-
-        // Get the range of the current attribute(s)
-        gint start, end;
-        pango_attr_iterator_range(iter, &start, &end);
-
-        TextRange range;
-        // XIMReverse | XIMUnderline
-        if (attrUnderline && attrForeground) {
-            range.mRangeType = NS_TEXTRANGE_SELECTEDCONVERTEDTEXT;
-        }
-        // XIMUnderline
-        else if (attrUnderline) {
-            range.mRangeType = NS_TEXTRANGE_CONVERTEDTEXT;
-        }
-        // XIMReverse
-        else if (attrForeground) {
-            range.mRangeType = NS_TEXTRANGE_SELECTEDRAWTEXT;
-        } else {
-            range.mRangeType = NS_TEXTRANGE_RAWINPUT;
-        }
-
-        gunichar2* uniStr = nullptr;
-        if (start == 0) {
-            range.mStartOffset = 0;
-        } else {
-            glong uniStrLen;
-            uniStr = g_utf8_to_utf16(preedit_string, start,
-                                     nullptr, &uniStrLen, nullptr);
-            if (uniStr) {
-                range.mStartOffset = uniStrLen;
-                g_free(uniStr);
-                uniStr = nullptr;
-            }
-        }
-
-        glong uniStrLen;
-        uniStr = g_utf8_to_utf16(preedit_string + start, end - start,
-                                 nullptr, &uniStrLen, nullptr);
-        if (!uniStr) {
-            range.mEndOffset = range.mStartOffset;
-        } else {
-            range.mEndOffset = range.mStartOffset + uniStrLen;
-            g_free(uniStr);
-            uniStr = nullptr;
-        }
-
         textRangeArray->AppendElement(range);
-
-        MOZ_LOG(gGtkIMLog, LogLevel::Debug,
-            ("GTKIM: %p   CreateTextRangeArray(), mStartOffset=%u, "
-             "mEndOffset=%u, mRangeType=%s",
-             this, range.mStartOffset, range.mEndOffset,
-             GetRangeTypeName(range.mRangeType)));
     } while (pango_attr_iterator_next(iter));
 
     TextRange range;
     if (cursor_pos < 0) {
         range.mStartOffset = 0;
     } else if (uint32_t(cursor_pos) > aLastDispatchedData.Length()) {
         range.mStartOffset = aLastDispatchedData.Length();
     } else {
@@ -1526,16 +1462,94 @@ IMContextWrapper::CreateTextRangeArray(G
 
     pango_attr_iterator_destroy(iter);
     pango_attr_list_unref(feedback_list);
     g_free(preedit_string);
 
     return textRangeArray.forget();
 }
 
+bool
+IMContextWrapper::SetTextRange(PangoAttrIterator* aPangoAttrIter,
+                               const gchar* aUTF8CompositionString,
+                               TextRange& aTextRange) const
+{
+    /**
+     * Depend on gtk2's implementation on XIM support.
+     * In aFeedback got from gtk2, there are only three types of data:
+     * PANGO_ATTR_UNDERLINE, PANGO_ATTR_FOREGROUND, PANGO_ATTR_BACKGROUND.
+     * Corresponding to XIMUnderline, XIMReverse.
+     * Don't take PANGO_ATTR_BACKGROUND into account, since
+     * PANGO_ATTR_BACKGROUND and PANGO_ATTR_FOREGROUND are always
+     * a couple.
+     */
+
+    PangoAttribute* attrUnderline =
+        pango_attr_iterator_get(aPangoAttrIter, PANGO_ATTR_UNDERLINE);
+    PangoAttribute* attrForeground =
+        pango_attr_iterator_get(aPangoAttrIter, PANGO_ATTR_FOREGROUND);
+    if (!attrUnderline && !attrForeground) {
+        MOZ_LOG(gGtkIMLog, LogLevel::Warning,
+            ("GTKIM: %p   SetTextRange(), FAILED, due to no attr", this));
+        return false;
+    }
+
+    // Get the range of the current attribute(s)
+    gint start, end;
+    pango_attr_iterator_range(aPangoAttrIter, &start, &end);
+
+    // XIMReverse | XIMUnderline
+    if (attrUnderline && attrForeground) {
+        aTextRange.mRangeType = NS_TEXTRANGE_SELECTEDCONVERTEDTEXT;
+    }
+    // XIMUnderline
+    else if (attrUnderline) {
+        aTextRange.mRangeType = NS_TEXTRANGE_CONVERTEDTEXT;
+    }
+    // XIMReverse
+    else if (attrForeground) {
+        aTextRange.mRangeType = NS_TEXTRANGE_SELECTEDRAWTEXT;
+    } else {
+        aTextRange.mRangeType = NS_TEXTRANGE_RAWINPUT;
+    }
+
+    gunichar2* uniStr = nullptr;
+    if (start == 0) {
+        aTextRange.mStartOffset = 0;
+    } else {
+        glong uniStrLen;
+        uniStr = g_utf8_to_utf16(aUTF8CompositionString, start,
+                                 nullptr, &uniStrLen, nullptr);
+        if (uniStr) {
+            aTextRange.mStartOffset = uniStrLen;
+            g_free(uniStr);
+            uniStr = nullptr;
+        }
+    }
+
+    glong uniStrLen;
+    uniStr = g_utf8_to_utf16(aUTF8CompositionString + start, end - start,
+                             nullptr, &uniStrLen, nullptr);
+    if (!uniStr) {
+        aTextRange.mEndOffset = aTextRange.mStartOffset;
+    } else {
+        aTextRange.mEndOffset = aTextRange.mStartOffset + uniStrLen;
+        g_free(uniStr);
+        uniStr = nullptr;
+    }
+
+    MOZ_LOG(gGtkIMLog, LogLevel::Debug,
+        ("GTKIM: %p   SetTextRange(), succeeded, aTextRange= { "
+         "mStartOffset=%u, mEndOffset=%u, mRangeType=%s }",
+         this, aTextRange.mStartOffset, aTextRange.mEndOffset,
+         GetRangeTypeName(aTextRange.mRangeType)));
+
+    return true;
+}
+
 void
 IMContextWrapper::SetCursorPosition(GtkIMContext* aContext)
 {
     MOZ_LOG(gGtkIMLog, LogLevel::Info,
         ("GTKIM: %p SetCursorPosition(aContext=%p), "
          "mCompositionTargetRange={ mOffset=%u, mLength=%u }"
          "mSelection={ mOffset=%u, mLength=%u, mWritingMode=%s }",
          this, aContext, mCompositionTargetRange.mOffset,
--- a/widget/gtk/IMContextWrapper.h
+++ b/widget/gtk/IMContextWrapper.h
@@ -349,16 +349,30 @@ protected:
      *                              of current composition.  This should be
      *                              mDispatchedCompositionString.
      */
     already_AddRefed<TextRangeArray>
         CreateTextRangeArray(GtkIMContext* aContext,
                              const nsAString& aLastDispatchedData);
 
     /**
+     * SetTextRange() initializes aTextRange with aPangoAttrIter.
+     *
+     * @param aPangoAttrIter            An iter which represents a clause of the
+     *                                  composition string.
+     * @param aUTF8CompositionString    The whole composition string (UTF-8).
+     * @param aTextRange                The result.
+     * @return                          true if this initializes aTextRange.
+     *                                  Otherwise, false.
+     */
+    bool SetTextRange(PangoAttrIterator* aPangoAttrIter,
+                      const gchar* aUTF8CompositionString,
+                      TextRange& aTextRange) const;
+
+    /**
      * Move the candidate window with "fake" cursor position.
      *
      * @param aContext              A GtkIMContext which is being handled.
      */
     void SetCursorPosition(GtkIMContext* aContext);
 
     // Queries the current selection offset of the window.
     uint32_t GetSelectionOffset(nsWindow* aWindow);