Skip to content

Commit 70bbd12

Browse files
split extremely wide ligatures to fit atlas
1 parent 377f887 commit 70bbd12

File tree

4 files changed

+198
-167
lines changed

4 files changed

+198
-167
lines changed

addons/xterm-addon-canvas/src/BaseRenderLayer.ts

Lines changed: 32 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -368,37 +368,43 @@ export abstract class BaseRenderLayer extends Disposable implements IRenderLayer
368368
protected _drawChars(cell: ICellData, x: number, y: number): void {
369369
const chars = cell.getChars();
370370
this._cellColorResolver.resolve(cell, x, this._bufferService.buffer.ydisp + y);
371-
let glyph: IRasterizedGlyph;
371+
let glyphs: IRasterizedGlyph[];
372372
if (chars && chars.length > 1) {
373-
glyph = this._charAtlas.getRasterizedGlyphCombinedChar(chars, this._cellColorResolver.result.bg, this._cellColorResolver.result.fg, this._cellColorResolver.result.ext);
373+
glyphs = this._charAtlas.getRasterizedGlyphCombinedChar(chars, this._cellColorResolver.result.bg, this._cellColorResolver.result.fg, this._cellColorResolver.result.ext);
374374
} else {
375-
glyph = this._charAtlas.getRasterizedGlyph(cell.getCode() || WHITESPACE_CELL_CODE, this._cellColorResolver.result.bg, this._cellColorResolver.result.fg, this._cellColorResolver.result.ext);
375+
glyphs = this._charAtlas.getRasterizedGlyph(cell.getCode() || WHITESPACE_CELL_CODE, this._cellColorResolver.result.bg, this._cellColorResolver.result.fg, this._cellColorResolver.result.ext);
376376
}
377-
if (!glyph.size.x || !glyph.size.y) {
378-
return;
379-
}
380-
this._ctx.save();
381-
this._clipRow(y);
382-
// Draw the image, use the bitmap if it's available
383-
if (this._charAtlas.pages[glyph.texturePage].version !== this._bitmapGenerator[glyph.texturePage]?.version) {
384-
if (!this._bitmapGenerator[glyph.texturePage]) {
385-
this._bitmapGenerator[glyph.texturePage] = new BitmapGenerator(this._charAtlas.pages[glyph.texturePage].canvas);
377+
378+
let glyphsOffsetX = 0;
379+
for (let i = 0; i < glyphs.length; i++) {
380+
const glyph = glyphs[i];
381+
if (!glyph.size.x || !glyph.size.y) {
382+
continue;
386383
}
387-
this._bitmapGenerator[glyph.texturePage]!.refresh();
388-
this._bitmapGenerator[glyph.texturePage]!.version = this._charAtlas.pages[glyph.texturePage].version;
384+
this._ctx.save();
385+
this._clipRow(y);
386+
// Draw the image, use the bitmap if it's available
387+
if (this._charAtlas.pages[glyph.texturePage].version !== this._bitmapGenerator[glyph.texturePage]?.version) {
388+
if (!this._bitmapGenerator[glyph.texturePage]) {
389+
this._bitmapGenerator[glyph.texturePage] = new BitmapGenerator(this._charAtlas.pages[glyph.texturePage].canvas);
390+
}
391+
this._bitmapGenerator[glyph.texturePage]!.refresh();
392+
this._bitmapGenerator[glyph.texturePage]!.version = this._charAtlas.pages[glyph.texturePage].version;
393+
}
394+
this._ctx.drawImage(
395+
this._bitmapGenerator[glyph.texturePage]?.bitmap || this._charAtlas!.pages[glyph.texturePage].canvas,
396+
glyph.texturePosition.x,
397+
glyph.texturePosition.y,
398+
glyph.size.x,
399+
glyph.size.y,
400+
x * this._deviceCellWidth + this._deviceCharLeft - glyph.offset.x + glyphsOffsetX,
401+
y * this._deviceCellHeight + this._deviceCharTop - glyph.offset.y,
402+
glyph.size.x,
403+
glyph.size.y
404+
);
405+
glyphsOffsetX += glyph.size.x;
406+
this._ctx.restore();
389407
}
390-
this._ctx.drawImage(
391-
this._bitmapGenerator[glyph.texturePage]?.bitmap || this._charAtlas!.pages[glyph.texturePage].canvas,
392-
glyph.texturePosition.x,
393-
glyph.texturePosition.y,
394-
glyph.size.x,
395-
glyph.size.y,
396-
x * this._deviceCellWidth + this._deviceCharLeft - glyph.offset.x,
397-
y * this._deviceCellHeight + this._deviceCharTop - glyph.offset.y,
398-
glyph.size.x,
399-
glyph.size.y
400-
);
401-
this._ctx.restore();
402408
}
403409

404410
/**

addons/xterm-addon-webgl/src/GlyphRenderer.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ const CELL_POSITION_INDICES = 2;
8585
// Work variables to avoid garbage collection
8686
let $i = 0;
8787
let $glyph: IRasterizedGlyph | undefined = undefined;
88+
let $glyphs: IRasterizedGlyph[] | undefined = undefined;
8889
let $leftCellPadding = 0;
8990
let $clippedPixels = 0;
9091

@@ -236,10 +237,11 @@ export class GlyphRenderer extends Disposable {
236237

237238
// Get the glyph
238239
if (chars && chars.length > 1) {
239-
$glyph = this._atlas.getRasterizedGlyphCombinedChar(chars, bg, fg, ext);
240+
$glyphs = this._atlas.getRasterizedGlyphCombinedChar(chars, bg, fg, ext);
240241
} else {
241-
$glyph = this._atlas.getRasterizedGlyph(code, bg, fg, ext);
242+
$glyphs = this._atlas.getRasterizedGlyph(code, bg, fg, ext);
242243
}
244+
$glyph = $glyphs[0];
243245

244246
$leftCellPadding = Math.floor((this._dimensions.device.cell.width - this._dimensions.device.char.width) / 2);
245247
if (bg !== lastBg && $glyph.offset.x > $leftCellPadding) {

0 commit comments

Comments
 (0)