uint32_t KeyboardEngine::processCompose(uint32_t keyval, uint32_t state) { // FIXME, should we check if state is 0? FCITX_UNUSED(state); if (!m_xkbComposeState) { return 0; } enum xkb_compose_feed_result result = xkb_compose_state_feed(m_xkbComposeState.get(), keyval); if (result == XKB_COMPOSE_FEED_IGNORED) { return 0; } enum xkb_compose_status status = xkb_compose_state_get_status(m_xkbComposeState.get()); if (status == XKB_COMPOSE_NOTHING) { return 0; } else if (status == XKB_COMPOSE_COMPOSED) { char buffer[FCITX_UTF8_MAX_LENGTH + 1] = {'\0', '\0', '\0', '\0', '\0', '\0', '\0'}; int length = xkb_compose_state_get_utf8(m_xkbComposeState.get(), buffer, sizeof(buffer)); xkb_compose_state_reset(m_xkbComposeState.get()); if (length == 0) { return INVALID_COMPOSE_RESULT; } uint32_t c = 0; fcitx_utf8_get_char(buffer, &c); return c; } else if (status == XKB_COMPOSE_CANCELLED) { xkb_compose_state_reset(m_xkbComposeState.get()); } return INVALID_COMPOSE_RESULT; }
char* ProcessFullWidthChar(void* arg, const char* str) { FcitxFullWidthChar* fwchar = (FcitxFullWidthChar*)arg; FcitxProfile* profile = FcitxInstanceGetProfile(fwchar->owner); if (profile->bUseFullWidthChar) { size_t i = 0, ret_len = 0, len = fcitx_utf8_strlen(str); char* ret = (char *) fcitx_utils_malloc0(sizeof(char) * (UTF8_MAX_LENGTH * len + 1)); const char* ps = str; ret[0] = '\0'; for (; i < len; ++i) { int wc; int chr_len = fcitx_utf8_char_len(ps); char *nps; nps = fcitx_utf8_get_char(ps , &wc); if (chr_len == 1 && ps[0] >= '\x20' && ps[0] <= '\x7e') { strcat(ret, sCornerTrans[ps[0] - 32]); ret_len += strlen(sCornerTrans[ps[0] - 32]); } else { strncat(ret, ps, chr_len); ret_len += chr_len; } ps = nps; } ret[ret_len] = '\0'; return ret; } else return NULL; }
char* SplitHZAndPY(char* string) { if (string == NULL) return NULL; char* s = string; while (*s) { char* p; int chr; p = fcitx_utf8_get_char(s, &chr); if (p - s == 1) break; s = p; } return s; }
char* MapSogouStringToHalf(const char* string) { const char* s = string; const char* sn; size_t len = strlen(string); char* half = fcitx_utils_malloc0(sizeof(char) * (len + 1)); char* halfp = half; int upperCount = 0; while (*s) { unsigned int chr = 0; sn = fcitx_utf8_get_char(s, &chr); /* from A to Z */ if ((chr >= 0xff21 && chr <= 0xff3a) || (chr >= 0xff41 && chr <= 0xff5a)) { *halfp = (char) (chr & 0xff) + 0x20; if (isupper(*halfp)) upperCount ++; halfp ++; } else { while(s < sn) { *halfp = *s; if (isupper(*halfp)) upperCount ++; s++; halfp++; } } s = sn; } if (*half && isupper(*half) && upperCount == 1) { *half = tolower(*half); } return half; }
static int SpellCustomGetDistance(SpellCustomDict *custom_dict, const char *word, const char *dict, int word_len) { #define REPLACE_WEIGHT 3 #define INSERT_WEIGHT 3 #define REMOVE_WEIGHT 3 #define END_WEIGHT 1 /* * three kinds of error, replace, insert and remove * replace means apple vs aplle * insert means apple vs applee * remove means apple vs aple * * each error need to follow a correct match. * * number of "remove error" shoud be no more than "maxremove" * while maxremove equals to (length - 2) / 3 * * and the total error number should be no more than "maxdiff" * while maxdiff equales to length / 3. */ int replace = 0; int insert = 0; int remove = 0; int diff = 0; int maxdiff; int maxremove; unsigned int cur_word_c; unsigned int cur_dict_c; unsigned int next_word_c; unsigned int next_dict_c; maxdiff = word_len / 3; maxremove = (word_len - 2) / 3; word = fcitx_utf8_get_char(word, &cur_word_c); dict = fcitx_utf8_get_char(dict, &cur_dict_c); while ((diff = replace + insert + remove) <= maxdiff && remove <= maxremove) { /* * cur_word_c and cur_dict_c are the current characters * and dict and word are pointing to the next one. */ if (!cur_word_c) { return ((replace * REPLACE_WEIGHT + insert * INSERT_WEIGHT + remove * REMOVE_WEIGHT) + (cur_dict_c ? (fcitx_utf8_strlen(dict) + 1) * END_WEIGHT : 0)); } word = fcitx_utf8_get_char(word, &next_word_c); /* check remove error */ if (!cur_dict_c) { if (next_word_c) return -1; remove++; if (diff <= maxdiff && remove <= maxremove) { return (replace * REPLACE_WEIGHT + insert * INSERT_WEIGHT + remove * REMOVE_WEIGHT); } return -1; } dict = fcitx_utf8_get_char(dict, &next_dict_c); if (cur_word_c == cur_dict_c || (custom_dict->word_comp_func && custom_dict->word_comp_func(cur_word_c, cur_dict_c))) { cur_word_c = next_word_c; cur_dict_c = next_dict_c; continue; } if (next_word_c == cur_dict_c || (custom_dict->word_comp_func && next_word_c && custom_dict->word_comp_func(next_word_c, cur_dict_c))) { word = fcitx_utf8_get_char(word, &cur_word_c); cur_dict_c = next_dict_c; remove++; continue; } /* check insert error */ if (cur_word_c == next_dict_c || (custom_dict->word_comp_func && next_dict_c && custom_dict->word_comp_func(cur_word_c, next_dict_c))) { cur_word_c = next_word_c; dict = fcitx_utf8_get_char(dict, &cur_dict_c); insert++; continue; } /* check replace error */ if (next_word_c == next_dict_c || (custom_dict->word_comp_func && next_word_c && next_dict_c && custom_dict->word_comp_func(next_word_c, next_dict_c))) { if (next_word_c) { dict = fcitx_utf8_get_char(dict, &cur_dict_c); word = fcitx_utf8_get_char(word, &cur_word_c); } else { cur_word_c = 0; cur_dict_c = 0; } replace++; continue; } break; } return -1; }
/** * 该函数装载data/gbks2t.tab的简体转繁体的码表, * 然后按码表将GBK字符转换成GBK繁体字符。 * * WARNING: 该函数返回新分配内存字符串,请调用者 * 注意释放。 */ char *ConvertGBKTradition2Simple(FcitxChttrans* transState, const char *strHZ) { if (strHZ == NULL) return NULL; switch (transState->engine) { case ENGINE_OPENCC: #ifdef ENABLE_OPENCC do { if (transState->odt2s == NULL) { OpenCCInit(transState); if (transState->odt2s == NULL) { break; } } char * res = OpenCCConvert(transState->odt2s, strHZ, (size_t) - 1); if (!res || res == (char *) - 1) { return NULL; } return res; } while(0); #endif case ENGINE_NATIVE: { FILE *fp; char *ret; int i, len, ret_len; const char *ps; if (!transState->t2s_table) { char *strBuf = NULL; size_t bufLen = 0; fp = FcitxXDGGetFileWithPrefix("data", TABLE_GBKS2T, "r", NULL); if (!fp) { ret = (char *) malloc(sizeof(char) * (strlen(strHZ) + 1)); strcpy(ret, strHZ); return ret; } while (getline(&strBuf, &bufLen, fp) != -1) { simple2trad_t *t2s = NULL; char *ps; uint32_t wc; ps = fcitx_utf8_get_char(strBuf, &wc); HASH_FIND_INT(transState->s2t_table, &wc, t2s); if (t2s) { continue; } t2s = (simple2trad_t*) malloc(sizeof(simple2trad_t)); fcitx_utf8_get_char(ps, &wc); t2s->wc = wc; t2s->len = fcitx_utf8_char_len(strBuf); strncpy(t2s->str, strBuf, t2s->len); t2s->str[t2s->len] = '\0'; HASH_ADD_INT(transState->t2s_table, wc, t2s); } fcitx_utils_free(strBuf); } i = 0; len = fcitx_utf8_strlen(strHZ); ret_len = 0; ret = fcitx_utils_malloc0(UTF8_MAX_LENGTH * len + 1); ps = strHZ; ret[0] = '\0'; for (; i < len; ++i) { uint32_t wc; simple2trad_t *t2s = NULL; int chr_len = fcitx_utf8_char_len(ps); char *nps; nps = fcitx_utf8_get_char(ps , &wc); HASH_FIND_INT(transState->t2s_table, &wc, t2s); if (t2s) { strcat(ret, t2s->str); ret_len += t2s->len; } else { strncat(ret, ps, chr_len); ret_len += chr_len; } ps = nps; } ret[ret_len] = '\0'; return ret; } } return NULL; }
/** * 该函数装载data/gbks2t.tab的简体转繁体的码表, * 然后按码表将GBK字符转换成GBK繁体字符。 * * WARNING: 该函数返回新分配内存字符串,请调用者 * 注意释放。 */ char *ConvertGBKTradition2Simple(FcitxChttrans* transState, const char *strHZ) { if (strHZ == NULL) return NULL; switch (transState->engine) { case ENGINE_OPENCC: #ifdef _ENABLE_OPENCC { if (transState->odt2s == NULL) { transState->odt2s = opencc_open(OPENCC_DEFAULT_CONFIG_TRAD_TO_SIMP); if (transState->odt2s == NULL) { opencc_perror(_("OpenCC initialization error")); return NULL; } } char * res = opencc_convert_utf8(transState->odt2s, strHZ, (size_t) - 1); if (res == (char *) - 1) { opencc_perror(_("OpenCC error")); return NULL; } return res; } #endif case ENGINE_NATIVE: { FILE *fp; char *ret; int i, len, ret_len; char *strBuf = NULL; size_t bufLen = 0; const char *ps; if (!transState->t2s_table) { len = 0; fp = FcitxXDGGetFileWithPrefix("data", TABLE_GBKS2T, "r", NULL); if (!fp) { ret = (char *) malloc(sizeof(char) * (strlen(strHZ) + 1)); strcpy(ret, strHZ); return ret; } while (getline(&strBuf, &bufLen, fp) != -1) { simple2trad_t *t2s; char *ps; unsigned int wc; ps = fcitx_utf8_get_char(strBuf, &wc); t2s = (simple2trad_t*) malloc(sizeof(simple2trad_t)); fcitx_utf8_get_char(ps, &wc); t2s->wc = wc; t2s->len = fcitx_utf8_char_len(strBuf); strncpy(t2s->str, strBuf, t2s->len); t2s->str[t2s->len] = '\0'; HASH_ADD_INT(transState->t2s_table, wc, t2s); } if (strBuf) free(strBuf); } i = 0; len = fcitx_utf8_strlen(strHZ); ret_len = 0; ret = (char *) fcitx_utils_malloc0(sizeof(char) * (UTF8_MAX_LENGTH * len + 1)); ps = strHZ; ret[0] = '\0'; for (; i < len; ++i) { unsigned int wc; simple2trad_t *t2s = NULL; int chr_len = fcitx_utf8_char_len(ps); char *nps; nps = fcitx_utf8_get_char(ps , &wc); HASH_FIND_INT(transState->t2s_table, &wc, t2s); if (t2s) { strcat(ret, t2s->str); ret_len += t2s->len; } else { strncat(ret, ps, chr_len); ret_len += chr_len; } ps = nps; } ret[ret_len] = '\0'; return ret; } } return NULL; }