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.
- package/README.md +56 -15
- package/dist/assets/caladea-bold.cjs +5 -0
- package/dist/assets/caladea-bold.d.cts +4 -0
- package/dist/assets/caladea-bold.d.ts +4 -0
- package/dist/assets/caladea-bold.js +4 -0
- package/dist/assets/caladea-bolditalic.cjs +5 -0
- package/dist/assets/caladea-bolditalic.d.cts +4 -0
- package/dist/assets/caladea-bolditalic.d.ts +4 -0
- package/dist/assets/caladea-bolditalic.js +4 -0
- package/dist/assets/caladea-italic.cjs +5 -0
- package/dist/assets/caladea-italic.d.cts +4 -0
- package/dist/assets/caladea-italic.d.ts +4 -0
- package/dist/assets/caladea-italic.js +4 -0
- package/dist/assets/caladea-regular.cjs +5 -0
- package/dist/assets/caladea-regular.d.cts +4 -0
- package/dist/assets/caladea-regular.d.ts +4 -0
- package/dist/assets/caladea-regular.js +4 -0
- package/dist/assets/carlito-bold.cjs +5 -0
- package/dist/assets/carlito-bold.d.cts +4 -0
- package/dist/assets/carlito-bold.d.ts +4 -0
- package/dist/assets/carlito-bold.js +4 -0
- package/dist/assets/carlito-bolditalic.cjs +5 -0
- package/dist/assets/carlito-bolditalic.d.cts +4 -0
- package/dist/assets/carlito-bolditalic.d.ts +4 -0
- package/dist/assets/carlito-bolditalic.js +4 -0
- package/dist/assets/carlito-italic.cjs +5 -0
- package/dist/assets/carlito-italic.d.cts +4 -0
- package/dist/assets/carlito-italic.d.ts +4 -0
- package/dist/assets/carlito-italic.js +4 -0
- package/dist/assets/carlito-regular.cjs +5 -0
- package/dist/assets/carlito-regular.d.cts +4 -0
- package/dist/assets/carlito-regular.d.ts +4 -0
- package/dist/assets/carlito-regular.js +4 -0
- package/dist/cff-probe.cjs +133 -0
- package/dist/cff-probe.d.cts +10 -0
- package/dist/cff-probe.d.ts +10 -0
- package/dist/cff-probe.js +132 -0
- package/dist/cmap-table.cjs +108 -0
- package/dist/cmap-table.d.cts +6 -0
- package/dist/cmap-table.d.ts +6 -0
- package/dist/cmap-table.js +107 -0
- package/dist/content-write.cjs +36 -17
- package/dist/content-write.d.cts +9 -2
- package/dist/content-write.d.ts +9 -2
- package/dist/content-write.js +35 -16
- package/dist/crypto/aes.cjs +166 -0
- package/dist/crypto/aes.d.cts +6 -0
- package/dist/crypto/aes.d.ts +6 -0
- package/dist/crypto/aes.js +163 -0
- package/dist/crypto/md5.cjs +215 -0
- package/dist/crypto/md5.d.cts +4 -0
- package/dist/crypto/md5.d.ts +4 -0
- package/dist/crypto/md5.js +214 -0
- package/dist/crypto/rc4.cjs +29 -0
- package/dist/crypto/rc4.d.cts +4 -0
- package/dist/crypto/rc4.d.ts +4 -0
- package/dist/crypto/rc4.js +28 -0
- package/dist/crypto/sha2.cjs +261 -0
- package/dist/crypto/sha2.d.cts +6 -0
- package/dist/crypto/sha2.d.ts +6 -0
- package/dist/crypto/sha2.js +258 -0
- package/dist/diagnostics.cjs +7 -0
- package/dist/diagnostics.d.cts +4 -1
- package/dist/diagnostics.d.ts +4 -1
- package/dist/diagnostics.js +7 -1
- package/dist/document.cjs +38 -2
- package/dist/document.js +38 -2
- package/dist/embedded-font-CLedn-mT.d.cts +42 -0
- package/dist/embedded-font-CbqkKgBl.d.ts +42 -0
- package/dist/embedded-font-write.cjs +92 -0
- package/dist/embedded-font-write.d.cts +22 -0
- package/dist/embedded-font-write.d.ts +22 -0
- package/dist/embedded-font-write.js +90 -0
- package/dist/embedded-font.cjs +142 -0
- package/dist/embedded-font.d.cts +2 -0
- package/dist/embedded-font.d.ts +2 -0
- package/dist/embedded-font.js +138 -0
- package/dist/encrypt.cjs +264 -0
- package/dist/encrypt.d.cts +11 -0
- package/dist/encrypt.d.ts +11 -0
- package/dist/encrypt.js +263 -0
- package/dist/filters.cjs +19 -1
- package/dist/filters.js +19 -1
- package/dist/font-registry-Cn7P9lAh.d.ts +38 -0
- package/dist/font-registry-yby02snZ.d.cts +38 -0
- package/dist/font-registry.cjs +152 -0
- package/dist/font-registry.d.cts +2 -0
- package/dist/font-registry.d.ts +2 -0
- package/dist/font-registry.js +150 -0
- package/dist/font-substitutes.cjs +13 -0
- package/dist/font-substitutes.d.cts +5 -0
- package/dist/font-substitutes.d.ts +5 -0
- package/dist/font-substitutes.js +12 -0
- package/dist/font-tables.cjs +127 -0
- package/dist/font-tables.d.cts +43 -0
- package/dist/font-tables.d.ts +43 -0
- package/dist/font-tables.js +122 -0
- package/dist/fonts.cjs +1 -0
- package/dist/fonts.d.cts +2 -1
- package/dist/fonts.d.ts +2 -1
- package/dist/fonts.js +1 -1
- package/dist/glyf.cjs +127 -0
- package/dist/glyf.d.cts +31 -0
- package/dist/glyf.d.ts +31 -0
- package/dist/glyf.js +125 -0
- package/dist/{math-hmtx.cjs → hmtx-table.cjs} +3 -3
- package/dist/{math-hmtx.d.ts → hmtx-table.d.cts} +2 -2
- package/dist/{math-hmtx.d.cts → hmtx-table.d.ts} +2 -2
- package/dist/{math-hmtx.js → hmtx-table.js} +3 -3
- package/dist/image/ccitt.cjs +488 -0
- package/dist/image/ccitt.d.cts +17 -0
- package/dist/image/ccitt.d.ts +17 -0
- package/dist/image/ccitt.js +487 -0
- package/dist/images-read.cjs +1 -4
- package/dist/images-read.js +2 -5
- package/dist/index.cjs +8 -0
- package/dist/index.d.cts +7 -4
- package/dist/index.d.ts +7 -4
- package/dist/index.js +5 -3
- package/dist/interpret.cjs +173 -38
- package/dist/interpret.d.cts +27 -10
- package/dist/interpret.d.ts +27 -10
- package/dist/interpret.js +174 -39
- package/dist/math-font-write.cjs +3 -32
- package/dist/math-font-write.js +2 -31
- package/dist/math-font.cjs +7 -5
- package/dist/math-font.js +5 -3
- package/dist/math-table.d.cts +1 -1
- package/dist/math-table.d.ts +1 -1
- package/dist/{matrix-B3c2_a2f.d.cts → matrix-BHzJESll.d.cts} +2 -1
- package/dist/{matrix-B3c2_a2f.d.ts → matrix-BHzJESll.d.ts} +2 -1
- package/dist/matrix.cjs +2 -0
- package/dist/matrix.d.cts +2 -2
- package/dist/matrix.d.ts +2 -2
- package/dist/matrix.js +2 -1
- package/dist/measure.cjs +65 -14
- package/dist/measure.d.cts +8 -1
- package/dist/measure.d.ts +8 -1
- package/dist/measure.js +64 -15
- package/dist/objects.cjs +4 -0
- package/dist/objects.d.cts +2 -1
- package/dist/objects.d.ts +2 -1
- package/dist/objects.js +4 -1
- package/dist/read.cjs +43 -4
- package/dist/read.d.cts +1 -1
- package/dist/read.d.ts +1 -1
- package/dist/read.js +43 -4
- package/dist/sfnt-V08bb5ut.d.cts +21 -0
- package/dist/sfnt-V08bb5ut.d.ts +21 -0
- package/dist/sfnt-subset.cjs +250 -0
- package/dist/sfnt-subset.d.cts +11 -0
- package/dist/sfnt-subset.d.ts +11 -0
- package/dist/sfnt-subset.js +249 -0
- package/dist/sfnt.cjs +50 -4
- package/dist/sfnt.d.cts +2 -17
- package/dist/sfnt.d.ts +2 -17
- package/dist/sfnt.js +47 -5
- package/dist/tounicode.cjs +34 -0
- package/dist/tounicode.d.cts +5 -0
- package/dist/tounicode.d.ts +5 -0
- package/dist/tounicode.js +33 -0
- package/dist/write.cjs +81 -11
- package/dist/write.d.cts +6 -0
- package/dist/write.d.ts +6 -0
- package/dist/write.js +82 -12
- package/package.json +1 -1
- package/dist/math-cmap.cjs +0 -81
- package/dist/math-cmap.d.cts +0 -6
- package/dist/math-cmap.d.ts +0 -6
- 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
|
-
|
|
10
|
-
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
2
|
-
|
|
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
|
-
|
|
2
|
-
|
|
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
|
-
|
|
9
|
-
|
|
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 =
|
|
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 =
|
|
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,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 };
|