static void hangul_engine_shape (PangoEngineShape *engine, PangoFont *font, const char *text, gint length, const PangoAnalysis *analysis, PangoGlyphString *glyphs) { int n_chars, n_glyphs; int i; const char *p, *start; gunichar jamos_static[8]; gint max_jamos = G_N_ELEMENTS (jamos_static); gunichar *jamos = jamos_static; int n_jamos; n_chars = g_utf8_strlen (text, length); n_glyphs = 0; start = p = text; n_jamos = 0; for (i = 0; i < n_chars; i++) { gunichar wc; wc = g_utf8_get_char (p); /* Check syllable boundaries. */ if (n_jamos) { gunichar prev = jamos[n_jamos - 1]; if ((!IS_JAMO (wc) && !IS_S (wc) && !IS_M (wc)) || (!IS_L (prev) && IS_S (wc)) || (IS_T (prev) && IS_L (wc)) || (IS_V (prev) && IS_L (wc)) || (IS_T (prev) && IS_V (wc)) || IS_M (prev)) { /* Draw a syllable with these jamos. */ render_syllable (font, jamos, n_jamos, glyphs, &n_glyphs, start - text); n_jamos = 0; start = p; } } if (n_jamos >= max_jamos - 3) { max_jamos += 8; /* at most 3 for each syllable code (L+V+T) */ if (jamos == jamos_static) { jamos = g_new (gunichar, max_jamos); memcpy (jamos, jamos_static, n_jamos*sizeof(gunichar)); } else jamos = g_renew (gunichar, jamos, max_jamos); } if (!IS_JAMO (wc) && !IS_S (wc) && !IS_M (wc)) { render_basic (font, wc, glyphs, &n_glyphs, start - text); start = g_utf8_next_char (p); } else if (IS_S (wc)) { jamos[n_jamos++] = L_FROM_S (wc); jamos[n_jamos++] = V_FROM_S (wc); if (S_HAS_T (wc)) jamos[n_jamos++] = T_FROM_S (wc); } else if (IS_M (wc) && !n_jamos) { /* Tone mark not following syllable */ render_isolated_tone (font, wc, glyphs, &n_glyphs, start - text); start = g_utf8_next_char (p); } else jamos[n_jamos++] = wc; p = g_utf8_next_char (p); } if (n_jamos != 0) render_syllable (font, jamos, n_jamos, glyphs, &n_glyphs, start - text); if (jamos != jamos_static) g_free(jamos); }
static void hangul_engine_shape (PangoEngineShape *engine, PangoFont *font, const char *text, gint length, const PangoAnalysis *analysis, PangoGlyphString *glyphs) { int n_chars = g_utf8_strlen (text, length); int n_glyphs; int i; const char *p, *start; int n_jamos; gunichar prev = 0; n_glyphs = 0; start = p = text; n_jamos = 0; for (i = 0; i < n_chars; i++) { gunichar wc; wc = g_utf8_get_char (p); /* Check syllable boundaries. */ if (n_jamos && IS_BOUNDARY (prev, wc)) { if (n_jamos == 1 && IS_S (prev)) /* common case which the most people use */ render_basic (font, prev, glyphs, &n_glyphs, start - text); else /* possibly complex composition */ render_syllable (font, start, n_jamos, glyphs, &n_glyphs, start - text); n_jamos = 0; start = p; } prev = wc; if (!IS_HANGUL (wc)) { render_basic (font, wc, glyphs, &n_glyphs, start - text); start = g_utf8_next_char (p); } else if (IS_M (wc) && !n_jamos) { /* Tone mark not following syllable */ render_isolated_tone (font, wc, glyphs, &n_glyphs, start - text); start = g_utf8_next_char (p); } else n_jamos++; p = g_utf8_next_char (p); } if (n_jamos == 1 && IS_S (prev)) render_basic (font, prev, glyphs, &n_glyphs, start - text); else if (n_jamos > 0) render_syllable (font, start, n_jamos, glyphs, &n_glyphs, start - text); }