@univerjs/engine-render 0.23.0 → 0.24.0-insiders.20260528-29f582d

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/cjs/index.js CHANGED
@@ -309,14 +309,7 @@ function getFontStyleString(textStyle) {
309
309
  let originFontSize = defaultFontSize;
310
310
  if (textStyle.fs) originFontSize = Math.ceil(textStyle.fs);
311
311
  let fontSize = originFontSize;
312
- let fontFamilyResult = defaultFont;
313
- if (textStyle.ff) {
314
- let fontFamily = textStyle.ff;
315
- fontFamily = fontFamily.replace(/"/g, "").replace(/'/g, "");
316
- if (fontFamily.indexOf(" ") > -1) fontFamily = `"${fontFamily}"`;
317
- if (fontFamily == null) fontFamily = defaultFont;
318
- fontFamilyResult = fontFamily;
319
- }
312
+ const fontFamilyResult = normalizeFontFamily(textStyle.ff, defaultFont);
320
313
  const { va: baselineOffset } = textStyle;
321
314
  if (baselineOffset === _univerjs_core.BaselineOffset.SUBSCRIPT || baselineOffset === _univerjs_core.BaselineOffset.SUPERSCRIPT) {
322
315
  const { sbr, spr } = FontCache.getBaselineOffsetInfo(fontFamilyResult, fontSize);
@@ -331,6 +324,13 @@ function getFontStyleString(textStyle) {
331
324
  fontFamily: fontFamilyResult
332
325
  };
333
326
  }
327
+ function normalizeFontFamily(fontFamily, defaultFont) {
328
+ if (!(fontFamily === null || fontFamily === void 0 ? void 0 : fontFamily.trim())) return defaultFont;
329
+ return fontFamily.split(",").map((item) => {
330
+ const family = item.trim().replace(/^['"]|['"]$/g, "");
331
+ return family.includes(" ") ? `"${family}"` : family;
332
+ }).filter(Boolean).join(", ");
333
+ }
334
334
  const CJK_LETTER_REG = cjk_regex.letters().toRegExp();
335
335
  function hasCJKText(text) {
336
336
  return CJK_LETTER_REG.test(text);
@@ -384,6 +384,9 @@ function hasArabic(text) {
384
384
  function hasTibetan(text) {
385
385
  return /[\u0180-\u024F]/gi.test(text);
386
386
  }
387
+ function hasThai(text) {
388
+ return /[\u0E00-\u0E7F]/.test(text);
389
+ }
387
390
  function hasSpace(text) {
388
391
  return /\s+/g.test(text);
389
392
  }
@@ -2952,6 +2955,37 @@ var Transform = class Transform {
2952
2955
  }
2953
2956
  };
2954
2957
 
2958
+ //#endregion
2959
+ //#region src/basics/zoom.ts
2960
+ const MIN_ZOOM_RATIO = .1;
2961
+ const MAX_ZOOM_RATIO = 4;
2962
+ const PIXEL_DELTA_TO_ZOOM_RATIO = .008;
2963
+ const MAX_WHEEL_ZOOM_STEP = .14;
2964
+ const MAX_WHEEL_ZOOM_STEP_BELOW_ONE = .07;
2965
+ const LINE_DELTA_PIXEL_SIZE = 16;
2966
+ const PAGE_DELTA_PIXEL_SIZE = 800;
2967
+ const ZOOM_RATIO_PRECISION = 100;
2968
+ function clamp(value, min, max) {
2969
+ return Math.min(max, Math.max(min, value));
2970
+ }
2971
+ function normalizeWheelDelta(event) {
2972
+ const deltaY = Number.isFinite(event.deltaY) ? event.deltaY : 0;
2973
+ const deltaX = Number.isFinite(event.deltaX) ? event.deltaX : 0;
2974
+ let delta = Math.abs(deltaY) >= Math.abs(deltaX) ? deltaY : deltaX;
2975
+ if (delta === 0 && typeof event.wheelDelta === "number") delta = -event.wheelDelta / 3;
2976
+ if (event.deltaMode === EventConstants.DOM_DELTA_LINE) delta *= LINE_DELTA_PIXEL_SIZE;
2977
+ else if (event.deltaMode === EventConstants.DOM_DELTA_PAGE) delta *= PAGE_DELTA_PIXEL_SIZE;
2978
+ return delta;
2979
+ }
2980
+ function getNextWheelZoomRatio(currentRatio, event) {
2981
+ const validCurrentRatio = Number.isFinite(currentRatio) ? currentRatio : 1;
2982
+ const normalizedDelta = normalizeWheelDelta(event);
2983
+ if (normalizedDelta === 0) return clamp(validCurrentRatio, MIN_ZOOM_RATIO, MAX_ZOOM_RATIO);
2984
+ const maxStep = validCurrentRatio < 1 ? MAX_WHEEL_ZOOM_STEP_BELOW_ONE : MAX_WHEEL_ZOOM_STEP;
2985
+ const ratioDelta = clamp(-normalizedDelta * PIXEL_DELTA_TO_ZOOM_RATIO, -maxStep, maxStep);
2986
+ return clamp(Math.round((validCurrentRatio + ratioDelta) * ZOOM_RATIO_PRECISION) / ZOOM_RATIO_PRECISION, MIN_ZOOM_RATIO, MAX_ZOOM_RATIO);
2987
+ }
2988
+
2955
2989
  //#endregion
2956
2990
  //#region src/base-object.ts
2957
2991
  const BASE_OBJECT_ARRAY = [
@@ -4715,8 +4749,9 @@ var SpreadsheetColumnHeader = class extends SpreadsheetHeader {
4715
4749
  const segment = spreadsheetSkeleton.rowColumnSegment;
4716
4750
  if (!segment) return;
4717
4751
  if (segment.startColumn === -1 && segment.endColumn === -1) return;
4718
- const { rowHeaderWidth } = spreadsheetSkeleton;
4719
- ctx.translateWithPrecision(rowHeaderWidth, 0);
4752
+ const { columnHeaderHeight, columnHeaderHeightAndMarginTop, rowHeaderWidthAndMarginLeft } = spreadsheetSkeleton;
4753
+ const marginTop = columnHeaderHeightAndMarginTop - columnHeaderHeight;
4754
+ ctx.translateWithPrecision(rowHeaderWidthAndMarginLeft, marginTop);
4720
4755
  const extensions = this.getExtensionsByOrder();
4721
4756
  for (const extension of extensions) extension.draw(ctx, parentScale, spreadsheetSkeleton);
4722
4757
  }
@@ -4724,8 +4759,9 @@ var SpreadsheetColumnHeader = class extends SpreadsheetHeader {
4724
4759
  const oCoord = this.getInverseCoord(coord);
4725
4760
  const skeleton = this.getSkeleton();
4726
4761
  if (!skeleton) return false;
4727
- const { rowHeaderWidth, columnHeaderHeight } = skeleton;
4728
- if (oCoord.x > rowHeaderWidth && oCoord.y >= 0 && oCoord.y <= columnHeaderHeight) return true;
4762
+ const { rowHeaderWidthAndMarginLeft, columnHeaderHeight, columnHeaderHeightAndMarginTop } = skeleton;
4763
+ const marginTop = columnHeaderHeightAndMarginTop - columnHeaderHeight;
4764
+ if (oCoord.x > rowHeaderWidthAndMarginLeft && oCoord.y >= marginTop && oCoord.y <= columnHeaderHeightAndMarginTop) return true;
4729
4765
  return false;
4730
4766
  }
4731
4767
  _initialDefaultExtension() {
@@ -12051,6 +12087,17 @@ var Liquid = class {
12051
12087
  }
12052
12088
  };
12053
12089
 
12090
+ //#endregion
12091
+ //#region src/components/docs/table-render-viewport.ts
12092
+ let docsTableRenderViewportProvider = null;
12093
+ function setDocsTableRenderViewportProvider(provider) {
12094
+ docsTableRenderViewportProvider = provider;
12095
+ }
12096
+ function getDocsTableRenderViewport(unitId, tableId) {
12097
+ var _docsTableRenderViewp;
12098
+ return (_docsTableRenderViewp = docsTableRenderViewportProvider === null || docsTableRenderViewportProvider === void 0 ? void 0 : docsTableRenderViewportProvider(unitId, tableId)) !== null && _docsTableRenderViewp !== void 0 ? _docsTableRenderViewp : null;
12099
+ }
12100
+
12054
12101
  //#endregion
12055
12102
  //#region src/components/docs/view-model/data-stream-tree-node.ts
12056
12103
  var DataStreamTreeNode = class DataStreamTreeNode {
@@ -12219,6 +12266,17 @@ function parseDataStreamToTree(dataStream, tables) {
12219
12266
  const tableRowList = [];
12220
12267
  const tableCellList = [];
12221
12268
  const currentBlocks = [];
12269
+ const getParagraphList = () => tableCellList.length > 0 ? cellParagraphList : paragraphList;
12270
+ const appendToPreviousParagraph = (char) => {
12271
+ const tempParagraphList = getParagraphList();
12272
+ const lastParagraph = tempParagraphList[tempParagraphList.length - 1];
12273
+ if (lastParagraph) {
12274
+ var _lastParagraph$conten;
12275
+ lastParagraph.content = `${(_lastParagraph$conten = lastParagraph.content) !== null && _lastParagraph$conten !== void 0 ? _lastParagraph$conten : ""}${char}`;
12276
+ return true;
12277
+ }
12278
+ return false;
12279
+ };
12222
12280
  for (let i = 0; i < dataStreamLen; i++) {
12223
12281
  const char = dataStream[i];
12224
12282
  if (char === _univerjs_core.DataStreamTreeTokenType.PARAGRAPH) {
@@ -12279,6 +12337,9 @@ function parseDataStreamToTree(dataStream, tables) {
12279
12337
  const cellNode = tableCellList.pop();
12280
12338
  const lastRow = tableRowList[tableRowList.length - 1];
12281
12339
  batchParent(lastRow, [cellNode], _univerjs_core.DataStreamTreeNodeType.TABLE_ROW);
12340
+ } else if (char === _univerjs_core.DataStreamTreeTokenType.BLOCK_START) content += char;
12341
+ else if (char === _univerjs_core.DataStreamTreeTokenType.BLOCK_END) {
12342
+ if (content.length > 0 || !appendToPreviousParagraph(char)) content += char;
12282
12343
  } else if (char === _univerjs_core.DataStreamTreeTokenType.CUSTOM_BLOCK) {
12283
12344
  currentBlocks.push(i);
12284
12345
  content += char;
@@ -12595,6 +12656,8 @@ function _createSkeletonWordOrLetter(glyphType, content, config, glyphWidth, gly
12595
12656
  _univerjs_core.DataStreamTreeTokenType.TABLE_ROW_END,
12596
12657
  _univerjs_core.DataStreamTreeTokenType.TABLE_CELL_START,
12597
12658
  _univerjs_core.DataStreamTreeTokenType.TABLE_CELL_END,
12659
+ _univerjs_core.DataStreamTreeTokenType.BLOCK_START,
12660
+ _univerjs_core.DataStreamTreeTokenType.BLOCK_END,
12598
12661
  _univerjs_core.DataStreamTreeTokenType.CUSTOM_RANGE_START,
12599
12662
  _univerjs_core.DataStreamTreeTokenType.CUSTOM_RANGE_END,
12600
12663
  _univerjs_core.DataStreamTreeTokenType.COLUMN_BREAK,
@@ -13104,7 +13167,16 @@ function createTableSkeleton(ctx, curPage, viewModel, tableNode, sectionBreakCon
13104
13167
  let left = 0;
13105
13168
  let rowHeight = 0;
13106
13169
  for (const cellNode of cellNodes) {
13107
- const cellPageSkeleton = createSkeletonCellPages(ctx, viewModel, cellNode, sectionBreakConfig, table, row, cellNodes.indexOf(cellNode))[0];
13170
+ const col = cellNodes.indexOf(cellNode);
13171
+ const cellConfig = rowSource.tableCells[col];
13172
+ if (isCoveredTableCell(cellConfig)) {
13173
+ const cellPageSkeleton = createMergedCoveredCellPage(ctx, sectionBreakConfig, table, row, col, rowSkeleton);
13174
+ cellPageSkeleton.left = left;
13175
+ if (shouldAdvanceTableCellLeft(table, row, col)) left += cellPageSkeleton.pageWidth;
13176
+ rowSkeleton.cells.push(cellPageSkeleton);
13177
+ continue;
13178
+ }
13179
+ const cellPageSkeleton = createSkeletonCellPages(ctx, viewModel, cellNode, sectionBreakConfig, table, row, col)[0];
13108
13180
  const { marginTop = 0, marginBottom = 0 } = cellPageSkeleton;
13109
13181
  const pageHeight = cellPageSkeleton.height + marginTop + marginBottom;
13110
13182
  cellPageSkeleton.left = left;
@@ -13114,7 +13186,7 @@ function createTableSkeleton(ctx, curPage, viewModel, tableNode, sectionBreakCon
13114
13186
  rowHeight = Math.max(rowHeight, pageHeight);
13115
13187
  }
13116
13188
  if (hRule === _univerjs_core.TableRowHeightRule.AT_LEAST) rowHeight = Math.max(rowHeight, val.v);
13117
- else if (hRule === _univerjs_core.TableRowHeightRule.EXACT) rowHeight = val.v;
13189
+ else if (hRule === _univerjs_core.TableRowHeightRule.EXACT) rowHeight = Math.max(rowHeight, val.v);
13118
13190
  for (const cellPageSkeleton of rowSkeleton.cells) cellPageSkeleton.pageHeight = rowHeight;
13119
13191
  const rowConfig = table.tableRows[row];
13120
13192
  for (let i = 0; i < rowConfig.tableCells.length; i++) {
@@ -13145,6 +13217,7 @@ function createTableSkeleton(ctx, curPage, viewModel, tableNode, sectionBreakCon
13145
13217
  }
13146
13218
  tableSkeleton.width = tableWidth;
13147
13219
  tableSkeleton.height = rowTop;
13220
+ applyMergedCellSpanHeights(tableSkeleton);
13148
13221
  const { pageWidth, marginLeft = 0, marginRight = 0 } = curPage;
13149
13222
  tableSkeleton.left = _getTableLeft(pageWidth - marginLeft - marginRight, tableWidth, table.align, table.indent);
13150
13223
  return tableSkeleton;
@@ -13168,14 +13241,14 @@ function createTableSkeletons(ctx, curPage, viewModel, tableNode, sectionBreakCo
13168
13241
  fromCurrentPage: false
13169
13242
  };
13170
13243
  }
13171
- const needRepeatHeader = table.tableRows[0].repeatHeaderRow === _univerjs_core.BooleanNumber.TRUE;
13244
+ const repeatRows = getLeadingRepeatHeaderRows(table, rowNodes);
13172
13245
  const curTableSkeleton = getNullTableSkeleton(startIndex, endIndex, table);
13173
13246
  const createCache = {
13174
13247
  rowTop: 0,
13175
13248
  tableWidth: 0,
13176
13249
  remainHeight: availableHeight,
13177
- repeatRow: needRepeatHeader ? rowNodes[0] : null,
13178
- repeatRowHeight: 0
13250
+ repeatRows,
13251
+ repeatRowsHeight: 0
13179
13252
  };
13180
13253
  skeTables.push(curTableSkeleton);
13181
13254
  for (const rowNode of rowNodes) dealWithTableRow(ctx, curPage, skeTables, viewModel, sectionBreakConfig, rowNode, rowNodes.indexOf(rowNode), table, createCache);
@@ -13191,6 +13264,7 @@ function updateTableSkeletonsPosition(cache, curPage, skeTables, table) {
13191
13264
  const tableLeft = _getTableLeft(pageWidth - marginLeft - marginRight, tableWidth, table.align, table.indent);
13192
13265
  let tableIndex = 0;
13193
13266
  for (const tableSkeleton of skeTables) {
13267
+ applyMergedCellSpanHeights(tableSkeleton);
13194
13268
  tableSkeleton.width = tableWidth;
13195
13269
  tableSkeleton.left = tableLeft;
13196
13270
  tableSkeleton.st = tableSkeleton.rows[0].st - 1;
@@ -13207,7 +13281,7 @@ function getCurTableSkeleton(skeTables) {
13207
13281
  function getAvailableHeight(curPage, cache, hasRepeatHeader) {
13208
13282
  const { marginTop, marginBottom, pageHeight } = curPage;
13209
13283
  let pageContentHeight = pageHeight - marginTop - marginBottom;
13210
- if (hasRepeatHeader) pageContentHeight -= cache.repeatRowHeight;
13284
+ if (hasRepeatHeader) pageContentHeight -= cache.repeatRowsHeight;
13211
13285
  return pageContentHeight;
13212
13286
  }
13213
13287
  function dealWithTableRow(ctx, curPage, skeTables, viewModel, sectionBreakConfig, rowNode, row, table, cache, isRepeatRow = false) {
@@ -13225,17 +13299,13 @@ function dealWithTableRow(ctx, curPage, skeTables, viewModel, sectionBreakConfig
13225
13299
  const rowHeights = [0];
13226
13300
  for (const cellNode of cellNodes) {
13227
13301
  const col = cellNodes.indexOf(cellNode);
13228
- const cellPageSkeletons = createSkeletonCellPages(ctx, viewModel, cellNode, sectionBreakConfig, table, row, col, canRowSplit && !needOpenNewTable ? cache.remainHeight : availableHeight, pageContentHeight);
13229
- while (rowSkeletons.length < cellPageSkeletons.length) {
13230
- const rowSkeleton = _getNullTableRowSkeleton(startIndex, endIndex, row, rowSource, isRepeatRow);
13231
- const colCount = cellNodes.length;
13232
- rowSkeleton.cells = [...new Array(colCount)].map((_, i) => {
13233
- const cellSkeleton = createNullCellPage(ctx, sectionBreakConfig, table, row, i).page;
13234
- cellSkeleton.parent = rowSkeleton;
13235
- return cellSkeleton;
13236
- });
13237
- rowSkeletons.push(rowSkeleton);
13302
+ const cellConfig = rowSource.tableCells[col];
13303
+ if (isCoveredTableCell(cellConfig)) {
13304
+ if (rowSkeletons.length === 0) rowSkeletons.push(createNullRowSkeletonWithCells(ctx, sectionBreakConfig, table, row, startIndex, endIndex, rowSource, isRepeatRow));
13305
+ continue;
13238
13306
  }
13307
+ const cellPageSkeletons = createSkeletonCellPages(ctx, viewModel, cellNode, sectionBreakConfig, table, row, col, canRowSplit && !needOpenNewTable ? cache.remainHeight : availableHeight, pageContentHeight);
13308
+ while (rowSkeletons.length < cellPageSkeletons.length) rowSkeletons.push(createNullRowSkeletonWithCells(ctx, sectionBreakConfig, table, row, startIndex, endIndex, rowSource, isRepeatRow));
13239
13309
  while (rowHeights.length < cellPageSkeletons.length) rowHeights.push(0);
13240
13310
  for (const cellPageSkeleton of cellPageSkeletons) {
13241
13311
  const { marginTop: cellMarginTop = 0, marginBottom: cellMarginBottom = 0 } = cellPageSkeleton;
@@ -13250,18 +13320,20 @@ function dealWithTableRow(ctx, curPage, skeTables, viewModel, sectionBreakConfig
13250
13320
  for (const rowSke of rowSkeletons) {
13251
13321
  const rowIndex = rowSkeletons.indexOf(rowSke);
13252
13322
  if (hRule === _univerjs_core.TableRowHeightRule.AT_LEAST) rowHeights[rowIndex] = Math.max(rowHeights[rowIndex], val.v);
13253
- else if (hRule === _univerjs_core.TableRowHeightRule.EXACT) rowHeights[rowIndex] = val.v;
13323
+ else if (hRule === _univerjs_core.TableRowHeightRule.EXACT) rowHeights[rowIndex] = Math.max(rowHeights[rowIndex], val.v);
13254
13324
  rowHeights[rowIndex] = Math.min(rowHeights[rowIndex], pageContentHeight);
13255
13325
  let left = 0;
13256
- for (const cellPageSkeleton of rowSke.cells) {
13326
+ for (let col = 0; col < rowSke.cells.length; col++) {
13327
+ const cellPageSkeleton = rowSke.cells[col];
13328
+ if (cellPageSkeleton == null) continue;
13257
13329
  cellPageSkeleton.left = left;
13258
13330
  cellPageSkeleton.pageHeight = rowHeights[rowIndex];
13259
- left += cellPageSkeleton.pageWidth;
13331
+ if (shouldAdvanceTableCellLeft(table, rowSke.index, col)) left += cellPageSkeleton.pageWidth;
13260
13332
  cache.tableWidth = Math.max(cache.tableWidth, left);
13261
13333
  }
13262
13334
  rowSke.height = rowHeights[rowIndex];
13263
13335
  }
13264
- if (row === 0 && cache.repeatRow) cache.repeatRowHeight = rowHeights[rowHeights.length - 1];
13336
+ if (!isRepeatRow && row < cache.repeatRows.length) cache.repeatRowsHeight += rowHeights.reduce((total, height) => total + height, 0);
13265
13337
  for (const rowSkeleton of rowSkeletons) _verticalAlignInCell(rowSkeleton, rowSource);
13266
13338
  while (rowSkeletons.length > 0) {
13267
13339
  const rowSkeleton = rowSkeletons.shift();
@@ -13272,10 +13344,11 @@ function dealWithTableRow(ctx, curPage, skeTables, viewModel, sectionBreakConfig
13272
13344
  if (curTableSkeleton.rows.length > 0) {
13273
13345
  curTableSkeleton = getNullTableSkeleton(startIndex, endIndex, table);
13274
13346
  skeTables.push(curTableSkeleton);
13275
- if (cache.repeatRow && isRepeatRow === false && row !== 0 && rowSkeleton.index !== lastRow.index) {
13276
- const FIRST_ROW_INDEX = 0;
13347
+ if (cache.repeatRows.length > 0 && isRepeatRow === false && row >= cache.repeatRows.length && rowSkeleton.index !== lastRow.index) {
13277
13348
  cache.remainHeight = getAvailableHeight(curPage, cache, false);
13278
- dealWithTableRow(ctx, curPage, skeTables, viewModel, sectionBreakConfig, cache.repeatRow, FIRST_ROW_INDEX, table, cache, true);
13349
+ cache.repeatRows.forEach((repeatRow, repeatRowIndex) => {
13350
+ dealWithTableRow(ctx, curPage, skeTables, viewModel, sectionBreakConfig, repeatRow, repeatRowIndex, table, cache, true);
13351
+ });
13279
13352
  }
13280
13353
  }
13281
13354
  }
@@ -13288,6 +13361,15 @@ function dealWithTableRow(ctx, curPage, skeTables, viewModel, sectionBreakConfig
13288
13361
  cache.rowTop += rowSkeleton.height;
13289
13362
  }
13290
13363
  }
13364
+ function getLeadingRepeatHeaderRows(table, rowNodes) {
13365
+ const repeatRows = [];
13366
+ for (let index = 0; index < rowNodes.length; index++) {
13367
+ var _table$tableRows$inde;
13368
+ if (((_table$tableRows$inde = table.tableRows[index]) === null || _table$tableRows$inde === void 0 ? void 0 : _table$tableRows$inde.repeatHeaderRow) !== _univerjs_core.BooleanNumber.TRUE) break;
13369
+ repeatRows.push(rowNodes[index]);
13370
+ }
13371
+ return repeatRows;
13372
+ }
13291
13373
  function _verticalAlignInCell(rowSkeleton, rowSource) {
13292
13374
  for (let i = 0; i < rowSource.tableCells.length; i++) {
13293
13375
  const cellConfig = rowSource.tableCells[i];
@@ -13312,6 +13394,75 @@ function _verticalAlignInCell(rowSkeleton, rowSource) {
13312
13394
  cellPageSkeleton.marginTop = marginTop;
13313
13395
  }
13314
13396
  }
13397
+ function createNullRowSkeletonWithCells(ctx, sectionBreakConfig, table, row, startIndex, endIndex, rowSource, isRepeatRow = false) {
13398
+ const rowSkeleton = _getNullTableRowSkeleton(startIndex, endIndex, row, rowSource, isRepeatRow);
13399
+ const colCount = rowSource.tableCells.length;
13400
+ rowSkeleton.cells = Array.from({ length: colCount }, (_, col) => createMergedAwareNullCellPage(ctx, sectionBreakConfig, table, row, col, rowSkeleton));
13401
+ return rowSkeleton;
13402
+ }
13403
+ function createMergedCoveredCellPage(ctx, sectionBreakConfig, table, row, col, rowSkeleton) {
13404
+ return createMergedAwareNullCellPage(ctx, sectionBreakConfig, table, row, col, rowSkeleton);
13405
+ }
13406
+ function applyMergedCellSpanHeights(tableSkeleton) {
13407
+ var _tableSkeleton$tableS, _tableSkeleton$tableS2;
13408
+ const tableRows = (_tableSkeleton$tableS = (_tableSkeleton$tableS2 = tableSkeleton.tableSource) === null || _tableSkeleton$tableS2 === void 0 ? void 0 : _tableSkeleton$tableS2.tableRows) !== null && _tableSkeleton$tableS !== void 0 ? _tableSkeleton$tableS : [];
13409
+ if (tableRows.length === 0) return;
13410
+ const skeletonRowsByIndex = new Map(tableSkeleton.rows.map((row) => [row.index, row]));
13411
+ tableRows.forEach((rowSource, rowIndex) => {
13412
+ rowSource.tableCells.forEach((cellConfig, columnIndex) => {
13413
+ var _cellConfig$rowSpan, _cellConfig$columnSpa;
13414
+ const rowSpan = (_cellConfig$rowSpan = cellConfig.rowSpan) !== null && _cellConfig$rowSpan !== void 0 ? _cellConfig$rowSpan : 1;
13415
+ const columnSpan = (_cellConfig$columnSpa = cellConfig.columnSpan) !== null && _cellConfig$columnSpa !== void 0 ? _cellConfig$columnSpa : 1;
13416
+ if (rowSpan <= 1 && columnSpan <= 1) return;
13417
+ const masterRow = skeletonRowsByIndex.get(rowIndex);
13418
+ const masterCell = masterRow === null || masterRow === void 0 ? void 0 : masterRow.cells[columnIndex];
13419
+ if (!masterCell || masterCell.isMergedCellCovered) return;
13420
+ let pageHeight = 0;
13421
+ for (let row = rowIndex; row < rowIndex + rowSpan; row++) {
13422
+ var _skeletonRowsByIndex$, _skeletonRowsByIndex$2;
13423
+ pageHeight += (_skeletonRowsByIndex$ = (_skeletonRowsByIndex$2 = skeletonRowsByIndex.get(row)) === null || _skeletonRowsByIndex$2 === void 0 ? void 0 : _skeletonRowsByIndex$2.height) !== null && _skeletonRowsByIndex$ !== void 0 ? _skeletonRowsByIndex$ : 0;
13424
+ }
13425
+ if (pageHeight > 0) masterCell.pageHeight = pageHeight;
13426
+ });
13427
+ });
13428
+ }
13429
+ function createMergedAwareNullCellPage(ctx, sectionBreakConfig, table, row, col, rowSkeleton) {
13430
+ const cellSkeleton = createNullCellPage(ctx, sectionBreakConfig, table, row, col).page;
13431
+ cellSkeleton.parent = rowSkeleton;
13432
+ if (isCoveredTableCell(table.tableRows[row].tableCells[col])) Object.assign(cellSkeleton, { isMergedCellCovered: true });
13433
+ return cellSkeleton;
13434
+ }
13435
+ function shouldAdvanceTableCellLeft(table, row, col) {
13436
+ var _table$tableRows$row;
13437
+ if (!isCoveredTableCell((_table$tableRows$row = table.tableRows[row]) === null || _table$tableRows$row === void 0 ? void 0 : _table$tableRows$row.tableCells[col])) return true;
13438
+ const masterCell = findMergedMasterCell(table, row, col);
13439
+ if (masterCell == null) return true;
13440
+ return masterCell.row !== row;
13441
+ }
13442
+ function findMergedMasterCell(table, row, col) {
13443
+ for (let rowIndex = 0; rowIndex <= row; rowIndex++) {
13444
+ const rowSource = table.tableRows[rowIndex];
13445
+ if (rowSource == null) continue;
13446
+ for (let columnIndex = 0; columnIndex < rowSource.tableCells.length; columnIndex++) {
13447
+ var _cellConfig$rowSpan2, _cellConfig$columnSpa2;
13448
+ const cellConfig = rowSource.tableCells[columnIndex];
13449
+ if (isCoveredTableCell(cellConfig)) continue;
13450
+ const rowSpan = Math.max(1, (_cellConfig$rowSpan2 = cellConfig.rowSpan) !== null && _cellConfig$rowSpan2 !== void 0 ? _cellConfig$rowSpan2 : 1);
13451
+ const columnSpan = Math.max(1, (_cellConfig$columnSpa2 = cellConfig.columnSpan) !== null && _cellConfig$columnSpa2 !== void 0 ? _cellConfig$columnSpa2 : 1);
13452
+ if (rowSpan <= 1 && columnSpan <= 1) continue;
13453
+ const containsRow = row >= rowIndex && row < rowIndex + rowSpan;
13454
+ const containsColumn = col >= columnIndex && col < columnIndex + columnSpan;
13455
+ if (containsRow && containsColumn) return {
13456
+ row: rowIndex,
13457
+ col: columnIndex
13458
+ };
13459
+ }
13460
+ }
13461
+ return null;
13462
+ }
13463
+ function isCoveredTableCell(cellConfig) {
13464
+ return (cellConfig === null || cellConfig === void 0 ? void 0 : cellConfig.rowSpan) === 0 || (cellConfig === null || cellConfig === void 0 ? void 0 : cellConfig.columnSpan) === 0;
13465
+ }
13315
13466
  function _getTableLeft(pageWidth, tableWidth, align, indent = { v: 0 }) {
13316
13467
  switch (align) {
13317
13468
  case _univerjs_core.TableAlignmentType.START: return indent.v;
@@ -14417,13 +14568,13 @@ const DEFAULT_PAGE_SIZE = {
14417
14568
  const DEFAULT_MODERN_DOCUMENT_STYLE = {
14418
14569
  pageNumberStart: 1,
14419
14570
  pageSize: {
14420
- width: ptToPixel(595),
14571
+ width: _univerjs_core.MODERN_DOCUMENT_WIDTH[_univerjs_core.ModernDocumentWidthMode.MEDIUM],
14421
14572
  height: Number.POSITIVE_INFINITY
14422
14573
  },
14423
- marginTop: ptToPixel(50),
14424
- marginBottom: ptToPixel(50),
14425
- marginRight: ptToPixel(50),
14426
- marginLeft: ptToPixel(50),
14574
+ marginTop: _univerjs_core.MODERN_DOCUMENT_DEFAULT_MARGIN,
14575
+ marginBottom: _univerjs_core.MODERN_DOCUMENT_DEFAULT_MARGIN,
14576
+ marginRight: _univerjs_core.MODERN_DOCUMENT_DEFAULT_MARGIN,
14577
+ marginLeft: _univerjs_core.MODERN_DOCUMENT_DEFAULT_MARGIN,
14427
14578
  renderConfig: {
14428
14579
  vertexAngle: 0,
14429
14580
  centerAngle: 0,
@@ -14453,8 +14604,13 @@ function prepareSectionBreakConfig(ctx, nodeIndex) {
14453
14604
  const { documentFlavor } = documentStyle;
14454
14605
  let sectionBreak = viewModel.getSectionBreak(sectionNode.endIndex) || DEFAULT_SECTION_BREAK;
14455
14606
  if (documentFlavor === _univerjs_core.DocumentFlavor.MODERN) {
14607
+ var _documentStyle$pageSi, _documentStyle$pageSi2;
14608
+ const modernPageWidth = (_documentStyle$pageSi = (_documentStyle$pageSi2 = documentStyle.pageSize) === null || _documentStyle$pageSi2 === void 0 ? void 0 : _documentStyle$pageSi2.width) !== null && _documentStyle$pageSi !== void 0 ? _documentStyle$pageSi : DEFAULT_MODERN_DOCUMENT_STYLE.pageSize.width;
14456
14609
  sectionBreak = Object.assign({}, sectionBreak, DEFAULT_MODERN_SECTION_BREAK);
14457
- documentStyle = Object.assign({}, documentStyle, DEFAULT_MODERN_DOCUMENT_STYLE);
14610
+ documentStyle = Object.assign({}, documentStyle, DEFAULT_MODERN_DOCUMENT_STYLE, { pageSize: {
14611
+ ...DEFAULT_MODERN_DOCUMENT_STYLE.pageSize,
14612
+ width: modernPageWidth
14613
+ } });
14458
14614
  }
14459
14615
  const { pageNumberStart: global_pageNumberStart = 1, pageSize: global_pageSize = DEFAULT_PAGE_SIZE, pageOrient: global_pageOrient = _univerjs_core.PageOrientType.PORTRAIT, defaultHeaderId: global_defaultHeaderId, defaultFooterId: global_defaultFooterId, evenPageHeaderId: global_evenPageHeaderId, evenPageFooterId: global_evenPageFooterId, firstPageHeaderId: global_firstPageHeaderId, firstPageFooterId: global_firstPageFooterId, useFirstPageHeaderFooter: global_useFirstPageHeaderFooter, evenAndOddHeaders: global_evenAndOddHeaders, marginTop: global_marginTop = 0, marginBottom: global_marginBottom = 0, marginRight: global_marginRight = 0, marginLeft: global_marginLeft = 0, marginHeader: global_marginHeader = 0, marginFooter: global_marginFooter = 0, autoHyphenation = _univerjs_core.BooleanNumber.FALSE, doNotHyphenateCaps = _univerjs_core.BooleanNumber.FALSE, consecutiveHyphenLimit = Number.POSITIVE_INFINITY, hyphenationZone, renderConfig: global_renderConfig = {
14460
14616
  horizontalAlign: _univerjs_core.HorizontalAlign.LEFT,
@@ -14691,12 +14847,14 @@ function _createSkeletonHeaderFooter(ctx, headerOrFooterViewModel, sectionBreakC
14691
14847
  return page;
14692
14848
  }
14693
14849
  function createNullCellPage(ctx, sectionBreakConfig, tableConfig, row, col, availableHeight = Number.POSITIVE_INFINITY, maxCellPageHeight = Number.POSITIVE_INFINITY) {
14694
- var _ref, _cellConfig$margin;
14850
+ var _ref, _cellConfig$margin, _cellConfig$columnSpa;
14695
14851
  const { lists, footerTreeMap, headerTreeMap, localeService, drawings } = sectionBreakConfig;
14696
14852
  const { skeletonResourceReference } = ctx;
14697
14853
  const { cellMargin, tableRows, tableColumns, tableId } = tableConfig;
14698
- const { start = { v: 10 }, end = { v: 10 }, top = { v: 5 }, bottom = { v: 5 } } = (_ref = (_cellConfig$margin = tableRows[row].tableCells[col].margin) !== null && _cellConfig$margin !== void 0 ? _cellConfig$margin : cellMargin) !== null && _ref !== void 0 ? _ref : {};
14699
- const pageWidth = tableColumns[col].size.width.v;
14854
+ const cellConfig = tableRows[row].tableCells[col];
14855
+ const { start = { v: 10 }, end = { v: 10 }, top = { v: 5 }, bottom = { v: 5 } } = (_ref = (_cellConfig$margin = cellConfig.margin) !== null && _cellConfig$margin !== void 0 ? _cellConfig$margin : cellMargin) !== null && _ref !== void 0 ? _ref : {};
14856
+ const columnSpan = Math.max(1, (_cellConfig$columnSpa = cellConfig.columnSpan) !== null && _cellConfig$columnSpa !== void 0 ? _cellConfig$columnSpa : 1);
14857
+ const pageWidth = tableColumns.slice(col, col + columnSpan).reduce((sum, column) => sum + column.size.width.v, 0);
14700
14858
  const pageHeight = maxCellPageHeight;
14701
14859
  const cellSectionBreakConfig = {
14702
14860
  lists,
@@ -14725,6 +14883,7 @@ function createNullCellPage(ctx, sectionBreakConfig, tableConfig, row, col, avai
14725
14883
  };
14726
14884
  }
14727
14885
  function createSkeletonCellPages(ctx, viewModel, cellNode, sectionBreakConfig, tableConfig, row, col, availableHeight = Number.POSITIVE_INFINITY, maxCellPageHeight = Number.POSITIVE_INFINITY) {
14886
+ var _ctx$dataModel, _ctx$dataModel$getBod;
14728
14887
  const sectionNode = cellNode.children[0];
14729
14888
  const { page: areaPage, sectionBreakConfig: cellSectionBreakConfig } = createNullCellPage(ctx, sectionBreakConfig, tableConfig, row, col, availableHeight, maxCellPageHeight);
14730
14889
  const { pages } = dealWithSection(ctx, viewModel, sectionNode, areaPage, cellSectionBreakConfig);
@@ -14733,9 +14892,36 @@ function createSkeletonCellPages(ctx, viewModel, cellNode, sectionBreakConfig, t
14733
14892
  p.segmentId = tableConfig.tableId;
14734
14893
  }
14735
14894
  updateBlockIndex(pages, cellNode.startIndex);
14895
+ applyTrailingCellBlockRangeSpaceBelow(pages, (_ctx$dataModel = ctx.dataModel) === null || _ctx$dataModel === void 0 || (_ctx$dataModel$getBod = _ctx$dataModel.getBody) === null || _ctx$dataModel$getBod === void 0 ? void 0 : _ctx$dataModel$getBod.call(_ctx$dataModel), cellNode.endIndex);
14736
14896
  updateInlineDrawingCoordsAndBorder(ctx, pages);
14897
+ expandCellPageHeightForInlineDrawings(pages);
14737
14898
  return pages;
14738
14899
  }
14900
+ function expandCellPageHeightForInlineDrawings(pages) {
14901
+ for (const page of pages) {
14902
+ var _page$skeDrawings;
14903
+ (_page$skeDrawings = page.skeDrawings) === null || _page$skeDrawings === void 0 || _page$skeDrawings.forEach((drawing) => {
14904
+ var _drawing$drawingOrigi, _drawing$aTop, _drawing$height;
14905
+ if (((_drawing$drawingOrigi = drawing.drawingOrigin) === null || _drawing$drawingOrigi === void 0 ? void 0 : _drawing$drawingOrigi.layoutType) !== _univerjs_core.PositionedObjectLayoutType.INLINE) return;
14906
+ const drawingBottom = ((_drawing$aTop = drawing.aTop) !== null && _drawing$aTop !== void 0 ? _drawing$aTop : 0) + ((_drawing$height = drawing.height) !== null && _drawing$height !== void 0 ? _drawing$height : 0);
14907
+ if (drawingBottom > page.height) page.height = drawingBottom;
14908
+ });
14909
+ }
14910
+ }
14911
+ function applyTrailingCellBlockRangeSpaceBelow(pages, body, cellEndIndex) {
14912
+ const blockRanges = body === null || body === void 0 ? void 0 : body.blockRanges;
14913
+ const trailingBlockRangeSpace = 28;
14914
+ if (!(blockRanges === null || blockRanges === void 0 ? void 0 : blockRanges.length)) return;
14915
+ for (const page of pages) {
14916
+ var _page$sections$at, _body$paragraphs;
14917
+ const lastLine = (_page$sections$at = page.sections.at(-1)) === null || _page$sections$at === void 0 || (_page$sections$at = _page$sections$at.columns.at(-1)) === null || _page$sections$at === void 0 ? void 0 : _page$sections$at.lines.at(-1);
14918
+ if (!lastLine) continue;
14919
+ const paragraphIndex = lastLine.paragraphIndex;
14920
+ if (!blockRanges.some((range) => range.startIndex < paragraphIndex && paragraphIndex < range.endIndex)) continue;
14921
+ if (body === null || body === void 0 || (_body$paragraphs = body.paragraphs) === null || _body$paragraphs === void 0 ? void 0 : _body$paragraphs.some((paragraph) => paragraph.startIndex > paragraphIndex && paragraph.startIndex < cellEndIndex)) continue;
14922
+ page.height += lastLine.spaceBelowApply || trailingBlockRangeSpace;
14923
+ }
14924
+ }
14739
14925
  function _getVerticalMargin(marginTB, headerOrFooter, pageHeight) {
14740
14926
  if (!headerOrFooter || headerOrFooter.sections[0].columns[0].lines.length === 0) return marginTB;
14741
14927
  const HeaderFooterPageHeight = headerOrFooter.height + headerOrFooter.marginTop + headerOrFooter.marginBottom;
@@ -15142,6 +15328,11 @@ function ___getLevelAndSuffix(levelAndSuffixPre) {
15142
15328
 
15143
15329
  //#endregion
15144
15330
  //#region src/components/docs/layout/block/paragraph/linebreaking.ts
15331
+ const BLOCK_LAYOUT_OUTER_SPACING_MAP = new Map([
15332
+ ["callout", 34],
15333
+ ["code", 32],
15334
+ ["quote", 24]
15335
+ ]);
15145
15336
  function _getListLevelAncestors(bullet, listLevel) {
15146
15337
  if (!bullet || !listLevel) return;
15147
15338
  const { listId, nestingLevel } = bullet;
@@ -15168,6 +15359,57 @@ function _updateListLevelAncestors(paragraph, bullet, bulletSkeleton, listLevel)
15168
15359
  cacheItem.splice(nestingLevel + 1);
15169
15360
  listLevel === null || listLevel === void 0 || listLevel.set(listId, cacheItem);
15170
15361
  }
15362
+ function _withMinSpacing(style, key, value) {
15363
+ var _current$v;
15364
+ const current = style[key];
15365
+ const nextValue = Math.max((_current$v = current === null || current === void 0 ? void 0 : current.v) !== null && _current$v !== void 0 ? _current$v : 0, value);
15366
+ style[key] = {
15367
+ ...current,
15368
+ v: nextValue
15369
+ };
15370
+ }
15371
+ function _getNextAdjacentBlockRange(blockRanges, blockRange) {
15372
+ return blockRanges === null || blockRanges === void 0 ? void 0 : blockRanges.filter((range) => range.startIndex > blockRange.endIndex).sort((left, right) => left.startIndex - right.startIndex)[0];
15373
+ }
15374
+ function _hasNextAdjacentLayoutBlockRange(blockRanges, blockRange) {
15375
+ const nextBlockRange = _getNextAdjacentBlockRange(blockRanges, blockRange);
15376
+ return nextBlockRange != null && BLOCK_LAYOUT_OUTER_SPACING_MAP.has(nextBlockRange.blockType) && nextBlockRange.startIndex === blockRange.endIndex + 1;
15377
+ }
15378
+ function _applyDefaultLayoutParagraphStyle(style, hasBlockRange) {
15379
+ if (style.lineSpacing == null) style.lineSpacing = _univerjs_core.DEFAULT_DOCUMENT_PARAGRAPH_LINE_SPACING;
15380
+ if (hasBlockRange) return;
15381
+ if (style.spaceAbove == null) style.spaceAbove = { v: _univerjs_core.DEFAULT_DOCUMENT_PARAGRAPH_SPACE_ABOVE };
15382
+ if (style.spaceBelow == null) style.spaceBelow = { v: _univerjs_core.DEFAULT_DOCUMENT_PARAGRAPH_SPACE_BELOW };
15383
+ }
15384
+ function _applyBlockRangeLayoutParagraphStyle(body, paragraph, paragraphStyle, shouldApplyDocumentDefaults) {
15385
+ var _body$paragraphs, _BLOCK_LAYOUT_OUTER_S;
15386
+ const style = _univerjs_core.Tools.deepClone(paragraphStyle);
15387
+ const blockRanges = body === null || body === void 0 ? void 0 : body.blockRanges;
15388
+ if (!(blockRanges === null || blockRanges === void 0 ? void 0 : blockRanges.length)) {
15389
+ if (shouldApplyDocumentDefaults) _applyDefaultLayoutParagraphStyle(style, false);
15390
+ return style;
15391
+ }
15392
+ const blockRange = blockRanges.find((range) => BLOCK_LAYOUT_OUTER_SPACING_MAP.has(range.blockType) && paragraph.startIndex > range.startIndex && paragraph.startIndex < range.endIndex);
15393
+ if (!blockRange) {
15394
+ if (shouldApplyDocumentDefaults) _applyDefaultLayoutParagraphStyle(style, false);
15395
+ return style;
15396
+ }
15397
+ _applyDefaultLayoutParagraphStyle(style, true);
15398
+ const blockParagraphs = ((_body$paragraphs = body === null || body === void 0 ? void 0 : body.paragraphs) !== null && _body$paragraphs !== void 0 ? _body$paragraphs : []).filter((item) => item.startIndex > blockRange.startIndex && item.startIndex < blockRange.endIndex).sort((left, right) => left.startIndex - right.startIndex);
15399
+ const firstParagraph = blockParagraphs[0];
15400
+ const lastParagraph = blockParagraphs[blockParagraphs.length - 1];
15401
+ const outerSpacing = (_BLOCK_LAYOUT_OUTER_S = BLOCK_LAYOUT_OUTER_SPACING_MAP.get(blockRange.blockType)) !== null && _BLOCK_LAYOUT_OUTER_S !== void 0 ? _BLOCK_LAYOUT_OUTER_S : 0;
15402
+ if ((firstParagraph === null || firstParagraph === void 0 ? void 0 : firstParagraph.startIndex) === paragraph.startIndex) _withMinSpacing(style, "spaceAbove", outerSpacing);
15403
+ if ((lastParagraph === null || lastParagraph === void 0 ? void 0 : lastParagraph.startIndex) === paragraph.startIndex && !_hasNextAdjacentLayoutBlockRange(blockRanges, blockRange)) _withMinSpacing(style, "spaceBelow", outerSpacing);
15404
+ return style;
15405
+ }
15406
+ function _shouldApplyDocumentDefaultParagraphStyle(viewModel) {
15407
+ var _viewModel$getSnapsho;
15408
+ const snapshot = (_viewModel$getSnapsho = viewModel.getSnapshot) === null || _viewModel$getSnapsho === void 0 ? void 0 : _viewModel$getSnapsho.call(viewModel);
15409
+ const documentFlavor = snapshot === null || snapshot === void 0 ? void 0 : snapshot.documentStyle.documentFlavor;
15410
+ if (snapshot == null) return true;
15411
+ return documentFlavor != null && documentFlavor !== _univerjs_core.DocumentFlavor.UNSPECIFIED;
15412
+ }
15171
15413
  function _getDrawingSkeletonFormat(drawingOrigin) {
15172
15414
  const { drawingId } = drawingOrigin;
15173
15415
  return {
@@ -15190,6 +15432,7 @@ function _getNextPageNumber(lastPage) {
15190
15432
  return lastPage.pageNumber + 1;
15191
15433
  }
15192
15434
  function lineBreaking(ctx, viewModel, shapedTextList, curPage, paragraphNode, sectionBreakConfig, tableSkeleton) {
15435
+ var _viewModel$getBody, _viewModel$getBody2;
15193
15436
  const { skeletonResourceReference } = ctx;
15194
15437
  const { lists, drawings = {}, localeService } = sectionBreakConfig;
15195
15438
  const { endIndex, blocks = [], children } = paragraphNode;
@@ -15206,7 +15449,7 @@ function lineBreaking(ctx, viewModel, shapedTextList, curPage, paragraphNode, se
15206
15449
  }
15207
15450
  const paragraphConfig = {
15208
15451
  paragraphIndex: endIndex,
15209
- paragraphStyle: _univerjs_core.Tools.deepClone(paragraphStyle),
15452
+ paragraphStyle: _applyBlockRangeLayoutParagraphStyle((_viewModel$getBody = (_viewModel$getBody2 = viewModel.getBody) === null || _viewModel$getBody2 === void 0 ? void 0 : _viewModel$getBody2.call(viewModel)) !== null && _viewModel$getBody !== void 0 ? _viewModel$getBody : null, paragraph, paragraphStyle, _shouldApplyDocumentDefaultParagraphStyle(viewModel)),
15210
15453
  paragraphNonInlineSkeDrawings,
15211
15454
  paragraphInlineSkeDrawings,
15212
15455
  skeTablesInParagraph: tableSkeleton ? [{
@@ -15766,6 +16009,22 @@ function TibetanHandler(index, charArray, viewModel, paragraphNode, sectionBreak
15766
16009
  glyphGroup: [createSkeletonWordGlyph(glyph.join(""), config)]
15767
16010
  };
15768
16011
  }
16012
+ function ThaiHandler(index, charArray, viewModel, paragraphNode, sectionBreakConfig, paragraph) {
16013
+ const config = getFontCreateConfig(index, viewModel, paragraphNode, sectionBreakConfig, paragraph);
16014
+ const glyph = [];
16015
+ let step = 0;
16016
+ for (let i = 0; i < charArray.length; i++) {
16017
+ const newChar = charArray[i];
16018
+ if (hasThai(newChar)) {
16019
+ glyph.push(newChar);
16020
+ step++;
16021
+ } else break;
16022
+ }
16023
+ return {
16024
+ step,
16025
+ glyphGroup: [createSkeletonWordGlyph(glyph.join(""), config)]
16026
+ };
16027
+ }
15769
16028
 
15770
16029
  //#endregion
15771
16030
  //#region src/components/docs/layout/block/paragraph/shaping.ts
@@ -15911,6 +16170,11 @@ function shaping(ctx, content, viewModel, paragraphNode, sectionBreakConfig, use
15911
16170
  shapedGlyphs.push(...glyphGroup);
15912
16171
  i += step;
15913
16172
  src = src.substring(step);
16173
+ } else if (hasThai(char)) {
16174
+ const { step, glyphGroup } = ThaiHandler(i, src, viewModel, paragraphNode, sectionBreakConfig, paragraph);
16175
+ shapedGlyphs.push(...glyphGroup);
16176
+ i += step;
16177
+ src = src.substring(step);
15914
16178
  } else {
15915
16179
  const { step, glyphGroup } = otherHandler(i, src, viewModel, paragraphNode, sectionBreakConfig, paragraph);
15916
16180
  shapedGlyphs.push(...glyphGroup);
@@ -16766,28 +17030,45 @@ var DocumentSkeleton = class DocumentSkeleton extends _univerjs_core.Skeleton {
16766
17030
  }
16767
17031
  }
16768
17032
  let exactMatch = null;
16769
- if (skeTables.size > 0) for (const table of skeTables.values()) {
16770
- var _this$_findLiquid, _this$_findLiquid2, _this$_findLiquid9;
16771
- const { top: tableTop, left: tableLeft, rows } = table;
16772
- (_this$_findLiquid = this._findLiquid) === null || _this$_findLiquid === void 0 || _this$_findLiquid.translateSave();
16773
- (_this$_findLiquid2 = this._findLiquid) === null || _this$_findLiquid2 === void 0 || _this$_findLiquid2.translate(tableLeft, tableTop);
16774
- for (const row of rows) {
16775
- var _this$_findLiquid3, _this$_findLiquid4, _this$_findLiquid8;
16776
- const { top: rowTop, cells, isRepeatRow } = row;
16777
- if (isRepeatRow) continue;
16778
- (_this$_findLiquid3 = this._findLiquid) === null || _this$_findLiquid3 === void 0 || _this$_findLiquid3.translateSave();
16779
- (_this$_findLiquid4 = this._findLiquid) === null || _this$_findLiquid4 === void 0 || _this$_findLiquid4.translate(0, rowTop);
16780
- for (const cell of cells) {
16781
- var _this$_findLiquid5, _this$_findLiquid6, _exactMatch3, _this$_findLiquid7;
16782
- const { left: cellLeft } = cell;
17033
+ if (skeTables.size > 0) {
17034
+ var _this$_docViewModel$g, _this$_docViewModel$g2, _this$_docViewModel$g3;
17035
+ const unitId = (_this$_docViewModel$g = (_this$_docViewModel$g2 = (_this$_docViewModel$g3 = this._docViewModel.getDataModel()).getUnitId) === null || _this$_docViewModel$g2 === void 0 ? void 0 : _this$_docViewModel$g2.call(_this$_docViewModel$g3)) !== null && _this$_docViewModel$g !== void 0 ? _this$_docViewModel$g : "";
17036
+ for (const table of skeTables.values()) {
17037
+ var _this$_findLiquid, _this$_findLiquid2, _this$_findLiquid11;
17038
+ const { top: tableTop, left: tableLeft, rows } = table;
17039
+ const sourceTableId = getTableIdAndSliceIndex(table.tableId).tableId;
17040
+ const viewport = getDocsTableRenderViewport(unitId, sourceTableId);
17041
+ (_this$_findLiquid = this._findLiquid) === null || _this$_findLiquid === void 0 || _this$_findLiquid.translateSave();
17042
+ (_this$_findLiquid2 = this._findLiquid) === null || _this$_findLiquid2 === void 0 || _this$_findLiquid2.translate(tableLeft, tableTop);
17043
+ if (viewport && viewport.contentWidth > viewport.viewportWidth) {
17044
+ var _this$_findLiquid4;
17045
+ const visibleLeft = this._findLiquid.x;
17046
+ const visibleRight = visibleLeft + viewport.viewportWidth;
17047
+ if (x < visibleLeft || x > visibleRight) {
17048
+ var _this$_findLiquid3;
17049
+ (_this$_findLiquid3 = this._findLiquid) === null || _this$_findLiquid3 === void 0 || _this$_findLiquid3.translateRestore();
17050
+ continue;
17051
+ }
17052
+ (_this$_findLiquid4 = this._findLiquid) === null || _this$_findLiquid4 === void 0 || _this$_findLiquid4.translate(-viewport.scrollLeft, 0);
17053
+ }
17054
+ for (const row of rows) {
17055
+ var _this$_findLiquid5, _this$_findLiquid6, _this$_findLiquid10;
17056
+ const { top: rowTop, cells, isRepeatRow } = row;
17057
+ if (isRepeatRow) continue;
16783
17058
  (_this$_findLiquid5 = this._findLiquid) === null || _this$_findLiquid5 === void 0 || _this$_findLiquid5.translateSave();
16784
- (_this$_findLiquid6 = this._findLiquid) === null || _this$_findLiquid6 === void 0 || _this$_findLiquid6.translate(cellLeft, 0);
16785
- exactMatch = (_exactMatch3 = exactMatch) !== null && _exactMatch3 !== void 0 ? _exactMatch3 : this._collectNearestNode(cell, 3, cell, segmentId, pi, cache, x, y, pageLength, nestLevel + 1);
16786
- (_this$_findLiquid7 = this._findLiquid) === null || _this$_findLiquid7 === void 0 || _this$_findLiquid7.translateRestore();
17059
+ (_this$_findLiquid6 = this._findLiquid) === null || _this$_findLiquid6 === void 0 || _this$_findLiquid6.translate(0, rowTop);
17060
+ for (const cell of cells) {
17061
+ var _this$_findLiquid7, _this$_findLiquid8, _exactMatch3, _this$_findLiquid9;
17062
+ const { left: cellLeft } = cell;
17063
+ (_this$_findLiquid7 = this._findLiquid) === null || _this$_findLiquid7 === void 0 || _this$_findLiquid7.translateSave();
17064
+ (_this$_findLiquid8 = this._findLiquid) === null || _this$_findLiquid8 === void 0 || _this$_findLiquid8.translate(cellLeft, 0);
17065
+ exactMatch = (_exactMatch3 = exactMatch) !== null && _exactMatch3 !== void 0 ? _exactMatch3 : this._collectNearestNode(cell, 3, cell, segmentId, pi, cache, x, y, pageLength, nestLevel + 1);
17066
+ (_this$_findLiquid9 = this._findLiquid) === null || _this$_findLiquid9 === void 0 || _this$_findLiquid9.translateRestore();
17067
+ }
17068
+ (_this$_findLiquid10 = this._findLiquid) === null || _this$_findLiquid10 === void 0 || _this$_findLiquid10.translateRestore();
16787
17069
  }
16788
- (_this$_findLiquid8 = this._findLiquid) === null || _this$_findLiquid8 === void 0 || _this$_findLiquid8.translateRestore();
17070
+ (_this$_findLiquid11 = this._findLiquid) === null || _this$_findLiquid11 === void 0 || _this$_findLiquid11.translateRestore();
16789
17071
  }
16790
- (_this$_findLiquid9 = this._findLiquid) === null || _this$_findLiquid9 === void 0 || _this$_findLiquid9.translateRestore();
16791
17072
  }
16792
17073
  if (exactMatch) {
16793
17074
  this._findLiquid.translateRestore();
@@ -17072,10 +17353,12 @@ function createDocumentModelWithStyle(content, textStyle, config = {}) {
17072
17353
  width: Number.POSITIVE_INFINITY,
17073
17354
  height: Number.POSITIVE_INFINITY
17074
17355
  },
17356
+ documentFlavor: _univerjs_core.DocumentFlavor.UNSPECIFIED,
17075
17357
  marginTop,
17076
17358
  marginBottom,
17077
17359
  marginRight,
17078
17360
  marginLeft,
17361
+ paragraphLineGapDefault: 0,
17079
17362
  renderConfig: {
17080
17363
  horizontalAlign,
17081
17364
  verticalAlign,
@@ -18974,8 +19257,9 @@ var SpreadsheetRowHeader = class extends SpreadsheetHeader {
18974
19257
  const segment = spreadsheetSkeleton.rowColumnSegment;
18975
19258
  if (!segment) return;
18976
19259
  if (segment.startRow === -1 && segment.endRow === -1) return;
18977
- const { columnHeaderHeight } = spreadsheetSkeleton;
18978
- ctx.translateWithPrecision(0, columnHeaderHeight);
19260
+ const { columnHeaderHeightAndMarginTop, rowHeaderWidth, rowHeaderWidthAndMarginLeft } = spreadsheetSkeleton;
19261
+ const marginLeft = rowHeaderWidthAndMarginLeft - rowHeaderWidth;
19262
+ ctx.translateWithPrecision(marginLeft, columnHeaderHeightAndMarginTop);
18979
19263
  const extensions = this.getExtensionsByOrder();
18980
19264
  for (const extension of extensions) extension.draw(ctx, parentScale, spreadsheetSkeleton);
18981
19265
  }
@@ -18983,8 +19267,9 @@ var SpreadsheetRowHeader = class extends SpreadsheetHeader {
18983
19267
  const oCoord = this.getInverseCoord(coord);
18984
19268
  const skeleton = this.getSkeleton();
18985
19269
  if (!skeleton) return false;
18986
- const { rowHeaderWidth, columnHeaderHeight } = skeleton;
18987
- if (oCoord.x >= 0 && oCoord.x <= rowHeaderWidth && oCoord.y > columnHeaderHeight) return true;
19270
+ const { rowHeaderWidth, rowHeaderWidthAndMarginLeft, columnHeaderHeightAndMarginTop } = skeleton;
19271
+ const marginLeft = rowHeaderWidthAndMarginLeft - rowHeaderWidth;
19272
+ if (oCoord.x >= marginLeft && oCoord.x <= rowHeaderWidthAndMarginLeft && oCoord.y > columnHeaderHeightAndMarginTop) return true;
18988
19273
  return false;
18989
19274
  }
18990
19275
  _initialDefaultExtension() {
@@ -21539,7 +21824,8 @@ DocumentsSpanAndLineExtensionRegistry.add(new Line());
21539
21824
 
21540
21825
  //#endregion
21541
21826
  //#region src/components/docs/document.ts
21542
- const DEFAULT_BORDER_COLOR = { color: { rgb: "#dee0e3" } };
21827
+ const DEFAULT_BORDER_COLOR = { color: { rgb: "#c7c9cc" } };
21828
+ const TABLE_VIEWPORT_BORDER_CLIP_PADDING = 2;
21543
21829
  var Documents = class Documents extends DocComponent {
21544
21830
  constructor(oKey, documentSkeleton, config) {
21545
21831
  super(oKey, documentSkeleton, config);
@@ -21722,29 +22008,62 @@ var Documents = class Documents extends DocComponent {
21722
22008
  }
21723
22009
  }
21724
22010
  _drawTable(ctx, page, skeTables, extensions, backgroundExtension, glyphExtensionsExcludeBackground, alignOffsetNoAngle, centerAngle, vertexAngle, renderConfig, parentScale) {
21725
- for (const [_tableId, tableSkeleton] of skeTables) {
21726
- var _this$_drawLiquid, _this$_drawLiquid2, _this$_drawLiquid9;
22011
+ const drawLiquid = this._drawLiquid;
22012
+ if (drawLiquid == null) return;
22013
+ const renderUnitId = this._getRenderUnitId();
22014
+ for (const [tableId, tableSkeleton] of skeTables) {
21727
22015
  const { top: tableTop, left: tableLeft, rows } = tableSkeleton;
21728
- (_this$_drawLiquid = this._drawLiquid) === null || _this$_drawLiquid === void 0 || _this$_drawLiquid.translateSave();
21729
- (_this$_drawLiquid2 = this._drawLiquid) === null || _this$_drawLiquid2 === void 0 || _this$_drawLiquid2.translate(tableLeft, tableTop);
22016
+ const sourceTableId = getTableIdAndSliceIndex(tableId).tableId;
22017
+ const viewport = this._getTableViewport(page, tableSkeleton, renderUnitId, sourceTableId);
22018
+ drawLiquid.translateSave();
22019
+ drawLiquid.translate(tableLeft, tableTop);
22020
+ if (viewport && viewport.contentWidth > viewport.viewportWidth) {
22021
+ const { x, y } = drawLiquid;
22022
+ ctx.save();
22023
+ ctx.beginPath();
22024
+ ctx.rectByPrecision(x + page.marginLeft - TABLE_VIEWPORT_BORDER_CLIP_PADDING, y + page.marginTop - TABLE_VIEWPORT_BORDER_CLIP_PADDING, viewport.viewportWidth + TABLE_VIEWPORT_BORDER_CLIP_PADDING * 2, tableSkeleton.height + TABLE_VIEWPORT_BORDER_CLIP_PADDING * 2);
22025
+ ctx.closePath();
22026
+ ctx.clip();
22027
+ drawLiquid.translate(-viewport.scrollLeft, 0);
22028
+ }
21730
22029
  for (const row of rows) {
21731
- var _this$_drawLiquid3, _this$_drawLiquid4, _this$_drawLiquid8;
21732
22030
  const { top: rowTop, cells } = row;
21733
- (_this$_drawLiquid3 = this._drawLiquid) === null || _this$_drawLiquid3 === void 0 || _this$_drawLiquid3.translateSave();
21734
- (_this$_drawLiquid4 = this._drawLiquid) === null || _this$_drawLiquid4 === void 0 || _this$_drawLiquid4.translate(0, rowTop);
22031
+ drawLiquid.translateSave();
22032
+ drawLiquid.translate(0, rowTop);
21735
22033
  for (const cell of cells) {
21736
- var _this$_drawLiquid5, _this$_drawLiquid6, _this$_drawLiquid7;
22034
+ if (cell.isMergedCellCovered) continue;
21737
22035
  const { left: cellLeft } = cell;
21738
- (_this$_drawLiquid5 = this._drawLiquid) === null || _this$_drawLiquid5 === void 0 || _this$_drawLiquid5.translateSave();
21739
- (_this$_drawLiquid6 = this._drawLiquid) === null || _this$_drawLiquid6 === void 0 || _this$_drawLiquid6.translate(cellLeft, 0);
22036
+ drawLiquid.translateSave();
22037
+ drawLiquid.translate(cellLeft, 0);
21740
22038
  this._drawTableCell(ctx, page, cell, extensions, backgroundExtension, glyphExtensionsExcludeBackground, alignOffsetNoAngle, centerAngle, vertexAngle, renderConfig, parentScale);
21741
- (_this$_drawLiquid7 = this._drawLiquid) === null || _this$_drawLiquid7 === void 0 || _this$_drawLiquid7.translateRestore();
22039
+ drawLiquid.translateRestore();
21742
22040
  }
21743
- (_this$_drawLiquid8 = this._drawLiquid) === null || _this$_drawLiquid8 === void 0 || _this$_drawLiquid8.translateRestore();
22041
+ drawLiquid.translateRestore();
21744
22042
  }
21745
- (_this$_drawLiquid9 = this._drawLiquid) === null || _this$_drawLiquid9 === void 0 || _this$_drawLiquid9.translateRestore();
22043
+ if (viewport && viewport.contentWidth > viewport.viewportWidth) ctx.restore();
22044
+ drawLiquid.translateRestore();
21746
22045
  }
21747
22046
  }
22047
+ _getTableViewport(page, tableSkeleton, unitId, tableId) {
22048
+ const viewport = getDocsTableRenderViewport(unitId, tableId);
22049
+ if (viewport) return viewport;
22050
+ const { pageWidth, marginLeft = 0, marginRight = 0 } = page;
22051
+ if (!Number.isFinite(pageWidth)) return null;
22052
+ const viewportWidth = Math.max(0, pageWidth - marginLeft - marginRight - tableSkeleton.left);
22053
+ if (viewportWidth <= 0 || tableSkeleton.width <= viewportWidth) return null;
22054
+ return {
22055
+ contentWidth: tableSkeleton.width,
22056
+ scrollLeft: 0,
22057
+ viewportWidth
22058
+ };
22059
+ }
22060
+ _getRenderUnitId() {
22061
+ var _skeleton$getViewMode, _viewModel$getDataMod, _dataModel$getUnitId, _dataModel$getUnitId2;
22062
+ const skeleton = this.getSkeleton();
22063
+ const viewModel = skeleton === null || skeleton === void 0 || (_skeleton$getViewMode = skeleton.getViewModel) === null || _skeleton$getViewMode === void 0 ? void 0 : _skeleton$getViewMode.call(skeleton);
22064
+ const dataModel = viewModel === null || viewModel === void 0 || (_viewModel$getDataMod = viewModel.getDataModel) === null || _viewModel$getDataMod === void 0 ? void 0 : _viewModel$getDataMod.call(viewModel);
22065
+ return (_dataModel$getUnitId = dataModel === null || dataModel === void 0 || (_dataModel$getUnitId2 = dataModel.getUnitId) === null || _dataModel$getUnitId2 === void 0 ? void 0 : _dataModel$getUnitId2.call(dataModel)) !== null && _dataModel$getUnitId !== void 0 ? _dataModel$getUnitId : this.oKey;
22066
+ }
21748
22067
  _drawBorderBottom(ctx, page, line, left = 0, top = 0) {
21749
22068
  var _line$borderBottom$pa, _line$borderBottom, _line$borderBottom$co, _line$borderBottom2;
21750
22069
  if (this._drawLiquid == null) return;
@@ -21854,60 +22173,68 @@ var Documents = class Documents extends DocComponent {
21854
22173
  ctx.restore();
21855
22174
  }
21856
22175
  _drawTableCellBordersAndBg(ctx, page, cell) {
21857
- var _borderLeft$color$rgb, _borderTop$color$rgb, _borderRight$color$rg, _borderBottom$color$r;
22176
+ var _rowSke$index, _cellSource$backgroun;
21858
22177
  const { marginLeft, marginTop } = page;
21859
22178
  const { pageWidth, pageHeight } = cell;
21860
22179
  const rowSke = cell.parent;
21861
22180
  const index = rowSke.cells.indexOf(cell);
21862
- const { borderTop = DEFAULT_BORDER_COLOR, borderBottom = DEFAULT_BORDER_COLOR, borderLeft = DEFAULT_BORDER_COLOR, borderRight = DEFAULT_BORDER_COLOR, backgroundColor } = rowSke.rowSource.tableCells[index];
22181
+ if (index < 0) return;
22182
+ const cellSource = rowSke.rowSource.tableCells[index];
22183
+ const tableSke = rowSke.parent;
22184
+ const rowIndexInTable = tableSke === null || tableSke === void 0 ? void 0 : tableSke.rows.indexOf(rowSke);
22185
+ const rowIndex = rowIndexInTable == null || rowIndexInTable < 0 ? (_rowSke$index = rowSke.index) !== null && _rowSke$index !== void 0 ? _rowSke$index : 0 : rowIndexInTable;
22186
+ if (!cellSource || cellSource.rowSpan === 0 || cellSource.columnSpan === 0) return;
21863
22187
  if (this._drawLiquid == null) return;
21864
22188
  let { x, y } = this._drawLiquid;
21865
22189
  x += marginLeft;
21866
22190
  y += marginTop;
21867
- if (backgroundColor && backgroundColor.rgb) {
22191
+ if ((_cellSource$backgroun = cellSource.backgroundColor) === null || _cellSource$backgroun === void 0 ? void 0 : _cellSource$backgroun.rgb) {
21868
22192
  ctx.save();
21869
- ctx.fillStyle = backgroundColor.rgb;
22193
+ ctx.fillStyle = cellSource.backgroundColor.rgb;
21870
22194
  ctx.fillRectByPrecision(x, y, pageWidth, pageHeight);
21871
22195
  ctx.restore();
21872
22196
  }
21873
- ctx.save();
21874
- ctx.setLineWidthByPrecision(1);
21875
- ctx.save();
21876
- ctx.strokeStyle = (_borderLeft$color$rgb = borderLeft.color.rgb) !== null && _borderLeft$color$rgb !== void 0 ? _borderLeft$color$rgb : DEFAULT_BORDER_COLOR.color.rgb;
21877
- drawLineByBorderType(ctx, "l", 0, {
21878
- startX: x,
21879
- startY: y,
21880
- endX: x + pageWidth,
21881
- endY: y + pageHeight
21882
- });
21883
- ctx.restore();
21884
- ctx.save();
21885
- ctx.strokeStyle = (_borderTop$color$rgb = borderTop.color.rgb) !== null && _borderTop$color$rgb !== void 0 ? _borderTop$color$rgb : DEFAULT_BORDER_COLOR.color.rgb;
21886
- drawLineByBorderType(ctx, "t", 0, {
21887
- startX: x,
21888
- startY: y,
21889
- endX: x + pageWidth,
21890
- endY: y + pageHeight
21891
- });
21892
- ctx.restore();
21893
- ctx.save();
21894
- ctx.strokeStyle = (_borderRight$color$rg = borderRight.color.rgb) !== null && _borderRight$color$rg !== void 0 ? _borderRight$color$rg : DEFAULT_BORDER_COLOR.color.rgb;
21895
- drawLineByBorderType(ctx, "r", 0, {
22197
+ const position = {
21896
22198
  startX: x,
21897
22199
  startY: y,
21898
22200
  endX: x + pageWidth,
21899
22201
  endY: y + pageHeight
21900
- });
21901
- ctx.restore();
22202
+ };
22203
+ const rightCellSource = this._getTableCellSource(rowSke, index + 1);
22204
+ const bottomCellSource = tableSke ? this._getTableCellSource(tableSke.rows[rowIndex + 1], index) : void 0;
22205
+ this._drawTableCellBorder(ctx, this._resolveTableCellBorder(cellSource.borderRight, rightCellSource === null || rightCellSource === void 0 ? void 0 : rightCellSource.borderLeft), "r", position);
22206
+ this._drawTableCellBorder(ctx, this._resolveTableCellBorder(cellSource.borderBottom, bottomCellSource === null || bottomCellSource === void 0 ? void 0 : bottomCellSource.borderTop), "b", position);
22207
+ if (rowIndex <= 0) this._drawTableCellBorder(ctx, this._resolveTableCellBorder(cellSource.borderTop), "t", position);
22208
+ if (index <= 0) this._drawTableCellBorder(ctx, this._resolveTableCellBorder(cellSource.borderLeft), "l", position);
22209
+ }
22210
+ _getTableCellSource(row, column) {
22211
+ var _row$rowSource$tableC;
22212
+ return (_row$rowSource$tableC = row === null || row === void 0 ? void 0 : row.rowSource.tableCells[column]) !== null && _row$rowSource$tableC !== void 0 ? _row$rowSource$tableC : null;
22213
+ }
22214
+ _resolveTableCellBorder(primary, secondary) {
22215
+ if (this._isDrawableTableCellBorder(primary)) return primary;
22216
+ if (this._isDrawableTableCellBorder(secondary)) return secondary;
22217
+ if (primary || secondary) return null;
22218
+ return DEFAULT_BORDER_COLOR;
22219
+ }
22220
+ _isDrawableTableCellBorder(border) {
22221
+ var _border$width$v, _border$width, _border$color$rgb, _border$color;
22222
+ if (!border) return false;
22223
+ const lineWidth = (_border$width$v = (_border$width = border.width) === null || _border$width === void 0 ? void 0 : _border$width.v) !== null && _border$width$v !== void 0 ? _border$width$v : 1;
22224
+ const color = (_border$color$rgb = (_border$color = border.color) === null || _border$color === void 0 ? void 0 : _border$color.rgb) !== null && _border$color$rgb !== void 0 ? _border$color$rgb : DEFAULT_BORDER_COLOR.color.rgb;
22225
+ return lineWidth > 0 && color !== "transparent";
22226
+ }
22227
+ _drawTableCellBorder(ctx, border, type, position) {
22228
+ var _border$width$v2, _border$width2, _border$color$rgb2, _border$color2;
22229
+ if (!border) return;
22230
+ const lineWidth = (_border$width$v2 = (_border$width2 = border.width) === null || _border$width2 === void 0 ? void 0 : _border$width2.v) !== null && _border$width$v2 !== void 0 ? _border$width$v2 : 1;
22231
+ const color = (_border$color$rgb2 = (_border$color2 = border.color) === null || _border$color2 === void 0 ? void 0 : _border$color2.rgb) !== null && _border$color$rgb2 !== void 0 ? _border$color$rgb2 : DEFAULT_BORDER_COLOR.color.rgb;
22232
+ if (lineWidth <= 0 || color === "transparent") return;
21902
22233
  ctx.save();
21903
- ctx.strokeStyle = (_borderBottom$color$r = borderBottom.color.rgb) !== null && _borderBottom$color$r !== void 0 ? _borderBottom$color$r : DEFAULT_BORDER_COLOR.color.rgb;
21904
- drawLineByBorderType(ctx, "b", 0, {
21905
- startX: x,
21906
- startY: y,
21907
- endX: x + pageWidth,
21908
- endY: y + pageHeight
21909
- });
21910
- ctx.restore();
22234
+ ctx.setLineWidthByPrecision(lineWidth);
22235
+ setTableCellBorderDash(ctx, border.dashStyle);
22236
+ ctx.strokeStyle = color;
22237
+ drawLineByBorderType(ctx, type, 0, position);
21911
22238
  ctx.restore();
21912
22239
  }
21913
22240
  _drawHeaderFooter(page, ctx, extensions, backgroundExtension, glyphExtensionsExcludeBackground, alignOffsetNoAngle, centerAngle, vertexAngle, renderConfig, parentScale, parentPage, isHeader = true) {
@@ -22038,6 +22365,17 @@ var Documents = class Documents extends DocComponent {
22038
22365
  });
22039
22366
  }
22040
22367
  };
22368
+ function setTableCellBorderDash(ctx, dashStyle) {
22369
+ if (dashStyle === _univerjs_core.DashStyleType.DOT) {
22370
+ ctx.setLineDash([2]);
22371
+ return;
22372
+ }
22373
+ if (dashStyle === _univerjs_core.DashStyleType.DASH) {
22374
+ ctx.setLineDash([6]);
22375
+ return;
22376
+ }
22377
+ ctx.setLineDash([0]);
22378
+ }
22041
22379
 
22042
22380
  //#endregion
22043
22381
  //#region src/components/sheets/spreadsheet.ts
@@ -22144,8 +22482,8 @@ var Spreadsheet = class extends SheetComponent {
22144
22482
  const oCoord = this.getInverseCoord(coord);
22145
22483
  const skeleton = this.getSkeleton();
22146
22484
  if (!skeleton) return false;
22147
- const { rowHeaderWidth, columnHeaderHeight } = skeleton;
22148
- if (oCoord.x > rowHeaderWidth && oCoord.y > columnHeaderHeight) return true;
22485
+ const { rowHeaderWidthAndMarginLeft, columnHeaderHeightAndMarginTop } = skeleton;
22486
+ if (oCoord.x > rowHeaderWidthAndMarginLeft && oCoord.y > columnHeaderHeightAndMarginTop) return true;
22149
22487
  return false;
22150
22488
  }
22151
22489
  getNoMergeCellPositionByIndex(rowIndex, columnIndex) {
@@ -22213,7 +22551,7 @@ var Spreadsheet = class extends SheetComponent {
22213
22551
  }
22214
22552
  renderByViewports(mainCtx, viewportInfo, spreadsheetSkeleton) {
22215
22553
  const { diffBounds, diffX, diffY, viewPortPosition, cacheCanvas, leftOrigin, topOrigin, bufferEdgeX, bufferEdgeY, isDirty: isViewportDirty, isForceDirty: isViewportForceDirty } = viewportInfo;
22216
- const { rowHeaderWidth, columnHeaderHeight } = spreadsheetSkeleton;
22554
+ const { rowHeaderWidthAndMarginLeft, columnHeaderHeightAndMarginTop } = spreadsheetSkeleton;
22217
22555
  const { a: scaleX = 1, d: scaleY = 1 } = mainCtx.getTransform();
22218
22556
  const bufferEdgeSizeX = bufferEdgeX * scaleX / window.devicePixelRatio;
22219
22557
  const bufferEdgeSizeY = bufferEdgeY * scaleY / window.devicePixelRatio;
@@ -22221,8 +22559,10 @@ var Spreadsheet = class extends SheetComponent {
22221
22559
  cacheCtx.save();
22222
22560
  const isForceDirty = isViewportForceDirty || this.isForceDirty();
22223
22561
  const isDirty = isViewportDirty || this.isDirty();
22224
- if (diffBounds.length === 0 || diffX === 0 && diffY === 0 || isForceDirty || isDirty) {
22225
- if (isDirty || isForceDirty) {
22562
+ const isScrollJumpOutsideCache = Math.abs(diffX) * scaleX >= cacheCanvas.getWidth() || Math.abs(diffY) * scaleY >= cacheCanvas.getHeight();
22563
+ const shouldRefreshCache = isDirty || isForceDirty || isScrollJumpOutsideCache;
22564
+ if (diffBounds.length === 0 || diffX === 0 && diffY === 0 || shouldRefreshCache) {
22565
+ if (shouldRefreshCache) {
22226
22566
  this.addRenderTagToScene("scrolling", false);
22227
22567
  this.refreshCacheCanvas(viewportInfo, {
22228
22568
  cacheCanvas,
@@ -22246,20 +22586,20 @@ var Spreadsheet = class extends SheetComponent {
22246
22586
  bufferEdgeY,
22247
22587
  scaleX,
22248
22588
  scaleY,
22249
- columnHeaderHeight,
22250
- rowHeaderWidth
22589
+ columnHeaderHeightAndMarginTop,
22590
+ rowHeaderWidthAndMarginLeft
22251
22591
  });
22252
22592
  }
22253
22593
  const sourceLeft = bufferEdgeSizeX * Math.min(1, window.devicePixelRatio);
22254
22594
  const sourceTop = bufferEdgeSizeY * Math.min(1, window.devicePixelRatio);
22255
22595
  const { left, top, right, bottom } = viewPortPosition;
22256
- const dw = right - left + rowHeaderWidth;
22257
- const dh = bottom - top + columnHeaderHeight;
22596
+ const dw = right - left + rowHeaderWidthAndMarginLeft;
22597
+ const dh = bottom - top + columnHeaderHeightAndMarginTop;
22258
22598
  this._applyCache(cacheCanvas, mainCtx, sourceLeft, sourceTop, dw, dh, left, top, dw, dh);
22259
22599
  cacheCtx.restore();
22260
22600
  }
22261
22601
  paintNewAreaForScrolling(viewportInfo, param) {
22262
- const { cacheCanvas, cacheCtx, mainCtx, topOrigin, leftOrigin, bufferEdgeX, bufferEdgeY, scaleX, scaleY, columnHeaderHeight, rowHeaderWidth } = param;
22602
+ const { cacheCanvas, cacheCtx, mainCtx, topOrigin, leftOrigin, bufferEdgeX, bufferEdgeY, scaleX, scaleY, columnHeaderHeightAndMarginTop, rowHeaderWidthAndMarginLeft } = param;
22263
22603
  const { shouldCacheUpdate, diffCacheBounds, diffX, diffY } = viewportInfo;
22264
22604
  cacheCtx.save();
22265
22605
  cacheCtx.setTransform(1, 0, 0, 1, 0, 0);
@@ -22272,8 +22612,8 @@ var Spreadsheet = class extends SheetComponent {
22272
22612
  cacheCtx.translateWithPrecision(m.e / m.a - leftOrigin + bufferEdgeX, m.f / m.d - topOrigin + bufferEdgeY);
22273
22613
  if (shouldCacheUpdate) for (const diffBound of diffCacheBounds) {
22274
22614
  const { left: diffLeft, right: diffRight, bottom: diffBottom, top: diffTop } = diffBound;
22275
- const x = diffLeft - rowHeaderWidth;
22276
- const y = diffTop - columnHeaderHeight;
22615
+ const x = diffLeft - rowHeaderWidthAndMarginLeft;
22616
+ const y = diffTop - columnHeaderHeightAndMarginTop;
22277
22617
  const w = diffRight - diffLeft;
22278
22618
  const h = diffBottom - diffTop;
22279
22619
  cacheCtx.clearRectByPrecision(x, y, w, h);
@@ -22319,9 +22659,9 @@ var Spreadsheet = class extends SheetComponent {
22319
22659
  if (!segment) return;
22320
22660
  if (segment.startRow === -1 && segment.endRow === -1 || segment.startColumn === -1 && segment.endColumn === -1) return;
22321
22661
  mainCtx.save();
22322
- const { rowHeaderWidth, columnHeaderHeight } = spreadsheetSkeleton;
22323
- mainCtx.translateWithPrecision(rowHeaderWidth, columnHeaderHeight);
22324
- (_this$getScene = this.getScene()) === null || _this$getScene === void 0 || _this$getScene.updateTransformerZero(spreadsheetSkeleton.rowHeaderWidth, spreadsheetSkeleton.columnHeaderHeight);
22662
+ const { rowHeaderWidthAndMarginLeft, columnHeaderHeightAndMarginTop } = spreadsheetSkeleton;
22663
+ mainCtx.translateWithPrecision(rowHeaderWidthAndMarginLeft, columnHeaderHeightAndMarginTop);
22664
+ (_this$getScene = this.getScene()) === null || _this$getScene === void 0 || _this$getScene.updateTransformerZero(rowHeaderWidthAndMarginLeft, columnHeaderHeightAndMarginTop);
22325
22665
  const { viewportKey } = viewportInfo;
22326
22666
  if (sheetContentViewportKeys.includes(viewportKey)) if (viewportInfo && viewportInfo.cacheCanvas) this.renderByViewports(mainCtx, viewportInfo, spreadsheetSkeleton);
22327
22667
  else this._draw(mainCtx, viewportInfo);
@@ -23238,29 +23578,49 @@ var Slide = class extends SceneViewer {
23238
23578
  //#region src/components/docs/doc-background.ts
23239
23579
  const PAGE_STROKE_COLOR = "rgba(198, 198, 198, 1)";
23240
23580
  const PAGE_FILL_COLOR = "rgba(255, 255, 255, 1)";
23581
+ const DOCS_WORKSPACE_FILL_COLOR = "#fafafa";
23241
23582
  const MARGIN_STROKE_COLOR = "rgba(158, 158, 158, 1)";
23242
23583
  var DocBackground = class DocBackground extends DocComponent {
23243
23584
  constructor(oKey, documentSkeleton, config) {
23244
23585
  super(oKey, documentSkeleton, config);
23245
23586
  _defineProperty(this, "_drawLiquid", void 0);
23587
+ _defineProperty(this, "_backgroundFillColor", void 0);
23588
+ _defineProperty(this, "_pageFillColor", void 0);
23589
+ _defineProperty(this, "_pageStrokeColor", void 0);
23590
+ _defineProperty(this, "_marginStrokeColor", void 0);
23246
23591
  this._drawLiquid = new Liquid();
23592
+ this._backgroundFillColor = config === null || config === void 0 ? void 0 : config.backgroundFillColor;
23593
+ this._pageFillColor = config === null || config === void 0 ? void 0 : config.pageFillColor;
23594
+ this._pageStrokeColor = config === null || config === void 0 ? void 0 : config.pageStrokeColor;
23595
+ this._marginStrokeColor = config === null || config === void 0 ? void 0 : config.marginStrokeColor;
23247
23596
  this.makeDirty(true);
23248
23597
  }
23249
23598
  static create(oKey, documentSkeleton, config) {
23250
23599
  return new DocBackground(oKey, documentSkeleton, config);
23251
23600
  }
23601
+ setFillColors(backgroundFillColor, pageFillColor, pageStrokeColor, marginStrokeColor) {
23602
+ if (this._backgroundFillColor === backgroundFillColor && this._pageFillColor === pageFillColor && this._pageStrokeColor === pageStrokeColor && this._marginStrokeColor === marginStrokeColor) return;
23603
+ this._backgroundFillColor = backgroundFillColor;
23604
+ this._pageFillColor = pageFillColor;
23605
+ this._pageStrokeColor = pageStrokeColor;
23606
+ this._marginStrokeColor = marginStrokeColor;
23607
+ this.makeDirty(true);
23608
+ }
23252
23609
  draw(ctx, bounds) {
23253
- var _this$getSkeleton, _this$getSkeleton2;
23610
+ var _this$getSkeleton, _this$getSkeleton2, _this$_backgroundFill;
23254
23611
  const skeletonData = (_this$getSkeleton = this.getSkeleton()) === null || _this$getSkeleton === void 0 ? void 0 : _this$getSkeleton.getSkeletonData();
23255
23612
  const docDataModel = (_this$getSkeleton2 = this.getSkeleton()) === null || _this$getSkeleton2 === void 0 ? void 0 : _this$getSkeleton2.getViewModel().getDataModel();
23256
23613
  if (skeletonData == null || docDataModel == null) return;
23257
23614
  const { documentFlavor } = docDataModel.getSnapshot().documentStyle;
23258
- if (documentFlavor !== _univerjs_core.DocumentFlavor.TRADITIONAL) return;
23615
+ const workspaceFill = (_this$_backgroundFill = this._backgroundFillColor) !== null && _this$_backgroundFill !== void 0 ? _this$_backgroundFill : documentFlavor === _univerjs_core.DocumentFlavor.MODERN ? PAGE_FILL_COLOR : DOCS_WORKSPACE_FILL_COLOR;
23616
+ this._drawWorkspaceBackground(ctx, workspaceFill, bounds);
23617
+ if (documentFlavor === _univerjs_core.DocumentFlavor.MODERN) return;
23259
23618
  this._drawLiquid.reset();
23260
23619
  const { pages } = skeletonData;
23261
23620
  let pageTop = 0;
23262
23621
  let pageLeft = 0;
23263
23622
  for (let i = 0, len = pages.length; i < len; i++) {
23623
+ var _this$_pageStrokeColo, _this$_pageFillColor, _this$_marginStrokeCo;
23264
23624
  const page = pages[i];
23265
23625
  if (this.isSkipByDiffBounds(page, pageTop, pageLeft, bounds)) {
23266
23626
  const { x, y } = this._drawLiquid.translatePage(page, this.pageLayoutType, this.pageMarginLeft, this.pageMarginTop);
@@ -23275,8 +23635,8 @@ var DocBackground = class DocBackground extends DocComponent {
23275
23635
  width: pageWidth !== null && pageWidth !== void 0 ? pageWidth : width,
23276
23636
  height: pageHeight !== null && pageHeight !== void 0 ? pageHeight : height,
23277
23637
  strokeWidth: 1,
23278
- stroke: PAGE_STROKE_COLOR,
23279
- fill: PAGE_FILL_COLOR,
23638
+ stroke: (_this$_pageStrokeColo = this._pageStrokeColor) !== null && _this$_pageStrokeColo !== void 0 ? _this$_pageStrokeColo : PAGE_STROKE_COLOR,
23639
+ fill: (_this$_pageFillColor = this._pageFillColor) !== null && _this$_pageFillColor !== void 0 ? _this$_pageFillColor : PAGE_FILL_COLOR,
23280
23640
  zIndex: 3
23281
23641
  };
23282
23642
  Rect.drawWith(ctx, backgroundOptions);
@@ -23333,7 +23693,7 @@ var DocBackground = class DocBackground extends DocComponent {
23333
23693
  }
23334
23694
  ],
23335
23695
  strokeWidth: 1.5,
23336
- stroke: MARGIN_STROKE_COLOR
23696
+ stroke: (_this$_marginStrokeCo = this._marginStrokeColor) !== null && _this$_marginStrokeCo !== void 0 ? _this$_marginStrokeCo : MARGIN_STROKE_COLOR
23337
23697
  };
23338
23698
  Path.drawWith(ctx, marginIdentification);
23339
23699
  ctx.restore();
@@ -23342,6 +23702,24 @@ var DocBackground = class DocBackground extends DocComponent {
23342
23702
  pageTop += y;
23343
23703
  }
23344
23704
  }
23705
+ _drawWorkspaceBackground(ctx, fill, bounds) {
23706
+ var _bounds$cacheBound, _visibleBound$left, _visibleBound$top;
23707
+ const visibleBound = (_bounds$cacheBound = bounds === null || bounds === void 0 ? void 0 : bounds.cacheBound) !== null && _bounds$cacheBound !== void 0 ? _bounds$cacheBound : bounds === null || bounds === void 0 ? void 0 : bounds.viewBound;
23708
+ const left = (_visibleBound$left = visibleBound === null || visibleBound === void 0 ? void 0 : visibleBound.left) !== null && _visibleBound$left !== void 0 ? _visibleBound$left : 0;
23709
+ const top = (_visibleBound$top = visibleBound === null || visibleBound === void 0 ? void 0 : visibleBound.top) !== null && _visibleBound$top !== void 0 ? _visibleBound$top : 0;
23710
+ const width = visibleBound == null ? this.width : visibleBound.right - visibleBound.left;
23711
+ const height = visibleBound == null ? this.height : visibleBound.bottom - visibleBound.top;
23712
+ if (width <= 0 || height <= 0) return;
23713
+ ctx.save();
23714
+ ctx.translate(left, top);
23715
+ Rect.drawWith(ctx, {
23716
+ width,
23717
+ height,
23718
+ fill,
23719
+ zIndex: 0
23720
+ });
23721
+ ctx.restore();
23722
+ }
23345
23723
  changeSkeleton(newSkeleton) {
23346
23724
  this.setSkeleton(newSkeleton);
23347
23725
  return this;
@@ -24458,14 +24836,13 @@ let Engine = class Engine extends _univerjs_core.Disposable {
24458
24836
  }
24459
24837
  _getPassive() {
24460
24838
  let passiveSupported = false;
24461
- const noop = () => {};
24462
24839
  try {
24463
24840
  const options = { passive: { get() {
24464
24841
  passiveSupported = true;
24465
24842
  } } };
24466
24843
  const canvasEle = this.getCanvasElement();
24467
- canvasEle.addEventListener("test", noop, options);
24468
- canvasEle.removeEventListener("test", noop, options);
24844
+ canvasEle.addEventListener("test", _univerjs_core.noop, options);
24845
+ canvasEle.removeEventListener("test", _univerjs_core.noop, options);
24469
24846
  } catch (e) {}
24470
24847
  return passiveSupported;
24471
24848
  }
@@ -24492,7 +24869,7 @@ Engine = __decorate([__decorateParam(2, ICanvasColorService)], Engine);
24492
24869
  //#endregion
24493
24870
  //#region package.json
24494
24871
  var name = "@univerjs/engine-render";
24495
- var version = "0.23.0";
24872
+ var version = "0.24.0-insiders.20260528-29f582d";
24496
24873
 
24497
24874
  //#endregion
24498
24875
  //#region src/config/config.ts
@@ -27576,6 +27953,7 @@ function subtractViewportRange(range1, range2) {
27576
27953
  //#endregion
27577
27954
  //#region src/viewport.ts
27578
27955
  const MOUSE_WHEEL_SPEED_SMOOTHING_FACTOR = 3;
27956
+ const WHEEL_CROSS_AXIS_LOCK_RATIO = 2;
27579
27957
  var Viewport = class {
27580
27958
  constructor(viewportKey, scene, props) {
27581
27959
  var _this$scene$getEngine;
@@ -28219,11 +28597,22 @@ var Viewport = class {
28219
28597
  let offsetX = 0;
28220
28598
  let offsetY = 0;
28221
28599
  const allWidth = this._scene.width;
28222
- offsetX = (this.width || 1) / allWidth * evt.deltaX;
28600
+ const viewWidth = this.width || 1;
28601
+ const scaleX = Math.abs(this._scene.scaleX) || 1;
28602
+ const scaleY = Math.abs(this._scene.scaleY) || 1;
28603
+ const rawOffsetX = evt.deltaX / scaleX;
28604
+ const rawOffsetY = evt.deltaY / scaleY;
28605
+ offsetX = viewWidth / allWidth * rawOffsetX;
28223
28606
  const allHeight = this._scene.height;
28224
28607
  const viewHeight = this.height || 1;
28225
- if (evt.shiftKey) offsetX = viewHeight / allHeight * evt.deltaY * MOUSE_WHEEL_SPEED_SMOOTHING_FACTOR;
28226
- else offsetY = viewHeight / allHeight * evt.deltaY;
28608
+ if (evt.shiftKey) offsetX = viewHeight / allHeight * evt.deltaY * MOUSE_WHEEL_SPEED_SMOOTHING_FACTOR / scaleX;
28609
+ else {
28610
+ offsetY = viewHeight / allHeight * rawOffsetY;
28611
+ const absOffsetX = Math.abs(rawOffsetX);
28612
+ const absOffsetY = Math.abs(rawOffsetY);
28613
+ if (absOffsetY >= absOffsetX * WHEEL_CROSS_AXIS_LOCK_RATIO) offsetX = 0;
28614
+ else if (absOffsetX >= absOffsetY * WHEEL_CROSS_AXIS_LOCK_RATIO) offsetY = 0;
28615
+ }
28227
28616
  const isLimitedStore = this.scrollByBarDeltaValue({
28228
28617
  x: offsetX,
28229
28618
  y: offsetY
@@ -28550,6 +28939,7 @@ var Viewport = class {
28550
28939
  }
28551
28940
  _calcDiffCacheBound(prevBound, currBound) {
28552
28941
  if (!prevBound) return [currBound];
28942
+ if (prevBound.right <= currBound.left || currBound.right <= prevBound.left || prevBound.bottom <= currBound.top || currBound.bottom <= prevBound.top) return [currBound];
28553
28943
  const additionalAreas = [];
28554
28944
  if (currBound.left < prevBound.left) additionalAreas.push({
28555
28945
  top: currBound.top,
@@ -28806,6 +29196,7 @@ exports.getCurrentTypeOfRenderer = getCurrentTypeOfRenderer;
28806
29196
  exports.getDPI = getDPI;
28807
29197
  exports.getDevicePixelRatio = getDevicePixelRatio;
28808
29198
  exports.getDocsSkeletonPageSize = getDocsSkeletonPageSize;
29199
+ exports.getDocsTableRenderViewport = getDocsTableRenderViewport;
28809
29200
  exports.getDrawingGroupState = getDrawingGroupState;
28810
29201
  exports.getFirstGrapheme = getFirstGrapheme;
28811
29202
  exports.getFontStyleString = getFontStyleString;
@@ -28815,6 +29206,7 @@ exports.getLastLine = getLastLine;
28815
29206
  exports.getLineOffset = getLineOffset;
28816
29207
  exports.getLineWidth = getLineWidth;
28817
29208
  exports.getLineWith = getLineWith;
29209
+ exports.getNextWheelZoomRatio = getNextWheelZoomRatio;
28818
29210
  exports.getNumberUnitValue = getNumberUnitValue;
28819
29211
  exports.getOffsetRectForDom = getOffsetRectForDom;
28820
29212
  exports.getPageFromPath = getPageFromPath;
@@ -28842,6 +29234,7 @@ exports.hasLatinExtendedB = hasLatinExtendedB;
28842
29234
  exports.hasLatinOneSupplement = hasLatinOneSupplement;
28843
29235
  exports.hasListGlyph = hasListGlyph;
28844
29236
  exports.hasSpace = hasSpace;
29237
+ exports.hasThai = hasThai;
28845
29238
  exports.hasTibetan = hasTibetan;
28846
29239
  exports.hasUnMergedCellInRow = hasUnMergedCellInRow;
28847
29240
  exports.inViewRanges = inViewRanges;
@@ -28880,6 +29273,7 @@ exports.renderTextWatermark = renderTextWatermark;
28880
29273
  exports.renderUserInfoWatermark = renderUserInfoWatermark;
28881
29274
  exports.renderWatermark = renderWatermark;
28882
29275
  exports.requestNewFrame = requestNewFrame;
29276
+ exports.setDocsTableRenderViewportProvider = setDocsTableRenderViewportProvider;
28883
29277
  exports.setLineType = setLineType;
28884
29278
  exports.sheetContentViewportKeys = sheetContentViewportKeys;
28885
29279
  exports.sheetHeaderViewportKeys = sheetHeaderViewportKeys;