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

Commit a25dd3b5 authored by Yusuke Nojima's avatar Yusuke Nojima Committed by Android (Google) Code Review
Browse files

Merge "Pass the touch position correction flag from KeyboardSwitcher."

parents c812d0b8 294e1b4a
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