mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
Support clip path on any draw definition
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user