Skip to content

Commit 1d7c951

Browse files
committed
Refactor render options to use withForms/withAnnotations
Replaces the 'renderForms' and 'initForms' options with 'withForms' and adds 'withAnnotations' throughout the rendering pipeline, including plugin configuration, engine, and example usage. Moves computeFormDrawParams to a helper file for better modularity.
1 parent eb0526e commit 1d7c951

5 files changed

Lines changed: 94 additions & 79 deletions

File tree

packages/engines/src/lib/pdfium/engine.ts

Lines changed: 16 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ import {
122122
PdfStampFit,
123123
PdfAddAttachmentParams,
124124
} from '@embedpdf/models';
125-
import { isValidCustomKey, readArrayBuffer, readString } from './helper';
125+
import { computeFormDrawParams, isValidCustomKey, readArrayBuffer, readString } from './helper';
126126
import { WrappedPdfiumModule } from '@embedpdf/pdfium';
127127
import { DocumentContext, PageContext, PdfCache } from './cache';
128128
import { ImageDataConverter, LazyImageData } from '../converters/types';
@@ -155,63 +155,6 @@ export enum RenderFlag {
155155
REVERSE_BYTE_ORDER = 0x10, // Set whether render in a reverse Byte order, this flag only.
156156
}
157157

158-
interface FormDrawParams {
159-
startX: number;
160-
startY: number;
161-
formsWidth: number;
162-
formsHeight: number;
163-
scaleX: number;
164-
scaleY: number;
165-
}
166-
167-
function computeFormDrawParams(matrix: Matrix, rect: Rect, pageSize: Size, rotation: Rotation): FormDrawParams {
168-
const rectLeft = rect.origin.x;
169-
const rectBottom = rect.origin.y;
170-
const rectRight = rectLeft + rect.size.width;
171-
const rectTop = rectBottom + rect.size.height;
172-
const pageWidth = pageSize.width;
173-
const pageHeight = pageSize.height;
174-
175-
// Extract the per-axis scale that the render matrix applies.
176-
const scaleX = Math.hypot(matrix.a, matrix.b);
177-
const scaleY = Math.hypot(matrix.c, matrix.d);
178-
const swap = (rotation & 1) === 1;
179-
180-
const formsWidth = swap
181-
? Math.max(1, Math.round(pageHeight * scaleX))
182-
: Math.max(1, Math.round(pageWidth * scaleX));
183-
const formsHeight = swap
184-
? Math.max(1, Math.round(pageWidth * scaleY))
185-
: Math.max(1, Math.round(pageHeight * scaleY));
186-
187-
let startX: number;
188-
let startY: number;
189-
switch (rotation) {
190-
case Rotation.Degree0:
191-
startX = -Math.round(rectLeft * scaleX);
192-
startY = -Math.round(rectBottom * scaleY);
193-
break;
194-
case Rotation.Degree90:
195-
startX = Math.round((rectTop - pageHeight) * scaleX);
196-
startY = -Math.round(rectLeft * scaleY);
197-
break;
198-
case Rotation.Degree180:
199-
startX = Math.round((rectRight - pageWidth) * scaleX);
200-
startY = Math.round((rectTop - pageHeight) * scaleY);
201-
break;
202-
case Rotation.Degree270:
203-
startX = -Math.round(rectBottom * scaleX);
204-
startY = Math.round((rectRight - pageWidth) * scaleY);
205-
break;
206-
default:
207-
startX = -Math.round(rectLeft * scaleX);
208-
startY = -Math.round(rectBottom * scaleY);
209-
break;
210-
}
211-
212-
return { startX, startY, formsWidth, formsHeight, scaleX, scaleY };
213-
}
214-
215158
const LOG_SOURCE = 'PDFiumEngine';
216159
const LOG_CATEGORY = 'Engine';
217160

@@ -270,8 +213,8 @@ export const browserImageDataToBlobConverter: ImageDataConverter<Blob> = (
270213
return Promise.reject(
271214
new OffscreenCanvasError(
272215
'OffscreenCanvas is not available in this environment. ' +
273-
'This converter is intended for browser use only. ' +
274-
'Falling back to WASM-based image encoding.',
216+
'This converter is intended for browser use only. ' +
217+
'Falling back to WASM-based image encoding.',
275218
),
276219
);
277220
}
@@ -897,9 +840,9 @@ export class PdfiumEngine<T = Blob> implements PdfEngine<T> {
897840
return ok
898841
? PdfTaskHelper.resolve(true)
899842
: PdfTaskHelper.reject({
900-
code: PdfErrorCode.Unknown,
901-
message: 'one or more metadata fields could not be written',
902-
});
843+
code: PdfErrorCode.Unknown,
844+
message: 'one or more metadata fields could not be written',
845+
});
903846
}
904847

