From 26a59ee99db767da812a4c5669d8e9e80d42034b Mon Sep 17 00:00:00 2001 From: Lucas Gass Date: Wed, 21 Jan 2026 18:31:51 +0000 Subject: [PATCH] Bug 40478: Add ability to justify CODE39 barcodes To test: 1. Apply patch, updatedatabase, restart_all 2. Create at least 1 label batch 3. Create or edit an existing layout. 4. You should now see a dropdown labeled "Barcode justification:" with options to align left, right, and center. 5. At this point I like to check "Draw guide boxes" as it makes testing alignment much easier. 6. Now test generating label sets to "Download as PDF". 7. You will want to make sure the barcode properly aligns left, right, and center. 8. Test with all the different "Choose barcode type (encoding):" options. Ensuring the barcodes align correectly left, right, and center. 9. Also test with all the different "Choose layout type:" that will display a barcode. --- C4/Creators/Layout.pm | 32 ++++----- C4/Labels/Label.pm | 38 +++++++++-- .../en/modules/labels/label-edit-layout.tt | 12 ++++ labels/label-create-pdf.pl | 3 + labels/label-edit-layout.pl | 66 ++++++++++--------- 5 files changed, 98 insertions(+), 53 deletions(-) diff --git a/C4/Creators/Layout.pm b/C4/Creators/Layout.pm index 3edb8b19625..7153bd64e13 100644 --- a/C4/Creators/Layout.pm +++ b/C4/Creators/Layout.pm @@ -35,6 +35,7 @@ sub _check_params { 'scale_height', 'callnum_split', 'text_justify', + 'barcode_justify', 'format_string', 'layout_xml', # FIXME: all layouts should be stored in xml format to greatly simplify handling -chris_n 'creator', @@ -69,21 +70,22 @@ sub new { my $type = ref($invocant) || $invocant; if ( grep { $_ eq 'Labels' } @_ ) { $self = { - layout_xml => '', - units => 'POINT', - start_label => 1, - barcode_type => 'CODE39', - printing_type => 'BAR', - layout_name => 'DEFAULT', - guidebox => 0, - oblique_title => 1, - font => 'TR', - font_size => 3, - scale_width => 0.8, - scale_height => 0.01, - callnum_split => 0, - text_justify => 'L', - format_string => join( ', ', @{ PRESET_FIELDS() } ), + layout_xml => '', + units => 'POINT', + start_label => 1, + barcode_type => 'CODE39', + printing_type => 'BAR', + layout_name => 'DEFAULT', + guidebox => 0, + oblique_title => 1, + font => 'TR', + font_size => 3, + scale_width => 0.8, + scale_height => 0.01, + callnum_split => 0, + text_justify => 'L', + barcode_justify => 'L', + format_string => join( ', ', @{ PRESET_FIELDS() } ), @_, }; } elsif ( grep { $_ eq 'Patroncards' } @_ ) { diff --git a/C4/Labels/Label.pm b/C4/Labels/Label.pm index e7a28efc9f2..f8c118c56d0 100644 --- a/C4/Labels/Label.pm +++ b/C4/Labels/Label.pm @@ -317,6 +317,7 @@ sub new { scale_height => $params{'scale_height'}, callnum_split => $params{'callnum_split'}, justify => $params{'justify'}, + barcode_justify => $params{'barcode_justify'}, format_string => $params{'format_string'}, text_wrap_cols => $params{'text_wrap_cols'}, barcode => $params{'barcode'}, @@ -368,10 +369,11 @@ sub create_label { if ( $self->{'printing_type'} =~ /BAR/ ) { barcode( $self, - llx => $barcode_llx, - lly => $barcode_lly, - width => $barcode_width, - y_scale_factor => $barcode_y_scale_factor, + llx => $barcode_llx, + lly => $barcode_lly, + width => $barcode_width, + y_scale_factor => $barcode_y_scale_factor, + barcode_justify => $self->{'barcode_justify'}, ); } return $label_text if $label_text; @@ -516,9 +518,13 @@ sub draw_guide_box { sub barcode { my $self = shift; my %params = @_; + $params{'barcode_data'} = ( $self->{'barcode'} || _get_label_item( $self->{'item_number'}, 1 ) ) if !$params{'barcode_data'}; $params{'barcode_type'} = $self->{'barcode_type'} if !$params{'barcode_type'}; + + my $barcode_justify = $params{'barcode_justify'} || 'L'; + my $x_scale_factor = 1; my $num_of_bars = length( $params{'barcode_data'} ); my $tot_bar_length = 0; @@ -541,8 +547,18 @@ sub barcode { my $oGdB = GD::Barcode::Code39->new("*$params{'barcode_data'}*"); my $whole_barcode_length = ( length( $oGdB->barcode() ) * 0.9 ) + 20; $x_scale_factor = ( $params{'width'} / $whole_barcode_length ); + + my $adjusted_llx = $params{'llx'}; + my $barcode_width = $whole_barcode_length * $x_scale_factor; + + if ( $barcode_justify eq 'C' ) { + $adjusted_llx = $params{'llx'} + ( ( $self->{'width'} - $barcode_width ) / 2 ); + } elsif ( $barcode_justify eq 'R' ) { + $adjusted_llx = $params{'llx'} + ( $self->{'width'} - $barcode_width ); + } + PDF::Reuse::Barcode::Code39( - x => $params{'llx'}, + x => $adjusted_llx, y => $params{'lly'}, value => "*$params{barcode_data}*", xSize => $x_scale_factor, @@ -559,9 +575,13 @@ sub barcode { $bar_length = '9.43333333333333'; $tot_bar_length = ( $bar_length * $num_of_bars ) + ( $guard_length * 2 ); $x_scale_factor = ( $params{'width'} / $tot_bar_length ) * 0.9; + + my $adjusted_llx = $params{'llx'}; + my $barcode_width = $tot_bar_length * $x_scale_factor; + eval { PDF::Reuse::Barcode::COOP2of5( - x => $params{'llx'}, + x => $adjusted_llx, y => $params{'lly'}, value => $params{barcode_data}, xSize => $x_scale_factor, @@ -576,9 +596,13 @@ sub barcode { $bar_length = '13.1333333333333'; $tot_bar_length = ( $bar_length * $num_of_bars ) + ( $guard_length * 2 ); $x_scale_factor = ( $params{'width'} / $tot_bar_length ) * 0.9; + + my $adjusted_llx = $params{'llx'}; + my $barcode_width = $tot_bar_length * $x_scale_factor; + eval { PDF::Reuse::Barcode::Industrial2of5( - x => $params{'llx'}, + x => $adjusted_llx, y => $params{'lly'}, value => $params{barcode_data}, xSize => $x_scale_factor, diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/labels/label-edit-layout.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/labels/label-edit-layout.tt index 73bd4d53fa4..d0a15a0330e 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/labels/label-edit-layout.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/labels/label-edit-layout.tt @@ -184,6 +184,18 @@ [% END %] +
  • + + +