Table of Contents
Errors
freetype-error
Every failure in cl-ft2 is signalled as one flat condition class, freetype-error, a subclass of error. It covers three cases:
- A FreeType function returned a non-zero
FT_Error. - cl-ft2 saw that a call could not succeed and stopped it before it reached FreeType: a destroyed object, a glyph index out of range, a strike or instance that does not exist, an outline asked of a bitmap, or a variation on a font without axes.
- No FreeType could be loaded when cl-ft2 was. The error is named
:cannot-open-resource; its message lists each file tried and why it failed, and its hint says how to get FreeType:
cl-ft2 could not load FreeType: Could not load the foreign library LIBFREETYPE.
libfreetype.so.6: Error opening shared object "libfreetype.so.6": …
libfreetype.so: Error opening shared object "libfreetype.so": …
Install FreeType 2.13.1 or newer: on Debian or Ubuntu, libfreetype6.
On Windows the hint asks to restore native\windows-x64\freetype.dll from the repository.
| Reader | Value |
|---|---|
freetype-error-message |
what went wrong, in terms of the cl-ft2 call (a string) |
freetype-error-hint |
what to do about it (a string), or nil |
freetype-error-name |
a keyword that classifies the error, such as :cannot-open-resource, or :unknown |
freetype-error-code |
the integer FT_Error code. For errors cl-ft2 caught itself, the code FreeType uses for that kind of problem |
freetype-error-function |
the FreeType function that failed, such as "FT_New_Face", or nil when cl-ft2 caught the problem itself |
The report prints the message, then the hint, then the FreeType function and error name when there is one:
(handler-case (ft2:open-face lib "/no/such/font.ttf")
(ft2:freetype-error (e)
(values (ft2:freetype-error-name e)
(ft2:freetype-error-code e)
(princ-to-string e))))
;; => :CANNOT-OPEN-RESOURCE
;; 1
;; "Could not open the font /no/such/font.ttf: the file does not exist or cannot be read.
;; Check the path and the file's permissions.
;; (FreeType: FT_New_Face returned cannot-open-resource)"
Dispatch on freetype-error-name, not on the message text:
(defun try-open (lib path)
(handler-case (ft2:open-face lib path)
(ft2:freetype-error (e)
(case (ft2:freetype-error-name e)
((:cannot-open-resource) nil) ; missing: skip it
((:unknown-file-format :invalid-file-format) ; not a usable font
(warn "~A is not a usable font" path) nil)
(t (error e))))))
Errors you are likely to meet
| Name | Typical cause | Hint given |
|---|---|---|
:cannot-open-resource |
file missing or unreadable; when loading cl-ft2, no FreeType found | check the path and permissions; install FreeType |
:unknown-file-format |
not a font, or a format FreeType does not know | pass a font file FreeType supports |
:invalid-file-format, :invalid-table, :invalid-offset |
damaged font | use another copy |
:invalid-stream-operation |
octet vector too short or truncated | — |
:invalid-argument |
bad face index, strike that does not exist, instance index out of range, too many coordinates, unknown axis tag, variation call on a static font |
specific to the call |
:invalid-glyph-index |
index ≥ face-num-glyphs |
use char-index |
:invalid-character-code |
code not valid in the current charmap | pass a character or select a charmap |
:invalid-charmap-handle |
setting face-charmap to a charmap from another face |
pass one of this face's charmaps |
:invalid-glyph-format |
glyph-bitmap on an unrendered glyph, glyph-outline / transform-glyph / stroke-glyph on a bitmap |
render first, or load without :render |
:cannot-render-glyph |
no renderer for the glyph's format | — |
:invalid-pixel-size, :invalid-ppem |
size not available in a bitmap-only face | set face-strike to one of face-strikes |
:missing-bitmap |
strike has no image for this glyph | — |
:invalid-library-handle |
library destroyed | make a new library and keep it until you are done |
:invalid-face-handle |
face destroyed (directly or by destroy-library) |
reopen with open-face |
:invalid-handle |
glyph or stroker destroyed | make a new one |
:invalid-outline |
make-outline given arrays FreeType cannot use; the message says what is wrong |
give two coordinates and a tag for each point, and each contour's last point |
:array-too-large |
a stroke with more points than an outline holds | stroke fewer or simpler contours at a time |
:out-of-memory |
FreeType could not allocate memory | — |
:unimplemented-feature |
FreeType does not support this for this font | — |
Errors caught by cl-ft2 itself read like this:
Glyph index 999999 is out of range: DejaVu Sans has 6253 glyphs.
Glyph indexes run from 0 below FACE-NUM-GLYPHS; CHAR-INDEX gives the
glyph for a character.
The face has no bitmap strikes, so strike 0 does not exist.
Set the size of a scalable face with FACE-SIZE.
freetype-error-name knows FreeType's whole public error table (fterrdef.h), about 100 codes covering TrueType bytecode, BDF/PCF and stream errors, whether or not your FreeType was built with error strings. Module-specific codes are classified by their low byte, which is FreeType's base error.
Bad arguments: type-error
Arguments of the wrong type or kind are rejected with a standard type-error before anything reaches FreeType or cl-ffi:
- an unknown keyword for a load flag, hinting target, render mode, encoding, kerning mode, line cap, line join, stroke border or fill rule
- an
openforstroke-outlinethat is neither a boolean nor a sequence of one for each contour - a negative or non-integer size, index or radius
- a variation axis tag that is not four characters, or a box for
render-outlinebeyond 2^23 pixels - an object of the wrong kind, such as a glyph where a face belongs, or a keyword where a library belongs
(ft2:load-glyph face 1 :flags '(:bogus))
;; type-error: The value :BOGUS is not of type
;; (MEMBER :NO-SVG :BITMAP-METRICS-ONLY … :NO-HINTING :NO-SCALE)
Every exported function declares these types, so SBCL checks them on entry and warns at compile time about a constant that does not fit. The report is SBCL's:
(ft2:render-outline lib outline 4 4 :x 1e9)
;; type-error: The value 1.0e9 is not of type (REAL -8388608 8388608) when binding :X
So a freetype-error always means the arguments were well-formed: the font, the state of the object, or FreeType itself refused the call.