Bug 40473

Summary: X scale for Code39 barcodes is calculated incorrectly when generating barcode labels
Product: Koha Reporter: David Cook <dcook>
Component: Label/patron card printingAssignee: David Cook <dcook>
Status: Needs Signoff --- QA Contact: Testopia <testopia>
Severity: normal    
Priority: P5 - low    
Version: Main   
Hardware: All   
OS: All   
See Also: https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=10762
GIT URL: Change sponsored?: ---
Patch complexity: --- Documentation contact:
Documentation submission: Text to go in the release notes:
Version(s) released in:
Circulation function:
Attachments: Bug 40473: Use better algorithm for calculating Code39 barcode length

Description David Cook 2025-07-23 02:07:27 UTC
While reviewing how "Barcode width" works as added by bug 10762, I noticed that the calculation of the X scale factor for Code39 barcodes is incorrect.

If you specify a Barcode width of 1, you'd expect that to use 100% of the label width. But it doesn't. 

Now this isn't a problem introduced by Bug 10762, because Bug 10762 just replaced a hard-coded value of .8 with a editable value. It's a much older bug.

Consider the following:

$x_scale_factor = ( $params{'width'} / $tot_bar_length );

$params{'width'} is the "Barcode width" multiplied by the label width. This makes sense as it represents the total width that we're willing to use.

The problem is $tot_bar_length. It uses an algorithm which is inconsistent with the algorithm used by PDF::Reuse::Barcode. But that's easy to fix!
Comment 1 David Cook 2025-07-23 02:16:46 UTC
In PDF::Reuse::Barcode, the barcode is actually rendered on top of a white background, and that white background is calculated using this code:

$length     = 20 + (length($sPtn) * 0.9);

20 is an arbitrary number chosen by the creator of PDF::Reuse::Barcode to add padding around the barcode. 

Now $sPtn is the output of the following:

my $oGDBar = GD::Barcode::Code39->new($value);
$sPtn = $oGDBar->barcode();

Consider you have the Koha item barcode 39999000001310

The $sPtn will contain the following:
1000101110111010111011100010101010111000101110101011100010111010101110001011101010111000101110101010001110111010101000111011101010100011101110101010001110111010101000111011101011101000101011101110111000101010111010001010111010100011101110101000101110111010

When we use this calculation from PDF::Reuse::Barcode in Koha to calculate the barcode length, we get the *real* length of the barcode. 

With this patched, if we use a "Barcode width" of "1", the barcode plus its white barcode box background will take up 100% of the label. Thanks to that 20 point padding, we'll have some whitespace on the left and right sides of the barcode.

When using a "Barcode with" of 1, you get a perfectly centered barcode as well.
Comment 2 David Cook 2025-07-23 02:17:27 UTC
Note: if you use a Barcode width of .8, you do not get a centered barcode, but that's the status quo. That's how it is in main anyway.

I'll raise a different bug report for that...
Comment 3 David Cook 2025-07-23 02:31:19 UTC
The difference becomes even more obvious when you use "Code39 + Modulo43" or "Code39 + Modulo10".
Comment 4 David Cook 2025-07-23 02:49:39 UTC
Created attachment 184529 [details] [review]
Bug 40473: Use better algorithm for calculating Code39 barcode length

This patch uses the PDF::Reuse::Barcode algorithm for calculating barcode
background box length relative to barcode length in order to determine
the actual barcode width and thus the X scale factor required to re-size
that barcode so that it fits on the label width (or rather the
"Barcode width" which is a percentage applied to the label width
to create a narrower usable surface for the barcode and barcode background
box).

To test:
0. Apply the patch
1. Go to http://localhost:8081/cgi-bin/koha/cataloguing/additem.pl?biblionumber=29
2. Add an item with barcode 123456, add an item with barcode 39999000001310399991,
    and ensure an item with barcode 39999000001310 already exists
3. Go to http://localhost:8081/cgi-bin/koha/labels/label-manage.pl?label_element=batch
4. Create a patch that uses 3 items using 39999000001310, 2 items with 123456,
    and 2 items with 39999000001310399991
4. Go to http://localhost:8081/cgi-bin/koha/labels/label-manage.pl?label_element=layout
5. Edit the layout "Label Test"
6. Change the "Barcode width" to 1, and enable "Draw guide boxes", and click "Save"
7. Export the batch using the template "Avery 5160 | 1 x 2-5/8" and the layout "Label Test" and open as PDF
8. Note that the whole barcode fits inside the red guidebox (there should be some
overlap of white on top of the red guidebox but that is normal since we're using 100% of the
barcode label width).
9. Edit the "Label Test" layout to try "Code39 + Modulo43" and "Code39 + Modulo10" and retry batch export
10. Edit the "Label Test" and try different "Barcode width" like the usual default .8
11. Celebrate that your barcodes fit on the label!