From d6ed174d094dcb16713aba251c7bb7cb6c617a8a Mon Sep 17 00:00:00 2001 From: Benno Schulenberg Date: Fri, 9 Apr 2021 16:24:22 +0200 Subject: [PATCH] tweaks: morph a function into what it is actually used for Since the previous commit, mbwidth() is used only to determine whether a character is either double width or zero width. There is no need to return the actual width of the character; a simple yes or no is enough. Transforming mbwidth() into is_doublewidth() also allows streamlining it and is_zerowidth() a bit, so that they become slightly faster. --- src/chars.c | 35 +++++++++++++++++++---------------- src/prototypes.h | 2 +- src/winio.c | 8 ++++---- 3 files changed, 24 insertions(+), 21 deletions(-) diff --git a/src/chars.c b/src/chars.c index 620d2b26..5c51602c 100644 --- a/src/chars.c +++ b/src/chars.c @@ -225,31 +225,34 @@ int mbtowide(wchar_t *wc, const char *c) return 1; } -/* Return the width in columns of the given (multibyte) character. */ -int mbwidth(const char *c) +/* Return TRUE when the given character occupies two cells. */ +bool is_doublewidth(const char *ch) { - /* Only characters beyond U+02FF can be other than one column wide. */ - if ((unsigned char)*c > 0xCB) { - wchar_t wc; - int width; + wchar_t wc; - if (mbtowide(&wc, c) < 0) - return 1; + /* Only from U+1100 can code points have double width. */ + if ((unsigned char)*ch < 0xE1 || !use_utf8) + return FALSE; - width = wcwidth(wc); + if (mbtowide(&wc, ch) < 0) + return FALSE; - if (width < 0) - return 1; - - return width; - } else - return 1; + return (wcwidth(wc) == 2); } /* Return TRUE when the given character occupies zero cells. */ bool is_zerowidth(const char *ch) { - return (use_utf8 && mbwidth(ch) == 0); + wchar_t wc; + + /* Only from U+0300 can code points have zero width. */ + if ((unsigned char)*ch < 0xCC || !use_utf8) + return FALSE; + + if (mbtowide(&wc, ch) < 0) + return FALSE; + + return (wcwidth(wc) == 0); } #endif /* ENABLE_UTF8 */ diff --git a/src/prototypes.h b/src/prototypes.h index 6c9fec2a..4523c398 100644 --- a/src/prototypes.h +++ b/src/prototypes.h @@ -205,7 +205,7 @@ bool is_word_char(const char *c, bool allow_punct); char control_mbrep(const char *c, bool isdata); #ifdef ENABLE_UTF8 int mbtowide(wchar_t *wc, const char *c); -int mbwidth(const char *c); +bool is_doublewidth(const char *ch); bool is_zerowidth(const char *ch); #endif int char_length(const char *pointer); diff --git a/src/winio.c b/src/winio.c index b677a630..6f14c6c9 100644 --- a/src/winio.c +++ b/src/winio.c @@ -1749,7 +1749,7 @@ char *display_string(const char *text, size_t column, size_t span, } } #ifdef ENABLE_UTF8 - else if (mbwidth(text) == 2) { + else if (is_doublewidth(text)) { if (start_col == column) { converted[index++] = ' '; column++; @@ -1765,7 +1765,7 @@ char *display_string(const char *text, size_t column, size_t span, #ifdef ENABLE_UTF8 #define ISO8859_CHAR FALSE -#define ZEROWIDTH_CHAR (mbwidth(text) == 0) +#define ZEROWIDTH_CHAR (is_zerowidth(text)) #else #define ISO8859_CHAR ((unsigned char)*text > 0x9F) #define ZEROWIDTH_CHAR FALSE @@ -1873,10 +1873,10 @@ char *display_string(const char *text, size_t column, size_t span, #ifdef ENABLE_UTF8 do { index = step_left(converted, index); - } while (mbwidth(converted + index) == 0); + } while (is_zerowidth(converted + index)); /* Display the left half of a two-column character as '['. */ - if (mbwidth(converted + index) == 2) + if (is_doublewidth(converted + index)) converted[index++] = '['; #else index--;