@jsonpdf/plugins 0.1.0-alpha.1
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 +59 -0
- package/dist/barcode/barcode-generator.d.ts +18 -0
- package/dist/barcode/barcode-generator.d.ts.map +1 -0
- package/dist/barcode/barcode-generator.js +94 -0
- package/dist/barcode/barcode-generator.js.map +1 -0
- package/dist/barcode/barcode-plugin.d.ts +4 -0
- package/dist/barcode/barcode-plugin.d.ts.map +1 -0
- package/dist/barcode/barcode-plugin.js +70 -0
- package/dist/barcode/barcode-plugin.js.map +1 -0
- package/dist/barcode/barcode-types.d.ts +29 -0
- package/dist/barcode/barcode-types.d.ts.map +1 -0
- package/dist/barcode/barcode-types.js +60 -0
- package/dist/barcode/barcode-types.js.map +1 -0
- package/dist/chart/chart-generator.d.ts +17 -0
- package/dist/chart/chart-generator.d.ts.map +1 -0
- package/dist/chart/chart-generator.js +77 -0
- package/dist/chart/chart-generator.js.map +1 -0
- package/dist/chart/chart-plugin.d.ts +4 -0
- package/dist/chart/chart-plugin.d.ts.map +1 -0
- package/dist/chart/chart-plugin.js +65 -0
- package/dist/chart/chart-plugin.js.map +1 -0
- package/dist/chart/chart-types.d.ts +18 -0
- package/dist/chart/chart-types.d.ts.map +1 -0
- package/dist/chart/chart-types.js +18 -0
- package/dist/chart/chart-types.js.map +1 -0
- package/dist/container/container-plugin.d.ts +15 -0
- package/dist/container/container-plugin.d.ts.map +1 -0
- package/dist/container/container-plugin.js +190 -0
- package/dist/container/container-plugin.js.map +1 -0
- package/dist/frame/frame-plugin.d.ts +4 -0
- package/dist/frame/frame-plugin.d.ts.map +1 -0
- package/dist/frame/frame-plugin.js +52 -0
- package/dist/frame/frame-plugin.js.map +1 -0
- package/dist/frame/frame-types.d.ts +8 -0
- package/dist/frame/frame-types.d.ts.map +1 -0
- package/dist/frame/frame-types.js +17 -0
- package/dist/frame/frame-types.js.map +1 -0
- package/dist/image/image-loader.d.ts +13 -0
- package/dist/image/image-loader.d.ts.map +1 -0
- package/dist/image/image-loader.js +73 -0
- package/dist/image/image-loader.js.map +1 -0
- package/dist/image/image-plugin.d.ts +19 -0
- package/dist/image/image-plugin.d.ts.map +1 -0
- package/dist/image/image-plugin.js +112 -0
- package/dist/image/image-plugin.js.map +1 -0
- package/dist/image/svg-rasterizer.d.ts +30 -0
- package/dist/image/svg-rasterizer.d.ts.map +1 -0
- package/dist/image/svg-rasterizer.js +97 -0
- package/dist/image/svg-rasterizer.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +38 -0
- package/dist/index.js.map +1 -0
- package/dist/line/line-plugin.d.ts +11 -0
- package/dist/line/line-plugin.d.ts.map +1 -0
- package/dist/line/line-plugin.js +68 -0
- package/dist/line/line-plugin.js.map +1 -0
- package/dist/list/list-plugin.d.ts +13 -0
- package/dist/list/list-plugin.d.ts.map +1 -0
- package/dist/list/list-plugin.js +194 -0
- package/dist/list/list-plugin.js.map +1 -0
- package/dist/list/list-types.d.ts +9 -0
- package/dist/list/list-types.d.ts.map +1 -0
- package/dist/list/list-types.js +9 -0
- package/dist/list/list-types.js.map +1 -0
- package/dist/platform/base64.d.ts +7 -0
- package/dist/platform/base64.d.ts.map +1 -0
- package/dist/platform/base64.js +17 -0
- package/dist/platform/base64.js.map +1 -0
- package/dist/platform/font-store.d.ts +3 -0
- package/dist/platform/font-store.d.ts.map +1 -0
- package/dist/platform/font-store.js +8 -0
- package/dist/platform/font-store.js.map +1 -0
- package/dist/platform/fs.browser.d.ts +6 -0
- package/dist/platform/fs.browser.d.ts.map +1 -0
- package/dist/platform/fs.browser.js +10 -0
- package/dist/platform/fs.browser.js.map +1 -0
- package/dist/platform/fs.d.ts +5 -0
- package/dist/platform/fs.d.ts.map +1 -0
- package/dist/platform/fs.js +10 -0
- package/dist/platform/fs.js.map +1 -0
- package/dist/platform/init.browser.d.ts +10 -0
- package/dist/platform/init.browser.d.ts.map +1 -0
- package/dist/platform/init.browser.js +24 -0
- package/dist/platform/init.browser.js.map +1 -0
- package/dist/platform/init.d.ts +6 -0
- package/dist/platform/init.d.ts.map +1 -0
- package/dist/platform/init.js +12 -0
- package/dist/platform/init.js.map +1 -0
- package/dist/platform/svg-rasterizer.browser.d.ts +2 -0
- package/dist/platform/svg-rasterizer.browser.d.ts.map +1 -0
- package/dist/platform/svg-rasterizer.browser.js +2 -0
- package/dist/platform/svg-rasterizer.browser.js.map +1 -0
- package/dist/platform/svg-rasterizer.d.ts +2 -0
- package/dist/platform/svg-rasterizer.d.ts.map +1 -0
- package/dist/platform/svg-rasterizer.js +2 -0
- package/dist/platform/svg-rasterizer.js.map +1 -0
- package/dist/registry.d.ts +32 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +67 -0
- package/dist/registry.js.map +1 -0
- package/dist/shape/shape-plugin.d.ts +21 -0
- package/dist/shape/shape-plugin.d.ts.map +1 -0
- package/dist/shape/shape-plugin.js +148 -0
- package/dist/shape/shape-plugin.js.map +1 -0
- package/dist/table/table-plugin.d.ts +4 -0
- package/dist/table/table-plugin.d.ts.map +1 -0
- package/dist/table/table-plugin.js +232 -0
- package/dist/table/table-plugin.js.map +1 -0
- package/dist/table/table-types.d.ts +50 -0
- package/dist/table/table-types.d.ts.map +1 -0
- package/dist/table/table-types.js +129 -0
- package/dist/table/table-types.js.map +1 -0
- package/dist/text/text-decoration.d.ts +22 -0
- package/dist/text/text-decoration.d.ts.map +1 -0
- package/dist/text/text-decoration.js +43 -0
- package/dist/text/text-decoration.js.map +1 -0
- package/dist/text/text-plugin.d.ts +9 -0
- package/dist/text/text-plugin.d.ts.map +1 -0
- package/dist/text/text-plugin.js +496 -0
- package/dist/text/text-plugin.js.map +1 -0
- package/dist/text/word-wrap.d.ts +41 -0
- package/dist/text/word-wrap.d.ts.map +1 -0
- package/dist/text/word-wrap.js +149 -0
- package/dist/text/word-wrap.js.map +1 -0
- package/dist/types.d.ts +96 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +8 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +27 -0
- package/dist/utils.js.map +1 -0
- package/package.json +62 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { JSONSchema } from '@jsonpdf/core';
|
|
2
|
+
import type { Plugin } from '../types.js';
|
|
3
|
+
export interface ContainerProps {
|
|
4
|
+
/** Layout mode for child elements. */
|
|
5
|
+
layout: 'horizontal' | 'vertical' | 'absolute' | 'grid';
|
|
6
|
+
/** Spacing between children in points (horizontal, vertical, grid). Default 0. */
|
|
7
|
+
gap?: number;
|
|
8
|
+
/** Number of columns for grid layout. Default 2. */
|
|
9
|
+
gridColumns?: number;
|
|
10
|
+
/** Cross-axis alignment for horizontal/vertical/grid layouts. */
|
|
11
|
+
alignItems?: 'start' | 'center' | 'end';
|
|
12
|
+
}
|
|
13
|
+
export declare const containerPropsSchema: JSONSchema;
|
|
14
|
+
export declare const containerPlugin: Plugin<ContainerProps>;
|
|
15
|
+
//# sourceMappingURL=container-plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"container-plugin.d.ts","sourceRoot":"","sources":["../../src/container/container-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,UAAU,EAAmB,MAAM,eAAe,CAAC;AAC1E,OAAO,KAAK,EAAE,MAAM,EAAiC,MAAM,aAAa,CAAC;AAEzE,MAAM,WAAW,cAAc;IAC7B,sCAAsC;IACtC,MAAM,EAAE,YAAY,GAAG,UAAU,GAAG,UAAU,GAAG,MAAM,CAAC;IACxD,kFAAkF;IAClF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iEAAiE;IACjE,UAAU,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;CACzC;AAED,eAAO,MAAM,oBAAoB,EAAE,UAUlC,CAAC;AA4JF,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,cAAc,CA+FlD,CAAC"}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
export const containerPropsSchema = {
|
|
2
|
+
type: 'object',
|
|
3
|
+
required: ['layout'],
|
|
4
|
+
additionalProperties: false,
|
|
5
|
+
properties: {
|
|
6
|
+
layout: { type: 'string', enum: ['horizontal', 'vertical', 'absolute', 'grid'] },
|
|
7
|
+
gap: { type: 'number', minimum: 0 },
|
|
8
|
+
gridColumns: { type: 'integer', minimum: 1 },
|
|
9
|
+
alignItems: { type: 'string', enum: ['start', 'center', 'end'] },
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
|
+
const DEFAULTS = {
|
|
13
|
+
layout: 'absolute',
|
|
14
|
+
gap: 0,
|
|
15
|
+
gridColumns: 2,
|
|
16
|
+
alignItems: 'start',
|
|
17
|
+
};
|
|
18
|
+
async function measureChildren(children, measureChild) {
|
|
19
|
+
const entries = await Promise.all(children.map(async (child) => [child.id, await measureChild(child)]));
|
|
20
|
+
return new Map(entries);
|
|
21
|
+
}
|
|
22
|
+
function computeAbsoluteLayout(children, sizes) {
|
|
23
|
+
const layouts = [];
|
|
24
|
+
let maxRight = 0;
|
|
25
|
+
let maxBottom = 0;
|
|
26
|
+
for (const child of children) {
|
|
27
|
+
layouts.push({ element: child, offsetX: child.x, offsetY: child.y });
|
|
28
|
+
const size = sizes.get(child.id);
|
|
29
|
+
const childHeight = size ? size.height : child.height;
|
|
30
|
+
maxRight = Math.max(maxRight, child.x + child.width);
|
|
31
|
+
maxBottom = Math.max(maxBottom, child.y + childHeight);
|
|
32
|
+
}
|
|
33
|
+
return { layouts, totalWidth: maxRight, totalHeight: maxBottom };
|
|
34
|
+
}
|
|
35
|
+
function computeHorizontalLayout(children, sizes, gap, alignItems, containerHeight) {
|
|
36
|
+
const layouts = [];
|
|
37
|
+
let cursorX = 0;
|
|
38
|
+
let maxHeight = 0;
|
|
39
|
+
for (const child of children) {
|
|
40
|
+
const size = sizes.get(child.id);
|
|
41
|
+
const childHeight = size ? size.height : child.height;
|
|
42
|
+
maxHeight = Math.max(maxHeight, childHeight);
|
|
43
|
+
}
|
|
44
|
+
for (const child of children) {
|
|
45
|
+
const size = sizes.get(child.id);
|
|
46
|
+
const childHeight = size ? size.height : child.height;
|
|
47
|
+
const offsetY = alignOffset(alignItems, containerHeight, childHeight);
|
|
48
|
+
layouts.push({ element: child, offsetX: cursorX, offsetY });
|
|
49
|
+
cursorX += child.width + gap;
|
|
50
|
+
}
|
|
51
|
+
const totalWidth = children.length > 0 ? cursorX - gap : 0;
|
|
52
|
+
return { layouts, totalWidth, totalHeight: maxHeight };
|
|
53
|
+
}
|
|
54
|
+
function computeVerticalLayout(children, sizes, gap, alignItems, containerWidth) {
|
|
55
|
+
const layouts = [];
|
|
56
|
+
let cursorY = 0;
|
|
57
|
+
let maxWidth = 0;
|
|
58
|
+
for (const child of children) {
|
|
59
|
+
maxWidth = Math.max(maxWidth, child.width);
|
|
60
|
+
}
|
|
61
|
+
for (const child of children) {
|
|
62
|
+
const size = sizes.get(child.id);
|
|
63
|
+
const childHeight = size ? size.height : child.height;
|
|
64
|
+
const offsetX = alignOffset(alignItems, containerWidth, child.width);
|
|
65
|
+
layouts.push({ element: child, offsetX, offsetY: cursorY });
|
|
66
|
+
cursorY += childHeight + gap;
|
|
67
|
+
}
|
|
68
|
+
const totalHeight = children.length > 0 ? cursorY - gap : 0;
|
|
69
|
+
return { layouts, totalWidth: maxWidth, totalHeight };
|
|
70
|
+
}
|
|
71
|
+
function computeGridLayout(children, sizes, gap, gridColumns, alignItems, containerWidth) {
|
|
72
|
+
const layouts = [];
|
|
73
|
+
const colWidth = (containerWidth - gap * (gridColumns - 1)) / gridColumns;
|
|
74
|
+
// Compute row heights
|
|
75
|
+
const rowCount = Math.ceil(children.length / gridColumns);
|
|
76
|
+
const rowHeights = [];
|
|
77
|
+
for (let row = 0; row < rowCount; row++) {
|
|
78
|
+
let maxH = 0;
|
|
79
|
+
for (let col = 0; col < gridColumns; col++) {
|
|
80
|
+
const idx = row * gridColumns + col;
|
|
81
|
+
if (idx >= children.length)
|
|
82
|
+
break;
|
|
83
|
+
const child = children[idx];
|
|
84
|
+
const size = sizes.get(child.id);
|
|
85
|
+
const childHeight = size ? size.height : child.height;
|
|
86
|
+
maxH = Math.max(maxH, childHeight);
|
|
87
|
+
}
|
|
88
|
+
rowHeights.push(maxH);
|
|
89
|
+
}
|
|
90
|
+
let cursorY = 0;
|
|
91
|
+
for (let row = 0; row < rowCount; row++) {
|
|
92
|
+
for (let col = 0; col < gridColumns; col++) {
|
|
93
|
+
const idx = row * gridColumns + col;
|
|
94
|
+
if (idx >= children.length)
|
|
95
|
+
break;
|
|
96
|
+
const child = children[idx];
|
|
97
|
+
const size = sizes.get(child.id);
|
|
98
|
+
const childHeight = size ? size.height : child.height;
|
|
99
|
+
const offsetX = col * (colWidth + gap);
|
|
100
|
+
const offsetY = cursorY + alignOffset(alignItems, rowHeights[row], childHeight);
|
|
101
|
+
layouts.push({ element: child, offsetX, offsetY });
|
|
102
|
+
}
|
|
103
|
+
cursorY += rowHeights[row] + gap;
|
|
104
|
+
}
|
|
105
|
+
const totalHeight = rowCount > 0 ? cursorY - gap : 0;
|
|
106
|
+
return { layouts, totalWidth: containerWidth, totalHeight };
|
|
107
|
+
}
|
|
108
|
+
function alignOffset(alignItems, available, size) {
|
|
109
|
+
switch (alignItems) {
|
|
110
|
+
case 'center':
|
|
111
|
+
return (available - size) / 2;
|
|
112
|
+
case 'end':
|
|
113
|
+
return available - size;
|
|
114
|
+
default:
|
|
115
|
+
return 0;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
export const containerPlugin = {
|
|
119
|
+
type: 'container',
|
|
120
|
+
propsSchema: containerPropsSchema,
|
|
121
|
+
defaultProps: DEFAULTS,
|
|
122
|
+
resolveProps(raw) {
|
|
123
|
+
return { ...DEFAULTS, ...raw };
|
|
124
|
+
},
|
|
125
|
+
validate(props) {
|
|
126
|
+
const errors = [];
|
|
127
|
+
if (props.layout === 'grid' && props.gridColumns !== undefined && props.gridColumns < 1) {
|
|
128
|
+
errors.push({ path: '/gridColumns', message: 'must be at least 1' });
|
|
129
|
+
}
|
|
130
|
+
return errors;
|
|
131
|
+
},
|
|
132
|
+
async measure(props, ctx) {
|
|
133
|
+
const children = ctx.children ?? [];
|
|
134
|
+
if (children.length === 0) {
|
|
135
|
+
return { width: ctx.availableWidth, height: ctx.availableHeight };
|
|
136
|
+
}
|
|
137
|
+
if (!ctx.measureChild) {
|
|
138
|
+
return { width: ctx.availableWidth, height: ctx.availableHeight };
|
|
139
|
+
}
|
|
140
|
+
const sizes = await measureChildren(children, ctx.measureChild);
|
|
141
|
+
const gap = props.gap ?? 0;
|
|
142
|
+
const align = props.alignItems ?? 'start';
|
|
143
|
+
let result;
|
|
144
|
+
switch (props.layout) {
|
|
145
|
+
case 'absolute':
|
|
146
|
+
result = computeAbsoluteLayout(children, sizes);
|
|
147
|
+
break;
|
|
148
|
+
case 'horizontal':
|
|
149
|
+
result = computeHorizontalLayout(children, sizes, gap, align, ctx.availableHeight);
|
|
150
|
+
break;
|
|
151
|
+
case 'vertical':
|
|
152
|
+
result = computeVerticalLayout(children, sizes, gap, align, ctx.availableWidth);
|
|
153
|
+
break;
|
|
154
|
+
case 'grid':
|
|
155
|
+
result = computeGridLayout(children, sizes, gap, props.gridColumns ?? 2, align, ctx.availableWidth);
|
|
156
|
+
break;
|
|
157
|
+
}
|
|
158
|
+
return { width: result.totalWidth, height: result.totalHeight };
|
|
159
|
+
},
|
|
160
|
+
async render(props, ctx) {
|
|
161
|
+
const children = ctx.children ?? [];
|
|
162
|
+
if (children.length === 0 || !ctx.renderChild)
|
|
163
|
+
return;
|
|
164
|
+
if (!ctx.measureChild) {
|
|
165
|
+
throw new Error('Container plugin requires measureChild callback');
|
|
166
|
+
}
|
|
167
|
+
const sizes = await measureChildren(children, ctx.measureChild);
|
|
168
|
+
const gap = props.gap ?? 0;
|
|
169
|
+
const align = props.alignItems ?? 'start';
|
|
170
|
+
let layouts;
|
|
171
|
+
switch (props.layout) {
|
|
172
|
+
case 'absolute':
|
|
173
|
+
layouts = computeAbsoluteLayout(children, sizes).layouts;
|
|
174
|
+
break;
|
|
175
|
+
case 'horizontal':
|
|
176
|
+
layouts = computeHorizontalLayout(children, sizes, gap, align, ctx.height).layouts;
|
|
177
|
+
break;
|
|
178
|
+
case 'vertical':
|
|
179
|
+
layouts = computeVerticalLayout(children, sizes, gap, align, ctx.width).layouts;
|
|
180
|
+
break;
|
|
181
|
+
case 'grid':
|
|
182
|
+
layouts = computeGridLayout(children, sizes, gap, props.gridColumns ?? 2, align, ctx.width).layouts;
|
|
183
|
+
break;
|
|
184
|
+
}
|
|
185
|
+
for (const layout of layouts) {
|
|
186
|
+
await ctx.renderChild(layout.element, layout.offsetX, layout.offsetY);
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
};
|
|
190
|
+
//# sourceMappingURL=container-plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"container-plugin.js","sourceRoot":"","sources":["../../src/container/container-plugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frame-plugin.d.ts","sourceRoot":"","sources":["../../src/frame/frame-plugin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAiC,MAAM,aAAa,CAAC;AACzE,OAAO,EAAE,KAAK,UAAU,EAAoC,MAAM,kBAAkB,CAAC;AAErF,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,UAAU,CA4D1C,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { framePropsSchema, FRAME_DEFAULTS } from './frame-types.js';
|
|
2
|
+
export const framePlugin = {
|
|
3
|
+
type: 'frame',
|
|
4
|
+
propsSchema: framePropsSchema,
|
|
5
|
+
defaultProps: FRAME_DEFAULTS,
|
|
6
|
+
resolveProps(raw) {
|
|
7
|
+
return { ...FRAME_DEFAULTS, ...raw };
|
|
8
|
+
},
|
|
9
|
+
validate(props) {
|
|
10
|
+
const errors = [];
|
|
11
|
+
const bands = props.bands;
|
|
12
|
+
if (!Array.isArray(bands)) {
|
|
13
|
+
errors.push({ path: '/bands', message: 'bands is required and must be an array' });
|
|
14
|
+
return errors;
|
|
15
|
+
}
|
|
16
|
+
if (bands.length === 0) {
|
|
17
|
+
errors.push({ path: '/bands', message: 'bands must not be empty' });
|
|
18
|
+
return errors;
|
|
19
|
+
}
|
|
20
|
+
for (let i = 0; i < bands.length; i++) {
|
|
21
|
+
const band = bands[i];
|
|
22
|
+
const prefix = `/bands/${String(i)}`;
|
|
23
|
+
if (!band.id) {
|
|
24
|
+
errors.push({ path: `${prefix}/id`, message: 'band must have an id' });
|
|
25
|
+
}
|
|
26
|
+
if (!band.type) {
|
|
27
|
+
errors.push({ path: `${prefix}/type`, message: 'band must have a type' });
|
|
28
|
+
}
|
|
29
|
+
if (!Array.isArray(band.elements)) {
|
|
30
|
+
errors.push({ path: `${prefix}/elements`, message: 'band must have an elements array' });
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return errors;
|
|
34
|
+
},
|
|
35
|
+
async measure(props, ctx) {
|
|
36
|
+
if (props.bands.length === 0) {
|
|
37
|
+
return { width: 0, height: 0 };
|
|
38
|
+
}
|
|
39
|
+
if (!ctx.measureBands) {
|
|
40
|
+
return { width: ctx.availableWidth, height: ctx.availableHeight };
|
|
41
|
+
}
|
|
42
|
+
const { totalHeight } = await ctx.measureBands(props.bands);
|
|
43
|
+
return { width: ctx.availableWidth, height: totalHeight };
|
|
44
|
+
},
|
|
45
|
+
async render(props, ctx) {
|
|
46
|
+
if (props.bands.length === 0 || !ctx.renderBands) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
await ctx.renderBands(props.bands);
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
//# sourceMappingURL=frame-plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frame-plugin.js","sourceRoot":"","sources":["../../src/frame/frame-plugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Band, JSONSchema } from '@jsonpdf/core';
|
|
2
|
+
export interface FrameProps {
|
|
3
|
+
/** Nested bands to expand and render within the frame. */
|
|
4
|
+
bands: Band[];
|
|
5
|
+
}
|
|
6
|
+
export declare const framePropsSchema: JSONSchema;
|
|
7
|
+
export declare const FRAME_DEFAULTS: FrameProps;
|
|
8
|
+
//# sourceMappingURL=frame-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frame-types.d.ts","sourceRoot":"","sources":["../../src/frame/frame-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEtD,MAAM,WAAW,UAAU;IACzB,0DAA0D;IAC1D,KAAK,EAAE,IAAI,EAAE,CAAC;CACf;AAED,eAAO,MAAM,gBAAgB,EAAE,UAc9B,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,UAA0B,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export const framePropsSchema = {
|
|
2
|
+
type: 'object',
|
|
3
|
+
required: ['bands'],
|
|
4
|
+
additionalProperties: false,
|
|
5
|
+
properties: {
|
|
6
|
+
bands: {
|
|
7
|
+
type: 'array',
|
|
8
|
+
minItems: 1,
|
|
9
|
+
items: {
|
|
10
|
+
type: 'object',
|
|
11
|
+
required: ['id', 'type', 'height', 'elements'],
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
export const FRAME_DEFAULTS = { bands: [] };
|
|
17
|
+
//# sourceMappingURL=frame-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frame-types.js","sourceRoot":"","sources":["../../src/frame/frame-types.ts"],"names":[],"mappings":"AAOA,MAAM,CAAC,MAAM,gBAAgB,GAAe;IAC1C,IAAI,EAAE,QAAQ;IACd,QAAQ,EAAE,CAAC,OAAO,CAAC;IACnB,oBAAoB,EAAE,KAAK;IAC3B,UAAU,EAAE;QACV,KAAK,EAAE;YACL,IAAI,EAAE,OAAO;YACb,QAAQ,EAAE,CAAC;YACX,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,CAAC;aAC/C;SACF;KACF;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAe,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ImageCache } from '../types.js';
|
|
2
|
+
export type ImageFormat = 'png' | 'jpeg';
|
|
3
|
+
export interface LoadedImage {
|
|
4
|
+
bytes: Uint8Array;
|
|
5
|
+
format: ImageFormat;
|
|
6
|
+
}
|
|
7
|
+
/** Detect image format from the first few bytes. */
|
|
8
|
+
export declare function detectFormat(bytes: Uint8Array): ImageFormat;
|
|
9
|
+
/** Load image bytes from a data URI. */
|
|
10
|
+
export declare function loadImageBytes(src: string): LoadedImage;
|
|
11
|
+
/** Create an image cache that deduplicates loads. */
|
|
12
|
+
export declare function createImageCache(): ImageCache;
|
|
13
|
+
//# sourceMappingURL=image-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image-loader.d.ts","sourceRoot":"","sources":["../../src/image/image-loader.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAiB,UAAU,EAAE,MAAM,aAAa,CAAC;AAG7D,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,MAAM,CAAC;AAEzC,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,UAAU,CAAC;IAClB,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,oDAAoD;AACpD,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,WAAW,CAU3D;AAED,wCAAwC;AACxC,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAoCvD;AAaD,qDAAqD;AACrD,wBAAgB,gBAAgB,IAAI,UAAU,CAe7C"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { isSvgBytes, rasterizeSvg } from './svg-rasterizer.js';
|
|
2
|
+
/** Detect image format from the first few bytes. */
|
|
3
|
+
export function detectFormat(bytes) {
|
|
4
|
+
// PNG: starts with \x89PNG
|
|
5
|
+
if (bytes[0] === 0x89 && bytes[1] === 0x50 && bytes[2] === 0x4e && bytes[3] === 0x47) {
|
|
6
|
+
return 'png';
|
|
7
|
+
}
|
|
8
|
+
// JPEG: starts with \xFF\xD8
|
|
9
|
+
if (bytes[0] === 0xff && bytes[1] === 0xd8) {
|
|
10
|
+
return 'jpeg';
|
|
11
|
+
}
|
|
12
|
+
throw new Error('Unsupported image format: expected PNG or JPEG');
|
|
13
|
+
}
|
|
14
|
+
/** Load image bytes from a data URI. */
|
|
15
|
+
export function loadImageBytes(src) {
|
|
16
|
+
let bytes;
|
|
17
|
+
let isSvgDataUri = false;
|
|
18
|
+
if (src.startsWith('data:')) {
|
|
19
|
+
const commaIdx = src.indexOf(',');
|
|
20
|
+
if (commaIdx === -1) {
|
|
21
|
+
throw new Error(`Invalid data URI: ${src.slice(0, 50)}`);
|
|
22
|
+
}
|
|
23
|
+
const header = src.slice(0, commaIdx).toLowerCase();
|
|
24
|
+
isSvgDataUri = header.includes('image/svg+xml');
|
|
25
|
+
if (header.includes(';base64')) {
|
|
26
|
+
// Base64-encoded data URI (PNG, JPEG, or SVG)
|
|
27
|
+
const base64 = src.slice(commaIdx + 1);
|
|
28
|
+
bytes = Uint8Array.from(atob(base64), (c) => c.charCodeAt(0));
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
// URL-encoded data URI (common for SVG)
|
|
32
|
+
const decoded = decodeURIComponent(src.slice(commaIdx + 1));
|
|
33
|
+
bytes = new TextEncoder().encode(decoded);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
throw new Error(`Unsupported image source: "${src.slice(0, 80)}". Use a data URI (base64 or URL-encoded).`);
|
|
38
|
+
}
|
|
39
|
+
// SVG: rasterize to PNG before embedding
|
|
40
|
+
if (isSvgDataUri || isSvgBytes(bytes)) {
|
|
41
|
+
const svgString = new TextDecoder().decode(bytes);
|
|
42
|
+
const { pngBytes } = rasterizeSvg(svgString);
|
|
43
|
+
return { bytes: pngBytes, format: 'png' };
|
|
44
|
+
}
|
|
45
|
+
const format = detectFormat(bytes);
|
|
46
|
+
return { bytes, format };
|
|
47
|
+
}
|
|
48
|
+
/** Embed an image into a PDF document. */
|
|
49
|
+
async function embedImage(doc, loaded) {
|
|
50
|
+
const image = loaded.format === 'png' ? await doc.embedPng(loaded.bytes) : await doc.embedJpg(loaded.bytes);
|
|
51
|
+
return {
|
|
52
|
+
image,
|
|
53
|
+
width: image.width,
|
|
54
|
+
height: image.height,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/** Create an image cache that deduplicates loads. */
|
|
58
|
+
export function createImageCache() {
|
|
59
|
+
const cache = new Map();
|
|
60
|
+
return {
|
|
61
|
+
async getOrEmbed(src, doc) {
|
|
62
|
+
let promise = cache.get(src);
|
|
63
|
+
if (!promise) {
|
|
64
|
+
promise = embedImage(doc, loadImageBytes(src));
|
|
65
|
+
// Remove from cache on failure so retries can succeed
|
|
66
|
+
promise.catch(() => cache.delete(src));
|
|
67
|
+
cache.set(src, promise);
|
|
68
|
+
}
|
|
69
|
+
return promise;
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=image-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image-loader.js","sourceRoot":"","sources":["../../src/image/image-loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { JSONSchema } from '@jsonpdf/core';
|
|
2
|
+
import type { Plugin } from '../types.js';
|
|
3
|
+
export interface ImageProps {
|
|
4
|
+
src: string;
|
|
5
|
+
fit?: 'contain' | 'cover' | 'fill' | 'none';
|
|
6
|
+
}
|
|
7
|
+
export declare const imagePropsSchema: JSONSchema;
|
|
8
|
+
/**
|
|
9
|
+
* Compute the draw dimensions and offset for an image within an element.
|
|
10
|
+
* Returns { drawWidth, drawHeight, offsetX, offsetY } in element-local coordinates.
|
|
11
|
+
*/
|
|
12
|
+
export declare function computeFitDimensions(imgWidth: number, imgHeight: number, elemWidth: number, elemHeight: number, fit: 'contain' | 'cover' | 'fill' | 'none'): {
|
|
13
|
+
drawWidth: number;
|
|
14
|
+
drawHeight: number;
|
|
15
|
+
offsetX: number;
|
|
16
|
+
offsetY: number;
|
|
17
|
+
};
|
|
18
|
+
export declare const imagePlugin: Plugin<ImageProps>;
|
|
19
|
+
//# sourceMappingURL=image-plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image-plugin.d.ts","sourceRoot":"","sources":["../../src/image/image-plugin.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAmB,UAAU,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,KAAK,EAAE,MAAM,EAAgD,MAAM,aAAa,CAAC;AAExF,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;CAC7C;AAED,eAAO,MAAM,gBAAgB,EAAE,UAO9B,CAAC;AAIF;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GACzC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAmC7E;AAoBD,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,UAAU,CAiF1C,CAAC"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { pushGraphicsState, popGraphicsState, moveTo, lineTo, closePath, clip, endPath, } from 'pdf-lib';
|
|
2
|
+
export const imagePropsSchema = {
|
|
3
|
+
type: 'object',
|
|
4
|
+
required: ['src'],
|
|
5
|
+
properties: {
|
|
6
|
+
src: { type: 'string', minLength: 1, pattern: '^data:' },
|
|
7
|
+
fit: { type: 'string', enum: ['contain', 'cover', 'fill', 'none'] },
|
|
8
|
+
},
|
|
9
|
+
};
|
|
10
|
+
const IMAGE_DEFAULTS = { src: '', fit: 'contain' };
|
|
11
|
+
/**
|
|
12
|
+
* Compute the draw dimensions and offset for an image within an element.
|
|
13
|
+
* Returns { drawWidth, drawHeight, offsetX, offsetY } in element-local coordinates.
|
|
14
|
+
*/
|
|
15
|
+
export function computeFitDimensions(imgWidth, imgHeight, elemWidth, elemHeight, fit) {
|
|
16
|
+
// Guard against degenerate (zero-dimension) images
|
|
17
|
+
if (imgWidth <= 0 || imgHeight <= 0) {
|
|
18
|
+
return { drawWidth: 0, drawHeight: 0, offsetX: 0, offsetY: 0 };
|
|
19
|
+
}
|
|
20
|
+
switch (fit) {
|
|
21
|
+
case 'fill':
|
|
22
|
+
return { drawWidth: elemWidth, drawHeight: elemHeight, offsetX: 0, offsetY: 0 };
|
|
23
|
+
case 'none': {
|
|
24
|
+
const offsetX = (elemWidth - imgWidth) / 2;
|
|
25
|
+
const offsetY = (elemHeight - imgHeight) / 2;
|
|
26
|
+
return { drawWidth: imgWidth, drawHeight: imgHeight, offsetX, offsetY };
|
|
27
|
+
}
|
|
28
|
+
case 'cover': {
|
|
29
|
+
const scale = Math.max(elemWidth / imgWidth, elemHeight / imgHeight);
|
|
30
|
+
const drawWidth = imgWidth * scale;
|
|
31
|
+
const drawHeight = imgHeight * scale;
|
|
32
|
+
const offsetX = (elemWidth - drawWidth) / 2;
|
|
33
|
+
const offsetY = (elemHeight - drawHeight) / 2;
|
|
34
|
+
return { drawWidth, drawHeight, offsetX, offsetY };
|
|
35
|
+
}
|
|
36
|
+
case 'contain':
|
|
37
|
+
default: {
|
|
38
|
+
const scale = Math.min(elemWidth / imgWidth, elemHeight / imgHeight);
|
|
39
|
+
const drawWidth = imgWidth * scale;
|
|
40
|
+
const drawHeight = imgHeight * scale;
|
|
41
|
+
const offsetX = (elemWidth - drawWidth) / 2;
|
|
42
|
+
const offsetY = (elemHeight - drawHeight) / 2;
|
|
43
|
+
return { drawWidth, drawHeight, offsetX, offsetY };
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
async function getImage(src, ctx) {
|
|
48
|
+
return ctx.imageCache.getOrEmbed(src, ctx.pdfDoc);
|
|
49
|
+
}
|
|
50
|
+
/** Apply a clipping rectangle to the current page graphics state. */
|
|
51
|
+
function clipToElementBounds(ctx) {
|
|
52
|
+
ctx.page.pushOperators(pushGraphicsState(), moveTo(ctx.x, ctx.y), lineTo(ctx.x + ctx.width, ctx.y), lineTo(ctx.x + ctx.width, ctx.y - ctx.height), lineTo(ctx.x, ctx.y - ctx.height), closePath(), clip(), endPath());
|
|
53
|
+
}
|
|
54
|
+
export const imagePlugin = {
|
|
55
|
+
type: 'image',
|
|
56
|
+
propsSchema: imagePropsSchema,
|
|
57
|
+
defaultProps: IMAGE_DEFAULTS,
|
|
58
|
+
resolveProps(raw) {
|
|
59
|
+
return { ...IMAGE_DEFAULTS, ...raw };
|
|
60
|
+
},
|
|
61
|
+
validate(props) {
|
|
62
|
+
const errors = [];
|
|
63
|
+
if (!props.src || typeof props.src !== 'string' || props.src.trim().length === 0) {
|
|
64
|
+
errors.push({ path: '/src', message: 'src is required and must be a non-empty string' });
|
|
65
|
+
}
|
|
66
|
+
else if (!props.src.startsWith('data:')) {
|
|
67
|
+
errors.push({
|
|
68
|
+
path: '/src',
|
|
69
|
+
message: 'src must be a data URI (e.g. data:image/png;base64,... or data:image/svg+xml,...)',
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
if (props.fit !== undefined && !['contain', 'cover', 'fill', 'none'].includes(props.fit)) {
|
|
73
|
+
errors.push({ path: '/fit', message: 'fit must be contain, cover, fill, or none' });
|
|
74
|
+
}
|
|
75
|
+
return errors;
|
|
76
|
+
},
|
|
77
|
+
async measure(props, ctx) {
|
|
78
|
+
const embedded = await getImage(props.src, ctx);
|
|
79
|
+
const fit = props.fit ?? 'contain';
|
|
80
|
+
const { drawWidth, drawHeight } = computeFitDimensions(embedded.width, embedded.height, ctx.availableWidth, ctx.availableHeight, fit);
|
|
81
|
+
if (fit === 'none') {
|
|
82
|
+
return { width: drawWidth, height: drawHeight };
|
|
83
|
+
}
|
|
84
|
+
return { width: ctx.availableWidth, height: ctx.availableHeight };
|
|
85
|
+
},
|
|
86
|
+
async render(props, ctx) {
|
|
87
|
+
const embedded = await getImage(props.src, ctx);
|
|
88
|
+
const fit = props.fit ?? 'contain';
|
|
89
|
+
const { drawWidth, drawHeight, offsetX, offsetY } = computeFitDimensions(embedded.width, embedded.height, ctx.width, ctx.height, fit);
|
|
90
|
+
// pdf-lib drawImage: x,y is the bottom-left corner of the image.
|
|
91
|
+
// ctx.x, ctx.y is the top-left of content area in pdf-lib coords (y up).
|
|
92
|
+
// offsetY is the distance from the top of the element to the top of the image (top-down).
|
|
93
|
+
const imgX = ctx.x + offsetX;
|
|
94
|
+
const imgY = ctx.y - offsetY - drawHeight;
|
|
95
|
+
// Clip to element bounds for modes that can overflow (cover, none)
|
|
96
|
+
const needsClip = fit === 'cover' || fit === 'none';
|
|
97
|
+
if (needsClip) {
|
|
98
|
+
clipToElementBounds(ctx);
|
|
99
|
+
}
|
|
100
|
+
ctx.page.drawImage(embedded.image, {
|
|
101
|
+
x: imgX,
|
|
102
|
+
y: imgY,
|
|
103
|
+
width: drawWidth,
|
|
104
|
+
height: drawHeight,
|
|
105
|
+
opacity: ctx.opacity,
|
|
106
|
+
});
|
|
107
|
+
if (needsClip) {
|
|
108
|
+
ctx.page.pushOperators(popGraphicsState());
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
//# sourceMappingURL=image-plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image-plugin.js","sourceRoot":"","sources":["../../src/image/image-plugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/** Default scale factor for SVG rasterization (2x for HiDPI). */
|
|
2
|
+
export declare const DEFAULT_SVG_SCALE = 2;
|
|
3
|
+
/**
|
|
4
|
+
* Check if raw bytes look like SVG content.
|
|
5
|
+
* Examines the first 1024 bytes (after BOM/whitespace) for `<svg` or `<?xml`.
|
|
6
|
+
*/
|
|
7
|
+
export declare function isSvgBytes(bytes: Uint8Array): boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Parse intrinsic dimensions from an SVG string.
|
|
10
|
+
* Uses regex to extract width/height attributes or viewBox from the `<svg>` tag.
|
|
11
|
+
* Falls back to 300×150 (HTML spec default for replaced elements).
|
|
12
|
+
*/
|
|
13
|
+
export declare function parseSvgDimensions(svg: string): {
|
|
14
|
+
width: number;
|
|
15
|
+
height: number;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Rasterize an SVG string to PNG bytes using @resvg/resvg-js.
|
|
19
|
+
*
|
|
20
|
+
* @param svg SVG markup string
|
|
21
|
+
* @param scale Scale factor (default {@link DEFAULT_SVG_SCALE}).
|
|
22
|
+
* The SVG intrinsic dimensions are multiplied by this value.
|
|
23
|
+
* @returns PNG bytes and intrinsic (pre-scale) dimensions for aspect ratio calculations.
|
|
24
|
+
*/
|
|
25
|
+
export declare function rasterizeSvg(svg: string, scale?: number): {
|
|
26
|
+
pngBytes: Uint8Array;
|
|
27
|
+
width: number;
|
|
28
|
+
height: number;
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=svg-rasterizer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"svg-rasterizer.d.ts","sourceRoot":"","sources":["../../src/image/svg-rasterizer.ts"],"names":[],"mappings":"AAUA,iEAAiE;AACjE,eAAO,MAAM,iBAAiB,IAAI,CAAC;AAEnC;;;GAGG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAWrD;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAoCjF;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,GAAG,EAAE,MAAM,EACX,KAAK,GAAE,MAA0B,GAChC;IAAE,QAAQ,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAgCzD"}
|