1. A length too long for any stock is a named refusal. Length.parse
narrowed the micrometres to an int before it applied the 2 m limit, so
"84600in" or "99999in" threw ArithmeticException: the opaque
RENDER_FAILED, and an error instead of a REFUSED answer when collecting.
The limit is now compared in long before narrowing, so it is
SCENE_INVALID at the pointer of the length.
2. The printable area holds a box of its own size at every resolution. It
was floor(far edge) less ceil(near margin), which can be one dot smaller
than a box of the stated printable width: 100 mm stock with 3 mm margins
and a 94 mm box fitted at 203 and 600 dpi and was refused at 300. It is
now floor((W - L - R) x dpi) by floor((H - T - B) x dpi), the rounding of
a box size, starting at ceil(L x dpi), ceil(T x dpi), moved back one dot
where it would otherwise pass the page edge. New golden case `margins`
with fractional-dot margins; the three existing goldens at 600 dpi are
regenerated (the area grew by one dot each way; 203 and 300 unchanged).
3. The version 2 mutation campaign accepts only a Refusal (the package's
own invariants are IllegalArgumentExceptions too) and renders about one
input in four, reading the label back and comparing with validation. It
found nothing at 20000 or 100000 iterations for either seed.
4. A refused answer carries no label bytes: with COLLECT and an error the
answer had base64 of a label with elements missing. Scene2.render answers
no label for a refused scene and the answer has no document fields. This
changes the wire contract of section B.1 of the design, which records it.
5. One scene may paint sixteen times its printable area, an overlap counted
each time, counted before any ink and in validation too. The element
that would pass it is SCENE_INVALID with measured.paintedPercent against
limit.paintedPercent 1600. 1000 fills of a 64 million dot canvas were
8 GB of byte writes; the worst scene is now 128 MB.
6. The README states what changed in the version 1 answer envelope in
0.2.0 (diagnostics on every answer; SCENE_INVALID with detail where
unreadable JSON and a missing or unknown schema were RENDER_FAILED) and
what the bridge must handle. The version 1 ZPL bytes are unchanged.
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
A scene may hold 1000 elements and a canvas 64 million dots, so a scene of
many large filled boxes visited tens of billions of dots one at a time.
Filling and reversing a box now write whole bytes, check the box against
the canvas before any dot changes (a box that leaves the canvas paints
nothing rather than its first rows), and a seeded property test holds the
result to painting each dot, at byte boundaries as everywhere else. The
goldens are unchanged.
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
A source with schema qqq-zpl-scene/2 is a label layout in millimetres,
inches, points, percentages and dots that renders at 203, 300 or 600 dpi.
The worker routes by the schema alone: version 1 takes exactly the path it
always took (the compatibility corpus is unchanged and green), version 2
takes the new package com.kingsrook.qbits.renderer.scene2, and anything
else is refused by name.
- Length: parse, whole micrometres, dots by the rule of each use
(position nearest, box size down, thickness nearest and at least one,
module up, font size not rounded).
- Layout: nine-point anchors, offsets inward from the anchored edge,
omitted sizes, content alignment, groups four deep, percentages of the
container. Coordinates start at the top left of the printable area.
- Canvas and ZplEmitter: the whole label on one 1-bit canvas, emitted as
trimmed ^GFA bands that pass the unchanged ZplOutputPolicy.
- Diagnostics: every refusal is one diagnostic with a code, the element
id, the box and named integers; SCENE_INVALID carries a JSON pointer.
A diagnostic names only an id the scene declares and points only
through schema names, indexes and declared ids.
- box and group elements; overrides by resolution, checked for all three
resolutions; samples accepted and ignored. Text, barcodes and images
are parsed and placed and then refused as RENDERER_TOO_OLD by
placeholder factories in their own sub-packages.
- Renderer 0.2.0: optional targetDpi and "diagnostics": "COLLECT" on the
request, diagnostics on the answer, detail on a version 2 error, the
REFUSED outcome, and INSPECT_ASSET and UPGRADE_SCENE routed and refused
as UNSUPPORTED_OPERATION. A version 1 scene with a target other than
its stock's dpi is refused as TARGET_REQUIRES_SCENE_2.
Tests: every length and rounding rule; all nine anchors; seeded property
tests (mirrored anchors, boxes never leave the printable area, the bitmap
rebuilt from the emitted fields equals the canvas); goldens at three
resolutions as pictures and as ZPL, the ZPL also checked against the host
gate in bridges/renderer; every refusal asserted as the whole diagnostic;
a mutation campaign over the version 2 parser. The new package is at 100%
line coverage.
Also, from the review of the foundations: the mutation campaigns accept
only declared refusals (a NullPointerException in a parser is now a
finding), git no longer treats the stored corpus as text, and both
compatibility tests pin the digest of the corpus manifest.
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
The design says SCENE_INVALID carries the JSON pointer of the offending
property, and GenerationPorts.Diagnostic had no field for one. It gains an
optional seventh component, pointer, held to the shape of at most sixteen
segments that are array indexes or names; the six-argument constructor
stays, so existing callers compile unchanged. The renderer builds a
pointer only from schema property names, indexes and declared element ids.
Section 8.1 of the design records this decision and the others made while
building the scene 2 core.
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
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>