FCITX_EXPORT_API void FcitxInstanceCommitString(FcitxInstance* instance, FcitxInputContext* ic, const char* str) { if (str == NULL) return ; if (ic == NULL) return; char *pstr = FcitxInstanceProcessCommitFilter(instance, str); if (pstr != NULL) str = pstr; FcitxAddon **pfrontend = FcitxInstanceGetPFrontend(instance, ic->frontendid); if (pfrontend == NULL) return; FcitxFrontend* frontend = (*pfrontend)->frontend; frontend->CommitString((*pfrontend)->addonInstance, ic, str); FcitxInputState* input = instance->input; fcitx_utf8_strncpy(input->strLastCommit, str, MAX_USER_INPUT); input->strLastCommit[MAX_USER_INPUT] = '\0'; instance->iHZInputed += (int)(fcitx_utf8_strlen(str)); if (pstr) free(pstr); }
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; }
static void _fcitx_im_context_update_preedit_cb(DBusGProxy* proxy, char* str, int cursor_pos, void* user_data) { FcitxLog(LOG_LEVEL, "_fcitx_im_context_commit_string_cb"); FcitxIMContext* context = FCITX_IM_CONTEXT(user_data); gboolean visible = false; if (context->preedit_string != NULL) { if (strlen(context->preedit_string) != 0) visible = true; g_free(context->preedit_string); context->preedit_string = NULL; } context->preedit_string = g_strdup(str); char* tempstr = g_strndup(str, cursor_pos); context->cursor_pos = fcitx_utf8_strlen(tempstr); g_free(tempstr); gboolean new_visible = false; if (context->preedit_string != NULL) { if (strlen(context->preedit_string) != 0) new_visible = true; } gboolean flag = new_visible != visible; if (new_visible) { if (flag) { /* invisible => visible */ g_signal_emit(context, _signal_preedit_start_id, 0); } g_signal_emit(context, _signal_preedit_changed_id, 0); } else { if (flag) { /* visible => invisible */ g_signal_emit(context, _signal_preedit_changed_id, 0); g_signal_emit(context, _signal_preedit_end_id, 0); } else { /* still invisible */ /* do nothing */ } } g_signal_emit(context, _signal_preedit_changed_id, 0); }
/** * @brief get the candidate word by index * * @param iIndex index of candidate word * @return the string of canidate word **/ __EXPORT_API INPUT_RETURN_VALUE FcitxLibpinyinGetCandWord (void* arg, FcitxCandidateWord* candWord) { FcitxLibpinyin* libpinyin = (FcitxLibpinyin* )arg; FcitxLibpinyinCandWord* pyCand = (FcitxLibpinyinCandWord*) candWord->priv; FcitxInstance* instance = libpinyin->owner->owner; FcitxInputState* input = FcitxInstanceGetInputState(instance); if (pyCand->ispunc) { strcpy(FcitxInputStateGetOutputString(input), candWord->strWord); return IRV_COMMIT_STRING; } else { if (!libpinyin->candidate || libpinyin->candidate->len <= pyCand->idx) return IRV_TO_PROCESS; lookup_candidate_t* cand = &g_array_index(libpinyin->candidate, lookup_candidate_t, pyCand->idx); pinyin_choose_candidate(libpinyin->inst, LibpinyinGetOffset(libpinyin), cand); FcitxLibpinyinFixed f; f.len = fcitx_utf8_strlen(cand->m_phrase_string); g_array_append_val(libpinyin->fixed_string, f); int offset = LibpinyinGetOffset(libpinyin); if (offset >= libpinyin->inst->m_pinyin_keys->len) { char* sentence = NULL; pinyin_guess_sentence(libpinyin->inst); sentence = LibpinyinGetSentence(libpinyin); if (sentence) { strcpy(FcitxInputStateGetOutputString(input), sentence); g_free(sentence); pinyin_train(libpinyin->inst); } else strcpy(FcitxInputStateGetOutputString(input), ""); return IRV_COMMIT_STRING; } int pyoffset = LibpinyinGetPinyinOffset(libpinyin); if (pyoffset > libpinyin->cursor_pos) libpinyin->cursor_pos = pyoffset; return IRV_DISPLAY_CANDWORDS; } return IRV_TO_PROCESS; }
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; }
SpellHint* SpellCustomHintWords(FcitxSpell *spell, unsigned int len_limit) { SpellCustomCWord clist[len_limit + 1]; int i; unsigned int num = 0; int word_type = 0; SpellCustomDict *dict = spell->custom_dict; const char *word; const char *prefix = NULL; int prefix_len = 0; const char *real_word; SpellHint *res; int word_len; if (!SpellCustomCheck(spell)) return NULL; if (!*spell->current_str) return NULL; word = spell->current_str; real_word = word; if (dict->delim && *dict->delim) { size_t delta; while (real_word[delta = strcspn(real_word, dict->delim)]) { prefix = word; real_word += delta + 1; } prefix_len = prefix ? real_word - prefix : 0; } if (!*real_word) return NULL; if (dict->word_check_func) word_type = dict->word_check_func(real_word); word_len = fcitx_utf8_strlen(real_word); for (i = 0;i < dict->words_count;i++) { int dist; if ((dist = SpellCustomGetDistance( dict, real_word, dict->map + dict->words[i], word_len)) >= 0) { int j = num; clist[j].word = dict->map + dict->words[i]; clist[j].dist = dist; if (num < len_limit) num++; for (;j > 0;j--) { if (SpellCustomCWordCompare(clist + j - 1, clist + j) > 0) { SpellCustomCWord tmp = clist[j]; clist[j] = clist[j - 1]; clist[j - 1] = tmp; continue; } break; } } } res = SpellHintListWithPrefix(num, prefix, prefix_len, &clist->word, sizeof(SpellCustomCWord)); if (!res) return NULL; if (dict->hint_cmplt_func) dict->hint_cmplt_func(res, word_type); return res; }
/** * 该函数装载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; }
boolean TableCreatePhraseCode(TableDict* tableDict, char *strHZ) { unsigned char i; unsigned char i1, i2; size_t iLen; char strTemp[UTF8_MAX_LENGTH + 1] = {'\0', }; RECORD *recTemp; boolean bCanntFindCode = false; iLen = fcitx_utf8_strlen(strHZ); if (iLen >= tableDict->iCodeLength) { i2 = tableDict->iCodeLength; i1 = 1; } else { i2 = iLen; i1 = 0; } for (i = 0; i < tableDict->iCodeLength - 1; i++) { if (tableDict->rule[i].iWords == i2 && tableDict->rule[i].iFlag == i1) break; } if (i == tableDict->iCodeLength - 1) return true; int codeIdx = 0; for (i1 = 0; i1 < tableDict->iCodeLength; i1++) { int clen; char* ps; if (tableDict->rule[i].rule[i1].iFlag) { ps = fcitx_utf8_get_nth_char(strHZ, tableDict->rule[i].rule[i1].iWhich - 1); clen = fcitx_utf8_char_len(ps); strncpy(strTemp, ps, clen); } else { ps = fcitx_utf8_get_nth_char(strHZ, iLen - tableDict->rule[i].rule[i1].iWhich); clen = fcitx_utf8_char_len(ps); strncpy(strTemp, ps, clen); } int hzIndex = CalHZIndex(strTemp); if (tableDict->tableSingleHZ[hzIndex]) { if (tableDict->tableSingleHZCons[hzIndex]) recTemp = tableDict->tableSingleHZCons[hzIndex]; else recTemp = tableDict->tableSingleHZ[hzIndex]; } else { bCanntFindCode = true; break; } if (strlen(recTemp->strCode) >= tableDict->rule[i].rule[i1].iIndex) { tableDict->strNewPhraseCode[codeIdx] = recTemp->strCode[tableDict->rule[i].rule[i1].iIndex - 1]; codeIdx++; } } return bCanntFindCode; }
boolean LoadTableDict(TableMetaData* tableMetaData) { char strCode[MAX_CODE_LENGTH + 1]; char *strHZ = 0; FILE *fpDict; RECORD *recTemp; unsigned int i = 0; uint32_t iTemp, iTempCount; char cChar = 0, cTemp; int8_t iVersion = 1; int iRecordIndex; TableDict *tableDict; //读入码表 FcitxLog(DEBUG, _("Loading Table Dict")); int reload = 0; do { boolean error = false; if (!reload) { /** * kcm saves a absolute path here but it is then interpreted as * a relative path? **/ fpDict = FcitxXDGGetFileWithPrefix("table", tableMetaData->strPath, "r", NULL); } else { char *tablepath; char *path = fcitx_utils_get_fcitx_path("pkgdatadir"); fcitx_utils_alloc_cat_str(tablepath, path, "/table/", tableMetaData->strPath); fpDict = fopen(tablepath, "r"); free(tablepath); } if (!fpDict) return false; tableMetaData->tableDict = fcitx_utils_new(TableDict); tableDict = tableMetaData->tableDict; tableDict->pool = fcitx_memory_pool_create(); #define CHECK_LOAD_TABLE_ERROR(SIZE) if (size < (SIZE)) { error = true; goto table_load_error; } //先读取码表的信息 //判断版本信息 size_t size; size = fcitx_utils_read_uint32(fpDict, &iTemp); CHECK_LOAD_TABLE_ERROR(1); if (!iTemp) { size = fread(&iVersion, sizeof(int8_t), 1, fpDict); CHECK_LOAD_TABLE_ERROR(1); iVersion = (iVersion < INTERNAL_VERSION); size = fcitx_utils_read_uint32(fpDict, &iTemp); CHECK_LOAD_TABLE_ERROR(1); } tableDict->strInputCode = (char*)realloc(tableDict->strInputCode, sizeof(char) * (iTemp + 1)); size = fread(tableDict->strInputCode, sizeof(char), iTemp + 1, fpDict); CHECK_LOAD_TABLE_ERROR(iTemp + 1); /* * 建立索引,加26是为了为拼音编码预留空间 */ size_t tmp_len = strlen(tableDict->strInputCode) + 26; tableDict->recordIndex = (RECORD_INDEX*)fcitx_memory_pool_alloc(tableDict->pool, tmp_len * sizeof(RECORD_INDEX)); for (iTemp = 0; iTemp < tmp_len; iTemp++) { tableDict->recordIndex[iTemp].cCode = 0; tableDict->recordIndex[iTemp].record = NULL; } /********************************************************************/ size = fread(&(tableDict->iCodeLength), sizeof(uint8_t), 1, fpDict); CHECK_LOAD_TABLE_ERROR(1); UpdateTableMetaData(tableMetaData); if (!iVersion) { size = fread(&(tableDict->iPYCodeLength), sizeof(uint8_t), 1, fpDict); CHECK_LOAD_TABLE_ERROR(1); } else tableDict->iPYCodeLength = tableDict->iCodeLength; size = fcitx_utils_read_uint32(fpDict, &iTemp); CHECK_LOAD_TABLE_ERROR(1); tableDict->strIgnoreChars = (char*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(char) * (iTemp + 1)); size = fread(tableDict->strIgnoreChars, sizeof(char), iTemp + 1, fpDict); CHECK_LOAD_TABLE_ERROR(iTemp + 1); size = fread(&(tableDict->bRule), sizeof(unsigned char), 1, fpDict); CHECK_LOAD_TABLE_ERROR(1); if (tableDict->bRule) { //表示有组词规则 tableDict->rule = (RULE*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(RULE) * (tableDict->iCodeLength - 1)); for (i = 0; i < tableDict->iCodeLength - 1; i++) { size = fread(&(tableDict->rule[i].iFlag), sizeof(unsigned char), 1, fpDict); CHECK_LOAD_TABLE_ERROR(1); size = fread(&(tableDict->rule[i].iWords), sizeof(unsigned char), 1, fpDict); CHECK_LOAD_TABLE_ERROR(1); tableDict->rule[i].rule = (RULE_RULE*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(RULE_RULE) * tableDict->iCodeLength); for (iTemp = 0; iTemp < tableDict->iCodeLength; iTemp++) { size = fread(&(tableDict->rule[i].rule[iTemp].iFlag), sizeof(unsigned char), 1, fpDict); CHECK_LOAD_TABLE_ERROR(1); size = fread(&(tableDict->rule[i].rule[iTemp].iWhich), sizeof(unsigned char), 1, fpDict); CHECK_LOAD_TABLE_ERROR(1); size = fread(&(tableDict->rule[i].rule[iTemp].iIndex), sizeof(unsigned char), 1, fpDict); CHECK_LOAD_TABLE_ERROR(1); } } } tableDict->recordHead = (RECORD*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(RECORD)); tableDict->currentRecord = tableDict->recordHead; size = fcitx_utils_read_uint32(fpDict, &tableDict->iRecordCount); CHECK_LOAD_TABLE_ERROR(1); for (i = 0; i < SINGLE_HZ_COUNT; i++) { tableDict->tableSingleHZ[i] = (RECORD*)NULL; tableDict->tableSingleHZCons[i] = (RECORD*)NULL; } iRecordIndex = 0; size_t bufSize = 0; for (i = 0; i < tableDict->iRecordCount; i++) { size = fread(strCode, sizeof(int8_t), tableDict->iPYCodeLength + 1, fpDict); CHECK_LOAD_TABLE_ERROR(tableDict->iPYCodeLength + 1); size = fcitx_utils_read_uint32(fpDict, &iTemp); CHECK_LOAD_TABLE_ERROR(1); /* we don't actually have such limit, but sometimes, broken table * may break this, so we need to give a limitation. */ if (iTemp > UTF8_MAX_LENGTH * 30) { error = true; goto table_load_error; } if (iTemp > bufSize) { bufSize = iTemp; strHZ = realloc(strHZ, bufSize); } size = fread(strHZ, sizeof(int8_t), iTemp, fpDict); CHECK_LOAD_TABLE_ERROR(iTemp); recTemp = (RECORD*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(RECORD)); recTemp->strCode = (char*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(char) * (tableDict->iPYCodeLength + 1)); memset(recTemp->strCode, 0, sizeof(char) * (tableDict->iPYCodeLength + 1)); strcpy(recTemp->strCode, strCode); recTemp->strHZ = (char*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(char) * iTemp); strcpy(recTemp->strHZ, strHZ); if (!iVersion) { size = fread(&cTemp, sizeof(int8_t), 1, fpDict); CHECK_LOAD_TABLE_ERROR(1); recTemp->type = cTemp; } size = fcitx_utils_read_uint32(fpDict, &recTemp->iHit); CHECK_LOAD_TABLE_ERROR(1); size = fcitx_utils_read_uint32(fpDict, &recTemp->iIndex); CHECK_LOAD_TABLE_ERROR(1); if (recTemp->iIndex > tableDict->iTableIndex) tableDict->iTableIndex = recTemp->iIndex; /* 建立索引 */ if (cChar != recTemp->strCode[0]) { cChar = recTemp->strCode[0]; tableDict->recordIndex[iRecordIndex].cCode = cChar; tableDict->recordIndex[iRecordIndex].record = recTemp; iRecordIndex++; } /******************************************************************/ /** 为单字生成一个表 */ if (fcitx_utf8_strlen(recTemp->strHZ) == 1 && !IsIgnoreChar(tableDict, strCode[0])) { RECORD** tableSingleHZ = NULL; if (recTemp->type == RECORDTYPE_NORMAL) tableSingleHZ = tableDict->tableSingleHZ; else if (recTemp->type == RECORDTYPE_CONSTRUCT) tableSingleHZ = tableDict->tableSingleHZCons; if (tableSingleHZ) { iTemp = CalHZIndex(recTemp->strHZ); if (iTemp < SINGLE_HZ_COUNT) { if (tableSingleHZ[iTemp]) { if (strlen(strCode) > strlen(tableDict->tableSingleHZ[iTemp]->strCode)) tableSingleHZ[iTemp] = recTemp; } else tableSingleHZ[iTemp] = recTemp; } } } if (recTemp->type == RECORDTYPE_PINYIN) tableDict->bHasPinyin = true; if (recTemp->type == RECORDTYPE_PROMPT && strlen(recTemp->strCode) == 1) tableDict->promptCode[(uint8_t) recTemp->strCode[0]] = recTemp; tableDict->currentRecord->next = recTemp; recTemp->prev = tableDict->currentRecord; tableDict->currentRecord = recTemp; } if (strHZ) { free(strHZ); strHZ = NULL; } tableDict->currentRecord->next = tableDict->recordHead; tableDict->recordHead->prev = tableDict->currentRecord; table_load_error: fclose(fpDict); if (error) { fcitx_memory_pool_destroy(tableDict->pool); tableDict->pool = NULL; reload++; } else { break; } } while(reload < 2); if (!tableDict->pool) return false; FcitxLog(DEBUG, _("Load Table Dict OK")); //读取相应的特殊符号表 fpDict = FcitxXDGGetFileWithPrefix("table", tableMetaData->strSymbolFile, "r", NULL); if (fpDict) { tableDict->iFH = fcitx_utils_calculate_record_number(fpDict); tableDict->fh = (FH*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(FH) * tableDict->iFH); char* strBuf = NULL; size_t bufLen = 0; for (i = 0; i < tableDict->iFH; i++) { if (getline(&strBuf, &bufLen, fpDict) == -1) break; if (!fcitx_utf8_check_string(strBuf)) break; if (fcitx_utf8_strlen(strBuf) > FH_MAX_LENGTH) break; strcpy(tableDict->fh[i].strFH, strBuf); } fcitx_utils_free(strBuf); tableDict->iFH = i; fclose(fpDict); } tableDict->strNewPhraseCode = (char*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(char) * (tableDict->iCodeLength + 1)); tableDict->strNewPhraseCode[tableDict->iCodeLength] = '\0'; tableDict->iAutoPhrase = 0; if (tableMetaData->bAutoPhrase) { tableDict->autoPhrase = (AUTOPHRASE*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(AUTOPHRASE) * AUTO_PHRASE_COUNT); //读取上次保存的自动词组信息 FcitxLog(DEBUG, _("Loading Autophrase.")); char *temppath; fcitx_utils_alloc_cat_str(temppath, tableMetaData->uniqueName, "_LastAutoPhrase.tmp"); fpDict = FcitxXDGGetFileWithPrefix("table", temppath, "r", NULL); free(temppath); i = 0; if (fpDict) { size_t size = fcitx_utils_read_int32(fpDict, &tableDict->iAutoPhrase); if (size == 1) { for (; i < tableDict->iAutoPhrase; i++) { tableDict->autoPhrase[i].strCode = (char*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(char) * (tableDict->iCodeLength + 1)); tableDict->autoPhrase[i].strHZ = (char*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(char) * (PHRASE_MAX_LENGTH * UTF8_MAX_LENGTH + 1)); size = fread(tableDict->autoPhrase[i].strCode, tableDict->iCodeLength + 1, 1, fpDict); if (size != 1) { tableDict->iAutoPhrase = i; break; } size = fread(tableDict->autoPhrase[i].strHZ, PHRASE_MAX_LENGTH * UTF8_MAX_LENGTH + 1, 1, fpDict); tableDict->autoPhrase[i].strHZ[PHRASE_MAX_LENGTH * UTF8_MAX_LENGTH] = 0; if (size != 1 || !fcitx_utf8_check_string(tableDict->autoPhrase[i].strHZ)) { tableDict->iAutoPhrase = i; break; } size = fcitx_utils_read_uint32(fpDict, &iTempCount); if (size != 1) { tableDict->iAutoPhrase = i; break; } tableDict->autoPhrase[i].iSelected = iTempCount; if (i == AUTO_PHRASE_COUNT - 1) tableDict->autoPhrase[i].next = &tableDict->autoPhrase[0]; else tableDict->autoPhrase[i].next = &tableDict->autoPhrase[i + 1]; } } fclose(fpDict); } for (; i < AUTO_PHRASE_COUNT; i++) { tableDict->autoPhrase[i].strCode = (char*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(char) * (tableDict->iCodeLength + 1)); tableDict->autoPhrase[i].strHZ = (char*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(char) * (PHRASE_MAX_LENGTH * UTF8_MAX_LENGTH + 1)); tableDict->autoPhrase[i].iSelected = 0; if (i == AUTO_PHRASE_COUNT - 1) tableDict->autoPhrase[i].next = &tableDict->autoPhrase[0]; else tableDict->autoPhrase[i].next = &tableDict->autoPhrase[i + 1]; } if (i == AUTO_PHRASE_COUNT) tableDict->insertPoint = &tableDict->autoPhrase[0]; else tableDict->insertPoint = &tableDict->autoPhrase[i - 1]; FcitxLog(DEBUG, _("Load Autophrase OK")); } else tableDict->autoPhrase = (AUTOPHRASE *) NULL; return true; }
void FcitxLibpinyinUpdatePreedit(FcitxLibpinyin* libpinyin, char* sentence) { FcitxInstance* instance = libpinyin->owner->owner; FcitxInputState* input = FcitxInstanceGetInputState(instance); int offset = LibpinyinGetOffset(libpinyin); if (libpinyin->type == LPT_Pinyin) { int libpinyinLen = strlen(libpinyin->inst->m_raw_full_pinyin); int fcitxLen = strlen(libpinyin->buf); if (fcitxLen != libpinyinLen) { strcpy(libpinyin->buf, libpinyin->inst->m_raw_full_pinyin); libpinyin->cursor_pos += libpinyinLen - fcitxLen; } } int pyoffset = LibpinyinGetPinyinOffset(libpinyin); if (pyoffset > libpinyin->cursor_pos) libpinyin->cursor_pos = pyoffset; int hzlen = 0; if (fcitx_utf8_strlen(sentence) > offset) hzlen = fcitx_utf8_get_nth_char(sentence, offset) - sentence; else hzlen = strlen(sentence); if (hzlen > 0) { char* buf = (char*) fcitx_utils_malloc0((hzlen + 1) * sizeof(char)); strncpy(buf, sentence, hzlen); buf[hzlen] = 0; FcitxMessagesAddMessageAtLast(FcitxInputStateGetPreedit(input), MSG_INPUT, "%s", buf); free(buf); } int charcurpos = hzlen; int lastpos = pyoffset; int curoffset = pyoffset; for (int i = offset; i < libpinyin->inst->m_pinyin_keys->len; i ++) { PinyinKey* pykey = &g_array_index(libpinyin->inst->m_pinyin_keys, PinyinKey, i); PinyinKeyPos* pykeypos = &g_array_index(libpinyin->inst->m_pinyin_key_rests, PinyinKeyPos, i); if (lastpos > 0) { FcitxMessagesMessageConcatLast (FcitxInputStateGetPreedit(input), " "); if (curoffset < libpinyin->cursor_pos) charcurpos ++; for (int j = lastpos; j < pykeypos->m_raw_begin; j ++) { char temp[2] = {'\0', '\0'}; temp[0] = libpinyin->buf[j]; FcitxMessagesMessageConcatLast (FcitxInputStateGetPreedit(input), temp); if (curoffset < libpinyin->cursor_pos) { curoffset ++; charcurpos ++; } } } lastpos = pykeypos->m_raw_end; switch (libpinyin->type) { case LPT_Pinyin: { gchar* pystring = pykey->get_pinyin_string(); FcitxMessagesAddMessageAtLast(FcitxInputStateGetPreedit(input), MSG_CODE, "%s", pystring); size_t pylen = strlen(pystring); if (curoffset + pylen < libpinyin->cursor_pos) { curoffset += pylen; charcurpos += pylen; } else { charcurpos += libpinyin->cursor_pos - curoffset; curoffset = libpinyin->cursor_pos; } g_free(pystring); break; } case LPT_Shuangpin: { if (pykeypos->length() == 2) { const char* initial = 0; if (pykey->m_initial == CHEWING_ZERO_INITIAL) initial = "'"; else initial = get_initial_string(pykey); if (curoffset + 1 <= libpinyin->cursor_pos) { curoffset += 1; charcurpos += strlen(initial); } FcitxMessagesAddMessageAtLast(FcitxInputStateGetPreedit(input), MSG_CODE, "%s", initial); if (curoffset + 1 <= libpinyin->cursor_pos) { curoffset += 1; charcurpos += strlen(get_middle_string(pykey)) + strlen(get_final_string(pykey)); } FcitxMessagesAddMessageAtLast(FcitxInputStateGetPreedit(input), MSG_CODE, "%s%s", get_middle_string(pykey), get_final_string(pykey)); } else if (pykeypos->length() == 1) { gchar* pystring = pykey->get_pinyin_string(); if (curoffset + 1 <= libpinyin->cursor_pos) { curoffset += 1; charcurpos += strlen(pystring); } FcitxMessagesAddMessageAtLast(FcitxInputStateGetPreedit(input), MSG_CODE, "%s", pystring); g_free(pystring); } break; } case LPT_Zhuyin: { gchar* pystring = pykey->get_chewing_string(); FcitxMessagesAddMessageAtLast(FcitxInputStateGetPreedit(input), MSG_CODE, "%s", pystring); if (curoffset + pykeypos->length() <= libpinyin->cursor_pos) { curoffset += pykeypos->length(); charcurpos += strlen(pystring); } else { int diff = libpinyin->cursor_pos - curoffset; curoffset = libpinyin->cursor_pos; size_t len = fcitx_utf8_strlen(pystring); if (pykey->m_tone != CHEWING_ZERO_TONE) len --; if (diff > len) charcurpos += strlen(pystring); else { charcurpos += fcitx_utf8_get_nth_char(pystring, diff) - pystring; } } g_free(pystring); break; } } } int buflen = strlen(libpinyin->buf); if (lastpos < buflen) { FcitxMessagesMessageConcatLast (FcitxInputStateGetPreedit(input), " "); if (lastpos < libpinyin->cursor_pos) charcurpos ++; for (int i = lastpos; i < buflen; i ++) { char temp[2] = {'\0', '\0'}; temp[0] = libpinyin->buf[i]; FcitxMessagesMessageConcatLast (FcitxInputStateGetPreedit(input), temp); if (lastpos < libpinyin->cursor_pos) { charcurpos ++; lastpos++; } } } FcitxInputStateSetCursorPos(input, charcurpos); }
void CreatePYBase(void) { _PyStruct *head, *pyList, *temp, *t; char strPY[7], strHZ[UTF8_MAX_LENGTH * 80 + 1], strMap[3]; int iIndex, iCount, i; int iBaseCount; int s = 0; int tt = 0; head = (_PyStruct *) malloc(sizeof(_PyStruct)); head->prev = head; head->next = head; iBaseCount = 0; while (PYTable_template[iBaseCount].strPY[0] != '\0') iBaseCount++; for (iIndex = 0; iIndex < iBaseCount; iIndex++) YY[iIndex] = 0; iIndex = 0; while (!feof(fps)) { fscanf(fps, "%s", strPY); fscanf(fps, "%s\n", strHZ); if (MapPY(&pyconfig, strPY, strMap, PY_PARSE_INPUT_SYSTEM)) { for (i = 0; i < iBaseCount; i++) if ((!strcmp(PYTable_template[i].strPY, strPY)) && PYTable_template[i].control == PYTABLE_NONE) YY[i] += 1; iIndex++; if (fcitx_utf8_strlen(strHZ) > 1) { int8_t charLen = fcitx_utf8_char_len(strHZ); fprintf(stderr, "%s length is larger that 1, truncated to ", strHZ); strHZ[charLen] = '\0'; fprintf(stderr, "%s.\n", strHZ); } temp = (_PyStruct *) malloc(sizeof(_PyStruct)); strcpy(temp->strHZ, strHZ); strcpy(temp->strPY, strMap); pyList = head->prev; while (pyList != head) { if (strcmp(pyList->strPY, strMap) <= 0) break; pyList = pyList->prev; } temp->next = pyList->next; temp->prev = pyList; pyList->next->prev = temp; pyList->next = temp; } else fprintf(stderr, "%s Error!!!!\n", strPY); } iCount = 0; for (i = 0; i < iBaseCount; i++) { if (YY[i]) iCount++; } fwrite(&iCount, sizeof(int), 1, fp1); printf("Groups: %d\n", iCount); iAllCount = iIndex; pyList = head->next; strcpy(strPY, pyList->strPY); iCount = 0; t = pyList; while (pyList != head) { if (!strcmp(strPY, pyList->strPY)) { iCount++; } else { tt++; fwrite(strPY, sizeof(char) * 2, 1, fp1); fwrite(&iCount, sizeof(int), 1, fp1); for (i = 0; i < iCount; i++) { int8_t len = strlen(t->strHZ); fwrite(&len, sizeof(int8_t), 1, fp1); fwrite(t->strHZ, sizeof(char) * len , 1, fp1); t = t->next; } s += iCount; t = pyList; iCount = 1; strcpy(strPY, pyList->strPY); } pyList = pyList->next; } fwrite(strPY, sizeof(char) * 2, 1, fp1); fwrite(&iCount, sizeof(int), 1, fp1); for (i = 0; i < iCount; i++) { int8_t len = strlen(t->strHZ); fwrite(&len, sizeof(int8_t), 1, fp1); fwrite(t->strHZ, sizeof(char) * len , 1, fp1); t = t->next; } s += iCount; fclose(fp1); fclose(fps); }
void CreatePYPhrase(void) { char strPY[256]; char strPhrase[256]; char strMap[256]; ParsePYStruct strTemp; int iIndex, i, s1, s2, j, k; _PyPhrase *phrase, *t, *tt; FILE *f = fopen("pyERROR", "w"); FILE *fg = fopen("pyPhrase.ok", "w"); int kkk; unsigned int uIndex, uTemp; FcitxPinyinConfig pyconfig; memset(&pyconfig, 0 , sizeof(pyconfig)); InitMHPY(&pyconfig.MHPY_C, MHPY_C_TEMPLATE); InitMHPY(&pyconfig.MHPY_S, MHPY_S_TEMPLATE); InitPYTable(&pyconfig); s1 = 0; s2 = 0; uIndex = 0; printf("Start Loading Phrase...\n"); while (!feof(fpt)) { fscanf(fpt, "%s", strPY); fscanf(fpt, "%s\n", strPhrase); if (strlen(strPhrase) < 3) continue; ParsePY(&pyconfig, strPY, &strTemp, PY_PARSE_INPUT_SYSTEM, false); s2++; kkk = 0; if (strTemp.iHZCount != fcitx_utf8_strlen(strPhrase) || (strTemp.iMode & PARSE_ABBR)) { fprintf(f, "%s %s\n", strPY, strPhrase); continue; } strMap[0] = '\0'; for (iIndex = 0; iIndex < strTemp.iHZCount; iIndex++) strcat(strMap, strTemp.strMap[iIndex]); for (iIndex = 0; iIndex < iPYFACount; iIndex++) { if (!strncmp(PYFAList[iIndex].strMap, strMap, 2)) { for (i = 0; i < PYFAList[iIndex].iHZCount; i++) { if (!fcitx_utf8_strncmp(PYFAList[iIndex].pyBase[i].strHZ, strPhrase, 1)) { t = PYFAList[iIndex].pyBase[i].phrase; for (j = 0; j < PYFAList[iIndex].pyBase[i].iPhraseCount; j++) { tt = t; t = t->next; if (!strcmp(t->strMap, strMap + 2) && !strcmp(t->strPhrase, strPhrase + fcitx_utf8_char_len(strPhrase))) { printf("\n\t%d: %s %s ----->deleted.\n", s2, strPY, strPhrase); goto _next; } if (strcmp(t->strMap, strMap + 2) > 0) { t = tt; break; } } phrase = (_PyPhrase *) malloc(sizeof(_PyPhrase)); phrase->strPhrase = (char *) malloc(sizeof(char) * (strlen(strPhrase) - fcitx_utf8_char_len(strPhrase) + 1)); phrase->strMap = (char *) malloc(sizeof(char) * ((strTemp.iHZCount - 1) * 2 + 1)); phrase->uIndex = uIndex++; strcpy(phrase->strPhrase, strPhrase + fcitx_utf8_char_len(strPhrase)); strcpy(phrase->strMap, strMap + 2); tt = t->next; t->next = phrase; phrase->next = tt; PYFAList[iIndex].pyBase[i].iPhraseCount++; s1++; kkk = 1; _next: ; } } } } if (!kkk) fprintf(f, "%s %s %s\n", strPY, strPhrase, (char *)(strTemp.strPYParsed)); else fprintf(fg, "%s %s\n", strPY, strPhrase); } printf("%d Phrases, %d Converted!\nWriting Phrase file ...", s2, s1); for (i = 0; i < iPYFACount; i++) { for (j = 0; j < PYFAList[i].iHZCount; j++) { iIndex = PYFAList[i].pyBase[j].iPhraseCount; if (iIndex) { int8_t clen = strlen(PYFAList[i].pyBase[j].strHZ); fwrite(&i, sizeof(int), 1, fp2); fwrite(&clen, sizeof(int8_t), 1, fp2); fwrite(PYFAList[i].pyBase[j].strHZ, sizeof(char) * clen, 1, fp2); fwrite(&iIndex, sizeof(int), 1, fp2); t = PYFAList[i].pyBase[j].phrase->next; for (k = 0; k < PYFAList[i].pyBase[j].iPhraseCount; k++) { int slen = strlen(t->strPhrase); iIndex = strlen(t->strMap); fwrite(&iIndex, sizeof(int), 1, fp2); fwrite(t->strMap, sizeof(char), iIndex, fp2); fwrite(&slen, sizeof(int), 1, fp2); fwrite(t->strPhrase, sizeof(char), strlen(t->strPhrase), fp2); uTemp = uIndex - 1 - t->uIndex; fwrite(&uTemp, sizeof(unsigned int), 1, fp2); t = t->next; } } } } printf("\nOK!\n"); fclose(fp2); fclose(fpt); }
int main(int argc, char *argv[]) { FILE *fpDict, *fpNew; RECORD *temp, *head, *newRec, *current; uint32_t s = 0; int i; uint32_t iTemp; char *pstr = 0; char strTemp[10]; unsigned char bRule; RULE *rule = NULL; unsigned int l; unsigned char iCodeLength = 0; unsigned char iPYCodeLength = 0; int8_t type; if (argc != 3) { printf("\nUsage: txt2mb <Source File> <IM File>\n\n"); exit(1); } fpDict = fopen(argv[1], "r"); if (!fpDict) { printf("\nCannot read source file!\n\n"); exit(2); } head = (RECORD *) malloc(sizeof(RECORD)); head->next = head; head->prev = head; current = head; bRule = 0; l = 0; char* buf = NULL, *buf1 = NULL; size_t len; for (;;) { l++; if (getline(&buf, &len, fpDict) == -1) break; i = strlen(buf) - 1; while ((i >= 0) && (buf[i] == ' ' || buf[i] == '\n' || buf[i] == '\r')) buf[i--] = '\0'; pstr = buf; if (*pstr == ' ') pstr++; if (pstr[0] == '#') continue; if (CHECK_OPTION(pstr, STR_KEYCODE)) { pstr += ADD_LENGTH(pstr, STR_KEYCODE); strcpy(strInputCode, pstr); } else if (CHECK_OPTION(pstr, STR_CODELEN)) { pstr += ADD_LENGTH(pstr, STR_CODELEN); iCodeLength = atoi(pstr); if (iCodeLength > MAX_CODE_LENGTH) { iCodeLength = MAX_CODE_LENGTH; printf("Max Code Length is %d\n", MAX_CODE_LENGTH); } } else if (CHECK_OPTION(pstr, STR_IGNORECHAR)) { pstr += ADD_LENGTH(pstr, STR_IGNORECHAR); strcpy(strIgnoreChars, pstr); } else if (CHECK_OPTION(pstr, STR_PINYIN)) { pstr += ADD_LENGTH(pstr, STR_PINYIN); while (*pstr == ' ' && *pstr != '\0') pstr++; cPinyinKey = *pstr; } else if (CHECK_OPTION(pstr, STR_PROMPT)) { pstr += ADD_LENGTH(pstr, STR_PROMPT); while (*pstr == ' ' && *pstr != '\0') pstr++; cPromptKey = *pstr; } else if (CHECK_OPTION(pstr, STR_CONSTRUCTPHRASE)) { pstr += ADD_LENGTH(pstr, STR_CONSTRUCTPHRASE); while (*pstr == ' ' && *pstr != '\0') pstr++; cPhraseKey = *pstr; } else if (CHECK_OPTION(pstr, STR_PINYINLEN)) { pstr += ADD_LENGTH(pstr, STR_PINYINLEN); iPYCodeLength = atoi(pstr); } else if (CHECK_OPTION(pstr, STR_DATA)) break; else if (CHECK_OPTION(pstr, STR_RULE)) { bRule = 1; break; } } if (iCodeLength <= 0 || !strInputCode[0]) { printf("Source File Format Error!\n"); exit(1); } if (bRule) { /* * 组词规则数应该比键码长度小1 */ rule = (RULE *) malloc(sizeof(RULE) * (iCodeLength - 1)); for (iTemp = 0; iTemp < (iCodeLength - 1); iTemp++) { l++; if (getline(&buf, &len, fpDict) == -1) break; rule[iTemp].rule = (RULE_RULE *) malloc(sizeof(RULE_RULE) * iCodeLength); i = strlen(buf) - 1; while ((i >= 0) && (buf[i] == ' ' || buf[i] == '\n' || buf[i] == '\r')) buf[i--] = '\0'; pstr = buf; if (*pstr == ' ') pstr++; if (pstr[0] == '#') continue; if (CHECK_OPTION(pstr, STR_DATA)) break; switch (*pstr) { case 'e': case 'E': rule[iTemp].iFlag = 0; break; case 'a': case 'A': rule[iTemp].iFlag = 1; break; default: printf("2 Phrase rules are not suitable!\n"); printf("\t\t%s\n", buf); exit(1); } pstr++; char* p = pstr; while (*p && *p != '=') p++; if (!(*p)) { printf("3 Phrase rules are not suitable!\n"); printf("\t\t%s\n", buf); exit(1); } strncpy(strTemp, pstr, p - pstr); strTemp[p - pstr] = '\0'; rule[iTemp].iWords = atoi(strTemp); p++; for (i = 0; i < iCodeLength; i++) { while (*p == ' ') p++; switch (*p) { case 'p': case 'P': rule[iTemp].rule[i].iFlag = 1; break; case 'n': case 'N': rule[iTemp].rule[i].iFlag = 0; break; default: printf("4 Phrase rules are not suitable!\n"); printf("\t\t%s\n", buf); exit(1); } p++; rule[iTemp].rule[i].iWhich = *p++ - '0'; rule[iTemp].rule[i].iIndex = *p++ - '0'; while (*p == ' ') p++; if (i != (iCodeLength - 1)) { if (*p != '+') { printf("5 Phrase rules are not suitable!\n"); printf("\t\t%s %d\n", buf, iCodeLength); exit(1); } p++; } } } if (iTemp != iCodeLength - 1) { printf("6 Phrase rules are not suitable!\n"); exit(1); } for (iTemp = 0; iTemp < (iCodeLength - 1); iTemp++) { l++; if (getline(&buf, &len, fpDict) == -1) break; i = strlen(buf) - 1; while ((i >= 0) && (buf[i] == ' ' || buf[i] == '\n' || buf[i] == '\r')) buf[i--] = '\0'; pstr = buf; if (*pstr == ' ') pstr++; if (pstr[0] == '#') continue; if (CHECK_OPTION(pstr, STR_DATA)) break; } } if (iPYCodeLength < iCodeLength) iPYCodeLength = iCodeLength; if (!CHECK_OPTION(pstr, STR_DATA)) { printf("Source File Format Error!\n"); exit(1); } while (getline(&buf, &len, fpDict) != -1) { l++; if (buf1) free(buf1); buf1 = fcitx_utils_trim(buf); char *p = buf1; while (*p && !isspace(*p)) p ++; if (*p == '\0') continue; while (isspace(*p)) { *p = '\0'; p ++; } char* strHZ = p; if (!IsValidCode(buf1[0])) { printf("Invalid Format: Line-%d %s %s\n", l, buf1, strHZ); exit(1); } if (((buf1[0] != cPinyinKey) && (strlen(buf1) > iCodeLength)) || ((buf1[0] == cPinyinKey) && (strlen(buf1) > (iPYCodeLength + 1))) || ((buf1[0] == cPhraseKey) && (strlen(buf1) > (iCodeLength + 1))) || ((buf1[0] == cPromptKey) && (strlen(buf1) > (iPYCodeLength + 1))) ) { printf("Delete: %s %s, Too long\n", buf1, strHZ); continue; } size_t hzLen = fcitx_utf8_strlen(strHZ); if (buf1[0] == cPhraseKey && hzLen != 1) { printf("Delete: %s %s, Too long\n", buf1, strHZ); continue; } type = RECORDTYPE_NORMAL; pstr = buf1; if (buf1[0] == cPinyinKey) { pstr ++; type = RECORDTYPE_PINYIN; } else if (buf1[0] == cPhraseKey) { pstr ++; type = RECORDTYPE_CONSTRUCT; } else if (buf1[0] == cPromptKey) { pstr ++; type = RECORDTYPE_PROMPT; } //查找是否重复 temp = current; if (temp != head) { if (strcmp(temp->strCode, pstr) >= 0) { while (temp != head && strcmp(temp->strCode, pstr) >= 0) { if (!strcmp(temp->strHZ, strHZ) && !strcmp(temp->strCode, pstr) && temp->type == type) { printf("Delete: %s %s\n", pstr, strHZ); goto _next; } temp = temp->prev; } if (temp == head) temp = temp->next; while (temp != head && strcmp(temp->strCode, pstr) <= 0) temp = temp->next; } else { while (temp != head && strcmp(temp->strCode, pstr) <= 0) { if (!strcmp(temp->strHZ, strHZ) && !strcmp(temp->strCode, pstr) && temp->type == type) { printf("Delete: %s %s\n", pstr, strHZ); goto _next; } temp = temp->next; } } } //插在temp的前面 newRec = (RECORD *) fcitx_utils_malloc0(sizeof(RECORD)); newRec->strCode = (char *) fcitx_utils_malloc0(sizeof(char) * (iPYCodeLength + 1)); newRec->strHZ = (char *) fcitx_utils_malloc0(sizeof(char) * strlen(strHZ) + 1); strcpy(newRec->strCode, pstr); strcpy(newRec->strHZ, strHZ); newRec->type = type; newRec->iHit = 0; newRec->iIndex = 0; temp->prev->next = newRec; newRec->next = temp; newRec->prev = temp->prev; temp->prev = newRec; current = newRec; s++; _next: continue; } if (buf) free(buf); if (buf1) free(buf1); fclose(fpDict); printf("\nReading %d records.\n\n", s); fpNew = fopen(argv[2], "w"); if (!fpNew) { printf("\nCannot create target file!\n\n"); exit(3); } int8_t iInternalVersion = INTERNAL_VERSION; //写入版本号--如果第一个字为0,表示后面那个字节为版本号 fcitx_utils_write_uint32(fpNew, 0); fwrite(&iInternalVersion, sizeof(int8_t), 1, fpNew); iTemp = (uint32_t)strlen(strInputCode); fcitx_utils_write_uint32(fpNew, iTemp); fwrite(strInputCode, sizeof(char), iTemp + 1, fpNew); fwrite(&iCodeLength, sizeof(unsigned char), 1, fpNew); fwrite(&iPYCodeLength, sizeof(unsigned char), 1, fpNew); iTemp = (uint32_t)strlen(strIgnoreChars); fcitx_utils_write_uint32(fpNew, iTemp); fwrite(strIgnoreChars, sizeof(char), iTemp + 1, fpNew); fwrite(&bRule, sizeof(unsigned char), 1, fpNew); if (bRule) { for (i = 0; i < iCodeLength - 1; i++) { fwrite(&(rule[i].iFlag), sizeof(unsigned char), 1, fpNew); fwrite(&(rule[i].iWords), sizeof(unsigned char), 1, fpNew); for (iTemp = 0; iTemp < iCodeLength; iTemp++) { fwrite(&(rule[i].rule[iTemp].iFlag), sizeof(unsigned char), 1, fpNew); fwrite(&(rule[i].rule[iTemp].iWhich), sizeof(unsigned char), 1, fpNew); fwrite(&(rule[i].rule[iTemp].iIndex), sizeof(unsigned char), 1, fpNew); } } } fcitx_utils_write_uint32(fpNew, s); current = head->next; while (current != head) { fwrite(current->strCode, sizeof(char), iPYCodeLength + 1, fpNew); s = strlen(current->strHZ) + 1; fcitx_utils_write_uint32(fpNew, s); fwrite(current->strHZ, sizeof(char), s, fpNew); fwrite(&(current->type), sizeof(int8_t), 1, fpNew); fcitx_utils_write_uint32(fpNew, current->iHit); fcitx_utils_write_uint32(fpNew, current->iIndex); current = current->next; } fclose(fpNew); return 0; }
void XimPreeditCallbackDraw(FcitxXimFrontend* xim, FcitxXimIC* ic, const char* preedit_string, int cursorPos) { XTextProperty tp; uint i, len; if (preedit_string == NULL) return; len = fcitx_utf8_strlen(preedit_string); if (len + 1 > xim->feedback_len) { xim->feedback_len = len + 1; if (xim->feedback) { xim->feedback = realloc(xim->feedback, sizeof(XIMFeedback) * xim->feedback_len); } else { xim->feedback = fcitx_utils_malloc0(sizeof(XIMFeedback) * xim->feedback_len); } } FcitxInputState* input = FcitxInstanceGetInputState(xim->owner); FcitxMessages* clientPreedit = FcitxInputStateGetClientPreedit(input); int offset = 0; for (i = 0; i < FcitxMessagesGetMessageCount(clientPreedit) ; i ++) { int type = FcitxMessagesGetClientMessageType(clientPreedit, i); char* str = FcitxMessagesGetMessageString(clientPreedit, i); int j = 0; XIMFeedback fb = 0; if ((type & MSG_NOUNDERLINE) == 0) fb |= XIMUnderline; if (type & MSG_HIGHLIGHT) fb |= XIMReverse; for (; j < fcitx_utf8_strlen(str); j++) { xim->feedback[offset] = fb; offset ++; } } xim->feedback[len] = 0; IMPreeditCBStruct* pcb = fcitx_utils_new(IMPreeditCBStruct); XIMText* text = fcitx_utils_new(XIMText); pcb->major_code = XIM_PREEDIT_DRAW; pcb->connect_id = ic->connect_id; pcb->icid = ic->id; pcb->todo.draw.caret = fcitx_utf8_strnlen(preedit_string, cursorPos); pcb->todo.draw.chg_first = 0; pcb->todo.draw.chg_length = ic->onspot_preedit_length; pcb->todo.draw.text = text; text->feedback = xim->feedback; Xutf8TextListToTextProperty(xim->display, (char **)&preedit_string, 1, XCompoundTextStyle, &tp); text->encoding_is_wchar = 0; text->length = strlen((char*)tp.value); text->string.multi_byte = (char*)tp.value; XimPendingCall(xim, XCT_CALLCALLBACK, (XPointer) pcb); ic->onspot_preedit_length = len; }
static void _fcitx_im_context_update_formatted_preedit_cb(FcitxClient* im, GPtrArray* array, int cursor_pos, void* user_data) { FcitxLog(LOG_LEVEL, "_fcitx_im_context_commit_string_cb"); FcitxIMContext* context = FCITX_IM_CONTEXT(user_data); gboolean visible = false; if (context->preedit_string != NULL) { if (strlen(context->preedit_string) != 0) visible = true; g_free(context->preedit_string); context->preedit_string = NULL; } if (context->attrlist != NULL) { pango_attr_list_unref(context->attrlist); } context->attrlist = pango_attr_list_new(); GString* gstr = g_string_new(NULL); int i = 0; for (i = 0; i < array->len; i++) { size_t bytelen = strlen(gstr->str); FcitxPreeditItem* preedit = g_ptr_array_index(array, i); const gchar* s = preedit->string; gint type = preedit->type; PangoAttribute *pango_attr = NULL; if ((type & MSG_NOUNDERLINE) == 0) { pango_attr = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE); pango_attr->start_index = bytelen; pango_attr->end_index = bytelen + strlen(s); pango_attr_list_insert(context->attrlist, pango_attr); } if (type & MSG_HIGHLIGHT) { gboolean hasColor; GdkColor fg; GdkColor bg; if (context->client_window) { GtkWidget *widget; gdk_window_get_user_data (context->client_window, (gpointer *)&widget); if (GTK_IS_WIDGET(widget)) { hasColor = true; GtkStyle* style = gtk_widget_get_style(widget); fg = style->text[GTK_STATE_SELECTED]; bg = style->bg[GTK_STATE_SELECTED]; } } if (!hasColor) { fg.red = 0xffff; fg.green = 0xffff; fg.blue = 0xffff; bg.red = 0x43ff; bg.green = 0xacff; bg.blue = 0xe8ff; } pango_attr = pango_attr_foreground_new(fg.red, fg.green, fg.blue); pango_attr->start_index = bytelen; pango_attr->end_index = bytelen + strlen(s); pango_attr_list_insert(context->attrlist, pango_attr); pango_attr = pango_attr_background_new(bg.red, bg.green, bg.blue); pango_attr->start_index = bytelen; pango_attr->end_index = bytelen + strlen(s); pango_attr_list_insert(context->attrlist, pango_attr); } gstr = g_string_append(gstr, s); } gchar* str = g_string_free(gstr, FALSE); context->preedit_string = g_strdup(str); char* tempstr = g_strndup(str, cursor_pos); context->cursor_pos = fcitx_utf8_strlen(tempstr); g_free(tempstr); gboolean new_visible = false; if (context->preedit_string != NULL) { if (strlen(context->preedit_string) != 0) new_visible = true; } gboolean flag = new_visible != visible; if (new_visible) { if (flag) { /* invisible => visible */ g_signal_emit(context, _signal_preedit_start_id, 0); } g_signal_emit(context, _signal_preedit_changed_id, 0); } else { if (flag) { /* visible => invisible */ g_signal_emit(context, _signal_preedit_changed_id, 0); g_signal_emit(context, _signal_preedit_end_id, 0); } else { /* still invisible */ /* do nothing */ } } g_signal_emit(context, _signal_preedit_changed_id, 0); }