> (patches welcome)

My patch is attached.

Screen capture:
http://www1.interq.or.jp/~deton/lynx-wcwidth/

Known issue:
* Highlight is incorrect on selecting wrapped long wide-char link text.
* Whereis highlight position is incorrect after wide-char text.
* Not support treating double-width for East Asian Ambiguous Width characters.
  (for xterm -cjk_width)
  TODO:
    * Use mk_wcwidth_cjk() in http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
    * Add cjk_width option to lynx
diff --git a/src/GridText.c b/src/GridText.c
index e7221bf..b0e30ad 100644
--- a/src/GridText.c
+++ b/src/GridText.c
@@ -74,6 +74,9 @@
 
 static void HText_trimHightext(HText *text, int final, int stop_before);
 
+#define IS_UTF_FIRST(ch) (text->T.output_utf8 && \
+			  (UCH((ch))&0xc0) == 0xc0)
+
 #define IS_UTF_EXTRA(ch) (text->T.output_utf8 && \
 			  (UCH((ch))&0xc0) == 0x80)
 
@@ -589,8 +592,16 @@ static int ctrl_chars_on_this_line = 0;		/* num of ctrl chars in current line */
 static int utfxtra_on_this_line = 0;	/* num of UTF-8 extra bytes in line,
 
 					   they *also* count as ctrl chars. */
+#ifdef UTFWIDEWIDTH_SUPPORT
+static int utfxtracells_on_this_line = 0;	/* num of UTF-8 extra cells in line */
+static int utfextracells(const char *s);
+#endif
 #ifdef WIDEC_CURSES
+# ifdef UTFWIDEWIDTH_SUPPORT /* TODO: support for !WIDEC_CURSES */
+#define UTFXTRA_ON_THIS_LINE utfxtracells_on_this_line
+# else
 #define UTFXTRA_ON_THIS_LINE 0
+# endif
 #else
 #define UTFXTRA_ON_THIS_LINE utfxtra_on_this_line
 #endif
@@ -2690,6 +2701,10 @@ static HTLine *insert_blanks_in_line(HTLine *line, int line_number,
 		    break;
 		ioldc++;
 		pre = s + 1;
+#ifdef UTFWIDEWIDTH_SUPPORT
+		if (text && text->T.output_utf8 && IS_UTF_FIRST(*s))
+		    ioldc += utfextracells(s);
+#endif
 	    }
 	    s++;
 	}
@@ -2832,6 +2847,9 @@ static void split_line(HText *text, unsigned split)
 
     ctrl_chars_on_this_line = 0;	/*reset since we are going to a new line */
     utfxtra_on_this_line = 0;	/*reset too, we'll count them */
+#ifdef UTFWIDEWIDTH_SUPPORT
+    utfxtracells_on_this_line = 0;
+#endif
     text->LastChar = ' ';
 
 #ifdef DEBUG_APPCH
@@ -2959,6 +2977,10 @@ static void split_line(HText *text, unsigned split)
 		    ctrl_chars_on_this_line++;
 		} else if (IS_UTF_EXTRA(p[i])) {
 		    utfxtra_on_this_line++;
+#ifdef UTFWIDEWIDTH_SUPPORT
+		} else if (IS_UTF_FIRST(p[i])) {
+		    utfxtracells_on_this_line += utfextracells(&p[i]);
+#endif
 		}
 		if (p[i] == LY_SOFT_HYPHEN &&
 		    (int) text->permissible_split < i)
@@ -4112,6 +4134,18 @@ void HText_appendCharacter(HText *text, int ch)
 	    line->data[line->size] = '\0';
 	    utfxtra_on_this_line++;
 	    ctrl_chars_on_this_line++;
+#ifdef UTFWIDEWIDTH_SUPPORT
+	    /* update utfxtracells_on_this_line on last byte of UTF-8 sequence */
+	    {
+		/* find start position of UTF-8 sequence */
+		int utff = line->size - 2;
+		while (utff > 0 && IS_UTF_EXTRA(line->data[utff]))
+		    utff--;
+		int utf_xlen = UTF_XLEN(line->data[utff]);
+		if (line->size - utff == utf_xlen + 1) /* have last byte */
+		    utfxtracells_on_this_line += utfextracells(&(line->data[utff]));
+	    }
+#endif
 	    return;
 	} else if (ch & 0x80) {	/* a first char of UTF-8 sequence - kw */
 	    if ((line->size > (MAX_LINE - 7))) {
@@ -4331,6 +4365,9 @@ void HText_appendCharacter(HText *text, int ch)
 	    (actual
 	     + (int) style->rightIndent
 	     + ((IS_CJK_TTY && text->kanji_buf) ? 1 : 0)
+#ifdef UTFWIDEWIDTH_SUPPORT
+	     + utfxtracells_on_this_line
+#endif
 	    ) >= WRAP_COLS(text))
 	|| (text->T.output_utf8
 	    && ((actual
@@ -9176,6 +9213,12 @@ static int HText_TrueLineSize(HTLine *line, HText *text, int IgnoreSpaces)
 		UCH(line->data[i]) != HT_NON_BREAK_SPACE &&
 		UCH(line->data[i]) != HT_EN_SPACE) {
 		true_size++;
+#ifdef UTFWIDEWIDTH_SUPPORT
+		if (text && text->T.output_utf8 &&
+		    IS_UTF_FIRST(line->data[i])) {
+		    true_size += utfextracells(&(line->data[i]));
+		}
+#endif
 	    }
 	}
     } else {
@@ -9183,6 +9226,12 @@ static int HText_TrueLineSize(HTLine *line, HText *text, int IgnoreSpaces)
 	    if (!IsSpecialAttrChar(line->data[i]) &&
 		IS_UTF8_EXTRA(line->data[i])) {
 		true_size++;
+#ifdef UTFWIDEWIDTH_SUPPORT
+		if (text && text->T.output_utf8 &&
+		    IS_UTF_FIRST(line->data[i])) {
+		    true_size += utfextracells(&(line->data[i]));
+		}
+#endif
 	    }
 	}
     }
@@ -14869,3 +14918,16 @@ GLOBALDEF HTProtocol LYLynxCache =
 {"LYNXCACHE", LYHandleCache, 0};
 #endif /* GLOBALDEF_IS_MACRO */
 #endif /* USE_CACHEJAR */
+
+#ifdef UTFWIDEWIDTH_SUPPORT
+static int utfextracells(const char *s)
+{
+    UCode_t ucs = UCGetUniFromUtf8String(&s);
+    if (ucs <= 0) 
+	return 0;
+    int cells = wcwidth(ucs);
+    if (cells <= 1)
+	return 0;
+    return cells - 1;
+}
+#endif
_______________________________________________
Lynx-dev mailing list
Lynx-dev@nongnu.org
https://lists.nongnu.org/mailman/listinfo/lynx-dev

Reply via email to