What is FreeType?
FreeType is the industry-standard open-source font rendering engine, used in virtually every major computing platform. It loads and decodes font files in every common format — TrueType (TTF), OpenType (OTF), WOFF, Type 1, CFF, PCF, and more — and renders individual glyphs to pixel bitmaps with high-quality anti-aliasing.
At small sizes, FreeType's hinting engine snaps glyph outlines to the pixel grid so characters remain crisp and readable. At larger sizes it produces smooth, sub-pixel-accurate outlines. Three hinting strategies are available: TrueType native bytecode hints (best for screen text), FreeType's own auto-hinter (good for OpenType/CFF), and no hinting (best for large sizes or subpixel rendering).
FreeType powers Android, Chrome, Firefox, the entire Linux desktop stack (GTK, Qt, Pango, Cairo), LibreOffice, SDL2_ttf, and many embedded systems. It is the de-facto standard for anything that draws text.
Ubuntu/Debian: sudo apt install libfreetype-dev • Fedora/RHEL: sudo dnf install freetype-devel • macOS: brew install freetype
Font Rendering Pipeline
Every glyph goes through the same sequence of steps:
FreeType uses 26.6 fixed-point format for glyph metrics (multiply by 64 to get real pixels). The advance width tells you how far to move the pen after drawing a glyph; the bearing is the offset from the pen position to the glyph's bounding box.
Types
Opaque integer handles returned by the library. Pass them to every API call. Always free with FreeLibrary / FreeFace.
| Value | Description |
|---|---|
| rmMono | 1-bit monochrome bitmap (aliased, sharp edges) |
| rmNormal | 8-bit grayscale anti-aliased (most common mode) |
| rmLCD | Horizontal subpixel rendering for LCD screens (R,G,B strips) |
| rmLCDV | Vertical subpixel rendering for rotated LCD panels |
| Field | Type | Description |
|---|---|---|
| Width | Integer | Width in pixels (LCD mode: divide by 3 for visual pixels) |
| Rows | Integer | Height in pixels |
| Pitch | Integer | Bytes per row (may be negative for bottom-up bitmaps) |
| PixelMode | TFTPixelMode | pmMono / pmGray / pmLCD / pmLCDV |
| Data | string | Raw pixel bytes |
| Field | Description |
|---|---|
| Width / Height | Glyph bounding box size |
| HoriBearingX / Y | Left and top bearing (horizontal layout) |
| HoriAdvance | How far to advance the pen after this glyph |
| VertBearingX / Y | Bearings for vertical text layout |
| VertAdvance | Advance for vertical text layout |
| Field | Description |
|---|---|
| FamilyName / StyleName | e.g. 'Arial' / 'Bold Italic' |
| NumGlyphs / NumFaces | Total glyphs; faces in font file (usually 1) |
| IsScalable / IsFixedWidth | Vector (TTF/OTF) vs bitmap; monospace flag |
| HasKerning | Font contains a kern table |
| UnitsPerEM | Design units per Em (typically 2048 for TrueType) |
| Ascender / Descender / Height | Line metrics in design units |
Fields X and Y (Int64, 26.6 fixed-point): horizontal and vertical kerning adjustment between two adjacent glyphs.
Code Example — Render “Hello” Glyph by Glyph
uses freetype;
var
Lib : TFTLibrary;
Face : TFTFace;
Bmp : TFTBitmap;
Metrics : TFTGlyphMetrics;
C : Char;
begin
Lib := InitLibrary;
Face := NewFace(Lib, '/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf', 0);
SetPixelSize(Face, 0, 32); { 0 = auto width, 32 = height in pixels }
for C in 'Hello' do begin
LoadChar(Face, Ord(C)); { GetGlyphIndex + LoadGlyph in one call }
RenderGlyph(Face, rmNormal); { 8-bit grayscale anti-aliased }
Bmp := GetBitmap(Face);
Metrics := GetMetrics(Face);
{ Bmp.Data holds Bmp.Rows * Bmp.Pitch bytes of grayscale pixel data }
{ Pen advance (pixels) = Metrics.HoriAdvance div 64 }
{ blit Bmp.Data to your screen surface at the current pen position }
end;
FreeFace(Face);
FreeLibrary(Lib);
end.
API Reference
Library
| Function | Description |
|---|---|
| InitLibrary(): TFTLibrary | Initialize the FreeType library. Call once per process. |
| FreeLibrary(Lib) | Release the library and all associated resources. |
| FreeTypeVersion(): string | Return the linked FreeType version string (e.g. "2.13.2"). |
Face (font file)
| Function | Description |
|---|---|
| NewFace(Lib, Path, FaceIndex): TFTFace | Load a font face from a file path. FaceIndex 0 = first face. |
| NewFaceMemory(Lib, Data, FaceIndex): TFTFace | Load a font face from an in-memory byte string. |
| FreeFace(Face) | Release a font face handle. |
| GetFaceInfo(Face): TFTFaceInfo | Return family name, style, glyph count, line metrics, flags. |
Size Selection
| Function | Description |
|---|---|
| SetPixelSize(Face, Width, Height) | Set rendering size in pixels. Pass 0 for Width to auto-compute from height. |
| SetCharSize(Face, WidthPt, HeightPt, HorizDPI, VertDPI) | Set size in points at a given DPI (typically 72 or 96). Use for print-quality output. |
Glyph Rendering
| Function | Description |
|---|---|
| GetGlyphIndex(Face, Codepoint): Integer | Map a Unicode codepoint to a glyph index. Returns 0 if not in font. |
| LoadGlyph(Face, GlyphIndex) | Load a glyph by its index into the glyph slot. |
| LoadChar(Face, Codepoint) | Convenience: GetGlyphIndex + LoadGlyph in one call. |
| RenderGlyph(Face, Mode) | Render the loaded glyph to a bitmap using the given TFTRenderMode. |
| GetBitmap(Face): TFTBitmap | Return the rendered bitmap from the glyph slot. |
| GetMetrics(Face): TFTGlyphMetrics | Return advance width, bearing, and bounding box (26.6 fixed-point). |
Kerning
| Function | Description |
|---|---|
| GetKerning(Face, LeftGlyph, RightGlyph): TFTKerning | Return the kerning adjustment (X, Y) between two adjacent glyph indices. Both indices must come from GetGlyphIndex. |
Text Metrics & Convenience
| Function | Description |
|---|---|
| MeasureText(Face, Text): Integer | Return the total advance width of a UTF-8 string in pixels. |
| GetTextBounds(Face, Text; out Width, Height) | Return bounding box dimensions of a UTF-8 string. |
| RenderText(Face, Text): TFTBitmap | Render a full UTF-8 string to an 8-bit grayscale bitmap in one call. |
| RenderTextRGBA(Face, Text, R, G, B): TFTBitmap | Render a UTF-8 string to an RGBA bitmap with the given color, ready for direct alpha-blending onto a surface. |
FreeType renders individual glyphs to bitmaps. For complex scripts, ligatures, and right-to-left text you need
HarfBuzz alongside it. HarfBuzz runs the shaping algorithm: it decides which glyphs
to use (applying ligature substitutions, mark positioning, RTL reordering) and tells you the exact X/Y placement
of each glyph. FreeType then renders each glyph at those coordinates. For simple Latin text FreeType alone
is sufficient; for Arabic, Devanagari, or full Unicode shaping, use the harfbuzz PPM package
together with this one.
Install
libfreetype-devPackage Info
API
- InitLibrary()
- FreeLibrary(Lib)
- FreeTypeVersion()
- NewFace(Lib, Path, Idx)
- NewFaceMemory(Lib, Data, Idx)
- FreeFace(Face)
- GetFaceInfo(Face)
- SetPixelSize(Face, W, H)
- SetCharSize(Face, Wpt, Hpt, HDPI, VDPI)
- GetGlyphIndex(Face, Cp)
- LoadGlyph(Face, Idx)
- LoadChar(Face, Cp)
- RenderGlyph(Face, Mode)
- GetBitmap(Face)
- GetMetrics(Face)
- GetKerning(Face, L, R)
- MeasureText(Face, Text)
- GetTextBounds(Face, Text, W, H)
- RenderText(Face, Text)
- RenderTextRGBA(Face, Text, R, G, B)
Powers Android, Chrome, Firefox, Linux desktop (GTK, Qt, Pango, Cairo), LibreOffice, SDL2_ttf, and most embedded systems with a display.
Divide metric fields by 64 to convert to pixels. E.g. HoriAdvance div 64 = pixel advance.