File Coverage

blib/lib/Imager/IMBarcode/JP.pm
Criterion Covered Total %
statement 18 86 20.9
branch 0 18 0.0
condition n/a
subroutine 6 12 50.0
pod 1 2 50.0
total 25 118 21.1


line stmt bran cond sub pod time code
1             package Imager::IMBarcode::JP;
2              
3 1     1   804 use strict;
  1         2  
  1         30  
4 1     1   5 use warnings;
  1         2  
  1         24  
5 1     1   695 use utf8;
  1         16  
  1         5  
6 1     1   1031 use Imager;
  1         48203  
  1         8  
7 1     1   674 use Mouse;
  1         30813  
  1         5  
8              
9             our $VERSION = '0.01';
10              
11             has zipcode => (
12             is => 'rw',
13             isa => 'Int',
14             default => '00000000',
15             );
16              
17             has address => (
18             is => 'rw',
19             isa => 'Str',
20             default => '',
21             );
22              
23             has _pos => (
24             is => 'rw',
25             isa => 'Int',
26             default => 0,
27             );
28              
29             has _base => (
30             is => 'ro',
31             isa => 'Imager',
32             lazy_build => 1,
33             );
34              
35             has _char_code => (
36             is => 'ro',
37             isa => 'HashRef',
38             default => sub {
39             my %code = (
40             STC => +{
41             bar => 13,
42             },
43             SPC => +{
44             bar => 31,
45             },
46             1 => +{
47             check => 1,
48             bar => 114,
49             },
50             2 => +{
51             check => 2,
52             bar => 132,
53             },
54             3 => +{
55             check => 3,
56             bar => 312,
57             },
58             4 => +{
59             check => 4,
60             bar => 123,
61             },
62             5 => +{
63             check => 5,
64             bar => 141,
65             },
66             6 => +{
67             check => 6,
68             bar => 321,
69             },
70             7 => +{
71             check => 7,
72             bar => 213,
73             },
74             8 => +{
75             check => 8,
76             bar => 231,
77             },
78             9 => +{
79             check => 9,
80             bar => 411,
81             },
82             0 => +{
83             check => 0,
84             bar => 144,
85             },
86             '-' => +{
87             check => 10,
88             bar => 414,
89             },
90             CC1 => +{
91             check => 11,
92             bar => 324,
93             },
94             CC2 => +{
95             check => 12,
96             bar => 342,
97             },
98             CC3 => => +{
99             check => 13,
100             bar => 234,
101             },
102             CC4 => +{
103             check => 14,
104             bar => 432,
105             },
106             CC5 => +{
107             check => 15,
108             bar => 243,
109             },
110             CC6 => +{
111             check => 16,
112             bar => 423,
113             },
114             CC7 => +{
115             check => 17,
116             bar => 441,
117             },
118             CC8 => +{
119             check => 18,
120             bar => 111,
121             },
122             );
123             my @cc = @code{qw(CC1 CC2 CC3)};
124             for my $i (0 .. $#cc) {
125             for my $num (0 .. 9) {
126             my $k = chr(65 + (10 * $i) + $num);
127             my $v = [ $cc[$i], $code{$num} ];
128             $code{$k} = +{
129             check => [ $cc[$i]->{check}, $code{$num}->{check} ],
130             bar => [ $cc[$i]->{bar}, $code{$num}->{bar} ],
131             };
132             last if $k ge 'Z';
133             }
134             }
135             return \%code;
136             },
137             );
138              
139 1     1   778 no Mouse;
  1         3  
  1         13  
140              
141             __PACKAGE__->meta->make_immutable;
142              
143             sub _to_code {
144 0     0     my($self, $char) = @_;
145 0           return $self->_char_code->{uc($char)};
146             }
147              
148             sub _find_bar_by_check {
149 0     0     my($self, $check) = @_;
150 0           my $code = $self->_char_code;
151 0           for my $v (values %$code) {
152 0 0         next unless exists $v->{check};
153 0           my $val = $v->{check};
154 0 0         next if ref($val) eq 'ARRAY';
155 0 0         next if $val != $check;
156 0           return $v->{bar};
157             }
158             }
159              
160             sub draw {
161 0     0 1   my $self = shift;
162 0           my $bars = $self->make_bars;
163 0           for my $bar (@$bars) {
164 0           $self->_draw_num(split //, $bar);
165             }
166 0           return $self->_base;
167             }
168              
169             sub make_bars {
170 0     0 0   my $self = shift;
171 0 0         unless ($self->zipcode =~ /^\d{7}$/) {
172 0           croak('Invalid zipcode(): ' . $self->zipcode);
173             }
174 0 0         unless ($self->address =~ /^[-0-9A-Z]*$/i) {
175 0           croak('Invalid address(): ' . $self->zipcode);
176             }
177 0           my @bars = ();
178 0           my $checksum = 0;
179              
180 0           my $start = $self->_to_code('STC');
181 0           push @bars, $start->{bar};
182              
183 0           for my $chr (split //, $self->zipcode) {
184 0           my $code = $self->_to_code($chr);
185 0           $checksum += $code->{check};
186 0           push @bars, $code->{bar};
187             }
188              
189 0           for my $chr (split //, $self->address) {
190 0           my $code = $self->_to_code($chr);
191 0           my $check = $code->{check};
192 0 0         if (ref($check) eq 'ARRAY') {
193 0           my $bar = $code->{bar};
194 0           for my $i (0 .. $#{$check}) {
  0            
195 0           my $c = $check->[$i];
196 0           my $b = $bar->[$i];
197 0           $checksum += $c;
198 0           push @bars, $b;
199 0 0         last if @bars >= 21;
200             }
201             }
202             else {
203 0           $checksum += $code->{check};
204 0           push @bars, $code->{bar};
205             }
206 0 0         last if @bars >= 21;
207             }
208              
209 0           while (scalar(@bars) < 21) {
210 0           my $code = $self->_to_code('CC4');
211 0           $checksum += $code->{check};
212 0           push @bars, $code->{bar};
213             }
214              
215 0           my $checkdigit = 19 - ($checksum % 19);
216 0           my $bar = $self->_find_bar_by_check($checkdigit);
217 0           push @bars, $bar;
218              
219 0           my $stop = $self->_to_code('SPC');
220 0           push @bars, $stop->{bar};
221 0           return \@bars;
222             }
223              
224             sub _build__base {
225 0     0     my $self = shift;
226 0           my $img = Imager->new(
227             xsize => 979,
228             ysize => 90,
229             );
230 0           $img->settag(name => 'i_xres', value => 300);
231 0           $img->settag(name => 'i_xres', value => 300);
232 0           $img->box(filled => 1, color => '#ffffff');
233 0           return $img;
234             }
235              
236             sub _draw_num {
237 0     0     my $self = shift;
238 0           my @nums = @_;
239 0           for my $num (@nums) {
240 0           my $pos = $self->_pos;
241 0           my $x = 24 + $pos * 14;
242 0 0         my $ymin = $num =~ m{^[12]$} ? 24 : 37;
243             my $ymax = +{
244             1 => $ymin + 41,
245             2 => $ymin + 27,
246             3 => $ymin + 27,
247             4 => $ymin + 13,
248 0           }->{$num};
249 0           $self->_base->box(
250             xmin => $x,
251             ymin => $ymin,
252             xmax => $x + 6,
253             ymax => $ymax,
254             color => '#000000',
255             filled => 1,
256             );
257 0           $self->_pos($self->_pos + 1);
258             }
259             }
260              
261             1;
262             __END__