From d6339639c39cbe0a833361623bf6963cff526784 Mon Sep 17 00:00:00 2001
From: Yusuke Nojima <nojima@google.com>
Date: Thu, 29 Sep 2011 11:53:51 +0900
Subject: [PATCH] Add touch position correction data to resources.

Change-Id: I156205672f3935f70c250a6c538793f35c5d86b2
---
 java/res/values/attrs.xml                     |  4 +-
 java/res/values/themes-basic-highcontrast.xml |  1 +
 java/res/values/themes-basic.xml              |  1 +
 java/res/values/themes-gingerbread.xml        |  1 +
 java/res/values/themes-ics.xml                |  1 +
 java/res/values/themes-stone-bold.xml         |  1 +
 java/res/values/themes-stone.xml              |  1 +
 java/res/values/touch-position-correction.xml | 74 +++++++++++++++++++
 .../inputmethod/keyboard/Keyboard.java        |  3 +-
 .../inputmethod/keyboard/ProximityInfo.java   | 14 +++-
 .../keyboard/internal/KeyboardBuilder.java    | 55 ++++++++++++++
 .../keyboard/internal/KeyboardParams.java     |  4 +
 12 files changed, 155 insertions(+), 5 deletions(-)
 create mode 100644 java/res/values/touch-position-correction.xml

diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml
index 2a7632124..34ce527f1 100644
--- a/java/res/values/attrs.xml
+++ b/java/res/values/attrs.xml
@@ -34,7 +34,9 @@
         <attr name="moreSuggestionsViewStyle" format="reference" />
         <attr name="suggestionBackgroundStyle" format="reference" />
         <attr name="suggestionPreviewBackgroundStyle" format="reference" />
-        </declare-styleable>
+        <!-- Touch position correction -->
+        <attr name="touchPositionCorrectionData" format="reference" />
+    </declare-styleable>
 
     <declare-styleable name="KeyboardView">
         <!-- Image for the key. This image needs to be a StateListDrawable, with the following
diff --git a/java/res/values/themes-basic-highcontrast.xml b/java/res/values/themes-basic-highcontrast.xml
index 91272356f..bc3c84706 100644
--- a/java/res/values/themes-basic-highcontrast.xml
+++ b/java/res/values/themes-basic-highcontrast.xml
@@ -28,5 +28,6 @@
         <item name="moreSuggestionsViewStyle">@style/MoreSuggestionsViewStyle</item>
         <item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle</item>
         <item name="suggestionPreviewBackgroundStyle">@style/SuggestionPreviewBackgroundStyle</item>
+        <item name="touchPositionCorrectionData">@array/touch_position_correction_data_empty</item>
     </style>
 </resources>
diff --git a/java/res/values/themes-basic.xml b/java/res/values/themes-basic.xml
index 6c0e16e7b..29cb9cc7d 100644
--- a/java/res/values/themes-basic.xml
+++ b/java/res/values/themes-basic.xml
@@ -28,5 +28,6 @@
         <item name="moreSuggestionsViewStyle">@style/MoreSuggestionsViewStyle</item>
         <item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle</item>
         <item name="suggestionPreviewBackgroundStyle">@style/SuggestionPreviewBackgroundStyle</item>
+        <item name="touchPositionCorrectionData">@array/touch_position_correction_data_empty</item>
     </style>
 </resources>
diff --git a/java/res/values/themes-gingerbread.xml b/java/res/values/themes-gingerbread.xml
index 43bff5082..c4a0f804a 100644
--- a/java/res/values/themes-gingerbread.xml
+++ b/java/res/values/themes-gingerbread.xml
@@ -28,5 +28,6 @@
         <item name="moreSuggestionsViewStyle">@style/MoreSuggestionsViewStyle</item>
         <item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle</item>
         <item name="suggestionPreviewBackgroundStyle">@style/SuggestionPreviewBackgroundStyle</item>
+        <item name="touchPositionCorrectionData">@array/touch_position_correction_data_gingerbread</item>
     </style>
 </resources>
diff --git a/java/res/values/themes-ics.xml b/java/res/values/themes-ics.xml
index 1235d4e88..dd2b6a334 100644
--- a/java/res/values/themes-ics.xml
+++ b/java/res/values/themes-ics.xml
@@ -28,5 +28,6 @@
         <item name="moreSuggestionsViewStyle">@style/MoreSuggestionsViewStyle.IceCreamSandwich</item>
         <item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle.IceCreamSandwich</item>
         <item name="suggestionPreviewBackgroundStyle">@style/SuggestionPreviewBackgroundStyle.IceCreamSandwich</item>
+        <item name="touchPositionCorrectionData">@array/touch_position_correction_data_ice_cream_sandwich</item>
     </style>
 </resources>
