diff options
54 files changed, 1484 insertions, 263 deletions
diff --git a/java/res/values-hi/strings.xml b/java/res/values-hi/strings.xml index 01bba5c6e..dcbbcd97c 100644 --- a/java/res/values-hi/strings.xml +++ b/java/res/values-hi/strings.xml @@ -31,7 +31,7 @@ <string name="correction_category" msgid="2236750915056607613">"पाठ सुधार"</string> <string name="gesture_typing_category" msgid="497263612130532630">"जेस्चर लिखना"</string> <string name="misc_category" msgid="6894192814868233453">"अन्य विकल्प"</string> - <string name="advanced_settings" msgid="362895144495591463">"उन्नत सेटिंग"</string> + <string name="advanced_settings" msgid="362895144495591463">"अतिरिक्त सेटिंग"</string> <string name="advanced_settings_summary" msgid="4487980456152830271">"विशेषज्ञों के लिए विकल्प"</string> <string name="include_other_imes_in_language_switch_list" msgid="4533689960308565519">"अन्य इनपुट पद्धतियों पर जाएं"</string> <string name="include_other_imes_in_language_switch_list_summary" msgid="840637129103317635">"भाषा स्विच कुंजी में अन्य इनपुट पद्धतियां भी शामिल हैं"</string> diff --git a/java/res/values-land/dimens.xml b/java/res/values-land/dimens.xml index c954e60da..42a746b60 100644 --- a/java/res/values-land/dimens.xml +++ b/java/res/values-land/dimens.xml @@ -75,5 +75,9 @@ <dimen name="gesture_floating_preview_vertical_padding">15dp</dimen> <!-- Emoji keyboard --> - <fraction name="emoji_keyboard_key_width">8.3333%p</fraction> + <fraction name="emoji_keyboard_key_width">10%p</fraction> + <fraction name="emoji_keyboard_row_height">50%p</fraction> + <fraction name="emoji_keyboard_key_letter_size">60%p</fraction> + <integer name="emoji_keyboard_max_key_count">20</integer> + </resources> diff --git a/java/res/values-lo/donottranslate.xml b/java/res/values-lo/donottranslate.xml new file mode 100644 index 000000000..a9893feec --- /dev/null +++ b/java/res/values-lo/donottranslate.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** +** Copyright 2013, 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. +*/ +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- Whether this language uses spaces between words --> + <bool name="current_language_has_spaces">false</bool> +</resources> diff --git a/java/res/values-pt-rPT/strings.xml b/java/res/values-pt-rPT/strings.xml index bad0bd669..cd89a7765 100644 --- a/java/res/values-pt-rPT/strings.xml +++ b/java/res/values-pt-rPT/strings.xml @@ -134,7 +134,7 @@ <string name="select_language" msgid="3693815588777926848">"Idiomas de introdução"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Toque novamente para guardar"</string> <string name="has_dictionary" msgid="6071847973466625007">"Dicionário disponível"</string> - <string name="prefs_enable_log" msgid="6620424505072963557">"Activar comentários do utilizador"</string> + <string name="prefs_enable_log" msgid="6620424505072963557">"Ativar comentários do utilizador"</string> <string name="prefs_description_log" msgid="7525225584555429211">"Envie automaticamente estatísticas de utilização e relatórios de falhas e ajude-nos a melhorar este editor do método de introdução."</string> <string name="keyboard_layout" msgid="8451164783510487501">"Tema do teclado"</string> <string name="subtype_en_GB" msgid="88170601942311355">"Inglês (RU)"</string> diff --git a/java/res/values-th/donottranslate.xml b/java/res/values-th/donottranslate.xml index aeeebed15..a9893feec 100644 --- a/java/res/values-th/donottranslate.xml +++ b/java/res/values-th/donottranslate.xml @@ -18,6 +18,6 @@ */ --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- Whether this language uses spaces --> + <!-- Whether this language uses spaces between words --> <bool name="current_language_has_spaces">false</bool> </resources> diff --git a/java/res/values/dimens.xml b/java/res/values/dimens.xml index 7de93e6e3..88e327f26 100644 --- a/java/res/values/dimens.xml +++ b/java/res/values/dimens.xml @@ -117,6 +117,9 @@ <!-- Emoji keyboard --> <fraction name="emoji_keyboard_key_width">14.2857%p</fraction> + <fraction name="emoji_keyboard_row_height">33%p</fraction> + <fraction name="emoji_keyboard_key_letter_size">90%p</fraction> + <integer name="emoji_keyboard_max_key_count">21</integer> <!-- Inset used in Accessibility mode to avoid accidental key presses when a finger slides off the screen. --> <dimen name="accessibility_edge_slop">8dp</dimen> @@ -124,4 +127,5 @@ <integer name="user_dictionary_max_word_length" translatable="false">48</integer> <dimen name="language_on_spacebar_horizontal_margin">1dp</dimen> + </resources> diff --git a/java/res/values/donottranslate.xml b/java/res/values/donottranslate.xml index 52ebe161c..82c5ce456 100644 --- a/java/res/values/donottranslate.xml +++ b/java/res/values/donottranslate.xml @@ -31,7 +31,7 @@ <string name="symbols_word_separators">"	 \n"()[]{}*&<>+=|.,;:!?/_\"</string> <!-- Word connectors --> <string name="symbols_word_connectors">\'-</string> - <!-- Whether this language uses spaces --> + <!-- Whether this language uses spaces between words --> <bool name="current_language_has_spaces">true</bool> <!-- Always show the suggestion strip --> diff --git a/java/res/xml-sw600dp/rows_lao.xml b/java/res/xml-sw600dp/rows_lao.xml new file mode 100644 index 000000000..cfe8db98e --- /dev/null +++ b/java/res/xml-sw600dp/rows_lao.xml @@ -0,0 +1,63 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** +** Copyright 2013, 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. +*/ +--> + +<merge + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" +> + <include + latin:keyboardLayout="@xml/key_styles_common" /> + <Row + latin:keyWidth="7.5%p" + > + <include + latin:keyboardLayout="@xml/rowkeys_lao1" /> + <Key + latin:keyStyle="deleteKeyStyle" + latin:keyWidth="fillRight" /> + </Row> + <Row + latin:keyWidth="7.5%p" + > + <include + latin:keyboardLayout="@xml/rowkeys_lao2" /> + </Row> + <Row + latin:keyWidth="7.5%p" + > + <include + latin:keyboardLayout="@xml/rowkeys_lao3" /> + <Key + latin:keyStyle="enterKeyStyle" + latin:keyWidth="fillRight" /> + </Row> + <Row + latin:keyWidth="7.5%p" + > + <Key + latin:keyStyle="shiftKeyStyle" + latin:keyWidth="10.0%p" /> + <include + latin:keyboardLayout="@xml/rowkeys_lao4" /> + <include + latin:keyboardLayout="@xml/keys_exclamation_question" /> + </Row> + <include + latin:keyboardLayout="@xml/row_qwerty4" /> +</merge> diff --git a/java/res/xml/kbd_emoji_recents.xml b/java/res/xml/kbd_emoji_recents.xml index f56b79ab7..73926ecc0 100644 --- a/java/res/xml/kbd_emoji_recents.xml +++ b/java/res/xml/kbd_emoji_recents.xml @@ -21,8 +21,9 @@ <Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" latin:keyWidth="@fraction/emoji_keyboard_key_width" - latin:keyLetterSize="90%p" + latin:keyLetterSize="@fraction/emoji_keyboard_key_letter_size" latin:keyLabelSize="60%p" + latin:rowHeight="@fraction/emoji_keyboard_row_height" > <GridRows latin:codesArray="@array/emoji_recents" diff --git a/java/res/xml/kbd_lao.xml b/java/res/xml/kbd_lao.xml new file mode 100644 index 000000000..2bba330de --- /dev/null +++ b/java/res/xml/kbd_lao.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** +** Copyright 2013, 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. +*/ +--> + +<Keyboard + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" + latin:rowHeight="20%p" + latin:verticalGap="@fraction/key_bottom_gap_5row" + latin:keyLetterSize="@fraction/key_letter_ratio_5row" + latin:keyShiftedLetterHintRatio="@fraction/key_uppercase_letter_ratio_5row" + latin:touchPositionCorrectionData="@array/touch_position_correction_data_default" +> + <include + latin:keyboardLayout="@xml/rows_lao" /> +</Keyboard> diff --git a/java/res/xml/key_space_5kw.xml b/java/res/xml/key_space_5kw.xml index 02ee42fd2..b6d38fb33 100644 --- a/java/res/xml/key_space_5kw.xml +++ b/java/res/xml/key_space_5kw.xml @@ -23,7 +23,7 @@ > <switch> <case - latin:languageCode="fa" + latin:languageCode="fa|ne" latin:languageSwitchKeyEnabled="true" > <Key @@ -35,7 +35,7 @@ latin:keyStyle="zwnjKeyStyle" /> </case> <case - latin:languageCode="fa" + latin:languageCode="fa|ne" latin:languageSwitchKeyEnabled="false" > <Key diff --git a/java/res/xml/key_styles_currency.xml b/java/res/xml/key_styles_currency.xml index 60333eeb4..b7677a20d 100644 --- a/java/res/xml/key_styles_currency.xml +++ b/java/res/xml/key_styles_currency.xml @@ -95,14 +95,16 @@ <!-- fa: Persian (Rial and Afgahni) hi: Hindi (Indian Rupee) iw: Hebrew (New Sheqel) + lo: Lao (Kip) mn: Mongolian (Tugrik) + ne: Nepali (Nepalese Rupee) th: Thai (Baht) uk: Ukrainian (Hryvnia) vi: Vietnamese (Dong) --> <!-- TODO: The currency sign of Turkish Lira was created in 2012 and assigned U+20BA for its unicode, although there is no font glyph for it as of November 2012. --> <case - latin:languageCode="fa|hi|iw|mn|th|uk|vi" + latin:languageCode="fa|hi|iw|lo|mn|ne|th|uk|vi" > <!-- U+00A3: "£" POUND SIGN U+20AC: "€" EURO SIGN diff --git a/java/res/xml/keyboard_layout_set_lao.xml b/java/res/xml/keyboard_layout_set_lao.xml new file mode 100644 index 000000000..2ffde45db --- /dev/null +++ b/java/res/xml/keyboard_layout_set_lao.xml @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** +** Copyright 2013, 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. +*/ +--> + +<KeyboardLayoutSet + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"> + <Element + latin:elementName="alphabet" + latin:elementKeyboard="@xml/kbd_lao" + latin:enableProximityCharsCorrection="true" /> + <Element + latin:elementName="alphabetAutomaticShifted" + latin:elementKeyboard="@xml/kbd_lao" + latin:enableProximityCharsCorrection="true" /> + <!-- On these shifted alphabet layouts the proximity characters correction should be disabled + because the letters on these layouts aren't the ones in different case of the above + unshifted layouts. --> + <Element + latin:elementName="alphabetManualShifted" + latin:elementKeyboard="@xml/kbd_lao" /> + <Element + latin:elementName="alphabetShiftLocked" + latin:elementKeyboard="@xml/kbd_lao" /> + <Element + latin:elementName="alphabetShiftLockShifted" + latin:elementKeyboard="@xml/kbd_lao" /> + <Element + latin:elementName="symbols" + latin:elementKeyboard="@xml/kbd_symbols" /> + <Element + latin:elementName="symbolsShifted" + latin:elementKeyboard="@xml/kbd_symbols_shift" /> + <Element + latin:elementName="phone" + latin:elementKeyboard="@xml/kbd_phone" /> + <Element + latin:elementName="phoneSymbols" + latin:elementKeyboard="@xml/kbd_phone_symbols" /> + <Element + latin:elementName="number" + latin:elementKeyboard="@xml/kbd_number" /> +</KeyboardLayoutSet> diff --git a/java/res/xml/keyboard_layout_set_nepali_romanized.xml b/java/res/xml/keyboard_layout_set_nepali_romanized.xml index 82f36cfbd..fbbc6a5a0 100644 --- a/java/res/xml/keyboard_layout_set_nepali_romanized.xml +++ b/java/res/xml/keyboard_layout_set_nepali_romanized.xml @@ -44,6 +44,9 @@ latin:elementName="symbols" latin:elementKeyboard="@xml/kbd_symbols" /> <Element + latin:elementName="symbolsShifted" + latin:elementKeyboard="@xml/kbd_symbols_shift" /> + <Element latin:elementName="phone" latin:elementKeyboard="@xml/kbd_phone" /> <Element diff --git a/java/res/xml/keyboard_layout_set_nepali_traditional.xml b/java/res/xml/keyboard_layout_set_nepali_traditional.xml index 2a6dc8e83..4a3b60153 100644 --- a/java/res/xml/keyboard_layout_set_nepali_traditional.xml +++ b/java/res/xml/keyboard_layout_set_nepali_traditional.xml @@ -44,6 +44,9 @@ latin:elementName="symbols" latin:elementKeyboard="@xml/kbd_symbols" /> <Element + latin:elementName="symbolsShifted" + latin:elementKeyboard="@xml/kbd_symbols_shift" /> + <Element latin:elementName="phone" latin:elementKeyboard="@xml/kbd_phone" /> <Element diff --git a/java/res/xml/method.xml b/java/res/xml/method.xml index c3d68c6e5..6014646bb 100644 --- a/java/res/xml/method.xml +++ b/java/res/xml/method.xml @@ -55,6 +55,7 @@ ka: Georgian/georgian (kk: Kazakh/east_slavic) # disabled temporarily. waiting for strnig resources. ky: Kyrgyz/east_slavic + lo: Lao/lao lt: Lithuanian/qwerty lv: Latvian/qwerty mk: Macedonian/south_slavic @@ -332,6 +333,13 @@ /> <subtype android:icon="@drawable/ic_subtype_keyboard" android:label="@string/subtype_generic" + android:subtypeId="0x8315772c" + android:imeSubtypeLocale="lo" + android:imeSubtypeMode="keyboard" + android:imeSubtypeExtraValue="KeyboardLayoutSet=lao" + /> + <subtype android:icon="@drawable/ic_subtype_keyboard" + android:label="@string/subtype_generic" android:subtypeId="0x8321bb43" android:imeSubtypeLocale="lt" android:imeSubtypeMode="keyboard" diff --git a/java/res/xml/rowkeys_lao1.xml b/java/res/xml/rowkeys_lao1.xml new file mode 100644 index 000000000..fa1ad97d8 --- /dev/null +++ b/java/res/xml/rowkeys_lao1.xml @@ -0,0 +1,164 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** +** Copyright 2013, 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. +*/ +--> + +<merge + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" +> + <switch> + <case + latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted" + > + <!-- U+0ED1: "໑" LAO DIGIT ONE --> + <Key + latin:keyLabel="໑" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0ED2: "໒" LAO DIGIT TWO --> + <Key + latin:keyLabel="໒" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0ED3: "໓" LAO DIGIT THREE --> + <Key + latin:keyLabel="໓" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0ED4: "໔" LAO DIGIT FOUR --> + <Key + latin:keyLabel="໔" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0ECC: "໌" LAO CANCELLATION MARK --> + <Key + latin:keyLabel="໌" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EBC: "ຼ" LAO SEMIVOWEL SIGN LO --> + <Key + latin:keyLabel="ຼ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0ED5: "໕" LAO DIGIT FIVE --> + <Key + latin:keyLabel="໕" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0ED6: "໖" LAO DIGIT SIX --> + <Key + latin:keyLabel="໖" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0ED7: "໗" LAO DIGIT SEVEN --> + <Key + latin:keyLabel="໗" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0ED8: "໘" LAO DIGIT EIGHT --> + <Key + latin:keyLabel="໘" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0ED9: "໙" LAO DIGIT NINE --> + <Key + latin:keyLabel="໙" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0ECD/U+0EC8: "ໍ່" LAO NIGGAHITA/LAO TONE MAI EK --> + <Key + latin:keyLabel="ໍ່" + latin:keyLabelFlags="fontNormal|followKeyLetterRatio" /> + </case> + <default> + <!-- U+0EA2: "ຢ" LAO LETTER YO + U+0ED1: "໑" LAO DIGIT ONE --> + <Key + latin:keyLabel="ຢ" + latin:keyHintLabel="1" + latin:additionalMoreKeys="1" + latin:moreKeys="໑" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0E9F: "ຟ" LAO LETTER FO SUNG + U+0ED2: "໒" LAO DIGIT TWO --> + <Key + latin:keyLabel="ຟ" + latin:keyHintLabel="2" + latin:additionalMoreKeys="2" + latin:moreKeys="໒" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EC2: "ໂ" LAO VOWEL SIGN O + U+0ED3: "໓" LAO DIGIT THREE --> + <Key + latin:keyLabel="ໂ" + latin:keyHintLabel="3" + latin:additionalMoreKeys="3" + latin:moreKeys="໓" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0E96: "ຖ" LAO LETTER THO SUNG + U+0ED4: "໔" LAO DIGIT FOUR --> + <Key + latin:keyLabel="ຖ" + latin:keyHintLabel="4" + latin:additionalMoreKeys="4" + latin:moreKeys="໔" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EB8: "ຸ" LAO VOWEL SIGN U --> + <Key + latin:keyLabel="ຸ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EB9: "ູ" LAO VOWEL SIGN UU --> + <Key + latin:keyLabel="ູ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0E84: "ຄ" LAO LETTER KHO TAM + U+0ED5: "໕" LAO DIGIT FIVE --> + <Key + latin:keyLabel="ຄ" + latin:keyHintLabel="5" + latin:additionalMoreKeys="5" + latin:moreKeys="໕" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0E95: "ຕ" LAO LETTER TO + U+0ED6: "໖" LAO DIGIT SIX --> + <Key + latin:keyLabel="ຕ" + latin:keyHintLabel="6" + latin:additionalMoreKeys="6" + latin:moreKeys="໖" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0E88: "ຈ" LAO LETTER CO + U+0ED7: "໗" LAO DIGIT SEVEN --> + <Key + latin:keyLabel="ຈ" + latin:keyHintLabel="7" + latin:additionalMoreKeys="7" + latin:moreKeys="໗" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0E82: "ຂ" LAO LETTER KHO SUNG + U+0ED8: "໘" LAO DIGIT EIGHT --> + <Key + latin:keyLabel="ຂ" + latin:keyHintLabel="8" + latin:additionalMoreKeys="8" + latin:moreKeys="໘" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0E8A: "ຊ" LAO LETTER SO TAM + U+0ED9: "໙" LAO DIGIT NINE --> + <Key + latin:keyLabel="ຊ" + latin:keyHintLabel="9" + latin:additionalMoreKeys="9" + latin:moreKeys="໙" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0ECD: "ໍ" LAO NIGGAHITA --> + <Key + latin:keyLabel="ໍ" + latin:keyLabelFlags="fontNormal" /> + </default> + </switch> +</merge> diff --git a/java/res/xml/rowkeys_lao2.xml b/java/res/xml/rowkeys_lao2.xml new file mode 100644 index 000000000..fca58ac0e --- /dev/null +++ b/java/res/xml/rowkeys_lao2.xml @@ -0,0 +1,127 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** +** Copyright 2013, 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. +*/ +--> + +<merge + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" +> + <switch> + <case + latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted" + > + <!-- U+0EBB/U+0EC9: "" LAO VOWEL SIGN MAI KON/LAO TONE MAI THO --> + <Key + latin:keyLabel="ົ້" + latin:keyLabelFlags="fontNormal|followKeyLetterRatio" /> + <!-- U+0ED0: "໐" LAO DIGIT ZERO --> + <Key + latin:keyLabel="໐" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EB3/U+0EC9: "ຳ້" LAO VOWEL SIGN AM/LAO TONE MAI THO --> + <Key + latin:keyLabel="ຳ້" + latin:keyLabelFlags="fontNormal|followKeyLetterRatio" /> + <Key + latin:keyLabel="_" /> + <Key + latin:keyLabel="+" /> + <!-- U+0EB4/U+0EC9: "ິ້" LAO VOWEL SIGN I/LAO TONE MAI THO --> + <Key + latin:keyLabel="ິ້" + latin:keyLabelFlags="fontNormal|followKeyLetterRatio" /> + <!-- U+0EB5/U+0EC9: "ີ້" LAO VOWEL SIGN II/LAO TONE MAI THO --> + <Key + latin:keyLabel="ີ້" + latin:keyLabelFlags="fontNormal|followKeyLetterRatio" /> + <!-- U+0EA3: "ຣ" LAO LETTER LO LING --> + <Key + latin:keyLabel="ຣ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EDC: "ໜ" LAO HO NO --> + <Key + latin:keyLabel="ໜ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EBD: "ຽ" LAO SEMIVOWEL SIGN NYO --> + <Key + latin:keyLabel="ຽ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EAB/U+0EBC: "" LAO LETTER HO SUNG/LAO SEMIVOWEL SIGN LO --> + <Key + latin:keyLabel="ຫຼ" + latin:keyLabelFlags="fontNormal|followKeyLetterRatio" /> + <!-- U+201D: "”" RIGHT DOUBLE QUOTATION MARK --> + <Key + latin:keyLabel="”" /> + </case> + <default> + <!-- U+0EBB: "ົ" LAO VOWEL SIGN MAI KON --> + <Key + latin:keyLabel="ົ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EC4: "ໄ" LAO VOWEL SIGN AI + U+0ED0: "໐" LAO DIGIT ZERO --> + <Key + latin:keyLabel="ໄ" + latin:keyHintLabel="0" + latin:additionalMoreKeys="0" + latin:moreKeys="໐" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EB3: "ຳ" LAO VOWEL SIGN AM --> + <Key + latin:keyLabel="ຳ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0E9E: "ພ" LAO LETTER PHO TAM --> + <Key + latin:keyLabel="ພ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EB0: "ະ" LAO VOWEL SIGN A --> + <Key + latin:keyLabel="ະ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EB4: "ິ" LAO VOWEL SIGN I --> + <Key + latin:keyLabel="ິ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EB5: "ີ" LAO VOWEL SIGN II --> + <Key + latin:keyLabel="ີ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EAE: "ຮ" LAO LETTER HO TAM --> + <Key + latin:keyLabel="ຮ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0E99: "ນ" LAO LETTER NO --> + <Key + latin:keyLabel="ນ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0E8D: "ຍ" LAO LETTER NYO --> + <Key + latin:keyLabel="ຍ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0E9A: "ບ" LAO LETTER BO --> + <Key + latin:keyLabel="ບ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EA5: "ລ" LAO LETTER LO LOOT --> + <Key + latin:keyLabel="ລ" + latin:keyLabelFlags="fontNormal" /> + </default> + </switch> +</merge> diff --git a/java/res/xml/rowkeys_lao3.xml b/java/res/xml/rowkeys_lao3.xml new file mode 100644 index 000000000..2a6c2d1dd --- /dev/null +++ b/java/res/xml/rowkeys_lao3.xml @@ -0,0 +1,110 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** +** Copyright 2013, 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. +*/ +--> + +<merge + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" +> + <switch> + <case + latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted" + > + <!-- U+0EB1/U+0EC9: "ັ້" LAO VOWEL SIGN MAI KAN/LAO TONE MAI THO --> + <Key + latin:keyLabel="ັ້" + latin:keyLabelFlags="fontNormal|followKeyLetterRatio" /> + <Key + latin:keyLabel=";" /> + <Key + latin:keyLabel="." /> + <Key + latin:keyLabel="," /> + <Key + latin:keyLabel=":" /> + <!-- U+0ECA: "໊" LAO TONE MAI TI --> + <Key + latin:keyLabel="໊" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0ECB: "໋" LAO TONE MAI CATAWA --> + <Key + latin:keyLabel="໋" + latin:keyLabelFlags="fontNormal" /> + <Key + latin:keyLabel="!" /> + <Key + latin:keyLabel="\?" /> + <Key + latin:keyLabel="%" /> + <Key + latin:keyLabel="=" /> + <!-- U+201C: "“" LEFT DOUBLE QUOTATION MARK --> + <Key + latin:keyLabel="“" /> + </case> + <default> + <!-- U+0EB1: "ັ" LAO VOWEL SIGN MAI KAN --> + <Key + latin:keyLabel="ັ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EAB: "ຫ" LAO LETTER HO SUNG --> + <Key + latin:keyLabel="ຫ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0E81: "ກ" LAO LETTER KO --> + <Key + latin:keyLabel="ກ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0E94: "ດ" LAO LETTER DO --> + <Key + latin:keyLabel="ດ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EC0: "ເ" LAO VOWEL SIGN E --> + <Key + latin:keyLabel="ເ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EC9: "້" LAO TONE MAI THO --> + <Key + latin:keyLabel="້" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EC8: "່" LAO TONE MAI EK --> + <Key + latin:keyLabel="່" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EB2: "າ" LAO VOWEL SIGN AA --> + <Key + latin:keyLabel="າ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EAA: "ສ" LAO LETTER SO SUNG --> + <Key + latin:keyLabel="ສ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EA7: "ວ" LAO LETTER WO --> + <Key + latin:keyLabel="ວ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0E87: "ງ" LAO LETTER NGO --> + <Key + latin:keyLabel="ງ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+201C: "“" LEFT DOUBLE QUOTATION MARK --> + <Key + latin:keyLabel="“" /> + </default> + </switch> +</merge> diff --git a/java/res/xml/rowkeys_lao4.xml b/java/res/xml/rowkeys_lao4.xml new file mode 100644 index 000000000..fae9cc923 --- /dev/null +++ b/java/res/xml/rowkeys_lao4.xml @@ -0,0 +1,103 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** +** Copyright 2013, 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. +*/ +--> + +<merge + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" +> + <switch> + <case + latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted" + > + <!-- U+20AD: "₭" KIP SIGN --> + <Key + latin:keyLabel="₭" /> + <Key + latin:keyLabel="(" /> + <!-- U+0EAF: "ຯ" LAO ELLIPSIS --> + <Key + latin:keyLabel="ຯ" + latin:keyLabelFlags="fontNormal" /> + <Key + latin:keyLabel="\@" /> + <!-- U+0EB6/U+0EC9: "ຶ້" LAO VOWEL SIGN Y/LAO TONE MAI THO --> + <Key + latin:keyLabel="ຶ້" + latin:keyLabelFlags="fontNormal|followKeyLetterRatio" /> + <!-- U+0EB7/U+0EC9: "ື້" LAO VOWEL SIGN YY/LAO TONE MAI THO --> + <Key + latin:keyLabel="ື້" + latin:keyLabelFlags="fontNormal|followKeyLetterRatio" /> + <!-- U+0EC6: "ໆ" LAO KO LA --> + <Key + latin:keyLabel="ໆ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EDD: "ໝ" LAO HO MO --> + <Key + latin:keyLabel="ໝ" + latin:keyLabelFlags="fontNormal" /> + <Key + latin:keyLabel="$" /> + <Key + latin:keyLabel=")" /> + </case> + <default> + <!-- U+0E9C: "ຜ" LAO LETTER PHO SUNG --> + <Key + latin:keyLabel="ຜ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0E9B: "ປ" LAO LETTER PO --> + <Key + latin:keyLabel="ປ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EC1: "ແ" LAO VOWEL SIGN EI --> + <Key + latin:keyLabel="ແ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EAD: "ອ" LAO LETTER O --> + <Key + latin:keyLabel="ອ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EB6: "ຶ" LAO VOWEL SIGN Y --> + <Key + latin:keyLabel="ຶ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EB7: "ື" LAO VOWEL SIGN YY --> + <Key + latin:keyLabel="ື" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0E97: "ທ" LAO LETTER THO TAM --> + <Key + latin:keyLabel="ທ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EA1: "ມ" LAO LETTER MO --> + <Key + latin:keyLabel="ມ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0EC3: "ໃ" LAO VOWEL SIGN AY --> + <Key + latin:keyLabel="ໃ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+0E9D: "ຝ" LAO LETTER FO TAM --> + <Key + latin:keyLabel="ຝ" + latin:keyLabelFlags="fontNormal" /> + </default> + </switch> +</merge> diff --git a/java/res/xml/rowkeys_nepali_romanized3.xml b/java/res/xml/rowkeys_nepali_romanized3.xml index 5660596f0..166d028a3 100644 --- a/java/res/xml/rowkeys_nepali_romanized3.xml +++ b/java/res/xml/rowkeys_nepali_romanized3.xml @@ -48,7 +48,7 @@ latin:keyLabelFlags="fontNormal" /> <!-- U+0923: "ण" DEVANAGARI LETTER NNA --> <Key - latin:keyLabel="श" + latin:keyLabel="ण" latin:keyLabelFlags="fontNormal" /> <!-- Because the font rendering system prior to API version 16 can't automatically render dotted circle for incomplete combining letter of some scripts, different diff --git a/java/res/xml/rows_lao.xml b/java/res/xml/rows_lao.xml new file mode 100644 index 000000000..321f4112a --- /dev/null +++ b/java/res/xml/rows_lao.xml @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** +** Copyright 2013, 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. +*/ +--> + +<merge + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" +> + <include + latin:keyboardLayout="@xml/key_styles_common" /> + <Row + latin:keyWidth="8.3333%p" + > + <include + latin:keyboardLayout="@xml/rowkeys_lao1" /> + </Row> + <Row + latin:keyWidth="8.3333%p" + > + <include + latin:keyboardLayout="@xml/rowkeys_lao2" /> + </Row> + <Row + latin:keyWidth="8.3333%p" + > + <include + latin:keyboardLayout="@xml/rowkeys_lao3" /> + </Row> + <Row + latin:keyWidth="8.3333%p" + > + <Key + latin:keyStyle="shiftKeyStyle" /> + <include + latin:keyboardLayout="@xml/rowkeys_lao4" /> + <Key + latin:keyStyle="deleteKeyStyle" /> + </Row> + <include + latin:keyboardLayout="@xml/row_qwerty4" /> +</merge> diff --git a/java/src/com/android/inputmethod/keyboard/EmojiKeyboardView.java b/java/src/com/android/inputmethod/keyboard/EmojiKeyboardView.java index 9996a6d6a..d28b5088c 100644 --- a/java/src/com/android/inputmethod/keyboard/EmojiKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/EmojiKeyboardView.java @@ -19,14 +19,18 @@ package com.android.inputmethod.keyboard; import static com.android.inputmethod.latin.Constants.NOT_A_COORDINATE; import android.content.Context; +import android.content.SharedPreferences; import android.content.res.ColorStateList; import android.content.res.Resources; import android.content.res.TypedArray; +import android.graphics.Rect; import android.os.Build; +import android.preference.PreferenceManager; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.util.AttributeSet; import android.util.Log; +import android.util.Pair; import android.util.SparseArray; import android.view.LayoutInflater; import android.view.View; @@ -43,11 +47,15 @@ import com.android.inputmethod.keyboard.internal.ScrollViewWithNotifier; import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.SubtypeSwitcher; +import com.android.inputmethod.latin.settings.Settings; import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.ResourceUtils; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; import java.util.HashMap; +import java.util.concurrent.ConcurrentHashMap; /** * View class to implement Emoji keyboards. @@ -75,16 +83,25 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange private KeyboardActionListener mKeyboardActionListener = KeyboardActionListener.EMPTY_LISTENER; + private static final int CATEGORY_ID_UNSPECIFIED = -1; + public static final int CATEGORY_ID_RECENTS = 0; + public static final int CATEGORY_ID_PEOPLE = 1; + public static final int CATEGORY_ID_OBJECTS = 2; + public static final int CATEGORY_ID_NATURE = 3; + public static final int CATEGORY_ID_PLACES = 4; + public static final int CATEGORY_ID_SYMBOLS = 5; + public static final int CATEGORY_ID_EMOTICONS = 6; + + private static class CategoryProperties { + public int mCategoryId; + public int mPageCount; + public CategoryProperties(final int categoryId, final int pageCount) { + mCategoryId = categoryId; + mPageCount = pageCount; + } + } + private static class EmojiCategory { - private int mCurrentCategory = CATEGORY_UNSPECIFIED; - private static final int CATEGORY_UNSPECIFIED = -1; - private static final int CATEGORY_RECENTS = 0; - private static final int CATEGORY_PEOPLE = 1; - private static final int CATEGORY_OBJECTS = 2; - private static final int CATEGORY_NATURE = 3; - private static final int CATEGORY_PLACES = 4; - private static final int CATEGORY_SYMBOLS = 5; - private static final int CATEGORY_EMOTICONS = 6; private static final String[] sCategoryName = { "recents", "people", @@ -110,87 +127,231 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange KeyboardId.ELEMENT_EMOJI_CATEGORY3, KeyboardId.ELEMENT_EMOJI_CATEGORY4, KeyboardId.ELEMENT_EMOJI_CATEGORY5, - KeyboardId.ELEMENT_EMOJI_CATEGORY6, }; + KeyboardId.ELEMENT_EMOJI_CATEGORY6 }; + private final SharedPreferences mPrefs; + private final int mMaxPageKeyCount; + private final KeyboardLayoutSet mLayoutSet; private final HashMap<String, Integer> mCategoryNameToIdMap = CollectionUtils.newHashMap(); - private final ArrayList<Integer> mShownCategories = new ArrayList<Integer>(); - - public EmojiCategory() { + private final ArrayList<CategoryProperties> mShownCategories = + CollectionUtils.newArrayList(); + private final ConcurrentHashMap<Long, DynamicGridKeyboard> + mCategoryKeyboardMap = new ConcurrentHashMap<Long, DynamicGridKeyboard>(); + + private int mCurrentCategoryId = CATEGORY_ID_UNSPECIFIED; + private int mCurrentCategoryPageId = 0; + + public EmojiCategory(final SharedPreferences prefs, final Resources res, + final KeyboardLayoutSet layoutSet) { + mPrefs = prefs; + mMaxPageKeyCount = res.getInteger(R.integer.emoji_keyboard_max_key_count); + mLayoutSet = layoutSet; for (int i = 0; i < sCategoryName.length; ++i) { mCategoryNameToIdMap.put(sCategoryName[i], i); } - mShownCategories.add(CATEGORY_RECENTS); + addShownCategoryId(CATEGORY_ID_RECENTS); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { - mShownCategories.add(CATEGORY_PEOPLE); - mShownCategories.add(CATEGORY_OBJECTS); - mShownCategories.add(CATEGORY_NATURE); - mShownCategories.add(CATEGORY_PLACES); - // TODO: Restore last saved category - mCurrentCategory = CATEGORY_PEOPLE; + addShownCategoryId(CATEGORY_ID_PEOPLE); + addShownCategoryId(CATEGORY_ID_OBJECTS); + addShownCategoryId(CATEGORY_ID_NATURE); + addShownCategoryId(CATEGORY_ID_PLACES); + mCurrentCategoryId = CATEGORY_ID_PEOPLE; } else { - // TODO: Restore last saved category - mCurrentCategory = CATEGORY_SYMBOLS; + mCurrentCategoryId = CATEGORY_ID_SYMBOLS; } - mShownCategories.add(CATEGORY_SYMBOLS); - mShownCategories.add(CATEGORY_EMOTICONS); + addShownCategoryId(CATEGORY_ID_SYMBOLS); + addShownCategoryId(CATEGORY_ID_EMOTICONS); + getKeyboard(CATEGORY_ID_RECENTS, 0 /* cagetoryPageId */) + .loadRecentKeys(mCategoryKeyboardMap.values()); + } + + private void addShownCategoryId(int categoryId) { + // Load a keyboard of categoryId + getKeyboard(categoryId, 0 /* cagetoryPageId */); + final CategoryProperties properties = + new CategoryProperties(categoryId, getCategoryPageCount(categoryId)); + mShownCategories.add(properties); } - public String getCategoryName(int category) { - return sCategoryName[category]; + public String getCategoryName(int categoryId, int categoryPageId) { + return sCategoryName[categoryId] + "-" + categoryPageId; } public int getCategoryId(String name) { - return mCategoryNameToIdMap.get(name); + final String[] strings = name.split("-"); + return mCategoryNameToIdMap.get(strings[0]); } - public int getCategoryIcon(int category) { - return sCategoryIcon[category]; + public int getCategoryIcon(int categoryId) { + return sCategoryIcon[categoryId]; } - public String getCategoryLabel(int category) { - return sCategoryLabel[category]; + public String getCategoryLabel(int categoryId) { + return sCategoryLabel[categoryId]; } - public ArrayList<Integer> getShownCategories() { + public ArrayList<CategoryProperties> getShownCategories() { return mShownCategories; } - public int getCurrentCategory() { - // TODO: Record current category. - return mCurrentCategory; + public int getCurrentCategoryId() { + return mCurrentCategoryId; + } + + public void setCurrentCategoryId(int categoryId) { + mCurrentCategoryId = categoryId; } - public void setCurrentCategory(int category) { - mCurrentCategory = category; + public void setCurrentCategoryPageId(int id) { + mCurrentCategoryPageId = id; + } + + public void saveLastTypedCategoryPage() { + Settings.writeEmojiCategoryLastTypedId( + mPrefs, mCurrentCategoryId, mCurrentCategoryPageId); } public boolean isInRecentTab() { - return mCurrentCategory == CATEGORY_RECENTS; + return mCurrentCategoryId == CATEGORY_ID_RECENTS; } - public int getTabIdFromCategory(int category) { + public int getTabIdFromCategoryId(int categoryId) { for (int i = 0; i < mShownCategories.size(); ++i) { - if (mShownCategories.get(i) == category) { + if (mShownCategories.get(i).mCategoryId == categoryId) { return i; } } - Log.w(TAG, "category not found: " + category); + Log.w(TAG, "categoryId not found: " + categoryId); + return 0; + } + + // Returns the view pager's page position for the categoryId + public int getPageIdFromCategoryId(int categoryId) { + final int lastSavedCategoryPageId = + Settings.readEmojiCategoryLastTypedId(mPrefs, categoryId); + int sum = 0; + for (int i = 0; i < mShownCategories.size(); ++i) { + final CategoryProperties props = mShownCategories.get(i); + if (props.mCategoryId == categoryId) { + return sum + lastSavedCategoryPageId; + } + sum += props.mPageCount; + } + Log.w(TAG, "categoryId not found: " + categoryId); return 0; } public int getRecentTabId() { - return getTabIdFromCategory(CATEGORY_RECENTS); + return getTabIdFromCategoryId(CATEGORY_ID_RECENTS); } - public int getCategoryFromTabId(int tabId) { - return mShownCategories.get(tabId); + private int getCategoryPageCount(int categoryId) { + final Keyboard keyboard = mLayoutSet.getKeyboard(sCategoryElementId[categoryId]); + return (keyboard.getKeys().length - 1) / mMaxPageKeyCount + 1; } - public int getElementIdFromTabId(int tabId) { - return sCategoryElementId[getCategoryFromTabId(tabId)]; + // Returns a pair of the category id and the category page id from the view pager's page + // position. The category page id is numbered in each category. And the view page position + // is the position of the current shown page in the view pager which contains all pages of + // all categories. + public Pair<Integer, Integer> getCategoryIdAndPageIdFromPagePosition(int position) { + int sum = 0; + for (CategoryProperties properties : mShownCategories) { + final int temp = sum; + sum += properties.mPageCount; + if (sum > position) { + return new Pair<Integer, Integer>(properties.mCategoryId, position - temp); + } + } + return null; + } + + // Returns a keyboard from the view pager's page position. + public DynamicGridKeyboard getKeyboardFromPagePosition(int position) { + final Pair<Integer, Integer> categoryAndId = + getCategoryIdAndPageIdFromPagePosition(position); + if (categoryAndId != null) { + return getKeyboard(categoryAndId.first, categoryAndId.second); + } + return null; + } + + public DynamicGridKeyboard getKeyboard(int categoryId, int id) { + synchronized(mCategoryKeyboardMap) { + final long key = (((long) categoryId) << Constants.MAX_INT_BIT_COUNT) | id; + final DynamicGridKeyboard kbd; + if (!mCategoryKeyboardMap.containsKey(key)) { + if (categoryId != CATEGORY_ID_RECENTS) { + final Keyboard keyboard = + mLayoutSet.getKeyboard(sCategoryElementId[categoryId]); + final Key[][] sortedKeys = sortKeys(keyboard.getKeys(), mMaxPageKeyCount); + for (int i = 0; i < sortedKeys.length; ++i) { + final DynamicGridKeyboard tempKbd = new DynamicGridKeyboard(mPrefs, + mLayoutSet.getKeyboard(KeyboardId.ELEMENT_EMOJI_RECENTS), + mMaxPageKeyCount, categoryId, i /* categoryPageId */); + for (Key emojiKey : sortedKeys[i]) { + if (emojiKey == null) { + break; + } + tempKbd.addKeyLast(emojiKey); + } + mCategoryKeyboardMap.put((((long) categoryId) + << Constants.MAX_INT_BIT_COUNT) | i, tempKbd); + } + kbd = mCategoryKeyboardMap.get(key); + } else { + kbd = new DynamicGridKeyboard(mPrefs, + mLayoutSet.getKeyboard(KeyboardId.ELEMENT_EMOJI_RECENTS), + mMaxPageKeyCount, categoryId, 0 /* categoryPageId */); + mCategoryKeyboardMap.put(key, kbd); + } + } else { + kbd = mCategoryKeyboardMap.get(key); + } + return kbd; + } + } + + public int getTotalPageCountOfAllCategories() { + int sum = 0; + for (CategoryProperties properties : mShownCategories) { + sum += properties.mPageCount; + } + return sum; + } + + private Key[][] sortKeys(Key[] inKeys, int maxPageCount) { + Key[] keys = Arrays.copyOf(inKeys, inKeys.length); + Arrays.sort(keys, 0, keys.length, new Comparator<Key>() { + @Override + public int compare(Key lhs, Key rhs) { + final Rect lHitBox = lhs.getHitBox(); + final Rect rHitBox = rhs.getHitBox(); + if (lHitBox.top < rHitBox.top) { + return -1; + } else if (lHitBox.top > rHitBox.top) { + return 1; + } + if (lHitBox.left < rHitBox.left) { + return -1; + } else if (lHitBox.left > rHitBox.left) { + return 1; + } + if (lhs.getCode() == rhs.getCode()) { + return 0; + } + return lhs.getCode() < rhs.getCode() ? -1 : 1; + } + }); + final int pageCount = (keys.length - 1) / maxPageCount + 1; + final Key[][] retval = new Key[pageCount][maxPageCount]; + for (int i = 0; i < keys.length; ++i) { + retval[i / maxPageCount][i % maxPageCount] = keys[i]; + } + return retval; } } - private final EmojiCategory mEmojiCategory = new EmojiCategory(); + private final EmojiCategory mEmojiCategory; public EmojiKeyboardView(final Context context, final AttributeSet attrs) { this(context, attrs, R.attr.emojiKeyboardViewStyle); @@ -213,13 +374,14 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange final KeyboardLayoutSet.Builder builder = new KeyboardLayoutSet.Builder( context, null /* editorInfo */); final Resources res = context.getResources(); + final EmojiLayoutParams emojiLp = new EmojiLayoutParams(res); builder.setSubtype(SubtypeSwitcher.getInstance().getEmojiSubtype()); builder.setKeyboardGeometry(ResourceUtils.getDefaultKeyboardWidth(res), - (int)ResourceUtils.getDefaultKeyboardHeight(res) - + res.getDimensionPixelSize(R.dimen.suggestions_strip_height)); + emojiLp.mEmojiKeyboardHeight); builder.setOptions(false, false, false /* lanuageSwitchKeyEnabled */); mLayoutSet = builder.build(); - // TODO: Save/restore recent keys from/to preferences. + mEmojiCategory = new EmojiCategory(PreferenceManager.getDefaultSharedPreferences(context), + context.getResources(), builder.build()); } @Override @@ -235,20 +397,20 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange setMeasuredDimension(width, height); } - private void addTab(final TabHost host, final int category) { - final String tabId = mEmojiCategory.getCategoryName(category); + private void addTab(final TabHost host, final int categoryId) { + final String tabId = mEmojiCategory.getCategoryName(categoryId, 0 /* categoryPageId */); final TabHost.TabSpec tspec = host.newTabSpec(tabId); tspec.setContent(R.id.emoji_keyboard_dummy); - if (mEmojiCategory.getCategoryIcon(category) != 0) { + if (mEmojiCategory.getCategoryIcon(categoryId) != 0) { final ImageView iconView = (ImageView)LayoutInflater.from(getContext()).inflate( R.layout.emoji_keyboard_tab_icon, null); - iconView.setImageResource(mEmojiCategory.getCategoryIcon(category)); + iconView.setImageResource(mEmojiCategory.getCategoryIcon(categoryId)); tspec.setIndicator(iconView); } - if (mEmojiCategory.getCategoryLabel(category) != null) { + if (mEmojiCategory.getCategoryLabel(categoryId) != null) { final TextView textView = (TextView)LayoutInflater.from(getContext()).inflate( R.layout.emoji_keyboard_tab_label, null); - textView.setText(mEmojiCategory.getCategoryLabel(category)); + textView.setText(mEmojiCategory.getCategoryLabel(categoryId)); textView.setTextColor(mTabLabelColor); tspec.setIndicator(textView); } @@ -259,8 +421,8 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange protected void onFinishInflate() { mTabHost = (TabHost)findViewById(R.id.emoji_category_tabhost); mTabHost.setup(); - for (final int i : mEmojiCategory.getShownCategories()) { - addTab(mTabHost, i); + for (final CategoryProperties properties : mEmojiCategory.getShownCategories()) { + addTab(mTabHost, properties.mCategoryId); } mTabHost.setOnTabChangedListener(this); mTabHost.getTabWidget().setStripEnabled(true); @@ -275,7 +437,7 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange final EmojiLayoutParams emojiLp = new EmojiLayoutParams(res); emojiLp.setPagerProps(mEmojiPager); - setCurrentCategory(mEmojiCategory.getCurrentCategory(), true /* force */); + setCurrentCategoryId(mEmojiCategory.getCurrentCategoryId(), true /* force */); final LinearLayout actionBar = (LinearLayout)findViewById(R.id.emoji_action_bar); emojiLp.setActionBarProps(actionBar); @@ -302,14 +464,17 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange @Override public void onTabChanged(final String tabId) { - final int category = mEmojiCategory.getCategoryId(tabId); - setCurrentCategory(category, false /* force */); + final int categoryId = mEmojiCategory.getCategoryId(tabId); + setCurrentCategoryId(categoryId, false /* force */); } @Override public void onPageSelected(final int position) { - setCurrentCategory(mEmojiCategory.getCategoryFromTabId(position), false /* force */); + final Pair<Integer, Integer> newPos = + mEmojiCategory.getCategoryIdAndPageIdFromPagePosition(position); + setCurrentCategoryId(newPos.first /* categoryId */, false /* force */); + mEmojiCategory.setCurrentCategoryPageId(newPos.second /* categoryPageId */); } @Override @@ -341,6 +506,7 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange @Override public void onKeyClick(final Key key) { mEmojiKeyboardAdapter.addRecentKey(key); + mEmojiCategory.saveLastTypedCategoryPage(); final int code = key.getCode(); if (code == Constants.CODE_OUTPUT_TEXT) { mKeyboardActionListener.onTextInput(key.getOutputText()); @@ -357,25 +523,25 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange mKeyboardActionListener = listener; } - private void setCurrentCategory(final int category, final boolean force) { - if (mEmojiCategory.getCurrentCategory() == category && !force) { + private void setCurrentCategoryId(final int categoryId, final boolean force) { + if (mEmojiCategory.getCurrentCategoryId() == categoryId && !force) { return; } - mEmojiCategory.setCurrentCategory(category); - final int newTabId = mEmojiCategory.getTabIdFromCategory(category); - if (force || mEmojiPager.getCurrentItem() != newTabId) { - mEmojiPager.setCurrentItem(newTabId, true /* smoothScroll */); + mEmojiCategory.setCurrentCategoryId(categoryId); + final int newTabId = mEmojiCategory.getTabIdFromCategoryId(categoryId); + final int newCategoryPageId = mEmojiCategory.getPageIdFromCategoryId(categoryId); + if (force || mEmojiCategory.getCategoryIdAndPageIdFromPagePosition( + mEmojiPager.getCurrentItem()).first != categoryId) { + mEmojiPager.setCurrentItem(newCategoryPageId, true /* smoothScroll */); } if (force || mTabHost.getCurrentTab() != newTabId) { mTabHost.setCurrentTab(newTabId); } - // TODO: Record current category } private static class EmojiKeyboardAdapter extends PagerAdapter { private final ScrollKeyboardView.OnKeyClickListener mListener; - private final KeyboardLayoutSet mLayoutSet; private final DynamicGridKeyboard mRecentsKeyboard; private final SparseArray<ScrollKeyboardView> mActiveKeyboardView = CollectionUtils.newSparseArray(); @@ -387,16 +553,14 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange final ScrollKeyboardView.OnKeyClickListener listener) { mEmojiCategory = emojiCategory; mListener = listener; - mLayoutSet = layoutSet; - mRecentsKeyboard = new DynamicGridKeyboard( - layoutSet.getKeyboard(KeyboardId.ELEMENT_EMOJI_RECENTS)); + mRecentsKeyboard = mEmojiCategory.getKeyboard(CATEGORY_ID_RECENTS, 0); } public void addRecentKey(final Key key) { if (mEmojiCategory.isInRecentTab()) { return; } - mRecentsKeyboard.addRecentKey(key); + mRecentsKeyboard.addKeyFirst(key); final KeyboardView recentKeyboardView = mActiveKeyboardView.get(mEmojiCategory.getRecentTabId()); if (recentKeyboardView != null) { @@ -406,7 +570,7 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange @Override public int getCount() { - return mEmojiCategory.getShownCategories().size(); + return mEmojiCategory.getTotalPageCountOfAllCategories(); } @Override @@ -424,9 +588,8 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange @Override public Object instantiateItem(final ViewGroup container, final int position) { - final int elementId = mEmojiCategory.getElementIdFromTabId(position); - final Keyboard keyboard = (elementId == KeyboardId.ELEMENT_EMOJI_RECENTS) - ? mRecentsKeyboard : mLayoutSet.getKeyboard(elementId); + final Keyboard keyboard = + mEmojiCategory.getKeyboardFromPagePosition(position); final LayoutInflater inflater = LayoutInflater.from(container.getContext()); final View view = inflater.inflate( R.layout.emoji_keyboard_page, container, false /* attachToRoot */); diff --git a/java/src/com/android/inputmethod/keyboard/EmojiLayoutParams.java b/java/src/com/android/inputmethod/keyboard/EmojiLayoutParams.java index 6486fc9db..5570d594d 100644 --- a/java/src/com/android/inputmethod/keyboard/EmojiLayoutParams.java +++ b/java/src/com/android/inputmethod/keyboard/EmojiLayoutParams.java @@ -27,6 +27,8 @@ import android.widget.LinearLayout; public class EmojiLayoutParams { private static final int DEFAULT_KEYBOARD_ROWS = 4; + public final int mEmojiPagerHeight; + private final int mEmojiPagerBottomMargin; public final int mEmojiKeyboardHeight; public final int mEmojiActionBarHeight; public final int mKeyVerticalGap; @@ -49,13 +51,15 @@ public class EmojiLayoutParams { + mKeyVerticalGap; mEmojiActionBarHeight = ((int) baseheight) / DEFAULT_KEYBOARD_ROWS - (mKeyVerticalGap - mBottomPadding) / 2; - mEmojiKeyboardHeight = defaultKeyboardHeight - mEmojiActionBarHeight; + mEmojiPagerHeight = defaultKeyboardHeight - mEmojiActionBarHeight; + mEmojiPagerBottomMargin = mKeyVerticalGap / 2; + mEmojiKeyboardHeight = mEmojiPagerHeight - mEmojiPagerBottomMargin - 1; } public void setPagerProps(ViewPager vp) { final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) vp.getLayoutParams(); - lp.height = mEmojiKeyboardHeight - mKeyVerticalGap / 2; - lp.bottomMargin = mKeyVerticalGap / 2; + lp.height = mEmojiPagerHeight - mEmojiPagerBottomMargin; + lp.bottomMargin = mEmojiPagerBottomMargin; vp.setLayoutParams(lp); } diff --git a/java/src/com/android/inputmethod/keyboard/internal/DynamicGridKeyboard.java b/java/src/com/android/inputmethod/keyboard/internal/DynamicGridKeyboard.java index a226891b4..f203eb7d7 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/DynamicGridKeyboard.java +++ b/java/src/com/android/inputmethod/keyboard/internal/DynamicGridKeyboard.java @@ -16,33 +16,41 @@ package com.android.inputmethod.keyboard.internal; +import android.content.SharedPreferences; import android.text.TextUtils; +import com.android.inputmethod.keyboard.EmojiKeyboardView; import com.android.inputmethod.keyboard.Key; import com.android.inputmethod.keyboard.Keyboard; +import com.android.inputmethod.latin.Constants; +import com.android.inputmethod.latin.settings.Settings; import com.android.inputmethod.latin.utils.CollectionUtils; import java.util.ArrayDeque; -import java.util.Random; +import java.util.Collection; /** * This is a Keyboard class where you can add keys dynamically shown in a grid layout */ -// TODO: Save/restore recent keys from/to preferences. public class DynamicGridKeyboard extends Keyboard { private static final int TEMPLATE_KEY_CODE_0 = 0x30; private static final int TEMPLATE_KEY_CODE_1 = 0x31; + // Recent codes are saved as an integer array, so we use comma as a separater. + private static final String RECENT_KEY_SEPARATOR = Constants.STRING_COMMA; + private final SharedPreferences mPrefs; private final int mLeftPadding; private final int mHorizontalStep; private final int mVerticalStep; private final int mColumnsNum; - private final int mMaxRecentKeyCount; - private final ArrayDeque<RecentKey> mRecentKeys = CollectionUtils.newArrayDeque(); + private final int mMaxKeyCount; + private final boolean mIsRecents; + private final ArrayDeque<GridKey> mGridKeys = CollectionUtils.newArrayDeque(); - private Key[] mCachedRecentKeys; + private Key[] mCachedGridKeys; - public DynamicGridKeyboard(final Keyboard templateKeyboard) { + public DynamicGridKeyboard(final SharedPreferences prefs, final Keyboard templateKeyboard, + final int maxKeyCount, final int categoryId, final int categoryPageId) { super(templateKeyboard); final Key key0 = getTemplateKey(TEMPLATE_KEY_CODE_0); final Key key1 = getTemplateKey(TEMPLATE_KEY_CODE_1); @@ -50,8 +58,9 @@ public class DynamicGridKeyboard extends Keyboard { mHorizontalStep = Math.abs(key1.getX() - key0.getX()); mVerticalStep = key0.getHeight() + mVerticalGap; mColumnsNum = mBaseWidth / mHorizontalStep; - final int rowsNum = mBaseHeight / mVerticalStep; - mMaxRecentKeyCount = mColumnsNum * rowsNum; + mMaxKeyCount = maxKeyCount; + mIsRecents = categoryId == EmojiKeyboardView.CATEGORY_ID_RECENTS; + mPrefs = prefs; } private Key getTemplateKey(final int code) { @@ -63,32 +72,67 @@ public class DynamicGridKeyboard extends Keyboard { throw new RuntimeException("Can't find template key: code=" + code); } - private final Random random = new Random(); + public void addKeyFirst(final Key usedKey) { + addKey(usedKey, true); + if (mIsRecents) { + saveRecentKeys(); + } + } + + public void addKeyLast(final Key usedKey) { + addKey(usedKey, false); + } - public void addRecentKey(final Key usedKey) { - synchronized (mRecentKeys) { - mCachedRecentKeys = null; - final RecentKey key = (usedKey instanceof RecentKey) - ? (RecentKey)usedKey : new RecentKey(usedKey); - while (mRecentKeys.remove(key)) { + private void addKey(final Key usedKey, final boolean addFirst) { + synchronized (mGridKeys) { + mCachedGridKeys = null; + final GridKey key = new GridKey(usedKey); + while (mGridKeys.remove(key)) { // Remove duplicate keys. } - mRecentKeys.addFirst(key); - while (mRecentKeys.size() > mMaxRecentKeyCount) { - mRecentKeys.removeLast(); + if (addFirst) { + mGridKeys.addFirst(key); + } else { + mGridKeys.addLast(key); + } + while (mGridKeys.size() > mMaxKeyCount) { + mGridKeys.removeLast(); } int index = 0; - for (final RecentKey recentKey : mRecentKeys) { + for (final GridKey gridKey : mGridKeys) { final int keyX = getKeyX(index); final int keyY = getKeyY(index); - final int x = keyX+random.nextInt(recentKey.getWidth()); - final int y = keyY+random.nextInt(recentKey.getHeight()); - recentKey.updateCorrdinates(keyX, keyY); + gridKey.updateCorrdinates(keyX, keyY); index++; } } } + private void saveRecentKeys() { + final StringBuilder sb = new StringBuilder(); + for (final Key key : mGridKeys) { + sb.append(key.getCode()).append(RECENT_KEY_SEPARATOR); + } + Settings.writeEmojiRecentKeys(mPrefs, sb.toString()); + } + + public void loadRecentKeys(Collection<DynamicGridKeyboard> keyboards) { + final String str = Settings.readEmojiRecentKeys(mPrefs); + for (String s : str.split(RECENT_KEY_SEPARATOR)) { + if (TextUtils.isEmpty(s)) { + continue; + } + final int code = Integer.valueOf(s); + for (DynamicGridKeyboard kbd : keyboards) { + final Key key = kbd.getKey(code); + if (key != null) { + addKeyLast(key); + break; + } + } + } + } + private int getKeyX(final int index) { final int column = index % mColumnsNum; return column * mHorizontalStep + mLeftPadding; @@ -101,26 +145,26 @@ public class DynamicGridKeyboard extends Keyboard { @Override public Key[] getKeys() { - synchronized (mRecentKeys) { - if (mCachedRecentKeys != null) { - return mCachedRecentKeys; + synchronized (mGridKeys) { + if (mCachedGridKeys != null) { + return mCachedGridKeys; } - mCachedRecentKeys = mRecentKeys.toArray(new Key[mRecentKeys.size()]); - return mCachedRecentKeys; + mCachedGridKeys = mGridKeys.toArray(new Key[mGridKeys.size()]); + return mCachedGridKeys; } } @Override public Key[] getNearestKeys(final int x, final int y) { - // TODO: Calculate the nearest key index in mRecentKeys from x and y. + // TODO: Calculate the nearest key index in mGridKeys from x and y. return getKeys(); } - static final class RecentKey extends Key { + static final class GridKey extends Key { private int mCurrentX; private int mCurrentY; - public RecentKey(final Key originalKey) { + public GridKey(final Key originalKey) { super(originalKey); } @@ -151,7 +195,7 @@ public class DynamicGridKeyboard extends Keyboard { @Override public String toString() { - return "RecentKey: " + super.toString(); + return "GridKey: " + super.toString(); } } } diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java index 7008b0619..a72595f7c 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java @@ -383,7 +383,7 @@ public final class KeyboardTextsSet { // Label for "switch to more symbol" modifier key. Must be short to fit on key! /* 124 */ "= \\ <", // Label for "switch to more symbol" modifier key on tablets. Must be short to fit on key! - /* 125 */ "~ [ {", + /* 125 */ "~ [ <", // Label for "Tab" key. Must be short to fit on key! /* 126 */ "Tab", // Label for "switch to phone numeric" key. Must be short to fit on key! @@ -2056,6 +2056,25 @@ public final class KeyboardTextsSet { /* 45 */ "\u0410\u0411\u0412", }; + /* Language lo: Lao */ + private static final String[] LANGUAGE_lo = { + /* 0~ */ + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + /* ~44 */ + // Label for "switch to alphabetic" key. + // U+0E81: "ກ" LAO LETTER KO + // U+0E82: "ຂ" LAO LETTER KHO SUNG + // U+0E84: "ຄ" LAO LETTER KHO TAM + /* 45 */ "\u0E81\u0E82\u0E84", + /* 46~ */ + null, null, null, null, null, + /* ~50 */ + // U+20AD: "₭" KIP SIGN + /* 51 */ "\u20AD", + }; + /* Language lt: Lithuanian */ private static final String[] LANGUAGE_lt = { // U+0105: "ą" LATIN SMALL LETTER A WITH OGONEK @@ -2347,6 +2366,63 @@ public final class KeyboardTextsSet { /* 47 */ "!text/double_9qm_rqm", }; + /* Language ne: Nepali */ + private static final String[] LANGUAGE_ne = { + /* 0~ */ + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + /* ~44 */ + // Label for "switch to alphabetic" key. + // U+0915: "क" DEVANAGARI LETTER KA + // U+0916: "ख" DEVANAGARI LETTER KHA + // U+0917: "ग" DEVANAGARI LETTER GA + /* 45 */ "\u0915\u0916\u0917", + /* 46~ */ + null, null, null, null, null, + /* ~50 */ + // U+0930/U+0941/U+002E "रु." NEPALESE RUPEE SIGN + /* 51 */ "\u0930\u0941.", + /* 52~ */ + null, null, null, null, null, null, null, null, null, null, null, + /* ~62 */ + // U+0967: "१" DEVANAGARI DIGIT ONE + /* 63 */ "\u0967", + // U+0968: "२" DEVANAGARI DIGIT TWO + /* 64 */ "\u0968", + // U+0969: "३" DEVANAGARI DIGIT THREE + /* 65 */ "\u0969", + // U+096A: "४" DEVANAGARI DIGIT FOUR + /* 66 */ "\u096A", + // U+096B: "५" DEVANAGARI DIGIT FIVE + /* 67 */ "\u096B", + // U+096C: "६" DEVANAGARI DIGIT SIX + /* 68 */ "\u096C", + // U+096D: "७" DEVANAGARI DIGIT SEVEN + /* 69 */ "\u096D", + // U+096E: "८" DEVANAGARI DIGIT EIGHT + /* 70 */ "\u096E", + // U+096F: "९" DEVANAGARI DIGIT NINE + /* 71 */ "\u096F", + // U+0966: "०" DEVANAGARI DIGIT ZERO + /* 72 */ "\u0966", + // Label for "switch to symbols" key. + /* 73 */ "?\u0967\u0968\u0969", + // Label for "switch to symbols with microphone" key. This string shouldn't include the "mic" + // part because it'll be appended by the code. + /* 74 */ "\u0967\u0968\u0969", + /* 75 */ "1", + /* 76 */ "2", + /* 77 */ "3", + /* 78 */ "4", + /* 79 */ "5", + /* 80 */ "6", + /* 81 */ "7", + /* 82 */ "8", + /* 83 */ "9", + /* 84 */ "0", + }; + /* Language nl: Dutch */ private static final String[] LANGUAGE_nl = { // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE @@ -3332,11 +3408,13 @@ public final class KeyboardTextsSet { "ka", LANGUAGE_ka, /* Georgian */ "kk", LANGUAGE_kk, /* Kazakh */ "ky", LANGUAGE_ky, /* Kirghiz */ + "lo", LANGUAGE_lo, /* Lao */ "lt", LANGUAGE_lt, /* Lithuanian */ "lv", LANGUAGE_lv, /* Latvian */ "mk", LANGUAGE_mk, /* Macedonian */ "mn", LANGUAGE_mn, /* Mongolian */ "nb", LANGUAGE_nb, /* Norwegian Bokmål */ + "ne", LANGUAGE_ne, /* Nepali */ "nl", LANGUAGE_nl, /* Dutch */ "pl", LANGUAGE_pl, /* Polish */ "pt", LANGUAGE_pt, /* Portuguese */ diff --git a/java/src/com/android/inputmethod/latin/Constants.java b/java/src/com/android/inputmethod/latin/Constants.java index 8aec03f71..029ba02ed 100644 --- a/java/src/com/android/inputmethod/latin/Constants.java +++ b/java/src/com/android/inputmethod/latin/Constants.java @@ -220,7 +220,11 @@ public final class Constants { } } + public static final int MAX_INT_BIT_COUNT = 32; + public static final String STRING_COMMA = ","; + private Constants() { // This utility class is not publicly instantiable. } + } diff --git a/java/src/com/android/inputmethod/latin/settings/Settings.java b/java/src/com/android/inputmethod/latin/settings/Settings.java index 686c8d5f5..1a0fecc62 100644 --- a/java/src/com/android/inputmethod/latin/settings/Settings.java +++ b/java/src/com/android/inputmethod/latin/settings/Settings.java @@ -98,6 +98,10 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang public static final String PREF_SEND_FEEDBACK = "send_feedback"; public static final String PREF_ABOUT_KEYBOARD = "about_keyboard"; + // Emoji + public static final String PREF_EMOJI_RECENT_KEYS = "emoji_recent_keys"; + public static final String PREF_EMOJI_CATEGORY_LAST_TYPED_ID = "emoji_category_last_typed_id"; + private Resources mRes; private SharedPreferences mPrefs; private SettingsValues mSettingsValues; @@ -370,4 +374,24 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang final String tokenStr = mPrefs.getString(PREF_LAST_USED_PERSONALIZATION_TOKEN, null); return StringUtils.hexStringToByteArray(tokenStr); } + + public static void writeEmojiRecentKeys(final SharedPreferences prefs, String str) { + prefs.edit().putString(PREF_EMOJI_RECENT_KEYS, str).apply(); + } + + public static String readEmojiRecentKeys(final SharedPreferences prefs) { + return prefs.getString(PREF_EMOJI_RECENT_KEYS, ""); + } + + public static void writeEmojiCategoryLastTypedId( + final SharedPreferences prefs, final int category, final int id) { + final String key = PREF_EMOJI_CATEGORY_LAST_TYPED_ID + category; + prefs.edit().putInt(key, id).apply(); + } + + public static int readEmojiCategoryLastTypedId( + final SharedPreferences prefs, final int category) { + final String key = PREF_EMOJI_CATEGORY_LAST_TYPED_ID + category; + return prefs.getInt(key, 0); + } } diff --git a/native/jni/src/defines.h b/native/jni/src/defines.h index 4605890c7..89dfa39b3 100644 --- a/native/jni/src/defines.h +++ b/native/jni/src/defines.h @@ -292,7 +292,6 @@ static inline void prof_out(void) { // of the binary dictionary where a {key,value} string pair scheme is used. #define LARGEST_INT_DIGIT_COUNT 11 -#define NOT_A_VALID_WORD_POS (-99) #define NOT_A_CODE_POINT (-1) #define NOT_A_DISTANCE (-1) #define NOT_A_COORDINATE (-1) diff --git a/native/jni/src/suggest/core/dicnode/dic_node.h b/native/jni/src/suggest/core/dicnode/dic_node.h index cdd9f59aa..377015371 100644 --- a/native/jni/src/suggest/core/dicnode/dic_node.h +++ b/native/jni/src/suggest/core/dicnode/dic_node.h @@ -112,7 +112,7 @@ class DicNode { mIsUsed = true; mIsCachedForNextSuggestion = false; mDicNodeProperties.init( - NOT_A_VALID_WORD_POS /* pos */, rootGroupPos, NOT_A_CODE_POINT /* nodeCodePoint */, + NOT_A_DICT_POS /* pos */, rootGroupPos, NOT_A_CODE_POINT /* nodeCodePoint */, NOT_A_PROBABILITY /* probability */, false /* isTerminal */, true /* hasChildren */, false /* isBlacklistedOrNotAWord */, 0 /* depth */, 0 /* terminalDepth */); @@ -125,7 +125,7 @@ class DicNode { mIsUsed = true; mIsCachedForNextSuggestion = dicNode->mIsCachedForNextSuggestion; mDicNodeProperties.init( - NOT_A_VALID_WORD_POS /* pos */, rootGroupPos, NOT_A_CODE_POINT /* nodeCodePoint */, + NOT_A_DICT_POS /* pos */, rootGroupPos, NOT_A_CODE_POINT /* nodeCodePoint */, NOT_A_PROBABILITY /* probability */, false /* isTerminal */, true /* hasChildren */, false /* isBlacklistedOrNotAWord */, 0 /* depth */, 0 /* terminalDepth */); @@ -234,7 +234,7 @@ class DicNode { } bool isFirstWord() const { - return mDicNodeState.mDicNodeStatePrevWord.getPrevWordNodePos() == NOT_A_VALID_WORD_POS; + return mDicNodeState.mDicNodeStatePrevWord.getPrevWordNodePos() == NOT_A_DICT_POS; } bool isCompletion(const int inputSize) const { 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 e81591992..ec65114c7 100644 --- a/native/jni/src/suggest/core/dicnode/dic_node_utils.cpp +++ b/native/jni/src/suggest/core/dicnode/dic_node_utils.cpp @@ -89,7 +89,7 @@ namespace latinime { const int unigramProbability = node->getProbability(); const int wordPos = node->getPos(); const int prevWordPos = node->getPrevWordPos(); - if (NOT_A_VALID_WORD_POS == wordPos || NOT_A_VALID_WORD_POS == prevWordPos) { + if (NOT_A_DICT_POS == wordPos || NOT_A_DICT_POS == prevWordPos) { // Note: Normally wordPos comes from the dictionary and should never equal // NOT_A_VALID_WORD_POS. return dictionaryStructurePolicy->getProbability(unigramProbability, diff --git a/native/jni/src/suggest/core/dicnode/internal/dic_node_state_prevword.h b/native/jni/src/suggest/core/dicnode/internal/dic_node_state_prevword.h index 9bc96877e..b7af97018 100644 --- a/native/jni/src/suggest/core/dicnode/internal/dic_node_state_prevword.h +++ b/native/jni/src/suggest/core/dicnode/internal/dic_node_state_prevword.h @@ -29,7 +29,7 @@ class DicNodeStatePrevWord { public: AK_FORCE_INLINE DicNodeStatePrevWord() : mPrevWordCount(0), mPrevWordLength(0), mPrevWordStart(0), mPrevWordProbability(0), - mPrevWordNodePos(NOT_A_VALID_WORD_POS) { + mPrevWordNodePos(NOT_A_DICT_POS) { memset(mPrevWord, 0, sizeof(mPrevWord)); memset(mPrevSpacePositions, 0, sizeof(mPrevSpacePositions)); } @@ -41,7 +41,7 @@ class DicNodeStatePrevWord { mPrevWordCount = 0; mPrevWordStart = 0; mPrevWordProbability = -1; - mPrevWordNodePos = NOT_A_VALID_WORD_POS; + mPrevWordNodePos = NOT_A_DICT_POS; memset(mPrevSpacePositions, 0, sizeof(mPrevSpacePositions)); } diff --git a/native/jni/src/suggest/core/dictionary/bigram_dictionary.cpp b/native/jni/src/suggest/core/dictionary/bigram_dictionary.cpp index cf1cd8815..425b07624 100644 --- a/native/jni/src/suggest/core/dictionary/bigram_dictionary.cpp +++ b/native/jni/src/suggest/core/dictionary/bigram_dictionary.cpp @@ -116,7 +116,7 @@ int BigramDictionary::getPredictions(const int *prevWord, const int prevWordLeng mDictionaryStructurePolicy->getBigramsStructurePolicy(), pos); while (bigramsIt.hasNext()) { bigramsIt.next(); - if (bigramsIt.getBigramPos() == NOT_A_VALID_WORD_POS) { + if (bigramsIt.getBigramPos() == NOT_A_DICT_POS) { continue; } const int codePointCount = mDictionaryStructurePolicy-> @@ -146,7 +146,7 @@ int BigramDictionary::getBigramListPositionForWord(const int *prevWord, const in if (0 >= prevWordLength) return NOT_A_DICT_POS; int pos = mDictionaryStructurePolicy->getTerminalNodePositionOfWord(prevWord, prevWordLength, forceLowerCaseSearch); - if (NOT_A_VALID_WORD_POS == pos) return NOT_A_DICT_POS; + if (NOT_A_DICT_POS == pos) return NOT_A_DICT_POS; return mDictionaryStructurePolicy->getBigramsPositionOfNode(pos); } @@ -157,7 +157,7 @@ bool BigramDictionary::isValidBigram(const int *word0, int length0, const int *w if (NOT_A_DICT_POS == pos) return false; int nextWordPos = mDictionaryStructurePolicy->getTerminalNodePositionOfWord(word1, length1, false /* forceLowerCaseSearch */); - if (NOT_A_VALID_WORD_POS == nextWordPos) return false; + if (NOT_A_DICT_POS == nextWordPos) return false; BinaryDictionaryBigramsIterator bigramsIt( mDictionaryStructurePolicy->getBigramsStructurePolicy(), pos); diff --git a/native/jni/src/suggest/core/dictionary/dictionary.cpp b/native/jni/src/suggest/core/dictionary/dictionary.cpp index 02ece639c..29fe7ab94 100644 --- a/native/jni/src/suggest/core/dictionary/dictionary.cpp +++ b/native/jni/src/suggest/core/dictionary/dictionary.cpp @@ -87,7 +87,7 @@ int Dictionary::getBigrams(const int *word, int length, int *outWords, int *freq int Dictionary::getProbability(const int *word, int length) const { int pos = getDictionaryStructurePolicy()->getTerminalNodePositionOfWord(word, length, false /* forceLowerCaseSearch */); - if (NOT_A_VALID_WORD_POS == pos) { + if (NOT_A_DICT_POS == pos) { return NOT_A_PROBABILITY; } return getDictionaryStructurePolicy()->getUnigramProbabilityOfPtNode(pos); 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 9efe5f6f9..aecf41386 100644 --- a/native/jni/src/suggest/core/dictionary/multi_bigram_map.h +++ b/native/jni/src/suggest/core/dictionary/multi_bigram_map.h @@ -73,7 +73,7 @@ class MultiBigramMap { bigramsListPos); while (bigramsIt.hasNext()) { bigramsIt.next(); - if (bigramsIt.getBigramPos() == NOT_A_VALID_WORD_POS) { + if (bigramsIt.getBigramPos() == NOT_A_DICT_POS) { continue; } mBigramMap[bigramsIt.getBigramPos()] = bigramsIt.getProbability(); 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 2c2259214..50f2bbd8d 100644 --- a/native/jni/src/suggest/core/session/dic_traverse_session.cpp +++ b/native/jni/src/suggest/core/session/dic_traverse_session.cpp @@ -35,13 +35,13 @@ void DicTraverseSession::init(const Dictionary *const dictionary, const int *pre ->getMultiWordCostMultiplier(); mSuggestOptions = suggestOptions; if (!prevWord) { - mPrevWordPos = NOT_A_VALID_WORD_POS; + mPrevWordPos = NOT_A_DICT_POS; return; } // TODO: merge following similar calls to getTerminalPosition into one case-insensitive call. mPrevWordPos = getDictionaryStructurePolicy()->getTerminalNodePositionOfWord( prevWord, prevWordLength, false /* forceLowerCaseSearch */); - if (mPrevWordPos == NOT_A_VALID_WORD_POS) { + if (mPrevWordPos == NOT_A_DICT_POS) { // Check bigrams for lower-cased previous word if original was not found. Useful for // auto-capitalized words like "The [current_word]". mPrevWordPos = getDictionaryStructurePolicy()->getTerminalNodePositionOfWord( 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 fe8893590..e2ef5fc76 100644 --- a/native/jni/src/suggest/core/session/dic_traverse_session.h +++ b/native/jni/src/suggest/core/session/dic_traverse_session.h @@ -59,7 +59,7 @@ class DicTraverseSession { } AK_FORCE_INLINE DicTraverseSession(JNIEnv *env, jstring localeStr, bool usesLargeCache) - : mPrevWordPos(NOT_A_VALID_WORD_POS), mProximityInfo(0), + : mPrevWordPos(NOT_A_DICT_POS), mProximityInfo(0), mDictionary(0), mSuggestOptions(0), mDicNodesCache(usesLargeCache), mMultiBigramMap(), mInputSize(0), mPartiallyCommited(false), mMaxPointerCount(1), mMultiWordCostMultiplier(1.0f) { diff --git a/native/jni/src/suggest/policyimpl/dictionary/bigram/bigram_list_read_write_utils.cpp b/native/jni/src/suggest/policyimpl/dictionary/bigram/bigram_list_read_write_utils.cpp index d57547445..09e832f07 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/bigram/bigram_list_read_write_utils.cpp +++ b/native/jni/src/suggest/policyimpl/dictionary/bigram/bigram_list_read_write_utils.cpp @@ -38,6 +38,22 @@ const BigramListReadWriteUtils::BigramFlags BigramListReadWriteUtils::MASK_ATTRIBUTE_PROBABILITY = 0x0F; const int BigramListReadWriteUtils::ATTRIBUTE_ADDRESS_SHIFT = 4; +/* static */ BigramListReadWriteUtils::BigramFlags + BigramListReadWriteUtils::getFlagsAndForwardPointer(const uint8_t *const bigramsBuf, + int *const pos) { + return ByteArrayUtils::readUint8AndAdvancePosition(bigramsBuf, pos); +} + +/* static */ void BigramListReadWriteUtils::skipExistingBigrams(const uint8_t *const bigramsBuf, + int *const pos) { + BigramFlags flags = getFlagsAndForwardPointer(bigramsBuf, pos); + while (hasNext(flags)) { + *pos += attributeAddressSize(flags); + flags = getFlagsAndForwardPointer(bigramsBuf, pos); + } + *pos += attributeAddressSize(flags); +} + /* static */ int BigramListReadWriteUtils::getBigramAddressAndForwardPointer( const uint8_t *const bigramsBuf, const BigramFlags flags, int *const pos) { int offset = 0; @@ -54,7 +70,7 @@ const int BigramListReadWriteUtils::ATTRIBUTE_ADDRESS_SHIFT = 4; break; } if (offset == 0) { - return NOT_A_VALID_WORD_POS; + return NOT_A_DICT_POS; } if (isOffsetNegative(flags)) { return origin - offset; diff --git a/native/jni/src/suggest/policyimpl/dictionary/bigram/bigram_list_read_write_utils.h b/native/jni/src/suggest/policyimpl/dictionary/bigram/bigram_list_read_write_utils.h index ee2b722a4..9a930747c 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/bigram/bigram_list_read_write_utils.h +++ b/native/jni/src/suggest/policyimpl/dictionary/bigram/bigram_list_read_write_utils.h @@ -21,7 +21,6 @@ #include <stdint.h> #include "defines.h" -#include "suggest/policyimpl/dictionary/utils/byte_array_utils.h" namespace latinime { @@ -29,10 +28,7 @@ class BigramListReadWriteUtils { public: typedef uint8_t BigramFlags; - static AK_FORCE_INLINE BigramFlags getFlagsAndForwardPointer( - const uint8_t *const bigramsBuf, int *const pos) { - return ByteArrayUtils::readUint8AndAdvancePosition(bigramsBuf, pos); - } + static BigramFlags getFlagsAndForwardPointer(const uint8_t *const bigramsBuf, int *const pos); static AK_FORCE_INLINE int getProbabilityFromFlags(const BigramFlags flags) { return flags & MASK_ATTRIBUTE_PROBABILITY; @@ -43,15 +39,7 @@ public: } // Bigrams reading methods - static AK_FORCE_INLINE void skipExistingBigrams(const uint8_t *const bigramsBuf, - int *const pos) { - BigramFlags flags = getFlagsAndForwardPointer(bigramsBuf, pos); - while (hasNext(flags)) { - *pos += attributeAddressSize(flags); - flags = getFlagsAndForwardPointer(bigramsBuf, pos); - } - *pos += attributeAddressSize(flags); - } + static void skipExistingBigrams(const uint8_t *const bigramsBuf, int *const pos); static int getBigramAddressAndForwardPointer(const uint8_t *const bigramsBuf, const BigramFlags flags, int *const pos); @@ -79,7 +67,7 @@ public: const int entryPos, const int targetPos, const int probability, const bool hasNext, BigramFlags *const outBigramFlags, uint32_t *const outOffset, int *const outOffsetFieldSize) { - if (targetPos == NOT_A_VALID_WORD_POS) { + if (targetPos == NOT_A_DICT_POS) { return false; } BigramFlags flags = probability & MASK_ATTRIBUTE_PROBABILITY; diff --git a/native/jni/src/suggest/policyimpl/dictionary/bigram/dynamic_bigram_list_policy.cpp b/native/jni/src/suggest/policyimpl/dictionary/bigram/dynamic_bigram_list_policy.cpp index 4ee138125..ca3b64da1 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/bigram/dynamic_bigram_list_policy.cpp +++ b/native/jni/src/suggest/policyimpl/dictionary/bigram/dynamic_bigram_list_policy.cpp @@ -31,7 +31,7 @@ void DynamicBigramListPolicy::getNextBigram(int *const outBigramPos, int *const BigramListReadWriteUtils::getFlagsAndForwardPointer(buffer, pos); int originalBigramPos = BigramListReadWriteUtils::getBigramAddressAndForwardPointer( buffer, flags, pos); - if (usesAdditionalBuffer && originalBigramPos != NOT_A_VALID_WORD_POS) { + if (usesAdditionalBuffer && originalBigramPos != NOT_A_DICT_POS) { originalBigramPos += mBuffer->getOriginalBufferSize(); } *outBigramPos = followBigramLinkAndGetCurrentBigramPtNodePos(originalBigramPos); @@ -66,7 +66,7 @@ bool DynamicBigramListPolicy::copyAllBigrams(int *const fromPos, int *const toPo flags = BigramListReadWriteUtils::getFlagsAndForwardPointer(buffer, fromPos); int originalBigramPos = BigramListReadWriteUtils::getBigramAddressAndForwardPointer( buffer, flags, fromPos); - if (originalBigramPos == NOT_A_VALID_WORD_POS) { + if (originalBigramPos == NOT_A_DICT_POS) { // skip invalid bigram entry. continue; } @@ -172,7 +172,7 @@ bool DynamicBigramListPolicy::removeBigram(const int bigramListPos, const int ta } int originalBigramPos = BigramListReadWriteUtils::getBigramAddressAndForwardPointer( buffer, flags, &pos); - if (usesAdditionalBuffer && originalBigramPos != NOT_A_VALID_WORD_POS) { + if (usesAdditionalBuffer && originalBigramPos != NOT_A_DICT_POS) { originalBigramPos += mBuffer->getOriginalBufferSize(); } const int bigramPos = followBigramLinkAndGetCurrentBigramPtNodePos(originalBigramPos); @@ -192,8 +192,8 @@ bool DynamicBigramListPolicy::removeBigram(const int bigramListPos, const int ta int DynamicBigramListPolicy::followBigramLinkAndGetCurrentBigramPtNodePos( const int originalBigramPos) const { - if (originalBigramPos == NOT_A_VALID_WORD_POS) { - return NOT_A_VALID_WORD_POS; + if (originalBigramPos == NOT_A_DICT_POS) { + return NOT_A_DICT_POS; } int currentPos = originalBigramPos; DynamicPatriciaTrieNodeReader nodeReader(mBuffer, this /* bigramsPolicy */, mShortcutPolicy); @@ -206,7 +206,7 @@ int DynamicBigramListPolicy::followBigramLinkAndGetCurrentBigramPtNodePos( if (bigramLinkCount > BIGRAM_LINK_COUNT_LIMIT) { AKLOGI("Bigram link is invalid. start position: %d", bigramPos); ASSERT(false); - return NOT_A_VALID_WORD_POS; + return NOT_A_DICT_POS; } } return currentPos; diff --git a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.cpp b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.cpp index 56ef60ae4..e455080d7 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.cpp +++ b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.cpp @@ -25,6 +25,13 @@ namespace latinime { void DynamicPatriciaTrieNodeReader::fetchNodeInfoFromBufferAndProcessMovedNode(const int nodePos, const int maxCodePointCount, int *const outCodePoints) { + if (nodePos < 0 || nodePos >= mBuffer->getTailPosition()) { + AKLOGE("Fetching PtNode info form invalid dictionary position: %d, dictionary size: %d", + nodePos, mBuffer->getTailPosition()); + ASSERT(false); + invalidatePtNodeInfo(); + return; + } const bool usesAdditionalBuffer = mBuffer->isInAdditionalBuffer(nodePos); const uint8_t *const dictBuf = mBuffer->getBuffer(usesAdditionalBuffer); int pos = nodePos; @@ -62,7 +69,7 @@ void DynamicPatriciaTrieNodeReader::fetchNodeInfoFromBufferAndProcessMovedNode(c if (usesAdditionalBuffer && mChildrenPos != NOT_A_DICT_POS) { mChildrenPos += mBuffer->getOriginalBufferSize(); } - if (mSiblingPos == NOT_A_VALID_WORD_POS && DynamicPatriciaTrieReadingUtils::isMoved(mFlags)) { + if (mSiblingPos == NOT_A_DICT_POS && DynamicPatriciaTrieReadingUtils::isMoved(mFlags)) { mBigramLinkedNodePos = mChildrenPos; } else { mBigramLinkedNodePos = NOT_A_DICT_POS; @@ -83,7 +90,7 @@ void DynamicPatriciaTrieNodeReader::fetchNodeInfoFromBufferAndProcessMovedNode(c mBigramPos = NOT_A_DICT_POS; } // Update siblingPos if needed. - if (mSiblingPos == NOT_A_VALID_WORD_POS) { + if (mSiblingPos == NOT_A_DICT_POS) { // Sibling position is the tail position of current node. mSiblingPos = pos; } @@ -94,4 +101,19 @@ void DynamicPatriciaTrieNodeReader::fetchNodeInfoFromBufferAndProcessMovedNode(c } } +void DynamicPatriciaTrieNodeReader::invalidatePtNodeInfo() { + mHeadPos = NOT_A_DICT_POS; + mFlags = 0; + mParentPos = NOT_A_DICT_POS; + mCodePointCount = 0; + mProbabilityFieldPos = NOT_A_DICT_POS; + mProbability = NOT_A_PROBABILITY; + mChildrenPosFieldPos = NOT_A_DICT_POS; + mChildrenPos = NOT_A_DICT_POS; + mBigramLinkedNodePos = NOT_A_DICT_POS; + mShortcutPos = NOT_A_DICT_POS; + mBigramPos = NOT_A_DICT_POS; + mSiblingPos = NOT_A_DICT_POS; +} + } diff --git a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.h b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.h index 89d38a590..6ef5f5813 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.h +++ b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.h @@ -39,12 +39,12 @@ class DynamicPatriciaTrieNodeReader { const DictionaryBigramsStructurePolicy *const bigramsPolicy, const DictionaryShortcutsStructurePolicy *const shortcutsPolicy) : mBuffer(buffer), mBigramsPolicy(bigramsPolicy), - mShortcutsPolicy(shortcutsPolicy), mHeadPos(NOT_A_VALID_WORD_POS), mFlags(0), + mShortcutsPolicy(shortcutsPolicy), mHeadPos(NOT_A_DICT_POS), mFlags(0), mParentPos(NOT_A_DICT_POS), mCodePointCount(0), mProbabilityFieldPos(NOT_A_DICT_POS), mProbability(NOT_A_PROBABILITY), mChildrenPosFieldPos(NOT_A_DICT_POS), mChildrenPos(NOT_A_DICT_POS), mBigramLinkedNodePos(NOT_A_DICT_POS), mShortcutPos(NOT_A_DICT_POS), mBigramPos(NOT_A_DICT_POS), - mSiblingPos(NOT_A_VALID_WORD_POS) {} + mSiblingPos(NOT_A_DICT_POS) {} ~DynamicPatriciaTrieNodeReader() {} @@ -56,7 +56,7 @@ class DynamicPatriciaTrieNodeReader { AK_FORCE_INLINE void fetchNodeInfoFromBufferAndGetNodeCodePoints(const int nodePos, const int maxCodePointCount, int *const outCodePoints) { - mSiblingPos = NOT_A_VALID_WORD_POS; + mSiblingPos = NOT_A_DICT_POS; mBigramLinkedNodePos = NOT_A_DICT_POS; fetchNodeInfoFromBufferAndProcessMovedNode(nodePos, maxCodePointCount, outCodePoints); } @@ -156,6 +156,8 @@ class DynamicPatriciaTrieNodeReader { void fetchNodeInfoFromBufferAndProcessMovedNode(const int nodePos, const int maxCodePointCount, int *const outCodePoints); + + void invalidatePtNodeInfo(); }; } // namespace latinime #endif /* LATINIME_DYNAMIC_PATRICIA_TRIE_NODE_READER_H */ diff --git a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_policy.cpp b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_policy.cpp index ece1781f1..cccc09041 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_policy.cpp +++ b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_policy.cpp @@ -116,7 +116,7 @@ int DynamicPatriciaTriePolicy::getTerminalNodePositionOfWord(const int *const in if (!readingHelper.isMatchedCodePoint( j, searchCodePoints[matchedCodePointCount + j])) { // Different code point is found. The given word is not included in the dictionary. - return NOT_A_VALID_WORD_POS; + return NOT_A_DICT_POS; } } // All characters are matched. @@ -125,14 +125,14 @@ int DynamicPatriciaTriePolicy::getTerminalNodePositionOfWord(const int *const in return nodeReader->getHeadPos(); } if (!nodeReader->hasChildren()) { - return NOT_A_VALID_WORD_POS; + return NOT_A_DICT_POS; } // Advance to the children nodes. readingHelper.readChildNode(); } // If we already traversed the tree further than the word is long, there means // there was no match (or we would have found it). - return NOT_A_VALID_WORD_POS; + return NOT_A_DICT_POS; } int DynamicPatriciaTriePolicy::getProbability(const int unigramProbability, @@ -149,7 +149,7 @@ int DynamicPatriciaTriePolicy::getProbability(const int unigramProbability, } int DynamicPatriciaTriePolicy::getUnigramProbabilityOfPtNode(const int nodePos) const { - if (nodePos == NOT_A_VALID_WORD_POS) { + if (nodePos == NOT_A_DICT_POS) { return NOT_A_PROBABILITY; } DynamicPatriciaTrieNodeReader nodeReader(&mBufferWithExtendableBuffer, @@ -162,7 +162,7 @@ int DynamicPatriciaTriePolicy::getUnigramProbabilityOfPtNode(const int nodePos) } int DynamicPatriciaTriePolicy::getShortcutPositionOfNode(const int nodePos) const { - if (nodePos == NOT_A_VALID_WORD_POS) { + if (nodePos == NOT_A_DICT_POS) { return NOT_A_DICT_POS; } DynamicPatriciaTrieNodeReader nodeReader(&mBufferWithExtendableBuffer, @@ -175,7 +175,7 @@ int DynamicPatriciaTriePolicy::getShortcutPositionOfNode(const int nodePos) cons } int DynamicPatriciaTriePolicy::getBigramsPositionOfNode(const int nodePos) const { - if (nodePos == NOT_A_VALID_WORD_POS) { + if (nodePos == NOT_A_DICT_POS) { return NOT_A_DICT_POS; } DynamicPatriciaTrieNodeReader nodeReader(&mBufferWithExtendableBuffer, @@ -209,12 +209,12 @@ bool DynamicPatriciaTriePolicy::addBigramWords(const int *const word0, const int } const int word0Pos = getTerminalNodePositionOfWord(word0, length0, false /* forceLowerCaseSearch */); - if (word0Pos == NOT_A_VALID_WORD_POS) { + if (word0Pos == NOT_A_DICT_POS) { return false; } const int word1Pos = getTerminalNodePositionOfWord(word1, length1, false /* forceLowerCaseSearch */); - if (word1Pos == NOT_A_VALID_WORD_POS) { + if (word1Pos == NOT_A_DICT_POS) { return false; } DynamicPatriciaTrieWritingHelper writingHelper(&mBufferWithExtendableBuffer, @@ -230,12 +230,12 @@ bool DynamicPatriciaTriePolicy::removeBigramWords(const int *const word0, const } const int word0Pos = getTerminalNodePositionOfWord(word0, length0, false /* forceLowerCaseSearch */); - if (word0Pos == NOT_A_VALID_WORD_POS) { + if (word0Pos == NOT_A_DICT_POS) { return false; } const int word1Pos = getTerminalNodePositionOfWord(word1, length1, false /* forceLowerCaseSearch */); - if (word1Pos == NOT_A_VALID_WORD_POS) { + if (word1Pos == NOT_A_DICT_POS) { return false; } DynamicPatriciaTrieWritingHelper writingHelper(&mBufferWithExtendableBuffer, diff --git a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_reading_helper.h b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_reading_helper.h index db1c392bb..120fd7699 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_reading_helper.h +++ b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_reading_helper.h @@ -72,8 +72,7 @@ class DynamicPatriciaTrieReadingHelper { // Initialize reading state with the head position of a node. AK_FORCE_INLINE void initWithNodePos(const int nodePos) { - // TODO: Consolidate NOT_A_VALID_WORD_POS and NOT_A_DICT_POS - if (nodePos == NOT_A_VALID_WORD_POS || nodePos == NOT_A_DICT_POS) { + if (nodePos == NOT_A_DICT_POS) { mPos = NOT_A_DICT_POS; } else { mIsError = false; diff --git a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_reading_utils.cpp b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_reading_utils.cpp index c7e89fff8..8428c0b15 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_reading_utils.cpp +++ b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_reading_utils.cpp @@ -28,6 +28,17 @@ const DptReadingUtils::NodeFlags DptReadingUtils::FLAG_IS_NOT_MOVED = 0xC0; const DptReadingUtils::NodeFlags DptReadingUtils::FLAG_IS_MOVED = 0x40; const DptReadingUtils::NodeFlags DptReadingUtils::FLAG_IS_DELETED = 0x80; +/* static */ int DptReadingUtils::getForwardLinkPosition(const uint8_t *const buffer, + const int pos) { + int linkAddressPos = pos; + return ByteArrayUtils::readSint24AndAdvancePosition(buffer, &linkAddressPos); +} + +/* static */ int DptReadingUtils::getParentPosAndAdvancePosition(const uint8_t *const buffer, + int *const pos) { + return ByteArrayUtils::readSint24AndAdvancePosition(buffer, pos); +} + /* static */ int DptReadingUtils::readChildrenPositionAndAdvancePosition( const uint8_t *const buffer, int *const pos) { const int base = *pos; diff --git a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_reading_utils.h b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_reading_utils.h index 5a2ad9cb9..db5f9b1bd 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_reading_utils.h +++ b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_reading_utils.h @@ -20,7 +20,6 @@ #include <stdint.h> #include "defines.h" -#include "suggest/policyimpl/dictionary/utils/byte_array_utils.h" namespace latinime { @@ -28,19 +27,13 @@ class DynamicPatriciaTrieReadingUtils { public: typedef uint8_t NodeFlags; - static AK_FORCE_INLINE int getForwardLinkPosition(const uint8_t *const buffer, const int pos) { - int linkAddressPos = pos; - return ByteArrayUtils::readSint24AndAdvancePosition(buffer, &linkAddressPos); - } + static int getForwardLinkPosition(const uint8_t *const buffer, const int pos); static AK_FORCE_INLINE bool isValidForwardLinkPosition(const int forwardLinkAddress) { return forwardLinkAddress != 0; } - static AK_FORCE_INLINE int getParentPosAndAdvancePosition(const uint8_t *const buffer, - int *const pos) { - return ByteArrayUtils::readSint24AndAdvancePosition(buffer, pos); - } + static int getParentPosAndAdvancePosition(const uint8_t *const buffer, int *const pos); static int readChildrenPositionAndAdvancePosition(const uint8_t *const buffer, int *const pos); diff --git a/native/jni/src/suggest/policyimpl/dictionary/patricia_trie_policy.cpp b/native/jni/src/suggest/policyimpl/dictionary/patricia_trie_policy.cpp index d5a83a938..e6cff431b 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/patricia_trie_policy.cpp +++ b/native/jni/src/suggest/policyimpl/dictionary/patricia_trie_policy.cpp @@ -219,7 +219,7 @@ int PatriciaTriePolicy::getCodePointsAndProbabilityAndReturnCodePointCount( } // This function gets the position of the terminal node of the exact matching word in the -// dictionary. If no match is found, it returns NOT_A_VALID_WORD_POS. +// dictionary. If no match is found, it returns NOT_A_DICT_POS. int PatriciaTriePolicy::getTerminalNodePositionOfWord(const int *const inWord, const int length, const bool forceLowerCaseSearch) const { int pos = getRootPosition(); @@ -228,7 +228,7 @@ int PatriciaTriePolicy::getTerminalNodePositionOfWord(const int *const inWord, while (true) { // If we already traversed the tree further than the word is long, there means // there was no match (or we would have found it). - if (wordPos >= length) return NOT_A_VALID_WORD_POS; + if (wordPos >= length) return NOT_A_DICT_POS; int ptNodeCount = PatriciaTrieReadingUtils::getPtNodeArraySizeAndAdvancePosition(mDictRoot, &pos); const int wChar = forceLowerCaseSearch @@ -236,7 +236,7 @@ int PatriciaTriePolicy::getTerminalNodePositionOfWord(const int *const inWord, while (true) { // If there are no more PtNodes in this array, it means we could not // find a matching character for this depth, therefore there is no match. - if (0 >= ptNodeCount) return NOT_A_VALID_WORD_POS; + if (0 >= ptNodeCount) return NOT_A_DICT_POS; const int ptNodePos = pos; const PatriciaTrieReadingUtils::NodeFlags flags = PatriciaTrieReadingUtils::getFlagsAndAdvancePosition(mDictRoot, &pos); @@ -245,7 +245,7 @@ int PatriciaTriePolicy::getTerminalNodePositionOfWord(const int *const inWord, if (character == wChar) { // This is the correct PtNode. Only one PtNode may start with the same char within // a PtNode array, so either we found our match in this array, or there is - // no match and we can return NOT_A_VALID_WORD_POS. So we will check all the + // no match and we can return NOT_A_DICT_POS. So we will check all the // characters in this PtNode indeed does match. if (PatriciaTrieReadingUtils::hasMultipleChars(flags)) { character = PatriciaTrieReadingUtils::getCodePointAndAdvancePosition(mDictRoot, @@ -256,8 +256,8 @@ int PatriciaTriePolicy::getTerminalNodePositionOfWord(const int *const inWord, // character that does not match, as explained above, it means the word is // not in the dictionary (by virtue of this PtNode being the only one to // match the word on the first character, but not matching the whole word). - if (wordPos >= length) return NOT_A_VALID_WORD_POS; - if (inWord[wordPos] != character) return NOT_A_VALID_WORD_POS; + if (wordPos >= length) return NOT_A_DICT_POS; + if (inWord[wordPos] != character) return NOT_A_DICT_POS; character = PatriciaTrieReadingUtils::getCodePointAndAdvancePosition( mDictRoot, &pos); } @@ -274,7 +274,7 @@ int PatriciaTriePolicy::getTerminalNodePositionOfWord(const int *const inWord, PatriciaTrieReadingUtils::readProbabilityAndAdvancePosition(mDictRoot, &pos); } if (!PatriciaTrieReadingUtils::hasChildrenInFlags(flags)) { - return NOT_A_VALID_WORD_POS; + return NOT_A_DICT_POS; } // We have children and we are still shorter than the word we are searching for, so // we need to traverse children. Put the pointer on the children position, and @@ -320,7 +320,7 @@ int PatriciaTriePolicy::getProbability(const int unigramProbability, } int PatriciaTriePolicy::getUnigramProbabilityOfPtNode(const int nodePos) const { - if (nodePos == NOT_A_VALID_WORD_POS) { + if (nodePos == NOT_A_DICT_POS) { return NOT_A_PROBABILITY; } int pos = nodePos; @@ -342,7 +342,7 @@ int PatriciaTriePolicy::getUnigramProbabilityOfPtNode(const int nodePos) const { } int PatriciaTriePolicy::getShortcutPositionOfNode(const int nodePos) const { - if (nodePos == NOT_A_VALID_WORD_POS) { + if (nodePos == NOT_A_DICT_POS) { return NOT_A_DICT_POS; } int pos = nodePos; @@ -362,7 +362,7 @@ int PatriciaTriePolicy::getShortcutPositionOfNode(const int nodePos) const { } int PatriciaTriePolicy::getBigramsPositionOfNode(const int nodePos) const { - if (nodePos == NOT_A_VALID_WORD_POS) { + if (nodePos == NOT_A_DICT_POS) { return NOT_A_DICT_POS; } int pos = nodePos; diff --git a/native/jni/src/suggest/policyimpl/dictionary/patricia_trie_reading_utils.cpp b/native/jni/src/suggest/policyimpl/dictionary/patricia_trie_reading_utils.cpp index 576a158bc..1316b425f 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/patricia_trie_reading_utils.cpp +++ b/native/jni/src/suggest/policyimpl/dictionary/patricia_trie_reading_utils.cpp @@ -42,6 +42,63 @@ const PtReadingUtils::NodeFlags PtReadingUtils::FLAG_IS_NOT_A_WORD = 0x02; // Flag for blacklist const PtReadingUtils::NodeFlags PtReadingUtils::FLAG_IS_BLACKLISTED = 0x01; +/* static */ int PtReadingUtils::getPtNodeArraySizeAndAdvancePosition( + const uint8_t *const buffer, int *const pos) { + const uint8_t firstByte = ByteArrayUtils::readUint8AndAdvancePosition(buffer, pos); + if (firstByte < 0x80) { + return firstByte; + } else { + return ((firstByte & 0x7F) << 8) ^ ByteArrayUtils::readUint8AndAdvancePosition( + buffer, pos); + } +} + +/* static */ PtReadingUtils::NodeFlags PtReadingUtils::getFlagsAndAdvancePosition( + const uint8_t *const buffer, int *const pos) { + return ByteArrayUtils::readUint8AndAdvancePosition(buffer, pos); +} + +/* static */ int PtReadingUtils::getCodePointAndAdvancePosition(const uint8_t *const buffer, + int *const pos) { + return ByteArrayUtils::readCodePointAndAdvancePosition(buffer, pos); +} + +// Returns the number of read characters. +/* static */ int PtReadingUtils::getCharsAndAdvancePosition(const uint8_t *const buffer, + const NodeFlags flags, const int maxLength, int *const outBuffer, int *const pos) { + int length = 0; + if (hasMultipleChars(flags)) { + length = ByteArrayUtils::readStringAndAdvancePosition(buffer, maxLength, outBuffer, + pos); + } else { + if (maxLength > 0) { + outBuffer[0] = getCodePointAndAdvancePosition(buffer, pos); + length = 1; + } + } + return length; +} + +// Returns the number of skipped characters. +/* static */ int PtReadingUtils::skipCharacters(const uint8_t *const buffer, const NodeFlags flags, + const int maxLength, int *const pos) { + if (hasMultipleChars(flags)) { + return ByteArrayUtils::advancePositionToBehindString(buffer, maxLength, pos); + } else { + if (maxLength > 0) { + getCodePointAndAdvancePosition(buffer, pos); + return 1; + } else { + return 0; + } + } +} + +/* static */ int PtReadingUtils::readProbabilityAndAdvancePosition(const uint8_t *const buffer, + int *const pos) { + return ByteArrayUtils::readUint8AndAdvancePosition(buffer, pos); +} + /* static */ int PtReadingUtils::readChildrenPositionAndAdvancePosition( const uint8_t *const buffer, const NodeFlags flags, int *const pos) { const int base = *pos; diff --git a/native/jni/src/suggest/policyimpl/dictionary/patricia_trie_reading_utils.h b/native/jni/src/suggest/policyimpl/dictionary/patricia_trie_reading_utils.h index 2b0646db2..8420ee95a 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/patricia_trie_reading_utils.h +++ b/native/jni/src/suggest/policyimpl/dictionary/patricia_trie_reading_utils.h @@ -20,7 +20,6 @@ #include <stdint.h> #include "defines.h" -#include "suggest/policyimpl/dictionary/utils/byte_array_utils.h" namespace latinime { @@ -28,62 +27,21 @@ class PatriciaTrieReadingUtils { public: typedef uint8_t NodeFlags; - static AK_FORCE_INLINE int getPtNodeArraySizeAndAdvancePosition( - const uint8_t *const buffer, int *const pos) { - const uint8_t firstByte = ByteArrayUtils::readUint8AndAdvancePosition(buffer, pos); - if (firstByte < 0x80) { - return firstByte; - } else { - return ((firstByte & 0x7F) << 8) ^ ByteArrayUtils::readUint8AndAdvancePosition( - buffer, pos); - } - } + static int getPtNodeArraySizeAndAdvancePosition(const uint8_t *const buffer, int *const pos); - static AK_FORCE_INLINE NodeFlags getFlagsAndAdvancePosition(const uint8_t *const buffer, - int *const pos) { - return ByteArrayUtils::readUint8AndAdvancePosition(buffer, pos); - } + static NodeFlags getFlagsAndAdvancePosition(const uint8_t *const buffer, int *const pos); - static AK_FORCE_INLINE int getCodePointAndAdvancePosition(const uint8_t *const buffer, - int *const pos) { - return ByteArrayUtils::readCodePointAndAdvancePosition(buffer, pos); - } + static int getCodePointAndAdvancePosition(const uint8_t *const buffer, int *const pos); // Returns the number of read characters. - static AK_FORCE_INLINE int getCharsAndAdvancePosition(const uint8_t *const buffer, - const NodeFlags flags, const int maxLength, int *const outBuffer, int *const pos) { - int length = 0; - if (hasMultipleChars(flags)) { - length = ByteArrayUtils::readStringAndAdvancePosition(buffer, maxLength, outBuffer, - pos); - } else { - if (maxLength > 0) { - outBuffer[0] = getCodePointAndAdvancePosition(buffer, pos); - length = 1; - } - } - return length; - } + static int getCharsAndAdvancePosition(const uint8_t *const buffer, const NodeFlags flags, + const int maxLength, int *const outBuffer, int *const pos); // Returns the number of skipped characters. - static AK_FORCE_INLINE int skipCharacters(const uint8_t *const buffer, const NodeFlags flags, - const int maxLength, int *const pos) { - if (hasMultipleChars(flags)) { - return ByteArrayUtils::advancePositionToBehindString(buffer, maxLength, pos); - } else { - if (maxLength > 0) { - getCodePointAndAdvancePosition(buffer, pos); - return 1; - } else { - return 0; - } - } - } + static int skipCharacters(const uint8_t *const buffer, const NodeFlags flags, + const int maxLength, int *const pos); - static AK_FORCE_INLINE int readProbabilityAndAdvancePosition(const uint8_t *const buffer, - int *const pos) { - return ByteArrayUtils::readUint8AndAdvancePosition(buffer, pos); - } + static int readProbabilityAndAdvancePosition(const uint8_t *const buffer, int *const pos); static int readChildrenPositionAndAdvancePosition(const uint8_t *const buffer, const NodeFlags flags, int *const pos); diff --git a/native/jni/src/suggest/policyimpl/dictionary/shortcut/shortcut_list_reading_utils.cpp b/native/jni/src/suggest/policyimpl/dictionary/shortcut/shortcut_list_reading_utils.cpp index e70bb5071..847dcdee5 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/shortcut/shortcut_list_reading_utils.cpp +++ b/native/jni/src/suggest/policyimpl/dictionary/shortcut/shortcut_list_reading_utils.cpp @@ -16,6 +16,8 @@ #include "suggest/policyimpl/dictionary/shortcut/shortcut_list_reading_utils.h" +#include "suggest/policyimpl/dictionary/utils/byte_array_utils.h" + namespace latinime { // Flag for presence of more attributes @@ -28,4 +30,22 @@ const int ShortcutListReadingUtils::SHORTCUT_LIST_SIZE_FIELD_SIZE = 2; // The numeric value of the shortcut probability that means 'whitelist'. const int ShortcutListReadingUtils::WHITELIST_SHORTCUT_PROBABILITY = 15; +/* static */ ShortcutListReadingUtils::ShortcutFlags + ShortcutListReadingUtils::getFlagsAndForwardPointer(const uint8_t *const dictRoot, + int *const pos) { + return ByteArrayUtils::readUint8AndAdvancePosition(dictRoot, pos); +} + +/* static */ int ShortcutListReadingUtils::getShortcutListSizeAndForwardPointer( + const uint8_t *const dictRoot, int *const pos) { + // readUint16andAdvancePosition() returns an offset *including* the uint16 field itself. + return ByteArrayUtils::readUint16AndAdvancePosition(dictRoot, pos) + - SHORTCUT_LIST_SIZE_FIELD_SIZE; +} + +/* static */ int ShortcutListReadingUtils::readShortcutTarget( + const uint8_t *const dictRoot, const int maxLength, int *const outWord, int *const pos) { + return ByteArrayUtils::readStringAndAdvancePosition(dictRoot, maxLength, outWord, pos); +} + } // namespace latinime diff --git a/native/jni/src/suggest/policyimpl/dictionary/shortcut/shortcut_list_reading_utils.h b/native/jni/src/suggest/policyimpl/dictionary/shortcut/shortcut_list_reading_utils.h index 5f4f240f5..a83ed5a50 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/shortcut/shortcut_list_reading_utils.h +++ b/native/jni/src/suggest/policyimpl/dictionary/shortcut/shortcut_list_reading_utils.h @@ -20,7 +20,6 @@ #include <stdint.h> #include "defines.h" -#include "suggest/policyimpl/dictionary/utils/byte_array_utils.h" namespace latinime { @@ -28,10 +27,7 @@ class ShortcutListReadingUtils { public: typedef uint8_t ShortcutFlags; - static AK_FORCE_INLINE ShortcutFlags getFlagsAndForwardPointer( - const uint8_t *const dictRoot, int *const pos) { - return ByteArrayUtils::readUint8AndAdvancePosition(dictRoot, pos); - } + static ShortcutFlags getFlagsAndForwardPointer(const uint8_t *const dictRoot, int *const pos); static AK_FORCE_INLINE int getProbabilityFromFlags(const ShortcutFlags flags) { return flags & MASK_ATTRIBUTE_PROBABILITY; @@ -43,12 +39,7 @@ class ShortcutListReadingUtils { // This method returns the size of the shortcut list region excluding the shortcut list size // field at the beginning. - static AK_FORCE_INLINE int getShortcutListSizeAndForwardPointer( - const uint8_t *const dictRoot, int *const pos) { - // readUint16andAdvancePosition() returns an offset *including* the uint16 field itself. - return ByteArrayUtils::readUint16AndAdvancePosition(dictRoot, pos) - - SHORTCUT_LIST_SIZE_FIELD_SIZE; - } + static int getShortcutListSizeAndForwardPointer(const uint8_t *const dictRoot, int *const pos); static AK_FORCE_INLINE int getShortcutListSizeFieldSize() { return SHORTCUT_LIST_SIZE_FIELD_SIZE; @@ -63,11 +54,8 @@ class ShortcutListReadingUtils { return getProbabilityFromFlags(flags) == WHITELIST_SHORTCUT_PROBABILITY; } - static AK_FORCE_INLINE int readShortcutTarget( - const uint8_t *const dictRoot, const int maxLength, int *const outWord, - int *const pos) { - return ByteArrayUtils::readStringAndAdvancePosition(dictRoot, maxLength, outWord, pos); - } + static int readShortcutTarget(const uint8_t *const dictRoot, const int maxLength, + int *const outWord, int *const pos); private: DISALLOW_IMPLICIT_CONSTRUCTORS(ShortcutListReadingUtils); diff --git a/tools/make-keyboard-text/res/values-lo/donottranslate-more-keys.xml b/tools/make-keyboard-text/res/values-lo/donottranslate-more-keys.xml new file mode 100644 index 000000000..1d8ffa8cf --- /dev/null +++ b/tools/make-keyboard-text/res/values-lo/donottranslate-more-keys.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** +** Copyright 2013, 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. +*/ +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- Label for "switch to alphabetic" key. + U+0E81: "ກ" LAO LETTER KO + U+0E82: "ຂ" LAO LETTER KHO SUNG + U+0E84: "ຄ" LAO LETTER KHO TAM --> + <string name="label_to_alpha_key">ກຂຄ</string> + <!-- U+20AD: "₭" KIP SIGN --> + <string name="keylabel_for_currency">₭</string> +</resources> diff --git a/tools/make-keyboard-text/res/values-ne/donottranslate-more-keys.xml b/tools/make-keyboard-text/res/values-ne/donottranslate-more-keys.xml new file mode 100644 index 000000000..9205e5309 --- /dev/null +++ b/tools/make-keyboard-text/res/values-ne/donottranslate-more-keys.xml @@ -0,0 +1,63 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** +** Copyright 2013, 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. +*/ +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- Label for "switch to alphabetic" key. + U+0915: "क" DEVANAGARI LETTER KA + U+0916: "ख" DEVANAGARI LETTER KHA + U+0917: "ग" DEVANAGARI LETTER GA --> + <string name="label_to_alpha_key">कखग</string> + <!-- U+0967: "१" DEVANAGARI DIGIT ONE --> + <string name="keylabel_for_symbols_1">१</string> + <!-- U+0968: "२" DEVANAGARI DIGIT TWO --> + <string name="keylabel_for_symbols_2">२</string> + <!-- U+0969: "३" DEVANAGARI DIGIT THREE --> + <string name="keylabel_for_symbols_3">३</string> + <!-- U+096A: "४" DEVANAGARI DIGIT FOUR --> + <string name="keylabel_for_symbols_4">४</string> + <!-- U+096B: "५" DEVANAGARI DIGIT FIVE --> + <string name="keylabel_for_symbols_5">५</string> + <!-- U+096C: "६" DEVANAGARI DIGIT SIX --> + <string name="keylabel_for_symbols_6">६</string> + <!-- U+096D: "७" DEVANAGARI DIGIT SEVEN --> + <string name="keylabel_for_symbols_7">७</string> + <!-- U+096E: "८" DEVANAGARI DIGIT EIGHT --> + <string name="keylabel_for_symbols_8">८</string> + <!-- U+096F: "९" DEVANAGARI DIGIT NINE --> + <string name="keylabel_for_symbols_9">९</string> + <!-- U+0966: "०" DEVANAGARI DIGIT ZERO --> + <string name="keylabel_for_symbols_0">०</string> + <!-- Label for "switch to symbols" key. --> + <string name="label_to_symbol_key">\?१२३</string> + <!-- Label for "switch to symbols with microphone" key. This string shouldn't include the "mic" + part because it'll be appended by the code. --> + <string name="label_to_symbol_with_microphone_key">१२३</string> + <string name="additional_more_keys_for_symbols_1">1</string> + <string name="additional_more_keys_for_symbols_2">2</string> + <string name="additional_more_keys_for_symbols_3">3</string> + <string name="additional_more_keys_for_symbols_4">4</string> + <string name="additional_more_keys_for_symbols_5">5</string> + <string name="additional_more_keys_for_symbols_6">6</string> + <string name="additional_more_keys_for_symbols_7">7</string> + <string name="additional_more_keys_for_symbols_8">8</string> + <string name="additional_more_keys_for_symbols_9">9</string> + <string name="additional_more_keys_for_symbols_0">0</string> + <!-- U+0930/U+0941/U+002E "रु." NEPALESE RUPEE SIGN --> + <string name="keylabel_for_currency">रु.</string> +</resources> diff --git a/tools/make-keyboard-text/res/values/donottranslate-more-keys.xml b/tools/make-keyboard-text/res/values/donottranslate-more-keys.xml index a4c2f126d..cc09f7fe5 100644 --- a/tools/make-keyboard-text/res/values/donottranslate-more-keys.xml +++ b/tools/make-keyboard-text/res/values/donottranslate-more-keys.xml @@ -190,7 +190,7 @@ <!-- Label for "switch to more symbol" modifier key. Must be short to fit on key! --> <string name="label_to_more_symbol_key">= \\ <</string> <!-- Label for "switch to more symbol" modifier key on tablets. Must be short to fit on key! --> - <string name="label_to_more_symbol_for_tablet_key">~ [ {</string> + <string name="label_to_more_symbol_for_tablet_key">~ [ <</string> <!-- Label for "Tab" key. Must be short to fit on key! --> <string name="label_tab_key">Tab</string> <!-- Label for "switch to phone numeric" key. Must be short to fit on key! --> |