From 08ac22ddb9e848123934dad215c58cb03e7ad094 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= Date: Thu, 14 Jan 2021 09:59:11 +0100 Subject: RichString: refactor writing limited amount of columns Closes: #468 --- Process.c | 5 +++-- RichString.c | 38 +++++++++++++++++++++++++++++++++++++- RichString.h | 5 +++++ 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/Process.c b/Process.c index 152fbe68..551959a5 100644 --- a/Process.c +++ b/Process.c @@ -245,8 +245,9 @@ void Process_outputRate(RichString* str, char* buffer, size_t n, double rate, in } void Process_printLeftAlignedField(RichString* str, int attr, const char* content, unsigned int width) { - int c = RichString_appendnWide(str, attr, content, MINIMUM(width, strlen(content))); - RichString_appendChr(str, attr, ' ', width + 1 - c); + int columns = width; + RichString_appendnWideColumns(str, attr, content, strlen(content), &columns); + RichString_appendChr(str, attr, ' ', width + 1 - columns); } void Process_writeField(const Process* this, RichString* str, ProcessField field) { diff --git a/RichString.c b/RichString.c index 86344eac..5a2c2e14 100644 --- a/RichString.c +++ b/RichString.c @@ -60,7 +60,37 @@ static inline int RichString_writeFromWide(RichString* this, int attrs, const ch this->chptr[i] = (CharType) { .attr = attrs & 0xffffff, .chars = { (iswprint(data[j]) ? data[j] : '?') } }; } - return wcswidth(data, len); + return len; +} + +int RichString_appendnWideColumns(RichString* this, int attrs, const char* data_c, int len, int* columns) { + wchar_t data[len + 1]; + len = mbstowcs(data, data_c, len); + if (len <= 0) + return 0; + + int from = this->chlen; + int newLen = from + len; + RichString_setLen(this, newLen); + int columnsWritten = 0; + int pos = from; + for (int j = 0; j < len; j++) { + wchar_t c = iswprint(data[j]) ? data[j] : '?'; + int cwidth = wcwidth(c); + if (cwidth > *columns) + break; + + *columns -= cwidth; + columnsWritten += cwidth; + + this->chptr[pos] = (CharType) { .attr = attrs & 0xffffff, .chars = { c, '\0' } }; + pos++; + } + + RichString_setLen(this, pos); + *columns = columnsWritten; + + return pos - from; } static inline int RichString_writeFromAscii(RichString* this, int attrs, const char* data, int from, int len) { @@ -113,6 +143,12 @@ static inline int RichString_writeFromWide(RichString* this, int attrs, const ch return len; } +int RichString_appendnWideColumns(RichString* this, int attrs, const char* data_c, int len, int* columns) { + int written = RichString_writeFromWide(this, attrs, data_c, this->chlen, MINIMUM(len, *columns)); + *columns = written; + return written; +} + static inline int RichString_writeFromAscii(RichString* this, int attrs, const char* data_c, int from, int len) { return RichString_writeFromWide(this, attrs, data_c, from, len); } diff --git a/RichString.h b/RichString.h index 73e78204..7464fff1 100644 --- a/RichString.h +++ b/RichString.h @@ -52,10 +52,15 @@ void RichString_setAttr(RichString* this, int attrs); void RichString_appendChr(RichString* this, int attrs, char c, int count); +/* All appending and writing functions return the number of written characters (not columns). */ + int RichString_appendWide(RichString* this, int attrs, const char* data); int RichString_appendnWide(RichString* this, int attrs, const char* data, int len); +/* columns takes the maximum number of columns to write and contains on return the number of columns written. */ +int RichString_appendnWideColumns(RichString* this, int attrs, const char* data, int len, int* columns); + int RichString_writeWide(RichString* this, int attrs, const char* data); int RichString_appendAscii(RichString* this, int attrs, const char* data); -- cgit v1.2.3