diff --git a/addons/addon-webgl/src/customGlyphs/CustomGlyphDefinitions.ts b/addons/addon-webgl/src/customGlyphs/CustomGlyphDefinitions.ts index 11b6f9ac..0dcbb8ed 100644 --- a/addons/addon-webgl/src/customGlyphs/CustomGlyphDefinitions.ts +++ b/addons/addon-webgl/src/customGlyphs/CustomGlyphDefinitions.ts @@ -501,22 +501,22 @@ export const customGlyphDefinitions: { [index: string]: CustomGlyphCharacterDefi '\u{1FB9B}': { type: CustomGlyphDefinitionType.VECTOR_SHAPE, data: { d: 'M0,0 L.5,.5 L1,0 L1,1 L.5,.5 L0,1', type: CustomGlyphVectorType.FILL } }, // LEFT AND RIGHT TRIANGULAR HALF BLOCK // Triangular shade characters (1FB9C-1FB9F) - '\u{1FB9C}': { type: CustomGlyphDefinitionType.BLOCK_PATTERN_WITH_CLIP_PATH, data: [[ // UPPER LEFT TRIANGULAR MEDIUM SHADE + '\u{1FB9C}': { type: CustomGlyphDefinitionType.BLOCK_PATTERN, data: [ // UPPER LEFT TRIANGULAR MEDIUM SHADE [1, 0], [0, 1] - ], 'M0,0 L1,0 L0,1 Z'] }, - '\u{1FB9D}': { type: CustomGlyphDefinitionType.BLOCK_PATTERN_WITH_CLIP_PATH, data: [[ // UPPER RIGHT TRIANGULAR MEDIUM SHADE + ], clipPath: 'M0,0 L1,0 L0,1 Z' }, + '\u{1FB9D}': { type: CustomGlyphDefinitionType.BLOCK_PATTERN, data: [ // UPPER RIGHT TRIANGULAR MEDIUM SHADE [1, 0], [0, 1] - ], 'M0,0 L1,0 L1,1 Z'] }, - '\u{1FB9E}': { type: CustomGlyphDefinitionType.BLOCK_PATTERN_WITH_CLIP_PATH, data: [[ // LOWER RIGHT TRIANGULAR MEDIUM SHADE + ], clipPath: 'M0,0 L1,0 L1,1 Z' }, + '\u{1FB9E}': { type: CustomGlyphDefinitionType.BLOCK_PATTERN, data: [ // LOWER RIGHT TRIANGULAR MEDIUM SHADE [1, 0], [0, 1] - ], 'M1,0 L1,1 L0,1 Z'] }, - '\u{1FB9F}': { type: CustomGlyphDefinitionType.BLOCK_PATTERN_WITH_CLIP_PATH, data: [[ // LOWER LEFT TRIANGULAR MEDIUM SHADE + ], clipPath: 'M1,0 L1,1 L0,1 Z' }, + '\u{1FB9F}': { type: CustomGlyphDefinitionType.BLOCK_PATTERN, data: [ // LOWER LEFT TRIANGULAR MEDIUM SHADE [1, 0], [0, 1] - ], 'M0,0 L1,1 L0,1 Z'] }, + ], clipPath: 'M0,0 L1,1 L0,1 Z' }, // Character cell diagonals (1FBA0-1FBAE) '\u{1FBA0}': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: 'M.5,0 L0,.5' } }, // BOX DRAWINGS LIGHT DIAGONAL UPPER CENTRE TO MIDDLE LEFT diff --git a/addons/addon-webgl/src/customGlyphs/CustomGlyphRasterizer.ts b/addons/addon-webgl/src/customGlyphs/CustomGlyphRasterizer.ts index 614941c3..b444fd31 100644 --- a/addons/addon-webgl/src/customGlyphs/CustomGlyphRasterizer.ts +++ b/addons/addon-webgl/src/customGlyphs/CustomGlyphRasterizer.ts @@ -46,6 +46,12 @@ function drawDefinitionPart( devicePixelRatio: number, backgroundColor?: string ): void { + // Handle clipPath generically for any definition type + if (part.clipPath) { + ctx.save(); + applyClipPath(ctx, part.clipPath, xOffset, yOffset, deviceCellWidth, deviceCellHeight); + } + switch (part.type) { case CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR: drawBlockVectorChar(ctx, part.data, xOffset, yOffset, deviceCellWidth, deviceCellHeight); @@ -56,9 +62,6 @@ function drawDefinitionPart( case CustomGlyphDefinitionType.BLOCK_PATTERN_WITH_REGION: drawBlockPatternWithRegion(ctx, part.data, xOffset, yOffset, deviceCellWidth, deviceCellHeight); break; - case CustomGlyphDefinitionType.BLOCK_PATTERN_WITH_CLIP_PATH: - drawBlockPatternWithClipPath(ctx, part.data, xOffset, yOffset, deviceCellWidth, deviceCellHeight); - break; case CustomGlyphDefinitionType.PATH_FUNCTION: case CustomGlyphDefinitionType.PATH: drawPathDefinitionCharacter(ctx, part.data, xOffset, yOffset, deviceCellWidth, deviceCellHeight); @@ -73,6 +76,10 @@ function drawDefinitionPart( drawPathDefinitionCharacterWithWeight(ctx, part.data, xOffset, yOffset, deviceCellWidth, deviceCellHeight, devicePixelRatio); break; } + + if (part.clipPath) { + ctx.restore(); + } } function drawBlockVectorChar( @@ -491,21 +498,16 @@ function drawPathDefinitionCharacterWithWeight( } /** - * Draws a pattern clipped to an arbitrary path (for triangular shades, etc.) + * Applies a clip path to the canvas context from SVG-like path instructions. */ -function drawBlockPatternWithClipPath( +function applyClipPath( ctx: CanvasRenderingContext2D, - definition: [pattern: CustomGlyphPatternDefinition, clipPath: string], + clipPath: string, xOffset: number, yOffset: number, deviceCellWidth: number, deviceCellHeight: number ): void { - const [pattern, clipPath] = definition; - - ctx.save(); - - // Build clip path from SVG-like instructions ctx.beginPath(); for (const instruction of clipPath.split(' ')) { const type = instruction[0]; @@ -526,11 +528,6 @@ function drawBlockPatternWithClipPath( } } ctx.clip(); - - // Draw the pattern - drawPatternChar(ctx, pattern, xOffset, yOffset, deviceCellWidth, deviceCellHeight); - - ctx.restore(); } function drawVectorShape( diff --git a/addons/addon-webgl/src/customGlyphs/Types.ts b/addons/addon-webgl/src/customGlyphs/Types.ts index 52e81b55..113522fd 100644 --- a/addons/addon-webgl/src/customGlyphs/Types.ts +++ b/addons/addon-webgl/src/customGlyphs/Types.ts @@ -34,7 +34,6 @@ export const enum CustomGlyphDefinitionType { SOLID_OCTANT_BLOCK_VECTOR, BLOCK_PATTERN, BLOCK_PATTERN_WITH_REGION, - BLOCK_PATTERN_WITH_CLIP_PATH, PATH_FUNCTION, PATH_FUNCTION_WITH_WEIGHT, PATH, @@ -44,18 +43,26 @@ export const enum CustomGlyphDefinitionType { export type CustomGlyphRegionDefinition = [x: number, y: number, w: number, h: number]; -export type CustomGlyphDefinitionPart = ( +export type CustomGlyphDefinitionPartRaw = ( { type: CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR, data: ICustomGlyphSolidOctantBlockVector[] } | { type: CustomGlyphDefinitionType.BLOCK_PATTERN, data: CustomGlyphPatternDefinition } | { type: CustomGlyphDefinitionType.BLOCK_PATTERN_WITH_REGION, data: [pattern: CustomGlyphPatternDefinition, region: CustomGlyphRegionDefinition] } | - { type: CustomGlyphDefinitionType.BLOCK_PATTERN_WITH_CLIP_PATH, data: [pattern: CustomGlyphPatternDefinition, clipPath: string] } | { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: CustomGlyphPathDrawFunctionDefinition } | { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [fontWeight: number]: string | CustomGlyphPathDrawFunctionDefinition } } | { type: CustomGlyphDefinitionType.PATH, data: string } | { type: CustomGlyphDefinitionType.PATH_NEGATIVE, data: ICustomGlyphVectorShape } | - { type: CustomGlyphDefinitionType.VECTOR_SHAPE, data: ICustomGlyphVectorShape } + { type: CustomGlyphDefinitionType.VECTOR_SHAPE, data: ICustomGlyphVectorShape} ); +export interface ICustomGlyphDefinitionCommon { + /** + * A custom clip path for the draw definition, restricting the area it can draw to. + */ + clipPath?: string; +} + +export type CustomGlyphDefinitionPart = CustomGlyphDefinitionPartRaw & ICustomGlyphDefinitionCommon; + /** * A character definition that can be a single part or an array of parts drawn in sequence. */