introduce ncwidth() to handle sextants on pre-U13 libcs #1274

pull/1279/head
nick black 4 years ago
parent 4a57436bb8
commit 8b0de2aa1b
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC

@ -11,6 +11,7 @@
#include <string.h>
#include <unigbrk.h>
#include <stdbool.h>
#include "ncwidth.h"
#include "notcurses/notcurses.h"
#ifdef __cplusplus
@ -66,7 +67,7 @@ egcpool_grow(egcpool* pool, size_t len){
// any NUL terminator. Neither the number of bytes nor columns is necessarily
// equal to the number of decoded code points. Such are the ways of Unicode.
// uc_is_grapheme_break() wants UTF-32, which is fine, because we need wchar_t
// to use wcwidth() anyway FIXME except this doesn't work with 16-bit wchar_t!
// to use ncwidth() anyway FIXME except this doesn't work with 16-bit wchar_t!
static inline int
utf8_egc_len(const char* gcluster, int* colcount){
size_t ret = 0;
@ -83,7 +84,7 @@ utf8_egc_len(const char* gcluster, int* colcount){
if(prevw && uc_is_grapheme_break(prevw, wc)){
break; // starts a new EGC, exit and do not claim
}
int cols = wcwidth(wc);
int cols = ncwidth(wc);
if(cols < 0){
if(iswspace(wc)){ // newline or tab
return ret + 1;

@ -397,7 +397,7 @@ mbstr_find_codepoint(const char* s, char32_t cp, int* col){
if(towlower(cp) == towlower(w)){
return bytes;
}
*col += wcwidth(w);
*col += ncwidth(w);
bytes += r;
}
return -1;

@ -95,7 +95,7 @@ puttext_line(ncplane* n, ncalign_e align, const char* text, size_t* bytes){
return cols;
}
b += consumed;
int width = wcwidth(w);
int width = ncwidth(w);
if(width < 0){
width = 0; // FIXME
}

@ -0,0 +1,18 @@
#include <wchar.h>
// wcwidth() might be missing some lengths (for instance, glibc didn't get
// Unicode 13 support until 2.31). ncwidth() handles some characters on the
// wcwidth() error path. it ought generally be used rather than wcwidth().
static inline int
ncwidth(wchar_t c){
int r = wcwidth(c);
if(r >= 0){
return r;
}
// Symbols for Legacy Computing were only added to glibc in 2.32 (along with
// the rest of Unicode 13). Handle them explicitly if wcwidth() failed.
if(c >= 0x1fb00 && c <= 0x1fb3b){
return 1;
}
return -1;
}
Loading…
Cancel
Save