Merge "Announce keyboard mode changes as a WINDOW_STATE_CHANGED event." into jb-mr2-dev
diff --git a/java/res/values-es-rUS/strings.xml b/java/res/values-es-rUS/strings.xml
index 52ef956..71841f8 100644
--- a/java/res/values-es-rUS/strings.xml
+++ b/java/res/values-es-rUS/strings.xml
@@ -157,6 +157,6 @@
     <string name="read_external_dictionary_confirm_install_message" msgid="6898610163768980870">"¿Realmente quieres instalar este archivo para <xliff:g id="LOCALE_NAME">%s</xliff:g>?"</string>
     <string name="error" msgid="8940763624668513648">"Se produjo un error."</string>
     <string name="button_default" msgid="3988017840431881491">"Predeterminado"</string>
-    <string name="language_settings" msgid="1671153053201809031">"Idioma &amp; entrada"</string>
-    <string name="select_input_method" msgid="4301602374609275003">"Seleccionar método de introducción"</string>
+    <string name="language_settings" msgid="1671153053201809031">"Teclado e idioma"</string>
+    <string name="select_input_method" msgid="4301602374609275003">"Seleccionar método de entrada"</string>
 </resources>
diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java
index 1e5af51..d160038 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -519,11 +519,11 @@
         // TODO: Handle "bold" here too?
         if ((mLabelFlags & LABEL_FLAGS_FONT_NORMAL) != 0) {
             return Typeface.DEFAULT;
-        } else if ((mLabelFlags & LABEL_FLAGS_FONT_MONO_SPACE) != 0) {
-            return Typeface.MONOSPACE;
-        } else {
-            return params.mTypeface;
         }
+        if ((mLabelFlags & LABEL_FLAGS_FONT_MONO_SPACE) != 0) {
+            return Typeface.MONOSPACE;
+        }
+        return params.mTypeface;
     }
 
     public final int selectTextSize(final KeyDrawParams params) {
@@ -550,28 +550,51 @@
     public final int selectHintTextSize(final KeyDrawParams params) {
         if (hasHintLabel()) {
             return params.mHintLabelSize;
-        } else if (hasShiftedLetterHint()) {
-            return params.mShiftedLetterHintSize;
-        } else {
-            return params.mHintLetterSize;
         }
+        if (hasShiftedLetterHint()) {
+            return params.mShiftedLetterHintSize;
+        }
+        return params.mHintLetterSize;
     }
 
     public final int selectHintTextColor(final KeyDrawParams params) {
         if (hasHintLabel()) {
             return params.mHintLabelColor;
-        } else if (hasShiftedLetterHint()) {
+        }
+        if (hasShiftedLetterHint()) {
             return isShiftedLetterActivated() ? params.mShiftedLetterHintActivatedColor
                     : params.mShiftedLetterHintInactivatedColor;
-        } else {
-            return params.mHintLetterColor;
         }
+        return params.mHintLetterColor;
     }
 
     public final int selectMoreKeyTextSize(final KeyDrawParams params) {
         return hasLabelsInMoreKeys() ? params.mLabelSize : params.mLetterSize;
     }
 
+    public final String getPreviewLabel() {
+        return isShiftedLetterActivated() ? mHintLabel : mLabel;
+    }
+
+    private boolean previewHasLetterSize() {
+        return (mLabelFlags & LABEL_FLAGS_FOLLOW_KEY_LETTER_RATIO) != 0
+                || StringUtils.codePointCount(getPreviewLabel()) == 1;
+    }
+
+    public final int selectPreviewTextSize(final KeyDrawParams params) {
+        if (previewHasLetterSize()) {
+            return params.mPreviewTextSize;
+        }
+        return params.mLetterSize;
+    }
+
+    public Typeface selectPreviewTypeface(final KeyDrawParams params) {
+        if (previewHasLetterSize()) {
+            return selectTypeface(params);
+        }
+        return Typeface.DEFAULT_BOLD;
+    }
+
     public final boolean isAlignLeft() {
         return (mLabelFlags & LABEL_FLAGS_ALIGN_LEFT) != 0;
     }
diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
index bc27f85..d37b69b 100644
--- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
@@ -811,18 +811,14 @@
             background.setState(KEY_PREVIEW_BACKGROUND_DEFAULT_STATE);
             background.setAlpha(PREVIEW_ALPHA);
         }
