From 96fbeea48a87abd78ce2780b24664c207a2c08d9 Mon Sep 17 00:00:00 2001 From: Wolfgang Apolinarski Date: Sun, 14 Jul 2024 22:13:17 +0200 Subject: [PATCH] Bug 37356: Refactor barcode drawing code Created new Drawer class in the Barcodes directory which contains now the common code Updated the Patroncard file to refer to this new common barcode drawing code. Update the Label file to refer to this new common barcode drawing code. I had to add the barcode_data parameter to the call. --- C4/Barcodes/Drawer.pm | 159 +++++++++++++++++++++++++++++++++++ C4/Labels/Label.pm | 127 +--------------------------- C4/Patroncards/Patroncard.pm | 86 +------------------ 3 files changed, 164 insertions(+), 208 deletions(-) create mode 100644 C4/Barcodes/Drawer.pm diff --git a/C4/Barcodes/Drawer.pm b/C4/Barcodes/Drawer.pm new file mode 100644 index 0000000000..4285fa2cb0 --- /dev/null +++ b/C4/Barcodes/Drawer.pm @@ -0,0 +1,159 @@ +package C4::Barcodes::Drawer; + +# Copyright 2024 Koha Development Team +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +=head1 NAME + +C4::Barcodes::Drawer - Common Barcode Drawer + +=head1 SYNOPSIS + +use C4::Barcodes::Drawer; + +C4::Barcodes::Drawer::draw_barcode(); + +=head1 FUNCTIONS + +=head2 draw_barcode() + + Invoking the I method generates a barcode for the label object and inserts it into the current pdf stream. This method accepts the following parameters as key => value + pairs (C is optional and omitting it will cause the barcode from the current item to be used. C is also optional. Omission results in the barcode + type of the current template being used.): + + C The lower-left x coordinate for the barcode block (The point of origin for all PDF's is the lower left of the page per ISO 32000-1) + C The lower-left y coordinate for the barcode block + C The width of the barcode block + C The scale factor to be applied to the y axis of the barcode block + C The data to be encoded in the barcode + C The barcode type (See the C method for supported barcode types) + + example: + C<$label->barcode( + llx => $barcode_llx, + lly => $barcode_lly, + width => $barcode_width, + y_scale_factor => $barcode_y_scale_factor, + barcode_data => $barcode, + barcode_type => $barcodetype, + );> + +=cut + +sub draw_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 $x_scale_factor = 1; + my $num_of_bars = length($params{'barcode_data'}); + my $tot_bar_length = 0; + my $bar_length = 0; + my $guard_length = 10; + my $hide_text = 'yes'; + if ($params{'barcode_type'} =~ m/CODE39/) { + $bar_length = '17.5'; + $tot_bar_length = ($bar_length * $num_of_bars) + ($guard_length * 2); + $x_scale_factor = ($params{'width'} / $tot_bar_length); + if ($params{'barcode_type'} eq 'CODE39MOD') { + my $c39 = CheckDigits('code_39'); # get modulo43 checksum + $params{'barcode_data'} = $c39->complete($params{'barcode_data'}); + } + elsif ($params{'barcode_type'} eq 'CODE39MOD10') { + my $c39_10 = CheckDigits('siret'); # get modulo43 checksum + $params{'barcode_data'} = $c39_10->complete($params{'barcode_data'}); + $hide_text = ''; + } + eval { + PDF::Reuse::Barcode::Code39( + x => $params{'llx'}, + y => $params{'lly'}, + value => "*$params{barcode_data}*", + xSize => $x_scale_factor, + ySize => $params{'y_scale_factor'}, + hide_asterisk => 1, + text => $hide_text, + mode => 'graphic', + ); + }; + if ($@) { + warn sprintf('Barcode generation failed for item %s with this error: %s', $self->{'item_number'}, $@); + } + } + elsif ($params{'barcode_type'} eq 'COOP2OF5') { + $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; + eval { + PDF::Reuse::Barcode::COOP2of5( + x => $params{'llx'}, + y => $params{'lly'}, + value => $params{barcode_data}, + xSize => $x_scale_factor, + ySize => $params{'y_scale_factor'}, + mode => 'graphic', + ); + }; + if ($@) { + warn sprintf('Barcode generation failed for item %s with this error: %s', $self->{'item_number'}, $@); + } + } + elsif ( $params{'barcode_type'} eq 'INDUSTRIAL2OF5' ) { + $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; + eval { + PDF::Reuse::Barcode::Industrial2of5( + x => $params{'llx'}, + y => $params{'lly'}, + value => $params{barcode_data}, + xSize => $x_scale_factor, + ySize => $params{'y_scale_factor'}, + mode => 'graphic', + ); + }; + if ($@) { + warn sprintf('Barcode generation failed for item %s with this error: %s', $self->{'item_number'}, $@); + } + } + elsif ($params{'barcode_type'} eq 'EAN13') { + $bar_length = 4; # FIXME + $num_of_bars = 13; + $tot_bar_length = ($bar_length * $num_of_bars) + ($guard_length * 2); + $x_scale_factor = ($params{'width'} / $tot_bar_length) * 0.9; + eval { + PDF::Reuse::Barcode::EAN13( + x => $params{'llx'}, + y => $params{'lly'}, + value => sprintf('%013d',$params{barcode_data}), +# xSize => $x_scale_factor, +# ySize => $params{'y_scale_factor'}, + mode => 'graphic', + ); + }; + if ($@) { + warn sprintf('Barcode generation failed for item %s with this error: %s', $self->{'item_number'}, $@); + } + } + else { + warn "unknown barcode_type: $params{barcode_type}"; + } +} + +1; diff --git a/C4/Labels/Label.pm b/C4/Labels/Label.pm index 1d6ea20e8b..7f06490262 100644 --- a/C4/Labels/Label.pm +++ b/C4/Labels/Label.pm @@ -14,6 +14,7 @@ use Koha::Biblios; use Koha::ClassSources; use Koha::ClassSortRules; use Koha::ClassSplitRules; +use C4::Barcodes::Drawer; use C4::ClassSplitRoutine::Dewey; use C4::ClassSplitRoutine::LCC; use C4::ClassSplitRoutine::Generic; @@ -353,11 +354,12 @@ sub create_label { ); } if ($self->{'printing_type'} =~ /BAR/) { - barcode( $self, + C4::Barcodes::Drawer::draw_barcode( $self, llx => $barcode_llx, lly => $barcode_lly, width => $barcode_width, y_scale_factor => $barcode_y_scale_factor, + barcode_data => $self->{'barcode'} || _get_label_item($self->{'item_number'}, 1), ); } return $label_text if $label_text; @@ -486,106 +488,6 @@ sub draw_guide_box { return $_[0]->{'guidebox'}; } -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 $x_scale_factor = 1; - my $num_of_bars = length($params{'barcode_data'}); - my $tot_bar_length = 0; - my $bar_length = 0; - my $guard_length = 10; - my $hide_text = 'yes'; - if ($params{'barcode_type'} =~ m/CODE39/) { - $bar_length = '17.5'; - $tot_bar_length = ($bar_length * $num_of_bars) + ($guard_length * 2); - $x_scale_factor = ($params{'width'} / $tot_bar_length); - if ($params{'barcode_type'} eq 'CODE39MOD') { - my $c39 = CheckDigits('code_39'); # get modulo43 checksum - $params{'barcode_data'} = $c39->complete($params{'barcode_data'}); - } - elsif ($params{'barcode_type'} eq 'CODE39MOD10') { - my $c39_10 = CheckDigits('siret'); # get modulo43 checksum - $params{'barcode_data'} = $c39_10->complete($params{'barcode_data'}); - $hide_text = ''; - } - eval { - PDF::Reuse::Barcode::Code39( - x => $params{'llx'}, - y => $params{'lly'}, - value => "*$params{barcode_data}*", - xSize => $x_scale_factor, - ySize => $params{'y_scale_factor'}, - hide_asterisk => 1, - text => $hide_text, - mode => 'graphic', - ); - }; - if ($@) { - warn sprintf('Barcode generation failed for item %s with this error: %s', $self->{'item_number'}, $@); - } - } - elsif ($params{'barcode_type'} eq 'COOP2OF5') { - $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; - eval { - PDF::Reuse::Barcode::COOP2of5( - x => $params{'llx'}, - y => $params{'lly'}, - value => $params{barcode_data}, - xSize => $x_scale_factor, - ySize => $params{'y_scale_factor'}, - mode => 'graphic', - ); - }; - if ($@) { - warn sprintf('Barcode generation failed for item %s with this error: %s', $self->{'item_number'}, $@); - } - } - elsif ( $params{'barcode_type'} eq 'INDUSTRIAL2OF5' ) { - $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; - eval { - PDF::Reuse::Barcode::Industrial2of5( - x => $params{'llx'}, - y => $params{'lly'}, - value => $params{barcode_data}, - xSize => $x_scale_factor, - ySize => $params{'y_scale_factor'}, - mode => 'graphic', - ); - }; - if ($@) { - warn sprintf('Barcode generation failed for item %s with this error: %s', $self->{'item_number'}, $@); - } - } - elsif ($params{'barcode_type'} eq 'EAN13') { - $bar_length = 4; # FIXME - $num_of_bars = 13; - $tot_bar_length = ($bar_length * $num_of_bars) + ($guard_length * 2); - $x_scale_factor = ($params{'width'} / $tot_bar_length) * 0.9; - eval { - PDF::Reuse::Barcode::EAN13( - x => $params{'llx'}, - y => $params{'lly'}, - value => sprintf('%013d',$params{barcode_data}), -# xSize => $x_scale_factor, -# ySize => $params{'y_scale_factor'}, - mode => 'graphic', - ); - }; - if ($@) { - warn sprintf('Barcode generation failed for item %s with this error: %s', $self->{'item_number'}, $@); - } - } - else { - warn "unknown barcode_type: $params{barcode_type}"; - } -} - sub csv_data { my $self = shift; my $label_fields = _get_text_fields($self->{'format_string'}); @@ -776,29 +678,6 @@ R = Right justify => $text_justification, );> -=head2 barcode() - - Invoking the I method generates a barcode for the label object and inserts it into the current pdf stream. This method accepts the following parameters as key => value - pairs (C is optional and omitting it will cause the barcode from the current item to be used. C is also optional. Omission results in the barcode - type of the current template being used.): - - C The lower-left x coordinate for the barcode block (The point of origin for all PDF's is the lower left of the page per ISO 32000-1) - C The lower-left y coordinate for the barcode block - C The width of the barcode block - C The scale factor to be applied to the y axis of the barcode block - C The data to be encoded in the barcode - C The barcode type (See the C method for supported barcode types) - - example: - C<$label->barcode( - llx => $barcode_llx, - lly => $barcode_lly, - width => $barcode_width, - y_scale_factor => $barcode_y_scale_factor, - barcode_data => $barcode, - barcode_type => $barcodetype, - );> - =head2 csv_data() Invoking the I method returns an arrayref of an array containing the label data suitable for passing to Text::CSV_XS->combine() to produce csv output. diff --git a/C4/Patroncards/Patroncard.pm b/C4/Patroncards/Patroncard.pm index ee5c73e352..c468334eef 100644 --- a/C4/Patroncards/Patroncard.pm +++ b/C4/Patroncards/Patroncard.pm @@ -23,6 +23,7 @@ use warnings; use autouse 'Data::Dumper' => qw(Dumper); #use Font::TTFMetrics; +use C4::Barcodes::Drawer; use C4::Creators::Lib qw( get_unit_values ); use C4::Creators::PDF qw(StrWidth); use C4::Patroncards::Lib qw( @@ -100,7 +101,7 @@ sub draw_barcode { my $llx_layout = $self->{'layout'}->{'barcode'}->[0]->{'llx'} || 0; my $lly = $self->{'lly'} || 0; my $lly_layout = $self->{'layout'}->{'barcode'}->[0]->{'lly'} || 0; - _draw_barcode( + C4::Barcodes::Drawer::draw_barcode( $self, llx => $llx + $llx_layout * $self->{'unitvalue'}, lly => $lly + $lly_layout * $self->{'unitvalue'}, @@ -378,89 +379,6 @@ sub draw_image { } } -=head2 draw_barcode - - $patron_card->draw_barcode($pdf) - -Draws a barcode to PDF output ($pdf) - -=cut - -sub _draw_barcode { # this is cut-and-paste from Label.pm because there is no common place for it atm... - my $self = shift; - my %params = @_; - - my $x_scale_factor = 1; - my $num_of_chars = length($params{'barcode_data'}); - my $tot_bar_length = 0; - my $bar_length = 0; - my $guard_length = 10; - if ($params{'barcode_type'} =~ m/CODE39/) { - $bar_length = '17.5'; - $tot_bar_length = ($bar_length * $num_of_chars) + ($guard_length * 2); # not sure what all is going on here and on the next line; this is old (very) code - $x_scale_factor = ($params{'width'} / $tot_bar_length); - if ($params{'barcode_type'} eq 'CODE39MOD') { - my $c39 = CheckDigits('code_39'); # get modulo 43 checksum - $params{'barcode_data'} = $c39->complete($params{'barcode_data'}); - } - elsif ($params{'barcode_type'} eq 'CODE39MOD10') { - my $c39_10 = CheckDigits('siret'); # get modulo 10 checksum - $params{'barcode_data'} = $c39_10->complete($params{'barcode_data'}); - } - eval { - PDF::Reuse::Barcode::Code39( - x => $params{'llx'}, - y => $params{'lly'}, - value => "*$params{barcode_data}*", - xSize => $x_scale_factor, - ySize => $params{'y_scale_factor'}, - hide_asterisk => 1, - text => $params{'text'}, - mode => 'graphic', - ); - }; - if ($@) { - warn sprintf('Barcode generation failed for item %s with this error: %s', $self->{'item_number'}, $@); - } - } - elsif ($params{'barcode_type'} eq 'COOP2OF5') { - $bar_length = '9.43333333333333'; - $tot_bar_length = ($bar_length * $num_of_chars) + ($guard_length * 2); - $x_scale_factor = ($params{'width'} / $tot_bar_length) * 0.9; - eval { - PDF::Reuse::Barcode::COOP2of5( - x => $params{'llx'}, - y => $params{'lly'}, - value => $params{barcode_data}, - xSize => $x_scale_factor, - ySize => $params{'y_scale_factor'}, - mode => 'graphic', - ); - }; - if ($@) { - warn sprintf('Barcode generation failed for item %s with this error: %s', $self->{'item_number'}, $@); - } - } - elsif ( $params{'barcode_type'} eq 'INDUSTRIAL2OF5' ) { - $bar_length = '13.1333333333333'; - $tot_bar_length = ($bar_length * $num_of_chars) + ($guard_length * 2); - $x_scale_factor = ($params{'width'} / $tot_bar_length) * 0.9; - eval { - PDF::Reuse::Barcode::Industrial2of5( - x => $params{'llx'}, - y => $params{'lly'}, - value => $params{barcode_data}, - xSize => $x_scale_factor, - ySize => $params{'y_scale_factor'}, - mode => 'graphic', - ); - }; - if ($@) { - warn sprintf('Barcode generation failed for item %s with this error: %s', $self->{'item_number'}, $@); - } - } -} - 1; __END__ -- 2.45.2.windows.1