@reekon-tools/react-native-pdf-canvas 0.1.0
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/PdfCanvas.podspec +80 -0
- package/README.md +1391 -0
- package/android/build.gradle +175 -0
- package/android/consumer-rules.pro +3 -0
- package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/android/gradle/wrapper/gradle-wrapper.properties +7 -0
- package/android/gradle.properties +2 -0
- package/android/gradlew +248 -0
- package/android/gradlew.bat +98 -0
- package/android/settings.gradle +34 -0
- package/android/src/androidTest/java/tools/reekon/pdfcanvas/PdfCanvasCancellationTest.java +226 -0
- package/android/src/androidTest/java/tools/reekon/pdfcanvas/PdfCanvasConcurrencyTest.java +239 -0
- package/android/src/androidTest/java/tools/reekon/pdfcanvas/PdfCanvasDeviceTimingTest.java +251 -0
- package/android/src/androidTest/java/tools/reekon/pdfcanvas/PdfCanvasFailureTest.java +221 -0
- package/android/src/androidTest/java/tools/reekon/pdfcanvas/PdfCanvasJsiTransportTest.java +783 -0
- package/android/src/androidTest/java/tools/reekon/pdfcanvas/PdfCanvasPhaseTimingTest.java +1388 -0
- package/android/src/androidTest/java/tools/reekon/pdfcanvas/PdfCanvasPoisonGuardTest.java +98 -0
- package/android/src/androidTest/java/tools/reekon/pdfcanvas/PdfCanvasQuirksTest.java +324 -0
- package/android/src/androidTest/java/tools/reekon/pdfcanvas/PdfCanvasRasterizerTest.java +775 -0
- package/android/src/androidTest/java/tools/reekon/pdfcanvas/PoisonsTheProcess.java +20 -0
- package/android/src/androidTest/java/tools/reekon/pdfcanvas/TestPdfs.java +558 -0
- package/android/src/jsi/cpp/CMakeLists.txt +33 -0
- package/android/src/jsi/cpp/pdfcanvas-jsi.cpp +469 -0
- package/android/src/jsi/java/tools/reekon/pdfcanvas/jsi/PdfCanvasPixelBridge.java +140 -0
- package/android/src/main/AndroidManifest.xml +7 -0
- package/android/src/main/java/tools/reekon/pdfcanvas/PageGeometry.java +45 -0
- package/android/src/main/java/tools/reekon/pdfcanvas/PdfCanvasRasterizer.java +564 -0
- package/android/src/main/java/tools/reekon/pdfcanvas/PdfErrorCode.java +33 -0
- package/android/src/main/java/tools/reekon/pdfcanvas/PdfPlatformQuirks.java +277 -0
- package/android/src/main/java/tools/reekon/pdfcanvas/PdfPreflight.java +214 -0
- package/android/src/main/java/tools/reekon/pdfcanvas/PdfRasterException.java +30 -0
- package/android/src/main/java/tools/reekon/pdfcanvas/PdfRendererPool.java +234 -0
- package/android/src/main/java/tools/reekon/pdfcanvas/RasterCancellation.java +47 -0
- package/android/src/main/java/tools/reekon/pdfcanvas/RasterPixels.java +143 -0
- package/android/src/main/java/tools/reekon/pdfcanvas/RasterRequest.java +95 -0
- package/android/src/reactnative/java/tools/reekon/pdfcanvas/rn/PdfCanvasModule.java +626 -0
- package/android/src/reactnative/java/tools/reekon/pdfcanvas/rn/PdfCanvasPackage.java +33 -0
- package/android/tools/compile-gate.sh +289 -0
- package/dist/cache.d.ts +161 -0
- package/dist/cache.js +389 -0
- package/dist/clock.d.ts +21 -0
- package/dist/clock.js +31 -0
- package/dist/controller.d.ts +131 -0
- package/dist/controller.js +1002 -0
- package/dist/geometry.d.ts +96 -0
- package/dist/geometry.js +248 -0
- package/dist/index.d.ts +52 -0
- package/dist/index.js +50 -0
- package/dist/index.native.d.ts +21 -0
- package/dist/index.native.js +23 -0
- package/dist/index.web.d.ts +24 -0
- package/dist/index.web.js +26 -0
- package/dist/layout.d.ts +78 -0
- package/dist/layout.js +152 -0
- package/dist/peer-check.d.ts +83 -0
- package/dist/peer-check.js +183 -0
- package/dist/planner.d.ts +35 -0
- package/dist/planner.js +530 -0
- package/dist/policy.d.ts +14 -0
- package/dist/policy.js +168 -0
- package/dist/rasterizer/android.d.ts +121 -0
- package/dist/rasterizer/android.js +126 -0
- package/dist/rasterizer/buffer.d.ts +18 -0
- package/dist/rasterizer/buffer.js +18 -0
- package/dist/rasterizer/fake.d.ts +92 -0
- package/dist/rasterizer/fake.js +433 -0
- package/dist/rasterizer/index.d.ts +38 -0
- package/dist/rasterizer/index.js +69 -0
- package/dist/rasterizer/index.native.d.ts +19 -0
- package/dist/rasterizer/index.native.js +80 -0
- package/dist/rasterizer/index.web.d.ts +63 -0
- package/dist/rasterizer/index.web.js +75 -0
- package/dist/rasterizer/ingest.d.ts +180 -0
- package/dist/rasterizer/ingest.js +307 -0
- package/dist/rasterizer/ios.d.ts +84 -0
- package/dist/rasterizer/ios.js +155 -0
- package/dist/rasterizer/native-bridge.d.ts +261 -0
- package/dist/rasterizer/native-bridge.js +413 -0
- package/dist/rasterizer/web/client.d.ts +84 -0
- package/dist/rasterizer/web/client.js +359 -0
- package/dist/rasterizer/web/engine.d.ts +69 -0
- package/dist/rasterizer/web/engine.js +308 -0
- package/dist/rasterizer/web/index.d.ts +26 -0
- package/dist/rasterizer/web/index.js +21 -0
- package/dist/rasterizer/web/pdfium.d.ts +213 -0
- package/dist/rasterizer/web/pdfium.js +170 -0
- package/dist/rasterizer/web/protocol.d.ts +138 -0
- package/dist/rasterizer/web/protocol.js +37 -0
- package/dist/rasterizer/web/session.d.ts +106 -0
- package/dist/rasterizer/web/session.js +413 -0
- package/dist/rasterizer/web/worker.d.ts +44 -0
- package/dist/rasterizer/web/worker.js +76 -0
- package/dist/react/PdfContentView.d.ts +98 -0
- package/dist/react/PdfContentView.js +189 -0
- package/dist/react/index.d.ts +6 -0
- package/dist/react/index.js +3 -0
- package/dist/react/usePdfDocument.d.ts +134 -0
- package/dist/react/usePdfDocument.js +275 -0
- package/dist/react/usePdfLayer.d.ts +94 -0
- package/dist/react/usePdfLayer.js +388 -0
- package/dist/skia/index.d.ts +26 -0
- package/dist/skia/index.js +25 -0
- package/dist/skia/index.native.d.ts +14 -0
- package/dist/skia/index.native.js +16 -0
- package/dist/skia/index.web.d.ts +12 -0
- package/dist/skia/index.web.js +14 -0
- package/dist/skia/resolve.native.d.ts +18 -0
- package/dist/skia/resolve.native.js +22 -0
- package/dist/skia/resolve.web.d.ts +41 -0
- package/dist/skia/resolve.web.js +62 -0
- package/dist/skia/skia-api.d.ts +94 -0
- package/dist/skia/skia-api.js +113 -0
- package/dist/testing/index.d.ts +27 -0
- package/dist/testing/index.js +28 -0
- package/dist/testing/scenes.d.ts +100 -0
- package/dist/testing/scenes.js +267 -0
- package/dist/types.d.ts +611 -0
- package/dist/types.js +21 -0
- package/dist/web-init.d.ts +68 -0
- package/dist/web-init.js +64 -0
- package/ios/Package.swift +58 -0
- package/ios/Sources/PdfCanvasBridge/PdfCanvasModule.mm +743 -0
- package/ios/Sources/PdfCanvasBridge/include/PdfCanvasModule.h +36 -0
- package/ios/Sources/PdfCanvasCore/PdfCanvasCancellation.m +38 -0
- package/ios/Sources/PdfCanvasCore/PdfCanvasDocumentPool.m +389 -0
- package/ios/Sources/PdfCanvasCore/PdfCanvasErrorCode.m +57 -0
- package/ios/Sources/PdfCanvasCore/PdfCanvasPageGeometry.m +44 -0
- package/ios/Sources/PdfCanvasCore/PdfCanvasPageTransform.m +82 -0
- package/ios/Sources/PdfCanvasCore/PdfCanvasPixelSink.m +37 -0
- package/ios/Sources/PdfCanvasCore/PdfCanvasPreflight.m +158 -0
- package/ios/Sources/PdfCanvasCore/PdfCanvasRasterPixels.m +80 -0
- package/ios/Sources/PdfCanvasCore/PdfCanvasRasterRequest.m +65 -0
- package/ios/Sources/PdfCanvasCore/PdfCanvasRasterizer.m +548 -0
- package/ios/Sources/PdfCanvasCore/include/PdfCanvasCancellation.h +48 -0
- package/ios/Sources/PdfCanvasCore/include/PdfCanvasCore.h +26 -0
- package/ios/Sources/PdfCanvasCore/include/PdfCanvasDocumentPool.h +122 -0
- package/ios/Sources/PdfCanvasCore/include/PdfCanvasErrorCode.h +80 -0
- package/ios/Sources/PdfCanvasCore/include/PdfCanvasPageGeometry.h +79 -0
- package/ios/Sources/PdfCanvasCore/include/PdfCanvasPageTransform.h +129 -0
- package/ios/Sources/PdfCanvasCore/include/PdfCanvasPixelSink.h +100 -0
- package/ios/Sources/PdfCanvasCore/include/PdfCanvasPreflight.h +65 -0
- package/ios/Sources/PdfCanvasCore/include/PdfCanvasRasterPixels.h +111 -0
- package/ios/Sources/PdfCanvasCore/include/PdfCanvasRasterRequest.h +85 -0
- package/ios/Sources/PdfCanvasCore/include/PdfCanvasRasterizer.h +163 -0
- package/ios/Sources/PdfCanvasSlots/PdfCanvasSlots.mm +297 -0
- package/ios/Sources/PdfCanvasSlots/include/PdfCanvasSlots.h +140 -0
- package/ios/Tests/PdfCanvasCoreTests/ConcurrencyTests.swift +358 -0
- package/ios/Tests/PdfCanvasCoreTests/FailureTests.swift +262 -0
- package/ios/Tests/PdfCanvasCoreTests/GeometryTests.swift +173 -0
- package/ios/Tests/PdfCanvasCoreTests/PreviewTests.swift +114 -0
- package/ios/Tests/PdfCanvasCoreTests/RasterAssertions.swift +158 -0
- package/ios/Tests/PdfCanvasCoreTests/RasterizerTests.swift +544 -0
- package/ios/Tests/PdfCanvasCoreTests/SinkTests.swift +287 -0
- package/ios/Tests/PdfCanvasCoreTests/SlotsTests.swift +396 -0
- package/ios/Tests/PdfCanvasCoreTests/TestPdfs.swift +639 -0
- package/ios/Tests/PdfCanvasCoreTests/TimingTests.swift +179 -0
- package/ios/Tests/PdfCanvasCoreTests/TransformTests.swift +283 -0
- package/package.json +144 -0
- package/react-native.config.js +40 -0
- package/scripts/check-skia-peer.mjs +86 -0
- package/scripts/skia-peer-check.mjs +363 -0
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reference scenes: the composition contract, stated as DATA.
|
|
3
|
+
*
|
|
4
|
+
* BUILD STEP 1 pixel-snapshots the composition of a set of rasters offscreen and
|
|
5
|
+
* calls the result the reference every backend is later checked against. The
|
|
6
|
+
* IMAGES cannot be that reference on their own — they are specific to whichever
|
|
7
|
+
* document produced the bytes, so a PDFium suite and a PDFKit suite would never
|
|
8
|
+
* agree byte for byte. What generalises is the SCENE: which rasters the planner
|
|
9
|
+
* asked for, where the host transform puts them, and which canvas coordinates
|
|
10
|
+
* must be covered by what.
|
|
11
|
+
*
|
|
12
|
+
* A backend suite therefore uses this module as follows:
|
|
13
|
+
*
|
|
14
|
+
* 1. `buildReferenceScenes()` and pick a scene.
|
|
15
|
+
* 2. For each `scene.rasters`, hand `.request` to your own `RasterizerHandle`
|
|
16
|
+
* and `.meta` to your `ingest`.
|
|
17
|
+
* 3. Compose them into a `PdfContent`, draw it through `PdfContentView` inside
|
|
18
|
+
* `<Group transform={referenceTransform(scene.transform)}>` on a
|
|
19
|
+
* `scene.canvas`-sized surface.
|
|
20
|
+
* 4. Assert `scene.probes`: every 'raster' probe must be opaque, every
|
|
21
|
+
* 'nothing' probe must be untouched.
|
|
22
|
+
*
|
|
23
|
+
* SKIA-FREE, like the rest of `src/testing/`. It reaches `planRasters` (pure) and
|
|
24
|
+
* nothing else — the plan is DERIVED here rather than hand-written, so a change
|
|
25
|
+
* to the splitting rule shows up as a changed scene rather than as a scene that
|
|
26
|
+
* quietly stops describing what the planner does.
|
|
27
|
+
*/
|
|
28
|
+
import { planRasters } from '../planner.js';
|
|
29
|
+
import { resolvePolicy } from '../policy.js';
|
|
30
|
+
import { LETTER } from '../rasterizer/fake.js';
|
|
31
|
+
export function docToCanvas(transform, docX, docY) {
|
|
32
|
+
return {
|
|
33
|
+
x: docX * transform.scale + transform.translateX,
|
|
34
|
+
y: docY * transform.scale + transform.translateY,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
export function docRectToCanvas(transform, rect) {
|
|
38
|
+
const origin = docToCanvas(transform, rect.x, rect.y);
|
|
39
|
+
return {
|
|
40
|
+
x: origin.x,
|
|
41
|
+
y: origin.y,
|
|
42
|
+
width: rect.width * transform.scale,
|
|
43
|
+
height: rect.height * transform.scale,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Plan item -> backend request.
|
|
48
|
+
*
|
|
49
|
+
* `annotations: false` and `background: 'white'` match what the tile path asks
|
|
50
|
+
* for in production (the app draws its own annotations above, and an unfilled
|
|
51
|
+
* buffer composites as black — see `ingest.ts`).
|
|
52
|
+
*/
|
|
53
|
+
export function sceneRasterRequest(item, over = {}) {
|
|
54
|
+
return {
|
|
55
|
+
page: item.page,
|
|
56
|
+
docRect: item.docRect,
|
|
57
|
+
scale: item.scale,
|
|
58
|
+
annotations: false,
|
|
59
|
+
background: 'white',
|
|
60
|
+
...over,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
export function sceneRasterMeta(item, epoch = 1) {
|
|
64
|
+
return {
|
|
65
|
+
key: item.key,
|
|
66
|
+
page: item.page,
|
|
67
|
+
role: item.role,
|
|
68
|
+
docRect: item.docRect,
|
|
69
|
+
scale: item.scale,
|
|
70
|
+
epoch,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
function toSceneRasters(plan, epoch = 1) {
|
|
74
|
+
return plan.items.map(item => ({
|
|
75
|
+
item,
|
|
76
|
+
request: sceneRasterRequest(item),
|
|
77
|
+
meta: sceneRasterMeta(item, epoch),
|
|
78
|
+
}));
|
|
79
|
+
}
|
|
80
|
+
function letterPage() {
|
|
81
|
+
return {
|
|
82
|
+
pages: [
|
|
83
|
+
{ index: 0, width: LETTER.width, height: LETTER.height, rotation: 0 },
|
|
84
|
+
],
|
|
85
|
+
pageRects: [{ x: 0, y: 0, width: LETTER.width, height: LETTER.height }],
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Scene 1 — a whole LETTER page at fit zoom, drawn under a translated,
|
|
90
|
+
* downscaled host transform.
|
|
91
|
+
*
|
|
92
|
+
* The planner emits a BASE and no detail here (the base is already at the
|
|
93
|
+
* display scale, so detail would be the same pixels twice), which makes this the
|
|
94
|
+
* scene that proves the base layer alone paints the page and paints it inside
|
|
95
|
+
* the page rect.
|
|
96
|
+
*/
|
|
97
|
+
function fitScene() {
|
|
98
|
+
const { pages, pageRects } = letterPage();
|
|
99
|
+
const policy = resolvePolicy();
|
|
100
|
+
const viewport = {
|
|
101
|
+
visibleDocRect: { x: 0, y: 0, width: LETTER.width, height: LETTER.height },
|
|
102
|
+
scale: 0.5,
|
|
103
|
+
};
|
|
104
|
+
const plan = planRasters({
|
|
105
|
+
viewport,
|
|
106
|
+
pages,
|
|
107
|
+
pageRects,
|
|
108
|
+
visiblePages: [0],
|
|
109
|
+
policy,
|
|
110
|
+
});
|
|
111
|
+
const transform = {
|
|
112
|
+
scale: 0.5,
|
|
113
|
+
translateX: 20,
|
|
114
|
+
translateY: 20,
|
|
115
|
+
};
|
|
116
|
+
return {
|
|
117
|
+
id: 'letter-fit',
|
|
118
|
+
description: 'One LETTER page at fit zoom under a translated 0.5x host transform. ' +
|
|
119
|
+
'Base raster only — the planner suppresses detail when the base is ' +
|
|
120
|
+
'already at the display scale.',
|
|
121
|
+
canvas: { width: 400, height: 440 },
|
|
122
|
+
transform,
|
|
123
|
+
pages,
|
|
124
|
+
pageRects,
|
|
125
|
+
viewport,
|
|
126
|
+
policy,
|
|
127
|
+
plan,
|
|
128
|
+
rasters: toSceneRasters(plan),
|
|
129
|
+
probes: [
|
|
130
|
+
{
|
|
131
|
+
docX: LETTER.width / 2,
|
|
132
|
+
docY: LETTER.height / 2,
|
|
133
|
+
expect: 'raster',
|
|
134
|
+
why: 'the base raster must cover the middle of the page',
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
docX: 1,
|
|
138
|
+
docY: 1,
|
|
139
|
+
expect: 'raster',
|
|
140
|
+
why: 'the top-left of the page is inside the base rect; a base drawn ' +
|
|
141
|
+
'letterboxed (fit="contain") or offset by the host translate leaves ' +
|
|
142
|
+
'it blank',
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
docX: LETTER.width - 1,
|
|
146
|
+
docY: LETTER.height - 1,
|
|
147
|
+
expect: 'raster',
|
|
148
|
+
why: 'the bottom-right corner of the page, same reasoning',
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
docX: -20,
|
|
152
|
+
docY: -20,
|
|
153
|
+
expect: 'nothing',
|
|
154
|
+
why: 'outside the page rect. A base that ignored its doc rect and filled ' +
|
|
155
|
+
'the canvas would paint here.',
|
|
156
|
+
},
|
|
157
|
+
],
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Scene 2 — a detail set the planner SPLITS into a 2x2 grid, over a base that
|
|
162
|
+
* stays ONE piece.
|
|
163
|
+
*
|
|
164
|
+
* `maxTextureDimension` is lowered so the split is the PLANNER's decision, driven
|
|
165
|
+
* by the same code path a 4096-limited device takes on a large sheet. The canvas
|
|
166
|
+
* is 1:1 with the detail scale, so a correctly-placed piece lands on whole canvas
|
|
167
|
+
* pixels and the composite can be compared against the same region rastered as a
|
|
168
|
+
* single piece.
|
|
169
|
+
*
|
|
170
|
+
* THE NUMBER IS 512 BECAUSE THE SHAPE IS CHOSEN, NOT INHERITED. It was 320, and
|
|
171
|
+
* `min(maxPieceDimension, maxTextureDimension)` therefore tiled the BASE into two
|
|
172
|
+
* pieces as well (the base is 309x400 device px here) — a change no probe in this
|
|
173
|
+
* scene could see, because the second base piece begins at doc y ~394 and the
|
|
174
|
+
* canvas stops at doc y 360. A backend suite is diffed against these scenes, so
|
|
175
|
+
* how many rasters one asks for is part of the contract and may not drift out of
|
|
176
|
+
* a default. 512 divides the 600px detail target and leaves the base whole; the
|
|
177
|
+
* detail grid is byte-for-byte the one 320 produced, because both give
|
|
178
|
+
* `ceil(600 / usable) == 2`. `composition.test.ts` pins both counts.
|
|
179
|
+
*
|
|
180
|
+
* The host translate is POSITIVE and the canvas is larger than the detail
|
|
181
|
+
* target, which is what buys the scene a 'nothing' probe. With the target
|
|
182
|
+
* mapped exactly onto the canvas — the obvious framing — every canvas pixel is
|
|
183
|
+
* inside the page, the whole-page base paints all of them, and no coordinate is
|
|
184
|
+
* left for "must be untouched" to describe. A scene with only 'raster' probes
|
|
185
|
+
* asserts nothing about a raster that overruns its rect.
|
|
186
|
+
*/
|
|
187
|
+
function splitDetailScene() {
|
|
188
|
+
const { pages, pageRects } = letterPage();
|
|
189
|
+
const policy = resolvePolicy({ maxTextureDimension: 512 });
|
|
190
|
+
const viewport = {
|
|
191
|
+
visibleDocRect: { x: 100, y: 100, width: 200, height: 200 },
|
|
192
|
+
scale: 2,
|
|
193
|
+
};
|
|
194
|
+
const plan = planRasters({
|
|
195
|
+
viewport,
|
|
196
|
+
pages,
|
|
197
|
+
pageRects,
|
|
198
|
+
visiblePages: [0],
|
|
199
|
+
policy,
|
|
200
|
+
});
|
|
201
|
+
// detailOverflow 0.25 inflates {100,100,200,200} to {50,50,300,300}, entirely
|
|
202
|
+
// inside the page, so the covered rect is exactly that. The translate puts
|
|
203
|
+
// doc (0,0) at canvas (20,20), so the target occupies canvas [120, 720) on
|
|
204
|
+
// both axes and a 20px margin of NEGATIVE doc space stays visible.
|
|
205
|
+
const transform = {
|
|
206
|
+
scale: 2,
|
|
207
|
+
translateX: 20,
|
|
208
|
+
translateY: 20,
|
|
209
|
+
};
|
|
210
|
+
return {
|
|
211
|
+
id: 'letter-split-detail',
|
|
212
|
+
description: 'A 300x300pt detail target at scale 2, split into a 2x2 grid by a ' +
|
|
213
|
+
'512px texture limit, over a single whole-page base. Canvas is 1:1 with ' +
|
|
214
|
+
'the detail scale, with a margin of off-page canvas around it.',
|
|
215
|
+
canvas: { width: 740, height: 740 },
|
|
216
|
+
transform,
|
|
217
|
+
pages,
|
|
218
|
+
pageRects,
|
|
219
|
+
viewport,
|
|
220
|
+
policy,
|
|
221
|
+
plan,
|
|
222
|
+
rasters: toSceneRasters(plan),
|
|
223
|
+
probes: [
|
|
224
|
+
{
|
|
225
|
+
docX: 50.25,
|
|
226
|
+
docY: 50.25,
|
|
227
|
+
expect: 'raster',
|
|
228
|
+
why: 'top-left corner of the detail target',
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
docX: 349.75,
|
|
232
|
+
docY: 349.75,
|
|
233
|
+
expect: 'raster',
|
|
234
|
+
why: 'bottom-right corner of the detail target',
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
docX: 200,
|
|
238
|
+
docY: 200,
|
|
239
|
+
expect: 'raster',
|
|
240
|
+
why: 'the interior seam. Pieces OVERLAP rather than abut, so no doc ' +
|
|
241
|
+
'coordinate inside the target may be uncovered.',
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
docX: -5,
|
|
245
|
+
docY: -5,
|
|
246
|
+
expect: 'nothing',
|
|
247
|
+
why: 'off the page entirely, and the only kind of point that can be ' +
|
|
248
|
+
'unpainted in this scene — the base covers the whole sheet. A base ' +
|
|
249
|
+
'or a detail piece that ignored its doc rect and filled the canvas ' +
|
|
250
|
+
'paints here, and every other probe in this scene would still pass.',
|
|
251
|
+
},
|
|
252
|
+
],
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
export function buildReferenceScenes() {
|
|
256
|
+
return [fitScene(), splitDetailScene()];
|
|
257
|
+
}
|
|
258
|
+
export function referenceScene(id) {
|
|
259
|
+
const scene = buildReferenceScenes().find(s => s.id === id);
|
|
260
|
+
if (!scene) {
|
|
261
|
+
throw new Error(`No reference scene '${id}'. Known: ` +
|
|
262
|
+
buildReferenceScenes()
|
|
263
|
+
.map(s => s.id)
|
|
264
|
+
.join(', '));
|
|
265
|
+
}
|
|
266
|
+
return scene;
|
|
267
|
+
}
|