web-doc 0.9.0 → 0.10.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/THIRD_PARTY_NOTICES.md +14 -0
- package/dist/adapters/office.js +2 -1
- package/dist/contracts.d.ts +9 -0
- package/dist/edit/pdf/engine/cff.d.ts +28 -0
- package/dist/edit/pdf/engine/cff.js +416 -0
- package/dist/edit/pdf/engine/document.d.ts +3 -1
- package/dist/edit/pdf/engine/document.js +21 -1
- package/dist/edit/pdf/engine/elements.d.ts +7 -0
- package/dist/edit/pdf/engine/elements.js +12 -1
- package/dist/edit/pdf/engine/existing-text.js +6 -4
- package/dist/edit/pdf/engine/glyph-names.d.ts +2 -0
- package/dist/edit/pdf/engine/glyph-names.js +163 -0
- package/dist/edit/pdf/engine/handler.js +2 -0
- package/dist/edit/pdf/engine/opentype.d.ts +14 -0
- package/dist/edit/pdf/engine/opentype.js +317 -0
- package/dist/edit/pdf/engine/text-font.d.ts +4 -0
- package/dist/edit/pdf/engine/text-font.js +81 -0
- package/dist/edit/pdf/provider.d.ts +3 -1
- package/dist/edit/pdf/provider.js +3 -0
- package/dist/edit/pdf/session.d.ts +2 -1
- package/dist/edit/pdf/session.js +3 -0
- package/dist/edit/pdf/types.d.ts +40 -0
- package/dist/edit/pptx/session.d.ts +7 -2
- package/dist/edit/pptx/session.js +41 -3
- package/dist/viewport.js +83 -20
- package/dist/worker-protocol.d.ts +1 -1
- package/dist/workers/pdf-edit-worker.js +1118 -184
- package/package.json +1 -1
|
@@ -3661,7 +3661,7 @@ var init_index_browser = __esm({
|
|
|
3661
3661
|
// count: 1
|
|
3662
3662
|
];
|
|
3663
3663
|
generateFuncType(sig, typeSectionBody);
|
|
3664
|
-
var
|
|
3664
|
+
var bytes2 = [
|
|
3665
3665
|
0,
|
|
3666
3666
|
97,
|
|
3667
3667
|
115,
|
|
@@ -3675,9 +3675,9 @@ var init_index_browser = __esm({
|
|
|
3675
3675
|
1
|
|
3676
3676
|
// Type section code
|
|
3677
3677
|
];
|
|
3678
|
-
uleb128Encode(typeSectionBody.length,
|
|
3679
|
-
|
|
3680
|
-
|
|
3678
|
+
uleb128Encode(typeSectionBody.length, bytes2);
|
|
3679
|
+
bytes2.push(...typeSectionBody);
|
|
3680
|
+
bytes2.push(
|
|
3681
3681
|
2,
|
|
3682
3682
|
7,
|
|
3683
3683
|
// import section
|
|
@@ -3699,7 +3699,7 @@ var init_index_browser = __esm({
|
|
|
3699
3699
|
0,
|
|
3700
3700
|
0
|
|
3701
3701
|
);
|
|
3702
|
-
var module = new WebAssembly.Module(new Uint8Array(
|
|
3702
|
+
var module = new WebAssembly.Module(new Uint8Array(bytes2));
|
|
3703
3703
|
var instance = new WebAssembly.Instance(module, { "e": { "f": func } });
|
|
3704
3704
|
var wrappedFunc = instance.exports["f"];
|
|
3705
3705
|
return wrappedFunc;
|
|
@@ -6378,15 +6378,15 @@ function readMark(pdfium, object) {
|
|
|
6378
6378
|
for (let index = 0; index < lib.FPDFPageObj_CountMarks(object); index += 1) {
|
|
6379
6379
|
const mark = lib.FPDFPageObj_GetMark(object, index);
|
|
6380
6380
|
const name = pdfium.readWideStringOut(
|
|
6381
|
-
(buffer,
|
|
6381
|
+
(buffer, bytes2, out) => lib.FPDFPageObjMark_GetName(mark, buffer, bytes2, out)
|
|
6382
6382
|
);
|
|
6383
6383
|
if (name !== MARK_NAME) continue;
|
|
6384
6384
|
const raw = pdfium.readWideStringOut(
|
|
6385
|
-
(buffer,
|
|
6385
|
+
(buffer, bytes2, out) => lib.FPDFPageObjMark_GetParamStringValue(
|
|
6386
6386
|
mark,
|
|
6387
6387
|
MARK_PARAM,
|
|
6388
6388
|
buffer,
|
|
6389
|
-
|
|
6389
|
+
bytes2,
|
|
6390
6390
|
out
|
|
6391
6391
|
)
|
|
6392
6392
|
);
|
|
@@ -6535,17 +6535,21 @@ var TABLE_OPERATIONS = Object.freeze([
|
|
|
6535
6535
|
]);
|
|
6536
6536
|
function textOf(pdfium, object, textPage) {
|
|
6537
6537
|
return pdfium.readWideString(
|
|
6538
|
-
(buffer,
|
|
6538
|
+
(buffer, bytes2) => pdfium.lib.FPDFTextObj_GetText(object, textPage, buffer, bytes2)
|
|
6539
6539
|
);
|
|
6540
6540
|
}
|
|
6541
|
+
function textScale(matrix) {
|
|
6542
|
+
const scale = matrix ? Math.hypot(matrix[2], matrix[3]) : 1;
|
|
6543
|
+
return Number.isFinite(scale) && scale > 0 ? scale : 1;
|
|
6544
|
+
}
|
|
6541
6545
|
function textStyle(pdfium, object) {
|
|
6542
6546
|
const { lib } = pdfium;
|
|
6543
6547
|
const font = lib.FPDFTextObj_GetFont(object);
|
|
6544
6548
|
const baseName = pdfium.readUtf8String(
|
|
6545
|
-
(buffer,
|
|
6549
|
+
(buffer, bytes2) => lib.FPDFFont_GetBaseFontName(font, buffer, bytes2)
|
|
6546
6550
|
);
|
|
6547
6551
|
const family = lib.FPDFFont_GetIsEmbedded(font) ? pdfium.readUtf8String(
|
|
6548
|
-
(buffer,
|
|
6552
|
+
(buffer, bytes2) => lib.FPDFFont_GetFamilyName(font, buffer, bytes2)
|
|
6549
6553
|
) || declaredFamily(baseName) : declaredFamily(baseName);
|
|
6550
6554
|
const flags = lib.FPDFFont_GetFlags(font);
|
|
6551
6555
|
const weight = lib.FPDFFont_GetWeight(font);
|
|
@@ -6554,9 +6558,14 @@ function textStyle(pdfium, object) {
|
|
|
6554
6558
|
"float",
|
|
6555
6559
|
([pointer]) => lib.FPDFTextObj_GetFontSize(object, pointer)
|
|
6556
6560
|
)?.[0] ?? 0;
|
|
6561
|
+
const matrix = pdfium.readNumbers(
|
|
6562
|
+
6,
|
|
6563
|
+
"float",
|
|
6564
|
+
([pointer]) => lib.FPDFPageObj_GetMatrix(object, pointer)
|
|
6565
|
+
);
|
|
6557
6566
|
return {
|
|
6558
6567
|
fontFamily: family,
|
|
6559
|
-
fontSize: round(size),
|
|
6568
|
+
fontSize: round(size * textScale(matrix)),
|
|
6560
6569
|
bold: weight >= 600 || (flags & FLAG_FORCE_BOLD) !== 0 || /bold|black|heavy/i.test(baseName),
|
|
6561
6570
|
italic: (flags & FLAG_ITALIC) !== 0 || /italic|oblique/i.test(baseName),
|
|
6562
6571
|
color: fillColor(pdfium, object) ?? "#000000"
|
|
@@ -6947,8 +6956,8 @@ var FontLibrary = class {
|
|
|
6947
6956
|
for (const handle of handles.values()) pdfium.lib.FPDFFont_Close(handle);
|
|
6948
6957
|
this.#handles.delete(document2);
|
|
6949
6958
|
}
|
|
6950
|
-
covers(
|
|
6951
|
-
return this.#covers(
|
|
6959
|
+
covers(bytes2, text) {
|
|
6960
|
+
return this.#covers(bytes2, text);
|
|
6952
6961
|
}
|
|
6953
6962
|
#coveringRegistered(request) {
|
|
6954
6963
|
const candidates = this.#registered.filter((font) => sameFamily(font.family, request.family)).map((font) => ({ font, bytes: this.#loadedBytes(font) })).filter(
|
|
@@ -6957,15 +6966,15 @@ var FontLibrary = class {
|
|
|
6957
6966
|
const score = (font) => (isBold(font) === request.bold ? 2 : 0) + (isItalic(font) === request.italic ? 1 : 0);
|
|
6958
6967
|
return candidates.sort((a, b) => score(b.font) - score(a.font))[0];
|
|
6959
6968
|
}
|
|
6960
|
-
#covers(
|
|
6961
|
-
return this.#firstMissing(
|
|
6969
|
+
#covers(bytes2, text) {
|
|
6970
|
+
return this.#firstMissing(bytes2, text) === void 0;
|
|
6962
6971
|
}
|
|
6963
6972
|
/** The first character of `text` the font has no glyph for; layout handles line breaks and spaces. */
|
|
6964
|
-
#firstMissing(
|
|
6965
|
-
let coverage = this.#coverage.get(
|
|
6973
|
+
#firstMissing(bytes2, text) {
|
|
6974
|
+
let coverage = this.#coverage.get(bytes2);
|
|
6966
6975
|
if (!coverage) {
|
|
6967
|
-
coverage = parseCmap(
|
|
6968
|
-
this.#coverage.set(
|
|
6976
|
+
coverage = parseCmap(bytes2);
|
|
6977
|
+
this.#coverage.set(bytes2, coverage);
|
|
6969
6978
|
}
|
|
6970
6979
|
for (const character of text) {
|
|
6971
6980
|
const code = character.codePointAt(0);
|
|
@@ -6974,20 +6983,20 @@ var FontLibrary = class {
|
|
|
6974
6983
|
}
|
|
6975
6984
|
return void 0;
|
|
6976
6985
|
}
|
|
6977
|
-
#load(pdfium, document2,
|
|
6986
|
+
#load(pdfium, document2, bytes2) {
|
|
6978
6987
|
let handles = this.#handles.get(document2);
|
|
6979
6988
|
if (!handles) {
|
|
6980
6989
|
handles = /* @__PURE__ */ new Map();
|
|
6981
6990
|
this.#handles.set(document2, handles);
|
|
6982
6991
|
}
|
|
6983
|
-
let handle = handles.get(
|
|
6992
|
+
let handle = handles.get(bytes2);
|
|
6984
6993
|
if (handle === void 0) {
|
|
6985
|
-
const pointer = pdfium.writeBytes(
|
|
6994
|
+
const pointer = pdfium.writeBytes(bytes2);
|
|
6986
6995
|
try {
|
|
6987
6996
|
handle = pdfium.lib.FPDFText_LoadFont(
|
|
6988
6997
|
document2,
|
|
6989
6998
|
pointer,
|
|
6990
|
-
|
|
6999
|
+
bytes2.byteLength,
|
|
6991
7000
|
FONT_TRUETYPE,
|
|
6992
7001
|
true
|
|
6993
7002
|
);
|
|
@@ -6995,7 +7004,7 @@ var FontLibrary = class {
|
|
|
6995
7004
|
pdfium.free(pointer);
|
|
6996
7005
|
}
|
|
6997
7006
|
if (!handle) throw new Error("PDFium could not load the font");
|
|
6998
|
-
handles.set(
|
|
7007
|
+
handles.set(bytes2, handle);
|
|
6999
7008
|
}
|
|
7000
7009
|
return handle;
|
|
7001
7010
|
}
|
|
@@ -7004,12 +7013,12 @@ var FontLibrary = class {
|
|
|
7004
7013
|
}
|
|
7005
7014
|
async #bytesOf(font) {
|
|
7006
7015
|
const key = sourceKey(font);
|
|
7007
|
-
let
|
|
7008
|
-
if (!
|
|
7009
|
-
|
|
7010
|
-
this.#bytes.set(key,
|
|
7016
|
+
let bytes2 = this.#bytes.get(key);
|
|
7017
|
+
if (!bytes2) {
|
|
7018
|
+
bytes2 = typeof font.source === "string" ? await this.#fetch(font.source) : new Uint8Array(font.source);
|
|
7019
|
+
this.#bytes.set(key, bytes2);
|
|
7011
7020
|
}
|
|
7012
|
-
return
|
|
7021
|
+
return bytes2;
|
|
7013
7022
|
}
|
|
7014
7023
|
};
|
|
7015
7024
|
function sourceKey(font) {
|
|
@@ -7025,11 +7034,11 @@ function isItalic(font) {
|
|
|
7025
7034
|
return font.style !== "normal";
|
|
7026
7035
|
}
|
|
7027
7036
|
function glyphOutlines(view, tables) {
|
|
7028
|
-
const
|
|
7037
|
+
const head2 = tables.get("head");
|
|
7029
7038
|
const maxp = tables.get("maxp");
|
|
7030
7039
|
const loca = tables.get("loca");
|
|
7031
|
-
if (!
|
|
7032
|
-
const longOffsets = view.getInt16(
|
|
7040
|
+
if (!head2 || !maxp || !loca || !tables.has("glyf")) return void 0;
|
|
7041
|
+
const longOffsets = view.getInt16(head2.offset + 50) === 1;
|
|
7033
7042
|
const count = view.getUint16(maxp.offset + 4);
|
|
7034
7043
|
return (glyph) => {
|
|
7035
7044
|
if (glyph < 0 || glyph >= count) return false;
|
|
@@ -7039,8 +7048,8 @@ function glyphOutlines(view, tables) {
|
|
|
7039
7048
|
return end > start;
|
|
7040
7049
|
};
|
|
7041
7050
|
}
|
|
7042
|
-
function parseCmap(
|
|
7043
|
-
const view = new DataView(
|
|
7051
|
+
function parseCmap(bytes2) {
|
|
7052
|
+
const view = new DataView(bytes2.buffer, bytes2.byteOffset, bytes2.byteLength);
|
|
7044
7053
|
const ranges = [];
|
|
7045
7054
|
const glyphs = /* @__PURE__ */ new Map();
|
|
7046
7055
|
let outlines;
|
|
@@ -7051,10 +7060,10 @@ function parseCmap(bytes) {
|
|
|
7051
7060
|
for (let index = 0; index < tables; index += 1) {
|
|
7052
7061
|
const record = 12 + index * 16;
|
|
7053
7062
|
const tag = String.fromCharCode(
|
|
7054
|
-
|
|
7055
|
-
|
|
7056
|
-
|
|
7057
|
-
|
|
7063
|
+
bytes2[record],
|
|
7064
|
+
bytes2[record + 1],
|
|
7065
|
+
bytes2[record + 2],
|
|
7066
|
+
bytes2[record + 3]
|
|
7058
7067
|
);
|
|
7059
7068
|
offsets.set(tag, {
|
|
7060
7069
|
offset: view.getUint32(record + 8),
|
|
@@ -7223,6 +7232,915 @@ var TextMeasurer = class {
|
|
|
7223
7232
|
}
|
|
7224
7233
|
};
|
|
7225
7234
|
|
|
7235
|
+
// src/edit/pdf/engine/glyph-names.ts
|
|
7236
|
+
var AGLFN = `
|
|
7237
|
+
A 0041 AE 00C6 AEacute 01FC Aacute 00C1 Abreve 0102 Acircumflex 00C2
|
|
7238
|
+
Adieresis 00C4 Agrave 00C0 Alpha 0391 Alphatonos 0386 Amacron 0100
|
|
7239
|
+
Aogonek 0104 Aring 00C5 Aringacute 01FA Atilde 00C3 B 0042 Beta 0392 C 0043
|
|
7240
|
+
Cacute 0106 Ccaron 010C Ccedilla 00C7 Ccircumflex 0108 Cdotaccent 010A
|
|
7241
|
+
Chi 03A7 D 0044 Dcaron 010E Dcroat 0110 Delta 2206 E 0045 Eacute 00C9
|
|
7242
|
+
Ebreve 0114 Ecaron 011A Ecircumflex 00CA Edieresis 00CB Edotaccent 0116
|
|
7243
|
+
Egrave 00C8 Emacron 0112 Eng 014A Eogonek 0118 Epsilon 0395
|
|
7244
|
+
Epsilontonos 0388 Eta 0397 Etatonos 0389 Eth 00D0 Euro 20AC F 0046 G 0047
|
|
7245
|
+
Gamma 0393 Gbreve 011E Gcaron 01E6 Gcircumflex 011C Gdotaccent 0120 H 0048
|
|
7246
|
+
H18533 25CF H18543 25AA H18551 25AB H22073 25A1 Hbar 0126 Hcircumflex 0124
|
|
7247
|
+
I 0049 IJ 0132 Iacute 00CD Ibreve 012C Icircumflex 00CE Idieresis 00CF
|
|
7248
|
+
Idotaccent 0130 Ifraktur 2111 Igrave 00CC Imacron 012A Iogonek 012E
|
|
7249
|
+
Iota 0399 Iotadieresis 03AA Iotatonos 038A Itilde 0128 J 004A
|
|
7250
|
+
Jcircumflex 0134 K 004B Kappa 039A L 004C Lacute 0139 Lambda 039B
|
|
7251
|
+
Lcaron 013D Ldot 013F Lslash 0141 M 004D Mu 039C N 004E Nacute 0143
|
|
7252
|
+
Ncaron 0147 Ntilde 00D1 Nu 039D O 004F OE 0152 Oacute 00D3 Obreve 014E
|
|
7253
|
+
Ocircumflex 00D4 Odieresis 00D6 Ograve 00D2 Ohorn 01A0 Ohungarumlaut 0150
|
|
7254
|
+
Omacron 014C Omega 2126 Omegatonos 038F Omicron 039F Omicrontonos 038C
|
|
7255
|
+
Oslash 00D8 Oslashacute 01FE Otilde 00D5 P 0050 Phi 03A6 Pi 03A0 Psi 03A8
|
|
7256
|
+
Q 0051 R 0052 Racute 0154 Rcaron 0158 Rfraktur 211C Rho 03A1 S 0053
|
|
7257
|
+
SF010000 250C SF020000 2514 SF030000 2510 SF040000 2518 SF050000 253C
|
|
7258
|
+
SF060000 252C SF070000 2534 SF080000 251C SF090000 2524 SF100000 2500
|
|
7259
|
+
SF110000 2502 SF190000 2561 SF200000 2562 SF210000 2556 SF220000 2555
|
|
7260
|
+
SF230000 2563 SF240000 2551 SF250000 2557 SF260000 255D SF270000 255C
|
|
7261
|
+
SF280000 255B SF360000 255E SF370000 255F SF380000 255A SF390000 2554
|
|
7262
|
+
SF400000 2569 SF410000 2566 SF420000 2560 SF430000 2550 SF440000 256C
|
|
7263
|
+
SF450000 2567 SF460000 2568 SF470000 2564 SF480000 2565 SF490000 2559
|
|
7264
|
+
SF500000 2558 SF510000 2552 SF520000 2553 SF530000 256B SF540000 256A
|
|
7265
|
+
Sacute 015A Scaron 0160 Scedilla 015E Scircumflex 015C Sigma 03A3 T 0054
|
|
7266
|
+
Tau 03A4 Tbar 0166 Tcaron 0164 Theta 0398 Thorn 00DE U 0055 Uacute 00DA
|
|
7267
|
+
Ubreve 016C Ucircumflex 00DB Udieresis 00DC Ugrave 00D9 Uhorn 01AF
|
|
7268
|
+
Uhungarumlaut 0170 Umacron 016A Uogonek 0172 Upsilon 03A5 Upsilon1 03D2
|
|
7269
|
+
Upsilondieresis 03AB Upsilontonos 038E Uring 016E Utilde 0168 V 0056 W 0057
|
|
7270
|
+
Wacute 1E82 Wcircumflex 0174 Wdieresis 1E84 Wgrave 1E80 X 0058 Xi 039E
|
|
7271
|
+
Y 0059 Yacute 00DD Ycircumflex 0176 Ydieresis 0178 Ygrave 1EF2 Z 005A
|
|
7272
|
+
Zacute 0179 Zcaron 017D Zdotaccent 017B Zeta 0396 a 0061 aacute 00E1
|
|
7273
|
+
abreve 0103 acircumflex 00E2 acute 00B4 acutecomb 0301 adieresis 00E4
|
|
7274
|
+
ae 00E6 aeacute 01FD agrave 00E0 aleph 2135 alpha 03B1 alphatonos 03AC
|
|
7275
|
+
amacron 0101 ampersand 0026 angle 2220 angleleft 2329 angleright 232A
|
|
7276
|
+
anoteleia 0387 aogonek 0105 approxequal 2248 aring 00E5 aringacute 01FB
|
|
7277
|
+
arrowboth 2194 arrowdblboth 21D4 arrowdbldown 21D3 arrowdblleft 21D0
|
|
7278
|
+
arrowdblright 21D2 arrowdblup 21D1 arrowdown 2193 arrowleft 2190
|
|
7279
|
+
arrowright 2192 arrowup 2191 arrowupdn 2195 arrowupdnbse 21A8
|
|
7280
|
+
asciicircum 005E asciitilde 007E asterisk 002A asteriskmath 2217 at 0040
|
|
7281
|
+
atilde 00E3 b 0062 backslash 005C bar 007C beta 03B2 block 2588
|
|
7282
|
+
braceleft 007B braceright 007D bracketleft 005B bracketright 005D breve 02D8
|
|
7283
|
+
brokenbar 00A6 bullet 2022 c 0063 cacute 0107 caron 02C7 carriagereturn 21B5
|
|
7284
|
+
ccaron 010D ccedilla 00E7 ccircumflex 0109 cdotaccent 010B cedilla 00B8
|
|
7285
|
+
cent 00A2 chi 03C7 circle 25CB circlemultiply 2297 circleplus 2295
|
|
7286
|
+
circumflex 02C6 club 2663 colon 003A colonmonetary 20A1 comma 002C
|
|
7287
|
+
congruent 2245 copyright 00A9 currency 00A4 d 0064 dagger 2020
|
|
7288
|
+
daggerdbl 2021 dcaron 010F dcroat 0111 degree 00B0 delta 03B4 diamond 2666
|
|
7289
|
+
dieresis 00A8 dieresistonos 0385 divide 00F7 dkshade 2593 dnblock 2584
|
|
7290
|
+
dollar 0024 dong 20AB dotaccent 02D9 dotbelowcomb 0323 dotlessi 0131
|
|
7291
|
+
dotmath 22C5 e 0065 eacute 00E9 ebreve 0115 ecaron 011B ecircumflex 00EA
|
|
7292
|
+
edieresis 00EB edotaccent 0117 egrave 00E8 eight 0038 element 2208
|
|
7293
|
+
ellipsis 2026 emacron 0113 emdash 2014 emptyset 2205 endash 2013 eng 014B
|
|
7294
|
+
eogonek 0119 epsilon 03B5 epsilontonos 03AD equal 003D equivalence 2261
|
|
7295
|
+
estimated 212E eta 03B7 etatonos 03AE eth 00F0 exclam 0021 exclamdbl 203C
|
|
7296
|
+
exclamdown 00A1 existential 2203 f 0066 female 2640 figuredash 2012
|
|
7297
|
+
filledbox 25A0 filledrect 25AC five 0035 fiveeighths 215D florin 0192
|
|
7298
|
+
four 0034 fraction 2044 franc 20A3 g 0067 gamma 03B3 gbreve 011F gcaron 01E7
|
|
7299
|
+
gcircumflex 011D gdotaccent 0121 germandbls 00DF gradient 2207 grave 0060
|
|
7300
|
+
gravecomb 0300 greater 003E greaterequal 2265 guillemotleft 00AB
|
|
7301
|
+
guillemotright 00BB guilsinglleft 2039 guilsinglright 203A h 0068 hbar 0127
|
|
7302
|
+
hcircumflex 0125 heart 2665 hookabovecomb 0309 house 2302 hungarumlaut 02DD
|
|
7303
|
+
hyphen 002D i 0069 iacute 00ED ibreve 012D icircumflex 00EE idieresis 00EF
|
|
7304
|
+
igrave 00EC ij 0133 imacron 012B infinity 221E integral 222B integralbt 2321
|
|
7305
|
+
integraltp 2320 intersection 2229 invbullet 25D8 invcircle 25D9
|
|
7306
|
+
invsmileface 263B iogonek 012F iota 03B9 iotadieresis 03CA
|
|
7307
|
+
iotadieresistonos 0390 iotatonos 03AF itilde 0129 j 006A jcircumflex 0135
|
|
7308
|
+
k 006B kappa 03BA kgreenlandic 0138 l 006C lacute 013A lambda 03BB
|
|
7309
|
+
lcaron 013E ldot 0140 less 003C lessequal 2264 lfblock 258C lira 20A4
|
|
7310
|
+
logicaland 2227 logicalnot 00AC logicalor 2228 longs 017F lozenge 25CA
|
|
7311
|
+
lslash 0142 ltshade 2591 m 006D macron 00AF male 2642 minus 2212 minute 2032
|
|
7312
|
+
mu 00B5 multiply 00D7 musicalnote 266A musicalnotedbl 266B n 006E
|
|
7313
|
+
nacute 0144 napostrophe 0149 ncaron 0148 nine 0039 notelement 2209
|
|
7314
|
+
notequal 2260 notsubset 2284 ntilde 00F1 nu 03BD numbersign 0023 o 006F
|
|
7315
|
+
oacute 00F3 obreve 014F ocircumflex 00F4 odieresis 00F6 oe 0153 ogonek 02DB
|
|
7316
|
+
ograve 00F2 ohorn 01A1 ohungarumlaut 0151 omacron 014D omega 03C9
|
|
7317
|
+
omega1 03D6 omegatonos 03CE omicron 03BF omicrontonos 03CC one 0031
|
|
7318
|
+
onedotenleader 2024 oneeighth 215B onehalf 00BD onequarter 00BC
|
|
7319
|
+
onethird 2153 openbullet 25E6 ordfeminine 00AA ordmasculine 00BA
|
|
7320
|
+
orthogonal 221F oslash 00F8 oslashacute 01FF otilde 00F5 p 0070
|
|
7321
|
+
paragraph 00B6 parenleft 0028 parenright 0029 partialdiff 2202 percent 0025
|
|
7322
|
+
period 002E periodcentered 00B7 perpendicular 22A5 perthousand 2030
|
|
7323
|
+
peseta 20A7 phi 03C6 phi1 03D5 pi 03C0 plus 002B plusminus 00B1
|
|
7324
|
+
prescription 211E product 220F propersubset 2282 propersuperset 2283
|
|
7325
|
+
proportional 221D psi 03C8 q 0071 question 003F questiondown 00BF
|
|
7326
|
+
quotedbl 0022 quotedblbase 201E quotedblleft 201C quotedblright 201D
|
|
7327
|
+
quoteleft 2018 quotereversed 201B quoteright 2019 quotesinglbase 201A
|
|
7328
|
+
quotesingle 0027 r 0072 racute 0155 radical 221A rcaron 0159
|
|
7329
|
+
reflexsubset 2286 reflexsuperset 2287 registered 00AE revlogicalnot 2310
|
|
7330
|
+
rho 03C1 ring 02DA rtblock 2590 s 0073 sacute 015B scaron 0161 scedilla 015F
|
|
7331
|
+
scircumflex 015D second 2033 section 00A7 semicolon 003B seven 0037
|
|
7332
|
+
seveneighths 215E shade 2592 sigma 03C3 sigma1 03C2 similar 223C six 0036
|
|
7333
|
+
slash 002F smileface 263A space 0020 spade 2660 sterling 00A3 suchthat 220B
|
|
7334
|
+
summation 2211 sun 263C t 0074 tau 03C4 tbar 0167 tcaron 0165 therefore 2234
|
|
7335
|
+
theta 03B8 theta1 03D1 thorn 00FE three 0033 threeeighths 215C
|
|
7336
|
+
threequarters 00BE tilde 02DC tildecomb 0303 tonos 0384 trademark 2122
|
|
7337
|
+
triagdn 25BC triaglf 25C4 triagrt 25BA triagup 25B2 two 0032
|
|
7338
|
+
twodotenleader 2025 twothirds 2154 u 0075 uacute 00FA ubreve 016D
|
|
7339
|
+
ucircumflex 00FB udieresis 00FC ugrave 00F9 uhorn 01B0 uhungarumlaut 0171
|
|
7340
|
+
umacron 016B underscore 005F underscoredbl 2017 union 222A universal 2200
|
|
7341
|
+
uogonek 0173 upblock 2580 upsilon 03C5 upsilondieresis 03CB
|
|
7342
|
+
upsilondieresistonos 03B0 upsilontonos 03CD uring 016F utilde 0169 v 0076
|
|
7343
|
+
w 0077 wacute 1E83 wcircumflex 0175 wdieresis 1E85 weierstrass 2118
|
|
7344
|
+
wgrave 1E81 x 0078 xi 03BE y 0079 yacute 00FD ycircumflex 0177
|
|
7345
|
+
ydieresis 00FF yen 00A5 ygrave 1EF3 z 007A zacute 017A zcaron 017E
|
|
7346
|
+
zdotaccent 017C zero 0030 zeta 03B6
|
|
7347
|
+
`;
|
|
7348
|
+
var AGL_EXTRAS = `
|
|
7349
|
+
fi FB01 fl FB02 ff FB00 ffi FB03 ffl FB04 onesuperior 00B9 twosuperior 00B2
|
|
7350
|
+
threesuperior 00B3 nbspace 00A0
|
|
7351
|
+
`;
|
|
7352
|
+
var GLYPH_UNICODE = new Map(
|
|
7353
|
+
`${AGLFN} ${AGL_EXTRAS}`.trim().split(/\s+/).flatMap(
|
|
7354
|
+
(word, index, words) => index % 2 === 0 ? [[word, Number.parseInt(words[index + 1], 16)]] : []
|
|
7355
|
+
)
|
|
7356
|
+
);
|
|
7357
|
+
|
|
7358
|
+
// src/edit/pdf/engine/cff.ts
|
|
7359
|
+
var ISO_ADOBE_NAMES = `
|
|
7360
|
+
.notdef space exclam quotedbl numbersign dollar percent ampersand
|
|
7361
|
+
quoteright parenleft parenright asterisk plus comma hyphen period slash
|
|
7362
|
+
zero one two three four five six seven eight nine colon semicolon less
|
|
7363
|
+
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
|
|
7364
|
+
Z bracketleft backslash bracketright asciicircum underscore quoteleft a b c
|
|
7365
|
+
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
|
|
7366
|
+
asciitilde exclamdown cent sterling fraction yen florin section currency
|
|
7367
|
+
quotesingle quotedblleft guillemotleft guilsinglleft guilsinglright fi fl
|
|
7368
|
+
endash dagger daggerdbl periodcentered paragraph bullet quotesinglbase
|
|
7369
|
+
quotedblbase quotedblright guillemotright ellipsis perthousand questiondown
|
|
7370
|
+
grave acute circumflex tilde macron breve dotaccent dieresis ring cedilla
|
|
7371
|
+
hungarumlaut ogonek caron emdash AE ordfeminine Lslash Oslash OE
|
|
7372
|
+
ordmasculine ae dotlessi lslash oslash oe germandbls onesuperior logicalnot
|
|
7373
|
+
mu trademark Eth onehalf plusminus Thorn onequarter divide brokenbar degree
|
|
7374
|
+
thorn threequarters twosuperior registered minus eth multiply threesuperior
|
|
7375
|
+
copyright Aacute Acircumflex Adieresis Agrave Aring Atilde Ccedilla Eacute
|
|
7376
|
+
Ecircumflex Edieresis Egrave Iacute Icircumflex Idieresis Igrave Ntilde
|
|
7377
|
+
Oacute Ocircumflex Odieresis Ograve Otilde Scaron Uacute Ucircumflex
|
|
7378
|
+
Udieresis Ugrave Yacute Ydieresis Zcaron aacute acircumflex adieresis
|
|
7379
|
+
agrave aring atilde ccedilla eacute ecircumflex edieresis egrave iacute
|
|
7380
|
+
icircumflex idieresis igrave ntilde oacute ocircumflex odieresis ograve
|
|
7381
|
+
otilde scaron uacute ucircumflex udieresis ugrave yacute ydieresis zcaron
|
|
7382
|
+
`.trim().split(/\s+/);
|
|
7383
|
+
function glyphUnicode(name) {
|
|
7384
|
+
if (!name || name === ".notdef") return void 0;
|
|
7385
|
+
const known = GLYPH_UNICODE.get(name);
|
|
7386
|
+
if (known !== void 0) return known;
|
|
7387
|
+
const match = /^uni([0-9A-F]{4})$|^u([0-9A-F]{4,6})$/.exec(name);
|
|
7388
|
+
const hex2 = match?.[1] ?? match?.[2];
|
|
7389
|
+
if (!hex2) return void 0;
|
|
7390
|
+
const code = Number.parseInt(hex2, 16);
|
|
7391
|
+
const surrogate = code >= 55296 && code <= 57343;
|
|
7392
|
+
const nonCharacter = (code & 65534) === 65534;
|
|
7393
|
+
return code <= 1114111 && !surrogate && !nonCharacter ? code : void 0;
|
|
7394
|
+
}
|
|
7395
|
+
var OP = {
|
|
7396
|
+
fontBBox: 5,
|
|
7397
|
+
charset: 15,
|
|
7398
|
+
charStrings: 17,
|
|
7399
|
+
private: 18,
|
|
7400
|
+
defaultWidthX: 20,
|
|
7401
|
+
nominalWidthX: 21,
|
|
7402
|
+
subrs: 19,
|
|
7403
|
+
charstringType: 1206,
|
|
7404
|
+
fontMatrix: 1207,
|
|
7405
|
+
ros: 1230
|
|
7406
|
+
};
|
|
7407
|
+
var STANDARD_STRINGS = 391;
|
|
7408
|
+
function readCff(bytes2) {
|
|
7409
|
+
try {
|
|
7410
|
+
const at = (offset2) => {
|
|
7411
|
+
if (!Number.isInteger(offset2) || offset2 < 0 || offset2 >= bytes2.length)
|
|
7412
|
+
throw new RangeError("Outside the font");
|
|
7413
|
+
return bytes2[offset2];
|
|
7414
|
+
};
|
|
7415
|
+
const u162 = (offset2) => at(offset2) << 8 | at(offset2 + 1);
|
|
7416
|
+
if (at(0) !== 1) return void 0;
|
|
7417
|
+
const names2 = readIndex(bytes2, at(2), at, u162);
|
|
7418
|
+
const tops = readIndex(bytes2, names2.end, at, u162);
|
|
7419
|
+
const strings = readIndex(bytes2, tops.end, at, u162);
|
|
7420
|
+
const globalSubrs = readIndex(bytes2, strings.end, at, u162);
|
|
7421
|
+
if (names2.items.length !== 1 || tops.items.length !== 1) return void 0;
|
|
7422
|
+
const top = readDict(bytes2, ...tops.items[0], at);
|
|
7423
|
+
const charStringsAt = top.get(OP.charStrings)?.[0];
|
|
7424
|
+
if (charStringsAt === void 0) return void 0;
|
|
7425
|
+
if ((top.get(OP.charstringType)?.[0] ?? 2) !== 2) return void 0;
|
|
7426
|
+
const charStrings = readIndex(bytes2, charStringsAt, at, u162);
|
|
7427
|
+
const glyphCount = charStrings.items.length;
|
|
7428
|
+
if (glyphCount === 0) return void 0;
|
|
7429
|
+
const [scale = 1e-3, skewX = 0, skewY = 0, scaleY = 1e-3] = top.get(OP.fontMatrix) ?? [];
|
|
7430
|
+
if (skewX !== 0 || skewY !== 0 || scale !== scaleY || scale <= 0)
|
|
7431
|
+
return void 0;
|
|
7432
|
+
const unitsPerEm = Math.round(1 / scale);
|
|
7433
|
+
if (unitsPerEm < 16 || unitsPerEm > 16384) return void 0;
|
|
7434
|
+
const [xMin = 0, yMin = 0, xMax = 0, yMax = 0] = top.get(OP.fontBBox) ?? [];
|
|
7435
|
+
const cid = top.has(OP.ros);
|
|
7436
|
+
const [nameStart, nameEnd] = names2.items[0];
|
|
7437
|
+
const name = latin1(
|
|
7438
|
+
bytes2.subarray(nameStart, Math.min(nameEnd, nameStart + 127))
|
|
7439
|
+
);
|
|
7440
|
+
if (cid)
|
|
7441
|
+
return {
|
|
7442
|
+
name,
|
|
7443
|
+
cid,
|
|
7444
|
+
glyphNames: [],
|
|
7445
|
+
widths: [],
|
|
7446
|
+
bbox: [xMin, yMin, xMax, yMax],
|
|
7447
|
+
unitsPerEm
|
|
7448
|
+
};
|
|
7449
|
+
const custom = /* @__PURE__ */ new Map();
|
|
7450
|
+
const stringOf = (sid) => {
|
|
7451
|
+
if (sid < ISO_ADOBE_NAMES.length) return ISO_ADOBE_NAMES[sid];
|
|
7452
|
+
const item = strings.items[sid - STANDARD_STRINGS];
|
|
7453
|
+
if (!item) return void 0;
|
|
7454
|
+
if (!custom.has(sid))
|
|
7455
|
+
custom.set(
|
|
7456
|
+
sid,
|
|
7457
|
+
// A glyph name is 63 characters at most.
|
|
7458
|
+
item[1] - item[0] <= 63 ? latin1(bytes2.subarray(...item)) : void 0
|
|
7459
|
+
);
|
|
7460
|
+
return custom.get(sid);
|
|
7461
|
+
};
|
|
7462
|
+
const glyphNames = charsetNames(
|
|
7463
|
+
top.get(OP.charset)?.[0] ?? 0,
|
|
7464
|
+
glyphCount,
|
|
7465
|
+
stringOf,
|
|
7466
|
+
at,
|
|
7467
|
+
u162
|
|
7468
|
+
);
|
|
7469
|
+
const [privateSize, privateAt] = top.get(OP.private) ?? [0, 0];
|
|
7470
|
+
const privateDict = privateSize ? readDict(bytes2, privateAt, privateAt + privateSize, at) : /* @__PURE__ */ new Map();
|
|
7471
|
+
const localAt = privateDict.get(OP.subrs)?.[0];
|
|
7472
|
+
const metrics = {
|
|
7473
|
+
bytes: bytes2,
|
|
7474
|
+
defaultWidth: privateDict.get(OP.defaultWidthX)?.[0] ?? 0,
|
|
7475
|
+
nominalWidth: privateDict.get(OP.nominalWidthX)?.[0] ?? 0,
|
|
7476
|
+
global: globalSubrs.items,
|
|
7477
|
+
local: localAt === void 0 ? [] : readIndex(bytes2, privateAt + localAt, at, u162).items
|
|
7478
|
+
};
|
|
7479
|
+
const widths = charStrings.items.map(
|
|
7480
|
+
([start, end]) => charstringWidth(metrics, start, end)
|
|
7481
|
+
);
|
|
7482
|
+
return {
|
|
7483
|
+
name,
|
|
7484
|
+
cid,
|
|
7485
|
+
glyphNames,
|
|
7486
|
+
widths,
|
|
7487
|
+
bbox: [xMin, yMin, xMax, yMax],
|
|
7488
|
+
unitsPerEm
|
|
7489
|
+
};
|
|
7490
|
+
} catch (error) {
|
|
7491
|
+
if (error instanceof RangeError) return void 0;
|
|
7492
|
+
throw error;
|
|
7493
|
+
}
|
|
7494
|
+
}
|
|
7495
|
+
function cffWithSafeName(bytes2) {
|
|
7496
|
+
try {
|
|
7497
|
+
const at = (offset2) => {
|
|
7498
|
+
if (offset2 < 0 || offset2 >= bytes2.length)
|
|
7499
|
+
throw new RangeError("Outside the font");
|
|
7500
|
+
return bytes2[offset2];
|
|
7501
|
+
};
|
|
7502
|
+
const u162 = (offset2) => at(offset2) << 8 | at(offset2 + 1);
|
|
7503
|
+
const names2 = readIndex(bytes2, at(2), at, u162);
|
|
7504
|
+
const [start, end] = names2.items[0] ?? [0, 0];
|
|
7505
|
+
if (names2.items.length !== 1 || end - start > 127) return void 0;
|
|
7506
|
+
const safe = bytes2.slice();
|
|
7507
|
+
for (let offset2 = start; offset2 < end; offset2 += 1) {
|
|
7508
|
+
const byte = safe[offset2];
|
|
7509
|
+
if (offset2 === start && byte === 0) continue;
|
|
7510
|
+
if (byte < 33 || byte > 126 || UNSAFE_NAME_BYTES.has(byte))
|
|
7511
|
+
safe[offset2] = 95;
|
|
7512
|
+
}
|
|
7513
|
+
return safe;
|
|
7514
|
+
} catch (error) {
|
|
7515
|
+
if (error instanceof RangeError) return void 0;
|
|
7516
|
+
throw error;
|
|
7517
|
+
}
|
|
7518
|
+
}
|
|
7519
|
+
var UNSAFE_NAME_BYTES = new Set(
|
|
7520
|
+
[..."[](){}<>/%"].map((character) => character.charCodeAt(0))
|
|
7521
|
+
);
|
|
7522
|
+
function readIndex(bytes2, start, at, u162) {
|
|
7523
|
+
const count = u162(start);
|
|
7524
|
+
if (count === 0) return { items: [], end: start + 2 };
|
|
7525
|
+
const offSize = at(start + 2);
|
|
7526
|
+
if (offSize < 1 || offSize > 4) throw new RangeError("Bad offset size");
|
|
7527
|
+
const offset2 = (index) => {
|
|
7528
|
+
let value = 0;
|
|
7529
|
+
for (let byte = 0; byte < offSize; byte += 1)
|
|
7530
|
+
value = value * 256 + at(start + 3 + index * offSize + byte);
|
|
7531
|
+
return value;
|
|
7532
|
+
};
|
|
7533
|
+
if (offset2(0) !== 1) throw new RangeError("Bad INDEX");
|
|
7534
|
+
const base = start + 2 + (count + 1) * offSize;
|
|
7535
|
+
const items = [];
|
|
7536
|
+
for (let index = 0; index < count; index += 1) {
|
|
7537
|
+
const from = base + offset2(index);
|
|
7538
|
+
const to = base + offset2(index + 1);
|
|
7539
|
+
if (to < from || to > bytes2.length) throw new RangeError("Bad INDEX");
|
|
7540
|
+
items.push([from, to]);
|
|
7541
|
+
}
|
|
7542
|
+
return { items, end: base + offset2(count) };
|
|
7543
|
+
}
|
|
7544
|
+
function readDict(bytes2, start, end, at) {
|
|
7545
|
+
if (end > bytes2.length) throw new RangeError("DICT past the font");
|
|
7546
|
+
const entries = /* @__PURE__ */ new Map();
|
|
7547
|
+
let operands = [];
|
|
7548
|
+
let offset2 = start;
|
|
7549
|
+
while (offset2 < end) {
|
|
7550
|
+
const byte = at(offset2);
|
|
7551
|
+
if (byte <= 21) {
|
|
7552
|
+
const operator = byte === 12 ? 1200 + at(offset2 + 1) : byte;
|
|
7553
|
+
offset2 += byte === 12 ? 2 : 1;
|
|
7554
|
+
entries.set(operator, operands);
|
|
7555
|
+
operands = [];
|
|
7556
|
+
} else if (byte === 28) {
|
|
7557
|
+
operands.push(int16(at(offset2 + 1) << 8 | at(offset2 + 2)));
|
|
7558
|
+
offset2 += 3;
|
|
7559
|
+
} else if (byte === 29) {
|
|
7560
|
+
operands.push(
|
|
7561
|
+
at(offset2 + 1) << 24 | at(offset2 + 2) << 16 | at(offset2 + 3) << 8 | at(offset2 + 4)
|
|
7562
|
+
);
|
|
7563
|
+
offset2 += 5;
|
|
7564
|
+
} else if (byte === 30) {
|
|
7565
|
+
let text = "";
|
|
7566
|
+
offset2 += 1;
|
|
7567
|
+
for (let done = false; !done; offset2 += 1) {
|
|
7568
|
+
const pair = at(offset2);
|
|
7569
|
+
for (const nibble of [pair >> 4, pair & 15]) {
|
|
7570
|
+
if (nibble === 15) {
|
|
7571
|
+
done = true;
|
|
7572
|
+
break;
|
|
7573
|
+
}
|
|
7574
|
+
text += REAL_NIBBLES[nibble] ?? "";
|
|
7575
|
+
}
|
|
7576
|
+
}
|
|
7577
|
+
operands.push(Number.parseFloat(text));
|
|
7578
|
+
} else if (byte >= 32 && byte <= 246) {
|
|
7579
|
+
operands.push(byte - 139);
|
|
7580
|
+
offset2 += 1;
|
|
7581
|
+
} else if (byte >= 247 && byte <= 250) {
|
|
7582
|
+
operands.push((byte - 247) * 256 + at(offset2 + 1) + 108);
|
|
7583
|
+
offset2 += 2;
|
|
7584
|
+
} else if (byte >= 251 && byte <= 254) {
|
|
7585
|
+
operands.push(-(byte - 251) * 256 - at(offset2 + 1) - 108);
|
|
7586
|
+
offset2 += 2;
|
|
7587
|
+
} else throw new RangeError("Bad DICT byte");
|
|
7588
|
+
}
|
|
7589
|
+
return entries;
|
|
7590
|
+
}
|
|
7591
|
+
var REAL_NIBBLES = [
|
|
7592
|
+
"0",
|
|
7593
|
+
"1",
|
|
7594
|
+
"2",
|
|
7595
|
+
"3",
|
|
7596
|
+
"4",
|
|
7597
|
+
"5",
|
|
7598
|
+
"6",
|
|
7599
|
+
"7",
|
|
7600
|
+
"8",
|
|
7601
|
+
"9",
|
|
7602
|
+
".",
|
|
7603
|
+
"E",
|
|
7604
|
+
"E-",
|
|
7605
|
+
"",
|
|
7606
|
+
"-"
|
|
7607
|
+
];
|
|
7608
|
+
function charsetNames(offset2, glyphCount, stringOf, at, u162) {
|
|
7609
|
+
const names2 = [".notdef"];
|
|
7610
|
+
if (offset2 === 0) {
|
|
7611
|
+
for (let glyph = 1; glyph < glyphCount; glyph += 1)
|
|
7612
|
+
names2.push(stringOf(glyph));
|
|
7613
|
+
return names2;
|
|
7614
|
+
}
|
|
7615
|
+
if (offset2 <= 2) return [...names2, ...Array(glyphCount - 1)];
|
|
7616
|
+
const format = at(offset2);
|
|
7617
|
+
let cursor = offset2 + 1;
|
|
7618
|
+
if (format === 0) {
|
|
7619
|
+
for (let glyph = 1; glyph < glyphCount; glyph += 1, cursor += 2)
|
|
7620
|
+
names2.push(stringOf(u162(cursor)));
|
|
7621
|
+
} else if (format === 1 || format === 2) {
|
|
7622
|
+
while (names2.length < glyphCount) {
|
|
7623
|
+
const first = u162(cursor);
|
|
7624
|
+
const left = format === 1 ? at(cursor + 2) : u162(cursor + 2);
|
|
7625
|
+
cursor += format === 1 ? 3 : 4;
|
|
7626
|
+
for (let step = 0; step <= left && names2.length < glyphCount; step += 1)
|
|
7627
|
+
names2.push(stringOf(first + step));
|
|
7628
|
+
}
|
|
7629
|
+
} else throw new RangeError("Bad charset format");
|
|
7630
|
+
return names2;
|
|
7631
|
+
}
|
|
7632
|
+
function charstringWidth(context, start, end) {
|
|
7633
|
+
const { bytes: bytes2, defaultWidth, nominalWidth } = context;
|
|
7634
|
+
const stack = [];
|
|
7635
|
+
const walk = (from, to, depth) => {
|
|
7636
|
+
let offset2 = from;
|
|
7637
|
+
while (offset2 < to) {
|
|
7638
|
+
const byte = bytes2[offset2];
|
|
7639
|
+
const size = byte === 28 ? 3 : byte === 255 ? 5 : byte >= 247 && byte <= 254 ? 2 : 1;
|
|
7640
|
+
if (offset2 + size > to) return defaultWidth;
|
|
7641
|
+
if (byte === 28 || byte >= 32) {
|
|
7642
|
+
const next = (step) => bytes2[offset2 + step];
|
|
7643
|
+
stack.push(
|
|
7644
|
+
byte === 28 ? int16(next(1) << 8 | next(2)) : byte <= 246 ? byte - 139 : byte <= 250 ? (byte - 247) * 256 + next(1) + 108 : byte <= 254 ? -(byte - 251) * 256 - next(1) - 108 : (next(1) << 24 | next(2) << 16 | next(3) << 8 | next(4)) / 65536
|
|
7645
|
+
);
|
|
7646
|
+
if (stack.length > 48) return defaultWidth;
|
|
7647
|
+
offset2 += size;
|
|
7648
|
+
continue;
|
|
7649
|
+
}
|
|
7650
|
+
offset2 += 1;
|
|
7651
|
+
if (byte === 10 || byte === 29) {
|
|
7652
|
+
const subrs = byte === 10 ? context.local : context.global;
|
|
7653
|
+
const index = stack.pop();
|
|
7654
|
+
const subr = index === void 0 ? void 0 : subrs[index + subrBias(subrs.length)];
|
|
7655
|
+
if (!subr || depth >= 10) return defaultWidth;
|
|
7656
|
+
const width = walk(subr[0], subr[1], depth + 1);
|
|
7657
|
+
if (width !== void 0) return width;
|
|
7658
|
+
continue;
|
|
7659
|
+
}
|
|
7660
|
+
if (byte === 11) return depth > 0 ? void 0 : defaultWidth;
|
|
7661
|
+
const takes = STACK_CLEARING[byte];
|
|
7662
|
+
if (takes === void 0) return defaultWidth;
|
|
7663
|
+
const count = stack.length;
|
|
7664
|
+
const widthFirst = takes === "pairs" ? count % 2 === 1 : takes === "endchar" ? count === 1 || count === 5 : count > takes;
|
|
7665
|
+
return widthFirst ? stack[0] + nominalWidth : defaultWidth;
|
|
7666
|
+
}
|
|
7667
|
+
return depth > 0 ? void 0 : defaultWidth;
|
|
7668
|
+
};
|
|
7669
|
+
return walk(start, end, 0) ?? defaultWidth;
|
|
7670
|
+
}
|
|
7671
|
+
function subrBias(count) {
|
|
7672
|
+
return count < 1240 ? 107 : count < 33900 ? 1131 : 32768;
|
|
7673
|
+
}
|
|
7674
|
+
var STACK_CLEARING = {
|
|
7675
|
+
1: "pairs",
|
|
7676
|
+
// hstem
|
|
7677
|
+
3: "pairs",
|
|
7678
|
+
// vstem
|
|
7679
|
+
18: "pairs",
|
|
7680
|
+
// hstemhm
|
|
7681
|
+
23: "pairs",
|
|
7682
|
+
// vstemhm
|
|
7683
|
+
19: "pairs",
|
|
7684
|
+
// hintmask, after implied vstems
|
|
7685
|
+
20: "pairs",
|
|
7686
|
+
// cntrmask
|
|
7687
|
+
21: 2,
|
|
7688
|
+
// rmoveto
|
|
7689
|
+
22: 1,
|
|
7690
|
+
// hmoveto
|
|
7691
|
+
4: 1,
|
|
7692
|
+
// vmoveto
|
|
7693
|
+
14: "endchar"
|
|
7694
|
+
// endchar: none, or four for an accented character
|
|
7695
|
+
};
|
|
7696
|
+
function int16(value) {
|
|
7697
|
+
return value >= 32768 ? value - 65536 : value;
|
|
7698
|
+
}
|
|
7699
|
+
function latin1(bytes2) {
|
|
7700
|
+
return String.fromCharCode(...bytes2);
|
|
7701
|
+
}
|
|
7702
|
+
|
|
7703
|
+
// src/edit/pdf/engine/opentype.ts
|
|
7704
|
+
var SFNT_TRUETYPE = 65536;
|
|
7705
|
+
var SFNT_CFF = 1330926671;
|
|
7706
|
+
function cffOpenType(program, font, unicode) {
|
|
7707
|
+
const safe = cffWithSafeName(program);
|
|
7708
|
+
if (unicode.size === 0 || !safe) return void 0;
|
|
7709
|
+
const em = font.unitsPerEm;
|
|
7710
|
+
const [xMin, yMin, xMax, yMax] = fontBox(font.bbox, em);
|
|
7711
|
+
const glyphCount = font.widths.length;
|
|
7712
|
+
const widths = font.widths.map(
|
|
7713
|
+
(width) => Math.max(0, Math.min(65535, Math.round(width)))
|
|
7714
|
+
);
|
|
7715
|
+
const codes = [...unicode.keys()].sort((a, b) => a - b);
|
|
7716
|
+
const tables = /* @__PURE__ */ new Map([
|
|
7717
|
+
["CFF ", safe],
|
|
7718
|
+
["OS/2", os2(em, widths, codes, yMin, yMax)],
|
|
7719
|
+
["cmap", cmap(unicode, codes)],
|
|
7720
|
+
["head", head(em, xMin, yMin, xMax, yMax)],
|
|
7721
|
+
["hhea", hhea(widths, glyphCount, xMin, yMin, xMax, yMax)],
|
|
7722
|
+
["hmtx", concat(widths.map((width) => bytes(u16(width), i16(0))))],
|
|
7723
|
+
["maxp", bytes(u32(20480), u16(glyphCount))],
|
|
7724
|
+
["name", names(postScriptName(font.name))],
|
|
7725
|
+
["post", post(em)]
|
|
7726
|
+
]);
|
|
7727
|
+
return assemble(tables, SFNT_CFF);
|
|
7728
|
+
}
|
|
7729
|
+
function fontBox(box, em) {
|
|
7730
|
+
const clamp = (value) => Math.max(-32768, Math.min(32767, Math.round(value)));
|
|
7731
|
+
const [x0 = 0, y0 = 0, x1 = 0, y1 = 0] = box.map(clamp);
|
|
7732
|
+
if (y1 <= y0) return [0, clamp(-em * 0.2), clamp(em), clamp(em * 0.8)];
|
|
7733
|
+
return [Math.min(x0, x1), y0, Math.max(x0, x1), y1];
|
|
7734
|
+
}
|
|
7735
|
+
function completeSfnt(program, fontName) {
|
|
7736
|
+
const tables = sfntTables(program);
|
|
7737
|
+
const headTable = tables?.get("head");
|
|
7738
|
+
const hheaTable = tables?.get("hhea");
|
|
7739
|
+
const maxpTable = tables?.get("maxp");
|
|
7740
|
+
const hmtxTable = tables?.get("hmtx");
|
|
7741
|
+
if (!tables || !tables.has("cmap") || !headTable || headTable.length < 54 || !hheaTable || hheaTable.length < 36 || !maxpTable || maxpTable.length < 6 || !hmtxTable)
|
|
7742
|
+
return void 0;
|
|
7743
|
+
const view = (table) => new DataView(table.buffer, table.byteOffset, table.byteLength);
|
|
7744
|
+
const headView = view(headTable);
|
|
7745
|
+
const em = headView.getUint16(18);
|
|
7746
|
+
const yMin = headView.getInt16(38);
|
|
7747
|
+
const yMax = headView.getInt16(42);
|
|
7748
|
+
const ownHead = headTable.slice();
|
|
7749
|
+
ownHead.fill(0, 8, 12);
|
|
7750
|
+
tables.set("head", ownHead);
|
|
7751
|
+
if (!tables.has("OS/2")) {
|
|
7752
|
+
const metrics = view(hheaTable).getUint16(34);
|
|
7753
|
+
const widths = Array.from(
|
|
7754
|
+
{ length: Math.min(metrics, hmtxTable.length >> 2) },
|
|
7755
|
+
(_, glyph) => view(hmtxTable).getUint16(glyph * 4)
|
|
7756
|
+
);
|
|
7757
|
+
tables.set("OS/2", os2(em, widths, [], yMin, yMax));
|
|
7758
|
+
}
|
|
7759
|
+
if (!tables.has("name")) tables.set("name", names(postScriptName(fontName)));
|
|
7760
|
+
if (!tables.has("post")) tables.set("post", post(em));
|
|
7761
|
+
const version = view(program).getUint32(0);
|
|
7762
|
+
return assemble(tables, version === SFNT_CFF ? SFNT_CFF : SFNT_TRUETYPE);
|
|
7763
|
+
}
|
|
7764
|
+
function hasUnicodeCmap(program) {
|
|
7765
|
+
const table = sfntTables(program)?.get("cmap");
|
|
7766
|
+
if (!table || table.length < 4) return false;
|
|
7767
|
+
const view = new DataView(table.buffer, table.byteOffset, table.byteLength);
|
|
7768
|
+
const count = Math.min(view.getUint16(2), table.length - 4 >> 3);
|
|
7769
|
+
for (let index = 0; index < count; index += 1) {
|
|
7770
|
+
const platform = view.getUint16(4 + index * 8);
|
|
7771
|
+
const encoding = view.getUint16(6 + index * 8);
|
|
7772
|
+
if (platform === 0 || platform === 3 && (encoding === 1 || encoding === 10))
|
|
7773
|
+
return true;
|
|
7774
|
+
}
|
|
7775
|
+
return false;
|
|
7776
|
+
}
|
|
7777
|
+
function sfntTables(program) {
|
|
7778
|
+
if (program.length < 12) return void 0;
|
|
7779
|
+
const view = new DataView(
|
|
7780
|
+
program.buffer,
|
|
7781
|
+
program.byteOffset,
|
|
7782
|
+
program.byteLength
|
|
7783
|
+
);
|
|
7784
|
+
const count = view.getUint16(4);
|
|
7785
|
+
if (count === 0 || 12 + count * 16 > program.length) return void 0;
|
|
7786
|
+
const tables = /* @__PURE__ */ new Map();
|
|
7787
|
+
for (let index = 0; index < count; index += 1) {
|
|
7788
|
+
const record = 12 + index * 16;
|
|
7789
|
+
const tag = String.fromCharCode(...program.subarray(record, record + 4));
|
|
7790
|
+
const offset2 = view.getUint32(record + 8);
|
|
7791
|
+
const length = view.getUint32(record + 12);
|
|
7792
|
+
if (tables.has(tag) || offset2 + length > program.length) return void 0;
|
|
7793
|
+
tables.set(tag, program.subarray(offset2, offset2 + length));
|
|
7794
|
+
}
|
|
7795
|
+
return tables;
|
|
7796
|
+
}
|
|
7797
|
+
function postScriptName(name) {
|
|
7798
|
+
return name.replace(/^[A-Z]{6}\+/, "").replace(/[^\x21-\x7e]|[[\](){}<>/%]/g, "").slice(0, 63) || "Embedded";
|
|
7799
|
+
}
|
|
7800
|
+
function post(em) {
|
|
7801
|
+
return bytes(
|
|
7802
|
+
u32(196608),
|
|
7803
|
+
u32(0),
|
|
7804
|
+
i16(-Math.round(em / 10)),
|
|
7805
|
+
i16(Math.round(em / 20)),
|
|
7806
|
+
u32(0),
|
|
7807
|
+
u32(0),
|
|
7808
|
+
u32(0),
|
|
7809
|
+
u32(0),
|
|
7810
|
+
u32(0)
|
|
7811
|
+
);
|
|
7812
|
+
}
|
|
7813
|
+
function head(em, xMin, yMin, xMax, yMax) {
|
|
7814
|
+
return bytes(
|
|
7815
|
+
u32(65536),
|
|
7816
|
+
u32(65536),
|
|
7817
|
+
u32(0),
|
|
7818
|
+
// checkSumAdjustment, set once the font is assembled
|
|
7819
|
+
u32(1594834165),
|
|
7820
|
+
u16(11),
|
|
7821
|
+
u16(em),
|
|
7822
|
+
u32(0),
|
|
7823
|
+
u32(0),
|
|
7824
|
+
u32(0),
|
|
7825
|
+
u32(0),
|
|
7826
|
+
i16(xMin),
|
|
7827
|
+
i16(yMin),
|
|
7828
|
+
i16(xMax),
|
|
7829
|
+
i16(yMax),
|
|
7830
|
+
u16(0),
|
|
7831
|
+
u16(8),
|
|
7832
|
+
i16(2),
|
|
7833
|
+
i16(0),
|
|
7834
|
+
i16(0)
|
|
7835
|
+
);
|
|
7836
|
+
}
|
|
7837
|
+
function hhea(widths, glyphCount, xMin, yMin, xMax, yMax) {
|
|
7838
|
+
return bytes(
|
|
7839
|
+
u32(65536),
|
|
7840
|
+
i16(yMax),
|
|
7841
|
+
i16(yMin),
|
|
7842
|
+
i16(0),
|
|
7843
|
+
u16(widths.reduce((most, width) => Math.max(most, width), 0)),
|
|
7844
|
+
i16(xMin),
|
|
7845
|
+
i16(0),
|
|
7846
|
+
i16(xMax),
|
|
7847
|
+
i16(1),
|
|
7848
|
+
i16(0),
|
|
7849
|
+
i16(0),
|
|
7850
|
+
i16(0),
|
|
7851
|
+
i16(0),
|
|
7852
|
+
i16(0),
|
|
7853
|
+
i16(0),
|
|
7854
|
+
i16(0),
|
|
7855
|
+
u16(glyphCount)
|
|
7856
|
+
);
|
|
7857
|
+
}
|
|
7858
|
+
function os2(em, widths, codes, yMin, yMax) {
|
|
7859
|
+
const scaled = (fraction) => Math.round(em * fraction);
|
|
7860
|
+
const drawn = widths.filter((width) => width > 0);
|
|
7861
|
+
const average = drawn.length ? Math.round(drawn.reduce((sum, width) => sum + width, 0) / drawn.length) : 0;
|
|
7862
|
+
return bytes(
|
|
7863
|
+
u16(4),
|
|
7864
|
+
i16(average),
|
|
7865
|
+
u16(400),
|
|
7866
|
+
u16(5),
|
|
7867
|
+
u16(0),
|
|
7868
|
+
i16(scaled(0.65)),
|
|
7869
|
+
i16(scaled(0.6)),
|
|
7870
|
+
i16(0),
|
|
7871
|
+
i16(scaled(0.075)),
|
|
7872
|
+
i16(scaled(0.65)),
|
|
7873
|
+
i16(scaled(0.6)),
|
|
7874
|
+
i16(0),
|
|
7875
|
+
i16(scaled(0.35)),
|
|
7876
|
+
i16(scaled(0.05)),
|
|
7877
|
+
i16(scaled(0.25)),
|
|
7878
|
+
i16(0),
|
|
7879
|
+
new Array(10).fill(0),
|
|
7880
|
+
u32(0),
|
|
7881
|
+
u32(0),
|
|
7882
|
+
u32(0),
|
|
7883
|
+
u32(0),
|
|
7884
|
+
[87, 68, 79, 67],
|
|
7885
|
+
// "WDOC"
|
|
7886
|
+
u16(64),
|
|
7887
|
+
// regular
|
|
7888
|
+
u16(Math.min(codes[0] ?? 32, 65535)),
|
|
7889
|
+
u16(Math.min(codes.at(-1) ?? 65535, 65535)),
|
|
7890
|
+
i16(yMax),
|
|
7891
|
+
i16(yMin),
|
|
7892
|
+
i16(0),
|
|
7893
|
+
u16(Math.max(0, yMax)),
|
|
7894
|
+
u16(Math.max(0, -yMin)),
|
|
7895
|
+
u32(1),
|
|
7896
|
+
u32(0),
|
|
7897
|
+
i16(scaled(0.5)),
|
|
7898
|
+
i16(scaled(0.7)),
|
|
7899
|
+
u16(0),
|
|
7900
|
+
u16(32),
|
|
7901
|
+
u16(0)
|
|
7902
|
+
);
|
|
7903
|
+
}
|
|
7904
|
+
function cmap(unicode, codes) {
|
|
7905
|
+
const basic = codes.filter((code) => code <= 65535);
|
|
7906
|
+
const format4 = cmapFormat4(unicode, basic);
|
|
7907
|
+
const format12 = !format4 || codes.length > basic.length ? cmapFormat12(unicode, codes) : void 0;
|
|
7908
|
+
const subtables = [
|
|
7909
|
+
...format4 ? [{ platform: 0, encoding: 3, data: format4 }] : [],
|
|
7910
|
+
...format12 ? [{ platform: 0, encoding: 4, data: format12 }] : [],
|
|
7911
|
+
...format4 ? [{ platform: 3, encoding: 1, data: format4 }] : [],
|
|
7912
|
+
...format12 ? [{ platform: 3, encoding: 10, data: format12 }] : []
|
|
7913
|
+
];
|
|
7914
|
+
const unique = [...new Set(subtables.map((subtable) => subtable.data))];
|
|
7915
|
+
const headerSize = 4 + subtables.length * 8;
|
|
7916
|
+
const offsets = /* @__PURE__ */ new Map();
|
|
7917
|
+
let offset2 = headerSize;
|
|
7918
|
+
for (const data of unique) {
|
|
7919
|
+
offsets.set(data, offset2);
|
|
7920
|
+
offset2 += data.length;
|
|
7921
|
+
}
|
|
7922
|
+
return concat([
|
|
7923
|
+
bytes(u16(0), u16(subtables.length)),
|
|
7924
|
+
...subtables.map(
|
|
7925
|
+
({ platform, encoding, data }) => bytes(u16(platform), u16(encoding), u32(offsets.get(data)))
|
|
7926
|
+
),
|
|
7927
|
+
...unique
|
|
7928
|
+
]);
|
|
7929
|
+
}
|
|
7930
|
+
function cmapFormat4(unicode, codes) {
|
|
7931
|
+
const segments = [];
|
|
7932
|
+
for (const code of codes) {
|
|
7933
|
+
const glyph = unicode.get(code);
|
|
7934
|
+
const last = segments.at(-1);
|
|
7935
|
+
if (last && code === last.end + 1 && glyph === last.glyph + (code - last.start))
|
|
7936
|
+
last.end = code;
|
|
7937
|
+
else segments.push({ start: code, end: code, glyph });
|
|
7938
|
+
}
|
|
7939
|
+
segments.push({ start: 65535, end: 65535, glyph: 0 });
|
|
7940
|
+
const count = segments.length;
|
|
7941
|
+
if (16 + count * 8 > 65535) return void 0;
|
|
7942
|
+
const searchRange = 2 * 2 ** Math.floor(Math.log2(count));
|
|
7943
|
+
const delta = (segment) => segment.start === 65535 ? 1 : segment.glyph - segment.start & 65535;
|
|
7944
|
+
return bytes(
|
|
7945
|
+
u16(4),
|
|
7946
|
+
u16(16 + count * 8),
|
|
7947
|
+
u16(0),
|
|
7948
|
+
u16(count * 2),
|
|
7949
|
+
u16(searchRange),
|
|
7950
|
+
u16(Math.floor(Math.log2(count))),
|
|
7951
|
+
u16(count * 2 - searchRange),
|
|
7952
|
+
segments.flatMap((segment) => u16(segment.end)),
|
|
7953
|
+
u16(0),
|
|
7954
|
+
segments.flatMap((segment) => u16(segment.start)),
|
|
7955
|
+
segments.flatMap((segment) => u16(delta(segment))),
|
|
7956
|
+
segments.flatMap(() => u16(0))
|
|
7957
|
+
);
|
|
7958
|
+
}
|
|
7959
|
+
function cmapFormat12(unicode, codes) {
|
|
7960
|
+
const groups = [];
|
|
7961
|
+
for (const code of codes) {
|
|
7962
|
+
const glyph = unicode.get(code);
|
|
7963
|
+
const last = groups.at(-1);
|
|
7964
|
+
if (last && code === last.end + 1 && glyph === last.glyph + (code - last.start))
|
|
7965
|
+
last.end = code;
|
|
7966
|
+
else groups.push({ start: code, end: code, glyph });
|
|
7967
|
+
}
|
|
7968
|
+
return bytes(
|
|
7969
|
+
u16(12),
|
|
7970
|
+
u16(0),
|
|
7971
|
+
u32(16 + groups.length * 12),
|
|
7972
|
+
u32(0),
|
|
7973
|
+
u32(groups.length),
|
|
7974
|
+
groups.flatMap((group) => [
|
|
7975
|
+
...u32(group.start),
|
|
7976
|
+
...u32(group.end),
|
|
7977
|
+
...u32(group.glyph)
|
|
7978
|
+
])
|
|
7979
|
+
);
|
|
7980
|
+
}
|
|
7981
|
+
function names(postScript) {
|
|
7982
|
+
const records = [
|
|
7983
|
+
[1, postScript],
|
|
7984
|
+
[2, "Regular"],
|
|
7985
|
+
[3, `${postScript}-web-doc`],
|
|
7986
|
+
[4, postScript],
|
|
7987
|
+
[5, "Version 1.0"],
|
|
7988
|
+
[6, postScript]
|
|
7989
|
+
];
|
|
7990
|
+
const strings = records.map(
|
|
7991
|
+
([, text]) => [...text].flatMap((character) => u16(character.charCodeAt(0)))
|
|
7992
|
+
);
|
|
7993
|
+
let offset2 = 0;
|
|
7994
|
+
const entries = records.map(([id], index) => {
|
|
7995
|
+
const entry = [
|
|
7996
|
+
...u16(3),
|
|
7997
|
+
...u16(1),
|
|
7998
|
+
...u16(1033),
|
|
7999
|
+
...u16(id),
|
|
8000
|
+
...u16(strings[index].length),
|
|
8001
|
+
...u16(offset2)
|
|
8002
|
+
];
|
|
8003
|
+
offset2 += strings[index].length;
|
|
8004
|
+
return entry;
|
|
8005
|
+
});
|
|
8006
|
+
return bytes(
|
|
8007
|
+
u16(0),
|
|
8008
|
+
u16(records.length),
|
|
8009
|
+
u16(6 + records.length * 12),
|
|
8010
|
+
entries.flat(),
|
|
8011
|
+
strings.flat()
|
|
8012
|
+
);
|
|
8013
|
+
}
|
|
8014
|
+
function assemble(tables, version) {
|
|
8015
|
+
const tags = [...tables.keys()].sort();
|
|
8016
|
+
const count = tags.length;
|
|
8017
|
+
const selector = Math.floor(Math.log2(count));
|
|
8018
|
+
const headerSize = 12 + count * 16;
|
|
8019
|
+
let offset2 = headerSize;
|
|
8020
|
+
const placed = tags.map((tag) => {
|
|
8021
|
+
const data = tables.get(tag);
|
|
8022
|
+
const at = offset2;
|
|
8023
|
+
offset2 += data.length + 3 & ~3;
|
|
8024
|
+
return { tag, data, at };
|
|
8025
|
+
});
|
|
8026
|
+
const font = new Uint8Array(offset2);
|
|
8027
|
+
font.set(
|
|
8028
|
+
bytes(
|
|
8029
|
+
u32(version),
|
|
8030
|
+
u16(count),
|
|
8031
|
+
u16(2 ** selector * 16),
|
|
8032
|
+
u16(selector),
|
|
8033
|
+
u16(count * 16 - 2 ** selector * 16),
|
|
8034
|
+
placed.flatMap(({ tag, data, at }) => [
|
|
8035
|
+
...[...tag].map((character) => character.charCodeAt(0)),
|
|
8036
|
+
...u32(checksum(data)),
|
|
8037
|
+
...u32(at),
|
|
8038
|
+
...u32(data.length)
|
|
8039
|
+
])
|
|
8040
|
+
)
|
|
8041
|
+
);
|
|
8042
|
+
for (const { data, at } of placed) font.set(data, at);
|
|
8043
|
+
const head2 = placed.find((table) => table.tag === "head");
|
|
8044
|
+
const adjustment = 2981146554 - checksum(font) >>> 0;
|
|
8045
|
+
font.set(u32(adjustment), head2.at + 8);
|
|
8046
|
+
return font;
|
|
8047
|
+
}
|
|
8048
|
+
function checksum(data) {
|
|
8049
|
+
let sum = 0;
|
|
8050
|
+
for (let offset2 = 0; offset2 < data.length; offset2 += 4)
|
|
8051
|
+
sum = sum + ((data[offset2] ?? 0) << 24 | (data[offset2 + 1] ?? 0) << 16 | (data[offset2 + 2] ?? 0) << 8 | (data[offset2 + 3] ?? 0)) >>> 0;
|
|
8052
|
+
return sum;
|
|
8053
|
+
}
|
|
8054
|
+
function u16(value) {
|
|
8055
|
+
return [value >> 8 & 255, value & 255];
|
|
8056
|
+
}
|
|
8057
|
+
function i16(value) {
|
|
8058
|
+
return u16(value < 0 ? value + 65536 : value);
|
|
8059
|
+
}
|
|
8060
|
+
function u32(value) {
|
|
8061
|
+
return [
|
|
8062
|
+
value >>> 24 & 255,
|
|
8063
|
+
value >>> 16 & 255,
|
|
8064
|
+
value >>> 8 & 255,
|
|
8065
|
+
value & 255
|
|
8066
|
+
];
|
|
8067
|
+
}
|
|
8068
|
+
function bytes(...parts) {
|
|
8069
|
+
return concat(parts.map((part) => Uint8Array.from(part)));
|
|
8070
|
+
}
|
|
8071
|
+
function concat(parts) {
|
|
8072
|
+
const out = new Uint8Array(parts.reduce((sum, part) => sum + part.length, 0));
|
|
8073
|
+
let offset2 = 0;
|
|
8074
|
+
for (const part of parts) {
|
|
8075
|
+
out.set(part, offset2);
|
|
8076
|
+
offset2 += part.length;
|
|
8077
|
+
}
|
|
8078
|
+
return out;
|
|
8079
|
+
}
|
|
8080
|
+
|
|
8081
|
+
// src/edit/pdf/engine/text-font.ts
|
|
8082
|
+
function textFaceOf(pdfium, object, cache) {
|
|
8083
|
+
const { lib } = pdfium;
|
|
8084
|
+
const font = lib.FPDFTextObj_GetFont(object);
|
|
8085
|
+
const family = textStyle(pdfium, object).fontFamily;
|
|
8086
|
+
const baseName = pdfium.readUtf8String(
|
|
8087
|
+
(buffer, bytes2) => lib.FPDFFont_GetBaseFontName(font, buffer, bytes2)
|
|
8088
|
+
);
|
|
8089
|
+
if (!lib.FPDFFont_GetIsEmbedded(font))
|
|
8090
|
+
return { key: `name:${baseName}`, family, missing: "not-embedded" };
|
|
8091
|
+
const program = fontProgram(pdfium, font);
|
|
8092
|
+
if (!program)
|
|
8093
|
+
return { key: `embedded:${baseName}`, family, missing: "unreadable" };
|
|
8094
|
+
const key = `${baseName}#${fnv1a(program).toString(16)}`;
|
|
8095
|
+
const known = cache.get(key);
|
|
8096
|
+
if (known) return { ...known, family };
|
|
8097
|
+
const face = { key, family, ...faceOf(program, baseName) };
|
|
8098
|
+
cache.set(key, face);
|
|
8099
|
+
return face;
|
|
8100
|
+
}
|
|
8101
|
+
function faceOf(program, baseName) {
|
|
8102
|
+
const tag = String.fromCharCode(...program.subarray(0, 4));
|
|
8103
|
+
const truetype = tag === "true" || program[0] === 0 && program[1] === 1 && program[2] === 0 && program[3] === 0;
|
|
8104
|
+
if (truetype || tag === "OTTO") {
|
|
8105
|
+
if (!hasUnicodeCmap(program)) return { missing: "no-unicode" };
|
|
8106
|
+
const data2 = completeSfnt(program, baseName);
|
|
8107
|
+
return data2 ? { face: { data: data2, format: truetype ? "truetype" : "opentype" } } : { missing: "unreadable" };
|
|
8108
|
+
}
|
|
8109
|
+
if (tag.startsWith("%!") || program[0] === 128) return { missing: "type1" };
|
|
8110
|
+
const cff = readCff(program);
|
|
8111
|
+
if (!cff) return { missing: "unreadable" };
|
|
8112
|
+
if (cff.cid) return { missing: "cid-keyed" };
|
|
8113
|
+
const unicode = /* @__PURE__ */ new Map();
|
|
8114
|
+
cff.glyphNames.forEach((name, glyph) => {
|
|
8115
|
+
const code = glyphUnicode(name);
|
|
8116
|
+
if (code !== void 0 && !unicode.has(code)) unicode.set(code, glyph);
|
|
8117
|
+
});
|
|
8118
|
+
const data = cffOpenType(program, cff, unicode);
|
|
8119
|
+
return data ? { face: { data, format: "opentype" } } : { missing: "no-unicode" };
|
|
8120
|
+
}
|
|
8121
|
+
function fontProgram(pdfium, font) {
|
|
8122
|
+
const { lib } = pdfium;
|
|
8123
|
+
const size = pdfium.readNumbers(
|
|
8124
|
+
1,
|
|
8125
|
+
"i32",
|
|
8126
|
+
([out2]) => lib.FPDFFont_GetFontData(font, 0, 0, out2)
|
|
8127
|
+
)?.[0];
|
|
8128
|
+
if (!size) return void 0;
|
|
8129
|
+
const buffer = pdfium.malloc(size);
|
|
8130
|
+
const out = pdfium.malloc(4);
|
|
8131
|
+
try {
|
|
8132
|
+
return lib.FPDFFont_GetFontData(font, buffer, size, out) ? pdfium.readBytes(buffer, size) : void 0;
|
|
8133
|
+
} finally {
|
|
8134
|
+
pdfium.free(out);
|
|
8135
|
+
pdfium.free(buffer);
|
|
8136
|
+
}
|
|
8137
|
+
}
|
|
8138
|
+
function fnv1a(bytes2) {
|
|
8139
|
+
let hash = 2166136261;
|
|
8140
|
+
for (const byte of bytes2) hash = Math.imul(hash ^ byte, 16777619);
|
|
8141
|
+
return hash >>> 0;
|
|
8142
|
+
}
|
|
8143
|
+
|
|
7226
8144
|
// src/edit/pdf/engine/text-layout.ts
|
|
7227
8145
|
function layoutText(input) {
|
|
7228
8146
|
const step = input.fontSize * input.lineHeight;
|
|
@@ -7408,7 +8326,7 @@ function drawTable(context, pageIndex, spec, insertAt) {
|
|
|
7408
8326
|
);
|
|
7409
8327
|
const geometry = context.geometry(pageIndex);
|
|
7410
8328
|
const overflow = spec.at.y + layout.height > displayedSize(geometry).height + 1e-3;
|
|
7411
|
-
const
|
|
8329
|
+
const head2 = JSON.stringify(spec);
|
|
7412
8330
|
const memberMark = { kind: "table", id: spec.id };
|
|
7413
8331
|
const member = JSON.stringify(memberMark);
|
|
7414
8332
|
const at = (x, y) => pageToUser(geometry, x, y);
|
|
@@ -7447,7 +8365,7 @@ function drawTable(context, pageIndex, spec, insertAt) {
|
|
|
7447
8365
|
const [r2, g2, b2] = parseColor(style.headerFill);
|
|
7448
8366
|
lib.FPDFPageObj_SetFillColor(fill, r2, g2, b2, 255);
|
|
7449
8367
|
lib.FPDFPath_SetDrawMode(fill, FILL_ALTERNATE, false);
|
|
7450
|
-
place(fill, OBJECT_PATH, spec,
|
|
8368
|
+
place(fill, OBJECT_PATH, spec, head2);
|
|
7451
8369
|
}
|
|
7452
8370
|
const frame = [
|
|
7453
8371
|
at(spec.at.x, spec.at.y),
|
|
@@ -7475,7 +8393,7 @@ function drawTable(context, pageIndex, spec, insertAt) {
|
|
|
7475
8393
|
lib.FPDFPageObj_SetStrokeColor(grid, r, g, b, 255);
|
|
7476
8394
|
lib.FPDFPageObj_SetStrokeWidth(grid, style.borderWidth);
|
|
7477
8395
|
lib.FPDFPath_SetDrawMode(grid, FILL_NONE, true);
|
|
7478
|
-
place(grid, OBJECT_PATH, spec,
|
|
8396
|
+
place(grid, OBJECT_PATH, spec, head2);
|
|
7479
8397
|
layout.rows.forEach((row) => {
|
|
7480
8398
|
row.cells.forEach((lines, columnIndex) => {
|
|
7481
8399
|
const column = layout.columns[columnIndex];
|
|
@@ -8130,7 +9048,7 @@ function canKeepFont(context, target, text) {
|
|
|
8130
9048
|
const font = lib.FPDFTextObj_GetFont(object);
|
|
8131
9049
|
if (!lib.FPDFFont_GetIsEmbedded(font)) {
|
|
8132
9050
|
const base = pdfium.readUtf8String(
|
|
8133
|
-
(buffer,
|
|
9051
|
+
(buffer, bytes2) => lib.FPDFFont_GetBaseFontName(font, buffer, bytes2)
|
|
8134
9052
|
);
|
|
8135
9053
|
return isStandardFamily(base.split(/[-,]/)[0] ?? "") && firstNonWinAnsi(text) === void 0;
|
|
8136
9054
|
}
|
|
@@ -8180,11 +9098,11 @@ function replaceInPlace(context, target, text) {
|
|
|
8180
9098
|
const textPage = lib.FPDFText_LoadPage(page);
|
|
8181
9099
|
try {
|
|
8182
9100
|
return pdfium.readWideString(
|
|
8183
|
-
(buffer,
|
|
9101
|
+
(buffer, bytes2) => lib.FPDFTextObj_GetText(
|
|
8184
9102
|
lib.FPDFPage_GetObject(page, index),
|
|
8185
9103
|
textPage,
|
|
8186
9104
|
buffer,
|
|
8187
|
-
|
|
9105
|
+
bytes2
|
|
8188
9106
|
)
|
|
8189
9107
|
);
|
|
8190
9108
|
} finally {
|
|
@@ -8222,7 +9140,7 @@ function splitAround(context, target, before, middle, after) {
|
|
|
8222
9140
|
1,
|
|
8223
9141
|
"float",
|
|
8224
9142
|
([pointer]) => lib.FPDFTextObj_GetFontSize(old, pointer)
|
|
8225
|
-
)?.[0] ?? style.fontSize;
|
|
9143
|
+
)?.[0] ?? style.fontSize / textScale(matrix);
|
|
8226
9144
|
const [a, b, c, d, e, f] = matrix;
|
|
8227
9145
|
const [r, g, bl] = parseColor(style.color);
|
|
8228
9146
|
const parts = [
|
|
@@ -8267,7 +9185,7 @@ function splitAround(context, target, before, middle, after) {
|
|
|
8267
9185
|
try {
|
|
8268
9186
|
objects.forEach((object, at) => {
|
|
8269
9187
|
const read2 = pdfium.readWideString(
|
|
8270
|
-
(buffer,
|
|
9188
|
+
(buffer, bytes2) => lib.FPDFTextObj_GetText(object, textPage, buffer, bytes2)
|
|
8271
9189
|
);
|
|
8272
9190
|
if (read2.trimEnd() !== parts[at].text.trimEnd()) faithful = false;
|
|
8273
9191
|
});
|
|
@@ -8329,7 +9247,7 @@ function replaceWithFallback(context, target, text) {
|
|
|
8329
9247
|
1,
|
|
8330
9248
|
"float",
|
|
8331
9249
|
([pointer]) => lib.FPDFTextObj_GetFontSize(old, pointer)
|
|
8332
|
-
)?.[0] ?? style.fontSize;
|
|
9250
|
+
)?.[0] ?? style.fontSize / textScale(matrix);
|
|
8333
9251
|
const object = lib.FPDFPageObj_CreateTextObj(
|
|
8334
9252
|
context.document,
|
|
8335
9253
|
font.handle,
|
|
@@ -8372,7 +9290,7 @@ function resize(context, target, fontSize) {
|
|
|
8372
9290
|
let text;
|
|
8373
9291
|
try {
|
|
8374
9292
|
text = pdfium.readWideString(
|
|
8375
|
-
(buffer,
|
|
9293
|
+
(buffer, bytes2) => lib.FPDFTextObj_GetText(old, textPage, buffer, bytes2)
|
|
8376
9294
|
);
|
|
8377
9295
|
} finally {
|
|
8378
9296
|
lib.FPDFText_ClosePage(textPage);
|
|
@@ -8390,7 +9308,7 @@ function resize(context, target, fontSize) {
|
|
|
8390
9308
|
const object = lib.FPDFPageObj_CreateTextObj(
|
|
8391
9309
|
context.document,
|
|
8392
9310
|
lib.FPDFTextObj_GetFont(old),
|
|
8393
|
-
fontSize
|
|
9311
|
+
fontSize / textScale(matrix)
|
|
8394
9312
|
);
|
|
8395
9313
|
setText(pdfium, object, text);
|
|
8396
9314
|
lib.FPDFPageObj_SetFillColor(
|
|
@@ -8892,8 +9810,8 @@ var PdfCompactionError = class extends ViewerError {
|
|
|
8892
9810
|
});
|
|
8893
9811
|
}
|
|
8894
9812
|
};
|
|
8895
|
-
function compactPdf(
|
|
8896
|
-
const { objects, trailer, trailerReferences, headerEnd } = parseFile(
|
|
9813
|
+
function compactPdf(bytes2) {
|
|
9814
|
+
const { objects, trailer, trailerReferences, headerEnd } = parseFile(bytes2);
|
|
8897
9815
|
const byNumber = new Map(objects.map((object) => [object.number, object]));
|
|
8898
9816
|
const reachable = /* @__PURE__ */ new Set();
|
|
8899
9817
|
const queue = [...trailerReferences];
|
|
@@ -8906,12 +9824,12 @@ function compactPdf(bytes) {
|
|
|
8906
9824
|
queue.push(...object.references);
|
|
8907
9825
|
}
|
|
8908
9826
|
const kept = objects.filter((object) => reachable.has(object.number));
|
|
8909
|
-
const parts = [
|
|
9827
|
+
const parts = [bytes2.subarray(0, headerEnd)];
|
|
8910
9828
|
const offsets = /* @__PURE__ */ new Map();
|
|
8911
9829
|
let position = headerEnd;
|
|
8912
9830
|
for (const object of kept) {
|
|
8913
9831
|
offsets.set(object.number, position);
|
|
8914
|
-
const slice =
|
|
9832
|
+
const slice = bytes2.subarray(object.start, object.end);
|
|
8915
9833
|
parts.push(slice, NEWLINE);
|
|
8916
9834
|
position += slice.byteLength + 1;
|
|
8917
9835
|
}
|
|
@@ -8937,10 +9855,10 @@ ${position}
|
|
|
8937
9855
|
%%EOF
|
|
8938
9856
|
`)
|
|
8939
9857
|
);
|
|
8940
|
-
return
|
|
9858
|
+
return concat2(parts);
|
|
8941
9859
|
}
|
|
8942
|
-
function parseFile(
|
|
8943
|
-
const lexer = new Lexer(
|
|
9860
|
+
function parseFile(bytes2) {
|
|
9861
|
+
const lexer = new Lexer(bytes2);
|
|
8944
9862
|
const objects = [];
|
|
8945
9863
|
let trailer;
|
|
8946
9864
|
let trailerReferences = [];
|
|
@@ -8960,7 +9878,7 @@ function parseFile(bytes) {
|
|
|
8960
9878
|
throw new PdfCompactionError("an object header is malformed");
|
|
8961
9879
|
const object = parseObject(
|
|
8962
9880
|
lexer,
|
|
8963
|
-
|
|
9881
|
+
bytes2,
|
|
8964
9882
|
first.value,
|
|
8965
9883
|
second.value,
|
|
8966
9884
|
first.start
|
|
@@ -8975,7 +9893,7 @@ function parseFile(bytes) {
|
|
|
8975
9893
|
const dictionaryStart = lexer.skipWhitespace();
|
|
8976
9894
|
const references = [];
|
|
8977
9895
|
const dictionaryEnd = skipValue(lexer, references);
|
|
8978
|
-
trailer =
|
|
9896
|
+
trailer = latin12(bytes2.subarray(dictionaryStart, dictionaryEnd));
|
|
8979
9897
|
trailerReferences = references;
|
|
8980
9898
|
continue;
|
|
8981
9899
|
}
|
|
@@ -8997,7 +9915,7 @@ function parseFile(bytes) {
|
|
|
8997
9915
|
throw new PdfCompactionError("the file has no objects");
|
|
8998
9916
|
return { objects, trailer, trailerReferences, headerEnd };
|
|
8999
9917
|
}
|
|
9000
|
-
function parseObject(lexer,
|
|
9918
|
+
function parseObject(lexer, bytes2, number, generation, start) {
|
|
9001
9919
|
const references = [];
|
|
9002
9920
|
let integer;
|
|
9003
9921
|
let lengthValue;
|
|
@@ -9018,7 +9936,7 @@ function parseObject(lexer, bytes, number, generation, start) {
|
|
|
9018
9936
|
const dictionaryStart = lexer.position;
|
|
9019
9937
|
const dictionaryEnd = skipValue(lexer, references);
|
|
9020
9938
|
if (first.kind === "delimiter" && first.value === "<<") {
|
|
9021
|
-
const length = findLength(
|
|
9939
|
+
const length = findLength(bytes2, dictionaryStart, dictionaryEnd);
|
|
9022
9940
|
lengthValue = length?.value;
|
|
9023
9941
|
lengthReference = length?.reference;
|
|
9024
9942
|
}
|
|
@@ -9026,16 +9944,16 @@ function parseObject(lexer, bytes, number, generation, start) {
|
|
|
9026
9944
|
let next = lexer.next();
|
|
9027
9945
|
if (next.kind === "keyword" && next.value === "stream") {
|
|
9028
9946
|
let dataStart = next.end;
|
|
9029
|
-
if (
|
|
9030
|
-
if (
|
|
9947
|
+
if (bytes2[dataStart] === CR) dataStart += 1;
|
|
9948
|
+
if (bytes2[dataStart] === LF) dataStart += 1;
|
|
9031
9949
|
let dataEnd;
|
|
9032
9950
|
if (lengthValue !== void 0) dataEnd = dataStart + lengthValue;
|
|
9033
9951
|
else if (lengthReference !== void 0) {
|
|
9034
9952
|
const known = lexer.integerObjects.get(lengthReference);
|
|
9035
9953
|
if (known !== void 0) dataEnd = dataStart + known;
|
|
9036
9954
|
}
|
|
9037
|
-
if (dataEnd === void 0 || dataEnd >
|
|
9038
|
-
dataEnd = findEndstream(
|
|
9955
|
+
if (dataEnd === void 0 || dataEnd > bytes2.length || !followedByEndstream(bytes2, dataEnd)) {
|
|
9956
|
+
dataEnd = findEndstream(bytes2, dataStart);
|
|
9039
9957
|
if (dataEnd === void 0)
|
|
9040
9958
|
throw new PdfCompactionError(`object ${number} has no endstream`);
|
|
9041
9959
|
}
|
|
@@ -9090,8 +10008,8 @@ function skipValue(lexer, references) {
|
|
|
9090
10008
|
} while (depth > 0);
|
|
9091
10009
|
return end;
|
|
9092
10010
|
}
|
|
9093
|
-
function findLength(
|
|
9094
|
-
const lexer = new Lexer(
|
|
10011
|
+
function findLength(bytes2, start, end) {
|
|
10012
|
+
const lexer = new Lexer(bytes2.subarray(start, end));
|
|
9095
10013
|
for (; ; ) {
|
|
9096
10014
|
const token = lexer.next();
|
|
9097
10015
|
if (token.kind === "end") return void 0;
|
|
@@ -9107,20 +10025,20 @@ function findLength(bytes, start, end) {
|
|
|
9107
10025
|
return { value: value.value };
|
|
9108
10026
|
}
|
|
9109
10027
|
}
|
|
9110
|
-
function followedByEndstream(
|
|
10028
|
+
function followedByEndstream(bytes2, at) {
|
|
9111
10029
|
let index = at;
|
|
9112
|
-
while (index <
|
|
9113
|
-
return matchesAscii(
|
|
10030
|
+
while (index < bytes2.length && isWhitespace(bytes2[index])) index += 1;
|
|
10031
|
+
return matchesAscii(bytes2, index, "endstream");
|
|
9114
10032
|
}
|
|
9115
|
-
function findEndstream(
|
|
9116
|
-
for (let index = from; index <=
|
|
9117
|
-
if (
|
|
10033
|
+
function findEndstream(bytes2, from) {
|
|
10034
|
+
for (let index = from; index <= bytes2.length - 9; index += 1) {
|
|
10035
|
+
if (bytes2[index] !== 101 || !matchesAscii(bytes2, index, "endstream"))
|
|
9118
10036
|
continue;
|
|
9119
10037
|
const after = index + 9;
|
|
9120
|
-
if (after <
|
|
10038
|
+
if (after < bytes2.length && !isWhitespace(bytes2[after])) continue;
|
|
9121
10039
|
let end = index;
|
|
9122
|
-
if (end > from &&
|
|
9123
|
-
if (end > from &&
|
|
10040
|
+
if (end > from && bytes2[end - 1] === LF) end -= 1;
|
|
10041
|
+
if (end > from && bytes2[end - 1] === CR) end -= 1;
|
|
9124
10042
|
return end;
|
|
9125
10043
|
}
|
|
9126
10044
|
return void 0;
|
|
@@ -9131,8 +10049,8 @@ var Lexer = class {
|
|
|
9131
10049
|
#lastName = "";
|
|
9132
10050
|
/** Objects whose value is a bare integer, as seen so far: indirect lengths. */
|
|
9133
10051
|
integerObjects = /* @__PURE__ */ new Map();
|
|
9134
|
-
constructor(
|
|
9135
|
-
this.#bytes =
|
|
10052
|
+
constructor(bytes2) {
|
|
10053
|
+
this.#bytes = bytes2;
|
|
9136
10054
|
}
|
|
9137
10055
|
get position() {
|
|
9138
10056
|
return this.#position;
|
|
@@ -9151,35 +10069,35 @@ var Lexer = class {
|
|
|
9151
10069
|
}
|
|
9152
10070
|
/** Skips whitespace and comments; returns where the next token starts. */
|
|
9153
10071
|
skipWhitespace() {
|
|
9154
|
-
const
|
|
10072
|
+
const bytes2 = this.#bytes;
|
|
9155
10073
|
for (; ; ) {
|
|
9156
|
-
while (this.#position <
|
|
10074
|
+
while (this.#position < bytes2.length && isWhitespace(bytes2[this.#position]))
|
|
9157
10075
|
this.#position += 1;
|
|
9158
|
-
if (
|
|
9159
|
-
while (this.#position <
|
|
10076
|
+
if (bytes2[this.#position] !== 37) return this.#position;
|
|
10077
|
+
while (this.#position < bytes2.length && bytes2[this.#position] !== LF && bytes2[this.#position] !== CR)
|
|
9160
10078
|
this.#position += 1;
|
|
9161
10079
|
}
|
|
9162
10080
|
}
|
|
9163
10081
|
next() {
|
|
9164
|
-
const
|
|
10082
|
+
const bytes2 = this.#bytes;
|
|
9165
10083
|
const start = this.skipWhitespace();
|
|
9166
|
-
if (start >=
|
|
9167
|
-
const byte =
|
|
10084
|
+
if (start >= bytes2.length) return { kind: "end", start, end: start };
|
|
10085
|
+
const byte = bytes2[start];
|
|
9168
10086
|
if (byte === 40) {
|
|
9169
10087
|
let depth = 0;
|
|
9170
10088
|
let index2 = start;
|
|
9171
|
-
for (; index2 <
|
|
9172
|
-
const current =
|
|
10089
|
+
for (; index2 < bytes2.length; index2 += 1) {
|
|
10090
|
+
const current = bytes2[index2];
|
|
9173
10091
|
if (current === 92)
|
|
9174
10092
|
index2 += 1;
|
|
9175
10093
|
else if (current === 40) depth += 1;
|
|
9176
10094
|
else if (current === 41 && --depth === 0) break;
|
|
9177
10095
|
}
|
|
9178
|
-
this.#position = Math.min(index2 + 1,
|
|
10096
|
+
this.#position = Math.min(index2 + 1, bytes2.length);
|
|
9179
10097
|
return { kind: "string", start, end: this.#position };
|
|
9180
10098
|
}
|
|
9181
10099
|
if (byte === 60) {
|
|
9182
|
-
if (
|
|
10100
|
+
if (bytes2[start + 1] === 60) {
|
|
9183
10101
|
this.#position = start + 2;
|
|
9184
10102
|
return {
|
|
9185
10103
|
kind: "delimiter",
|
|
@@ -9189,11 +10107,11 @@ var Lexer = class {
|
|
|
9189
10107
|
};
|
|
9190
10108
|
}
|
|
9191
10109
|
let index2 = start + 1;
|
|
9192
|
-
while (index2 <
|
|
9193
|
-
this.#position = Math.min(index2 + 1,
|
|
10110
|
+
while (index2 < bytes2.length && bytes2[index2] !== 62) index2 += 1;
|
|
10111
|
+
this.#position = Math.min(index2 + 1, bytes2.length);
|
|
9194
10112
|
return { kind: "string", start, end: this.#position };
|
|
9195
10113
|
}
|
|
9196
|
-
if (byte === 62 &&
|
|
10114
|
+
if (byte === 62 && bytes2[start + 1] === 62) {
|
|
9197
10115
|
this.#position = start + 2;
|
|
9198
10116
|
return {
|
|
9199
10117
|
kind: "delimiter",
|
|
@@ -9213,16 +10131,16 @@ var Lexer = class {
|
|
|
9213
10131
|
}
|
|
9214
10132
|
if (byte === 47) {
|
|
9215
10133
|
let index2 = start + 1;
|
|
9216
|
-
while (index2 <
|
|
10134
|
+
while (index2 < bytes2.length && isRegular(bytes2[index2])) index2 += 1;
|
|
9217
10135
|
this.#position = index2;
|
|
9218
|
-
this.#lastName =
|
|
10136
|
+
this.#lastName = latin12(bytes2.subarray(start + 1, index2));
|
|
9219
10137
|
return { kind: "name", start, end: index2 };
|
|
9220
10138
|
}
|
|
9221
10139
|
let index = start;
|
|
9222
|
-
while (index <
|
|
10140
|
+
while (index < bytes2.length && isRegular(bytes2[index])) index += 1;
|
|
9223
10141
|
if (index === start) index += 1;
|
|
9224
10142
|
this.#position = index;
|
|
9225
|
-
const text =
|
|
10143
|
+
const text = latin12(bytes2.subarray(start, index));
|
|
9226
10144
|
const value = Number(text);
|
|
9227
10145
|
if (/^[+-]?(\d+\.?\d*|\.\d+)$/.test(text) && Number.isFinite(value))
|
|
9228
10146
|
return { kind: "number", value, start, end: index };
|
|
@@ -9239,22 +10157,22 @@ function isWhitespace(byte) {
|
|
|
9239
10157
|
function isRegular(byte) {
|
|
9240
10158
|
return !isWhitespace(byte) && byte !== 40 && byte !== 41 && byte !== 60 && byte !== 62 && byte !== 91 && byte !== 93 && byte !== 123 && byte !== 125 && byte !== 47 && byte !== 37;
|
|
9241
10159
|
}
|
|
9242
|
-
function matchesAscii(
|
|
9243
|
-
if (at + text.length >
|
|
10160
|
+
function matchesAscii(bytes2, at, text) {
|
|
10161
|
+
if (at + text.length > bytes2.length) return false;
|
|
9244
10162
|
for (let index = 0; index < text.length; index += 1)
|
|
9245
|
-
if (
|
|
10163
|
+
if (bytes2[at + index] !== text.charCodeAt(index)) return false;
|
|
9246
10164
|
return true;
|
|
9247
10165
|
}
|
|
9248
|
-
function
|
|
10166
|
+
function latin12(bytes2) {
|
|
9249
10167
|
let text = "";
|
|
9250
|
-
for (let offset2 = 0; offset2 <
|
|
9251
|
-
text += String.fromCharCode(...
|
|
10168
|
+
for (let offset2 = 0; offset2 < bytes2.length; offset2 += 32768)
|
|
10169
|
+
text += String.fromCharCode(...bytes2.subarray(offset2, offset2 + 32768));
|
|
9252
10170
|
return text;
|
|
9253
10171
|
}
|
|
9254
10172
|
function ascii(text) {
|
|
9255
10173
|
return Uint8Array.from(text, (character) => character.charCodeAt(0) & 255);
|
|
9256
10174
|
}
|
|
9257
|
-
function
|
|
10175
|
+
function concat2(parts) {
|
|
9258
10176
|
const out = new Uint8Array(
|
|
9259
10177
|
parts.reduce((total, part) => total + part.byteLength, 0)
|
|
9260
10178
|
);
|
|
@@ -9280,10 +10198,10 @@ var AssetStore = class {
|
|
|
9280
10198
|
has(id) {
|
|
9281
10199
|
return this.#bytes.has(id);
|
|
9282
10200
|
}
|
|
9283
|
-
set(id,
|
|
10201
|
+
set(id, bytes2) {
|
|
9284
10202
|
if (this.#bytes.has(id)) return;
|
|
9285
|
-
this.#bytes.set(id,
|
|
9286
|
-
this.#total +=
|
|
10203
|
+
this.#bytes.set(id, bytes2);
|
|
10204
|
+
this.#total += bytes2.byteLength;
|
|
9287
10205
|
}
|
|
9288
10206
|
/** Bytes held, for limits. */
|
|
9289
10207
|
get byteLength() {
|
|
@@ -9293,8 +10211,8 @@ var AssetStore = class {
|
|
|
9293
10211
|
function resolveBinary(data, assets) {
|
|
9294
10212
|
if (data instanceof Uint8Array) return data;
|
|
9295
10213
|
if (isAssetReference(data)) {
|
|
9296
|
-
const
|
|
9297
|
-
if (!
|
|
10214
|
+
const bytes2 = assets.get(data);
|
|
10215
|
+
if (!bytes2)
|
|
9298
10216
|
throw new ViewerError("invalid-operation", `Unknown asset ${data}`, {
|
|
9299
10217
|
details: {
|
|
9300
10218
|
issues: [
|
|
@@ -9307,7 +10225,7 @@ function resolveBinary(data, assets) {
|
|
|
9307
10225
|
]
|
|
9308
10226
|
}
|
|
9309
10227
|
});
|
|
9310
|
-
return
|
|
10228
|
+
return bytes2;
|
|
9311
10229
|
}
|
|
9312
10230
|
return Uint8Array.from(atob(data), (character) => character.charCodeAt(0));
|
|
9313
10231
|
}
|
|
@@ -9322,17 +10240,17 @@ var ImageCache = class {
|
|
|
9322
10240
|
const operation2 = raw;
|
|
9323
10241
|
if (operation2.op !== "insertImage" || operation2.mimeType !== "image/png")
|
|
9324
10242
|
continue;
|
|
9325
|
-
const
|
|
9326
|
-
if (!isPng(
|
|
9327
|
-
const key = contentKey(
|
|
10243
|
+
const bytes2 = resolveBinary(operation2.data, assets);
|
|
10244
|
+
if (!isPng(bytes2)) continue;
|
|
10245
|
+
const key = contentKey(bytes2);
|
|
9328
10246
|
if (this.#decoded.has(key)) continue;
|
|
9329
|
-
this.#decoded.set(key, await decode(
|
|
10247
|
+
this.#decoded.set(key, await decode(bytes2, "image/png"));
|
|
9330
10248
|
while (this.#decoded.size > 8)
|
|
9331
10249
|
this.#decoded.delete(this.#decoded.keys().next().value);
|
|
9332
10250
|
}
|
|
9333
10251
|
}
|
|
9334
|
-
get(
|
|
9335
|
-
return this.#decoded.get(contentKey(
|
|
10252
|
+
get(bytes2) {
|
|
10253
|
+
return this.#decoded.get(contentKey(bytes2));
|
|
9336
10254
|
}
|
|
9337
10255
|
};
|
|
9338
10256
|
var insertImage = {
|
|
@@ -9342,19 +10260,19 @@ var insertImage = {
|
|
|
9342
10260
|
return;
|
|
9343
10261
|
}
|
|
9344
10262
|
validateRect(operation2.rect, context.geometry(operation2.pageIndex), issue);
|
|
9345
|
-
const
|
|
9346
|
-
if (
|
|
10263
|
+
const bytes2 = resolveBinary(operation2.data, context.assets);
|
|
10264
|
+
if (bytes2.byteLength > context.limits.maxInputBytes)
|
|
9347
10265
|
throw new ViewerError(
|
|
9348
10266
|
"resource-limit",
|
|
9349
10267
|
"Image data exceeds maxInputBytes",
|
|
9350
10268
|
{
|
|
9351
10269
|
details: {
|
|
9352
|
-
bytes:
|
|
10270
|
+
bytes: bytes2.byteLength,
|
|
9353
10271
|
limit: context.limits.maxInputBytes
|
|
9354
10272
|
}
|
|
9355
10273
|
}
|
|
9356
10274
|
);
|
|
9357
|
-
const size = operation2.mimeType === "image/png" ? pngSize(
|
|
10275
|
+
const size = operation2.mimeType === "image/png" ? pngSize(bytes2) : jpegSize(bytes2);
|
|
9358
10276
|
if (!size) {
|
|
9359
10277
|
issue(
|
|
9360
10278
|
"/data",
|
|
@@ -9370,19 +10288,19 @@ var insertImage = {
|
|
|
9370
10288
|
"Decoded image exceeds maxDecodedPixels",
|
|
9371
10289
|
{ details: { pixels, limit: context.limits.maxDecodedPixels } }
|
|
9372
10290
|
);
|
|
9373
|
-
if (operation2.mimeType === "image/png" && !context.images.get(
|
|
10291
|
+
if (operation2.mimeType === "image/png" && !context.images.get(bytes2))
|
|
9374
10292
|
issue("/data", "invalid-data", "The PNG could not be decoded");
|
|
9375
10293
|
},
|
|
9376
10294
|
apply(operation2, context) {
|
|
9377
10295
|
const { pdfium } = context;
|
|
9378
10296
|
const { lib } = pdfium;
|
|
9379
|
-
const
|
|
10297
|
+
const bytes2 = resolveBinary(operation2.data, context.assets);
|
|
9380
10298
|
const id = context.newId(operation2.pageIndex);
|
|
9381
10299
|
const geometry = context.geometry(operation2.pageIndex);
|
|
9382
10300
|
const image = lib.FPDFPageObj_NewImageObj(context.document);
|
|
9383
10301
|
if (operation2.mimeType === "image/jpeg") {
|
|
9384
10302
|
const loaded = pdfium.withFileAccess(
|
|
9385
|
-
|
|
10303
|
+
bytes2,
|
|
9386
10304
|
(fileAccess) => lib.FPDFImageObj_LoadJpegFileInline(0, 0, image, fileAccess)
|
|
9387
10305
|
);
|
|
9388
10306
|
if (!loaded)
|
|
@@ -9390,7 +10308,7 @@ var insertImage = {
|
|
|
9390
10308
|
details: { stage: "apply" }
|
|
9391
10309
|
});
|
|
9392
10310
|
} else {
|
|
9393
|
-
const decoded = context.images.get(
|
|
10311
|
+
const decoded = context.images.get(bytes2);
|
|
9394
10312
|
setBitmap(context.pdfium, image, decoded);
|
|
9395
10313
|
}
|
|
9396
10314
|
const { rect } = operation2;
|
|
@@ -9464,24 +10382,24 @@ function setBitmap(pdfium, image, decoded) {
|
|
|
9464
10382
|
pdfium.free(buffer);
|
|
9465
10383
|
}
|
|
9466
10384
|
}
|
|
9467
|
-
function isPng(
|
|
9468
|
-
return
|
|
10385
|
+
function isPng(bytes2) {
|
|
10386
|
+
return bytes2.length > 24 && bytes2[0] === 137 && bytes2[1] === 80 && bytes2[2] === 78 && bytes2[3] === 71;
|
|
9469
10387
|
}
|
|
9470
|
-
function pngSize(
|
|
9471
|
-
if (!isPng(
|
|
9472
|
-
const view = new DataView(
|
|
10388
|
+
function pngSize(bytes2) {
|
|
10389
|
+
if (!isPng(bytes2)) return void 0;
|
|
10390
|
+
const view = new DataView(bytes2.buffer, bytes2.byteOffset, bytes2.byteLength);
|
|
9473
10391
|
const width = view.getUint32(16);
|
|
9474
10392
|
const height = view.getUint32(20);
|
|
9475
10393
|
return width > 0 && height > 0 ? { width, height } : void 0;
|
|
9476
10394
|
}
|
|
9477
|
-
function jpegSize(
|
|
9478
|
-
if (
|
|
10395
|
+
function jpegSize(bytes2) {
|
|
10396
|
+
if (bytes2.length < 4 || bytes2[0] !== 255 || bytes2[1] !== 216)
|
|
9479
10397
|
return void 0;
|
|
9480
|
-
const view = new DataView(
|
|
10398
|
+
const view = new DataView(bytes2.buffer, bytes2.byteOffset, bytes2.byteLength);
|
|
9481
10399
|
let offset2 = 2;
|
|
9482
|
-
while (offset2 + 9 <
|
|
9483
|
-
if (
|
|
9484
|
-
const marker =
|
|
10400
|
+
while (offset2 + 9 < bytes2.length) {
|
|
10401
|
+
if (bytes2[offset2] !== 255) return void 0;
|
|
10402
|
+
const marker = bytes2[offset2 + 1];
|
|
9485
10403
|
if (marker === 216 || marker >= 208 && marker <= 215 || marker === 1) {
|
|
9486
10404
|
offset2 += 2;
|
|
9487
10405
|
continue;
|
|
@@ -9497,10 +10415,10 @@ function jpegSize(bytes) {
|
|
|
9497
10415
|
}
|
|
9498
10416
|
return void 0;
|
|
9499
10417
|
}
|
|
9500
|
-
function contentKey(
|
|
10418
|
+
function contentKey(bytes2) {
|
|
9501
10419
|
let hash = 2166136261;
|
|
9502
|
-
for (const byte of
|
|
9503
|
-
return `${
|
|
10420
|
+
for (const byte of bytes2) hash = Math.imul(hash ^ byte, 16777619) >>> 0;
|
|
10421
|
+
return `${bytes2.byteLength}:${hash.toString(16)}`;
|
|
9504
10422
|
}
|
|
9505
10423
|
|
|
9506
10424
|
// src/limits.ts
|
|
@@ -9546,12 +10464,12 @@ function detectFeatures(pdfium, document2, original) {
|
|
|
9546
10464
|
if (containsAscii(original, "pdfaid:part")) features.push("pdfa");
|
|
9547
10465
|
return features;
|
|
9548
10466
|
}
|
|
9549
|
-
function containsAscii(
|
|
10467
|
+
function containsAscii(bytes2, needle) {
|
|
9550
10468
|
const first = needle.charCodeAt(0);
|
|
9551
|
-
const limit =
|
|
9552
|
-
for (let at =
|
|
10469
|
+
const limit = bytes2.length - needle.length;
|
|
10470
|
+
for (let at = bytes2.indexOf(first); at >= 0 && at <= limit; at = bytes2.indexOf(first, at + 1)) {
|
|
9553
10471
|
let index = 1;
|
|
9554
|
-
while (index < needle.length &&
|
|
10472
|
+
while (index < needle.length && bytes2[at + index] === needle.charCodeAt(index))
|
|
9555
10473
|
index += 1;
|
|
9556
10474
|
if (index === needle.length) return true;
|
|
9557
10475
|
}
|
|
@@ -9616,6 +10534,8 @@ var PdfEditDocument = class {
|
|
|
9616
10534
|
#measurer;
|
|
9617
10535
|
#pages;
|
|
9618
10536
|
#batches = 0;
|
|
10537
|
+
/** Browser faces of the document's fonts, by font program; see `textFont`. */
|
|
10538
|
+
#faces = /* @__PURE__ */ new Map();
|
|
9619
10539
|
constructor(pdfium, original, fonts = new FontLibrary(async () => {
|
|
9620
10540
|
throw new Error("No font source is configured");
|
|
9621
10541
|
}), limits = defaultResourceLimits, assets = new AssetStore(), compact = compactPdf) {
|
|
@@ -9891,6 +10811,18 @@ var PdfEditDocument = class {
|
|
|
9891
10811
|
return element ? layoutOf(this.#pdfium, scan, element) : void 0;
|
|
9892
10812
|
});
|
|
9893
10813
|
}
|
|
10814
|
+
/** The browser face of the font a text or text box element is drawn in, see `TextFont`. */
|
|
10815
|
+
textFont(elementId) {
|
|
10816
|
+
const location = this.#locate(elementId);
|
|
10817
|
+
const element = location && this.getElement(elementId);
|
|
10818
|
+
if (!element || element.kind !== "text" && element.kind !== "textBox")
|
|
10819
|
+
return void 0;
|
|
10820
|
+
const { lib } = this.#pdfium;
|
|
10821
|
+
return this.#withPage(location.pageIndex, (page) => {
|
|
10822
|
+
const object = location.indexes.map((index) => lib.FPDFPage_GetObject(page, index)).find((entry) => lib.FPDFPageObj_GetType(entry) === OBJECT_TEXT);
|
|
10823
|
+
return object === void 0 ? void 0 : { elementId, ...textFaceOf(this.#pdfium, object, this.#faces) };
|
|
10824
|
+
});
|
|
10825
|
+
}
|
|
9894
10826
|
/** The layouts of every text element on a page, with the page's displayed size. */
|
|
9895
10827
|
pageLayout(pageIndex) {
|
|
9896
10828
|
if (pageIndex < 0 || pageIndex >= this.#pages.length) return void 0;
|
|
@@ -10198,8 +11130,8 @@ var PdfEditDocument = class {
|
|
|
10198
11130
|
const textPage = lib.FPDFText_LoadPage(page);
|
|
10199
11131
|
try {
|
|
10200
11132
|
for (const [id, indexes] of members) {
|
|
10201
|
-
const
|
|
10202
|
-
if (!
|
|
11133
|
+
const head2 = heads.get(id);
|
|
11134
|
+
if (!head2 || !markIsFresh(this.#pdfium, page, textPage, geometry, head2, indexes))
|
|
10203
11135
|
stale.add(id);
|
|
10204
11136
|
}
|
|
10205
11137
|
} finally {
|
|
@@ -10317,12 +11249,12 @@ var PdfEditDocument = class {
|
|
|
10317
11249
|
const { lib } = this.#pdfium;
|
|
10318
11250
|
const count = lib.FPDFText_CountChars(textPage);
|
|
10319
11251
|
if (count === 0) return;
|
|
10320
|
-
const
|
|
10321
|
-
const buffer = this.#pdfium.malloc(
|
|
11252
|
+
const bytes2 = (count + 1) * 2;
|
|
11253
|
+
const buffer = this.#pdfium.malloc(bytes2);
|
|
10322
11254
|
let text;
|
|
10323
11255
|
try {
|
|
10324
11256
|
lib.FPDFText_GetText(textPage, 0, count, buffer);
|
|
10325
|
-
text = this.#pdfium.readWideStringAt(buffer,
|
|
11257
|
+
text = this.#pdfium.readWideStringAt(buffer, bytes2);
|
|
10326
11258
|
} finally {
|
|
10327
11259
|
this.#pdfium.free(buffer);
|
|
10328
11260
|
}
|
|
@@ -10363,7 +11295,7 @@ var PdfEditDocument = class {
|
|
|
10363
11295
|
}
|
|
10364
11296
|
if (!bases.has(object)) {
|
|
10365
11297
|
const own = this.#pdfium.readWideString(
|
|
10366
|
-
(buffer,
|
|
11298
|
+
(buffer, bytes2) => lib.FPDFTextObj_GetText(object, textPage, buffer, bytes2)
|
|
10367
11299
|
);
|
|
10368
11300
|
const whole = elementTexts.get(elementId) ?? "";
|
|
10369
11301
|
const from = cursors.get(elementId) ?? 0;
|
|
@@ -10495,11 +11427,11 @@ function createPdfEditHandler(host) {
|
|
|
10495
11427
|
case "edit-materialize": {
|
|
10496
11428
|
const { purpose, options } = payload ?? {};
|
|
10497
11429
|
const mode = options?.mode;
|
|
10498
|
-
const { bytes, warnings } = engine().materializeDocument(
|
|
11430
|
+
const { bytes: bytes2, warnings } = engine().materializeDocument(
|
|
10499
11431
|
purpose ?? "show",
|
|
10500
11432
|
mode === "full" || mode === "incremental" ? mode : void 0
|
|
10501
11433
|
);
|
|
10502
|
-
return { data:
|
|
11434
|
+
return { data: bytes2.buffer, warnings };
|
|
10503
11435
|
}
|
|
10504
11436
|
case "edit-restore": {
|
|
10505
11437
|
const { batches, base } = payload;
|
|
@@ -10540,6 +11472,8 @@ function createPdfEditHandler(host) {
|
|
|
10540
11472
|
const { pageIndex, elementIds, scale } = payload;
|
|
10541
11473
|
return engine().renderPageWithout(pageIndex, elementIds, scale);
|
|
10542
11474
|
}
|
|
11475
|
+
case "edit-text-font":
|
|
11476
|
+
return engine().textFont(payload.id);
|
|
10543
11477
|
case "edit-page-layout":
|
|
10544
11478
|
return engine().pageLayout(
|
|
10545
11479
|
payload.pageIndex
|
|
@@ -10591,9 +11525,9 @@ var Pdfium = class _Pdfium {
|
|
|
10591
11525
|
if (pointer) this.#runtime.wasmExports.free(pointer);
|
|
10592
11526
|
}
|
|
10593
11527
|
/** Copies bytes into the WASM heap; the caller frees the pointer. */
|
|
10594
|
-
writeBytes(
|
|
10595
|
-
const pointer = this.malloc(
|
|
10596
|
-
this.#runtime.HEAPU8.set(
|
|
11528
|
+
writeBytes(bytes2) {
|
|
11529
|
+
const pointer = this.malloc(bytes2.byteLength);
|
|
11530
|
+
this.#runtime.HEAPU8.set(bytes2, pointer);
|
|
10597
11531
|
return pointer;
|
|
10598
11532
|
}
|
|
10599
11533
|
readBytes(pointer, length) {
|
|
@@ -10601,26 +11535,26 @@ var Pdfium = class _Pdfium {
|
|
|
10601
11535
|
}
|
|
10602
11536
|
/** Writes a NUL-terminated UTF-16LE string; the caller frees the pointer. */
|
|
10603
11537
|
writeWideString(text) {
|
|
10604
|
-
const
|
|
10605
|
-
const pointer = this.malloc(
|
|
10606
|
-
this.#runtime.stringToUTF16(text, pointer,
|
|
11538
|
+
const bytes2 = (text.length + 1) * 2;
|
|
11539
|
+
const pointer = this.malloc(bytes2);
|
|
11540
|
+
this.#runtime.stringToUTF16(text, pointer, bytes2);
|
|
10607
11541
|
return pointer;
|
|
10608
11542
|
}
|
|
10609
11543
|
/** Reads a NUL-terminated UTF-16LE string of at most `bytes` bytes. */
|
|
10610
|
-
readWideStringAt(pointer,
|
|
10611
|
-
return this.#runtime.UTF16ToString(pointer,
|
|
11544
|
+
readWideStringAt(pointer, bytes2) {
|
|
11545
|
+
return this.#runtime.UTF16ToString(pointer, bytes2);
|
|
10612
11546
|
}
|
|
10613
11547
|
/**
|
|
10614
11548
|
* Reads a UTF-16LE string from an API that returns the byte size it needs
|
|
10615
11549
|
* when called with an empty buffer.
|
|
10616
11550
|
*/
|
|
10617
11551
|
readWideString(read2) {
|
|
10618
|
-
const
|
|
10619
|
-
if (
|
|
10620
|
-
const pointer = this.malloc(
|
|
11552
|
+
const bytes2 = read2(0, 0);
|
|
11553
|
+
if (bytes2 <= 2) return "";
|
|
11554
|
+
const pointer = this.malloc(bytes2);
|
|
10621
11555
|
try {
|
|
10622
|
-
read2(pointer,
|
|
10623
|
-
return this.#runtime.UTF16ToString(pointer,
|
|
11556
|
+
read2(pointer, bytes2);
|
|
11557
|
+
return this.#runtime.UTF16ToString(pointer, bytes2);
|
|
10624
11558
|
} finally {
|
|
10625
11559
|
this.free(pointer);
|
|
10626
11560
|
}
|
|
@@ -10633,12 +11567,12 @@ var Pdfium = class _Pdfium {
|
|
|
10633
11567
|
const outBytes = this.malloc(4);
|
|
10634
11568
|
try {
|
|
10635
11569
|
if (!read2(0, 0, outBytes)) return "";
|
|
10636
|
-
const
|
|
10637
|
-
if (
|
|
10638
|
-
const pointer = this.malloc(
|
|
11570
|
+
const bytes2 = this.#runtime.getValue(outBytes, "i32");
|
|
11571
|
+
if (bytes2 <= 2) return "";
|
|
11572
|
+
const pointer = this.malloc(bytes2);
|
|
10639
11573
|
try {
|
|
10640
|
-
if (!read2(pointer,
|
|
10641
|
-
return this.#runtime.UTF16ToString(pointer,
|
|
11574
|
+
if (!read2(pointer, bytes2, outBytes)) return "";
|
|
11575
|
+
return this.#runtime.UTF16ToString(pointer, bytes2);
|
|
10642
11576
|
} finally {
|
|
10643
11577
|
this.free(pointer);
|
|
10644
11578
|
}
|
|
@@ -10648,12 +11582,12 @@ var Pdfium = class _Pdfium {
|
|
|
10648
11582
|
}
|
|
10649
11583
|
/** Reads a NUL-terminated UTF-8 string from an API that returns the byte size it needs. */
|
|
10650
11584
|
readUtf8String(read2) {
|
|
10651
|
-
const
|
|
10652
|
-
if (
|
|
10653
|
-
const pointer = this.malloc(
|
|
11585
|
+
const bytes2 = read2(0, 0);
|
|
11586
|
+
if (bytes2 <= 1) return "";
|
|
11587
|
+
const pointer = this.malloc(bytes2);
|
|
10654
11588
|
try {
|
|
10655
|
-
read2(pointer,
|
|
10656
|
-
const raw = this.readBytes(pointer,
|
|
11589
|
+
read2(pointer, bytes2);
|
|
11590
|
+
const raw = this.readBytes(pointer, bytes2);
|
|
10657
11591
|
const end = raw.indexOf(0);
|
|
10658
11592
|
return new TextDecoder().decode(end < 0 ? raw : raw.subarray(0, end));
|
|
10659
11593
|
} finally {
|
|
@@ -10688,20 +11622,20 @@ var Pdfium = class _Pdfium {
|
|
|
10688
11622
|
* a WASM table callback. Only for APIs that read the data before returning,
|
|
10689
11623
|
* such as the inline JPEG loader.
|
|
10690
11624
|
*/
|
|
10691
|
-
withFileAccess(
|
|
11625
|
+
withFileAccess(bytes2, use) {
|
|
10692
11626
|
const runtime = this.#runtime;
|
|
10693
11627
|
const callback = runtime.addFunction(
|
|
10694
11628
|
(_parameter, position, buffer, size) => {
|
|
10695
|
-
if (position < 0 || size < 0 || position + size >
|
|
11629
|
+
if (position < 0 || size < 0 || position + size > bytes2.byteLength)
|
|
10696
11630
|
return 0;
|
|
10697
|
-
runtime.HEAPU8.set(
|
|
11631
|
+
runtime.HEAPU8.set(bytes2.subarray(position, position + size), buffer);
|
|
10698
11632
|
return 1;
|
|
10699
11633
|
},
|
|
10700
11634
|
"iiiii"
|
|
10701
11635
|
);
|
|
10702
11636
|
const fileAccess = this.malloc(FILE_ACCESS_BYTES);
|
|
10703
11637
|
try {
|
|
10704
|
-
runtime.setValue(fileAccess,
|
|
11638
|
+
runtime.setValue(fileAccess, bytes2.byteLength, "i32");
|
|
10705
11639
|
runtime.setValue(fileAccess + 4, callback, "i32");
|
|
10706
11640
|
runtime.setValue(fileAccess + 8, 0, "i32");
|
|
10707
11641
|
return use(fileAccess);
|
|
@@ -10711,9 +11645,9 @@ var Pdfium = class _Pdfium {
|
|
|
10711
11645
|
}
|
|
10712
11646
|
}
|
|
10713
11647
|
/** Opens a document from bytes; PDFium reads them lazily, so they stay in the heap. */
|
|
10714
|
-
openDocument(
|
|
10715
|
-
const data = this.writeBytes(
|
|
10716
|
-
const handle = this.lib.FPDF_LoadMemDocument(data,
|
|
11648
|
+
openDocument(bytes2) {
|
|
11649
|
+
const data = this.writeBytes(bytes2);
|
|
11650
|
+
const handle = this.lib.FPDF_LoadMemDocument(data, bytes2.byteLength, "");
|
|
10717
11651
|
if (!handle) {
|
|
10718
11652
|
const error = this.lib.FPDF_GetLastError();
|
|
10719
11653
|
this.free(data);
|
|
@@ -10778,9 +11712,9 @@ var PdfiumDocument = class {
|
|
|
10778
11712
|
this.#pdfium.free(this.#data);
|
|
10779
11713
|
}
|
|
10780
11714
|
};
|
|
10781
|
-
function exactArrayBuffer(
|
|
10782
|
-
if (
|
|
10783
|
-
return
|
|
11715
|
+
function exactArrayBuffer(bytes2) {
|
|
11716
|
+
if (bytes2 instanceof ArrayBuffer) return bytes2;
|
|
11717
|
+
return bytes2.buffer instanceof ArrayBuffer && bytes2.byteOffset === 0 && bytes2.byteLength === bytes2.buffer.byteLength ? bytes2.buffer : bytes2.slice().buffer;
|
|
10784
11718
|
}
|
|
10785
11719
|
|
|
10786
11720
|
// src/worker-protocol.ts
|
|
@@ -10865,9 +11799,9 @@ attachWorkerEndpoint(
|
|
|
10865
11799
|
createPdfEditHandler({
|
|
10866
11800
|
loadPdfium: async (wasmUrl) => Pdfium.load(await fetchBytes(wasmUrl)),
|
|
10867
11801
|
fetchBytes,
|
|
10868
|
-
decodeImage: async (
|
|
11802
|
+
decodeImage: async (bytes2, mimeType) => {
|
|
10869
11803
|
const bitmap = await createImageBitmap(
|
|
10870
|
-
new Blob([new Uint8Array(
|
|
11804
|
+
new Blob([new Uint8Array(bytes2)], { type: mimeType })
|
|
10871
11805
|
);
|
|
10872
11806
|
try {
|
|
10873
11807
|
const canvas = new OffscreenCanvas(bitmap.width, bitmap.height);
|