@@ -55,23 +55,32 @@ 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+ # Fast path: codepoint beyond table range
63+ last_entry = table [- 1 ]
64+ if codepoint > last_entry [1 ]:
6065 return 1
66+
67+ # Binary search with fewer tuple unpacks
6168 lower_bound = 0
6269 upper_bound = len (table ) - 1
63- index = (lower_bound + upper_bound ) // 2
64- while True :
65- start , end , width = table [index ]
70+
71+ while lower_bound <= upper_bound :
72+ index = (lower_bound + upper_bound ) >> 1 # Faster than // 2
73+ entry = table [index ]
74+ start = entry [0 ]
75+
6676 if codepoint < start :
6777 upper_bound = index - 1
68- elif codepoint > end :
78+ elif codepoint > entry [ 1 ]: # end
6979 lower_bound = index + 1
7080 else :
71- return 0 if width == - 1 else width
72- if upper_bound < lower_bound :
73- break
74- index = (lower_bound + upper_bound ) // 2
81+ # Found: codepoint is in range [start, end]
82+ return entry [2 ]
83+
7584 return 1
7685
7786
@@ -135,19 +144,20 @@ def _cell_len(text: str, unicode_version: str) -> int:
135144
136145 SPECIAL = {"\u200d " , "\ufe0f " }
137146
138- iter_characters = iter (text )
147+ index = 0
148+ character_count = len (text )
139149
140- for character in iter_characters :
150+ while index < character_count :
151+ character = text [index ]
141152 if character in SPECIAL :
142- if character == "\u200d " :
143- next (iter_characters )
144- elif last_measured_character :
153+ if character == "\ufe0f " and last_measured_character :
145154 total_width += last_measured_character in cell_table .narrow_to_wide
146155 last_measured_character = None
147156 else :
148157 if character_width := get_character_cell_size (character , unicode_version ):
149158 last_measured_character = character
150159 total_width += character_width
160+ index += 1
151161
152162 return total_width
153163
0 commit comments