135ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka/*
235ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka * Copyright (C) 2012 The Android Open Source Project
335ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka *
435ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka * Licensed under the Apache License, Version 2.0 (the "License"); you may not
535ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka * use this file except in compliance with the License. You may obtain a copy of
635ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka * the License at
735ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka *
835ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka * http://www.apache.org/licenses/LICENSE-2.0
935ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka *
1035ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka * Unless required by applicable law or agreed to in writing, software
1135ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
1235ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
1335ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka * License for the specific language governing permissions and limitations under
1435ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka * the License.
1535ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka */
1635ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka
1735ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaokapackage com.android.inputmethod.keyboard.internal;
1835ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka
1935ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaokaimport android.util.SparseIntArray;
2035ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka
2135ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaokaimport com.android.inputmethod.keyboard.Key;
2235ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaokaimport com.android.inputmethod.keyboard.Keyboard;
2335ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaokaimport com.android.inputmethod.keyboard.KeyboardId;
2435ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaokaimport com.android.inputmethod.latin.CollectionUtils;
2535ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka
2635ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaokaimport java.util.ArrayList;
27e30c4e0bb1522f45b3bb37b54c35ee1f6a21dd4bKen Wakasaimport java.util.TreeSet;
2835ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka
2935ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaokapublic class KeyboardParams {
3035ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    public KeyboardId mId;
3135ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    public int mThemeId;
3235ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka
3335ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    /** Total height and width of the keyboard, including the paddings and keys */
3435ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    public int mOccupiedHeight;
3535ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    public int mOccupiedWidth;
3635ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka
3735ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    /** Base height and width of the keyboard used to calculate rows' or keys' heights and
3835ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka     *  widths
3935ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka     */
4035ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    public int mBaseHeight;
4135ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    public int mBaseWidth;
4235ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka
4335ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    public int mTopPadding;
4435ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    public int mBottomPadding;
4535ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    public int mHorizontalEdgesPadding;
4635ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    public int mHorizontalCenterPadding;
4735ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka
48dc34da218a22489d92d1015e9e5dac8d951b89f4Tadashi G. Takaoka    public KeyVisualAttributes mKeyVisualAttributes;
4935ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka
5035ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    public int mDefaultRowHeight;
5135ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    public int mDefaultKeyWidth;
5235ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    public int mHorizontalGap;
5335ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    public int mVerticalGap;
5435ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka
5535ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    public int mMoreKeysTemplate;
5635ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    public int mMaxMoreKeysKeyboardColumn;
5735ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka
5835ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    public int GRID_WIDTH;
5935ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    public int GRID_HEIGHT;
6035ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka
61e30c4e0bb1522f45b3bb37b54c35ee1f6a21dd4bKen Wakasa    public final TreeSet<Key> mKeys = CollectionUtils.newTreeSet(); // ordered set
6235ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    public final ArrayList<Key> mShiftKeys = CollectionUtils.newArrayList();
6335ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    public final ArrayList<Key> mAltCodeKeysWhileTyping = CollectionUtils.newArrayList();
6435ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    public final KeyboardIconsSet mIconsSet = new KeyboardIconsSet();
6535ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    public final KeyboardCodesSet mCodesSet = new KeyboardCodesSet();
6635ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    public final KeyboardTextsSet mTextsSet = new KeyboardTextsSet();
6735ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    public final KeyStylesSet mKeyStyles = new KeyStylesSet(mTextsSet);
6835ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka
6935ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    public KeysCache mKeysCache;
7035ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka
7135ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    public int mMostCommonKeyHeight = 0;
7235ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    public int mMostCommonKeyWidth = 0;
7335ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka
7435ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    public boolean mProximityCharsCorrectionEnabled;
7535ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka
7635ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    public final TouchPositionCorrection mTouchPositionCorrection =
7735ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka            new TouchPositionCorrection();
7835ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka
7935ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    protected void clearKeys() {
8035ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka        mKeys.clear();
8135ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka        mShiftKeys.clear();
8235ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka        clearHistogram();
8335ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    }
8435ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka
8535ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    public void onAddKey(final Key newKey) {
8635ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka        final Key key = (mKeysCache != null) ? mKeysCache.get(newKey) : newKey;
8735ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka        final boolean zeroWidthSpacer = key.isSpacer() && key.mWidth == 0;
8835ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka        if (!zeroWidthSpacer) {
8935ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka            mKeys.add(key);
9035ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka            updateHistogram(key);
9135ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka        }
9235ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka        if (key.mCode == Keyboard.CODE_SHIFT) {
9335ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka            mShiftKeys.add(key);
9435ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka        }
9535ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka        if (key.altCodeWhileTyping()) {
9635ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka            mAltCodeKeysWhileTyping.add(key);
9735ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka        }
9835ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    }
9935ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka
10035ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    private int mMaxHeightCount = 0;
10135ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    private int mMaxWidthCount = 0;
10235ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    private final SparseIntArray mHeightHistogram = new SparseIntArray();
10335ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    private final SparseIntArray mWidthHistogram = new SparseIntArray();
10435ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka
10535ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    private void clearHistogram() {
10635ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka        mMostCommonKeyHeight = 0;
10735ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka        mMaxHeightCount = 0;
10835ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka        mHeightHistogram.clear();
10935ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka
11035ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka        mMaxWidthCount = 0;
11135ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka        mMostCommonKeyWidth = 0;
11235ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka        mWidthHistogram.clear();
11335ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    }
11435ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka
11535ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    private static int updateHistogramCounter(final SparseIntArray histogram, final int key) {
11635ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka        final int index = histogram.indexOfKey(key);
11735ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka        final int count = (index >= 0 ? histogram.get(key) : 0) + 1;
11835ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka        histogram.put(key, count);
11935ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka        return count;
12035ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    }
12135ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka
12235ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    private void updateHistogram(final Key key) {
12335ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka        final int height = key.mHeight + mVerticalGap;
12435ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka        final int heightCount = updateHistogramCounter(mHeightHistogram, height);
12535ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka        if (heightCount > mMaxHeightCount) {
12635ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka            mMaxHeightCount = heightCount;
12735ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka            mMostCommonKeyHeight = height;
12835ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka        }
12935ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka
13035ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka        final int width = key.mWidth + mHorizontalGap;
13135ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka        final int widthCount = updateHistogramCounter(mWidthHistogram, width);
13235ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka        if (widthCount > mMaxWidthCount) {
13335ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka            mMaxWidthCount = widthCount;
13435ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka            mMostCommonKeyWidth = width;
13535ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka        }
13635ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka    }
13735ff94547c16c84c5b6fafdae0b4a683be782b97Tadashi G. Takaoka}
138