Support min contrast ratio in decoration fg/bg

This commit is contained in:
Daniel Imms
2022-05-09 15:39:02 -07:00
parent 10598462d0
commit 13abd2aa96
@@ -175,6 +175,8 @@ export class DomRendererRowFactory {
// Apply any decoration foreground/background overrides // Apply any decoration foreground/background overrides
const decorations = this._decorationService.getDecorationsOnLine(row); const decorations = this._decorationService.getDecorationsOnLine(row);
let bgOverride: IColor | undefined;
let fgOverride: IColor | undefined;
for (const d of decorations) { for (const d of decorations) {
const xmin = d.options.x ?? 0; const xmin = d.options.x ?? 0;
const xmax = xmin + (d.options.width ?? 1); const xmax = xmin + (d.options.width ?? 1);
@@ -182,10 +184,12 @@ export class DomRendererRowFactory {
if (d.backgroundColorRGB) { if (d.backgroundColorRGB) {
bgColorMode = Attributes.CM_RGB; bgColorMode = Attributes.CM_RGB;
bg = d.backgroundColorRGB.rgba >> 8; bg = d.backgroundColorRGB.rgba >> 8;
bgOverride = d.backgroundColorRGB;
} }
if (d.foregroundColorRGB) { if (d.foregroundColorRGB) {
fgColorMode = Attributes.CM_RGB; fgColorMode = Attributes.CM_RGB;
fg = d.foregroundColorRGB.rgba >> 8; fg = d.foregroundColorRGB.rgba >> 8;
fgOverride = d.foregroundColorRGB;
} }
} }
} }
@@ -198,7 +202,7 @@ export class DomRendererRowFactory {
fg += 8; fg += 8;
} }
// TODO: Pass in bg override // TODO: Pass in bg override
if (!this._applyMinimumContrast(charElement, this._colors.background, this._colors.ansi[fg], cell)) { if (!this._applyMinimumContrast(charElement, this._colors.background, this._colors.ansi[fg], cell, undefined, undefined)) {
charElement.classList.add(`xterm-fg-${fg}`); charElement.classList.add(`xterm-fg-${fg}`);
} }
break; break;
@@ -208,13 +212,13 @@ export class DomRendererRowFactory {
(fg >> 8) & 0xFF, (fg >> 8) & 0xFF,
(fg ) & 0xFF (fg ) & 0xFF
); );
if (!this._applyMinimumContrast(charElement, this._colors.background, color, cell)) { if (!this._applyMinimumContrast(charElement, this._colors.background, color, cell, bgOverride, fgOverride)) {
this._addStyle(charElement, `color:#${padStart(fg.toString(16), '0', 6)}`); this._addStyle(charElement, `color:#${padStart(fg.toString(16), '0', 6)}`);
} }
break; break;
case Attributes.CM_DEFAULT: case Attributes.CM_DEFAULT:
default: default:
if (!this._applyMinimumContrast(charElement, this._colors.background, this._colors.foreground, cell)) { if (!this._applyMinimumContrast(charElement, this._colors.background, this._colors.foreground, cell, undefined, undefined)) {
if (isInverse) { if (isInverse) {
charElement.classList.add(`xterm-fg-${INVERTED_DEFAULT_COLOR}`); charElement.classList.add(`xterm-fg-${INVERTED_DEFAULT_COLOR}`);
} }
@@ -228,7 +232,7 @@ export class DomRendererRowFactory {
charElement.classList.add(`xterm-bg-${bg}`); charElement.classList.add(`xterm-bg-${bg}`);
break; break;
case Attributes.CM_RGB: case Attributes.CM_RGB:
this._addStyle(charElement, `background-color:#${padStart(bg.toString(16), '0', 6)}`); this._addStyle(charElement, `background-color:#${padStart((bg >>> 0).toString(16), '0', 6)}`);
break; break;
case Attributes.CM_DEFAULT: case Attributes.CM_DEFAULT:
default: default:
@@ -244,18 +248,23 @@ export class DomRendererRowFactory {
return fragment; return fragment;
} }
private _applyMinimumContrast(element: HTMLElement, bg: IColor, fg: IColor, cell: ICellData): boolean { private _applyMinimumContrast(element: HTMLElement, bg: IColor, fg: IColor, cell: ICellData, bgOverride: IColor | undefined, fgOverride: IColor | undefined): boolean {
if (this._optionsService.rawOptions.minimumContrastRatio === 1 || isPowerlineGlyph(cell.getCode())) { if (this._optionsService.rawOptions.minimumContrastRatio === 1 || isPowerlineGlyph(cell.getCode())) {
return false; return false;
} }
// Try get from cache first // Try get from cache first, only use the cache when there are no decoration overrides
let adjustedColor = this._colors.contrastCache.getColor(this._workCell.bg, this._workCell.fg); let adjustedColor: IColor | undefined | null = undefined;
if (!bgOverride || !fgOverride) {
adjustedColor = this._colors.contrastCache.getColor(this._workCell.bg, this._workCell.fg);
}
// Calculate and store in cache // Calculate and store in cache
if (adjustedColor === undefined) { if (adjustedColor === undefined) {
adjustedColor = color.ensureContrastRatio(bg, fg, this._optionsService.rawOptions.minimumContrastRatio); adjustedColor = color.ensureContrastRatio(bgOverride || bg, fgOverride || fg, this._optionsService.rawOptions.minimumContrastRatio);
this._colors.contrastCache.setColor(this._workCell.bg, this._workCell.fg, adjustedColor ?? null); if (!bgOverride || !fgOverride) {
this._colors.contrastCache.setColor(this._workCell.bg, this._workCell.fg, adjustedColor ?? null);
}
} }
if (adjustedColor) { if (adjustedColor) {