UNPKG

lazy-widgets

Version:

Typescript retained mode GUI for the HTML canvas API

60 lines 2.78 kB
import { Msg } from '../core/Strings.js'; import { AsyncImageBitmap } from './AsyncImageBitmap.js'; import { measureTextDims } from './measureTextDims.js'; /** * Renders text as an ImageBitmap, which can then be used in widgets that * consume a {@link BackingMediaSource}, like {@link Icon}. Useful for using * font icons instead of images. * * Height is retreived by measuring the fontBoundingBoxAscent and * fontBoundingBoxDescent (falling back to actualBoundingBoxAscent and * actualBoundingBoxDescent), as well as the hangingBaseline (falling back to * the actualBoundingBoxAscent of the `M` character). Width is measured from the * text being rendered, however, it's set to be the same as the height if it's * smaller than the height to avoid issues with thin font icons (such as * vertical ellipsis). The font is assumed to already be loaded by the time this * class is instantiated. * * Throws if a scratch canvas can't be created. */ export class TextImageBitmap extends AsyncImageBitmap { constructor(text, font, fillStyle, options) { var _a, _b, _c, _d; super(); this.text = text; this.font = font; this.fillStyle = fillStyle; this._bitmap = null; this._presentationHash = -1; const metrics = measureTextDims(text, font); const ascent = (_a = metrics.fontBoundingBoxAscent) !== null && _a !== void 0 ? _a : metrics.actualBoundingBoxAscent; const descent = (_b = metrics.fontBoundingBoxDescent) !== null && _b !== void 0 ? _b : metrics.actualBoundingBoxDescent; const hangingBaseline = (_c = metrics.hangingBaseline) !== null && _c !== void 0 ? _c : measureTextDims('M', font).actualBoundingBoxAscent; const pad = Math.max(ascent - hangingBaseline, descent); this.height = hangingBaseline + pad * 2; this.width = Math.max(metrics.width, this.height); this.resolution = (_d = options === null || options === void 0 ? void 0 : options.resolution) !== null && _d !== void 0 ? _d : 1; const canvas = document.createElement('canvas'); canvas.width = this.width; canvas.height = this.height; const context = canvas.getContext('2d'); if (!context) { throw new Error(Msg.CANVAS_CONTEXT); } context.textAlign = 'center'; context.font = font; context.fillStyle = fillStyle; context.fillText(text, this.width * 0.5, this.height - pad); createImageBitmap(canvas).then((bitmap) => { this._presentationHash++; this._bitmap = bitmap; }); } get bitmap() { return this._bitmap; } get presentationHash() { return this._presentationHash; } } //# sourceMappingURL=TextImageBitmap.js.map