ui: sharpen onroad speed readout

This commit is contained in:
Comma Device
2026-10-17 16:31:33 +08:00
parent 0efac0f858
commit 6ec5e334cd
2 changed files with 33 additions and 8 deletions
@@ -8,7 +8,7 @@ import pyray as rl
from openpilot.common.constants import CV
from openpilot.selfdrive.ui.ui_state import ui_state
from openpilot.system.ui.lib.application import gui_app, FontWeight
from openpilot.system.ui.lib.application import gui_app
from openpilot.system.ui.lib.multilang import tr
from openpilot.system.ui.lib.text_measure import measure_text_cached
from openpilot.selfdrive.ui.onroad.hud_renderer import FONT_SIZES, COLORS
@@ -19,8 +19,7 @@ class SpeedRenderer:
self.speed: float = 0.0
self.v_ego_cluster_seen: bool = False
self._font_bold: rl.Font = gui_app.font(FontWeight.BOLD)
self._font_medium: rl.Font = gui_app.font(FontWeight.MEDIUM)
self._font_speed: rl.Font = gui_app.high_res_speed_font()
def update(self) -> None:
car_state = ui_state.sm['carState']
@@ -36,11 +35,11 @@ class SpeedRenderer:
# Draw current speed and unit
speed_text = str(round(self.speed))
speed_text_size = measure_text_cached(self._font_bold, speed_text, FONT_SIZES.current_speed)
speed_text_size = measure_text_cached(self._font_speed, speed_text, FONT_SIZES.current_speed)
speed_pos = rl.Vector2(rect.x + rect.width / 2 - speed_text_size.x / 2, 180 - speed_text_size.y / 2)
rl.draw_text_ex(self._font_bold, speed_text, speed_pos, FONT_SIZES.current_speed, 0, COLORS.WHITE)
rl.draw_text_ex(self._font_speed, speed_text, speed_pos, FONT_SIZES.current_speed, 0, COLORS.WHITE)
unit_text = tr("km/h") if ui_state.is_metric else tr("mph")
unit_text_size = measure_text_cached(self._font_medium, unit_text, FONT_SIZES.speed_unit)
unit_text_size = measure_text_cached(self._font_speed, unit_text, FONT_SIZES.speed_unit)
unit_pos = rl.Vector2(rect.x + rect.width / 2 - unit_text_size.x / 2, 290 - unit_text_size.y / 2)
rl.draw_text_ex(self._font_medium, unit_text, unit_pos, FONT_SIZES.speed_unit, 0, COLORS.WHITE_TRANSLUCENT)
rl.draw_text_ex(self._font_speed, unit_text, unit_pos, FONT_SIZES.speed_unit, 0, COLORS.WHITE_TRANSLUCENT)
+27 -1
View File
@@ -102,6 +102,8 @@ NOTO_FONTS = {
"zh-CHS": "SourceHanSansSC-Bold.otf",
"zh-CHT": "NotoSansCJKtc-Regular.otf",
}
HIGH_RES_SPEED_CHARS = "0123456789.-/ kmhp"
HIGH_RES_SPEED_FONT_SIZE = 280
class FontWeight(StrEnum):
@@ -132,7 +134,7 @@ class TextAlignmentVertical(IntEnum):
def font_fallback(font: rl.Font) -> rl.Font:
"""Use a Noto fallback for languages not covered by Inter."""
if multilang.requires_font_fallback():
if multilang.requires_font_fallback() and not gui_app.is_high_res_speed_font(font):
return gui_app.fallback_font()
return font
@@ -222,6 +224,8 @@ class GuiApplication(GuiApplicationExt):
self._fonts: dict[FontWeight, rl.Font] = {}
self._fallback_fonts: dict[str, rl.Font] = {}
self._high_res_speed_fonts: dict[str, rl.Font] = {}
self._high_res_speed_font_ids: set[int] = set()
self._width = width if width is not None else GuiApplication._default_width()
self._height = height if height is not None else GuiApplication._default_height()
@@ -746,6 +750,28 @@ class GuiApplication(GuiApplicationExt):
self._fallback_fonts[language] = font
return self._fallback_fonts[language]
def high_res_speed_font(self) -> rl.Font:
"""Font subset rasterized near the size used by the onroad speed display."""
if not multilang.requires_font_fallback():
return self._fonts[FontWeight.BOLD]
language = multilang.language
if language not in self._high_res_speed_fonts:
codepoints = sorted(map(ord, HIGH_RES_SPEED_CHARS))
codepoint_buffer = rl.ffi.new("int[]", codepoints)
with as_file(FONT_DIR) as fspath:
font = rl.load_font_ex((fspath / NOTO_FONTS[language]).as_posix(), HIGH_RES_SPEED_FONT_SIZE,
rl.ffi.cast("int *", codepoint_buffer), len(codepoints))
rl.gen_texture_mipmaps(font.texture)
rl.set_texture_filter(font.texture, rl.TextureFilter.TEXTURE_FILTER_TRILINEAR)
self._high_res_speed_fonts[language] = font
if font.texture.id != 0:
self._high_res_speed_font_ids.add(font.texture.id)
return self._high_res_speed_fonts[language]
def is_high_res_speed_font(self, font: rl.Font) -> bool:
return font.texture.id in self._high_res_speed_font_ids
@property
def width(self):
return self._width