@@ -188,6 +188,23 @@ export function get1DBwipScale(
188188 return Math . max ( 1 , Math . round ( dotsToPx ( moduleWidth , scale , dpmm ) ) ) ;
189189}
190190
191+ /**
192+ * Render-scale for 1D barcodes: integer-aligned per-module scale when the
193+ * caller supplies the canvas scale + dpmm, otherwise the BWIP_SCALE default.
194+ * Wrapping the branch lets per-type cases pass their own (narrowed,
195+ * required-typed) `moduleWidth` instead of going through a cast at the
196+ * generic top of buildBwipOptions.
197+ */
198+ function bwipScale1D (
199+ moduleWidth : number ,
200+ renderScale : number | undefined ,
201+ renderDpmm : number | undefined ,
202+ ) : number {
203+ return renderScale != null && renderDpmm != null
204+ ? get1DBwipScale ( moduleWidth , renderScale , renderDpmm )
205+ : BWIP_SCALE ;
206+ }
207+
191208export function eanCheckDigit ( digits : string , w0 : number , w1 : number ) : string {
192209 let sum = 0 ;
193210 for ( let i = 0 ; i < digits . length ; i ++ )
@@ -232,14 +249,6 @@ export function buildBwipOptions(
232249 const bcid = BCID [ obj . type ] ;
233250 if ( ! bcid ) return null ;
234251
235- // For 1D barcodes, choose an integer-aligned scale so module widths map
236- // exactly to display pixels (no fractional upscaling / anti-aliasing).
237- const mw = ( obj . props as { moduleWidth ?: number } ) . moduleWidth ?? 2 ;
238- const scale1D =
239- renderScale != null && renderDpmm != null
240- ? get1DBwipScale ( mw , renderScale , renderDpmm )
241- : BWIP_SCALE ;
242-
243252 // bwip-js takes the same N/R/I/B letters ZPL does for symbol orientation;
244253 // emitting it post-build means the produced bitmap is already rotated and
245254 // its dimensions are the post-rotation extents — no Konva-side rotation math
@@ -254,26 +263,28 @@ export function buildBwipOptions(
254263 case "upca" :
255264 case "upce" : {
256265 const p = obj . props ;
266+ const scale = bwipScale1D ( p . moduleWidth , renderScale , renderDpmm ) ;
257267 let text : string ;
258268 if ( obj . type === "upce" ) {
259269 const r = p . content || "000000" ;
260270 text = r . length === 6 ? `0${ r } ` : r ;
261271 } else {
262272 text = p . content || "0" ;
263273 }
264- opts = { bcid, text, scale : scale1D , height : 10 } ;
274+ opts = { bcid, text, scale, height : 10 } ;
265275 break ;
266276 }
267277 case "code128" : {
268- const p = obj . props as { content ?: string } ;
278+ const p = obj . props ;
279+ const scale = bwipScale1D ( p . moduleWidth , renderScale , renderDpmm ) ;
269280 const text = p . content || "0" ;
270281 // Note: ZPL ^BC e=Y (checkDigit) only prints the MOD-10 digit in the
271282 // interpretation line — it does NOT append it to the encoded barcode data.
272283 const rawB = toCode128BRaw ( text ) ;
273284 if ( rawB ) {
274- opts = { bcid, text : rawB , raw : true , scale : scale1D , height : 10 } ;
285+ opts = { bcid, text : rawB , raw : true , scale, height : 10 } ;
275286 } else {
276- opts = { bcid, text, scale : scale1D , height : 10 } ;
287+ opts = { bcid, text, scale, height : 10 } ;
277288 }
278289 break ;
279290 }
@@ -286,6 +297,7 @@ export function buildBwipOptions(
286297 case "codabar" :
287298 case "plessey" : {
288299 const p = obj . props ;
300+ const scale = bwipScale1D ( p . moduleWidth , renderScale , renderDpmm ) ;
289301 // Code39/Codabar/Plessey only encode uppercase letters. Zebra firmware
290302 // (and Labelary) silently uppercase lowercase input; bwip-js does not and
291303 // throws instead, which would crash the canvas for any imported ZPL with
@@ -294,35 +306,39 @@ export function buildBwipOptions(
294306 const needsUpper = obj . type === "code39" || obj . type === "codabar" || obj . type === "plessey" ;
295307 const raw = p . content || "0" ;
296308 const text = needsUpper ? raw . toUpperCase ( ) : raw ;
297- opts = { bcid, text, scale : scale1D , height : 10 } ;
309+ opts = { bcid, text, scale, height : 10 } ;
298310 break ;
299311 }
300312 case "msi" : {
301313 const p = obj . props ;
314+ const scale = bwipScale1D ( p . moduleWidth , renderScale , renderDpmm ) ;
302315 // Zebra always encodes a Mod10 check digit in MSI regardless of the ^BM e=N
303316 // parameter (which only suppresses it in the interpretation line).
304- opts = { bcid, text : p . content || "0" , scale : scale1D , height : 10 , includecheck : true } ;
317+ opts = { bcid, text : p . content || "0" , scale, height : 10 , includecheck : true } ;
305318 break ;
306319 }
307320 case "postal" : {
308321 const p = obj . props ;
309- opts = { bcid, text : p . content || "0" , scale : scale1D , height : 10 } ;
322+ const scale = bwipScale1D ( p . moduleWidth , renderScale , renderDpmm ) ;
323+ opts = { bcid, text : p . content || "0" , scale, height : 10 } ;
310324 break ;
311325 }
312326 case "logmars" : {
313327 const p = obj . props ;
328+ const scale = bwipScale1D ( p . moduleWidth , renderScale , renderDpmm ) ;
314329 // LOGMARS is a Code39 subset; same uppercase rule applies.
315330 opts = {
316331 bcid,
317332 text : ( p . content || "0" ) . toUpperCase ( ) ,
318- scale : scale1D ,
333+ scale,
319334 height : 10 ,
320335 includecheck : true ,
321336 } ;
322337 break ;
323338 }
324339 case "gs1databar" : {
325340 const p = obj . props ;
341+ const scale = bwipScale1D ( p . moduleWidth , renderScale , renderDpmm ) ;
326342 const sym = p . symbology ;
327343 const isExpanded = GS1_DATABAR_EXPANDED_SYMBOLOGIES . has ( sym ) ;
328344 // bwip-js needs (AI)data parens; canonical model stores raw digits.
@@ -333,7 +349,7 @@ export function buildBwipOptions(
333349 opts = {
334350 bcid : GS1_DATABAR_BCID [ sym ] ,
335351 text,
336- scale : scale1D ,
352+ scale,
337353 height : 10 ,
338354 paddingheight : 2 ,
339355 ...( sym === 7 ? { segments : p . segments ?? GS1_DATABAR_DEFAULT_SEGMENTS } : { } ) ,
@@ -342,13 +358,14 @@ export function buildBwipOptions(
342358 }
343359 case "planet" : {
344360 const p = obj . props ;
361+ const scale = bwipScale1D ( p . moduleWidth , renderScale , renderDpmm ) ;
345362 let raw = ( p . content || "0" ) . replace ( / \D / g, "" ) ;
346363 if ( raw . length < 11 ) raw = raw . padStart ( 11 , "0" ) ;
347364 else if ( raw . length === 12 ) raw = raw . padStart ( 13 , "0" ) ;
348365 opts = {
349366 bcid,
350367 text : raw ,
351- scale : scale1D ,
368+ scale,
352369 height : 10 ,
353370 includecheck : true ,
354371 } ;
0 commit comments