diff --git a/java/res/values/themes-stone-bold.xml b/java/res/values/themes-stone-bold.xml
index 6e25f41d7..6e864bed0 100644
--- a/java/res/values/themes-stone-bold.xml
+++ b/java/res/values/themes-stone-bold.xml
@@ -28,5 +28,6 @@
         <item name="moreSuggestionsViewStyle">@style/MoreSuggestionsViewStyle</item>
         <item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle</item>
         <item name="suggestionPreviewBackgroundStyle">@style/SuggestionPreviewBackgroundStyle</item>
+        <item name="touchPositionCorrectionData">@array/touch_position_correction_data_empty</item>
     </style>
 </resources>
diff --git a/java/res/values/themes-stone.xml b/java/res/values/themes-stone.xml
index 3cbda810e..64c557035 100644
--- a/java/res/values/themes-stone.xml
+++ b/java/res/values/themes-stone.xml
@@ -28,5 +28,6 @@
         <item name="moreSuggestionsViewStyle">@style/MoreSuggestionsViewStyle</item>
         <item name="suggestionBackgroundStyle">@style/SuggestionBackgroundStyle</item>
         <item name="suggestionPreviewBackgroundStyle">@style/SuggestionPreviewBackgroundStyle</item>
+        <item name="touchPositionCorrectionData">@array/touch_position_correction_data_empty</item>
     </style>
 </resources>
