package
0.1.1
Repository: https://github.com/go-text/typesetting.git
Documentation: pkg.go.dev

# README

Description and purpose of the package

This package provides a way to locate and load a font.Font, which is the fundamental object needed by go-text for shaping and text rendering.

Use case

This package may be used by UI toolkits and markup language renderers. Both use-cases may need to display large quantities of text of varying languages and writing systems, and want to make use of all available fonts, both packaged within the application and installed on the system. In both cases, content/UI authors provide hints about the fonts that they want chosen (family names, weights, styles, etc...) and want the closest available match to the requested properties.

Overview of the API

The entry point of the library is the FontMap type. It should be created for each text shaping task and be filled either with system fonts (by calling UseSystemFonts) or with user-provided font files (using AddFont, AddFace), or both. To leverage all the system fonts, the first usage of UseSystemFonts triggers a scan which builds a font index. Its content is saved on disk so that subsequent usage by the same app are not slowed down by this step.

Once initialized, the font map is used to select fonts matching a Query with SetQuery. A query is defined by one or several families and an Aspect, containining style, weight, stretchiness. Finally, the font map satisfies the shaping.Fontmap interface, so that is may be used with shaping.SplitByFace.

Zoom on the implementation

Font directories

Fonts are searched by walking the file system, in the folders returned by DefaultFontDirectories, which are platform dependent. The current list is copied from fontconfig and go-findfont.

Font family substitutions

A key concept of the implementation (inspired by fontconfig) is the idea to enlarge the requested family with similar known families. This ensure that suitable font fallbacks may be provided even if the required font is not available. It is implemented by a list of susbtitutions, each of them having a test and a list of additions.

Simplified example : if the list of susbtitutions is

  • Test: the input family is Arial, Addition: Arimo
  • Test: the input family is Arimo, Addition: sans-serif
  • Test: the input family is sans-serif, Addition: DejaVu Sans et Verdana

then,

  • for the Arimo input family, [Arimo, sans-serif, DejaVu Sans, Verdana] would be matched
  • for the Arial input family, [Arial, Arimo, sans-serif, DejaVu Sans, Verdana] would be matched

To respect the user request, the order of the list is significant (first entries have higher priority).

FontMap.SetQuery apply a list of hard-coded subsitutions, extracted from Fontconfig configurations files.

Style matching

FontMap.SetQuery takes an optional argument describing the style of the required font (style, weight, stretchiness).

When no exact match is found, the CSS font selection rules are applied to return the closest match. As an example, if the user asks for (Italic, ExtraBold) but only (Normal, Bold) and (Oblique, Bold) are available, the (Oblique, Bold) would be returned.

System font index

The FontMap type requires more information than the font paths to be able to quickly and accurately match a font against family, aspect, and rune coverage query. This information is provided by a list of font summaries, which are lightweight enough to be loaded and queried efficiently.

The initial scan required to build this index has a significant latency (say between 0.2 and 0.5 sec on a laptop). Once the first scan has been done, however, the subsequent launches are fast : at the first call of UseSystemFonts, the index is loaded from an on-disk cache, and its integrity is checked against the current file system state to detect font installation or suppression.

# Functions

DefaultFontDirectories return the OS-dependent usual directories for fonts, or an error if no one exists.
NewFontMap return a new font map, which should be filled with the `UseSystemFonts` or `AddFont` methods.
NewLangID returns the compact index of the given language, or false if it is not supported by this package.

# Constants

Generic families as defined by https://www.w3.org/TR/css-fonts-4/#generic-font-families.
Generic families as defined by https://www.w3.org/TR/css-fonts-4/#generic-font-families.
Generic families as defined by https://www.w3.org/TR/css-fonts-4/#generic-font-families.
Generic families as defined by https://www.w3.org/TR/css-fonts-4/#generic-font-families.
Generic families as defined by https://www.w3.org/TR/css-fonts-4/#generic-font-families.
Generic families as defined by https://www.w3.org/TR/css-fonts-4/#generic-font-families.
Generic families as defined by https://www.w3.org/TR/css-fonts-4/#generic-font-families.

# Structs

FontMap provides a mechanism to select a [font.Face] from a font description.
Query exposes the intention of an author about the font to use to shape and render text.

# Interfaces

Logger is a type that can log warnings.

# Type aliases

LangID is a compact representation of a language this package has orthographic knowledge of.
Location identifies where a font.Face is stored.