AFAIK, GD doesn't (yet) support OpenType fonts.
There's Font::FreeType, however, a binding to the powerful
FreeType 2 library, which provides access to
the individual glyphs of a font etc. FreeType 2 supports OpenType
(among other formats like TrueType and Type 1).
Unfortunately, Font::FreeType doesn't necessarily build out
of the box... (I had to mess with FreeType.xs and Makefile.PL
to get it compiled). In other words, try to find a ready-to-install,
compiled package for your platform, if possible.
Using Font::FreeType is an admittedly somewhat low-level
approach (as you have to write code to render individual glyphs), but
unless someone comes up with a better suggestion, you could at least
use it as a last resort.
Below is some sample code to render "Hello world!" as well as a
glyph table (showing all chars from codepoint 32 to 255), which should
give you an idea how to use the module. I've also put up the PNG sample
output here
and here,
so you can decide for yourself, whether it's worth the trouble getting
the necessary tools installed (Font::FreeType, libfreetype, ghostscript).
I'm using the $glyph->postscript() method to render
individual glyphs indirectly via PostScript (and ghostscript). Font::FreeType::Glyph also
provides a bitmap method, but assembling individual glyph bitmaps into
a composite image looked more daunting to me than simply making use of
PostScript... (the postscript method outputs the glyph outlines
as snippets in PS syntax, which can easily be positioned and concatenated).
HTH, and good luck!
#!/usr/bin/perl
use strict;
use warnings;
for my $fontfile ( 'MinionPro-BoldIt.otf' # comes with Acrobat Reader
# ...
# (you probably want to specify the full paths)
) {
my $demo = OpenTypeDemo->new(
font => $fontfile,
size => 30, # in points
);
$demo->print_text("Hello world!");
$demo->print_glyph_table();
}
package OpenTypeDemo;
use Font::FreeType;
sub new {
my $class = shift;
my $self = { @_ };
my $freetype = Font::FreeType->new();
$self->{face} = $freetype->face($self->{font});
$self->{face}->set_char_size($self->{size}, $self->{size}, 100, 10
+0);
return bless $self, $class;
}
sub _print_glyph {
my ($fh, $x, $y, $ps) = @_;
print $fh "gsave $x $y translate newpath $ps closepath fill gresto
+re\n";
}
sub _generate_png {
my ($ps_fname, $png_fname) = @_;
# use ghostscript to render into bitmap (PNG) format
# (you might want to fiddle with the settings (in particular -g an
+d -r)...)
system "gs -q -dBATCH -dNOPAUSE -sDEVICE=pngalpha -r100 -g850x950
+-sOutputFile=$png_fname $ps_fname";
}
sub print_text {
my $self = shift;
my $text = shift;
my $tmpfile = $self->{font}.".text.ps";
open my $fh, ">", $tmpfile or die "cannot create $tmpfile: $!";
my ($x, $y) = (20, 20);
for my $char (split //, $text) {
my $glyph = $self->{face}->glyph_from_char($char);
_print_glyph($fh, $x, $y, $glyph->postscript());
my $width = $char eq " " ? $self->{size}*0.7 : $glyph->width()
++2;
$x += $width;
}
print $fh "showpage";
close $fh;
_generate_png($tmpfile, $self->{font}.".text.png");
}
sub print_glyph_table {
my $self = shift;
my $size = $self->{size};
my $tmpfile = $self->{font}.".glyph-table.ps";
open my $fh, ">", $tmpfile or die "cannot create $tmpfile: $!";
# show the Isolatin1 set (an OpenType font may also contain other
+(unicode) glyphs)
for my $charcode (32..255) {
my $glyph = $self->{face}->glyph_from_char_code($charcode);
if (ref($glyph) && $glyph->has_outline()) {
my $x = 20 + ($charcode % 16) * $size*1.2;
my $y = 16*$size*1.5 - int($charcode / 16) * $size*1.5;
_print_glyph($fh, $x, $y, $glyph->postscript());
}
}
print $fh "showpage";
close $fh;
_generate_png($tmpfile, $self->{font}.".glyph-table.png");
}
|