Skip to content

Commit 6524f03

Browse files
committed
fix(zpl): UPC-A and UPC-E render the mandatory check digit
Pre-existing bug surfaced during the rotation refactor review: - `^BU` (UPC-A) was emitted with the 5th parameter (printCheckDigit) hardcoded to `N`. Zebra's own default is `Y`; with `N` the printer omits the check digit from the HRI line. Industry retail UPC-A always shows it floated right of the bars, mirror of the system digit on the left. - `^B9` (UPC-E) likewise hardcoded the 4th parameter to `N`. Same fix: switch to `Y` to match Zebra/Labelary default and the print convention. The canvas overlay already had `trail()` wired for UPC-E, so the visual side needed no change for it. - UPC-A canvas overlay (`eanUpcDigitNodes.tsx`) now renders the trailing check digit (slice[11]) symmetric to UPC-E's trail node, with `clipRight` extended so the floated digit stays visible past the bar bbox. Stale comment claiming Labelary suppresses the digit was wrong — Labelary suppressed it only because we asked it to via the hardcoded `N`. Labelary fixtures regenerated with the new ZPL; sync test fixtures updated accordingly. No new prop introduced — UPC-A/E HRI is a fixed retail format, the check digit isn't an opt-in display setting.
1 parent d3c38d0 commit 6524f03

7 files changed

Lines changed: 20 additions & 7 deletions

File tree

‎src/components/Canvas/eanUpcDigitNodes.tsx‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,13 +81,18 @@ export function buildEanUpcDigitOverlay(args: BuildArgs): EanUpcDigitOverlay {
8181
],
8282
};
8383
case "upca":
84+
// UPC-A HRI: number system (1) | 5 manuf | 5 product | check (1).
85+
// System digit floats left of the bars, check digit floats right —
86+
// matches Zebra's ^BU default (checkDigit=Y) which the generator
87+
// now emits.
8488
return {
8589
clipLeft: ldW,
86-
clipRight: 0,
90+
clipRight: ldW,
8791
nodes: [
8892
sys(displayText[0] ?? ""),
8993
main("left", xLeft, halfW, displayText.slice(1, 6)),
9094
main("right", xRight, halfW, displayText.slice(6, 11)),
95+
trail(displayText[11] ?? ""),
9196
],
9297
};
9398
case "upce":

‎src/registry/upca.tsx‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,12 @@ export const upca = createBarcode1D({
1212
contentSpec: { charset: '0-9', maxLength: 11 },
1313
zplCommand: (p) => {
1414
const interp = p.printInterpretation ? 'Y' : 'N';
15-
return `^BU${p.rotation},${p.height},${interp},N,N`;
15+
// ^BU params: rotation, height, interpretation, above, checkDigit.
16+
// checkDigit=Y matches Zebra's own default (we previously forced N
17+
// and the HRI line dropped the 12th digit) and the retail/UPC-A
18+
// print convention — the 12th digit floats right of the bars,
19+
// analogous to the system digit on the left.
20+
return `^BU${p.rotation},${p.height},${interp},N,Y`;
1621
},
1722
hri: { formatHri: formatUpcaHri },
1823
});

‎src/registry/upce.tsx‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ export const upce = createBarcode1D({
1212
contentSpec: { charset: '0-9', maxLength: 6 },
1313
zplCommand: (p) => {
1414
const interp = p.printInterpretation ? 'Y' : 'N';
15-
return `^B9${p.rotation},${p.height},${interp},N`;
15+
// ^B9 params: rotation, height, interpretation, checkDigit.
16+
// checkDigit=Y matches Zebra's own default and the print
17+
// convention — the check digit floats right of the bars.
18+
return `^B9${p.rotation},${p.height},${interp},Y`;
1619
},
1720
hri: { formatHri: formatUpceHri },
1821
});
0 Bytes
Loading
1 Byte
Loading

‎tests/fixtures/labelary_images/fixtures.json‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@
101101
},
102102
{
103103
"id": "barcode_upca_standard",
104-
"zpl_input": "^XA^BY2^FO50,50^BUN,100,N,N,N^FD01234567890^FS^XZ",
104+
"zpl_input": "^XA^BY2^FO50,50^BUN,100,N,N,Y^FD01234567890^FS^XZ",
105105
"expected_bounds": {
106106
"x": 50,
107107
"y": 50,
@@ -321,7 +321,7 @@
321321
},
322322
{
323323
"id": "barcode_upce_standard",
324-
"zpl_input": "^XA^BY2^FO50,50^B9N,100,N,N^FD012345^FS^XZ",
324+
"zpl_input": "^XA^BY2^FO50,50^B9N,100,N,Y^FD012345^FS^XZ",
325325
"expected_bounds": {
326326
"x": 50,
327327
"y": 50,

‎tests/fixtures/testCases.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ export const testCases: TestCase[] = [
6868
},
6969
{
7070
id: "barcode_upca_standard",
71-
zpl_input: "^XA^BY2^FO50,50^BUN,100,N,N,N^FD01234567890^FS^XZ",
71+
zpl_input: "^XA^BY2^FO50,50^BUN,100,N,N,Y^FD01234567890^FS^XZ",
7272
expected_bounds: { x: 50, y: 50, width: 200, height: 100 },
7373
image_ref: "barcode_upca_standard.png",
7474
},
@@ -224,7 +224,7 @@ export const testCases: TestCase[] = [
224224
// The ZPL roundtrip is covered by a unit test in zplGenerator.test.ts.
225225
{
226226
id: "barcode_upce_standard",
227-
zpl_input: "^XA^BY2^FO50,50^B9N,100,N,N^FD012345^FS^XZ",
227+
zpl_input: "^XA^BY2^FO50,50^B9N,100,N,Y^FD012345^FS^XZ",
228228
expected_bounds: { x: 50, y: 50, width: 102, height: 113 },
229229
image_ref: "barcode_upce_standard.png",
230230
},

0 commit comments

Comments
 (0)