[view_curses] fix wrapping issues with CJK characters

Related to #935
master
Tim Stack 1 month ago
parent 03d000736f
commit 49aea165d4

@ -425,25 +425,22 @@ listview_curses::do_update()
require_ge(attr.sa_range.lr_start, 0);
}
size_t remaining = 0;
view_curses::mvwattrline_result write_res;
do {
remaining = mvwattrline(this->lv_window,
if (this->lv_word_wrap) {
mvwhline(this->lv_window, y, this->lv_x, ' ', width);
}
write_res = mvwattrline(this->lv_window,
y,
this->lv_x,
al,
lr,
this->vc_default_role);
if (this->lv_word_wrap) {
mvwhline(this->lv_window,
y,
this->lv_x + wrap_width,
' ',
width - wrap_width);
}
lr.lr_start += wrap_width;
lr.lr_end += wrap_width;
lr.lr_start += write_res.mr_chars_out;
lr.lr_end += write_res.mr_chars_out;
++y;
} while (this->lv_word_wrap && y < bottom && remaining > 0);
} while (this->lv_word_wrap && y < bottom
&& write_res.mr_bytes_remaining > 0);
if (this->lv_overlay_source != nullptr) {
row_overlay_content.clear();

@ -140,7 +140,7 @@ view_curses::awaiting_user_input()
}
}
size_t
view_curses::mvwattrline_result
view_curses::mvwattrline(WINDOW* window,
int y,
const int x,
@ -155,6 +155,7 @@ view_curses::mvwattrline(WINDOW* window,
require(lr_chars.lr_end >= 0);
mvwattrline_result retval;
auto line_width_chars = lr_chars.length();
std::string expanded_line;
line_range lr_bytes;
@ -168,6 +169,7 @@ view_curses::mvwattrline(WINDOW* window,
lr_bytes.lr_start = exp_start_index;
} else if (char_index == lr_chars.lr_end) {
lr_bytes.lr_end = exp_start_index;
retval.mr_chars_out = char_index;
}
switch (ch) {
@ -234,6 +236,10 @@ view_curses::mvwattrline(WINDOW* window,
}
auto wch = read_res.unwrap();
char_index += wcwidth(wch);
if (lr_bytes.lr_end == -1 && char_index > lr_chars.lr_end) {
lr_bytes.lr_end = exp_start_index;
retval.mr_chars_out = char_index - wcwidth(wch);
}
}
break;
}
@ -245,7 +251,10 @@ view_curses::mvwattrline(WINDOW* window,
if (lr_bytes.lr_end == -1) {
lr_bytes.lr_end = expanded_line.size();
}
size_t retval = expanded_line.size() - lr_bytes.lr_end;
if (retval.mr_chars_out == 0) {
retval.mr_chars_out = char_index;
}
retval.mr_bytes_remaining = expanded_line.size() - lr_bytes.lr_end;
full_line = expanded_line;

@ -387,12 +387,17 @@ public:
static void awaiting_user_input();
static size_t mvwattrline(WINDOW* window,
int y,
int x,
attr_line_t& al,
const struct line_range& lr,
role_t base_role = role_t::VCR_TEXT);
struct mvwattrline_result {
size_t mr_chars_out{0};
size_t mr_bytes_remaining{0};
};
static mvwattrline_result mvwattrline(WINDOW* window,
int y,
int x,
attr_line_t& al,
const struct line_range& lr,
role_t base_role = role_t::VCR_TEXT);
protected:
bool vc_visible{true};

@ -0,0 +1,3 @@
一二三四五六七八九十Group1一二三四五六七八九十Group2一二三四五六七八九十Group3一二三四五六七八九十Group4一二三四五六七八九十Group5
This is an example of a normally-behavioring text wrap example. All letters are ASCII and containing no CJK letters.
Loading…
Cancel
Save