aboutsummaryrefslogtreecommitdiffstats
path: root/java/src
diff options
context:
space:
mode:
authorTadashi G. Takaoka <takaoka@google.com>2014-09-24 15:52:11 +0900
committerTadashi G. Takaoka <takaoka@google.com>2014-09-25 15:12:06 +0900
commit0be4e6e5853daca7813fc7ca853a5492a064d696 (patch)
tree02a9db8116a8ab5976b2458edd75e19c8abba232 /java/src
parent145f05d6371fac2a3f6f7cf840add38280c432fe (diff)
downloadlatinime-0be4e6e5853daca7813fc7ca853a5492a064d696.tar.gz
latinime-0be4e6e5853daca7813fc7ca853a5492a064d696.tar.xz
latinime-0be4e6e5853daca7813fc7ca853a5492a064d696.zip
Add allowRedundantMoreKeys attribute
This CL also adds a couple of custom layout tests of Nordic languages. Bug: 10787354 Change-Id: I5e875d3f30863395511afa82f0a02deb093d3a6f
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/android/inputmethod/compat/CharacterCompat.java47
-rw-r--r--java/src/com/android/inputmethod/keyboard/Key.java14
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java4
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java5
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java18
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeysCache.java8
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/MoreKeySpec.java43
7 files changed, 138 insertions, 1 deletions
diff --git a/java/src/com/android/inputmethod/compat/CharacterCompat.java b/java/src/com/android/inputmethod/compat/CharacterCompat.java
new file mode 100644
index 000000000..609fe1638
--- /dev/null
+++ b/java/src/com/android/inputmethod/compat/CharacterCompat.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+package com.android.inputmethod.compat;
+
+import java.lang.reflect.Method;
+
+public final class CharacterCompat {
+ // Note that Character.isAlphabetic(int), has been introduced in API level 19
+ // (Build.VERSION_CODE.KITKAT).
+ private static final Method METHOD_isAlphabetic = CompatUtils.getMethod(
+ Character.class, "isAlphabetic", int.class);
+
+ private CharacterCompat() {
+ // This utility class is not publicly instantiable.
+ }
+
+ public static boolean isAlphabetic(final int code) {
+ if (METHOD_isAlphabetic != null) {
+ return (Boolean)CompatUtils.invoke(null, false, METHOD_isAlphabetic, code);
+ }
+ switch (Character.getType(code)) {
+ case Character.UPPERCASE_LETTER:
+ case Character.LOWERCASE_LETTER:
+ case Character.TITLECASE_LETTER:
+ case Character.MODIFIER_LETTER:
+ case Character.OTHER_LETTER:
+ case Character.LETTER_NUMBER:
+ return true;
+ default:
+ return false;
+ }
+ }
+}
diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java
index 863a8b7ad..bf29b5ffe 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -395,6 +395,10 @@ public class Key implements Comparable<Key> {
* @param key the original key.
*/
protected Key(final Key key) {
+ this(key, key.mMoreKeys);
+ }
+
+ private Key(final Key key, final MoreKeySpec[] moreKeys) {
// Final attributes.
mCode = key.mCode;
mLabel = key.mLabel;
@@ -408,7 +412,7 @@ public class Key implements Comparable<Key> {
mX = key.mX;
mY = key.mY;
mHitBox.set(key.mHitBox);
- mMoreKeys = key.mMoreKeys;
+ mMoreKeys = moreKeys;
mMoreKeysColumnAndFlags = key.mMoreKeysColumnAndFlags;
mBackgroundType = key.mBackgroundType;
mActionFlags = key.mActionFlags;
@@ -420,6 +424,14 @@ public class Key implements Comparable<Key> {
mEnabled = key.mEnabled;
}
+ public static Key removeRedundantMoreKeys(final Key key,
+ final MoreKeySpec.LettersOnBaseLayout lettersOnBaseLayout) {
+ final MoreKeySpec[] moreKeys = key.getMoreKeys();
+ final MoreKeySpec[] filteredMoreKeys = MoreKeySpec.removeRedundantMoreKeys(
+ moreKeys, lettersOnBaseLayout);
+ return (filteredMoreKeys == moreKeys) ? key : new Key(key, filteredMoreKeys);
+ }
+
private static boolean needsToUpperCase(final int labelFlags, final int keyboardElementId) {
if ((labelFlags & LABEL_FLAGS_PRESERVE_CASE) != 0) return false;
switch (keyboardElementId) {
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java b/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java
index 47fb7b320..52b9284be 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java
@@ -97,6 +97,7 @@ public final class KeyboardLayoutSet {
int mKeyboardXmlId;
boolean mProximityCharsCorrectionEnabled;
boolean mSupportsSplitLayout;
+ boolean mAllowRedundantMoreKeys;
public ElementParams() {}
}
@@ -202,6 +203,7 @@ public final class KeyboardLayoutSet {
if (id.isAlphabetKeyboard()) {
builder.setAutoGenerate(sKeysCache);
}
+ builder.setAllowRedundantMoreKes(elementParams.mAllowRedundantMoreKeys);
final int keyboardXmlId = elementParams.mKeyboardXmlId;
builder.load(keyboardXmlId, id);
if (mParams.mDisableTouchPositionCorrectionDataForTest) {
@@ -395,6 +397,8 @@ public final class KeyboardLayoutSet {
false);
elementParams.mSupportsSplitLayout = a.getBoolean(
R.styleable.KeyboardLayoutSet_Element_supportsSplitLayout, false);
+ elementParams.mAllowRedundantMoreKeys = a.getBoolean(
+ R.styleable.KeyboardLayoutSet_Element_allowRedundantMoreKeys, true);
mParams.mKeyboardLayoutSetElementIdToParamsMap.put(elementName, elementParams);
} finally {
a.recycle();
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
index 2056a0b9d..50385555c 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
@@ -162,6 +162,10 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
mParams.mKeysCache = keysCache;
}
+ public void setAllowRedundantMoreKes(final boolean enabled) {
+ mParams.mAllowRedundantMoreKeys = enabled;
+ }
+
public KeyboardBuilder<KP> load(final int xmlId, final KeyboardId id) {
mParams.mId = id;
final XmlResourceParser parser = mResources.getXml(xmlId);
@@ -851,6 +855,7 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
}
private void endKeyboard() {
+ mParams.removeRedundantMoreKeys();
// {@link #parseGridRows(XmlPullParser,boolean)} may populate keyboard rows higher than
// previously expected.
final int actualHeight = mCurrentY - mParams.mVerticalGap + mParams.mBottomPadding;
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java
index 5df9d3ece..1e1188bd0 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java
@@ -68,6 +68,7 @@ public class KeyboardParams {
public final KeyStylesSet mKeyStyles = new KeyStylesSet(mTextsSet);
public KeysCache mKeysCache;
+ public boolean mAllowRedundantMoreKeys;
public int mMostCommonKeyHeight = 0;
public int mMostCommonKeyWidth = 0;
@@ -115,6 +116,23 @@ public class KeyboardParams {
}
}
+ public void removeRedundantMoreKeys() {
+ if (mAllowRedundantMoreKeys) {
+ return;
+ }
+ final MoreKeySpec.LettersOnBaseLayout lettersOnBaseLayout =
+ new MoreKeySpec.LettersOnBaseLayout();
+ for (final Key key : mSortedKeys) {
+ lettersOnBaseLayout.addLetter(key);
+ }
+ final ArrayList<Key> allKeys = new ArrayList<>(mSortedKeys);
+ mSortedKeys.clear();
+ for (final Key key : allKeys) {
+ final Key filteredKey = Key.removeRedundantMoreKeys(key, lettersOnBaseLayout);
+ mSortedKeys.add(mKeysCache.replace(key, filteredKey));
+ }
+ }
+
private int mMaxHeightCount = 0;
private int mMaxWidthCount = 0;
private final SparseIntArray mHeightHistogram = new SparseIntArray();
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeysCache.java b/java/src/com/android/inputmethod/keyboard/internal/KeysCache.java
index 7743d4744..e8678637b 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeysCache.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeysCache.java
@@ -36,4 +36,12 @@ public final class KeysCache {
mMap.put(key, key);
return key;
}
+
+ public Key replace(final Key oldKey, final Key newKey) {
+ if (oldKey.equals(newKey)) {
+ return oldKey;
+ }
+ mMap.remove(oldKey);
+ return get(newKey);
+ }
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/MoreKeySpec.java b/java/src/com/android/inputmethod/keyboard/internal/MoreKeySpec.java
index 625a0c283..764159c3d 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/MoreKeySpec.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/MoreKeySpec.java
@@ -17,7 +17,9 @@
package com.android.inputmethod.keyboard.internal;
import android.text.TextUtils;
+import android.util.SparseIntArray;
+import com.android.inputmethod.compat.CharacterCompat;
import com.android.inputmethod.keyboard.Key;
import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.define.DebugFlags;
@@ -26,6 +28,7 @@ import com.android.inputmethod.latin.utils.StringUtils;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashSet;
import java.util.Locale;
/**
@@ -110,6 +113,46 @@ public final class MoreKeySpec {
}
}
+ public static class LettersOnBaseLayout {
+ private final SparseIntArray mCodes = new SparseIntArray();
+ private final HashSet<String> mTexts = new HashSet<>();
+
+ public void addLetter(final Key key) {
+ final int code = key.getCode();
+ if (CharacterCompat.isAlphabetic(code)) {
+ mCodes.put(code, 0);
+ } else if (code == Constants.CODE_OUTPUT_TEXT) {
+ mTexts.add(key.getOutputText());
+ }
+ }
+
+ public boolean contains(final MoreKeySpec moreKey) {
+ final int code = moreKey.mCode;
+ if (CharacterCompat.isAlphabetic(code) && mCodes.indexOfKey(code) >= 0) {
+ return true;
+ } else if (code == Constants.CODE_OUTPUT_TEXT && mTexts.contains(moreKey.mOutputText)) {
+ return true;
+ }
+ return false;
+ }
+ }
+
+ public static MoreKeySpec[] removeRedundantMoreKeys(final MoreKeySpec[] moreKeys,
+ final LettersOnBaseLayout lettersOnBaseLayout) {
+ if (moreKeys == null) {
+ return null;
+ }
+ final ArrayList<MoreKeySpec> filteredMoreKeys = new ArrayList<>();
+ for (final MoreKeySpec moreKey : moreKeys) {
+ if (!lettersOnBaseLayout.contains(moreKey)) {
+ filteredMoreKeys.add(moreKey);
+ }
+ }
+ final int size = filteredMoreKeys.size();
+ return (moreKeys.length == size) ? moreKeys
+ : filteredMoreKeys.toArray(new MoreKeySpec[size]);
+ }
+
private static final boolean DEBUG = DebugFlags.DEBUG_ENABLED;
// Constants for parsing.
private static final char COMMA = Constants.CODE_COMMA;