static void ChoiceInfoAppendChi( ChewingData *pgdata, ChoiceInfo *pci, uint16_t phone ) { Word tempWord; GetCharFirst( pgdata, &tempWord, phone ); do { if ( ChoiceTheSame( pci, tempWord.word, ueBytesFromChar( tempWord.word[ 0 ] ) * sizeof( char ) ) ) continue; memcpy( pci->totalChoiceStr[ pci->nTotalChoice ], tempWord.word, ueBytesFromChar( tempWord.word[ 0 ] ) * sizeof( char ) ); assert( pci->nTotalChoice <= MAX_CHOICE ); pci->totalChoiceStr[ pci->nTotalChoice ] [ ueBytesFromChar( tempWord.word[ 0 ] ) ] = '\0'; pci->nTotalChoice++; } while ( GetCharNext( pgdata, &tempWord ) ); }
void show_interval_buffer( int x, int y, ChewingContext *ctx ) { char *buf; char *p; int buf_len; char out_buf[ 100 ]; int i, count; int arrPos[ 50 ]; IntervalType it; move( x, y ); addstr( FILL_BLANK ); move( x, y ); /* Check if buffer is available. */ if ( ! chewing_buffer_Check( ctx ) ) { return; } buf = chewing_buffer_String( ctx ); buf_len = chewing_buffer_Len( ctx ); p = buf; count = 0; for ( i = 0 ;i < buf_len; i++ ) { arrPos[ i ] = count; count += ueBytesFromChar(*p) <= 1 ? 1 : 2; p += ueBytesFromChar(*p); } arrPos[ i ] = count; memset( out_buf, ' ', count * ( sizeof( char ) ) ); out_buf[ count ] = '\0'; chewing_interval_Enumerate( ctx ); while ( chewing_interval_hasNext( ctx ) ) { chewing_interval_Get( ctx, &it ); out_buf[ arrPos[ it.from ] ] = '['; out_buf[ arrPos[ it.to ] - 1 ] = ']'; memset( &out_buf[ arrPos[ it.from ] + 1 ], '-', arrPos[ it.to ] - arrPos[ it.from ] - 2 ); } addstr( out_buf ); }
char *ueStrSeek( char *src, size_t n ) { int i = 0; char *iter = src; for ( i = 0; i < n; i++ ) { iter += ueBytesFromChar( iter[0] ); } return iter; }
/* Return byets of a UTF-8 string until n position */ int ueStrNBytes( const char *str, int n ) { int i = 0, len = 0; char *iter = (char *) str; for ( i = 0; i < n; i++ ) { len += ueBytesFromChar( iter[ len ] ); } return len; }
/* Return length of UTF-8 string */ int ueStrLen( char *str ) { int length = 0; char *strptr = str; while ( strptr[ 0 ] != '\0' ) { strptr += ueBytesFromChar( strptr[0] ); ++length; } return length; }
void show_edit_buffer( int x, int y, ChewingContext *ctx ) { int i, cursor, count; char *buffer_string; char *p; move( x, y ); addstr( FILL_BLANK ); if ( ! chewing_buffer_Check( ctx ) ) { move( x, y ); return; } buffer_string = chewing_buffer_String( ctx ); mvaddstr( x, y, buffer_string ); cursor = chewing_cursor_Current( ctx ); p = buffer_string; count = 0; for ( i = 0 ;i < cursor; i++ ) { count += ueBytesFromChar(*p) <= 1 ? 1 : 2; p += ueBytesFromChar(*p); } move( x, count ); free( buffer_string ); }
static void ChoiceInfoAppendChi(ChewingData *pgdata, ChoiceInfo *pci, uint16_t phone) { Phrase tempWord; int len; if (GetCharFirst(pgdata, &tempWord, phone)) { do { len = ueBytesFromChar(tempWord.phrase[0]); if (ChoiceTheSame(pci, tempWord.phrase, len)) continue; assert(pci->nTotalChoice < MAX_CHOICE); memcpy(pci->totalChoiceStr[pci->nTotalChoice], tempWord.phrase, len); pci->totalChoiceStr[pci->nTotalChoice] [len] = '\0'; pci->nTotalChoice++; } while (GetVocabNext(pgdata, &tempWord)); } }
/** @brief Loading all possible phrases of certain length. * * Loading all possible phrases of certain length into ChoiceInfo structure from static * and dynamic dictionaries,\n * including number of total pages and the number of current page.\n */ static void SetChoiceInfo( ChoiceInfo *pci,AvailInfo *pai, uint16 *phoneSeq, int cursor, int candPerPage ) { Word tempWord; Phrase tempPhrase; int len; UserPhraseData *pUserPhraseData; uint16 userPhoneSeq[ MAX_PHONE_SEQ_LEN ]; /* Clears previous candidates. */ memset( pci->totalChoiceStr, '\0', sizeof(char) * MAX_CHOICE * MAX_PHRASE_LEN * MAX_UTF8_SIZE + 1); pci->nTotalChoice = 0; len = pai->avail[ pai->currentAvail ].len; assert(len); /* secondly, read tree phrase */ if ( len == 1 ) { /* single character */ GetCharFirst( &tempWord, phoneSeq[ cursor ] ); do { if ( ChoiceTheSame( pci, tempWord.word, ueBytesFromChar( tempWord.word[0] ) * sizeof( char ) ) ) continue; memcpy( pci->totalChoiceStr[ pci->nTotalChoice ], tempWord.word, ueBytesFromChar( tempWord.word[0] ) * sizeof( char ) ); assert(pci->nTotalChoice <= MAX_CHOICE); pci->totalChoiceStr[ pci->nTotalChoice ][ ueBytesFromChar( tempWord.word[0] ) ] = '\0'; pci->nTotalChoice++; } while( GetCharNext( &tempWord ) ); } /* phrase */ else { if ( pai->avail[ pai->currentAvail ].id != -1 ) { GetPhraseFirst( &tempPhrase, pai->avail[ pai->currentAvail ].id ); do { if ( ChoiceTheSame( pci, tempPhrase.phrase, len * ueBytesFromChar( tempPhrase.phrase[0] ) * sizeof( char ) ) ) { continue; } ueStrNCpy( pci->totalChoiceStr[ pci->nTotalChoice ], tempPhrase.phrase, len, 1); pci->nTotalChoice++; } while( GetPhraseNext( &tempPhrase ) ); } memcpy( userPhoneSeq, &phoneSeq[ cursor ], sizeof( uint16 ) * len ); userPhoneSeq[ len ] = 0; pUserPhraseData = UserGetPhraseFirst( userPhoneSeq ); if ( pUserPhraseData ) { do { /* check if the phrase is already in the choice list */ if ( ChoiceTheSame( pci, pUserPhraseData->wordSeq, len * ueBytesFromChar( pUserPhraseData->wordSeq[0] ) * sizeof( char ) ) ) continue; /* otherwise store it */ ueStrNCpy( pci->totalChoiceStr[ pci->nTotalChoice ], pUserPhraseData->wordSeq, len, 1); pci->nTotalChoice++; } while( ( pUserPhraseData = UserGetPhraseNext( userPhoneSeq ) ) != NULL ); } } /* magic number */ pci->nChoicePerPage = candPerPage; if ( pci->nChoicePerPage > MAX_SELKEY ) pci->nChoicePerPage = MAX_SELKEY; pci->nPage = CEIL_DIV( pci->nTotalChoice, pci->nChoicePerPage ); pci->pageNo = 0; }
/** @brief Loading all possible phrases of certain length. * * Loading all possible phrases of certain length into ChoiceInfo structure * from static and dynamic dictionaries, including number of total pages and * the number of current page. */ static void SetChoiceInfo(ChewingData *pgdata) { Phrase tempPhrase; int len; UserPhraseData *pUserPhraseData; uint16_t userPhoneSeq[MAX_PHONE_SEQ_LEN]; ChoiceInfo *pci = &(pgdata->choiceInfo); AvailInfo *pai = &(pgdata->availInfo); uint16_t *phoneSeq = pgdata->phoneSeq; uint16_t *phoneSeqAlt = pgdata->phoneSeqAlt; int cursor = PhoneSeqCursor(pgdata); int candPerPage = pgdata->config.candPerPage; /* Clears previous candidates. */ memset(pci->totalChoiceStr, '\0', MAX_CHOICE * MAX_PHRASE_LEN * MAX_UTF8_SIZE + 1); pci->nTotalChoice = 0; len = pai->avail[pai->currentAvail].len; assert(len); /* secondly, read tree phrase */ if (len == 1) { /* single character */ ChoiceInfoAppendChi(pgdata, pci, phoneSeq[cursor]); if (phoneSeq[cursor] != phoneSeqAlt[cursor]) { ChoiceInfoAppendChi(pgdata, pci, phoneSeqAlt[cursor]); } if (pgdata->bopomofoData.kbtype == KB_HSU || pgdata->bopomofoData.kbtype == KB_DVORAK_HSU) { switch (phoneSeq[cursor]) { case 0x2800: /* 'ㄘ' */ ChoiceInfoAppendChi(pgdata, pci, 0x30); /* 'ㄟ' */ break; case 0x80: /* 'ㄧ' */ ChoiceInfoAppendChi(pgdata, pci, 0x20); /* 'ㄝ' */ break; case 0x2A00: /* 'ㄙ' */ ChoiceInfoAppendChi(pgdata, pci, 0x1); /* '˙' */ break; case 0xA00: /* 'ㄉ' */ ChoiceInfoAppendChi(pgdata, pci, 0x2); /* 'ˊ' */ break; case 0x800: /* 'ㄈ' */ ChoiceInfoAppendChi(pgdata, pci, 0x3); /* 'ˇ' */ break; case 0x18: /* 'ㄜ' */ ChoiceInfoAppendChi(pgdata, pci, 0x1200); /* 'ㄍ' */ break; case 0x10: /* 'ㄛ' */ ChoiceInfoAppendChi(pgdata, pci, 0x1600); /* 'ㄏ' */ break; case 0x1E00: /* 'ㄓ' */ ChoiceInfoAppendChi(pgdata, pci, 0x1800); /* 'ㄐ' */ ChoiceInfoAppendChi(pgdata, pci, 0x4); /* 'ˋ' */ break; case 0x58: /* 'ㄤ' */ ChoiceInfoAppendChi(pgdata, pci, 0x1400); /* 'ㄎ' */ break; case 0x68: /* 'ㄦ' */ ChoiceInfoAppendChi(pgdata, pci, 0x1000); /* 'ㄌ' */ ChoiceInfoAppendChi(pgdata, pci, 0x60); /* 'ㄥ' */ break; case 0x2200: /* 'ㄕ' */ ChoiceInfoAppendChi(pgdata, pci, 0x1C00); /* 'ㄒ' */ break; case 0x2000: /* 'ㄔ' */ ChoiceInfoAppendChi(pgdata, pci, 0x1A00); /* 'ㄑ' */ break; case 0x50: /* 'ㄣ' */ ChoiceInfoAppendChi(pgdata, pci, 0xE00); /* 'ㄋ' */ break; case 0x48: /* 'ㄢ' */ ChoiceInfoAppendChi(pgdata, pci, 0x600); /* 'ㄇ' */ break; default: break; } } } /* phrase */ else { if (pai->avail[pai->currentAvail].id) { GetPhraseFirst(pgdata, &tempPhrase, pai->avail[pai->currentAvail].id); do { if (ChoiceTheSame(pci, tempPhrase.phrase, len * ueBytesFromChar(tempPhrase.phrase[0]))) { continue; } ueStrNCpy(pci->totalChoiceStr[pci->nTotalChoice], tempPhrase.phrase, len, 1); pci->nTotalChoice++; } while (GetVocabNext(pgdata, &tempPhrase)); } memcpy(userPhoneSeq, &phoneSeq[cursor], sizeof(uint16_t) * len); userPhoneSeq[len] = 0; pUserPhraseData = UserGetPhraseFirst(pgdata, userPhoneSeq); if (pUserPhraseData) { do { /* check if the phrase is already in the choice list */ if (ChoiceTheSame(pci, pUserPhraseData->wordSeq, len * ueBytesFromChar(pUserPhraseData->wordSeq[0]))) continue; /* otherwise store it */ ueStrNCpy(pci->totalChoiceStr[pci->nTotalChoice], pUserPhraseData->wordSeq, len, 1); pci->nTotalChoice++; } while ((pUserPhraseData = UserGetPhraseNext(pgdata, userPhoneSeq)) != NULL); } UserGetPhraseEnd(pgdata, userPhoneSeq); } /* magic number */ pci->nChoicePerPage = candPerPage; assert(pci->nTotalChoice > 0); pci->nPage = CEIL_DIV(pci->nTotalChoice, pci->nChoicePerPage); pci->pageNo = 0; pci->isSymbol = WORD_CHOICE; }