Skip to content

fix(boot): keep QR scannable on landscape 800x600+ boot screens - #167

Open
davelee98 wants to merge 2 commits into
OpenDisplay:mainfrom
davelee98:claude/boot-screen-formatting-dual-ca-q4w3is
Open

davelee98 wants to merge 2 commits into
OpenDisplay:mainfrom
davelee98:claude/boot-screen-formatting-dual-ca-q4w3is

Conversation

@davelee98

Copy link
Copy Markdown
Contributor

Problem

On the reTerminal E1004 (1200x1600 dual-controller Spectra6) rotated to 1600x1200, the boot screen's middle zone had huge text and a QR code squeezed down to 2–3 px modules in the corner. This isn't specific to dual-controller panels. The same thing happened on every landscape panel ≥ 800x600, including 1304x984, 960x640 and 800x600. Only 1872x1404 avoided it, because of its hard-coded ultraHiResPanel scale offset.

Root cause: the layout search in writeBootScreenWithQr() tried text scales from the largest down. It accepted the first scale at which any QR module size fit, even 1 px. So the text always stayed at its largest size and the QR took whatever space was left.

Fix (src/boot_screen.cpp)

  • New bootQrModuleMin(): returns half of bootQrModuleMax() on panels whose cap is ≥ 8 (≥ 800x600), and 1 on smaller panels.
  • New moduleMin parameter in bootLayoutFit(): the module-size loop stops at moduleMin instead of going down to 1.
  • Two-pass search: pass 0 enforces the minimum module size and shrinks the text until the layout fits. Pass 1 is the original any-size search. Panels below 800x600 start at pass 1, so they behave exactly as before.
  • Follow-up commit: renames the loop variable to fitPass (so it doesn't shadow round()) and corrects the comment. No behaviour change.

Performance: the search runs once at boot and does at most about 10 × 16 iterations of integer math. There is no heap allocation, no new globals and no change to the row-streaming path.

Verification

  • Host render harness: compiles the real boot_screen.cpp against stubs and renders 14 panel sizes, including the E1004 in both orientations with the split stream.
    • The E1004 at 1600x1200 goes from text scale 10 / 3 px modules to text scale 8 / 9 px modules.
    • Portrait E1004, 1872x1404, 1024x576, 800x480, 640x384, 600x448, 400x300, 480x800 and 296x128 are byte-identical to before.
  • Adversarial review: a sweep of 2,115 logical sizes (400–2648 px each way) found no overlap, clipping, out-of-bounds QR or loss of the QR's blank margin on any size this changes.
    • Every size that changed got a bigger QR and text that is 1–2 scale steps smaller.
    • A few near-square landscape sizes (e.g. 1700x1600, 1232x1028) switch from the stacked layout to text-left/QR-right, and render better that way.
  • Firmware build: all 12 CI targets build green on the branch head (54cf579). The change still needs a look on a real E1004.

Known, not addressed here

The existing qrX = contentRightX - modulePx*(qrSize+quiet) override leaves the QR's right blank margin narrower than the standard 4 modules (about 2.7–3.6) on some unchanged sizes (1872x1404, 2560x1440, 1024x576, 800x480). A possible follow-up fix is to clamp qrX to w_log - qrPx.

The middle-zone layout search took the largest text scale for which any
QR module size fit, so on landscape panels >= 800x600 it kept oversized
text and shrank the QR to 2-3px modules in the corner. Most visible on
the reTerminal E1004 (1200x1600 dual-controller) rotated to 1600x1200;
also hit 1304x984, 960x640 and 800x600.

The search now first requires a module floor of half the panel's module
cap (panels with cap >= 8 only) and shrinks the text to fit, falling
back to the old any-size search if nothing fits. Panels below 800x600,
portrait layouts and 1872x1404 render identically to before (checked
with a host render of boot_screen.cpp across 14 panel sizes).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BquLGp9hmm8sgAYixz8you
Rename the layout-search loop variable from `round` to `fitPass` so a
later round() call inside it cannot bind to the int, and correct the
comment: panels below 800x600 skip the floored pass entirely rather
than falling back to the unfloored one. No behaviour change (host
renders of 14 panel sizes are byte-identical).

Note on the previous commit: besides the 800x600+ landscape panels, the
floor also moves some near-square landscape sizes (e.g. 1700x1600,
1232x1028, 816x716) from the stacked layout to text-left/QR-right with
a larger QR.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BquLGp9hmm8sgAYixz8you
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.

2 participants