@vyaz/core 0.1.0 → 0.4.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/dist/index.js CHANGED
@@ -2358,7 +2358,7 @@ function positionLines(pretextLines, items, fontMetricsFn, style, maxWidth, star
2358
2358
  const indent = isFirstLine ? effectiveLeftIndent + (style.indent || 0) : effectiveLeftIndent;
2359
2359
  const rightIndent = style.rightIndent || 0;
2360
2360
  const availableWidth = maxWidth - indent - rightIndent;
2361
- const slack = Math.max(0, availableWidth - effectiveLineWidth);
2361
+ const slack = Number.isFinite(availableWidth) ? Math.max(0, availableWidth - effectiveLineWidth) : 0;
2362
2362
  let xOffset = indent;
2363
2363
  if (style.alignment === "center") {
2364
2364
  xOffset = indent + slack / 2;
@@ -5079,7 +5079,16 @@ setProfileChangeHook(clearMeasurementCaches);
5079
5079
  function glyphCacheKey(text, fontSize, fontFamily, fontWeight, fontStyle) {
5080
5080
  return `${fontSize}_${fontFamily || ""}_${fontWeight || ""}_${fontStyle || ""}_${text}`;
5081
5081
  }
5082
+ function inlineWidgetMetrics(iw, fontSize) {
5083
+ const bo = iw.baselineOffset ?? 0;
5084
+ const ascent = Math.max(0, iw.height - bo);
5085
+ const descent = Math.max(0, bo);
5086
+ return { ascent, descent, capHeight: ascent, unitsPerEm: fontSize || 1, sourceTable: "fallback" };
5087
+ }
5082
5088
  function getFontMetricsForItem(item, mode) {
5089
+ if (item.metadata.inlineWidget) {
5090
+ return inlineWidgetMetrics(item.metadata.inlineWidget, item.metadata.effectiveFontSize);
5091
+ }
5083
5092
  return fontMetricsProvider.getMetrics(item.metadata.style.fontFamily, item.metadata.effectiveFontSize, String(item.metadata.style.fontWeight || 400), item.metadata.style.fontStyle || "normal", mode);
5084
5093
  }
5085
5094
  function preparedCacheKey(paragraph) {
@@ -5167,6 +5176,9 @@ class ParagraphLayoutEngine {
5167
5176
  return Math.round(total * 100) / 100;
5168
5177
  };
5169
5178
  const { lines, contentWidth } = positionLines(materializedLines, items, (item) => {
5179
+ if (item.metadata.inlineWidget) {
5180
+ return inlineWidgetMetrics(item.metadata.inlineWidget, item.metadata.effectiveFontSize);
5181
+ }
5170
5182
  if (fontProvider) {
5171
5183
  return fontProvider.getMetrics(item.metadata.style.fontFamily, item.metadata.effectiveFontSize, String(item.metadata.style.fontWeight || 400), item.metadata.style.fontStyle || "normal", renderMode);
5172
5184
  }
@@ -5256,6 +5268,10 @@ function findScale(doc, layoutFn, config, options) {
5256
5268
  }
5257
5269
 
5258
5270
  // src/layout/TextFrameLayoutEngine.ts
5271
+ function normalizeDeg(d) {
5272
+ const r = d % 360;
5273
+ return r < 0 ? r + 360 : r;
5274
+ }
5259
5275
  function getMarkerTextHelper(listStyle, listIndex) {
5260
5276
  if (listStyle.type === "bullet") {
5261
5277
  return listStyle.bulletChar ?? defaultBulletChar(listStyle.level ?? 0);
@@ -5316,11 +5332,13 @@ function runFlow(frame, options, engine) {
5316
5332
  const mode = options.mode;
5317
5333
  const onMissingFont = options.onMissingFont ?? "throw";
5318
5334
  const warnings = [];
5335
+ const writingMode = frame.writingMode ?? "horizontal-tb";
5336
+ const sideways = writingMode === "sideways-rl" || writingMode === "sideways-lr";
5319
5337
  const leftPad = frame.padding?.left ?? 0;
5320
5338
  const rightPad = frame.padding?.right ?? 0;
5321
5339
  const topPad = frame.padding?.top ?? 0;
5322
5340
  const bottomPad = frame.padding?.bottom ?? 0;
5323
- const hasColumns = frame.columns != null && frame.columns.count > 1 && frame.width != null;
5341
+ const hasColumns = !sideways && frame.columns != null && frame.columns.count > 1 && frame.width != null;
5324
5342
  let colWidth;
5325
5343
  let colCount = 1;
5326
5344
  let colGap = 0;
@@ -5411,14 +5429,14 @@ function runFlow(frame, options, engine) {
5411
5429
  for (let i2 = 0;i2 < frame.paragraphs.length; i2++) {
5412
5430
  const p = frame.paragraphs[i2];
5413
5431
  const subParagraphs = splitParagraphByHardBreaks(p);
5414
- const maxWidth = hasColumns ? colWidth : frame.width !== undefined ? frame.width - leftPad - rightPad : Infinity;
5415
- if (frame.wrap === false) {
5416
- p.style = { ...p.style, whiteSpace: "nowrap" };
5417
- }
5432
+ const inlineFrameSize = sideways ? frame.height : frame.width;
5433
+ const inlinePadStart = sideways ? topPad : leftPad;
5434
+ const inlinePadEnd = sideways ? bottomPad : rightPad;
5435
+ const maxWidth = hasColumns ? colWidth : inlineFrameSize !== undefined ? inlineFrameSize - inlinePadStart - inlinePadEnd : Infinity;
5418
5436
  const listIndex = listIndices[i2];
5419
5437
  const listMarkerWidth = listMarkerWidths[i2];
5420
5438
  for (let subIdx = 0;subIdx < subParagraphs.length; subIdx++) {
5421
- const subPara = subParagraphs[subIdx];
5439
+ const subPara = frame.wrap === false && subParagraphs[subIdx].style.whiteSpace !== "nowrap" ? { ...subParagraphs[subIdx], style: { ...subParagraphs[subIdx].style, whiteSpace: "nowrap" } } : subParagraphs[subIdx];
5422
5440
  if (subIdx === 0) {
5423
5441
  if (hasColumns)
5424
5442
  pendingColGap += p.style.spaceBefore;
@@ -5493,18 +5511,32 @@ function runFlow(frame, options, engine) {
5493
5511
  }
5494
5512
  const lastLine = allLines.length > 0 ? allLines[allLines.length - 1] : null;
5495
5513
  const contentHeight = lastLine ? lastLine.y + lastLine.height + bottomPad : bottomPad;
5514
+ const wmRotate = sideways ? writingMode === "sideways-rl" ? 90 : 270 : 0;
5515
+ const rotate = normalizeDeg(wmRotate + (frame.rotation ?? 0));
5516
+ const quarterTurned = rotate === 90 || rotate === 270;
5517
+ const visualContentWidth = quarterTurned ? contentHeight : contentWidth;
5518
+ const visualContentHeight = quarterTurned ? contentWidth : contentHeight;
5519
+ const transform = rotate === 0 ? undefined : {
5520
+ rotate,
5521
+ layoutBox: {
5522
+ width: (sideways ? frame.height : frame.width) ?? contentWidth,
5523
+ height: (sideways ? frame.width : frame.height) ?? contentHeight
5524
+ }
5525
+ };
5496
5526
  return {
5497
5527
  lines: allLines,
5498
- content: { width: contentWidth, height: contentHeight },
5528
+ content: { width: visualContentWidth, height: visualContentHeight },
5499
5529
  frame: { width: frame.width, height: frame.height },
5500
5530
  overflow: {
5501
- horizontal: frame.width !== undefined && contentWidth > frame.width + 0.01,
5502
- vertical: frame.height !== undefined && contentHeight > frame.height + 0.01
5531
+ horizontal: frame.width !== undefined && visualContentWidth > frame.width + 0.01,
5532
+ vertical: frame.height !== undefined && visualContentHeight > frame.height + 0.01
5503
5533
  },
5504
5534
  fit: {
5505
5535
  horizontal: frame.width !== undefined ? "frame" : "content",
5506
5536
  vertical: frame.height !== undefined ? "frame" : "content"
5507
5537
  },
5538
+ writingMode,
5539
+ ...transform ? { transform } : {},
5508
5540
  ...warnings.length ? { warnings } : {}
5509
5541
  };
5510
5542
  }
@@ -5549,6 +5581,382 @@ function createLayoutEngine(options = {}) {
5549
5581
  clearCache: () => pe.clearCache()
5550
5582
  };
5551
5583
  }
5584
+ // src/utils/sides.ts
5585
+ function resolveSide(v, side, fallback) {
5586
+ if (v === undefined)
5587
+ return fallback;
5588
+ if (!Array.isArray(v))
5589
+ return v;
5590
+ if (v.length === 2) {
5591
+ const [tb, lr] = v;
5592
+ return side === "top" || side === "bottom" ? tb : lr;
5593
+ }
5594
+ const [t, r, b, l] = v;
5595
+ return side === "top" ? t : side === "right" ? r : side === "bottom" ? b : l;
5596
+ }
5597
+ function resolveAllSides(v, fallback) {
5598
+ return {
5599
+ top: resolveSide(v, "top", fallback),
5600
+ right: resolveSide(v, "right", fallback),
5601
+ bottom: resolveSide(v, "bottom", fallback),
5602
+ left: resolveSide(v, "left", fallback)
5603
+ };
5604
+ }
5605
+ function resolveWidths(w, fallback = 0) {
5606
+ return resolveAllSides(w, fallback);
5607
+ }
5608
+ function resolveColors(c, fallback = "#000") {
5609
+ return resolveAllSides(c, fallback);
5610
+ }
5611
+ function resolvePatterns(p) {
5612
+ if (p === undefined)
5613
+ return { top: undefined, right: undefined, bottom: undefined, left: undefined };
5614
+ if (p.length === 0 || typeof p[0] === "number") {
5615
+ const flat = p;
5616
+ return { top: flat, right: flat, bottom: flat, left: flat };
5617
+ }
5618
+ const tuples = p;
5619
+ if (tuples.length === 2) {
5620
+ const [tb, lr] = tuples;
5621
+ return { top: tb, right: lr, bottom: tb, left: lr };
5622
+ }
5623
+ const [t, r, b, l] = tuples;
5624
+ return { top: t, right: r, bottom: b, left: l };
5625
+ }
5626
+ function resolveShapes(s, fallback = "butt") {
5627
+ return resolveAllSides(s, fallback);
5628
+ }
5629
+
5630
+ // src/layout/TableLayoutEngine.ts
5631
+ var MAX_NESTED_TABLE_DEPTH = 50;
5632
+ function isNestedTable(content) {
5633
+ return "rows" in content;
5634
+ }
5635
+ function placeholderContentFor(nested) {
5636
+ return {
5637
+ lines: [],
5638
+ content: { width: nested.width, height: nested.height },
5639
+ frame: { width: nested.width, height: nested.height },
5640
+ overflow: { horizontal: false, vertical: false },
5641
+ fit: { horizontal: "content", vertical: "content" },
5642
+ writingMode: "horizontal-tb"
5643
+ };
5644
+ }
5645
+ var DEFAULT_PADDING = 8;
5646
+ function resolveCellStyle(cell, table) {
5647
+ const d = table.defaultCellStyle ?? {};
5648
+ const s = cell.style ?? {};
5649
+ return {
5650
+ bgColor: s.bgColor ?? d.bgColor ?? "",
5651
+ paddings: s.paddings ?? d.paddings ?? DEFAULT_PADDING,
5652
+ verticalAlign: s.verticalAlign ?? d.verticalAlign ?? "top",
5653
+ cx: s.cx ?? d.cx ?? 0,
5654
+ cy: s.cy ?? d.cy ?? 0,
5655
+ allowOverflow: s.allowOverflow ?? d.allowOverflow ?? false,
5656
+ borderWidths: s.borderWidths ?? d.borderWidths,
5657
+ borderColors: s.borderColors ?? d.borderColors,
5658
+ borderPatterns: s.borderPatterns ?? d.borderPatterns,
5659
+ borderShapes: s.borderShapes ?? d.borderShapes,
5660
+ rx: s.rx ?? d.rx,
5661
+ ry: s.ry ?? d.ry
5662
+ };
5663
+ }
5664
+ function resolveRowStyle(row, table) {
5665
+ const d = table.defaultRowStyle ?? {};
5666
+ const s = row.style ?? {};
5667
+ return {
5668
+ height: s.height ?? d.height ?? 0,
5669
+ bgColor: s.bgColor ?? d.bgColor ?? "",
5670
+ borderWidths: s.borderWidths ?? d.borderWidths,
5671
+ borderColors: s.borderColors ?? d.borderColors,
5672
+ borderPatterns: s.borderPatterns ?? d.borderPatterns,
5673
+ borderShapes: s.borderShapes ?? d.borderShapes,
5674
+ rx: s.rx ?? d.rx,
5675
+ ry: s.ry ?? d.ry
5676
+ };
5677
+ }
5678
+ function resolveBorder(raw) {
5679
+ if (!raw)
5680
+ return;
5681
+ const widths = resolveWidths(raw.borderWidths, 0);
5682
+ if (widths.top === 0 && widths.right === 0 && widths.bottom === 0 && widths.left === 0)
5683
+ return;
5684
+ const colors = resolveColors(raw.borderColors, "#000");
5685
+ const border = { widths, colors };
5686
+ if (raw.borderPatterns !== undefined) {
5687
+ const patterns = resolvePatterns(raw.borderPatterns);
5688
+ if (patterns.top?.length || patterns.right?.length || patterns.bottom?.length || patterns.left?.length) {
5689
+ border.patterns = patterns;
5690
+ }
5691
+ }
5692
+ if (raw.borderShapes !== undefined)
5693
+ border.shapes = resolveShapes(raw.borderShapes);
5694
+ if (raw.rx !== undefined || raw.ry !== undefined) {
5695
+ border.rx = raw.rx ?? raw.ry;
5696
+ border.ry = raw.ry ?? raw.rx;
5697
+ }
5698
+ return border;
5699
+ }
5700
+ function verticalOffsetFor(align, available, content) {
5701
+ const extra = available - content;
5702
+ if (extra <= 0)
5703
+ return 0;
5704
+ if (align === "middle")
5705
+ return extra / 2;
5706
+ if (align === "bottom")
5707
+ return extra;
5708
+ return 0;
5709
+ }
5710
+ function sumSpan(arr, start, count, gap) {
5711
+ let sum = 0;
5712
+ for (let i = start;i < start + count; i++)
5713
+ sum += arr[i] ?? 0;
5714
+ return sum + gap * Math.max(0, count - 1);
5715
+ }
5716
+ function placeCells(rows) {
5717
+ const placed = [];
5718
+ const autoLastCell = [];
5719
+ const occupied = new Map;
5720
+ const isOccupied = (r, c) => occupied.get(r)?.has(c) ?? false;
5721
+ const occupy = (r, c) => {
5722
+ let set = occupied.get(r);
5723
+ if (!set)
5724
+ occupied.set(r, set = new Set);
5725
+ set.add(c);
5726
+ };
5727
+ let colCount = 0;
5728
+ for (let ri = 0;ri < rows.length; ri++) {
5729
+ let ci = 0;
5730
+ const cells = rows[ri].cells;
5731
+ for (let idx = 0;idx < cells.length; idx++) {
5732
+ const cell = cells[idx];
5733
+ while (isOccupied(ri, ci))
5734
+ ci++;
5735
+ const isAuto = cell.colSpan === "auto";
5736
+ const colSpan = cell.colSpan === "auto" ? 1 : Math.max(1, cell.colSpan ?? 1);
5737
+ const rowSpan = Math.max(1, cell.rowSpan ?? 1);
5738
+ const p = {
5739
+ cell,
5740
+ startRow: ri,
5741
+ startCol: ci,
5742
+ colSpan,
5743
+ rowSpan,
5744
+ cs: undefined,
5745
+ pad: undefined,
5746
+ inset: undefined,
5747
+ natural: 0,
5748
+ width: 0,
5749
+ content: undefined,
5750
+ cellHeight: 0
5751
+ };
5752
+ placed.push(p);
5753
+ if (isAuto && idx === cells.length - 1)
5754
+ autoLastCell.push(p);
5755
+ for (let dr = 1;dr < rowSpan; dr++) {
5756
+ for (let dc = 0;dc < colSpan; dc++)
5757
+ occupy(ri + dr, ci + dc);
5758
+ }
5759
+ colCount = Math.max(colCount, ci + colSpan);
5760
+ ci += colSpan;
5761
+ }
5762
+ }
5763
+ for (const p of autoLastCell) {
5764
+ if (p.startCol < colCount - 1)
5765
+ p.colSpan = colCount - p.startCol;
5766
+ }
5767
+ return { placed, colCount };
5768
+ }
5769
+ function layoutTableFrame(table, options = {}) {
5770
+ const depth = options._depth ?? 0;
5771
+ if (depth > MAX_NESTED_TABLE_DEPTH) {
5772
+ throw new Error(`layoutTableFrame: nested table depth exceeded ${MAX_NESTED_TABLE_DEPTH} \u2014 likely a cyclic or pathological TableCell.content structure, not a real document.`);
5773
+ }
5774
+ const style = table.style ?? {};
5775
+ const margins = resolveWidths(style.margins, 0);
5776
+ const colGaps = style.colGaps ?? 0;
5777
+ const rowGaps = style.rowGaps ?? 0;
5778
+ const rowCount = table.rows.length;
5779
+ const tableBorder = resolveBorder(style);
5780
+ const { placed, colCount } = placeCells(table.rows);
5781
+ if (colCount === 0 || rowCount === 0) {
5782
+ return {
5783
+ width: margins.left + margins.right,
5784
+ height: margins.top + margins.bottom,
5785
+ bgColor: style.bgColor,
5786
+ ...tableBorder ? { border: tableBorder } : {},
5787
+ contentBox: { x: margins.left, y: margins.top, width: 0, height: 0 },
5788
+ rows: []
5789
+ };
5790
+ }
5791
+ for (const p of placed) {
5792
+ p.cs = resolveCellStyle(p.cell, table);
5793
+ p.pad = resolveWidths(p.cs.paddings, DEFAULT_PADDING);
5794
+ p.border = resolveBorder(p.cs);
5795
+ const bw = p.border?.widths;
5796
+ p.inset = {
5797
+ top: p.pad.top + (bw?.top ?? 0),
5798
+ right: p.pad.right + (bw?.right ?? 0),
5799
+ bottom: p.pad.bottom + (bw?.bottom ?? 0),
5800
+ left: p.pad.left + (bw?.left ?? 0)
5801
+ };
5802
+ const naturalWidth = isNestedTable(p.cell.content) ? layoutTableFrame(p.cell.content, { mode: options.mode, onMissingFont: options.onMissingFont, _depth: depth + 1 }).width : layoutTextFrame({ ...p.cell.content, width: undefined, wrap: false }, { mode: options.mode, onMissingFont: options.onMissingFont }).content.width;
5803
+ p.natural = naturalWidth + p.inset.left + p.inset.right;
5804
+ }
5805
+ const colWidths = new Array(colCount).fill(0);
5806
+ if (table.columnWidths) {
5807
+ for (let c = 0;c < colCount; c++)
5808
+ colWidths[c] = table.columnWidths[c] ?? 0;
5809
+ } else {
5810
+ for (const p of placed)
5811
+ if (p.colSpan === 1)
5812
+ colWidths[p.startCol] = Math.max(colWidths[p.startCol], p.natural);
5813
+ for (const p of placed) {
5814
+ if (p.colSpan <= 1)
5815
+ continue;
5816
+ const covered = sumSpan(colWidths, p.startCol, p.colSpan, colGaps);
5817
+ if (p.natural > covered) {
5818
+ const extra = (p.natural - covered) / p.colSpan;
5819
+ for (let c = p.startCol;c < p.startCol + p.colSpan; c++)
5820
+ colWidths[c] += extra;
5821
+ }
5822
+ }
5823
+ }
5824
+ if (table.width !== undefined) {
5825
+ const budget = table.width - margins.left - margins.right - colGaps * Math.max(0, colCount - 1);
5826
+ const naturalSum = colWidths.reduce((a, b) => a + b, 0);
5827
+ if (naturalSum > 0 && budget > 0) {
5828
+ const scale = budget / naturalSum;
5829
+ for (let i = 0;i < colWidths.length; i++)
5830
+ colWidths[i] *= scale;
5831
+ }
5832
+ }
5833
+ for (const p of placed) {
5834
+ p.width = sumSpan(colWidths, p.startCol, p.colSpan, colGaps);
5835
+ const contentWidth = Math.max(0, p.width - p.inset.left - p.inset.right);
5836
+ if (isNestedTable(p.cell.content)) {
5837
+ const nested = layoutTableFrame({ ...p.cell.content, width: contentWidth }, { mode: options.mode, onMissingFont: options.onMissingFont, _depth: depth + 1 });
5838
+ p.nestedTable = nested;
5839
+ p.content = placeholderContentFor(nested);
5840
+ } else {
5841
+ p.content = layoutTextFrame({ ...p.cell.content, width: contentWidth, wrap: true }, { mode: options.mode, onMissingFont: options.onMissingFont });
5842
+ }
5843
+ p.cellHeight = p.content.content.height + p.inset.top + p.inset.bottom;
5844
+ }
5845
+ const rowHeights = new Array(rowCount).fill(0);
5846
+ if (table.rowHeights) {
5847
+ for (let r = 0;r < rowCount; r++)
5848
+ rowHeights[r] = table.rowHeights[r] ?? 0;
5849
+ } else {
5850
+ for (let ri = 0;ri < rowCount; ri++) {
5851
+ const explicitHeight = resolveRowStyle(table.rows[ri], table).height;
5852
+ if (explicitHeight > 0)
5853
+ rowHeights[ri] = explicitHeight;
5854
+ }
5855
+ for (const p of placed) {
5856
+ if (p.rowSpan === 1 && rowHeights[p.startRow] === 0)
5857
+ rowHeights[p.startRow] = p.cellHeight;
5858
+ else if (p.rowSpan === 1)
5859
+ rowHeights[p.startRow] = Math.max(rowHeights[p.startRow], p.cellHeight);
5860
+ }
5861
+ for (const p of placed) {
5862
+ if (p.rowSpan <= 1)
5863
+ continue;
5864
+ const covered = sumSpan(rowHeights, p.startRow, p.rowSpan, rowGaps);
5865
+ if (p.cellHeight > covered) {
5866
+ const extra = (p.cellHeight - covered) / p.rowSpan;
5867
+ for (let r = p.startRow;r < p.startRow + p.rowSpan; r++)
5868
+ rowHeights[r] += extra;
5869
+ }
5870
+ }
5871
+ }
5872
+ if (table.height !== undefined) {
5873
+ const budget = table.height - margins.top - margins.bottom - rowGaps * Math.max(0, rowCount - 1);
5874
+ const naturalSum = rowHeights.reduce((a, b) => a + b, 0);
5875
+ if (naturalSum > 0 && budget > 0) {
5876
+ const scale = budget / naturalSum;
5877
+ for (let i = 0;i < rowHeights.length; i++)
5878
+ rowHeights[i] *= scale;
5879
+ }
5880
+ }
5881
+ const colX = [];
5882
+ {
5883
+ let acc = margins.left;
5884
+ for (let c = 0;c < colCount; c++) {
5885
+ colX.push(acc);
5886
+ acc += colWidths[c] + colGaps;
5887
+ }
5888
+ }
5889
+ const rowY = [];
5890
+ {
5891
+ let acc = margins.top;
5892
+ for (let r = 0;r < rowCount; r++) {
5893
+ rowY.push(acc);
5894
+ acc += rowHeights[r] + rowGaps;
5895
+ }
5896
+ }
5897
+ const rows = table.rows.map((row, ri) => {
5898
+ const rs = resolveRowStyle(row, table);
5899
+ const rowBorder = resolveBorder(rs);
5900
+ const cells = placed.filter((p) => p.startRow === ri).map((p) => {
5901
+ const height = sumSpan(rowHeights, p.startRow, p.rowSpan, rowGaps);
5902
+ const available = height - p.inset.top - p.inset.bottom;
5903
+ const verticalOffset = verticalOffsetFor(p.cs.verticalAlign, available, p.content.content.height);
5904
+ const cellX = colX[p.startCol];
5905
+ const cellY = rowY[p.startRow];
5906
+ let before;
5907
+ if (p.cell.before) {
5908
+ const bc = layoutTextFrame({ ...p.cell.before, width: undefined, wrap: false }, { mode: options.mode, onMissingFont: options.onMissingFont });
5909
+ before = { content: bc, x: cellX + p.inset.left, y: cellY + (height - bc.content.height) / 2 };
5910
+ }
5911
+ let after;
5912
+ if (p.cell.after) {
5913
+ const ac = layoutTextFrame({ ...p.cell.after, width: undefined, wrap: false }, { mode: options.mode, onMissingFont: options.onMissingFont });
5914
+ after = { content: ac, x: cellX + p.width - p.inset.right - ac.content.width, y: cellY + (height - ac.content.height) / 2 };
5915
+ }
5916
+ return {
5917
+ x: cellX,
5918
+ y: cellY,
5919
+ width: p.width,
5920
+ height,
5921
+ padding: p.pad,
5922
+ verticalOffset,
5923
+ cx: p.cs.cx,
5924
+ cy: p.cs.cy,
5925
+ allowOverflow: p.cs.allowOverflow,
5926
+ ...p.cs.bgColor ? { bgColor: p.cs.bgColor } : {},
5927
+ ...p.border ? { border: p.border } : {},
5928
+ content: p.content,
5929
+ ...p.nestedTable ? { nestedTable: p.nestedTable } : {},
5930
+ ...before ? { before } : {},
5931
+ ...after ? { after } : {},
5932
+ colSpan: p.colSpan,
5933
+ rowSpan: p.rowSpan
5934
+ };
5935
+ });
5936
+ return {
5937
+ y: rowY[ri],
5938
+ height: rowHeights[ri],
5939
+ ...rs.bgColor ? { bgColor: rs.bgColor } : {},
5940
+ ...rowBorder ? { border: rowBorder } : {},
5941
+ cells
5942
+ };
5943
+ });
5944
+ const totalWidth = margins.left + colWidths.reduce((a, b) => a + b, 0) + colGaps * Math.max(0, colCount - 1) + margins.right;
5945
+ const totalHeight = margins.top + rowHeights.reduce((a, b) => a + b, 0) + rowGaps * Math.max(0, rowCount - 1) + margins.bottom;
5946
+ return {
5947
+ width: totalWidth,
5948
+ height: totalHeight,
5949
+ bgColor: style.bgColor,
5950
+ ...tableBorder ? { border: tableBorder } : {},
5951
+ contentBox: {
5952
+ x: margins.left,
5953
+ y: margins.top,
5954
+ width: totalWidth - margins.left - margins.right,
5955
+ height: totalHeight - margins.top - margins.bottom
5956
+ },
5957
+ rows
5958
+ };
5959
+ }
5552
5960
  // src/utils/groupLinesByParagraph.ts
5553
5961
  function groupLinesByParagraph(lines) {
5554
5962
  const map = new Map;
@@ -5673,6 +6081,7 @@ export {
5673
6081
  measurePx,
5674
6082
  makeFontToken,
5675
6083
  layoutTextFrame,
6084
+ layoutTableFrame,
5676
6085
  isFontEngineAvailable,
5677
6086
  groupLinesByParagraph,
5678
6087
  getParagraphText,
@@ -1 +1 @@
1
- {"version":3,"file":"ParagraphLayoutEngine.d.ts","sourceRoot":"","sources":["../../src/layout/ParagraphLayoutEngine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAQrE,OAAO,EAAqB,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AA+E1E,qBAAa,qBAAqB;IAChC,yFAAyF;IACzF,OAAO,CAAC,aAAa,CAAyC;IAC9D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;gBAEtB,QAAQ,GAAE,MAAmC;IAIzD,mEAAmE;IACnE,UAAU,IAAI,IAAI;IAIlB;;;;;;;OAOG;IACH,MAAM,CACJ,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,MAAU,EACnB,YAAY,CAAC,EAAE,oBAAoB,EACnC,SAAS,CAAC,EAAE,SAAS,EACrB,SAAS,CAAC,EAAE,MAAM,EAClB,eAAe,CAAC,EAAE,MAAM,EACxB,iBAAiB,GAAE,OAAe,EAClC,IAAI,CAAC,EAAE,SAAS,GAAG,QAAQ,EAC3B,aAAa,GAAE,aAAuB,GACrC,qBAAqB;IAgLxB;;;OAGG;IACH,WAAW,CACT,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,MAAU,GAClB,qBAAqB;IAIxB;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;CAoC7B;AAED,gBAAgB;AAChB,eAAO,MAAM,qBAAqB,EAAE,qBAAmD,CAAC"}
1
+ {"version":3,"file":"ParagraphLayoutEngine.d.ts","sourceRoot":"","sources":["../../src/layout/ParagraphLayoutEngine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAQrE,OAAO,EAAqB,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAyG1E,qBAAa,qBAAqB;IAChC,yFAAyF;IACzF,OAAO,CAAC,aAAa,CAAyC;IAC9D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;gBAEtB,QAAQ,GAAE,MAAmC;IAIzD,mEAAmE;IACnE,UAAU,IAAI,IAAI;IAIlB;;;;;;;OAOG;IACH,MAAM,CACJ,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,MAAU,EACnB,YAAY,CAAC,EAAE,oBAAoB,EACnC,SAAS,CAAC,EAAE,SAAS,EACrB,SAAS,CAAC,EAAE,MAAM,EAClB,eAAe,CAAC,EAAE,MAAM,EACxB,iBAAiB,GAAE,OAAe,EAClC,IAAI,CAAC,EAAE,SAAS,GAAG,QAAQ,EAC3B,aAAa,GAAE,aAAuB,GACrC,qBAAqB;IAmLxB;;;OAGG;IACH,WAAW,CACT,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,MAAU,GAClB,qBAAqB;IAIxB;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;CAoC7B;AAED,gBAAgB;AAChB,eAAO,MAAM,qBAAqB,EAAE,qBAAmD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"PositioningEngine.d.ts","sourceRoot":"","sources":["../../src/layout/PositioningEngine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAgB,MAAM,sBAAsB,CAAC;AACpF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAE,IAAI,EAAyB,MAAM,yBAAyB,CAAC;AAC3E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAK9E,UAAU,eAAe;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;IACvD,GAAG,EAAE;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;CACtD;AAED,UAAU,WAAW;IACnB,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;CACtD;AAmDD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,aAAa,CAC3B,YAAY,EAAE,WAAW,EAAE,EAC3B,KAAK,EAAE,sBAAsB,EAAE,EAC/B,aAAa,EAAE,CAAC,IAAI,EAAE,sBAAsB,KAAK,WAAW,EAC5D,KAAK,EAAE,cAAc,EACrB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,YAAI,EAClB,IAAI,EAAE,SAAS,GAAG,QAAQ,YAAY,EACtC,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,MAAM,EACrH,GAAG,CAAC,EAAE,MAAM,EACZ,SAAS,CAAC,EAAE,SAAS,EACrB,SAAS,CAAC,EAAE,MAAM,EAClB,eAAe,CAAC,EAAE,MAAM,GACvB;IAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CA6gBzC"}
1
+ {"version":3,"file":"PositioningEngine.d.ts","sourceRoot":"","sources":["../../src/layout/PositioningEngine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAgB,MAAM,sBAAsB,CAAC;AACpF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAE,IAAI,EAAyB,MAAM,yBAAyB,CAAC;AAC3E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAK9E,UAAU,eAAe;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;IACvD,GAAG,EAAE;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;CACtD;AAED,UAAU,WAAW;IACnB,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;CACtD;AAmDD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,aAAa,CAC3B,YAAY,EAAE,WAAW,EAAE,EAC3B,KAAK,EAAE,sBAAsB,EAAE,EAC/B,aAAa,EAAE,CAAC,IAAI,EAAE,sBAAsB,KAAK,WAAW,EAC5D,KAAK,EAAE,cAAc,EACrB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,YAAI,EAClB,IAAI,EAAE,SAAS,GAAG,QAAQ,YAAY,EACtC,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,MAAM,EACrH,GAAG,CAAC,EAAE,MAAM,EACZ,SAAS,CAAC,EAAE,SAAS,EACrB,SAAS,CAAC,EAAE,MAAM,EAClB,eAAe,CAAC,EAAE,MAAM,GACvB;IAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAohBzC"}