Skip to content

Commit

Permalink
fix(render): fix the issue loop span many times (#3394)
Browse files Browse the repository at this point in the history
  • Loading branch information
VicKun4937 authored Sep 10, 2024
1 parent 47e695c commit f3d55f7
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 14 deletions.
73 changes: 73 additions & 0 deletions packages/engine-render/src/basics/tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import type {
IRange,
IRangeWithCoord,
IScale,
ISelectionCell,
ISelectionCellWithMergeInfo,
IStyleBase,
LocaleService,
Expand Down Expand Up @@ -522,6 +523,78 @@ export function getCellPositionByIndex(
};
}

export function getCellByIndexWithMergeInfo(
row: number,
column: number,
rowHeightAccumulation: number[],
columnWidthAccumulation: number[],
mergeDataInfo: ISelectionCell
) {
// eslint-disable-next-line prefer-const
let { startY, endY, startX, endX } = getCellPositionByIndex(
row,
column,
rowHeightAccumulation,
columnWidthAccumulation
);

const { isMerged, isMergedMainCell, startRow, startColumn, endRow, endColumn } = mergeDataInfo;

let mergeInfo = {
startRow,
startColumn,
endRow,
endColumn,

startY: 0,
endY: 0,
startX: 0,
endX: 0,
};

const rowAccumulationCount = rowHeightAccumulation.length - 1;

const columnAccumulationCount = columnWidthAccumulation.length - 1;

if (isMerged && startRow !== -1 && startColumn !== -1) {
const mergeStartY = rowHeightAccumulation[startRow - 1] || 0;
const mergeEndY = rowHeightAccumulation[endRow] || rowHeightAccumulation[rowAccumulationCount];

const mergeStartX = columnWidthAccumulation[startColumn - 1] || 0;
const mergeEndX = columnWidthAccumulation[endColumn] || columnWidthAccumulation[columnAccumulationCount];
mergeInfo = {
...mergeInfo,
startY: mergeStartY,
endY: mergeEndY,
startX: mergeStartX,
endX: mergeEndX,
};
} else if (!isMerged && endRow !== -1 && endColumn !== -1) {
const mergeEndY = rowHeightAccumulation[endRow] || rowHeightAccumulation[rowAccumulationCount];
const mergeEndX = columnWidthAccumulation[endColumn] || columnWidthAccumulation[columnAccumulationCount];

mergeInfo = {
...mergeInfo,
startY,
endY: mergeEndY,
startX,
endX: mergeEndX,
};
}

return {
isMerged,
isMergedMainCell,
actualRow: row,
actualColumn: column,
startY,
endY,
startX,
endX,
mergeInfo,
};
}

export function getCellByIndex(
row: number,
column: number,
Expand Down
72 changes: 60 additions & 12 deletions packages/engine-render/src/components/sheets/sheet-skeleton.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import {
DEFAULT_STYLES,
DocumentDataModel,
extractPureTextFromCell,
getCellInfoInMergeData,
getColorStyle,
HorizontalAlign,
IContextService,
Expand Down Expand Up @@ -52,6 +51,7 @@ import type {
IRange,
IRowAutoHeightInfo,
IRowData,
ISelectionCell,
ISelectionCellWithMergeInfo,
ISize,
IStyleBase,
Expand All @@ -71,7 +71,7 @@ import { getRotateOffsetAndFarthestHypotenuse } from '../../basics/draw';
import type { IDocumentSkeletonColumn } from '../../basics/i-document-skeleton-cached';
import {
degToRad,
getCellByIndex,
getCellByIndexWithMergeInfo,
getCellPositionByIndex,
getFontStyleString,
hasUnMergedCellInRow,
Expand Down Expand Up @@ -234,6 +234,7 @@ export class SpreadsheetSkeleton extends Skeleton {
};

private _dataMergeCache: IRange[] = [];
private _dataMergeCacheMap: Map<string, IRange> = new Map();
private _overflowCache: ObjectMatrix<IRange> = new ObjectMatrix();
private _stylesCache: IStylesCache = {
background: {},
Expand Down Expand Up @@ -417,6 +418,7 @@ export class SpreadsheetSkeleton extends Skeleton {
const { mergeData } = this._worksheetData;

this._dataMergeCache = mergeData && this._getMergeCells(mergeData, this._rowColumnSegment);
this._dataMergeCacheMap = mergeData && this._getMergeCellsCache(mergeData);

this._calculateStylesCache();

Expand Down Expand Up @@ -484,7 +486,7 @@ export class SpreadsheetSkeleton extends Skeleton {
for (let i = 0; i < columnCount; i++) {
// When calculating the automatic height of a row, if a cell is in a merged cell,
// skip the cell directly, which currently follows the logic of Excel
const { isMerged, isMergedMainCell } = getCellInfoInMergeData(rowNum, i, mergeData);
const { isMerged, isMergedMainCell } = this._getCellMergeInfo(rowNum, i, mergeData);

if (isMerged || isMergedMainCell) {
continue;
Expand Down Expand Up @@ -957,12 +959,12 @@ export class SpreadsheetSkeleton extends Skeleton {
columnHeaderHeightAndMarginTop,
} = this;

const primary = getCellByIndex(
const primary = getCellByIndexWithMergeInfo(
row,
column,
rowHeightAccumulation,
columnWidthAccumulation,
this._worksheetData.mergeData
this._getCellMergeInfo(row, column, this._worksheetData.mergeData)
);
const { isMerged, isMergedMainCell } = primary;
let { startY, endY, startX, endX, mergeInfo } = primary;
Expand Down Expand Up @@ -990,12 +992,12 @@ export class SpreadsheetSkeleton extends Skeleton {
getCellByIndexWithNoHeader(row: number, column: number): ISelectionCellWithMergeInfo {
const { rowHeightAccumulation, columnWidthAccumulation } = this;

const primary = getCellByIndex(
const primary = getCellByIndexWithMergeInfo(
row,
column,
rowHeightAccumulation,
columnWidthAccumulation,
this._worksheetData.mergeData
this._getCellMergeInfo(row, column, this._worksheetData.mergeData)
);
const { isMerged, isMergedMainCell } = primary;
const { startY, endY, startX, endX, mergeInfo } = primary;
Expand Down Expand Up @@ -1251,12 +1253,12 @@ export class SpreadsheetSkeleton extends Skeleton {
}

if (vertexAngle !== 0) {
const { startY, endY, startX, endX } = getCellByIndex(
const { startY, endY, startX, endX } = getCellByIndexWithMergeInfo(
row,
column,
this.rowHeightAccumulation,
this.columnWidthAccumulation,
this.mergeData
this._getCellMergeInfo(row, column, this._worksheetData.mergeData)
);
const cellWidth = endX - startX;
const cellHeight = endY - startY;
Expand Down Expand Up @@ -1289,12 +1291,12 @@ export class SpreadsheetSkeleton extends Skeleton {
return true;
}

const { startY, endY } = getCellByIndex(
const { startY, endY } = getCellByIndexWithMergeInfo(
row,
column,
this.rowHeightAccumulation,
this.columnWidthAccumulation,
this.mergeData
this._getCellMergeInfo(row, column, this._worksheetData.mergeData)
);

const cellHeight = endY - startY;
Expand Down Expand Up @@ -1695,7 +1697,7 @@ export class SpreadsheetSkeleton extends Skeleton {

const hidden = this.worksheet.getColVisible(c) === false || this.worksheet.getRowVisible(r) === false;
if (hidden) {
const { isMerged, isMergedMainCell } = getCellInfoInMergeData(
const { isMerged, isMergedMainCell } = this._getCellMergeInfo(
r,
c,
this._dataMergeCache
Expand Down Expand Up @@ -2099,6 +2101,52 @@ export class SpreadsheetSkeleton extends Skeleton {
} as ICellOtherConfig;
}

private _getMergeCellsCache(mergeData: IRange[]) {
const map = new Map<string, IRange>();
mergeData.forEach((range) => {
for (let r = range.startRow; r <= range.endRow; r++) {
for (let c = range.startColumn; c <= range.endColumn; c++) {
map.set(`${r}-${c}`, range);
}
}
});
return map;
}

private _getCellMergeInfo(row: number, column: number, mergeData: IRange[]): ISelectionCell {
if (!this._dataMergeCacheMap) {
this._dataMergeCacheMap = this._getMergeCellsCache(mergeData);
}
const key = `${row}-${column}`;
const mergeRange = this._dataMergeCacheMap.get(key);

let isMerged = false; // The upper left cell only renders the content
let isMergedMainCell = false;
let newEndRow = row;
let newEndColumn = column;
let mergeRow = row;
let mergeColumn = column;
if (mergeRange) {
isMerged = true;
isMergedMainCell = mergeRange.startRow === row && mergeRange.startColumn === column;
newEndRow = mergeRange.endRow;
newEndColumn = mergeRange.endColumn;
mergeRow = mergeRange.startRow;
mergeColumn = mergeRange.startColumn;
}

return {
actualRow: row,
actualColumn: column,
isMergedMainCell,
isMerged,
endRow: newEndRow,
endColumn: newEndColumn,
startRow: mergeRow,
startColumn: mergeColumn,
};
}

/**
* Cache the merged cells on the current screen to improve computational performance.
* @param mergeData all marge data
Expand Down
24 changes: 22 additions & 2 deletions packages/engine-render/src/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import { fixLineWidthByScale, getColor } from './basics/tools';

export class UniverRenderingContext2D implements CanvasRenderingContext2D {
__mode = 'rendering';
private _system: string;
private _browser: string;
readonly canvas: HTMLCanvasElement;

_context: CanvasRenderingContext2D;
Expand Down Expand Up @@ -484,13 +486,31 @@ export class UniverRenderingContext2D implements CanvasRenderingContext2D {
this._context.closePath();
}

getSystem() {
if (this._system) {
return this._system;
} else {
this._system = Tools.getSystemType();
}
return this._system;
}

getBrowser() {
if (this._browser) {
return this._browser;
} else {
this._browser = Tools.getBrowserType();
}
return this._browser;
}

/**
* Chrome hardware acceleration causes canvas stroke to fail to draw lines on Mac.
*/
closePathByEnv() {
const system = Tools.getSystemType();
const system = this.getSystem();
const isMac = system === 'Mac';
const browser = Tools.getBrowserType();
const browser = this.getBrowser();
const isChrome = browser === 'Chrome';

if (isMac && isChrome) {
Expand Down

0 comments on commit f3d55f7

Please sign in to comment.