pdf-truetype
TOC »
Description
pdf-truetype provides functionality to embed TrueType fonts in documents created with the pdf egg, and draws text in them.
The standard fonts from pdf's build-font are not stored in the file: the viewer supplies them, so text can look different from one viewer to the next. This egg embeds a TrueType font file in the document instead, so the text always looks the same. Every metric the PDF needs (the widths of the characters, ascent, descent, cap height, italic angle, bounding box) is read from the font file itself, so it always matches the embedded font.
Text is encoded in WinAnsiEncoding, which covers the Latin-1 characters and common typographic symbols such as the euro sign, dashes and curly quotes. Embedded fonts are also what pdfa needs for PDF/A archival documents.
Author
Repository
This egg is hosted on the CHICKEN Subversion repository:
https://anonymous@code.call-cc.org/svn/chicken-eggs/release/6/pdf-truetype
If you want to check out the source code repository of this egg and you are not familiar with Subversion, see this page.
Requirements
pdf, srfi-1, srfi-13, matchable
Documentation
Supported fonts
A font file can be embedded if:
- it is a TrueType font (with glyf outlines); OpenType fonts with CFF outlines (usually .otf files) are not supported;
- it has a Windows Unicode (platform 3, encoding 1) character map in format 4, as almost all text fonts do; symbol fonts are not supported;
- it has a licence that allows embedding. A font whose licence (its OS/2 fsType field) forbids embedding is still embedded, with a warning, but pdfa rejects it.
The whole font file is embedded; fonts are not subset. Each embedded font covers the WinAnsi codes 32 to 255.
Embedding fonts
build-embedded-font
- build-embedded-font DOC TTF-PATH #!key BASE-NAME AFM-PATH FLAGS FONT-BBOX ITALIC-ANGLE ASCENT DESCENT CAP-HEIGHT STEM-Vprocedure
Embeds the TrueType font in the file TTF-PATH in DOC and returns an embedded-font. Use it with pdf's set-font through embedded-font-name, just as a build-font font is used through font-name.
BASE-NAME sets the font's name in the PDF; it defaults to the font file's PostScript name. Characters not allowed in PDF names (spaces, delimiters such as parentheses, and #) are removed, and a name left empty is an error.
FLAGS, FONT-BBOX (a vector of four numbers), ITALIC-ANGLE, ASCENT, DESCENT, CAP-HEIGHT and STEM-V replace the values otherwise read from the font file, in the 1000-units-per-em scale PDF uses. They are rarely needed. The stem width (/StemV) is not recorded in TrueType files, so by default it is estimated from the font's weight.
AFM-PATH, if given, names an AFM metrics file whose widths are registered with pdf's pdf-font module, for its get-char-width and get-string-width. It does not change what is written into the PDF. embedded-font-string-width measures text from the font file directly.
Raises an error if the file cannot be read as a supported TrueType font.
embedded-font?
- embedded-font? Xprocedure
Tests whether X is an embedded font.
embedded-font-name
- embedded-font-name FONTprocedure
Returns the resource name of FONT, for set-font, e.g. "/LiberationSans101".
embedded-font-string-width
- embedded-font-string-width FONT STRING SIZEprocedure
Returns the width of STRING set in FONT at SIZE, in the same units as SIZE (normally points). The widths are exactly those written in the PDF, so this is suitable for centring, right-aligning and line breaking. Raises an error for a character that embedded-font-has-glyph? rejects.
embedded-font-has-glyph?
- embedded-font-has-glyph? FONT CHARprocedure
Returns true if CHAR can be drawn in FONT: it has a WinAnsi code, and the font has a glyph for it.
embedded-font-truetype
- embedded-font-truetype FONTprocedure
Returns the truetype-font metrics FONT was built from (see below).
embedded-font-fs-type
- embedded-font-fs-type FONTprocedure
- embedded-font-restricted? FONTprocedure
embedded-font-fs-type returns the embedding permissions recorded in FONT's file (the OS/2 fsType value). embedded-font-restricted? returns true when they forbid embedding.
Drawing text
pdf's text operators write their strings unchanged. Text in an embedded font should be drawn with the procedures below instead, which map each character to its WinAnsi code, escape the result for a PDF string, and raise an error, naming the character and its position, for any character the font cannot draw. A missing character would otherwise be drawn as a blank.
draw-encoded-text
- draw-encoded-text PAGE FONT STRINGprocedure
Draws STRING at the current text position, like pdf's draw-text. FONT is the embedded font that the page's current set-font names: set-font does not record the current font, so it is passed again here. Must be called inside in-text-mode.
draw-encoded-text-on-next-line
- draw-encoded-text-on-next-line PAGE FONT STRINGprocedure
Moves to the next line, then draws STRING, like pdf's draw-text-on-next-line. The distance between lines is set with set-text-leading.
encode-text
- encode-text FONT STRINGprocedure
Returns STRING encoded for FONT and escaped, ready for pdf's draw-text or draw-and-adjust-string. Raises an error like draw-encoded-text.
WinAnsiEncoding
winansi->unicode
- winansi->unicode CODEprocedure
- unicode->winansi CHARprocedure
Convert between WinAnsi codes (integers 0 to 255) and Unicode. winansi->unicode returns the Unicode code point of CODE, and unicode->winansi the WinAnsi code of CHAR; each returns #f when there is none. Codes 32 to 126 and 160 to 255 are the same as in Unicode; codes 128 to 159 hold characters such as €, — and “; the control codes and codes 129, 141, 143, 144 and 157 are undefined.
Reading TrueType files
These procedures read the metrics build-embedded-font uses, and are exported for programs that want them directly.
read-truetype-font
- read-truetype-font BYTEVECTORprocedure
Parses the TrueType font file held in BYTEVECTOR (see read-byte-file) and returns a truetype-font. Raises an error, naming the problem, for data that is not a supported TrueType font, is truncated, or lacks one of the required tables (head, hhea, hmtx, cmap, post).
truetype-font accessors
- truetype-font? Xprocedure
- truetype-font-units-per-em FONTprocedure
- truetype-font-bbox FONTprocedure
- truetype-font-ascent FONTprocedure
- truetype-font-descent FONTprocedure
- truetype-font-cap-height FONTprocedure
- truetype-font-italic-angle FONTprocedure
- truetype-font-fixed-pitch? FONTprocedure
- truetype-font-italic? FONTprocedure
- truetype-font-weight-class FONTprocedure
- truetype-font-fs-type FONTprocedure
- truetype-font-postscript-name FONTprocedure
- truetype-font-unicode->glyph FONTprocedure
Return the font's metrics, in the font's own design units: units per em; bounding box, as a vector #(XMIN YMIN XMAX YMAX); ascent, descent and cap height; italic angle in degrees (negative for fonts that lean right); whether every glyph has the same width; whether the font is italic; weight class (400 regular, 700 bold); embedding permissions; and PostScript name (#f if absent). truetype-font-unicode->glyph returns a procedure mapping a Unicode code point to a glyph number, or 0 when the font has no glyph for it.
truetype-glyph-advance
- truetype-glyph-advance FONT GLYPHprocedure
Returns the advance width of glyph number GLYPH, in design units.
truetype-scale
- truetype-scale FONT VALUEprocedure
Converts VALUE from FONT's design units to the 1000 units per em PDF uses, rounded to an integer.
truetype-embedding-restricted?
- truetype-embedding-restricted? FONTprocedure
Returns true when FONT's licence forbids embedding.
read-byte-file
- read-byte-file PATHprocedure
Returns the contents of the file PATH as a bytevector. Use it for binary data such as font files and ICC profiles, which should not be read into Scheme strings.
AFM metrics files
An AFM file holds a Type 1 font's metrics as text. These procedures read the parts relevant to PDF; they are kept for AFM-PATH and for programs that work with AFM files.
read-afm-file
- read-afm-file PATHprocedure
Reads the AFM file PATH and returns an afm-metrics record, with the header fields below and the width of each character code. Other parts of the file, such as kerning data, are ignored.
afm-metrics accessors
- afm-metrics? Xprocedure
- afm-metrics-name METRICSprocedure
- afm-metrics-weight METRICSprocedure
- afm-metrics-font-bbox METRICSprocedure
- afm-metrics-cap-height METRICSprocedure
- afm-metrics-x-height METRICSprocedure
- afm-metrics-italic-angle METRICSprocedure
- afm-metrics-ascent METRICSprocedure
- afm-metrics-descent METRICSprocedure
- afm-metrics-widths METRICSprocedure
- afm-metrics-first-char METRICSprocedure
- afm-metrics-last-char METRICSprocedure
Return the AFM file's FontName, Weight, FontBBox (a vector of four numbers), CapHeight, XHeight, ItalicAngle, Ascender and Descender, each #f if absent; the widths, as a list of pairs (CODE . WIDTH) in code order; and the lowest and highest codes with a width.
parse-char-metric
- parse-char-metric LINEprocedure
Parses an AFM character metrics line, such as "C 32 ; WX 250 ; N space ;", into a pair (CODE . WIDTH). Codes may be decimal (C) or hexadecimal (CH <20>), and widths WX or W0X. Returns #f for composite characters (code -1) and lines without a code or width.
parse-font-bbox
- parse-font-bbox STRINGprocedure
Parses the arguments of an AFM FontBBox line ("-100 -200 900 800") into a vector of four numbers, or #f if there are not four.
Examples
Centered text in an embedded font. The example in the repository examples.scm draws a full font specimen, with the font's metrics and a table of all its characters.
(import scheme (chicken base) pdf pdf-truetype) (define font-file "/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf") ;; Draws text centered on x, measured with the font's own widths. (define (draw-centered page font size x y text) (in-text-mode page (set-font page (embedded-font-name font) size) (move-text page (- x (/ (embedded-font-string-width font text size) 2)) y) (draw-encoded-text page font text))) (with-document-to-file (doc #t "1.4") "embedded.pdf" (let ((font (build-embedded-font doc font-file))) (with-page doc (page) (draw-centered page font 28 306 700 "Caf\xe9; \x2014; 5 \x20ac;") (draw-centered page font 12 306 670 (string-append "Set in " (truetype-font-postscript-name (embedded-font-truetype font)))))))
Version history
- 1.0
- Initial release
License
Copyright 2026 Ivan Raikov. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.