diff options
| author | Marc André Tanner <mat@brain-dump.org> | 2016-05-24 21:39:58 +0200 |
|---|---|---|
| committer | Marc André Tanner <mat@brain-dump.org> | 2016-05-24 21:39:58 +0200 |
| commit | 3cea78b00dcebe76da9a69d58c33c8b2a58d41ed (patch) | |
| tree | c23f89a8eafe1b7547ebdf57c6b01701d709b0bc | |
| parent | 9bcfd3f83098dcd4246b95fc37d523e06129ed12 (diff) | |
| download | vis-3cea78b00dcebe76da9a69d58c33c8b2a58d41ed.tar.gz vis-3cea78b00dcebe76da9a69d58c33c8b2a58d41ed.tar.xz | |
Add utility function to calculate display width of a string
This is based on the implementation of text_line_width_get
from text-motions.c. There might be an opportunity for code
sharing.
| -rw-r--r-- | text-util.c | 38 | ||||
| -rw-r--r-- | text-util.h | 2 |
2 files changed, 40 insertions, 0 deletions
diff --git a/text-util.c b/text-util.c index 6794a78..c7a1349 100644 --- a/text-util.c +++ b/text-util.c @@ -2,6 +2,7 @@ #include "util.h" #include <wchar.h> #include <errno.h> +#include <stdlib.h> bool text_range_valid(const Filerange *r) { return r->start != EPOS && r->end != EPOS && r->start <= r->end; @@ -75,3 +76,40 @@ int text_char_count(const char *data, size_t len) { } return count; } + +int text_string_width(const char *data, size_t len) { + + int width = 0; + mbstate_t ps = { 0 }; + const char *s = data; + + while (len > 0) { + char buf[MB_CUR_MAX]; + wchar_t wc; + size_t wclen = mbrtowc(&wc, s, len, &ps); + if (wclen == (size_t)-1 && errno == EILSEQ) { + /* assume a replacement symbol will be displayed */ + width++; + wclen = 1; + } else if (wclen == (size_t)-2) { + /* do nothing, advance to next character */ + wclen = 1; + } else if (wclen == 0) { + /* assume NUL byte will be displayed as ^@ */ + width += 2; + wclen = 1; + } else if (buf[0] == '\t') { + width++; + wclen = 1; + } else { + int w = wcwidth(wc); + if (w == -1) + w = 2; /* assume non-printable will be displayed as ^{char} */ + width += w; + } + len -= wclen; + s += wclen; + } + + return width; +} diff --git a/text-util.h b/text-util.h index a4d31b1..86d3307 100644 --- a/text-util.h +++ b/text-util.h @@ -23,5 +23,7 @@ bool text_range_overlap(const Filerange*, const Filerange*); bool text_range_contains(const Filerange*, size_t pos); /* count the number of graphemes in data */ int text_char_count(const char *data, size_t len); +/* get the approximate display width of data */ +int text_string_width(const char *data, size_t len); #endif |
