@embedpdf/angular 3.0.0-next.14 → 3.0.0-next.16
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 +309 -0
- package/dist/README.md +309 -0
- package/dist/actions/index.d.ts +34 -16
- package/dist/anchored/index.d.ts +67 -0
- package/dist/annotation/index.d.ts +602 -0
- package/dist/attachment/index.d.ts +29 -0
- package/dist/commands/index.d.ts +109 -0
- package/dist/fesm2022/embedpdf-angular-actions.mjs +117 -36
- package/dist/fesm2022/embedpdf-angular-actions.mjs.map +1 -1
- package/dist/fesm2022/embedpdf-angular-anchored.mjs +148 -0
- package/dist/fesm2022/embedpdf-angular-anchored.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-annotation.mjs +1933 -0
- package/dist/fesm2022/embedpdf-angular-annotation.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-attachment.mjs +67 -0
- package/dist/fesm2022/embedpdf-angular-attachment.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-commands.mjs +235 -0
- package/dist/fesm2022/embedpdf-angular-commands.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-form.mjs +1074 -0
- package/dist/fesm2022/embedpdf-angular-form.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-history.mjs +54 -0
- package/dist/fesm2022/embedpdf-angular-history.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-i18n.mjs +100 -0
- package/dist/fesm2022/embedpdf-angular-i18n.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-interaction.mjs +157 -0
- package/dist/fesm2022/embedpdf-angular-interaction.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-link.mjs +306 -0
- package/dist/fesm2022/embedpdf-angular-link.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-measurement.mjs +106 -0
- package/dist/fesm2022/embedpdf-angular-measurement.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-metadata.mjs +77 -0
- package/dist/fesm2022/embedpdf-angular-metadata.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-outline.mjs +76 -0
- package/dist/fesm2022/embedpdf-angular-outline.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-page-edit.mjs +68 -0
- package/dist/fesm2022/embedpdf-angular-page-edit.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-page-view.mjs +297 -0
- package/dist/fesm2022/embedpdf-angular-page-view.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-redaction.mjs +93 -0
- package/dist/fesm2022/embedpdf-angular-redaction.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-render.mjs +331 -69
- package/dist/fesm2022/embedpdf-angular-render.mjs.map +1 -1
- package/dist/fesm2022/embedpdf-angular-runtime.mjs +1151 -390
- package/dist/fesm2022/embedpdf-angular-runtime.mjs.map +1 -1
- package/dist/fesm2022/embedpdf-angular-search.mjs +251 -0
- package/dist/fesm2022/embedpdf-angular-search.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-selection.mjs +477 -0
- package/dist/fesm2022/embedpdf-angular-selection.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-shell.mjs +177 -0
- package/dist/fesm2022/embedpdf-angular-shell.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-signature.mjs +120 -0
- package/dist/fesm2022/embedpdf-angular-signature.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-stage.mjs +688 -288
- package/dist/fesm2022/embedpdf-angular-stage.mjs.map +1 -1
- package/dist/fesm2022/embedpdf-angular-stamp.mjs +169 -0
- package/dist/fesm2022/embedpdf-angular-stamp.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-testing.mjs +89 -0
- package/dist/fesm2022/embedpdf-angular-testing.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-toolbar.mjs +1123 -0
- package/dist/fesm2022/embedpdf-angular-toolbar.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular-view-manager.mjs +69 -0
- package/dist/fesm2022/embedpdf-angular-view-manager.mjs.map +1 -0
- package/dist/fesm2022/embedpdf-angular.mjs +25 -3
- package/dist/fesm2022/embedpdf-angular.mjs.map +1 -1
- package/dist/form/index.d.ts +79 -0
- package/dist/history/index.d.ts +28 -0
- package/dist/i18n/index.d.ts +52 -0
- package/dist/index.d.ts +22 -0
- package/dist/interaction/index.d.ts +58 -0
- package/dist/link/index.d.ts +77 -0
- package/dist/measurement/index.d.ts +46 -0
- package/dist/metadata/index.d.ts +51 -0
- package/dist/outline/index.d.ts +32 -0
- package/dist/page-edit/index.d.ts +27 -0
- package/dist/page-view/index.d.ts +94 -0
- package/dist/redaction/index.d.ts +38 -0
- package/dist/render/index.d.ts +45 -6
- package/dist/runtime/index.d.ts +579 -199
- package/dist/search/index.d.ts +71 -0
- package/dist/selection/index.d.ts +141 -0
- package/dist/shell/index.d.ts +88 -0
- package/dist/signature/index.d.ts +45 -0
- package/dist/stage/index.d.ts +242 -141
- package/dist/stamp/index.d.ts +58 -0
- package/dist/testing/index.d.ts +53 -0
- package/dist/toolbar/index.d.ts +257 -0
- package/dist/view-manager/index.d.ts +23 -0
- package/package.json +145 -14
|
@@ -1,119 +1,381 @@
|
|
|
1
|
-
import { RenderToken } from '@embedpdf/plugin-render';
|
|
1
|
+
import { RenderToken, renderPlugin } from '@embedpdf/plugin-render';
|
|
2
2
|
export * from '@embedpdf/plugin-render';
|
|
3
|
-
import { isPlatformBrowser } from '@angular/common';
|
|
4
3
|
import * as i0 from '@angular/core';
|
|
5
|
-
import {
|
|
6
|
-
import { injectPage,
|
|
4
|
+
import { Injectable, input, inject, ElementRef, computed, effect, untracked, Directive, signal, ChangeDetectionStrategy, Component, viewChild, PLATFORM_ID } from '@angular/core';
|
|
5
|
+
import { pluginService, CapabilityBinding, injectKernelHost, injectPage, devWarn, injectPaintedParts } from '@embedpdf/angular/runtime';
|
|
6
|
+
import { isPlatformBrowser } from '@angular/common';
|
|
7
|
+
import { RenderToken as RenderToken$1 } from '@embedpdf/plugin-render/contract/host';
|
|
8
|
+
import { bindPaintedImage, pictureLayerOptionsOf, partsDrawnTwice } from '@embedpdf/web';
|
|
7
9
|
|
|
8
10
|
/**
|
|
9
|
-
*
|
|
11
|
+
* The render plugin's service and feature:
|
|
10
12
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
* withRender(options) the plugin, for provideEmbedPdf()
|
|
14
|
+
* inject(EpdfRender) pictures of pages on demand (`renderPage`, `renderPages`), redraws
|
|
15
|
+
* (`invalidate`, `invalidated$`), and the settings (`settings()`)
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Pictures of pages, apart from the Stage: a thumbnail, a page at an exact width, every page in
|
|
19
|
+
* batches. `invalidate()` redraws pages, `invalidated$` tells you when they were, and
|
|
20
|
+
* `settings()` / `updateSettings()` are the picture budget and tiles.
|
|
16
21
|
*/
|
|
22
|
+
class EpdfRender extends pluginService({
|
|
23
|
+
name: 'EpdfRender',
|
|
24
|
+
feature: 'withRender()',
|
|
25
|
+
token: RenderToken,
|
|
26
|
+
methods: [
|
|
27
|
+
'canRender',
|
|
28
|
+
'renderPage',
|
|
29
|
+
'renderThumbnail',
|
|
30
|
+
'renderPages',
|
|
31
|
+
'getRenderPolicy',
|
|
32
|
+
'getRenderEpoch',
|
|
33
|
+
'invalidate',
|
|
34
|
+
],
|
|
35
|
+
events: ['onInvalidated'],
|
|
36
|
+
}) {
|
|
37
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: EpdfRender, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
38
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: EpdfRender, providedIn: 'root' });
|
|
39
|
+
}
|
|
40
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: EpdfRender, decorators: [{
|
|
41
|
+
type: Injectable,
|
|
42
|
+
args: [{ providedIn: 'root' }]
|
|
43
|
+
}] });
|
|
44
|
+
/** The render plugin, with its settings: `withRender({ fullPage: { maxWidth: 1280 } })`. */
|
|
45
|
+
function withRender(options) {
|
|
46
|
+
return { plugins: [renderPlugin(options)], services: [EpdfRender] };
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* `<epdf-render-layer>`: the page's picture, in two planes.
|
|
51
|
+
*
|
|
52
|
+
* - The base: one picture of the whole page, at the size the render plugin resolves (the
|
|
53
|
+
* settled demand within the pixel budget on a local engine, the advertised ladder on a
|
|
54
|
+
* cloud one). Always there; the instant backdrop.
|
|
55
|
+
* - The tiles: sharper pieces above it, when the view wants more pixels than the base may
|
|
56
|
+
* spend. A thumbnail-sized demand engages none: the arithmetic is the configuration.
|
|
57
|
+
*
|
|
58
|
+
* The layer only paints: plain images, bound with `@embedpdf/web`'s painted-image helper, which
|
|
59
|
+
* reports each tile painted after the browser could show it. What to fetch, when to settle,
|
|
60
|
+
* what to keep and when to let go are all the render plugin's; mid-gesture the pictures are
|
|
61
|
+
* simply scaled with the page until the plugin hands down new ones.
|
|
62
|
+
*/
|
|
63
|
+
const NO_PAINT_SETTINGS = Object.freeze({ tiles: false });
|
|
64
|
+
const NO_PLAN = Object.freeze({
|
|
65
|
+
engaged: false,
|
|
66
|
+
paint: [],
|
|
67
|
+
fetching: [],
|
|
68
|
+
stamp: '',
|
|
69
|
+
});
|
|
70
|
+
/** The render plugin's host side, for the document the page belongs to. */
|
|
71
|
+
const renderOf = (page, what) => new CapabilityBinding(injectKernelHost(what), () => RenderToken$1, () => page.documentId);
|
|
72
|
+
/**
|
|
73
|
+
* One tile: binds the painted-image helper to the element for the tile's picture. The helper
|
|
74
|
+
* hides the image until it's loaded, tells the tile's view it's painted after the browser could
|
|
75
|
+
* show it, and unpainted when the element goes.
|
|
76
|
+
*/
|
|
77
|
+
class EpdfTileImage {
|
|
78
|
+
tile = input.required(...(ngDevMode ? [{ debugName: "tile", alias: 'epdfTile' }] : [{ alias: 'epdfTile' }]));
|
|
79
|
+
/** The view the tile is painted for; it hears when the picture is painted and when it goes. */
|
|
80
|
+
view = input.required(...(ngDevMode ? [{ debugName: "view", alias: 'epdfTileView' }] : [{ alias: 'epdfTileView' }]));
|
|
81
|
+
constructor() {
|
|
82
|
+
const element = inject(ElementRef).nativeElement;
|
|
83
|
+
const page = injectPage('<epdf-render-layer>');
|
|
84
|
+
// Bound again only for a new picture, not for every new plan that holds the same one.
|
|
85
|
+
const handle = computed(() => this.tile().handle, ...(ngDevMode ? [{ debugName: "handle" }] : []));
|
|
86
|
+
// The view is told directly, not through outputs: the picture goes when the element does,
|
|
87
|
+
// and an output emitted while its directive is destroyed is dropped.
|
|
88
|
+
effect((onCleanup) => {
|
|
89
|
+
const picture = handle();
|
|
90
|
+
const view = this.view();
|
|
91
|
+
const key = untracked(this.tile).key;
|
|
92
|
+
onCleanup(bindPaintedImage(element, picture, {
|
|
93
|
+
onPainted: () => view?.markPainted(page.ref, key),
|
|
94
|
+
onUnpainted: () => view?.markUnpainted(page.ref, key),
|
|
95
|
+
}));
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: EpdfTileImage, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
99
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.2.4", type: EpdfTileImage, isStandalone: true, selector: "img[epdfTile]", inputs: { tile: { classPropertyName: "tile", publicName: "epdfTile", isSignal: true, isRequired: true, transformFunction: null }, view: { classPropertyName: "view", publicName: "epdfTileView", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 });
|
|
100
|
+
}
|
|
101
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: EpdfTileImage, decorators: [{
|
|
102
|
+
type: Directive,
|
|
103
|
+
args: [{ selector: 'img[epdfTile]' }]
|
|
104
|
+
}], ctorParameters: () => [] });
|
|
105
|
+
/**
|
|
106
|
+
* The tiles: the render plugin's paint plan for this page in this view, as images keyed by
|
|
107
|
+
* tile. They're placed in view pixels, not in page points under a scaled box: browsers round
|
|
108
|
+
* lengths to 1/64 pixel before transforms apply, and under a 25× zoom that rounding would move
|
|
109
|
+
* each tile by up to half a pixel, showing seams that shift with every zoom step.
|
|
110
|
+
*/
|
|
111
|
+
class EpdfTilePlane {
|
|
112
|
+
layers = input.required(...(ngDevMode ? [{ debugName: "layers" }] : []));
|
|
113
|
+
page = injectPage('<epdf-render-layer>');
|
|
114
|
+
render = renderOf(this.page, '<epdf-render-layer>');
|
|
115
|
+
/**
|
|
116
|
+
* This view's tile surface. Tile state is kept per view and page, so a thumbnail strip's
|
|
117
|
+
* small demand never disturbs the main view's tiles.
|
|
118
|
+
*/
|
|
119
|
+
view = signal(null, ...(ngDevMode ? [{ debugName: "view" }] : []));
|
|
120
|
+
/**
|
|
121
|
+
* Which page this plane plans for: a new value only when the page changes (a page view can be
|
|
122
|
+
* given another page), never with the camera.
|
|
123
|
+
*/
|
|
124
|
+
pageRef = computed(() => this.page.ref, ...(ngDevMode ? [{ debugName: "pageRef" }] : []));
|
|
125
|
+
plan = this.render.host.read(() => this.view()?.getPlan(this.pageRef()) ?? NO_PLAN, () => NO_PLAN);
|
|
126
|
+
constructor() {
|
|
127
|
+
// The page's claim on the view, let go of when the page changes or the plane goes: that
|
|
128
|
+
// stops what's still being fetched for it, and what arrived stays cached. Before the view's
|
|
129
|
+
// own effect, so as the plane goes the page is released before the view is disposed.
|
|
130
|
+
effect((onCleanup) => {
|
|
131
|
+
const view = this.view();
|
|
132
|
+
const page = this.pageRef();
|
|
133
|
+
if (view)
|
|
134
|
+
onCleanup(() => view.release(page));
|
|
135
|
+
});
|
|
136
|
+
effect((onCleanup) => {
|
|
137
|
+
const render = this.render.capability();
|
|
138
|
+
if (!render)
|
|
139
|
+
return;
|
|
140
|
+
const view = untracked(() => render.createViewDemand(this.page.view));
|
|
141
|
+
this.view.set(view);
|
|
142
|
+
onCleanup(() => {
|
|
143
|
+
view.dispose();
|
|
144
|
+
this.view.set(null);
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
// What the view wants, on every camera frame: setting it is the one call that plans and
|
|
148
|
+
// fetches; reading the paint plan above is pure.
|
|
149
|
+
effect(() => {
|
|
150
|
+
const view = this.view();
|
|
151
|
+
const page = this.pageRef();
|
|
152
|
+
const transform = this.page.transform();
|
|
153
|
+
const layers = this.layers();
|
|
154
|
+
if (!view)
|
|
155
|
+
return;
|
|
156
|
+
untracked(() => {
|
|
157
|
+
const demand = this.page.getViewDemand?.() ?? {
|
|
158
|
+
desiredDeviceWidth: transform.deviceWidth,
|
|
159
|
+
};
|
|
160
|
+
view.setDemand(page, demand, layers);
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
/** A picture whose size doesn't match its box would be stretched into place: a stale tile. */
|
|
165
|
+
checkSize(event, tile) {
|
|
166
|
+
const naturalWidth = event.target.naturalWidth;
|
|
167
|
+
const expected = Math.round(tile.rect.width * tile.scale);
|
|
168
|
+
if (naturalWidth > 0 && Math.abs(naturalWidth - expected) > 1) {
|
|
169
|
+
devWarn('tile-size', `[render] tile picture ${naturalWidth}px wide does not match its box (expected ` +
|
|
170
|
+
`~${expected}px): a stale picture? key=${tile.key}`);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: EpdfTilePlane, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
174
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.4", type: EpdfTilePlane, isStandalone: true, selector: "epdf-tile-plane", inputs: { layers: { classPropertyName: "layers", publicName: "layers", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
|
|
175
|
+
@if (plan().paint.length > 0) {
|
|
176
|
+
<!-- Its own stacking context: the tiles' z-index ranks stay inside it, below the
|
|
177
|
+
annotations and the page chrome, even mid-zoom while coarse and sharp tiles mix. -->
|
|
178
|
+
<div
|
|
179
|
+
style="position: absolute; left: 0; top: 0; pointer-events: none; isolation: isolate"
|
|
180
|
+
[style.width.px]="page.transform().contentWidth"
|
|
181
|
+
[style.height.px]="page.transform().contentHeight"
|
|
182
|
+
>
|
|
183
|
+
@for (tile of plan().paint; track tile.key) {
|
|
184
|
+
<img
|
|
185
|
+
alt=""
|
|
186
|
+
draggable="false"
|
|
187
|
+
style="position: absolute"
|
|
188
|
+
[epdfTile]="tile"
|
|
189
|
+
[epdfTileView]="view()"
|
|
190
|
+
[style.left.px]="tile.rect.x * page.transform().viewScale"
|
|
191
|
+
[style.top.px]="tile.rect.y * page.transform().viewScale"
|
|
192
|
+
[style.width.px]="tile.rect.width * page.transform().viewScale"
|
|
193
|
+
[style.height.px]="tile.rect.height * page.transform().viewScale"
|
|
194
|
+
[style.z-index]="tile.z"
|
|
195
|
+
(load)="checkSize($event, tile)"
|
|
196
|
+
/>
|
|
197
|
+
}
|
|
198
|
+
</div>
|
|
199
|
+
}
|
|
200
|
+
`, isInline: true, dependencies: [{ kind: "directive", type: EpdfTileImage, selector: "img[epdfTile]", inputs: ["epdfTile", "epdfTileView"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
201
|
+
}
|
|
202
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: EpdfTilePlane, decorators: [{
|
|
203
|
+
type: Component,
|
|
204
|
+
args: [{
|
|
205
|
+
selector: 'epdf-tile-plane',
|
|
206
|
+
imports: [EpdfTileImage],
|
|
207
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
208
|
+
template: `
|
|
209
|
+
@if (plan().paint.length > 0) {
|
|
210
|
+
<!-- Its own stacking context: the tiles' z-index ranks stay inside it, below the
|
|
211
|
+
annotations and the page chrome, even mid-zoom while coarse and sharp tiles mix. -->
|
|
212
|
+
<div
|
|
213
|
+
style="position: absolute; left: 0; top: 0; pointer-events: none; isolation: isolate"
|
|
214
|
+
[style.width.px]="page.transform().contentWidth"
|
|
215
|
+
[style.height.px]="page.transform().contentHeight"
|
|
216
|
+
>
|
|
217
|
+
@for (tile of plan().paint; track tile.key) {
|
|
218
|
+
<img
|
|
219
|
+
alt=""
|
|
220
|
+
draggable="false"
|
|
221
|
+
style="position: absolute"
|
|
222
|
+
[epdfTile]="tile"
|
|
223
|
+
[epdfTileView]="view()"
|
|
224
|
+
[style.left.px]="tile.rect.x * page.transform().viewScale"
|
|
225
|
+
[style.top.px]="tile.rect.y * page.transform().viewScale"
|
|
226
|
+
[style.width.px]="tile.rect.width * page.transform().viewScale"
|
|
227
|
+
[style.height.px]="tile.rect.height * page.transform().viewScale"
|
|
228
|
+
[style.z-index]="tile.z"
|
|
229
|
+
(load)="checkSize($event, tile)"
|
|
230
|
+
/>
|
|
231
|
+
}
|
|
232
|
+
</div>
|
|
233
|
+
}
|
|
234
|
+
`,
|
|
235
|
+
}]
|
|
236
|
+
}], ctorParameters: () => [] });
|
|
17
237
|
class EpdfRenderLayer {
|
|
18
238
|
/**
|
|
19
|
-
*
|
|
20
|
-
*
|
|
239
|
+
* Draw the annotations into the page's picture (`true`) or leave them out (`false`). Left
|
|
240
|
+
* unset, the picture leaves them to an `<epdf-annotation-layer>` on the page, and otherwise
|
|
241
|
+
* draws them when the user may read them.
|
|
242
|
+
*/
|
|
243
|
+
annotations = input(undefined, ...(ngDevMode ? [{ debugName: "annotations" }] : []));
|
|
244
|
+
/** The same for the form fields, which an `<epdf-form-layer>` paints. */
|
|
245
|
+
formFields = input(undefined, ...(ngDevMode ? [{ debugName: "formFields" }] : []));
|
|
246
|
+
/**
|
|
247
|
+
* The sharp tiles over the picture when zoomed in (default true). Whether they cost anything
|
|
248
|
+
* is decided by what the view wants; set it to false only for a view that must never tile.
|
|
249
|
+
*/
|
|
250
|
+
tiles = input(true, ...(ngDevMode ? [{ debugName: "tiles" }] : []));
|
|
251
|
+
page = injectPage('<epdf-render-layer>');
|
|
252
|
+
render = renderOf(this.page, '<epdf-render-layer>');
|
|
253
|
+
/** The same object until a setting it reads changes. */
|
|
254
|
+
paintSettings = this.render.select((render) => render.getPaintSettings(), NO_PAINT_SETTINGS, Object.is);
|
|
255
|
+
parts = computed(() => ({
|
|
256
|
+
annotations: this.annotations(),
|
|
257
|
+
formFields: this.formFields(),
|
|
258
|
+
}), ...(ngDevMode ? [{ debugName: "parts" }] : []));
|
|
259
|
+
painted = injectPaintedParts(() => this.page.ref);
|
|
260
|
+
may = this.render.select((render) => render.getLayerRights(), null, Object.is);
|
|
261
|
+
/** The parts the picture draws; `null` until the page's layers have said what they paint. */
|
|
262
|
+
layers = computed(() => {
|
|
263
|
+
const painted = this.painted();
|
|
264
|
+
const may = this.may();
|
|
265
|
+
return painted && may ? pictureLayerOptionsOf(painted, this.parts(), may) : null;
|
|
266
|
+
}, ...(ngDevMode ? [{ debugName: "layers" }] : []));
|
|
267
|
+
/**
|
|
268
|
+
* The picture's identity: its size, the parts it draws and the page's version. Within a
|
|
269
|
+
* size step it doesn't move as you zoom (the page's transform scales the picture), so
|
|
270
|
+
* nothing is fetched again; it moves at a step and when the page changes.
|
|
21
271
|
*/
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
// materialized before publish, so the key is always computable.
|
|
33
|
-
sourceKey = injectSelector(RenderToken, (c) => c.renderSourceKey(this.page.pon, {
|
|
34
|
-
scale: this.page.transform().renderScale,
|
|
35
|
-
includeAnnotations: this.annotations(),
|
|
36
|
-
}));
|
|
37
|
-
src = signal(null, ...(ngDevMode ? [{ debugName: "src" }] : []));
|
|
272
|
+
sourceKey = this.render.select((render) => {
|
|
273
|
+
const layers = this.layers();
|
|
274
|
+
return layers
|
|
275
|
+
? render.getSourceKey(this.page.ref, {
|
|
276
|
+
scale: this.page.transform().renderScale,
|
|
277
|
+
...layers,
|
|
278
|
+
})
|
|
279
|
+
: null;
|
|
280
|
+
}, null, Object.is);
|
|
281
|
+
picture = viewChild.required('picture');
|
|
38
282
|
constructor() {
|
|
283
|
+
effect(() => {
|
|
284
|
+
const painted = this.painted();
|
|
285
|
+
if (painted && partsDrawnTwice(painted, this.parts()).length > 0) {
|
|
286
|
+
devWarn('render-layer-draws-what-a-layer-paints', '<epdf-render-layer [annotations]> or [formFields] draws what an ' +
|
|
287
|
+
'<epdf-annotation-layer> or an <epdf-form-layer> on the page paints too, so it shows ' +
|
|
288
|
+
'twice. Leave the input out: the picture leaves out what a layer paints.');
|
|
289
|
+
}
|
|
290
|
+
});
|
|
39
291
|
if (!isPlatformBrowser(inject(PLATFORM_ID)))
|
|
40
292
|
return;
|
|
41
293
|
effect((onCleanup) => {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
this.sourceKey();
|
|
48
|
-
const includeAnnotations = this.annotations();
|
|
294
|
+
const render = this.render.capability();
|
|
295
|
+
const key = this.sourceKey();
|
|
296
|
+
const layers = this.layers();
|
|
297
|
+
if (!render || key === null || !layers)
|
|
298
|
+
return;
|
|
49
299
|
const controller = new AbortController();
|
|
50
300
|
let revoke;
|
|
51
301
|
onCleanup(() => {
|
|
52
302
|
controller.abort();
|
|
53
303
|
revoke?.();
|
|
54
304
|
});
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
objectUrl.revoke();
|
|
70
|
-
return;
|
|
71
|
-
}
|
|
72
|
-
revoke = objectUrl.revoke;
|
|
73
|
-
this.src.set(objectUrl.url);
|
|
305
|
+
// Any scale inside this key's step asks for this key's picture, so reading it now is safe.
|
|
306
|
+
const scale = untracked(() => this.page.transform().renderScale);
|
|
307
|
+
void (async () => {
|
|
308
|
+
try {
|
|
309
|
+
const image = await render.renderSource(this.page.ref, {
|
|
310
|
+
scale,
|
|
311
|
+
...layers,
|
|
312
|
+
view: this.page.view,
|
|
313
|
+
signal: controller.signal,
|
|
314
|
+
});
|
|
315
|
+
const objectUrl = await image.objectUrl().abortWith(controller.signal);
|
|
316
|
+
if (controller.signal.aborted) {
|
|
317
|
+
objectUrl.revoke();
|
|
318
|
+
return;
|
|
74
319
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
320
|
+
revoke = objectUrl.revoke;
|
|
321
|
+
// Set on the element now, not through a binding. A binding applies at the next change
|
|
322
|
+
// detection, and the key can move on before that, revoking this URL: the image would
|
|
323
|
+
// then be handed a revoked URL and lose its picture. Set at once, the browser keeps
|
|
324
|
+
// showing the old picture until the new one is decoded and never asks for the old URL
|
|
325
|
+
// again, so revoking it when the next one comes is safe.
|
|
326
|
+
this.picture().nativeElement.src = objectUrl.url;
|
|
327
|
+
}
|
|
328
|
+
catch {
|
|
329
|
+
// Cancelled (the camera moved on, the layer went away) or the render failed.
|
|
330
|
+
}
|
|
331
|
+
})();
|
|
80
332
|
});
|
|
81
333
|
}
|
|
82
334
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: EpdfRenderLayer, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
83
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.
|
|
335
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.4", type: EpdfRenderLayer, isStandalone: true, selector: "epdf-render-layer", inputs: { annotations: { classPropertyName: "annotations", publicName: "annotations", isSignal: true, isRequired: false, transformFunction: null }, formFields: { classPropertyName: "formFields", publicName: "formFields", isSignal: true, isRequired: false, transformFunction: null }, tiles: { classPropertyName: "tiles", publicName: "tiles", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "picture", first: true, predicate: ["picture"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
84
336
|
<img
|
|
337
|
+
#picture
|
|
85
338
|
alt=""
|
|
86
339
|
draggable="false"
|
|
87
|
-
|
|
88
|
-
style="position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none;"
|
|
340
|
+
style="position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none"
|
|
89
341
|
/>
|
|
90
|
-
|
|
342
|
+
@if (tiles() && paintSettings().tiles && layers(); as drawn) {
|
|
343
|
+
<epdf-tile-plane [layers]="drawn" />
|
|
344
|
+
}
|
|
345
|
+
`, isInline: true, dependencies: [{ kind: "component", type: EpdfTilePlane, selector: "epdf-tile-plane", inputs: ["layers"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
91
346
|
}
|
|
92
347
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.4", ngImport: i0, type: EpdfRenderLayer, decorators: [{
|
|
93
348
|
type: Component,
|
|
94
349
|
args: [{
|
|
95
350
|
selector: 'epdf-render-layer',
|
|
96
|
-
|
|
351
|
+
imports: [EpdfTilePlane],
|
|
97
352
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
98
353
|
template: `
|
|
99
354
|
<img
|
|
355
|
+
#picture
|
|
100
356
|
alt=""
|
|
101
357
|
draggable="false"
|
|
102
|
-
|
|
103
|
-
style="position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none;"
|
|
358
|
+
style="position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none"
|
|
104
359
|
/>
|
|
360
|
+
@if (tiles() && paintSettings().tiles && layers(); as drawn) {
|
|
361
|
+
<epdf-tile-plane [layers]="drawn" />
|
|
362
|
+
}
|
|
105
363
|
`,
|
|
106
364
|
}]
|
|
107
365
|
}], ctorParameters: () => [] });
|
|
108
366
|
|
|
109
367
|
/**
|
|
110
|
-
* @embedpdf/angular/render
|
|
368
|
+
* @embedpdf/angular/render: the page pictures.
|
|
369
|
+
*
|
|
370
|
+
* withRender(options) the plugin, for provideEmbedPdf()
|
|
371
|
+
* inject(EpdfRender) pictures on demand, redraws, the settings
|
|
372
|
+
* <epdf-render-layer> the picture of each page on a Stage
|
|
111
373
|
*/
|
|
112
|
-
//
|
|
374
|
+
// The plugin's types and helpers, so app code has one import for the feature.
|
|
113
375
|
|
|
114
376
|
/**
|
|
115
377
|
* Generated bundle index. Do not edit.
|
|
116
378
|
*/
|
|
117
379
|
|
|
118
|
-
export { EpdfRenderLayer };
|
|
380
|
+
export { EpdfRender, EpdfRenderLayer, withRender };
|
|
119
381
|
//# sourceMappingURL=embedpdf-angular-render.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"embedpdf-angular-render.mjs","sources":["../../render/src/render-layer.ts","../../render/src/public_api.ts","../../render/src/embedpdf-angular-render.ts"],"sourcesContent":["/**\n * `<epdf-render-layer>` — the Angular view of @embedpdf/plugin-render.\n *\n * Paints a page to an `<img>` from the engine's ENCODED image() (identical for\n * local & cloud). Abortable (cancels when the camera moves / the layer is\n * destroyed) and leak-free (revokes the object URL). React's useEffect deps\n * become `effect()` auto-tracking: scale, the annotations input, and the\n * render epoch are the tracked reads; everything else is untracked.\n */\nimport { isPlatformBrowser } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n effect,\n inject,\n input,\n PLATFORM_ID,\n signal,\n untracked,\n} from '@angular/core';\nimport { RenderToken } from '@embedpdf/plugin-render';\nimport { injectCapability, injectPage, injectSelector } from '@embedpdf/angular/runtime';\n\n@Component({\n selector: 'epdf-render-layer',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <img\n alt=\"\"\n draggable=\"false\"\n [attr.src]=\"src()\"\n style=\"position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none;\"\n />\n `,\n})\nexport class EpdfRenderLayer {\n /**\n * Bake annotations into the page bitmap (default true). Pass false when an\n * annotation layer owns annotation rendering, so they aren't drawn twice.\n */\n readonly annotations = input(true);\n\n private readonly page = injectPage();\n private readonly render = injectCapability(RenderToken);\n // ONE tracked dependency: the raster's canonical identity — conformed\n // viewport + annotations flag + epoch.\n // Inside a lattice rung, zoom changes don't move it: no refetch, no DOM\n // churn — the stage's CSS transform does the scaling. It changes exactly at\n // rung crossings and on CONFIRMED mutations (epoch bumps at commit, never\n // mid-gesture). Under `continuous` it embeds the exact scale — v2 behavior\n // byte-for-byte. The policy behind it is a document fact the kernel\n // materialized before publish, so the key is always computable.\n private readonly sourceKey = injectSelector(RenderToken, (c) =>\n c.renderSourceKey(this.page.pon, {\n scale: this.page.transform().renderScale,\n includeAnnotations: this.annotations(),\n }),\n );\n protected readonly src = signal<string | null>(null);\n\n constructor() {\n if (!isPlatformBrowser(inject(PLATFORM_ID))) return;\n effect((onCleanup) => {\n // Tracked reads — the effect's dependency set. `sourceKey` folds scale,\n // annotations, and the epoch into one identity; a stale scale read\n // inside the untracked body is harmless by construction (any scale in\n // this rung produces this key's canonical request).\n const render = this.render();\n this.sourceKey();\n const includeAnnotations = this.annotations();\n\n const controller = new AbortController();\n let revoke: (() => void) | undefined;\n onCleanup(() => {\n controller.abort();\n revoke?.();\n });\n\n untracked(() => {\n const scale = this.page.transform().renderScale;\n void (async () => {\n try {\n // The capability conforms this to the policy (lattice → ladder\n // width, continuous → this exact scale) and collapses same-key\n // asks in its raster store.\n const image = await render.renderPage(this.page.pon, {\n scale,\n includeAnnotations,\n signal: controller.signal,\n });\n const objectUrl = await image.objectUrl(controller.signal);\n if (controller.signal.aborted) {\n objectUrl.revoke();\n return;\n }\n revoke = objectUrl.revoke;\n this.src.set(objectUrl.url);\n } catch {\n /* aborted (camera moved / destroyed) or render failed */\n }\n })();\n });\n });\n }\n}\n","/**\n * @embedpdf/angular/render — `<epdf-render-layer>`.\n */\n\n// One-line-per-feature: registration travels with the UI.\nexport * from '@embedpdf/plugin-render';\nexport * from './render-layer';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"embedpdf-angular-render.mjs","sources":["../../render/src/render.ts","../../render/src/render-layer.ts","../../render/src/public_api.ts","../../render/src/embedpdf-angular-render.ts"],"sourcesContent":["/**\n * The render plugin's service and feature:\n *\n * withRender(options) the plugin, for provideEmbedPdf()\n * inject(EpdfRender) pictures of pages on demand (`renderPage`, `renderPages`), redraws\n * (`invalidate`, `invalidated$`), and the settings (`settings()`)\n */\nimport { Injectable } from '@angular/core';\nimport { pluginService, type EmbedPdfFeature } from '@embedpdf/angular/runtime';\nimport { renderPlugin, RenderToken, type RenderConfig } from '@embedpdf/plugin-render';\n\n/**\n * Pictures of pages, apart from the Stage: a thumbnail, a page at an exact width, every page in\n * batches. `invalidate()` redraws pages, `invalidated$` tells you when they were, and\n * `settings()` / `updateSettings()` are the picture budget and tiles.\n */\n@Injectable({ providedIn: 'root' })\nexport class EpdfRender extends pluginService({\n name: 'EpdfRender',\n feature: 'withRender()',\n token: RenderToken,\n methods: [\n 'canRender',\n 'renderPage',\n 'renderThumbnail',\n 'renderPages',\n 'getRenderPolicy',\n 'getRenderEpoch',\n 'invalidate',\n ],\n events: ['onInvalidated'],\n}) {}\n\n/** The render plugin, with its settings: `withRender({ fullPage: { maxWidth: 1280 } })`. */\nexport function withRender(options?: RenderConfig): EmbedPdfFeature {\n return { plugins: [renderPlugin(options)], services: [EpdfRender] };\n}\n","/**\n * `<epdf-render-layer>`: the page's picture, in two planes.\n *\n * - The base: one picture of the whole page, at the size the render plugin resolves (the\n * settled demand within the pixel budget on a local engine, the advertised ladder on a\n * cloud one). Always there; the instant backdrop.\n * - The tiles: sharper pieces above it, when the view wants more pixels than the base may\n * spend. A thumbnail-sized demand engages none: the arithmetic is the configuration.\n *\n * The layer only paints: plain images, bound with `@embedpdf/web`'s painted-image helper, which\n * reports each tile painted after the browser could show it. What to fetch, when to settle,\n * what to keep and when to let go are all the render plugin's; mid-gesture the pictures are\n * simply scaled with the page until the plugin hands down new ones.\n */\nimport { isPlatformBrowser } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n Directive,\n effect,\n ElementRef,\n inject,\n input,\n PLATFORM_ID,\n signal,\n untracked,\n viewChild,\n} from '@angular/core';\nimport {\n RenderToken,\n type PageLayerOptions,\n type PaintSettings,\n type RenderHostCapability,\n type TilePaintPlan,\n type TilePaintSource,\n type ViewDemand,\n} from '@embedpdf/plugin-render/contract/host';\nimport { bindPaintedImage, partsDrawnTwice, pictureLayerOptionsOf } from '@embedpdf/web';\nimport {\n CapabilityBinding,\n devWarn,\n injectKernelHost,\n injectPage,\n injectPaintedParts,\n type EpdfPageContext,\n} from '@embedpdf/angular/runtime';\n\nconst NO_PAINT_SETTINGS: PaintSettings = Object.freeze({ tiles: false });\nconst NO_PLAN: TilePaintPlan = Object.freeze({\n engaged: false,\n paint: [],\n fetching: [],\n stamp: '',\n});\n\n/** The render plugin's host side, for the document the page belongs to. */\nconst renderOf = (page: EpdfPageContext, what: string) =>\n new CapabilityBinding<RenderHostCapability>(\n injectKernelHost(what),\n () => RenderToken,\n () => page.documentId,\n );\n\n/**\n * One tile: binds the painted-image helper to the element for the tile's picture. The helper\n * hides the image until it's loaded, tells the tile's view it's painted after the browser could\n * show it, and unpainted when the element goes.\n */\n@Directive({ selector: 'img[epdfTile]' })\nexport class EpdfTileImage {\n readonly tile = input.required<TilePaintSource>({ alias: 'epdfTile' });\n /** The view the tile is painted for; it hears when the picture is painted and when it goes. */\n readonly view = input.required<ViewDemand | null>({ alias: 'epdfTileView' });\n\n constructor() {\n const element = inject<ElementRef<HTMLImageElement>>(ElementRef).nativeElement;\n const page = injectPage('<epdf-render-layer>');\n // Bound again only for a new picture, not for every new plan that holds the same one.\n const handle = computed(() => this.tile().handle);\n // The view is told directly, not through outputs: the picture goes when the element does,\n // and an output emitted while its directive is destroyed is dropped.\n effect((onCleanup) => {\n const picture = handle();\n const view = this.view();\n const key = untracked(this.tile).key;\n onCleanup(\n bindPaintedImage(element, picture, {\n onPainted: () => view?.markPainted(page.ref, key),\n onUnpainted: () => view?.markUnpainted(page.ref, key),\n }),\n );\n });\n }\n}\n\n/**\n * The tiles: the render plugin's paint plan for this page in this view, as images keyed by\n * tile. They're placed in view pixels, not in page points under a scaled box: browsers round\n * lengths to 1/64 pixel before transforms apply, and under a 25× zoom that rounding would move\n * each tile by up to half a pixel, showing seams that shift with every zoom step.\n */\n@Component({\n selector: 'epdf-tile-plane',\n imports: [EpdfTileImage],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (plan().paint.length > 0) {\n <!-- Its own stacking context: the tiles' z-index ranks stay inside it, below the\n annotations and the page chrome, even mid-zoom while coarse and sharp tiles mix. -->\n <div\n style=\"position: absolute; left: 0; top: 0; pointer-events: none; isolation: isolate\"\n [style.width.px]=\"page.transform().contentWidth\"\n [style.height.px]=\"page.transform().contentHeight\"\n >\n @for (tile of plan().paint; track tile.key) {\n <img\n alt=\"\"\n draggable=\"false\"\n style=\"position: absolute\"\n [epdfTile]=\"tile\"\n [epdfTileView]=\"view()\"\n [style.left.px]=\"tile.rect.x * page.transform().viewScale\"\n [style.top.px]=\"tile.rect.y * page.transform().viewScale\"\n [style.width.px]=\"tile.rect.width * page.transform().viewScale\"\n [style.height.px]=\"tile.rect.height * page.transform().viewScale\"\n [style.z-index]=\"tile.z\"\n (load)=\"checkSize($event, tile)\"\n />\n }\n </div>\n }\n `,\n})\nexport class EpdfTilePlane {\n readonly layers = input.required<PageLayerOptions>();\n\n protected readonly page = injectPage('<epdf-render-layer>');\n private readonly render = renderOf(this.page, '<epdf-render-layer>');\n /**\n * This view's tile surface. Tile state is kept per view and page, so a thumbnail strip's\n * small demand never disturbs the main view's tiles.\n */\n protected readonly view = signal<ViewDemand | null>(null);\n /**\n * Which page this plane plans for: a new value only when the page changes (a page view can be\n * given another page), never with the camera.\n */\n private readonly pageRef = computed(() => this.page.ref);\n protected readonly plan = this.render.host.read(\n () => this.view()?.getPlan(this.pageRef()) ?? NO_PLAN,\n () => NO_PLAN,\n );\n\n constructor() {\n // The page's claim on the view, let go of when the page changes or the plane goes: that\n // stops what's still being fetched for it, and what arrived stays cached. Before the view's\n // own effect, so as the plane goes the page is released before the view is disposed.\n effect((onCleanup) => {\n const view = this.view();\n const page = this.pageRef();\n if (view) onCleanup(() => view.release(page));\n });\n effect((onCleanup) => {\n const render = this.render.capability();\n if (!render) return;\n const view = untracked(() => render.createViewDemand(this.page.view));\n this.view.set(view);\n onCleanup(() => {\n view.dispose();\n this.view.set(null);\n });\n });\n // What the view wants, on every camera frame: setting it is the one call that plans and\n // fetches; reading the paint plan above is pure.\n effect(() => {\n const view = this.view();\n const page = this.pageRef();\n const transform = this.page.transform();\n const layers = this.layers();\n if (!view) return;\n untracked(() => {\n const demand = this.page.getViewDemand?.() ?? {\n desiredDeviceWidth: transform.deviceWidth,\n };\n view.setDemand(page, demand, layers);\n });\n });\n }\n\n /** A picture whose size doesn't match its box would be stretched into place: a stale tile. */\n protected checkSize(event: Event, tile: TilePaintSource): void {\n const naturalWidth = (event.target as HTMLImageElement).naturalWidth;\n const expected = Math.round(tile.rect.width * tile.scale);\n if (naturalWidth > 0 && Math.abs(naturalWidth - expected) > 1) {\n devWarn(\n 'tile-size',\n `[render] tile picture ${naturalWidth}px wide does not match its box (expected ` +\n `~${expected}px): a stale picture? key=${tile.key}`,\n );\n }\n }\n}\n\n@Component({\n selector: 'epdf-render-layer',\n imports: [EpdfTilePlane],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <img\n #picture\n alt=\"\"\n draggable=\"false\"\n style=\"position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none\"\n />\n @if (tiles() && paintSettings().tiles && layers(); as drawn) {\n <epdf-tile-plane [layers]=\"drawn\" />\n }\n `,\n})\nexport class EpdfRenderLayer {\n /**\n * Draw the annotations into the page's picture (`true`) or leave them out (`false`). Left\n * unset, the picture leaves them to an `<epdf-annotation-layer>` on the page, and otherwise\n * draws them when the user may read them.\n */\n readonly annotations = input<boolean | undefined>(undefined);\n /** The same for the form fields, which an `<epdf-form-layer>` paints. */\n readonly formFields = input<boolean | undefined>(undefined);\n /**\n * The sharp tiles over the picture when zoomed in (default true). Whether they cost anything\n * is decided by what the view wants; set it to false only for a view that must never tile.\n */\n readonly tiles = input(true);\n\n private readonly page = injectPage('<epdf-render-layer>');\n private readonly render = renderOf(this.page, '<epdf-render-layer>');\n /** The same object until a setting it reads changes. */\n protected readonly paintSettings = this.render.select(\n (render) => render.getPaintSettings(),\n NO_PAINT_SETTINGS,\n Object.is,\n );\n private readonly parts = computed(() => ({\n annotations: this.annotations(),\n formFields: this.formFields(),\n }));\n private readonly painted = injectPaintedParts(() => this.page.ref);\n private readonly may = this.render.select((render) => render.getLayerRights(), null, Object.is);\n /** The parts the picture draws; `null` until the page's layers have said what they paint. */\n protected readonly layers = computed(() => {\n const painted = this.painted();\n const may = this.may();\n return painted && may ? pictureLayerOptionsOf(painted, this.parts(), may) : null;\n });\n /**\n * The picture's identity: its size, the parts it draws and the page's version. Within a\n * size step it doesn't move as you zoom (the page's transform scales the picture), so\n * nothing is fetched again; it moves at a step and when the page changes.\n */\n private readonly sourceKey = this.render.select(\n (render) => {\n const layers = this.layers();\n return layers\n ? render.getSourceKey(this.page.ref, {\n scale: this.page.transform().renderScale,\n ...layers,\n })\n : null;\n },\n null,\n Object.is,\n );\n private readonly picture = viewChild.required<ElementRef<HTMLImageElement>>('picture');\n\n constructor() {\n effect(() => {\n const painted = this.painted();\n if (painted && partsDrawnTwice(painted, this.parts()).length > 0) {\n devWarn(\n 'render-layer-draws-what-a-layer-paints',\n '<epdf-render-layer [annotations]> or [formFields] draws what an ' +\n '<epdf-annotation-layer> or an <epdf-form-layer> on the page paints too, so it shows ' +\n 'twice. Leave the input out: the picture leaves out what a layer paints.',\n );\n }\n });\n if (!isPlatformBrowser(inject(PLATFORM_ID))) return;\n effect((onCleanup) => {\n const render = this.render.capability();\n const key = this.sourceKey();\n const layers = this.layers();\n if (!render || key === null || !layers) return;\n const controller = new AbortController();\n let revoke: (() => void) | undefined;\n onCleanup(() => {\n controller.abort();\n revoke?.();\n });\n // Any scale inside this key's step asks for this key's picture, so reading it now is safe.\n const scale = untracked(() => this.page.transform().renderScale);\n void (async () => {\n try {\n const image = await render.renderSource(this.page.ref, {\n scale,\n ...layers,\n view: this.page.view,\n signal: controller.signal,\n });\n const objectUrl = await image.objectUrl().abortWith(controller.signal);\n if (controller.signal.aborted) {\n objectUrl.revoke();\n return;\n }\n revoke = objectUrl.revoke;\n // Set on the element now, not through a binding. A binding applies at the next change\n // detection, and the key can move on before that, revoking this URL: the image would\n // then be handed a revoked URL and lose its picture. Set at once, the browser keeps\n // showing the old picture until the new one is decoded and never asks for the old URL\n // again, so revoking it when the next one comes is safe.\n this.picture().nativeElement.src = objectUrl.url;\n } catch {\n // Cancelled (the camera moved on, the layer went away) or the render failed.\n }\n })();\n });\n }\n}\n","/**\n * @embedpdf/angular/render: the page pictures.\n *\n * withRender(options) the plugin, for provideEmbedPdf()\n * inject(EpdfRender) pictures on demand, redraws, the settings\n * <epdf-render-layer> the picture of each page on a Stage\n */\n\n// The plugin's types and helpers, so app code has one import for the feature.\nexport * from '@embedpdf/plugin-render';\nexport * from './render';\nexport { EpdfRenderLayer } from './render-layer';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":["RenderToken"],"mappings":"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"}
|