File Coverage

blib/lib/PDF/Builder/Resource/XObject/Form/BarCode.pm
Criterion Covered Total %
statement 105 130 80.7
branch 26 36 72.2
condition 37 70 52.8
subroutine 9 11 81.8
pod 3 6 50.0
total 180 253 71.1


line stmt bran cond sub pod time code
1             package PDF::Builder::Resource::XObject::Form::BarCode;
2              
3 2     2   1091 use base 'PDF::Builder::Resource::XObject::Form::Hybrid';
  2         4  
  2         230  
4              
5 2     2   14 use strict;
  2         4  
  2         42  
6 2     2   10 use warnings;
  2         5  
  2         155  
7              
8             our $VERSION = '3.025'; # VERSION
9             our $LAST_UPDATE = '3.024'; # manually update whenever code is changed
10              
11 2     2   14 use PDF::Builder::Util;
  2         5  
  2         318  
12 2     2   14 use PDF::Builder::Basic::PDF::Utils;
  2         8  
  2         3051  
13              
14             =head1 NAME
15              
16             PDF::Builder::Resource::XObject::Form::BarCode - Base class for one-dimensional barcodes
17              
18             =head1 METHODS
19              
20             =over
21              
22             =item $barcode = PDF::Builder::Resource::XObject::Form::BarCode->new($pdf, %options)
23              
24             Creates a barcode form resource.
25              
26             =cut
27              
28             sub new {
29 6     6 1 22 my ($class, $pdf, %options) = @_;
30             # copy dashed option names to preferred undashed names
31 6 100 66     24 if (defined $options{'-font'} && !defined $options{'font'}) { $options{'font'} = delete($options{'-font'}); }
  1         3  
32 6 100 66     20 if (defined $options{'-umzn'} && !defined $options{'umzn'}) { $options{'umzn'} = delete($options{'-umzn'}); }
  1         3  
33 6 100 66     19 if (defined $options{'-lmzn'} && !defined $options{'lmzn'}) { $options{'lmzn'} = delete($options{'-lmzn'}); }
  1         3  
34 6 100 66     17 if (defined $options{'-zone'} && !defined $options{'zone'}) { $options{'zone'} = delete($options{'-zone'}); }
  1         3  
35 6 50 33     17 if (defined $options{'-quzn'} && !defined $options{'quzn'}) { $options{'quzn'} = delete($options{'-quzn'}); }
  0         0  
36 6 50 33     16 if (defined $options{'-ofwt'} && !defined $options{'ofwt'}) { $options{'ofwt'} = delete($options{'-ofwt'}); }
  0         0  
37 6 100 66     23 if (defined $options{'-fnsz'} && !defined $options{'fnsz'}) { $options{'fnsz'} = delete($options{'-fnsz'}); }
  1         3  
38 6 50 33     12 if (defined $options{'-spcr'} && !defined $options{'spcr'}) { $options{'spcr'} = delete($options{'-spcr'}); }
  0         0  
39 6 50 33     17 if (defined $options{'-mils'} && !defined $options{'mils'}) { $options{'mils'} = delete($options{'-mils'}); }
  0         0  
40 6 50 33     16 if (defined $options{'-color'} && !defined $options{'color'}) { $options{'color'} = delete($options{'-color'}); }
  0         0  
41              
42 6         37 my $self = $class->SUPER::new($pdf);
43              
44 6         13 $self->{' bfont'} = $options{'font'};
45              
46 6   50     27 $self->{' umzn'} = $options{'umzn'} || 0; # (u)pper (m)ending (z)o(n)e
47 6   100     23 $self->{' lmzn'} = $options{'lmzn'} || 0; # (l)ower (m)ending (z)o(n)e
48 6   100     28 $self->{' zone'} = $options{'zone'} || 0; # barcode height
49 6   50     19 $self->{' quzn'} = $options{'quzn'} || 0; # (qu)iet (z)o(n)e
50 6   50     31 $self->{' ofwt'} = $options{'ofwt'} || 0.01; # (o)ver(f)low (w)id(t)h
51 6         10 $self->{' fnsz'} = $options{'fnsz'}; # (f)o(n)t(s)i(z)e
52 6   50     20 $self->{' spcr'} = $options{'spcr'} || ''; # (sp)a(c)e(r) between chars in label
53 6   50     21 $self->{' mils'} = $options{'mils'} || 1000/72; # single barcode unit width. 1 mil = 1/1000 of one inch. 1000/72 - for backward compatibility
54 6   50     18 $self->{' color'} = $options{'color'} || 'black'; # barcode color
55              
56 6         22 return $self;
57             }
58              
59             my %bar_widths = (
60             0 => 0,
61             1 => 1, 'a' => 1, 'A' => 1,
62             2 => 2, 'b' => 2, 'B' => 2,
63             3 => 3, 'c' => 3, 'C' => 3,
64             4 => 4, 'd' => 4, 'D' => 4,
65             5 => 5, 'e' => 5, 'E' => 5,
66             6 => 6, 'f' => 6, 'F' => 6,
67             7 => 7, 'g' => 7, 'G' => 7,
68             8 => 8, 'h' => 8, 'H' => 8,
69             9 => 9, 'i' => 9, 'I' => 9,
70             );
71              
72             sub encode {
73 2     2 0 2604 my ($self, $string) = @_;
74              
75 2         10 my @bars = map { [ $self->encode_string($_), $_ ] } split(//, $string);
  17         34  
76 2         8 return @bars;
77             }
78              
79             sub encode_string {
80 17     17 0 30 my ($self, $string) = @_;
81              
82 17         25 my $bar;
83 17         34 foreach my $character (split(//, $string)) {
84 17         39 $bar .= $self->encode_char($character);
85             }
86 17         50 return $bar;
87             }
88              
89             sub drawbar {
90 6     6 0 13 my $self = shift();
91 6         11 my @sets = @{shift()};
  6         14  
92 6         23 my $caption = shift();
93              
94 6         44 $self->fillcolor($self->{' color'});
95 6         49 $self->strokecolor($self->{' color'});
96 6         62 $self->linedash();
97              
98 6         13 my $x = $self->{' quzn'};
99 6         11 my $is_space_next = 0;
100 6         19 my $wdt_factor = $self->{' mils'} / 1000 * 72;
101 6         16 foreach my $set (@sets) {
102 30         48 my ($code, $label);
103 30 100       63 if (ref($set)) {
104 18         29 ($code, $label) = @{$set};
  18         36  
105             } else {
106 12         19 $code = $set;
107 12         22 $label = undef;
108             }
109              
110 30         48 my $code_width = 0;
111 30         44 my ($font_size, $y_label);
112 30         97 foreach my $bar (split(//, $code)) {
113 172         315 my $bar_width = $bar_widths{$bar} * $wdt_factor;
114              
115 172         264 my ($y0, $y1);
116 172 100       486 if ($bar =~ /[0-9]/) {
    50          
    0          
117 115         198 $y0 = $self->{' quzn'} + $self->{' lmzn'};
118 115         203 $y1 = $self->{' quzn'} + $self->{' lmzn'} + $self->{' zone'} + $self->{' umzn'};
119 115         165 $y_label = $self->{' quzn'};
120 115 50 66     272 if ($self->{' fnsz'} and $self->{' lmzn'} < $self->{' fnsz'}) {
121 0         0 $y_label -= $self->{' fnsz'} * 0.8 - $self->{' lmzn'};
122             }
123 115   66     313 $font_size = $self->{' fnsz'} || $self->{' lmzn'};
124             } elsif ($bar =~ /[a-z]/) {
125 57         99 $y0 = $self->{' quzn'};
126 57         94 $y1 = $self->{' quzn'} + $self->{' lmzn'} + $self->{' zone'} + $self->{' umzn'};
127 57         100 $y_label = $self->{' quzn'} + $self->{' lmzn'} + $self->{' zone'} + $self->{' umzn'} + 2;
128 57   66     154 $font_size = $self->{' fnsz'} || $self->{' umzn'};
129             } elsif ($bar =~ /[A-Z]/) {
130 0         0 $y0 = $self->{' quzn'};
131 0         0 $y1 = $self->{' quzn'} + $self->{' lmzn'} + $self->{' zone'};
132 0   0     0 $font_size = $self->{' fnsz'} || $self->{' umzn'};
133 0         0 $y_label = $self->{' quzn'} + $self->{' lmzn'} + $self->{' zone'} + $self->{' umzn'} - $font_size;
134             } else {
135 0         0 $y0 = $self->{' quzn'} + $self->{' lmzn'};
136 0         0 $y1 = $self->{' quzn'} + $self->{' lmzn'} + $self->{' zone'} + $self->{' umzn'};
137 0         0 $y_label = $self->{' quzn'};
138 0   0     0 $font_size = $self->{' fnsz'} || $self->{' lmzn'};
139             }
140              
141 172 100 100     463 unless ($is_space_next or $bar eq '0') {
142 86         327 $self->linewidth($bar_width - $self->{' ofwt'});
143 86         349 $self->move($x + $code_width + $bar_width / 2, $y0);
144 86         355 $self->line($x + $code_width + $bar_width / 2, $y1);
145 86         217 $self->stroke();
146             }
147 172         290 $is_space_next = not $is_space_next;
148              
149 172         305 $code_width += $bar_width;
150             }
151              
152 30 100 100     108 if (defined($label) and $self->{' lmzn'}) {
153 1         5 $label = join($self->{' spcr'}, split(//, $label));
154 1         49 $self->textstart();
155 1         15 $self->translate($x + ($code_width / 2), $y_label);
156 1         12 $self->font($self->{' bfont'}, $font_size);
157 1         13 $self->text_center($label);
158 1         8 $self->textend();
159             }
160              
161 30         63 $x += $code_width;
162             }
163              
164 6         15 $x += $self->{' quzn'};
165              
166 6 50       14 if (defined $caption) {
167 0   0     0 my $font_size = $self->{' fnsz'} || $self->{' lmzn'};
168 0         0 my $y_caption = $self->{' quzn'} - $font_size;
169 0         0 $self->textstart();
170 0         0 $self->translate($x / 2, $y_caption);
171 0         0 $self->font($self->{' bfont'}, $font_size);
172 0         0 $self->text_center($caption);
173 0         0 $self->textend();
174             }
175              
176 6         12 $self->{' w'} = $x;
177 6         19 $self->{' h'} = 2 * $self->{' quzn'} + $self->{' lmzn'} + $self->{' zone'} + $self->{' umzn'};
178 6         56 $self->bbox(0, 0, $self->{' w'}, $self->{' h'});
179 6         19 return;
180             }
181              
182             =item $width = $barcode->width()
183              
184             =cut
185              
186             sub width {
187 0     0 1   my $self = shift;
188              
189 0           return $self->{' w'};
190             }
191              
192             =item $height = $barcode->height()
193              
194             =cut
195              
196             sub height {
197 0     0 1   my $self = shift;
198              
199 0           return $self->{' h'};
200             }
201              
202             =back
203              
204             =cut
205              
206             1;