pdf-codec 1.7.0 → 1.9.0

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.
Files changed (52) hide show
  1. package/README.md +21 -14
  2. package/dist/content-write.cjs +26 -5
  3. package/dist/content-write.d.cts +1 -1
  4. package/dist/content-write.d.ts +1 -1
  5. package/dist/content-write.js +27 -6
  6. package/dist/{embedded-font-CLedn-mT.d.cts → embedded-font-BU6Jgcof.d.cts} +7 -1
  7. package/dist/{embedded-font-CbqkKgBl.d.ts → embedded-font-fREdbxnr.d.ts} +7 -1
  8. package/dist/embedded-font-write.d.cts +1 -1
  9. package/dist/embedded-font-write.d.ts +1 -1
  10. package/dist/embedded-font.cjs +22 -5
  11. package/dist/embedded-font.d.cts +2 -2
  12. package/dist/embedded-font.d.ts +2 -2
  13. package/dist/embedded-font.js +22 -5
  14. package/dist/{font-registry-yby02snZ.d.cts → font-registry-B5qL0Vi0.d.cts} +1 -1
  15. package/dist/{font-registry-Cn7P9lAh.d.ts → font-registry-mgdbNP8_.d.ts} +1 -1
  16. package/dist/font-registry.d.cts +1 -1
  17. package/dist/font-registry.d.ts +1 -1
  18. package/dist/formula.d.cts +1 -1
  19. package/dist/formula.d.ts +1 -1
  20. package/dist/gpos-table.cjs +189 -0
  21. package/dist/gpos-table.d.cts +6 -0
  22. package/dist/gpos-table.d.ts +6 -0
  23. package/dist/gpos-table.js +188 -0
  24. package/dist/index.d.cts +6 -6
  25. package/dist/index.d.ts +6 -6
  26. package/dist/math-content-write.cjs +37 -1
  27. package/dist/math-content-write.d.cts +1 -1
  28. package/dist/math-content-write.d.ts +1 -1
  29. package/dist/math-content-write.js +38 -2
  30. package/dist/math-font-write.cjs +6 -1
  31. package/dist/math-font-write.d.cts +1 -1
  32. package/dist/math-font-write.d.ts +1 -1
  33. package/dist/math-font-write.js +6 -1
  34. package/dist/math-font.cjs +48 -0
  35. package/dist/math-font.d.cts +1 -1
  36. package/dist/math-font.d.ts +1 -1
  37. package/dist/math-font.js +48 -0
  38. package/dist/math-table.cjs +7 -21
  39. package/dist/math-table.js +7 -21
  40. package/dist/{math-types-YSQUTviw.d.ts → math-types-BZkWO5Ow.d.cts} +28 -2
  41. package/dist/{math-types-YSQUTviw.d.cts → math-types-Bq7tyV4g.d.ts} +28 -2
  42. package/dist/math-types.d.cts +3 -2
  43. package/dist/math-types.d.ts +3 -2
  44. package/dist/measure.d.cts +1 -1
  45. package/dist/measure.d.ts +1 -1
  46. package/dist/ot-layout-common.cjs +95 -0
  47. package/dist/ot-layout-common.d.cts +10 -0
  48. package/dist/ot-layout-common.d.ts +10 -0
  49. package/dist/ot-layout-common.js +93 -0
  50. package/dist/write.d.cts +2 -2
  51. package/dist/write.d.ts +2 -2
  52. package/package.json +1 -1
