package fontscan

import "github.com/go-text/typesetting/fontscan"

Index

Examples

Constants

const (
	Fantasy   = "fantasy"
	Math      = "math"
	Emoji     = "emoji"
	Serif     = "serif"
	SansSerif = "sans-serif"
	Cursive   = "cursive"
	Monospace = "monospace"
)

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

Variables

var NewLangID = language.NewLangID

NewLangID is language.NewLangID.

Deprecated: use language.NewLangID instead.

Functions

func DefaultFontDirectories

func DefaultFontDirectories(logger Logger) ([]string, error)

DefaultFontDirectories return the OS-dependent usual directories for fonts, or an error if no one exists. These are the directories used by `FontMap.UseSystemFonts` to locate fonts.

Types

type FontMap

type FontMap struct {
	// contains filtered or unexported fields
}

FontMap provides a mechanism to select a font.Face from a font description. It supports system and user-provided fonts, and implements the CSS font substitutions rules.

Note that FontMap is NOT safe for concurrent use, but several font maps may coexist in an application.

FontMap is mainly designed to work with an index built by scanning the system fonts : see [UseSystemFonts] for more details.

func NewFontMap

func NewFontMap(logger Logger) *FontMap

NewFontMap return a new font map, which should be filled with the `UseSystemFonts` or `AddFont` methods. The provided logger will be used to record non-fatal errors encountered during font loading. If logger is nil, log.Default() is used.

func (*FontMap) AddFace

func (fm *FontMap) AddFace(face *font.Face, location Location, md font.Description)

[AddFace] inserts an already-loaded font.Face into the FontMap. The caller is responsible for ensuring that [md] is accurate for the face.

The order of calls to [AddFont] and [AddFace] determines relative priority of manually loaded fonts. See [ResolveFace] for details about when this matters.

Example

Code:

{
	// Open an on-disk font file.
	fontFile, _ := os.Open("myFont.ttf") // error handling omitted
	defer fontFile.Close()

	// Load it and its metadata.
	ld, _ := ot.NewLoader(fontFile) // error handling omitted
	f, _ := font.NewFont(ld)        // error handling omitted
	md := f.Describe()
	fontMap := NewFontMap(log.Default())
	fontMap.AddFace(font.NewFace(f), Location{File: fmt.Sprint(md)}, md)

	// set the font description
	fontMap.SetQuery(Query{Families: []string{"Arial", "serif"}}) // regular Aspect
	// set the script, if known in advance
	fontMap.SetScript(language.Latin)

	// `fontMap` is now ready for text shaping, using the `ResolveFace` method
}

func (*FontMap) AddFont

func (fm *FontMap) AddFont(fontFile font.Resource, fileID, familyName string) error

[AddFont] loads the faces contained in [fontFile] and add them to the font map. [fileID] is used as the [Location.File] entry returned by [FontLocation].

If `familyName` is not empty, it is used as the family name for `fontFile` instead of the one found in the font file.

An error is returned if the font resource is not supported.

The order of calls to [AddFont] and [AddFace] determines relative priority of manually loaded fonts. See [ResolveFace] for details about when this matters.

Example

Code:

{
	// Open an on-disk font file. Do not close it, as the fontMap will need to parse
	// it on-demand. If you need to close it, read all of the bytes into a bytes.Reader
	// first.
	fontFile, _ := os.Open("myFont.ttf") // error handling omitted

	fontMap := NewFontMap(log.Default())
	fontMap.AddFont(fontFile, "myFont.ttf", "My Font") // error handling omitted

	// set the font description
	fontMap.SetQuery(Query{Families: []string{"Arial", "serif"}}) // regular Aspect
	// set the script, if known in advance
	fontMap.SetScript(language.Latin)

	// `fontMap` is now ready for text shaping, using the `ResolveFace` method
}

func (*FontMap) FindSystemFont

func (fm *FontMap) FindSystemFont(family string) (Location, bool)

FindSystemFont looks for a system font with the given [family], returning the first match, or false is no one is found.

User added fonts are ignored, and the FontMap must have been initialized with [UseSystemFonts] or this method will always return false.

Family names are compared through font.Normalize.

func (*FontMap) FindSystemFonts

func (fm *FontMap) FindSystemFonts(family string) []Location

FindSystemFonts is the same as FindSystemFont, but returns all matched fonts.

func (*FontMap) FontLocation

func (fm *FontMap) FontLocation(ft *font.Font) Location

FontLocation returns the origin of the provided font. If the font was not previously returned from this FontMap by a call to ResolveFace, the zero value will be returned instead.

func (*FontMap) FontMetadata

func (fm *FontMap) FontMetadata(ft *font.Font) (family string, aspect font.Aspect)

FontMetadata returns a description of the provided font. If the font was not previously returned from this FontMap by a call to ResolveFace, the zero value will be returned instead.

Note that, for fonts added with [AddFace], it is the user provided description that is returned, not the one returned by [Font.Describe]

func (*FontMap) ResolveFace

func (fm *FontMap) ResolveFace(r rune) (face *font.Face)

ResolveFace select a font based on the current query (set by FontMap.SetQuery and FontMap.SetScript), and supporting the given rune, applying CSS font selection rules.

Fonts are tried with the following steps :

1 - Only fonts matching exacly one of the [Query.Families] are considered; the list
	is prunned to keep the best match with [Query.Aspect]
2 - Fallback fonts are considered, that is fonts with similar families and fonts
	supporting the current script; the list is also prunned according to [Query.Aspect]
3 - Fonts added manually by [AddFont] and [AddFace] (prunned according to [Query.Aspect]),
	will be searched, in the order in which they were added.
