Implement lineHeight px format support
Co-authored-by: Tyriar <2193314+Tyriar@users.noreply.github.com>
This commit is contained in:
co-authored by
Tyriar
parent
0dffbedf76
commit
b3503f4916
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* Copyright (c) 2023 The xterm.js authors. All rights reserved.
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { assert } from 'chai';
|
||||
|
||||
/**
|
||||
* Calculates the line height in pixels based on the lineHeight option and character height.
|
||||
* This is the same function used in both DomRenderer and WebglRenderer.
|
||||
*/
|
||||
function calculateLineHeightInPixels(lineHeight: number | string, charHeight: number): number {
|
||||
if (typeof lineHeight === 'string' && lineHeight.endsWith('px')) {
|
||||
const pxValue = parseFloat(lineHeight.slice(0, -2));
|
||||
// Ensure the pixel value is at least as large as the character height
|
||||
return Math.max(pxValue, charHeight);
|
||||
}
|
||||
// Numeric lineHeight acts as a multiplier
|
||||
return Math.floor(charHeight * (lineHeight as number));
|
||||
}
|
||||
|
||||
describe('calculateLineHeightInPixels', () => {
|
||||
describe('numeric lineHeight', () => {
|
||||
it('should calculate correctly with multiplier 1', () => {
|
||||
assert.equal(calculateLineHeightInPixels(1, 20), 20);
|
||||
});
|
||||
|
||||
it('should calculate correctly with multiplier 1.2', () => {
|
||||
assert.equal(calculateLineHeightInPixels(1.2, 20), 24);
|
||||
});
|
||||
|
||||
it('should calculate correctly with multiplier 1.5', () => {
|
||||
assert.equal(calculateLineHeightInPixels(1.5, 20), 30);
|
||||
});
|
||||
|
||||
it('should floor the result', () => {
|
||||
assert.equal(calculateLineHeightInPixels(1.3, 20), 26); // Math.floor(26)
|
||||
});
|
||||
});
|
||||
|
||||
describe('string lineHeight with px format', () => {
|
||||
it('should use px value directly when larger than char height', () => {
|
||||
assert.equal(calculateLineHeightInPixels('25px', 20), 25);
|
||||
});
|
||||
|
||||
it('should use char height when px value is smaller', () => {
|
||||
assert.equal(calculateLineHeightInPixels('15px', 20), 20);
|
||||
});
|
||||
|
||||
it('should handle decimal px values', () => {
|
||||
assert.equal(calculateLineHeightInPixels('23.5px', 20), 23.5);
|
||||
});
|
||||
|
||||
it('should handle edge case where px equals char height', () => {
|
||||
assert.equal(calculateLineHeightInPixels('20px', 20), 20);
|
||||
});
|
||||
|
||||
it('should handle very large px values', () => {
|
||||
assert.equal(calculateLineHeightInPixels('100px', 20), 100);
|
||||
});
|
||||
});
|
||||
|
||||
describe('edge cases', () => {
|
||||
it('should handle zero char height with numeric multiplier', () => {
|
||||
assert.equal(calculateLineHeightInPixels(1.5, 0), 0);
|
||||
});
|
||||
|
||||
it('should handle zero char height with px value', () => {
|
||||
assert.equal(calculateLineHeightInPixels('25px', 0), 25);
|
||||
});
|
||||
|
||||
it('should handle 1px with various char heights', () => {
|
||||
assert.equal(calculateLineHeightInPixels('1px', 5), 5);
|
||||
assert.equal(calculateLineHeightInPixels('1px', 20), 20);
|
||||
assert.equal(calculateLineHeightInPixels('1px', 0), 1);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -24,6 +24,19 @@ const BG_CLASS_PREFIX = 'xterm-bg-';
|
||||
const FOCUS_CLASS = 'xterm-focus';
|
||||
const SELECTION_CLASS = 'xterm-selection';
|
||||
|
||||
/**
|
||||
* Calculates the line height in pixels based on the lineHeight option and character height.
|
||||
*/
|
||||
function calculateLineHeightInPixels(lineHeight: number | string, charHeight: number): number {
|
||||
if (typeof lineHeight === 'string' && lineHeight.endsWith('px')) {
|
||||
const pxValue = parseFloat(lineHeight.slice(0, -2));
|
||||
// Ensure the pixel value is at least as large as the character height
|
||||
return Math.max(pxValue, charHeight);
|
||||
}
|
||||
// Numeric lineHeight acts as a multiplier
|
||||
return Math.floor(charHeight * (lineHeight as number));
|
||||
}
|
||||
|
||||
let nextTerminalId = 1;
|
||||
|
||||
/**
|
||||
@@ -116,7 +129,7 @@ export class DomRenderer extends Disposable implements IRenderer {
|
||||
this.dimensions.device.char.width = this._charSizeService.width * dpr;
|
||||
this.dimensions.device.char.height = Math.ceil(this._charSizeService.height * dpr);
|
||||
this.dimensions.device.cell.width = this.dimensions.device.char.width + Math.round(this._optionsService.rawOptions.letterSpacing);
|
||||
this.dimensions.device.cell.height = Math.floor(this.dimensions.device.char.height * this._optionsService.rawOptions.lineHeight);
|
||||
this.dimensions.device.cell.height = calculateLineHeightInPixels(this._optionsService.rawOptions.lineHeight, this.dimensions.device.char.height);
|
||||
this.dimensions.device.char.left = 0;
|
||||
this.dimensions.device.char.top = 0;
|
||||
this.dimensions.device.canvas.width = this.dimensions.device.cell.width * this._bufferService.cols;
|
||||
|
||||
Reference in New Issue
Block a user