diff --git a/packages/engine-render/src/components/docs/__tests__/document.spec.ts b/packages/engine-render/src/components/docs/__tests__/document.spec.ts index 61b73e53f8..bf154eb285 100644 --- a/packages/engine-render/src/components/docs/__tests__/document.spec.ts +++ b/packages/engine-render/src/components/docs/__tests__/document.spec.ts @@ -1152,6 +1152,7 @@ describe('documents render', () => { [], null, [], + [], {} as any, 0, 0, @@ -1230,6 +1231,7 @@ describe('documents render', () => { [], null, [], + [], {} as any, 0, 0, @@ -1289,6 +1291,7 @@ describe('documents render', () => { [], null, [], + [], {} as any, 0, 0, @@ -1350,6 +1353,7 @@ describe('documents render', () => { [], null, [], + [], {} as any, 0, 0, @@ -1512,6 +1516,7 @@ describe('documents render', () => { [], null, [], + [], { x: 0, y: 0 }, 0, 0, @@ -1560,6 +1565,7 @@ describe('documents render', () => { [], null, [], + [], { x: 100, y: 200 }, 0, 0, @@ -1609,6 +1615,7 @@ describe('documents render', () => { [], null, [], + [], { x: 0, y: 0 }, 0, 0, @@ -1626,6 +1633,7 @@ describe('documents render', () => { [], null, [], + [], { x: 0, y: 0 }, 0, 0, @@ -1680,6 +1688,7 @@ describe('documents render', () => { [], null, [], + [], { x: 0, y: 0 }, 0, 0, @@ -1732,7 +1741,9 @@ describe('documents render', () => { const lineDraw = vi.fn(); const bgDraw = vi.fn(); - const spanDraw = vi.fn(); + const drawOrder: Array<{ glyph: unknown; phase: 'background' | 'span' }> = []; + const preTextBackgroundDraw = vi.fn((_ctx, _parentScale, glyph) => drawOrder.push({ glyph, phase: 'background' })); + const spanDraw = vi.fn((_ctx, _parentScale, glyph) => drawOrder.push({ glyph, phase: 'span' })); const clearCache = vi.fn(); vi.spyOn(documents as any, 'getExtensionsByOrder').mockReturnValue([ @@ -1743,6 +1754,13 @@ describe('documents render', () => { clearCache, draw: bgDraw, }, + { + uKey: 'DocsPreTextBackgroundExtension', + type: DOCS_EXTENSION_TYPE.BACKGROUND, + extensionOffset: {}, + clearCache, + draw: preTextBackgroundDraw, + }, { uKey: 'DocsLineExtension', type: DOCS_EXTENSION_TYPE.LINE, @@ -1777,7 +1795,13 @@ describe('documents render', () => { expect(pageEvents.length).toBe(1); expect(clearCache).toHaveBeenCalled(); expect(lineDraw).toHaveBeenCalled(); + expect(preTextBackgroundDraw).toHaveBeenCalled(); expect(spanDraw).toHaveBeenCalled(); + drawOrder.forEach((entry, index) => { + if (entry.phase === 'span') { + expect(drawOrder.slice(0, index)).toContainEqual({ glyph: entry.glyph, phase: 'background' }); + } + }); expect(tableDraw).toHaveBeenCalledTimes(2); expect(tableDraw.mock.calls[1][1]).toMatchObject({ marginLeft: 48, @@ -1837,6 +1861,7 @@ describe('documents render', () => { [], null, [], + [], Vector2.create(0, 300), 0, 0, diff --git a/packages/engine-render/src/components/docs/doc-extension.ts b/packages/engine-render/src/components/docs/doc-extension.ts index 300cd73efa..3f646bb0bc 100644 --- a/packages/engine-render/src/components/docs/doc-extension.ts +++ b/packages/engine-render/src/components/docs/doc-extension.ts @@ -21,6 +21,8 @@ import { ComponentExtension } from '../extension'; export enum DOCS_EXTENSION_TYPE { SPAN, LINE, + /** Draws range or block backgrounds before inline backgrounds and text. */ + BACKGROUND, } export class docExtension extends ComponentExtension< diff --git a/packages/engine-render/src/components/docs/document.ts b/packages/engine-render/src/components/docs/document.ts index fe82ba042f..a0f6891360 100644 --- a/packages/engine-render/src/components/docs/document.ts +++ b/packages/engine-render/src/components/docs/document.ts @@ -248,6 +248,7 @@ export class Documents extends DocComponent { } const backgroundExtension = extensions.find((e) => e.uKey === 'DefaultDocsBackgroundExtension'); + const preTextBackgroundExtensions = extensions.filter((e) => e.type === DOCS_EXTENSION_TYPE.BACKGROUND); const glyphExtensionsExcludeBackground = extensions .filter((e) => e.type === DOCS_EXTENSION_TYPE.SPAN && e.uKey !== 'DefaultDocsBackgroundExtension'); @@ -323,6 +324,7 @@ export class Documents extends DocComponent { skeTables, extensions, backgroundExtension, + preTextBackgroundExtensions, glyphExtensionsExcludeBackground, alignOffsetNoAngle, centerAngle, @@ -345,6 +347,7 @@ export class Documents extends DocComponent { ctx, extensions, backgroundExtension, + preTextBackgroundExtensions, glyphExtensionsExcludeBackground, headerAlignOffsetNoAngle, centerAngle, @@ -506,7 +509,8 @@ export class Documents extends DocComponent { alignOffset, centerAngle, vertexAngle, - backgroundExtension + backgroundExtension, + preTextBackgroundExtensions ); // Draw text\border\lines etc. @@ -582,6 +586,7 @@ export class Documents extends DocComponent { skeColumnGroups, extensions, backgroundExtension, + preTextBackgroundExtensions, glyphExtensionsExcludeBackground, alignOffsetNoAngle, centerAngle, @@ -606,6 +611,7 @@ export class Documents extends DocComponent { ctx, extensions, backgroundExtension, + preTextBackgroundExtensions, glyphExtensionsExcludeBackground, footerAlignOffsetNoAngle, centerAngle, @@ -642,6 +648,7 @@ export class Documents extends DocComponent { skeTables: Map, extensions: ComponentExtension[], backgroundExtension: Nullable>, + preTextBackgroundExtensions: ComponentExtension[], glyphExtensionsExcludeBackground: ComponentExtension[], alignOffsetNoAngle: Vector2, centerAngle: number, @@ -701,6 +708,7 @@ export class Documents extends DocComponent { cell, extensions, backgroundExtension, + preTextBackgroundExtensions, glyphExtensionsExcludeBackground, alignOffsetNoAngle, centerAngle, @@ -729,6 +737,7 @@ export class Documents extends DocComponent { skeColumnGroups: Map, extensions: ComponentExtension[], backgroundExtension: Nullable>, + preTextBackgroundExtensions: ComponentExtension[], glyphExtensionsExcludeBackground: ComponentExtension[], alignOffsetNoAngle: Vector2, centerAngle: number, @@ -754,6 +763,7 @@ export class Documents extends DocComponent { column.page, extensions, backgroundExtension, + preTextBackgroundExtensions, glyphExtensionsExcludeBackground, alignOffsetNoAngle, centerAngle, @@ -956,9 +966,42 @@ export class Documents extends DocComponent { alignOffset: Vector2, centerAngle: number, vertexAngle: number, - backgroundExtension: Nullable> + backgroundExtension: Nullable>, + preTextBackgroundExtensions: ComponentExtension[] ) { - if (!backgroundExtension || this._drawLiquid == null) { + if (this._drawLiquid == null) { + return; + } + + for (const glyph of glyphGroup) { + if (!glyph.content) { + continue; + } + + const { width: spanWidth, left: spanLeft, xOffset } = glyph; + const { x: translateX, y: translateY } = this._drawLiquid; + const originTranslate = Vector2.create(translateX, translateY); + const centerPoint = Vector2.create(spanWidth / 2, lineHeight / 2); + const spanStartPoint = calculateRectRotate( + originTranslate.addByPoint(spanLeft + xOffset, 0), + centerPoint, + centerAngle, + vertexAngle, + alignOffset + ); + + for (const extension of preTextBackgroundExtensions) { + extension.extensionOffset = { + originTranslate, + spanStartPoint, + centerPoint, + alignOffset, + }; + extension.draw(ctx, parentScale, glyph); + } + } + + if (!backgroundExtension) { return; } @@ -991,6 +1034,7 @@ export class Documents extends DocComponent { cell: IDocumentSkeletonPage, extensions: ComponentExtension[], backgroundExtension: Nullable>, + preTextBackgroundExtensions: ComponentExtension[], glyphExtensionsExcludeBackground: ComponentExtension[], alignOffsetNoAngle: Vector2, centerAngle: number, @@ -1009,6 +1053,7 @@ export class Documents extends DocComponent { cell, extensions, backgroundExtension, + preTextBackgroundExtensions, glyphExtensionsExcludeBackground, alignOffsetNoAngle, centerAngle, @@ -1024,6 +1069,7 @@ export class Documents extends DocComponent { nestedPage: IDocumentSkeletonPage, extensions: ComponentExtension[], backgroundExtension: Nullable>, + preTextBackgroundExtensions: ComponentExtension[], glyphExtensionsExcludeBackground: ComponentExtension[], alignOffsetNoAngle: Vector2, centerAngle: number, @@ -1060,6 +1106,7 @@ export class Documents extends DocComponent { skeTables, extensions, backgroundExtension, + preTextBackgroundExtensions, glyphExtensionsExcludeBackground, Vector2.create(0, 0), centerAngle, @@ -1075,6 +1122,7 @@ export class Documents extends DocComponent { skeTables, extensions, backgroundExtension, + preTextBackgroundExtensions, glyphExtensionsExcludeBackground, alignOffset, centerAngle, @@ -1140,7 +1188,8 @@ export class Documents extends DocComponent { alignOffset, centerAngle, vertexAngle, - backgroundExtension + backgroundExtension, + preTextBackgroundExtensions ); // Draw text\border\lines etc. @@ -1331,6 +1380,7 @@ export class Documents extends DocComponent { ctx: UniverRenderingContext, extensions: ComponentExtension[], backgroundExtension: Nullable>, + preTextBackgroundExtensions: ComponentExtension[], glyphExtensionsExcludeBackground: ComponentExtension[], alignOffsetNoAngle: Vector2, centerAngle: number, @@ -1369,6 +1419,7 @@ export class Documents extends DocComponent { skeTables, extensions, backgroundExtension, + preTextBackgroundExtensions, glyphExtensionsExcludeBackground, alignOffsetNoAngle, centerAngle, @@ -1444,7 +1495,8 @@ export class Documents extends DocComponent { alignOffset, centerAngle, vertexAngle, - backgroundExtension + backgroundExtension, + preTextBackgroundExtensions ); // Draw text\border\lines etc.