From 007410995a5218c3bde2196065deb11f41ffabc5 Mon Sep 17 00:00:00 2001 From: Bruno Ribeito Date: Wed, 8 Nov 2017 21:04:04 +0000 Subject: [PATCH] Fix#1117 --- fixtures/typings-test/typings-test.ts | 8 +++++--- src/Interfaces.ts | 3 ++- src/Terminal.ts | 10 ++++++++-- src/renderer/BaseRenderLayer.ts | 22 +++++++++++++++------- src/renderer/CharAtlas.ts | 18 ++++++++++++------ src/renderer/TextRenderLayer.ts | 2 +- typings/xterm.d.ts | 6 ++++++ 7 files changed, 49 insertions(+), 20 deletions(-) diff --git a/fixtures/typings-test/typings-test.ts b/fixtures/typings-test/typings-test.ts index 93fd501f..b8425205 100644 --- a/fixtures/typings-test/typings-test.ts +++ b/fixtures/typings-test/typings-test.ts @@ -143,8 +143,9 @@ namespace methods_core { const r18: (data: string) => void = t.getOption('handler'); const r19: string = t.getOption('bellSound'); const r20: string = t.getOption('bellStyle'); - const r21: boolean = t.getOption('enableBold'); - const r22: number = t.getOption('letterSpacing'); + const r21: number = t.getOption('letterSpacing'); + const r22: number = t.getOption('fontWeight'); + const r23: number = t.getOption('fontWeightBold'); } { const t: Terminal = new Terminal(); @@ -157,7 +158,8 @@ namespace methods_core { t.setOption('cursorBlink', true); t.setOption('debug', true); t.setOption('disableStdin', true); - t.setOption('enableBold', true); + t.setOption('fontWeight', 'normal'); + t.setOption('fontWeightBold', 'bold'); t.setOption('popOnBell', true); t.setOption('screenKeys', true); t.setOption('useFlowControl', true); diff --git a/src/Interfaces.ts b/src/Interfaces.ts index 354e2c4e..77e94978 100644 --- a/src/Interfaces.ts +++ b/src/Interfaces.ts @@ -137,9 +137,10 @@ export interface ITerminalOptions { cursorStyle?: string; debug?: boolean; disableStdin?: boolean; - enableBold?: boolean; fontSize?: number; fontFamily?: string; + fontWeight?: string; + fontWeightBold?: string; geometry?: [number, number]; handler?: (data: string) => void; letterSpacing?: number; diff --git a/src/Terminal.ts b/src/Terminal.ts index 867c522d..1f08ce8a 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -77,9 +77,10 @@ const DEFAULT_OPTIONS: ITerminalOptions = { cursorStyle: 'block', bellSound: BellSound, bellStyle: 'none', - enableBold: true, fontFamily: 'courier-new, courier, monospace', fontSize: 15, + fontWeight: 'normal', + fontWeightBold: 'bold', lineHeight: 1.0, letterSpacing: 0, scrollback: 1000, @@ -416,7 +417,6 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT this.renderer.clear(); this.charMeasure.measure(this.options); break; - case 'enableBold': case 'letterSpacing': case 'lineHeight': // When the font changes the size of the cells may change which requires a renderer clear @@ -424,6 +424,12 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT this.renderer.onResize(this.cols, this.rows, false); this.refresh(0, this.rows - 1); // this.charMeasure.measure(this.options); + case 'fontWeight': + case 'fontWeightBold': + // When the font weight changes the size of the cells may change which requires a renderer clear + this.renderer.clear(); + this.renderer.onResize(this.cols, this.rows, true); + this.refresh(0, this.rows - 1); case 'scrollback': this.buffers.resize(this.cols, this.rows); this.viewport.syncScrollArea(); diff --git a/src/renderer/BaseRenderLayer.ts b/src/renderer/BaseRenderLayer.ts index b4becbce..a5f4370c 100644 --- a/src/renderer/BaseRenderLayer.ts +++ b/src/renderer/BaseRenderLayer.ts @@ -201,7 +201,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { * @param color The color of the character. */ protected fillCharTrueColor(terminal: ITerminal, charData: CharData, x: number, y: number): void { - this._ctx.font = `${terminal.options.fontSize * window.devicePixelRatio}px ${terminal.options.fontFamily}`; + this._ctx.font = this._getFont(terminal, false); this._ctx.textBaseline = 'top'; this._clipRow(terminal, y); this._ctx.fillText( @@ -230,7 +230,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { colorIndex = fg + 2; } else { // If default color and bold - if (bold && terminal.options.enableBold) { + if (bold) { colorIndex = 1; } } @@ -252,7 +252,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { } // Draw the non-bold version of the same color if bold is not enabled - if (bold && !terminal.options.enableBold) { + if (bold) { // Ignore default color as it's not touched above if (colorIndex > 1) { colorIndex -= 8; @@ -289,10 +289,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { */ private _drawUncachedChar(terminal: ITerminal, char: string, width: number, fg: number, x: number, y: number, bold: boolean, dim: boolean): void { this._ctx.save(); - this._ctx.font = `${terminal.options.fontSize * window.devicePixelRatio}px ${terminal.options.fontFamily}`; - if (bold && terminal.options.enableBold) { - this._ctx.font = `bold ${this._ctx.font}`; - } + this._ctx.font = this._getFont(terminal, bold); this._ctx.textBaseline = 'top'; if (fg === INVERTED_DEFAULT_COLOR) { @@ -332,5 +329,16 @@ export abstract class BaseRenderLayer implements IRenderLayer { this._scaledCellHeight); this._ctx.clip(); } + + /** + * Gets the current font. + * @param terminal The terminal. + * @param isBold The font weight that should be used uses terminal option as fallback. + */ + private _getFont(terminal: ITerminal, isBold: boolean): string { + const fontWeight = isBold ? terminal.options.fontWeightBold : terminal.options.fontWeight; + + return `${fontWeight} ${terminal.options.fontSize * window.devicePixelRatio}px ${terminal.options.fontFamily}`; + } } diff --git a/src/renderer/CharAtlas.ts b/src/renderer/CharAtlas.ts index 9ac1e161..50b9b9bd 100644 --- a/src/renderer/CharAtlas.ts +++ b/src/renderer/CharAtlas.ts @@ -12,6 +12,8 @@ export const CHAR_ATLAS_CELL_SPACING = 1; interface ICharAtlasConfig { fontSize: number; fontFamily: string; + fontWeight: string; + fontWeightBold: string; scaledCharWidth: number; scaledCharHeight: number; colors: IColorSet; @@ -64,7 +66,7 @@ export function acquireCharAtlas(terminal: ITerminal, colors: IColorSet, scaledC } const newEntry: ICharAtlasCacheEntry = { - bitmap: generator.generate(scaledCharWidth, scaledCharHeight, terminal.options.fontSize, terminal.options.fontFamily, colors.background, colors.foreground, colors.ansi), + bitmap: generator.generate(scaledCharWidth, scaledCharHeight, terminal.options.fontSize, terminal.options.fontFamily, terminal.options.fontWeight, terminal.options.fontWeightBold, colors.background, colors.foreground, colors.ansi), config: newConfig, ownedBy: [terminal] }; @@ -86,6 +88,8 @@ function generateConfig(scaledCharWidth: number, scaledCharHeight: number, termi scaledCharHeight, fontFamily: terminal.options.fontFamily, fontSize: terminal.options.fontSize, + fontWeight: terminal.options.fontWeight, + fontWeightBold: terminal.options.fontWeightBold, colors: clonedColors }; } @@ -98,6 +102,8 @@ function configEquals(a: ICharAtlasConfig, b: ICharAtlasConfig): boolean { } return a.fontFamily === b.fontFamily && a.fontSize === b.fontSize && + a.fontWeight === b.fontWeight && + a.fontWeightBold === b.fontWeightBold && a.scaledCharWidth === b.scaledCharWidth && a.scaledCharHeight === b.scaledCharHeight && a.colors.foreground === b.colors.foreground && @@ -126,7 +132,7 @@ class CharAtlasGenerator { this._ctx.scale(window.devicePixelRatio, window.devicePixelRatio); } - public generate(scaledCharWidth: number, scaledCharHeight: number, fontSize: number, fontFamily: string, background: string, foreground: string, ansiColors: string[]): HTMLCanvasElement | Promise { + public generate(scaledCharWidth: number, scaledCharHeight: number, fontSize: number, fontFamily: string, fontWeight: string, fontWeightBold: string, background: string, foreground: string, ansiColors: string[]): HTMLCanvasElement | Promise { const cellWidth = scaledCharWidth + CHAR_ATLAS_CELL_SPACING; const cellHeight = scaledCharHeight + CHAR_ATLAS_CELL_SPACING; this._canvas.width = 255 * cellWidth; @@ -137,7 +143,7 @@ class CharAtlasGenerator { this._ctx.save(); this._ctx.fillStyle = foreground; - this._ctx.font = `${fontSize * window.devicePixelRatio}px ${fontFamily}`; + this._ctx.font = `${fontWeight} ${fontSize * window.devicePixelRatio}px ${fontFamily}`; this._ctx.textBaseline = 'top'; // Default color @@ -151,7 +157,7 @@ class CharAtlasGenerator { } // Default color bold this._ctx.save(); - this._ctx.font = `bold ${this._ctx.font}`; + this._ctx.font = `${fontWeightBold} ${fontSize * window.devicePixelRatio}px ${fontFamily}`; for (let i = 0; i < 256; i++) { this._ctx.save(); this._ctx.beginPath(); @@ -163,11 +169,11 @@ class CharAtlasGenerator { this._ctx.restore(); // Colors 0-15 - this._ctx.font = `${fontSize * window.devicePixelRatio}px ${fontFamily}`; + this._ctx.font = `${fontWeight} ${fontSize * window.devicePixelRatio}px ${fontFamily}`; for (let colorIndex = 0; colorIndex < 16; colorIndex++) { // colors 8-15 are bold if (colorIndex === 8) { - this._ctx.font = `bold ${this._ctx.font}`; + this._ctx.font = `${fontWeightBold} ${fontSize * window.devicePixelRatio}px ${fontFamily}`; } const y = (colorIndex + 2) * cellHeight; // Draw ascii characters diff --git a/src/renderer/TextRenderLayer.ts b/src/renderer/TextRenderLayer.ts index 2ecb6ec6..5a13242f 100644 --- a/src/renderer/TextRenderLayer.ts +++ b/src/renderer/TextRenderLayer.ts @@ -33,7 +33,7 @@ export class TextRenderLayer extends BaseRenderLayer { super.resize(terminal, dim, charSizeChanged); // Clear the character width cache if the font or width has changed - const terminalFont = `${terminal.options.fontSize * window.devicePixelRatio}px ${terminal.options.fontFamily}`; + const terminalFont = `${terminal.options.fontWeight} ${terminal.options.fontSize * window.devicePixelRatio}px ${terminal.options.fontFamily}`; if (this._characterWidth !== dim.scaledCharWidth || this._characterFont !== terminalFont) { this._characterWidth = dim.scaledCharWidth; this._characterFont = terminalFont; diff --git a/typings/xterm.d.ts b/typings/xterm.d.ts index b0f5ac4d..aa7d8f3e 100644 --- a/typings/xterm.d.ts +++ b/typings/xterm.d.ts @@ -442,6 +442,12 @@ declare module 'xterm' { * @param value The option value. */ setOption(key: 'fontFamily' | 'termName' | 'bellSound', value: string): void; + /** + * Sets an option on the terminal. + * @param key The option key. + * @param value The option value. + */ + setOption(key: 'fontWeight' | 'fontWeightBold', value: null | 'normal' | 'bold' | 'bolder' | 'lighter' | '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900'): void; /** * Sets an option on the terminal. * @param key The option key.