From 8c980bc30d6d1b460a2cbbfccffb610dcf7d8da4 Mon Sep 17 00:00:00 2001 From: Benjamin Woodruff Date: Sat, 10 Mar 2018 20:08:09 -0800 Subject: [PATCH] Add a dummy NoneCharAtlas implementation This adds the logic needed to switch between multiple char atlas implementations, and an example second implementation to test it out with. This also offers an escape hatch if something goes wrong with the char atlas implementation(s). --- demo/index.html | 9 +++++++++ demo/main.js | 4 ++++ src/Terminal.ts | 2 ++ src/renderer/atlas/CharAtlasCache.ts | 12 +++++++++--- src/renderer/atlas/CharAtlasUtils.ts | 4 +++- src/renderer/atlas/NoneCharAtlas.ts | 25 +++++++++++++++++++++++++ src/shared/atlas/Types.ts | 1 + typings/xterm.d.ts | 14 ++++++++++++++ 8 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 src/renderer/atlas/NoneCharAtlas.ts diff --git a/demo/index.html b/demo/index.html index 760d5990..e18614a4 100644 --- a/demo/index.html +++ b/demo/index.html @@ -53,6 +53,15 @@

+

+ +

Size

diff --git a/demo/main.js b/demo/main.js index d9c0151a..f7c863f5 100644 --- a/demo/main.js +++ b/demo/main.js @@ -32,6 +32,7 @@ var terminalContainer = document.getElementById('terminal-container'), macOptionIsMeta: document.querySelector('#option-mac-option-is-meta'), scrollback: document.querySelector('#option-scrollback'), tabstopwidth: document.querySelector('#option-tabstopwidth'), + experimentalCharAtlas: document.querySelector('#option-experimental-char-atlas'), bellStyle: document.querySelector('#option-bell-style'), screenReaderMode: document.querySelector('#option-screen-reader-mode') }, @@ -89,6 +90,9 @@ optionElements.scrollback.addEventListener('change', function () { optionElements.tabstopwidth.addEventListener('change', function () { term.setOption('tabStopWidth', parseInt(optionElements.tabstopwidth.value, 10)); }); +optionElements.experimentalCharAtlas.addEventListener('change', function () { + term.setOption('experimentalCharAtlas', optionElements.experimentalCharAtlas.value); +}); optionElements.screenReaderMode.addEventListener('change', function () { term.setOption('screenReaderMode', optionElements.screenReaderMode.checked); }); diff --git a/src/Terminal.ts b/src/Terminal.ts index 4b58f47d..809d0dd8 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -102,6 +102,7 @@ const DEFAULT_OPTIONS: ITerminalOptions = { bellSound: DEFAULT_BELL_SOUND, bellStyle: 'none', enableBold: true, + experimentalCharAtlas: 'static', fontFamily: 'courier-new, courier, monospace', fontSize: 15, fontWeight: 'normal', @@ -454,6 +455,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT this.charMeasure.measure(this.options); } break; + case 'experimentalCharAtlas': case 'enableBold': case 'letterSpacing': case 'lineHeight': diff --git a/src/renderer/atlas/CharAtlasCache.ts b/src/renderer/atlas/CharAtlasCache.ts index ea887a1a..14037acf 100644 --- a/src/renderer/atlas/CharAtlasCache.ts +++ b/src/renderer/atlas/CharAtlasCache.ts @@ -4,11 +4,17 @@ */ import { ITerminal } from '../../Types'; -import BaseCharAtlas from './BaseCharAtlas'; -import StaticCharAtlas from './StaticCharAtlas'; import { IColorSet } from '../Types'; import { ICharAtlasConfig } from '../../shared/atlas/Types'; import { generateConfig, configEquals } from './CharAtlasUtils'; +import BaseCharAtlas from './BaseCharAtlas'; +import NoneCharAtlas from './NoneCharAtlas'; +import StaticCharAtlas from './StaticCharAtlas'; + +const charAtlasImplementations = { + 'none': NoneCharAtlas, + 'static': StaticCharAtlas, +}; interface ICharAtlasCacheEntry { atlas: BaseCharAtlas; @@ -64,7 +70,7 @@ export function acquireCharAtlas( } const newEntry: ICharAtlasCacheEntry = { - atlas: new StaticCharAtlas( + atlas: new charAtlasImplementations[terminal.options.experimentalCharAtlas]( document, newConfig, ), diff --git a/src/renderer/atlas/CharAtlasUtils.ts b/src/renderer/atlas/CharAtlasUtils.ts index 24ed5a48..c0c54783 100644 --- a/src/renderer/atlas/CharAtlasUtils.ts +++ b/src/renderer/atlas/CharAtlasUtils.ts @@ -17,6 +17,7 @@ export function generateConfig(scaledCharWidth: number, scaledCharHeight: number ansi: colors.ansi.slice(0, 16) }; return { + type: terminal.options.experimentalCharAtlas, devicePixelRatio: window.devicePixelRatio, scaledCharWidth, scaledCharHeight, @@ -35,7 +36,8 @@ export function configEquals(a: ICharAtlasConfig, b: ICharAtlasConfig): boolean return false; } } - return a.devicePixelRatio === b.devicePixelRatio && + return a.type === b.type && + a.devicePixelRatio === b.devicePixelRatio && a.fontFamily === b.fontFamily && a.fontSize === b.fontSize && a.fontWeight === b.fontWeight && diff --git a/src/renderer/atlas/NoneCharAtlas.ts b/src/renderer/atlas/NoneCharAtlas.ts new file mode 100644 index 00000000..1cbc9eea --- /dev/null +++ b/src/renderer/atlas/NoneCharAtlas.ts @@ -0,0 +1,25 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + * + * A dummy CharAtlas implementation that always fails to draw characters. + */ + +import { IGlyphIdentifier } from './Types'; +import { ICharAtlasConfig } from '../../shared/atlas/Types'; +import BaseCharAtlas from './BaseCharAtlas'; + +export default class NoneCharAtlas extends BaseCharAtlas { + constructor(document: Document, config: ICharAtlasConfig) { + super(); + } + + public draw( + ctx: CanvasRenderingContext2D, + glyph: IGlyphIdentifier, + x: number, + y: number + ): boolean { + return false; + } +} diff --git a/src/shared/atlas/Types.ts b/src/shared/atlas/Types.ts index 4a66d554..2bec4194 100644 --- a/src/shared/atlas/Types.ts +++ b/src/shared/atlas/Types.ts @@ -9,6 +9,7 @@ import { IColorSet } from '../Types'; export const CHAR_ATLAS_CELL_SPACING = 1; export interface ICharAtlasConfig { + type: 'none' | 'static'; devicePixelRatio: number; fontSize: number; fontFamily: string; diff --git a/typings/xterm.d.ts b/typings/xterm.d.ts index 5c9e95e5..a208b7ed 100644 --- a/typings/xterm.d.ts +++ b/typings/xterm.d.ts @@ -61,6 +61,20 @@ declare module 'xterm' { */ enableBold?: boolean; + /** + * What character atlas implementation to use. The character atlas caches drawn characters, + * speeding up rendering significantly. However, it can introduce some minor rendering + * artifacts. + * + * - 'none': Don't use an atlas. + * - 'static': Generate an atlas when the terminal starts or is reconfigured. This atlas will + * only contain ASCII characters in 16 colors. + * + * Currently defaults to 'static'. This option may be removed in the future. If it is, passed + * parameters will be ignored. + */ + experimentalCharAtlas?: 'none' | 'static'; + /** * The font size used to render text. */