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