- Imager::Font::BBox objects now have right_bearing() and display_width()
methods. Hopefully this and the advance_width() method fills out
the Imager bounding box interface to a useful state.
- Implemented for FT2 so far.
+ Implemented for FT2, FT1.x, T1Lib so far.
=================================================================
}
# EU::MM crashes without this when we define it in the base Makefile.PL
+# but then warns about redefinition, so delete the GLOB entry
+BEGIN { delete $MY::{metafile} }
sub MY::metafile {
'';
}
cords[BBOX_ASCENT]=((float)bbox.ury*points)/1000;
cords[BBOX_ADVANCE_WIDTH] = ((float)advance * points)/1000;
+ cords[BBOX_RIGHT_BEARING] =
+ cords[BBOX_ADVANCE_WIDTH] - cords[BBOX_POS_WIDTH];
- return BBOX_ADVANCE_WIDTH+1;
+ return BBOX_RIGHT_BEARING+1;
}
- (gm->bbox.xMax - gm->bbox.xMin);
/* fprintf(stderr, "font info last: %d %d %d %d\n",
gm->bbox.xMax, gm->bbox.xMin, gm->advance, rightb); */
- if (rightb > 0)
- rightb = 0;
}
ascent = (ascent > casc ? ascent : casc );
cords[BBOX_NEG_WIDTH]=start;
cords[BBOX_GLOBAL_DESCENT]=gdescent;
- cords[BBOX_POS_WIDTH]=width - rightb / 64;
+ cords[BBOX_POS_WIDTH]=width;
+ if (rightb < 0)
+ cords[BBOX_POS_WIDTH] -= rightb / 64;
cords[BBOX_GLOBAL_ASCENT]=gascent;
cords[BBOX_DESCENT]=descent;
cords[BBOX_ASCENT]=ascent;
cords[BBOX_ADVANCE_WIDTH] = width;
+ cords[BBOX_RIGHT_BEARING] = rightb / 64;
- return BBOX_ADVANCE_WIDTH + 1;
+ return BBOX_RIGHT_BEARING + 1;
}
You need to modify this class to add new font types.
+The $pos_width member returned by the bounding_box() method has
+historically returned different values from different drivers. The
+Freetype 1.x and 2.x, and the Win32 drivers return the max of the
+advance width and the right edge of the right-most glyph. The Type 1
+driver always returns the right edge of the right-most glyph.
+
+The newer advance_width and right_bearing values allow access to any
+of the above.
+
=head1 SEE ALSO
Imager(3), Imager::Font::FreeType2(3), Imager::Font::Type1(3),
# Change 1..1 below to 1..last_test_to_print .
# (It may become useful if the test is moved to ./t subdirectory.)
use strict;
-use Test::More tests => 41;
+use Test::More tests => 50;
BEGIN { use_ok(Imager => ':all') }
#$Imager::DEBUG=1;
SKIP:
{
if (!(i_has_format("t1")) ) {
- skip(40, "t1lib unavailable or disabled", 40);
+ skip("t1lib unavailable or disabled", 49);
}
elsif (! -f $fontname_pfb) {
- skip("cannot find fontfile for type 1 test $fontname_pfb", 40);
+ skip("cannot find fontfile for type 1 test $fontname_pfb", 49);
}
elsif (! -f $fontname_afm) {
- skip("cannot find fontfile for type 1 test $fontname_afm", 40);
+ skip("cannot find fontfile for type 1 test $fontname_afm", 49);
}
print "# has t1\n";
my $fnum=Imager::i_t1_new($fontname_pfb,$fontname_afm); # this will load the pfb font
unless (ok($fnum >= 0, "load font $fontname_pfb")) {
- skip("without the font I can't do a thing", 39);
+ skip("without the font I can't do a thing", 48);
}
my $bgcolor=Imager::Color->new(255,0,0,0);
i_line($overlay,0,50,100,50,$bgcolor,1);
my @bbox=i_t1_bbox(0,50.0,'XMCLH',5);
- ok(@bbox == 7, "i_t1_bbox");
+ is(@bbox, 8, "i_t1_bbox");
print "# bbox: ($bbox[0], $bbox[1]) - ($bbox[2], $bbox[3])\n";
open(FH,">testout/t30t1font.ppm") || die "cannot open testout/t35t1font.ppm\n";
my $alttext = "A\xA1A";
my @utf8box = i_t1_bbox($fnum, 50.0, $text, length($text), 1);
- is(@utf8box, 7, "utf8 bbox element count");
+ is(@utf8box, 8, "utf8 bbox element count");
my @base = i_t1_bbox($fnum, 50.0, $alttext, length($alttext), 0);
- is(@base, 7, "alt bbox element count");
+ is(@base, 8, "alt bbox element count");
my $maxdiff = $fontname_pfb eq $deffont ? 0 : $base[2] / 3;
print "# (@utf8box vs @base)\n";
ok(abs($utf8box[2] - $base[2]) <= $maxdiff,
ok(i_t1_cp($backgr, 80, 180, 1, $fnum, 32, $text, length($text), 1),
"cp UTF8");
@utf8box = i_t1_bbox($fnum, 50.0, $text, length($text), 0);
- is(@utf8box, 7, "native utf8 bbox element count");
+ is(@utf8box, 8, "native utf8 bbox element count");
ok(abs($utf8box[2] - $base[2]) <= $maxdiff,
"compare box sizes native $utf8box[2] vs $base[2] (maxerror $maxdiff)");
eval q{$text = "A\xA1\xA2\x01\x1F\x{0100}A"};
SKIP:
{
ok($font, "loaded OO font")
- or skip("Could not load test font", 15);
+ or skip("Could not load test font", 24);
my @exists = $font->has_chars(string=>"!A");
is(@exists, 2, "return count from has_chars");
ok($exists[0], "we have an exclamation mark");
};
is($@, "", "correct error handling");
cmp_ok(Imager->errstr, '=~', qr/no string parameter/, "error message");
+
+ # test extended bounding box results
+ # the test font is known to have a shorter advance width for that char
+ @bbox = $font->bounding_box(string=>"/", size=>100);
+ is(@bbox, 8, "should be 8 entries");
+ isnt($bbox[6], $bbox[2], "different advance width");
+ my $bbox = $font->bounding_box(string=>"/", size=>100);
+ cmp_ok($bbox->pos_width, '>', $bbox->advance_width, "OO check");
+
+ cmp_ok($bbox->right_bearing, '<', 0, "check right bearing");
+
+ cmp_ok($bbox->display_width, '>', $bbox->advance_width,
+ "check display width (roughly)");
+
+ # check with a char that fits inside the box
+ $bbox = $font->bounding_box(string=>"!", size=>100);
+ print "# pos width ", $bbox->pos_width, "\n";
+
+ # they aren't the same historically for the type 1 driver
+ isnt($bbox->pos_width, $bbox->advance_width,
+ "check backwards compatibility");
+ cmp_ok($bbox->left_bearing, '>', 0, "left bearing positive");
+ cmp_ok($bbox->right_bearing, '>', 0, "right bearing positive");
+ cmp_ok($bbox->display_width, '<', $bbox->advance_width,
+ "display smaller than advance");
}
}
#!perl -w
use strict;
use lib 't';
-use Test::More tests => 43;
+use Test::More tests => 49;
BEGIN { use_ok(Imager => ':all') }
require "t/testtools.pl";
ok($ttraw, "create font");
my @bbox = i_tt_bbox($ttraw,50.0,'XMCLH',5,0);
- is(@bbox, 7, "bounding box");
+ is(@bbox, 8, "bounding box");
print "#bbox: ($bbox[0], $bbox[1]) - ($bbox[2], $bbox[3])\n";
ok(i_tt_cp($ttraw,$overlay,5,50,1,50.0,'XMCLH',5,1,0), "cp output");
my $alttext = "A-A";
my @utf8box = i_tt_bbox($ttraw, 50.0, $text, length($text), 1);
- is(@utf8box, 7, "utf8 bbox element count");
+ is(@utf8box, 8, "utf8 bbox element count");
my @base = i_tt_bbox($ttraw, 50.0, $alttext, length($alttext), 0);
- is(@base, 7, "alt bbox element count");
+ is(@base, 8, "alt bbox element count");
my $maxdiff = $fontname eq $deffont ? 0 : $base[2] / 3;
print "# (@utf8box vs @base)\n";
ok(abs($utf8box[2] - $base[2]) <= $maxdiff,
ok(i_tt_cp($ttraw, $backgr, 350, 80, 0, 14, $text, 0, 1, 0),
"cp UTF8");
@utf8box = i_tt_bbox($ttraw, 50.0, $text, length($text), 0);
- is(@utf8box, 7, "native utf8 bbox element count");
+ is(@utf8box, 8, "native utf8 bbox element count");
ok(abs($utf8box[2] - $base[2]) <= $maxdiff,
"compare box sizes native $utf8box[2] vs $base[2] (maxerror $maxdiff)");
eval q{$text = "A\x{0905}\x{0906}\x{0103}A"}; # Devanagari
SKIP:
{
ok($hcfont, "loading existence test font")
- or skip("could not load test font", 14);
+ or skip("could not load test font", 20);
# list interface
my @exists = $hcfont->has_chars(string=>'!A');
# the test font is known to have a shorter advance width for that char
my @bbox = $hcfont->bounding_box(string=>"/", size=>100);
- is(@bbox, 7, "should be 7 entries");
+ is(@bbox, 8, "should be 8 entries");
isnt($bbox[6], $bbox[2], "different advance width from pos width");
print "# @bbox\n";
my $bbox = $hcfont->bounding_box(string=>"/", size=>100);
isnt($bbox->pos_width, $bbox->advance_width, "OO check");
+
+ cmp_ok($bbox->right_bearing, '<', 0, "check right bearing");
+
+ cmp_ok($bbox->display_width, '>', $bbox->advance_width,
+ "check display width (roughly)");
+
+ # check with a char that fits inside the box
+ $bbox = $hcfont->bounding_box(string=>"!", size=>100);
+ print "# @$bbox\n";
+ print "# pos width ", $bbox->pos_width, "\n";
+ is($bbox->pos_width, $bbox->advance_width,
+ "check backwards compatibility");
+ cmp_ok($bbox->left_bearing, '>', 0, "left bearing positive");
+ cmp_ok($bbox->right_bearing, '>', 0, "right bearing positive");
+ cmp_ok($bbox->display_width, '<', $bbox->advance_width,
+ "display smaller than advance");
}
undef $hcfont;
BEGIN { $| = 1; print "1..20\n"; }
END {print "not ok 1\n" unless $loaded;}
use Imager;
-require "t/testtools.pl";
+BEGIN { require "t/testtools.pl"; }
$loaded=1;
okx(1, "loaded");
my $text="LLySja";
my @bbox=$font->bounding_box(string=>$text, 'x'=>0, 'y'=>50);
- okx(@bbox == 7, "bounding box list length");
+ isx(@bbox, 8, "bounding box list length");
$img->box(box=>\@bbox, color=>$green);
my $text="LLySja";
my @bbox=$font->bounding_box(string=>$text, 'x'=>0, 'y'=>50);
- okx(@bbox == 7, "bbox list size");
+ isx(@bbox, 8, "bbox list size");
$img->box(box=>\@bbox, color=>$green);