Skip to content

Commit 878d69c

Browse files
committed
fix(line): clamp thickness <= length to avoid ^GB promotion
Zebra firmware promotes ^GB w,h,t with t > min(w,h) to max(w,t) x max(h,t), so a vertical line emitted as ^GB t,length,t prints as a t x t square once thickness exceeds length rather than the declared length x t band. Enforce the t <= length invariant at every edit path: - Thickness side-handle drag caps at p.length - Property panel thickness gets max=p.length, length gets min=p.thickness (NumberInput already clamps typed values, so the cap is authoritative) - Start/end handle drag commits cap thickness to the new length so shrinking a line below its current thickness pulls thickness down rather than violating the invariant Existing stored lines with t > length keep their data and continue to print the promoted square; touching any handle or input snaps them back into a valid state. An explicit import-time warning for this case will follow in a separate change.
1 parent e4d9cd4 commit 878d69c

2 files changed

Lines changed: 31 additions & 6 deletions

File tree

‎src/components/Canvas/LineObject.tsx‎

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -459,10 +459,18 @@ export function LineObject({
459459
e.target.getParent(),
460460
);
461461
clearSnap();
462+
// Shrinking the line below the current thickness would
463+
// push the ZPL into the `^GB` promotion regime (t > length
464+
// → printed `t × t`); cap thickness to the new length so
465+
// the model preserves the t ≤ length invariant.
462466
onChange({
463467
x: r.movingDotX,
464468
y: r.movingDotY,
465-
props: { length: r.length, angle: r.angle },
469+
props: {
470+
length: r.length,
471+
angle: r.angle,
472+
thickness: Math.min(p.thickness, r.length),
473+
},
466474
});
467475
}}
468476
/>
@@ -520,7 +528,13 @@ export function LineObject({
520528
e.target.getParent(),
521529
);
522530
clearSnap();
523-
onChange({ props: { length: r.length, angle: r.angle } });
531+
onChange({
532+
props: {
533+
length: r.length,
534+
angle: r.angle,
535+
thickness: Math.min(p.thickness, r.length),
536+
},
537+
});
524538
}}
525539
/>
526540
<Rect
@@ -549,9 +563,13 @@ export function LineObject({
549563
const extPx = isHorizontal
550564
? cursorY - lineCenterY
551565
: cursorX - lineCenterX;
552-
const newT = Math.max(
553-
1,
554-
Math.round(pxToDots(extPx, scale, dpmm)),
566+
// Cap at p.length so the line never enters the ZPL ^GB
567+
// promotion regime where thickness exceeds length and
568+
// Labelary would print `t × t` rather than the band the
569+
// user is dragging.
570+
const newT = Math.min(
571+
p.length,
572+
Math.max(1, Math.round(pxToDots(extPx, scale, dpmm))),
555573
);
556574
setLiveThicknessDots(newT);
557575
// Pin the Rect to the (possibly-clamped) anchor so

‎src/registry/line.tsx‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,10 @@ export const line: ObjectTypeDefinition<LineProps> = {
124124
<NumberInput
125125
label={t.registry.line.length}
126126
value={p.length}
127-
min={1}
127+
// Floored at thickness for the same reason thickness is
128+
// capped at length below: keeps the model out of the ^GB
129+
// promotion regime where t > length prints `t × t`.
130+
min={p.thickness}
128131
onChange={(length) => onChange({ length })}
129132
/>
130133
<NumberInput
@@ -140,6 +143,10 @@ export const line: ObjectTypeDefinition<LineProps> = {
140143
label={t.registry.line.thickness}
141144
value={p.thickness}
142145
min={1}
146+
// Capped at length so the ZPL output stays out of the ^GB
147+
// promotion regime (max(w, t) × max(h, t)), where the printer
148+
// would extend the line beyond its declared length.
149+
max={p.length}
143150
onChange={(thickness) => onChange({ thickness })}
144151
/>
145152

0 commit comments

Comments
 (0)