Patch attached. -- Changwoo Ryu <cwryu debian org>
Index: src/htmlclueflow.c =================================================================== --- src/htmlclueflow.c (.../upstream/3.2.2) (revision 67) +++ src/htmlclueflow.c (.../patches/000-67022-cjk-line-wrapping) (revision 67) @@ -1773,6 +1773,26 @@ } } +/* + * Calculate given UTF-8 string's "cell width", determined by + * g_unichar_iswide() on each characters. (So it doesn't work on + * combined characters.) + */ +static gint +utf8_width (const char *str, gint len) +{ + gunichar c; + int width = 0; + const char *s = str; + + while (len--) { + c = g_utf8_get_char (s); + width += g_unichar_iswide(c) ? 2 : 1; + s = g_utf8_next_char(s); + } + return width; +} + static gboolean save_plain (HTMLObject *self, HTMLEngineSaveState *state, @@ -1784,18 +1804,18 @@ gint pad; gint align_pad; gboolean firstline = TRUE; - gint max_len; + gint max_width; flow = HTML_CLUEFLOW (self); pad = plain_padding (flow, NULL, FALSE); buffer_state = html_engine_save_buffer_new (state->engine, state->inline_frames); - max_len = MAX (requested_width - pad, 0); + max_width = MAX (requested_width - pad, 0); /* buffer the paragraph's content into the save buffer */ if (HTML_OBJECT_CLASS (&html_clue_class)->save_plain (self, buffer_state, - max_len)) { + max_width)) { guchar *s; int offset; @@ -1816,7 +1836,7 @@ PangoContext *pc = gtk_widget_get_pango_context (GTK_WIDGET (state->engine->widget)); PangoLogAttr *lattrs; PangoItem **items; - gint len, skip; + gint len, width, skip; items_list = pango_itemize (pc, s, 0, bytes, attrs, NULL); lattrs = g_new (PangoLogAttr, slen + 1); @@ -1859,15 +1879,20 @@ while (*s) { len = strcspn (s, "\n"); len = g_utf8_strlen (s, len); + width = utf8_width (s, len); skip = 0; if ((flow->style != HTML_CLUEFLOW_STYLE_PRE) && !HTML_IS_TABLE (HTML_CLUE (flow)->head)) { - if (len > max_len) { + if (width > max_width) { gboolean look_backward = TRUE; + gint wmax; gint wi, wl; - wl = clen + max_len; + wmax = MIN(clen + max_width, slen); + while (utf8_width (s, wmax - clen) > max_width) + wmax--; + wl = wmax; if (lattrs [wl].is_white) { @@ -1877,7 +1902,7 @@ if (wl < slen && html_text_is_line_break (lattrs [wl])) look_backward = FALSE; else - wl = clen + max_len; + wl = wmax; } if (look_backward) { @@ -1889,10 +1914,11 @@ } if (wl > clen && wl < slen && html_text_is_line_break (lattrs [wl])) { - wi = MIN (wl, clen + max_len); + wi = MIN (wl, wmax); while (wi > 0 && lattrs [wi - 1].is_white) wi --; len = wi - clen; + width = utf8_width (s, len); skip = wl - wi; } } @@ -1905,10 +1931,10 @@ switch (html_clueflow_get_halignment (flow)) { case HTML_HALIGN_RIGHT: - align_pad = max_len - len; + align_pad = max_width - width; break; case HTML_HALIGN_CENTER: - align_pad = (max_len - len) / 2; + align_pad = (max_width - width) / 2; break; default: align_pad = 0;
Attachment:
signature.asc
Description: This is a digitally signed message part