From: Choe Hwanjin Date: Sat, 20 Dec 2008 11:53:05 +0000 (+0900) Subject: 자모 스트링을 음절 단위로 iterate하는 함수 구현: X-Git-Tag: libhangul-0.0.9~4 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=fa3b58f093b444d9f0fef7afa7934a41ae95a7cd;p=platform%2Fcore%2Fuifw%2Flibhangul.git 자모 스트링을 음절 단위로 iterate하는 함수 구현: * hangul_syllable_iterator_prev() * hangul_syllable_iterator_next() * 음절을 구분하는 단위에 방점이나 combining char도 포함 git-svn-id: http://kldp.net/svn/hangul/libhangul/trunk@189 8f00fcd2-89fc-0310-932e-b01be5b65e01 --- diff --git a/hangul/hangul.h b/hangul/hangul.h index edd1761..f111c67 100644 --- a/hangul/hangul.h +++ b/hangul/hangul.h @@ -53,6 +53,11 @@ ucschar hangul_choseong_to_jongseong(ucschar ch); ucschar hangul_jongseong_to_choseong(ucschar ch); void hangul_jongseong_dicompose(ucschar ch, ucschar* jong, ucschar* cho); +const ucschar* hangul_syllable_iterator_prev(const ucschar* str, + const ucschar* begin); +const ucschar* hangul_syllable_iterator_next(const ucschar* str, + const ucschar* end); + int hangul_syllable_len(const ucschar* str, int max_len); ucschar hangul_jaso_to_syllable(ucschar choseong, diff --git a/hangul/hangulctype.c b/hangul/hangulctype.c index ee0be2f..9bcc819 100644 --- a/hangul/hangulctype.c +++ b/hangul/hangulctype.c @@ -29,7 +29,7 @@ #include "hangul.h" -static const ucschar hangul_base = 0xac00; +static const ucschar syllable_base = 0xac00; static const ucschar choseong_base = 0x1100; static const ucschar jungseong_base = 0x1161; static const ucschar jongseong_base = 0x11a7; @@ -78,6 +78,15 @@ hangul_is_jongseong(ucschar c) return c >= 0x11a8 && c <= 0x11f9; } +bool +hangul_is_combining_mark(ucschar c) +{ + return c == 0x302e || c == 0x302f || + (c >= 0x0300 && c <= 0x036F) || + (c >= 0x1dc0 && c <= 0x1dff) || + (c >= 0xfe20 && c <= 0xfe2f); +} + bool hangul_is_choseong_conjoinable(ucschar c) { @@ -372,7 +381,7 @@ hangul_jaso_to_syllable(ucschar choseong, ucschar jungseong, ucschar jongseong) jongseong -= jongseong_base; c = ((choseong * njungseong) + jungseong) * njongseong + jongseong - + hangul_base; + + syllable_base; return c; } @@ -392,7 +401,7 @@ hangul_syllable_to_jaso(ucschar syllable, if (!hangul_is_syllable(syllable)) return; - syllable -= hangul_base; + syllable -= syllable_base; if (jongseong != NULL) { if (syllable % njongseong != 0) *jongseong = jongseong_base + syllable % njongseong; @@ -417,14 +426,46 @@ is_syllable_boundary(ucschar prev, ucschar next) return false; if (hangul_is_jungseong(next)) return false; + if (hangul_is_syllable(next)) + return false; + if (hangul_is_combining_mark(next)) + return false; + if (next == HANGUL_JUNGSEONG_FILLER) + return false; + } else if (prev == HANGUL_CHOSEONG_FILLER) { + if (hangul_is_jungseong(next)) + return false; + if (next == HANGUL_JUNGSEONG_FILLER) + return false; } else if (hangul_is_jungseong(prev)) { if (hangul_is_jungseong(next)) return false; if (hangul_is_jongseong(next)) return false; + if (hangul_is_combining_mark(next)) + return false; + } else if (prev == HANGUL_JUNGSEONG_FILLER) { + if (hangul_is_jongseong(next)) + return false; } else if (hangul_is_jongseong(prev)) { if (hangul_is_jongseong(next)) return false; + if (hangul_is_combining_mark(next)) + return false; + } else if (hangul_is_syllable(prev)) { + if ((prev - syllable_base) % njongseong == 0) { + // 종성이 없는 음절: LV + if (hangul_is_jungseong(next)) + return false; + if (hangul_is_jongseong(next)) + return false; + } else { + // 종성이 있는 음절: LVT + if (hangul_is_jongseong(next)) + return false; + } + if (hangul_is_combining_mark(next)) + return false; } return true; @@ -609,6 +650,64 @@ hangul_syllable_len(const ucschar* str, int max_len) return i; } +/** + * @brief @a iter를 기준으로 이전 음절의 첫자모 글자에 대한 포인터를 구한다. + * @param iter 현재 위치 + * @param begin 스트링의 시작위치, 포인터가 이동할 한계값 + * @return 이전 음절의 첫번째 자모에 대한 포인터 + * + * 이 함수는 @a iter로 주어진 자모 스트링의 포인터를 기준으로 이전 음절의 + * 첫번째 자모에 대한 포인터를 리턴한다. 음절을 찾기위해서 begin보다 + * 앞쪽으로 이동하지 않는다. + * + * 한 음절이라고 판단하는 기준은 L*V*T+M? 패턴에 따른다. + */ +const ucschar* +hangul_syllable_iterator_prev(const ucschar* iter, const ucschar* begin) +{ + if (iter > begin) + iter--; + + while (iter > begin) { + ucschar prev = iter[-1]; + ucschar curr = iter[0]; + if (is_syllable_boundary(prev, curr)) + break; + iter--; + } + + return iter; +} + +/** + * @brief @a iter를 기준으로 다음 음절의 첫자모 글자에 대한 포인터를 구한다. + * @param iter 현재 위치 + * @param end 스트링의 끝위치, 포인터가 이동할 한계값 + * @return 다음 음절의 첫번째 자모에 대한 포인터 + * + * 이 함수는 @a iter로 주어진 자모 스트링의 포인터를 기준으로 다음 음절의 + * 첫번째 자모에 대한 포인터를 리턴한다. 음절을 찾기위해서 end를 넘어 + * 이동하지 않는다. + * + * 한 음절이라고 판단하는 기준은 L*V*T+M? 패턴에 따른다. + */ +const ucschar* +hangul_syllable_iterator_next(const ucschar* iter, const ucschar* end) +{ + if (iter < end) + iter++; + + while (iter < end) { + ucschar prev = iter[-1]; + ucschar curr = iter[0]; + if (is_syllable_boundary(prev, curr)) + break; + iter++; + } + + return iter; +} + /** * @brief 자모 스트링을 음절 스트링을 변환한다 * @param dest 음절형으로 변환된 결과가 저장될 버퍼 @@ -617,7 +716,7 @@ hangul_syllable_len(const ucschar* str, int max_len) * @param srclen 변환할 자모 스트링의 길이(ucschar 코드 단위) * @return @a destlen 에 저장한 코드의 갯수 * - * 이 함수는 L+V+T* 패턴에 따라 자모 스트링 변환을 시도한다. 한 음절을 + * 이 함수는 L+V+T*M? 패턴에 따라 자모 스트링 변환을 시도한다. 한 음절을 * 판단하는 기준은 @ref hangul_syllable_len 을 참조한다. * 만일 @a src 가 적절한 음절형태로 변환이 불가능한 경우에는 자모 스트링이 * 그대로 복사된다.