@@ -0,0 +1,189 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_sfnt = require("./sfnt.cjs");
3
+ const require_ot_layout_common = require("./ot-layout-common.cjs");
4
+ //#region src/gpos-table.ts
5
+ const GPOS_HEADER_SIZE = 10;
6
+ const SCRIPT_RECORD_SIZE = 6;
7
+ const FEATURE_RECORD_SIZE = 6;
8
+ const LANG_SYS_HEADER_SIZE = 6;
9
+ const FEATURE_HEADER_SIZE = 4;
10
+ const LOOKUP_HEADER_SIZE = 6;
11
+ const EXTENSION_POS_HEADER_SIZE = 8;
12
+ const LOOKUP_TYPE_PAIR_POS = 2;
13
+ const LOOKUP_TYPE_EXTENSION_POS = 9;
14
+ const KERN_FEATURE_TAG = "kern";
15
+ const PREFERRED_SCRIPT_TAGS = ["latn", "DFLT"];
16
+ 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 + 3));
18
+ }
19
+ function valueRecordSize(valueFormat) {
20
+ let size = 0;
21
+ for (let bit = valueFormat; bit !== 0; bit >>= 1) size += (bit & 1) * 2;
22
+ return size;
23
+ }
24
+ const VALUE_FORMAT_X_ADVANCE = 4;
25
+ function xAdvanceOffset(valueFormat) {
26
+ if ((valueFormat & VALUE_FORMAT_X_ADVANCE) === 0) return;
27
+ return valueRecordSize(valueFormat & 3);
28
+ }
29
+ const PAIR_POS_FORMAT_1_HEADER_SIZE = 10;
30
+ const PAIR_VALUE_RECORD_GLYPH_SIZE = 2;
31
+ function parsePairPosFormat1(bytes, subtableOffset) {
32
+ if (!require_sfnt.hasBytes(bytes, subtableOffset, PAIR_POS_FORMAT_1_HEADER_SIZE)) return;
33
+ const coverage = require_ot_layout_common.parseCoverage(bytes, subtableOffset + require_sfnt.u16(bytes, subtableOffset + 2));
34
+ if (coverage === void 0) return;
35
+ const valueFormat1 = require_sfnt.u16(bytes, subtableOffset + 4);
36
+ const valueFormat2 = require_sfnt.u16(bytes, subtableOffset + 6);
37
+ const pairSetCount = require_sfnt.u16(bytes, subtableOffset + 8);
38
+ const pairSetOffsetsOffset = subtableOffset + PAIR_POS_FORMAT_1_HEADER_SIZE;
39
+ if (!require_sfnt.hasBytes(bytes, pairSetOffsetsOffset, pairSetCount * 2)) return;
40
+ const recordSize = PAIR_VALUE_RECORD_GLYPH_SIZE + valueRecordSize(valueFormat1) + valueRecordSize(valueFormat2);
41
+ const advanceOffset = xAdvanceOffset(valueFormat1);
42
+ return (leftGlyphId, rightGlyphId) => {
43
+ const coverageIndex = coverage.coverageIndex(leftGlyphId);
44
+ if (coverageIndex === void 0 || coverageIndex >= pairSetCount) return;
45
+ const pairSetOffset = subtableOffset + require_sfnt.u16(bytes, pairSetOffsetsOffset + coverageIndex * 2);
46
+ if (!require_sfnt.hasBytes(bytes, pairSetOffset, 2)) return;
47
+ const pairValueCount = require_sfnt.u16(bytes, pairSetOffset);
48
+ const recordsOffset = pairSetOffset + 2;
49
+ if (!require_sfnt.hasBytes(bytes, recordsOffset, pairValueCount * recordSize)) return;
50
+ let low = 0;
51
+ let high = pairValueCount - 1;
52
+ while (low <= high) {
53
+ const mid = low + high >> 1;
54
+ const recordOffset = recordsOffset + mid * recordSize;
55
+ const secondGlyph = require_sfnt.u16(bytes, recordOffset);
56
+ if (rightGlyphId < secondGlyph) high = mid - 1;
57
+ else if (rightGlyphId > secondGlyph) low = mid + 1;
58
+ else return advanceOffset === void 0 ? 0 : require_sfnt.i16(bytes, recordOffset + PAIR_VALUE_RECORD_GLYPH_SIZE + advanceOffset);
59
+ }
60
+ };
61
+ }
62
+ const PAIR_POS_FORMAT_2_HEADER_SIZE = 16;
63
+ function parsePairPosFormat2(bytes, subtableOffset) {
64
+ if (!require_sfnt.hasBytes(bytes, subtableOffset, PAIR_POS_FORMAT_2_HEADER_SIZE)) return;
65
+ 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 + 8));
67
+ const classDef2 = require_ot_layout_common.parseClassDef(bytes, subtableOffset + require_sfnt.u16(bytes, subtableOffset + 10));
68
+ if (coverage === void 0 || classDef1 === void 0 || classDef2 === void 0) return;
69
+ const valueFormat1 = require_sfnt.u16(bytes, subtableOffset + 4);
70
+ const valueFormat2 = require_sfnt.u16(bytes, subtableOffset + 6);
71
+ const class1Count = require_sfnt.u16(bytes, subtableOffset + 12);
72
+ const class2Count = require_sfnt.u16(bytes, subtableOffset + 14);
73
+ const class2RecordSize = valueRecordSize(valueFormat1) + valueRecordSize(valueFormat2);
74
+ const class1RecordSize = class2Count * class2RecordSize;
75
+ const matrixOffset = subtableOffset + PAIR_POS_FORMAT_2_HEADER_SIZE;
76
+ if (!require_sfnt.hasBytes(bytes, matrixOffset, class1Count * class1RecordSize)) return;
77
+ const advanceOffset = xAdvanceOffset(valueFormat1);
78
+ return (leftGlyphId, rightGlyphId) => {
79
+ if (coverage.coverageIndex(leftGlyphId) === void 0) return;
80
+ const class1 = classDef1(leftGlyphId);
81
+ const class2 = classDef2(rightGlyphId);
82
+ if (class1 >= class1Count || class2 >= class2Count) return;
83
+ if (advanceOffset === void 0) return 0;
84
+ return require_sfnt.i16(bytes, matrixOffset + class1 * class1RecordSize + class2 * class2RecordSize + advanceOffset);
85
+ };
86
+ }
87
+ function parseSubtable(bytes, lookupType, subtableOffset) {
88
+ if (lookupType === LOOKUP_TYPE_EXTENSION_POS) {
89
+ if (!require_sfnt.hasBytes(bytes, subtableOffset, EXTENSION_POS_HEADER_SIZE) || require_sfnt.u16(bytes, subtableOffset) !== 1) return;
90
+ const extensionLookupType = require_sfnt.u16(bytes, subtableOffset + 2);
91
+ if (extensionLookupType === LOOKUP_TYPE_EXTENSION_POS) return;
92
+ return parseSubtable(bytes, extensionLookupType, subtableOffset + require_sfnt.u32(bytes, subtableOffset + 4));
93
+ }
94
+ if (lookupType !== LOOKUP_TYPE_PAIR_POS) return;
95
+ if (!require_sfnt.hasBytes(bytes, subtableOffset, 2)) return;
96
+ const posFormat = require_sfnt.u16(bytes, subtableOffset);
97
+ if (posFormat === 1) return parsePairPosFormat1(bytes, subtableOffset);
98
+ if (posFormat === 2) return parsePairPosFormat2(bytes, subtableOffset);
99
+ }
100
+ function parseLookupSubtables(bytes, lookupOffset) {
101
+ if (!require_sfnt.hasBytes(bytes, lookupOffset, LOOKUP_HEADER_SIZE)) return [];
102
+ const lookupType = require_sfnt.u16(bytes, lookupOffset);
103
+ const subTableCount = require_sfnt.u16(bytes, lookupOffset + 4);
104
+ const offsetsOffset = lookupOffset + LOOKUP_HEADER_SIZE;
105
+ if (!require_sfnt.hasBytes(bytes, offsetsOffset, subTableCount * 2)) return [];
106
+ const subtables = [];
107
+ for (let i = 0; i < subTableCount; i++) {
108
+ const subtable = parseSubtable(bytes, lookupType, lookupOffset + require_sfnt.u16(bytes, offsetsOffset + i * 2));
109
+ if (subtable !== void 0) subtables.push(subtable);
110
+ }
111
+ return subtables;
112
+ }
113
+ function parseDefaultLangSysFeatureIndices(bytes, scriptOffset) {
114
+ if (!require_sfnt.hasBytes(bytes, scriptOffset, 2)) return [];
115
+ const defaultLangSysOffset = require_sfnt.u16(bytes, scriptOffset);
116
+ if (defaultLangSysOffset === 0) return [];
117
+ const langSysOffset = scriptOffset + defaultLangSysOffset;
118
+ if (!require_sfnt.hasBytes(bytes, langSysOffset, LANG_SYS_HEADER_SIZE)) return [];
119
+ const featureIndexCount = require_sfnt.u16(bytes, langSysOffset + 4);
120
+ const indicesOffset = langSysOffset + LANG_SYS_HEADER_SIZE;
121
+ if (!require_sfnt.hasBytes(bytes, indicesOffset, featureIndexCount * 2)) return [];
122
+ const indices = [];
123
+ for (let i = 0; i < featureIndexCount; i++) indices.push(require_sfnt.u16(bytes, indicesOffset + i * 2));
124
+ return indices;
125
+ }
126
+ function findScriptOffset(bytes, scriptListOffset) {
127
+ if (!require_sfnt.hasBytes(bytes, scriptListOffset, 2)) return;
128
+ const scriptCount = require_sfnt.u16(bytes, scriptListOffset);
129
+ const recordsOffset = scriptListOffset + 2;
130
+ if (!require_sfnt.hasBytes(bytes, recordsOffset, scriptCount * SCRIPT_RECORD_SIZE) || scriptCount === 0) return;
131
+ for (const wanted of PREFERRED_SCRIPT_TAGS) for (let i = 0; i < scriptCount; i++) {
132
+ const recordOffset = recordsOffset + i * SCRIPT_RECORD_SIZE;
133
+ if (readTag(bytes, recordOffset) === wanted) return scriptListOffset + require_sfnt.u16(bytes, recordOffset + 4);
134
+ }
135
+ return scriptListOffset + require_sfnt.u16(bytes, recordsOffset + 4);
136
+ }
137
+ function collectKernLookupIndices(bytes, featureListOffset, featureIndices) {
138
+ if (!require_sfnt.hasBytes(bytes, featureListOffset, 2)) return [];
139
+ const featureCount = require_sfnt.u16(bytes, featureListOffset);
140
+ const recordsOffset = featureListOffset + 2;
141
+ if (!require_sfnt.hasBytes(bytes, recordsOffset, featureCount * FEATURE_RECORD_SIZE)) return [];
142
+ const lookupIndices = [];
143
+ const seen = /* @__PURE__ */ new Set();
144
+ for (const featureIndex of featureIndices) {
145
+ if (featureIndex >= featureCount) continue;
146
+ const recordOffset = recordsOffset + featureIndex * FEATURE_RECORD_SIZE;
147
+ if (readTag(bytes, recordOffset) !== KERN_FEATURE_TAG) continue;
148
+ const featureOffset = featureListOffset + require_sfnt.u16(bytes, recordOffset + 4);
149
+ if (!require_sfnt.hasBytes(bytes, featureOffset, FEATURE_HEADER_SIZE)) continue;
150
+ const lookupIndexCount = require_sfnt.u16(bytes, featureOffset + 2);
151
+ const indicesOffset = featureOffset + FEATURE_HEADER_SIZE;
152
+ if (!require_sfnt.hasBytes(bytes, indicesOffset, lookupIndexCount * 2)) continue;
153
+ for (let i = 0; i < lookupIndexCount; i++) {
154
+ const lookupIndex = require_sfnt.u16(bytes, indicesOffset + i * 2);
155
+ if (!seen.has(lookupIndex)) {
156
+ seen.add(lookupIndex);
157
+ lookupIndices.push(lookupIndex);
158
+ }
159
+ }
160
+ }
161
+ return lookupIndices;
162
+ }
163
+ function buildGposKernLookup(font) {
164
+ const bytes = require_sfnt.sfntTableBytes(font, "GPOS");
165
+ 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, 4));
167
+ if (scriptOffset === void 0) return;
168
+ const lookupIndices = collectKernLookupIndices(bytes, require_sfnt.u16(bytes, 6), parseDefaultLangSysFeatureIndices(bytes, scriptOffset));
169
+ if (lookupIndices.length === 0) return;
170
+ const lookupListOffset = require_sfnt.u16(bytes, 8);
171
+ if (!require_sfnt.hasBytes(bytes, lookupListOffset, 2)) return;
172
+ const lookupCount = require_sfnt.u16(bytes, lookupListOffset);
173
+ const lookupOffsetsOffset = lookupListOffset + 2;
174
+ if (!require_sfnt.hasBytes(bytes, lookupOffsetsOffset, lookupCount * 2)) return;
175
+ const subtables = [];
176
+ for (const lookupIndex of lookupIndices) {
177
+ if (lookupIndex >= lookupCount) continue;
178
+ subtables.push(...parseLookupSubtables(bytes, lookupListOffset + require_sfnt.u16(bytes, lookupOffsetsOffset + lookupIndex * 2)));
179
+ }
180
+ if (subtables.length === 0) return;
181
+ return (leftGlyphId, rightGlyphId) => {
182
+ for (const subtable of subtables) {
183
+ const adjustment = subtable(leftGlyphId, rightGlyphId);
184
+ if (adjustment !== void 0) return adjustment;
185
+ }
186
+ };
187
+ }
188
+ //#endregion
189
+ exports.buildGposKernLookup = buildGposKernLookup;
@@ -0,0 +1,6 @@
1
+ import { t as SfntFont } from "./sfnt-V08bb5ut.cjs";
2
+ //#region src/gpos-table.d.ts
3
+ type GposKernLookup = (leftGlyphId: number, rightGlyphId: number) => number | undefined;
4
+ declare function buildGposKernLookup(font: SfntFont): GposKernLookup | undefined;
5
+ //#endregion
6
+ export { GposKernLookup, buildGposKernLookup };
@@ -0,0 +1,6 @@
1
+ import { t as SfntFont } from "./sfnt-V08bb5ut.js";
2
+ //#region src/gpos-table.d.ts
3
+ type GposKernLookup = (leftGlyphId: number, rightGlyphId: number) => number | undefined;
4
+ declare function buildGposKernLookup(font: SfntFont): GposKernLookup | undefined;
5
+ //#endregion
6
+ export { GposKernLookup, buildGposKernLookup };
@@ -0,0 +1,188 @@
1
+ import { hasBytes, i16, sfntTableBytes, u16, u32, u8 } from "./sfnt.js";
2
+ import { parseClassDef, parseCoverage } from "./ot-layout-common.js";
3
+ //#region src/gpos-table.ts
4
+ const GPOS_HEADER_SIZE = 10;
5
+ const SCRIPT_RECORD_SIZE = 6;
6
+ const FEATURE_RECORD_SIZE = 6;
7
+ const LANG_SYS_HEADER_SIZE = 6;
8
+ const FEATURE_HEADER_SIZE = 4;
9
+ const LOOKUP_HEADER_SIZE = 6;
10
+ const EXTENSION_POS_HEADER_SIZE = 8;
11
+ const LOOKUP_TYPE_PAIR_POS = 2;
12
+ const LOOKUP_TYPE_EXTENSION_POS = 9;
13
+ const KERN_FEATURE_TAG = "kern";
14
+ const PREFERRED_SCRIPT_TAGS = ["latn", "DFLT"];
15
+ function readTag(bytes, offset) {
16
+ return String.fromCharCode(u8(bytes, offset), u8(bytes, offset + 1), u8(bytes, offset + 2), u8(bytes, offset + 3));
17
+ }
18
+ function valueRecordSize(valueFormat) {
19
+ let size = 0;
20
+ for (let bit = valueFormat; bit !== 0; bit >>= 1) size += (bit & 1) * 2;
21
+ return size;
22
+ }
23
+ const VALUE_FORMAT_X_ADVANCE = 4;
24
+ function xAdvanceOffset(valueFormat) {
25
+ if ((valueFormat & VALUE_FORMAT_X_ADVANCE) === 0) return;
26
+ return valueRecordSize(valueFormat & 3);
27
+ }
28
+ const PAIR_POS_FORMAT_1_HEADER_SIZE = 10;
29
+ const PAIR_VALUE_RECORD_GLYPH_SIZE = 2;
30
+ function parsePairPosFormat1(bytes, subtableOffset) {
31
+ if (!hasBytes(bytes, subtableOffset, PAIR_POS_FORMAT_1_HEADER_SIZE)) return;
32
+ const coverage = parseCoverage(bytes, subtableOffset + u16(bytes, subtableOffset + 2));
33
+ if (coverage === void 0) return;
34
+ const valueFormat1 = u16(bytes, subtableOffset + 4);
35
+ const valueFormat2 = u16(bytes, subtableOffset + 6);
36
+ const pairSetCount = u16(bytes, subtableOffset + 8);
37
+ const pairSetOffsetsOffset = subtableOffset + PAIR_POS_FORMAT_1_HEADER_SIZE;
38
+ if (!hasBytes(bytes, pairSetOffsetsOffset, pairSetCount * 2)) return;
39
+ const recordSize = PAIR_VALUE_RECORD_GLYPH_SIZE + valueRecordSize(valueFormat1) + valueRecordSize(valueFormat2);
40
+ const advanceOffset = xAdvanceOffset(valueFormat1);
41
+ return (leftGlyphId, rightGlyphId) => {
42
+ const coverageIndex = coverage.coverageIndex(leftGlyphId);
43
+ if (coverageIndex === void 0 || coverageIndex >= pairSetCount) return;
44
+ const pairSetOffset = subtableOffset + u16(bytes, pairSetOffsetsOffset + coverageIndex * 2);
45
+ if (!hasBytes(bytes, pairSetOffset, 2)) return;
46
+ const pairValueCount = u16(bytes, pairSetOffset);
47
+ const recordsOffset = pairSetOffset + 2;
48
+ if (!hasBytes(bytes, recordsOffset, pairValueCount * recordSize)) return;
49
+ let low = 0;
50
+ let high = pairValueCount - 1;
51
+ while (low <= high) {
52
+ const mid = low + high >> 1;
53
+ const recordOffset = recordsOffset + mid * recordSize;
54
+ const secondGlyph = u16(bytes, recordOffset);
55
+ if (rightGlyphId < secondGlyph) high = mid - 1;
56
+ else if (rightGlyphId > secondGlyph) low = mid + 1;
57
+ else return advanceOffset === void 0 ? 0 : i16(bytes, recordOffset + PAIR_VALUE_RECORD_GLYPH_SIZE + advanceOffset);
58
+ }
59
+ };
60
+ }
61
+ const PAIR_POS_FORMAT_2_HEADER_SIZE = 16;
62
+ function parsePairPosFormat2(bytes, subtableOffset) {
63
+ if (!hasBytes(bytes, subtableOffset, PAIR_POS_FORMAT_2_HEADER_SIZE)) return;
64
+ const coverage = parseCoverage(bytes, subtableOffset + u16(bytes, subtableOffset + 2));
65
+ const classDef1 = parseClassDef(bytes, subtableOffset + u16(bytes, subtableOffset + 8));
66
+ const classDef2 = parseClassDef(bytes, subtableOffset + u16(bytes, subtableOffset + 10));
67
+ if (coverage === void 0 || classDef1 === void 0 || classDef2 === void 0) return;
68
+ const valueFormat1 = u16(bytes, subtableOffset + 4);
69
+ const valueFormat2 = u16(bytes, subtableOffset + 6);
70
+ const class1Count = u16(bytes, subtableOffset + 12);
71
+ const class2Count = u16(bytes, subtableOffset + 14);
72
+ const class2RecordSize = valueRecordSize(valueFormat1) + valueRecordSize(valueFormat2);
73
+ const class1RecordSize = class2Count * class2RecordSize;
74
+ const matrixOffset = subtableOffset + PAIR_POS_FORMAT_2_HEADER_SIZE;
75
+ if (!hasBytes(bytes, matrixOffset, class1Count * class1RecordSize)) return;
76
+ const advanceOffset = xAdvanceOffset(valueFormat1);
77
+ return (leftGlyphId, rightGlyphId) => {
78
+ if (coverage.coverageIndex(leftGlyphId) === void 0) return;
79
+ const class1 = classDef1(leftGlyphId);
80
+ const class2 = classDef2(rightGlyphId);
81
+ if (class1 >= class1Count || class2 >= class2Count) return;
82
+ if (advanceOffset === void 0) return 0;
83
+ return i16(bytes, matrixOffset + class1 * class1RecordSize + class2 * class2RecordSize + advanceOffset);
84
+ };
85
+ }
86
+ function parseSubtable(bytes, lookupType, subtableOffset) {
87
+ if (lookupType === LOOKUP_TYPE_EXTENSION_POS) {
88
+ if (!hasBytes(bytes, subtableOffset, EXTENSION_POS_HEADER_SIZE) || u16(bytes, subtableOffset) !== 1) return;
89
+ const extensionLookupType = u16(bytes, subtableOffset + 2);
90
+ if (extensionLookupType === LOOKUP_TYPE_EXTENSION_POS) return;
91
+ return parseSubtable(bytes, extensionLookupType, subtableOffset + u32(bytes, subtableOffset + 4));
92
+ }
93
+ if (lookupType !== LOOKUP_TYPE_PAIR_POS) return;
94
+ if (!hasBytes(bytes, subtableOffset, 2)) return;
95
+ const posFormat = u16(bytes, subtableOffset);
96
+ if (posFormat === 1) return parsePairPosFormat1(bytes, subtableOffset);
97
+ if (posFormat === 2) return parsePairPosFormat2(bytes, subtableOffset);
98
+ }
99
+ function parseLookupSubtables(bytes, lookupOffset) {
100
+ if (!hasBytes(bytes, lookupOffset, LOOKUP_HEADER_SIZE)) return [];
101
+ const lookupType = u16(bytes, lookupOffset);
102
+ const subTableCount = u16(bytes, lookupOffset + 4);
103
+ const offsetsOffset = lookupOffset + LOOKUP_HEADER_SIZE;
104
+ if (!hasBytes(bytes, offsetsOffset, subTableCount * 2)) return [];
105
+ const subtables = [];
106
+ for (let i = 0; i < subTableCount; i++) {
107
+ const subtable = parseSubtable(bytes, lookupType, lookupOffset + u16(bytes, offsetsOffset + i * 2));
108
+ if (subtable !== void 0) subtables.push(subtable);
109
+ }
110
+ return subtables;
111
+ }
112
+ function parseDefaultLangSysFeatureIndices(bytes, scriptOffset) {
113
+ if (!hasBytes(bytes, scriptOffset, 2)) return [];
114
+ const defaultLangSysOffset = u16(bytes, scriptOffset);
115
+ if (defaultLangSysOffset === 0) return [];
116
+ const langSysOffset = scriptOffset + defaultLangSysOffset;
117
+ if (!hasBytes(bytes, langSysOffset, LANG_SYS_HEADER_SIZE)) return [];
118
+ const featureIndexCount = u16(bytes, langSysOffset + 4);
119
+ const indicesOffset = langSysOffset + LANG_SYS_HEADER_SIZE;
120
+ if (!hasBytes(bytes, indicesOffset, featureIndexCount * 2)) return [];
121
+ const indices = [];
122
+ for (let i = 0; i < featureIndexCount; i++) indices.push(u16(bytes, indicesOffset + i * 2));
123
+ return indices;
124
+ }
125
+ function findScriptOffset(bytes, scriptListOffset) {
126
+ if (!hasBytes(bytes, scriptListOffset, 2)) return;
127
+ const scriptCount = u16(bytes, scriptListOffset);
128
+ const recordsOffset = scriptListOffset + 2;
129
+ if (!hasBytes(bytes, recordsOffset, scriptCount * SCRIPT_RECORD_SIZE) || scriptCount === 0) return;
130
+ for (const wanted of PREFERRED_SCRIPT_TAGS) for (let i = 0; i < scriptCount; i++) {
131
+ const recordOffset = recordsOffset + i * SCRIPT_RECORD_SIZE;
132
+ if (readTag(bytes, recordOffset) === wanted) return scriptListOffset + u16(bytes, recordOffset + 4);
133
+ }
134
+ return scriptListOffset + u16(bytes, recordsOffset + 4);
135
+ }
136
+ function collectKernLookupIndices(bytes, featureListOffset, featureIndices) {
137
+ if (!hasBytes(bytes, featureListOffset, 2)) return [];
138
+ const featureCount = u16(bytes, featureListOffset);
139
+ const recordsOffset = featureListOffset + 2;
140
+ if (!hasBytes(bytes, recordsOffset, featureCount * FEATURE_RECORD_SIZE)) return [];
141
+ const lookupIndices = [];
142
+ const seen = /* @__PURE__ */ new Set();
143
+ for (const featureIndex of featureIndices) {
144
+ if (featureIndex >= featureCount) continue;
145
+ const recordOffset = recordsOffset + featureIndex * FEATURE_RECORD_SIZE;
146
+ if (readTag(bytes, recordOffset) !== KERN_FEATURE_TAG) continue;
147
+ const featureOffset = featureListOffset + u16(bytes, recordOffset + 4);
148
+ if (!hasBytes(bytes, featureOffset, FEATURE_HEADER_SIZE)) continue;
149
+ const lookupIndexCount = u16(bytes, featureOffset + 2);
150
+ const indicesOffset = featureOffset + FEATURE_HEADER_SIZE;
151
+ if (!hasBytes(bytes, indicesOffset, lookupIndexCount * 2)) continue;
152
+ for (let i = 0; i < lookupIndexCount; i++) {
153
+ const lookupIndex = u16(bytes, indicesOffset + i * 2);
154
+ if (!seen.has(lookupIndex)) {
155
+ seen.add(lookupIndex);
156
+ lookupIndices.push(lookupIndex);
157
+ }
158
+ }
159
+ }
160
+ return lookupIndices;
161
+ }
162
+ function buildGposKernLookup(font) {
163
+ const bytes = sfntTableBytes(font, "GPOS");
164
+ if (bytes === void 0 || !hasBytes(bytes, 0, GPOS_HEADER_SIZE) || u16(bytes, 0) !== 1) return;
165
+ const scriptOffset = findScriptOffset(bytes, u16(bytes, 4));
166
+ if (scriptOffset === void 0) return;
167
+ const lookupIndices = collectKernLookupIndices(bytes, u16(bytes, 6), parseDefaultLangSysFeatureIndices(bytes, scriptOffset));
168
+ if (lookupIndices.length === 0) return;
169
+ const lookupListOffset = u16(bytes, 8);
170
+ if (!hasBytes(bytes, lookupListOffset, 2)) return;
171
+ const lookupCount = u16(bytes, lookupListOffset);
172
+ const lookupOffsetsOffset = lookupListOffset + 2;
173
+ if (!hasBytes(bytes, lookupOffsetsOffset, lookupCount * 2)) return;
174
+ const subtables = [];
175
+ for (const lookupIndex of lookupIndices) {
176
+ if (lookupIndex >= lookupCount) continue;
177
+ subtables.push(...parseLookupSubtables(bytes, lookupListOffset + u16(bytes, lookupOffsetsOffset + lookupIndex * 2)));
178
+ }
179
+ if (subtables.length === 0) return;
180
+ return (leftGlyphId, rightGlyphId) => {
181
+ for (const subtable of subtables) {
182
+ const adjustment = subtable(leftGlyphId, rightGlyphId);
183
+ if (adjustment !== void 0) return adjustment;
184
+ }
185
+ };
186
+ }
187
+ //#endregion
188
+ export { buildGposKernLookup };
package/dist/index.d.cts CHANGED
@@ -6,13 +6,15 @@ import { ByteWriter, concatBytes } from "./bytes/writer.cjs";
6
6
  import { t as GlyphInkBounds } from "./glyph-bounds-BV_Z40KS.cjs";
