From 59917ed12607da95beb33b81a43d349e0f1b7734 Mon Sep 17 00:00:00 2001 From: Markus Gans Date: Wed, 24 Feb 2021 19:55:20 +0100 Subject: [PATCH] Fixed the incorrect display on terminals without UTF-8 character encoding --- ChangeLog | 4 ++++ scripts/xterm-latin1.sh | 2 +- src/fterm_functions.cpp | 6 +++++- test/fterm_functions-test.cpp | 27 +++++++++++++++++++++------ 4 files changed, 31 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index a8384848..0ac7f5b3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2021-02-24 Markus Gans + * Fixed the incorrect display on terminals without + UTF-8 character encoding + 2021-02-20 Markus Gans * Optimize terminal output buffer queue with differencing for strings, and control characters and control sequences diff --git a/scripts/xterm-latin1.sh b/scripts/xterm-latin1.sh index 267cdfea..14a998aa 100755 --- a/scripts/xterm-latin1.sh +++ b/scripts/xterm-latin1.sh @@ -1,3 +1,3 @@ #!/bin/sh -luit -encoding POSIX ../examples/ui +luit -encoding C ../examples/ui $@ diff --git a/src/fterm_functions.cpp b/src/fterm_functions.cpp index 70755212..bbbac89f 100644 --- a/src/fterm_functions.cpp +++ b/src/fterm_functions.cpp @@ -513,7 +513,11 @@ std::size_t getColumnWidth (const wchar_t wchar) column_width = wcwidth(wchar); if ( (wchar >= UniChar::NF_rev_left_arrow2 && wchar <= UniChar::NF_check_mark) - || ! hasFullWidthSupports() ) + || FTerm::getEncoding() != Encoding::UTF8 ) + { + column_width = 1; + } + else if ( ! hasFullWidthSupports() ) { column_width = std::min(column_width, 1); } diff --git a/test/fterm_functions-test.cpp b/test/fterm_functions-test.cpp index ea0b6b54..ae5ffce2 100644 --- a/test/fterm_functions-test.cpp +++ b/test/fterm_functions-test.cpp @@ -484,6 +484,8 @@ void FTermFunctionsTest::FullWidthHalfWidthTest() CPPUNIT_ASSERT ( finalcut::getHalfWidth(L"ㄴ") == L"ᄂ" ); // Column width (wchar_t) + const auto& data = finalcut::FTerm::getFTermData(); + data->setTermEncoding (finalcut::Encoding::UTF8); CPPUNIT_ASSERT ( finalcut::getColumnWidth(L"\t") == 0 ); CPPUNIT_ASSERT ( finalcut::getColumnWidth(L"\r") == 0 ); CPPUNIT_ASSERT ( finalcut::getColumnWidth(L"\n") == 0 ); @@ -502,6 +504,21 @@ void FTermFunctionsTest::FullWidthHalfWidthTest() CPPUNIT_ASSERT ( finalcut::getColumnWidth(L"\U0000094d") == 0 ); CPPUNIT_ASSERT ( finalcut::getColumnWidth(L"\U00000e37") == 0 ); + // Column width (wchar_t) in latin-1 + std::setlocale (LC_CTYPE, "C"); + data->setTermEncoding (finalcut::Encoding::VT100); + CPPUNIT_ASSERT ( finalcut::getColumnWidth(L'─') == 1 ); // wcwidth(L'─') == -1 (for LC_CTYPE = C) + CPPUNIT_ASSERT ( finalcut::getColumnWidth(L'│') == 1 ); // wcwidth(L'│') == -1 (for LC_CTYPE = C) + CPPUNIT_ASSERT ( finalcut::getColumnWidth(L'├') == 1 ); // wcwidth(L'├') == -1 (for LC_CTYPE = C) + CPPUNIT_ASSERT ( finalcut::getColumnWidth(L'┤') == 1 ); // wcwidth(L'┤') == -1 (for LC_CTYPE = C) + CPPUNIT_ASSERT ( finalcut::getColumnWidth(L'┼') == 1 ); // wcwidth(L'┼') == -1 (for LC_CTYPE = C) + CPPUNIT_ASSERT ( finalcut::getColumnWidth(L'┐') == 1 ); // wcwidth(L'┐') == -1 (for LC_CTYPE = C) + CPPUNIT_ASSERT ( finalcut::getColumnWidth(L'└') == 1 ); // wcwidth(L'└') == -1 (for LC_CTYPE = C) + CPPUNIT_ASSERT ( finalcut::getColumnWidth(L'┌') == 1 ); // wcwidth(L'┌') == -1 (for LC_CTYPE = C) + CPPUNIT_ASSERT ( finalcut::getColumnWidth(L'┘') == 1 ); // wcwidth(L'┘') == -1 (for LC_CTYPE = C) + std::setlocale (LC_CTYPE, "en_US.UTF-8"); + data->setTermEncoding (finalcut::Encoding::UTF8); + // Column width (FString) CPPUNIT_ASSERT ( finalcut::getColumnWidth(L"\v\t 100") == 4 ); CPPUNIT_ASSERT ( finalcut::getColumnWidth(L"0123456789") == 10 ); @@ -733,25 +750,25 @@ void FTermFunctionsTest::FullWidthHalfWidthTest() std::copy(std::begin(s), std::end(s), std::begin(fchar.ch)); CPPUNIT_ASSERT ( finalcut::getColumnWidth(fchar) == 0 ); finalcut::addColumnWidth(fchar); - CPPUNIT_ASSERT ( finalcut::getColumnWidth(fchar) == 1 ); + CPPUNIT_ASSERT ( finalcut::getColumnWidth(fchar) == 2 ); fchar.attr.bit.char_width = 0x00 & 0x03; s = L"1"; std::copy(std::begin(s), std::end(s), std::begin(fchar.ch)); CPPUNIT_ASSERT ( finalcut::getColumnWidth(fchar) == 0 ); finalcut::addColumnWidth(fchar); - CPPUNIT_ASSERT ( finalcut::getColumnWidth(fchar) == 1 ); + CPPUNIT_ASSERT ( finalcut::getColumnWidth(fchar) == 2 ); fchar.attr.bit.char_width = 0x00 & 0x03; s = L"2"; std::copy(std::begin(s), std::end(s), std::begin(fchar.ch)); CPPUNIT_ASSERT ( finalcut::getColumnWidth(fchar) == 0 ); finalcut::addColumnWidth(fchar); - CPPUNIT_ASSERT ( finalcut::getColumnWidth(fchar) == 1 ); + CPPUNIT_ASSERT ( finalcut::getColumnWidth(fchar) == 2 ); fchar.attr.bit.char_width = 0x00 & 0x03; s = L"3"; std::copy(std::begin(s), std::end(s), std::begin(fchar.ch)); CPPUNIT_ASSERT ( finalcut::getColumnWidth(fchar) == 0 ); finalcut::addColumnWidth(fchar); - CPPUNIT_ASSERT ( finalcut::getColumnWidth(fchar) == 1 ); + CPPUNIT_ASSERT ( finalcut::getColumnWidth(fchar) == 2 ); fchar.attr.bit.char_width = 0x00 & 0x03; s = L"\U00000300"; std::copy(std::begin(s), std::end(s), std::begin(fchar.ch)); @@ -779,8 +796,6 @@ void FTermFunctionsTest::FullWidthHalfWidthTest() fchar.attr.bit.char_width = 0x00 & 0x03; // Column width (FTermBuffer) - const auto& data = finalcut::FTerm::getFTermData(); - data->setTermEncoding (finalcut::Encoding::UTF8); finalcut::FTermBuffer term_buf{}; term_buf << L"\v\t 100"; CPPUNIT_ASSERT ( finalcut::getColumnWidth(term_buf) == 4 );