Draft. Design and work plan only; no code changes. Nothing here should merge until James has answered the five decisions in section 12.
What this is
docs/design/LABEL-LAYOUT-FONTS-PREVIEW.md: the design James asked for on 2026-11-11 for labels, barcode generation, page layout and templates, and for a preview inside the QBit, followed by a work plan (section B) that separate agents can build from.
The main choices
Topic
Choice
Layout
New schema qqq-zpl-scene/2 in physical units (mm, in, pt, %), nine-point anchors plus align / valign on every element, group containers, per-dpi overrides
Existing documents
qqq-zpl-scene/1 is frozen and pinned by a byte-for-byte corpus; conversion is an explicit authoring action, never automatic
Resolution
A render target chosen at print or preview time, so one document serves 203, 300 and 600 dpi
Text
TrueType only in version 2; a bundled default set in the renderer; fit rules per element (wrap, shrink to a floor, then refuse or truncate with a mark); maxLength proves fit at publish
Uploaded fonts
Bytes in a table owned by the QBit, so upload and seeding work with no object storage; Record Files stays optional
Barcodes
Whole-dot modules from a physical minimum, centred in the box, never printed below the stated minimum; GS1 builder and human-readable line; tests decode the emitted bitmap
Output
The whole label as trimmed ^GFA strips, inside the grammar the host output policy already allows
Preview
The print path stopped before retention; the picture is decoded on the host from the validated ZPL bytes; shown with existing frontend components first, a purpose-built component later
Errors
Structured diagnostics (element id and numbers only) replace the opaque RENDER_FAILED for version 2
Release
New release/1.4 line, host library before renderer image
Findings worth reading first
PR 11's justified text blocks emit ^FB, which ZplOutputPolicy rejects, and the PR does not change the bridge. The design replaces PR 11 and carries its barcode alignment and tests into version 2 (section 12).
rasterText already wraps and centres; what is missing is shrink, measurement for printer font text, and barcode centring.
The document filter that hides a document on a stock or dpi mismatch is Forge code (EchoPrintingDestinations), not scanner or printing QBit code.
The SIL Open Font License is not on the dependency standard's allowlist, yet qbit-printing and Forge already ship OFL fonts with no recorded exception (decision 1).
Decisions for James (section 12)
Bundled fonts and the licence exception.
Asset bytes stored in the QBit's own table.
Version 2 prints the whole label as a bitmap and offers no printer font.
Release line release/1.4 and the rollout order.
Renderer image build automation and registry.
Verification
Documentation only. Statements about existing behaviour were read in code at the refs named in the document; items that could not be confirmed are marked "not verified". No build or test was run for this change.
Draft. Design and work plan only; no code changes. Nothing here should merge until James has answered the five decisions in section 12.
## What this is
`docs/design/LABEL-LAYOUT-FONTS-PREVIEW.md`: the design James asked for on 2026-11-11 for labels, barcode generation, page layout and templates, and for a preview inside the QBit, followed by a work plan (section B) that separate agents can build from.
## The main choices
| Topic | Choice |
|---|---|
| Layout | New schema `qqq-zpl-scene/2` in physical units (mm, in, pt, %), nine-point anchors plus `align` / `valign` on every element, `group` containers, per-dpi `overrides` |
| Existing documents | `qqq-zpl-scene/1` is frozen and pinned by a byte-for-byte corpus; conversion is an explicit authoring action, never automatic |
| Resolution | A render target chosen at print or preview time, so one document serves 203, 300 and 600 dpi |
| Text | TrueType only in version 2; a bundled default set in the renderer; fit rules per element (wrap, shrink to a floor, then refuse or truncate with a mark); `maxLength` proves fit at publish |
| Uploaded fonts | Bytes in a table owned by the QBit, so upload and seeding work with no object storage; Record Files stays optional |
| Barcodes | Whole-dot modules from a physical minimum, centred in the box, never printed below the stated minimum; GS1 builder and human-readable line; tests decode the emitted bitmap |
| Output | The whole label as trimmed `^GFA` strips, inside the grammar the host output policy already allows |
| Preview | The print path stopped before retention; the picture is decoded on the host from the validated ZPL bytes; shown with existing frontend components first, a purpose-built component later |
| Errors | Structured diagnostics (element id and numbers only) replace the opaque `RENDER_FAILED` for version 2 |
| Release | New `release/1.4` line, host library before renderer image |
## Findings worth reading first
- PR 11's justified text blocks emit `^FB`, which `ZplOutputPolicy` rejects, and the PR does not change the bridge. The design replaces PR 11 and carries its barcode alignment and tests into version 2 (section 12).
- `rasterText` already wraps and centres; what is missing is shrink, measurement for printer font text, and barcode centring.
- The document filter that hides a document on a stock or dpi mismatch is Forge code (`EchoPrintingDestinations`), not scanner or printing QBit code.
- The SIL Open Font License is not on the dependency standard's allowlist, yet `qbit-printing` and Forge already ship OFL fonts with no recorded exception (decision 1).
## Decisions for James (section 12)
1. Bundled fonts and the licence exception.
2. Asset bytes stored in the QBit's own table.
3. Version 2 prints the whole label as a bitmap and offers no printer font.
4. Release line `release/1.4` and the rollout order.
5. Renderer image build automation and registry.
## Verification
Documentation only. Statements about existing behaviour were read in code at the refs named in the document; items that could not be confirmed are marked "not verified". No build or test was run for this change.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Design and work plan only; no code changes. Covers scene version 2 beside a frozen
version 1, bundled and database-stored fonts, whole-dot barcode fitting with
centring, structured diagnostics, a preview decoded from the validated ZPL, the
release order and what GG Forge pins and deletes.
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Draft. Design and work plan only; no code changes. Nothing here should merge until James has answered the five decisions in section 12.
What this is
docs/design/LABEL-LAYOUT-FONTS-PREVIEW.md: the design James asked for on 2026-11-11 for labels, barcode generation, page layout and templates, and for a preview inside the QBit, followed by a work plan (section B) that separate agents can build from.The main choices
qqq-zpl-scene/2in physical units (mm, in, pt, %), nine-point anchors plusalign/valignon every element,groupcontainers, per-dpioverridesqqq-zpl-scene/1is frozen and pinned by a byte-for-byte corpus; conversion is an explicit authoring action, never automaticmaxLengthproves fit at publish^GFAstrips, inside the grammar the host output policy already allowsRENDER_FAILEDfor version 2release/1.4line, host library before renderer imageFindings worth reading first
^FB, whichZplOutputPolicyrejects, and the PR does not change the bridge. The design replaces PR 11 and carries its barcode alignment and tests into version 2 (section 12).rasterTextalready wraps and centres; what is missing is shrink, measurement for printer font text, and barcode centring.EchoPrintingDestinations), not scanner or printing QBit code.qbit-printingand Forge already ship OFL fonts with no recorded exception (decision 1).Decisions for James (section 12)
release/1.4and the rollout order.Verification
Documentation only. Statements about existing behaviour were read in code at the refs named in the document; items that could not be confirmed are marked "not verified". No build or test was run for this change.
🤖 Generated with Claude Code
View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.