Merge "Distinguish action-enter/shift-enter/enter"
diff --git a/native/jni/Android.mk b/native/jni/Android.mk
index 75f85b1..f2aebd5 100644
--- a/native/jni/Android.mk
+++ b/native/jni/Android.mk
@@ -66,11 +66,11 @@
 
 ifeq ($(FLAG_DO_PROFILE), true)
     $(warning Making profiling version of native library)
-    LOCAL_CFLAGS += -DFLAG_DO_PROFILE -funwind-tables
+    LOCAL_CFLAGS += -DFLAG_DO_PROFILE -funwind-tables -fno-inline
 else # FLAG_DO_PROFILE
 ifeq ($(FLAG_DBG), true)
     $(warning Making debug version of native library)
-    LOCAL_CFLAGS += -DFLAG_DBG -funwind-tables
+    LOCAL_CFLAGS += -DFLAG_DBG -funwind-tables -fno-inline
 ifeq ($(FLAG_FULL_DBG), true)
     $(warning Making full debug version of native library)
     LOCAL_CFLAGS += -DFLAG_FULL_DBG
diff --git a/native/jni/src/correction.cpp b/native/jni/src/correction.cpp
index afeda48..e892c85 100644
--- a/native/jni/src/correction.cpp
+++ b/native/jni/src/correction.cpp
@@ -16,10 +16,13 @@
 
 #define LOG_TAG "LatinIME: correction.cpp"
 
+#include <cmath>
+
 #include "char_utils.h"
 #include "correction.h"
 #include "defines.h"
 #include "proximity_info_state.h"
+#include "suggest_utils.h"
 
 namespace latinime {
 
@@ -671,27 +674,9 @@
             if (i < adjustedProximityMatchedCount) {
                 multiplyIntCapped(typedLetterMultiplier, &finalFreq);
             }
-            if (squaredDistance >= 0) {
-                // Promote or demote the score according to the distance from the sweet spot
-                static const float A = ZERO_DISTANCE_PROMOTION_RATE / 100.0f;
-                static const float B = 1.0f;
-                static const float C = 0.5f;
-                static const float MIN = 0.3f;
-                static const float R1 = NEUTRAL_SCORE_SQUARED_RADIUS;
-                static const float R2 = HALF_SCORE_SQUARED_RADIUS;
-                const float x = static_cast<float>(squaredDistance)
-                        / ProximityInfoState::NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR;
-                const float factor = max((x < R1)
-                        ? (A * (R1 - x) + B * x) / R1
-                        : (B * (R2 - x) + C * (x - R1)) / (R2 - R1), MIN);
-                // factor is a piecewise linear function like:
-                // A -_                  .
-                //     ^-_               .
-                // B      \              .
-                //         \_            .
-                // C         ------------.
-                //                       .
-                // 0   R1 R2             .
+            const float factor =
+                    SuggestUtils::getDistanceScalingFactor(static_cast<float>(squaredDistance));
+            if (factor > 0.0f) {
                 multiplyRate((int)(factor * 100.0f), &finalFreq);
             } else if (squaredDistance == PROXIMITY_CHAR_WITHOUT_DISTANCE_INFO) {
                 multiplyRate(WORDS_WITH_PROXIMITY_CHARACTER_DEMOTION_RATE, &finalFreq);
diff --git a/native/jni/src/defines.h b/native/jni/src/defines.h
index 4e0c570..c89a870 100644
--- a/native/jni/src/defines.h
+++ b/native/jni/src/defines.h
@@ -23,6 +23,11 @@
 #define AK_FORCE_INLINE inline
 #endif // __GNUC__
 
+#if defined(FLAG_DO_PROFILE) || defined(FLAG_DBG)
+#undef AK_FORCE_INLINE
+#define AK_FORCE_INLINE inline
+#endif // defined(FLAG_DO_PROFILE) || defined(FLAG_DBG)
+
 // Must be identical to Constants.Dictionary.MAX_WORD_LENGTH in Java
 #define MAX_WORD_LENGTH 48
 // Must be identical to BinaryDictionary.MAX_RESULTS in Java
@@ -32,7 +37,7 @@
 #include <android/log.h>
 #ifndef LOG_TAG
 #define LOG_TAG "LatinIME: "
-#endif
+#endif // LOG_TAG
 #define AKLOGE(fmt, ...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, fmt, ##__VA_ARGS__)
 #define AKLOGI(fmt, ...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, fmt, ##__VA_ARGS__)
 
@@ -110,14 +115,14 @@
     }
     free(strs);
 }
-#else
+#else // __ANDROID__
 #include <cassert>
 #define DO_ASSERT_TEST
 #define ASSERT(success) assert(success)
 #define SHOW_STACK_TRACE
-#endif
+#endif // __ANDROID__
 
-#else
+#else // defined(FLAG_DO_PROFILE) || defined(FLAG_DBG)
 #define AKLOGE(fmt, ...)
 #define AKLOGI(fmt, ...)
 #define DUMP_RESULT(words, frequencies)
@@ -126,7 +131,7 @@
 #define ASSERT(success)
 #define SHOW_STACK_TRACE
 #define INTS_TO_CHARS(input, length, output)
-#endif
+#endif // defined(FLAG_DO_PROFILE) || defined(FLAG_DBG)
 
 #ifdef FLAG_DO_PROFILE
 // Profiler
diff --git a/native/jni/src/geometry_utils.h b/native/jni/src/geometry_utils.h
index 4060a7b..4bff80f 100644
--- a/native/jni/src/geometry_utils.h
+++ b/native/jni/src/geometry_utils.h
@@ -21,8 +21,6 @@
 
 #include "defines.h"
 
-#define DEBUG_DECODER false
-
 #define M_PI_F 3.14159265f
 #define ROUND_FLOAT_10000(f) ((f) < 1000.0f && (f) > 0.001f) \
         ? (floorf((f) * 10000.0f) / 10000.0f) : (f)
@@ -36,19 +34,8 @@
     return SQUARE_FLOAT(x1 - x2) + SQUARE_FLOAT(y1 - y2);
 }
 
