@jasy/pdf 1.0.0-alpha.2 → 1.0.0-alpha.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/README.md +3 -3
- 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 +60 -13
- package/dist/api/structure.js +132 -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 +6 -0
- package/dist/assets/font-data.ts +7 -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/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 +83 -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 +80 -0
- package/dist/utils/pdf-object-manager.d.ts +10 -6
- package/dist/utils/pdf-object-manager.js +89 -94
- 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,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,85 @@
|
|
|
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
|
-
objectManager.finalizeCustomFonts();
|
|
85
|
-
// Add rendered objects
|
|
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
|
+
// Add rendered objects
|
|
78
|
+
pdfContent += objectManager.getRenderedObjects();
|
|
79
|
+
// Add XRef table and trailer
|
|
80
|
+
const startxref = pdfContent.length;
|
|
81
|
+
pdfContent += objectManager.getXRefTable();
|
|
82
|
+
pdfContent += objectManager.getTrailerAndXRef(startxref);
|
|
83
|
+
return pdfContent;
|
|
93
84
|
}
|
|
94
85
|
}
|
|
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;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { PDFObjectManager } from "../utils/pdf-object-manager";
|
|
2
|
-
import { RectangleElement } from "../elements/rectangle-element";
|
|
3
|
-
import { IRNode } from "../ir/display-list";
|
|
1
|
+
import { PDFObjectManager } from "../utils/pdf-object-manager.js";
|
|
2
|
+
import { RectangleElement } from "../elements/rectangle-element.js";
|
|
3
|
+
import { IRNode } from "../ir/display-list.js";
|
|
4
4
|
export declare class RectangleRenderer {
|
|
5
5
|
static render(rectangleElement: RectangleElement, objectManager: PDFObjectManager): Promise<IRNode[]>;
|
|
6
6
|
/** One `line` node per present side, along the box edges (top-left coordinates). */
|
|
@@ -1,56 +1,50 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
exports.RectangleRenderer = void 0;
|
|
13
|
-
const renderer_registry_1 = require("../utils/renderer-registry");
|
|
14
|
-
class RectangleRenderer {
|
|
15
|
-
static render(rectangleElement, objectManager) {
|
|
16
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
17
|
-
const { x, y, width, height, children, color, backgroundColor, borderWidth, radius, sideBorders, overflow, } = rectangleElement.getProps();
|
|
18
|
-
const h = height;
|
|
19
|
-
const nodes = [];
|
|
20
|
-
if (sideBorders) {
|
|
21
|
-
// Per-side borders: a fill-only box (no stroke), then a line per present side
|
|
22
|
-
// (sharp corners). This is what lets cells draw grid lines.
|
|
23
|
-
if (backgroundColor) {
|
|
24
|
-
nodes.push({ type: "rect", x, y, width, height: h, strokeWidth: 0, fill: backgroundColor });
|
|
25
|
-
}
|
|
26
|
-
nodes.push(...RectangleRenderer.sideLines(x, y, width, h, borderWidth, sideBorders));
|
|
27
|
-
}
|
|
28
|
-
else {
|
|
29
|
-
// The box itself becomes a display-list primitive. A background means a filled box;
|
|
30
|
-
// otherwise it is stroked only. (Unchanged path - byte-identical.)
|
|
31
|
-
const node = Object.assign(Object.assign({ type: "rect", x,
|
|
32
|
-
y,
|
|
33
|
-
width, height: h, stroke: color, strokeWidth: borderWidth }, (backgroundColor ? { fill: backgroundColor } : {})), (radius ? { radius } : {}));
|
|
34
|
-
nodes.push(node);
|
|
1
|
+
import { RendererRegistry } from "../utils/renderer-registry.js";
|
|
2
|
+
export class RectangleRenderer {
|
|
3
|
+
static async render(rectangleElement, objectManager) {
|
|
4
|
+
const { x, y, width, height, children, color, backgroundColor, borderWidth, radius, sideBorders, overflow, } = rectangleElement.getProps();
|
|
5
|
+
const h = height;
|
|
6
|
+
const nodes = [];
|
|
7
|
+
if (sideBorders) {
|
|
8
|
+
// Per-side borders: a fill-only box (no stroke), then a line per present side
|
|
9
|
+
// (sharp corners). This is what lets cells draw grid lines.
|
|
10
|
+
if (backgroundColor) {
|
|
11
|
+
nodes.push({ type: "rect", x, y, width, height: h, strokeWidth: 0, fill: backgroundColor });
|
|
35
12
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
13
|
+
nodes.push(...RectangleRenderer.sideLines(x, y, width, h, borderWidth, sideBorders));
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
// The box itself becomes a display-list primitive. A background means a filled box;
|
|
17
|
+
// otherwise it is stroked only. (Unchanged path - byte-identical.)
|
|
18
|
+
const node = {
|
|
19
|
+
type: "rect",
|
|
20
|
+
x,
|
|
21
|
+
y,
|
|
22
|
+
width,
|
|
23
|
+
height: h,
|
|
24
|
+
stroke: color,
|
|
25
|
+
strokeWidth: borderWidth,
|
|
26
|
+
...(backgroundColor ? { fill: backgroundColor } : {}),
|
|
27
|
+
...(radius ? { radius } : {}),
|
|
28
|
+
};
|
|
29
|
+
nodes.push(node);
|
|
30
|
+
}
|
|
31
|
+
// Children follow the box (Rectangle is also a container). With overflow: "hidden" they are
|
|
32
|
+
// wrapped in a clip to the (rounded) box rect, so a Positioned child is cropped at the edge
|
|
33
|
+
// instead of spilling over. Default "visible" emits no clip - byte-identical.
|
|
34
|
+
const clip = overflow === "hidden";
|
|
35
|
+
if (clip) {
|
|
36
|
+
nodes.push({ type: "clip-push", x, y, width, height: h, ...(radius ? { radius } : {}) });
|
|
37
|
+
}
|
|
38
|
+
if (children)
|
|
39
|
+
for (const child of children) {
|
|
40
|
+
const renderer = RendererRegistry.getRenderer(child);
|
|
41
|
+
if (renderer) {
|
|
42
|
+
nodes.push(...(await renderer(child, objectManager)));
|
|
49
43
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
44
|
+
}
|
|
45
|
+
if (clip)
|
|
46
|
+
nodes.push({ type: "clip-pop" });
|
|
47
|
+
return nodes;
|
|
54
48
|
}
|
|
55
49
|
/** One `line` node per present side, along the box edges (top-left coordinates). */
|
|
56
50
|
static sideLines(x, y, width, height, strokeWidth, sides) {
|
|
@@ -66,4 +60,3 @@ class RectangleRenderer {
|
|
|
66
60
|
return lines;
|
|
67
61
|
}
|
|
68
62
|
}
|
|
69
|
-
exports.RectangleRenderer = RectangleRenderer;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { PDFObjectManager } from "../utils/pdf-object-manager";
|
|
2
|
-
import { RepeatingHeaderElement } from "../elements/layout/repeating-header-element";
|
|
3
|
-
import { IRNode } from "../ir/display-list";
|
|
1
|
+
import { PDFObjectManager } from "../utils/pdf-object-manager.js";
|
|
2
|
+
import { RepeatingHeaderElement } from "../elements/layout/repeating-header-element.js";
|
|
3
|
+
import { IRNode } from "../ir/display-list.js";
|
|
4
4
|
export declare class RepeatingHeaderRenderer {
|
|
5
5
|
static render(element: RepeatingHeaderElement, objectManager: PDFObjectManager): Promise<IRNode[]>;
|
|
6
6
|
}
|
|
@@ -1,28 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
exports.RepeatingHeaderRenderer = void 0;
|
|
13
|
-
const renderer_registry_1 = require("../utils/renderer-registry");
|
|
14
|
-
class RepeatingHeaderRenderer {
|
|
15
|
-
static render(element, objectManager) {
|
|
16
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
17
|
-
const { header, body } = element.getProps();
|
|
18
|
-
const nodes = [];
|
|
19
|
-
for (const child of [header, body]) {
|
|
20
|
-
const renderer = renderer_registry_1.RendererRegistry.getRenderer(child);
|
|
21
|
-
if (renderer)
|
|
22
|
-
nodes.push(...(yield renderer(child, objectManager)));
|
|
23
|
-
}
|
|
24
|
-
return nodes;
|
|
25
|
-
});
|
|
1
|
+
import { RendererRegistry } from "../utils/renderer-registry.js";
|
|
2
|
+
export class RepeatingHeaderRenderer {
|
|
3
|
+
static async render(element, objectManager) {
|
|
4
|
+
const { header, body } = element.getProps();
|
|
5
|
+
const nodes = [];
|
|
6
|
+
for (const child of [header, body]) {
|
|
7
|
+
const renderer = RendererRegistry.getRenderer(child);
|
|
8
|
+
if (renderer)
|
|
9
|
+
nodes.push(...(await renderer(child, objectManager)));
|
|
10
|
+
}
|
|
11
|
+
return nodes;
|
|
26
12
|
}
|
|
27
13
|
}
|
|
28
|
-
exports.RepeatingHeaderRenderer = RepeatingHeaderRenderer;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { PDFObjectManager } from "../utils/pdf-object-manager";
|
|
2
|
-
import { RowElement } from "../elements/row-element";
|
|
3
|
-
import { IRNode } from "../ir/display-list";
|
|
1
|
+
import { PDFObjectManager } from "../utils/pdf-object-manager.js";
|
|
2
|
+
import { RowElement } from "../elements/row-element.js";
|
|
3
|
+
import { IRNode } from "../ir/display-list.js";
|
|
4
4
|
export declare class RowRenderer {
|
|
5
5
|
static render(rowElement: RowElement, objectManager: PDFObjectManager): Promise<IRNode[]>;
|
|
6
6
|
}
|