pdf-parser.js 3.0.8 → 4.5.2
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 +105 -54
- package/dist/{afm-widths-Dxucrg7D.js → afm-widths-BTu0IDp2.cjs} +1517 -4
- package/dist/{afm-widths-DyDq56Ph.d.cts → afm-widths-CneRyu5l.d.cts} +1 -1
- package/dist/{afm-widths-DyDq56Ph.d.ts → afm-widths-CneRyu5l.d.ts} +1 -1
- package/dist/{afm-widths-BoeTOK2r.cjs → afm-widths-De_QMWgC.js} +1416 -51
- package/dist/afm-widths.cjs +1 -1
- package/dist/afm-widths.d.cts +1 -1
- package/dist/afm-widths.d.ts +1 -1
- package/dist/afm-widths.js +1 -1
- package/dist/annotations.cjs +104 -0
- package/dist/annotations.d.cts +9 -0
- package/dist/annotations.d.ts +9 -0
- package/dist/annotations.js +103 -0
- package/dist/attachments.cjs +65 -0
- package/dist/attachments.d.cts +8 -0
- package/dist/attachments.d.ts +8 -0
- package/dist/attachments.js +64 -0
- package/dist/builtin-encoding.cjs +221 -0
- package/dist/builtin-encoding.d.cts +8 -0
- package/dist/builtin-encoding.d.ts +8 -0
- package/dist/builtin-encoding.js +220 -0
- package/dist/bytes/flate.cjs +1 -1
- package/dist/bytes/flate.js +1 -1
- package/dist/cff.cjs +14 -0
- package/dist/cff.d.cts +4 -1
- package/dist/cff.d.ts +4 -1
- package/dist/cff.js +12 -1
- package/dist/cmap-table.cjs +76 -13
- package/dist/cmap-table.d.cts +9 -1
- package/dist/cmap-table.d.ts +9 -1
- package/dist/cmap-table.js +77 -15
- package/dist/codec.cjs +1 -1
- package/dist/codec.d.cts +134 -0
- package/dist/codec.d.ts +134 -0
- package/dist/codec.js +1 -1
- package/dist/content-read.cjs +1 -1
- package/dist/content-read.d.cts +3 -3
- package/dist/content-read.d.ts +3 -3
- package/dist/content-read.js +1 -1
- package/dist/content-write.cjs +32 -10
- package/dist/content-write.d.cts +12 -5
- package/dist/content-write.d.ts +12 -5
- package/dist/content-write.js +32 -10
- package/dist/crypto/random.cjs +9 -0
- package/dist/crypto/random.d.cts +4 -0
- package/dist/crypto/random.d.ts +4 -0
- package/dist/crypto/random.js +8 -0
- package/dist/diagnostics.d.cts +1 -1
- package/dist/diagnostics.d.ts +1 -1
- package/dist/document.cjs +12 -3
- package/dist/document.d.cts +3 -1
- package/dist/document.d.ts +3 -1
- package/dist/document.js +12 -3
- package/dist/{embedded-font-fREdbxnr.d.ts → embedded-font-B4p9a3O3.d.ts} +3 -1
- package/dist/{embedded-font-BU6Jgcof.d.cts → embedded-font-oc65VGlr.d.cts} +3 -1
- package/dist/embedded-font-write.cjs +1 -1
- package/dist/embedded-font-write.d.cts +3 -3
- package/dist/embedded-font-write.d.ts +3 -3
- package/dist/embedded-font-write.js +1 -1
- package/dist/embedded-font.cjs +46 -15
- package/dist/embedded-font.d.cts +1 -1
- package/dist/embedded-font.d.ts +1 -1
- package/dist/embedded-font.js +46 -15
- package/dist/encoding.cjs +10 -1
- package/dist/encoding.d.cts +10 -1
- package/dist/encoding.d.ts +10 -1
- package/dist/encoding.js +2 -2
- package/dist/encrypt-write.cjs +234 -0
- package/dist/encrypt-write.d.cts +31 -0
- package/dist/encrypt-write.d.ts +31 -0
- package/dist/encrypt-write.js +231 -0
- package/dist/encrypt.cjs +51 -21
- package/dist/encrypt.d.cts +19 -3
- package/dist/encrypt.d.ts +19 -3
- package/dist/encrypt.js +36 -22
- package/dist/filters.cjs +18 -14
- package/dist/filters.d.cts +1 -1
- package/dist/filters.d.ts +1 -1
- package/dist/filters.js +18 -14
- package/dist/font-read.cjs +68 -13
- package/dist/font-read.d.cts +1 -1
- package/dist/font-read.d.ts +1 -1
- package/dist/font-read.js +69 -14
- package/dist/font-registry.cjs +1 -1
- package/dist/font-registry.d.cts +4 -4
- package/dist/font-registry.d.ts +4 -4
- package/dist/font-registry.js +1 -1
- package/dist/font-substitutes.d.cts +1 -1
- package/dist/font-substitutes.d.ts +1 -1
- package/dist/font-tables.cjs +31 -0
- package/dist/font-tables.d.cts +3 -1
- package/dist/font-tables.d.ts +3 -1
- package/dist/font-tables.js +31 -2
- package/dist/fonts.d.cts +2 -2
- package/dist/fonts.d.ts +2 -2
- package/dist/form.cjs +138 -0
- package/dist/form.d.cts +9 -0
- package/dist/form.d.ts +9 -0
- package/dist/form.js +137 -0
- package/dist/gsub-table-BRTQ8EUW.d.ts +10 -0
- package/dist/gsub-table-URczLd85.d.cts +10 -0
- package/dist/gsub-table.cjs +225 -0
- package/dist/gsub-table.d.cts +2 -0
- package/dist/gsub-table.d.ts +2 -0
- package/dist/gsub-table.js +224 -0
- package/dist/image/ccitt-encode.cjs +119 -0
- package/dist/image/ccitt-encode.d.cts +9 -0
- package/dist/image/ccitt-encode.d.ts +9 -0
- package/dist/image/ccitt-encode.js +118 -0
- package/dist/image/ccitt.cjs +3 -0
- package/dist/image/ccitt.d.cts +4 -1
- package/dist/image/ccitt.d.ts +4 -1
- package/dist/image/ccitt.js +1 -1
- package/dist/image/jbig2-bitmap.d.cts +1 -1
- package/dist/image/jbig2-bitmap.d.ts +1 -1
- package/dist/image/jbig2.cjs +3 -1
- package/dist/image/jbig2.js +3 -1
- package/dist/image/jp2-boxes.d.cts +1 -1
- package/dist/image/jp2-boxes.d.ts +1 -1
- package/dist/image/jpeg2000-codestream.d.cts +3 -3
- package/dist/image/jpeg2000-codestream.d.ts +3 -3
- package/dist/image/jpeg2000-t1.d.cts +1 -1
- package/dist/image/jpeg2000-t1.d.ts +1 -1
- package/dist/image/jpeg2000.cjs +1 -0
- package/dist/image/jpeg2000.d.cts +3 -0
- package/dist/image/jpeg2000.d.ts +3 -0
- package/dist/image/jpeg2000.js +1 -0
- package/dist/image/png-decode.cjs +1 -1
- package/dist/image/png-decode.js +1 -1
- package/dist/image/png-filter.d.cts +1 -1
- package/dist/image/png-filter.d.ts +1 -1
- package/dist/images-read.cjs +18 -12
- package/dist/images-read.d.cts +2 -2
- package/dist/images-read.d.ts +2 -2
- package/dist/images-read.js +15 -9
- package/dist/index.cjs +17 -4
- package/dist/index.d.cts +7 -6
- package/dist/index.d.ts +7 -6
- package/dist/index.js +6 -5
- package/dist/interpret.cjs +178 -56
- package/dist/interpret.d.cts +27 -12
- package/dist/interpret.d.ts +27 -12
- package/dist/interpret.js +178 -56
- package/dist/layout.cjs +149 -2
- package/dist/layout.d.cts +394 -1
- package/dist/layout.d.ts +394 -1
- package/dist/layout.js +140 -4
- package/dist/lexer.d.cts +9 -9
- package/dist/lexer.d.ts +9 -9
- package/dist/math-content-write.cjs +1 -1
- package/dist/math-content-write.js +1 -1
- package/dist/math-font-write.cjs +1 -1
- package/dist/math-font-write.d.cts +1 -1
- package/dist/math-font-write.d.ts +1 -1
- package/dist/math-font-write.js +1 -1
- package/dist/math-font.cjs +2 -2
- package/dist/math-font.d.cts +1 -1
- package/dist/math-font.d.ts +1 -1
- package/dist/math-font.js +2 -2
- package/dist/{math-stretch-a_rHNRvc.d.ts → math-stretch-BbC2o4Br.d.ts} +1 -1
- package/dist/{math-stretch-E26z6byT.d.cts → math-stretch-C2JanDAz.d.cts} +1 -1
- package/dist/math-stretch.d.cts +1 -1
- package/dist/math-stretch.d.ts +1 -1
- package/dist/measure.cjs +1 -1
- package/dist/measure.d.cts +1 -1
- package/dist/measure.d.ts +1 -1
- package/dist/measure.js +1 -1
- package/dist/names.cjs +41 -0
- package/dist/names.d.cts +11 -0
- package/dist/names.d.ts +11 -0
- package/dist/names.js +40 -0
- package/dist/navigation.cjs +210 -0
- package/dist/navigation.d.cts +18 -0
- package/dist/navigation.d.ts +18 -0
- package/dist/navigation.js +207 -0
- package/dist/notes-annotation-author.cjs +5 -0
- package/dist/notes-annotation-author.d.cts +4 -0
- package/dist/notes-annotation-author.d.ts +4 -0
- package/dist/notes-annotation-author.js +4 -0
- package/dist/objects-B7HdMeWS.d.cts +59 -0
- package/dist/objects-B7HdMeWS.d.ts +59 -0
- package/dist/objects.d.cts +1 -58
- package/dist/objects.d.ts +1 -58
- package/dist/optional-content.cjs +63 -0
- package/dist/optional-content.d.cts +12 -0
- package/dist/optional-content.d.ts +12 -0
- package/dist/optional-content.js +62 -0
- package/dist/parse.cjs +1 -1
- package/dist/parse.d.cts +2 -2
- package/dist/parse.d.ts +2 -2
- package/dist/parse.js +1 -1
- package/dist/pdf-text.cjs +21 -0
- package/dist/pdf-text.d.cts +5 -0
- package/dist/pdf-text.d.ts +5 -0
- package/dist/pdf-text.js +19 -0
- package/dist/predictors.d.cts +1 -1
- package/dist/predictors.d.ts +1 -1
- package/dist/read.cjs +287 -72
- package/dist/read.d.cts +2 -4
- package/dist/read.d.ts +2 -4
- package/dist/read.js +284 -67
- package/dist/serialize.cjs +5 -1
- package/dist/serialize.d.cts +3 -2
- package/dist/serialize.d.ts +3 -2
- package/dist/serialize.js +5 -2
- package/dist/sfnt-subset.cjs +10 -3
- package/dist/sfnt-subset.d.cts +1 -1
- package/dist/sfnt-subset.d.ts +1 -1
- package/dist/sfnt-subset.js +10 -3
- package/dist/structure.cjs +184 -0
- package/dist/structure.d.cts +12 -0
- package/dist/structure.d.ts +12 -0
- package/dist/structure.js +183 -0
- package/dist/tounicode.cjs +8 -3
- package/dist/tounicode.d.cts +2 -2
- package/dist/tounicode.d.ts +2 -2
- package/dist/tounicode.js +8 -3
- package/dist/util/base64.cjs +4 -4
- package/dist/util/base64.js +4 -4
- package/dist/winansi.cjs +1 -1
- package/dist/winansi.d.cts +1 -1
- package/dist/winansi.d.ts +1 -1
- package/dist/winansi.js +1 -1
- package/dist/write.cjs +464 -21
- package/dist/write.d.cts +4 -3
- package/dist/write.d.ts +4 -3
- package/dist/write.js +464 -20
- package/dist/xmp.cjs +46 -0
- package/dist/xmp.d.cts +14 -0
- package/dist/xmp.d.ts +14 -0
- package/dist/xmp.js +45 -0
- package/dist/xref.cjs +2 -2
- package/dist/xref.d.cts +3 -3
- package/dist/xref.d.ts +3 -3
- package/dist/xref.js +2 -2
- package/package.json +46 -31
- package/dist/image/png-encode.cjs +0 -64
- package/dist/image/png-encode.d.cts +0 -8
- package/dist/image/png-encode.d.ts +0 -8
- package/dist/image/png-encode.js +0 -63
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import { c as glyphNameToUnicode, d as standardGlyphName } from "./afm-widths-De_QMWgC.js";
|
|
2
|
+
import { hasBytes, parseSfnt, sfntTableBytes, u16, u8 } from "./sfnt.js";
|
|
3
|
+
import { cffStringForSid, parseCffDict, readCffIndex } from "./cff.js";
|
|
4
|
+
import { readCmapSubtables } from "./cmap-table.js";
|
|
5
|
+
import { parsePostGlyphNames } from "./font-tables.js";
|
|
6
|
+
//#region src/builtin-encoding.ts
|
|
7
|
+
function isPrivateUse(codePoint) {
|
|
8
|
+
return codePoint >= 57344 && codePoint <= 63743 || codePoint >= 983040 && codePoint <= 1048573 || codePoint >= 1048576 && codePoint <= 1114109;
|
|
9
|
+
}
|
|
10
|
+
function encodingFromSources(sources) {
|
|
11
|
+
const { codeToGlyphId, codeToName, glyphIdToName, glyphIdToUnicode } = sources;
|
|
12
|
+
const glyphUnicode = (glyphId) => {
|
|
13
|
+
const name = glyphIdToName?.(glyphId);
|
|
14
|
+
return (name !== void 0 ? glyphNameToUnicode(name) : void 0) ?? glyphIdToUnicode?.(glyphId);
|
|
15
|
+
};
|
|
16
|
+
const codeUnicode = (code) => {
|
|
17
|
+
const name = codeToName?.(code);
|
|
18
|
+
if (name !== void 0) {
|
|
19
|
+
const named = glyphNameToUnicode(name);
|
|
20
|
+
if (named !== void 0) return named;
|
|
21
|
+
}
|
|
22
|
+
const glyphId = codeToGlyphId?.(code);
|
|
23
|
+
return glyphId === void 0 ? void 0 : glyphUnicode(glyphId);
|
|
24
|
+
};
|
|
25
|
+
return codeToName !== void 0 || codeToGlyphId !== void 0 || glyphIdToName !== void 0 || glyphIdToUnicode !== void 0 ? {
|
|
26
|
+
codeToUnicode: codeUnicode,
|
|
27
|
+
glyphIdToUnicode: glyphUnicode
|
|
28
|
+
} : void 0;
|
|
29
|
+
}
|
|
30
|
+
const SYMBOL_CMAP_CODE_BASE = 61440;
|
|
31
|
+
function symbolSubtable(subtables) {
|
|
32
|
+
return subtables.find((s) => s.platformId === 3 && s.encodingId === 0) ?? subtables.find((s) => s.platformId === 1 && s.encodingId === 0);
|
|
33
|
+
}
|
|
34
|
+
function unicodeSubtable(subtables) {
|
|
35
|
+
return subtables.find((s) => s.platformId === 3 && s.encodingId === 10) ?? subtables.find((s) => s.platformId === 3 && s.encodingId === 1) ?? subtables.find((s) => s.platformId === 0);
|
|
36
|
+
}
|
|
37
|
+
function invertUnicodeSubtable(subtable) {
|
|
38
|
+
let inverse;
|
|
39
|
+
return (glyphId) => {
|
|
40
|
+
if (inverse === void 0) {
|
|
41
|
+
const built = /* @__PURE__ */ new Map();
|
|
42
|
+
subtable.forEachMapping((code, mappedGlyphId) => {
|
|
43
|
+
if (!isPrivateUse(code) && !built.has(mappedGlyphId)) built.set(mappedGlyphId, code);
|
|
44
|
+
});
|
|
45
|
+
inverse = built;
|
|
46
|
+
}
|
|
47
|
+
return inverse.get(glyphId);
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function trueTypeSources(font) {
|
|
51
|
+
const subtables = readCmapSubtables(font);
|
|
52
|
+
const symbol = symbolSubtable(subtables);
|
|
53
|
+
const unicode = unicodeSubtable(subtables);
|
|
54
|
+
return {
|
|
55
|
+
codeToGlyphId: symbol !== void 0 ? (code) => symbol.lookup(SYMBOL_CMAP_CODE_BASE | code) ?? symbol.lookup(code) : unicode !== void 0 ? (code) => unicode.lookup(SYMBOL_CMAP_CODE_BASE | code) : void 0,
|
|
56
|
+
glyphIdToName: parsePostGlyphNames(font),
|
|
57
|
+
glyphIdToUnicode: unicode !== void 0 ? invertUnicodeSubtable(unicode) : void 0
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
const CFF_HEADER_SIZE = 4;
|
|
61
|
+
const CFF_MAJOR_VERSION = 1;
|
|
62
|
+
const CFF_PREDEFINED_CHARSET_ISO_ADOBE = 0;
|
|
63
|
+
const CFF_PREDEFINED_ENCODING_STANDARD = 0;
|
|
64
|
+
const CFF_ENCODING_FORMAT_MASK = 127;
|
|
65
|
+
const CFF_ENCODING_SUPPLEMENT_FLAG = 128;
|
|
66
|
+
function readCffCharset(bytes, offset, glyphCount) {
|
|
67
|
+
const sidByGlyph = /* @__PURE__ */ new Map();
|
|
68
|
+
if (offset === CFF_PREDEFINED_CHARSET_ISO_ADOBE) {
|
|
69
|
+
for (let glyphId = 1; glyphId < glyphCount; glyphId++) sidByGlyph.set(glyphId, glyphId);
|
|
70
|
+
return sidByGlyph;
|
|
71
|
+
}
|
|
72
|
+
if (offset < CFF_HEADER_SIZE || !hasBytes(bytes, offset, 1)) return;
|
|
73
|
+
const format = u8(bytes, offset);
|
|
74
|
+
let cursor = offset + 1;
|
|
75
|
+
if (format === 0) {
|
|
76
|
+
for (let glyphId = 1; glyphId < glyphCount; glyphId++) {
|
|
77
|
+
if (!hasBytes(bytes, cursor, 2)) return sidByGlyph;
|
|
78
|
+
sidByGlyph.set(glyphId, u16(bytes, cursor));
|
|
79
|
+
cursor += 2;
|
|
80
|
+
}
|
|
81
|
+
return sidByGlyph;
|
|
82
|
+
}
|
|
83
|
+
if (format !== 1 && format !== 2) return;
|
|
84
|
+
const nLeftSize = format === 1 ? 1 : 2;
|
|
85
|
+
let glyphId = 1;
|
|
86
|
+
while (glyphId < glyphCount) {
|
|
87
|
+
if (!hasBytes(bytes, cursor, 2 + nLeftSize)) return sidByGlyph;
|
|
88
|
+
const firstSid = u16(bytes, cursor);
|
|
89
|
+
const nLeft = format === 1 ? u8(bytes, cursor + 2) : u16(bytes, cursor + 2);
|
|
90
|
+
for (let i = 0; i <= nLeft && glyphId < glyphCount; i++) {
|
|
91
|
+
sidByGlyph.set(glyphId, firstSid + i);
|
|
92
|
+
glyphId++;
|
|
93
|
+
}
|
|
94
|
+
cursor += 2 + nLeftSize;
|
|
95
|
+
}
|
|
96
|
+
return sidByGlyph;
|
|
97
|
+
}
|
|
98
|
+
function readCffEncoding(bytes, offset, glyphCount, glyphBySid) {
|
|
99
|
+
if (offset < CFF_HEADER_SIZE || !hasBytes(bytes, offset, 2)) return;
|
|
100
|
+
const formatByte = u8(bytes, offset);
|
|
101
|
+
const format = formatByte & CFF_ENCODING_FORMAT_MASK;
|
|
102
|
+
const glyphByCode = /* @__PURE__ */ new Map();
|
|
103
|
+
let cursor = offset + 1;
|
|
104
|
+
if (format === 0) {
|
|
105
|
+
const nCodes = u8(bytes, cursor);
|
|
106
|
+
cursor += 1;
|
|
107
|
+
for (let i = 0; i < nCodes; i++) {
|
|
108
|
+
if (!hasBytes(bytes, cursor, 1)) return glyphByCode;
|
|
109
|
+
const glyphId = i + 1;
|
|
110
|
+
if (glyphId < glyphCount) glyphByCode.set(u8(bytes, cursor), glyphId);
|
|
111
|
+
cursor += 1;
|
|
112
|
+
}
|
|
113
|
+
} else if (format === 1) {
|
|
114
|
+
const nRanges = u8(bytes, cursor);
|
|
115
|
+
cursor += 1;
|
|
116
|
+
let glyphId = 1;
|
|
117
|
+
for (let i = 0; i < nRanges; i++) {
|
|
118
|
+
if (!hasBytes(bytes, cursor, 2)) return glyphByCode;
|
|
119
|
+
const first = u8(bytes, cursor);
|
|
120
|
+
const nLeft = u8(bytes, cursor + 1);
|
|
121
|
+
for (let j = 0; j <= nLeft && glyphId < glyphCount; j++) {
|
|
122
|
+
glyphByCode.set(first + j, glyphId);
|
|
123
|
+
glyphId++;
|
|
124
|
+
}
|
|
125
|
+
cursor += 2;
|
|
126
|
+
}
|
|
127
|
+
} else return;
|
|
128
|
+
if ((formatByte & CFF_ENCODING_SUPPLEMENT_FLAG) !== 0) {
|
|
129
|
+
if (!hasBytes(bytes, cursor, 1)) return glyphByCode;
|
|
130
|
+
const nSups = u8(bytes, cursor);
|
|
131
|
+
cursor += 1;
|
|
132
|
+
for (let i = 0; i < nSups; i++) {
|
|
133
|
+
if (!hasBytes(bytes, cursor, 3)) return glyphByCode;
|
|
134
|
+
const glyphId = glyphBySid.get(u16(bytes, cursor + 1));
|
|
135
|
+
if (glyphId !== void 0) glyphByCode.set(u8(bytes, cursor), glyphId);
|
|
136
|
+
cursor += 3;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return glyphByCode;
|
|
140
|
+
}
|
|
141
|
+
function cffSources(bytes, predefinedEncodingApplies) {
|
|
142
|
+
if (!hasBytes(bytes, 0, CFF_HEADER_SIZE)) return;
|
|
143
|
+
const headerSize = u8(bytes, 2);
|
|
144
|
+
if (u8(bytes, 0) !== CFF_MAJOR_VERSION || headerSize < CFF_HEADER_SIZE) return;
|
|
145
|
+
const nameIndex = readCffIndex(bytes, headerSize);
|
|
146
|
+
if (nameIndex === void 0) return;
|
|
147
|
+
const topDictIndex = readCffIndex(bytes, nameIndex.endOffset);
|
|
148
|
+
const topDictBytes = topDictIndex?.entry(0);
|
|
149
|
+
if (topDictIndex === void 0 || topDictBytes === void 0) return;
|
|
150
|
+
const topDict = parseCffDict(topDictBytes);
|
|
151
|
+
if (topDict === void 0 || topDict.has(1230)) return;
|
|
152
|
+
const stringIndex = readCffIndex(bytes, topDictIndex.endOffset);
|
|
153
|
+
const charStringsOffset = topDict.get(17)?.[0];
|
|
154
|
+
const glyphCount = charStringsOffset === void 0 ? void 0 : readCffIndex(bytes, charStringsOffset)?.count;
|
|
155
|
+
if (glyphCount === void 0) return;
|
|
156
|
+
const sidByGlyph = readCffCharset(bytes, topDict.get(15)?.[0] ?? CFF_PREDEFINED_CHARSET_ISO_ADOBE, glyphCount);
|
|
157
|
+
const glyphIdToName = sidByGlyph === void 0 ? void 0 : (glyphId) => {
|
|
158
|
+
const sid = sidByGlyph.get(glyphId);
|
|
159
|
+
return sid === void 0 ? void 0 : cffStringForSid(sid, stringIndex);
|
|
160
|
+
};
|
|
161
|
+
const encodingOffset = topDict.get(16)?.[0] ?? CFF_PREDEFINED_ENCODING_STANDARD;
|
|
162
|
+
if (encodingOffset === CFF_PREDEFINED_ENCODING_STANDARD) return predefinedEncodingApplies ? {
|
|
163
|
+
codeToName: standardGlyphName,
|
|
164
|
+
glyphIdToName
|
|
165
|
+
} : { glyphIdToName };
|
|
166
|
+
const glyphBySid = /* @__PURE__ */ new Map();
|
|
167
|
+
for (const [glyphId, sid] of sidByGlyph ?? []) if (!glyphBySid.has(sid)) glyphBySid.set(sid, glyphId);
|
|
168
|
+
const glyphByCode = readCffEncoding(bytes, encodingOffset, glyphCount, glyphBySid);
|
|
169
|
+
return glyphByCode === void 0 ? { glyphIdToName } : {
|
|
170
|
+
codeToGlyphId: (code) => glyphByCode.get(code),
|
|
171
|
+
glyphIdToName
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
function matchesAscii(bytes, offset, text) {
|
|
175
|
+
for (let i = 0; i < text.length; i++) if (bytes[offset + i] !== text.charCodeAt(i)) return false;
|
|
176
|
+
return true;
|
|
177
|
+
}
|
|
178
|
+
const TYPE1_CLEARTEXT_TERMINATOR = "eexec";
|
|
179
|
+
const PFB_SEGMENT_MARKER = 128;
|
|
180
|
+
const PFB_SEGMENT_HEADER_SIZE = 6;
|
|
181
|
+
const POSTSCRIPT_MAGIC = "%!";
|
|
182
|
+
function type1Sources(bytes) {
|
|
183
|
+
const start = bytes[0] === PFB_SEGMENT_MARKER ? PFB_SEGMENT_HEADER_SIZE : 0;
|
|
184
|
+
if (!matchesAscii(bytes, start, POSTSCRIPT_MAGIC)) return;
|
|
185
|
+
let cleartextEnd = bytes.length;
|
|
186
|
+
for (let i = start; i + 5 <= bytes.length; i++) if (matchesAscii(bytes, i, TYPE1_CLEARTEXT_TERMINATOR)) {
|
|
187
|
+
cleartextEnd = i;
|
|
188
|
+
break;
|
|
189
|
+
}
|
|
190
|
+
let header = "";
|
|
191
|
+
for (let i = start; i < cleartextEnd; i++) header += String.fromCharCode(bytes[i] ?? 0);
|
|
192
|
+
if (!header.includes("/Encoding")) return;
|
|
193
|
+
if (/\/Encoding\s+StandardEncoding\s+def/.test(header)) return { codeToName: standardGlyphName };
|
|
194
|
+
const nameByCode = /* @__PURE__ */ new Map();
|
|
195
|
+
for (const match of header.matchAll(/dup\s+(\d+)\s*\/([^\s/[\]{}<>()%]+)\s+put/g)) {
|
|
196
|
+
const code = Number(match[1]);
|
|
197
|
+
const name = match[2];
|
|
198
|
+
if (name !== void 0 && Number.isInteger(code)) nameByCode.set(code, name);
|
|
199
|
+
}
|
|
200
|
+
return nameByCode.size === 0 ? void 0 : { codeToName: (code) => nameByCode.get(code) };
|
|
201
|
+
}
|
|
202
|
+
function readFontProgramEncoding(program) {
|
|
203
|
+
const font = parseSfnt(program);
|
|
204
|
+
if (font !== void 0) {
|
|
205
|
+
const cff = sfntTableBytes(font, "CFF ");
|
|
206
|
+
const container = trueTypeSources(font);
|
|
207
|
+
const outlines = cff === void 0 ? void 0 : cffSources(cff, false);
|
|
208
|
+
return encodingFromSources({
|
|
209
|
+
codeToGlyphId: container.codeToGlyphId ?? outlines?.codeToGlyphId,
|
|
210
|
+
glyphIdToName: container.glyphIdToName ?? outlines?.glyphIdToName,
|
|
211
|
+
glyphIdToUnicode: container.glyphIdToUnicode
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
const cff = cffSources(program, true);
|
|
215
|
+
if (cff !== void 0) return encodingFromSources(cff);
|
|
216
|
+
const type1 = type1Sources(program);
|
|
217
|
+
return type1 === void 0 ? void 0 : encodingFromSources(type1);
|
|
218
|
+
}
|
|
219
|
+
//#endregion
|
|
220
|
+
export { readFontProgramEncoding };
|
package/dist/bytes/flate.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_bytes_reader = require("./reader.cjs");
|
|
3
2
|
const require_bytes_writer = require("./writer.cjs");
|
|
3
|
+
const require_bytes_reader = require("./reader.cjs");
|
|
4
4
|
let fflate = require("fflate");
|
|
5
5
|
//#region src/bytes/flate.ts
|
|
6
6
|
const MAX_INFLATE_OUTPUT_BYTES = 536870912;
|
package/dist/bytes/flate.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { isAsciiWhitespace } from "./reader.js";
|
|
2
1
|
import { concatBytes } from "./writer.js";
|
|
2
|
+
import { isAsciiWhitespace } from "./reader.js";
|
|
3
3
|
import { Unzlib, inflateSync, unzlibSync, zlibSync } from "fflate";
|
|
4
4
|
//#region src/bytes/flate.ts
|
|
5
5
|
const MAX_INFLATE_OUTPUT_BYTES = 536870912;
|
package/dist/cff.cjs
CHANGED
|
@@ -3,6 +3,7 @@ const require_sfnt = require("./sfnt.cjs");
|
|
|
3
3
|
//#region src/cff.ts
|
|
4
4
|
const CFF_ESCAPED_OPERATOR_BASE = 1200;
|
|
5
5
|
const CFF_DICT_OP_CHARSET = 15;
|
|
6
|
+
const CFF_DICT_OP_ENCODING = 16;
|
|
6
7
|
const CFF_DICT_OP_CHARSTRINGS = 17;
|
|
7
8
|
const CFF_DICT_OP_PRIVATE = 18;
|
|
8
9
|
const CFF_DICT_OP_SUBRS = 19;
|
|
@@ -147,12 +148,25 @@ function parseCffDict(data) {
|
|
|
147
148
|
}
|
|
148
149
|
return dict;
|
|
149
150
|
}
|
|
151
|
+
const CFF_STANDARD_STRINGS = ".notdef space exclam quotedbl numbersign dollar percent ampersand quoteright parenleft parenright asterisk plus comma hyphen period slash zero one two three four five six seven eight nine colon semicolon less equal greater question at A B C D E F G H I J K L M N O P Q R S T U V W X Y Z bracketleft backslash bracketright asciicircum underscore quoteleft a b c d e f g h i j k l m n o p q r s t u v w x y z braceleft bar braceright asciitilde exclamdown cent sterling fraction yen florin section currency quotesingle quotedblleft guillemotleft guilsinglleft guilsinglright fi fl endash dagger daggerdbl periodcentered paragraph bullet quotesinglbase quotedblbase quotedblright guillemotright ellipsis perthousand questiondown grave acute circumflex tilde macron breve dotaccent dieresis ring cedilla hungarumlaut ogonek caron emdash AE ordfeminine Lslash Oslash OE ordmasculine ae dotlessi lslash oslash oe germandbls onesuperior logicalnot mu trademark Eth onehalf plusminus Thorn onequarter divide brokenbar degree thorn threequarters twosuperior registered minus eth multiply threesuperior copyright Aacute Acircumflex Adieresis Agrave Aring Atilde Ccedilla Eacute Ecircumflex Edieresis Egrave Iacute Icircumflex Idieresis Igrave Ntilde Oacute Ocircumflex Odieresis Ograve Otilde Scaron Uacute Ucircumflex Udieresis Ugrave Yacute Ydieresis Zcaron aacute acircumflex adieresis agrave aring atilde ccedilla eacute ecircumflex edieresis egrave iacute icircumflex idieresis igrave ntilde oacute ocircumflex odieresis ograve otilde scaron uacute ucircumflex udieresis ugrave yacute ydieresis zcaron exclamsmall Hungarumlautsmall dollaroldstyle dollarsuperior ampersandsmall Acutesmall parenleftsuperior parenrightsuperior twodotenleader onedotenleader zerooldstyle oneoldstyle twooldstyle threeoldstyle fouroldstyle fiveoldstyle sixoldstyle sevenoldstyle eightoldstyle nineoldstyle commasuperior threequartersemdash periodsuperior questionsmall asuperior bsuperior centsuperior dsuperior esuperior isuperior lsuperior msuperior nsuperior osuperior rsuperior ssuperior tsuperior ff ffi ffl parenleftinferior parenrightinferior Circumflexsmall hyphensuperior Gravesmall Asmall Bsmall Csmall Dsmall Esmall Fsmall Gsmall Hsmall Ismall Jsmall Ksmall Lsmall Msmall Nsmall Osmall Psmall Qsmall Rsmall Ssmall Tsmall Usmall Vsmall Wsmall Xsmall Ysmall Zsmall colonmonetary onefitted rupiah Tildesmall exclamdownsmall centoldstyle Lslashsmall Scaronsmall Zcaronsmall Dieresissmall Brevesmall Caronsmall Dotaccentsmall Macronsmall figuredash hypheninferior Ogoneksmall Ringsmall Cedillasmall questiondownsmall oneeighth threeeighths fiveeighths seveneighths onethird twothirds zerosuperior foursuperior fivesuperior sixsuperior sevensuperior eightsuperior ninesuperior zeroinferior oneinferior twoinferior threeinferior fourinferior fiveinferior sixinferior seveninferior eightinferior nineinferior centinferior dollarinferior periodinferior commainferior Agravesmall Aacutesmall Acircumflexsmall Atildesmall Adieresissmall Aringsmall AEsmall Ccedillasmall Egravesmall Eacutesmall Ecircumflexsmall Edieresissmall Igravesmall Iacutesmall Icircumflexsmall Idieresissmall Ethsmall Ntildesmall Ogravesmall Oacutesmall Ocircumflexsmall Otildesmall Odieresissmall OEsmall Oslashsmall Ugravesmall Uacutesmall Ucircumflexsmall Udieresissmall Yacutesmall Thornsmall Ydieresissmall 001.000 001.001 001.002 001.003 Black Bold Book Light Medium Regular Roman Semibold".split(" ");
|
|
152
|
+
function cffStringForSid(sid, stringIndex) {
|
|
153
|
+
const standard = CFF_STANDARD_STRINGS[sid];
|
|
154
|
+
if (standard !== void 0) return standard;
|
|
155
|
+
const entry = stringIndex?.entry(sid - CFF_STANDARD_STRINGS.length);
|
|
156
|
+
if (entry === void 0) return;
|
|
157
|
+
let text = "";
|
|
158
|
+
for (const byte of entry) text += String.fromCharCode(byte);
|
|
159
|
+
return text;
|
|
160
|
+
}
|
|
150
161
|
//#endregion
|
|
151
162
|
exports.CFF_DICT_OP_CHARSET = CFF_DICT_OP_CHARSET;
|
|
152
163
|
exports.CFF_DICT_OP_CHARSTRINGS = CFF_DICT_OP_CHARSTRINGS;
|
|
164
|
+
exports.CFF_DICT_OP_ENCODING = CFF_DICT_OP_ENCODING;
|
|
153
165
|
exports.CFF_DICT_OP_PRIVATE = CFF_DICT_OP_PRIVATE;
|
|
154
166
|
exports.CFF_DICT_OP_ROS = CFF_DICT_OP_ROS;
|
|
155
167
|
exports.CFF_DICT_OP_SUBRS = CFF_DICT_OP_SUBRS;
|
|
156
168
|
exports.CFF_ESCAPED_OPERATOR_BASE = CFF_ESCAPED_OPERATOR_BASE;
|
|
169
|
+
exports.CFF_STANDARD_STRINGS = CFF_STANDARD_STRINGS;
|
|
170
|
+
exports.cffStringForSid = cffStringForSid;
|
|
157
171
|
exports.parseCffDict = parseCffDict;
|
|
158
172
|
exports.readCffIndex = readCffIndex;
|
package/dist/cff.d.cts
CHANGED
|
@@ -7,11 +7,14 @@ interface CffIndex {
|
|
|
7
7
|
type CffDict = ReadonlyMap<number, readonly number[]>;
|
|
8
8
|
declare const CFF_ESCAPED_OPERATOR_BASE = 1200;
|
|
9
9
|
declare const CFF_DICT_OP_CHARSET = 15;
|
|
10
|
+
declare const CFF_DICT_OP_ENCODING = 16;
|
|
10
11
|
declare const CFF_DICT_OP_CHARSTRINGS = 17;
|
|
11
12
|
declare const CFF_DICT_OP_PRIVATE = 18;
|
|
12
13
|
declare const CFF_DICT_OP_SUBRS = 19;
|
|
13
14
|
declare const CFF_DICT_OP_ROS: number;
|
|
14
15
|
declare function readCffIndex(bytes: Uint8Array<ArrayBuffer>, offset: number): CffIndex | undefined;
|
|
15
16
|
declare function parseCffDict(data: Uint8Array<ArrayBuffer>): CffDict | undefined;
|
|
17
|
+
declare const CFF_STANDARD_STRINGS: readonly string[];
|
|
18
|
+
declare function cffStringForSid(sid: number, stringIndex: CffIndex | undefined): string | undefined;
|
|
16
19
|
//#endregion
|
|
17
|
-
export { CFF_DICT_OP_CHARSET, CFF_DICT_OP_CHARSTRINGS, CFF_DICT_OP_PRIVATE, CFF_DICT_OP_ROS, CFF_DICT_OP_SUBRS, CFF_ESCAPED_OPERATOR_BASE, CffDict, CffIndex, parseCffDict, readCffIndex };
|
|
20
|
+
export { CFF_DICT_OP_CHARSET, CFF_DICT_OP_CHARSTRINGS, CFF_DICT_OP_ENCODING, CFF_DICT_OP_PRIVATE, CFF_DICT_OP_ROS, CFF_DICT_OP_SUBRS, CFF_ESCAPED_OPERATOR_BASE, CFF_STANDARD_STRINGS, CffDict, CffIndex, cffStringForSid, parseCffDict, readCffIndex };
|
package/dist/cff.d.ts
CHANGED
|
@@ -7,11 +7,14 @@ interface CffIndex {
|
|
|
7
7
|
type CffDict = ReadonlyMap<number, readonly number[]>;
|
|
8
8
|
declare const CFF_ESCAPED_OPERATOR_BASE = 1200;
|
|
9
9
|
declare const CFF_DICT_OP_CHARSET = 15;
|
|
10
|
+
declare const CFF_DICT_OP_ENCODING = 16;
|
|
10
11
|
declare const CFF_DICT_OP_CHARSTRINGS = 17;
|
|
11
12
|
declare const CFF_DICT_OP_PRIVATE = 18;
|
|
12
13
|
declare const CFF_DICT_OP_SUBRS = 19;
|
|
13
14
|
declare const CFF_DICT_OP_ROS: number;
|
|
14
15
|
declare function readCffIndex(bytes: Uint8Array<ArrayBuffer>, offset: number): CffIndex | undefined;
|
|
15
16
|
declare function parseCffDict(data: Uint8Array<ArrayBuffer>): CffDict | undefined;
|
|
17
|
+
declare const CFF_STANDARD_STRINGS: readonly string[];
|
|
18
|
+
declare function cffStringForSid(sid: number, stringIndex: CffIndex | undefined): string | undefined;
|
|
16
19
|
//#endregion
|
|
17
|
-
export { CFF_DICT_OP_CHARSET, CFF_DICT_OP_CHARSTRINGS, CFF_DICT_OP_PRIVATE, CFF_DICT_OP_ROS, CFF_DICT_OP_SUBRS, CFF_ESCAPED_OPERATOR_BASE, CffDict, CffIndex, parseCffDict, readCffIndex };
|
|
20
|
+
export { CFF_DICT_OP_CHARSET, CFF_DICT_OP_CHARSTRINGS, CFF_DICT_OP_ENCODING, CFF_DICT_OP_PRIVATE, CFF_DICT_OP_ROS, CFF_DICT_OP_SUBRS, CFF_ESCAPED_OPERATOR_BASE, CFF_STANDARD_STRINGS, CffDict, CffIndex, cffStringForSid, parseCffDict, readCffIndex };
|
package/dist/cff.js
CHANGED
|
@@ -2,6 +2,7 @@ import { hasBytes, u16, u24, u32, u8 } from "./sfnt.js";
|
|
|
2
2
|
//#region src/cff.ts
|
|
3
3
|
const CFF_ESCAPED_OPERATOR_BASE = 1200;
|
|
4
4
|
const CFF_DICT_OP_CHARSET = 15;
|
|
5
|
+
const CFF_DICT_OP_ENCODING = 16;
|
|
5
6
|
const CFF_DICT_OP_CHARSTRINGS = 17;
|
|
6
7
|
const CFF_DICT_OP_PRIVATE = 18;
|
|
7
8
|
const CFF_DICT_OP_SUBRS = 19;
|
|
@@ -146,5 +147,15 @@ function parseCffDict(data) {
|
|
|
146
147
|
}
|
|
147
148
|
return dict;
|
|
148
149
|
}
|
|
150
|
+
const CFF_STANDARD_STRINGS = ".notdef space exclam quotedbl numbersign dollar percent ampersand quoteright parenleft parenright asterisk plus comma hyphen period slash zero one two three four five six seven eight nine colon semicolon less equal greater question at A B C D E F G H I J K L M N O P Q R S T U V W X Y Z bracketleft backslash bracketright asciicircum underscore quoteleft a b c d e f g h i j k l m n o p q r s t u v w x y z braceleft bar braceright asciitilde exclamdown cent sterling fraction yen florin section currency quotesingle quotedblleft guillemotleft guilsinglleft guilsinglright fi fl endash dagger daggerdbl periodcentered paragraph bullet quotesinglbase quotedblbase quotedblright guillemotright ellipsis perthousand questiondown grave acute circumflex tilde macron breve dotaccent dieresis ring cedilla hungarumlaut ogonek caron emdash AE ordfeminine Lslash Oslash OE ordmasculine ae dotlessi lslash oslash oe germandbls onesuperior logicalnot mu trademark Eth onehalf plusminus Thorn onequarter divide brokenbar degree thorn threequarters twosuperior registered minus eth multiply threesuperior copyright Aacute Acircumflex Adieresis Agrave Aring Atilde Ccedilla Eacute Ecircumflex Edieresis Egrave Iacute Icircumflex Idieresis Igrave Ntilde Oacute Ocircumflex Odieresis Ograve Otilde Scaron Uacute Ucircumflex Udieresis Ugrave Yacute Ydieresis Zcaron aacute acircumflex adieresis agrave aring atilde ccedilla eacute ecircumflex edieresis egrave iacute icircumflex idieresis igrave ntilde oacute ocircumflex odieresis ograve otilde scaron uacute ucircumflex udieresis ugrave yacute ydieresis zcaron exclamsmall Hungarumlautsmall dollaroldstyle dollarsuperior ampersandsmall Acutesmall parenleftsuperior parenrightsuperior twodotenleader onedotenleader zerooldstyle oneoldstyle twooldstyle threeoldstyle fouroldstyle fiveoldstyle sixoldstyle sevenoldstyle eightoldstyle nineoldstyle commasuperior threequartersemdash periodsuperior questionsmall asuperior bsuperior centsuperior dsuperior esuperior isuperior lsuperior msuperior nsuperior osuperior rsuperior ssuperior tsuperior ff ffi ffl parenleftinferior parenrightinferior Circumflexsmall hyphensuperior Gravesmall Asmall Bsmall Csmall Dsmall Esmall Fsmall Gsmall Hsmall Ismall Jsmall Ksmall Lsmall Msmall Nsmall Osmall Psmall Qsmall Rsmall Ssmall Tsmall Usmall Vsmall Wsmall Xsmall Ysmall Zsmall colonmonetary onefitted rupiah Tildesmall exclamdownsmall centoldstyle Lslashsmall Scaronsmall Zcaronsmall Dieresissmall Brevesmall Caronsmall Dotaccentsmall Macronsmall figuredash hypheninferior Ogoneksmall Ringsmall Cedillasmall questiondownsmall oneeighth threeeighths fiveeighths seveneighths onethird twothirds zerosuperior foursuperior fivesuperior sixsuperior sevensuperior eightsuperior ninesuperior zeroinferior oneinferior twoinferior threeinferior fourinferior fiveinferior sixinferior seveninferior eightinferior nineinferior centinferior dollarinferior periodinferior commainferior Agravesmall Aacutesmall Acircumflexsmall Atildesmall Adieresissmall Aringsmall AEsmall Ccedillasmall Egravesmall Eacutesmall Ecircumflexsmall Edieresissmall Igravesmall Iacutesmall Icircumflexsmall Idieresissmall Ethsmall Ntildesmall Ogravesmall Oacutesmall Ocircumflexsmall Otildesmall Odieresissmall OEsmall Oslashsmall Ugravesmall Uacutesmall Ucircumflexsmall Udieresissmall Yacutesmall Thornsmall Ydieresissmall 001.000 001.001 001.002 001.003 Black Bold Book Light Medium Regular Roman Semibold".split(" ");
|
|
151
|
+
function cffStringForSid(sid, stringIndex) {
|
|
152
|
+
const standard = CFF_STANDARD_STRINGS[sid];
|
|
153
|
+
if (standard !== void 0) return standard;
|
|
154
|
+
const entry = stringIndex?.entry(sid - CFF_STANDARD_STRINGS.length);
|
|
155
|
+
if (entry === void 0) return;
|
|
156
|
+
let text = "";
|
|
157
|
+
for (const byte of entry) text += String.fromCharCode(byte);
|
|
158
|
+
return text;
|
|
159
|
+
}
|
|
149
160
|
//#endregion
|
|
150
|
-
export { CFF_DICT_OP_CHARSET, CFF_DICT_OP_CHARSTRINGS, CFF_DICT_OP_PRIVATE, CFF_DICT_OP_ROS, CFF_DICT_OP_SUBRS, CFF_ESCAPED_OPERATOR_BASE, parseCffDict, readCffIndex };
|
|
161
|
+
export { CFF_DICT_OP_CHARSET, CFF_DICT_OP_CHARSTRINGS, CFF_DICT_OP_ENCODING, CFF_DICT_OP_PRIVATE, CFF_DICT_OP_ROS, CFF_DICT_OP_SUBRS, CFF_ESCAPED_OPERATOR_BASE, CFF_STANDARD_STRINGS, cffStringForSid, parseCffDict, readCffIndex };
|
package/dist/cmap-table.cjs
CHANGED
|
@@ -3,6 +3,7 @@ const require_sfnt = require("./sfnt.cjs");
|
|
|
3
3
|
//#region src/cmap-table.ts
|
|
4
4
|
const CMAP_HEADER_SIZE = 4;
|
|
5
5
|
const SUBTABLE_RECORD_SIZE = 8;
|
|
6
|
+
const MAX_UNICODE_CODE_POINT = 1114111;
|
|
6
7
|
const FORMAT_4_HEADER_SIZE = 14;
|
|
7
8
|
function parseFormat4(bytes, subtableOffset) {
|
|
8
9
|
if (!require_sfnt.hasBytes(bytes, subtableOffset, FORMAT_4_HEADER_SIZE)) return;
|
|
@@ -26,7 +27,7 @@ function parseFormat4(bytes, subtableOffset) {
|
|
|
26
27
|
idRangeOffset: require_sfnt.u16(bytes, idRangeOffsetPos)
|
|
27
28
|
});
|
|
28
29
|
}
|
|
29
|
-
|
|
30
|
+
const lookup = (codePoint) => {
|
|
30
31
|
if (codePoint > 65535) return;
|
|
31
32
|
for (const segment of segments) {
|
|
32
33
|
if (codePoint < segment.startCode || codePoint > segment.endCode) continue;
|
|
@@ -37,6 +38,18 @@ function parseFormat4(bytes, subtableOffset) {
|
|
|
37
38
|
return glyphId === 0 ? void 0 : glyphId + segment.idDelta & 65535;
|
|
38
39
|
}
|
|
39
40
|
};
|
|
41
|
+
return {
|
|
42
|
+
lookup,
|
|
43
|
+
forEachMapping(visit) {
|
|
44
|
+
for (const segment of segments) {
|
|
45
|
+
const end = Math.min(segment.endCode, 65534);
|
|
46
|
+
for (let code = segment.startCode; code <= end; code++) {
|
|
47
|
+
const glyphId = lookup(code);
|
|
48
|
+
if (glyphId !== void 0 && glyphId !== 0) visit(code, glyphId);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
};
|
|
40
53
|
}
|
|
41
54
|
const FORMAT_12_HEADER_SIZE = 16;
|
|
42
55
|
const FORMAT_12_GROUP_SIZE = 12;
|
|
@@ -54,8 +67,35 @@ function parseFormat12(bytes, subtableOffset) {
|
|
|
54
67
|
startGlyphId: require_sfnt.u32(bytes, recordOffset + 8)
|
|
55
68
|
});
|
|
56
69
|
}
|
|
57
|
-
return
|
|
58
|
-
|
|
70
|
+
return {
|
|
71
|
+
lookup(codePoint) {
|
|
72
|
+
for (const group of groups) if (codePoint >= group.startCharCode && codePoint <= group.endCharCode) return group.startGlyphId + (codePoint - group.startCharCode);
|
|
73
|
+
},
|
|
74
|
+
forEachMapping(visit) {
|
|
75
|
+
for (const group of groups) {
|
|
76
|
+
const end = Math.min(group.endCharCode, MAX_UNICODE_CODE_POINT);
|
|
77
|
+
for (let code = group.startCharCode; code <= end; code++) visit(code, group.startGlyphId + (code - group.startCharCode));
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
const FORMAT_0_SIZE = 262;
|
|
83
|
+
function parseFormat0(bytes, subtableOffset) {
|
|
84
|
+
if (!require_sfnt.hasBytes(bytes, subtableOffset, FORMAT_0_SIZE)) return;
|
|
85
|
+
const glyphIdArrayOffset = subtableOffset + 6;
|
|
86
|
+
const lookup = (codePoint) => {
|
|
87
|
+
if (codePoint < 0 || codePoint > 255) return;
|
|
88
|
+
const glyphId = require_sfnt.u8(bytes, glyphIdArrayOffset + codePoint);
|
|
89
|
+
return glyphId === 0 ? void 0 : glyphId;
|
|
90
|
+
};
|
|
91
|
+
return {
|
|
92
|
+
lookup,
|
|
93
|
+
forEachMapping(visit) {
|
|
94
|
+
for (let code = 0; code <= 255; code++) {
|
|
95
|
+
const glyphId = lookup(code);
|
|
96
|
+
if (glyphId !== void 0) visit(code, glyphId);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
59
99
|
};
|
|
60
100
|
}
|
|
61
101
|
const FORMAT_6_HEADER_SIZE = 10;
|
|
@@ -65,12 +105,22 @@ function parseFormat6(bytes, subtableOffset) {
|
|
|
65
105
|
const entryCount = require_sfnt.u16(bytes, subtableOffset + 8);
|
|
66
106
|
const glyphIdArrayOffset = subtableOffset + FORMAT_6_HEADER_SIZE;
|
|
67
107
|
if (!require_sfnt.hasBytes(bytes, glyphIdArrayOffset, entryCount * 2)) return;
|
|
68
|
-
|
|
108
|
+
const lookup = (codePoint) => {
|
|
69
109
|
const index = codePoint - firstCode;
|
|
70
110
|
if (index < 0 || index >= entryCount) return;
|
|
71
111
|
const glyphId = require_sfnt.u16(bytes, glyphIdArrayOffset + index * 2);
|
|
72
112
|
return glyphId === 0 ? void 0 : glyphId;
|
|
73
113
|
};
|
|
114
|
+
return {
|
|
115
|
+
lookup,
|
|
116
|
+
forEachMapping(visit) {
|
|
117
|
+
for (let index = 0; index < entryCount; index++) {
|
|
118
|
+
const code = firstCode + index;
|
|
119
|
+
const glyphId = lookup(code);
|
|
120
|
+
if (glyphId !== void 0) visit(code, glyphId);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
};
|
|
74
124
|
}
|
|
75
125
|
function preferenceRank(subtable) {
|
|
76
126
|
if (subtable.format === 12) {
|
|
@@ -81,28 +131,41 @@ function preferenceRank(subtable) {
|
|
|
81
131
|
if (subtable.format === 4) return subtable.platformId === 3 && subtable.encodingId === 1 ? 3 : 4;
|
|
82
132
|
return 5;
|
|
83
133
|
}
|
|
84
|
-
function
|
|
134
|
+
function parseSubtable(bytes, record) {
|
|
135
|
+
if (record.format === 12) return parseFormat12(bytes, record.offset);
|
|
136
|
+
if (record.format === 4) return parseFormat4(bytes, record.offset);
|
|
137
|
+
if (record.format === 6) return parseFormat6(bytes, record.offset);
|
|
138
|
+
return record.format === 0 ? parseFormat0(bytes, record.offset) : void 0;
|
|
139
|
+
}
|
|
140
|
+
function readCmapSubtables(font) {
|
|
85
141
|
const cmapBytes = require_sfnt.sfntTableBytes(font, "cmap");
|
|
86
|
-
if (cmapBytes === void 0 || !require_sfnt.hasBytes(cmapBytes, 0, CMAP_HEADER_SIZE)) return;
|
|
142
|
+
if (cmapBytes === void 0 || !require_sfnt.hasBytes(cmapBytes, 0, CMAP_HEADER_SIZE)) return [];
|
|
87
143
|
const numTables = require_sfnt.u16(cmapBytes, 2);
|
|
88
|
-
if (!require_sfnt.hasBytes(cmapBytes, CMAP_HEADER_SIZE, numTables * SUBTABLE_RECORD_SIZE)) return;
|
|
144
|
+
if (!require_sfnt.hasBytes(cmapBytes, CMAP_HEADER_SIZE, numTables * SUBTABLE_RECORD_SIZE)) return [];
|
|
89
145
|
const subtables = [];
|
|
90
146
|
for (let i = 0; i < numTables; i++) {
|
|
91
147
|
const recordOffset = CMAP_HEADER_SIZE + i * SUBTABLE_RECORD_SIZE;
|
|
92
148
|
const offset = require_sfnt.u32(cmapBytes, recordOffset + 4);
|
|
93
149
|
if (!require_sfnt.hasBytes(cmapBytes, offset, 2)) continue;
|
|
94
|
-
|
|
150
|
+
const record = {
|
|
95
151
|
platformId: require_sfnt.u16(cmapBytes, recordOffset),
|
|
96
152
|
encodingId: require_sfnt.u16(cmapBytes, recordOffset + 2),
|
|
97
153
|
offset,
|
|
98
154
|
format: require_sfnt.u16(cmapBytes, offset)
|
|
155
|
+
};
|
|
156
|
+
const parsed = parseSubtable(cmapBytes, record);
|
|
157
|
+
if (parsed !== void 0) subtables.push({
|
|
158
|
+
platformId: record.platformId,
|
|
159
|
+
encodingId: record.encodingId,
|
|
160
|
+
format: record.format,
|
|
161
|
+
...parsed
|
|
99
162
|
});
|
|
100
163
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}
|
|
164
|
+
return subtables;
|
|
165
|
+
}
|
|
166
|
+
function buildCmapLookup(font) {
|
|
167
|
+
return readCmapSubtables(font).filter((s) => s.format === 4 || s.format === 6 || s.format === 12).sort((a, b) => preferenceRank(a) - preferenceRank(b))[0]?.lookup;
|
|
106
168
|
}
|
|
107
169
|
//#endregion
|
|
108
170
|
exports.buildCmapLookup = buildCmapLookup;
|
|
171
|
+
exports.readCmapSubtables = readCmapSubtables;
|
package/dist/cmap-table.d.cts
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import { t as SfntFont } from "./sfnt-V08bb5ut.cjs";
|
|
2
2
|
//#region src/cmap-table.d.ts
|
|
3
3
|
type CmapLookup = (codePoint: number) => number | undefined;
|
|
4
|
+
interface CmapSubtable {
|
|
5
|
+
readonly platformId: number;
|
|
6
|
+
readonly encodingId: number;
|
|
7
|
+
readonly format: number;
|
|
8
|
+
readonly lookup: CmapLookup;
|
|
9
|
+
forEachMapping(visit: (code: number, glyphId: number) => void): void;
|
|
10
|
+
}
|
|
11
|
+
declare function readCmapSubtables(font: SfntFont): readonly CmapSubtable[];
|
|
4
12
|
declare function buildCmapLookup(font: SfntFont): CmapLookup | undefined;
|
|
5
13
|
//#endregion
|
|
6
|
-
export { CmapLookup, buildCmapLookup };
|
|
14
|
+
export { CmapLookup, CmapSubtable, buildCmapLookup, readCmapSubtables };
|
package/dist/cmap-table.d.ts
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import { t as SfntFont } from "./sfnt-V08bb5ut.js";
|
|
2
2
|
//#region src/cmap-table.d.ts
|
|
3
3
|
type CmapLookup = (codePoint: number) => number | undefined;
|
|
4
|
+
interface CmapSubtable {
|
|
5
|
+
readonly platformId: number;
|
|
6
|
+
readonly encodingId: number;
|
|
7
|
+
readonly format: number;
|
|
8
|
+
readonly lookup: CmapLookup;
|
|
9
|
+
forEachMapping(visit: (code: number, glyphId: number) => void): void;
|
|
10
|
+
}
|
|
11
|
+
declare function readCmapSubtables(font: SfntFont): readonly CmapSubtable[];
|
|
4
12
|
declare function buildCmapLookup(font: SfntFont): CmapLookup | undefined;
|
|
5
13
|
//#endregion
|
|
6
|
-
export { CmapLookup, buildCmapLookup };
|
|
14
|
+
export { CmapLookup, CmapSubtable, buildCmapLookup, readCmapSubtables };
|
package/dist/cmap-table.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { hasBytes, sfntTableBytes, u16, u32 } from "./sfnt.js";
|
|
1
|
+
import { hasBytes, sfntTableBytes, u16, u32, u8 } from "./sfnt.js";
|
|
2
2
|
//#region src/cmap-table.ts
|
|
3
3
|
const CMAP_HEADER_SIZE = 4;
|
|
4
4
|
const SUBTABLE_RECORD_SIZE = 8;
|
|
5
|
+
const MAX_UNICODE_CODE_POINT = 1114111;
|
|
5
6
|
const FORMAT_4_HEADER_SIZE = 14;
|
|
6
7
|
function parseFormat4(bytes, subtableOffset) {
|
|
7
8
|
if (!hasBytes(bytes, subtableOffset, FORMAT_4_HEADER_SIZE)) return;
|
|
@@ -25,7 +26,7 @@ function parseFormat4(bytes, subtableOffset) {
|
|
|
25
26
|
idRangeOffset: u16(bytes, idRangeOffsetPos)
|
|
26
27
|
});
|
|
27
28
|
}
|
|
28
|
-
|
|
29
|
+
const lookup = (codePoint) => {
|
|
29
30
|
if (codePoint > 65535) return;
|
|
30
31
|
for (const segment of segments) {
|
|
31
32
|
if (codePoint < segment.startCode || codePoint > segment.endCode) continue;
|
|
@@ -36,6 +37,18 @@ function parseFormat4(bytes, subtableOffset) {
|
|
|
36
37
|
return glyphId === 0 ? void 0 : glyphId + segment.idDelta & 65535;
|
|
37
38
|
}
|
|
38
39
|
};
|
|
40
|
+
return {
|
|
41
|
+
lookup,
|
|
42
|
+
forEachMapping(visit) {
|
|
43
|
+
for (const segment of segments) {
|
|
44
|
+
const end = Math.min(segment.endCode, 65534);
|
|
45
|
+
for (let code = segment.startCode; code <= end; code++) {
|
|
46
|
+
const glyphId = lookup(code);
|
|
47
|
+
if (glyphId !== void 0 && glyphId !== 0) visit(code, glyphId);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
};
|
|
39
52
|
}
|
|
40
53
|
const FORMAT_12_HEADER_SIZE = 16;
|
|
41
54
|
const FORMAT_12_GROUP_SIZE = 12;
|
|
@@ -53,8 +66,35 @@ function parseFormat12(bytes, subtableOffset) {
|
|
|
53
66
|
startGlyphId: u32(bytes, recordOffset + 8)
|
|
54
67
|
});
|
|
55
68
|
}
|
|
56
|
-
return
|
|
57
|
-
|
|
69
|
+
return {
|
|
70
|
+
lookup(codePoint) {
|
|
71
|
+
for (const group of groups) if (codePoint >= group.startCharCode && codePoint <= group.endCharCode) return group.startGlyphId + (codePoint - group.startCharCode);
|
|
72
|
+
},
|
|
73
|
+
forEachMapping(visit) {
|
|
74
|
+
for (const group of groups) {
|
|
75
|
+
const end = Math.min(group.endCharCode, MAX_UNICODE_CODE_POINT);
|
|
76
|
+
for (let code = group.startCharCode; code <= end; code++) visit(code, group.startGlyphId + (code - group.startCharCode));
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
const FORMAT_0_SIZE = 262;
|
|
82
|
+
function parseFormat0(bytes, subtableOffset) {
|
|
83
|
+
if (!hasBytes(bytes, subtableOffset, FORMAT_0_SIZE)) return;
|
|
84
|
+
const glyphIdArrayOffset = subtableOffset + 6;
|
|
85
|
+
const lookup = (codePoint) => {
|
|
86
|
+
if (codePoint < 0 || codePoint > 255) return;
|
|
87
|
+
const glyphId = u8(bytes, glyphIdArrayOffset + codePoint);
|
|
88
|
+
return glyphId === 0 ? void 0 : glyphId;
|
|
89
|
+
};
|
|
90
|
+
return {
|
|
91
|
+
lookup,
|
|
92
|
+
forEachMapping(visit) {
|
|
93
|
+
for (let code = 0; code <= 255; code++) {
|
|
94
|
+
const glyphId = lookup(code);
|
|
95
|
+
if (glyphId !== void 0) visit(code, glyphId);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
58
98
|
};
|
|
59
99
|
}
|
|
60
100
|
const FORMAT_6_HEADER_SIZE = 10;
|
|
@@ -64,12 +104,22 @@ function parseFormat6(bytes, subtableOffset) {
|
|
|
64
104
|
const entryCount = u16(bytes, subtableOffset + 8);
|
|
65
105
|
const glyphIdArrayOffset = subtableOffset + FORMAT_6_HEADER_SIZE;
|
|
66
106
|
if (!hasBytes(bytes, glyphIdArrayOffset, entryCount * 2)) return;
|
|
67
|
-
|
|
107
|
+
const lookup = (codePoint) => {
|
|
68
108
|
const index = codePoint - firstCode;
|
|
69
109
|
if (index < 0 || index >= entryCount) return;
|
|
70
110
|
const glyphId = u16(bytes, glyphIdArrayOffset + index * 2);
|
|
71
111
|
return glyphId === 0 ? void 0 : glyphId;
|
|
72
112
|
};
|
|
113
|
+
return {
|
|
114
|
+
lookup,
|
|
115
|
+
forEachMapping(visit) {
|
|
116
|
+
for (let index = 0; index < entryCount; index++) {
|
|
117
|
+
const code = firstCode + index;
|
|
118
|
+
const glyphId = lookup(code);
|
|
119
|
+
if (glyphId !== void 0) visit(code, glyphId);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
};
|
|
73
123
|
}
|
|
74
124
|
function preferenceRank(subtable) {
|
|
75
125
|
if (subtable.format === 12) {
|
|
@@ -80,28 +130,40 @@ function preferenceRank(subtable) {
|
|
|
80
130
|
if (subtable.format === 4) return subtable.platformId === 3 && subtable.encodingId === 1 ? 3 : 4;
|
|
81
131
|
return 5;
|
|
82
132
|
}
|
|
83
|
-
function
|
|
133
|
+
function parseSubtable(bytes, record) {
|
|
134
|
+
if (record.format === 12) return parseFormat12(bytes, record.offset);
|
|
135
|
+
if (record.format === 4) return parseFormat4(bytes, record.offset);
|
|
136
|
+
if (record.format === 6) return parseFormat6(bytes, record.offset);
|
|
137
|
+
return record.format === 0 ? parseFormat0(bytes, record.offset) : void 0;
|
|
138
|
+
}
|
|
139
|
+
function readCmapSubtables(font) {
|
|
84
140
|
const cmapBytes = sfntTableBytes(font, "cmap");
|
|
85
|
-
if (cmapBytes === void 0 || !hasBytes(cmapBytes, 0, CMAP_HEADER_SIZE)) return;
|
|
141
|
+
if (cmapBytes === void 0 || !hasBytes(cmapBytes, 0, CMAP_HEADER_SIZE)) return [];
|
|
86
142
|
const numTables = u16(cmapBytes, 2);
|
|
87
|
-
if (!hasBytes(cmapBytes, CMAP_HEADER_SIZE, numTables * SUBTABLE_RECORD_SIZE)) return;
|
|
143
|
+
if (!hasBytes(cmapBytes, CMAP_HEADER_SIZE, numTables * SUBTABLE_RECORD_SIZE)) return [];
|
|
88
144
|
const subtables = [];
|
|
89
145
|
for (let i = 0; i < numTables; i++) {
|
|
90
146
|
const recordOffset = CMAP_HEADER_SIZE + i * SUBTABLE_RECORD_SIZE;
|
|
91
147
|
const offset = u32(cmapBytes, recordOffset + 4);
|
|
92
148
|
if (!hasBytes(cmapBytes, offset, 2)) continue;
|
|
93
|
-
|
|
149
|
+
const record = {
|
|
94
150
|
platformId: u16(cmapBytes, recordOffset),
|
|
95
151
|
encodingId: u16(cmapBytes, recordOffset + 2),
|
|
96
152
|
offset,
|
|
97
153
|
format: u16(cmapBytes, offset)
|
|
154
|
+
};
|
|
155
|
+
const parsed = parseSubtable(cmapBytes, record);
|
|
156
|
+
if (parsed !== void 0) subtables.push({
|
|
157
|
+
platformId: record.platformId,
|
|
158
|
+
encodingId: record.encodingId,
|
|
159
|
+
format: record.format,
|
|
160
|
+
...parsed
|
|
98
161
|
});
|
|
99
162
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
}
|
|
163
|
+
return subtables;
|
|
164
|
+
}
|
|
165
|
+
function buildCmapLookup(font) {
|
|
166
|
+
return readCmapSubtables(font).filter((s) => s.format === 4 || s.format === 6 || s.format === 12).sort((a, b) => preferenceRank(a) - preferenceRank(b))[0]?.lookup;
|
|
105
167
|
}
|
|
106
168
|
//#endregion
|
|
107
|
-
export { buildCmapLookup };
|
|
169
|
+
export { buildCmapLookup, readCmapSubtables };
|