Documentation ¶
Overview ¶
Package ot provides access to OpenType font tables and features. Intended audience for this package are:
▪︎ text shapers, such as HarfBuzz (https://harfbuzz.github.io/what-does-harfbuzz-do.html)
▪︎ glyph rasterizers, such as FreeType (https://github.com/golang/freetype)
▪︎ any application needing to have the internal structure of an OpenType font file available, and possibly extending the methods of package `ot` by handling additional font tables
Package `ot` will not provide functions to interpret any table of a font, but rather just expose the tables to the client. For example, it is not possible to ask package `ot` for a kerning distance between two glyphs. Clients have to check for the availability of kerning information and consult the appropriate table(s) themselves. From this point of view, `ot` is a low-level package. Functions for getting kerning values and other layout directives from a font are homed in a sister package. Likewise, this package is not intended for font manipulation applications (you may check out https://pkg.go.dev/github.com/ConradIrwin/font for that).
OpenType fonts contain a whole lot of different tables and sub-tables. This package strives to make the semantics of the tables accessible, thus has a lot of different types for the different kinds of OT tables. This makes `ot` a shallow API, but it will nevertheless abstract away some implementation details of fonts:
▪︎ Format versions: many OT tables may occur in a variety of formats. Tables in `ot` will hide the concrete format and structure of underlying OT tables.
▪︎ Word size: offsets in OT may either be 2-byte or 4-byte values. Package `ot` will hide offset-related details (see section below).
▪︎ Bugs in fonts: many fonts in the wild contain entries that—strictly speaking—infringe upon the OT specification (for example, Calibri has an overflow in a 'kern' table variable), but an application using it should not fail because of recoverable errors. Package `ot` will try to circumvent known bugs in common fonts.
Schrödinger's Cat ¶
OpenType fonts contain quite a multitude of tables, and a package intended to expose the semantics of OT tables ought to wrap each of these into a Go type. However, this would waste both time and space, as the usage of subsets of these tables is mutually exclusive (think 'head' and 'bhea'). And it would make the API of package `ot` even more broad as it already is. We therefore focus on the most important tables to be semantically wrapped in Go types and find a different approach for other tables and their OT data structures.
The binary data of a font can be thought of as a bunch of structures connected by links. The linking is done by offsets (u16 or u32) from link anchors defined by the spec. Data-structures may be categorized into fields-like, list-like and map-like. The implementation details of these structures vary heavily, and many internal tables combine more than one category, but conceptually it should be possible to navigate the graph, spanned by links and structures, without caring about implementation details. This is where the cat comes in.
We design an abstraction resting on chains of navigation items and links. There surely is a fancy name from functional theory on this (monads on functions on font data), but I prefer to think about them as Schrödinger's cat: In the end you have to open the box in order to know if the cat is alive or dead. Before we get too quantum, however, let's consider an example. The OpenType specification flags the 'OS/2' table as mandatory (though unused on Mac platforms), but package `ot` does not offer a type for it. As a client, how do you access, e.g., OS/2.xAvgCharWidth? We start by requesting OS/2 as a vanilla table:
os2 := myfont.Table[T("OS/2")]
This should succeed unless `myfont` is broken. From there on, clients will have to consult the OpenType specification. That will tell them that xAvgCharWidth is the 2nd field (index 1) of table OS/2, right after the version field.
xAvgCharWidth := os2.Fields().Get(1).U16(0)
This will read xAvgCharWidth as an uint16, which is the data type of xAvgCharWidth according to the spec. That sure looks like a complicated way of getting a number out of a struct, but remember that we agreed on having an abstraction on top of field-likes, list-likes and map-likes. You didn't have to think about version differences in OT OS/2-tables or byte-offsets from anchors.
But I promised you a cat, you say? In fact, the example already had one included, but's let's head over to a bigger cat. The most complex OT tables, apart from glyphs themselves, include the so-called “layout-tables”.
calibri := ot.Parse(…) // find font 'Calibri' on our system gsub := calibri.Table(T("GSUB")).Self().AsGSub() // semantic Go type
GSUB is an important table for text shaping, so package `ot` offers a special type. However, this type is not exposing GSUB in full depth! Thus we type:
feats := gsub.ScriptList.LookupTag(T("latn")).Navigate().Map().LookupTag(T("TRK")).Navigate().List() fmt.Println("%d features for Turkish", feats.Len()) // => yields 24
If you happen to not know the OpenType specification by heart, I'll help you out: We want to know if the font contains features applicable for Latin script with Turkish language flavour ('Calibri' actually does). The line of code is quite a mouthful, I'll readily concede. However, if you ever wrote code to extract information from a font file, you'd probably be used to a lot of error branches like this:
latinScript, ok := GSUB.lookup("latn") // pseudo code if !ok { … // opt out } turkishLangRecord, ok := latinScript.lookup("TRK") // pseudo code if !ok { … // opt out (use default) } // etc …
So in effect, we're checking multiple times if the cat is still okay, until we eventually reach the box we're looking for. Package `ot` will let you travel the distance without reboxing the cat and just check once at the end. In other words, it's null-safe (imagine some kind of hidden Maybe-type).
Some problems arise with such an approach:
▪︎ Neither syntax nor type-system do guide you, but clients rather have to consult the OpenType specification (not a fun read).
▪︎ Oftentimes you need some trial-and-error to find the right navigation items. It's hard to completely document every path, because then one would re-write the OT tables' spec.
▪︎ To fit every OT-structure in the mould of the aforementioned three abstractions, some OT tables have to be “bended”. It's sometimes not intuitively clear what abstraction is the best, or which one `ot` would choose.
At the end of the day we will see if this approach does the job when we gain some experience with using it from a client perspective.
Status ¶
Work in progress. Handling fonts is fiddly and fonts have become complex software applications in their own right. I often need a break from the vast desert of bytes (without any sign posts), which is what font data files are at their core. A break where I talk to myself and ask, this is what you do in your spare time? Really?
No font collections nor variable fonts are supported yet, but will be in time.
License ¶
Governed by a 3-Clause BSD license. License file may be found in the root folder of this module.
Copyright © 2017–2021 Norbert Pillmayer <norbert@pillmayer.com>
Some code has originally been copied over from golang.org/x/image/font/sfnt/cmap.go, as the cmap-routines are not accessible through the sfnt package's API. I understand this to be legally okay as long as the Go license information stays intact.
Copyright 2017 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
The license file mentioned can be found in file GO-LICENSE at the root folder of this module.
Index ¶
- Constants
- Variables
- func IsGPosLookupType(ltype LayoutTableLookupType) bool
- type AttachmentPointList
- type AxisTable
- type BaseTable
- type CMapGlyphIndex
- type CMapTable
- type ClassDefinitions
- type Coverage
- type Font
- type FontHeader
- type GDefHeader
- type GDefTable
- type GPosTable
- type GSubTable
- type GlyphClassDefEnum
- type GlyphIndex
- type GlyphRange
- type HHeaTable
- type HMtxTable
- type HeadTable
- type KernSubTableInfo
- type KernTable
- type LayoutHeader
- type LayoutTable
- type LayoutTableLookupFlag
- type LayoutTableLookupType
- type LocaTable
- type Lookup
- type LookupList
- type LookupSubtable
- type MaxPTable
- type NavLink
- type NavList
- type NavLocation
- type NavMap
- type Navigator
- type SequenceContext
- type Table
- type TableSelf
- func (self TableSelf) AsCMap() *CMapTable
- func (self TableSelf) AsGDef() *GDefTable
- func (self TableSelf) AsGPos() *GPosTable
- func (self TableSelf) AsGSub() *GSubTable
- func (self TableSelf) AsHHea() *HHeaTable
- func (self TableSelf) AsHMtx() *HMtxTable
- func (self TableSelf) AsHead() *HeadTable
- func (self TableSelf) AsKern() *KernTable
- func (self TableSelf) AsLoca() *LocaTable
- func (self TableSelf) AsMaxP() *MaxPTable
- func (self TableSelf) NameTag() Tag
- type Tag
- type TagRecordMap
- type VarArray
Constants ¶
const ( GDefGlyphClassDefSection = "GlyphClassDef" GDefAttachListSection = "AttachList" GDefLigCaretListSection = "LigCaretList" GDefMarkAttachClassSection = "MarkAttachClassDef" GDefMarkGlyphSetsDefSection = "MarkGlyphSetsDef" GDefItemVarStoreSection = "ItemVarStore" )
Sections of a GDEF table.
Variables ¶
var DFLT = T("DFLT")
Functions ¶
func IsGPosLookupType ¶
func IsGPosLookupType(ltype LayoutTableLookupType) bool
Types ¶
type AttachmentPointList ¶
type AttachmentPointList struct { Coverage GlyphRange Count int // contains filtered or unexported fields }
An AttachmentPointList consists of a count of the attachment points on a single glyph (PointCount) and an array of contour indices of those points (PointIndex), listed in increasing numerical order.
type BaseTable ¶
type BaseTable struct {
// contains filtered or unexported fields
}
BaseTable, the Baseline table (BASE), provides information used to align glyphs of different scripts and sizes in a line of text, whether the glyphs are in the same font or in different fonts. BaseTable, the Glyph Definition (BSE) table, provides various glyph properties used in OpenType Layout processing.
See also https://docs.microsoft.com/en-us/typography/opentype/spec/base
func (*BaseTable) Binary ¶
func (tb *BaseTable) Binary() []byte
Binary returns the bytes of this table. Should be treatet as read-only by clients, as it is a view into the original data.
type CMapGlyphIndex ¶
type CMapGlyphIndex interface {
Lookup(rune) GlyphIndex
}
CMapGlyphIndex represents a CMap table index to receive a glyph index from a code-point.
type CMapTable ¶
type CMapTable struct { GlyphIndexMap CMapGlyphIndex // contains filtered or unexported fields }
CMapTable represents an OpenType cmap table, i.e. the table to receive glyphs from code-points.
See https://docs.microsoft.com/de-de/typography/opentype/spec/cmap
Consulting the cmap table is a very frequent operation on fonts. We therefore construct an internal representation of the looup table. A cmap table may contain more than one lookup table, but we will only instantiate the most appropriate one. Clients who need access to all the lookup tables will have to parse them themselves.
func (*CMapTable) Binary ¶
func (tb *CMapTable) Binary() []byte
Binary returns the bytes of this table. Should be treatet as read-only by clients, as it is a view into the original data.
type ClassDefinitions ¶
type ClassDefinitions struct {
// contains filtered or unexported fields
}
ClassDefinitions groups glyphs into classes, denoted as integer values.
From the spec: For efficiency and ease of representation, a font developer can group glyph indices to form glyph classes. Class assignments vary in meaning from one lookup subtable to another. For example, in the GSUB and GPOS tables, classes are used to describe glyph contexts. GDEF tables also use the idea of glyph classes. (see https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#class-definition-table)
func (*ClassDefinitions) Lookup ¶
func (cdef *ClassDefinitions) Lookup(glyph GlyphIndex) int
Lookup returns the class defined for a glyph, or 0 (= default class).
type Coverage ¶
type Coverage struct { GlyphRange GlyphRange // contains filtered or unexported fields }
Covarage denotes an indexed set of glyphs. Each LookupSubtable (except an Extension LookupType subtable) in a lookup references a Coverage table (Coverage), which specifies all the glyphs affected by a substitution or positioning operation described in the subtable. The GSUB, GPOS, and GDEF tables rely on this notion of coverage. If a glyph does not appear in a Coverage table, the client can skip that subtable and move immediately to the next subtable.
type Font ¶
type Font struct { F *font.ScalableFont Header *FontHeader // contains filtered or unexported fields }
Font represents the internal structure of an OpenType font. It is used to navigate properties of a font for typesetting tasks.
func Parse ¶
Parse parses an OpenType font from a byte slice. An ot.Font needs ongoing access to the fonts byte-data after the Parse function returns. Its elements are assumed immutable while the ot.Font remains in use.
func (*Font) Table ¶
Table returns the font table for a given tag. If a table for a tag cannot be found in the font, nil is returned.
Please note that the current implementation will not interpret every kind of font table, either because there is no need to do so (with regard to text shaping or rasterization), or because implementation is not yet finished. However, `Table` will return at least a generic table type for each table contained in the font, i.e. no table information will be dropped.
For example to receive the `OS/2` and the `loca` table, clients may call
os2 := otf.Table(ot.T("OS/2")) loca := otf.Table(ot.T("loca")).Self().AsLoca()
Table tag names are case-sensitive, following the names in the OpenType specification, i.e., one of:
avar BASE CBDT CBLC CFF CFF2 cmap COLR CPAL cvar cvt DSIG EBDT EBLC EBSC fpgm fvar gasp GDEF glyf GPOS GSUB gvar hdmx head hhea hmtx HVAR JSTF kern loca LTSH MATH maxp MERG meta MVAR name OS/2 PCLT post prep sbix STAT SVG VDMX vhea vmtx VORG VVAR
type FontHeader ¶
FontHeader is a directory of the top-level tables in a font. If the font file contains only one font, the table directory will begin at byte 0 of the file. If the font file is an OpenType Font Collection file (see below), the beginning point of the table directory for each font is indicated in the TTCHeader.
OpenType fonts that contain TrueType outlines should use the value of 0x00010000 for the FontType. OpenType fonts containing CFF data (version 1 or 2) should use 0x4F54544F ('OTTO', when re-interpreted as a Tag). The Apple specification for TrueType fonts allows for 'true' and 'typ1', but these version tags should not be used for OpenType fonts.
type GDefHeader ¶
type GDefHeader struct {
// contains filtered or unexported fields
}
GDefHeader contains general information for a Glyph Definition table (GDEF).
func (GDefHeader) Version ¶
func (h GDefHeader) Version() (int, int)
Version returns major and minor version numbers for this GDef table.
type GDefTable ¶
type GDefTable struct { GlyphClassDef ClassDefinitions AttachmentPointList AttachmentPointList MarkAttachmentClassDef ClassDefinitions MarkGlyphSets []GlyphRange // contains filtered or unexported fields }
GDefTable, the Glyph Definition (GDEF) table, provides various glyph properties used in OpenType Layout processing.
See also https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#class-definition-table
func (*GDefTable) Binary ¶
func (tb *GDefTable) Binary() []byte
Binary returns the bytes of this table. Should be treatet as read-only by clients, as it is a view into the original data.
func (*GDefTable) Extent ¶
Offset returns offset and byte size of this table within the OpenType font.
func (*GDefTable) Header ¶
func (t *GDefTable) Header() GDefHeader
Header returns the Glyph Definition header for t.
type GPosTable ¶
type GPosTable struct { LayoutTable // contains filtered or unexported fields }
GPosTable is a type representing an OpenType GPOS table (see https://docs.microsoft.com/en-us/typography/opentype/spec/gsub).
func (*GPosTable) Binary ¶
func (tb *GPosTable) Binary() []byte
Binary returns the bytes of this table. Should be treatet as read-only by clients, as it is a view into the original data.
type GSubTable ¶
type GSubTable struct { LayoutTable // contains filtered or unexported fields }
GSubTable is a type representing an OpenType GSUB table (see https://docs.microsoft.com/en-us/typography/opentype/spec/gpos).
func (*GSubTable) Binary ¶
func (tb *GSubTable) Binary() []byte
Binary returns the bytes of this table. Should be treatet as read-only by clients, as it is a view into the original data.
type GlyphClassDefEnum ¶
type GlyphClassDefEnum uint16
GlyphClassDefEnum lists the glyph classes for ClassDefinitions ('GlyphClassDef'-table).
const ( BaseGlyph GlyphClassDefEnum = iota //single character, spacing glyph LigatureGlyph //multiple character, spacing glyph MarkGlyph //non-spacing combining glyph ComponentGlyph //part of single character, spacing glyph )
type GlyphRange ¶
type GlyphRange interface { Match(g GlyphIndex) (int, bool) // is glyph ID g ByteSize() int }
GlyphRange is a type frequently used by sub-tables of layout tables (GPOS and GSUB). If an input glyph g is contained in the range, and index and true is returned, false otherwise.
type HHeaTable ¶
type HHeaTable struct { NumberOfHMetrics int // contains filtered or unexported fields }
HHeaTable contains information for horizontal layout.
func (*HHeaTable) Binary ¶
func (tb *HHeaTable) Binary() []byte
Binary returns the bytes of this table. Should be treatet as read-only by clients, as it is a view into the original data.
type HMtxTable ¶
type HMtxTable struct { NumberOfHMetrics int // contains filtered or unexported fields }
HMtxTable contains metric information for the horizontal layout each of the glyphs in the font. Each element in the contained hMetrics-array has two parts: the advance width and left side bearing. The value NumberOfHMetrics is taken from the `hhea` table. In a monospaced font, only one entry is required but that entry may not be omitted. Optionally, an array of left side bearings follows. The corresponding glyphs are assumed to have the same advance width as that found in the last entry in the hMetrics array. Since there must be a left side bearing and an advance width associated with each glyph in the font, the number of entries in this array is derived from the total number of glyphs in the font minus the value `HHea.NumberOfHMetrics`, which is copied into the HMtxTable for easier access.
func (*HMtxTable) Binary ¶
func (tb *HMtxTable) Binary() []byte
Binary returns the bytes of this table. Should be treatet as read-only by clients, as it is a view into the original data.
type HeadTable ¶
type HeadTable struct { Flags uint16 // see https://docs.microsoft.com/en-us/typography/opentype/spec/head UnitsPerEm uint16 // values 16 … 16384 are valid IndexToLocFormat uint16 // needed to interpret loca table // contains filtered or unexported fields }
HeadTable gives global information about the font. Only a small subset of fields are made public by HeadTable, as they are needed for consistency-checks. To read any of the other fields of table 'head' use:
head := otf.Table(T("head")) fields := head.Fields().Get(n) // get nth field value fields := head.Fields().All() // get a slice with all field values
See also type `Navigator`.
func (*HeadTable) Binary ¶
func (tb *HeadTable) Binary() []byte
Binary returns the bytes of this table. Should be treatet as read-only by clients, as it is a view into the original data.
type KernSubTableInfo ¶
type KernSubTableInfo struct { IsHorizontal bool // kern data may be horizontal or vertical IsMinimum bool // if false, table has kerning values, otherwise has minimum values IsOverride bool // if true, the value in this table should replace the value currently being accumulated IsCrossStream bool // if true, kerning is perpendicular to the flow of the text Offset uint16 Length uint32 }
KernSubTableInfo contains header information for a kerning sub-table. Currently only format 0 of kerning tables is supported (as does MS Windows).
type KernTable ¶
type KernTable struct {
// contains filtered or unexported fields
}
KernTable gives information about kerning and kern pairs. The kerning table contains the values that control the inter-character spacing for the glyphs in a font. OpenType™ fonts containing CFF outlines are not supported by the 'kern' table and must use the GPOS OpenType Layout table.
func (*KernTable) Binary ¶
func (tb *KernTable) Binary() []byte
Binary returns the bytes of this table. Should be treatet as read-only by clients, as it is a view into the original data.
func (*KernTable) Extent ¶
Offset returns offset and byte size of this table within the OpenType font.
func (*KernTable) SubTableInfo ¶
func (t *KernTable) SubTableInfo(n int) KernSubTableInfo
SubTableInfo returns information about a kerning sub-table. n is 0…N-1.
type LayoutHeader ¶
type LayoutHeader struct {
// contains filtered or unexported fields
}
LayoutHeader represents header information common to the layout tables.
func (LayoutHeader) Version ¶
func (h LayoutHeader) Version() (int, int)
Version returns major and minor version numbers for this layout table.
type LayoutTable ¶
type LayoutTable struct { ScriptList TagRecordMap FeatureList TagRecordMap LookupList LookupList // contains filtered or unexported fields }
LayoutTable is a base type for layout tables. OpenType specifies two such tables–GPOS and GSUB–which share some of their structure.
func (*LayoutTable) Header ¶
func (t *LayoutTable) Header() LayoutHeader
Header returns the layout table header for this GSUB table.
type LayoutTableLookupFlag ¶
type LayoutTableLookupFlag uint16
LayoutTableLookupFlag is a flag type for layout tables (GPOS and GSUB).
const ( // Note that the RIGHT_TO_LEFT flag is used only for GPOS type 3 lookups and is ignored // otherwise. It is not used by client software in determining text direction. LOOKUP_FLAG_RIGHT_TO_LEFT LayoutTableLookupFlag = 0x0001 LOOKUP_FLAG_IGNORE_BASE_GLYPHS LayoutTableLookupFlag = 0x0002 // If set, skips over base glyphs LOOKUP_FLAG_IGNORE_LIGATURES LayoutTableLookupFlag = 0x0004 // If set, skips over ligatures LOOKUP_FLAG_IGNORE_MARKS LayoutTableLookupFlag = 0x0008 // If set, skips over all combining marks LOOKUP_FLAG_USE_MARK_FILTERING_SET LayoutTableLookupFlag = 0x0010 // If set, indicates that the lookup table structure is followed by a MarkFilteringSet field. LOOKUP_FLAG_reserved LayoutTableLookupFlag = 0x00E0 // For future use (Set to zero) LOOKUP_FLAG_MARK_ATTACHMENT_TYPE_MASK LayoutTableLookupFlag = 0xFF00 // If not zero, skips over all marks of attachment type different from specified. )
Lookup flags of layout tables (GPOS and GSUB)
type LayoutTableLookupType ¶
type LayoutTableLookupType uint16
LayoutTableLookupType is a type identifier for layout lookup records (GPOS and GSUB). Enum values are different for GPOS and GSUB.
const ( GPosLookupTypeSingle LayoutTableLookupType = 1 // Adjust position of a single glyph GPosLookupTypePair LayoutTableLookupType = 2 // Adjust position of a pair of glyphs GPosLookupTypeCursive LayoutTableLookupType = 3 // Attach cursive glyphs GPosLookupTypeMarkToBase LayoutTableLookupType = 4 // Attach a combining mark to a base glyph GPosLookupTypeMarkToLigature LayoutTableLookupType = 5 // Attach a combining mark to a ligature GPosLookupTypeMarkToMark LayoutTableLookupType = 6 // Attach a combining mark to another mark GPosLookupTypeContextPos LayoutTableLookupType = 7 // Position one or more glyphs in context GPosLookupTypeChainedContextPos LayoutTableLookupType = 8 // Position one or more glyphs in chained context GPosLookupTypeExtensionPos LayoutTableLookupType = 9 // Extension mechanism for other positionings )
GPOS Lookup Type Enumeration
const ( GSubLookupTypeSingle LayoutTableLookupType = 1 // Replace one glyph with one glyph GSubLookupTypeMultiple LayoutTableLookupType = 2 // Replace one glyph with more than one glyph GSubLookupTypeAlternate LayoutTableLookupType = 3 // Replace one glyph with one of many glyphs GSubLookupTypeLigature LayoutTableLookupType = 4 // Replace multiple glyphs with one glyph GSubLookupTypeContext LayoutTableLookupType = 5 // Replace one or more glyphs in context GSubLookupTypeChainingContext LayoutTableLookupType = 6 // Replace one or more glyphs in chained context GSubLookupTypeExtensionSubs LayoutTableLookupType = 7 // Extension mechanism for other substitutions GSubLookupTypeReverseChaining LayoutTableLookupType = 8 // Applied in reverse order, replace single glyph in chaining context )
GSUB Lookup Type Enumeration
func GPosLookupType ¶
func GPosLookupType(ltype LayoutTableLookupType) LayoutTableLookupType
func GSubLookupType ¶
func GSubLookupType(ltype LayoutTableLookupType) LayoutTableLookupType
func MaskGPosLookupType ¶
func MaskGPosLookupType(ltype LayoutTableLookupType) LayoutTableLookupType
func (LayoutTableLookupType) GPosString ¶
func (lt LayoutTableLookupType) GPosString() string
GPosString interprets a layout table lookup type as a GPOS table type.
func (LayoutTableLookupType) GSubString ¶
func (lt LayoutTableLookupType) GSubString() string
GSubString interprets a layout table lookup type as a GSUB table type.
type LocaTable ¶
type LocaTable struct {
// contains filtered or unexported fields
}
LocaTable stores the offsets to the locations of the glyphs in the font, relative to the beginning of the glyph data table. By definition, index zero points to the “missing character”, which is the character that appears if a character is not found in the font. The missing character is commonly represented by a blank box or a space.
func (*LocaTable) Binary ¶
func (tb *LocaTable) Binary() []byte
Binary returns the bytes of this table. Should be treatet as read-only by clients, as it is a view into the original data.
type Lookup ¶
type Lookup struct {
// contains filtered or unexported fields
}
Lookup tables are contained in a LookupList. A Lookup table defines the specific conditions, type, and results of a substitution or positioning action that is used to implement a feature. For example, a substitution operation requires a list of target glyph indices to be replaced, a list of replacement glyph indices, and a description of the type of substitution action.
Each Lookup table may contain only one type of information (LookupType), determined by whether the lookup is part of a GSUB or GPOS table. GSUB supports eight LookupTypes, and GPOS supports nine LookupTypes
Lookup implements the NavMap interface.
func (Lookup) AsTagRecordMap ¶
func (l Lookup) AsTagRecordMap() TagRecordMap
AsTagRecordMap returns an empty TagRecordMap
func (Lookup) Lookup ¶
func (l Lookup) Lookup(g uint32) NavLocation
Lookup returns a byte segment as output of applying lookup l to input glyph g. g is shortened from 32-bit to 16-bit by using the low bits.
If g is not identified as applicable for the lookup feature, an emtpy byte segment is returned.
func (Lookup) Subtable ¶
func (l Lookup) Subtable(i int) *LookupSubtable
type LookupList ¶
type LookupList struct {
// contains filtered or unexported fields
}
A LookupList table contains an array of offsets to Lookup tables (lookupOffsets). The font developer defines the Lookup sequence in the Lookup array to control the order in which a text-processing client applies lookup data to glyph substitution or positioning operations. (See https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#lookup-list-table).
Lookup tables are essential for implementing the various OpenType font features. The details are sometimes tricky and it's often hard to remember how a lookup type works, if you're not doing it on a daily basis. As this is a low-level package, we focus on decoding the sub-tables for lookups and on abstracting the details of the specific variants of GSUB- and GPOS-lookup away, offering a map-like behaviour.
Lookups depend on sub-tables to do the actual work, which in turn may occur in various format versions. This package implements all table/sub-table variants defined by the OT spec, together with the algorithms to access their functionality.
Other packages working on top of `ot` should abstract this further and operate in terms of OT features, hiding altogether the existence of lookup lists and lookups from clients.
LookupList implements the NavList interface.
func (LookupList) All ¶
func (a LookupList) All() []NavLocation
func (LookupList) Get ¶
func (a LookupList) Get(i int) NavLocation
Get returns item #i as a byte location.
func (LookupList) Len ¶
func (a LookupList) Len() int
Len returns the number of entries in the list.
func (LookupList) Navigate ¶
func (ll LookupList) Navigate(i int) Lookup
Navigate will navigate to Lookup i in the list.
type LookupSubtable ¶
type LookupSubtable struct { LookupType LayoutTableLookupType // may differ from Lookup.Type for Type=Extension Format uint16 // lookup subtables may come in more than one format Coverage Coverage // for which glyphs is this lookup applicable Index VarArray // Index tables/arrays to lookup up substitutions/positions Support interface{} // some lookup variants use additional data }
LookupSubtable is a type for OpenType Lookup Subtables, which are the basis for Lookup operations (see https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#lookup-table).
“Each LookupType may occur in one or more subtable formats. The ‘best’ format depends on the type of substitution and the resulting storage efficiency. When glyph information is best presented in more than one format, a single lookup may define more than one subtable, as long as all the subtables are for the same LookupType.”
The interpretation of the Index-elements and the Support field depend heavily on the type of the lookup-subtable. For example, for a GSUB lookup of type 'Single Substitution Format 1' Support will be interpreted as a delta and be added to glyph IDs, while lookup type 'Ligature Substitution Format 1' will ignore the Support field and repeatedly descend into the Index tables to match glyph sequences suitable for ligature substitution. (see https://docs.microsoft.com/en-us/typography/opentype/spec/gsub#lookuptype-1-single-substitution-subtable). Package `ot` will not do this interpretation, but rather leave it to higher-protocol packages.
func (LookupSubtable) SequenceRule ¶
func (lksub LookupSubtable) SequenceRule(b fontBinSegm) sequenceRule
TODO Argument should be NavLocation, return value should be []SeqLookupRecord
SequenceRule table: Type Name Description uint16 glyphCount Number of glyphs to be matched uint16 seqLookupCount Number of SequenceLookupRecords uint16 inputSequence[glyphCount-1] Sequence of classes to be matched to the input glyph sequence, beginning with the second glyph position SequenceLookupRecord seqLookupRecords[seqLookupCount] Array of SequenceLookupRecords
type MaxPTable ¶
type MaxPTable struct { NumGlyphs int // contains filtered or unexported fields }
MaxPTable establishes the memory requirements for this font. The 'maxp' table contains a count for the number of glyphs in the font. Whenever this value changes, other tables which depend on it should also be updated.
func (*MaxPTable) Binary ¶
func (tb *MaxPTable) Binary() []byte
Binary returns the bytes of this table. Should be treatet as read-only by clients, as it is a view into the original data.
type NavLink ¶
type NavLink interface {}
NavLink is a type to represent the transfer between one Navigator item and another. Clients may use it to either arrive at the binary segment of the destination (call Jump) or to receive the destination as a Navigator item (call Navigate).
Name returns the class name of the link's destination. IsNull is used to check if this NavLink represents a link to a valid destination.
type NavList ¶
type NavList interface {}
NavList represents a sequence of—possibly unequal sized—items, addressable by position.
type NavLocation ¶
type NavLocation interface {}
NavLocation is a position at a byte within a font's binary data. It represents the start of a segment/slice of binary data.
NavLocation is always the final link of a chain of Navigator calls, giving access to underlying (unstructured) font data. It is the client's responsibility to interpret the structure and impose it onto the NavLocation's bytes.
If somewhere along a chain of navigation calls an error occured, the finally resulting NavLocation may be of size 0.
type NavMap ¶
type NavMap interface {}
NavMap wraps OpenType structures which are map-like. Lookup is always done on 32-bit values, even if the map's keys are 16-bit (will be shortened to low bytes in such cases).
TagRecordMap is a special kind of NavMap.
type Navigator ¶
type Navigator interface {}
Navigator is an interface type to wrap various kinds of OpenType structure. On any given Navigator item, not all of the functions may result in sensible values returned. For example, OpenType map-like structures will return a map with a call to `Map`, but will return an invalid `Link` and an empty `List`. A Navigator may contain more than one OT structure, thus more than one such call may return a valid non-void entry.
If a previous call in a navigation chain has caused an error, successing Navigator items will remember that error (call to `Error`) and will wrap only void Navigators (nil-safe).
type SequenceContext ¶
type SequenceContext struct { BacktrackCoverage []Coverage // for format 3 InputCoverage []Coverage // for format 3 LookaheadCoverage []Coverage // for format 3 ClassDefs []ClassDefinitions // for format 2 }
SequenceContext is a type for identifying the input sequence context for contextual lookups (see https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#common-structures-for-contextual-lookup-subtables).
Clients will receive this struct in the `Support` field of a LookupSubtable, whenever it's appropriate:
▪︎ GSUB Lookup Type 5 and 6, format 2 and 3
▪︎ GPOS Lookup Type 5 and 7, format 2 and 3
For type 5, the length of each non-void slice will be exactly 1; for type 6/7 they may be of arbitrary length. Its exact allocation will depend on the type/format combination of the lookup subtable.
type Table ¶
type Table interface { Extent() (uint32, uint32) // offset and byte size within the font's binary data Binary() []byte // the bytes of this table; should be treatet as read-only by clients Fields() Navigator // start for navigation calls Self() TableSelf // reference to itself }
Table represents one of the various OpenType font tables
Required Tables, according to the OpenType specification: 'cmap' (Character to glyph mapping), 'head' (Font header), 'hhea' (Horizontal header), 'hmtx' (Horizontal metrics), 'maxp' (Maximum profile), 'name' (Naming table), 'OS/2' (OS/2 and Windows specific metrics), 'post' (PostScript information).
Advanced Typographic Tables: 'BASE' (Baseline data), 'GDEF' (Glyph definition data), 'GPOS' (Glyph positioning data), 'GSUB' (Glyph substitution data), 'JSTF' (Justification data), 'MATH' (Math layout data).
For TrueType outline fonts: 'cvt ' (Control Value Table, optional), 'fpgm' (Font program, optional), 'glyf' (Glyph data), 'loca' (Index to location), 'prep' (CVT Program, optional), 'gasp' (Grid-fitting/Scan-conversion, optional).
For OpenType fonts based on CFF outlines: 'CFF ' (Compact Font Format 1.0), 'CFF2' (Compact Font Format 2.0), 'VORG' (Vertical Origin, optional).
Currently not used/supported: SVG font table, bitmap glyph tables, color font tables, font variations.
type TableSelf ¶
type TableSelf struct {
// contains filtered or unexported fields
}
TableSelf is a reference to a table. Its primary use is for converting a generic table to a concrete table flavour, and for reproducing the name tag of a table.
type Tag ¶
type Tag uint32
Tag is defined by the spec as: Array of four uint8s (length = 32 bits) used to identify a table, design-variation axis, script, language system, feature, or baseline
func MakeTag ¶
MakeTag creates a Tag from 4 bytes, e.g., If b is shorter or longer, it will be silently extended or cut as appropriate
MakeTag([]byte("cmap"))
type TagRecordMap ¶
type TagRecordMap interface { Name() string // OpenType specification name of this map LookupTag(Tag) NavLink // returns the link associated with a given tag Tags() []Tag // returns all the tags which the map uses as keys Count() int // number of entries in the map Get(int) (Tag, NavLink) // get entry at position n }
A TagRecordMap is a dict-type (map) to receive a data record (returned as a link) from a given tag. This kind of map is used within OpenType fonts in several instances, e.g. https://docs.microsoft.com/en-us/typography/opentype/spec/base#basescriptlist-table
For some record maps the (tag) keys are not unique (e.g., the feature-list table), so in this case the first matching entry will be returned.
type VarArray ¶
type VarArray interface { Get(i int, deep bool) (NavLocation, error) // get record at index i; if deep: query nested arrays Size() int // get the number of entries }
VarArray is a type for arrays of variable length records, which in turn may point to nested arrays of (variable size) records.
func ParseVarArray ¶
func ParseVarArray(loc NavLocation, sizeOffset, arrayDataGap int, name string) VarArray
ParseVarArray interprets a byte sequence as a `VarArray`.