aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--java/res/values/predefined-subtypes.xml7
-rw-r--r--java/res/xml-sw600dp/row_symbols4.xml4
-rw-r--r--java/res/xml-sw600dp/row_symbols_shift4.xml4
-rw-r--r--java/res/xml-sw600dp/rows_number_normal.xml3
-rw-r--r--java/res/xml-sw768dp/row_dvorak4.xml7
-rw-r--r--java/res/xml-sw768dp/row_hebrew4.xml7
-rw-r--r--java/res/xml-sw768dp/row_qwerty4.xml7
-rw-r--r--java/res/xml-sw768dp/row_symbols4.xml8
-rw-r--r--java/res/xml-sw768dp/row_symbols_shift4.xml9
-rw-r--r--java/res/xml-sw768dp/rows_number_normal.xml3
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyDetector.java12
-rw-r--r--java/src/com/android/inputmethod/latin/AdditionalSubtype.java44
-rw-r--r--java/src/com/android/inputmethod/latin/AdditionalSubtypeSettings.java99
-rw-r--r--java/src/com/android/inputmethod/latin/SettingsValues.java78
-rw-r--r--java/src/com/android/inputmethod/latin/SuggestedWords.java2
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java4
-rw-r--r--native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp10
-rw-r--r--native/jni/src/additional_proximity_chars.h4
-rw-r--r--native/jni/src/basechars.cpp4
-rw-r--r--native/jni/src/bigram_dictionary.cpp2
-rw-r--r--native/jni/src/binary_format.h42
-rw-r--r--native/jni/src/bloom_filter.h14
-rw-r--r--native/jni/src/char_utils.h3
-rw-r--r--native/jni/src/correction.cpp18
-rw-r--r--native/jni/src/defines.h49
-rw-r--r--native/jni/src/dictionary.h9
-rw-r--r--native/jni/src/proximity_info.cpp61
-rw-r--r--native/jni/src/proximity_info.h36
-rw-r--r--native/jni/src/proximity_info_state.cpp71
-rw-r--r--native/jni/src/proximity_info_state.h9
-rw-r--r--native/jni/src/terminal_attributes.h10
-rw-r--r--native/jni/src/unigram_dictionary.cpp83
-rw-r--r--native/jni/src/unigram_dictionary.h12
-rw-r--r--native/jni/src/words_priority_queue_pool.h2
-rw-r--r--tests/src/com/android/inputmethod/latin/InputTestsBase.java27
-rw-r--r--tests/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerServiceTest.java63
36 files changed, 526 insertions, 301 deletions
diff --git a/java/res/values/predefined-subtypes.xml b/java/res/values/predefined-subtypes.xml
index 602f53eac..3bf0e617f 100644
--- a/java/res/values/predefined-subtypes.xml
+++ b/java/res/values/predefined-subtypes.xml
@@ -18,6 +18,9 @@
*/
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- Predefined subtypes (language:layout[:extraValue]) in semicolon separated format -->
- <string name="predefined_subtypes" translatable="false">de:qwerty:AsciiCapable;fr:qwertz:AsciiCapable</string>
+ <!-- Predefined subtypes (language:layout[:extraValue]) -->
+ <string-array name="predefined_subtypes" translatable="false">
+ <item>de:qwerty:AsciiCapable</item>
+ <item>fr:qwertz:AsciiCapable</item>
+ </string-array>
</resources>
diff --git a/java/res/xml-sw600dp/row_symbols4.xml b/java/res/xml-sw600dp/row_symbols4.xml
index 73a5b1703..f138d8ef4 100644
--- a/java/res/xml-sw600dp/row_symbols4.xml
+++ b/java/res/xml-sw600dp/row_symbols4.xml
@@ -41,6 +41,8 @@
latin:moreKeys="!text/more_keys_for_tablet_double_quote" />
<Key
latin:keyLabel="_" />
- <!-- Here is empty space. -->
+ <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
+ <Spacer
+ latin:keyWidth="fillRight" />
</Row>
</merge>
diff --git a/java/res/xml-sw600dp/row_symbols_shift4.xml b/java/res/xml-sw600dp/row_symbols_shift4.xml
index 6f3aac7c6..29befa92a 100644
--- a/java/res/xml-sw600dp/row_symbols_shift4.xml
+++ b/java/res/xml-sw600dp/row_symbols_shift4.xml
@@ -33,6 +33,8 @@
latin:keyXPos="28.0%p"
latin:keyboardLayout="@xml/key_space"
latin:backgroundType="normal" />
- <!-- Here is empty space. -->
+ <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
+ <Spacer
+ latin:keyWidth="fillRight" />
</Row>
</merge>
diff --git a/java/res/xml-sw600dp/rows_number_normal.xml b/java/res/xml-sw600dp/rows_number_normal.xml
index 48b304089..f69239456 100644
--- a/java/res/xml-sw600dp/rows_number_normal.xml
+++ b/java/res/xml-sw600dp/rows_number_normal.xml
@@ -153,5 +153,8 @@
<Key
latin:keyLabel="#"
latin:keyStyle="numKeyStyle" />
+ <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
+ <Spacer
+ latin:keyWidth="fillRight" />
</Row>
</merge>
diff --git a/java/res/xml-sw768dp/row_dvorak4.xml b/java/res/xml-sw768dp/row_dvorak4.xml
index 0827815c9..8f9230d4a 100644
--- a/java/res/xml-sw768dp/row_dvorak4.xml
+++ b/java/res/xml-sw768dp/row_dvorak4.xml
@@ -25,8 +25,10 @@
latin:keyWidth="8.047%p"
latin:backgroundType="functional"
>
+ <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
+ <Spacer
+ latin:keyWidth="5.782%p" />
<include
- latin:keyXPos="5.782%p"
latin:keyboardLayout="@xml/key_settings" />
<include
latin:keyboardLayout="@xml/key_shortcut" />
@@ -42,5 +44,8 @@
latin:keyboardLayout="@xml/key_dash" />
<include
latin:keyboardLayout="@xml/key_f2" />
+ <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
+ <Spacer
+ latin:keyWidth="fillRight" />
</Row>
</merge>
diff --git a/java/res/xml-sw768dp/row_hebrew4.xml b/java/res/xml-sw768dp/row_hebrew4.xml
index 180c5641d..ae14f0296 100644
--- a/java/res/xml-sw768dp/row_hebrew4.xml
+++ b/java/res/xml-sw768dp/row_hebrew4.xml
@@ -25,8 +25,10 @@
latin:keyWidth="8.047%p"
latin:backgroundType="functional"
>
+ <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
+ <Spacer
+ latin:keyWidth="5.782%p" />
<include
- latin:keyXPos="5.782%p"
latin:keyboardLayout="@xml/key_settings" />
<include
latin:keyboardLayout="@xml/key_shortcut" />
@@ -40,5 +42,8 @@
latin:keyboardLayout="@xml/keys_comma_period" />
<include
latin:keyboardLayout="@xml/key_f2" />
+ <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
+ <Spacer
+ latin:keyWidth="fillRight" />
</Row>
</merge>
diff --git a/java/res/xml-sw768dp/row_qwerty4.xml b/java/res/xml-sw768dp/row_qwerty4.xml
index 92411f54e..f1f4214ca 100644
--- a/java/res/xml-sw768dp/row_qwerty4.xml
+++ b/java/res/xml-sw768dp/row_qwerty4.xml
@@ -25,8 +25,10 @@
latin:keyWidth="8.047%p"
latin:backgroundType="functional"
>
+ <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
+ <Spacer
+ latin:keyWidth="5.782%p" />
<include
- latin:keyXPos="5.782%p"
latin:keyboardLayout="@xml/key_settings" />
<include
latin:keyboardLayout="@xml/key_shortcut" />
@@ -42,5 +44,8 @@
latin:keyboardLayout="@xml/key_dash" />
<include
latin:keyboardLayout="@xml/key_f2" />
+ <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
+ <Spacer
+ latin:keyWidth="fillRight" />
</Row>
</merge>
diff --git a/java/res/xml-sw768dp/row_symbols4.xml b/java/res/xml-sw768dp/row_symbols4.xml
index 4e1c11994..b801a12a7 100644
--- a/java/res/xml-sw768dp/row_symbols4.xml
+++ b/java/res/xml-sw768dp/row_symbols4.xml
@@ -25,8 +25,10 @@
latin:keyWidth="8.047%p"
latin:backgroundType="functional"
>
+ <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
+ <Spacer
+ latin:keyWidth="13.829%p" />
<Key
- latin:keyXPos="13.829%p"
latin:keyLabel="/" />
<include
latin:keyboardLayout="@xml/key_f1" />
@@ -39,6 +41,8 @@
latin:moreKeys="!text/more_keys_for_tablet_double_quote" />
<Key
latin:keyLabel="_" />
- <!-- Here is empty space. -->
+ <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
+ <Spacer
+ latin:keyWidth="fillRight" />
</Row>
</merge>
diff --git a/java/res/xml-sw768dp/row_symbols_shift4.xml b/java/res/xml-sw768dp/row_symbols_shift4.xml
index 561351cab..f71864bc3 100644
--- a/java/res/xml-sw768dp/row_symbols_shift4.xml
+++ b/java/res/xml-sw768dp/row_symbols_shift4.xml
@@ -25,11 +25,14 @@
latin:keyWidth="8.047%p"
latin:backgroundType="functional"
>
- <!-- Here is empty space. -->
+ <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
+ <Spacer
+ latin:keyWidth="29.923%p" />
<include
- latin:keyXPos="29.923%p"
latin:keyboardLayout="@xml/key_space"
latin:backgroundType="normal" />
- <!-- Here is empty space. -->
+ <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
+ <Spacer
+ latin:keyWidth="fillRight" />
</Row>
</merge>
diff --git a/java/res/xml-sw768dp/rows_number_normal.xml b/java/res/xml-sw768dp/rows_number_normal.xml
index 84910a88f..d4d7c722a 100644
--- a/java/res/xml-sw768dp/rows_number_normal.xml
+++ b/java/res/xml-sw768dp/rows_number_normal.xml
@@ -168,5 +168,8 @@
<Key
latin:keyLabel="#"
latin:keyStyle="numKeyStyle" />
+ <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
+ <Spacer
+ latin:keyWidth="fillRight" />
</Row>
</merge>
diff --git a/java/src/com/android/inputmethod/keyboard/KeyDetector.java b/java/src/com/android/inputmethod/keyboard/KeyDetector.java
index 868c8cab5..f5686dcda 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyDetector.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyDetector.java
@@ -83,11 +83,17 @@ public class KeyDetector {
int minDistance = Integer.MAX_VALUE;
Key primaryKey = null;
for (final Key key: mKeyboard.getNearestKeys(touchX, touchY)) {
- final boolean isOnKey = key.isOnKey(touchX, touchY);
+ // An edge key always has its enlarged hitbox to respond to an event that occurred in
+ // the empty area around the key. (@see Key#markAsLeftEdge(KeyboardParams)} etc.)
+ if (!key.isOnKey(touchX, touchY)) {
+ continue;
+ }
final int distance = key.squaredDistanceToEdge(touchX, touchY);
+ if (distance > minDistance) {
+ continue;
+ }
// To take care of hitbox overlaps, we compare mCode here too.
- if (primaryKey == null || distance < minDistance
- || (distance == minDistance && isOnKey && key.mCode > primaryKey.mCode)) {
+ if (primaryKey == null || distance < minDistance || key.mCode > primaryKey.mCode) {
minDistance = distance;
primaryKey = key;
}
diff --git a/java/src/com/android/inputmethod/latin/AdditionalSubtype.java b/java/src/com/android/inputmethod/latin/AdditionalSubtype.java
index 4b47a261f..509fc1ba3 100644
--- a/java/src/com/android/inputmethod/latin/AdditionalSubtype.java
+++ b/java/src/com/android/inputmethod/latin/AdditionalSubtype.java
@@ -27,22 +27,22 @@ import android.view.inputmethod.InputMethodSubtype;
import java.util.ArrayList;
-public class AdditionalSubtype {
+public final class AdditionalSubtype {
private static final InputMethodSubtype[] EMPTY_SUBTYPE_ARRAY = new InputMethodSubtype[0];
private AdditionalSubtype() {
// This utility class is not publicly instantiable.
}
- public static boolean isAdditionalSubtype(InputMethodSubtype subtype) {
+ public static boolean isAdditionalSubtype(final InputMethodSubtype subtype) {
return subtype.containsExtraValueKey(IS_ADDITIONAL_SUBTYPE);
}
private static final String LOCALE_AND_LAYOUT_SEPARATOR = ":";
- public static final String PREF_SUBTYPE_SEPARATOR = ";";
+ private static final String PREF_SUBTYPE_SEPARATOR = ";";
- public static InputMethodSubtype createAdditionalSubtype(
- String localeString, String keyboardLayoutSetName, String extraValue) {
+ public static InputMethodSubtype createAdditionalSubtype(final String localeString,
+ final String keyboardLayoutSetName, final String extraValue) {
final String layoutExtraValue = KEYBOARD_LAYOUT_SET + "=" + keyboardLayoutSetName;
final String layoutDisplayNameExtraValue;
if (Build.VERSION.SDK_INT >= /* JELLY_BEAN */ 15
@@ -62,7 +62,7 @@ public class AdditionalSubtype {
layoutExtraValue + "," + additionalSubtypeExtraValue, false, false);
}
- public static String getPrefSubtype(InputMethodSubtype subtype) {
+ public static String getPrefSubtype(final InputMethodSubtype subtype) {
final String localeString = subtype.getLocale();
final String keyboardLayoutSetName = SubtypeLocale.getKeyboardLayoutSetName(subtype);
final String layoutExtraValue = KEYBOARD_LAYOUT_SET + "=" + keyboardLayoutSetName;
@@ -74,7 +74,7 @@ public class AdditionalSubtype {
: basePrefSubtype + LOCALE_AND_LAYOUT_SEPARATOR + extraValue;
}
- public static InputMethodSubtype createAdditionalSubtype(String prefSubtype) {
+ public static InputMethodSubtype createAdditionalSubtype(final String prefSubtype) {
final String elems[] = prefSubtype.split(LOCALE_AND_LAYOUT_SEPARATOR);
if (elems.length < 2 || elems.length > 3) {
throw new RuntimeException("Unknown additional subtype specified: " + prefSubtype);
@@ -85,7 +85,7 @@ public class AdditionalSubtype {
return createAdditionalSubtype(localeString, keyboardLayoutSetName, extraValue);
}
- public static InputMethodSubtype[] createAdditionalSubtypesArray(String prefSubtypes) {
+ public static InputMethodSubtype[] createAdditionalSubtypesArray(final String prefSubtypes) {
if (TextUtils.isEmpty(prefSubtypes)) {
return EMPTY_SUBTYPE_ARRAY;
}
@@ -103,4 +103,32 @@ public class AdditionalSubtype {
}
return subtypesList.toArray(new InputMethodSubtype[subtypesList.size()]);
}
+
+ public static String createPrefSubtypes(final InputMethodSubtype[] subtypes) {
+ if (subtypes == null || subtypes.length == 0) {
+ return "";
+ }
+ final StringBuilder sb = new StringBuilder();
+ for (final InputMethodSubtype subtype : subtypes) {
+ if (sb.length() > 0) {
+ sb.append(PREF_SUBTYPE_SEPARATOR);
+ }
+ sb.append(getPrefSubtype(subtype));
+ }
+ return sb.toString();
+ }
+
+ public static String createPrefSubtypes(final String[] prefSubtypes) {
+ if (prefSubtypes == null || prefSubtypes.length == 0) {
+ return "";
+ }
+ final StringBuilder sb = new StringBuilder();
+ for (final String prefSubtype : prefSubtypes) {
+ if (sb.length() > 0) {
+ sb.append(PREF_SUBTYPE_SEPARATOR);
+ }
+ sb.append(prefSubtype);
+ }
+ return sb.toString();
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/AdditionalSubtypeSettings.java b/java/src/com/android/inputmethod/latin/AdditionalSubtypeSettings.java
index d01592a4d..ae51d2537 100644
--- a/java/src/com/android/inputmethod/latin/AdditionalSubtypeSettings.java
+++ b/java/src/com/android/inputmethod/latin/AdditionalSubtypeSettings.java
@@ -63,13 +63,13 @@ public class AdditionalSubtypeSettings extends PreferenceFragment {
private static final String KEY_IS_SUBTYPE_ENABLER_NOTIFICATION_DIALOG_OPEN =
"is_subtype_enabler_notification_dialog_open";
private static final String KEY_SUBTYPE_FOR_SUBTYPE_ENABLER = "subtype_for_subtype_enabler";
- static class SubtypeLocaleItem extends Pair<String, String>
+ static final class SubtypeLocaleItem extends Pair<String, String>
implements Comparable<SubtypeLocaleItem> {
- public SubtypeLocaleItem(String localeString, String displayName) {
+ public SubtypeLocaleItem(final String localeString, final String displayName) {
super(localeString, displayName);
}
- public SubtypeLocaleItem(String localeString) {
+ public SubtypeLocaleItem(final String localeString) {
this(localeString, SubtypeLocale.getSubtypeLocaleDisplayName(localeString));
}
@@ -79,13 +79,13 @@ public class AdditionalSubtypeSettings extends PreferenceFragment {
}
@Override
- public int compareTo(SubtypeLocaleItem o) {
+ public int compareTo(final SubtypeLocaleItem o) {
return first.compareTo(o.first);
}
}
- static class SubtypeLocaleAdapter extends ArrayAdapter<SubtypeLocaleItem> {
- public SubtypeLocaleAdapter(Context context) {
+ static final class SubtypeLocaleAdapter extends ArrayAdapter<SubtypeLocaleItem> {
+ public SubtypeLocaleAdapter(final Context context) {
super(context, android.R.layout.simple_spinner_item);
setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
@@ -102,7 +102,8 @@ public class AdditionalSubtypeSettings extends PreferenceFragment {
addAll(items);
}
- public static SubtypeLocaleItem createItem(Context context, String localeString) {
+ public static SubtypeLocaleItem createItem(final Context context,
+ final String localeString) {
if (localeString.equals(SubtypeLocale.NO_LANGUAGE)) {
final String displayName = context.getString(R.string.subtype_no_language);
return new SubtypeLocaleItem(localeString, displayName);
@@ -112,8 +113,8 @@ public class AdditionalSubtypeSettings extends PreferenceFragment {
}
}
- static class KeyboardLayoutSetItem extends Pair<String, String> {
- public KeyboardLayoutSetItem(InputMethodSubtype subtype) {
+ static final class KeyboardLayoutSetItem extends Pair<String, String> {
+ public KeyboardLayoutSetItem(final InputMethodSubtype subtype) {
super(SubtypeLocale.getKeyboardLayoutSetName(subtype),
SubtypeLocale.getKeyboardLayoutSetDisplayName(subtype));
}
@@ -124,8 +125,8 @@ public class AdditionalSubtypeSettings extends PreferenceFragment {
}
}
- static class KeyboardLayoutSetAdapter extends ArrayAdapter<KeyboardLayoutSetItem> {
- public KeyboardLayoutSetAdapter(Context context) {
+ static final class KeyboardLayoutSetAdapter extends ArrayAdapter<KeyboardLayoutSetItem> {
+ public KeyboardLayoutSetAdapter(final Context context) {
super(context, android.R.layout.simple_spinner_item);
setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
@@ -147,7 +148,7 @@ public class AdditionalSubtypeSettings extends PreferenceFragment {
public KeyboardLayoutSetAdapter getKeyboardLayoutSetAdapter();
}
- static class SubtypePreference extends DialogPreference
+ static final class SubtypePreference extends DialogPreference
implements DialogInterface.OnCancelListener {
private static final String KEY_PREFIX = "subtype_pref_";
private static final String KEY_NEW_SUBTYPE = KEY_PREFIX + "new";
@@ -159,13 +160,13 @@ public class AdditionalSubtypeSettings extends PreferenceFragment {
private Spinner mSubtypeLocaleSpinner;
private Spinner mKeyboardLayoutSetSpinner;
- public static SubtypePreference newIncompleteSubtypePreference(
- Context context, SubtypeDialogProxy proxy) {
+ public static SubtypePreference newIncompleteSubtypePreference(final Context context,
+ final SubtypeDialogProxy proxy) {
return new SubtypePreference(context, null, proxy);
}
- public SubtypePreference(Context context, InputMethodSubtype subtype,
- SubtypeDialogProxy proxy) {
+ public SubtypePreference(final Context context, final InputMethodSubtype subtype,
+ final SubtypeDialogProxy proxy) {
super(context, null);
setDialogLayoutResource(R.layout.additional_subtype_dialog);
setPersistent(false);
@@ -185,7 +186,7 @@ public class AdditionalSubtypeSettings extends PreferenceFragment {
return mSubtype;
}
- public void setSubtype(InputMethodSubtype subtype) {
+ public void setSubtype(final InputMethodSubtype subtype) {
mPreviousSubtype = mSubtype;
mSubtype = subtype;
if (isIncomplete()) {
@@ -221,7 +222,7 @@ public class AdditionalSubtypeSettings extends PreferenceFragment {
}
@Override
- protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
+ protected void onPrepareDialogBuilder(final AlertDialog.Builder builder) {
final Context context = builder.getContext();
builder.setCancelable(true).setOnCancelListener(this);
if (isIncomplete()) {
@@ -239,7 +240,7 @@ public class AdditionalSubtypeSettings extends PreferenceFragment {
}
}
- private static void setSpinnerPosition(Spinner spinner, Object itemToSelect) {
+ private static void setSpinnerPosition(final Spinner spinner, final Object itemToSelect) {
final SpinnerAdapter adapter = spinner.getAdapter();
final int count = adapter.getCount();
for (int i = 0; i < count; i++) {
@@ -252,14 +253,14 @@ public class AdditionalSubtypeSettings extends PreferenceFragment {
}
@Override
- public void onCancel(DialogInterface dialog) {
+ public void onCancel(final DialogInterface dialog) {
if (isIncomplete()) {
mProxy.onRemovePressed(this);
}
}
@Override
- public void onClick(DialogInterface dialog, int which) {
+ public void onClick(final DialogInterface dialog, final int which) {
super.onClick(dialog, which);
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
@@ -287,12 +288,12 @@ public class AdditionalSubtypeSettings extends PreferenceFragment {
}
}
- private static int getSpinnerPosition(Spinner spinner) {
+ private static int getSpinnerPosition(final Spinner spinner) {
if (spinner == null) return -1;
return spinner.getSelectedItemPosition();
}
- private static void setSpinnerPosition(Spinner spinner, int position) {
+ private static void setSpinnerPosition(final Spinner spinner, final int position) {
if (spinner == null || position < 0) return;
spinner.setSelection(position);
}
@@ -313,7 +314,7 @@ public class AdditionalSubtypeSettings extends PreferenceFragment {
}
@Override
- protected void onRestoreInstanceState(Parcelable state) {
+ protected void onRestoreInstanceState(final Parcelable state) {
if (!(state instanceof SavedState)) {
super.onRestoreInstanceState(state);
return;
@@ -326,24 +327,24 @@ public class AdditionalSubtypeSettings extends PreferenceFragment {
setSubtype(myState.mSubtype);
}
- static class SavedState extends Preference.BaseSavedState {
+ static final class SavedState extends Preference.BaseSavedState {
InputMethodSubtype mSubtype;
int mSubtypeLocaleSelectedPos;
int mKeyboardLayoutSetSelectedPos;
- public SavedState(Parcelable superState) {
+ public SavedState(final Parcelable superState) {
super(superState);
}
@Override
- public void writeToParcel(Parcel dest, int flags) {
+ public void writeToParcel(final Parcel dest, final int flags) {
super.writeToParcel(dest, flags);
dest.writeInt(mSubtypeLocaleSelectedPos);
dest.writeInt(mKeyboardLayoutSetSelectedPos);
dest.writeParcelable(mSubtype, 0);
}
- public SavedState(Parcel source) {
+ public SavedState(final Parcel source) {
super(source);
mSubtypeLocaleSelectedPos = source.readInt();
mKeyboardLayoutSetSelectedPos = source.readInt();
@@ -354,12 +355,12 @@ public class AdditionalSubtypeSettings extends PreferenceFragment {
public static final Parcelable.Creator<SavedState> CREATOR =
new Parcelable.Creator<SavedState>() {
@Override
- public SavedState createFromParcel(Parcel source) {
+ public SavedState createFromParcel(final Parcel source) {
return new SavedState(source);
}
@Override
- public SavedState[] newArray(int size) {
+ public SavedState[] newArray(final int size) {
return new SavedState[size];
}
};
@@ -371,7 +372,7 @@ public class AdditionalSubtypeSettings extends PreferenceFragment {
}
@Override
- public void onCreate(Bundle savedInstanceState) {
+ public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.additional_subtype_settings);
@@ -381,7 +382,7 @@ public class AdditionalSubtypeSettings extends PreferenceFragment {
}
@Override
- public void onActivityCreated(Bundle savedInstanceState) {
+ public void onActivityCreated(final Bundle savedInstanceState) {
final Context context = getActivity();
mSubtypeLocaleAdapter = new SubtypeLocaleAdapter(context);
mKeyboardLayoutSetAdapter = new KeyboardLayoutSetAdapter(context);
@@ -411,7 +412,7 @@ public class AdditionalSubtypeSettings extends PreferenceFragment {
}
@Override
- public void onSaveInstanceState(Bundle outState) {
+ public void onSaveInstanceState(final Bundle outState) {
super.onSaveInstanceState(outState);
if (mIsAddingNewSubtype) {
outState.putBoolean(KEY_IS_ADDING_NEW_SUBTYPE, true);
@@ -426,7 +427,7 @@ public class AdditionalSubtypeSettings extends PreferenceFragment {
private final SubtypeDialogProxy mSubtypeProxy = new SubtypeDialogProxy() {
@Override
- public void onRemovePressed(SubtypePreference subtypePref) {
+ public void onRemovePressed(final SubtypePreference subtypePref) {
mIsAddingNewSubtype = false;
final PreferenceGroup group = getPreferenceScreen();
group.removePreference(subtypePref);
@@ -434,7 +435,7 @@ public class AdditionalSubtypeSettings extends PreferenceFragment {
}
@Override
- public void onSavePressed(SubtypePreference subtypePref) {
+ public void onSavePressed(final SubtypePreference subtypePref) {
final InputMethodSubtype subtype = subtypePref.getSubtype();
if (!subtypePref.hasBeenModified()) {
return;
@@ -453,7 +454,7 @@ public class AdditionalSubtypeSettings extends PreferenceFragment {
}
@Override
- public void onAddPressed(SubtypePreference subtypePref) {
+ public void onAddPressed(final SubtypePreference subtypePref) {
mIsAddingNewSubtype = false;
final InputMethodSubtype subtype = subtypePref.getSubtype();
if (findDuplicatedSubtype(subtype) == null) {
@@ -481,7 +482,7 @@ public class AdditionalSubtypeSettings extends PreferenceFragment {
}
};
- private void showSubtypeAlreadyExistsToast(InputMethodSubtype subtype) {
+ private void showSubtypeAlreadyExistsToast(final InputMethodSubtype subtype) {
final Context context = getActivity();
final Resources res = context.getResources();
final String message = res.getString(R.string.custom_input_style_already_exists,
@@ -489,14 +490,15 @@ public class AdditionalSubtypeSettings extends PreferenceFragment {
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
}
- private InputMethodSubtype findDuplicatedSubtype(InputMethodSubtype subtype) {
+ private InputMethodSubtype findDuplicatedSubtype(final InputMethodSubtype subtype) {
final String localeString = subtype.getLocale();
final String keyboardLayoutSetName = SubtypeLocale.getKeyboardLayoutSetName(subtype);
return ImfUtils.findSubtypeByLocaleAndKeyboardLayoutSet(
getActivity(), localeString, keyboardLayoutSetName);
}
- private AlertDialog createDialog(SubtypePreference subtypePref) {
+ private AlertDialog createDialog(
+ @SuppressWarnings("unused") final SubtypePreference subtypePref) {
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(R.string.custom_input_styles_title)
.setMessage(R.string.custom_input_style_note_message)
@@ -519,7 +521,7 @@ public class AdditionalSubtypeSettings extends PreferenceFragment {
return builder.create();
}
- private void setPrefSubtypes(String prefSubtypes, Context context) {
+ private void setPrefSubtypes(final String prefSubtypes, final Context context) {
final PreferenceGroup group = getPreferenceScreen();
group.removeAll();
final InputMethodSubtype[] subtypesArray =
@@ -547,23 +549,12 @@ public class AdditionalSubtypeSettings extends PreferenceFragment {
return subtypes.toArray(new InputMethodSubtype[subtypes.size()]);
}
- private String getPrefSubtypes(InputMethodSubtype[] subtypes) {
- final StringBuilder sb = new StringBuilder();
- for (final InputMethodSubtype subtype : subtypes) {
- if (sb.length() > 0) {
- sb.append(AdditionalSubtype.PREF_SUBTYPE_SEPARATOR);
- }
- sb.append(AdditionalSubtype.getPrefSubtype(subtype));
- }
- return sb.toString();
- }
-
@Override
public void onPause() {
super.onPause();
final String oldSubtypes = SettingsValues.getPrefAdditionalSubtypes(mPrefs, getResources());
final InputMethodSubtype[] subtypes = getSubtypes();
- final String prefSubtypes = getPrefSubtypes(subtypes);
+ final String prefSubtypes = AdditionalSubtype.createPrefSubtypes(subtypes);
if (prefSubtypes.equals(oldSubtypes)) {
return;
}
@@ -578,13 +569,13 @@ public class AdditionalSubtypeSettings extends PreferenceFragment {
}
@Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
final MenuItem addSubtypeMenu = menu.add(0, MENU_ADD_SUBTYPE, 0, R.string.add_style);
addSubtypeMenu.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
}
@Override
- public boolean onOptionsItemSelected(MenuItem item) {
+ public boolean onOptionsItemSelected(final MenuItem item) {
final int itemId = item.getItemId();
if (itemId == MENU_ADD_SUBTYPE) {
final SubtypePreference newSubtype =
diff --git a/java/src/com/android/inputmethod/latin/SettingsValues.java b/java/src/com/android/inputmethod/latin/SettingsValues.java
index 5e355a3b8..5e9c870d4 100644
--- a/java/src/com/android/inputmethod/latin/SettingsValues.java
+++ b/java/src/com/android/inputmethod/latin/SettingsValues.java
@@ -35,7 +35,7 @@ import java.util.HashMap;
* When you call the constructor of this class, you may want to change the current system locale by
* using {@link LocaleUtils.RunInLocale}.
*/
-public class SettingsValues {
+public final class SettingsValues {
private static final String TAG = SettingsValues.class.getSimpleName();
private static final int SUGGESTION_VISIBILITY_SHOW_VALUE
@@ -246,64 +246,65 @@ public class SettingsValues {
&& orientation == Configuration.ORIENTATION_PORTRAIT);
}
- public boolean isWordSeparator(int code) {
+ public boolean isWordSeparator(final int code) {
return mWordSeparators.contains(String.valueOf((char)code));
}
- public boolean isSymbolExcludedFromWordSeparators(int code) {
+ public boolean isSymbolExcludedFromWordSeparators(final int code) {
return mSymbolsExcludedFromWordSeparators.contains(String.valueOf((char)code));
}
- public boolean isWeakSpaceStripper(int code) {
+ public boolean isWeakSpaceStripper(final int code) {
// TODO: this does not work if the code does not fit in a char
return mWeakSpaceStrippers.contains(String.valueOf((char)code));
}
- public boolean isWeakSpaceSwapper(int code) {
+ public boolean isWeakSpaceSwapper(final int code) {
// TODO: this does not work if the code does not fit in a char
return mWeakSpaceSwappers.contains(String.valueOf((char)code));
}
- public boolean isPhantomSpacePromotingSymbol(int code) {
+ public boolean isPhantomSpacePromotingSymbol(final int code) {
// TODO: this does not work if the code does not fit in a char
return mPhantomSpacePromotingSymbols.contains(String.valueOf((char)code));
}
- private static boolean isAutoCorrectEnabled(final Resources resources,
+ private static boolean isAutoCorrectEnabled(final Resources res,
final String currentAutoCorrectionSetting) {
- final String autoCorrectionOff = resources.getString(
+ final String autoCorrectionOff = res.getString(
R.string.auto_correction_threshold_mode_index_off);
return !currentAutoCorrectionSetting.equals(autoCorrectionOff);
}
// Public to access from KeyboardSwitcher. Should it have access to some
// process-global instance instead?
- public static boolean isKeyPreviewPopupEnabled(SharedPreferences sp, Resources resources) {
- final boolean showPopupOption = resources.getBoolean(
+ public static boolean isKeyPreviewPopupEnabled(final SharedPreferences prefs,
+ final Resources res) {
+ final boolean showPopupOption = res.getBoolean(
R.bool.config_enable_show_popup_on_keypress_option);
- if (!showPopupOption) return resources.getBoolean(R.bool.config_default_popup_preview);
- return sp.getBoolean(Settings.PREF_POPUP_ON,
- resources.getBoolean(R.bool.config_default_popup_preview));
+ if (!showPopupOption) return res.getBoolean(R.bool.config_default_popup_preview);
+ return prefs.getBoolean(Settings.PREF_POPUP_ON,
+ res.getBoolean(R.bool.config_default_popup_preview));
}
// Likewise
- public static int getKeyPreviewPopupDismissDelay(SharedPreferences sp,
- Resources resources) {
+ public static int getKeyPreviewPopupDismissDelay(final SharedPreferences prefs,
+ final Resources res) {
// TODO: use mKeyPreviewPopupDismissDelayRawValue instead of reading it again here.
- return Integer.parseInt(sp.getString(Settings.PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY,
- Integer.toString(resources.getInteger(
+ return Integer.parseInt(prefs.getString(Settings.PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY,
+ Integer.toString(res.getInteger(
R.integer.config_key_preview_linger_timeout))));
}
- private static boolean isBigramPredictionEnabled(final SharedPreferences sp,
- final Resources resources) {
- return sp.getBoolean(Settings.PREF_BIGRAM_PREDICTIONS, resources.getBoolean(
+ private static boolean isBigramPredictionEnabled(final SharedPreferences prefs,
+ final Resources res) {
+ return prefs.getBoolean(Settings.PREF_BIGRAM_PREDICTIONS, res.getBoolean(
R.bool.config_default_next_word_prediction));
}
- private static float getAutoCorrectionThreshold(final Resources resources,
+ private static float getAutoCorrectionThreshold(final Resources res,
final String currentAutoCorrectionSetting) {
- final String[] autoCorrectionThresholdValues = resources.getStringArray(
+ final String[] autoCorrectionThresholdValues = res.getStringArray(
R.array.auto_correction_threshold_values);
// When autoCorrectionThreshold is greater than 1.0, it's like auto correction is off.
float autoCorrectionThreshold = Float.MAX_VALUE;
@@ -335,11 +336,11 @@ public class SettingsValues {
return mVoiceKeyOnMain;
}
- public static boolean isLanguageSwitchKeySupressed(SharedPreferences sp) {
- return sp.getBoolean(Settings.PREF_SUPPRESS_LANGUAGE_SWITCH_KEY, false);
+ public static boolean isLanguageSwitchKeySupressed(final SharedPreferences prefs) {
+ return prefs.getBoolean(Settings.PREF_SUPPRESS_LANGUAGE_SWITCH_KEY, false);
}
- public boolean isLanguageSwitchKeyEnabled(Context context) {
+ public boolean isLanguageSwitchKeyEnabled(final Context context) {
if (mIsLanguageSwitchKeySuppressed) {
return false;
}
@@ -352,7 +353,7 @@ public class SettingsValues {
}
}
- public boolean isFullscreenModeAllowed(Resources res) {
+ public boolean isFullscreenModeAllowed(final Resources res) {
return res.getBoolean(R.bool.config_use_fullscreen_mode);
}
@@ -362,15 +363,16 @@ public class SettingsValues {
public static String getPrefAdditionalSubtypes(final SharedPreferences prefs,
final Resources res) {
- final String prefSubtypes = res.getString(R.string.predefined_subtypes, "");
- return prefs.getString(Settings.PREF_CUSTOM_INPUT_STYLES, prefSubtypes);
+ final String predefinedPrefSubtypes = AdditionalSubtype.createPrefSubtypes(
+ res.getStringArray(R.array.predefined_subtypes));
+ return prefs.getString(Settings.PREF_CUSTOM_INPUT_STYLES, predefinedPrefSubtypes);
}
// Accessed from the settings interface, hence public
- public static float getCurrentKeypressSoundVolume(final SharedPreferences sp,
- final Resources res) {
+ public static float getCurrentKeypressSoundVolume(final SharedPreferences prefs,
+ final Resources res) {
// TODO: use mVibrationDurationSettingsRawValue instead of reading it again here
- final float volume = sp.getFloat(Settings.PREF_KEYPRESS_SOUND_VOLUME, -1.0f);
+ final float volume = prefs.getFloat(Settings.PREF_KEYPRESS_SOUND_VOLUME, -1.0f);
if (volume >= 0) {
return volume;
}
@@ -380,10 +382,10 @@ public class SettingsValues {
}
// Likewise
- public static int getCurrentVibrationDuration(final SharedPreferences sp,
- final Resources res) {
+ public static int getCurrentVibrationDuration(final SharedPreferences prefs,
+ final Resources res) {
// TODO: use mKeypressVibrationDuration instead of reading it again here
- final int ms = sp.getInt(Settings.PREF_VIBRATION_DURATION_SETTINGS, -1);
+ final int ms = prefs.getInt(Settings.PREF_VIBRATION_DURATION_SETTINGS, -1);
if (ms >= 0) {
return ms;
}
@@ -398,8 +400,8 @@ public class SettingsValues {
return prefs.getBoolean(Settings.PREF_USABILITY_STUDY_MODE, true);
}
- public static long getLastUserHistoryWriteTime(
- final SharedPreferences prefs, final String locale) {
+ public static long getLastUserHistoryWriteTime(final SharedPreferences prefs,
+ final String locale) {
final String str = prefs.getString(Settings.PREF_LAST_USER_DICTIONARY_WRITE_TIME, "");
final HashMap<String, Long> map = LocaleUtils.localeAndTimeStrToHashMap(str);
if (map.containsKey(locale)) {
@@ -408,8 +410,8 @@ public class SettingsValues {
return 0;
}
- public static void setLastUserHistoryWriteTime(
- final SharedPreferences prefs, final String locale) {
+ public static void setLastUserHistoryWriteTime(final SharedPreferences prefs,
+ final String locale) {
final String oldStr = prefs.getString(Settings.PREF_LAST_USER_DICTIONARY_WRITE_TIME, "");
final HashMap<String, Long> map = LocaleUtils.localeAndTimeStrToHashMap(oldStr);
map.put(locale, System.currentTimeMillis());
diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java
index 68ecfa0d7..d9f48c4a4 100644
--- a/java/src/com/android/inputmethod/latin/SuggestedWords.java
+++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java
@@ -177,7 +177,7 @@ public class SuggestedWords {
return;
}
int i = 1;
- while(i < candidates.size()) {
+ while (i < candidates.size()) {
final SuggestedWordInfo cur = candidates.get(i);
for (int j = 0; j < i; ++j) {
final SuggestedWordInfo previous = candidates.get(j);
diff --git a/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java b/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
index f1abea9ec..61f7371b8 100644
--- a/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
+++ b/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
@@ -728,7 +728,7 @@ public class FusionDictionary implements Iterable<Word> {
// StringBuilder s = new StringBuilder();
// for (CharGroup g : node.data) {
// s.append(g.frequency);
-// for (int ch : g.chars){
+// for (int ch : g.chars) {
// s.append(Character.toChars(ch));
// }
// }
@@ -794,7 +794,7 @@ public class FusionDictionary implements Iterable<Word> {
currentPos = mPositions.getLast();
mCurrentString.setLength(mCurrentString.length() - mPositions.getLast().length);
}
- } while(true);
+ } while (true);
}
@Override
diff --git a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
index a20958a88..dd2513f9f 100644
--- a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
+++ b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
@@ -68,9 +68,9 @@ static jlong latinime_BinaryDictionary_open(JNIEnv *env, jobject object,
return 0;
}
int pagesize = getpagesize();
- adjust = dictOffset % pagesize;
- int adjDictOffset = dictOffset - adjust;
- int adjDictSize = dictSize + adjust;
+ adjust = static_cast<int>(dictOffset) % pagesize;
+ int adjDictOffset = static_cast<int>(dictOffset) - adjust;
+ int adjDictSize = static_cast<int>(dictSize) + adjust;
dictBuf = mmap(0, sizeof(char) * adjDictSize, PROT_READ, MAP_PRIVATE, fd, adjDictOffset);
if (dictBuf == MAP_FAILED) {
AKLOGE("DICT: Can't mmap dictionary. errno=%d", errno);
@@ -120,8 +120,8 @@ static jlong latinime_BinaryDictionary_open(JNIEnv *env, jobject object,
releaseDictBuf(dictBuf, 0, 0);
#endif // USE_MMAP_FOR_DICTIONARY
} else {
- dictionary = new Dictionary(dictBuf, dictSize, fd, adjust, typedLetterMultiplier,
- fullWordMultiplier, maxWordLength, maxWords, maxPredictions);
+ dictionary = new Dictionary(dictBuf, static_cast<int>(dictSize), fd, adjust,
+ typedLetterMultiplier, fullWordMultiplier, maxWordLength, maxWords, maxPredictions);
}
PROF_END(66);
PROF_CLOSE;
diff --git a/native/jni/src/additional_proximity_chars.h b/native/jni/src/additional_proximity_chars.h
index 1fe996d0d..d420c4664 100644
--- a/native/jni/src/additional_proximity_chars.h
+++ b/native/jni/src/additional_proximity_chars.h
@@ -50,7 +50,7 @@ class AdditionalProximityChars {
if (!isEnLocale(localeStr)) {
return 0;
}
- switch(c) {
+ switch (c) {
case 'a':
return EN_US_ADDITIONAL_A_SIZE;
case 'e':
@@ -70,7 +70,7 @@ class AdditionalProximityChars {
if (!isEnLocale(localeStr)) {
return 0;
}
- switch(c) {
+ switch (c) {
case 'a':
return EN_US_ADDITIONAL_A;
case 'e':
diff --git a/native/jni/src/basechars.cpp b/native/jni/src/basechars.cpp
index c91e5f741..379cb6226 100644
--- a/native/jni/src/basechars.cpp
+++ b/native/jni/src/basechars.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include <stdint.h>
+
#include "char_utils.h"
namespace latinime {
@@ -24,7 +26,7 @@ namespace latinime {
* if c is not a combined character, or the base character if it
* is combined.
*/
-const unsigned short BASE_CHARS[BASE_CHARS_SIZE] = {
+const uint16_t BASE_CHARS[BASE_CHARS_SIZE] = {
0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
diff --git a/native/jni/src/bigram_dictionary.cpp b/native/jni/src/bigram_dictionary.cpp
index f1d538095..3eea51a41 100644
--- a/native/jni/src/bigram_dictionary.cpp
+++ b/native/jni/src/bigram_dictionary.cpp
@@ -156,7 +156,7 @@ int BigramDictionary::getBigramListPositionForWord(const int32_t *prevWord,
const int flags = BinaryFormat::getFlagsAndForwardPointer(root, &pos);
if (0 == (flags & BinaryFormat::FLAG_HAS_BIGRAMS)) return 0;
if (0 == (flags & BinaryFormat::FLAG_HAS_MULTIPLE_CHARS)) {
- BinaryFormat::getCharCodeAndForwardPointer(root, &pos);
+ BinaryFormat::getCodePointAndForwardPointer(root, &pos);
} else {
pos = BinaryFormat::skipOtherCharacters(root, pos);
}
diff --git a/native/jni/src/binary_format.h b/native/jni/src/binary_format.h
index 25d504bfb..5d8b2a0f2 100644
--- a/native/jni/src/binary_format.h
+++ b/native/jni/src/binary_format.h
@@ -84,7 +84,7 @@ class BinaryFormat {
static unsigned int getFlags(const uint8_t *const dict);
static int getGroupCountAndForwardPointer(const uint8_t *const dict, int *pos);
static uint8_t getFlagsAndForwardPointer(const uint8_t *const dict, int *pos);
- static int32_t getCharCodeAndForwardPointer(const uint8_t *const dict, int *pos);
+ static int32_t getCodePointAndForwardPointer(const uint8_t *const dict, int *pos);
static int readFrequencyWithoutMovingPointer(const uint8_t *const dict, const int pos);
static int skipOtherCharacters(const uint8_t *const dict, const int pos);
static int skipChildrenPosition(const uint8_t flags, const int pos);
@@ -176,22 +176,22 @@ inline uint8_t BinaryFormat::getFlagsAndForwardPointer(const uint8_t *const dict
return dict[(*pos)++];
}
-inline int32_t BinaryFormat::getCharCodeAndForwardPointer(const uint8_t *const dict, int *pos) {
+inline int32_t BinaryFormat::getCodePointAndForwardPointer(const uint8_t *const dict, int *pos) {
const int origin = *pos;
- const int32_t character = dict[origin];
- if (character < MINIMAL_ONE_BYTE_CHARACTER_VALUE) {
- if (character == CHARACTER_ARRAY_TERMINATOR) {
+ const int32_t codePoint = dict[origin];
+ if (codePoint < MINIMAL_ONE_BYTE_CHARACTER_VALUE) {
+ if (codePoint == CHARACTER_ARRAY_TERMINATOR) {
*pos = origin + 1;
- return NOT_A_CHARACTER;
+ return NOT_A_CODE_POINT;
} else {
*pos = origin + 3;
- const int32_t char_1 = character << 16;
+ const int32_t char_1 = codePoint << 16;
const int32_t char_2 = char_1 + (dict[origin + 1] << 8);
return char_2 + dict[origin + 2];
}
} else {
*pos = origin + 1;
- return character;
+ return codePoint;
}
}
@@ -369,15 +369,15 @@ inline int BinaryFormat::getTerminalPosition(const uint8_t *const root,
if (0 >= charGroupCount) return NOT_VALID_WORD;
const int charGroupPos = pos;
const uint8_t flags = BinaryFormat::getFlagsAndForwardPointer(root, &pos);
- int32_t character = BinaryFormat::getCharCodeAndForwardPointer(root, &pos);
+ int32_t character = BinaryFormat::getCodePointAndForwardPointer(root, &pos);
if (character == wChar) {
// This is the correct node. Only one character group may start with the same
// char within a node, so either we found our match in this node, or there is
// no match and we can return NOT_VALID_WORD. So we will check all the characters
// in this character group indeed does match.
if (FLAG_HAS_MULTIPLE_CHARS & flags) {
- character = BinaryFormat::getCharCodeAndForwardPointer(root, &pos);
- while (NOT_A_CHARACTER != character) {
+ character = BinaryFormat::getCodePointAndForwardPointer(root, &pos);
+ while (NOT_A_CODE_POINT != character) {
++wordPos;
// If we shoot the length of the word we search for, or if we find a single
// character that does not match, as explained above, it means the word is
@@ -385,7 +385,7 @@ inline int BinaryFormat::getTerminalPosition(const uint8_t *const root,
// match the word on the first character, but not matching the whole word).
if (wordPos > length) return NOT_VALID_WORD;
if (inWord[wordPos] != character) return NOT_VALID_WORD;
- character = BinaryFormat::getCharCodeAndForwardPointer(root, &pos);
+ character = BinaryFormat::getCodePointAndForwardPointer(root, &pos);
}
}
// If we come here we know that so far, we do match. Either we are on a terminal
@@ -457,19 +457,19 @@ inline int BinaryFormat::getWordAtAddress(const uint8_t *const root, const int a
--charGroupCount) {
const int startPos = pos;
const uint8_t flags = getFlagsAndForwardPointer(root, &pos);
- const int32_t character = getCharCodeAndForwardPointer(root, &pos);
+ const int32_t character = getCodePointAndForwardPointer(root, &pos);
if (address == startPos) {
// We found the address. Copy the rest of the word in the buffer and return
// the length.
outWord[wordPos] = character;
if (FLAG_HAS_MULTIPLE_CHARS & flags) {
- int32_t nextChar = getCharCodeAndForwardPointer(root, &pos);
+ int32_t nextChar = getCodePointAndForwardPointer(root, &pos);
// We count chars in order to avoid infinite loops if the file is broken or
// if there is some other bug
int charCount = maxDepth;
- while (NOT_A_CHARACTER != nextChar && --charCount > 0) {
+ while (NOT_A_CODE_POINT != nextChar && --charCount > 0) {
outWord[++wordPos] = nextChar;
- nextChar = getCharCodeAndForwardPointer(root, &pos);
+ nextChar = getCodePointAndForwardPointer(root, &pos);
}
}
*outUnigramFrequency = readFrequencyWithoutMovingPointer(root, pos);
@@ -523,16 +523,16 @@ inline int BinaryFormat::getWordAtAddress(const uint8_t *const root, const int a
const uint8_t lastFlags =
getFlagsAndForwardPointer(root, &lastCandidateGroupPos);
const int32_t lastChar =
- getCharCodeAndForwardPointer(root, &lastCandidateGroupPos);
+ getCodePointAndForwardPointer(root, &lastCandidateGroupPos);
// We copy all the characters in this group to the buffer
outWord[wordPos] = lastChar;
if (FLAG_HAS_MULTIPLE_CHARS & lastFlags) {
int32_t nextChar =
- getCharCodeAndForwardPointer(root, &lastCandidateGroupPos);
+ getCodePointAndForwardPointer(root, &lastCandidateGroupPos);
int charCount = maxDepth;
while (-1 != nextChar && --charCount > 0) {
outWord[++wordPos] = nextChar;
- nextChar = getCharCodeAndForwardPointer(root, &lastCandidateGroupPos);
+ nextChar = getCodePointAndForwardPointer(root, &lastCandidateGroupPos);
}
}
++wordPos;
@@ -582,8 +582,8 @@ inline int BinaryFormat::computeFrequencyForBigram(const int unigramFreq, const
// 0 for the bigram frequency represents the middle of the 16th step from the top,
// while a value of 15 represents the middle of the top step.
// See makedict.BinaryDictInputOutput for details.
- const float stepSize = (static_cast<float>(MAX_FREQ) - unigramFreq) / (1.5f + MAX_BIGRAM_FREQ);
- return static_cast<int>(unigramFreq + (bigramFreq + 1) * stepSize);
+ const float stepSize = static_cast<float>(MAX_FREQ - unigramFreq) / (1.5f + MAX_BIGRAM_FREQ);
+ return unigramFreq + static_cast<int>(static_cast<float>(bigramFreq + 1) * stepSize);
}
// This returns a probability in log space.
diff --git a/native/jni/src/bloom_filter.h b/native/jni/src/bloom_filter.h
index 47177dcba..bcce1f7ea 100644
--- a/native/jni/src/bloom_filter.h
+++ b/native/jni/src/bloom_filter.h
@@ -23,14 +23,16 @@
namespace latinime {
-static inline void setInFilter(uint8_t *filter, const int position) {
- const unsigned int bucket = position % BIGRAM_FILTER_MODULO;
- filter[bucket >> 3] |= (1 << (bucket & 0x7));
+// TODO: uint32_t position
+static inline void setInFilter(uint8_t *filter, const int32_t position) {
+ const uint32_t bucket = static_cast<uint32_t>(position % BIGRAM_FILTER_MODULO);
+ filter[bucket >> 3] |= static_cast<uint8_t>(1 << (bucket & 0x7));
}
-static inline bool isInFilter(const uint8_t *filter, const int position) {
- const unsigned int bucket = position % BIGRAM_FILTER_MODULO;
- return filter[bucket >> 3] & (1 << (bucket & 0x7));
+// TODO: uint32_t position
+static inline bool isInFilter(const uint8_t *filter, const int32_t position) {
+ const uint32_t bucket = static_cast<uint32_t>(position % BIGRAM_FILTER_MODULO);
+ return filter[bucket >> 3] & static_cast<uint8_t>(1 << (bucket & 0x7));
}
} // namespace latinime
#endif // LATINIME_BLOOM_FILTER_H
diff --git a/native/jni/src/char_utils.h b/native/jni/src/char_utils.h
index b30677fa7..b17f262ec 100644
--- a/native/jni/src/char_utils.h
+++ b/native/jni/src/char_utils.h
@@ -18,6 +18,7 @@
#define LATINIME_CHAR_UTILS_H
#include <cctype>
+#include <stdint.h>
namespace latinime {
@@ -43,7 +44,7 @@ unsigned short latin_tolower(const unsigned short c);
*/
static const int BASE_CHARS_SIZE = 0x0500;
-extern const unsigned short BASE_CHARS[BASE_CHARS_SIZE];
+extern const uint16_t BASE_CHARS[BASE_CHARS_SIZE];
inline static unsigned short toBaseChar(unsigned short c) {
if (c < BASE_CHARS_SIZE) {
diff --git a/native/jni/src/correction.cpp b/native/jni/src/correction.cpp
index 9ad65b09d..92cfd1a49 100644
--- a/native/jni/src/correction.cpp
+++ b/native/jni/src/correction.cpp
@@ -362,7 +362,8 @@ Correction::CorrectionType Correction::processCharAndCalcState(
if (mSkipPos >= 0) {
if (mSkippedCount == 0 && mSkipPos < mOutputIndex) {
if (DEBUG_DICT) {
- assert(mSkipPos == mOutputIndex - 1);
+ // TODO: Enable this assertion.
+ //assert(mSkipPos == mOutputIndex - 1);
}
mSkipPos = mOutputIndex;
}
@@ -630,7 +631,7 @@ Correction::CorrectionType Correction::processCharAndCalcState(
inline static int getQuoteCount(const unsigned short *word, const int length) {
int quoteCount = 0;
for (int i = 0; i < length; ++i) {
- if(word[i] == '\'') {
+ if (word[i] == '\'') {
++quoteCount;
}
}
@@ -936,7 +937,7 @@ int Correction::RankingAlgorithm::calcFreqForSplitMultipleWords(
int totalLength = 0;
int totalFreq = 0;
- for (int i = 0; i < wordCount; ++i){
+ for (int i = 0; i < wordCount; ++i) {
const int wordLength = wordLengthArray[i];
if (wordLength <= 0) {
return 0;
@@ -1126,15 +1127,16 @@ float Correction::RankingAlgorithm::calcNormalizedScore(const unsigned short *be
return 0;
}
- const float maxScore = score >= S_INT_MAX ? S_INT_MAX : MAX_INITIAL_SCORE
- * powf(static_cast<float>(TYPED_LETTER_MULTIPLIER),
- static_cast<float>(min(beforeLength, afterLength - spaceCount)))
- * FULL_WORD_MULTIPLIER;
+ const float maxScore = score >= S_INT_MAX ? static_cast<float>(S_INT_MAX)
+ : static_cast<float>(MAX_INITIAL_SCORE)
+ * powf(static_cast<float>(TYPED_LETTER_MULTIPLIER),
+ static_cast<float>(min(beforeLength, afterLength - spaceCount)))
+ * static_cast<float>(FULL_WORD_MULTIPLIER);
// add a weight based on edit distance.
// distance <= max(afterLength, beforeLength) == afterLength,
// so, 0 <= distance / afterLength <= 1
const float weight = 1.0f - static_cast<float>(distance) / static_cast<float>(afterLength);
- return (score / maxScore) * weight;
+ return (static_cast<float>(score) / maxScore) * weight;
}
} // namespace latinime
diff --git a/native/jni/src/defines.h b/native/jni/src/defines.h
index 28661ab20..0286365bc 100644
--- a/native/jni/src/defines.h
+++ b/native/jni/src/defines.h
@@ -17,6 +17,8 @@
#ifndef LATINIME_DEFINES_H
#define LATINIME_DEFINES_H
+#include <stdint.h>
+
#if defined(FLAG_DO_PROFILE) || defined(FLAG_DBG)
#include <android/log.h>
#ifndef LOG_TAG
@@ -26,9 +28,9 @@
#define AKLOGI(fmt, ...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, fmt, ##__VA_ARGS__)
#define DUMP_RESULT(words, frequencies, maxWordCount, maxWordLength) do { \
- dumpResult(words, frequencies, maxWordCount, maxWordLength); } while(0)
-#define DUMP_WORD(word, length) do { dumpWord(word, length); } while(0)
-#define DUMP_WORD_INT(word, length) do { dumpWordInt(word, length); } while(0)
+ dumpResult(words, frequencies, maxWordCount, maxWordLength); } while (0)
+#define DUMP_WORD(word, length) do { dumpWord(word, length); } while (0)
+#define DUMP_WORD_INT(word, length) do { dumpWordInt(word, length); } while (0)
static inline void dumpWordInfo(const unsigned short *word, const int length,
const int rank, const int frequency) {
@@ -39,7 +41,8 @@ static inline void dumpWordInfo(const unsigned short *word, const int length,
if (c == 0) {
break;
}
- charBuf[i] = c;
+ // static_cast only for debugging
+ charBuf[i] = static_cast<char>(c);
}
charBuf[i] = 0;
if (i > 1) {
@@ -65,7 +68,8 @@ static inline void dumpWord(const unsigned short *word, const int length) {
if (c == 0) {
break;
}
- charBuf[i] = c;
+ // static_cast only for debugging
+ charBuf[i] = static_cast<char>(c);
}
charBuf[i] = 0;
if (i > 1) {
@@ -84,7 +88,7 @@ static inline void dumpWordInt(const int *word, const int length) {
}
#ifndef __ANDROID__
-#define ASSERT(success) do { if(!success) { showStackTrace(); assert(success);};} while (0)
+#define ASSERT(success) do { if (!success) { showStackTrace(); assert(success);};} while (0)
#define SHOW_STACK_TRACE do { showStackTrace(); } while (0)
#include <execinfo.h>
@@ -128,14 +132,14 @@ static unsigned int profile_counter[PROF_BUF_SIZE];
#define PROF_RESET prof_reset()
#define PROF_COUNT(prof_buf_id) ++profile_counter[prof_buf_id]
-#define PROF_OPEN do { PROF_RESET; PROF_START(PROF_BUF_SIZE - 1); } while(0)
+#define PROF_OPEN do { PROF_RESET; PROF_START(PROF_BUF_SIZE - 1); } while (0)
#define PROF_START(prof_buf_id) do { \
- PROF_COUNT(prof_buf_id); profile_old[prof_buf_id] = (clock()); } while(0)
-#define PROF_CLOSE do { PROF_END(PROF_BUF_SIZE - 1); PROF_OUTALL; } while(0)
+ PROF_COUNT(prof_buf_id); profile_old[prof_buf_id] = (clock()); } while (0)
+#define PROF_CLOSE do { PROF_END(PROF_BUF_SIZE - 1); PROF_OUTALL; } while (0)
#define PROF_END(prof_buf_id) profile_buf[prof_buf_id] += ((clock()) - profile_old[prof_buf_id])
#define PROF_CLOCKOUT(prof_buf_id) \
AKLOGI("%s : clock is %f", __FUNCTION__, (clock() - profile_old[prof_buf_id]))
-#define PROF_OUTALL do { AKLOGI("--- %s ---", __FUNCTION__); prof_out(); } while(0)
+#define PROF_OUTALL do { AKLOGI("--- %s ---", __FUNCTION__); prof_out(); } while (0)
static inline void prof_reset(void) {
for (int i = 0; i < PROF_BUF_SIZE; ++i) {
@@ -236,15 +240,15 @@ static inline void prof_out(void) {
#define FLAG_BIGRAM_FREQ 0x7F
#define DICTIONARY_VERSION_MIN 200
-#define NOT_VALID_WORD -99
-#define NOT_A_CHARACTER -1
-#define NOT_A_DISTANCE -1
-#define NOT_A_COORDINATE -1
-#define EQUIVALENT_CHAR_WITHOUT_DISTANCE_INFO -2
-#define PROXIMITY_CHAR_WITHOUT_DISTANCE_INFO -3
-#define ADDITIONAL_PROXIMITY_CHAR_DISTANCE_INFO -4
-#define NOT_AN_INDEX -1
-#define NOT_A_PROBABILITY -1
+#define NOT_VALID_WORD (-99)
+#define NOT_A_CODE_POINT (-1)
+#define NOT_A_DISTANCE (-1)
+#define NOT_A_COORDINATE (-1)
+#define EQUIVALENT_CHAR_WITHOUT_DISTANCE_INFO (-2)
+#define PROXIMITY_CHAR_WITHOUT_DISTANCE_INFO (-3)
+#define ADDITIONAL_PROXIMITY_CHAR_DISTANCE_INFO (-4)
+#define NOT_AN_INDEX (-1)
+#define NOT_A_PROBABILITY (-1)
#define KEYCODE_SPACE ' '
@@ -323,6 +327,9 @@ static inline void prof_out(void) {
// Max Distance between point to key
#define MAX_POINT_TO_KEY_LENGTH 10000000
+// The max number of the keys in one keyboard layout
+#define MAX_KEY_COUNT_IN_A_KEYBOARD 64
+
// TODO: Reduce this constant if possible; check the maximum number of digraphs in the same
// word in the dictionary for languages with digraphs, like German and French
#define DEFAULT_MAX_DIGRAPH_SEARCH_DEPTH 5
@@ -355,8 +362,8 @@ template<typename T> inline T max(T a, T b) { return a > b ? a : b; }
#define NEUTRAL_AREA_RADIUS_RATIO 1.3f
// DEBUG
-#define INPUTLENGTH_FOR_DEBUG -1
-#define MIN_OUTPUT_INDEX_FOR_DEBUG -1
+#define INPUTLENGTH_FOR_DEBUG (-1)
+#define MIN_OUTPUT_INDEX_FOR_DEBUG (-1)
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName&); \
diff --git a/native/jni/src/dictionary.h b/native/jni/src/dictionary.h
index e9a03ce55..a1358890d 100644
--- a/native/jni/src/dictionary.h
+++ b/native/jni/src/dictionary.h
@@ -90,11 +90,12 @@ class Dictionary {
// static inline methods should be defined in the header file
inline int Dictionary::wideStrLen(unsigned short *str) {
if (!str) return 0;
- unsigned short *end = str;
- while (*end) {
- end++;
+ int length = 0;
+ while (*str) {
+ str++;
+ length++;
}
- return end - str;
+ return length;
}
} // namespace latinime
#endif // LATINIME_DICTIONARY_H
diff --git a/native/jni/src/proximity_info.cpp b/native/jni/src/proximity_info.cpp
index 765632e46..a8c04300f 100644
--- a/native/jni/src/proximity_info.cpp
+++ b/native/jni/src/proximity_info.cpp
@@ -29,7 +29,6 @@
namespace latinime {
-/* static */ const int ProximityInfo::NOT_A_CODE = -1;
/* static */ const float ProximityInfo::NOT_A_DISTANCE_FLOAT = -1.0f;
static inline void safeGetOrFillZeroIntArrayRegion(JNIEnv *env, jintArray jArray, jsize len,
@@ -63,6 +62,7 @@ ProximityInfo::ProximityInfo(JNIEnv *env, const jstring localeJStr, const int ma
CELL_WIDTH((keyboardWidth + gridWidth - 1) / gridWidth),
CELL_HEIGHT((keyboardHeight + gridHeight - 1) / gridHeight),
KEY_COUNT(min(keyCount, MAX_KEY_COUNT_IN_A_KEYBOARD)),
+ KEYBOARD_WIDTH(keyboardWidth), KEYBOARD_HEIGHT(keyboardHeight),
HAS_TOUCH_POSITION_CORRECTION_DATA(keyCount > 0 && keyXCoordinates && keyYCoordinates
&& keyWidths && keyHeights && keyCharCodes && sweetSpotCenterXs
&& sweetSpotCenterYs && sweetSpotRadii),
@@ -84,22 +84,22 @@ ProximityInfo::ProximityInfo(JNIEnv *env, const jstring localeJStr, const int ma
safeGetOrFillZeroIntArrayRegion(env, keyYCoordinates, KEY_COUNT, mKeyYCoordinates);
safeGetOrFillZeroIntArrayRegion(env, keyWidths, KEY_COUNT, mKeyWidths);
safeGetOrFillZeroIntArrayRegion(env, keyHeights, KEY_COUNT, mKeyHeights);
- safeGetOrFillZeroIntArrayRegion(env, keyCharCodes, KEY_COUNT, mKeyCharCodes);
+ safeGetOrFillZeroIntArrayRegion(env, keyCharCodes, KEY_COUNT, mKeyCodePoints);
safeGetOrFillZeroFloatArrayRegion(env, sweetSpotCenterXs, KEY_COUNT, mSweetSpotCenterXs);
safeGetOrFillZeroFloatArrayRegion(env, sweetSpotCenterYs, KEY_COUNT, mSweetSpotCenterYs);
safeGetOrFillZeroFloatArrayRegion(env, sweetSpotRadii, KEY_COUNT, mSweetSpotRadii);
- initializeCodeToKeyIndex();
+ initializeCodePointToKeyIndex();
initializeG();
}
// Build the reversed look up table from the char code to the index in mKeyXCoordinates,
// mKeyYCoordinates, mKeyWidths, mKeyHeights, mKeyCharCodes.
-void ProximityInfo::initializeCodeToKeyIndex() {
- memset(mCodeToKeyIndex, -1, (MAX_CHAR_CODE + 1) * sizeof(mCodeToKeyIndex[0]));
+void ProximityInfo::initializeCodePointToKeyIndex() {
+ memset(mCodePointToKeyIndex, -1, sizeof(mCodePointToKeyIndex));
for (int i = 0; i < KEY_COUNT; ++i) {
- const int code = mKeyCharCodes[i];
+ const int code = mKeyCodePoints[i];
if (0 <= code && code <= MAX_CHAR_CODE) {
- mCodeToKeyIndex[code] = i;
+ mCodePointToKeyIndex[code] = i;
}
}
}
@@ -117,7 +117,8 @@ bool ProximityInfo::hasSpaceProximity(const int x, const int y) const {
if (x < 0 || y < 0) {
if (DEBUG_DICT) {
AKLOGI("HasSpaceProximity: Illegal coordinates (%d, %d)", x, y);
- assert(false);
+ // TODO: Enable this assertion.
+ //assert(false);
}
return false;
}
@@ -145,8 +146,8 @@ static inline float getNormalizedSquaredDistanceFloat(float x1, float y1, float
float ProximityInfo::getNormalizedSquaredDistanceFromCenterFloat(
const int keyId, const int x, const int y) const {
- const float centerX = static_cast<float>(getKeyCenterXOfIdG(keyId));
- const float centerY = static_cast<float>(getKeyCenterYOfIdG(keyId));
+ const float centerX = static_cast<float>(getKeyCenterXOfKeyIdG(keyId));
+ const float centerY = static_cast<float>(getKeyCenterYOfKeyIdG(keyId));
const float touchX = static_cast<float>(x);
const float touchY = static_cast<float>(y);
const float keyWidth = static_cast<float>(getMostCommonKeyWidth());
@@ -178,7 +179,7 @@ void ProximityInfo::calculateNearbyKeyCodes(
if (c < KEYCODE_SPACE || c == primaryKey) {
continue;
}
- const int keyIndex = getKeyIndex(c);
+ const int keyIndex = getKeyIndexOf(c);
const bool onKey = isOnKey(keyIndex, x, y);
const int distance = squaredDistanceToEdge(keyIndex, x, y);
if (onKey || distance < MOST_COMMON_KEY_WIDTH_SQUARE) {
@@ -208,7 +209,7 @@ void ProximityInfo::calculateNearbyKeyCodes(
const int32_t ac = additionalProximityChars[j];
int k = 0;
for (; k < insertPos; ++k) {
- if ((int)ac == inputCodes[k]) {
+ if (static_cast<int>(ac) == inputCodes[k]) {
break;
}
}
@@ -227,11 +228,11 @@ void ProximityInfo::calculateNearbyKeyCodes(
}
// Add a delimiter for the proximity characters
for (int i = insertPos; i < MAX_PROXIMITY_CHARS_SIZE; ++i) {
- inputCodes[i] = NOT_A_CODE;
+ inputCodes[i] = NOT_A_CODE_POINT;
}
}
-int ProximityInfo::getKeyIndex(const int c) const {
+int ProximityInfo::getKeyIndexOf(const int c) const {
if (KEY_COUNT == 0) {
// We do not have the coordinate data
return NOT_AN_INDEX;
@@ -240,28 +241,28 @@ int ProximityInfo::getKeyIndex(const int c) const {
if (baseLowerC > MAX_CHAR_CODE) {
return NOT_AN_INDEX;
}
- return mCodeToKeyIndex[baseLowerC];
+ return mCodePointToKeyIndex[baseLowerC];
}
-int ProximityInfo::getKeyCode(const int keyIndex) const {
+int ProximityInfo::getCodePointOf(const int keyIndex) const {
if (keyIndex < 0 || keyIndex >= KEY_COUNT) {
- return NOT_AN_INDEX;
+ return NOT_A_CODE_POINT;
}
- return mKeyToCodeIndexG[keyIndex];
+ return mKeyIndexToCodePointG[keyIndex];
}
void ProximityInfo::initializeG() {
// TODO: Optimize
for (int i = 0; i < KEY_COUNT; ++i) {
- const int code = mKeyCharCodes[i];
+ const int code = mKeyCodePoints[i];
const int lowerCode = toBaseLowerCase(code);
mCenterXsG[i] = mKeyXCoordinates[i] + mKeyWidths[i] / 2;
mCenterYsG[i] = mKeyYCoordinates[i] + mKeyHeights[i] / 2;
if (code != lowerCode && lowerCode >= 0 && lowerCode <= MAX_CHAR_CODE) {
- mCodeToKeyIndex[lowerCode] = i;
- mKeyToCodeIndexG[i] = lowerCode;
+ mCodePointToKeyIndex[lowerCode] = i;
+ mKeyIndexToCodePointG[i] = lowerCode;
} else {
- mKeyToCodeIndexG[i] = code;
+ mKeyIndexToCodePointG[i] = code;
}
}
for (int i = 0; i < KEY_COUNT; i++) {
@@ -274,22 +275,22 @@ void ProximityInfo::initializeG() {
}
}
-float ProximityInfo::getKeyCenterXOfCharG(int charCode) const {
- return getKeyCenterXOfIdG(getKeyIndex(charCode));
+float ProximityInfo::getKeyCenterXOfCodePointG(int charCode) const {
+ return getKeyCenterXOfKeyIdG(getKeyIndexOf(charCode));
}
-float ProximityInfo::getKeyCenterYOfCharG(int charCode) const {
- return getKeyCenterYOfIdG(getKeyIndex(charCode));
+float ProximityInfo::getKeyCenterYOfCodePointG(int charCode) const {
+ return getKeyCenterYOfKeyIdG(getKeyIndexOf(charCode));
}
-float ProximityInfo::getKeyCenterXOfIdG(int keyId) const {
+float ProximityInfo::getKeyCenterXOfKeyIdG(int keyId) const {
if (keyId >= 0) {
return mCenterXsG[keyId];
}
return 0;
}
-float ProximityInfo::getKeyCenterYOfIdG(int keyId) const {
+float ProximityInfo::getKeyCenterYOfKeyIdG(int keyId) const {
if (keyId >= 0) {
return mCenterYsG[keyId];
}
@@ -297,8 +298,8 @@ float ProximityInfo::getKeyCenterYOfIdG(int keyId) const {
}
int ProximityInfo::getKeyKeyDistanceG(int key0, int key1) const {
- const int keyId0 = getKeyIndex(key0);
- const int keyId1 = getKeyIndex(key1);
+ const int keyId0 = getKeyIndexOf(key0);
+ const int keyId1 = getKeyIndexOf(key1);
if (keyId0 >= 0 && keyId1 >= 0) {
return mKeyKeyDistancesG[keyId0][keyId1];
}
diff --git a/native/jni/src/proximity_info.h b/native/jni/src/proximity_info.h
index 822909b7a..7c22e108b 100644
--- a/native/jni/src/proximity_info.h
+++ b/native/jni/src/proximity_info.h
@@ -41,8 +41,8 @@ class ProximityInfo {
float getNormalizedSquaredDistanceFromCenterFloat(
const int keyId, const int x, const int y) const;
bool sameAsTyped(const unsigned short *word, int length) const;
- int getKeyIndex(const int c) const;
- int getKeyCode(const int keyIndex) const;
+ int getKeyIndexOf(const int c) const;
+ int getCodePointOf(const int keyIndex) const;
bool hasSweetSpotData(const int keyIndex) const {
// When there are no calibration data for a key,
// the radius of the key is assigned to zero.
@@ -96,23 +96,29 @@ class ProximityInfo {
return GRID_HEIGHT;
}
- float getKeyCenterXOfCharG(int charCode) const;
- float getKeyCenterYOfCharG(int charCode) const;
- float getKeyCenterXOfIdG(int keyId) const;
- float getKeyCenterYOfIdG(int keyId) const;
+ int getKeyboardWidth() const {
+ return KEYBOARD_WIDTH;
+ }
+
+ int getKeyboardHeight() const {
+ return KEYBOARD_HEIGHT;
+ }
+
+ // TODO: These should return int.
+ float getKeyCenterXOfCodePointG(int charCode) const;
+ float getKeyCenterYOfCodePointG(int charCode) const;
+ float getKeyCenterXOfKeyIdG(int keyId) const;
+ float getKeyCenterYOfKeyIdG(int keyId) const;
int getKeyKeyDistanceG(int key0, int key1) const;
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(ProximityInfo);
- // The max number of the keys in one keyboard layout
- static const int MAX_KEY_COUNT_IN_A_KEYBOARD = 64;
- // The upper limit of the char code in mCodeToKeyIndex
+ // The upper limit of the char code in mCodePointToKeyIndex
static const int MAX_CHAR_CODE = 127;
- static const int NOT_A_CODE;
static const float NOT_A_DISTANCE_FLOAT;
int getStartIndexFromCoordinates(const int x, const int y) const;
- void initializeCodeToKeyIndex();
+ void initializeCodePointToKeyIndex();
void initializeG();
float calculateNormalizedSquaredDistance(const int keyIndex, const int inputIndex) const;
float calculateSquaredDistanceFromSweetSpotCenter(
@@ -136,6 +142,8 @@ class ProximityInfo {
const int CELL_WIDTH;
const int CELL_HEIGHT;
const int KEY_COUNT;
+ const int KEYBOARD_WIDTH;
+ const int KEYBOARD_HEIGHT;
const bool HAS_TOUCH_POSITION_CORRECTION_DATA;
char mLocaleStr[MAX_LOCALE_STRING_LENGTH];
int32_t *mProximityCharsArray;
@@ -143,13 +151,13 @@ class ProximityInfo {
int32_t mKeyYCoordinates[MAX_KEY_COUNT_IN_A_KEYBOARD];
int32_t mKeyWidths[MAX_KEY_COUNT_IN_A_KEYBOARD];
int32_t mKeyHeights[MAX_KEY_COUNT_IN_A_KEYBOARD];
- int32_t mKeyCharCodes[MAX_KEY_COUNT_IN_A_KEYBOARD];
+ int32_t mKeyCodePoints[MAX_KEY_COUNT_IN_A_KEYBOARD];
float mSweetSpotCenterXs[MAX_KEY_COUNT_IN_A_KEYBOARD];
float mSweetSpotCenterYs[MAX_KEY_COUNT_IN_A_KEYBOARD];
float mSweetSpotRadii[MAX_KEY_COUNT_IN_A_KEYBOARD];
- int mCodeToKeyIndex[MAX_CHAR_CODE + 1];
+ int mCodePointToKeyIndex[MAX_CHAR_CODE + 1];
- int mKeyToCodeIndexG[MAX_KEY_COUNT_IN_A_KEYBOARD];
+ int mKeyIndexToCodePointG[MAX_KEY_COUNT_IN_A_KEYBOARD];
int mCenterXsG[MAX_KEY_COUNT_IN_A_KEYBOARD];
int mCenterYsG[MAX_KEY_COUNT_IN_A_KEYBOARD];
int mKeyKeyDistancesG[MAX_KEY_COUNT_IN_A_KEYBOARD][MAX_KEY_COUNT_IN_A_KEYBOARD];
diff --git a/native/jni/src/proximity_info_state.cpp b/native/jni/src/proximity_info_state.cpp
index e13d4e664..c9a1ed0c0 100644
--- a/native/jni/src/proximity_info_state.cpp
+++ b/native/jni/src/proximity_info_state.cpp
@@ -76,6 +76,7 @@ void ProximityInfoState::initInputParams(const int pointerId, const float maxPoi
mTimes.clear();
mLengthCache.clear();
mDistanceCache.clear();
+ mNearKeysVector.clear();
mInputSize = 0;
if (xCoordinates && yCoordinates) {
@@ -122,14 +123,34 @@ void ProximityInfoState::initInputParams(const int pointerId, const float maxPoi
if (mInputSize > 0) {
const int keyCount = mProximityInfo->getKeyCount();
+ mNearKeysVector.resize(mInputSize);
mDistanceCache.resize(mInputSize * keyCount);
for (int i = 0; i < mInputSize; ++i) {
+ mNearKeysVector[i].reset();
+ static const float NEAR_KEY_NORMALIZED_SQUARED_THRESHOLD = 4.0f;
for (int k = 0; k < keyCount; ++k) {
const int index = i * keyCount + k;
const int x = mInputXs[i];
const int y = mInputYs[i];
- mDistanceCache[index] =
+ const float normalizedSquaredDistance =
mProximityInfo->getNormalizedSquaredDistanceFromCenterFloat(k, x, y);
+ mDistanceCache[index] = normalizedSquaredDistance;
+ if (normalizedSquaredDistance < NEAR_KEY_NORMALIZED_SQUARED_THRESHOLD) {
+ mNearKeysVector[i].set(k, 1);
+ }
+ }
+ }
+
+ static const float READ_FORWORD_LENGTH_SCALE = 0.95f;
+ const int readForwordLength = static_cast<int>(
+ hypotf(mProximityInfo->getKeyboardWidth(), mProximityInfo->getKeyboardHeight())
+ * READ_FORWORD_LENGTH_SCALE);
+ for (int i = 0; i < mInputSize; ++i) {
+ for (int j = i + 1; j < mInputSize; ++j) {
+ if (mLengthCache[j] - mLengthCache[i] >= readForwordLength) {
+ break;
+ }
+ mNearKeysVector[i] |= mNearKeysVector[j];
}
}
}
@@ -160,7 +181,7 @@ void ProximityInfoState::initInputParams(const int pointerId, const float maxPoi
const int currentChar = proximityChars[j];
const float squaredDistance =
hasInputCoordinates() ? calculateNormalizedSquaredDistance(
- mProximityInfo->getKeyIndex(currentChar), i) :
+ mProximityInfo->getKeyIndexOf(currentChar), i) :
NOT_A_DISTANCE_FLOAT;
if (squaredDistance >= 0.0f) {
mNormalizedSquaredDistances[i * MAX_PROXIMITY_CHARS_SIZE_INTERNAL + j] =
@@ -182,7 +203,7 @@ void ProximityInfoState::initInputParams(const int pointerId, const float maxPoi
// the given point and the nearest key position.
float ProximityInfoState::updateNearKeysDistances(const int x, const int y,
NearKeysDistanceMap *const currentNearKeysDistances) {
- static const float NEAR_KEY_THRESHOLD = 10.0f;
+ static const float NEAR_KEY_THRESHOLD = 4.0f;
currentNearKeysDistances->clear();
const int keyCount = mProximityInfo->getKeyCount();
@@ -282,7 +303,7 @@ bool ProximityInfoState::pushTouchPoint(const int nodeChar, int x, int y, const
const NearKeysDistanceMap *const prevPrevNearKeysDistances) {
static const float LAST_POINT_SKIP_DISTANCE_SCALE = 0.25f;
- uint32_t size = mInputXs.size();
+ size_t size = mInputXs.size();
bool popped = false;
if (nodeChar < 0 && sample) {
const float nearest = updateNearKeysDistances(x, y, currentNearKeysDistances);
@@ -309,7 +330,7 @@ bool ProximityInfoState::pushTouchPoint(const int nodeChar, int x, int y, const
float minDist = mMaxPointToKeyLength;
for (NearKeysDistanceMap::const_iterator it = currentNearKeysDistances->begin();
it != currentNearKeysDistances->end(); ++it) {
- if(minDist > it->second){
+ if (minDist > it->second) {
minChar = it->first;
minDist = it->second;
}
@@ -324,10 +345,10 @@ bool ProximityInfoState::pushTouchPoint(const int nodeChar, int x, int y, const
}
if (nodeChar >= 0 && (x < 0 || y < 0)) {
- const int keyId = mProximityInfo->getKeyIndex(nodeChar);
+ const int keyId = mProximityInfo->getKeyIndexOf(nodeChar);
if (keyId >= 0) {
- x = mProximityInfo->getKeyCenterXOfIdG(keyId);
- y = mProximityInfo->getKeyCenterYOfIdG(keyId);
+ x = mProximityInfo->getKeyCenterXOfKeyIdG(keyId);
+ y = mProximityInfo->getKeyCenterYOfKeyIdG(keyId);
}
}
@@ -368,8 +389,8 @@ int ProximityInfoState::getDuration(const int index) const {
return 0;
}
-float ProximityInfoState::getPointToKeyLength(int inputIndex, int charCode, float scale) {
- const int keyId = mProximityInfo->getKeyIndex(charCode);
+float ProximityInfoState::getPointToKeyLength(int inputIndex, int codePoint, float scale) {
+ const int keyId = mProximityInfo->getKeyIndexOf(codePoint);
if (keyId >= 0) {
const int index = inputIndex * mProximityInfo->getKeyCount() + keyId;
return min(mDistanceCache[index] * scale, mMaxPointToKeyLength);
@@ -382,8 +403,8 @@ int ProximityInfoState::getKeyKeyDistance(int key0, int key1) {
}
int ProximityInfoState::getSpaceY() {
- const int keyId = mProximityInfo->getKeyIndex(' ');
- return mProximityInfo->getKeyCenterYOfIdG(keyId);
+ const int keyId = mProximityInfo->getKeyIndexOf(' ');
+ return mProximityInfo->getKeyCenterYOfKeyIdG(keyId);
}
float ProximityInfoState::calculateSquaredDistanceFromSweetSpotCenter(
@@ -394,4 +415,30 @@ float ProximityInfoState::calculateSquaredDistanceFromSweetSpotCenter(
const float inputY = static_cast<float>(mInputYs[inputIndex]);
return square(inputX - sweetSpotCenterX) + square(inputY - sweetSpotCenterY);
}
+
+// Puts possible characters into filter and returns new filter size.
+int32_t ProximityInfoState::getAllPossibleChars(
+ const size_t index, int32_t *const filter, const int32_t filterSize) const {
+ if (index >= mInputXs.size()) {
+ return filterSize;
+ }
+ int i = filterSize;
+ for (int j = 0; j < mProximityInfo->getKeyCount(); ++j) {
+ if (mNearKeysVector[index].test(j)) {
+ const int32_t keyCodePoint = mProximityInfo->getCodePointOf(j);
+ bool insert = true;
+ // TODO: Avoid linear search
+ for (int k = 0; k < filterSize; ++k) {
+ if (filter[k] == keyCodePoint) {
+ insert = false;
+ break;
+ }
+ }
+ if (insert) {
+ filter[i++] = keyCodePoint;
+ }
+ }
+ }
+ return i;
+}
} // namespace latinime
diff --git a/native/jni/src/proximity_info_state.h b/native/jni/src/proximity_info_state.h
index 746b9c968..80b84e962 100644
--- a/native/jni/src/proximity_info_state.h
+++ b/native/jni/src/proximity_info_state.h
@@ -17,6 +17,7 @@
#ifndef LATINIME_PROXIMITY_INFO_STATE_H
#define LATINIME_PROXIMITY_INFO_STATE_H
+#include <bitset>
#include <cstring> // for memset()
#include <stdint.h>
#include <string>
@@ -32,6 +33,7 @@ class ProximityInfo;
class ProximityInfoState {
public:
+ typedef std::bitset<MAX_KEY_COUNT_IN_A_KEYBOARD> NearKeycodesSet;
static const int NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR_LOG_2 = 10;
static const int NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR =
1 << NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR_LOG_2;
@@ -56,7 +58,8 @@ class ProximityInfoState {
mHasTouchPositionCorrectionData(false), mMostCommonKeyWidthSquare(0), mLocaleStr(),
mKeyCount(0), mCellHeight(0), mCellWidth(0), mGridHeight(0), mGridWidth(0),
mInputXs(), mInputYs(), mTimes(), mDistanceCache(), mLengthCache(),
- mTouchPositionCorrectionEnabled(false), mInputSize(0) {
+ mNearKeysVector(), mTouchPositionCorrectionEnabled(false),
+ mInputSize(0) {
memset(mInputCodes, 0, sizeof(mInputCodes));
memset(mNormalizedSquaredDistances, 0, sizeof(mNormalizedSquaredDistances));
memset(mPrimaryInputWord, 0, sizeof(mPrimaryInputWord));
@@ -215,6 +218,9 @@ class ProximityInfoState {
int getSpaceY();
+ int32_t getAllPossibleChars(
+ const size_t startIndex, int32_t *const filter, int32_t filterSize) const;
+
private:
DISALLOW_COPY_AND_ASSIGN(ProximityInfoState);
typedef hash_map_compat<int, float> NearKeysDistanceMap;
@@ -272,6 +278,7 @@ class ProximityInfoState {
std::vector<int> mTimes;
std::vector<float> mDistanceCache;
std::vector<int> mLengthCache;
+ std::vector<NearKeycodesSet> mNearKeysVector;
bool mTouchPositionCorrectionEnabled;
int32_t mInputCodes[MAX_PROXIMITY_CHARS_SIZE_INTERNAL * MAX_WORD_LENGTH_INTERNAL];
int mNormalizedSquaredDistances[MAX_PROXIMITY_CHARS_SIZE_INTERNAL * MAX_WORD_LENGTH_INTERNAL];
diff --git a/native/jni/src/terminal_attributes.h b/native/jni/src/terminal_attributes.h
index 9ff2772b1..53ae385ea 100644
--- a/native/jni/src/terminal_attributes.h
+++ b/native/jni/src/terminal_attributes.h
@@ -52,9 +52,9 @@ class TerminalAttributes {
0 != (shortcutFlags & BinaryFormat::FLAG_ATTRIBUTE_HAS_NEXT);
unsigned int i;
for (i = 0; i < MAX_WORD_LENGTH_INTERNAL; ++i) {
- const int charCode = BinaryFormat::getCharCodeAndForwardPointer(mDict, &mPos);
- if (NOT_A_CHARACTER == charCode) break;
- outWord[i] = (uint16_t)charCode;
+ const int codePoint = BinaryFormat::getCodePointAndForwardPointer(mDict, &mPos);
+ if (NOT_A_CODE_POINT == codePoint) break;
+ outWord[i] = (uint16_t)codePoint;
}
*outFreq = BinaryFormat::getAttributeFrequencyFromFlags(shortcutFlags);
mPos += BinaryFormat::CHARACTER_ARRAY_TERMINATOR_SIZE;
@@ -62,8 +62,8 @@ class TerminalAttributes {
}
};
- TerminalAttributes(const uint8_t *const dict, const uint8_t flags, const int pos) :
- mDict(dict), mFlags(flags), mStartPos(pos) {
+ TerminalAttributes(const uint8_t *const dict, const uint8_t flags, const int pos)
+ : mDict(dict), mFlags(flags), mStartPos(pos) {
}
inline ShortcutIterator getShortcutIterator() const {
diff --git a/native/jni/src/unigram_dictionary.cpp b/native/jni/src/unigram_dictionary.cpp
index d4c51df63..b7e245a6c 100644
--- a/native/jni/src/unigram_dictionary.cpp
+++ b/native/jni/src/unigram_dictionary.cpp
@@ -58,12 +58,12 @@ UnigramDictionary::~UnigramDictionary() {
}
static inline unsigned int getCodesBufferSize(const int *codes, const int codesSize) {
- return sizeof(*codes) * codesSize;
+ return static_cast<unsigned int>(sizeof(*codes)) * codesSize;
}
// TODO: This needs to take a const unsigned short* and not tinker with its contents
-static inline void addWord(
- unsigned short *word, int length, int frequency, WordsPriorityQueue *queue, int type) {
+static inline void addWord(unsigned short *word, int length, int frequency,
+ WordsPriorityQueue *queue, int type) {
queue->push(frequency, word, length, type);
}
@@ -106,7 +106,7 @@ void UnigramDictionary::getWordWithDigraphSuggestionsRec(ProximityInfo *proximit
WordsPriorityQueuePool *queuePool,
const digraph_t *const digraphs, const unsigned int digraphsSize) const {
- const int startIndex = codesDest - codesBuffer;
+ const int startIndex = static_cast<int>(codesDest - codesBuffer);
if (currentDepth < MAX_DIGRAPH_SEARCH_DEPTH) {
for (int i = 0; i < codesRemain; ++i) {
xCoordinatesBuffer[startIndex + i] = xcoordinates[codesBufferSize - codesRemain + i];
@@ -170,8 +170,7 @@ void UnigramDictionary::getWordWithDigraphSuggestionsRec(ProximityInfo *proximit
// bigramMap contains the association <bigram address> -> <bigram frequency>
// bigramFilter is a bloom filter for fast rejection: see functions setInFilter and isInFilter
// in bigram_dictionary.cpp
-int UnigramDictionary::getSuggestions(ProximityInfo *proximityInfo,
- const int *xcoordinates,
+int UnigramDictionary::getSuggestions(ProximityInfo *proximityInfo, const int *xcoordinates,
const int *ycoordinates, const int *codes, const int codesSize,
const std::map<int, int> *bigramMap, const uint8_t *bigramFilter,
const bool useFullEditDistance, unsigned short *outWords, int *frequencies,
@@ -597,11 +596,10 @@ int UnigramDictionary::getSubStringSuggestion(
void UnigramDictionary::getMultiWordsSuggestionRec(ProximityInfo *proximityInfo,
const int *xcoordinates, const int *ycoordinates, const int *codes,
- const bool useFullEditDistance, const int inputSize,
- Correction *correction, WordsPriorityQueuePool *queuePool,
- const bool hasAutoCorrectionCandidate, const int startInputPos, const int startWordIndex,
- const int outputWordLength, int *freqArray, int *wordLengthArray,
- unsigned short *outputWord) const {
+ const bool useFullEditDistance, const int inputSize, Correction *correction,
+ WordsPriorityQueuePool *queuePool, const bool hasAutoCorrectionCandidate,
+ const int startInputPos, const int startWordIndex, const int outputWordLength,
+ int *freqArray, int *wordLengthArray, unsigned short *outputWord) const {
if (startWordIndex >= (MULTIPLE_WORDS_SUGGESTION_MAX_WORDS - 1)) {
// Return if the last word index
return;
@@ -641,7 +639,7 @@ void UnigramDictionary::getMultiWordsSuggestionRec(ProximityInfo *proximityInfo,
// Missing space
inputWordStartPos = i;
inputWordLength = inputSize - i;
- if(getSubStringSuggestion(proximityInfo, xcoordinates, ycoordinates, codes,
+ if (getSubStringSuggestion(proximityInfo, xcoordinates, ycoordinates, codes,
useFullEditDistance, correction, queuePool, inputSize, hasAutoCorrectionCandidate,
startWordIndex + 1, inputWordStartPos, inputWordLength, tempOutputWordLength,
false /* missing space */, freqArray, wordLengthArray, outputWord, 0)
@@ -724,13 +722,13 @@ inline int UnigramDictionary::getMostFrequentWordLike(const int startInputIndex,
// In and out parameters may point to the same location. This function takes care
// not to use any input parameters after it wrote into its outputs.
static inline bool testCharGroupForContinuedLikeness(const uint8_t flags,
- const uint8_t *const root, const int startPos,
- const uint16_t *const inWord, const int startInputIndex,
- int32_t *outNewWord, int *outInputIndex, int *outPos) {
+ const uint8_t *const root, const int startPos, const uint16_t *const inWord,
+ const int startInputIndex, const int inputSize, int32_t *outNewWord, int *outInputIndex,
+ int *outPos) {
const bool hasMultipleChars = (0 != (BinaryFormat::FLAG_HAS_MULTIPLE_CHARS & flags));
int pos = startPos;
- int32_t character = BinaryFormat::getCharCodeAndForwardPointer(root, &pos);
- int32_t baseChar = toBaseLowerCase(character);
+ int32_t codePoint = BinaryFormat::getCodePointAndForwardPointer(root, &pos);
+ int32_t baseChar = toBaseLowerCase(codePoint);
const uint16_t wChar = toBaseLowerCase(inWord[startInputIndex]);
if (baseChar != wChar) {
@@ -739,18 +737,18 @@ static inline bool testCharGroupForContinuedLikeness(const uint8_t flags,
return false;
}
int inputIndex = startInputIndex;
- outNewWord[inputIndex] = character;
+ outNewWord[inputIndex] = codePoint;
if (hasMultipleChars) {
- character = BinaryFormat::getCharCodeAndForwardPointer(root, &pos);
- while (NOT_A_CHARACTER != character) {
- baseChar = toBaseLowerCase(character);
- if (toBaseLowerCase(inWord[++inputIndex]) != baseChar) {
+ codePoint = BinaryFormat::getCodePointAndForwardPointer(root, &pos);
+ while (NOT_A_CODE_POINT != codePoint) {
+ baseChar = toBaseLowerCase(codePoint);
+ if (inputIndex + 1 >= inputSize || toBaseLowerCase(inWord[++inputIndex]) != baseChar) {
*outPos = BinaryFormat::skipOtherCharacters(root, pos);
*outInputIndex = startInputIndex;
return false;
}
- outNewWord[inputIndex] = character;
- character = BinaryFormat::getCharCodeAndForwardPointer(root, &pos);
+ outNewWord[inputIndex] = codePoint;
+ codePoint = BinaryFormat::getCodePointAndForwardPointer(root, &pos);
}
}
*outInputIndex = inputIndex + 1;
@@ -765,8 +763,9 @@ static inline bool testCharGroupForContinuedLikeness(const uint8_t flags,
static inline void onTerminalWordLike(const int freq, int32_t *newWord, const int length,
short unsigned int *outWord, int *maxFreq) {
if (freq > *maxFreq) {
- for (int q = 0; q < length; ++q)
+ for (int q = 0; q < length; ++q) {
outWord[q] = newWord[q];
+ }
outWord[length] = 0;
*maxFreq = freq;
}
@@ -775,7 +774,7 @@ static inline void onTerminalWordLike(const int freq, int32_t *newWord, const in
// Will find the highest frequency of the words like the one passed as an argument,
// that is, everything that only differs by case/accents.
int UnigramDictionary::getMostFrequentWordLikeInner(const uint16_t *const inWord,
- const int length, short unsigned int *outWord) const {
+ const int inputSize, short unsigned int *outWord) const {
int32_t newWord[MAX_WORD_LENGTH_INTERNAL];
int depth = 0;
int maxFreq = -1;
@@ -795,12 +794,12 @@ int UnigramDictionary::getMostFrequentWordLikeInner(const uint16_t *const inWord
int inputIndex = stackInputIndex[depth];
const uint8_t flags = BinaryFormat::getFlagsAndForwardPointer(root, &pos);
// Test whether all chars in this group match with the word we are searching for. If so,
- // we want to traverse its children (or if the length match, evaluate its frequency).
+ // we want to traverse its children (or if the inputSize match, evaluate its frequency).
// Note that this function will output the position regardless, but will only write
// into inputIndex if there is a match.
const bool isAlike = testCharGroupForContinuedLikeness(flags, root, pos, inWord,
- inputIndex, newWord, &inputIndex, &pos);
- if (isAlike && (BinaryFormat::FLAG_IS_TERMINAL & flags) && (inputIndex == length)) {
+ inputIndex, inputSize, newWord, &inputIndex, &pos);
+ if (isAlike && (BinaryFormat::FLAG_IS_TERMINAL & flags) && (inputIndex == inputSize)) {
const int frequency = BinaryFormat::readFrequencyWithoutMovingPointer(root, pos);
onTerminalWordLike(frequency, newWord, inputIndex, outWord, &maxFreq);
}
@@ -809,8 +808,8 @@ int UnigramDictionary::getMostFrequentWordLikeInner(const uint16_t *const inWord
const int childrenNodePos = BinaryFormat::readChildrenPosition(root, flags, pos);
// If we had a match and the word has children, we want to traverse them. We don't have
// to traverse words longer than the one we are searching for, since they will not match
- // anyway, so don't traverse unless inputIndex < length.
- if (isAlike && (-1 != childrenNodePos) && (inputIndex < length)) {
+ // anyway, so don't traverse unless inputIndex < inputSize.
+ if (isAlike && (-1 != childrenNodePos) && (inputIndex < inputSize)) {
// Save position for this depth, to get back to this once children are done
stackChildCount[depth] = charGroupIndex;
stackSiblingPos[depth] = siblingPos;
@@ -853,7 +852,7 @@ int UnigramDictionary::getFrequency(const int32_t *const inWord, const int lengt
if (hasMultipleChars) {
pos = BinaryFormat::skipOtherCharacters(root, pos);
} else {
- BinaryFormat::getCharCodeAndForwardPointer(DICT_ROOT, &pos);
+ BinaryFormat::getCodePointAndForwardPointer(DICT_ROOT, &pos);
}
const int unigramFreq = BinaryFormat::readFrequencyWithoutMovingPointer(root, pos);
return unigramFreq;
@@ -907,23 +906,23 @@ inline bool UnigramDictionary::processCurrentNode(const int initialPos,
// else if FLAG_IS_TERMINAL: the frequency
// else if MASK_GROUP_ADDRESS_TYPE is not NONE: the children address
// Note that you can't have a node that both is not a terminal and has no children.
- int32_t c = BinaryFormat::getCharCodeAndForwardPointer(DICT_ROOT, &pos);
- assert(NOT_A_CHARACTER != c);
+ int32_t c = BinaryFormat::getCodePointAndForwardPointer(DICT_ROOT, &pos);
+ assert(NOT_A_CODE_POINT != c);
// We are going to loop through each character and make it look like it's a different
// node each time. To do that, we will process characters in this node in order until
- // we find the character terminator. This is signalled by getCharCode* returning
- // NOT_A_CHARACTER.
+ // we find the character terminator. This is signalled by getCodePoint* returning
+ // NOT_A_CODE_POINT.
// As a special case, if there is only one character in this node, we must not read the
- // next bytes so we will simulate the NOT_A_CHARACTER return by testing the flags.
+ // next bytes so we will simulate the NOT_A_CODE_POINT return by testing the flags.
// This way, each loop run will look like a "virtual node".
do {
// We prefetch the next char. If 'c' is the last char of this node, we will have
- // NOT_A_CHARACTER in the next char. From this we can decide whether this virtual node
+ // NOT_A_CODE_POINT in the next char. From this we can decide whether this virtual node
// should behave as a terminal or not and whether we have children.
const int32_t nextc = hasMultipleChars
- ? BinaryFormat::getCharCodeAndForwardPointer(DICT_ROOT, &pos) : NOT_A_CHARACTER;
- const bool isLastChar = (NOT_A_CHARACTER == nextc);
+ ? BinaryFormat::getCodePointAndForwardPointer(DICT_ROOT, &pos) : NOT_A_CODE_POINT;
+ const bool isLastChar = (NOT_A_CODE_POINT == nextc);
// If there are more chars in this nodes, then this virtual node is not a terminal.
// If we are on the last char, this virtual node is a terminal if this node is.
const bool isTerminal = isLastChar && isTerminalNode;
@@ -952,9 +951,9 @@ inline bool UnigramDictionary::processCurrentNode(const int initialPos,
// Prepare for the next character. Promote the prefetched char to current char - the loop
// will take care of prefetching the next. If we finally found our last char, nextc will
- // contain NOT_A_CHARACTER.
+ // contain NOT_A_CODE_POINT.
c = nextc;
- } while (NOT_A_CHARACTER != c);
+ } while (NOT_A_CODE_POINT != c);
if (isTerminalNode) {
// The frequency should be here, because we come here only if this is actually
diff --git a/native/jni/src/unigram_dictionary.h b/native/jni/src/unigram_dictionary.h
index 2c6622210..57129bb07 100644
--- a/native/jni/src/unigram_dictionary.h
+++ b/native/jni/src/unigram_dictionary.h
@@ -43,11 +43,11 @@ class UnigramDictionary {
int fullWordMultiplier, int maxWordLength, int maxWords, const unsigned int flags);
int getFrequency(const int32_t *const inWord, const int length) const;
int getBigramPosition(int pos, unsigned short *word, int offset, int length) const;
- int getSuggestions(
- ProximityInfo *proximityInfo, const int *xcoordinates, const int *ycoordinates,
- const int *codes, const int codesSize, const std::map<int, int> *bigramMap,
- const uint8_t *bigramFilter, const bool useFullEditDistance, unsigned short *outWords,
- int *frequencies, int *outputTypes) const;
+ int getSuggestions(ProximityInfo *proximityInfo, const int *xcoordinates,
+ const int *ycoordinates, const int *codes, const int codesSize,
+ const std::map<int, int> *bigramMap, const uint8_t *bigramFilter,
+ const bool useFullEditDistance, unsigned short *outWords, int *frequencies,
+ int *outputTypes) const;
virtual ~UnigramDictionary();
private:
@@ -94,7 +94,7 @@ class UnigramDictionary {
const int currentWordIndex) const;
int getMostFrequentWordLike(const int startInputIndex, const int inputSize,
Correction *correction, unsigned short *word) const;
- int getMostFrequentWordLikeInner(const uint16_t *const inWord, const int length,
+ int getMostFrequentWordLikeInner(const uint16_t *const inWord, const int inputSize,
short unsigned int *outWord) const;
int getSubStringSuggestion(
ProximityInfo *proximityInfo, const int *xcoordinates, const int *ycoordinates,
diff --git a/native/jni/src/words_priority_queue_pool.h b/native/jni/src/words_priority_queue_pool.h
index c5de9797f..2d52903e0 100644
--- a/native/jni/src/words_priority_queue_pool.h
+++ b/native/jni/src/words_priority_queue_pool.h
@@ -30,7 +30,7 @@ class WordsPriorityQueuePool {
mainQueueMaxWords, maxWordLength)) {
for (int i = 0, subQueueBufOffset = 0;
i < MULTIPLE_WORDS_SUGGESTION_MAX_WORDS * SUB_QUEUE_MAX_COUNT;
- ++i, subQueueBufOffset += sizeof(WordsPriorityQueue)) {
+ ++i, subQueueBufOffset += static_cast<int>(sizeof(WordsPriorityQueue))) {
mSubQueues[i] = new(mSubQueueBuf + subQueueBufOffset)
WordsPriorityQueue(subQueueMaxWords, maxWordLength);
}
diff --git a/tests/src/com/android/inputmethod/latin/InputTestsBase.java b/tests/src/com/android/inputmethod/latin/InputTestsBase.java
index ffd95f57a..fe58cb84e 100644
--- a/tests/src/com/android/inputmethod/latin/InputTestsBase.java
+++ b/tests/src/com/android/inputmethod/latin/InputTestsBase.java
@@ -41,6 +41,7 @@ import com.android.inputmethod.keyboard.Key;
import com.android.inputmethod.keyboard.Keyboard;
import java.util.HashMap;
+import java.util.Locale;
public class InputTestsBase extends ServiceTestCase<LatinIME> {
@@ -51,7 +52,7 @@ public class InputTestsBase extends ServiceTestCase<LatinIME> {
protected LatinIME mLatinIME;
protected Keyboard mKeyboard;
- protected TextView mTextView;
+ protected MyTextView mTextView;
protected InputConnection mInputConnection;
private final HashMap<String, InputMethodSubtype> mSubtypeMap =
new HashMap<String, InputMethodSubtype>();
@@ -86,6 +87,27 @@ public class InputTestsBase extends ServiceTestCase<LatinIME> {
return (mSpan instanceof SuggestionSpan) &&
0 != (SuggestionSpan.FLAG_AUTO_CORRECTION & ((SuggestionSpan)mSpan).getFlags());
}
+ public String[] getSuggestions() {
+ return ((SuggestionSpan)mSpan).getSuggestions();
+ }
+ }
+
+ // A helper class to increase control over the TextView
+ public static class MyTextView extends TextView {
+ public Locale mCurrentLocale;
+ public MyTextView(final Context c) {
+ super(c);
+ }
+ public void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ }
+ public Locale getTextServicesLocale() {
+ // This method is necessary because TextView is asking this method for the language
+ // to check the spell in. If we don't override this, the spell checker will run in
+ // whatever language the keyboard is currently set on the test device, ignoring any
+ // settings we do inside the tests.
+ return mCurrentLocale;
+ }
}
public InputTestsBase() {
@@ -112,7 +134,7 @@ public class InputTestsBase extends ServiceTestCase<LatinIME> {
@Override
protected void setUp() throws Exception {
super.setUp();
- mTextView = new TextView(getContext());
+ mTextView = new MyTextView(getContext());
mTextView.setInputType(InputType.TYPE_CLASS_TEXT);
mTextView.setEnabled(true);
setupService();
@@ -248,6 +270,7 @@ public class InputTestsBase extends ServiceTestCase<LatinIME> {
protected void changeLanguage(final String locale) {
final InputMethodSubtype subtype = mSubtypeMap.get(locale);
+ mTextView.mCurrentLocale = LocaleUtils.constructLocaleFromString(locale);
if (subtype == null) {
fail("InputMethodSubtype for locale " + locale + " is not enabled");
}
diff --git a/tests/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerServiceTest.java b/tests/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerServiceTest.java
new file mode 100644
index 000000000..21406d370
--- /dev/null
+++ b/tests/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerServiceTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2012 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.latin.spellcheck;
+
+import android.text.SpannableStringBuilder;
+import android.text.style.CharacterStyle;
+import android.text.style.SuggestionSpan;
+
+import com.android.inputmethod.latin.InputTestsBase;
+
+public class AndroidSpellCheckerServiceTest extends InputTestsBase {
+ public void testSpellchecker() {
+ mTextView.onAttachedToWindow();
+ mTextView.setText("tgis");
+ type(" ");
+ sleep(1000);
+ runMessages();
+ sleep(1000);
+
+ final SpanGetter span = new SpanGetter(mTextView.getText(), SuggestionSpan.class);
+ // If no span, the following will crash
+ final String[] suggestions = span.getSuggestions();
+ // For this test we consider "tgis" should yield at least 2 suggestions (at this moment
+ // it yields 5).
+ assertTrue(suggestions.length >= 2);
+ // We also assume the top suggestion should be "this".
+ assertEquals("", "this", suggestions[0]);
+ }
+
+ public void testRussianSpellchecker() {
+ changeLanguage("ru");
+ mTextView.onAttachedToWindow();
+ mTextView.setText("годп");
+ type(" ");
+ sleep(1000);
+ runMessages();
+ sleep(1000);
+
+ final SpanGetter span = new SpanGetter(mTextView.getText(), SuggestionSpan.class);
+ // If no span, the following will crash
+ final String[] suggestions = span.getSuggestions();
+ // For this test we consider "годп" should yield at least 2 suggestions (at this moment
+ // it yields 5).
+ assertTrue(suggestions.length >= 2);
+ // We also assume the top suggestion should be "года", which is the top word in the
+ // Russian dictionary.
+ assertEquals("", "года", suggestions[0]);
+ }
+}