Character maps
A charmap maps character codes to glyph indexes. Most fonts have several, for different platforms and encodings. FreeType selects a Unicode charmap automatically when the face has one, so for most fonts char-index with a Lisp character just works.
Looking up glyphs
char-index face char → glyph index
The glyph index for char in the current charmap, or 0 (the .notdef glyph) if the face has no glyph for it. char is a character, which uses its char-code, or a non-negative integer code in the current charmap: the type character-or-code, which load-char and char-bitmap take too.
(ft2:char-index face #\A) ; => 36
(ft2:char-index face #x4E2D) ; => 0: DejaVu Sans has no CJK ideographs
Test for 0 to implement font fallback:
(find-if (lambda (face) (plusp (ft2:char-index face char))) fallback-faces)
glyph-index-name face glyph-index → string or nil
The glyph's PostScript name, or nil when the face has no glyph names (face-has-glyph-names-p). Names longer than 255 characters are truncated.
(ft2:glyph-index-name face 36) ; => "A"
name-index face name → glyph index
The inverse of glyph-index-name: the index of the glyph named name, or 0 if there is none.
(ft2:name-index face "A") ; => 36
Iterating
map-characters function face → nil
Calls function with (code glyph-index) for every character code mapped by the current charmap, in increasing order of code.
do-characters ((code glyph-index) face &optional result) &body body
The iteration-macro form of map-characters. body runs in an implicit block nil and tagbody, so return works.
;; Count the characters DejaVu Sans covers.
(let ((n 0))
(ft2:do-characters ((code glyph) face n)
(incf n)))
;; => 5918
;; Collect the first ten covered characters.
(let ((chars '()))
(ft2:do-characters ((code glyph) face (nreverse chars))
(push (code-char code) chars)
(when (= (length chars) 10) (return (nreverse chars)))))
;; => (#\ #\! #\" #\# #\$ #\% #\& #\' #\( #\))
Charmaps
face-charmaps face → list of charmap
Every charmap in the face, in order.
(ft2:face-charmaps dejavu)
;; => (#S(CHARMAP :ENCODING :UNICODE :PLATFORM-ID 0 :ENCODING-ID 3 :INDEX 0)
;; #S(CHARMAP :ENCODING :UNICODE :PLATFORM-ID 0 :ENCODING-ID 4 :INDEX 1)
;; #S(CHARMAP :ENCODING :APPLE-ROMAN :PLATFORM-ID 1 :ENCODING-ID 0 :INDEX 2)
;; #S(CHARMAP :ENCODING :UNICODE :PLATFORM-ID 3 :ENCODING-ID 1 :INDEX 3)
;; #S(CHARMAP :ENCODING :UNICODE :PLATFORM-ID 3 :ENCODING-ID 10 :INDEX 4))
charmap is a read-only struct:
| Accessor | Meaning |
|---|---|
charmap-encoding |
the encoding keyword (table below) |
charmap-platform-id |
TrueType/OpenType platform ID: 0 Unicode, 1 Macintosh, 3 Windows |
charmap-encoding-id |
platform-specific encoding ID. Windows 1 is the BMP, Windows 10 is full Unicode |
charmap-index |
position in face-charmaps |
face-charmap face → charmap or nil · setf
The current charmap. Above, FreeType chose index 4, the full-repertoire Unicode map.
Set it to select another charmap. The new value is one of:
- an encoding keyword, which selects the face's charmap for that encoding. It fails with
:invalid-argumentif the face has none. - a
charmapfromface-charmaps, which selects exactly that one. Use this to choose between charmaps with the same encoding, such as Windows BMP and Windows full Unicode. A charmap from another face whose index this face does not have signals:invalid-charmap-handle.
The encoding keywords are:
| Encoding keyword | Meaning |
|---|---|
:none |
no encoding |
:unicode |
Unicode (UCS-4 codes) |
:ms-symbol |
Microsoft Symbol |
:sjis |
Shift JIS |
:prc |
GB2312 / GBK |
:big5 |
Big5 |
:wansung |
Korean Wansung |
:johab |
Korean Johab |
:adobe-standard, :adobe-expert, :adobe-custom, :adobe-latin-1 |
Type 1 / CFF encodings |
:old-latin-2 |
obsolete |
:apple-roman |
Mac Roman |
These keywords make up the type encoding, which charmap-encoding returns; anything else given to (setf face-charmap) is a type-error.
(setf (ft2:face-charmap face) :apple-roman)
(ft2:char-index face 138) ; => 166, the glyph for ä (code 138 in Mac Roman)
(setf (ft2:face-charmap face) :unicode)
(ft2:char-index face #\ä) ; => 166, the same glyph
Selecting by charmap:
(setf (ft2:face-charmap face) (find 1 (ft2:face-charmaps face) :key #'ft2:charmap-encoding-id))
The charmap affects char-index, load-char, char-bitmap, map-characters and do-characters. Integer codes are interpreted in the current charmap, while a Lisp character always passes its char-code, which is a Unicode code point.