File Coverage

/root/.cpan/build/Imager-1.019-0/blib/lib/Imager/Test.pm
Criterion Covered Total %
statement 268 463 57.8
branch 49 118 41.5
condition 6 28 21.4
subroutine 35 40 87.5
pod 29 29 100.0
total 387 678 57.0


line stmt bran cond sub pod time code
1             package Imager::Test;
2 37     37   736847 use 5.006;
  37         152  
3 37     37   171 use strict;
  37         68  
  37         697  
4 37     37   3534 use Imager;
  37         58  
  37         177  
5 37     37   1286 use Test::More;
  37         105105  
  37         269  
6 37     37   8432 use Test::Builder;
  37         68  
  37         1090  
7             require Exporter;
8 37     37   211 use Carp qw(croak carp);
  37         71  
  37         1540  
9 37     37   192 use Config;
  37         86  
  37         138787  
10              
11             our $VERSION = "1.007";
12              
13             our @ISA = qw(Exporter);
14             our @EXPORT_OK =
15             qw(
16             diff_text_with_nul
17             test_image_raw
18             test_image_16
19             test_image
20             test_image_double
21             test_image_mono
22             test_image_gray
23             test_image_gray_16
24             test_image_named
25             is_color1
26             is_color3
27             is_color4
28             is_color_close3
29             is_fcolor1
30             is_fcolor3
31             is_fcolor4
32             color_cmp
33             is_image
34             is_imaged
35             is_image_similar
36             isnt_image
37             image_bounds_checks
38             mask_tests
39             test_colorf_gpix
40             test_color_gpix
41             test_colorf_glin
42             can_test_threads
43             std_font_tests
44             std_font_test_count
45             );
46              
47             sub diff_text_with_nul {
48 0     0 1 0 my ($desc, $text1, $text2, @params) = @_;
49              
50 0         0 my $builder = Test::Builder->new;
51              
52 0         0 print "# $desc\n";
53 0         0 my $imbase = Imager->new(xsize => 100, ysize => 100);
54 0         0 my $imcopy = Imager->new(xsize => 100, ysize => 100);
55              
56 0         0 $builder->ok($imbase->string(x => 5, 'y' => 50, size => 20,
57             string => $text1,
58             @params), "$desc - draw text1");
59 0         0 $builder->ok($imcopy->string(x => 5, 'y' => 50, size => 20,
60             string => $text2,
61             @params), "$desc - draw text2");
62 0         0 $builder->isnt_num(Imager::i_img_diff($imbase->{IMG}, $imcopy->{IMG}), 0,
63             "$desc - check result different");
64             }
65              
66             sub is_color3($$$$$) {
67 207     207 1 129061 my ($color, $red, $green, $blue, $comment) = @_;
68              
69 207         662 my $builder = Test::Builder->new;
70              
71 207 50       1291 unless (defined $color) {
72 0         0 $builder->ok(0, $comment);
73 0         0 $builder->diag("color is undef");
74 0         0 return;
75             }
76 207 50       834 unless ($color->can('rgba')) {
77 0         0 $builder->ok(0, $comment);
78 0         0 $builder->diag("color is not a color object");
79 0         0 return;
80             }
81              
82 207         698 my ($cr, $cg, $cb) = $color->rgba;
83 207 50 33     1488 unless ($builder->ok($cr == $red && $cg == $green && $cb == $blue, $comment)) {
84 0         0 print <
85             Color mismatch:
86             Red: $red vs $cr
87             Green: $green vs $cg
88             Blue: $blue vs $cb
89             END_DIAG
90 0         0 return;
91             }
92              
93 207         63322 return 1;
94             }
95              
96             sub is_color_close3($$$$$$) {
97 0     0 1 0 my ($color, $red, $green, $blue, $tolerance, $comment) = @_;
98              
99 0         0 my $builder = Test::Builder->new;
100              
101 0 0       0 unless (defined $color) {
102 0         0 $builder->ok(0, $comment);
103 0         0 $builder->diag("color is undef");
104 0         0 return;
105             }
106 0 0       0 unless ($color->can('rgba')) {
107 0         0 $builder->ok(0, $comment);
108 0         0 $builder->diag("color is not a color object");
109 0         0 return;
110             }
111              
112 0         0 my ($cr, $cg, $cb) = $color->rgba;
113 0 0 0     0 unless ($builder->ok(abs($cr - $red) <= $tolerance
114             && abs($cg - $green) <= $tolerance
115             && abs($cb - $blue) <= $tolerance, $comment)) {
116 0         0 $builder->diag(<
117             Color out of tolerance ($tolerance):
118             Red: expected $red vs received $cr
119             Green: expected $green vs received $cg
120             Blue: expected $blue vs received $cb
121             END_DIAG
122 0         0 return;
123             }
124              
125 0         0 return 1;
126             }
127              
128             sub is_color4($$$$$$) {
129 116     116 1 3192 my ($color, $red, $green, $blue, $alpha, $comment) = @_;
130              
131 116         324 my $builder = Test::Builder->new;
132              
133 116 50       693 unless (defined $color) {
134 0         0 $builder->ok(0, $comment);
135 0         0 $builder->diag("color is undef");
136 0         0 return;
137             }
138 116 50       429 unless ($color->can('rgba')) {
139 0         0 $builder->ok(0, $comment);
140 0         0 $builder->diag("color is not a color object");
141 0         0 return;
142             }
143              
144 116         370 my ($cr, $cg, $cb, $ca) = $color->rgba;
145 116 50 33     666 unless ($builder->ok($cr == $red && $cg == $green && $cb == $blue
146             && $ca == $alpha, $comment)) {
147 0         0 $builder->diag(<
148             Color mismatch:
149             Red: $cr vs $red
150             Green: $cg vs $green
151             Blue: $cb vs $blue
152             Alpha: $ca vs $alpha
153             END_DIAG
154 0         0 return;
155             }
156              
157 116         45074 return 1;
158             }
159              
160             sub is_fcolor4($$$$$$;$) {
161 68     68 1 443 my ($color, $red, $green, $blue, $alpha, $comment_or_diff, $comment_or_undef) = @_;
162 68         90 my ($comment, $mindiff);
163 68 100       119 if (defined $comment_or_undef) {
164 2         4 ( $mindiff, $comment ) = ( $comment_or_diff, $comment_or_undef )
165             }
166             else {
167 66         100 ( $mindiff, $comment ) = ( 0.001, $comment_or_diff )
168             }
169              
170 68         188 my $builder = Test::Builder->new;
171              
172 68 50       374 unless (defined $color) {
173 0         0 $builder->ok(0, $comment);
174 0         0 $builder->diag("color is undef");
175 0         0 return;
176             }
177 68 50       224 unless ($color->can('rgba')) {
178 0         0 $builder->ok(0, $comment);
179 0         0 $builder->diag("color is not a color object");
180 0         0 return;
181             }
182              
183 68         209 my ($cr, $cg, $cb, $ca) = $color->rgba;
184 68 50 33     475 unless ($builder->ok(abs($cr - $red) <= $mindiff
185             && abs($cg - $green) <= $mindiff
186             && abs($cb - $blue) <= $mindiff
187             && abs($ca - $alpha) <= $mindiff, $comment)) {
188 0         0 $builder->diag(<
189             Color mismatch:
190             Red: $cr vs $red
191             Green: $cg vs $green
192             Blue: $cb vs $blue
193             Alpha: $ca vs $alpha
194             END_DIAG
195 0         0 return;
196             }
197              
198 68         18312 return 1;
199             }
200              
201             sub is_fcolor1($$$;$) {
202 1     1 1 9 my ($color, $grey, $comment_or_diff, $comment_or_undef) = @_;
203 1         2 my ($comment, $mindiff);
204 1 50       3 if (defined $comment_or_undef) {
205 1         2 ( $mindiff, $comment ) = ( $comment_or_diff, $comment_or_undef )
206             }
207             else {
208 0         0 ( $mindiff, $comment ) = ( 0.001, $comment_or_diff )
209             }
210              
211 1         4 my $builder = Test::Builder->new;
212              
213 1 50       8 unless (defined $color) {
214 0         0 $builder->ok(0, $comment);
215 0         0 $builder->diag("color is undef");
216 0         0 return;
217             }
218 1 50       4 unless ($color->can('rgba')) {
219 0         0 $builder->ok(0, $comment);
220 0         0 $builder->diag("color is not a color object");
221 0         0 return;
222             }
223              
224 1         4 my ($cgrey) = $color->rgba;
225 1 50       5 unless ($builder->ok(abs($cgrey - $grey) <= $mindiff, $comment)) {
226 0         0 print <
227             Color mismatch:
228             Gray: $cgrey vs $grey
229             END_DIAG
230 0         0 return;
231             }
232              
233 1         272 return 1;
234             }
235              
236             sub is_fcolor3($$$$$;$) {
237 25     25 1 2708 my ($color, $red, $green, $blue, $comment_or_diff, $comment_or_undef) = @_;
238 25         35 my ($comment, $mindiff);
239 25 100       51 if (defined $comment_or_undef) {
240 9         19 ( $mindiff, $comment ) = ( $comment_or_diff, $comment_or_undef )
241             }
242             else {
243 16         27 ( $mindiff, $comment ) = ( 0.001, $comment_or_diff )
244             }
245              
246 25         65 my $builder = Test::Builder->new;
247              
248 25 50       159 unless (defined $color) {
249 0         0 $builder->ok(0, $comment);
250 0         0 $builder->diag("color is undef");
251 0         0 return;
252             }
253 25 50       99 unless ($color->can('rgba')) {
254 0         0 $builder->ok(0, $comment);
255 0         0 $builder->diag("color is not a color object");
256 0         0 return;
257             }
258              
259 25         98 my ($cr, $cg, $cb) = $color->rgba;
260 25 50 33     181 unless ($builder->ok(abs($cr - $red) <= $mindiff
261             && abs($cg - $green) <= $mindiff
262             && abs($cb - $blue) <= $mindiff, $comment)) {
263 0         0 $builder->diag(<
264             Color mismatch:
265             Red: $cr vs $red
266             Green: $cg vs $green
267             Blue: $cb vs $blue
268             END_DIAG
269 0         0 return;
270             }
271              
272 25         6270 return 1;
273             }
274              
275             sub is_color1($$$) {
276 1     1 1 5 my ($color, $grey, $comment) = @_;
277              
278 1         5 my $builder = Test::Builder->new;
279              
280 1 50       9 unless (defined $color) {
281 0         0 $builder->ok(0, $comment);
282 0         0 $builder->diag("color is undef");
283 0         0 return;
284             }
285 1 50       6 unless ($color->can('rgba')) {
286 0         0 $builder->ok(0, $comment);
287 0         0 $builder->diag("color is not a color object");
288 0         0 return;
289             }
290              
291 1         6 my ($cgrey) = $color->rgba;
292 1 50       4 unless ($builder->ok($cgrey == $grey, $comment)) {
293 0         0 $builder->diag(<
294             Color mismatch:
295             Grey: $grey vs $cgrey
296             END_DIAG
297 0         0 return;
298             }
299              
300 1         324 return 1;
301             }
302              
303             sub test_image_raw {
304 2     2 1 32 my $green=Imager::i_color_new(0,255,0,255);
305 2         12 my $blue=Imager::i_color_new(0,0,255,255);
306 2         10 my $red=Imager::i_color_new(255,0,0,255);
307            
308 2         443 my $img=Imager::ImgRaw::new(150,150,3);
309            
310 2         405 Imager::i_box_filled($img,70,25,130,125,$green);
311 2         329 Imager::i_box_filled($img,20,25,80,125,$blue);
312 2         12976 Imager::i_arc($img,75,75,30,0,361,$red);
313 2         23817 Imager::i_conv($img,[0.1, 0.2, 0.4, 0.2, 0.1]);
314              
315 2         375 $img;
316             }
317              
318             sub test_image {
319 25     25 1 502 my $green = Imager::Color->new(0, 255, 0, 255);
320 25         132 my $blue = Imager::Color->new(0, 0, 255, 255);
321 25         116 my $red = Imager::Color->new(255, 0, 0, 255);
322 25         153 my $img = Imager->new(xsize => 150, ysize => 150);
323 25         173 $img->box(filled => 1, color => $green, box => [ 70, 24, 130, 124 ]);
324 25         201 $img->box(filled => 1, color => $blue, box => [ 20, 26, 80, 126 ]);
325 25         153 $img->arc(x => 75, y => 75, r => 30, color => $red);
326 25         242 $img->filter(type => 'conv', coef => [ 0.1, 0.2, 0.4, 0.2, 0.1 ]);
327              
328 25         3332 $img;
329             }
330              
331             sub test_image_16 {
332 4     4 1 57 my $green = Imager::Color->new(0, 255, 0, 255);
333 4         15 my $blue = Imager::Color->new(0, 0, 255, 255);
334 4         17 my $red = Imager::Color->new(255, 0, 0, 255);
335 4         23 my $img = Imager->new(xsize => 150, ysize => 150, bits => 16);
336 4         24 $img->box(filled => 1, color => $green, box => [ 70, 24, 130, 124 ]);
337 4         21 $img->box(filled => 1, color => $blue, box => [ 20, 26, 80, 126 ]);
338 4         23 $img->arc(x => 75, y => 75, r => 30, color => $red);
339 4         35 $img->filter(type => 'conv', coef => [ 0.1, 0.2, 0.4, 0.2, 0.1 ]);
340              
341 4         323 $img;
342             }
343              
344             sub test_image_double {
345 4     4 1 31 my $green = Imager::Color->new(0, 255, 0, 255);
346 4         15 my $blue = Imager::Color->new(0, 0, 255, 255);
347 4         19 my $red = Imager::Color->new(255, 0, 0, 255);
348 4         16 my $img = Imager->new(xsize => 150, ysize => 150, bits => 'double');
349 4         31 $img->box(filled => 1, color => $green, box => [ 70, 24, 130, 124 ]);
350 4         20 $img->box(filled => 1, color => $blue, box => [ 20, 26, 80, 126 ]);
351 4         18 $img->arc(x => 75, y => 75, r => 30, color => $red);
352 4         23 $img->filter(type => 'conv', coef => [ 0.1, 0.2, 0.4, 0.2, 0.1 ]);
353              
354 4         170 $img;
355             }
356              
357             sub test_image_gray {
358 3     3 1 22 my $g50 = Imager::Color->new(128, 128, 128);
359 3         29 my $g30 = Imager::Color->new(76, 76, 76);
360 3         11 my $g70 = Imager::Color->new(178, 178, 178);
361 3         15 my $img = Imager->new(xsize => 150, ysize => 150, channels => 1);
362 3         19 $img->box(filled => 1, color => $g50, box => [ 70, 24, 130, 124 ]);
363 3         41 $img->box(filled => 1, color => $g30, box => [ 20, 26, 80, 126 ]);
364 3         14 $img->arc(x => 75, y => 75, r => 30, color => $g70);
365 3         27 $img->filter(type => 'conv', coef => [ 0.1, 0.2, 0.4, 0.2, 0.1 ]);
366              
367 3         166 return $img;
368             }
369              
370             sub test_image_gray_16 {
371 3     3 1 23 my $g50 = Imager::Color->new(128, 128, 128);
372 3         12 my $g30 = Imager::Color->new(76, 76, 76);
373 3         11 my $g70 = Imager::Color->new(178, 178, 178);
374 3         17 my $img = Imager->new(xsize => 150, ysize => 150, channels => 1, bits => 16);
375 3         16 $img->box(filled => 1, color => $g50, box => [ 70, 24, 130, 124 ]);
376 3         17 $img->box(filled => 1, color => $g30, box => [ 20, 26, 80, 126 ]);
377 3         13 $img->arc(x => 75, y => 75, r => 30, color => $g70);
378 3         24 $img->filter(type => 'conv', coef => [ 0.1, 0.2, 0.4, 0.2, 0.1 ]);
379              
380 3         168 return $img;
381             }
382              
383             sub test_image_mono {
384 4     4 1 1846 require Imager::Fill;
385 4         26 my $fh = Imager::Fill->new(hatch => 'check1x1');
386 4         23 my $img = Imager->new(xsize => 150, ysize => 150, type => "paletted");
387 4         17 my $black = Imager::Color->new(0, 0, 0);
388 4         87 my $white = Imager::Color->new(255, 255, 255);
389 4         29 $img->addcolors(colors => [ $black, $white ]);
390 4         27 $img->box(fill => $fh, box => [ 70, 24, 130, 124 ]);
391 4         65 $img->box(filled => 1, color => $white, box => [ 20, 26, 80, 126 ]);
392 4         21 $img->arc(x => 75, y => 75, r => 30, color => $black, aa => 0);
393              
394 4         334 return $img;
395             }
396              
397             my %name_to_sub =
398             (
399             basic => \&test_image,
400             basic16 => \&test_image_16,
401             basic_double => \&test_image_double,
402             gray => \&test_image_gray,
403             gray16 => \&test_image_gray_16,
404             mono => \&test_image_mono,
405             );
406              
407             sub test_image_named {
408 11 50   11 1 528 my $name = shift
409             or croak("No name supplied to test_image_named()");
410 11 50       38 my $sub = $name_to_sub{$name}
411             or croak("Unknown name $name supplied to test_image_named()");
412              
413 11         30 return $sub->();
414             }
415              
416             sub _low_image_diff_check {
417 251     251   441 my ($left, $right, $comment) = @_;
418              
419 251         681 my $builder = Test::Builder->new;
420              
421 251 50       1511 unless (defined $left) {
422 0         0 $builder->ok(0, $comment);
423 0         0 $builder->diag("left is undef");
424 0         0 return;
425             }
426 251 50       435 unless (defined $right) {
427 0         0 $builder->ok(0, $comment);
428 0         0 $builder->diag("right is undef");
429 0         0 return;
430             }
431 251 50       633 unless ($left->{IMG}) {
432 0         0 $builder->ok(0, $comment);
433 0         0 $builder->diag("left image has no low level object");
434 0         0 return;
435             }
436 251 50       529 unless ($right->{IMG}) {
437 0         0 $builder->ok(0, $comment);
438 0         0 $builder->diag("right image has no low level object");
439 0         0 return;
440             }
441 251 50       671 unless ($left->getwidth == $right->getwidth) {
442 0         0 $builder->ok(0, $comment);
443 0         0 $builder->diag("left width " . $left->getwidth . " vs right width "
444             . $right->getwidth);
445 0         0 return;
446             }
447 251 50       591 unless ($left->getheight == $right->getheight) {
448 0         0 $builder->ok(0, $comment);
449 0         0 $builder->diag("left height " . $left->getheight . " vs right height "
450             . $right->getheight);
451 0         0 return;
452             }
453 251 50       649 unless ($left->getchannels == $right->getchannels) {
454 0         0 $builder->ok(0, $comment);
455 0         0 $builder->diag("left channels " . $left->getchannels . " vs right channels "
456             . $right->getchannels);
457 0         0 return;
458             }
459              
460 251         589 return 1;
461             }
462              
463             sub is_image_similar($$$$) {
464 222     222 1 446 my ($left, $right, $limit, $comment) = @_;
465              
466             {
467 222         339 local $Test::Builder::Level = $Test::Builder::Level + 1;
  222         324  
468              
469 222 50       508 _low_image_diff_check($left, $right, $comment)
470             or return;
471             }
472              
473 222         490 my $builder = Test::Builder->new;
474              
475 222         93706 my $diff = Imager::i_img_diff($left->{IMG}, $right->{IMG});
476 222 50       772 if ($diff > $limit) {
477 0         0 $builder->ok(0, $comment);
478 0         0 $builder->diag("image data difference > $limit - $diff");
479            
480 0 0       0 if ($limit == 0) {
481             # find the first mismatch
482             PIXELS:
483 0         0 for my $y (0 .. $left->getheight()-1) {
484 0         0 for my $x (0.. $left->getwidth()-1) {
485 0         0 my @lsamples = $left->getsamples(x => $x, y => $y, width => 1);
486 0         0 my @rsamples = $right->getsamples(x => $x, y => $y, width => 1);
487 0 0       0 if ("@lsamples" ne "@rsamples") {
488 0         0 $builder->diag("first mismatch at ($x, $y) - @lsamples vs @rsamples");
489 0         0 last PIXELS;
490             }
491             }
492             }
493             }
494              
495 0         0 return;
496             }
497            
498 222         697 return $builder->ok(1, $comment);
499             }
500              
501             sub is_image($$$) {
502 217     217 1 2786 my ($left, $right, $comment) = @_;
503              
504 217         363 local $Test::Builder::Level = $Test::Builder::Level + 1;
505              
506 217         522 return is_image_similar($left, $right, 0, $comment);
507             }
508              
509             sub is_imaged($$$;$) {
510 29     29 1 128 my $epsilon = Imager::i_img_epsilonf();
511 29 50       86 if (@_ > 3) {
512 0         0 ($epsilon) = splice @_, 2, 1;
513             }
514              
515 29         72 my ($left, $right, $comment) = @_;
516              
517             {
518 29         42 local $Test::Builder::Level = $Test::Builder::Level + 1;
  29         50  
519              
520 29 50       79 _low_image_diff_check($left, $right, $comment)
521             or return;
522             }
523              
524 29         156 my $builder = Test::Builder->new;
525              
526 29         19598 my $same = Imager::i_img_samef($left->{IMG}, $right->{IMG}, $epsilon, $comment);
527 29 50       131 if (!$same) {
528 0         0 $builder->ok(0, $comment);
529 0         0 $builder->diag("images different");
530              
531             # find the first mismatch
532             PIXELS:
533 0         0 for my $y (0 .. $left->getheight()-1) {
534 0         0 for my $x (0.. $left->getwidth()-1) {
535 0         0 my @lsamples = $left->getsamples(x => $x, y => $y, width => 1, type => "float");
536 0         0 my @rsamples = $right->getsamples(x => $x, y => $y, width => 1, type => "float");
537 0 0       0 if ("@lsamples" ne "@rsamples") {
538 0         0 $builder->diag("first mismatch at ($x, $y) - @lsamples vs @rsamples");
539 0         0 last PIXELS;
540             }
541             }
542             }
543              
544 0         0 return;
545             }
546            
547 29         109 return $builder->ok(1, $comment);
548             }
549              
550             sub isnt_image {
551 2     2 1 21 my ($left, $right, $comment) = @_;
552              
553 2         9 my $builder = Test::Builder->new;
554              
555 2         1055 my $diff = Imager::i_img_diff($left->{IMG}, $right->{IMG});
556              
557 2         17 return $builder->ok($diff, "$comment");
558             }
559              
560             sub image_bounds_checks {
561 4     4 1 26 my $im = shift;
562              
563 4         14 my $builder = Test::Builder->new;
564              
565 4         40 $builder->ok(!$im->getpixel(x => -1, y => 0), 'bounds check get (-1, 0)');
566 4         1077 $builder->ok(!$im->getpixel(x => 10, y => 0), 'bounds check get (10, 0)');
567 4         1007 $builder->ok(!$im->getpixel(x => 0, y => -1), 'bounds check get (0, -1)');
568 4         1011 $builder->ok(!$im->getpixel(x => 0, y => 10), 'bounds check get (0, 10)');
569 4         1048 $builder->ok(!$im->getpixel(x => -1, y => 0), 'bounds check get (-1, 0) float');
570 4         1010 $builder->ok(!$im->getpixel(x => 10, y => 0), 'bounds check get (10, 0) float');
571 4         987 $builder->ok(!$im->getpixel(x => 0, y => -1), 'bounds check get (0, -1) float');
572 4         1040 $builder->ok(!$im->getpixel(x => 0, y => 10), 'bounds check get (0, 10) float');
573 4         993 my $black = Imager::Color->new(0, 0, 0);
574 4         35 require Imager::Color::Float;
575 4         28 my $blackf = Imager::Color::Float->new(0, 0, 0);
576 4         29 $builder->ok($im->setpixel(x => -1, y => 0, color => $black) == 0,
577             'bounds check set (-1, 0)');
578 4         1034 $builder->ok($im->setpixel(x => 10, y => 0, color => $black) == 0,
579             'bounds check set (10, 0)');
580 4         952 $builder->ok($im->setpixel(x => 0, y => -1, color => $black) == 0,
581             'bounds check set (0, -1)');
582 4         969 $builder->ok($im->setpixel(x => 0, y => 10, color => $black) == 0,
583             'bounds check set (0, 10)');
584 4         980 $builder->ok($im->setpixel(x => -1, y => 0, color => $blackf) == 0,
585             'bounds check set (-1, 0) float');
586 4         974 $builder->ok($im->setpixel(x => 10, y => 0, color => $blackf) == 0,
587             'bounds check set (10, 0) float');
588 4         966 $builder->ok($im->setpixel(x => 0, y => -1, color => $blackf) == 0,
589             'bounds check set (0, -1) float');
590 4         992 $builder->ok($im->setpixel(x => 0, y => 10, color => $blackf) == 0,
591             'bounds check set (0, 10) float');
592             }
593              
594             sub test_colorf_gpix {
595 21     21 1 12821 my ($im, $x, $y, $expected, $epsilon, $comment) = @_;
596              
597 21         65 my $builder = Test::Builder->new;
598            
599 21 100       130 defined $comment or $comment = '';
600              
601 21         804 my $c = Imager::i_gpixf($im, $x, $y);
602 21 50       85 unless ($c) {
603 0         0 $builder->ok(0, "$comment - retrieve color at ($x,$y)");
604 0         0 return;
605             }
606 21 50       50 unless ($builder->ok(colorf_cmp($c, $expected, $epsilon) == 0,
607             "$comment - got right color ($x, $y)")) {
608 0         0 my @c = $c->rgba;
609 0         0 my @exp = $expected->rgba;
610 0         0 $builder->diag(<
611             # got: ($c[0], $c[1], $c[2])
612             # expected: ($exp[0], $exp[1], $exp[2])
613             EOS
614             }
615 21         7472 1;
616             }
617              
618             sub test_color_gpix {
619 12     12 1 29 my ($im, $x, $y, $expected, $comment) = @_;
620              
621 12         35 my $builder = Test::Builder->new;
622            
623 12 50       80 defined $comment or $comment = '';
624 12         465 my $c = Imager::i_get_pixel($im, $x, $y);
625 12 50       53 unless ($c) {
626 0         0 $builder->ok(0, "$comment - retrieve color at ($x,$y)");
627 0         0 return;
628             }
629 12 50       35 unless ($builder->ok(color_cmp($c, $expected) == 0,
630             "got right color ($x, $y)")) {
631 0         0 my @c = $c->rgba;
632 0         0 my @exp = $expected->rgba;
633 0         0 $builder->diag(<
634             # got: ($c[0], $c[1], $c[2])
635             # expected: ($exp[0], $exp[1], $exp[2])
636             EOS
637 0         0 return;
638             }
639              
640 12         3907 return 1;
641             }
642              
643             sub test_colorf_glin {
644 6     6 1 1360 my ($im, $x, $y, $pels, $comment) = @_;
645              
646 6         19 my $builder = Test::Builder->new;
647            
648 6         13695 my @got = Imager::i_glinf($im, $x, $x+@$pels, $y);
649 6 50       28 @got == @$pels
650             or return $builder->is_num(scalar(@got), scalar(@$pels), "$comment - pixels retrieved");
651            
652 6         48 return $builder->ok(!grep(colorf_cmp($pels->[$_], $got[$_], 0.005), 0..$#got),
653             "$comment - check colors ($x, $y)");
654             }
655              
656             sub colorf_cmp {
657 621     621 1 814 my ($c1, $c2, $epsilon) = @_;
658              
659 621 100       820 defined $epsilon or $epsilon = 0;
660              
661 621         1109 my @s1 = $c1->rgba;
662 621         896 my @s2 = $c2->rgba;
663              
664             # print "# (",join(",", @s1[0..2]),") <=> (",join(",", @s2[0..2]),")\n";
665 621   33     3043 return abs($s1[0]-$s2[0]) >= $epsilon && $s1[0] <=> $s2[0]
666             || abs($s1[1]-$s2[1]) >= $epsilon && $s1[1] <=> $s2[1]
667             || abs($s1[2]-$s2[2]) >= $epsilon && $s1[2] <=> $s2[2];
668             }
669              
670             sub color_cmp {
671 18     18 1 9032 my ($c1, $c2) = @_;
672              
673 18         59 my @s1 = $c1->rgba;
674 18         43 my @s2 = $c2->rgba;
675              
676 18   33     156 return $s1[0] <=> $s2[0]
677             || $s1[1] <=> $s2[1]
678             || $s1[2] <=> $s2[2];
679             }
680              
681             # these test the action of the channel mask on the image supplied
682             # which should be an OO image.
683             sub mask_tests {
684 3     3 1 24 my ($im, $epsilon) = @_;
685              
686 37     37   376 no if $] >= 5.014, warnings => 'Imager::channelmask';
  37         98  
  37         343  
687 3         13 my $builder = Test::Builder->new;
688              
689 3 100       25 defined $epsilon or $epsilon = 0;
690              
691             # we want to check all four of ppix() and plin(), ppix() and plinf()
692             # basic test procedure:
693             # first using default/all 1s mask, set to white
694             # make sure we got white
695             # set mask to skip a channel, set to grey
696             # make sure only the right channels set
697              
698 3         199 print "# channel mask tests\n";
699             # 8-bit color tests
700 3         24 my $white = Imager::NC(255, 255, 255);
701 3         42 my $grey = Imager::NC(128, 128, 128);
702 3         26 my $white_grey = Imager::NC(128, 255, 128);
703              
704 3         160 print "# with ppix\n";
705 3         29 $builder->ok($im->setmask(mask=>~0), "set to default mask");
706 3         852 $builder->ok($im->setpixel(x=>0, 'y'=>0, color=>$white), "set to white all channels");
707 3         783 test_color_gpix($im->{IMG}, 0, 0, $white, "ppix");
708 3         19 $builder->ok($im->setmask(mask=>0xF-0x2), "set channel to exclude channel1");
709 3         793 $builder->ok($im->setpixel(x=>0, 'y'=>0, color=>$grey), "set to grey, no channel 2");
710 3         758 test_color_gpix($im->{IMG}, 0, 0, $white_grey, "ppix masked");
711              
712 3         113 print "# with plin\n";
713 3         31 $builder->ok($im->setmask(mask=>~0), "set to default mask");
714 3         820 $builder->ok($im->setscanline(x=>0, 'y'=>1, pixels => [$white]),
715             "set to white all channels");
716 3         894 test_color_gpix($im->{IMG}, 0, 1, $white, "plin");
717 3         35 $builder->ok($im->setmask(mask=>0xF-0x2), "set channel to exclude channel1");
718 3         792 $builder->ok($im->setscanline(x=>0, 'y'=>1, pixels=>[$grey]),
719             "set to grey, no channel 2");
720 3         774 test_color_gpix($im->{IMG}, 0, 1, $white_grey, "plin masked");
721              
722             # float color tests
723 3         22 my $whitef = Imager::NCF(1.0, 1.0, 1.0);
724 3         49 my $greyf = Imager::NCF(0.5, 0.5, 0.5);
725 3         14 my $white_greyf = Imager::NCF(0.5, 1.0, 0.5);
726              
727 3         157 print "# with ppixf\n";
728 3         30 $builder->ok($im->setmask(mask=>~0), "set to default mask");
729 3         784 $builder->ok($im->setpixel(x=>0, 'y'=>2, color=>$whitef), "set to white all channels");
730 3         804 test_colorf_gpix($im->{IMG}, 0, 2, $whitef, $epsilon, "ppixf");
731 3         31 $builder->ok($im->setmask(mask=>0xF-0x2), "set channel to exclude channel1");
732 3         804 $builder->ok($im->setpixel(x=>0, 'y'=>2, color=>$greyf), "set to grey, no channel 2");
733 3         830 test_colorf_gpix($im->{IMG}, 0, 2, $white_greyf, $epsilon, "ppixf masked");
734              
735 3         115 print "# with plinf\n";
736 3         19 $builder->ok($im->setmask(mask=>~0), "set to default mask");
737 3         794 $builder->ok($im->setscanline(x=>0, 'y'=>3, pixels => [$whitef]),
738             "set to white all channels");
739 3         808 test_colorf_gpix($im->{IMG}, 0, 3, $whitef, $epsilon, "plinf");
740 3         26 $builder->ok($im->setmask(mask=>0xF-0x2), "set channel to exclude channel1");
741 3         774 $builder->ok($im->setscanline(x=>0, 'y'=>3, pixels=>[$greyf]),
742             "set to grey, no channel 2");
743 3         802 test_colorf_gpix($im->{IMG}, 0, 3, $white_greyf, $epsilon, "plinf masked");
744              
745             }
746              
747             sub std_font_test_count {
748 0     0 1   return 21;
749             }
750              
751             sub std_font_tests {
752 0     0 1   my ($opts) = @_;
753              
754             my $font = $opts->{font}
755 0 0         or carp "Missing font parameter";
756              
757 0   0       my $name_font = $opts->{glyph_name_font} || $font;
758              
759 0   0       my $has_chars = $opts->{has_chars} || [ 1, '', 1 ];
760              
761 0   0       my $glyph_names = $opts->{glyph_names} || [ "A", undef, "A" ];
762              
763             SKIP:
764             { # check magic is handled correctly
765             # https://rt.cpan.org/Ticket/Display.html?id=83438
766 0 0         skip("no native UTF8 support in this version of perl", 11)
767             unless $] >= 5.006;
768 0 0         skip("overloading handling of magic is broken in this version of perl", 11)
769             unless $] >= 5.008;
770 0           Imager->log("utf8 magic tests\n");
771 0           my $over = bless {}, "Imager::Test::OverUtf8";
772 0           my $text = "A".chr(0x2010)."A";
773 0           my $white = Imager::Color->new("#FFF");
774 0           my $base_draw = Imager->new(xsize => 80, ysize => 20);
775 0           ok($base_draw->string(font => $font,
776             text => $text,
777             x => 2,
778             y => 18,
779             size => 15,
780             color => $white,
781             aa => 1),
782             "magic: make a base image");
783 0           my $test_draw = Imager->new(xsize => 80, ysize => 20);
784 0           ok($test_draw->string(font => $font,
785             text => $over,
786             x => 2,
787             y => 18,
788             size => 15,
789             color => $white,
790             aa => 1),
791             "magic: draw with overload");
792 0           is_image($base_draw, $test_draw, "check they match");
793 0 0         if ($opts->{files}) {
794 0           $test_draw->write(file => "testout/utf8tdr.ppm");
795 0           $base_draw->write(file => "testout/utf8bdr.ppm");
796             }
797              
798 0           my $base_cp = Imager->new(xsize => 80, ysize => 20);
799 0           $base_cp->box(filled => 1, color => "#808080");
800 0           my $test_cp = $base_cp->copy;
801 0           ok($base_cp->string(font => $font,
802             text => $text,
803             y => 2,
804             y => 18,
805             size => 16,
806             channel => 2,
807             aa => 1),
808             "magic: make a base image (channel)");
809 0           Imager->log("magic: draw to channel with overload\n");
810 0           ok($test_cp->string(font => $font,
811             text => $over,
812             y => 2,
813             y => 18,
814             size => 16,
815             channel => 2,
816             aa => 1),
817             "magic: draw with overload (channel)");
818 0           is_image($test_cp, $base_cp, "check they match");
819 0 0         if ($opts->{files}) {
820 0           $test_cp->write(file => "testout/utf8tcp.ppm");
821 0           $base_cp->write(file => "testout/utf8bcp.ppm");
822             }
823              
824             SKIP:
825             {
826 0           Imager->log("magic: has_chars\n");
  0            
827 0 0         $font->can("has_chars")
828             or skip "No has_chars aupport", 2;
829 0           is_deeply([ $font->has_chars(string => $text) ], $has_chars,
830             "magic: has_chars with normal utf8 text");
831 0           is_deeply([ $font->has_chars(string => $over) ], $has_chars,
832             "magic: has_chars with magic utf8 text");
833             }
834              
835 0           Imager->log("magic: bounding_box\n");
836 0           my @base_bb = $font->bounding_box(string => $text, size => 30);
837 0           is_deeply([ $font->bounding_box(string => $over, size => 30) ],
838             \@base_bb,
839             "check bounding box magic");
840              
841             SKIP:
842             {
843 0 0         $font->can_glyph_names
  0            
844             or skip "No glyph_names", 2;
845 0           Imager->log("magic: glyph_names\n");
846 0           my @text_names = $name_font->glyph_names(string => $text, reliable_only => 0);
847 0           is_deeply(\@text_names, $glyph_names,
848             "magic: glyph_names with normal utf8 text");
849 0           my @over_names = $name_font->glyph_names(string => $over, reliable_only => 0);
850 0           is_deeply(\@over_names, $glyph_names,
851             "magic: glyph_names with magic utf8 text");
852             }
853             }
854              
855             { # invalid UTF8 handling at the OO level
856 0           my $im = Imager->new(xsize => 80, ysize => 20);
  0            
  0            
857 0           my $bad_utf8 = pack("C", 0xC0);
858 0           Imager->_set_error("");
859 0           ok(!$im->string(font => $font, size => 1, text => $bad_utf8, utf8 => 1,
860             y => 18, x => 2),
861             "drawing invalid utf8 should fail");
862 0           is($im->errstr, "invalid UTF8 character", "check error message");
863 0           Imager->_set_error("");
864 0           ok(!$im->string(font => $font, size => 1, text => $bad_utf8, utf8 => 1,
865             y => 18, x => 2, channel => 1),
866             "drawing invalid utf8 should fail (channel)");
867 0           is($im->errstr, "invalid UTF8 character", "check error message");
868 0           Imager->_set_error("");
869 0           ok(!$font->bounding_box(string => $bad_utf8, size => 30, utf8 => 1),
870             "bounding_box() bad utf8 should fail");
871 0           is(Imager->errstr, "invalid UTF8 character", "check error message");
872             SKIP:
873             {
874 0 0         $font->can_glyph_names
  0            
875             or skip "No glyph_names support", 2;
876 0           Imager->_set_error("");
877 0           is_deeply([ $font->glyph_names(string => $bad_utf8, utf8 => 1) ],
878             [ ],
879             "glyph_names returns empty list for bad string");
880 0           is(Imager->errstr, "invalid UTF8 character", "check error message");
881             }
882             SKIP:
883             {
884 0 0         $font->can("has_chars")
  0            
885             or skip "No has_chars support", 2;
886 0           Imager->_set_error("");
887 0           is_deeply([ $font->has_chars(string => $bad_utf8, utf8 => 1) ],
888             [ ],
889             "has_chars returns empty list for bad string");
890 0           is(Imager->errstr, "invalid UTF8 character", "check error message");
891             }
892             }
893             }
894              
895             package Imager::Test::OverUtf8;
896 37     37   83243 use overload '""' => sub { "A".chr(0x2010)."A" };
  37     0   31056  
  37         327  
  0         0  
897              
898              
899             1;
900              
901             __END__