From 74483fb2948bbfcb42e6d22b6a3f764144195c95 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sat, 31 Dec 2016 15:56:53 -0800 Subject: [PATCH] Use CharMeasure in Viewport and to style wide chars Fixes #439 --- src/Viewport.ts | 25 ++++++++++++------------- src/xterm.css | 4 ++++ src/xterm.js | 18 +++++++++++++----- 3 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/Viewport.ts b/src/Viewport.ts index 3aa1319f..013ae65a 100644 --- a/src/Viewport.ts +++ b/src/Viewport.ts @@ -3,6 +3,7 @@ */ import { ITerminal } from './Interfaces'; +import { CharMeasure } from './utils/CharMeasure'; /** * Represents the viewport of a terminal, the visible area within the larger buffer of output. @@ -24,7 +25,7 @@ export class Viewport { private terminal: ITerminal, private viewportElement: HTMLElement, private scrollArea: HTMLElement, - private charMeasureElement: HTMLElement + private charMeasure: CharMeasure ) { this.currentRowHeight = 0; this.lastRecordedBufferLength = 0; @@ -43,21 +44,20 @@ export class Viewport { * @param charSize A character size measurement bounding rect object, if it doesn't exist it will * be created. */ - private refresh(charSize?: ClientRect): void { - var size = charSize || this.charMeasureElement.getBoundingClientRect(); - if (size.height > 0) { - var rowHeightChanged = size.height !== this.currentRowHeight; + private refresh(): void { + if (this.charMeasure.height > 0) { + var rowHeightChanged = this.charMeasure.height !== this.currentRowHeight; if (rowHeightChanged) { - this.currentRowHeight = size.height; - this.viewportElement.style.lineHeight = size.height + 'px'; - this.terminal.rowContainer.style.lineHeight = size.height + 'px'; + this.currentRowHeight = this.charMeasure.height; + this.viewportElement.style.lineHeight = this.charMeasure.height + 'px'; + this.terminal.rowContainer.style.lineHeight = this.charMeasure.height + 'px'; } var viewportHeightChanged = this.lastRecordedViewportHeight !== this.terminal.rows; if (rowHeightChanged || viewportHeightChanged) { this.lastRecordedViewportHeight = this.terminal.rows; - this.viewportElement.style.height = size.height * this.terminal.rows + 'px'; + this.viewportElement.style.height = this.charMeasure.height * this.terminal.rows + 'px'; } - this.scrollArea.style.height = (size.height * this.lastRecordedBufferLength) + 'px'; + this.scrollArea.style.height = (this.charMeasure.height * this.lastRecordedBufferLength) + 'px'; } } @@ -74,9 +74,8 @@ export class Viewport { this.refresh(); } else { // If size has changed, refresh viewport - var size = this.charMeasureElement.getBoundingClientRect(); - if (size.height !== this.currentRowHeight) { - this.refresh(size); + if (this.charMeasure.height !== this.currentRowHeight) { + this.refresh(); } } diff --git a/src/xterm.css b/src/xterm.css index 4877f86e..3f4f4bbe 100644 --- a/src/xterm.css +++ b/src/xterm.css @@ -116,6 +116,10 @@ overflow-y: scroll; } +.terminal .xterm-wide-char { + display: inline-block; +} + .terminal .xterm-rows { position: absolute; left: 0; diff --git a/src/xterm.js b/src/xterm.js index 826531e2..999dc08b 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -574,10 +574,8 @@ Terminal.prototype.open = function(parent) { this.compositionHelper = new CompositionHelper(this.textarea, this.compositionView, this); this.helperContainer.appendChild(this.compositionView); - this.charMeasureElement = document.createElement('div'); - this.charMeasureElement.classList.add('xterm-char-measure-element'); - this.charMeasureElement.innerHTML = 'W'; - this.helperContainer.appendChild(this.charMeasureElement); + this.charSizeStyleElement = document.createElement('style'); + this.helperContainer.appendChild(this.charSizeStyleElement); for (; i < this.rows; i++) { this.insertRow(); @@ -585,9 +583,12 @@ Terminal.prototype.open = function(parent) { this.parent.appendChild(this.element); this.charMeasure = new CharMeasure(this.rowContainer); + this.charMeasure.on('charsizechanged', function () { + self.updateCharSizeCSS(); + }); this.charMeasure.measure(); - this.viewport = new Viewport(this, this.viewportElement, this.viewportScrollArea, this.charMeasureElement); + this.viewport = new Viewport(this, this.viewportElement, this.viewportScrollArea, this.charMeasure); // Draw the screen. this.refresh(0, this.rows - 1); @@ -645,6 +646,13 @@ Terminal.loadAddon = function(addon, callback) { } }; +/** + * Updates the helper CSS class with any changes necessary after the terminal's + * character width has been changed. + */ +Terminal.prototype.updateCharSizeCSS = function() { + this.charSizeStyleElement.textContent = '.xterm-wide-char{width:' + (this.charMeasure.width * 2) + 'px;}'; +} /** * XTerm mouse events