From 2114abe88ca85390832a221a62cf2fc823eee0c7 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 24 Dec 2025 04:19:14 -0800 Subject: [PATCH 1/4] Support multiple glyphs with multiple draw calls --- .../customGlyphs/CustomGlyphDefinitions.ts | 30 ++--- .../src/customGlyphs/CustomGlyphRasterizer.ts | 117 +++++++----------- addons/addon-webgl/src/customGlyphs/Types.ts | 11 +- 3 files changed, 67 insertions(+), 91 deletions(-) diff --git a/addons/addon-webgl/src/customGlyphs/CustomGlyphDefinitions.ts b/addons/addon-webgl/src/customGlyphs/CustomGlyphDefinitions.ts index 9340212c..11b6f9ac 100644 --- a/addons/addon-webgl/src/customGlyphs/CustomGlyphDefinitions.ts +++ b/addons/addon-webgl/src/customGlyphs/CustomGlyphDefinitions.ts @@ -452,28 +452,28 @@ export const customGlyphDefinitions: { [index: string]: CustomGlyphCharacterDefi [0, 1], [1, 0] ], [0, 0, 1, 1]] }, - '\u{1FB91}': { type: CustomGlyphDefinitionType.BLOCK_PATTERN_WITH_REGION_AND_SOLID_OCTANT_BLOCK_VECTOR, data: { // UPPER HALF BLOCK AND LOWER HALF INVERSE MEDIUM SHADE - pattern: [[ + '\u{1FB91}': [ // UPPER HALF BLOCK AND LOWER HALF INVERSE MEDIUM SHADE + { type: CustomGlyphDefinitionType.BLOCK_PATTERN_WITH_REGION, data: [[ [0, 1], [1, 0] - ], [0, 0.5, 1, 0.5]], - vectors: [{ x: 0, y: 0, w: 8, h: 4 }] - } }, - '\u{1FB92}': { type: CustomGlyphDefinitionType.BLOCK_PATTERN_WITH_REGION_AND_SOLID_OCTANT_BLOCK_VECTOR, data: { // UPPER HALF INVERSE MEDIUM SHADE AND LOWER HALF BLOCK - pattern: [[ + ], [0, 0.5, 1, 0.5]] }, + { type: CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR, data: [{ x: 0, y: 0, w: 8, h: 4 }] } + ], + '\u{1FB92}': [ // UPPER HALF INVERSE MEDIUM SHADE AND LOWER HALF BLOCK + { type: CustomGlyphDefinitionType.BLOCK_PATTERN_WITH_REGION, data: [[ [0, 1], [1, 0] - ], [0, 0, 1, 0.5]], - vectors: [{ x: 0, y: 4, w: 8, h: 4 }] - } }, + ], [0, 0, 1, 0.5]] }, + { type: CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR, data: [{ x: 0, y: 4, w: 8, h: 4 }] } + ], // 1FB93 is - '\u{1FB94}': { type: CustomGlyphDefinitionType.BLOCK_PATTERN_WITH_REGION_AND_SOLID_OCTANT_BLOCK_VECTOR, data: { // LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK - pattern: [[ + '\u{1FB94}': [ // LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK + { type: CustomGlyphDefinitionType.BLOCK_PATTERN_WITH_REGION, data: [[ [0, 1], [1, 0] - ], [0, 0, 0.5, 1]], - vectors: [{ x: 4, y: 0, w: 4, h: 8 }] - } }, + ], [0, 0, 0.5, 1]] }, + { type: CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR, data: [{ x: 4, y: 0, w: 4, h: 8 }] } + ], // Fill characters (1FB95-1FB97) '\u{1FB95}': { type: CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR, data: [ // CHECKER BOARD FILL diff --git a/addons/addon-webgl/src/customGlyphs/CustomGlyphRasterizer.ts b/addons/addon-webgl/src/customGlyphs/CustomGlyphRasterizer.ts index 5e557016..614941c3 100644 --- a/addons/addon-webgl/src/customGlyphs/CustomGlyphRasterizer.ts +++ b/addons/addon-webgl/src/customGlyphs/CustomGlyphRasterizer.ts @@ -5,7 +5,7 @@ import { throwIfFalsy } from 'browser/renderer/shared/RendererUtils'; import { customGlyphDefinitions } from './CustomGlyphDefinitions'; -import { CustomGlyphDefinitionType, CustomGlyphVectorType, type CustomGlyphPathDrawFunctionDefinition, type CustomGlyphPatternDefinition, type CustomGlyphRegionDefinition, type ICustomGlyphSolidOctantBlockVector, type ICustomGlyphVectorShape } from './Types'; +import { CustomGlyphDefinitionType, CustomGlyphVectorType, type CustomGlyphDefinitionPart, type CustomGlyphPathDrawFunctionDefinition, type CustomGlyphPatternDefinition, type CustomGlyphRegionDefinition, type ICustomGlyphSolidOctantBlockVector, type ICustomGlyphVectorShape } from './Types'; /** * Try drawing a custom block element or box drawing character, returning whether it was @@ -24,42 +24,57 @@ export function tryDrawCustomGlyph( ): boolean { const unifiedCharDefinition = customGlyphDefinitions[c]; if (unifiedCharDefinition) { - switch (unifiedCharDefinition.type) { - case CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR: - drawBlockVectorChar(ctx, unifiedCharDefinition.data, xOffset, yOffset, deviceCellWidth, deviceCellHeight); - return true; - case CustomGlyphDefinitionType.BLOCK_PATTERN: - drawPatternChar(ctx, unifiedCharDefinition.data, xOffset, yOffset, deviceCellWidth, deviceCellHeight); - return true; - case CustomGlyphDefinitionType.BLOCK_PATTERN_WITH_REGION: - drawBlockPatternWithRegion(ctx, unifiedCharDefinition.data, xOffset, yOffset, deviceCellWidth, deviceCellHeight); - return true; - case CustomGlyphDefinitionType.BLOCK_PATTERN_WITH_REGION_AND_SOLID_OCTANT_BLOCK_VECTOR: - 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); - return true; - case CustomGlyphDefinitionType.PATH_NEGATIVE: - drawPathNegativeDefinitionCharacter(ctx, unifiedCharDefinition.data, xOffset, yOffset, deviceCellWidth, deviceCellHeight, devicePixelRatio, backgroundColor); - return true; - case CustomGlyphDefinitionType.VECTOR_SHAPE: - drawVectorShape(ctx, unifiedCharDefinition.data, xOffset, yOffset, deviceCellWidth, deviceCellHeight, fontSize, devicePixelRatio); - return true; - case CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT: - drawPathDefinitionCharacterWithWeight(ctx, unifiedCharDefinition.data, xOffset, yOffset, deviceCellWidth, deviceCellHeight, devicePixelRatio); - return true; + // Normalize to array for uniform handling + const parts = Array.isArray(unifiedCharDefinition) ? unifiedCharDefinition : [unifiedCharDefinition]; + for (const part of parts) { + drawDefinitionPart(ctx, part, xOffset, yOffset, deviceCellWidth, deviceCellHeight, fontSize, devicePixelRatio, backgroundColor); } + return true; } return false; } +function drawDefinitionPart( + ctx: CanvasRenderingContext2D, + part: CustomGlyphDefinitionPart, + xOffset: number, + yOffset: number, + deviceCellWidth: number, + deviceCellHeight: number, + fontSize: number, + devicePixelRatio: number, + backgroundColor?: string +): void { + switch (part.type) { + case CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR: + drawBlockVectorChar(ctx, part.data, xOffset, yOffset, deviceCellWidth, deviceCellHeight); + break; + case CustomGlyphDefinitionType.BLOCK_PATTERN: + drawPatternChar(ctx, part.data, xOffset, yOffset, deviceCellWidth, deviceCellHeight); + break; + 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); + break; + case CustomGlyphDefinitionType.PATH_NEGATIVE: + drawPathNegativeDefinitionCharacter(ctx, part.data, xOffset, yOffset, deviceCellWidth, deviceCellHeight, devicePixelRatio, backgroundColor); + break; + case CustomGlyphDefinitionType.VECTOR_SHAPE: + drawVectorShape(ctx, part.data, xOffset, yOffset, deviceCellWidth, deviceCellHeight, fontSize, devicePixelRatio); + break; + case CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT: + drawPathDefinitionCharacterWithWeight(ctx, part.data, xOffset, yOffset, deviceCellWidth, deviceCellHeight, devicePixelRatio); + break; + } +} + function drawBlockVectorChar( ctx: CanvasRenderingContext2D, charDefinition: ICustomGlyphSolidOctantBlockVector[], @@ -432,46 +447,6 @@ function drawBlockPatternWithRegion( ctx.restore(); } -/** - * Draws the following box drawing characters by mapping a subset of SVG d attribute instructions to - * canvas draw calls. - * - * Box styles: ┎┰┒┍┯┑╓╥╖╒╤╕ ┏┳┓┌┲┓┌┬┐┏┱┐ - * ┌─┬─┐ ┏━┳━┓ ╔═╦═╗ ┠╂┨┝┿┥╟╫╢╞╪╡ ┡╇┩├╊┫┢╈┪┣╉┤ - * │ │ │ ┃ ┃ ┃ ║ ║ ║ ┖┸┚┕┷┙╙╨╜╘╧╛ └┴┘└┺┛┗┻┛┗┹┘ - * ├─┼─┤ ┣━╋━┫ ╠═╬═╣ ┏┱┐┌┲┓┌┬┐┌┬┐ ┏┳┓┌┮┓┌┬┐┏┭┐ - * │ │ │ ┃ ┃ ┃ ║ ║ ║ ┡╃┤├╄┩├╆┪┢╅┤ ┞╀┦├┾┫┟╁┧┣┽┤ - * └─┴─┘ ┗━┻━┛ ╚═╩═╝ └┴┘└┴┘└┺┛┗┹┘ └┴┘└┶┛┗┻┛┗┵┘ - * - * Other: - * ╭─╮ ╲ ╱ ╷╻╎╏┆┇┊┋ ╺╾╴ ╌╌╌ ┄┄┄ ┈┈┈ - * │ │ ╳ ╽╿╎╏┆┇┊┋ ╶╼╸ ╍╍╍ ┅┅┅ ┉┉┉ - * ╰─╯ ╱ ╲ ╹╵╎╏┆┇┊┋ - * - * All box drawing characters: - * ─ ━ │ ┃ ┄ ┅ ┆ ┇ ┈ ┉ ┊ ┋ ┌ ┍ ┎ ┏ - * ┐ ┑ ┒ ┓ └ ┕ ┖ ┗ ┘ ┙ ┚ ┛ ├ ┝ ┞ ┟ - * ┠ ┡ ┢ ┣ ┤ ┥ ┦ ┧ ┨ ┩ ┪ ┫ ┬ ┭ ┮ ┯ - * ┰ ┱ ┲ ┳ ┴ ┵ ┶ ┷ ┸ ┹ ┺ ┻ ┼ ┽ ┾ ┿ - * ╀ ╁ ╂ ╃ ╄ ╅ ╆ ╇ ╈ ╉ ╊ ╋ ╌ ╍ ╎ ╏ - * ═ ║ ╒ ╓ ╔ ╕ ╖ ╗ ╘ ╙ ╚ ╛ ╜ ╝ ╞ ╟ - * ╠ ╡ ╢ ╣ ╤ ╥ ╦ ╧ ╨ ╩ ╪ ╫ ╬ ╭ ╮ ╯ - * ╰ ╱ ╲ ╳ ╴ ╵ ╶ ╷ ╸ ╹ ╺ ╻ ╼ ╽ ╾ ╿ - * - * --- - * - * Box drawing alignment tests: █ - * ▉ - * ╔══╦══╗ ┌──┬──┐ ╭──┬──╮ ╭──┬──╮ ┏━━┳━━┓ ┎┒┏┑ ╷ ╻ ┏┯┓ ┌┰┐ ▊ ╱╲╱╲╳╳╳ - * ║┌─╨─┐║ │╔═╧═╗│ │╒═╪═╕│ │╓─╁─╖│ ┃┌─╂─┐┃ ┗╃╄┙ ╶┼╴╺╋╸┠┼┨ ┝╋┥ ▋ ╲╱╲╱╳╳╳ - * ║│╲ ╱│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╿ │┃ ┍╅╆┓ ╵ ╹ ┗┷┛ └┸┘ ▌ ╱╲╱╲╳╳╳ - * ╠╡ ╳ ╞╣ ├╢ ╟┤ ├┼─┼─┼┤ ├╫─╂─╫┤ ┣┿╾┼╼┿┫ ┕┛┖┚ ┌┄┄┐ ╎ ┏┅┅┓ ┋ ▍ ╲╱╲╱╳╳╳ - * ║│╱ ╲│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╽ │┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▎ - * ║└─╥─┘║ │╚═╤═╝│ │╘═╪═╛│ │╙─╀─╜│ ┃└─╂─┘┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▏ - * ╚══╩══╝ └──┴──┘ ╰──┴──╯ ╰──┴──╯ ┗━━┻━━┛ └╌╌┘ ╎ ┗╍╍┛ ┋ ▁▂▃▄▅▆▇█ - * - * Source: https://www.w3.org/2001/06/utf-8-test/UTF-8-demo.html - */ function drawPathDefinitionCharacterWithWeight( ctx: CanvasRenderingContext2D, charDefinition: { [fontWeight: number]: string | ((xp: number, yp: number) => string) }, diff --git a/addons/addon-webgl/src/customGlyphs/Types.ts b/addons/addon-webgl/src/customGlyphs/Types.ts index 0cc8bdc8..52e81b55 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_REGION_AND_SOLID_OCTANT_BLOCK_VECTOR, BLOCK_PATTERN_WITH_CLIP_PATH, PATH_FUNCTION, PATH_FUNCTION_WITH_WEIGHT, @@ -45,13 +44,10 @@ export const enum CustomGlyphDefinitionType { export type CustomGlyphRegionDefinition = [x: number, y: number, w: number, h: number]; -export type CustomGlyphCharacterDefinition = ( +export type CustomGlyphDefinitionPart = ( { 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] } | - // 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 } } | @@ -59,3 +55,8 @@ export type CustomGlyphCharacterDefinition = ( { type: CustomGlyphDefinitionType.PATH_NEGATIVE, data: ICustomGlyphVectorShape } | { type: CustomGlyphDefinitionType.VECTOR_SHAPE, data: ICustomGlyphVectorShape } ); + +/** + * A character definition that can be a single part or an array of parts drawn in sequence. + */ +export type CustomGlyphCharacterDefinition = CustomGlyphDefinitionPart | CustomGlyphDefinitionPart[]; From 11dae84ff737d31eec3c99774160a89e77a1f606 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 24 Dec 2025 04:25:59 -0800 Subject: [PATCH 2/4] Support clip path on any draw definition --- .../customGlyphs/CustomGlyphDefinitions.ts | 16 +++++----- .../src/customGlyphs/CustomGlyphRasterizer.ts | 29 +++++++++---------- addons/addon-webgl/src/customGlyphs/Types.ts | 15 +++++++--- 3 files changed, 32 insertions(+), 28 deletions(-) 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. */ From 20fdfba16f66e4a05224b6e5dd7c3cdaa0d356ed Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 24 Dec 2025 04:33:32 -0800 Subject: [PATCH 3/4] Replace BLOCK_PATTERN_WITH_REGION with new clipPath --- .../customGlyphs/CustomGlyphDefinitions.ts | 32 +++++++-------- .../src/customGlyphs/CustomGlyphRasterizer.ts | 39 +------------------ addons/addon-webgl/src/customGlyphs/Types.ts | 4 -- 3 files changed, 17 insertions(+), 58 deletions(-) diff --git a/addons/addon-webgl/src/customGlyphs/CustomGlyphDefinitions.ts b/addons/addon-webgl/src/customGlyphs/CustomGlyphDefinitions.ts index 0dcbb8ed..9ede47de 100644 --- a/addons/addon-webgl/src/customGlyphs/CustomGlyphDefinitions.ts +++ b/addons/addon-webgl/src/customGlyphs/CustomGlyphDefinitions.ts @@ -432,46 +432,46 @@ export const customGlyphDefinitions: { [index: string]: CustomGlyphCharacterDefi '\u{1FB8B}': { type: CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR, data: [{ x: 1, y: 0, w: 7, h: 8 }] }, // RIGHT SEVEN EIGHTHS B0OCK // Rectangular shade characters (1FB8C-1FB94) - '\u{1FB8C}': { type: CustomGlyphDefinitionType.BLOCK_PATTERN_WITH_REGION, data: [[ // LEFT HALF MEDIUM SHADE + '\u{1FB8C}': { type: CustomGlyphDefinitionType.BLOCK_PATTERN, data: [ // LEFT HALF MEDIUM SHADE [1, 0], [0, 1] - ], [0, 0, 0.5, 1]] }, - '\u{1FB8D}': { type: CustomGlyphDefinitionType.BLOCK_PATTERN_WITH_REGION, data: [[ // RIGHT HALF MEDIUM SHADE + ], clipPath: 'M0,0 L0.5,0 L0.5,1 L0,1 Z' }, + '\u{1FB8D}': { type: CustomGlyphDefinitionType.BLOCK_PATTERN, data: [ // RIGHT HALF MEDIUM SHADE [1, 0], [0, 1] - ], [0.5, 0, 0.5, 1]] }, - '\u{1FB8E}': { type: CustomGlyphDefinitionType.BLOCK_PATTERN_WITH_REGION, data: [[ // UPPER HALF MEDIUM SHADE + ], clipPath: 'M0.5,0 L1,0 L1,1 L0.5,1 Z' }, + '\u{1FB8E}': { type: CustomGlyphDefinitionType.BLOCK_PATTERN, data: [ // UPPER HALF MEDIUM SHADE [1, 0], [0, 1] - ], [0, 0, 1, 0.5]] }, - '\u{1FB8F}': { type: CustomGlyphDefinitionType.BLOCK_PATTERN_WITH_REGION, data: [[ // LOWER HALF MEDIUM SHADE + ], clipPath: 'M0,0 L1,0 L1,0.5 L0,0.5 Z' }, + '\u{1FB8F}': { type: CustomGlyphDefinitionType.BLOCK_PATTERN, data: [ // LOWER HALF MEDIUM SHADE [1, 0], [0, 1] - ], [0, 0.5, 1, 0.5]] }, - '\u{1FB90}': { type: CustomGlyphDefinitionType.BLOCK_PATTERN_WITH_REGION, data: [[ // INVERSE MEDIUM SHADE + ], clipPath: 'M0,0.5 L1,0.5 L1,1 L0,1 Z' }, + '\u{1FB90}': { type: CustomGlyphDefinitionType.BLOCK_PATTERN, data: [ // INVERSE MEDIUM SHADE [0, 1], [1, 0] - ], [0, 0, 1, 1]] }, + ] }, '\u{1FB91}': [ // UPPER HALF BLOCK AND LOWER HALF INVERSE MEDIUM SHADE - { type: CustomGlyphDefinitionType.BLOCK_PATTERN_WITH_REGION, data: [[ + { type: CustomGlyphDefinitionType.BLOCK_PATTERN, data: [ [0, 1], [1, 0] - ], [0, 0.5, 1, 0.5]] }, + ], clipPath: 'M0,0.5 L1,0.5 L1,1 L0,1 Z' }, { type: CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR, data: [{ x: 0, y: 0, w: 8, h: 4 }] } ], '\u{1FB92}': [ // UPPER HALF INVERSE MEDIUM SHADE AND LOWER HALF BLOCK - { type: CustomGlyphDefinitionType.BLOCK_PATTERN_WITH_REGION, data: [[ + { type: CustomGlyphDefinitionType.BLOCK_PATTERN, data: [ [0, 1], [1, 0] - ], [0, 0, 1, 0.5]] }, + ], clipPath: 'M0,0 L1,0 L1,0.5 L0,0.5 Z' }, { type: CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR, data: [{ x: 0, y: 4, w: 8, h: 4 }] } ], // 1FB93 is '\u{1FB94}': [ // LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK - { type: CustomGlyphDefinitionType.BLOCK_PATTERN_WITH_REGION, data: [[ + { type: CustomGlyphDefinitionType.BLOCK_PATTERN, data: [ [0, 1], [1, 0] - ], [0, 0, 0.5, 1]] }, + ], clipPath: 'M0,0 L0.5,0 L0.5,1 L0,1 Z' }, { type: CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR, data: [{ x: 4, y: 0, w: 4, h: 8 }] } ], diff --git a/addons/addon-webgl/src/customGlyphs/CustomGlyphRasterizer.ts b/addons/addon-webgl/src/customGlyphs/CustomGlyphRasterizer.ts index b444fd31..a68cf4f2 100644 --- a/addons/addon-webgl/src/customGlyphs/CustomGlyphRasterizer.ts +++ b/addons/addon-webgl/src/customGlyphs/CustomGlyphRasterizer.ts @@ -5,7 +5,7 @@ import { throwIfFalsy } from 'browser/renderer/shared/RendererUtils'; import { customGlyphDefinitions } from './CustomGlyphDefinitions'; -import { CustomGlyphDefinitionType, CustomGlyphVectorType, type CustomGlyphDefinitionPart, type CustomGlyphPathDrawFunctionDefinition, type CustomGlyphPatternDefinition, type CustomGlyphRegionDefinition, type ICustomGlyphSolidOctantBlockVector, type ICustomGlyphVectorShape } from './Types'; +import { CustomGlyphDefinitionType, CustomGlyphVectorType, type CustomGlyphDefinitionPart, type CustomGlyphPathDrawFunctionDefinition, type CustomGlyphPatternDefinition, type ICustomGlyphSolidOctantBlockVector, type ICustomGlyphVectorShape } from './Types'; /** * Try drawing a custom block element or box drawing character, returning whether it was @@ -59,9 +59,6 @@ function drawDefinitionPart( case CustomGlyphDefinitionType.BLOCK_PATTERN: drawPatternChar(ctx, part.data, xOffset, yOffset, deviceCellWidth, deviceCellHeight); break; - case CustomGlyphDefinitionType.BLOCK_PATTERN_WITH_REGION: - drawBlockPatternWithRegion(ctx, part.data, xOffset, yOffset, deviceCellWidth, deviceCellHeight); - break; case CustomGlyphDefinitionType.PATH_FUNCTION: case CustomGlyphDefinitionType.PATH: drawPathDefinitionCharacter(ctx, part.data, xOffset, yOffset, deviceCellWidth, deviceCellHeight); @@ -420,40 +417,6 @@ function drawPatternChar( ctx.fillRect(xOffset, yOffset, deviceCellWidth, deviceCellHeight); } -/** - * Draws rectangular shade characters - medium shade pattern clipped to a region. - * Uses a checkerboard pattern that shifts 1px each row (same as medium shade U+2592). - */ -function drawBlockPatternWithRegion( - ctx: CanvasRenderingContext2D, - definition: [pattern: CustomGlyphPatternDefinition, region: CustomGlyphRegionDefinition], - xOffset: number, - yOffset: number, - deviceCellWidth: number, - deviceCellHeight: number -): void { - const [pattern, region] = definition; - const [rx, ry, rw, rh] = region; - const regionX = Math.round(xOffset + rx * deviceCellWidth); - const regionY = Math.round(yOffset + ry * deviceCellHeight); - const regionW = Math.round(rw * deviceCellWidth); - const regionH = Math.round(rh * deviceCellHeight); - - // Save context state - ctx.save(); - - // Clip to the region - ctx.beginPath(); - ctx.rect(regionX, regionY, regionW, regionH); - ctx.clip(); - - // Draw the pattern - drawPatternChar(ctx, pattern, xOffset, yOffset, deviceCellWidth, deviceCellHeight); - - // Restore context state - ctx.restore(); -} - function drawPathDefinitionCharacterWithWeight( ctx: CanvasRenderingContext2D, charDefinition: { [fontWeight: number]: string | ((xp: number, yp: number) => string) }, diff --git a/addons/addon-webgl/src/customGlyphs/Types.ts b/addons/addon-webgl/src/customGlyphs/Types.ts index 113522fd..faf31f3c 100644 --- a/addons/addon-webgl/src/customGlyphs/Types.ts +++ b/addons/addon-webgl/src/customGlyphs/Types.ts @@ -33,7 +33,6 @@ export type CustomGlyphPatternDefinition = number[][]; export const enum CustomGlyphDefinitionType { SOLID_OCTANT_BLOCK_VECTOR, BLOCK_PATTERN, - BLOCK_PATTERN_WITH_REGION, PATH_FUNCTION, PATH_FUNCTION_WITH_WEIGHT, PATH, @@ -41,12 +40,9 @@ export const enum CustomGlyphDefinitionType { VECTOR_SHAPE, } -export type CustomGlyphRegionDefinition = [x: number, y: number, w: number, h: number]; - 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.PATH_FUNCTION, data: CustomGlyphPathDrawFunctionDefinition } | { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [fontWeight: number]: string | CustomGlyphPathDrawFunctionDefinition } } | { type: CustomGlyphDefinitionType.PATH, data: string } | From ed779b9062fe9af5a59f38de8beb6c97190e5958 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 24 Dec 2025 06:14:12 -0800 Subject: [PATCH 4/4] Replace PATH_FUNCTION_WITH_WEIGHT with a generic strokeWidth prop --- .../customGlyphs/CustomGlyphDefinitions.ts | 329 +++++++++--------- .../src/customGlyphs/CustomGlyphRasterizer.ts | 70 ++-- addons/addon-webgl/src/customGlyphs/Types.ts | 8 +- 3 files changed, 201 insertions(+), 206 deletions(-) diff --git a/addons/addon-webgl/src/customGlyphs/CustomGlyphDefinitions.ts b/addons/addon-webgl/src/customGlyphs/CustomGlyphDefinitions.ts index 9ede47de..0bea7f3d 100644 --- a/addons/addon-webgl/src/customGlyphs/CustomGlyphDefinitions.ts +++ b/addons/addon-webgl/src/customGlyphs/CustomGlyphDefinitions.ts @@ -14,152 +14,152 @@ export const customGlyphDefinitions: { [index: string]: CustomGlyphCharacterDefi // https://www.unicode.org/charts/PDF/U2500.pdf // Light and heavy solid lines (2500-2503) - '─': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.LEFT_TO_RIGHT } }, - '━': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.BOLD]: Shapes.LEFT_TO_RIGHT } }, - '│': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.TOP_TO_BOTTOM } }, - '┃': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.BOLD]: Shapes.TOP_TO_BOTTOM } }, + '─': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.LEFT_TO_RIGHT, strokeWidth: 1 }, + '━': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.LEFT_TO_RIGHT, strokeWidth: 3 }, + '│': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.TOP_TO_BOTTOM, strokeWidth: 1 }, + '┃': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.TOP_TO_BOTTOM, strokeWidth: 3 }, // Light and heavy dashed lines (2504-250B) - '┄': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.THREE_DASHES_HORIZONTAL } }, - '┅': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.BOLD]: Shapes.THREE_DASHES_HORIZONTAL } }, - '┆': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.THREE_DASHES_VERTICAL } }, - '┇': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.BOLD]: Shapes.THREE_DASHES_VERTICAL } }, - '┈': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.FOUR_DASHES_HORIZONTAL } }, - '┉': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.BOLD]: Shapes.FOUR_DASHES_HORIZONTAL } }, - '┊': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.FOUR_DASHES_VERTICAL } }, - '┋': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.BOLD]: Shapes.FOUR_DASHES_VERTICAL } }, + '┄': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.THREE_DASHES_HORIZONTAL, strokeWidth: 1 }, + '┅': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.THREE_DASHES_HORIZONTAL, strokeWidth: 3 }, + '┆': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.THREE_DASHES_VERTICAL, strokeWidth: 1 }, + '┇': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.THREE_DASHES_VERTICAL, strokeWidth: 3 }, + '┈': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.FOUR_DASHES_HORIZONTAL, strokeWidth: 1 }, + '┉': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.FOUR_DASHES_HORIZONTAL, strokeWidth: 3 }, + '┊': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.FOUR_DASHES_VERTICAL, strokeWidth: 1 }, + '┋': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.FOUR_DASHES_VERTICAL, strokeWidth: 3 }, // Light and heavy line box components (250C-254B) - '┌': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.RIGHT_TO_BOTTOM } }, - '┍': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.MIDDLE_TO_BOTTOM, [FontWeight.BOLD]: Shapes.MIDDLE_TO_RIGHT } }, - '┎': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.MIDDLE_TO_RIGHT, [FontWeight.BOLD]: Shapes.MIDDLE_TO_BOTTOM } }, - '┏': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.BOLD]: Shapes.RIGHT_TO_BOTTOM } }, - '┐': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.LEFT_TO_BOTTOM } }, - '┑': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.MIDDLE_TO_BOTTOM, [FontWeight.BOLD]: Shapes.MIDDLE_TO_LEFT } }, - '┒': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.MIDDLE_TO_LEFT, [FontWeight.BOLD]: Shapes.MIDDLE_TO_BOTTOM } }, - '┓': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.BOLD]: Shapes.LEFT_TO_BOTTOM } }, - '└': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.TOP_TO_RIGHT } }, - '┕': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.MIDDLE_TO_TOP, [FontWeight.BOLD]: Shapes.MIDDLE_TO_RIGHT } }, - '┖': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.MIDDLE_TO_RIGHT, [FontWeight.BOLD]: Shapes.MIDDLE_TO_TOP } }, - '┗': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.BOLD]: Shapes.TOP_TO_RIGHT } }, - '┘': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.TOP_TO_LEFT } }, - '┙': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.MIDDLE_TO_TOP, [FontWeight.BOLD]: Shapes.MIDDLE_TO_LEFT } }, - '┚': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.MIDDLE_TO_LEFT, [FontWeight.BOLD]: Shapes.MIDDLE_TO_TOP } }, - '┛': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.BOLD]: Shapes.TOP_TO_LEFT } }, - '├': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.T_RIGHT } }, - '┝': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.TOP_TO_BOTTOM, [FontWeight.BOLD]: Shapes.MIDDLE_TO_RIGHT } }, - '┞': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.RIGHT_TO_BOTTOM, [FontWeight.BOLD]: Shapes.MIDDLE_TO_TOP } }, - '┟': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.TOP_TO_RIGHT, [FontWeight.BOLD]: Shapes.MIDDLE_TO_BOTTOM } }, - '┠': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.MIDDLE_TO_RIGHT, [FontWeight.BOLD]: Shapes.TOP_TO_BOTTOM } }, - '┡': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.MIDDLE_TO_BOTTOM, [FontWeight.BOLD]: Shapes.TOP_TO_RIGHT } }, - '┢': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.MIDDLE_TO_TOP, [FontWeight.BOLD]: Shapes.RIGHT_TO_BOTTOM } }, - '┣': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.BOLD]: Shapes.T_RIGHT } }, - '┤': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.T_LEFT } }, - '┥': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.TOP_TO_BOTTOM, [FontWeight.BOLD]: Shapes.MIDDLE_TO_LEFT } }, - '┦': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.LEFT_TO_BOTTOM, [FontWeight.BOLD]: Shapes.MIDDLE_TO_TOP } }, - '┧': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.TOP_TO_LEFT, [FontWeight.BOLD]: Shapes.MIDDLE_TO_BOTTOM } }, - '┨': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.MIDDLE_TO_LEFT, [FontWeight.BOLD]: Shapes.TOP_TO_BOTTOM } }, - '┩': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.MIDDLE_TO_BOTTOM, [FontWeight.BOLD]: Shapes.TOP_TO_LEFT } }, - '┪': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.MIDDLE_TO_TOP, [FontWeight.BOLD]: Shapes.LEFT_TO_BOTTOM } }, - '┫': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.BOLD]: Shapes.T_LEFT } }, - '┬': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.T_BOTTOM } }, - '┭': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.RIGHT_TO_BOTTOM, [FontWeight.BOLD]: Shapes.MIDDLE_TO_LEFT } }, - '┮': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.LEFT_TO_BOTTOM, [FontWeight.BOLD]: Shapes.MIDDLE_TO_RIGHT } }, - '┯': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.MIDDLE_TO_BOTTOM, [FontWeight.BOLD]: Shapes.LEFT_TO_RIGHT } }, - '┰': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.LEFT_TO_RIGHT, [FontWeight.BOLD]: Shapes.MIDDLE_TO_BOTTOM } }, - '┱': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.MIDDLE_TO_RIGHT, [FontWeight.BOLD]: Shapes.LEFT_TO_BOTTOM } }, - '┲': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.MIDDLE_TO_LEFT, [FontWeight.BOLD]: Shapes.RIGHT_TO_BOTTOM } }, - '┳': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.BOLD]: Shapes.T_BOTTOM } }, - '┴': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.T_TOP } }, - '┵': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.TOP_TO_RIGHT, [FontWeight.BOLD]: Shapes.MIDDLE_TO_LEFT } }, - '┶': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.TOP_TO_LEFT, [FontWeight.BOLD]: Shapes.MIDDLE_TO_RIGHT } }, - '┷': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.MIDDLE_TO_TOP, [FontWeight.BOLD]: Shapes.LEFT_TO_RIGHT } }, - '┸': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.LEFT_TO_RIGHT, [FontWeight.BOLD]: Shapes.MIDDLE_TO_TOP } }, - '┹': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.MIDDLE_TO_RIGHT, [FontWeight.BOLD]: Shapes.TOP_TO_LEFT } }, - '┺': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.MIDDLE_TO_LEFT, [FontWeight.BOLD]: Shapes.TOP_TO_RIGHT } }, - '┻': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.BOLD]: Shapes.T_TOP } }, - '┼': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.CROSS } }, - '┽': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: `${Shapes.TOP_TO_BOTTOM} ${Shapes.MIDDLE_TO_RIGHT}`, [FontWeight.BOLD]: Shapes.MIDDLE_TO_LEFT } }, - '┾': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: `${Shapes.TOP_TO_BOTTOM} ${Shapes.MIDDLE_TO_LEFT}`, [FontWeight.BOLD]: Shapes.MIDDLE_TO_RIGHT } }, - '┿': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.TOP_TO_BOTTOM, [FontWeight.BOLD]: Shapes.LEFT_TO_RIGHT } }, - '╀': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: `${Shapes.LEFT_TO_RIGHT} ${Shapes.MIDDLE_TO_BOTTOM}`, [FontWeight.BOLD]: Shapes.MIDDLE_TO_TOP } }, - '╁': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: `${Shapes.MIDDLE_TO_TOP} ${Shapes.LEFT_TO_RIGHT}`, [FontWeight.BOLD]: Shapes.MIDDLE_TO_BOTTOM } }, - '╂': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.LEFT_TO_RIGHT, [FontWeight.BOLD]: Shapes.TOP_TO_BOTTOM } }, - '╃': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.RIGHT_TO_BOTTOM, [FontWeight.BOLD]: Shapes.TOP_TO_LEFT } }, - '╄': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.LEFT_TO_BOTTOM, [FontWeight.BOLD]: Shapes.TOP_TO_RIGHT } }, - '╅': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.TOP_TO_RIGHT, [FontWeight.BOLD]: Shapes.LEFT_TO_BOTTOM } }, - '╆': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.TOP_TO_LEFT, [FontWeight.BOLD]: Shapes.RIGHT_TO_BOTTOM } }, - '╇': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.MIDDLE_TO_BOTTOM, [FontWeight.BOLD]: `${Shapes.MIDDLE_TO_TOP} ${Shapes.LEFT_TO_RIGHT}` } }, - '╈': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.MIDDLE_TO_TOP, [FontWeight.BOLD]: `${Shapes.LEFT_TO_RIGHT} ${Shapes.MIDDLE_TO_BOTTOM}` } }, - '╉': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.MIDDLE_TO_RIGHT, [FontWeight.BOLD]: `${Shapes.TOP_TO_BOTTOM} ${Shapes.MIDDLE_TO_LEFT}` } }, - '╊': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.MIDDLE_TO_LEFT, [FontWeight.BOLD]: `${Shapes.TOP_TO_BOTTOM} ${Shapes.MIDDLE_TO_RIGHT}` } }, - '╋': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.BOLD]: Shapes.CROSS } }, + '┌': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.RIGHT_TO_BOTTOM, strokeWidth: 1 }, + '┍': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_BOTTOM, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_RIGHT, strokeWidth: 3 }], + '┎': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_RIGHT, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_BOTTOM, strokeWidth: 3 }], + '┏': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.RIGHT_TO_BOTTOM, strokeWidth: 3 }, + '┐': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.LEFT_TO_BOTTOM, strokeWidth: 1 }, + '┑': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_BOTTOM, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_LEFT, strokeWidth: 3 }], + '┒': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_LEFT, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_BOTTOM, strokeWidth: 3 }], + '┓': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.LEFT_TO_BOTTOM, strokeWidth: 3 }, + '└': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.TOP_TO_RIGHT, strokeWidth: 1 }, + '┕': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_TOP, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_RIGHT, strokeWidth: 3 }], + '┖': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_RIGHT, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_TOP, strokeWidth: 3 }], + '┗': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.TOP_TO_RIGHT, strokeWidth: 3 }, + '┘': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.TOP_TO_LEFT, strokeWidth: 1 }, + '┙': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_TOP, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_LEFT, strokeWidth: 3 }], + '┚': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_LEFT, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_TOP, strokeWidth: 3 }], + '┛': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.TOP_TO_LEFT, strokeWidth: 3 }, + '├': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.T_RIGHT, strokeWidth: 1 }, + '┝': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.TOP_TO_BOTTOM, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_RIGHT, strokeWidth: 3 }], + '┞': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.RIGHT_TO_BOTTOM, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_TOP, strokeWidth: 3 }], + '┟': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.TOP_TO_RIGHT, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_BOTTOM, strokeWidth: 3 }], + '┠': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_RIGHT, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.TOP_TO_BOTTOM, strokeWidth: 3 }], + '┡': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_BOTTOM, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.TOP_TO_RIGHT, strokeWidth: 3 }], + '┢': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_TOP, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.RIGHT_TO_BOTTOM, strokeWidth: 3 }], + '┣': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.T_RIGHT, strokeWidth: 3 }, + '┤': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.T_LEFT, strokeWidth: 1 }, + '┥': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.TOP_TO_BOTTOM, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_LEFT, strokeWidth: 3 }], + '┦': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.LEFT_TO_BOTTOM, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_TOP, strokeWidth: 3 }], + '┧': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.TOP_TO_LEFT, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_BOTTOM, strokeWidth: 3 }], + '┨': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_LEFT, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.TOP_TO_BOTTOM, strokeWidth: 3 }], + '┩': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_BOTTOM, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.TOP_TO_LEFT, strokeWidth: 3 }], + '┪': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_TOP, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.LEFT_TO_BOTTOM, strokeWidth: 3 }], + '┫': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.T_LEFT, strokeWidth: 3 }, + '┬': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.T_BOTTOM, strokeWidth: 1 }, + '┭': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.RIGHT_TO_BOTTOM, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_LEFT, strokeWidth: 3 }], + '┮': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.LEFT_TO_BOTTOM, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_RIGHT, strokeWidth: 3 }], + '┯': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_BOTTOM, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.LEFT_TO_RIGHT, strokeWidth: 3 }], + '┰': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.LEFT_TO_RIGHT, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_BOTTOM, strokeWidth: 3 }], + '┱': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_RIGHT, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.LEFT_TO_BOTTOM, strokeWidth: 3 }], + '┲': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_LEFT, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.RIGHT_TO_BOTTOM, strokeWidth: 3 }], + '┳': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.T_BOTTOM, strokeWidth: 3 }, + '┴': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.T_TOP, strokeWidth: 1 }, + '┵': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.TOP_TO_RIGHT, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_LEFT, strokeWidth: 3 }], + '┶': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.TOP_TO_LEFT, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_RIGHT, strokeWidth: 3 }], + '┷': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_TOP, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.LEFT_TO_RIGHT, strokeWidth: 3 }], + '┸': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.LEFT_TO_RIGHT, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_TOP, strokeWidth: 3 }], + '┹': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_RIGHT, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.TOP_TO_LEFT, strokeWidth: 3 }], + '┺': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_LEFT, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.TOP_TO_RIGHT, strokeWidth: 3 }], + '┻': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.T_TOP, strokeWidth: 3 }, + '┼': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.CROSS, strokeWidth: 1 }, + '┽': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: `${Shapes.TOP_TO_BOTTOM} ${Shapes.MIDDLE_TO_RIGHT}`, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_LEFT, strokeWidth: 3 }], + '┾': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: `${Shapes.TOP_TO_BOTTOM} ${Shapes.MIDDLE_TO_LEFT}`, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_RIGHT, strokeWidth: 3 }], + '┿': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.TOP_TO_BOTTOM, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.LEFT_TO_RIGHT, strokeWidth: 3 }], + '╀': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: `${Shapes.LEFT_TO_RIGHT} ${Shapes.MIDDLE_TO_BOTTOM}`, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_TOP, strokeWidth: 3 }], + '╁': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: `${Shapes.MIDDLE_TO_TOP} ${Shapes.LEFT_TO_RIGHT}`, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_BOTTOM, strokeWidth: 3 }], + '╂': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.LEFT_TO_RIGHT, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.TOP_TO_BOTTOM, strokeWidth: 3 }], + '╃': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.RIGHT_TO_BOTTOM, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.TOP_TO_LEFT, strokeWidth: 3 }], + '╄': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.LEFT_TO_BOTTOM, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.TOP_TO_RIGHT, strokeWidth: 3 }], + '╅': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.TOP_TO_RIGHT, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.LEFT_TO_BOTTOM, strokeWidth: 3 }], + '╆': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.TOP_TO_LEFT, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.RIGHT_TO_BOTTOM, strokeWidth: 3 }], + '╇': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_BOTTOM, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: `${Shapes.MIDDLE_TO_TOP} ${Shapes.LEFT_TO_RIGHT}`, strokeWidth: 3 }], + '╈': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_TOP, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: `${Shapes.LEFT_TO_RIGHT} ${Shapes.MIDDLE_TO_BOTTOM}`, strokeWidth: 3 }], + '╉': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_RIGHT, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: `${Shapes.TOP_TO_BOTTOM} ${Shapes.MIDDLE_TO_LEFT}`, strokeWidth: 3 }], + '╊': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_LEFT, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: `${Shapes.TOP_TO_BOTTOM} ${Shapes.MIDDLE_TO_RIGHT}`, strokeWidth: 3 }], + '╋': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.CROSS, strokeWidth: 3 }, // Light and heavy dashed lines (254C-254F) - '╌': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.TWO_DASHES_HORIZONTAL } }, - '╍': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.BOLD]: Shapes.TWO_DASHES_HORIZONTAL } }, - '╎': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.TWO_DASHES_VERTICAL } }, - '╏': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.BOLD]: Shapes.TWO_DASHES_VERTICAL } }, + '╌': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.TWO_DASHES_HORIZONTAL, strokeWidth: 1 }, + '╍': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.TWO_DASHES_HORIZONTAL, strokeWidth: 3 }, + '╎': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.TWO_DASHES_VERTICAL, strokeWidth: 1 }, + '╏': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.TWO_DASHES_VERTICAL, strokeWidth: 3 }, // Double lines (2550-2551) - '═': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: (xp, yp) => `M0,${.5 - yp} L1,${.5 - yp} M0,${.5 + yp} L1,${.5 + yp}` } }, - '║': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: (xp, yp) => `M${.5 - xp},0 L${.5 - xp},1 M${.5 + xp},0 L${.5 + xp},1` } }, + '═': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: (xp, yp) => `M0,${.5 - yp} L1,${.5 - yp} M0,${.5 + yp} L1,${.5 + yp}`, strokeWidth: 1 }, + '║': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: (xp, yp) => `M${.5 - xp},0 L${.5 - xp},1 M${.5 + xp},0 L${.5 + xp},1`, strokeWidth: 1 }, // Light and double line box components (2552-256C) - '╒': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: (xp, yp) => `M.5,1 L.5,${.5 - yp} L1,${.5 - yp} M.5,${.5 + yp} L1,${.5 + yp}` } }, - '╓': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: (xp, yp) => `M${.5 - xp},1 L${.5 - xp},.5 L1,.5 M${.5 + xp},.5 L${.5 + xp},1` } }, - '╔': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: (xp, yp) => `M1,${.5 - yp} L${.5 - xp},${.5 - yp} L${.5 - xp},1 M1,${.5 + yp} L${.5 + xp},${.5 + yp} L${.5 + xp},1` } }, - '╕': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: (xp, yp) => `M0,${.5 - yp} L.5,${.5 - yp} L.5,1 M0,${.5 + yp} L.5,${.5 + yp}` } }, - '╖': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: (xp, yp) => `M${.5 + xp},1 L${.5 + xp},.5 L0,.5 M${.5 - xp},.5 L${.5 - xp},1` } }, - '╗': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: (xp, yp) => `M0,${.5 + yp} L${.5 - xp},${.5 + yp} L${.5 - xp},1 M0,${.5 - yp} L${.5 + xp},${.5 - yp} L${.5 + xp},1` } }, - '╘': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: (xp, yp) => `M.5,0 L.5,${.5 + yp} L1,${.5 + yp} M.5,${.5 - yp} L1,${.5 - yp}` } }, - '╙': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: (xp, yp) => `M1,.5 L${.5 - xp},.5 L${.5 - xp},0 M${.5 + xp},.5 L${.5 + xp},0` } }, - '╚': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: (xp, yp) => `M1,${.5 - yp} L${.5 + xp},${.5 - yp} L${.5 + xp},0 M1,${.5 + yp} L${.5 - xp},${.5 + yp} L${.5 - xp},0` } }, - '╛': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: (xp, yp) => `M0,${.5 + yp} L.5,${.5 + yp} L.5,0 M0,${.5 - yp} L.5,${.5 - yp}` } }, - '╜': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: (xp, yp) => `M0,.5 L${.5 + xp},.5 L${.5 + xp},0 M${.5 - xp},.5 L${.5 - xp},0` } }, - '╝': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: (xp, yp) => `M0,${.5 - yp} L${.5 - xp},${.5 - yp} L${.5 - xp},0 M0,${.5 + yp} L${.5 + xp},${.5 + yp} L${.5 + xp},0` } }, - '╞': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: (xp, yp) => `${Shapes.TOP_TO_BOTTOM} M.5,${.5 - yp} L1,${.5 - yp} M.5,${.5 + yp} L1,${.5 + yp}` } }, - '╟': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: (xp, yp) => `M${.5 - xp},0 L${.5 - xp},1 M${.5 + xp},0 L${.5 + xp},1 M${.5 + xp},.5 L1,.5` } }, - '╠': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: (xp, yp) => `M${.5 - xp},0 L${.5 - xp},1 M1,${.5 + yp} L${.5 + xp},${.5 + yp} L${.5 + xp},1 M1,${.5 - yp} L${.5 + xp},${.5 - yp} L${.5 + xp},0` } }, - '╡': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: (xp, yp) => `${Shapes.TOP_TO_BOTTOM} M0,${.5 - yp} L.5,${.5 - yp} M0,${.5 + yp} L.5,${.5 + yp}` } }, - '╢': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: (xp, yp) => `M0,.5 L${.5 - xp},.5 M${.5 - xp},0 L${.5 - xp},1 M${.5 + xp},0 L${.5 + xp},1` } }, - '╣': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: (xp, yp) => `M${.5 + xp},0 L${.5 + xp},1 M0,${.5 + yp} L${.5 - xp},${.5 + yp} L${.5 - xp},1 M0,${.5 - yp} L${.5 - xp},${.5 - yp} L${.5 - xp},0` } }, - '╤': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: (xp, yp) => `M0,${.5 - yp} L1,${.5 - yp} M0,${.5 + yp} L1,${.5 + yp} M.5,${.5 + yp} L.5,1` } }, - '╥': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: (xp, yp) => `${Shapes.LEFT_TO_RIGHT} M${.5 - xp},.5 L${.5 - xp},1 M${.5 + xp},.5 L${.5 + xp},1` } }, - '╦': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: (xp, yp) => `M0,${.5 - yp} L1,${.5 - yp} M0,${.5 + yp} L${.5 - xp},${.5 + yp} L${.5 - xp},1 M1,${.5 + yp} L${.5 + xp},${.5 + yp} L${.5 + xp},1` } }, - '╧': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: (xp, yp) => `M.5,0 L.5,${.5 - yp} M0,${.5 - yp} L1,${.5 - yp} M0,${.5 + yp} L1,${.5 + yp}` } }, - '╨': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: (xp, yp) => `${Shapes.LEFT_TO_RIGHT} M${.5 - xp},.5 L${.5 - xp},0 M${.5 + xp},.5 L${.5 + xp},0` } }, - '╩': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: (xp, yp) => `M0,${.5 + yp} L1,${.5 + yp} M0,${.5 - yp} L${.5 - xp},${.5 - yp} L${.5 - xp},0 M1,${.5 - yp} L${.5 + xp},${.5 - yp} L${.5 + xp},0` } }, - '╪': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: (xp, yp) => `${Shapes.TOP_TO_BOTTOM} M0,${.5 - yp} L1,${.5 - yp} M0,${.5 + yp} L1,${.5 + yp}` } }, - '╫': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: (xp, yp) => `${Shapes.LEFT_TO_RIGHT} M${.5 - xp},0 L${.5 - xp},1 M${.5 + xp},0 L${.5 + xp},1` } }, - '╬': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: (xp, yp) => `M0,${.5 + yp} L${.5 - xp},${.5 + yp} L${.5 - xp},1 M1,${.5 + yp} L${.5 + xp},${.5 + yp} L${.5 + xp},1 M0,${.5 - yp} L${.5 - xp},${.5 - yp} L${.5 - xp},0 M1,${.5 - yp} L${.5 + xp},${.5 - yp} L${.5 + xp},0` } }, + '╒': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: (xp, yp) => `M.5,1 L.5,${.5 - yp} L1,${.5 - yp} M.5,${.5 + yp} L1,${.5 + yp}`, strokeWidth: 1 }, + '╓': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: (xp, yp) => `M${.5 - xp},1 L${.5 - xp},.5 L1,.5 M${.5 + xp},.5 L${.5 + xp},1`, strokeWidth: 1 }, + '╔': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: (xp, yp) => `M1,${.5 - yp} L${.5 - xp},${.5 - yp} L${.5 - xp},1 M1,${.5 + yp} L${.5 + xp},${.5 + yp} L${.5 + xp},1`, strokeWidth: 1 }, + '╕': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: (xp, yp) => `M0,${.5 - yp} L.5,${.5 - yp} L.5,1 M0,${.5 + yp} L.5,${.5 + yp}`, strokeWidth: 1 }, + '╖': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: (xp, yp) => `M${.5 + xp},1 L${.5 + xp},.5 L0,.5 M${.5 - xp},.5 L${.5 - xp},1`, strokeWidth: 1 }, + '╗': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: (xp, yp) => `M0,${.5 + yp} L${.5 - xp},${.5 + yp} L${.5 - xp},1 M0,${.5 - yp} L${.5 + xp},${.5 - yp} L${.5 + xp},1`, strokeWidth: 1 }, + '╘': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: (xp, yp) => `M.5,0 L.5,${.5 + yp} L1,${.5 + yp} M.5,${.5 - yp} L1,${.5 - yp}`, strokeWidth: 1 }, + '╙': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: (xp, yp) => `M1,.5 L${.5 - xp},.5 L${.5 - xp},0 M${.5 + xp},.5 L${.5 + xp},0`, strokeWidth: 1 }, + '╚': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: (xp, yp) => `M1,${.5 - yp} L${.5 + xp},${.5 - yp} L${.5 + xp},0 M1,${.5 + yp} L${.5 - xp},${.5 + yp} L${.5 - xp},0`, strokeWidth: 1 }, + '╛': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: (xp, yp) => `M0,${.5 + yp} L.5,${.5 + yp} L.5,0 M0,${.5 - yp} L.5,${.5 - yp}`, strokeWidth: 1 }, + '╜': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: (xp, yp) => `M0,.5 L${.5 + xp},.5 L${.5 + xp},0 M${.5 - xp},.5 L${.5 - xp},0`, strokeWidth: 1 }, + '╝': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: (xp, yp) => `M0,${.5 - yp} L${.5 - xp},${.5 - yp} L${.5 - xp},0 M0,${.5 + yp} L${.5 + xp},${.5 + yp} L${.5 + xp},0`, strokeWidth: 1 }, + '╞': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: (xp, yp) => `${Shapes.TOP_TO_BOTTOM} M.5,${.5 - yp} L1,${.5 - yp} M.5,${.5 + yp} L1,${.5 + yp}`, strokeWidth: 1 }, + '╟': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: (xp, yp) => `M${.5 - xp},0 L${.5 - xp},1 M${.5 + xp},0 L${.5 + xp},1 M${.5 + xp},.5 L1,.5`, strokeWidth: 1 }, + '╠': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: (xp, yp) => `M${.5 - xp},0 L${.5 - xp},1 M1,${.5 + yp} L${.5 + xp},${.5 + yp} L${.5 + xp},1 M1,${.5 - yp} L${.5 + xp},${.5 - yp} L${.5 + xp},0`, strokeWidth: 1 }, + '╡': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: (xp, yp) => `${Shapes.TOP_TO_BOTTOM} M0,${.5 - yp} L.5,${.5 - yp} M0,${.5 + yp} L.5,${.5 + yp}`, strokeWidth: 1 }, + '╢': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: (xp, yp) => `M0,.5 L${.5 - xp},.5 M${.5 - xp},0 L${.5 - xp},1 M${.5 + xp},0 L${.5 + xp},1`, strokeWidth: 1 }, + '╣': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: (xp, yp) => `M${.5 + xp},0 L${.5 + xp},1 M0,${.5 + yp} L${.5 - xp},${.5 + yp} L${.5 - xp},1 M0,${.5 - yp} L${.5 - xp},${.5 - yp} L${.5 - xp},0`, strokeWidth: 1 }, + '╤': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: (xp, yp) => `M0,${.5 - yp} L1,${.5 - yp} M0,${.5 + yp} L1,${.5 + yp} M.5,${.5 + yp} L.5,1`, strokeWidth: 1 }, + '╥': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: (xp, yp) => `${Shapes.LEFT_TO_RIGHT} M${.5 - xp},.5 L${.5 - xp},1 M${.5 + xp},.5 L${.5 + xp},1`, strokeWidth: 1 }, + '╦': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: (xp, yp) => `M0,${.5 - yp} L1,${.5 - yp} M0,${.5 + yp} L${.5 - xp},${.5 + yp} L${.5 - xp},1 M1,${.5 + yp} L${.5 + xp},${.5 + yp} L${.5 + xp},1`, strokeWidth: 1 }, + '╧': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: (xp, yp) => `M.5,0 L.5,${.5 - yp} M0,${.5 - yp} L1,${.5 - yp} M0,${.5 + yp} L1,${.5 + yp}`, strokeWidth: 1 }, + '╨': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: (xp, yp) => `${Shapes.LEFT_TO_RIGHT} M${.5 - xp},.5 L${.5 - xp},0 M${.5 + xp},.5 L${.5 + xp},0`, strokeWidth: 1 }, + '╩': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: (xp, yp) => `M0,${.5 + yp} L1,${.5 + yp} M0,${.5 - yp} L${.5 - xp},${.5 - yp} L${.5 - xp},0 M1,${.5 - yp} L${.5 + xp},${.5 - yp} L${.5 + xp},0`, strokeWidth: 1 }, + '╪': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: (xp, yp) => `${Shapes.TOP_TO_BOTTOM} M0,${.5 - yp} L1,${.5 - yp} M0,${.5 + yp} L1,${.5 + yp}`, strokeWidth: 1 }, + '╫': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: (xp, yp) => `${Shapes.LEFT_TO_RIGHT} M${.5 - xp},0 L${.5 - xp},1 M${.5 + xp},0 L${.5 + xp},1`, strokeWidth: 1 }, + '╬': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: (xp, yp) => `M0,${.5 + yp} L${.5 - xp},${.5 + yp} L${.5 - xp},1 M1,${.5 + yp} L${.5 + xp},${.5 + yp} L${.5 + xp},1 M0,${.5 - yp} L${.5 - xp},${.5 - yp} L${.5 - xp},0 M1,${.5 - yp} L${.5 + xp},${.5 - yp} L${.5 + xp},0`, strokeWidth: 1 }, // Character cell arcs (256D-2570) - '╭': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: (xp, yp) => `M.5,1 L.5,${.5 + (yp / .15 * .5)} C.5,${.5 + (yp / .15 * .5)},.5,.5,1,.5` } }, - '╮': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: (xp, yp) => `M.5,1 L.5,${.5 + (yp / .15 * .5)} C.5,${.5 + (yp / .15 * .5)},.5,.5,0,.5` } }, - '╯': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: (xp, yp) => `M.5,0 L.5,${.5 - (yp / .15 * .5)} C.5,${.5 - (yp / .15 * .5)},.5,.5,0,.5` } }, - '╰': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: (xp, yp) => `M.5,0 L.5,${.5 - (yp / .15 * .5)} C.5,${.5 - (yp / .15 * .5)},.5,.5,1,.5` } }, + '╭': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: (xp, yp) => `M.5,1 L.5,${.5 + (yp / .15 * .5)} C.5,${.5 + (yp / .15 * .5)},.5,.5,1,.5`, strokeWidth: 1 }, + '╮': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: (xp, yp) => `M.5,1 L.5,${.5 + (yp / .15 * .5)} C.5,${.5 + (yp / .15 * .5)},.5,.5,0,.5`, strokeWidth: 1 }, + '╯': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: (xp, yp) => `M.5,0 L.5,${.5 - (yp / .15 * .5)} C.5,${.5 - (yp / .15 * .5)},.5,.5,0,.5`, strokeWidth: 1 }, + '╰': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: (xp, yp) => `M.5,0 L.5,${.5 - (yp / .15 * .5)} C.5,${.5 - (yp / .15 * .5)},.5,.5,1,.5`, strokeWidth: 1 }, // Character cell diagonals (2571-2573) - '╱': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: 'M1,0 L0,1' } }, - '╲': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: 'M0,0 L1,1' } }, - '╳': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: 'M1,0 L0,1 M0,0 L1,1' } }, + '╱': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: 'M1,0 L0,1', strokeWidth: 1 }, + '╲': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: 'M0,0 L1,1', strokeWidth: 1 }, + '╳': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: 'M1,0 L0,1 M0,0 L1,1', strokeWidth: 1 }, // Light and heavy half lines (2574-257B) - '╴': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.MIDDLE_TO_LEFT } }, - '╵': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.MIDDLE_TO_TOP } }, - '╶': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.MIDDLE_TO_RIGHT } }, - '╷': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.MIDDLE_TO_BOTTOM } }, - '╸': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.BOLD]: Shapes.MIDDLE_TO_LEFT } }, - '╹': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.BOLD]: Shapes.MIDDLE_TO_TOP } }, - '╺': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.BOLD]: Shapes.MIDDLE_TO_RIGHT } }, - '╻': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.BOLD]: Shapes.MIDDLE_TO_BOTTOM } }, + '╴': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_LEFT, strokeWidth: 1 }, + '╵': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_TOP, strokeWidth: 1 }, + '╶': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_RIGHT, strokeWidth: 1 }, + '╷': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_BOTTOM, strokeWidth: 1 }, + '╸': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_LEFT, strokeWidth: 3 }, + '╹': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_TOP, strokeWidth: 3 }, + '╺': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_RIGHT, strokeWidth: 3 }, + '╻': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_BOTTOM, strokeWidth: 3 }, // Mixed light and heavy lines (257C-257F) - '╼': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.MIDDLE_TO_LEFT, [FontWeight.BOLD]: Shapes.MIDDLE_TO_RIGHT } }, - '╽': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.MIDDLE_TO_TOP, [FontWeight.BOLD]: Shapes.MIDDLE_TO_BOTTOM } }, - '╾': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.MIDDLE_TO_RIGHT, [FontWeight.BOLD]: Shapes.MIDDLE_TO_LEFT } }, - '╿': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: Shapes.MIDDLE_TO_BOTTOM, [FontWeight.BOLD]: Shapes.MIDDLE_TO_TOP } }, + '╼': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_LEFT, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_RIGHT, strokeWidth: 3 }], + '╽': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_TOP, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_BOTTOM, strokeWidth: 3 }], + '╾': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_RIGHT, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_LEFT, strokeWidth: 3 }], + '╿': [{ type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_BOTTOM, strokeWidth: 1 }, { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: Shapes.MIDDLE_TO_TOP, strokeWidth: 3 }], // #endregion @@ -493,8 +493,8 @@ export const customGlyphDefinitions: { [index: string]: CustomGlyphCharacterDefi ] }, // Diagonal fill characters (1FB98-1FB99) - '\u{1FB98}': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: 'M0,0 L1,1 M0,.25 L.75,1 M0,.5 L.5,1 M0,.75 L.25,1 M.25,0 L1,.75 M.5,0 L1,.5 M.75,0 L1,.25' } }, // UPPER LEFT TO LOWER RIGHT FILL - '\u{1FB99}': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: 'M0,.25 L.25,0 M0,.5 L.5,0 M0,.75 L.75,0 M0,1 L1,0 M.25,1 L1,.25 M.5,1 L1,.5 M.75,1 L1,.75' } }, // UPPER RIGHT TO LOWER LEFT FILL + '\u{1FB98}': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: 'M0,0 L1,1 M0,.25 L.75,1 M0,.5 L.5,1 M0,.75 L.25,1 M.25,0 L1,.75 M.5,0 L1,.5 M.75,0 L1,.25', strokeWidth: 1 }, // UPPER LEFT TO LOWER RIGHT FILL + '\u{1FB99}': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: 'M0,.25 L.25,0 M0,.5 L.5,0 M0,.75 L.75,0 M0,1 L1,0 M.25,1 L1,.25 M.5,1 L1,.5 M.75,1 L1,.75', strokeWidth: 1 }, // UPPER RIGHT TO LOWER LEFT FILL // Smooth mosaic terminal graphic characters (1FB9A-1FB9B) '\u{1FB9A}': { type: CustomGlyphDefinitionType.VECTOR_SHAPE, data: { d: 'M0,0 L.5,.5 L0,1 L1,1 L.5,.5 L1,0', type: CustomGlyphVectorType.FILL } }, // UPPER AND LOWER TRIANGULAR HALF BLOCK @@ -519,24 +519,24 @@ export const customGlyphDefinitions: { [index: string]: CustomGlyphCharacterDefi ], 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 - '\u{1FBA1}': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: 'M.5,0 L1,.5' } }, // BOX DRAWINGS LIGHT DIAGONAL UPPER CENTRE TO MIDDLE RIGHT - '\u{1FBA2}': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: 'M0,.5 L.5,1' } }, // BOX DRAWINGS LIGHT DIAGONAL MIDDLE LEFT TO LOWER CENTRE - '\u{1FBA3}': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: 'M1,.5 L.5,1' } }, // BOX DRAWINGS LIGHT DIAGONAL MIDDLE RIGHT TO LOWER CENTRE - '\u{1FBA4}': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: 'M.5,0 L0,.5 L.5,1' } }, // BOX DRAWINGS LIGHT DIAGONAL UPPER CENTRE TO MIDDLE LEFT TO LOWER CENTRE - '\u{1FBA5}': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: 'M.5,0 L1,.5 L.5,1' } }, // BOX DRAWINGS LIGHT DIAGONAL UPPER CENTRE TO MIDDLE RIGHT TO LOWER CENTRE - '\u{1FBA6}': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: 'M0,.5 L.5,1 L1,.5' } }, // BOX DRAWINGS LIGHT DIAGONAL MIDDLE LEFT TO LOWER CENTRE TO MIDDLE RIGHT - '\u{1FBA7}': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: 'M0,.5 L.5,0 L1,.5' } }, // BOX DRAWINGS LIGHT DIAGONAL MIDDLE LEFT TO UPPER CENTRE TO MIDDLE RIGHT - '\u{1FBA8}': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: 'M.5,0 L0,.5 M1,.5 L.5,1' } }, // BOX DRAWINGS LIGHT DIAGONAL UPPER CENTRE TO MIDDLE LEFT AND MIDDLE RIGHT TO LOWER CENTRE - '\u{1FBA9}': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: 'M.5,0 L1,.5 M0,.5 L.5,1' } }, // BOX DRAWINGS LIGHT DIAGONAL UPPER CENTRE TO MIDDLE RIGHT AND MIDDLE LEFT TO LOWER CENTRE - '\u{1FBAA}': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: 'M.5,0 L1,.5 L.5,1 L0,.5' } }, // BOX DRAWINGS LIGHT DIAGONAL UPPER CENTRE TO MIDDLE RIGHT TO LOWER CENTRE TO MIDDLE LEFT - '\u{1FBAB}': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: 'M.5,0 L0,.5 L.5,1 L1,.5' } }, // BOX DRAWINGS LIGHT DIAGONAL UPPER CENTRE TO MIDDLE LEFT TO LOWER CENTRE TO MIDDLE RIGHT - '\u{1FBAC}': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: 'M0,.5 L.5,0 L1,.5 L.5,1' } }, // BOX DRAWINGS LIGHT DIAGONAL MIDDLE LEFT TO UPPER CENTRE TO MIDDLE RIGHT TO LOWER CENTRE - '\u{1FBAD}': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: 'M1,.5 L.5,0 L0,.5 L.5,1' } }, // BOX DRAWINGS LIGHT DIAGONAL MIDDLE RIGHT TO UPPER CENTRE TO MIDDLE LEFT TO LOWER CENTRE - '\u{1FBAE}': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: 'M.5,0 L1,.5 L.5,1 L0,.5 Z' } }, // BOX DRAWINGS LIGHT DIAGONAL DIAMOND + '\u{1FBA0}': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: 'M.5,0 L0,.5', strokeWidth: 1 }, // BOX DRAWINGS LIGHT DIAGONAL UPPER CENTRE TO MIDDLE LEFT + '\u{1FBA1}': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: 'M.5,0 L1,.5', strokeWidth: 1 }, // BOX DRAWINGS LIGHT DIAGONAL UPPER CENTRE TO MIDDLE RIGHT + '\u{1FBA2}': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: 'M0,.5 L.5,1', strokeWidth: 1 }, // BOX DRAWINGS LIGHT DIAGONAL MIDDLE LEFT TO LOWER CENTRE + '\u{1FBA3}': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: 'M1,.5 L.5,1', strokeWidth: 1 }, // BOX DRAWINGS LIGHT DIAGONAL MIDDLE RIGHT TO LOWER CENTRE + '\u{1FBA4}': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: 'M.5,0 L0,.5 L.5,1', strokeWidth: 1 }, // BOX DRAWINGS LIGHT DIAGONAL UPPER CENTRE TO MIDDLE LEFT TO LOWER CENTRE + '\u{1FBA5}': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: 'M.5,0 L1,.5 L.5,1', strokeWidth: 1 }, // BOX DRAWINGS LIGHT DIAGONAL UPPER CENTRE TO MIDDLE RIGHT TO LOWER CENTRE + '\u{1FBA6}': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: 'M0,.5 L.5,1 L1,.5', strokeWidth: 1 }, // BOX DRAWINGS LIGHT DIAGONAL MIDDLE LEFT TO LOWER CENTRE TO MIDDLE RIGHT + '\u{1FBA7}': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: 'M0,.5 L.5,0 L1,.5', strokeWidth: 1 }, // BOX DRAWINGS LIGHT DIAGONAL MIDDLE LEFT TO UPPER CENTRE TO MIDDLE RIGHT + '\u{1FBA8}': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: 'M.5,0 L0,.5 M1,.5 L.5,1', strokeWidth: 1 }, // BOX DRAWINGS LIGHT DIAGONAL UPPER CENTRE TO MIDDLE LEFT AND MIDDLE RIGHT TO LOWER CENTRE + '\u{1FBA9}': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: 'M.5,0 L1,.5 M0,.5 L.5,1', strokeWidth: 1 }, // BOX DRAWINGS LIGHT DIAGONAL UPPER CENTRE TO MIDDLE RIGHT AND MIDDLE LEFT TO LOWER CENTRE + '\u{1FBAA}': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: 'M.5,0 L1,.5 L.5,1 L0,.5', strokeWidth: 1 }, // BOX DRAWINGS LIGHT DIAGONAL UPPER CENTRE TO MIDDLE RIGHT TO LOWER CENTRE TO MIDDLE LEFT + '\u{1FBAB}': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: 'M.5,0 L0,.5 L.5,1 L1,.5', strokeWidth: 1 }, // BOX DRAWINGS LIGHT DIAGONAL UPPER CENTRE TO MIDDLE LEFT TO LOWER CENTRE TO MIDDLE RIGHT + '\u{1FBAC}': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: 'M0,.5 L.5,0 L1,.5 L.5,1', strokeWidth: 1 }, // BOX DRAWINGS LIGHT DIAGONAL MIDDLE LEFT TO UPPER CENTRE TO MIDDLE RIGHT TO LOWER CENTRE + '\u{1FBAD}': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: 'M1,.5 L.5,0 L0,.5 L.5,1', strokeWidth: 1 }, // BOX DRAWINGS LIGHT DIAGONAL MIDDLE RIGHT TO UPPER CENTRE TO MIDDLE LEFT TO LOWER CENTRE + '\u{1FBAE}': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: 'M.5,0 L1,.5 L.5,1 L0,.5 Z', strokeWidth: 1 }, // BOX DRAWINGS LIGHT DIAGONAL DIAMOND // Light solid line with stroke (1FBAF-1FBAF) - '\u{1FBAF}': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: `${Shapes.LEFT_TO_RIGHT} M.5,.35 L.5,.65` } }, // BOX DRAWINGS LIGHT HORIZONTAL WITH VERTICAL STROKE + '\u{1FBAF}': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: `${Shapes.LEFT_TO_RIGHT} M.5,.35 L.5,.65`, strokeWidth: 1 }, // BOX DRAWINGS LIGHT HORIZONTAL WITH VERTICAL STROKE // Terminal graphic characters (1FBB0-1FBB3) '\u{1FBB0}': { type: CustomGlyphDefinitionType.PATH, data: 'M0.1,0.2 L0.1,.8 L.4,.6 L.9,0.6 Z' }, // ARROWHEAD-SHAPED POINTER @@ -586,22 +586,22 @@ export const customGlyphDefinitions: { [index: string]: CustomGlyphCharacterDefi '\u{1FBCF}': { type: CustomGlyphDefinitionType.PATH, data: 'M0,0 L0.3333,0 L0.3333,1 L0,1 Z' }, // LEFT ONE THIRD BLOCK // Character cell diagonals (1FBD0-1FBDF) - '\u{1FBD0}': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: 'M1,.5 L0,1' } }, // BOX DRAWINGS LIGHT DIAGONAL MIDDLE RIGHT TO LOWER LEFT - '\u{1FBD1}': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: 'M1,0 L0,.5' } }, // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO MIDDLE LEFT - '\u{1FBD2}': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: 'M0,0 L1,.5' } }, // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO MIDDLE RIGHT - '\u{1FBD3}': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: 'M0,.5 L1,1' } }, // BOX DRAWINGS LIGHT DIAGONAL MIDDLE LEFT TO LOWER RIGHT - '\u{1FBD4}': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: 'M0,0 L.5,1' } }, // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER CENTRE - '\u{1FBD5}': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: 'M.5,0 L1,1' } }, // BOX DRAWINGS LIGHT DIAGONAL UPPER CENTRE TO LOWER RIGHT - '\u{1FBD6}': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: 'M1,0 L.5,1' } }, // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER CENTRE - '\u{1FBD7}': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: 'M.5,0 L0,1' } }, // BOX DRAWINGS LIGHT DIAGONAL UPPER CENTRE TO LOWER LEFT - '\u{1FBD8}': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: 'M0,0 L.5,.5 L1,0' } }, // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO MIDDLE CENTRE TO UPPER RIGHT - '\u{1FBD9}': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: 'M1,0 L.5,.5 L1,1' } }, // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO MIDDLE CENTRE TO LOWER RIGHT - '\u{1FBDA}': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: 'M0,1 L.5,.5 L1,1' } }, // BOX DRAWINGS LIGHT DIAGONAL LOWER LEFT TO MIDDLE CENTRE TO LOWER RIGHT - '\u{1FBDB}': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: 'M0,0 L.5,.5 L0,1' } }, // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO MIDDLE CENTRE TO LOWER LEFT - '\u{1FBDC}': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: 'M0,0 L.5,1 L1,0' } }, // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER CENTRE TO UPPER RIGHT - '\u{1FBDD}': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: 'M1,0 L0,.5 L1,1' } }, // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO MIDDLE LEFT TO LOWER RIGHT - '\u{1FBDE}': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: 'M0,1 L.5,0 L1,1' } }, // BOX DRAWINGS LIGHT DIAGONAL LOWER LEFT TO UPPER CENTRE TO LOWER RIGHT - '\u{1FBDF}': { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [FontWeight.NORMAL]: 'M0,0 L1,.5 L0,1' } }, // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO MIDDLE RIGHT TO LOWER LEFT + '\u{1FBD0}': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: 'M1,.5 L0,1', strokeWidth: 1 }, // BOX DRAWINGS LIGHT DIAGONAL MIDDLE RIGHT TO LOWER LEFT + '\u{1FBD1}': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: 'M1,0 L0,.5', strokeWidth: 1 }, // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO MIDDLE LEFT + '\u{1FBD2}': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: 'M0,0 L1,.5', strokeWidth: 1 }, // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO MIDDLE RIGHT + '\u{1FBD3}': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: 'M0,.5 L1,1', strokeWidth: 1 }, // BOX DRAWINGS LIGHT DIAGONAL MIDDLE LEFT TO LOWER RIGHT + '\u{1FBD4}': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: 'M0,0 L.5,1', strokeWidth: 1 }, // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER CENTRE + '\u{1FBD5}': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: 'M.5,0 L1,1', strokeWidth: 1 }, // BOX DRAWINGS LIGHT DIAGONAL UPPER CENTRE TO LOWER RIGHT + '\u{1FBD6}': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: 'M1,0 L.5,1', strokeWidth: 1 }, // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER CENTRE + '\u{1FBD7}': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: 'M.5,0 L0,1', strokeWidth: 1 }, // BOX DRAWINGS LIGHT DIAGONAL UPPER CENTRE TO LOWER LEFT + '\u{1FBD8}': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: 'M0,0 L.5,.5 L1,0', strokeWidth: 1 }, // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO MIDDLE CENTRE TO UPPER RIGHT + '\u{1FBD9}': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: 'M1,0 L.5,.5 L1,1', strokeWidth: 1 }, // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO MIDDLE CENTRE TO LOWER RIGHT + '\u{1FBDA}': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: 'M0,1 L.5,.5 L1,1', strokeWidth: 1 }, // BOX DRAWINGS LIGHT DIAGONAL LOWER LEFT TO MIDDLE CENTRE TO LOWER RIGHT + '\u{1FBDB}': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: 'M0,0 L.5,.5 L0,1', strokeWidth: 1 }, // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO MIDDLE CENTRE TO LOWER LEFT + '\u{1FBDC}': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: 'M0,0 L.5,1 L1,0', strokeWidth: 1 }, // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER CENTRE TO UPPER RIGHT + '\u{1FBDD}': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: 'M1,0 L0,.5 L1,1', strokeWidth: 1 }, // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO MIDDLE LEFT TO LOWER RIGHT + '\u{1FBDE}': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: 'M0,1 L.5,0 L1,1', strokeWidth: 1 }, // BOX DRAWINGS LIGHT DIAGONAL LOWER LEFT TO UPPER CENTRE TO LOWER RIGHT + '\u{1FBDF}': { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: 'M0,0 L1,.5 L0,1', strokeWidth: 1 }, // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO MIDDLE RIGHT TO LOWER LEFT // Geometric shapes (1FBE0-1FBEF) '\u{1FBE0}': { type: CustomGlyphDefinitionType.VECTOR_SHAPE, data: { d: 'M0,0 C0,.276,.224,.5,.5,.5 C.776,.5,1,.276,1,0', type: CustomGlyphVectorType.STROKE } }, // TOP JUSTIFIED LOWER HALF WHITE CIRCLE @@ -814,8 +814,3 @@ const enum Shapes { /** ┆ */ THREE_DASHES_VERTICAL = 'M.5,.0667 L.5,.2667 M.5,.4 L.5,.6 M.5,.7333 L.5,.9333', /** ┊ */ FOUR_DASHES_VERTICAL = 'M.5,.05 L.5,.2 M.5,.3 L.5,.45 L.5,.55 M.5,.7 L.5,.95', } - -const enum FontWeight { - NORMAL = 1, - BOLD = 3 -} diff --git a/addons/addon-webgl/src/customGlyphs/CustomGlyphRasterizer.ts b/addons/addon-webgl/src/customGlyphs/CustomGlyphRasterizer.ts index a68cf4f2..b533c2d7 100644 --- a/addons/addon-webgl/src/customGlyphs/CustomGlyphRasterizer.ts +++ b/addons/addon-webgl/src/customGlyphs/CustomGlyphRasterizer.ts @@ -60,6 +60,8 @@ function drawDefinitionPart( drawPatternChar(ctx, part.data, xOffset, yOffset, deviceCellWidth, deviceCellHeight); break; case CustomGlyphDefinitionType.PATH_FUNCTION: + drawPathFunctionCharacter(ctx, part.data, xOffset, yOffset, deviceCellWidth, deviceCellHeight, devicePixelRatio, part.strokeWidth); + break; case CustomGlyphDefinitionType.PATH: drawPathDefinitionCharacter(ctx, part.data, xOffset, yOffset, deviceCellWidth, deviceCellHeight); break; @@ -69,9 +71,6 @@ function drawDefinitionPart( case CustomGlyphDefinitionType.VECTOR_SHAPE: drawVectorShape(ctx, part.data, xOffset, yOffset, deviceCellWidth, deviceCellHeight, fontSize, devicePixelRatio); break; - case CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT: - drawPathDefinitionCharacterWithWeight(ctx, part.data, xOffset, yOffset, deviceCellWidth, deviceCellHeight, devicePixelRatio); - break; } if (part.clipPath) { @@ -417,47 +416,46 @@ function drawPatternChar( ctx.fillRect(xOffset, yOffset, deviceCellWidth, deviceCellHeight); } -function drawPathDefinitionCharacterWithWeight( +function drawPathFunctionCharacter( ctx: CanvasRenderingContext2D, - charDefinition: { [fontWeight: number]: string | ((xp: number, yp: number) => string) }, + charDefinition: string | ((xp: number, yp: number) => string), xOffset: number, yOffset: number, deviceCellWidth: number, deviceCellHeight: number, - devicePixelRatio: number + devicePixelRatio: number, + strokeWidth?: number ): void { ctx.strokeStyle = ctx.fillStyle; - for (const [fontWeight, instructions] of Object.entries(charDefinition)) { - ctx.beginPath(); - ctx.lineWidth = devicePixelRatio * Number.parseInt(fontWeight); - let actualInstructions: string; - if (typeof instructions === 'function') { - const xp = .15; - const yp = .15 / deviceCellHeight * deviceCellWidth; - actualInstructions = instructions(xp, yp); - } else { - actualInstructions = instructions; - } - for (const instruction of actualInstructions.split(' ')) { - const type = instruction[0]; - if (type === 'Z') { - ctx.closePath(); - continue; - } - const f = svgToCanvasInstructionMap[type]; - if (!f) { - console.error(`Could not find drawing instructions for "${type}"`); - continue; - } - const args: string[] = instruction.substring(1).split(','); - if (!args[0] || !args[1]) { - continue; - } - f(ctx, translateArgs(args, deviceCellWidth, deviceCellHeight, xOffset, yOffset, true, devicePixelRatio)); - } - ctx.stroke(); - ctx.closePath(); + ctx.beginPath(); + ctx.lineWidth = devicePixelRatio * (strokeWidth ?? 1); + let actualInstructions: string; + if (typeof charDefinition === 'function') { + const xp = .15; + const yp = .15 / deviceCellHeight * deviceCellWidth; + actualInstructions = charDefinition(xp, yp); + } else { + actualInstructions = charDefinition; } + for (const instruction of actualInstructions.split(' ')) { + const type = instruction[0]; + if (type === 'Z') { + ctx.closePath(); + continue; + } + const f = svgToCanvasInstructionMap[type]; + if (!f) { + console.error(`Could not find drawing instructions for "${type}"`); + continue; + } + const args: string[] = instruction.substring(1).split(','); + if (!args[0] || !args[1]) { + continue; + } + f(ctx, translateArgs(args, deviceCellWidth, deviceCellHeight, xOffset, yOffset, true, devicePixelRatio)); + } + ctx.stroke(); + ctx.closePath(); } /** diff --git a/addons/addon-webgl/src/customGlyphs/Types.ts b/addons/addon-webgl/src/customGlyphs/Types.ts index faf31f3c..0e4a2fa6 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, PATH_FUNCTION, - PATH_FUNCTION_WITH_WEIGHT, PATH, PATH_NEGATIVE, VECTOR_SHAPE, @@ -43,8 +42,7 @@ export const enum CustomGlyphDefinitionType { export type CustomGlyphDefinitionPartRaw = ( { type: CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR, data: ICustomGlyphSolidOctantBlockVector[] } | { type: CustomGlyphDefinitionType.BLOCK_PATTERN, data: CustomGlyphPatternDefinition } | - { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: CustomGlyphPathDrawFunctionDefinition } | - { type: CustomGlyphDefinitionType.PATH_FUNCTION_WITH_WEIGHT, data: { [fontWeight: number]: string | CustomGlyphPathDrawFunctionDefinition } } | + { type: CustomGlyphDefinitionType.PATH_FUNCTION, data: CustomGlyphPathDrawFunctionDefinition | string } | { type: CustomGlyphDefinitionType.PATH, data: string } | { type: CustomGlyphDefinitionType.PATH_NEGATIVE, data: ICustomGlyphVectorShape } | { type: CustomGlyphDefinitionType.VECTOR_SHAPE, data: ICustomGlyphVectorShape} @@ -55,6 +53,10 @@ export interface ICustomGlyphDefinitionCommon { * A custom clip path for the draw definition, restricting the area it can draw to. */ clipPath?: string; + /** + * The stroke width to use when drawing the path. Defaults to 1. + */ + strokeWidth?: number; } export type CustomGlyphDefinitionPart = CustomGlyphDefinitionPartRaw & ICustomGlyphDefinitionCommon;