static bool hangul_buffer_backspace(HangulBuffer *buffer) { if (buffer->index >= 0) { ucschar ch = hangul_buffer_pop(buffer); if (ch == 0) return false; if (buffer->index >= 0) { if (hangul_is_choseong(ch)) { ch = hangul_buffer_peek(buffer); buffer->choseong = hangul_is_choseong(ch) ? ch : 0; return true; } else if (hangul_is_jungseong(ch)) { ch = hangul_buffer_peek(buffer); buffer->jungseong = hangul_is_jungseong(ch) ? ch : 0; return true; } else if (hangul_is_jongseong(ch)) { ch = hangul_buffer_peek(buffer); buffer->jongseong = hangul_is_jongseong(ch) ? ch : 0; return true; } } else { buffer->choseong = 0; buffer->jungseong = 0; buffer->jongseong = 0; return true; } } return false; }
static ucschar hangul_ic_combine(HangulInputContext* hic, ucschar first, ucschar second) { if (!hic->option_combi_on_double_stroke) { if (hangul_keyboard_get_type(hic->keyboard) == HANGUL_KEYBOARD_TYPE_JAMO) { /* 옛한글은 아래 규칙을 적용하지 않아야 입력가능한 글자가 있으므로 * 적용하지 않는다. */ if (first == second && hangul_is_jamo_conjoinable(first)) { return 0; } } } ucschar combined = 0; combined = hangul_keyboard_combine(hic->keyboard, 0, first, second); if (!hic->option_non_choseong_combi) { if (hangul_is_choseong(first) && hangul_is_choseong(second) && hangul_is_jongseong(combined)) { return 0; } } return combined; }
static void hangul_buffer_push(HangulBuffer *buffer, ucschar ch) { if (hangul_is_choseong(ch)) { buffer->choseong = ch; } else if (hangul_is_jungseong(ch)) { buffer->jungseong = ch; } else if (hangul_is_jongseong(ch)) { buffer->jongseong = ch; } else { } buffer->stack[++buffer->index] = ch; }
static inline bool hangul_ic_push(HangulInputContext *hic, ucschar c) { ucschar buf[64] = { 0, }; if (hic->on_transition != NULL) { ucschar cho, jung, jong; if (hangul_is_choseong(c)) { cho = c; jung = hic->buffer.jungseong; jong = hic->buffer.jongseong; } else if (hangul_is_jungseong(c)) { cho = hic->buffer.choseong; jung = c; jong = hic->buffer.jongseong; } else if (hangul_is_jongseong(c)) { cho = hic->buffer.choseong; jung = hic->buffer.jungseong; jong = c; } else { hangul_ic_flush_internal(hic); return false; } hangul_jaso_to_string(cho, jung, jong, buf, N_ELEMENTS(buf)); if (!hic->on_transition(hic, c, buf, hic->on_transition_data)) { hangul_ic_flush_internal(hic); return false; } } else { if (!hangul_is_jamo(c)) { hangul_ic_flush_internal(hic); return false; } } hangul_buffer_push(&hic->buffer, c); return true; }
static bool hangul_ic_process_romaja(HangulInputContext *hic, int ascii, ucschar ch) { ucschar jong; ucschar combined; if (!hangul_is_jamo(ch) && ch > 0) { hangul_ic_save_commit_string(hic); hangul_ic_append_commit_string(hic, ch); return true; } if (isupper(ascii)) { hangul_ic_save_commit_string(hic); } if (hic->buffer.jongseong) { if (ascii == 'x' || ascii == 'X') { ch = 0x110c; hangul_ic_save_commit_string(hic); if (!hangul_ic_push(hic, ch)) { return false; } } else if (hangul_is_choseong(ch) || hangul_is_jongseong(ch)) { if (hangul_is_jongseong(ch)) jong = ch; else jong = hangul_choseong_to_jongseong(ch); combined = hangul_combination_combine(hic->combination, hic->buffer.jongseong, jong); if (hangul_is_jongseong(combined)) { if (!hangul_ic_push(hic, combined)) { if (!hangul_ic_push(hic, ch)) { return false; } } } else { hangul_ic_save_commit_string(hic); if (!hangul_ic_push(hic, ch)) { return false; } } } else if (hangul_is_jungseong(ch)) { if (hic->buffer.jongseong == 0x11bc) { hangul_ic_save_commit_string(hic); hic->buffer.choseong = 0x110b; hangul_ic_push(hic, ch); } else { ucschar pop, peek; pop = hangul_ic_pop(hic); peek = hangul_ic_peek(hic); if (hangul_is_jungseong(peek)) { if (pop == 0x11aa) { hic->buffer.jongseong = 0x11a8; } else { hic->buffer.jongseong = 0; } hangul_ic_save_commit_string(hic); hangul_ic_push(hic, hangul_jongseong_to_choseong(pop)); if (!hangul_ic_push(hic, ch)) { return false; } } else { ucschar choseong = 0, jongseong = 0; hangul_jongseong_dicompose(hic->buffer.jongseong, &jongseong, &choseong); hic->buffer.jongseong = jongseong; hangul_ic_save_commit_string(hic); hangul_ic_push(hic, choseong); if (!hangul_ic_push(hic, ch)) { return false; } } } } else { 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)) { if (!hangul_ic_push(hic, jong)) { if (!hangul_ic_push(hic, ch)) { return false; } } } else { hangul_ic_save_commit_string(hic); if (!hangul_ic_push(hic, ch)) { return false; } } } else { if (!hangul_ic_push(hic, ch)) { if (!hangul_ic_push(hic, ch)) { return false; } } } } else if (hangul_is_jungseong(ch)) { combined = hangul_combination_combine(hic->combination, hic->buffer.jungseong, ch); if (hangul_is_jungseong(combined)) { if (!hangul_ic_push(hic, combined)) { return false; } } else { hangul_ic_save_commit_string(hic); hic->buffer.choseong = 0x110b; if (!hangul_ic_push(hic, ch)) { return false; } } } else if (hangul_is_jongseong(ch)) { if (!hangul_ic_push(hic, ch)) { if (!hangul_ic_push(hic, ch)) { return false; } } } else { goto flush; } } else if (hic->buffer.choseong) { if (hangul_is_choseong(ch)) { combined = hangul_combination_combine(hic->combination, hic->buffer.choseong, ch); if (combined == 0) { hic->buffer.jungseong = 0x1173; hangul_ic_flush_internal(hic); if (!hangul_ic_push(hic, ch)) { return false; } } else { if (!hangul_ic_push(hic, combined)) { if (!hangul_ic_push(hic, ch)) { return false; } } } } else if (hangul_is_jongseong(ch)) { hic->buffer.jungseong = 0x1173; hangul_ic_save_commit_string(hic); if (ascii == 'x' || ascii == 'X') ch = 0x110c; if (!hangul_ic_push(hic, ch)) { return false; } } else { if (!hangul_ic_push(hic, ch)) { if (!hangul_ic_push(hic, ch)) { return false; } } } } else { if (ascii == 'x' || ascii == 'X') { ch = 0x110c; } if (!hangul_ic_push(hic, ch)) { return false; } else { if (hic->buffer.choseong == 0 && hic->buffer.jungseong != 0) hic->buffer.choseong = 0x110b; } } hangul_ic_save_preedit_string(hic); return true; flush: hangul_ic_flush_internal(hic); return false; }
static bool hangul_ic_process_jaso(HangulInputContext *hic, ucschar ch) { if (hangul_is_choseong(ch)) { if (hic->buffer.choseong == 0) { if (!hangul_ic_push(hic, ch)) { if (!hangul_ic_push(hic, ch)) { return false; } } } else { ucschar choseong = 0; if (hangul_is_choseong(hangul_ic_peek(hic))) { choseong = hangul_combination_combine(hic->combination, hic->buffer.choseong, ch); } if (choseong) { if (!hangul_ic_push(hic, choseong)) { if (!hangul_ic_push(hic, choseong)) { return false; } } } else { hangul_ic_save_commit_string(hic); if (!hangul_ic_push(hic, ch)) { return false; } } } } else if (hangul_is_jungseong(ch)) { if (hic->buffer.jungseong == 0) { if (!hangul_ic_push(hic, ch)) { if (!hangul_ic_push(hic, ch)) { return false; } } } else { ucschar jungseong = 0; if (hangul_is_jungseong(hangul_ic_peek(hic))) { jungseong = hangul_combination_combine(hic->combination, hic->buffer.jungseong, ch); } if (jungseong) { if (!hangul_ic_push(hic, jungseong)) { if (!hangul_ic_push(hic, jungseong)) { return false; } } } else { hangul_ic_save_commit_string(hic); if (!hangul_ic_push(hic, ch)) { if (!hangul_ic_push(hic, ch)) { return false; } } } } } else if (hangul_is_jongseong(ch)) { if (hic->buffer.jongseong == 0) { if (!hangul_ic_push(hic, ch)) { if (!hangul_ic_push(hic, ch)) { return false; } } } else { ucschar jongseong = 0; if (hangul_is_jongseong(hangul_ic_peek(hic))) { jongseong = hangul_combination_combine(hic->combination, hic->buffer.jongseong, ch); } if (jongseong) { if (!hangul_ic_push(hic, jongseong)) { if (!hangul_ic_push(hic, jongseong)) { return false; } } } else { hangul_ic_save_commit_string(hic); if (!hangul_ic_push(hic, ch)) { if (!hangul_ic_push(hic, ch)) { return false; } } } } } else if (ch > 0) { hangul_ic_save_commit_string(hic); hangul_ic_append_commit_string(hic, ch); } else { hangul_ic_save_commit_string(hic); return false; } hangul_ic_save_preedit_string(hic); return true; }
static bool hangul_ic_process_jamo(HangulInputContext *hic, ucschar ch) { ucschar jong; ucschar combined; if (!hangul_is_jamo(ch) && ch > 0) { hangul_ic_save_commit_string(hic); hangul_ic_append_commit_string(hic, ch); return true; } if (hic->buffer.jongseong) { if (hangul_is_choseong(ch)) { jong = hangul_choseong_to_jongseong(ch); combined = hangul_combination_combine(hic->combination, hic->buffer.jongseong, jong); if (hangul_is_jongseong(combined)) { if (!hangul_ic_push(hic, combined)) { if (!hangul_ic_push(hic, ch)) { return false; } } } else { hangul_ic_save_commit_string(hic); if (!hangul_ic_push(hic, ch)) { return false; } } } else if (hangul_is_jungseong(ch)) { ucschar pop, peek; pop = hangul_ic_pop(hic); peek = hangul_ic_peek(hic); if (hangul_is_jungseong(peek)) { hic->buffer.jongseong = 0; hangul_ic_save_commit_string(hic); hangul_ic_push(hic, hangul_jongseong_to_choseong(pop)); if (!hangul_ic_push(hic, ch)) { return false; } } else { ucschar choseong = 0, jongseong = 0; hangul_jongseong_dicompose(hic->buffer.jongseong, &jongseong, &choseong); hic->buffer.jongseong = jongseong; hangul_ic_save_commit_string(hic); hangul_ic_push(hic, choseong); if (!hangul_ic_push(hic, ch)) { return false; } } } else { 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)) { if (!hangul_ic_push(hic, jong)) { if (!hangul_ic_push(hic, ch)) { return false; } } } else { hangul_ic_save_commit_string(hic); if (!hangul_ic_push(hic, ch)) { return false; } } } else { if (!hangul_ic_push(hic, ch)) { if (!hangul_ic_push(hic, ch)) { return false; } } } } else if (hangul_is_jungseong(ch)) { combined = hangul_combination_combine(hic->combination, hic->buffer.jungseong, ch); if (hangul_is_jungseong(combined)) { if (!hangul_ic_push(hic, combined)) { return false; } } else { hangul_ic_save_commit_string(hic); if (!hangul_ic_push(hic, ch)) { return false; } } } else { goto flush; } } else if (hic->buffer.choseong) { if (hangul_is_choseong(ch)) { combined = hangul_combination_combine(hic->combination, hic->buffer.choseong, ch); if (!hangul_ic_push(hic, combined)) { if (!hangul_ic_push(hic, ch)) { return false; } } } else { if (!hangul_ic_push(hic, ch)) { if (!hangul_ic_push(hic, ch)) { return false; } } } } else { if (!hangul_ic_push(hic, ch)) { return false; } } hangul_ic_save_preedit_string(hic); return true; flush: hangul_ic_flush_internal(hic); return false; }
static bool hangul_ic_process_jamo(HangulInputContext *hic, ucschar ch) { ucschar jong; ucschar combined; if (!hangul_is_jamo(ch) && ch > 0) { hangul_ic_save_commit_string(hic); hangul_ic_append_commit_string(hic, ch); return true; } if (hic->buffer.jongseong) { if (hangul_is_choseong(ch)) { jong = hangul_ic_choseong_to_jongseong(hic, ch); combined = hangul_ic_combine(hic, hic->buffer.jongseong, jong); if (hangul_is_jongseong(combined)) { if (!hangul_ic_push(hic, combined)) { if (!hangul_ic_push(hic, ch)) { return false; } } } else { hangul_ic_save_commit_string(hic); if (!hangul_ic_push(hic, ch)) { return false; } } } else if (hangul_is_jungseong(ch)) { ucschar pop, peek; pop = hangul_ic_pop(hic); peek = hangul_ic_peek(hic); if (hangul_is_jongseong(peek)) { ucschar choseong = hangul_jongseong_get_diff(peek, hic->buffer.jongseong); if (choseong == 0) { hangul_ic_save_commit_string(hic); if (!hangul_ic_push(hic, ch)) { return false; } } else { hic->buffer.jongseong = peek; hangul_ic_save_commit_string(hic); hangul_ic_push(hic, choseong); if (!hangul_ic_push(hic, ch)) { return false; } } } else { hic->buffer.jongseong = 0; hangul_ic_save_commit_string(hic); hangul_ic_push(hic, hangul_jongseong_to_choseong(pop)); if (!hangul_ic_push(hic, ch)) { return false; } } } else { goto flush; } } else if (hic->buffer.jungseong) { if (hangul_is_choseong(ch)) { if (hic->buffer.choseong) { jong = hangul_ic_choseong_to_jongseong(hic, ch); if (hangul_is_jongseong(jong)) { if (!hangul_ic_push(hic, jong)) { if (!hangul_ic_push(hic, ch)) { return false; } } } else { hangul_ic_save_commit_string(hic); if (!hangul_ic_push(hic, ch)) { return false; } } } else { if (hic->option_auto_reorder) { /* kr 처럼 자모가 역순인 경우 처리 */ if (!hangul_ic_push(hic, ch)) { if (!hangul_ic_push(hic, ch)) { return false; } } } else { hangul_ic_save_commit_string(hic); if (!hangul_ic_push(hic, ch)) { return false; } } } } else if (hangul_is_jungseong(ch)) { combined = hangul_ic_combine(hic, hic->buffer.jungseong, ch); if (hangul_is_jungseong(combined)) { if (!hangul_ic_push(hic, combined)) { return false; } } else { hangul_ic_save_commit_string(hic); if (!hangul_ic_push(hic, ch)) { return false; } } } else { goto flush; } } else if (hic->buffer.choseong) { if (hangul_is_choseong(ch)) { combined = hangul_ic_combine(hic, hic->buffer.choseong, ch); /* 초성을 입력한 combine 함수에서 종성이 나오게 된다면 * 이전 초성도 종성으로 바꿔 주는 편이 나머지 처리에 편리하다. * 이 기능은 MS IME 호환기능으로 ㄳ을 입력하는데 사용한다. */ if (hangul_is_jongseong(combined)) { hic->buffer.choseong = 0; ucschar pop = hangul_ic_pop(hic); ucschar jong = hangul_choseong_to_jongseong(pop); hangul_ic_push(hic, jong); } if (!hangul_ic_push(hic, combined)) { if (!hangul_ic_push(hic, ch)) { return false; } } } else { if (!hangul_ic_push(hic, ch)) { if (!hangul_ic_push(hic, ch)) { return false; } } } } else { if (!hangul_ic_push(hic, ch)) { return false; } } hangul_ic_save_preedit_string(hic); return true; flush: hangul_ic_flush_internal(hic); return false; }