[FarGroup/FarManager] master: Continue fullwidth-aware rendering (43ca2c386)

0 views
Skip to first unread message

farg...@farmanager.com

unread,
Feb 21, 2026, 2:30:56 PM (5 days ago) Feb 21
to farco...@googlegroups.com
Repository : https://github.com/FarGroup/FarManager
On branch : master
Link : https://github.com/FarGroup/FarManager/commit/43ca2c386a067f80dbb4fd12ca8881d8340747bf

>---------------------------------------------------------------

commit 43ca2c386a067f80dbb4fd12ca8881d8340747bf
Author: Alex Alabuzhev <alab...@gmail.com>
Date: Sat Feb 21 19:22:15 2026 +0000

Continue fullwidth-aware rendering


>---------------------------------------------------------------

43ca2c386a067f80dbb4fd12ca8881d8340747bf
far/changelog | 5 +++++
far/char_width.cpp | 65 +++++++++++++++++++-----------------------------------
far/char_width.hpp | 2 +-
far/config.cpp | 4 ++--
far/config.hpp | 2 +-
far/interf.cpp | 4 ++--
far/testing.cpp | 17 ++++++++++++--
far/testing.hpp | 1 +
far/vbuild.m4 | 2 +-
9 files changed, 51 insertions(+), 51 deletions(-)

diff --git a/far/changelog b/far/changelog
index 9f4e07329..92a479489 100644
--- a/far/changelog
+++ b/far/changelog
@@ -1,3 +1,8 @@
+--------------------------------------------------------------------------------
+drkns 2026-02-21 19:21:50+00:00 - build 6646
+
+1. Continue fullwidth-aware rendering.
+
--------------------------------------------------------------------------------
drkns 2026-02-19 21:12:02+00:00 - build 6645

diff --git a/far/char_width.cpp b/far/char_width.cpp
index f71e586ca..6c2708e9e 100644
--- a/far/char_width.cpp
+++ b/far/char_width.cpp
@@ -48,18 +48,15 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// External:

+#ifdef ENABLE_TESTS
+#include "testing.hpp"
+#endif
+
//----------------------------------------------------------------------------

namespace
{
- enum class full_width
- {
- off,
- on,
- automatic
- };
-
- auto s_FullWidthState = full_width::off;
+ auto s_FullWidthEnabled = false;

enum class codepoint_width: signed char
{
@@ -457,8 +454,14 @@ namespace
}

[[nodiscard]]
- auto is_fullwidth_needed()
+ auto is_fullwidth_supported()
{
+#ifdef ENABLE_TESTS
+ if (is_test_run())
+ return true;
+#endif
+
+ // FW works in VT (Win10+) and in classic grid mode with CJK locales (LVB)
return console.IsVtSupported() || locale.is_cjk();
}

@@ -484,9 +487,12 @@ namespace
[[nodiscard]]
bool is_legacy_rendering()
{
- DWORD Mode;
- static const auto IsRedirected = !console.GetMode(console.GetOutputHandle(), Mode);
- return !IsRedirected && !console.IsVtActive();
+#ifdef ENABLE_TESTS
+ if (is_test_run())
+ return false;
+#endif
+
+ return !console.IsVtActive();
}
}

@@ -498,21 +504,10 @@ namespace char_width
if (!is_bmp(Codepoint) && is_legacy_rendering())
return 2; // Classic grid mode, nothing we can do :(

- switch (s_FullWidthState)
- {
- default:
- case full_width::off:
+ if (!s_FullWidthEnabled || !is_fullwidth_supported())
return 1;

- case full_width::automatic:
- if (!is_fullwidth_needed())
- return 1;
-
- [[fallthrough]];
-
- case full_width::on:
- return static_cast<size_t>(get_width(Codepoint));
- }
+ return static_cast<size_t>(get_width(Codepoint));
}

[[nodiscard]]
@@ -521,29 +516,15 @@ namespace char_width
return get(Codepoint) > 1;
}

- void enable(int const Value)
+ void enable(bool const Value)
{
- switch (Value)
- {
- case BSTATE_UNCHECKED:
- invalidate();
- s_FullWidthState = full_width::off;
- break;
-
- case BSTATE_CHECKED:
- s_FullWidthState = full_width::on;
- break;
-
- case BSTATE_3STATE:
- s_FullWidthState = full_width::automatic;
- break;
- }
+ s_FullWidthEnabled = Value;
}