-static inline float getNormalizedSquaredDistanceFloat(const float x1, const float y1,
-        const float x2, const float y2, const float scale) {
-    return getSquaredDistanceFloat(x1, y1, x2, y2) / SQUARE_FLOAT(scale);
-}
-
-static inline float getDistanceFloat(const float x1, const float y1, const float x2,
-        const float y2) {
-    return hypotf(x1 - x2, y1 - y2);
-}
-
 static AK_FORCE_INLINE int getDistanceInt(const int x1, const int y1, const int x2, const int y2) {
-    return static_cast<int>(getDistanceFloat(static_cast<float>(x1), static_cast<float>(y1),
-            static_cast<float>(x2), static_cast<float>(y2)));
+    return static_cast<int>(hypotf(static_cast<float>(x1 - x2), static_cast<float>(y1 - y2)));
 }
 
 static AK_FORCE_INLINE float getAngle(const int x1, const int y1, const int x2, const int y2) {
diff --git a/native/jni/src/proximity_info.cpp b/native/jni/src/proximity_info.cpp
index 8ad9c77..9b99554 100644
--- a/native/jni/src/proximity_info.cpp
+++ b/native/jni/src/proximity_info.cpp
@@ -144,7 +144,7 @@
     const float touchX = static_cast<float>(x);
     const float touchY = static_cast<float>(y);
     const float keyWidth = static_cast<float>(getMostCommonKeyWidth());
-    return getNormalizedSquaredDistanceFloat(centerX, centerY, touchX, touchY, keyWidth);
+    return getSquaredDistanceFloat(centerX, centerY, touchX, touchY) / SQUARE_FLOAT(keyWidth);
 }
 
 int ProximityInfo::squaredDistanceToEdge(const int keyId, const int x, const int y) const {
diff --git a/native/jni/src/proximity_info_state.cpp b/native/jni/src/proximity_info_state.cpp
index 2e89e9a..aa02929 100644
--- a/native/jni/src/proximity_info_state.cpp
+++ b/native/jni/src/proximity_info_state.cpp
@@ -20,6 +20,7 @@
 #define LOG_TAG "LatinIME: proximity_info_state.cpp"
 
 #include "defines.h"
+#include "geometry_utils.h"
 #include "proximity_info.h"
 #include "proximity_info_state.h"
 
@@ -100,7 +101,7 @@
         mTimes.clear();
         mInputIndice.clear();
         mLengthCache.clear();
-        mDistanceCache.clear();
+        mDistanceCache_G.clear();
         mNearKeysVector.clear();
         mSearchKeysVector.clear();
         mSpeedRates.clear();
@@ -209,7 +210,7 @@
         const int keyCount = mProximityInfo->getKeyCount();
         mNearKeysVector.resize(mSampledInputSize);
         mSearchKeysVector.resize(mSampledInputSize);
-        mDistanceCache.resize(mSampledInputSize * keyCount);
+        mDistanceCache_G.resize(mSampledInputSize * keyCount);
         for (int i = lastSavedInputSize; i < mSampledInputSize; ++i) {
             mNearKeysVector[i].reset();
             mSearchKeysVector[i].reset();
@@ -220,7 +221,7 @@
                 const int y = mSampledInputYs[i];
                 const float normalizedSquaredDistance =
                         mProximityInfo->getNormalizedSquaredDistanceFromCenterFloatG(k, x, y);
-                mDistanceCache[index] = normalizedSquaredDistance;
+                mDistanceCache_G[index] = normalizedSquaredDistance;
                 if (normalizedSquaredDistance < NEAR_KEY_NORMALIZED_SQUARED_THRESHOLD) {
                     mNearKeysVector[i][k] = true;
                 }
@@ -685,7 +686,7 @@
     const int keyId = mProximityInfo->getKeyIndexOf(codePoint);
     if (keyId != NOT_AN_INDEX) {
         const int index = inputIndex * mProximityInfo->getKeyCount() + keyId;
-        return min(mDistanceCache[index] * scale, mMaxPointToKeyLength);
+        return min(mDistanceCache_G[index] * scale, mMaxPointToKeyLength);
     }
     if (isSkippableCodePoint(codePoint)) {
         return 0.0f;
@@ -694,7 +695,7 @@
     return MAX_POINT_TO_KEY_LENGTH;
 }
 
-float ProximityInfoState::getPointToKeyLength(const int inputIndex, const int codePoint) const {
+float ProximityInfoState::getPointToKeyLength_G(const int inputIndex, const int codePoint) const {
     return getPointToKeyLength(inputIndex, codePoint, 1.0f);
 }
 
@@ -705,7 +706,7 @@
         const int inputIndex, const int keyId, const float scale) const {
     if (keyId != NOT_AN_INDEX) {
         const int index = inputIndex * mProximityInfo->getKeyCount() + keyId;
-        return min(mDistanceCache[index] * scale, mMaxPointToKeyLength);
+        return min(mDistanceCache_G[index] * scale, mMaxPointToKeyLength);
     }
     // If the char is not a key on the keyboard then return the max length.
     return static_cast<float>(MAX_POINT_TO_KEY_LENGTH);
diff --git a/native/jni/src/proximity_info_state.h b/native/jni/src/proximity_info_state.h
index 49c33e5..d747bae 100644
--- a/native/jni/src/proximity_info_state.h
+++ b/native/jni/src/proximity_info_state.h
@@ -24,7 +24,6 @@
 
 #include "char_utils.h"
 #include "defines.h"
-#include "geometry_utils.h"
 #include "hash_map_compat.h"
 
 namespace latinime {
@@ -59,7 +58,7 @@
               mHasTouchPositionCorrectionData(false), mMostCommonKeyWidthSquare(0), mLocaleStr(),
               mKeyCount(0), mCellHeight(0), mCellWidth(0), mGridHeight(0), mGridWidth(0),
               mIsContinuationPossible(false), mSampledInputXs(), mSampledInputYs(), mTimes(),
-              mInputIndice(), mLengthCache(), mBeelineSpeedPercentiles(), mDistanceCache(),
+              mInputIndice(), mLengthCache(), mBeelineSpeedPercentiles(), mDistanceCache_G(),
               mSpeedRates(), mDirections(), mCharProbabilities(), mNearKeysVector(),
               mSearchKeysVector(), mTouchPositionCorrectionEnabled(false), mSampledInputSize(0) {
         memset(mInputCodes, 0, sizeof(mInputCodes));
@@ -158,7 +157,7 @@
     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(const int inputIndex, const int codePoint) const;
+    float getPointToKeyLength_G(const int inputIndex, const int codePoint) const;
 
     ProximityType getMatchedProximityId(const int index, const int c,
             const bool checkProximityChars, int *proximityIndex = 0) const;
@@ -275,7 +274,7 @@
     std::vector<int> mInputIndice;
     std::vector<int> mLengthCache;
     std::vector<int> mBeelineSpeedPercentiles;
-    std::vector<float> mDistanceCache;
+    std::vector<float> mDistanceCache_G;
     std::vector<float> mSpeedRates;
     std::vector<float> mDirections;
     // probabilities of skipping or mapping to a key for each point.
diff --git a/native/jni/src/suggest/gesture_suggest.h b/native/jni/src/suggest/gesture_suggest.h
index eff6dc9..82c3a69 100644
--- a/native/jni/src/suggest/gesture_suggest.h
+++ b/native/jni/src/suggest/gesture_suggest.h
@@ -31,14 +31,14 @@
     virtual ~GestureSuggest();
 
     int getSuggestions(ProximityInfo *pInfo, void *traverseSession, int *inputXs, int *inputYs,
-            int *times, int *pointerIds, int *codes, int inputSize, int commitPoint, int *outWords,
-            int *frequencies, int *outputIndices, int *outputTypes) const {
+            int *times, int *pointerIds, int *inputCodePoints, int inputSize, int commitPoint,
+            int *outWords, int *frequencies, int *outputIndices, int *outputTypes) const {
         if (!mSuggestInterface) {
             return 0;
         }
         return mSuggestInterface->getSuggestions(pInfo, traverseSession, inputXs, inputYs, times,
-                pointerIds, codes, inputSize, commitPoint, outWords, frequencies, outputIndices,
-                outputTypes);
+                pointerIds, inputCodePoints, inputSize, commitPoint, outWords, frequencies,
+                outputIndices, outputTypes);
     }
 
     static void setGestureSuggestFactoryMethod(SuggestInterface *(*factoryMethod)()) {
diff --git a/native/jni/src/suggest/suggest_interface.h b/native/jni/src/suggest/suggest_interface.h
index 0fb5426..0bb85d7 100644
--- a/native/jni/src/suggest/suggest_interface.h
+++ b/native/jni/src/suggest/suggest_interface.h
@@ -26,8 +26,9 @@
 class SuggestInterface {
  public:
     virtual int getSuggestions(ProximityInfo *pInfo, void *traverseSession, int *inputXs,
-            int *inputYs, int *times, int *pointerIds, int *codes, int inputSize, int commitPoint,
-            int *outWords, int *frequencies, int *outputIndices, int *outputTypes) const = 0;
+            int *inputYs, int *times, int *pointerIds, int *inputCodePoints, int inputSize,
+            int commitPoint, int *outWords, int *frequencies, int *outputIndices,
+            int *outputTypes) const = 0;
     SuggestInterface() {}
     virtual ~SuggestInterface() {}
  private:
diff --git a/native/jni/src/suggest/typing_suggest.h b/native/jni/src/suggest/typing_suggest.h
index 1e944cb..678037a 100644
--- a/native/jni/src/suggest/typing_suggest.h
+++ b/native/jni/src/suggest/typing_suggest.h
@@ -26,20 +26,19 @@
 
 class TypingSuggest : public SuggestInterface {
  public:
-    TypingSuggest() : mSuggestInterface(getTypingSuggestInstance()) {
-    }
+    TypingSuggest() : mSuggestInterface(getTypingSuggestInstance()) {}
 
     virtual ~TypingSuggest();
 
     int getSuggestions(ProximityInfo *pInfo, void *traverseSession, int *inputXs, int *inputYs,
-            int *times, int *pointerIds, int *codes, int inputSize, int commitPoint, int *outWords,
-            int *frequencies, int *outputIndices, int *outputTypes) const {
+            int *times, int *pointerIds, int *inputCodePoints, int inputSize, int commitPoint,
+            int *outWords, int *frequencies, int *outputIndices, int *outputTypes) const {
         if (!mSuggestInterface) {
             return 0;
         }
         return mSuggestInterface->getSuggestions(pInfo, traverseSession, inputXs, inputYs, times,
-                pointerIds, codes, inputSize, commitPoint, outWords, frequencies, outputIndices,
-                outputTypes);
+                pointerIds, inputCodePoints, inputSize, commitPoint, outWords, frequencies,
+                outputIndices, outputTypes);
     }
 
     static void setTypingSuggestFactoryMethod(SuggestInterface *(*factoryMethod)()) {
diff --git a/native/jni/src/suggest_utils.h b/native/jni/src/suggest_utils.h
new file mode 100644
index 0000000..a3b3c12
--- /dev/null
+++ b/native/jni/src/suggest_utils.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LATINIME_SUGGEST_UTILS_H
+#define LATINIME_SUGGEST_UTILS_H
+
+#include "defines.h"
+
+namespace latinime {
+class SuggestUtils {
+ public:
+    static float getDistanceScalingFactor(float normalizedSquaredDistance) {
+        if (normalizedSquaredDistance < 0.0f) {
+            return -1.0f;
+        }
+        // Promote or demote the score according to the distance from the sweet spot
+        static const float A = ZERO_DISTANCE_PROMOTION_RATE / 100.0f;
+        static const float B = 1.0f;
+        static const float C = 0.5f;
+        static const float MIN = 0.3f;
+        static const float R1 = NEUTRAL_SCORE_SQUARED_RADIUS;
+        static const float R2 = HALF_SCORE_SQUARED_RADIUS;
+        const float x = static_cast<float>(normalizedSquaredDistance)
+                / ProximityInfoState::NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR;
+        const float factor = max((x < R1)
+                ? (A * (R1 - x) + B * x) / R1
+                : (B * (R2 - x) + C * (x - R1)) / (R2 - R1), MIN);
+        // factor is a piecewise linear function like:
+        // A -_                  .
+        //     ^-_               .
+        // B      \              .
+        //         \_            .
+        // C         ------------.
+        //                       .
+        // 0   R1 R2             .
+        return factor;
+    }
+};
+} // namespace latinime
+#endif // LATINIME_SUGGEST_UTILS_H