905848
/**
@@ -1143,9 +1086,9 @@ export class PdfiumEngine<T = Blob> implements PdfEngine<T> {
11431086
return ok
11441087
? PdfTaskHelper.resolve(true)
11451088
: PdfTaskHelper.reject({
1146-
code: PdfErrorCode.Unknown,
1147-
message: 'failed to clear bookmarks',
1148-
});
1089+
code: PdfErrorCode.Unknown,
1090+
message: 'failed to clear bookmarks',
1091+
});
11491092
}
11501093

11511094
/**
@@ -1643,9 +1586,9 @@ export class PdfiumEngine<T = Blob> implements PdfEngine<T> {
16431586
return ok
16441587
? PdfTaskHelper.resolve<boolean>(true)
16451588
: PdfTaskHelper.reject<boolean>({
1646-
code: PdfErrorCode.CantSetAnnotContent,
1647-
message: 'failed to update annotation',
1648-
});
1589+
code: PdfErrorCode.CantSetAnnotContent,
1590+
message: 'failed to update annotation',
1591+
});
16491592
}
16501593

16511594
/**
@@ -7015,7 +6958,7 @@ export class PdfiumEngine<T = Blob> implements PdfEngine<T> {
70156958
const bytes = stride * hDev;
70166959

70176960
const pageCtx = ctx.acquirePage(page.index);
7018-
const shouldRenderForms = options?.renderForms ?? false;
6961+
const shouldRenderForms = options?.withForms ?? false;
70196962
const formHandle = shouldRenderForms ? pageCtx.getFormHandle() : undefined;
70206963

70216964
// ---- 2) allocate a BGRA bitmap in WASM
@@ -7842,7 +7785,7 @@ export class PdfiumEngine<T = Blob> implements PdfEngine<T> {
78427785

78437786
let cancelled = false;
78447787
task.wait(
7845-
() => { },
7788+
() => {},
78467789
(err) => {
78477790
if (err.type === 'abort') cancelled = true;
78487791
},
@@ -7895,12 +7838,12 @@ export class PdfiumEngine<T = Blob> implements PdfEngine<T> {
78957838

78967839
// Ensure buffer is freed if caller aborts mid-flight
78977840
task.wait(
7898-
() => { },
7841+
() => {},
78997842
(err) => {
79007843
if (err.type === 'abort') {
79017844
try {
79027845
this.memoryManager.free(keywordPtr);
7903-
} catch { }
7846+
} catch {}
79047847
}
79057848
},
79067849
);

packages/engines/src/lib/pdfium/helper.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { Matrix, Rotation, Rect, Size } from '@embedpdf/models';
12
import { PdfiumRuntimeMethods, PdfiumModule } from '@embedpdf/pdfium';
23

34
/**
@@ -92,3 +93,65 @@ export function isValidCustomKey(key: string): boolean {
9293
}
9394
return true;
9495
}
96+
97+
interface FormDrawParams {
98+
startX: number;
99+
startY: number;
100+
formsWidth: number;
101+
formsHeight: number;
102+
scaleX: number;
103+
scaleY: number;
104+
}
105+
106+
export function computeFormDrawParams(
107+
matrix: Matrix,
108+
rect: Rect,
109+
pageSize: Size,
110+
rotation: Rotation,
111+
): FormDrawParams {
112+
const rectLeft = rect.origin.x;
113+
const rectBottom = rect.origin.y;
114+
const rectRight = rectLeft + rect.size.width;
115+
const rectTop = rectBottom + rect.size.height;
116+
const pageWidth = pageSize.width;
117+
const pageHeight = pageSize.height;
118+
119+
// Extract the per-axis scale that the render matrix applies.
120+
const scaleX = Math.hypot(matrix.a, matrix.b);
121+
const scaleY = Math.hypot(matrix.c, matrix.d);
122+
const swap = (rotation & 1) === 1;
123+
124+
const formsWidth = swap
125+
? Math.max(1, Math.round(pageHeight * scaleX))
126+
: Math.max(1, Math.round(pageWidth * scaleX));
127+
const formsHeight = swap
128+
? Math.max(1, Math.round(pageWidth * scaleY))
129+
: Math.max(1, Math.round(pageHeight * scaleY));
130+
131+
let startX: number;
132+
let startY: number;
133+
switch (rotation) {
134+
case Rotation.Degree0:
135+
startX = -Math.round(rectLeft * scaleX);
136+
startY = -Math.round(rectBottom * scaleY);
137+
break;
138+
case Rotation.Degree90:
139+
startX = Math.round((rectTop - pageHeight) * scaleX);
140+
startY = -Math.round(rectLeft * scaleY);
141+
break;
142+
case Rotation.Degree180:
143+
startX = Math.round((rectRight - pageWidth) * scaleX);
144+
startY = Math.round((rectTop - pageHeight) * scaleY);
145+
break;
146+
case Rotation.Degree270:
147+
startX = -Math.round(rectBottom * scaleX);
148+
startY = Math.round((rectRight - pageWidth) * scaleY);
149+
break;
150+
default:
151+
startX = -Math.round(rectLeft * scaleX);
152+
startY = -Math.round(rectBottom * scaleY);
153+
break;
154+
}
155+
156+
return { startX, startY, formsWidth, formsHeight, scaleX, scaleY };
157+
}

packages/models/src/pdf.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2515,7 +2515,7 @@ export interface PdfRenderPageOptions extends PdfRenderOptions {
25152515
/**
25162516
* Whether to render interactive form widgets
25172517
*/
2518-
renderForms?: boolean;
2518+
withForms?: boolean;
25192519
}
25202520