7
7
  import { NOOP_DIAGNOSTIC_SINK, PdfDiagnostic, PdfDiagnosticSeverity, PdfDiagnosticSink, PdfEncryptedError, PdfParseError, PdfPasswordRequiredError } from "./diagnostics.cjs";
8
8
  import { PdfBytesSchema, pdfCodec } from "./codec.cjs";
9
- import { n as EmbeddedFaceMetrics, r as EmbeddedFaceSubstitution, t as EmbeddedFace } from "./embedded-font-CLedn-mT.cjs";
10
- import { a as ResolvedFace, i as ProvidedFont, n as FontRegistryOptions, o as createFontRegistry, r as FontSubstitution, s as resolveFaceWithRegistry, t as FontRegistry } from "./font-registry-yby02snZ.cjs";
9
+ import { n as EmbeddedFaceMetrics, r as EmbeddedFaceSubstitution, t as EmbeddedFace } from "./embedded-font-BU6Jgcof.cjs";
10
+ import { a as ResolvedFace, i as ProvidedFont, n as FontRegistryOptions, o as createFontRegistry, r as FontSubstitution, s as resolveFaceWithRegistry, t as FontRegistry } from "./font-registry-B5qL0Vi0.cjs";
11
11
  import { DEFAULT_VERTICAL_METRIC_POLICY, FontMeasurerOptions, StandardFontMeasurerOptions, TextMeasurer, UnderlineMetrics, VerticalMetricPolicy, createFontMeasurer, createStandardFontMeasurer } from "./measure.cjs";
