pdf-codec 1.4.2 → 1.6.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 (170) hide show
  1. package/README.md +56 -15
  2. package/dist/assets/caladea-bold.cjs +5 -0
  3. package/dist/assets/caladea-bold.d.cts +4 -0
  4. package/dist/assets/caladea-bold.d.ts +4 -0
  5. package/dist/assets/caladea-bold.js +4 -0
  6. package/dist/assets/caladea-bolditalic.cjs +5 -0
  7. package/dist/assets/caladea-bolditalic.d.cts +4 -0
  8. package/dist/assets/caladea-bolditalic.d.ts +4 -0
  9. package/dist/assets/caladea-bolditalic.js +4 -0
  10. package/dist/assets/caladea-italic.cjs +5 -0
  11. package/dist/assets/caladea-italic.d.cts +4 -0
  12. package/dist/assets/caladea-italic.d.ts +4 -0
  13. package/dist/assets/caladea-italic.js +4 -0
  14. package/dist/assets/caladea-regular.cjs +5 -0
  15. package/dist/assets/caladea-regular.d.cts +4 -0
  16. package/dist/assets/caladea-regular.d.ts +4 -0
  17. package/dist/assets/caladea-regular.js +4 -0
  18. package/dist/assets/carlito-bold.cjs +5 -0
  19. package/dist/assets/carlito-bold.d.cts +4 -0
  20. package/dist/assets/carlito-bold.d.ts +4 -0
  21. package/dist/assets/carlito-bold.js +4 -0
  22. package/dist/assets/carlito-bolditalic.cjs +5 -0
  23. package/dist/assets/carlito-bolditalic.d.cts +4 -0
  24. package/dist/assets/carlito-bolditalic.d.ts +4 -0
  25. package/dist/assets/carlito-bolditalic.js +4 -0
  26. package/dist/assets/carlito-italic.cjs +5 -0
  27. package/dist/assets/carlito-italic.d.cts +4 -0
  28. package/dist/assets/carlito-italic.d.ts +4 -0
  29. package/dist/assets/carlito-italic.js +4 -0
  30. package/dist/assets/carlito-regular.cjs +5 -0
  31. package/dist/assets/carlito-regular.d.cts +4 -0
  32. package/dist/assets/carlito-regular.d.ts +4 -0
  33. package/dist/assets/carlito-regular.js +4 -0
  34. package/dist/cff-probe.cjs +133 -0
  35. package/dist/cff-probe.d.cts +10 -0
  36. package/dist/cff-probe.d.ts +10 -0
  37. package/dist/cff-probe.js +132 -0
  38. package/dist/cmap-table.cjs +108 -0
  39. package/dist/cmap-table.d.cts +6 -0
  40. package/dist/cmap-table.d.ts +6 -0
  41. package/dist/cmap-table.js +107 -0
  42. package/dist/content-write.cjs +36 -17
  43. package/dist/content-write.d.cts +9 -2
  44. package/dist/content-write.d.ts +9 -2
  45. package/dist/content-write.js +35 -16
  46. package/dist/crypto/aes.cjs +166 -0
  47. package/dist/crypto/aes.d.cts +6 -0
  48. package/dist/crypto/aes.d.ts +6 -0
  49. package/dist/crypto/aes.js +163 -0
  50. package/dist/crypto/md5.cjs +215 -0
  51. package/dist/crypto/md5.d.cts +4 -0
  52. package/dist/crypto/md5.d.ts +4 -0
  53. package/dist/crypto/md5.js +214 -0
  54. package/dist/crypto/rc4.cjs +29 -0
  55. package/dist/crypto/rc4.d.cts +4 -0
  56. package/dist/crypto/rc4.d.ts +4 -0
  57. package/dist/crypto/rc4.js +28 -0
  58. package/dist/crypto/sha2.cjs +261 -0
  59. package/dist/crypto/sha2.d.cts +6 -0
  60. package/dist/crypto/sha2.d.ts +6 -0
  61. package/dist/crypto/sha2.js +258 -0
  62. package/dist/diagnostics.cjs +7 -0
  63. package/dist/diagnostics.d.cts +4 -1
  64. package/dist/diagnostics.d.ts +4 -1
  65. package/dist/diagnostics.js +7 -1
  66. package/dist/document.cjs +38 -2
  67. package/dist/document.js +38 -2
  68. package/dist/embedded-font-CLedn-mT.d.cts +42 -0
  69. package/dist/embedded-font-CbqkKgBl.d.ts +42 -0
  70. package/dist/embedded-font-write.cjs +92 -0
  71. package/dist/embedded-font-write.d.cts +22 -0
  72. package/dist/embedded-font-write.d.ts +22 -0
  73. package/dist/embedded-font-write.js +90 -0
  74. package/dist/embedded-font.cjs +142 -0
  75. package/dist/embedded-font.d.cts +2 -0
  76. package/dist/embedded-font.d.ts +2 -0
  77. package/dist/embedded-font.js +138 -0
  78. package/dist/encrypt.cjs +264 -0
  79. package/dist/encrypt.d.cts +11 -0
  80. package/dist/encrypt.d.ts +11 -0
  81. package/dist/encrypt.js +263 -0
  82. package/dist/filters.cjs +19 -1
  83. package/dist/filters.js +19 -1
  84. package/dist/font-registry-Cn7P9lAh.d.ts +38 -0
  85. package/dist/font-registry-yby02snZ.d.cts +38 -0
  86. package/dist/font-registry.cjs +152 -0
  87. package/dist/font-registry.d.cts +2 -0
  88. package/dist/font-registry.d.ts +2 -0
  89. package/dist/font-registry.js +150 -0
  90. package/dist/font-substitutes.cjs +13 -0
  91. package/dist/font-substitutes.d.cts +5 -0
  92. package/dist/font-substitutes.d.ts +5 -0
  93. package/dist/font-substitutes.js +12 -0
  94. package/dist/font-tables.cjs +127 -0
  95. package/dist/font-tables.d.cts +43 -0
  96. package/dist/font-tables.d.ts +43 -0
  97. package/dist/font-tables.js +122 -0
  98. package/dist/fonts.cjs +1 -0
  99. package/dist/fonts.d.cts +2 -1
  100. package/dist/fonts.d.ts +2 -1
  101. package/dist/fonts.js +1 -1
  102. package/dist/glyf.cjs +127 -0
  103. package/dist/glyf.d.cts +31 -0
  104. package/dist/glyf.d.ts +31 -0
  105. package/dist/glyf.js +125 -0
  106. package/dist/{math-hmtx.cjs → hmtx-table.cjs} +3 -3
  107. package/dist/{math-hmtx.d.ts → hmtx-table.d.cts} +2 -2
  108. package/dist/{math-hmtx.d.cts → hmtx-table.d.ts} +2 -2
  109. package/dist/{math-hmtx.js → hmtx-table.js} +3 -3
  110. package/dist/image/ccitt.cjs +488 -0
  111. package/dist/image/ccitt.d.cts +17 -0
  112. package/dist/image/ccitt.d.ts +17 -0
  113. package/dist/image/ccitt.js +487 -0
  114. package/dist/images-read.cjs +1 -4
  115. package/dist/images-read.js +2 -5
  116. package/dist/index.cjs +8 -0
  117. package/dist/index.d.cts +7 -4
  118. package/dist/index.d.ts +7 -4
  119. package/dist/index.js +5 -3
  120. package/dist/interpret.cjs +173 -38
  121. package/dist/interpret.d.cts +27 -10
  122. package/dist/interpret.d.ts +27 -10
  123. package/dist/interpret.js +174 -39
  124. package/dist/math-font-write.cjs +3 -32
  125. package/dist/math-font-write.js +2 -31
  126. package/dist/math-font.cjs +7 -5
  127. package/dist/math-font.js +5 -3
  128. package/dist/math-table.d.cts +1 -1
  129. package/dist/math-table.d.ts +1 -1
  130. package/dist/{matrix-B3c2_a2f.d.cts → matrix-BHzJESll.d.cts} +2 -1
  131. package/dist/{matrix-B3c2_a2f.d.ts → matrix-BHzJESll.d.ts} +2 -1
  132. package/dist/matrix.cjs +2 -0
  133. package/dist/matrix.d.cts +2 -2
  134. package/dist/matrix.d.ts +2 -2
  135. package/dist/matrix.js +2 -1
  136. package/dist/measure.cjs +65 -14
  137. package/dist/measure.d.cts +8 -1
  138. package/dist/measure.d.ts +8 -1
  139. package/dist/measure.js +64 -15
  140. package/dist/objects.cjs +4 -0
  141. package/dist/objects.d.cts +2 -1
  142. package/dist/objects.d.ts +2 -1
  143. package/dist/objects.js +4 -1
  144. package/dist/read.cjs +43 -4
  145. package/dist/read.d.cts +1 -1
  146. package/dist/read.d.ts +1 -1
  147. package/dist/read.js +43 -4
  148. package/dist/sfnt-V08bb5ut.d.cts +21 -0
  149. package/dist/sfnt-V08bb5ut.d.ts +21 -0
  150. package/dist/sfnt-subset.cjs +250 -0
  151. package/dist/sfnt-subset.d.cts +11 -0
  152. package/dist/sfnt-subset.d.ts +11 -0
  153. package/dist/sfnt-subset.js +249 -0
  154. package/dist/sfnt.cjs +50 -4
  155. package/dist/sfnt.d.cts +2 -17
  156. package/dist/sfnt.d.ts +2 -17
  157. package/dist/sfnt.js +47 -5
  158. package/dist/tounicode.cjs +34 -0
  159. package/dist/tounicode.d.cts +5 -0
  160. package/dist/tounicode.d.ts +5 -0
  161. package/dist/tounicode.js +33 -0
  162. package/dist/write.cjs +81 -11
  163. package/dist/write.d.cts +6 -0
  164. package/dist/write.d.ts +6 -0
  165. package/dist/write.js +82 -12
  166. package/package.json +1 -1
  167. package/dist/math-cmap.cjs +0 -81
  168. package/dist/math-cmap.d.cts +0 -6
  169. package/dist/math-cmap.d.ts +0 -6
  170. package/dist/math-cmap.js +0 -80
