# `tecs.gfx.truetype`
TrueType outlines, metrics, coverage rasterization, and signed distance fields.
A face is parsed once from the bytes of a `.ttf` or `.ttc`-free single-font
file and answers three questions: which glyph a codepoint selects, what that
glyph advances, and where its outline runs. `rasterize` turns one outline into
an antialiased coverage bitmap and `distanceField` turns that bitmap into the
field a distance-field text shader samples.
```nupp
const face, reason = tecs.gfx.truetype.parse(bytes)
assert(face, reason)
const glyph = face:glyphIndex(0x41)
const contours = tecs.gfx.truetype.outline(face, glyph, 48.0 / face.unitsPerEm)
```
Everything here works in font units until a scale is supplied. A font unit is
one of `unitsPerEm` divisions of the em square, so dividing by `unitsPerEm`
gives em units and multiplying those by a point size gives pixels.
Only the `glyf` outline format is read. A face whose outlines live in a `CFF `
table, which is what an OpenType font built from PostScript curves carries,
parses to a failure reason rather than to empty glyphs. Kerning comes from a
format-zero `kern` table when one is present; `GPOS` positioning is not read,
so a font that kerns only through `GPOS` lays out with its advance widths
alone.
## Types
### `Face` _record_
```nupp
record Face
unitsPerEm: integer
ascender: integer
descender: integer
lineGap: integer
numGlyphs: integer
glyphIndex: function(borrows self: Face, codepoint: integer): integer
advanceOf: function(borrows self: Face, glyph: integer): number
bearingOf: function(borrows self: Face, glyph: integer): number
kerningOf: function(exclusive self: Face, left: integer, right: integer): number
end
```
A parsed font file.
Immutable once `parse` returns, apart from the kerning table it fills in on
first use.
#### Methods
##### `glyphIndex`
```nupp
glyphIndex: function(borrows self: Face, codepoint: integer): integer
```
Returns the glyph one codepoint selects.
Zero is the `.notdef` glyph rather than an error, which is the glyph a font
draws for a character it does not carry, so a caller renders it instead of
branching.
###### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `borrows self` | `Face` | |
| `codepoint` | `integer` | |
###### Returns
| Type | Description |
| --- | --- |
| `integer` | |
##### `advanceOf`
```nupp
advanceOf: function(borrows self: Face, glyph: integer): number
```
Returns one glyph's horizontal advance in font units.
###### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `borrows self` | `Face` | |
| `glyph` | `integer` | |
###### Returns
| Type | Description |
| --- | --- |
| `number` | |
##### `bearingOf`
```nupp
bearingOf: function(borrows self: Face, glyph: integer): number
```
Returns one glyph's left side bearing in font units.
###### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `borrows self` | `Face` | |
| `glyph` | `integer` | |
###### Returns
| Type | Description |
| --- | --- |
| `number` | |
##### `kerningOf`
```nupp
kerningOf: function(exclusive self: Face, left: integer, right: integer): number
```
Returns the kerning between two glyphs in font units.
Reads the pairs on first use and keeps them, because a face that kerns is
asked about most of its adjacent pairs within one line of text.
###### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `exclusive self` | `Face` | |
| `left` | `integer` | |
| `right` | `integer` | |
###### Returns
| Type | Description |
| --- | --- |
| `number` | |
#### Fields
##### `unitsPerEm`
```nupp
unitsPerEm: integer
```
Read-only. Reports the em square's divisions, which every font unit in
this face is one of.
##### `ascender`
```nupp
ascender: integer
```
Read-only. Reports the distance from the baseline to the top of the
typographic ascent, in font units.
##### `descender`
```nupp
descender: integer
```
Read-only. Reports the distance from the baseline to the bottom of the
typographic descent, in font units. It is negative in every ordinary
font.
##### `lineGap`
```nupp
lineGap: integer
```
Read-only. Reports the extra leading between two lines, in font units.
##### `numGlyphs`
```nupp
numGlyphs: integer
```
Read-only. Reports how many glyphs the face holds, including `.notdef`
at index zero.
### `Outline` _type_
```nupp
type Outline = {{number}}
```
One glyph outline, as closed contours of flattened points.
Each contour is a flat array of alternating x and y in font units, with y
increasing upward the way the font file stores it. The last point joins the
first; the closing segment is not repeated.
## Functions
### `distanceField` _function_
```nupp
function distanceField(coverage: {integer}, width: integer, height: integer, spread: number): {integer}
```
Turns one coverage bitmap into a signed distance field.
The field is stored the way a distance-field shader expects it: `0.5` sits
on the outline, values above it are inside, and one texel of distance is
`0.5 / spread` of the stored range. A shader recovers coverage by
smoothstepping around `0.5`.
Distance comes from a two-pass sequential Euclidean transform over the
thresholded coverage, which is exact for the texel centers it visits and
within a fraction of a texel elsewhere. That is well inside what a spread
of several texels can represent.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `coverage` | `{integer}` | the bitmap `rasterize` produced |
| `width` | `integer` | the bitmap width in texels |
| `height` | `integer` | the bitmap height in texels |
| `spread` | `number` | the distance in texels the field reaches on each side of the outline, which must be positive |
#### Returns
| Type | Description |
| --- | --- |
| `{integer}` | a `width` times `height` array of field values from zero to 255, indexed from one, which the caller owns |
### `outline` _function_
```nupp
function outline(self: Face, glyph: integer, scale: number): Outline, number, number, number, number
```
Returns one glyph's flattened outline and its bounding box.
The box comes from the flattened points rather than from the glyph header,
so it encloses exactly what `rasterize` will fill. An empty glyph, which is
what a space is, returns no contours and a zero box.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `self` | `Face` | the parsed face |
| `glyph` | `integer` | the glyph index |
| `scale` | `number` | the font units to pixels factor the flattening is tuned for |
#### Returns
| Type | Description |
| --- | --- |
| `Outline` | the contours, in font units with y increasing upward |
| `number` | the smallest x, then the smallest y, then the largest x, then the largest y, all in font units |
| `number` | |
| `number` | |
| `number` | |
### `parse` _function_
```nupp
function parse(bytes: string): Face?, string?
```
Parses a single-font TrueType file.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `bytes` | `string` | the complete contents of a `.ttf` or `.otf` file |
#### Returns
| Type | Description |
| --- | --- |
| `Face?` | the face, or nil when the bytes are not a readable TrueType font |
| `string?` | why the bytes were rejected, when unsuccessful |
### `rasterize` _function_
```nupp
function rasterize(contours: Outline, width: integer, height: integer, originX: number, originY: number, scale: number): {integer}
```
Fills one outline into an antialiased coverage bitmap.
The bitmap runs left to right and top to bottom, so it uploads as image
rows without a flip. Font y increases upward and texel y increases
downward, which is the only place the two conventions meet.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `contours` | `Outline` | the flattened contours, in font units |
| `width` | `integer` | the bitmap width in texels, which must be positive |
| `height` | `integer` | the bitmap height in texels, which must be positive |
| `originX` | `number` | the font-unit x that lands on the bitmap's left edge |
| `originY` | `number` | the font-unit y that lands on the bitmap's top edge |
| `scale` | `number` | the font units to texels factor |
#### Returns
| Type | Description |
| --- | --- |
| `{integer}` | a `width` times `height` array of coverage from zero to 255, indexed from one, which the caller owns |