1 package C4
::Labels
::Label
;
7 use Algorithm
::CheckDigits
;
10 use Library
::CallNumber
::LC
;
11 use Text
::Bidi
qw( log2vis );
18 my $possible_decimal = qr/\d{3,}(?:\.\d+)?/; # at least three digits for a DDCN
21 my $given_params = {};
23 my @valid_label_params = (
46 foreach my $key (keys %{$given_params}) {
47 if (!(grep m/$key/, @valid_label_params)) {
48 warn sprintf('Unrecognized parameter type of "%s".', $key);
54 if (!(grep m/$_/, @valid_label_params)) {
55 warn sprintf('Unrecognized parameter type of "%s".', $_);
63 my ( $llx, $lly, $width, $height ) = @_;
64 return unless ( defined $llx and defined $lly and
65 defined $width and defined $height );
66 my $obj_stream = "q\n"; # save the graphic state
67 $obj_stream .= "0.5 w\n"; # border line width
68 $obj_stream .= "1.0 0.0 0.0 RG\n"; # border color red
69 $obj_stream .= "1.0 1.0 1.0 rg\n"; # fill color white
70 $obj_stream .= "$llx $lly $width $height re\n"; # a rectangle
71 $obj_stream .= "B\n"; # fill (and a little more)
72 $obj_stream .= "Q\n"; # restore the graphic state
77 my $item_number = shift;
78 my $barcode_only = shift || 0;
79 my $dbh = C4
::Context
->dbh;
80 # FIXME This makes for a very bulky data structure; data from tables w/duplicate col names also gets overwritten.
81 # Something like this, perhaps, but this also causes problems because we need more fields sometimes.
82 # SELECT i.barcode, i.itemcallnumber, i.itype, bi.isbn, bi.issn, b.title, b.author
83 my $sth = $dbh->prepare("SELECT bi.*, i.*, b.*,br.* FROM items AS i, biblioitems AS bi ,biblio AS b, branches AS br WHERE itemnumber=? AND i.biblioitemnumber=bi.biblioitemnumber AND bi.biblionumber=b.biblionumber AND i.homebranch=br.branchcode;");
84 $sth->execute($item_number);
86 warn sprintf('Database returned the following error: %s', $sth->errstr);
88 my $data = $sth->fetchrow_hashref;
89 # Replaced item's itemtype with the more user-friendly description...
90 my $sth1 = $dbh->prepare("SELECT itemtype,description FROM itemtypes WHERE itemtype = ?");
91 $sth1->execute($data->{'itemtype'});
93 warn sprintf('Database returned the following error: %s', $sth1->errstr);
95 my $data1 = $sth1->fetchrow_hashref;
96 $data->{'itemtype'} = $data1->{'description'};
97 $data->{'itype'} = $data1->{'description'};
98 # add *_description fields
99 if ($data->{'homebranch'} || $data->{'holdingbranch'}){
101 $data->{'homebranch_description'} = C4
::Branch
::GetBranchName
($data->{'homebranch'}) if $data->{'homebranch'};
102 $data->{'holdingbranch_description'} = C4
::Branch
::GetBranchName
($data->{'holdingbranch'}) if $data->{'holdingbranch'};
104 $data->{'ccode_description'} = C4
::Biblio
::GetAuthorisedValueDesc
('','', $data->{'ccode'} ,'','','CCODE', 1) if $data->{'ccode'};
105 $data->{'location_description'} = C4
::Biblio
::GetAuthorisedValueDesc
('','', $data->{'location'} ,'','','LOC', 1) if $data->{'location'};
106 $data->{'permanent_location_description'} = C4
::Biblio
::GetAuthorisedValueDesc
('','', $data->{'permanent_location'} ,'','','LOC', 1) if $data->{'permanent_location'};
108 $barcode_only ?
return $data->{'barcode'} : return $data;
111 sub _get_text_fields
{
112 my $format_string = shift;
113 my $csv = Text
::CSV_XS
->new({allow_whitespace
=> 1});
114 my $status = $csv->parse($format_string);
115 my @sorted_fields = map {{ 'code' => $_, desc
=> $_ }}
116 map { $_ && $_ eq 'callnumber' ?
'itemcallnumber' : $_ } # see bug 5653
118 my $error = $csv->error_input();
119 warn sprintf('Text field sort failed with this error: %s', $error) if $error;
120 return \
@sorted_fields;
127 # lccn examples: 'HE8700.7 .P6T44 1983', 'BS2545.E8 H39 1996';
128 my @parts = Library
::CallNumber
::LC
->new($lccn)->components();
129 unless (scalar @parts && defined $parts[0]) {
130 $debug and warn sprintf('regexp failed to match string: %s', $_);
131 @parts = $_; # if no match, just use the whole string.
133 my $LastPiece = pop @parts;
134 push @parts, split /\s+/, $LastPiece if $LastPiece; # split the last piece into an arbitrary number of pieces at spaces
135 $debug and warn "split_lccn array: ", join(" | ", @parts), "\n";
142 s/\///g
; # in theory we should be able to simply remove all segmentation markers and arrive at the correct call number...
144 ^([-a
-zA
-Z
]*\s?
(?
:$possible_decimal)?
) # R220.3 CD-ROM 787.87 # will require extra splitting
146 (.+) # H2793Z H32 c.2 EAS # everything else (except bracketing spaces)
149 unless (scalar @parts) {
150 warn sprintf('regexp failed to match string: %s', $_);
151 push @parts, $_; # if no match, just push the whole string.
154 if ($parts[0] =~ /^([-a-zA-Z]+)\s?($possible_decimal)$/) {
155 shift @parts; # pull off the mathching first element, like example 1
156 unshift @parts, $1, $2; # replace it with the two pieces
159 push @parts, split /\s+/, pop @parts; # split the last piece into an arbitrary number of pieces at spaces
160 $debug and print STDERR
"split_ddcn array: ", join(" | ", @parts), "\n";
164 ## NOTE: Custom call number types go here. It may be necessary to create additional splitting algorithms if some custom call numbers
165 ## cannot be made to work here. Presently this splits standard non-ddcn, non-lccn fiction and biography call numbers.
170 # Split call numbers based on spaces
171 push @parts, split /\s+/, $fcn; # split the call number into an arbitrary number of pieces at spaces
172 if ($parts[-1] !~ /^.*\d-\d.*$/ && $parts[-1] =~ /^(.*\d+)(\D.*)$/) {
173 pop @parts; # pull off the matching last element
174 push @parts, $1, $2; # replace it with the two pieces
176 unless (scalar @parts) {
177 warn sprintf('regexp failed to match string: %s', $_);
180 $debug and print STDERR
"split_ccn array: ", join(" | ", @parts), "\n";
184 sub _get_barcode_data
{
185 my ( $f, $item, $record ) = @_;
186 my $kohatables = _desc_koha_tables
();
188 my $match_kohatable = join(
191 @
{ $kohatables->{'biblio'} },
192 @
{ $kohatables->{'biblioitems'} },
193 @
{ $kohatables->{'items'} },
194 @
{ $kohatables->{'branches'} }
201 if ( $f =~ /^'(.*)'.*/ ) {
202 # single quotes indicate a static text string.
207 elsif ( $f =~ /^($match_kohatable).*/ ) {
209 $datastring .= $item->{$f};
211 $debug and warn sprintf("The '%s' field contains no data.", $f);
216 elsif ( $f =~ /^([0-9a-z]{3})(\w)(\W?).*?/ ) {
217 my ($field,$subf,$ws) = ($1,$2,$3);
219 my ($itemtag, $itemsubfieldcode) = &GetMarcFromKohaField
("items.itemnumber",'');
220 my @marcfield = $record->field($field);
222 if($field eq $itemtag) { # item-level data, we need to get the right item.
224 foreach my $itemfield (@marcfield) {
225 if ( $itemfield->subfield($itemsubfieldcode) eq $item->{'itemnumber'} ) {
226 if ($itemfield->subfield($subf)) {
227 $datastring .= $itemfield->subfield($subf) . $ws;
230 warn sprintf("The '%s' field contains no data.", $f);
235 } else { # bib-level data, we'll take the first matching tag/subfield.
236 if ($marcfield[0]->subfield($subf)) {
237 $datastring .= $marcfield[0]->subfield($subf) . $ws;
240 warn sprintf("The '%s' field contains no data.", $f);
248 warn sprintf('Failed to parse label format string
: %s', $f);
249 last FIELD_LIST; # Failed to match
255 sub _desc_koha_tables {
256 my $dbh = C4::Context->dbh();
258 for my $table ( 'biblio
','biblioitems
','items
','branches
' ) {
259 my $sth = $dbh->column_info(undef,undef,$table,'%');
260 while (my $info = $sth->fetchrow_hashref()){
261 push @{$kohatables->{$table}} , $info->{'COLUMN_NAME
'} ;
268 ### This series of functions calculates the position of text and barcode on individual labels
269 ### Please *do not* add printing types which are non-atomic. Instead, build code which calls the necessary atomic printing types to form the non-atomic types. See the ALT type
270 ### in labels/label-create-pdf.pl as an example.
271 ### NOTE: Each function must be passed seven parameters and return seven even if some are 0 or undef
275 my $line_spacer = ($self->{'font_size
'} * 1); # number of pixels between text rows (This is actually leading: baseline to baseline minus font size. Recommended starting point is 20% of font size.).
276 my $text_lly = ($self->{'lly
'} + ($self->{'height
'} - $self->{'top_text_margin
'}));
277 return $self->{'llx
'}, $text_lly, $line_spacer, 0, 0, 0, 0;
282 my $barcode_llx = $self->{'llx
'} + $self->{'left_text_margin
'}; # this places the bottom left of the barcode the left text margin distance to right of the left edge of the label ($llx)
283 my $barcode_lly = $self->{'lly
'} + $self->{'top_text_margin
'}; # this places the bottom left of the barcode the top text margin distance above the bottom of the label ($lly)
284 my $barcode_width = 0.8 * $self->{'width
'}; # this scales the barcode width to 80% of the label width
285 my $barcode_y_scale_factor = 0.01 * $self->{'height
'}; # this scales the barcode height to 10% of the label height
286 return 0, 0, 0, $barcode_llx, $barcode_lly, $barcode_width, $barcode_y_scale_factor;
291 my $barcode_llx = $self->{'llx
'} + $self->{'left_text_margin
'}; # this places the bottom left of the barcode the left text margin distance to right of the left edge of the label ($self->{'llx
'})
292 my $barcode_lly = $self->{'lly
'} + $self->{'top_text_margin
'}; # this places the bottom left of the barcode the top text margin distance above the bottom of the label ($lly)
293 my $barcode_width = 0.8 * $self->{'width
'}; # this scales the barcode width to 80% of the label width
294 my $barcode_y_scale_factor = 0.01 * $self->{'height
'}; # this scales the barcode height to 10% of the label height
295 my $line_spacer = ($self->{'font_size
'} * 1); # number of pixels between text rows (This is actually leading: baseline to baseline minus font size. Recommended starting point is 20% of font size.).
296 my $text_lly = ($self->{'lly
'} + ($self->{'height
'} - $self->{'top_text_margin
'}));
297 $debug and warn "Label: llx $self->{'llx
'}, lly $self->{'lly
'}, Text: lly $text_lly, $line_spacer, Barcode: llx $barcode_llx, lly $barcode_lly, $barcode_width, $barcode_y_scale_factor\n";
298 return $self->{'llx
'}, $text_lly, $line_spacer, $barcode_llx, $barcode_lly, $barcode_width, $barcode_y_scale_factor;
303 my $barcode_llx = $self->{'llx
'} + $self->{'left_text_margin
'}; # this places the bottom left of the barcode the left text margin distance to right of the left edge of the label ($self->{'llx
'})
304 my $barcode_lly = ($self->{'lly
'} + $self->{'height
'}) - $self->{'top_text_margin
'}; # this places the bottom left of the barcode the top text margin distance below the top of the label ($self->{'lly
'})
305 my $barcode_width = 0.8 * $self->{'width
'}; # this scales the barcode width to 80% of the label width
306 my $barcode_y_scale_factor = 0.01 * $self->{'height
'}; # this scales the barcode height to 10% of the label height
307 my $line_spacer = ($self->{'font_size
'} * 1); # number of pixels between text rows (This is actually leading: baseline to baseline minus font size. Recommended starting point is 20% of font size.).
308 my $text_lly = (($self->{'lly
'} + $self->{'height
'}) - $self->{'top_text_margin
'} - (($self->{'lly
'} + $self->{'height
'}) - $barcode_lly));
309 return $self->{'llx
'}, $text_lly, $line_spacer, $barcode_llx, $barcode_lly, $barcode_width, $barcode_y_scale_factor;
313 my ($invocant, %params) = @_;
314 my $type = ref($invocant) || $invocant;
316 batch_id => $params{'batch_id
'},
317 item_number => $params{'item_number
'},
318 llx => $params{'llx
'},
319 lly => $params{'lly
'},
320 height => $params{'height
'},
321 width => $params{'width
'},
322 top_text_margin => $params{'top_text_margin
'},
323 left_text_margin => $params{'left_text_margin
'},
324 barcode_type => $params{'barcode_type
'},
325 printing_type => $params{'printing_type
'},
326 guidebox => $params{'guidebox
'},
327 oblique_title => $params{'oblique_title
'},
328 font => $params{'font
'},
329 font_size => $params{'font_size
'},
330 callnum_split => $params{'callnum_split
'},
331 justify => $params{'justify
'},
332 format_string => $params{'format_string
'},
333 text_wrap_cols => $params{'text_wrap_cols
'},
336 if ($self->{'guidebox
'}) {
337 $self->{'guidebox
'} = _guide_box($self->{'llx
'}, $self->{'lly
'}, $self->{'width
'}, $self->{'height
'});
339 bless ($self, $type);
345 return $self->{'printing_type
'};
350 if (_check_params(@_) eq 1) {
354 if (exists($self->{$attr})) {
355 return $self->{$attr};
366 my ($text_llx, $text_lly, $line_spacer, $barcode_llx, $barcode_lly, $barcode_width, $barcode_y_scale_factor);
369 ($text_llx, $text_lly, $line_spacer, $barcode_llx, $barcode_lly, $barcode_width, $barcode_y_scale_factor) = &{"_$self->{'printing_type
'}"}($self); # an obfuscated call to the correct printing type sub
371 if ($self->{'printing_type
'} =~ /BIB/) {
372 $label_text = draw_label_text( $self,
375 line_spacer => $line_spacer,
378 if ($self->{'printing_type
'} =~ /BAR/) {
382 width => $barcode_width,
383 y_scale_factor => $barcode_y_scale_factor,
386 return $label_text if $label_text;
390 sub draw_label_text {
391 my ($self, %params) = @_;
394 my $text_lly = $params{'lly
'};
395 my $font = $self->{'font
'};
396 my $item = _get_label_item($self->{'item_number
'});
397 my $label_fields = _get_text_fields($self->{'format_string
'});
398 my $record = GetMarcBiblio($item->{'biblionumber
'});
399 # FIXME - returns all items, so you can't get data from an embedded holdings field
.
400 # TODO - add a GetMarcBiblio1item(bibnum,itemnum) or a GetMarcItem(itemnum).
401 my $cn_source = ($item->{'cn_source'} ?
$item->{'cn_source'} : C4
::Context
->preference('DefaultClassificationSource'));
402 LABEL_FIELDS
: # process data for requested fields on current label
403 for my $field (@
$label_fields) {
404 if ($field->{'code'} eq 'itemtype') {
405 $field->{'data'} = C4
::Context
->preference('item-level_itypes') ?
$item->{'itype'} : $item->{'itemtype'};
408 $field->{'data'} = _get_barcode_data
($field->{'code'},$item,$record);
410 # Find apropriate font it oblique title selected, except main font is oblique
411 if ( ( $field->{'code'} eq 'title' ) and ( $self->{'oblique_title'} == 1 ) ) {
412 if ( $font =~ /^TB$/ ) {
415 elsif ( $font =~ /^TR$/ ) {
418 elsif ( $font !~ /^T/ and $font !~ /O$/ ) {
422 my $field_data = $field->{'data'};
424 $field_data =~ s/\n//g;
425 $field_data =~ s/\r//g;
428 # Fields which hold call number data FIXME: ( 060? 090? 092? 099? )
429 my @callnumber_list = qw(itemcallnumber 050a 050b 082a 952o 995k);
430 if ((grep {$field->{'code'} =~ m/$_/} @callnumber_list) and ($self->{'printing_type'} eq 'BIB') and ($self->{'callnum_split'})) { # If the field contains the call number, we do some sp
431 if ($cn_source eq 'lcc' || $cn_source eq 'nlm') { # NLM and LCC should be split the same way
432 @label_lines = _split_lccn
($field_data);
433 @label_lines = _split_ccn
($field_data) if !@label_lines; # If it was not a true lccn, try it as a custom call number
434 push (@label_lines, $field_data) if !@label_lines; # If it was not that, send it on unsplit
435 } elsif ($cn_source eq 'ddc') {
436 @label_lines = _split_ddcn
($field_data);
437 @label_lines = _split_ccn
($field_data) if !@label_lines;
438 push (@label_lines, $field_data) if !@label_lines;
440 warn sprintf('Call number splitting failed for: %s. Please add this call number to bug #2500 at bugs.koha-community.org', $field_data);
441 push @label_lines, $field_data;
446 $field_data =~ s/\/$//g; # Here we will strip out all trailing '/' in fields other than the call number...
447 # Escaping the parens was causing odd output, see bug 13124
448 # $field_data =~ s/\(/\\\(/g; # Escape '(' and ')' for the pdf object stream...
449 # $field_data =~ s/\)/\\\)/g;
451 eval{$Text::Wrap::columns = $self->{'text_wrap_cols
'};};
452 my @line = split(/\n/ ,wrap('', '', $field_data));
453 # If this is a title field, limit to two lines; all others limit to one... FIXME: this is rather arbitrary
454 if ($field->{'code
'} eq 'title
' && scalar(@line) >= 2) {
455 while (scalar(@line) > 2) {
459 while (scalar(@line) > 1) {
463 push(@label_lines, @line);
465 LABEL_LINES: # generate lines of label text for current field
466 foreach my $line (@label_lines) {
467 next LABEL_LINES if $line eq '';
468 $line = log2vis( $line );
469 my $string_width = C4::Creators::PDF->StrWidth($line, $font, $self->{'font_size
'});
470 if ($self->{'justify
'} eq 'R
') {
471 $text_llx = $params{'llx
'} + $self->{'width
'} - ($self->{'left_text_margin
'} + $string_width);
473 elsif($self->{'justify
'} eq 'C
') {
474 # some code to try and center each line on the label based on font size and string point width...
475 my $whitespace = ($self->{'width
'} - ($string_width + (2 * $self->{'left_text_margin
'})));
476 $text_llx = (($whitespace / 2) + $params{'llx
'} + $self->{'left_text_margin
'});
479 $text_llx = ($params{'llx
'} + $self->{'left_text_margin
'});
482 text_llx => $text_llx,
483 text_lly => $text_lly,
485 font_size => $self->{'font_size
'},
488 $text_lly = $text_lly - $params{'line_spacer
'};
490 $font = $self->{'font
'}; # reset font for next field
496 return $_[0]->{'guidebox
'};
502 $params{'barcode_data
'} = _get_label_item($self->{'item_number
'}, 1) if !$params{'barcode_data
'};
503 $params{'barcode_type
'} = $self->{'barcode_type
'} if !$params{'barcode_type
'};
504 my $x_scale_factor = 1;
505 my $num_of_bars = length($params{'barcode_data
'});
506 my $tot_bar_length = 0;
508 my $guard_length = 10;
509 my $hide_text = 'yes
';
510 if ($params{'barcode_type
'} =~ m/CODE39/) {
511 $bar_length = '17.5';
512 $tot_bar_length = ($bar_length * $num_of_bars) + ($guard_length * 2);
513 $x_scale_factor = ($params{'width
'} / $tot_bar_length);
514 if ($params{'barcode_type
'} eq 'CODE39MOD
') {
515 my $c39 = CheckDigits('code_39
'); # get modulo43 checksum
516 $params{'barcode_data
'} = $c39->complete($params{'barcode_data
'});
518 elsif ($params{'barcode_type
'} eq 'CODE39MOD10
') {
519 my $c39_10 = CheckDigits('siret
'); # get modulo43 checksum
520 $params{'barcode_data
'} = $c39_10->complete($params{'barcode_data
'});
524 PDF::Reuse::Barcode::Code39(
527 value => "*$params{barcode_data}*",
528 xSize => $x_scale_factor,
529 ySize => $params{'y_scale_factor
'},
536 warn sprintf('Barcode generation failed
for item
%s with this error
: %s', $self->{'item_number
'}, $@);
539 elsif ($params{'barcode_type
'} eq 'COOP2OF5
') {
540 $bar_length = '9.43333333333333';
541 $tot_bar_length = ($bar_length * $num_of_bars) + ($guard_length * 2);
542 $x_scale_factor = ($params{'width
'} / $tot_bar_length) * 0.9;
544 PDF::Reuse::Barcode::COOP2of5(
547 value => $params{barcode_data},
548 xSize => $x_scale_factor,
549 ySize => $params{'y_scale_factor
'},
554 warn sprintf('Barcode generation failed
for item
%s with this error
: %s', $self->{'item_number
'}, $@);
557 elsif ( $params{'barcode_type
'} eq 'INDUSTRIAL2OF5
' ) {
558 $bar_length = '13.1333333333333';
559 $tot_bar_length = ($bar_length * $num_of_bars) + ($guard_length * 2);
560 $x_scale_factor = ($params{'width
'} / $tot_bar_length) * 0.9;
562 PDF::Reuse::Barcode::Industrial2of5(
565 value => $params{barcode_data},
566 xSize => $x_scale_factor,
567 ySize => $params{'y_scale_factor
'},
572 warn sprintf('Barcode generation failed
for item
%s with this error
: %s', $self->{'item_number
'}, $@);
575 elsif ($params{'barcode_type
'} eq 'EAN13
') {
576 $bar_length = 4; # FIXME
578 $tot_bar_length = ($bar_length * $num_of_bars) + ($guard_length * 2);
579 $x_scale_factor = ($params{'width
'} / $tot_bar_length) * 0.9;
581 PDF::Reuse::Barcode::EAN13(
584 value => sprintf('%013d',$params{barcode_data}),
585 # xSize => $x_scale_factor,
586 # ySize => $params{'y_scale_factor
'},
591 warn sprintf('Barcode generation failed
for item
%s with this error
: %s', $self->{'item_number
'}, $@);
595 warn "unknown barcode_type: $params{barcode_type}";
601 my $label_fields = _get_text_fields($self->{'format_string
'});
602 my $item = _get_label_item($self->{'item_number
'});
603 my $bib_record = GetMarcBiblio($item->{biblionumber});
604 my @csv_data = (map { _get_barcode_data($_->{'code
'},$item,$bib_record) } @$label_fields);
613 C4::Labels::Label - A class for creating and manipulating label objects in Koha
617 This module provides methods for creating, and otherwise manipulating single label objects used by Koha to create and export labels.
623 Invoking the I<new> method constructs a new label object containing the supplied values. Depending on the final output format of the label data
624 the minimal required parameters change. (See the implimentation of this object type in labels/label-create-pdf.pl and labels/label-create-csv.pl
625 and labels/label-create-xml.pl for examples.) The following parameters are optionally accepted as key => value pairs:
627 C<batch_id> Batch id with which this label is associated
628 C<item_number> Item number of item to be the data source for this label
629 C<height> Height of this label (All measures passed to this method B<must> be supplied in postscript points)
630 C<width> Width of this label
631 C<top_text_margin> Top margin of this label
632 C<left_text_margin> Left margin of this label
633 C<barcode_type> Defines the barcode type to be used on labels. NOTE: At present only the following barcode types are supported in the label creator code:
641 CODE39MOD = Code 3 of 9 with modulo 43 checksum
644 CODE39MOD10 = Code 3 of 9 with modulo 10 checksum
647 COOP2OF5 = A variant of 2 of 5 barcode based on NEC's
"Process 8000" code
650 INDUSTRIAL2OF5 = The standard 2 of 5 barcode (a binary level bar code developed by Identicon Corp. and Computer Identics Corp. in 1970)
653 EAN13 = The standard EAN-13 barcode
657 C<printing_type> Defines the general layout to be used on labels. NOTE: At present there are only five printing types supported in the label creator code:
662 BIB = Only the bibliographic data is printed
665 BARBIB = Barcode proceeds bibliographic data
668 BIBBAR = Bibliographic data proceeds barcode
671 ALT = Barcode and bibliographic data are printed on alternating labels
674 BAR = Only the barcode is printed
678 C<guidebox> Setting this to '1' will result in a guide box being drawn around the labels marking the edge of each label
679 C<font> Defines the type of font to be used on labels. NOTE: The following fonts are available by default on most systems:
693 TBI = Times Bold Italic
702 CO = Courier Oblique (Italic)
705 CBO = Courier Bold Oblique
714 HBO = Helvetical Bold Oblique
718 C<font_size> Defines the size of the font in postscript points to be used on labels
719 C<callnum_split> Setting this to '1' will enable call number splitting on labels
720 C<text_justify> Defines the text justification to be used on labels. NOTE: The following justification styles are currently supported by label creator code:
735 C<format_string> Defines what fields will be printed and in what order they will be printed on labels. These include any of the data fields that may be mapped
736 to your MARC frameworks. Specify MARC subfields as a 4-character tag-subfield string: ie. 254a Enclose a whitespace-separated list of fields
737 to concatenate on one line in double quotes. ie. "099a 099b" or "itemcallnumber barcode" Static text strings may be entered in single-quotes:
738 ie. 'Some static text here.'
739 C<text_wrap_cols> Defines the column after which the text will wrap to the next line.
741 =head2 get_label_type()
743 Invoking the I<get_label_type> method will return the printing type of the label object.
746 C<my $label_type = $label->get_label_type();>
748 =head2 get_attr($attribute)
750 Invoking the I<get_attr> method will return the value of the requested attribute or -1 on errors.
753 C<my $value = $label->get_attr($attribute);>
755 =head2 create_label()
757 Invoking the I<create_label> method generates the text for that label and returns it as an arrayref of an array contianing the formatted text as well as creating the barcode
758 and writing it directly to the pdf stream. The handling of the barcode is not quite good OO form due to the linear format of PDF::Reuse::Barcode. Be aware that the instantiating
759 code is responsible to properly format the text for insertion into the pdf stream as well as the actual insertion.
762 my $label_text = $label->create_label();
764 =head2 draw_label_text()
766 Invoking the I<draw_label_text> method generates the label text for the label object and returns it as an arrayref of an array containing the formatted text. The same caveats
767 apply to this method as to C<create_label()>. This method accepts the following parameters as key => value pairs: (NOTE: The unit is the postscript point - 72 per inch)
769 C<llx> The lower-left x coordinate for the text block (The point of origin for all PDF's is the lower left of the page per ISO 32000-1)
770 C<lly> The lower-left y coordinate for the text block
771 C<top_text_margin> The top margin for the text block.
772 C<line_spacer> The number of pixels between text rows (This is actually leading: baseline to baseline minus font size. Recommended starting point is 20% of font size)
773 C<font> The font to use for this label. See documentation on the new() method for supported fonts.
774 C<font_size> The font size in points to use for this label.
775 C<justify> The style of justification to use for this label. See documentation on the new() method for supported justification styles.
778 C<my $label_text = $label->draw_label_text(
781 top_text_margin => $label_top_text_margin,
782 line_spacer => $text_leading,
784 font_size => $text_font_size,
785 justify => $text_justification,
790 Invoking the I<barcode> 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
791 pairs (C<barcode_data> is optional and omitting it will cause the barcode from the current item to be used. C<barcode_type> is also optional. Omission results in the barcode
792 type of the current template being used.):
794 C<llx> 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)
795 C<lly> The lower-left y coordinate for the barcode block
796 C<width> The width of the barcode block
797 C<y_scale_factor> The scale factor to be applied to the y axis of the barcode block
798 C<barcode_data> The data to be encoded in the barcode
799 C<barcode_type> The barcode type (See the C<new()> method for supported barcode types)
805 width => $barcode_width,
806 y_scale_factor => $barcode_y_scale_factor,
807 barcode_data => $barcode,
808 barcode_type => $barcodetype,
813 Invoking the I<csv_data> method returns an arrayref of an array containing the label data suitable for passing to Text::CSV_XS->combine() to produce csv output.
816 C<my $csv_data = $label->csv_data();>
820 Mason James <mason@katipo.co.nz>
822 Chris Nighswonger <cnighswonger AT foundations DOT edu>
826 Copyright 2006 Katipo Communications.
828 Copyright 2009 Foundations Bible College.
832 This file is part of Koha.
834 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
835 Foundation; either version 2 of the License, or (at your option) any later version.
837 You should have received a copy of the GNU General Public License along with Koha; if not, write to the Free Software Foundation, Inc., 51 Franklin Street,
838 Fifth Floor, Boston, MA 02110-1301 USA.
840 =head1 DISCLAIMER OF WARRANTY
842 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
843 A PARTICULAR PURPOSE. See the GNU General Public License for more details.