@jasy/pdf 1.0.0-alpha.1 → 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 +27 -12
- package/dist/api/layout.js +46 -45
- 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 -10
- package/dist/elements/index.js +12 -28
- 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 +44 -0
- package/dist/elements/layout/positioned-element.js +61 -0
- 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 +31 -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 +28 -3
- package/dist/elements/pdf-element.js +10 -19
- package/dist/elements/rectangle-element.d.ts +14 -6
- package/dist/elements/rectangle-element.js +44 -21
- 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 +22 -3
- 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 +34 -17
- 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 -90
- package/dist/renderer/positioned-renderer.d.ts +6 -0
- package/dist/renderer/positioned-renderer.js +10 -0
- package/dist/renderer/rectangle-renderer.d.ts +3 -3
- package/dist/renderer/rectangle-renderer.js +45 -44
- 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 +17 -23
- package/package.json +14 -2
|
@@ -1,12 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.isFragmentable = isFragmentable;
|
|
4
|
-
exports.packChildren = packChildren;
|
|
5
|
-
const box_constraints_1 = require("./box-constraints");
|
|
6
|
-
function isFragmentable(element) {
|
|
1
|
+
import { BoxConstraints } from "./box-constraints.js";
|
|
2
|
+
export function isFragmentable(element) {
|
|
7
3
|
return ("fragment" in element &&
|
|
8
4
|
typeof element.fragment === "function");
|
|
9
5
|
}
|
|
6
|
+
function reportOverflow(child, childHeight, maxHeight, policy) {
|
|
7
|
+
if (policy === "ignore")
|
|
8
|
+
return;
|
|
9
|
+
const name = child.constructor.name.replace(/Element$/, "");
|
|
10
|
+
const detail = `${name} is ${Math.round(childHeight)}pt tall but the page region is only ` +
|
|
11
|
+
`${Math.round(maxHeight)}pt and it cannot be broken - reduce its size, give it a bounded ` +
|
|
12
|
+
`height, or let it split across pages.`;
|
|
13
|
+
if (policy === "error")
|
|
14
|
+
throw new Error(`Layout overflow: ${detail}`);
|
|
15
|
+
console.warn(`Layout overflow (clipped): ${detail}`);
|
|
16
|
+
}
|
|
10
17
|
/**
|
|
11
18
|
* Packs a vertical stack of children into `maxHeight`, in order. Children are measured
|
|
12
19
|
* against `width` (unbounded height) and added until one would overflow; that straddling
|
|
@@ -21,13 +28,13 @@ function isFragmentable(element) {
|
|
|
21
28
|
* Shared by every element that lays out a vertical stack and can split it across regions
|
|
22
29
|
* (Container, and the decorated boxes Padding/Rectangle).
|
|
23
30
|
*/
|
|
24
|
-
function packChildren(children, maxHeight, width, ctx, gap = 0) {
|
|
31
|
+
export function packChildren(children, maxHeight, width, ctx, gap = 0) {
|
|
25
32
|
const fitted = [];
|
|
26
33
|
const remainder = [];
|
|
27
34
|
let usedHeight = 0;
|
|
28
35
|
for (let i = 0; i < children.length; i++) {
|
|
29
36
|
const child = children[i];
|
|
30
|
-
const childHeight = child.calculateLayout(
|
|
37
|
+
const childHeight = child.calculateLayout(BoxConstraints.loose(width, Infinity), { x: 0, y: 0 }, ctx).height;
|
|
31
38
|
// A gap precedes every child except the first one placed in this region.
|
|
32
39
|
const lead = fitted.length > 0 ? gap : 0;
|
|
33
40
|
if (usedHeight + lead + childHeight <= maxHeight) {
|
|
@@ -48,10 +55,15 @@ function packChildren(children, maxHeight, width, ctx, gap = 0) {
|
|
|
48
55
|
}
|
|
49
56
|
}
|
|
50
57
|
if (!placedPart) {
|
|
51
|
-
if (fitted.length === 0)
|
|
58
|
+
if (fitted.length === 0) {
|
|
59
|
+
// Taller than the whole region and unsplittable: force it on (it overflows and is clipped)
|
|
60
|
+
// so the next region still advances - and surface it per the overflow policy.
|
|
61
|
+
reportOverflow(child, childHeight, maxHeight, ctx.onOverflow ?? "ignore");
|
|
52
62
|
fitted.push(child);
|
|
53
|
-
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
54
65
|
remainder.push(child);
|
|
66
|
+
}
|
|
55
67
|
}
|
|
56
68
|
for (let j = i + 1; j < children.length; j++)
|
|
57
69
|
remainder.push(children[j]);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// Browser stand-in for platform/node-fs.ts (selected by the package.json "browser" field). The browser has
|
|
2
|
+
// no file paths, so loading from one throws a clear, actionable error - pass bytes instead.
|
|
3
|
+
const hint = "needs Node. In the browser pass bytes (Uint8Array / ArrayBuffer) instead - e.g. import the file as a URL and fetch() it, or register a font from its bytes.";
|
|
4
|
+
export function readFileBytes(_path) {
|
|
5
|
+
throw new Error(`Loading a font from a file path ${hint}`);
|
|
6
|
+
}
|
|
7
|
+
export function readFileBytesAsync(_path) {
|
|
8
|
+
throw new Error(`Loading an image from a file path ${hint}`);
|
|
9
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// PNG decode in the browser: the platform's own image decoder, via an OffscreenCanvas, to raw RGBA. No
|
|
2
|
+
// jimp, no Buffer - keeps the browser bundle lean and works wherever Canvas does. The package `browser`
|
|
3
|
+
// field swaps `node-image.ts` for this module at bundle time.
|
|
4
|
+
export async function pngToRgba(bytes) {
|
|
5
|
+
const bitmap = await createImageBitmap(new Blob([new Uint8Array(bytes)], { type: "image/png" }));
|
|
6
|
+
const { width, height } = bitmap;
|
|
7
|
+
const ctx = new OffscreenCanvas(width, height).getContext("2d");
|
|
8
|
+
if (!ctx)
|
|
9
|
+
throw new Error("@jasy/pdf: no 2D canvas context available to decode the PNG.");
|
|
10
|
+
ctx.drawImage(bitmap, 0, 0);
|
|
11
|
+
bitmap.close();
|
|
12
|
+
return { width, height, rgba: new Uint8Array(ctx.getImageData(0, 0, width, height).data.buffer) };
|
|
13
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// Node implementation of the platform file reads. In a browser bundle this whole module is swapped for
|
|
2
|
+
// platform/browser-fs.ts via the package.json "browser" field, so `node:fs` never reaches the browser.
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
|
+
import { readFile } from "node:fs/promises";
|
|
5
|
+
export function readFileBytes(path) {
|
|
6
|
+
return readFileSync(path);
|
|
7
|
+
}
|
|
8
|
+
export function readFileBytesAsync(path) {
|
|
9
|
+
return readFile(path);
|
|
10
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// PNG decode on Node: jimp → raw RGBA pixels. jimp is lazy-imported (it pulls Node-ish bits in) so a
|
|
2
|
+
// text-only render never loads it. The browser swaps this whole module for `browser-image.ts` (a Canvas
|
|
3
|
+
// decode) via the package `browser` field, so neither jimp nor Buffer reach the browser bundle.
|
|
4
|
+
export async function pngToRgba(bytes) {
|
|
5
|
+
const { Jimp } = await import("jimp");
|
|
6
|
+
const image = await Jimp.fromBuffer(Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength));
|
|
7
|
+
const { width, height, data } = image.bitmap;
|
|
8
|
+
return { width, height, rgba: new Uint8Array(data.buffer, data.byteOffset, data.byteLength) };
|
|
9
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { PDFObjectManager } from "../utils/pdf-object-manager";
|
|
2
|
-
import { ContainerElement } from "../elements/container-element";
|
|
3
|
-
import { IRNode } from "../ir/display-list";
|
|
1
|
+
import { PDFObjectManager } from "../utils/pdf-object-manager.js";
|
|
2
|
+
import { ContainerElement } from "../elements/container-element.js";
|
|
3
|
+
import { IRNode } from "../ir/display-list.js";
|
|
4
4
|
export declare class ContainerRenderer {
|
|
5
5
|
static render(containerElement: ContainerElement, objectManager: PDFObjectManager): Promise<IRNode[]>;
|
|
6
6
|
}
|
|
@@ -1,30 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.ContainerRenderer = void 0;
|
|
13
|
-
const renderer_registry_1 = require("../utils/renderer-registry");
|
|
14
|
-
class ContainerRenderer {
|
|
15
|
-
static render(containerElement, objectManager) {
|
|
16
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
17
|
-
const { children } = containerElement.getProps();
|
|
18
|
-
const nodes = [];
|
|
19
|
-
if (children)
|
|
20
|
-
for (const child of children) {
|
|
21
|
-
const renderer = renderer_registry_1.RendererRegistry.getRenderer(child);
|
|
22
|
-
if (renderer) {
|
|
23
|
-
nodes.push(...(yield renderer(child, objectManager)));
|
|
24
|
-
}
|
|
1
|
+
import { RendererRegistry } from "../utils/renderer-registry.js";
|
|
2
|
+
export class ContainerRenderer {
|
|
3
|
+
static async render(containerElement, objectManager) {
|
|
4
|
+
const { children } = containerElement.getProps();
|
|
5
|
+
const nodes = [];
|
|
6
|
+
if (children)
|
|
7
|
+
for (const child of children) {
|
|
8
|
+
const renderer = RendererRegistry.getRenderer(child);
|
|
9
|
+
if (renderer) {
|
|
10
|
+
nodes.push(...(await renderer(child, objectManager)));
|
|
25
11
|
}
|
|
26
|
-
|
|
27
|
-
|
|
12
|
+
}
|
|
13
|
+
return nodes;
|
|
28
14
|
}
|
|
29
15
|
}
|
|
30
|
-
exports.ContainerRenderer = ContainerRenderer;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { PDFObjectManager } from "../utils/pdf-object-manager.js";
|
|
2
|
+
import { DefaultTextStyleElement } from "../elements/layout/default-text-style-element.js";
|
|
3
|
+
import { IRNode } from "../ir/display-list.js";
|
|
4
|
+
export declare class DefaultTextStyleRenderer {
|
|
5
|
+
static render(element: DefaultTextStyleElement, objectManager: PDFObjectManager): Promise<IRNode[]>;
|
|
6
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { RendererRegistry } from "../utils/renderer-registry.js";
|
|
2
|
+
// Transparent wrapper: the text style was already resolved onto the descendants at layout time, so
|
|
3
|
+
// the renderer just emits the child's display list (like PaddingRenderer).
|
|
4
|
+
export class DefaultTextStyleRenderer {
|
|
5
|
+
static async render(element, objectManager) {
|
|
6
|
+
const { child } = element.getProps();
|
|
7
|
+
const renderer = RendererRegistry.getRenderer(child);
|
|
8
|
+
return renderer ? await renderer(child, objectManager) : [];
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { PDFObjectManager } from "../utils/pdf-object-manager";
|
|
2
|
-
import { DeferredElement } from "../elements/layout/deferred-element";
|
|
3
|
-
import { IRNode } from "../ir/display-list";
|
|
1
|
+
import { PDFObjectManager } from "../utils/pdf-object-manager.js";
|
|
2
|
+
import { DeferredElement } from "../elements/layout/deferred-element.js";
|
|
3
|
+
import { IRNode } from "../ir/display-list.js";
|
|
4
4
|
export declare class DeferredRenderer {
|
|
5
5
|
static render(element: DeferredElement, 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.DeferredRenderer = void 0;
|
|
13
|
-
const renderer_registry_1 = require("../utils/renderer-registry");
|
|
14
|
-
class DeferredRenderer {
|
|
15
|
-
static render(element, objectManager) {
|
|
16
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
17
|
-
const { composed } = element.getProps();
|
|
18
|
-
if (!composed)
|
|
19
|
-
return [];
|
|
20
|
-
const renderer = renderer_registry_1.RendererRegistry.getRenderer(composed);
|
|
21
|
-
return renderer ? renderer(composed, objectManager) : [];
|
|
22
|
-
});
|
|
1
|
+
import { RendererRegistry } from "../utils/renderer-registry.js";
|
|
2
|
+
export class DeferredRenderer {
|
|
3
|
+
static async render(element, objectManager) {
|
|
4
|
+
const { composed } = element.getProps();
|
|
5
|
+
if (!composed)
|
|
6
|
+
return [];
|
|
7
|
+
const renderer = RendererRegistry.getRenderer(composed);
|
|
8
|
+
return renderer ? renderer(composed, objectManager) : [];
|
|
23
9
|
}
|
|
24
10
|
}
|
|
25
|
-
exports.DeferredRenderer = DeferredRenderer;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { PDFObjectManager } from "../utils/pdf-object-manager";
|
|
2
|
-
import { ExpandedElement } from "../elements";
|
|
3
|
-
import { IRNode } from "../ir/display-list";
|
|
1
|
+
import { PDFObjectManager } from "../utils/pdf-object-manager.js";
|
|
2
|
+
import { ExpandedElement } from "../elements/index.js";
|
|
3
|
+
import { IRNode } from "../ir/display-list.js";
|
|
4
4
|
export declare class ExpandedRenderer {
|
|
5
5
|
static render(expandedElement: ExpandedElement, objectManager: PDFObjectManager): Promise<IRNode[]>;
|
|
6
6
|
}
|
|
@@ -1,23 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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.ExpandedRenderer = void 0;
|
|
13
|
-
const renderer_registry_1 = require("../utils/renderer-registry");
|
|
14
|
-
class ExpandedRenderer {
|
|
15
|
-
static render(expandedElement, objectManager) {
|
|
16
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
17
|
-
const { child } = expandedElement.getProps();
|
|
18
|
-
const renderer = renderer_registry_1.RendererRegistry.getRenderer(child);
|
|
19
|
-
return renderer ? yield renderer(child, objectManager) : [];
|
|
20
|
-
});
|
|
1
|
+
import { RendererRegistry } from "../utils/renderer-registry.js";
|
|
2
|
+
export class ExpandedRenderer {
|
|
3
|
+
static async render(expandedElement, objectManager) {
|
|
4
|
+
const { child } = expandedElement.getProps();
|
|
5
|
+
const renderer = RendererRegistry.getRenderer(child);
|
|
6
|
+
return renderer ? await renderer(child, objectManager) : [];
|
|
21
7
|
}
|
|
22
8
|
}
|
|
23
|
-
exports.ExpandedRenderer = ExpandedRenderer;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { ImageElement } from "../elements/image-element";
|
|
2
|
-
import { PDFObjectManager } from "../utils/pdf-object-manager";
|
|
3
|
-
import { IRNode } from "../ir/display-list";
|
|
1
|
+
import { ImageElement } from "../elements/image-element.js";
|
|
2
|
+
import { PDFObjectManager } from "../utils/pdf-object-manager.js";
|
|
3
|
+
import { IRNode } from "../ir/display-list.js";
|
|
4
4
|
export declare class ImageRenderer {
|
|
5
5
|
static render(imageElement: ImageElement, _objectManager: PDFObjectManager): Promise<IRNode[]>;
|
|
6
6
|
}
|
|
@@ -1,74 +1,77 @@
|
|
|
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
|
-
|
|
1
|
+
import { BoxFit } from "../elements/image-element.js";
|
|
2
|
+
import { bytesFromLatin1 } from "../utils/bytes.js";
|
|
3
|
+
import { applyContainFit, applyCoverFit, applyFillFit, applyFitNone, decodePngToRgbFlate, } from "../utils/image-helper.js";
|
|
4
|
+
export class ImageRenderer {
|
|
5
|
+
static async render(imageElement, _objectManager) {
|
|
6
|
+
// Load the image and convert it in a binary string
|
|
7
|
+
let { x, y, width, height, image, fit, radius } = imageElement.getProps();
|
|
8
|
+
await image.init(); // Load and initialize the image
|
|
9
|
+
const imageType = await image.getImageType(); // For the moment we can handle `png` and `jpg/jpeg` files
|
|
10
|
+
const fileData = await image.getFileData();
|
|
11
|
+
const dimensions = await image.getImageDimensions();
|
|
12
|
+
if (!fileData) {
|
|
13
|
+
throw new Error("File data cannot be `null`");
|
|
14
|
+
}
|
|
15
|
+
// JPEG embeds raw (PDF decodes DCTDecode natively). PNG is not a valid Flate stream,
|
|
16
|
+
// so decode it to raw DeviceRGB samples that the FlateDecode XObject path expects.
|
|
17
|
+
let embedData = fileData;
|
|
18
|
+
let smask;
|
|
19
|
+
if (imageType === "FlateDecode") {
|
|
20
|
+
const decoded = await decodePngToRgbFlate(bytesFromLatin1(fileData));
|
|
21
|
+
embedData = decoded.data;
|
|
22
|
+
smask = decoded.smask;
|
|
23
|
+
}
|
|
24
|
+
// Now we check the `fit` property and changing the dimensions of the image
|
|
25
|
+
// Optionally we must add an overflow container
|
|
26
|
+
let mustCreateOverflowContainer = false;
|
|
27
|
+
const containerDimensions = JSON.parse(JSON.stringify({ x, y, width, height })); // Deep clone images dimensions
|
|
28
|
+
switch (fit) {
|
|
29
|
+
case BoxFit.cover:
|
|
30
|
+
mustCreateOverflowContainer = true;
|
|
31
|
+
const fitCoverResult = applyCoverFit(dimensions.width, dimensions.height, width ?? 0, height ?? 0);
|
|
32
|
+
x += fitCoverResult.offsetX;
|
|
33
|
+
y += fitCoverResult.offsetY;
|
|
34
|
+
width = fitCoverResult.width;
|
|
35
|
+
height = fitCoverResult.height;
|
|
36
|
+
break;
|
|
37
|
+
case BoxFit.contain:
|
|
38
|
+
mustCreateOverflowContainer = true;
|
|
39
|
+
const fitContainResult = applyContainFit(dimensions.width, dimensions.height, width ?? 0, height ?? 0);
|
|
40
|
+
x += fitContainResult.offsetX;
|
|
41
|
+
y += fitContainResult.offsetY;
|
|
42
|
+
width = fitContainResult.width;
|
|
43
|
+
height = fitContainResult.height;
|
|
44
|
+
break;
|
|
45
|
+
case BoxFit.none:
|
|
46
|
+
const fitNoneResult = applyFitNone(dimensions.width, dimensions.height, width ?? 0, height ?? 0);
|
|
47
|
+
x += fitNoneResult.offsetX;
|
|
48
|
+
y += fitNoneResult.offsetY;
|
|
49
|
+
width = fitNoneResult.width;
|
|
50
|
+
height = fitNoneResult.height;
|
|
51
|
+
break;
|
|
52
|
+
case BoxFit.fill:
|
|
53
|
+
const fitFillResult = applyFillFit(width ?? 0, height ?? 0);
|
|
54
|
+
width = fitFillResult.width;
|
|
55
|
+
height = fitFillResult.height;
|
|
56
|
+
}
|
|
57
|
+
// A radius rounds the image BOX (the element frame), so it clips to that frame too -
|
|
58
|
+
// independent of the cover/contain overflow clip.
|
|
59
|
+
const wantsClip = mustCreateOverflowContainer || (radius ?? 0) > 0;
|
|
60
|
+
// The fitted geometry becomes a display-list primitive; the backend registers
|
|
61
|
+
// the XObject and emits the placement (+ clip, rounded when a radius is set).
|
|
62
|
+
const node = {
|
|
63
|
+
type: "image",
|
|
64
|
+
x,
|
|
65
|
+
y,
|
|
66
|
+
width: width,
|
|
67
|
+
height: height,
|
|
68
|
+
intrinsicWidth: dimensions.width,
|
|
69
|
+
intrinsicHeight: dimensions.height,
|
|
70
|
+
data: embedData,
|
|
71
|
+
imageType,
|
|
72
|
+
...(smask ? { smask } : {}),
|
|
73
|
+
...(radius ? { radius } : {}),
|
|
74
|
+
...(wantsClip
|
|
72
75
|
? {
|
|
73
76
|
clip: {
|
|
74
77
|
x: containerDimensions.x,
|
|
@@ -77,9 +80,8 @@ class ImageRenderer {
|
|
|
77
80
|
height: containerDimensions.height,
|
|
78
81
|
},
|
|
79
82
|
}
|
|
80
|
-
: {})
|
|
81
|
-
|
|
82
|
-
|
|
83
|
+
: {}),
|
|
84
|
+
};
|
|
85
|
+
return [node];
|
|
83
86
|
}
|
|
84
87
|
}
|
|
85
|
-
exports.ImageRenderer = ImageRenderer;
|
package/dist/renderer/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
export * from "./container-renderer";
|
|
2
|
-
export * from "./page-renderer";
|
|
3
|
-
export * from "./pdf-document-class";
|
|
4
|
-
export * from "./pdf-document-renderer";
|
|
5
|
-
export * from "./pdf-renderer";
|
|
6
|
-
export * from "./rectangle-renderer";
|
|
7
|
-
export * from "./text-renderer";
|
|
8
|
-
export * from "./expanded-renderer";
|
|
9
|
-
export * from "./line-renderer";
|
|
10
|
-
export * from "./row-renderer";
|
|
1
|
+
export * from "./container-renderer.js";
|
|
2
|
+
export * from "./page-renderer.js";
|
|
3
|
+
export * from "./pdf-document-class.js";
|
|
4
|
+
export * from "./pdf-document-renderer.js";
|
|
5
|
+
export * from "./pdf-renderer.js";
|
|
6
|
+
export * from "./rectangle-renderer.js";
|
|
7
|
+
export * from "./text-renderer.js";
|
|
8
|
+
export * from "./expanded-renderer.js";
|
|
9
|
+
export * from "./line-renderer.js";
|
|
10
|
+
export * from "./row-renderer.js";
|
package/dist/renderer/index.js
CHANGED
|
@@ -1,26 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./container-renderer"), exports);
|
|
18
|
-
__exportStar(require("./page-renderer"), exports);
|
|
19
|
-
__exportStar(require("./pdf-document-class"), exports);
|
|
20
|
-
__exportStar(require("./pdf-document-renderer"), exports);
|
|
21
|
-
__exportStar(require("./pdf-renderer"), exports);
|
|
22
|
-
__exportStar(require("./rectangle-renderer"), exports);
|
|
23
|
-
__exportStar(require("./text-renderer"), exports);
|
|
24
|
-
__exportStar(require("./expanded-renderer"), exports);
|
|
25
|
-
__exportStar(require("./line-renderer"), exports);
|
|
26
|
-
__exportStar(require("./row-renderer"), exports);
|
|
1
|
+
export * from "./container-renderer.js";
|
|
2
|
+
export * from "./page-renderer.js";
|
|
3
|
+
export * from "./pdf-document-class.js";
|
|
4
|
+
export * from "./pdf-document-renderer.js";
|
|
5
|
+
export * from "./pdf-renderer.js";
|
|
6
|
+
export * from "./rectangle-renderer.js";
|
|
7
|
+
export * from "./text-renderer.js";
|
|
8
|
+
export * from "./expanded-renderer.js";
|
|
9
|
+
export * from "./line-renderer.js";
|
|
10
|
+
export * from "./row-renderer.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { PDFObjectManager } from "../utils/pdf-object-manager";
|
|
2
|
-
import { LineElement } from "../elements";
|
|
3
|
-
import { IRNode } from "../ir/display-list";
|
|
1
|
+
import { PDFObjectManager } from "../utils/pdf-object-manager.js";
|
|
2
|
+
import { LineElement } from "../elements/index.js";
|
|
3
|
+
import { IRNode } from "../ir/display-list.js";
|
|
4
4
|
export declare class LineRenderer {
|
|
5
5
|
static render(lineElement: LineElement, _objectManager: PDFObjectManager): Promise<IRNode[]>;
|
|
6
6
|
}
|
|
@@ -1,30 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
static render(lineElement, _objectManager) {
|
|
15
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
16
|
-
const { x, y, xEnd, yEnd, color, strokeWidth } = lineElement.getProps();
|
|
17
|
-
const node = {
|
|
18
|
-
type: "line",
|
|
19
|
-
x1: x,
|
|
20
|
-
y1: y,
|
|
21
|
-
x2: xEnd,
|
|
22
|
-
y2: yEnd,
|
|
23
|
-
stroke: color,
|
|
24
|
-
strokeWidth: strokeWidth,
|
|
25
|
-
};
|
|
26
|
-
return [node];
|
|
27
|
-
});
|
|
1
|
+
export class LineRenderer {
|
|
2
|
+
static async render(lineElement, _objectManager) {
|
|
3
|
+
const { x, y, xEnd, yEnd, color, strokeWidth } = lineElement.getProps();
|
|
4
|
+
const node = {
|
|
5
|
+
type: "line",
|
|
6
|
+
x1: x,
|
|
7
|
+
y1: y,
|
|
8
|
+
x2: xEnd,
|
|
9
|
+
y2: yEnd,
|
|
10
|
+
stroke: color,
|
|
11
|
+
strokeWidth: strokeWidth,
|
|
12
|
+
};
|
|
13
|
+
return [node];
|
|
28
14
|
}
|
|
29
15
|
}
|
|
30
|
-
exports.LineRenderer = LineRenderer;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { PDFObjectManager } from "../utils/pdf-object-manager";
|
|
2
|
-
import { PaddingElement } from "../elements/layout/padding-element";
|
|
3
|
-
import { IRNode } from "../ir/display-list";
|
|
1
|
+
import { PDFObjectManager } from "../utils/pdf-object-manager.js";
|
|
2
|
+
import { PaddingElement } from "../elements/layout/padding-element.js";
|
|
3
|
+
import { IRNode } from "../ir/display-list.js";
|
|
4
4
|
export declare class PaddingRenderer {
|
|
5
5
|
static render(paddingElement: PaddingElement, objectManager: PDFObjectManager): Promise<IRNode[]>;
|
|
6
6
|
}
|