Module Hugin_font.Font
OpenType fonts.
A font is one face of an OpenType file with TrueType, CFF or CFF2 outlines, decoded once: its character map, glyph advances, pair kerning, vertical metrics, glyph outlines and their ink boxes. Two faces of Inter are bundled, regular and bold, so output is the same on every machine without system fonts; other faces load from a file's bytes with of_string or of_file.
Fonts are immutable values. Every function of this module is pure, none fails on account of a font's data once of_string returned it, and fonts may be shared between domains.
Units
Metrics and outlines are in em, the font's design size: text set at size s scales them by s. Vertical metrics are distances from the baseline, positive away from it. Outlines and boxes are in the y-down plane of the geometry conventions with the glyph's origin at (0, 0) on the baseline, so ink above the baseline has negative y.
Types
type tThe type for fonts.
type glyph = intThe type for glyph ids. They index the font's glyph table, from 0 to glyph_count f - 1. Glyph 0 is .notdef, which fonts draw for characters they lack, often as a box.
The type for slants: upright, italic, or upright letterforms slanted.
Bundled faces
Inter is distributed under the SIL Open Font License 1.1. The bundled faces are subsets covering Latin and Greek letters, digits, punctuation, arrows and common mathematical symbols, without Cyrillic or CJK. Their digits are tabular: the ten share one advance, so numbers set in a column align.
Loading
type error = The type for loading errors. Each message says what is at fault and where, for users.
of_string s is Ok f if s is an OpenType font file with TrueType (glyf), CFF (CFF ) or CFF2 (CFF2) outlines, and Error e otherwise. Decoding reads the tables head, hhea, maxp, hmtx, cmap, and loca and glyf or the CFF table, and OS/2, name, post, GPOS and kern when present, and checks all it reads, every glyph outline included, so that later queries cannot fail.
CFF outlines are read as Adobe Technical Notes #5176, The Compact Font Format Specification, and #5177, The Type 2 Charstring Format, state them, and CFF2 outlines as OpenType's CFF2 table does: their charstrings are run, subroutines included, the argument stack holding at most 48 numbers for CFF and 513 for CFF2 and subroutines nesting at most 10 deep. Coordinates are in units of the head table's em, whatever the CFF font matrix says, and the result of an arithmetic operator is rounded to a 16.16 number.
The error is Unsupported _ for a valid font that uses what this decoder does not handle, such as a font collection, a character map without a Unicode subtable (platform 0, or platform 3 with encoding 1 or 10) of format 4 or 12, a CFF glyph built from two by the deprecated four-argument endchar, a charstring running the random operator, or one whose outline, written as one charstring without subroutines as subset writes it, takes more than 65535 bytes. It is Malformed _ for anything else, which includes a composite glyph whose components, expanded down to simple glyphs, hold more than 65535 points or more than 65535 components, and a stack or nesting beyond the limits above.
Decoding checks every glyph's outline whole, and two bounds of hugin's own, which OpenType does not set, keep that work linear in the size of the file, however its glyphs share components or subroutines: the error is Unsupported _ for a CFF glyph that runs more than 65535 bytes of charstring and subroutine code, as calls fanning out through subroutines do, and for a font whose glyphs, expanded, take more than 16_777_216 + 64 n steps for a file of n bytes, a step being a point or a component of a TrueType glyph and a byte a CFF glyph runs. A variable font decodes as its default instance.
of_file path is of_string s for the contents s of the file path, or Error (Io msg) if the file cannot be read.
Identity
A font is identified by its bytes: renderers embed a font once however many runs use it, and pictures compare fonts by equal.
bytes f is an OpenType file holding exactly the face of f. For a font from of_string it is the string decoded. PDF and SVG output embed it.
outlines f is the format of the outlines of f: `Truetype for quadratic glyf outlines and `Cff for cubic CFF or CFF2 ones.
family f is the typographic family name of f (name ID 16) if it has one and its family name (name ID 1) otherwise, or "" if f names no family. A name is read from the US English Windows Unicode record (platform 3, encoding 1 or 10, language 0x409) if there is one, else from the first Windows Unicode record in table order, else from the first Macintosh Roman one (platform 1, encoding 0).
postscript_name f is the PostScript name of f (name ID 6), the name PDF output gives the font, read as family reads names, or "" if f has none.
weight f is the weight class of f from its OS/2 table, clamped to [1;1000]: 400 is regular and 700 bold. It is 400 without an OS/2 table.
slant f is `Italic if the OS/2 table of f marks it italic, or its head table does when it has no OS/2 table; `Oblique if OS/2 marks it oblique; and `Normal otherwise.
pp ppf f formats the family, weight and slant of f for debugging, the family as Run.pp formats text.
Subsetting
subset f gs is an OpenType file holding the face of f cut down to the glyphs it keeps: glyph 0, the glyphs gs, and the components of every composite glyph it keeps. PDF output embeds it in place of bytes, so that a document carries only the glyphs it shows.
Glyphs keep their ids, so a run of glyphs of gs draws the same from the subset as from f. Decoded by of_string, the subset is a font f' such that:
glyph_count f'is one more than the largest glyph it keeps.outline f' gisoutline f gandadvance f' gisadvance f gfor a glyphgit keeps. Any other glyph has an empty outline and a zero advance.glyph f' uisglyph f uif that glyph is kept, and0otherwise.- Its
family,postscript_name,weight,slant,ascent,descent,line_gap,italic_angleandboundsare those off, and so are itscap_heightandx_heightwhere theOS/2table offrecords them. Face-wide maxima of thehead,hheaandmaxptables are those off, which bound the glyphs it keeps. - It has no kerning: runs place its glyphs, so it holds no
GPOS,kernor other layout table.
The subset holds the tables head, hhea, maxp, hmtx, cmap and post, without glyph names, and the OS/2 and name tables of f when it has them. Its outlines are in the format of those of f (outlines): for TrueType outlines, loca and glyf, with the hinting tables cvt , fpgm, prep and gasp of f when it has them; for CFF and CFF2 outlines, a CID-keyed CFF table whose glyph i is CID i, each outline one charstring without hints or subroutines, which PDF output embeds as an OpenType font program. It depends only on f and the set of glyphs gs: their order and repetitions do not change a byte.
Raises Invalid_argument if a glyph of gs is not in [0;glyph_count f - 1].
Metrics
descent f is the distance below the baseline that lines of f reserve, from the table ascent reads.
line_gap f is the extra space f puts between the descent of a line and the ascent of the next, from the table ascent reads.
cap_height f is the height of flat capital letters above the baseline: the OS/2 value if f records a positive one, else the top of the ink of f's glyph for H if it has ink, else ascent, as CSS assumes.
x_height f is the height of flat lowercase letters above the baseline: the OS/2 value if f records a positive one, else the top of the ink of f's glyph for x if it has ink, else 0.5, as CSS assumes.
italic_angle f is the angle of f's upright strokes from the vertical, in radians, negative when they lean right (the sign of OpenType and PDF, opposite to the plane's convention for angles), from the post table. It is 0. for an upright face or without a post table.
val bounds : t -> Hugin_gg.Box2.tbounds f is the box enclosing every glyph of f as recorded in its head table.
Glyphs
Functions that take a glyph raise Invalid_argument if it is not in [0;glyph_count f - 1].
glyph f u is the glyph f's character map gives u, and 0 if it gives none or gives a glyph f does not have.
advance f g is the horizontal distance the pen moves after drawing g (hmtx).
kerning f g g' is the change to advance f g when g' follows g, usually negative. It is the sum, over the set of lookups that any kern feature of the GPOS table refers to, each counted once whatever the number of features or scripts referencing it, of the x advance of the first pair adjustment of that lookup covering the pair. Other adjustments are ignored. A font whose GPOS table has no kern feature, or that has no GPOS table, uses its kern table instead: the sum of the values that its horizontal format 0 subtables give the pair, minimum and cross-stream subtables excluded. A font with neither has no kerning.
val outline : t -> glyph -> Hugin_gg.Path.toutline f g is the outline of g, unhinted, to be filled under the nonzero rule. Its quadratic or cubic curves are exact, composite glyphs are the union of their transformed components, and a glyph without ink, such as a space, is Hugin_gg.Path.empty. A CFF contour is closed by a line back to its start, and a moveto followed by no segment draws nothing. Its ink box is ink.
val ink : t -> glyph -> Hugin_gg.Box2.t optionink f g is Path.bounds (outline f g), the smallest box containing the ink of g, or None if g has no ink. It is recorded when f is decoded, so ink builds no outline.