fix(sports): rebuild un-shared faces through the pinned layout engine

unshare_element_fonts re-instantiates a duplicate font face so two
elements can be told apart by id(). It did so through bare
ImageFont.truetype, which takes PIL's default layout engine rather than
the one src/common/font_layout.py pins. Raqm and Basic disagree on
fractional advances -- that disagreement is the reason the pin exists,
having broken golden images across machines -- so a rebuilt face could
measure differently from the shared face it replaced, on any host where
Raqm is installed.

These were the only two call sites in src/ bypassing the pin.

The guard asserts that the rebuild goes through the pinned loader rather
than comparing engine values: where Raqm is absent, bare truetype returns
BASIC anyway, so an engine comparison passes whether or not the pin is
honoured. The first draft of this test did exactly that and passed with
the bug reintroduced.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Chuck
2026-09-10 09:59:53 -04:00
co-authored by Claude Opus 5
parent a29c84208e
commit 0d7e409d77
4 changed files with 121 additions and 4 deletions
+2 -2
View File
@@ -448,7 +448,7 @@ def unshare_element_fonts(logger, fonts):
path) are left shared, and their draws stay white as before.
"""
try:
from PIL import ImageFont as _IF
from src.common.font_layout import load_truetype as _load
except ImportError: # pragma: no cover
return fonts
seen = {}
@@ -463,7 +463,7 @@ def unshare_element_fonts(logger, fonts):
if not path or not size:
continue
try:
fonts[key] = _IF.truetype(path, size)
fonts[key] = _load(path, size)
except (OSError, ValueError, TypeError):
logger.debug(
"Could not un-share the %s face; it keeps the default colour", key)
+2 -2
View File
@@ -787,7 +787,7 @@ class SportsCoreSharedMixin:
path) are left shared, and their draws stay white as before.
"""
try:
from PIL import ImageFont as _IF
from src.common.font_layout import load_truetype as _load
except ImportError: # pragma: no cover
return fonts
seen = {}
@@ -802,7 +802,7 @@ class SportsCoreSharedMixin:
if not path or not size:
continue
try:
fonts[key] = _IF.truetype(path, size)
fonts[key] = _load(path, size)
except (OSError, ValueError, TypeError):
self.logger.debug(
"Could not un-share the %s face; it keeps the default colour", key)