]> git.imager.perl.org - imager.git/blob - t/t82inline.t
use SvPV to get the length of text to draw rather than strlen(), add
[imager.git] / t / t82inline.t
1 #!perl -w
2 #
3 # this tests both the Inline interface and the API
4 use strict;
5 use lib 't';
6 use Test::More;
7 eval "require Inline::C;";
8 plan skip_all => "Inline required for testing API" if $@;
9
10 use Cwd 'getcwd';
11 plan skip_all => "Inline won't work in directories with spaces"
12   if getcwd() =~ / /;
13
14 plan tests => 8;
15 require Inline;
16 Inline->import(with => 'Imager');
17
18 Inline->bind(C => <<'EOS');
19 #include <math.h>
20
21 int pixel_count(Imager::ImgRaw im) {
22   return im->xsize * im->ysize;
23 }
24
25 int count_color(Imager::ImgRaw im, Imager::Color c) {
26   int count = 0, x, y, chan;
27   i_color read_c;
28
29   for (x = 0; x < im->xsize; ++x) {
30     for (y = 0; y < im->ysize; ++y) {
31       int match = 1;
32       i_gpix(im, x, y, &read_c);
33       for (chan = 0; chan < im->channels; ++chan) {
34         if (read_c.channel[chan] != c->channel[chan]) {
35           match = 0;
36           break;
37         }
38       }
39       if (match)
40         ++count;
41     }
42   }
43
44   return count;
45 }
46
47 Imager make_10x10() {
48   i_img *im = i_img_8_new(10, 10, 3);
49   i_color c;
50   c.channel[0] = c.channel[1] = c.channel[2] = 255;
51   i_box_filled(im, 0, 0, im->xsize-1, im->ysize-1, &c);
52
53   return im;
54 }
55
56 /* tests that all of the APIs are visible - most of them anyway */
57 Imager do_lots(Imager src) {
58   i_img *im = i_img_8_new(100, 100, 3);
59   i_img *fill_im = i_img_8_new(5, 5, 3);
60   i_img *testim;
61   i_color red, blue, green, black, temp_color;
62   i_fcolor redf, bluef;
63   i_fill_t *hatch, *fhatch_fill;
64   i_fill_t *im_fill;
65   i_fill_t *solid_fill, *fsolid_fill;
66   i_fill_t *fount_fill;
67   void *block;
68   double matrix[9] = /* 30 degree rotation */
69     {
70       0.866025,  -0.5,      0, 
71       0.5,       0.866025,  0, 
72       0,         0,         1,      
73     };
74   i_fountain_seg fseg;
75   i_img_tags tags;
76   int entry;
77   double temp_double;
78
79   red.channel[0] = 255; red.channel[1] = 0; red.channel[2] = 0;
80   red.channel[3] = 255;
81   blue.channel[0] = 0; blue.channel[1] = 0; blue.channel[2] = 255;
82   blue.channel[3] = 255;
83   green.channel[0] = 0; green.channel[1] = 255; green.channel[2] = 0;
84   green.channel[3] = 255;
85   black.channel[0] = black.channel[1] = black.channel[2] = 0;
86   black.channel[3] = 255;
87   hatch = i_new_fill_hatch(&red, &blue, 0, 1, NULL, 0, 0);
88
89   i_box(im, 0, 0, 9, 9, &red);
90   i_box_filled(im, 10, 0, 19, 9, &blue);
91   i_box_cfill(im, 20, 0, 29, 9, hatch);
92
93   /* make an image fill, and try it */
94   i_box_cfill(fill_im, 0, 0, 4, 4, hatch);
95   im_fill = i_new_fill_image(fill_im, matrix, 2, 2, 0);
96
97   i_box_cfill(im, 30, 0, 39, 9, im_fill);
98
99   /* make a solid fill and try it */
100   solid_fill = i_new_fill_solid(&red, 0);
101   i_box_cfill(im, 40, 0, 49, 9, solid_fill);
102
103   /* floating fills */
104   redf.channel[0] = 1.0; redf.channel[1] = 0; redf.channel[2] = 0;
105   redf.channel[3] = 1.0;
106   bluef.channel[0] = 0; bluef.channel[1] = 0; bluef.channel[2] = 1.0;
107   bluef.channel[3] = 1.0;
108
109   fsolid_fill = i_new_fill_solidf(&redf, 0);
110   i_box_cfill(im, 50, 0, 59, 9, fsolid_fill);
111  
112   fhatch_fill = i_new_fill_hatchf(&redf, &bluef, 0, 2, NULL, 0, 0);
113   i_box_cfill(im, 60, 0, 69, 9, fhatch_fill);
114
115   /* fountain fill */
116   fseg.start = 0;
117   fseg.middle = 0.5;
118   fseg.end = 1.0;
119   fseg.c[0] = redf;
120   fseg.c[1] = bluef;
121   fseg.type = i_fst_linear;
122   fseg.color = i_fc_hue_down;
123   fount_fill = i_new_fill_fount(70, 0, 80, 0, i_ft_linear, i_fr_triangle, 0, i_fts_none, 1, 1, &fseg);
124
125   i_box_cfill(im, 70, 0, 79, 9, fount_fill);
126
127   i_line(im, 0, 10, 10, 15, &blue, 1);
128   i_line_aa(im, 0, 19, 10, 15, &red, 1);
129   
130   i_arc(im, 15, 15, 4, 45, 160, &blue);
131   i_arc_aa(im, 25, 15, 4, 75, 280, &red);
132   i_arc_cfill(im, 35, 15, 4, 0, 215, hatch);
133   i_arc_aa_cfill(im, 45, 15, 4, 30, 210, hatch);
134   i_circle_aa(im, 55, 15, 4, &red);
135   
136   i_box(im, 61, 11, 68, 18, &red);
137   i_flood_fill(im, 65, 15, &blue);
138   i_box(im, 71, 11, 78, 18, &red);
139   i_flood_cfill(im, 75, 15, hatch);
140
141   i_box_filled(im, 1, 21, 9, 24, &red);
142   i_box_filled(im, 1, 25, 9, 29, &blue);
143   i_flood_fill_border(im, 5, 25, &green, &black);
144
145   i_box_filled(im, 11, 21, 19, 24, &red);
146   i_box_filled(im, 11, 25, 19, 29, &blue);
147   i_flood_cfill_border(im, 15, 25, hatch, &black);
148
149   i_fill_destroy(fount_fill);
150   i_fill_destroy(fhatch_fill);
151   i_fill_destroy(solid_fill);
152   i_fill_destroy(fsolid_fill);
153   i_fill_destroy(hatch);
154   i_fill_destroy(im_fill);
155   i_img_destroy(fill_im);
156
157   /* make sure we can make each image type */
158   testim = i_img_16_new(100, 100, 3);
159   i_img_destroy(testim);
160   testim = i_img_double_new(100, 100, 3);
161   i_img_destroy(testim);
162   testim = i_img_pal_new(100, 100, 3, 256);
163   i_img_destroy(testim);
164   testim = i_sametype(im, 50, 50);
165   i_img_destroy(testim);
166   testim = i_sametype_chans(im, 50, 50, 4);
167   i_img_destroy(testim);
168
169   i_clear_error();
170   i_push_error(0, "Hello");
171   i_push_errorf(0, "%s", "World");
172
173   /* make sure tags create/destroy work */
174   i_tags_new(&tags);
175   i_tags_destroy(&tags);  
176
177   block = mymalloc(20);
178   block = myrealloc(block, 50);
179   myfree(block);
180
181   i_tags_set(&im->tags, "lots_string", "foo", -1);
182   i_tags_setn(&im->tags, "lots_number", 101);
183
184   if (!i_tags_find(&im->tags, "lots_number", 0, &entry)) {
185     i_push_error(0, "lots_number tag not found");
186     i_img_destroy(im);
187     return NULL;
188   }
189   i_tags_delete(&im->tags, entry);
190
191   /* these won't delete anything, but it makes sure the macros and function
192      pointers are correct */
193   i_tags_delbyname(&im->tags, "unknown");
194   i_tags_delbycode(&im->tags, 501);
195   i_tags_set_float(&im->tags, "lots_float", 0, 3.14);
196   if (!i_tags_get_float(&im->tags, "lots_float", 0, &temp_double)) {
197     i_push_error(0, "lots_float not found");
198     i_img_destroy(im);
199     return NULL;
200   }
201   if (fabs(temp_double - 3.14) > 0.001) {
202     i_push_errorf(0, "lots_float incorrect %g", temp_double);
203     i_img_destroy(im);
204     return NULL;
205   }
206   i_tags_set_float2(&im->tags, "lots_float2", 0, 100 * sqrt(2.0), 5);
207   if (!i_tags_get_int(&im->tags, "lots_float2", 0, &entry)) {
208     i_push_error(0, "lots_float2 not found as int");
209     i_img_destroy(im);
210     return NULL;
211   }
212   if (entry != 141) { 
213     i_push_errorf(0, "lots_float2 unexpected value %d", entry);
214     i_img_destroy(im);
215     return NULL;
216   }
217
218   i_tags_set_color(&im->tags, "lots_color", 0, &red);
219   if (!i_tags_get_color(&im->tags, "lots_color", 0, &temp_color)) {
220     i_push_error(0, "lots_color not found as color");
221     i_img_destroy(im);
222     return NULL;
223   }
224     
225   return im;
226 }
227
228 EOS
229
230 my $im = Imager->new(xsize=>50, ysize=>50);
231 is(pixel_count($im), 2500, "pixel_count");
232
233 my $black = Imager::Color->new(0,0,0);
234 is(count_color($im, $black), 2500, "count_color black on black image");
235
236 my $im2 = make_10x10();
237 my $white = Imager::Color->new(255, 255, 255);
238 is(count_color($im2, $white), 100, "check new image white count");
239 ok($im2->box(filled=>1, xmin=>1, ymin=>1, xmax => 8, ymax=>8, color=>$black),
240    "try new image");
241 is(count_color($im2, $black), 64, "check modified black count");
242 is(count_color($im2, $white), 36, "check modified white count");
243
244 my $im3 = do_lots($im2);
245 ok($im3, "do_lots()")
246   or print "# ", Imager->_error_as_msg, "\n";
247 ok($im3->write(file=>'testout/t82lots.ppm'), "write t82lots.ppm");