minor error handling in bmp.c
[imager.git] / t / t20fill.t
CommitLineData
f1ac5027
TC
1#!perl -w
2use strict;
3
efdc2568
TC
4print "1..34\n";
5
f1ac5027
TC
6use Imager ':handy';
7use Imager::Fill;
8use Imager::Color::Float;
9
efdc2568 10sub ok ($$$);
f1ac5027 11
efdc2568 12Imager::init_log("testout/t20fill.log", 1);
f1ac5027
TC
13
14my $blue = NC(0,0,255);
15my $red = NC(255, 0, 0);
16my $redf = Imager::Color::Float->new(1, 0, 0);
17my $rsolid = Imager::i_new_fill_solid($blue, 0);
18ok(1, $rsolid, "building solid fill");
19my $raw1 = Imager::ImgRaw::new(100, 100, 3);
20# use the normal filled box
21Imager::i_box_filled($raw1, 0, 0, 99, 99, $blue);
22my $raw2 = Imager::ImgRaw::new(100, 100, 3);
23Imager::i_box_cfill($raw2, 0, 0, 99, 99, $rsolid);
24ok(2, 1, "drawing with solid fill");
25my $diff = Imager::i_img_diff($raw1, $raw2);
26ok(3, $diff == 0, "solid fill doesn't match");
27Imager::i_box_filled($raw1, 0, 0, 99, 99, $red);
28my $rsolid2 = Imager::i_new_fill_solidf($redf, 0);
29ok(4, $rsolid2, "creating float solid fill");
30Imager::i_box_cfill($raw2, 0, 0, 99, 99, $rsolid2);
31$diff = Imager::i_img_diff($raw1, $raw2);
32ok(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
36my $rhatcha = Imager::i_new_fill_hatch($red, $blue, 0, 1, undef, 0, 0);
37my $rhatchb = Imager::i_new_fill_hatch($blue, $red, 0, 1, undef, 2, 0);
38ok(6, $rhatcha && $rhatchb, "can't build hatched fill");
39
40# the offset should make these match
41Imager::i_box_cfill($raw1, 0, 0, 99, 99, $rhatcha);
42Imager::i_box_cfill($raw2, 0, 0, 99, 99, $rhatchb);
43ok(7, 1, "filling with hatch");
44$diff = Imager::i_img_diff($raw1, $raw2);
45ok(8, $diff == 0, "hatch images different");
46$rhatchb = Imager::i_new_fill_hatch($blue, $red, 0, 1, undef, 4, 6);
47Imager::i_box_cfill($raw2, 0, 0, 99, 99, $rhatchb);
48$diff = Imager::i_img_diff($raw1, $raw2);
49ok(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);
55Imager::i_box_cfill($raw2, 0, 0, 99, 99, $rhatchb);
56$diff = Imager::i_img_diff($raw1, $raw2);
57ok(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);
61Imager::i_box_cfill($raw2, 0, 0, 99, 99, $rhatchb);
62$diff = Imager::i_img_diff($raw1, $raw2);
63ok(11, $diff, "hatch images the same!");
64
65# custom hatch
66# the inverse of the 2x2 checkerboard
67my $hatch = pack("C8", 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC);
68my $rcustom = Imager::i_new_fill_hatch($blue, $red, 0, 0, $hatch, 0, 0);
69Imager::i_box_cfill($raw2, 0, 0, 99, 99, $rcustom);
70$diff = Imager::i_img_diff($raw1, $raw2);
71ok(12, !$diff, "custom hatch mismatch");
72
73# test the oo interface
74my $im1 = Imager->new(xsize=>100, ysize=>100);
75my $im2 = Imager->new(xsize=>100, ysize=>100);
76
efdc2568 77my $solid = Imager::Fill->new(solid=>'#FF0000');
f1ac5027
TC
78ok(13, $solid, "creating oo solid fill");
79ok(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});
83ok(15, !$diff, "oo solid fill");
84
85my $hatcha = Imager::Fill->new(hatch=>'check2x2');
86my $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});
91ok(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});
95ok(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});
101ok(18, !$diff, "offset and flipped should be the same");
102
103# a simple demo
104my $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
120my $rffimg = Imager::ImgRaw::new(100, 100, 3);
121# build a H
122Imager::i_box_filled($rffimg, 10, 10, 20, 90, $blue);
123Imager::i_box_filled($rffimg, 80, 10, 90, 90, $blue);
124Imager::i_box_filled($rffimg, 20, 45, 80, 55, $blue);
125my $black = Imager::Color->new(0, 0, 0);
126Imager::i_flood_fill($rffimg, 15, 15, $red);
127my $rffcmp = Imager::ImgRaw::new(100, 100, 3);
128# build a H
129Imager::i_box_filled($rffcmp, 10, 10, 20, 90, $red);
130Imager::i_box_filled($rffcmp, 80, 10, 90, 90, $red);
131Imager::i_box_filled($rffcmp, 20, 45, 80, 55, $red);
132$diff = Imager::i_img_diff($rffimg, $rffcmp);
133ok(19, !$diff, "flood fill difference");
134
135my $ffim = Imager->new(xsize=>100, ysize=>100);
136my $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);
140ok(20, $ffim->flood_fill(x=>50, 'y'=>50, color=>$red), "flood fill");
141$diff = Imager::i_img_diff($rffcmp, $ffim->{IMG});
142ok(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
155my $fill = NC(192, 128, 128, 128);
156my $target = NC(64, 32, 64);
157my %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
177my $testnum = 22; # from 22 to 34
178for 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
198sub 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
210sub 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
225sub 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}