12
12
  import { WinAnsiSubstitution } from "./winansi.cjs";
13
13
  import { i as Point, u as rotatePointAboutCenter } from "./matrix-BHzJESll.cjs";
14
14
  import { ResolvedFont, resolveStandardFont } from "./fonts.cjs";
15
- import { a as MathGlyphRun, c as MathStroke, i as MathGlyphMetrics, n as MathColor, o as MathLayoutItem, r as MathFontMetrics, s as MathRule, t as MathBox } from "./math-types-YSQUTviw.cjs";
15
+ import { a as MathGlyphPart, c as MathVariants, n as MathGlyphAssembly, o as MathGlyphVariant, r as MathGlyphConstruction } from "./math-table-gFNB8DmQ.cjs";
16
+ import { a as assembleStretchyGlyph, i as MathStretchPlacement, n as MathStretchConstruction, o as scaleMathStretchConstruction, r as MathStretchOptions, t as MathStretchAxis } from "./math-stretch-DXWjs8gL.cjs";
17
+ import { a as MathGlyphMetrics, c as MathLayoutItem, d as MathStretchResult, f as MathStroke, i as MathFontMetrics, l as MathRule, n as MathBox, o as MathGlyphPlacement, r as MathColor, s as MathGlyphRun, t as MathAssembledGlyphs, u as MathStretchGlyph } from "./math-types-BZkWO5Ow.cjs";
16
18
  import { PositionedFormula } from "./formula.cjs";
