@@ -55,23 +55,26 @@ def get_character_cell_size(character: str, unicode_version: str = "auto") -> in
5555 int: Number of cells (0, 1 or 2) occupied by that character.
5656 """
5757 codepoint = ord (character )
58+ if codepoint and codepoint < 32 or 0x07F <= codepoint < 0x0A0 :
59+ return 0
5860 table = load_cell_table (unicode_version ).widths
59- if codepoint > table [- 1 ][1 ]:
61+
62+ last_entry = table [- 1 ]
63+ if codepoint > last_entry [1 ]:
6064 return 1
65+
6166 lower_bound = 0
6267 upper_bound = len (table ) - 1
63- index = (lower_bound + upper_bound ) // 2
64- while True :
68+
69+ while lower_bound <= upper_bound :
70+ index = (lower_bound + upper_bound ) >> 1
6571 start , end , width = table [index ]
6672 if codepoint < start :
6773 upper_bound = index - 1
6874 elif codepoint > end :
6975 lower_bound = index + 1
7076 else :
71- return 0 if width == - 1 else width
72- if upper_bound < lower_bound :
73- break
74- index = (lower_bound + upper_bound ) // 2
77+ return width
7578 return 1
7679
7780
@@ -135,19 +138,22 @@ def _cell_len(text: str, unicode_version: str) -> int:
135138
136139 SPECIAL = {"\u200d " , "\ufe0f " }
137140
138- iter_characters = iter (text )
141+ index = 0
142+ character_count = len (text )
139143
140- for character in iter_characters :
144+ while index < character_count :
145+ character = text [index ]
141146 if character in SPECIAL :
142147 if character == "\u200d " :
143- next ( iter_characters )
148+ index += 1
144149 elif last_measured_character :
145150 total_width += last_measured_character in cell_table .narrow_to_wide
146151 last_measured_character = None
147152 else :
148153 if character_width := get_character_cell_size (character , unicode_version ):
149154 last_measured_character = character
150155 total_width += character_width
156+ index += 1
151157
152158 return total_width
153159
0 commit comments