@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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cantoo/fontkit",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.7",
|
|
4
4
|
"description": "An advanced font engine for Node and the browser",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"opentype",
|
|
@@ -18,9 +18,12 @@
|
|
|
18
18
|
"trie:indic": "node src/opentype/shapers/gen-indic.js",
|
|
19
19
|
"tries": "npm run trie:data && npm run trie:use && npm run trie:indic",
|
|
20
20
|
"build:packages": "node scripts/build-unicode-packages.js",
|
|
21
|
-
"build": "
|
|
21
|
+
"build:types": "node scripts/build-types.js",
|
|
22
|
+
"build:umd": "node scripts/build-umd.js",
|
|
23
|
+
"build": "npm run build:packages && tsup && npm run build:umd && npm run build:types",
|
|
22
24
|
"prebuild": "node --input-type=module -e \"import fs from 'node:fs'; if (!fs.existsSync('src/opentype/shapers/data.trie')) { console.error('Missing trie files. Run: npm run tries'); process.exit(1); }\"",
|
|
23
25
|
"lint": "eslint .",
|
|
26
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
24
27
|
"test": "vitest run",
|
|
25
28
|
"test:watch": "vitest",
|
|
26
29
|
"coverage": "vitest run --coverage",
|
|
@@ -32,15 +35,27 @@
|
|
|
32
35
|
"node-module": "dist/module.mjs",
|
|
33
36
|
"browser": "dist/browser.cjs",
|
|
34
37
|
"module": "dist/browser-module.mjs",
|
|
38
|
+
"unpkg": "dist/fontkit.umd.js",
|
|
39
|
+
"jsdelivr": "dist/fontkit.umd.js",
|
|
40
|
+
"types": "dist/index.d.ts",
|
|
35
41
|
"source": "src/index.js",
|
|
36
42
|
"exports": {
|
|
37
43
|
".": {
|
|
44
|
+
"types": "./dist/index.d.ts",
|
|
38
45
|
"node": {
|
|
46
|
+
"types": "./dist/index.d.ts",
|
|
39
47
|
"import": "./dist/module.mjs",
|
|
40
48
|
"require": "./dist/main.cjs"
|
|
41
49
|
},
|
|
42
|
-
"import":
|
|
43
|
-
|
|
50
|
+
"import": {
|
|
51
|
+
"types": "./dist/index.d.ts",
|
|
52
|
+
"default": "./dist/browser-module.mjs"
|
|
53
|
+
},
|
|
54
|
+
"require": {
|
|
55
|
+
"types": "./dist/index.d.ts",
|
|
56
|
+
"default": "./dist/browser.cjs"
|
|
57
|
+
},
|
|
58
|
+
"default": "./dist/browser-module.mjs"
|
|
44
59
|
},
|
|
45
60
|
"./unicode-trie": {
|
|
46
61
|
"import": "./src/packages/unicode-trie/dist/index.mjs",
|
|
@@ -58,7 +73,8 @@
|
|
|
58
73
|
},
|
|
59
74
|
"files": [
|
|
60
75
|
"src",
|
|
61
|
-
"dist"
|
|
76
|
+
"dist",
|
|
77
|
+
"types"
|
|
62
78
|
],
|
|
63
79
|
"author": "Devon Govett <devongovett@gmail.com>",
|
|
64
80
|
"license": "MIT",
|
|
@@ -83,6 +99,7 @@
|
|
|
83
99
|
"@babel/plugin-proposal-decorators": "^8.0.2",
|
|
84
100
|
"@eslint/js": "^10.0.1",
|
|
85
101
|
"@stylistic/eslint-plugin": "^5.10.0",
|
|
102
|
+
"@types/node": "^26.5.0",
|
|
86
103
|
"@vitest/coverage-v8": "^5.0.0",
|
|
87
104
|
"codepoints": "^1.3.0",
|
|
88
105
|
"esbuild": "^0.28.2",
|
package/src/CmapProcessor.js
CHANGED
|
@@ -3,9 +3,19 @@ import { getEncoding, getEncodingMapping } from './encodings';
|
|
|
3
3
|
import { cache } from './decorators';
|
|
4
4
|
import { range } from './utils';
|
|
5
5
|
|
|
6
|
+
/** @typedef {import('../types/fontkit').CmapTable} CmapTable */
|
|
7
|
+
/** @typedef {import('../types/fontkit').CmapSubtable} CmapSubtable */
|
|
8
|
+
/** @typedef {import('../types/fontkit').CmapSubtable14} CmapSubtable14 */
|
|
9
|
+
/** @typedef {import('../types/fontkit').CmapGroup} CmapGroup */
|
|
10
|
+
/** @typedef {import('../types/fontkit').CmapVarSelector} CmapVarSelector */
|
|
11
|
+
|
|
6
12
|
export default class CmapProcessor {
|
|
13
|
+
/**
|
|
14
|
+
* @param {CmapTable} cmapTable
|
|
15
|
+
*/
|
|
7
16
|
constructor(cmapTable) {
|
|
8
17
|
// Attempt to find a Unicode cmap first
|
|
18
|
+
/** @type {Map<number, number> | null} */
|
|
9
19
|
this.encoding = null;
|
|
10
20
|
this.cmap = this.findSubtable(cmapTable, [
|
|
11
21
|
// 32-bit subtables
|
|
@@ -24,7 +34,14 @@ export default class CmapProcessor {
|
|
|
24
34
|
// If not unicode cmap was found, take the first table with a supported encoding.
|
|
25
35
|
if (!this.cmap) {
|
|
26
36
|
for (let cmap of cmapTable.tables) {
|
|
27
|
-
let
|
|
37
|
+
let language
|
|
38
|
+
= 'language' in cmap.table && typeof cmap.table.language === 'number'
|
|
39
|
+
? cmap.table.language - 1
|
|
40
|
+
: 0;
|
|
41
|
+
let encoding = getEncoding(cmap.platformID, cmap.encodingID, language);
|
|
42
|
+
if (!encoding) {
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
28
45
|
let mapping = getEncodingMapping(encoding);
|
|
29
46
|
if (mapping) {
|
|
30
47
|
this.cmap = cmap.table;
|
|
@@ -37,12 +54,16 @@ export default class CmapProcessor {
|
|
|
37
54
|
throw new Error('Could not find a supported cmap table');
|
|
38
55
|
}
|
|
39
56
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
57
|
+
let uvs = this.findSubtable(cmapTable, [[0, 5]]);
|
|
58
|
+
/** @type {CmapSubtable14 | null} */
|
|
59
|
+
this.uvs = uvs && uvs.version === 14 ? /** @type {CmapSubtable14} */ (uvs) : null;
|
|
44
60
|
}
|
|
45
61
|
|
|
62
|
+
/**
|
|
63
|
+
* @param {CmapTable} cmapTable
|
|
64
|
+
* @param {Array<[number, number]>} pairs
|
|
65
|
+
* @returns {CmapSubtable | null}
|
|
66
|
+
*/
|
|
46
67
|
findSubtable(cmapTable, pairs) {
|
|
47
68
|
for (let [platformID, encodingID] of pairs) {
|
|
48
69
|
for (let cmap of cmapTable.tables) {
|
|
@@ -55,6 +76,11 @@ export default class CmapProcessor {
|
|
|
55
76
|
return null;
|
|
56
77
|
}
|
|
57
78
|
|
|
79
|
+
/**
|
|
80
|
+
* @param {number} codepoint
|
|
81
|
+
* @param {number} [variationSelector]
|
|
82
|
+
* @returns {number}
|
|
83
|
+
*/
|
|
58
84
|
lookup(codepoint, variationSelector) {
|
|
59
85
|
// If there is no Unicode cmap in this font, we need to re-encode
|
|
60
86
|
// the codepoint in the encoding that the cmap supports.
|
|
@@ -80,21 +106,21 @@ export default class CmapProcessor {
|
|
|
80
106
|
while (min <= max) {
|
|
81
107
|
let mid = (min + max) >> 1;
|
|
82
108
|
|
|
83
|
-
if (codepoint < cmap.startCode.get(mid)) {
|
|
109
|
+
if (codepoint < /** @type {number} */ (cmap.startCode.get(mid))) {
|
|
84
110
|
max = mid - 1;
|
|
85
|
-
} else if (codepoint > cmap.endCode.get(mid)) {
|
|
111
|
+
} else if (codepoint > /** @type {number} */ (cmap.endCode.get(mid))) {
|
|
86
112
|
min = mid + 1;
|
|
87
113
|
} else {
|
|
88
|
-
let rangeOffset = cmap.idRangeOffset.get(mid);
|
|
114
|
+
let rangeOffset = /** @type {number} */ (cmap.idRangeOffset.get(mid));
|
|
89
115
|
let gid;
|
|
90
116
|
|
|
91
117
|
if (rangeOffset === 0) {
|
|
92
|
-
gid = codepoint + cmap.idDelta.get(mid);
|
|
118
|
+
gid = codepoint + /** @type {number} */ (cmap.idDelta.get(mid));
|
|
93
119
|
} else {
|
|
94
|
-
let index = rangeOffset / 2 + (codepoint - cmap.startCode.get(mid)) - (cmap.segCount - mid);
|
|
120
|
+
let index = rangeOffset / 2 + (codepoint - /** @type {number} */ (cmap.startCode.get(mid))) - (cmap.segCount - mid);
|
|
95
121
|
gid = cmap.glyphIndexArray.get(index) || 0;
|
|
96
122
|
if (gid !== 0) {
|
|
97
|
-
gid += cmap.idDelta.get(mid);
|
|
123
|
+
gid += /** @type {number} */ (cmap.idDelta.get(mid));
|
|
98
124
|
}
|
|
99
125
|
}
|
|
100
126
|
|
|
@@ -118,7 +144,7 @@ export default class CmapProcessor {
|
|
|
118
144
|
let max = cmap.nGroups - 1;
|
|
119
145
|
while (min <= max) {
|
|
120
146
|
let mid = (min + max) >> 1;
|
|
121
|
-
let group = cmap.groups.get(mid);
|
|
147
|
+
let group = /** @type {CmapGroup} */ (cmap.groups.get(mid));
|
|
122
148
|
|
|
123
149
|
if (codepoint < group.startCharCode) {
|
|
124
150
|
max = mid - 1;
|
|
@@ -140,10 +166,15 @@ export default class CmapProcessor {
|
|
|
140
166
|
throw new Error('TODO: cmap format 14');
|
|
141
167
|
|
|
142
168
|
default:
|
|
143
|
-
throw new Error(`Unknown cmap format ${cmap.version}`);
|
|
169
|
+
throw new Error(`Unknown cmap format ${/** @type {{ version: number }} */ (cmap).version}`);
|
|
144
170
|
}
|
|
145
171
|
}
|
|
146
172
|
|
|
173
|
+
/**
|
|
174
|
+
* @param {number} codepoint
|
|
175
|
+
* @param {number} variationSelector
|
|
176
|
+
* @returns {number}
|
|
177
|
+
*/
|
|
147
178
|
getVariationSelector(codepoint, variationSelector) {
|
|
148
179
|
if (!this.uvs) {
|
|
149
180
|
return 0;
|
|
@@ -155,7 +186,8 @@ export default class CmapProcessor {
|
|
|
155
186
|
return 0;
|
|
156
187
|
}
|
|
157
188
|
|
|
158
|
-
let
|
|
189
|
+
let sel = /** @type {CmapVarSelector} */ (selectors[i]);
|
|
190
|
+
let { defaultUVS, nonDefaultUVS } = sel;
|
|
159
191
|
|
|
160
192
|
// Default UVS: fall back to the base character's normal cmap glyph.
|
|
161
193
|
if (defaultUVS && binarySearch(defaultUVS, x =>
|
|
@@ -168,6 +200,9 @@ export default class CmapProcessor {
|
|
|
168
200
|
return ni !== -1 ? nonDefaultUVS[ni].glyphID : 0;
|
|
169
201
|
}
|
|
170
202
|
|
|
203
|
+
/**
|
|
204
|
+
* @returns {number[]}
|
|
205
|
+
*/
|
|
171
206
|
@cache
|
|
172
207
|
getCharacterSet() {
|
|
173
208
|
let cmap = this.cmap;
|
|
@@ -180,7 +215,7 @@ export default class CmapProcessor {
|
|
|
180
215
|
let endCodes = cmap.endCode.toArray();
|
|
181
216
|
for (let i = 0; i < endCodes.length; i++) {
|
|
182
217
|
let tail = endCodes[i] + 1;
|
|
183
|
-
let start = cmap.startCode.get(i);
|
|
218
|
+
let start = /** @type {number} */ (cmap.startCode.get(i));
|
|
184
219
|
res.push(...range(start, tail));
|
|
185
220
|
}
|
|
186
221
|
|
|
@@ -208,10 +243,14 @@ export default class CmapProcessor {
|
|
|
208
243
|
throw new Error('TODO: cmap format 14');
|
|
209
244
|
|
|
210
245
|
default:
|
|
211
|
-
throw new Error(`Unknown cmap format ${cmap.version}`);
|
|
246
|
+
throw new Error(`Unknown cmap format ${/** @type {{ version: number }} */ (cmap).version}`);
|
|
212
247
|
}
|
|
213
248
|
}
|
|
214
249
|
|
|
250
|
+
/**
|
|
251
|
+
* @param {number} gid
|
|
252
|
+
* @returns {number[]}
|
|
253
|
+
*/
|
|
215
254
|
@cache
|
|
216
255
|
codePointsForGlyph(gid) {
|
|
217
256
|
let cmap = this.cmap;
|
|
@@ -230,10 +269,10 @@ export default class CmapProcessor {
|
|
|
230
269
|
case 4: {
|
|
231
270
|
let res = [];
|
|
232
271
|
for (let i = 0; i < cmap.segCount; i++) {
|
|
233
|
-
let end = cmap.endCode.get(i);
|
|
234
|
-
let start = cmap.startCode.get(i);
|
|
235
|
-
let rangeOffset = cmap.idRangeOffset.get(i);
|
|
236
|
-
let delta = cmap.idDelta.get(i);
|
|
272
|
+
let end = /** @type {number} */ (cmap.endCode.get(i));
|
|
273
|
+
let start = /** @type {number} */ (cmap.startCode.get(i));
|
|
274
|
+
let rangeOffset = /** @type {number} */ (cmap.idRangeOffset.get(i));
|
|
275
|
+
let delta = /** @type {number} */ (cmap.idDelta.get(i));
|
|
237
276
|
|
|
238
277
|
for (var c = start; c <= end; c++) {
|
|
239
278
|
let g;
|
package/src/DFont.js
CHANGED
|
@@ -1,6 +1,68 @@
|
|
|
1
1
|
import * as r from 'restructure';
|
|
2
2
|
import TTFFont from './TTFFont';
|
|
3
3
|
|
|
4
|
+
/** @typedef {import('restructure').DecodeStream} DecodeStream */
|
|
5
|
+
/** @typedef {import('restructure').StructValue} StructValue */
|
|
6
|
+
/** @typedef {import('restructure').BinaryBuffer} BinaryBuffer */
|
|
7
|
+
/** @typedef {import('../types/fontkit').NameString} NameString */
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @param {NameString | null | undefined} a
|
|
11
|
+
* @param {string | Uint8Array} b
|
|
12
|
+
* @returns {boolean}
|
|
13
|
+
*/
|
|
14
|
+
function postscriptNamesEqual(a, b) {
|
|
15
|
+
if (a === b) {
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
if (a instanceof Uint8Array && b instanceof Uint8Array) {
|
|
19
|
+
return a.length === b.length && a.every((v, i) => b[i] === v);
|
|
20
|
+
}
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @typedef {StructValue & {
|
|
26
|
+
* id: number,
|
|
27
|
+
* nameOffset: number,
|
|
28
|
+
* attr: number,
|
|
29
|
+
* dataOffset: number,
|
|
30
|
+
* handle: number,
|
|
31
|
+
* name?: string | null
|
|
32
|
+
* }} DFontRef
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @typedef {StructValue & {
|
|
37
|
+
* name: string,
|
|
38
|
+
* maxTypeIndex: number,
|
|
39
|
+
* refList: DFontRef[]
|
|
40
|
+
* }} DFontType
|
|
41
|
+
*/
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @typedef {StructValue & {
|
|
45
|
+
* length: number,
|
|
46
|
+
* types: DFontType[]
|
|
47
|
+
* }} DFontTypeList
|
|
48
|
+
*/
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @typedef {StructValue & {
|
|
52
|
+
* typeList: DFontTypeList,
|
|
53
|
+
* nameListOffset: number
|
|
54
|
+
* }} DFontMap
|
|
55
|
+
*/
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @typedef {StructValue & {
|
|
59
|
+
* dataOffset: number,
|
|
60
|
+
* map: DFontMap,
|
|
61
|
+
* dataLength: number,
|
|
62
|
+
* mapLength: number
|
|
63
|
+
* }} DFontHeaderValue
|
|
64
|
+
*/
|
|
65
|
+
|
|
4
66
|
let DFontName = new r.String(r.uint8);
|
|
5
67
|
|
|
6
68
|
let Ref = new r.Struct({
|
|
@@ -14,12 +76,16 @@ let Ref = new r.Struct({
|
|
|
14
76
|
let Type = new r.Struct({
|
|
15
77
|
name: new r.String(4),
|
|
16
78
|
maxTypeIndex: r.uint16,
|
|
17
|
-
refList: new r.Pointer(
|
|
79
|
+
refList: new r.Pointer(
|
|
80
|
+
r.uint16,
|
|
81
|
+
new r.Array(Ref, t => /** @type {DFontType} */ (t).maxTypeIndex + 1),
|
|
82
|
+
{ type: 'parent' }
|
|
83
|
+
)
|
|
18
84
|
});
|
|
19
85
|
|
|
20
86
|
let TypeList = new r.Struct({
|
|
21
87
|
length: r.uint16,
|
|
22
|
-
types: new r.Array(Type, t => t.length + 1)
|
|
88
|
+
types: new r.Array(Type, t => /** @type {DFontTypeList} */ (t).length + 1)
|
|
23
89
|
});
|
|
24
90
|
|
|
25
91
|
let DFontMap = new r.Struct({
|
|
@@ -36,13 +102,27 @@ let DFontHeader = new r.Struct({
|
|
|
36
102
|
});
|
|
37
103
|
|
|
38
104
|
export default class DFont {
|
|
105
|
+
/** @type {string} */
|
|
39
106
|
type = 'DFont';
|
|
40
107
|
|
|
108
|
+
/** @type {DecodeStream} */
|
|
109
|
+
stream;
|
|
110
|
+
/** @type {DFontHeaderValue} */
|
|
111
|
+
header;
|
|
112
|
+
/** @type {DFontType | undefined} */
|
|
113
|
+
sfnt;
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* @param {BinaryBuffer | Uint8Array} buffer
|
|
117
|
+
* @returns {boolean}
|
|
118
|
+
*/
|
|
41
119
|
static probe(buffer) {
|
|
42
120
|
let stream = new r.DecodeStream(buffer);
|
|
43
121
|
|
|
44
122
|
try {
|
|
45
|
-
var header =
|
|
123
|
+
var header = /** @type {DFontHeaderValue} */ (
|
|
124
|
+
/** @type {unknown} */ (DFontHeader.decode(stream))
|
|
125
|
+
);
|
|
46
126
|
} catch (e) {
|
|
47
127
|
return false;
|
|
48
128
|
}
|
|
@@ -56,9 +136,14 @@ export default class DFont {
|
|
|
56
136
|
return false;
|
|
57
137
|
}
|
|
58
138
|
|
|
139
|
+
/**
|
|
140
|
+
* @param {DecodeStream} stream
|
|
141
|
+
*/
|
|
59
142
|
constructor(stream) {
|
|
60
143
|
this.stream = stream;
|
|
61
|
-
this.header =
|
|
144
|
+
this.header = /** @type {DFontHeaderValue} */ (
|
|
145
|
+
/** @type {unknown} */ (DFontHeader.decode(this.stream))
|
|
146
|
+
);
|
|
62
147
|
|
|
63
148
|
for (let type of this.header.map.typeList.types) {
|
|
64
149
|
for (let ref of type.refList) {
|
|
@@ -76,6 +161,10 @@ export default class DFont {
|
|
|
76
161
|
}
|
|
77
162
|
}
|
|
78
163
|
|
|
164
|
+
/**
|
|
165
|
+
* @param {string | Uint8Array} name
|
|
166
|
+
* @returns {TTFFont | null}
|
|
167
|
+
*/
|
|
79
168
|
getFont(name) {
|
|
80
169
|
if (!this.sfnt) {
|
|
81
170
|
return null;
|
|
@@ -83,16 +172,14 @@ export default class DFont {
|
|
|
83
172
|
|
|
84
173
|
for (let ref of this.sfnt.refList) {
|
|
85
174
|
let pos = this.header.dataOffset + ref.dataOffset + 4;
|
|
86
|
-
let
|
|
175
|
+
let buf = this.stream.buffer;
|
|
176
|
+
let bytes
|
|
177
|
+
= buf instanceof Uint8Array
|
|
178
|
+
? buf
|
|
179
|
+
: new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
|
|
180
|
+
let stream = new r.DecodeStream(bytes.subarray(pos));
|
|
87
181
|
let font = new TTFFont(stream);
|
|
88
|
-
if (
|
|
89
|
-
font.postscriptName === name
|
|
90
|
-
|| (
|
|
91
|
-
font.postscriptName instanceof Uint8Array
|
|
92
|
-
&& name instanceof Uint8Array
|
|
93
|
-
&& font.postscriptName.every((v, i) => name[i] === v)
|
|
94
|
-
)
|
|
95
|
-
) {
|
|
182
|
+
if (postscriptNamesEqual(font.postscriptName, name)) {
|
|
96
183
|
return font;
|
|
97
184
|
}
|
|
98
185
|
}
|
|
@@ -100,11 +187,24 @@ export default class DFont {
|
|
|
100
187
|
return null;
|
|
101
188
|
}
|
|
102
189
|
|
|
190
|
+
/**
|
|
191
|
+
* @type {TTFFont[]}
|
|
192
|
+
*/
|
|
103
193
|
get fonts() {
|
|
194
|
+
/** @type {TTFFont[]} */
|
|
104
195
|
let fonts = [];
|
|
196
|
+
if (!this.sfnt) {
|
|
197
|
+
return fonts;
|
|
198
|
+
}
|
|
199
|
+
|
|
105
200
|
for (let ref of this.sfnt.refList) {
|
|
106
201
|
let pos = this.header.dataOffset + ref.dataOffset + 4;
|
|
107
|
-
let
|
|
202
|
+
let buf = this.stream.buffer;
|
|
203
|
+
let bytes
|
|
204
|
+
= buf instanceof Uint8Array
|
|
205
|
+
? buf
|
|
206
|
+
: new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
|
|
207
|
+
let stream = new r.DecodeStream(bytes.subarray(pos));
|
|
108
208
|
fonts.push(new TTFFont(stream));
|
|
109
209
|
}
|
|
110
210
|
|