Separator: uses widecharwidth for Unicode wcwidth and fixes issue that wchar_t on Windows is 2-byte length

This commit is contained in:
李通洲
2025-09-09 09:54:30 +08:00
parent 8eafec479e
commit baaeef5ab5
8 changed files with 1677 additions and 366 deletions
+32
View File
@@ -0,0 +1,32 @@
#include "wcwidth.h"
#include "3rdparty/widecharwidth/widechar_width_c.h"
int mk_wcwidth(uint32_t wc)
{
// // We render U+1F6E1 (🛡) with a width of 2,
// // but widechar_width says it has a width of 1 because Unicode classifies it as "neutral".
// //
// // So we simply decide the width ourselves
// if (wc == 0x1F6E1) return 2;
//
// Well terminals do show it as width 1 after all
int width = widechar_wcwidth(wc);
switch (width) {
case widechar_ambiguous:
case widechar_private_use:
return 1;
case widechar_widened_in_9:
// Our renderer supports Unicode 9
return 2;
// case widechar_nonprint:
// case widechar_combining:
// case widechar_unassigned:
// case widechar_non_character:
// return -1;
default:
// Use the width widechar_width gave us.
return width;
}
}
+9 -9
View File
@@ -1,16 +1,16 @@
#pragma once
#include <wchar.h>
#include <stdint.h>
#ifdef FF_HAVE_WCWIDTH
static inline int mk_wcwidth(wchar_t ucs) {
return wcwidth(ucs);
}
static inline int mk_wcswidth(const wchar_t *pwcs, size_t n) {
return wcswidth(pwcs, n);
#include <wchar.h>
// Should be char32_t but it's not defined on macOS
static_assert(sizeof(wchar_t) == sizeof(uint32_t), "wcwidth implementation requires wchar_t to be 32 bits");
static inline int mk_wcwidth(uint32_t ucs) {
return wcwidth((wchar_t) ucs);
}
#else
// https://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
int mk_wcwidth(wchar_t ucs);
int mk_wcswidth(const wchar_t *pwcs, size_t n);
int mk_wcwidth(uint32_t wc);
#endif