package PDF::API2::Resource::XObject::Form::BarCode; use base 'PDF::API2::Resource::XObject::Form::Hybrid'; use strict; use warnings; our $VERSION = '2.043'; # VERSION use PDF::API2::Util; use PDF::API2::Basic::PDF::Utils; =head1 NAME PDF::API2::Resource::XObject::Form::BarCode - Base class for one-dimensional barcodes =head1 METHODS =over =item $barcode = PDF::API2::Resource::XObject::Form::BarCode->new($pdf, %options) Creates a barcode form resource. =cut sub new { my ($class, $pdf, %options) = @_; my $self = $class->SUPER::new($pdf); $self->{' bfont'} = $options{'-font'}; $self->{' umzn'} = $options{'-umzn'} || 0; # (u)pper (m)ending (z)o(n)e $self->{' lmzn'} = $options{'-lmzn'} || 0; # (l)ower (m)ending (z)o(n)e $self->{' zone'} = $options{'-zone'} || 0; # barcode height $self->{' quzn'} = $options{'-quzn'} || 0; # (qu)iet (z)o(n)e $self->{' ofwt'} = $options{'-ofwt'} || 0.01; # (o)ver(f)low (w)id(t)h $self->{' fnsz'} = $options{'-fnsz'}; # (f)o(n)t(s)i(z)e $self->{' spcr'} = $options{'-spcr'} || ''; # (sp)a(c)e(r) between chars in label $self->{' mils'} = $options{'-mils'} || 1000/72; # single barcode unit width. 1 mil = 1/1000 of one inch. 1000/72 - for backward compatibility $self->{' color'} = $options{'-color'} || 'black'; # barcode color return $self; } my %bar_widths = ( 0 => 0, 1 => 1, 'a' => 1, 'A' => 1, 2 => 2, 'b' => 2, 'B' => 2, 3 => 3, 'c' => 3, 'C' => 3, 4 => 4, 'd' => 4, 'D' => 4, 5 => 5, 'e' => 5, 'E' => 5, 6 => 6, 'f' => 6, 'F' => 6, 7 => 7, 'g' => 7, 'G' => 7, 8 => 8, 'h' => 8, 'H' => 8, 9 => 9, 'i' => 9, 'I' => 9, ); sub encode { my ($self, $string) = @_; my @bars = map { [ $self->encode_string($_), $_ ] } split //, $string; return @bars; } sub encode_string { my ($self, $string) = @_; my $bar; foreach my $character (split //, $string) { $bar .= $self->encode_char($character); } return $bar; } sub drawbar { my $self = shift(); my @sets = @{shift()}; my $caption = shift(); $self->fillcolor($self->{' color'}); $self->strokecolor($self->{' color'}); $self->linedash(); my $x = $self->{' quzn'}; my $is_space_next = 0; my $wdt_factor = $self->{' mils'} / 1000 * 72; foreach my $set (@sets) { my ($code, $label); if (ref($set)) { ($code, $label) = @{$set}; } else { $code = $set; $label = undef; } my $code_width = 0; my ($font_size, $y_label); foreach my $bar (split //, $code) { my $bar_width = $bar_widths{$bar} * $wdt_factor; my ($y0, $y1); if ($bar =~ /[0-9]/) { $y0 = $self->{' quzn'} + $self->{' lmzn'}; $y1 = $self->{' quzn'} + $self->{' lmzn'} + $self->{' zone'} + $self->{' umzn'}; $y_label = $self->{' quzn'}; if ($self->{' fnsz'} and $self->{' lmzn'} < $self->{' fnsz'}) { $y_label -= $self->{' fnsz'} * 0.8 - $self->{' lmzn'}; } $font_size = $self->{' fnsz'} || $self->{' lmzn'}; } elsif ($bar =~ /[a-z]/) { $y0 = $self->{' quzn'}; $y1 = $self->{' quzn'} + $self->{' lmzn'} + $self->{' zone'} + $self->{' umzn'}; $y_label = $self->{' quzn'} + $self->{' lmzn'} + $self->{' zone'} + $self->{' umzn'} + 2; $font_size = $self->{' fnsz'} || $self->{' umzn'}; } elsif ($bar =~ /[A-Z]/) { $y0 = $self->{' quzn'}; $y1 = $self->{' quzn'} + $self->{' lmzn'} + $self->{' zone'}; $font_size = $self->{' fnsz'} || $self->{' umzn'}; $y_label = $self->{' quzn'} + $self->{' lmzn'} + $self->{' zone'} + $self->{' umzn'} - $font_size; } else { $y0 = $self->{' quzn'} + $self->{' lmzn'}; $y1 = $self->{' quzn'} + $self->{' lmzn'} + $self->{' zone'} + $self->{' umzn'}; $y_label = $self->{' quzn'}; $font_size = $self->{' fnsz'} || $self->{' lmzn'}; } unless ($is_space_next or $bar eq '0') { $self->linewidth($bar_width - $self->{' ofwt'}); $self->move($x + $code_width + $bar_width / 2, $y0); $self->line($x + $code_width + $bar_width / 2, $y1); $self->stroke(); } $is_space_next = not $is_space_next; $code_width += $bar_width; } if (defined($label) and $self->{' lmzn'}) { $label = join($self->{' spcr'}, split //, $label); $self->textstart(); $self->translate($x + ($code_width / 2), $y_label); $self->font($self->{' bfont'}, $font_size); $self->text_center($label); $self->textend(); } $x += $code_width; } $x += $self->{' quzn'}; if (defined $caption) { my $font_size = $self->{' fnsz'} || $self->{' lmzn'}; my $y_caption = $self->{' quzn'} - $font_size; $self->textstart(); $self->translate($x / 2, $y_caption); $self->font($self->{' bfont'}, $font_size); $self->text_center($caption); $self->textend(); } $self->{' w'} = $x; $self->{' h'} = 2 * $self->{' quzn'} + $self->{' lmzn'} + $self->{' zone'} + $self->{' umzn'}; $self->bbox(0, 0, $self->{' w'}, $self->{' h'}); } =item $width = $barcode->width() =cut sub width { my $self = shift(); return $self->{' w'}; } =item $height = $barcode->height() =cut sub height { my $self = shift(); return $self->{' h'}; } =back =cut 1;