Implement Triangular shade characters (1FB9C-1FB9F)

This commit is contained in:
Daniel Imms
2025-12-22 15:30:55 -08:00
parent 1c3813f3d4
commit e1803ed5a5
3 changed files with 64 additions and 1 deletions
@@ -499,7 +499,22 @@ export const customGlyphDefinitions: { [index: string]: CustomGlyphCharacterDefi
// Triangular shade characters (1FB9C-1FB9F)
// TODO: Implement
'\u{1FB9C}': { type: CustomGlyphDefinitionType.BLOCK_PATTERN_WITH_CLIP_PATH, 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
[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
[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
[1, 0],
[0, 1]
], '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
@@ -37,6 +37,9 @@ export function tryDrawCustomGlyph(
drawBlockPatternWithRegion(ctx, unifiedCharDefinition.data.pattern, xOffset, yOffset, deviceCellWidth, deviceCellHeight);
drawBlockVectorChar(ctx, unifiedCharDefinition.data.vectors, xOffset, yOffset, deviceCellWidth, deviceCellHeight);
return true;
case CustomGlyphDefinitionType.BLOCK_PATTERN_WITH_CLIP_PATH:
drawBlockPatternWithClipPath(ctx, unifiedCharDefinition.data, xOffset, yOffset, deviceCellWidth, deviceCellHeight);
return true;
case CustomGlyphDefinitionType.PATH_FUNCTION:
case CustomGlyphDefinitionType.PATH:
drawPathDefinitionCharacter(ctx, unifiedCharDefinition.data, xOffset, yOffset, deviceCellWidth, deviceCellHeight);
@@ -286,6 +289,49 @@ function drawPathDefinitionCharacterWithWeight(
}
}
/**
* Draws a pattern clipped to an arbitrary path (for triangular shades, etc.)
*/
function drawBlockPatternWithClipPath(
ctx: CanvasRenderingContext2D,
definition: [pattern: CustomGlyphPatternDefinition, 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];
if (type === 'Z') {
ctx.closePath();
continue;
}
const args: string[] = instruction.substring(1).split(',');
if (!args[0] || !args[1]) {
continue;
}
const x = xOffset + parseFloat(args[0]) * deviceCellWidth;
const y = yOffset + parseFloat(args[1]) * deviceCellHeight;
if (type === 'M') {
ctx.moveTo(x, y);
} else if (type === 'L') {
ctx.lineTo(x, y);
}
}
ctx.clip();
// Draw the pattern
drawPatternChar(ctx, pattern, xOffset, yOffset, deviceCellWidth, deviceCellHeight);
ctx.restore();
}
function drawVectorShape(
ctx: CanvasRenderingContext2D,
charDefinition: ICustomGlyphVectorShape,
@@ -35,6 +35,7 @@ export const enum CustomGlyphDefinitionType {
BLOCK_PATTERN,
BLOCK_PATTERN_WITH_REGION,
BLOCK_PATTERN_WITH_REGION_AND_SOLID_OCTANT_BLOCK_VECTOR,
BLOCK_PATTERN_WITH_CLIP_PATH,
PATH_FUNCTION,
PATH_FUNCTION_WITH_WEIGHT,
PATH,
@@ -50,6 +51,7 @@ export type CustomGlyphCharacterDefinition = (
// TODO: Consolidate these, draws should be possible via regions/clipping instead of special
// casing
{ type: CustomGlyphDefinitionType.BLOCK_PATTERN_WITH_REGION_AND_SOLID_OCTANT_BLOCK_VECTOR, data: { pattern: [pattern: CustomGlyphPatternDefinition, region: CustomGlyphRegionDefinition], vectors: ICustomGlyphSolidOctantBlockVector[] } } |
{ 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 } |