17
19
  import { CcittFaxImage, CcittFaxOptions, decodeCcittFax } from "./image/ccitt.cjs";
18
20
  import { n as Jbig2UnsupportedError, t as Jbig2ParseError } from "./jbig2-errors-Bj6MPxrx.cjs";
@@ -27,8 +29,6 @@ import { PngEncodeOptions, encodePng } from "./image/png-encode.cjs";
27
29
  import { PngFilterType, filterScanlines, unfilterScanlines } from "./image/png-filter.cjs";
28
30
  import { ReadPdfOptions, readPdf } from "./read.cjs";
29
31
  import { WritePdfOptions, writePdf } from "./write.cjs";
30
- import { a as MathGlyphPart, c as MathVariants, n as MathGlyphAssembly, o as MathGlyphVariant, r as MathGlyphConstruction } from "./math-table-gFNB8DmQ.cjs";
31
- import { a as assembleStretchyGlyph, i as MathStretchPlacement, n as MathStretchConstruction, o as scaleMathStretchConstruction, r as MathStretchOptions, t as MathStretchAxis } from "./math-stretch-DXWjs8gL.cjs";
32
32
  import { LoadedMathFont, MathFont, MathFontDescriptorMetrics, loadMathFont } from "./math-font.cjs";
33
33
  import { StyledFragment, StyledRun, WrapOptions, WrappedLine, wrapRunsToWidth } from "./text-layout.cjs";
34
- export { ByteReader, ByteWriter, type CcittFaxImage, type CcittFaxOptions, DEFAULT_VERTICAL_METRIC_POLICY, type DeflateLevel, type EmbeddedFace, type EmbeddedFaceMetrics, type EmbeddedFaceSubstitution, type FontMeasurerOptions, type FontMetrics, type FontRegistry, type FontRegistryOptions, type FontSubstitution, type GlyphInkBounds, type InflateResult, type Jbig2DecodeOptions, type Jbig2Image, Jbig2ParseError, Jbig2UnsupportedError, type Jp2ChannelDefinition, type Jp2ColourSpace, type Jp2Container, type Jp2ImageHeader, type Jpeg2000ComponentMetadata, type Jpeg2000DecodeOptions, type Jpeg2000Image, type Jpeg2000Metadata, Jpeg2000ParseError, type Jpeg2000ProgressionOrder, type Jpeg2000QuantizationStyle, type Jpeg2000Transform, Jpeg2000UnsupportedError, type JpegInfo, type LoadedMathFont, MAX_INFLATE_OUTPUT_BYTES, type MathBox, type MathColor, type MathFont, type MathFontDescriptorMetrics, type MathFontMetrics, type MathGlyphAssembly, type MathGlyphConstruction, type MathGlyphMetrics, type MathGlyphPart, type MathGlyphRun, type MathGlyphVariant, type MathLayoutItem, type MathRule, type MathStretchAxis, type MathStretchConstruction, type MathStretchOptions, type MathStretchPlacement, type MathStroke, type MathVariants, NOOP_DIAGNOSTIC_SINK, PdfBytesSchema, type PdfDiagnostic, type PdfDiagnosticSeverity, type PdfDiagnosticSink, PdfEncryptedError, PdfParseError, PdfPasswordRequiredError, type PngDecodeOptions, type PngEncodeOptions, type PngFilterType, type Point, type PositionedFormula, type ProvidedFont, type RawImage, type ReadPdfOptions, type ResolvedFace, type ResolvedFont, STANDARD_METRICS, type StandardFontMeasurerOptions, type StandardFontName, type StyledFragment, type StyledRun, type TextMeasurer, type UnderlineMetrics, type VerticalMetricPolicy, type WinAnsiSubstitution, type WrapOptions, type WrappedLine, type WritePdfOptions, assembleStretchyGlyph, concatBytes, crc32, createFontMeasurer, createFontRegistry, createStandardFontMeasurer, decodeCcittFax, decodeJbig2Embedded, decodeJpeg2000, decodePng, deflate, encodePng, filterScanlines, inflate, inflateTolerant, isAsciiWhitespace, loadMathFont, looksLikeBareCodestream, parseJp2Container, pdfCodec, readJpeg2000Metadata, readJpegInfo, readPdf, resolveFaceWithRegistry, resolveStandardFont, rotatePointAboutCenter, scaleMathStretchConstruction, unfilterScanlines, wrapRunsToWidth, writePdf };
34
+ export { ByteReader, ByteWriter, type CcittFaxImage, type CcittFaxOptions, DEFAULT_VERTICAL_METRIC_POLICY, type DeflateLevel, type EmbeddedFace, type EmbeddedFaceMetrics, type EmbeddedFaceSubstitution, type FontMeasurerOptions, type FontMetrics, type FontRegistry, type FontRegistryOptions, type FontSubstitution, type GlyphInkBounds, type InflateResult, type Jbig2DecodeOptions, type Jbig2Image, Jbig2ParseError, Jbig2UnsupportedError, type Jp2ChannelDefinition, type Jp2ColourSpace, type Jp2Container, type Jp2ImageHeader, type Jpeg2000ComponentMetadata, type Jpeg2000DecodeOptions, type Jpeg2000Image, type Jpeg2000Metadata, Jpeg2000ParseError, type Jpeg2000ProgressionOrder, type Jpeg2000QuantizationStyle, type Jpeg2000Transform, Jpeg2000UnsupportedError, type JpegInfo, type LoadedMathFont, MAX_INFLATE_OUTPUT_BYTES, type MathAssembledGlyphs, type MathBox, type MathColor, type MathFont, type MathFontDescriptorMetrics, type MathFontMetrics, type MathGlyphAssembly, type MathGlyphConstruction, type MathGlyphMetrics, type MathGlyphPart, type MathGlyphPlacement, type MathGlyphRun, type MathGlyphVariant, type MathLayoutItem, type MathRule, type MathStretchAxis, type MathStretchConstruction, type MathStretchGlyph, type MathStretchOptions, type MathStretchPlacement, type MathStretchResult, type MathStroke, type MathVariants, NOOP_DIAGNOSTIC_SINK, PdfBytesSchema, type PdfDiagnostic, type PdfDiagnosticSeverity, type PdfDiagnosticSink, PdfEncryptedError, PdfParseError, PdfPasswordRequiredError, type PngDecodeOptions, type PngEncodeOptions, type PngFilterType, type Point, type PositionedFormula, type ProvidedFont, type RawImage, type ReadPdfOptions, type ResolvedFace, type ResolvedFont, STANDARD_METRICS, type StandardFontMeasurerOptions, type StandardFontName, type StyledFragment, type StyledRun, type TextMeasurer, type UnderlineMetrics, type VerticalMetricPolicy, type WinAnsiSubstitution, type WrapOptions, type WrappedLine, type WritePdfOptions, assembleStretchyGlyph, concatBytes, crc32, createFontMeasurer, createFontRegistry, createStandardFontMeasurer, decodeCcittFax, decodeJbig2Embedded, decodeJpeg2000, decodePng, deflate, encodePng, filterScanlines, inflate, inflateTolerant, isAsciiWhitespace, loadMathFont, looksLikeBareCodestream, parseJp2Container, pdfCodec, readJpeg2000Metadata, readJpegInfo, readPdf, resolveFaceWithRegistry, resolveStandardFont, rotatePointAboutCenter, scaleMathStretchConstruction, unfilterScanlines, wrapRunsToWidth, writePdf };
package/dist/index.d.ts CHANGED
@@ -6,13 +6,15 @@ import { ByteWriter, concatBytes } from "./bytes/writer.js";
6
6
  import { t as GlyphInkBounds } from "./glyph-bounds-BV_Z40KS.js";