4 - All fonts matching the current script (set by [FontMap.SetScript]) are tried,
	ignoring [Query.Aspect]

If no fonts match after these steps, an arbitrary face will be returned. This face will be nil only if the underlying font database is empty, or if the file system is broken; otherwise the returned font.Face is always valid.

func (*FontMap) ResolveFaceForLang

func (fm *FontMap) ResolveFaceForLang(lang LangID) *font.Face

ResolveForLang returns the first face supporting the given language (for the actual query), or nil if no one is found.

The matching logic is similar to the one used by [ResolveFace].

func (*FontMap) SetQuery

func (fm *FontMap) SetQuery(query Query)

SetQuery set the families and aspect required, influencing subsequent [ResolveFace] calls. See also [SetScript].

func (*FontMap) SetRuneCacheSize

func (fm *FontMap) SetRuneCacheSize(size int)

SetRuneCacheSize configures the size of the cache powering FontMap.ResolveFace. Applications displaying large quantities of text should tune this value to be greater than the number of unique glyphs they expect to display at one time in order to achieve optimal performance when segmenting text by face rune coverage.

func (*FontMap) SetScript

func (fm *FontMap) SetScript(s language.Script)

SetScript set the script to which the (next) runes passed to [ResolveFace] belongs, influencing the choice of fallback fonts.

func (*FontMap) UseSystemFonts

func (fm *FontMap) UseSystemFonts(cacheDir string) error

UseSystemFonts loads the system fonts and adds them to the font map.

The first call of this method trigger a rather long scan. A per-application on-disk cache is used to speed up subsequent initialisations. Callers can provide an appropriate directory path within which this cache may be stored. If the empty string is provided, the FontMap will attempt to infer a correct, platform-dependent cache path.

NOTE: On Android, callers *must* provide a writable path manually, as it cannot be inferred without access to the Java runtime environment of the application.

Multiple font maps may call this method concurrently, without duplicating the work of finding the system fonts.

Example

Code:

{
	fontMap := NewFontMap(log.Default())
	fontMap.UseSystemFonts("cachdir") // error handling omitted

	// set the font description
	fontMap.SetQuery(Query{Families: []string{"Arial", "serif"}}) // regular Aspect
	// set the script, if known in advance
	fontMap.SetScript(language.Latin)
	// `fontMap` is now ready for text shaping, using the `ResolveFace` method
}

type Footprint

type Footprint struct {
	// Location stores the adress of the font resource.
	Location Location

	// Family is the general nature of the font, like
	// "Arial"
	// Note that, for performance reason, we store the
	// normalized version of the family name.
	Family string

	// Runes is the set of runes supported by the font.
	Runes RuneSet

	// Scripts is the set of scripts deduced from [Runes]
	Scripts ScriptSet

	// Langs is the set of languages deduced from [Runes]
	Langs LangSet

	// Aspect precises the visual characteristics
	// of the font among a family, like "Bold Italic"
	Aspect font.Aspect
	// contains filtered or unexported fields
}

Footprint is a condensed summary of the main information about a font, serving as a lightweight surrogate for the original font file.

func SystemFonts

func SystemFonts(logger Logger, cacheDir string) ([]Footprint, error)

SystemFonts loads the system fonts, using an index stored in [cacheDir]. See FontMap.UseSystemFonts for more details.

If [logger] is nil, log.Default() is used.

type LangID

type LangID = language.LangID

LangID is a compact representation of a language this package has orthographic knowledge of.

type LangSet

type LangSet [8]uint64

LangSet is a bit set for 512 languages

It works as a map[LangID]bool, with the limitation that only the 9 low bits of a LangID are used. More precisely, the page of a LangID l is given by its 3 "higher" bits : 8-6 and the bit position by its 6 lower bits : 5-0

func (*LangSet) Add

func (ls *LangSet) Add(l LangID)

func (LangSet) Contains

func (ls LangSet) Contains(l LangID) bool

func (LangSet) String

func (ls LangSet) String() string

type Location

type Location = font.FontID

Location identifies where a font.Face is stored.

type Logger

type Logger interface {
	Printf(format string, args ...interface{})
}

Logger is a type that can log warnings.

type Query

type Query struct {
	// Families is a list of required families,
	// the first having the highest priority.
	// Each of them is tried until a suitable match is found.
	Families []string

	// Aspect selects which particular face to use among
	// the font matching the family criteria.
	Aspect font.Aspect
}

Query exposes the intention of an author about the font to use to shape and render text.

type RuneSet

type RuneSet []runePage

RuneSet is an efficient implementation of a rune set (that is a map[rune]bool), used to store the Unicode points supported by a font, and optimized to deal with consecutive runes.

func (*RuneSet) Add

func (rs *RuneSet) Add(r rune)

Add adds `r` to the rune set.

func (RuneSet) Contains

func (rs RuneSet) Contains(r rune) bool

Contains returns `true` if `r` is in the set.

func (RuneSet) Delete

func (rs RuneSet) Delete(r rune)

Delete removes the rune from the rune set.

func (RuneSet) Len

func (a RuneSet) Len() int

Len returns the number of runes in the set.

type ScriptSet

type ScriptSet []language.Script

ScriptSet is a set of scripts, implemented as a sorted slice of unique, increasing scripts

Source Files

fontconfig.go fontmap.go footprint.go langset.go langset_gen.go lru.go match.go rune_coverage.go scan.go scandir.go serialize.go substitutions.go substitutions_table.go

Version
v0.3.0 (latest)
Published
Feb 21, 2025
Platform
linux/amd64
Imports
23 packages
Last checked
16 hours ago

Tools for package owners.