reamkit 1.5.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/esm/core/converter/facade.js +6 -1
- package/dist/esm/core/converter/ream.js +2 -1
- package/dist/esm/core/document-model/types.d.ts +9 -1
- package/dist/esm/core/drawingml/chart-serializer.d.ts +2 -0
- package/dist/esm/core/drawingml/chart-serializer.js +53 -0
- package/dist/esm/core/spreadsheet-model/index.d.ts +1 -1
- package/dist/esm/core/spreadsheet-model/types.d.ts +5 -0
- package/dist/esm/excel/column-bands.d.ts +7 -0
- package/dist/esm/excel/column-bands.js +87 -0
- package/dist/esm/excel/conditional-format.js +22 -0
- package/dist/esm/excel/print-model.js +33 -11
- package/dist/esm/excel/worksheet-parser.js +26 -0
- package/dist/esm/excel/xlsx-writer.js +88 -17
- package/dist/esm/html/html-writer.js +100 -5
- package/dist/esm/layout/styled-layout.js +88 -19
- package/dist/esm/pdf-reader/cmap.d.ts +5 -0
- package/dist/esm/pdf-reader/cmap.js +72 -0
- package/dist/esm/pdf-reader/content.d.ts +52 -0
- package/dist/esm/pdf-reader/content.js +420 -0
- package/dist/esm/pdf-reader/crypto.d.ts +7 -0
- package/dist/esm/pdf-reader/crypto.js +609 -0
- package/dist/esm/pdf-reader/decrypt.d.ts +5 -0
- package/dist/esm/pdf-reader/decrypt.js +199 -0
- package/dist/esm/pdf-reader/document.d.ts +30 -0
- package/dist/esm/pdf-reader/document.js +413 -0
- package/dist/esm/pdf-reader/flow-build.d.ts +19 -0
- package/dist/esm/pdf-reader/flow-build.js +126 -0
- package/dist/esm/pdf-reader/font.d.ts +4 -0
- package/dist/esm/pdf-reader/font.js +69 -0
- package/dist/esm/pdf-reader/image-decode.d.ts +15 -0
- package/dist/esm/pdf-reader/image-decode.js +442 -0
- package/dist/esm/pdf-reader/images.d.ts +16 -0
- package/dist/esm/pdf-reader/images.js +90 -0
- package/dist/esm/pdf-reader/layout.d.ts +3 -0
- package/dist/esm/pdf-reader/layout.js +103 -0
- package/dist/esm/pdf-reader/lexer.d.ts +43 -0
- package/dist/esm/pdf-reader/lexer.js +250 -0
- package/dist/esm/pdf-reader/parser.d.ts +10 -0
- package/dist/esm/pdf-reader/parser.js +86 -0
- package/dist/esm/pdf-reader/png-encode.d.ts +2 -0
- package/dist/esm/pdf-reader/png-encode.js +98 -0
- package/dist/esm/pdf-reader/predictor.d.ts +7 -0
- package/dist/esm/pdf-reader/predictor.js +61 -0
- package/dist/esm/pdf-reader/reader.d.ts +4 -0
- package/dist/esm/pdf-reader/reader.js +50 -0
- package/dist/esm/pdf-reader/struct-tree.d.ts +14 -0
- package/dist/esm/pdf-reader/struct-tree.js +92 -0
- package/dist/esm/pdf-reader/tagged.d.ts +3 -0
- package/dist/esm/pdf-reader/tagged.js +141 -0
- package/dist/esm/pdf-reader/text.d.ts +3 -0
- package/dist/esm/pdf-reader/text.js +65 -0
- package/dist/esm/pdf-reader/vector.d.ts +12 -0
- package/dist/esm/pdf-reader/vector.js +54 -0
- package/dist/esm/word/docx-writer.js +96 -7
- package/dist/esm/word/omml-serializer.d.ts +2 -0
- package/dist/esm/word/omml-serializer.js +48 -0
- package/package.json +2 -2
|
@@ -356,6 +356,21 @@ function emitTable(out, table, ctx) {
|
|
|
356
356
|
return start;
|
|
357
357
|
});
|
|
358
358
|
});
|
|
359
|
+
const frozen = table.properties.frozen;
|
|
360
|
+
const leftOffsets = [];
|
|
361
|
+
const topOffsets = [];
|
|
362
|
+
if (frozen) {
|
|
363
|
+
let left = 0;
|
|
364
|
+
for (const w of table.grid) {
|
|
365
|
+
leftOffsets.push(left);
|
|
366
|
+
left += w;
|
|
367
|
+
}
|
|
368
|
+
let top = 0;
|
|
369
|
+
for (const row of table.rows) {
|
|
370
|
+
topOffsets.push(top);
|
|
371
|
+
top += row.properties.height ?? 15;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
359
374
|
for (let ri = 0; ri < table.rows.length; ri++) {
|
|
360
375
|
const row = table.rows[ri];
|
|
361
376
|
out.push("<tr>");
|
|
@@ -363,14 +378,17 @@ function emitTable(out, table, ctx) {
|
|
|
363
378
|
const cell = row.cells[ci];
|
|
364
379
|
const merge = cell.properties.merge;
|
|
365
380
|
if (merge === "middle" || merge === "end") continue;
|
|
366
|
-
const
|
|
381
|
+
const cs = colStarts[ri][ci];
|
|
382
|
+
const rowSpan = merge === "start" ? mergeRowSpan(table, colStarts, ri, cs) : 1;
|
|
367
383
|
emitCell(out, cell, table, ctx, {
|
|
368
384
|
isHeader: row.properties.isHeader === true,
|
|
369
385
|
firstRow: ri === 0,
|
|
370
386
|
lastRow: ri === table.rows.length - 1,
|
|
371
|
-
firstCol:
|
|
372
|
-
lastCol:
|
|
373
|
-
rowSpan
|
|
387
|
+
firstCol: cs === 0,
|
|
388
|
+
lastCol: cs + (cell.properties.colSpan ?? 1) >= table.grid.length,
|
|
389
|
+
rowSpan,
|
|
390
|
+
...frozen && ri < frozen.rows ? { stickyTop: topOffsets[ri] } : {},
|
|
391
|
+
...frozen && cs < frozen.cols ? { stickyLeft: leftOffsets[cs] } : {}
|
|
374
392
|
});
|
|
375
393
|
}
|
|
376
394
|
out.push("</tr>");
|
|
@@ -417,6 +435,14 @@ function emitCell(out, cell, table, ctx, pos) {
|
|
|
417
435
|
const padBottom = margins?.bottom ?? 0;
|
|
418
436
|
const padLeft = margins?.left ?? 5.4;
|
|
419
437
|
css.push(`padding:${fmt(padTop)}pt ${fmt(padRight)}pt ${fmt(padBottom)}pt ${fmt(padLeft)}pt`);
|
|
438
|
+
if (pos.stickyTop !== void 0 || pos.stickyLeft !== void 0) {
|
|
439
|
+
css.push("position:sticky");
|
|
440
|
+
if (pos.stickyTop !== void 0) css.push(`top:${fmt(pos.stickyTop)}pt`);
|
|
441
|
+
if (pos.stickyLeft !== void 0) css.push(`left:${fmt(pos.stickyLeft)}pt`);
|
|
442
|
+
const z = pos.stickyTop !== void 0 && pos.stickyLeft !== void 0 ? 3 : pos.stickyTop !== void 0 ? 2 : 1;
|
|
443
|
+
css.push(`z-index:${z}`);
|
|
444
|
+
if (!cell.properties.shading) css.push("background-color:#fff");
|
|
445
|
+
}
|
|
420
446
|
out.push(`<${tag}${attrs.length > 0 ? ` ${attrs.join(" ")}` : ""} style="${css.join(";")}">`);
|
|
421
447
|
if (cell.properties.icon) out.push(cellIconSvg(cell.properties.icon));
|
|
422
448
|
if (cell.properties.sparkline) out.push(cellSparklineSvg(cell.properties.sparkline));
|
|
@@ -436,8 +462,77 @@ function cellSparklineSvg(sp) {
|
|
|
436
462
|
}
|
|
437
463
|
return `<svg width="${W}" height="${H}" viewBox="0 0 ${W} ${H}" style="vertical-align:middle"><g transform="translate(0,${H}) scale(1,-1)">${parts.join("")}</g></svg>`;
|
|
438
464
|
}
|
|
465
|
+
var ICON_EMPTY_HEX = "BFBFBF";
|
|
439
466
|
function cellIconSvg(icon) {
|
|
440
|
-
|
|
467
|
+
const fill = `#${icon.colorHex}`;
|
|
468
|
+
let body;
|
|
469
|
+
switch (icon.shape) {
|
|
470
|
+
case "square":
|
|
471
|
+
body = `<rect x="1" y="1" width="8" height="8" fill="${fill}"/>`;
|
|
472
|
+
break;
|
|
473
|
+
case "diamond":
|
|
474
|
+
body = `<polygon points="5,1 9,5 5,9 1,5" fill="${fill}"/>`;
|
|
475
|
+
break;
|
|
476
|
+
case "triangleUp":
|
|
477
|
+
body = `<polygon points="5,1 9,9 1,9" fill="${fill}"/>`;
|
|
478
|
+
break;
|
|
479
|
+
case "triangleDown":
|
|
480
|
+
body = `<polygon points="1,1 9,1 5,9" fill="${fill}"/>`;
|
|
481
|
+
break;
|
|
482
|
+
case "triangleRight":
|
|
483
|
+
body = `<polygon points="9,5 1,1 1,9" fill="${fill}"/>`;
|
|
484
|
+
break;
|
|
485
|
+
case "check":
|
|
486
|
+
body = `<polyline points="1.6,5 4,7.4 8.4,2.6" fill="none" stroke="${fill}" stroke-width="1.6"/>`;
|
|
487
|
+
break;
|
|
488
|
+
case "cross":
|
|
489
|
+
body = `<path d="M2.4 2.4 L7.6 7.6 M2.4 7.6 L7.6 2.4" fill="none" stroke="${fill}" stroke-width="1.6"/>`;
|
|
490
|
+
break;
|
|
491
|
+
case "exclamation":
|
|
492
|
+
body = `<rect x="4.1" y="1" width="1.8" height="5.6" fill="${fill}"/><rect x="4.1" y="7.4" width="1.8" height="1.6" fill="${fill}"/>`;
|
|
493
|
+
break;
|
|
494
|
+
case "bars":
|
|
495
|
+
body = barsIconSvg(icon.fill, fill, `#${ICON_EMPTY_HEX}`);
|
|
496
|
+
break;
|
|
497
|
+
case "pie":
|
|
498
|
+
body = pieIconSvg(icon.fill, fill, `#${ICON_EMPTY_HEX}`);
|
|
499
|
+
break;
|
|
500
|
+
case "circle":
|
|
501
|
+
body = `<circle cx="5" cy="5" r="4" fill="${fill}"/>`;
|
|
502
|
+
break;
|
|
503
|
+
}
|
|
504
|
+
return `<svg width="10" height="10" viewBox="0 0 10 10" style="vertical-align:middle;margin-right:3px">${body}</svg>`;
|
|
505
|
+
}
|
|
506
|
+
var round2 = (n) => (Math.round(n * 100) / 100).toString();
|
|
507
|
+
function barsIconSvg(fill, color, empty) {
|
|
508
|
+
const n = Math.max(1, fill?.levels ?? 4);
|
|
509
|
+
const filled = fill?.filled ?? 0;
|
|
510
|
+
const gap = 10 * .12;
|
|
511
|
+
const bw = (10 - gap * (n - 1)) / n;
|
|
512
|
+
let out = "";
|
|
513
|
+
for (let i = 0; i < n; i++) {
|
|
514
|
+
const h = 10 * (.32 + .68 * (i + 1) / n);
|
|
515
|
+
out += `<rect x="${round2(i * (bw + gap))}" y="${round2(10 - h)}" width="${round2(bw)}" height="${round2(h)}" fill="${i < filled ? color : empty}"/>`;
|
|
516
|
+
}
|
|
517
|
+
return out;
|
|
518
|
+
}
|
|
519
|
+
function pieIconSvg(fill, color, empty) {
|
|
520
|
+
const cx = 5;
|
|
521
|
+
const cy = 5;
|
|
522
|
+
const r = 4.4;
|
|
523
|
+
const levels = Math.max(1, fill?.levels ?? 4);
|
|
524
|
+
const filled = Math.max(0, Math.min(levels, fill?.filled ?? 0));
|
|
525
|
+
let out = `<circle cx="${cx}" cy="${cy}" r="${r}" fill="${empty}"/>`;
|
|
526
|
+
if (filled >= levels) out += `<circle cx="${cx}" cy="${cy}" r="${r}" fill="${color}"/>`;
|
|
527
|
+
else if (filled > 0) {
|
|
528
|
+
const frac = filled / levels;
|
|
529
|
+
const ang = -Math.PI / 2 + frac * 2 * Math.PI;
|
|
530
|
+
const ex = cx + r * Math.cos(ang);
|
|
531
|
+
const ey = cy + r * Math.sin(ang);
|
|
532
|
+
const large = frac > .5 ? 1 : 0;
|
|
533
|
+
out += `<path d="M${cx} ${cy} L${cx} ${round2(cy - r)} A${r} ${r} 0 ${large} 1 ${round2(ex)} ${round2(ey)} Z" fill="${color}"/>`;
|
|
534
|
+
}
|
|
535
|
+
return out;
|
|
441
536
|
}
|
|
442
537
|
function pushBorder(css, side, border) {
|
|
443
538
|
if (!border || border.style === "none") return;
|
|
@@ -563,11 +563,35 @@ function rectAtPath(x, y, w, h) {
|
|
|
563
563
|
}
|
|
564
564
|
var CF_ICON_SIZE_PT = 9;
|
|
565
565
|
var CF_ICON_GUTTER_PT = 12;
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
566
|
+
var CF_ICON_EMPTY_HEX = "BFBFBF";
|
|
567
|
+
function buildCellIconShape(icon, s) {
|
|
568
|
+
const color = icon.colorHex;
|
|
569
|
+
switch (icon.shape) {
|
|
570
|
+
case "bars": return barsIconPrims(s, color, icon.fill);
|
|
571
|
+
case "pie": return pieIconPrims(s, color, icon.fill);
|
|
572
|
+
case "check": return [{
|
|
573
|
+
paths: [checkPath(s)],
|
|
574
|
+
stroke: {
|
|
575
|
+
colorHex: color,
|
|
576
|
+
widthPt: s * .16
|
|
577
|
+
}
|
|
578
|
+
}];
|
|
579
|
+
case "cross": return [{
|
|
580
|
+
paths: crossPaths(s),
|
|
581
|
+
stroke: {
|
|
582
|
+
colorHex: color,
|
|
583
|
+
widthPt: s * .16
|
|
584
|
+
}
|
|
585
|
+
}];
|
|
586
|
+
case "exclamation": return [{
|
|
587
|
+
paths: [rectAtPath(s * .41, s * .34, s * .18, s * .56), rectAtPath(s * .41, s * .1, s * .18, s * .16)],
|
|
588
|
+
fillColorHex: color
|
|
589
|
+
}];
|
|
590
|
+
default: return [{
|
|
591
|
+
paths: [cellIconPath(icon.shape, s)],
|
|
592
|
+
fillColorHex: color
|
|
593
|
+
}];
|
|
594
|
+
}
|
|
571
595
|
}
|
|
572
596
|
function cellIconPath(shape, s) {
|
|
573
597
|
switch (shape) {
|
|
@@ -579,6 +603,52 @@ function cellIconPath(shape, s) {
|
|
|
579
603
|
case "circle": return circlePath(s / 2, s / 2, s * .42);
|
|
580
604
|
}
|
|
581
605
|
}
|
|
606
|
+
function barsIconPrims(s, color, fill) {
|
|
607
|
+
const n = Math.max(1, fill?.levels ?? 4);
|
|
608
|
+
const filled = fill?.filled ?? 0;
|
|
609
|
+
const gap = s * .12;
|
|
610
|
+
const bw = (s - gap * (n - 1)) / n;
|
|
611
|
+
const prims = [];
|
|
612
|
+
for (let i = 0; i < n; i++) {
|
|
613
|
+
const h = s * (.32 + .68 * (i + 1) / n);
|
|
614
|
+
prims.push({
|
|
615
|
+
paths: [rectAtPath(i * (bw + gap), 0, bw, h)],
|
|
616
|
+
fillColorHex: i < filled ? color : CF_ICON_EMPTY_HEX
|
|
617
|
+
});
|
|
618
|
+
}
|
|
619
|
+
return prims;
|
|
620
|
+
}
|
|
621
|
+
function pieIconPrims(s, color, fill) {
|
|
622
|
+
const cx = s / 2;
|
|
623
|
+
const cy = s / 2;
|
|
624
|
+
const r = s * .46;
|
|
625
|
+
const levels = Math.max(1, fill?.levels ?? 4);
|
|
626
|
+
const filled = Math.max(0, Math.min(levels, fill?.filled ?? 0));
|
|
627
|
+
const prims = [{
|
|
628
|
+
paths: [circlePath(cx, cy, r)],
|
|
629
|
+
fillColorHex: CF_ICON_EMPTY_HEX
|
|
630
|
+
}];
|
|
631
|
+
if (filled >= levels) prims.push({
|
|
632
|
+
paths: [circlePath(cx, cy, r)],
|
|
633
|
+
fillColorHex: color
|
|
634
|
+
});
|
|
635
|
+
else if (filled > 0) {
|
|
636
|
+
const start = Math.PI / 2;
|
|
637
|
+
const sweep = -(filled / levels) * 2 * Math.PI;
|
|
638
|
+
const [sx, sy] = arcPoint(cx, cy, r, r, start);
|
|
639
|
+
prims.push({
|
|
640
|
+
paths: [new PathBuilder().moveTo(cx, cy).lineTo(sx, sy).append(arcToBeziers(cx, cy, r, r, start, sweep)).close().build()],
|
|
641
|
+
fillColorHex: color
|
|
642
|
+
});
|
|
643
|
+
}
|
|
644
|
+
return prims;
|
|
645
|
+
}
|
|
646
|
+
function checkPath(s) {
|
|
647
|
+
return new PathBuilder().moveTo(s * .16, s * .5).lineTo(s * .4, s * .26).lineTo(s * .84, s * .78).build();
|
|
648
|
+
}
|
|
649
|
+
function crossPaths(s) {
|
|
650
|
+
return [new PathBuilder().moveTo(s * .24, s * .24).lineTo(s * .76, s * .76).build(), new PathBuilder().moveTo(s * .24, s * .76).lineTo(s * .76, s * .24).build()];
|
|
651
|
+
}
|
|
582
652
|
function trianglePath(a, b, c) {
|
|
583
653
|
return new PathBuilder().moveTo(a[0], a[1]).lineTo(b[0], b[1]).lineTo(c[0], c[1]).close().build();
|
|
584
654
|
}
|
|
@@ -2129,22 +2199,21 @@ function emitRowChunk(out, row, marginLeft, cursorY, pageHeight, colCount, cellS
|
|
|
2129
2199
|
if (cell.icon && cell.mergeRole !== "middle" && cell.mergeRole !== "end") {
|
|
2130
2200
|
const iconSize = Math.min(CF_ICON_SIZE_PT, Math.max(0, row.heightPt - 1));
|
|
2131
2201
|
if (iconSize > 0) {
|
|
2132
|
-
const
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2202
|
+
const iconTransform = flipTransform([
|
|
2203
|
+
1,
|
|
2204
|
+
0,
|
|
2205
|
+
0,
|
|
2206
|
+
1,
|
|
2207
|
+
cellX + (CF_ICON_GUTTER_PT - iconSize) / 2,
|
|
2208
|
+
rowBottom + (row.heightPt - iconSize) / 2
|
|
2209
|
+
], pageHeight);
|
|
2210
|
+
for (const prim of buildCellIconShape(cell.icon, iconSize)) out.push({
|
|
2136
2211
|
type: "shape",
|
|
2137
2212
|
shape: {
|
|
2138
|
-
paths,
|
|
2139
|
-
fillColorHex,
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
0,
|
|
2143
|
-
0,
|
|
2144
|
-
1,
|
|
2145
|
-
iconX,
|
|
2146
|
-
iconBottomYUp
|
|
2147
|
-
], pageHeight)
|
|
2213
|
+
paths: prim.paths,
|
|
2214
|
+
...prim.fillColorHex ? { fillColorHex: prim.fillColorHex } : {},
|
|
2215
|
+
...prim.stroke ? { stroke: prim.stroke } : {},
|
|
2216
|
+
transform: iconTransform
|
|
2148
2217
|
}
|
|
2149
2218
|
});
|
|
2150
2219
|
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { Lexer } from "./lexer.js";
|
|
2
|
+
//#region src/pdf-reader/cmap.ts
|
|
3
|
+
var MAX_RANGE = 65536;
|
|
4
|
+
function parseToUnicodeCMap(bytes) {
|
|
5
|
+
const lexer = new Lexer(bytes);
|
|
6
|
+
const map = /* @__PURE__ */ new Map();
|
|
7
|
+
let codeBytes = 1;
|
|
8
|
+
for (;;) {
|
|
9
|
+
const tok = lexer.nextToken();
|
|
10
|
+
if (tok.kind === "eof") break;
|
|
11
|
+
if (tok.kind !== "keyword") continue;
|
|
12
|
+
if (tok.value === "begincodespacerange") for (;;) {
|
|
13
|
+
const t = lexer.nextToken();
|
|
14
|
+
if (t.kind === "eof" || t.kind === "keyword" && t.value === "endcodespacerange") break;
|
|
15
|
+
if (t.kind === "hexstr") {
|
|
16
|
+
if (t.bytes.length >= 2) codeBytes = 2;
|
|
17
|
+
lexer.nextToken();
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
else if (tok.value === "beginbfchar") for (;;) {
|
|
21
|
+
const src = lexer.nextToken();
|
|
22
|
+
if (src.kind === "eof" || src.kind === "keyword" && src.value === "endbfchar") break;
|
|
23
|
+
if (src.kind !== "hexstr") continue;
|
|
24
|
+
const dst = lexer.nextToken();
|
|
25
|
+
if (dst.kind !== "hexstr") continue;
|
|
26
|
+
map.set(bytesToInt(src.bytes), utf16be(dst.bytes));
|
|
27
|
+
}
|
|
28
|
+
else if (tok.value === "beginbfrange") for (;;) {
|
|
29
|
+
const lo = lexer.nextToken();
|
|
30
|
+
if (lo.kind === "eof" || lo.kind === "keyword" && lo.value === "endbfrange") break;
|
|
31
|
+
if (lo.kind !== "hexstr") continue;
|
|
32
|
+
const hi = lexer.nextToken();
|
|
33
|
+
if (hi.kind !== "hexstr") continue;
|
|
34
|
+
const loN = bytesToInt(lo.bytes);
|
|
35
|
+
const hiN = bytesToInt(hi.bytes);
|
|
36
|
+
const dst = lexer.nextToken();
|
|
37
|
+
if (dst.kind === "hexstr") {
|
|
38
|
+
const base = utf16be(dst.bytes);
|
|
39
|
+
for (let i = 0; loN + i <= hiN && i < MAX_RANGE; i++) map.set(loN + i, incString(base, i));
|
|
40
|
+
} else if (dst.kind === "arrayOpen") {
|
|
41
|
+
let i = 0;
|
|
42
|
+
for (;;) {
|
|
43
|
+
const el = lexer.nextToken();
|
|
44
|
+
if (el.kind === "arrayClose" || el.kind === "eof") break;
|
|
45
|
+
if (el.kind === "hexstr") map.set(loN + i++, utf16be(el.bytes));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
map,
|
|
52
|
+
codeBytes
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function bytesToInt(bytes) {
|
|
56
|
+
let n = 0;
|
|
57
|
+
for (const b of bytes) n = n * 256 + b;
|
|
58
|
+
return n;
|
|
59
|
+
}
|
|
60
|
+
function utf16be(bytes) {
|
|
61
|
+
let s = "";
|
|
62
|
+
for (let i = 0; i + 1 < bytes.length; i += 2) s += String.fromCharCode(bytes[i] << 8 | bytes[i + 1]);
|
|
63
|
+
if (bytes.length % 2 === 1) s += String.fromCharCode(bytes[bytes.length - 1]);
|
|
64
|
+
return s;
|
|
65
|
+
}
|
|
66
|
+
function incString(base, i) {
|
|
67
|
+
if (i === 0) return base;
|
|
68
|
+
if (base.length === 1) return String.fromCharCode(base.charCodeAt(0) + i);
|
|
69
|
+
return base;
|
|
70
|
+
}
|
|
71
|
+
//#endregion
|
|
72
|
+
export { parseToUnicodeCMap };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export interface ContentFont {
|
|
2
|
+
readonly bytesPerCode: 1 | 2;
|
|
3
|
+
decode: (codes: ReadonlyArray<number>) => string;
|
|
4
|
+
width: (code: number) => number;
|
|
5
|
+
}
|
|
6
|
+
export interface TextRun {
|
|
7
|
+
readonly text: string;
|
|
8
|
+
readonly x: number;
|
|
9
|
+
readonly y: number;
|
|
10
|
+
readonly fontSizePt: number;
|
|
11
|
+
readonly fontKey: string;
|
|
12
|
+
readonly mcid?: number;
|
|
13
|
+
readonly href?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface ImagePlacement {
|
|
16
|
+
readonly name: string;
|
|
17
|
+
readonly ctm: Matrix;
|
|
18
|
+
readonly mcid?: number;
|
|
19
|
+
}
|
|
20
|
+
export type PathSeg = {
|
|
21
|
+
readonly op: 'move';
|
|
22
|
+
readonly x: number;
|
|
23
|
+
readonly y: number;
|
|
24
|
+
} | {
|
|
25
|
+
readonly op: 'line';
|
|
26
|
+
readonly x: number;
|
|
27
|
+
readonly y: number;
|
|
28
|
+
} | {
|
|
29
|
+
readonly op: 'cubic';
|
|
30
|
+
readonly x1: number;
|
|
31
|
+
readonly y1: number;
|
|
32
|
+
readonly x2: number;
|
|
33
|
+
readonly y2: number;
|
|
34
|
+
readonly x: number;
|
|
35
|
+
readonly y: number;
|
|
36
|
+
} | {
|
|
37
|
+
readonly op: 'close';
|
|
38
|
+
};
|
|
39
|
+
export interface VectorPlacement {
|
|
40
|
+
readonly segs: ReadonlyArray<PathSeg>;
|
|
41
|
+
readonly fillHex: string;
|
|
42
|
+
readonly mcid?: number;
|
|
43
|
+
}
|
|
44
|
+
export interface InterpretResult {
|
|
45
|
+
readonly texts: Array<TextRun>;
|
|
46
|
+
readonly images: Array<ImagePlacement>;
|
|
47
|
+
readonly vectors: Array<VectorPlacement>;
|
|
48
|
+
}
|
|
49
|
+
export type Matrix = readonly [number, number, number, number, number, number];
|
|
50
|
+
export declare const IDENTITY: Matrix;
|
|
51
|
+
export declare function multiply(a: Matrix, b: Matrix): Matrix;
|
|
52
|
+
export declare function interpretContent(bytes: Uint8Array, fonts: ReadonlyMap<string, ContentFont>, initialCtm?: Matrix): InterpretResult;
|