Skip to content

Commit

Permalink
Merge pull request #1317 from bgw/rm-char-atlas-request
Browse files Browse the repository at this point in the history
Merge ICharAtlasRequest with ICharAtlasConfig
  • Loading branch information
Tyriar authored Mar 9, 2018
2 parents a41e183 + cfe936a commit ed7741e
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 72 deletions.
11 changes: 3 additions & 8 deletions src/renderer/Types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import { ITerminal } from '../Types';
import { IEventEmitter, ITheme } from 'xterm';
import { IColorSet } from '../shared/Types';

/**
* Flags used to render terminal text properly.
Expand Down Expand Up @@ -39,14 +40,8 @@ export interface IColorManager {
colors: IColorSet;
}

export interface IColorSet {
foreground: string;
background: string;
cursor: string;
cursorAccent: string;
selection: string;
ansi: string[];
}
// TODO: We should probably rewrite the imports for IColorSet, but there's a lot of them
export { IColorSet };

export interface IRenderDimensions {
scaledCharWidth: number;
Expand Down
20 changes: 3 additions & 17 deletions src/renderer/atlas/CharAtlas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@

import { ITerminal } from '../../Types';
import { IColorSet } from '../Types';
import { ICharAtlasConfig } from './Types';
import { ICharAtlasConfig } from '../../shared/atlas/Types';
import { isFirefox } from '../../shared/utils/Browser';
import { generateCharAtlas, ICharAtlasRequest } from '../../shared/atlas/CharAtlasGenerator';
import { generateCharAtlas } from '../../shared/atlas/CharAtlasGenerator';
import { generateConfig, configEquals } from './CharAtlasUtils';

interface ICharAtlasCacheEntry {
Expand Down Expand Up @@ -63,22 +63,8 @@ export function acquireCharAtlas(terminal: ITerminal, colors: IColorSet, scaledC
return canvas;
};

const charAtlasConfig: ICharAtlasRequest = {
scaledCharWidth,
scaledCharHeight,
fontSize: terminal.options.fontSize,
fontFamily: terminal.options.fontFamily,
fontWeight: terminal.options.fontWeight,
fontWeightBold: terminal.options.fontWeightBold,
background: colors.background,
foreground: colors.foreground,
ansiColors: colors.ansi,
devicePixelRatio: window.devicePixelRatio,
allowTransparency: terminal.options.allowTransparency
};

const newEntry: ICharAtlasCacheEntry = {
bitmap: generateCharAtlas(window, canvasFactory, charAtlasConfig),
bitmap: generateCharAtlas(window, canvasFactory, newConfig),
config: newConfig,
ownedBy: [terminal]
};
Expand Down
6 changes: 4 additions & 2 deletions src/renderer/atlas/CharAtlasUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import { ITerminal } from '../../Types';
import { ITheme } from 'xterm';
import { IColorSet } from '../Types';
import { ICharAtlasConfig } from './Types';
import { ICharAtlasConfig } from '../../shared/atlas/Types';

export function generateConfig(scaledCharWidth: number, scaledCharHeight: number, terminal: ITerminal, colors: IColorSet): ICharAtlasConfig {
const clonedColors = {
Expand All @@ -18,6 +18,7 @@ export function generateConfig(scaledCharWidth: number, scaledCharHeight: number
ansi: colors.ansi.slice(0, 16)
};
return {
devicePixelRatio: window.devicePixelRatio,
scaledCharWidth,
scaledCharHeight,
fontFamily: terminal.options.fontFamily,
Expand All @@ -35,7 +36,8 @@ export function configEquals(a: ICharAtlasConfig, b: ICharAtlasConfig): boolean
return false;
}
}
return a.fontFamily === b.fontFamily &&
return a.devicePixelRatio === b.devicePixelRatio &&
a.fontFamily === b.fontFamily &&
a.fontSize === b.fontSize &&
a.fontWeight === b.fontWeight &&
a.fontWeightBold === b.fontWeightBold &&
Expand Down
14 changes: 0 additions & 14 deletions src/renderer/atlas/Types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,5 @@
* @license MIT
*/

import { FontWeight } from 'xterm';
import { IColorSet } from '../Types';

export const INVERTED_DEFAULT_COLOR = -1;
export const DIM_OPACITY = 0.5;

export interface ICharAtlasConfig {
fontSize: number;
fontFamily: string;
fontWeight: FontWeight;
fontWeightBold: FontWeight;
scaledCharWidth: number;
scaledCharHeight: number;
allowTransparency: boolean;
colors: IColorSet;
}
13 changes: 13 additions & 0 deletions src/shared/Types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* Copyright (c) 2017 The xterm.js authors. All rights reserved.
* @license MIT
*/

export interface IColorSet {
foreground: string;
background: string;
cursor: string;
cursorAccent: string;
selection: string;
ansi: string[];
}
48 changes: 17 additions & 31 deletions src/shared/atlas/CharAtlasGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/

import { FontWeight } from 'xterm';
import { CHAR_ATLAS_CELL_SPACING } from './Types';
import { CHAR_ATLAS_CELL_SPACING, ICharAtlasConfig } from './Types';
import { isFirefox } from '../utils/Browser';

declare const Promise: any;
Expand All @@ -16,41 +16,27 @@ export interface IOffscreenCanvas {
transferToImageBitmap(): ImageBitmap;
}

