reamkit 1.24.0 → 1.25.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 +22 -11
- package/dist/esm/core/converter/facade.d.ts +3 -3
- package/dist/esm/core/converter/facade.js +12 -0
- package/dist/esm/core/converter/ream.d.ts +48 -4
- package/dist/esm/core/converter/ream.js +25 -4
- package/dist/esm/core/document-model/index.d.ts +1 -1
- package/dist/esm/core/document-model/types.d.ts +17 -0
- package/dist/esm/core/outline.d.ts +17 -0
- package/dist/esm/core/outline.js +30 -0
- package/dist/esm/core/style-cascade/resolver.js +1 -0
- package/dist/esm/core/style-cascade/types.d.ts +3 -1
- package/dist/esm/excel/sheet-to-flow.d.ts +10 -0
- package/dist/esm/excel/sheet-to-flow.js +14 -1
- package/dist/esm/html/html-writer.js +3 -2
- package/dist/esm/index.d.ts +3 -0
- package/dist/esm/index.js +2 -1
- package/dist/esm/layout/page-doc.js +1 -1
- package/dist/esm/layout/styled-layout.js +41 -15
- package/dist/esm/markdown/markdown-writer.d.ts +41 -0
- package/dist/esm/markdown/markdown-writer.js +733 -0
- package/dist/esm/pdf/styled-page-emitter.js +20 -1
- package/dist/esm/pdf-reader/annots.d.ts +24 -0
- package/dist/esm/pdf-reader/annots.js +126 -0
- package/dist/esm/pdf-reader/content.d.ts +131 -5
- package/dist/esm/pdf-reader/content.js +169 -12
- package/dist/esm/pdf-reader/display.d.ts +56 -0
- package/dist/esm/pdf-reader/display.js +162 -0
- package/dist/esm/pdf-reader/document.d.ts +36 -1
- package/dist/esm/pdf-reader/document.js +92 -25
- package/dist/esm/pdf-reader/embedded-fonts.d.ts +31 -0
- package/dist/esm/pdf-reader/embedded-fonts.js +94 -0
- package/dist/esm/pdf-reader/flow-build.d.ts +61 -6
- package/dist/esm/pdf-reader/flow-build.js +128 -22
- package/dist/esm/pdf-reader/font.js +185 -4
- package/dist/esm/pdf-reader/image-decode.js +55 -4
- package/dist/esm/pdf-reader/images.d.ts +6 -0
- package/dist/esm/pdf-reader/images.js +25 -5
- package/dist/esm/pdf-reader/jpeg.d.ts +18 -0
- package/dist/esm/pdf-reader/jpeg.js +419 -0
- package/dist/esm/pdf-reader/layout.d.ts +1 -1
- package/dist/esm/pdf-reader/layout.js +221 -32
- package/dist/esm/pdf-reader/pattern-tint.d.ts +17 -0
- package/dist/esm/pdf-reader/pattern-tint.js +181 -0
- package/dist/esm/pdf-reader/reader.d.ts +9 -1
- package/dist/esm/pdf-reader/reader.js +22 -6
- package/dist/esm/pdf-reader/shading.d.ts +14 -0
- package/dist/esm/pdf-reader/shading.js +27 -1
- package/dist/esm/pdf-reader/tagged.js +156 -17
- package/dist/esm/pdf-reader/text.d.ts +13 -1
- package/dist/esm/pdf-reader/text.js +70 -3
- package/dist/esm/pdf-reader/vector.d.ts +25 -1
- package/dist/esm/pdf-reader/vector.js +168 -12
- package/dist/esm/pptx/slide-parser.js +5 -0
- package/dist/esm/word/docx-writer.js +11 -1
- package/dist/esm/word/drawing-parser.js +7 -1
- package/package.json +1 -1
|
@@ -653,6 +653,7 @@ function emitPageContent(page, tagging, gradientNames, alphaStateNames, duotoneS
|
|
|
653
653
|
let lastSize = -1;
|
|
654
654
|
let lastColor = "";
|
|
655
655
|
let lastFauxWidth = 0;
|
|
656
|
+
let lastStroke;
|
|
656
657
|
let lastTz = 100;
|
|
657
658
|
const switchFontIfNeeded = (tok) => {
|
|
658
659
|
const fontKey = tok.font.resourceName;
|
|
@@ -661,11 +662,20 @@ function emitPageContent(page, tagging, gradientNames, alphaStateNames, duotoneS
|
|
|
661
662
|
lastFont = fontKey;
|
|
662
663
|
lastSize = tok.fontSizePt;
|
|
663
664
|
}
|
|
664
|
-
const
|
|
665
|
+
const outline = tok.resolvedRun.textOutline;
|
|
666
|
+
const fauxWidth = outline !== void 0 ? outline.widthPt : tok.synthetic?.bold === true ? tok.fontSizePt * .03 : 0;
|
|
665
667
|
if (fauxWidth !== lastFauxWidth) {
|
|
666
668
|
out.push(fauxWidth > 0 ? `2 Tr ${formatNumber(fauxWidth)} w` : "0 Tr");
|
|
667
669
|
lastFauxWidth = fauxWidth;
|
|
668
670
|
}
|
|
671
|
+
const strokeHex = outline?.colorHex;
|
|
672
|
+
if (strokeHex !== lastStroke) {
|
|
673
|
+
if (strokeHex !== void 0) {
|
|
674
|
+
const [sr, sg, sb] = hexToRgb01(strokeHex);
|
|
675
|
+
out.push(`${formatNumber(sr)} ${formatNumber(sg)} ${formatNumber(sb)} RG`);
|
|
676
|
+
}
|
|
677
|
+
lastStroke = strokeHex;
|
|
678
|
+
}
|
|
669
679
|
const tz = Math.round((tok.synthetic?.widthScale ?? 1) * 100);
|
|
670
680
|
if (tz !== lastTz) {
|
|
671
681
|
out.push(`${formatNumber(tz)} Tz`);
|
|
@@ -722,6 +732,8 @@ function emitPageContent(page, tagging, gradientNames, alphaStateNames, duotoneS
|
|
|
722
732
|
}
|
|
723
733
|
lastFont = "";
|
|
724
734
|
lastFauxWidth = 0;
|
|
735
|
+
lastStroke = void 0;
|
|
736
|
+
lastStroke = void 0;
|
|
725
737
|
lastTz = 100;
|
|
726
738
|
lastSize = -1;
|
|
727
739
|
lastColor = "";
|
|
@@ -770,6 +782,7 @@ function emitPageContent(page, tagging, gradientNames, alphaStateNames, duotoneS
|
|
|
770
782
|
}
|
|
771
783
|
lastFont = "";
|
|
772
784
|
lastFauxWidth = 0;
|
|
785
|
+
lastStroke = void 0;
|
|
773
786
|
lastTz = 100;
|
|
774
787
|
lastSize = -1;
|
|
775
788
|
lastColor = "";
|
|
@@ -804,6 +817,8 @@ function emitPageContent(page, tagging, gradientNames, alphaStateNames, duotoneS
|
|
|
804
817
|
out.push("Q");
|
|
805
818
|
lastFont = "";
|
|
806
819
|
lastFauxWidth = 0;
|
|
820
|
+
lastStroke = void 0;
|
|
821
|
+
lastStroke = void 0;
|
|
807
822
|
lastTz = 100;
|
|
808
823
|
lastSize = -1;
|
|
809
824
|
lastColor = "";
|
|
@@ -831,6 +846,8 @@ function emitPageContent(page, tagging, gradientNames, alphaStateNames, duotoneS
|
|
|
831
846
|
for (const op of emitVectorShape(shape)) out.push(op);
|
|
832
847
|
lastFont = "";
|
|
833
848
|
lastFauxWidth = 0;
|
|
849
|
+
lastStroke = void 0;
|
|
850
|
+
lastStroke = void 0;
|
|
834
851
|
lastTz = 100;
|
|
835
852
|
lastSize = -1;
|
|
836
853
|
lastColor = "";
|
|
@@ -850,6 +867,7 @@ function emitPageContent(page, tagging, gradientNames, alphaStateNames, duotoneS
|
|
|
850
867
|
out.push(`${formatNumber(clip.x)} ${formatNumber(H - clip.y - clip.height)} ${formatNumber(clip.width)} ${formatNumber(clip.height)} re W n`);
|
|
851
868
|
lastFont = "";
|
|
852
869
|
lastFauxWidth = 0;
|
|
870
|
+
lastStroke = void 0;
|
|
853
871
|
lastTz = 100;
|
|
854
872
|
lastSize = -1;
|
|
855
873
|
lastColor = "";
|
|
@@ -864,6 +882,7 @@ function emitPageContent(page, tagging, gradientNames, alphaStateNames, duotoneS
|
|
|
864
882
|
out.push("Q");
|
|
865
883
|
lastFont = "";
|
|
866
884
|
lastFauxWidth = 0;
|
|
885
|
+
lastStroke = void 0;
|
|
867
886
|
lastTz = 100;
|
|
868
887
|
lastSize = -1;
|
|
869
888
|
lastColor = "";
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Matrix } from './content.js';
|
|
2
|
+
import { PdfDict, PdfStream } from '../pdf/objects.js';
|
|
3
|
+
import { PdfFile, PdfPage } from './document.js';
|
|
4
|
+
/** One annotation's normal appearance, ready to interpret in page space. */
|
|
5
|
+
export interface Appearance {
|
|
6
|
+
readonly stream: PdfStream;
|
|
7
|
+
/** Maps the appearance's own space onto the page (§12.5.5). */
|
|
8
|
+
readonly ctm: Matrix;
|
|
9
|
+
/** The appearance's `/Resources`, when it states its own. */
|
|
10
|
+
readonly resources: PdfDict | undefined;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Every annotation appearance the page shows, in `/Annots` order — which is
|
|
14
|
+
* the order they paint in, over the page's own content.
|
|
15
|
+
*
|
|
16
|
+
* A `Popup` is a note's window and is never part of the page. An annotation
|
|
17
|
+
* flagged Hidden or NoView paints nothing. An `/AP` `/N` may be a stream or a
|
|
18
|
+
* dictionary of states, in which case `/AS` names the one in force.
|
|
19
|
+
*
|
|
20
|
+
* @param file The owning file, for resolving references.
|
|
21
|
+
* @param page The page whose annotations are wanted.
|
|
22
|
+
* @returns The appearances, each with the matrix that places it on the page.
|
|
23
|
+
*/
|
|
24
|
+
export declare function collectPageAppearances(file: PdfFile, page: PdfPage): Array<Appearance>;
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { PDF_NULL, PdfName, PdfStream } from "../pdf/objects.js";
|
|
2
|
+
import { IDENTITY, multiply } from "./content.js";
|
|
3
|
+
//#region src/pdf-reader/annots.ts
|
|
4
|
+
/** §12.5.3 `/F` — the annotation is not painted at all. */
|
|
5
|
+
var FLAG_HIDDEN = 2;
|
|
6
|
+
var FLAG_NOVIEW = 32;
|
|
7
|
+
/**
|
|
8
|
+
* Every annotation appearance the page shows, in `/Annots` order — which is
|
|
9
|
+
* the order they paint in, over the page's own content.
|
|
10
|
+
*
|
|
11
|
+
* A `Popup` is a note's window and is never part of the page. An annotation
|
|
12
|
+
* flagged Hidden or NoView paints nothing. An `/AP` `/N` may be a stream or a
|
|
13
|
+
* dictionary of states, in which case `/AS` names the one in force.
|
|
14
|
+
*
|
|
15
|
+
* @param file The owning file, for resolving references.
|
|
16
|
+
* @param page The page whose annotations are wanted.
|
|
17
|
+
* @returns The appearances, each with the matrix that places it on the page.
|
|
18
|
+
*/
|
|
19
|
+
function collectPageAppearances(file, page) {
|
|
20
|
+
const annots = file.get(page.dict, "Annots");
|
|
21
|
+
if (!Array.isArray(annots)) return [];
|
|
22
|
+
const out = [];
|
|
23
|
+
for (const entry of annots) {
|
|
24
|
+
const annot = file.resolve(entry);
|
|
25
|
+
if (!(annot instanceof Map)) continue;
|
|
26
|
+
const subtype = file.get(annot, "Subtype");
|
|
27
|
+
if (subtype instanceof PdfName && subtype.value === "Popup") continue;
|
|
28
|
+
const flags = file.get(annot, "F");
|
|
29
|
+
if (typeof flags === "number" && (flags & FLAG_HIDDEN || flags & FLAG_NOVIEW)) continue;
|
|
30
|
+
const stream = normalAppearance(file, annot);
|
|
31
|
+
if (!stream) continue;
|
|
32
|
+
const rect = rectangle(file.get(annot, "Rect"));
|
|
33
|
+
if (!rect) continue;
|
|
34
|
+
const matrix = matrixOf(file, stream.dict);
|
|
35
|
+
const bbox = rectangle(file.get(stream.dict, "BBox"));
|
|
36
|
+
const resources = file.get(stream.dict, "Resources");
|
|
37
|
+
out.push({
|
|
38
|
+
stream,
|
|
39
|
+
ctm: multiply(matrix, fitToRect(bbox, matrix, rect)),
|
|
40
|
+
resources: resources instanceof Map ? resources : void 0
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
return out;
|
|
44
|
+
}
|
|
45
|
+
/** §12.5.5 `/AP` `/N` — the normal appearance, through `/AS` when it is a set. */
|
|
46
|
+
function normalAppearance(file, annot) {
|
|
47
|
+
const ap = file.get(annot, "AP");
|
|
48
|
+
if (!(ap instanceof Map)) return void 0;
|
|
49
|
+
const normal = file.get(ap, "N");
|
|
50
|
+
if (normal instanceof PdfStream) return normal;
|
|
51
|
+
if (!(normal instanceof Map)) return void 0;
|
|
52
|
+
const state = file.get(annot, "AS");
|
|
53
|
+
const picked = state instanceof PdfName ? file.resolve(normal.get(state.value) ?? PDF_NULL) : PDF_NULL;
|
|
54
|
+
if (picked instanceof PdfStream) return picked;
|
|
55
|
+
const only = [...normal.values()].map((v) => file.resolve(v)).filter((v) => v instanceof PdfStream);
|
|
56
|
+
return only.length === 1 ? only[0] : void 0;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* §12.5.5 — the matrix taking the form's `/Matrix`-transformed `/BBox` onto the
|
|
60
|
+
* annotation's `/Rect`: the two are fitted corner to corner, so an appearance
|
|
61
|
+
* authored at any size lands exactly in the rectangle that owns it.
|
|
62
|
+
*/
|
|
63
|
+
function fitToRect(bbox, matrix, rect) {
|
|
64
|
+
if (!bbox) return [
|
|
65
|
+
1,
|
|
66
|
+
0,
|
|
67
|
+
0,
|
|
68
|
+
1,
|
|
69
|
+
rect[0],
|
|
70
|
+
rect[1]
|
|
71
|
+
];
|
|
72
|
+
const xs = [];
|
|
73
|
+
const ys = [];
|
|
74
|
+
for (const [x, y] of [
|
|
75
|
+
[bbox[0], bbox[1]],
|
|
76
|
+
[bbox[2], bbox[1]],
|
|
77
|
+
[bbox[2], bbox[3]],
|
|
78
|
+
[bbox[0], bbox[3]]
|
|
79
|
+
]) {
|
|
80
|
+
xs.push(matrix[0] * x + matrix[2] * y + matrix[4]);
|
|
81
|
+
ys.push(matrix[1] * x + matrix[3] * y + matrix[5]);
|
|
82
|
+
}
|
|
83
|
+
const bw = Math.max(...xs) - Math.min(...xs);
|
|
84
|
+
const bh = Math.max(...ys) - Math.min(...ys);
|
|
85
|
+
const sx = bw > 0 ? (rect[2] - rect[0]) / bw : 1;
|
|
86
|
+
const sy = bh > 0 ? (rect[3] - rect[1]) / bh : 1;
|
|
87
|
+
return [
|
|
88
|
+
sx,
|
|
89
|
+
0,
|
|
90
|
+
0,
|
|
91
|
+
sy,
|
|
92
|
+
rect[0] - Math.min(...xs) * sx,
|
|
93
|
+
rect[1] - Math.min(...ys) * sy
|
|
94
|
+
];
|
|
95
|
+
}
|
|
96
|
+
/** §8.10.2 `/Matrix`, or the identity when the form states none. */
|
|
97
|
+
function matrixOf(file, dict) {
|
|
98
|
+
const m = file.resolve(dict.get("Matrix") ?? PDF_NULL);
|
|
99
|
+
if (!Array.isArray(m) || m.length !== 6) return IDENTITY;
|
|
100
|
+
const n = m.map((v) => {
|
|
101
|
+
const r = file.resolve(v);
|
|
102
|
+
return typeof r === "number" ? r : 0;
|
|
103
|
+
});
|
|
104
|
+
return [
|
|
105
|
+
n[0],
|
|
106
|
+
n[1],
|
|
107
|
+
n[2],
|
|
108
|
+
n[3],
|
|
109
|
+
n[4],
|
|
110
|
+
n[5]
|
|
111
|
+
];
|
|
112
|
+
}
|
|
113
|
+
/** A four-number array as an ordered rectangle, or `undefined`. */
|
|
114
|
+
function rectangle(v) {
|
|
115
|
+
if (!Array.isArray(v) || v.length < 4) return void 0;
|
|
116
|
+
const n = v.slice(0, 4).map((x) => typeof x === "number" ? x : NaN);
|
|
117
|
+
if (n.some((x) => !Number.isFinite(x))) return void 0;
|
|
118
|
+
return [
|
|
119
|
+
Math.min(n[0], n[2]),
|
|
120
|
+
Math.min(n[1], n[3]),
|
|
121
|
+
Math.max(n[0], n[2]),
|
|
122
|
+
Math.max(n[1], n[3])
|
|
123
|
+
];
|
|
124
|
+
}
|
|
125
|
+
//#endregion
|
|
126
|
+
export { collectPageAppearances };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ShapeGradient } from '../core/vector.js';
|
|
2
|
+
import { PdfDict, PdfStream } from '../pdf/objects.js';
|
|
2
3
|
/**
|
|
3
4
|
* A page font as the interpreter needs it (built from the font dictionaries in
|
|
4
5
|
* EP2b): how wide each code is, and how a run of codes decodes to Unicode. An
|
|
@@ -12,6 +13,27 @@ export interface ContentFont {
|
|
|
12
13
|
decode: (codes: ReadonlyArray<number>) => string;
|
|
13
14
|
/** Glyph advance for one code, in 1000-unit text space. */
|
|
14
15
|
width: (code: number) => number;
|
|
16
|
+
/** §9.6.2 — the face's own `/BaseFont` name, for a document that embeds it. */
|
|
17
|
+
readonly name?: string;
|
|
18
|
+
/** §9.8.1 — the face is a bold one (weight, the ForceBold flag, or its name). */
|
|
19
|
+
readonly bold?: boolean;
|
|
20
|
+
/** §9.8.1 — the face is slanted (`/ItalicAngle`, the Italic flag, or its name). */
|
|
21
|
+
readonly italic?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* §9.6.5 — a Type 3 face, whose glyphs are content streams rather than
|
|
24
|
+
* outlines. What such a font draws is not type at all: it is whatever the
|
|
25
|
+
* procedure paints, in the resources the font states.
|
|
26
|
+
*/
|
|
27
|
+
readonly type3?: Type3Face;
|
|
28
|
+
}
|
|
29
|
+
/** §9.6.5 — the parts of a Type 3 font a caller needs to run its glyphs. */
|
|
30
|
+
export interface Type3Face {
|
|
31
|
+
/** `/FontMatrix` — glyph space to text space. */
|
|
32
|
+
readonly matrix: Matrix;
|
|
33
|
+
/** `/Encoding` + `/CharProcs` — the content stream one code draws. */
|
|
34
|
+
readonly proc: (code: number) => PdfStream | undefined;
|
|
35
|
+
/** `/Resources` the procedures draw with, when the font states its own. */
|
|
36
|
+
readonly resources: PdfDict | undefined;
|
|
15
37
|
}
|
|
16
38
|
/**
|
|
17
39
|
* One positioned text run emitted by a show operator: its decoded text, the
|
|
@@ -24,8 +46,63 @@ export interface TextRun {
|
|
|
24
46
|
readonly x: number;
|
|
25
47
|
/** Glyph origin y in page space (points). */
|
|
26
48
|
readonly y: number;
|
|
49
|
+
/**
|
|
50
|
+
* Where the pen stood after the last glyph, in page space (§9.4.4). The
|
|
51
|
+
* interpreter advances the text matrix by the font's own widths, so this is
|
|
52
|
+
* a measurement, not the half-em-per-character guess the reader used to make
|
|
53
|
+
* — and the difference between a word space and a table column is exactly
|
|
54
|
+
* the kind of thing a guess gets wrong.
|
|
55
|
+
*/
|
|
56
|
+
readonly endX: number;
|
|
57
|
+
/** The pen's y after the last glyph — with {@link endX}, the whole advance. */
|
|
58
|
+
readonly endY: number;
|
|
59
|
+
/**
|
|
60
|
+
* The baseline's direction in page space, degrees counter-clockwise from
|
|
61
|
+
* left-to-right (§9.4.2 — the text matrix may turn as well as move). Absent
|
|
62
|
+
* for ordinary upright text, which is nearly all of it.
|
|
63
|
+
*/
|
|
64
|
+
readonly angleDeg?: number;
|
|
27
65
|
readonly fontSizePt: number;
|
|
28
66
|
readonly fontKey: string;
|
|
67
|
+
/**
|
|
68
|
+
* §9.6.2 `/BaseFont` — the face's own name, subset prefix dropped and
|
|
69
|
+
* lowercased, or absent when the font states none. This is what a rebuilt run
|
|
70
|
+
* asks for, so a page whose faces the file EMBEDS is re-set in them rather
|
|
71
|
+
* than in a substitute (see `./embedded-fonts`).
|
|
72
|
+
*/
|
|
73
|
+
readonly fontName?: string;
|
|
74
|
+
/** §9.8.1 — the face the glyphs were shown in is a bold one. */
|
|
75
|
+
readonly bold?: boolean;
|
|
76
|
+
/**
|
|
77
|
+
* §8.6.6.2 — the glyphs are filled with a tiling PATTERN, named here for the
|
|
78
|
+
* caller to resolve: a pattern is a content stream, not a colour, and the
|
|
79
|
+
* fill colour still standing from before is not what the page shows.
|
|
80
|
+
*/
|
|
81
|
+
readonly fillPatternName?: string;
|
|
82
|
+
/**
|
|
83
|
+
* §9.3.6 — the page painted these glyphs NOWHERE: mode 3 shows nothing and
|
|
84
|
+
* mode 7 only adds to the clip. A scanned page carries its recognised words
|
|
85
|
+
* that way, under the picture of the page — so the run is kept, because it
|
|
86
|
+
* is the only text such a document has, and a reader reproducing the page
|
|
87
|
+
* leaves it to the picture.
|
|
88
|
+
*/
|
|
89
|
+
readonly invisible?: boolean;
|
|
90
|
+
/**
|
|
91
|
+
* §9.3.6 — the colour the glyphs are STROKED in, when the rendering mode
|
|
92
|
+
* asks for a stroke, and how wide the pen is.
|
|
93
|
+
*/
|
|
94
|
+
readonly outlineHex?: string;
|
|
95
|
+
readonly outlineWidthPt?: number;
|
|
96
|
+
/** §9.8.1 — the face the glyphs were shown in is a slanted one. */
|
|
97
|
+
readonly italic?: boolean;
|
|
98
|
+
/**
|
|
99
|
+
* §9.6.5 — the face is a Type 3 one, so what the page SHOWS here is the
|
|
100
|
+
* glyph procedures, not type. The run is kept for its words; a reader that
|
|
101
|
+
* reproduces the page draws the procedures instead of re-setting it.
|
|
102
|
+
*/
|
|
103
|
+
readonly type3?: boolean;
|
|
104
|
+
/** §8.6.8 — the non-stroking colour the glyphs were painted in (6-hex). */
|
|
105
|
+
readonly colorHex: string;
|
|
29
106
|
/**
|
|
30
107
|
* The marked-content id of the enclosing `BDC` sequence (§14.6), if any — the
|
|
31
108
|
* link from this text to the structure element that owns it (E-PDF EP3).
|
|
@@ -43,6 +120,8 @@ export interface TextRun {
|
|
|
43
120
|
* `mcid` links the paint to its structure element (a `/Figure`, E-PDF EP6).
|
|
44
121
|
*/
|
|
45
122
|
export interface ImagePlacement {
|
|
123
|
+
/** Where the `Do` fell in the stream's painting order — see {@link VectorPlacement.order}. */
|
|
124
|
+
readonly order: number;
|
|
46
125
|
/** XObject resource name (no leading slash). */
|
|
47
126
|
readonly name: string;
|
|
48
127
|
readonly ctm: Matrix;
|
|
@@ -72,17 +151,38 @@ export type PathSeg = {
|
|
|
72
151
|
readonly op: 'close';
|
|
73
152
|
};
|
|
74
153
|
/**
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
* a fill colour/gradient (EP10/EP16c) and/or a stroke colour + width (EP11),
|
|
78
|
-
* plus the enclosing structure id.
|
|
154
|
+
* §8.5.4 — the clipping region in force when a path was painted: the path that
|
|
155
|
+
* `W`/`W*` installed, plus its page-space bounding box.
|
|
79
156
|
*/
|
|
157
|
+
export interface ClipRegion {
|
|
158
|
+
readonly segs: ReadonlyArray<PathSeg>;
|
|
159
|
+
readonly minX: number;
|
|
160
|
+
readonly minY: number;
|
|
161
|
+
readonly maxX: number;
|
|
162
|
+
readonly maxY: number;
|
|
163
|
+
}
|
|
80
164
|
export interface VectorPlacement {
|
|
165
|
+
/**
|
|
166
|
+
* Where this fell in the stream's painting order (§8.5.3): later covers
|
|
167
|
+
* earlier, and a `Do` of a form is numbered here too, so a caller walking
|
|
168
|
+
* into that form knows exactly where its marks belong among these.
|
|
169
|
+
*/
|
|
170
|
+
readonly order: number;
|
|
81
171
|
readonly segs: ReadonlyArray<PathSeg>;
|
|
172
|
+
/** §8.5.4 — the clip in force when it was painted, when there was one. */
|
|
173
|
+
readonly clip?: ClipRegion;
|
|
82
174
|
/** Fill colour (6-hex), present iff the path is filled (`f` / `F` / `f*` / `B` / `b`). */
|
|
83
175
|
readonly fillHex?: string;
|
|
84
176
|
/** Shading pattern, present iff filled with one (EP16c). */
|
|
85
177
|
readonly gradient?: ShapeGradient;
|
|
178
|
+
/** §11.6.4.4 `/ca` — how opaque the fill is, when the page asked for less. */
|
|
179
|
+
readonly alpha?: number;
|
|
180
|
+
/**
|
|
181
|
+
* §8.7.3 — the TILING pattern resource name the path is filled with. Its
|
|
182
|
+
* content is a stream of its own, so what the fill actually shows is only
|
|
183
|
+
* known by walking into it; the `fillHex` beside this is not the fill.
|
|
184
|
+
*/
|
|
185
|
+
readonly patternName?: string;
|
|
86
186
|
/** Stroke colour (6-hex), present iff the path is stroked (`S` / `s` / `B` / `b`) — EP11. */
|
|
87
187
|
readonly strokeHex?: string;
|
|
88
188
|
/** Stroke width in page-space points — EP11. */
|
|
@@ -94,6 +194,19 @@ export interface InterpretResult {
|
|
|
94
194
|
readonly texts: Array<TextRun>;
|
|
95
195
|
readonly images: Array<ImagePlacement>;
|
|
96
196
|
readonly vectors: Array<VectorPlacement>;
|
|
197
|
+
/** §9.6.5 — every Type 3 glyph the stream showed, with where to run it. */
|
|
198
|
+
readonly glyphs: Array<Type3Call>;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* §9.6.5 — one showing of a Type 3 glyph: which procedure, and the matrix that
|
|
202
|
+
* puts glyph space on the page.
|
|
203
|
+
*/
|
|
204
|
+
export interface Type3Call {
|
|
205
|
+
readonly stream: PdfStream;
|
|
206
|
+
readonly resources: PdfDict | undefined;
|
|
207
|
+
readonly ctm: Matrix;
|
|
208
|
+
/** §8.5.3 — its place in the stream's painting order, as a form call has. */
|
|
209
|
+
readonly order: number;
|
|
97
210
|
}
|
|
98
211
|
/**
|
|
99
212
|
* 2D affine matrix `[a b c d e f]`, row-vector convention (`[x y 1] · M`):
|
|
@@ -120,6 +233,19 @@ export declare function multiply(a: Matrix, b: Matrix): Matrix;
|
|
|
120
233
|
* an unmapped key falls back to Latin-1 with a half-em advance.
|
|
121
234
|
* @param initialCtm The starting CTM mapping user space to page space.
|
|
122
235
|
* @param shadings Shading patterns by name, selected by `scn`/`sc` (EP16c).
|
|
236
|
+
* @param alphas Constant fill alphas by `/ExtGState` name, selected by `gs`.
|
|
123
237
|
* @returns The extracted text runs, image placements and vector paths.
|
|
124
238
|
*/
|
|
125
|
-
export declare function interpretContent(bytes: Uint8Array, fonts: ReadonlyMap<string, ContentFont>, initialCtm?: Matrix, shadings?: ReadonlyMap<string, ShapeGradient>): InterpretResult;
|
|
239
|
+
export declare function interpretContent(bytes: Uint8Array, fonts: ReadonlyMap<string, ContentFont>, initialCtm?: Matrix, shadings?: ReadonlyMap<string, ShapeGradient>, alphas?: ReadonlyMap<string, number>): InterpretResult;
|
|
240
|
+
/**
|
|
241
|
+
* Whether a string is wholly right-to-left: at least one letter of an RTL
|
|
242
|
+
* script and nothing of any other, spaces and joiners aside.
|
|
243
|
+
*
|
|
244
|
+
* Anything mixed — a number inside an Arabic sentence runs left to right —
|
|
245
|
+
* needs the full bidi algorithm, and guessing at it would be worse than
|
|
246
|
+
* leaving it alone.
|
|
247
|
+
*
|
|
248
|
+
* @param text The string to judge.
|
|
249
|
+
* @returns Whether it is one run of right-to-left script.
|
|
250
|
+
*/
|
|
251
|
+
export declare function isRightToLeft(text: string): boolean;
|