Add a basic dynamic character atlas implementation

This adds a very minimal implementation of DynamicCharAtlas using a LRU
cache.

I've got some optimizations that I'll add on top of this, but this
proves the concept.
This commit is contained in:
Benjamin Woodruff
2018-04-15 18:49:07 -07:00
parent 8c980bc30d
commit 24feaabd9a
9 changed files with 226 additions and 13 deletions
+8 -7
View File
@@ -5,6 +5,7 @@
import { FontWeight } from 'xterm';
import { CHAR_ATLAS_CELL_SPACING, ICharAtlasConfig } from './Types';
import { IColor } from '../Types';
import { isFirefox } from '../utils/Browser';
declare const Promise: any;
@@ -20,9 +21,9 @@ export interface IOffscreenCanvas {
* 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.
* @param config The config for the new char atlas.
*/
export function generateCharAtlas(context: Window, canvasFactory: (width: number, height: number) => HTMLCanvasElement | IOffscreenCanvas, config: ICharAtlasConfig): HTMLCanvasElement | Promise<ImageBitmap> {
export function generateStaticCharAtlasTexture(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(
@@ -100,10 +101,7 @@ 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 = config.colors.background.rgba >>> 24;
const g = config.colors.background.rgba >>> 16 & 0xFF;
const b = config.colors.background.rgba >>> 8 & 0xFF;
clearColor(charAtlasImageData, r, g, b);
clearColor(charAtlasImageData, config.colors.background);
return context.createImageBitmap(charAtlasImageData);
}
@@ -111,7 +109,10 @@ export function generateCharAtlas(context: Window, canvasFactory: (width: number
/**
* Makes a partiicular rgb color in an ImageData completely transparent.
*/
function clearColor(imageData: ImageData, r: number, g: number, b: number): void {
export function clearColor(imageData: ImageData, color: IColor): void {
const r = color.rgba >>> 24;
const g = color.rgba >>> 16 & 0xFF;
const b = color.rgba >>> 8 & 0xFF;
for (let offset = 0; offset < imageData.data.length; offset += 4) {
if (imageData.data[offset] === r &&
imageData.data[offset + 1] === g &&
+1 -1
View File
@@ -9,7 +9,7 @@ import { IColorSet } from '../Types';
export const CHAR_ATLAS_CELL_SPACING = 1;
export interface ICharAtlasConfig {
type: 'none' | 'static';
type: 'none' | 'static' | 'dynamic';
devicePixelRatio: number;
fontSize: number;
fontFamily: string;