[[nodiscard]]
bool is_enabled()
{
- return s_FullWidthState != full_width::off;
+ return s_FullWidthEnabled;
}

void invalidate()
diff --git a/far/char_width.hpp b/far/char_width.hpp
index 8a8bcf7dd..343065204 100644
--- a/far/char_width.hpp
+++ b/far/char_width.hpp
@@ -54,7 +54,7 @@ namespace char_width
[[nodiscard]]
bool is_wide(codepoint Codepoint);

- void enable(int Value);
+ void enable(bool Value);

[[nodiscard]]
bool is_enabled();
diff --git a/far/config.cpp b/far/config.cpp
index b4457b1e6..949cc3882 100644
--- a/far/config.cpp
+++ b/far/config.cpp
@@ -1867,9 +1867,9 @@ Options::Options():
console.EnableVirtualTerminal(Value);
}));

- FullWidthAwareRendering.SetCallback(option::notifier([](long long const Value)
+ FullWidthAwareRendering.SetCallback(option::notifier([](bool const Value)
{
- char_width::enable(static_cast<int>(Value));
+ char_width::enable(Value);
}));

Clock.SetCallback(option::notifier([](bool const Value)
diff --git a/far/config.hpp b/far/config.hpp
index dc2e5b9e9..3f43e7505 100644
--- a/far/config.hpp
+++ b/far/config.hpp
@@ -982,7 +982,7 @@ public:

BoolOption VirtualTerminalRendering;
Bool3Option ClearType;
- Bool3Option FullWidthAwareRendering;
+ BoolOption FullWidthAwareRendering;

Bool3Option PgUpChangeDisk;
BoolOption ShowDotsInRoot;
diff --git a/far/interf.cpp b/far/interf.cpp
index a3d304d9e..7d8d216cb 100644
--- a/far/interf.cpp
+++ b/far/interf.cpp
@@ -1960,7 +1960,7 @@ TEST_CASE("wide_chars")

const auto IsVtActive = console.IsVtActive();

- char_width::enable(1);
+ char_width::enable(true);

for (const auto& i: Tests)
{
@@ -1980,7 +1980,7 @@ TEST_CASE("wide_chars")
}
}

- char_width::enable(0);
+ char_width::enable(false);
}

TEST_CASE("tabs")
diff --git a/far/testing.cpp b/far/testing.cpp
index 5e0dd7454..d0fcb3499 100644
--- a/far/testing.cpp
+++ b/far/testing.cpp
@@ -90,10 +90,18 @@ static bool is_ui_test_run(std::span<wchar_t const* const> const Args)
return false;
}

+static bool s_IsTestRun;
+
+static int run_tests(std::span<wchar_t const* const> const Args)
+{
+ s_IsTestRun = true;
+ return Catch::Session().run(static_cast<int>(Args.size()), Args.data());
+}
+
std::optional<int> testing_main(std::span<wchar_t const* const> const Args)
{
if (is_ui_test_run(Args.subspan(1)))
- return Catch::Session().run(static_cast<int>(Args.size()), Args.data());
+ return run_tests(Args);

const auto ServiceTestIterator = std::ranges::find(Args, L"/service:test"sv);
const auto IsBuildStep = ServiceTestIterator != Args.end();
@@ -138,7 +146,12 @@ std::optional<int> testing_main(std::span<wchar_t const* const> const Args)

locale = invariant_locale();

- return Catch::Session().run(static_cast<int>(NewArgs.size()), NewArgs.data());
+ return run_tests(NewArgs);
+}
+
+bool is_test_run()
+{
+ return s_IsTestRun;
}

namespace
diff --git a/far/testing.hpp b/far/testing.hpp
index d3bf06b9a..d600d2850 100644
--- a/far/testing.hpp
+++ b/far/testing.hpp
@@ -97,6 +97,7 @@ private:
#endif

std::optional<int> testing_main(std::span<wchar_t const* const> Args);
+bool is_test_run();

#endif

diff --git a/far/vbuild.m4 b/far/vbuild.m4
index 77a875b3a..28180d18c 100644
--- a/far/vbuild.m4
+++ b/far/vbuild.m4
@@ -1 +1 @@
-6645
+6646


Reply all
Reply to author
Forward
0 new messages