Bug 489951 [TSF] Korean TIP's composition string looks like normal text r=VYV03354, sr=roc
authorMasayuki Nakano <masayuki@d-toybox.com>
Fri, 15 May 2009 09:45:15 +0900
changeset 28351 422c2a0c712b651b691fedeb610461c8cebb6bb8
parent 28350 38d50cc03a7209f8315746fb2aa9ac32363872f0
child 28352 7e016af801e478c6dbf89b2edacf303dd1c6f2ec
push idunknown
push userunknown
push dateunknown
reviewersVYV03354, roc
bugs489951
milestone1.9.2a1pre
Bug 489951 [TSF] Korean TIP's composition string looks like normal text r=VYV03354, sr=roc
editor/libeditor/base/IMETextTxn.cpp
widget/public/nsGUIEvent.h
widget/src/windows/nsTextStore.cpp
--- a/editor/libeditor/base/IMETextTxn.cpp
+++ b/editor/libeditor/base/IMETextTxn.cpp
@@ -313,16 +313,18 @@ NS_IMETHODIMP IMETextTxn::CollapseTextSe
                break;
           result = textRange->GetRangeEnd(&selectionEnd);
           NS_ASSERTION(NS_SUCCEEDED(result), "cannot get range end");
           if(NS_FAILED(result))
                break;
 
           if(nsIPrivateTextRange::TEXTRANGE_CARETPOSITION == textRangeType)
           {
+             NS_ASSERTION(selectionStart == selectionEnd,
+                          "nsEditor doesn't support wide caret");
              // Set the caret....
              result = selection->Collapse(mElement,
                       mOffset+selectionStart);
              NS_ASSERTION(NS_SUCCEEDED(result), "Cannot Collapse");
              if(NS_SUCCEEDED(result))
              setCaret = PR_TRUE;
           } else {
              // NS_ASSERTION(selectionStart != selectionEnd, "end == start");
--- a/widget/public/nsGUIEvent.h
+++ b/widget/public/nsGUIEvent.h
@@ -860,21 +860,27 @@ struct nsTextRangeStyle
     DEFINED_LINESTYLE        = 0x01,
     DEFINED_FOREGROUND_COLOR = 0x02,
     DEFINED_BACKGROUND_COLOR = 0x04,
     DEFINED_UNDERLINE_COLOR  = 0x08
   };
 
   // Initialize all members, because nsTextRange instances may be compared by
   // memcomp.
-  nsTextRangeStyle() :
-    mDefinedStyles(DEFINED_NONE), mLineStyle(LINESTYLE_NONE),
-    mIsBoldLine(PR_FALSE), mForegroundColor(NS_RGBA(0, 0, 0, 0)),
-    mBackgroundColor(NS_RGBA(0, 0, 0, 0)), mUnderlineColor(NS_RGBA(0, 0, 0, 0))
+  nsTextRangeStyle()
   {
+    Clear();
+  }
+
+  void Clear()
+  {
+    mDefinedStyles = DEFINED_NONE;
+    mLineStyle = LINESTYLE_NONE;
+    mIsBoldLine = PR_FALSE;
+    mForegroundColor = mBackgroundColor = mUnderlineColor = NS_RGBA(0, 0, 0, 0);
   }
 
   PRBool IsDefined() const { return mDefinedStyles != DEFINED_NONE; }
 
   PRBool IsLineStyleDefined() const
   {
     return (mDefinedStyles & DEFINED_LINESTYLE) != 0;
   }
@@ -889,16 +895,22 @@ struct nsTextRangeStyle
     return (mDefinedStyles & DEFINED_BACKGROUND_COLOR) != 0;
   }
 
   PRBool IsUnderlineColorDefined() const
   {
     return (mDefinedStyles & DEFINED_UNDERLINE_COLOR) != 0;
   }
 
