Skip to content

fix(display): draw text 1-bit, so glyphs stay crisp on the LED grid - #521

Open
ChuckBuilds wants to merge 1 commit into
mainfrom
fix/crisp-text-shared-draw
Open

fix(display): draw text 1-bit, so glyphs stay crisp on the LED grid#521
ChuckBuilds wants to merge 1 commit into
mainfrom
fix/crisp-text-shared-draw

Conversation

@ChuckBuilds

@ChuckBuilds ChuckBuilds commented Sep 4, 2026

Copy link
Copy Markdown
Owner

The bug

An LED panel has no partial brightness. PIL defaults ImageDraw's fontmode to "L", which anti-aliases TrueType glyphs into a grey fringe the panel can only round off — a 4px glyph arrives smeared into 3px.

DisplayManager creates its shared draw in six places and set fontmode at none of them, while _load_fonts loads extra_small_font as 4x6-font.ttf at size 6. Measured at draw time, that face at that size puts 74% of its lit pixels at partial coverage. Every plugin that draws small text through the shared draw inherited the blur.

The harness had the same gap, and that mattered more

src/plugin_system/testing/visual_display_manager.py creates its own draw in five places, also at the default. So the harness was recording anti-aliased goldens that production would never produce — it structurally could not have caught this.

That is not a theoretical point. After the production fix, geochron was still rendering anti-aliased under the harness; tracing the draw object's creation stack led to visual_display_manager.py:72. Fixing only production would have left the harness disagreeing with the panel.

Both are now "1", so the harness renders what the panel renders.

Verification

A probe hooked ImageDraw.text and recorded, for every real draw, the fontmode in effect, the font and size, the call site, and the Draw() object's creation site.

  • before: 18 anti-aliased sites across 9 plugins
  • after: 0, across 31 plugins × all 8 panel sizes

Companion plugin-side PR: ChuckBuilds/ledmatrix-plugins#417.

🤖 Generated with Claude Code

https://claude.ai/code/session_014RRtqXDCnvnY6EQwhT5CV9

Summary by CodeRabbit

  • Bug Fixes
    • Standardized text rendering to use 1-bit, non-anti-aliased output across physical and visual displays.
    • Improved consistency between displayed text and visual test results.

An LED panel has no partial brightness. PIL defaults ImageDraw's fontmode to
"L", which anti-aliases TrueType glyphs into a grey fringe the panel can only
round off -- a 4px glyph arrives smeared into 3px.

DisplayManager creates its shared `draw` in six places and set fontmode at
none of them, while _load_fonts loads extra_small_font as 4x6-font.ttf at
size 6. Measured at draw time, that face at that size puts 74% of its lit
pixels at partial coverage. Every plugin drawing small text through the
shared draw inherited the blur; geochron was the case that surfaced it.

The harness's VisualDisplayManager had the same gap, which mattered more than
it looks: goldens were recording anti-aliased text that production would not
produce, so the harness could not have caught this. Fixing only production
left geochron still blurry under the harness -- that is how the second site
was found.

Both are set to "1" so the harness renders what the panel renders.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RRtqXDCnvnY6EQwhT5CV9
@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 0 complexity · 0 duplication

Metric Results
Complexity 0
Duplication 0

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@coderabbitai

coderabbitai Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

No new commits to review since the last review.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: 5079c8a8-589f-4f94-b150-54f9727fdc59

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: e8d09e7f-20f4-4135-838a-f06fbd5052bd

📥 Commits

Reviewing files that changed from the base of the PR and between 0730d95 and 1168c32.

📒 Files selected for processing (2)
  • src/display_manager.py
  • src/plugin_system/testing/visual_display_manager.py

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The change sets ImageDraw.fontmode to "1" for all newly created production and visual test canvases. This applies during setup, resizing, clearing, resetting, and cleanup.

Changes

1-bit text rendering alignment

Layer / File(s) Summary
Production canvas fontmode configuration
src/display_manager.py
Production ImageDraw objects use fontmode = "1" across setup, resizing, clearing, and cleanup paths.
Visual test canvas fontmode configuration
src/plugin_system/testing/visual_display_manager.py
Visual test ImageDraw objects use fontmode = "1" during initialization, clearing, resizing, resetting, and cleanup.

Estimated code review effort: 1 (Trivial) | ~5 minutes

Merge Risk: ⚪ Minimal · up to 1168c

Text rendering now uses 1-bit glyphs in production and visual test canvases, eliminating partial-brightness text on LED panels while keeping visual test rendering aligned. The change is ready to merge.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 90.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 10 functions across 2 files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: configuring text rendering to 1-bit mode so glyphs remain crisp on the LED grid.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/crisp-text-shared-draw

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@ChuckBuilds

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor
⚠️ Action not completed

Already reviewed the last commit. Use @coderabbitai full review to rerun a review of the entire changeset.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant