Add a PC renderer for the themed pages; fix overlapping layouts

tools/render_pages.py compiles the page code natively with g++ against
ESPHome's own display and font code and the font bitmaps of the last
`esphome compile`, and draws pages to PNG at chosen moments with sample
data (normal, empty, alert, busy), as a contact sheet, or as one example
per page in docs/images/pages (now shown in the README).

Fixes found with it: Cyber HUD zone names ran into the temperatures,
the breach header label hit the tag and the column marker the matrix
label; KonoSuba subtitle, guild weather icon, cabbage text and all-day
deadline, and hills through the party; Steins;Gate D-mail recipient, the
microwave display, the gadget card value and world line labels; LCARS
room rows, readout bars and data cascade, warp core readouts, and the
captain's log weather wording.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
mangavalkandClaude Opus 5.5 committed 2026-10-19 16:46:31 +02:00
1 parent 13a499fd97
commit d2e81a5a36
27 files changed
+627 -38

No files matched your search

+7 -6
View File
@@ -404,9 +404,10 @@ void netrunner_hud(EL512Display &it, const Fonts &f, const HomeData &d, ESPTime
cut_frame(it, 254, 150, 258, 86);
tag(it, f.mono, 254, 150, 14, "ZONES");
for (int i = 0; i < 4; i++) {
const int x = 264 + (i % 2) * 124, y = 192 + (i / 2) * 34;
it.print(x, y, f.label, TextAlign::BASELINE_LEFT, el512::fit(f.label, d.rooms[i].name, 62).c_str());
it.print(x + 116, y, f.value, TextAlign::BASELINE_RIGHT, temp_text(d.rooms[i].value).c_str());
// Name on top, temperature below it.
const int x = 264 + (i % 2) * 124, y = 164 + (i / 2) * 36;
it.print(x, y + 11, f.mono, TextAlign::BASELINE_LEFT, el512::fit(f.mono, upper(d.rooms[i].name), 114).c_str());
it.print(x, y + 33, f.value, TextAlign::BASELINE_LEFT, temp_text(d.rooms[i].value).c_str());
}
// Bottom: ticker.
@@ -432,7 +433,7 @@ void breach_protocol(EL512Display &it, const Fonts &f) {
// Header and timer.
tag(it, f.title, 0, 0, 24, "BREACH PROTOCOL");
it.print(420, 18, f.label, TextAlign::BASELINE_RIGHT, "BREACH TIME REMAINING");
it.print(420, 18, f.label, TextAlign::BASELINE_RIGHT, "TIME REMAINING");
cut_frame(it, 428, 0, 84, 26, 6);
const bool low = v.remain < 10.0f && (t / 250) % 2;
if (!low)
@@ -441,8 +442,8 @@ void breach_protocol(EL512Display &it, const Fonts &f) {
// Code matrix.
cut_frame(it, 0, 40, 296, 216);
it.print(10, 54, f.mono, TextAlign::BASELINE_LEFT, "CODE MATRIX");
draw_matrix(it, {10, 62, 46, 31, f.code}, p, v);
it.print(10, 52, f.mono, TextAlign::BASELINE_LEFT, "CODE MATRIX");
draw_matrix(it, {10, 64, 46, 31, f.code}, p, v);
// Buffer.
it.print(304, 54, f.mono, TextAlign::BASELINE_LEFT, "BUFFER");