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 | * License along with mpv. If not, see <http://www.gnu.org/licenses/>. | 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 | static const int ambiguous_width = 1; | 669 | static const int ambiguous_width = 1; |
| 668 | 670 | ||
| 669 | int width = 0; | 671 | int width = 0; |
| 670 | 672 | ||
| 673 | const unsigned char *prev_pos = str.start; | ||
| 671 | while (str.len) { | 674 | while (str.len) { |
| 675 | int current_width = 0; | ||
| 676 | |||
| 672 | if (bstr_eatstart0(&str, "\033[")) { | 677 | if (bstr_eatstart0(&str, "\033[")) { |
| 673 | while (str.len && !((*str.start >= '@' && *str.start <= '~') || *str.start == 'm')) | 678 | while (str.len && !((*str.start >= '@' && *str.start <= '~') || *str.start == 'm')) |
| 674 | str = bstr_cut(str, 1); | 679 | str = bstr_cut(str, 1); |
| 675 | str = bstr_cut(str, 1); | 680 | str = bstr_cut(str, 1); |
| 676 | continue; | 681 | goto next; |
| 677 | } | 682 | } |
| 678 | 683 | ||
| 684 | prev_pos = str.start; | ||
| 679 | int cp = bstr_decode_utf8(str, &str); | 685 | int cp = bstr_decode_utf8(str, &str); |
| 680 | 686 | ||
| 681 | // Stop processing on any invalid input | 687 | // Stop processing on any invalid input |
| @@ -684,18 +690,17 @@ int term_disp_width(bstr str) · 2 unmodified lines | |||
| 684 | 690 | ||
| 685 | if (cp == '\r') { | 691 | if (cp == '\r') { |
| 686 | width = 0; | 692 | width = 0; |
| 687 | continue; | 693 | goto next; |
| 688 | } | 694 | } |
| 689 | 695 | ||
| 690 | if (cp < 0x20) | 696 | if (cp < 0x20) |
| 691 | continue; | 697 | goto next; |
| 692 | 698 | ||
| 693 | if (cp <= 0x7E) { | 699 | if (cp <= 0x7E) { |
| 694 | width++; | 700 | current_width = 1; |
| 695 | continue; | 701 | goto next; |
| 696 | } | 702 | } |
| 697 | 703 | ||
| 698 | int grapheme_width = 0; | ||
| 699 | int state = 0; | 704 | int state = 0; |
| 700 | 705 | ||
| 701 | while (true) { | 706 | while (true) { |
| @@ -711,7 +716,7 @@ int term_disp_width(bstr str) · 9 unmodified lines | |||
| 711 | if (cp == 0xFE0F) | 716 | if (cp == 0xFE0F) |
| 712 | w = 2; | 717 | w = 2; |
| 713 | 718 | ||
| 714 | grapheme_width += w; | 719 | current_width += w; |
| 715 | 720 | ||
| 716 | if (!str.len) | 721 | if (!str.len) |
| 717 | break; | 722 | break; |
| @@ -730,7 +735,20 @@ int term_disp_width(bstr str) · 12 unmodified lines | |||
| 730 | 735 | ||
| 731 | str = cluster_end; | 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 | return width; | 754 | return width; |