raylib: ban non-cached measure_text_ex (#35462)

* add

* use it

* Update pyproject.toml

* many more

* comment
This commit is contained in:
Shane Smiskol
2025-06-05 14:37:12 -07:00
committed by GitHub
parent 3a622cbe25
commit 2000f9aff3
8 changed files with 20 additions and 12 deletions
+2 -1
View File
@@ -1,6 +1,7 @@
import pyray as rl
from enum import IntEnum
from openpilot.system.ui.lib.application import gui_app, FontWeight
from openpilot.system.ui.lib.text_measure import measure_text_cached
class ButtonStyle(IntEnum):
@@ -99,7 +100,7 @@ def gui_button(
# Handle icon and text positioning
font = gui_app.font(font_weight)
text_size = rl.measure_text_ex(font, text, font_size, 0)
text_size = measure_text_cached(font, text, font_size)
text_pos = rl.Vector2(0, rect.y + (rect.height - text_size.y) // 2) # Vertical centering
# Draw icon if provided
+4 -3
View File
@@ -1,6 +1,7 @@
import pyray as rl
import time
from openpilot.system.ui.lib.application import gui_app
from openpilot.system.ui.lib.text_measure import measure_text_cached
PASSWORD_MASK_CHAR = ""
@@ -60,7 +61,7 @@ class InputBox:
padding = 10
if self._cursor_position > 0:
cursor_x = rl.measure_text_ex(font, display_text[: self._cursor_position], self._font_size, 0).x
cursor_x = measure_text_cached(font, display_text[: self._cursor_position], self._font_size).x
else:
cursor_x = 0
@@ -141,7 +142,7 @@ class InputBox:
if self._show_cursor:
cursor_x = rect.x + padding
if len(display_text) > 0 and self._cursor_position > 0:
cursor_x += rl.measure_text_ex(font, display_text[: self._cursor_position], font_size, 0).x
cursor_x += measure_text_cached(font, display_text[: self._cursor_position], font_size).x
# Apply text offset to cursor position
cursor_x -= self._text_offset
@@ -182,7 +183,7 @@ class InputBox:
min_distance = float('inf')
for i in range(len(self._input_text) + 1):
char_width = rl.measure_text_ex(font, display_text[:i], font_size, 0).x
char_width = measure_text_cached(font, display_text[:i], font_size).x
distance = abs(relative_x - char_width)
if distance < min_distance:
min_distance = distance
+4 -3
View File
@@ -1,5 +1,6 @@
import pyray as rl
from openpilot.system.ui.lib.application import gui_app, FontWeight, DEFAULT_TEXT_SIZE, DEFAULT_TEXT_COLOR
from openpilot.system.ui.lib.text_measure import measure_text_cached
from openpilot.system.ui.lib.utils import GuiStyleContext
@@ -14,7 +15,7 @@ def gui_label(
elide_right: bool = True
):
font = gui_app.font(font_weight)
text_size = rl.measure_text_ex(font, text, font_size, 0)
text_size = measure_text_cached(font, text, font_size)
display_text = text
# Elide text to fit within the rectangle
@@ -24,13 +25,13 @@ def gui_label(
while left < right:
mid = (left + right) // 2
candidate = text[:mid] + ellipsis
candidate_size = rl.measure_text_ex(font, candidate, font_size, 0)
candidate_size = measure_text_cached(font, candidate, font_size)
if candidate_size.x <= rect.width:
left = mid + 1
else:
right = mid
display_text = text[: left - 1] + ellipsis if left > 0 else ellipsis
text_size = rl.measure_text_ex(font, display_text, font_size, 0)
text_size = measure_text_cached(font, display_text, font_size)
# Calculate horizontal position based on alignment
text_x = rect.x + {
+2 -1
View File
@@ -4,10 +4,11 @@ _cache: dict[int, rl.Vector2] = {}
def measure_text_cached(font: rl.Font, text: str, font_size: int, spacing: int = 0) -> rl.Vector2:
"""Caches text measurements to avoid redundant calculations."""
key = hash((font.texture.id, text, font_size, spacing))
if key in _cache:
return _cache[key]
result = rl.measure_text_ex(font, text, font_size, spacing)
result = rl.measure_text_ex(font, text, font_size, spacing) # noqa: TID251
_cache[key] = result
return result
+2 -1
View File
@@ -4,6 +4,7 @@ import threading
import time
from openpilot.system.ui.lib.application import gui_app
from openpilot.system.ui.lib.text_measure import measure_text_cached
from openpilot.system.ui.lib.window import BaseWindow
from openpilot.system.ui.text import wrap_text
@@ -78,7 +79,7 @@ class SpinnerRenderer:
rl.draw_rectangle_rounded(bar, 1, 10, rl.WHITE)
elif wrapped_lines:
for i, line in enumerate(wrapped_lines):
text_size = rl.measure_text_ex(gui_app.font(), line, FONT_SIZE, 0.0)
text_size = measure_text_cached(gui_app.font(), line, FONT_SIZE)
rl.draw_text_ex(gui_app.font(), line, rl.Vector2(center.x - text_size.x / 2, y_pos + i * LINE_HEIGHT),
FONT_SIZE, 0.0, rl.WHITE)
+2 -1
View File
@@ -3,6 +3,7 @@ import re
import time
import pyray as rl
from openpilot.system.hardware import HARDWARE, PC
from openpilot.system.ui.lib.text_measure import measure_text_cached
from openpilot.system.ui.lib.button import gui_button, ButtonStyle
from openpilot.system.ui.lib.scroll_panel import GuiScrollPanel
from openpilot.system.ui.lib.application import gui_app
@@ -33,7 +34,7 @@ def wrap_text(text, font_size, max_width):
while len(words):
word = words.pop(0)
test_line = current_line + word + (words.pop(0) if words else "")
if rl.measure_text_ex(font, test_line, font_size, 0).x <= max_width:
if measure_text_cached(font, test_line, font_size).x <= max_width:
current_line = test_line
else:
lines.append(current_line)