Showing the changes to misc/codepoint_width.c (1 of 9 files). Show all
Unified · Split
| @@ -662,20 +662,26 @@ static int ucdToCharacterWidth(const int val) · 661 unmodified lines | ||
| 662 | 662 | * License along with mpv. If not, see <http://www.gnu.org/licenses/>. |
| 663 | 663 | */ |
| 664 | 664 | |
| 665 | −int term_disp_width(bstr str) | |
| 665 | +#include "common/common.h" | |
| 666 | + | |
| 667 | +int term_disp_width(bstr str, int max_width, const unsigned char **cut_pos) | |
| 666 | 668 | { |
| 667 | 669 | static const int ambiguous_width = 1; |
| 668 | 670 | |
| 669 | 671 | int width = 0; |
| 670 | 672 | |
| 673 | + const unsigned char *prev_pos = str.start; | |
| 671 | 674 | while (str.len) { |
| 675 | + int current_width = 0; | |
| 676 | + | |
| 672 | 677 | if (bstr_eatstart0(&str, "\033[")) { |
| 673 | 678 | while (str.len && !((*str.start >= '@' && *str.start <= '~') || *str.start == 'm')) |
| 674 | 679 | str = bstr_cut(str, 1); |
| 675 | 680 | str = bstr_cut(str, 1); |
| 676 | − continue; | |
| 681 | + goto next; | |
| 677 | 682 | } |
| 678 | 683 | |
| 684 | + prev_pos = str.start; | |
| 679 | 685 | int cp = bstr_decode_utf8(str, &str); |
| 680 | 686 | |
| 681 | 687 | // Stop processing on any invalid input |
| @@ -684,18 +690,17 @@ int term_disp_width(bstr str) · 2 unmodified lines | ||
| 684 | 690 | |
| 685 | 691 | if (cp == '\r') { |
| 686 | 692 | width = 0; |
| 687 | − continue; | |
| 693 | + goto next; | |
| 688 | 694 | } |
| 689 | 695 | |
| 690 | 696 | if (cp < 0x20) |
| 691 | − continue; | |
| 697 | + goto next; | |
| 692 | 698 | |
| 693 | 699 | if (cp <= 0x7E) { |
| 694 | − width++; | |
| 695 | − continue; | |
| 700 | + current_width = 1; | |
| 701 | + goto next; | |
| 696 | 702 | } |
| 697 | 703 | |
| 698 | − int grapheme_width = 0; | |
| 699 | 704 | int state = 0; |
| 700 | 705 | |
| 701 | 706 | while (true) { |
| @@ -711,7 +716,7 @@ int term_disp_width(bstr str) · 9 unmodified lines | ||
| 711 | 716 | if (cp == 0xFE0F) |
| 712 | 717 | w = 2; |
| 713 | 718 | |
| 714 | − grapheme_width += w; | |
| 719 | + current_width += w; | |
| 715 | 720 | |
| 716 | 721 | if (!str.len) |
| 717 | 722 | break; |
| @@ -730,7 +735,20 @@ int term_disp_width(bstr str) · 12 unmodified lines | ||
| 730 | 735 | |
| 731 | 736 | str = cluster_end; |
| 732 | 737 | } |
| 733 | − width += grapheme_width > 2 ? 2 : grapheme_width; | |
| 738 | + | |
| 739 | +next: | |
| 740 | + current_width = MPMIN(current_width, 2); | |
| 741 | + if (width + current_width > max_width) { | |
| 742 | + assert(prev_pos < str.start + str.len); | |
| 743 | + *cut_pos = prev_pos; | |
| 744 | + break; | |
| 745 | + } | |
| 746 | + width += current_width; | |
| 747 | + if (width == max_width) { | |
| 748 | + if (str.len) | |
| 749 | + *cut_pos = str.start; | |
| 750 | + break; | |
| 751 | + } | |
| 734 | 752 | } |
| 735 | 753 | |
| 736 | 754 | return width; |