131 lines
4.4 KiB
JavaScript
131 lines
4.4 KiB
JavaScript
import { ExtensionType } from '../../extensions/Extensions.mjs';
|
|
import { TexturePool } from '../../rendering/renderers/shared/texture/TexturePool.mjs';
|
|
import { RendererType } from '../../rendering/renderers/types.mjs';
|
|
import { isSafari } from '../../utils/browser/isSafari.mjs';
|
|
import { warn } from '../../utils/logging/warn.mjs';
|
|
import { BigPool } from '../../utils/pool/PoolGroup.mjs';
|
|
import { getPo2TextureFromSource } from '../text/utils/getPo2TextureFromSource.mjs';
|
|
import { HTMLTextRenderData } from './HTMLTextRenderData.mjs';
|
|
import { HTMLTextStyle } from './HtmlTextStyle.mjs';
|
|
import { extractFontFamilies } from './utils/extractFontFamilies.mjs';
|
|
import { getFontCss } from './utils/getFontCss.mjs';
|
|
import { getSVGUrl } from './utils/getSVGUrl.mjs';
|
|
import { getTemporaryCanvasFromImage } from './utils/getTemporaryCanvasFromImage.mjs';
|
|
import { loadSVGImage } from './utils/loadSVGImage.mjs';
|
|
import { measureHtmlText } from './utils/measureHtmlText.mjs';
|
|
|
|
"use strict";
|
|
class HTMLTextSystem {
|
|
constructor(renderer) {
|
|
this._activeTextures = {};
|
|
this._renderer = renderer;
|
|
this._createCanvas = renderer.type === RendererType.WEBGPU;
|
|
}
|
|
getTexture(options) {
|
|
return this._buildTexturePromise(
|
|
options.text,
|
|
options.resolution,
|
|
options.style
|
|
);
|
|
}
|
|
getManagedTexture(text, resolution, style, textKey) {
|
|
if (this._activeTextures[textKey]) {
|
|
this._increaseReferenceCount(textKey);
|
|
return this._activeTextures[textKey].promise;
|
|
}
|
|
const promise = this._buildTexturePromise(text, resolution, style).then((texture) => {
|
|
this._activeTextures[textKey].texture = texture;
|
|
return texture;
|
|
});
|
|
this._activeTextures[textKey] = {
|
|
texture: null,
|
|
promise,
|
|
usageCount: 1
|
|
};
|
|
return promise;
|
|
}
|
|
async _buildTexturePromise(text, resolution, style) {
|
|
const htmlTextData = BigPool.get(HTMLTextRenderData);
|
|
const fontFamilies = extractFontFamilies(text, style);
|
|
const fontCSS = await getFontCss(
|
|
fontFamilies,
|
|
style,
|
|
HTMLTextStyle.defaultTextStyle
|
|
);
|
|
const measured = measureHtmlText(text, style, fontCSS, htmlTextData);
|
|
const width = Math.ceil(Math.ceil(Math.max(1, measured.width) + style.padding * 2) * resolution);
|
|
const height = Math.ceil(Math.ceil(Math.max(1, measured.height) + style.padding * 2) * resolution);
|
|
const image = htmlTextData.image;
|
|
const uvSafeOffset = 2;
|
|
image.width = (width | 0) + uvSafeOffset;
|
|
image.height = (height | 0) + uvSafeOffset;
|
|
const svgURL = getSVGUrl(text, style, resolution, fontCSS, htmlTextData);
|
|
await loadSVGImage(image, svgURL, isSafari() && fontFamilies.length > 0);
|
|
let resource = image;
|
|
if (this._createCanvas) {
|
|
resource = getTemporaryCanvasFromImage(image, resolution);
|
|
}
|
|
const texture = getPo2TextureFromSource(
|
|
resource,
|
|
image.width - uvSafeOffset,
|
|
image.height - uvSafeOffset,
|
|
resolution
|
|
);
|
|
if (this._createCanvas) {
|
|
this._renderer.texture.initSource(texture.source);
|
|
}
|
|
BigPool.return(htmlTextData);
|
|
return texture;
|
|
}
|
|
_increaseReferenceCount(textKey) {
|
|
this._activeTextures[textKey].usageCount++;
|
|
}
|
|
decreaseReferenceCount(textKey) {
|
|
const activeTexture = this._activeTextures[textKey];
|
|
if (!activeTexture)
|
|
return;
|
|
activeTexture.usageCount--;
|
|
if (activeTexture.usageCount === 0) {
|
|
if (activeTexture.texture) {
|
|
this._cleanUp(activeTexture);
|
|
} else {
|
|
activeTexture.promise.then((texture) => {
|
|
activeTexture.texture = texture;
|
|
this._cleanUp(activeTexture);
|
|
}).catch(() => {
|
|
warn("HTMLTextSystem: Failed to clean texture");
|
|
});
|
|
}
|
|
this._activeTextures[textKey] = null;
|
|
}
|
|
}
|
|
_cleanUp(activeTexture) {
|
|
TexturePool.returnTexture(activeTexture.texture);
|
|
activeTexture.texture.source.resource = null;
|
|
activeTexture.texture.source.uploadMethodId = "unknown";
|
|
}
|
|
getReferenceCount(textKey) {
|
|
return this._activeTextures[textKey].usageCount;
|
|
}
|
|
destroy() {
|
|
this._activeTextures = null;
|
|
}
|
|
}
|
|
/** @ignore */
|
|
HTMLTextSystem.extension = {
|
|
type: [
|
|
ExtensionType.WebGLSystem,
|
|
ExtensionType.WebGPUSystem,
|
|
ExtensionType.CanvasSystem
|
|
],
|
|
name: "htmlText"
|
|
};
|
|
HTMLTextSystem.defaultFontOptions = {
|
|
fontFamily: "Arial",
|
|
fontStyle: "normal",
|
|
fontWeight: "normal"
|
|
};
|
|
|
|
export { HTMLTextSystem };
|
|
//# sourceMappingURL=HTMLTextSystem.mjs.map
|