reamkit 1.15.1 → 1.15.3
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/dist/esm/core/arc-to-bezier.d.ts +23 -0
- package/dist/esm/core/arc-to-bezier.js +23 -0
- package/dist/esm/core/bidi/algorithm.d.ts +26 -0
- package/dist/esm/core/bidi/algorithm.js +21 -0
- package/dist/esm/core/bidi/char-types.d.ts +17 -0
- package/dist/esm/core/bidi/char-types.js +10 -0
- package/dist/esm/core/bidi/index.d.ts +42 -0
- package/dist/esm/core/bidi/index.js +27 -0
- package/dist/esm/core/bidi/segments.d.ts +22 -0
- package/dist/esm/core/bidi/segments.js +14 -0
- package/dist/esm/core/bytes.d.ts +20 -0
- package/dist/esm/core/bytes.js +24 -1
- package/dist/esm/core/converter/facade.d.ts +38 -1
- package/dist/esm/core/converter/facade.js +25 -0
- package/dist/esm/core/converter/project.d.ts +12 -0
- package/dist/esm/core/converter/project.js +11 -0
- package/dist/esm/core/converter/ream.d.ts +107 -0
- package/dist/esm/core/converter/ream.js +76 -0
- package/dist/esm/core/crypto/asn1.d.ts +77 -0
- package/dist/esm/core/crypto/asn1.js +65 -0
- package/dist/esm/core/crypto/cms.d.ts +25 -0
- package/dist/esm/core/crypto/cms.js +8 -0
- package/dist/esm/core/document-model/index.d.ts +7 -0
- package/dist/esm/core/document-model/types.d.ts +328 -0
- package/dist/esm/core/drawingml/chart-geometry.d.ts +125 -0
- package/dist/esm/core/drawingml/chart-geometry.js +96 -0
- package/dist/esm/core/drawingml/chart-parser.d.ts +34 -0
- package/dist/esm/core/drawingml/chart-parser.js +34 -0
- package/dist/esm/core/drawingml/chart-serializer.d.ts +12 -0
- package/dist/esm/core/drawingml/chart-serializer.js +12 -0
- package/dist/esm/core/drawingml/colors.d.ts +53 -0
- package/dist/esm/core/drawingml/colors.js +41 -0
- package/dist/esm/core/drawingml/preset-geometry.d.ts +30 -0
- package/dist/esm/core/drawingml/preset-geometry.js +30 -0
- package/dist/esm/core/drawingml/shape-render.d.ts +54 -0
- package/dist/esm/core/drawingml/shape-render.js +54 -0
- package/dist/esm/core/drawingml/sparkline-geometry.d.ts +15 -0
- package/dist/esm/core/drawingml/sparkline-geometry.js +13 -0
- package/dist/esm/core/drawingml/theme-parser.d.ts +11 -0
- package/dist/esm/core/drawingml/theme-parser.js +11 -0
- package/dist/esm/core/font/arabic-joining.d.ts +21 -0
- package/dist/esm/core/font/arabic-joining.js +16 -0
- package/dist/esm/core/font/binary-reader.d.ts +17 -0
- package/dist/esm/core/font/binary-reader.js +17 -0
- package/dist/esm/core/font/font-registry.d.ts +37 -0
- package/dist/esm/core/font/font-registry.js +31 -0
- package/dist/esm/core/font/measure.d.ts +20 -0
- package/dist/esm/core/font/measure.js +11 -0
- package/dist/esm/core/font/opentype-layout.d.ts +49 -0
- package/dist/esm/core/font/opentype-layout.js +37 -0
- package/dist/esm/core/font/ttf-parser.d.ts +32 -0
- package/dist/esm/core/font/ttf-parser.js +7 -0
- package/dist/esm/core/font/ttf-subset.d.ts +21 -0
- package/dist/esm/core/font/ttf-subset.js +21 -0
- package/dist/esm/core/fonts/provider.d.ts +8 -1
- package/dist/esm/core/fonts/provider.js +1 -0
- package/dist/esm/core/fonts/remote-fonts.d.ts +22 -0
- package/dist/esm/core/fonts/remote-fonts.js +16 -0
- package/dist/esm/core/hyphenation/index.d.ts +25 -0
- package/dist/esm/core/hyphenation/index.js +17 -0
- package/dist/esm/core/hyphenation/liang.d.ts +27 -0
- package/dist/esm/core/hyphenation/liang.js +14 -0
- package/dist/esm/core/images.d.ts +32 -0
- package/dist/esm/core/images.js +12 -0
- package/dist/esm/core/ir/adapters.d.ts +23 -0
- package/dist/esm/core/ir/features.d.ts +8 -0
- package/dist/esm/core/ir/features.js +1 -0
- package/dist/esm/core/ir/flow.d.ts +20 -0
- package/dist/esm/core/ir/index.d.ts +7 -0
- package/dist/esm/core/ir/loss.d.ts +12 -0
- package/dist/esm/core/ir/loss.js +8 -0
- package/dist/esm/core/ir/resources.d.ts +12 -0
- package/dist/esm/core/ir/resources.js +11 -0
- package/dist/esm/core/ir/sheet.d.ts +81 -0
- package/dist/esm/core/ir/units.d.ts +9 -0
- package/dist/esm/core/ir/units.js +2 -0
- package/dist/esm/core/line-breaker/cjk.d.ts +26 -0
- package/dist/esm/core/line-breaker/cjk.js +60 -0
- package/dist/esm/core/line-breaker/greedy.d.ts +14 -0
- package/dist/esm/core/line-breaker/greedy.js +14 -0
- package/dist/esm/core/line-breaker/index.d.ts +1 -0
- package/dist/esm/core/line-breaker/index.js +3 -0
- package/dist/esm/core/line-breaker/knuth-plass.d.ts +29 -5
- package/dist/esm/core/line-breaker/knuth-plass.js +10 -5
- package/dist/esm/core/numbering/apply.d.ts +19 -0
- package/dist/esm/core/numbering/apply.js +19 -0
- package/dist/esm/core/numbering/state.d.ts +15 -0
- package/dist/esm/core/numbering/state.js +15 -0
- package/dist/esm/core/ole/cfb.d.ts +19 -0
- package/dist/esm/core/ole/cfb.js +16 -0
- package/dist/esm/core/opc/core-properties.d.ts +12 -0
- package/dist/esm/core/opc/core-properties.js +5 -0
- package/dist/esm/core/opc/opc-writer.d.ts +24 -4
- package/dist/esm/core/opc/opc-writer.js +12 -0
- package/dist/esm/core/opc/package.d.ts +55 -0
- package/dist/esm/core/opc/package.js +49 -1
- package/dist/esm/core/opc/relationship-types.d.ts +8 -0
- package/dist/esm/core/opc/relationship-types.js +5 -0
- package/dist/esm/core/opc/relationships.d.ts +12 -0
- package/dist/esm/core/opc/relationships.js +7 -0
- package/dist/esm/core/po-helpers.d.ts +38 -0
- package/dist/esm/core/po-helpers.js +33 -0
- package/dist/esm/core/spreadsheet-model/types.d.ts +302 -0
- package/dist/esm/core/style-cascade/resolver.d.ts +31 -0
- package/dist/esm/core/style-cascade/resolver.js +31 -0
- package/dist/esm/core/style-cascade/table.d.ts +7 -0
- package/dist/esm/core/style-cascade/table.js +7 -0
- package/dist/esm/core/style-cascade/types.d.ts +27 -0
- package/dist/esm/core/style-cascade/types.js +2 -0
- package/dist/esm/core/vector.d.ts +67 -0
- package/dist/esm/core/vector.js +23 -0
- package/dist/esm/excel/activex-parser.d.ts +31 -0
- package/dist/esm/excel/activex-parser.js +24 -0
- package/dist/esm/excel/cell-reference.d.ts +14 -0
- package/dist/esm/excel/cell-reference.js +9 -0
- package/dist/esm/excel/column-bands.d.ts +29 -0
- package/dist/esm/excel/column-bands.js +27 -7
- package/dist/esm/excel/comments-parser.d.ts +19 -0
- package/dist/esm/excel/comments-parser.js +19 -0
- package/dist/esm/excel/conditional-format.d.ts +38 -0
- package/dist/esm/excel/conditional-format.js +25 -0
- package/dist/esm/excel/defined-name-ref.d.ts +21 -0
- package/dist/esm/excel/defined-name-ref.js +20 -0
- package/dist/esm/excel/form-control-parser.d.ts +13 -0
- package/dist/esm/excel/form-control-parser.js +5 -0
- package/dist/esm/excel/formula/context.d.ts +37 -0
- package/dist/esm/excel/formula/dates.d.ts +23 -0
- package/dist/esm/excel/formula/dates.js +20 -0
- package/dist/esm/excel/formula/eval.d.ts +21 -0
- package/dist/esm/excel/formula/eval.js +11 -0
- package/dist/esm/excel/formula/functions.d.ts +12 -0
- package/dist/esm/excel/formula/functions.js +12 -0
- package/dist/esm/excel/formula/index.d.ts +21 -0
- package/dist/esm/excel/formula/index.js +16 -0
- package/dist/esm/excel/formula/lexer.d.ts +12 -0
- package/dist/esm/excel/formula/lexer.js +10 -0
- package/dist/esm/excel/formula/parser.d.ts +20 -0
- package/dist/esm/excel/formula/parser.js +53 -0
- package/dist/esm/excel/formula/value.d.ts +53 -0
- package/dist/esm/excel/formula/value.js +30 -0
- package/dist/esm/excel/header-footer.d.ts +9 -0
- package/dist/esm/excel/header-footer.js +9 -0
- package/dist/esm/excel/number-format.d.ts +34 -0
- package/dist/esm/excel/number-format.js +34 -0
- package/dist/esm/excel/pivot-table-parser.d.ts +8 -0
- package/dist/esm/excel/pivot-table-parser.js +8 -0
- package/dist/esm/excel/print-model.d.ts +77 -1
- package/dist/esm/excel/print-model.js +230 -26
- package/dist/esm/excel/shared-strings-parser.d.ts +13 -0
- package/dist/esm/excel/shared-strings-parser.js +5 -0
- package/dist/esm/excel/sheet-drawing.d.ts +34 -0
- package/dist/esm/excel/sheet-drawing.js +21 -0
- package/dist/esm/excel/sheet-shape-parser.d.ts +12 -0
- package/dist/esm/excel/sheet-shape-parser.js +12 -0
- package/dist/esm/excel/sheet-to-flow.d.ts +29 -0
- package/dist/esm/excel/sheet-to-flow.js +24 -7
- package/dist/esm/excel/slicer-parser.d.ts +23 -0
- package/dist/esm/excel/slicer-parser.js +10 -0
- package/dist/esm/excel/styles-parser.d.ts +8 -0
- package/dist/esm/excel/styles-parser.js +8 -0
- package/dist/esm/excel/table-parser.d.ts +24 -0
- package/dist/esm/excel/table-parser.js +5 -0
- package/dist/esm/excel/workbook-parser.d.ts +17 -0
- package/dist/esm/excel/workbook-parser.js +5 -0
- package/dist/esm/excel/worksheet-parser.d.ts +9 -0
- package/dist/esm/excel/worksheet-parser.js +39 -6
- package/dist/esm/excel/xls/biff-chart.d.ts +10 -0
- package/dist/esm/excel/xls/biff-chart.js +10 -0
- package/dist/esm/excel/xls/biff-reader.d.ts +27 -0
- package/dist/esm/excel/xls/biff-reader.js +44 -0
- package/dist/esm/excel/xls/biff-styles.d.ts +20 -0
- package/dist/esm/excel/xls/biff-styles.js +20 -0
- package/dist/esm/excel/xls/escher.d.ts +27 -0
- package/dist/esm/excel/xls/escher.js +18 -0
- package/dist/esm/excel/xls/xls-reader.d.ts +6 -0
- package/dist/esm/excel/xls/xls-reader.js +6 -0
- package/dist/esm/excel/xlsx-reader.d.ts +30 -0
- package/dist/esm/excel/xlsx-reader.js +38 -4
- package/dist/esm/excel/xlsx-to-pdf.d.ts +27 -0
- package/dist/esm/excel/xlsx-writer.d.ts +14 -0
- package/dist/esm/excel/xlsx-writer.js +13 -0
- package/dist/esm/html/html-writer.d.ts +18 -0
- package/dist/esm/html/html-writer.js +18 -0
- package/dist/esm/index.d.ts +23 -0
- package/dist/esm/layout/math-layout.d.ts +39 -0
- package/dist/esm/layout/math-layout.js +18 -0
- package/dist/esm/layout/page-doc.d.ts +91 -0
- package/dist/esm/layout/styled-layout.d.ts +175 -0
- package/dist/esm/layout/styled-layout.js +136 -4
- package/dist/esm/pdf/builtin-fonts.d.ts +5 -0
- package/dist/esm/pdf/cid-font.d.ts +22 -0
- package/dist/esm/pdf/cid-font.js +10 -0
- package/dist/esm/pdf/embedded-file.d.ts +16 -0
- package/dist/esm/pdf/embedded-file.js +9 -0
- package/dist/esm/pdf/encryption.d.ts +59 -0
- package/dist/esm/pdf/encryption.js +37 -0
- package/dist/esm/pdf/icc-profile.d.ts +8 -0
- package/dist/esm/pdf/icc-profile.js +8 -0
- package/dist/esm/pdf/image-xobject.d.ts +19 -0
- package/dist/esm/pdf/image-xobject.js +9 -0
- package/dist/esm/pdf/objects.d.ts +40 -0
- package/dist/esm/pdf/objects.js +36 -0
- package/dist/esm/pdf/serialize.d.ts +18 -0
- package/dist/esm/pdf/serialize.js +18 -0
- package/dist/esm/pdf/shading.d.ts +16 -0
- package/dist/esm/pdf/shading.js +16 -0
- package/dist/esm/pdf/signature.d.ts +36 -0
- package/dist/esm/pdf/signature.js +22 -0
- package/dist/esm/pdf/struct-tree.d.ts +64 -0
- package/dist/esm/pdf/struct-tree.js +60 -0
- package/dist/esm/pdf/styled-page-emitter.d.ts +33 -0
- package/dist/esm/pdf/styled-page-emitter.js +21 -0
- package/dist/esm/pdf/styled-page-renderer.d.ts +18 -0
- package/dist/esm/pdf/styled-page-renderer.js +18 -0
- package/dist/esm/pdf/text-encoding.d.ts +16 -0
- package/dist/esm/pdf/text-page-renderer.d.ts +11 -0
- package/dist/esm/pdf/vector-graphics.d.ts +12 -0
- package/dist/esm/pdf/vector-graphics.js +12 -0
- package/dist/esm/pdf/writer.d.ts +39 -0
- package/dist/esm/pdf/writer.js +27 -0
- package/dist/esm/pdf/xmp.d.ts +16 -0
- package/dist/esm/pdf/xmp.js +9 -0
- package/dist/esm/pdf-reader/ccitt.d.ts +25 -0
- package/dist/esm/pdf-reader/ccitt.js +15 -0
- package/dist/esm/pdf-reader/cmap.d.ts +12 -0
- package/dist/esm/pdf-reader/cmap.js +9 -0
- package/dist/esm/pdf-reader/content.d.ts +69 -0
- package/dist/esm/pdf-reader/content.js +16 -0
- package/dist/esm/pdf-reader/crypto.d.ts +5 -0
- package/dist/esm/pdf-reader/crypto.js +5 -0
- package/dist/esm/pdf-reader/decrypt.d.ts +17 -0
- package/dist/esm/pdf-reader/decrypt.js +12 -0
- package/dist/esm/pdf-reader/document.d.ts +53 -0
- package/dist/esm/pdf-reader/document.js +50 -0
- package/dist/esm/pdf-reader/flow-build.d.ts +47 -0
- package/dist/esm/pdf-reader/flow-build.js +42 -0
- package/dist/esm/pdf-reader/font.d.ts +12 -0
- package/dist/esm/pdf-reader/font.js +12 -0
- package/dist/esm/pdf-reader/image-decode.d.ts +21 -0
- package/dist/esm/pdf-reader/image-decode.js +14 -0
- package/dist/esm/pdf-reader/images.d.ts +19 -0
- package/dist/esm/pdf-reader/images.js +9 -0
- package/dist/esm/pdf-reader/layout.d.ts +15 -0
- package/dist/esm/pdf-reader/layout.js +15 -0
- package/dist/esm/pdf-reader/lexer.d.ts +43 -0
- package/dist/esm/pdf-reader/lexer.js +38 -0
- package/dist/esm/pdf-reader/parser.d.ts +15 -0
- package/dist/esm/pdf-reader/parser.js +8 -0
- package/dist/esm/pdf-reader/png-encode.d.ts +9 -0
- package/dist/esm/pdf-reader/png-encode.js +8 -0
- package/dist/esm/pdf-reader/predictor.d.ts +9 -0
- package/dist/esm/pdf-reader/predictor.js +8 -0
- package/dist/esm/pdf-reader/reader.d.ts +16 -0
- package/dist/esm/pdf-reader/reader.js +16 -0
- package/dist/esm/pdf-reader/shading.d.ts +10 -0
- package/dist/esm/pdf-reader/shading.js +10 -0
- package/dist/esm/pdf-reader/struct-tree.d.ts +24 -0
- package/dist/esm/pdf-reader/struct-tree.js +12 -0
- package/dist/esm/pdf-reader/tagged.d.ts +13 -0
- package/dist/esm/pdf-reader/tagged.js +13 -0
- package/dist/esm/pdf-reader/text.d.ts +11 -0
- package/dist/esm/pdf-reader/text.js +11 -0
- package/dist/esm/pdf-reader/vector.d.ts +19 -0
- package/dist/esm/pdf-reader/vector.js +9 -0
- package/dist/esm/pptx/placeholder-cascade.d.ts +21 -0
- package/dist/esm/pptx/placeholder-cascade.js +10 -0
- package/dist/esm/pptx/ppt/ppt-reader.d.ts +16 -0
- package/dist/esm/pptx/ppt/ppt-reader.js +16 -0
- package/dist/esm/pptx/ppt/ppt-text.d.ts +55 -0
- package/dist/esm/pptx/ppt/ppt-text.js +14 -0
- package/dist/esm/pptx/pptx-reader.d.ts +21 -0
- package/dist/esm/pptx/pptx-reader.js +23 -2
- package/dist/esm/pptx/slide-parser.d.ts +102 -0
- package/dist/esm/pptx/slide-parser.js +78 -0
- package/dist/esm/pptx/sp-helpers.d.ts +28 -0
- package/dist/esm/pptx/sp-helpers.js +22 -0
- package/dist/esm/svg/svg-writer.d.ts +17 -0
- package/dist/esm/svg/svg-writer.js +16 -0
- package/dist/esm/word/doc/doc-reader.d.ts +16 -0
- package/dist/esm/word/doc/doc-reader.js +16 -0
- package/dist/esm/word/doc/doc-text.d.ts +77 -0
- package/dist/esm/word/doc/doc-text.js +13 -0
- package/dist/esm/word/document-parser.d.ts +134 -0
- package/dist/esm/word/document-parser.js +86 -0
- package/dist/esm/word/docx-reader.d.ts +16 -0
- package/dist/esm/word/docx-reader.js +18 -2
- package/dist/esm/word/docx-to-pdf.d.ts +52 -0
- package/dist/esm/word/docx-to-pdf.js +21 -0
- package/dist/esm/word/docx-writer.d.ts +17 -0
- package/dist/esm/word/docx-writer.js +17 -0
- package/dist/esm/word/drawing-parser.d.ts +88 -0
- package/dist/esm/word/drawing-parser.js +68 -0
- package/dist/esm/word/font-table.d.ts +24 -0
- package/dist/esm/word/font-table.js +24 -0
- package/dist/esm/word/numbering-parser.d.ts +11 -0
- package/dist/esm/word/numbering-parser.js +11 -0
- package/dist/esm/word/omml-parser.d.ts +15 -0
- package/dist/esm/word/omml-parser.js +15 -0
- package/dist/esm/word/omml-serializer.d.ts +9 -0
- package/dist/esm/word/omml-serializer.js +9 -0
- package/dist/esm/word/paragraph-properties.d.ts +10 -0
- package/dist/esm/word/paragraph-properties.js +10 -0
- package/dist/esm/word/po-to-flat.d.ts +11 -0
- package/dist/esm/word/po-to-flat.js +11 -0
- package/dist/esm/word/run-properties.d.ts +10 -0
- package/dist/esm/word/run-properties.js +10 -0
- package/dist/esm/word/settings-parser.d.ts +13 -0
- package/dist/esm/word/settings-parser.js +8 -0
- package/dist/esm/word/styles-parser.d.ts +10 -0
- package/dist/esm/word/styles-parser.js +10 -0
- package/dist/esm/word/table-parser.d.ts +11 -0
- package/dist/esm/word/table-parser.js +11 -0
- package/dist/esm/word/text-extractor.d.ts +9 -0
- package/dist/esm/word/xml-helpers.d.ts +44 -0
- package/dist/esm/word/xml-helpers.js +38 -0
- package/package.json +5 -2
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import { Lexer } from "./lexer.js";
|
|
2
2
|
//#region src/pdf-reader/cmap.ts
|
|
3
3
|
var MAX_RANGE = 65536;
|
|
4
|
+
/**
|
|
5
|
+
* Parse a `/ToUnicode` CMap (ISO 32000-1 §9.10.3) into a code→Unicode map. Reads
|
|
6
|
+
* the `codespacerange` (code width), `bfchar` (single codes) and `bfrange`
|
|
7
|
+
* (contiguous ranges, scalar or array destination) blocks; everything else is
|
|
8
|
+
* ignored.
|
|
9
|
+
*
|
|
10
|
+
* @param bytes The decoded CMap stream.
|
|
11
|
+
* @returns The mapping plus the declared code width (1 or 2 bytes).
|
|
12
|
+
*/
|
|
4
13
|
function parseToUnicodeCMap(bytes) {
|
|
5
14
|
const lexer = new Lexer(bytes);
|
|
6
15
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -1,23 +1,57 @@
|
|
|
1
1
|
import { ShapeGradient } from '../core/vector.js';
|
|
2
|
+
/**
|
|
3
|
+
* A page font as the interpreter needs it (built from the font dictionaries in
|
|
4
|
+
* EP2b): how wide each code is, and how a run of codes decodes to Unicode. An
|
|
5
|
+
* unmapped font falls back to Latin-1 with a half-em advance so text still
|
|
6
|
+
* surfaces.
|
|
7
|
+
*/
|
|
2
8
|
export interface ContentFont {
|
|
9
|
+
/** Bytes per character code: simple fonts read 1 byte/code, Type0 reads 2. */
|
|
3
10
|
readonly bytesPerCode: 1 | 2;
|
|
11
|
+
/** Decode a sequence of character codes to a Unicode string. */
|
|
4
12
|
decode: (codes: ReadonlyArray<number>) => string;
|
|
13
|
+
/** Glyph advance for one code, in 1000-unit text space. */
|
|
5
14
|
width: (code: number) => number;
|
|
6
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* One positioned text run emitted by a show operator: its decoded text, the
|
|
18
|
+
* glyph origin in page space and the effective font size — the raw material a
|
|
19
|
+
* later stage groups into lines and paragraphs.
|
|
20
|
+
*/
|
|
7
21
|
export interface TextRun {
|
|
8
22
|
readonly text: string;
|
|
23
|
+
/** Glyph origin x in page space (points). */
|
|
9
24
|
readonly x: number;
|
|
25
|
+
/** Glyph origin y in page space (points). */
|
|
10
26
|
readonly y: number;
|
|
11
27
|
readonly fontSizePt: number;
|
|
12
28
|
readonly fontKey: string;
|
|
29
|
+
/**
|
|
30
|
+
* The marked-content id of the enclosing `BDC` sequence (§14.6), if any — the
|
|
31
|
+
* link from this text to the structure element that owns it (E-PDF EP3).
|
|
32
|
+
*/
|
|
13
33
|
readonly mcid?: number;
|
|
34
|
+
/**
|
|
35
|
+
* A `/Link` annotation whose `/Rect` covers this run's origin attaches its URI
|
|
36
|
+
* here (E-PDF EP8), so the reconstructed run carries the hyperlink.
|
|
37
|
+
*/
|
|
14
38
|
readonly href?: string;
|
|
15
39
|
}
|
|
40
|
+
/**
|
|
41
|
+
* A painted XObject (`/Name Do`, §8.8) — an image or form. The CTM maps the unit
|
|
42
|
+
* square to page space, so it carries both the placement and the size; the
|
|
43
|
+
* `mcid` links the paint to its structure element (a `/Figure`, E-PDF EP6).
|
|
44
|
+
*/
|
|
16
45
|
export interface ImagePlacement {
|
|
46
|
+
/** XObject resource name (no leading slash). */
|
|
17
47
|
readonly name: string;
|
|
18
48
|
readonly ctm: Matrix;
|
|
19
49
|
readonly mcid?: number;
|
|
20
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* One segment of a painted path (E-PDF EP10/EP11), in page space (y-up): a
|
|
53
|
+
* `move`/`line`/`cubic` Bézier point or a subpath `close`.
|
|
54
|
+
*/
|
|
21
55
|
export type PathSeg = {
|
|
22
56
|
readonly op: 'move';
|
|
23
57
|
readonly x: number;
|
|
@@ -37,20 +71,55 @@ export type PathSeg = {
|
|
|
37
71
|
} | {
|
|
38
72
|
readonly op: 'close';
|
|
39
73
|
};
|
|
74
|
+
/**
|
|
75
|
+
* A painted path emitted by the path-painting operators (§8.5.3), captured in
|
|
76
|
+
* page space (y-up). The optional fields record only what the paint mode set:
|
|
77
|
+
* a fill colour/gradient (EP10/EP16c) and/or a stroke colour + width (EP11),
|
|
78
|
+
* plus the enclosing structure id.
|
|
79
|
+
*/
|
|
40
80
|
export interface VectorPlacement {
|
|
41
81
|
readonly segs: ReadonlyArray<PathSeg>;
|
|
82
|
+
/** Fill colour (6-hex), present iff the path is filled (`f` / `F` / `f*` / `B` / `b`). */
|
|
42
83
|
readonly fillHex?: string;
|
|
84
|
+
/** Shading pattern, present iff filled with one (EP16c). */
|
|
43
85
|
readonly gradient?: ShapeGradient;
|
|
86
|
+
/** Stroke colour (6-hex), present iff the path is stroked (`S` / `s` / `B` / `b`) — EP11. */
|
|
44
87
|
readonly strokeHex?: string;
|
|
88
|
+
/** Stroke width in page-space points — EP11. */
|
|
45
89
|
readonly lineWidth?: number;
|
|
46
90
|
readonly mcid?: number;
|
|
47
91
|
}
|
|
92
|
+
/** Everything {@link interpretContent} extracts from one page's content stream. */
|
|
48
93
|
export interface InterpretResult {
|
|
49
94
|
readonly texts: Array<TextRun>;
|
|
50
95
|
readonly images: Array<ImagePlacement>;
|
|
51
96
|
readonly vectors: Array<VectorPlacement>;
|
|
52
97
|
}
|
|
98
|
+
/**
|
|
99
|
+
* 2D affine matrix `[a b c d e f]`, row-vector convention (`[x y 1] · M`):
|
|
100
|
+
* ```
|
|
101
|
+
* ⎡a b 0⎤
|
|
102
|
+
* ⎢c d 0⎥
|
|
103
|
+
* ⎣e f 1⎦
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
53
106
|
export type Matrix = readonly [number, number, number, number, number, number];
|
|
107
|
+
/** The identity {@link Matrix} (no transform). */
|
|
54
108
|
export declare const IDENTITY: Matrix;
|
|
109
|
+
/** Compose two {@link Matrix matrices}: `a` applied first, then `b`. */
|
|
55
110
|
export declare function multiply(a: Matrix, b: Matrix): Matrix;
|
|
111
|
+
/**
|
|
112
|
+
* Walk a page's decoded content stream (§9.4) and extract its positioned text,
|
|
113
|
+
* painted XObjects and painted paths. Tracks the graphics state (CTM via
|
|
114
|
+
* `q`/`Q`/`cm`) and text state (text/line matrices, font, size, spacing), and
|
|
115
|
+
* emits one {@link TextRun} per show operator (`Tj` / `TJ` / `'` / `"`) in page
|
|
116
|
+
* space (points).
|
|
117
|
+
*
|
|
118
|
+
* @param bytes The page's decoded content-stream bytes.
|
|
119
|
+
* @param fonts Page fonts by resource key (`Tf` name), for decoding + widths;
|
|
120
|
+
* an unmapped key falls back to Latin-1 with a half-em advance.
|
|
121
|
+
* @param initialCtm The starting CTM mapping user space to page space.
|
|
122
|
+
* @param shadings Shading patterns by name, selected by `scn`/`sc` (EP16c).
|
|
123
|
+
* @returns The extracted text runs, image placements and vector paths.
|
|
124
|
+
*/
|
|
56
125
|
export declare function interpretContent(bytes: Uint8Array, fonts: ReadonlyMap<string, ContentFont>, initialCtm?: Matrix, shadings?: ReadonlyMap<string, ShapeGradient>): InterpretResult;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { PDF_NULL, PdfHexString, PdfName } from "../pdf/objects.js";
|
|
2
2
|
import { Lexer } from "./lexer.js";
|
|
3
3
|
//#region src/pdf-reader/content.ts
|
|
4
|
+
/** The identity {@link Matrix} (no transform). */
|
|
4
5
|
var IDENTITY = [
|
|
5
6
|
1,
|
|
6
7
|
0,
|
|
@@ -9,6 +10,7 @@ var IDENTITY = [
|
|
|
9
10
|
0,
|
|
10
11
|
0
|
|
11
12
|
];
|
|
13
|
+
/** Compose two {@link Matrix matrices}: `a` applied first, then `b`. */
|
|
12
14
|
function multiply(a, b) {
|
|
13
15
|
return [
|
|
14
16
|
a[0] * b[0] + a[1] * b[2],
|
|
@@ -51,6 +53,20 @@ function initialState() {
|
|
|
51
53
|
fillGradient: void 0
|
|
52
54
|
};
|
|
53
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* Walk a page's decoded content stream (§9.4) and extract its positioned text,
|
|
58
|
+
* painted XObjects and painted paths. Tracks the graphics state (CTM via
|
|
59
|
+
* `q`/`Q`/`cm`) and text state (text/line matrices, font, size, spacing), and
|
|
60
|
+
* emits one {@link TextRun} per show operator (`Tj` / `TJ` / `'` / `"`) in page
|
|
61
|
+
* space (points).
|
|
62
|
+
*
|
|
63
|
+
* @param bytes The page's decoded content-stream bytes.
|
|
64
|
+
* @param fonts Page fonts by resource key (`Tf` name), for decoding + widths;
|
|
65
|
+
* an unmapped key falls back to Latin-1 with a half-em advance.
|
|
66
|
+
* @param initialCtm The starting CTM mapping user space to page space.
|
|
67
|
+
* @param shadings Shading patterns by name, selected by `scn`/`sc` (EP16c).
|
|
68
|
+
* @returns The extracted text runs, image placements and vector paths.
|
|
69
|
+
*/
|
|
54
70
|
function interpretContent(bytes, fonts, initialCtm = IDENTITY, shadings = /* @__PURE__ */ new Map()) {
|
|
55
71
|
const runs = [];
|
|
56
72
|
const images = [];
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RC4 stream cipher (§7.6.2). Symmetric, so the same call both encrypts and
|
|
3
|
+
* decrypts; used by the legacy V1/V2/V4 Standard security handlers.
|
|
4
|
+
*/
|
|
1
5
|
export declare function rc4(key: Uint8Array, data: Uint8Array): Uint8Array;
|
|
6
|
+
/** MD5 digest (RFC 1321) → 16 bytes; the key-derivation hash for V1/V2/V4. */
|
|
2
7
|
export declare function md5(input: Uint8Array): Uint8Array;
|
|
3
8
|
export declare function sha256(input: Uint8Array): Uint8Array;
|
|
4
9
|
export declare function sha512(input: Uint8Array): Uint8Array;
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
//#region src/pdf-reader/crypto.ts
|
|
2
|
+
/**
|
|
3
|
+
* RC4 stream cipher (§7.6.2). Symmetric, so the same call both encrypts and
|
|
4
|
+
* decrypts; used by the legacy V1/V2/V4 Standard security handlers.
|
|
5
|
+
*/
|
|
2
6
|
function rc4(key, data) {
|
|
3
7
|
const s = new Uint8Array(256);
|
|
4
8
|
for (let i = 0; i < 256; i++) s[i] = i;
|
|
@@ -85,6 +89,7 @@ var MD5_S = [
|
|
|
85
89
|
21
|
|
86
90
|
];
|
|
87
91
|
var MD5_K = Array.from({ length: 64 }, (_, i) => Math.floor(Math.abs(Math.sin(i + 1)) * 4294967296));
|
|
92
|
+
/** MD5 digest (RFC 1321) → 16 bytes; the key-derivation hash for V1/V2/V4. */
|
|
88
93
|
function md5(input) {
|
|
89
94
|
const len = input.length;
|
|
90
95
|
const withOne = (len + 8 >> 6) + 1;
|
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
import { PdfDict, PdfValue } from '../pdf/objects.js';
|
|
2
|
+
/** Decrypts the strings and streams of an encrypted PDF, per indirect object. */
|
|
2
3
|
export interface Decryptor {
|
|
4
|
+
/**
|
|
5
|
+
* Decrypt one value with its owning object's number and generation (which seed
|
|
6
|
+
* the per-object key). Recurses into arrays and dictionaries.
|
|
7
|
+
*/
|
|
3
8
|
decrypt: (value: PdfValue, objNum: number, gen: number) => PdfValue;
|
|
4
9
|
}
|
|
10
|
+
/**
|
|
11
|
+
* Build a {@link Decryptor} from the `/Encrypt` dictionary and the file `/ID`
|
|
12
|
+
* (ISO 32000 §7.6.3 / ISO 32000-2 §7.6.4). Derives the file key for the
|
|
13
|
+
* handler's revision — R6/V5 via `/UE` (AES-256), else the legacy MD5 key — and
|
|
14
|
+
* picks the cipher (RC4, AES-128 `/AESV2`, AES-256 `/AESV3`).
|
|
15
|
+
*
|
|
16
|
+
* @param encrypt The `/Encrypt` dictionary.
|
|
17
|
+
* @param idArray The trailer `/ID` array (its first element seeds the legacy key).
|
|
18
|
+
* @param password The user password (EP14); the empty string opens permissions-only encryption.
|
|
19
|
+
* @returns A decryptor, or `undefined` for a non-Standard filter, an unencrypting
|
|
20
|
+
* crypt filter, or a password that fails key validation.
|
|
21
|
+
*/
|
|
5
22
|
export declare function buildDecryptor(encrypt: PdfDict, idArray: PdfValue | undefined, password?: string): Decryptor | undefined;
|
|
@@ -43,6 +43,18 @@ var AES_SALT = Uint8Array.from([
|
|
|
43
43
|
]);
|
|
44
44
|
var ZERO16 = new Uint8Array(16);
|
|
45
45
|
var EMPTY = new Uint8Array(0);
|
|
46
|
+
/**
|
|
47
|
+
* Build a {@link Decryptor} from the `/Encrypt` dictionary and the file `/ID`
|
|
48
|
+
* (ISO 32000 §7.6.3 / ISO 32000-2 §7.6.4). Derives the file key for the
|
|
49
|
+
* handler's revision — R6/V5 via `/UE` (AES-256), else the legacy MD5 key — and
|
|
50
|
+
* picks the cipher (RC4, AES-128 `/AESV2`, AES-256 `/AESV3`).
|
|
51
|
+
*
|
|
52
|
+
* @param encrypt The `/Encrypt` dictionary.
|
|
53
|
+
* @param idArray The trailer `/ID` array (its first element seeds the legacy key).
|
|
54
|
+
* @param password The user password (EP14); the empty string opens permissions-only encryption.
|
|
55
|
+
* @returns A decryptor, or `undefined` for a non-Standard filter, an unencrypting
|
|
56
|
+
* crypt filter, or a password that fails key validation.
|
|
57
|
+
*/
|
|
46
58
|
function buildDecryptor(encrypt, idArray, password = "") {
|
|
47
59
|
const filter = encrypt.get("Filter");
|
|
48
60
|
if (!(filter instanceof PdfName) || filter.value !== "Standard") return void 0;
|
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
import { PdfArray, PdfDict, PdfValue, PdfStream } from '../pdf/objects.js';
|
|
2
|
+
/** A PDF rectangle `[llx, lly, urx, ury]` in default user-space units (§7.9.5). */
|
|
2
3
|
export type Rectangle = readonly [number, number, number, number];
|
|
4
|
+
/** A resolved leaf page: its dictionary plus its inherited `/MediaBox` and `/Resources`. */
|
|
3
5
|
export interface PdfPage {
|
|
4
6
|
readonly dict: PdfDict;
|
|
5
7
|
readonly mediaBox: Rectangle;
|
|
6
8
|
readonly resources: PdfDict | undefined;
|
|
7
9
|
}
|
|
10
|
+
/**
|
|
11
|
+
* The document layer (E-PDF EP1/EP7): wraps a whole PDF byte buffer and exposes
|
|
12
|
+
* its objects — the cross-reference table (classic `xref` + `trailer` and
|
|
13
|
+
* cross-reference streams), cached indirect-reference resolution (including
|
|
14
|
+
* objects packed inside object streams), the page tree (walked with attribute
|
|
15
|
+
* inheritance), and stream decoding (FlateDecode + predictors). A brute-force
|
|
16
|
+
* object scan recovers files whose xref is broken. Construct via {@link PdfFile.parse}.
|
|
17
|
+
*/
|
|
8
18
|
export declare class PdfFile {
|
|
9
19
|
private readonly buf;
|
|
10
20
|
private readonly xref;
|
|
@@ -14,17 +24,60 @@ export declare class PdfFile {
|
|
|
14
24
|
private decryptor;
|
|
15
25
|
private encryptObjNum;
|
|
16
26
|
private constructor();
|
|
27
|
+
/**
|
|
28
|
+
* Parse a whole PDF byte buffer: read the cross-reference chain (or brute-force
|
|
29
|
+
* recover a broken one) and initialize decryption from `/Encrypt` (§7.6).
|
|
30
|
+
*
|
|
31
|
+
* @param bytes The complete PDF file bytes.
|
|
32
|
+
* @param password The user password for an encrypted source (EP14); the empty
|
|
33
|
+
* string opens permissions-only encryption.
|
|
34
|
+
* @returns A ready-to-query {@link PdfFile}.
|
|
35
|
+
*/
|
|
17
36
|
static parse(bytes: Uint8Array, password?: string): PdfFile;
|
|
37
|
+
/**
|
|
38
|
+
* Build the decryptor from `/Encrypt` (§7.6). Runs before any other object is
|
|
39
|
+
* resolved, so the `/Encrypt` dictionary itself is read in the clear; its object
|
|
40
|
+
* is then never decrypted.
|
|
41
|
+
*/
|
|
18
42
|
private initEncryption;
|
|
43
|
+
/** Resolve a stream's `/Length` when it is an indirect reference. */
|
|
19
44
|
private readonly lengthResolver;
|
|
45
|
+
/**
|
|
46
|
+
* Dereference one level: a `PdfRef` becomes the object it points at (parsed and
|
|
47
|
+
* cached); any other value is returned unchanged. Decrypts each resolved
|
|
48
|
+
* string/stream (§7.6) except the `/Encrypt` dictionary itself, and guards
|
|
49
|
+
* against self-referential cycles.
|
|
50
|
+
*/
|
|
20
51
|
resolve(value: PdfValue): PdfValue;
|
|
52
|
+
/** Decode (once) the members of an object stream (§7.5.7) and return objNum → value. */
|
|
21
53
|
private objectFromStream;
|
|
54
|
+
/** Resolve `dict[key]` in one step (look up then dereference). */
|
|
22
55
|
get(dict: PdfDict, key: string): PdfValue;
|
|
56
|
+
/** The document catalog (`/Root`), or an empty dict when it cannot be resolved. */
|
|
23
57
|
get catalog(): PdfDict;
|
|
58
|
+
/**
|
|
59
|
+
* The document is encrypted but no decryptor could be built (an unsupported
|
|
60
|
+
* handler, or a wrong/missing user password) — its content is unreadable.
|
|
61
|
+
*/
|
|
24
62
|
get encryptionUnsupported(): boolean;
|
|
63
|
+
/** The leaf pages, in document order, each with its inherited `/MediaBox` and `/Resources`. */
|
|
25
64
|
pages(): Array<PdfPage>;
|
|
65
|
+
/**
|
|
66
|
+
* Recurse the `/Pages` tree, accumulating leaf pages into `out` with inherited
|
|
67
|
+
* `/MediaBox` and `/Resources`. Bounded by `MAX_PAGES` and a `seen` set (cycle
|
|
68
|
+
* guard).
|
|
69
|
+
*/
|
|
26
70
|
private walkPageTree;
|
|
71
|
+
/**
|
|
72
|
+
* A page's concatenated, decoded content stream bytes (`/Contents` may be a
|
|
73
|
+
* single stream or an array of streams joined with a separator, per §7.8.2).
|
|
74
|
+
*/
|
|
27
75
|
pageContent(page: PdfPage): Uint8Array;
|
|
76
|
+
/**
|
|
77
|
+
* Decode a stream's bytes, applying its `/Filter` chain (FlateDecode + any
|
|
78
|
+
* `/Predictor` supported; unknown filters pass through undecoded).
|
|
79
|
+
*/
|
|
28
80
|
streamData(stream: PdfStream): Uint8Array;
|
|
29
81
|
}
|
|
82
|
+
/** Re-export for callers that walk a resolved dict's array values. */
|
|
30
83
|
export type { PdfArray };
|
|
@@ -13,6 +13,14 @@ var DEFAULT_MEDIA_BOX = [
|
|
|
13
13
|
];
|
|
14
14
|
var MAX_PAGES = 5e4;
|
|
15
15
|
var MAX_OBJSTM_N = 2e5;
|
|
16
|
+
/**
|
|
17
|
+
* The document layer (E-PDF EP1/EP7): wraps a whole PDF byte buffer and exposes
|
|
18
|
+
* its objects — the cross-reference table (classic `xref` + `trailer` and
|
|
19
|
+
* cross-reference streams), cached indirect-reference resolution (including
|
|
20
|
+
* objects packed inside object streams), the page tree (walked with attribute
|
|
21
|
+
* inheritance), and stream decoding (FlateDecode + predictors). A brute-force
|
|
22
|
+
* object scan recovers files whose xref is broken. Construct via {@link PdfFile.parse}.
|
|
23
|
+
*/
|
|
16
24
|
var PdfFile = class PdfFile {
|
|
17
25
|
cache = /* @__PURE__ */ new Map();
|
|
18
26
|
objStmCache = /* @__PURE__ */ new Map();
|
|
@@ -23,6 +31,15 @@ var PdfFile = class PdfFile {
|
|
|
23
31
|
this.xref = xref;
|
|
24
32
|
this.trailer = trailer;
|
|
25
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* Parse a whole PDF byte buffer: read the cross-reference chain (or brute-force
|
|
36
|
+
* recover a broken one) and initialize decryption from `/Encrypt` (§7.6).
|
|
37
|
+
*
|
|
38
|
+
* @param bytes The complete PDF file bytes.
|
|
39
|
+
* @param password The user password for an encrypted source (EP14); the empty
|
|
40
|
+
* string opens permissions-only encryption.
|
|
41
|
+
* @returns A ready-to-query {@link PdfFile}.
|
|
42
|
+
*/
|
|
26
43
|
static parse(bytes, password = "") {
|
|
27
44
|
let xref = /* @__PURE__ */ new Map();
|
|
28
45
|
let trailer = /* @__PURE__ */ new Map();
|
|
@@ -46,6 +63,11 @@ var PdfFile = class PdfFile {
|
|
|
46
63
|
file.initEncryption(password);
|
|
47
64
|
return file;
|
|
48
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* Build the decryptor from `/Encrypt` (§7.6). Runs before any other object is
|
|
68
|
+
* resolved, so the `/Encrypt` dictionary itself is read in the clear; its object
|
|
69
|
+
* is then never decrypted.
|
|
70
|
+
*/
|
|
49
71
|
initEncryption(password) {
|
|
50
72
|
const encVal = this.trailer.get("Encrypt");
|
|
51
73
|
if (encVal === void 0) return;
|
|
@@ -55,10 +77,17 @@ var PdfFile = class PdfFile {
|
|
|
55
77
|
const id = this.trailer.get("ID");
|
|
56
78
|
this.decryptor = buildDecryptor(enc, Array.isArray(id) ? id : void 0, password);
|
|
57
79
|
}
|
|
80
|
+
/** Resolve a stream's `/Length` when it is an indirect reference. */
|
|
58
81
|
lengthResolver = (r) => {
|
|
59
82
|
const n = this.resolve(r);
|
|
60
83
|
return typeof n === "number" ? n : void 0;
|
|
61
84
|
};
|
|
85
|
+
/**
|
|
86
|
+
* Dereference one level: a `PdfRef` becomes the object it points at (parsed and
|
|
87
|
+
* cached); any other value is returned unchanged. Decrypts each resolved
|
|
88
|
+
* string/stream (§7.6) except the `/Encrypt` dictionary itself, and guards
|
|
89
|
+
* against self-referential cycles.
|
|
90
|
+
*/
|
|
62
91
|
resolve(value) {
|
|
63
92
|
if (!(value instanceof PdfRef)) return value;
|
|
64
93
|
const cached = this.cache.get(value.id);
|
|
@@ -77,6 +106,7 @@ var PdfFile = class PdfFile {
|
|
|
77
106
|
this.cache.set(value.id, result);
|
|
78
107
|
return result;
|
|
79
108
|
}
|
|
109
|
+
/** Decode (once) the members of an object stream (§7.5.7) and return objNum → value. */
|
|
80
110
|
objectFromStream(streamObj) {
|
|
81
111
|
const cached = this.objStmCache.get(streamObj);
|
|
82
112
|
if (cached) return cached;
|
|
@@ -96,22 +126,34 @@ var PdfFile = class PdfFile {
|
|
|
96
126
|
for (const member of objStmHeader(data, numOf(this.resolve(stream.dict.get("N") ?? PDF_NULL)))) out.set(member.id, parseObject(new Lexer(data, first + member.off), this.lengthResolver));
|
|
97
127
|
return out;
|
|
98
128
|
}
|
|
129
|
+
/** Resolve `dict[key]` in one step (look up then dereference). */
|
|
99
130
|
get(dict, key) {
|
|
100
131
|
return this.resolve(dict.get(key) ?? PDF_NULL);
|
|
101
132
|
}
|
|
133
|
+
/** The document catalog (`/Root`), or an empty dict when it cannot be resolved. */
|
|
102
134
|
get catalog() {
|
|
103
135
|
const root = this.resolve(this.trailer.get("Root") ?? PDF_NULL);
|
|
104
136
|
return root instanceof Map ? root : /* @__PURE__ */ new Map();
|
|
105
137
|
}
|
|
138
|
+
/**
|
|
139
|
+
* The document is encrypted but no decryptor could be built (an unsupported
|
|
140
|
+
* handler, or a wrong/missing user password) — its content is unreadable.
|
|
141
|
+
*/
|
|
106
142
|
get encryptionUnsupported() {
|
|
107
143
|
return this.trailer.get("Encrypt") !== void 0 && this.decryptor === void 0;
|
|
108
144
|
}
|
|
145
|
+
/** The leaf pages, in document order, each with its inherited `/MediaBox` and `/Resources`. */
|
|
109
146
|
pages() {
|
|
110
147
|
const out = [];
|
|
111
148
|
const root = this.get(this.catalog, "Pages");
|
|
112
149
|
if (root instanceof Map) this.walkPageTree(root, {}, out, /* @__PURE__ */ new Set());
|
|
113
150
|
return out;
|
|
114
151
|
}
|
|
152
|
+
/**
|
|
153
|
+
* Recurse the `/Pages` tree, accumulating leaf pages into `out` with inherited
|
|
154
|
+
* `/MediaBox` and `/Resources`. Bounded by `MAX_PAGES` and a `seen` set (cycle
|
|
155
|
+
* guard).
|
|
156
|
+
*/
|
|
115
157
|
walkPageTree(node, inherited, out, seen) {
|
|
116
158
|
if (out.length >= MAX_PAGES || seen.has(node)) return;
|
|
117
159
|
seen.add(node);
|
|
@@ -137,6 +179,10 @@ var PdfFile = class PdfFile {
|
|
|
137
179
|
resources
|
|
138
180
|
});
|
|
139
181
|
}
|
|
182
|
+
/**
|
|
183
|
+
* A page's concatenated, decoded content stream bytes (`/Contents` may be a
|
|
184
|
+
* single stream or an array of streams joined with a separator, per §7.8.2).
|
|
185
|
+
*/
|
|
140
186
|
pageContent(page) {
|
|
141
187
|
const contents = this.get(page.dict, "Contents");
|
|
142
188
|
const streams = [];
|
|
@@ -147,6 +193,10 @@ var PdfFile = class PdfFile {
|
|
|
147
193
|
}
|
|
148
194
|
return concatWithSpaces(streams.map((s) => this.streamData(s)));
|
|
149
195
|
}
|
|
196
|
+
/**
|
|
197
|
+
* Decode a stream's bytes, applying its `/Filter` chain (FlateDecode + any
|
|
198
|
+
* `/Predictor` supported; unknown filters pass through undecoded).
|
|
199
|
+
*/
|
|
150
200
|
streamData(stream) {
|
|
151
201
|
let data = stream.data;
|
|
152
202
|
const filter = this.resolve(stream.dict.get("Filter") ?? PDF_NULL);
|
|
@@ -4,18 +4,65 @@ import { Loss, ResourceStore } from '../core/ir/index.js';
|
|
|
4
4
|
import { PdfImage } from './images.js';
|
|
5
5
|
import { PdfPage } from './document.js';
|
|
6
6
|
import { PdfVector } from './vector.js';
|
|
7
|
+
/**
|
|
8
|
+
* A reconstruction's document plus the losses incurred reading it (e.g. an
|
|
9
|
+
* undecodable image colour space) — surfaced through the reader's `LossReport`.
|
|
10
|
+
*/
|
|
7
11
|
export interface Reconstruction {
|
|
8
12
|
readonly doc: FlowDoc;
|
|
9
13
|
readonly losses: ReadonlyArray<Loss>;
|
|
10
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* Build a paragraph {@link BodyElement} from a single plain-text string,
|
|
17
|
+
* optionally at the given outline (heading) level. Empty text yields a
|
|
18
|
+
* paragraph with no runs. The link-free counterpart of {@link paragraphFromRuns}.
|
|
19
|
+
*/
|
|
11
20
|
export declare function paragraphBlock(text: string, outlineLevel?: number): BodyElement;
|
|
21
|
+
/** One piece of reconstructed text, carrying any hyperlink (E-PDF EP8). */
|
|
12
22
|
export interface TextSpan {
|
|
13
23
|
readonly text: string;
|
|
14
24
|
readonly href?: string;
|
|
15
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* Build a paragraph {@link BodyElement} from positioned {@link TextSpan}s,
|
|
28
|
+
* coalescing consecutive spans that share an `href` into one run (so a link
|
|
29
|
+
* survives as its own run) and squashing whitespace. With no hrefs this
|
|
30
|
+
* collapses to a single run — the same shape {@link paragraphBlock} produces.
|
|
31
|
+
*/
|
|
16
32
|
export declare function paragraphFromRuns(spans: ReadonlyArray<TextSpan>, outlineLevel?: number): BodyElement;
|
|
33
|
+
/**
|
|
34
|
+
* Store a {@link PdfImage}'s bytes (content-addressed dedup) and build the image
|
|
35
|
+
* {@link BodyElement} that references them, sized in points from the placement
|
|
36
|
+
* CTM. `alt` becomes the block's alt text when given.
|
|
37
|
+
*/
|
|
17
38
|
export declare function imageBlock(image: PdfImage, resources: ResourceStore, alt?: string): BodyElement;
|
|
39
|
+
/** Collapse losses sharing a `detail` message (the same colour space dropped on many pages). */
|
|
18
40
|
export declare function dedupeLosses(losses: ReadonlyArray<Loss>): Array<Loss>;
|
|
41
|
+
/**
|
|
42
|
+
* Turn a lifted {@link PdfVector} path (filled EP10 / stroked EP11) into a
|
|
43
|
+
* custom-geometry shape {@link BodyElement}. Page-space points (y-up) become
|
|
44
|
+
* path-space (bbox-relative, y-down); the shape is sized from the bounding box
|
|
45
|
+
* (plus the stroke thickness) and placed in flow order by the caller. A fill
|
|
46
|
+
* becomes a solid fill, a stroke becomes the outline.
|
|
47
|
+
*/
|
|
19
48
|
export declare function shapeBlock(v: PdfVector): BodyElement;
|
|
49
|
+
/**
|
|
50
|
+
* Derive the {@link SectionProperties} geometry from the source pages so a
|
|
51
|
+
* reconstructed PDF re-renders at its real page size and orientation rather than
|
|
52
|
+
* the layout engine's `A4` default — without it an `A3` source paginates onto
|
|
53
|
+
* several `A4` pages, a wide/landscape page is letterboxed, and so on. PDF
|
|
54
|
+
* user-space units are points, matching `Pt`, so the `MediaBox` extents map
|
|
55
|
+
* straight to the page size. Uses the first {@link PdfPage}'s box (the
|
|
56
|
+
* near-universal uniform-size case); a PDF whose pages differ in size reflows to
|
|
57
|
+
* this single geometry — a known approximation, still far better than a fixed
|
|
58
|
+
* `A4`. Returns `undefined` when there is no usable first-page box.
|
|
59
|
+
*/
|
|
20
60
|
export declare function sectionFromPdfPages(pages: ReadonlyArray<PdfPage>): SectionProperties | undefined;
|
|
61
|
+
/**
|
|
62
|
+
* Assemble the final {@link FlowDoc} for a reconstruction: the body elements
|
|
63
|
+
* with their styles resolved against the empty style sheet, the lifted-image
|
|
64
|
+
* resource store, and the optional page {@link SectionProperties}. Shared by
|
|
65
|
+
* both reconstruction paths (the tagged fast-path EP3 and the heuristic layout
|
|
66
|
+
* path EP4).
|
|
67
|
+
*/
|
|
21
68
|
export declare function buildFlowDoc(body: ReadonlyArray<BodyElement>, resources?: ResourceStore, section?: SectionProperties): FlowDoc;
|
|
@@ -3,6 +3,11 @@ import { ResourceStore } from "../core/ir/resources.js";
|
|
|
3
3
|
import { EMPTY_STYLE_SHEET, resolveBodyStyles } from "../core/style-cascade/resolver.js";
|
|
4
4
|
import "../core/style-cascade/index.js";
|
|
5
5
|
//#region src/pdf-reader/flow-build.ts
|
|
6
|
+
/**
|
|
7
|
+
* Build a paragraph {@link BodyElement} from a single plain-text string,
|
|
8
|
+
* optionally at the given outline (heading) level. Empty text yields a
|
|
9
|
+
* paragraph with no runs. The link-free counterpart of {@link paragraphFromRuns}.
|
|
10
|
+
*/
|
|
6
11
|
function paragraphBlock(text, outlineLevel) {
|
|
7
12
|
return {
|
|
8
13
|
kind: "paragraph",
|
|
@@ -15,6 +20,12 @@ function paragraphBlock(text, outlineLevel) {
|
|
|
15
20
|
}
|
|
16
21
|
};
|
|
17
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* Build a paragraph {@link BodyElement} from positioned {@link TextSpan}s,
|
|
25
|
+
* coalescing consecutive spans that share an `href` into one run (so a link
|
|
26
|
+
* survives as its own run) and squashing whitespace. With no hrefs this
|
|
27
|
+
* collapses to a single run — the same shape {@link paragraphBlock} produces.
|
|
28
|
+
*/
|
|
18
29
|
function paragraphFromRuns(spans, outlineLevel) {
|
|
19
30
|
const merged = [];
|
|
20
31
|
for (const s of spans) {
|
|
@@ -46,6 +57,11 @@ function paragraphFromRuns(spans, outlineLevel) {
|
|
|
46
57
|
}
|
|
47
58
|
};
|
|
48
59
|
}
|
|
60
|
+
/**
|
|
61
|
+
* Store a {@link PdfImage}'s bytes (content-addressed dedup) and build the image
|
|
62
|
+
* {@link BodyElement} that references them, sized in points from the placement
|
|
63
|
+
* CTM. `alt` becomes the block's alt text when given.
|
|
64
|
+
*/
|
|
49
65
|
function imageBlock(image, resources, alt) {
|
|
50
66
|
return {
|
|
51
67
|
kind: "image",
|
|
@@ -58,11 +74,19 @@ function imageBlock(image, resources, alt) {
|
|
|
58
74
|
}
|
|
59
75
|
};
|
|
60
76
|
}
|
|
77
|
+
/** Collapse losses sharing a `detail` message (the same colour space dropped on many pages). */
|
|
61
78
|
function dedupeLosses(losses) {
|
|
62
79
|
const byDetail = /* @__PURE__ */ new Map();
|
|
63
80
|
for (const loss of losses) if (!byDetail.has(loss.detail)) byDetail.set(loss.detail, loss);
|
|
64
81
|
return [...byDetail.values()];
|
|
65
82
|
}
|
|
83
|
+
/**
|
|
84
|
+
* Turn a lifted {@link PdfVector} path (filled EP10 / stroked EP11) into a
|
|
85
|
+
* custom-geometry shape {@link BodyElement}. Page-space points (y-up) become
|
|
86
|
+
* path-space (bbox-relative, y-down); the shape is sized from the bounding box
|
|
87
|
+
* (plus the stroke thickness) and placed in flow order by the caller. A fill
|
|
88
|
+
* becomes a solid fill, a stroke becomes the outline.
|
|
89
|
+
*/
|
|
66
90
|
function shapeBlock(v) {
|
|
67
91
|
const w = v.maxX - v.minX;
|
|
68
92
|
const h = v.maxY - v.minY;
|
|
@@ -124,6 +148,17 @@ function shapeBlock(v) {
|
|
|
124
148
|
}
|
|
125
149
|
};
|
|
126
150
|
}
|
|
151
|
+
/**
|
|
152
|
+
* Derive the {@link SectionProperties} geometry from the source pages so a
|
|
153
|
+
* reconstructed PDF re-renders at its real page size and orientation rather than
|
|
154
|
+
* the layout engine's `A4` default — without it an `A3` source paginates onto
|
|
155
|
+
* several `A4` pages, a wide/landscape page is letterboxed, and so on. PDF
|
|
156
|
+
* user-space units are points, matching `Pt`, so the `MediaBox` extents map
|
|
157
|
+
* straight to the page size. Uses the first {@link PdfPage}'s box (the
|
|
158
|
+
* near-universal uniform-size case); a PDF whose pages differ in size reflows to
|
|
159
|
+
* this single geometry — a known approximation, still far better than a fixed
|
|
160
|
+
* `A4`. Returns `undefined` when there is no usable first-page box.
|
|
161
|
+
*/
|
|
127
162
|
function sectionFromPdfPages(pages) {
|
|
128
163
|
const box = pages[0]?.mediaBox;
|
|
129
164
|
if (!box) return void 0;
|
|
@@ -146,6 +181,13 @@ function sectionFromPdfPages(pages) {
|
|
|
146
181
|
footers: []
|
|
147
182
|
};
|
|
148
183
|
}
|
|
184
|
+
/**
|
|
185
|
+
* Assemble the final {@link FlowDoc} for a reconstruction: the body elements
|
|
186
|
+
* with their styles resolved against the empty style sheet, the lifted-image
|
|
187
|
+
* resource store, and the optional page {@link SectionProperties}. Shared by
|
|
188
|
+
* both reconstruction paths (the tagged fast-path EP3 and the heuristic layout
|
|
189
|
+
* path EP4).
|
|
190
|
+
*/
|
|
149
191
|
function buildFlowDoc(body, resources = new ResourceStore(), section) {
|
|
150
192
|
return {
|
|
151
193
|
kind: "flow",
|
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
import { PdfDict } from '../pdf/objects.js';
|
|
2
2
|
import { ContentFont } from './content.js';
|
|
3
3
|
import { PdfFile } from './document.js';
|
|
4
|
+
/**
|
|
5
|
+
* Build a {@link ContentFont} (the interpreter's decode + advance hooks) from a
|
|
6
|
+
* `/Font` dictionary (E-PDF EP2). Unicode comes from the `/ToUnicode` CMap;
|
|
7
|
+
* glyph advances from a simple font's `/Widths` (§9.6.2.1) or a composite
|
|
8
|
+
* `/Type0` font's descendant `/W` array (§9.7.4.3). A code with no `/ToUnicode`
|
|
9
|
+
* entry decodes to its Latin-1 character for a simple font, or to nothing for a
|
|
10
|
+
* composite one.
|
|
11
|
+
*
|
|
12
|
+
* @param file The owning {@link PdfFile}, used to resolve indirect references.
|
|
13
|
+
* @param fontDict The `/Font` dictionary.
|
|
14
|
+
* @returns The decode/advance hooks plus the code width (1 or 2 bytes per code).
|
|
15
|
+
*/
|
|
4
16
|
export declare function buildContentFont(file: PdfFile, fontDict: PdfDict): ContentFont;
|
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
import { PDF_NULL, PdfName, PdfStream } from "../pdf/objects.js";
|
|
2
2
|
import { parseToUnicodeCMap } from "./cmap.js";
|
|
3
3
|
//#region src/pdf-reader/font.ts
|
|
4
|
+
/**
|
|
5
|
+
* Build a {@link ContentFont} (the interpreter's decode + advance hooks) from a
|
|
6
|
+
* `/Font` dictionary (E-PDF EP2). Unicode comes from the `/ToUnicode` CMap;
|
|
7
|
+
* glyph advances from a simple font's `/Widths` (§9.6.2.1) or a composite
|
|
8
|
+
* `/Type0` font's descendant `/W` array (§9.7.4.3). A code with no `/ToUnicode`
|
|
9
|
+
* entry decodes to its Latin-1 character for a simple font, or to nothing for a
|
|
10
|
+
* composite one.
|
|
11
|
+
*
|
|
12
|
+
* @param file The owning {@link PdfFile}, used to resolve indirect references.
|
|
13
|
+
* @param fontDict The `/Font` dictionary.
|
|
14
|
+
* @returns The decode/advance hooks plus the code width (1 or 2 bytes per code).
|
|
15
|
+
*/
|
|
4
16
|
function buildContentFont(file, fontDict) {
|
|
5
17
|
const isType0 = asName(file.resolve(fontDict.get("Subtype") ?? PDF_NULL)) === "Type0";
|
|
6
18
|
let toUnicode = /* @__PURE__ */ new Map();
|