http://www.perlmonks.org?node_id=656108

sanPerl has asked for the wisdom of the Perl Monks concerning the following question:

Dear All,
I would like to use TTF as well as OTF fonts to create image of some string. I used use GD::Simple;. I have used following code. This is CGI and dosen't print OTF file data on screen.
use strict; use GD::Simple; use CGI; # create a new image my $query = CGI->new(); print $query->header( -type => "image/png"); my $img = GD::Simple->new(1800,1550); # built-in font $img->moveTo(10,100); $img->font('C:\WINNT\Fonts\Arial.ttf'); # Here this line dosen't work #$img->font('C:\WINNT\Zemestrostd-bk.otf'); $img->fontsize(50); $img->string('Hello World'); ######################################## print $img->png;
Please check ## Here this line dosen't work would tell you where the things are going wrong.

Replies are listed 'Best First'.
Re: OpenType Fonts support in CPAN
by talexb (Chancellor) on Dec 10, 2007 at 14:51 UTC

    As a first guess, what does $img->font(..) return? I would check the return value amd see if there is any information there. I'd also like to see a test to prove that the font file exists.

    Apart from that, does GD::Simple's code reveal anything more about the return value of the font method call? I suggest that since the man page doesn't reveal anything about the return code (bad form, IMO).

    Alex / talexb / Toronto

    "Groklaw is the open-source mentality applied to legal research" ~ Linus Torvalds

      Dear talexb
      Thanks for the reply. The real program is checking existance of font file before feeding to $img->font(...),when I say it dosen't work, it dosen't provide "Hello World" text with the requested Font on screen, inspite of font file being present in the location. It gives blank page
      I am trying to build a Font library for my company, where user will get sense of Font looks and he/she can order Font from the library. This is to take care of all licensing issues and to ensure if we can check all fonts anytime.

        OK, but what about the return code from the font method call? That's the very first place I'd look for information, with the next place being the module code.

        Alex / talexb / Toronto

        "Groklaw is the open-source mentality applied to legal research" ~ Linus Torvalds

Re: OpenType Fonts support in CPAN
by almut (Canon) on Dec 11, 2007 at 01:56 UTC

    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"); }