| 495 | } |
| 496 | |
| 497 | static void set_line_contents(std::string new_line, std::string & line, std::vector<int> & widths, size_t & char_pos, |
| 498 | size_t & byte_pos, int cursor_byte_pos = -1) { |
| 499 | move_to_line_start(char_pos, byte_pos, widths); |
| 500 | clear_current_line(widths); |
| 501 | |
| 502 | line = std::move(new_line); |
| 503 | widths.clear(); |
| 504 | byte_pos = 0; |
| 505 | char_pos = 0; |
| 506 | |
| 507 | size_t idx = 0; |
| 508 | int back_width = 0; |
| 509 | while (idx < line.size()) { |
| 510 | size_t advance = 0; |
| 511 | char32_t cp = decode_utf8(line, idx, advance); |
| 512 | int expected_width = estimateWidth(cp); |
| 513 | int real_width = put_codepoint(line.c_str() + idx, advance, expected_width); |
| 514 | if (real_width < 0) real_width = 0; |
| 515 | widths.push_back(real_width); |
| 516 | idx += advance; |
| 517 | if (cursor_byte_pos >= 0 && static_cast<size_t>(cursor_byte_pos) < idx) { |
| 518 | back_width += real_width; |
| 519 | } else { |
| 520 | ++char_pos; |
| 521 | byte_pos = idx; |
| 522 | } |
| 523 | } |
| 524 | if (cursor_byte_pos >= 0) { |
| 525 | move_cursor(-back_width); |
| 526 | } |
| 527 | } |
| 528 | |
| 529 | static void move_to_line_start(size_t & char_pos, size_t & byte_pos, const std::vector<int> & widths) { |
| 530 | int back_width = 0; |
no test coverage detected