25212521
export interface PdfRenderPageAnnotationOptions extends PdfRenderOptions {

packages/plugin-render/src/lib/render-plugin.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ export class RenderPlugin extends BasePlugin<RenderPluginConfig, RenderCapabilit
1616
static readonly id = 'render' as const;
1717

1818
private readonly refreshPages$ = createEmitter<number[]>();
19-
private initForms = false;
19+
private withForms = false;
20+
private withAnnotations = false;
2021

2122
constructor(id: string, registry: PluginRegistry) {
2223
super(id, registry);
@@ -27,7 +28,8 @@ export class RenderPlugin extends BasePlugin<RenderPluginConfig, RenderCapabilit
2728
}
2829

2930
async initialize(config: RenderPluginConfig): Promise<void> {
30-
this.initForms = config.initForms ?? false;
31+
this.withForms = config.withForms ?? false;
32+
this.withAnnotations = config.withAnnotations ?? false;
3133
}
3234

3335
protected buildCapability(): RenderCapability {
@@ -55,7 +57,8 @@ export class RenderPlugin extends BasePlugin<RenderPluginConfig, RenderCapabilit
5557

5658
const mergedOptions = {
5759
...(options ?? {}),
58-
renderForms: options?.renderForms ?? this.initForms,
60+
withForms: options?.withForms ?? this.withForms,
61+
withAnnotations: options?.withAnnotations ?? this.withAnnotations,
5962
};
6063

6164
return this.engine.renderPage(coreState.document, page, mergedOptions);
@@ -75,7 +78,8 @@ export class RenderPlugin extends BasePlugin<RenderPluginConfig, RenderCapabilit
7578

7679
const mergedOptions = {
7780
...(options ?? {}),
78-
renderForms: options?.renderForms ?? this.initForms,
81+
withForms: options?.withForms ?? this.withForms,
82+
withAnnotations: options?.withAnnotations ?? this.withAnnotations,
7983
};
8084

8185
return this.engine.renderPageRect(coreState.document, page, rect, mergedOptions);

packages/plugin-render/src/lib/types.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,12 @@ export interface RenderPluginConfig extends BasePluginConfig {
66
* Initialize and draw form widgets during renders.
77
* Defaults to `false`.
88
*/
9-
initForms?: boolean;
9+
withForms?: boolean;
10+
/**
11+
* Whether to render annotations
12+
* Defaults to `false`.
13+
*/
14+
withAnnotations?: boolean;
1015
}
1116

1217
export interface RenderPageRectOptions {

0 commit comments

Comments
 (0)