7
7
  import { NOOP_DIAGNOSTIC_SINK, PdfDiagnostic, PdfDiagnosticSeverity, PdfDiagnosticSink, PdfEncryptedError, PdfParseError, PdfPasswordRequiredError } from "./diagnostics.js";
8
8
  import { PdfBytesSchema, pdfCodec } from "./codec.js";
9
- import { n as EmbeddedFaceMetrics, r as EmbeddedFaceSubstitution, t as EmbeddedFace } from "./embedded-font-CbqkKgBl.js";
10
- import { a as ResolvedFace, i as ProvidedFont, n as FontRegistryOptions, o as createFontRegistry, r as FontSubstitution, s as resolveFaceWithRegistry, t as FontRegistry } from "./font-registry-Cn7P9lAh.js";
9
+ import { n as EmbeddedFaceMetrics, r as EmbeddedFaceSubstitution, t as EmbeddedFace } from "./embedded-font-fREdbxnr.js";
10
+ import { a as ResolvedFace, i as ProvidedFont, n as FontRegistryOptions, o as createFontRegistry, r as FontSubstitution, s as resolveFaceWithRegistry, t as FontRegistry } from "./font-registry-mgdbNP8_.js";
11
11
  import { DEFAULT_VERTICAL_METRIC_POLICY, FontMeasurerOptions, StandardFontMeasurerOptions, TextMeasurer, UnderlineMetrics, VerticalMetricPolicy, createFontMeasurer, createStandardFontMeasurer } from "./measure.js";
12
12
  import { WinAnsiSubstitution } from "./winansi.js";
13
13
  import { i as Point, u as rotatePointAboutCenter } from "./matrix-BHzJESll.js";
14
14
  import { ResolvedFont, resolveStandardFont } from "./fonts.js";
15
- import { a as MathGlyphRun, c as MathStroke, i as MathGlyphMetrics, n as MathColor, o as MathLayoutItem, r as MathFontMetrics, s as MathRule, t as MathBox } from "./math-types-YSQUTviw.js";
15
+ import { a as MathGlyphPart, c as MathVariants, n as MathGlyphAssembly, o as MathGlyphVariant, r as MathGlyphConstruction } from "./math-table-DhPrNoPa.js";
16
+ import { a as assembleStretchyGlyph, i as MathStretchPlacement, n as MathStretchConstruction, o as scaleMathStretchConstruction, r as MathStretchOptions, t as MathStretchAxis } from "./math-stretch-Bwk_bxh1.js";
17
+ import { a as MathGlyphMetrics, c as MathLayoutItem, d as MathStretchResult, f as MathStroke, i as MathFontMetrics, l as MathRule, n as MathBox, o as MathGlyphPlacement, r as MathColor, s as MathGlyphRun, t as MathAssembledGlyphs, u as MathStretchGlyph } from "./math-types-Bq7tyV4g.js";
16
18
  import { PositionedFormula } from "./formula.js";
17
19
  import { CcittFaxImage, CcittFaxOptions, decodeCcittFax } from "./image/ccitt.js";
18
20
  import { n as Jbig2UnsupportedError, t as Jbig2ParseError } from "./jbig2-errors-Bj6MPxrx.js";
@@ -27,8 +29,6 @@ import { PngEncodeOptions, encodePng } from "./image/png-encode.js";
27
29
  import { PngFilterType, filterScanlines, unfilterScanlines } from "./image/png-filter.js";
28
30
  import { ReadPdfOptions, readPdf } from "./read.js";
29
31
  import { WritePdfOptions, writePdf } from "./write.js";
30
- import { a as MathGlyphPart, c as MathVariants, n as MathGlyphAssembly, o as MathGlyphVariant, r as MathGlyphConstruction } from "./math-table-DhPrNoPa.js";
31
- import { a as assembleStretchyGlyph, i as MathStretchPlacement, n as MathStretchConstruction, o as scaleMathStretchConstruction, r as MathStretchOptions, t as MathStretchAxis } from "./math-stretch-Bwk_bxh1.js";
32
32
  import { LoadedMathFont, MathFont, MathFontDescriptorMetrics, loadMathFont } from "./math-font.js";
33
33
  import { StyledFragment, StyledRun, WrapOptions, WrappedLine, wrapRunsToWidth } from "./text-layout.js";
