2004-10-18 (월), 18:45 +0200, Radek Doulík 쓰시길: > This part seems to be unnecessarily slow: > > > - wl = clen + max_len; > > + wmax = MIN(clen + max_width, slen); > > + while (utf8_width (s, wmax - clen) > max_width) > > + wmax--; > > + wl = wmax; > > I think it will be better to have another helper function returning > the lenght of string starting on s which is not exceeding max_width. You're right. Attached the revised patch, against gtkhtml 3.2.3. -- Changwoo Ryu <cwryu debian org>
Index: src/htmlclueflow.c
===================================================================
--- src/htmlclueflow.c (.../upstream/3.2.3) (revision 115)
+++ src/htmlclueflow.c (.../patches/000-67022-cjk-line-wrapping/3.2.3) (revision 115)
@@ -1773,6 +1773,47 @@
}
}
+/*
+ * Calculate given UTF-8 string's "cell width", determined by
+ * g_unichar_iswide() on each character. (So it doesn't work on
+ * zero-width or combined characters.)
+ */
+static gint
+utf8_width (const char *str, gint len)
+{
+ gunichar c;
+ gint width = 0;
+
+ while (len--) {
+ c = g_utf8_get_char (str);
+ width += g_unichar_iswide (c) ? 2 : 1;
+ str = g_utf8_next_char (str);
+ }
+ return width;
+}
+
+/*
+ * Returns the length of string starting on the given string which is
+ * not exceeding the given width.
+ */
+static gint
+utf8_length_in_width (const char *str, gint len, gint width)
+{
+ gunichar c;
+ gint l = 0;
+
+ while (len--) {
+ c = g_utf8_get_char (str);
+ width -= g_unichar_iswide (c) ? 2 : 1;
+ if (width < 0)
+ break;
+ str = g_utf8_next_char (str);
+ l++;
+ }
+
+ return l;
+}
+
static gboolean
save_plain (HTMLObject *self,
HTMLEngineSaveState *state,
@@ -1784,18 +1825,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 +1857,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 +1900,18 @@
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 = clen + utf8_length_in_width (s, len, max_width);
+ wl = wmax;
if (lattrs [wl].is_white) {
@@ -1877,7 +1921,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 +1933,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 > clen && lattrs [wi - 1].is_white)
wi --;
len = wi - clen;
+ width = utf8_width (s, len);
skip = wl - wi;
}
}
@@ -1905,10 +1950,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