From 2c352b90b4278dbed8a74eb9b00cecd118046b41 Mon Sep 17 00:00:00 2001 From: firestar5683 <168790843+firestar5683@users.noreply.github.com> Date: Thu, 22 Oct 2026 19:57:34 -0500 Subject: [PATCH] Keep offset sign previews within the visible canvas --- openpilot/starpilot/ui/layout_preview_renderer.py | 7 +++++-- openpilot/starpilot/ui/tests/test_dinish_speed.py | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/openpilot/starpilot/ui/layout_preview_renderer.py b/openpilot/starpilot/ui/layout_preview_renderer.py index 8cf7e5360f..52aa7ca68e 100644 --- a/openpilot/starpilot/ui/layout_preview_renderer.py +++ b/openpilot/starpilot/ui/layout_preview_renderer.py @@ -340,8 +340,9 @@ class _Canvas: for key in RUNTIME_PREVIEW_WIDGETS[str(self.profile)]: logical_width, logical_height = widget_size(state.customization, self.profile, key) # The restored compact US sign adds an offset row beyond its saved base size. - if (self.profile == Profile.COMPACT and key == 'speed_limit' and - not state.appearance.use_vienna_sign and resolve_unified_speed(state).offset_text): + compact_offset = (self.profile == Profile.COMPACT and key == 'speed_limit' and + not state.appearance.use_vienna_sign and bool(resolve_unified_speed(state).offset_text)) + if compact_offset: logical_height += 44 position = positions[key] widget = PROFILES[str(self.profile)]['widgets'][key] @@ -349,6 +350,8 @@ class _Canvas: crop_y = max(0, math.floor(position['y'] - widget.get('visualInsetTop', 0))) offset_x, offset_y = crop_x - position['x'], crop_y - position['y'] width, height = math.ceil(logical_width - offset_x), math.ceil(logical_height - offset_y) + if compact_offset and 0 <= crop_y < canvas_height: + height = min(height, canvas_height - crop_y) if x + width > 1024: x, y, row_height = 0, y + row_height, 0 sprites[key] = {'x': x, 'y': y, 'width': width, 'height': height, 'offsetX': offset_x, 'offsetY': offset_y} diff --git a/openpilot/starpilot/ui/tests/test_dinish_speed.py b/openpilot/starpilot/ui/tests/test_dinish_speed.py index a2e264d8c0..65e565e6c8 100644 --- a/openpilot/starpilot/ui/tests/test_dinish_speed.py +++ b/openpilot/starpilot/ui/tests/test_dinish_speed.py @@ -238,9 +238,10 @@ def test_compact_preview_sprite_keeps_the_sign_offset_arrow_and_override_cross() rl.init_window(128, 128, 'SLC preview crop fixture') canvas = _Canvas(Profile.COMPACT) try: - for y, scene in product((20, 0), ('slc_pending', 'slc_retained')): + for y, scene in product((20, 0, 64, 108), ('slc_pending', 'slc_retained')): document = default_document() document['layouts']['compact']['speed_limit']['y'] = y + assert validate_document(document)['layouts']['compact']['speed_limit']['y'] == y with patch.dict('openpilot.starpilot.ui.layout_preview_renderer.RUNTIME_PREVIEW_WIDGETS', compact=('speed_limit',)): png = canvas.render_widget_art(sample_state(scene, document), document['layouts']['compact']) with Image.open(io.BytesIO(png)) as sheet: @@ -256,7 +257,9 @@ def test_compact_preview_sprite_keeps_the_sign_offset_arrow_and_override_cross() rl.unload_image(image) assert np.array_equal(direct[..., 3], np.asarray(rebuilt)[..., 3]) assert slot['offsetX'] == slot['offsetY'] == 0 - assert (slot['width'], slot['height']) == (118, 176) + assert (slot['width'], slot['height']) == (118, min(176, Profile.COMPACT.size[1] - y)) + if scene == 'slc_retained': + assert np.any(direct[..., 3]), (y, scene) finally: canvas.close() if owns_context: