Skip to content

fix(news): make every offered font work, and document every setting - #369

Merged
ChuckBuilds merged 2 commits into
mainfrom
docs/news-readme
Sep 3, 2026
Merged

fix(news): make every offered font work, and document every setting#369
ChuckBuilds merged 2 commits into
mainfrom
docs/news-readme

Conversation

@ChuckBuilds

Copy link
Copy Markdown
Owner

Ninth plugin in the README pass.

Three of six fonts did nothing — again

23eb6d2999: ['PressStart2P-Regular.ttf', '5x7.bdf', '4x6.bdf', 'cozette.bdf']
f1d424588c: ['4x6-font.ttf']
4b175f63d3: ['5by7.regular.ttf']

Same two causes as #362 (clock-simple), which shares this loader almost line for line — including the comment "FreeType handles .ttf and (at its native size) .bdf faces", which is true and is exactly what the code doesn't do. cozette.bdf has no font file anywhere; .bdf faces exist at one pixel size and were requested at font_size.

Fixed the same way. All five remaining faces now render distinctly.

This is the third plugin with this bug (clock-simple, countdown, news). If you'd like, I can sweep the remaining plugins for the same loader pattern in one pass rather than finding it a plugin at a time.

New tooling: mid-scroll frames

A scrolling plugin starts its strip off the right edge, so a single frame is an empty panel — I skipped a scrolling screenshot in text-display for this reason. Shots can now set frames, rendered through a runner that steps display() before snapshotting.

The first attempt still produced blank frames, which turned out to be informative: animation is driven by elapsed wall-clock time, not by how many times display() was called, so stepping frames against a frozen clock renders the same first frame forever. The freeze shim gained an advance() hook the runner calls between frames.

This unblocks text-display, and the stock/odds/leaderboard tickers still to come.

README

Rewritten around real recorded ESPN headlines, covering all 31 settings. Two things it now says that it didn't:

  • A fresh install shows nothingfeeds.enabled_feeds is an empty list, on top of enabled being false.
  • font_size is the first thing to lower. At the default 12, a 128-wide panel holds about ten characters, which reads as a stream of letters rather than a headline. The comparison image makes that obvious in a way prose doesn't.

Also documented BIG10 being a Google News query rather than an official feed, and that Atom-only feeds fetch successfully and yield nothing since the parser needs RSS <item> elements.

Audits

  • Config tokens: none dropped
  • Schema leaves: the audit caught four I'd missedglobal.font_path and the three background_service keys. Now documented; 31/31
  • Section check: flagged Dependencies → restored, and corrected while writing it, since requirements.txt lists deps as comments rather than pins
  • No broken TOC anchors

Verification

  • check_plugin.py --plugin news — 8/8 PASS
  • render_docs_assets.py --plugin news --check — images match
  • check_module_collisions.py — OK across 43 plugins
  • manifest bumped 1.3.2 → 1.4.0 (minor: font behaviour changes and an enum option is removed)

🤖 Generated with Claude Code

Three of the six font faces in the picker rendered identically to the default.
Hashing one render per face:

  23eb6d2999: ['PressStart2P-Regular.ttf', '5x7.bdf', '4x6.bdf', 'cozette.bdf']
  f1d424588c: ['4x6-font.ttf']
  4b175f63d3: ['5by7.regular.ttf']

Same two causes as clock-simple, which shares this loader almost line for line:
cozette.bdf has no font file in the core or the plugin, and a .bdf exists at
exactly one pixel size so FreeType rejected every request at font_size. Bitmap
faces are now retried at the size the file's PIXEL_SIZE header declares, and
cozette.bdf is dropped from both pickers. All five remaining faces now render
distinctly.

The README is rewritten around real recorded ESPN headlines and documents all
31 settings. The audits caught four it had missed on the first pass --
global.font_path and the three background_service keys -- which are now in.

