Move freetype 2 support into its own module
[imager.git] / FT2 / t / t10ft2.t
1 #!perl -w
2 use strict;
3 use Test::More tests => 189;
4 use Cwd qw(getcwd abs_path);
5
6 use Imager qw(:all);
7
8 use Imager::Test qw(diff_text_with_nul is_color3);
9
10 -d "testout" or mkdir "testout";
11
12 init_log("testout/t38ft2font.log",2);
13
14 my $deffont = "fontfiles/dodge.ttf";
15
16 my @base_color = (64, 255, 64);
17
18 SKIP:
19 {
20   ok($Imager::formats{ft2}, "ft2 should be in %formats");
21
22   my $fontname=$ENV{'TTFONTTEST'} || $deffont;
23
24   -f $fontname or skip("cannot find fontfile $fontname", 188);
25
26
27   my $bgcolor=i_color_new(255,0,0,0);
28   my $overlay=Imager::ImgRaw::new(200,70,3);
29   
30   my $ttraw=Imager::Font::FT2::i_ft2_new($fontname, 0);
31   
32   $ttraw or print Imager::_error_as_msg(),"\n";
33   ok($ttraw, "loaded raw font");
34
35   my @bbox=Imager::Font::FT2::i_ft2_bbox($ttraw, 50.0, 0, 'XMCLH', 0);
36   print "#bbox @bbox\n";
37   
38   is(@bbox, 8, "i_ft2_bbox() returns 8 values");
39
40   ok(Imager::Font::FT2::i_ft2_cp($ttraw,$overlay,5,50,1,50.0,50, 'XMCLH',1,1, 0, 0), "drawn to channel");
41   i_line($overlay,0,50,100,50,$bgcolor,1);
42
43   open(FH,">testout/t38ft2font.ppm") || die "cannot open testout/t38ft2font.ppm\n";
44   binmode(FH);
45   my $IO = Imager::io_new_fd(fileno(FH));
46   ok(i_writeppm_wiol($overlay, $IO), "saved image");
47   close(FH);
48
49   $bgcolor=i_color_set($bgcolor,200,200,200,0);
50   my $backgr=Imager::ImgRaw::new(500,300,3);
51   
52   #     i_tt_set_aa(2);
53   ok(Imager::Font::FT2::i_ft2_text($ttraw,$backgr,100,150,NC(255, 64, 64),200.0,50, 'MAW',1,1,0, 0), "drew MAW");
54   Imager::Font::FT2::i_ft2_settransform($ttraw, [0.9659, 0.2588, 0, -0.2588, 0.9659, 0 ]);
55   ok(Imager::Font::FT2::i_ft2_text($ttraw,$backgr,100,150,NC(0, 128, 0),200.0,50, 'MAW',0,1, 0, 0), "drew rotated MAW");
56   i_line($backgr, 0,150, 499, 150, NC(0, 0, 255),1);
57
58   open(FH,">testout/t38ft2font2.ppm") || die "cannot open testout/t38ft2font.ppm\n";
59   binmode(FH);
60   $IO = Imager::io_new_fd(fileno(FH));
61   ok(i_writeppm_wiol($backgr,$IO), "saved second image");
62   close(FH);
63
64   my $oof = Imager::Font->new(file=>$fontname, type=>'ft2', 'index'=>0);
65
66   ok($oof, "loaded OO font");
67
68   my $im = Imager->new(xsize=>400, ysize=>250);
69   
70   ok($im->string(font=>$oof,
71                  text=>"Via OO",
72                  'x'=>20,
73                  'y'=>20,
74                  size=>60,
75                  color=>NC(255, 128, 255),
76                  aa => 1,
77                  align=>0), "drawn through OO interface");
78   ok($oof->transform(matrix=>[1, 0.1, 0, 0, 1, 0]),
79      "set matrix via OO interface");
80   ok($im->string(font=>$oof,
81                  text=>"Shear",
82                  'x'=>20,
83                  'y'=>40,
84                  size=>60,
85                  sizew=>50,
86                  channel=>1,
87                  aa=>1,
88                  align=>1), "drawn transformed through OO");
89   use Imager::Matrix2d ':handy';
90   ok($oof->transform(matrix=>m2d_rotate(degrees=>-30)),
91      "set transform from m2d module");
92   ok($im->string(font=>$oof,
93                  text=>"SPIN",
94                  'x'=>20,
95                  'y'=>50,
96                  size=>50,
97                  sizew=>40,
98                  color=>NC(255,255,0),
99                  aa => 1,
100                  align=>0, vlayout=>0), "drawn first rotated");
101
102   ok($im->string(font=>$oof,
103                  text=>"SPIN",
104                  'x'=>20,
105                  'y'=>50,
106                  size=>50,
107                  sizew=>40,
108             channel=>2,
109                  aa => 1,
110                  align=>0, vlayout=>0), "drawn second rotated");
111   
112   $oof->transform(matrix=>m2d_identity());
113   $oof->hinting(hinting=>1);
114
115   # UTF8 testing
116   # the test font (dodge.ttf) only supports one character above 0xFF that
117   # I can see, 0x2010 HYPHEN (which renders the same as 0x002D HYPHEN MINUS)
118   # an attempt at utf8 support
119   # first attempt to use native perl UTF8
120  SKIP:
121   {
122     skip("no native UTF8 support in this version of perl", 1) 
123       unless $] >= 5.006;
124     my $text;
125     # we need to do this in eval to prevent compile time errors in older
126     # versions
127     eval q{$text = "A\x{2010}A"}; # A, HYPHEN, A in our test font
128     #$text = "A".chr(0x2010)."A"; # this one works too
129     unless (ok($im->string(font=>$oof,
130                            text=>$text,
131                            'x'=>20,
132                            'y'=>200,
133                            size=>50,
134                            color=>NC(0,255,0),
135                            aa=>1), "drawn UTF natively")) {
136       print "# ",$im->errstr,"\n";
137     }
138   }
139
140   # an attempt using emulation of UTF8
141   my $text = pack("C*", 0x41, 0xE2, 0x80, 0x90, 0x41);
142   #my $text = "A\xE2\x80\x90\x41\x{2010}";
143   #substr($text, -1, 0) = '';
144   unless (ok($im->string(font=>$oof,
145                          text=>$text,
146                          'x'=>20,
147                          'y'=>230,
148                          size=>50,
149                          color=>NC(255,128,0),
150                          aa=>1, 
151                          utf8=>1), "drawn UTF emulated")) {
152     print "# ",$im->errstr,"\n";
153   }
154
155   # just a bit of fun
156   # well it was - it demostrates what happens when you combine
157   # transformations and font hinting
158   for my $steps (0..39) {
159     $oof->transform(matrix=>m2d_rotate(degrees=>-$steps+5));
160     # demonstrates why we disable hinting on a doing a transform
161     # if the following line is enabled then the 0 degrees output sticks 
162     # out a bit
163     # $oof->hinting(hinting=>1);
164     $im->string(font=>$oof,
165                 text=>"SPIN",
166                 'x'=>160,
167                 'y'=>70,
168                 size=>65,
169                 color=>NC(255, $steps * 5, 200-$steps * 5),
170                 aa => 1,
171                 align=>0, );
172   }
173
174   $im->write(file=>'testout/t38_oo.ppm')
175     or print "# could not save OO output: ",$im->errstr,"\n";
176   
177   my (@got) = $oof->has_chars(string=>"\x01H");
178   ok(@got == 2, "has_chars returned 2 items");
179   ok(!$got[0], "have no chr(1)");
180   ok($got[1], "have 'H'");
181   is($oof->has_chars(string=>"H\x01"), "\x01\x00",
182      "scalar has_chars()");
183
184   print "# OO bounding boxes\n";
185   @bbox = $oof->bounding_box(string=>"hello", size=>30);
186   my $bbox = $oof->bounding_box(string=>"hello", size=>30);
187
188   is(@bbox, 8, "list bbox returned 8 items");
189   ok($bbox->isa('Imager::Font::BBox'), "scalar bbox returned right class");
190   ok($bbox->start_offset == $bbox[0], "start_offset");
191   ok($bbox->end_offset == $bbox[2], "end_offset");
192   ok($bbox->global_ascent == $bbox[3], "global_ascent");
193   ok($bbox->global_descent == $bbox[1], "global_descent");
194   ok($bbox->ascent == $bbox[5], "ascent");
195   ok($bbox->descent == $bbox[4], "descent");
196   ok($bbox->advance_width == $bbox[6], "advance_width");
197
198   print "# aligned text output\n";
199   my $alimg = Imager->new(xsize=>300, ysize=>300);
200   $alimg->box(color=>'40FF40', filled=>1);
201
202   $oof->transform(matrix=>m2d_identity());
203   $oof->hinting(hinting=>1);
204   
205   align_test('left', 'top', 10, 10, $oof, $alimg);
206   align_test('start', 'top', 10, 40, $oof, $alimg);
207   align_test('center', 'top', 150, 70, $oof, $alimg);
208   align_test('end', 'top', 290, 100, $oof, $alimg);
209   align_test('right', 'top', 290, 130, $oof, $alimg);
210
211   align_test('center', 'top', 150, 160, $oof, $alimg);
212   align_test('center', 'center', 150, 190, $oof, $alimg);
213   align_test('center', 'bottom', 150, 220, $oof, $alimg);
214   align_test('center', 'baseline', 150, 250, $oof, $alimg);
215   
216   ok($alimg->write(file=>'testout/t38aligned.ppm'), 
217      "saving aligned output image");
218   
219   my $exfont = Imager::Font->new(file=>'fontfiles/ExistenceTest.ttf',
220                                  type=>'ft2');
221   SKIP:
222   {
223     ok($exfont, "loaded existence font")
224       or diag(Imager->errstr);
225     $exfont
226       or skip("couldn't load test font", 11);
227
228     # the test font is known to have a shorter advance width for that char
229     my @bbox = $exfont->bounding_box(string=>"/", size=>100);
230     is(@bbox, 8, "should be 8 entries");
231     isnt($bbox[6], $bbox[2], "different advance width");
232     my $bbox = $exfont->bounding_box(string=>"/", size=>100);
233     ok($bbox->pos_width != $bbox->advance_width, "OO check");
234
235     cmp_ok($bbox->right_bearing, '<', 0, "check right bearing");
236
237     cmp_ok($bbox->display_width, '>', $bbox->advance_width,
238            "check display width (roughly)");
239
240     # check with a char that fits inside the box
241     $bbox = $exfont->bounding_box(string=>"!", size=>100);
242     print "# pos width ", $bbox->pos_width, "\n";
243     is($bbox->pos_width, $bbox->advance_width, 
244        "check backwards compatibility");
245     cmp_ok($bbox->left_bearing, '>', 0, "left bearing positive");
246     cmp_ok($bbox->right_bearing, '>', 0, "right bearing positive");
247     cmp_ok($bbox->display_width, '<', $bbox->advance_width,
248            "display smaller than advance");
249
250     # name tests
251     # make sure the number of tests on each branch match
252     if (Imager::Font::FT2::i_ft2_can_face_name()) {
253       my $facename = Imager::Font::FT2::i_ft2_face_name($exfont->{id});
254       print "# face name '$facename'\n";
255       is($facename, 'ExistenceTest', "test face name");
256       $facename = $exfont->face_name;
257       is($facename, 'ExistenceTest', "test face name OO");
258     }
259     else {
260       # make sure we get the error we expect
261       my $facename = Imager::Font::FT2::i_ft2_face_name($exfont->{id});
262       my ($msg) = Imager::_error_as_msg();
263       ok(!defined($facename), "test face name not supported");
264       print "# $msg\n";
265       ok(scalar($msg =~ /or later required/), "test face name not supported");
266     }
267   }
268
269   SKIP:
270   {
271     Imager::Font::FT2->can_glyph_names
272         or skip("FT2 compiled without glyph names support", 9);
273         
274     # FT2 considers POST tables in TTF fonts unreliable, so use
275     # a type 1 font, see below for TTF test 
276     my $exfont = Imager::Font->new(file=>'fontfiles/ExistenceTest.pfb',
277                                type=>'ft2');
278   SKIP:
279     {
280       ok($exfont, "load Type 1 via FT2")
281         or skip("couldn't load type 1 with FT2", 8);
282       my @glyph_names = 
283         Imager::Font::FT2::i_ft2_glyph_name($exfont->{id}, "!J/");
284       #use Data::Dumper;
285       #print Dumper \@glyph_names;
286       is($glyph_names[0], 'exclam', "check exclam name");
287       ok(!defined($glyph_names[1]), "check for no J name");
288       is($glyph_names[2], 'slash', "check slash name");
289
290       # oo interfaces
291       @glyph_names = $exfont->glyph_names(string=>"!J/");
292       is($glyph_names[0], 'exclam', "check exclam name OO");
293       ok(!defined($glyph_names[1]), "check for no J name OO");
294       is($glyph_names[2], 'slash', "check slash name OO");
295
296       # make sure a missing string parameter is handled correctly
297       eval {
298         $exfont->glyph_names();
299       };
300       is($@, "", "correct error handling");
301       cmp_ok(Imager->errstr, '=~', qr/no string parameter/, "error message");
302     }
303   
304     # freetype 2 considers truetype glyph name tables unreliable
305     # due to some specific fonts, supplying reliable_only=>0 bypasses
306     # that check and lets us get the glyph names even for truetype fonts
307     # so we can test this stuff <sigh>
308     # we can't use ExistenceTest.ttf since that's generated with 
309     # AppleStandardEncoding since the same .sfd needs to generate
310     # a .pfb file, NameTest.ttf uses a Unicode encoding
311     
312     # we were using an unsigned char to store a unicode character
313     # https://rt.cpan.org/Ticket/Display.html?id=7949
314     $exfont = Imager::Font->new(file=>'fontfiles/NameTest.ttf',
315                                 type=>'ft2');
316   SKIP:
317     {
318       ok($exfont, "load TTF via FT2")
319         or skip("could not load TTF with FT2", 1);
320       my $text = pack("C*", 0xE2, 0x80, 0x90); # "\x{2010}" as utf-8
321       my @names = $exfont->glyph_names(string=>$text,
322                                        utf8=>1, reliable_only=>0);
323       is($names[0], "hyphentwo", "check utf8 glyph name");
324     }
325   }
326
327   # check that error codes are translated correctly
328   my $errfont = Imager::Font->new(file=>"t/t10ft2.t", type=>"ft2");
329   is($errfont, undef, "new font vs non font");
330   cmp_ok(Imager->errstr, '=~', qr/unknown file format/, "check error message");
331
332   # Multiple Master tests
333   # we check a non-MM font errors correctly
334   print "# check that the methods act correctly for a non-MM font\n";
335   ok(!$exfont->is_mm, "exfont not MM");
336   ok((() = $exfont->mm_axes) == 0, "exfont has no MM axes");
337   cmp_ok(Imager->errstr, '=~', qr/no multiple masters/, 
338          "and returns correct error when we ask");
339   ok(!$exfont->set_mm_coords(coords=>[0, 0]), "fail setting axis on exfont");
340   cmp_ok(Imager->errstr, '=~', qr/no multiple masters/, 
341          "and returns correct error when we ask");
342
343   # try a MM font now - test font only has A defined
344   print "# Try a multiple master font\n";
345   my $mmfont = Imager::Font->new(file=>"fontfiles/MMOne.pfb", type=>"ft2", 
346                                  color=>"white", aa=>1, size=>60);
347   ok($mmfont, "loaded MM font");
348   ok($mmfont->is_mm, "font is multiple master");
349   my @axes = $mmfont->mm_axes;
350   is(@axes, 2, "check we got both axes");
351   is($axes[0][0], "Weight", "name of first axis");
352   is($axes[0][1],  50, "min for first axis");
353   is($axes[0][2], 999, "max for first axis");
354   is($axes[1][0], "Slant", "name of second axis");
355   is($axes[1][1],   0, "min for second axis");
356   is($axes[1][2], 999, "max for second axis");
357   my $mmim = Imager->new(xsize=>200, ysize=>200);
358   $mmim->string(font=>$mmfont, x=>0, 'y'=>50, text=>"A");
359   ok($mmfont->set_mm_coords(coords=>[ 700, 0 ]), "set to bold, unsloped");
360   $mmim->string(font=>$mmfont, x=>0, 'y'=>100, text=>"A", color=>'blue');
361   my @weights = qw(50 260 525 760 999);
362   my @slants = qw(0 333 666 999);
363   for my $windex (0 .. $#weights) {
364     my $weight = $weights[$windex];
365     for my $sindex (0 .. $#slants) {
366       my $slant = $slants[$sindex];
367       $mmfont->set_mm_coords(coords=>[ $weight, $slant ]);
368       $mmim->string(font=>$mmfont, x=>30+32*$windex, 'y'=>50+45*$sindex,
369                     text=>"A");
370     }
371   }
372
373   ok($mmim->write(file=>"testout/t38mm.ppm"), "save MM output");
374
375  SKIP:
376   { print "# alignment tests\n";
377     my $font = Imager::Font->new(file=>'fontfiles/ImUgly.ttf', type=>'ft2');
378     ok($font, "loaded deffont OO")
379       or skip("could not load font:".Imager->errstr, 4);
380     my $im = Imager->new(xsize=>140, ysize=>150);
381     my %common = 
382       (
383        font=>$font, 
384        size=>40, 
385        aa=>1,
386       );
387     $im->line(x1=>0, y1=>40, x2=>139, y2=>40, color=>'blue');
388     $im->line(x1=>0, y1=>90, x2=>139, y2=>90, color=>'blue');
389     $im->line(x1=>0, y1=>110, x2=>139, y2=>110, color=>'blue');
390     for my $args ([ x=>5,   text=>"A", color=>"white" ],
391                   [ x=>40,  text=>"y", color=>"white" ],
392                   [ x=>75,  text=>"A", channel=>1 ],
393                   [ x=>110, text=>"y", channel=>1 ]) {
394       ok($im->string(%common, @$args, 'y'=>40), "A no alignment");
395       ok($im->string(%common, @$args, 'y'=>90, align=>1), "A align=1");
396       ok($im->string(%common, @$args, 'y'=>110, align=>0), "A align=0");
397     }
398     ok($im->write(file=>'testout/t38align.ppm'), "save align image");
399   }
400
401
402   { # outputting a space in non-AA could either crash 
403     # or fail (ft 2.2+)
404     my $font = Imager::Font->new(file=>'fontfiles/ImUgly.ttf', type=>'ft2');
405     my $im = Imager->new(xsize => 100, ysize => 100);
406     ok($im->string(x => 10, y => 10, string => "test space", aa => 0,
407                    color => '#FFF', size => 8, font => $font),
408        "draw space non-antialiased (color)");
409     ok($im->string(x => 10, y => 50, string => "test space", aa => 0,
410                    channel => 0, size => 8, font => $font),
411        "draw space non-antialiased (channel)");
412   }
413
414   { # cannot output "0"
415     # https://rt.cpan.org/Ticket/Display.html?id=21770
416     my $font = Imager::Font->new(file=>'fontfiles/ImUgly.ttf', type=>'ft2');
417     ok($font, "loaded imugly");
418     my $imbase = Imager->new(xsize => 100, ysize => 100);
419     my $im = $imbase->copy;
420     ok($im->string(x => 10, y => 50, string => "0", aa => 0,
421                    color => '#FFF', size => 20, font => $font),
422        "draw '0'");
423     ok(Imager::i_img_diff($im->{IMG}, $imbase->{IMG}),
424        "make sure we actually drew it");
425     $im = $imbase->copy;
426     ok($im->string(x => 10, y => 50, string => 0.0, aa => 0,
427                    color => '#FFF', size => 20, font => $font),
428        "draw 0.0");
429     ok(Imager::i_img_diff($im->{IMG}, $imbase->{IMG}),
430        "make sure we actually drew it");
431   }
432   { # string output cut off at NUL ('\0')
433     # https://rt.cpan.org/Ticket/Display.html?id=21770 cont'd
434     my $font = Imager::Font->new(file=>'fontfiles/ImUgly.ttf', type=>'ft2');
435     ok($font, "loaded imugly");
436
437     diff_text_with_nul("a\\0b vs a", "a\0b", "a", 
438                        font => $font, color => '#FFFFFF');
439     diff_text_with_nul("a\\0b vs a", "a\0b", "a", 
440                        font => $font, channel => 1);
441
442     # UTF8 encoded \x{2010}
443     my $dash = pack("C*", 0xE2, 0x80, 0x90);
444     diff_text_with_nul("utf8 dash\0dash vs dash", "$dash\0$dash", $dash,
445                        font => $font, color => '#FFFFFF', utf8 => 1);
446     diff_text_with_nul("utf8 dash\0dash vs dash", "$dash\0$dash", $dash,
447                        font => $font, channel => 1, utf8 => 1);
448   }
449
450   { # RT 11972
451     # when rendering to a transparent image the coverage should be
452     # expressed in terms of the alpha channel rather than the color
453     my $font = Imager::Font->new(file=>'fontfiles/ImUgly.ttf', type=>'ft2');
454     my $im = Imager->new(xsize => 40, ysize => 20, channels => 4);
455     ok($im->string(string => "AB", size => 20, aa => 1, color => '#F00',
456                    x => 0, y => 15, font => $font),
457        "draw to transparent image");
458     my $im_noalpha = $im->convert(preset => 'noalpha');
459     my $im_pal = $im->to_paletted(make_colors => 'mediancut');
460     my @colors = $im_pal->getcolors;
461     is(@colors, 2, "should be only 2 colors");
462     @colors = sort { ($a->rgba)[0] <=> ($b->rgba)[0] } @colors;
463     is_color3($colors[0], 0, 0, 0, "check we got black");
464     is_color3($colors[1], 255, 0, 0, "and red");
465   }
466
467   { # RT 27546
468     my $im = Imager->new(xsize => 100, ysize => 100, channels => 4);
469     $im->box(filled => 1, color => '#ff0000FF');
470     my $font = Imager::Font->new(file=>'fontfiles/ImUgly.ttf', type=>'ft2');
471     ok($im->string(x => 0, 'y' => 40, text => 'test', 
472                    size => 11, sizew => 11, font => $font, aa => 1),
473        'draw on translucent image')
474   }
475
476   { # RT 60199
477     # not ft2 specific, but Imager
478     my $im = Imager->new(xsize => 100, ysize => 100);
479     my $font = Imager::Font->new(file=>'fontfiles/ImUgly.ttf', type=>'ft2');
480     my $imcopy = $im->copy;
481     ok($im, "make test image");
482     ok($font, "make test font");
483     ok($im->align_string(valign => "center", halign => "center",
484                          x => 50, y => 50, string => "0", color => "#FFF",
485                          font => $font),
486        "draw 0 aligned");
487     ok(Imager::i_img_diff($im->{IMG}, $imcopy->{IMG}),
488        "make sure we drew the '0'");
489   }
490
491  SKIP:
492   { # RT 60509
493     # checks that a c:foo or c:\foo path is handled correctly on win32
494     my $type = "ft2";
495     $^O eq "MSWin32" || $^O eq "cygwin"
496       or skip("only for win32", 2);
497     my $dir = getcwd
498       or skip("Cannot get cwd", 2);
499     if ($^O eq "cygwin") {
500       $dir = Cygwin::posix_to_win_path($dir);
501     }
502     my $abs_path = abs_path($deffont);
503     my $font = Imager::Font->new(file => $abs_path, type => $type);
504     ok($font, "found font by absolute path")
505       or print "# path $abs_path\n";
506     undef $font;
507
508     $^O eq "cygwin"
509       and skip("cygwin doesn't support drive relative DOSsish paths", 1);
510     my ($drive) = $dir =~ /^([a-z]:)/i
511       or skip("cwd has no drive letter", 2);
512     my $drive_path = $drive . $deffont;
513     $font = Imager::Font->new(file => $drive_path, type => $type);
514     ok($font, "found font by drive relative path")
515       or print "# path $drive_path\n";
516   }
517
518 }
519
520 sub align_test {
521   my ($h, $v, $x, $y, $f, $img) = @_;
522
523   my @pos = $f->align(halign=>$h, valign=>$v, 'x'=>$x, 'y'=>$y,
524                       image=>$img, size=>15, color=>'FFFFFF',
525                       string=>"x$h ${v}y", channel=>1, aa=>1);
526   @pos = $img->align_string(halign=>$h, valign=>$v, 'x'=>$x, 'y'=>$y,
527                       font=>$f, size=>15, color=>'FF99FF',
528                       string=>"x$h ${v}y", aa=>1);
529   if (ok(@pos == 4, "$h $v aligned output")) {
530     # checking corners
531     my $cx = int(($pos[0] + $pos[2]) / 2);
532     my $cy = int(($pos[1] + $pos[3]) / 2);
533     
534     print "# @pos cx $cx cy $cy\n";
535     okmatchcolor($img, $cx, $pos[1]-1, @base_color, "outer top edge");
536     okmatchcolor($img, $cx, $pos[3], @base_color, "outer bottom edge");
537     okmatchcolor($img, $pos[0]-1, $cy, @base_color, "outer left edge");
538     okmatchcolor($img, $pos[2], $cy, @base_color, "outer right edge");
539     
540     okmismatchcolor($img, $cx, $pos[1], @base_color, "inner top edge");
541     okmismatchcolor($img, $cx, $pos[3]-1, @base_color, "inner bottom edge");
542     okmismatchcolor($img, $pos[0], $cy, @base_color, "inner left edge");
543 #    okmismatchcolor($img, $pos[2]-1, $cy, @base_color, "inner right edge");
544 # XXX: This gets triggered by a freetype2 bug I think 
545 #    $ rpm -qa | grep freetype
546 #    freetype-2.1.3-6
547 #
548 # (addi: 4/1/2004).
549
550     cross($img, $x, $y, 'FF0000');
551     cross($img, $cx, $pos[1]-1, '0000FF');
552     cross($img, $cx, $pos[3], '0000FF');
553     cross($img, $pos[0]-1, $cy, '0000FF');
554     cross($img, $pos[2], $cy, '0000FF');
555   }
556   else {
557     SKIP: { skip("couldn't draw text", 7) };
558   }
559 }
560
561 sub okmatchcolor {
562   my ($img, $x, $y, $r, $g, $b, $about) = @_;
563
564   my $c = $img->getpixel('x'=>$x, 'y'=>$y);
565   my ($fr, $fg, $fb) = $c->rgba;
566   ok($fr == $r && $fg == $g && $fb == $b,
567       "want ($r,$g,$b) found ($fr,$fg,$fb)\@($x,$y) $about");
568 }
569
570 sub okmismatchcolor {
571   my ($img, $x, $y, $r, $g, $b, $about) = @_;
572
573   my $c = $img->getpixel('x'=>$x, 'y'=>$y);
574   my ($fr, $fg, $fb) = $c->rgba;
575   ok($fr != $r || $fg != $g || $fb != $b,
576       "don't want ($r,$g,$b) found ($fr,$fg,$fb)\@($x,$y) $about");
577 }
578
579 sub cross {
580   my ($img, $x, $y, $color) = @_;
581
582   $img->setpixel('x'=>[$x, $x, $x, $x, $x, $x-2, $x-1, $x+1, $x+2], 
583                  'y'=>[$y-2, $y-1, $y, $y+1, $y+2, $y, $y, $y, $y], 
584                  color => $color);
585   
586 }