34
- export { ByteReader, ByteWriter, type CcittFaxImage, type CcittFaxOptions, DEFAULT_VERTICAL_METRIC_POLICY, type DeflateLevel, type EmbeddedFace, type EmbeddedFaceMetrics, type EmbeddedFaceSubstitution, type FontMeasurerOptions, type FontMetrics, type FontRegistry, type FontRegistryOptions, type FontSubstitution, type GlyphInkBounds, type InflateResult, type Jbig2DecodeOptions, type Jbig2Image, Jbig2ParseError, Jbig2UnsupportedError, type Jp2ChannelDefinition, type Jp2ColourSpace, type Jp2Container, type Jp2ImageHeader, type Jpeg2000ComponentMetadata, type Jpeg2000DecodeOptions, type Jpeg2000Image, type Jpeg2000Metadata, Jpeg2000ParseError, type Jpeg2000ProgressionOrder, type Jpeg2000QuantizationStyle, type Jpeg2000Transform, Jpeg2000UnsupportedError, type JpegInfo, type LoadedMathFont, MAX_INFLATE_OUTPUT_BYTES, type MathBox, type MathColor, type MathFont, type MathFontDescriptorMetrics, type MathFontMetrics, type MathGlyphAssembly, type MathGlyphConstruction, type MathGlyphMetrics, type MathGlyphPart, type MathGlyphRun, type MathGlyphVariant, type MathLayoutItem, type MathRule, type MathStretchAxis, type MathStretchConstruction, type MathStretchOptions, type MathStretchPlacement, type MathStroke, type MathVariants, NOOP_DIAGNOSTIC_SINK, PdfBytesSchema, type PdfDiagnostic, type PdfDiagnosticSeverity, type PdfDiagnosticSink, PdfEncryptedError, PdfParseError, PdfPasswordRequiredError, type PngDecodeOptions, type PngEncodeOptions, type PngFilterType, type Point, type PositionedFormula, type ProvidedFont, type RawImage, type ReadPdfOptions, type ResolvedFace, type ResolvedFont, STANDARD_METRICS, type StandardFontMeasurerOptions, type StandardFontName, type StyledFragment, type StyledRun, type TextMeasurer, type UnderlineMetrics, type VerticalMetricPolicy, type WinAnsiSubstitution, type WrapOptions, type WrappedLine, type WritePdfOptions, assembleStretchyGlyph, concatBytes, crc32, createFontMeasurer, createFontRegistry, createStandardFontMeasurer, decodeCcittFax, decodeJbig2Embedded, decodeJpeg2000, decodePng, deflate, encodePng, filterScanlines, inflate, inflateTolerant, isAsciiWhitespace, loadMathFont, looksLikeBareCodestream, parseJp2Container, pdfCodec, readJpeg2000Metadata, readJpegInfo, readPdf, resolveFaceWithRegistry, resolveStandardFont, rotatePointAboutCenter, scaleMathStretchConstruction, unfilterScanlines, wrapRunsToWidth, writePdf };
34
+ export { ByteReader, ByteWriter, type CcittFaxImage, type CcittFaxOptions, DEFAULT_VERTICAL_METRIC_POLICY, type DeflateLevel, type EmbeddedFace, type EmbeddedFaceMetrics, type EmbeddedFaceSubstitution, type FontMeasurerOptions, type FontMetrics, type FontRegistry, type FontRegistryOptions, type FontSubstitution, type GlyphInkBounds, type InflateResult, type Jbig2DecodeOptions, type Jbig2Image, Jbig2ParseError, Jbig2UnsupportedError, type Jp2ChannelDefinition, type Jp2ColourSpace, type Jp2Container, type Jp2ImageHeader, type Jpeg2000ComponentMetadata, type Jpeg2000DecodeOptions, type Jpeg2000Image, type Jpeg2000Metadata, Jpeg2000ParseError, type Jpeg2000ProgressionOrder, type Jpeg2000QuantizationStyle, type Jpeg2000Transform, Jpeg2000UnsupportedError, type JpegInfo, type LoadedMathFont, MAX_INFLATE_OUTPUT_BYTES, type MathAssembledGlyphs, type MathBox, type MathColor, type MathFont, type MathFontDescriptorMetrics, type MathFontMetrics, type MathGlyphAssembly, type MathGlyphConstruction, type MathGlyphMetrics, type MathGlyphPart, type MathGlyphPlacement, type MathGlyphRun, type MathGlyphVariant, type MathLayoutItem, type MathRule, type MathStretchAxis, type MathStretchConstruction, type MathStretchGlyph, type MathStretchOptions, type MathStretchPlacement, type MathStretchResult, type MathStroke, type MathVariants, NOOP_DIAGNOSTIC_SINK, PdfBytesSchema, type PdfDiagnostic, type PdfDiagnosticSeverity, type PdfDiagnosticSink, PdfEncryptedError, PdfParseError, PdfPasswordRequiredError, type PngDecodeOptions, type PngEncodeOptions, type PngFilterType, type Point, type PositionedFormula, type ProvidedFont, type RawImage, type ReadPdfOptions, type ResolvedFace, type ResolvedFont, STANDARD_METRICS, type StandardFontMeasurerOptions, type StandardFontName, type StyledFragment, type StyledRun, type TextMeasurer, type UnderlineMetrics, type VerticalMetricPolicy, type WinAnsiSubstitution, type WrapOptions, type WrappedLine, type WritePdfOptions, assembleStretchyGlyph, concatBytes, crc32, createFontMeasurer, createFontRegistry, createStandardFontMeasurer, decodeCcittFax, decodeJbig2Embedded, decodeJpeg2000, decodePng, deflate, encodePng, filterScanlines, inflate, inflateTolerant, isAsciiWhitespace, loadMathFont, looksLikeBareCodestream, parseJp2Container, pdfCodec, readJpeg2000Metadata, readJpegInfo, readPdf, resolveFaceWithRegistry, resolveStandardFont, rotatePointAboutCenter, scaleMathStretchConstruction, unfilterScanlines, wrapRunsToWidth, writePdf };
@@ -40,6 +40,37 @@ function writeGlyphRun(writer, positioned, item, ctx) {
40
40
  writer.writeAscii(" Tj\n");
41
41
  writer.writeAscii("ET\n");
42
42
  }
