Commit | Line | Data |
---|---|---|
f1ac5027 TC |
1 | #!perl -w |
2 | use strict; | |
3 | ||
efdc2568 TC |
4 | print "1..34\n"; |
5 | ||
f1ac5027 TC |
6 | use Imager ':handy'; |
7 | use Imager::Fill; | |
8 | use Imager::Color::Float; | |
9 | ||
efdc2568 | 10 | sub ok ($$$); |
f1ac5027 | 11 | |
efdc2568 | 12 | Imager::init_log("testout/t20fill.log", 1); |
f1ac5027 TC |
13 | |
14 | my $blue = NC(0,0,255); | |
15 | my $red = NC(255, 0, 0); | |
16 | my $redf = Imager::Color::Float->new(1, 0, 0); | |
17 | my $rsolid = Imager::i_new_fill_solid($blue, 0); | |
18 | ok(1, $rsolid, "building solid fill"); | |
19 | my $raw1 = Imager::ImgRaw::new(100, 100, 3); | |
20 | # use the normal filled box | |
21 | Imager::i_box_filled($raw1, 0, 0, 99, 99, $blue); | |
22 | my $raw2 = Imager::ImgRaw::new(100, 100, 3); | |
23 | Imager::i_box_cfill($raw2, 0, 0, 99, 99, $rsolid); | |
24 | ok(2, 1, "drawing with solid fill"); | |
25 | my $diff = Imager::i_img_diff($raw1, $raw2); | |
26 | ok(3, $diff == 0, "solid fill doesn't match"); | |
27 | Imager::i_box_filled($raw1, 0, 0, 99, 99, $red); | |
28 | my $rsolid2 = Imager::i_new_fill_solidf($redf, 0); | |
29 | ok(4, $rsolid2, "creating float solid fill"); | |
30 | Imager::i_box_cfill($raw2, 0, 0, 99, 99, $rsolid2); | |
31 | $diff = Imager::i_img_diff($raw1, $raw2); | |
32 | ok(5, $diff == 0, "float solid fill doesn't match"); | |
33 | ||
34 | # ok solid still works, let's try a hatch | |
35 | # hash1 is a 2x2 checkerboard | |
36 | my $rhatcha = Imager::i_new_fill_hatch($red, $blue, 0, 1, undef, 0, 0); | |
37 | my $rhatchb = Imager::i_new_fill_hatch($blue, $red, 0, 1, undef, 2, 0); | |
38 | ok(6, $rhatcha && $rhatchb, "can't build hatched fill"); | |
39 | ||
40 | # the offset should make these match | |
41 | Imager::i_box_cfill($raw1, 0, 0, 99, 99, $rhatcha); | |
42 | Imager::i_box_cfill($raw2, 0, 0, 99, 99, $rhatchb); | |
43 | ok(7, 1, "filling with hatch"); | |
44 | $diff = Imager::i_img_diff($raw1, $raw2); | |
45 | ok(8, $diff == 0, "hatch images different"); | |
46 | $rhatchb = Imager::i_new_fill_hatch($blue, $red, 0, 1, undef, 4, 6); | |
47 | Imager::i_box_cfill($raw2, 0, 0, 99, 99, $rhatchb); | |
48 | $diff = Imager::i_img_diff($raw1, $raw2); | |
49 | ok(9, $diff == 0, "hatch images different"); | |
50 | ||
51 | # I guess I was tired when I originally did this - make sure it keeps | |
52 | # acting the way it's meant to | |
53 | # I had originally expected these to match with the red and blue swapped | |
54 | $rhatchb = Imager::i_new_fill_hatch($red, $blue, 0, 1, undef, 2, 2); | |
55 | Imager::i_box_cfill($raw2, 0, 0, 99, 99, $rhatchb); | |
56 | $diff = Imager::i_img_diff($raw1, $raw2); | |
57 | ok(10, $diff == 0, "hatch images different"); | |
58 | ||
59 | # this shouldn't match | |
60 | $rhatchb = Imager::i_new_fill_hatch($red, $blue, 0, 1, undef, 1, 1); | |
61 | Imager::i_box_cfill($raw2, 0, 0, 99, 99, $rhatchb); | |
62 | $diff = Imager::i_img_diff($raw1, $raw2); | |
63 | ok(11, $diff, "hatch images the same!"); | |
64 | ||
65 | # custom hatch | |
66 | # the inverse of the 2x2 checkerboard | |
67 | my $hatch = pack("C8", 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC); | |
68 | my $rcustom = Imager::i_new_fill_hatch($blue, $red, 0, 0, $hatch, 0, 0); | |
69 | Imager::i_box_cfill($raw2, 0, 0, 99, 99, $rcustom); | |
70 | $diff = Imager::i_img_diff($raw1, $raw2); | |
71 | ok(12, !$diff, "custom hatch mismatch"); | |
72 | ||
73 | # test the oo interface | |
74 | my $im1 = Imager->new(xsize=>100, ysize=>100); | |
75 | my $im2 = Imager->new(xsize=>100, ysize=>100); | |
76 | ||
efdc2568 | 77 | my $solid = Imager::Fill->new(solid=>'#FF0000'); |
f1ac5027 TC |
78 | ok(13, $solid, "creating oo solid fill"); |
79 | ok(14, $solid->{fill}, "bad oo solid fill"); | |
80 | $im1->box(fill=>$solid); | |
81 | $im2->box(filled=>1, color=>$red); | |
82 | $diff = Imager::i_img_diff($im1->{IMG}, $im2->{IMG}); | |
83 | ok(15, !$diff, "oo solid fill"); | |
84 | ||
85 | my $hatcha = Imager::Fill->new(hatch=>'check2x2'); | |
86 | my $hatchb = Imager::Fill->new(hatch=>'check2x2', dx=>2); | |
87 | $im1->box(fill=>$hatcha); | |
88 | $im2->box(fill=>$hatchb); | |
89 | # should be different | |
90 | $diff = Imager::i_img_diff($im1->{IMG}, $im2->{IMG}); | |
91 | ok(16, $diff, "offset checks the same!"); | |
92 | $hatchb = Imager::Fill->new(hatch=>'check2x2', dx=>2, dy=>2); | |
93 | $im2->box(fill=>$hatchb); | |
94 | $diff = Imager::i_img_diff($im1->{IMG}, $im2->{IMG}); | |
95 | ok(17, !$diff, "offset into similar check should be the same"); | |
96 | ||
97 | # test dymanic build of fill | |
98 | $im2->box(fill=>{hatch=>'check2x2', dx=>2, fg=>NC(255,255,255), | |
99 | bg=>NC(0,0,0)}); | |
100 | $diff = Imager::i_img_diff($im1->{IMG}, $im2->{IMG}); | |
101 | ok(18, !$diff, "offset and flipped should be the same"); | |
102 | ||
103 | # a simple demo | |
104 | my $im = Imager->new(xsize=>200, ysize=>200); | |
105 | ||
106 | $im->box(xmin=>10, ymin=>10, xmax=>190, ymax=>190, | |
107 | fill=>{ hatch=>'check4x4', | |
108 | fg=>NC(128, 0, 0), | |
109 | bg=>NC(128, 64, 0) }); | |
110 | $im->arc(r=>80, d1=>45, d2=>75, | |
111 | fill=>{ hatch=>'stipple2', | |
112 | combine=>1, | |
efdc2568 TC |
113 | fg=>[ 0, 0, 0, 255 ], |
114 | bg=>{ rgba=>[255,255,255,160] } }); | |
f1ac5027 TC |
115 | $im->arc(r=>80, d1=>75, d2=>135, |
116 | fill=>{ fountain=>'radial', xa=>100, ya=>100, xb=>20, yb=>100 }); | |
117 | $im->write(file=>'testout/t20_sample.ppm'); | |
118 | ||
cc6483e0 TC |
119 | # flood fill tests |
120 | my $rffimg = Imager::ImgRaw::new(100, 100, 3); | |
121 | # build a H | |
122 | Imager::i_box_filled($rffimg, 10, 10, 20, 90, $blue); | |
123 | Imager::i_box_filled($rffimg, 80, 10, 90, 90, $blue); | |
124 | Imager::i_box_filled($rffimg, 20, 45, 80, 55, $blue); | |
125 | my $black = Imager::Color->new(0, 0, 0); | |
126 | Imager::i_flood_fill($rffimg, 15, 15, $red); | |
127 | my $rffcmp = Imager::ImgRaw::new(100, 100, 3); | |
128 | # build a H | |
129 | Imager::i_box_filled($rffcmp, 10, 10, 20, 90, $red); | |
130 | Imager::i_box_filled($rffcmp, 80, 10, 90, 90, $red); | |
131 | Imager::i_box_filled($rffcmp, 20, 45, 80, 55, $red); | |
132 | $diff = Imager::i_img_diff($rffimg, $rffcmp); | |
133 | ok(19, !$diff, "flood fill difference"); | |
134 | ||
135 | my $ffim = Imager->new(xsize=>100, ysize=>100); | |
136 | my $yellow = Imager::Color->new(255, 255, 0); | |
137 | $ffim->box(xmin=>10, ymin=>10, xmax=>20, ymax=>90, color=>$blue, filled=>1); | |
138 | $ffim->box(xmin=>20, ymin=>45, xmax=>80, ymax=>55, color=>$blue, filled=>1); | |
139 | $ffim->box(xmin=>80, ymin=>10, xmax=>90, ymax=>90, color=>$blue, filled=>1); | |
140 | ok(20, $ffim->flood_fill(x=>50, 'y'=>50, color=>$red), "flood fill"); | |
141 | $diff = Imager::i_img_diff($rffcmp, $ffim->{IMG}); | |
142 | ok(21, !$diff, "oo flood fill difference"); | |
143 | $ffim->flood_fill(x=>50, 'y'=>50, | |
144 | fill=> { | |
145 | hatch => 'check2x2' | |
146 | }); | |
147 | # fill=>{ | |
148 | # fountain=>'radial', | |
149 | # xa=>50, ya=>50, | |
150 | # xb=>10, yb=>10, | |
151 | # }); | |
152 | $ffim->write(file=>'testout/t20_ooflood.ppm'); | |
153 | ||
efdc2568 TC |
154 | # test combining modes |
155 | my $fill = NC(192, 128, 128, 128); | |
156 | my $target = NC(64, 32, 64); | |
157 | my %comb_tests = | |
158 | ( | |
159 | none=>{ result=>$fill }, | |
160 | normal=>{ result=>NC(128, 80, 96) }, | |
161 | multiply => { result=>NC(56, 24, 48) }, | |
162 | dissolve => { result=>[ $target, NC(128, 80, 96) ] }, | |
163 | add => { result=>NC(159, 96, 128) }, | |
164 | subtract => { result=>NC(31, 15, 31) }, # 31.87, 15.9, 31.87 | |
165 | diff => { result=>NC(96, 64, 64) }, | |
166 | lighten => { result=>NC(128, 80, 96) }, | |
167 | darken => { result=>$target }, | |
168 | # the following results are based on the results of the tests and | |
169 | # are suspect for that reason (and were broken at one point <sigh>) | |
170 | # but trying to work them out manually just makes my head hurt - TC | |
171 | hue => { result=>NC(64, 32, 55) }, | |
172 | saturation => { result=>NC(63, 37, 64) }, | |
173 | value => { result=>NC(127, 64, 128) }, | |
174 | color => { result=>NC(64, 37, 52) }, | |
175 | ); | |
176 | ||
177 | my $testnum = 22; # from 22 to 34 | |
178 | for my $comb (Imager::Fill->combines) { | |
179 | my $test = $comb_tests{$comb}; | |
180 | my $targim = Imager->new(xsize=>1, ysize=>1); | |
181 | $targim->box(filled=>1, color=>$target); | |
182 | my $fillobj = Imager::Fill->new(solid=>$fill, combine=>$comb); | |
183 | $targim->box(fill=>$fillobj); | |
184 | my $c = Imager::i_get_pixel($targim->{IMG}, 0, 0); | |
185 | if ($test->{result} =~ /ARRAY/) { | |
186 | ok($testnum++, scalar grep(color_close($_, $c), @{$test->{result}}), | |
187 | "combine '$comb'") | |
188 | or print "# got:",join(",", $c->rgba)," allowed: ", | |
189 | join("|", map { join(",", $_->rgba) } @{$test->{result}}),"\n"; | |
190 | } | |
191 | else { | |
192 | ok($testnum++, color_close($c, $test->{result}), "combine '$comb'") | |
193 | or print "# got: ",join(",", $c->rgba), | |
194 | " allowed: ",join(",", $test->{result}->rgba),"\n"; | |
195 | } | |
196 | } | |
197 | ||
198 | sub ok ($$$) { | |
f1ac5027 TC |
199 | my ($num, $test, $desc) = @_; |
200 | ||
201 | if ($test) { | |
202 | print "ok $num\n"; | |
203 | } | |
204 | else { | |
205 | print "not ok $num # $desc\n"; | |
206 | } | |
efdc2568 TC |
207 | $test; |
208 | } | |
209 | ||
210 | sub color_close { | |
211 | my ($c1, $c2) = @_; | |
212 | ||
213 | my @c1 = $c1->rgba; | |
214 | my @c2 = $c2->rgba; | |
215 | ||
216 | for my $i (0..2) { | |
217 | if (abs($c1[$i]-$c2[$i]) > 2) { | |
218 | return 0; | |
219 | } | |
220 | } | |
221 | return 1; | |
f1ac5027 TC |
222 | } |
223 | ||
224 | # for use during testing | |
225 | sub save { | |
226 | my ($im, $name) = @_; | |
227 | ||
228 | open FH, "> $name" or die "Cannot create $name: $!"; | |
229 | binmode FH; | |
230 | my $io = Imager::io_new_fd(fileno(FH)); | |
231 | Imager::i_writeppm_wiol($im, $io) or die "Cannot save to $name"; | |
232 | undef $io; | |
233 | close FH; | |
234 | } |