We changed plans from moving web worker compatible code to shared/ to enforcing layers using core/, common/, ui/ and public/. This change moves files back from the shared/ dir to clean up the codebase. Part of #1507
101 lines
2.8 KiB
TypeScript
101 lines
2.8 KiB
TypeScript
/**
|
|
* Copyright (c) 2017 The xterm.js authors. All rights reserved.
|
|
* @license MIT
|
|
*/
|
|
|
|
import { DIM_OPACITY, IGlyphIdentifier, DEFAULT_COLOR, ICharAtlasConfig, CHAR_ATLAS_CELL_SPACING } from './Types';
|
|
import { generateStaticCharAtlasTexture } from './CharAtlasGenerator';
|
|
import BaseCharAtlas from './BaseCharAtlas';
|
|
import { is256Color } from './CharAtlasUtils';
|
|
|
|
export default class StaticCharAtlas extends BaseCharAtlas {
|
|
private _texture: HTMLCanvasElement | ImageBitmap;
|
|
|
|
constructor(private _document: Document, private _config: ICharAtlasConfig) {
|
|
super();
|
|
}
|
|
|
|
private _canvasFactory = (width: number, height: number) => {
|
|
const canvas = this._document.createElement('canvas');
|
|
canvas.width = width;
|
|
canvas.height = height;
|
|
|
|
// This is useful for debugging
|
|
// document.body.appendChild(canvas);
|
|
|
|
return canvas;
|
|
}
|
|
|
|
protected _doWarmUp(): void {
|
|
const result = generateStaticCharAtlasTexture(window, this._canvasFactory, this._config);
|
|
if (result instanceof HTMLCanvasElement) {
|
|
this._texture = result;
|
|
} else {
|
|
result.then(texture => {
|
|
this._texture = texture;
|
|
});
|
|
}
|
|
}
|
|
|
|
private _isCached(glyph: IGlyphIdentifier, colorIndex: number): boolean {
|
|
const isAscii = glyph.code < 256;
|
|
// A color is basic if it is one of the 4 bit ANSI colors.
|
|
const isBasicColor = glyph.fg < 16;
|
|
const isDefaultColor = glyph.fg === DEFAULT_COLOR;
|
|
const isDefaultBackground = glyph.bg === DEFAULT_COLOR;
|
|
return isAscii && (isBasicColor || isDefaultColor) && isDefaultBackground && !glyph.italic;
|
|
}
|
|
|
|
public draw(
|
|
ctx: CanvasRenderingContext2D,
|
|
glyph: IGlyphIdentifier,
|
|
x: number,
|
|
y: number
|
|
): boolean {
|
|
// we're not warmed up yet
|
|
if (this._texture === null || this._texture === undefined) {
|
|
return false;
|
|
}
|
|
|
|
let colorIndex = 0;
|
|
if (is256Color(glyph.fg)) {
|
|
colorIndex = 2 + glyph.fg + (glyph.bold ? 16 : 0);
|
|
} else if (glyph.fg === DEFAULT_COLOR) {
|
|
// If default color and bold
|
|
if (glyph.bold) {
|
|
colorIndex = 1;
|
|
}
|
|
}
|
|
if (!this._isCached(glyph, colorIndex)) {
|
|
return false;
|
|
}
|
|
|
|
ctx.save();
|
|
|
|
// ImageBitmap's draw about twice as fast as from a canvas
|
|
const charAtlasCellWidth = this._config.scaledCharWidth + CHAR_ATLAS_CELL_SPACING;
|
|
const charAtlasCellHeight = this._config.scaledCharHeight + CHAR_ATLAS_CELL_SPACING;
|
|
|
|
// Apply alpha to dim the character
|
|
if (glyph.dim) {
|
|
ctx.globalAlpha = DIM_OPACITY;
|
|
}
|
|
|
|
ctx.drawImage(
|
|
this._texture,
|
|
glyph.code * charAtlasCellWidth,
|
|
colorIndex * charAtlasCellHeight,
|
|
charAtlasCellWidth,
|
|
this._config.scaledCharHeight,
|
|
x,
|
|
y,
|
|
charAtlasCellWidth,
|
|
this._config.scaledCharHeight
|
|
);
|
|
|
|
ctx.restore();
|
|
|
|
return true;
|
|
}
|
|
}
|