43
+ function cidBytes(glyphId) {
44
+ return new Uint8Array([glyphId >> 8 & 255, glyphId & 255]);
45
+ }
46
+ function utf16BeWithBom(text) {
47
+ const bytes = new Uint8Array(2 + text.length * 2);
48
+ bytes[0] = 254;
49
+ bytes[1] = 255;
50
+ for (let i = 0; i < text.length; i++) {
51
+ const unit = text.charCodeAt(i);
52
+ bytes[2 + i * 2] = unit >> 8 & 255;
53
+ bytes[3 + i * 2] = unit & 255;
54
+ }
55
+ return bytes;
56
+ }
57
+ function writeAssembledGlyphs(writer, positioned, item, ctx) {
58
+ if (item.placements.length === 0) return;
59
+ require_serialize.writeObject(writer, require_objects.pdfName("Span"));
60
+ writer.writeAscii(" ");
61
+ require_serialize.writeObject(writer, require_objects.pdfDict({ ActualText: require_objects.pdfHexString(utf16BeWithBom(item.text)) }));
62
+ writer.writeAscii(" BDC\n");
63
+ for (const placement of item.placements) {
64
+ writer.writeAscii("BT\n");
65
+ writer.writeAscii(`/${ctx.resourceName} ${require_serialize.formatNumber(item.sizePt)} Tf\n`);
66
+ writeRgbOperator(writer, item.color, "rg");
67
+ writer.writeAscii(`1 0 0 1 ${require_serialize.formatNumber(toPdfX(positioned, placement.xPt))} ${require_serialize.formatNumber(toPdfY(positioned, placement.yPt))} Tm\n`);
68
+ require_serialize.writeObject(writer, require_objects.pdfHexString(cidBytes(placement.glyphId)));
69
+ writer.writeAscii(" Tj\n");
70
+ writer.writeAscii("ET\n");
71
+ }
72
+ writer.writeAscii("EMC\n");
73
+ }
43
74
  function writeRule(writer, positioned, item) {
44
75
  const x = toPdfX(positioned, item.xPt);
45
76
  const topY = toPdfY(positioned, item.yPt);
@@ -62,18 +93,23 @@ function writeFormulaContentStream(formulas, ctx) {
62
93
  const writer = new require_bytes_writer.ByteWriter();
63
94
  for (const positioned of formulas) for (const item of positioned.box.items) if (item.kind === "glyphs") writeGlyphRun(writer, positioned, item, ctx);
64
95
  else if (item.kind === "rule") writeRule(writer, positioned, item);
96
+ else if (item.kind === "assembled-glyphs") writeAssembledGlyphs(writer, positioned, item, ctx);
65
97
  else writeStroke(writer, positioned, item);
66
98
  return writer.toBytes();
67
99
  }
68
100
  function collectUsedGlyphs(formulas, font) {
69
101
  const used = /* @__PURE__ */ new Map();
70
102
  for (const positioned of formulas) for (const item of positioned.box.items) {
103
+ if (item.kind === "assembled-glyphs") {
104
+ for (const placement of item.placements) if (!used.has(placement.glyphId)) used.set(placement.glyphId, void 0);
105
+ continue;
106
+ }
71
107
  if (item.kind !== "glyphs") continue;
72
108
  for (const ch of item.text) {
73
109
  const codePoint = ch.codePointAt(0);
74
110
  if (codePoint === void 0) continue;
75
111
  const glyphId = font.glyphId(codePoint);
76
- if (glyphId !== void 0 && !used.has(glyphId)) used.set(glyphId, codePoint);
112
+ if (glyphId !== void 0 && used.get(glyphId) === void 0) used.set(glyphId, codePoint);
77
113
  }
78
114
  }
79
115
  return used;
@@ -6,6 +6,6 @@ interface MathContentWriteContext {
6
6
  readonly resourceName: string;
7
7
  }
8
8
  declare function writeFormulaContentStream(formulas: readonly PositionedFormula[], ctx: MathContentWriteContext): Uint8Array<ArrayBuffer>;
9
- declare function collectUsedGlyphs(formulas: readonly PositionedFormula[], font: MathFont): ReadonlyMap<number, number>;
9
+ declare function collectUsedGlyphs(formulas: readonly PositionedFormula[], font: MathFont): ReadonlyMap<number, number | undefined>;
10
10
  //#endregion
11
11
  export { MathContentWriteContext, collectUsedGlyphs, writeFormulaContentStream };
@@ -6,6 +6,6 @@ interface MathContentWriteContext {
6
6
  readonly resourceName: string;
7
7
  }
8
8
  declare function writeFormulaContentStream(formulas: readonly PositionedFormula[], ctx: MathContentWriteContext): Uint8Array<ArrayBuffer>;
9
- declare function collectUsedGlyphs(formulas: readonly PositionedFormula[], font: MathFont): ReadonlyMap<number, number>;
9
+ declare function collectUsedGlyphs(formulas: readonly PositionedFormula[], font: MathFont): ReadonlyMap<number, number | undefined>;
10
10
  //#endregion
11
11
  export { MathContentWriteContext, collectUsedGlyphs, writeFormulaContentStream };
@@ -1,5 +1,5 @@
1
1
  import { ByteWriter } from "./bytes/writer.js";
2
- import { pdfHexString } from "./objects.js";
2
+ import { pdfDict, pdfHexString, pdfName } from "./objects.js";
3
3
  import { formatNumber, writeObject } from "./serialize.js";
4
4
  //#region src/math-content-write.ts
5
5
  function toPdfX(positioned, itemXPt) {
@@ -39,6 +39,37 @@ function writeGlyphRun(writer, positioned, item, ctx) {
39
39
  writer.writeAscii(" Tj\n");
40
40
  writer.writeAscii("ET\n");
41
41
  }
42
+ function cidBytes(glyphId) {
43
+ return new Uint8Array([glyphId >> 8 & 255, glyphId & 255]);
44
+ }
45
+ function utf16BeWithBom(text) {
46
+ const bytes = new Uint8Array(2 + text.length * 2);
47
+ bytes[0] = 254;
48
+ bytes[1] = 255;
49
+ for (let i = 0; i < text.length; i++) {
50
+ const unit = text.charCodeAt(i);
51
+ bytes[2 + i * 2] = unit >> 8 & 255;
52
+ bytes[3 + i * 2] = unit & 255;
53
+ }
54
+ return bytes;
55
+ }
56
+ function writeAssembledGlyphs(writer, positioned, item, ctx) {
57
+ if (item.placements.length === 0) return;
58
+ writeObject(writer, pdfName("Span"));
59
+ writer.writeAscii(" ");
60
+ writeObject(writer, pdfDict({ ActualText: pdfHexString(utf16BeWithBom(item.text)) }));
61
+ writer.writeAscii(" BDC\n");
62
+ for (const placement of item.placements) {
63
+ writer.writeAscii("BT\n");
64
+ writer.writeAscii(`/${ctx.resourceName} ${formatNumber(item.sizePt)} Tf\n`);
65
+ writeRgbOperator(writer, item.color, "rg");
66
+ writer.writeAscii(`1 0 0 1 ${formatNumber(toPdfX(positioned, placement.xPt))} ${formatNumber(toPdfY(positioned, placement.yPt))} Tm\n`);
67
+ writeObject(writer, pdfHexString(cidBytes(placement.glyphId)));
68
+ writer.writeAscii(" Tj\n");
69
+ writer.writeAscii("ET\n");
70
+ }
71
+ writer.writeAscii("EMC\n");
72
+ }
42
73
  function writeRule(writer, positioned, item) {
43
74
  const x = toPdfX(positioned, item.xPt);
44
75
  const topY = toPdfY(positioned, item.yPt);
@@ -61,18 +92,23 @@ function writeFormulaContentStream(formulas, ctx) {
61
92
  const writer = new ByteWriter();
62
93
  for (const positioned of formulas) for (const item of positioned.box.items) if (item.kind === "glyphs") writeGlyphRun(writer, positioned, item, ctx);
63
94
  else if (item.kind === "rule") writeRule(writer, positioned, item);
95
+ else if (item.kind === "assembled-glyphs") writeAssembledGlyphs(writer, positioned, item, ctx);
64
96
  else writeStroke(writer, positioned, item);
65
97
  return writer.toBytes();
66
98
  }
67
99
  function collectUsedGlyphs(formulas, font) {
68
100
  const used = /* @__PURE__ */ new Map();
69
101
  for (const positioned of formulas) for (const item of positioned.box.items) {
102
+ if (item.kind === "assembled-glyphs") {
103
+ for (const placement of item.placements) if (!used.has(placement.glyphId)) used.set(placement.glyphId, void 0);
104
+ continue;
105
+ }
70
106
  if (item.kind !== "glyphs") continue;
71
107
  for (const ch of item.text) {
72
108
  const codePoint = ch.codePointAt(0);
73
109
  if (codePoint === void 0) continue;
74
110
  const glyphId = font.glyphId(codePoint);
75
- if (glyphId !== void 0 && !used.has(glyphId)) used.set(glyphId, codePoint);
111
+ if (glyphId !== void 0 && used.get(glyphId) === void 0) used.set(glyphId, codePoint);
76
112
  }
77
113
  }
78
114
  return used;
@@ -38,6 +38,11 @@ function buildFontFileStream(font, compress) {
38
38
  } : { Subtype: require_objects.pdfName("CIDFontType0C") });
39
39
  return require_objects.pdfStream(dict, compress ? require_bytes_flate.deflate(font.cffBytes) : font.cffBytes);
40
40
  }
41
+ function toUnicodeEntries(usedGlyphs) {
42
+ const entries = /* @__PURE__ */ new Map();
43
+ for (const [glyphId, codePoint] of usedGlyphs) if (codePoint !== void 0) entries.set(glyphId, codePoint);
44
+ return entries;
45
+ }
41
46
  function buildMathFontObjects(font, usedGlyphs, refs, compress) {
42
47
  const cidFont = require_objects.pdfDict({
43
48
  Type: require_objects.pdfName("Font"),
@@ -64,7 +69,7 @@ function buildMathFontObjects(font, usedGlyphs, refs, compress) {
64
69
  cidFont,
65
70
  descriptor: buildFontDescriptor(font, refs.fontFileRef),
66
71
  fontFile: buildFontFileStream(font, compress),
67
- toUnicode: require_tounicode.buildToUnicodeCMap(usedGlyphs)
72
+ toUnicode: require_tounicode.buildToUnicodeCMap(toUnicodeEntries(usedGlyphs))
68
73
  };
69
74
  }
70
75
  //#endregion