3 # Copyright 2006 Katipo Communications.
5 # This file is part of Koha.
7 # Koha is free software; you can redistribute it and/or modify it under the
8 # terms of the GNU General Public License as published by the Free Software
9 # Foundation; either version 2 of the License, or (at your option) any later
12 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License along with
17 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
18 # Suite 330, Boston, MA 02111-1307 USA
21 use vars qw($VERSION @ISA @EXPORT);
25 use Algorithm::CheckDigits;
27 # use Smart::Comments;
34 &get_label_options &get_label_items
35 &build_circ_barcode &draw_boundaries
36 &drawbox &GetActiveLabelTemplate
37 &GetAllLabelTemplates &DeleteTemplate
38 &GetSingleLabelTemplate &SaveTemplate
39 &CreateTemplate &SetActiveTemplate
40 &SaveConf &DrawSpineText &GetTextWrapCols
41 &GetUnitsValue &DrawBarcode
45 &get_batches &delete_batch
46 &add_batch &SetFontSize &printText
49 get_layout &save_layout &add_layout
50 &set_active_layout &by_order
52 &delete_layout &get_active_layout
60 C4::Labels - Functions for printing spine labels and barcodes in Koha
66 =item get_label_options;
68 $options = get_label_options()
70 Return a pointer on a hash list containing info from labels_conf table in Koha DB.
75 sub get_label_options {
76 my $dbh = C4::Context->dbh;
77 my $query2 = " SELECT * FROM labels_conf where active = 1";
78 my $sth = $dbh->prepare($query2);
80 my $conf_data = $sth->fetchrow_hashref;
87 ## FIXME: this if/else could be compacted...
88 my $dbh = C4::Context->dbh;
90 my $query = " Select * from labels_conf";
91 my $sth = $dbh->prepare($query);
94 while ( my $data = $sth->fetchrow_hashref ) {
96 $data->{'fieldlist'} = get_text_fields( $data->{'id'} );
97 push( @resultsloop, $data );
107 my ($layout_id) = @_;
108 my $dbh = C4::Context->dbh;
110 # get the actual items to be printed.
111 my $query = " Select * from labels_conf where id = ?";
112 my $sth = $dbh->prepare($query);
113 $sth->execute($layout_id);
114 my $data = $sth->fetchrow_hashref;
119 sub get_active_layout {
120 my ($layout_id) = @_;
121 my $dbh = C4::Context->dbh;
123 # get the actual items to be printed.
124 my $query = " Select * from labels_conf where active = 1";
125 my $sth = $dbh->prepare($query);
127 my $data = $sth->fetchrow_hashref;
133 my ($layout_id) = @_;
134 my $dbh = C4::Context->dbh;
136 # get the actual items to be printed.
137 my $query = "delete from labels_conf where id = ?";
138 my $sth = $dbh->prepare($query);
139 $sth->execute($layout_id);
143 sub get_printingtypes {
144 my ($layout_id) = @_;
147 push( @printtypes, { code => 'BAR', desc => "barcode" } );
148 push( @printtypes, { code => 'BIB', desc => "biblio" } );
149 push( @printtypes, { code => 'BARBIB', desc => "barcode / biblio" } );
150 push( @printtypes, { code => 'BIBBAR', desc => "biblio / barcode" } );
151 push( @printtypes, { code => 'ALT', desc => "alternating labels" } );
153 my $conf = get_layout($layout_id);
154 my $active_printtype = $conf->{'printingtype'};
156 # lop thru layout, insert selected to hash
158 foreach my $printtype (@printtypes) {
159 if ( $printtype->{'code'} eq $active_printtype ) {
160 $printtype->{'active'} = 'MOO';
166 sub build_text_dropbox {
169 # my @fields = get_text_fields();
170 # my $field_count = scalar @fields;
171 my $field_count = 10; # <----------- FIXME hard coded
175 ? push( @lines, { num => '', selected => '1' } )
176 : push( @lines, { num => '' } );
177 for ( my $i = 1 ; $i <= $field_count ; $i++ ) {
178 my $line = { num => "$i" };
179 $line->{'selected'} = 1 if $i eq $order;
180 push( @lines, $line );
183 # add a blank row too
188 sub get_text_fields {
189 my ($layout_id, $sorttype) = @_;
191 my ( $a, $b, $c, $d, $e, $f, $g, $h, $i ,$j, $k );
193 my $sortorder = get_layout($layout_id);
200 order => $sortorder->{'itemtype'}
205 order => $sortorder->{'dewey'}
207 $c = { code => 'issn', desc => "ISSN",
208 order => $sortorder->{'issn'} };
209 $d = { code => 'isbn', desc => "ISBN",
210 order => $sortorder->{'isbn'} };
213 desc => "Classification",
214 order => $sortorder->{'class'}
219 order => $sortorder->{'subclass'}
224 order => $sortorder->{'barcode'}
227 { code => 'author', desc => "Author", order => $sortorder->{'author'} };
228 $i = { code => 'title', desc => "Title", order => $sortorder->{'title'} };
229 $j = { code => 'itemcallnumber', desc => "Call Number", order => $sortorder->{'itemcallnumber'} };
230 $k = { code => 'subtitle', desc => "Subtitle", order => $sortorder->{'subtitle'} };
232 my @text_fields = ( $a, $b, $c, $d, $e, $f, $g, $h, $i ,$j, $k );
235 foreach my $field (@text_fields) {
236 push( @new_fields, $field ) if $field->{'order'} > 0;
239 my @sorted_fields = sort by_order @new_fields;
241 foreach my $field (@sorted_fields) {
242 $sorttype eq 'codes' ? $active_fields .= "$field->{'code'} " :
243 $active_fields .= "$field->{'desc'} ";
245 return $active_fields;
250 $$a{order} <=> $$b{order};
255 my $dbh = C4::Context->dbh;
257 "select distinct batch_id from labels order by batch_id desc limit 1";
258 my $sth = $dbh->prepare($q);
260 my $data = $sth->fetchrow_hashref;
263 if ( !$data->{'batch_id'} ) {
267 $new_batch = ( $data->{'batch_id'} + 1 );
274 sub get_highest_batch {
276 my $dbh = C4::Context->dbh;
278 "select distinct batch_id from labels order by batch_id desc limit 1";
279 my $sth = $dbh->prepare($q);
281 my $data = $sth->fetchrow_hashref;
284 if ( !$data->{'batch_id'} ) {
288 $new_batch = $data->{'batch_id'};
296 my $dbh = C4::Context->dbh;
297 my $q = "select batch_id, count(*) as num from labels group by batch_id";
298 my $sth = $dbh->prepare($q);
301 while ( my $data = $sth->fetchrow_hashref ) {
302 push( @resultsloop, $data );
306 # adding a dummy batch=1 value , if none exists in the db
307 if ( !scalar(@resultsloop) ) {
308 push( @resultsloop, { batch_id => '1' , num => '0' } );
315 my $dbh = C4::Context->dbh;
316 my $q = "DELETE FROM labels where batch_id = ?";
317 my $sth = $dbh->prepare($q);
318 $sth->execute($batch_id);
322 sub get_barcode_types {
323 my ($layout_id) = @_;
324 my $layout = get_layout($layout_id);
325 my $barcode = $layout->{'barcodetype'};
328 push( @array, { code => 'CODE39', desc => 'Code 39' } );
329 push( @array, { code => 'CODE39MOD', desc => 'Code39 + Modulo43' } );
330 push( @array, { code => 'CODE39MOD10', desc => 'Code39 + Modulo10' } );
331 push( @array, { code => 'ITF', desc => 'Interleaved 2 of 5' } );
333 foreach my $line (@array) {
334 if ( $line->{'code'} eq $barcode ) {
335 $line->{'active'} = 1;
346 $unitvalue = '1' if ( $units eq 'POINT' );
347 $unitvalue = '2.83464567' if ( $units eq 'MM' );
348 $unitvalue = '28.3464567' if ( $units eq 'CM' );
349 $unitvalue = 72 if ( $units eq 'INCH' );
353 sub GetTextWrapCols {
354 my ( $fontsize, $label_width ) = @_;
356 my $left_text_margin = 3;
357 my ( $strtmp, $strwidth );
359 my $textlimit = $label_width - $left_text_margin;
361 while ( $strwidth < $textlimit ) {
362 $strwidth = prStrWidth( $string, 'C', $fontsize );
363 $string = $string . '0';
365 # warn "strwidth $strwidth, $textlimit, $string";
371 sub GetActiveLabelTemplate {
372 my $dbh = C4::Context->dbh;
373 my $query = " SELECT * FROM labels_templates where active = 1 limit 1";
374 my $sth = $dbh->prepare($query);
376 my $active_tmpl = $sth->fetchrow_hashref;
381 sub GetSingleLabelTemplate {
383 my $dbh = C4::Context->dbh;
384 my $query = " SELECT * FROM labels_templates where tmpl_id = ?";
385 my $sth = $dbh->prepare($query);
386 $sth->execute($tmpl_id);
387 my $template = $sth->fetchrow_hashref;
392 sub SetActiveTemplate {
396 my $dbh = C4::Context->dbh;
397 my $query = " UPDATE labels_templates SET active = NULL";
398 my $sth = $dbh->prepare($query);
401 $query = "UPDATE labels_templates SET active = 1 WHERE tmpl_id = ?";
402 $sth = $dbh->prepare($query);
403 $sth->execute($tmpl_id);
407 sub set_active_layout {
409 my ($layout_id) = @_;
410 my $dbh = C4::Context->dbh;
411 my $query = " UPDATE labels_conf SET active = NULL";
412 my $sth = $dbh->prepare($query);
415 $query = "UPDATE labels_conf SET active = 1 WHERE id = ?";
416 $sth = $dbh->prepare($query);
417 $sth->execute($layout_id);
423 my $dbh = C4::Context->dbh;
424 my $query = " DELETE FROM labels_templates where tmpl_id = ?";
425 my $sth = $dbh->prepare($query);
426 $sth->execute($tmpl_id);
432 $tmpl_id, $tmpl_code, $tmpl_desc, $page_width,
433 $page_height, $label_width, $label_height, $topmargin,
434 $leftmargin, $cols, $rows, $colgap,
435 $rowgap, $fontsize, $units
437 my $dbh = C4::Context->dbh;
439 " UPDATE labels_templates SET tmpl_code=?, tmpl_desc=?, page_width=?,
440 page_height=?, label_width=?, label_height=?, topmargin=?,
441 leftmargin=?, cols=?, rows=?, colgap=?, rowgap=?, fontsize=?,
445 my $sth = $dbh->prepare($query);
447 $tmpl_code, $tmpl_desc, $page_width, $page_height,
448 $label_width, $label_height, $topmargin, $leftmargin,
449 $cols, $rows, $colgap, $rowgap,
450 $fontsize, $units, $tmpl_id
458 $tmpl_code, $tmpl_desc, $page_width, $page_height,
459 $label_width, $label_height, $topmargin, $leftmargin,
460 $cols, $rows, $colgap, $rowgap,
464 my $dbh = C4::Context->dbh;
466 my $query = "INSERT INTO labels_templates (tmpl_code, tmpl_desc, page_width,
467 page_height, label_width, label_height, topmargin,
468 leftmargin, cols, rows, colgap, rowgap, fontsize, units)
469 VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
471 my $sth = $dbh->prepare($query);
473 $tmpl_code, $tmpl_desc, $page_width, $page_height,
474 $label_width, $label_height, $topmargin, $leftmargin,
475 $cols, $rows, $colgap, $rowgap,
480 sub GetAllLabelTemplates {
481 my $dbh = C4::Context->dbh;
483 # get the actual items to be printed.
485 my $query = " Select * from labels_templates ";
486 my $sth = $dbh->prepare($query);
489 while ( my $data = $sth->fetchrow_hashref ) {
490 push( @resultsloop, $data );
494 #warn Dumper @resultsloop;
502 $barcodetype, $title, $subtitle, $isbn, $issn,
503 $itemtype, $bcn, $dcn, $classif,
504 $subclass, $itemcallnumber, $author, $tmpl_id,
505 $printingtype, $guidebox, $startlabel, $layoutname
508 my $dbh = C4::Context->dbh;
509 my $query2 = "update labels_conf set active = NULL";
510 my $sth2 = $dbh->prepare($query2);
512 $query2 = "INSERT INTO labels_conf
513 ( barcodetype, title, subtitle, isbn,issn, itemtype, barcode,
514 dewey, class, subclass, itemcallnumber, author, printingtype,
515 guidebox, startlabel, layoutname, active )
516 values ( ?, ?, ?, ?, ?, ?, ?, ?,?, ?, ?, ?, ?, ?,?,?, 1 )";
517 $sth2 = $dbh->prepare($query2);
519 $barcodetype, $title, $subtitle, $isbn, $issn,
521 $itemtype, $bcn, $dcn, $classif,
522 $subclass, $itemcallnumber, $author, $printingtype,
523 $guidebox, $startlabel, $layoutname
527 SetActiveTemplate($tmpl_id);
534 $barcodetype, $title, $subtitle, $isbn, $issn,
535 $itemtype, $bcn, $dcn, $classif,
536 $subclass, $itemcallnumber, $author, $tmpl_id,
537 $printingtype, $guidebox, $startlabel, $layoutname,
543 my $dbh = C4::Context->dbh;
544 my $query2 = "update labels_conf set
545 barcodetype=?, title=?, subtitle=?, isbn=?,issn=?,
546 itemtype=?, barcode=?, dewey=?, class=?,
547 subclass=?, itemcallnumber=?, author=?, printingtype=?,
548 guidebox=?, startlabel=?, layoutname=? where id = ?";
549 my $sth2 = $dbh->prepare($query2);
551 $barcodetype, $title, $subtitle, $isbn, $issn,
552 $itemtype, $bcn, $dcn, $classif,
553 $subclass, $itemcallnumber, $author, $printingtype,
554 $guidebox, $startlabel, $layoutname, $layout_id
561 =item get_label_items;
563 $options = get_label_items()
565 Returns an array of references-to-hash, whos keys are the field from the biblio, biblioitems, items and labels tables in the Koha database.
570 sub get_label_items {
572 my $dbh = C4::Context->dbh;
574 my @resultsloop = ();
580 my $query3 = "Select * from labels where batch_id = ? order by labelid ";
581 $sth = $dbh->prepare($query3);
582 $sth->execute($batch_id);
587 my $query3 = "Select * from labels";
588 $sth = $dbh->prepare($query3);
591 my $cnt = $sth->rows;
593 while ( my $data = $sth->fetchrow_hashref ) {
595 # lets get some summary info from each item
597 select i.*, bi.*, b.* from items i,biblioitems bi,biblio b
598 where itemnumber=? and i.biblioitemnumber=bi.biblioitemnumber and
599 bi.biblionumber=b.biblionumber";
601 my $sth1 = $dbh->prepare($query1);
602 $sth1->execute( $data->{'itemnumber'} );
604 my $data1 = $sth1->fetchrow_hashref();
605 $data1->{'labelno'} = $i1;
606 $data1->{'labelid'} = $data->{'labelid'};
607 $data1->{'batch_id'} = $batch_id;
608 $data1->{'summary'} =
609 "$data1->{'barcode'}, $data1->{'title'}, $data1->{'isbn'}";
611 push( @resultsloop, $data1 );
623 barcode title subtitle
624 dewey isbn issn author class
625 itemtype subclass itemcallnumber
631 sub deduplicate_batch {
632 my $batch_id = shift or return undef;
636 count(labelid) as count
639 GROUP BY itemnumber,batch_id
643 my $sth = C4::Context->dbh->prepare($query);
644 $sth->execute($batch_id);
645 $sth->rows or return undef;
652 ORDER BY timestamp ASC
655 while (my $data = $sth->fetchrow_hashref()) {
656 my $itemnumber = $data->{itemnumber} or next;
657 my $limit = $data->{count} - 1 or next;
658 my $sth2 = C4::Context->dbh->prepare("$del_query LIMIT $limit");
659 # die sprintf "$del_query LIMIT %s\n (%s, %s)", $limit, $batch_id, $itemnumber;
660 # $sth2->execute($batch_id, C4::Context->dbh->quote($data->{itemnumber}), $data->{count} - 1)
661 $sth2->execute($batch_id, $itemnumber) and
662 $killed += ($data->{count} - 1);
669 my ( $y_pos, $label_height, $fontsize, $x_pos, $left_text_margin,
670 $text_wrap_cols, $item, $conf_data )
672 # hack to fix column name mismatch betwen labels_conf.class, and bibitems.classification
673 $$item->{'class'} = $$item->{'classification'};
675 $Text::Wrap::columns = $text_wrap_cols;
676 $Text::Wrap::separator = "\n";
681 my $top_text_margin = ( $fontsize + 3 );
682 my $line_spacer = ($fontsize); # number of pixels between text rows.
684 # add your printable fields manually in here
686 my $layout_id = $$conf_data->{'id'};
688 # my @fields = GetItemFields();
690 my $str_fields = get_text_fields($layout_id, 'codes' );
691 my @fields = split(/ /, $str_fields);
694 my $vPos = ( $y_pos + ( $label_height - $top_text_margin ) );
695 my $hPos = ( $x_pos + $left_text_margin );
697 # warn Dumper $conf_data;
700 foreach my $field (@fields) {
703 # $$item->{"$field"} = $field . ": " . $$item->{"$field"};
705 # if the display option for this field is selected in the DB,
706 # and the item record has some values for this field, display it.
707 if ( $$conf_data->{"$field"} && $$item->{"$field"} ) {
709 # warn "CONF_TYPE = $field";
712 $str = $$item->{"$field"};
713 # strip out naughty existing nl/cr's
717 # chop the string up into _upto_ 12 chunks
718 # and seperate the chunks with newlines
720 $str = wrap( "", "", "$str" );
721 $str = wrap( "", "", "$str" );
723 # split the chunks between newline's, into an array
724 my @strings = split /\n/, $str;
726 # then loop for each string line
727 foreach my $str (@strings) {
729 #warn "HPOS , VPOS $hPos, $vPos ";
730 # set the font size A
732 # prText( $hPos, $vPos, $str );
733 PrintText( $hPos, $vPos, $fontsize, $str );
734 $vPos = $vPos - $line_spacer;
736 } # if field is } #foreach feild
741 my ( $hPos, $vPos, $fontsize, $text ) = @_;
742 my $str = "BT /Ft1 $fontsize Tf $hPos $vPos Td ($text) Tj ET";
750 my $str = "BT/F13 30 Tf288 720 Td( AAAAAAAAAA ) TjET";
756 # x and y are from the top-left :)
757 my ( $x_pos, $y_pos, $height, $width, $barcode, $barcodetype ) = @_;
758 my $num_of_bars = length($barcode);
759 my $bar_width = $width * .8; # %80 of length of label width
762 my $guard_length = 10;
765 if ( $barcodetype eq 'CODE39' ) {
766 $bar_length = '17.5';
768 ( $bar_length * $num_of_bars ) + ( $guard_length * 2 );
769 $xsize_ratio = ( $bar_width / $tot_bar_length );
771 PDF::Reuse::Barcode::Code39(
772 x => ( $x_pos + ( $width / 10 ) ),
773 y => ( $y_pos + ( $height / 10 ) ),
774 value => "*$barcode*",
775 ySize => ( .02 * $height ),
776 xSize => $xsize_ratio,
781 warn "$barcodetype, $barcode FAILED:$@";
785 elsif ( $barcodetype eq 'CODE39MOD' ) {
787 # get modulo43 checksum
788 my $c39 = CheckDigits('code_39');
789 $barcode = $c39->complete($barcode);
793 ( $bar_length * $num_of_bars ) + ( $guard_length * 2 );
794 $xsize_ratio = ( $bar_width / $tot_bar_length );
796 PDF::Reuse::Barcode::Code39(
797 x => ( $x_pos + ( $width / 10 ) ),
798 y => ( $y_pos + ( $height / 10 ) ),
799 value => "*$barcode*",
800 ySize => ( .02 * $height ),
801 xSize => $xsize_ratio,
807 warn "$barcodetype, $barcode FAILED:$@";
810 elsif ( $barcodetype eq 'CODE39MOD10' ) {
812 # get modulo43 checksum
813 my $c39_10 = CheckDigits('visa');
814 $barcode = $c39_10->complete($barcode);
818 ( $bar_length * $num_of_bars ) + ( $guard_length * 2 );
819 $xsize_ratio = ( $bar_width / $tot_bar_length );
821 PDF::Reuse::Barcode::Code39(
822 x => ( $x_pos + ( $width / 10 ) ),
823 y => ( $y_pos + ( $height / 10 ) ),
824 value => "*$barcode*",
825 ySize => ( .02 * $height ),
826 xSize => $xsize_ratio,
833 warn "$barcodetype, $barcode FAILED:$@";
838 elsif ( $barcodetype eq 'COOP2OF5' ) {
839 $bar_length = '9.43333333333333';
841 ( $bar_length * $num_of_bars ) + ( $guard_length * 2 );
842 $xsize_ratio = ( $bar_width / $tot_bar_length ) * .9;
844 PDF::Reuse::Barcode::COOP2of5(
845 x => ( $x_pos + ( $width / 10 ) ),
846 y => ( $y_pos + ( $height / 10 ) ),
848 ySize => ( .02 * $height ),
849 xSize => $xsize_ratio,
853 warn "$barcodetype, $barcode FAILED:$@";
857 elsif ( $barcodetype eq 'INDUSTRIAL2OF5' ) {
858 $bar_length = '13.1333333333333';
860 ( $bar_length * $num_of_bars ) + ( $guard_length * 2 );
861 $xsize_ratio = ( $bar_width / $tot_bar_length ) * .9;
863 PDF::Reuse::Barcode::Industrial2of5(
864 x => ( $x_pos + ( $width / 10 ) ),
865 y => ( $y_pos + ( $height / 10 ) ),
867 ySize => ( .02 * $height ),
868 xSize => $xsize_ratio,
872 warn "$barcodetype, $barcode FAILED:$@";
876 my $moo2 = $tot_bar_length * $xsize_ratio;
878 warn " $x_pos, $y_pos, $barcode, $barcodetype\n";
880 "BAR_WDTH = $bar_width, TOT.BAR.LGHT=$tot_bar_length R*TOT.BAR =$moo2 \n";
883 =item build_circ_barcode;
885 build_circ_barcode( $x_pos, $y_pos, $barcode,
886 $barcodetype, \$item);
888 $item is the result of a previous call to get_label_items();
893 sub build_circ_barcode {
894 my ( $x_pos_circ, $y_pos, $value, $barcodetype, $item ) = @_;
898 #warn "value = $value\n";
902 if ( $barcodetype eq 'EAN13' ) {
904 #testing EAN13 barcodes hack
905 $value = $value . '000000000';
907 $value = substr( $value, 0, 12 );
911 PDF::Reuse::Barcode::EAN13(
912 x => ( $x_pos_circ + 27 ),
913 y => ( $y_pos + 15 ),
921 # added for xpdf compat. doesnt use type3 fonts., but increases filesize from 20k to 200k
922 # i think its embedding extra fonts in the pdf file.
927 $item->{'barcodeerror'} = 1;
929 #warn "EAN13BARCODE FAILED:$@";
935 elsif ( $barcodetype eq 'Code39' ) {
938 PDF::Reuse::Barcode::Code39(
939 x => ( $x_pos_circ + 9 ),
940 y => ( $y_pos + 15 ),
950 $item->{'barcodeerror'} = 1;
952 #warn "CODE39BARCODE $value FAILED:$@";
959 elsif ( $barcodetype eq 'Matrix2of5' ) {
961 #warn "MATRIX ELSE:";
963 #testing MATRIX25 barcodes hack
964 # $value = $value.'000000000';
967 # $value = substr( $value, 0, 12 );
971 PDF::Reuse::Barcode::Matrix2of5(
972 x => ( $x_pos_circ + 27 ),
973 y => ( $y_pos + 15 ),
983 $item->{'barcodeerror'} = 1;
985 #warn "BARCODE FAILED:$@";
992 elsif ( $barcodetype eq 'EAN8' ) {
994 #testing ean8 barcodes hack
995 $value = $value . '000000000';
997 $value = substr( $value, 0, 8 );
1001 #warn "EAN8 ELSEIF";
1003 PDF::Reuse::Barcode::EAN8(
1004 x => ( $x_pos_circ + 42 ),
1005 y => ( $y_pos + 15 ),
1015 $item->{'barcodeerror'} = 1;
1017 #warn "BARCODE FAILED:$@";
1024 elsif ( $barcodetype eq 'UPC-E' ) {
1026 PDF::Reuse::Barcode::UPCE(
1027 x => ( $x_pos_circ + 27 ),
1028 y => ( $y_pos + 15 ),
1038 $item->{'barcodeerror'} = 1;
1040 #warn "BARCODE FAILED:$@";
1046 elsif ( $barcodetype eq 'NW7' ) {
1048 PDF::Reuse::Barcode::NW7(
1049 x => ( $x_pos_circ + 27 ),
1050 y => ( $y_pos + 15 ),
1060 $item->{'barcodeerror'} = 1;
1062 #warn "BARCODE FAILED:$@";
1068 elsif ( $barcodetype eq 'ITF' ) {
1070 PDF::Reuse::Barcode::ITF(
1071 x => ( $x_pos_circ + 27 ),
1072 y => ( $y_pos + 15 ),
1082 $item->{'barcodeerror'} = 1;
1084 #warn "BARCODE FAILED:$@";
1090 elsif ( $barcodetype eq 'Industrial2of5' ) {
1092 PDF::Reuse::Barcode::Industrial2of5(
1093 x => ( $x_pos_circ + 27 ),
1094 y => ( $y_pos + 15 ),
1103 $item->{'barcodeerror'} = 1;
1105 #warn "BARCODE FAILED:$@";
1111 elsif ( $barcodetype eq 'IATA2of5' ) {
1113 PDF::Reuse::Barcode::IATA2of5(
1114 x => ( $x_pos_circ + 27 ),
1115 y => ( $y_pos + 15 ),
1124 $item->{'barcodeerror'} = 1;
1126 #warn "BARCODE FAILED:$@";
1133 elsif ( $barcodetype eq 'COOP2of5' ) {
1135 PDF::Reuse::Barcode::COOP2of5(
1136 x => ( $x_pos_circ + 27 ),
1137 y => ( $y_pos + 15 ),
1146 $item->{'barcodeerror'} = 1;
1148 #warn "BARCODE FAILED:$@";
1154 elsif ( $barcodetype eq 'UPC-A' ) {
1157 PDF::Reuse::Barcode::UPCA(
1158 x => ( $x_pos_circ + 27 ),
1159 y => ( $y_pos + 15 ),
1168 $item->{'barcodeerror'} = 1;
1170 #warn "BARCODE FAILED:$@";
1179 =item draw_boundaries
1181 sub draw_boundaries ($x_pos_spine, $x_pos_circ1, $x_pos_circ2,
1182 $y_pos, $spine_width, $label_height, $circ_width)
1184 This sub draws boundary lines where the label outlines are, to aid in printer testing, and debugging.
1189 sub draw_boundaries {
1192 $x_pos_spine, $x_pos_circ1, $x_pos_circ2, $y_pos,
1193 $spine_width, $label_height, $circ_width
1196 my $y_pos_initial = ( ( 792 - 36 ) - 90 );
1197 $y_pos = $y_pos_initial; # FIXME - why are we ignoring the y_pos parameter by redefining it?
1200 for ( $i = 1 ; $i <= 8 ; $i++ ) {
1202 &drawbox( $x_pos_spine, $y_pos, ($spine_width), ($label_height) );
1204 #warn "OLD BOXES x=$x_pos_spine, y=$y_pos, w=$spine_width, h=$label_height";
1205 &drawbox( $x_pos_circ1, $y_pos, ($circ_width), ($label_height) );
1206 &drawbox( $x_pos_circ2, $y_pos, ($circ_width), ($label_height) );
1208 $y_pos = ( $y_pos - $label_height );
1215 sub drawbox { $lower_left_x, $lower_left_y,
1216 $upper_right_x, $upper_right_y )
1218 this is a low level sub, that draws a pdf box, it is called by draw_boxes
1220 FYI: the $upper_right_x and $upper_right_y values are RELATIVE to $lower_left_x and $lower_left_y
1222 and $lower_left_x, $lower_left_y are ABSOLUTE, this caught me out!
1228 my ( $llx, $lly, $urx, $ury ) = @_;
1230 # warn "llx,y= $llx,$lly , urx,y=$urx,$ury \n";
1232 my $str = "q\n"; # save the graphic state
1233 $str .= "0.5 w\n"; # border color red
1234 $str .= "1.0 0.0 0.0 RG\n"; # border color red
1235 # $str .= "0.5 0.75 1.0 rg\n"; # fill color blue
1236 $str .= "1.0 1.0 1.0 rg\n"; # fill color white
1238 $str .= "$llx $lly $urx $ury re\n"; # a rectangle
1239 $str .= "B\n"; # fill (and a little more)
1240 $str .= "Q\n"; # save the graphic state
1246 END { } # module clean-up code here (global destructor)
1255 Mason James <mason@katipo.co.nz>