oasis-editor 0.0.114 → 0.0.116

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 (51) hide show
  1. package/dist/{OasisEditorApp-XloOiKSu.js → OasisEditorApp-DY_N4M54.js} +424 -366
  2. package/dist/adapters/react.d.ts +11 -0
  3. package/dist/adapters/ui.d.ts +2 -0
  4. package/dist/adapters/vue.d.ts +23 -0
  5. package/dist/assets/{importDocxWorker-D0F0jbcF.js → importDocxWorker-nIS-zjkj.js} +1 -1
  6. package/dist/core/decorationGeometry.d.ts +10 -0
  7. package/dist/core/gradientAxis.d.ts +11 -0
  8. package/dist/core/html/inlineImageParser.d.ts +7 -0
  9. package/dist/core/layoutConstants.d.ts +18 -0
  10. package/dist/core/textStyleMappings.d.ts +2 -0
  11. package/dist/export/pdf/draw/drawFragment.d.ts +4 -4
  12. package/dist/export/pdf/draw/fragment/pdfColor.d.ts +1 -0
  13. package/dist/export/pdf/draw/fragment/pdfEmphasisAndTabLeaders.d.ts +5 -0
  14. package/dist/export/pdf/draw/fragment/pdfGradient.d.ts +4 -0
  15. package/dist/export/pdf/draw/fragment/pdfRunBackground.d.ts +12 -0
  16. package/dist/export/pdf/draw/fragment/pdfTextChunks.d.ts +25 -0
  17. package/dist/export/pdf/draw/fragment/pdfTextDecoration.d.ts +4 -0
  18. package/dist/{index-CwpzM--5.js → index-DLKF27_V.js} +1211 -1121
  19. package/dist/layoutProjection/blocksPaginationTypes.d.ts +2 -0
  20. package/dist/layoutProjection/headerFooterLayoutContext.d.ts +2 -0
  21. package/dist/layoutProjection/paginationTrack.d.ts +2 -0
  22. package/dist/layoutProjection/paragraphPagination.d.ts +8 -3
  23. package/dist/layoutProjection/sectionPagination.d.ts +3 -0
  24. package/dist/layoutProjection/tableRowSlicing.d.ts +2 -1
  25. package/dist/oasis-editor.js +55 -55
  26. package/dist/oasis-editor.umd.cjs +4 -4
  27. package/dist/react.d.ts +7 -8
  28. package/dist/react.js +18 -22
  29. package/dist/ui/canvas/CanvasTableLayout.d.ts +12 -63
  30. package/dist/ui/canvas/canvasParagraphPainter.d.ts +4 -22
  31. package/dist/ui/canvas/paragraph/canvasEmphasis.d.ts +3 -0
  32. package/dist/ui/canvas/paragraph/canvasInlineImage.d.ts +26 -0
  33. package/dist/ui/canvas/paragraph/canvasRunBackground.d.ts +13 -0
  34. package/dist/ui/canvas/paragraph/canvasTabLeaders.d.ts +4 -0
  35. package/dist/ui/canvas/paragraph/canvasTextDecoration.d.ts +4 -0
  36. package/dist/ui/canvas/paragraph/canvasTextEffects.d.ts +43 -0
  37. package/dist/ui/canvas/table/assembleCellEntries.d.ts +15 -0
  38. package/dist/ui/canvas/table/prepareCells.d.ts +53 -0
  39. package/dist/ui/canvas/table/resolveRowHeights.d.ts +9 -0
  40. package/dist/ui/canvas/table/tableCellGeometry.d.ts +37 -0
  41. package/dist/ui/canvas/table/types.d.ts +63 -0
  42. package/dist/ui/components/FindReplace/FindReplaceDialog.d.ts +1 -2
  43. package/dist/ui/components/Menubar/Menubar.d.ts +1 -2
  44. package/dist/ui/components/PageBreak.d.ts +1 -1
  45. package/dist/ui.d.ts +2 -42
  46. package/dist/ui.js +19 -18
  47. package/dist/utils/performanceMetrics.d.ts +0 -6
  48. package/dist/utils/round.d.ts +7 -0
  49. package/dist/vue.d.ts +22 -8
  50. package/dist/vue.js +18 -24
  51. package/package.json +9 -6
