Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 294e1b4a authored by Yusuke Nojima's avatar Yusuke Nojima
Browse files

Pass the touch position correction flag from KeyboardSwitcher.

Change-Id: Ia242a9fa2fa71f7fdf8f974071a2df7acc4aa51f
parent 21ffb08a
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -138,8 +138,7 @@ public class Keyboard {

        mProximityInfo = new ProximityInfo(
                params.GRID_WIDTH, params.GRID_HEIGHT, mOccupiedWidth, mOccupiedHeight,
                mMostCommonKeyWidth, mMostCommonKeyHeight, mKeys, params.mTouchPositionCorrectionXs,
                params.mTouchPositionCorrectionYs, params.mTouchPositionCorrectionRadii);
                mMostCommonKeyWidth, mMostCommonKeyHeight, mKeys, params.mTouchPositionCorrection);
    }

    public ProximityInfo getProximityInfo() {
+6 −1
Original line number Diff line number Diff line
@@ -264,7 +264,12 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
        if (keyboard == null) {
            final Locale savedLocale = LocaleUtils.setSystemLocale(mResources, id.mLocale);
            try {
                keyboard = new LatinKeyboard.Builder(mThemeContext).load(id).build();
                final LatinKeyboard.Builder builder = new LatinKeyboard.Builder(mThemeContext);
                builder.load(id);
                builder.setTouchPositionCorrectionEnabled(
                        mSubtypeSwitcher.currentSubtypeContainsExtraValueKey(
                                LatinIME.SUBTYPE_EXTRA_VALUE_SUPPORT_TOUCH_POSITION_CORRECTION));
                keyboard = builder.build();
            } finally {
                LocaleUtils.setSystemLocale(mResources, savedLocale);
            }
+29 −39
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.inputmethod.keyboard;
import android.graphics.Rect;

import com.android.inputmethod.keyboard.Key;
import com.android.inputmethod.keyboard.internal.KeyboardParams.TouchPositionCorrection;
import com.android.inputmethod.latin.SubtypeSwitcher;
import com.android.inputmethod.latin.Utils;
import com.android.inputmethod.latin.spellcheck.SpellCheckerProximityInfo;
@@ -32,8 +33,6 @@ public class ProximityInfo {
    /** Number of key widths from current touch point to search for nearest keys. */
    private static float SEARCH_DISTANCE = 1.2f;
    private static final int[] EMPTY_INT_ARRAY = new int[0];
    private static final String SUPPORT_TOUCH_POSITION_CORRECTION =
            "SupportTouchPositionCorrection";

    private final int mKeyHeight;
    private final int mGridWidth;
@@ -46,13 +45,8 @@ public class ProximityInfo {
    private final int mKeyboardHeight;
    private final int[][] mGridNeighbors;

    private final float[] mTouchPositionCorrectionXs;
    private final float[] mTouchPositionCorrectionYs;
    private final float[] mTouchPositionCorrectionRadii;

    ProximityInfo(int gridWidth, int gridHeight, int minWidth, int height, int keyWidth,
            int keyHeight, List<Key> keys, float[] touchPositionCorrectionXs,
            float[] touchPositionCorrectionYs, float[] touchPositionCorrectionRadii) {
            int keyHeight, List<Key> keys, TouchPositionCorrection touchPositionCorrection) {
        mGridWidth = gridWidth;
        mGridHeight = gridHeight;
        mGridSize = mGridWidth * mGridHeight;
@@ -61,19 +55,16 @@ public class ProximityInfo {
        mKeyboardMinWidth = minWidth;
        mKeyboardHeight = height;
        mKeyHeight = keyHeight;
        mTouchPositionCorrectionXs = touchPositionCorrectionXs;
        mTouchPositionCorrectionYs = touchPositionCorrectionYs;
        mTouchPositionCorrectionRadii = touchPositionCorrectionRadii;
        mGridNeighbors = new int[mGridSize][];
        if (minWidth == 0 || height == 0) {
            // No proximity required. Keyboard might be mini keyboard.
            return;
        }
        computeNearestNeighbors(keyWidth, keys);
        computeNearestNeighbors(keyWidth, keys, touchPositionCorrection);
    }

    public static ProximityInfo createDummyProximityInfo() {
        return new ProximityInfo(1, 1, 1, 1, 1, 1, Collections.<Key>emptyList(), null, null, null);
        return new ProximityInfo(1, 1, 1, 1, 1, 1, Collections.<Key>emptyList(), null);
    }

    public static ProximityInfo createSpellCheckerProximityInfo() {
@@ -98,7 +89,8 @@ public class ProximityInfo {
    private native void releaseProximityInfoNative(int nativeProximityInfo);

    private final void setProximityInfo(int[][] gridNeighborKeyIndexes, int keyboardWidth,
            int keyboardHeight, List<Key> keys) {
            int keyboardHeight, List<Key> keys,
            TouchPositionCorrection touchPositionCorrection) {
        int[] proximityCharsArray = new int[mGridSize * MAX_PROXIMITY_CHARS_SIZE];
        Arrays.fill(proximityCharsArray, KeyDetector.NOT_A_CODE);
        for (int i = 0; i < mGridSize; ++i) {
@@ -123,23 +115,16 @@ public class ProximityInfo {
            keyCharCodes[i] = key.mCode;
        }

        final SubtypeSwitcher switcher = SubtypeSwitcher.getInstance();
        final boolean hasTouchPositionCorrectionData =
                switcher.currentSubtypeContainsExtraValueKey(SUPPORT_TOUCH_POSITION_CORRECTION)
                && mTouchPositionCorrectionXs != null
                && mTouchPositionCorrectionYs != null
                && mTouchPositionCorrectionRadii != null
                && mTouchPositionCorrectionXs.length > 0
                && mTouchPositionCorrectionYs.length > 0
                && mTouchPositionCorrectionRadii.length > 0;
        final float[] sweetSpotCenterXs =
                hasTouchPositionCorrectionData ? new float[keyCount] : null;
        final float[] sweetSpotCenterYs =
                hasTouchPositionCorrectionData ? new float[keyCount] : null;
        final float[] sweetSpotRadii =
                hasTouchPositionCorrectionData ? new float[keyCount] : null;
        if (hasTouchPositionCorrectionData) {
            calculateSweetSpot(keys, sweetSpotCenterXs, sweetSpotCenterYs, sweetSpotRadii);
        float[] sweetSpotCenterXs = null;
        float[] sweetSpotCenterYs = null;
        float[] sweetSpotRadii = null;

        if (touchPositionCorrection != null && touchPositionCorrection.isValid()) {
            sweetSpotCenterXs = new float[keyCount];
            sweetSpotCenterYs = new float[keyCount];
            sweetSpotRadii = new float[keyCount];
            calculateSweetSpot(keys, touchPositionCorrection,
                    sweetSpotCenterXs, sweetSpotCenterYs, sweetSpotRadii);
        }

        mNativeProximityInfo = setProximityInfoNative(MAX_PROXIMITY_CHARS_SIZE,
@@ -148,21 +133,24 @@ public class ProximityInfo {
                sweetSpotCenterXs, sweetSpotCenterYs, sweetSpotRadii);
    }

    private void calculateSweetSpot(List<Key> keys, float[] sweetSpotCenterXs,
            float[] sweetSpotCenterYs, float[] sweetSpotRadii) {
    private void calculateSweetSpot(List<Key> keys, TouchPositionCorrection touchPositionCorrection,
            float[] sweetSpotCenterXs, float[] sweetSpotCenterYs, float[] sweetSpotRadii) {
        final int keyCount = keys.size();
        final float[] xs = touchPositionCorrection.mXs;
        final float[] ys = touchPositionCorrection.mYs;
        final float[] radii = touchPositionCorrection.mRadii;
        for (int i = 0; i < keyCount; ++i) {
            final Key key = keys.get(i);
            final Rect hitBox = key.mHitBox;
            final int row = hitBox.top / mKeyHeight;
            if (row < mTouchPositionCorrectionRadii.length) {
            if (row < radii.length) {
                final float hitBoxCenterX = (hitBox.left + hitBox.right) * 0.5f;
                final float hitBoxCenterY = (hitBox.top + hitBox.bottom) * 0.5f;
                final float hitBoxWidth = hitBox.right - hitBox.left;
                final float hitBoxHeight = hitBox.bottom - hitBox.top;
                final float x = mTouchPositionCorrectionXs[row];
                final float y = mTouchPositionCorrectionYs[row];
                final float radius = mTouchPositionCorrectionRadii[row];
                final float x = xs[row];
                final float y = ys[row];
                final float radius = radii[row];
                sweetSpotCenterXs[i] = hitBoxCenterX + x * hitBoxWidth;
                sweetSpotCenterYs[i] = hitBoxCenterY + y * hitBoxHeight;
                sweetSpotRadii[i] = radius
@@ -187,7 +175,8 @@ public class ProximityInfo {
        }
    }

    private void computeNearestNeighbors(int defaultWidth, List<Key> keys) {
    private void computeNearestNeighbors(int defaultWidth, List<Key> keys,
            TouchPositionCorrection touchPositionCorrection) {
        final int thresholdBase = (int) (defaultWidth * SEARCH_DISTANCE);
        final int threshold = thresholdBase * thresholdBase;
        // Round-up so we don't have any pixels outside the grid
@@ -210,7 +199,8 @@ public class ProximityInfo {
                mGridNeighbors[(y / mCellHeight) * mGridWidth + (x / mCellWidth)] = cell;
            }
        }
        setProximityInfo(mGridNeighbors, mKeyboardMinWidth, mKeyboardHeight, keys);
        setProximityInfo(mGridNeighbors, mKeyboardMinWidth, mKeyboardHeight, keys,
                touchPositionCorrection);
    }

    public int[] getNearestKeys(int x, int y) {
+5 −39
Original line number Diff line number Diff line
@@ -127,8 +127,6 @@ 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;
@@ -254,10 +252,6 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
    }

    private static void setTouchPositionCorrectionData(Context context, KeyboardParams params) {
        params.mTouchPositionCorrectionXs = null;
        params.mTouchPositionCorrectionYs = null;
        params.mTouchPositionCorrectionRadii = null;

        final TypedArray a = context.obtainStyledAttributes(
                null, R.styleable.Keyboard, R.attr.keyboardStyle, 0);
        params.mThemeId = a.getInt(R.styleable.Keyboard_themeId, 0);
@@ -270,39 +264,7 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
        }

        final String[] data = context.getResources().getStringArray(resourceId);
        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;
        }

        final int length = dataLength / TOUCH_POSITION_CORRECTION_RECORD_SIZE;
        params.mTouchPositionCorrectionXs = new float[length];
        params.mTouchPositionCorrectionYs = new float[length];
        params.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) {
                    params.mTouchPositionCorrectionXs[index] = value;
                } else if (type == 1) {
                    params.mTouchPositionCorrectionYs[index] = value;
                } else {
                    params.mTouchPositionCorrectionRadii[index] = value;
                }
            }
        } catch (NumberFormatException e) {
            if (LatinImeLogger.sDBG) {
                throw new RuntimeException(
                        "the number format for touch position correction data is invalid");
            }
            params.mTouchPositionCorrectionXs = null;
            params.mTouchPositionCorrectionYs = null;
            params.mTouchPositionCorrectionRadii = null;
        }
        params.mTouchPositionCorrection.load(data);
    }

    public KeyboardBuilder<KP> load(KeyboardId id) {
@@ -319,6 +281,10 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
        return this;
    }

    public void setTouchPositionCorrectionEnabled(boolean enabled) {
        mParams.mTouchPositionCorrection.setEnabled(enabled);
    }

    public Keyboard build() {
        return new Keyboard(mParams);
    }
+57 −3
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.graphics.drawable.Drawable;
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 java.util.ArrayList;
import java.util.HashMap;
@@ -68,9 +69,62 @@ public class KeyboardParams {
    public int mMostCommonKeyHeight = 0;
    public int mMostCommonKeyWidth = 0;

    public float[] mTouchPositionCorrectionXs;
    public float[] mTouchPositionCorrectionYs;
    public float[] mTouchPositionCorrectionRadii;
    public final TouchPositionCorrection mTouchPositionCorrection = new TouchPositionCorrection();

    public static class TouchPositionCorrection {
        private static final int TOUCH_POSITION_CORRECTION_RECORD_SIZE = 3;

        public boolean mEnabled;
        public float[] mXs;
        public float[] mYs;
        public float[] mRadii;

        public void load(String[] data) {
            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;
            }

            final int length = dataLength / TOUCH_POSITION_CORRECTION_RECORD_SIZE;
            mXs = new float[length];
            mYs = new float[length];
            mRadii = 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) {
                        mXs[index] = value;
                    } else if (type == 1) {
                        mYs[index] = value;
                    } else {
                        mRadii[index] = value;
                    }
                }
            } catch (NumberFormatException e) {
                if (LatinImeLogger.sDBG) {
                    throw new RuntimeException(
                            "the number format for touch position correction data is invalid");
                }
                mXs = null;
                mYs = null;
                mRadii = null;
            }
        }

        public void setEnabled(boolean enabled) {
            mEnabled = enabled;
        }

        public boolean isValid() {
            return mEnabled && mXs != null && mYs != null && mRadii != null
                && mXs.length > 0 && mYs.length > 0 && mRadii.length > 0;
        }
    }

    protected void clearKeys() {
        mKeys.clear();
Loading