mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-10-04 06:15:09 +00:00
perf(common): rasterize outlined text once instead of nine times (#718)
New draw_text_outlined(draw, xy, text, font, fill, outline_color=(0, 0, 0), offsets=OUTLINE_SQUARE) in src/common/text_helper.py, with OUTLINE_SQUARE and OUTLINE_CROSS. It rasterizes the string once and stamps the mask at each outline offset instead of one draw.text per offset: the same pixels as the nine-draw loop (an equivalence sweep across the bundled fonts, image and font modes, colours and positions pins it, on Windows and Linux), about 8x faster per outlined string. Fractional coordinates, multiline text, fonts other than a plain FreeTypeFont, other image modes and a replaced draw.text take the old loop. SportsCoreSharedMixin._draw_text_with_outline and TextHelper.draw_text_with_outline draw through it; the scoreboards' own game_renderer loops adopt it in a ledmatrix-plugins change after a core release. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -19,6 +19,30 @@ accepts both, but the store flags the old spelling as deprecated
|
||||
|
||||
## Unreleased
|
||||
|
||||
### Outlined text: one rasterization
|
||||
|
||||
- New `draw_text_outlined(draw, xy, text, font, fill, outline_color=(0, 0,
|
||||
0), offsets=OUTLINE_SQUARE)` in `src/common/text_helper.py`, with
|
||||
`OUTLINE_SQUARE` (the eight-sided outline the scoreboards draw) and
|
||||
`OUTLINE_CROSS` (four sides). Outlined text was one `draw.text` per
|
||||
outline offset plus one for the text, so FreeType rasterized the same
|
||||
string nine times. This rasterizes it once and stamps the mask at each
|
||||
offset: the same pixels, about 8x faster per outlined string (Pillow 12.3,
|
||||
desktop). `test/test_text_helper.py` compares it with the nine-draw loop
|
||||
across the bundled fonts, image and font modes, colours and positions,
|
||||
and fails if it stops rasterizing once. Fractional coordinates, multiline
|
||||
text, fonts other than a plain `FreeTypeFont`, image modes other than
|
||||
RGB, RGBA and L, and a subclassed or replaced `draw.text` take the old
|
||||
loop unchanged. A whole-pixel float such as `52.0`, which the scorebugs'
|
||||
centring passes, is not fractional.
|
||||
- `SportsCoreSharedMixin._draw_text_with_outline`, which eight of the nine
|
||||
scoreboards inherit for their switch-mode scorebug (ufc has its own), and
|
||||
`TextHelper.draw_text_with_outline` now draw through it. Scroll and Vegas
|
||||
cards still use each plugin's own `game_renderer.py` loop, so building a
|
||||
scroll strip costs the same until the plugins adopt `draw_text_outlined`,
|
||||
importing it with an `ImportError` fallback to their own loop (a separate
|
||||
ledmatrix-plugins change after a core release ships it).
|
||||
|
||||
### Shared fetch service (stage 1)
|
||||
|
||||
Core's own HTTP fetch paths now go through one service, so the plugins that
|
||||
|
||||
Reference in New Issue
Block a user