resolved RESOLVED UNSUBMITTED PASS · None tool calls · 0 s · Textualize/rich
Fix ZWJ and edge cases Fixes https://github.com/Textualize/rich/issues/3947 Fixes https://github.com/Textualize/rich/issues/3950
| # | Tool | Arguments | Result |
|---|---|---|---|
| No trace captured. | |||
--- a/rich/cells.py
+++ b/rich/cells.py
@@ -55,23 +55,26 @@ def get_character_cell_size(character: str, unicode_version: str = "auto") -> in
int: Number of cells (0, 1 or 2) occupied by that character.
"""
codepoint = ord(character)
+ if codepoint and codepoint < 32 or 0x07F <= codepoint < 0x0A0:
+ return 0
table = load_cell_table(unicode_version).widths
- if codepoint > table[-1][1]:
+
+ last_entry = table[-1]
+ if codepoint > last_entry[1]:
return 1
+
lower_bound = 0
upper_bound = len(table) - 1
- index = (lower_bound + upper_bound) // 2
- while True:
+
+ while lower_bound <= upper_bound:
+ index = (lower_bound + upper_bound) >> 1
start, end, width = table[index]
if codepoint < start:
upper_bound = index - 1
elif codepoint > end:
lower_bound = index + 1
else:
- return 0 if width == -1 else width
- if upper_bound < lower_bound:
- break
- index = (lower_bound + upper_bound) // 2
+ return width
return 1
@@ -135,19 +138,22 @@ def _cell_len(text: str, unicode_version: str) -> int:
SPECIAL = {"\u200d", "\ufe0f"}
- iter_characters = iter(text)
+ index = 0
+ character_count = len(text)
- for character in iter_characters:
+ while index < character_count:
+ character = text[index]
if character in SPECIAL:
if character == "\u200d":
- next(iter_characters)
+ index += 1
elif last_measured_character:
total_width += last_measured_character in cell_table.narrow_to_wide
last_measured_character = None
else:
if character_width := get_character_cell_size(character, unicode_version):
last_measured_character = character
total_width += character_width
+ index += 1
return total_width
........................................................ [100%] 56 passed in 0.04s