@@ -2539,7 +2539,7 @@ function OasisEditorAppLazy(props = {}) {
2539
2539
  onCleanup(() => {
2540
2540
  cancelled = true;
2541
2541
  });
2542
- import("./OasisEditorApp-XloOiKSu.js").then((m) => {
2542
+ import("./OasisEditorApp-DY_N4M54.js").then((m) => {
2543
2543
  cancelled = true;
2544
2544
  setProgress(1);
2545
2545
  setTimeout(() => setApp(() => m.OasisEditorApp), 180);
@@ -13135,6 +13135,10 @@ function getPreciseFontProgram(family, bold, italic) {
13135
13135
  const resolved = family ?? "";
13136
13136
  return registry.get(faceKey(resolved, bold, italic)) ?? registry.get(faceKey(resolved, false, false)) ?? null;
13137
13137
  }
13138
+ function roundTo(value, decimals) {
13139
+ const factor = 10 ** decimals;
13140
+ return Math.round(value * factor) / factor;
13141
+ }
13138
13142
  const familyFileCache = /* @__PURE__ */ new Map();
13139
13143
  const fontLogger$1 = createEditorLogger("fonts");
13140
13144
  function resolveFaceFiles(family) {
@@ -13312,7 +13316,7 @@ async function preloadLayoutFonts(families) {
13312
13316
  );
13313
13317
  const finishedAt = typeof performance !== "undefined" ? performance.now() : Date.now();
13314
13318
  fontLogger$1.info("preload:done", {
13315
- durationMs: Math.round((finishedAt - startedAt) * 100) / 100,
13319
+ durationMs: roundTo(finishedAt - startedAt, 2),
13316
13320
  results,
13317
13321
  documentFontsStatus: typeof document !== "undefined" && document.fonts ? document.fonts.status : "unavailable"
13318
13322
  });
@@ -14086,7 +14090,6 @@ function findHyphenationPoints(word, lang) {
14086
14090
  }
14087
14091
  const DEFAULT_CONTENT_WIDTH = 624;
14088
14092
  const MIN_CONTENT_WIDTH = 120;
14089
- const PT_TO_PX = 96 / 72;
14090
14093
  function intersectsVertically(aTop, aBottom, bTop, bBottom) {
14091
14094
  return aTop < bBottom && aBottom > bTop;
14092
14095
  }
@@ -14538,7 +14541,7 @@ function composeMeasuredParagraphLines(options) {
14538
14541
  }
14539
14542
  if (!isEmptyLine) {
14540
14543
  const remaining = lineAvailableWidth - lineWidth;
14541
- const zonePx = ((hyphenation == null ? void 0 : hyphenation.zone) ?? 0) * PT_TO_PX;
14544
+ const zonePx = ((hyphenation == null ? void 0 : hyphenation.zone) ?? 0) * PX_PER_POINT;
14542
14545
  if (remaining > zonePx) {
14543
14546
  const hy = tryHyphenate(token.chars, remaining);
14544
14547
  if (hy) {
@@ -14938,6 +14941,9 @@ function getParagraphBorderInsets(style2) {
14938
14941
  bottom: edgeInset(style2.borderBottom)
14939
14942
  };
14940
14943
  }
14944
+ const VERTICAL_HIT_WEIGHT = 1e3;
14945
+ const TEXT_BASELINE_RATIO = 0.8;
14946
+ const NO_WRAP_MEASURE_WIDTH_PX = 1e5;
14941
14947
  function formatTimestamp() {
14942
14948
  const now = /* @__PURE__ */ new Date();
14943
14949
  const h = String(now.getHours()).padStart(2, "0");
@@ -14972,7 +14978,7 @@ function markEnd(label) {
14972
14978
  performance.mark(endName);
14973
14979
  try {
14974
14980
  const measure = performance.measure(label, startName, endName);
14975
- const duration = Math.round(measure.duration * 100) / 100;
14981
+ const duration = roundTo(measure.duration, 2);
14976
14982
  marks.push({
14977
14983
  name: label,
14978
14984
  duration,
@@ -14993,14 +14999,14 @@ function markEnd(label) {
14993
14999
  function recordDuration(label, durationMs) {
14994
15000
  marks.push({
14995
15001
  name: label,
14996
- duration: Math.round(durationMs * 100) / 100,
15002
+ duration: roundTo(durationMs, 2),
14997
15003
  timestamp: Date.now()
14998
15004
  });
14999
15005
  if (shouldLogPerformanceMetrics()) {
15000
15006
  console.info(
15001
15007
  `%c[perf] ${label}`,
15002
15008
  "color: #f59e0b;",
15003
- `${formatTimestamp()} ${Math.round(durationMs * 100) / 100}ms`
15009
+ `${formatTimestamp()} ${roundTo(durationMs, 2)}ms`
15004
15010
  );
15005
15011
  }
15006
15012
  }
@@ -15052,7 +15058,7 @@ function startLongTaskObserver() {
15052
15058
  observer = new PerformanceObserver((list) => {
15053
15059
  for (const entry of list.getEntries()) {
15054
15060
  longTasks.push({
15055
- duration: Math.round(entry.duration * 100) / 100,
15061
+ duration: roundTo(entry.duration, 2),
15056
15062
  startTime: Math.round(entry.startTime)
15057
15063
  });
15058
15064
  }
@@ -15347,11 +15353,14 @@ function resolveDropCapExclusion(options) {
15347
15353
  sourceRunId: DROP_CAP_EXCLUSION_RUN_ID
15348
15354
  };
15349
15355
  }
15350
- let activeHyphenation;
15351
- let activeHyphenationSignature = "";
15352
- function setActiveHyphenation(options) {
15353
- activeHyphenation = (options == null ? void 0 : options.enabled) ? options : void 0;
15354
- activeHyphenationSignature = activeHyphenation ? `h:${activeHyphenation.zone ?? ""}:${activeHyphenation.consecutiveLimit ?? ""}:${activeHyphenation.doNotHyphenateCaps ? 1 : 0}` : "";
15356
+ const EMPTY_PROJECTION_CONTEXT = {
15357
+ hyphenation: void 0,
15358
+ hyphenationSignature: ""
15359
+ };
15360
+ function createProjectionContext(options) {
15361
+ const hyphenation = (options == null ? void 0 : options.enabled) ? options : void 0;
15362
+ const hyphenationSignature = hyphenation ? `h:${hyphenation.zone ?? ""}:${hyphenation.consecutiveLimit ?? ""}:${hyphenation.doNotHyphenateCaps ? 1 : 0}` : "";
15363
+ return { hyphenation, hyphenationSignature };
15355
15364
  }
15356
15365
  function paragraphStyleComparableKey(style2) {
15357
15366
  const {
@@ -15418,9 +15427,9 @@ function getParagraphFieldDependence(paragraph) {
15418
15427
  paragraphFieldDependenceCache.set(paragraph, result);
15419
15428
  return result;
15420
15429
  }
15421
- function projectParagraphLayout(paragraph, pageIndex, totalPages, styles, contentWidth, measurer = domTextMeasurer, defaultTabStop) {
15430
+ function projectParagraphLayout(paragraph, pageIndex, totalPages, styles, contentWidth, measurer = domTextMeasurer, defaultTabStop, context2 = EMPTY_PROJECTION_CONTEXT) {
15422
15431
  const { dependsOnPageIndex, dependsOnTotalPages } = getParagraphFieldDependence(paragraph);
15423
- const cacheKey = `${dependsOnPageIndex ? pageIndex ?? "" : ""}:${dependsOnTotalPages ? totalPages ?? "" : ""}:${contentWidth ?? ""}:${defaultTabStop ?? ""}:${activeHyphenationSignature}`;
15432
+ const cacheKey = `${dependsOnPageIndex ? pageIndex ?? "" : ""}:${dependsOnTotalPages ? totalPages ?? "" : ""}:${contentWidth ?? ""}:${defaultTabStop ?? ""}:${context2.hyphenationSignature}`;
15424
15433
  let cacheForParagraph = paragraphLayoutCache.get(paragraph);
15425
15434
  if (cacheForParagraph) {
15426
15435
  const cached = cacheForParagraph.get(cacheKey);
@@ -15478,7 +15487,7 @@ function projectParagraphLayout(paragraph, pageIndex, totalPages, styles, conten
15478
15487
  styles,
15479
15488
  contentWidth,
15480
15489
  defaultTabStop,
15481
- hyphenation: activeHyphenation
15490
+ hyphenation: context2.hyphenation
15482
15491
  }).map((line) => ({
15483
15492
  ...line,
15484
15493
  height: line.height || lineHeight,
@@ -15507,7 +15516,7 @@ function projectParagraphLayout(paragraph, pageIndex, totalPages, styles, conten
15507
15516
  cacheForParagraph.set(cacheKey, result);
15508
15517
  return result;
15509
15518
  }
15510
- function projectParagraphLayoutWithExclusions(paragraph, pageSettings, contentWidth, measurer = domTextMeasurer, pageIndex, totalPages, styles, defaultTabStop, resolveTextBoxHeight, externalExclusions = []) {
15519
+ function projectParagraphLayoutWithExclusions(paragraph, pageSettings, contentWidth, measurer = domTextMeasurer, pageIndex, totalPages, styles, defaultTabStop, resolveTextBoxHeight, externalExclusions = [], context2 = EMPTY_PROJECTION_CONTEXT) {
15511
15520
  const preliminary = projectParagraphLayout(
15512
15521
  paragraph,
15513
15522
  pageIndex,
@@ -15515,7 +15524,8 @@ function projectParagraphLayoutWithExclusions(paragraph, pageSettings, contentWi
15515
15524
  styles,
15516
15525
  contentWidth,
15517
15526
  measurer,
15518
- defaultTabStop
15527
+ defaultTabStop,
15528
+ context2
15519
15529
  );
15520
15530
  if (!pageSettings || !contentWidth) {
15521
15531
  return preliminary;
@@ -15776,7 +15786,6 @@ function estimateParagraphBlockHeight(paragraph, styles, contentWidth, measurer
15776
15786
  }
15777
15787
  const MIN_TABLE_CELL_CONTENT_WIDTH_PX$2 = 24;
15778
15788
  const DEFAULT_CELL_PADDING_LEFT_RIGHT_PX$1 = 7.2;
15779
- const NO_WRAP_MEASURE_WIDTH_PX$1 = 1e5;
15780
15789
  function toPx$1(valuePt) {
15781
15790
  return valuePt * PX_PER_POINT;
15782
15791
  }
@@ -15850,7 +15859,7 @@ function getTableCellContentWidthForParagraph(document2, paragraphId, activeSect
15850
15859
  if (!row) return null;
15851
15860
  const cell = row.cells[tableLocation.cellIndex];
15852
15861
  if (!cell) return null;
15853
- if ((_a = cell.style) == null ? void 0 : _a.noWrap) return NO_WRAP_MEASURE_WIDTH_PX$1;
15862
+ if ((_a = cell.style) == null ? void 0 : _a.noWrap) return NO_WRAP_MEASURE_WIDTH_PX;
15854
15863
  const pageContentWidthPx = getPageContentWidth(
15855
15864
  getDocumentPageSettings(document2)
15856
15865
  );
@@ -15917,7 +15926,6 @@ function resolveCachedTableCellParagraph(source, formatting, styles) {
15917
15926
  return resolved;
15918
15927
  }
15919
15928
  const DEFAULT_LINE_HEIGHT = 1.15;
15920
- const NO_WRAP_MEASURE_WIDTH_PX = 1e5;
15921
15929
  const DEFAULT_TABLE_CELL_HORIZONTAL_PADDING_PX = 14.4;
15922
15930
  const MIN_TABLE_CELL_CONTENT_WIDTH_PX$1 = 24;
15923
15931
  const DEFAULT_TABLE_SEGMENT_VERTICAL_SPACING = 0;
@@ -16471,7 +16479,8 @@ function paginateParagraphBlock(track, params, sourceBlock, nextBlock, index) {
16471
16479
  track.floatingExclusions.map((exclusion) => ({
16472
16480
  ...exclusion,
16473
16481
  y: exclusion.y - track.height
16474
- }))
16482
+ })),
16483
+ params.projectionContext ?? EMPTY_PROJECTION_CONTEXT
16475
16484
  );
16476
16485
  const measuredParagraphLayout = measuredParagraphLayouts == null ? void 0 : measuredParagraphLayouts[sourceBlock.id];
16477
16486
  const paragraphLayout = measuredParagraphLayout && isMeasuredLayoutCurrent(projectedParagraphLayout, measuredParagraphLayout) ? applyMeasuredLineGeometry(
@@ -16783,7 +16792,7 @@ function estimateSingleCellRowSliceHeight(row, cellIndex, start, end, styles, me
16783
16792
  rowIndex
16784
16793
  );
16785
16794
  }
16786
- function findCellSplitEndPosition(row, cellIndex, start, availableHeight, styles, measurer, defaultTabStop, contentWidth, table, rowIndex) {
16795
+ function findCellSplitEndPosition(row, cellIndex, start, availableHeight, styles, measurer, defaultTabStop, contentWidth, table, rowIndex, projectionContext = EMPTY_PROJECTION_CONTEXT) {
16787
16796
  const cell = row.cells[cellIndex];
16788
16797
  if (!cell) return start;
16789
16798
  const limit = cell.blocks.length;
@@ -16822,7 +16831,8 @@ function findCellSplitEndPosition(row, cellIndex, start, availableHeight, styles
16822
16831
  styles,
16823
16832
  contentWidth,
16824
16833
  measurer,
16825
- defaultTabStop
16834
+ defaultTabStop,
16835
+ projectionContext
16826
16836
  );
16827
16837
  for (const line of layout.lines) {
16828
16838
  if (line.endOffset <= startOffset || line.endOffset >= paragraphLength) {
@@ -16894,7 +16904,14 @@ function resolveFloatingTableWidth(table, contentWidth) {
16894
16904
  }
16895
16905
  function paginateTableBlock(track, params, sourceBlock, index) {
16896
16906
  var _a;
16897
- const { contentWidth, measurer, styles, defaultTabStop, measuredHeights } = params;
16907
+ const {
16908
+ contentWidth,
16909
+ measurer,
16910
+ styles,
16911
+ defaultTabStop,
16912
+ measuredHeights,
16913
+ projectionContext
16914
+ } = params;
16898
16915
  const tableHeight = (measuredHeights == null ? void 0 : measuredHeights[sourceBlock.id]) ?? estimateTableBlockHeight(
16899
16916
  sourceBlock,
16900
16917
  styles,
@@ -17108,7 +17125,8 @@ function paginateTableBlock(track, params, sourceBlock, index) {
17108
17125
  defaultTabStop,
17109
17126
  contentWidth,
17110
17127
  sourceBlock,
17111
- rowGroups[groupEndIndex].startRowIndex
17128
+ rowGroups[groupEndIndex].startRowIndex,
17129
+ projectionContext
17112
17130
  )
17113
17131
  );
17114
17132
  if (positionsProgressed(starts, ends)) {
@@ -17155,7 +17173,12 @@ function paginateTableBlock(track, params, sourceBlock, index) {
17155
17173
  splitEndPositions,
17156
17174
  startCellPositions
17157
17175
  );
17158
- advanceCursor(groupEndIndex, isLastRowSplit, splitEnds, splitEndPositions);
17176
+ advanceCursor(
17177
+ groupEndIndex,
17178
+ isLastRowSplit,
17179
+ splitEnds,
17180
+ splitEndPositions
17181
+ );
17159
17182
  return block;
17160
17183
  },
17161
17184
  force(segmentId) {
@@ -17187,7 +17210,8 @@ function paginateTableBlock(track, params, sourceBlock, index) {
17187
17210
  defaultTabStop,
17188
17211
  contentWidth,
17189
17212
  sourceBlock,
17190
- startRowIndex
17213
+ startRowIndex,
17214
+ projectionContext
17191
17215
  )
17192
17216
  );
17193
17217
  if (!positionsProgressed(starts, ends)) {
@@ -17201,7 +17225,11 @@ function paginateTableBlock(track, params, sourceBlock, index) {
17201
17225
  splitEnds = positionsToBlockIndexes(ends);
17202
17226
  splitEndPositions = ends;
17203
17227
  isLastRowSplit = true;
17204
- const slicedLastRow = buildRowSliceFromPositions(targetRow, starts, ends);
17228
+ const slicedLastRow = buildRowSliceFromPositions(
17229
+ targetRow,
17230
+ starts,
17231
+ ends
17232
+ );
17205
17233
  segmentHeight = getTableSegmentHeight(
17206
17234
  { ...sourceBlock, rows: [slicedLastRow] },
17207
17235
  0,
@@ -17236,7 +17264,12 @@ function paginateTableBlock(track, params, sourceBlock, index) {
17236
17264
  splitEndPositions,
17237
17265
  startCellPositions
17238
17266
  );
17239
- advanceCursor(groupEndIndex, isLastRowSplit, splitEnds, splitEndPositions);
17267
+ advanceCursor(
17268
+ groupEndIndex,
17269
+ isLastRowSplit,
17270
+ splitEnds,
17271
+ splitEndPositions
17272
+ );
17240
17273
  return block;
17241
17274
  }
17242
17275
  });
@@ -17267,7 +17300,8 @@ function projectColumnTrackLayout(context2) {
17267
17300
  measurer = domTextMeasurer,
17268
17301
  reservedHeightByPageIndex,
17269
17302
  defaultTabStop,
17270
- contentWidthOverride
17303
+ contentWidthOverride,
17304
+ projectionContext
17271
17305
  } = context2;
17272
17306
  const contentWidth = contentWidthOverride ?? getPageContentWidth(pageSettings);
17273
17307
  const track = new PaginationTrack(
@@ -17285,7 +17319,8 @@ function projectColumnTrackLayout(context2) {
17285
17319
  totalPages,
17286
17320
  defaultTabStop,
17287
17321
  measuredHeights,
17288
- measuredParagraphLayouts
17322
+ measuredParagraphLayouts,
17323
+ projectionContext
17289
17324
  };
17290
17325
  for (let index = 0; index < blocks.length; index += 1) {
17291
17326
  const sourceBlock = blocks[index];
@@ -17843,17 +17878,8 @@ function drawStackedParagraph(ctx, paragraph, state, box, startColumn, columnsRt
17843
17878
  ctx.restore();
17844
17879
  return endColumnRight;
17845
17880
  }
17846
- const NO_WRAP_WIDTH_PX = 1e5;
17847
- function resolveCellVerticalMode(cell) {
17848
- var _a, _b, _c;
17849
- const direction = ((_a = cell.style) == null ? void 0 : _a.textDirection) ?? ((_c = (_b = cell.blocks[0]) == null ? void 0 : _b.style) == null ? void 0 : _c.textDirection) ?? null;
17850
- return resolveVerticalMode(direction);
17851
- }
17852
- const DEFAULT_TABLE_ROW_HEIGHT = 14;
17853
17881
  const DEFAULT_CELL_PADDING_TOP_BOTTOM_PX = 0;
17854
17882
  const DEFAULT_CELL_PADDING_LEFT_RIGHT_PX = 7.2;
17855
- const MIN_TABLE_CELL_CONTENT_WIDTH_PX = 24;
17856
- const MIN_TABLE_CELL_CONTENT_HEIGHT_PX = 1;
17857
17883
  function toPx(value) {
17858
17884
  return value * PX_PER_POINT;
17859
17885
  }
@@ -17872,51 +17898,6 @@ function parseDimensionToPx(value) {
17872
17898
  const parsed = Number.parseFloat(trimmed);
17873
17899
  return Number.isFinite(parsed) ? parsed : null;
17874
17900
  }
17875
- function resolveCanvasTableWidth(table, contentWidth) {
17876
- var _a;
17877
- const raw = (_a = table.style) == null ? void 0 : _a.width;
17878
- if (typeof raw === "number") return Math.max(24, toPx(raw));
17879
- if (typeof raw === "string" && raw.trim().endsWith("%")) {
17880
- const value = Number.parseFloat(raw.trim().slice(0, -1));
17881
- if (Number.isFinite(value))
17882
- return Math.max(24, contentWidth * (value / 100));
17883
- }
17884
- return contentWidth;
17885
- }
17886
- function resolveTableIndentLeft(table) {
17887
- var _a;
17888
- const raw = (_a = table.style) == null ? void 0 : _a.indentLeft;
17889
- return typeof raw === "number" && Number.isFinite(raw) ? toPx(raw) : 0;
17890
- }
17891
- function resolveTableCellSpacingPx(table) {
17892
- var _a;
17893
- const px = parseDimensionToPx((_a = table.style) == null ? void 0 : _a.cellSpacing);
17894
- return px !== null && px > 0 ? px : 0;
17895
- }
17896
- function lineNaturalWidth(line) {
17897
- if (line.slots.length < 2) return 0;
17898
- return line.slots[line.slots.length - 1].left - line.slots[0].left;
17899
- }
17900
- function applyFitTextScale(paragraph, scalePercent) {
17901
- return {
17902
- ...paragraph,
17903
- runs: paragraph.runs.map((run) => {
17904
- var _a;
17905
- const existing = (_a = run.styles) == null ? void 0 : _a.characterScale;
17906
- const combined = typeof existing === "number" && existing > 0 ? existing * scalePercent / 100 : scalePercent;
17907
- return { ...run, styles: { ...run.styles, characterScale: combined } };
17908
- })
17909
- };
17910
- }
17911
- function resolveTableLeftOffset(table, tableWidth, contentWidth) {
17912
- var _a;
17913
- const align = (_a = table.style) == null ? void 0 : _a.align;
17914
- if (align === "center" || align === "right") {
17915
- const slack = Math.max(0, contentWidth - tableWidth);
17916
- return align === "center" ? slack / 2 : slack;
17917
- }
17918
- return resolveTableIndentLeft(table);
17919
- }
17920
17901
  function resolveDefaultBorder() {
17921
17902
  return { width: 1, color: "#6f6f6f", type: "solid" };
17922
17903
  }
@@ -17945,6 +17926,17 @@ function resolveCellPadding(cell) {
17945
17926
  const left = ((_f = cell.style) == null ? void 0 : _f.paddingLeft) !== void 0 ? toPx(cell.style.paddingLeft) : ((_g = cell.style) == null ? void 0 : _g.paddingStart) !== void 0 ? toPx(cell.style.paddingStart) : DEFAULT_CELL_PADDING_LEFT_RIGHT_PX;
17946
17927
  return { top, right, bottom, left };
17947
17928
  }
17929
+ function resolveVerticalContentOffset(cell, contentHeightPx, contentNaturalHeightPx) {
17930
+ var _a, _b;
17931
+ const available = Math.max(0, contentHeightPx - contentNaturalHeightPx);
17932
+ if (((_a = cell.style) == null ? void 0 : _a.verticalAlign) === "bottom") {
17933
+ return available;
17934
+ }
17935
+ if (((_b = cell.style) == null ? void 0 : _b.verticalAlign) === "middle") {
17936
+ return available / 2;
17937
+ }
17938
+ return 0;
17939
+ }
17948
17940
  function fitImagesToCellWidth(paragraph, maxImageWidthPx) {
17949
17941
  if (!Number.isFinite(maxImageWidthPx) || maxImageWidthPx <= 0) {
17950
17942
  return paragraph;
@@ -17968,116 +17960,86 @@ function fitImagesToCellWidth(paragraph, maxImageWidthPx) {
17968
17960
  if (!changed) return paragraph;
17969
17961
  return { ...paragraph, runs };
17970
17962
  }
17971
- function resolveVerticalContentOffset(cell, contentHeightPx, contentNaturalHeightPx) {
17972
- var _a, _b;
17973
- const available = Math.max(0, contentHeightPx - contentNaturalHeightPx);
17974
- if (((_a = cell.style) == null ? void 0 : _a.verticalAlign) === "bottom") {
17975
- return available;
17963
+ function applyFitTextScale(paragraph, scalePercent) {
17964
+ return {
17965
+ ...paragraph,
17966
+ runs: paragraph.runs.map((run) => {
17967
+ var _a;
17968
+ const existing = (_a = run.styles) == null ? void 0 : _a.characterScale;
17969
+ const combined = typeof existing === "number" && existing > 0 ? existing * scalePercent / 100 : scalePercent;
17970
+ return { ...run, styles: { ...run.styles, characterScale: combined } };
17971
+ })
17972
+ };
17973
+ }
17974
+ function resolveCanvasTableWidth(table, contentWidth) {
17975
+ var _a;
17976
+ const raw = (_a = table.style) == null ? void 0 : _a.width;
17977
+ if (typeof raw === "number") return Math.max(24, toPx(raw));
17978
+ if (typeof raw === "string" && raw.trim().endsWith("%")) {
17979
+ const value = Number.parseFloat(raw.trim().slice(0, -1));
17980
+ if (Number.isFinite(value))
17981
+ return Math.max(24, contentWidth * (value / 100));
17976
17982
  }
17977
- if (((_b = cell.style) == null ? void 0 : _b.verticalAlign) === "middle") {
17978
- return available / 2;
17983
+ return contentWidth;
17984
+ }
17985
+ function resolveTableIndentLeft(table) {
17986
+ var _a;
17987
+ const raw = (_a = table.style) == null ? void 0 : _a.indentLeft;
17988
+ return typeof raw === "number" && Number.isFinite(raw) ? toPx(raw) : 0;
17989
+ }
17990
+ function resolveTableCellSpacingPx(table) {
17991
+ var _a;
17992
+ const px = parseDimensionToPx((_a = table.style) == null ? void 0 : _a.cellSpacing);
17993
+ return px !== null && px > 0 ? px : 0;
17994
+ }
17995
+ function resolveTableLeftOffset(table, tableWidth, contentWidth) {
17996
+ var _a;
17997
+ const align = (_a = table.style) == null ? void 0 : _a.align;
17998
+ if (align === "center" || align === "right") {
17999
+ const slack = Math.max(0, contentWidth - tableWidth);
18000
+ return align === "center" ? slack / 2 : slack;
17979
18001
  }
17980
- return 0;
18002
+ return resolveTableIndentLeft(table);
17981
18003
  }
17982
- function buildCanvasTableLayout(options) {
17983
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J;
18004
+ const MIN_TABLE_CELL_CONTENT_WIDTH_PX = 24;
18005
+ function resolveCellVerticalMode(cell) {
18006
+ var _a, _b, _c;
18007
+ const direction = ((_a = cell.style) == null ? void 0 : _a.textDirection) ?? ((_c = (_b = cell.blocks[0]) == null ? void 0 : _b.style) == null ? void 0 : _c.textDirection) ?? null;
18008
+ return resolveVerticalMode(direction);
18009
+ }
18010
+ function lineNaturalWidth(line) {
18011
+ if (line.slots.length < 2) return 0;
18012
+ return line.slots[line.slots.length - 1].left - line.slots[0].left;
18013
+ }
18014
+ function prepareCells(options) {
18015
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y;
17984
18016
  const {
17985
- table: sourceTable,
18017
+ table,
18018
+ sourceTable,
18019
+ tableEntries,
18020
+ columnOffsets,
18021
+ cellSpacingPx,
18022
+ visualColumnCount,
18023
+ effectiveRowStyles,
17986
18024
  state,
17987
- pageIndex,
17988
- originX,
17989
- originY,
17990
- contentWidth,
17991
- estimatedHeight
18025
+ pageIndex
17992
18026
  } = options;
17993
- const table = {
17994
- ...sourceTable,
17995
- style: resolveEffectiveTableStyle(sourceTable, state.document.styles)
17996
- };
17997
- const tableWidth = resolveCanvasTableWidth(table, contentWidth);
17998
- const tableLeft = originX + resolveTableLeftOffset(table, tableWidth, contentWidth);
17999
- const cellSpacingPx = resolveTableCellSpacingPx(table);
18000
- const tableEntries = buildTableCellLayout(table);
18001
18027
  const unsupported = [];
18002
- const visualColumnCount = Math.max(
18003
- 1,
18004
- ...tableEntries.map(
18005
- (entry) => entry.visualColumnIndex + Math.max(1, entry.colSpan)
18006
- )
18007
- );
18008
- const columnsWidthBudget = Math.max(
18009
- visualColumnCount,
18010
- tableWidth - (visualColumnCount + 1) * cellSpacingPx
18011
- );
18012
- let resolvedColumnWidths = [];
18013
- if (table.gridCols && table.gridCols.length >= visualColumnCount) {
18014
- const gridTotalWidth = table.gridCols.reduce((a, b) => a + b, 0);
18015
- const scale = gridTotalWidth > 0 ? columnsWidthBudget / gridTotalWidth : 1;
18016
- resolvedColumnWidths = table.gridCols.map((w) => w * scale);
18017
- } else {
18018
- const baseCellWidth = columnsWidthBudget / visualColumnCount;
18019
- resolvedColumnWidths = Array(visualColumnCount).fill(baseCellWidth);
18020
- for (const entry of tableEntries) {
18021
- if (Math.max(1, entry.colSpan) !== 1) continue;
18022
- const cell = (_a = table.rows[entry.rowIndex]) == null ? void 0 : _a.cells[entry.cellIndex];
18023
- if (!cell || resolveCellVerticalMode(cell) !== "stack") continue;
18024
- let glyphWidth = 0;
18025
- for (const block of cell.blocks) {
18026
- if (block.type !== "paragraph") continue;
18027
- glyphWidth = Math.max(
18028
- glyphWidth,
18029
- estimateStackedColumnWidth(block, state)
18030
- );
18031
- }
18032
- if (glyphWidth <= 0) continue;
18033
- const padding = resolveCellPadding(cell);
18034
- const needed = glyphWidth + padding.left + padding.right + resolveBorder(((_b = cell.style) == null ? void 0 : _b.borderLeft) ?? ((_c = cell.style) == null ? void 0 : _c.borderStart)).width + resolveBorder(((_d = cell.style) == null ? void 0 : _d.borderRight) ?? ((_e = cell.style) == null ? void 0 : _e.borderEnd)).width;
18035
- const col = entry.visualColumnIndex;
18036
- if (needed > (resolvedColumnWidths[col] ?? 0)) {
18037
- resolvedColumnWidths[col] = needed;
18038
- }
18039
- }
18040
- }
18041
- const columnOffsets = [cellSpacingPx];
18042
- for (let i = 0; i < resolvedColumnWidths.length; i++) {
18043
- columnOffsets[i + 1] = columnOffsets[i] + resolvedColumnWidths[i] + cellSpacingPx;
18044
- }
18045
18028
  const cellEntriesByKey = new Map(
18046
18029
  tableEntries.map(
18047
18030
  (entry) => [`${entry.rowIndex}:${entry.cellIndex}`, entry]
18048
18031
  )
18049
18032
  );
18050
- const effectiveRowStyles = table.rows.map((row, rowIndex) => {
18051
- const entry = tableEntries.find(
18052
- (candidate) => candidate.rowIndex === rowIndex
18053
- );
18054
- return entry ? resolveEffectiveTableCellFormatting({
18055
- table: sourceTable,
18056
- rowIndex,
18057
- cellIndex: entry.cellIndex,
18058
- visualColumnIndex: entry.visualColumnIndex,
18059
- columnCount: visualColumnCount,
18060
- styles: state.document.styles
18061
- }).rowStyle : row.style;
18062
- });
18063
18033
  const prepared = [];
18064
18034
  for (let rowIndex = 0; rowIndex < table.rows.length; rowIndex += 1) {
18065
18035
  const row = table.rows[rowIndex];
18066
- if ((_f = effectiveRowStyles[rowIndex]) == null ? void 0 : _f.hidden) {
18067
- continue;
18068
- }
18069
- if (((_h = (_g = effectiveRowStyles[rowIndex]) == null ? void 0 : _g.revision) == null ? void 0 : _h.type) === "delete") {
18070
- continue;
18071
- }
18036
+ if ((_a = effectiveRowStyles[rowIndex]) == null ? void 0 : _a.hidden) continue;
18037
+ if (((_c = (_b = effectiveRowStyles[rowIndex]) == null ? void 0 : _b.revision) == null ? void 0 : _c.type) === "delete") continue;
18072
18038
  for (let cellIndex = 0; cellIndex < row.cells.length; cellIndex += 1) {
18073
18039
  const sourceCell = row.cells[cellIndex];
18074
- if (((_j = (_i = sourceCell.style) == null ? void 0 : _i.revision) == null ? void 0 : _j.type) === "delete") {
18075
- continue;
18076
- }
18040
+ if (((_e = (_d = sourceCell.style) == null ? void 0 : _d.revision) == null ? void 0 : _e.type) === "delete") continue;
18077
18041
  const entry = cellEntriesByKey.get(`${rowIndex}:${cellIndex}`);
18078
- if (!entry) {
18079
- continue;
18080
- }
18042
+ if (!entry) continue;
18081
18043
  const formatting = resolveEffectiveTableCellFormatting({
18082
18044
  table: sourceTable,
18083
18045
  rowIndex,
@@ -18099,32 +18061,29 @@ function buildCanvasTableLayout(options) {
18099
18061
  };
18100
18062
  const effectiveRow = formatting.rowStyle;
18101
18063
  const rowSpan = Math.max(1, cell.rowSpan ?? 1);
18102
- if (rowSpan > 1) {
18103
- unsupported.push("unsupported:v-span");
18104
- }
18105
- if (cell.vMerge === "continue" || cell.vMerge === "restart") {
18064
+ if (rowSpan > 1) unsupported.push("unsupported:v-span");
18065
+ if (cell.vMerge === "continue" || cell.vMerge === "restart")
18106
18066
  unsupported.push("unsupported:v-merge");
18107
- }
18108
18067
  const visualCol = entry.visualColumnIndex;
18109
18068
  const colSpan = Math.max(1, entry.colSpan);
18110
18069
  const width = Math.max(
18111
18070
  1,
18112
- (columnOffsets[visualCol + colSpan] ?? tableWidth) - (columnOffsets[visualCol] ?? 0) - cellSpacingPx
18071
+ (columnOffsets[visualCol + colSpan] ?? 0) - (columnOffsets[visualCol] ?? 0) - cellSpacingPx
18113
18072
  );
18114
18073
  const padding = resolveCellPadding(cell);
18115
- const logicalLeft = ((_k = table.style) == null ? void 0 : _k.bidiVisual) ? (_l = cell.style) == null ? void 0 : _l.borderEnd : (_m = cell.style) == null ? void 0 : _m.borderStart;
18116
- const logicalRight = ((_n = table.style) == null ? void 0 : _n.bidiVisual) ? (_o = cell.style) == null ? void 0 : _o.borderStart : (_p = cell.style) == null ? void 0 : _p.borderEnd;
18074
+ const logicalLeft = ((_f = table.style) == null ? void 0 : _f.bidiVisual) ? (_g = cell.style) == null ? void 0 : _g.borderEnd : (_h = cell.style) == null ? void 0 : _h.borderStart;
18075
+ const logicalRight = ((_i = table.style) == null ? void 0 : _i.bidiVisual) ? (_j = cell.style) == null ? void 0 : _j.borderStart : (_k = cell.style) == null ? void 0 : _k.borderEnd;
18117
18076
  const borders = {
18118
- top: resolveBorder((_q = cell.style) == null ? void 0 : _q.borderTop),
18119
- right: resolveBorder(((_r = cell.style) == null ? void 0 : _r.borderRight) ?? logicalRight),
18120
- bottom: resolveBorder((_s = cell.style) == null ? void 0 : _s.borderBottom),
18121
- left: resolveBorder(((_t = cell.style) == null ? void 0 : _t.borderLeft) ?? logicalLeft),
18122
- ...((_u = cell.style) == null ? void 0 : _u.borderTopLeftToBottomRight) ? {
18077
+ top: resolveBorder((_l = cell.style) == null ? void 0 : _l.borderTop),
18078
+ right: resolveBorder(((_m = cell.style) == null ? void 0 : _m.borderRight) ?? logicalRight),
18079
+ bottom: resolveBorder((_n = cell.style) == null ? void 0 : _n.borderBottom),
18080
+ left: resolveBorder(((_o = cell.style) == null ? void 0 : _o.borderLeft) ?? logicalLeft),
18081
+ ...((_p = cell.style) == null ? void 0 : _p.borderTopLeftToBottomRight) ? {
18123
18082
  topLeftToBottomRight: resolveBorder(
18124
18083
  cell.style.borderTopLeftToBottomRight
18125
18084
  )
18126
18085
  } : {},
18127
- ...((_v = cell.style) == null ? void 0 : _v.borderTopRightToBottomLeft) ? {
18086
+ ...((_q = cell.style) == null ? void 0 : _q.borderTopRightToBottomLeft) ? {
18128
18087
  topRightToBottomLeft: resolveBorder(
18129
18088
  cell.style.borderTopRightToBottomLeft
18130
18089
  )
@@ -18137,13 +18096,13 @@ function buildCanvasTableLayout(options) {
18137
18096
  const verticalMode = resolveCellVerticalMode(cell);
18138
18097
  const isRotated = verticalMode === "rotate-cw" || verticalMode === "rotate-ccw";
18139
18098
  const isStacked = verticalMode === "stack";
18140
- const isFitText = !!((_w = cell.style) == null ? void 0 : _w.fitText) && !isRotated && !isStacked;
18099
+ const isFitText = !!((_r = cell.style) == null ? void 0 : _r.fitText) && !isRotated && !isStacked;
18141
18100
  const explicitRowHeightPx = parseDimensionToPx(effectiveRow.height);
18142
18101
  const hasExplicitRowHeight = explicitRowHeightPx !== null && explicitRowHeightPx > 0;
18143
- const wrapWidth = isRotated || ((_x = cell.style) == null ? void 0 : _x.noWrap) ? isRotated && hasExplicitRowHeight ? Math.max(
18102
+ const wrapWidth = isRotated || ((_s = cell.style) == null ? void 0 : _s.noWrap) ? isRotated && hasExplicitRowHeight ? Math.max(
18144
18103
  MIN_TABLE_CELL_CONTENT_WIDTH_PX,
18145
18104
  explicitRowHeightPx - borders.top.width - borders.bottom.width - padding.top - padding.bottom
18146
- ) : NO_WRAP_WIDTH_PX : contentWidthPx;
18105
+ ) : NO_WRAP_MEASURE_WIDTH_PX : contentWidthPx;
18147
18106
  const projectedParagraphs = [];
18148
18107
  let contentNaturalHeightPx = 0;
18149
18108
  for (const original of cell.blocks) {
@@ -18154,9 +18113,9 @@ function buildCanvasTableLayout(options) {
18154
18113
  pageIndex,
18155
18114
  void 0,
18156
18115
  state.document.styles,
18157
- NO_WRAP_WIDTH_PX,
18116
+ NO_WRAP_MEASURE_WIDTH_PX,
18158
18117
  void 0,
18159
- (_y = state.document.settings) == null ? void 0 : _y.defaultTabStop
18118
+ (_t = state.document.settings) == null ? void 0 : _t.defaultTabStop
18160
18119
  );
18161
18120
  const naturalWidth = noWrapProjected.lines.length > 0 ? lineNaturalWidth(noWrapProjected.lines[0]) : 0;
18162
18121
  if (naturalWidth > 0 && contentWidthPx > 0) {
@@ -18182,7 +18141,7 @@ function buildCanvasTableLayout(options) {
18182
18141
  spacingBefore,
18183
18142
  spacingAfter
18184
18143
  });
18185
- const paragraphStyleSize = ((_A = (_z = paragraph.runs[0]) == null ? void 0 : _z.styles) == null ? void 0 : _A.fontSize) ?? DEFAULT_FONT_SIZE_PX;
18144
+ const paragraphStyleSize = ((_v = (_u = paragraph.runs[0]) == null ? void 0 : _u.styles) == null ? void 0 : _v.fontSize) ?? DEFAULT_FONT_SIZE_PX;
18186
18145
  contentNaturalHeightPx = Math.max(
18187
18146
  contentNaturalHeightPx,
18188
18147
  hasExplicitRowHeight ? paragraphStyleSize * 1.25 : stackLength
@@ -18196,13 +18155,13 @@ function buildCanvasTableLayout(options) {
18196
18155
  state.document.styles,
18197
18156
  wrapWidth,
18198
18157
  void 0,
18199
- (_B = state.document.settings) == null ? void 0 : _B.defaultTabStop
18158
+ (_w = state.document.settings) == null ? void 0 : _w.defaultTabStop
18200
18159
  );
18201
18160
  const linesBottom = projected.lines.length > 0 ? Math.max(...projected.lines.map((line) => line.top + line.height)) : 1;
18202
18161
  let effectiveSpacingBefore = spacingBefore;
18203
18162
  if (!isRotated && projectedParagraphs.length > 0) {
18204
18163
  const previous = projectedParagraphs[projectedParagraphs.length - 1];
18205
- if (((_C = state.document.settings) == null ? void 0 : _C.allowSpaceOfSameStyleInTable) && shouldCollapseContextualSpacing(
18164
+ if (((_x = state.document.settings) == null ? void 0 : _x.allowSpaceOfSameStyleInTable) && shouldCollapseContextualSpacing(
18206
18165
  previous.paragraph,
18207
18166
  paragraph,
18208
18167
  state.document.styles
@@ -18258,15 +18217,13 @@ function buildCanvasTableLayout(options) {
18258
18217
  contentNaturalHeightPx += paragraphHeight;
18259
18218
  }
18260
18219
  }
18261
- if ((_D = cell.style) == null ? void 0 : _D.hideMark) {
18220
+ if ((_y = cell.style) == null ? void 0 : _y.hideMark) {
18262
18221
  const allEmpty = cell.blocks.every(
18263
18222
  (para) => para.runs.every(
18264
18223
  (run) => (run.kind === "text" || run.kind === void 0) && (!run.text || run.text.length === 0)
18265
18224
  )
18266
18225
  );
18267
- if (allEmpty) {
18268
- contentNaturalHeightPx = 0;
18269
- }
18226
+ if (allEmpty) contentNaturalHeightPx = 0;
18270
18227
  }
18271
18228
  prepared.push({
18272
18229
  rowIndex,
@@ -18285,21 +18242,24 @@ function buildCanvasTableLayout(options) {
18285
18242
  });
18286
18243
  }
18287
18244
  }
18245
+ return { prepared, unsupported };
18246
+ }
18247
+ const DEFAULT_TABLE_ROW_HEIGHT$1 = 14;
18248
+ function resolveRowHeights(options) {
18249
+ var _a, _b, _c;
18250
+ const { prepared, table, effectiveRowStyles, estimatedHeight } = options;
18288
18251
  const rowCount = Math.max(1, table.rows.length);
18289
- const explicitRowHeights = table.rows.map((row) => {
18252
+ const explicitRowHeights = table.rows.map((row, rowIndex) => {
18290
18253
  var _a2;
18291
- const rowIndex = table.rows.indexOf(row);
18292
18254
  const effective = effectiveRowStyles[rowIndex];
18293
- if ((effective == null ? void 0 : effective.hidden) || ((_a2 = effective == null ? void 0 : effective.revision) == null ? void 0 : _a2.type) === "delete") {
18294
- return 0;
18295
- }
18255
+ if ((effective == null ? void 0 : effective.hidden) || ((_a2 = effective == null ? void 0 : effective.revision) == null ? void 0 : _a2.type) === "delete") return 0;
18296
18256
  const explicit = parseDimensionToPx(effective == null ? void 0 : effective.height);
18297
18257
  return explicit !== null && explicit > 0 ? explicit : null;
18298
18258
  });
18299
- const fallbackPerRow = estimatedHeight > 0 ? estimatedHeight / rowCount : DEFAULT_TABLE_ROW_HEIGHT;
18259
+ const fallbackPerRow = estimatedHeight > 0 ? estimatedHeight / rowCount : DEFAULT_TABLE_ROW_HEIGHT$1;
18300
18260
  const rowHeights = [];
18301
18261
  for (let rowIndex = 0; rowIndex < table.rows.length; rowIndex += 1) {
18302
- if (((_E = effectiveRowStyles[rowIndex]) == null ? void 0 : _E.hidden) || ((_G = (_F = effectiveRowStyles[rowIndex]) == null ? void 0 : _F.revision) == null ? void 0 : _G.type) === "delete") {
18262
+ if (((_a = effectiveRowStyles[rowIndex]) == null ? void 0 : _a.hidden) || ((_c = (_b = effectiveRowStyles[rowIndex]) == null ? void 0 : _b.revision) == null ? void 0 : _c.type) === "delete") {
18303
18263
  rowHeights[rowIndex] = 0;
18304
18264
  continue;
18305
18265
  }
@@ -18314,12 +18274,22 @@ function buildCanvasTableLayout(options) {
18314
18274
  const baseFloor = explicit !== null ? explicit : Math.max(1, fallbackPerRow * 0.25);
18315
18275
  rowHeights[rowIndex] = Math.max(baseFloor, measured, 1);
18316
18276
  }
18317
- const rowOffsets = [];
18318
- let cumulativeY = cellSpacingPx;
18319
- for (let rowIndex = 0; rowIndex < table.rows.length; rowIndex += 1) {
18320
- rowOffsets[rowIndex] = cumulativeY;
18321
- cumulativeY += (rowHeights[rowIndex] ?? DEFAULT_TABLE_ROW_HEIGHT) + cellSpacingPx;
18322
- }
18277
+ return rowHeights;
18278
+ }
18279
+ const DEFAULT_TABLE_ROW_HEIGHT = 14;
18280
+ const MIN_TABLE_CELL_CONTENT_HEIGHT_PX = 1;
18281
+ function assembleCellEntries(options) {
18282
+ var _a, _b, _c;
18283
+ const {
18284
+ prepared,
18285
+ rowHeights,
18286
+ rowOffsets,
18287
+ columnOffsets,
18288
+ tableLeft,
18289
+ originY,
18290
+ cellSpacingPx,
18291
+ table
18292
+ } = options;
18323
18293
  const cells = [];
18324
18294
  for (const cellEntry of prepared) {
18325
18295
  const {
@@ -18383,21 +18353,137 @@ function buildCanvasTableLayout(options) {
18383
18353
  contentTop,
18384
18354
  contentWidth: contentWidthPx,
18385
18355
  contentHeight: contentHeightPx,
18386
- shading: (_H = cell.style) == null ? void 0 : _H.shading,
18356
+ shading: (_a = cell.style) == null ? void 0 : _a.shading,
18387
18357
  anchorPosition,
18388
18358
  padding,
18389
18359
  borders,
18390
18360
  paragraphs,
18391
18361
  verticalMode: cellEntry.verticalMode,
18392
- revision: ((_I = cell.style) == null ? void 0 : _I.revision) ?? (((_J = cell.style) == null ? void 0 : _J.propertyRevision) ? { ...cell.style.propertyRevision, type: "property" } : void 0)
18362
+ revision: ((_b = cell.style) == null ? void 0 : _b.revision) ?? (((_c = cell.style) == null ? void 0 : _c.propertyRevision) ? { ...cell.style.propertyRevision, type: "property" } : void 0)
18393
18363
  });
18394
18364
  }
18365
+ return cells;
18366
+ }
18367
+ function buildRowOffsets(rowHeights, cellSpacingPx) {
18368
+ const rowOffsets = [];
18369
+ let cumulativeY = cellSpacingPx;
18370
+ for (let rowIndex = 0; rowIndex < rowHeights.length; rowIndex += 1) {
18371
+ rowOffsets[rowIndex] = cumulativeY;
18372
+ cumulativeY += (rowHeights[rowIndex] ?? DEFAULT_TABLE_ROW_HEIGHT) + cellSpacingPx;
18373
+ }
18374
+ return rowOffsets;
18375
+ }
18376
+ function buildCanvasTableLayout(options) {
18377
+ var _a, _b, _c, _d, _e, _f, _g, _h;
18378
+ const {
18379
+ table: sourceTable,
18380
+ state,
18381
+ pageIndex,
18382
+ originX,
18383
+ originY,
18384
+ contentWidth,
18385
+ estimatedHeight
18386
+ } = options;
18387
+ const table = {
18388
+ ...sourceTable,
18389
+ style: resolveEffectiveTableStyle(sourceTable, state.document.styles)
18390
+ };
18391
+ const tableWidth = resolveCanvasTableWidth(table, contentWidth);
18392
+ const tableLeft = originX + resolveTableLeftOffset(table, tableWidth, contentWidth);
18393
+ const cellSpacingPx = resolveTableCellSpacingPx(table);
18394
+ const tableEntries = buildTableCellLayout(table);
18395
+ const visualColumnCount = Math.max(
18396
+ 1,
18397
+ ...tableEntries.map(
18398
+ (entry) => entry.visualColumnIndex + Math.max(1, entry.colSpan)
18399
+ )
18400
+ );
18401
+ const columnsWidthBudget = Math.max(
18402
+ visualColumnCount,
18403
+ tableWidth - (visualColumnCount + 1) * cellSpacingPx
18404
+ );
18405
+ let resolvedColumnWidths = [];
18406
+ if (table.gridCols && table.gridCols.length >= visualColumnCount) {
18407
+ const gridTotalWidth = table.gridCols.reduce((a, b) => a + b, 0);
18408
+ const scale = gridTotalWidth > 0 ? columnsWidthBudget / gridTotalWidth : 1;
18409
+ resolvedColumnWidths = table.gridCols.map((w) => w * scale);
18410
+ } else {
18411
+ const baseCellWidth = columnsWidthBudget / visualColumnCount;
18412
+ resolvedColumnWidths = Array(visualColumnCount).fill(baseCellWidth);
18413
+ for (const entry of tableEntries) {
18414
+ if (Math.max(1, entry.colSpan) !== 1) continue;
18415
+ const cell = (_a = table.rows[entry.rowIndex]) == null ? void 0 : _a.cells[entry.cellIndex];
18416
+ if (!cell) continue;
18417
+ const direction = ((_b = cell.style) == null ? void 0 : _b.textDirection) ?? ((_d = (_c = cell.blocks[0]) == null ? void 0 : _c.style) == null ? void 0 : _d.textDirection) ?? null;
18418
+ if (direction !== "tbRl" && direction !== "btLr" && direction !== "lrTbV" && direction !== "tbRlV")
18419
+ continue;
18420
+ let glyphWidth = 0;
18421
+ for (const block of cell.blocks) {
18422
+ if (block.type !== "paragraph") continue;
18423
+ glyphWidth = Math.max(
18424
+ glyphWidth,
18425
+ estimateStackedColumnWidth(block, state)
18426
+ );
18427
+ }
18428
+ if (glyphWidth <= 0) continue;
18429
+ const padding = resolveCellPadding(cell);
18430
+ const needed = glyphWidth + padding.left + padding.right + resolveBorder(((_e = cell.style) == null ? void 0 : _e.borderLeft) ?? ((_f = cell.style) == null ? void 0 : _f.borderStart)).width + resolveBorder(((_g = cell.style) == null ? void 0 : _g.borderRight) ?? ((_h = cell.style) == null ? void 0 : _h.borderEnd)).width;
18431
+ const col = entry.visualColumnIndex;
18432
+ if (needed > (resolvedColumnWidths[col] ?? 0)) {
18433
+ resolvedColumnWidths[col] = needed;
18434
+ }
18435
+ }
18436
+ }
18437
+ const columnOffsets = [cellSpacingPx];
18438
+ for (let i = 0; i < resolvedColumnWidths.length; i++) {
18439
+ columnOffsets[i + 1] = columnOffsets[i] + resolvedColumnWidths[i] + cellSpacingPx;
18440
+ }
18441
+ const effectiveRowStyles = table.rows.map((row, rowIndex) => {
18442
+ const entry = tableEntries.find(
18443
+ (candidate) => candidate.rowIndex === rowIndex
18444
+ );
18445
+ return entry ? resolveEffectiveTableCellFormatting({
18446
+ table: sourceTable,
18447
+ rowIndex,
18448
+ cellIndex: entry.cellIndex,
18449
+ visualColumnIndex: entry.visualColumnIndex,
18450
+ columnCount: visualColumnCount,
18451
+ styles: state.document.styles
18452
+ }).rowStyle : row.style;
18453
+ });
18454
+ const { prepared, unsupported } = prepareCells({
18455
+ table,
18456
+ sourceTable,
18457
+ tableEntries,
18458
+ columnOffsets,
18459
+ cellSpacingPx,
18460
+ visualColumnCount,
18461
+ effectiveRowStyles,
18462
+ state,
18463
+ pageIndex
18464
+ });
18465
+ const rowHeights = resolveRowHeights({
18466
+ prepared,
18467
+ table,
18468
+ effectiveRowStyles,
18469
+ estimatedHeight
18470
+ });
18471
+ const rowOffsets = buildRowOffsets(rowHeights, cellSpacingPx);
18472
+ const cells = assembleCellEntries({
18473
+ prepared,
18474
+ rowHeights,
18475
+ rowOffsets,
18476
+ columnOffsets,
18477
+ tableLeft,
18478
+ originY,
18479
+ cellSpacingPx,
18480
+ table
18481
+ });
18395
18482
  return {
18396
18483
  tableId: table.id,
18397
18484
  left: tableLeft,
18398
18485
  top: originY,
18399
18486
  width: tableWidth,
18400
- // Total height includes the leading/trailing/inter-row cell-spacing gaps.
18401
18487
  height: rowHeights.reduce((sum, current) => sum + current, 0) + (rowHeights.length + 1) * cellSpacingPx,
18402
18488
  rowHeights,
18403
18489
  cells,
@@ -18405,7 +18491,7 @@ function buildCanvasTableLayout(options) {
18405
18491
  };
18406
18492
  }
18407
18493
  var _tmpl$$y = /* @__PURE__ */ template(`<div class=oasis-editor-page-break style="display:flex;align-items:center;justify-content:center;margin:16px 0;position:relative;user-select:none"><div style="position:absolute;left:0;right:0;top:50%;border-top:1px dashed var(--oasis-toolbar-border, #e0e3e7)"></div><div style="background:var(--oasis-bg, #f6f8fb);padding:0 12px;color:var(--oasis-text-muted, #5f6368);font-size:12px;font-family:var(--oasis-font-ui, sans-serif);z-index:1">`);
18408
- function PageBreak(props) {
18494
+ function PageBreak(_props) {
18409
18495
  const t = useI18n();
18410
18496
  return (() => {
18411
18497
  var _el$ = _tmpl$$y(), _el$2 = _el$.firstChild, _el$3 = _el$2.nextSibling;
@@ -18413,45 +18499,6 @@ function PageBreak(props) {
18413
18499
  return _el$;
18414
18500
  })();
18415
18501
  }
18416
- const HEX6_PATTERN = /^[0-9a-fA-F]{6}$/;
18417
- function stripHashPrefix(color) {
18418
- return color.trim().replace(/^#/, "");
18419
- }
18420
- function normalizeHex6(color) {
18421
- if (!color) {
18422
- return null;
18423
- }
18424
- const body = stripHashPrefix(color);
18425
- return HEX6_PATTERN.test(body) ? body.toUpperCase() : null;
18426
- }
18427
- function parseHexColorToRgb255(color) {
18428
- if (!color) {
18429
- return null;
18430
- }
18431
- const normalized = stripHashPrefix(color);
18432
- if (!HEX6_PATTERN.test(normalized)) {
18433
- return null;
18434
- }
18435
- return [
18436
- Number.parseInt(normalized.slice(0, 2), 16),
18437
- Number.parseInt(normalized.slice(2, 4), 16),
18438
- Number.parseInt(normalized.slice(4, 6), 16)
18439
- ];
18440
- }
18441
- function rgb255ToHex(r, g2, b) {
18442
- const toHex2 = (value) => Math.max(0, Math.min(255, Math.round(value))).toString(16).padStart(2, "0");
18443
- return `#${toHex2(r)}${toHex2(g2)}${toHex2(b)}`;
18444
- }
18445
- const imageCache = /* @__PURE__ */ new Map();
18446
- function getCachedCanvasImage(src, onUpdate) {
18447
- const cached = imageCache.get(src);
18448
- if (cached) return cached;
18449
- const img = new Image();
18450
- img.src = src;
18451
- img.onload = onUpdate;
18452
- imageCache.set(src, img);
18453
- return img;
18454
- }
18455
18502
  const listLabelsCache = /* @__PURE__ */ new WeakMap();
18456
18503
  function resolveListPrefix(paragraph, document2) {
18457
18504
  let labels = listLabelsCache.get(document2);
@@ -19986,7 +20033,7 @@ function buildPresetPath(preset, x, y, width, height) {
19986
20033
  }
19987
20034
  return path;
19988
20035
  }
19989
- const DEG_TO_RAD = Math.PI / 180;
20036
+ const DEG_TO_RAD$1 = Math.PI / 180;
19990
20037
  const CANVAS_DASH_DASHED = [5, 3];
19991
20038
  const CANVAS_DASH_DOTTED = [1, 3];
19992
20039
  function drawEdge(ctx, border, x1, y1, x2, y2) {
@@ -20203,7 +20250,7 @@ function paintTextBox(ctx, textBox, state, x, y, width, height, pageIndex, onUpd
20203
20250
  if (rotation) {
20204
20251
  ctx.save();
20205
20252
  ctx.translate(x + width / 2, y + height / 2);
20206
- ctx.rotate(rotation * DEG_TO_RAD);
20253
+ ctx.rotate(rotation * DEG_TO_RAD$1);
20207
20254
  ctx.translate(-(x + width / 2), -(y + height / 2));
20208
20255
  }
20209
20256
  drawTextBoxShape(ctx, textBox, x, y, width, height);
@@ -20375,6 +20422,262 @@ function collectInlineTextBoxesFromLines(options) {
20375
20422
  }
20376
20423
  return inlineTextBoxes;
20377
20424
  }
20425
+ const imageCache = /* @__PURE__ */ new Map();
20426
+ function getCachedCanvasImage(src, onUpdate) {
20427
+ const cached = imageCache.get(src);
20428
+ if (cached) return cached;
20429
+ const img = new Image();
20430
+ img.src = src;
20431
+ img.onload = onUpdate;
20432
+ imageCache.set(src, img);
20433
+ return img;
20434
+ }
20435
+ function resolveFragmentPaintBounds(line, fragment) {
20436
+ const slotByOffset = new Map(
20437
+ line.slots.map((slot) => [slot.offset, slot])
20438
+ );
20439
+ const slots = fragment.chars.filter((char) => char.char !== "\n").map((char) => slotByOffset.get(char.paragraphOffset)).filter((slot) => Boolean(slot));
20440
+ if (slots.length === 0) return null;
20441
+ const first = slots[0];
20442
+ const last = slots[slots.length - 1];
20443
+ const nextSlot = slotByOffset.get(last.offset + 1);
20444
+ if (nextSlot) {
20445
+ return { left: first.left, right: nextSlot.left };
20446
+ }
20447
+ const lastSlotIndex = line.slots.findIndex(
20448
+ (slot) => slot.offset === last.offset
20449
+ );
20450
+ const followingSlot = lastSlotIndex >= 0 ? line.slots[lastSlotIndex + 1] : void 0;
20451
+ return {
20452
+ left: first.left,
20453
+ right: (followingSlot == null ? void 0 : followingSlot.left) ?? last.left + Math.max(8, line.height * 0.45)
20454
+ };
20455
+ }
20456
+ function drawFragmentColorRect(ctx, line, fragment, originX, originY, color, alpha) {
20457
+ const bounds = resolveFragmentPaintBounds(line, fragment);
20458
+ if (!bounds) return;
20459
+ ctx.save();
20460
+ if (alpha !== void 0) ctx.globalAlpha = alpha;
20461
+ ctx.fillStyle = color;
20462
+ ctx.fillRect(
20463
+ originX + bounds.left,
20464
+ originY + line.top + 2,
20465
+ Math.max(0, bounds.right - bounds.left),
20466
+ Math.max(2, line.height - 4)
20467
+ );
20468
+ ctx.restore();
20469
+ }
20470
+ function drawFragmentHighlight(ctx, line, fragment, originX, originY, color) {
20471
+ drawFragmentColorRect(ctx, line, fragment, originX, originY, color, 0.35);
20472
+ }
20473
+ function drawFragmentShading(ctx, line, fragment, originX, originY, color) {
20474
+ drawFragmentColorRect(ctx, line, fragment, originX, originY, color);
20475
+ }
20476
+ function drawFragmentBorder(ctx, line, fragment, originX, originY, border) {
20477
+ if (border.type === "none" || border.width <= 0) return;
20478
+ const bounds = resolveFragmentPaintBounds(line, fragment);
20479
+ if (!bounds) return;
20480
+ const edge = { ...border, width: Math.max(0.5, border.width * PX_PER_POINT) };
20481
+ drawBorderBox(
20482
+ ctx,
20483
+ originX + bounds.left,
20484
+ originY + line.top + 1,
20485
+ Math.max(0, bounds.right - bounds.left),
20486
+ Math.max(2, line.height - 2),
20487
+ { top: edge, right: edge, bottom: edge, left: edge }
20488
+ );
20489
+ }
20490
+ const HEX6_PATTERN = /^[0-9a-fA-F]{6}$/;
20491
+ function stripHashPrefix(color) {
20492
+ return color.trim().replace(/^#/, "");
20493
+ }
20494
+ function normalizeHex6(color) {
20495
+ if (!color) {
20496
+ return null;
20497
+ }
20498
+ const body = stripHashPrefix(color);
20499
+ return HEX6_PATTERN.test(body) ? body.toUpperCase() : null;
20500
+ }
20501
+ function parseHexColorToRgb255(color) {
20502
+ if (!color) {
20503
+ return null;
20504
+ }
20505
+ const normalized = stripHashPrefix(color);
20506
+ if (!HEX6_PATTERN.test(normalized)) {
20507
+ return null;
20508
+ }
20509
+ return [
20510
+ Number.parseInt(normalized.slice(0, 2), 16),
20511
+ Number.parseInt(normalized.slice(2, 4), 16),
20512
+ Number.parseInt(normalized.slice(4, 6), 16)
20513
+ ];
20514
+ }
20515
+ function rgb255ToHex(r, g2, b) {
20516
+ const toHex2 = (value) => Math.max(0, Math.min(255, Math.round(value))).toString(16).padStart(2, "0");
20517
+ return `#${toHex2(r)}${toHex2(g2)}${toHex2(b)}`;
20518
+ }
20519
+ const DEG_TO_RAD = Math.PI / 180;
20520
+ function resolveGradientAxis(boxX0, boxY0, boxX1, boxY1, angleDeg) {
20521
+ const cx = (boxX0 + boxX1) / 2;
20522
+ const cy = (boxY0 + boxY1) / 2;
20523
+ const rad = angleDeg * DEG_TO_RAD;
20524
+ const dx = Math.cos(rad) * (boxX1 - boxX0) / 2;
20525
+ const dy = Math.sin(rad) * (boxY1 - boxY0) / 2;
20526
+ return { x0: cx - dx, y0: cy - dy, x1: cx + dx, y1: cy + dy };
20527
+ }
20528
+ function hexToRgba(color, alpha) {
20529
+ const [r, g2, b] = parseHexColorToRgb255(color) ?? [0, 0, 0];
20530
+ return `rgba(${r},${g2},${b},${alpha})`;
20531
+ }
20532
+ function resolveCanvasTextFill(ctx, styles, line, fragment, originX, originY) {
20533
+ const fill = styles.textFill;
20534
+ if (!fill) return styles.color ?? "#000000";
20535
+ if (fill.type === "solid") return fill.color;
20536
+ if (fill.stops.length < 2) return styles.color ?? "#000000";
20537
+ const bounds = resolveFragmentPaintBounds(line, fragment);
20538
+ if (!bounds) return fill.stops[0].color;
20539
+ const x0 = originX + bounds.left;
20540
+ const x1 = originX + bounds.right;
20541
+ const y0 = originY + line.top;
20542
+ const y1 = originY + line.top + line.height;
20543
+ const axis = resolveGradientAxis(x0, y0, x1, y1, fill.angle ?? 0);
20544
+ const gradient = ctx.createLinearGradient(axis.x0, axis.y0, axis.x1, axis.y1);
20545
+ for (const stop of fill.stops) {
20546
+ gradient.addColorStop(
20547
+ stop.position,
20548
+ hexToRgba(stop.color, stop.alpha ?? 1)
20549
+ );
20550
+ }
20551
+ return gradient;
20552
+ }
20553
+ function drawScaledText(ctx, text, x, y, scale) {
20554
+ if (scale === 1) {
20555
+ ctx.fillText(text, x, y);
20556
+ return;
20557
+ }
20558
+ ctx.save();
20559
+ ctx.translate(x, y);
20560
+ ctx.scale(scale, 1);
20561
+ ctx.fillText(text, 0, 0);
20562
+ ctx.restore();
20563
+ }
20564
+ function drawStyledText(ctx, text, x, y, scale, styles) {
20565
+ const hasEffects = styles.outline || styles.shadow || styles.textShadow || styles.glow || styles.emboss || styles.imprint || styles.textOutline || styles.reflection;
20566
+ if (!hasEffects) {
20567
+ drawScaledText(ctx, text, x, y, scale);
20568
+ return;
20569
+ }
20570
+ if (styles.emboss || styles.imprint) {
20571
+ const offset = styles.imprint ? 1 : -1;
20572
+ ctx.save();
20573
+ ctx.shadowColor = "transparent";
20574
+ ctx.fillStyle = "rgba(255,255,255,0.75)";
20575
+ drawScaledText(ctx, text, x + offset, y + offset, scale);
20576
+ ctx.restore();
20577
+ }
20578
+ ctx.save();
20579
+ if (styles.textShadow) {
20580
+ const ts = styles.textShadow;
20581
+ const dirRad = ts.dirDeg * DEG_TO_RAD$1;
20582
+ const distPx = ts.distPt * PX_PER_POINT;
20583
+ ctx.shadowColor = hexToRgba(ts.color, ts.alpha ?? 1);
20584
+ ctx.shadowBlur = ts.blurPt * PX_PER_POINT;
20585
+ ctx.shadowOffsetX = Math.cos(dirRad) * distPx;
20586
+ ctx.shadowOffsetY = Math.sin(dirRad) * distPx;
20587
+ } else if (styles.glow) {
20588
+ const gl = styles.glow;
20589
+ ctx.shadowColor = hexToRgba(gl.color, gl.alpha ?? 0.7);
20590
+ ctx.shadowBlur = gl.radiusPt * PX_PER_POINT;
20591
+ ctx.shadowOffsetX = 0;
20592
+ ctx.shadowOffsetY = 0;
20593
+ } else if (styles.shadow) {
20594
+ ctx.shadowColor = "rgba(0,0,0,0.45)";
20595
+ ctx.shadowOffsetX = 1;
20596
+ ctx.shadowOffsetY = 1;
20597
+ ctx.shadowBlur = 1;
20598
+ }
20599
+ if (styles.textOutline) {
20600
+ ctx.strokeStyle = styles.textOutline.color ?? ctx.fillStyle;
20601
+ ctx.lineWidth = styles.textOutline.widthPt * PX_PER_POINT;
20602
+ drawScaledText(ctx, text, x, y, scale);
20603
+ if (scale === 1) {
20604
+ ctx.strokeText(text, x, y);
20605
+ } else {
20606
+ ctx.save();
20607
+ ctx.translate(x, y);
20608
+ ctx.scale(scale, 1);
20609
+ ctx.strokeText(text, 0, 0);
20610
+ ctx.restore();
20611
+ }
20612
+ } else if (styles.outline) {
20613
+ ctx.strokeStyle = ctx.fillStyle;
20614
+ ctx.lineWidth = 0.75;
20615
+ if (scale === 1) {
20616
+ ctx.strokeText(text, x, y);
20617
+ } else {
20618
+ ctx.translate(x, y);
20619
+ ctx.scale(scale, 1);
20620
+ ctx.strokeText(text, 0, 0);
20621
+ }
20622
+ } else {
20623
+ drawScaledText(ctx, text, x, y, scale);
20624
+ }
20625
+ ctx.restore();
20626
+ if (styles.reflection) {
20627
+ const ref = styles.reflection;
20628
+ const distPx = ref.distPt * PX_PER_POINT;
20629
+ const avgAlpha = Math.max(
20630
+ 0,
20631
+ Math.min(1, (ref.startAlpha + ref.endAlpha) / 2)
20632
+ );
20633
+ ctx.save();
20634
+ ctx.shadowColor = "transparent";
20635
+ ctx.globalAlpha = avgAlpha;
20636
+ if (ref.blurPt > 0 && "filter" in ctx) {
20637
+ ctx.filter = `blur(${ref.blurPt * PX_PER_POINT}px)`;
20638
+ }
20639
+ ctx.translate(0, 2 * y + distPx);
20640
+ ctx.scale(1, -1);
20641
+ drawScaledText(ctx, text, x, y, scale);
20642
+ ctx.restore();
20643
+ }
20644
+ }
20645
+ function drawFragmentReflection(ctx, fragment, slotByOffset, styles, originX, baselineY, reflection) {
20646
+ const firstChar = fragment.chars.find(
20647
+ (c) => c.char !== "\n" && c.char !== " "
20648
+ );
20649
+ if (!firstChar) return;
20650
+ const firstSlot = slotByOffset.get(firstChar.paragraphOffset);
20651
+ if (!firstSlot) return;
20652
+ const text = fragment.chars.filter((c) => c.char !== "\n" && c.char !== " ").map((c) => styles.allCaps ? c.char.toUpperCase() : c.char).join("");
20653
+ if (!text) return;
20654
+ const scale = styles.characterScale && styles.characterScale > 0 ? styles.characterScale / 100 : 1;
20655
+ const avgAlpha = (reflection.startAlpha + reflection.endAlpha) / 2;
20656
+ const distPx = reflection.distPt * PX_PER_POINT;
20657
+ const reflectY = baselineY + distPx;
20658
+ ctx.save();
20659
+ ctx.globalAlpha = (ctx.globalAlpha ?? 1) * avgAlpha;
20660
+ ctx.shadowColor = "transparent";
20661
+ ctx.shadowBlur = 0;
20662
+ ctx.shadowOffsetX = 0;
20663
+ ctx.shadowOffsetY = 0;
20664
+ ctx.translate(0, 2 * reflectY);
20665
+ ctx.scale(1, -1);
20666
+ const x = originX + firstSlot.left;
20667
+ if (scale === 1) {
20668
+ ctx.fillText(text, x, baselineY);
20669
+ } else {
20670
+ ctx.save();
20671
+ ctx.translate(x, baselineY);
20672
+ ctx.scale(scale, 1);
20673
+ ctx.fillText(text, 0, 0);
20674
+ ctx.restore();
20675
+ }
20676
+ ctx.restore();
20677
+ }
20678
+ function getRenderedChar(char, styles) {
20679
+ return styles.allCaps ? char.toUpperCase() : char;
20680
+ }
20378
20681
  function underlineStyleToCssDecorationStyle(underlineStyle) {
20379
20682
  switch (underlineStyle) {
20380
20683
  case "double":
@@ -20451,6 +20754,12 @@ function resolveOpenTypeFeatureTags(style2, fontSizePt) {
20451
20754
  }
20452
20755
  return Array.from(tags).sort();
20453
20756
  }
20757
+ const EMPHASIS_GLYPH = {
20758
+ dot: "•",
20759
+ comma: "‚",
20760
+ circle: "○",
20761
+ underDot: "•"
20762
+ };
20454
20763
  function underlineStyleDashArray(underlineStyle) {
20455
20764
  switch (underlineStyle) {
20456
20765
  case "dotted":
@@ -20474,75 +20783,100 @@ function underlineStyleDashArray(underlineStyle) {
20474
20783
  }
20475
20784
  const DOUBLE_STRIKE_OFFSET_PX = 1.3;
20476
20785
  const DOUBLE_UNDERLINE_OFFSET_PX = 1.5;
20477
- function hexToRgba(color, alpha) {
20478
- const [r, g2, b] = parseHexColorToRgb255(color) ?? [0, 0, 0];
20479
- return `rgba(${r},${g2},${b},${alpha})`;
20786
+ function resolveDecorationLineY(kind, lineTop, lineHeight) {
20787
+ if (kind === "underline") return lineTop + lineHeight - 2;
20788
+ if (kind === "doubleStrike") return lineTop + lineHeight * 0.5;
20789
+ return lineTop + lineHeight * 0.52;
20480
20790
  }
20481
- const canvasTextLogger = createEditorLogger("canvas-text");
20482
- const loggedCanvasFontKeys = /* @__PURE__ */ new Set();
20483
- const MAX_CANVAS_FONT_LOGS = 40;
20484
- function logCanvasFontUse(options) {
20485
- if (loggedCanvasFontKeys.size >= MAX_CANVAS_FONT_LOGS) {
20791
+ function drawTextDecoration(ctx, line, fragment, originX, originY, kind, underlineStyle, underlineColor) {
20792
+ const bounds = resolveFragmentPaintBounds(line, fragment);
20793
+ if (!bounds) return;
20794
+ const y = originY + resolveDecorationLineY(kind, line.top, line.height);
20795
+ const x1 = originX + bounds.left;
20796
+ const x2 = originX + bounds.right;
20797
+ ctx.save();
20798
+ ctx.strokeStyle = underlineColor || ctx.fillStyle;
20799
+ if (kind === "underline") {
20800
+ drawUnderlineWithStyle(ctx, x1, x2, y, underlineStyle);
20801
+ } else if (kind === "doubleStrike") {
20802
+ ctx.beginPath();
20803
+ ctx.lineWidth = 1;
20804
+ ctx.setLineDash([]);
20805
+ ctx.moveTo(x1, y - DOUBLE_STRIKE_OFFSET_PX);
20806
+ ctx.lineTo(x2, y - DOUBLE_STRIKE_OFFSET_PX);
20807
+ ctx.moveTo(x1, y + DOUBLE_STRIKE_OFFSET_PX);
20808
+ ctx.lineTo(x2, y + DOUBLE_STRIKE_OFFSET_PX);
20809
+ ctx.stroke();
20810
+ } else {
20811
+ ctx.beginPath();
20812
+ ctx.lineWidth = 1;
20813
+ ctx.setLineDash([]);
20814
+ ctx.moveTo(x1, y);
20815
+ ctx.lineTo(x2, y);
20816
+ ctx.stroke();
20817
+ }
20818
+ ctx.restore();
20819
+ }
20820
+ function drawUnderlineWithStyle(ctx, x1, x2, y, underlineStyle) {
20821
+ ctx.setLineDash([]);
20822
+ ctx.lineWidth = underlineStyleLineWidthPx(underlineStyle);
20823
+ if (isDoubleUnderlineStyle(underlineStyle)) {
20824
+ ctx.beginPath();
20825
+ ctx.moveTo(x1, y - DOUBLE_UNDERLINE_OFFSET_PX);
20826
+ ctx.lineTo(x2, y - DOUBLE_UNDERLINE_OFFSET_PX);
20827
+ ctx.moveTo(x1, y + DOUBLE_UNDERLINE_OFFSET_PX);
20828
+ ctx.lineTo(x2, y + DOUBLE_UNDERLINE_OFFSET_PX);
20829
+ ctx.stroke();
20486
20830
  return;
20487
20831
  }
20488
- const key = [
20489
- options.requestedFamily ?? "",
20490
- options.metricFamily,
20491
- options.fontSize,
20492
- options.bold,
20493
- options.italic
20494
- ].join("|");
20495
- if (loggedCanvasFontKeys.has(key)) {
20832
+ if (isWavyUnderlineStyle(underlineStyle)) {
20833
+ drawWavyLine(ctx, x1, x2, y);
20496
20834
  return;
20497
20835
  }
20498
- loggedCanvasFontKeys.add(key);
20499
- const style2 = options.italic ? "italic " : "";
20500
- const weight = options.bold ? "700" : "400";
20501
- const fontCheck = typeof document !== "undefined" && document.fonts ? document.fonts.check(
20502
- `${style2}${weight} ${options.fontSize}px "${options.metricFamily}"`
20503
- ) : "unavailable";
20504
- canvasTextLogger.info("font:use", {
20505
- ...options,
20506
- fontCheck,
20507
- documentFontsStatus: typeof document !== "undefined" && document.fonts ? document.fonts.status : "unavailable"
20508
- });
20509
- }
20510
- function resolveTabLeader(paragraph, line, tabLeft, state) {
20511
- var _a;
20512
- const paragraphStyle = resolveEffectiveParagraphStyle(
20513
- paragraph.style,
20514
- state.document.styles
20515
- );
20516
- const tabs = paragraphStyle.tabs ?? [];
20517
- if (tabs.length === 0) {
20518
- return void 0;
20836
+ const dashArray = underlineStyleDashArray(underlineStyle);
20837
+ if (dashArray) {
20838
+ ctx.setLineDash(dashArray);
20519
20839
  }
20520
- const lineStart = ((_a = line.slots[0]) == null ? void 0 : _a.left) ?? 0;
20521
- const relativeLeft = tabLeft - lineStart;
20522
- const stop = tabs.filter((tab) => tab.type !== "clear").map((tab) => ({ ...tab, positionPx: tab.position * PX_PER_POINT })).filter((tab) => tab.positionPx > relativeLeft + 0.01).sort((a, b) => a.positionPx - b.positionPx)[0];
20523
- return (stop == null ? void 0 : stop.leader) && stop.leader !== "none" ? stop.leader : void 0;
20840
+ ctx.beginPath();
20841
+ ctx.moveTo(x1, y);
20842
+ ctx.lineTo(x2, y);
20843
+ ctx.stroke();
20844
+ ctx.setLineDash([]);
20524
20845
  }
20525
- function drawTabLeader(ctx, leader, x1, x2, y) {
20526
- if (x2 <= x1 + 2) {
20527
- return;
20846
+ function drawWavyLine(ctx, x1, x2, y) {
20847
+ ctx.beginPath();
20848
+ ctx.moveTo(x1, y);
20849
+ for (let x = x1; x <= x2; x += 1) {
20850
+ const dy = Math.sin((x - x1) / WAVY_UNDERLINE_WAVELENGTH_PX * Math.PI) * WAVY_UNDERLINE_AMPLITUDE_PX;
20851
+ ctx.lineTo(x, y + dy);
20528
20852
  }
20853
+ ctx.stroke();
20854
+ }
20855
+ function drawFragmentEmphasis(ctx, line, fragment, slotByOffset, originX, originY, mark, color) {
20856
+ if (mark === "none") return;
20857
+ const glyph = EMPHASIS_GLYPH[mark];
20858
+ if (!glyph) return;
20859
+ const below = mark === "underDot";
20860
+ const y = below ? originY + line.top + line.height + 1 : originY + line.top + 2;
20529
20861
  ctx.save();
20530
- ctx.lineWidth = leader === "heavy" ? 1.5 : 1;
20531
- ctx.strokeStyle = ctx.fillStyle;
20532
- if (leader === "dot" || leader === "middleDot") {
20533
- ctx.setLineDash(CANVAS_DASH_DOTTED);
20534
- } else if (leader === "hyphen") {
20535
- ctx.setLineDash(CANVAS_DASH_DASHED);
20536
- } else {
20537
- ctx.setLineDash([]);
20862
+ ctx.fillStyle = color;
20863
+ ctx.textAlign = "center";
20864
+ ctx.textBaseline = below ? "top" : "bottom";
20865
+ ctx.font = `400 ${Math.max(6, line.height * 0.35)}px Calibri`;
20866
+ for (const char of fragment.chars) {
20867
+ if (char.char === "\n" || char.char === " " || char.char === " ") continue;
20868
+ const slot = slotByOffset.get(char.paragraphOffset);
20869
+ const nextSlot = slotByOffset.get(char.paragraphOffset + 1);
20870
+ if (!slot) continue;
20871
+ const centerX = nextSlot ? (slot.left + nextSlot.left) / 2 : slot.left + line.height * 0.25;
20872
+ ctx.fillText(glyph, originX + centerX, y);
20538
20873
  }
20539
- const leaderY = leader === "underscore" ? y + 2 : y;
20540
- ctx.beginPath();
20541
- ctx.moveTo(x1, leaderY);
20542
- ctx.lineTo(x2, leaderY);
20543
- ctx.stroke();
20544
20874
  ctx.restore();
20545
20875
  }
20876
+ function clamp01(value) {
20877
+ if (!Number.isFinite(value) || value < 0) return 0;
20878
+ return value > 1 ? 1 : value;
20879
+ }
20546
20880
  function drawImageFragment(ctx, img, image, x, y) {
20547
20881
  const { width, height, crop, fillMode, rotation, flipH, flipV } = image;
20548
20882
  const hasTransform = Boolean(rotation) || Boolean(flipH) || Boolean(flipV);
@@ -20555,9 +20889,7 @@ function drawImageFragment(ctx, img, image, x, y) {
20555
20889
  ctx.save();
20556
20890
  if (hasTransform) {
20557
20891
  ctx.translate(x + width / 2, y + height / 2);
20558
- if (rotation) {
20559
- ctx.rotate(rotation * DEG_TO_RAD);
20560
- }
20892
+ if (rotation) ctx.rotate(rotation * DEG_TO_RAD$1);
20561
20893
  ctx.scale(flipH ? -1 : 1, flipV ? -1 : 1);
20562
20894
  ctx.translate(-(x + width / 2), -(y + height / 2));
20563
20895
  }
@@ -20589,19 +20921,11 @@ function drawImageFragment(ctx, img, image, x, y) {
20589
20921
  }
20590
20922
  ctx.save();
20591
20923
  ctx.translate(x + width / 2, y + height / 2);
20592
- if (rotation) {
20593
- ctx.rotate(rotation * DEG_TO_RAD);
20594
- }
20924
+ if (rotation) ctx.rotate(rotation * DEG_TO_RAD$1);
20595
20925
  ctx.scale(flipH ? -1 : 1, flipV ? -1 : 1);
20596
20926
  ctx.drawImage(img, sx, sy, sw, sh, -width / 2, -height / 2, width, height);
20597
20927
  ctx.restore();
20598
20928
  }
20599
- function clamp01(value) {
20600
- if (!Number.isFinite(value) || value < 0) {
20601
- return 0;
20602
- }
20603
- return value > 1 ? 1 : value;
20604
- }
20605
20929
  function drawFloatingImagesForParagraph(options) {
20606
20930
  const {
20607
20931
  ctx,
@@ -20621,13 +20945,9 @@ function drawFloatingImagesForParagraph(options) {
20621
20945
  );
20622
20946
  for (const fragment of line.fragments) {
20623
20947
  const image = fragment.image;
20624
- if (!(image == null ? void 0 : image.floating)) {
20625
- continue;
20626
- }
20948
+ if (!(image == null ? void 0 : image.floating)) continue;
20627
20949
  const isBehind = Boolean(image.floating.behindDoc);
20628
- if (layer === "behind" !== isBehind) {
20629
- continue;
20630
- }
20950
+ if (layer === "behind" !== isBehind) continue;
20631
20951
  const slot = slotByOffset.get(fragment.startOffset);
20632
20952
  const anchorLeft = contentLeft + ((slot == null ? void 0 : slot.left) ?? 0);
20633
20953
  const lineTop = paragraphTop + line.top;
@@ -20649,453 +20969,62 @@ function drawFloatingImagesForParagraph(options) {
20649
20969
  }
20650
20970
  }
20651
20971
  }
20652
- function drawParagraph(ctx, paragraph, lines, state, originX, originY, onUpdate, painters, pageIndex = 0) {
20653
- var _a, _b, _c, _d;
20654
- for (const line of lines) {
20655
- const slotByOffset = /* @__PURE__ */ new Map();
20656
- for (const slot of line.slots) {
20657
- slotByOffset.set(slot.offset, slot);
20658
- }
20659
- const baselineY = originY + line.top + line.height * 0.8;
20660
- const listPrefix = line.index === 0 ? resolveListPrefix(paragraph, state.document) : "";
20661
- if (listPrefix) {
20662
- const prefixStyles = resolveEffectiveTextStyleForParagraph(
20663
- (_a = paragraph.runs[0]) == null ? void 0 : _a.styles,
20664
- (_b = paragraph.style) == null ? void 0 : _b.styleId,
20665
- state.document.styles
20666
- );
20667
- const { font: prefixFont, fillStyle: prefixFillStyle } = resolveCanvasRunPaintStyle(prefixStyles);
20668
- ctx.save();
20669
- ctx.font = prefixFont;
20670
- ctx.fillStyle = prefixFillStyle;
20671
- const first = line.slots[0];
20672
- const gap = ctx.measureText(`${listPrefix} `).width;
20673
- const labelInset = getListLabelInset(paragraph, state.document.styles);
20674
- const labelWidth = ctx.measureText(listPrefix).width;
20675
- const alignedLeft = getAlignedListLabelInset(
20676
- paragraph,
20677
- state.document.styles,
20678
- (first == null ? void 0 : first.left) ?? labelInset + labelWidth,
20679
- labelWidth
20680
- );
20681
- const left = first !== void 0 && labelInset + labelWidth > first.left ? Math.max(0, first.left - gap) : alignedLeft;
20682
- ctx.fillText(listPrefix, originX + left, baselineY);
20683
- ctx.restore();
20684
- }
20685
- for (const fragment of line.fragments) {
20686
- const styles = resolveEffectiveTextStyleForParagraph(
20687
- fragment.styles,
20688
- (_c = paragraph.style) == null ? void 0 : _c.styleId,
20689
- state.document.styles
20690
- );
20691
- if (styles.hidden) {
20692
- continue;
20693
- }
20694
- const fontSize = styles.fontSize ?? DEFAULT_FONT_SIZE_PX;
20695
- const metricFamily = resolveMetricCompatibleFamily(
20696
- styles.fontFamily ?? "Calibri"
20697
- );
20698
- const { font, renderMetrics } = resolveCanvasRunPaintStyle(styles);
20699
- ctx.save();
20700
- ctx.font = font;
20701
- applyCanvasTextFeatureHints(ctx, styles, fontSize);
20702
- logCanvasFontUse({
20703
- requestedFamily: styles.fontFamily,
20704
- metricFamily,
20705
- cssFont: ctx.font,
20706
- fontSize: renderMetrics.fontSize,
20707
- bold: Boolean(styles.bold),
20708
- italic: Boolean(styles.italic),
20709
- sample: fragment.text.slice(0, 80)
20710
- });
20711
- ctx.fillStyle = resolveCanvasTextFill(
20712
- ctx,
20713
- styles,
20714
- line,
20715
- fragment,
20716
- originX,
20717
- originY
20718
- );
20719
- if (styles.shading) {
20720
- drawFragmentShading(
20721
- ctx,
20722
- line,
20723
- fragment,
20724
- originX,
20725
- originY,
20726
- styles.shading
20727
- );
20728
- }
20729
- if (styles.highlight) {
20730
- drawFragmentHighlight(
20731
- ctx,
20732
- line,
20733
- fragment,
20734
- originX,
20735
- originY,
20736
- styles.highlight
20737
- );
20738
- }
20739
- if (styles.textBorder) {
20740
- drawFragmentBorder(
20741
- ctx,
20742
- line,
20743
- fragment,
20744
- originX,
20745
- originY,
20746
- styles.textBorder
20747
- );
20748
- }
20749
- if (fragment.image && !fragment.image.floating) {
20750
- const slot = slotByOffset.get(fragment.startOffset);
20751
- if (slot) {
20752
- const src = resolveImageSrc(state.document, fragment.image.src);
20753
- const img = getCachedCanvasImage(src, onUpdate);
20754
- if (img.complete && img.naturalWidth > 0) {
20755
- const rect = resolveInlineObjectRect({
20756
- originLeft: originX,
20757
- originTop: originY,
20758
- lineTop: line.top,
20759
- lineHeight: line.height,
20760
- slotLeft: slot.left,
20761
- objectWidth: fragment.image.width,
20762
- objectHeight: fragment.image.height
20763
- });
20764
- drawImageFragment(ctx, img, fragment.image, rect.left, rect.top);
20765
- }
20766
- }
20767
- } else if (fragment.textBox && !fragment.textBox.floating) {
20768
- const slot = slotByOffset.get(fragment.startOffset);
20769
- if (slot) {
20770
- const textBox = fragment.textBox;
20771
- const height = resolveTextBoxRenderHeight(textBox, state, pageIndex);
20772
- const rect = resolveInlineObjectRect({
20773
- originLeft: originX,
20774
- originTop: originY,
20775
- lineTop: line.top,
20776
- lineHeight: line.height,
20777
- slotLeft: slot.left,
20778
- objectWidth: textBox.width,
20779
- objectHeight: height
20780
- });
20781
- paintTextBox(
20782
- ctx,
20783
- textBox,
20784
- state,
20785
- rect.left,
20786
- rect.top,
20787
- rect.width,
20788
- rect.height,
20789
- pageIndex,
20790
- onUpdate,
20791
- painters
20792
- );
20793
- }
20794
- } else {
20795
- drawTextFragment(
20796
- ctx,
20797
- paragraph,
20798
- line,
20799
- fragment,
20800
- slotByOffset,
20801
- state,
20802
- styles,
20803
- originX,
20804
- baselineY + renderMetrics.baselineOffset
20805
- );
20806
- if (styles.reflection) {
20807
- drawFragmentReflection(
20808
- ctx,
20809
- fragment,
20810
- slotByOffset,
20811
- styles,
20812
- originX,
20813
- baselineY + renderMetrics.baselineOffset,
20814
- styles.reflection
20815
- );
20816
- }
20817
- }
20818
- if (styles.underline) {
20819
- drawTextDecoration(
20820
- ctx,
20821
- line,
20822
- fragment,
20823
- originX,
20824
- originY,
20825
- "underline",
20826
- styles.underlineStyle ?? void 0,
20827
- styles.underlineColor ?? void 0
20828
- );
20829
- }
20830
- if (styles.strike) {
20831
- drawTextDecoration(ctx, line, fragment, originX, originY, "strike");
20832
- }
20833
- if (styles.doubleStrike) {
20834
- drawTextDecoration(
20835
- ctx,
20836
- line,
20837
- fragment,
20838
- originX,
20839
- originY,
20840
- "doubleStrike"
20841
- );
20842
- }
20843
- if (styles.emphasisMark) {
20844
- drawFragmentEmphasis(
20845
- ctx,
20846
- line,
20847
- fragment,
20848
- slotByOffset,
20849
- originX,
20850
- originY,
20851
- styles.emphasisMark,
20852
- styles.color ?? "#000000"
20853
- );
20854
- }
20855
- ctx.restore();
20856
- }
20857
- if (line.trailingHyphen) {
20858
- const lastFragment = [...line.fragments].reverse().find(
20859
- (fragment) => fragment.text && !fragment.image && !fragment.textBox
20860
- );
20861
- const endSlot = slotByOffset.get(line.endOffset) ?? line.slots[line.slots.length - 1];
20862
- if (lastFragment && endSlot) {
20863
- const styles = resolveEffectiveTextStyleForParagraph(
20864
- lastFragment.styles,
20865
- (_d = paragraph.style) == null ? void 0 : _d.styleId,
20866
- state.document.styles
20867
- );
20868
- if (!styles.hidden) {
20869
- const { font, fillStyle, renderMetrics, scale } = resolveCanvasRunPaintStyle(styles);
20870
- ctx.save();
20871
- ctx.font = font;
20872
- ctx.fillStyle = fillStyle;
20873
- drawStyledText(
20874
- ctx,
20875
- "-",
20876
- originX + endSlot.left,
20877
- baselineY + renderMetrics.baselineOffset,
20878
- scale,
20879
- styles
20880
- );
20881
- ctx.restore();
20882
- }
20883
- }
20884
- }
20885
- const isLastLine = line.index === lines.length - 1;
20886
- if (state.showParagraphMarks && isLastLine) {
20887
- const lastSlot = line.slots[line.slots.length - 1];
20888
- const markSlot = line.slots.find((slot) => slot.offset === line.endOffset) ?? lastSlot;
20889
- if (markSlot) {
20890
- ctx.save();
20891
- ctx.font = "400 13px Calibri";
20892
- ctx.fillStyle = "#9ca3af";
20893
- const y = originY + line.top + line.height * 0.8;
20894
- ctx.fillText("¶", originX + markSlot.left + 2, y);
20895
- ctx.restore();
20896
- }
20897
- }
20898
- }
20899
- }
20900
- function drawFragmentColorRect(ctx, line, fragment, originX, originY, color, alpha) {
20901
- const bounds = resolveFragmentPaintBounds(line, fragment);
20902
- if (!bounds) return;
20903
- ctx.save();
20904
- if (alpha !== void 0) ctx.globalAlpha = alpha;
20905
- ctx.fillStyle = color;
20906
- ctx.fillRect(
20907
- originX + bounds.left,
20908
- originY + line.top + 2,
20909
- Math.max(0, bounds.right - bounds.left),
20910
- Math.max(2, line.height - 4)
20911
- );
20912
- ctx.restore();
20913
- }
20914
- function drawFragmentHighlight(ctx, line, fragment, originX, originY, color) {
20915
- drawFragmentColorRect(ctx, line, fragment, originX, originY, color, 0.35);
20916
- }
20917
- function resolveFragmentPaintBounds(line, fragment) {
20918
- const slotByOffset = new Map(
20919
- line.slots.map((slot) => [slot.offset, slot])
20920
- );
20921
- const slots = fragment.chars.filter((char) => char.char !== "\n").map((char) => slotByOffset.get(char.paragraphOffset)).filter((slot) => Boolean(slot));
20922
- if (slots.length === 0) return null;
20923
- const first = slots[0];
20924
- const last = slots[slots.length - 1];
20925
- const nextSlot = slotByOffset.get(last.offset + 1);
20926
- if (nextSlot) {
20927
- return { left: first.left, right: nextSlot.left };
20928
- }
20929
- const lastSlotIndex = line.slots.findIndex(
20930
- (slot) => slot.offset === last.offset
20972
+ function resolveTabLeader(paragraph, line, tabLeft, state) {
20973
+ var _a;
20974
+ const paragraphStyle = resolveEffectiveParagraphStyle(
20975
+ paragraph.style,
20976
+ state.document.styles
20931
20977
  );
20932
- const followingSlot = lastSlotIndex >= 0 ? line.slots[lastSlotIndex + 1] : void 0;
20933
- return {
20934
- left: first.left,
20935
- right: (followingSlot == null ? void 0 : followingSlot.left) ?? last.left + Math.max(8, line.height * 0.45)
20936
- };
20937
- }
20938
- function drawFragmentShading(ctx, line, fragment, originX, originY, color) {
20939
- drawFragmentColorRect(ctx, line, fragment, originX, originY, color);
20940
- }
20941
- function getRenderedChar(char, styles) {
20942
- return styles.allCaps ? char.toUpperCase() : char;
20943
- }
20944
- function drawScaledText(ctx, text, x, y, scale) {
20945
- if (scale === 1) {
20946
- ctx.fillText(text, x, y);
20947
- return;
20948
- }
20949
- ctx.save();
20950
- ctx.translate(x, y);
20951
- ctx.scale(scale, 1);
20952
- ctx.fillText(text, 0, 0);
20953
- ctx.restore();
20954
- }
20955
- function resolveCanvasTextFill(ctx, styles, line, fragment, originX, originY) {
20956
- const fill = styles.textFill;
20957
- if (!fill) return styles.color ?? "#000000";
20958
- if (fill.type === "solid") return fill.color;
20959
- if (fill.stops.length < 2) return styles.color ?? "#000000";
20960
- const bounds = resolveFragmentPaintBounds(line, fragment);
20961
- if (!bounds) return fill.stops[0].color;
20962
- const x0 = originX + bounds.left;
20963
- const x1 = originX + bounds.right;
20964
- const y0 = originY + line.top;
20965
- const y1 = originY + line.top + line.height;
20966
- const cx = (x0 + x1) / 2;
20967
- const cy = (y0 + y1) / 2;
20968
- const angleDeg = fill.angle ?? 0;
20969
- const rad = angleDeg * DEG_TO_RAD;
20970
- const dx = Math.cos(rad) * (x1 - x0) / 2;
20971
- const dy = Math.sin(rad) * (y1 - y0) / 2;
20972
- const gradient = ctx.createLinearGradient(cx - dx, cy - dy, cx + dx, cy + dy);
20973
- for (const stop of fill.stops) {
20974
- gradient.addColorStop(stop.position, hexToRgba(stop.color, stop.alpha ?? 1));
20975
- }
20976
- return gradient;
20978
+ const tabs = paragraphStyle.tabs ?? [];
20979
+ if (tabs.length === 0) return void 0;
20980
+ const lineStart = ((_a = line.slots[0]) == null ? void 0 : _a.left) ?? 0;
20981
+ const relativeLeft = tabLeft - lineStart;
20982
+ const stop = tabs.filter((tab) => tab.type !== "clear").map((tab) => ({ ...tab, positionPx: tab.position * PX_PER_POINT })).filter((tab) => tab.positionPx > relativeLeft + 0.01).sort((a, b) => a.positionPx - b.positionPx)[0];
20983
+ return (stop == null ? void 0 : stop.leader) && stop.leader !== "none" ? stop.leader : void 0;
20977
20984
  }
20978
- function drawStyledText(ctx, text, x, y, scale, styles) {
20979
- const hasEffects = styles.outline || styles.shadow || styles.textShadow || styles.glow || styles.emboss || styles.imprint || styles.textOutline || styles.reflection;
20980
- if (!hasEffects) {
20981
- drawScaledText(ctx, text, x, y, scale);
20982
- return;
20983
- }
20984
- if (styles.emboss || styles.imprint) {
20985
- const offset = styles.imprint ? 1 : -1;
20986
- ctx.save();
20987
- ctx.shadowColor = "transparent";
20988
- ctx.fillStyle = "rgba(255,255,255,0.75)";
20989
- drawScaledText(ctx, text, x + offset, y + offset, scale);
20990
- ctx.restore();
20991
- }
20985
+ function drawTabLeader(ctx, leader, x1, x2, y) {
20986
+ if (x2 <= x1 + 2) return;
20992
20987
  ctx.save();
20993
- if (styles.textShadow) {
20994
- const ts = styles.textShadow;
20995
- const dirRad = ts.dirDeg * DEG_TO_RAD;
20996
- const distPx = ts.distPt * PX_PER_POINT;
20997
- ctx.shadowColor = hexToRgba(ts.color, ts.alpha ?? 1);
20998
- ctx.shadowBlur = ts.blurPt * PX_PER_POINT;
20999
- ctx.shadowOffsetX = Math.cos(dirRad) * distPx;
21000
- ctx.shadowOffsetY = Math.sin(dirRad) * distPx;
21001
- } else if (styles.glow) {
21002
- const gl = styles.glow;
21003
- ctx.shadowColor = hexToRgba(gl.color, gl.alpha ?? 0.7);
21004
- ctx.shadowBlur = gl.radiusPt * PX_PER_POINT;
21005
- ctx.shadowOffsetX = 0;
21006
- ctx.shadowOffsetY = 0;
21007
- } else if (styles.shadow) {
21008
- ctx.shadowColor = "rgba(0,0,0,0.45)";
21009
- ctx.shadowOffsetX = 1;
21010
- ctx.shadowOffsetY = 1;
21011
- ctx.shadowBlur = 1;
21012
- }
21013
- if (styles.textOutline) {
21014
- ctx.strokeStyle = styles.textOutline.color ?? ctx.fillStyle;
21015
- ctx.lineWidth = styles.textOutline.widthPt * PX_PER_POINT;
21016
- drawScaledText(ctx, text, x, y, scale);
21017
- if (scale === 1) {
21018
- ctx.strokeText(text, x, y);
21019
- } else {
21020
- ctx.save();
21021
- ctx.translate(x, y);
21022
- ctx.scale(scale, 1);
21023
- ctx.strokeText(text, 0, 0);
21024
- ctx.restore();
21025
- }
21026
- } else if (styles.outline) {
21027
- ctx.strokeStyle = ctx.fillStyle;
21028
- ctx.lineWidth = 0.75;
21029
- if (scale === 1) {
21030
- ctx.strokeText(text, x, y);
21031
- } else {
21032
- ctx.translate(x, y);
21033
- ctx.scale(scale, 1);
21034
- ctx.strokeText(text, 0, 0);
21035
- }
20988
+ ctx.lineWidth = leader === "heavy" ? 1.5 : 1;
20989
+ ctx.strokeStyle = ctx.fillStyle;
20990
+ if (leader === "dot" || leader === "middleDot") {
20991
+ ctx.setLineDash(CANVAS_DASH_DOTTED);
20992
+ } else if (leader === "hyphen") {
20993
+ ctx.setLineDash(CANVAS_DASH_DASHED);
21036
20994
  } else {
21037
- drawScaledText(ctx, text, x, y, scale);
20995
+ ctx.setLineDash([]);
21038
20996
  }
20997
+ const leaderY = leader === "underscore" ? y + 2 : y;
20998
+ ctx.beginPath();
20999
+ ctx.moveTo(x1, leaderY);
21000
+ ctx.lineTo(x2, leaderY);
21001
+ ctx.stroke();
21039
21002
  ctx.restore();
21040
- if (styles.reflection) {
21041
- const ref = styles.reflection;
21042
- const distPx = ref.distPt * PX_PER_POINT;
21043
- const avgAlpha = Math.max(
21044
- 0,
21045
- Math.min(1, (ref.startAlpha + ref.endAlpha) / 2)
21046
- );
21047
- ctx.save();
21048
- ctx.shadowColor = "transparent";
21049
- ctx.globalAlpha = avgAlpha;
21050
- if (ref.blurPt > 0 && "filter" in ctx) {
21051
- ctx.filter = `blur(${ref.blurPt * PX_PER_POINT}px)`;
21052
- }
21053
- ctx.translate(0, 2 * y + distPx);
21054
- ctx.scale(1, -1);
21055
- drawScaledText(ctx, text, x, y, scale);
21056
- ctx.restore();
21057
- }
21058
- }
21059
- function drawFragmentBorder(ctx, line, fragment, originX, originY, border) {
21060
- if (border.type === "none" || border.width <= 0) return;
21061
- const bounds = resolveFragmentPaintBounds(line, fragment);
21062
- if (!bounds) return;
21063
- const edge = { ...border, width: Math.max(0.5, border.width * PX_PER_POINT) };
21064
- drawBorderBox(
21065
- ctx,
21066
- originX + bounds.left,
21067
- originY + line.top + 1,
21068
- Math.max(0, bounds.right - bounds.left),
21069
- Math.max(2, line.height - 2),
21070
- { top: edge, right: edge, bottom: edge, left: edge }
21071
- );
21072
21003
  }
21073
- const EMPHASIS_GLYPH = {
21074
- dot: "•",
21075
- comma: "‚",
21076
- circle: "○",
21077
- underDot: "•"
21078
- };
21079
- function drawFragmentEmphasis(ctx, line, fragment, slotByOffset, originX, originY, mark, color) {
21080
- if (mark === "none") return;
21081
- const glyph = EMPHASIS_GLYPH[mark];
21082
- if (!glyph) return;
21083
- const below = mark === "underDot";
21084
- const y = below ? originY + line.top + line.height + 1 : originY + line.top + 2;
21085
- ctx.save();
21086
- ctx.fillStyle = color;
21087
- ctx.textAlign = "center";
21088
- ctx.textBaseline = below ? "top" : "bottom";
21089
- ctx.font = `400 ${Math.max(6, line.height * 0.35)}px Calibri`;
21090
- for (const char of fragment.chars) {
21091
- if (char.char === "\n" || char.char === " " || char.char === " ") continue;
21092
- const slot = slotByOffset.get(char.paragraphOffset);
21093
- const nextSlot = slotByOffset.get(char.paragraphOffset + 1);
21094
- if (!slot) continue;
21095
- const centerX = nextSlot ? (slot.left + nextSlot.left) / 2 : slot.left + line.height * 0.25;
21096
- ctx.fillText(glyph, originX + centerX, y);
21097
- }
21098
- ctx.restore();
21004
+ const canvasTextLogger = createEditorLogger("canvas-text");
21005
+ const loggedCanvasFontKeys = /* @__PURE__ */ new Set();
21006
+ const MAX_CANVAS_FONT_LOGS = 40;
21007
+ function logCanvasFontUse(options) {
21008
+ if (loggedCanvasFontKeys.size >= MAX_CANVAS_FONT_LOGS) return;
21009
+ const key = [
21010
+ options.requestedFamily ?? "",
21011
+ options.metricFamily,
21012
+ options.fontSize,
21013
+ options.bold,
21014
+ options.italic
21015
+ ].join("|");
21016
+ if (loggedCanvasFontKeys.has(key)) return;
21017
+ loggedCanvasFontKeys.add(key);
21018
+ const style2 = options.italic ? "italic " : "";
21019
+ const weight = options.bold ? "700" : "400";
21020
+ const fontCheck = typeof document !== "undefined" && document.fonts ? document.fonts.check(
21021
+ `${style2}${weight} ${options.fontSize}px "${options.metricFamily}"`
21022
+ ) : "unavailable";
21023
+ canvasTextLogger.info("font:use", {
21024
+ ...options,
21025
+ fontCheck,
21026
+ documentFontsStatus: typeof document !== "undefined" && document.fonts ? document.fonts.status : "unavailable"
21027
+ });
21099
21028
  }
21100
21029
  function drawTextFragment(ctx, paragraph, line, fragment, slotByOffset, state, styles, originX, baselineY) {
21101
21030
  const scale = styles.characterScale && styles.characterScale > 0 ? styles.characterScale / 100 : 1;
@@ -21164,109 +21093,254 @@ function drawTextFragment(ctx, paragraph, line, fragment, slotByOffset, state, s
21164
21093
  flushSegment();
21165
21094
  continue;
21166
21095
  }
21167
- if (segmentLeft === null) {
21168
- segmentLeft = slot.left;
21169
- }
21096
+ if (segmentLeft === null) segmentLeft = slot.left;
21170
21097
  segmentText += renderedChar;
21171
21098
  }
21172
21099
  flushSegment();
21173
21100
  }
21174
- function drawFragmentReflection(ctx, fragment, slotByOffset, styles, originX, baselineY, reflection) {
21175
- const firstChar = fragment.chars.find(
21176
- (c) => c.char !== "\n" && c.char !== " "
21177
- );
21178
- if (!firstChar) return;
21179
- const firstSlot = slotByOffset.get(firstChar.paragraphOffset);
21180
- if (!firstSlot) return;
21181
- const text = fragment.chars.filter((c) => c.char !== "\n" && c.char !== " ").map((c) => styles.allCaps ? c.char.toUpperCase() : c.char).join("");
21182
- if (!text) return;
21183
- const scale = styles.characterScale && styles.characterScale > 0 ? styles.characterScale / 100 : 1;
21184
- const avgAlpha = (reflection.startAlpha + reflection.endAlpha) / 2;
21185
- const distPx = reflection.distPt * PX_PER_POINT;
21186
- const reflectY = baselineY + distPx;
21187
- ctx.save();
21188
- ctx.globalAlpha = (ctx.globalAlpha ?? 1) * avgAlpha;
21189
- ctx.shadowColor = "transparent";
21190
- ctx.shadowBlur = 0;
21191
- ctx.shadowOffsetX = 0;
21192
- ctx.shadowOffsetY = 0;
21193
- ctx.translate(0, 2 * reflectY);
21194
- ctx.scale(1, -1);
21195
- const x = originX + firstSlot.left;
21196
- if (scale === 1) {
21197
- ctx.fillText(text, x, baselineY);
21198
- } else {
21199
- ctx.save();
21200
- ctx.translate(x, baselineY);
21201
- ctx.scale(scale, 1);
21202
- ctx.fillText(text, 0, 0);
21203
- ctx.restore();
21204
- }
21205
- ctx.restore();
21206
- }
21207
- function drawTextDecoration(ctx, line, fragment, originX, originY, kind, underlineStyle, underlineColor) {
21208
- const bounds = resolveFragmentPaintBounds(line, fragment);
21209
- if (!bounds) return;
21210
- const y = kind === "underline" ? originY + line.top + line.height - 2 : kind === "doubleStrike" ? originY + line.top + line.height * 0.5 : originY + line.top + line.height * 0.52;
21211
- const x1 = originX + bounds.left;
21212
- const x2 = originX + bounds.right;
21213
- ctx.save();
21214
- ctx.strokeStyle = underlineColor || ctx.fillStyle;
21215
- if (kind === "underline") {
21216
- drawUnderlineWithStyle(ctx, x1, x2, y, underlineStyle);
21217
- } else if (kind === "doubleStrike") {
21218
- ctx.beginPath();
21219
- ctx.lineWidth = 1;
21220
- ctx.setLineDash([]);
21221
- ctx.moveTo(x1, y - DOUBLE_STRIKE_OFFSET_PX);
21222
- ctx.lineTo(x2, y - DOUBLE_STRIKE_OFFSET_PX);
21223
- ctx.moveTo(x1, y + DOUBLE_STRIKE_OFFSET_PX);
21224
- ctx.lineTo(x2, y + DOUBLE_STRIKE_OFFSET_PX);
21225
- ctx.stroke();
21226
- } else {
21227
- ctx.beginPath();
21228
- ctx.lineWidth = 1;
21229
- ctx.setLineDash([]);
21230
- ctx.moveTo(x1, y);
21231
- ctx.lineTo(x2, y);
21232
- ctx.stroke();
21233
- }
21234
- ctx.restore();
21235
- }
21236
- function drawUnderlineWithStyle(ctx, x1, x2, y, underlineStyle) {
21237
- ctx.setLineDash([]);
21238
- ctx.lineWidth = underlineStyleLineWidthPx(underlineStyle);
21239
- if (isDoubleUnderlineStyle(underlineStyle)) {
21240
- ctx.beginPath();
21241
- ctx.moveTo(x1, y - DOUBLE_UNDERLINE_OFFSET_PX);
21242
- ctx.lineTo(x2, y - DOUBLE_UNDERLINE_OFFSET_PX);
21243
- ctx.moveTo(x1, y + DOUBLE_UNDERLINE_OFFSET_PX);
21244
- ctx.lineTo(x2, y + DOUBLE_UNDERLINE_OFFSET_PX);
21245
- ctx.stroke();
21246
- return;
21247
- }
21248
- if (isWavyUnderlineStyle(underlineStyle)) {
21249
- drawWavyLine(ctx, x1, x2, y);
21250
- return;
21251
- }
21252
- const dashArray = underlineStyleDashArray(underlineStyle);
21253
- if (dashArray) {
21254
- ctx.setLineDash(dashArray);
21255
- }
21256
- ctx.beginPath();
21257
- ctx.moveTo(x1, y);
21258
- ctx.lineTo(x2, y);
21259
- ctx.stroke();
21260
- ctx.setLineDash([]);
21261
- }
21262
- function drawWavyLine(ctx, x1, x2, y) {
21263
- ctx.beginPath();
21264
- ctx.moveTo(x1, y);
21265
- for (let x = x1; x <= x2; x += 1) {
21266
- const dy = Math.sin((x - x1) / WAVY_UNDERLINE_WAVELENGTH_PX * Math.PI) * WAVY_UNDERLINE_AMPLITUDE_PX;
21267
- ctx.lineTo(x, y + dy);
21101
+ function drawParagraph(ctx, paragraph, lines, state, originX, originY, onUpdate, painters, pageIndex = 0) {
21102
+ var _a, _b, _c, _d;
21103
+ for (const line of lines) {
21104
+ const slotByOffset = /* @__PURE__ */ new Map();
21105
+ for (const slot of line.slots) {
21106
+ slotByOffset.set(slot.offset, slot);
21107
+ }
21108
+ const baselineY = originY + line.top + line.height * TEXT_BASELINE_RATIO;
21109
+ const listPrefix = line.index === 0 ? resolveListPrefix(paragraph, state.document) : "";
21110
+ if (listPrefix) {
21111
+ const prefixStyles = resolveEffectiveTextStyleForParagraph(
21112
+ (_a = paragraph.runs[0]) == null ? void 0 : _a.styles,
21113
+ (_b = paragraph.style) == null ? void 0 : _b.styleId,
21114
+ state.document.styles
21115
+ );
21116
+ const { font: prefixFont, fillStyle: prefixFillStyle } = resolveCanvasRunPaintStyle(prefixStyles);
21117
+ ctx.save();
21118
+ ctx.font = prefixFont;
21119
+ ctx.fillStyle = prefixFillStyle;
21120
+ const first = line.slots[0];
21121
+ const gap = ctx.measureText(`${listPrefix} `).width;
21122
+ const labelInset = getListLabelInset(paragraph, state.document.styles);
21123
+ const labelWidth = ctx.measureText(listPrefix).width;
21124
+ const alignedLeft = getAlignedListLabelInset(
21125
+ paragraph,
21126
+ state.document.styles,
21127
+ (first == null ? void 0 : first.left) ?? labelInset + labelWidth,
21128
+ labelWidth
21129
+ );
21130
+ const left = first !== void 0 && labelInset + labelWidth > first.left ? Math.max(0, first.left - gap) : alignedLeft;
21131
+ ctx.fillText(listPrefix, originX + left, baselineY);
21132
+ ctx.restore();
21133
+ }
21134
+ for (const fragment of line.fragments) {
21135
+ const styles = resolveEffectiveTextStyleForParagraph(
21136
+ fragment.styles,
21137
+ (_c = paragraph.style) == null ? void 0 : _c.styleId,
21138
+ state.document.styles
21139
+ );
21140
+ if (styles.hidden) continue;
21141
+ const fontSize = styles.fontSize ?? DEFAULT_FONT_SIZE_PX;
21142
+ const metricFamily = resolveMetricCompatibleFamily(
21143
+ styles.fontFamily ?? "Calibri"
21144
+ );
21145
+ const { font, renderMetrics } = resolveCanvasRunPaintStyle(styles);
21146
+ ctx.save();
21147
+ ctx.font = font;
21148
+ applyCanvasTextFeatureHints(ctx, styles, fontSize);
21149
+ logCanvasFontUse({
21150
+ requestedFamily: styles.fontFamily,
21151
+ metricFamily,
21152
+ cssFont: ctx.font,
21153
+ fontSize: renderMetrics.fontSize,
21154
+ bold: Boolean(styles.bold),
21155
+ italic: Boolean(styles.italic),
21156
+ sample: fragment.text.slice(0, 80)
21157
+ });
21158
+ ctx.fillStyle = resolveCanvasTextFill(
21159
+ ctx,
21160
+ styles,
21161
+ line,
21162
+ fragment,
21163
+ originX,
21164
+ originY
21165
+ );
21166
+ if (styles.shading) {
21167
+ drawFragmentShading(
21168
+ ctx,
21169
+ line,
21170
+ fragment,
21171
+ originX,
21172
+ originY,
21173
+ styles.shading
21174
+ );
21175
+ }
21176
+ if (styles.highlight) {
21177
+ drawFragmentHighlight(
21178
+ ctx,
21179
+ line,
21180
+ fragment,
21181
+ originX,
21182
+ originY,
21183
+ styles.highlight
21184
+ );
21185
+ }
21186
+ if (styles.textBorder) {
21187
+ drawFragmentBorder(
21188
+ ctx,
21189
+ line,
21190
+ fragment,
21191
+ originX,
21192
+ originY,
21193
+ styles.textBorder
21194
+ );
21195
+ }
21196
+ if (fragment.image && !fragment.image.floating) {
21197
+ const slot = slotByOffset.get(fragment.startOffset);
21198
+ if (slot) {
21199
+ const src = resolveImageSrc(state.document, fragment.image.src);
21200
+ const img = getCachedCanvasImage(src, onUpdate);
21201
+ if (img.complete && img.naturalWidth > 0) {
21202
+ const rect = resolveInlineObjectRect({
21203
+ originLeft: originX,
21204
+ originTop: originY,
21205
+ lineTop: line.top,
21206
+ lineHeight: line.height,
21207
+ slotLeft: slot.left,
21208
+ objectWidth: fragment.image.width,
21209
+ objectHeight: fragment.image.height
21210
+ });
21211
+ drawImageFragment(ctx, img, fragment.image, rect.left, rect.top);
21212
+ }
21213
+ }
21214
+ } else if (fragment.textBox && !fragment.textBox.floating) {
21215
+ const slot = slotByOffset.get(fragment.startOffset);
21216
+ if (slot) {
21217
+ const textBox = fragment.textBox;
21218
+ const height = resolveTextBoxRenderHeight(textBox, state, pageIndex);
21219
+ const rect = resolveInlineObjectRect({
21220
+ originLeft: originX,
21221
+ originTop: originY,
21222
+ lineTop: line.top,
21223
+ lineHeight: line.height,
21224
+ slotLeft: slot.left,
21225
+ objectWidth: textBox.width,
21226
+ objectHeight: height
21227
+ });
21228
+ paintTextBox(
21229
+ ctx,
21230
+ textBox,
21231
+ state,
21232
+ rect.left,
21233
+ rect.top,
21234
+ rect.width,
21235
+ rect.height,
21236
+ pageIndex,
21237
+ onUpdate,
21238
+ painters
21239
+ );
21240
+ }
21241
+ } else {
21242
+ drawTextFragment(
21243
+ ctx,
21244
+ paragraph,
21245
+ line,
21246
+ fragment,
21247
+ slotByOffset,
21248
+ state,
21249
+ styles,
21250
+ originX,
21251
+ baselineY + renderMetrics.baselineOffset
21252
+ );
21253
+ if (styles.reflection) {
21254
+ drawFragmentReflection(
21255
+ ctx,
21256
+ fragment,
21257
+ slotByOffset,
21258
+ styles,
21259
+ originX,
21260
+ baselineY + renderMetrics.baselineOffset,
21261
+ styles.reflection
21262
+ );
21263
+ }
21264
+ }
21265
+ if (styles.underline) {
21266
+ drawTextDecoration(
21267
+ ctx,
21268
+ line,
21269
+ fragment,
21270
+ originX,
21271
+ originY,
21272
+ "underline",
21273
+ styles.underlineStyle ?? void 0,
21274
+ styles.underlineColor ?? void 0
21275
+ );
21276
+ }
21277
+ if (styles.strike) {
21278
+ drawTextDecoration(ctx, line, fragment, originX, originY, "strike");
21279
+ }
21280
+ if (styles.doubleStrike) {
21281
+ drawTextDecoration(
21282
+ ctx,
21283
+ line,
21284
+ fragment,
21285
+ originX,
21286
+ originY,
21287
+ "doubleStrike"
21288
+ );
21289
+ }
21290
+ if (styles.emphasisMark) {
21291
+ drawFragmentEmphasis(
21292
+ ctx,
21293
+ line,
21294
+ fragment,
21295
+ slotByOffset,
21296
+ originX,
21297
+ originY,
21298
+ styles.emphasisMark,
21299
+ styles.color ?? "#000000"
21300
+ );
21301
+ }
21302
+ ctx.restore();
21303
+ }
21304
+ if (line.trailingHyphen) {
21305
+ const lastFragment = [...line.fragments].reverse().find((f) => f.text && !f.image && !f.textBox);
21306
+ const endSlot = slotByOffset.get(line.endOffset) ?? line.slots[line.slots.length - 1];
21307
+ if (lastFragment && endSlot) {
21308
+ const styles = resolveEffectiveTextStyleForParagraph(
21309
+ lastFragment.styles,
21310
+ (_d = paragraph.style) == null ? void 0 : _d.styleId,
21311
+ state.document.styles
21312
+ );
21313
+ if (!styles.hidden) {
21314
+ const { font, fillStyle, renderMetrics, scale } = resolveCanvasRunPaintStyle(styles);
21315
+ ctx.save();
21316
+ ctx.font = font;
21317
+ ctx.fillStyle = fillStyle;
21318
+ drawStyledText(
21319
+ ctx,
21320
+ "-",
21321
+ originX + endSlot.left,
21322
+ baselineY + renderMetrics.baselineOffset,
21323
+ scale,
21324
+ styles
21325
+ );
21326
+ ctx.restore();
21327
+ }
21328
+ }
21329
+ }
21330
+ const isLastLine = line.index === lines.length - 1;
21331
+ if (state.showParagraphMarks && isLastLine) {
21332
+ const lastSlot = line.slots[line.slots.length - 1];
21333
+ const markSlot = line.slots.find((slot) => slot.offset === line.endOffset) ?? lastSlot;
21334
+ if (markSlot) {
21335
+ ctx.save();
21336
+ ctx.font = "400 13px Calibri";
21337
+ ctx.fillStyle = "#9ca3af";
21338
+ const y = originY + line.top + line.height * TEXT_BASELINE_RATIO;
21339
+ ctx.fillText("¶", originX + markSlot.left + 2, y);
21340
+ ctx.restore();
21341
+ }
21342
+ }
21268
21343
  }
21269
- ctx.stroke();
21270
21344
  }
21271
21345
  const __vite_import_meta_env__ = { "DEV": false };
21272
21346
  function drawVerticalCell(ctx, cell, state, pageIndex, onUpdate, painters) {
@@ -21390,7 +21464,7 @@ function drawDropCapForParagraph(options) {
21390
21464
  }
21391
21465
  const style2 = dropCap.style;
21392
21466
  const { font, fillStyle, renderMetrics } = resolveCanvasRunPaintStyle(style2);
21393
- const bodyLineHeight = ((_a = lines[0]) == null ? void 0 : _a.height) ?? ((style2 == null ? void 0 : style2.fontSize) ?? DEFAULT_FONT_SIZE_PX);
21467
+ const bodyLineHeight = ((_a = lines[0]) == null ? void 0 : _a.height) ?? (style2 == null ? void 0 : style2.fontSize) ?? DEFAULT_FONT_SIZE_PX;
21394
21468
  const glyphWidth = measureDropCapWidth(dropCap);
21395
21469
  const x = dropCap.type === "margin" ? originX - glyphWidth : originX;
21396
21470
  const baselineY = paragraphTop + (dropCap.lines - 0.2) * bodyLineHeight + renderMetrics.baselineOffset;
@@ -23252,7 +23326,6 @@ const WRAP_OPTIONS = [{
23252
23326
  labelKey: "layoutOptions.front"
23253
23327
  }];
23254
23328
  function WrapIcon(props) {
23255
- useI18n();
23256
23329
  const line = (x, y, w) => (() => {
23257
23330
  var _el$ = _tmpl$$q();
23258
23331
  setAttribute(_el$, "x", x);
@@ -32301,14 +32374,14 @@ function twipsToPoints(value) {
32301
32374
  if (!Number.isFinite(parsed)) {
32302
32375
  return void 0;
32303
32376
  }
32304
- return Math.round(parsed / 20 * 1e4) / 1e4;
32377
+ return roundTo(parsed / 20, 4);
32305
32378
  }
32306
32379
  function halfPointsToPx(value) {
32307
32380
  const parsed = value ? Number(value) : Number.NaN;
32308
32381
  if (!Number.isFinite(parsed)) {
32309
32382
  return null;
32310
32383
  }
32311
- return Math.round(parsed / 2 / 72 * PX_PER_INCH * 1e4) / 1e4;
32384
+ return roundTo(parsed / 2 / 72 * PX_PER_INCH, 4);
32312
32385
  }
32313
32386
  function normalizeImportedFontFamily(value) {
32314
32387
  const family = value == null ? void 0 : value.trim();
@@ -32773,7 +32846,7 @@ function parseDocxBorder(borderNode) {
32773
32846
  return { width: 0, type: "none", color: "transparent" };
32774
32847
  }
32775
32848
  const size = Number(getAttributeValue(borderNode, "sz"));
32776
- const width = Number.isFinite(size) && size > 0 ? Math.round(size / 8 * 1e4) / 1e4 : 0.75;
32849
+ const width = Number.isFinite(size) && size > 0 ? roundTo(size / 8, 4) : 0.75;
32777
32850
  const color = normalizeImportedHexColor(getAttributeValue(borderNode, "color")) ?? "#000000";
32778
32851
  const normalizedValue = (value == null ? void 0 : value.toLowerCase()) ?? "single";
32779
32852
  const type = normalizedValue.includes("dotted") || normalizedValue.includes("dot") ? "dotted" : normalizedValue.includes("dash") ? "dashed" : "solid";
@@ -33505,7 +33578,7 @@ function parseParagraphStyle$1(paragraphProperties, colors) {
33505
33578
  }
33506
33579
  if (line) {
33507
33580
  if (lineRule === "exact" || lineRule === "atLeast") {
33508
- style2.lineHeight = Math.round(Number(line) / 1440 * 96 * 1e4) / 1e4;
33581
+ style2.lineHeight = roundTo(Number(line) / 1440 * 96, 4);
33509
33582
  style2.lineRule = lineRule;
33510
33583
  } else {
33511
33584
  style2.lineHeight = Number(line) / 240;
@@ -33638,7 +33711,7 @@ function parseDocxWidthValue(element) {
33638
33711
  return void 0;
33639
33712
  }
33640
33713
  const pct = raw.trim().endsWith("%") ? Number.parseFloat(raw) : Number(raw) / 50;
33641
- return Number.isFinite(pct) ? `${Math.round(pct * 1e4) / 1e4}%` : void 0;
33714
+ return Number.isFinite(pct) ? `${roundTo(pct, 4)}%` : void 0;
33642
33715
  }
33643
33716
  return twipsToPoints(raw);
33644
33717
  }
@@ -34022,7 +34095,7 @@ function parseTableCellStyle(cellProperties, tableDefaultMargins, colors) {
34022
34095
  } else if (cellWidthType === "pct" && cellWidthValue) {
34023
34096
  const pct = Number(cellWidthValue);
34024
34097
  if (Number.isFinite(pct)) {
34025
- style2.width = `${Math.round(pct / 50 * 1e4) / 1e4}%`;
34098
+ style2.width = `${roundTo(pct / 50, 4)}%`;
34026
34099
  }
34027
34100
  }
34028
34101
  const tcMar = parseCellMargins(
@@ -35080,7 +35153,7 @@ function parseTextBoxShape(wsp) {
35080
35153
  } else if (el.localName === "ln") {
35081
35154
  const width = parseOptionalInt$1(el.getAttribute("w"));
35082
35155
  if (width !== void 0) {
35083
- shape.borderWidthPt = Math.round(width / EMU_PER_PT * 100) / 100;
35156
+ shape.borderWidthPt = roundTo(width / EMU_PER_PT, 2);
35084
35157
  }
35085
35158
  const color = normalizeHexColor(
35086
35159
  (_b = findElementDeep(el, "srgbClr")) == null ? void 0 : _b.getAttribute("val")
@@ -36850,12 +36923,16 @@ async function importDocxToEditorDocument(buffer, options = {}) {
36850
36923
  const hasAssets = Object.keys(assets.assets).length > 0;
36851
36924
  const finalize = (doc2) => {
36852
36925
  const settingsPatch = {};
36853
- if (docSettings.defaultTabStop !== void 0) settingsPatch.defaultTabStop = docSettings.defaultTabStop;
36854
- if (docSettings.allowSpaceOfSameStyleInTable) settingsPatch.allowSpaceOfSameStyleInTable = true;
36926
+ if (docSettings.defaultTabStop !== void 0)
36927
+ settingsPatch.defaultTabStop = docSettings.defaultTabStop;
36928
+ if (docSettings.allowSpaceOfSameStyleInTable)
36929
+ settingsPatch.allowSpaceOfSameStyleInTable = true;
36855
36930
  if (docSettings.autoHyphenation) settingsPatch.autoHyphenation = true;
36856
36931
  if (docSettings.doNotHyphenateCaps) settingsPatch.doNotHyphenateCaps = true;
36857
- if (docSettings.consecutiveHyphenLimit !== void 0) settingsPatch.consecutiveHyphenLimit = docSettings.consecutiveHyphenLimit;
36858
- if (docSettings.hyphenationZone !== void 0) settingsPatch.hyphenationZone = docSettings.hyphenationZone;
36932
+ if (docSettings.consecutiveHyphenLimit !== void 0)
36933
+ settingsPatch.consecutiveHyphenLimit = docSettings.consecutiveHyphenLimit;
36934
+ if (docSettings.hyphenationZone !== void 0)
36935
+ settingsPatch.hyphenationZone = docSettings.hyphenationZone;
36859
36936
  if (Object.keys(settingsPatch).length > 0) {
36860
36937
  doc2.settings = { ...doc2.settings ?? {}, ...settingsPatch };
36861
36938
  }
@@ -37043,7 +37120,7 @@ function importDocxInWorker(buffer, options = {}) {
37043
37120
  const worker = new Worker(
37044
37121
  new URL(
37045
37122
  /* @vite-ignore */
37046
- "" + new URL("assets/importDocxWorker-D0F0jbcF.js", import.meta.url).href,
37123
+ "" + new URL("assets/importDocxWorker-nIS-zjkj.js", import.meta.url).href,
37047
37124
  import.meta.url
37048
37125
  ),
37049
37126
  {
@@ -37102,6 +37179,10 @@ const docxImporter = {
37102
37179
  });
37103
37180
  }
37104
37181
  };
37182
+ function isAllowedImageSrc(src) {
37183
+ const normalized = src.trim().toLowerCase();
37184
+ return normalized.startsWith("data:image/") || normalized.startsWith("blob:");
37185
+ }
37105
37186
  function parseInlineImage(element) {
37106
37187
  var _a, _b, _c;
37107
37188
  if (element.tagName !== "IMG") {
@@ -37109,7 +37190,7 @@ function parseInlineImage(element) {
37109
37190
  }
37110
37191
  const img = element;
37111
37192
  const src = ((_a = img.getAttribute("src")) == null ? void 0 : _a.trim()) ?? "";
37112
- if (!src) {
37193
+ if (!src || !isAllowedImageSrc(src)) {
37113
37194
  return void 0;
37114
37195
  }
37115
37196
  const widthAttr = ((_b = img.getAttribute("width")) == null ? void 0 : _b.trim()) ?? "";
@@ -38903,7 +38984,7 @@ function buildCanvasLayoutSnapshot(options) {
38903
38984
  };
38904
38985
  }
38905
38986
  function rounded(value) {
38906
- return Math.round(value * 100) / 100;
38987
+ return roundTo(value, 2);
38907
38988
  }
38908
38989
  function getCanvasPageRectSignature(surface) {
38909
38990
  const surfaceRect = surface.getBoundingClientRect();
@@ -40257,10 +40338,10 @@ function previousFontSizePt(currentPt) {
40257
40338
  return Math.max(1, Math.round(currentPt) - 1);
40258
40339
  }
40259
40340
  function fontSizePxToPt(px) {
40260
- return Math.round(pxToPt(px) * 100) / 100;
40341
+ return roundTo(pxToPt(px), 2);
40261
40342
  }
40262
40343
  function fontSizePtToPx(pt2) {
40263
- return Math.round(ptToPx(pt2) * 1e4) / 1e4;
40344
+ return roundTo(ptToPx(pt2), 4);
40264
40345
  }
40265
40346
  function formatFontSizePt(px) {
40266
40347
  const value = Number(px);
@@ -41150,7 +41231,7 @@ function cmToPx(cm) {
41150
41231
  return Math.round(cm * PX_PER_CM);
41151
41232
  }
41152
41233
  function pxToCm(px) {
41153
- return Math.round(px / PX_PER_CM * 100) / 100;
41234
+ return roundTo(px / PX_PER_CM, 2);
41154
41235
  }
41155
41236
  const MARGIN_PRESETS = [
41156
41237
  {
@@ -42672,249 +42753,258 @@ const OASIS_MENU_ITEMS = {
42672
42753
  formatListsNumbered: "format_lists_numbered"
42673
42754
  };
42674
42755
  export {
42675
- isParagraphTag as $,
42756
+ resolveImageSrc as $,
42676
42757
  getParagraphLength as A,
42677
42758
  getParagraphText as B,
42678
42759
  getActiveZone as C,
42679
42760
  getActiveSectionIndex as D,
42680
- getParagraphs as E,
42681
- normalizeSelection as F,
42682
- positionToParagraphOffset as G,
42683
- paragraphOffsetToPosition as H,
42684
- clampPosition as I,
42685
- findParagraphIndex as J,
42686
- createCollapsedSelection as K,
42687
- isSelectionCollapsed as L,
42761
+ EMPTY_PROJECTION_CONTEXT as E,
42762
+ getParagraphs as F,
42763
+ normalizeSelection as G,
42764
+ positionToParagraphOffset as H,
42765
+ paragraphOffsetToPosition as I,
42766
+ clampPosition as J,
42767
+ findParagraphIndex as K,
42768
+ createCollapsedSelection as L,
42688
42769
  MAX_FOOTNOTE_LAYOUT_ITERATIONS as M,
42689
- parseFontSizePtToPx as N,
42690
- formatFontSizePt as O,
42691
- createEditorParagraph as P,
42692
- getBlockParagraphs as Q,
42693
- findParagraphTableLocation as R,
42770
+ isSelectionCollapsed as N,
42771
+ parseFontSizePtToPx as O,
42772
+ formatFontSizePt as P,
42773
+ createEditorParagraph as Q,
42774
+ getBlockParagraphs as R,
42694
42775
  STANDARD_FONT_SIZES_PT as S,
42695
- buildTableCellLayout as T,
42696
- PT_PER_PX as U,
42697
- createEditorTableCell as V,
42698
- createEditorTableRow as W,
42699
- createEditorTable as X,
42700
- underlineStyleToCssDecorationStyle as Y,
42701
- resolveImageSrc as Z,
42702
- listKindForTag as _,
42776
+ findParagraphTableLocation as T,
42777
+ buildTableCellLayout as U,
42778
+ PT_PER_PX as V,
42779
+ createEditorTableCell as W,
42780
+ createEditorTableRow as X,
42781
+ createEditorTable as Y,
42782
+ PX_PER_POINT as Z,
42783
+ underlineStyleToCssDecorationStyle as _,
42703
42784
  getPageContentWidth as a,
42704
- resolveFloatingObjectRect as a$,
42705
- collectInlineRuns as a0,
42706
- parseParagraphStyle as a1,
42707
- getRunImage as a2,
42708
- InlineShell as a3,
42709
- BalloonShell as a4,
42710
- DocumentShell as a5,
42711
- createMemo as a6,
42712
- getCaretRectFromSnapshot as a7,
42713
- getParagraphRectFromSnapshot as a8,
42714
- createComponent as a9,
42715
- setPreciseFontPreference as aA,
42716
- setWelcomeSeen as aB,
42717
- enablePreciseFontMode as aC,
42718
- TWIPS_PER_POINT as aD,
42719
- PX_PER_INCH as aE,
42720
- TWIPS_PER_INCH as aF,
42721
- normalizeHex6 as aG,
42722
- TABLE_CONDITIONAL_FLAG_ATTRIBUTES as aH,
42723
- TABLE_BORDER_EDGE_KEYS as aI,
42724
- resolveEffectiveParagraphStyle as aJ,
42725
- resolveEffectiveTextStyleForParagraph as aK,
42726
- EMU_PER_PT as aL,
42727
- OOXML_ROTATION_UNITS as aM,
42728
- OOXML_PERCENT_DENOMINATOR as aN,
42729
- parseHexColorToRgb255 as aO,
42730
- EMU_PER_PX as aP,
42731
- getRunFootnoteReference as aQ,
42732
- getRunEndnoteReference as aR,
42733
- iterateFootnoteReferenceRuns as aS,
42734
- iterateEndnoteReferenceRuns as aT,
42735
- imageContentTypeDefaults as aU,
42736
- getRunFieldChar as aV,
42737
- getRunFieldInstruction as aW,
42738
- createEditorRun as aX,
42739
- JSZip as aY,
42740
- imageExtensionFromMime as aZ,
42741
- pxToPt as a_,
42742
- CaretOverlay as aa,
42743
- Show as ab,
42744
- createRenderEffect as ac,
42745
- style as ad,
42746
- setAttribute as ae,
42747
- setStyleProperty as af,
42748
- memo as ag,
42749
- template as ah,
42750
- addEventListener as ai,
42751
- insert as aj,
42752
- delegateEvents as ak,
42753
- useI18n as al,
42754
- createEffect as am,
42755
- use as an,
42756
- Dialog as ao,
42757
- className as ap,
42758
- For as aq,
42759
- UNDERLINE_STYLE_OPTIONS as ar,
42760
- Tabs as as,
42761
- createStore as at,
42762
- reconcile as au,
42763
- onMount as av,
42764
- onCleanup as aw,
42765
- PluginUiHost as ax,
42766
- OasisEditorEditor as ay,
42767
- OasisBrandMark as az,
42785
+ imageExtensionFromMime as a$,
42786
+ listKindForTag as a0,
42787
+ isParagraphTag as a1,
42788
+ collectInlineRuns as a2,
42789
+ parseParagraphStyle as a3,
42790
+ getRunImage as a4,
42791
+ InlineShell as a5,
42792
+ BalloonShell as a6,
42793
+ DocumentShell as a7,
42794
+ createMemo as a8,
42795
+ getCaretRectFromSnapshot as a9,
42796
+ OasisEditorEditor as aA,
42797
+ OasisBrandMark as aB,
42798
+ setPreciseFontPreference as aC,
42799
+ setWelcomeSeen as aD,
42800
+ enablePreciseFontMode as aE,
42801
+ TWIPS_PER_POINT as aF,
42802
+ PX_PER_INCH as aG,
42803
+ TWIPS_PER_INCH as aH,
42804
+ normalizeHex6 as aI,
42805
+ TABLE_CONDITIONAL_FLAG_ATTRIBUTES as aJ,
42806
+ TABLE_BORDER_EDGE_KEYS as aK,
42807
+ resolveEffectiveParagraphStyle as aL,
42808
+ resolveEffectiveTextStyleForParagraph as aM,
42809
+ EMU_PER_PT as aN,
42810
+ OOXML_ROTATION_UNITS as aO,
42811
+ OOXML_PERCENT_DENOMINATOR as aP,
42812
+ parseHexColorToRgb255 as aQ,
42813
+ EMU_PER_PX as aR,
42814
+ getRunFootnoteReference as aS,
42815
+ getRunEndnoteReference as aT,
42816
+ iterateFootnoteReferenceRuns as aU,
42817
+ iterateEndnoteReferenceRuns as aV,
42818
+ imageContentTypeDefaults as aW,
42819
+ getRunFieldChar as aX,
42820
+ getRunFieldInstruction as aY,
42821
+ createEditorRun as aZ,
42822
+ JSZip as a_,
42823
+ getParagraphRectFromSnapshot as aa,
42824
+ createComponent as ab,
42825
+ CaretOverlay as ac,
42826
+ Show as ad,
42827
+ createRenderEffect as ae,
42828
+ style as af,
42829
+ setAttribute as ag,
42830
+ setStyleProperty as ah,
42831
+ memo as ai,
42832
+ template as aj,
42833
+ addEventListener as ak,
42834
+ insert as al,
42835
+ delegateEvents as am,
42836
+ useI18n as an,
42837
+ createEffect as ao,
42838
+ use as ap,
42839
+ Dialog as aq,
42840
+ className as ar,
42841
+ For as as,
42842
+ UNDERLINE_STYLE_OPTIONS as at,
42843
+ Tabs as au,
42844
+ createStore as av,
42845
+ reconcile as aw,
42846
+ onMount as ax,
42847
+ onCleanup as ay,
42848
+ PluginUiHost as az,
42768
42849
  getPageBodyTop as b,
42769
- markEnd as b$,
42770
- getTextBoxFloatingGeometry as b0,
42771
- getPresetPathSegments as b1,
42772
- buildListLabels as b2,
42773
- getImageFloatingGeometry as b3,
42774
- textStyleToFontSizePt as b4,
42775
- PX_PER_POINT as b5,
42776
- DEFAULT_FONT_SIZE_PX as b6,
42777
- resolveOpenTypeFeatureTags as b7,
42778
- rgb255ToHex as b8,
42779
- isDoubleUnderlineStyle as b9,
42780
- FOOTNOTE_MARKER_GUTTER_PX as bA,
42781
- resolveImporterForFile as bB,
42782
- getDocumentSectionsCanonical as bC,
42783
- getDocumentParagraphsCanonical as bD,
42784
- getDocumentParagraphs as bE,
42785
- getDocumentPageSettings as bF,
42786
- getTableCellContentWidthForParagraph as bG,
42787
- layoutMetricsEpoch as bH,
42788
- bumpLayoutMetricsEpoch as bI,
42789
- createCanvasLayoutSnapshotProvider as bJ,
42790
- on as bK,
42791
- debounce as bL,
42792
- unwrap as bM,
42793
- perfTimer as bN,
42794
- getRunTextBox as bO,
42795
- createEditorDocument as bP,
42796
- resolveResizedDimensions as bQ,
42797
- resolveTextBoxRenderHeight as bR,
42798
- getToolbarStyleState as bS,
42799
- getCachedCanvasImage as bT,
42800
- measureParagraphMinContentWidthPx as bU,
42801
- getEditableBlocksForZone as bV,
42802
- findParagraphLocation as bW,
42803
- createSectionBoundaryParagraph as bX,
42804
- normalizePageSettings as bY,
42805
- DEFAULT_EDITOR_PAGE_SETTINGS as bZ,
42806
- markStart as b_,
42807
- isWavyUnderlineStyle as ba,
42808
- underlineStyleLineWidthPx as bb,
42809
- WAVY_UNDERLINE_WAVELENGTH_PX as bc,
42810
- WAVY_UNDERLINE_AMPLITUDE_PX as bd,
42811
- underlineStyleDashArray as be,
42812
- resolveListLabel as bf,
42813
- getListLabelInset as bg,
42814
- getAlignedListLabelInset as bh,
42815
- getParagraphBorderInsets as bi,
42816
- buildSegmentTable as bj,
42817
- buildCanvasTableLayout as bk,
42818
- resolveCanvasTableWidth as bl,
42819
- resolveFloatingTableRect as bm,
42820
- normalizeFamily as bn,
42821
- ROBOTO_FONT_FILES as bo,
42822
- loadFontAsset as bp,
42823
- OFFICE_COMPAT_FONT_FAMILIES as bq,
42824
- BinaryReader as br,
42825
- buildSfnt as bs,
42826
- defaultFontDecoderRegistry as bt,
42827
- SfntFontProgram as bu,
42828
- collectPdfFontFamilies as bv,
42829
- outlineFrom as bw,
42830
- getPageHeaderZoneTop as bx,
42831
- getPageColumnRects as by,
42832
- findFootnoteReference as bz,
42850
+ VERTICAL_HIT_WEIGHT as b$,
42851
+ pxToPt as b0,
42852
+ resolveFloatingObjectRect as b1,
42853
+ getTextBoxFloatingGeometry as b2,
42854
+ getPresetPathSegments as b3,
42855
+ buildListLabels as b4,
42856
+ DEFAULT_FONT_SIZE_PX as b5,
42857
+ resolveGradientAxis as b6,
42858
+ isDoubleUnderlineStyle as b7,
42859
+ isWavyUnderlineStyle as b8,
42860
+ underlineStyleLineWidthPx as b9,
42861
+ defaultFontDecoderRegistry as bA,
42862
+ SfntFontProgram as bB,
42863
+ collectPdfFontFamilies as bC,
42864
+ outlineFrom as bD,
42865
+ getPageHeaderZoneTop as bE,
42866
+ getPageColumnRects as bF,
42867
+ findFootnoteReference as bG,
42868
+ FOOTNOTE_MARKER_GUTTER_PX as bH,
42869
+ resolveImporterForFile as bI,
42870
+ roundTo as bJ,
42871
+ getDocumentSectionsCanonical as bK,
42872
+ getDocumentParagraphsCanonical as bL,
42873
+ getDocumentParagraphs as bM,
42874
+ getDocumentPageSettings as bN,
42875
+ getTableCellContentWidthForParagraph as bO,
42876
+ layoutMetricsEpoch as bP,
42877
+ bumpLayoutMetricsEpoch as bQ,
42878
+ createCanvasLayoutSnapshotProvider as bR,
42879
+ on as bS,
42880
+ debounce as bT,
42881
+ unwrap as bU,
42882
+ perfTimer as bV,
42883
+ getRunTextBox as bW,
42884
+ createEditorDocument as bX,
42885
+ resolveResizedDimensions as bY,
42886
+ resolveTextBoxRenderHeight as bZ,
42887
+ getToolbarStyleState as b_,
42888
+ WAVY_UNDERLINE_WAVELENGTH_PX as ba,
42889
+ WAVY_UNDERLINE_AMPLITUDE_PX as bb,
42890
+ DOUBLE_UNDERLINE_OFFSET_PX as bc,
42891
+ underlineStyleDashArray as bd,
42892
+ EMPHASIS_GLYPH as be,
42893
+ rgb255ToHex as bf,
42894
+ getImageFloatingGeometry as bg,
42895
+ textStyleToFontSizePt as bh,
42896
+ TEXT_BASELINE_RATIO as bi,
42897
+ resolveOpenTypeFeatureTags as bj,
42898
+ resolveDecorationLineY as bk,
42899
+ DOUBLE_STRIKE_OFFSET_PX as bl,
42900
+ resolveListLabel as bm,
42901
+ getListLabelInset as bn,
42902
+ getAlignedListLabelInset as bo,
42903
+ getParagraphBorderInsets as bp,
42904
+ buildSegmentTable as bq,
42905
+ buildCanvasTableLayout as br,
42906
+ resolveCanvasTableWidth as bs,
42907
+ resolveFloatingTableRect as bt,
42908
+ normalizeFamily as bu,
42909
+ ROBOTO_FONT_FILES as bv,
42910
+ loadFontAsset as bw,
42911
+ OFFICE_COMPAT_FONT_FAMILIES as bx,
42912
+ BinaryReader as by,
42913
+ buildSfnt as bz,
42833
42914
  getPageBodyBottom as c,
42834
- createEditorCommandBus as c$,
42835
- getParagraphEntries as c0,
42836
- getParagraphById as c1,
42837
- createEditorFootnote as c2,
42838
- createFootnoteReferenceRun as c3,
42839
- renumberFootnotes as c4,
42840
- getHeadingLevel as c5,
42841
- preciseFontModeVersion as c6,
42842
- isPreciseFontModeEnabled as c7,
42843
- resolveNamedTextStyle as c8,
42844
- togglePreciseFontMode as c9,
42845
- CommandRegistry as cA,
42846
- DEFAULT_PALETTE as cB,
42847
- DialogFooter as cC,
42848
- FloatingActionButton as cD,
42849
- GridPicker as cE,
42850
- IconButton as cF,
42851
- Menu as cG,
42852
- OASIS_BUILTIN_COMMANDS as cH,
42853
- OASIS_MENU_ITEMS as cI,
42854
- OASIS_TOOLBAR_ITEMS as cJ,
42855
- OasisEditorAppLazy as cK,
42856
- OasisEditorContainer as cL,
42857
- PluginCollection as cM,
42858
- Popover as cN,
42859
- RIBBON_TABS as cO,
42860
- Select as cP,
42861
- SelectField as cQ,
42862
- Separator as cR,
42863
- SidePanel as cS,
42864
- SidePanelBody as cT,
42865
- SidePanelFooter as cU,
42866
- SidePanelHeader as cV,
42867
- SplitButton as cW,
42868
- StyleGallery as cX,
42869
- TextField as cY,
42870
- Button$1 as cZ,
42871
- buildRibbonTabDefinitions as c_,
42872
- nextFontSizePt as ca,
42873
- previousFontSizePt as cb,
42874
- fontSizePtToPx as cc,
42875
- createDefaultToolbarPreset as cd,
42876
- MenuRegistry as ce,
42877
- createToolbarRegistry as cf,
42878
- Editor as cg,
42879
- resolveCommandRef as ch,
42880
- commandRefName as ci,
42881
- createOasisEditorClient as cj,
42882
- createEditorZoom as ck,
42883
- startLongTaskObserver as cl,
42884
- installGlobalReport as cm,
42885
- applyStoredPreciseFontPreference as cn,
42886
- getWelcomeSeen as co,
42887
- isLocalFontAccessSupported as cp,
42888
- EDITOR_SCROLL_PADDING_PX as cq,
42889
- Toolbar as cr,
42890
- OasisEditorLoading as cs,
42891
- I18nProvider as ct,
42892
- createTranslator as cu,
42893
- createEditorLogger as cv,
42894
- registerDomStatsSurface as cw,
42895
- Button as cx,
42896
- Checkbox as cy,
42897
- ColorPicker as cz,
42915
+ SidePanel as c$,
42916
+ getCachedCanvasImage as c0,
42917
+ measureParagraphMinContentWidthPx as c1,
42918
+ getEditableBlocksForZone as c2,
42919
+ findParagraphLocation as c3,
42920
+ createSectionBoundaryParagraph as c4,
42921
+ normalizePageSettings as c5,
42922
+ DEFAULT_EDITOR_PAGE_SETTINGS as c6,
42923
+ markStart as c7,
42924
+ markEnd as c8,
42925
+ getParagraphEntries as c9,
42926
+ Toolbar as cA,
42927
+ OasisEditorLoading as cB,
42928
+ I18nProvider as cC,
42929
+ createTranslator as cD,
42930
+ createEditorLogger as cE,
42931
+ registerDomStatsSurface as cF,
42932
+ Button as cG,
42933
+ Checkbox as cH,
42934
+ ColorPicker as cI,
42935
+ CommandRegistry as cJ,
42936
+ DEFAULT_PALETTE as cK,
42937
+ DialogFooter as cL,
42938
+ FloatingActionButton as cM,
42939
+ GridPicker as cN,
42940
+ IconButton as cO,
42941
+ Menu as cP,
42942
+ OASIS_BUILTIN_COMMANDS as cQ,
42943
+ OASIS_MENU_ITEMS as cR,
42944
+ OASIS_TOOLBAR_ITEMS as cS,
42945
+ OasisEditorAppLazy as cT,
42946
+ OasisEditorContainer as cU,
42947
+ PluginCollection as cV,
42948
+ Popover as cW,
42949
+ RIBBON_TABS as cX,
42950
+ Select as cY,
42951
+ SelectField as cZ,
42952
+ Separator as c_,
42953
+ getParagraphById as ca,
42954
+ createEditorFootnote as cb,
42955
+ createFootnoteReferenceRun as cc,
42956
+ renumberFootnotes as cd,
42957
+ getHeadingLevel as ce,
42958
+ preciseFontModeVersion as cf,
42959
+ isPreciseFontModeEnabled as cg,
42960
+ resolveNamedTextStyle as ch,
42961
+ togglePreciseFontMode as ci,
42962
+ nextFontSizePt as cj,
42963
+ previousFontSizePt as ck,
42964
+ fontSizePtToPx as cl,
42965
+ createDefaultToolbarPreset as cm,
42966
+ MenuRegistry as cn,
42967
+ createToolbarRegistry as co,
42968
+ Editor as cp,
42969
+ resolveCommandRef as cq,
42970
+ commandRefName as cr,
42971
+ createOasisEditorClient as cs,
42972
+ createEditorZoom as ct,
42973
+ startLongTaskObserver as cu,
42974
+ installGlobalReport as cv,
42975
+ applyStoredPreciseFontPreference as cw,
42976
+ getWelcomeSeen as cx,
42977
+ isLocalFontAccessSupported as cy,
42978
+ EDITOR_SCROLL_PADDING_PX as cz,
42898
42979
  domTextMeasurer as d,
42899
- createOasisEditor as d0,
42900
- createOasisEditorContainer as d1,
42901
- mount as d2,
42902
- registerToolbarRenderer as d3,
42980
+ SidePanelBody as d0,
42981
+ SidePanelFooter as d1,
42982
+ SidePanelHeader as d2,
42983
+ SplitButton as d3,
42984
+ StyleGallery as d4,
42985
+ TextField as d5,
42986
+ Button$1 as d6,
42987
+ buildRibbonTabDefinitions as d7,
42988
+ createEditorCommandBus as d8,
42989
+ createOasisEditor as d9,
42990
+ createOasisEditorContainer as da,
42991
+ mount as db,
42992
+ registerToolbarRenderer as dc,
42903
42993
  estimateTableBlockHeight as e,
42904
42994
  getFootnoteDisplayMarker as f,
42905
42995
  getProjectedParagraphBlockHeight as g,
42906
- getDocumentSections as h,
42907
- buildFootnoteReservations as i,
42908
- applyFootnotesToPages as j,
42909
- getRunField as k,
42996
+ createProjectionContext as h,
42997
+ getDocumentSections as i,
42998
+ buildFootnoteReservations as j,
42999
+ applyFootnotesToPages as k,
42910
43000
  listReferencedEndnotes as l,
42911
- projectBlocksLayout as m,
42912
- assertNever as n,
42913
- createSignal as o,
43001
+ getRunField as m,
43002
+ projectBlocksLayout as n,
43003
+ assertNever as o,
42914
43004
  projectParagraphLayout as p,
42915
- createEditorStateFromDocument as q,
43005
+ createSignal as q,
42916
43006
  reservationSignature as r,
42917
- setActiveHyphenation as s,
43007
+ createEditorStateFromDocument as s,
42918
43008
  createInitialEditorState as t,
42919
43009
  fontSizePxToPt as u,
42920
43010
  visitRun as v,