mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
Make medium shade consistent, make all shades less heavy
This commit is contained in:
@@ -291,21 +291,32 @@ export const symbolsForLegacyComputingDefinitions: { [index: string]: CustomGlyp
|
||||
'\u{1FB6F}': () => 'M0,1 L1,1 L0.5,0.5 Z' // LOWER TRIANGULAR ONE QUARTER BLOCK
|
||||
};
|
||||
|
||||
/**
|
||||
* 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];
|
||||
|
||||
/**
|
||||
* Rectangular shade characters - these use medium shade pattern with region bounds.
|
||||
* Pattern is a checkerboard that shifts 1px each row (same as medium shade).
|
||||
*/
|
||||
export const rectangularShadeDefinitions: { [index: string]: RegionDefinition | undefined } = {
|
||||
'\u{1FB8C}': [0, 0, 0.5, 1], // LEFT HALF MEDIUM SHADE
|
||||
'\u{1FB8D}': [0.5, 0, 0.5, 1], // RIGHT HALF MEDIUM SHADE
|
||||
'\u{1FB8E}': [0, 0, 1, 0.5], // UPPER HALF MEDIUM SHADE
|
||||
'\u{1FB8F}': [0, 0.5, 1, 0.5], // LOWER HALF MEDIUM SHADE
|
||||
'\u{1FB90}': [0, 0, 1, 1] // INVERSE MEDIUM SHADE
|
||||
};
|
||||
|
||||
/** [solidRegion, shadeRegion] where shade region uses inverse medium shade pattern. */
|
||||
type BlockShadeComboDefinition = [RegionDefinition, RegionDefinition];
|
||||
|
||||
@@ -326,22 +337,16 @@ export const blockShadeComboDefinitions: { [index: string]: BlockShadeComboDefin
|
||||
export const patternCharacterDefinitions: { [key: string]: CustomGlyphPatternDefinition | undefined } = {
|
||||
// Shade characters (0x2591-0x2593)
|
||||
'░': [ // LIGHT SHADE (25%)
|
||||
[1, 0, 0, 0],
|
||||
[0, 0, 0, 0],
|
||||
[0, 0, 1, 0],
|
||||
[0, 0, 0, 0]
|
||||
[1, 0],
|
||||
[0, 0]
|
||||
],
|
||||
'▒': [ // MEDIUM SHADE (50%)
|
||||
[1, 0],
|
||||
[0, 0],
|
||||
[0, 1],
|
||||
[0, 0]
|
||||
[0, 1]
|
||||
],
|
||||
'▓': [ // DARK SHADE (75%)
|
||||
[0, 1],
|
||||
[1, 1],
|
||||
[1, 0],
|
||||
[1, 1]
|
||||
[1, 0]
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ export function tryDrawCustomGlyph(
|
||||
|
||||
const rectangularShadeDefinition = rectangularShadeDefinitions[c];
|
||||
if (rectangularShadeDefinition) {
|
||||
drawRectangularShadeChar(ctx, rectangularShadeDefinition, xOffset, yOffset, deviceCellWidth, deviceCellHeight, c === '\u{1FB90}');
|
||||
drawRectangularShadeChar(ctx, rectangularShadeDefinition, xOffset, yOffset, deviceCellWidth, deviceCellHeight);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -214,34 +214,32 @@ function drawPatternChar(
|
||||
*/
|
||||
function drawRectangularShadeChar(
|
||||
ctx: CanvasRenderingContext2D,
|
||||
region: [number, number, number, number],
|
||||
definition: [CustomGlyphPatternDefinition, [number, number, number, number]],
|
||||
xOffset: number,
|
||||
yOffset: number,
|
||||
deviceCellWidth: number,
|
||||
deviceCellHeight: number,
|
||||
isInverse: boolean
|
||||
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);
|
||||
|
||||
// For inverse medium shade, we use the opposite pattern (fill where medium shade doesn't)
|
||||
// Medium shade pattern: fills at (x+y) % 2 === 0, so inverse fills at (x+y) % 2 === 1
|
||||
const patternOffset = isInverse ? 1 : 0;
|
||||
// Save context state
|
||||
ctx.save();
|
||||
|
||||
for (let py = 0; py < regionH; py++) {
|
||||
// Calculate the absolute y position for pattern calculation
|
||||
const absY = regionY + py - yOffset;
|
||||
for (let px = 0; px < regionW; px++) {
|
||||
const absX = regionX + px - xOffset;
|
||||
// Checkerboard pattern: fill if (x + y) % 2 matches the offset
|
||||
if (((absX + absY) % 2) === patternOffset) {
|
||||
ctx.fillRect(regionX + px, regionY + py, 1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user