From 59f940c19c53fa440b7f8e21d027cb59fd821e86 Mon Sep 17 00:00:00 2001 From: Daniel Steinberg Date: Wed, 16 Jun 2021 23:16:36 +0000 Subject: [PATCH] Set text baseline conditionally by browser. --- addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts | 4 ++-- addons/xterm-addon-webgl/src/renderLayer/BaseRenderLayer.ts | 3 ++- src/browser/renderer/BaseRenderLayer.ts | 6 +++--- src/browser/renderer/atlas/Constants.ts | 6 ++++++ src/browser/renderer/atlas/DynamicCharAtlas.ts | 4 ++-- 5 files changed, 15 insertions(+), 8 deletions(-) diff --git a/addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts b/addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts index 6128c836..609df6eb 100644 --- a/addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts +++ b/addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts @@ -4,7 +4,7 @@ */ import { ICharAtlasConfig } from './Types'; -import { DIM_OPACITY } from 'browser/renderer/atlas/Constants'; +import { DIM_OPACITY, TEXT_BASELINE } from 'browser/renderer/atlas/Constants'; import { IRasterizedGlyph, IBoundingBox, IRasterizedGlyphSet } from '../Types'; import { DEFAULT_COLOR, Attributes } from 'common/buffer/Constants'; import { throwIfFalsy } from '../WebglUtils'; @@ -368,7 +368,7 @@ export class WebglCharAtlas implements IDisposable { const fontStyle = italic ? 'italic' : ''; this._tmpCtx.font = `${fontStyle} ${fontWeight} ${this._config.fontSize * this._config.devicePixelRatio}px ${this._config.fontFamily}`; - this._tmpCtx.textBaseline = 'ideographic'; + this._tmpCtx.textBaseline = TEXT_BASELINE; this._tmpCtx.fillStyle = this._getForegroundCss(bg, bgColorMode, bgColor, fg, fgColorMode, fgColor, inverse, bold); diff --git a/addons/xterm-addon-webgl/src/renderLayer/BaseRenderLayer.ts b/addons/xterm-addon-webgl/src/renderLayer/BaseRenderLayer.ts index 532836ee..4c17aad4 100644 --- a/addons/xterm-addon-webgl/src/renderLayer/BaseRenderLayer.ts +++ b/addons/xterm-addon-webgl/src/renderLayer/BaseRenderLayer.ts @@ -7,6 +7,7 @@ import { IRenderLayer } from './Types'; import { acquireCharAtlas } from '../atlas/CharAtlasCache'; import { Terminal } from 'xterm'; import { IColorSet } from 'browser/Types'; +import { TEXT_BASELINE } from 'browser/renderer/atlas/Constants'; import { IRenderDimensions } from 'browser/renderer/Types'; import { CellData } from 'common/buffer/CellData'; import { WebglCharAtlas } from 'atlas/WebglCharAtlas'; @@ -224,7 +225,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { */ protected _fillCharTrueColor(terminal: Terminal, cell: CellData, x: number, y: number): void { this._ctx.font = this._getFont(terminal, false, false); - this._ctx.textBaseline = 'ideographic'; + this._ctx.textBaseline = TEXT_BASELINE; this._clipRow(terminal, y); this._ctx.fillText( cell.getChars(), diff --git a/src/browser/renderer/BaseRenderLayer.ts b/src/browser/renderer/BaseRenderLayer.ts index 68f83a75..40b6e3f9 100644 --- a/src/browser/renderer/BaseRenderLayer.ts +++ b/src/browser/renderer/BaseRenderLayer.ts @@ -7,7 +7,7 @@ import { IRenderDimensions, IRenderLayer } from 'browser/renderer/Types'; import { ICellData } from 'common/Types'; import { DEFAULT_COLOR, WHITESPACE_CELL_CHAR, WHITESPACE_CELL_CODE, Attributes } from 'common/buffer/Constants'; import { IGlyphIdentifier } from 'browser/renderer/atlas/Types'; -import { DIM_OPACITY, INVERTED_DEFAULT_COLOR } from 'browser/renderer/atlas/Constants'; +import { DIM_OPACITY, INVERTED_DEFAULT_COLOR, TEXT_BASELINE } from 'browser/renderer/atlas/Constants'; import { BaseCharAtlas } from 'browser/renderer/atlas/BaseCharAtlas'; import { acquireCharAtlas } from 'browser/renderer/atlas/CharAtlasCache'; import { AttributeData } from 'common/buffer/AttributeData'; @@ -262,7 +262,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { */ protected _fillCharTrueColor(cell: CellData, x: number, y: number): void { this._ctx.font = this._getFont(false, false); - this._ctx.textBaseline = 'ideographic'; + this._ctx.textBaseline = TEXT_BASELINE; this._clipRow(y); // Draw custom characters if applicable @@ -350,7 +350,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { private _drawUncachedChars(cell: ICellData, x: number, y: number, fgOverride?: IColor): void { this._ctx.save(); this._ctx.font = this._getFont(!!cell.isBold(), !!cell.isItalic()); - this._ctx.textBaseline = 'ideographic'; + this._ctx.textBaseline = TEXT_BASELINE; if (cell.isInverse()) { if (fgOverride) { diff --git a/src/browser/renderer/atlas/Constants.ts b/src/browser/renderer/atlas/Constants.ts index 150aad88..e698bcd8 100644 --- a/src/browser/renderer/atlas/Constants.ts +++ b/src/browser/renderer/atlas/Constants.ts @@ -3,7 +3,13 @@ * @license MIT */ +import { isFirefox } from 'common/Platform'; + export const INVERTED_DEFAULT_COLOR = 257; export const DIM_OPACITY = 0.5; +// The text baseline is set conditionally by browser. Using 'ideographic' for Firefox would +// result in truncated text (Issue 3353). Using 'bottom' for Chrome would result in slightly +// unaligned Powerline fonts (PR 3356#issuecomment-850928179). +export const TEXT_BASELINE: CanvasTextBaseline = isFirefox ? 'bottom' : 'ideographic'; export const CHAR_ATLAS_CELL_SPACING = 1; diff --git a/src/browser/renderer/atlas/DynamicCharAtlas.ts b/src/browser/renderer/atlas/DynamicCharAtlas.ts index 666324ad..118dbcd2 100644 --- a/src/browser/renderer/atlas/DynamicCharAtlas.ts +++ b/src/browser/renderer/atlas/DynamicCharAtlas.ts @@ -3,7 +3,7 @@ * @license MIT */ -import { DIM_OPACITY, INVERTED_DEFAULT_COLOR } from 'browser/renderer/atlas/Constants'; +import { DIM_OPACITY, INVERTED_DEFAULT_COLOR, TEXT_BASELINE } from 'browser/renderer/atlas/Constants'; import { IGlyphIdentifier, ICharAtlasConfig } from 'browser/renderer/atlas/Types'; import { BaseCharAtlas } from 'browser/renderer/atlas/BaseCharAtlas'; import { DEFAULT_ANSI_COLORS } from 'browser/ColorManager'; @@ -266,7 +266,7 @@ export class DynamicCharAtlas extends BaseCharAtlas { const fontStyle = glyph.italic ? 'italic' : ''; this._tmpCtx.font = `${fontStyle} ${fontWeight} ${this._config.fontSize * this._config.devicePixelRatio}px ${this._config.fontFamily}`; - this._tmpCtx.textBaseline = 'ideographic'; + this._tmpCtx.textBaseline = TEXT_BASELINE; this._tmpCtx.fillStyle = this._getForegroundColor(glyph).css;