Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions src/components/Canvas/BarcodeObject.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import bwipjs from "bwip-js/browser";
import { Image as KImage, Group, Rect, Text } from "react-konva";
import type Konva from "konva";
import type { LabelObject } from "../../registry";
import { BARCODE_1D_TYPES } from "../../registry";
import { BARCODE_1D_TYPES, ObjectRegistry } from "../../registry";
import type { ObjectChanges } from "../../store/labelStore";
import { dotsToPx, pxToDots } from "../../lib/coordinates";
import {
Expand Down Expand Up @@ -144,8 +144,12 @@ export function BarcodeObject({
if (barcodeCanvas) {
const w = displayW;
const h = displayH;
const printInterp = !!(obj.props as { printInterpretation?: boolean })
.printInterpretation;
// Force-off when the symbology has no HRI in ZPL (e.g. GS1 Databar) — the
// canvas must match the print output even if a legacy saved object still
// carries printInterpretation: true.
const printInterp =
!ObjectRegistry[obj.type]?.interpretationLocked &&
!!(obj.props as { printInterpretation?: boolean }).printInterpretation;
Comment thread
u8array marked this conversation as resolved.
const moduleWidth =
(obj.props as { moduleWidth?: number }).moduleWidth ?? 2;
const textFontSize = Math.max(dotsToPx(moduleWidth * 10, scale, dpmm), 6);
Expand Down Expand Up @@ -435,9 +439,7 @@ export function BarcodeObject({
}

// ── Other 1D: separate Konva Text below bars ──────────────────────────
const showText =
BARCODE_1D_TYPES.has(obj.type) &&
(obj.props as { printInterpretation?: boolean }).printInterpretation;
const showText = BARCODE_1D_TYPES.has(obj.type) && printInterp;

let displayText = rawContent;
if (obj.type === "code39") {
Expand Down
32 changes: 21 additions & 11 deletions src/registry/barcode1d.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ interface Barcode1DConfig {
byRatio?: number;
/** See {@link ObjectTypeDefinition.heightLocked}. */
heightLocked?: boolean;
/** See {@link ObjectTypeDefinition.interpretationLocked}. */
interpretationLocked?: boolean;
}

interface BarcodeLocale {
Expand All @@ -52,16 +54,22 @@ export function createBarcode1D(config: Barcode1DConfig): ObjectTypeDefinition<B
content: config.defaultContent,
height: 100,
moduleWidth: 2,
printInterpretation: true,
printInterpretation: !config.interpretationLocked,
Comment thread
u8array marked this conversation as resolved.
checkDigit: false,
},
defaultSize: { width: 300, height: 120 },
heightLocked: config.heightLocked,
interpretationLocked: config.interpretationLocked,

commitTransform: config.heightLocked ? undefined : commitHeightTransform,

toZPL: (obj: LabelObjectBase & { props: Barcode1DProps }) => {
const p = obj.props;
// Normalize printInterpretation for symbologies that have no HRI in ZPL
// (e.g. ^BR). This protects against legacy saved objects that still carry
// printInterpretation: true from emitting an out-of-spec interpretation flag.
const p = config.interpretationLocked
? { ...obj.props, printInterpretation: false }
: obj.props;
const byCmd = config.byRatio !== undefined
? `^BY${p.moduleWidth},${config.byRatio}`
: `^BY${p.moduleWidth}`;
Expand Down Expand Up @@ -115,15 +123,17 @@ export function createBarcode1D(config: Barcode1DConfig): ObjectTypeDefinition<B
/>
</div>

<label className="flex items-center gap-2 cursor-pointer">
<input
type="checkbox"
className="accent-accent"
checked={p.printInterpretation}
onChange={(e) => onChange({ printInterpretation: e.target.checked })}
/>
<span className={labelCls}>{loc.printInterpretation}</span>
</label>
{!config.interpretationLocked && (
<label className="flex items-center gap-2 cursor-pointer">
<input
type="checkbox"
className="accent-accent"
checked={p.printInterpretation}
onChange={(e) => onChange({ printInterpretation: e.target.checked })}
/>
<span className={labelCls}>{loc.printInterpretation}</span>
</label>
)}

{config.hasCheckDigit && (
<label className="flex items-center gap-2 cursor-pointer">
Expand Down
2 changes: 2 additions & 0 deletions src/registry/gs1databar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ export const gs1databar = createBarcode1D({
// ignore the ^BR height parameter for this variant. Disabling resize and the
// height input keeps the designer honest about what affects the print.
heightLocked: true,
// ZPL ^BR has no HRI parameter — Labelary never prints text under the bars.
interpretationLocked: true,
zplCommand: (p) => {
// ^BR{orientation},{symbology},{magnification},{separator},{height},{segments}
// symbology 1 = omnidirectional
Expand Down
7 changes: 7 additions & 0 deletions src/types/ObjectType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,13 @@ export interface ObjectTypeDefinition<P extends object = object> {
* read-only — both reflect that the value cannot influence the print output.
*/
heightLocked?: boolean;
/**
* True if the symbology has no human-readable interpretation in ZPL output
* (e.g. GS1 Databar — `^BR` exposes no HRI parameter and Labelary never
* renders text). The properties panel hides the checkbox and the canvas
* renderer suppresses the text so the designer matches the print output.
*/
interpretationLocked?: boolean;
toZPL: (obj: LabelObjectBase & { props: P }) => string;
/**
* Optional hook to enforce type-specific invariants on incoming changes
Expand Down