fontres

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 5, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package fontres implements the font resolution chain, metrics, and word wrap of doc/template.md#font-resolution.

Index

Constants

View Source
const LeadingRatio = 1.2

LeadingRatio is the baseline-to-baseline distance as a multiple of the font size.

A constant multiplier is predictable and font-independent, which is what a paginating engine wants: line spacing must not change when a typeface is substituted, because that changes what fits on a page.

The font's own suggestion -- hhea ascent + descent + lineGap -- is per-face and does exactly that.

Variables

This section is empty.

Functions

func LineWidth

func LineWidth(face *Face, line string) float64

LineWidth measures a wrapped line, which is what alignment positions.

func TextHeight

func TextHeight(face *Face, lines int) float64

TextHeight is the height a run of lines occupies.

func Wrap

func Wrap(face *Face, text string, width float64) []string

Wrap breaks text into lines that fit a box of the given width.

Breaking is greedy and by word: the longest run of words that fits goes on the line. A single word wider than the box is broken by character, since the alternative is a line that overflows silently. Explicit newlines in the text always break.

Trailing spaces at a break are dropped, so a line's measured width is the width of what is drawn.

Types

type Face

type Face struct {
	// Name is the template's name for this font.
	Name string
	Size int

	Bold      bool
	Italic    bool
	Underline bool

	// Requested is the template's typeface,
	// absent when the template pinned a file or a data blob.
	Requested string

	ResolvedFile string
	ResolvedData string
	ResolvedFace string
	ResolvedBy   ResolvedBy
	// contains filtered or unexported fields
}

Face is a resolved font at a size, and the only thing the engine measures with.

func Load

func Load(raw []byte, index int, size int) (*Face, error)

Load parses a font file for measuring, outside the resolution chain.

A renderer takes this path: the printout already names the file and the face inside it, so there is nothing left to resolve, and measuring through the same code as the engine is what keeps the two agreeing.

func (*Face) Advance

func (face *Face) Advance(char rune) float64

Advance returns a rune's advance width in points at the face's size.

Advance means hmtx throughout: the engine does not kern and does not shape, so this is the only notion of advance it has, and a renderer must be told to match. A rune the font lacks measures the .notdef glyph, which is the visible empty box the specification asks for, and is recorded as missing.

func (*Face) AdvanceUnits

func (face *Face) AdvanceUnits(char rune) (float64, bool)

AdvanceUnits returns a rune's advance in font units, which is what a monospace check compares.

func (*Face) FaceIndex

func (face *Face) FaceIndex() int

FaceIndex is the face's position inside the file it was parsed from, which is 0 for every file that is not a collection.

The printout carries it so that a renderer, handed nothing but the document, opens the same face out of a collection that the engine measured with.

func (*Face) Glyph

func (face *Face) Glyph(char rune) (uint16, bool)

Glyph maps a rune to a glyph index, reporting whether the font has it.

The mapping comes from the same cmap the engine measured through, which is what keeps a renderer's glyph choice and the printout's metrics describing one font.

func (*Face) GlyphAdvance

func (face *Face) GlyphAdvance(gid uint16) float64

GlyphAdvance returns a glyph's advance in font units.

func (*Face) Key

func (face *Face) Key() string

Key identifies a face for the printout's font table.

func (*Face) Leading

func (face *Face) Leading() float64

Leading is the baseline-to-baseline distance.

func (*Face) MissingRunes

func (face *Face) MissingRunes() []rune

MissingRunes lists the characters this face was asked for and does not have. The order is by code point rather than the map's, so that a font missing more than one glyph produces the same warning sequence on every run.

func (*Face) UnderlineMetrics

func (face *Face) UnderlineMetrics() (offset, thickness float64)

UnderlineMetrics returns the underline's offset below the baseline and its thickness, in font units.

func (*Face) Upem

func (face *Face) Upem() float64

Upem is the face's units per em, the denominator every font-unit metric below is expressed in.

func (*Face) VerticalMetrics

func (face *Face) VerticalMetrics() (ascender, descender float64)

VerticalMetrics returns the ascender and descender in font units, the descender positive downward.

They position the baseline inside the leading the printout carries; they do not decide the leading, which is a constant multiple of the size.

func (*Face) Width

func (face *Face) Width(text string) float64

Width measures a string in points.

type FaceInfo

type FaceInfo struct {
	File  string
	Index int
	// Family is name ID 16 where the font has one, and name ID 1 otherwise.
	Family string
	// Subfamily is name ID 17 or 2, read only as a last resort.
	Subfamily string
	Style     Style
	Font      *gofont.Font

	// Ascender and Descender are the face's hhea metrics in font units,
	// the descender positive downward. Both are zero for a face without
	// an hhea table.
	Ascender, Descender float64
}

FaceInfo describes one face inside a font file.

type Request

type Request struct {
	Name      string
	Typeface  string
	File      string
	Data      string
	Size      int
	Bold      bool
	Italic    bool
	Underline bool
}

Request is one `font` node: what the template asked for.

type ResolvedBy

type ResolvedBy string

ResolvedBy names the step of the resolution chain that produced a face.

const (
	ByExplicit   ResolvedBy = "explicit"
	ByHost       ResolvedBy = "host"
	ByAlias      ResolvedBy = "alias"
	BySubstitute ResolvedBy = "substitute"
)

Resolution steps, as the printout spells them.

type Resolver

type Resolver struct {
	// Strict stops resolution after an explicit file or data blob
	// and fails with the unresolved typeface named.
	Strict bool
	// BaseDir resolves a relative `font file=`.
	BaseDir string
	// Blob returns a named data blob's bytes.
	Blob func(name string) ([]byte, bool)
	// Dirs overrides the machine's font directories. Empty means
	// the platform's own, which is what a build uses; a test points it
	// at a fixture directory so that the chain can be exercised without
	// depending on what is installed.
	Dirs []string

	// Diagnostics describe the machine rather than the document --
	// a font file that could not be used, or two faces claiming one key.
	// They are surfaced by validation and by the library's hook,
	// and never enter a printout's warning list.
	Diagnostics []string
	// Warnings describe the document: a typeface that reached the substitute,
	// or a candidate substitute that is not in fact monospaced.
	Warnings []string
	// contains filtered or unexported fields
}

Resolver resolves font requests, caching what it finds.

func NewResolver

func NewResolver(baseDir string, strict bool) *Resolver

NewResolver builds a resolver.

func (*Resolver) HostFamilies

func (resolver *Resolver) HostFamilies() []string

HostFamilies lists the families the machine offers, for diagnostics.

func (*Resolver) Resolve

func (resolver *Resolver) Resolve(req Request) (*Face, error)

Resolve produces a measurable face for a request.

type Style

type Style struct {
	Bold   bool
	Italic bool
}

Style bits, read from the tables the specification ranks in order.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL