Skip to content

feat(render): make the QR quiet zone configurable - #17

Merged
impuls42 merged 1 commit into
mainfrom
feat/qr-quiet-zone
Sep 25, 2026
Merged

impuls42 merged 1 commit into
mainfrom
feat/qr-quiet-zone

Conversation

@impuls42

@impuls42 impuls42 commented Sep 25, 2026 •

Copy link
Copy Markdown
Member

With qr_base_url = "https://sngn.top/i/" a phone camera offers to open the label instead of showing SNGN.TOP/I/PA39 as plain text, which is the whole point of the redirector. But the scheme costs a QR version, and the quiet zone is fixed at the spec's 4 modules inside the presets, so on 12mm tape the code lands at 2px per module.

This adds render.qr_quiet_zone (default 4, range 1 to 8) and threads it the same way qr_base_url goes: config section, worker _render_cfg, RenderConfig, PresetContext, and both preset QrElement sites. The render CLI gets --qr-quiet-zone to match. Default behaviour doesn't change.

Measured on the part preset at 12mm, decoding the image rebuilt from the packed device bytes, with the half-resolution round trip standing in for a phone:

base 4 3 2
SNGN.TOP/I/ ✅ ✅ ✅
https://sngn.top/i/ ❌ ❌ ✅

3 buys nothing. In pixels, the prefixed code's dark area is 50px (2px/module) at 4 and 3, and 75px (3px/module) at 2, which is bigger than the bare code's 63px at 4. The QR box is 81 to 92px here rather than the full 96, because the text takes part of the row.

That table is pinned as test_a_scheme_in_the_base_costs_two_quiet_zone_modules. The other new tests check that the value actually reaches the worker's RenderConfig (a value that stopped at the config section would still print at 4) and that 0 and 9 are rejected at load.

This has been running on the D30 here as a local patch since this afternoon. iOS picks up the printed label as a link straight away, and zxing decodes a photo of it with no preprocessing.

Unrelated, but found while testing layouts: a one-word title can run off the label. That fix is #18.

A base URL with a scheme (https://sngn.top/i/ instead of SNGN.TOP/I/) is what makes
a phone offer to open a label's QR rather than show it as text. The payload is one
QR version larger, though, and in the 12mm presets the QR shares its row with the
text, so at the spec's 4-module quiet zone it drops to 2px per module and fails a
degraded read.

Add render.qr_quiet_zone (default 4, 1..8), threaded through the worker,
RenderConfig and PresetContext to every preset QR, plus a --qr-quiet-zone flag on
the render commands. Measured through the wire bytes on the part preset at 12mm: 3
does not help, 2 brings the prefixed code back to 3px per module and survives the
phone-camera proxy. That table is pinned in test_scannability and in the README.
@impuls42
impuls42 merged commit ac1d200 into main Sep 25, 2026
1 check passed
@impuls42
impuls42 deleted the feat/qr-quiet-zone branch September 25, 2026 15:12
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