-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathot_layout_src.go
170 lines (149 loc) · 7.42 KB
/
ot_layout_src.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
package tables
import (
"encoding/binary"
"fmt"
)
// Layout represents the common layout table used by GPOS and GSUB.
// The Features field contains all the features for this layout. However,
// the script and language determines which feature is used.
//
// See https://learn.microsoft.com/typography/opentype/spec/chapter2#organization
// See https://learn.microsoft.com/typography/opentype/spec/gpos
// See https://www.microsoft.com/typography/otspec/GSUB.htm
type Layout struct {
majorVersion uint16 // Major version of the GPOS table, = 1
minorVersion uint16 // Minor version of the GPOS table, = 0 or 1
ScriptList ScriptList `offsetSize:"Offset16"` // Offset to ScriptList table, from beginning of GPOS table
FeatureList FeatureList `offsetSize:"Offset16"` // Offset to FeatureList table, from beginning of GPOS table
LookupList lookupList `offsetSize:"Offset16"` // Offset to LookupList table, from beginning of GPOS table
FeatureVariations *FeatureVariation `isOpaque:""` // Offset to FeatureVariations table, from beginning of GPOS table (may be NULL)
}
func (lt *Layout) parseFeatureVariations(src []byte) (int, error) {
const layoutHeaderSize = 2 + 2 + 2 + 2 + 2
if lt.minorVersion != 1 {
return 0, nil
}
if L := len(src); L < layoutHeaderSize+4 {
return 0, fmt.Errorf("reading Layout: EOF: expected length: 4, got %d", L)
}
offset := binary.BigEndian.Uint32(src[layoutHeaderSize:])
if offset == 0 {
return 4, nil
}
if L := len(src); L < int(offset) {
return 0, fmt.Errorf("reading Layout: EOF: expected length: %d, got %d", offset, L)
}
fv, _, err := ParseFeatureVariation(src[offset:])
if err != nil {
return 0, err
}
lt.FeatureVariations = &fv
return 4, nil
}
type TagOffsetRecord struct {
Tag Tag // 4-byte script tag identifier
Offset uint16 // Offset to object from beginning of list
}
type ScriptList struct {
Records []TagOffsetRecord `arrayCount:"FirstUint16"` // Array of ScriptRecords, listed alphabetically by script tag
Scripts []Script `isOpaque:""`
}
func (sl *ScriptList) parseScripts(src []byte) error {
sl.Scripts = make([]Script, len(sl.Records))
for i, rec := range sl.Records {
var err error
if L := len(src); L < int(rec.Offset) {
return fmt.Errorf("EOF: expected length: %d, got %d", rec.Offset, L)
}
sl.Scripts[i], _, err = ParseScript(src[rec.Offset:])
if err != nil {
return err
}
}
return nil
}
type Script struct {
DefaultLangSys *LangSys `offsetSize:"Offset16"` // Offset to default LangSys table, from beginning of Script table — may be NULL
LangSysRecords []TagOffsetRecord `arrayCount:"FirstUint16"` // [langSysCount] Array of LangSysRecords, listed alphabetically by LangSys tag
LangSys []LangSys `isOpaque:""` // same length as langSysRecords
}
func (sc *Script) parseLangSys(src []byte) error {
sc.LangSys = make([]LangSys, len(sc.LangSysRecords))
for i, rec := range sc.LangSysRecords {
var err error
if L := len(src); L < int(rec.Offset) {
return fmt.Errorf("EOF: expected length: %d, got %d", rec.Offset, L)
}
sc.LangSys[i], _, err = ParseLangSys(src[rec.Offset:])
if err != nil {
return err
}
}
return nil
}
type LangSys struct {
lookupOrderOffset uint16 // = NULL (reserved for an offset to a reordering table)
RequiredFeatureIndex uint16 // Index of a feature required for this language system; if no required features = 0xFFFF
FeatureIndices []uint16 `arrayCount:"FirstUint16"` // [featureIndexCount] Array of indices into the FeatureList, in arbitrary order
}
type FeatureList struct {
Records []TagOffsetRecord `arrayCount:"FirstUint16"` // Array of FeatureRecords — zero-based (first feature has FeatureIndex = 0), listed alphabetically by feature tag
Features []Feature `isOpaque:""`
}
func (fl *FeatureList) parseFeatures(src []byte) error {
fl.Features = make([]Feature, len(fl.Records))
for i, rec := range fl.Records {
var err error
if L := len(src); L < int(rec.Offset) {
return fmt.Errorf("EOF: expected length: %d, got %d", rec.Offset, L)
}
fl.Features[i], _, err = ParseFeature(src[rec.Offset:])
if err != nil {
return err
}
}
return nil
}
type Feature struct {
featureParamsOffset uint16 // Offset from start of Feature table to FeatureParams table, if defined for the feature and present, else NULL
LookupListIndices []uint16 `arrayCount:"FirstUint16"` // [lookupIndexCount] Array of indices into the LookupList — zero-based (first lookup is LookupListIndex = 0)
}
type lookupList struct {
Lookups []Lookup `arrayCount:"FirstUint16" offsetsArray:"Offset16"` // Array of offsets to Lookup tables, from beginning of LookupList — zero based (first lookup is Lookup index = 0)
}
// Lookup is the common format for GSUB and GPOS lookups
type Lookup struct {
lookupType uint16 // Different enumerations for GSUB and GPOS
LookupFlag uint16 // Lookup qualifiers
subtableOffsets []Offset16 `arrayCount:"FirstUint16"` // [subTableCount] Array of offsets to lookup subtables, from beginning of Lookup table
MarkFilteringSet uint16 // Index (base 0) into GDEF mark glyph sets structure. This field is only present if the USE_MARK_FILTERING_SET lookup flag is set.
rawData []byte `subsliceStart:"AtStart" arrayCount:"ToEnd"`
}
type FeatureVariation struct {
majorVersion uint16 // Major version of the FeatureVariations table — set to 1.
minorVersion uint16 // Minor version of the FeatureVariations table — set to 0.
FeatureVariationRecords []FeatureVariationRecord `arrayCount:"FirstUint32"` //[featureVariationRecordCount] Array of feature variation records.
}
type FeatureVariationRecord struct {
ConditionSet ConditionSet `offsetSize:"Offset32" offsetRelativeTo:"Parent"` // Offset to a condition set table, from beginning of FeatureVariations table.
Substitutions FeatureTableSubstitution `offsetSize:"Offset32" offsetRelativeTo:"Parent"` // Offset to a feature table substitution table, from beginning of the FeatureVariations table.
}
type ConditionSet struct {
// uint16 conditionCount Number of Conditions for this condition set.
Conditions []ConditionFormat1 `arrayCount:"FirstUint16" offsetsArray:"Offset32"` // [conditionCount] Array of offsets to condition tables, from beginning of the ConditionSet table.
}
type ConditionFormat1 struct {
format uint16 // Format, = 1
AxisIndex uint16 // Index (zero-based) for the variation axis within the 'fvar' table.
FilterRangeMinValue Float214 // Minimum value of the font variation instances that satisfy this condition.
FilterRangeMaxValue Float214 // Maximum value of the font variation instances that satisfy this condition.
}
type FeatureTableSubstitution struct {
majorVersion uint16 // Major version of the feature table substitution table — set to 1
minorVersion uint16 // Minor version of the feature table substitution table — set to 0.
Substitutions []FeatureTableSubstitutionRecord `arrayCount:"FirstUint16"` // [substitutionCount] Array of feature table substitution records.
}
type FeatureTableSubstitutionRecord struct {
FeatureIndex uint16 // The feature table index to match.
AlternateFeature Feature `offsetSize:"Offset32" offsetRelativeTo:"Parent"` // Offset to an alternate feature table, from start of the FeatureTableSubstitution table.
}