Documentation
¶
Overview ¶
Package sfnt reads the parts of a TrueType or OpenType font that embedding one in a PDF needs, and cuts a subset of it down to the glyphs a document actually uses.
It is deliberately not a font library. It does not rasterize, it does not shape, it does not kern, and it reads no table it has no use for. What it answers is the four questions github.com/timzifer/refract/backend/pdf has to ask before it can write a font into a document: which glyph is this rune, how wide is that glyph, what does the font descriptor say about the face, and what is the smallest file that still draws these glyphs.
It lives in the core module because the core module has no dependencies and keeps none — see AGENTS.md — and because parsing a table-directory format is a few hundred lines of `binary.BigEndian` and nothing else.
What it supports ¶
TrueType outlines — a `glyf` and `loca` pair — are parsed and can be subset. CFF outlines, which is what an `.otf` file usually carries, are recognised and *not* subset: the charstring format is a second interpreter and cutting one up correctly is a different project. Such a font is embedded whole, which is a correct document and a larger one; Font.CanSubset is how a caller finds out which it has.
Bitmap-only fonts, `ttc` collections and variable-font instancing are out of scope and are refused rather than half-read.
Index ¶
- Variables
- type Font
- func (f *Font) Advance(g uint16) int
- func (f *Font) Ascent() int
- func (f *Font) BBox() (xMin, yMin, xMax, yMax int)
- func (f *Font) CFF() bool
- func (f *Font) CanSubset() bool
- func (f *Font) CapHeight() int
- func (f *Font) Descent() int
- func (f *Font) GlyphIndex(r rune) uint16
- func (f *Font) HasUnicodeMap() bool
- func (f *Font) ItalicAngle() float64
- func (f *Font) NumGlyphs() int
- func (f *Font) PostScriptName() string
- func (f *Font) Raw() []byte
- func (f *Font) Subset(order []uint16) (data []byte, final []uint16, err error)
- func (f *Font) UnitsPerEm() int
- func (f *Font) WeightClass() int
Constants ¶
This section is empty.
Variables ¶
var ErrFormat = errors.New("refract/internal/sfnt: unsupported font file")
ErrFormat reports a file this package cannot read.
Functions ¶
This section is empty.
Types ¶
type Font ¶
type Font struct {
// contains filtered or unexported fields
}
Font is a parsed font.
It borrows the bytes it was parsed from: the tables are slices into the caller's buffer, so the buffer must outlive the Font. That is the same bargain github.com/timzifer/refract/data.Float64Columns makes about a column, for the same reason — a font file is a megabyte and copying it to read four tables would be the only allocation in the package worth naming.
func (*Font) Ascent ¶
Ascent, Descent, CapHeight and the bounding box are the descriptor's numbers, in font units. Descent is negative, as the font stores it.
func (*Font) CFF ¶
CFF reports whether the outlines are CFF charstrings, which decides which PDF font subtype the caller has to write.
func (*Font) CanSubset ¶
CanSubset reports whether this font's outlines can be cut down. It is true for TrueType outlines and false for CFF ones — see the package comment.
func (*Font) GlyphIndex ¶
GlyphIndex maps a rune to a glyph, returning 0 — .notdef — for a rune the font has no glyph for.
func (*Font) HasUnicodeMap ¶
HasUnicodeMap reports whether the font carries a character map this package can read. A font without one — which includes every subset Font.Subset writes — answers 0 for every rune, because a CID font addresses glyphs by id and never asks.
func (*Font) ItalicAngle ¶
ItalicAngle is degrees anticlockwise from vertical, negative for a face that leans right.
func (*Font) PostScriptName ¶
PostScriptName is the font's own name, or "" when it carries none.
func (*Font) Raw ¶
Raw returns the bytes the font was parsed from, which is what a caller embedding a font it cannot subset writes out.
func (*Font) Subset ¶
Subset builds a font file holding only the glyphs in order, renumbered so that glyph i of the result is order[i] of the original.
The caller decides the order and the result honours it, which is what lets a PDF writer hand out a glyph id the moment it first sees a rune and write the content stream immediately, rather than buffering the whole document until it knows which glyphs it used. First-appearance order is also what makes the output a pure function of the input — the same rule [ADR 0012](../../docs/adr/0012-parallel-panels.md) puts on everything else in this repository that could have reached for a map.
order[0] must be glyph 0, the .notdef glyph: every TrueType font has one and every consumer assumes glyph 0 is it.
A composite glyph refers to other glyphs, so the subset is closed over those references: the components are appended to order and the returned slice is the order the result actually uses, which is order with whatever it pulled in. A caller that assigned ids from its own copy of order therefore keeps them — nothing already in the list moves.
func (*Font) WeightClass ¶
WeightClass is the OS/2 usWeightClass, or 0 for a font that carries none.