This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
FFI layer: cl-ft2/ffi
cl-ft2/ffi is a direct transcription, on cl-ffi, of the part of the FreeType 2 C API that cl-ft2 uses. Nothing in it checks errors or manages lifetimes: functions return raw FT_Error integers, and handles are raw pointers. Use it to reach FreeType fields and functions that the idiomatic layer does not wrap.
Naming
C names are spelled the usual Lisp way:
| C | Lisp |
|---|---|
FT_Load_Glyph |
ft-load-glyph |
FT_FaceRec |
(:struct ft-face-rec) |
horiBearingX |
hori-bearing-x |
FT_Pos, FT_Fixed, FT_F26Dot6 |
ft-pos, ft-fixed, ft-f26dot6 (all :long) |
Two names change, to avoid clashing with cl:format and cl:string: the format field of FT_GlyphSlotRec and FT_GlyphRec is glyph-format, and FT_SfntName.string is name-string. Struct slot names are exported symbols of cl-ft2/ffi, such as cl-ft2/ffi:num-glyphs and cl-ft2/ffi:x-ppem.
Bridging from cl-ft2
library-handle and face-handle return the raw FT_Library and FT_Face of live cl-ft2 objects. They signal an error if the object has been destroyed. The pointers stay valid until destroy-library or destroy-face. Never free them yourself.
;; Read the hinting deltas of the glyph in the slot (FT_GlyphSlotRec.lsb_delta
;; and rsb_delta), which cl-ft2 does not expose. They are non-zero mainly when
;; the auto-hinter runs, e.g. with :target :light.
(defun glyph-deltas (face)
(let ((slot (cl-ffi:foreign-slot-value (ft2:face-handle face)
'(:struct cl-ft2/ffi:ft-face-rec)
'cl-ft2/ffi:glyph)))
(values (/ (cl-ffi:foreign-slot-value slot '(:struct cl-ft2/ffi:ft-glyph-slot-rec)
'cl-ft2/ffi:lsb-delta)
64)
(/ (cl-ffi:foreign-slot-value slot '(:struct cl-ft2/ffi:ft-glyph-slot-rec)
'cl-ft2/ffi:rsb-delta)
64))))
Contents
Foreign library
libfreetype, loaded when the system loads. See Installation.
Scalar types
ft-error, ft-pos, ft-fixed, ft-f26dot6, ft-long, ft-ulong, ft-int, ft-uint, ft-int32, ft-short, ft-ushort, ft-byte. Each maps to the cl-ffi type of the same C width, so the layouts follow the platform's data model (LP64 or LLP64) without per-platform code.
Enums and bitfields
| Type | Kind | Values |
|---|---|---|
ft-encoding |
enum | :none :ms-symbol :unicode :sjis :prc :big5 :wansung :johab :adobe-standard :adobe-expert :adobe-custom :adobe-latin-1 :old-latin-2 :apple-roman |
ft-glyph-format |
enum | :none :composite :bitmap :outline :plotter :svg |
ft-pixel-mode |
enum | :none :mono :gray :gray2 :gray4 :lcd :lcd-v :bgra |
ft-render-mode |
enum | :normal :light :mono :lcd :lcd-v :sdf |
ft-kerning-mode |
enum | :default :unfitted :unscaled |
ft-load-flags |
bitfield (ft-int32) |
see load flags. FT_LOAD_TARGET_… is not included; it goes in bits 16–19 |
ft-face-flags |
bitfield (ft-long) |
see face flags |
ft-style-flags |
bitfield (ft-long) |
:italic :bold (the high 16 bits hold the instance count) |
ft-glyph-bbox-mode |
enum | :unscaled :gridfit :truncate :pixels |
ft-stroker-linecap |
enum | :butt :round :square |
ft-stroker-linejoin |
enum | :round :bevel :miter-variable :miter-fixed |
ft-var-axis-flags |
bitfield (ft-uint) |
:hidden |
ft-outline-flags |
bitfield (:int) |
:owner :even-odd-fill :reverse-fill :ignore-dropouts :smart-dropouts :include-stubs :overlap :high-precision :single-pass, the values of FT_Outline.flags |
(encoding-tag "unic") packs a four-character tag into the 32-bit value used by FT_ENC_TAG and FT_IMAGE_TAG.
To build a raw load-flags value with a target:
(logior (cl-ffi:foreign-bitfield-value 'cl-ft2/ffi:ft-load-flags '(:no-bitmap))
(ash (cl-ffi:foreign-enum-value 'cl-ft2/ffi:ft-render-mode :light) 16))
Structs
ft-vector, ft-matrix, ft-bbox, ft-generic, ft-bitmap-size, ft-charmap-rec, ft-face-rec, ft-size-metrics, ft-size-rec, ft-glyph-metrics, ft-bitmap, ft-outline, ft-glyph-slot-rec, ft-outline-funcs, ft-glyph-rec, ft-outline-glyph-rec, ft-bitmap-glyph-rec, ft-var-axis, ft-var-named-style, ft-mm-var, ft-sfnt-name.
The layouts are written by hand from freetype.h, ftimage.h, fttypes.h, ftglyph.h, ftmm.h and ftsnames.h. The records that FreeType allocates and that are only read through a pointer (ft-face-rec, ft-size-rec, ft-glyph-slot-rec) stop after their last public field. Never allocate them yourself. Note that ft-glyph-rec's advance is 16.16 fixed point, while the glyph slot's is 26.6.
Functions
| Area | Functions |
|---|---|
| Library | ft-init-freetype, ft-done-freetype, ft-library-version |
| Faces | ft-new-face, ft-new-memory-face, ft-done-face, ft-get-postscript-name, ft-get-font-format |
| Sizes | ft-set-char-size, ft-set-pixel-sizes, ft-select-size, ft-set-transform |
| Glyphs | ft-load-glyph, ft-load-char, ft-render-glyph, ft-get-kerning, ft-get-advance |
| Charmaps | ft-get-char-index, ft-get-first-char, ft-get-next-char, ft-get-glyph-name, ft-get-name-index, ft-select-charmap, ft-set-charmap, ft-get-charmap-index |
| Outlines | ft-outline-decompose, ft-outline-get-cbox, ft-outline-new, ft-outline-done, ft-outline-get-bitmap |
| Glyph objects | ft-get-glyph, ft-glyph-copy, ft-glyph-transform, ft-glyph-get-cbox, ft-glyph-to-bitmap, ft-done-glyph |
| Strokers | ft-stroker-new, ft-stroker-set, ft-stroker-done, ft-glyph-stroke, ft-glyph-stroke-border, ft-stroker-parse-outline, ft-stroker-get-counts, ft-stroker-export |
| Variations | ft-get-mm-var, ft-done-mm-var, ft-get-var-axis-flags, ft-set-var-design-coordinates, ft-get-var-design-coordinates, ft-set-var-blend-coordinates, ft-get-var-blend-coordinates, ft-set-named-instance, ft-get-default-named-instance |
| SFNT names | ft-get-sfnt-name-count, ft-get-sfnt-name |
Arguments follow the C signatures. Out-parameters are pointers you allocate, for example with cl-ffi:with-foreign-object.
Extending the FFI
To call a FreeType function that cl-ft2/ffi does not bind, define it yourself with the package's types:
(cl-ffi:defcfun ("FT_Library_SetLcdFilter" ft-library-set-lcd-filter) cl-ft2/ffi:ft-error
(library :pointer)
(filter :int)) ; FT_LCD_FILTER_NONE 0, DEFAULT 1, LIGHT 2, LEGACY 16
(let ((code (ft-library-set-lcd-filter (ft2:library-handle lib) 2)))
(unless (zerop code)
(warn "FT_Library_SetLcdFilter failed with FreeType error ~D" code)))
Raw calls return error codes and never signal. Check them yourself, as above.