diff --git a/src/listview_curses.cc b/src/listview_curses.cc index c3f9c086..cc5fabf5 100644 --- a/src/listview_curses.cc +++ b/src/listview_curses.cc @@ -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(); diff --git a/src/view_curses.cc b/src/view_curses.cc index 4e67ac8b..9dc671f5 100644 --- a/src/view_curses.cc +++ b/src/view_curses.cc @@ -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; diff --git a/src/view_curses.hh b/src/view_curses.hh index c3a8b6e5..4981bf20 100644 --- a/src/view_curses.hh +++ b/src/view_curses.hh @@ -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}; diff --git a/test/textfile_cjk.0 b/test/textfile_cjk.0 new file mode 100644 index 00000000..09c48997 --- /dev/null +++ b/test/textfile_cjk.0 @@ -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. \ No newline at end of file