@xterm/xterm 5.4.0-beta.18 → 5.4.0-beta.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/xterm.js +1 -1
- package/lib/xterm.js.map +1 -1
- package/package.json +1 -1
- package/src/browser/renderer/dom/DomRendererRowFactory.ts +2 -2
- package/src/browser/renderer/shared/CellColorResolver.ts +94 -8
- package/src/browser/renderer/shared/RendererUtils.ts +1 -1
- package/src/browser/renderer/shared/TextureAtlas.ts +2 -2
- package/src/common/Color.ts +17 -0
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@ import { ICoreService, IDecorationService, IOptionsService } from 'common/servic
|
|
|
11
11
|
import { color, rgba } from 'common/Color';
|
|
12
12
|
import { ICharacterJoinerService, ICoreBrowserService, IThemeService } from 'browser/services/Services';
|
|
13
13
|
import { JoinedCellData } from 'browser/services/CharacterJoinerService';
|
|
14
|
-
import {
|
|
14
|
+
import { treatGlyphAsBackgroundColor } from 'browser/renderer/shared/RendererUtils';
|
|
15
15
|
import { AttributeData } from 'common/buffer/AttributeData';
|
|
16
16
|
import { WidthCache } from 'browser/renderer/dom/WidthCache';
|
|
17
17
|
import { IColorContrastCache } from 'browser/Types';
|
|
@@ -458,7 +458,7 @@ export class DomRendererRowFactory {
|
|
|
458
458
|
}
|
|
459
459
|
|
|
460
460
|
private _applyMinimumContrast(element: HTMLElement, bg: IColor, fg: IColor, cell: ICellData, bgOverride: IColor | undefined, fgOverride: IColor | undefined): boolean {
|
|
461
|
-
if (this._optionsService.rawOptions.minimumContrastRatio === 1 ||
|
|
461
|
+
if (this._optionsService.rawOptions.minimumContrastRatio === 1 || treatGlyphAsBackgroundColor(cell.getCode())) {
|
|
462
462
|
return false;
|
|
463
463
|
}
|
|
464
464
|
|
|
@@ -5,6 +5,8 @@ import { Attributes, BgFlags, ExtFlags, FgFlags, NULL_CELL_CODE, UnderlineStyle
|
|
|
5
5
|
import { IDecorationService, IOptionsService } from 'common/services/Services';
|
|
6
6
|
import { ICellData } from 'common/Types';
|
|
7
7
|
import { Terminal } from '@xterm/xterm';
|
|
8
|
+
import { rgba } from 'common/Color';
|
|
9
|
+
import { treatGlyphAsBackgroundColor } from 'browser/renderer/shared/RendererUtils';
|
|
8
10
|
|
|
9
11
|
// Work variables to avoid garbage collection
|
|
10
12
|
let $fg = 0;
|
|
@@ -65,11 +67,11 @@ export class CellColorResolver {
|
|
|
65
67
|
// Apply decorations on the bottom layer
|
|
66
68
|
this._decorationService.forEachDecorationAtCell(x, y, 'bottom', d => {
|
|
67
69
|
if (d.backgroundColorRGB) {
|
|
68
|
-
$bg = d.backgroundColorRGB.rgba >> 8 &
|
|
70
|
+
$bg = d.backgroundColorRGB.rgba >> 8 & Attributes.RGB_MASK;
|
|
69
71
|
$hasBg = true;
|
|
70
72
|
}
|
|
71
73
|
if (d.foregroundColorRGB) {
|
|
72
|
-
$fg = d.foregroundColorRGB.rgba >> 8 &
|
|
74
|
+
$fg = d.foregroundColorRGB.rgba >> 8 & Attributes.RGB_MASK;
|
|
73
75
|
$hasFg = true;
|
|
74
76
|
}
|
|
75
77
|
});
|
|
@@ -77,10 +79,94 @@ export class CellColorResolver {
|
|
|
77
79
|
// Apply the selection color if needed
|
|
78
80
|
$isSelected = this._selectionRenderModel.isCellSelected(this._terminal, x, y);
|
|
79
81
|
if ($isSelected) {
|
|
80
|
-
|
|
82
|
+
// If the cell has a bg color, retain the color by blending it with the selection color
|
|
83
|
+
if (
|
|
84
|
+
(this.result.fg & FgFlags.INVERSE) ||
|
|
85
|
+
(this.result.bg & Attributes.CM_MASK) !== Attributes.CM_DEFAULT
|
|
86
|
+
) {
|
|
87
|
+
// Resolve the standard bg color
|
|
88
|
+
if (this.result.fg & FgFlags.INVERSE) {
|
|
89
|
+
switch (this.result.fg & Attributes.CM_MASK) {
|
|
90
|
+
case Attributes.CM_P16:
|
|
91
|
+
case Attributes.CM_P256:
|
|
92
|
+
$bg = this._themeService.colors.ansi[this.result.fg & Attributes.PCOLOR_MASK].rgba;
|
|
93
|
+
break;
|
|
94
|
+
case Attributes.CM_RGB:
|
|
95
|
+
$bg = (this.result.fg & Attributes.RGB_MASK) << 8 | 0xFF;
|
|
96
|
+
break;
|
|
97
|
+
case Attributes.CM_DEFAULT:
|
|
98
|
+
default:
|
|
99
|
+
$bg = this._themeService.colors.foreground.rgba;
|
|
100
|
+
}
|
|
101
|
+
} else {
|
|
102
|
+
switch (this.result.bg & Attributes.CM_MASK) {
|
|
103
|
+
case Attributes.CM_P16:
|
|
104
|
+
case Attributes.CM_P256:
|
|
105
|
+
$bg = this._themeService.colors.ansi[this.result.bg & Attributes.PCOLOR_MASK].rgba;
|
|
106
|
+
break;
|
|
107
|
+
case Attributes.CM_RGB:
|
|
108
|
+
$bg = this.result.bg & Attributes.RGB_MASK << 8 | 0xFF;
|
|
109
|
+
break;
|
|
110
|
+
// No need to consider default bg color here as it's not possible
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// Blend with selection bg color
|
|
114
|
+
$bg = rgba.blend(
|
|
115
|
+
$bg,
|
|
116
|
+
((this._coreBrowserService.isFocused ? $colors.selectionBackgroundOpaque : $colors.selectionInactiveBackgroundOpaque).rgba & 0xFFFFFF00) | 0x80
|
|
117
|
+
) >> 8 & Attributes.RGB_MASK;
|
|
118
|
+
} else {
|
|
119
|
+
$bg = (this._coreBrowserService.isFocused ? $colors.selectionBackgroundOpaque : $colors.selectionInactiveBackgroundOpaque).rgba >> 8 & Attributes.RGB_MASK;
|
|
120
|
+
}
|
|
81
121
|
$hasBg = true;
|
|
122
|
+
|
|
123
|
+
// Apply explicit selection foreground if present
|
|
82
124
|
if ($colors.selectionForeground) {
|
|
83
|
-
$fg = $colors.selectionForeground.rgba >> 8 &
|
|
125
|
+
$fg = $colors.selectionForeground.rgba >> 8 & Attributes.RGB_MASK;
|
|
126
|
+
$hasFg = true;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Overwrite fg as bg if it's a special decorative glyph (eg. powerline)
|
|
130
|
+
if (treatGlyphAsBackgroundColor(cell.getCode())) {
|
|
131
|
+
// Inverse default background should be treated as transparent
|
|
132
|
+
if (
|
|
133
|
+
(this.result.fg & FgFlags.INVERSE) &&
|
|
134
|
+
(this.result.bg & Attributes.CM_MASK) === Attributes.CM_DEFAULT
|
|
135
|
+
) {
|
|
136
|
+
$fg = (this._coreBrowserService.isFocused ? $colors.selectionBackgroundOpaque : $colors.selectionInactiveBackgroundOpaque).rgba >> 8 & Attributes.RGB_MASK;
|
|
137
|
+
} else {
|
|
138
|
+
|
|
139
|
+
if (this.result.fg & FgFlags.INVERSE) {
|
|
140
|
+
switch (this.result.bg & Attributes.CM_MASK) {
|
|
141
|
+
case Attributes.CM_P16:
|
|
142
|
+
case Attributes.CM_P256:
|
|
143
|
+
$fg = this._themeService.colors.ansi[this.result.bg & Attributes.PCOLOR_MASK].rgba;
|
|
144
|
+
break;
|
|
145
|
+
case Attributes.CM_RGB:
|
|
146
|
+
$fg = this.result.bg & Attributes.RGB_MASK << 8 | 0xFF;
|
|
147
|
+
break;
|
|
148
|
+
// No need to consider default bg color here as it's not possible
|
|
149
|
+
}
|
|
150
|
+
} else {
|
|
151
|
+
switch (this.result.fg & Attributes.CM_MASK) {
|
|
152
|
+
case Attributes.CM_P16:
|
|
153
|
+
case Attributes.CM_P256:
|
|
154
|
+
$fg = this._themeService.colors.ansi[this.result.fg & Attributes.PCOLOR_MASK].rgba;
|
|
155
|
+
break;
|
|
156
|
+
case Attributes.CM_RGB:
|
|
157
|
+
$fg = (this.result.fg & Attributes.RGB_MASK) << 8 | 0xFF;
|
|
158
|
+
break;
|
|
159
|
+
case Attributes.CM_DEFAULT:
|
|
160
|
+
default:
|
|
161
|
+
$fg = this._themeService.colors.foreground.rgba;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
$fg = rgba.blend(
|
|
166
|
+
$fg,
|
|
167
|
+
((this._coreBrowserService.isFocused ? $colors.selectionBackgroundOpaque : $colors.selectionInactiveBackgroundOpaque).rgba & 0xFFFFFF00) | 0x80
|
|
168
|
+
) >> 8 & Attributes.RGB_MASK;
|
|
169
|
+
}
|
|
84
170
|
$hasFg = true;
|
|
85
171
|
}
|
|
86
172
|
}
|
|
@@ -88,11 +174,11 @@ export class CellColorResolver {
|
|
|
88
174
|
// Apply decorations on the top layer
|
|
89
175
|
this._decorationService.forEachDecorationAtCell(x, y, 'top', d => {
|
|
90
176
|
if (d.backgroundColorRGB) {
|
|
91
|
-
$bg = d.backgroundColorRGB.rgba >> 8 &
|
|
177
|
+
$bg = d.backgroundColorRGB.rgba >> 8 & Attributes.RGB_MASK;
|
|
92
178
|
$hasBg = true;
|
|
93
179
|
}
|
|
94
180
|
if (d.foregroundColorRGB) {
|
|
95
|
-
$fg = d.foregroundColorRGB.rgba >> 8 &
|
|
181
|
+
$fg = d.foregroundColorRGB.rgba >> 8 & Attributes.RGB_MASK;
|
|
96
182
|
$hasFg = true;
|
|
97
183
|
}
|
|
98
184
|
});
|
|
@@ -119,7 +205,7 @@ export class CellColorResolver {
|
|
|
119
205
|
if ($hasBg && !$hasFg) {
|
|
120
206
|
// Resolve bg color type (default color has a different meaning in fg vs bg)
|
|
121
207
|
if ((this.result.bg & Attributes.CM_MASK) === Attributes.CM_DEFAULT) {
|
|
122
|
-
$fg = (this.result.fg & ~(Attributes.RGB_MASK | FgFlags.INVERSE | Attributes.CM_MASK)) | (($colors.background.rgba >> 8 &
|
|
208
|
+
$fg = (this.result.fg & ~(Attributes.RGB_MASK | FgFlags.INVERSE | Attributes.CM_MASK)) | (($colors.background.rgba >> 8 & Attributes.RGB_MASK) & Attributes.RGB_MASK) | Attributes.CM_RGB;
|
|
123
209
|
} else {
|
|
124
210
|
$fg = (this.result.fg & ~(Attributes.RGB_MASK | FgFlags.INVERSE | Attributes.CM_MASK)) | this.result.bg & (Attributes.RGB_MASK | Attributes.CM_MASK);
|
|
125
211
|
}
|
|
@@ -128,7 +214,7 @@ export class CellColorResolver {
|
|
|
128
214
|
if (!$hasBg && $hasFg) {
|
|
129
215
|
// Resolve bg color type (default color has a different meaning in fg vs bg)
|
|
130
216
|
if ((this.result.fg & Attributes.CM_MASK) === Attributes.CM_DEFAULT) {
|
|
131
|
-
$bg = (this.result.bg & ~(Attributes.RGB_MASK | Attributes.CM_MASK)) | (($colors.foreground.rgba >> 8 &
|
|
217
|
+
$bg = (this.result.bg & ~(Attributes.RGB_MASK | Attributes.CM_MASK)) | (($colors.foreground.rgba >> 8 & Attributes.RGB_MASK) & Attributes.RGB_MASK) | Attributes.CM_RGB;
|
|
132
218
|
} else {
|
|
133
219
|
$bg = (this.result.bg & ~(Attributes.RGB_MASK | Attributes.CM_MASK)) | this.result.fg & (Attributes.RGB_MASK | Attributes.CM_MASK);
|
|
134
220
|
}
|
|
@@ -27,7 +27,7 @@ function isBoxOrBlockGlyph(codepoint: number): boolean {
|
|
|
27
27
|
return 0x2500 <= codepoint && codepoint <= 0x259F;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
export function
|
|
30
|
+
export function treatGlyphAsBackgroundColor(codepoint: number): boolean {
|
|
31
31
|
return isPowerlineGlyph(codepoint) || isBoxOrBlockGlyph(codepoint);
|
|
32
32
|
}
|
|
33
33
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import { IColorContrastCache } from 'browser/Types';
|
|
7
7
|
import { DIM_OPACITY, TEXT_BASELINE } from 'browser/renderer/shared/Constants';
|
|
8
8
|
import { tryDrawCustomChar } from 'browser/renderer/shared/CustomGlyphs';
|
|
9
|
-
import { computeNextVariantOffset,
|
|
9
|
+
import { computeNextVariantOffset, treatGlyphAsBackgroundColor, isPowerlineGlyph, isRestrictedPowerlineGlyph, throwIfFalsy } from 'browser/renderer/shared/RendererUtils';
|
|
10
10
|
import { IBoundingBox, ICharAtlasConfig, IRasterizedGlyph, ITextureAtlas } from 'browser/renderer/shared/Types';
|
|
11
11
|
import { NULL_COLOR, color, rgba } from 'common/Color';
|
|
12
12
|
import { EventEmitter } from 'common/EventEmitter';
|
|
@@ -490,7 +490,7 @@ export class TextureAtlas implements ITextureAtlas {
|
|
|
490
490
|
|
|
491
491
|
const powerlineGlyph = chars.length === 1 && isPowerlineGlyph(chars.charCodeAt(0));
|
|
492
492
|
const restrictedPowerlineGlyph = chars.length === 1 && isRestrictedPowerlineGlyph(chars.charCodeAt(0));
|
|
493
|
-
const foregroundColor = this._getForegroundColor(bg, bgColorMode, bgColor, fg, fgColorMode, fgColor, inverse, dim, bold,
|
|
493
|
+
const foregroundColor = this._getForegroundColor(bg, bgColorMode, bgColor, fg, fgColorMode, fgColor, inverse, dim, bold, treatGlyphAsBackgroundColor(chars.charCodeAt(0)));
|
|
494
494
|
this._tmpCtx.fillStyle = foregroundColor.css;
|
|
495
495
|
|
|
496
496
|
// For powerline glyphs left/top padding is excluded (https://github.com/microsoft/vscode/issues/120129)
|
package/src/common/Color.ts
CHANGED
|
@@ -245,6 +245,23 @@ export namespace rgb {
|
|
|
245
245
|
* Helper functions where the source type is "rgba" (number: 0xrrggbbaa).
|
|
246
246
|
*/
|
|
247
247
|
export namespace rgba {
|
|
248
|
+
export function blend(bg: number, fg: number): number {
|
|
249
|
+
$a = (fg & 0xFF) / 0xFF;
|
|
250
|
+
if ($a === 1) {
|
|
251
|
+
return fg;
|
|
252
|
+
}
|
|
253
|
+
const fgR = (fg >> 24) & 0xFF;
|
|
254
|
+
const fgG = (fg >> 16) & 0xFF;
|
|
255
|
+
const fgB = (fg >> 8) & 0xFF;
|
|
256
|
+
const bgR = (bg >> 24) & 0xFF;
|
|
257
|
+
const bgG = (bg >> 16) & 0xFF;
|
|
258
|
+
const bgB = (bg >> 8) & 0xFF;
|
|
259
|
+
$r = bgR + Math.round((fgR - bgR) * $a);
|
|
260
|
+
$g = bgG + Math.round((fgG - bgG) * $a);
|
|
261
|
+
$b = bgB + Math.round((fgB - bgB) * $a);
|
|
262
|
+
return channels.toRgba($r, $g, $b);
|
|
263
|
+
}
|
|
264
|
+
|
|
248
265
|
/**
|
|
249
266
|
* Given a foreground color and a background color, either increase or reduce the luminance of the
|
|
250
267
|
* foreground color until the specified contrast ratio is met. If pure white or black is hit
|