mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
Move rectangular shade chars into unified
This commit is contained in:
@@ -128,7 +128,7 @@ export const unifiedCharDefinitions: { [index: string]: CustomGlyphCharacterDefi
|
||||
'\u{1FB38}': sextant(0b111011), // BLOCK SEXTANT-12456
|
||||
'\u{1FB39}': sextant(0b111100), // BLOCK SEXTANT-3456 (lower two thirds block)
|
||||
'\u{1FB3A}': sextant(0b111101), // BLOCK SEXTANT-13456
|
||||
'\u{1FB3B}': sextant(0b111110), // BLOCK SEXTANT-23456
|
||||
'\u{1FB3B}': sextant(0b111110), // BLOCK SEXTANT-23456
|
||||
|
||||
// Smooth mosaic terminal graphic characters (1FB3C-1FB6F)
|
||||
'\u{1FB3C}': { type: CustomGlyphDefinitionType.PATH, data: 'M0,0.6667 L0,1 L0.5,1 Z' }, // LOWER LEFT BLOCK DIAGONAL LOWER MIDDLE LEFT TO LOWER CENTRE
|
||||
@@ -184,6 +184,53 @@ export const unifiedCharDefinitions: { [index: string]: CustomGlyphCharacterDefi
|
||||
'\u{1FB6E}': { type: CustomGlyphDefinitionType.PATH, data: 'M1,0 L1,1 L0.5,0.5 Z' }, // RIGHT TRIANGULAR ONE QUARTER BLOCK
|
||||
'\u{1FB6F}': { type: CustomGlyphDefinitionType.PATH, data: 'M0,1 L1,1 L0.5,0.5 Z' }, // LOWER TRIANGULAR ONE QUARTER BLOCK
|
||||
|
||||
// TODO: Block elements, window title bar, block elements
|
||||
|
||||
// Rectangular shade characters (1FB8C-1FB94)
|
||||
'\u{1FB8C}': { type: CustomGlyphDefinitionType.BLOCK_PATTERN_WITH_REGION, 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
|
||||
[1, 0],
|
||||
[0, 1]
|
||||
], [0.5, 0, 0.5, 1]] },
|
||||
'\u{1FB8E}': { type: CustomGlyphDefinitionType.BLOCK_PATTERN_WITH_REGION, 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
|
||||
[1, 0],
|
||||
[0, 1]
|
||||
], [0, 0.5, 1, 0.5]] },
|
||||
'\u{1FB90}': { type: CustomGlyphDefinitionType.BLOCK_PATTERN_WITH_REGION, data: [[ // INVERSE MEDIUM SHADE
|
||||
[0, 1],
|
||||
[1, 0]
|
||||
], [0, 0, 1, 1]] },
|
||||
// TODO: Make sure these are rendered correctly
|
||||
'\u{1FB91}': { type: CustomGlyphDefinitionType.BLOCK_PATTERN_WITH_REGION_AND_SOLID_OCTANT_BLOCK_VECTOR, data: { // UPPER HALF BLOCK AND LOWER HALF INVERSE MEDIUM SHADE
|
||||
pattern: [[
|
||||
[1, 0],
|
||||
[0, 1]
|
||||
], [0, 0, 1, 0.5]],
|
||||
vectors: [{ x: 0, y: 4, 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: [[
|
||||
[1, 0],
|
||||
[0, 1]
|
||||
], [0, 0.5, 1, 0.5]],
|
||||
vectors: [{ x: 0, y: 0, w: 8, h: 4 }]
|
||||
} },
|
||||
// 1FB93 is reserved
|
||||
'\u{1FB94}': { type: CustomGlyphDefinitionType.BLOCK_PATTERN_WITH_REGION_AND_SOLID_OCTANT_BLOCK_VECTOR, data: { // LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK
|
||||
pattern: [[
|
||||
[1, 0],
|
||||
[0, 1]
|
||||
], [0.5, 0, 0.5, 1]],
|
||||
vectors: [{ x: 0, y: 0, w: 4, h: 8 }]
|
||||
} },
|
||||
|
||||
// #endregion
|
||||
};
|
||||
|
||||
@@ -293,45 +340,6 @@ function sextant(pattern: number): { type: CustomGlyphDefinitionType.PATH_FUNCTI
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Rectangular shade characters - these use medium shade pattern (50%) like 0x2592.
|
||||
* Each entry is [pattern, region] where region is [x, y, width, height] in 0-1 normalized
|
||||
* coordinates. Pattern is the medium shade checkerboard pattern.
|
||||
*/
|
||||
const mediumShadePattern: CustomGlyphPatternDefinition = [
|
||||
[1, 0],
|
||||
[0, 1]
|
||||
];
|
||||
|
||||
const inverseMediumShadePattern: CustomGlyphPatternDefinition = [
|
||||
[0, 1],
|
||||
[1, 0]
|
||||
];
|
||||
|
||||
export const rectangularShadeDefinitions: { [index: string]: [CustomGlyphPatternDefinition, [number, number, number, number]] | undefined } = {
|
||||
'\u{1FB8C}': [mediumShadePattern, [0, 0, 0.5, 1]], // LEFT HALF MEDIUM SHADE
|
||||
'\u{1FB8D}': [mediumShadePattern, [0.5, 0, 0.5, 1]], // RIGHT HALF MEDIUM SHADE
|
||||
'\u{1FB8E}': [mediumShadePattern, [0, 0, 1, 0.5]], // UPPER HALF MEDIUM SHADE
|
||||
'\u{1FB8F}': [mediumShadePattern, [0, 0.5, 1, 0.5]], // LOWER HALF MEDIUM SHADE
|
||||
'\u{1FB90}': [inverseMediumShadePattern, [0, 0, 1, 1]] // INVERSE MEDIUM SHADE
|
||||
};
|
||||
|
||||
/** Region defined as [x, y, width, height] in 0-1 normalized coordinates. */
|
||||
type RegionDefinition = [number, number, number, number];
|
||||
|
||||
/** [solidRegion, shadeRegion] where shade region uses inverse medium shade pattern. */
|
||||
type BlockShadeComboDefinition = [RegionDefinition, RegionDefinition];
|
||||
|
||||
/**
|
||||
* Block + inverse shade combo characters.
|
||||
*/
|
||||
export const blockShadeComboDefinitions: { [index: string]: BlockShadeComboDefinition | undefined } = {
|
||||
'\u{1FB91}': [[0, 0, 1, 0.5], [0, 0.5, 1, 0.5]], // UPPER HALF BLOCK AND LOWER HALF INVERSE MEDIUM SHADE
|
||||
'\u{1FB92}': [[0, 0.5, 1, 0.5], [0, 0, 1, 0.5]], // UPPER HALF INVERSE MEDIUM SHADE AND LOWER HALF BLOCK
|
||||
// 1FB93 is reserved
|
||||
'\u{1FB94}': [[0.5, 0, 0.5, 1], [0, 0, 0.5, 1]] // LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK
|
||||
};
|
||||
|
||||
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, powerlineDefinitions, rectangularShadeDefinitions, unifiedCharDefinitions } from 'customGlyphs/CustomGlyphDefinitions';
|
||||
import { CustomGlyphDefinitionType, CustomGlyphVectorType, type CustomGlyphPathDrawFunctionDefinition, type CustomGlyphPatternDefinition, type ICustomGlyphSolidOctantBlockVector, type ICustomGlyphVectorShape } from 'customGlyphs/Types';
|
||||
import { blockElementDefinitions, boxDrawingDefinitions, powerlineDefinitions, unifiedCharDefinitions } from 'customGlyphs/CustomGlyphDefinitions';
|
||||
import { CustomGlyphDefinitionType, CustomGlyphVectorType, type CustomGlyphPathDrawFunctionDefinition, type CustomGlyphPatternDefinition, type CustomGlyphRegionDefinition, type ICustomGlyphSolidOctantBlockVector, type ICustomGlyphVectorShape } from 'customGlyphs/Types';
|
||||
|
||||
/**
|
||||
* Try drawing a custom block element or box drawing character, returning whether it was
|
||||
@@ -30,6 +30,13 @@ export function tryDrawCustomGlyph(
|
||||
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.PATH_FUNCTION:
|
||||
case CustomGlyphDefinitionType.PATH:
|
||||
drawPathDefinitionCharacter(ctx, unifiedCharDefinition.data, xOffset, yOffset, deviceCellWidth, deviceCellHeight);
|
||||
@@ -43,18 +50,6 @@ export function tryDrawCustomGlyph(
|
||||
return true;
|
||||
}
|
||||
|
||||
const rectangularShadeDefinition = rectangularShadeDefinitions[c];
|
||||
if (rectangularShadeDefinition) {
|
||||
drawRectangularShadeChar(ctx, rectangularShadeDefinition, xOffset, yOffset, deviceCellWidth, deviceCellHeight);
|
||||
return true;
|
||||
}
|
||||
|
||||
const blockShadeComboDefinition = blockShadeComboDefinitions[c];
|
||||
if (blockShadeComboDefinition) {
|
||||
drawBlockShadeComboChar(ctx, blockShadeComboDefinition, xOffset, yOffset, deviceCellWidth, deviceCellHeight);
|
||||
return true;
|
||||
}
|
||||
|
||||
const boxDrawingDefinition = boxDrawingDefinitions[c];
|
||||
if (boxDrawingDefinition) {
|
||||
drawBoxDrawingChar(ctx, boxDrawingDefinition, xOffset, yOffset, deviceCellWidth, deviceCellHeight, devicePixelRatio);
|
||||
@@ -190,9 +185,9 @@ function drawPatternChar(
|
||||
* 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 drawRectangularShadeChar(
|
||||
function drawBlockPatternWithRegion(
|
||||
ctx: CanvasRenderingContext2D,
|
||||
definition: [CustomGlyphPatternDefinition, [number, number, number, number]],
|
||||
definition: [pattern: CustomGlyphPatternDefinition, region: CustomGlyphRegionDefinition],
|
||||
xOffset: number,
|
||||
yOffset: number,
|
||||
deviceCellWidth: number,
|
||||
@@ -224,40 +219,40 @@ function drawRectangularShadeChar(
|
||||
* Draws block + inverse shade combo characters.
|
||||
* Fills the solid region completely, then draws inverse medium shade in the shade region.
|
||||
*/
|
||||
function drawBlockShadeComboChar(
|
||||
ctx: CanvasRenderingContext2D,
|
||||
regions: [[number, number, number, number], [number, number, number, number]],
|
||||
xOffset: number,
|
||||
yOffset: number,
|
||||
deviceCellWidth: number,
|
||||
deviceCellHeight: number
|
||||
): void {
|
||||
const [solidRegion, shadeRegion] = regions;
|
||||
// function drawBlockShadeComboChar(
|
||||
// ctx: CanvasRenderingContext2D,
|
||||
// regions: [[number, number, number, number], [number, number, number, number]],
|
||||
// xOffset: number,
|
||||
// yOffset: number,
|
||||
// deviceCellWidth: number,
|
||||
// deviceCellHeight: number
|
||||
// ): void {
|
||||
// const [solidRegion, shadeRegion] = regions;
|
||||
|
||||
// Draw solid block region
|
||||
const solidX = Math.round(xOffset + solidRegion[0] * deviceCellWidth);
|
||||
const solidY = Math.round(yOffset + solidRegion[1] * deviceCellHeight);
|
||||
const solidW = Math.round(solidRegion[2] * deviceCellWidth);
|
||||
const solidH = Math.round(solidRegion[3] * deviceCellHeight);
|
||||
ctx.fillRect(solidX, solidY, solidW, solidH);
|
||||
// // Draw solid block region
|
||||
// const solidX = Math.round(xOffset + solidRegion[0] * deviceCellWidth);
|
||||
// const solidY = Math.round(yOffset + solidRegion[1] * deviceCellHeight);
|
||||
// const solidW = Math.round(solidRegion[2] * deviceCellWidth);
|
||||
// const solidH = Math.round(solidRegion[3] * deviceCellHeight);
|
||||
// ctx.fillRect(solidX, solidY, solidW, solidH);
|
||||
|
||||
// Draw inverse medium shade region
|
||||
const shadeX = Math.round(xOffset + shadeRegion[0] * deviceCellWidth);
|
||||
const shadeY = Math.round(yOffset + shadeRegion[1] * deviceCellHeight);
|
||||
const shadeW = Math.round(shadeRegion[2] * deviceCellWidth);
|
||||
const shadeH = Math.round(shadeRegion[3] * deviceCellHeight);
|
||||
// // Draw inverse medium shade region
|
||||
// const shadeX = Math.round(xOffset + shadeRegion[0] * deviceCellWidth);
|
||||
// const shadeY = Math.round(yOffset + shadeRegion[1] * deviceCellHeight);
|
||||
// const shadeW = Math.round(shadeRegion[2] * deviceCellWidth);
|
||||
// const shadeH = Math.round(shadeRegion[3] * deviceCellHeight);
|
||||
|
||||
for (let py = 0; py < shadeH; py++) {
|
||||
const absY = shadeY + py - yOffset;
|
||||
for (let px = 0; px < shadeW; px++) {
|
||||
const absX = shadeX + px - xOffset;
|
||||
// Inverse checkerboard: fill at (x + y) % 2 === 1
|
||||
if (((absX + absY) % 2) === 1) {
|
||||
ctx.fillRect(shadeX + px, shadeY + py, 1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// for (let py = 0; py < shadeH; py++) {
|
||||
// const absY = shadeY + py - yOffset;
|
||||
// for (let px = 0; px < shadeW; px++) {
|
||||
// const absX = shadeX + px - xOffset;
|
||||
// // Inverse checkerboard: fill at (x + y) % 2 === 1
|
||||
// if (((absX + absY) % 2) === 1) {
|
||||
// ctx.fillRect(shadeX + px, shadeY + py, 1, 1);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* Draws the following box drawing characters by mapping a subset of SVG d attribute instructions to
|
||||
|
||||
@@ -33,13 +33,21 @@ export type CustomGlyphPatternDefinition = number[][];
|
||||
export const enum CustomGlyphDefinitionType {
|
||||
SOLID_OCTANT_BLOCK_VECTOR,
|
||||
BLOCK_PATTERN,
|
||||
BLOCK_PATTERN_WITH_REGION,
|
||||
BLOCK_PATTERN_WITH_REGION_AND_SOLID_OCTANT_BLOCK_VECTOR,
|
||||
PATH_FUNCTION,
|
||||
PATH,
|
||||
}
|
||||
|
||||
export type CustomGlyphRegionDefinition = [x: number, y: number, w: number, h: number];
|
||||
|
||||
export type CustomGlyphCharacterDefinition = (
|
||||
{ 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.PATH_FUNCTION, data: CustomGlyphPathDrawFunctionDefinition } |
|
||||
{ type: CustomGlyphDefinitionType.PATH, data: string }
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user