@beyondwork/docx-react-component 1.0.109 → 1.0.111
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/package.json +1 -1
- package/src/api/public-types.ts +3 -0
- package/src/model/layout/page-graph-types.ts +33 -0
- package/src/model/layout/runtime-page-graph-types.ts +25 -0
- package/src/runtime/document-runtime.ts +46 -0
- package/src/runtime/geometry/adjacent-geometry-intake.ts +820 -15
- package/src/runtime/geometry/caret-geometry.ts +219 -7
- package/src/runtime/geometry/geometry-index.ts +52 -12
- package/src/runtime/geometry/object-handles.ts +42 -1
- package/src/runtime/layout/index.ts +3 -0
- package/src/runtime/layout/inert-layout-facet.ts +13 -0
- package/src/runtime/layout/layout-engine-instance.ts +233 -4
- package/src/runtime/layout/layout-engine-version.ts +47 -2
- package/src/runtime/layout/layout-facet-types.ts +3 -0
- package/src/runtime/layout/page-graph.ts +88 -7
- package/src/runtime/layout/paginated-layout-engine.ts +34 -0
- package/src/runtime/layout/project-block-fragments.ts +144 -1
- package/src/runtime/layout/public-facet.ts +228 -9
- package/src/runtime/layout/resolve-page-previews.ts +46 -8
- package/src/runtime/scopes/adjacent-geometry-evidence.ts +456 -0
- package/src/runtime/scopes/compile-scope-bundle.ts +8 -0
- package/src/runtime/scopes/evidence.ts +16 -0
- package/src/runtime/scopes/index.ts +13 -0
- package/src/runtime/scopes/semantic-scope-types.ts +67 -0
- package/src/ui-tailwind/chrome-overlay/tw-table-split-row-carry-overlay.tsx +62 -0
- package/src/ui-tailwind/debug/layer11-consumer-readiness.ts +104 -0
- package/src/ui-tailwind/editor-surface/pm-page-break-decorations.ts +50 -5
- package/src/ui-tailwind/editor-surface/tw-prosemirror-surface.tsx +27 -0
- package/src/ui-tailwind/page-stack/tw-page-chrome-entry.tsx +62 -0
- package/src/ui-tailwind/page-stack/tw-page-stack-chrome-layer.tsx +1 -0
- package/src/README.md +0 -85
- package/src/api/README.md +0 -26
- package/src/api/v3/README.md +0 -91
- package/src/component-inventory.md +0 -99
- package/src/core/README.md +0 -10
- package/src/core/commands/README.md +0 -3
- package/src/core/schema/README.md +0 -3
- package/src/core/selection/README.md +0 -3
- package/src/core/state/README.md +0 -3
- package/src/io/README.md +0 -10
- package/src/io/export/README.md +0 -3
- package/src/io/normalize/README.md +0 -3
- package/src/io/ooxml/README.md +0 -3
- package/src/io/opc/README.md +0 -3
- package/src/model/README.md +0 -3
- package/src/preservation/README.md +0 -3
- package/src/review/README.md +0 -16
- package/src/review/store/README.md +0 -3
- package/src/runtime/README.md +0 -3
- package/src/ui/README.md +0 -30
- package/src/ui/comments/README.md +0 -3
- package/src/ui/compatibility/README.md +0 -3
- package/src/ui/editor-surface/README.md +0 -3
- package/src/ui/review/README.md +0 -3
- package/src/ui/status/README.md +0 -3
- package/src/ui/theme/README.md +0 -3
- package/src/ui/toolbar/README.md +0 -3
- package/src/ui-tailwind/debug/README.md +0 -22
- package/src/validation/README.md +0 -3
|
@@ -20,20 +20,116 @@ export interface AdjacentGeometryTwipsRect {
|
|
|
20
20
|
readonly heightTwips?: number;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
export interface AdjacentGeometryFramePxRect {
|
|
24
|
+
readonly leftPx: number;
|
|
25
|
+
readonly topPx: number;
|
|
26
|
+
readonly widthPx: number;
|
|
27
|
+
readonly heightPx: number;
|
|
28
|
+
readonly coordinateSpace: "frame-px";
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface AdjacentGeometryFramePxPoint {
|
|
32
|
+
readonly xPx: number;
|
|
33
|
+
readonly yPx: number;
|
|
34
|
+
readonly coordinateSpace: "frame-px";
|
|
35
|
+
}
|
|
36
|
+
|
|
23
37
|
export interface AdjacentGeometryPageSpan {
|
|
24
38
|
readonly startPage?: number | null;
|
|
25
39
|
readonly endPage?: number | null;
|
|
26
40
|
}
|
|
27
41
|
|
|
42
|
+
export type AdjacentGeometryPageIndexStatus =
|
|
43
|
+
| "matches-runtime"
|
|
44
|
+
| "differs-from-runtime"
|
|
45
|
+
| "runtime-missing"
|
|
46
|
+
| "word-page-missing";
|
|
47
|
+
|
|
48
|
+
export interface AdjacentGeometryL04FrameProjection {
|
|
49
|
+
readonly pageIndex?: number;
|
|
50
|
+
readonly pageId?: string;
|
|
51
|
+
readonly frameId?: string;
|
|
52
|
+
readonly frameCompleteness?: string;
|
|
53
|
+
readonly physicalBoundsTwips?: AdjacentGeometryTwipsRect;
|
|
54
|
+
readonly framePixelScale?: AdjacentGeometryFramePixelScale;
|
|
55
|
+
readonly markerLane?: AdjacentGeometryTwipsRect;
|
|
56
|
+
readonly textColumn?: AdjacentGeometryTwipsRect;
|
|
57
|
+
readonly fieldStartAnchorTwips?: {
|
|
58
|
+
readonly x?: number;
|
|
59
|
+
readonly y?: number;
|
|
60
|
+
};
|
|
61
|
+
readonly fieldEndAnchorTwips?: {
|
|
62
|
+
readonly x?: number;
|
|
63
|
+
readonly y?: number;
|
|
64
|
+
};
|
|
65
|
+
readonly coordinateSpace: "l04-frame-twips";
|
|
66
|
+
readonly precision: "word-page-local-calibration";
|
|
67
|
+
readonly status:
|
|
68
|
+
| "projected-l04-frame"
|
|
69
|
+
| "page-index-differs-from-runtime"
|
|
70
|
+
| "runtime-page-missing"
|
|
71
|
+
| "word-page-missing"
|
|
72
|
+
| "missing-l04-page-frame"
|
|
73
|
+
| "missing-word-page-local-geometry";
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface AdjacentGeometryFramePixelScale {
|
|
77
|
+
readonly source: "runtime-render-frame-page-rect";
|
|
78
|
+
readonly pageIndex: number;
|
|
79
|
+
readonly pageId?: string;
|
|
80
|
+
readonly frameId?: string;
|
|
81
|
+
readonly renderFrameRevision?: number;
|
|
82
|
+
readonly renderPageFrame: AdjacentGeometryFramePxRect;
|
|
83
|
+
readonly physicalBoundsTwips: AdjacentGeometryTwipsRect;
|
|
84
|
+
readonly pxPerTwipX: number;
|
|
85
|
+
readonly pxPerTwipY: number;
|
|
86
|
+
readonly zoomPxPerTwip?: number;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export interface AdjacentGeometryFramePixelProjection {
|
|
90
|
+
readonly pageIndex?: number;
|
|
91
|
+
readonly pageId?: string;
|
|
92
|
+
readonly frameId?: string;
|
|
93
|
+
readonly scale?: AdjacentGeometryFramePixelScale;
|
|
94
|
+
readonly markerLane?: AdjacentGeometryFramePxRect;
|
|
95
|
+
readonly textColumn?: AdjacentGeometryFramePxRect;
|
|
96
|
+
readonly fieldStartAnchorPx?: AdjacentGeometryFramePxPoint;
|
|
97
|
+
readonly fieldEndAnchorPx?: AdjacentGeometryFramePxPoint;
|
|
98
|
+
readonly fieldResultRangePx?: AdjacentGeometryFramePxRect;
|
|
99
|
+
readonly coordinateSpace: "frame-px";
|
|
100
|
+
readonly precision: "word-page-local-calibration";
|
|
101
|
+
readonly status:
|
|
102
|
+
| "projected-frame-pixels"
|
|
103
|
+
| "awaiting-l04-frame-projection"
|
|
104
|
+
| "missing-frame-pixel-scale"
|
|
105
|
+
| "missing-l04-frame-rect"
|
|
106
|
+
| "missing-l04-field-anchor";
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
interface AdjacentGeometryPageFrame {
|
|
110
|
+
readonly pageId?: string;
|
|
111
|
+
readonly pageIndex: number;
|
|
112
|
+
readonly frameId?: string;
|
|
113
|
+
readonly completeness?: string;
|
|
114
|
+
readonly physicalBoundsTwips?: AdjacentGeometryTwipsRect;
|
|
115
|
+
readonly framePixelScale?: AdjacentGeometryFramePixelScale;
|
|
116
|
+
}
|
|
117
|
+
|
|
28
118
|
export interface AdjacentGeometryPageLocalNumberingGeometry {
|
|
29
119
|
readonly wordPage?: number;
|
|
120
|
+
readonly normalizedWordPageIndex?: number;
|
|
30
121
|
readonly runtimePageIndex?: number;
|
|
122
|
+
readonly pageIndexStatus: AdjacentGeometryPageIndexStatus;
|
|
31
123
|
readonly runtimeFragmentId?: string;
|
|
32
124
|
readonly markerLane?: AdjacentGeometryTwipsRect;
|
|
33
125
|
readonly textColumn?: AdjacentGeometryTwipsRect;
|
|
126
|
+
readonly l04FrameProjection: AdjacentGeometryL04FrameProjection;
|
|
127
|
+
readonly framePixelProjection: AdjacentGeometryFramePixelProjection;
|
|
128
|
+
readonly compositorReady: boolean;
|
|
34
129
|
readonly coordinateSpace: "word-page-twips";
|
|
35
130
|
readonly precision: "word-page-local-calibration";
|
|
36
131
|
readonly normalizationStatus:
|
|
132
|
+
| "l04-frame-twips-projected"
|
|
37
133
|
| "word-page-local-awaiting-l04-frame-projection"
|
|
38
134
|
| "missing-word-page-local-lane";
|
|
39
135
|
}
|
|
@@ -56,9 +152,13 @@ export interface AdjacentGeometryPageLocalFieldGeometry {
|
|
|
56
152
|
readonly x?: number;
|
|
57
153
|
readonly y?: number;
|
|
58
154
|
};
|
|
155
|
+
readonly l04FrameProjection: AdjacentGeometryL04FrameProjection;
|
|
156
|
+
readonly framePixelProjection: AdjacentGeometryFramePixelProjection;
|
|
157
|
+
readonly compositorReady: boolean;
|
|
59
158
|
readonly coordinateSpace: "word-page-twips";
|
|
60
159
|
readonly precision: "word-page-local-calibration";
|
|
61
160
|
readonly normalizationStatus:
|
|
161
|
+
| "l04-frame-twips-projected"
|
|
62
162
|
| "word-page-local-awaiting-l04-frame-projection"
|
|
63
163
|
| "missing-word-placement";
|
|
64
164
|
}
|
|
@@ -69,6 +169,9 @@ export interface AdjacentGeometryNumberingRowSummary {
|
|
|
69
169
|
readonly canonicalBlockId?: string;
|
|
70
170
|
readonly runtimeBlockId?: string;
|
|
71
171
|
readonly runtimeFragmentId?: string;
|
|
172
|
+
readonly runtimeNumberingId?: string;
|
|
173
|
+
readonly layoutObjectId?: string;
|
|
174
|
+
readonly runtimeJoinSource: "adjacent-live" | "l04-numbering-readback";
|
|
72
175
|
readonly runtimePageIndex?: number;
|
|
73
176
|
readonly sourceParagraphPath?: string;
|
|
74
177
|
readonly canonicalNumberingInstanceId?: string;
|
|
@@ -94,6 +197,7 @@ export interface AdjacentGeometryNumberingRowSummary {
|
|
|
94
197
|
readonly heightTwips?: number;
|
|
95
198
|
};
|
|
96
199
|
readonly pageLocalGeometry: AdjacentGeometryPageLocalNumberingGeometry;
|
|
200
|
+
readonly compositorReady: boolean;
|
|
97
201
|
readonly rangeMappingMethod?: string;
|
|
98
202
|
readonly coordinateSpace: "screen-px";
|
|
99
203
|
readonly precision: "screen-space-approximate";
|
|
@@ -116,6 +220,7 @@ export interface AdjacentGeometryFieldRegionRowSummary {
|
|
|
116
220
|
readonly endPage?: number | null;
|
|
117
221
|
};
|
|
118
222
|
readonly pageLocalGeometry: AdjacentGeometryPageLocalFieldGeometry;
|
|
223
|
+
readonly compositorReady: boolean;
|
|
119
224
|
readonly instructionFamily?: string;
|
|
120
225
|
readonly resultLineRectCount: number;
|
|
121
226
|
readonly wordPlacement?: {
|
|
@@ -141,6 +246,7 @@ export interface AdjacentGeometryDocumentSummary {
|
|
|
141
246
|
readonly docId: string;
|
|
142
247
|
readonly numberingRows: number;
|
|
143
248
|
readonly numberingRowsWithRuntimeFragment: number;
|
|
249
|
+
readonly numberingRowsJoinedFromL04Readback: number;
|
|
144
250
|
readonly numberingParagraphLineRects: number;
|
|
145
251
|
readonly numberingTextOnlyLineRects: number;
|
|
146
252
|
readonly numberingRawMarkerRectRows: number;
|
|
@@ -150,6 +256,13 @@ export interface AdjacentGeometryDocumentSummary {
|
|
|
150
256
|
readonly numberingRowsWithUiaCapture: number;
|
|
151
257
|
readonly numberingRowsWithPageLocalMarkerLane: number;
|
|
152
258
|
readonly numberingRowsWithPageLocalTextColumn: number;
|
|
259
|
+
readonly numberingRowsWithRuntimePageMatch: number;
|
|
260
|
+
readonly numberingUiaRowsWithRuntimePageMatch: number;
|
|
261
|
+
readonly numberingRowsWithL04FrameProjection: number;
|
|
262
|
+
readonly numberingUiaRowsWithL04FrameProjection: number;
|
|
263
|
+
readonly numberingRowsWithFramePixelProjection: number;
|
|
264
|
+
readonly numberingUiaRowsWithFramePixelProjection: number;
|
|
265
|
+
readonly numberingCompositorReadyRows: number;
|
|
153
266
|
readonly fieldRegionRows: number;
|
|
154
267
|
readonly fieldRegionRowsWithRuntimeId: number;
|
|
155
268
|
readonly fieldRegionResultLineRects: number;
|
|
@@ -157,10 +270,15 @@ export interface AdjacentGeometryDocumentSummary {
|
|
|
157
270
|
readonly fieldRegionRowsWithWordPlacement: number;
|
|
158
271
|
readonly fieldRegionRowsWithRuntimePageMatch: number;
|
|
159
272
|
readonly fieldRegionRowsWithRuntimePageContainment: number;
|
|
273
|
+
readonly fieldRegionRowsWithL04FrameProjection: number;
|
|
274
|
+
readonly fieldRegionUiaRowsWithL04FrameProjection: number;
|
|
275
|
+
readonly fieldRegionRowsWithFramePixelProjection: number;
|
|
276
|
+
readonly fieldRegionUiaRowsWithFramePixelProjection: number;
|
|
277
|
+
readonly fieldRegionCompositorReadyRows: number;
|
|
160
278
|
}
|
|
161
279
|
|
|
162
280
|
export interface AdjacentGeometryIntakeSummary {
|
|
163
|
-
readonly schemaVersion: "layer-05-adjacent-geometry-intake/
|
|
281
|
+
readonly schemaVersion: "layer-05-adjacent-geometry-intake/v2";
|
|
164
282
|
readonly generatedAtUtc: string;
|
|
165
283
|
readonly sourceRuns: {
|
|
166
284
|
readonly adjacentLiveWordJoins: string;
|
|
@@ -170,6 +288,7 @@ export interface AdjacentGeometryIntakeSummary {
|
|
|
170
288
|
readonly totals: {
|
|
171
289
|
readonly numberingRows: number;
|
|
172
290
|
readonly numberingRowsWithRuntimeFragment: number;
|
|
291
|
+
readonly numberingRowsJoinedFromL04Readback: number;
|
|
173
292
|
readonly numberingParagraphLineRects: number;
|
|
174
293
|
readonly numberingTextOnlyLineRects: number;
|
|
175
294
|
readonly numberingRawMarkerRectRows: number;
|
|
@@ -179,6 +298,13 @@ export interface AdjacentGeometryIntakeSummary {
|
|
|
179
298
|
readonly numberingRowsWithUiaCapture: number;
|
|
180
299
|
readonly numberingRowsWithPageLocalMarkerLane: number;
|
|
181
300
|
readonly numberingRowsWithPageLocalTextColumn: number;
|
|
301
|
+
readonly numberingRowsWithRuntimePageMatch: number;
|
|
302
|
+
readonly numberingUiaRowsWithRuntimePageMatch: number;
|
|
303
|
+
readonly numberingRowsWithL04FrameProjection: number;
|
|
304
|
+
readonly numberingUiaRowsWithL04FrameProjection: number;
|
|
305
|
+
readonly numberingRowsWithFramePixelProjection: number;
|
|
306
|
+
readonly numberingUiaRowsWithFramePixelProjection: number;
|
|
307
|
+
readonly numberingCompositorReadyRows: number;
|
|
182
308
|
readonly fieldRegionRows: number;
|
|
183
309
|
readonly fieldRegionRowsWithRuntimeId: number;
|
|
184
310
|
readonly fieldRegionResultLineRects: number;
|
|
@@ -186,6 +312,11 @@ export interface AdjacentGeometryIntakeSummary {
|
|
|
186
312
|
readonly fieldRegionRowsWithWordPlacement: number;
|
|
187
313
|
readonly fieldRegionRowsWithRuntimePageMatch: number;
|
|
188
314
|
readonly fieldRegionRowsWithRuntimePageContainment: number;
|
|
315
|
+
readonly fieldRegionRowsWithL04FrameProjection: number;
|
|
316
|
+
readonly fieldRegionUiaRowsWithL04FrameProjection: number;
|
|
317
|
+
readonly fieldRegionRowsWithFramePixelProjection: number;
|
|
318
|
+
readonly fieldRegionUiaRowsWithFramePixelProjection: number;
|
|
319
|
+
readonly fieldRegionCompositorReadyRows: number;
|
|
189
320
|
};
|
|
190
321
|
readonly routing: {
|
|
191
322
|
readonly routedTo: "L05";
|
|
@@ -198,7 +329,12 @@ export interface AdjacentGeometryIntakeSummary {
|
|
|
198
329
|
readonly coordinateSpace: "word-page-twips";
|
|
199
330
|
readonly precision: "word-page-local-calibration";
|
|
200
331
|
readonly requiredUpstreamFact: "L04 frame-to-pixel projection";
|
|
201
|
-
readonly
|
|
332
|
+
readonly l04FrameProjectionCoordinateSpace: "l04-frame-twips";
|
|
333
|
+
readonly l04FrameProjectionPrecision: "word-page-local-calibration";
|
|
334
|
+
readonly framePixelCoordinateSpace: "frame-px";
|
|
335
|
+
readonly framePixelPrecision: "word-page-local-calibration";
|
|
336
|
+
readonly scaleSource: "runtime-render-frame-page-rect";
|
|
337
|
+
readonly compositorReady: boolean;
|
|
202
338
|
};
|
|
203
339
|
readonly documents: readonly AdjacentGeometryDocumentSummary[];
|
|
204
340
|
readonly numberingRows: readonly AdjacentGeometryNumberingRowSummary[];
|
|
@@ -210,16 +346,23 @@ export function summarizeAdjacentGeometryIntake(input: {
|
|
|
210
346
|
readonly sourceRuns: AdjacentGeometryIntakeSummary["sourceRuns"];
|
|
211
347
|
readonly numberingArtifact: unknown;
|
|
212
348
|
readonly numberingLiveJoinArtifacts: readonly unknown[];
|
|
349
|
+
readonly numberingRuntimeReadbackArtifacts?: readonly unknown[];
|
|
213
350
|
readonly fieldRegionRuntimeReadback: unknown;
|
|
214
351
|
readonly fieldRegionLiveJoinArtifacts: readonly unknown[];
|
|
215
352
|
}): AdjacentGeometryIntakeSummary {
|
|
353
|
+
const pageFramesByDocId = collectPageFramesByDocId(
|
|
354
|
+
input.numberingRuntimeReadbackArtifacts ?? [],
|
|
355
|
+
);
|
|
216
356
|
const numberingRows = summarizeNumberingRows(
|
|
217
357
|
input.numberingArtifact,
|
|
218
358
|
input.numberingLiveJoinArtifacts,
|
|
359
|
+
input.numberingRuntimeReadbackArtifacts ?? [],
|
|
360
|
+
pageFramesByDocId,
|
|
219
361
|
);
|
|
220
362
|
const fieldRegionRows = summarizeFieldRegionRows(
|
|
221
363
|
input.fieldRegionRuntimeReadback,
|
|
222
364
|
input.fieldRegionLiveJoinArtifacts,
|
|
365
|
+
pageFramesByDocId,
|
|
223
366
|
);
|
|
224
367
|
const docIds = [
|
|
225
368
|
...new Set([
|
|
@@ -228,7 +371,7 @@ export function summarizeAdjacentGeometryIntake(input: {
|
|
|
228
371
|
]),
|
|
229
372
|
].sort();
|
|
230
373
|
return {
|
|
231
|
-
schemaVersion: "layer-05-adjacent-geometry-intake/
|
|
374
|
+
schemaVersion: "layer-05-adjacent-geometry-intake/v2",
|
|
232
375
|
generatedAtUtc: input.generatedAtUtc,
|
|
233
376
|
sourceRuns: input.sourceRuns,
|
|
234
377
|
totals: {
|
|
@@ -236,6 +379,9 @@ export function summarizeAdjacentGeometryIntake(input: {
|
|
|
236
379
|
numberingRowsWithRuntimeFragment: numberingRows.filter(
|
|
237
380
|
(row) => row.runtimeFragmentId !== undefined,
|
|
238
381
|
).length,
|
|
382
|
+
numberingRowsJoinedFromL04Readback: numberingRows.filter(
|
|
383
|
+
(row) => row.runtimeJoinSource === "l04-numbering-readback",
|
|
384
|
+
).length,
|
|
239
385
|
numberingParagraphLineRects: sum(
|
|
240
386
|
numberingRows,
|
|
241
387
|
(row) => row.paragraphLineRectCount,
|
|
@@ -258,6 +404,28 @@ export function summarizeAdjacentGeometryIntake(input: {
|
|
|
258
404
|
numberingRowsWithPageLocalTextColumn: numberingRows.filter(
|
|
259
405
|
(row) => row.pageLocalGeometry.textColumn !== undefined,
|
|
260
406
|
).length,
|
|
407
|
+
numberingRowsWithRuntimePageMatch: numberingRows.filter(
|
|
408
|
+
(row) => row.pageLocalGeometry.pageIndexStatus === "matches-runtime",
|
|
409
|
+
).length,
|
|
410
|
+
numberingUiaRowsWithRuntimePageMatch: numberingRows.filter(
|
|
411
|
+
(row) =>
|
|
412
|
+
hasNumberingUiaCapture(row) &&
|
|
413
|
+
row.pageLocalGeometry.pageIndexStatus === "matches-runtime",
|
|
414
|
+
).length,
|
|
415
|
+
numberingRowsWithL04FrameProjection: numberingRows.filter(hasL04FrameProjection)
|
|
416
|
+
.length,
|
|
417
|
+
numberingUiaRowsWithL04FrameProjection: numberingRows.filter(
|
|
418
|
+
(row) => hasNumberingUiaCapture(row) && hasL04FrameProjection(row),
|
|
419
|
+
).length,
|
|
420
|
+
numberingRowsWithFramePixelProjection: numberingRows.filter(
|
|
421
|
+
hasFramePixelProjection,
|
|
422
|
+
).length,
|
|
423
|
+
numberingUiaRowsWithFramePixelProjection: numberingRows.filter(
|
|
424
|
+
(row) => hasNumberingUiaCapture(row) && hasFramePixelProjection(row),
|
|
425
|
+
).length,
|
|
426
|
+
numberingCompositorReadyRows: numberingRows.filter(
|
|
427
|
+
(row) => row.pageLocalGeometry.compositorReady,
|
|
428
|
+
).length,
|
|
261
429
|
fieldRegionRows: fieldRegionRows.length,
|
|
262
430
|
fieldRegionRowsWithRuntimeId: fieldRegionRows.filter(
|
|
263
431
|
(row) => row.runtimeFieldRegionId !== undefined,
|
|
@@ -278,6 +446,21 @@ export function summarizeAdjacentGeometryIntake(input: {
|
|
|
278
446
|
fieldRegionRowsWithRuntimePageContainment: fieldRegionRows.filter(
|
|
279
447
|
(row) => row.pageLocalGeometry.pageSpanStatus === "contained-in-runtime",
|
|
280
448
|
).length,
|
|
449
|
+
fieldRegionRowsWithL04FrameProjection: fieldRegionRows.filter(
|
|
450
|
+
hasL04FrameProjection,
|
|
451
|
+
).length,
|
|
452
|
+
fieldRegionUiaRowsWithL04FrameProjection: fieldRegionRows.filter(
|
|
453
|
+
(row) => row.resultLineRectCount > 0 && hasL04FrameProjection(row),
|
|
454
|
+
).length,
|
|
455
|
+
fieldRegionRowsWithFramePixelProjection: fieldRegionRows.filter(
|
|
456
|
+
hasFramePixelProjection,
|
|
457
|
+
).length,
|
|
458
|
+
fieldRegionUiaRowsWithFramePixelProjection: fieldRegionRows.filter(
|
|
459
|
+
(row) => row.resultLineRectCount > 0 && hasFramePixelProjection(row),
|
|
460
|
+
).length,
|
|
461
|
+
fieldRegionCompositorReadyRows: fieldRegionRows.filter(
|
|
462
|
+
(row) => row.pageLocalGeometry.compositorReady,
|
|
463
|
+
).length,
|
|
281
464
|
},
|
|
282
465
|
routing: {
|
|
283
466
|
routedTo: "L05",
|
|
@@ -290,7 +473,14 @@ export function summarizeAdjacentGeometryIntake(input: {
|
|
|
290
473
|
coordinateSpace: "word-page-twips",
|
|
291
474
|
precision: "word-page-local-calibration",
|
|
292
475
|
requiredUpstreamFact: "L04 frame-to-pixel projection",
|
|
293
|
-
|
|
476
|
+
l04FrameProjectionCoordinateSpace: "l04-frame-twips",
|
|
477
|
+
l04FrameProjectionPrecision: "word-page-local-calibration",
|
|
478
|
+
framePixelCoordinateSpace: "frame-px",
|
|
479
|
+
framePixelPrecision: "word-page-local-calibration",
|
|
480
|
+
scaleSource: "runtime-render-frame-page-rect",
|
|
481
|
+
compositorReady:
|
|
482
|
+
numberingRows.some((row) => row.pageLocalGeometry.compositorReady) ||
|
|
483
|
+
fieldRegionRows.some((row) => row.pageLocalGeometry.compositorReady),
|
|
294
484
|
},
|
|
295
485
|
documents: docIds.map((docId) =>
|
|
296
486
|
summarizeDocument(
|
|
@@ -307,6 +497,8 @@ export function summarizeAdjacentGeometryIntake(input: {
|
|
|
307
497
|
function summarizeNumberingRows(
|
|
308
498
|
artifact: unknown,
|
|
309
499
|
liveJoinArtifacts: readonly unknown[],
|
|
500
|
+
runtimeReadbackArtifacts: readonly unknown[],
|
|
501
|
+
pageFramesByDocId: ReadonlyMap<string, ReadonlyMap<number, AdjacentGeometryPageFrame>>,
|
|
310
502
|
): readonly AdjacentGeometryNumberingRowSummary[] {
|
|
311
503
|
const uiaRowsByKey = new Map<string, Record<string, unknown>>();
|
|
312
504
|
for (const raw of array(record(artifact).rows)) {
|
|
@@ -322,8 +514,16 @@ function summarizeNumberingRows(
|
|
|
322
514
|
const liveRows = liveJoinArtifacts.flatMap((artifact) =>
|
|
323
515
|
array(record(artifact).numberingRows).map(record),
|
|
324
516
|
);
|
|
517
|
+
const runtimeReadbacksByKey = collectNumberingRuntimeReadbacks(
|
|
518
|
+
runtimeReadbackArtifacts,
|
|
519
|
+
);
|
|
325
520
|
const rows = liveRows.length > 0
|
|
326
|
-
? liveRows.filter((row) =>
|
|
521
|
+
? liveRows.filter((row) => {
|
|
522
|
+
if (stringValue(row.runtimeFragmentId) !== undefined) return true;
|
|
523
|
+
return (
|
|
524
|
+
numberingRuntimeReadbackForRow(row, runtimeReadbacksByKey) !== undefined
|
|
525
|
+
);
|
|
526
|
+
})
|
|
327
527
|
: array(record(artifact).rows).map(record);
|
|
328
528
|
|
|
329
529
|
return rows
|
|
@@ -338,6 +538,10 @@ function summarizeNumberingRows(
|
|
|
338
538
|
const uiaRow =
|
|
339
539
|
uiaRowsByKey.get(numberingKey(docId, wordParagraphOrdinalGlobal) ?? "") ??
|
|
340
540
|
{};
|
|
541
|
+
const runtimeReadback = numberingRuntimeReadbackForRow(
|
|
542
|
+
row,
|
|
543
|
+
runtimeReadbacksByKey,
|
|
544
|
+
);
|
|
341
545
|
const uiaTargetJoin = record(uiaRow.targetJoin);
|
|
342
546
|
const paragraphLineRects = chooseRects(
|
|
343
547
|
uiaRow.paragraphLineRects,
|
|
@@ -350,28 +554,63 @@ function summarizeNumberingRows(
|
|
|
350
554
|
const rawMarkerRects = chooseRawArray(uiaRow.markerRects, row.markerRects);
|
|
351
555
|
const markerRects = chooseRects(uiaRow.markerRects, row.markerRects);
|
|
352
556
|
const markerLane =
|
|
353
|
-
normalizeTwipsRect(row.markerLane) ??
|
|
557
|
+
normalizeTwipsRect(row.markerLane) ??
|
|
558
|
+
normalizeTwipsRect(runtimeReadback?.markerLane) ??
|
|
559
|
+
normalizeTwipsRect(uiaTargetJoin.markerLane);
|
|
354
560
|
const textColumn =
|
|
355
|
-
normalizeTwipsRect(row.textColumn) ??
|
|
561
|
+
normalizeTwipsRect(row.textColumn) ??
|
|
562
|
+
normalizeTwipsRect(runtimeReadback?.textColumn) ??
|
|
563
|
+
normalizeTwipsRect(uiaTargetJoin.textColumn);
|
|
356
564
|
const runtimeFragmentId =
|
|
357
|
-
stringValue(row.runtimeFragmentId) ??
|
|
565
|
+
stringValue(row.runtimeFragmentId) ??
|
|
566
|
+
stringValue(runtimeReadback?.runtimeFragmentId) ??
|
|
567
|
+
stringValue(uiaTargetJoin.runtimeFragmentId);
|
|
568
|
+
const runtimeJoinSource: AdjacentGeometryNumberingRowSummary["runtimeJoinSource"] =
|
|
569
|
+
stringValue(row.runtimeFragmentId) !== undefined
|
|
570
|
+
? "adjacent-live"
|
|
571
|
+
: "l04-numbering-readback";
|
|
358
572
|
const runtimePageIndex =
|
|
359
|
-
numberValue(row.runtimePageIndex) ??
|
|
573
|
+
numberValue(row.runtimePageIndex) ??
|
|
574
|
+
numberValue(runtimeReadback?.pageIndex) ??
|
|
575
|
+
numberValue(uiaTargetJoin.runtimePageIndex);
|
|
360
576
|
const wordStartPage =
|
|
361
577
|
numberValue(record(row.pageSpan).startPage) ??
|
|
362
578
|
numberValue(row.wordStartPage) ??
|
|
363
579
|
numberValue(uiaRow.wordStartPage);
|
|
580
|
+
const normalizedWordPageIndex =
|
|
581
|
+
wordStartPage === undefined ? undefined : wordStartPage - 1;
|
|
582
|
+
const pageIndexStatus = classifyPageIndex(
|
|
583
|
+
normalizedWordPageIndex,
|
|
584
|
+
runtimePageIndex,
|
|
585
|
+
);
|
|
586
|
+
const l04FrameProjection = projectNumberingToL04Frame({
|
|
587
|
+
docId,
|
|
588
|
+
normalizedWordPageIndex,
|
|
589
|
+
runtimePageIndex,
|
|
590
|
+
pageIndexStatus,
|
|
591
|
+
markerLane,
|
|
592
|
+
textColumn,
|
|
593
|
+
pageFramesByDocId,
|
|
594
|
+
});
|
|
595
|
+
const framePixelProjection = projectNumberingToFramePixels(l04FrameProjection);
|
|
364
596
|
const pageLocalGeometry: AdjacentGeometryPageLocalNumberingGeometry = {
|
|
365
597
|
wordPage: wordStartPage,
|
|
598
|
+
normalizedWordPageIndex,
|
|
366
599
|
runtimePageIndex,
|
|
600
|
+
pageIndexStatus,
|
|
367
601
|
runtimeFragmentId,
|
|
368
602
|
markerLane,
|
|
369
603
|
textColumn,
|
|
604
|
+
l04FrameProjection,
|
|
605
|
+
framePixelProjection,
|
|
606
|
+
compositorReady: framePixelProjection.status === "projected-frame-pixels",
|
|
370
607
|
coordinateSpace: "word-page-twips",
|
|
371
608
|
precision: "word-page-local-calibration",
|
|
372
609
|
normalizationStatus:
|
|
373
|
-
|
|
374
|
-
? "
|
|
610
|
+
l04FrameProjection.status === "projected-l04-frame"
|
|
611
|
+
? "l04-frame-twips-projected"
|
|
612
|
+
: markerLane || textColumn
|
|
613
|
+
? "word-page-local-awaiting-l04-frame-projection"
|
|
375
614
|
: "missing-word-page-local-lane",
|
|
376
615
|
};
|
|
377
616
|
return {
|
|
@@ -380,11 +619,20 @@ function summarizeNumberingRows(
|
|
|
380
619
|
canonicalBlockId:
|
|
381
620
|
stringValue(row.canonicalBlockId) ?? stringValue(uiaTargetJoin.canonicalBlockId),
|
|
382
621
|
runtimeBlockId:
|
|
383
|
-
stringValue(row.runtimeBlockId) ??
|
|
622
|
+
stringValue(row.runtimeBlockId) ??
|
|
623
|
+
stringValue(runtimeReadback?.numberingSourceBlockId) ??
|
|
624
|
+
stringValue(runtimeReadback?.sourceBlockId) ??
|
|
625
|
+
stringValue(uiaTargetJoin.runtimeBlockId),
|
|
384
626
|
runtimeFragmentId,
|
|
627
|
+
runtimeNumberingId:
|
|
628
|
+
stringValue(runtimeReadback?.runtimeNumberingId) ??
|
|
629
|
+
stringValue(record(row.runtimeJoinAttempt).runtimeNumberingId),
|
|
630
|
+
layoutObjectId: stringValue(runtimeReadback?.layoutObjectId),
|
|
631
|
+
runtimeJoinSource,
|
|
385
632
|
runtimePageIndex,
|
|
386
633
|
sourceParagraphPath:
|
|
387
634
|
stringValue(row.sourceParagraphPath) ??
|
|
635
|
+
stringValue(runtimeReadback?.sourceBlockPath) ??
|
|
388
636
|
stringValue(uiaTargetJoin.sourceParagraphPath),
|
|
389
637
|
canonicalNumberingInstanceId:
|
|
390
638
|
stringValue(row.canonicalNumberingInstanceId) ??
|
|
@@ -403,6 +651,7 @@ function summarizeNumberingRows(
|
|
|
403
651
|
markerLane,
|
|
404
652
|
textColumn,
|
|
405
653
|
pageLocalGeometry,
|
|
654
|
+
compositorReady: pageLocalGeometry.compositorReady,
|
|
406
655
|
rangeMappingMethod:
|
|
407
656
|
stringValue(uiaRow.rangeMappingMethod) ?? stringValue(row.rangeMappingMethod),
|
|
408
657
|
coordinateSpace: "screen-px" as const,
|
|
@@ -423,6 +672,7 @@ function summarizeNumberingRows(
|
|
|
423
672
|
function summarizeFieldRegionRows(
|
|
424
673
|
runtimeReadback: unknown,
|
|
425
674
|
liveJoinArtifacts: readonly unknown[],
|
|
675
|
+
pageFramesByDocId: ReadonlyMap<string, ReadonlyMap<number, AdjacentGeometryPageFrame>>,
|
|
426
676
|
): readonly AdjacentGeometryFieldRegionRowSummary[] {
|
|
427
677
|
const liveJoinByOrdinalKey = new Map<string, Record<string, unknown>>();
|
|
428
678
|
const uniqueLiveJoinRows: Record<string, unknown>[] = [];
|
|
@@ -500,18 +750,33 @@ function summarizeFieldRegionRows(
|
|
|
500
750
|
const wordPlacement = normalizeWordPlacement(
|
|
501
751
|
record(readbackRow.wordResultPlacement),
|
|
502
752
|
);
|
|
753
|
+
const pageSpanStatus = classifyPageSpan(normalizedWordPageIndexSpan, runtimePageSpan);
|
|
754
|
+
const l04FrameProjection = projectFieldToL04Frame({
|
|
755
|
+
docId,
|
|
756
|
+
normalizedWordPageIndexSpan,
|
|
757
|
+
runtimePageSpan,
|
|
758
|
+
pageSpanStatus,
|
|
759
|
+
wordPlacement,
|
|
760
|
+
pageFramesByDocId,
|
|
761
|
+
});
|
|
762
|
+
const framePixelProjection = projectFieldToFramePixels(l04FrameProjection);
|
|
503
763
|
const pageLocalGeometry: AdjacentGeometryPageLocalFieldGeometry = {
|
|
504
764
|
expectedPageSpan,
|
|
505
765
|
normalizedWordPageIndexSpan,
|
|
506
766
|
runtimePageSpan,
|
|
507
|
-
pageSpanStatus
|
|
767
|
+
pageSpanStatus,
|
|
508
768
|
startAnchorTwips: wordPlacement?.startXYTwips,
|
|
509
769
|
endAnchorTwips: wordPlacement?.endXYTwips,
|
|
770
|
+
l04FrameProjection,
|
|
771
|
+
framePixelProjection,
|
|
772
|
+
compositorReady: framePixelProjection.status === "projected-frame-pixels",
|
|
510
773
|
coordinateSpace: "word-page-twips",
|
|
511
774
|
precision: "word-page-local-calibration",
|
|
512
775
|
normalizationStatus:
|
|
513
|
-
|
|
514
|
-
? "
|
|
776
|
+
l04FrameProjection.status === "projected-l04-frame"
|
|
777
|
+
? "l04-frame-twips-projected"
|
|
778
|
+
: wordPlacement?.startXYTwips || wordPlacement?.endXYTwips
|
|
779
|
+
? "word-page-local-awaiting-l04-frame-projection"
|
|
515
780
|
: "missing-word-placement",
|
|
516
781
|
};
|
|
517
782
|
return {
|
|
@@ -534,6 +799,7 @@ function summarizeFieldRegionRows(
|
|
|
534
799
|
runtimePageSpan,
|
|
535
800
|
expectedPageSpan,
|
|
536
801
|
pageLocalGeometry,
|
|
802
|
+
compositorReady: pageLocalGeometry.compositorReady,
|
|
537
803
|
instructionFamily:
|
|
538
804
|
stringValue(liveJoin.instructionFamily) ??
|
|
539
805
|
stringValue(targetJoin.instructionFamily),
|
|
@@ -562,6 +828,9 @@ function summarizeDocument(
|
|
|
562
828
|
numberingRowsWithRuntimeFragment: numberingRows.filter(
|
|
563
829
|
(row) => row.runtimeFragmentId !== undefined,
|
|
564
830
|
).length,
|
|
831
|
+
numberingRowsJoinedFromL04Readback: numberingRows.filter(
|
|
832
|
+
(row) => row.runtimeJoinSource === "l04-numbering-readback",
|
|
833
|
+
).length,
|
|
565
834
|
numberingParagraphLineRects: sum(
|
|
566
835
|
numberingRows,
|
|
567
836
|
(row) => row.paragraphLineRectCount,
|
|
@@ -584,6 +853,27 @@ function summarizeDocument(
|
|
|
584
853
|
numberingRowsWithPageLocalTextColumn: numberingRows.filter(
|
|
585
854
|
(row) => row.pageLocalGeometry.textColumn !== undefined,
|
|
586
855
|
).length,
|
|
856
|
+
numberingRowsWithRuntimePageMatch: numberingRows.filter(
|
|
857
|
+
(row) => row.pageLocalGeometry.pageIndexStatus === "matches-runtime",
|
|
858
|
+
).length,
|
|
859
|
+
numberingUiaRowsWithRuntimePageMatch: numberingRows.filter(
|
|
860
|
+
(row) =>
|
|
861
|
+
hasNumberingUiaCapture(row) &&
|
|
862
|
+
row.pageLocalGeometry.pageIndexStatus === "matches-runtime",
|
|
863
|
+
).length,
|
|
864
|
+
numberingRowsWithL04FrameProjection: numberingRows.filter(hasL04FrameProjection)
|
|
865
|
+
.length,
|
|
866
|
+
numberingUiaRowsWithL04FrameProjection: numberingRows.filter(
|
|
867
|
+
(row) => hasNumberingUiaCapture(row) && hasL04FrameProjection(row),
|
|
868
|
+
).length,
|
|
869
|
+
numberingRowsWithFramePixelProjection: numberingRows.filter(
|
|
870
|
+
hasFramePixelProjection,
|
|
871
|
+
).length,
|
|
872
|
+
numberingUiaRowsWithFramePixelProjection: numberingRows.filter(
|
|
873
|
+
(row) => hasNumberingUiaCapture(row) && hasFramePixelProjection(row),
|
|
874
|
+
).length,
|
|
875
|
+
numberingCompositorReadyRows: numberingRows.filter((row) => row.compositorReady)
|
|
876
|
+
.length,
|
|
587
877
|
fieldRegionRows: fieldRegionRows.length,
|
|
588
878
|
fieldRegionRowsWithRuntimeId: fieldRegionRows.filter(
|
|
589
879
|
(row) => row.runtimeFieldRegionId !== undefined,
|
|
@@ -604,9 +894,35 @@ function summarizeDocument(
|
|
|
604
894
|
fieldRegionRowsWithRuntimePageContainment: fieldRegionRows.filter(
|
|
605
895
|
(row) => row.pageLocalGeometry.pageSpanStatus === "contained-in-runtime",
|
|
606
896
|
).length,
|
|
897
|
+
fieldRegionRowsWithL04FrameProjection: fieldRegionRows.filter(
|
|
898
|
+
hasL04FrameProjection,
|
|
899
|
+
).length,
|
|
900
|
+
fieldRegionUiaRowsWithL04FrameProjection: fieldRegionRows.filter(
|
|
901
|
+
(row) => row.resultLineRectCount > 0 && hasL04FrameProjection(row),
|
|
902
|
+
).length,
|
|
903
|
+
fieldRegionRowsWithFramePixelProjection: fieldRegionRows.filter(
|
|
904
|
+
hasFramePixelProjection,
|
|
905
|
+
).length,
|
|
906
|
+
fieldRegionUiaRowsWithFramePixelProjection: fieldRegionRows.filter(
|
|
907
|
+
(row) => row.resultLineRectCount > 0 && hasFramePixelProjection(row),
|
|
908
|
+
).length,
|
|
909
|
+
fieldRegionCompositorReadyRows: fieldRegionRows.filter((row) => row.compositorReady)
|
|
910
|
+
.length,
|
|
607
911
|
};
|
|
608
912
|
}
|
|
609
913
|
|
|
914
|
+
function hasL04FrameProjection(
|
|
915
|
+
row: AdjacentGeometryNumberingRowSummary | AdjacentGeometryFieldRegionRowSummary,
|
|
916
|
+
): boolean {
|
|
917
|
+
return row.pageLocalGeometry.l04FrameProjection.status === "projected-l04-frame";
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
function hasFramePixelProjection(
|
|
921
|
+
row: AdjacentGeometryNumberingRowSummary | AdjacentGeometryFieldRegionRowSummary,
|
|
922
|
+
): boolean {
|
|
923
|
+
return row.pageLocalGeometry.framePixelProjection.status === "projected-frame-pixels";
|
|
924
|
+
}
|
|
925
|
+
|
|
610
926
|
function hasNumberingUiaCapture(row: AdjacentGeometryNumberingRowSummary): boolean {
|
|
611
927
|
return (
|
|
612
928
|
row.paragraphLineRectCount > 0 ||
|
|
@@ -615,6 +931,462 @@ function hasNumberingUiaCapture(row: AdjacentGeometryNumberingRowSummary): boole
|
|
|
615
931
|
);
|
|
616
932
|
}
|
|
617
933
|
|
|
934
|
+
function collectPageFramesByDocId(
|
|
935
|
+
artifacts: readonly unknown[],
|
|
936
|
+
): Map<string, Map<number, AdjacentGeometryPageFrame>> {
|
|
937
|
+
const byDocId = new Map<string, Map<number, AdjacentGeometryPageFrame>>();
|
|
938
|
+
for (const artifact of artifacts) {
|
|
939
|
+
const artifactRecord = record(artifact);
|
|
940
|
+
const docId = stringValue(artifactRecord.docId);
|
|
941
|
+
if (!docId) continue;
|
|
942
|
+
for (const raw of array(artifactRecord.pages)) {
|
|
943
|
+
const page = record(raw);
|
|
944
|
+
const pageIndex = numberValue(page.pageIndex);
|
|
945
|
+
if (pageIndex === undefined) continue;
|
|
946
|
+
const frame = record(page.frame);
|
|
947
|
+
const physicalBoundsTwips = normalizeTwipsRect(frame.physicalBoundsTwips);
|
|
948
|
+
const renderFrame = record(page.renderFrame);
|
|
949
|
+
const renderPageFrame = normalizeFramePxRect(renderFrame.frame);
|
|
950
|
+
const renderFrameRevision = numberValue(renderFrame.revision);
|
|
951
|
+
const zoomPxPerTwip =
|
|
952
|
+
numberValue(record(page.renderZoom).pxPerTwip) ??
|
|
953
|
+
numberValue(renderFrame.zoomPxPerTwip);
|
|
954
|
+
const frameId = stringValue(frame.frameId);
|
|
955
|
+
const pageFrame: AdjacentGeometryPageFrame = {
|
|
956
|
+
pageId: stringValue(page.pageId),
|
|
957
|
+
pageIndex,
|
|
958
|
+
frameId,
|
|
959
|
+
completeness: stringValue(frame.completeness),
|
|
960
|
+
physicalBoundsTwips,
|
|
961
|
+
framePixelScale: buildFramePixelScale({
|
|
962
|
+
pageIndex,
|
|
963
|
+
pageId: stringValue(page.pageId),
|
|
964
|
+
frameId,
|
|
965
|
+
physicalBoundsTwips,
|
|
966
|
+
renderPageFrame,
|
|
967
|
+
renderFrameRevision,
|
|
968
|
+
zoomPxPerTwip,
|
|
969
|
+
}),
|
|
970
|
+
};
|
|
971
|
+
let docFrames = byDocId.get(docId);
|
|
972
|
+
if (!docFrames) {
|
|
973
|
+
docFrames = new Map<number, AdjacentGeometryPageFrame>();
|
|
974
|
+
byDocId.set(docId, docFrames);
|
|
975
|
+
}
|
|
976
|
+
if (!docFrames.has(pageIndex)) docFrames.set(pageIndex, pageFrame);
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
return byDocId;
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
function buildFramePixelScale(input: {
|
|
983
|
+
readonly pageIndex: number;
|
|
984
|
+
readonly pageId?: string;
|
|
985
|
+
readonly frameId?: string;
|
|
986
|
+
readonly physicalBoundsTwips?: AdjacentGeometryTwipsRect;
|
|
987
|
+
readonly renderPageFrame?: AdjacentGeometryFramePxRect;
|
|
988
|
+
readonly renderFrameRevision?: number;
|
|
989
|
+
readonly zoomPxPerTwip?: number;
|
|
990
|
+
}): AdjacentGeometryFramePixelScale | undefined {
|
|
991
|
+
const physicalBounds = input.physicalBoundsTwips;
|
|
992
|
+
const renderPageFrame = input.renderPageFrame;
|
|
993
|
+
if (!physicalBounds || !renderPageFrame) return undefined;
|
|
994
|
+
if (
|
|
995
|
+
physicalBounds.xTwips === undefined ||
|
|
996
|
+
physicalBounds.yTwips === undefined ||
|
|
997
|
+
physicalBounds.widthTwips === undefined ||
|
|
998
|
+
physicalBounds.heightTwips === undefined ||
|
|
999
|
+
physicalBounds.widthTwips <= 0 ||
|
|
1000
|
+
physicalBounds.heightTwips <= 0
|
|
1001
|
+
) {
|
|
1002
|
+
return undefined;
|
|
1003
|
+
}
|
|
1004
|
+
const pxPerTwipX = renderPageFrame.widthPx / physicalBounds.widthTwips;
|
|
1005
|
+
const pxPerTwipY = renderPageFrame.heightPx / physicalBounds.heightTwips;
|
|
1006
|
+
if (!isFinitePositive(pxPerTwipX) || !isFinitePositive(pxPerTwipY)) {
|
|
1007
|
+
return undefined;
|
|
1008
|
+
}
|
|
1009
|
+
return {
|
|
1010
|
+
source: "runtime-render-frame-page-rect",
|
|
1011
|
+
pageIndex: input.pageIndex,
|
|
1012
|
+
pageId: input.pageId,
|
|
1013
|
+
frameId: input.frameId,
|
|
1014
|
+
renderFrameRevision: input.renderFrameRevision,
|
|
1015
|
+
renderPageFrame,
|
|
1016
|
+
physicalBoundsTwips: physicalBounds,
|
|
1017
|
+
pxPerTwipX,
|
|
1018
|
+
pxPerTwipY,
|
|
1019
|
+
zoomPxPerTwip:
|
|
1020
|
+
input.zoomPxPerTwip === undefined ? undefined : roundNumber(input.zoomPxPerTwip),
|
|
1021
|
+
};
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
function collectNumberingRuntimeReadbacks(
|
|
1025
|
+
artifacts: readonly unknown[],
|
|
1026
|
+
): Map<string, Record<string, unknown>> {
|
|
1027
|
+
const byKey = new Map<string, Record<string, unknown>>();
|
|
1028
|
+
for (const artifact of artifacts) {
|
|
1029
|
+
const artifactRecord = record(artifact);
|
|
1030
|
+
const docId = stringValue(artifactRecord.docId);
|
|
1031
|
+
for (const raw of array(artifactRecord.numberingFragments)) {
|
|
1032
|
+
const row = record(raw);
|
|
1033
|
+
const key = numberingRuntimeReadbackKey(
|
|
1034
|
+
docId ?? stringValue(row.docId),
|
|
1035
|
+
stringValue(row.numberingKey) ?? stringValue(row.runtimeNumberingId),
|
|
1036
|
+
stringValue(row.numberingInstanceId),
|
|
1037
|
+
numberValue(row.level),
|
|
1038
|
+
);
|
|
1039
|
+
if (key && !byKey.has(key)) byKey.set(key, row);
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
return byKey;
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
function numberingRuntimeReadbackForRow(
|
|
1046
|
+
row: Record<string, unknown>,
|
|
1047
|
+
runtimeReadbacksByKey: ReadonlyMap<string, Record<string, unknown>>,
|
|
1048
|
+
): Record<string, unknown> | undefined {
|
|
1049
|
+
const key = numberingRuntimeReadbackKey(
|
|
1050
|
+
stringValue(row.docId),
|
|
1051
|
+
stringValue(record(row.canonicalJoinAttempt).numberingKey),
|
|
1052
|
+
stringValue(row.canonicalNumberingInstanceId),
|
|
1053
|
+
numberValue(row.canonicalLevel),
|
|
1054
|
+
);
|
|
1055
|
+
return key ? runtimeReadbacksByKey.get(key) : undefined;
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
function projectNumberingToL04Frame(input: {
|
|
1059
|
+
readonly docId: string;
|
|
1060
|
+
readonly normalizedWordPageIndex: number | undefined;
|
|
1061
|
+
readonly runtimePageIndex: number | undefined;
|
|
1062
|
+
readonly pageIndexStatus: AdjacentGeometryPageIndexStatus;
|
|
1063
|
+
readonly markerLane: AdjacentGeometryTwipsRect | undefined;
|
|
1064
|
+
readonly textColumn: AdjacentGeometryTwipsRect | undefined;
|
|
1065
|
+
readonly pageFramesByDocId: ReadonlyMap<string, ReadonlyMap<number, AdjacentGeometryPageFrame>>;
|
|
1066
|
+
}): AdjacentGeometryL04FrameProjection {
|
|
1067
|
+
if (input.pageIndexStatus === "word-page-missing") {
|
|
1068
|
+
return baseFrameProjection("word-page-missing");
|
|
1069
|
+
}
|
|
1070
|
+
if (input.pageIndexStatus === "runtime-missing") {
|
|
1071
|
+
return baseFrameProjection("runtime-page-missing", input.normalizedWordPageIndex);
|
|
1072
|
+
}
|
|
1073
|
+
if (input.pageIndexStatus === "differs-from-runtime") {
|
|
1074
|
+
return baseFrameProjection(
|
|
1075
|
+
"page-index-differs-from-runtime",
|
|
1076
|
+
input.normalizedWordPageIndex,
|
|
1077
|
+
);
|
|
1078
|
+
}
|
|
1079
|
+
if (!input.markerLane && !input.textColumn) {
|
|
1080
|
+
return baseFrameProjection(
|
|
1081
|
+
"missing-word-page-local-geometry",
|
|
1082
|
+
input.normalizedWordPageIndex,
|
|
1083
|
+
);
|
|
1084
|
+
}
|
|
1085
|
+
const frame = pageFrameFor(input.pageFramesByDocId, input.docId, input.runtimePageIndex);
|
|
1086
|
+
if (!frame?.physicalBoundsTwips) {
|
|
1087
|
+
return baseFrameProjection("missing-l04-page-frame", input.runtimePageIndex);
|
|
1088
|
+
}
|
|
1089
|
+
return {
|
|
1090
|
+
pageIndex: input.runtimePageIndex,
|
|
1091
|
+
pageId: frame.pageId,
|
|
1092
|
+
frameId: frame.frameId,
|
|
1093
|
+
frameCompleteness: frame.completeness,
|
|
1094
|
+
physicalBoundsTwips: frame.physicalBoundsTwips,
|
|
1095
|
+
framePixelScale: frame.framePixelScale,
|
|
1096
|
+
markerLane: addFrameOrigin(input.markerLane, frame.physicalBoundsTwips),
|
|
1097
|
+
textColumn: addFrameOrigin(input.textColumn, frame.physicalBoundsTwips),
|
|
1098
|
+
coordinateSpace: "l04-frame-twips",
|
|
1099
|
+
precision: "word-page-local-calibration",
|
|
1100
|
+
status: "projected-l04-frame",
|
|
1101
|
+
};
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
function projectFieldToL04Frame(input: {
|
|
1105
|
+
readonly docId: string;
|
|
1106
|
+
readonly normalizedWordPageIndexSpan: AdjacentGeometryPageSpan | undefined;
|
|
1107
|
+
readonly runtimePageSpan: AdjacentGeometryPageSpan | undefined;
|
|
1108
|
+
readonly pageSpanStatus: AdjacentGeometryPageLocalFieldGeometry["pageSpanStatus"];
|
|
1109
|
+
readonly wordPlacement:
|
|
1110
|
+
| AdjacentGeometryFieldRegionRowSummary["wordPlacement"]
|
|
1111
|
+
| undefined;
|
|
1112
|
+
readonly pageFramesByDocId: ReadonlyMap<string, ReadonlyMap<number, AdjacentGeometryPageFrame>>;
|
|
1113
|
+
}): AdjacentGeometryL04FrameProjection {
|
|
1114
|
+
const normalizedStart = input.normalizedWordPageIndexSpan?.startPage;
|
|
1115
|
+
if (normalizedStart == null) return baseFrameProjection("word-page-missing");
|
|
1116
|
+
if (!input.runtimePageSpan || input.runtimePageSpan.startPage == null) {
|
|
1117
|
+
return baseFrameProjection("runtime-page-missing", normalizedStart);
|
|
1118
|
+
}
|
|
1119
|
+
if (
|
|
1120
|
+
input.pageSpanStatus !== "matches-runtime" &&
|
|
1121
|
+
input.pageSpanStatus !== "contained-in-runtime"
|
|
1122
|
+
) {
|
|
1123
|
+
return baseFrameProjection("page-index-differs-from-runtime", normalizedStart);
|
|
1124
|
+
}
|
|
1125
|
+
if (!input.wordPlacement?.startXYTwips && !input.wordPlacement?.endXYTwips) {
|
|
1126
|
+
return baseFrameProjection("missing-word-page-local-geometry", normalizedStart);
|
|
1127
|
+
}
|
|
1128
|
+
const frame = pageFrameFor(
|
|
1129
|
+
input.pageFramesByDocId,
|
|
1130
|
+
input.docId,
|
|
1131
|
+
input.runtimePageSpan.startPage,
|
|
1132
|
+
);
|
|
1133
|
+
if (!frame?.physicalBoundsTwips) {
|
|
1134
|
+
return baseFrameProjection("missing-l04-page-frame", input.runtimePageSpan.startPage);
|
|
1135
|
+
}
|
|
1136
|
+
return {
|
|
1137
|
+
pageIndex: input.runtimePageSpan.startPage,
|
|
1138
|
+
pageId: frame.pageId,
|
|
1139
|
+
frameId: frame.frameId,
|
|
1140
|
+
frameCompleteness: frame.completeness,
|
|
1141
|
+
physicalBoundsTwips: frame.physicalBoundsTwips,
|
|
1142
|
+
framePixelScale: frame.framePixelScale,
|
|
1143
|
+
fieldStartAnchorTwips: addFrameOriginToPoint(
|
|
1144
|
+
input.wordPlacement.startXYTwips,
|
|
1145
|
+
frame.physicalBoundsTwips,
|
|
1146
|
+
),
|
|
1147
|
+
fieldEndAnchorTwips: addFrameOriginToPoint(
|
|
1148
|
+
input.wordPlacement.endXYTwips,
|
|
1149
|
+
frame.physicalBoundsTwips,
|
|
1150
|
+
),
|
|
1151
|
+
coordinateSpace: "l04-frame-twips",
|
|
1152
|
+
precision: "word-page-local-calibration",
|
|
1153
|
+
status: "projected-l04-frame",
|
|
1154
|
+
};
|
|
1155
|
+
}
|
|
1156
|
+
|
|
1157
|
+
function projectNumberingToFramePixels(
|
|
1158
|
+
projection: AdjacentGeometryL04FrameProjection,
|
|
1159
|
+
): AdjacentGeometryFramePixelProjection {
|
|
1160
|
+
if (projection.status !== "projected-l04-frame") {
|
|
1161
|
+
return baseFramePixelProjection("awaiting-l04-frame-projection", projection);
|
|
1162
|
+
}
|
|
1163
|
+
const scale = projectionScale(projection);
|
|
1164
|
+
if (!scale) return baseFramePixelProjection("missing-frame-pixel-scale", projection);
|
|
1165
|
+
const markerLane = l04FrameTwipsRectToFramePx(projection.markerLane, scale);
|
|
1166
|
+
const textColumn = l04FrameTwipsRectToFramePx(projection.textColumn, scale);
|
|
1167
|
+
if (!markerLane) {
|
|
1168
|
+
return baseFramePixelProjection("missing-l04-frame-rect", projection, scale);
|
|
1169
|
+
}
|
|
1170
|
+
return {
|
|
1171
|
+
pageIndex: projection.pageIndex,
|
|
1172
|
+
pageId: projection.pageId,
|
|
1173
|
+
frameId: projection.frameId,
|
|
1174
|
+
scale,
|
|
1175
|
+
markerLane,
|
|
1176
|
+
textColumn,
|
|
1177
|
+
coordinateSpace: "frame-px",
|
|
1178
|
+
precision: "word-page-local-calibration",
|
|
1179
|
+
status: "projected-frame-pixels",
|
|
1180
|
+
};
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1183
|
+
function projectFieldToFramePixels(
|
|
1184
|
+
projection: AdjacentGeometryL04FrameProjection,
|
|
1185
|
+
): AdjacentGeometryFramePixelProjection {
|
|
1186
|
+
if (projection.status !== "projected-l04-frame") {
|
|
1187
|
+
return baseFramePixelProjection("awaiting-l04-frame-projection", projection);
|
|
1188
|
+
}
|
|
1189
|
+
const scale = projectionScale(projection);
|
|
1190
|
+
if (!scale) return baseFramePixelProjection("missing-frame-pixel-scale", projection);
|
|
1191
|
+
const fieldStartAnchorPx = l04FrameTwipsPointToFramePx(
|
|
1192
|
+
projection.fieldStartAnchorTwips,
|
|
1193
|
+
scale,
|
|
1194
|
+
);
|
|
1195
|
+
const fieldEndAnchorPx = l04FrameTwipsPointToFramePx(
|
|
1196
|
+
projection.fieldEndAnchorTwips,
|
|
1197
|
+
scale,
|
|
1198
|
+
);
|
|
1199
|
+
if (!fieldStartAnchorPx || !fieldEndAnchorPx) {
|
|
1200
|
+
return baseFramePixelProjection("missing-l04-field-anchor", projection, scale);
|
|
1201
|
+
}
|
|
1202
|
+
return {
|
|
1203
|
+
pageIndex: projection.pageIndex,
|
|
1204
|
+
pageId: projection.pageId,
|
|
1205
|
+
frameId: projection.frameId,
|
|
1206
|
+
scale,
|
|
1207
|
+
fieldStartAnchorPx,
|
|
1208
|
+
fieldEndAnchorPx,
|
|
1209
|
+
fieldResultRangePx: rangeRectFromPoints(fieldStartAnchorPx, fieldEndAnchorPx),
|
|
1210
|
+
coordinateSpace: "frame-px",
|
|
1211
|
+
precision: "word-page-local-calibration",
|
|
1212
|
+
status: "projected-frame-pixels",
|
|
1213
|
+
};
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
function baseFrameProjection(
|
|
1217
|
+
status: AdjacentGeometryL04FrameProjection["status"],
|
|
1218
|
+
pageIndex?: number,
|
|
1219
|
+
): AdjacentGeometryL04FrameProjection {
|
|
1220
|
+
return {
|
|
1221
|
+
pageIndex,
|
|
1222
|
+
coordinateSpace: "l04-frame-twips",
|
|
1223
|
+
precision: "word-page-local-calibration",
|
|
1224
|
+
status,
|
|
1225
|
+
};
|
|
1226
|
+
}
|
|
1227
|
+
|
|
1228
|
+
function baseFramePixelProjection(
|
|
1229
|
+
status: AdjacentGeometryFramePixelProjection["status"],
|
|
1230
|
+
projection: AdjacentGeometryL04FrameProjection,
|
|
1231
|
+
scale?: AdjacentGeometryFramePixelScale,
|
|
1232
|
+
): AdjacentGeometryFramePixelProjection {
|
|
1233
|
+
return {
|
|
1234
|
+
pageIndex: projection.pageIndex,
|
|
1235
|
+
pageId: projection.pageId,
|
|
1236
|
+
frameId: projection.frameId,
|
|
1237
|
+
scale,
|
|
1238
|
+
coordinateSpace: "frame-px",
|
|
1239
|
+
precision: "word-page-local-calibration",
|
|
1240
|
+
status,
|
|
1241
|
+
};
|
|
1242
|
+
}
|
|
1243
|
+
|
|
1244
|
+
function pageFrameFor(
|
|
1245
|
+
pageFramesByDocId: ReadonlyMap<string, ReadonlyMap<number, AdjacentGeometryPageFrame>>,
|
|
1246
|
+
docId: string,
|
|
1247
|
+
pageIndex: number | undefined,
|
|
1248
|
+
): AdjacentGeometryPageFrame | undefined {
|
|
1249
|
+
return pageIndex === undefined ? undefined : pageFramesByDocId.get(docId)?.get(pageIndex);
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
function projectionScale(
|
|
1253
|
+
projection: AdjacentGeometryL04FrameProjection,
|
|
1254
|
+
): AdjacentGeometryFramePixelScale | undefined {
|
|
1255
|
+
return projection.framePixelScale;
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1258
|
+
function addFrameOrigin(
|
|
1259
|
+
rect: AdjacentGeometryTwipsRect | undefined,
|
|
1260
|
+
frame: AdjacentGeometryTwipsRect,
|
|
1261
|
+
): AdjacentGeometryTwipsRect | undefined {
|
|
1262
|
+
if (!rect) return undefined;
|
|
1263
|
+
return {
|
|
1264
|
+
xTwips:
|
|
1265
|
+
rect.xTwips === undefined || frame.xTwips === undefined
|
|
1266
|
+
? rect.xTwips
|
|
1267
|
+
: rect.xTwips + frame.xTwips,
|
|
1268
|
+
yTwips:
|
|
1269
|
+
rect.yTwips === undefined || frame.yTwips === undefined
|
|
1270
|
+
? rect.yTwips
|
|
1271
|
+
: rect.yTwips + frame.yTwips,
|
|
1272
|
+
widthTwips: rect.widthTwips,
|
|
1273
|
+
heightTwips: rect.heightTwips,
|
|
1274
|
+
};
|
|
1275
|
+
}
|
|
1276
|
+
|
|
1277
|
+
function addFrameOriginToPoint(
|
|
1278
|
+
point: { readonly x?: number; readonly y?: number } | undefined,
|
|
1279
|
+
frame: AdjacentGeometryTwipsRect,
|
|
1280
|
+
): { readonly x?: number; readonly y?: number } | undefined {
|
|
1281
|
+
if (!point) return undefined;
|
|
1282
|
+
return {
|
|
1283
|
+
x:
|
|
1284
|
+
point.x === undefined || frame.xTwips === undefined
|
|
1285
|
+
? point.x
|
|
1286
|
+
: point.x + frame.xTwips,
|
|
1287
|
+
y:
|
|
1288
|
+
point.y === undefined || frame.yTwips === undefined
|
|
1289
|
+
? point.y
|
|
1290
|
+
: point.y + frame.yTwips,
|
|
1291
|
+
};
|
|
1292
|
+
}
|
|
1293
|
+
|
|
1294
|
+
function l04FrameTwipsRectToFramePx(
|
|
1295
|
+
rect: AdjacentGeometryTwipsRect | undefined,
|
|
1296
|
+
scale: AdjacentGeometryFramePixelScale,
|
|
1297
|
+
): AdjacentGeometryFramePxRect | undefined {
|
|
1298
|
+
if (
|
|
1299
|
+
!rect ||
|
|
1300
|
+
rect.xTwips === undefined ||
|
|
1301
|
+
rect.yTwips === undefined ||
|
|
1302
|
+
rect.widthTwips === undefined ||
|
|
1303
|
+
rect.heightTwips === undefined ||
|
|
1304
|
+
scale.physicalBoundsTwips.xTwips === undefined ||
|
|
1305
|
+
scale.physicalBoundsTwips.yTwips === undefined
|
|
1306
|
+
) {
|
|
1307
|
+
return undefined;
|
|
1308
|
+
}
|
|
1309
|
+
return {
|
|
1310
|
+
leftPx: roundNumber(
|
|
1311
|
+
scale.renderPageFrame.leftPx +
|
|
1312
|
+
(rect.xTwips - scale.physicalBoundsTwips.xTwips) * scale.pxPerTwipX,
|
|
1313
|
+
),
|
|
1314
|
+
topPx: roundNumber(
|
|
1315
|
+
scale.renderPageFrame.topPx +
|
|
1316
|
+
(rect.yTwips - scale.physicalBoundsTwips.yTwips) * scale.pxPerTwipY,
|
|
1317
|
+
),
|
|
1318
|
+
widthPx: roundNumber(Math.max(0, rect.widthTwips * scale.pxPerTwipX)),
|
|
1319
|
+
heightPx: roundNumber(Math.max(0, rect.heightTwips * scale.pxPerTwipY)),
|
|
1320
|
+
coordinateSpace: "frame-px",
|
|
1321
|
+
};
|
|
1322
|
+
}
|
|
1323
|
+
|
|
1324
|
+
function l04FrameTwipsPointToFramePx(
|
|
1325
|
+
point: { readonly x?: number; readonly y?: number } | undefined,
|
|
1326
|
+
scale: AdjacentGeometryFramePixelScale,
|
|
1327
|
+
): AdjacentGeometryFramePxPoint | undefined {
|
|
1328
|
+
if (
|
|
1329
|
+
!point ||
|
|
1330
|
+
point.x === undefined ||
|
|
1331
|
+
point.y === undefined ||
|
|
1332
|
+
scale.physicalBoundsTwips.xTwips === undefined ||
|
|
1333
|
+
scale.physicalBoundsTwips.yTwips === undefined
|
|
1334
|
+
) {
|
|
1335
|
+
return undefined;
|
|
1336
|
+
}
|
|
1337
|
+
return {
|
|
1338
|
+
xPx: roundNumber(
|
|
1339
|
+
scale.renderPageFrame.leftPx +
|
|
1340
|
+
(point.x - scale.physicalBoundsTwips.xTwips) * scale.pxPerTwipX,
|
|
1341
|
+
),
|
|
1342
|
+
yPx: roundNumber(
|
|
1343
|
+
scale.renderPageFrame.topPx +
|
|
1344
|
+
(point.y - scale.physicalBoundsTwips.yTwips) * scale.pxPerTwipY,
|
|
1345
|
+
),
|
|
1346
|
+
coordinateSpace: "frame-px",
|
|
1347
|
+
};
|
|
1348
|
+
}
|
|
1349
|
+
|
|
1350
|
+
function rangeRectFromPoints(
|
|
1351
|
+
start: AdjacentGeometryFramePxPoint,
|
|
1352
|
+
end: AdjacentGeometryFramePxPoint,
|
|
1353
|
+
): AdjacentGeometryFramePxRect {
|
|
1354
|
+
const leftPx = Math.min(start.xPx, end.xPx);
|
|
1355
|
+
const topPx = Math.min(start.yPx, end.yPx);
|
|
1356
|
+
return {
|
|
1357
|
+
leftPx,
|
|
1358
|
+
topPx,
|
|
1359
|
+
widthPx: roundNumber(Math.abs(end.xPx - start.xPx)),
|
|
1360
|
+
heightPx: roundNumber(Math.abs(end.yPx - start.yPx)),
|
|
1361
|
+
coordinateSpace: "frame-px",
|
|
1362
|
+
};
|
|
1363
|
+
}
|
|
1364
|
+
|
|
1365
|
+
function classifyPageIndex(
|
|
1366
|
+
normalizedWordPageIndex: number | undefined,
|
|
1367
|
+
runtimePageIndex: number | undefined,
|
|
1368
|
+
): AdjacentGeometryPageIndexStatus {
|
|
1369
|
+
if (normalizedWordPageIndex === undefined) return "word-page-missing";
|
|
1370
|
+
if (runtimePageIndex === undefined) return "runtime-missing";
|
|
1371
|
+
return normalizedWordPageIndex === runtimePageIndex
|
|
1372
|
+
? "matches-runtime"
|
|
1373
|
+
: "differs-from-runtime";
|
|
1374
|
+
}
|
|
1375
|
+
|
|
1376
|
+
function numberingRuntimeReadbackKey(
|
|
1377
|
+
docId: string | undefined,
|
|
1378
|
+
numberingKeyValue: string | undefined,
|
|
1379
|
+
numberingInstanceId: string | undefined,
|
|
1380
|
+
level: number | undefined,
|
|
1381
|
+
): string | undefined {
|
|
1382
|
+
return docId &&
|
|
1383
|
+
numberingKeyValue &&
|
|
1384
|
+
numberingInstanceId &&
|
|
1385
|
+
level !== undefined
|
|
1386
|
+
? `${docId}\0${numberingKeyValue}\0${numberingInstanceId}\0${level}`
|
|
1387
|
+
: undefined;
|
|
1388
|
+
}
|
|
1389
|
+
|
|
618
1390
|
function normalizeRects(raw: unknown): readonly AdjacentGeometryRect[] {
|
|
619
1391
|
if (Array.isArray(raw)) return raw.map(normalizeRect).filter(isRect);
|
|
620
1392
|
const maybeRect = normalizeRect(raw);
|
|
@@ -661,6 +1433,31 @@ function normalizeRect(raw: unknown): AdjacentGeometryRect | undefined {
|
|
|
661
1433
|
};
|
|
662
1434
|
}
|
|
663
1435
|
|
|
1436
|
+
function normalizeFramePxRect(
|
|
1437
|
+
raw: unknown,
|
|
1438
|
+
): AdjacentGeometryFramePxRect | undefined {
|
|
1439
|
+
const rect = record(raw);
|
|
1440
|
+
const leftPx = numberValue(rect.leftPx);
|
|
1441
|
+
const topPx = numberValue(rect.topPx);
|
|
1442
|
+
const widthPx = numberValue(rect.widthPx);
|
|
1443
|
+
const heightPx = numberValue(rect.heightPx);
|
|
1444
|
+
if (
|
|
1445
|
+
leftPx === undefined ||
|
|
1446
|
+
topPx === undefined ||
|
|
1447
|
+
widthPx === undefined ||
|
|
1448
|
+
heightPx === undefined
|
|
1449
|
+
) {
|
|
1450
|
+
return undefined;
|
|
1451
|
+
}
|
|
1452
|
+
return {
|
|
1453
|
+
leftPx: roundNumber(leftPx),
|
|
1454
|
+
topPx: roundNumber(topPx),
|
|
1455
|
+
widthPx: roundNumber(widthPx),
|
|
1456
|
+
heightPx: roundNumber(heightPx),
|
|
1457
|
+
coordinateSpace: "frame-px",
|
|
1458
|
+
};
|
|
1459
|
+
}
|
|
1460
|
+
|
|
664
1461
|
function normalizeTwipsRect(raw: unknown):
|
|
665
1462
|
| {
|
|
666
1463
|
readonly xTwips?: number;
|
|
@@ -819,6 +1616,14 @@ function numberValue(value: unknown): number | undefined {
|
|
|
819
1616
|
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
820
1617
|
}
|
|
821
1618
|
|
|
1619
|
+
function isFinitePositive(value: number): boolean {
|
|
1620
|
+
return Number.isFinite(value) && value > 0;
|
|
1621
|
+
}
|
|
1622
|
+
|
|
1623
|
+
function roundNumber(value: number): number {
|
|
1624
|
+
return Number.parseFloat(value.toFixed(6));
|
|
1625
|
+
}
|
|
1626
|
+
|
|
822
1627
|
function nullableNumberValue(value: unknown): number | null | undefined {
|
|
823
1628
|
return value === null ? null : numberValue(value);
|
|
824
1629
|
}
|