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