Wiki
Download
Manual
Eggs
API
Tests
Bugs
show
edit
You can edit this page using
wiki syntax
for markup.
Article contents:
[[tags: egg]] == 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 [[/users/ivan-raikov|Ivan Raikov]] === Repository This egg is hosted on the CHICKEN Subversion repository: [[https://anonymous@code.call-cc.org/svn/chicken-eggs/release/6/pdf-truetype|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 [[/egg-svn-checkout|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 <procedure>(build-embedded-font DOC TTF-PATH #!key BASE-NAME AFM-PATH FLAGS FONT-BBOX ITALIC-ANGLE ASCENT DESCENT CAP-HEIGHT STEM-V)</procedure> 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? <procedure>(embedded-font? X)</procedure> Tests whether {{X}} is an embedded font. ===== embedded-font-name <procedure>(embedded-font-name FONT)</procedure> Returns the resource name of {{FONT}}, for {{set-font}}, e.g. {{"/LiberationSans101"}}. ===== embedded-font-string-width <procedure>(embedded-font-string-width FONT STRING SIZE)</procedure> 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? <procedure>(embedded-font-has-glyph? FONT CHAR)</procedure> 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 <procedure>(embedded-font-truetype FONT)</procedure> Returns the {{truetype-font}} metrics {{FONT}} was built from (see below). ===== embedded-font-fs-type <procedure>(embedded-font-fs-type FONT)</procedure> <procedure>(embedded-font-restricted? FONT)</procedure> {{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 <procedure>(draw-encoded-text PAGE FONT STRING)</procedure> 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 <procedure>(draw-encoded-text-on-next-line PAGE FONT STRING)</procedure> 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 <procedure>(encode-text FONT STRING)</procedure> 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 <procedure>(winansi->unicode CODE)</procedure> <procedure>(unicode->winansi CHAR)</procedure> 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 <procedure>(read-truetype-font BYTEVECTOR)</procedure> 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 <procedure>(truetype-font? X)</procedure> <procedure>(truetype-font-units-per-em FONT)</procedure> <procedure>(truetype-font-bbox FONT)</procedure> <procedure>(truetype-font-ascent FONT)</procedure> <procedure>(truetype-font-descent FONT)</procedure> <procedure>(truetype-font-cap-height FONT)</procedure> <procedure>(truetype-font-italic-angle FONT)</procedure> <procedure>(truetype-font-fixed-pitch? FONT)</procedure> <procedure>(truetype-font-italic? FONT)</procedure> <procedure>(truetype-font-weight-class FONT)</procedure> <procedure>(truetype-font-fs-type FONT)</procedure> <procedure>(truetype-font-postscript-name FONT)</procedure> <procedure>(truetype-font-unicode->glyph FONT)</procedure> 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 <procedure>(truetype-glyph-advance FONT GLYPH)</procedure> Returns the advance width of glyph number {{GLYPH}}, in design units. ===== truetype-scale <procedure>(truetype-scale FONT VALUE)</procedure> Converts {{VALUE}} from {{FONT}}'s design units to the 1000 units per em PDF uses, rounded to an integer. ===== truetype-embedding-restricted? <procedure>(truetype-embedding-restricted? FONT)</procedure> Returns true when {{FONT}}'s licence forbids embedding. ===== read-byte-file <procedure>(read-byte-file PATH)</procedure> 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 <procedure>(read-afm-file PATH)</procedure> 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 <procedure>(afm-metrics? X)</procedure> <procedure>(afm-metrics-name METRICS)</procedure> <procedure>(afm-metrics-weight METRICS)</procedure> <procedure>(afm-metrics-font-bbox METRICS)</procedure> <procedure>(afm-metrics-cap-height METRICS)</procedure> <procedure>(afm-metrics-x-height METRICS)</procedure> <procedure>(afm-metrics-italic-angle METRICS)</procedure> <procedure>(afm-metrics-ascent METRICS)</procedure> <procedure>(afm-metrics-descent METRICS)</procedure> <procedure>(afm-metrics-widths METRICS)</procedure> <procedure>(afm-metrics-first-char METRICS)</procedure> <procedure>(afm-metrics-last-char METRICS)</procedure> 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 <procedure>(parse-char-metric LINE)</procedure> 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 <procedure>(parse-font-bbox STRING)</procedure> 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. <enscript highlight="scheme"> (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))))))) </enscript> === 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.
Description of your changes:
I would like to authenticate
Authentication
Username:
Password:
Spam control
What do you get when you multiply 5 by 6?