Merge "Attempt retry for broken dictionaries"
diff --git a/java/res/anim/key_preview_dismiss_holo.xml b/java/res/anim/key_preview_dismiss_holo.xml
new file mode 100644
index 0000000..0bf7254
--- /dev/null
+++ b/java/res/anim/key_preview_dismiss_holo.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+ <objectAnimator
+ android:propertyName="scaleX"
+ android:duration="53"
+ android:valueFrom="1.00"
+ android:valueTo="0.94" />
+ <objectAnimator
+ android:propertyName="scaleY"
+ android:duration="53"
+ android:valueFrom="1.00"
+ android:valueTo="0.94" />
+</set>
diff --git a/java/res/anim/key_preview_dismiss_lxx.xml b/java/res/anim/key_preview_dismiss_lxx.xml
new file mode 100644
index 0000000..326e534
--- /dev/null
+++ b/java/res/anim/key_preview_dismiss_lxx.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+ <objectAnimator
+ android:propertyName="scaleX"
+ android:duration="53"
+ android:valueFrom="1.00"
+ android:valueTo="1.00" />
+ <objectAnimator
+ android:propertyName="scaleY"
+ android:duration="53"
+ android:valueFrom="1.00"
+ android:valueTo="0.94" />
+</set>
diff --git a/java/res/anim/key_preview_show_up_holo.xml b/java/res/anim/key_preview_show_up_holo.xml
new file mode 100644
index 0000000..ad2e413
--- /dev/null
+++ b/java/res/anim/key_preview_show_up_holo.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+ <objectAnimator
+ android:propertyName="scaleX"
+ android:duration="17"
+ android:valueFrom="0.98"
+ android:valueTo="1.00" />
+ <objectAnimator
+ android:propertyName="scaleY"
+ android:duration="17"
+ android:valueFrom="0.98"
+ android:valueTo="1.00" />
+</set>
diff --git a/java/res/anim/key_preview_show_up_lxx.xml b/java/res/anim/key_preview_show_up_lxx.xml
new file mode 100644
index 0000000..f500349
--- /dev/null
+++ b/java/res/anim/key_preview_show_up_lxx.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+ <objectAnimator
+ android:propertyName="scaleX"
+ android:duration="17"
+ android:valueFrom="1.00"
+ android:valueTo="1.00" />
+ <objectAnimator
+ android:propertyName="scaleY"
+ android:duration="17"
+ android:valueFrom="0.98"
+ android:valueTo="1.00" />
+</set>
diff --git a/java/res/drawable/btn_keyboard_key_popup_lxx_light.xml b/java/res/drawable/btn_keyboard_key_popup_lxx_light.xml
new file mode 100644
index 0000000..d6cd2b8
--- /dev/null
+++ b/java/res/drawable/btn_keyboard_key_popup_lxx_light.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true"
+ android:drawable="@drawable/btn_keyboard_key_popup_selected_lxx_light" />
+ <item android:drawable="@android:color/transparent" />
+</selector>
diff --git a/java/res/values-ne-rNP/strings.xml b/java/res/values-ne-rNP/strings.xml
index c7c95ae..1764e76 100644
--- a/java/res/values-ne-rNP/strings.xml
+++ b/java/res/values-ne-rNP/strings.xml
@@ -80,7 +80,7 @@
<string name="help_and_feedback" msgid="5328219371839879161">"मद्दत र प्रतिक्रिया"</string>
<string name="select_language" msgid="3693815588777926848">"इनपुट भाषाहरू"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"बचत गर्न पुनः छुनुहोस्"</string>
- <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"बचत गर्न यहाँ छुनुहोस्"</string>
+ <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"सुरक्षित गर्न यहाँ छुनुहोस्"</string>
<string name="has_dictionary" msgid="6071847973466625007">"उपलब्ध शब्दकोश"</string>
<string name="keyboard_layout" msgid="8451164783510487501">"किबोर्ड थिम"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"अंग्रेजी (युके)"</string>
diff --git a/java/res/values-ta-rIN/strings-talkback-descriptions.xml b/java/res/values-ta-rIN/strings-talkback-descriptions.xml
index 911e1a5..0ef0720 100644
--- a/java/res/values-ta-rIN/strings-talkback-descriptions.xml
+++ b/java/res/values-ta-rIN/strings-talkback-descriptions.xml
@@ -58,7 +58,7 @@
<string name="keyboard_mode_date" msgid="6597407244976713364">"தேதி"</string>
<string name="keyboard_mode_date_time" msgid="3642804408726668808">"தேதி மற்றும் நேரம்"</string>
<string name="keyboard_mode_email" msgid="1239682082047693644">"மின்னஞ்சல்"</string>
- <string name="keyboard_mode_im" msgid="3812086215529493501">"செய்தியிடல்"</string>
+ <string name="keyboard_mode_im" msgid="3812086215529493501">"மெசேஜ்"</string>
<string name="keyboard_mode_number" msgid="5395042245837996809">"எண்"</string>
<string name="keyboard_mode_phone" msgid="2486230278064523665">"ஃபோன்"</string>
<string name="keyboard_mode_text" msgid="9138789594969187494">"உரை"</string>
diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml
index e89912a..c756f8c 100644
--- a/java/res/values/attrs.xml
+++ b/java/res/values/attrs.xml
@@ -113,6 +113,10 @@
<!-- TODO: consolidate key preview linger timeout with the key preview animation parameters. -->
<!-- Delay after key releasing and key press feedback dismissing in millisecond -->
<attr name="keyPreviewLingerTimeout" format="integer" />
+ <!-- Key preview show up animator -->
+ <attr name="keyPreviewShowUpAnimator" format="reference" />
+ <!-- Key preview dismiss animator -->
+ <attr name="keyPreviewDismissAnimator" format="reference" />
<!-- Layout resource for more keys keyboard -->
<attr name="moreKeysKeyboardLayout" format="reference" />
<attr name="backgroundDimAlpha" format="integer" />
diff --git a/java/res/values/donottranslate-text-decorator.xml b/java/res/values/donottranslate-text-decorator.xml
index 9c39a46..a200349 100644
--- a/java/res/values/donottranslate-text-decorator.xml
+++ b/java/res/values/donottranslate-text-decorator.xml
@@ -31,7 +31,7 @@
<!-- If true, the commit/add-to-text indicator will be suppressed when the word isn't going to
trigger auto-correction. -->
- <bool name="text_decorator_only_for_auto_correction">false</bool>
+ <bool name="text_decorator_only_for_auto_correction">true</bool>
<!-- If true, the commit/add-to-text indicator will be suppressed when the word is already in
the dictionary. -->
@@ -61,18 +61,24 @@
<!-- Coordinates of the closed path to be used to render the commit indicator.
The format is: X[0], Y[0], X[1], Y[1], ..., X[N-1], Y[N-1] -->
<integer-array name="text_decorator_commit_indicator_path">
- <item>180</item>
- <item>323</item>
- <item>97</item>
<item>240</item>
- <item>68</item>
- <item>268</item>
- <item>180</item>
- <item>380</item>
- <item>420</item>
- <item>140</item>
- <item>392</item>
- <item>112</item>
+ <item>80</item>
+ <item>212</item>
+ <item>108</item>
+ <item>323</item>
+ <item>220</item>
+ <item>80</item>
+ <item>220</item>
+ <item>80</item>
+ <item>260</item>
+ <item>323</item>
+ <item>260</item>
+ <item>212</item>
+ <item>372</item>
+ <item>240</item>
+ <item>400</item>
+ <item>400</item>
+ <item>240</item>
</integer-array>
<!-- Background color to be used to highlight the target text when the add-to-dictionary
diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml
index 2a6495a..414820b 100644
--- a/java/res/values/strings.xml
+++ b/java/res/values/strings.xml
@@ -336,14 +336,20 @@
<string name="prefs_keypress_vibration_duration_settings">Keypress vibration duration</string>
<!-- Title of the settings for keypress sound volume [CHAR LIMIT=35] -->
<string name="prefs_keypress_sound_volume_settings">Keypress sound volume</string>
+ <!-- Title of the settings for customize key popup animation parameters [CHAR LIMIT=35] -->
+ <string name="prefs_customize_key_preview_animation">Customize key preview animation</string>
<!-- Title of the settings for key popup show up animation duration (in milliseconds) [CHAR LIMIT=35] -->
<string name="prefs_key_popup_show_up_duration_settings" translatable="false">Key popup show up duration</string>
<!-- Title of the settings for key popup dismiss animation duration (in milliseconds) [CHAR LIMIT=35] -->
<string name="prefs_key_popup_dismiss_duration_settings" translatable="false">Key popup dismiss duration</string>
- <!-- Title of the settings for key popup show up animation start scale (in percentile) [CHAR LIMIT=35] -->
- <string name="prefs_key_popup_show_up_start_scale_settings" translatable="false">Key popup show up start scale</string>
- <!-- Title of the settings for key popup dismiss animation end scale (in percentile) [CHAR LIMIT=35] -->
- <string name="prefs_key_popup_dismiss_end_scale_settings" translatable="false">Key popup dismiss end scale</string>
+ <!-- Title of the settings for key popup show up animation start X-scale (in percentile) [CHAR LIMIT=35] -->
+ <string name="prefs_key_popup_show_up_start_x_scale_settings" translatable="false">Key popup show up start X scale</string>
+ <!-- Title of the settings for key popup show up animation start Y-scale (in percentile) [CHAR LIMIT=35] -->
+ <string name="prefs_key_popup_show_up_start_y_scale_settings" translatable="false">Key popup show up start Y scale</string>
+ <!-- Title of the settings for key popup dismiss animation end X-scale (in percentile) [CHAR LIMIT=35] -->
+ <string name="prefs_key_popup_dismiss_end_x_scale_settings" translatable="false">Key popup dismiss end X scale</string>
+ <!-- Title of the settings for key popup dismiss animation end Y-scale (in percentile) [CHAR LIMIT=35] -->
+ <string name="prefs_key_popup_dismiss_end_y_scale_settings" translatable="false">Key popup dismiss end Y scale</string>
<!-- Title of the settings for reading an external dictionary file -->
<string name="prefs_read_external_dictionary">Read external dictionary file</string>
<!-- Message to show when there are no files to install as an external dictionary [CHAR LIMIT=100] -->
diff --git a/java/res/values/themes-ics.xml b/java/res/values/themes-ics.xml
index 6fddcb9..051489e 100644
--- a/java/res/values/themes-ics.xml
+++ b/java/res/values/themes-ics.xml
@@ -59,6 +59,8 @@
>
<item name="keyPreviewBackground">@drawable/keyboard_key_feedback_ics</item>
<item name="keyPreviewOffset">@dimen/config_key_preview_offset_holo</item>
+ <item name="keyPreviewShowUpAnimator">@anim/key_preview_show_up_holo</item>
+ <item name="keyPreviewDismissAnimator">@anim/key_preview_dismiss_holo</item>
<item name="gestureFloatingPreviewTextColor">@color/highlight_color_ics</item>
<item name="gestureFloatingPreviewColor">@color/gesture_floating_preview_color_holo</item>
<item name="gestureTrailColor">@color/highlight_color_ics</item>
diff --git a/java/res/values/themes-klp.xml b/java/res/values/themes-klp.xml
index c9b8331..a853ed9 100644
--- a/java/res/values/themes-klp.xml
+++ b/java/res/values/themes-klp.xml
@@ -59,6 +59,8 @@
>
<item name="keyPreviewBackground">@drawable/keyboard_key_feedback_klp</item>
<item name="keyPreviewOffset">@dimen/config_key_preview_offset_holo</item>
+ <item name="keyPreviewShowUpAnimator">@anim/key_preview_show_up_holo</item>
+ <item name="keyPreviewDismissAnimator">@anim/key_preview_dismiss_holo</item>
<item name="gestureFloatingPreviewTextColor">@color/highlight_color_klp</item>
<item name="gestureFloatingPreviewColor">@color/gesture_floating_preview_color_holo</item>
<item name="gestureTrailColor">@color/highlight_color_klp</item>
diff --git a/java/res/values/themes-lxx-dark.xml b/java/res/values/themes-lxx-dark.xml
index 6afbd9b..2aaee13 100644
--- a/java/res/values/themes-lxx-dark.xml
+++ b/java/res/values/themes-lxx-dark.xml
@@ -59,6 +59,8 @@
>
<item name="keyPreviewBackground">@drawable/keyboard_key_feedback_lxx_dark</item>
<item name="keyPreviewOffset">@dimen/config_key_preview_offset_holo</item>
+ <item name="keyPreviewShowUpAnimator">@anim/key_preview_show_up_lxx</item>
+ <item name="keyPreviewDismissAnimator">@anim/key_preview_dismiss_lxx</item>
<item name="gestureFloatingPreviewTextColor">@color/auto_correct_color_lxx_dark</item>
<item name="gestureFloatingPreviewColor">@color/gesture_floating_preview_color_lxx_dark</item>
<item name="gestureTrailColor">@color/gesture_trail_color_lxx_dark</item>
diff --git a/java/res/values/themes-lxx-light.xml b/java/res/values/themes-lxx-light.xml
index b3ced80..e7a6f58 100644
--- a/java/res/values/themes-lxx-light.xml
+++ b/java/res/values/themes-lxx-light.xml
@@ -59,6 +59,8 @@
>
<item name="keyPreviewBackground">@drawable/keyboard_key_feedback_lxx_light</item>
<item name="keyPreviewOffset">@dimen/config_key_preview_offset_holo</item>
+ <item name="keyPreviewShowUpAnimator">@anim/key_preview_show_up_lxx</item>
+ <item name="keyPreviewDismissAnimator">@anim/key_preview_dismiss_lxx</item>
<item name="gestureFloatingPreviewTextColor">@color/auto_correct_color_lxx_light</item>
<item name="gestureFloatingPreviewColor">@color/gesture_floating_preview_color_lxx_light</item>
<item name="gestureTrailColor">@color/gesture_trail_color_lxx_light</item>
@@ -98,8 +100,7 @@
parent="KeyboardView.LXX_Light"
>
<item name="android:background">@drawable/keyboard_popup_panel_background_lxx_light</item>
- <!-- Reuse KLP key background -->
- <item name="keyBackground">@drawable/btn_keyboard_key_popup_klp</item>
+ <item name="keyBackground">@drawable/btn_keyboard_key_popup_lxx_light</item>
<item name="keyTypeface">normal</item>
<item name="verticalCorrection">@dimen/config_more_keys_keyboard_vertical_correction_holo</item>
</style>
diff --git a/java/res/xml/prefs_screen_debug.xml b/java/res/xml/prefs_screen_debug.xml
index 965369a..e0f3501 100644
--- a/java/res/xml/prefs_screen_debug.xml
+++ b/java/res/xml/prefs_screen_debug.xml
@@ -52,19 +52,38 @@
latin:minValue="@integer/config_min_longpress_timeout"
latin:maxValue="@integer/config_max_longpress_timeout"
latin:stepValue="@integer/config_longpress_timeout_step" />
+ <CheckBoxPreference
+ android:key="pref_has_custom_key_preview_animation_params"
+ android:title="@string/prefs_customize_key_preview_animation"
+ android:defaultValue="false"
+ android:persistent="true" />
<com.android.inputmethod.latin.settings.SeekBarDialogPreference
- android:key="pref_key_preview_show_up_start_scale"
- android:title="@string/prefs_key_popup_show_up_start_scale_settings"
+ android:dependency="pref_customize_key_preview_animation"
+ android:key="pref_key_preview_show_up_start_x_scale"
+ android:title="@string/prefs_key_popup_show_up_start_x_scale_settings"
latin:maxValue="100" /> <!-- percent -->
<com.android.inputmethod.latin.settings.SeekBarDialogPreference
- android:key="pref_key_preview_dismiss_end_scale"
- android:title="@string/prefs_key_popup_dismiss_end_scale_settings"
+ android:dependency="pref_customize_key_preview_animation"
+ android:key="pref_key_preview_show_up_start_y_scale"
+ android:title="@string/prefs_key_popup_show_up_start_y_scale_settings"
latin:maxValue="100" /> <!-- percent -->
<com.android.inputmethod.latin.settings.SeekBarDialogPreference
+ android:dependency="pref_customize_key_preview_animation"
+ android:key="pref_key_preview_dismiss_end_x_scale"
+ android:title="@string/prefs_key_popup_dismiss_end_x_scale_settings"
+ latin:maxValue="100" /> <!-- percent -->
+ <com.android.inputmethod.latin.settings.SeekBarDialogPreference
+ android:dependency="pref_customize_key_preview_animation"
+ android:key="pref_key_preview_dismiss_end_y_scale"
+ android:title="@string/prefs_key_popup_dismiss_end_y_scale_settings"
+ latin:maxValue="100" /> <!-- percent -->
+ <com.android.inputmethod.latin.settings.SeekBarDialogPreference
+ android:dependency="pref_customize_key_preview_animation"
android:key="pref_key_preview_show_up_duration"
android:title="@string/prefs_key_popup_show_up_duration_settings"
latin:maxValue="100" /> <!-- milliseconds -->
<com.android.inputmethod.latin.settings.SeekBarDialogPreference
+ android:dependency="pref_customize_key_preview_animation"
android:key="pref_key_preview_dismiss_duration"
android:title="@string/prefs_key_popup_dismiss_duration_settings"
latin:maxValue="100" /> <!-- milliseconds -->
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index 389d58a..91d7033 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -154,9 +154,12 @@
mCurrentSettingsValues.mKeyPreviewPopupOn,
mCurrentSettingsValues.mKeyPreviewPopupDismissDelay);
keyboardView.setKeyPreviewAnimationParams(
- mCurrentSettingsValues.mKeyPreviewShowUpStartScale,
+ mCurrentSettingsValues.mHasCustomKeyPreviewAnimationParams,
+ mCurrentSettingsValues.mKeyPreviewShowUpStartXScale,
+ mCurrentSettingsValues.mKeyPreviewShowUpStartYScale,
mCurrentSettingsValues.mKeyPreviewShowUpDuration,
- mCurrentSettingsValues.mKeyPreviewDismissEndScale,
+ mCurrentSettingsValues.mKeyPreviewDismissEndXScale,
+ mCurrentSettingsValues.mKeyPreviewDismissEndYScale,
mCurrentSettingsValues.mKeyPreviewDismissDuration);
keyboardView.updateShortcutKey(mSubtypeSwitcher.isShortcutImeReady());
final boolean subtypeChanged = (oldKeyboard == null)
diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
index 847d907..d2f3e97 100644
--- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
@@ -85,6 +85,8 @@
* @attr ref R.styleable#MainKeyboardView_keyPreviewOffset
* @attr ref R.styleable#MainKeyboardView_keyPreviewHeight
* @attr ref R.styleable#MainKeyboardView_keyPreviewLingerTimeout
+ * @attr ref R.styleable#MainKeyboardView_keyPreviewShowUpAnimator
+ * @attr ref R.styleable#MainKeyboardView_keyPreviewDismissAnimator
* @attr ref R.styleable#MainKeyboardView_moreKeysKeyboardLayout
* @attr ref R.styleable#MainKeyboardView_backgroundDimAlpha
* @attr ref R.styleable#MainKeyboardView_showMoreKeysKeyboardAtTouchPoint
@@ -390,20 +392,34 @@
}
/**
- * Enables or disables the key feedback popup. This is a popup that shows a magnified
+ * Enables or disables the key preview popup. This is a popup that shows a magnified
* version of the depressed key. By default the preview is enabled.
* @param previewEnabled whether or not to enable the key feedback preview
* @param delay the delay after which the preview is dismissed
- * @see #isKeyPreviewPopupEnabled()
*/
public void setKeyPreviewPopupEnabled(final boolean previewEnabled, final int delay) {
mKeyPreviewDrawParams.setPopupEnabled(previewEnabled, delay);
}
- public void setKeyPreviewAnimationParams(final float showUpStartScale, final int showUpDuration,
- final float dismissEndScale, final int dismissDuration) {
- mKeyPreviewDrawParams.setAnimationParams(
- showUpStartScale, showUpDuration, dismissEndScale, dismissDuration);
+ /**
+ * Enables or disables the key preview popup animations and set animations' parameters.
+ *
+ * @param hasCustomAnimationParams false to use the default key preview popup animations
+ * specified by keyPreviewShowUpAnimator and keyPreviewDismissAnimator attributes.
+ * true to override the default animations with the specified parameters.
+ * @param showUpStartXScale from this x-scale the show up animation will start.
+ * @param showUpStartYScale from this y-scale the show up animation will start.
+ * @param showUpDuration the duration of the show up animation in milliseconds.
+ * @param dismissEndXScale to this x-scale the dismiss animation will end.
+ * @param dismissEndYScale to this y-scale the dismiss animation will end.
+ * @param dismissDuration the duration of the dismiss animation in milliseconds.
+ */
+ public void setKeyPreviewAnimationParams(final boolean hasCustomAnimationParams,
+ final float showUpStartXScale, final float showUpStartYScale, final int showUpDuration,
+ final float dismissEndXScale, final float dismissEndYScale, final int dismissDuration) {
+ mKeyPreviewDrawParams.setAnimationParams(hasCustomAnimationParams,
+ showUpStartXScale, showUpStartYScale, showUpDuration,
+ dismissEndXScale, dismissEndYScale, dismissDuration);
}
private void locatePreviewPlacerView() {
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyPreviewChoreographer.java b/java/src/com/android/inputmethod/keyboard/internal/KeyPreviewChoreographer.java
index cd29c8d..5005b7d 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyPreviewChoreographer.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyPreviewChoreographer.java
@@ -18,13 +18,9 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
-import android.view.animation.AccelerateInterpolator;
-import android.view.animation.DecelerateInterpolator;
import com.android.inputmethod.keyboard.Key;
import com.android.inputmethod.latin.utils.CoordinateUtils;
@@ -89,9 +85,9 @@
}
final Object tag = keyPreviewView.getTag();
if (withAnimation) {
- if (tag instanceof KeyPreviewAnimations) {
- final KeyPreviewAnimations animation = (KeyPreviewAnimations)tag;
- animation.startDismiss();
+ if (tag instanceof KeyPreviewAnimators) {
+ final KeyPreviewAnimators animators = (KeyPreviewAnimators)tag;
+ animators.startDismiss();
return;
}
}
@@ -161,87 +157,60 @@
}
// Show preview with animation.
- final Animator showUpAnimation = createShowUpAniation(key, keyPreviewView);
- final Animator dismissAnimation = createDismissAnimation(key, keyPreviewView);
- final KeyPreviewAnimations animation = new KeyPreviewAnimations(
- showUpAnimation, dismissAnimation);
- keyPreviewView.setTag(animation);
- animation.startShowUp();
+ final Animator showUpAnimator = createShowUpAnimator(key, keyPreviewView);
+ final Animator dismissAnimator = createDismissAnimator(key, keyPreviewView);
+ final KeyPreviewAnimators animators = new KeyPreviewAnimators(
+ showUpAnimator, dismissAnimator);
+ keyPreviewView.setTag(animators);
+ animators.startShowUp();
}
- private static final float KEY_PREVIEW_SHOW_UP_END_SCALE = 1.0f;
- private static final AccelerateInterpolator ACCELERATE_INTERPOLATOR =
- new AccelerateInterpolator();
- private static final DecelerateInterpolator DECELERATE_INTERPOLATOR =
- new DecelerateInterpolator();
-
- private Animator createShowUpAniation(final Key key, final KeyPreviewView keyPreviewView) {
- // TODO: Optimization for no scale animation and no duration.
- final ObjectAnimator scaleXAnimation = ObjectAnimator.ofFloat(
- keyPreviewView, View.SCALE_X, mParams.getShowUpStartScale(),
- KEY_PREVIEW_SHOW_UP_END_SCALE);
- final ObjectAnimator scaleYAnimation = ObjectAnimator.ofFloat(
- keyPreviewView, View.SCALE_Y, mParams.getShowUpStartScale(),
- KEY_PREVIEW_SHOW_UP_END_SCALE);
- final AnimatorSet showUpAnimation = new AnimatorSet();
- showUpAnimation.play(scaleXAnimation).with(scaleYAnimation);
- showUpAnimation.setDuration(mParams.getShowUpDuration());
- showUpAnimation.setInterpolator(DECELERATE_INTERPOLATOR);
- showUpAnimation.addListener(new AnimatorListenerAdapter() {
+ public Animator createShowUpAnimator(final Key key, final KeyPreviewView keyPreviewView) {
+ final Animator animator = mParams.createShowUpAnimator(keyPreviewView);
+ animator.addListener(new AnimatorListenerAdapter() {
@Override
- public void onAnimationStart(final Animator animation) {
+ public void onAnimationStart(final Animator animator) {
showKeyPreview(key, keyPreviewView, false /* withAnimation */);
}
});
- return showUpAnimation;
+ return animator;
}
- private Animator createDismissAnimation(final Key key, final KeyPreviewView keyPreviewView) {
- // TODO: Optimization for no scale animation and no duration.
- final ObjectAnimator scaleXAnimation = ObjectAnimator.ofFloat(
- keyPreviewView, View.SCALE_X, mParams.getDismissEndScale());
- final ObjectAnimator scaleYAnimation = ObjectAnimator.ofFloat(
- keyPreviewView, View.SCALE_Y, mParams.getDismissEndScale());
- final AnimatorSet dismissAnimation = new AnimatorSet();
- dismissAnimation.play(scaleXAnimation).with(scaleYAnimation);
- final int dismissDuration = Math.min(
- mParams.getDismissDuration(), mParams.getLingerTimeout());
- dismissAnimation.setDuration(dismissDuration);
- dismissAnimation.setInterpolator(ACCELERATE_INTERPOLATOR);
- dismissAnimation.addListener(new AnimatorListenerAdapter() {
+ private Animator createDismissAnimator(final Key key, final KeyPreviewView keyPreviewView) {
+ final Animator animator = mParams.createDismissAnimator(keyPreviewView);
+ animator.addListener(new AnimatorListenerAdapter() {
@Override
- public void onAnimationEnd(final Animator animation) {
+ public void onAnimationEnd(final Animator animator) {
dismissKeyPreview(key, false /* withAnimation */);
}
});
- return dismissAnimation;
+ return animator;
}
- private static class KeyPreviewAnimations extends AnimatorListenerAdapter {
- private final Animator mShowUpAnimation;
- private final Animator mDismissAnimation;
+ private static class KeyPreviewAnimators extends AnimatorListenerAdapter {
+ private final Animator mShowUpAnimator;
+ private final Animator mDismissAnimator;
- public KeyPreviewAnimations(final Animator showUpAnimation,
- final Animator dismissAnimation) {
- mShowUpAnimation = showUpAnimation;
- mDismissAnimation = dismissAnimation;
+ public KeyPreviewAnimators(final Animator showUpAnimator, final Animator dismissAnimator) {
+ mShowUpAnimator = showUpAnimator;
+ mDismissAnimator = dismissAnimator;
}
public void startShowUp() {
- mShowUpAnimation.start();
+ mShowUpAnimator.start();
}
public void startDismiss() {
- if (mShowUpAnimation.isRunning()) {
- mShowUpAnimation.addListener(this);
+ if (mShowUpAnimator.isRunning()) {
+ mShowUpAnimator.addListener(this);
return;
}
- mDismissAnimation.start();
+ mDismissAnimator.start();
}
@Override
- public void onAnimationEnd(final Animator animation) {
- mDismissAnimation.start();
+ public void onAnimationEnd(final Animator animator) {
+ mDismissAnimator.start();
}
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyPreviewDrawParams.java b/java/src/com/android/inputmethod/keyboard/internal/KeyPreviewDrawParams.java
index 68c9831..5ed39f9 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyPreviewDrawParams.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyPreviewDrawParams.java
@@ -16,8 +16,14 @@
package com.android.inputmethod.keyboard.internal;
+import android.animation.Animator;
+import android.animation.AnimatorInflater;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
import android.content.res.TypedArray;
import android.view.View;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.DecelerateInterpolator;
import com.android.inputmethod.latin.R;
@@ -26,10 +32,15 @@
public final int mPreviewOffset;
public final int mPreviewHeight;
public final int mPreviewBackgroundResId;
+ private final int mShowUpAnimatorResId;
+ private final int mDismissAnimatorResId;
+ private boolean mHasCustomAnimationParams;
private int mShowUpDuration;
private int mDismissDuration;
- private float mShowUpStartScale;
- private float mDismissEndScale;
+ private float mShowUpStartXScale;
+ private float mShowUpStartYScale;
+ private float mDismissEndXScale;
+ private float mDismissEndYScale;
private int mLingerTimeout;
private boolean mShowPopup = true;
@@ -67,6 +78,10 @@
R.styleable.MainKeyboardView_keyPreviewBackground, 0);
mLingerTimeout = mainKeyboardViewAttr.getInt(
R.styleable.MainKeyboardView_keyPreviewLingerTimeout, 0);
+ mShowUpAnimatorResId = mainKeyboardViewAttr.getResourceId(
+ R.styleable.MainKeyboardView_keyPreviewShowUpAnimator, 0);
+ mDismissAnimatorResId = mainKeyboardViewAttr.getResourceId(
+ R.styleable.MainKeyboardView_keyPreviewDismissAnimator, 0);
}
public void setVisibleOffset(final int previewVisibleOffset) {
@@ -112,27 +127,62 @@
return mLingerTimeout;
}
- public void setAnimationParams(final float showUpStartScale, final int showUpDuration,
- final float dismissEndScale, final int dismissDuration) {
- mShowUpStartScale = showUpStartScale;
+ public void setAnimationParams(final boolean hasCustomAnimationParams,
+ final float showUpStartXScale, final float showUpStartYScale, final int showUpDuration,
+ final float dismissEndXScale, final float dismissEndYScale, final int dismissDuration) {
+ mHasCustomAnimationParams = hasCustomAnimationParams;
+ mShowUpStartXScale = showUpStartXScale;
+ mShowUpStartYScale = showUpStartYScale;
mShowUpDuration = showUpDuration;
- mDismissEndScale = dismissEndScale;
+ mDismissEndXScale = dismissEndXScale;
+ mDismissEndYScale = dismissEndYScale;
mDismissDuration = dismissDuration;
}
- public float getShowUpStartScale() {
- return mShowUpStartScale;
+ private static final float KEY_PREVIEW_SHOW_UP_END_SCALE = 1.0f;
+ private static final AccelerateInterpolator ACCELERATE_INTERPOLATOR =
+ new AccelerateInterpolator();
+ private static final DecelerateInterpolator DECELERATE_INTERPOLATOR =
+ new DecelerateInterpolator();
+
+ public Animator createShowUpAnimator(final View target) {
+ if (mHasCustomAnimationParams) {
+ final ObjectAnimator scaleXAnimator = ObjectAnimator.ofFloat(
+ target, View.SCALE_X, mShowUpStartXScale,
+ KEY_PREVIEW_SHOW_UP_END_SCALE);
+ final ObjectAnimator scaleYAnimator = ObjectAnimator.ofFloat(
+ target, View.SCALE_Y, mShowUpStartYScale,
+ KEY_PREVIEW_SHOW_UP_END_SCALE);
+ final AnimatorSet showUpAnimator = new AnimatorSet();
+ showUpAnimator.play(scaleXAnimator).with(scaleYAnimator);
+ showUpAnimator.setDuration(mShowUpDuration);
+ showUpAnimator.setInterpolator(DECELERATE_INTERPOLATOR);
+ return showUpAnimator;
+ }
+ final Animator animator = AnimatorInflater.loadAnimator(
+ target.getContext(), mShowUpAnimatorResId);
+ animator.setTarget(target);
+ animator.setInterpolator(DECELERATE_INTERPOLATOR);
+ return animator;
}
- public int getShowUpDuration() {
- return mShowUpDuration;
- }
-
- public float getDismissEndScale() {
- return mDismissEndScale;
- }
-
- public int getDismissDuration() {
- return mDismissDuration;
+ public Animator createDismissAnimator(final View target) {
+ if (mHasCustomAnimationParams) {
+ final ObjectAnimator scaleXAnimator = ObjectAnimator.ofFloat(
+ target, View.SCALE_X, mDismissEndXScale);
+ final ObjectAnimator scaleYAnimator = ObjectAnimator.ofFloat(
+ target, View.SCALE_Y, mDismissEndYScale);
+ final AnimatorSet dismissAnimator = new AnimatorSet();
+ dismissAnimator.play(scaleXAnimator).with(scaleYAnimator);
+ final int dismissDuration = Math.min(mDismissDuration, mLingerTimeout);
+ dismissAnimator.setDuration(dismissDuration);
+ dismissAnimator.setInterpolator(ACCELERATE_INTERPOLATOR);
+ return dismissAnimator;
+ }
+ final Animator animator = AnimatorInflater.loadAnimator(
+ target.getContext(), mDismissAnimatorResId);
+ animator.setTarget(target);
+ animator.setInterpolator(ACCELERATE_INTERPOLATOR);
+ return animator;
}
}
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index 693e1cd..2e10875 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -83,7 +83,6 @@
public static final String DIR_NAME_SUFFIX_FOR_RECORD_MIGRATION = ".migrating";
private long mNativeDict;
- private final Locale mLocale;
private final long mDictSize;
private final String mDictFilePath;
private final boolean mUseFullEditDistance;
@@ -117,8 +116,7 @@
public BinaryDictionary(final String filename, final long offset, final long length,
final boolean useFullEditDistance, final Locale locale, final String dictType,
final boolean isUpdatable) {
- super(dictType);
- mLocale = locale;
+ super(dictType, locale);
mDictSize = length;
mDictFilePath = filename;
mIsUpdatable = isUpdatable;
@@ -138,8 +136,7 @@
public BinaryDictionary(final String filename, final boolean useFullEditDistance,
final Locale locale, final String dictType, final long formatVersion,
final Map<String, String> attributeMap) {
- super(dictType);
- mLocale = locale;
+ super(dictType, locale);
mDictSize = 0;
mDictFilePath = filename;
// On memory dictionary is always updatable.
diff --git a/java/src/com/android/inputmethod/latin/Dictionary.java b/java/src/com/android/inputmethod/latin/Dictionary.java
index 560ced9..2f79c76 100644
--- a/java/src/com/android/inputmethod/latin/Dictionary.java
+++ b/java/src/com/android/inputmethod/latin/Dictionary.java
@@ -16,12 +16,12 @@
package com.android.inputmethod.latin;
-import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.settings.SettingsValuesForSuggestion;
import java.util.ArrayList;
+import java.util.Locale;
/**
* Abstract base class for a dictionary that can do a fuzzy search for words based on a set of key
@@ -62,9 +62,12 @@
// Contextual dictionary.
public static final String TYPE_CONTEXTUAL = "contextual";
public final String mDictType;
+ // The locale for this dictionary. May be null if unknown (phony dictionary for example).
+ public final Locale mLocale;
- public Dictionary(final String dictType) {
+ public Dictionary(final String dictType, final Locale locale) {
mDictType = dictType;
+ mLocale = locale;
}
/**
@@ -162,7 +165,7 @@
private static class PhonyDictionary extends Dictionary {
// This class is not publicly instantiable.
private PhonyDictionary(final String type) {
- super(type);
+ super(type, null);
}
@Override
diff --git a/java/src/com/android/inputmethod/latin/DictionaryCollection.java b/java/src/com/android/inputmethod/latin/DictionaryCollection.java
index 2b4c54d..ca5e937 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryCollection.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryCollection.java
@@ -25,6 +25,7 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.Locale;
import java.util.concurrent.CopyOnWriteArrayList;
/**
@@ -34,13 +35,14 @@
private final String TAG = DictionaryCollection.class.getSimpleName();
protected final CopyOnWriteArrayList<Dictionary> mDictionaries;
- public DictionaryCollection(final String dictType) {
- super(dictType);
+ public DictionaryCollection(final String dictType, final Locale locale) {
+ super(dictType, locale);
mDictionaries = new CopyOnWriteArrayList<>();
}
- public DictionaryCollection(final String dictType, final Dictionary... dictionaries) {
- super(dictType);
+ public DictionaryCollection(final String dictType, final Locale locale,
+ final Dictionary... dictionaries) {
+ super(dictType, locale);
if (null == dictionaries) {
mDictionaries = new CopyOnWriteArrayList<>();
} else {
@@ -49,8 +51,9 @@
}
}
- public DictionaryCollection(final String dictType, final Collection<Dictionary> dictionaries) {
- super(dictType);
+ public DictionaryCollection(final String dictType, final Locale locale,
+ final Collection<Dictionary> dictionaries) {
+ super(dictType, locale);
mDictionaries = new CopyOnWriteArrayList<>(dictionaries);
mDictionaries.removeAll(Collections.singleton(null));
}
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
index fe395a8..480bd1f 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
@@ -503,7 +503,7 @@
final SettingsValuesForSuggestion settingsValuesForSuggestion, final int sessionId) {
final Dictionaries dictionaries = mDictionaries;
final SuggestionResults suggestionResults =
- new SuggestionResults(dictionaries.mLocale, SuggestedWords.MAX_SUGGESTIONS);
+ new SuggestionResults(SuggestedWords.MAX_SUGGESTIONS);
final float[] languageWeight = new float[] { Dictionary.NOT_A_LANGUAGE_WEIGHT };
for (final String dictType : DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS) {
final Dictionary dictionary = dictionaries.getDict(dictType);
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFactory.java b/java/src/com/android/inputmethod/latin/DictionaryFactory.java
index 59de4f8..3459b42 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFactory.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFactory.java
@@ -50,7 +50,7 @@
final Locale locale, final boolean useFullEditDistance) {
if (null == locale) {
Log.e(TAG, "No locale defined for dictionary");
- return new DictionaryCollection(Dictionary.TYPE_MAIN,
+ return new DictionaryCollection(Dictionary.TYPE_MAIN, locale,
createReadOnlyBinaryDictionary(context, locale));
}
@@ -75,7 +75,7 @@
// If the list is empty, that means we should not use any dictionary (for example, the user
// explicitly disabled the main dictionary), so the following is okay. dictList is never
// null, but if for some reason it is, DictionaryCollection handles it gracefully.
- return new DictionaryCollection(Dictionary.TYPE_MAIN, dictList);
+ return new DictionaryCollection(Dictionary.TYPE_MAIN, locale, dictList);
}
/**
@@ -188,7 +188,7 @@
public static Dictionary createDictionaryForTest(final AssetFileAddress[] dictionaryList,
final boolean useFullEditDistance, Locale locale) {
final DictionaryCollection dictionaryCollection =
- new DictionaryCollection(Dictionary.TYPE_MAIN);
+ new DictionaryCollection(Dictionary.TYPE_MAIN, locale);
for (final AssetFileAddress address : dictionaryList) {
final ReadOnlyBinaryDictionary readOnlyBinaryDictionary = new ReadOnlyBinaryDictionary(
address.mFilename, address.mOffset, address.mLength, useFullEditDistance,
diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
index de38403..a1dd67f 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
@@ -86,9 +86,6 @@
*/
private final String mDictName;
- /** Dictionary locale */
- private final Locale mLocale;
-
/** Dictionary file */
private final File mDictFile;
@@ -137,10 +134,9 @@
*/
public ExpandableBinaryDictionary(final Context context, final String dictName,
final Locale locale, final String dictType, final File dictFile) {
- super(dictType);
+ super(dictType, locale);
mDictName = dictName;
mContext = context;
- mLocale = locale;
mDictFile = getDictFile(context, dictName, dictFile);
mBinaryDictionary = null;
mIsReloading = new AtomicBoolean();
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 59150ae..c55acd4 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -1179,10 +1179,6 @@
return mInputLogic.getCurrentRecapitalizeState();
}
- public Locale getCurrentSubtypeLocale() {
- return mSubtypeSwitcher.getCurrentSubtypeLocale();
- }
-
/**
* @param codePoints code points to get coordinates for.
* @return x,y coordinates for this keyboard, as a flattened array.
@@ -1496,7 +1492,7 @@
}
final String wordToShow;
if (CapsModeUtils.isAutoCapsMode(mInputLogic.mLastComposedWord.mCapitalizedMode)) {
- wordToShow = word.toLowerCase(getCurrentSubtypeLocale());
+ wordToShow = word.toLowerCase(mSubtypeSwitcher.getCurrentSubtypeLocale());
} else {
wordToShow = word;
}
diff --git a/java/src/com/android/inputmethod/latin/ReadOnlyBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ReadOnlyBinaryDictionary.java
index 5d4fc58..ecf25c2 100644
--- a/java/src/com/android/inputmethod/latin/ReadOnlyBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ReadOnlyBinaryDictionary.java
@@ -40,7 +40,7 @@
public ReadOnlyBinaryDictionary(final String filename, final long offset, final long length,
final boolean useFullEditDistance, final Locale locale, final String dictType) {
- super(dictType);
+ super(dictType, locale);
mBinaryDictionary = new BinaryDictionary(filename, offset, length, useFullEditDistance,
locale, dictType, false /* isUpdatable */);
}
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index 6779351..9e4aa40 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -84,7 +84,7 @@
private static ArrayList<SuggestedWordInfo> getTransformedSuggestedWordInfoList(
final WordComposer wordComposer, final SuggestionResults results,
- final int trailingSingleQuotesCount) {
+ final int trailingSingleQuotesCount, final Locale defaultLocale) {
final boolean shouldMakeSuggestionsAllUpperCase = wordComposer.isAllUpperCase()
&& !wordComposer.isResumed();
final boolean isOnlyFirstCharCapitalized =
@@ -96,9 +96,11 @@
|| 0 != trailingSingleQuotesCount) {
for (int i = 0; i < suggestionsCount; ++i) {
final SuggestedWordInfo wordInfo = suggestionsContainer.get(i);
+ final Locale wordLocale = wordInfo.mSourceDict.mLocale;
final SuggestedWordInfo transformedWordInfo = getTransformedSuggestedWordInfo(
- wordInfo, results.mLocale, shouldMakeSuggestionsAllUpperCase,
- isOnlyFirstCharCapitalized, trailingSingleQuotesCount);
+ wordInfo, null == wordLocale ? defaultLocale : wordLocale,
+ shouldMakeSuggestionsAllUpperCase, isOnlyFirstCharCapitalized,
+ trailingSingleQuotesCount);
suggestionsContainer.set(i, transformedWordInfo);
}
}
@@ -134,7 +136,7 @@
SESSION_ID_TYPING);
final ArrayList<SuggestedWordInfo> suggestionsContainer =
getTransformedSuggestedWordInfoList(wordComposer, suggestionResults,
- trailingSingleQuotesCount);
+ trailingSingleQuotesCount, mDictionaryFacilitator.getLocale());
final boolean didRemoveTypedWord =
SuggestedWordInfo.removeDups(wordComposer.getTypedWord(), suggestionsContainer);
@@ -208,6 +210,7 @@
final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults(
wordComposer, prevWordsInfo, proximityInfo, settingsValuesForSuggestion,
SESSION_ID_GESTURE);
+ final Locale defaultLocale = mDictionaryFacilitator.getLocale();
final ArrayList<SuggestedWordInfo> suggestionsContainer =
new ArrayList<>(suggestionResults);
final int suggestionsCount = suggestionsContainer.size();
@@ -216,9 +219,10 @@
if (isFirstCharCapitalized || isAllUpperCase) {
for (int i = 0; i < suggestionsCount; ++i) {
final SuggestedWordInfo wordInfo = suggestionsContainer.get(i);
+ final Locale wordlocale = wordInfo.mSourceDict.mLocale;
final SuggestedWordInfo transformedWordInfo = getTransformedSuggestedWordInfo(
- wordInfo, suggestionResults.mLocale, isAllUpperCase, isFirstCharCapitalized,
- 0 /* trailingSingleQuotesCount */);
+ wordInfo, null == wordlocale ? defaultLocale : wordlocale, isAllUpperCase,
+ isFirstCharCapitalized, 0 /* trailingSingleQuotesCount */);
suggestionsContainer.set(i, transformedWordInfo);
}
}
diff --git a/java/src/com/android/inputmethod/latin/settings/DebugSettings.java b/java/src/com/android/inputmethod/latin/settings/DebugSettings.java
index 63d848e..48f4c75 100644
--- a/java/src/com/android/inputmethod/latin/settings/DebugSettings.java
+++ b/java/src/com/android/inputmethod/latin/settings/DebugSettings.java
@@ -23,10 +23,16 @@
"force_physical_keyboard_special_key";
public static final String PREF_SHOW_UI_TO_ACCEPT_TYPED_WORD =
"pref_show_ui_to_accept_typed_word";
- public static final String PREF_KEY_PREVIEW_SHOW_UP_START_SCALE =
- "pref_key_preview_show_up_start_scale";
- public static final String PREF_KEY_PREVIEW_DISMISS_END_SCALE =
- "pref_key_preview_dismiss_end_scale";
+ public static final String PREF_HAS_CUSTOM_KEY_PREVIEW_ANIMATION_PARAMS =
+ "pref_has_custom_key_preview_animation_params";
+ public static final String PREF_KEY_PREVIEW_SHOW_UP_START_X_SCALE =
+ "pref_key_preview_show_up_start_x_scale";
+ public static final String PREF_KEY_PREVIEW_SHOW_UP_START_Y_SCALE =
+ "pref_key_preview_show_up_start_y_scale";
+ public static final String PREF_KEY_PREVIEW_DISMISS_END_X_SCALE =
+ "pref_key_preview_dismiss_end_x_scale";
+ public static final String PREF_KEY_PREVIEW_DISMISS_END_Y_SCALE =
+ "pref_key_preview_dismiss_end_y_scale";
public static final String PREF_KEY_PREVIEW_SHOW_UP_DURATION =
"pref_key_preview_show_up_duration";
public static final String PREF_KEY_PREVIEW_DISMISS_DURATION =
diff --git a/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java
index dc2f88a..5640e20 100644
--- a/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java
@@ -78,12 +78,18 @@
res.getInteger(R.integer.config_key_preview_show_up_duration));
setupKeyPreviewAnimationDuration(DebugSettings.PREF_KEY_PREVIEW_DISMISS_DURATION,
res.getInteger(R.integer.config_key_preview_dismiss_duration));
- setupKeyPreviewAnimationScale(DebugSettings.PREF_KEY_PREVIEW_SHOW_UP_START_SCALE,
- ResourceUtils.getFloatFromFraction(
- res, R.fraction.config_key_preview_show_up_start_scale));
- setupKeyPreviewAnimationScale(DebugSettings.PREF_KEY_PREVIEW_DISMISS_END_SCALE,
- ResourceUtils.getFloatFromFraction(
- res, R.fraction.config_key_preview_dismiss_end_scale));
+ final float defaultKeyPreviewShowUpStartScale = ResourceUtils.getFloatFromFraction(
+ res, R.fraction.config_key_preview_show_up_start_scale);
+ final float defaultKeyPreviewDismissEndScale = ResourceUtils.getFloatFromFraction(
+ res, R.fraction.config_key_preview_dismiss_end_scale);
+ setupKeyPreviewAnimationScale(DebugSettings.PREF_KEY_PREVIEW_SHOW_UP_START_X_SCALE,
+ defaultKeyPreviewShowUpStartScale);
+ setupKeyPreviewAnimationScale(DebugSettings.PREF_KEY_PREVIEW_SHOW_UP_START_Y_SCALE,
+ defaultKeyPreviewShowUpStartScale);
+ setupKeyPreviewAnimationScale(DebugSettings.PREF_KEY_PREVIEW_DISMISS_END_X_SCALE,
+ defaultKeyPreviewDismissEndScale);
+ setupKeyPreviewAnimationScale(DebugSettings.PREF_KEY_PREVIEW_DISMISS_END_Y_SCALE,
+ defaultKeyPreviewDismissEndScale);
mServiceNeedsRestart = false;
mDebugMode = (TwoStatePreference) findPreference(DebugSettings.PREF_DEBUG_MODE);
diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
index e91862d..1129195 100644
--- a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
+++ b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
@@ -104,10 +104,13 @@
// Debug settings
public final boolean mIsInternal;
+ public final boolean mHasCustomKeyPreviewAnimationParams;
public final int mKeyPreviewShowUpDuration;
public final int mKeyPreviewDismissDuration;
- public final float mKeyPreviewShowUpStartScale;
- public final float mKeyPreviewDismissEndScale;
+ public final float mKeyPreviewShowUpStartXScale;
+ public final float mKeyPreviewShowUpStartYScale;
+ public final float mKeyPreviewDismissEndXScale;
+ public final float mKeyPreviewDismissEndYScale;
public SettingsValues(final Context context, final SharedPreferences prefs, final Resources res,
final InputAttributes inputAttributes) {
@@ -179,20 +182,30 @@
mTextHighlightColorForAddToDictionaryIndicator = res.getColor(
R.color.text_decorator_add_to_dictionary_indicator_text_highlight_color);
mIsInternal = Settings.isInternal(prefs);
+ mHasCustomKeyPreviewAnimationParams = prefs.getBoolean(
+ DebugSettings.PREF_HAS_CUSTOM_KEY_PREVIEW_ANIMATION_PARAMS, false);
mKeyPreviewShowUpDuration = Settings.readKeyPreviewAnimationDuration(
prefs, DebugSettings.PREF_KEY_PREVIEW_SHOW_UP_DURATION,
res.getInteger(R.integer.config_key_preview_show_up_duration));
mKeyPreviewDismissDuration = Settings.readKeyPreviewAnimationDuration(
prefs, DebugSettings.PREF_KEY_PREVIEW_DISMISS_DURATION,
res.getInteger(R.integer.config_key_preview_dismiss_duration));
- mKeyPreviewShowUpStartScale = Settings.readKeyPreviewAnimationScale(
- prefs, DebugSettings.PREF_KEY_PREVIEW_SHOW_UP_START_SCALE,
- ResourceUtils.getFloatFromFraction(
- res, R.fraction.config_key_preview_show_up_start_scale));
- mKeyPreviewDismissEndScale = Settings.readKeyPreviewAnimationScale(
- prefs, DebugSettings.PREF_KEY_PREVIEW_DISMISS_END_SCALE,
- ResourceUtils.getFloatFromFraction(
- res, R.fraction.config_key_preview_dismiss_end_scale));
+ final float defaultKeyPreviewShowUpStartScale = ResourceUtils.getFloatFromFraction(
+ res, R.fraction.config_key_preview_show_up_start_scale);
+ final float defaultKeyPreviewDismissEndScale = ResourceUtils.getFloatFromFraction(
+ res, R.fraction.config_key_preview_dismiss_end_scale);
+ mKeyPreviewShowUpStartXScale = Settings.readKeyPreviewAnimationScale(
+ prefs, DebugSettings.PREF_KEY_PREVIEW_SHOW_UP_START_X_SCALE,
+ defaultKeyPreviewShowUpStartScale);
+ mKeyPreviewShowUpStartYScale = Settings.readKeyPreviewAnimationScale(
+ prefs, DebugSettings.PREF_KEY_PREVIEW_SHOW_UP_START_Y_SCALE,
+ defaultKeyPreviewShowUpStartScale);
+ mKeyPreviewDismissEndXScale = Settings.readKeyPreviewAnimationScale(
+ prefs, DebugSettings.PREF_KEY_PREVIEW_DISMISS_END_X_SCALE,
+ defaultKeyPreviewDismissEndScale);
+ mKeyPreviewDismissEndYScale = Settings.readKeyPreviewAnimationScale(
+ prefs, DebugSettings.PREF_KEY_PREVIEW_DISMISS_END_Y_SCALE,
+ defaultKeyPreviewDismissEndScale);
mDisplayOrientation = res.getConfiguration().orientation;
mAppWorkarounds = new AsyncResultHolder<>();
final PackageInfo packageInfo = TargetPackageInfoGetterTask.getCachedPackageInfo(
@@ -429,10 +442,14 @@
sb.append("" + mKeyPreviewShowUpDuration);
sb.append("\n mKeyPreviewDismissDuration = ");
sb.append("" + mKeyPreviewDismissDuration);
- sb.append("\n mKeyPreviewShowUpStartScale = ");
- sb.append("" + mKeyPreviewShowUpStartScale);
- sb.append("\n mKeyPreviewDismissEndScale = ");
- sb.append("" + mKeyPreviewDismissEndScale);
+ sb.append("\n mKeyPreviewShowUpStartScaleX = ");
+ sb.append("" + mKeyPreviewShowUpStartXScale);
+ sb.append("\n mKeyPreviewShowUpStartScaleY = ");
+ sb.append("" + mKeyPreviewShowUpStartYScale);
+ sb.append("\n mKeyPreviewDismissEndScaleX = ");
+ sb.append("" + mKeyPreviewDismissEndXScale);
+ sb.append("\n mKeyPreviewDismissEndScaleY = ");
+ sb.append("" + mKeyPreviewDismissEndYScale);
return sb.toString();
}
}
diff --git a/java/src/com/android/inputmethod/latin/utils/SuggestionResults.java b/java/src/com/android/inputmethod/latin/utils/SuggestionResults.java
index 7170bd7..eaa5743 100644
--- a/java/src/com/android/inputmethod/latin/utils/SuggestionResults.java
+++ b/java/src/com/android/inputmethod/latin/utils/SuggestionResults.java
@@ -30,18 +30,16 @@
* than its limit
*/
public final class SuggestionResults extends TreeSet<SuggestedWordInfo> {
- public final Locale mLocale;
public final ArrayList<SuggestedWordInfo> mRawSuggestions;
private final int mCapacity;
- public SuggestionResults(final Locale locale, final int capacity) {
- this(locale, sSuggestedWordInfoComparator, capacity);
+ public SuggestionResults(final int capacity) {
+ this(sSuggestedWordInfoComparator, capacity);
}
- public SuggestionResults(final Locale locale, final Comparator<SuggestedWordInfo> comparator,
+ public SuggestionResults(final Comparator<SuggestedWordInfo> comparator,
final int capacity) {
super(comparator);
- mLocale = locale;
mCapacity = capacity;
if (ProductionFlags.INCLUDE_RAW_SUGGESTIONS) {
mRawSuggestions = new ArrayList<>();
diff --git a/native/jni/NativeFileList.mk b/native/jni/NativeFileList.mk
index 082e1e2..4f77388 100644
--- a/native/jni/NativeFileList.mk
+++ b/native/jni/NativeFileList.mk
@@ -123,6 +123,7 @@
defines_test.cpp \
suggest/core/dicnode/dic_node_pool_test.cpp \
suggest/core/dictionary/bloom_filter_test.cpp \
+ suggest/core/layout/geometry_utils_test.cpp \
suggest/core/layout/normal_distribution_2d_test.cpp \
suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content_test.cpp \
suggest/policyimpl/dictionary/structure/v4/content/probability_entry_test.cpp \
@@ -131,6 +132,8 @@
suggest/policyimpl/dictionary/utils/byte_array_utils_test.cpp \
suggest/policyimpl/dictionary/utils/sparse_table_test.cpp \
suggest/policyimpl/dictionary/utils/trie_map_test.cpp \
+ suggest/policyimpl/utils/damerau_levenshtein_edit_distance_policy_test.cpp \
utils/autocorrection_threshold_utils_test.cpp \
+ utils/char_utils_test.cpp \
utils/int_array_view_test.cpp \
utils/time_keeper_test.cpp
diff --git a/native/jni/src/suggest/core/dicnode/dic_node.h b/native/jni/src/suggest/core/dicnode/dic_node.h
index 214cdfc..e44d5ae 100644
--- a/native/jni/src/suggest/core/dicnode/dic_node.h
+++ b/native/jni/src/suggest/core/dicnode/dic_node.h
@@ -103,10 +103,10 @@
PROF_NODE_COPY(&dicNode->mProfiler, mProfiler);
}
- // Init for root with prevWordsPtNodePos which is used for n-gram
- void initAsRoot(const int rootPtNodeArrayPos, const int *const prevWordsPtNodePos) {
+ // Init for root with prevWordIds which is used for n-gram
+ void initAsRoot(const int rootPtNodeArrayPos, const int *const prevWordIds) {
mIsCachedForNextSuggestion = false;
- mDicNodeProperties.init(rootPtNodeArrayPos, prevWordsPtNodePos);
+ mDicNodeProperties.init(rootPtNodeArrayPos, prevWordIds);
mDicNodeState.init();
PROF_NODE_RESET(mProfiler);
}
@@ -114,12 +114,12 @@
// Init for root with previous word
void initAsRootWithPreviousWord(const DicNode *const dicNode, const int rootPtNodeArrayPos) {
mIsCachedForNextSuggestion = dicNode->mIsCachedForNextSuggestion;
- int newPrevWordsPtNodePos[MAX_PREV_WORD_COUNT_FOR_N_GRAM];
- newPrevWordsPtNodePos[0] = dicNode->mDicNodeProperties.getPtNodePos();
- for (size_t i = 1; i < NELEMS(newPrevWordsPtNodePos); ++i) {
- newPrevWordsPtNodePos[i] = dicNode->getPrevWordsTerminalPtNodePos()[i - 1];
+ int newPrevWordIds[MAX_PREV_WORD_COUNT_FOR_N_GRAM];
+ newPrevWordIds[0] = dicNode->mDicNodeProperties.getWordId();
+ for (size_t i = 1; i < NELEMS(newPrevWordIds); ++i) {
+ newPrevWordIds[i] = dicNode->getPrevWordIds()[i - 1];
}
- mDicNodeProperties.init(rootPtNodeArrayPos, newPrevWordsPtNodePos);
+ mDicNodeProperties.init(rootPtNodeArrayPos, newPrevWordIds);
mDicNodeState.initAsRootWithPreviousWord(&dicNode->mDicNodeState,
dicNode->mDicNodeProperties.getDepth());
PROF_NODE_COPY(&dicNode->mProfiler, mProfiler);
@@ -145,7 +145,7 @@
dicNode->mDicNodeProperties.getLeavingDepth() + mergedNodeCodePointCount);
mDicNodeProperties.init(ptNodePos, childrenPtNodeArrayPos, mergedNodeCodePoints[0],
probability, wordId, hasChildren, isBlacklistedOrNotAWord, newDepth,
- newLeavingDepth, dicNode->mDicNodeProperties.getPrevWordsTerminalPtNodePos());
+ newLeavingDepth, dicNode->mDicNodeProperties.getPrevWordIds());
mDicNodeState.init(&dicNode->mDicNodeState, mergedNodeCodePointCount,
mergedNodeCodePoints);
PROF_NODE_COPY(&dicNode->mProfiler, mProfiler);
@@ -204,13 +204,18 @@
}
// Used to get n-gram probability in DicNodeUtils.
+ int getWordId() const {
+ return mDicNodeProperties.getWordId();
+ }
+
+ // TODO: Remove
int getPtNodePos() const {
return mDicNodeProperties.getPtNodePos();
}
- // TODO: Use view class to return PtNodePos array.
- const int *getPrevWordsTerminalPtNodePos() const {
- return mDicNodeProperties.getPrevWordsTerminalPtNodePos();
+ // TODO: Use view class to return word id array.
+ const int *getPrevWordIds() const {
+ return mDicNodeProperties.getPrevWordIds();
}
// Used in DicNodeUtils
diff --git a/native/jni/src/suggest/core/dicnode/dic_node_utils.cpp b/native/jni/src/suggest/core/dicnode/dic_node_utils.cpp
index 69ea674..87d2452 100644
--- a/native/jni/src/suggest/core/dicnode/dic_node_utils.cpp
+++ b/native/jni/src/suggest/core/dicnode/dic_node_utils.cpp
@@ -29,8 +29,8 @@
/* static */ void DicNodeUtils::initAsRoot(
const DictionaryStructureWithBufferPolicy *const dictionaryStructurePolicy,
- const int *const prevWordsPtNodePos, DicNode *const newRootDicNode) {
- newRootDicNode->initAsRoot(dictionaryStructurePolicy->getRootPosition(), prevWordsPtNodePos);
+ const int *const prevWordIds, DicNode *const newRootDicNode) {
+ newRootDicNode->initAsRoot(dictionaryStructurePolicy->getRootPosition(), prevWordIds);
}
/*static */ void DicNodeUtils::initAsRootWithPreviousWord(
@@ -86,9 +86,9 @@
const DicNode *const dicNode, MultiBigramMap *const multiBigramMap) {
const int unigramProbability = dicNode->getProbability();
if (multiBigramMap) {
- const int *const prevWordsPtNodePos = dicNode->getPrevWordsTerminalPtNodePos();
+ const int *const prevWordIds = dicNode->getPrevWordIds();
return multiBigramMap->getBigramProbability(dictionaryStructurePolicy,
- prevWordsPtNodePos, dicNode->getPtNodePos(), unigramProbability);
+ prevWordIds, dicNode->getWordId(), unigramProbability);
}
return dictionaryStructurePolicy->getProbability(unigramProbability,
NOT_A_PROBABILITY);
diff --git a/native/jni/src/suggest/core/dicnode/dic_node_utils.h b/native/jni/src/suggest/core/dicnode/dic_node_utils.h
index 00e80c6..56ff6e3 100644
--- a/native/jni/src/suggest/core/dicnode/dic_node_utils.h
+++ b/native/jni/src/suggest/core/dicnode/dic_node_utils.h
@@ -30,7 +30,7 @@
public:
static void initAsRoot(
const DictionaryStructureWithBufferPolicy *const dictionaryStructurePolicy,
- const int *const prevWordPtNodePos, DicNode *const newRootDicNode);
+ const int *const prevWordIds, DicNode *const newRootDicNode);
static void initAsRootWithPreviousWord(
const DictionaryStructureWithBufferPolicy *const dictionaryStructurePolicy,
const DicNode *const prevWordLastDicNode, DicNode *const newRootDicNode);
diff --git a/native/jni/src/suggest/core/dicnode/internal/dic_node_properties.h b/native/jni/src/suggest/core/dicnode/internal/dic_node_properties.h
index fc242a9..1d905b9 100644
--- a/native/jni/src/suggest/core/dicnode/internal/dic_node_properties.h
+++ b/native/jni/src/suggest/core/dicnode/internal/dic_node_properties.h
@@ -39,7 +39,7 @@
// Should be called only once per DicNode is initialized.
void init(const int pos, const int childrenPos, const int nodeCodePoint, const int probability,
const int wordId, const bool hasChildren, const bool isBlacklistedOrNotAWord,
- const uint16_t depth, const uint16_t leavingDepth, const int *const prevWordsNodePos) {
+ const uint16_t depth, const uint16_t leavingDepth, const int *const prevWordIds) {
mPtNodePos = pos;
mChildrenPtNodeArrayPos = childrenPos;
mDicNodeCodePoint = nodeCodePoint;
@@ -49,11 +49,11 @@
mIsBlacklistedOrNotAWord = isBlacklistedOrNotAWord;
mDepth = depth;
mLeavingDepth = leavingDepth;
- memmove(mPrevWordsTerminalPtNodePos, prevWordsNodePos, sizeof(mPrevWordsTerminalPtNodePos));
+ memmove(mPrevWordIds, prevWordIds, sizeof(mPrevWordIds));
}
// Init for root with prevWordsPtNodePos which is used for n-gram
- void init(const int rootPtNodeArrayPos, const int *const prevWordsNodePos) {
+ void init(const int rootPtNodeArrayPos, const int *const prevWordIds) {
mPtNodePos = NOT_A_DICT_POS;
mChildrenPtNodeArrayPos = rootPtNodeArrayPos;
mDicNodeCodePoint = NOT_A_CODE_POINT;
@@ -63,7 +63,7 @@
mIsBlacklistedOrNotAWord = false;
mDepth = 0;
mLeavingDepth = 0;
- memmove(mPrevWordsTerminalPtNodePos, prevWordsNodePos, sizeof(mPrevWordsTerminalPtNodePos));
+ memmove(mPrevWordIds, prevWordIds, sizeof(mPrevWordIds));
}
void initByCopy(const DicNodeProperties *const dicNodeProp) {
@@ -76,8 +76,7 @@
mIsBlacklistedOrNotAWord = dicNodeProp->mIsBlacklistedOrNotAWord;
mDepth = dicNodeProp->mDepth;
mLeavingDepth = dicNodeProp->mLeavingDepth;
- memmove(mPrevWordsTerminalPtNodePos, dicNodeProp->mPrevWordsTerminalPtNodePos,
- sizeof(mPrevWordsTerminalPtNodePos));
+ memmove(mPrevWordIds, dicNodeProp->mPrevWordIds, sizeof(mPrevWordIds));
}
// Init as passing child
@@ -91,8 +90,7 @@
mIsBlacklistedOrNotAWord = dicNodeProp->mIsBlacklistedOrNotAWord;
mDepth = dicNodeProp->mDepth + 1; // Increment the depth of a passing child
mLeavingDepth = dicNodeProp->mLeavingDepth;
- memmove(mPrevWordsTerminalPtNodePos, dicNodeProp->mPrevWordsTerminalPtNodePos,
- sizeof(mPrevWordsTerminalPtNodePos));
+ memmove(mPrevWordIds, dicNodeProp->mPrevWordIds, sizeof(mPrevWordIds));
}
int getPtNodePos() const {
@@ -132,8 +130,12 @@
return mIsBlacklistedOrNotAWord;
}
- const int *getPrevWordsTerminalPtNodePos() const {
- return mPrevWordsTerminalPtNodePos;
+ const int *getPrevWordIds() const {
+ return mPrevWordIds;
+ }
+
+ int getWordId() const {
+ return mWordId;
}
private:
@@ -149,7 +151,7 @@
bool mIsBlacklistedOrNotAWord;
uint16_t mDepth;
uint16_t mLeavingDepth;
- int mPrevWordsTerminalPtNodePos[MAX_PREV_WORD_COUNT_FOR_N_GRAM];
+ int mPrevWordIds[MAX_PREV_WORD_COUNT_FOR_N_GRAM];
};
} // namespace latinime
#endif // LATINIME_DIC_NODE_PROPERTIES_H
diff --git a/native/jni/src/suggest/core/dictionary/dictionary.cpp b/native/jni/src/suggest/core/dictionary/dictionary.cpp
index c025bfc..9562431 100644
--- a/native/jni/src/suggest/core/dictionary/dictionary.cpp
+++ b/native/jni/src/suggest/core/dictionary/dictionary.cpp
@@ -93,11 +93,10 @@
TimeKeeper::setCurrentTime();
NgramListenerForPrediction listener(prevWordsInfo, outSuggestionResults,
mDictionaryStructureWithBufferPolicy.get());
- int prevWordsPtNodePos[MAX_PREV_WORD_COUNT_FOR_N_GRAM];
- prevWordsInfo->getPrevWordsTerminalPtNodePos(
- mDictionaryStructureWithBufferPolicy.get(), prevWordsPtNodePos,
+ int prevWordIds[MAX_PREV_WORD_COUNT_FOR_N_GRAM];
+ prevWordsInfo->getPrevWordIds(mDictionaryStructureWithBufferPolicy.get(), prevWordIds,
true /* tryLowerCaseSearch */);
- mDictionaryStructureWithBufferPolicy->iterateNgramEntries(prevWordsPtNodePos, &listener);
+ mDictionaryStructureWithBufferPolicy->iterateNgramEntries(prevWordIds, &listener);
}
int Dictionary::getProbability(const int *word, int length) const {
@@ -113,18 +112,17 @@
int Dictionary::getNgramProbability(const PrevWordsInfo *const prevWordsInfo, const int *word,
int length) const {
TimeKeeper::setCurrentTime();
- int nextWordPos = mDictionaryStructureWithBufferPolicy->getTerminalPtNodePositionOfWord(
+ int wordId = mDictionaryStructureWithBufferPolicy->getWordId(
CodePointArrayView(word, length), false /* forceLowerCaseSearch */);
- if (NOT_A_DICT_POS == nextWordPos) return NOT_A_PROBABILITY;
+ if (wordId == NOT_A_WORD_ID) return NOT_A_PROBABILITY;
if (!prevWordsInfo) {
- return getDictionaryStructurePolicy()->getProbabilityOfPtNode(
- nullptr /* prevWordsPtNodePos */, nextWordPos);
+ return getDictionaryStructurePolicy()->getProbabilityOfWord(
+ nullptr /* prevWordsPtNodePos */, wordId);
}
- int prevWordsPtNodePos[MAX_PREV_WORD_COUNT_FOR_N_GRAM];
- prevWordsInfo->getPrevWordsTerminalPtNodePos(
- mDictionaryStructureWithBufferPolicy.get(), prevWordsPtNodePos,
+ int prevWordIds[MAX_PREV_WORD_COUNT_FOR_N_GRAM];
+ prevWordsInfo->getPrevWordIds(mDictionaryStructureWithBufferPolicy.get(), prevWordIds,
true /* tryLowerCaseSearch */);
- return getDictionaryStructurePolicy()->getProbabilityOfPtNode(prevWordsPtNodePos, nextWordPos);
+ return getDictionaryStructurePolicy()->getProbabilityOfWord(prevWordIds, wordId);
}
bool Dictionary::addUnigramEntry(const int *const word, const int length,
diff --git a/native/jni/src/suggest/core/dictionary/dictionary_utils.cpp b/native/jni/src/suggest/core/dictionary/dictionary_utils.cpp
index b94966c..b372b6b 100644
--- a/native/jni/src/suggest/core/dictionary/dictionary_utils.cpp
+++ b/native/jni/src/suggest/core/dictionary/dictionary_utils.cpp
@@ -34,11 +34,11 @@
// No prev words information.
PrevWordsInfo emptyPrevWordsInfo;
- int prevWordsPtNodePos[MAX_PREV_WORD_COUNT_FOR_N_GRAM];
- emptyPrevWordsInfo.getPrevWordsTerminalPtNodePos(dictionaryStructurePolicy,
- prevWordsPtNodePos, false /* tryLowerCaseSearch */);
+ int prevWordIds[MAX_PREV_WORD_COUNT_FOR_N_GRAM];
+ emptyPrevWordsInfo.getPrevWordIds(dictionaryStructurePolicy, prevWordIds,
+ false /* tryLowerCaseSearch */);
current.emplace_back();
- DicNodeUtils::initAsRoot(dictionaryStructurePolicy, prevWordsPtNodePos, ¤t.front());
+ DicNodeUtils::initAsRoot(dictionaryStructurePolicy, prevWordIds, ¤t.front());
for (int i = 0; i < codePointCount; ++i) {
// The base-lower input is used to ignore case errors and accent errors.
const int codePoint = CharUtils::toBaseLowerCase(codePoints[i]);
diff --git a/native/jni/src/suggest/core/dictionary/multi_bigram_map.cpp b/native/jni/src/suggest/core/dictionary/multi_bigram_map.cpp
index 91f33a8..979d61e 100644
--- a/native/jni/src/suggest/core/dictionary/multi_bigram_map.cpp
+++ b/native/jni/src/suggest/core/dictionary/multi_bigram_map.cpp
@@ -35,39 +35,37 @@
// Also caches the bigrams if there is space remaining and they have not been cached already.
int MultiBigramMap::getBigramProbability(
const DictionaryStructureWithBufferPolicy *const structurePolicy,
- const int *const prevWordsPtNodePos, const int nextWordPosition,
+ const int *const prevWordIds, const int nextWordId,
const int unigramProbability) {
- if (!prevWordsPtNodePos || prevWordsPtNodePos[0] == NOT_A_DICT_POS) {
+ if (!prevWordIds || prevWordIds[0] == NOT_A_WORD_ID) {
return structurePolicy->getProbability(unigramProbability, NOT_A_PROBABILITY);
}
- std::unordered_map<int, BigramMap>::const_iterator mapPosition =
- mBigramMaps.find(prevWordsPtNodePos[0]);
+ const auto mapPosition = mBigramMaps.find(prevWordIds[0]);
if (mapPosition != mBigramMaps.end()) {
- return mapPosition->second.getBigramProbability(structurePolicy, nextWordPosition,
+ return mapPosition->second.getBigramProbability(structurePolicy, nextWordId,
unigramProbability);
}
if (mBigramMaps.size() < MAX_CACHED_PREV_WORDS_IN_BIGRAM_MAP) {
- addBigramsForWordPosition(structurePolicy, prevWordsPtNodePos);
- return mBigramMaps[prevWordsPtNodePos[0]].getBigramProbability(structurePolicy,
- nextWordPosition, unigramProbability);
+ addBigramsForWord(structurePolicy, prevWordIds);
+ return mBigramMaps[prevWordIds[0]].getBigramProbability(structurePolicy,
+ nextWordId, unigramProbability);
}
- return readBigramProbabilityFromBinaryDictionary(structurePolicy, prevWordsPtNodePos,
- nextWordPosition, unigramProbability);
+ return readBigramProbabilityFromBinaryDictionary(structurePolicy, prevWordIds,
+ nextWordId, unigramProbability);
}
void MultiBigramMap::BigramMap::init(
const DictionaryStructureWithBufferPolicy *const structurePolicy,
- const int *const prevWordsPtNodePos) {
- structurePolicy->iterateNgramEntries(prevWordsPtNodePos, this /* listener */);
+ const int *const prevWordIds) {
+ structurePolicy->iterateNgramEntries(prevWordIds, this /* listener */);
}
int MultiBigramMap::BigramMap::getBigramProbability(
const DictionaryStructureWithBufferPolicy *const structurePolicy,
- const int nextWordPosition, const int unigramProbability) const {
+ const int nextWordId, const int unigramProbability) const {
int bigramProbability = NOT_A_PROBABILITY;
- if (mBloomFilter.isInFilter(nextWordPosition)) {
- const std::unordered_map<int, int>::const_iterator bigramProbabilityIt =
- mBigramMap.find(nextWordPosition);
+ if (mBloomFilter.isInFilter(nextWordId)) {
+ const auto bigramProbabilityIt = mBigramMap.find(nextWordId);
if (bigramProbabilityIt != mBigramMap.end()) {
bigramProbability = bigramProbabilityIt->second;
}
@@ -75,29 +73,27 @@
return structurePolicy->getProbability(unigramProbability, bigramProbability);
}
-void MultiBigramMap::BigramMap::onVisitEntry(const int ngramProbability,
- const int targetPtNodePos) {
- if (targetPtNodePos == NOT_A_DICT_POS) {
+void MultiBigramMap::BigramMap::onVisitEntry(const int ngramProbability, const int targetWordId) {
+ if (targetWordId == NOT_A_WORD_ID) {
return;
}
- mBigramMap[targetPtNodePos] = ngramProbability;
- mBloomFilter.setInFilter(targetPtNodePos);
+ mBigramMap[targetWordId] = ngramProbability;
+ mBloomFilter.setInFilter(targetWordId);
}
-void MultiBigramMap::addBigramsForWordPosition(
+void MultiBigramMap::addBigramsForWord(
const DictionaryStructureWithBufferPolicy *const structurePolicy,
- const int *const prevWordsPtNodePos) {
- if (prevWordsPtNodePos) {
- mBigramMaps[prevWordsPtNodePos[0]].init(structurePolicy, prevWordsPtNodePos);
+ const int *const prevWordIds) {
+ if (prevWordIds) {
+ mBigramMaps[prevWordIds[0]].init(structurePolicy, prevWordIds);
}
}
int MultiBigramMap::readBigramProbabilityFromBinaryDictionary(
const DictionaryStructureWithBufferPolicy *const structurePolicy,
- const int *const prevWordsPtNodePos, const int nextWordPosition,
+ const int *const prevWordIds, const int nextWordId,
const int unigramProbability) {
- const int bigramProbability = structurePolicy->getProbabilityOfPtNode(prevWordsPtNodePos,
- nextWordPosition);
+ const int bigramProbability = structurePolicy->getProbabilityOfWord(prevWordIds, nextWordId);
if (bigramProbability != NOT_A_PROBABILITY) {
return bigramProbability;
}
diff --git a/native/jni/src/suggest/core/dictionary/multi_bigram_map.h b/native/jni/src/suggest/core/dictionary/multi_bigram_map.h
index ad36dde..a8c4ded 100644
--- a/native/jni/src/suggest/core/dictionary/multi_bigram_map.h
+++ b/native/jni/src/suggest/core/dictionary/multi_bigram_map.h
@@ -39,8 +39,7 @@
// Look up the bigram probability for the given word pair from the cached bigram maps.
// Also caches the bigrams if there is space remaining and they have not been cached already.
int getBigramProbability(const DictionaryStructureWithBufferPolicy *const structurePolicy,
- const int *const prevWordsPtNodePos, const int nextWordPosition,
- const int unigramProbability);
+ const int *const prevWordIds, const int nextWordId, const int unigramProbability);
void clear() {
mBigramMaps.clear();
@@ -58,11 +57,11 @@
virtual ~BigramMap() {}
void init(const DictionaryStructureWithBufferPolicy *const structurePolicy,
- const int *const prevWordsPtNodePos);
+ const int *const prevWordIds);
int getBigramProbability(
const DictionaryStructureWithBufferPolicy *const structurePolicy,
- const int nextWordPosition, const int unigramProbability) const;
- virtual void onVisitEntry(const int ngramProbability, const int targetPtNodePos);
+ const int nextWordId, const int unigramProbability) const;
+ virtual void onVisitEntry(const int ngramProbability, const int targetWordId);
private:
static const int DEFAULT_HASH_MAP_SIZE_FOR_EACH_BIGRAM_MAP;
@@ -70,14 +69,12 @@
BloomFilter mBloomFilter;
};
- void addBigramsForWordPosition(
- const DictionaryStructureWithBufferPolicy *const structurePolicy,
- const int *const prevWordsPtNodePos);
+ void addBigramsForWord(const DictionaryStructureWithBufferPolicy *const structurePolicy,
+ const int *const prevWordIds);
int readBigramProbabilityFromBinaryDictionary(
const DictionaryStructureWithBufferPolicy *const structurePolicy,
- const int *const prevWordsPtNodePos, const int nextWordPosition,
- const int unigramProbability);
+ const int *const prevWordIds, const int nextWordId, const int unigramProbability);
static const size_t MAX_CACHED_PREV_WORDS_IN_BIGRAM_MAP;
std::unordered_map<int, BigramMap> mBigramMaps;
diff --git a/native/jni/src/suggest/core/dictionary/ngram_listener.h b/native/jni/src/suggest/core/dictionary/ngram_listener.h
index 88b88ba..e9b3c1a 100644
--- a/native/jni/src/suggest/core/dictionary/ngram_listener.h
+++ b/native/jni/src/suggest/core/dictionary/ngram_listener.h
@@ -26,7 +26,7 @@
*/
class NgramListener {
public:
- virtual void onVisitEntry(const int ngramProbability, const int targetPtNodePos) = 0;
+ virtual void onVisitEntry(const int ngramProbability, const int targetWordId) = 0;
virtual ~NgramListener() {};
protected:
diff --git a/native/jni/src/suggest/core/layout/geometry_utils.h b/native/jni/src/suggest/core/layout/geometry_utils.h
index b667df6..000fcd4 100644
--- a/native/jni/src/suggest/core/layout/geometry_utils.h
+++ b/native/jni/src/suggest/core/layout/geometry_utils.h
@@ -38,13 +38,15 @@
}
static AK_FORCE_INLINE float getAngleDiff(const float a1, const float a2) {
- const float deltaA = fabsf(a1 - a2);
- const float diff = ROUND_FLOAT_10000(deltaA);
- if (diff > M_PI_F) {
- const float normalizedDiff = 2.0f * M_PI_F - diff;
- return ROUND_FLOAT_10000(normalizedDiff);
+ static const float M_2PI_F = M_PI * 2.0f;
+ float delta = fabsf(a1 - a2);
+ if (delta > M_2PI_F) {
+ delta -= (M_2PI_F * static_cast<int>(delta / M_2PI_F));
}
- return diff;
+ if (delta > M_PI_F) {
+ delta = M_2PI_F - delta;
+ }
+ return ROUND_FLOAT_10000(delta);
}
static AK_FORCE_INLINE int getDistanceInt(const int x1, const int y1, const int x2,
diff --git a/native/jni/src/suggest/core/policy/dictionary_structure_with_buffer_policy.h b/native/jni/src/suggest/core/policy/dictionary_structure_with_buffer_policy.h
index 0faf000..72ec13f 100644
--- a/native/jni/src/suggest/core/policy/dictionary_structure_with_buffer_policy.h
+++ b/native/jni/src/suggest/core/policy/dictionary_structure_with_buffer_policy.h
@@ -53,15 +53,14 @@
const int ptNodePos, const int maxCodePointCount, int *const outCodePoints,
int *const outUnigramProbability) const = 0;
- virtual int getTerminalPtNodePositionOfWord(const CodePointArrayView wordCodePoints,
+ virtual int getWordId(const CodePointArrayView wordCodePoints,
const bool forceLowerCaseSearch) const = 0;
virtual int getProbability(const int unigramProbability, const int bigramProbability) const = 0;
- virtual int getProbabilityOfPtNode(const int *const prevWordsPtNodePos,
- const int ptNodePos) const = 0;
+ virtual int getProbabilityOfWord(const int *const prevWordIds, const int wordId) const = 0;
- virtual void iterateNgramEntries(const int *const prevWordsPtNodePos,
+ virtual void iterateNgramEntries(const int *const prevWordIds,
NgramListener *const listener) const = 0;
virtual int getShortcutPositionOfPtNode(const int ptNodePos) const = 0;
diff --git a/native/jni/src/suggest/core/session/dic_traverse_session.cpp b/native/jni/src/suggest/core/session/dic_traverse_session.cpp
index f1e411f..d4d4d1e 100644
--- a/native/jni/src/suggest/core/session/dic_traverse_session.cpp
+++ b/native/jni/src/suggest/core/session/dic_traverse_session.cpp
@@ -35,8 +35,8 @@
mMultiWordCostMultiplier = getDictionaryStructurePolicy()->getHeaderStructurePolicy()
->getMultiWordCostMultiplier();
mSuggestOptions = suggestOptions;
- prevWordsInfo->getPrevWordsTerminalPtNodePos(
- getDictionaryStructurePolicy(), mPrevWordsPtNodePos, true /* tryLowerCaseSearch */);
+ prevWordsInfo->getPrevWordIds(getDictionaryStructurePolicy(), mPrevWordsIds,
+ true /* tryLowerCaseSearch */);
}
void DicTraverseSession::setupForGetSuggestions(const ProximityInfo *pInfo,
diff --git a/native/jni/src/suggest/core/session/dic_traverse_session.h b/native/jni/src/suggest/core/session/dic_traverse_session.h
index 5a51a11..0e676d8 100644
--- a/native/jni/src/suggest/core/session/dic_traverse_session.h
+++ b/native/jni/src/suggest/core/session/dic_traverse_session.h
@@ -55,8 +55,8 @@
mMultiWordCostMultiplier(1.0f) {
// NOTE: mProximityInfoStates is an array of instances.
// No need to initialize it explicitly here.
- for (size_t i = 0; i < NELEMS(mPrevWordsPtNodePos); ++i) {
- mPrevWordsPtNodePos[i] = NOT_A_DICT_POS;
+ for (size_t i = 0; i < NELEMS(mPrevWordsIds); ++i) {
+ mPrevWordsIds[i] = NOT_A_DICT_POS;
}
}
@@ -79,7 +79,7 @@
//--------------------
const ProximityInfo *getProximityInfo() const { return mProximityInfo; }
const SuggestOptions *getSuggestOptions() const { return mSuggestOptions; }
- const int *getPrevWordsPtNodePos() const { return mPrevWordsPtNodePos; }
+ const int *getPrevWordIds() const { return mPrevWordsIds; }
DicNodesCache *getDicTraverseCache() { return &mDicNodesCache; }
MultiBigramMap *getMultiBigramMap() { return &mMultiBigramMap; }
const ProximityInfoState *getProximityInfoState(int id) const {
@@ -166,7 +166,7 @@
const int *const inputYs, const int *const times, const int *const pointerIds,
const int inputSize, const float maxSpatialDistance, const int maxPointerCount);
- int mPrevWordsPtNodePos[MAX_PREV_WORD_COUNT_FOR_N_GRAM];
+ int mPrevWordsIds[MAX_PREV_WORD_COUNT_FOR_N_GRAM];
const ProximityInfo *mProximityInfo;
const Dictionary *mDictionary;
const SuggestOptions *mSuggestOptions;
diff --git a/native/jni/src/suggest/core/session/prev_words_info.h b/native/jni/src/suggest/core/session/prev_words_info.h
index 9b3a7d4..fc9a359 100644
--- a/native/jni/src/suggest/core/session/prev_words_info.h
+++ b/native/jni/src/suggest/core/session/prev_words_info.h
@@ -18,14 +18,12 @@
#define LATINIME_PREV_WORDS_INFO_H
#include "defines.h"
-#include "suggest/core/dictionary/binary_dictionary_bigrams_iterator.h"
#include "suggest/core/policy/dictionary_structure_with_buffer_policy.h"
#include "utils/char_utils.h"
#include "utils/int_array_view.h"
namespace latinime {
-// TODO: Support n-gram.
class PrevWordsInfo {
public:
// No prev word information.
@@ -81,11 +79,10 @@
return false;
}
- void getPrevWordsTerminalPtNodePos(
- const DictionaryStructureWithBufferPolicy *const dictStructurePolicy,
- int *const outPrevWordsTerminalPtNodePos, const bool tryLowerCaseSearch) const {
+ void getPrevWordIds(const DictionaryStructureWithBufferPolicy *const dictStructurePolicy,
+ int *const outPrevWordIds, const bool tryLowerCaseSearch) const {
for (size_t i = 0; i < NELEMS(mPrevWordCodePoints); ++i) {
- outPrevWordsTerminalPtNodePos[i] = getTerminalPtNodePosOfWord(dictStructurePolicy,
+ outPrevWordIds[i] = getWordId(dictStructurePolicy,
mPrevWordCodePoints[i], mPrevWordCodePointCount[i],
mIsBeginningOfSentence[i], tryLowerCaseSearch);
}
@@ -110,12 +107,11 @@
private:
DISALLOW_COPY_AND_ASSIGN(PrevWordsInfo);
- static int getTerminalPtNodePosOfWord(
- const DictionaryStructureWithBufferPolicy *const dictStructurePolicy,
+ static int getWordId(const DictionaryStructureWithBufferPolicy *const dictStructurePolicy,
const int *const wordCodePoints, const int wordCodePointCount,
const bool isBeginningOfSentence, const bool tryLowerCaseSearch) {
if (!dictStructurePolicy || !wordCodePoints || wordCodePointCount > MAX_WORD_LENGTH) {
- return NOT_A_DICT_POS;
+ return NOT_A_WORD_ID;
}
int codePoints[MAX_WORD_LENGTH];
int codePointCount = wordCodePointCount;
@@ -124,21 +120,19 @@
codePointCount = CharUtils::attachBeginningOfSentenceMarker(codePoints,
codePointCount, MAX_WORD_LENGTH);
if (codePointCount <= 0) {
- return NOT_A_DICT_POS;
+ return NOT_A_WORD_ID;
}
}
const CodePointArrayView codePointArrayView(codePoints, codePointCount);
- const int wordPtNodePos = dictStructurePolicy->getTerminalPtNodePositionOfWord(
+ const int wordId = dictStructurePolicy->getWordId(
codePointArrayView, false /* forceLowerCaseSearch */);
- if (wordPtNodePos != NOT_A_DICT_POS || !tryLowerCaseSearch) {
- // Return the position when when the word was found or doesn't try lower case
- // search.
- return wordPtNodePos;
+ if (wordId != NOT_A_WORD_ID || !tryLowerCaseSearch) {
+ // Return the id when when the word was found or doesn't try lower case search.
+ return wordId;
}
// Check bigrams for lower-cased previous word if original was not found. Useful for
// auto-capitalized words like "The [current_word]".
- return dictStructurePolicy->getTerminalPtNodePositionOfWord(
- codePointArrayView, true /* forceLowerCaseSearch */);
+ return dictStructurePolicy->getWordId(codePointArrayView, true /* forceLowerCaseSearch */);
}
void clear() {
diff --git a/native/jni/src/suggest/core/suggest.cpp b/native/jni/src/suggest/core/suggest.cpp
index 0cd305f..66c87f0 100644
--- a/native/jni/src/suggest/core/suggest.cpp
+++ b/native/jni/src/suggest/core/suggest.cpp
@@ -92,7 +92,7 @@
// Create a new dic node here
DicNode rootNode;
DicNodeUtils::initAsRoot(traverseSession->getDictionaryStructurePolicy(),
- traverseSession->getPrevWordsPtNodePos(), &rootNode);
+ traverseSession->getPrevWordIds(), &rootNode);
traverseSession->getDicTraverseCache()->copyPushActive(&rootNode);
}
}
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.cpp
index 9f6ae11..5dff1fc 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.cpp
@@ -104,7 +104,7 @@
return codePointCount;
}
-int Ver4PatriciaTriePolicy::getTerminalPtNodePositionOfWord(const CodePointArrayView wordCodePoints,
+int Ver4PatriciaTriePolicy::getWordId(const CodePointArrayView wordCodePoints,
const bool forceLowerCaseSearch) const {
DynamicPtReadingHelper readingHelper(&mNodeReader, &mPtNodeArrayReader);
readingHelper.initWithPtNodeArrayPos(getRootPosition());
@@ -112,9 +112,9 @@
wordCodePoints.size(), forceLowerCaseSearch);
if (readingHelper.isError()) {
mIsCorrupted = true;
- AKLOGE("Dictionary reading error in createAndGetAllChildDicNodes().");
+ AKLOGE("Dictionary reading error in getWordId().");
}
- return ptNodePos;
+ return getWordIdFromTerminalPtNodePos(ptNodePos);
}
int Ver4PatriciaTriePolicy::getProbability(const int unigramProbability,
@@ -133,17 +133,19 @@
}
}
-int Ver4PatriciaTriePolicy::getProbabilityOfPtNode(const int *const prevWordsPtNodePos,
- const int ptNodePos) const {
- if (ptNodePos == NOT_A_DICT_POS) {
+int Ver4PatriciaTriePolicy::getProbabilityOfWord(const int *const prevWordIds,
+ const int wordId) const {
+ if (wordId == NOT_A_WORD_ID) {
return NOT_A_PROBABILITY;
}
+ const int ptNodePos = getTerminalPtNodePosFromWordId(wordId);
const PtNodeParams ptNodeParams(mNodeReader.fetchPtNodeParamsInBufferFromPtNodePos(ptNodePos));
if (ptNodeParams.isDeleted() || ptNodeParams.isBlacklisted() || ptNodeParams.isNotAWord()) {
return NOT_A_PROBABILITY;
}
- if (prevWordsPtNodePos) {
- const int bigramsPosition = getBigramsPositionOfPtNode(prevWordsPtNodePos[0]);
+ if (prevWordIds) {
+ const int bigramsPosition = getBigramsPositionOfPtNode(
+ getTerminalPtNodePosFromWordId(prevWordIds[0]));
BinaryDictionaryBigramsIterator bigramsIt(&mBigramPolicy, bigramsPosition);
while (bigramsIt.hasNext()) {
bigramsIt.next();
@@ -157,16 +159,18 @@
return getProbability(ptNodeParams.getProbability(), NOT_A_PROBABILITY);
}
-void Ver4PatriciaTriePolicy::iterateNgramEntries(const int *const prevWordsPtNodePos,
+void Ver4PatriciaTriePolicy::iterateNgramEntries(const int *const prevWordIds,
NgramListener *const listener) const {
- if (!prevWordsPtNodePos) {
+ if (!prevWordIds) {
return;
}
- const int bigramsPosition = getBigramsPositionOfPtNode(prevWordsPtNodePos[0]);
+ const int bigramsPosition = getBigramsPositionOfPtNode(
+ getTerminalPtNodePosFromWordId(prevWordIds[0]));
BinaryDictionaryBigramsIterator bigramsIt(&mBigramPolicy, bigramsPosition);
while (bigramsIt.hasNext()) {
bigramsIt.next();
- listener->onVisitEntry(bigramsIt.getProbability(), bigramsIt.getBigramPos());
+ listener->onVisitEntry(bigramsIt.getProbability(),
+ getWordIdFromTerminalPtNodePos(bigramsIt.getBigramPos()));
}
}
@@ -238,8 +242,8 @@
}
if (unigramProperty->getShortcuts().size() > 0) {
// Add shortcut target.
- const int wordPos = getTerminalPtNodePositionOfWord(codePointArrayView,
- false /* forceLowerCaseSearch */);
+ const int wordPos = getTerminalPtNodePosFromWordId(
+ getWordId(codePointArrayView, false /* forceLowerCaseSearch */));
if (wordPos == NOT_A_DICT_POS) {
AKLOGE("Cannot find terminal PtNode position to add shortcut target.");
return false;
@@ -266,8 +270,8 @@
AKLOGI("Warning: removeUnigramEntry() is called for non-updatable dictionary.");
return false;
}
- const int ptNodePos = getTerminalPtNodePositionOfWord(wordCodePoints,
- false /* forceLowerCaseSearch */);
+ const int ptNodePos = getTerminalPtNodePosFromWordId(
+ getWordId(wordCodePoints, false /* forceLowerCaseSearch */));
if (ptNodePos == NOT_A_DICT_POS) {
return false;
}
@@ -295,11 +299,9 @@
"length: %zd", bigramProperty->getTargetCodePoints()->size());
return false;
}
- int prevWordsPtNodePos[MAX_PREV_WORD_COUNT_FOR_N_GRAM];
- prevWordsInfo->getPrevWordsTerminalPtNodePos(this, prevWordsPtNodePos,
- false /* tryLowerCaseSearch */);
- // TODO: Support N-gram.
- if (prevWordsPtNodePos[0] == NOT_A_DICT_POS) {
+ int prevWordIds[MAX_PREV_WORD_COUNT_FOR_N_GRAM];
+ prevWordsInfo->getPrevWordIds(this, prevWordIds, false /* tryLowerCaseSearch */);
+ if (prevWordIds[0] == NOT_A_WORD_ID) {
if (prevWordsInfo->isNthPrevWordBeginningOfSentence(1 /* n */)) {
const std::vector<UnigramProperty::ShortcutProperty> shortcuts;
const UnigramProperty beginningOfSentenceUnigramProperty(
@@ -311,22 +313,22 @@
AKLOGE("Cannot add unigram entry for the beginning-of-sentence.");
return false;
}
- // Refresh Terminal PtNode positions.
- prevWordsInfo->getPrevWordsTerminalPtNodePos(this, prevWordsPtNodePos,
- false /* tryLowerCaseSearch */);
+ // Refresh word ids.
+ prevWordsInfo->getPrevWordIds(this, prevWordIds, false /* tryLowerCaseSearch */);
} else {
return false;
}
}
- const int word1Pos = getTerminalPtNodePositionOfWord(
+ const int wordPos = getTerminalPtNodePosFromWordId(getWordId(
CodePointArrayView(*bigramProperty->getTargetCodePoints()),
- false /* forceLowerCaseSearch */);
- if (word1Pos == NOT_A_DICT_POS) {
+ false /* forceLowerCaseSearch */));
+ if (wordPos == NOT_A_DICT_POS) {
return false;
}
bool addedNewBigram = false;
- if (mUpdatingHelper.addNgramEntry(PtNodePosArrayView::fromObject(prevWordsPtNodePos),
- word1Pos, bigramProperty, &addedNewBigram)) {
+ const int prevWordPtNodePos = getTerminalPtNodePosFromWordId(prevWordIds[0]);
+ if (mUpdatingHelper.addNgramEntry(PtNodePosArrayView::fromObject(&prevWordPtNodePos),
+ wordPos, bigramProperty, &addedNewBigram)) {
if (addedNewBigram) {
mBigramCount++;
}
@@ -355,20 +357,19 @@
AKLOGE("word is too long to remove n-gram entry form the dictionary. length: %zd",
wordCodePoints.size());
}
- int prevWordsPtNodePos[MAX_PREV_WORD_COUNT_FOR_N_GRAM];
- prevWordsInfo->getPrevWordsTerminalPtNodePos(this, prevWordsPtNodePos,
- false /* tryLowerCaseSerch */);
- // TODO: Support N-gram.
- if (prevWordsPtNodePos[0] == NOT_A_DICT_POS) {
+ int prevWordIds[MAX_PREV_WORD_COUNT_FOR_N_GRAM];
+ prevWordsInfo->getPrevWordIds(this, prevWordIds, false /* tryLowerCaseSerch */);
+ if (prevWordIds[0] == NOT_A_WORD_ID) {
return false;
}
- const int wordPos = getTerminalPtNodePositionOfWord(wordCodePoints,
- false /* forceLowerCaseSearch */);
+ const int wordPos = getTerminalPtNodePosFromWordId(getWordId(wordCodePoints,
+ false /* forceLowerCaseSearch */));
if (wordPos == NOT_A_DICT_POS) {
return false;
}
+ const int prevWordPtNodePos = getTerminalPtNodePosFromWordId(prevWordIds[0]);
if (mUpdatingHelper.removeNgramEntry(
- PtNodePosArrayView::fromObject(prevWordsPtNodePos), wordPos)) {
+ PtNodePosArrayView::fromObject(&prevWordPtNodePos), wordPos)) {
mBigramCount--;
return true;
} else {
@@ -449,8 +450,8 @@
const WordProperty Ver4PatriciaTriePolicy::getWordProperty(
const CodePointArrayView wordCodePoints) const {
- const int ptNodePos = getTerminalPtNodePositionOfWord(wordCodePoints,
- false /* forceLowerCaseSearch */);
+ const int ptNodePos = getTerminalPtNodePosFromWordId(
+ getWordId(wordCodePoints, false /* forceLowerCaseSearch */));
if (ptNodePos == NOT_A_DICT_POS) {
AKLOGE("getWordProperty is called for invalid word.");
return WordProperty();
@@ -553,6 +554,14 @@
return nextToken;
}
+int Ver4PatriciaTriePolicy::getWordIdFromTerminalPtNodePos(const int ptNodePos) const {
+ return ptNodePos == NOT_A_DICT_POS ? NOT_A_WORD_ID : ptNodePos;
+}
+
+int Ver4PatriciaTriePolicy::getTerminalPtNodePosFromWordId(const int wordId) const {
+ return wordId == NOT_A_WORD_ID ? NOT_A_DICT_POS : wordId;
+}
+
} // namespace v402
} // namespace backward
} // namespace latinime
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.h b/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.h
index df119e3..508a46c 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.h
@@ -28,6 +28,7 @@
#include <vector>
#include "defines.h"
+#include "suggest/core/dictionary/binary_dictionary_bigrams_iterator.h"
#include "suggest/core/policy/dictionary_structure_with_buffer_policy.h"
#include "suggest/policyimpl/dictionary/header/header_policy.h"
#include "suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_updating_helper.h"
@@ -87,15 +88,13 @@
const int terminalPtNodePos, const int maxCodePointCount, int *const outCodePoints,
int *const outUnigramProbability) const;
- int getTerminalPtNodePositionOfWord(const CodePointArrayView wordCodePoints,
- const bool forceLowerCaseSearch) const;
+ int getWordId(const CodePointArrayView wordCodePoints, const bool forceLowerCaseSearch) const;
int getProbability(const int unigramProbability, const int bigramProbability) const;
- int getProbabilityOfPtNode(const int *const prevWordsPtNodePos, const int ptNodePos) const;
+ int getProbabilityOfWord(const int *const prevWordIds, const int wordId) const;
- void iterateNgramEntries(const int *const prevWordsPtNodePos,
- NgramListener *const listener) const;
+ void iterateNgramEntries(const int *const prevWordIds, NgramListener *const listener) const;
int getShortcutPositionOfPtNode(const int ptNodePos) const;
@@ -164,6 +163,8 @@
mutable bool mIsCorrupted;
int getBigramsPositionOfPtNode(const int ptNodePos) const;
+ int getWordIdFromTerminalPtNodePos(const int ptNodePos) const;
+ int getTerminalPtNodePosFromWordId(const int wordId) const;
};
} // namespace v402
} // namespace backward
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.cpp
index 4ac366e..85971f1 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.cpp
@@ -267,8 +267,8 @@
}
// This function gets the position of the terminal PtNode of the exact matching word in the
-// dictionary. If no match is found, it returns NOT_A_DICT_POS.
-int PatriciaTriePolicy::getTerminalPtNodePositionOfWord(const CodePointArrayView wordCodePoints,
+// dictionary. If no match is found, it returns NOT_A_WORD_ID.
+int PatriciaTriePolicy::getWordId(const CodePointArrayView wordCodePoints,
const bool forceLowerCaseSearch) const {
DynamicPtReadingHelper readingHelper(&mPtNodeReader, &mPtNodeArrayReader);
readingHelper.initWithPtNodeArrayPos(getRootPosition());
@@ -276,9 +276,9 @@
wordCodePoints.size(), forceLowerCaseSearch);
if (readingHelper.isError()) {
mIsCorrupted = true;
- AKLOGE("Dictionary reading error in createAndGetAllChildDicNodes().");
+ AKLOGE("Dictionary reading error in getWordId().");
}
- return ptNodePos;
+ return getWordIdFromTerminalPtNodePos(ptNodePos);
}
int PatriciaTriePolicy::getProbability(const int unigramProbability,
@@ -297,11 +297,11 @@
}
}
-int PatriciaTriePolicy::getProbabilityOfPtNode(const int *const prevWordsPtNodePos,
- const int ptNodePos) const {
- if (ptNodePos == NOT_A_DICT_POS) {
+int PatriciaTriePolicy::getProbabilityOfWord(const int *const prevWordIds, const int wordId) const {
+ if (wordId == NOT_A_WORD_ID) {
return NOT_A_PROBABILITY;
}
+ const int ptNodePos = getTerminalPtNodePosFromWordId(wordId);
const PtNodeParams ptNodeParams =
mPtNodeReader.fetchPtNodeParamsInBufferFromPtNodePos(ptNodePos);
if (ptNodeParams.isNotAWord() || ptNodeParams.isBlacklisted()) {
@@ -310,8 +310,9 @@
// for shortcuts).
return NOT_A_PROBABILITY;
}
- if (prevWordsPtNodePos) {
- const int bigramsPosition = getBigramsPositionOfPtNode(prevWordsPtNodePos[0]);
+ if (prevWordIds) {
+ const int bigramsPosition = getBigramsPositionOfPtNode(
+ getTerminalPtNodePosFromWordId(prevWordIds[0]));
BinaryDictionaryBigramsIterator bigramsIt(&mBigramListPolicy, bigramsPosition);
while (bigramsIt.hasNext()) {
bigramsIt.next();
@@ -325,16 +326,18 @@
return getProbability(ptNodeParams.getProbability(), NOT_A_PROBABILITY);
}
-void PatriciaTriePolicy::iterateNgramEntries(const int *const prevWordsPtNodePos,
+void PatriciaTriePolicy::iterateNgramEntries(const int *const prevWordIds,
NgramListener *const listener) const {
- if (!prevWordsPtNodePos) {
+ if (!prevWordIds) {
return;
}
- const int bigramsPosition = getBigramsPositionOfPtNode(prevWordsPtNodePos[0]);
+ const int bigramsPosition = getBigramsPositionOfPtNode(
+ getTerminalPtNodePosFromWordId(prevWordIds[0]));
BinaryDictionaryBigramsIterator bigramsIt(&mBigramListPolicy, bigramsPosition);
while (bigramsIt.hasNext()) {
bigramsIt.next();
- listener->onVisitEntry(bigramsIt.getProbability(), bigramsIt.getBigramPos());
+ listener->onVisitEntry(bigramsIt.getProbability(),
+ getWordIdFromTerminalPtNodePos(bigramsIt.getBigramPos()));
}
}
@@ -379,12 +382,12 @@
const WordProperty PatriciaTriePolicy::getWordProperty(
const CodePointArrayView wordCodePoints) const {
- const int ptNodePos = getTerminalPtNodePositionOfWord(wordCodePoints,
- false /* forceLowerCaseSearch */);
- if (ptNodePos == NOT_A_DICT_POS) {
+ const int wordId = getWordId(wordCodePoints, false /* forceLowerCaseSearch */);
+ if (wordId == NOT_A_WORD_ID) {
AKLOGE("getWordProperty was called for invalid word.");
return WordProperty();
}
+ const int ptNodePos = getTerminalPtNodePosFromWordId(wordId);
const PtNodeParams ptNodeParams =
mPtNodeReader.fetchPtNodeParamsInBufferFromPtNodePos(ptNodePos);
std::vector<int> codePointVector(ptNodeParams.getCodePoints(),
@@ -467,4 +470,11 @@
return nextToken;
}
+int PatriciaTriePolicy::getWordIdFromTerminalPtNodePos(const int ptNodePos) const {
+ return ptNodePos == NOT_A_DICT_POS ? NOT_A_WORD_ID : ptNodePos;
+}
+
+int PatriciaTriePolicy::getTerminalPtNodePosFromWordId(const int wordId) const {
+ return wordId == NOT_A_WORD_ID ? NOT_A_DICT_POS : wordId;
+}
} // namespace latinime
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.h
index 4d9af28..31fee77 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.h
@@ -64,15 +64,13 @@
const int terminalNodePos, const int maxCodePointCount, int *const outCodePoints,
int *const outUnigramProbability) const;
- int getTerminalPtNodePositionOfWord(const CodePointArrayView wordCodePoints,
- const bool forceLowerCaseSearch) const;
+ int getWordId(const CodePointArrayView wordCodePoints, const bool forceLowerCaseSearch) const;
int getProbability(const int unigramProbability, const int bigramProbability) const;
- int getProbabilityOfPtNode(const int *const prevWordsPtNodePos, const int ptNodePos) const;
+ int getProbabilityOfWord(const int *const prevWordIds, const int wordId) const;
- void iterateNgramEntries(const int *const prevWordsPtNodePos,
- NgramListener *const listener) const;
+ void iterateNgramEntries(const int *const prevWordIds, NgramListener *const listener) const;
int getShortcutPositionOfPtNode(const int ptNodePos) const;
@@ -163,6 +161,8 @@
int getBigramsPositionOfPtNode(const int ptNodePos) const;
int createAndGetLeavingChildNode(const DicNode *const dicNode, const int ptNodePos,
DicNodeVector *const childDicNodes) const;
+ int getWordIdFromTerminalPtNodePos(const int ptNodePos) const;
+ int getTerminalPtNodePosFromWordId(const int wordId) const;
};
} // namespace latinime
#endif // LATINIME_PATRICIA_TRIE_POLICY_H
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.cpp
index 619cdb5..7024682 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.cpp
@@ -94,7 +94,7 @@
return codePointCount;
}
-int Ver4PatriciaTriePolicy::getTerminalPtNodePositionOfWord(const CodePointArrayView wordCodePoints,
+int Ver4PatriciaTriePolicy::getWordId(const CodePointArrayView wordCodePoints,
const bool forceLowerCaseSearch) const {
DynamicPtReadingHelper readingHelper(&mNodeReader, &mPtNodeArrayReader);
readingHelper.initWithPtNodeArrayPos(getRootPosition());
@@ -104,7 +104,11 @@
mIsCorrupted = true;
AKLOGE("Dictionary reading error in createAndGetAllChildDicNodes().");
}
- return ptNodePos;
+ if (ptNodePos == NOT_A_DICT_POS) {
+ return NOT_A_WORD_ID;
+ }
+ const PtNodeParams ptNodeParams = mNodeReader.fetchPtNodeParamsInBufferFromPtNodePos(ptNodePos);
+ return ptNodeParams.getTerminalId();
}
int Ver4PatriciaTriePolicy::getProbability(const int unigramProbability,
@@ -123,24 +127,22 @@
}
}
-int Ver4PatriciaTriePolicy::getProbabilityOfPtNode(const int *const prevWordsPtNodePos,
- const int ptNodePos) const {
- if (ptNodePos == NOT_A_DICT_POS) {
+int Ver4PatriciaTriePolicy::getProbabilityOfWord(const int *const prevWordIds,
+ const int wordId) const {
+ if (wordId == NOT_A_WORD_ID) {
return NOT_A_PROBABILITY;
}
+ const int ptNodePos =
+ mBuffers->getTerminalPositionLookupTable()->getTerminalPtNodePosition(wordId);
const PtNodeParams ptNodeParams = mNodeReader.fetchPtNodeParamsInBufferFromPtNodePos(ptNodePos);
if (ptNodeParams.isDeleted() || ptNodeParams.isBlacklisted() || ptNodeParams.isNotAWord()) {
return NOT_A_PROBABILITY;
}
- if (prevWordsPtNodePos) {
+ if (prevWordIds) {
// TODO: Support n-gram.
- const PtNodeParams prevWordPtNodeParams =
- mNodeReader.fetchPtNodeParamsInBufferFromPtNodePos(prevWordsPtNodePos[0]);
- const int prevWordTerminalId = prevWordPtNodeParams.getTerminalId();
const ProbabilityEntry probabilityEntry =
mBuffers->getLanguageModelDictContent()->getNgramProbabilityEntry(
- IntArrayView::fromObject(&prevWordTerminalId),
- ptNodeParams.getTerminalId());
+ IntArrayView::fromObject(prevWordIds), wordId);
if (!probabilityEntry.isValid()) {
return NOT_A_PROBABILITY;
}
@@ -154,26 +156,21 @@
return getProbability(ptNodeParams.getProbability(), NOT_A_PROBABILITY);
}
-void Ver4PatriciaTriePolicy::iterateNgramEntries(const int *const prevWordsPtNodePos,
+void Ver4PatriciaTriePolicy::iterateNgramEntries(const int *const prevWordIds,
NgramListener *const listener) const {
- if (!prevWordsPtNodePos) {
+ if (!prevWordIds) {
return;
}
// TODO: Support n-gram.
- const PtNodeParams ptNodeParams =
- mNodeReader.fetchPtNodeParamsInBufferFromPtNodePos(prevWordsPtNodePos[0]);
- const int prevWordId = ptNodeParams.getTerminalId();
- const WordIdArrayView prevWordIds = WordIdArrayView::fromObject(&prevWordId);
const auto languageModelDictContent = mBuffers->getLanguageModelDictContent();
- for (const auto entry : languageModelDictContent->getProbabilityEntries(prevWordIds)) {
+ for (const auto entry : languageModelDictContent->getProbabilityEntries(
+ WordIdArrayView::fromObject(prevWordIds))) {
const ProbabilityEntry &probabilityEntry = entry.getProbabilityEntry();
const int probability = probabilityEntry.hasHistoricalInfo() ?
ForgettingCurveUtils::decodeProbability(
probabilityEntry.getHistoricalInfo(), mHeaderPolicy) :
probabilityEntry.getProbability();
- const int ptNodePos = mBuffers->getTerminalPositionLookupTable()->getTerminalPtNodePosition(
- entry.getWordId());
- listener->onVisitEntry(probability, ptNodePos);
+ listener->onVisitEntry(probability, entry.getWordId());
}
}
@@ -233,12 +230,13 @@
}
if (unigramProperty->getShortcuts().size() > 0) {
// Add shortcut target.
- const int wordPos = getTerminalPtNodePositionOfWord(codePointArrayView,
- false /* forceLowerCaseSearch */);
- if (wordPos == NOT_A_DICT_POS) {
- AKLOGE("Cannot find terminal PtNode position to add shortcut target.");
+ const int wordId = getWordId(codePointArrayView, false /* forceLowerCaseSearch */);
+ if (wordId == NOT_A_WORD_ID) {
+ AKLOGE("Cannot find word id to add shortcut target.");
return false;
}
+ const int wordPos =
+ mBuffers->getTerminalPositionLookupTable()->getTerminalPtNodePosition(wordId);
for (const auto &shortcut : unigramProperty->getShortcuts()) {
if (!mUpdatingHelper.addShortcutTarget(wordPos,
shortcut.getTargetCodePoints()->data(),
@@ -261,20 +259,19 @@
AKLOGI("Warning: removeUnigramEntry() is called for non-updatable dictionary.");
return false;
}
- const int ptNodePos = getTerminalPtNodePositionOfWord(wordCodePoints,
- false /* forceLowerCaseSearch */);
- if (ptNodePos == NOT_A_DICT_POS) {
+ const int wordId = getWordId(wordCodePoints, false /* forceLowerCaseSearch */);
+ if (wordId == NOT_A_WORD_ID) {
return false;
}
+ const int ptNodePos =
+ mBuffers->getTerminalPositionLookupTable()->getTerminalPtNodePosition(wordId);
const PtNodeParams ptNodeParams = mNodeReader.fetchPtNodeParamsInBufferFromPtNodePos(ptNodePos);
if (!mNodeWriter.markPtNodeAsDeleted(&ptNodeParams)) {
AKLOGE("Cannot remove unigram. ptNodePos: %d", ptNodePos);
return false;
}
- if (!mBuffers->getMutableLanguageModelDictContent()->removeProbabilityEntry(
- ptNodeParams.getTerminalId())) {
- // TODO: Uncomment.
- // return false;
+ if (!mBuffers->getMutableLanguageModelDictContent()->removeProbabilityEntry(wordId)) {
+ return false;
}
if (!ptNodeParams.representsNonWordInfo()) {
mUnigramCount--;
@@ -302,12 +299,10 @@
"length: %zd", bigramProperty->getTargetCodePoints()->size());
return false;
}
- int prevWordsPtNodePos[MAX_PREV_WORD_COUNT_FOR_N_GRAM];
- prevWordsInfo->getPrevWordsTerminalPtNodePos(this, prevWordsPtNodePos,
- false /* tryLowerCaseSearch */);
- const auto prevWordsPtNodePosView = PtNodePosArrayView::fromFixedSizeArray(prevWordsPtNodePos);
+ int prevWordIds[MAX_PREV_WORD_COUNT_FOR_N_GRAM];
+ prevWordsInfo->getPrevWordIds(this, prevWordIds, false /* tryLowerCaseSearch */);
// TODO: Support N-gram.
- if (prevWordsPtNodePos[0] == NOT_A_DICT_POS) {
+ if (prevWordIds[0] == NOT_A_WORD_ID) {
if (prevWordsInfo->isNthPrevWordBeginningOfSentence(1 /* n */)) {
const std::vector<UnigramProperty::ShortcutProperty> shortcuts;
const UnigramProperty beginningOfSentenceUnigramProperty(
@@ -319,22 +314,27 @@
AKLOGE("Cannot add unigram entry for the beginning-of-sentence.");
return false;
}
- // Refresh Terminal PtNode positions.
- prevWordsInfo->getPrevWordsTerminalPtNodePos(this, prevWordsPtNodePos,
- false /* tryLowerCaseSearch */);
+ // Refresh word ids.
+ prevWordsInfo->getPrevWordIds(this, prevWordIds, false /* tryLowerCaseSearch */);
} else {
return false;
}
}
- const int word1Pos = getTerminalPtNodePositionOfWord(
- CodePointArrayView(*bigramProperty->getTargetCodePoints()),
+ const int wordId = getWordId(CodePointArrayView(*bigramProperty->getTargetCodePoints()),
false /* forceLowerCaseSearch */);
- if (word1Pos == NOT_A_DICT_POS) {
+ if (wordId == NOT_A_WORD_ID) {
return false;
}
bool addedNewEntry = false;
- if (mUpdatingHelper.addNgramEntry(prevWordsPtNodePosView, word1Pos, bigramProperty,
- &addedNewEntry)) {
+ int prevWordsPtNodePos[MAX_PREV_WORD_COUNT_FOR_N_GRAM];
+ for (size_t i = 0; i < NELEMS(prevWordIds); ++i) {
+ prevWordsPtNodePos[i] = mBuffers->getTerminalPositionLookupTable()
+ ->getTerminalPtNodePosition(prevWordIds[i]);
+ }
+ const int wordPtNodePos = mBuffers->getTerminalPositionLookupTable()
+ ->getTerminalPtNodePosition(wordId);
+ if (mUpdatingHelper.addNgramEntry(WordIdArrayView::fromFixedSizeArray(prevWordsPtNodePos),
+ wordPtNodePos, bigramProperty, &addedNewEntry)) {
if (addedNewEntry) {
mBigramCount++;
}
@@ -363,20 +363,25 @@
AKLOGE("word is too long to remove n-gram entry form the dictionary. length: %zd",
wordCodePoints.size());
}
- int prevWordsPtNodePos[MAX_PREV_WORD_COUNT_FOR_N_GRAM];
- prevWordsInfo->getPrevWordsTerminalPtNodePos(this, prevWordsPtNodePos,
- false /* tryLowerCaseSerch */);
- const auto prevWordsPtNodePosView = PtNodePosArrayView::fromFixedSizeArray(prevWordsPtNodePos);
+ int prevWordIds[MAX_PREV_WORD_COUNT_FOR_N_GRAM];
+ prevWordsInfo->getPrevWordIds(this, prevWordIds, false /* tryLowerCaseSerch */);
// TODO: Support N-gram.
- if (prevWordsPtNodePos[0] == NOT_A_DICT_POS) {
+ if (prevWordIds[0] == NOT_A_WORD_ID) {
return false;
}
- const int wordPos = getTerminalPtNodePositionOfWord(wordCodePoints,
- false /* forceLowerCaseSearch */);
- if (wordPos == NOT_A_DICT_POS) {
+ const int wordId = getWordId(wordCodePoints, false /* forceLowerCaseSearch */);
+ if (wordId == NOT_A_WORD_ID) {
return false;
}
- if (mUpdatingHelper.removeNgramEntry(prevWordsPtNodePosView, wordPos)) {
+ int prevWordsPtNodePos[MAX_PREV_WORD_COUNT_FOR_N_GRAM];
+ for (size_t i = 0; i < NELEMS(prevWordIds); ++i) {
+ prevWordsPtNodePos[i] = mBuffers->getTerminalPositionLookupTable()
+ ->getTerminalPtNodePosition(prevWordIds[i]);
+ }
+ const int wordPtNodePos = mBuffers->getTerminalPositionLookupTable()
+ ->getTerminalPtNodePosition(wordId);
+ if (mUpdatingHelper.removeNgramEntry(WordIdArrayView::fromFixedSizeArray(prevWordsPtNodePos),
+ wordPtNodePos)) {
mBigramCount--;
return true;
} else {
@@ -457,12 +462,13 @@
const WordProperty Ver4PatriciaTriePolicy::getWordProperty(
const CodePointArrayView wordCodePoints) const {
- const int ptNodePos = getTerminalPtNodePositionOfWord(wordCodePoints,
- false /* forceLowerCaseSearch */);
- if (ptNodePos == NOT_A_DICT_POS) {
+ const int wordId = getWordId(wordCodePoints, false /* forceLowerCaseSearch */);
+ if (wordId == NOT_A_WORD_ID) {
AKLOGE("getWordProperty is called for invalid word.");
return WordProperty();
}
+ const int ptNodePos =
+ mBuffers->getTerminalPositionLookupTable()->getTerminalPtNodePosition(wordId);
const PtNodeParams ptNodeParams = mNodeReader.fetchPtNodeParamsInBufferFromPtNodePos(ptNodePos);
std::vector<int> codePointVector(ptNodeParams.getCodePoints(),
ptNodeParams.getCodePoints() + ptNodeParams.getCodePointCount());
@@ -473,7 +479,6 @@
// Fetch bigram information.
// TODO: Support n-gram.
std::vector<BigramProperty> bigrams;
- const int wordId = ptNodeParams.getTerminalId();
const WordIdArrayView prevWordIds = WordIdArrayView::fromObject(&wordId);
const TerminalPositionLookupTable *const terminalPositionLookupTable =
mBuffers->getTerminalPositionLookupTable();
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.h
index 24f92a4..1d2712a 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.h
@@ -66,15 +66,13 @@
const int terminalPtNodePos, const int maxCodePointCount, int *const outCodePoints,
int *const outUnigramProbability) const;
- int getTerminalPtNodePositionOfWord(const CodePointArrayView wordCodePoints,
- const bool forceLowerCaseSearch) const;
+ int getWordId(const CodePointArrayView wordCodePoints, const bool forceLowerCaseSearch) const;
int getProbability(const int unigramProbability, const int bigramProbability) const;
- int getProbabilityOfPtNode(const int *const prevWordsPtNodePos, const int ptNodePos) const;
+ int getProbabilityOfWord(const int *const prevWordIds, const int wordId) const;
- void iterateNgramEntries(const int *const prevWordsPtNodePos,
- NgramListener *const listener) const;
+ void iterateNgramEntries(const int *const prevWordIds, NgramListener *const listener) const;
int getShortcutPositionOfPtNode(const int ptNodePos) const;
diff --git a/native/jni/src/utils/char_utils.cpp b/native/jni/src/utils/char_utils.cpp
index b17e084..3bb9055 100644
--- a/native/jni/src/utils/char_utils.cpp
+++ b/native/jni/src/utils/char_utils.cpp
@@ -1057,11 +1057,11 @@
- static_cast<int>((static_cast<const struct LatinCapitalSmallPair *>(b))->capital);
}
-/* static */ unsigned short CharUtils::latin_tolower(const unsigned short c) {
+/* static */ int CharUtils::latin_tolower(const int c) {
struct LatinCapitalSmallPair *p =
static_cast<struct LatinCapitalSmallPair *>(bsearch(&c, SORTED_CHAR_MAP,
NELEMS(SORTED_CHAR_MAP), sizeof(SORTED_CHAR_MAP[0]), compare_pair_capital));
- return p ? p->small : c;
+ return p ? static_cast<int>(p->small) : c;
}
/*
diff --git a/native/jni/src/utils/char_utils.h b/native/jni/src/utils/char_utils.h
index 6378650..5e9cdd9 100644
--- a/native/jni/src/utils/char_utils.h
+++ b/native/jni/src/utils/char_utils.h
@@ -27,20 +27,14 @@
class CharUtils {
public:
+ static const std::vector<int> EMPTY_STRING;
+
static AK_FORCE_INLINE bool isAsciiUpper(int c) {
// Note: isupper(...) reports false positives for some Cyrillic characters, causing them to
// be incorrectly lower-cased using toAsciiLower(...) rather than latin_tolower(...).
return (c >= 'A' && c <= 'Z');
}
- static AK_FORCE_INLINE int toAsciiLower(int c) {
- return c - 'A' + 'a';
- }
-
- static AK_FORCE_INLINE bool isAscii(int c) {
- return isascii(c) != 0;
- }
-
static AK_FORCE_INLINE int toLowerCase(const int c) {
if (isAsciiUpper(c)) {
return toAsciiLower(c);
@@ -48,7 +42,7 @@
if (isAscii(c)) {
return c;
}
- return static_cast<int>(latin_tolower(static_cast<unsigned short>(c)));
+ return latin_tolower(c);
}
static AK_FORCE_INLINE int toBaseLowerCase(const int c) {
@@ -59,7 +53,6 @@
// TODO: Do not hardcode here
return codePoint == KEYCODE_SINGLE_QUOTE || codePoint == KEYCODE_HYPHEN_MINUS;
}
-
static AK_FORCE_INLINE int getCodePointCount(const int arraySize, const int *const codePoints) {
int size = 0;
for (; size < arraySize; ++size) {
@@ -91,9 +84,6 @@
return codePoint >= MIN_UNICODE_CODE_POINT && codePoint <= MAX_UNICODE_CODE_POINT;
}
- static unsigned short latin_tolower(const unsigned short c);
- static const std::vector<int> EMPTY_STRING;
-
// Returns updated code point count. Returns 0 when the code points cannot be marked as a
// Beginning-of-Sentence.
static AK_FORCE_INLINE int attachBeginningOfSentenceMarker(int *const codePoints,
@@ -125,6 +115,16 @@
*/
static const int BASE_CHARS_SIZE = 0x0500;
static const unsigned short BASE_CHARS[BASE_CHARS_SIZE];
+
+ static AK_FORCE_INLINE bool isAscii(int c) {
+ return isascii(c) != 0;
+ }
+
+ static AK_FORCE_INLINE int toAsciiLower(int c) {
+ return c - 'A' + 'a';
+ }
+
+ static int latin_tolower(const int c);
};
} // namespace latinime
#endif // LATINIME_CHAR_UTILS_H
diff --git a/native/jni/tests/suggest/core/layout/geometry_utils_test.cpp b/native/jni/tests/suggest/core/layout/geometry_utils_test.cpp
new file mode 100644
index 0000000..f5f89ed
--- /dev/null
+++ b/native/jni/tests/suggest/core/layout/geometry_utils_test.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "suggest/core/layout/geometry_utils.h"
+
+#include <gtest/gtest.h>
+
+namespace latinime {
+namespace {
+
+::testing::AssertionResult ExpectAngleDiffEq(const char* expectedExpression,
+ const char* actualExpression, float expected, float actual) {
+ if (actual < 0.0f || M_PI_F < actual) {
+ return ::testing::AssertionFailure()
+ << "Must be in the range of [0.0f, M_PI_F]."
+ << " expected: " << expected
+ << " actual: " << actual;
+ }
+ return ::testing::internal::CmpHelperFloatingPointEQ<float>(
+ expectedExpression, actualExpression, expected, actual);
+}
+
+#define EXPECT_ANGLE_DIFF_EQ(expected, actual) \
+ EXPECT_PRED_FORMAT2(ExpectAngleDiffEq, expected, actual);
+
+TEST(GeometryUtilsTest, testSquareFloat) {
+ const float test_data[] = { 0.0f, 1.0f, 123.456f, -1.0f, -9876.54321f };
+ for (const float value : test_data) {
+ EXPECT_FLOAT_EQ(value * value, GeometryUtils::SQUARE_FLOAT(value));
+ }
+}
+
+TEST(GeometryUtilsTest, testGetAngle) {
+ EXPECT_FLOAT_EQ(0.0f, GeometryUtils::getAngle(0, 0, 0, 0));
+ EXPECT_FLOAT_EQ(0.0f, GeometryUtils::getAngle(100, -10, 100, -10));
+
+ EXPECT_FLOAT_EQ(M_PI_F / 4.0f, GeometryUtils::getAngle(1, 1, 0, 0));
+ EXPECT_FLOAT_EQ(M_PI_F, GeometryUtils::getAngle(-1, 0, 0, 0));
+
+ EXPECT_FLOAT_EQ(GeometryUtils::getAngle(0, 0, -1, 0), GeometryUtils::getAngle(1, 0, 0, 0));
+ EXPECT_FLOAT_EQ(GeometryUtils::getAngle(1, 2, 3, 4),
+ GeometryUtils::getAngle(100, 200, 300, 400));
+}
+
+TEST(GeometryUtilsTest, testGetAngleDiff) {
+ EXPECT_ANGLE_DIFF_EQ(0.0f, GeometryUtils::getAngleDiff(0.0f, 0.0f));
+ EXPECT_ANGLE_DIFF_EQ(0.0f, GeometryUtils::getAngleDiff(10000.0f, 10000.0f));
+ EXPECT_ANGLE_DIFF_EQ(ROUND_FLOAT_10000(M_PI_F),
+ GeometryUtils::getAngleDiff(0.0f, M_PI_F));
+ EXPECT_ANGLE_DIFF_EQ(ROUND_FLOAT_10000(M_PI_F / 6.0f),
+ GeometryUtils::getAngleDiff(M_PI_F / 3.0f, M_PI_F / 2.0f));
+ EXPECT_ANGLE_DIFF_EQ(ROUND_FLOAT_10000(M_PI_F / 2.0f),
+ GeometryUtils::getAngleDiff(0.0f, M_PI_F * 1.5f));
+ EXPECT_ANGLE_DIFF_EQ(0.0f, GeometryUtils::getAngleDiff(0.0f, M_PI_F * 1024.0f));
+ EXPECT_ANGLE_DIFF_EQ(0.0f, GeometryUtils::getAngleDiff(-M_PI_F, M_PI_F));
+}
+
+TEST(GeometryUtilsTest, testGetDistanceInt) {
+ EXPECT_EQ(0, GeometryUtils::getDistanceInt(0, 0, 0, 0));
+ EXPECT_EQ(0, GeometryUtils::getAngle(100, -10, 100, -10));
+
+ EXPECT_EQ(5, GeometryUtils::getDistanceInt(0, 0, 5, 0));
+ EXPECT_EQ(5, GeometryUtils::getDistanceInt(0, 0, 3, 4));
+ EXPECT_EQ(5, GeometryUtils::getDistanceInt(0, -4, 3, 0));
+ EXPECT_EQ(5, GeometryUtils::getDistanceInt(0, 0, -3, -4));
+ EXPECT_EQ(500, GeometryUtils::getDistanceInt(0, 0, 300, -400));
+}
+
+} // namespace
+} // namespace latinime
diff --git a/native/jni/tests/suggest/policyimpl/utils/damerau_levenshtein_edit_distance_policy_test.cpp b/native/jni/tests/suggest/policyimpl/utils/damerau_levenshtein_edit_distance_policy_test.cpp
new file mode 100644
index 0000000..d134179
--- /dev/null
+++ b/native/jni/tests/suggest/policyimpl/utils/damerau_levenshtein_edit_distance_policy_test.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "suggest/policyimpl/utils/damerau_levenshtein_edit_distance_policy.h"
+
+#include <gtest/gtest.h>
+
+#include <vector>
+
+#include "suggest/policyimpl/utils/edit_distance.h"
+#include "utils/int_array_view.h"
+
+namespace latinime {
+namespace {
+
+TEST(DamerauLevenshteinEditDistancePolicyTest, TestConstructPolicy) {
+ const std::vector<int> codePoints0 = { 0x20, 0x40, 0x60 };
+ const std::vector<int> codePoints1 = { 0x10, 0x20, 0x30, 0x40, 0x50, 0x60 };
+ DamerauLevenshteinEditDistancePolicy policy(codePoints0.data(), codePoints0.size(),
+ codePoints1.data(), codePoints1.size());
+
+ EXPECT_EQ(static_cast<int>(codePoints0.size()), policy.getString0Length());
+ EXPECT_EQ(static_cast<int>(codePoints1.size()), policy.getString1Length());
+}
+
+float getEditDistance(const std::vector<int> &codePoints0, const std::vector<int> &codePoints1) {
+ DamerauLevenshteinEditDistancePolicy policy(codePoints0.data(), codePoints0.size(),
+ codePoints1.data(), codePoints1.size());
+ return EditDistance::getEditDistance(&policy);
+}
+
+TEST(DamerauLevenshteinEditDistancePolicyTest, TestEditDistance) {
+ EXPECT_FLOAT_EQ(0.0f, getEditDistance({}, {}));
+ EXPECT_FLOAT_EQ(0.0f, getEditDistance({ 1 }, { 1 }));
+ EXPECT_FLOAT_EQ(0.0f, getEditDistance({ 1, 2, 3 }, { 1, 2, 3 }));
+
+ EXPECT_FLOAT_EQ(1.0f, getEditDistance({ 1 }, { }));
+ EXPECT_FLOAT_EQ(1.0f, getEditDistance({}, { 100 }));
+ EXPECT_FLOAT_EQ(5.0f, getEditDistance({}, { 1, 2, 3, 4, 5 }));
+
+ EXPECT_FLOAT_EQ(1.0f, getEditDistance({ 0 }, { 100 }));
+ EXPECT_FLOAT_EQ(5.0f, getEditDistance({ 1, 2, 3, 4, 5 }, { 11, 12, 13, 14, 15 }));
+
+ EXPECT_FLOAT_EQ(1.0f, getEditDistance({ 1 }, { 1, 2 }));
+ EXPECT_FLOAT_EQ(2.0f, getEditDistance({ 1, 2 }, { 0, 1, 2, 3 }));
+ EXPECT_FLOAT_EQ(2.0f, getEditDistance({ 0, 1, 2, 3 }, { 1, 2 }));
+
+ EXPECT_FLOAT_EQ(1.0f, getEditDistance({ 1, 2 }, { 2, 1 }));
+ EXPECT_FLOAT_EQ(2.0f, getEditDistance({ 1, 2, 3, 4 }, { 2, 1, 4, 3 }));
+}
+} // namespace
+} // namespace latinime
diff --git a/native/jni/tests/utils/char_utils_test.cpp b/native/jni/tests/utils/char_utils_test.cpp
new file mode 100644
index 0000000..01d5340
--- /dev/null
+++ b/native/jni/tests/utils/char_utils_test.cpp
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "utils/char_utils.h"
+
+#include <gtest/gtest.h>
+
+#include "defines.h"
+
+namespace latinime {
+namespace {
+
+TEST(CharUtilsTest, TestIsAsciiUpper) {
+ EXPECT_TRUE(CharUtils::isAsciiUpper('A'));
+ EXPECT_TRUE(CharUtils::isAsciiUpper('Z'));
+ EXPECT_FALSE(CharUtils::isAsciiUpper('a'));
+ EXPECT_FALSE(CharUtils::isAsciiUpper('z'));
+ EXPECT_FALSE(CharUtils::isAsciiUpper('@'));
+ EXPECT_FALSE(CharUtils::isAsciiUpper(' '));
+ EXPECT_FALSE(CharUtils::isAsciiUpper(0x00C0 /* LATIN CAPITAL LETTER A WITH GRAVE */));
+ EXPECT_FALSE(CharUtils::isAsciiUpper(0x00E0 /* LATIN SMALL LETTER A WITH GRAVE */));
+ EXPECT_FALSE(CharUtils::isAsciiUpper(0x03C2 /* GREEK SMALL LETTER FINAL SIGMA */));
+ EXPECT_FALSE(CharUtils::isAsciiUpper(0x0410 /* CYRILLIC CAPITAL LETTER A */));
+ EXPECT_FALSE(CharUtils::isAsciiUpper(0x0430 /* CYRILLIC SMALL LETTER A */));
+ EXPECT_FALSE(CharUtils::isAsciiUpper(0x3042 /* HIRAGANA LETTER A */));
+ EXPECT_FALSE(CharUtils::isAsciiUpper(0x1F36A /* COOKIE */));
+}
+
+TEST(CharUtilsTest, TestToLowerCase) {
+ EXPECT_EQ('a', CharUtils::toLowerCase('A'));
+ EXPECT_EQ('z', CharUtils::toLowerCase('Z'));
+ EXPECT_EQ('a', CharUtils::toLowerCase('a'));
+ EXPECT_EQ('z', CharUtils::toLowerCase('z'));
+ EXPECT_EQ('@', CharUtils::toLowerCase('@'));
+ EXPECT_EQ(' ', CharUtils::toLowerCase(' '));
+ EXPECT_EQ(0x00E0 /* LATIN SMALL LETTER A WITH GRAVE */,
+ CharUtils::toLowerCase(0x00C0 /* LATIN CAPITAL LETTER A WITH GRAVE */));
+ EXPECT_EQ(0x00E0 /* LATIN SMALL LETTER A WITH GRAVE */,
+ CharUtils::toLowerCase(0x00E0 /* LATIN SMALL LETTER A WITH GRAVE */));
+ EXPECT_EQ(0x03C2 /* GREEK SMALL LETTER FINAL SIGMA */,
+ CharUtils::toLowerCase(0x03C2 /* GREEK SMALL LETTER FINAL SIGMA */));
+ EXPECT_EQ(0x0430 /* CYRILLIC SMALL LETTER A */,
+ CharUtils::toLowerCase(0x0410 /* CYRILLIC CAPITAL LETTER A */));
+ EXPECT_EQ(0x0430 /* CYRILLIC SMALL LETTER A */,
+ CharUtils::toLowerCase(0x0430 /* CYRILLIC SMALL LETTER A */));
+ EXPECT_EQ(0x3042 /* HIRAGANA LETTER A */,
+ CharUtils::toLowerCase(0x3042 /* HIRAGANA LETTER A */));
+ EXPECT_EQ(0x1F36A /* COOKIE */, CharUtils::toLowerCase(0x1F36A /* COOKIE */));
+}
+
+TEST(CharUtilsTest, TestToBaseLowerCase) {
+ EXPECT_EQ('a', CharUtils::toBaseLowerCase('A'));
+ EXPECT_EQ('z', CharUtils::toBaseLowerCase('Z'));
+ EXPECT_EQ('a', CharUtils::toBaseLowerCase('a'));
+ EXPECT_EQ('z', CharUtils::toBaseLowerCase('z'));
+ EXPECT_EQ('@', CharUtils::toBaseLowerCase('@'));
+ EXPECT_EQ(' ', CharUtils::toBaseLowerCase(' '));
+ EXPECT_EQ('a', CharUtils::toBaseLowerCase(0x00C0 /* LATIN CAPITAL LETTER A WITH GRAVE */));
+ EXPECT_EQ('a', CharUtils::toBaseLowerCase(0x00E0 /* LATIN SMALL LETTER A WITH GRAVE */));
+ EXPECT_EQ(0x03C2 /* GREEK SMALL LETTER FINAL SIGMA */,
+ CharUtils::toBaseLowerCase(0x03C2 /* GREEK SMALL LETTER FINAL SIGMA */));
+ EXPECT_EQ(0x0430 /* CYRILLIC SMALL LETTER A */,
+ CharUtils::toBaseLowerCase(0x0410 /* CYRILLIC CAPITAL LETTER A */));
+ EXPECT_EQ(0x0430 /* CYRILLIC SMALL LETTER A */,
+ CharUtils::toBaseLowerCase(0x0430 /* CYRILLIC SMALL LETTER A */));
+ EXPECT_EQ(0x3042 /* HIRAGANA LETTER A */,
+ CharUtils::toBaseLowerCase(0x3042 /* HIRAGANA LETTER A */));
+ EXPECT_EQ(0x1F36A /* COOKIE */, CharUtils::toBaseLowerCase(0x1F36A /* COOKIE */));
+}
+
+TEST(CharUtilsTest, TestToBaseCodePoint) {
+ EXPECT_EQ('A', CharUtils::toBaseCodePoint('A'));
+ EXPECT_EQ('Z', CharUtils::toBaseCodePoint('Z'));
+ EXPECT_EQ('a', CharUtils::toBaseCodePoint('a'));
+ EXPECT_EQ('z', CharUtils::toBaseCodePoint('z'));
+ EXPECT_EQ('@', CharUtils::toBaseCodePoint('@'));
+ EXPECT_EQ(' ', CharUtils::toBaseCodePoint(' '));
+ EXPECT_EQ('A', CharUtils::toBaseCodePoint(0x00C0 /* LATIN CAPITAL LETTER A WITH GRAVE */));
+ EXPECT_EQ('a', CharUtils::toBaseCodePoint(0x00E0 /* LATIN SMALL LETTER A WITH GRAVE */));
+ EXPECT_EQ(0x03C2 /* GREEK SMALL LETTER FINAL SIGMA */,
+ CharUtils::toBaseLowerCase(0x03C2 /* GREEK SMALL LETTER FINAL SIGMA */));
+ EXPECT_EQ(0x0410 /* CYRILLIC CAPITAL LETTER A */,
+ CharUtils::toBaseCodePoint(0x0410 /* CYRILLIC CAPITAL LETTER A */));
+ EXPECT_EQ(0x0430 /* CYRILLIC SMALL LETTER A */,
+ CharUtils::toBaseCodePoint(0x0430 /* CYRILLIC SMALL LETTER A */));
+ EXPECT_EQ(0x3042 /* HIRAGANA LETTER A */,
+ CharUtils::toBaseCodePoint(0x3042 /* HIRAGANA LETTER A */));
+ EXPECT_EQ(0x1F36A /* COOKIE */, CharUtils::toBaseCodePoint(0x1F36A /* COOKIE */));
+}
+
+TEST(CharUtilsTest, TestIsIntentionalOmissionCodePoint) {
+ EXPECT_TRUE(CharUtils::isIntentionalOmissionCodePoint('\''));
+ EXPECT_TRUE(CharUtils::isIntentionalOmissionCodePoint('-'));
+ EXPECT_FALSE(CharUtils::isIntentionalOmissionCodePoint('a'));
+ EXPECT_FALSE(CharUtils::isIntentionalOmissionCodePoint('?'));
+ EXPECT_FALSE(CharUtils::isIntentionalOmissionCodePoint('/'));
+}
+
+TEST(CharUtilsTest, TestIsInUnicodeSpace) {
+ EXPECT_FALSE(CharUtils::isInUnicodeSpace(NOT_A_CODE_POINT));
+ EXPECT_FALSE(CharUtils::isInUnicodeSpace(CODE_POINT_BEGINNING_OF_SENTENCE));
+ EXPECT_TRUE(CharUtils::isInUnicodeSpace('a'));
+ EXPECT_TRUE(CharUtils::isInUnicodeSpace(0x0410 /* CYRILLIC CAPITAL LETTER A */));
+ EXPECT_TRUE(CharUtils::isInUnicodeSpace(0x3042 /* HIRAGANA LETTER A */));
+ EXPECT_TRUE(CharUtils::isInUnicodeSpace(0x1F36A /* COOKIE */));
+}
+
+} // namespace
+} // namespace latinime