Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move rgba.toColor to channels.toColor #4927

Merged
merged 3 commits into from
Dec 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions src/browser/Terminal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ import { RenderService } from 'browser/services/RenderService';
import { SelectionService } from 'browser/services/SelectionService';
import { ICharSizeService, ICharacterJoinerService, ICoreBrowserService, ILinkProviderService, IMouseService, IRenderService, ISelectionService, IThemeService } from 'browser/services/Services';
import { ThemeService } from 'browser/services/ThemeService';
import { color, rgba } from 'common/Color';
import { channels, color } from 'common/Color';
import { CoreTerminal } from 'common/CoreTerminal';
import { EventEmitter, IEvent, forwardEvent } from 'common/EventEmitter';
import { MutableDisposable, toDisposable } from 'common/Lifecycle';
Expand Down Expand Up @@ -211,17 +211,17 @@ export class Terminal extends CoreTerminal implements ITerminal {
}
switch (req.type) {
case ColorRequestType.REPORT:
const channels = color.toColorRGB(acc === 'ansi'
const colorRgb = color.toColorRGB(acc === 'ansi'
? this._themeService.colors.ansi[req.index]
: this._themeService.colors[acc]);
this.coreService.triggerDataEvent(`${C0.ESC}]${ident};${toRgbString(channels)}${C1_ESCAPED.ST}`);
this.coreService.triggerDataEvent(`${C0.ESC}]${ident};${toRgbString(colorRgb)}${C1_ESCAPED.ST}`);
break;
case ColorRequestType.SET:
if (acc === 'ansi') {
this._themeService.modifyColors(colors => colors.ansi[req.index] = rgba.toColor(...req.color));
this._themeService.modifyColors(colors => colors.ansi[req.index] = channels.toColor(...req.color));
} else {
const narrowedAcc = acc;
this._themeService.modifyColors(colors => colors[narrowedAcc] = rgba.toColor(...req.color));
this._themeService.modifyColors(colors => colors[narrowedAcc] = channels.toColor(...req.color));
}
break;
case ColorRequestType.RESTORE:
Expand Down
6 changes: 3 additions & 3 deletions src/browser/renderer/dom/DomRendererRowFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { INVERTED_DEFAULT_COLOR } from 'browser/renderer/shared/Constants';
import { WHITESPACE_CELL_CHAR, Attributes } from 'common/buffer/Constants';
import { CellData } from 'common/buffer/CellData';
import { ICoreService, IDecorationService, IOptionsService } from 'common/services/Services';
import { color, rgba } from 'common/Color';
import { channels, color } from 'common/Color';
import { ICharacterJoinerService, ICoreBrowserService, IThemeService } from 'browser/services/Services';
import { JoinedCellData } from 'browser/services/CharacterJoinerService';
import { treatGlyphAsBackgroundColor } from 'browser/renderer/shared/RendererUtils';
Expand Down Expand Up @@ -376,7 +376,7 @@ export class DomRendererRowFactory {
classes.push(`xterm-bg-${bg}`);
break;
case Attributes.CM_RGB:
resolvedBg = rgba.toColor(bg >> 16, bg >> 8 & 0xFF, bg & 0xFF);
resolvedBg = channels.toColor(bg >> 16, bg >> 8 & 0xFF, bg & 0xFF);
this._addStyle(charElement, `background-color:#${padStart((bg >>> 0).toString(16), '0', 6)}`);
break;
case Attributes.CM_DEFAULT:
Expand Down Expand Up @@ -408,7 +408,7 @@ export class DomRendererRowFactory {
}
break;
case Attributes.CM_RGB:
const color = rgba.toColor(
const color = channels.toColor(
(fg >> 16) & 0xFF,
(fg >> 8) & 0xFF,
(fg ) & 0xFF
Expand Down
9 changes: 4 additions & 5 deletions src/browser/renderer/shared/TextureAtlas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { DIM_OPACITY, TEXT_BASELINE } from 'browser/renderer/shared/Constants';
import { tryDrawCustomChar } from 'browser/renderer/shared/CustomGlyphs';
import { computeNextVariantOffset, treatGlyphAsBackgroundColor, isPowerlineGlyph, isRestrictedPowerlineGlyph, throwIfFalsy } from 'browser/renderer/shared/RendererUtils';
import { IBoundingBox, ICharAtlasConfig, IRasterizedGlyph, ITextureAtlas } from 'browser/renderer/shared/Types';
import { NULL_COLOR, color, rgba } from 'common/Color';
import { NULL_COLOR, channels, color, rgba } from 'common/Color';
import { EventEmitter } from 'common/EventEmitter';
import { FourKeyMap } from 'common/MultiKeyMap';
import { IdleTaskQueue } from 'common/TaskQueue';
Expand Down Expand Up @@ -291,8 +291,7 @@ export class TextureAtlas implements ITextureAtlas {
break;
case Attributes.CM_RGB:
const arr = AttributeData.toColorRGB(bgColor);
// TODO: This object creation is slow
result = rgba.toColor(arr[0], arr[1], arr[2]);
result = channels.toColor(arr[0], arr[1], arr[2]);
break;
case Attributes.CM_DEFAULT:
default:
Expand Down Expand Up @@ -324,7 +323,7 @@ export class TextureAtlas implements ITextureAtlas {
break;
case Attributes.CM_RGB:
const arr = AttributeData.toColorRGB(fgColor);
result = rgba.toColor(arr[0], arr[1], arr[2]);
result = channels.toColor(arr[0], arr[1], arr[2]);
break;
case Attributes.CM_DEFAULT:
default:
Expand Down Expand Up @@ -406,7 +405,7 @@ export class TextureAtlas implements ITextureAtlas {
return undefined;
}

const color = rgba.toColor(
const color = channels.toColor(
(result >> 24) & 0xFF,
(result >> 16) & 0xFF,
(result >> 8) & 0xFF
Expand Down
60 changes: 60 additions & 0 deletions src/common/Color.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,25 @@ describe('Color', () => {
assert.equal(channels.toCss(0xf0, 0xf0, 0xf0), '#f0f0f0');
assert.equal(channels.toCss(0xff, 0xff, 0xff), '#ffffff');
});
it('should convert an rgba array to css hex string', () => {
assert.equal(channels.toCss(0x00, 0x00, 0x00, 0x00), '#00000000');
assert.equal(channels.toCss(0x10, 0x10, 0x10, 0x10), '#10101010');
assert.equal(channels.toCss(0x20, 0x20, 0x20, 0x20), '#20202020');
assert.equal(channels.toCss(0x30, 0x30, 0x30, 0x30), '#30303030');
assert.equal(channels.toCss(0x40, 0x40, 0x40, 0x40), '#40404040');
assert.equal(channels.toCss(0x50, 0x50, 0x50, 0x50), '#50505050');
assert.equal(channels.toCss(0x60, 0x60, 0x60, 0x60), '#60606060');
assert.equal(channels.toCss(0x70, 0x70, 0x70, 0x70), '#70707070');
assert.equal(channels.toCss(0x80, 0x80, 0x80, 0x80), '#80808080');
assert.equal(channels.toCss(0x90, 0x90, 0x90, 0x90), '#90909090');
assert.equal(channels.toCss(0xa0, 0xa0, 0xa0, 0xa0), '#a0a0a0a0');
assert.equal(channels.toCss(0xb0, 0xb0, 0xb0, 0xb0), '#b0b0b0b0');
assert.equal(channels.toCss(0xc0, 0xc0, 0xc0, 0xc0), '#c0c0c0c0');
assert.equal(channels.toCss(0xd0, 0xd0, 0xd0, 0xd0), '#d0d0d0d0');
assert.equal(channels.toCss(0xe0, 0xe0, 0xe0, 0xe0), '#e0e0e0e0');
assert.equal(channels.toCss(0xf0, 0xf0, 0xf0, 0xf0), '#f0f0f0f0');
assert.equal(channels.toCss(0xff, 0xff, 0xff, 0xff), '#ffffffff');
});
});

describe('toRgba', () => {
Expand Down Expand Up @@ -71,6 +90,47 @@ describe('Color', () => {
assert.equal(channels.toRgba(0xff, 0xff, 0xff, 0xff), 0xffffffff);
});
});

describe('toColor', () => {
it('should convert an rgb array to an IColor', () => {
assert.deepStrictEqual(channels.toColor(0x00, 0x00, 0x00), { css: '#000000', rgba: 0x000000FF });
assert.deepStrictEqual(channels.toColor(0x10, 0x10, 0x10), { css: '#101010', rgba: 0x101010FF });
assert.deepStrictEqual(channels.toColor(0x20, 0x20, 0x20), { css: '#202020', rgba: 0x202020FF });
assert.deepStrictEqual(channels.toColor(0x30, 0x30, 0x30), { css: '#303030', rgba: 0x303030FF });
assert.deepStrictEqual(channels.toColor(0x40, 0x40, 0x40), { css: '#404040', rgba: 0x404040FF });
assert.deepStrictEqual(channels.toColor(0x50, 0x50, 0x50), { css: '#505050', rgba: 0x505050FF });
assert.deepStrictEqual(channels.toColor(0x60, 0x60, 0x60), { css: '#606060', rgba: 0x606060FF });
assert.deepStrictEqual(channels.toColor(0x70, 0x70, 0x70), { css: '#707070', rgba: 0x707070FF });
assert.deepStrictEqual(channels.toColor(0x80, 0x80, 0x80), { css: '#808080', rgba: 0x808080FF });
assert.deepStrictEqual(channels.toColor(0x90, 0x90, 0x90), { css: '#909090', rgba: 0x909090FF });
assert.deepStrictEqual(channels.toColor(0xa0, 0xa0, 0xa0), { css: '#a0a0a0', rgba: 0xa0a0a0FF });
assert.deepStrictEqual(channels.toColor(0xb0, 0xb0, 0xb0), { css: '#b0b0b0', rgba: 0xb0b0b0FF });
assert.deepStrictEqual(channels.toColor(0xc0, 0xc0, 0xc0), { css: '#c0c0c0', rgba: 0xc0c0c0FF });
assert.deepStrictEqual(channels.toColor(0xd0, 0xd0, 0xd0), { css: '#d0d0d0', rgba: 0xd0d0d0FF });
assert.deepStrictEqual(channels.toColor(0xe0, 0xe0, 0xe0), { css: '#e0e0e0', rgba: 0xe0e0e0FF });
assert.deepStrictEqual(channels.toColor(0xf0, 0xf0, 0xf0), { css: '#f0f0f0', rgba: 0xf0f0f0FF });
assert.deepStrictEqual(channels.toColor(0xff, 0xff, 0xff), { css: '#ffffff', rgba: 0xffffffFF });
});
it('should convert an rgba array to an IColor', () => {
assert.deepStrictEqual(channels.toColor(0x00, 0x00, 0x00, 0x00), { css: '#00000000', rgba: 0x00000000 });
assert.deepStrictEqual(channels.toColor(0x10, 0x10, 0x10, 0x10), { css: '#10101010', rgba: 0x10101010 });
assert.deepStrictEqual(channels.toColor(0x20, 0x20, 0x20, 0x20), { css: '#20202020', rgba: 0x20202020 });
assert.deepStrictEqual(channels.toColor(0x30, 0x30, 0x30, 0x30), { css: '#30303030', rgba: 0x30303030 });
assert.deepStrictEqual(channels.toColor(0x40, 0x40, 0x40, 0x40), { css: '#40404040', rgba: 0x40404040 });
assert.deepStrictEqual(channels.toColor(0x50, 0x50, 0x50, 0x50), { css: '#50505050', rgba: 0x50505050 });
assert.deepStrictEqual(channels.toColor(0x60, 0x60, 0x60, 0x60), { css: '#60606060', rgba: 0x60606060 });
assert.deepStrictEqual(channels.toColor(0x70, 0x70, 0x70, 0x70), { css: '#70707070', rgba: 0x70707070 });
assert.deepStrictEqual(channels.toColor(0x80, 0x80, 0x80, 0x80), { css: '#80808080', rgba: 0x80808080 });
assert.deepStrictEqual(channels.toColor(0x90, 0x90, 0x90, 0x90), { css: '#90909090', rgba: 0x90909090 });
assert.deepStrictEqual(channels.toColor(0xa0, 0xa0, 0xa0, 0xa0), { css: '#a0a0a0a0', rgba: 0xa0a0a0a0 });
assert.deepStrictEqual(channels.toColor(0xb0, 0xb0, 0xb0, 0xb0), { css: '#b0b0b0b0', rgba: 0xb0b0b0b0 });
assert.deepStrictEqual(channels.toColor(0xc0, 0xc0, 0xc0, 0xc0), { css: '#c0c0c0c0', rgba: 0xc0c0c0c0 });
assert.deepStrictEqual(channels.toColor(0xd0, 0xd0, 0xd0, 0xd0), { css: '#d0d0d0d0', rgba: 0xd0d0d0d0 });
assert.deepStrictEqual(channels.toColor(0xe0, 0xe0, 0xe0, 0xe0), { css: '#e0e0e0e0', rgba: 0xe0e0e0e0 });
assert.deepStrictEqual(channels.toColor(0xf0, 0xf0, 0xf0, 0xf0), { css: '#f0f0f0f0', rgba: 0xf0f0f0f0 });
assert.deepStrictEqual(channels.toColor(0xff, 0xff, 0xff, 0xff), { css: '#ffffffff', rgba: 0xffffffff });
});
});
});

describe('color', () => {
Expand Down
23 changes: 11 additions & 12 deletions src/common/Color.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ export namespace channels {
// >>> 0 forces an unsigned int
return (r << 24 | g << 16 | b << 8 | a) >>> 0;
}

export function toColor(r: number, g: number, b: number, a?: number): IColor {
return {
css: channels.toCss(r, g, b, a),
rgba: channels.toRgba(r, g, b, a)
};
}
}

/**
Expand Down Expand Up @@ -70,7 +77,7 @@ export namespace color {
if (!result) {
return undefined;
}
return rgba.toColor(
return channels.toColor(
(result >> 24 & 0xFF),
(result >> 16 & 0xFF),
(result >> 8 & 0xFF)
Expand Down Expand Up @@ -142,14 +149,14 @@ export namespace css {
$r = parseInt(css.slice(1, 2).repeat(2), 16);
$g = parseInt(css.slice(2, 3).repeat(2), 16);
$b = parseInt(css.slice(3, 4).repeat(2), 16);
return rgba.toColor($r, $g, $b);
return channels.toColor($r, $g, $b);
}
case 5: { // #rgba
$r = parseInt(css.slice(1, 2).repeat(2), 16);
$g = parseInt(css.slice(2, 3).repeat(2), 16);
$b = parseInt(css.slice(3, 4).repeat(2), 16);
$a = parseInt(css.slice(4, 5).repeat(2), 16);
return rgba.toColor($r, $g, $b, $a);
return channels.toColor($r, $g, $b, $a);
}
case 7: // #rrggbb
return {
Expand All @@ -171,7 +178,7 @@ export namespace css {
$g = parseInt(rgbaMatch[2]);
$b = parseInt(rgbaMatch[3]);
$a = Math.round((rgbaMatch[5] === undefined ? 1 : parseFloat(rgbaMatch[5])) * 0xFF);
return rgba.toColor($r, $g, $b, $a);
return channels.toColor($r, $g, $b, $a);
}

// Validate the context is available for canvas-based color parsing
Expand Down Expand Up @@ -342,17 +349,9 @@ export namespace rgba {
return (fgR << 24 | fgG << 16 | fgB << 8 | 0xFF) >>> 0;
}

// FIXME: Move this to channels NS?
export function toChannels(value: number): [number, number, number, number] {
return [(value >> 24) & 0xFF, (value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF];
}

export function toColor(r: number, g: number, b: number, a?: number): IColor {
return {
css: channels.toCss(r, g, b, a),
rgba: channels.toRgba(r, g, b, a)
};
}
}

export function toPaddedHex(c: number): string {
Expand Down
4 changes: 2 additions & 2 deletions src/common/Types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ export interface ICharset {
export type CharData = [number, string, number, number];

export interface IColor {
css: string;
rgba: number; // 32-bit int with rgba in each byte
readonly css: string;
readonly rgba: number; // 32-bit int with rgba in each byte
}
export type IColorRGB = [number, number, number];

Expand Down