fix(testing): harness calendar_font is sized like the panel's

VisualTestDisplayManager built its 5x7 calendar_font / bdf_5x7_font as a
bare freetype.Face. With no size set its ascender reads 0, so BDF text
drawn with it landed 6px above where DisplayManager draws it -- entirely
off the canvas at y=0 -- and get_font_height() returned 0. Golden images
and check_plugin / dev_server previews showed text the panel does not.

Load it through load_bdf_face at the panel's 7px, so it is the very face
DisplayManager uses. Across the differential run this changes only the
cases drawn with the harness's own calendar_font (968 of 220,032), which
now match the panel's output.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Chuck
2026-09-23 17:29:30 -04:00
co-authored by Claude Opus 5.5
parent f412a59b76
commit 048a709a5e
3 changed files with 26 additions and 8 deletions
+5 -1
View File
@@ -38,7 +38,11 @@ accepts both, but the store flags the old spelling as deprecated
the file's native strike) and `draw_bdf_text(draw, text, x, y, face, color)`. the file's native strike) and `draw_bdf_text(draw, text, x, y, face, color)`.
`DisplayManager`, `FontManager`, `element_style` and the plugin test harness `DisplayManager`, `FontManager`, `element_style` and the plugin test harness
now all load and draw BDF text through it; the panel's pixels are unchanged now all load and draw BDF text through it; the panel's pixels are unchanged
and BDF text draws 10-250x faster. and BDF text draws 10-250x faster. The plugin test harness's
`calendar_font` / `bdf_5x7_font` now has the panel's 7px size set: it used
to be an unsized face, so in golden images and `check_plugin` /
`dev_server` previews its text sat 6px above where the panel draws it (off
the canvas entirely near the top) and `get_font_height()` returned 0.
- The web UI's Fonts tab has a **Used by** column: the loaded plugins that - The web UI's Fonts tab has a **Used by** column: the loaded plugins that
registered each font with `FontManager.register_manager_font()`, published registered each font with `FontManager.register_manager_font()`, published
@@ -22,8 +22,8 @@ process_deferred_updates, update_display, render_size. A behavior
change to any of those in DisplayManager must be mirrored here, or change to any of those in DisplayManager must be mirrored here, or
plugin visual tests will pass against stale behavior. plugin visual tests will pass against stale behavior.
BDF glyphs are not mirrored: both classes draw them through BDF text is not mirrored: both classes load BDF faces and draw BDF glyphs
src/common/bdf_font.py, so those pixels cannot drift. through src/common/bdf_font.py, so those pixels cannot drift.
""" """
import math import math
@@ -34,7 +34,7 @@ from pathlib import Path
from typing import Any, List, Optional, Tuple from typing import Any, List, Optional, Tuple
from PIL import Image, ImageDraw, ImageFont from PIL import Image, ImageDraw, ImageFont
from src.common.bdf_font import draw_bdf_text from src.common.bdf_font import draw_bdf_text, load_bdf_face
from src.common.font_layout import crisp_size, load_truetype from src.common.font_layout import crisp_size, load_truetype
from src.logging_config import get_logger from src.logging_config import get_logger
@@ -151,16 +151,18 @@ class VisualTestDisplayManager:
self.small_font = load_truetype(ttf_path, crisp_size(press_start, 8)) self.small_font = load_truetype(ttf_path, crisp_size(press_start, 8))
self.font = self.regular_font # alias used by some code paths self.font = self.regular_font # alias used by some code paths
# 5x7 BDF font via freetype # 5x7 BDF font, loaded exactly as DisplayManager._load_fonts does
# (same loader, same 7px request as its _CALENDAR_FONT_PX). A bare
# freetype.Face has no active size, so its ascender reads 0 and
# every line drew a baseline too high.
try: try:
import freetype
bdf_path = str(fonts_dir / '5x7.bdf') bdf_path = str(fonts_dir / '5x7.bdf')
if not os.path.exists(bdf_path): if not os.path.exists(bdf_path):
raise FileNotFoundError(f"BDF font not found: {bdf_path}") raise FileNotFoundError(f"BDF font not found: {bdf_path}")
face = freetype.Face(bdf_path) face, _ = load_bdf_face(bdf_path, 7)
self.calendar_font = face self.calendar_font = face
self.bdf_5x7_font = face self.bdf_5x7_font = face
except (ImportError, FileNotFoundError, OSError) as e: except Exception as e: # freetype missing or the file unloadable
logger.debug("BDF font not available, using small_font as fallback: %s", e) logger.debug("BDF font not available, using small_font as fallback: %s", e)
self.calendar_font = self.small_font self.calendar_font = self.small_font
self.bdf_5x7_font = self.small_font self.bdf_5x7_font = self.small_font
+12
View File
@@ -188,6 +188,18 @@ def test_display_manager_and_test_harness_draw_the_reference_pixels(name):
_assert_same(ref, vt.image, ("VisualTestDisplayManager", name, text)) _assert_same(ref, vt.image, ("VisualTestDisplayManager", name, text))
def test_harness_calendar_font_is_the_panels():
# The harness built a bare freetype.Face with no size: ascender 0, so
# every calendar_font line drew a baseline too high, and its
# get_font_height() returned 0.
from src.plugin_system.testing.visual_display_manager import VisualTestDisplayManager
vt = VisualTestDisplayManager(64, 32)
panel_face, _ = load_bdf_face(str(FONTS_DIR / "5x7.bdf"), 7)
assert vt.calendar_font is panel_face
assert vt.get_font_height(vt.calendar_font) == panel_face.size.height >> 6 > 0
# -------------------------------------------------------------------- loader # -------------------------------------------------------------------- loader
def test_off_strike_size_loads_the_native_strike(): def test_off_strike_size_loads_the_native_strike():