[view_curses] fix wrapping issues with CJK characters

Related to #935
pull/1265/head
Tim Stack 2 months ago
parent 03d000736f
commit 49aea165d4

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

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

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