@@ -0,0 +1,11 @@
1
+ import { t as SfntFont } from "./sfnt-V08bb5ut.cjs";
2
+ //#region src/sfnt-subset.d.ts
3
+ interface SfntSubsetResult {
4
+ readonly bytes: Uint8Array<ArrayBuffer>;
5
+ readonly numGlyphs: number;
6
+ readonly glyphIds: readonly number[];
7
+ readonly unmappedCodePoints: readonly number[];
8
+ }
9
+ declare function subsetSfnt(font: SfntFont, codePoints: Iterable<number>): SfntSubsetResult | undefined;
10
+ //#endregion
11
+ export { SfntSubsetResult, subsetSfnt };
@@ -0,0 +1,11 @@
1
+ import { t as SfntFont } from "./sfnt-V08bb5ut.js";
2
+ //#region src/sfnt-subset.d.ts
3
+ interface SfntSubsetResult {
4
+ readonly bytes: Uint8Array<ArrayBuffer>;
5
+ readonly numGlyphs: number;
6
+ readonly glyphIds: readonly number[];
7
+ readonly unmappedCodePoints: readonly number[];
8
+ }
9
+ declare function subsetSfnt(font: SfntFont, codePoints: Iterable<number>): SfntSubsetResult | undefined;
10
+ //#endregion
11
+ export { SfntSubsetResult, subsetSfnt };
@@ -0,0 +1,249 @@
1
+ import { hasBytes, sfntTableBytes, u16, u32 } from "./sfnt.js";
2
+ import { buildCmapLookup } from "./cmap-table.js";
3
+ import { parseHead, parseMaxp } from "./font-tables.js";
4
+ import { parseGlyf } from "./glyf.js";
5
+ //#region src/sfnt-subset.ts
6
+ const HEAD_TABLE_SIZE = 54;
7
+ const HEAD_CHECKSUM_ADJUSTMENT_OFFSET = 8;
8
+ const HEAD_INDEX_TO_LOC_FORMAT_OFFSET = 50;
9
+ const INDEX_TO_LOC_FORMAT_LONG = 1;
10
+ const HHEA_TABLE_SIZE = 36;
11
+ const HHEA_NUMBER_OF_HMETRICS_OFFSET = 34;
12
+ const MAXP_MIN_SIZE = 6;
13
+ const MAXP_NUM_GLYPHS_OFFSET = 4;
14
+ const POST_STUB_SIZE = 32;
15
+ const POST_VERSION_3_0 = 196608;
16
+ const POST_METRICS_OFFSET = 4;
17
+ const POST_METRICS_SIZE = 12;
18
+ const LONG_HOR_METRIC_SIZE = 4;
19
+ const LEFT_SIDE_BEARING_SIZE = 2;
20
+ const LOCA_LONG_ENTRY_SIZE = 4;
21
+ const TABLE_DIRECTORY_HEADER_SIZE = 12;
22
+ const TABLE_RECORD_SIZE = 16;
23
+ const SFNT_VERSION_TRUETYPE = 65536;
24
+ const CHECKSUM_ADJUSTMENT_MAGIC = 2981146554;
25
+ const GLYPH_ALIGNMENT = 4;
26
+ const COPIED_TAGS = [
27
+ "cvt ",
28
+ "fpgm",
29
+ "prep"
30
+ ];
31
+ function alignUp(value) {
32
+ return Math.ceil(value / GLYPH_ALIGNMENT) * GLYPH_ALIGNMENT;
33
+ }
34
+ function writeU16(bytes, offset, value) {
35
+ bytes[offset] = value >>> 8 & 255;
36
+ bytes[offset + 1] = value & 255;
37
+ }
38
+ function writeU32(bytes, offset, value) {
39
+ bytes[offset] = value >>> 24 & 255;
40
+ bytes[offset + 1] = value >>> 16 & 255;
41
+ bytes[offset + 2] = value >>> 8 & 255;
42
+ bytes[offset + 3] = value & 255;
43
+ }
44
+ function checksum(bytes, offset, length) {
45
+ let sum = 0;
46
+ for (let i = 0; i < length; i += GLYPH_ALIGNMENT) sum = sum + u32(bytes, offset + i) >>> 0;
47
+ return sum;
48
+ }
49
+ function readHorizontalMetrics(source, glyphId) {
50
+ if (glyphId < source.numberOfHMetrics) {
51
+ const offset = glyphId * LONG_HOR_METRIC_SIZE;
52
+ if (!hasBytes(source.bytes, offset, LONG_HOR_METRIC_SIZE)) return;
53
+ return {
54
+ advanceWidth: u16(source.bytes, offset),
55
+ leftSideBearing: u16(source.bytes, offset + 2)
56
+ };
57
+ }
58
+ const lastAdvanceOffset = (source.numberOfHMetrics - 1) * LONG_HOR_METRIC_SIZE;
59
+ const bearingOffset = source.numberOfHMetrics * LONG_HOR_METRIC_SIZE + (glyphId - source.numberOfHMetrics) * LEFT_SIDE_BEARING_SIZE;
60
+ if (!hasBytes(source.bytes, lastAdvanceOffset, LONG_HOR_METRIC_SIZE) || !hasBytes(source.bytes, bearingOffset, LEFT_SIDE_BEARING_SIZE)) return;
61
+ return {
62
+ advanceWidth: u16(source.bytes, lastAdvanceOffset),
63
+ leftSideBearing: u16(source.bytes, bearingOffset)
64
+ };
65
+ }
66
+ function buildPostStub(font) {
67
+ const post = new Uint8Array(POST_STUB_SIZE);
68
+ writeU32(post, 0, POST_VERSION_3_0);
69
+ const sourcePost = sfntTableBytes(font, "post");
70
+ if (sourcePost !== void 0 && hasBytes(sourcePost, POST_METRICS_OFFSET, POST_METRICS_SIZE)) post.set(sourcePost.subarray(POST_METRICS_OFFSET, 16), POST_METRICS_OFFSET);
71
+ return post;
72
+ }
73
+ function collectGlyphIds(glyf, cmap, numGlyphs, codePoints) {
74
+ const used = /* @__PURE__ */ new Set([0]);
75
+ const unmapped = /* @__PURE__ */ new Set();
76
+ const pending = [0];
77
+ for (const codePoint of codePoints) {
78
+ const glyphId = cmap(codePoint);
79
+ if (glyphId === void 0) {
80
+ unmapped.add(codePoint);
81
+ continue;
82
+ }
83
+ if (glyphId >= numGlyphs) return;
84
+ if (!used.has(glyphId)) {
85
+ used.add(glyphId);
86
+ pending.push(glyphId);
87
+ }
88
+ }
89
+ while (pending.length > 0) {
90
+ const glyphId = pending.pop();
91
+ if (glyf.glyphBytes(glyphId) === void 0) return;
92
+ const header = glyf.glyphHeader(glyphId);
93
+ if (header === void 0 || header.numberOfContours >= 0) continue;
94
+ const components = glyf.compositeComponents(glyphId);
95
+ if (components === void 0) return;
96
+ for (const component of components) {
97
+ if (component.glyphIndex >= numGlyphs) return;
98
+ if (!used.has(component.glyphIndex)) {
99
+ used.add(component.glyphIndex);
100
+ pending.push(component.glyphIndex);
101
+ }
102
+ }
103
+ }
104
+ return {
105
+ used,
106
+ unmapped: [...unmapped].sort((a, b) => a - b)
107
+ };
108
+ }
109
+ function subsetSfnt(font, codePoints) {
110
+ const head = parseHead(font);
111
+ const maxp = parseMaxp(font);
112
+ const sourceHead = sfntTableBytes(font, "head");
113
+ const sourceHhea = sfntTableBytes(font, "hhea");
114
+ const sourceMaxp = sfntTableBytes(font, "maxp");
115
+ const sourceHmtx = sfntTableBytes(font, "hmtx");
116
+ if (head === void 0 || maxp === void 0 || sourceHead === void 0 || sourceHhea === void 0 || sourceMaxp === void 0 || sourceHmtx === void 0) return;
117
+ if (!hasBytes(sourceHead, 0, HEAD_TABLE_SIZE) || !hasBytes(sourceHhea, 0, HHEA_TABLE_SIZE) || !hasBytes(sourceMaxp, 0, MAXP_MIN_SIZE)) return;
118
+ const numberOfHMetrics = u16(sourceHhea, HHEA_NUMBER_OF_HMETRICS_OFFSET);
119
+ if (numberOfHMetrics === 0) return;
120
+ const glyf = parseGlyf(font, {
121
+ numGlyphs: maxp.numGlyphs,
122
+ indexToLocFormat: head.indexToLocFormat
123
+ });
124
+ const cmap = buildCmapLookup(font);
125
+ if (glyf === void 0 || cmap === void 0) return;
126
+ const collected = collectGlyphIds(glyf, cmap, maxp.numGlyphs, codePoints);
127
+ if (collected === void 0) return;
128
+ const glyphIds = [...collected.used].sort((a, b) => a - b);
129
+ const numGlyphs = glyphIds[glyphIds.length - 1] + 1;
130
+ const outlines = /* @__PURE__ */ new Map();
131
+ let glyfLength = 0;
132
+ for (const glyphId of glyphIds) {
133
+ const bytes = glyf.glyphBytes(glyphId);
134
+ if (bytes === void 0) return;
135
+ outlines.set(glyphId, bytes);
136
+ glyfLength += alignUp(bytes.length);
137
+ }
138
+ const glyfData = new Uint8Array(glyfLength);
139
+ const locaData = new Uint8Array((numGlyphs + 1) * LOCA_LONG_ENTRY_SIZE);
140
+ let glyfOffset = 0;
141
+ for (let glyphId = 0; glyphId < numGlyphs; glyphId++) {
142
+ writeU32(locaData, glyphId * LOCA_LONG_ENTRY_SIZE, glyfOffset);
143
+ const bytes = outlines.get(glyphId);
144
+ if (bytes === void 0) continue;
145
+ glyfData.set(bytes, glyfOffset);
146
+ glyfOffset += alignUp(bytes.length);
147
+ }
148
+ writeU32(locaData, numGlyphs * LOCA_LONG_ENTRY_SIZE, glyfOffset);
149
+ const hmtxData = new Uint8Array(numGlyphs * LONG_HOR_METRIC_SIZE);
150
+ for (let glyphId = 0; glyphId < numGlyphs; glyphId++) {
151
+ const metrics = readHorizontalMetrics({
152
+ bytes: sourceHmtx,
153
+ numberOfHMetrics
154
+ }, glyphId);
155
+ if (metrics === void 0) return;
156
+ writeU16(hmtxData, glyphId * LONG_HOR_METRIC_SIZE, metrics.advanceWidth);
157
+ writeU16(hmtxData, glyphId * LONG_HOR_METRIC_SIZE + 2, metrics.leftSideBearing);
158
+ }
159
+ const headData = new Uint8Array(HEAD_TABLE_SIZE);
160
+ headData.set(sourceHead.subarray(0, HEAD_TABLE_SIZE));
161
+ writeU32(headData, HEAD_CHECKSUM_ADJUSTMENT_OFFSET, 0);
162
+ writeU16(headData, HEAD_INDEX_TO_LOC_FORMAT_OFFSET, INDEX_TO_LOC_FORMAT_LONG);
163
+ const hheaData = new Uint8Array(HHEA_TABLE_SIZE);
164
+ hheaData.set(sourceHhea.subarray(0, HHEA_TABLE_SIZE));
165
+ writeU16(hheaData, HHEA_NUMBER_OF_HMETRICS_OFFSET, numGlyphs);
166
+ const maxpData = new Uint8Array(sourceMaxp.length);
167
+ maxpData.set(sourceMaxp);
168
+ writeU16(maxpData, MAXP_NUM_GLYPHS_OFFSET, numGlyphs);
169
+ const tables = [
170
+ {
171
+ tag: "glyf",
172
+ data: glyfData
173
+ },
174
+ {
175
+ tag: "head",
176
+ data: headData
177
+ },
178
+ {
179
+ tag: "hhea",
180
+ data: hheaData
181
+ },
182
+ {
183
+ tag: "hmtx",
184
+ data: hmtxData
185
+ },
186
+ {
187
+ tag: "loca",
188
+ data: locaData
189
+ },
190
+ {
191
+ tag: "maxp",
192
+ data: maxpData
193
+ },
194
+ {
195
+ tag: "post",
196
+ data: buildPostStub(font)
197
+ }
198
+ ];
199
+ for (const tag of COPIED_TAGS) {
200
+ const bytes = sfntTableBytes(font, tag);
201
+ if (bytes !== void 0) {
202
+ const copy = new Uint8Array(bytes.length);
203
+ copy.set(bytes);
204
+ tables.push({
205
+ tag,
206
+ data: copy
207
+ });
208
+ }
209
+ }
210
+ tables.sort((a, b) => a.tag < b.tag ? -1 : 1);
211
+ const numTables = tables.length;
212
+ let entrySelector = 0;
213
+ while (1 << entrySelector + 1 <= numTables) entrySelector++;
214
+ const searchRange = (1 << entrySelector) * TABLE_RECORD_SIZE;
215
+ const rangeShift = numTables * TABLE_RECORD_SIZE - searchRange;
216
+ const directorySize = TABLE_DIRECTORY_HEADER_SIZE + numTables * TABLE_RECORD_SIZE;
217
+ const offsets = [];
218
+ let fileLength = alignUp(directorySize);
219
+ for (const table of tables) {
220
+ offsets.push(fileLength);
221
+ fileLength += alignUp(table.data.length);
222
+ }
223
+ const file = new Uint8Array(fileLength);
224
+ writeU32(file, 0, SFNT_VERSION_TRUETYPE);
225
+ writeU16(file, 4, numTables);
226
+ writeU16(file, 6, searchRange);
227
+ writeU16(file, 8, entrySelector);
228
+ writeU16(file, 10, rangeShift);
229
+ for (let i = 0; i < numTables; i++) {
230
+ const table = tables[i];
231
+ const tableOffset = offsets[i];
232
+ file.set(table.data, tableOffset);
233
+ const recordOffset = TABLE_DIRECTORY_HEADER_SIZE + i * TABLE_RECORD_SIZE;
234
+ for (let c = 0; c < table.tag.length; c++) file[recordOffset + c] = table.tag.charCodeAt(c);
235
+ writeU32(file, recordOffset + 4, checksum(file, tableOffset, alignUp(table.data.length)));
236
+ writeU32(file, recordOffset + 8, tableOffset);
237
+ writeU32(file, recordOffset + 12, table.data.length);
238
+ }
239
+ const headOffsetInFile = offsets[tables.findIndex((table) => table.tag === "head")];
240
+ writeU32(file, headOffsetInFile + HEAD_CHECKSUM_ADJUSTMENT_OFFSET, CHECKSUM_ADJUSTMENT_MAGIC - checksum(file, 0, fileLength) >>> 0);
241
+ return {
242
+ bytes: file,
243
+ numGlyphs,
244
+ glyphIds,
245
+ unmappedCodePoints: collected.unmapped
246
+ };
247
+ }
248
+ //#endregion
249
+ export { subsetSfnt };
package/dist/sfnt.cjs CHANGED
@@ -1,21 +1,49 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  //#region src/sfnt.ts
3
+ const TABLE_DIRECTORY_HEADER_SIZE = 12;
4
+ const TABLE_RECORD_SIZE = 16;
5
+ const TABLE_TAG_SIZE = 4;
6
+ const SFNT_VERSIONS = /* @__PURE__ */ new Set([
7
+ 65536,
8
+ 1330926671,
9
+ 1953658213,
10
+ 1954115633
11
+ ]);
12
+ function hasBytes(bytes, offset, length) {
13
+ return Number.isInteger(offset) && Number.isInteger(length) && offset >= 0 && length >= 0 && offset + length <= bytes.length;
14
+ }
15
+ function requireBytes(bytes, offset, length) {
16
+ if (!hasBytes(bytes, offset, length)) throw new Error(`sfnt read of ${String(length)} byte(s) at offset ${String(offset)} is outside the ${String(bytes.length)}-byte range`);
17
+ }
3
18
  function readUint16(bytes, offset) {
4
19
  return bytes[offset] << 8 | bytes[offset + 1];
5
20
  }