Two things it now says that it did not: a fresh install shows nothing because
feeds.enabled_feeds is an empty list as well as enabled being false; and
font_size is the first thing to lower, because at the default 12 a 128-wide
panel holds about ten characters, which reads as a stream of letters rather
than a headline.

Tooling: shots can now ask for `frames`, which renders through a runner that
steps display() before snapshotting. A scrolling plugin starts its strip off
the right edge, so a single frame is an empty panel -- true of this plugin,
text-display, and the stock and leaderboard tickers still to come. The frozen
clock gained an advance() hook the runner calls between frames, because
animation is driven by elapsed time rather than by call count: stepping frames
against a clock that never moves renders the same first frame forever, which is
what the first attempt did.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: 6d476af9-7437-4d83-8065-5b8876cdaa81


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.

@codacy-production

Copy link
Copy Markdown

Not up to standards ⛔

🔴 Issues 1 medium

Alerts:
⚠ 1 issue (≤ 0 issues of at least minor severity)

Results:
1 new issue

Category Results
Security 1 medium

View in Codacy

🟢 Metrics 16 complexity

Metric Results
Complexity 16

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.

@ChuckBuilds
ChuckBuilds merged commit e5ee291 into main Sep 3, 2026
2 checks passed
ChuckBuilds added a commit that referenced this pull request Sep 3, 2026
…ns (#374)

Completes the sweep. A .bdf exists at exactly one pixel size and FreeType
rejects any other with "invalid pixel size", so every bitmap face in these two
pickers failed at the configured font_size and silently fell back to the
default -- choosing one appeared to do nothing, with only a log warning nobody
reads. Bitmap faces are now retried at the size the file's PIXEL_SIZE header
declares.

cozette.bdf is also removed from mqtt-notifications' picker. The file is
shipped by neither the core nor the plugin, so selecting it could only ever
fall back. youtube-stats never listed it.

Same fix already landed for clock-simple (#362), news (#369) and tide-display
(#370), which carry copies of this loader. That is five plugins with one bug,
so the root cause is filed against the core as ChuckBuilds/LEDMatrix#517:
FontManager.resolve_font degrades to the default face for any .bdf without
signalling it, which is why each plugin had to work around it separately.

Verification is unit-level rather than by render, because neither plugin draws
text without credentials -- mqtt-notifications needs a broker and youtube-stats
an API key, so the hash-comparison used on the other plugins produces identical
"no data" screens either way. Instead the loader's own path is exercised
directly: _bdf_pixel_size returns 7 for 5x7.bdf and 6 for 4x6.bdf,
ImageFont.truetype fails for both at size 8, and succeeds at the reported
native size. That is exactly the branch the fix takes.

The harness passes 8/8 for both. mqtt-notifications could not be harnessed at
all before this: it fails to instantiate without paho-mqtt, which is in its
requirements.txt but not in the core's environment, so anyone running
check_plugin without installing it first sees eight load errors rather than a
result.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
ChuckBuilds added a commit that referenced this pull request Sep 3, 2026
… setting (#394)

A .bdf is a bitmap face that exists at exactly one pixel size. Choosing
5x7.bdf or 4x6.bdf at any other size raised inside FreeType, and the renderer
caught it and substituted PressStart2P with a log warning -- so the font menu
appeared to work while quietly ignoring the choice at twelve of the thirteen
offered sizes. Bitmap faces now load at their declared PIXEL_SIZE instead.

cozette.bdf is removed from all six font menus: the core ships no file of that
name, so it could never load at any size (#387).

README: real rendered screenshots throughout -- a gain, a loss, a crypto entry,
both display modes, the inline chart on and off, and four panel sizes -- all
from a recorded quote seeded into the cache the plugin already reads.

The eight per-element colour keys were previously one sentence ("green for
positive deltas and red for negative"); they are now a table, including the
detail that price_delta has no text_color because its colour comes from the
sign of the change. That takes the plugin to 41 of 41 settings documented.

The scroll shots use the frames option from #369: the ticker starts off-panel,
so frame 0 of a scrolling plugin is blank.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
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