Feat/zpl bs and hri refactor#90
Merged
Merged
Conversation
New standalone object type for the ^BS supplement printed alongside
UPC-A / EAN-13. Common uses: 5-digit ISBN price code on books,
2-digit issue number on magazines. The user positions it manually
next to the main barcode (separate object), mirroring how the rest
of the registry works (one type per ZPL command, no cross-cutting
props on existing types).
ZPL: single ^BS{o},{h},{f} command for both lengths. Canvas:
bwip-js bcid resolved from content.length (ean2 vs ean5) since
bwip splits what ZPL unifies. bwip needs explicit includetext +
textyalign='above' to match Zebra firmware, which prints the
human-readable digits above the bars (unlike main EAN/UPC where
they sit below).
Bbox math matches Labelary:
- printInterpretation=Y: bbox extends UPC_SUPP_TEXT_ZONE_DOTS (18)
above the FO anchor; bars sit at obj.y, text above
- printInterpretation=N: bbox = bar height (no guard, unlike main
EAN/UPC which always reserves 13)
The canvas y-shift handles the above-anchor placement in
BarcodeObject; tests special-case visualY for the supplement.
Validation: ContentSpec gained `validLengths` for soft-warning when
the field isn't a valid length set. UPC/EAN supplement spec uses
[2, 5]; the PropertiesPanel surfaces an inline amber hint when the
length is wrong (no input blocking, since the user has to pass
through invalid lengths to reach 5).
Parser, generator, locale entries for all 32 locales (best-effort
quality tier), support matrix update (BS unsupported -> supported),
public roadmap entry moved from Coming soon to Supported.
Coverage: round-trip tests for both lengths and rotation;
bcid-resolution test in bwipHelpers; contentSpec validation tests;
Labelary visual-regression and bbox-sync fixtures for both supps
(bars-only N variant so the bwip-vs-Zebra font difference doesn't
break the strict pixel diff).
Known limitation: bwip-js ean2 renders 19 modules where Zebra
prints 20, a 2-dot width delta documented at hasBwipSizeMismatch
in labelarySync.test.ts.
Three changes that all centre on the rotated 1D HRI overlay: 1. Extract getRotatedTextAnchor in bwipHelpers. The previous per-rotation sideX math (-textGap / w+textGap) anchored against the bbox edge, which silently double-counted the firmware text zone (EAN/UPC: 13 dots, logmars: 20 dots). The helper anchors against the bar sub-rectangle so the gap is exactly textGap regardless of which side the zone sits on. Fixes a pre-existing spacing bug on rotated logmars + ean13/upca/ean8/upce. 2. Switch ^BS (upcEanExtension) HRI from bwip-embedded text to a Konva overlay, matching the logmars pattern. bwip's includetext bakes the text into the bitmap, which then rotates as a unit and lands on the wrong side for R/B/I; the overlay positions correctly via the helper. Drops the fillFullBbox special case and the upcEanExtension exclusion from showText. 3. Per-type above-bars gap. logmars keeps its wider 10-dot air gap (LOGMARS_TEXT_ABOVE_GAP_DOTS); ^BS sits very tight to the bars (UPC_SUPP_TEXT_ABOVE_GAP_DOTS = 2) per Labelary. Also anchor the upright text-above against btY so the firmware-reserved text zone isn't added on top of the visual gap. HRI text now renders bold across all 1D types, slightly closer to the Zebra HRI weight than plain Courier New.
Replace the obj.type-string chains in BarcodeObject (isTextAbove, aboveGap, displayText) with an `hri?: HriBehavior` field on each 1D leaf. New `hri` fields wired for ean13/ean8/upca/upce/code39/logmars/ upcEanExtension; defaults preserve behaviour for the remaining 1D types (raw content, below bars, textGap). Per-type formatters live in registry/hriFormatters.ts. Check-digit math (eanCheckDigit / upceCheckDigit) moved from Canvas/bwipHelpers to lib/barcodeCheckDigits.ts so the registry can import without crossing into the Canvas layer; bwipHelpers re-exports for backwards compat. The EAN/UPC multi-Text digit-split branches consume displayText directly instead of recomputing the formatted string inline, so the registry's formatHri is the single source of truth for HRI content. Net effect: adding a new 1D symbology no longer touches BarcodeObject to wire up its HRI behaviour; everything lives in the leaf.
There was a problem hiding this comment.
Code Review
This pull request implements support for the ^BS UPC/EAN supplement barcode, including its 2-digit and 5-digit variants. The changes involve updating the ZPL parser and generator, adding localization strings across multiple languages, and introducing a new HriBehavior configuration to handle human-readable interpretation (HRI) text positioning (specifically for text rendered above bars). Additionally, check-digit logic was moved to a pure utility file for better reusability. A critical issue was identified in the bounding box calculation for logmars barcodes, where the isTextAbove flag needs to be applied to ensure correct rendering bounds.
bwipHelpers.getDisplaySize was hardcoding `isTextAbove` to upcEanExtension only, leaving logmars treated as text-below. The bbox reserved the firmware text zone at the bottom while BarcodeObject drew the HRI overlay above the bars at negative y — text leaked outside the selection bbox. Reading hri.textAbove from the registry fixes logmars and matches the source of truth BarcodeObject already consumes. Bug spotted by gemini review on PR #90. Also pick up the remaining nits from the prior round: - JSDoc on HriBehavior points at logmars / upcEanExtension as canonical examples for new contributors - Unit tests for hriFormatters cover happy path + edge cases (invalid chars in LOGMARS charset, short inputs, length-driven routing in ^BS) — 15 new tests
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.