+  PRBool IsNoChangeStyle() const
+  {
+    return !IsForegroundColorDefined() && !IsBackgroundColorDefined() &&
+           IsLineStyleDefined() && mLineStyle == LINESTYLE_NONE;
+  }
+
   PRBool Equals(const nsTextRangeStyle& aOther)
   {
     if (mDefinedStyles != aOther.mDefinedStyles)
       return PR_FALSE;
     if (IsLineStyleDefined() && (mLineStyle != aOther.mLineStyle ||
                                  !mIsBoldLine != !aOther.mIsBoldLine))
       return PR_FALSE;
     if (IsForegroundColorDefined() &&
--- a/widget/src/windows/nsTextStore.cpp
+++ b/widget/src/windows/nsTextStore.cpp
@@ -696,22 +696,16 @@ nsTextStore::SendTextEventForComposition
 
   nsRefPtr<IEnumTfRanges> enumRanges;
   hr = attrPropetry->EnumRanges(TfEditCookie(mEditCookie),
                                 getter_AddRefs(enumRanges), composingRange);
   NS_ENSURE_TRUE(SUCCEEDED(hr) && enumRanges, hr);
 
   nsAutoTArray<nsTextRange, 4> textRanges;
   nsTextRange newRange;
-  newRange.mStartOffset =
-    PRUint32(mCompositionSelection.acpStart - mCompositionStart);
-  newRange.mEndOffset =
-    PRUint32(mCompositionSelection.acpEnd - mCompositionStart);
-  newRange.mRangeType = NS_TEXTRANGE_CARETPOSITION;
-  textRanges.AppendElement(newRange);
   // No matter if we have display attribute info or not,
   // we always pass in at least one range to NS_TEXT_TEXT
   newRange.mStartOffset = 0;
   newRange.mEndOffset = mCompositionString.Length();
   newRange.mRangeType = NS_TEXTRANGE_RAWINPUT;
   textRanges.AppendElement(newRange);
 
   nsRefPtr<ITfRange> range;
@@ -758,16 +752,49 @@ nsTextStore::SendTextEventForComposition
       // So that ranges don't overlap and confuse the editor
       lastRange = newRange;
     } else {
       lastRange.mEndOffset = newRange.mStartOffset;
       textRanges.AppendElement(newRange);
     }
   }
 
+  // We need to hack for Korean Input System which is Korean standard TIP.
+  // It sets no change style to IME selection (the selection is always only
+  // one).  So, the composition string looks like normal (or committed) string.
+  // At this time, mCompositionSelection range is same as the composition
+  // string range.  Other applications set a wide caret which covers the
+  // composition string, however, Gecko doesn't support the wide caret drawing
+  // now (Gecko doesn't support XOR drawing), unfortunately.  For now, we should
+  // change the range style to undefined.
+  if (mCompositionSelection.acpStart != mCompositionSelection.acpEnd &&
+      textRanges.Length() == 1) {
+    nsTextRange& range = textRanges[0];
+    LONG start = PR_MIN(mCompositionSelection.acpStart,
+                        mCompositionSelection.acpEnd);
+    LONG end = PR_MAX(mCompositionSelection.acpStart,
+                      mCompositionSelection.acpEnd);
+    if (range.mStartOffset == start - mCompositionStart &&
+        range.mEndOffset == end - mCompositionStart &&
+        range.mRangeStyle.IsNoChangeStyle()) {
+      range.mRangeStyle.Clear();
+      // The looks of selected type is better than others.
+      range.mRangeType = NS_TEXTRANGE_SELECTEDRAWTEXT;
+    }
+  }
+
+  // The caret position has to be collapsed.
+  LONG caretPosition = PR_MAX(mCompositionSelection.acpStart,
+                              mCompositionSelection.acpEnd);
+  caretPosition -= mCompositionStart;
+  nsTextRange caretRange;
+  caretRange.mStartOffset = caretRange.mEndOffset = PRUint32(caretPosition);
+  caretRange.mRangeType = NS_TEXTRANGE_CARETPOSITION;
+  textRanges.AppendElement(caretRange);
+
   event.theText = mCompositionString;
   event.rangeArray = textRanges.Elements();
   event.rangeCount = textRanges.Length();
 
   // If we are already send same text event, we should not resend it.  Because
   // it can be a cause of flickering.
   if (IsSameTextEvent(mLastDispatchedTextEvent, &event)) {
     PR_LOG(sTextStoreLog, PR_LOG_ALWAYS,