Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(sheet): render viewport wrong size #1727

Draft
wants to merge 13 commits into
base: dev
Choose a base branch
from
Prev Previous commit
Next Next commit
feat: cache by viewport
chore: merge fix1

fix: fix viewport start pos

feat: add vp dirty when moving range

fix: shrink font extension merge range

fix: zoom out cause blank area!!

chore: fix viewport mainCtx scaling

chore: better code 2

chore: better code2

chore: update with dev

chore: turn off test canvas
  • Loading branch information
lumixraku committed May 24, 2024
commit ffe97fd20289b22bd61f9412ef347cc7d366d030
31 changes: 31 additions & 0 deletions packages/core/src/shared/tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -671,4 +671,35 @@ export class Tools {

return !containsInvalidChars && isValidLength;
}

static hasIntersectionBetweenTwoBounds(
rect1: {
left: number;
top: number;
right: number;
bottom: number;
},
rect2: {
left: number;
top: number;
right: number;
bottom: number;
}
) {
// const rect1Right = rect1.left + rect1.width;
// const rect2Right = rect2.left + rect2.width;
// const rect1Bottom = rect1.top + rect1.height;
// const rect2Bottom = rect2.top + rect2.height;

if (
rect1.left > rect2.right || // rect1 在 rect2 右侧
rect1.right < rect2.left || // rect1 在 rect2 左侧
rect1.top > rect2.bottom || // rect1 在 rect2 下方
rect1.bottom < rect2.top // rect1 在 rect2 上方
) {
return false;
}

return true;
}
}
2 changes: 2 additions & 0 deletions packages/docs-ui/src/views/doc-canvas-view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ export class DocCanvasView extends RxDisposable {
top: 0,
bottom: 0,
right: 0,
isRelativeX: true,
isRelativeY: true,
isWheelPreventDefaultX: true,
});

Expand Down
6 changes: 3 additions & 3 deletions packages/engine-render/src/base-object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import type { IObjectFullState, ITransformChangeState } from './basics/interface
import { TRANSFORM_CHANGE_OBSERVABLE_TYPE } from './basics/interfaces';
import { generateRandomKey, toPx } from './basics/tools';
import { Transform } from './basics/transform';
import type { IViewportBound, Vector2 } from './basics/vector2';
import type { IViewportInfo, Vector2 } from './basics/vector2';
import type { UniverRenderingContext } from './context';
import type { Layer } from './layer';

Expand Down Expand Up @@ -514,7 +514,7 @@ export abstract class BaseObject extends Disposable {
return this;
}

