module=>'Imager/Font/Truetype.pm',
files=>'.*\.ttf$',
description => 'FreeType 1.x',
+ checktype => 1,
},
t1=>{
class=>'Imager::Font::Type1',
module=>'Imager/Font/Type1.pm',
files=>'.*\.pfb$',
description => 'T1Lib',
+ checktype => 1,
},
ft2=>{
class=>'Imager::Font::FT2',
undef $type;
my $re = $drivers{$drv}{files} or next;
if ($file =~ /$re/i) {
- $type = $drv;
- last;
+ if (eval { require $drivers{$drv}{module}; 1 }) {
+ $type = $drv;
+ last;
+ }
}
}
}
return;
}
- if (!$Imager::formats{$type}) {
+ if ($drivers{$type}{checktype} && !$Imager::formats{$type}) {
$Imager::ERRSTR = "`$type' not enabled";
return;
}
my @old = @priority;
if (@_) {
- @priority = grep Imager::i_has_format($_), @_;
+ @priority = @_;
}
return @old;
}
+sub register {
+ my ($self, %opts) = @_;
+
+ my $type = delete $opts{type};
+ my $class = delete $opts{class};
+ my $files = delete $opts{files};
+ my $description = delete $opts{description} || $class;
+
+ defined $type
+ or return Imager->_set_error("No type parameter supplied to Imager::Font->regster");
+
+ defined $class
+ or return Imager->_set_error("No class parameter supplied to Imager::Font->register");
+
+ if ($files) {
+ eval { qr/$files/ }
+ or return Imager->_set_error("files isn't a valid regexp");
+ }
+
+ if ($drivers{$type} && $drivers{$type}{class} ne $class) {
+ Imager->_set_error("Font type $type already registered as $drivers{$type}{class}");
+ return;
+ }
+
+ (my $module = $class . ".pm") =~ s(::)(/)g;
+
+ my $driver =
+ {
+ class => $class,
+ module => $module,
+ description => $description,
+ };
+ $files and $driver->{files} = $files;
+
+ $drivers{$type} = $driver;
+
+ 1;
+}
+
1;
__END__
@old = Imager::Font->priorities(@drivers);
-=back
-
If you supply driver names that are not currently supported, they will
be ignored.
my @old = Imager::Font->priorities(qw(tt ft2 t1));
+=item register
+
+Registers an extra font driver. Accepts the following parameters:
+
+=over
+
+=item *
+
+type - a brief identifier for the font driver. You can supply this
+value to C<< Imager::Font->new() >> to create fonts of this type.
+Required.
+
+=item *
+
+class - the font class name. Imager will attempted to load this
+module by name. Required.
+
+=item *
+
+files - a regular expression to match against file names. If supplied
+this must be a valid perl regular expression. If not supplied you can
+only create fonts of this type by supplying the C<type> parameter to
+C<< Imager::Font->new() >>
+
+=item *
+
+description - a brief description of the font driver. Defaults to the
+value supplied in C<class>.
+
+=back
+
+=back
+
=head1 AUTHOR
Arnar M. Hrafnkelsson, addi@umich.edu
=head1 BUGS
-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
--- /dev/null
+#!perl -w
+use strict;
+use Imager;
+use Test::More tests => 10;
+
+unshift @INC, "t";
+
+ok(Imager::Font->register(type => "test",
+ class=>"GoodTestFont",
+ files => "\\.ppm\$"),
+ "register a test font");
+
+ok(Imager::Font->register(type => "bad",
+ class => "BadTestFont",
+ files => "\\.ppm\$"),
+ "register a bad test font");
+
+ok(!Imager::Font->register(), "no register parameters");
+like(Imager->errstr, qr/No type parameter/, "check message");
+
+ok(!Imager::Font->register(type => "bad1"), "no class parameter");
+like(Imager->errstr, qr/No class parameter/, "check message");
+
+ok(!Imager::Font->register(type => "bad2", class => "BadFont", files => "**"),
+ "bad files parameter");
+is(Imager->errstr, "files isn't a valid regexp", "check message");
+
+Imager::Font->priorities("bad", "test");
+
+# RT #62855
+# previously we'd select the first file matched font driver, even if
+# it wasn't available, then crash loading it.
+
+SKIP:
+{
+ my $good;
+ ok(eval {
+ $good = Imager::Font->new(file => "testimg/penguin-base.ppm");
+ }, "load good font avoiding RT 62855")
+ or skip("Failed to load", 1);
+ ok($good->isa("GoodTestFont"), "and it's the right type");
+}