export interface ICharAtlasRequest {
scaledCharWidth: number;
scaledCharHeight: number;
fontSize: number;
fontFamily: string;
fontWeight: FontWeight;
fontWeightBold: FontWeight;
background: string;
foreground: string;
ansiColors: string[];
devicePixelRatio: number;
allowTransparency: boolean;
}

/**
* Generates a char atlas.
* @param context The window or worker context.
* @param canvasFactory A function to generate a canvas with a width or height.
* @param request The config for the new char atlas.
*/
export function generateCharAtlas(context: Window, canvasFactory: (width: number, height: number) => HTMLCanvasElement | IOffscreenCanvas, request: ICharAtlasRequest): HTMLCanvasElement | Promise<ImageBitmap> {
const cellWidth = request.scaledCharWidth + CHAR_ATLAS_CELL_SPACING;
const cellHeight = request.scaledCharHeight + CHAR_ATLAS_CELL_SPACING;
export function generateCharAtlas(context: Window, canvasFactory: (width: number, height: number) => HTMLCanvasElement | IOffscreenCanvas, config: ICharAtlasConfig): HTMLCanvasElement | Promise<ImageBitmap> {
const cellWidth = config.scaledCharWidth + CHAR_ATLAS_CELL_SPACING;
const cellHeight = config.scaledCharHeight + CHAR_ATLAS_CELL_SPACING;
const canvas = canvasFactory(
/*255 ascii chars*/255 * cellWidth,
(/*default+default bold*/2 + /*0-15*/16) * cellHeight
);
const ctx = canvas.getContext('2d', {alpha: request.allowTransparency});
const ctx = canvas.getContext('2d', {alpha: config.allowTransparency});

ctx.fillStyle = request.background;
ctx.fillStyle = config.colors.background;
ctx.fillRect(0, 0, canvas.width, canvas.height);

ctx.save();
ctx.fillStyle = request.foreground;
ctx.font = getFont(request.fontWeight, request);
ctx.fillStyle = config.colors.foreground;
ctx.font = getFont(config.fontWeight, config);
ctx.textBaseline = 'top';

// Default color
Expand All @@ -64,7 +50,7 @@ export function generateCharAtlas(context: Window, canvasFactory: (width: number
}
// Default color bold
ctx.save();
ctx.font = getFont(request.fontWeightBold, request);
ctx.font = getFont(config.fontWeightBold, config);
for (let i = 0; i < 256; i++) {
ctx.save();
ctx.beginPath();
Expand All @@ -76,11 +62,11 @@ export function generateCharAtlas(context: Window, canvasFactory: (width: number
ctx.restore();

// Colors 0-15
ctx.font = getFont(request.fontWeight, request);
ctx.font = getFont(config.fontWeight, config);
for (let colorIndex = 0; colorIndex < 16; colorIndex++) {
// colors 8-15 are bold
if (colorIndex === 8) {
ctx.font = getFont(request.fontWeightBold, request);
ctx.font = getFont(config.fontWeightBold, config);
}
const y = (colorIndex + 2) * cellHeight;
// Draw ascii characters
Expand All @@ -89,7 +75,7 @@ export function generateCharAtlas(context: Window, canvasFactory: (width: number
ctx.beginPath();
ctx.rect(i * cellWidth, y, cellWidth, cellHeight);
ctx.clip();
ctx.fillStyle = request.ansiColors[colorIndex];
ctx.fillStyle = config.colors.ansi[colorIndex];
ctx.fillText(String.fromCharCode(i), i * cellWidth, y);
ctx.restore();
}
Expand All @@ -114,9 +100,9 @@ export function generateCharAtlas(context: Window, canvasFactory: (width: number
const charAtlasImageData = ctx.getImageData(0, 0, canvas.width, canvas.height);

// Remove the background color from the image so characters may overlap
const r = parseInt(request.background.substr(1, 2), 16);
const g = parseInt(request.background.substr(3, 2), 16);
const b = parseInt(request.background.substr(5, 2), 16);
const r = parseInt(config.colors.background.substr(1, 2), 16);
const g = parseInt(config.colors.background.substr(3, 2), 16);
const b = parseInt(config.colors.background.substr(5, 2), 16);
clearColor(charAtlasImageData, r, g, b);

return context.createImageBitmap(charAtlasImageData);
Expand All @@ -135,6 +121,6 @@ function clearColor(imageData: ImageData, r: number, g: number, b: number): void
}
}

function getFont(fontWeight: FontWeight, request: ICharAtlasRequest): string {
return `${fontWeight} ${request.fontSize * request.devicePixelRatio}px ${request.fontFamily}`;
function getFont(fontWeight: FontWeight, config: ICharAtlasConfig): string {
return `${fontWeight} ${config.fontSize * config.devicePixelRatio}px ${config.fontFamily}`;
}
15 changes: 15 additions & 0 deletions src/shared/atlas/Types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,19 @@
* @license MIT
*/

import { FontWeight } from 'xterm';
import { IColorSet } from '../Types';

export const CHAR_ATLAS_CELL_SPACING = 1;

export interface ICharAtlasConfig {
devicePixelRatio: number;
fontSize: number;
fontFamily: string;
fontWeight: FontWeight;
fontWeightBold: FontWeight;
scaledCharWidth: number;
scaledCharHeight: number;
allowTransparency: boolean;
colors: IColorSet;
}

0 comments on commit ed7741e

Please sign in to comment.