Files
qmltermwidget/lib/konsole_wcwidth.cpp
2026-05-04 22:25:48 +02:00

65 lines
1.8 KiB
C++

/* $XFree86: xc/programs/xterm/wcwidth.character,v 1.3 2001/07/29 22:08:16 tsi Exp $ */
/*
* This is an implementation of wcwidth() and wcswidth() as defined in
* "The Single UNIX Specification, Version 2, The Open Group, 1997"
* <http://www.UNIX-systems.org/online.html>
*
* Markus Kuhn -- 2001-01-12 -- public domain
*/
#include <QString>
#ifdef HAVE_UTF8PROC
#include <utf8proc.h>
#else
#include <cwchar>
#if defined(Q_OS_WIN)
// wcwidth is a POSIX function not available on Windows; provide a minimal substitute.
static int wcwidth(wchar_t ucs)
{
if (ucs == 0) return 0;
if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0)) return -1;
// Double-width CJK ranges (approximate but correct for common cases)
if ((ucs >= 0x1100 && ucs <= 0x115F) ||
(ucs >= 0x2E80 && ucs <= 0x303E) ||
(ucs >= 0x3040 && ucs <= 0xA4CF) ||
(ucs >= 0xAC00 && ucs <= 0xD7A3) ||
(ucs >= 0xF900 && ucs <= 0xFAFF) ||
(ucs >= 0xFE10 && ucs <= 0xFE1F) ||
(ucs >= 0xFE30 && ucs <= 0xFE4F) ||
(ucs >= 0xFF01 && ucs <= 0xFF60) ||
(ucs >= 0xFFE0 && ucs <= 0xFFE6) ||
ucs == 0x2329 || ucs == 0x232A)
return 2;
return 1;
}
#endif
#endif
#include "konsole_wcwidth.h"
int konsole_wcwidth(wchar_t ucs)
{
#ifdef HAVE_UTF8PROC
utf8proc_category_t cat = utf8proc_category( ucs );
if (cat == UTF8PROC_CATEGORY_CO) {
// Co: Private use area. libutf8proc makes them zero width, while tmux
// assumes them to be width 1, and glibc's default width is also 1
return 1;
}
return utf8proc_charwidth( ucs );
#else
return wcwidth( ucs );
#endif
}
// single byte char: +1, multi byte char: +2
int string_width( const std::wstring & wstr )
{
int w = 0;
for ( size_t i = 0; i < wstr.length(); ++i ) {
w += konsole_wcwidth( wstr[ i ] );
}
return w;
}