From 24cbedb71528bc2d65b7c200af7ae1eac1fe85ab Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Thu, 19 Aug 2021 05:32:46 -0700 Subject: [PATCH] Fix custom glyphs when using transparency --- .../test/WebglRenderer.api.ts | 6 ++-- src/browser/renderer/CustomGlyphs.ts | 30 ++++++++++++++----- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/addons/xterm-addon-webgl/test/WebglRenderer.api.ts b/addons/xterm-addon-webgl/test/WebglRenderer.api.ts index 48f9c3d0..793929e9 100644 --- a/addons/xterm-addon-webgl/test/WebglRenderer.api.ts +++ b/addons/xterm-addon-webgl/test/WebglRenderer.api.ts @@ -3,11 +3,11 @@ * @license MIT */ -import { ITerminalOptions } from '../../../src/common/Types'; -import { ITheme } from 'xterm'; import { assert } from 'chai'; -import { openTerminal, pollFor, writeSync, getBrowserType, timeout } from '../../../out-test/api/TestUtils'; import { Browser, Page } from 'playwright'; +import { ITheme } from 'xterm'; +import { getBrowserType, openTerminal, pollFor, writeSync } from '../../../out-test/api/TestUtils'; +import { ITerminalOptions } from '../../../src/common/Types'; const APP = 'http://127.0.0.1:3001/test'; diff --git a/src/browser/renderer/CustomGlyphs.ts b/src/browser/renderer/CustomGlyphs.ts index 82e086c4..a132877a 100644 --- a/src/browser/renderer/CustomGlyphs.ts +++ b/src/browser/renderer/CustomGlyphs.ts @@ -379,8 +379,10 @@ function drawPatternChar( patternSet = new Map(); cachedPatterns.set(charDefinition, patternSet); } - // TODO: Unsafe? - const fillStyle = ctx.fillStyle as string; + const fillStyle = ctx.fillStyle; + if (typeof fillStyle !== 'string') { + throw new Error(`Unexpected fillStyle type "${fillStyle}"`); + } let pattern = patternSet.get(fillStyle); if (!pattern) { const width = charDefinition[0].length; @@ -390,17 +392,29 @@ function drawPatternChar( tmpCanvas.height = height; const tmpCtx = throwIfFalsy(tmpCanvas.getContext('2d')); const imageData = new ImageData(width, height); - // TODO: This is a little unsafe, fillStyle could be rgb/rgba format - const r = parseInt(fillStyle.substr(1, 2), 16); - const g = parseInt(fillStyle.substr(3, 2), 16); - const b = parseInt(fillStyle.substr(5, 2), 16); - const a = fillStyle.length > 7 && parseInt(fillStyle.substr(7, 2), 16) || undefined; + + // Extract rgba from fillStyle + let r: number; + let g: number; + let b: number; + let a: number; + if (fillStyle.startsWith('#')) { + r = parseInt(fillStyle.substr(1, 2), 16); + g = parseInt(fillStyle.substr(3, 2), 16); + b = parseInt(fillStyle.substr(5, 2), 16); + a = fillStyle.length > 7 && parseInt(fillStyle.substr(7, 2), 16) || 1; + } else if (fillStyle.startsWith('rgba')) { + ([r, g, b, a] = fillStyle.substring(5, fillStyle.length - 1).split(',').map(e => parseFloat(e))); + } else { + throw new Error(`Unexpected fillStyle color format "${fillStyle}" when drawing pattern glyph`); + } + for (let y = 0; y < height; y++) { for (let x = 0; x < width; x++) { imageData.data[(y * width + x) * 4 ] = r; imageData.data[(y * width + x) * 4 + 1] = g; imageData.data[(y * width + x) * 4 + 2] = b; - imageData.data[(y * width + x) * 4 + 3] = charDefinition[y][x] * (a ?? 255); + imageData.data[(y * width + x) * 4 + 3] = charDefinition[y][x] * (a * 255); } } tmpCtx.putImageData(imageData, 0, 0);