/* find the maximum frequency of the same phrase */ static int LoadMaxFreq( const uint16 phoneSeq[], int len ) { int pho_id; Phrase *phrase = ALC( Phrase, 1 ); int maxFreq = FREQ_INIT_VALUE; UserPhraseData *uphrase; pho_id = TreeFindPhrase( 0, len - 1, phoneSeq ); if ( pho_id != -1 ) { GetPhraseFirst( phrase, pho_id ); do { if ( phrase->freq > maxFreq ) maxFreq = phrase->freq; } while( GetPhraseNext( phrase ) ); } free( phrase ); uphrase = UserGetPhraseFirst( phoneSeq ); while ( uphrase ) { if ( uphrase->userfreq > maxFreq ) maxFreq = uphrase->userfreq; uphrase = UserGetPhraseNext( phoneSeq ); } return maxFreq; }
/* * phrase is said to satisfy a choose interval if * their intersections are the same */ static int CheckChoose( ChewingData *pgdata, int ph_id, int from, int to, Phrase **pp_phr, char selectStr[][ MAX_PHONE_SEQ_LEN * MAX_UTF8_SIZE + 1 ], IntervalType selectInterval[], int nSelect ) { IntervalType inte, c; int chno, len; Phrase *phrase = ALC( Phrase, 1 ); assert( phrase ); inte.from = from; inte.to = to; *pp_phr = NULL; /* if there exist one phrase satisfied all selectStr then return 1, else return 0. */ GetPhraseFirst( pgdata, phrase, ph_id ); do { for ( chno = 0; chno < nSelect; chno++ ) { c = selectInterval[ chno ]; if ( IsContain( inte, c ) ) { /* find a phrase of ph_id where the text contains * 'selectStr[chno]' test if not ok then return 0, if ok * then continue to test */ len = c.to - c.from; if ( memcmp( ueStrSeek( phrase->phrase, c.from - from ), selectStr[ chno ], ueStrNBytes( selectStr[ chno ], len ) ) ) break; } else if ( IsIntersect( inte, selectInterval[ chno ] ) ) { free( phrase ); return 0; } } if ( chno == nSelect ) { *pp_phr = phrase; return 1; } } while ( GetPhraseNext( pgdata, phrase ) ); free( phrase ); return 0; }
/* load the orginal frequency from the static dict */ static int LoadOriginalFreq( const uint16 phoneSeq[], const char wordSeq[], int len ) { int pho_id; int retval; Phrase *phrase = ALC( Phrase, 1 ); pho_id = TreeFindPhrase( 0, len - 1, phoneSeq ); if ( pho_id != -1 ) { GetPhraseFirst( phrase, pho_id ); do { /* find the same phrase */ if ( ! strcmp( phrase->phrase, wordSeq ) ) { retval = phrase->freq; free( phrase ); return retval; } } while ( GetPhraseNext( phrase ) ); } free( phrase ); return FREQ_INIT_VALUE; }
/** @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; int cursor = PhoneSeqCursor( pgdata ); int candPerPage = pgdata->config.candPerPage; /* 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 */ ChoiceInfoAppendChi( pgdata, pci, phoneSeq[cursor] ); if ( pgdata->zuinData.kbtype == KB_HSU || pgdata->zuinData.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 != -1 ) { GetPhraseFirst( pgdata, &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( 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] ) * sizeof( char ) ) ) continue; /* otherwise store it */ ueStrNCpy( pci->totalChoiceStr[ pci->nTotalChoice ], pUserPhraseData->wordSeq, len, 1); pci->nTotalChoice++; } while ( ( pUserPhraseData = UserGetPhraseNext( pgdata, userPhoneSeq ) ) != NULL ); } } /* magic number */ pci->nChoicePerPage = candPerPage; pci->nPage = CEIL_DIV( pci->nTotalChoice, pci->nChoicePerPage ); pci->pageNo = 0; }