6
21
  function readUint32(bytes, offset) {
7
22
  return (bytes[offset] << 24 | bytes[offset + 1] << 16 | bytes[offset + 2] << 8 | bytes[offset + 3]) >>> 0;
8
23
  }
9
- const TABLE_DIRECTORY_HEADER_SIZE = 12;
10
- const TABLE_RECORD_SIZE = 16;
24
+ function decodeTag(bytes, offset) {
25
+ let tag = "";
26
+ for (let i = 0; i < TABLE_TAG_SIZE; i++) {
27
+ const byte = bytes[offset + i];
28
+ if (byte < 32 || byte > 126) return;
29
+ tag += String.fromCharCode(byte);
30
+ }
31
+ return tag;
32
+ }
11
33
  function parseSfnt(bytes) {
34
+ if (!hasBytes(bytes, 0, TABLE_DIRECTORY_HEADER_SIZE)) return;
35
+ if (!SFNT_VERSIONS.has(readUint32(bytes, 0))) return;
12
36
  const numTables = readUint16(bytes, 4);
37
+ if (!hasBytes(bytes, 0, TABLE_DIRECTORY_HEADER_SIZE + numTables * TABLE_RECORD_SIZE)) return;
13
38
  const tables = /* @__PURE__ */ new Map();
14
39
  for (let i = 0; i < numTables; i++) {
15
40
  const recordOffset = TABLE_DIRECTORY_HEADER_SIZE + i * TABLE_RECORD_SIZE;
16
- const tag = new TextDecoder("ascii").decode(bytes.subarray(recordOffset, recordOffset + 4));
41
+ const tag = decodeTag(bytes, recordOffset);
42
+ if (tag === void 0) return;
17
43
  const offset = readUint32(bytes, recordOffset + 8);
18
44
  const length = readUint32(bytes, recordOffset + 12);
45
+ if (!hasBytes(bytes, offset, length)) continue;
46
+ if (tables.has(tag)) continue;
19
47
  tables.set(tag, {
20
48
  offset,
21
49
  length
@@ -31,22 +59,40 @@ function sfntTableBytes(font, tag) {
31
59
  return table === void 0 ? void 0 : font.bytes.subarray(table.offset, table.offset + table.length);
32
60
  }
33
61
  function u8(bytes, offset) {
62
+ requireBytes(bytes, offset, 1);
34
63
  return bytes[offset];
35
64
  }
36
65
  function u16(bytes, offset) {
66
+ requireBytes(bytes, offset, 2);
37
67
  return readUint16(bytes, offset);
38
68
  }
39
69
  function i16(bytes, offset) {
40
- const value = readUint16(bytes, offset);
70
+ const value = u16(bytes, offset);
41
71
  return value >= 32768 ? value - 65536 : value;
42
72
  }
73
+ function u24(bytes, offset) {
74
+ requireBytes(bytes, offset, 3);
75
+ return bytes[offset] << 16 | bytes[offset + 1] << 8 | bytes[offset + 2];
76
+ }
43
77
  function u32(bytes, offset) {
78
+ requireBytes(bytes, offset, 4);
44
79
  return readUint32(bytes, offset);
45
80
  }
81
+ function i32(bytes, offset) {
82
+ return u32(bytes, offset) | 0;
83
+ }
84
+ const F2DOT14_SCALE = 16384;
85
+ function f2dot14(bytes, offset) {
86
+ return i16(bytes, offset) / F2DOT14_SCALE;
87
+ }
46
88
  //#endregion
89
+ exports.f2dot14 = f2dot14;
90
+ exports.hasBytes = hasBytes;
47
91
  exports.i16 = i16;
92
+ exports.i32 = i32;
48
93
  exports.parseSfnt = parseSfnt;
49
94
  exports.sfntTableBytes = sfntTableBytes;
50
95
  exports.u16 = u16;
96
+ exports.u24 = u24;
51
97
  exports.u32 = u32;
52
98
  exports.u8 = u8;
package/dist/sfnt.d.cts CHANGED
@@ -1,17 +1,2 @@
1
- //#region src/sfnt.d.ts
2
- interface SfntTable {
3
- readonly offset: number;
4
- readonly length: number;
5
- }
6
- interface SfntFont {
7
- readonly bytes: Uint8Array<ArrayBuffer>;
8
- readonly tables: ReadonlyMap<string, SfntTable>;
9
- }
10
- declare function parseSfnt(bytes: Uint8Array<ArrayBuffer>): SfntFont;
11
- declare function sfntTableBytes(font: SfntFont, tag: string): Uint8Array<ArrayBuffer> | undefined;
12
- declare function u8(bytes: Uint8Array<ArrayBuffer>, offset: number): number;
13
- declare function u16(bytes: Uint8Array<ArrayBuffer>, offset: number): number;
14
- declare function i16(bytes: Uint8Array<ArrayBuffer>, offset: number): number;
15
- declare function u32(bytes: Uint8Array<ArrayBuffer>, offset: number): number;
16
- //#endregion
17
- export { SfntFont, SfntTable, i16, parseSfnt, sfntTableBytes, u16, u32, u8 };
1
+ import { a as i16, c as sfntTableBytes, d as u32, f as u8, i as hasBytes, l as u16, n as SfntTable, o as i32, r as f2dot14, s as parseSfnt, t as SfntFont, u as u24 } from "./sfnt-V08bb5ut.cjs";
2
+ export { SfntFont, SfntTable, f2dot14, hasBytes, i16, i32, parseSfnt, sfntTableBytes, u16, u24, u32, u8 };
package/dist/sfnt.d.ts CHANGED
@@ -1,17 +1,2 @@
1
- //#region src/sfnt.d.ts
2
- interface SfntTable {
3
- readonly offset: number;
4
- readonly length: number;
5
- }
6
- interface SfntFont {
7
- readonly bytes: Uint8Array<ArrayBuffer>;
8
- readonly tables: ReadonlyMap<string, SfntTable>;
9
- }
10
- declare function parseSfnt(bytes: Uint8Array<ArrayBuffer>): SfntFont;
11
- declare function sfntTableBytes(font: SfntFont, tag: string): Uint8Array<ArrayBuffer> | undefined;
12
- declare function u8(bytes: Uint8Array<ArrayBuffer>, offset: number): number;
13
- declare function u16(bytes: Uint8Array<ArrayBuffer>, offset: number): number;
14
- declare function i16(bytes: Uint8Array<ArrayBuffer>, offset: number): number;
15
- declare function u32(bytes: Uint8Array<ArrayBuffer>, offset: number): number;
16
- //#endregion
17
- export { SfntFont, SfntTable, i16, parseSfnt, sfntTableBytes, u16, u32, u8 };
1
+ import { a as i16, c as sfntTableBytes, d as u32, f as u8, i as hasBytes, l as u16, n as SfntTable, o as i32, r as f2dot14, s as parseSfnt, t as SfntFont, u as u24 } from "./sfnt-V08bb5ut.js";
2
+ export { SfntFont, SfntTable, f2dot14, hasBytes, i16, i32, parseSfnt, sfntTableBytes, u16, u24, u32, u8 };
package/dist/sfnt.js CHANGED
@@ -1,20 +1,48 @@
1
1
  //#region src/sfnt.ts
2
+ const TABLE_DIRECTORY_HEADER_SIZE = 12;
3
+ const TABLE_RECORD_SIZE = 16;
4
+ const TABLE_TAG_SIZE = 4;
5
+ const SFNT_VERSIONS = /* @__PURE__ */ new Set([
6
+ 65536,
7
+ 1330926671,
8
+ 1953658213,
9
+ 1954115633
10
+ ]);
11
+ function hasBytes(bytes, offset, length) {
12
+ return Number.isInteger(offset) && Number.isInteger(length) && offset >= 0 && length >= 0 && offset + length <= bytes.length;
13
+ }
14
+ function requireBytes(bytes, offset, length) {
15
+ if (!hasBytes(bytes, offset, length)) throw new Error(`sfnt read of ${String(length)} byte(s) at offset ${String(offset)} is outside the ${String(bytes.length)}-byte range`);
16
+ }
2
17
  function readUint16(bytes, offset) {
3
18
  return bytes[offset] << 8 | bytes[offset + 1];
4
19
  }
5
20
  function readUint32(bytes, offset) {
6
21
  return (bytes[offset] << 24 | bytes[offset + 1] << 16 | bytes[offset + 2] << 8 | bytes[offset + 3]) >>> 0;
7
22
  }
8
- const TABLE_DIRECTORY_HEADER_SIZE = 12;
9
- const TABLE_RECORD_SIZE = 16;
23
+ function decodeTag(bytes, offset) {
24
+ let tag = "";
25
+ for (let i = 0; i < TABLE_TAG_SIZE; i++) {
26
+ const byte = bytes[offset + i];
27
+ if (byte < 32 || byte > 126) return;
28
+ tag += String.fromCharCode(byte);
29
+ }
30
+ return tag;
31
+ }
10
32
  function parseSfnt(bytes) {
33
+ if (!hasBytes(bytes, 0, TABLE_DIRECTORY_HEADER_SIZE)) return;
34
+ if (!SFNT_VERSIONS.has(readUint32(bytes, 0))) return;
11
35
  const numTables = readUint16(bytes, 4);
36
+ if (!hasBytes(bytes, 0, TABLE_DIRECTORY_HEADER_SIZE + numTables * TABLE_RECORD_SIZE)) return;
12
37
  const tables = /* @__PURE__ */ new Map();
13
38
  for (let i = 0; i < numTables; i++) {
14
39
  const recordOffset = TABLE_DIRECTORY_HEADER_SIZE + i * TABLE_RECORD_SIZE;
15
- const tag = new TextDecoder("ascii").decode(bytes.subarray(recordOffset, recordOffset + 4));
40
+ const tag = decodeTag(bytes, recordOffset);
41
+ if (tag === void 0) return;
16
42
  const offset = readUint32(bytes, recordOffset + 8);
17
43
  const length = readUint32(bytes, recordOffset + 12);
44
+ if (!hasBytes(bytes, offset, length)) continue;
45
+ if (tables.has(tag)) continue;
18
46
  tables.set(tag, {
19
47
  offset,
20
48
  length
@@ -30,17 +58,31 @@ function sfntTableBytes(font, tag) {
30
58
  return table === void 0 ? void 0 : font.bytes.subarray(table.offset, table.offset + table.length);
31
59
  }
32
60
  function u8(bytes, offset) {
61
+ requireBytes(bytes, offset, 1);
33
62
  return bytes[offset];
34
63
  }
35
64
  function u16(bytes, offset) {
65
+ requireBytes(bytes, offset, 2);
36
66
  return readUint16(bytes, offset);
37
67
  }
38
68
  function i16(bytes, offset) {
39
- const value = readUint16(bytes, offset);
69
+ const value = u16(bytes, offset);
40
70
  return value >= 32768 ? value - 65536 : value;
41
71
  }
72
+ function u24(bytes, offset) {
73
+ requireBytes(bytes, offset, 3);
74
+ return bytes[offset] << 16 | bytes[offset + 1] << 8 | bytes[offset + 2];
75
+ }
42
76
  function u32(bytes, offset) {
77
+ requireBytes(bytes, offset, 4);
43
78
  return readUint32(bytes, offset);
44
79
  }
80
+ function i32(bytes, offset) {
81
+ return u32(bytes, offset) | 0;
82
+ }
83
+ const F2DOT14_SCALE = 16384;
84
+ function f2dot14(bytes, offset) {
85
+ return i16(bytes, offset) / F2DOT14_SCALE;
86
+ }
45
87
  //#endregion
46
- export { i16, parseSfnt, sfntTableBytes, u16, u32, u8 };
88
+ export { f2dot14, hasBytes, i16, i32, parseSfnt, sfntTableBytes, u16, u24, u32, u8 };
@@ -0,0 +1,34 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_objects = require("./objects.cjs");
3
+ //#region src/tounicode.ts
4
+ const MAX_BFCHAR_ENTRIES_PER_BLOCK = 100;
5
+ function codePointToUtf16BEHex(codePoint) {
6
+ const text = String.fromCodePoint(codePoint);
7
+ let hex = "";
8
+ for (let i = 0; i < text.length; i++) hex += text.charCodeAt(i).toString(16).padStart(4, "0");
9
+ return hex;
10
+ }
11
+ function buildToUnicodeCMap(codeToCodePoint) {
12
+ const entries = [...codeToCodePoint].sort((a, b) => a[0] - b[0]);
13
+ const lines = [
14
+ "/CIDInit /ProcSet findresource begin",
15
+ "12 dict begin",
16
+ "begincmap",
17
+ "/CIDSystemInfo << /Registry (Adobe) /Ordering (UCS) /Supplement 0 >> def",
18
+ "/CMapName /Adobe-Identity-UCS def",
19
+ "/CMapType 2 def",
20
+ "1 begincodespacerange",
21
+ "<0000> <FFFF>",
22
+ "endcodespacerange"
23
+ ];
24
+ for (let start = 0; start < entries.length; start += MAX_BFCHAR_ENTRIES_PER_BLOCK) {
25
+ const block = entries.slice(start, start + MAX_BFCHAR_ENTRIES_PER_BLOCK);
26
+ lines.push(`${block.length} beginbfchar`);
27
+ for (const [code, codePoint] of block) lines.push(`<${code.toString(16).padStart(4, "0")}> <${codePointToUtf16BEHex(codePoint)}>`);
28
+ lines.push("endbfchar");
29
+ }
30
+ lines.push("endcmap", "CMapName currentdict /CMap defineresource pop", "end", "end");
31
+ return require_objects.pdfStream(require_objects.pdfDict({}), new TextEncoder().encode(`${lines.join("\n")}\n`));
32
+ }
33
+ //#endregion
34
+ exports.buildToUnicodeCMap = buildToUnicodeCMap;
@@ -0,0 +1,5 @@
1
+ import { PdfObject } from "./objects.cjs";
2
+ //#region src/tounicode.d.ts
3
+ declare function buildToUnicodeCMap(codeToCodePoint: ReadonlyMap<number, number>): PdfObject;
4
+ //#endregion
5
+ export { buildToUnicodeCMap };
@@ -0,0 +1,5 @@
1
+ import { PdfObject } from "./objects.js";
2
+ //#region src/tounicode.d.ts
3
+ declare function buildToUnicodeCMap(codeToCodePoint: ReadonlyMap<number, number>): PdfObject;
4
+ //#endregion
5
+ export { buildToUnicodeCMap };
@@ -0,0 +1,33 @@
1
+ import { pdfDict, pdfStream } from "./objects.js";
2
+ //#region src/tounicode.ts
3
+ const MAX_BFCHAR_ENTRIES_PER_BLOCK = 100;
4
+ function codePointToUtf16BEHex(codePoint) {
5
+ const text = String.fromCodePoint(codePoint);
6
+ let hex = "";
7
+ for (let i = 0; i < text.length; i++) hex += text.charCodeAt(i).toString(16).padStart(4, "0");
8
+ return hex;
9
+ }
10
+ function buildToUnicodeCMap(codeToCodePoint) {
11
+ const entries = [...codeToCodePoint].sort((a, b) => a[0] - b[0]);
12
+ const lines = [
13
+ "/CIDInit /ProcSet findresource begin",
14
+ "12 dict begin",
15
+ "begincmap",
16
+ "/CIDSystemInfo << /Registry (Adobe) /Ordering (UCS) /Supplement 0 >> def",
17
+ "/CMapName /Adobe-Identity-UCS def",
18
+ "/CMapType 2 def",
19
+ "1 begincodespacerange",
20
+ "<0000> <FFFF>",
21
+ "endcodespacerange"
22
+ ];
23
+ for (let start = 0; start < entries.length; start += MAX_BFCHAR_ENTRIES_PER_BLOCK) {
24
+ const block = entries.slice(start, start + MAX_BFCHAR_ENTRIES_PER_BLOCK);
25
+ lines.push(`${block.length} beginbfchar`);
26
+ for (const [code, codePoint] of block) lines.push(`<${code.toString(16).padStart(4, "0")}> <${codePointToUtf16BEHex(codePoint)}>`);
27
+ lines.push("endbfchar");
28
+ }
29
+ lines.push("endcmap", "CMapName currentdict /CMap defineresource pop", "end", "end");
30
+ return pdfStream(pdfDict({}), new TextEncoder().encode(`${lines.join("\n")}\n`));
31
+ }
32
+ //#endregion
33
+ export { buildToUnicodeCMap };