summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorKacper Michajłow <kasper93@gmail.com>2023-12-23 20:09:06 +0100
committerDudemanguy <random342@airmail.cc>2024-01-04 13:41:06 +0000
commit5864b72d1a0aecd7e2d56e546fb615d291c88274 (patch)
treed03d5d0cdfdbe5dd87c18b56999e0507b29384d2 /common
parent687372e2a25453edcc6dca8748d7cb22782678e4 (diff)
downloadmpv-5864b72d1a0aecd7e2d56e546fb615d291c88274.tar.bz2
mpv-5864b72d1a0aecd7e2d56e546fb615d291c88274.tar.xz
msg: improve term_disp_width to support unicode
All characters are assumed to be single-width. This is consistent with the rest of the code and documentation. Fixes: #13150
Diffstat (limited to 'common')
-rw-r--r--common/msg.c25
1 files changed, 12 insertions, 13 deletions
diff --git a/common/msg.c b/common/msg.c
index f630d1ecc7..3373121c38 100644
--- a/common/msg.c
+++ b/common/msg.c
@@ -336,31 +336,30 @@ static bool test_terminal_level(struct mp_log *log, int lev)
}
// This is very basic way to infer needed width for a string.
-static int term_disp_width(bstr str, size_t start, size_t end)
+static int term_disp_width(bstr str)
{
int width = 0;
- bool escape = false;
- const char *line = str.start;
- for (size_t i = start; i < end && i < str.len; ++i) {
- if (escape) {
- escape = !(line[i] >= '@' && line[i] <= '~');
+ while (str.len) {
+ if (bstr_eatstart0(&str, "\033[")) {
+ while (str.len && !((*str.start >= '@' && *str.start <= '~') || *str.start == 'm'))
+ str = bstr_cut(str, 1);
+ str = bstr_cut(str, 1);
continue;
}
- if (line[i] == '\033' && line[i + 1] == '[') {
- escape = true;
- ++i;
+ bstr code = bstr_split_utf8(str, &str);
+ if (code.len == 0)
continue;
- }
- if (line[i] == '\n')
+ if (code.len == 1 && *code.start == '\n')
continue;
+ // Only single-width characters are supported
width++;
// Assume that everything before \r should be discarded for simplicity
- if (line[i] == '\r')
+ if (code.len == 1 && *code.start == '\r')
width = 0;
}
@@ -389,7 +388,7 @@ static void append_terminal_line(struct mp_log *log, int lev,
bstr_xappend(root, term_msg, text);
*line_w = root->isatty[term_msg_fileno(root, lev)]
- ? term_disp_width(*term_msg, start, term_msg->len) : 0;
+ ? term_disp_width(bstr_splice(*term_msg, start, term_msg->len)) : 0;
}
static struct mp_log_buffer_entry *log_buffer_read(struct mp_log_buffer *buffer)