-        final String label = key.isShiftedLetterActivated() ? key.mHintLabel : key.mLabel;
+        final String label = key.getPreviewLabel();
         // What we show as preview should match what we show on a key top in onDraw().
         if (label != null) {
             // TODO Should take care of temporaryShiftLabel here.
             previewText.setCompoundDrawables(null, null, null, null);
-            if (StringUtils.codePointCount(label) > 1) {
-                previewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, drawParams.mLetterSize);
-                previewText.setTypeface(Typeface.DEFAULT_BOLD);
-            } else {
-                previewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, drawParams.mPreviewTextSize);
-                previewText.setTypeface(key.selectTypeface(drawParams));
-            }
+            previewText.setTextSize(TypedValue.COMPLEX_UNIT_PX,
+                    key.selectPreviewTextSize(drawParams));
+            previewText.setTypeface(key.selectPreviewTypeface(drawParams));
             previewText.setText(label);
         } else {
             previewText.setCompoundDrawables(null, null, null,
diff --git a/native/jni/src/correction.cpp b/native/jni/src/correction.cpp
index b8690eb..0ae02d5 100644
--- a/native/jni/src/correction.cpp
+++ b/native/jni/src/correction.cpp
@@ -190,11 +190,11 @@
 }
 
 inline static bool isEquivalentChar(ProximityType type) {
-    return type == EQUIVALENT_CHAR;
+    return type == MATCH_CHAR;
 }
 
 inline static bool isProximityCharOrEquivalentChar(ProximityType type) {
-    return type == EQUIVALENT_CHAR || type == NEAR_PROXIMITY_CHAR;
+    return type == MATCH_CHAR || type == PROXIMITY_CHAR;
 }
 
 Correction::CorrectionType Correction::processCharAndCalcState(const int c, const bool isTerminal) {
@@ -221,7 +221,7 @@
                 --mExcessiveCount;
                 mDistances[mOutputIndex] =
                         mProximityInfoState.getNormalizedSquaredDistance(mInputIndex, 0);
-            } else if (matchId == NEAR_PROXIMITY_CHAR) {
+            } else if (matchId == PROXIMITY_CHAR) {
                 mLastCharExceeded = false;
                 --mExcessiveCount;
                 ++mProximityCount;
@@ -299,11 +299,11 @@
             : (noCorrectionsHappenedSoFar && mProximityCount == 0);
 
     ProximityType matchedProximityCharId = secondTransposing
-            ? EQUIVALENT_CHAR
+            ? MATCH_CHAR
             : mProximityInfoState.getProximityType(
                     mInputIndex, c, checkProximityChars, &proximityIndex);
 
-    if (UNRELATED_CHAR == matchedProximityCharId
+    if (SUBSTITUTION_CHAR == matchedProximityCharId
             || ADDITIONAL_PROXIMITY_CHAR == matchedProximityCharId) {
         if (canTryCorrection && mOutputIndex > 0
                 && mCorrectionStates[mOutputIndex].mProximityMatching
@@ -332,7 +332,7 @@
         }
     }
 
-    if (UNRELATED_CHAR == matchedProximityCharId
+    if (SUBSTITUTION_CHAR == matchedProximityCharId
             || ADDITIONAL_PROXIMITY_CHAR == matchedProximityCharId) {
         if (ADDITIONAL_PROXIMITY_CHAR == matchedProximityCharId) {
             mAdditionalProximityMatching = true;
@@ -455,7 +455,7 @@
         mMatching = true;
         ++mEquivalentCharCount;
         mDistances[mOutputIndex] = mProximityInfoState.getNormalizedSquaredDistance(mInputIndex, 0);
-    } else if (NEAR_PROXIMITY_CHAR == matchedProximityCharId) {
+    } else if (PROXIMITY_CHAR == matchedProximityCharId) {
         mProximityMatching = true;
         ++mProximityCount;
         mDistances[mOutputIndex] =
@@ -614,7 +614,7 @@
         multiplyIntCapped(matchWeight, &finalFreq);
     }
 
-    if (proximityInfoState->getProximityType(0, word[0], true) == UNRELATED_CHAR) {
+    if (proximityInfoState->getProximityType(0, word[0], true) == SUBSTITUTION_CHAR) {
         multiplyRate(FIRST_CHAR_DIFFERENT_DEMOTION_RATE, &finalFreq);
     }
 
diff --git a/native/jni/src/defines.h b/native/jni/src/defines.h
index 11dc3d2..0aedc28 100644
--- a/native/jni/src/defines.h
+++ b/native/jni/src/defines.h
@@ -275,7 +275,7 @@
 #define NOT_A_CODE_POINT (-1)
 #define NOT_A_DISTANCE (-1)
 #define NOT_A_COORDINATE (-1)
-#define EQUIVALENT_CHAR_WITHOUT_DISTANCE_INFO (-2)
+#define MATCH_CHAR_WITHOUT_DISTANCE_INFO (-2)
 #define PROXIMITY_CHAR_WITHOUT_DISTANCE_INFO (-3)
 #define ADDITIONAL_PROXIMITY_CHAR_DISTANCE_INFO (-4)
 #define NOT_AN_INDEX (-1)
@@ -396,15 +396,15 @@
 // Used as a return value for character comparison
 typedef enum {
     // Same char, possibly with different case or accent
-    EQUIVALENT_CHAR,
+    MATCH_CHAR,
     // It is a char located nearby on the keyboard
-    NEAR_PROXIMITY_CHAR,
-    // It is an unrelated char and could be a substitution char
-    UNRELATED_CHAR,
-    // It is an unrelated char nor a substitution char
-    UNRELATED_NOR_SUBSTITUTION_CHAR,
+    PROXIMITY_CHAR,
     // Additional proximity char which can differ by language.
-    ADDITIONAL_PROXIMITY_CHAR
+    ADDITIONAL_PROXIMITY_CHAR,
+    // It is a substitution char
+    SUBSTITUTION_CHAR,
+    // It is an unrelated char
+    UNRELATED_CHAR,
 } ProximityType;
 
 typedef enum {
@@ -415,15 +415,16 @@
 
 typedef enum {
     CT_MATCH,
+    CT_PROXIMITY,
+    CT_ADDITIONAL_PROXIMITY,
+    CT_SUBSTITUTION,
     CT_OMISSION,
     CT_INSERTION,
     CT_TRANSPOSITION,
-    CT_SUBSTITUTION,
     CT_SPACE_SUBSTITUTION,
     CT_SPACE_OMISSION,
     CT_COMPLETION,
     CT_TERMINAL,
     CT_NEW_WORD,
-    CT_NEW_WORD_BIGRAM,
 } CorrectionType;
 #endif // LATINIME_DEFINES_H
diff --git a/native/jni/src/proximity_info_state.cpp b/native/jni/src/proximity_info_state.cpp
index 00e7ffc..fe1c433 100644
--- a/native/jni/src/proximity_info_state.cpp
+++ b/native/jni/src/proximity_info_state.cpp
@@ -156,15 +156,14 @@
     }
 }
 
-// TODO: Remove the "scale" parameter
 // This function basically converts from a length to an edit distance. Accordingly, it's obviously
 // wrong to compare with mMaxPointToKeyLength.
 float ProximityInfoState::getPointToKeyLength(
-        const int inputIndex, const int codePoint, const float scale) const {
+        const int inputIndex, const int codePoint) const {
     const int keyId = mProximityInfo->getKeyIndexOf(codePoint);
     if (keyId != NOT_AN_INDEX) {
         const int index = inputIndex * mProximityInfo->getKeyCount() + keyId;
-        return min(mSampledDistanceCache_G[index] * scale, mMaxPointToKeyLength);
+        return min(mSampledDistanceCache_G[index], mMaxPointToKeyLength);
     }
     if (isSkippableCodePoint(codePoint)) {
         return 0.0f;
@@ -173,19 +172,10 @@
     return static_cast<float>(MAX_VALUE_FOR_WEIGHTING);
 }
 
-float ProximityInfoState::getPointToKeyLength_G(const int inputIndex, const int codePoint) const {
-    return getPointToKeyLength(inputIndex, codePoint, 1.0f);
-}
-
-// TODO: Remove the "scale" parameter
 float ProximityInfoState::getPointToKeyByIdLength(
-        const int inputIndex, const int keyId, const float scale) const {
+        const int inputIndex, const int keyId) const {
     return ProximityInfoStateUtils::getPointToKeyByIdLength(mMaxPointToKeyLength,
-            &mSampledDistanceCache_G, mProximityInfo->getKeyCount(), inputIndex, keyId, scale);
-}
-
-float ProximityInfoState::getPointToKeyByIdLength(const int inputIndex, const int keyId) const {
-    return getPointToKeyByIdLength(inputIndex, keyId, 1.0f);
+            &mSampledDistanceCache_G, mProximityInfo->getKeyCount(), inputIndex, keyId);
 }
 
 // In the following function, c is the current character of the dictionary word currently examined.
@@ -207,15 +197,15 @@
     // The first char in the array is what user typed. If it matches right away, that means the
     // user typed that same char for this pos.
     if (firstCodePoint == baseLowerC || firstCodePoint == codePoint) {
-        return EQUIVALENT_CHAR;
+        return MATCH_CHAR;
     }
 
-    if (!checkProximityChars) return UNRELATED_CHAR;
+    if (!checkProximityChars) return SUBSTITUTION_CHAR;
 
     // If the non-accented, lowercased version of that first character matches c, then we have a
     // non-accented version of the accented character the user typed. Treat it as a close char.
     if (toBaseLowerCase(firstCodePoint) == baseLowerC) {
-        return NEAR_PROXIMITY_CHAR;
+        return PROXIMITY_CHAR;
     }
 
     // Not an exact nor an accent-alike match: search the list of close keys
@@ -228,7 +218,7 @@
             if (proximityIndex) {
                 *proximityIndex = j;
             }
-            return NEAR_PROXIMITY_CHAR;
+            return PROXIMITY_CHAR;
         }
         ++j;
     }
@@ -248,23 +238,23 @@
             ++j;
         }
     }
-    // Was not included, signal this as an unrelated character.
-    return UNRELATED_CHAR;
+    // Was not included, signal this as a substitution character.
+    return SUBSTITUTION_CHAR;
 }
 
 ProximityType ProximityInfoState::getProximityTypeG(const int index, const int codePoint) const {
     if (!isUsed()) {
-        return UNRELATED_NOR_SUBSTITUTION_CHAR;
+        return UNRELATED_CHAR;
     }
     const int lowerCodePoint = toLowerCase(codePoint);
     const int baseLowerCodePoint = toBaseCodePoint(lowerCodePoint);
     for (int i = 0; i < static_cast<int>(mSampledSearchKeyVectors[index].size()); ++i) {
         if (mSampledSearchKeyVectors[index][i] == lowerCodePoint
                 || mSampledSearchKeyVectors[index][i] == baseLowerCodePoint) {
-            return EQUIVALENT_CHAR;
+            return MATCH_CHAR;
         }
     }
-    return UNRELATED_NOR_SUBSTITUTION_CHAR;
+    return UNRELATED_CHAR;
 }
 
 bool ProximityInfoState::isKeyInSerchKeysAfterIndex(const int index, const int keyId) const {
diff --git a/native/jni/src/proximity_info_state.h b/native/jni/src/proximity_info_state.h
index dd1eb76..224240b 100644
--- a/native/jni/src/proximity_info_state.h
+++ b/native/jni/src/proximity_info_state.h
@@ -147,10 +147,8 @@
         return mIsContinuationPossible;
     }
 