diff --git a/java/res/values/touch-position-correction.xml b/java/res/values/touch-position-correction.xml
new file mode 100644
index 000000000..0a0e4e545
--- /dev/null
+++ b/java/res/values/touch-position-correction.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!--
+        An entry of the touch_position_correction word should be:
+        1. (float) (touch_center_x - key_center_x) / key_width
+        2. (float) (touch_center_y - key_center_y) / key_height
+        3. (float) sweet_spot_radius / (key_width^2 + key_height^2)
+     -->
+
+    <string-array
+        name="touch_position_correction_data_empty"
+        translatable="false"
+    >
+        <!-- empty -->
+    </string-array>
+
+    <string-array
+        name="touch_position_correction_data_gingerbread"
+        translatable="false"
+    >
+        <!-- First row -->
+        <item>0.0091285</item>
+        <item>0.1193203</item>
+        <item>0.1622607</item>
+
+        <!-- Second row -->
+        <item>-0.0233128</item>
+        <item>0.1379798</item>
+        <item>0.1585229</item>
+
+        <!-- Third row -->
+        <item>-0.0080185</item>
+        <item>0.1911477</item>
+        <item>0.1570948</item>
+    </string-array>
+
+    <string-array
+        name="touch_position_correction_data_ice_cream_sandwich"
+        translatable="false"
+    >
+        <!-- First row -->
+        <item>0.0038756</item>
+        <item>-0.0005677</item>
+        <item>0.1577026</item>
+
+        <!-- Second row -->
+        <item>-0.0236678</item>
+        <item>0.0381731</item>
+        <item>0.1529972</item>
+
+        <!-- Third row -->
+        <item>-0.0086827</item>
+        <item>0.0880847</item>
+        <item>0.1522819</item>
+    </string-array>
+</resources>
\ No newline at end of file
diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java
index d8f8bef9d..b15172922 100644
--- a/java/src/com/android/inputmethod/keyboard/Keyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java
@@ -143,7 +143,8 @@ public class Keyboard {
 
         mProximityInfo = new ProximityInfo(
                 params.GRID_WIDTH, params.GRID_HEIGHT, mOccupiedWidth, mOccupiedHeight,
-                mMostCommonKeyWidth, mKeys);
+                mMostCommonKeyWidth, mKeys, params.mTouchPositionCorrectionXs,
+                params.mTouchPositionCorrectionYs, params.mTouchPositionCorrectionRadii);
     }
 
     public ProximityInfo getProximityInfo() {
diff --git a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
index 71b46d646..210ab48a1 100644
--- a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
+++ b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
@@ -40,8 +40,13 @@ public class ProximityInfo {
     private final int mKeyboardHeight;
     private final int[][] mGridNeighbors;
 
-    ProximityInfo(
-            int gridWidth, int gridHeight, int minWidth, int height, int keyWidth, List<Key> keys) {
+    private final float[] mTouchPositionCorrectionXs;
+    private final float[] mTouchPositionCorrectionYs;
+    private final float[] mTouchPositionCorrectionRadii;
+
+    ProximityInfo(int gridWidth, int gridHeight, int minWidth, int height, int keyWidth,
+            List<Key> keys, float[] touchPositionCorrectionXs, float[] touchPositionCorrectionYs,
+            float[] touchPositionCorrectionRadii) {
         mGridWidth = gridWidth;
         mGridHeight = gridHeight;
         mGridSize = mGridWidth * mGridHeight;
@@ -49,6 +54,9 @@ public class ProximityInfo {
         mCellHeight = (height + mGridHeight - 1) / mGridHeight;
         mKeyboardMinWidth = minWidth;
         mKeyboardHeight = height;
+        mTouchPositionCorrectionXs = touchPositionCorrectionXs;
+        mTouchPositionCorrectionYs = touchPositionCorrectionYs;
+        mTouchPositionCorrectionRadii = touchPositionCorrectionRadii;
         mGridNeighbors = new int[mGridSize][];
         if (minWidth == 0 || height == 0) {
             // No proximity required. Keyboard might be mini keyboard.
@@ -58,7 +66,7 @@ public class ProximityInfo {
     }
 
     public static ProximityInfo createDummyProximityInfo() {
-        return new ProximityInfo(1, 1, 1, 1, 1, Collections.<Key>emptyList());
+        return new ProximityInfo(1, 1, 1, 1, 1, Collections.<Key>emptyList(), null, null, null);
     }
 
     public static ProximityInfo createSpellCheckerProximityInfo() {
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
index 48f683aaf..70ba48fa6 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
@@ -30,6 +30,7 @@ import com.android.inputmethod.compat.EditorInfoCompatUtils;
 import com.android.inputmethod.keyboard.Key;
 import com.android.inputmethod.keyboard.Keyboard;
 import com.android.inputmethod.keyboard.KeyboardId;
+import com.android.inputmethod.latin.LatinImeLogger;
 import com.android.inputmethod.latin.R;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -126,6 +127,8 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
     private static final int DEFAULT_KEYBOARD_COLUMNS = 10;
     private static final int DEFAULT_KEYBOARD_ROWS = 4;
 
+    private static final int TOUCH_POSITION_CORRECTION_RECORD_SIZE = 3;
+
     protected final KP mParams;
     protected final Context mContext;
     protected final Resources mResources;
@@ -248,10 +251,62 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
         mParams.mThemeId = a.getInt(R.styleable.KeyboardTheme_themeId, 0);
         a.recycle();
 
+        if (!setTouchPositionCorrectionData(context)) {
+            // In the regression test, setTouchPositionCorrectionData() fails
+            mParams.mTouchPositionCorrectionXs = null;
+            mParams.mTouchPositionCorrectionYs = null;
+            mParams.mTouchPositionCorrectionRadii = null;
+        }
+
         mParams.GRID_WIDTH = res.getInteger(R.integer.config_keyboard_grid_width);
         mParams.GRID_HEIGHT = res.getInteger(R.integer.config_keyboard_grid_height);
     }
 
+    private boolean setTouchPositionCorrectionData(Context context) {
+        final TypedArray a = context.obtainStyledAttributes(R.styleable.KeyboardTheme);
+        final int resourceId = a.getResourceId(
+                R.styleable.KeyboardTheme_touchPositionCorrectionData, 0);
+        if (resourceId == 0) {
+            // In the regression test, we cannot use theme resources
+            // TODO: Fix this
+            return false;
+        }
+        final String[] data = context.getResources().getStringArray(resourceId);
+        a.recycle();
+        final int dataLength = data.length;
+        if (dataLength % TOUCH_POSITION_CORRECTION_RECORD_SIZE != 0) {
+            if (LatinImeLogger.sDBG) {
+                throw new RuntimeException("the size of touch position correction data is invalid");
+            }
+            return false;
+        }
+        final int length = dataLength / TOUCH_POSITION_CORRECTION_RECORD_SIZE;
+        mParams.mTouchPositionCorrectionXs = new float[length];
+        mParams.mTouchPositionCorrectionYs = new float[length];
+        mParams.mTouchPositionCorrectionRadii = new float[length];
+        try {
+            for (int i = 0; i < dataLength; ++i) {
+                final int type = i % TOUCH_POSITION_CORRECTION_RECORD_SIZE;
+                final int index = i / TOUCH_POSITION_CORRECTION_RECORD_SIZE;
+                final float value = Float.parseFloat(data[i]);
+                if (type == 0) {
+                    mParams.mTouchPositionCorrectionXs[index] = value;
+                } else if (type == 1) {
+                    mParams.mTouchPositionCorrectionYs[index] = value;
+                } else {
+                    mParams.mTouchPositionCorrectionRadii[index] = value;
+                }
+            }
+        } catch (NumberFormatException e) {
+            if (LatinImeLogger.sDBG) {
+                throw new RuntimeException(
+                        "the number format for touch position correction data is invalid");
+            }
+            return false;
+        }
+        return true;
+    }
+
     public KeyboardBuilder<KP> load(KeyboardId id) {
         mParams.mId = id;
         try {
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java
index 97f58fad2..d1aea72a5 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java
@@ -68,6 +68,10 @@ public class KeyboardParams {
     public int mMostCommonKeyHeight = 0;
     public int mMostCommonKeyWidth = 0;
 
+    public float[] mTouchPositionCorrectionXs;
+    public float[] mTouchPositionCorrectionYs;
+    public float[] mTouchPositionCorrectionRadii;
+
     protected void clearKeys() {
         mKeys.clear();
         mShiftKeys.clear();