documents.js 1.102.2 → 2.0.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.
Files changed (40) hide show
  1. package/README.md +8 -5
  2. package/dist/convert/composition.cjs +15 -4
  3. package/dist/convert/composition.js +15 -4
  4. package/dist/convert/convert.cjs +6 -3
  5. package/dist/convert/convert.js +6 -3
  6. package/dist/convert/from-package.cjs +179 -2
  7. package/dist/convert/from-package.d.cts +3 -2
  8. package/dist/convert/from-package.d.ts +3 -2
  9. package/dist/convert/from-package.js +179 -3
  10. package/dist/index.cjs +1 -0
  11. package/dist/index.d.cts +3 -3
  12. package/dist/index.d.ts +3 -3
  13. package/dist/index.js +2 -2
  14. package/dist/layout/drawing.cjs +71 -9
  15. package/dist/layout/drawing.d.cts +8 -3
  16. package/dist/layout/drawing.d.ts +8 -3
  17. package/dist/layout/drawing.js +71 -10
  18. package/dist/layout/engine.cjs +55 -43
  19. package/dist/layout/engine.d.cts +2 -1
  20. package/dist/layout/engine.d.ts +2 -1
  21. package/dist/layout/engine.js +57 -45
  22. package/dist/layout/reconstruct.cjs +259 -104
  23. package/dist/layout/reconstruct.js +259 -104
  24. package/dist/layout/shared.cjs +47 -2
  25. package/dist/layout/shared.d.cts +15 -4
  26. package/dist/layout/shared.d.ts +15 -4
  27. package/dist/layout/shared.js +44 -4
  28. package/dist/layout/sheets.cjs +18 -13
  29. package/dist/layout/sheets.d.cts +4 -2
  30. package/dist/layout/sheets.d.ts +4 -2
  31. package/dist/layout/sheets.js +20 -16
  32. package/dist/layout/slides.cjs +35 -31
  33. package/dist/layout/slides.d.cts +3 -2
  34. package/dist/layout/slides.d.ts +3 -2
  35. package/dist/layout/slides.js +37 -33
  36. package/dist/layout/text-layout.cjs +2 -1
  37. package/dist/layout/text-layout.d.cts +14 -3
  38. package/dist/layout/text-layout.d.ts +14 -3
  39. package/dist/layout/text-layout.js +2 -1
  40. package/package.json +5 -5
@@ -1,6 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_model_geometry = require("../model/geometry.cjs");
3
3
  const require_model_embedded_drawing = require("../model/embedded-drawing.cjs");
4
+ const require_layout_shared = require("./shared.cjs");
4
5
  const require_ports_abort = require("../ports/abort.cjs");
5
6
  const require_layout_cell_typing = require("./cell-typing.cjs");
6
7
  const require_layout_lattice = require("./lattice.cjs");
@@ -49,7 +50,37 @@ function textItemToContentRun(item) {
49
50
  };
50
51
  }
51
52
  const MIN_WORD_GAP_PT = .5;
