Center Reverse Gear Text

This commit is contained in:
firestarsdog
2026-10-18 22:56:34 -04:00
parent c68fa22202
commit c2f46fd534
2 changed files with 32 additions and 2 deletions
+8 -2
View File
@@ -21,8 +21,14 @@ class AlertRenderer:
def _center(self, text: str, role: FontRole, size: int, rect: rl.Rectangle, y: float,
color: rl.Color = rl.WHITE, *, letter_spacing: float = 0) -> None:
spacing = size * letter_spacing
measured = self.fonts.measure(text, role, size, spacing=spacing)
self.fonts.draw(text, role, size, rect.x + (rect.width - measured.width) / 2, y, color, spacing=spacing)
lines = text.split('\n')
height = self.fonts.measure(text, role, size, spacing=spacing).height
# Preserve Raylib's measured newline spacing when drawing lines separately.
line_step = (height - self.fonts.measure(lines[0], role, size, spacing=spacing).height) / max(1, len(lines) - 1)
for line in lines:
measured = self.fonts.measure(line, role, size, spacing=spacing)
self.fonts.draw(line, role, size, rect.x + (rect.width - measured.width) / 2, y, color, spacing=spacing)
y += line_step
def render(self, rect: rl.Rectangle, alert: OnroadAlert, *, signal_direction: int = 0) -> None:
event_name = alert.alert_type.split('/', 1)[0]
@@ -9,6 +9,30 @@ from openpilot.starpilot.ui.onroad_state import AlertSize, OnroadAlert
from openpilot.starpilot.ui.presentation import FontRole, Profile
@pytest.mark.parametrize('width', [1860, 2160])
@pytest.mark.parametrize('text', ['Reverse\nGear', 'Reverse Gear'])
def test_large_reverse_alert_centers_each_line_in_camera_view(width, text):
fonts = Mock(profile=Profile.LARGE)
def measure(text, role, size, **kwargs):
lines = text.split('\n')
return NS(width=max(len(line) for line in lines) * size * .5,
height=len(lines) * size + (len(lines) - 1) * 2)
fonts.measure.side_effect = measure
renderer = onroad_alerts.AlertRenderer(fonts)
bounds = rl.Rectangle(30, 30, width - 60, 1020)
with patch.object(rl, 'draw_rectangle'), patch.object(rl, 'draw_rectangle_gradient_v'):
renderer.render(bounds, OnroadAlert(AlertSize.FULL, text, alert_type='reverseGear/permanent'))
title = [call.args for call in fonts.draw.call_args_list if call.args[0]]
assert [args[0] for args in title] == text.split('\n')
for line, role, size, x, _y, _color in title:
assert x + measure(line, role, size).width / 2 == width / 2
top = title[0][4]
bottom = title[-1][4] + measure(title[-1][0], title[-1][1], title[-1][2]).height
assert (top + bottom) / 2 == bounds.y + bounds.height / 2
if len(title) > 1:
assert title[1][4] - top == title[0][2] + 2
@pytest.mark.parametrize("personality", ["Relaxed", "Standard", "Aggressive"])
def test_personality_banner_uses_name_and_consistent_large_type(personality):
fonts = Mock(profile=Profile.COMPACT)