-    float getPointToKeyByIdLength(const int inputIndex, const int keyId, const float scale) const;
     float getPointToKeyByIdLength(const int inputIndex, const int keyId) const;
-    float getPointToKeyLength(const int inputIndex, const int codePoint, const float scale) const;
-    float getPointToKeyLength_G(const int inputIndex, const int codePoint) const;
+    float getPointToKeyLength(const int inputIndex, const int codePoint) const;
 
     ProximityType getProximityType(const int index, const int codePoint,
             const bool checkProximityChars, int *proximityIndex = 0) const;
diff --git a/native/jni/src/proximity_info_state_utils.cpp b/native/jni/src/proximity_info_state_utils.cpp
index 2ca39f9..ccb28bc 100644
--- a/native/jni/src/proximity_info_state_utils.cpp
+++ b/native/jni/src/proximity_info_state_utils.cpp
@@ -209,7 +209,7 @@
                                 * ProximityInfoParams::NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR);
             } else {
                 normalizedSquaredDistances[i * MAX_PROXIMITY_CHARS_SIZE + j] =
-                        (j == 0) ? EQUIVALENT_CHAR_WITHOUT_DISTANCE_INFO :
+                        (j == 0) ? MATCH_CHAR_WITHOUT_DISTANCE_INFO :
                                 PROXIMITY_CHAR_WITHOUT_DISTANCE_INFO;
             }
             if (DEBUG_PROXIMITY_CHARS) {
@@ -634,27 +634,19 @@
     return getAngleDiff(previousDirection, nextDirection);
 }
 
