@jasy/pdf 1.0.0-alpha.2 → 1.0.0-alpha.4
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/LICENSE +21 -0
- package/README.md +24 -14
- package/dist/api/args.d.ts +1 -1
- package/dist/api/args.js +2 -5
- package/dist/api/color.d.ts +4 -4
- package/dist/api/color.js +11 -17
- package/dist/api/content.d.ts +8 -8
- package/dist/api/content.js +23 -24
- package/dist/api/descriptor.d.ts +2 -2
- package/dist/api/descriptor.js +75 -31
- package/dist/api/index.d.ts +8 -8
- package/dist/api/index.js +8 -24
- package/dist/api/insets.js +4 -8
- package/dist/api/layout.d.ts +18 -16
- package/dist/api/layout.js +41 -52
- package/dist/api/structure.d.ts +65 -13
- package/dist/api/structure.js +140 -88
- package/dist/api/table.d.ts +5 -5
- package/dist/api/table.js +28 -24
- package/dist/api/text.d.ts +27 -2
- package/dist/api/text.js +45 -27
- package/dist/assets/font-data.d.ts +2 -0
- package/dist/assets/font-data.js +21 -0
- package/dist/assets/font-data.ts +37 -0
- package/dist/common/color.js +1 -5
- package/dist/constants/page-sizes.js +3 -6
- package/dist/constants/pdf-parts.js +1 -4
- package/dist/crypto/security-handler.d.ts +46 -0
- package/dist/crypto/security-handler.js +129 -0
- package/dist/crypto/webcrypto.d.ts +11 -0
- package/dist/crypto/webcrypto.js +62 -0
- package/dist/elements/container-element.d.ts +4 -4
- package/dist/elements/container-element.js +9 -13
- package/dist/elements/image-element.d.ts +18 -2
- package/dist/elements/image-element.js +81 -105
- package/dist/elements/index.d.ts +12 -11
- package/dist/elements/index.js +12 -29
- package/dist/elements/layout/default-text-style-element.d.ts +30 -0
- package/dist/elements/layout/default-text-style-element.js +47 -0
- package/dist/elements/layout/deferred-element.d.ts +3 -3
- package/dist/elements/layout/deferred-element.js +4 -8
- package/dist/elements/layout/expanded-element.d.ts +3 -3
- package/dist/elements/layout/expanded-element.js +10 -14
- package/dist/elements/layout/padding-element.d.ts +3 -3
- package/dist/elements/layout/padding-element.js +9 -14
- package/dist/elements/layout/positioned-element.d.ts +17 -4
- package/dist/elements/layout/positioned-element.js +29 -25
- package/dist/elements/layout/repeating-header-element.d.ts +3 -3
- package/dist/elements/layout/repeating-header-element.js +8 -12
- package/dist/elements/layout/sized-container-element.d.ts +2 -2
- package/dist/elements/layout/sized-container-element.js +6 -11
- package/dist/elements/line-element.d.ts +3 -3
- package/dist/elements/line-element.js +5 -10
- package/dist/elements/page-element.d.ts +8 -6
- package/dist/elements/page-element.js +20 -23
- package/dist/elements/pdf-document-element.d.ts +10 -4
- package/dist/elements/pdf-document-element.js +11 -10
- package/dist/elements/pdf-element.d.ts +12 -3
- package/dist/elements/pdf-element.js +10 -19
- package/dist/elements/rectangle-element.d.ts +5 -5
- package/dist/elements/rectangle-element.js +19 -25
- package/dist/elements/row-element.d.ts +3 -3
- package/dist/elements/row-element.js +7 -11
- package/dist/elements/text-element.d.ts +37 -11
- package/dist/elements/text-element.js +64 -39
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -19
- package/dist/ir/display-list.d.ts +4 -2
- package/dist/ir/display-list.js +1 -2
- package/dist/layout/box-constraints.js +2 -6
- package/dist/layout/fragmentation.d.ts +8 -1
- package/dist/layout/fragmentation.js +22 -10
- package/dist/platform/browser-fs.d.ts +2 -0
- package/dist/platform/browser-fs.js +9 -0
- package/dist/platform/browser-image.d.ts +5 -0
- package/dist/platform/browser-image.js +13 -0
- package/dist/platform/node-fs.d.ts +2 -0
- package/dist/platform/node-fs.js +10 -0
- package/dist/platform/node-image.d.ts +5 -0
- package/dist/platform/node-image.js +9 -0
- package/dist/renderer/container-renderer.d.ts +3 -3
- package/dist/renderer/container-renderer.js +12 -27
- package/dist/renderer/default-text-style-renderer.d.ts +6 -0
- package/dist/renderer/default-text-style-renderer.js +10 -0
- package/dist/renderer/deferred-renderer.d.ts +3 -3
- package/dist/renderer/deferred-renderer.js +8 -23
- package/dist/renderer/expanded-renderer.d.ts +3 -3
- package/dist/renderer/expanded-renderer.js +6 -21
- package/dist/renderer/image-renderer.d.ts +3 -3
- package/dist/renderer/image-renderer.js +77 -75
- package/dist/renderer/index.d.ts +10 -10
- package/dist/renderer/index.js +10 -26
- package/dist/renderer/line-renderer.d.ts +3 -3
- package/dist/renderer/line-renderer.js +13 -28
- package/dist/renderer/padding-renderer.d.ts +3 -3
- package/dist/renderer/padding-renderer.js +6 -21
- package/dist/renderer/page-renderer.d.ts +2 -2
- package/dist/renderer/page-renderer.js +61 -77
- package/dist/renderer/pdf-backend.d.ts +2 -2
- package/dist/renderer/pdf-backend.js +21 -19
- package/dist/renderer/pdf-config.js +4 -7
- package/dist/renderer/pdf-document-class.d.ts +5 -5
- package/dist/renderer/pdf-document-class.js +24 -41
- package/dist/renderer/pdf-document-renderer.d.ts +3 -3
- package/dist/renderer/pdf-document-renderer.js +71 -85
- package/dist/renderer/pdf-renderer.d.ts +2 -2
- package/dist/renderer/pdf-renderer.js +85 -93
- package/dist/renderer/positioned-renderer.d.ts +3 -3
- package/dist/renderer/positioned-renderer.js +8 -23
- package/dist/renderer/rectangle-renderer.d.ts +3 -3
- package/dist/renderer/rectangle-renderer.js +45 -52
- package/dist/renderer/repeating-header-renderer.d.ts +3 -3
- package/dist/renderer/repeating-header-renderer.js +11 -26
- package/dist/renderer/row-renderer.d.ts +3 -3
- package/dist/renderer/row-renderer.js +12 -27
- package/dist/renderer/text-renderer.d.ts +6 -5
- package/dist/renderer/text-renderer.js +33 -42
- package/dist/text/line-breaker.d.ts +8 -5
- package/dist/text/line-breaker.js +67 -16
- package/dist/text/text-style.d.ts +25 -0
- package/dist/text/text-style.js +29 -0
- package/dist/utils/afm-parser.js +3 -13
- package/dist/utils/bytes.d.ts +24 -0
- package/dist/utils/bytes.js +76 -0
- package/dist/utils/flex-layout.d.ts +2 -2
- package/dist/utils/flex-layout.js +15 -20
- package/dist/utils/font-metrics.d.ts +1 -1
- package/dist/utils/font-metrics.js +1 -2
- package/dist/utils/font-path.js +3 -6
- package/dist/utils/image-helper.d.ts +6 -5
- package/dist/utils/image-helper.js +101 -111
- package/dist/utils/md5.d.ts +4 -0
- package/dist/utils/md5.js +79 -0
- package/dist/utils/pdf-object-manager.d.ts +18 -6
- package/dist/utils/pdf-object-manager.js +0 -0
- package/dist/utils/renderer-registry.js +1 -5
- package/dist/utils/ttf-parser.d.ts +2 -2
- package/dist/utils/ttf-parser.js +32 -36
- package/dist/utils/ttf-subsetter.d.ts +1 -1
- package/dist/utils/ttf-subsetter.js +40 -42
- package/dist/utils/utf8-to-windows1252-encoder.js +1 -4
- package/dist/validators/element-validator.d.ts +2 -2
- package/dist/validators/element-validator.js +9 -13
- package/package.json +14 -2
|
@@ -1,17 +1,14 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
// Leaf module: no imports, so it can never sit inside an import cycle. The page/color
|
|
3
2
|
// enums live here because they are runtime values used across modules that DO form
|
|
4
3
|
// cycles (object manager <-> document <-> elements); importing them from a cyclic
|
|
5
4
|
// module snapshots them as `undefined` under some load orders.
|
|
6
|
-
|
|
7
|
-
exports.ColorMode = exports.Orientation = void 0;
|
|
8
|
-
var Orientation;
|
|
5
|
+
export var Orientation;
|
|
9
6
|
(function (Orientation) {
|
|
10
7
|
Orientation["portrait"] = "PORTRAIT";
|
|
11
8
|
Orientation["landscape"] = "LANDSCAPE";
|
|
12
|
-
})(Orientation || (
|
|
13
|
-
var ColorMode;
|
|
9
|
+
})(Orientation || (Orientation = {}));
|
|
10
|
+
export var ColorMode;
|
|
14
11
|
(function (ColorMode) {
|
|
15
12
|
ColorMode["color"] = "COLOR";
|
|
16
13
|
ColorMode["grayscale"] = "GRAYSCALE";
|
|
17
|
-
})(ColorMode || (
|
|
14
|
+
})(ColorMode || (ColorMode = {}));
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { PageSize } from "../constants/page-sizes";
|
|
2
|
-
import { PDFDocumentElement } from "../elements";
|
|
3
|
-
import { FontStyle, PDFObjectManager } from "../utils/pdf-object-manager";
|
|
4
|
-
import { ColorMode, Orientation } from "./pdf-config";
|
|
5
|
-
export { ColorMode, Orientation } from "./pdf-config";
|
|
1
|
+
import { PageSize } from "../constants/page-sizes.js";
|
|
2
|
+
import { PDFDocumentElement } from "../elements/index.js";
|
|
3
|
+
import { FontStyle, PDFObjectManager } from "../utils/pdf-object-manager.js";
|
|
4
|
+
import { ColorMode, Orientation } from "./pdf-config.js";
|
|
5
|
+
export { ColorMode, Orientation } from "./pdf-config.js";
|
|
6
6
|
export interface Margin {
|
|
7
7
|
left: number;
|
|
8
8
|
top: number;
|
|
@@ -1,90 +1,76 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.PDFDocument = exports.Orientation = exports.ColorMode = void 0;
|
|
13
|
-
const pdf_object_manager_1 = require("../utils/pdf-object-manager");
|
|
14
|
-
const pdf_renderer_1 = require("./pdf-renderer");
|
|
1
|
+
import { FontStyle, PDFObjectManager } from "../utils/pdf-object-manager.js";
|
|
2
|
+
import { PDFRenderer } from "./pdf-renderer.js";
|
|
15
3
|
// Re-exported so existing `../renderer` consumers keep importing these from here.
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
Object.defineProperty(exports, "Orientation", { enumerable: true, get: function () { return pdf_config_1.Orientation; } });
|
|
19
|
-
class PDFDocument {
|
|
4
|
+
export { ColorMode, Orientation } from "./pdf-config.js";
|
|
5
|
+
export class PDFDocument {
|
|
20
6
|
//#region Helper
|
|
21
7
|
// Method to register all standard fonts
|
|
22
8
|
registerStandardFonts(objectManager) {
|
|
23
9
|
const standardFonts = [
|
|
24
10
|
{
|
|
25
11
|
fontName: "Helvetica",
|
|
26
|
-
fontStyle:
|
|
12
|
+
fontStyle: FontStyle.Normal,
|
|
27
13
|
fullName: "Helvetica",
|
|
28
14
|
},
|
|
29
15
|
{
|
|
30
16
|
fontName: "Helvetica",
|
|
31
|
-
fontStyle:
|
|
17
|
+
fontStyle: FontStyle.Bold,
|
|
32
18
|
fullName: "Helvetica-Bold",
|
|
33
19
|
},
|
|
34
20
|
{
|
|
35
21
|
fontName: "Helvetica",
|
|
36
|
-
fontStyle:
|
|
22
|
+
fontStyle: FontStyle.Italic,
|
|
37
23
|
fullName: "Helvetica-Oblique",
|
|
38
24
|
},
|
|
39
25
|
{
|
|
40
26
|
fontName: "Helvetica",
|
|
41
|
-
fontStyle:
|
|
27
|
+
fontStyle: FontStyle.BoldItalic,
|
|
42
28
|
fullName: "Helvetica-BoldOblique",
|
|
43
29
|
},
|
|
44
|
-
{ fontName: "Courier", fontStyle:
|
|
30
|
+
{ fontName: "Courier", fontStyle: FontStyle.Normal, fullName: "Courier" },
|
|
45
31
|
{
|
|
46
32
|
fontName: "Courier",
|
|
47
|
-
fontStyle:
|
|
33
|
+
fontStyle: FontStyle.Bold,
|
|
48
34
|
fullName: "Courier-Bold",
|
|
49
35
|
},
|
|
50
36
|
{
|
|
51
37
|
fontName: "Courier",
|
|
52
|
-
fontStyle:
|
|
38
|
+
fontStyle: FontStyle.Italic,
|
|
53
39
|
fullName: "Courier-Oblique",
|
|
54
40
|
},
|
|
55
41
|
{
|
|
56
42
|
fontName: "Courier",
|
|
57
|
-
fontStyle:
|
|
43
|
+
fontStyle: FontStyle.BoldItalic,
|
|
58
44
|
fullName: "Courier-BoldOblique",
|
|
59
45
|
},
|
|
60
46
|
{
|
|
61
47
|
fontName: "Times-Roman",
|
|
62
|
-
fontStyle:
|
|
48
|
+
fontStyle: FontStyle.Normal,
|
|
63
49
|
fullName: "Times-Roman",
|
|
64
50
|
},
|
|
65
51
|
{
|
|
66
52
|
fontName: "Times-Roman",
|
|
67
|
-
fontStyle:
|
|
53
|
+
fontStyle: FontStyle.Bold,
|
|
68
54
|
fullName: "Times-Bold",
|
|
69
55
|
},
|
|
70
56
|
{
|
|
71
57
|
fontName: "Times-Roman",
|
|
72
|
-
fontStyle:
|
|
58
|
+
fontStyle: FontStyle.Italic,
|
|
73
59
|
fullName: "Times-Italic",
|
|
74
60
|
},
|
|
75
61
|
{
|
|
76
62
|
fontName: "Times-Roman",
|
|
77
|
-
fontStyle:
|
|
63
|
+
fontStyle: FontStyle.BoldItalic,
|
|
78
64
|
fullName: "Times-BoldItalic",
|
|
79
65
|
},
|
|
80
66
|
{
|
|
81
67
|
fontName: "Symbol",
|
|
82
|
-
fontStyle:
|
|
68
|
+
fontStyle: FontStyle.Normal,
|
|
83
69
|
fullName: "Symbol",
|
|
84
70
|
},
|
|
85
71
|
{
|
|
86
72
|
fontName: "ITC Zapf Dingbats",
|
|
87
|
-
fontStyle:
|
|
73
|
+
fontStyle: FontStyle.Normal,
|
|
88
74
|
fullName: "ZapfDingbats",
|
|
89
75
|
},
|
|
90
76
|
];
|
|
@@ -94,10 +80,10 @@ class PDFDocument {
|
|
|
94
80
|
constructor(config) {
|
|
95
81
|
// One object manager per document instance - no global singleton. Threaded
|
|
96
82
|
// explicitly into the renderer.
|
|
97
|
-
this._objectManager = new
|
|
83
|
+
this._objectManager = new PDFObjectManager();
|
|
98
84
|
// Add all standard font families - unless the document is PDF/A, which forbids non-embedded
|
|
99
85
|
// fonts (the caller then supplies embedded fonts for every name it uses).
|
|
100
|
-
if (
|
|
86
|
+
if (config?.registerStandardFonts !== false) {
|
|
101
87
|
this.registerStandardFonts(this._objectManager);
|
|
102
88
|
}
|
|
103
89
|
if (config)
|
|
@@ -107,12 +93,9 @@ class PDFDocument {
|
|
|
107
93
|
return this._objectManager;
|
|
108
94
|
}
|
|
109
95
|
beforeRenderer() { }
|
|
110
|
-
static render() {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
return yield pdf_renderer_1.PDFRenderer.render(instance.child, instance._objectManager);
|
|
115
|
-
});
|
|
96
|
+
static async render() {
|
|
97
|
+
const instance = new this();
|
|
98
|
+
instance.child = instance.build();
|
|
99
|
+
return await PDFRenderer.render(instance.child, instance._objectManager);
|
|
116
100
|
}
|
|
117
101
|
}
|
|
118
|
-
exports.PDFDocument = PDFDocument;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { PDFDocumentElement } from "../elements/pdf-document-element";
|
|
2
|
-
import { LayoutContext } from "../elements/pdf-element";
|
|
3
|
-
import { PDFObjectManager } from "../utils/pdf-object-manager";
|
|
1
|
+
import { PDFDocumentElement } from "../elements/pdf-document-element.js";
|
|
2
|
+
import { LayoutContext } from "../elements/pdf-element.js";
|
|
3
|
+
import { PDFObjectManager } from "../utils/pdf-object-manager.js";
|
|
4
4
|
export declare class PDFDocumentRenderer {
|
|
5
5
|
static render(document: PDFDocumentElement, objectManager: PDFObjectManager, ctx: LayoutContext): Promise<number>;
|
|
6
6
|
/**
|
|
@@ -1,43 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
// The page driver: each logical PageElement may produce SEVERAL physical PDF pages
|
|
28
|
-
// when its content overflows (Slice 0: whole children reflow to the next page).
|
|
29
|
-
for (let page of document.getProps().children) {
|
|
30
|
-
const numbers = yield PDFDocumentRenderer.renderLogicalPage(page, objectManager, ctx);
|
|
31
|
-
pageNumbers.push(...numbers);
|
|
32
|
-
}
|
|
33
|
-
// We must update the pages object with the real physical page numbers and count.
|
|
34
|
-
const updatedPagesObject = `<< /Type /Pages /Kids [${pageNumbers
|
|
35
|
-
.map((num) => `${num} 0 R`)
|
|
36
|
-
.join(" ")}] /Count ${pageNumbers.length} >>`;
|
|
37
|
-
// Now we must replace it in the object manager
|
|
38
|
-
objectManager.replaceObject(pagesObjectNumber, updatedPagesObject);
|
|
39
|
-
return pagesObjectNumber;
|
|
40
|
-
});
|
|
1
|
+
import { layoutPageBands, PageElement } from "../elements/page-element.js";
|
|
2
|
+
import { BoxConstraints } from "../layout/box-constraints.js";
|
|
3
|
+
import { isFragmentable } from "../layout/fragmentation.js";
|
|
4
|
+
import { PageRenderer } from "./page-renderer.js";
|
|
5
|
+
export class PDFDocumentRenderer {
|
|
6
|
+
static async render(document, objectManager, ctx) {
|
|
7
|
+
const pageNumbers = [];
|
|
8
|
+
// Add the pages object first... we need its object number (resources). The count is
|
|
9
|
+
// a placeholder; it is replaced below with the real (post-pagination) page count.
|
|
10
|
+
const pagesObject = `<< /Type /Pages /Kids [] /Count ${document.getProps().children.length} >>`;
|
|
11
|
+
const pagesObjectNumber = objectManager.addObject(pagesObject);
|
|
12
|
+
// Now set the given object number all its childs
|
|
13
|
+
objectManager.setParentObjectNumber(pagesObjectNumber);
|
|
14
|
+
// The page driver: each logical PageElement may produce SEVERAL physical PDF pages
|
|
15
|
+
// when its content overflows (Slice 0: whole children reflow to the next page).
|
|
16
|
+
for (let page of document.getProps().children) {
|
|
17
|
+
const numbers = await PDFDocumentRenderer.renderLogicalPage(page, objectManager, ctx);
|
|
18
|
+
pageNumbers.push(...numbers);
|
|
19
|
+
}
|
|
20
|
+
// We must update the pages object with the real physical page numbers and count.
|
|
21
|
+
const updatedPagesObject = `<< /Type /Pages /Kids [${pageNumbers
|
|
22
|
+
.map((num) => `${num} 0 R`)
|
|
23
|
+
.join(" ")}] /Count ${pageNumbers.length} >>`;
|
|
24
|
+
// Now we must replace it in the object manager
|
|
25
|
+
objectManager.replaceObject(pagesObjectNumber, updatedPagesObject);
|
|
26
|
+
return pagesObjectNumber;
|
|
41
27
|
}
|
|
42
28
|
/**
|
|
43
29
|
* Renders one logical page, paginating it into one or more physical pages.
|
|
@@ -46,59 +32,59 @@ class PDFDocumentRenderer {
|
|
|
46
32
|
* fragmentation context (a Container). Anything else renders as a single page on the
|
|
47
33
|
* unchanged path, so non-overflowing documents stay byte-identical to pre-Slice-0.
|
|
48
34
|
*/
|
|
49
|
-
static renderLogicalPage(page, objectManager, ctx) {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
35
|
+
static async renderLogicalPage(page, objectManager, ctx) {
|
|
36
|
+
const { children, config, header, footer } = page.getProps();
|
|
37
|
+
if (children.length !== 1 || !isFragmentable(children[0])) {
|
|
38
|
+
return [await PageRenderer.render(page, objectManager)];
|
|
39
|
+
}
|
|
40
|
+
// Header/footer repeat on every physical page, so the body only ever flows into the
|
|
41
|
+
// band between them. Resolve that band once (config is already merged by pass 1).
|
|
42
|
+
const pageCtx = {
|
|
43
|
+
metrics: ctx.metrics,
|
|
44
|
+
pageConfig: config,
|
|
45
|
+
textStyle: ctx.textStyle,
|
|
46
|
+
onOverflow: ctx.onOverflow,
|
|
47
|
+
};
|
|
48
|
+
const { bodyWidth: width, bodyHeight: height } = layoutPageBands(config, header, footer, pageCtx);
|
|
49
|
+
const numbers = [];
|
|
50
|
+
let region = children[0];
|
|
51
|
+
let isFirstRegion = true;
|
|
52
|
+
while (region) {
|
|
53
|
+
if (!isFragmentable(region)) {
|
|
54
|
+
// A non-fragmentable remainder is placed whole on its own page.
|
|
55
|
+
numbers.push(await PDFDocumentRenderer.renderPhysicalPage(config, region, header, footer, objectManager, ctx));
|
|
56
|
+
break;
|
|
54
57
|
}
|
|
55
|
-
|
|
56
|
-
//
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
if (!(0, fragmentation_1.isFragmentable)(region)) {
|
|
64
|
-
// A non-fragmentable remainder is placed whole on its own page.
|
|
65
|
-
numbers.push(yield PDFDocumentRenderer.renderPhysicalPage(config, region, header, footer, objectManager, ctx));
|
|
66
|
-
break;
|
|
67
|
-
}
|
|
68
|
-
const { fitted, remainder } = region.fragment(height, width, ctx);
|
|
69
|
-
// Everything fits on one page: render the ORIGINAL page so output is unchanged.
|
|
70
|
-
// Measuring inside fragment() laid the children out at the origin to size them, so
|
|
71
|
-
// re-run the page layout first to restore their real positions (deterministic).
|
|
72
|
-
if (isFirstRegion && remainder === null) {
|
|
73
|
-
page.calculateLayout(new box_constraints_1.BoxConstraints(), { x: 0, y: 0 }, ctx);
|
|
74
|
-
numbers.push(yield page_renderer_1.PageRenderer.render(page, objectManager));
|
|
75
|
-
break;
|
|
76
|
-
}
|
|
77
|
-
if (fitted) {
|
|
78
|
-
numbers.push(yield PDFDocumentRenderer.renderPhysicalPage(config, fitted, header, footer, objectManager, ctx));
|
|
79
|
-
}
|
|
80
|
-
region = remainder;
|
|
81
|
-
isFirstRegion = false;
|
|
58
|
+
const { fitted, remainder } = region.fragment(height, width, ctx);
|
|
59
|
+
// Everything fits on one page: render the ORIGINAL page so output is unchanged.
|
|
60
|
+
// Measuring inside fragment() laid the children out at the origin to size them, so
|
|
61
|
+
// re-run the page layout first to restore their real positions (deterministic).
|
|
62
|
+
if (isFirstRegion && remainder === null) {
|
|
63
|
+
page.calculateLayout(new BoxConstraints(), { x: 0, y: 0 }, ctx);
|
|
64
|
+
numbers.push(await PageRenderer.render(page, objectManager));
|
|
65
|
+
break;
|
|
82
66
|
}
|
|
83
|
-
|
|
84
|
-
|
|
67
|
+
if (fitted) {
|
|
68
|
+
numbers.push(await PDFDocumentRenderer.renderPhysicalPage(config, fitted, header, footer, objectManager, ctx));
|
|
69
|
+
}
|
|
70
|
+
region = remainder;
|
|
71
|
+
isFirstRegion = false;
|
|
72
|
+
}
|
|
73
|
+
return numbers;
|
|
85
74
|
}
|
|
86
75
|
/**
|
|
87
76
|
* Lays out one fragment on a fresh page of the same geometry and renders it. The
|
|
88
77
|
* header/footer are attached to every physical page so they repeat; `PageElement`
|
|
89
78
|
* re-places them and the body in the band between.
|
|
90
79
|
*/
|
|
91
|
-
static renderPhysicalPage(config, content, header, footer, objectManager, ctx) {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
children: [content],
|
|
98
|
-
});
|
|
99
|
-
physicalPage.calculateLayout(new box_constraints_1.BoxConstraints(), { x: 0, y: 0 }, ctx);
|
|
100
|
-
return page_renderer_1.PageRenderer.render(physicalPage, objectManager);
|
|
80
|
+
static async renderPhysicalPage(config, content, header, footer, objectManager, ctx) {
|
|
81
|
+
const physicalPage = new PageElement({
|
|
82
|
+
config,
|
|
83
|
+
header,
|
|
84
|
+
footer,
|
|
85
|
+
children: [content],
|
|
101
86
|
});
|
|
87
|
+
physicalPage.calculateLayout(new BoxConstraints(), { x: 0, y: 0 }, ctx);
|
|
88
|
+
return PageRenderer.render(physicalPage, objectManager);
|
|
102
89
|
}
|
|
103
90
|
}
|
|
104
|
-
exports.PDFDocumentRenderer = PDFDocumentRenderer;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { PDFDocumentElement } from "../elements/pdf-document-element";
|
|
2
|
-
import { PDFObjectManager } from "../utils/pdf-object-manager";
|
|
1
|
+
import { PDFDocumentElement } from "../elements/pdf-document-element.js";
|
|
2
|
+
import { PDFObjectManager } from "../utils/pdf-object-manager.js";
|
|
3
3
|
export declare class PDFRenderer {
|
|
4
4
|
static render(document: PDFDocumentElement, objectManager: PDFObjectManager): Promise<string>;
|
|
5
5
|
}
|
|
@@ -1,95 +1,87 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
pdfContent += objectManager.getRenderedObjects();
|
|
87
|
-
// Add XRef table and trailer
|
|
88
|
-
const startxref = pdfContent.length;
|
|
89
|
-
pdfContent += objectManager.getXRefTable();
|
|
90
|
-
pdfContent += objectManager.getTrailerAndXRef(startxref);
|
|
91
|
-
return pdfContent;
|
|
92
|
-
});
|
|
1
|
+
import { PDFDocumentRenderer } from "./pdf-document-renderer.js";
|
|
2
|
+
import { RendererRegistry } from "../utils/renderer-registry.js";
|
|
3
|
+
import { DefaultTextStyleElement, ExpandedElement, ImageElement, LineElement, PaddingElement, TextElement, } from "../elements/index.js";
|
|
4
|
+
import { TextRenderer } from "./text-renderer.js";
|
|
5
|
+
import { ContainerElement } from "../elements/container-element.js";
|
|
6
|
+
import { RectangleElement } from "../elements/rectangle-element.js";
|
|
7
|
+
import { RowElement } from "../elements/row-element.js";
|
|
8
|
+
import { ContainerRenderer } from "./container-renderer.js";
|
|
9
|
+
import { RectangleRenderer } from "./rectangle-renderer.js";
|
|
10
|
+
import { RowRenderer } from "./row-renderer.js";
|
|
11
|
+
import { ExpandedRenderer } from "./expanded-renderer.js";
|
|
12
|
+
import { PaddingRenderer } from "./padding-renderer.js";
|
|
13
|
+
import { DefaultTextStyleRenderer } from "./default-text-style-renderer.js";
|
|
14
|
+
import { ImageRenderer } from "./image-renderer.js";
|
|
15
|
+
import { LineRenderer } from "./line-renderer.js";
|
|
16
|
+
import { RepeatingHeaderElement } from "../elements/layout/repeating-header-element.js";
|
|
17
|
+
import { RepeatingHeaderRenderer } from "./repeating-header-renderer.js";
|
|
18
|
+
import { DeferredElement } from "../elements/layout/deferred-element.js";
|
|
19
|
+
import { DeferredRenderer } from "./deferred-renderer.js";
|
|
20
|
+
import { PositionedElement } from "../elements/layout/positioned-element.js";
|
|
21
|
+
import { PositionedRenderer } from "./positioned-renderer.js";
|
|
22
|
+
import { BoxConstraints } from "../layout/box-constraints.js";
|
|
23
|
+
import { DEFAULT_TEXT_STYLE, mergeTextStyle } from "../text/text-style.js";
|
|
24
|
+
export class PDFRenderer {
|
|
25
|
+
static async render(document, objectManager) {
|
|
26
|
+
// Register all Renderer
|
|
27
|
+
RendererRegistry.register(TextElement, TextRenderer.render);
|
|
28
|
+
RendererRegistry.register(ContainerElement, ContainerRenderer.render);
|
|
29
|
+
RendererRegistry.register(RowElement, RowRenderer.render);
|
|
30
|
+
RendererRegistry.register(RectangleElement, RectangleRenderer.render);
|
|
31
|
+
RendererRegistry.register(ExpandedElement, ExpandedRenderer.render);
|
|
32
|
+
RendererRegistry.register(PaddingElement, PaddingRenderer.render);
|
|
33
|
+
RendererRegistry.register(DefaultTextStyleElement, DefaultTextStyleRenderer.render);
|
|
34
|
+
RendererRegistry.register(ImageElement, ImageRenderer.render);
|
|
35
|
+
RendererRegistry.register(LineElement, LineRenderer.render);
|
|
36
|
+
RendererRegistry.register(RepeatingHeaderElement, RepeatingHeaderRenderer.render);
|
|
37
|
+
RendererRegistry.register(DeferredElement, DeferredRenderer.render);
|
|
38
|
+
RendererRegistry.register(PositionedElement, PositionedRenderer.render);
|
|
39
|
+
let pdfContent = "";
|
|
40
|
+
// Header: version line + the PDF/A binary marker (the object manager owns it so its length
|
|
41
|
+
// matches the xref offset calculation).
|
|
42
|
+
pdfContent += objectManager.getHeader();
|
|
43
|
+
// Layout pass: thread the context explicitly. The seed page config is the document
|
|
44
|
+
// default; each PageElement overrides it for its own subtree.
|
|
45
|
+
const ctx = {
|
|
46
|
+
metrics: objectManager,
|
|
47
|
+
pageConfig: objectManager.getPDFConfig(),
|
|
48
|
+
textStyle: mergeTextStyle(DEFAULT_TEXT_STYLE, document.getDefaultTextStyle()),
|
|
49
|
+
onOverflow: objectManager.getOverflowPolicy(),
|
|
50
|
+
};
|
|
51
|
+
document.calculateLayout(new BoxConstraints(), { x: 0, y: 0 }, ctx);
|
|
52
|
+
// Render pages and contents (the driver paginates overflowing pages).
|
|
53
|
+
await PDFDocumentRenderer.render(document, objectManager, ctx);
|
|
54
|
+
// Add the catalog. XMP metadata (/Metadata) and embedded files (/AF + /Names/EmbeddedFiles)
|
|
55
|
+
// are added only when present; with neither, the catalog is byte-identical to before.
|
|
56
|
+
const catalogParts = [`/Type /Catalog /Pages ${objectManager.getParentObjectNumber()} 0 R`];
|
|
57
|
+
const xmp = objectManager.getXmpMetadata();
|
|
58
|
+
if (xmp) {
|
|
59
|
+
const metadataObject = objectManager.addObject(`<< /Type /Metadata /Subtype /XML /Length ${xmp.length} >>\nstream\n${xmp}\nendstream`);
|
|
60
|
+
catalogParts.push(`/Metadata ${metadataObject} 0 R`);
|
|
61
|
+
}
|
|
62
|
+
const outputIntent = objectManager.getOutputIntent();
|
|
63
|
+
if (outputIntent) {
|
|
64
|
+
catalogParts.push(`/OutputIntents [${outputIntent} 0 R]`);
|
|
65
|
+
}
|
|
66
|
+
const attachments = objectManager.getAttachments();
|
|
67
|
+
if (attachments.length > 0) {
|
|
68
|
+
const names = attachments.map((a) => `(${a.name}) ${a.filespec} 0 R`).join(" ");
|
|
69
|
+
const af = attachments.map((a) => `${a.filespec} 0 R`).join(" ");
|
|
70
|
+
catalogParts.push(`/AF [${af}]`, `/Names << /EmbeddedFiles << /Names [${names}] >> >>`);
|
|
71
|
+
}
|
|
72
|
+
const catalogObject = `<< ${catalogParts.join(" ")} >>`;
|
|
73
|
+
objectManager.addObject(catalogObject);
|
|
74
|
+
// Now that the render pass has revealed which glyphs each embedded font uses, fill the reserved
|
|
75
|
+
// font objects with the subset font program (must happen before the objects are serialized).
|
|
76
|
+
objectManager.finalizeCustomFonts();
|
|
77
|
+
// Encrypt every registered stream + add the /Encrypt object (no-op unless a security handler was set).
|
|
78
|
+
await objectManager.finalizeEncryption();
|
|
79
|
+
// Add rendered objects
|
|
80
|
+
pdfContent += objectManager.getRenderedObjects();
|
|
81
|
+
// Add XRef table and trailer
|
|
82
|
+
const startxref = pdfContent.length;
|
|
83
|
+
pdfContent += objectManager.getXRefTable();
|
|
84
|
+
pdfContent += objectManager.getTrailerAndXRef(startxref);
|
|
85
|
+
return pdfContent;
|
|
93
86
|
}
|
|
94
87
|
}
|
|
95
|
-
exports.PDFRenderer = PDFRenderer;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { PDFObjectManager } from "../utils/pdf-object-manager";
|
|
2
|
-
import { PositionedElement } from "../elements/layout/positioned-element";
|
|
3
|
-
import { IRNode } from "../ir/display-list";
|
|
1
|
+
import { PDFObjectManager } from "../utils/pdf-object-manager.js";
|
|
2
|
+
import { PositionedElement } from "../elements/layout/positioned-element.js";
|
|
3
|
+
import { IRNode } from "../ir/display-list.js";
|
|
4
4
|
export declare class PositionedRenderer {
|
|
5
5
|
static render(positionedElement: PositionedElement, objectManager: PDFObjectManager): Promise<IRNode[]>;
|
|
6
6
|
}
|
|
@@ -1,25 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.PositionedRenderer = void 0;
|
|
13
|
-
const renderer_registry_1 = require("../utils/renderer-registry");
|
|
14
|
-
class PositionedRenderer {
|
|
15
|
-
static render(positionedElement, objectManager) {
|
|
16
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
17
|
-
// The child was already placed (by the frame) during layout; just emit its IR. It is drawn
|
|
18
|
-
// after the frame's flow content, so it paints on top.
|
|
19
|
-
const { child } = positionedElement.getProps();
|
|
20
|
-
const renderer = renderer_registry_1.RendererRegistry.getRenderer(child);
|
|
21
|
-
return renderer ? renderer(child, objectManager) : [];
|
|
22
|
-
});
|
|
1
|
+
import { RendererRegistry } from "../utils/renderer-registry.js";
|
|
2
|
+
export class PositionedRenderer {
|
|
3
|
+
static async render(positionedElement, objectManager) {
|
|
4
|
+
// The child was already placed (by the frame) during layout; just emit its IR. It is drawn
|
|
5
|
+
// after the frame's flow content, so it paints on top.
|
|
6
|
+
const { child } = positionedElement.getProps();
|
|
7
|
+
const renderer = RendererRegistry.getRenderer(child);
|
|
8
|
+
return renderer ? renderer(child, objectManager) : [];
|
|
23
9
|
}
|
|
24
10
|
}
|
|
25
|
-
exports.PositionedRenderer = PositionedRenderer;
|