Start move to unified draw definition

Part of #5466
This commit is contained in:
Daniel Imms
2025-12-22 11:35:41 -08:00
parent ce41b175ee
commit 415de67106
6 changed files with 95 additions and 80 deletions
-8
View File
@@ -159,14 +159,6 @@
"@typescript-eslint/prefer-namespace-keyword": "warn",
"@typescript-eslint/type-annotation-spacing": "warn",
"comma-dangle": [
"warn",
{
"objects": "never",
"arrays": "never",
"functions": "never"
}
],
"curly": [
"warn",
"multi-line"
@@ -3,49 +3,67 @@
* @license MIT
*/
import { CustomGlyphVectorType, type CustomGlyphDrawFunctionDefinition, type CustomGlyphPatternDefinition, type ICustomGlyphSolidOctantBlockVector, type ICustomGlyphVectorShape } from 'customGlyphs/Types';
import { CustomGlyphDefinitionType, CustomGlyphVectorType, type CustomGlyphCharacterDefinition, type CustomGlyphDrawFunctionDefinition, type CustomGlyphPatternDefinition, type ICustomGlyphSolidOctantBlockVector, type ICustomGlyphVectorShape } from 'customGlyphs/Types';
/* eslint-disable @typescript-eslint/naming-convention */
export const unifiedCharDefinitions: { [index: string]: ICustomGlyphVectorShape[] | undefined } = {
export const unifiedCharDefinitions: { [index: string]: CustomGlyphCharacterDefinition | undefined } = {
// #region Block elements (2580-259F)
// Block elements (2580-2590)
// https://www.unicode.org/charts/PDF/U2580.pdf
'▀': { type: CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR, data: [{ x: 0, y: 0, w: 8, h: 4 }] }, // UPPER HALF BLOCK
'▁': { type: CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR, data: [{ x: 0, y: 7, w: 8, h: 1 }] }, // LOWER ONE EIGHTH BLOCK
'▂': { type: CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR, data: [{ x: 0, y: 6, w: 8, h: 2 }] }, // LOWER ONE QUARTER BLOCK
'▃': { type: CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR, data: [{ x: 0, y: 5, w: 8, h: 3 }] }, // LOWER THREE EIGHTHS BLOCK
'▄': { type: CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR, data: [{ x: 0, y: 4, w: 8, h: 4 }] }, // LOWER HALF BLOCK
'▅': { type: CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR, data: [{ x: 0, y: 3, w: 8, h: 5 }] }, // LOWER FIVE EIGHTHS BLOCK
'▆': { type: CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR, data: [{ x: 0, y: 2, w: 8, h: 6 }] }, // LOWER THREE QUARTERS BLOCK
'▇': { type: CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR, data: [{ x: 0, y: 1, w: 8, h: 7 }] }, // LOWER SEVEN EIGHTHS BLOCK
'█': { type: CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR, data: [{ x: 0, y: 0, w: 8, h: 8 }] }, // FULL BLOCK (=solid -> 25A0=black square)
'▉': { type: CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR, data: [{ x: 0, y: 0, w: 7, h: 8 }] }, // LEFT SEVEN EIGHTHS BLOCK
'▊': { type: CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR, data: [{ x: 0, y: 0, w: 6, h: 8 }] }, // LEFT THREE QUARTERS BLOCK
'▋': { type: CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR, data: [{ x: 0, y: 0, w: 5, h: 8 }] }, // LEFT FIVE EIGHTHS BLOCK
'▌': { type: CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR, data: [{ x: 0, y: 0, w: 4, h: 8 }] }, // LEFT HALF BLOCK
'▍': { type: CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR, data: [{ x: 0, y: 0, w: 3, h: 8 }] }, // LEFT THREE EIGHTHS BLOCK
'▎': { type: CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR, data: [{ x: 0, y: 0, w: 2, h: 8 }] }, // LEFT ONE QUARTER BLOCK
'▏': { type: CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR, data: [{ x: 0, y: 0, w: 1, h: 8 }] }, // LEFT ONE EIGHTH BLOCK
'▐': { type: CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR, data: [{ x: 4, y: 0, w: 4, h: 8 }] }, // RIGHT HALF BLOCK
// Shade characters (2591-2593)
'░': { type: CustomGlyphDefinitionType.BLOCK_PATTERN_DEFINITION, data: [ // LIGHT SHADE (25%)
[1, 0],
[0, 0]
] },
'▒': { type: CustomGlyphDefinitionType.BLOCK_PATTERN_DEFINITION, data: [ // MEDIUM SHADE (=speckles fill, dotted fill, 50%, used in mapping to cp949, -> 1FB90 inverse medium shade)
[1, 0],
[0, 1]
] },
'▓': { type: CustomGlyphDefinitionType.BLOCK_PATTERN_DEFINITION, data: [ // DARK SHADE (75%)
[1, 1],
[1, 0]
] },
// Block elements (2594-2595)
'▔': { type: CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR, data: [{ x: 0, y: 0, w: 8, h: 1 }] }, // UPPER ONE EIGHTH BLOCK
'▕': { type: CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR, data: [{ x: 7, y: 0, w: 1, h: 8 }] }, // RIGHT ONE EIGHTH BLOCK
// Terminal graphic characters (2596-259F)
'▖': { type: CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR, data: [{ x: 0, y: 4, w: 4, h: 4 }] }, // QUADRANT LOWER LEFT
'▗': { type: CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR, data: [{ x: 4, y: 4, w: 4, h: 4 }] }, // QUADRANT LOWER RIGHT
'▘': { type: CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR, data: [{ x: 0, y: 0, w: 4, h: 4 }] }, // QUADRANT UPPER LEFT
'▙': { type: CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR, data: [{ x: 0, y: 0, w: 4, h: 8 }, { x: 0, y: 4, w: 8, h: 4 }] }, // QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT (-> 1F67F reverse checker board, -> 1FB95 checker board fill)
'▚': { type: CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR, data: [{ x: 0, y: 0, w: 4, h: 4 }, { x: 4, y: 4, w: 4, h: 4 }] }, // QUADRANT UPPER LEFT AND LOWER RIGHT
'▛': { type: CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR, data: [{ x: 0, y: 0, w: 4, h: 8 }, { x: 4, y: 0, w: 4, h: 4 }] }, // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT
'▜': { type: CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR, data: [{ x: 0, y: 0, w: 8, h: 4 }, { x: 4, y: 0, w: 4, h: 8 }] }, // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT
'▝': { type: CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR, data: [{ x: 4, y: 0, w: 4, h: 4 }] }, // QUADRANT UPPER RIGHT
'▞': { type: CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR, data: [{ x: 4, y: 0, w: 4, h: 4 }, { x: 0, y: 4, w: 4, h: 4 }] }, // QUADRANT UPPER RIGHT AND LOWER LEFT (-> 1F67E checker board, 1FB96 inverse checker board fill)
'▟': { type: CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR, data: [{ x: 4, y: 0, w: 4, h: 8 }, { x: 0, y: 4, w: 8, h: 4 }] } // QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT
// #endregion
};
export const blockElementDefinitions: { [index: string]: ICustomGlyphSolidOctantBlockVector[] | undefined } = {
// Block elements (0x2580-0x2590)
'▀': [{ x: 0, y: 0, w: 8, h: 4 }], // UPPER HALF BLOCK
'▁': [{ x: 0, y: 7, w: 8, h: 1 }], // LOWER ONE EIGHTH BLOCK
'▂': [{ x: 0, y: 6, w: 8, h: 2 }], // LOWER ONE QUARTER BLOCK
'▃': [{ x: 0, y: 5, w: 8, h: 3 }], // LOWER THREE EIGHTHS BLOCK
'▄': [{ x: 0, y: 4, w: 8, h: 4 }], // LOWER HALF BLOCK
'▅': [{ x: 0, y: 3, w: 8, h: 5 }], // LOWER FIVE EIGHTHS BLOCK
'▆': [{ x: 0, y: 2, w: 8, h: 6 }], // LOWER THREE QUARTERS BLOCK
'▇': [{ x: 0, y: 1, w: 8, h: 7 }], // LOWER SEVEN EIGHTHS BLOCK
'█': [{ x: 0, y: 0, w: 8, h: 8 }], // FULL BLOCK
'▉': [{ x: 0, y: 0, w: 7, h: 8 }], // LEFT SEVEN EIGHTHS BLOCK
'▊': [{ x: 0, y: 0, w: 6, h: 8 }], // LEFT THREE QUARTERS BLOCK
'▋': [{ x: 0, y: 0, w: 5, h: 8 }], // LEFT FIVE EIGHTHS BLOCK
'▌': [{ x: 0, y: 0, w: 4, h: 8 }], // LEFT HALF BLOCK
'▍': [{ x: 0, y: 0, w: 3, h: 8 }], // LEFT THREE EIGHTHS BLOCK
'▎': [{ x: 0, y: 0, w: 2, h: 8 }], // LEFT ONE QUARTER BLOCK
'▏': [{ x: 0, y: 0, w: 1, h: 8 }], // LEFT ONE EIGHTH BLOCK
'▐': [{ x: 4, y: 0, w: 4, h: 8 }], // RIGHT HALF BLOCK
// Block elements (0x2594-0x2595)
'▔': [{ x: 0, y: 0, w: 8, h: 1 }], // UPPER ONE EIGHTH BLOCK
'▕': [{ x: 7, y: 0, w: 1, h: 8 }], // RIGHT ONE EIGHTH BLOCK
// Terminal graphic characters (0x2596-0x259F)
'▖': [{ x: 0, y: 4, w: 4, h: 4 }], // QUADRANT LOWER LEFT
'▗': [{ x: 4, y: 4, w: 4, h: 4 }], // QUADRANT LOWER RIGHT
'▘': [{ x: 0, y: 0, w: 4, h: 4 }], // QUADRANT UPPER LEFT
'▙': [{ x: 0, y: 0, w: 4, h: 8 }, { x: 0, y: 4, w: 8, h: 4 }], // QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT
'▚': [{ x: 0, y: 0, w: 4, h: 4 }, { x: 4, y: 4, w: 4, h: 4 }], // QUADRANT UPPER LEFT AND LOWER RIGHT
'▛': [{ x: 0, y: 0, w: 4, h: 8 }, { x: 4, y: 0, w: 4, h: 4 }], // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT
'▜': [{ x: 0, y: 0, w: 8, h: 4 }, { x: 4, y: 0, w: 4, h: 8 }], // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT
'▝': [{ x: 4, y: 0, w: 4, h: 4 }], // QUADRANT UPPER RIGHT
'▞': [{ x: 4, y: 0, w: 4, h: 4 }, { x: 0, y: 4, w: 4, h: 4 }], // QUADRANT UPPER RIGHT AND LOWER LEFT
'▟': [{ x: 4, y: 0, w: 4, h: 8 }, { x: 0, y: 4, w: 8, h: 4 }], // QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT
// VERTICAL ONE EIGHTH BLOCK-2 through VERTICAL ONE EIGHTH BLOCK-7
'\u{1FB70}': [{ x: 1, y: 0, w: 1, h: 8 }],
'\u{1FB71}': [{ x: 2, y: 0, w: 1, h: 8 }],
@@ -332,26 +350,6 @@ export const blockShadeComboDefinitions: { [index: string]: BlockShadeComboDefin
'\u{1FB94}': [[0.5, 0, 0.5, 1], [0, 0, 0.5, 1]] // LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK
};
/**
* Defines the repeating pattern used by special characters, the pattern is made up of a 2d array of
* pixel values to be filled (1) or not filled (0).
*/
export const patternCharacterDefinitions: { [key: string]: CustomGlyphPatternDefinition | undefined } = {
// Shade characters (0x2591-0x2593)
'░': [ // LIGHT SHADE (25%)
[1, 0],
[0, 0]
],
'▒': [ // MEDIUM SHADE (50%)
[1, 0],
[0, 1]
],
'▓': [ // DARK SHADE (75%)
[1, 1],
[1, 0]
]
};
const enum Shapes {
/** │ */ TOP_TO_BOTTOM = 'M.5,0 L.5,1',
/** ─ */ LEFT_TO_RIGHT = 'M0,.5 L1,.5',
@@ -4,8 +4,8 @@
*/
import { throwIfFalsy } from 'browser/renderer/shared/RendererUtils';
import { blockElementDefinitions, blockShadeComboDefinitions, boxDrawingDefinitions, patternCharacterDefinitions, powerlineDefinitions, rectangularShadeDefinitions, symbolsForLegacyComputingDefinitions } from 'customGlyphs/CustomGlyphDefinitions';
import { CustomGlyphVectorType, type CustomGlyphDrawFunctionDefinition, type CustomGlyphPatternDefinition, type ICustomGlyphSolidOctantBlockVector, type ICustomGlyphVectorShape } from 'customGlyphs/Types';
import { blockElementDefinitions, blockShadeComboDefinitions, boxDrawingDefinitions, powerlineDefinitions, rectangularShadeDefinitions, symbolsForLegacyComputingDefinitions, unifiedCharDefinitions } from 'customGlyphs/CustomGlyphDefinitions';
import { CustomGlyphDefinitionType, CustomGlyphVectorType, type CustomGlyphDrawFunctionDefinition, type CustomGlyphPatternDefinition, type ICustomGlyphSolidOctantBlockVector, type ICustomGlyphVectorShape } from 'customGlyphs/Types';
/**
* Try drawing a custom block element or box drawing character, returning whether it was
@@ -21,6 +21,18 @@ export function tryDrawCustomGlyph(
fontSize: number,
devicePixelRatio: number
): boolean {
const unifiedCharDefinition = unifiedCharDefinitions[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_DEFINITION:
drawPatternChar(ctx, unifiedCharDefinition.data, xOffset, yOffset, deviceCellWidth, deviceCellHeight);
return true;
}
}
const blockElementDefinition = blockElementDefinitions[c];
if (blockElementDefinition) {
drawBlockVectorChar(ctx, blockElementDefinition, xOffset, yOffset, deviceCellWidth, deviceCellHeight);
@@ -45,12 +57,6 @@ export function tryDrawCustomGlyph(
return true;
}
const patternDefinition = patternCharacterDefinitions[c];
if (patternDefinition) {
drawPatternChar(ctx, patternDefinition, xOffset, yOffset, deviceCellWidth, deviceCellHeight);
return true;
}
const boxDrawingDefinition = boxDrawingDefinitions[c];
if (boxDrawingDefinition) {
drawBoxDrawingChar(ctx, boxDrawingDefinition, xOffset, yOffset, deviceCellWidth, deviceCellHeight, devicePixelRatio);
@@ -29,3 +29,13 @@ export const enum CustomGlyphVectorType {
}
export type CustomGlyphPatternDefinition = number[][];
export const enum CustomGlyphDefinitionType {
SOLID_OCTANT_BLOCK_VECTOR,
BLOCK_PATTERN_DEFINITION,
}
export type CustomGlyphCharacterDefinition = (
{ type: CustomGlyphDefinitionType.SOLID_OCTANT_BLOCK_VECTOR, data: ICustomGlyphSolidOctantBlockVector[] } |
{ type: CustomGlyphDefinitionType.BLOCK_PATTERN_DEFINITION, data: CustomGlyphPatternDefinition }
);
+14 -5
View File
@@ -234,8 +234,8 @@ if (document.location.pathname === '/test') {
document.getElementById('create-new-window').addEventListener('click', createNewWindowButtonHandler);
document.getElementById('serialize').addEventListener('click', serializeButtonHandler);
document.getElementById('htmlserialize').addEventListener('click', htmlSerializeButtonHandler);
document.getElementById('custom-glyph').addEventListener('click', writeCustomGlyphHandler);
document.getElementById('symbols-for-legacy-computing').addEventListener('click', writeSymbolsForLegacyComputing);
document.getElementById('custom-glyph-alignment').addEventListener('click', customGlyphAlignmentHandler);
document.getElementById('custom-glyph-ranges').addEventListener('click', customGlyphRangesHandler);
document.getElementById('load-test').addEventListener('click', loadTest);
document.getElementById('load-test-long-lines').addEventListener('click', loadTestLongLines);
document.getElementById('print-cjk').addEventListener('click', addCjk);
@@ -786,7 +786,7 @@ function styleAtlasPage(e: HTMLCanvasElement): void {
e.style.height = `${e.height / window.devicePixelRatio}px`;
}
function writeCustomGlyphHandler(): void {
function customGlyphAlignmentHandler(): void {
term.write('\n\r');
term.write('\n\r');
term.write('Box styles: ┎┰┒┍┯┑╓╥╖╒╤╕ ┏┳┓┌┲┓┌┬┐┏┱┐\n\r');
@@ -839,10 +839,19 @@ function writeCustomGlyphHandler(): void {
window.scrollTo(0, 0);
}
function writeSymbolsForLegacyComputing(): void {
function customGlyphRangesHandler(): void {
// Box Elements
// 2580-259F
// https://www.unicode.org/charts/PDF/U2580.pdf
writeUnicodeTable(term, 'Box Elements', 0x2580, 0x259F, [
['Block elements', 0x2580, 0x2590],
['Shade characters', 0x2591, 0x2593],
['Block elements', 0x2594, 0x2595],
['Terminal graphic characters', 0x2596, 0x259F],
]);
// Symbols for Legacy Computing
// Range: 1FB001FBFF
// Source: The Unicode Standard, Version 17.0 https://www.unicode.org/charts/PDF/U1FB00.pdf
// https://www.unicode.org/charts/PDF/U1FB00.pdf
writeUnicodeTable(term, 'Symbols for Legacy Computing', 0x1FB00, 0x1FBFF, [
['Block mosaic terminal graphic characters (Sextants)', 0x1FB00, 0x1FB3B],
['Smooth mosaic terminal graphic characters', 0x1FB3C, 0x1FB6F],
+2 -2
View File
@@ -92,8 +92,8 @@
<dd><button id="print-cjk-sgr" title="Prints the 20977 characters from the CJK Unified Ideographs unicode block with randomized SGR attributes">CJK Unified Ideographs (random SGR)</button></dd>
<dt>Styles</dt>
<dd><button id="custom-glyph" title="Write custom box drawing and block element characters to the terminal">Test custom glyphs</button></dd>
<dd><button id="symbols-for-legacy-computing" title="Write this unicode range to the terminal">Print Symbols for Legacy Computing (Range: 1FB001FBFF)</button></dd>
<dd><button id="custom-glyph-alignment" title="Write custom glyph alignment tests to the terminal">Custom glyphs alignment test</button></dd>
<dd><button id="custom-glyph-ranges" title="Write custom glyph unicode range to the terminal">Custom glyph ranges</button></dd>
<dd><button id="powerline-symbol-test" title="Write powerline symbol characters to the terminal (\ue0a0+)">Powerline symbol test</button></dd>
<dd><button id="underline-test" title="Write text with Kitty's extended underline sequences">Underline test</button></dd>
<dd><button id="sgr-test" title="Write text with SGR attribute">SGR test</button></dd>