diff options
author | Choe Hwanjin <choe.hwanjin@gmail.com> | 2006-02-17 19:22:48 +0900 |
---|---|---|
committer | Choe Hwanjin <choe.hwanjin@gmail.com> | 2006-02-17 19:22:48 +0900 |
commit | 6867c770de3ab39ce4b4ed57cb93df923c8dfaf7 (patch) | |
tree | 1f6cc299219ed68734c50580b701e7373c4fbd98 | |
parent | 03c9b1fbaacb6bdfdce1dfeed1507a4387e7fb50 (diff) | |
download | libhangul-6867c770de3ab39ce4b4ed57cb93df923c8dfaf7.tar.gz |
add hangul_ic_set_filter() function
git-svn-id: http://kldp.net/svn/hangul/libhangul/trunk@52 8f00fcd2-89fc-0310-932e-b01be5b65e01
-rw-r--r-- | hangul/hangul.h | 11 | ||||
-rw-r--r-- | hangul/hangulinputcontext.c | 155 | ||||
-rw-r--r-- | test/test.c | 22 |
3 files changed, 145 insertions, 43 deletions
diff --git a/hangul/hangul.h b/hangul/hangul.h index 8fab484..5eea125 100644 --- a/hangul/hangul.h +++ b/hangul/hangul.h @@ -59,8 +59,9 @@ ucschar hangul_jaso_to_syllable(ucschar choseong, /* hangulinputcontext.c */ typedef struct _HangulJamoCombination HangulJamoCombination; -typedef struct _HangulBuffer HangulBuffer; -typedef struct _HangulInputContext HangulInputContext; +typedef struct _HangulBuffer HangulBuffer; +typedef struct _HangulInputContext HangulInputContext; +typedef bool (*HangulICFilter) (ucschar, ucschar, ucschar, void*); typedef enum { HANGUL_KEYBOARD_2, @@ -101,6 +102,8 @@ struct _HangulInputContext { const HangulJamoCombination *combination_table; int combination_table_size; HangulBuffer buffer; + HangulICFilter filter; + void *filter_data; int output_mode; ucschar preedit_string[64]; @@ -113,10 +116,14 @@ bool hangul_ic_process(HangulInputContext *hic, int ascii); void hangul_ic_reset(HangulInputContext *hic); void hangul_ic_flush(HangulInputContext *hic); bool hangul_ic_backspace(HangulInputContext *hic); +bool hangul_ic_is_empty(HangulInputContext *hic); void hangul_ic_set_output_mode(HangulInputContext *hic, int mode); void hangul_ic_set_keyboard(HangulInputContext *hic, HangulKeyboardType keyboard); +void hangul_ic_set_filter(HangulInputContext *hic, + HangulICFilter func, void *user_data); + const ucschar* hangul_ic_get_preedit_string(HangulInputContext *hic); const ucschar* hangul_ic_get_commit_string(HangulInputContext *hic); diff --git a/hangul/hangulinputcontext.c b/hangul/hangulinputcontext.c index 63470b5..e8b15ae 100644 --- a/hangul/hangulinputcontext.c +++ b/hangul/hangulinputcontext.c @@ -36,9 +36,17 @@ static void hangul_buffer_clear(HangulBuffer *buffer); static int hangul_buffer_get_string(HangulBuffer *buffer, ucschar*buf, int buflen); static int hangul_buffer_get_jamo_string(HangulBuffer *buffer, ucschar *buf, int buflen); +static void hangul_ic_flush_internal(HangulInputContext *hic); static ucschar hangul_ic_translate_jamo(HangulInputContext *hic, int ascii); static ucschar hangul_ic_combine_jamo(HangulInputContext *hic, ucschar first, ucschar second); +static bool +hangul_buffer_is_empty(HangulBuffer *buffer) +{ + return buffer->choseong == 0 && buffer->jungseong == 0 && + buffer->jongseong == 0; +} + static void hangul_buffer_push(HangulBuffer *buffer, ucschar ch) { @@ -234,10 +242,36 @@ hangul_ic_combine_jamo(HangulInputContext *hic, ucschar first, ucschar second) return 0; } -static inline void +static inline bool hangul_ic_push(HangulInputContext *hic, ucschar ch) { + if (hic->filter != NULL) { + ucschar cho, jung, jong; + if (hangul_is_choseong(ch)) { + cho = ch; + jung = hic->buffer.jungseong; + jong = hic->buffer.jungseong; + } else if (hangul_is_jungseong(ch)) { + cho = hic->buffer.choseong; + jung = ch; + jong = hic->buffer.jongseong; + } else if (hangul_is_jongseong(ch)) { + cho = hic->buffer.choseong; + jung = hic->buffer.jungseong; + jong = ch; + } else { + hangul_ic_flush_internal(hic); + return false; + } + + if (!hic->filter(cho, jung, jong, hic->filter_data)) { + hangul_ic_flush_internal(hic); + return false; + } + } + hangul_buffer_push(&hic->buffer, ch); + return true; } static inline ucschar @@ -285,15 +319,22 @@ hangul_ic_append_commit_string(HangulInputContext *hic, ucschar ch) static inline void hangul_ic_save_commit_string(HangulInputContext *hic) { + ucschar *string = hic->commit_string; + int len = N_ELEMENTS(hic->commit_string); + + while (len > 0) { + if (*string == 0) + break; + len--; + string++; + } + if (hic->output_mode == HANGUL_OUTPUT_JAMO) { - hangul_buffer_get_jamo_string(&hic->buffer, - hic->commit_string, - N_ELEMENTS(hic->commit_string)); + hangul_buffer_get_jamo_string(&hic->buffer, string, len); } else { - hangul_buffer_get_string(&hic->buffer, - hic->commit_string, - N_ELEMENTS(hic->commit_string)); + hangul_buffer_get_string(&hic->buffer, string, len); } + hangul_buffer_clear(&hic->buffer); } @@ -309,10 +350,16 @@ hangul_ic_process_jamo(HangulInputContext *hic, ucschar ch) combined = hangul_ic_combine_jamo(hic, hic->buffer.jongseong, jong); if (hangul_is_jongseong(combined)) { - hangul_ic_push(hic, combined); + if (!hangul_ic_push(hic, combined)) { + if (!hangul_ic_push(hic, ch)) { + return false; + } + } } else { hangul_ic_save_commit_string(hic); - hangul_ic_push(hic, ch); + if (!hangul_ic_push(hic, ch)) { + return false; + } } } else if (hangul_is_jungseong(ch)) { ucschar pop, peek; @@ -323,7 +370,9 @@ hangul_ic_process_jamo(HangulInputContext *hic, ucschar ch) hic->buffer.jongseong = 0; hangul_ic_save_commit_string(hic); hangul_ic_push(hic, hangul_jongseong_to_choseong(pop)); - hangul_ic_push(hic, ch); + if (!hangul_ic_push(hic, ch)) { + return false; + } } else { ucschar choseong = 0, jongseong = 0; hangul_jongseong_dicompose(hic->buffer.jongseong, @@ -331,64 +380,74 @@ hangul_ic_process_jamo(HangulInputContext *hic, ucschar ch) hic->buffer.jongseong = jongseong; hangul_ic_save_commit_string(hic); hangul_ic_push(hic, choseong); - hangul_ic_push(hic, ch); + if (!hangul_ic_push(hic, ch)) { + return false; + } } } else { - goto none_hangul; + goto flush; } } else if (hic->buffer.jungseong) { if (hangul_is_choseong(ch)) { if (hic->buffer.choseong) { jong = hangul_choseong_to_jongseong(ch); if (hangul_is_jongseong(jong)) { - hangul_ic_push(hic, jong); + if (!hangul_ic_push(hic, jong)) { + if (!hangul_ic_push(hic, ch)) { + return false; + } + } } else { hangul_ic_save_commit_string(hic); - hangul_ic_push(hic, ch); + if (!hangul_ic_push(hic, ch)) { + return false; + } } } else { - hangul_ic_push(hic, ch); + if (!hangul_ic_push(hic, ch)) { + return false; + } } } else if (hangul_is_jungseong(ch)) { combined = hangul_ic_combine_jamo(hic, hic->buffer.jungseong, ch); if (hangul_is_jungseong(combined)) { - hangul_ic_push(hic, combined); + if (!hangul_ic_push(hic, combined)) { + return false; + } } else { hangul_ic_save_commit_string(hic); - hangul_ic_push(hic, ch); + if (!hangul_ic_push(hic, ch)) { + return false; + } } } else { - goto none_hangul; + goto flush; } } else if (hic->buffer.choseong) { if (hangul_is_choseong(ch)) { combined = hangul_ic_combine_jamo(hic, hic->buffer.choseong, ch); - if (hangul_is_choseong(combined)) { - hangul_ic_push(hic, combined); - } else { - hangul_ic_save_commit_string(hic); - hangul_ic_push(hic, ch); + if (!hangul_ic_push(hic, combined)) { + if (!hangul_ic_push(hic, ch)) { + return false; + } } - } else if (hangul_is_jungseong(ch)) { - hangul_ic_push(hic, ch); } else { - goto none_hangul; + if (!hangul_ic_push(hic, ch)) { + return false; + } } } else { - if (hangul_is_choseong(ch)) { - hangul_ic_push(hic, ch); - } else if (hangul_is_jungseong(ch)) { - hangul_ic_push(hic, ch); - } else { - goto none_hangul; + if (!hangul_ic_push(hic, ch)) { + return false; } } hangul_ic_save_preedit_string(hic); return true; +flush: none_hangul: - hangul_ic_save_commit_string(hic); + hangul_ic_flush_internal(hic); return false; } @@ -504,14 +563,24 @@ hangul_ic_reset(HangulInputContext *hic) hangul_buffer_clear(&hic->buffer); } +/* this function does not clear previously made commit string */ +static void +hangul_ic_flush_internal(HangulInputContext *hic) +{ + hic->preedit_string[0] = 0; + + hangul_ic_save_commit_string(hic); + hangul_buffer_clear(&hic->buffer); +} + void hangul_ic_flush(HangulInputContext *hic) { if (hic == NULL) return; - hic->preedit_string[0] = 0; - hangul_ic_save_commit_string(hic); + hic->commit_string[0] = 0; + hangul_ic_flush_internal(hic); } bool @@ -528,6 +597,12 @@ hangul_ic_backspace(HangulInputContext *hic) return ret; } +bool +hangul_ic_is_empty(HangulInputContext *hic) +{ + return hangul_buffer_is_empty(&hic->buffer); +} + void hangul_ic_set_output_mode(HangulInputContext *hic, int mode) { @@ -538,6 +613,16 @@ hangul_ic_set_output_mode(HangulInputContext *hic, int mode) hic->output_mode = mode; } +void hangul_ic_set_filter(HangulInputContext *hic, + HangulICFilter func, void *user_data) +{ + if (hic == NULL) + return; + + hic->filter = func; + hic->filter_data = user_data; +} + void hangul_ic_set_keyboard(HangulInputContext *hic, HangulKeyboardType keyboard) { diff --git a/test/test.c b/test/test.c index a013e1e..306a265 100644 --- a/test/test.c +++ b/test/test.c @@ -6,6 +6,13 @@ #include "../hangul/hangul.h" +bool filter(ucschar cho, ucschar jung, ucschar jong, void *data) +{ + //printf("Filter: %x %x %x\n", cho, jung, jong); + //return jong == 0; + return true; +} + int main(int argc, char *argv[]) { @@ -27,6 +34,7 @@ main(int argc, char *argv[]) printf("hic is null\n"); return -1; } + hangul_ic_set_filter(hic, filter, NULL); for (ascii = getchar(); ascii != EOF; ascii = getchar()) { int ret = hangul_ic_process(hic, ascii); @@ -40,12 +48,14 @@ main(int argc, char *argv[]) printf("%c", ascii); } } - hangul_ic_flush(hic); - commit_string = (wchar_t*)hangul_ic_get_commit_string(hic); - n = wcstombs(commit, commit_string, sizeof(commit)); - commit[n] = '\0'; - if (strlen(commit) > 0) { - printf("%s", commit); + if (!hangul_ic_is_empty(hic)) { + hangul_ic_flush(hic); + commit_string = (wchar_t*)hangul_ic_get_commit_string(hic); + n = wcstombs(commit, commit_string, sizeof(commit)); + commit[n] = '\0'; + if (strlen(commit) > 0) { + printf("%s", commit); + } } hangul_ic_delete(hic); |