PHP/GD: Better Freetype2

Access more Freetype2 properties from PHP/gd.

Warning The software in this article is highly outdated and unsupported. It might still work, I don’t know and I don’t care.

Useless chatter

I love fonts. In my teenage years, when I had (well.. I still have one collecting dust somewhere) an Amiga computer, I once paid a huge phone bill for calling to PageStream's BBS, to download a huge (for the time) bunch of fonts.

Years ago, at the office, our graphist made images with PhotoShop.. like they do just about everywhere. PhotoShop however is clueless about rendering fonts: it completely ignores font hintings! Even after years, CS3 still does the same (except without anti-aliasing, either they fixed it, or I'm dreaming).

Anyway, other applications like PaintShopPro render fonts correctly, but.. it's not the Graphist Way (!) to use such a tool.

So.. having toyed much with freetype2, I decided to make a PHP web app allowing to upload, manage, select fonts, and render text using any Freetype2 property. (Obviously this can't be the Graphist Way either, but I'm not a graphist ;)

The patch described on this page was initially made when I built that system. I have since ported it from PHP3 to PHP4 to PHP5.0, and now, after a light cleanup, here it is for PHP 5.2.5.

I'm not releasing any older patches.. don't ask for them (the 5.2.5 one should probably work as is with 5.0). The older versions included the ability to handle PostScript metric files (.afm/.pfm), but this was too dirty. If you need to include PostScript metrics, convert your font to OpenType using some commercial application like FontLab's FontLab Studio or TransType, or the [FontForge]( free software.


  • If your version of freetype2 is compiled without the bytecode interpreter, it will render fonts with its automatic hinter instead. In a few cases, it'll provide a better output, but most of the time, it'll be the opposite! See Freetype's patents page for more information.
  • Many Linux distributions package a Freetype2 without the bytecode interpreter compiled in.


This is a patch adding the possibility to specify more of Freetype2 properties from within PHP's gd extension.

It allows, amongst other things, to set the render DPI, force Freetype2's Autohinting, render in monochrome (no anti-aliasing), skip hinting and create a “faux italic” (often called “oblique”).


Get the appropriate patch from this page (the 5.2.5 patch should work with 5.0.*).

Get PHP's source code and extract it. Go to the "php-(version)" directory, and apply the patch. For example:

$ zcat /some/where/php-gd-ft2-5.2.5.diff.gz | patch -p1

Configure, make, make install. For example:

$ ./configure --with-jpeg-dir=/usr --with-png-dir=/usr --with-zlib-dir=/usr \
    --with-freetype-dir=/usr --enable-gd-native-ttf --with-gd=shared
$ make
$ sudo make install

Enjoy (or not).


Here are a few samples generated with Freetype2 using the Arial TrueType font. The two PhotoShop samples display, in order, the anti-aliasing settings None, Sharp, Crisp, Strong and Smooth.

Please note that if a font is designed with TrueType hinting (like most quality fonts), it was designed to look like the "Normal" samples below (rendered using the bytecode interpreter).

Render at 12pt varying DPI:

72dpi (=12px):

Render at 8pt varying render type:

No Hinting:
8pt no hinting
Normal (Font hints):
8pt normal
8pt autohints
Mono + Auto:
8pt auto mono
8pt mono
8pt photoshop

Render at 18pt varying render type:

No Hinting:
18pt no hinting
Normal (Font hints):
18pt normal
18pt autohints
Mono + Auto:
18pt auto mono
18pt mono
18pt photoshop

Render at 18pt varying various options:

Slanted 12 degrees:
18pt slanted 12
70% width:
18pt 70pct width


All the settings are passed using imagefttext()'s extrainfo parameter, which is supposed to be an array. The following table lists the properties:

PHP Name Freetype2 Name
load_no_scale FT_LOAD_NO_SCALE
load_no_hinting FT_LOAD_NO_HINTING
load_no_bitmap FT_LOAD_NO_BITMAP
load_force_autohint FT_LOAD_FORCE_AUTOHINT
load_ignore_transform FT_LOAD_IGNORE_TRANSFORM
load_monochrome FT_LOAD_MONOCHROME
load_linear_design FT_LOAD_LINEAR_DESIGN
load_no_autohint FT_LOAD_NO_AUTOHINT
hdpi Horizontal DPI (default 96)
vdpi Vertical DPI (default 96)
screenres Shortcut to set both hdpi and vdpi
slant_angle "Faux italic", float in degrees (default 0)
advance_mult character spacing multiplication, float (default 1.0)
width_mult width multiplication, float (default 1.0)
height_mult height multiplication, float (default 1.0)

For more information on FT_LOAD_*, have a look at Freetype2's API.

DPI, Points

DPI means "dot per inch". There are 72 points in one inch.

If the resolution is 72 dpi and you want to render at 13 pixels, you select "13 points".

If the resolution is 96 dpi and you want 13 pixels, you want 13 × 96 ÷ 72 = 9.75pt. You can only pass integers to freetype2 (and thus GD), so you have to round it up to 10pt.


$opts = array('load_monochrome'=>1, 'screenres' => 72);
ImageFtText($img, 12, 0, $xpos, $ypos, $color, 'arial.ttf', "Hello World", $opts);




  • Fixed bug: when $extrainfo is omitted, advance_mult, width_mult and height_mult were left to 0, causing no output or, in imageftbox()'s case, bad calculations
  • Cosmetic changes to the code
  • Fixed bug: was assuming the presence of an initialized strex in libgd, which wasn't the case when using the “non-extended” functions imagettf*() (thanks to Jason Young)