@flighthq/font-formats 0.3.1-next.209.43ef1bc
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/cffCharstring.d.ts +13 -0
- package/dist/cffCharstring.d.ts.map +1 -0
- package/dist/cffCharstring.js +336 -0
- package/dist/cffCharstring.js.map +1 -0
- package/dist/cffDict.d.ts +8 -0
- package/dist/cffDict.d.ts.map +1 -0
- package/dist/cffDict.js +118 -0
- package/dist/cffDict.js.map +1 -0
- package/dist/cffFdSelect.d.ts +2 -0
- package/dist/cffFdSelect.d.ts.map +1 -0
- package/dist/cffFdSelect.js +60 -0
- package/dist/cffFdSelect.js.map +1 -0
- package/dist/cffIndex.d.ts +3 -0
- package/dist/cffIndex.d.ts.map +1 -0
- package/dist/cffIndex.js +52 -0
- package/dist/cffIndex.js.map +1 -0
- package/dist/cffTable.d.ts +3 -0
- package/dist/cffTable.d.ts.map +1 -0
- package/dist/cffTable.js +134 -0
- package/dist/cffTable.js.map +1 -0
- package/dist/contract.d.ts +15 -0
- package/dist/contract.d.ts.map +1 -0
- package/dist/contract.js +15 -0
- package/dist/contract.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/openTypeCmap.d.ts +5 -0
- package/dist/openTypeCmap.d.ts.map +1 -0
- package/dist/openTypeCmap.js +161 -0
- package/dist/openTypeCmap.js.map +1 -0
- package/dist/openTypeGlyf.d.ts +4 -0
- package/dist/openTypeGlyf.d.ts.map +1 -0
- package/dist/openTypeGlyf.js +229 -0
- package/dist/openTypeGlyf.js.map +1 -0
- package/dist/openTypeGlyphOutlineSource.d.ts +4 -0
- package/dist/openTypeGlyphOutlineSource.d.ts.map +1 -0
- package/dist/openTypeGlyphOutlineSource.js +168 -0
- package/dist/openTypeGlyphOutlineSource.js.map +1 -0
- package/dist/openTypeMetrics.d.ts +6 -0
- package/dist/openTypeMetrics.d.ts.map +1 -0
- package/dist/openTypeMetrics.js +74 -0
- package/dist/openTypeMetrics.js.map +1 -0
- package/dist/openTypeTestHelper.d.ts +26 -0
- package/dist/openTypeTestHelper.d.ts.map +1 -0
- package/dist/openTypeTestHelper.js +494 -0
- package/dist/openTypeTestHelper.js.map +1 -0
- package/dist/sfntAssembly.d.ts +7 -0
- package/dist/sfntAssembly.d.ts.map +1 -0
- package/dist/sfntAssembly.js +77 -0
- package/dist/sfntAssembly.js.map +1 -0
- package/dist/sfntTableDirectory.d.ts +4 -0
- package/dist/sfntTableDirectory.d.ts.map +1 -0
- package/dist/sfntTableDirectory.js +39 -0
- package/dist/sfntTableDirectory.js.map +1 -0
- package/dist/woff2Font.d.ts +6 -0
- package/dist/woff2Font.d.ts.map +1 -0
- package/dist/woff2Font.js +210 -0
- package/dist/woff2Font.js.map +1 -0
- package/dist/woff2GlyfTransform.d.ts +6 -0
- package/dist/woff2GlyfTransform.d.ts.map +1 -0
- package/dist/woff2GlyfTransform.js +104 -0
- package/dist/woff2GlyfTransform.js.map +1 -0
- package/dist/woffFont.d.ts +6 -0
- package/dist/woffFont.d.ts.map +1 -0
- package/dist/woffFont.js +112 -0
- package/dist/woffFont.js.map +1 -0
- package/package.json +50 -0
- package/src/cffCharstring.test.ts +177 -0
- package/src/cffDict.test.ts +67 -0
- package/src/cffFdSelect.test.ts +84 -0
- package/src/cffIndex.test.ts +97 -0
- package/src/cffTable.test.ts +84 -0
- package/src/openTypeCmap.test.ts +124 -0
- package/src/openTypeGlyf.test.ts +168 -0
- package/src/openTypeGlyphOutlineSource.test.ts +298 -0
- package/src/openTypeMetrics.test.ts +103 -0
- package/src/sfntAssembly.test.ts +92 -0
- package/src/sfntTableDirectory.test.ts +64 -0
- package/src/woff2Font.test.ts +125 -0
- package/src/woff2GlyfTransform.test.ts +88 -0
- package/src/woffFont.test.ts +167 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Path } from '@flighthq/types/contract';
|
|
2
|
+
export declare function cffSubroutineBias(count: number): number;
|
|
3
|
+
export declare function runCffCharstring(out: Path, bytes: Readonly<Uint8Array>, charstring: Readonly<{
|
|
4
|
+
end: number;
|
|
5
|
+
start: number;
|
|
6
|
+
}>, localSubrs: readonly Readonly<{
|
|
7
|
+
end: number;
|
|
8
|
+
start: number;
|
|
9
|
+
}>[], globalSubrs: readonly Readonly<{
|
|
10
|
+
end: number;
|
|
11
|
+
start: number;
|
|
12
|
+
}>[]): boolean;
|
|
13
|
+
//# sourceMappingURL=cffCharstring.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cffCharstring.d.ts","sourceRoot":"","sources":["../src/cffCharstring.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AA4BrD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIvD;AAQD,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,IAAI,EACT,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,EAC3B,UAAU,EAAE,QAAQ,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,EACpD,UAAU,EAAE,SAAS,QAAQ,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,EAAE,EAC/D,WAAW,EAAE,SAAS,QAAQ,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,EAAE,GAC/D,OAAO,CAwQT"}
|
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
import { PathCommand } from '@flighthq/types/contract';
|
|
2
|
+
// The Type 2 charstring interpreter: a stack machine whose operators emit path segments.
|
|
3
|
+
//
|
|
4
|
+
// WHAT MAKES IT DIFFERENT FROM THE `glyf` READER NEXT DOOR, AND WHY THEY SHARE NO CODE: `glyf` is a
|
|
5
|
+
// point list to be walked, while this is a PROGRAM to be executed — with subroutine calls, a stack, and
|
|
6
|
+
// operators whose argument count is variable and sometimes decided by parity. Its curves are CUBIC, so
|
|
7
|
+
// they emit `CUBIC_CURVE_TO` where `glyf` emits the quadratic `CURVE_TO`.
|
|
8
|
+
//
|
|
9
|
+
// Operator numbers and their argument shapes are interface facts about the format — what a published
|
|
10
|
+
// format exists to state. The execution model here is Flight's own.
|
|
11
|
+
//
|
|
12
|
+
// THREE RULES CAUSE MOST OF THE SILENT WRONGNESS IN A READER OF THIS FORMAT, SO THEY ARE NAMED:
|
|
13
|
+
//
|
|
14
|
+
// 1. THE OPTIONAL LEADING WIDTH. The first stack-clearing operator may carry ONE extra leading argument
|
|
15
|
+
// — a width delta. Detected by parity against the operator's expected argument count, never by
|
|
16
|
+
// assuming presence. Getting it wrong shifts every coordinate in the glyph by one argument.
|
|
17
|
+
// 2. SUBROUTINE INDICES ARE BIASED, and the bias depends on how many subroutines exist. An unbiased
|
|
18
|
+
// index selects a real-but-wrong subroutine, which draws plausible garbage rather than failing.
|
|
19
|
+
// 3. `hintmask` CARRIES INLINE DATA. It consumes a mask whose length depends on how many stems have
|
|
20
|
+
// been declared — including stems declared implicitly by leaving arguments on the stack before it.
|
|
21
|
+
// Miscounting desynchronises the instruction stream from that point on.
|
|
22
|
+
const MAX_CALL_DEPTH = 10;
|
|
23
|
+
// Subroutine indices are stored biased so that small negative indices are representable in one byte. The
|
|
24
|
+
// bias depends on the subroutine count, so it cannot be a constant.
|
|
25
|
+
export function cffSubroutineBias(count) {
|
|
26
|
+
if (count < 1240)
|
|
27
|
+
return 107;
|
|
28
|
+
if (count < 33900)
|
|
29
|
+
return 1131;
|
|
30
|
+
return 32768;
|
|
31
|
+
}
|
|
32
|
+
// Replaces `out` with one glyph's contours, in font design units. Returns false when the charstring is
|
|
33
|
+
// unreadable; a glyph that legitimately draws nothing returns true with an empty path, matching the
|
|
34
|
+
// `glyf` reader so a caller never has to know which flavor produced the source.
|
|
35
|
+
//
|
|
36
|
+
// `y` is negated on emit, exactly as the TrueType path does, so both flavors agree with the documented
|
|
37
|
+
// y-down convention of `Path` and `GlyphOutlineMetrics`.
|
|
38
|
+
export function runCffCharstring(out, bytes, charstring, localSubrs, globalSubrs) {
|
|
39
|
+
out.commands.length = 0;
|
|
40
|
+
out.data.length = 0;
|
|
41
|
+
// `out` is REPLACED, so every field it owns is written — including this one. Both outline
|
|
42
|
+
// flavors fill by the nonzero rule, and a caller reusing a scratch path would otherwise keep
|
|
43
|
+
// whatever winding the previous glyph left, which turns a counter into a solid blob.
|
|
44
|
+
out.winding = 'nonZero';
|
|
45
|
+
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
46
|
+
const stack = [];
|
|
47
|
+
const state = {
|
|
48
|
+
open: false,
|
|
49
|
+
stemCount: 0,
|
|
50
|
+
widthParsed: false,
|
|
51
|
+
x: 0,
|
|
52
|
+
y: 0,
|
|
53
|
+
};
|
|
54
|
+
const moveTo = (x, y) => {
|
|
55
|
+
if (state.open)
|
|
56
|
+
out.commands.push(PathCommand.CLOSE);
|
|
57
|
+
out.commands.push(PathCommand.MOVE_TO);
|
|
58
|
+
out.data.push(x, -y);
|
|
59
|
+
state.open = true;
|
|
60
|
+
};
|
|
61
|
+
const lineTo = (x, y) => {
|
|
62
|
+
out.commands.push(PathCommand.LINE_TO);
|
|
63
|
+
out.data.push(x, -y);
|
|
64
|
+
};
|
|
65
|
+
const curveTo = (x1, y1, x2, y2, x, y) => {
|
|
66
|
+
out.commands.push(PathCommand.CUBIC_CURVE_TO);
|
|
67
|
+
out.data.push(x1, -y1, x2, -y2, x, -y);
|
|
68
|
+
};
|
|
69
|
+
// An operator that clears the stack may be preceded by the width. `expected` is how many arguments the
|
|
70
|
+
// operator itself takes; anything beyond that, once, is the width and is discarded.
|
|
71
|
+
const takeWidth = (expected) => {
|
|
72
|
+
if (!state.widthParsed) {
|
|
73
|
+
state.widthParsed = true;
|
|
74
|
+
if (stack.length > expected)
|
|
75
|
+
stack.shift();
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
// For operators taking a variable count, the width is present when the count has the wrong parity.
|
|
79
|
+
const takeWidthByParity = (multiple) => {
|
|
80
|
+
if (!state.widthParsed) {
|
|
81
|
+
state.widthParsed = true;
|
|
82
|
+
if (stack.length % multiple !== 0)
|
|
83
|
+
stack.shift();
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
const execute = (start, end, depth) => {
|
|
87
|
+
if (depth > MAX_CALL_DEPTH)
|
|
88
|
+
return false;
|
|
89
|
+
let cursor = start;
|
|
90
|
+
while (cursor < end) {
|
|
91
|
+
const b0 = view.getUint8(cursor);
|
|
92
|
+
cursor += 1;
|
|
93
|
+
if (b0 >= 32 || b0 === 28) {
|
|
94
|
+
const operand = readCffCharstringOperand(view, b0, cursor, end);
|
|
95
|
+
if (operand === null)
|
|
96
|
+
return false;
|
|
97
|
+
stack.push(operand.value);
|
|
98
|
+
cursor = operand.cursor;
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
switch (b0) {
|
|
102
|
+
case 1:
|
|
103
|
+
case 3:
|
|
104
|
+
case 18:
|
|
105
|
+
case 23: {
|
|
106
|
+
// Stem hints. Not applied — this package produces unhinted outlines — but they must be COUNTED,
|
|
107
|
+
// because `hintmask` sizes its inline data from the total.
|
|
108
|
+
takeWidthByParity(2);
|
|
109
|
+
state.stemCount += stack.length >> 1;
|
|
110
|
+
stack.length = 0;
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
case 19:
|
|
114
|
+
case 20: {
|
|
115
|
+
// Arguments still on the stack before a mask are an implicit vstem declaration.
|
|
116
|
+
takeWidthByParity(2);
|
|
117
|
+
state.stemCount += stack.length >> 1;
|
|
118
|
+
stack.length = 0;
|
|
119
|
+
cursor += (state.stemCount + 7) >> 3;
|
|
120
|
+
if (cursor > end)
|
|
121
|
+
return false;
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
case 21: {
|
|
125
|
+
takeWidth(2);
|
|
126
|
+
state.x += stack[0] ?? 0;
|
|
127
|
+
state.y += stack[1] ?? 0;
|
|
128
|
+
moveTo(state.x, state.y);
|
|
129
|
+
stack.length = 0;
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
case 22: {
|
|
133
|
+
takeWidth(1);
|
|
134
|
+
state.x += stack[0] ?? 0;
|
|
135
|
+
moveTo(state.x, state.y);
|
|
136
|
+
stack.length = 0;
|
|
137
|
+
break;
|
|
138
|
+
}
|
|
139
|
+
case 4: {
|
|
140
|
+
takeWidth(1);
|
|
141
|
+
state.y += stack[0] ?? 0;
|
|
142
|
+
moveTo(state.x, state.y);
|
|
143
|
+
stack.length = 0;
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
case 5: {
|
|
147
|
+
for (let index = 0; index + 1 < stack.length; index += 2) {
|
|
148
|
+
state.x += stack[index];
|
|
149
|
+
state.y += stack[index + 1];
|
|
150
|
+
lineTo(state.x, state.y);
|
|
151
|
+
}
|
|
152
|
+
stack.length = 0;
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
case 6:
|
|
156
|
+
case 7: {
|
|
157
|
+
// Alternating axis lines. The starting axis is the operator; each argument flips it.
|
|
158
|
+
let horizontal = b0 === 6;
|
|
159
|
+
for (const delta of stack) {
|
|
160
|
+
if (horizontal)
|
|
161
|
+
state.x += delta;
|
|
162
|
+
else
|
|
163
|
+
state.y += delta;
|
|
164
|
+
lineTo(state.x, state.y);
|
|
165
|
+
horizontal = !horizontal;
|
|
166
|
+
}
|
|
167
|
+
stack.length = 0;
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
case 8: {
|
|
171
|
+
for (let index = 0; index + 5 < stack.length; index += 6)
|
|
172
|
+
emitRelativeCurve(index, 6);
|
|
173
|
+
stack.length = 0;
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
case 24: {
|
|
177
|
+
// Curves, then exactly one closing line.
|
|
178
|
+
let index = 0;
|
|
179
|
+
for (; index + 5 < stack.length - 2; index += 6)
|
|
180
|
+
emitRelativeCurve(index, 6);
|
|
181
|
+
state.x += stack[index] ?? 0;
|
|
182
|
+
state.y += stack[index + 1] ?? 0;
|
|
183
|
+
lineTo(state.x, state.y);
|
|
184
|
+
stack.length = 0;
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
case 25: {
|
|
188
|
+
// Lines, then exactly one closing curve.
|
|
189
|
+
let index = 0;
|
|
190
|
+
for (; index + 1 < stack.length - 6; index += 2) {
|
|
191
|
+
state.x += stack[index];
|
|
192
|
+
state.y += stack[index + 1];
|
|
193
|
+
lineTo(state.x, state.y);
|
|
194
|
+
}
|
|
195
|
+
emitRelativeCurve(index, 6);
|
|
196
|
+
stack.length = 0;
|
|
197
|
+
break;
|
|
198
|
+
}
|
|
199
|
+
case 26:
|
|
200
|
+
case 27: {
|
|
201
|
+
// Curves constrained to one axis at their ends. An odd leading argument is a one-off offset on
|
|
202
|
+
// the other axis, applied to the first curve only.
|
|
203
|
+
const vertical = b0 === 26;
|
|
204
|
+
let index = 0;
|
|
205
|
+
let lead = 0;
|
|
206
|
+
if (stack.length % 4 === 1) {
|
|
207
|
+
lead = stack[0];
|
|
208
|
+
index = 1;
|
|
209
|
+
}
|
|
210
|
+
for (; index + 3 < stack.length; index += 4) {
|
|
211
|
+
const x1 = state.x + (vertical ? lead : stack[index]);
|
|
212
|
+
const y1 = state.y + (vertical ? stack[index] : lead);
|
|
213
|
+
const x2 = x1 + stack[index + 1];
|
|
214
|
+
const y2 = y1 + stack[index + 2];
|
|
215
|
+
state.x = x2 + (vertical ? 0 : stack[index + 3]);
|
|
216
|
+
state.y = y2 + (vertical ? stack[index + 3] : 0);
|
|
217
|
+
curveTo(x1, y1, x2, y2, state.x, state.y);
|
|
218
|
+
lead = 0;
|
|
219
|
+
}
|
|
220
|
+
stack.length = 0;
|
|
221
|
+
break;
|
|
222
|
+
}
|
|
223
|
+
case 30:
|
|
224
|
+
case 31: {
|
|
225
|
+
// Curves alternating between starting horizontal and starting vertical. A trailing fifth
|
|
226
|
+
// argument on the final curve supplies the otherwise-implied last coordinate.
|
|
227
|
+
let horizontal = b0 === 31;
|
|
228
|
+
let index = 0;
|
|
229
|
+
while (index + 3 < stack.length) {
|
|
230
|
+
const last = index + 8 > stack.length;
|
|
231
|
+
const extra = last && stack.length - index === 5 ? stack[index + 4] : 0;
|
|
232
|
+
let x1;
|
|
233
|
+
let y1;
|
|
234
|
+
if (horizontal) {
|
|
235
|
+
x1 = state.x + stack[index];
|
|
236
|
+
y1 = state.y;
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
x1 = state.x;
|
|
240
|
+
y1 = state.y + stack[index];
|
|
241
|
+
}
|
|
242
|
+
const x2 = x1 + stack[index + 1];
|
|
243
|
+
const y2 = y1 + stack[index + 2];
|
|
244
|
+
if (horizontal) {
|
|
245
|
+
state.y = y2 + stack[index + 3];
|
|
246
|
+
state.x = x2 + extra;
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
state.x = x2 + stack[index + 3];
|
|
250
|
+
state.y = y2 + extra;
|
|
251
|
+
}
|
|
252
|
+
curveTo(x1, y1, x2, y2, state.x, state.y);
|
|
253
|
+
horizontal = !horizontal;
|
|
254
|
+
index += 4;
|
|
255
|
+
}
|
|
256
|
+
stack.length = 0;
|
|
257
|
+
break;
|
|
258
|
+
}
|
|
259
|
+
case 10:
|
|
260
|
+
case 29: {
|
|
261
|
+
const subrs = b0 === 10 ? localSubrs : globalSubrs;
|
|
262
|
+
const index = (stack.pop() ?? 0) + cffSubroutineBias(subrs.length);
|
|
263
|
+
const subr = subrs[index];
|
|
264
|
+
if (subr === undefined)
|
|
265
|
+
return false;
|
|
266
|
+
if (!execute(subr.start, subr.end, depth + 1))
|
|
267
|
+
return false;
|
|
268
|
+
break;
|
|
269
|
+
}
|
|
270
|
+
case 11:
|
|
271
|
+
return true;
|
|
272
|
+
case 14: {
|
|
273
|
+
takeWidth(0);
|
|
274
|
+
if (state.open)
|
|
275
|
+
out.commands.push(PathCommand.CLOSE);
|
|
276
|
+
state.open = false;
|
|
277
|
+
return true;
|
|
278
|
+
}
|
|
279
|
+
case 12: {
|
|
280
|
+
// Escaped operators are arithmetic and flex variants. None is needed to produce an outline at
|
|
281
|
+
// this package's fidelity, but the argument stack must still be cleared or the next operator
|
|
282
|
+
// would consume values meant for this one.
|
|
283
|
+
if (cursor >= end)
|
|
284
|
+
return false;
|
|
285
|
+
cursor += 1;
|
|
286
|
+
stack.length = 0;
|
|
287
|
+
break;
|
|
288
|
+
}
|
|
289
|
+
default:
|
|
290
|
+
return false;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
return true;
|
|
294
|
+
};
|
|
295
|
+
// Shared by the curve operators that take plain relative triples.
|
|
296
|
+
function emitRelativeCurve(index, _stride) {
|
|
297
|
+
const x1 = state.x + stack[index];
|
|
298
|
+
const y1 = state.y + stack[index + 1];
|
|
299
|
+
const x2 = x1 + stack[index + 2];
|
|
300
|
+
const y2 = y1 + stack[index + 3];
|
|
301
|
+
state.x = x2 + stack[index + 4];
|
|
302
|
+
state.y = y2 + stack[index + 5];
|
|
303
|
+
curveTo(x1, y1, x2, y2, state.x, state.y);
|
|
304
|
+
}
|
|
305
|
+
if (!execute(charstring.start, charstring.end, 0))
|
|
306
|
+
return false;
|
|
307
|
+
// A charstring that ended without `endchar` still leaves a contour to close.
|
|
308
|
+
if (state.open)
|
|
309
|
+
out.commands.push(PathCommand.CLOSE);
|
|
310
|
+
return true;
|
|
311
|
+
}
|
|
312
|
+
// Charstring numbers use a different encoding from DICT numbers: 255 is a 16.16 fixed-point value here,
|
|
313
|
+
// where in a DICT it is unused. Reading one with the other's rule yields plausible coordinates.
|
|
314
|
+
function readCffCharstringOperand(view, b0, cursor, end) {
|
|
315
|
+
if (b0 === 28) {
|
|
316
|
+
if (cursor + 2 > end)
|
|
317
|
+
return null;
|
|
318
|
+
return { cursor: cursor + 2, value: view.getInt16(cursor) };
|
|
319
|
+
}
|
|
320
|
+
if (b0 <= 246)
|
|
321
|
+
return { cursor, value: b0 - 139 };
|
|
322
|
+
if (b0 <= 250) {
|
|
323
|
+
if (cursor + 1 > end)
|
|
324
|
+
return null;
|
|
325
|
+
return { cursor: cursor + 1, value: (b0 - 247) * 256 + view.getUint8(cursor) + 108 };
|
|
326
|
+
}
|
|
327
|
+
if (b0 <= 254) {
|
|
328
|
+
if (cursor + 1 > end)
|
|
329
|
+
return null;
|
|
330
|
+
return { cursor: cursor + 1, value: -(b0 - 251) * 256 - view.getUint8(cursor) - 108 };
|
|
331
|
+
}
|
|
332
|
+
if (cursor + 4 > end)
|
|
333
|
+
return null;
|
|
334
|
+
return { cursor: cursor + 4, value: view.getInt32(cursor) / 65536 };
|
|
335
|
+
}
|
|
336
|
+
//# sourceMappingURL=cffCharstring.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cffCharstring.js","sourceRoot":"","sources":["../src/cffCharstring.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEvD,yFAAyF;AACzF,EAAE;AACF,oGAAoG;AACpG,wGAAwG;AACxG,uGAAuG;AACvG,0EAA0E;AAC1E,EAAE;AACF,qGAAqG;AACrG,oEAAoE;AACpE,EAAE;AACF,gGAAgG;AAChG,EAAE;AACF,0GAA0G;AAC1G,oGAAoG;AACpG,iGAAiG;AACjG,sGAAsG;AACtG,qGAAqG;AACrG,sGAAsG;AACtG,wGAAwG;AACxG,6EAA6E;AAE7E,MAAM,cAAc,GAAG,EAAE,CAAC;AAE1B,yGAAyG;AACzG,oEAAoE;AACpE,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC7C,IAAI,KAAK,GAAG,IAAI;QAAE,OAAO,GAAG,CAAC;IAC7B,IAAI,KAAK,GAAG,KAAK;QAAE,OAAO,IAAI,CAAC;IAC/B,OAAO,KAAK,CAAC;AACf,CAAC;AAED,uGAAuG;AACvG,oGAAoG;AACpG,gFAAgF;AAChF,EAAE;AACF,uGAAuG;AACvG,yDAAyD;AACzD,MAAM,UAAU,gBAAgB,CAC9B,GAAS,EACT,KAA2B,EAC3B,UAAoD,EACpD,UAA+D,EAC/D,WAAgE;IAEhE,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;IACxB,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;IACpB,0FAA0F;IAC1F,6FAA6F;IAC7F,qFAAqF;IACrF,GAAG,CAAC,OAAO,GAAG,SAAS,CAAC;IAExB,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;IAC5E,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,KAAK,GAAG;QACZ,IAAI,EAAE,KAAK;QACX,SAAS,EAAE,CAAC;QACZ,WAAW,EAAE,KAAK;QAClB,CAAC,EAAE,CAAC;QACJ,CAAC,EAAE,CAAC;KACL,CAAC;IAEF,MAAM,MAAM,GAAG,CAAC,CAAS,EAAE,CAAS,EAAQ,EAAE;QAC5C,IAAI,KAAK,CAAC,IAAI;YAAE,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACrD,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QACvC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACrB,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC;IACpB,CAAC,CAAC;IACF,MAAM,MAAM,GAAG,CAAC,CAAS,EAAE,CAAS,EAAQ,EAAE;QAC5C,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QACvC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACvB,CAAC,CAAC;IACF,MAAM,OAAO,GAAG,CAAC,EAAU,EAAE,EAAU,EAAE,EAAU,EAAE,EAAU,EAAE,CAAS,EAAE,CAAS,EAAQ,EAAE;QAC7F,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC;QAC9C,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACzC,CAAC,CAAC;IAEF,uGAAuG;IACvG,oFAAoF;IACpF,MAAM,SAAS,GAAG,CAAC,QAAgB,EAAQ,EAAE;QAC3C,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;YACvB,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC;YACzB,IAAI,KAAK,CAAC,MAAM,GAAG,QAAQ;gBAAE,KAAK,CAAC,KAAK,EAAE,CAAC;QAC7C,CAAC;IACH,CAAC,CAAC;IACF,mGAAmG;IACnG,MAAM,iBAAiB,GAAG,CAAC,QAAgB,EAAQ,EAAE;QACnD,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;YACvB,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC;YACzB,IAAI,KAAK,CAAC,MAAM,GAAG,QAAQ,KAAK,CAAC;gBAAE,KAAK,CAAC,KAAK,EAAE,CAAC;QACnD,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,OAAO,GAAG,CAAC,KAAa,EAAE,GAAW,EAAE,KAAa,EAAW,EAAE;QACrE,IAAI,KAAK,GAAG,cAAc;YAAE,OAAO,KAAK,CAAC;QACzC,IAAI,MAAM,GAAG,KAAK,CAAC;QAEnB,OAAO,MAAM,GAAG,GAAG,EAAE,CAAC;YACpB,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YACjC,MAAM,IAAI,CAAC,CAAC;YAEZ,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;gBAC1B,MAAM,OAAO,GAAG,wBAAwB,CAAC,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;gBAChE,IAAI,OAAO,KAAK,IAAI;oBAAE,OAAO,KAAK,CAAC;gBACnC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;gBAC1B,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;gBACxB,SAAS;YACX,CAAC;YAED,QAAQ,EAAE,EAAE,CAAC;gBACX,KAAK,CAAC,CAAC;gBACP,KAAK,CAAC,CAAC;gBACP,KAAK,EAAE,CAAC;gBACR,KAAK,EAAE,CAAC,CAAC,CAAC;oBACR,gGAAgG;oBAChG,2DAA2D;oBAC3D,iBAAiB,CAAC,CAAC,CAAC,CAAC;oBACrB,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;oBACrC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;oBACjB,MAAM;gBACR,CAAC;gBACD,KAAK,EAAE,CAAC;gBACR,KAAK,EAAE,CAAC,CAAC,CAAC;oBACR,gFAAgF;oBAChF,iBAAiB,CAAC,CAAC,CAAC,CAAC;oBACrB,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;oBACrC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;oBACjB,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;oBACrC,IAAI,MAAM,GAAG,GAAG;wBAAE,OAAO,KAAK,CAAC;oBAC/B,MAAM;gBACR,CAAC;gBACD,KAAK,EAAE,CAAC,CAAC,CAAC;oBACR,SAAS,CAAC,CAAC,CAAC,CAAC;oBACb,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;oBACzB,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;oBACzB,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;oBACzB,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;oBACjB,MAAM;gBACR,CAAC;gBACD,KAAK,EAAE,CAAC,CAAC,CAAC;oBACR,SAAS,CAAC,CAAC,CAAC,CAAC;oBACb,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;oBACzB,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;oBACzB,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;oBACjB,MAAM;gBACR,CAAC;gBACD,KAAK,CAAC,CAAC,CAAC,CAAC;oBACP,SAAS,CAAC,CAAC,CAAC,CAAC;oBACb,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;oBACzB,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;oBACzB,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;oBACjB,MAAM;gBACR,CAAC;gBACD,KAAK,CAAC,CAAC,CAAC,CAAC;oBACP,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;wBACzD,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,KAAK,CAAE,CAAC;wBACzB,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,KAAK,GAAG,CAAC,CAAE,CAAC;wBAC7B,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;oBAC3B,CAAC;oBACD,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;oBACjB,MAAM;gBACR,CAAC;gBACD,KAAK,CAAC,CAAC;gBACP,KAAK,CAAC,CAAC,CAAC,CAAC;oBACP,qFAAqF;oBACrF,IAAI,UAAU,GAAG,EAAE,KAAK,CAAC,CAAC;oBAC1B,KAAK,MAAM,KAAK,IAAI,KAAK,EAAE,CAAC;wBAC1B,IAAI,UAAU;4BAAE,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC;;4BAC5B,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC;wBACtB,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;wBACzB,UAAU,GAAG,CAAC,UAAU,CAAC;oBAC3B,CAAC;oBACD,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;oBACjB,MAAM;gBACR,CAAC;gBACD,KAAK,CAAC,CAAC,CAAC,CAAC;oBACP,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC;wBAAE,iBAAiB,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;oBACtF,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;oBACjB,MAAM;gBACR,CAAC;gBACD,KAAK,EAAE,CAAC,CAAC,CAAC;oBACR,yCAAyC;oBACzC,IAAI,KAAK,GAAG,CAAC,CAAC;oBACd,OAAO,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC;wBAAE,iBAAiB,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;oBAC7E,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBAC7B,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;oBACjC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;oBACzB,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;oBACjB,MAAM;gBACR,CAAC;gBACD,KAAK,EAAE,CAAC,CAAC,CAAC;oBACR,yCAAyC;oBACzC,IAAI,KAAK,GAAG,CAAC,CAAC;oBACd,OAAO,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;wBAChD,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,KAAK,CAAE,CAAC;wBACzB,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,KAAK,GAAG,CAAC,CAAE,CAAC;wBAC7B,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;oBAC3B,CAAC;oBACD,iBAAiB,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;oBAC5B,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;oBACjB,MAAM;gBACR,CAAC;gBACD,KAAK,EAAE,CAAC;gBACR,KAAK,EAAE,CAAC,CAAC,CAAC;oBACR,+FAA+F;oBAC/F,mDAAmD;oBACnD,MAAM,QAAQ,GAAG,EAAE,KAAK,EAAE,CAAC;oBAC3B,IAAI,KAAK,GAAG,CAAC,CAAC;oBACd,IAAI,IAAI,GAAG,CAAC,CAAC;oBACb,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;wBAC3B,IAAI,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;wBACjB,KAAK,GAAG,CAAC,CAAC;oBACZ,CAAC;oBACD,OAAO,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;wBAC5C,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAE,CAAC,CAAC;wBACvD,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;wBACvD,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC,KAAK,GAAG,CAAC,CAAE,CAAC;wBAClC,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC,KAAK,GAAG,CAAC,CAAE,CAAC;wBAClC,KAAK,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAE,CAAC,CAAC;wBAClD,KAAK,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;wBAClD,OAAO,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;wBAC1C,IAAI,GAAG,CAAC,CAAC;oBACX,CAAC;oBACD,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;oBACjB,MAAM;gBACR,CAAC;gBACD,KAAK,EAAE,CAAC;gBACR,KAAK,EAAE,CAAC,CAAC,CAAC;oBACR,yFAAyF;oBACzF,8EAA8E;oBAC9E,IAAI,UAAU,GAAG,EAAE,KAAK,EAAE,CAAC;oBAC3B,IAAI,KAAK,GAAG,CAAC,CAAC;oBACd,OAAO,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;wBAChC,MAAM,IAAI,GAAG,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC;wBACtC,MAAM,KAAK,GAAG,IAAI,IAAI,KAAK,CAAC,MAAM,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,CAAC;wBACzE,IAAI,EAAU,CAAC;wBACf,IAAI,EAAU,CAAC;wBACf,IAAI,UAAU,EAAE,CAAC;4BACf,EAAE,GAAG,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAAE,CAAC;4BAC7B,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC;wBACf,CAAC;6BAAM,CAAC;4BACN,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC;4BACb,EAAE,GAAG,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAAE,CAAC;wBAC/B,CAAC;wBACD,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC,KAAK,GAAG,CAAC,CAAE,CAAC;wBAClC,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC,KAAK,GAAG,CAAC,CAAE,CAAC;wBAClC,IAAI,UAAU,EAAE,CAAC;4BACf,KAAK,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,KAAK,GAAG,CAAC,CAAE,CAAC;4BACjC,KAAK,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;wBACvB,CAAC;6BAAM,CAAC;4BACN,KAAK,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,KAAK,GAAG,CAAC,CAAE,CAAC;4BACjC,KAAK,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;wBACvB,CAAC;wBACD,OAAO,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;wBAC1C,UAAU,GAAG,CAAC,UAAU,CAAC;wBACzB,KAAK,IAAI,CAAC,CAAC;oBACb,CAAC;oBACD,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;oBACjB,MAAM;gBACR,CAAC;gBACD,KAAK,EAAE,CAAC;gBACR,KAAK,EAAE,CAAC,CAAC,CAAC;oBACR,MAAM,KAAK,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC;oBACnD,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,GAAG,iBAAiB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;oBACnE,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;oBAC1B,IAAI,IAAI,KAAK,SAAS;wBAAE,OAAO,KAAK,CAAC;oBACrC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,KAAK,GAAG,CAAC,CAAC;wBAAE,OAAO,KAAK,CAAC;oBAC5D,MAAM;gBACR,CAAC;gBACD,KAAK,EAAE;oBACL,OAAO,IAAI,CAAC;gBACd,KAAK,EAAE,CAAC,CAAC,CAAC;oBACR,SAAS,CAAC,CAAC,CAAC,CAAC;oBACb,IAAI,KAAK,CAAC,IAAI;wBAAE,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;oBACrD,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC;oBACnB,OAAO,IAAI,CAAC;gBACd,CAAC;gBACD,KAAK,EAAE,CAAC,CAAC,CAAC;oBACR,8FAA8F;oBAC9F,6FAA6F;oBAC7F,2CAA2C;oBAC3C,IAAI,MAAM,IAAI,GAAG;wBAAE,OAAO,KAAK,CAAC;oBAChC,MAAM,IAAI,CAAC,CAAC;oBACZ,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;oBACjB,MAAM;gBACR,CAAC;gBACD;oBACE,OAAO,KAAK,CAAC;YACjB,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;IAEF,kEAAkE;IAClE,SAAS,iBAAiB,CAAC,KAAa,EAAE,OAAe;QACvD,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAAE,CAAC;QACnC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,GAAG,CAAC,CAAE,CAAC;QACvC,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC,KAAK,GAAG,CAAC,CAAE,CAAC;QAClC,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC,KAAK,GAAG,CAAC,CAAE,CAAC;QAClC,KAAK,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,KAAK,GAAG,CAAC,CAAE,CAAC;QACjC,KAAK,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,KAAK,GAAG,CAAC,CAAE,CAAC;QACjC,OAAO,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAC5C,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,EAAE,UAAU,CAAC,GAAG,EAAE,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IAChE,6EAA6E;IAC7E,IAAI,KAAK,CAAC,IAAI;QAAE,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IACrD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,wGAAwG;AACxG,gGAAgG;AAChG,SAAS,wBAAwB,CAC/B,IAAwB,EACxB,EAAU,EACV,MAAc,EACd,GAAW;IAEX,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACd,IAAI,MAAM,GAAG,CAAC,GAAG,GAAG;YAAE,OAAO,IAAI,CAAC;QAClC,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;IAC9D,CAAC;IACD,IAAI,EAAE,IAAI,GAAG;QAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,GAAG,GAAG,EAAE,CAAC;IAClD,IAAI,EAAE,IAAI,GAAG,EAAE,CAAC;QACd,IAAI,MAAM,GAAG,CAAC,GAAG,GAAG;YAAE,OAAO,IAAI,CAAC;QAClC,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,GAAG,EAAE,CAAC;IACvF,CAAC;IACD,IAAI,EAAE,IAAI,GAAG,EAAE,CAAC;QACd,IAAI,MAAM,GAAG,CAAC,GAAG,GAAG;YAAE,OAAO,IAAI,CAAC;QAClC,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,GAAG,EAAE,CAAC;IACxF,CAAC;IACD,IAAI,MAAM,GAAG,CAAC,GAAG,GAAG;QAAE,OAAO,IAAI,CAAC;IAClC,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,KAAK,EAAE,CAAC;AACtE,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const CFF_OPERATOR_CHARSTRINGS = 17;
|
|
2
|
+
export declare const CFF_OPERATOR_PRIVATE = 18;
|
|
3
|
+
export declare const CFF_OPERATOR_SUBRS = 19;
|
|
4
|
+
export declare const CFF_OPERATOR_ROS = 1230;
|
|
5
|
+
export declare const CFF_OPERATOR_FD_ARRAY = 1236;
|
|
6
|
+
export declare const CFF_OPERATOR_FD_SELECT = 1237;
|
|
7
|
+
export declare function readCffDict(bytes: Readonly<Uint8Array>, start: number, end: number): Map<number, number[]> | null;
|
|
8
|
+
//# sourceMappingURL=cffDict.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cffDict.d.ts","sourceRoot":"","sources":["../src/cffDict.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAE3C,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAEvC,eAAO,MAAM,kBAAkB,KAAK,CAAC;AAIrC,eAAO,MAAM,gBAAgB,OAAO,CAAC;AACrC,eAAO,MAAM,qBAAqB,OAAO,CAAC;AAC1C,eAAO,MAAM,sBAAsB,OAAO,CAAC;AAI3C,wBAAgB,WAAW,CAAC,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,IAAI,CAoDjH"}
|
package/dist/cffDict.js
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
// The CFF DICT: operands first, then the operator that consumes them.
|
|
2
|
+
//
|
|
3
|
+
// It is the reverse of most bytecode and that inversion is the whole reading rule — values accumulate
|
|
4
|
+
// until an operator byte arrives, which claims everything gathered so far. Operators are one byte, except
|
|
5
|
+
// that byte 12 introduces a second byte, so escaped operators are keyed here as `1200 + second`.
|
|
6
|
+
//
|
|
7
|
+
// Only the operators this package needs are named; the rest are read and kept as raw entries, because a
|
|
8
|
+
// DICT must be traversed completely to find the operators that matter and skipping an unknown one by
|
|
9
|
+
// guesswork would desynchronise everything after it.
|
|
10
|
+
//
|
|
11
|
+
// The encodings below are interface facts about the format. The reader is Flight's own.
|
|
12
|
+
// Top DICT: where the charstrings live, and where the private DICT is.
|
|
13
|
+
export const CFF_OPERATOR_CHARSTRINGS = 17;
|
|
14
|
+
// Two operands: the private DICT's size, then its offset from the start of the table.
|
|
15
|
+
export const CFF_OPERATOR_PRIVATE = 18;
|
|
16
|
+
// Private DICT: local subroutines, offset from the start of the private DICT itself.
|
|
17
|
+
export const CFF_OPERATOR_SUBRS = 19;
|
|
18
|
+
// Top DICT: present only on CID-keyed fonts, whose charstrings are reached through an FDSelect/FDArray
|
|
19
|
+
// indirection this package does not read. Its presence is what makes such a font detectable rather than
|
|
20
|
+
// silently mis-parsed.
|
|
21
|
+
export const CFF_OPERATOR_ROS = 1230;
|
|
22
|
+
export const CFF_OPERATOR_FD_ARRAY = 1236;
|
|
23
|
+
export const CFF_OPERATOR_FD_SELECT = 1237;
|
|
24
|
+
// Operator key → the operands that preceded it. Returns the null sentinel when the byte stream ends
|
|
25
|
+
// mid-number or holds a reserved value, since either means the offsets read from it would be arbitrary.
|
|
26
|
+
export function readCffDict(bytes, start, end) {
|
|
27
|
+
const dict = new Map();
|
|
28
|
+
const operands = [];
|
|
29
|
+
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
30
|
+
let cursor = start;
|
|
31
|
+
while (cursor < end) {
|
|
32
|
+
const b0 = view.getUint8(cursor);
|
|
33
|
+
if (b0 <= 21) {
|
|
34
|
+
cursor += 1;
|
|
35
|
+
let key = b0;
|
|
36
|
+
if (b0 === 12) {
|
|
37
|
+
if (cursor >= end)
|
|
38
|
+
return null;
|
|
39
|
+
key = 1200 + view.getUint8(cursor);
|
|
40
|
+
cursor += 1;
|
|
41
|
+
}
|
|
42
|
+
dict.set(key, operands.splice(0, operands.length));
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
// 28 and 29 are sized integers; 30 is a real number in packed nibbles; 32-254 encode small integers
|
|
46
|
+
// directly. 22-27 and 31 are reserved and their presence means this is not a DICT.
|
|
47
|
+
if (b0 === 28) {
|
|
48
|
+
if (cursor + 3 > end)
|
|
49
|
+
return null;
|
|
50
|
+
operands.push(view.getInt16(cursor + 1));
|
|
51
|
+
cursor += 3;
|
|
52
|
+
}
|
|
53
|
+
else if (b0 === 29) {
|
|
54
|
+
if (cursor + 5 > end)
|
|
55
|
+
return null;
|
|
56
|
+
operands.push(view.getInt32(cursor + 1));
|
|
57
|
+
cursor += 5;
|
|
58
|
+
}
|
|
59
|
+
else if (b0 === 30) {
|
|
60
|
+
const real = readCffRealOperand(view, cursor + 1, end);
|
|
61
|
+
if (real === null)
|
|
62
|
+
return null;
|
|
63
|
+
operands.push(real.value);
|
|
64
|
+
cursor = real.cursor;
|
|
65
|
+
}
|
|
66
|
+
else if (b0 >= 32 && b0 <= 246) {
|
|
67
|
+
operands.push(b0 - 139);
|
|
68
|
+
cursor += 1;
|
|
69
|
+
}
|
|
70
|
+
else if (b0 >= 247 && b0 <= 250) {
|
|
71
|
+
if (cursor + 2 > end)
|
|
72
|
+
return null;
|
|
73
|
+
operands.push((b0 - 247) * 256 + view.getUint8(cursor + 1) + 108);
|
|
74
|
+
cursor += 2;
|
|
75
|
+
}
|
|
76
|
+
else if (b0 >= 251 && b0 <= 254) {
|
|
77
|
+
if (cursor + 2 > end)
|
|
78
|
+
return null;
|
|
79
|
+
operands.push(-(b0 - 251) * 256 - view.getUint8(cursor + 1) - 108);
|
|
80
|
+
cursor += 2;
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return dict;
|
|
87
|
+
}
|
|
88
|
+
// Real numbers are packed two nibbles per byte, each nibble a digit or one of a few markers, terminated
|
|
89
|
+
// by 0xf. Parsed into a string and converted once rather than accumulated arithmetically, because the
|
|
90
|
+
// exponent marker can appear before the digits it applies to.
|
|
91
|
+
function readCffRealOperand(view, start, end) {
|
|
92
|
+
let text = '';
|
|
93
|
+
let cursor = start;
|
|
94
|
+
for (;;) {
|
|
95
|
+
if (cursor >= end)
|
|
96
|
+
return null;
|
|
97
|
+
const byte = view.getUint8(cursor);
|
|
98
|
+
cursor += 1;
|
|
99
|
+
for (const nibble of [byte >> 4, byte & 0x0f]) {
|
|
100
|
+
if (nibble <= 9)
|
|
101
|
+
text += String(nibble);
|
|
102
|
+
else if (nibble === 0x0a)
|
|
103
|
+
text += '.';
|
|
104
|
+
else if (nibble === 0x0b)
|
|
105
|
+
text += 'E';
|
|
106
|
+
else if (nibble === 0x0c)
|
|
107
|
+
text += 'E-';
|
|
108
|
+
else if (nibble === 0x0e)
|
|
109
|
+
text += '-';
|
|
110
|
+
else if (nibble === 0x0f) {
|
|
111
|
+
const value = Number(text);
|
|
112
|
+
return Number.isFinite(value) ? { cursor, value } : null;
|
|
113
|
+
}
|
|
114
|
+
// 0x0d is reserved and carries no digit; skipping it keeps the nibble stream aligned.
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=cffDict.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cffDict.js","sourceRoot":"","sources":["../src/cffDict.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,EAAE;AACF,sGAAsG;AACtG,0GAA0G;AAC1G,iGAAiG;AACjG,EAAE;AACF,wGAAwG;AACxG,qGAAqG;AACrG,qDAAqD;AACrD,EAAE;AACF,wFAAwF;AAExF,uEAAuE;AACvE,MAAM,CAAC,MAAM,wBAAwB,GAAG,EAAE,CAAC;AAC3C,sFAAsF;AACtF,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,CAAC;AACvC,qFAAqF;AACrF,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,CAAC;AACrC,uGAAuG;AACvG,wGAAwG;AACxG,uBAAuB;AACvB,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAC;AACrC,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,CAAC;AAC1C,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,CAAC;AAE3C,oGAAoG;AACpG,wGAAwG;AACxG,MAAM,UAAU,WAAW,CAAC,KAA2B,EAAE,KAAa,EAAE,GAAW;IACjF,MAAM,IAAI,GAAG,IAAI,GAAG,EAAoB,CAAC;IACzC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;IAC5E,IAAI,MAAM,GAAG,KAAK,CAAC;IAEnB,OAAO,MAAM,GAAG,GAAG,EAAE,CAAC;QACpB,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAEjC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC;YACb,MAAM,IAAI,CAAC,CAAC;YACZ,IAAI,GAAG,GAAG,EAAE,CAAC;YACb,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;gBACd,IAAI,MAAM,IAAI,GAAG;oBAAE,OAAO,IAAI,CAAC;gBAC/B,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;gBACnC,MAAM,IAAI,CAAC,CAAC;YACd,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;YACnD,SAAS;QACX,CAAC;QAED,oGAAoG;QACpG,mFAAmF;QACnF,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACd,IAAI,MAAM,GAAG,CAAC,GAAG,GAAG;gBAAE,OAAO,IAAI,CAAC;YAClC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;YACzC,MAAM,IAAI,CAAC,CAAC;QACd,CAAC;aAAM,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACrB,IAAI,MAAM,GAAG,CAAC,GAAG,GAAG;gBAAE,OAAO,IAAI,CAAC;YAClC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;YACzC,MAAM,IAAI,CAAC,CAAC;QACd,CAAC;aAAM,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACrB,MAAM,IAAI,GAAG,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;YACvD,IAAI,IAAI,KAAK,IAAI;gBAAE,OAAO,IAAI,CAAC;YAC/B,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC1B,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QACvB,CAAC;aAAM,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,GAAG,EAAE,CAAC;YACjC,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC;YACxB,MAAM,IAAI,CAAC,CAAC;QACd,CAAC;aAAM,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,IAAI,GAAG,EAAE,CAAC;YAClC,IAAI,MAAM,GAAG,CAAC,GAAG,GAAG;gBAAE,OAAO,IAAI,CAAC;YAClC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;YAClE,MAAM,IAAI,CAAC,CAAC;QACd,CAAC;aAAM,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,IAAI,GAAG,EAAE,CAAC;YAClC,IAAI,MAAM,GAAG,CAAC,GAAG,GAAG;gBAAE,OAAO,IAAI,CAAC;YAClC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;YACnE,MAAM,IAAI,CAAC,CAAC;QACd,CAAC;aAAM,CAAC;YACN,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,wGAAwG;AACxG,sGAAsG;AACtG,8DAA8D;AAC9D,SAAS,kBAAkB,CACzB,IAAwB,EACxB,KAAa,EACb,GAAW;IAEX,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,SAAS,CAAC;QACR,IAAI,MAAM,IAAI,GAAG;YAAE,OAAO,IAAI,CAAC;QAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACnC,MAAM,IAAI,CAAC,CAAC;QACZ,KAAK,MAAM,MAAM,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC;YAC9C,IAAI,MAAM,IAAI,CAAC;gBAAE,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC;iBACnC,IAAI,MAAM,KAAK,IAAI;gBAAE,IAAI,IAAI,GAAG,CAAC;iBACjC,IAAI,MAAM,KAAK,IAAI;gBAAE,IAAI,IAAI,GAAG,CAAC;iBACjC,IAAI,MAAM,KAAK,IAAI;gBAAE,IAAI,IAAI,IAAI,CAAC;iBAClC,IAAI,MAAM,KAAK,IAAI;gBAAE,IAAI,IAAI,GAAG,CAAC;iBACjC,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;gBACzB,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;gBAC3B,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;YAC3D,CAAC;YACD,sFAAsF;QACxF,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cffFdSelect.d.ts","sourceRoot":"","sources":["../src/cffFdSelect.ts"],"names":[],"mappings":"AAqBA,wBAAgB,eAAe,CAAC,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAmClH"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// FDSelect: which font DICT each glyph belongs to.
|
|
2
|
+
//
|
|
3
|
+
// A CID-keyed font is several fonts in one table. Rather than a single Private DICT, it carries an
|
|
4
|
+
// FDArray of font DICTs, each with its own Private DICT and therefore ITS OWN LOCAL SUBROUTINE POOL.
|
|
5
|
+
// FDSelect is the map from glyph index to which of those a glyph uses.
|
|
6
|
+
//
|
|
7
|
+
// ★ WHY THIS EXISTS AT ALL, WHICH IS THE WHOLE REASON CID FONTS WERE REFUSED UNTIL NOW: binding every
|
|
8
|
+
// glyph to one pool is not a partial implementation, it is a WRONG one. The subroutine index is biased
|
|
9
|
+
// by pool size, so an index valid in one pool selects a different, real entry in another — and a real
|
|
10
|
+
// entry draws something. The failure is per-glyph plausible geometry rather than an error.
|
|
11
|
+
//
|
|
12
|
+
// Two encodings exist and both are read: format 0 is one byte per glyph, format 3 is ranges. The layouts
|
|
13
|
+
// are interface facts about the format; the lookup below is Flight's own.
|
|
14
|
+
// Returns a dense glyph-index → FD-index array, so the per-glyph lookup in the outline path is a single
|
|
15
|
+
// indexed read rather than a range search. Ranges are expanded once here for the same reason the cmap is:
|
|
16
|
+
// the alternative pays a search on every glyph, inside text layout.
|
|
17
|
+
//
|
|
18
|
+
// Returns the null sentinel for a malformed table rather than a partial map. A partially-read FDSelect
|
|
19
|
+
// would silently bind the unmapped tail of the glyph range to FD 0 — which is exactly the wrong-pool
|
|
20
|
+
// outcome this whole module exists to prevent.
|
|
21
|
+
export function readCffFdSelect(bytes, offset, glyphCount) {
|
|
22
|
+
if (offset + 1 > bytes.byteLength)
|
|
23
|
+
return null;
|
|
24
|
+
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
25
|
+
const format = view.getUint8(offset);
|
|
26
|
+
if (format === 0) {
|
|
27
|
+
if (offset + 1 + glyphCount > bytes.byteLength)
|
|
28
|
+
return null;
|
|
29
|
+
const select = new Uint8Array(glyphCount);
|
|
30
|
+
for (let glyph = 0; glyph < glyphCount; glyph += 1)
|
|
31
|
+
select[glyph] = view.getUint8(offset + 1 + glyph);
|
|
32
|
+
return select;
|
|
33
|
+
}
|
|
34
|
+
if (format !== 3)
|
|
35
|
+
return null;
|
|
36
|
+
if (offset + 5 > bytes.byteLength)
|
|
37
|
+
return null;
|
|
38
|
+
const rangeCount = view.getUint16(offset + 1);
|
|
39
|
+
// Each range is a 3-byte record, and a trailing sentinel gives the end of the final range.
|
|
40
|
+
const sentinelAt = offset + 3 + rangeCount * 3;
|
|
41
|
+
if (sentinelAt + 2 > bytes.byteLength)
|
|
42
|
+
return null;
|
|
43
|
+
const select = new Uint8Array(glyphCount);
|
|
44
|
+
let covered = 0;
|
|
45
|
+
for (let range = 0; range < rangeCount; range += 1) {
|
|
46
|
+
const first = view.getUint16(offset + 3 + range * 3);
|
|
47
|
+
const fd = view.getUint8(offset + 5 + range * 3);
|
|
48
|
+
// The next range's first glyph is this one's end; the last is bounded by the trailing sentinel.
|
|
49
|
+
const next = range + 1 < rangeCount ? view.getUint16(offset + 3 + (range + 1) * 3) : view.getUint16(sentinelAt);
|
|
50
|
+
if (next < first || next > glyphCount)
|
|
51
|
+
return null;
|
|
52
|
+
for (let glyph = first; glyph < next; glyph += 1)
|
|
53
|
+
select[glyph] = fd;
|
|
54
|
+
covered = Math.max(covered, next);
|
|
55
|
+
}
|
|
56
|
+
// A range set that does not reach the end of the glyph range leaves a tail bound to FD 0 by default,
|
|
57
|
+
// which is the silent wrong-pool case. Refused rather than accepted with a plausible-looking map.
|
|
58
|
+
return covered === glyphCount ? select : null;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=cffFdSelect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cffFdSelect.js","sourceRoot":"","sources":["../src/cffFdSelect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cffIndex.d.ts","sourceRoot":"","sources":["../src/cffIndex.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAiB,MAAM,0BAA0B,CAAC;AAgBxE,wBAAgB,YAAY,CAAC,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAsCzF"}
|
package/dist/cffIndex.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// The CFF INDEX: the container every other CFF structure is stored in.
|
|
2
|
+
//
|
|
3
|
+
// An INDEX is a count, an offset width, `count + 1` offsets, and then the data those offsets carve up.
|
|
4
|
+
// Offsets are 1-based from the byte before the data block, which is the one detail that makes an
|
|
5
|
+
// off-by-one here silent rather than loud — it yields a shifted-but-plausible entry rather than a crash.
|
|
6
|
+
//
|
|
7
|
+
// Layout is an interface fact about the format. The reading is Flight's own.
|
|
8
|
+
//
|
|
9
|
+
// A CFF table holds five of these in a fixed order (name, top DICT, string, global subroutines) plus
|
|
10
|
+
// two reached by offset (charstrings, local subroutines), so this is the primitive the rest composes on.
|
|
11
|
+
// Reads one INDEX at `offset`. Returns the null sentinel for a structurally impossible one rather than a
|
|
12
|
+
// partial read: a truncated INDEX yields entry ranges that point at arbitrary bytes, and every consumer
|
|
13
|
+
// downstream would interpret those as real charstrings or DICTs.
|
|
14
|
+
export function readCffIndex(bytes, offset) {
|
|
15
|
+
if (offset + 2 > bytes.byteLength)
|
|
16
|
+
return null;
|
|
17
|
+
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
18
|
+
const count = view.getUint16(offset);
|
|
19
|
+
// A count of zero is a legitimate empty INDEX and occupies exactly its two-byte count. Fonts with no
|
|
20
|
+
// local subroutines rely on this, so it is a normal answer rather than an edge case.
|
|
21
|
+
if (count === 0)
|
|
22
|
+
return { endOffset: offset + 2, entries: [] };
|
|
23
|
+
const offSize = view.getUint8(offset + 2);
|
|
24
|
+
if (offSize < 1 || offSize > 4)
|
|
25
|
+
return null;
|
|
26
|
+
const offsetsAt = offset + 3;
|
|
27
|
+
const dataAt = offsetsAt + (count + 1) * offSize - 1;
|
|
28
|
+
if (dataAt >= bytes.byteLength)
|
|
29
|
+
return null;
|
|
30
|
+
const readOffset = (index) => {
|
|
31
|
+
let value = 0;
|
|
32
|
+
for (let byte = 0; byte < offSize; byte += 1)
|
|
33
|
+
value = value * 256 + view.getUint8(offsetsAt + index * offSize + byte);
|
|
34
|
+
return value;
|
|
35
|
+
};
|
|
36
|
+
const entries = [];
|
|
37
|
+
let previous = readOffset(0);
|
|
38
|
+
// The first offset is 1 by definition; anything else means the offsets are not what this INDEX claims.
|
|
39
|
+
if (previous !== 1)
|
|
40
|
+
return null;
|
|
41
|
+
for (let index = 0; index < count; index += 1) {
|
|
42
|
+
const next = readOffset(index + 1);
|
|
43
|
+
// Offsets must not run backwards, and the last must stay inside the buffer. Both conditions are the
|
|
44
|
+
// difference between a truncated file and one that merely holds an empty entry, which is legal.
|
|
45
|
+
if (next < previous || dataAt + next > bytes.byteLength)
|
|
46
|
+
return null;
|
|
47
|
+
entries.push({ end: dataAt + next, start: dataAt + previous });
|
|
48
|
+
previous = next;
|
|
49
|
+
}
|
|
50
|
+
return { endOffset: dataAt + previous, entries };
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=cffIndex.js.map
|