isRender(bounds?: IViewportBound) {
isRender(bounds?: IViewportInfo) {
if (this._forceRender) {
return false;
}
Expand Down Expand Up @@ -551,7 +551,7 @@ export abstract class BaseObject extends Disposable {
this._makeDirtyMix();
}

render(ctx: UniverRenderingContext, bounds?: IViewportBound) {
render(ctx: UniverRenderingContext, bounds?: IViewportInfo) {
/* abstract */
}

Expand Down
79 changes: 78 additions & 1 deletion packages/engine-render/src/basics/tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import type {
LocaleService,
Nullable,
} from '@univerjs/core';
import { BaselineOffset, DEFAULT_STYLES, FontStyleType, Tools } from '@univerjs/core';
import { BaselineOffset, DEFAULT_STYLES, FontStyleType, Rectangle, Tools } from '@univerjs/core';
import * as cjk from 'cjk-regex';

import { FontCache } from '../components/docs/layout/shaping-engine/font-cache';
Expand Down Expand Up @@ -757,3 +757,80 @@ export function ptToPixel(pt: number) {
export function pixelToPt(px: number) {
return px * PX_TO_PT_RATIO;
}

/**
* 当前单元格在任意一个 viewRanges 中
* @param ranges
* @param rowIndex
* @param colIndex
* @returns
*/
export function inViewRanges(ranges: IRange[], rowIndex: number, colIndex: number) {
for (const range of ranges) {
if (rowIndex >= range.startRow && rowIndex <= range.endRow &&
colIndex >= range.startColumn && colIndex <= range.endColumn) {
return true;
}
}
return false;
}

/**
* 在非下方区域中
* @param ranges
* @param rowIndex
* @returns
*/
export function inCurrentAndAboveViewRanges(ranges: IRange[], rowIndex: number) {
for (const range of ranges) {
if (rowIndex > range.endRow) {
return false;
}
}
return true;
}

/**
* row 在任意一个 Range 中
* @param ranges
* @param rowIndex
* @returns
*/
export function inRowViewRanges(ranges: IRange[], rowIndex: number) {
let flag = false;
for (const range of ranges) {
if (rowIndex >= range.startRow && rowIndex <= range.endRow) {
flag = true;
break;
}
}
return flag;
}

/**
* 如果 range 有相交, 那么扩展到第一个 range 中.
* @param ranges
*/
export function mergeRangeIfIntersects(mainRanges: IRange[], ranges: IRange[]) {
for (const mainRange of mainRanges) {
for (const range of ranges) {
if (Rectangle.intersects(mainRange, range)) {
mainRange.startRow = Math.min(mainRange.startRow, range.startRow);
mainRange.endRow = Math.max(mainRange.endRow, range.endRow);
mainRange.startColumn = Math.min(mainRange.startColumn, range.startColumn);
mainRange.endColumn = Math.max(mainRange.endColumn, range.endColumn);
}
}
}
return mainRanges;
}


export function clampRanges(range: IRange) {
return {
startRow: Math.max(0, range.startRow),
startColumn: Math.max(0, range.startColumn),
endRow: Math.max(0, range.endRow),
endColumn: Math.max(0, range.endColumn),
};
}
14 changes: 14 additions & 0 deletions packages/engine-render/src/basics/transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ export class Transform {
this._m[1] *= sx;
this._m[2] *= sy;
this._m[3] *= sy;
this._m[4] *= sx;
this._m[5] *= sy;
return this;
}

Expand Down Expand Up @@ -387,6 +389,18 @@ export class Transform {
return scaleMatrix;
}

convert2DOMMatrix2D() {
const m = this.getMatrix();
return {
a: m[0],
b: m[1],
c: m[2],
d: m[3],
e: m[4],
f: m[5],
};
}

// static createTransformByState(state: positionState) {
// const newTr = new this();
// let { x, y, angle, scaleX, scaleY, skewX, skewY, flipX, flipY } = state;
Expand Down
50 changes: 48 additions & 2 deletions packages/engine-render/src/basics/vector2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
* limitations under the License.
*/

import type { Canvas } from '../canvas';
import type { DeepImmutable, FloatArray } from './i-events';
import type { Transform } from './transform';

export interface IPoint {
x: number;
Expand Down Expand Up @@ -844,17 +846,61 @@ export interface IBoundRect {
}

export interface IBoundRectNoAngle {
/**
* 冻结区域相对 MainCanvas 的物理位置,
* left = n * colWidth + rowHeaderWidth
*/
left: number;
top: number;
right: number;
bottom: number;
}

export interface IViewportBound {
export interface IViewportInfo {
/**
* viewBound 的 left right 包括列头行头
*/
viewBound: IBoundRectNoAngle;
diffBounds: IBoundRectNoAngle[];

/**
* 让更多右侧内容呈现 diffX < 0
* previewBound.x - viewbound.x
*/
diffX: number;
diffY: number;

/**
* 冻结行列在 canvas 上的物理位置, drawImage 用
* 例如冻结从第四列开始, left 就是 4 * column + rowHeaderWidth
*/
viewPortPosition: IBoundRectNoAngle;
viewPortKey?: string;
viewPortKey: string;
isDirty?: boolean;
isForceDirty?: boolean;

allowCache?: boolean;
cacheBound: IBoundRectNoAngle;
diffCacheBounds: IBoundRectNoAngle[];
cacheViewPortPosition: IBoundRectNoAngle;

// vp?: Viewport;
shouldCacheUpdate: number;
sceneTrans: Transform;
cacheCanvas?: Canvas;

leftOrigin: number;
topOrigin: number;

bufferEdgeX: number;
bufferEdgeY: number;
}

export interface IViewportInfos {
left: number;
right: number;
top: number;
bottom: number;
width: number;
height: number;
}
4 changes: 2 additions & 2 deletions packages/engine-render/src/components/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import { DisposableCollection, sortRules, toDisposable } from '@univerjs/core';
import type { IDisposable } from '@wendellhu/redi';
import { BaseObject } from '../base-object';
import type { IViewportBound } from '../basics/vector2';
import type { IViewportInfo } from '../basics/vector2';
import type { UniverRenderingContext } from '../context';
import type { ComponentExtension } from './extension';

Expand Down Expand Up @@ -58,7 +58,7 @@ export class RenderComponent<T, U, V> extends BaseObject {
return this._extensions.get(uKey);
}

draw(ctx: UniverRenderingContext, bounds?: IViewportBound) {
draw(ctx: UniverRenderingContext, bounds?: IViewportInfo) {
/* abstract */
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

import type { IViewportBound } from '../../basics/vector2';
import type { IViewportInfo } from '../../basics/vector2';
import type { UniverRenderingContext } from '../../context';
import { Rect } from '../../shape';
import { Liquid } from './liquid';
Expand All @@ -40,7 +40,7 @@ export class DocBackground extends DocComponent {
return new DocBackground(oKey, documentSkeleton, config);
}

override draw(ctx: UniverRenderingContext, bounds?: IViewportBound) {
override draw(ctx: UniverRenderingContext, bounds?: IViewportInfo) {
const skeletonData = this.getSkeleton()?.getSkeletonData();

if (skeletonData == null) {
Expand Down Expand Up @@ -103,7 +103,7 @@ export class DocBackground extends DocComponent {
return this;
}

protected override _draw(ctx: UniverRenderingContext, bounds?: IViewportBound) {
protected override _draw(ctx: UniverRenderingContext, bounds?: IViewportInfo) {
this.draw(ctx, bounds);
}
}
6 changes: 3 additions & 3 deletions packages/engine-render/src/components/docs/doc-component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import { RENDER_CLASS_TYPE } from '../../basics/const';
import type { IDocumentSkeletonGlyph, IDocumentSkeletonLine, IDocumentSkeletonPage } from '../../basics/i-document-skeleton-cached';
import { PageLayoutType } from '../../basics/i-document-skeleton-cached';
import type { IBoundRectNoAngle, IViewportBound } from '../../basics/vector2';
import type { IBoundRectNoAngle, IViewportInfo } from '../../basics/vector2';
import type { UniverRenderingContext } from '../../context';
import { RenderComponent } from '../component';
import type { DOCS_EXTENSION_TYPE } from './doc-extension';
Expand Down Expand Up @@ -82,7 +82,7 @@ export abstract class DocComponent extends RenderComponent<
}
}

override render(mainCtx: UniverRenderingContext, bounds?: IViewportBound) {
override render(mainCtx: UniverRenderingContext, bounds?: IViewportInfo) {
if (!this.visible) {
this.makeDirty(false);
return this;
Expand Down Expand Up @@ -118,7 +118,7 @@ export abstract class DocComponent extends RenderComponent<
};
}

isSkipByDiffBounds(page: IDocumentSkeletonPage, pageTop: number, pageLeft: number, bounds?: IViewportBound) {
isSkipByDiffBounds(page: IDocumentSkeletonPage, pageTop: number, pageLeft: number, bounds?: IViewportInfo) {
if (bounds === null || bounds === undefined) {
return false;
}
Expand Down
6 changes: 3 additions & 3 deletions packages/engine-render/src/components/docs/document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import type { IDocumentSkeletonCached, IDocumentSkeletonPage } from '../../basic
import { LineType } from '../../basics/i-document-skeleton-cached';
import { degToRad } from '../../basics/tools';
import type { Transform } from '../../basics/transform';
import type { IViewportBound } from '../../basics/vector2';
import type { IViewportInfo } from '../../basics/vector2';
import { Vector2 } from '../../basics/vector2';
import type { UniverRenderingContext } from '../../context';
import type { Scene } from '../../scene';
Expand Down Expand Up @@ -164,7 +164,7 @@ export class Documents extends DocComponent {
return (this.getScene() as Scene).getEngine();
}

override draw(ctx: UniverRenderingContext, bounds?: IViewportBound) {
override draw(ctx: UniverRenderingContext, bounds?: IViewportInfo) {
const skeletonData = this.getSkeleton()?.getSkeletonData();

if (skeletonData == null) {
Expand Down Expand Up @@ -466,7 +466,7 @@ export class Documents extends DocComponent {
return this;
}

protected override _draw(ctx: UniverRenderingContext, bounds?: IViewportBound) {
protected override _draw(ctx: UniverRenderingContext, bounds?: IViewportInfo) {
this.draw(ctx, bounds);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import type {
} from '../../../basics/i-document-skeleton-cached';
import { GlyphType, LineType, PageLayoutType } from '../../../basics/i-document-skeleton-cached';
import type { IDocsConfig, INodeInfo, INodePosition, INodeSearch } from '../../../basics/interfaces';
import type { IViewportBound, Vector2 } from '../../../basics/vector2';
import type { IViewportInfo, Vector2 } from '../../../basics/vector2';
import { Skeleton } from '../../skeleton';
import { Liquid } from '../liquid';
import type { DocumentViewModel } from '../view-model/document-view-model';
Expand Down Expand Up @@ -94,7 +94,7 @@ export class DocumentSkeleton extends Skeleton {
}

// Layout the document.
calculate(bounds?: IViewportBound) {
calculate(bounds?: IViewportInfo) {
if (!this.dirty) {
return;
}
Expand Down Expand Up @@ -555,7 +555,7 @@ export class DocumentSkeleton extends Skeleton {
* @returns view model: skeleton
*/

private _createSkeleton(ctx: ILayoutContext, _bounds?: IViewportBound): IDocumentSkeletonCached {
private _createSkeleton(ctx: ILayoutContext, _bounds?: IViewportInfo): IDocumentSkeletonCached {
// console.log('createSkeleton: iterate ', this._iteratorCount, 'times');
const { viewModel, skeleton, skeletonResourceReference } = ctx;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -854,7 +854,7 @@ export class TextSelectionRenderManager extends RxDisposable implements ITextSel
return;
}
const unitId = this._docSkeleton.getViewModel().getDataModel().getUnitId();
const key = `${unitId}_${viewport.viewPortKey}`;
const key = `${unitId}_${viewport.viewportKey}`;

if (this._viewPortObserverMap.has(key)) {
return;
Expand Down