Support detailed ligatures and variants

Fixes #5284
This commit is contained in:
Daniel Imms
2025-01-08 06:26:15 -08:00
parent 9e206415b8
commit 408d0995dd
7 changed files with 77 additions and 32 deletions
+18 -8
View File
@@ -103,6 +103,7 @@ export class TextureAtlas implements ITextureAtlas {
}
public dispose(): void {
this._tmpCanvas.remove();
for (const page of this.pages) {
page.canvas.remove();
}
@@ -122,7 +123,7 @@ export class TextureAtlas implements ITextureAtlas {
for (let i = 33; i < 126; i++) {
queue.enqueue(() => {
if (!this._cacheMap.get(i, DEFAULT_COLOR, DEFAULT_COLOR, DEFAULT_EXT)) {
const rasterizedGlyph = this._drawToCache(i, DEFAULT_COLOR, DEFAULT_COLOR, DEFAULT_EXT);
const rasterizedGlyph = this._drawToCache(i, DEFAULT_COLOR, DEFAULT_COLOR, DEFAULT_EXT, false, undefined);
this._cacheMap.set(i, DEFAULT_COLOR, DEFAULT_COLOR, DEFAULT_EXT, rasterizedGlyph);
}
});
@@ -242,12 +243,12 @@ export class TextureAtlas implements ITextureAtlas {
}
}
public getRasterizedGlyphCombinedChar(chars: string, bg: number, fg: number, ext: number, restrictToCellHeight: boolean): IRasterizedGlyph {
return this._getFromCacheMap(this._cacheMapCombined, chars, bg, fg, ext, restrictToCellHeight);
public getRasterizedGlyphCombinedChar(chars: string, bg: number, fg: number, ext: number, restrictToCellHeight: boolean, domContainer: HTMLElement | undefined): IRasterizedGlyph {
return this._getFromCacheMap(this._cacheMapCombined, chars, bg, fg, ext, restrictToCellHeight, domContainer);
}
public getRasterizedGlyph(code: number, bg: number, fg: number, ext: number, restrictToCellHeight: boolean): IRasterizedGlyph {
return this._getFromCacheMap(this._cacheMap, code, bg, fg, ext, restrictToCellHeight);
public getRasterizedGlyph(code: number, bg: number, fg: number, ext: number, restrictToCellHeight: boolean, domContainer: HTMLElement | undefined): IRasterizedGlyph {
return this._getFromCacheMap(this._cacheMap, code, bg, fg, ext, restrictToCellHeight, domContainer);
}
/**
@@ -259,11 +260,12 @@ export class TextureAtlas implements ITextureAtlas {
bg: number,
fg: number,
ext: number,
restrictToCellHeight: boolean = false
restrictToCellHeight: boolean,
domContainer: HTMLElement | undefined
): IRasterizedGlyph {
$glyph = cacheMap.get(key, bg, fg, ext);
if (!$glyph) {
$glyph = this._drawToCache(key, bg, fg, ext, restrictToCellHeight);
$glyph = this._drawToCache(key, bg, fg, ext, restrictToCellHeight, domContainer);
cacheMap.set(key, bg, fg, ext, $glyph);
}
return $glyph;
@@ -423,12 +425,20 @@ export class TextureAtlas implements ITextureAtlas {
return this._config.colors.contrastCache;
}
private _drawToCache(codeOrChars: number | string, bg: number, fg: number, ext: number, restrictToCellHeight: boolean = false): IRasterizedGlyph {
private _drawToCache(codeOrChars: number | string, bg: number, fg: number, ext: number, restrictToCellHeight: boolean, domContainer: HTMLElement | undefined): IRasterizedGlyph {
const chars = typeof codeOrChars === 'number' ? String.fromCharCode(codeOrChars) : codeOrChars;
// Uncomment for debugging
// console.log(`draw to cache "${chars}"`, bg, fg, ext);
// Attach the canvas to the DOM in order to inherit font-feature-settings
// from the parent elements. This is necessary for ligatures and variants to
// work.
if (domContainer && this._tmpCanvas.parentElement !== domContainer) {
this._tmpCanvas.style.display = 'none';
domContainer.append(this._tmpCanvas);
}
// Allow 1 cell width per character, with a minimum of 2 (CJK), plus some padding. This is used
// to draw the glyph to the canvas as well as to restrict the bounding box search to ensure
// giant ligatures (eg. =====>) don't impact overall performance.
+2 -2
View File
@@ -108,8 +108,8 @@ export interface ITextureAtlas extends IDisposable {
* Clear all glyphs from the texture atlas.
*/
clearTexture(): void;
getRasterizedGlyph(code: number, bg: number, fg: number, ext: number, restrictToCellHeight: boolean): IRasterizedGlyph;
getRasterizedGlyphCombinedChar(chars: string, bg: number, fg: number, ext: number, restrictToCellHeight: boolean): IRasterizedGlyph;
getRasterizedGlyph(code: number, bg: number, fg: number, ext: number, restrictToCellHeight: boolean, domContainer: HTMLElement | undefined): IRasterizedGlyph;
getRasterizedGlyphCombinedChar(chars: string, bg: number, fg: number, ext: number, restrictToCellHeight: boolean, domContainer: HTMLElement | undefined): IRasterizedGlyph;
}
/**