@cantoo/fontkit 2.0.5 → 2.0.7
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/dist/browser-module.d.ts +239 -0
- package/dist/browser-module.mjs +4423 -1117
- package/dist/browser-module.mjs.map +1 -1
- package/dist/browser.cjs +4424 -1117
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.ts +239 -0
- package/dist/fontkit.umd.d.ts +239 -0
- package/dist/fontkit.umd.js +22076 -0
- package/dist/fontkit.umd.js.map +7 -0
- package/dist/index.d.ts +239 -0
- package/dist/main.cjs +4424 -1117
- package/dist/main.cjs.map +1 -1
- package/dist/main.d.ts +239 -0
- package/dist/module.d.ts +239 -0
- package/dist/module.mjs +4423 -1117
- package/dist/module.mjs.map +1 -1
- package/package.json +22 -5
- package/src/CmapProcessor.js +59 -20
- package/src/DFont.js +114 -14
- package/src/TTFFont.js +259 -57
- package/src/TrueTypeCollection.js +54 -10
- package/src/WOFF2Font.js +128 -16
- package/src/WOFFFont.js +45 -8
- package/src/aat/AATFeatureMap.js +62 -18
- package/src/aat/AATLayoutEngine.js +33 -1
- package/src/aat/AATLookupTable.js +22 -4
- package/src/aat/AATMorxProcessor.js +189 -52
- package/src/aat/AATStateMachine.js +32 -0
- package/src/base.js +19 -0
- package/src/cff/CFFCharsets.js +3 -0
- package/src/cff/CFFDict.js +79 -9
- package/src/cff/CFFEncodings.js +2 -0
- package/src/cff/CFFFont.js +119 -23
- package/src/cff/CFFIndex.js +62 -5
- package/src/cff/CFFOperand.js +52 -17
- package/src/cff/CFFPointer.js +41 -2
- package/src/cff/CFFPrivateDict.js +14 -4
- package/src/cff/CFFStandardStrings.js +1 -0
- package/src/cff/CFFTop.js +103 -10
- package/src/decorators.js +32 -13
- package/src/encodings.js +22 -5
- package/src/fs.js +10 -0
- package/src/glyph/BBox.js +14 -0
- package/src/glyph/CFFGlyph.js +290 -148
- package/src/glyph/COLRGlyph.js +38 -3
- package/src/glyph/Glyph.js +68 -9
- package/src/glyph/GlyphVariationProcessor.js +135 -34
- package/src/glyph/Path.js +107 -20
- package/src/glyph/SBIXGlyph.js +57 -8
- package/src/glyph/StandardNames.js +1 -0
- package/src/glyph/TTFGlyph.js +176 -29
- package/src/glyph/TTFGlyphEncoder.js +32 -0
- package/src/glyph/WOFF2Glyph.js +23 -4
- package/src/layout/GlyphPosition.js +6 -0
- package/src/layout/GlyphRun.js +25 -7
- package/src/layout/KernProcessor.js +62 -3
- package/src/layout/LayoutEngine.js +86 -12
- package/src/layout/Script.js +27 -1
- package/src/layout/UnicodeLayoutEngine.js +29 -4
- package/src/opentype/GPOSProcessor.js +156 -45
- package/src/opentype/GSUBProcessor.js +92 -33
- package/src/opentype/GlyphInfo.js +52 -4
- package/src/opentype/GlyphIterator.js +51 -2
- package/src/opentype/OTLayoutEngine.js +66 -8
- package/src/opentype/OTProcessor.js +283 -70
- package/src/opentype/ShapingPlan.js +51 -3
- package/src/opentype/shapers/ArabicShaper.js +19 -0
- package/src/opentype/shapers/DefaultShaper.js +51 -7
- package/src/opentype/shapers/HangulShaper.js +85 -7
- package/src/opentype/shapers/HebrewShaper.js +45 -11
- package/src/opentype/shapers/IndicShaper.js +141 -26
- package/src/opentype/shapers/ThaiShaper.js +35 -4
- package/src/opentype/shapers/UniversalShaper.js +83 -17
- package/src/opentype/shapers/index.js +15 -2
- package/src/packages/unicode-properties/data-trie.js +1 -0
- package/src/packages/unicode-properties/data.js +12 -0
- package/src/packages/unicode-properties/dist/index.cjs +22 -9
- package/src/packages/unicode-properties/dist/index.cjs.map +2 -2
- package/src/packages/unicode-properties/dist/index.mjs +21 -9
- package/src/packages/unicode-properties/dist/index.mjs.map +2 -2
- package/src/packages/unicode-properties/index.js +65 -0
- package/src/packages/unicode-properties/package.json +1 -1
- package/src/packages/unicode-trie/builder.js +128 -7
- package/src/packages/unicode-trie/dist/builder.cjs +129 -16
- package/src/packages/unicode-trie/dist/builder.cjs.map +2 -2
- package/src/packages/unicode-trie/dist/builder.mjs +128 -16
- package/src/packages/unicode-trie/dist/builder.mjs.map +2 -2
- package/src/packages/unicode-trie/dist/index.cjs +22 -9
- package/src/packages/unicode-trie/dist/index.cjs.map +2 -2
- package/src/packages/unicode-trie/dist/index.mjs +21 -9
- package/src/packages/unicode-trie/dist/index.mjs.map +2 -2
- package/src/packages/unicode-trie/index.js +62 -10
- package/src/packages/unicode-trie/package.json +1 -1
- package/src/packages/unicode-trie/swap.js +13 -0
- package/src/subset/CFFSubset.js +112 -22
- package/src/subset/Subset.js +21 -1
- package/src/subset/TTFSubset.js +79 -36
- package/src/tables/BASE.js +1 -0
- package/src/tables/COLR.js +1 -0
- package/src/tables/CPAL.js +1 -0
- package/src/tables/DSIG.js +1 -0
- package/src/tables/EBDT.js +10 -3
- package/src/tables/EBLC.js +67 -7
- package/src/tables/GDEF.js +1 -0
- package/src/tables/GPOS.js +79 -16
- package/src/tables/GSUB.js +14 -3
- package/src/tables/HVAR.js +51 -5
- package/src/tables/JSTF.js +3 -2
- package/src/tables/LTSH.js +1 -0
- package/src/tables/OS2.js +1 -0
- package/src/tables/PCLT.js +1 -0
- package/src/tables/STAT.js +46 -6
- package/src/tables/VDMX.js +1 -0
- package/src/tables/VORG.js +1 -0
- package/src/tables/WOFF2Directory.js +56 -8
- package/src/tables/WOFFDirectory.js +14 -2
- package/src/tables/aat.js +160 -35
- package/src/tables/avar.js +1 -0
- package/src/tables/bsln.js +3 -2
- package/src/tables/cmap.js +26 -6
- package/src/tables/cvt.js +1 -0
- package/src/tables/directory.js +44 -16
- package/src/tables/feat.js +24 -2
- package/src/tables/fpgm.js +1 -0
- package/src/tables/fvar.js +32 -4
- package/src/tables/gasp.js +1 -0
- package/src/tables/glyf.js +1 -0
- package/src/tables/gvar.js +29 -2
- package/src/tables/hdmx.js +12 -1
- package/src/tables/head.js +1 -0
- package/src/tables/hhea.js +1 -0
- package/src/tables/hmtx.js +18 -2
- package/src/tables/index.js +1 -0
- package/src/tables/just.js +15 -4
- package/src/tables/kern.js +43 -6
- package/src/tables/loca.js +21 -8
- package/src/tables/maxp.js +1 -0
- package/src/tables/morx.js +14 -7
- package/src/tables/name.js +104 -23
- package/src/tables/opbd.js +2 -1
- package/src/tables/opentype.js +39 -4
- package/src/tables/post.js +8 -1
- package/src/tables/prep.js +1 -0
- package/src/tables/sbix.js +12 -1
- package/src/tables/variations.js +23 -3
- package/src/tables/vhea.js +1 -0
- package/src/tables/vmtx.js +18 -2
- package/src/utils.js +15 -0
- package/types/assets.d.ts +13 -0
- package/types/deps.d.ts +83 -0
- package/types/fontkit.d.ts +1324 -0
- package/types/index.d.ts +239 -0
- package/types/restructure.d.ts +354 -0
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
import * as r from 'restructure';
|
|
2
2
|
|
|
3
|
+
/** @typedef {import('restructure').BaseType} BaseType */
|
|
4
|
+
/** @typedef {import('restructure').DecodeStream} DecodeStream */
|
|
5
|
+
/** @typedef {import('restructure').StructValue} StructValue */
|
|
6
|
+
/** @typedef {import('../../types/fontkit').TableEntry} TableEntry */
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* WOFF2 variable-length unsigned integer (Base128).
|
|
10
|
+
* @type {BaseType}
|
|
11
|
+
*/
|
|
3
12
|
const Base128 = {
|
|
13
|
+
/**
|
|
14
|
+
* @param {DecodeStream} stream
|
|
15
|
+
* @returns {number}
|
|
16
|
+
*/
|
|
4
17
|
decode(stream) {
|
|
5
18
|
let result = 0;
|
|
6
19
|
let iterable = [0, 1, 2, 3, 4];
|
|
@@ -34,14 +47,46 @@ let knownTags = [
|
|
|
34
47
|
|
|
35
48
|
let WOFF2DirectoryEntry = new r.Struct({
|
|
36
49
|
flags: r.uint8,
|
|
37
|
-
customTag: new r.Optional(
|
|
38
|
-
|
|
50
|
+
customTag: new r.Optional(
|
|
51
|
+
new r.String(4),
|
|
52
|
+
/** @param {StructValue} t @returns {boolean} */
|
|
53
|
+
t => (/** @type {number} */ (t.flags) & 0x3f) === 0x3f
|
|
54
|
+
),
|
|
55
|
+
/**
|
|
56
|
+
* @param {StructValue} t
|
|
57
|
+
* @returns {string}
|
|
58
|
+
*/
|
|
59
|
+
tag: (t) => {
|
|
60
|
+
let flags = /** @type {number} */ (t.flags);
|
|
61
|
+
return /** @type {string} */ (t.customTag) || knownTags[flags & 0x3f];
|
|
62
|
+
},
|
|
39
63
|
length: Base128,
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
64
|
+
/**
|
|
65
|
+
* @param {StructValue} t
|
|
66
|
+
* @returns {number}
|
|
67
|
+
*/
|
|
68
|
+
transformVersion: t => (/** @type {number} */ (t.flags) >>> 6) & 0x03,
|
|
69
|
+
/**
|
|
70
|
+
* @param {StructValue} t
|
|
71
|
+
* @returns {boolean}
|
|
72
|
+
*/
|
|
73
|
+
transformed: t => (t.tag === 'glyf' || t.tag === 'loca')
|
|
74
|
+
? t.transformVersion === 0
|
|
75
|
+
: t.transformVersion !== 0,
|
|
76
|
+
transformLength: new r.Optional(
|
|
77
|
+
Base128,
|
|
78
|
+
/** @param {StructValue} t @returns {boolean} */
|
|
79
|
+
t => !!t.transformed
|
|
80
|
+
)
|
|
43
81
|
});
|
|
44
82
|
|
|
83
|
+
/**
|
|
84
|
+
* @typedef {StructValue & {
|
|
85
|
+
* tables: TableEntry[] | Record<string, TableEntry>
|
|
86
|
+
* }} WOFF2DirectoryValue
|
|
87
|
+
*/
|
|
88
|
+
|
|
89
|
+
/** @type {import('restructure').Struct} */
|
|
45
90
|
let WOFF2Directory = new r.Struct({
|
|
46
91
|
tag: new r.String(4), // should be 'wOF2'
|
|
47
92
|
flavor: r.uint32,
|
|
@@ -61,13 +106,16 @@ let WOFF2Directory = new r.Struct({
|
|
|
61
106
|
});
|
|
62
107
|
|
|
63
108
|
WOFF2Directory.process = function () {
|
|
109
|
+
let self = /** @type {WOFF2DirectoryValue} */ (this);
|
|
110
|
+
/** @type {Record<string, TableEntry>} */
|
|
64
111
|
let tables = {};
|
|
65
|
-
|
|
66
|
-
|
|
112
|
+
let list = /** @type {TableEntry[]} */ (self.tables);
|
|
113
|
+
for (let i = 0; i < list.length; i++) {
|
|
114
|
+
let table = list[i];
|
|
67
115
|
tables[table.tag] = table;
|
|
68
116
|
}
|
|
69
117
|
|
|
70
|
-
|
|
118
|
+
self.tables = tables;
|
|
71
119
|
};
|
|
72
120
|
|
|
73
121
|
export default WOFF2Directory;
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import * as r from 'restructure';
|
|
2
2
|
|
|
3
|
+
/** @typedef {import('restructure').StructValue} StructValue */
|
|
4
|
+
/** @typedef {import('../../types/fontkit').TableEntry} TableEntry */
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @typedef {StructValue & {
|
|
8
|
+
* tables: TableEntry[] | Record<string, TableEntry>
|
|
9
|
+
* }} WOFFDirectoryValue
|
|
10
|
+
*/
|
|
11
|
+
|
|
3
12
|
let WOFFDirectoryEntry = new r.Struct({
|
|
4
13
|
tag: new r.String(4),
|
|
5
14
|
offset: new r.Pointer(r.uint32, 'void', { type: 'global' }),
|
|
@@ -8,6 +17,7 @@ let WOFFDirectoryEntry = new r.Struct({
|
|
|
8
17
|
origChecksum: r.uint32
|
|
9
18
|
});
|
|
10
19
|
|
|
20
|
+
/** @type {import('restructure').Struct} */
|
|
11
21
|
let WOFFDirectory = new r.Struct({
|
|
12
22
|
tag: new r.String(4), // should be 'wOFF'
|
|
13
23
|
flavor: r.uint32,
|
|
@@ -26,12 +36,14 @@ let WOFFDirectory = new r.Struct({
|
|
|
26
36
|
});
|
|
27
37
|
|
|
28
38
|
WOFFDirectory.process = function () {
|
|
39
|
+
let self = /** @type {WOFFDirectoryValue} */ (this);
|
|
40
|
+
/** @type {Record<string, TableEntry>} */
|
|
29
41
|
let tables = {};
|
|
30
|
-
for (let table of
|
|
42
|
+
for (let table of /** @type {TableEntry[]} */ (self.tables)) {
|
|
31
43
|
tables[table.tag] = table;
|
|
32
44
|
}
|
|
33
45
|
|
|
34
|
-
|
|
46
|
+
self.tables = tables;
|
|
35
47
|
};
|
|
36
48
|
|
|
37
49
|
export default WOFFDirectory;
|
package/src/tables/aat.js
CHANGED
|
@@ -1,64 +1,135 @@
|
|
|
1
1
|
import * as r from 'restructure';
|
|
2
2
|
|
|
3
|
+
/** @typedef {import('restructure').BaseType} BaseType */
|
|
4
|
+
/** @typedef {import('restructure').DecodeStream} DecodeStream */
|
|
5
|
+
/** @typedef {import('restructure').EncodeStream} EncodeStream */
|
|
6
|
+
/** @typedef {import('restructure').StructFields} StructFields */
|
|
7
|
+
/** @typedef {import('restructure').StructValue} StructValue */
|
|
8
|
+
/** @typedef {import('restructure').VersionedStruct} VersionedStruct */
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Lazy random-access view over an unbounded run of encoded items.
|
|
12
|
+
*/
|
|
3
13
|
class UnboundedArrayAccessor {
|
|
14
|
+
/**
|
|
15
|
+
* @param {BaseType} type
|
|
16
|
+
* @param {DecodeStream} stream
|
|
17
|
+
* @param {StructValue | null | undefined} parent
|
|
18
|
+
*/
|
|
4
19
|
constructor(type, stream, parent) {
|
|
20
|
+
/** @type {BaseType} */
|
|
5
21
|
this.type = type;
|
|
22
|
+
/** @type {DecodeStream} */
|
|
6
23
|
this.stream = stream;
|
|
24
|
+
/** @type {StructValue | null | undefined} */
|
|
7
25
|
this.parent = parent;
|
|
26
|
+
/** @type {number} */
|
|
8
27
|
this.base = this.stream.pos;
|
|
28
|
+
/** @type {unknown[]} */
|
|
9
29
|
this._items = [];
|
|
10
30
|
}
|
|
11
31
|
|
|
32
|
+
/**
|
|
33
|
+
* @param {number} index
|
|
34
|
+
* @returns {unknown}
|
|
35
|
+
*/
|
|
12
36
|
getItem(index) {
|
|
13
37
|
if (this._items[index] == null) {
|
|
14
38
|
let pos = this.stream.pos;
|
|
15
|
-
|
|
16
|
-
this.
|
|
39
|
+
let itemSize = this.type.size?.(null, this.parent);
|
|
40
|
+
this.stream.pos = this.base + /** @type {number} */ (itemSize) * index;
|
|
41
|
+
this._items[index] = this.type.decode?.(this.stream, this.parent);
|
|
17
42
|
this.stream.pos = pos;
|
|
18
43
|
}
|
|
19
44
|
|
|
20
45
|
return this._items[index];
|
|
21
46
|
}
|
|
22
47
|
|
|
48
|
+
/**
|
|
49
|
+
* @returns {string}
|
|
50
|
+
*/
|
|
23
51
|
inspect() {
|
|
24
|
-
|
|
52
|
+
let name = this.type.constructor && this.type.constructor.name
|
|
53
|
+
? this.type.constructor.name
|
|
54
|
+
: 'Type';
|
|
55
|
+
return `[UnboundedArray ${name}]`;
|
|
25
56
|
}
|
|
26
57
|
}
|
|
27
58
|
|
|
28
|
-
|
|
59
|
+
/**
|
|
60
|
+
* Array whose length is not stored; consumers index via getItem().
|
|
61
|
+
* @implements {BaseType}
|
|
62
|
+
*/
|
|
63
|
+
export class UnboundedArray {
|
|
64
|
+
/**
|
|
65
|
+
* @param {BaseType} type
|
|
66
|
+
*/
|
|
29
67
|
constructor(type) {
|
|
30
|
-
|
|
68
|
+
/** @type {BaseType} */
|
|
69
|
+
this.type = type;
|
|
31
70
|
}
|
|
32
71
|
|
|
72
|
+
/**
|
|
73
|
+
* @param {DecodeStream} stream
|
|
74
|
+
* @param {StructValue | null | undefined} parent
|
|
75
|
+
* @returns {UnboundedArrayAccessor}
|
|
76
|
+
*/
|
|
33
77
|
decode(stream, parent) {
|
|
34
78
|
return new UnboundedArrayAccessor(this.type, stream, parent);
|
|
35
79
|
}
|
|
36
80
|
}
|
|
37
81
|
|
|
38
|
-
|
|
39
|
-
|
|
82
|
+
/**
|
|
83
|
+
* @param {BaseType} [ValueType]
|
|
84
|
+
* @returns {VersionedStruct}
|
|
85
|
+
*/
|
|
86
|
+
export function LookupTable(ValueType = r.uint16) {
|
|
87
|
+
/**
|
|
88
|
+
* Re-parents decode/encode so internal lookup structs stay invisible to pointers.
|
|
89
|
+
* @implements {BaseType}
|
|
90
|
+
*/
|
|
40
91
|
class Shadow {
|
|
92
|
+
/**
|
|
93
|
+
* @param {BaseType} type
|
|
94
|
+
*/
|
|
41
95
|
constructor(type) {
|
|
96
|
+
/** @type {BaseType} */
|
|
42
97
|
this.type = type;
|
|
43
98
|
}
|
|
44
99
|
|
|
100
|
+
/**
|
|
101
|
+
* @param {DecodeStream} stream
|
|
102
|
+
* @param {StructValue | null | undefined} ctx
|
|
103
|
+
* @returns {unknown}
|
|
104
|
+
*/
|
|
45
105
|
decode(stream, ctx) {
|
|
46
|
-
|
|
47
|
-
return this.type.decode(stream,
|
|
106
|
+
let parent = ctx && ctx.parent && ctx.parent.parent ? ctx.parent.parent : ctx;
|
|
107
|
+
return this.type.decode?.(stream, parent);
|
|
48
108
|
}
|
|
49
109
|
|
|
110
|
+
/**
|
|
111
|
+
* @param {unknown} val
|
|
112
|
+
* @param {StructValue | null | undefined} ctx
|
|
113
|
+
* @returns {number}
|
|
114
|
+
*/
|
|
50
115
|
size(val, ctx) {
|
|
51
|
-
|
|
52
|
-
return this.type.size(val,
|
|
116
|
+
let parent = ctx && ctx.parent && ctx.parent.parent ? ctx.parent.parent : ctx;
|
|
117
|
+
return /** @type {number} */ (this.type.size?.(val, parent));
|
|
53
118
|
}
|
|
54
119
|
|
|
120
|
+
/**
|
|
121
|
+
* @param {EncodeStream | null} stream
|
|
122
|
+
* @param {unknown} val
|
|
123
|
+
* @param {StructValue | null | undefined} ctx
|
|
124
|
+
* @returns {unknown}
|
|
125
|
+
*/
|
|
55
126
|
encode(stream, val, ctx) {
|
|
56
|
-
|
|
57
|
-
return this.type.encode(stream, val,
|
|
127
|
+
let parent = ctx && ctx.parent && ctx.parent.parent ? ctx.parent.parent : ctx;
|
|
128
|
+
return this.type.encode?.(stream, val, parent);
|
|
58
129
|
}
|
|
59
130
|
}
|
|
60
131
|
|
|
61
|
-
|
|
132
|
+
let shadowed = new Shadow(ValueType);
|
|
62
133
|
|
|
63
134
|
let BinarySearchHeader = new r.Struct({
|
|
64
135
|
unitSize: r.uint16,
|
|
@@ -71,44 +142,69 @@ export let LookupTable = function (ValueType = r.uint16) {
|
|
|
71
142
|
let LookupSegmentSingle = new r.Struct({
|
|
72
143
|
lastGlyph: r.uint16,
|
|
73
144
|
firstGlyph: r.uint16,
|
|
74
|
-
value:
|
|
145
|
+
value: shadowed
|
|
75
146
|
});
|
|
76
147
|
|
|
77
148
|
let LookupSegmentArray = new r.Struct({
|
|
78
149
|
lastGlyph: r.uint16,
|
|
79
150
|
firstGlyph: r.uint16,
|
|
80
|
-
values: new r.Pointer(
|
|
151
|
+
values: new r.Pointer(
|
|
152
|
+
r.uint16,
|
|
153
|
+
new r.Array(
|
|
154
|
+
shadowed,
|
|
155
|
+
/** @param {StructValue} t @returns {number} */
|
|
156
|
+
t => /** @type {number} */ (t.lastGlyph) - /** @type {number} */ (t.firstGlyph) + 1
|
|
157
|
+
),
|
|
158
|
+
{ type: 'parent' }
|
|
159
|
+
)
|
|
81
160
|
});
|
|
82
161
|
|
|
83
162
|
let LookupSingle = new r.Struct({
|
|
84
163
|
glyph: r.uint16,
|
|
85
|
-
value:
|
|
164
|
+
value: shadowed
|
|
86
165
|
});
|
|
87
166
|
|
|
88
167
|
return new r.VersionedStruct(r.uint16, {
|
|
89
168
|
0: {
|
|
90
|
-
values: new UnboundedArray(
|
|
169
|
+
values: new UnboundedArray(shadowed) // length == number of glyphs maybe?
|
|
91
170
|
},
|
|
92
171
|
2: {
|
|
93
172
|
binarySearchHeader: BinarySearchHeader,
|
|
94
|
-
segments: new r.Array(
|
|
173
|
+
segments: new r.Array(
|
|
174
|
+
LookupSegmentSingle,
|
|
175
|
+
/** @param {StructValue} t @returns {number} */
|
|
176
|
+
t => /** @type {number} */ (/** @type {StructValue} */ (t.binarySearchHeader).nUnits)
|
|
177
|
+
)
|
|
95
178
|
},
|
|
96
179
|
4: {
|
|
97
180
|
binarySearchHeader: BinarySearchHeader,
|
|
98
|
-
segments: new r.Array(
|
|
181
|
+
segments: new r.Array(
|
|
182
|
+
LookupSegmentArray,
|
|
183
|
+
/** @param {StructValue} t @returns {number} */
|
|
184
|
+
t => /** @type {number} */ (/** @type {StructValue} */ (t.binarySearchHeader).nUnits)
|
|
185
|
+
)
|
|
99
186
|
},
|
|
100
187
|
6: {
|
|
101
188
|
binarySearchHeader: BinarySearchHeader,
|
|
102
|
-
segments: new r.Array(
|
|
189
|
+
segments: new r.Array(
|
|
190
|
+
LookupSingle,
|
|
191
|
+
/** @param {StructValue} t @returns {number} */
|
|
192
|
+
t => /** @type {number} */ (/** @type {StructValue} */ (t.binarySearchHeader).nUnits)
|
|
193
|
+
)
|
|
103
194
|
},
|
|
104
195
|
8: {
|
|
105
196
|
firstGlyph: r.uint16,
|
|
106
197
|
count: r.uint16,
|
|
107
|
-
values: new r.Array(
|
|
198
|
+
values: new r.Array(shadowed, 'count')
|
|
108
199
|
}
|
|
109
200
|
});
|
|
110
|
-
}
|
|
201
|
+
}
|
|
111
202
|
|
|
203
|
+
/**
|
|
204
|
+
* @param {StructFields} [entryData]
|
|
205
|
+
* @param {BaseType} [lookupType]
|
|
206
|
+
* @returns {import('restructure').Struct}
|
|
207
|
+
*/
|
|
112
208
|
export function StateTable(entryData = {}, lookupType = r.uint16) {
|
|
113
209
|
let entry = Object.assign({
|
|
114
210
|
newState: r.uint16,
|
|
@@ -116,21 +212,31 @@ export function StateTable(entryData = {}, lookupType = r.uint16) {
|
|
|
116
212
|
}, entryData);
|
|
117
213
|
|
|
118
214
|
let Entry = new r.Struct(entry);
|
|
119
|
-
let StateArray = new UnboundedArray(
|
|
215
|
+
let StateArray = new UnboundedArray(
|
|
216
|
+
new r.Array(
|
|
217
|
+
r.uint16,
|
|
218
|
+
/** @param {StructValue} t @returns {number} */
|
|
219
|
+
t => /** @type {number} */ (t.nClasses)
|
|
220
|
+
)
|
|
221
|
+
);
|
|
120
222
|
|
|
121
|
-
|
|
223
|
+
return new r.Struct({
|
|
122
224
|
nClasses: r.uint32,
|
|
123
|
-
classTable: new r.Pointer(r.uint32,
|
|
225
|
+
classTable: new r.Pointer(r.uint32, LookupTable(lookupType)),
|
|
124
226
|
stateArray: new r.Pointer(r.uint32, StateArray),
|
|
125
227
|
entryTable: new r.Pointer(r.uint32, new UnboundedArray(Entry))
|
|
126
228
|
});
|
|
127
|
-
|
|
128
|
-
return StateHeader;
|
|
129
229
|
}
|
|
130
230
|
|
|
131
|
-
|
|
231
|
+
/**
|
|
232
|
+
* Old (16-bit) StateTable structure.
|
|
233
|
+
* @param {StructFields} [entryData]
|
|
234
|
+
* @param {BaseType} [_lookupType]
|
|
235
|
+
* @returns {import('restructure').Struct}
|
|
236
|
+
*/
|
|
132
237
|
export function StateTable1(entryData = {}, _lookupType = r.uint16) {
|
|
133
238
|
let ClassLookupTable = new r.Struct({
|
|
239
|
+
/** @returns {number} */
|
|
134
240
|
version() { return 8; }, // simulate LookupTable
|
|
135
241
|
firstGlyph: r.uint16,
|
|
136
242
|
values: new r.Array(r.uint8, r.uint16)
|
|
@@ -138,20 +244,39 @@ export function StateTable1(entryData = {}, _lookupType = r.uint16) {
|
|
|
138
244
|
|
|
139
245
|
let entry = Object.assign({
|
|
140
246
|
newStateOffset: r.uint16,
|
|
141
|
-
|
|
142
|
-
|
|
247
|
+
/**
|
|
248
|
+
* Convert offset to stateArray index.
|
|
249
|
+
* @param {StructValue} t
|
|
250
|
+
* @returns {number}
|
|
251
|
+
*/
|
|
252
|
+
newState: (t) => {
|
|
253
|
+
/**
|
|
254
|
+
* @typedef {{
|
|
255
|
+
* stateArray: { base: number },
|
|
256
|
+
* _startOffset: number,
|
|
257
|
+
* nClasses: number
|
|
258
|
+
* }} StateParent
|
|
259
|
+
*/
|
|
260
|
+
let parent = /** @type {StructValue & StateParent} */ (t.parent);
|
|
261
|
+
return (/** @type {number} */ (t.newStateOffset)
|
|
262
|
+
- (parent.stateArray.base - parent._startOffset)) / parent.nClasses;
|
|
263
|
+
},
|
|
143
264
|
flags: r.uint16
|
|
144
265
|
}, entryData);
|
|
145
266
|
|
|
146
267
|
let Entry = new r.Struct(entry);
|
|
147
|
-
let StateArray = new UnboundedArray(
|
|
268
|
+
let StateArray = new UnboundedArray(
|
|
269
|
+
new r.Array(
|
|
270
|
+
r.uint8,
|
|
271
|
+
/** @param {StructValue} t @returns {number} */
|
|
272
|
+
t => /** @type {number} */ (t.nClasses)
|
|
273
|
+
)
|
|
274
|
+
);
|
|
148
275
|
|
|
149
|
-
|
|
276
|
+
return new r.Struct({
|
|
150
277
|
nClasses: r.uint16,
|
|
151
278
|
classTable: new r.Pointer(r.uint16, ClassLookupTable),
|
|
152
279
|
stateArray: new r.Pointer(r.uint16, StateArray),
|
|
153
280
|
entryTable: new r.Pointer(r.uint16, new UnboundedArray(Entry))
|
|
154
281
|
});
|
|
155
|
-
|
|
156
|
-
return StateHeader1;
|
|
157
282
|
}
|
package/src/tables/avar.js
CHANGED
package/src/tables/bsln.js
CHANGED
|
@@ -8,7 +8,7 @@ let BslnSubtable = new r.VersionedStruct('format', {
|
|
|
8
8
|
|
|
9
9
|
1: { // Distance-based, with mapping
|
|
10
10
|
deltas: new r.Array(r.int16, 32),
|
|
11
|
-
mappingData:
|
|
11
|
+
mappingData: LookupTable(r.uint16)
|
|
12
12
|
},
|
|
13
13
|
|
|
14
14
|
2: { // Control point-based, no mapping
|
|
@@ -19,10 +19,11 @@ let BslnSubtable = new r.VersionedStruct('format', {
|
|
|
19
19
|
3: { // Control point-based, with mapping
|
|
20
20
|
standardGlyph: r.uint16,
|
|
21
21
|
controlPoints: new r.Array(r.uint16, 32),
|
|
22
|
-
mappingData:
|
|
22
|
+
mappingData: LookupTable(r.uint16)
|
|
23
23
|
}
|
|
24
24
|
});
|
|
25
25
|
|
|
26
|
+
/** @type {import('restructure').Struct} */
|
|
26
27
|
export default new r.Struct({
|
|
27
28
|
version: r.fixed32,
|
|
28
29
|
format: r.uint16,
|
package/src/tables/cmap.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import * as r from 'restructure';
|
|
2
2
|
|
|
3
|
+
/** @typedef {import('restructure').StructValue} StructValue */
|
|
4
|
+
|
|
3
5
|
let SubHeader = new r.Struct({
|
|
4
6
|
firstCode: r.uint16,
|
|
5
7
|
entryCount: r.uint16,
|
|
@@ -43,16 +45,29 @@ let CmapSubtable = new r.VersionedStruct(r.uint16, {
|
|
|
43
45
|
length: r.uint16,
|
|
44
46
|
language: r.uint16,
|
|
45
47
|
subHeaderKeys: new r.Array(r.uint16, 256),
|
|
46
|
-
|
|
48
|
+
/**
|
|
49
|
+
* Keys store subHeaderIndex * 8; count is max index + 1.
|
|
50
|
+
* @param {StructValue} t
|
|
51
|
+
* @returns {number}
|
|
52
|
+
*/
|
|
53
|
+
subHeaderCount: t => (Math.max.apply(Math, /** @type {number[]} */ (t.subHeaderKeys)) / 8) + 1,
|
|
47
54
|
subHeaders: new r.LazyArray(SubHeader, 'subHeaderCount'),
|
|
48
|
-
glyphIndexArray: new r.LazyArray(
|
|
55
|
+
glyphIndexArray: new r.LazyArray(
|
|
56
|
+
r.uint16,
|
|
57
|
+
/** @param {StructValue} t @returns {number} */
|
|
58
|
+
t => (/** @type {number} */ (t.length) - /** @type {number} */ (t._currentOffset)) / 2
|
|
59
|
+
)
|
|
49
60
|
},
|
|
50
61
|
|
|
51
62
|
4: { // Segment mapping to delta values
|
|
52
63
|
length: r.uint16, // Total table length in bytes
|
|
53
64
|
language: r.uint16, // Language code
|
|
54
65
|
segCountX2: r.uint16,
|
|
55
|
-
|
|
66
|
+
/**
|
|
67
|
+
* @param {StructValue} t
|
|
68
|
+
* @returns {number}
|
|
69
|
+
*/
|
|
70
|
+
segCount: t => /** @type {number} */ (t.segCountX2) >> 1,
|
|
56
71
|
searchRange: r.uint16,
|
|
57
72
|
entrySelector: r.uint16,
|
|
58
73
|
rangeShift: r.uint16,
|
|
@@ -61,7 +76,11 @@ let CmapSubtable = new r.VersionedStruct(r.uint16, {
|
|
|
61
76
|
startCode: new r.LazyArray(r.uint16, 'segCount'),
|
|
62
77
|
idDelta: new r.LazyArray(r.int16, 'segCount'),
|
|
63
78
|
idRangeOffset: new r.LazyArray(r.uint16, 'segCount'),
|
|
64
|
-
glyphIndexArray: new r.LazyArray(
|
|
79
|
+
glyphIndexArray: new r.LazyArray(
|
|
80
|
+
r.uint16,
|
|
81
|
+
/** @param {StructValue} t @returns {number} */
|
|
82
|
+
t => (/** @type {number} */ (t.length) - /** @type {number} */ (t._currentOffset)) / 2
|
|
83
|
+
)
|
|
65
84
|
},
|
|
66
85
|
|
|
67
86
|
6: { // Trimmed table
|
|
@@ -86,8 +105,8 @@ let CmapSubtable = new r.VersionedStruct(r.uint16, {
|
|
|
86
105
|
length: r.uint32,
|
|
87
106
|
language: r.uint32,
|
|
88
107
|
firstCode: r.uint32,
|
|
89
|
-
entryCount: r.uint32,
|
|
90
|
-
glyphIndices: new r.LazyArray(r.uint16, '
|
|
108
|
+
entryCount: r.uint32, // OpenType name: numChars
|
|
109
|
+
glyphIndices: new r.LazyArray(r.uint16, 'entryCount')
|
|
91
110
|
},
|
|
92
111
|
|
|
93
112
|
12: { // Segmented coverage
|
|
@@ -120,6 +139,7 @@ let CmapEntry = new r.Struct({
|
|
|
120
139
|
});
|
|
121
140
|
|
|
122
141
|
// character to glyph mapping
|
|
142
|
+
/** @type {import('restructure').Struct} */
|
|
123
143
|
export default new r.Struct({
|
|
124
144
|
version: r.uint16,
|
|
125
145
|
numSubtables: r.uint16,
|
package/src/tables/cvt.js
CHANGED
package/src/tables/directory.js
CHANGED
|
@@ -1,58 +1,86 @@
|
|
|
1
1
|
import * as r from 'restructure';
|
|
2
2
|
import Tables from './';
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
/** @typedef {import('restructure').StructValue} StructValue */
|
|
5
|
+
/** @typedef {import('../../types/fontkit').TableEntry} TableEntry */
|
|
6
|
+
/** @typedef {import('../../types/fontkit').TableCodec} TableCodec */
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @typedef {StructValue & {
|
|
10
|
+
* tag: string,
|
|
11
|
+
* numTables: number,
|
|
12
|
+
* searchRange: number,
|
|
13
|
+
* entrySelector: number,
|
|
14
|
+
* rangeShift: number,
|
|
15
|
+
* tables: TableEntry[] | Record<string, TableEntry>
|
|
16
|
+
* }} DirectoryValue
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
let TableEntryStruct = new r.Struct({
|
|
5
20
|
tag: new r.String(4),
|
|
6
21
|
checkSum: r.uint32,
|
|
7
22
|
offset: new r.Pointer(r.uint32, 'void', { type: 'global' }),
|
|
8
23
|
length: r.uint32
|
|
9
24
|
});
|
|
10
25
|
|
|
26
|
+
/** @type {import('restructure').Struct} */
|
|
11
27
|
let Directory = new r.Struct({
|
|
12
28
|
tag: new r.String(4),
|
|
13
29
|
numTables: r.uint16,
|
|
14
30
|
searchRange: r.uint16,
|
|
15
31
|
entrySelector: r.uint16,
|
|
16
32
|
rangeShift: r.uint16,
|
|
17
|
-
tables: new r.Array(
|
|
33
|
+
tables: new r.Array(TableEntryStruct, 'numTables')
|
|
18
34
|
});
|
|
19
35
|
|
|
20
36
|
Directory.process = function () {
|
|
37
|
+
let self = /** @type {DirectoryValue} */ (this);
|
|
38
|
+
/** @type {Record<string, TableEntry>} */
|
|
21
39
|
let tables = {};
|
|
22
|
-
for (let table of
|
|
40
|
+
for (let table of /** @type {TableEntry[]} */ (self.tables)) {
|
|
23
41
|
tables[table.tag] = table;
|
|
24
42
|
}
|
|
25
43
|
|
|
26
|
-
|
|
44
|
+
self.tables = tables;
|
|
27
45
|
};
|
|
28
46
|
|
|
29
47
|
Directory.preEncode = function () {
|
|
30
|
-
|
|
48
|
+
let self = /** @type {DirectoryValue} */ (this);
|
|
49
|
+
if (!Array.isArray(self.tables)) {
|
|
50
|
+
/** @type {TableEntry[]} */
|
|
31
51
|
let tables = [];
|
|
32
|
-
|
|
33
|
-
|
|
52
|
+
/** @type {Record<string, TableEntry>} */
|
|
53
|
+
let byTag = self.tables;
|
|
54
|
+
for (let tag of Object.keys(byTag)) {
|
|
55
|
+
let table = byTag[tag];
|
|
34
56
|
if (table) {
|
|
57
|
+
let codec = /** @type {TableCodec | undefined} */ (Tables[tag]);
|
|
58
|
+
if (!codec || typeof codec.size !== 'function') {
|
|
59
|
+
throw new Error(`Missing encoder for table "${tag}"`);
|
|
60
|
+
}
|
|
35
61
|
tables.push({
|
|
36
62
|
tag: tag,
|
|
37
63
|
checkSum: 0,
|
|
38
|
-
offset:
|
|
39
|
-
|
|
64
|
+
offset: /** @type {number} */ (/** @type {unknown} */ (
|
|
65
|
+
new r.VoidPointer(/** @type {import('restructure').BaseType} */ (/** @type {unknown} */ (codec)), table)
|
|
66
|
+
)),
|
|
67
|
+
length: codec.size(table)
|
|
40
68
|
});
|
|
41
69
|
}
|
|
42
70
|
}
|
|
43
71
|
|
|
44
|
-
|
|
72
|
+
self.tables = tables;
|
|
45
73
|
}
|
|
46
74
|
|
|
47
|
-
|
|
48
|
-
|
|
75
|
+
self.tag = 'true';
|
|
76
|
+
self.numTables = self.tables.length;
|
|
49
77
|
|
|
50
|
-
let maxExponentFor2 = Math.floor((Math.log(
|
|
78
|
+
let maxExponentFor2 = Math.floor((Math.log(self.numTables) / Math.LN2));
|
|
51
79
|
let maxPowerOf2 = Math.pow(2, maxExponentFor2);
|
|
52
80
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
81
|
+
self.searchRange = maxPowerOf2 * 16;
|
|
82
|
+
self.entrySelector = Math.log(maxPowerOf2) / Math.LN2;
|
|
83
|
+
self.rangeShift = self.numTables * 16 - self.searchRange;
|
|
56
84
|
};
|
|
57
85
|
|
|
58
86
|
export default Directory;
|