-// TODO: Remove the "scale" parameter
 // This function basically converts from a length to an edit distance. Accordingly, it's obviously
 // wrong to compare with mMaxPointToKeyLength.
 /* static */ float ProximityInfoStateUtils::getPointToKeyByIdLength(const float maxPointToKeyLength,
         const std::vector<float> *const SampledDistanceCache_G, const int keyCount,
-        const int inputIndex, const int keyId, const float scale) {
+        const int inputIndex, const int keyId) {
     if (keyId != NOT_AN_INDEX) {
         const int index = inputIndex * keyCount + keyId;
-        return min((*SampledDistanceCache_G)[index] * scale, maxPointToKeyLength);
+        return min((*SampledDistanceCache_G)[index], maxPointToKeyLength);
     }
     // If the char is not a key on the keyboard then return the max length.
     return static_cast<float>(MAX_VALUE_FOR_WEIGHTING);
 }
 
-/* static */ float ProximityInfoStateUtils::getPointToKeyByIdLength(const float maxPointToKeyLength,
-        const std::vector<float> *const SampledDistanceCache_G, const int keyCount,
-        const int inputIndex, const int keyId) {
-    return getPointToKeyByIdLength(
-            maxPointToKeyLength, SampledDistanceCache_G, keyCount, inputIndex, keyId, 1.0f);
-}
-
 // Updates probabilities of aligning to some keys and skipping.
 // Word suggestion should be based on this probabilities.
 /* static */ void ProximityInfoStateUtils::updateAlignPointProbabilities(
diff --git a/native/jni/src/proximity_info_state_utils.h b/native/jni/src/proximity_info_state_utils.h
index d55730a..a7f4a34 100644
--- a/native/jni/src/proximity_info_state_utils.h
+++ b/native/jni/src/proximity_info_state_utils.h
@@ -81,9 +81,6 @@
             std::vector<std::vector<int> > *sampledSearchKeyVectors);
     static float getPointToKeyByIdLength(const float maxPointToKeyLength,
             const std::vector<float> *const SampledDistanceCache_G, const int keyCount,
-            const int inputIndex, const int keyId, const float scale);
-    static float getPointToKeyByIdLength(const float maxPointToKeyLength,
-            const std::vector<float> *const SampledDistanceCache_G, const int keyCount,
             const int inputIndex, const int keyId);
     static void initGeometricDistanceInfos(const ProximityInfo *const proximityInfo,
             const int sampledInputSize, const int lastSavedInputSize,