diff --git a/src/utils/CharMeasure.ts b/src/utils/CharMeasure.ts new file mode 100644 index 00000000..60684a2c --- /dev/null +++ b/src/utils/CharMeasure.ts @@ -0,0 +1,52 @@ +/** + * @module xterm/utils/CharMeasure + * @license MIT + */ + +import { EventEmitter } from '../EventEmitter.js'; + +/** + * Utility class that measures the size of a character. + */ +export class CharMeasure extends EventEmitter { + private _parentElement: HTMLElement; + private _measureElement: HTMLElement; + private _width: number; + private _height: number; + + constructor(parentElement: HTMLElement) { + super(); + this._parentElement = parentElement; + } + + public get width(): number { + return this._width; + } + + public get height(): number { + return this._height; + } + + public measure(): void { + const oldWidth = this._width; + const oldHeight = this._height; + + if (!this._measureElement) { + this._measureElement = document.createElement('span'); + this._measureElement.style.position = 'absolute'; + this._measureElement.style.top = '0'; + this._measureElement.style.left = '-9999em'; + this._measureElement.textContent = 'W'; + } + + this._parentElement.appendChild(this._measureElement); + const geometry = this._measureElement.getBoundingClientRect(); + this._width = geometry.width; + this._height = geometry.height; + this._parentElement.removeChild(this._measureElement); + + if (this._width !== oldWidth || this._height !== oldHeight) { + this.emit('charsizechanged'); + } + } +} diff --git a/src/xterm.js b/src/xterm.js index fcb60bf5..826531e2 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -15,6 +15,7 @@ import { EventEmitter } from './EventEmitter.js'; import { Viewport } from './Viewport.js'; import { rightClickHandler, pasteHandler, copyHandler } from './handlers/Clipboard.js'; import { CircularList } from './utils/CircularList.js'; +import { CharMeasure } from './utils/CharMeasure.js'; import * as Browser from './utils/Browser'; import * as Keyboard from './utils/Keyboard'; @@ -583,6 +584,9 @@ Terminal.prototype.open = function(parent) { } this.parent.appendChild(this.element); + this.charMeasure = new CharMeasure(this.rowContainer); + this.charMeasure.measure(); + this.viewport = new Viewport(this, this.viewportElement, this.viewportScrollArea, this.charMeasureElement); // Draw the screen. @@ -2951,6 +2955,8 @@ Terminal.prototype.resize = function(x, y) { this.scrollTop = 0; this.scrollBottom = y - 1; + this.charMeasure.measure(); + this.refresh(0, this.rows - 1); this.normal = null;