├── Android.mk ├── AndroidManifest.xml ├── CleanSpec.mk ├── MODULE_LICENSE_APACHE2 ├── NOTICE ├── jni ├── Android.mk ├── android │ └── com_android_inputmethod_pinyin_PinyinDecoderService.cpp ├── command │ ├── Makefile │ └── pinyinime_dictbuilder.cpp ├── data │ ├── rawdict_utf16_65105_freq.txt │ └── valid_utf16.txt ├── include │ ├── atomdictbase.h │ ├── dictbuilder.h │ ├── dictdef.h │ ├── dictlist.h │ ├── dicttrie.h │ ├── lpicache.h │ ├── matrixsearch.h │ ├── mystdlib.h │ ├── ngram.h │ ├── pinyinime.h │ ├── searchutility.h │ ├── spellingtable.h │ ├── spellingtrie.h │ ├── splparser.h │ ├── sync.h │ ├── userdict.h │ ├── utf16char.h │ └── utf16reader.h └── share │ ├── dictbuilder.cpp │ ├── dictlist.cpp │ ├── dicttrie.cpp │ ├── lpicache.cpp │ ├── matrixsearch.cpp │ ├── mystdlib.cpp │ ├── ngram.cpp │ ├── pinyinime.cpp │ ├── searchutility.cpp │ ├── spellingtable.cpp │ ├── spellingtrie.cpp │ ├── splparser.cpp │ ├── sync.cpp │ ├── userdict.cpp │ ├── utf16char.cpp │ └── utf16reader.cpp ├── lib ├── Android.mk └── com │ └── android │ └── inputmethod │ └── pinyin │ └── IPinyinDecoderService.aidl ├── proguard.cfg ├── proguard.flags ├── res ├── drawable │ ├── app_icon.png │ ├── arrow_bg.xml │ ├── arrow_left.png │ ├── arrow_right.png │ ├── candidate_balloon_bg.9.png │ ├── candidate_hl_bg.9.png │ ├── candidates_area_bg.9.png │ ├── candidates_vertical_line.png │ ├── cands_container_bg.9.png │ ├── comma_full_icon.png │ ├── comma_full_popup_icon.png │ ├── composing_area_bg.9.png │ ├── composing_area_cursor.png │ ├── composing_hl_bg.9.png │ ├── delete_icon.png │ ├── delete_popup_icon.png │ ├── dun_icon.png │ ├── dun_popup_icon.png │ ├── emotion_icon_00.png │ ├── emotion_icon_00_popup.png │ ├── emotion_icon_01.png │ ├── emotion_icon_01_popup.png │ ├── emotion_icon_02.png │ ├── emotion_icon_02_popup.png │ ├── emotion_icon_03.png │ ├── emotion_icon_03_popup.png │ ├── emotion_icon_04.png │ ├── emotion_icon_04_popup.png │ ├── emotion_icon_05.png │ ├── emotion_icon_05_popup.png │ ├── emotion_icon_06.png │ ├── emotion_icon_06_popup.png │ ├── emotion_icon_10.png │ ├── emotion_icon_10_popup.png │ ├── emotion_icon_11.png │ ├── emotion_icon_11_popup.png │ ├── emotion_icon_12.png │ ├── emotion_icon_12_popup.png │ ├── emotion_icon_13.png │ ├── emotion_icon_13_popup.png │ ├── emotion_icon_14.png │ ├── emotion_icon_14_popup.png │ ├── emotion_icon_15.png │ ├── emotion_icon_15_popup.png │ ├── emotion_icon_16.png │ ├── emotion_icon_16_popup.png │ ├── emotion_icon_20.png │ ├── emotion_icon_20_popup.png │ ├── emotion_icon_21.png │ ├── emotion_icon_21_popup.png │ ├── emotion_icon_22.png │ ├── emotion_icon_22_popup.png │ ├── emotion_icon_23.png │ ├── emotion_icon_23_popup.png │ ├── emotion_icon_24.png │ ├── emotion_icon_24_popup.png │ ├── enter_icon.png │ ├── enter_popup_icon.png │ ├── ime_en.png │ ├── ime_pinyin.png │ ├── key_balloon_bg.9.png │ ├── light_key_bg.9.png │ ├── light_key_hl_bg.9.png │ ├── light_key_up_bg.9.png │ ├── light_key_up_hl_bg.9.png │ ├── miniskb_bg.9.png │ ├── normal_key_bg.9.png │ ├── normal_key_hl_bg.9.png │ ├── num0.png │ ├── num1.png │ ├── num2.png │ ├── num3.png │ ├── num4.png │ ├── num5.png │ ├── num6.png │ ├── num7.png │ ├── num8.png │ ├── num9.png │ ├── numalt.png │ ├── numpound.png │ ├── numstar.png │ ├── period_full_icon.png │ ├── period_full_popup_icon.png │ ├── period_icon.png │ ├── period_popup_icon.png │ ├── search_icon.png │ ├── search_popup_icon.png │ ├── shift_off_icon.png │ ├── shift_off_popup_icon.png │ ├── shift_on_icon.png │ ├── shift_on_popup_icon.png │ ├── skb_bg.png │ ├── skb_container_bg.9.png │ ├── smiley_icon.png │ ├── smiley_popup_icon.png │ ├── space_icon.png │ └── space_popup_icon.png ├── layout │ ├── candidates_container.xml │ ├── floating_container.xml │ └── skb_container.xml ├── raw │ └── dict_pinyin.dat ├── values-land │ └── dimens.xml ├── values-port │ └── dimens.xml ├── values-zh │ └── bools.xml ├── values │ ├── colors.xml │ ├── dimens.xml │ └── strings.xml └── xml │ ├── method.xml │ ├── settings.xml │ ├── skb_phone.xml │ ├── skb_qwerty.xml │ ├── skb_smiley.xml │ ├── skb_sym1.xml │ ├── skb_sym2.xml │ └── skb_template1.xml └── src └── com └── android └── inputmethod └── pinyin ├── BalloonHint.java ├── CandidateView.java ├── CandidateViewListener.java ├── CandidatesContainer.java ├── ComposingView.java ├── EnglishInputProcessor.java ├── Environment.java ├── InputModeSwitcher.java ├── KeyMapDream.java ├── PinyinDecoderService.java ├── PinyinIME.java ├── Settings.java ├── SettingsActivity.java ├── SkbContainer.java ├── SkbPool.java ├── SkbTemplate.java ├── SoftKey.java ├── SoftKeyToggle.java ├── SoftKeyboard.java ├── SoftKeyboardView.java ├── SoundManager.java └── XmlKeyboardLoader.java /Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH:= $(call my-dir) 2 | 3 | include $(CLEAR_VARS) 4 | 5 | LOCAL_MODULE_TAGS := optional 6 | 7 | LOCAL_SRC_FILES := \ 8 | $(call all-subdir-java-files) 9 | 10 | LOCAL_PACKAGE_NAME := PinyinIME 11 | 12 | LOCAL_JNI_SHARED_LIBRARIES := libjni_pinyinime 13 | 14 | LOCAL_REQUIRED_MODULES := libjni_pinyinime 15 | 16 | LOCAL_STATIC_JAVA_LIBRARIES := com.android.inputmethod.pinyin.lib 17 | 18 | LOCAL_CERTIFICATE := shared 19 | 20 | LOCAL_PROGUARD_FLAG_FILES := proguard.cfg 21 | 22 | # Make sure our dictionary file is not compressed, so we can read it with 23 | # a raw file descriptor. 24 | LOCAL_AAPT_FLAGS := -0 .dat 25 | LOCAL_AAPT_FLAGS += -0 .dict 26 | 27 | LOCAL_PROGUARD_FLAG_FILES := proguard.flags 28 | 29 | include $(BUILD_PACKAGE) 30 | 31 | MY_PATH := $(LOCAL_PATH) 32 | 33 | include $(MY_PATH)/jni/Android.mk 34 | include $(MY_PATH)/lib/Android.mk 35 | -------------------------------------------------------------------------------- /AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 29 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /CleanSpec.mk: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2007 The Android Open Source Project 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # 15 | 16 | # If you don't need to do a full clean build but would like to touch 17 | # a file or delete some intermediate files, add a clean step to the end 18 | # of the list. These steps will only be run once, if they haven't been 19 | # run before. 20 | # 21 | # E.g.: 22 | # $(call add-clean-step, touch -c external/sqlite/sqlite3.h) 23 | # $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates) 24 | # 25 | # Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with 26 | # files that are missing or have been moved. 27 | # 28 | # Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory. 29 | # Use $(OUT_DIR) to refer to the "out" directory. 30 | # 31 | # If you need to re-do something that's already mentioned, just copy 32 | # the command and add it to the bottom of the list. E.g., if a change 33 | # that you made last week required touching a file and a change you 34 | # made today requires touching the same file, just copy the old 35 | # touch step and add it to the end of the list. 36 | # 37 | # ************************************************ 38 | # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST 39 | # ************************************************ 40 | 41 | # For example: 42 | #$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates) 43 | #$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates) 44 | #$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f) 45 | #$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*) 46 | 47 | # ************************************************ 48 | # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST 49 | # ************************************************ 50 | -------------------------------------------------------------------------------- /MODULE_LICENSE_APACHE2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/MODULE_LICENSE_APACHE2 -------------------------------------------------------------------------------- /jni/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | 3 | ### shared library 4 | 5 | include $(CLEAR_VARS) 6 | 7 | LOCAL_SRC_FILES := \ 8 | android/com_android_inputmethod_pinyin_PinyinDecoderService.cpp \ 9 | share/dictbuilder.cpp \ 10 | share/dictlist.cpp \ 11 | share/dicttrie.cpp \ 12 | share/lpicache.cpp \ 13 | share/matrixsearch.cpp \ 14 | share/mystdlib.cpp \ 15 | share/ngram.cpp \ 16 | share/pinyinime.cpp \ 17 | share/searchutility.cpp \ 18 | share/spellingtable.cpp \ 19 | share/spellingtrie.cpp \ 20 | share/splparser.cpp \ 21 | share/userdict.cpp \ 22 | share/utf16char.cpp \ 23 | share/utf16reader.cpp \ 24 | share/sync.cpp 25 | 26 | LOCAL_C_INCLUDES += $(JNI_H_INCLUDE) 27 | LOCAL_LDLIBS += -lpthread 28 | LOCAL_MODULE := libjni_pinyinime 29 | LOCAL_SHARED_LIBRARIES := libcutils libutils 30 | LOCAL_MODULE_TAGS := optional 31 | 32 | include $(BUILD_SHARED_LIBRARY) 33 | -------------------------------------------------------------------------------- /jni/command/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS= -g -Wall -std=c99 3 | CPP=g++ 4 | CPPFLAGS= -g3 -Wall -lpthread 5 | 6 | PINYINIME_DICTBUILDER=pinyinime_dictbuilder 7 | 8 | LIBRARY_SRC= \ 9 | ../share/dictbuilder.cpp \ 10 | ../share/dictlist.cpp \ 11 | ../share/dicttrie.cpp \ 12 | ../share/lpicache.cpp \ 13 | ../share/mystdlib.cpp \ 14 | ../share/ngram.cpp \ 15 | ../share/searchutility.cpp \ 16 | ../share/spellingtable.cpp \ 17 | ../share/spellingtrie.cpp \ 18 | ../share/splparser.cpp \ 19 | ../share/utf16char.cpp \ 20 | ../share/utf16reader.cpp \ 21 | 22 | all: engine 23 | 24 | engine: $(PINYINIME_DICTBUILDER) 25 | 26 | $(PINYINIME_DICTBUILDER): $(LIBRARY_SRC) pinyinime_dictbuilder.cpp 27 | @$(CPP) $(CPPFLAGS) -o $@ $? 28 | 29 | 30 | clean: 31 | -rm -rf $(PINYINIME_DICTBUILDER) 32 | 33 | .PHONY: clean 34 | -------------------------------------------------------------------------------- /jni/command/pinyinime_dictbuilder.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include "../include/dicttrie.h" 23 | 24 | using namespace ime_pinyin; 25 | 26 | /** 27 | * Build binary dictionary model. Make sure that ___BUILD_MODEL___ is defined 28 | * in dictdef.h. 29 | */ 30 | int main(int argc, char* argv[]) { 31 | DictTrie* dict_trie = new DictTrie(); 32 | bool success; 33 | if (argc >= 3) 34 | success = dict_trie->build_dict(argv[1], argv[2]); 35 | else 36 | success = dict_trie->build_dict("../data/rawdict_utf16_65105_freq.txt", 37 | "../data/valid_utf16.txt"); 38 | 39 | if (success) { 40 | printf("Build dictionary successfully.\n"); 41 | } else { 42 | printf("Build dictionary unsuccessfully.\n"); 43 | return -1; 44 | } 45 | 46 | success = dict_trie->save_dict("../../res/raw/dict_pinyin.dat"); 47 | 48 | if (success) { 49 | printf("Save dictionary successfully.\n"); 50 | } else { 51 | printf("Save dictionary unsuccessfully.\n"); 52 | return -1; 53 | } 54 | 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /jni/data/rawdict_utf16_65105_freq.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/jni/data/rawdict_utf16_65105_freq.txt -------------------------------------------------------------------------------- /jni/data/valid_utf16.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/jni/data/valid_utf16.txt -------------------------------------------------------------------------------- /jni/include/dictbuilder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef PINYINIME_INCLUDE_DICTBUILDER_H__ 18 | #define PINYINIME_INCLUDE_DICTBUILDER_H__ 19 | 20 | #include 21 | #include "./utf16char.h" 22 | #include "./dictdef.h" 23 | #include "./dictlist.h" 24 | #include "./spellingtable.h" 25 | #include "./spellingtrie.h" 26 | #include "./splparser.h" 27 | 28 | namespace ime_pinyin { 29 | 30 | #ifdef ___BUILD_MODEL___ 31 | 32 | #define ___DO_STATISTICS___ 33 | 34 | class DictTrie; 35 | 36 | class DictBuilder { 37 | private: 38 | // The raw lemma array buffer. 39 | LemmaEntry *lemma_arr_; 40 | size_t lemma_num_; 41 | 42 | // Used to store all possible single char items. 43 | // Two items may have the same Hanzi while their spelling ids are different. 44 | SingleCharItem *scis_; 45 | size_t scis_num_; 46 | 47 | // In the tree, root's level is -1. 48 | // Lemma nodes for root, and level 0 49 | LmaNodeLE0 *lma_nodes_le0_; 50 | 51 | // Lemma nodes for layers whose levels are deeper than 0 52 | LmaNodeGE1 *lma_nodes_ge1_; 53 | 54 | // Number of used lemma nodes 55 | size_t lma_nds_used_num_le0_; 56 | size_t lma_nds_used_num_ge1_; 57 | 58 | // Used to store homophonies' ids. 59 | LemmaIdType *homo_idx_buf_; 60 | // Number of homophonies each of which only contains one Chinese character. 61 | size_t homo_idx_num_eq1_; 62 | // Number of homophonies each of which contains more than one character. 63 | size_t homo_idx_num_gt1_; 64 | 65 | // The items with highest scores. 66 | LemmaEntry *top_lmas_; 67 | size_t top_lmas_num_; 68 | 69 | SpellingTable *spl_table_; 70 | SpellingParser *spl_parser_; 71 | 72 | #ifdef ___DO_STATISTICS___ 73 | size_t max_sonbuf_len_[kMaxLemmaSize]; 74 | size_t max_homobuf_len_[kMaxLemmaSize]; 75 | 76 | size_t total_son_num_[kMaxLemmaSize]; 77 | size_t total_node_hasson_[kMaxLemmaSize]; 78 | size_t total_sonbuf_num_[kMaxLemmaSize]; 79 | size_t total_sonbuf_allnoson_[kMaxLemmaSize]; 80 | size_t total_node_in_sonbuf_allnoson_[kMaxLemmaSize]; 81 | size_t total_homo_num_[kMaxLemmaSize]; 82 | 83 | size_t sonbufs_num1_; // Number of son buffer with only 1 son 84 | size_t sonbufs_numgt1_; // Number of son buffer with more 1 son; 85 | 86 | size_t total_lma_node_num_; 87 | 88 | void stat_init(); 89 | void stat_print(); 90 | #endif 91 | 92 | public: 93 | 94 | DictBuilder(); 95 | ~DictBuilder(); 96 | 97 | // Build dictionary trie from the file fn_raw. File fn_validhzs provides 98 | // valid chars. If fn_validhzs is NULL, only chars in GB2312 will be 99 | // included. 100 | bool build_dict(const char* fn_raw, const char* fn_validhzs, 101 | DictTrie *dict_trie); 102 | 103 | private: 104 | // Fill in the buffer with id. The caller guarantees that the paramters are 105 | // vaild. 106 | void id_to_charbuf(unsigned char *buf, LemmaIdType id); 107 | 108 | // Update the offset of sons for a node. 109 | void set_son_offset(LmaNodeGE1 *node, size_t offset); 110 | 111 | // Update the offset of homophonies' ids for a node. 112 | void set_homo_id_buf_offset(LmaNodeGE1 *node, size_t offset); 113 | 114 | // Format a speling string. 115 | void format_spelling_str(char *spl_str); 116 | 117 | // Sort the lemma_arr by the hanzi string, and give each of unique items 118 | // a id. Why we need to sort the lemma list according to their Hanzi string 119 | // is to find items started by a given prefix string to do prediction. 120 | // Actually, the single char items are be in other order, for example, 121 | // in spelling id order, etc. 122 | // Return value is next un-allocated idx available. 123 | LemmaIdType sort_lemmas_by_hz(); 124 | 125 | // Build the SingleCharItem list, and fill the hanzi_scis_ids in the 126 | // lemma buffer lemma_arr_. 127 | // This function should be called after the lemma array is ready. 128 | // Return the number of unique SingleCharItem elements. 129 | size_t build_scis(); 130 | 131 | // Construct a subtree using a subset of the spelling array (from 132 | // item_star to item_end) 133 | // parent is the parent node to update the necessary information 134 | // parent can be a member of LmaNodeLE0 or LmaNodeGE1 135 | bool construct_subset(void* parent, LemmaEntry* lemma_arr, 136 | size_t item_start, size_t item_end, size_t level); 137 | 138 | 139 | // Read valid Chinese Hanzis from the given file. 140 | // num is used to return number of chars. 141 | // The return buffer is sorted and caller needs to free the returned buffer. 142 | char16* read_valid_hanzis(const char *fn_validhzs, size_t *num); 143 | 144 | 145 | // Read a raw dictionary. max_item is the maximum number of items. If there 146 | // are more items in the ditionary, only the first max_item will be read. 147 | // Returned value is the number of items successfully read from the file. 148 | size_t read_raw_dict(const char* fn_raw, const char *fn_validhzs, 149 | size_t max_item); 150 | 151 | // Try to find if a character is in hzs buffer. 152 | bool hz_in_hanzis_list(const char16 *hzs, size_t hzs_len, char16 hz); 153 | 154 | // Try to find if all characters in str are in hzs buffer. 155 | bool str_in_hanzis_list(const char16 *hzs, size_t hzs_len, 156 | const char16 *str, size_t str_len); 157 | 158 | // Get these lemmas with toppest scores. 159 | void get_top_lemmas(); 160 | 161 | // Allocate resource to build dictionary. 162 | // lma_num is the number of items to be loaded 163 | bool alloc_resource(size_t lma_num); 164 | 165 | // Free resource. 166 | void free_resource(); 167 | }; 168 | #endif // ___BUILD_MODEL___ 169 | } 170 | 171 | #endif // PINYINIME_INCLUDE_DICTBUILDER_H__ 172 | -------------------------------------------------------------------------------- /jni/include/dictdef.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef PINYINIME_INCLUDE_DICTDEF_H__ 18 | #define PINYINIME_INCLUDE_DICTDEF_H__ 19 | 20 | #include 21 | #include "./utf16char.h" 22 | 23 | namespace ime_pinyin { 24 | 25 | // Enable the following line when building the binary dictionary model. 26 | // #define ___BUILD_MODEL___ 27 | 28 | typedef unsigned char uint8; 29 | typedef unsigned short uint16; 30 | typedef unsigned int uint32; 31 | 32 | typedef signed char int8; 33 | typedef short int16; 34 | typedef int int32; 35 | typedef long long int64; 36 | typedef unsigned long long uint64; 37 | 38 | const bool kPrintDebug0 = false; 39 | const bool kPrintDebug1 = false; 40 | const bool kPrintDebug2 = false; 41 | 42 | // The max length of a lemma. 43 | const size_t kMaxLemmaSize = 8; 44 | 45 | // The max length of a Pinyin (spelling). 46 | const size_t kMaxPinyinSize = 6; 47 | 48 | // The number of half spelling ids. For Chinese Pinyin, there 30 half ids. 49 | // See SpellingTrie.h for details. 50 | const size_t kHalfSpellingIdNum = 29; 51 | 52 | // The maximum number of full spellings. For Chinese Pinyin, there are only 53 | // about 410 spellings. 54 | // If change this value is bigger(needs more bits), please also update 55 | // other structures like SpellingNode, to make sure than a spelling id can be 56 | // stored. 57 | // -1 is because that 0 is never used. 58 | const size_t kMaxSpellingNum = 512 - kHalfSpellingIdNum - 1; 59 | const size_t kMaxSearchSteps = 40; 60 | 61 | // One character predicts its following characters. 62 | const size_t kMaxPredictSize = (kMaxLemmaSize - 1); 63 | 64 | // LemmaIdType must always be size_t. 65 | typedef size_t LemmaIdType; 66 | const size_t kLemmaIdSize = 3; // Actually, a Id occupies 3 bytes in storage. 67 | const size_t kLemmaIdComposing = 0xffffff; 68 | 69 | typedef uint16 LmaScoreType; 70 | typedef uint16 KeyScoreType; 71 | 72 | // Number of items with highest score are kept for prediction purpose. 73 | const size_t kTopScoreLemmaNum = 10; 74 | 75 | const size_t kMaxPredictNumByGt3 = 1; 76 | const size_t kMaxPredictNumBy3 = 2; 77 | const size_t kMaxPredictNumBy2 = 2; 78 | 79 | // The last lemma id (included) for the system dictionary. The system 80 | // dictionary's ids always start from 1. 81 | const LemmaIdType kSysDictIdEnd = 500000; 82 | 83 | // The first lemma id for the user dictionary. 84 | const LemmaIdType kUserDictIdStart = 500001; 85 | 86 | // The last lemma id (included) for the user dictionary. 87 | const LemmaIdType kUserDictIdEnd = 600000; 88 | 89 | typedef struct { 90 | uint16 half_splid:5; 91 | uint16 full_splid:11; 92 | } SpellingId, *PSpellingId; 93 | 94 | 95 | /** 96 | * We use different node types for different layers 97 | * Statistical data of the building result for a testing dictionary: 98 | * root, level 0, level 1, level 2, level 3 99 | * max son num of one node: 406 280 41 2 - 100 | * max homo num of one node: 0 90 23 2 2 101 | * total node num of a layer: 1 406 31766 13516 993 102 | * total homo num of a layer: 9 5674 44609 12667 995 103 | * 104 | * The node number for root and level 0 won't be larger than 500 105 | * According to the information above, two kinds of nodes can be used; one for 106 | * root and level 0, the other for these layers deeper than 0. 107 | * 108 | * LE = less and equal, 109 | * A node occupies 16 bytes. so, totallly less than 16 * 500 = 8K 110 | */ 111 | struct LmaNodeLE0 { 112 | size_t son_1st_off; 113 | size_t homo_idx_buf_off; 114 | uint16 spl_idx; 115 | uint16 num_of_son; 116 | uint16 num_of_homo; 117 | }; 118 | 119 | /** 120 | * GE = great and equal 121 | * A node occupies 8 bytes. 122 | */ 123 | struct LmaNodeGE1 { 124 | uint16 son_1st_off_l; // Low bits of the son_1st_off 125 | uint16 homo_idx_buf_off_l; // Low bits of the homo_idx_buf_off_1 126 | uint16 spl_idx; 127 | unsigned char num_of_son; // number of son nodes 128 | unsigned char num_of_homo; // number of homo words 129 | unsigned char son_1st_off_h; // high bits of the son_1st_off 130 | unsigned char homo_idx_buf_off_h; // high bits of the homo_idx_buf_off 131 | }; 132 | 133 | #ifdef ___BUILD_MODEL___ 134 | struct SingleCharItem { 135 | float freq; 136 | char16 hz; 137 | SpellingId splid; 138 | }; 139 | 140 | struct LemmaEntry { 141 | LemmaIdType idx_by_py; 142 | LemmaIdType idx_by_hz; 143 | char16 hanzi_str[kMaxLemmaSize + 1]; 144 | 145 | // The SingleCharItem id for each Hanzi. 146 | uint16 hanzi_scis_ids[kMaxLemmaSize]; 147 | 148 | uint16 spl_idx_arr[kMaxLemmaSize + 1]; 149 | char pinyin_str[kMaxLemmaSize][kMaxPinyinSize + 1]; 150 | unsigned char hz_str_len; 151 | float freq; 152 | }; 153 | #endif // ___BUILD_MODEL___ 154 | 155 | } // namespace ime_pinyin 156 | 157 | #endif // PINYINIME_INCLUDE_DICTDEF_H__ 158 | -------------------------------------------------------------------------------- /jni/include/dictlist.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef PINYINIME_INCLUDE_DICTLIST_H__ 18 | #define PINYINIME_INCLUDE_DICTLIST_H__ 19 | 20 | #include 21 | #include 22 | #include "./dictdef.h" 23 | #include "./searchutility.h" 24 | #include "./spellingtrie.h" 25 | #include "./utf16char.h" 26 | 27 | namespace ime_pinyin { 28 | 29 | class DictList { 30 | private: 31 | bool initialized_; 32 | 33 | const SpellingTrie *spl_trie_; 34 | 35 | // Number of SingCharItem. The first is blank, because id 0 is invalid. 36 | size_t scis_num_; 37 | char16 *scis_hz_; 38 | SpellingId *scis_splid_; 39 | 40 | // The large memory block to store the word list. 41 | char16 *buf_; 42 | 43 | // Starting position of those words whose lengths are i+1, counted in 44 | // char16 45 | size_t start_pos_[kMaxLemmaSize + 1]; 46 | 47 | size_t start_id_[kMaxLemmaSize + 1]; 48 | 49 | int (*cmp_func_[kMaxLemmaSize])(const void *, const void *); 50 | 51 | bool alloc_resource(size_t buf_size, size_t scim_num); 52 | 53 | void free_resource(); 54 | 55 | #ifdef ___BUILD_MODEL___ 56 | // Calculate the requsted memory, including the start_pos[] buffer. 57 | size_t calculate_size(const LemmaEntry *lemma_arr, size_t lemma_num); 58 | 59 | void fill_scis(const SingleCharItem *scis, size_t scis_num); 60 | 61 | // Copy the related content to the inner buffer 62 | // It should be called after calculate_size() 63 | void fill_list(const LemmaEntry *lemma_arr, size_t lemma_num); 64 | 65 | // Find the starting position for the buffer of those 2-character Chinese word 66 | // whose first character is the given Chinese character. 67 | char16* find_pos2_startedbyhz(char16 hz_char); 68 | #endif 69 | 70 | // Find the starting position for the buffer of those words whose lengths are 71 | // word_len. The given parameter cmp_func decides how many characters from 72 | // beginning will be used to compare. 73 | char16* find_pos_startedbyhzs(const char16 last_hzs[], 74 | size_t word_Len, 75 | int (*cmp_func)(const void *, const void *)); 76 | 77 | public: 78 | 79 | DictList(); 80 | ~DictList(); 81 | 82 | bool save_list(FILE *fp); 83 | bool load_list(FILE *fp); 84 | 85 | #ifdef ___BUILD_MODEL___ 86 | // Init the list from the LemmaEntry array. 87 | // lemma_arr should have been sorted by the hanzi_str, and have been given 88 | // ids from 1 89 | bool init_list(const SingleCharItem *scis, size_t scis_num, 90 | const LemmaEntry *lemma_arr, size_t lemma_num); 91 | #endif 92 | 93 | // Get the hanzi string for the given id 94 | uint16 get_lemma_str(LemmaIdType id_hz, char16 *str_buf, uint16 str_max); 95 | 96 | void convert_to_hanzis(char16 *str, uint16 str_len); 97 | 98 | void convert_to_scis_ids(char16 *str, uint16 str_len); 99 | 100 | // last_hzs stores the last n Chinese characters history, its length should be 101 | // less or equal than kMaxPredictSize. 102 | // hzs_len specifies the length(<= kMaxPredictSize). 103 | // predict_buf is used to store the result. 104 | // buf_len specifies the buffer length. 105 | // b4_used specifies how many items before predict_buf have been used. 106 | // Returned value is the number of newly added items. 107 | size_t predict(const char16 last_hzs[], uint16 hzs_len, 108 | NPredictItem *npre_items, size_t npre_max, 109 | size_t b4_used); 110 | 111 | // If half_splid is a valid half spelling id, return those full spelling 112 | // ids which share this half id. 113 | uint16 get_splids_for_hanzi(char16 hanzi, uint16 half_splid, 114 | uint16 *splids, uint16 max_splids); 115 | 116 | LemmaIdType get_lemma_id(const char16 *str, uint16 str_len); 117 | }; 118 | } 119 | 120 | #endif // PINYINIME_INCLUDE_DICTLIST_H__ 121 | -------------------------------------------------------------------------------- /jni/include/lpicache.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef PINYINIME_ANDPY_INCLUDE_LPICACHE_H__ 18 | #define PINYINIME_ANDPY_INCLUDE_LPICACHE_H__ 19 | 20 | #include 21 | #include "./searchutility.h" 22 | #include "./spellingtrie.h" 23 | 24 | namespace ime_pinyin { 25 | 26 | // Used to cache LmaPsbItem list for half spelling ids. 27 | class LpiCache { 28 | private: 29 | static LpiCache *instance_; 30 | static const int kMaxLpiCachePerId = 15; 31 | 32 | LmaPsbItem *lpi_cache_; 33 | uint16 *lpi_cache_len_; 34 | 35 | public: 36 | LpiCache(); 37 | ~LpiCache(); 38 | 39 | static LpiCache& get_instance(); 40 | 41 | // Test if the LPI list of the given splid has been cached. 42 | // If splid is a full spelling id, it returns false, because we only cache 43 | // list for half ids. 44 | bool is_cached(uint16 splid); 45 | 46 | // Put LPI list to cahce. If the length of the list, lpi_num, is longer than 47 | // the cache buffer. the list will be truncated, and function returns the 48 | // maximum length of the cache buffer. 49 | // Note: splid must be a half id, and lpi_items must be not NULL. The 50 | // caller of this function should guarantee this. 51 | size_t put_cache(uint16 splid, LmaPsbItem lpi_items[], size_t lpi_num); 52 | 53 | // Get the cached list for the given half id. 54 | // Return the length of the cached buffer. 55 | // Note: splid must be a half id, and lpi_items must be not NULL. The 56 | // caller of this function should guarantee this. 57 | size_t get_cache(uint16 splid, LmaPsbItem lpi_items[], size_t lpi_max); 58 | }; 59 | 60 | } // namespace 61 | 62 | #endif // PINYINIME_ANDPY_INCLUDE_LPICACHE_H__ 63 | -------------------------------------------------------------------------------- /jni/include/mystdlib.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef PINYINIME_INCLUDE_MYSTDLIB_H__ 18 | #define PINYINIME_INCLUDE_MYSTDLIB_H__ 19 | 20 | #include 21 | 22 | namespace ime_pinyin { 23 | 24 | void myqsort(void *p, size_t n, size_t es, 25 | int (*cmp)(const void *, const void *)); 26 | 27 | void *mybsearch(const void *key, const void *base, 28 | size_t nmemb, size_t size, 29 | int (*compar)(const void *, const void *)); 30 | } 31 | 32 | #endif // PINYINIME_INCLUDE_MYSTDLIB_H__ 33 | -------------------------------------------------------------------------------- /jni/include/ngram.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef PINYINIME_INCLUDE_NGRAM_H__ 18 | #define PINYINIME_INCLUDE_NGRAM_H__ 19 | 20 | #include 21 | #include 22 | #include "./dictdef.h" 23 | 24 | namespace ime_pinyin { 25 | 26 | typedef unsigned char CODEBOOK_TYPE; 27 | 28 | static const size_t kCodeBookSize = 256; 29 | 30 | class NGram { 31 | public: 32 | // The maximum score of a lemma item. 33 | static const LmaScoreType kMaxScore = 0x3fff; 34 | 35 | // In order to reduce the storage size, the original log value is amplified by 36 | // kScoreAmplifier, and we use LmaScoreType to store. 37 | // After this process, an item with a lower score has a higher frequency. 38 | static const int kLogValueAmplifier = -800; 39 | 40 | // System words' total frequency. It is not the real total frequency, instead, 41 | // It is only used to adjust system lemmas' scores when the user dictionary's 42 | // total frequency changes. 43 | // In this version, frequencies of system lemmas are fixed. We are considering 44 | // to make them changable in next version. 45 | static const size_t kSysDictTotalFreq = 100000000; 46 | 47 | private: 48 | 49 | static NGram* instance_; 50 | 51 | bool initialized_; 52 | size_t idx_num_; 53 | 54 | size_t total_freq_none_sys_; 55 | 56 | // Score compensation for system dictionary lemmas. 57 | // Because after user adds some user lemmas, the total frequency changes, and 58 | // we use this value to normalize the score. 59 | float sys_score_compensation_; 60 | 61 | #ifdef ___BUILD_MODEL___ 62 | double *freq_codes_df_; 63 | #endif 64 | LmaScoreType *freq_codes_; 65 | CODEBOOK_TYPE *lma_freq_idx_; 66 | 67 | public: 68 | NGram(); 69 | ~NGram(); 70 | 71 | static NGram& get_instance(); 72 | 73 | bool save_ngram(FILE *fp); 74 | bool load_ngram(FILE *fp); 75 | 76 | // Set the total frequency of all none system dictionaries. 77 | void set_total_freq_none_sys(size_t freq_none_sys); 78 | 79 | float get_uni_psb(LemmaIdType lma_id); 80 | 81 | // Convert a probability to score. Actually, the score will be limited to 82 | // kMaxScore, but at runtime, we also need float expression to get accurate 83 | // value of the score. 84 | // After the conversion, a lower score indicates a higher probability of the 85 | // item. 86 | static float convert_psb_to_score(double psb); 87 | 88 | #ifdef ___BUILD_MODEL___ 89 | // For constructing the unigram mode model. 90 | bool build_unigram(LemmaEntry *lemma_arr, size_t num, 91 | LemmaIdType next_idx_unused); 92 | #endif 93 | }; 94 | } 95 | 96 | #endif // PINYINIME_INCLUDE_NGRAM_H__ 97 | -------------------------------------------------------------------------------- /jni/include/pinyinime.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef PINYINIME_INCLUDE_ANDPYIME_H__ 18 | #define PINYINIME_INCLUDE_ANDPYIME_H__ 19 | 20 | #include 21 | #include "./dictdef.h" 22 | 23 | #ifdef __cplusplus 24 | extern "C" { 25 | #endif 26 | 27 | namespace ime_pinyin { 28 | 29 | /** 30 | * Open the decoder engine via the system and user dictionary file names. 31 | * 32 | * @param fn_sys_dict The file name of the system dictionary. 33 | * @param fn_usr_dict The file name of the user dictionary. 34 | * @return true if open the decoder engine successfully. 35 | */ 36 | bool im_open_decoder(const char *fn_sys_dict, const char *fn_usr_dict); 37 | 38 | /** 39 | * Open the decoder engine via the system dictionary FD and user dictionary 40 | * file name. Because on Android, the system dictionary is embedded in the 41 | * whole application apk file. 42 | * 43 | * @param sys_fd The file in which the system dictionary is embedded. 44 | * @param start_offset The starting position of the system dictionary in the 45 | * file sys_fd. 46 | * @param length The length of the system dictionary in the file sys_fd, 47 | * counted in byte. 48 | * @return true if succeed. 49 | */ 50 | bool im_open_decoder_fd(int sys_fd, long start_offset, long length, 51 | const char *fn_usr_dict); 52 | 53 | /** 54 | * Close the decoder engine. 55 | */ 56 | void im_close_decoder(); 57 | 58 | /** 59 | * Set maximum limitations for decoding. If this function is not called, 60 | * default values will be used. For example, due to screen size limitation, 61 | * the UI engine of the IME can only show a certain number of letters(input) 62 | * to decode, and a certain number of Chinese characters(output). If after 63 | * user adds a new letter, the input or the output string is longer than the 64 | * limitations, the engine will discard the recent letter. 65 | * 66 | * @param max_sps_len Maximum length of the spelling string(Pinyin string). 67 | * @max_hzs_len Maximum length of the decoded Chinese character string. 68 | */ 69 | void im_set_max_lens(size_t max_sps_len, size_t max_hzs_len); 70 | 71 | /** 72 | * Flush cached data to persistent memory. Because at runtime, in order to 73 | * achieve best performance, some data is only store in memory. 74 | */ 75 | void im_flush_cache(); 76 | 77 | /** 78 | * Use a spelling string(Pinyin string) to search. The engine will try to do 79 | * an incremental search based on its previous search result, so if the new 80 | * string has the same prefix with the previous one stored in the decoder, 81 | * the decoder will only continue the search from the end of the prefix. 82 | * If the caller needs to do a brand new search, please call im_reset_search() 83 | * first. Calling im_search() is equivalent to calling im_add_letter() one by 84 | * one. 85 | * 86 | * @param sps_buf The spelling string buffer to decode. 87 | * @param sps_len The length of the spelling string buffer. 88 | * @return The number of candidates. 89 | */ 90 | size_t im_search(const char* sps_buf, size_t sps_len); 91 | 92 | /** 93 | * Make a delete operation in the current search result, and make research if 94 | * necessary. 95 | * 96 | * @param pos The posistion of char in spelling string to delete, or the 97 | * position of spelling id in result string to delete. 98 | * @param is_pos_in_splid Indicate whether the pos parameter is the position 99 | * in the spelling string, or the position in the result spelling id string. 100 | * @return The number of candidates. 101 | */ 102 | size_t im_delsearch(size_t pos, bool is_pos_in_splid, 103 | bool clear_fixed_this_step); 104 | 105 | /** 106 | * Reset the previous search result. 107 | */ 108 | void im_reset_search(); 109 | 110 | /** 111 | * Add a Pinyin letter to the current spelling string kept by decoder. If the 112 | * decoder fails in adding the letter, it will do nothing. im_get_sps_str() 113 | * can be used to get the spelling string kept by decoder currently. 114 | * 115 | * @param ch The letter to add. 116 | * @return The number of candidates. 117 | */ 118 | size_t im_add_letter(char ch); 119 | 120 | /** 121 | * Get the spelling string kept by the decoder. 122 | * 123 | * @param decoded_len Used to return how many characters in the spelling 124 | * string is successfully parsed. 125 | * @return The spelling string kept by the decoder. 126 | */ 127 | const char *im_get_sps_str(size_t *decoded_len); 128 | 129 | /** 130 | * Get a candidate(or choice) string. 131 | * 132 | * @param cand_id The id to get a candidate. Started from 0. Usually, id 0 133 | * is a sentence-level candidate. 134 | * @param cand_str The buffer to store the candidate. 135 | * @param max_len The maximum length of the buffer. 136 | * @return cand_str if succeeds, otherwise NULL. 137 | */ 138 | char16* im_get_candidate(size_t cand_id, char16* cand_str, 139 | size_t max_len); 140 | 141 | /** 142 | * Get the segmentation information(the starting positions) of the spelling 143 | * string. 144 | * 145 | * @param spl_start Used to return the starting posistions. 146 | * @return The number of spelling ids. If it is L, there will be L+1 valid 147 | * elements in spl_start, and spl_start[L] is the posistion after the end of 148 | * the last spelling id. 149 | */ 150 | size_t im_get_spl_start_pos(const uint16 *&spl_start); 151 | 152 | /** 153 | * Choose a candidate and make it fixed. If the candidate does not match 154 | * the end of all spelling ids, new candidates will be provided from the 155 | * first unfixed position. If the candidate matches the end of the all 156 | * spelling ids, there will be only one new candidates, or the whole fixed 157 | * sentence. 158 | * 159 | * @param cand_id The id of candidate to select and make it fixed. 160 | * @return The number of candidates. If after the selection, the whole result 161 | * string has been fixed, there will be only one candidate. 162 | */ 163 | size_t im_choose(size_t cand_id); 164 | 165 | /** 166 | * Cancel the last selection, or revert the last operation of im_choose(). 167 | * 168 | * @return The number of candidates. 169 | */ 170 | size_t im_cancel_last_choice(); 171 | 172 | /** 173 | * Get the number of fixed spelling ids, or Chinese characters. 174 | * 175 | * @return The number of fixed spelling ids, of Chinese characters. 176 | */ 177 | size_t im_get_fixed_len(); 178 | 179 | /** 180 | * Cancel the input state and reset the search workspace. 181 | */ 182 | bool im_cancel_input(); 183 | 184 | /** 185 | * Get prediction candiates based on the given fixed Chinese string as the 186 | * history. 187 | * 188 | * @param his_buf The history buffer to do the prediction. It should be ended 189 | * with '\0'. 190 | * @param pre_buf Used to return prediction result list. 191 | * @return The number of predicted result string. 192 | */ 193 | size_t im_get_predicts(const char16 *his_buf, 194 | char16 (*&pre_buf)[kMaxPredictSize + 1]); 195 | 196 | /** 197 | * Enable Shengmus in ShouZiMu mode. 198 | */ 199 | void im_enable_shm_as_szm(bool enable); 200 | 201 | /** 202 | * Enable Yunmus in ShouZiMu mode. 203 | */ 204 | void im_enable_ym_as_szm(bool enable); 205 | } 206 | 207 | #ifdef __cplusplus 208 | } 209 | #endif 210 | 211 | #endif // PINYINIME_INCLUDE_ANDPYIME_H__ 212 | -------------------------------------------------------------------------------- /jni/include/searchutility.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef PINYINIME_ANDPY_INCLUDE_SEARCHCOMMON_H__ 18 | #define PINYINIME_ANDPY_INCLUDE_SEARCHCOMMON_H__ 19 | 20 | #include 21 | #include "./spellingtrie.h" 22 | 23 | namespace ime_pinyin { 24 | 25 | // Type used to identify the size of a pool, such as id pool, etc. 26 | typedef uint16 PoolPosType; 27 | 28 | // Type used to identify a parsing mile stone in an atom dictionary. 29 | typedef uint16 MileStoneHandle; 30 | 31 | // Type used to express a lemma and its probability score. 32 | typedef struct { 33 | size_t id:(kLemmaIdSize * 8); 34 | size_t lma_len:4; 35 | uint16 psb; // The score, the lower psb, the higher possibility. 36 | // For single character items, we may also need Hanzi. 37 | // For multiple characer items, ignore it. 38 | char16 hanzi; 39 | } LmaPsbItem, *PLmaPsbItem; 40 | 41 | // LmaPsbItem extended with string. 42 | typedef struct { 43 | LmaPsbItem lpi; 44 | char16 str[kMaxLemmaSize + 1]; 45 | } LmaPsbStrItem, *PLmaPsbStrItem; 46 | 47 | 48 | typedef struct { 49 | float psb; 50 | char16 pre_hzs[kMaxPredictSize]; 51 | uint16 his_len; // The length of the history used to do the prediction. 52 | } NPredictItem, *PNPredictItem; 53 | 54 | // Parameter structure used to extend in a dictionary. All dictionaries 55 | // receives the same DictExtPara and a dictionary specific MileStoneHandle for 56 | // extending. 57 | // 58 | // When the user inputs a new character, AtomDictBase::extend_dict() will be 59 | // called at least once for each dictionary. 60 | // 61 | // For example, when the user inputs "wm", extend_dict() will be called twice, 62 | // and the DictExtPara parameter are as follows respectively: 63 | // 1. splids = {w, m}; splids_extended = 1; ext_len = 1; step_no = 1; 64 | // splid_end_split = false; id_start = wa(the first id start with 'w'); 65 | // id_num = number of ids starting with 'w'. 66 | // 2. splids = {m}; splids_extended = 0; ext_len = 1; step_no = 1; 67 | // splid_end_split = false; id_start = wa; id_num = number of ids starting with 68 | // 'w'. 69 | // 70 | // For string "women", one of the cases of the DictExtPara parameter is: 71 | // splids = {wo, men}, splids_extended = 1, ext_len = 3 (length of "men"), 72 | // step_no = 4; splid_end_split = false; id_start = men, id_num = 1. 73 | // 74 | typedef struct { 75 | // Spelling ids for extending, there are splids_extended + 1 ids in the 76 | // buffer. 77 | // For a normal lemma, there can only be kMaxLemmaSize spelling ids in max, 78 | // but for a composing phrase, there can kMaxSearchSteps spelling ids. 79 | uint16 splids[kMaxSearchSteps]; 80 | 81 | // Number of ids that have been used before. splids[splids_extended] is the 82 | // newly added id for the current extension. 83 | uint16 splids_extended; 84 | 85 | // The step span of the extension. It is also the size of the string for 86 | // the newly added spelling id. 87 | uint16 ext_len; 88 | 89 | // The step number for the current extension. It is also the ending position 90 | // in the input Pinyin string for the substring of spelling ids in splids[]. 91 | // For example, when the user inputs "women", step_no = 4. 92 | // This parameter may useful to manage the MileStoneHandle list for each 93 | // step. When the user deletes a character from the string, MileStoneHandle 94 | // objects for the the steps after that character should be reset; when the 95 | // user begins a new string, all MileStoneHandle objects should be reset. 96 | uint16 step_no; 97 | 98 | // Indicate whether the newly added spelling ends with a splitting character 99 | bool splid_end_split; 100 | 101 | // If the newly added id is a half id, id_start is the first id of the 102 | // corresponding full ids; if the newly added id is a full id, id_start is 103 | // that id. 104 | uint16 id_start; 105 | 106 | // If the newly added id is a half id, id_num is the number of corresponding 107 | // ids; if it is a full id, id_num == 1. 108 | uint16 id_num; 109 | }DictExtPara, *PDictExtPara; 110 | 111 | bool is_system_lemma(LemmaIdType lma_id); 112 | bool is_user_lemma(LemmaIdType lma_id); 113 | bool is_composing_lemma(LemmaIdType lma_id); 114 | 115 | int cmp_lpi_with_psb(const void *p1, const void *p2); 116 | int cmp_lpi_with_unified_psb(const void *p1, const void *p2); 117 | int cmp_lpi_with_id(const void *p1, const void *p2); 118 | int cmp_lpi_with_hanzi(const void *p1, const void *p2); 119 | 120 | int cmp_lpsi_with_str(const void *p1, const void *p2); 121 | 122 | int cmp_hanzis_1(const void *p1, const void *p2); 123 | int cmp_hanzis_2(const void *p1, const void *p2); 124 | int cmp_hanzis_3(const void *p1, const void *p2); 125 | int cmp_hanzis_4(const void *p1, const void *p2); 126 | int cmp_hanzis_5(const void *p1, const void *p2); 127 | int cmp_hanzis_6(const void *p1, const void *p2); 128 | int cmp_hanzis_7(const void *p1, const void *p2); 129 | int cmp_hanzis_8(const void *p1, const void *p2); 130 | 131 | int cmp_npre_by_score(const void *p1, const void *p2); 132 | int cmp_npre_by_hislen_score(const void *p1, const void *p2); 133 | int cmp_npre_by_hanzi_score(const void *p1, const void *p2); 134 | 135 | 136 | size_t remove_duplicate_npre(NPredictItem *npre_items, size_t npre_num); 137 | 138 | size_t align_to_size_t(size_t size); 139 | 140 | } // namespace 141 | 142 | #endif // PINYINIME_ANDPY_INCLUDE_SEARCHCOMMON_H__ 143 | -------------------------------------------------------------------------------- /jni/include/spellingtable.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef PINYINIME_INCLUDE_SPELLINGTABLE_H__ 18 | #define PINYINIME_INCLUDE_SPELLINGTABLE_H__ 19 | 20 | #include 21 | #include "./dictdef.h" 22 | 23 | namespace ime_pinyin { 24 | 25 | #ifdef ___BUILD_MODEL___ 26 | 27 | const size_t kMaxSpellingSize = kMaxPinyinSize; 28 | 29 | typedef struct { 30 | char str[kMaxSpellingSize + 1]; 31 | double freq; 32 | } RawSpelling, *PRawSpelling; 33 | 34 | // This class is used to store the spelling strings 35 | // The length of the input spelling string should be less or equal to the 36 | // spelling_size_ (set by init_table). If the input string is too long, 37 | // we only keep its first spelling_size_ chars. 38 | class SpellingTable { 39 | private: 40 | static const size_t kNotSupportNum = 3; 41 | static const char kNotSupportList[kNotSupportNum][kMaxSpellingSize + 1]; 42 | 43 | bool need_score_; 44 | 45 | size_t spelling_max_num_; 46 | 47 | RawSpelling *raw_spellings_; 48 | 49 | // Used to store spelling strings. If the spelling table needs to calculate 50 | // score, an extra char after each spelling string is the score. 51 | // An item with a lower score has a higher probability. 52 | char *spelling_buf_; 53 | size_t spelling_size_; 54 | 55 | double total_freq_; 56 | 57 | size_t spelling_num_; 58 | 59 | double score_amplifier_; 60 | 61 | unsigned char average_score_; 62 | 63 | // If frozen is true, put_spelling() and contain() are not allowed to call. 64 | bool frozen_; 65 | 66 | size_t get_hash_pos(const char* spelling_str); 67 | size_t hash_pos_next(size_t hash_pos); 68 | void free_resource(); 69 | public: 70 | SpellingTable(); 71 | ~SpellingTable(); 72 | 73 | // pure_spl_size is the pure maximum spelling string size. For example, 74 | // "zhuang" is the longgest item in Pinyin, so pure_spl_size should be 6. 75 | // spl_max_num is the maximum number of spelling strings to store. 76 | // need_score is used to indicate whether the caller needs to calculate a 77 | // score for each spelling. 78 | bool init_table(size_t pure_spl_size, size_t spl_max_num, bool need_score); 79 | 80 | // Put a spelling string to the table. 81 | // It always returns false if called after arrange() withtout a new 82 | // init_table() operation. 83 | // freq is the spelling's occuring count. 84 | // If the spelling has been in the table, occuring count will accumulated. 85 | bool put_spelling(const char* spelling_str, double spl_count); 86 | 87 | // Test whether a spelling string is in the table. 88 | // It always returns false, when being called after arrange() withtout a new 89 | // init_table() operation. 90 | bool contain(const char* spelling_str); 91 | 92 | // Sort the spelling strings and put them from the begin of the buffer. 93 | // Return the pointer of the sorted spelling strings. 94 | // item_size and spl_num return the item size and number of spelling. 95 | // Because each spelling uses a '\0' as terminator, the returned item_size is 96 | // at least one char longer than the spl_size parameter specified by 97 | // init_table(). If the table is initialized to calculate score, item_size 98 | // will be increased by 1, and current_spl_str[item_size - 1] stores an 99 | // unsinged char score. 100 | // An item with a lower score has a higher probability. 101 | // Do not call put_spelling() and contains() after arrange(). 102 | const char* arrange(size_t *item_size, size_t *spl_num); 103 | 104 | float get_score_amplifier(); 105 | 106 | unsigned char get_average_score(); 107 | }; 108 | #endif // ___BUILD_MODEL___ 109 | } 110 | 111 | #endif // PINYINIME_INCLUDE_SPELLINGTABLE_H__ 112 | -------------------------------------------------------------------------------- /jni/include/splparser.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef PINYINIME_INCLUDE_SPLPARSER_H__ 18 | #define PINYINIME_INCLUDE_SPLPARSER_H__ 19 | 20 | #include "./dictdef.h" 21 | #include "./spellingtrie.h" 22 | 23 | namespace ime_pinyin { 24 | 25 | class SpellingParser { 26 | protected: 27 | const SpellingTrie *spl_trie_; 28 | 29 | public: 30 | SpellingParser(); 31 | 32 | // Given a string, parse it into a spelling id stream. 33 | // If the whole string are sucessfully parsed, last_is_pre will be true; 34 | // if the whole string is not fullly parsed, last_is_pre will return whether 35 | // the last part of the string is a prefix of a full spelling string. For 36 | // example, given string "zhengzhon", "zhon" is not a valid speling, but it is 37 | // the prefix of "zhong". 38 | // 39 | // If splstr starts with a character not in ['a'-z'] (it is a split char), 40 | // return 0. 41 | // Split char can only appear in the middle of the string or at the end. 42 | uint16 splstr_to_idxs(const char *splstr, uint16 str_len, uint16 splidx[], 43 | uint16 start_pos[], uint16 max_size, bool &last_is_pre); 44 | 45 | // Similar to splstr_to_idxs(), the only difference is that splstr_to_idxs() 46 | // convert single-character Yunmus into half ids, while this function converts 47 | // them into full ids. 48 | uint16 splstr_to_idxs_f(const char *splstr, uint16 str_len, uint16 splidx[], 49 | uint16 start_pos[], uint16 max_size, bool &last_is_pre); 50 | 51 | // Similar to splstr_to_idxs(), the only difference is that this function 52 | // uses char16 instead of char8. 53 | uint16 splstr16_to_idxs(const char16 *splstr, uint16 str_len, uint16 splidx[], 54 | uint16 start_pos[], uint16 max_size, bool &last_is_pre); 55 | 56 | // Similar to splstr_to_idxs_f(), the only difference is that this function 57 | // uses char16 instead of char8. 58 | uint16 splstr16_to_idxs_f(const char16 *splstr16, uint16 str_len, 59 | uint16 splidx[], uint16 start_pos[], 60 | uint16 max_size, bool &last_is_pre); 61 | 62 | // If the given string is a spelling, return the id, others, return 0. 63 | // If the give string is a single char Yunmus like "A", and the char is 64 | // enabled in ShouZiMu mode, the returned spelling id will be a half id. 65 | // When the returned spelling id is a half id, *is_pre returns whether it 66 | // is a prefix of a full spelling string. 67 | uint16 get_splid_by_str(const char *splstr, uint16 str_len, bool *is_pre); 68 | 69 | // If the given string is a spelling, return the id, others, return 0. 70 | // If the give string is a single char Yunmus like "a", no matter the char 71 | // is enabled in ShouZiMu mode or not, the returned spelling id will be 72 | // a full id. 73 | // When the returned spelling id is a half id, *p_is_pre returns whether it 74 | // is a prefix of a full spelling string. 75 | uint16 get_splid_by_str_f(const char *splstr, uint16 str_len, bool *is_pre); 76 | 77 | // Splitter chars are not included. 78 | bool is_valid_to_parse(char ch); 79 | 80 | // When auto-correction is not enabled, get_splid_by_str() will be called to 81 | // return the single result. When auto-correction is enabled, this function 82 | // will be called to get the results. Auto-correction is not ready. 83 | // full_id_num returns number of full spelling ids. 84 | // is_pre returns whether the given string is the prefix of a full spelling 85 | // string. 86 | // If splstr starts with a character not in [a-zA-Z] (it is a split char), 87 | // return 0. 88 | // Split char can only appear in the middle of the string or at the end. 89 | // The caller should guarantee NULL != splstr && str_len > 0 && NULL != splidx 90 | uint16 get_splids_parallel(const char *splstr, uint16 str_len, 91 | uint16 splidx[], uint16 max_size, 92 | uint16 &full_id_num, bool &is_pre); 93 | }; 94 | } 95 | 96 | #endif // PINYINIME_INCLUDE_SPLPARSER_H__ 97 | -------------------------------------------------------------------------------- /jni/include/sync.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef PINYINIME_INCLUDE_SYNC_H__ 18 | #define PINYINIME_INCLUDE_SYNC_H__ 19 | 20 | #define ___SYNC_ENABLED___ 21 | 22 | #ifdef ___SYNC_ENABLED___ 23 | 24 | #include "userdict.h" 25 | 26 | namespace ime_pinyin { 27 | 28 | // Class for user dictionary synchronization 29 | // This class is not thread safe 30 | // Normal invoking flow will be 31 | // begin() -> 32 | // put_lemmas() x N -> 33 | // { 34 | // get_lemmas() -> 35 | // [ get_last_got_count() ] -> 36 | // clear_last_got() -> 37 | // } x N -> 38 | // finish() 39 | class Sync { 40 | public: 41 | Sync(); 42 | ~Sync(); 43 | 44 | static const int kUserDictMaxLemmaCount = 5000; 45 | static const int kUserDictMaxLemmaSize = 200000; 46 | static const int kUserDictRatio = 20; 47 | 48 | bool begin(const char * filename); 49 | 50 | // Merge lemmas downloaded from sync server into local dictionary 51 | // lemmas, lemmas string encoded in UTF16LE 52 | // len, length of lemmas string 53 | // Return how many lemmas merged successfully 54 | int put_lemmas(char16 * lemmas, int len); 55 | 56 | // Get local new user lemmas into UTF16LE string 57 | // str, buffer ptr to store new user lemmas 58 | // size, size of buffer 59 | // Return length of returned buffer in measure of UTF16LE 60 | int get_lemmas(char16 * str, int size); 61 | 62 | // Return lemmas count in last get_lemmas() 63 | int get_last_got_count(); 64 | 65 | // Return total lemmas count need get_lemmas() 66 | int get_total_count(); 67 | 68 | // Clear lemmas got by recent get_lemmas() 69 | void clear_last_got(); 70 | 71 | void finish(); 72 | 73 | int get_capacity(); 74 | 75 | private: 76 | UserDict * userdict_; 77 | char * dictfile_; 78 | int last_count_; 79 | }; 80 | 81 | } 82 | 83 | #endif 84 | 85 | #endif // PINYINIME_INCLUDE_SYNC_H__ 86 | -------------------------------------------------------------------------------- /jni/include/utf16char.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef PINYINIME_INCLUDE_UTF16CHAR_H__ 18 | #define PINYINIME_INCLUDE_UTF16CHAR_H__ 19 | 20 | #include 21 | 22 | namespace ime_pinyin { 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | typedef unsigned short char16; 29 | 30 | // Get a token from utf16_str, 31 | // Returned pointer is a '\0'-terminated utf16 string, or NULL 32 | // *utf16_str_next returns the next part of the string for further tokenizing 33 | char16* utf16_strtok(char16 *utf16_str, size_t *token_size, 34 | char16 **utf16_str_next); 35 | 36 | int utf16_atoi(const char16 *utf16_str); 37 | 38 | float utf16_atof(const char16 *utf16_str); 39 | 40 | size_t utf16_strlen(const char16 *utf16_str); 41 | 42 | int utf16_strcmp(const char16 *str1, const char16 *str2); 43 | int utf16_strncmp(const char16 *str1, const char16 *str2, size_t size); 44 | 45 | char16* utf16_strcpy(char16 *dst, const char16 *src); 46 | char16* utf16_strncpy(char16 *dst, const char16 *src, size_t size); 47 | 48 | 49 | char* utf16_strcpy_tochar(char *dst, const char16 *src); 50 | 51 | #ifdef __cplusplus 52 | } 53 | #endif 54 | } 55 | 56 | #endif // PINYINIME_INCLUDE_UTF16CHAR_H__ 57 | -------------------------------------------------------------------------------- /jni/include/utf16reader.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef PINYINIME_INCLUDE_UTF16READER_H__ 18 | #define PINYINIME_INCLUDE_UTF16READER_H__ 19 | 20 | #include 21 | #include "./utf16char.h" 22 | 23 | namespace ime_pinyin { 24 | 25 | class Utf16Reader { 26 | private: 27 | FILE *fp_; 28 | char16 *buffer_; 29 | size_t buffer_total_len_; 30 | size_t buffer_next_pos_; 31 | 32 | // Always less than buffer_total_len_ - buffer_next_pos_ 33 | size_t buffer_valid_len_; 34 | 35 | public: 36 | Utf16Reader(); 37 | ~Utf16Reader(); 38 | 39 | // filename is the name of the file to open. 40 | // buffer_len specifies how long buffer should be allocated to speed up the 41 | // future reading 42 | bool open(const char* filename, size_t buffer_len); 43 | char16* readline(char16* read_buf, size_t max_len); 44 | bool close(); 45 | }; 46 | } 47 | 48 | #endif // PINYINIME_INCLUDE_UTF16READER_H__ 49 | -------------------------------------------------------------------------------- /jni/share/lpicache.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include "../include/lpicache.h" 19 | 20 | namespace ime_pinyin { 21 | 22 | LpiCache* LpiCache::instance_ = NULL; 23 | 24 | LpiCache::LpiCache() { 25 | lpi_cache_ = new LmaPsbItem[kFullSplIdStart * kMaxLpiCachePerId]; 26 | lpi_cache_len_ = new uint16[kFullSplIdStart]; 27 | assert(NULL != lpi_cache_); 28 | assert(NULL != lpi_cache_len_); 29 | for (uint16 id = 0; id < kFullSplIdStart; id++) 30 | lpi_cache_len_[id] = 0; 31 | } 32 | 33 | LpiCache::~LpiCache() { 34 | if (NULL != lpi_cache_) 35 | delete [] lpi_cache_; 36 | 37 | if (NULL != lpi_cache_len_) 38 | delete [] lpi_cache_len_; 39 | } 40 | 41 | LpiCache& LpiCache::get_instance() { 42 | if (NULL == instance_) { 43 | instance_ = new LpiCache(); 44 | assert(NULL != instance_); 45 | } 46 | return *instance_; 47 | } 48 | 49 | bool LpiCache::is_cached(uint16 splid) { 50 | if (splid >= kFullSplIdStart) 51 | return false; 52 | return lpi_cache_len_[splid] != 0; 53 | } 54 | 55 | size_t LpiCache::put_cache(uint16 splid, LmaPsbItem lpi_items[], 56 | size_t lpi_num) { 57 | uint16 num = kMaxLpiCachePerId; 58 | if (num > lpi_num) 59 | num = static_cast(lpi_num); 60 | 61 | LmaPsbItem *lpi_cache_this = lpi_cache_ + splid * kMaxLpiCachePerId; 62 | for (uint16 pos = 0; pos < num; pos++) 63 | lpi_cache_this[pos] = lpi_items[pos]; 64 | 65 | lpi_cache_len_[splid] = num; 66 | return num; 67 | } 68 | 69 | size_t LpiCache::get_cache(uint16 splid, LmaPsbItem lpi_items[], 70 | size_t lpi_max) { 71 | if (lpi_max > lpi_cache_len_[splid]) 72 | lpi_max = lpi_cache_len_[splid]; 73 | 74 | LmaPsbItem *lpi_cache_this = lpi_cache_ + splid * kMaxLpiCachePerId; 75 | for (uint16 pos = 0; pos < lpi_max; pos++) { 76 | lpi_items[pos] = lpi_cache_this[pos]; 77 | } 78 | return lpi_max; 79 | } 80 | 81 | } // namespace ime_pinyin 82 | -------------------------------------------------------------------------------- /jni/share/mystdlib.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | namespace ime_pinyin { 20 | 21 | // For debug purpose. You can add a fixed version of qsort and bsearch functions 22 | // here so that the output will be totally the same under different platforms. 23 | 24 | void myqsort(void *p, size_t n, size_t es, 25 | int (*cmp)(const void *, const void *)) { 26 | qsort(p,n, es, cmp); 27 | } 28 | 29 | void *mybsearch(const void *k, const void *b, 30 | size_t n, size_t es, 31 | int (*cmp)(const void *, const void *)) { 32 | return bsearch(k, b, n, es, cmp); 33 | } 34 | } // namespace ime_pinyin 35 | -------------------------------------------------------------------------------- /jni/share/pinyinime.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include "../include/pinyinime.h" 19 | #include "../include/dicttrie.h" 20 | #include "../include/matrixsearch.h" 21 | #include "../include/spellingtrie.h" 22 | 23 | #ifdef __cplusplus 24 | extern "C" { 25 | #endif 26 | 27 | using namespace ime_pinyin; 28 | 29 | // The maximum number of the prediction items. 30 | static const size_t kMaxPredictNum = 500; 31 | 32 | // Used to search Pinyin string and give the best candidate. 33 | MatrixSearch* matrix_search = NULL; 34 | 35 | char16 predict_buf[kMaxPredictNum][kMaxPredictSize + 1]; 36 | 37 | bool im_open_decoder(const char *fn_sys_dict, const char *fn_usr_dict) { 38 | if (NULL != matrix_search) 39 | delete matrix_search; 40 | 41 | matrix_search = new MatrixSearch(); 42 | if (NULL == matrix_search) { 43 | return false; 44 | } 45 | 46 | return matrix_search->init(fn_sys_dict, fn_usr_dict); 47 | } 48 | 49 | bool im_open_decoder_fd(int sys_fd, long start_offset, long length, 50 | const char *fn_usr_dict) { 51 | if (NULL != matrix_search) 52 | delete matrix_search; 53 | 54 | matrix_search = new MatrixSearch(); 55 | if (NULL == matrix_search) 56 | return false; 57 | 58 | return matrix_search->init_fd(sys_fd, start_offset, length, fn_usr_dict); 59 | } 60 | 61 | void im_close_decoder() { 62 | if (NULL != matrix_search) { 63 | matrix_search->close(); 64 | delete matrix_search; 65 | } 66 | matrix_search = NULL; 67 | } 68 | 69 | void im_set_max_lens(size_t max_sps_len, size_t max_hzs_len) { 70 | if (NULL != matrix_search) { 71 | matrix_search->set_max_lens(max_sps_len, max_hzs_len); 72 | } 73 | } 74 | 75 | void im_flush_cache() { 76 | if (NULL != matrix_search) 77 | matrix_search->flush_cache(); 78 | } 79 | 80 | // To be updated. 81 | size_t im_search(const char* pybuf, size_t pylen) { 82 | if (NULL == matrix_search) 83 | return 0; 84 | 85 | matrix_search->search(pybuf, pylen); 86 | return matrix_search->get_candidate_num(); 87 | } 88 | 89 | size_t im_delsearch(size_t pos, bool is_pos_in_splid, 90 | bool clear_fixed_this_step) { 91 | if (NULL == matrix_search) 92 | return 0; 93 | matrix_search->delsearch(pos, is_pos_in_splid, clear_fixed_this_step); 94 | return matrix_search->get_candidate_num(); 95 | } 96 | 97 | void im_reset_search() { 98 | if (NULL == matrix_search) 99 | return; 100 | 101 | matrix_search->reset_search(); 102 | } 103 | 104 | // To be removed 105 | size_t im_add_letter(char ch) { 106 | return 0; 107 | } 108 | 109 | const char* im_get_sps_str(size_t *decoded_len) { 110 | if (NULL == matrix_search) 111 | return NULL; 112 | 113 | return matrix_search->get_pystr(decoded_len); 114 | } 115 | 116 | char16* im_get_candidate(size_t cand_id, char16* cand_str, 117 | size_t max_len) { 118 | if (NULL == matrix_search) 119 | return NULL; 120 | 121 | return matrix_search->get_candidate(cand_id, cand_str, max_len); 122 | } 123 | 124 | size_t im_get_spl_start_pos(const uint16 *&spl_start) { 125 | if (NULL == matrix_search) 126 | return 0; 127 | 128 | return matrix_search->get_spl_start(spl_start); 129 | } 130 | 131 | size_t im_choose(size_t choice_id) { 132 | if (NULL == matrix_search) 133 | return 0; 134 | 135 | return matrix_search->choose(choice_id); 136 | } 137 | 138 | size_t im_cancel_last_choice() { 139 | if (NULL == matrix_search) 140 | return 0; 141 | 142 | return matrix_search->cancel_last_choice(); 143 | } 144 | 145 | size_t im_get_fixed_len() { 146 | if (NULL == matrix_search) 147 | return 0; 148 | 149 | return matrix_search->get_fixedlen(); 150 | } 151 | 152 | // To be removed 153 | bool im_cancel_input() { 154 | return true; 155 | } 156 | 157 | 158 | size_t im_get_predicts(const char16 *his_buf, 159 | char16 (*&pre_buf)[kMaxPredictSize + 1]) { 160 | if (NULL == his_buf) 161 | return 0; 162 | 163 | size_t fixed_len = utf16_strlen(his_buf); 164 | const char16 *fixed_ptr = his_buf; 165 | if (fixed_len > kMaxPredictSize) { 166 | fixed_ptr += fixed_len - kMaxPredictSize; 167 | fixed_len = kMaxPredictSize; 168 | } 169 | 170 | pre_buf = predict_buf; 171 | return matrix_search->get_predicts(his_buf, pre_buf, kMaxPredictNum); 172 | } 173 | 174 | void im_enable_shm_as_szm(bool enable) { 175 | SpellingTrie &spl_trie = SpellingTrie::get_instance(); 176 | spl_trie.szm_enable_shm(enable); 177 | } 178 | 179 | void im_enable_ym_as_szm(bool enable) { 180 | SpellingTrie &spl_trie = SpellingTrie::get_instance(); 181 | spl_trie.szm_enable_ym(enable); 182 | } 183 | 184 | #ifdef __cplusplus 185 | } 186 | #endif 187 | -------------------------------------------------------------------------------- /jni/share/searchutility.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include "../include/mystdlib.h" 19 | #include "../include/searchutility.h" 20 | 21 | namespace ime_pinyin { 22 | 23 | bool is_system_lemma(LemmaIdType lma_id) { 24 | return (0 < lma_id && lma_id <= kSysDictIdEnd); 25 | } 26 | 27 | bool is_user_lemma(LemmaIdType lma_id) { 28 | return (kUserDictIdStart <= lma_id && lma_id <= kUserDictIdEnd); 29 | } 30 | 31 | bool is_composing_lemma(LemmaIdType lma_id) { 32 | return (kLemmaIdComposing == lma_id); 33 | } 34 | 35 | int cmp_lpi_with_psb(const void *p1, const void *p2) { 36 | if ((static_cast(p1))->psb > 37 | (static_cast(p2))->psb) 38 | return 1; 39 | if ((static_cast(p1))->psb < 40 | (static_cast(p2))->psb) 41 | return -1; 42 | return 0; 43 | } 44 | 45 | int cmp_lpi_with_unified_psb(const void *p1, const void *p2) { 46 | const LmaPsbItem *item1 = static_cast(p1); 47 | const LmaPsbItem *item2 = static_cast(p2); 48 | 49 | // The real unified psb is psb1 / lma_len1 and psb2 * lma_len2 50 | // But we use psb1 * lma_len2 and psb2 * lma_len1 to get better 51 | // precision. 52 | size_t up1 = item1->psb * (item2->lma_len); 53 | size_t up2 = item2->psb * (item1->lma_len); 54 | if (up1 < up2) { 55 | return -1; 56 | } 57 | if (up1 > up2) { 58 | return 1; 59 | } 60 | return 0; 61 | } 62 | 63 | int cmp_lpi_with_id(const void *p1, const void *p2) { 64 | if ((static_cast(p1))->id < 65 | (static_cast(p2))->id) 66 | return -1; 67 | if ((static_cast(p1))->id > 68 | (static_cast(p2))->id) 69 | return 1; 70 | return 0; 71 | } 72 | 73 | int cmp_lpi_with_hanzi(const void *p1, const void *p2) { 74 | if ((static_cast(p1))->hanzi < 75 | (static_cast(p2))->hanzi) 76 | return -1; 77 | if ((static_cast(p1))->hanzi > 78 | (static_cast(p2))->hanzi) 79 | return 1; 80 | 81 | return 0; 82 | } 83 | 84 | int cmp_lpsi_with_str(const void *p1, const void *p2) { 85 | return utf16_strcmp((static_cast(p1))->str, 86 | (static_cast(p2))->str); 87 | } 88 | 89 | 90 | int cmp_hanzis_1(const void *p1, const void *p2) { 91 | if (*static_cast(p1) < 92 | *static_cast(p2)) 93 | return -1; 94 | 95 | if (*static_cast(p1) > 96 | *static_cast(p2)) 97 | return 1; 98 | return 0; 99 | } 100 | 101 | int cmp_hanzis_2(const void *p1, const void *p2) { 102 | return utf16_strncmp(static_cast(p1), 103 | static_cast(p2), 2); 104 | } 105 | 106 | int cmp_hanzis_3(const void *p1, const void *p2) { 107 | return utf16_strncmp(static_cast(p1), 108 | static_cast(p2), 3); 109 | } 110 | 111 | int cmp_hanzis_4(const void *p1, const void *p2) { 112 | return utf16_strncmp(static_cast(p1), 113 | static_cast(p2), 4); 114 | } 115 | 116 | int cmp_hanzis_5(const void *p1, const void *p2) { 117 | return utf16_strncmp(static_cast(p1), 118 | static_cast(p2), 5); 119 | } 120 | 121 | int cmp_hanzis_6(const void *p1, const void *p2) { 122 | return utf16_strncmp(static_cast(p1), 123 | static_cast(p2), 6); 124 | } 125 | 126 | int cmp_hanzis_7(const void *p1, const void *p2) { 127 | return utf16_strncmp(static_cast(p1), 128 | static_cast(p2), 7); 129 | } 130 | 131 | int cmp_hanzis_8(const void *p1, const void *p2) { 132 | return utf16_strncmp(static_cast(p1), 133 | static_cast(p2), 8); 134 | } 135 | 136 | int cmp_npre_by_score(const void *p1, const void *p2) { 137 | if ((static_cast(p1))->psb > 138 | (static_cast(p2))->psb) 139 | return 1; 140 | 141 | if ((static_cast(p1))->psb < 142 | (static_cast(p2))->psb) 143 | return -1; 144 | 145 | return 0; 146 | } 147 | 148 | int cmp_npre_by_hislen_score(const void *p1, const void *p2) { 149 | if ((static_cast(p1))->his_len < 150 | (static_cast(p2))->his_len) 151 | return 1; 152 | 153 | if ((static_cast(p1))->his_len > 154 | (static_cast(p2))->his_len) 155 | return -1; 156 | 157 | if ((static_cast(p1))->psb > 158 | (static_cast(p2))->psb) 159 | return 1; 160 | 161 | if ((static_cast(p1))->psb < 162 | (static_cast(p2))->psb) 163 | return -1; 164 | 165 | return 0; 166 | } 167 | 168 | int cmp_npre_by_hanzi_score(const void *p1, const void *p2) { 169 | int ret_v = (utf16_strncmp((static_cast(p1))->pre_hzs, 170 | (static_cast(p2))->pre_hzs, kMaxPredictSize)); 171 | if (0 != ret_v) 172 | return ret_v; 173 | 174 | if ((static_cast(p1))->psb > 175 | (static_cast(p2))->psb) 176 | return 1; 177 | 178 | if ((static_cast(p1))->psb < 179 | (static_cast(p2))->psb) 180 | return -1; 181 | 182 | return 0; 183 | } 184 | 185 | size_t remove_duplicate_npre(NPredictItem *npre_items, size_t npre_num) { 186 | if (NULL == npre_items || 0 == npre_num) 187 | return 0; 188 | 189 | myqsort(npre_items, npre_num, sizeof(NPredictItem), cmp_npre_by_hanzi_score); 190 | 191 | size_t remain_num = 1; // The first one is reserved. 192 | for (size_t pos = 1; pos < npre_num; pos++) { 193 | if (utf16_strncmp(npre_items[pos].pre_hzs, 194 | npre_items[remain_num - 1].pre_hzs, 195 | kMaxPredictSize) != 0) { 196 | if (remain_num != pos) { 197 | npre_items[remain_num] = npre_items[pos]; 198 | } 199 | remain_num++; 200 | } 201 | } 202 | return remain_num; 203 | } 204 | 205 | size_t align_to_size_t(size_t size) { 206 | size_t s = sizeof(size_t); 207 | return (size + s -1) / s * s; 208 | } 209 | 210 | } // namespace ime_pinyin 211 | -------------------------------------------------------------------------------- /jni/share/spellingtable.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include "../include/spellingtable.h" 23 | 24 | namespace ime_pinyin { 25 | 26 | #ifdef ___BUILD_MODEL___ 27 | 28 | const char SpellingTable:: 29 | kNotSupportList[kNotSupportNum][kMaxSpellingSize + 1] = {"HM", "HNG", "NG"}; 30 | 31 | // "" is the biggest, so that all empty strings will be moved to the end 32 | // _eb mean empty is biggest 33 | int compare_raw_spl_eb(const void* p1, const void* p2) { 34 | if ('\0' == (static_cast(p1))->str[0]) 35 | return 1; 36 | 37 | if ('\0' == (static_cast(p2))->str[0]) 38 | return -1; 39 | 40 | return strcmp((static_cast(p1))->str, 41 | (static_cast(p2))->str); 42 | } 43 | 44 | size_t get_odd_next(size_t value) { 45 | size_t v_next = value; 46 | while (true) { 47 | size_t v_next_sqrt = (size_t)sqrt(v_next); 48 | 49 | bool is_odd = true; 50 | for (size_t v_dv = 2; v_dv < v_next_sqrt + 1; v_dv++) { 51 | if (v_next % v_dv == 0) { 52 | is_odd = false; 53 | break; 54 | } 55 | } 56 | 57 | if (is_odd) 58 | return v_next; 59 | 60 | v_next++; 61 | } 62 | 63 | // never reach here 64 | return 0; 65 | } 66 | 67 | SpellingTable::SpellingTable() { 68 | need_score_ = false; 69 | raw_spellings_ = NULL; 70 | spelling_buf_ = NULL; 71 | spelling_num_ = 0; 72 | total_freq_ = 0; 73 | frozen_ = true; 74 | } 75 | 76 | SpellingTable::~SpellingTable() { 77 | free_resource(); 78 | } 79 | 80 | size_t SpellingTable::get_hash_pos(const char* spelling_str) { 81 | size_t hash_pos = 0; 82 | for (size_t pos = 0; pos < spelling_size_; pos++) { 83 | if ('\0' == spelling_str[pos]) 84 | break; 85 | hash_pos += (size_t)spelling_str[pos]; 86 | } 87 | 88 | hash_pos = hash_pos % spelling_max_num_; 89 | return hash_pos; 90 | } 91 | 92 | size_t SpellingTable::hash_pos_next(size_t hash_pos) { 93 | hash_pos += 123; 94 | hash_pos = hash_pos % spelling_max_num_; 95 | return hash_pos; 96 | } 97 | 98 | void SpellingTable::free_resource() { 99 | if (NULL != raw_spellings_) 100 | delete [] raw_spellings_; 101 | raw_spellings_ = NULL; 102 | 103 | if (NULL != spelling_buf_) 104 | delete [] spelling_buf_; 105 | spelling_buf_ = NULL; 106 | } 107 | 108 | bool SpellingTable::init_table(size_t pure_spl_size, size_t spl_max_num, 109 | bool need_score) { 110 | if (pure_spl_size == 0 || spl_max_num ==0) 111 | return false; 112 | 113 | need_score_ = need_score; 114 | 115 | free_resource(); 116 | 117 | spelling_size_ = pure_spl_size + 1; 118 | if (need_score) 119 | spelling_size_ += 1; 120 | spelling_max_num_ = get_odd_next(spl_max_num); 121 | spelling_num_ = 0; 122 | 123 | raw_spellings_ = new RawSpelling[spelling_max_num_]; 124 | spelling_buf_ = new char[spelling_max_num_ * (spelling_size_)]; 125 | if (NULL == raw_spellings_ || NULL == spelling_buf_) { 126 | free_resource(); 127 | return false; 128 | } 129 | 130 | memset(raw_spellings_, 0, spelling_max_num_ * sizeof(RawSpelling)); 131 | memset(spelling_buf_, 0, spelling_max_num_ * (spelling_size_)); 132 | frozen_ = false; 133 | total_freq_ = 0; 134 | return true; 135 | } 136 | 137 | bool SpellingTable::put_spelling(const char* spelling_str, double freq) { 138 | if (frozen_ || NULL == spelling_str) 139 | return false; 140 | 141 | for (size_t pos = 0; pos < kNotSupportNum; pos++) { 142 | if (strcmp(spelling_str, kNotSupportList[pos]) == 0) { 143 | return false; 144 | } 145 | } 146 | 147 | total_freq_ += freq; 148 | 149 | size_t hash_pos = get_hash_pos(spelling_str); 150 | 151 | raw_spellings_[hash_pos].str[spelling_size_ - 1] = '\0'; 152 | 153 | if (strncmp(raw_spellings_[hash_pos].str, spelling_str, 154 | spelling_size_ - 1) == 0) { 155 | raw_spellings_[hash_pos].freq += freq; 156 | return true; 157 | } 158 | 159 | size_t hash_pos_ori = hash_pos; 160 | 161 | while (true) { 162 | if (strncmp(raw_spellings_[hash_pos].str, 163 | spelling_str, spelling_size_ - 1) == 0) { 164 | raw_spellings_[hash_pos].freq += freq; 165 | return true; 166 | } 167 | 168 | if ('\0' == raw_spellings_[hash_pos].str[0]) { 169 | raw_spellings_[hash_pos].freq += freq; 170 | strncpy(raw_spellings_[hash_pos].str, spelling_str, spelling_size_ - 1); 171 | raw_spellings_[hash_pos].str[spelling_size_ - 1] = '\0'; 172 | spelling_num_++; 173 | return true; 174 | } 175 | 176 | hash_pos = hash_pos_next(hash_pos); 177 | if (hash_pos_ori == hash_pos) 178 | return false; 179 | } 180 | 181 | // never reach here 182 | return false; 183 | } 184 | 185 | bool SpellingTable::contain(const char* spelling_str) { 186 | if (NULL == spelling_str || NULL == spelling_buf_ || frozen_) 187 | return false; 188 | 189 | size_t hash_pos = get_hash_pos(spelling_str); 190 | 191 | if ('\0' == raw_spellings_[hash_pos].str[0]) 192 | return false; 193 | 194 | if (strncmp(raw_spellings_[hash_pos].str, spelling_str, spelling_size_ - 1) 195 | == 0) 196 | return true; 197 | 198 | size_t hash_pos_ori = hash_pos; 199 | 200 | while (true) { 201 | hash_pos = hash_pos_next(hash_pos); 202 | if (hash_pos_ori == hash_pos) 203 | return false; 204 | 205 | if ('\0' == raw_spellings_[hash_pos].str[0]) 206 | return false; 207 | 208 | if (strncmp(raw_spellings_[hash_pos].str, spelling_str, spelling_size_ - 1) 209 | == 0) 210 | return true; 211 | } 212 | 213 | // never reach here 214 | return false; 215 | } 216 | 217 | const char* SpellingTable::arrange(size_t *item_size, size_t *spl_num) { 218 | if (NULL == raw_spellings_ || NULL == spelling_buf_ || 219 | NULL == item_size || NULL == spl_num) 220 | return NULL; 221 | 222 | qsort(raw_spellings_, spelling_max_num_, sizeof(RawSpelling), 223 | compare_raw_spl_eb); 224 | 225 | // After sorting, only the first spelling_num_ items are valid. 226 | // Copy them to the destination buffer. 227 | for (size_t pos = 0; pos < spelling_num_; pos++) { 228 | strncpy(spelling_buf_ + pos * spelling_size_, raw_spellings_[pos].str, 229 | spelling_size_); 230 | } 231 | 232 | if (need_score_) { 233 | if (kPrintDebug0) 234 | printf("------------Spelling Possiblities--------------\n"); 235 | 236 | double max_score = 0; 237 | double min_score = 0; 238 | 239 | // After sorting, only the first spelling_num_ items are valid. 240 | for (size_t pos = 0; pos < spelling_num_; pos++) { 241 | raw_spellings_[pos].freq /= total_freq_; 242 | if (need_score_) { 243 | if (0 == pos) { 244 | max_score = raw_spellings_[0].freq; 245 | min_score = max_score; 246 | } else { 247 | if (raw_spellings_[pos].freq > max_score) 248 | max_score = raw_spellings_[pos].freq; 249 | if (raw_spellings_[pos].freq < min_score) 250 | min_score = raw_spellings_[pos].freq; 251 | } 252 | } 253 | } 254 | 255 | if (kPrintDebug0) 256 | printf("-----max psb: %f, min psb: %f\n", max_score, min_score); 257 | 258 | max_score = log(max_score); 259 | min_score = log(min_score); 260 | 261 | if (kPrintDebug0) 262 | printf("-----max log value: %f, min log value: %f\n", 263 | max_score, min_score); 264 | 265 | // The absolute value of min_score is bigger than that of max_score because 266 | // both of them are negative after log function. 267 | score_amplifier_ = 1.0 * 255 / min_score; 268 | 269 | double average_score = 0; 270 | for (size_t pos = 0; pos < spelling_num_; pos++) { 271 | double score = log(raw_spellings_[pos].freq) * score_amplifier_; 272 | assert(score >= 0); 273 | 274 | average_score += score; 275 | 276 | // Because of calculation precision issue, score might be a little bigger 277 | // than 255 after being amplified. 278 | if (score > 255) 279 | score = 255; 280 | char *this_spl_buf = spelling_buf_ + pos * spelling_size_; 281 | this_spl_buf[spelling_size_ - 1] = 282 | static_cast((unsigned char)score); 283 | 284 | if (kPrintDebug0) { 285 | printf("---pos:%d, %s, psb:%d\n", pos, this_spl_buf, 286 | (unsigned char)this_spl_buf[spelling_size_ -1]); 287 | } 288 | } 289 | average_score /= spelling_num_; 290 | assert(average_score <= 255); 291 | average_score_ = static_cast(average_score); 292 | 293 | if (kPrintDebug0) 294 | printf("\n----Score Amplifier: %f, Average Score: %d\n", score_amplifier_, 295 | average_score_); 296 | } 297 | 298 | *item_size = spelling_size_; 299 | *spl_num = spelling_num_; 300 | frozen_ = true; 301 | return spelling_buf_; 302 | } 303 | 304 | float SpellingTable::get_score_amplifier() { 305 | return static_cast(score_amplifier_); 306 | } 307 | 308 | unsigned char SpellingTable::get_average_score() { 309 | return average_score_; 310 | } 311 | 312 | #endif // ___BUILD_MODEL___ 313 | } // namespace ime_pinyin 314 | -------------------------------------------------------------------------------- /jni/share/sync.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "../include/sync.h" 18 | #include 19 | #include 20 | 21 | #ifdef ___SYNC_ENABLED___ 22 | 23 | namespace ime_pinyin { 24 | 25 | Sync::Sync() 26 | : userdict_(NULL), 27 | dictfile_(NULL), 28 | last_count_(0) { 29 | }; 30 | 31 | Sync::~Sync() { 32 | } 33 | 34 | 35 | bool Sync::begin(const char * filename) { 36 | if (userdict_) { 37 | finish(); 38 | } 39 | 40 | if (!filename) { 41 | return false; 42 | } 43 | 44 | dictfile_ = strdup(filename); 45 | if (!dictfile_) { 46 | return false; 47 | } 48 | 49 | userdict_ = new UserDict(); 50 | if (!userdict_) { 51 | free(dictfile_); 52 | dictfile_ = NULL; 53 | return false; 54 | } 55 | 56 | if (userdict_->load_dict((const char*)dictfile_, kUserDictIdStart, 57 | kUserDictIdEnd) == false) { 58 | delete userdict_; 59 | userdict_ = NULL; 60 | free(dictfile_); 61 | dictfile_ = NULL; 62 | return false; 63 | } 64 | 65 | userdict_->set_limit(kUserDictMaxLemmaCount, kUserDictMaxLemmaSize, kUserDictRatio); 66 | 67 | return true; 68 | } 69 | 70 | int Sync::put_lemmas(char16 * lemmas, int len) { 71 | return userdict_->put_lemmas_no_sync_from_utf16le_string(lemmas, len); 72 | } 73 | 74 | int Sync::get_lemmas(char16 * str, int size) { 75 | return userdict_->get_sync_lemmas_in_utf16le_string_from_beginning(str, size, &last_count_); 76 | } 77 | 78 | int Sync::get_last_got_count() { 79 | return last_count_; 80 | } 81 | 82 | int Sync::get_total_count() { 83 | return userdict_->get_sync_count(); 84 | } 85 | 86 | void Sync::clear_last_got() { 87 | if (last_count_ < 0) { 88 | return; 89 | } 90 | userdict_->clear_sync_lemmas(0, last_count_); 91 | last_count_ = 0; 92 | } 93 | 94 | void Sync::finish() { 95 | if (userdict_) { 96 | userdict_->close_dict(); 97 | delete userdict_; 98 | userdict_ = NULL; 99 | free(dictfile_); 100 | dictfile_ = NULL; 101 | last_count_ = 0; 102 | } 103 | } 104 | 105 | int Sync::get_capacity() { 106 | UserDict::UserDictStat stat; 107 | userdict_->state(&stat); 108 | return stat.limit_lemma_count - stat.lemma_count; 109 | } 110 | 111 | } 112 | #endif 113 | -------------------------------------------------------------------------------- /jni/share/utf16char.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include "../include/utf16char.h" 19 | 20 | namespace ime_pinyin { 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | char16* utf16_strtok(char16 *utf16_str, size_t *token_size, 27 | char16 **utf16_str_next) { 28 | if (NULL == utf16_str || NULL == token_size || NULL == utf16_str_next) { 29 | return NULL; 30 | } 31 | 32 | // Skip the splitters 33 | size_t pos = 0; 34 | while ((char16)' ' == utf16_str[pos] || (char16)'\n' == utf16_str[pos] 35 | || (char16)'\t' == utf16_str[pos]) 36 | pos++; 37 | 38 | utf16_str += pos; 39 | pos = 0; 40 | 41 | while ((char16)'\0' != utf16_str[pos] && (char16)' ' != utf16_str[pos] 42 | && (char16)'\n' != utf16_str[pos] 43 | && (char16)'\t' != utf16_str[pos]) { 44 | pos++; 45 | } 46 | 47 | char16 *ret_val = utf16_str; 48 | if ((char16)'\0' == utf16_str[pos]) { 49 | *utf16_str_next = NULL; 50 | if (0 == pos) 51 | return NULL; 52 | } else { 53 | *utf16_str_next = utf16_str + pos + 1; 54 | } 55 | 56 | utf16_str[pos] = (char16)'\0'; 57 | *token_size = pos; 58 | 59 | return ret_val; 60 | } 61 | 62 | int utf16_atoi(const char16 *utf16_str) { 63 | if (NULL == utf16_str) 64 | return 0; 65 | 66 | int value = 0; 67 | int sign = 1; 68 | size_t pos = 0; 69 | 70 | if ((char16)'-' == utf16_str[pos]) { 71 | sign = -1; 72 | pos++; 73 | } 74 | 75 | while ((char16)'0' <= utf16_str[pos] && 76 | (char16)'9' >= utf16_str[pos]) { 77 | value = value * 10 + static_cast(utf16_str[pos] - (char16)'0'); 78 | pos++; 79 | } 80 | 81 | return value*sign; 82 | } 83 | 84 | float utf16_atof(const char16 *utf16_str) { 85 | // A temporary implemetation. 86 | char char8[256]; 87 | if (utf16_strlen(utf16_str) >= 256) return 0; 88 | 89 | utf16_strcpy_tochar(char8, utf16_str); 90 | return atof(char8); 91 | } 92 | 93 | size_t utf16_strlen(const char16 *utf16_str) { 94 | if (NULL == utf16_str) 95 | return 0; 96 | 97 | size_t size = 0; 98 | while ((char16)'\0' != utf16_str[size]) 99 | size++; 100 | return size; 101 | } 102 | 103 | int utf16_strcmp(const char16* str1, const char16* str2) { 104 | size_t pos = 0; 105 | while (str1[pos] == str2[pos] && (char16)'\0' != str1[pos]) 106 | pos++; 107 | 108 | return static_cast(str1[pos]) - static_cast(str2[pos]); 109 | } 110 | 111 | int utf16_strncmp(const char16 *str1, const char16 *str2, size_t size) { 112 | size_t pos = 0; 113 | while (pos < size && str1[pos] == str2[pos] && (char16)'\0' != str1[pos]) 114 | pos++; 115 | 116 | if (pos == size) 117 | return 0; 118 | 119 | return static_cast(str1[pos]) - static_cast(str2[pos]); 120 | } 121 | 122 | // we do not consider overlapping 123 | char16* utf16_strcpy(char16 *dst, const char16 *src) { 124 | if (NULL == src || NULL == dst) 125 | return NULL; 126 | 127 | char16* cp = dst; 128 | 129 | while ((char16)'\0' != *src) { 130 | *cp = *src; 131 | cp++; 132 | src++; 133 | } 134 | 135 | *cp = *src; 136 | 137 | return dst; 138 | } 139 | 140 | char16* utf16_strncpy(char16 *dst, const char16 *src, size_t size) { 141 | if (NULL == src || NULL == dst || 0 == size) 142 | return NULL; 143 | 144 | if (src == dst) 145 | return dst; 146 | 147 | char16* cp = dst; 148 | 149 | if (dst < src || (dst > src && dst >= src + size)) { 150 | while (size-- && (*cp++ = *src++)) 151 | ; 152 | } else { 153 | cp += size - 1; 154 | src += size - 1; 155 | while (size-- && (*cp-- == *src--)) 156 | ; 157 | } 158 | return dst; 159 | } 160 | 161 | // We do not handle complicated cases like overlapping, because in this 162 | // codebase, it is not necessary. 163 | char* utf16_strcpy_tochar(char *dst, const char16 *src) { 164 | if (NULL == src || NULL == dst) 165 | return NULL; 166 | 167 | char* cp = dst; 168 | 169 | while ((char16)'\0' != *src) { 170 | *cp = static_cast(*src); 171 | cp++; 172 | src++; 173 | } 174 | *cp = *src; 175 | 176 | return dst; 177 | } 178 | 179 | #ifdef __cplusplus 180 | } 181 | #endif 182 | } // namespace ime_pinyin 183 | -------------------------------------------------------------------------------- /jni/share/utf16reader.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "../include/utf16reader.h" 18 | 19 | namespace ime_pinyin { 20 | 21 | #define MIN_BUF_LEN 128 22 | #define MAX_BUF_LEN 65535 23 | 24 | Utf16Reader::Utf16Reader() { 25 | fp_ = NULL; 26 | buffer_ = NULL; 27 | buffer_total_len_ = 0; 28 | buffer_next_pos_ = 0; 29 | buffer_valid_len_ = 0; 30 | } 31 | 32 | Utf16Reader::~Utf16Reader() { 33 | if (NULL != fp_) 34 | fclose(fp_); 35 | 36 | if (NULL != buffer_) 37 | delete [] buffer_; 38 | } 39 | 40 | 41 | bool Utf16Reader::open(const char* filename, size_t buffer_len) { 42 | if (filename == NULL) 43 | return false; 44 | 45 | if (buffer_len < MIN_BUF_LEN) 46 | buffer_len = MIN_BUF_LEN; 47 | else if (buffer_len > MAX_BUF_LEN) 48 | buffer_len = MAX_BUF_LEN; 49 | 50 | buffer_total_len_ = buffer_len; 51 | 52 | if (NULL != buffer_) 53 | delete [] buffer_; 54 | buffer_ = new char16[buffer_total_len_]; 55 | if (NULL == buffer_) 56 | return false; 57 | 58 | if ((fp_ = fopen(filename, "rb")) == NULL) 59 | return false; 60 | 61 | // the UTF16 file header, skip 62 | char16 header; 63 | if (fread(&header, sizeof(header), 1, fp_) != 1 || header != 0xfeff) { 64 | fclose(fp_); 65 | fp_ = NULL; 66 | return false; 67 | } 68 | 69 | return true; 70 | } 71 | 72 | char16* Utf16Reader::readline(char16* read_buf, size_t max_len) { 73 | if (NULL == fp_ || NULL == read_buf || 0 == max_len) 74 | return NULL; 75 | 76 | size_t ret_len = 0; 77 | 78 | do { 79 | if (buffer_valid_len_ == 0) { 80 | buffer_next_pos_ = 0; 81 | buffer_valid_len_ = fread(buffer_, sizeof(char16), 82 | buffer_total_len_, fp_); 83 | if (buffer_valid_len_ == 0) { 84 | if (0 == ret_len) 85 | return NULL; 86 | read_buf[ret_len] = (char16)'\0'; 87 | return read_buf; 88 | } 89 | } 90 | 91 | for (size_t i = 0; i < buffer_valid_len_; i++) { 92 | if (i == max_len - 1 || 93 | buffer_[buffer_next_pos_ + i] == (char16)'\n') { 94 | if (ret_len + i > 0 && read_buf[ret_len + i - 1] == (char16)'\r') { 95 | read_buf[ret_len + i - 1] = (char16)'\0'; 96 | } else { 97 | read_buf[ret_len + i] = (char16)'\0'; 98 | } 99 | 100 | i++; 101 | buffer_next_pos_ += i; 102 | buffer_valid_len_ -= i; 103 | if (buffer_next_pos_ == buffer_total_len_) { 104 | buffer_next_pos_ = 0; 105 | buffer_valid_len_ = 0; 106 | } 107 | return read_buf; 108 | } else { 109 | read_buf[ret_len + i] = buffer_[buffer_next_pos_ + i]; 110 | } 111 | } 112 | 113 | ret_len += buffer_valid_len_; 114 | buffer_valid_len_ = 0; 115 | } while (true); 116 | 117 | // Never reach here 118 | return NULL; 119 | } 120 | 121 | bool Utf16Reader::close() { 122 | if (NULL != fp_) 123 | fclose(fp_); 124 | fp_ = NULL; 125 | 126 | if (NULL != buffer_) 127 | delete [] buffer_; 128 | buffer_ = NULL; 129 | return true; 130 | } 131 | } // namespace ime_pinyin 132 | -------------------------------------------------------------------------------- /lib/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH:= $(call my-dir) 2 | include $(CLEAR_VARS) 3 | 4 | LOCAL_SRC_FILES := \ 5 | $(call all-subdir-java-files) \ 6 | com/android/inputmethod/pinyin/IPinyinDecoderService.aidl 7 | 8 | LOCAL_MODULE := com.android.inputmethod.pinyin.lib 9 | 10 | include $(BUILD_STATIC_JAVA_LIBRARY) 11 | -------------------------------------------------------------------------------- /lib/com/android/inputmethod/pinyin/IPinyinDecoderService.aidl: -------------------------------------------------------------------------------- 1 | /* //com/andriod/inputmethod/pinyin/IPinyinDecoderService.aidl 2 | * Copyright (C) 2009 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | package com.android.inputmethod.pinyin; 19 | 20 | interface IPinyinDecoderService { 21 | int getInt(); 22 | void setMaxLens(int maxSpsLen, int maxHzsLen); 23 | int imSearch(in byte[] pyBuf, int pyLen); 24 | int imDelSearch(int pos, boolean is_pos_in_splid, boolean clear_fixed_this_step); 25 | void imResetSearch(); 26 | int imAddLetter(byte ch); 27 | String imGetPyStr(boolean decoded); 28 | int imGetPyStrLen(boolean decoded); 29 | int[] imGetSplStart(); 30 | String imGetChoice(int choiceId); 31 | String imGetChoices(int choicesNum); 32 | List imGetChoiceList(int choicesStart, int choicesNum, int sentFixedLen); 33 | int imChoose(int choiceId); 34 | int imCancelLastChoice(); 35 | int imGetFixedLen(); 36 | boolean imCancelInput(); 37 | void imFlushCache(); 38 | int imGetPredictsNum(in String fixedStr); 39 | List imGetPredictList(int predictsStart, int predictsNum); 40 | String imGetPredictItem(int predictNo); 41 | 42 | String syncUserDict(in String tomerge); 43 | boolean syncBegin(); 44 | void syncFinish(); 45 | int syncPutLemmas(in String tomerge); 46 | String syncGetLemmas(); 47 | int syncGetLastCount(); 48 | int syncGetTotalCount(); 49 | void syncClearLastGot(); 50 | int imSyncGetCapacity(); 51 | } 52 | -------------------------------------------------------------------------------- /proguard.cfg: -------------------------------------------------------------------------------- 1 | -keep class com.android.inputmethod.pinyin.PinyinDecoderService{ 2 | native static boolean nativeImOpenDecoder(byte[], byte[]); 3 | } 4 | -------------------------------------------------------------------------------- /proguard.flags: -------------------------------------------------------------------------------- 1 | -keep class com.android.inputmethod.pinyin.PinyinDecoderService { 2 | *; 3 | } 4 | -------------------------------------------------------------------------------- /res/drawable/app_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/app_icon.png -------------------------------------------------------------------------------- /res/drawable/arrow_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 19 | 21 | 22 | -------------------------------------------------------------------------------- /res/drawable/arrow_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/arrow_left.png -------------------------------------------------------------------------------- /res/drawable/arrow_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/arrow_right.png -------------------------------------------------------------------------------- /res/drawable/candidate_balloon_bg.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/candidate_balloon_bg.9.png -------------------------------------------------------------------------------- /res/drawable/candidate_hl_bg.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/candidate_hl_bg.9.png -------------------------------------------------------------------------------- /res/drawable/candidates_area_bg.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/candidates_area_bg.9.png -------------------------------------------------------------------------------- /res/drawable/candidates_vertical_line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/candidates_vertical_line.png -------------------------------------------------------------------------------- /res/drawable/cands_container_bg.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/cands_container_bg.9.png -------------------------------------------------------------------------------- /res/drawable/comma_full_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/comma_full_icon.png -------------------------------------------------------------------------------- /res/drawable/comma_full_popup_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/comma_full_popup_icon.png -------------------------------------------------------------------------------- /res/drawable/composing_area_bg.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/composing_area_bg.9.png -------------------------------------------------------------------------------- /res/drawable/composing_area_cursor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/composing_area_cursor.png -------------------------------------------------------------------------------- /res/drawable/composing_hl_bg.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/composing_hl_bg.9.png -------------------------------------------------------------------------------- /res/drawable/delete_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/delete_icon.png -------------------------------------------------------------------------------- /res/drawable/delete_popup_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/delete_popup_icon.png -------------------------------------------------------------------------------- /res/drawable/dun_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/dun_icon.png -------------------------------------------------------------------------------- /res/drawable/dun_popup_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/dun_popup_icon.png -------------------------------------------------------------------------------- /res/drawable/emotion_icon_00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/emotion_icon_00.png -------------------------------------------------------------------------------- /res/drawable/emotion_icon_00_popup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/emotion_icon_00_popup.png -------------------------------------------------------------------------------- /res/drawable/emotion_icon_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/emotion_icon_01.png -------------------------------------------------------------------------------- /res/drawable/emotion_icon_01_popup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/emotion_icon_01_popup.png -------------------------------------------------------------------------------- /res/drawable/emotion_icon_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/emotion_icon_02.png -------------------------------------------------------------------------------- /res/drawable/emotion_icon_02_popup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/emotion_icon_02_popup.png -------------------------------------------------------------------------------- /res/drawable/emotion_icon_03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/emotion_icon_03.png -------------------------------------------------------------------------------- /res/drawable/emotion_icon_03_popup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/emotion_icon_03_popup.png -------------------------------------------------------------------------------- /res/drawable/emotion_icon_04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/emotion_icon_04.png -------------------------------------------------------------------------------- /res/drawable/emotion_icon_04_popup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/emotion_icon_04_popup.png -------------------------------------------------------------------------------- /res/drawable/emotion_icon_05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/emotion_icon_05.png -------------------------------------------------------------------------------- /res/drawable/emotion_icon_05_popup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/emotion_icon_05_popup.png -------------------------------------------------------------------------------- /res/drawable/emotion_icon_06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/emotion_icon_06.png -------------------------------------------------------------------------------- /res/drawable/emotion_icon_06_popup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/emotion_icon_06_popup.png -------------------------------------------------------------------------------- /res/drawable/emotion_icon_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/emotion_icon_10.png -------------------------------------------------------------------------------- /res/drawable/emotion_icon_10_popup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/emotion_icon_10_popup.png -------------------------------------------------------------------------------- /res/drawable/emotion_icon_11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/emotion_icon_11.png -------------------------------------------------------------------------------- /res/drawable/emotion_icon_11_popup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/emotion_icon_11_popup.png -------------------------------------------------------------------------------- /res/drawable/emotion_icon_12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/emotion_icon_12.png -------------------------------------------------------------------------------- /res/drawable/emotion_icon_12_popup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/emotion_icon_12_popup.png -------------------------------------------------------------------------------- /res/drawable/emotion_icon_13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/emotion_icon_13.png -------------------------------------------------------------------------------- /res/drawable/emotion_icon_13_popup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/emotion_icon_13_popup.png -------------------------------------------------------------------------------- /res/drawable/emotion_icon_14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/emotion_icon_14.png -------------------------------------------------------------------------------- /res/drawable/emotion_icon_14_popup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/emotion_icon_14_popup.png -------------------------------------------------------------------------------- /res/drawable/emotion_icon_15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/emotion_icon_15.png -------------------------------------------------------------------------------- /res/drawable/emotion_icon_15_popup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/emotion_icon_15_popup.png -------------------------------------------------------------------------------- /res/drawable/emotion_icon_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/emotion_icon_16.png -------------------------------------------------------------------------------- /res/drawable/emotion_icon_16_popup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/emotion_icon_16_popup.png -------------------------------------------------------------------------------- /res/drawable/emotion_icon_20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/emotion_icon_20.png -------------------------------------------------------------------------------- /res/drawable/emotion_icon_20_popup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/emotion_icon_20_popup.png -------------------------------------------------------------------------------- /res/drawable/emotion_icon_21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/emotion_icon_21.png -------------------------------------------------------------------------------- /res/drawable/emotion_icon_21_popup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/emotion_icon_21_popup.png -------------------------------------------------------------------------------- /res/drawable/emotion_icon_22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/emotion_icon_22.png -------------------------------------------------------------------------------- /res/drawable/emotion_icon_22_popup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/emotion_icon_22_popup.png -------------------------------------------------------------------------------- /res/drawable/emotion_icon_23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/emotion_icon_23.png -------------------------------------------------------------------------------- /res/drawable/emotion_icon_23_popup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/emotion_icon_23_popup.png -------------------------------------------------------------------------------- /res/drawable/emotion_icon_24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/emotion_icon_24.png -------------------------------------------------------------------------------- /res/drawable/emotion_icon_24_popup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/emotion_icon_24_popup.png -------------------------------------------------------------------------------- /res/drawable/enter_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/enter_icon.png -------------------------------------------------------------------------------- /res/drawable/enter_popup_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/enter_popup_icon.png -------------------------------------------------------------------------------- /res/drawable/ime_en.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/ime_en.png -------------------------------------------------------------------------------- /res/drawable/ime_pinyin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/ime_pinyin.png -------------------------------------------------------------------------------- /res/drawable/key_balloon_bg.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/key_balloon_bg.9.png -------------------------------------------------------------------------------- /res/drawable/light_key_bg.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/light_key_bg.9.png -------------------------------------------------------------------------------- /res/drawable/light_key_hl_bg.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/light_key_hl_bg.9.png -------------------------------------------------------------------------------- /res/drawable/light_key_up_bg.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/light_key_up_bg.9.png -------------------------------------------------------------------------------- /res/drawable/light_key_up_hl_bg.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/light_key_up_hl_bg.9.png -------------------------------------------------------------------------------- /res/drawable/miniskb_bg.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/miniskb_bg.9.png -------------------------------------------------------------------------------- /res/drawable/normal_key_bg.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/normal_key_bg.9.png -------------------------------------------------------------------------------- /res/drawable/normal_key_hl_bg.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/normal_key_hl_bg.9.png -------------------------------------------------------------------------------- /res/drawable/num0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/num0.png -------------------------------------------------------------------------------- /res/drawable/num1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/num1.png -------------------------------------------------------------------------------- /res/drawable/num2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/num2.png -------------------------------------------------------------------------------- /res/drawable/num3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/num3.png -------------------------------------------------------------------------------- /res/drawable/num4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/num4.png -------------------------------------------------------------------------------- /res/drawable/num5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/num5.png -------------------------------------------------------------------------------- /res/drawable/num6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/num6.png -------------------------------------------------------------------------------- /res/drawable/num7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/num7.png -------------------------------------------------------------------------------- /res/drawable/num8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/num8.png -------------------------------------------------------------------------------- /res/drawable/num9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/num9.png -------------------------------------------------------------------------------- /res/drawable/numalt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/numalt.png -------------------------------------------------------------------------------- /res/drawable/numpound.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/numpound.png -------------------------------------------------------------------------------- /res/drawable/numstar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/numstar.png -------------------------------------------------------------------------------- /res/drawable/period_full_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/period_full_icon.png -------------------------------------------------------------------------------- /res/drawable/period_full_popup_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/period_full_popup_icon.png -------------------------------------------------------------------------------- /res/drawable/period_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/period_icon.png -------------------------------------------------------------------------------- /res/drawable/period_popup_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/period_popup_icon.png -------------------------------------------------------------------------------- /res/drawable/search_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/search_icon.png -------------------------------------------------------------------------------- /res/drawable/search_popup_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/search_popup_icon.png -------------------------------------------------------------------------------- /res/drawable/shift_off_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/shift_off_icon.png -------------------------------------------------------------------------------- /res/drawable/shift_off_popup_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/shift_off_popup_icon.png -------------------------------------------------------------------------------- /res/drawable/shift_on_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/shift_on_icon.png -------------------------------------------------------------------------------- /res/drawable/shift_on_popup_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/shift_on_popup_icon.png -------------------------------------------------------------------------------- /res/drawable/skb_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/skb_bg.png -------------------------------------------------------------------------------- /res/drawable/skb_container_bg.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/skb_container_bg.9.png -------------------------------------------------------------------------------- /res/drawable/smiley_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/smiley_icon.png -------------------------------------------------------------------------------- /res/drawable/smiley_popup_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/smiley_popup_icon.png -------------------------------------------------------------------------------- /res/drawable/space_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/space_icon.png -------------------------------------------------------------------------------- /res/drawable/space_popup_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/drawable/space_popup_icon.png -------------------------------------------------------------------------------- /res/layout/candidates_container.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 22 | 23 | 30 | 31 | 38 | 39 | 44 | 48 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /res/layout/floating_container.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 21 | 22 | 27 | 28 | -------------------------------------------------------------------------------- /res/layout/skb_container.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 21 | 22 | 27 | 28 | 32 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /res/raw/dict_pinyin.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyanogenMod/android_packages_inputmethods_PinyinIME/1702573e564ed55257d7473b4e75edd19d53ad12/res/raw/dict_pinyin.dat -------------------------------------------------------------------------------- /res/values-land/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 10dip 18 | 16dip 19 | 20 | -------------------------------------------------------------------------------- /res/values-port/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 3dip 18 | 18dip 19 | 20 | -------------------------------------------------------------------------------- /res/values-zh/bools.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | true 18 | 19 | -------------------------------------------------------------------------------- /res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | #ffffffff 18 | #ffffffff 19 | #ff000000 20 | #ff000000 21 | #ff000000 22 | #ffe35900 23 | #ff343233 24 | #ff000000 25 | #ffffffff 26 | #ff777777 27 | 28 | -------------------------------------------------------------------------------- /res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 0dip 18 | 19 | -------------------------------------------------------------------------------- /res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 谷歌拼音输入法 18 | 谷歌拼音输入法设置 19 | 20 | 1.0.0 21 | 22 | 23 | 0 24 | 1 25 | 2 26 | 3 27 | 4 28 | 5 29 | 6 30 | 7 31 | 8 32 | 9 33 | 10 34 | 11 35 | 12 36 | 13 37 | 14 38 | 15 39 | 3 40 | 41 | 42 | setting_sound_key 43 | setting_vibrate_key 44 | setting_prediction_key 45 | setting_switch_key 46 | setting_advanced_key 47 | 48 | 谷歌拼音输入法设置 49 | 按键声音 50 | 按键震动 51 | 联想输入 52 | 中英文切换 53 | Shift-space 54 | 55 | 开启 56 | 关闭 57 | 58 | 其它设置 59 | 词典同步等 60 | 61 | 62 | -------------------------------------------------------------------------------- /res/xml/method.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | 22 | -------------------------------------------------------------------------------- /res/xml/settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 18 | 19 | 25 | 26 | 32 | 33 | 39 | 40 | 41 | 45 | 46 | 47 | 48 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /res/xml/skb_phone.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | icon="@drawable/numpound"/> 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /res/xml/skb_qwerty.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 26 | 27 | 28 | 30 | 31 | 32 | 33 | 35 | 36 | 37 | 38 | 40 | 43 | 46 | 49 | 51 | 52 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /res/xml/skb_smiley.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 25 | 26 | 27 | 29 | 31 | 33 | 35 | 37 | 39 | 41 | 42 | 43 | 44 | 46 | 48 | 50 | 52 | 54 | 56 | 58 | 59 | 60 | 61 | 63 | 65 | 67 | 69 | 71 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /res/xml/skb_sym1.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 24 | 25 | 26 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 80 | 82 | 84 | 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /res/xml/skb_sym2.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /res/xml/skb_template1.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 25 | 26 | 31 | 32 | 33 | 37 | 38 | 39 | 43 | 44 | 45 | 49 | 50 | 51 | 53 | 54 | 55 | 60 | 61 | 62 | 64 | 65 | 66 | 68 | 69 | 70 | 72 | 73 | 74 | 75 | 77 | 78 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 88 | 89 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 100 | 101 | 102 | 104 | 105 | 106 | 108 | 109 | 110 | 113 | 114 | 115 | 116 | 117 | 118 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /src/com/android/inputmethod/pinyin/CandidateViewListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.inputmethod.pinyin; 18 | 19 | /** 20 | * Interface to notify the input method when the user clicks a candidate or 21 | * makes a direction-gesture on candidate view. 22 | */ 23 | public interface CandidateViewListener { 24 | public void onClickChoice(int choiceId); 25 | 26 | public void onToLeftGesture(); 27 | 28 | public void onToRightGesture(); 29 | 30 | public void onToTopGesture(); 31 | 32 | public void onToBottomGesture(); 33 | } 34 | -------------------------------------------------------------------------------- /src/com/android/inputmethod/pinyin/EnglishInputProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.inputmethod.pinyin; 18 | 19 | import android.view.KeyEvent; 20 | import android.view.inputmethod.InputConnection; 21 | 22 | /** 23 | * Class to handle English input. 24 | */ 25 | public class EnglishInputProcessor { 26 | 27 | private int mLastKeyCode = KeyEvent.KEYCODE_UNKNOWN; 28 | 29 | public boolean processKey(InputConnection inputContext, KeyEvent event, 30 | boolean upperCase, boolean realAction) { 31 | if (null == inputContext || null == event) return false; 32 | 33 | int keyCode = event.getKeyCode(); 34 | 35 | CharSequence prefix = null; 36 | prefix = inputContext.getTextBeforeCursor(2, 0); 37 | 38 | int keyChar; 39 | keyChar = 0; 40 | if (keyCode >= KeyEvent.KEYCODE_A && keyCode <= KeyEvent.KEYCODE_Z) { 41 | keyChar = keyCode - KeyEvent.KEYCODE_A + 'a'; 42 | if (upperCase) { 43 | keyChar = keyChar + 'A' - 'a'; 44 | } 45 | } else if (keyCode >= KeyEvent.KEYCODE_0 46 | && keyCode <= KeyEvent.KEYCODE_9) 47 | keyChar = keyCode - KeyEvent.KEYCODE_0 + '0'; 48 | else if (keyCode == KeyEvent.KEYCODE_COMMA) 49 | keyChar = ','; 50 | else if (keyCode == KeyEvent.KEYCODE_PERIOD) 51 | keyChar = '.'; 52 | else if (keyCode == KeyEvent.KEYCODE_APOSTROPHE) 53 | keyChar = '\''; 54 | else if (keyCode == KeyEvent.KEYCODE_AT) 55 | keyChar = '@'; 56 | else if (keyCode == KeyEvent.KEYCODE_SLASH) keyChar = '/'; 57 | 58 | if (0 == keyChar) { 59 | mLastKeyCode = keyCode; 60 | 61 | String insert = null; 62 | if (KeyEvent.KEYCODE_DEL == keyCode) { 63 | if (realAction) { 64 | inputContext.deleteSurroundingText(1, 0); 65 | } 66 | } else if (KeyEvent.KEYCODE_ENTER == keyCode) { 67 | insert = "\n"; 68 | } else if (KeyEvent.KEYCODE_SPACE == keyCode) { 69 | insert = " "; 70 | } else { 71 | return false; 72 | } 73 | 74 | if (null != insert && realAction) 75 | inputContext.commitText(insert, insert.length()); 76 | 77 | return true; 78 | } 79 | 80 | if (!realAction) 81 | return true; 82 | 83 | if (KeyEvent.KEYCODE_SHIFT_LEFT == mLastKeyCode 84 | || KeyEvent.KEYCODE_SHIFT_LEFT == mLastKeyCode) { 85 | if (keyChar >= 'a' && keyChar <= 'z') 86 | keyChar = keyChar - 'a' + 'A'; 87 | } else if (KeyEvent.KEYCODE_ALT_LEFT == mLastKeyCode) { 88 | } 89 | 90 | String result = String.valueOf((char) keyChar); 91 | inputContext.commitText(result, result.length()); 92 | mLastKeyCode = keyCode; 93 | return true; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/com/android/inputmethod/pinyin/Environment.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.inputmethod.pinyin; 18 | 19 | import android.content.Context; 20 | import android.content.res.Configuration; 21 | import android.view.Display; 22 | import android.view.WindowManager; 23 | 24 | /** 25 | * Global environment configurations for showing soft keyboard and candidate 26 | * view. All original dimension values are defined in float, and the real size 27 | * is calculated from the float values of and screen size. In this way, this 28 | * input method can work even when screen size is changed. 29 | */ 30 | public class Environment { 31 | /** 32 | * The key height for portrait mode. It is relative to the screen height. 33 | */ 34 | private static final float KEY_HEIGHT_RATIO_PORTRAIT = 0.105f; 35 | 36 | /** 37 | * The key height for landscape mode. It is relative to the screen height. 38 | */ 39 | private static final float KEY_HEIGHT_RATIO_LANDSCAPE = 0.147f; 40 | 41 | /** 42 | * The height of the candidates area for portrait mode. It is relative to 43 | * screen height. 44 | */ 45 | private static final float CANDIDATES_AREA_HEIGHT_RATIO_PORTRAIT = 0.084f; 46 | 47 | /** 48 | * The height of the candidates area for portrait mode. It is relative to 49 | * screen height. 50 | */ 51 | private static final float CANDIDATES_AREA_HEIGHT_RATIO_LANDSCAPE = 0.125f; 52 | 53 | /** 54 | * How much should the balloon width be larger than width of the real key. 55 | * It is relative to the smaller one of screen width and height. 56 | */ 57 | private static final float KEY_BALLOON_WIDTH_PLUS_RATIO = 0.08f; 58 | 59 | /** 60 | * How much should the balloon height be larger than that of the real key. 61 | * It is relative to the smaller one of screen width and height. 62 | */ 63 | private static final float KEY_BALLOON_HEIGHT_PLUS_RATIO = 0.07f; 64 | 65 | /** 66 | * The text size for normal keys. It is relative to the smaller one of 67 | * screen width and height. 68 | */ 69 | private static final float NORMAL_KEY_TEXT_SIZE_RATIO = 0.075f; 70 | 71 | /** 72 | * The text size for function keys. It is relative to the smaller one of 73 | * screen width and height. 74 | */ 75 | private static final float FUNCTION_KEY_TEXT_SIZE_RATIO = 0.055f; 76 | 77 | /** 78 | * The text size balloons of normal keys. It is relative to the smaller one 79 | * of screen width and height. 80 | */ 81 | private static final float NORMAL_BALLOON_TEXT_SIZE_RATIO = 0.14f; 82 | 83 | /** 84 | * The text size balloons of function keys. It is relative to the smaller 85 | * one of screen width and height. 86 | */ 87 | private static final float FUNCTION_BALLOON_TEXT_SIZE_RATIO = 0.085f; 88 | 89 | /** 90 | * The configurations are managed in a singleton. 91 | */ 92 | private static Environment mInstance; 93 | 94 | private int mScreenWidth; 95 | private int mScreenHeight; 96 | private int mKeyHeight; 97 | private int mCandidatesAreaHeight; 98 | private int mKeyBalloonWidthPlus; 99 | private int mKeyBalloonHeightPlus; 100 | private int mNormalKeyTextSize; 101 | private int mFunctionKeyTextSize; 102 | private int mNormalBalloonTextSize; 103 | private int mFunctionBalloonTextSize; 104 | private Configuration mConfig = new Configuration(); 105 | private boolean mDebug = false; 106 | 107 | private Environment() { 108 | } 109 | 110 | public static Environment getInstance() { 111 | if (null == mInstance) { 112 | mInstance = new Environment(); 113 | } 114 | return mInstance; 115 | } 116 | 117 | public void onConfigurationChanged(Configuration newConfig, Context context) { 118 | if (mConfig.orientation != newConfig.orientation) { 119 | WindowManager wm = (WindowManager) context 120 | .getSystemService(Context.WINDOW_SERVICE); 121 | Display d = wm.getDefaultDisplay(); 122 | mScreenWidth = d.getWidth(); 123 | mScreenHeight = d.getHeight(); 124 | 125 | int scale; 126 | if (mScreenHeight > mScreenWidth) { 127 | mKeyHeight = (int) (mScreenHeight * KEY_HEIGHT_RATIO_PORTRAIT); 128 | mCandidatesAreaHeight = (int) (mScreenHeight * CANDIDATES_AREA_HEIGHT_RATIO_PORTRAIT); 129 | scale = mScreenWidth; 130 | } else { 131 | mKeyHeight = (int) (mScreenHeight * KEY_HEIGHT_RATIO_LANDSCAPE); 132 | mCandidatesAreaHeight = (int) (mScreenHeight * CANDIDATES_AREA_HEIGHT_RATIO_LANDSCAPE); 133 | scale = mScreenHeight; 134 | } 135 | mNormalKeyTextSize = (int) (scale * NORMAL_KEY_TEXT_SIZE_RATIO); 136 | mFunctionKeyTextSize = (int) (scale * FUNCTION_KEY_TEXT_SIZE_RATIO); 137 | mNormalBalloonTextSize = (int) (scale * NORMAL_BALLOON_TEXT_SIZE_RATIO); 138 | mFunctionBalloonTextSize = (int) (scale * FUNCTION_BALLOON_TEXT_SIZE_RATIO); 139 | mKeyBalloonWidthPlus = (int) (scale * KEY_BALLOON_WIDTH_PLUS_RATIO); 140 | mKeyBalloonHeightPlus = (int) (scale * KEY_BALLOON_HEIGHT_PLUS_RATIO); 141 | } 142 | 143 | mConfig.updateFrom(newConfig); 144 | } 145 | 146 | public Configuration getConfiguration() { 147 | return mConfig; 148 | } 149 | 150 | public int getScreenWidth() { 151 | return mScreenWidth; 152 | } 153 | 154 | public int getScreenHeight() { 155 | return mScreenHeight; 156 | } 157 | 158 | public int getHeightForCandidates() { 159 | return mCandidatesAreaHeight; 160 | } 161 | 162 | public float getKeyXMarginFactor() { 163 | return 1.0f; 164 | } 165 | 166 | public float getKeyYMarginFactor() { 167 | if (Configuration.ORIENTATION_LANDSCAPE == mConfig.orientation) { 168 | return 0.7f; 169 | } 170 | return 1.0f; 171 | } 172 | 173 | public int getKeyHeight() { 174 | return mKeyHeight; 175 | } 176 | 177 | public int getKeyBalloonWidthPlus() { 178 | return mKeyBalloonWidthPlus; 179 | } 180 | 181 | public int getKeyBalloonHeightPlus() { 182 | return mKeyBalloonHeightPlus; 183 | } 184 | 185 | public int getSkbHeight() { 186 | if (Configuration.ORIENTATION_PORTRAIT == mConfig.orientation) { 187 | return mKeyHeight * 4; 188 | } else if (Configuration.ORIENTATION_LANDSCAPE == mConfig.orientation) { 189 | return mKeyHeight * 4; 190 | } 191 | return 0; 192 | } 193 | 194 | public int getKeyTextSize(boolean isFunctionKey) { 195 | if (isFunctionKey) { 196 | return mFunctionKeyTextSize; 197 | } else { 198 | return mNormalKeyTextSize; 199 | } 200 | } 201 | 202 | public int getBalloonTextSize(boolean isFunctionKey) { 203 | if (isFunctionKey) { 204 | return mFunctionBalloonTextSize; 205 | } else { 206 | return mNormalBalloonTextSize; 207 | } 208 | } 209 | 210 | public boolean hasHardKeyboard() { 211 | if (mConfig.keyboard == Configuration.KEYBOARD_NOKEYS 212 | || mConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_YES) { 213 | return false; 214 | } 215 | return true; 216 | } 217 | 218 | public boolean needDebug() { 219 | return mDebug; 220 | } 221 | } 222 | -------------------------------------------------------------------------------- /src/com/android/inputmethod/pinyin/KeyMapDream.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.inputmethod.pinyin; 18 | 19 | import android.view.KeyEvent; 20 | 21 | /** 22 | * Class used to map the symbols on Dream's hardware keyboard to corresponding 23 | * Chinese full-width symbols. 24 | */ 25 | public class KeyMapDream { 26 | // Number of shift bits to store full-width symbols 27 | private static final int SHIFT_FWCH = 8; 28 | private static final int[] mKeyMap = { 29 | KeyEvent.KEYCODE_UNKNOWN, 30 | KeyEvent.KEYCODE_SOFT_LEFT, 31 | KeyEvent.KEYCODE_SOFT_RIGHT, 32 | KeyEvent.KEYCODE_HOME, 33 | KeyEvent.KEYCODE_BACK, 34 | KeyEvent.KEYCODE_CALL, 35 | KeyEvent.KEYCODE_ENDCALL, 36 | KeyEvent.KEYCODE_0 | ('\uff09' << SHIFT_FWCH), // ) 37 | KeyEvent.KEYCODE_1 | ('\uff01' << SHIFT_FWCH), // ! 38 | KeyEvent.KEYCODE_2 | ('\uff20' << SHIFT_FWCH), // @ 39 | KeyEvent.KEYCODE_3 | ('\uff03' << SHIFT_FWCH), // # 40 | KeyEvent.KEYCODE_4 | ('\uffe5' << SHIFT_FWCH), // $ - fullwidth Yuan 41 | KeyEvent.KEYCODE_5 | ('\uff05' << SHIFT_FWCH), // % 42 | KeyEvent.KEYCODE_6 | ('\u2026' << SHIFT_FWCH), // ^ - Apostrophe 43 | KeyEvent.KEYCODE_7 | ('\uff06' << SHIFT_FWCH), // & 44 | KeyEvent.KEYCODE_8 | ('\uff0a' << SHIFT_FWCH), // * 45 | KeyEvent.KEYCODE_9 | ('\uff08' << SHIFT_FWCH), // ( 46 | KeyEvent.KEYCODE_STAR, 47 | KeyEvent.KEYCODE_POUND, 48 | KeyEvent.KEYCODE_DPAD_UP, 49 | KeyEvent.KEYCODE_DPAD_DOWN, 50 | KeyEvent.KEYCODE_DPAD_LEFT, 51 | KeyEvent.KEYCODE_DPAD_RIGHT, 52 | KeyEvent.KEYCODE_DPAD_CENTER, 53 | KeyEvent.KEYCODE_VOLUME_UP, 54 | KeyEvent.KEYCODE_VOLUME_DOWN, 55 | KeyEvent.KEYCODE_POWER, 56 | KeyEvent.KEYCODE_CAMERA, 57 | KeyEvent.KEYCODE_CLEAR, 58 | KeyEvent.KEYCODE_A, 59 | KeyEvent.KEYCODE_B | ('\uff3d' << SHIFT_FWCH), // ] 60 | KeyEvent.KEYCODE_C | ('\u00a9' << SHIFT_FWCH), // copyright 61 | KeyEvent.KEYCODE_D | ('\u3001' << SHIFT_FWCH), // \\ 62 | KeyEvent.KEYCODE_E | ('_' << SHIFT_FWCH), // _ 63 | KeyEvent.KEYCODE_F | ('\uff5b' << SHIFT_FWCH), // { 64 | KeyEvent.KEYCODE_G | ('\uff5d' << SHIFT_FWCH), // } 65 | KeyEvent.KEYCODE_H | ('\uff1a' << SHIFT_FWCH), // : 66 | KeyEvent.KEYCODE_I | ('\uff0d' << SHIFT_FWCH), // - 67 | KeyEvent.KEYCODE_J | ('\uff1b' << SHIFT_FWCH), // ; 68 | KeyEvent.KEYCODE_K | ('\u201c' << SHIFT_FWCH), // " 69 | KeyEvent.KEYCODE_L | ('\u2019' << SHIFT_FWCH), // ' 70 | KeyEvent.KEYCODE_M | ('\u300b' << SHIFT_FWCH), // > - French quotes 71 | KeyEvent.KEYCODE_N | ('\u300a' << SHIFT_FWCH), // < - French quotes 72 | KeyEvent.KEYCODE_O | ('\uff0b' << SHIFT_FWCH), // + 73 | KeyEvent.KEYCODE_P | ('\uff1d' << SHIFT_FWCH), // = 74 | KeyEvent.KEYCODE_Q | ('\t' << SHIFT_FWCH), // \t 75 | KeyEvent.KEYCODE_R | ('\u00ae' << SHIFT_FWCH), // trademark 76 | KeyEvent.KEYCODE_S | ('\uff5c' << SHIFT_FWCH), // | 77 | KeyEvent.KEYCODE_T | ('\u20ac' << SHIFT_FWCH), // 78 | KeyEvent.KEYCODE_U | ('\u00d7' << SHIFT_FWCH), // multiplier 79 | KeyEvent.KEYCODE_V | ('\uff3b' << SHIFT_FWCH), // [ 80 | KeyEvent.KEYCODE_W | ('\uff40' << SHIFT_FWCH), // ` 81 | KeyEvent.KEYCODE_X, KeyEvent.KEYCODE_Y | ('\u00f7' << SHIFT_FWCH), 82 | KeyEvent.KEYCODE_Z, 83 | KeyEvent.KEYCODE_COMMA | ('\uff1f' << SHIFT_FWCH), 84 | KeyEvent.KEYCODE_PERIOD | ('\uff0f' << SHIFT_FWCH), 85 | KeyEvent.KEYCODE_ALT_LEFT, KeyEvent.KEYCODE_ALT_RIGHT, 86 | KeyEvent.KEYCODE_SHIFT_LEFT, KeyEvent.KEYCODE_SHIFT_RIGHT, 87 | KeyEvent.KEYCODE_TAB, KeyEvent.KEYCODE_SPACE, KeyEvent.KEYCODE_SYM, 88 | KeyEvent.KEYCODE_EXPLORER, KeyEvent.KEYCODE_ENVELOPE, 89 | KeyEvent.KEYCODE_ENTER, KeyEvent.KEYCODE_DEL, 90 | KeyEvent.KEYCODE_GRAVE, KeyEvent.KEYCODE_MINUS, 91 | KeyEvent.KEYCODE_EQUALS, KeyEvent.KEYCODE_LEFT_BRACKET, 92 | KeyEvent.KEYCODE_RIGHT_BRACKET, KeyEvent.KEYCODE_BACKSLASH, 93 | KeyEvent.KEYCODE_SEMICOLON, KeyEvent.KEYCODE_APOSTROPHE, 94 | KeyEvent.KEYCODE_SLASH, 95 | KeyEvent.KEYCODE_AT | ('\uff5e' << SHIFT_FWCH), 96 | KeyEvent.KEYCODE_NUM, KeyEvent.KEYCODE_HEADSETHOOK, 97 | KeyEvent.KEYCODE_FOCUS, KeyEvent.KEYCODE_PLUS, 98 | KeyEvent.KEYCODE_MENU, KeyEvent.KEYCODE_NOTIFICATION, 99 | KeyEvent.KEYCODE_SEARCH,}; 100 | 101 | static public char getChineseLabel(int keyCode) { 102 | if (keyCode <= 0 || keyCode >= KeyEvent.getMaxKeyCode()) return 0; 103 | assert ((mKeyMap[keyCode] & 0x000000ff) == keyCode); 104 | return (char) (mKeyMap[keyCode] >> SHIFT_FWCH); 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/com/android/inputmethod/pinyin/Settings.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.inputmethod.pinyin; 18 | 19 | import android.content.SharedPreferences; 20 | import android.content.SharedPreferences.Editor; 21 | 22 | /** 23 | * Class used to maintain settings. 24 | */ 25 | public class Settings { 26 | private static final String ANDPY_CONFS_KEYSOUND_KEY = "Sound"; 27 | private static final String ANDPY_CONFS_VIBRATE_KEY = "Vibrate"; 28 | private static final String ANDPY_CONFS_PREDICTION_KEY = "Prediction"; 29 | 30 | private static boolean mKeySound; 31 | private static boolean mVibrate; 32 | private static boolean mPrediction; 33 | 34 | private static Settings mInstance = null; 35 | 36 | private static int mRefCount = 0; 37 | 38 | private static SharedPreferences mSharedPref = null; 39 | 40 | protected Settings(SharedPreferences pref) { 41 | mSharedPref = pref; 42 | initConfs(); 43 | } 44 | 45 | public static Settings getInstance(SharedPreferences pref) { 46 | if (mInstance == null) { 47 | mInstance = new Settings(pref); 48 | } 49 | assert (pref == mSharedPref); 50 | mRefCount++; 51 | return mInstance; 52 | } 53 | 54 | public static void writeBack() { 55 | Editor editor = mSharedPref.edit(); 56 | editor.putBoolean(ANDPY_CONFS_VIBRATE_KEY, mVibrate); 57 | editor.putBoolean(ANDPY_CONFS_KEYSOUND_KEY, mKeySound); 58 | editor.putBoolean(ANDPY_CONFS_PREDICTION_KEY, mPrediction); 59 | editor.commit(); 60 | } 61 | 62 | public static void releaseInstance() { 63 | mRefCount--; 64 | if (mRefCount == 0) { 65 | mInstance = null; 66 | } 67 | } 68 | 69 | private void initConfs() { 70 | mKeySound = mSharedPref.getBoolean(ANDPY_CONFS_KEYSOUND_KEY, true); 71 | mVibrate = mSharedPref.getBoolean(ANDPY_CONFS_VIBRATE_KEY, false); 72 | mPrediction = mSharedPref.getBoolean(ANDPY_CONFS_PREDICTION_KEY, true); 73 | } 74 | 75 | public static boolean getKeySound() { 76 | return mKeySound; 77 | } 78 | 79 | public static void setKeySound(boolean v) { 80 | if (mKeySound == v) return; 81 | mKeySound = v; 82 | } 83 | 84 | public static boolean getVibrate() { 85 | return mVibrate; 86 | } 87 | 88 | public static void setVibrate(boolean v) { 89 | if (mVibrate == v) return; 90 | mVibrate = v; 91 | } 92 | 93 | public static boolean getPrediction() { 94 | return mPrediction; 95 | } 96 | 97 | public static void setPrediction(boolean v) { 98 | if (mPrediction == v) return; 99 | mPrediction = v; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/com/android/inputmethod/pinyin/SettingsActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.inputmethod.pinyin; 18 | 19 | import java.util.List; 20 | 21 | import android.os.Bundle; 22 | import android.preference.CheckBoxPreference; 23 | import android.preference.Preference; 24 | import android.preference.PreferenceActivity; 25 | import android.preference.PreferenceGroup; 26 | import android.preference.PreferenceManager; 27 | import android.preference.PreferenceScreen; 28 | import com.android.inputmethod.pinyin.Settings; 29 | import android.content.Intent; 30 | import android.content.pm.PackageManager; 31 | import android.content.pm.ResolveInfo; 32 | 33 | /** 34 | * Setting activity of Pinyin IME. 35 | */ 36 | public class SettingsActivity extends PreferenceActivity implements 37 | Preference.OnPreferenceChangeListener { 38 | 39 | private static String TAG = "SettingsActivity"; 40 | 41 | private CheckBoxPreference mKeySoundPref; 42 | private CheckBoxPreference mVibratePref; 43 | private CheckBoxPreference mPredictionPref; 44 | 45 | @Override 46 | protected void onCreate(Bundle savedInstanceState) { 47 | super.onCreate(savedInstanceState); 48 | addPreferencesFromResource(R.xml.settings); 49 | 50 | PreferenceScreen prefSet = getPreferenceScreen(); 51 | 52 | mKeySoundPref = (CheckBoxPreference) prefSet 53 | .findPreference(getString(R.string.setting_sound_key)); 54 | mVibratePref = (CheckBoxPreference) prefSet 55 | .findPreference(getString(R.string.setting_vibrate_key)); 56 | mPredictionPref = (CheckBoxPreference) prefSet 57 | .findPreference(getString(R.string.setting_prediction_key)); 58 | 59 | prefSet.setOnPreferenceChangeListener(this); 60 | 61 | Settings.getInstance(PreferenceManager 62 | .getDefaultSharedPreferences(getApplicationContext())); 63 | 64 | updatePreference(prefSet, getString(R.string.setting_advanced_key)); 65 | 66 | updateWidgets(); 67 | } 68 | 69 | @Override 70 | protected void onResume() { 71 | super.onResume(); 72 | updateWidgets(); 73 | } 74 | 75 | @Override 76 | protected void onDestroy() { 77 | Settings.releaseInstance(); 78 | super.onDestroy(); 79 | } 80 | 81 | @Override 82 | protected void onPause() { 83 | super.onPause(); 84 | Settings.setKeySound(mKeySoundPref.isChecked()); 85 | Settings.setVibrate(mVibratePref.isChecked()); 86 | Settings.setPrediction(mPredictionPref.isChecked()); 87 | 88 | Settings.writeBack(); 89 | } 90 | 91 | public boolean onPreferenceChange(Preference preference, Object newValue) { 92 | return true; 93 | } 94 | 95 | private void updateWidgets() { 96 | mKeySoundPref.setChecked(Settings.getKeySound()); 97 | mVibratePref.setChecked(Settings.getVibrate()); 98 | mPredictionPref.setChecked(Settings.getPrediction()); 99 | } 100 | 101 | public void updatePreference(PreferenceGroup parentPref, String prefKey) { 102 | Preference preference = parentPref.findPreference(prefKey); 103 | if (preference == null) { 104 | return; 105 | } 106 | Intent intent = preference.getIntent(); 107 | if (intent != null) { 108 | PackageManager pm = getPackageManager(); 109 | List list = pm.queryIntentActivities(intent, 0); 110 | int listSize = list.size(); 111 | if (listSize == 0) 112 | parentPref.removePreference(preference); 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/com/android/inputmethod/pinyin/SkbPool.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.inputmethod.pinyin; 18 | 19 | import java.util.Vector; 20 | 21 | import android.content.Context; 22 | 23 | /** 24 | * Class used to cache previously loaded soft keyboard layouts. 25 | */ 26 | public class SkbPool { 27 | private static SkbPool mInstance = null; 28 | 29 | private Vector mSkbTemplates = new Vector(); 30 | private Vector mSoftKeyboards = new Vector(); 31 | 32 | private SkbPool() { 33 | } 34 | 35 | public static SkbPool getInstance() { 36 | if (null == mInstance) mInstance = new SkbPool(); 37 | return mInstance; 38 | } 39 | 40 | public void resetCachedSkb() { 41 | mSoftKeyboards.clear(); 42 | } 43 | 44 | public SkbTemplate getSkbTemplate(int skbTemplateId, Context context) { 45 | for (int i = 0; i < mSkbTemplates.size(); i++) { 46 | SkbTemplate t = mSkbTemplates.elementAt(i); 47 | if (t.getSkbTemplateId() == skbTemplateId) { 48 | return t; 49 | } 50 | } 51 | 52 | if (null != context) { 53 | XmlKeyboardLoader xkbl = new XmlKeyboardLoader(context); 54 | SkbTemplate t = xkbl.loadSkbTemplate(skbTemplateId); 55 | if (null != t) { 56 | mSkbTemplates.add(t); 57 | return t; 58 | } 59 | } 60 | return null; 61 | } 62 | 63 | // Try to find the keyboard in the pool with the cache id. If there is no 64 | // keyboard found, try to load it with the given xml id. 65 | public SoftKeyboard getSoftKeyboard(int skbCacheId, int skbXmlId, 66 | int skbWidth, int skbHeight, Context context) { 67 | for (int i = 0; i < mSoftKeyboards.size(); i++) { 68 | SoftKeyboard skb = mSoftKeyboards.elementAt(i); 69 | if (skb.getCacheId() == skbCacheId && skb.getSkbXmlId() == skbXmlId) { 70 | skb.setSkbCoreSize(skbWidth, skbHeight); 71 | skb.setNewlyLoadedFlag(false); 72 | return skb; 73 | } 74 | } 75 | if (null != context) { 76 | XmlKeyboardLoader xkbl = new XmlKeyboardLoader(context); 77 | SoftKeyboard skb = xkbl.loadKeyboard(skbXmlId, skbWidth, skbHeight); 78 | if (skb != null) { 79 | if (skb.getCacheFlag()) { 80 | skb.setCacheId(skbCacheId); 81 | mSoftKeyboards.add(skb); 82 | } 83 | } 84 | return skb; 85 | } 86 | return null; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/com/android/inputmethod/pinyin/SkbTemplate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.inputmethod.pinyin; 18 | 19 | import android.graphics.drawable.Drawable; 20 | 21 | import java.util.Vector; 22 | 23 | /** 24 | * Key icon definition. It is defined in soft keyboard template. A soft keyboard 25 | * can refer to such an icon in its xml file directly to improve performance. 26 | */ 27 | class KeyIconRecord { 28 | int keyCode; 29 | Drawable icon; 30 | Drawable iconPopup; 31 | } 32 | 33 | 34 | /** 35 | * Default definition for a certain key. It is defined in soft keyboard 36 | * template. A soft keyboard can refer to a default key in its xml file. Nothing 37 | * of the key can be overwritten, including the size. 38 | */ 39 | class KeyRecord { 40 | int keyId; 41 | SoftKey softKey; 42 | } 43 | 44 | 45 | /** 46 | * Soft keyboard template used by soft keyboards to share common resources. In 47 | * this way, memory cost is reduced. 48 | */ 49 | public class SkbTemplate { 50 | private int mSkbTemplateId; 51 | private Drawable mSkbBg; 52 | private Drawable mBalloonBg; 53 | private Drawable mPopupBg; 54 | private float mXMargin = 0; 55 | private float mYMargin = 0; 56 | /** Key type list. */ 57 | private Vector mKeyTypeList = new Vector(); 58 | 59 | /** 60 | * Default key icon list. It is only for keys which do not have popup icons. 61 | */ 62 | private Vector mKeyIconRecords = new Vector(); 63 | 64 | /** 65 | * Default key list. 66 | */ 67 | private Vector mKeyRecords = new Vector(); 68 | 69 | public SkbTemplate(int skbTemplateId) { 70 | mSkbTemplateId = skbTemplateId; 71 | } 72 | 73 | public int getSkbTemplateId() { 74 | return mSkbTemplateId; 75 | } 76 | 77 | public void setBackgrounds(Drawable skbBg, Drawable balloonBg, 78 | Drawable popupBg) { 79 | mSkbBg = skbBg; 80 | mBalloonBg = balloonBg; 81 | mPopupBg = popupBg; 82 | } 83 | 84 | public Drawable getSkbBackground() { 85 | return mSkbBg; 86 | } 87 | 88 | public Drawable getBalloonBackground() { 89 | return mBalloonBg; 90 | } 91 | 92 | public Drawable getPopupBackground() { 93 | return mPopupBg; 94 | } 95 | 96 | public void setMargins(float xMargin, float yMargin) { 97 | mXMargin = xMargin; 98 | mYMargin = yMargin; 99 | } 100 | 101 | public float getXMargin() { 102 | return mXMargin; 103 | } 104 | 105 | public float getYMargin() { 106 | return mYMargin; 107 | } 108 | 109 | public SoftKeyType createKeyType(int id, Drawable bg, Drawable hlBg) { 110 | return new SoftKeyType(id, bg, hlBg); 111 | } 112 | 113 | public boolean addKeyType(SoftKeyType keyType) { 114 | // The newly added item should have the right id. 115 | if (mKeyTypeList.size() != keyType.mKeyTypeId) return false; 116 | mKeyTypeList.add(keyType); 117 | return true; 118 | } 119 | 120 | public SoftKeyType getKeyType(int typeId) { 121 | if (typeId < 0 || typeId > mKeyTypeList.size()) return null; 122 | return mKeyTypeList.elementAt(typeId); 123 | } 124 | 125 | public void addDefaultKeyIcons(int keyCode, Drawable icon, 126 | Drawable iconPopup) { 127 | if (null == icon || null == iconPopup) return; 128 | 129 | KeyIconRecord iconRecord = new KeyIconRecord(); 130 | iconRecord.icon = icon; 131 | iconRecord.iconPopup = iconPopup; 132 | iconRecord.keyCode = keyCode; 133 | 134 | int size = mKeyIconRecords.size(); 135 | int pos = 0; 136 | while (pos < size) { 137 | if (mKeyIconRecords.get(pos).keyCode >= keyCode) break; 138 | pos++; 139 | } 140 | mKeyIconRecords.add(pos, iconRecord); 141 | } 142 | 143 | public Drawable getDefaultKeyIcon(int keyCode) { 144 | int size = mKeyIconRecords.size(); 145 | int pos = 0; 146 | while (pos < size) { 147 | KeyIconRecord iconRecord = mKeyIconRecords.get(pos); 148 | if (iconRecord.keyCode < keyCode) { 149 | pos++; 150 | continue; 151 | } 152 | if (iconRecord.keyCode == keyCode) { 153 | return iconRecord.icon; 154 | } 155 | return null; 156 | } 157 | return null; 158 | } 159 | 160 | public Drawable getDefaultKeyIconPopup(int keyCode) { 161 | int size = mKeyIconRecords.size(); 162 | int pos = 0; 163 | while (pos < size) { 164 | KeyIconRecord iconRecord = mKeyIconRecords.get(pos); 165 | if (iconRecord.keyCode < keyCode) { 166 | pos++; 167 | continue; 168 | } 169 | if (iconRecord.keyCode == keyCode) { 170 | return iconRecord.iconPopup; 171 | } 172 | return null; 173 | } 174 | return null; 175 | } 176 | 177 | public void addDefaultKey(int keyId, SoftKey softKey) { 178 | if (null == softKey) return; 179 | 180 | KeyRecord keyRecord = new KeyRecord(); 181 | keyRecord.keyId = keyId; 182 | keyRecord.softKey = softKey; 183 | 184 | int size = mKeyRecords.size(); 185 | int pos = 0; 186 | while (pos < size) { 187 | if (mKeyRecords.get(pos).keyId >= keyId) break; 188 | pos++; 189 | } 190 | mKeyRecords.add(pos, keyRecord); 191 | } 192 | 193 | public SoftKey getDefaultKey(int keyId) { 194 | int size = mKeyRecords.size(); 195 | int pos = 0; 196 | while (pos < size) { 197 | KeyRecord keyRecord = mKeyRecords.get(pos); 198 | if (keyRecord.keyId < keyId) { 199 | pos++; 200 | continue; 201 | } 202 | if (keyRecord.keyId == keyId) { 203 | return keyRecord.softKey; 204 | } 205 | return null; 206 | } 207 | return null; 208 | } 209 | } 210 | 211 | 212 | class SoftKeyType { 213 | public static final int KEYTYPE_ID_NORMAL_KEY = 0; 214 | 215 | public int mKeyTypeId; 216 | public Drawable mKeyBg; 217 | public Drawable mKeyHlBg; 218 | public int mColor; 219 | public int mColorHl; 220 | public int mColorBalloon; 221 | 222 | SoftKeyType(int id, Drawable bg, Drawable hlBg) { 223 | mKeyTypeId = id; 224 | mKeyBg = bg; 225 | mKeyHlBg = hlBg; 226 | } 227 | 228 | public void setColors(int color, int colorHl, int colorBalloon) { 229 | mColor = color; 230 | mColorHl = colorHl; 231 | mColorBalloon = colorBalloon; 232 | } 233 | } 234 | -------------------------------------------------------------------------------- /src/com/android/inputmethod/pinyin/SoftKey.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.inputmethod.pinyin; 18 | 19 | import android.graphics.drawable.Drawable; 20 | 21 | /** 22 | * Class for soft keys which defined in the keyboard xml file. A soft key can be 23 | * a basic key or a toggling key. 24 | * 25 | * @see com.android.inputmethod.pinyin.SoftKeyToggle 26 | */ 27 | public class SoftKey { 28 | protected static final int KEYMASK_REPEAT = 0x10000000; 29 | protected static final int KEYMASK_BALLOON = 0x20000000; 30 | 31 | /** 32 | * For a finger touch device, after user presses a key, there will be some 33 | * consequent moving events because of the changing in touching pressure. If 34 | * the moving distance in x is within this threshold, the moving events will 35 | * be ignored. 36 | */ 37 | public static final int MAX_MOVE_TOLERANCE_X = 0; 38 | 39 | /** 40 | * For a finger touch device, after user presses a key, there will be some 41 | * consequent moving events because of the changing in touching pressure. If 42 | * the moving distance in y is within this threshold, the moving events will 43 | * be ignored. 44 | */ 45 | public static final int MAX_MOVE_TOLERANCE_Y = 0; 46 | 47 | /** 48 | * Used to indicate the type and attributes of this key. the lowest 8 bits 49 | * should be reserved for SoftkeyToggle. 50 | */ 51 | protected int mKeyMask; 52 | 53 | protected SoftKeyType mKeyType; 54 | 55 | protected Drawable mKeyIcon; 56 | 57 | protected Drawable mKeyIconPopup; 58 | 59 | protected String mKeyLabel; 60 | 61 | protected int mKeyCode; 62 | 63 | /** 64 | * If this value is not 0, this key can be used to popup a sub soft keyboard 65 | * when user presses it for some time. 66 | */ 67 | public int mPopupSkbId; 68 | 69 | public float mLeftF; 70 | public float mRightF; 71 | public float mTopF; 72 | public float mBottomF; 73 | public int mLeft; 74 | public int mRight; 75 | public int mTop; 76 | public int mBottom; 77 | 78 | public void setKeyType(SoftKeyType keyType, Drawable keyIcon, 79 | Drawable keyIconPopup) { 80 | mKeyType = keyType; 81 | mKeyIcon = keyIcon; 82 | mKeyIconPopup = keyIconPopup; 83 | } 84 | 85 | // The caller guarantees that all parameters are in [0, 1] 86 | public void setKeyDimensions(float left, float top, float right, 87 | float bottom) { 88 | mLeftF = left; 89 | mTopF = top; 90 | mRightF = right; 91 | mBottomF = bottom; 92 | } 93 | 94 | public void setKeyAttribute(int keyCode, String label, boolean repeat, 95 | boolean balloon) { 96 | mKeyCode = keyCode; 97 | mKeyLabel = label; 98 | 99 | if (repeat) { 100 | mKeyMask |= KEYMASK_REPEAT; 101 | } else { 102 | mKeyMask &= (~KEYMASK_REPEAT); 103 | } 104 | 105 | if (balloon) { 106 | mKeyMask |= KEYMASK_BALLOON; 107 | } else { 108 | mKeyMask &= (~KEYMASK_BALLOON); 109 | } 110 | } 111 | 112 | public void setPopupSkbId(int popupSkbId) { 113 | mPopupSkbId = popupSkbId; 114 | } 115 | 116 | // Call after setKeyDimensions(). The caller guarantees that the 117 | // keyboard with and height are valid. 118 | public void setSkbCoreSize(int skbWidth, int skbHeight) { 119 | mLeft = (int) (mLeftF * skbWidth); 120 | mRight = (int) (mRightF * skbWidth); 121 | mTop = (int) (mTopF * skbHeight); 122 | mBottom = (int) (mBottomF * skbHeight); 123 | } 124 | 125 | public Drawable getKeyIcon() { 126 | return mKeyIcon; 127 | } 128 | 129 | public Drawable getKeyIconPopup() { 130 | if (null != mKeyIconPopup) { 131 | return mKeyIconPopup; 132 | } 133 | return mKeyIcon; 134 | } 135 | 136 | public int getKeyCode() { 137 | return mKeyCode; 138 | } 139 | 140 | public String getKeyLabel() { 141 | return mKeyLabel; 142 | } 143 | 144 | public void changeCase(boolean upperCase) { 145 | if (null != mKeyLabel) { 146 | if (upperCase) 147 | mKeyLabel = mKeyLabel.toUpperCase(); 148 | else 149 | mKeyLabel = mKeyLabel.toLowerCase(); 150 | } 151 | } 152 | 153 | public Drawable getKeyBg() { 154 | return mKeyType.mKeyBg; 155 | } 156 | 157 | public Drawable getKeyHlBg() { 158 | return mKeyType.mKeyHlBg; 159 | } 160 | 161 | public int getColor() { 162 | return mKeyType.mColor; 163 | } 164 | 165 | public int getColorHl() { 166 | return mKeyType.mColorHl; 167 | } 168 | 169 | public int getColorBalloon() { 170 | return mKeyType.mColorBalloon; 171 | } 172 | 173 | public boolean isKeyCodeKey() { 174 | if (mKeyCode > 0) return true; 175 | return false; 176 | } 177 | 178 | public boolean isUserDefKey() { 179 | if (mKeyCode < 0) return true; 180 | return false; 181 | } 182 | 183 | public boolean isUniStrKey() { 184 | if (null != mKeyLabel && mKeyCode == 0) return true; 185 | return false; 186 | } 187 | 188 | public boolean needBalloon() { 189 | return (mKeyMask & KEYMASK_BALLOON) != 0; 190 | } 191 | 192 | public boolean repeatable() { 193 | return (mKeyMask & KEYMASK_REPEAT) != 0; 194 | } 195 | 196 | public int getPopupResId() { 197 | return mPopupSkbId; 198 | } 199 | 200 | public int width() { 201 | return mRight - mLeft; 202 | } 203 | 204 | public int height() { 205 | return mBottom - mTop; 206 | } 207 | 208 | public boolean moveWithinKey(int x, int y) { 209 | if (mLeft - MAX_MOVE_TOLERANCE_X <= x 210 | && mTop - MAX_MOVE_TOLERANCE_Y <= y 211 | && mRight + MAX_MOVE_TOLERANCE_X > x 212 | && mBottom + MAX_MOVE_TOLERANCE_Y > y) { 213 | return true; 214 | } 215 | return false; 216 | } 217 | 218 | @Override 219 | public String toString() { 220 | String str = "\n"; 221 | str += " keyCode: " + String.valueOf(mKeyCode) + "\n"; 222 | str += " keyMask: " + String.valueOf(mKeyMask) + "\n"; 223 | str += " keyLabel: " + (mKeyLabel == null ? "null" : mKeyLabel) + "\n"; 224 | str += " popupResId: " + String.valueOf(mPopupSkbId) + "\n"; 225 | str += " Position: " + String.valueOf(mLeftF) + ", " 226 | + String.valueOf(mTopF) + ", " + String.valueOf(mRightF) + ", " 227 | + String.valueOf(mBottomF) + "\n"; 228 | return str; 229 | } 230 | } 231 | -------------------------------------------------------------------------------- /src/com/android/inputmethod/pinyin/SoundManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.inputmethod.pinyin; 18 | 19 | import android.content.Context; 20 | import android.media.AudioManager; 21 | 22 | /** 23 | * Class used to manage related sound resources. 24 | */ 25 | public class SoundManager { 26 | private static SoundManager mInstance = null; 27 | private Context mContext; 28 | private AudioManager mAudioManager; 29 | // Align sound effect volume on music volume 30 | private final float FX_VOLUME = -1.0f; 31 | private boolean mSilentMode; 32 | 33 | private SoundManager(Context context) { 34 | mContext = context; 35 | updateRingerMode(); 36 | } 37 | 38 | public void updateRingerMode() { 39 | if (mAudioManager == null) { 40 | mAudioManager = (AudioManager) mContext 41 | .getSystemService(Context.AUDIO_SERVICE); 42 | } 43 | mSilentMode = (mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL); 44 | } 45 | 46 | public static SoundManager getInstance(Context context) { 47 | if (null == mInstance) { 48 | if (null != context) { 49 | mInstance = new SoundManager(context); 50 | } 51 | } 52 | return mInstance; 53 | } 54 | 55 | public void playKeyDown() { 56 | if (mAudioManager == null) { 57 | updateRingerMode(); 58 | } 59 | if (!mSilentMode) { 60 | int sound = AudioManager.FX_KEYPRESS_STANDARD; 61 | mAudioManager.playSoundEffect(sound, FX_VOLUME); 62 | } 63 | } 64 | } 65 | --------------------------------------------------------------------------------