pixi.js
Version:
<p align="center"> <a href="https://pixijs.com" target="_blank" rel="noopener noreferrer"> <img height="150" src="https://files.pixijs.download/branding/pixijs-logo-transparent-dark.svg?v=1" alt="PixiJS logo"> </a> </p> <br/> <p align="center">
164 lines (160 loc) • 6.05 kB
JavaScript
;
var Extensions = require('../../extensions/Extensions.js');
var CanvasPool = require('../../rendering/renderers/shared/texture/CanvasPool.js');
var TexturePool = require('../../rendering/renderers/shared/texture/TexturePool.js');
var types = require('../../rendering/renderers/types.js');
var isSafari = require('../../utils/browser/isSafari.js');
var warn = require('../../utils/logging/warn.js');
var PoolGroup = require('../../utils/pool/PoolGroup.js');
var getPo2TextureFromSource = require('../text/utils/getPo2TextureFromSource.js');
var HTMLTextRenderData = require('./HTMLTextRenderData.js');
var extractFontFamilies = require('./utils/extractFontFamilies.js');
var getFontCss = require('./utils/getFontCss.js');
var getSVGUrl = require('./utils/getSVGUrl.js');
var getTemporaryCanvasFromImage = require('./utils/getTemporaryCanvasFromImage.js');
var loadSVGImage = require('./utils/loadSVGImage.js');
var measureHtmlText = require('./utils/measureHtmlText.js');
;
class HTMLTextSystem {
constructor(renderer) {
this._activeTextures = {};
this._renderer = renderer;
this._createCanvas = renderer.type === types.RendererType.WEBGPU;
}
/**
* @param options
* @deprecated Use getTexturePromise instead
*/
getTexture(options) {
return this.getTexturePromise(options);
}
/**
* Increases the reference count for a texture.
* @param text - The HTMLText instance associated with the texture.
*/
getManagedTexture(text) {
const textKey = text.styleKey;
if (this._activeTextures[textKey]) {
this._increaseReferenceCount(textKey);
return this._activeTextures[textKey].promise;
}
const promise = this._buildTexturePromise(text).then((texture) => {
this._activeTextures[textKey].texture = texture;
return texture;
});
this._activeTextures[textKey] = {
texture: null,
promise,
usageCount: 1
};
return promise;
}
/**
* Gets the current reference count for a texture associated with a text key.
* @param textKey - The unique key identifying the text style configuration
* @returns The number of Text instances currently using this texture
*/
getReferenceCount(textKey) {
return this._activeTextures[textKey]?.usageCount ?? null;
}
_increaseReferenceCount(textKey) {
this._activeTextures[textKey].usageCount++;
}
/**
* Decreases the reference count for a texture.
* If the count reaches zero, the texture is cleaned up.
* @param textKey - The key associated with the HTMLText instance.
*/
decreaseReferenceCount(textKey) {
const activeTexture = this._activeTextures[textKey];
if (!activeTexture)
return;
activeTexture.usageCount--;
if (activeTexture.usageCount === 0) {
if (activeTexture.texture) {
this._cleanUp(activeTexture.texture);
} else {
activeTexture.promise.then((texture) => {
activeTexture.texture = texture;
this._cleanUp(activeTexture.texture);
}).catch(() => {
warn.warn("HTMLTextSystem: Failed to clean texture");
});
}
this._activeTextures[textKey] = null;
}
}
/**
* Returns a promise that resolves to a texture for the given HTMLText options.
* @param options - The options for the HTMLText.
* @returns A promise that resolves to a Texture.
*/
getTexturePromise(options) {
return this._buildTexturePromise(options);
}
async _buildTexturePromise(options) {
const { text, style, resolution, textureStyle } = options;
const htmlTextData = PoolGroup.BigPool.get(HTMLTextRenderData.HTMLTextRenderData);
const fontFamilies = extractFontFamilies.extractFontFamilies(text, style);
const fontCSS = await getFontCss.getFontCss(fontFamilies);
const measured = measureHtmlText.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.getSVGUrl(text, style, resolution, fontCSS, htmlTextData);
await loadSVGImage.loadSVGImage(image, svgURL, isSafari.isSafari() && fontFamilies.length > 0);
const resource = image;
let canvasAndContext;
if (this._createCanvas) {
canvasAndContext = getTemporaryCanvasFromImage.getTemporaryCanvasFromImage(image, resolution);
}
const texture = getPo2TextureFromSource.getPo2TextureFromSource(
canvasAndContext ? canvasAndContext.canvas : resource,
image.width - uvSafeOffset,
image.height - uvSafeOffset,
resolution
);
if (textureStyle)
texture.source.style = textureStyle;
if (this._createCanvas) {
this._renderer.texture.initSource(texture.source);
CanvasPool.CanvasPool.returnCanvasAndContext(canvasAndContext);
}
PoolGroup.BigPool.return(htmlTextData);
return texture;
}
returnTexturePromise(texturePromise) {
texturePromise.then((texture) => {
this._cleanUp(texture);
}).catch(() => {
warn.warn("HTMLTextSystem: Failed to clean texture");
});
}
_cleanUp(texture) {
TexturePool.TexturePool.returnTexture(texture, true);
texture.source.resource = null;
texture.source.uploadMethodId = "unknown";
}
destroy() {
this._renderer = null;
for (const key in this._activeTextures) {
if (this._activeTextures[key])
this.returnTexturePromise(this._activeTextures[key].promise);
}
this._activeTextures = null;
}
}
/** @ignore */
HTMLTextSystem.extension = {
type: [
Extensions.ExtensionType.WebGLSystem,
Extensions.ExtensionType.WebGPUSystem,
Extensions.ExtensionType.CanvasSystem
],
name: "htmlText"
};
exports.HTMLTextSystem = HTMLTextSystem;
//# sourceMappingURL=HTMLTextSystem.js.map