From 96dd021ca4c361a547b12901d8805a9c9c07926f Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 9 Jul 2021 07:32:25 -0700 Subject: [PATCH 1/5] Support underline in webgl renderer Fixes #2251 --- addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts b/addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts index 5e1ad195..fb20c1c8 100644 --- a/addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts +++ b/addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts @@ -338,6 +338,7 @@ export class WebglCharAtlas implements IDisposable { const inverse = !!this._workAttributeData.isInverse(); const dim = !!this._workAttributeData.isDim(); const italic = !!this._workAttributeData.isItalic(); + const underline = !!this._workAttributeData.isUnderline(); let fgColor = this._workAttributeData.getFgColor(); let fgColorMode = this._workAttributeData.getFgColorMode(); let bgColor = this._workAttributeData.getBgColor(); @@ -390,6 +391,12 @@ export class WebglCharAtlas implements IDisposable { // Draw the character this._tmpCtx.fillText(chars, padding, padding + this._config.scaledCharHeight); + if (underline) { + this._tmpCtx.strokeStyle = this._tmpCtx.fillStyle; + this._tmpCtx.moveTo(0, this._config.scaledCharHeight - 1); + this._tmpCtx.lineTo(this._config.scaledCharWidth, this._config.scaledCharHeight - 1); + this._tmpCtx.stroke(); + } this._tmpCtx.restore(); // clear the background from the character to avoid issues with drawing over the previous From bc702d28ff32ad3086b18a4db75e732ae544a55d Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 9 Jul 2021 07:39:19 -0700 Subject: [PATCH 2/5] Support webgl strikethrough, fix underline position Fixes #580 --- .../xterm-addon-webgl/src/atlas/WebglCharAtlas.ts | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts b/addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts index fb20c1c8..db0da6d7 100644 --- a/addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts +++ b/addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts @@ -339,6 +339,7 @@ export class WebglCharAtlas implements IDisposable { const dim = !!this._workAttributeData.isDim(); const italic = !!this._workAttributeData.isItalic(); const underline = !!this._workAttributeData.isUnderline(); + const strikethrough = !!this._workAttributeData.isStrikethrough(); let fgColor = this._workAttributeData.getFgColor(); let fgColorMode = this._workAttributeData.getFgColorMode(); let bgColor = this._workAttributeData.getBgColor(); @@ -393,9 +394,19 @@ export class WebglCharAtlas implements IDisposable { this._tmpCtx.fillText(chars, padding, padding + this._config.scaledCharHeight); if (underline) { this._tmpCtx.strokeStyle = this._tmpCtx.fillStyle; - this._tmpCtx.moveTo(0, this._config.scaledCharHeight - 1); - this._tmpCtx.lineTo(this._config.scaledCharWidth, this._config.scaledCharHeight - 1); + this._tmpCtx.beginPath(); + this._tmpCtx.moveTo(padding, padding + this._config.scaledCharHeight - 0.5); + this._tmpCtx.lineTo(padding + this._config.scaledCharWidth, padding + this._config.scaledCharHeight - 0.5); this._tmpCtx.stroke(); + this._tmpCtx.closePath(); + } + if (strikethrough) { + this._tmpCtx.strokeStyle = this._tmpCtx.fillStyle; + this._tmpCtx.beginPath(); + this._tmpCtx.moveTo(padding, padding + Math.floor(this._config.scaledCharHeight / 2) + 0.5); + this._tmpCtx.lineTo(padding + this._config.scaledCharWidth, padding + Math.floor(this._config.scaledCharHeight / 2) + 0.5); + this._tmpCtx.stroke(); + this._tmpCtx.closePath(); } this._tmpCtx.restore(); From aad6f8147e2696c9f1bb9e6cdfae10799294052c Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 9 Jul 2021 07:44:10 -0700 Subject: [PATCH 3/5] Increase underline/strikethrough width with font size --- .../src/atlas/WebglCharAtlas.ts | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts b/addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts index db0da6d7..5f729e28 100644 --- a/addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts +++ b/addons/xterm-addon-webgl/src/atlas/WebglCharAtlas.ts @@ -392,22 +392,26 @@ export class WebglCharAtlas implements IDisposable { // Draw the character this._tmpCtx.fillText(chars, padding, padding + this._config.scaledCharHeight); - if (underline) { + + // Draw underline and strikethrough + if (underline || strikethrough) { + const lineWidth = Math.max(1, Math.floor(this._config.fontSize / 10)); + const yOffset = this._tmpCtx.lineWidth % 2 === 1 ? 0.5 : 0; // When the width is odd, draw at 0.5 position + this._tmpCtx.lineWidth = lineWidth; this._tmpCtx.strokeStyle = this._tmpCtx.fillStyle; this._tmpCtx.beginPath(); - this._tmpCtx.moveTo(padding, padding + this._config.scaledCharHeight - 0.5); - this._tmpCtx.lineTo(padding + this._config.scaledCharWidth, padding + this._config.scaledCharHeight - 0.5); - this._tmpCtx.stroke(); - this._tmpCtx.closePath(); - } - if (strikethrough) { - this._tmpCtx.strokeStyle = this._tmpCtx.fillStyle; - this._tmpCtx.beginPath(); - this._tmpCtx.moveTo(padding, padding + Math.floor(this._config.scaledCharHeight / 2) + 0.5); - this._tmpCtx.lineTo(padding + this._config.scaledCharWidth, padding + Math.floor(this._config.scaledCharHeight / 2) + 0.5); + if (underline) { + this._tmpCtx.moveTo(padding, padding + this._config.scaledCharHeight - yOffset); + this._tmpCtx.lineTo(padding + this._config.scaledCharWidth, padding + this._config.scaledCharHeight - yOffset); + } + if (strikethrough) { + this._tmpCtx.moveTo(padding, padding + Math.floor(this._config.scaledCharHeight / 2) - yOffset); + this._tmpCtx.lineTo(padding + this._config.scaledCharWidth, padding + Math.floor(this._config.scaledCharHeight / 2) - yOffset); + } this._tmpCtx.stroke(); this._tmpCtx.closePath(); } + this._tmpCtx.restore(); // clear the background from the character to avoid issues with drawing over the previous From 1f019093fc59bb637ac9677ad5642ecd87c1241e Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 9 Jul 2021 07:48:26 -0700 Subject: [PATCH 4/5] Update SGR support table --- src/common/InputHandler.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/InputHandler.ts b/src/common/InputHandler.ts index d4f2159f..d4354e90 100644 --- a/src/common/InputHandler.ts +++ b/src/common/InputHandler.ts @@ -2360,12 +2360,12 @@ export class InputHandler extends Disposable implements IInputHandler { * | 1 | Bold. (also see `options.drawBoldTextInBrightColors`) | #Y | * | 2 | Faint, decreased intensity. | #Y | * | 3 | Italic. | #Y | - * | 4 | Underlined (see below for style support). | #P[Support in DOM and Canvas renderers, not WebGL] | + * | 4 | Underlined (see below for style support). | #Y | * | 5 | Slowly blinking. | #N | * | 6 | Rapidly blinking. | #N | * | 7 | Inverse. Flips foreground and background color. | #Y | * | 8 | Invisible (hidden). | #Y | - * | 9 | Crossed-out characters (strikethrough). | #P[Support in DOM and Canvas renderers, not WebGL] | + * | 9 | Crossed-out characters (strikethrough). | #Y | * | 21 | Doubly underlined. | #P[Currently outputs a single underline.] | * | 22 | Normal (neither bold nor faint). | #Y | * | 23 | No italic. | #Y | From 8ec33686366ad43304d818180a7bc3dcbff4f6bf Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 9 Jul 2021 08:17:52 -0700 Subject: [PATCH 5/5] Fix underline/strikethrough on space chars --- addons/xterm-addon-webgl/src/GlyphRenderer.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/addons/xterm-addon-webgl/src/GlyphRenderer.ts b/addons/xterm-addon-webgl/src/GlyphRenderer.ts index b09fe540..71b3659e 100644 --- a/addons/xterm-addon-webgl/src/GlyphRenderer.ts +++ b/addons/xterm-addon-webgl/src/GlyphRenderer.ts @@ -176,8 +176,9 @@ export class GlyphRenderer { const i = (y * terminal.cols + x) * INDICES_PER_CELL; - // Exit early if this is a null/space character - if (code === NULL_CELL_CODE || code === WHITESPACE_CELL_CODE || code === undefined/* This is used for the right side of wide chars */) { + // Exit early if this is a null character, allow space character to continue as it may have + // underline/strikethrough styles + if (code === NULL_CELL_CODE || code === undefined/* This is used for the right side of wide chars */) { fill(array, 0, i, i + INDICES_PER_CELL - 1 - CELL_POSITION_INDICES); return; }