52
- function pushRunsForLine(runs, line) {
53
+ function textBoxOfItem(item, pageIndex) {
54
+ const { ascentPt, descentPt } = textItemVerticalExtent(item);
55
+ return {
56
+ pageIndex,
57
+ xPt: item.xPt,
58
+ yPt: item.yPt - descentPt,
59
+ widthPt: item.widthPt ?? 0,
60
+ heightPt: ascentPt + descentPt
61
+ };
62
+ }
63
+ function lineBox(line, pageIndex) {
64
+ let minX = Number.POSITIVE_INFINITY;
65
+ let maxX = Number.NEGATIVE_INFINITY;
66
+ let minY = Number.POSITIVE_INFINITY;
67
+ let maxY = Number.NEGATIVE_INFINITY;
68
+ for (const item of line.items) {
69
+ const { ascentPt, descentPt } = textItemVerticalExtent(item);
70
+ minX = Math.min(minX, item.xPt);
71
+ maxX = Math.max(maxX, item.xPt + (item.widthPt ?? 0));
72
+ minY = Math.min(minY, item.yPt - descentPt);
73
+ maxY = Math.max(maxY, item.yPt + ascentPt);
74
+ }
75
+ return {
76
+ pageIndex,
77
+ xPt: minX,
78
+ yPt: minY,
79
+ widthPt: maxX - minX,
80
+ heightPt: maxY - minY
81
+ };
82
+ }
83
+ function pushRunsForLine(runs, line, pageIndex) {
53
84
  line.items.forEach((item, itemIndex) => {
54
85
  if (itemIndex > 0) {
55
86
  const prevItem = line.items[itemIndex - 1];
@@ -57,7 +88,9 @@ function pushRunsForLine(runs, line) {
57
88
  if (gap > LARGE_GAP_EM_MULTIPLIER * item.sizePt) runs.push({ text: " " });
58
89
  else if (gap > MIN_WORD_GAP_PT) runs[runs.length - 1].text += " ";
59
90
  }
60
- runs.push(textItemToContentRun(item));
91
+ const run = textItemToContentRun(item);
92
+ require_layout_shared.stampFrame(run, pageIndex, textBoxOfItem(item, pageIndex));
93
+ runs.push(run);
61
94
  });
62
95
  }
63
96
  function bucketCounts(values, bucketSize) {
@@ -103,15 +136,17 @@ function reconstructWordprocessing(doc, options) {
103
136
  const signal = options?.signal;
104
137
  const sections = [];
105
138
  let currentGroup = [];
139
+ let groupStartPageIndex = 0;
106
140
  for (const page of doc.pages) {
107
141
  require_ports_abort.throwIfAborted(signal);
108
142
  if (currentGroup.length > 0 && !samePageSize(currentGroup[0], page)) {
109
- sections.push(buildSection(currentGroup, doc.images));
143
+ sections.push(buildSection(currentGroup, groupStartPageIndex, doc.images));
144
+ groupStartPageIndex += currentGroup.length;
110
145
  currentGroup = [];
111
146
  }
112
147
  currentGroup.push(page);
113
148
  }
114
- if (currentGroup.length > 0) sections.push(buildSection(currentGroup, doc.images));
149
+ if (currentGroup.length > 0) sections.push(buildSection(currentGroup, groupStartPageIndex, doc.images));
115
150
  return {
116
151
  kind: "wordprocessing",
117
152
  formatVersion: document_schema_js.CONTENT_FORMAT_VERSION,
@@ -122,11 +157,11 @@ function reconstructWordprocessing(doc, options) {
122
157
  function samePageSize(a, b) {
123
158
  return a.widthPt === b.widthPt && a.heightPt === b.heightPt;
124
159
  }
125
- function buildSection(pages, images) {
160
+ function buildSection(pages, startPageIndex, images) {
126
161
  const blocks = [];
127
162
  pages.forEach((page, i) => {
128
163
  if (i > 0) blocks.push({ kind: "pageBreak" });
129
- blocks.push(...reconstructPageBlocks(page, images));
164
+ blocks.push(...reconstructPageBlocks(page, startPageIndex + i, images));
130
165
  });
131
166
  return {
132
167
  pageSize: {
@@ -137,8 +172,8 @@ function buildSection(pages, images) {
137
172
  blocks
138
173
  };
139
174
  }
140
- function reconstructPageBlocks(page, images) {
141
- const recoveredTable = recoverTable(page);
175
+ function reconstructPageBlocks(page, pageIndex, images) {
176
+ const recoveredTable = recoverTable(page, pageIndex);
142
177
  const consumedText = recoveredTable?.consumedText;
143
178
  const textItems = page.items.filter((i) => i.kind === "text" && consumedText?.has(i) !== true);
144
179
  const imageItems = page.items.filter((i) => i.kind === "image");
@@ -146,26 +181,35 @@ function reconstructPageBlocks(page, images) {
146
181
  const positioned = [];
147
182
  for (const paragraph of paragraphs) positioned.push({
148
183
  yPt: paragraph.lines[0].baselineY,
149
- block: paragraphToContentParagraph(paragraph)
184
+ block: paragraphToContentParagraph(paragraph, pageIndex)
150
185
  });
151
186
  for (const img of imageItems) {
152
187
  const asset = images[img.imageId];
153
- if (asset !== void 0) positioned.push({
154
- yPt: img.yPt,
155
- block: {
188
+ if (asset !== void 0) {
189
+ const block = {
156
190
  kind: "image",
157
191
  format: asset.format,
158
192
  base64: asset.base64,
159
193
  widthPt: img.widthPt,
160
194
  heightPt: img.heightPt
161
- }
162
- });
195
+ };
196
+ require_layout_shared.stampFrame(block, pageIndex, {
197
+ xPt: img.xPt,
198
+ yPt: img.yPt,
199
+ widthPt: img.widthPt,
200
+ heightPt: img.heightPt
201
+ });
202
+ positioned.push({
203
+ yPt: img.yPt,
204
+ block
205
+ });
206
+ }
163
207
  }
164
208
  if (recoveredTable !== void 0) positioned.push({
165
209
  yPt: recoveredTable.topYPt,
166
210
  block: recoveredTable.table
167
211
  });
168
- const recoveredVectors = recoverPageVectors(page, recoveredTable?.latticeItems ?? NO_ITEMS);
212
+ const recoveredVectors = recoverPageVectors(page, pageIndex, recoveredTable?.latticeItems ?? NO_ITEMS);
169
213
  if (recoveredVectors !== void 0) positioned.push({
170
214
  yPt: recoveredVectors.topYPt,
171
215
  block: recoveredVectors.block
@@ -196,28 +240,28 @@ function startsNewParagraph(prev, next, modalSpacing, dominantLeftX) {
196
240
  return nextIndented && prevAtMargin;
197
241
  }
198
242
  const LEFT_ALIGN_TOLERANCE_PT = 2;
199
- function paragraphToContentParagraph(paragraph) {
243
+ function paragraphToContentParagraph(paragraph, pageIndex) {
200
244
  const dominantLeftX = modeOf(paragraph.lines.map((l) => l.items[0].xPt), 1);
201
- const alignment = paragraph.lines.every((l) => Math.abs(l.items[0].xPt - dominantLeftX) <= LEFT_ALIGN_TOLERANCE_PT) ? "left" : void 0;
202
- const runs = [];
245
+ const result = {
246
+ kind: "paragraph",
247
+ runs: [],
248
+ alignment: paragraph.lines.every((l) => Math.abs(l.items[0].xPt - dominantLeftX) <= LEFT_ALIGN_TOLERANCE_PT) ? "left" : void 0
249
+ };
203
250
  paragraph.lines.forEach((line, lineIndex) => {
251
+ require_layout_shared.stampFrame(result, pageIndex, lineBox(line, pageIndex));
204
252
  if (lineIndex > 0) {
205
- const lastRun = runs[runs.length - 1];
253
+ const lastRun = result.runs[result.runs.length - 1];
206
254
  if (lastRun !== void 0) lastRun.text += " ";
207
255
  }
208
- pushRunsForLine(runs, line);
256
+ pushRunsForLine(result.runs, line, pageIndex);
209
257
  });
210
- return {
211
- kind: "paragraph",
212
- runs,
213
- alignment
214
- };
258
+ return result;
215
259
  }
216
260
  function reconstructPresentation(doc, options) {
217
261
  const signal = options?.signal;
218
- const slides = doc.pages.map((page) => {
262
+ const slides = doc.pages.map((page, pageIndex) => {
219
263
  require_ports_abort.throwIfAborted(signal);
220
- return reconstructSlide(page, doc.images);
264
+ return reconstructSlide(page, pageIndex, doc.images);
221
265
  });
222
266
  return {
223
267
  kind: "presentation",
@@ -226,25 +270,25 @@ function reconstructPresentation(doc, options) {
226
270
  slides
227
271
  };
228
272
  }
229
- function reconstructSlide(page, images) {
230
- const recoveredTable = recoverTable(page);
273
+ function reconstructSlide(page, pageIndex, images) {
274
+ const recoveredTable = recoverTable(page, pageIndex);
231
275
  const consumedText = recoveredTable?.consumedText;
232
276
  const textItems = page.items.filter((i) => i.kind === "text" && consumedText?.has(i) !== true);
233
277
  const imageItems = page.items.filter((i) => i.kind === "image");
234
- const textShapes = clusterIntoBlocks(clusterIntoLines(textItems)).map((block) => blockToShape(block, page.heightPt));
278
+ const textShapes = clusterIntoBlocks(clusterIntoLines(textItems)).map((block) => blockToShape(block, page.heightPt, pageIndex));
235
279
  const imageShapes = [];
236
280
  for (const img of imageItems) {
237
- const shape = imageToShape(img, page.heightPt, images);
281
+ const shape = imageToShape(img, page.heightPt, pageIndex, images);
238
282
  if (shape !== void 0) imageShapes.push(shape);
239
283
  }
240
- const recoveredVectors = recoverPageVectors(page, recoveredTable?.latticeItems ?? NO_ITEMS);
284
+ const recoveredVectors = recoverPageVectors(page, pageIndex, recoveredTable?.latticeItems ?? NO_ITEMS);
241
285
  const vectorShapes = recoveredVectors === void 0 ? [] : [wrapBlockInShape(recoveredVectors.block, {
242
286
  xPt: 0,
243
287
  yPt: 0,
244
288
  widthPt: page.widthPt,
245
289
  heightPt: page.heightPt
246
- })];
247
- const tableShapes = recoveredTable === void 0 ? [] : [wrapBlockInShape(recoveredTable.table, recoveredTable.frame)];
290
+ }, page.heightPt, pageIndex)];
291
+ const tableShapes = recoveredTable === void 0 ? [] : [wrapBlockInShape(recoveredTable.table, recoveredTable.frame, page.heightPt, pageIndex)];
248
292
  return {
249
293
  size: {
250
294
  widthPt: page.widthPt,
@@ -259,8 +303,8 @@ function reconstructSlide(page, images) {
259
303
  notes: page.notes ?? ""
260
304
  };
261
305
  }
262
- function wrapBlockInShape(block, frame) {
263
- return {
306
+ function wrapBlockInShape(block, frame, pageHeightPt, pageIndex) {
307
+ const shape = {
264
308
  frame,
265
309
  insetLeftPt: 0,
266
310
  insetTopPt: 0,
@@ -268,6 +312,8 @@ function wrapBlockInShape(block, frame) {
268
312
  insetBottomPt: 0,
269
313
  blocks: [block]
270
314
  };
315
+ require_layout_shared.stampFrame(shape, pageIndex, require_model_geometry.flipY(frame, pageHeightPt));
316
+ return shape;
271
317
  }
272
318
  function splitLineByLargeGaps(line) {
273
319
  const segments = [];
@@ -334,53 +380,71 @@ function computeBlockFrame(block, slideHeightPt) {
334
380
  heightPt: maxY - minY
335
381
  }, slideHeightPt);
336
382
  }
337
- function lineToParagraph(line) {
338
- const runs = [];
339
- pushRunsForLine(runs, line);
340
- return {
383
+ function lineToParagraph(line, pageIndex) {
384
+ const paragraph = {
341
385
  kind: "paragraph",
342
- runs
386
+ runs: []
343
387
  };
388
+ require_layout_shared.stampFrame(paragraph, pageIndex, lineBox(line, pageIndex));
389
+ pushRunsForLine(paragraph.runs, line, pageIndex);
390
+ return paragraph;
344
391
  }
345
- function blockToShape(block, slideHeightPt) {
346
- return {
392
+ function blockToShape(block, slideHeightPt, pageIndex) {
393
+ const shape = {
347
394
  frame: computeBlockFrame(block, slideHeightPt),
348
395
  insetLeftPt: 0,
349
396
  insetTopPt: 0,
350
397
  insetRightPt: 0,
351
398
  insetBottomPt: 0,
352
- blocks: block.lines.map(lineToParagraph)
399
+ blocks: block.lines.map((line) => lineToParagraph(line, pageIndex))
353
400
  };
401
+ require_layout_shared.stampFrame(shape, pageIndex, require_model_geometry.flipY(shape.frame, slideHeightPt));
402
+ return shape;
354
403
  }
355
- function imageToShape(img, slideHeightPt, images) {
404
+ function imageToShape(img, slideHeightPt, pageIndex, images) {
356
405
  const asset = images[img.imageId];
357
406
  if (asset === void 0) return;
358
- return {
359
- frame: require_model_geometry.flipY({
360
- xPt: img.xPt,
361
- yPt: img.yPt,
362
- widthPt: img.widthPt,
363
- heightPt: img.heightPt
364
- }, slideHeightPt),
407
+ const frame = require_model_geometry.flipY({
408
+ xPt: img.xPt,
409
+ yPt: img.yPt,
410
+ widthPt: img.widthPt,
411
+ heightPt: img.heightPt
412
+ }, slideHeightPt);
413
+ const block = {
414
+ kind: "image",
415
+ format: asset.format,
416
+ base64: asset.base64,
417
+ widthPt: img.widthPt,
418
+ heightPt: img.heightPt
419
+ };
420
+ require_layout_shared.stampFrame(block, pageIndex, {
421
+ xPt: img.xPt,
422
+ yPt: img.yPt,
423
+ widthPt: img.widthPt,
424
+ heightPt: img.heightPt
425
+ });
426
+ const shape = {
427
+ frame,
365
428
  rotationDeg: img.rotationDeg !== void 0 ? -img.rotationDeg : void 0,
366
429
  insetLeftPt: 0,
367
430
  insetTopPt: 0,
368
431
  insetRightPt: 0,
369
432
  insetBottomPt: 0,
370
- blocks: [{
371
- kind: "image",
372
- format: asset.format,
373
- base64: asset.base64,
374
- widthPt: img.widthPt,
375
- heightPt: img.heightPt
376
- }]
433
+ blocks: [block]
377
434
  };
435
+ require_layout_shared.stampFrame(shape, pageIndex, {
436
+ xPt: img.xPt,
437
+ yPt: img.yPt,
438
+ widthPt: img.widthPt,
439
+ heightPt: img.heightPt
440
+ });
441
+ return shape;
378
442
  }
379
443
  function reconstructDrawing(doc, options) {
380
444
  const signal = options?.signal;
381
- const pages = doc.pages.map((page) => {
445
+ const pages = doc.pages.map((page, pageIndex) => {
382
446
  require_ports_abort.throwIfAborted(signal);
383
- return reconstructDrawPage(page, doc.images);
447
+ return reconstructDrawPage(page, pageIndex, doc.images);
384
448
  });
385
449
  return {
386
450
  kind: "drawing",
@@ -389,25 +453,29 @@ function reconstructDrawing(doc, options) {
389
453
  pages
390
454
  };
391
455
  }
392
- function reconstructDrawPage(page, images) {
456
+ function reconstructDrawPage(page, pageIndex, images) {
393
457
  const vectors = [];
394
458
  const shapes = [];
395
459
  let paintOrder = 0;
396
460
  for (const item of page.items) {
397
461
  const vector = layoutItemToVector(item, page.heightPt);
398
462
  if (vector !== void 0) {
463
+ stampVectorFrame(vector, item, pageIndex);
399
464
  vectors.push({
400
465
  ...vector,
401
466
  paintOrder: paintOrder++
402
467
  });
403
468
  continue;
404
469
  }
405
- if (item.kind === "text") shapes.push({
406
- ...layoutTextToShape(item, page.heightPt),
407
- paintOrder: paintOrder++
408
- });
409
- else if (item.kind === "image") {
410
- const shape = imageToShape(item, page.heightPt, images);
470
+ if (item.kind === "text") {
471
+ const shape = layoutTextToShape(item, page.heightPt, pageIndex);
472
+ require_layout_shared.stampFrame(shape, pageIndex, require_model_geometry.flipY(shape.frame, page.heightPt));
473
+ shapes.push({
474
+ ...shape,
475
+ paintOrder: paintOrder++
476
+ });
477
+ } else if (item.kind === "image") {
478
+ const shape = imageToShape(item, page.heightPt, pageIndex, images);
411
479
  if (shape !== void 0) shapes.push({
412
480
  ...shape,
413
481
  paintOrder: paintOrder++
@@ -423,6 +491,44 @@ function reconstructDrawPage(page, images) {
423
491
  vectors
424
492
  };
425
493
  }
494
+ function stampVectorFrame(vector, item, pageIndex) {
495
+ if (item.kind === "rect" || item.kind === "ellipse") {
496
+ require_layout_shared.stampFrame(vector, pageIndex, {
497
+ xPt: item.xPt,
498
+ yPt: item.yPt,
499
+ widthPt: item.widthPt,
500
+ heightPt: item.heightPt
501
+ });
502
+ return;
503
+ }
504
+ if (item.kind === "line") {
505
+ require_layout_shared.stampFrame(vector, pageIndex, {
506
+ xPt: Math.min(item.x1Pt, item.x2Pt),
507
+ yPt: Math.min(item.y1Pt, item.y2Pt),
508
+ widthPt: Math.abs(item.x2Pt - item.x1Pt),
509
+ heightPt: Math.abs(item.y2Pt - item.y1Pt)
510
+ });
511
+ return;
512
+ }
513
+ if (item.kind !== "path") return;
514
+ const points = collectPathPoints(item.subpaths);
515
+ let minX = Number.POSITIVE_INFINITY;
516
+ let maxX = Number.NEGATIVE_INFINITY;
517
+ let minY = Number.POSITIVE_INFINITY;
518
+ let maxY = Number.NEGATIVE_INFINITY;
519
+ for (const point of points) {
520
+ minX = Math.min(minX, point.xPt);
521
+ maxX = Math.max(maxX, point.xPt);
522
+ minY = Math.min(minY, point.yPt);
523
+ maxY = Math.max(maxY, point.yPt);
524
+ }
525
+ require_layout_shared.stampFrame(vector, pageIndex, {
526
+ xPt: minX,
527
+ yPt: minY,
528
+ widthPt: maxX - minX,
529
+ heightPt: maxY - minY
530
+ });
531
+ }
426
532
  function layoutItemToVector(item, pageHeightPt) {
427
533
  if (item.kind === "rect") return layoutRectToVector(item, pageHeightPt);
428
534
  if (item.kind === "ellipse") return layoutEllipseToVector(item, pageHeightPt);
@@ -574,50 +680,65 @@ function layoutPathToVector(item, pageHeightPt) {
574
680
  sourcePath: item.sourcePath
575
681
  };
576
682
  }
577
- function layoutTextToShape(item, pageHeightPt) {
683
+ function layoutTextToShape(item, pageHeightPt, pageIndex) {
684
+ const frame = computeBlockFrame({ lines: [{
685
+ items: [item],
686
+ baselineY: item.yPt
687
+ }] }, pageHeightPt);
688
+ const run = textItemToContentRun(item);
689
+ require_layout_shared.stampFrame(run, pageIndex, textBoxOfItem(item, pageIndex));
690
+ const paragraph = {
691
+ kind: "paragraph",
692
+ runs: [run]
693
+ };
694
+ require_layout_shared.stampFrame(paragraph, pageIndex, textBoxOfItem(item, pageIndex));
578
695
  return {
579
- frame: computeBlockFrame({ lines: [{
580
- items: [item],
581
- baselineY: item.yPt
582
- }] }, pageHeightPt),
696
+ frame,
583
697
  rotationDeg: item.rotationDeg !== void 0 ? -item.rotationDeg : void 0,
584
698
  insetLeftPt: 0,
585
699
  insetTopPt: 0,
586
700
  insetRightPt: 0,
587
701
  insetBottomPt: 0,
588
- blocks: [{
589
- kind: "paragraph",
590
- runs: [textItemToContentRun(item)]
591
- }]
702
+ blocks: [paragraph]
592
703
  };
593
704
  }
594
705
  function vectorTopYDownPt(vector) {
595
706
  return vector.kind === "line" ? Math.min(vector.from.yPt, vector.to.yPt) : vector.frame.yPt;
596
707
  }
597
- function recoverPageVectors(page, excluded) {
708
+ function recoverPageVectors(page, pageIndex, excluded) {
598
709
  const vectors = [];
599
710
  for (const item of page.items) {
600
711
  if (excluded.has(item)) continue;
601
712
  const vector = layoutItemToVector(item, page.heightPt);
602
- if (vector !== void 0) vectors.push({
603
- ...vector,
604
- paintOrder: vectors.length
605
- });
713
+ if (vector !== void 0) {
714
+ stampVectorFrame(vector, item, pageIndex);
715
+ vectors.push({
716
+ ...vector,
717
+ paintOrder: vectors.length
718
+ });
719
+ }
606
720
  }
607
721
  if (vectors.length === 0) return;
608
722
  const topYDownPt = Math.min(...vectors.map(vectorTopYDownPt));
723
+ const block = require_model_embedded_drawing.buildDrawingBlock({
724
+ widthPt: page.widthPt,
725
+ heightPt: page.heightPt
726
+ }, vectors);
727
+ require_layout_shared.stampFrame(block, pageIndex, {
728
+ xPt: 0,
729
+ yPt: 0,
730
+ widthPt: page.widthPt,
731
+ heightPt: page.heightPt
732
+ });
609
733
  return {
610
- block: require_model_embedded_drawing.buildDrawingBlock({
611
- widthPt: page.widthPt,
612
- heightPt: page.heightPt
613
- }, vectors),
734
+ block,
614
735
  topYPt: page.heightPt - topYDownPt
615
736
  };
616
737
  }
617
- function cellBlocksFromItems(items) {
618
- return clusterIntoLines(items).map(lineToParagraph);
738
+ function cellBlocksFromItems(items, pageIndex) {
739
+ return clusterIntoLines(items).map((line) => lineToParagraph(line, pageIndex));
619
740
  }
620
- function recoverTable(page) {
741
+ function recoverTable(page, pageIndex) {
621
742
  const lattice = require_layout_lattice.detectGridLattice(page.items);
622
743
  if (lattice === void 0) return;
623
744
  const rowCount = lattice.rowBoundariesDescPt.length - 1;
@@ -638,7 +759,20 @@ function recoverTable(page) {
638
759
  const rows = [];
639
760
  for (let i = 0; i < rowCount; i++) {
640
761
  const cells = [];
641
- for (let j = 0; j < columnCount; j++) cells.push({ blocks: cellBlocksFromItems(groups.get(groupKey(i, j)) ?? []) });
762
+ for (let j = 0; j < columnCount; j++) {
763
+ const cell = { blocks: cellBlocksFromItems(groups.get(groupKey(i, j)) ?? [], pageIndex) };
764
+ const cellLeftXPt = lattice.columnBoundariesAscPt[j];
765
+ const cellRightXPt = lattice.columnBoundariesAscPt[j + 1];
766
+ const cellTopYPt = lattice.rowBoundariesDescPt[i];
767
+ const cellBottomYPt = lattice.rowBoundariesDescPt[i + 1];
768
+ require_layout_shared.stampFrame(cell, pageIndex, {
769
+ xPt: cellLeftXPt,
770
+ yPt: cellBottomYPt,
771
+ widthPt: cellRightXPt - cellLeftXPt,
772
+ heightPt: cellTopYPt - cellBottomYPt
773
+ });
774
+ cells.push(cell);
775
+ }
642
776
  rows.push({
643
777
  cells,
644
778
  heightPt: lattice.rowBoundariesDescPt[i] - lattice.rowBoundariesDescPt[i + 1]
@@ -648,18 +782,21 @@ function recoverTable(page) {
648
782
  const rightXPt = lattice.columnBoundariesAscPt[columnCount];
649
783
  const topYPt = lattice.rowBoundariesDescPt[0];
650
784
  const bottomYPt = lattice.rowBoundariesDescPt[rowCount];
651
- const frame = require_model_geometry.flipY({
785
+ const pdfBox = {
652
786
  xPt: leftXPt,
653
787
  yPt: bottomYPt,
654
788
  widthPt: rightXPt - leftXPt,
655
789
  heightPt: topYPt - bottomYPt
656
- }, page.heightPt);
790
+ };
791
+ const frame = require_model_geometry.flipY(pdfBox, page.heightPt);
792
+ const table = {
793
+ kind: "table",
794
+ rows,
795
+ columnWidthsPt
796
+ };
797
+ require_layout_shared.stampFrame(table, pageIndex, pdfBox);
657
798
  return {
658
- table: {
659
- kind: "table",
660
- rows,
661
- columnWidthsPt
662
- },
799
+ table,
663
800
  frame,
664
801
  topYPt,
665
802
  consumedText,
@@ -688,7 +825,7 @@ function addToGroup(groups, row, column, item) {
688
825
  if (existing === void 0) groups.set(key, [item]);
689
826
  else existing.push(item);
690
827
  }
691
- function buildCellsFromGroups(groups, context) {
828
+ function buildCellsFromGroups(groups, pageIndex, context) {
692
829
  const cells = [];
693
830
  for (const [key, items] of groups) {
694
831
  const displayText = joinCellText(items);
@@ -696,12 +833,30 @@ function buildCellsFromGroups(groups, context) {
696
833
  const [rowPart, columnPart] = key.split(",");
697
834
  const row = Number(rowPart);
698
835
  const column = Number(columnPart);
699
- cells.push({
836
+ const cell = {
700
837
  row,
701
838
  column,
702
839
  value: inferredCellValue(displayText, row, column, context),
703
840
  displayText
841
+ };
842
+ let minX = Number.POSITIVE_INFINITY;
843
+ let maxX = Number.NEGATIVE_INFINITY;
844
+ let minY = Number.POSITIVE_INFINITY;
845
+ let maxY = Number.NEGATIVE_INFINITY;
846
+ for (const item of items) {
847
+ const { ascentPt, descentPt } = textItemVerticalExtent(item);
848
+ minX = Math.min(minX, item.xPt);
849
+ maxX = Math.max(maxX, item.xPt + (item.widthPt ?? 0));
850
+ minY = Math.min(minY, item.yPt - descentPt);
851
+ maxY = Math.max(maxY, item.yPt + ascentPt);
852
+ }
853
+ require_layout_shared.stampFrame(cell, pageIndex, {
854
+ xPt: minX,
855
+ yPt: minY,
856
+ widthPt: maxX - minX,
857
+ heightPt: maxY - minY
704
858
  });
859
+ cells.push(cell);
705
860
  }
706
861
  cells.sort((a, b) => a.row - b.row || a.column - b.column);
707
862
  return cells;
@@ -725,7 +880,7 @@ function inferredCellValue(displayText, row, column, context) {
725
880
  value: displayText
726
881
  };
727
882
  }
728
- function buildGridFromLattice(textItems, lattice, context) {
883
+ function buildGridFromLattice(textItems, lattice, pageIndex, context) {
729
884
  const groups = /* @__PURE__ */ new Map();
730
885
  for (const item of textItems) {
731
886
  const row = require_layout_lattice.findRowIndex(lattice.rowBoundariesDescPt, item.yPt);
@@ -744,7 +899,7 @@ function buildGridFromLattice(textItems, lattice, context) {
744
899
  heightPt: lattice.rowBoundariesDescPt[i] - lattice.rowBoundariesDescPt[i + 1]
745
900
  });
746
901
  return {
747
- cells: buildCellsFromGroups(groups, context),
902
+ cells: buildCellsFromGroups(groups, pageIndex, context),
748
903
  columns,
749
904
  rows,
750
905
  gridlines: true
@@ -783,7 +938,7 @@ function lastColumnWidthPt(groups, columnIndex, anchorXPt) {
783
938
  }
784
939
  return maxWidthPt > 0 ? maxWidthPt : DEFAULT_COLUMN_WIDTH_FALLBACK_PT;
785
940
  }
786
- function buildGridFromTextClustering(textItems, context) {
941
+ function buildGridFromTextClustering(textItems, pageIndex, context) {
787
942
  const lines = clusterIntoLines(textItems);
788
943
  if (lines.length === 0) return {
789
944
  cells: [],
@@ -819,7 +974,7 @@ function buildGridFromTextClustering(textItems, context) {
819
974
  };
820
975
  });
821
976
  return {
822
- cells: buildCellsFromGroups(groups, context),
977
+ cells: buildCellsFromGroups(groups, pageIndex, context),
823
978
  columns,
824
979
  rows,
825
980
  gridlines: false
@@ -832,7 +987,7 @@ function reconstructSheet(page, pageIndex, sink) {
832
987
  sheetIndex: pageIndex,
833
988
  sink
834
989
  };
835
- const grid = lattice !== void 0 ? buildGridFromLattice(textItems, lattice, context) : buildGridFromTextClustering(textItems, context);
990
+ const grid = lattice !== void 0 ? buildGridFromLattice(textItems, lattice, pageIndex, context) : buildGridFromTextClustering(textItems, pageIndex, context);
836
991
  const printSettings = {
837
992
  pageSize: {
838
993
  widthPt: page.widthPt,