@cantoo/fontkit 2.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +274 -0
- package/dist/browser-module.mjs +13660 -0
- package/dist/browser-module.mjs.map +1 -0
- package/dist/browser.cjs +13689 -0
- package/dist/browser.cjs.map +1 -0
- package/dist/main.cjs +13712 -0
- package/dist/main.cjs.map +1 -0
- package/dist/module.mjs +13673 -0
- package/dist/module.mjs.map +1 -0
- package/package.json +99 -0
- package/src/CmapProcessor.js +285 -0
- package/src/DFont.js +113 -0
- package/src/TTFFont.js +621 -0
- package/src/TrueTypeCollection.js +65 -0
- package/src/WOFF2Font.js +222 -0
- package/src/WOFFFont.js +56 -0
- package/src/aat/AATFeatureMap.js +545 -0
- package/src/aat/AATLayoutEngine.js +48 -0
- package/src/aat/AATLookupTable.js +125 -0
- package/src/aat/AATMorxProcessor.js +429 -0
- package/src/aat/AATStateMachine.js +96 -0
- package/src/base.js +29 -0
- package/src/cff/CFFCharsets.js +99 -0
- package/src/cff/CFFDict.js +166 -0
- package/src/cff/CFFEncodings.js +48 -0
- package/src/cff/CFFFont.js +158 -0
- package/src/cff/CFFIndex.js +150 -0
- package/src/cff/CFFOperand.js +135 -0
- package/src/cff/CFFPointer.js +50 -0
- package/src/cff/CFFPrivateDict.js +39 -0
- package/src/cff/CFFStandardStrings.js +71 -0
- package/src/cff/CFFTop.js +236 -0
- package/src/decorators.js +36 -0
- package/src/encodings.js +219 -0
- package/src/fs.js +12 -0
- package/src/glyph/BBox.js +72 -0
- package/src/glyph/CBDTGlyph.js +9 -0
- package/src/glyph/CFFGlyph.js +635 -0
- package/src/glyph/COLRGlyph.js +108 -0
- package/src/glyph/Glyph.js +270 -0
- package/src/glyph/GlyphVariationProcessor.js +487 -0
- package/src/glyph/Path.js +257 -0
- package/src/glyph/SBIXGlyph.js +54 -0
- package/src/glyph/StandardNames.js +27 -0
- package/src/glyph/TTFGlyph.js +408 -0
- package/src/glyph/TTFGlyphEncoder.js +158 -0
- package/src/glyph/WOFF2Glyph.js +70 -0
- package/src/index.js +15 -0
- package/src/layout/GlyphPosition.js +30 -0
- package/src/layout/GlyphRun.js +108 -0
- package/src/layout/KernProcessor.js +97 -0
- package/src/layout/LayoutEngine.js +190 -0
- package/src/layout/Script.js +231 -0
- package/src/layout/UnicodeLayoutEngine.js +250 -0
- package/src/node.js +16 -0
- package/src/opentype/GPOSProcessor.js +311 -0
- package/src/opentype/GSUBProcessor.js +208 -0
- package/src/opentype/GlyphInfo.js +57 -0
- package/src/opentype/GlyphIterator.js +82 -0
- package/src/opentype/OTLayoutEngine.js +117 -0
- package/src/opentype/OTProcessor.js +472 -0
- package/src/opentype/ShapingPlan.js +121 -0
- package/src/opentype/shapers/ArabicShaper.js +124 -0
- package/src/opentype/shapers/DefaultShaper.js +116 -0
- package/src/opentype/shapers/HangulShaper.js +285 -0
- package/src/opentype/shapers/HebrewShaper.js +105 -0
- package/src/opentype/shapers/IndicShaper.js +914 -0
- package/src/opentype/shapers/ThaiShaper.js +238 -0
- package/src/opentype/shapers/UniversalShaper.js +186 -0
- package/src/opentype/shapers/data.trie +0 -0
- package/src/opentype/shapers/gen-indic.js +208 -0
- package/src/opentype/shapers/gen-use.js +287 -0
- package/src/opentype/shapers/generate-data.js +33 -0
- package/src/opentype/shapers/index.js +109 -0
- package/src/opentype/shapers/indic-data.js +175 -0
- package/src/opentype/shapers/indic.json +1 -0
- package/src/opentype/shapers/indic.machine +31 -0
- package/src/opentype/shapers/indic.trie +0 -0
- package/src/opentype/shapers/use.json +1 -0
- package/src/opentype/shapers/use.machine +44 -0
- package/src/opentype/shapers/use.trie +0 -0
- package/src/packages/unicode-properties/LICENSE +8 -0
- package/src/packages/unicode-properties/README.md +12 -0
- package/src/packages/unicode-properties/data-trie.js +1 -0
- package/src/packages/unicode-properties/data.js +1 -0
- package/src/packages/unicode-properties/data.json +1 -0
- package/src/packages/unicode-properties/data.trie +0 -0
- package/src/packages/unicode-properties/dist/index.cjs +257 -0
- package/src/packages/unicode-properties/dist/index.cjs.map +7 -0
- package/src/packages/unicode-properties/dist/index.mjs +234 -0
- package/src/packages/unicode-properties/dist/index.mjs.map +7 -0
- package/src/packages/unicode-properties/generate.js +107 -0
- package/src/packages/unicode-properties/index.js +184 -0
- package/src/packages/unicode-properties/package.json +50 -0
- package/src/packages/unicode-trie/LICENSE +8 -0
- package/src/packages/unicode-trie/README.md +13 -0
- package/src/packages/unicode-trie/builder.js +965 -0
- package/src/packages/unicode-trie/dist/builder.cjs +711 -0
- package/src/packages/unicode-trie/dist/builder.cjs.map +7 -0
- package/src/packages/unicode-trie/dist/builder.mjs +690 -0
- package/src/packages/unicode-trie/dist/builder.mjs.map +7 -0
- package/src/packages/unicode-trie/dist/index.cjs +112 -0
- package/src/packages/unicode-trie/dist/index.cjs.map +7 -0
- package/src/packages/unicode-trie/dist/index.mjs +91 -0
- package/src/packages/unicode-trie/dist/index.mjs.map +7 -0
- package/src/packages/unicode-trie/index.js +135 -0
- package/src/packages/unicode-trie/package.json +49 -0
- package/src/packages/unicode-trie/swap.js +21 -0
- package/src/subset/CFFSubset.js +176 -0
- package/src/subset/Subset.js +63 -0
- package/src/subset/TTFSubset.js +130 -0
- package/src/tables/BASE.js +78 -0
- package/src/tables/COLR.js +25 -0
- package/src/tables/CPAL.js +24 -0
- package/src/tables/DSIG.js +21 -0
- package/src/tables/EBDT.js +91 -0
- package/src/tables/EBLC.js +80 -0
- package/src/tables/GDEF.js +57 -0
- package/src/tables/GPOS.js +209 -0
- package/src/tables/GSUB.js +85 -0
- package/src/tables/HVAR.js +44 -0
- package/src/tables/JSTF.js +43 -0
- package/src/tables/LTSH.js +10 -0
- package/src/tables/OS2.js +84 -0
- package/src/tables/PCLT.js +21 -0
- package/src/tables/STAT.js +99 -0
- package/src/tables/VDMX.js +33 -0
- package/src/tables/VORG.js +14 -0
- package/src/tables/WOFF2Directory.js +73 -0
- package/src/tables/WOFFDirectory.js +37 -0
- package/src/tables/aat.js +157 -0
- package/src/tables/avar.js +19 -0
- package/src/tables/bsln.js +31 -0
- package/src/tables/cmap.js +127 -0
- package/src/tables/cvt.js +6 -0
- package/src/tables/directory.js +58 -0
- package/src/tables/feat.js +28 -0
- package/src/tables/fpgm.js +8 -0
- package/src/tables/fvar.js +31 -0
- package/src/tables/gasp.js +15 -0
- package/src/tables/glyf.js +4 -0
- package/src/tables/gvar.js +27 -0
- package/src/tables/hdmx.js +15 -0
- package/src/tables/head.js +25 -0
- package/src/tables/hhea.js +19 -0
- package/src/tables/hmtx.js +11 -0
- package/src/tables/index.js +119 -0
- package/src/tables/just.js +81 -0
- package/src/tables/kern.js +91 -0
- package/src/tables/loca.js +30 -0
- package/src/tables/maxp.js +20 -0
- package/src/tables/morx.js +79 -0
- package/src/tables/name.js +157 -0
- package/src/tables/opbd.js +15 -0
- package/src/tables/opentype.js +217 -0
- package/src/tables/post.js +34 -0
- package/src/tables/prep.js +6 -0
- package/src/tables/sbix.js +17 -0
- package/src/tables/variations.js +80 -0
- package/src/tables/vhea.js +19 -0
- package/src/tables/vmtx.js +12 -0
- package/src/utils.js +62 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as r from 'restructure';
|
|
2
|
+
|
|
3
|
+
let VerticalOrigin = new r.Struct({
|
|
4
|
+
glyphIndex: r.uint16,
|
|
5
|
+
vertOriginY: r.int16
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
export default new r.Struct({
|
|
9
|
+
majorVersion: r.uint16,
|
|
10
|
+
minorVersion: r.uint16,
|
|
11
|
+
defaultVertOriginY: r.int16,
|
|
12
|
+
numVertOriginYMetrics: r.uint16,
|
|
13
|
+
metrics: new r.Array(VerticalOrigin, 'numVertOriginYMetrics')
|
|
14
|
+
});
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import * as r from 'restructure';
|
|
2
|
+
|
|
3
|
+
const Base128 = {
|
|
4
|
+
decode(stream) {
|
|
5
|
+
let result = 0;
|
|
6
|
+
let iterable = [0, 1, 2, 3, 4];
|
|
7
|
+
for (let j = 0; j < iterable.length; j++) {
|
|
8
|
+
let code = stream.readUInt8();
|
|
9
|
+
|
|
10
|
+
// If any of the top seven bits are set then we're about to overflow.
|
|
11
|
+
if (result & 0xe0000000) {
|
|
12
|
+
throw new Error('Overflow');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
result = (result << 7) | (code & 0x7f);
|
|
16
|
+
if ((code & 0x80) === 0) {
|
|
17
|
+
return result;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
throw new Error('Bad base 128 number');
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
let knownTags = [
|
|
26
|
+
'cmap', 'head', 'hhea', 'hmtx', 'maxp', 'name', 'OS/2', 'post', 'cvt ',
|
|
27
|
+
'fpgm', 'glyf', 'loca', 'prep', 'CFF ', 'VORG', 'EBDT', 'EBLC', 'gasp',
|
|
28
|
+
'hdmx', 'kern', 'LTSH', 'PCLT', 'VDMX', 'vhea', 'vmtx', 'BASE', 'GDEF',
|
|
29
|
+
'GPOS', 'GSUB', 'EBSC', 'JSTF', 'MATH', 'CBDT', 'CBLC', 'COLR', 'CPAL',
|
|
30
|
+
'SVG ', 'sbix', 'acnt', 'avar', 'bdat', 'bloc', 'bsln', 'cvar', 'fdsc',
|
|
31
|
+
'feat', 'fmtx', 'fvar', 'gvar', 'hsty', 'just', 'lcar', 'mort', 'morx',
|
|
32
|
+
'opbd', 'prop', 'trak', 'Zapf', 'Silf', 'Glat', 'Gloc', 'Feat', 'Sill'
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
let WOFF2DirectoryEntry = new r.Struct({
|
|
36
|
+
flags: r.uint8,
|
|
37
|
+
customTag: new r.Optional(new r.String(4), t => (t.flags & 0x3f) === 0x3f),
|
|
38
|
+
tag: t => t.customTag || knownTags[t.flags & 0x3f],// || (() => { throw new Error(`Bad tag: ${flags & 0x3f}`); })(); },
|
|
39
|
+
length: Base128,
|
|
40
|
+
transformVersion: t => (t.flags >>> 6) & 0x03,
|
|
41
|
+
transformed: t => (t.tag === 'glyf' || t.tag === 'loca') ? t.transformVersion === 0 : t.transformVersion !== 0,
|
|
42
|
+
transformLength: new r.Optional(Base128, t => t.transformed)
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
let WOFF2Directory = new r.Struct({
|
|
46
|
+
tag: new r.String(4), // should be 'wOF2'
|
|
47
|
+
flavor: r.uint32,
|
|
48
|
+
length: r.uint32,
|
|
49
|
+
numTables: r.uint16,
|
|
50
|
+
reserved: new r.Reserved(r.uint16),
|
|
51
|
+
totalSfntSize: r.uint32,
|
|
52
|
+
totalCompressedSize: r.uint32,
|
|
53
|
+
majorVersion: r.uint16,
|
|
54
|
+
minorVersion: r.uint16,
|
|
55
|
+
metaOffset: r.uint32,
|
|
56
|
+
metaLength: r.uint32,
|
|
57
|
+
metaOrigLength: r.uint32,
|
|
58
|
+
privOffset: r.uint32,
|
|
59
|
+
privLength: r.uint32,
|
|
60
|
+
tables: new r.Array(WOFF2DirectoryEntry, 'numTables')
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
WOFF2Directory.process = function() {
|
|
64
|
+
let tables = {};
|
|
65
|
+
for (let i = 0; i < this.tables.length; i++) {
|
|
66
|
+
let table = this.tables[i];
|
|
67
|
+
tables[table.tag] = table;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return this.tables = tables;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export default WOFF2Directory;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import * as r from 'restructure';
|
|
2
|
+
|
|
3
|
+
let WOFFDirectoryEntry = new r.Struct({
|
|
4
|
+
tag: new r.String(4),
|
|
5
|
+
offset: new r.Pointer(r.uint32, 'void', {type: 'global'}),
|
|
6
|
+
compLength: r.uint32,
|
|
7
|
+
length: r.uint32,
|
|
8
|
+
origChecksum: r.uint32
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
let WOFFDirectory = new r.Struct({
|
|
12
|
+
tag: new r.String(4), // should be 'wOFF'
|
|
13
|
+
flavor: r.uint32,
|
|
14
|
+
length: r.uint32,
|
|
15
|
+
numTables: r.uint16,
|
|
16
|
+
reserved: new r.Reserved(r.uint16),
|
|
17
|
+
totalSfntSize: r.uint32,
|
|
18
|
+
majorVersion: r.uint16,
|
|
19
|
+
minorVersion: r.uint16,
|
|
20
|
+
metaOffset: r.uint32,
|
|
21
|
+
metaLength: r.uint32,
|
|
22
|
+
metaOrigLength: r.uint32,
|
|
23
|
+
privOffset: r.uint32,
|
|
24
|
+
privLength: r.uint32,
|
|
25
|
+
tables: new r.Array(WOFFDirectoryEntry, 'numTables')
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
WOFFDirectory.process = function() {
|
|
29
|
+
let tables = {};
|
|
30
|
+
for (let table of this.tables) {
|
|
31
|
+
tables[table.tag] = table;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
this.tables = tables;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export default WOFFDirectory;
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import * as r from 'restructure';
|
|
2
|
+
|
|
3
|
+
class UnboundedArrayAccessor {
|
|
4
|
+
constructor(type, stream, parent) {
|
|
5
|
+
this.type = type;
|
|
6
|
+
this.stream = stream;
|
|
7
|
+
this.parent = parent;
|
|
8
|
+
this.base = this.stream.pos;
|
|
9
|
+
this._items = [];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
getItem(index) {
|
|
13
|
+
if (this._items[index] == null) {
|
|
14
|
+
let pos = this.stream.pos;
|
|
15
|
+
this.stream.pos = this.base + this.type.size(null, this.parent) * index;
|
|
16
|
+
this._items[index] = this.type.decode(this.stream, this.parent);
|
|
17
|
+
this.stream.pos = pos;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return this._items[index];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
inspect() {
|
|
24
|
+
return `[UnboundedArray ${this.type.constructor.name}]`;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export class UnboundedArray extends r.Array {
|
|
29
|
+
constructor(type) {
|
|
30
|
+
super(type, 0);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
decode(stream, parent) {
|
|
34
|
+
return new UnboundedArrayAccessor(this.type, stream, parent);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export let LookupTable = function(ValueType = r.uint16) {
|
|
39
|
+
// Helper class that makes internal structures invisible to pointers
|
|
40
|
+
class Shadow {
|
|
41
|
+
constructor(type) {
|
|
42
|
+
this.type = type;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
decode(stream, ctx) {
|
|
46
|
+
ctx = ctx.parent.parent;
|
|
47
|
+
return this.type.decode(stream, ctx);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
size(val, ctx) {
|
|
51
|
+
ctx = ctx.parent.parent;
|
|
52
|
+
return this.type.size(val, ctx);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
encode(stream, val, ctx) {
|
|
56
|
+
ctx = ctx.parent.parent;
|
|
57
|
+
return this.type.encode(stream, val, ctx);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
ValueType = new Shadow(ValueType);
|
|
62
|
+
|
|
63
|
+
let BinarySearchHeader = new r.Struct({
|
|
64
|
+
unitSize: r.uint16,
|
|
65
|
+
nUnits: r.uint16,
|
|
66
|
+
searchRange: r.uint16,
|
|
67
|
+
entrySelector: r.uint16,
|
|
68
|
+
rangeShift: r.uint16
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
let LookupSegmentSingle = new r.Struct({
|
|
72
|
+
lastGlyph: r.uint16,
|
|
73
|
+
firstGlyph: r.uint16,
|
|
74
|
+
value: ValueType
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
let LookupSegmentArray = new r.Struct({
|
|
78
|
+
lastGlyph: r.uint16,
|
|
79
|
+
firstGlyph: r.uint16,
|
|
80
|
+
values: new r.Pointer(r.uint16, new r.Array(ValueType, t => t.lastGlyph - t.firstGlyph + 1), {type: 'parent'})
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
let LookupSingle = new r.Struct({
|
|
84
|
+
glyph: r.uint16,
|
|
85
|
+
value: ValueType
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
return new r.VersionedStruct(r.uint16, {
|
|
89
|
+
0: {
|
|
90
|
+
values: new UnboundedArray(ValueType) // length == number of glyphs maybe?
|
|
91
|
+
},
|
|
92
|
+
2: {
|
|
93
|
+
binarySearchHeader: BinarySearchHeader,
|
|
94
|
+
segments: new r.Array(LookupSegmentSingle, t => t.binarySearchHeader.nUnits)
|
|
95
|
+
},
|
|
96
|
+
4: {
|
|
97
|
+
binarySearchHeader: BinarySearchHeader,
|
|
98
|
+
segments: new r.Array(LookupSegmentArray, t => t.binarySearchHeader.nUnits)
|
|
99
|
+
},
|
|
100
|
+
6: {
|
|
101
|
+
binarySearchHeader: BinarySearchHeader,
|
|
102
|
+
segments: new r.Array(LookupSingle, t => t.binarySearchHeader.nUnits)
|
|
103
|
+
},
|
|
104
|
+
8: {
|
|
105
|
+
firstGlyph: r.uint16,
|
|
106
|
+
count: r.uint16,
|
|
107
|
+
values: new r.Array(ValueType, 'count')
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
export function StateTable(entryData = {}, lookupType = r.uint16) {
|
|
113
|
+
let entry = Object.assign({
|
|
114
|
+
newState: r.uint16,
|
|
115
|
+
flags: r.uint16
|
|
116
|
+
}, entryData);
|
|
117
|
+
|
|
118
|
+
let Entry = new r.Struct(entry);
|
|
119
|
+
let StateArray = new UnboundedArray(new r.Array(r.uint16, t => t.nClasses));
|
|
120
|
+
|
|
121
|
+
let StateHeader = new r.Struct({
|
|
122
|
+
nClasses: r.uint32,
|
|
123
|
+
classTable: new r.Pointer(r.uint32, new LookupTable(lookupType)),
|
|
124
|
+
stateArray: new r.Pointer(r.uint32, StateArray),
|
|
125
|
+
entryTable: new r.Pointer(r.uint32, new UnboundedArray(Entry))
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
return StateHeader;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// This is the old version of the StateTable structure
|
|
132
|
+
export function StateTable1(entryData = {}, _lookupType = r.uint16) {
|
|
133
|
+
let ClassLookupTable = new r.Struct({
|
|
134
|
+
version() { return 8; }, // simulate LookupTable
|
|
135
|
+
firstGlyph: r.uint16,
|
|
136
|
+
values: new r.Array(r.uint8, r.uint16)
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
let entry = Object.assign({
|
|
140
|
+
newStateOffset: r.uint16,
|
|
141
|
+
// convert offset to stateArray index
|
|
142
|
+
newState: t => (t.newStateOffset - (t.parent.stateArray.base - t.parent._startOffset)) / t.parent.nClasses,
|
|
143
|
+
flags: r.uint16
|
|
144
|
+
}, entryData);
|
|
145
|
+
|
|
146
|
+
let Entry = new r.Struct(entry);
|
|
147
|
+
let StateArray = new UnboundedArray(new r.Array(r.uint8, t => t.nClasses));
|
|
148
|
+
|
|
149
|
+
let StateHeader1 = new r.Struct({
|
|
150
|
+
nClasses: r.uint16,
|
|
151
|
+
classTable: new r.Pointer(r.uint16, ClassLookupTable),
|
|
152
|
+
stateArray: new r.Pointer(r.uint16, StateArray),
|
|
153
|
+
entryTable: new r.Pointer(r.uint16, new UnboundedArray(Entry))
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
return StateHeader1;
|
|
157
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as r from 'restructure';
|
|
2
|
+
|
|
3
|
+
let shortFrac = new r.Fixed(16, 'BE', 14);
|
|
4
|
+
|
|
5
|
+
let Correspondence = new r.Struct({
|
|
6
|
+
fromCoord: shortFrac,
|
|
7
|
+
toCoord: shortFrac
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
let Segment = new r.Struct({
|
|
11
|
+
pairCount: r.uint16,
|
|
12
|
+
correspondence: new r.Array(Correspondence, 'pairCount')
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
export default new r.Struct({
|
|
16
|
+
version: r.fixed32,
|
|
17
|
+
axisCount: r.uint32,
|
|
18
|
+
segment: new r.Array(Segment, 'axisCount')
|
|
19
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import * as r from 'restructure';
|
|
2
|
+
import { LookupTable } from './aat';
|
|
3
|
+
|
|
4
|
+
let BslnSubtable = new r.VersionedStruct('format', {
|
|
5
|
+
0: { // Distance-based, no mapping
|
|
6
|
+
deltas: new r.Array(r.int16, 32)
|
|
7
|
+
},
|
|
8
|
+
|
|
9
|
+
1: { // Distance-based, with mapping
|
|
10
|
+
deltas: new r.Array(r.int16, 32),
|
|
11
|
+
mappingData: new LookupTable(r.uint16)
|
|
12
|
+
},
|
|
13
|
+
|
|
14
|
+
2: { // Control point-based, no mapping
|
|
15
|
+
standardGlyph: r.uint16,
|
|
16
|
+
controlPoints: new r.Array(r.uint16, 32)
|
|
17
|
+
},
|
|
18
|
+
|
|
19
|
+
3: { // Control point-based, with mapping
|
|
20
|
+
standardGlyph: r.uint16,
|
|
21
|
+
controlPoints: new r.Array(r.uint16, 32),
|
|
22
|
+
mappingData: new LookupTable(r.uint16)
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
export default new r.Struct({
|
|
27
|
+
version: r.fixed32,
|
|
28
|
+
format: r.uint16,
|
|
29
|
+
defaultBaseline: r.uint16,
|
|
30
|
+
subtable: BslnSubtable
|
|
31
|
+
});
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import * as r from 'restructure';
|
|
2
|
+
|
|
3
|
+
let SubHeader = new r.Struct({
|
|
4
|
+
firstCode: r.uint16,
|
|
5
|
+
entryCount: r.uint16,
|
|
6
|
+
idDelta: r.int16,
|
|
7
|
+
idRangeOffset: r.uint16
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
let CmapGroup = new r.Struct({
|
|
11
|
+
startCharCode: r.uint32,
|
|
12
|
+
endCharCode: r.uint32,
|
|
13
|
+
glyphID: r.uint32
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
let UnicodeValueRange = new r.Struct({
|
|
17
|
+
startUnicodeValue: r.uint24,
|
|
18
|
+
additionalCount: r.uint8
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
let UVSMapping = new r.Struct({
|
|
22
|
+
unicodeValue: r.uint24,
|
|
23
|
+
glyphID: r.uint16
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
let DefaultUVS = new r.Array(UnicodeValueRange, r.uint32);
|
|
27
|
+
let NonDefaultUVS = new r.Array(UVSMapping, r.uint32);
|
|
28
|
+
|
|
29
|
+
let VarSelectorRecord = new r.Struct({
|
|
30
|
+
varSelector: r.uint24,
|
|
31
|
+
defaultUVS: new r.Pointer(r.uint32, DefaultUVS, {type: 'parent'}),
|
|
32
|
+
nonDefaultUVS: new r.Pointer(r.uint32, NonDefaultUVS, {type: 'parent'})
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
let CmapSubtable = new r.VersionedStruct(r.uint16, {
|
|
36
|
+
0: { // Byte encoding
|
|
37
|
+
length: r.uint16, // Total table length in bytes (set to 262 for format 0)
|
|
38
|
+
language: r.uint16, // Language code for this encoding subtable, or zero if language-independent
|
|
39
|
+
codeMap: new r.LazyArray(r.uint8, 256)
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
2: { // High-byte mapping (CJK)
|
|
43
|
+
length: r.uint16,
|
|
44
|
+
language: r.uint16,
|
|
45
|
+
subHeaderKeys: new r.Array(r.uint16, 256),
|
|
46
|
+
subHeaderCount: t => Math.max.apply(Math, t.subHeaderKeys),
|
|
47
|
+
subHeaders: new r.LazyArray(SubHeader, 'subHeaderCount'),
|
|
48
|
+
glyphIndexArray: new r.LazyArray(r.uint16, 'subHeaderCount')
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
4: { // Segment mapping to delta values
|
|
52
|
+
length: r.uint16, // Total table length in bytes
|
|
53
|
+
language: r.uint16, // Language code
|
|
54
|
+
segCountX2: r.uint16,
|
|
55
|
+
segCount: t => t.segCountX2 >> 1,
|
|
56
|
+
searchRange: r.uint16,
|
|
57
|
+
entrySelector: r.uint16,
|
|
58
|
+
rangeShift: r.uint16,
|
|
59
|
+
endCode: new r.LazyArray(r.uint16, 'segCount'),
|
|
60
|
+
reservedPad: new r.Reserved(r.uint16), // This value should be zero
|
|
61
|
+
startCode: new r.LazyArray(r.uint16, 'segCount'),
|
|
62
|
+
idDelta: new r.LazyArray(r.int16, 'segCount'),
|
|
63
|
+
idRangeOffset: new r.LazyArray(r.uint16, 'segCount'),
|
|
64
|
+
glyphIndexArray: new r.LazyArray(r.uint16, t => (t.length - t._currentOffset) / 2)
|
|
65
|
+
},
|
|
66
|
+
|
|
67
|
+
6: { // Trimmed table
|
|
68
|
+
length: r.uint16,
|
|
69
|
+
language: r.uint16,
|
|
70
|
+
firstCode: r.uint16,
|
|
71
|
+
entryCount: r.uint16,
|
|
72
|
+
glyphIndices: new r.LazyArray(r.uint16, 'entryCount')
|
|
73
|
+
},
|
|
74
|
+
|
|
75
|
+
8: { // mixed 16-bit and 32-bit coverage
|
|
76
|
+
reserved: new r.Reserved(r.uint16),
|
|
77
|
+
length: r.uint32,
|
|
78
|
+
language: r.uint16,
|
|
79
|
+
is32: new r.LazyArray(r.uint8, 8192),
|
|
80
|
+
nGroups: r.uint32,
|
|
81
|
+
groups: new r.LazyArray(CmapGroup, 'nGroups')
|
|
82
|
+
},
|
|
83
|
+
|
|
84
|
+
10: { // Trimmed Array
|
|
85
|
+
reserved: new r.Reserved(r.uint16),
|
|
86
|
+
length: r.uint32,
|
|
87
|
+
language: r.uint32,
|
|
88
|
+
firstCode: r.uint32,
|
|
89
|
+
entryCount: r.uint32,
|
|
90
|
+
glyphIndices: new r.LazyArray(r.uint16, 'numChars')
|
|
91
|
+
},
|
|
92
|
+
|
|
93
|
+
12: { // Segmented coverage
|
|
94
|
+
reserved: new r.Reserved(r.uint16),
|
|
95
|
+
length: r.uint32,
|
|
96
|
+
language: r.uint32,
|
|
97
|
+
nGroups: r.uint32,
|
|
98
|
+
groups: new r.LazyArray(CmapGroup, 'nGroups')
|
|
99
|
+
},
|
|
100
|
+
|
|
101
|
+
13: { // Many-to-one range mappings (same as 12 except for group.startGlyphID)
|
|
102
|
+
reserved: new r.Reserved(r.uint16),
|
|
103
|
+
length: r.uint32,
|
|
104
|
+
language: r.uint32,
|
|
105
|
+
nGroups: r.uint32,
|
|
106
|
+
groups: new r.LazyArray(CmapGroup, 'nGroups')
|
|
107
|
+
},
|
|
108
|
+
|
|
109
|
+
14: { // Unicode Variation Sequences
|
|
110
|
+
length: r.uint32,
|
|
111
|
+
numRecords: r.uint32,
|
|
112
|
+
varSelectors: new r.LazyArray(VarSelectorRecord, 'numRecords')
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
let CmapEntry = new r.Struct({
|
|
117
|
+
platformID: r.uint16, // Platform identifier
|
|
118
|
+
encodingID: r.uint16, // Platform-specific encoding identifier
|
|
119
|
+
table: new r.Pointer(r.uint32, CmapSubtable, {type: 'parent', lazy: true})
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// character to glyph mapping
|
|
123
|
+
export default new r.Struct({
|
|
124
|
+
version: r.uint16,
|
|
125
|
+
numSubtables: r.uint16,
|
|
126
|
+
tables: new r.Array(CmapEntry, 'numSubtables')
|
|
127
|
+
});
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import * as r from 'restructure';
|
|
2
|
+
import Tables from './';
|
|
3
|
+
|
|
4
|
+
let TableEntry = new r.Struct({
|
|
5
|
+
tag: new r.String(4),
|
|
6
|
+
checkSum: r.uint32,
|
|
7
|
+
offset: new r.Pointer(r.uint32, 'void', { type: 'global' }),
|
|
8
|
+
length: r.uint32
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
let Directory = new r.Struct({
|
|
12
|
+
tag: new r.String(4),
|
|
13
|
+
numTables: r.uint16,
|
|
14
|
+
searchRange: r.uint16,
|
|
15
|
+
entrySelector: r.uint16,
|
|
16
|
+
rangeShift: r.uint16,
|
|
17
|
+
tables: new r.Array(TableEntry, 'numTables')
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
Directory.process = function() {
|
|
21
|
+
let tables = {};
|
|
22
|
+
for (let table of this.tables) {
|
|
23
|
+
tables[table.tag] = table;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
this.tables = tables;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
Directory.preEncode = function() {
|
|
30
|
+
if (!Array.isArray(this.tables)) {
|
|
31
|
+
let tables = [];
|
|
32
|
+
for (let tag in this.tables) {
|
|
33
|
+
let table = this.tables[tag];
|
|
34
|
+
if (table) {
|
|
35
|
+
tables.push({
|
|
36
|
+
tag: tag,
|
|
37
|
+
checkSum: 0,
|
|
38
|
+
offset: new r.VoidPointer(Tables[tag], table),
|
|
39
|
+
length: Tables[tag].size(table)
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
this.tables = tables;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
this.tag = 'true';
|
|
48
|
+
this.numTables = this.tables.length;
|
|
49
|
+
|
|
50
|
+
let maxExponentFor2 = Math.floor((Math.log(this.numTables) / Math.LN2));
|
|
51
|
+
let maxPowerOf2 = Math.pow(2, maxExponentFor2);
|
|
52
|
+
|
|
53
|
+
this.searchRange = maxPowerOf2 * 16;
|
|
54
|
+
this.entrySelector = Math.log(maxPowerOf2) / Math.LN2;
|
|
55
|
+
this.rangeShift = this.numTables * 16 - this.searchRange;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export default Directory;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import * as r from 'restructure';
|
|
2
|
+
|
|
3
|
+
let Setting = new r.Struct({
|
|
4
|
+
setting: r.uint16,
|
|
5
|
+
nameIndex: r.int16,
|
|
6
|
+
name: t => t.parent.parent.parent.name.records.fontFeatures[t.nameIndex]
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
let FeatureName = new r.Struct({
|
|
10
|
+
feature: r.uint16,
|
|
11
|
+
nSettings: r.uint16,
|
|
12
|
+
settingTable: new r.Pointer(r.uint32, new r.Array(Setting, 'nSettings'), { type: 'parent' }),
|
|
13
|
+
featureFlags: new r.Bitfield(r.uint8, [
|
|
14
|
+
null, null, null, null, null, null,
|
|
15
|
+
'hasDefault', 'exclusive'
|
|
16
|
+
]),
|
|
17
|
+
defaultSetting: r.uint8,
|
|
18
|
+
nameIndex: r.int16,
|
|
19
|
+
name: t => t.parent.parent.name.records.fontFeatures[t.nameIndex]
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
export default new r.Struct({
|
|
23
|
+
version: r.fixed32,
|
|
24
|
+
featureNameCount: r.uint16,
|
|
25
|
+
reserved1: new r.Reserved(r.uint16),
|
|
26
|
+
reserved2: new r.Reserved(r.uint32),
|
|
27
|
+
featureNames: new r.Array(FeatureName, 'featureNameCount')
|
|
28
|
+
});
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import * as r from 'restructure';
|
|
2
|
+
|
|
3
|
+
// A list of instructions that are executed once when a font is first used.
|
|
4
|
+
// These instructions are known as the font program. The main use of this table
|
|
5
|
+
// is for the definition of functions that are used in many different glyph programs.
|
|
6
|
+
export default new r.Struct({
|
|
7
|
+
instructions: new r.Array(r.uint8)
|
|
8
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import * as r from 'restructure';
|
|
2
|
+
|
|
3
|
+
let Axis = new r.Struct({
|
|
4
|
+
axisTag: new r.String(4),
|
|
5
|
+
minValue: r.fixed32,
|
|
6
|
+
defaultValue: r.fixed32,
|
|
7
|
+
maxValue: r.fixed32,
|
|
8
|
+
flags: r.uint16,
|
|
9
|
+
nameID: r.uint16,
|
|
10
|
+
name: t => t.parent.parent.name.records.fontFeatures[t.nameID]
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
let Instance = new r.Struct({
|
|
14
|
+
nameID: r.uint16,
|
|
15
|
+
name: t => t.parent.parent.name.records.fontFeatures[t.nameID],
|
|
16
|
+
flags: r.uint16,
|
|
17
|
+
coord: new r.Array(r.fixed32, t => t.parent.axisCount),
|
|
18
|
+
postscriptNameID: new r.Optional(r.uint16, t => t.parent.instanceSize - t._currentOffset > 0)
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
export default new r.Struct({
|
|
22
|
+
version: r.fixed32,
|
|
23
|
+
offsetToData: r.uint16,
|
|
24
|
+
countSizePairs: r.uint16,
|
|
25
|
+
axisCount: r.uint16,
|
|
26
|
+
axisSize: r.uint16,
|
|
27
|
+
instanceCount: r.uint16,
|
|
28
|
+
instanceSize: r.uint16,
|
|
29
|
+
axis: new r.Array(Axis, 'axisCount'),
|
|
30
|
+
instance: new r.Array(Instance, 'instanceCount')
|
|
31
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as r from 'restructure';
|
|
2
|
+
|
|
3
|
+
let GaspRange = new r.Struct({
|
|
4
|
+
rangeMaxPPEM: r.uint16, // Upper limit of range, in ppem
|
|
5
|
+
rangeGaspBehavior: new r.Bitfield(r.uint16, [ // Flags describing desired rasterizer behavior
|
|
6
|
+
'grayscale', 'gridfit',
|
|
7
|
+
'symmetricSmoothing', 'symmetricGridfit' // only in version 1, for ClearType
|
|
8
|
+
])
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
export default new r.Struct({
|
|
12
|
+
version: r.uint16, // set to 0
|
|
13
|
+
numRanges: r.uint16,
|
|
14
|
+
gaspRanges: new r.Array(GaspRange, 'numRanges') // Sorted by ppem
|
|
15
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import * as r from 'restructure';
|
|
2
|
+
|
|
3
|
+
let shortFrac = new r.Fixed(16, 'BE', 14);
|
|
4
|
+
class Offset {
|
|
5
|
+
static decode(stream, parent) {
|
|
6
|
+
// In short format, offsets are multiplied by 2.
|
|
7
|
+
// This doesn't seem to be documented by Apple, but it
|
|
8
|
+
// is implemented this way in Freetype.
|
|
9
|
+
return parent.flags
|
|
10
|
+
? stream.readUInt32BE()
|
|
11
|
+
: stream.readUInt16BE() * 2;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
let gvar = new r.Struct({
|
|
16
|
+
version: r.uint16,
|
|
17
|
+
reserved: new r.Reserved(r.uint16),
|
|
18
|
+
axisCount: r.uint16,
|
|
19
|
+
globalCoordCount: r.uint16,
|
|
20
|
+
globalCoords: new r.Pointer(r.uint32, new r.Array(new r.Array(shortFrac, 'axisCount'), 'globalCoordCount')),
|
|
21
|
+
glyphCount: r.uint16,
|
|
22
|
+
flags: r.uint16,
|
|
23
|
+
offsetToData: r.uint32,
|
|
24
|
+
offsets: new r.Array(new r.Pointer(Offset, 'void', { relativeTo: ctx => ctx.offsetToData, allowNull: false }), t => t.glyphCount + 1)
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
export default gvar;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as r from 'restructure';
|
|
2
|
+
|
|
3
|
+
let DeviceRecord = new r.Struct({
|
|
4
|
+
pixelSize: r.uint8,
|
|
5
|
+
maximumWidth: r.uint8,
|
|
6
|
+
widths: new r.Array(r.uint8, t => t.parent.parent.maxp.numGlyphs)
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
// The Horizontal Device Metrics table stores integer advance widths scaled to particular pixel sizes
|
|
10
|
+
export default new r.Struct({
|
|
11
|
+
version: r.uint16,
|
|
12
|
+
numRecords: r.int16,
|
|
13
|
+
sizeDeviceRecord: r.int32,
|
|
14
|
+
records: new r.Array(DeviceRecord, 'numRecords')
|
|
15
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as r from 'restructure';
|
|
2
|
+
|
|
3
|
+
// font header
|
|
4
|
+
export default new r.Struct({
|
|
5
|
+
version: r.int32, // 0x00010000 (version 1.0)
|
|
6
|
+
revision: r.int32, // set by font manufacturer
|
|
7
|
+
checkSumAdjustment: r.uint32,
|
|
8
|
+
magicNumber: r.uint32, // set to 0x5F0F3CF5
|
|
9
|
+
flags: r.uint16,
|
|
10
|
+
unitsPerEm: r.uint16, // range from 64 to 16384
|
|
11
|
+
created: new r.Array(r.int32, 2),
|
|
12
|
+
modified: new r.Array(r.int32, 2),
|
|
13
|
+
xMin: r.int16, // for all glyph bounding boxes
|
|
14
|
+
yMin: r.int16, // for all glyph bounding boxes
|
|
15
|
+
xMax: r.int16, // for all glyph bounding boxes
|
|
16
|
+
yMax: r.int16, // for all glyph bounding boxes
|
|
17
|
+
macStyle: new r.Bitfield(r.uint16, [
|
|
18
|
+
'bold', 'italic', 'underline', 'outline',
|
|
19
|
+
'shadow', 'condensed', 'extended'
|
|
20
|
+
]),
|
|
21
|
+
lowestRecPPEM: r.uint16, // smallest readable size in pixels
|
|
22
|
+
fontDirectionHint: r.int16,
|
|
23
|
+
indexToLocFormat: r.int16, // 0 for short offsets, 1 for long
|
|
24
|
+
glyphDataFormat: r.int16 // 0 for current format
|
|
25
|
+
});
|