pdf-parser.js 5.2.26 → 5.2.28
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/{afm-widths-BYiX2L9D.cjs → afm-widths-BHD2HZIL.cjs} +553 -642
- package/dist/{afm-widths-blUDDjlI.js → afm-widths-B_IGbGky.js} +553 -642
- package/dist/afm-widths.cjs +1 -1
- package/dist/afm-widths.js +1 -1
- package/dist/annotations.cjs +5 -3
- package/dist/annotations.d.cts +2 -2
- package/dist/annotations.d.ts +2 -2
- package/dist/annotations.js +5 -3
- package/dist/attachments.d.cts +2 -2
- package/dist/attachments.d.ts +2 -2
- package/dist/builtin-encoding.cjs +17 -6
- package/dist/builtin-encoding.js +17 -6
- package/dist/bytes/crc32.cjs +5 -3
- package/dist/bytes/crc32.js +5 -3
- package/dist/bytes/flate.cjs +0 -1
- package/dist/bytes/flate.js +0 -1
- package/dist/cff-bounds.cjs +73 -45
- package/dist/cff-bounds.js +73 -45
- package/dist/cff.cjs +13 -6
- package/dist/cff.js +13 -6
- package/dist/cmap-table.cjs +54 -26
- package/dist/cmap-table.js +54 -26
- package/dist/cmap.cjs +5 -3
- package/dist/cmap.js +5 -3
- package/dist/content-read.d.cts +1 -1
- package/dist/content-read.d.ts +1 -1
- package/dist/content-write.cjs +21 -14
- package/dist/content-write.d.cts +2 -2
- package/dist/content-write.d.ts +2 -2
- package/dist/content-write.js +21 -14
- package/dist/crypto/aes.cjs +76 -55
- package/dist/crypto/aes.js +76 -55
- package/dist/crypto/md5.cjs +345 -149
- package/dist/crypto/md5.js +345 -149
- package/dist/crypto/rc4.cjs +5 -4
- package/dist/crypto/rc4.js +5 -4
- package/dist/crypto/sha2.cjs +92 -43
- package/dist/crypto/sha2.js +92 -43
- package/dist/document.cjs +17 -11
- package/dist/document.d.cts +1 -1
- package/dist/document.d.ts +1 -1
- package/dist/document.js +17 -11
- package/dist/{embedded-font-Bnhh4juV.d.ts → embedded-font-ByD7ZiQS.d.ts} +1 -1
- package/dist/{embedded-font-CEf-zBCA.d.cts → embedded-font-DgVBedw6.d.cts} +1 -1
- package/dist/embedded-font-write.d.cts +2 -2
- package/dist/embedded-font-write.d.ts +2 -2
- package/dist/embedded-font.cjs +4 -2
- package/dist/embedded-font.d.cts +1 -1
- package/dist/embedded-font.d.ts +1 -1
- package/dist/embedded-font.js +4 -2
- package/dist/encoding.cjs +1 -1
- package/dist/encoding.js +1 -1
- package/dist/encrypt-write.cjs +25 -21
- package/dist/encrypt-write.d.cts +1 -1
- package/dist/encrypt-write.d.ts +1 -1
- package/dist/encrypt-write.js +25 -21
- package/dist/encrypt.cjs +43 -64
- package/dist/encrypt.d.cts +1 -1
- package/dist/encrypt.d.ts +1 -1
- package/dist/encrypt.js +43 -64
- package/dist/filters.cjs +46 -26
- package/dist/filters.d.cts +1 -1
- package/dist/filters.d.ts +1 -1
- package/dist/filters.js +46 -26
- package/dist/font-face.cjs +2 -1
- package/dist/font-face.js +2 -1
- package/dist/font-read.cjs +12 -6
- package/dist/font-read.d.cts +1 -1
- package/dist/font-read.d.ts +1 -1
- package/dist/font-read.js +12 -6
- package/dist/font-registry.d.cts +3 -3
- package/dist/font-registry.d.ts +3 -3
- package/dist/font-tables.cjs +55 -28
- package/dist/font-tables.js +55 -28
- package/dist/form.cjs +13 -8
- package/dist/form.d.cts +2 -2
- package/dist/form.d.ts +2 -2
- package/dist/form.js +13 -8
- package/dist/gdef-table.cjs +6 -3
- package/dist/gdef-table.js +6 -3
- package/dist/{glyf-contours-C0epBNqP.d.ts → glyf-contours-B1PsI9oA.d.ts} +1 -1
- package/dist/{glyf-contours-BRpvd0rt.d.cts → glyf-contours-NHBpgks-.d.cts} +1 -1
- package/dist/glyf-contours.cjs +3 -1
- package/dist/glyf-contours.d.cts +1 -1
- package/dist/glyf-contours.d.ts +1 -1
- package/dist/glyf-contours.js +3 -1
- package/dist/glyf.cjs +22 -11
- package/dist/glyf.js +22 -11
- package/dist/gpos-table.cjs +37 -19
- package/dist/gpos-table.js +37 -19
- package/dist/gsub-table.cjs +40 -25
- package/dist/gsub-table.js +40 -25
- package/dist/hmtx-table.cjs +5 -3
- package/dist/hmtx-table.js +5 -3
- package/dist/image/ccitt-encode.cjs +8 -5
- package/dist/image/ccitt-encode.js +8 -5
- package/dist/image/ccitt.cjs +801 -209
- package/dist/image/ccitt.js +801 -209
- package/dist/image/jbig2-arith.cjs +340 -306
- package/dist/image/jbig2-arith.js +340 -306
- package/dist/image/jbig2-bitmap.cjs +8 -5
- package/dist/image/jbig2-bitmap.js +8 -5
- package/dist/image/jbig2-generic.cjs +240 -69
- package/dist/image/jbig2-generic.js +240 -69
- package/dist/image/jbig2-text.cjs +4 -2
- package/dist/image/jbig2-text.js +4 -2
- package/dist/image/jbig2.cjs +69 -31
- package/dist/image/jbig2.js +69 -31
- package/dist/image/jp2-boxes.cjs +52 -27
- package/dist/image/jp2-boxes.js +52 -27
- package/dist/image/jpeg-info.cjs +29 -24
- package/dist/image/jpeg-info.js +29 -24
- package/dist/image/jpeg2000-codestream.cjs +61 -32
- package/dist/image/jpeg2000-codestream.js +61 -32
- package/dist/image/jpeg2000-dwt.cjs +2 -1
- package/dist/image/jpeg2000-dwt.js +2 -1
- package/dist/image/jpeg2000-t1.cjs +21 -11
- package/dist/image/jpeg2000-t1.js +21 -11
- package/dist/image/jpeg2000-t2.cjs +12 -5
- package/dist/image/jpeg2000-t2.js +12 -5
- package/dist/image/jpeg2000-tagtree.cjs +8 -4
- package/dist/image/jpeg2000-tagtree.js +8 -4
- package/dist/image/jpeg2000.cjs +11 -6
- package/dist/image/jpeg2000.js +11 -6
- package/dist/image/png-decode.cjs +62 -39
- package/dist/image/png-decode.d.cts +3 -2
- package/dist/image/png-decode.d.ts +3 -2
- package/dist/image/png-decode.js +62 -39
- package/dist/image/png-filter.cjs +23 -15
- package/dist/image/png-filter.js +23 -15
- package/dist/images-read.cjs +41 -36
- package/dist/images-read.d.cts +2 -2
- package/dist/images-read.d.ts +2 -2
- package/dist/images-read.js +41 -36
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/interpret.cjs +68 -40
- package/dist/interpret.d.cts +1 -1
- package/dist/interpret.d.ts +1 -1
- package/dist/interpret.js +68 -40
- package/dist/lexer.cjs +86 -51
- package/dist/lexer.js +86 -51
- package/dist/math-content-write.cjs +9 -5
- package/dist/math-content-write.js +9 -5
- package/dist/math-font-write.cjs +2 -1
- package/dist/math-font-write.d.cts +1 -1
- package/dist/math-font-write.d.ts +1 -1
- package/dist/math-font-write.js +2 -1
- package/dist/math-font.cjs +16 -7
- package/dist/math-font.js +16 -7
- package/dist/math-table.cjs +25 -13
- package/dist/math-table.js +25 -13
- package/dist/matrix.cjs +3 -2
- package/dist/matrix.js +3 -2
- package/dist/measure.cjs +1 -1
- package/dist/measure.js +1 -1
- package/dist/names.cjs +7 -7
- package/dist/names.d.cts +2 -2
- package/dist/names.d.ts +2 -2
- package/dist/names.js +7 -7
- package/dist/navigation.cjs +16 -12
- package/dist/navigation.d.cts +4 -4
- package/dist/navigation.d.ts +4 -4
- package/dist/navigation.js +16 -12
- package/dist/{objects-B7HdMeWS.d.cts → objects-e2RS3-yT.d.cts} +3 -3
- package/dist/{objects-B7HdMeWS.d.ts → objects-e2RS3-yT.d.ts} +3 -3
- package/dist/objects.d.cts +1 -1
- package/dist/objects.d.ts +1 -1
- package/dist/optional-content.d.cts +2 -2
- package/dist/optional-content.d.ts +2 -2
- package/dist/ot-layout-common.cjs +22 -15
- package/dist/ot-layout-common.js +22 -15
- package/dist/parse.cjs +7 -5
- package/dist/parse.d.cts +1 -1
- package/dist/parse.d.ts +1 -1
- package/dist/parse.js +7 -5
- package/dist/pdf-text.cjs +5 -2
- package/dist/pdf-text.js +5 -2
- package/dist/predictors.cjs +14 -9
- package/dist/predictors.d.cts +1 -1
- package/dist/predictors.d.ts +1 -1
- package/dist/predictors.js +14 -9
- package/dist/raster.cjs +30 -19
- package/dist/raster.d.cts +8 -8
- package/dist/raster.d.ts +8 -8
- package/dist/raster.js +30 -19
- package/dist/read.cjs +29 -16
- package/dist/read.js +29 -16
- package/dist/serialize.cjs +6 -2
- package/dist/serialize.d.cts +1 -1
- package/dist/serialize.d.ts +1 -1
- package/dist/serialize.js +6 -2
- package/dist/sfnt-subset.cjs +25 -13
- package/dist/sfnt-subset.d.cts +1 -1
- package/dist/sfnt-subset.d.ts +1 -1
- package/dist/sfnt-subset.js +25 -13
- package/dist/sfnt.cjs +20 -10
- package/dist/sfnt.js +20 -10
- package/dist/structure.d.cts +2 -2
- package/dist/structure.d.ts +2 -2
- package/dist/text-group.cjs +0 -1
- package/dist/text-group.js +0 -1
- package/dist/text-layout.d.cts +1 -1
- package/dist/text-layout.d.ts +1 -1
- package/dist/tounicode.cjs +4 -2
- package/dist/tounicode.d.cts +1 -1
- package/dist/tounicode.d.ts +1 -1
- package/dist/tounicode.js +4 -2
- package/dist/winansi.cjs +1 -1
- package/dist/winansi.js +1 -1
- package/dist/write.cjs +20 -12
- package/dist/write.d.cts +1 -1
- package/dist/write.d.ts +1 -1
- package/dist/write.js +20 -12
- package/dist/xref.cjs +5 -2
- package/dist/xref.d.cts +1 -1
- package/dist/xref.d.ts +1 -1
- package/dist/xref.js +5 -2
- package/package.json +1 -1
package/dist/glyf.cjs
CHANGED
|
@@ -16,6 +16,9 @@ function parseLoca(font, options) {
|
|
|
16
16
|
return offsets;
|
|
17
17
|
}
|
|
18
18
|
const GLYPH_HEADER_SIZE = 10;
|
|
19
|
+
const GLYPH_HEADER_Y_MIN_OFFSET = 4;
|
|
20
|
+
const GLYPH_HEADER_X_MAX_OFFSET = 6;
|
|
21
|
+
const GLYPH_HEADER_Y_MAX_OFFSET = 8;
|
|
19
22
|
const ARG_1_AND_2_ARE_WORDS = 1;
|
|
20
23
|
const ARGS_ARE_XY_VALUES = 2;
|
|
21
24
|
const WE_HAVE_A_SCALE = 8;
|
|
@@ -26,8 +29,16 @@ const SCALED_COMPONENT_OFFSET = 2048;
|
|
|
26
29
|
const UNSCALED_COMPONENT_OFFSET = 4096;
|
|
27
30
|
const MAX_COMPOSITE_DEPTH = 5;
|
|
28
31
|
const COMPONENT_RECORD_HEADER_SIZE = 4;
|
|
32
|
+
const X_AND_Y_SCALE_SIZE = 4;
|
|
33
|
+
const TWO_BY_TWO_SCALE10_OFFSET = 4;
|
|
34
|
+
const TWO_BY_TWO_Y_SCALE_OFFSET = 6;
|
|
35
|
+
const TWO_BY_TWO_SIZE = 8;
|
|
36
|
+
const WORD_ARGS_SIZE = 4;
|
|
37
|
+
const BYTE_ARGS_SIZE = 2;
|
|
38
|
+
const SIGNED_BYTE_SIGN_THRESHOLD = 128;
|
|
39
|
+
const SIGNED_BYTE_MODULUS = 256;
|
|
29
40
|
function signedByte(value) {
|
|
30
|
-
return value >=
|
|
41
|
+
return value >= SIGNED_BYTE_SIGN_THRESHOLD ? value - SIGNED_BYTE_MODULUS : value;
|
|
31
42
|
}
|
|
32
43
|
function readComponents(glyph) {
|
|
33
44
|
const components = [];
|
|
@@ -39,7 +50,7 @@ function readComponents(glyph) {
|
|
|
39
50
|
offset += COMPONENT_RECORD_HEADER_SIZE;
|
|
40
51
|
const argsAreWords = (flags & ARG_1_AND_2_ARE_WORDS) !== 0;
|
|
41
52
|
const argsAreXyValues = (flags & ARGS_ARE_XY_VALUES) !== 0;
|
|
42
|
-
const argsSize = argsAreWords ?
|
|
53
|
+
const argsSize = argsAreWords ? WORD_ARGS_SIZE : BYTE_ARGS_SIZE;
|
|
43
54
|
if (!require_sfnt.hasBytes(glyph, offset, argsSize)) return;
|
|
44
55
|
let argument1;
|
|
45
56
|
let argument2;
|
|
@@ -63,23 +74,23 @@ function readComponents(glyph) {
|
|
|
63
74
|
];
|
|
64
75
|
offset += 2;
|
|
65
76
|
} else if ((flags & WE_HAVE_AN_X_AND_Y_SCALE) !== 0) {
|
|
66
|
-
if (!require_sfnt.hasBytes(glyph, offset,
|
|
77
|
+
if (!require_sfnt.hasBytes(glyph, offset, X_AND_Y_SCALE_SIZE)) return;
|
|
67
78
|
transform = [
|
|
68
79
|
require_sfnt.f2dot14(glyph, offset),
|
|
69
80
|
0,
|
|
70
81
|
0,
|
|
71
82
|
require_sfnt.f2dot14(glyph, offset + 2)
|
|
72
83
|
];
|
|
73
|
-
offset +=
|
|
84
|
+
offset += X_AND_Y_SCALE_SIZE;
|
|
74
85
|
} else if ((flags & WE_HAVE_A_TWO_BY_TWO) !== 0) {
|
|
75
|
-
if (!require_sfnt.hasBytes(glyph, offset,
|
|
86
|
+
if (!require_sfnt.hasBytes(glyph, offset, TWO_BY_TWO_SIZE)) return;
|
|
76
87
|
transform = [
|
|
77
88
|
require_sfnt.f2dot14(glyph, offset),
|
|
78
89
|
require_sfnt.f2dot14(glyph, offset + 2),
|
|
79
|
-
require_sfnt.f2dot14(glyph, offset +
|
|
80
|
-
require_sfnt.f2dot14(glyph, offset +
|
|
90
|
+
require_sfnt.f2dot14(glyph, offset + TWO_BY_TWO_SCALE10_OFFSET),
|
|
91
|
+
require_sfnt.f2dot14(glyph, offset + TWO_BY_TWO_Y_SCALE_OFFSET)
|
|
81
92
|
];
|
|
82
|
-
offset +=
|
|
93
|
+
offset += TWO_BY_TWO_SIZE;
|
|
83
94
|
}
|
|
84
95
|
components.push({
|
|
85
96
|
flags,
|
|
@@ -134,9 +145,9 @@ function parseGlyf(font, options) {
|
|
|
134
145
|
return {
|
|
135
146
|
numberOfContours: require_sfnt.i16(glyph, 0),
|
|
136
147
|
xMin: require_sfnt.i16(glyph, 2),
|
|
137
|
-
yMin: require_sfnt.i16(glyph,
|
|
138
|
-
xMax: require_sfnt.i16(glyph,
|
|
139
|
-
yMax: require_sfnt.i16(glyph,
|
|
148
|
+
yMin: require_sfnt.i16(glyph, GLYPH_HEADER_Y_MIN_OFFSET),
|
|
149
|
+
xMax: require_sfnt.i16(glyph, GLYPH_HEADER_X_MAX_OFFSET),
|
|
150
|
+
yMax: require_sfnt.i16(glyph, GLYPH_HEADER_Y_MAX_OFFSET)
|
|
140
151
|
};
|
|
141
152
|
};
|
|
142
153
|
const compositeComponents = (glyphId) => {
|
package/dist/glyf.js
CHANGED
|
@@ -15,6 +15,9 @@ function parseLoca(font, options) {
|
|
|
15
15
|
return offsets;
|
|
16
16
|
}
|
|
17
17
|
const GLYPH_HEADER_SIZE = 10;
|
|
18
|
+
const GLYPH_HEADER_Y_MIN_OFFSET = 4;
|
|
19
|
+
const GLYPH_HEADER_X_MAX_OFFSET = 6;
|
|
20
|
+
const GLYPH_HEADER_Y_MAX_OFFSET = 8;
|
|
18
21
|
const ARG_1_AND_2_ARE_WORDS = 1;
|
|
19
22
|
const ARGS_ARE_XY_VALUES = 2;
|
|
20
23
|
const WE_HAVE_A_SCALE = 8;
|
|
@@ -25,8 +28,16 @@ const SCALED_COMPONENT_OFFSET = 2048;
|
|
|
25
28
|
const UNSCALED_COMPONENT_OFFSET = 4096;
|
|
26
29
|
const MAX_COMPOSITE_DEPTH = 5;
|
|
27
30
|
const COMPONENT_RECORD_HEADER_SIZE = 4;
|
|
31
|
+
const X_AND_Y_SCALE_SIZE = 4;
|
|
32
|
+
const TWO_BY_TWO_SCALE10_OFFSET = 4;
|
|
33
|
+
const TWO_BY_TWO_Y_SCALE_OFFSET = 6;
|
|
34
|
+
const TWO_BY_TWO_SIZE = 8;
|
|
35
|
+
const WORD_ARGS_SIZE = 4;
|
|
36
|
+
const BYTE_ARGS_SIZE = 2;
|
|
37
|
+
const SIGNED_BYTE_SIGN_THRESHOLD = 128;
|
|
38
|
+
const SIGNED_BYTE_MODULUS = 256;
|
|
28
39
|
function signedByte(value) {
|
|
29
|
-
return value >=
|
|
40
|
+
return value >= SIGNED_BYTE_SIGN_THRESHOLD ? value - SIGNED_BYTE_MODULUS : value;
|
|
30
41
|
}
|
|
31
42
|
function readComponents(glyph) {
|
|
32
43
|
const components = [];
|
|
@@ -38,7 +49,7 @@ function readComponents(glyph) {
|
|
|
38
49
|
offset += COMPONENT_RECORD_HEADER_SIZE;
|
|
39
50
|
const argsAreWords = (flags & ARG_1_AND_2_ARE_WORDS) !== 0;
|
|
40
51
|
const argsAreXyValues = (flags & ARGS_ARE_XY_VALUES) !== 0;
|
|
41
|
-
const argsSize = argsAreWords ?
|
|
52
|
+
const argsSize = argsAreWords ? WORD_ARGS_SIZE : BYTE_ARGS_SIZE;
|
|
42
53
|
if (!hasBytes(glyph, offset, argsSize)) return;
|
|
43
54
|
let argument1;
|
|
44
55
|
let argument2;
|
|
@@ -62,23 +73,23 @@ function readComponents(glyph) {
|
|
|
62
73
|
];
|
|
63
74
|
offset += 2;
|
|
64
75
|
} else if ((flags & WE_HAVE_AN_X_AND_Y_SCALE) !== 0) {
|
|
65
|
-
if (!hasBytes(glyph, offset,
|
|
76
|
+
if (!hasBytes(glyph, offset, X_AND_Y_SCALE_SIZE)) return;
|
|
66
77
|
transform = [
|
|
67
78
|
f2dot14(glyph, offset),
|
|
68
79
|
0,
|
|
69
80
|
0,
|
|
70
81
|
f2dot14(glyph, offset + 2)
|
|
71
82
|
];
|
|
72
|
-
offset +=
|
|
83
|
+
offset += X_AND_Y_SCALE_SIZE;
|
|
73
84
|
} else if ((flags & WE_HAVE_A_TWO_BY_TWO) !== 0) {
|
|
74
|
-
if (!hasBytes(glyph, offset,
|
|
85
|
+
if (!hasBytes(glyph, offset, TWO_BY_TWO_SIZE)) return;
|
|
75
86
|
transform = [
|
|
76
87
|
f2dot14(glyph, offset),
|
|
77
88
|
f2dot14(glyph, offset + 2),
|
|
78
|
-
f2dot14(glyph, offset +
|
|
79
|
-
f2dot14(glyph, offset +
|
|
89
|
+
f2dot14(glyph, offset + TWO_BY_TWO_SCALE10_OFFSET),
|
|
90
|
+
f2dot14(glyph, offset + TWO_BY_TWO_Y_SCALE_OFFSET)
|
|
80
91
|
];
|
|
81
|
-
offset +=
|
|
92
|
+
offset += TWO_BY_TWO_SIZE;
|
|
82
93
|
}
|
|
83
94
|
components.push({
|
|
84
95
|
flags,
|
|
@@ -133,9 +144,9 @@ function parseGlyf(font, options) {
|
|
|
133
144
|
return {
|
|
134
145
|
numberOfContours: i16(glyph, 0),
|
|
135
146
|
xMin: i16(glyph, 2),
|
|
136
|
-
yMin: i16(glyph,
|
|
137
|
-
xMax: i16(glyph,
|
|
138
|
-
yMax: i16(glyph,
|
|
147
|
+
yMin: i16(glyph, GLYPH_HEADER_Y_MIN_OFFSET),
|
|
148
|
+
xMax: i16(glyph, GLYPH_HEADER_X_MAX_OFFSET),
|
|
149
|
+
yMax: i16(glyph, GLYPH_HEADER_Y_MAX_OFFSET)
|
|
139
150
|
};
|
|
140
151
|
};
|
|
141
152
|
const compositeComponents = (glyphId) => {
|
package/dist/gpos-table.cjs
CHANGED
|
@@ -3,18 +3,27 @@ const require_sfnt = require("./sfnt.cjs");
|
|
|
3
3
|
const require_ot_layout_common = require("./ot-layout-common.cjs");
|
|
4
4
|
//#region src/gpos-table.ts
|
|
5
5
|
const GPOS_HEADER_SIZE = 10;
|
|
6
|
+
const GPOS_SCRIPT_LIST_OFFSET_FIELD = 4;
|
|
7
|
+
const GPOS_FEATURE_LIST_OFFSET_FIELD = 6;
|
|
8
|
+
const GPOS_LOOKUP_LIST_OFFSET_FIELD = 8;
|
|
6
9
|
const SCRIPT_RECORD_SIZE = 6;
|
|
10
|
+
const SCRIPT_RECORD_OFFSET_FIELD = 4;
|
|
7
11
|
const FEATURE_RECORD_SIZE = 6;
|
|
12
|
+
const FEATURE_RECORD_OFFSET_FIELD = 4;
|
|
8
13
|
const LANG_SYS_HEADER_SIZE = 6;
|
|
14
|
+
const LANG_SYS_FEATURE_INDEX_COUNT_FIELD = 4;
|
|
9
15
|
const FEATURE_HEADER_SIZE = 4;
|
|
10
16
|
const LOOKUP_HEADER_SIZE = 6;
|
|
17
|
+
const LOOKUP_SUB_TABLE_COUNT_FIELD = 4;
|
|
11
18
|
const EXTENSION_POS_HEADER_SIZE = 8;
|
|
19
|
+
const EXTENSION_POS_OFFSET_FIELD = 4;
|
|
12
20
|
const LOOKUP_TYPE_PAIR_POS = 2;
|
|
13
21
|
const LOOKUP_TYPE_EXTENSION_POS = 9;
|
|
14
22
|
const KERN_FEATURE_TAG = "kern";
|
|
15
23
|
const PREFERRED_SCRIPT_TAGS = ["latn", "DFLT"];
|
|
24
|
+
const TAG_LENGTH_BYTES = 4;
|
|
16
25
|
function readTag(bytes, offset) {
|
|
17
|
-
return String.fromCharCode(require_sfnt.u8(bytes, offset), require_sfnt.u8(bytes, offset + 1), require_sfnt.u8(bytes, offset + 2), require_sfnt.u8(bytes, offset +
|
|
26
|
+
return String.fromCharCode(require_sfnt.u8(bytes, offset), require_sfnt.u8(bytes, offset + 1), require_sfnt.u8(bytes, offset + 2), require_sfnt.u8(bytes, offset + TAG_LENGTH_BYTES - 1));
|
|
18
27
|
}
|
|
19
28
|
function valueRecordSize(valueFormat) {
|
|
20
29
|
let size = 0;
|
|
@@ -27,14 +36,17 @@ function xAdvanceOffset(valueFormat) {
|
|
|
27
36
|
return valueRecordSize(valueFormat & 3);
|
|
28
37
|
}
|
|
29
38
|
const PAIR_POS_FORMAT_1_HEADER_SIZE = 10;
|
|
39
|
+
const PAIR_POS_FORMAT_1_VALUE_FORMAT_1_FIELD = 4;
|
|
40
|
+
const PAIR_POS_FORMAT_1_VALUE_FORMAT_2_FIELD = 6;
|
|
41
|
+
const PAIR_POS_FORMAT_1_PAIR_SET_COUNT_FIELD = 8;
|
|
30
42
|
const PAIR_VALUE_RECORD_GLYPH_SIZE = 2;
|
|
31
43
|
function parsePairPosFormat1(bytes, subtableOffset) {
|
|
32
44
|
if (!require_sfnt.hasBytes(bytes, subtableOffset, PAIR_POS_FORMAT_1_HEADER_SIZE)) return;
|
|
33
45
|
const coverage = require_ot_layout_common.parseCoverage(bytes, subtableOffset + require_sfnt.u16(bytes, subtableOffset + 2));
|
|
34
46
|
if (coverage === void 0) return;
|
|
35
|
-
const valueFormat1 = require_sfnt.u16(bytes, subtableOffset +
|
|
36
|
-
const valueFormat2 = require_sfnt.u16(bytes, subtableOffset +
|
|
37
|
-
const pairSetCount = require_sfnt.u16(bytes, subtableOffset +
|
|
47
|
+
const valueFormat1 = require_sfnt.u16(bytes, subtableOffset + PAIR_POS_FORMAT_1_VALUE_FORMAT_1_FIELD);
|
|
48
|
+
const valueFormat2 = require_sfnt.u16(bytes, subtableOffset + PAIR_POS_FORMAT_1_VALUE_FORMAT_2_FIELD);
|
|
49
|
+
const pairSetCount = require_sfnt.u16(bytes, subtableOffset + PAIR_POS_FORMAT_1_PAIR_SET_COUNT_FIELD);
|
|
38
50
|
const pairSetOffsetsOffset = subtableOffset + PAIR_POS_FORMAT_1_HEADER_SIZE;
|
|
39
51
|
if (!require_sfnt.hasBytes(bytes, pairSetOffsetsOffset, pairSetCount * 2)) return;
|
|
40
52
|
const recordSize = PAIR_VALUE_RECORD_GLYPH_SIZE + valueRecordSize(valueFormat1) + valueRecordSize(valueFormat2);
|
|
@@ -60,16 +72,22 @@ function parsePairPosFormat1(bytes, subtableOffset) {
|
|
|
60
72
|
};
|
|
61
73
|
}
|
|
62
74
|
const PAIR_POS_FORMAT_2_HEADER_SIZE = 16;
|
|
75
|
+
const PAIR_POS_FORMAT_2_VALUE_FORMAT_1_FIELD = 4;
|
|
76
|
+
const PAIR_POS_FORMAT_2_VALUE_FORMAT_2_FIELD = 6;
|
|
77
|
+
const PAIR_POS_FORMAT_2_CLASS_DEF_1_FIELD = 8;
|
|
78
|
+
const PAIR_POS_FORMAT_2_CLASS_DEF_2_FIELD = 10;
|
|
79
|
+
const PAIR_POS_FORMAT_2_CLASS_1_COUNT_FIELD = 12;
|
|
80
|
+
const PAIR_POS_FORMAT_2_CLASS_2_COUNT_FIELD = 14;
|
|
63
81
|
function parsePairPosFormat2(bytes, subtableOffset) {
|
|
64
82
|
if (!require_sfnt.hasBytes(bytes, subtableOffset, PAIR_POS_FORMAT_2_HEADER_SIZE)) return;
|
|
65
83
|
const coverage = require_ot_layout_common.parseCoverage(bytes, subtableOffset + require_sfnt.u16(bytes, subtableOffset + 2));
|
|
66
|
-
const classDef1 = require_ot_layout_common.parseClassDef(bytes, subtableOffset + require_sfnt.u16(bytes, subtableOffset +
|
|
67
|
-
const classDef2 = require_ot_layout_common.parseClassDef(bytes, subtableOffset + require_sfnt.u16(bytes, subtableOffset +
|
|
84
|
+
const classDef1 = require_ot_layout_common.parseClassDef(bytes, subtableOffset + require_sfnt.u16(bytes, subtableOffset + PAIR_POS_FORMAT_2_CLASS_DEF_1_FIELD));
|
|
85
|
+
const classDef2 = require_ot_layout_common.parseClassDef(bytes, subtableOffset + require_sfnt.u16(bytes, subtableOffset + PAIR_POS_FORMAT_2_CLASS_DEF_2_FIELD));
|
|
68
86
|
if (coverage === void 0 || classDef1 === void 0 || classDef2 === void 0) return;
|
|
69
|
-
const valueFormat1 = require_sfnt.u16(bytes, subtableOffset +
|
|
70
|
-
const valueFormat2 = require_sfnt.u16(bytes, subtableOffset +
|
|
71
|
-
const class1Count = require_sfnt.u16(bytes, subtableOffset +
|
|
72
|
-
const class2Count = require_sfnt.u16(bytes, subtableOffset +
|
|
87
|
+
const valueFormat1 = require_sfnt.u16(bytes, subtableOffset + PAIR_POS_FORMAT_2_VALUE_FORMAT_1_FIELD);
|
|
88
|
+
const valueFormat2 = require_sfnt.u16(bytes, subtableOffset + PAIR_POS_FORMAT_2_VALUE_FORMAT_2_FIELD);
|
|
89
|
+
const class1Count = require_sfnt.u16(bytes, subtableOffset + PAIR_POS_FORMAT_2_CLASS_1_COUNT_FIELD);
|
|
90
|
+
const class2Count = require_sfnt.u16(bytes, subtableOffset + PAIR_POS_FORMAT_2_CLASS_2_COUNT_FIELD);
|
|
73
91
|
const class2RecordSize = valueRecordSize(valueFormat1) + valueRecordSize(valueFormat2);
|
|
74
92
|
const class1RecordSize = class2Count * class2RecordSize;
|
|
75
93
|
const matrixOffset = subtableOffset + PAIR_POS_FORMAT_2_HEADER_SIZE;
|
|
@@ -89,7 +107,7 @@ function parseSubtable(bytes, lookupType, subtableOffset) {
|
|
|
89
107
|
if (!require_sfnt.hasBytes(bytes, subtableOffset, EXTENSION_POS_HEADER_SIZE) || require_sfnt.u16(bytes, subtableOffset) !== 1) return;
|
|
90
108
|
const extensionLookupType = require_sfnt.u16(bytes, subtableOffset + 2);
|
|
91
109
|
if (extensionLookupType === LOOKUP_TYPE_EXTENSION_POS) return;
|
|
92
|
-
return parseSubtable(bytes, extensionLookupType, subtableOffset + require_sfnt.u32(bytes, subtableOffset +
|
|
110
|
+
return parseSubtable(bytes, extensionLookupType, subtableOffset + require_sfnt.u32(bytes, subtableOffset + EXTENSION_POS_OFFSET_FIELD));
|
|
93
111
|
}
|
|
94
112
|
if (lookupType !== LOOKUP_TYPE_PAIR_POS) return;
|
|
95
113
|
if (!require_sfnt.hasBytes(bytes, subtableOffset, 2)) return;
|
|
@@ -100,7 +118,7 @@ function parseSubtable(bytes, lookupType, subtableOffset) {
|
|
|
100
118
|
function parseLookupSubtables(bytes, lookupOffset) {
|
|
101
119
|
if (!require_sfnt.hasBytes(bytes, lookupOffset, LOOKUP_HEADER_SIZE)) return [];
|
|
102
120
|
const lookupType = require_sfnt.u16(bytes, lookupOffset);
|
|
103
|
-
const subTableCount = require_sfnt.u16(bytes, lookupOffset +
|
|
121
|
+
const subTableCount = require_sfnt.u16(bytes, lookupOffset + LOOKUP_SUB_TABLE_COUNT_FIELD);
|
|
104
122
|
const offsetsOffset = lookupOffset + LOOKUP_HEADER_SIZE;
|
|
105
123
|
if (!require_sfnt.hasBytes(bytes, offsetsOffset, subTableCount * 2)) return [];
|
|
106
124
|
const subtables = [];
|
|
@@ -116,7 +134,7 @@ function parseDefaultLangSysFeatureIndices(bytes, scriptOffset) {
|
|
|
116
134
|
if (defaultLangSysOffset === 0) return [];
|
|
117
135
|
const langSysOffset = scriptOffset + defaultLangSysOffset;
|
|
118
136
|
if (!require_sfnt.hasBytes(bytes, langSysOffset, LANG_SYS_HEADER_SIZE)) return [];
|
|
119
|
-
const featureIndexCount = require_sfnt.u16(bytes, langSysOffset +
|
|
137
|
+
const featureIndexCount = require_sfnt.u16(bytes, langSysOffset + LANG_SYS_FEATURE_INDEX_COUNT_FIELD);
|
|
120
138
|
const indicesOffset = langSysOffset + LANG_SYS_HEADER_SIZE;
|
|
121
139
|
if (!require_sfnt.hasBytes(bytes, indicesOffset, featureIndexCount * 2)) return [];
|
|
122
140
|
const indices = [];
|
|
@@ -130,9 +148,9 @@ function findScriptOffset(bytes, scriptListOffset) {
|
|
|
130
148
|
if (!require_sfnt.hasBytes(bytes, recordsOffset, scriptCount * SCRIPT_RECORD_SIZE) || scriptCount === 0) return;
|
|
131
149
|
for (const wanted of PREFERRED_SCRIPT_TAGS) for (let i = 0; i < scriptCount; i++) {
|
|
132
150
|
const recordOffset = recordsOffset + i * SCRIPT_RECORD_SIZE;
|
|
133
|
-
if (readTag(bytes, recordOffset) === wanted) return scriptListOffset + require_sfnt.u16(bytes, recordOffset +
|
|
151
|
+
if (readTag(bytes, recordOffset) === wanted) return scriptListOffset + require_sfnt.u16(bytes, recordOffset + SCRIPT_RECORD_OFFSET_FIELD);
|
|
134
152
|
}
|
|
135
|
-
return scriptListOffset + require_sfnt.u16(bytes, recordsOffset +
|
|
153
|
+
return scriptListOffset + require_sfnt.u16(bytes, recordsOffset + SCRIPT_RECORD_OFFSET_FIELD);
|
|
136
154
|
}
|
|
137
155
|
function collectKernLookupIndices(bytes, featureListOffset, featureIndices) {
|
|
138
156
|
if (!require_sfnt.hasBytes(bytes, featureListOffset, 2)) return [];
|
|
@@ -145,7 +163,7 @@ function collectKernLookupIndices(bytes, featureListOffset, featureIndices) {
|
|
|
145
163
|
if (featureIndex >= featureCount) continue;
|
|
146
164
|
const recordOffset = recordsOffset + featureIndex * FEATURE_RECORD_SIZE;
|
|
147
165
|
if (readTag(bytes, recordOffset) !== KERN_FEATURE_TAG) continue;
|
|
148
|
-
const featureOffset = featureListOffset + require_sfnt.u16(bytes, recordOffset +
|
|
166
|
+
const featureOffset = featureListOffset + require_sfnt.u16(bytes, recordOffset + FEATURE_RECORD_OFFSET_FIELD);
|
|
149
167
|
if (!require_sfnt.hasBytes(bytes, featureOffset, FEATURE_HEADER_SIZE)) continue;
|
|
150
168
|
const lookupIndexCount = require_sfnt.u16(bytes, featureOffset + 2);
|
|
151
169
|
const indicesOffset = featureOffset + FEATURE_HEADER_SIZE;
|
|
@@ -163,11 +181,11 @@ function collectKernLookupIndices(bytes, featureListOffset, featureIndices) {
|
|
|
163
181
|
function buildGposKernLookup(font) {
|
|
164
182
|
const bytes = require_sfnt.sfntTableBytes(font, "GPOS");
|
|
165
183
|
if (bytes === void 0 || !require_sfnt.hasBytes(bytes, 0, GPOS_HEADER_SIZE) || require_sfnt.u16(bytes, 0) !== 1) return;
|
|
166
|
-
const scriptOffset = findScriptOffset(bytes, require_sfnt.u16(bytes,
|
|
184
|
+
const scriptOffset = findScriptOffset(bytes, require_sfnt.u16(bytes, GPOS_SCRIPT_LIST_OFFSET_FIELD));
|
|
167
185
|
if (scriptOffset === void 0) return;
|
|
168
|
-
const lookupIndices = collectKernLookupIndices(bytes, require_sfnt.u16(bytes,
|
|
186
|
+
const lookupIndices = collectKernLookupIndices(bytes, require_sfnt.u16(bytes, GPOS_FEATURE_LIST_OFFSET_FIELD), parseDefaultLangSysFeatureIndices(bytes, scriptOffset));
|
|
169
187
|
if (lookupIndices.length === 0) return;
|
|
170
|
-
const lookupListOffset = require_sfnt.u16(bytes,
|
|
188
|
+
const lookupListOffset = require_sfnt.u16(bytes, GPOS_LOOKUP_LIST_OFFSET_FIELD);
|
|
171
189
|
if (!require_sfnt.hasBytes(bytes, lookupListOffset, 2)) return;
|
|
172
190
|
const lookupCount = require_sfnt.u16(bytes, lookupListOffset);
|
|
173
191
|
const lookupOffsetsOffset = lookupListOffset + 2;
|
package/dist/gpos-table.js
CHANGED
|
@@ -2,18 +2,27 @@ import { hasBytes, i16, sfntTableBytes, u16, u32, u8 } from "./sfnt.js";
|
|
|
2
2
|
import { parseClassDef, parseCoverage } from "./ot-layout-common.js";
|
|
3
3
|
//#region src/gpos-table.ts
|
|
4
4
|
const GPOS_HEADER_SIZE = 10;
|
|
5
|
+
const GPOS_SCRIPT_LIST_OFFSET_FIELD = 4;
|
|
6
|
+
const GPOS_FEATURE_LIST_OFFSET_FIELD = 6;
|
|
7
|
+
const GPOS_LOOKUP_LIST_OFFSET_FIELD = 8;
|
|
5
8
|
const SCRIPT_RECORD_SIZE = 6;
|
|
9
|
+
const SCRIPT_RECORD_OFFSET_FIELD = 4;
|
|
6
10
|
const FEATURE_RECORD_SIZE = 6;
|
|
11
|
+
const FEATURE_RECORD_OFFSET_FIELD = 4;
|
|
7
12
|
const LANG_SYS_HEADER_SIZE = 6;
|
|
13
|
+
const LANG_SYS_FEATURE_INDEX_COUNT_FIELD = 4;
|
|
8
14
|
const FEATURE_HEADER_SIZE = 4;
|
|
9
15
|
const LOOKUP_HEADER_SIZE = 6;
|
|
16
|
+
const LOOKUP_SUB_TABLE_COUNT_FIELD = 4;
|
|
10
17
|
const EXTENSION_POS_HEADER_SIZE = 8;
|
|
18
|
+
const EXTENSION_POS_OFFSET_FIELD = 4;
|
|
11
19
|
const LOOKUP_TYPE_PAIR_POS = 2;
|
|
12
20
|
const LOOKUP_TYPE_EXTENSION_POS = 9;
|
|
13
21
|
const KERN_FEATURE_TAG = "kern";
|
|
14
22
|
const PREFERRED_SCRIPT_TAGS = ["latn", "DFLT"];
|
|
23
|
+
const TAG_LENGTH_BYTES = 4;
|
|
15
24
|
function readTag(bytes, offset) {
|
|
16
|
-
return String.fromCharCode(u8(bytes, offset), u8(bytes, offset + 1), u8(bytes, offset + 2), u8(bytes, offset +
|
|
25
|
+
return String.fromCharCode(u8(bytes, offset), u8(bytes, offset + 1), u8(bytes, offset + 2), u8(bytes, offset + TAG_LENGTH_BYTES - 1));
|
|
17
26
|
}
|
|
18
27
|
function valueRecordSize(valueFormat) {
|
|
19
28
|
let size = 0;
|
|
@@ -26,14 +35,17 @@ function xAdvanceOffset(valueFormat) {
|
|
|
26
35
|
return valueRecordSize(valueFormat & 3);
|
|
27
36
|
}
|
|
28
37
|
const PAIR_POS_FORMAT_1_HEADER_SIZE = 10;
|
|
38
|
+
const PAIR_POS_FORMAT_1_VALUE_FORMAT_1_FIELD = 4;
|
|
39
|
+
const PAIR_POS_FORMAT_1_VALUE_FORMAT_2_FIELD = 6;
|
|
40
|
+
const PAIR_POS_FORMAT_1_PAIR_SET_COUNT_FIELD = 8;
|
|
29
41
|
const PAIR_VALUE_RECORD_GLYPH_SIZE = 2;
|
|
30
42
|
function parsePairPosFormat1(bytes, subtableOffset) {
|
|
31
43
|
if (!hasBytes(bytes, subtableOffset, PAIR_POS_FORMAT_1_HEADER_SIZE)) return;
|
|
32
44
|
const coverage = parseCoverage(bytes, subtableOffset + u16(bytes, subtableOffset + 2));
|
|
33
45
|
if (coverage === void 0) return;
|
|
34
|
-
const valueFormat1 = u16(bytes, subtableOffset +
|
|
35
|
-
const valueFormat2 = u16(bytes, subtableOffset +
|
|
36
|
-
const pairSetCount = u16(bytes, subtableOffset +
|
|
46
|
+
const valueFormat1 = u16(bytes, subtableOffset + PAIR_POS_FORMAT_1_VALUE_FORMAT_1_FIELD);
|
|
47
|
+
const valueFormat2 = u16(bytes, subtableOffset + PAIR_POS_FORMAT_1_VALUE_FORMAT_2_FIELD);
|
|
48
|
+
const pairSetCount = u16(bytes, subtableOffset + PAIR_POS_FORMAT_1_PAIR_SET_COUNT_FIELD);
|
|
37
49
|
const pairSetOffsetsOffset = subtableOffset + PAIR_POS_FORMAT_1_HEADER_SIZE;
|
|
38
50
|
if (!hasBytes(bytes, pairSetOffsetsOffset, pairSetCount * 2)) return;
|
|
39
51
|
const recordSize = PAIR_VALUE_RECORD_GLYPH_SIZE + valueRecordSize(valueFormat1) + valueRecordSize(valueFormat2);
|
|
@@ -59,16 +71,22 @@ function parsePairPosFormat1(bytes, subtableOffset) {
|
|
|
59
71
|
};
|
|
60
72
|
}
|
|
61
73
|
const PAIR_POS_FORMAT_2_HEADER_SIZE = 16;
|
|
74
|
+
const PAIR_POS_FORMAT_2_VALUE_FORMAT_1_FIELD = 4;
|
|
75
|
+
const PAIR_POS_FORMAT_2_VALUE_FORMAT_2_FIELD = 6;
|
|
76
|
+
const PAIR_POS_FORMAT_2_CLASS_DEF_1_FIELD = 8;
|
|
77
|
+
const PAIR_POS_FORMAT_2_CLASS_DEF_2_FIELD = 10;
|
|
78
|
+
const PAIR_POS_FORMAT_2_CLASS_1_COUNT_FIELD = 12;
|
|
79
|
+
const PAIR_POS_FORMAT_2_CLASS_2_COUNT_FIELD = 14;
|
|
62
80
|
function parsePairPosFormat2(bytes, subtableOffset) {
|
|
63
81
|
if (!hasBytes(bytes, subtableOffset, PAIR_POS_FORMAT_2_HEADER_SIZE)) return;
|
|
64
82
|
const coverage = parseCoverage(bytes, subtableOffset + u16(bytes, subtableOffset + 2));
|
|
65
|
-
const classDef1 = parseClassDef(bytes, subtableOffset + u16(bytes, subtableOffset +
|
|
66
|
-
const classDef2 = parseClassDef(bytes, subtableOffset + u16(bytes, subtableOffset +
|
|
83
|
+
const classDef1 = parseClassDef(bytes, subtableOffset + u16(bytes, subtableOffset + PAIR_POS_FORMAT_2_CLASS_DEF_1_FIELD));
|
|
84
|
+
const classDef2 = parseClassDef(bytes, subtableOffset + u16(bytes, subtableOffset + PAIR_POS_FORMAT_2_CLASS_DEF_2_FIELD));
|
|
67
85
|
if (coverage === void 0 || classDef1 === void 0 || classDef2 === void 0) return;
|
|
68
|
-
const valueFormat1 = u16(bytes, subtableOffset +
|
|
69
|
-
const valueFormat2 = u16(bytes, subtableOffset +
|
|
70
|
-
const class1Count = u16(bytes, subtableOffset +
|
|
71
|
-
const class2Count = u16(bytes, subtableOffset +
|
|
86
|
+
const valueFormat1 = u16(bytes, subtableOffset + PAIR_POS_FORMAT_2_VALUE_FORMAT_1_FIELD);
|
|
87
|
+
const valueFormat2 = u16(bytes, subtableOffset + PAIR_POS_FORMAT_2_VALUE_FORMAT_2_FIELD);
|
|
88
|
+
const class1Count = u16(bytes, subtableOffset + PAIR_POS_FORMAT_2_CLASS_1_COUNT_FIELD);
|
|
89
|
+
const class2Count = u16(bytes, subtableOffset + PAIR_POS_FORMAT_2_CLASS_2_COUNT_FIELD);
|
|
72
90
|
const class2RecordSize = valueRecordSize(valueFormat1) + valueRecordSize(valueFormat2);
|
|
73
91
|
const class1RecordSize = class2Count * class2RecordSize;
|
|
74
92
|
const matrixOffset = subtableOffset + PAIR_POS_FORMAT_2_HEADER_SIZE;
|
|
@@ -88,7 +106,7 @@ function parseSubtable(bytes, lookupType, subtableOffset) {
|
|
|
88
106
|
if (!hasBytes(bytes, subtableOffset, EXTENSION_POS_HEADER_SIZE) || u16(bytes, subtableOffset) !== 1) return;
|
|
89
107
|
const extensionLookupType = u16(bytes, subtableOffset + 2);
|
|
90
108
|
if (extensionLookupType === LOOKUP_TYPE_EXTENSION_POS) return;
|
|
91
|
-
return parseSubtable(bytes, extensionLookupType, subtableOffset + u32(bytes, subtableOffset +
|
|
109
|
+
return parseSubtable(bytes, extensionLookupType, subtableOffset + u32(bytes, subtableOffset + EXTENSION_POS_OFFSET_FIELD));
|
|
92
110
|
}
|
|
93
111
|
if (lookupType !== LOOKUP_TYPE_PAIR_POS) return;
|
|
94
112
|
if (!hasBytes(bytes, subtableOffset, 2)) return;
|
|
@@ -99,7 +117,7 @@ function parseSubtable(bytes, lookupType, subtableOffset) {
|
|
|
99
117
|
function parseLookupSubtables(bytes, lookupOffset) {
|
|
100
118
|
if (!hasBytes(bytes, lookupOffset, LOOKUP_HEADER_SIZE)) return [];
|
|
101
119
|
const lookupType = u16(bytes, lookupOffset);
|
|
102
|
-
const subTableCount = u16(bytes, lookupOffset +
|
|
120
|
+
const subTableCount = u16(bytes, lookupOffset + LOOKUP_SUB_TABLE_COUNT_FIELD);
|
|
103
121
|
const offsetsOffset = lookupOffset + LOOKUP_HEADER_SIZE;
|
|
104
122
|
if (!hasBytes(bytes, offsetsOffset, subTableCount * 2)) return [];
|
|
105
123
|
const subtables = [];
|
|
@@ -115,7 +133,7 @@ function parseDefaultLangSysFeatureIndices(bytes, scriptOffset) {
|
|
|
115
133
|
if (defaultLangSysOffset === 0) return [];
|
|
116
134
|
const langSysOffset = scriptOffset + defaultLangSysOffset;
|
|
117
135
|
if (!hasBytes(bytes, langSysOffset, LANG_SYS_HEADER_SIZE)) return [];
|
|
118
|
-
const featureIndexCount = u16(bytes, langSysOffset +
|
|
136
|
+
const featureIndexCount = u16(bytes, langSysOffset + LANG_SYS_FEATURE_INDEX_COUNT_FIELD);
|
|
119
137
|
const indicesOffset = langSysOffset + LANG_SYS_HEADER_SIZE;
|
|
120
138
|
if (!hasBytes(bytes, indicesOffset, featureIndexCount * 2)) return [];
|
|
121
139
|
const indices = [];
|
|
@@ -129,9 +147,9 @@ function findScriptOffset(bytes, scriptListOffset) {
|
|
|
129
147
|
if (!hasBytes(bytes, recordsOffset, scriptCount * SCRIPT_RECORD_SIZE) || scriptCount === 0) return;
|
|
130
148
|
for (const wanted of PREFERRED_SCRIPT_TAGS) for (let i = 0; i < scriptCount; i++) {
|
|
131
149
|
const recordOffset = recordsOffset + i * SCRIPT_RECORD_SIZE;
|
|
132
|
-
if (readTag(bytes, recordOffset) === wanted) return scriptListOffset + u16(bytes, recordOffset +
|
|
150
|
+
if (readTag(bytes, recordOffset) === wanted) return scriptListOffset + u16(bytes, recordOffset + SCRIPT_RECORD_OFFSET_FIELD);
|
|
133
151
|
}
|
|
134
|
-
return scriptListOffset + u16(bytes, recordsOffset +
|
|
152
|
+
return scriptListOffset + u16(bytes, recordsOffset + SCRIPT_RECORD_OFFSET_FIELD);
|
|
135
153
|
}
|
|
136
154
|
function collectKernLookupIndices(bytes, featureListOffset, featureIndices) {
|
|
137
155
|
if (!hasBytes(bytes, featureListOffset, 2)) return [];
|
|
@@ -144,7 +162,7 @@ function collectKernLookupIndices(bytes, featureListOffset, featureIndices) {
|
|
|
144
162
|
if (featureIndex >= featureCount) continue;
|
|
145
163
|
const recordOffset = recordsOffset + featureIndex * FEATURE_RECORD_SIZE;
|
|
146
164
|
if (readTag(bytes, recordOffset) !== KERN_FEATURE_TAG) continue;
|
|
147
|
-
const featureOffset = featureListOffset + u16(bytes, recordOffset +
|
|
165
|
+
const featureOffset = featureListOffset + u16(bytes, recordOffset + FEATURE_RECORD_OFFSET_FIELD);
|
|
148
166
|
if (!hasBytes(bytes, featureOffset, FEATURE_HEADER_SIZE)) continue;
|
|
149
167
|
const lookupIndexCount = u16(bytes, featureOffset + 2);
|
|
150
168
|
const indicesOffset = featureOffset + FEATURE_HEADER_SIZE;
|
|
@@ -162,11 +180,11 @@ function collectKernLookupIndices(bytes, featureListOffset, featureIndices) {
|
|
|
162
180
|
function buildGposKernLookup(font) {
|
|
163
181
|
const bytes = sfntTableBytes(font, "GPOS");
|
|
164
182
|
if (bytes === void 0 || !hasBytes(bytes, 0, GPOS_HEADER_SIZE) || u16(bytes, 0) !== 1) return;
|
|
165
|
-
const scriptOffset = findScriptOffset(bytes, u16(bytes,
|
|
183
|
+
const scriptOffset = findScriptOffset(bytes, u16(bytes, GPOS_SCRIPT_LIST_OFFSET_FIELD));
|
|
166
184
|
if (scriptOffset === void 0) return;
|
|
167
|
-
const lookupIndices = collectKernLookupIndices(bytes, u16(bytes,
|
|
185
|
+
const lookupIndices = collectKernLookupIndices(bytes, u16(bytes, GPOS_FEATURE_LIST_OFFSET_FIELD), parseDefaultLangSysFeatureIndices(bytes, scriptOffset));
|
|
168
186
|
if (lookupIndices.length === 0) return;
|
|
169
|
-
const lookupListOffset = u16(bytes,
|
|
187
|
+
const lookupListOffset = u16(bytes, GPOS_LOOKUP_LIST_OFFSET_FIELD);
|
|
170
188
|
if (!hasBytes(bytes, lookupListOffset, 2)) return;
|
|
171
189
|
const lookupCount = u16(bytes, lookupListOffset);
|
|
172
190
|
const lookupOffsetsOffset = lookupListOffset + 2;
|
package/dist/gsub-table.cjs
CHANGED
|
@@ -12,17 +12,28 @@ const DEFAULT_GSUB_FEATURE_TAGS = [
|
|
|
12
12
|
];
|
|
13
13
|
const GSUB_OPT_IN_FEATURE_TAGS = ["smcp", "dlig"];
|
|
14
14
|
const GSUB_HEADER_SIZE = 10;
|
|
15
|
+
const GSUB_HEADER_SCRIPT_LIST_OFFSET = 4;
|
|
16
|
+
const GSUB_HEADER_FEATURE_LIST_OFFSET = 6;
|
|
17
|
+
const GSUB_HEADER_LOOKUP_LIST_OFFSET = 8;
|
|
15
18
|
const SCRIPT_RECORD_SIZE = 6;
|
|
19
|
+
const SCRIPT_RECORD_OFFSET_FIELD_OFFSET = 4;
|
|
16
20
|
const FEATURE_RECORD_SIZE = 6;
|
|
21
|
+
const FEATURE_RECORD_OFFSET_FIELD_OFFSET = 4;
|
|
17
22
|
const LANG_SYS_HEADER_SIZE = 6;
|
|
23
|
+
const LANG_SYS_FEATURE_INDEX_COUNT_OFFSET = 4;
|
|
18
24
|
const FEATURE_HEADER_SIZE = 4;
|
|
19
25
|
const LOOKUP_HEADER_SIZE = 6;
|
|
26
|
+
const LOOKUP_HEADER_SUBTABLE_COUNT_OFFSET = 4;
|
|
20
27
|
const LOOKUP_TYPE_SINGLE_SUBST = 1;
|
|
21
28
|
const LOOKUP_TYPE_LIGATURE_SUBST = 4;
|
|
22
29
|
const LOOKUP_TYPE_CONTEXT_SUBST = 5;
|
|
23
30
|
const LOOKUP_TYPE_CHAIN_CONTEXT_SUBST = 6;
|
|
24
31
|
const LOOKUP_TYPE_EXTENSION_SUBST = 7;
|
|
25
32
|
const EXTENSION_SUBST_HEADER_SIZE = 8;
|
|
33
|
+
const EXTENSION_SUBST_OFFSET_FIELD_OFFSET = 4;
|
|
34
|
+
const BITS_PER_BYTE = 8;
|
|
35
|
+
const BYTE_MASK = 255;
|
|
36
|
+
const SUBST_FORMAT_AND_COVERAGE_SIZE = 4;
|
|
26
37
|
const LOOKUP_FLAG_IGNORE_BASE_GLYPHS = 2;
|
|
27
38
|
const LOOKUP_FLAG_IGNORE_LIGATURES = 4;
|
|
28
39
|
const LOOKUP_FLAG_IGNORE_MARKS = 8;
|
|
@@ -31,14 +42,14 @@ const LOOKUP_FLAG_MARK_ATTACHMENT_TYPE = 65280;
|
|
|
31
42
|
const MAX_LOOKUP_NESTING_DEPTH = 6;
|
|
32
43
|
const PREFERRED_SCRIPT_TAGS = ["latn", "DFLT"];
|
|
33
44
|
function readTag(bytes, offset) {
|
|
34
|
-
return String.fromCharCode(require_sfnt.u16(bytes, offset) >>
|
|
45
|
+
return String.fromCharCode(require_sfnt.u16(bytes, offset) >> BITS_PER_BYTE, require_sfnt.u16(bytes, offset) & BYTE_MASK, require_sfnt.u16(bytes, offset + 2) >> BITS_PER_BYTE, require_sfnt.u16(bytes, offset + 2) & BYTE_MASK);
|
|
35
46
|
}
|
|
36
47
|
function glyphSkipper(lookupFlag, markFilteringSet, gdef) {
|
|
37
48
|
if (gdef === void 0 || lookupFlag === 0) return () => false;
|
|
38
49
|
const ignoreBase = (lookupFlag & LOOKUP_FLAG_IGNORE_BASE_GLYPHS) !== 0;
|
|
39
50
|
const ignoreLigatures = (lookupFlag & LOOKUP_FLAG_IGNORE_LIGATURES) !== 0;
|
|
40
51
|
const ignoreMarks = (lookupFlag & LOOKUP_FLAG_IGNORE_MARKS) !== 0;
|
|
41
|
-
const markAttachmentType = (lookupFlag & LOOKUP_FLAG_MARK_ATTACHMENT_TYPE) >>
|
|
52
|
+
const markAttachmentType = (lookupFlag & LOOKUP_FLAG_MARK_ATTACHMENT_TYPE) >> BITS_PER_BYTE;
|
|
42
53
|
const useMarkFilteringSet = (lookupFlag & LOOKUP_FLAG_USE_MARK_FILTERING_SET) !== 0;
|
|
43
54
|
return (glyphId) => {
|
|
44
55
|
const glyphClass = gdef.glyphClass(glyphId);
|
|
@@ -61,7 +72,7 @@ function parseSingleSubstFormat1(bytes, subtableOffset, skip) {
|
|
|
61
72
|
if (!require_sfnt.hasBytes(bytes, subtableOffset, SINGLE_SUBST_FORMAT_1_SIZE)) return;
|
|
62
73
|
const coverage = require_ot_layout_common.parseCoverage(bytes, subtableOffset + require_sfnt.u16(bytes, subtableOffset + 2));
|
|
63
74
|
if (coverage === void 0) return;
|
|
64
|
-
const delta = require_sfnt.i16(bytes, subtableOffset +
|
|
75
|
+
const delta = require_sfnt.i16(bytes, subtableOffset + SUBST_FORMAT_AND_COVERAGE_SIZE);
|
|
65
76
|
return (slots, index) => {
|
|
66
77
|
const slot = slots[index];
|
|
67
78
|
if (skip(slot.glyphId)) return;
|
|
@@ -80,7 +91,7 @@ function parseSingleSubstFormat2(bytes, subtableOffset, skip) {
|
|
|
80
91
|
if (!require_sfnt.hasBytes(bytes, subtableOffset, SINGLE_SUBST_FORMAT_2_HEADER_SIZE)) return;
|
|
81
92
|
const coverage = require_ot_layout_common.parseCoverage(bytes, subtableOffset + require_sfnt.u16(bytes, subtableOffset + 2));
|
|
82
93
|
if (coverage === void 0) return;
|
|
83
|
-
const glyphCount = require_sfnt.u16(bytes, subtableOffset +
|
|
94
|
+
const glyphCount = require_sfnt.u16(bytes, subtableOffset + SUBST_FORMAT_AND_COVERAGE_SIZE);
|
|
84
95
|
const substitutesOffset = subtableOffset + SINGLE_SUBST_FORMAT_2_HEADER_SIZE;
|
|
85
96
|
if (!require_sfnt.hasBytes(bytes, substitutesOffset, glyphCount * 2)) return;
|
|
86
97
|
return (slots, index) => {
|
|
@@ -104,7 +115,7 @@ function parseLigatureSubstFormat1(bytes, subtableOffset, skip) {
|
|
|
104
115
|
if (!require_sfnt.hasBytes(bytes, subtableOffset, LIGATURE_SUBST_FORMAT_1_HEADER_SIZE)) return;
|
|
105
116
|
const coverage = require_ot_layout_common.parseCoverage(bytes, subtableOffset + require_sfnt.u16(bytes, subtableOffset + 2));
|
|
106
117
|
if (coverage === void 0) return;
|
|
107
|
-
const ligSetCount = require_sfnt.u16(bytes, subtableOffset +
|
|
118
|
+
const ligSetCount = require_sfnt.u16(bytes, subtableOffset + SUBST_FORMAT_AND_COVERAGE_SIZE);
|
|
108
119
|
const ligSetOffsetsOffset = subtableOffset + LIGATURE_SUBST_FORMAT_1_HEADER_SIZE;
|
|
109
120
|
if (!require_sfnt.hasBytes(bytes, ligSetOffsetsOffset, ligSetCount * 2)) return;
|
|
110
121
|
return (slots, index) => {
|
|
@@ -193,7 +204,10 @@ function applyContextualRule(slots, inputSlots, records, lookupOf, skip, depth)
|
|
|
193
204
|
const lookup = lookupOf(record.lookupIndex);
|
|
194
205
|
if (lookup === void 0 || record.sequenceIndex >= inputSlots.length || depth >= MAX_LOOKUP_NESTING_DEPTH) return;
|
|
195
206
|
const target = visibleInputSlot(window, record.sequenceIndex, skip);
|
|
196
|
-
if (target !== void 0)
|
|
207
|
+
if (target !== void 0) {
|
|
208
|
+
const application = applyLookupAtSlot(window, target, lookup, depth + 1);
|
|
209
|
+
if (application !== void 0) window.splice(target, application.consumed, ...application.replacement);
|
|
210
|
+
}
|
|
197
211
|
}
|
|
198
212
|
return {
|
|
199
213
|
consumed: last - first + 1,
|
|
@@ -211,12 +225,8 @@ function visibleInputSlot(window, position, skip) {
|
|
|
211
225
|
function applyLookupAtSlot(slots, index, lookup, depth) {
|
|
212
226
|
for (const subtable of lookup.subtables) {
|
|
213
227
|
const application = subtable(slots, index, depth);
|
|
214
|
-
if (application !== void 0)
|
|
215
|
-
slots.splice(index, application.consumed, ...application.replacement);
|
|
216
|
-
return application.replacement.length;
|
|
217
|
-
}
|
|
228
|
+
if (application !== void 0) return application;
|
|
218
229
|
}
|
|
219
|
-
return 0;
|
|
220
230
|
}
|
|
221
231
|
const SUBST_LOOKUP_RECORD_SIZE = 4;
|
|
222
232
|
function readSubstLookupRecords(bytes, offset, count) {
|
|
@@ -361,7 +371,7 @@ function parseSubtable(bytes, lookupType, subtableOffset, skip, lookupOf) {
|
|
|
361
371
|
if (!require_sfnt.hasBytes(bytes, subtableOffset, EXTENSION_SUBST_HEADER_SIZE) || require_sfnt.u16(bytes, subtableOffset) !== 1) return;
|
|
362
372
|
const extensionLookupType = require_sfnt.u16(bytes, subtableOffset + 2);
|
|
363
373
|
if (extensionLookupType === LOOKUP_TYPE_EXTENSION_SUBST) return;
|
|
364
|
-
return parseSubtable(bytes, extensionLookupType, subtableOffset + require_sfnt.u32(bytes, subtableOffset +
|
|
374
|
+
return parseSubtable(bytes, extensionLookupType, subtableOffset + require_sfnt.u32(bytes, subtableOffset + EXTENSION_SUBST_OFFSET_FIELD_OFFSET), skip, lookupOf);
|
|
365
375
|
}
|
|
366
376
|
if (lookupType === LOOKUP_TYPE_SINGLE_SUBST) {
|
|
367
377
|
if (!require_sfnt.hasBytes(bytes, subtableOffset, 2)) return;
|
|
@@ -389,7 +399,7 @@ function parseContextualSubtable(bytes, chained, subtableOffset, skip, lookupOf)
|
|
|
389
399
|
if (!require_sfnt.hasBytes(bytes, subtableOffset, prefixSize)) return;
|
|
390
400
|
const coverage = require_ot_layout_common.parseCoverage(bytes, subtableOffset + require_sfnt.u16(bytes, subtableOffset + 2));
|
|
391
401
|
if (coverage === void 0) return;
|
|
392
|
-
const setCount = require_sfnt.u16(bytes, subtableOffset +
|
|
402
|
+
const setCount = require_sfnt.u16(bytes, subtableOffset + SUBST_FORMAT_AND_COVERAGE_SIZE);
|
|
393
403
|
const setOffsetsOffset = subtableOffset + prefixSize;
|
|
394
404
|
if (!require_sfnt.hasBytes(bytes, setOffsetsOffset, setCount * 2)) return;
|
|
395
405
|
const glyphEquality = (expected) => (glyphId) => glyphId === expected;
|
|
@@ -405,10 +415,10 @@ function parseContextualSubtable(bytes, chained, subtableOffset, skip, lookupOf)
|
|
|
405
415
|
if (!require_sfnt.hasBytes(bytes, subtableOffset, prefixSize)) return;
|
|
406
416
|
const coverage = require_ot_layout_common.parseCoverage(bytes, subtableOffset + require_sfnt.u16(bytes, subtableOffset + 2));
|
|
407
417
|
if (coverage === void 0) return;
|
|
408
|
-
const inputClassDefOffset = chained ? require_sfnt.u16(bytes, subtableOffset + 6) : require_sfnt.u16(bytes, subtableOffset +
|
|
418
|
+
const inputClassDefOffset = chained ? require_sfnt.u16(bytes, subtableOffset + 6) : require_sfnt.u16(bytes, subtableOffset + SUBST_FORMAT_AND_COVERAGE_SIZE);
|
|
409
419
|
const inputClassDef = inputClassDefOffset === 0 ? constantZeroClassDef : require_ot_layout_common.parseClassDef(bytes, subtableOffset + inputClassDefOffset);
|
|
410
420
|
const readAuxClassDef = (offset) => offset === 0 ? constantZeroClassDef : require_ot_layout_common.parseClassDef(bytes, subtableOffset + offset);
|
|
411
|
-
const backtrackClassDef = chained ? readAuxClassDef(require_sfnt.u16(bytes, subtableOffset +
|
|
421
|
+
const backtrackClassDef = chained ? readAuxClassDef(require_sfnt.u16(bytes, subtableOffset + SUBST_FORMAT_AND_COVERAGE_SIZE)) : constantZeroClassDef;
|
|
412
422
|
const lookaheadClassDef = chained ? readAuxClassDef(require_sfnt.u16(bytes, subtableOffset + 8)) : constantZeroClassDef;
|
|
413
423
|
if (inputClassDef === void 0 || backtrackClassDef === void 0 || lookaheadClassDef === void 0) return;
|
|
414
424
|
const setCount = require_sfnt.u16(bytes, subtableOffset + prefixSize - 2);
|
|
@@ -430,9 +440,9 @@ function findScriptOffset(bytes, scriptListOffset) {
|
|
|
430
440
|
if (!require_sfnt.hasBytes(bytes, recordsOffset, scriptCount * SCRIPT_RECORD_SIZE) || scriptCount === 0) return;
|
|
431
441
|
for (const wanted of PREFERRED_SCRIPT_TAGS) for (let i = 0; i < scriptCount; i++) {
|
|
432
442
|
const recordOffset = recordsOffset + i * SCRIPT_RECORD_SIZE;
|
|
433
|
-
if (readTag(bytes, recordOffset) === wanted) return scriptListOffset + require_sfnt.u16(bytes, recordOffset +
|
|
443
|
+
if (readTag(bytes, recordOffset) === wanted) return scriptListOffset + require_sfnt.u16(bytes, recordOffset + SCRIPT_RECORD_OFFSET_FIELD_OFFSET);
|
|
434
444
|
}
|
|
435
|
-
return scriptListOffset + require_sfnt.u16(bytes, recordsOffset +
|
|
445
|
+
return scriptListOffset + require_sfnt.u16(bytes, recordsOffset + SCRIPT_RECORD_OFFSET_FIELD_OFFSET);
|
|
436
446
|
}
|
|
437
447
|
function parseDefaultLangSysFeatureIndices(bytes, scriptOffset) {
|
|
438
448
|
if (!require_sfnt.hasBytes(bytes, scriptOffset, 2)) return [];
|
|
@@ -440,7 +450,7 @@ function parseDefaultLangSysFeatureIndices(bytes, scriptOffset) {
|
|
|
440
450
|
if (defaultLangSysOffset === 0) return [];
|
|
441
451
|
const langSysOffset = scriptOffset + defaultLangSysOffset;
|
|
442
452
|
if (!require_sfnt.hasBytes(bytes, langSysOffset, LANG_SYS_HEADER_SIZE)) return [];
|
|
443
|
-
const featureIndexCount = require_sfnt.u16(bytes, langSysOffset +
|
|
453
|
+
const featureIndexCount = require_sfnt.u16(bytes, langSysOffset + LANG_SYS_FEATURE_INDEX_COUNT_OFFSET);
|
|
444
454
|
const indicesOffset = langSysOffset + LANG_SYS_HEADER_SIZE;
|
|
445
455
|
if (!require_sfnt.hasBytes(bytes, indicesOffset, featureIndexCount * 2)) return [];
|
|
446
456
|
const indices = [];
|
|
@@ -458,7 +468,7 @@ function collectLookupIndices(bytes, featureListOffset, featureIndices, featureT
|
|
|
458
468
|
if (featureIndex >= featureCount) continue;
|
|
459
469
|
const recordOffset = recordsOffset + featureIndex * FEATURE_RECORD_SIZE;
|
|
460
470
|
if (!featureTags.includes(readTag(bytes, recordOffset))) continue;
|
|
461
|
-
const featureOffset = featureListOffset + require_sfnt.u16(bytes, recordOffset +
|
|
471
|
+
const featureOffset = featureListOffset + require_sfnt.u16(bytes, recordOffset + FEATURE_RECORD_OFFSET_FIELD_OFFSET);
|
|
462
472
|
if (!require_sfnt.hasBytes(bytes, featureOffset, FEATURE_HEADER_SIZE)) continue;
|
|
463
473
|
const lookupIndexCount = require_sfnt.u16(bytes, featureOffset + 2);
|
|
464
474
|
const indicesOffset = featureOffset + FEATURE_HEADER_SIZE;
|
|
@@ -476,12 +486,12 @@ function collectLookupIndices(bytes, featureListOffset, featureIndices, featureT
|
|
|
476
486
|
function buildGsubShaper(font, options = {}) {
|
|
477
487
|
const bytes = require_sfnt.sfntTableBytes(font, "GSUB");
|
|
478
488
|
if (bytes === void 0 || !require_sfnt.hasBytes(bytes, 0, GSUB_HEADER_SIZE) || require_sfnt.u16(bytes, 0) !== 1) return;
|
|
479
|
-
const scriptOffset = findScriptOffset(bytes, require_sfnt.u16(bytes,
|
|
489
|
+
const scriptOffset = findScriptOffset(bytes, require_sfnt.u16(bytes, GSUB_HEADER_SCRIPT_LIST_OFFSET));
|
|
480
490
|
if (scriptOffset === void 0) return;
|
|
481
491
|
const featureTags = [...DEFAULT_GSUB_FEATURE_TAGS, ...options.optInFeatures ?? []];
|
|
482
|
-
const lookupIndices = collectLookupIndices(bytes, require_sfnt.u16(bytes,
|
|
492
|
+
const lookupIndices = collectLookupIndices(bytes, require_sfnt.u16(bytes, GSUB_HEADER_FEATURE_LIST_OFFSET), parseDefaultLangSysFeatureIndices(bytes, scriptOffset), featureTags);
|
|
483
493
|
if (lookupIndices.length === 0) return;
|
|
484
|
-
const lookupListOffset = require_sfnt.u16(bytes,
|
|
494
|
+
const lookupListOffset = require_sfnt.u16(bytes, GSUB_HEADER_LOOKUP_LIST_OFFSET);
|
|
485
495
|
if (!require_sfnt.hasBytes(bytes, lookupListOffset, 2)) return;
|
|
486
496
|
const lookupCount = require_sfnt.u16(bytes, lookupListOffset);
|
|
487
497
|
const lookupOffsetsOffset = lookupListOffset + 2;
|
|
@@ -497,7 +507,7 @@ function buildGsubShaper(font, options = {}) {
|
|
|
497
507
|
}
|
|
498
508
|
const lookupFlag = require_sfnt.u16(bytes, lookupOffset + 2);
|
|
499
509
|
const lookupType = require_sfnt.u16(bytes, lookupOffset);
|
|
500
|
-
const subTableCount = require_sfnt.u16(bytes, lookupOffset +
|
|
510
|
+
const subTableCount = require_sfnt.u16(bytes, lookupOffset + LOOKUP_HEADER_SUBTABLE_COUNT_OFFSET);
|
|
501
511
|
const subtableOffsetsOffset = lookupOffset + LOOKUP_HEADER_SIZE;
|
|
502
512
|
const markFilteringSetWidth = (lookupFlag & LOOKUP_FLAG_USE_MARK_FILTERING_SET) !== 0 ? 2 : 0;
|
|
503
513
|
if (!require_sfnt.hasBytes(bytes, subtableOffsetsOffset, subTableCount * 2 + markFilteringSetWidth)) {
|
|
@@ -526,8 +536,13 @@ function buildGsubShaper(font, options = {}) {
|
|
|
526
536
|
for (const lookup of appliedLookups) {
|
|
527
537
|
let slotIndex = 0;
|
|
528
538
|
while (slotIndex < slots.length) {
|
|
529
|
-
const
|
|
530
|
-
|
|
539
|
+
const application = applyLookupAtSlot(slots, slotIndex, lookup, 0);
|
|
540
|
+
if (application === void 0) {
|
|
541
|
+
slotIndex += 1;
|
|
542
|
+
continue;
|
|
543
|
+
}
|
|
544
|
+
slots.splice(slotIndex, application.consumed, ...application.replacement);
|
|
545
|
+
slotIndex += application.replacement.length !== 0 ? application.replacement.length : 1;
|
|
531
546
|
}
|
|
532
547
|
}
|
|
533
548
|
return {
|