This commit is contained in:
Akko
2025-08-04 18:57:35 +02:00
parent 8cf6e78a79
commit 9495868c2e
5030 changed files with 518594 additions and 17609 deletions

61
node_modules/pixi.js/lib/scene/text-html/HTMLText.d.ts generated vendored Normal file
View File

@@ -0,0 +1,61 @@
import { AbstractText } from '../text/AbstractText';
import { HTMLTextStyle } from './HtmlTextStyle';
import type { View } from '../../rendering/renderers/shared/view/View';
import type { TextOptions, TextString } from '../text/AbstractText';
import type { HTMLTextStyleOptions } from './HtmlTextStyle';
/**
* Constructor options used for `HTMLText` instances.
* @property {string} [text=''] - The string that you would like the text to display.
* @property {text.HTMLTextStyle | text.HTMLTextStyleOptions} [style] - The style of the text.
* @memberof text
*/
export type HTMLTextOptions = TextOptions<HTMLTextStyle, HTMLTextStyleOptions>;
/**
* A HTMLText Object will create a line or multiple lines of text.
*
* To split a line you can use '\n' in your text string, or, on the `style` object,
* change its `wordWrap` property to true and and give the `wordWrapWidth` property a value.
*
* HTMLText uses an svg foreignObject to render HTML text.
*
*
* The primary advantages of this render mode are:
*
* - Supports [HTML tags](https://developer.mozilla.org/en-US/docs/Learn/HTML/Introduction_to_HTML/HTML_text_fundamentals)
* for styling such as `<strong>`, or `<em>`, as well as `<span style="">`
*
* - Better support for emojis and other HTML layout features, better compatibility with CSS
* line-height and letter-spacing.
*
*
* The primary disadvantages are:
* - Unlike `text`, `html` rendering will vary slightly between platforms and browsers.
* `html` uses SVG/DOM to render text and not Context2D's fillText like `text`.
*
* - Performance and memory usage is on-par with `text` (that is to say, slow and heavy)
*
* - Only works with browsers that support <foreignObject>.
* @example
* import { HTMLText } from 'pixi.js';
*
* const text = new HTMLText({
* text: 'Hello Pixi!',
* style: {
* fontFamily: 'Arial',
* fontSize: 24,
* fill: 0xff1010,
* align: 'center',
* }
* });
* @memberof scene
*/
export declare class HTMLText extends AbstractText<HTMLTextStyle, HTMLTextStyleOptions> implements View {
readonly renderPipeId: string;
/**
* @param {text.HTMLTextOptions} options - The options of the html text.
*/
constructor(options?: HTMLTextOptions);
/** @deprecated since 8.0.0 */
constructor(text?: TextString, options?: Partial<HTMLTextStyle>);
protected _updateBounds(): void;
}

27
node_modules/pixi.js/lib/scene/text-html/HTMLText.js generated vendored Normal file
View File

@@ -0,0 +1,27 @@
'use strict';
var AbstractText = require('../text/AbstractText.js');
var HtmlTextStyle = require('./HtmlTextStyle.js');
var measureHtmlText = require('./utils/measureHtmlText.js');
"use strict";
class HTMLText extends AbstractText.AbstractText {
constructor(...args) {
const options = AbstractText.ensureOptions(args, "HtmlText");
super(options, HtmlTextStyle.HTMLTextStyle);
this.renderPipeId = "htmlText";
}
_updateBounds() {
const bounds = this._bounds;
const anchor = this._anchor;
const htmlMeasurement = measureHtmlText.measureHtmlText(this.text, this._style);
const { width, height } = htmlMeasurement;
bounds.minX = -anchor._x * width;
bounds.maxX = bounds.minX + width;
bounds.minY = -anchor._y * height;
bounds.maxY = bounds.minY + height;
}
}
exports.HTMLText = HTMLText;
//# sourceMappingURL=HTMLText.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"HTMLText.js","sources":["../../../src/scene/text-html/HTMLText.ts"],"sourcesContent":["import { AbstractText, ensureOptions } from '../text/AbstractText';\nimport { HTMLTextStyle } from './HtmlTextStyle';\nimport { measureHtmlText } from './utils/measureHtmlText';\n\nimport type { View } from '../../rendering/renderers/shared/view/View';\nimport type { TextOptions, TextString } from '../text/AbstractText';\nimport type { HTMLTextStyleOptions } from './HtmlTextStyle';\n\n/**\n * Constructor options used for `HTMLText` instances.\n * @property {string} [text=''] - The string that you would like the text to display.\n * @property {text.HTMLTextStyle | text.HTMLTextStyleOptions} [style] - The style of the text.\n * @memberof text\n */\nexport type HTMLTextOptions = TextOptions<HTMLTextStyle, HTMLTextStyleOptions>;\n\n/**\n * A HTMLText Object will create a line or multiple lines of text.\n *\n * To split a line you can use '\\n' in your text string, or, on the `style` object,\n * change its `wordWrap` property to true and and give the `wordWrapWidth` property a value.\n *\n * HTMLText uses an svg foreignObject to render HTML text.\n *\n *\n * The primary advantages of this render mode are:\n *\n * - Supports [HTML tags](https://developer.mozilla.org/en-US/docs/Learn/HTML/Introduction_to_HTML/HTML_text_fundamentals)\n * for styling such as `<strong>`, or `<em>`, as well as `<span style=\"\">`\n *\n * - Better support for emojis and other HTML layout features, better compatibility with CSS\n * line-height and letter-spacing.\n *\n *\n * The primary disadvantages are:\n * - Unlike `text`, `html` rendering will vary slightly between platforms and browsers.\n * `html` uses SVG/DOM to render text and not Context2D's fillText like `text`.\n *\n * - Performance and memory usage is on-par with `text` (that is to say, slow and heavy)\n *\n * - Only works with browsers that support <foreignObject>.\n * @example\n * import { HTMLText } from 'pixi.js';\n *\n * const text = new HTMLText({\n * text: 'Hello Pixi!',\n * style: {\n * fontFamily: 'Arial',\n * fontSize: 24,\n * fill: 0xff1010,\n * align: 'center',\n * }\n * });\n * @memberof scene\n */\nexport class HTMLText extends AbstractText<HTMLTextStyle, HTMLTextStyleOptions> implements View\n{\n public readonly renderPipeId: string = 'htmlText';\n\n /**\n * @param {text.HTMLTextOptions} options - The options of the html text.\n */\n constructor(options?: HTMLTextOptions);\n /** @deprecated since 8.0.0 */\n constructor(text?: TextString, options?: Partial<HTMLTextStyle>);\n constructor(...args: [HTMLTextOptions?] | [TextString, Partial<HTMLTextStyle>])\n {\n const options = ensureOptions<HTMLTextStyle, HTMLTextStyleOptions>(args, 'HtmlText');\n\n super(options, HTMLTextStyle);\n }\n\n protected _updateBounds()\n {\n const bounds = this._bounds;\n const anchor = this._anchor;\n\n const htmlMeasurement = measureHtmlText(this.text, this._style as HTMLTextStyle);\n\n const { width, height } = htmlMeasurement;\n\n bounds.minX = (-anchor._x * width);\n bounds.maxX = bounds.minX + width;\n bounds.minY = (-anchor._y * height);\n bounds.maxY = bounds.minY + height;\n }\n}\n"],"names":["AbstractText","ensureOptions","HTMLTextStyle","measureHtmlText"],"mappings":";;;;;;;AAuDO,MAAM,iBAAiBA,yBAC9B,CAAA;AAAA,EASI,eAAe,IACf,EAAA;AACI,IAAM,MAAA,OAAA,GAAUC,0BAAmD,CAAA,IAAA,EAAM,UAAU,CAAA,CAAA;AAEnF,IAAA,KAAA,CAAM,SAASC,2BAAa,CAAA,CAAA;AAZhC,IAAA,IAAA,CAAgB,YAAuB,GAAA,UAAA,CAAA;AAAA,GAavC;AAAA,EAEU,aACV,GAAA;AACI,IAAA,MAAM,SAAS,IAAK,CAAA,OAAA,CAAA;AACpB,IAAA,MAAM,SAAS,IAAK,CAAA,OAAA,CAAA;AAEpB,IAAA,MAAM,eAAkB,GAAAC,+BAAA,CAAgB,IAAK,CAAA,IAAA,EAAM,KAAK,MAAuB,CAAA,CAAA;AAE/E,IAAM,MAAA,EAAE,KAAO,EAAA,MAAA,EAAW,GAAA,eAAA,CAAA;AAE1B,IAAO,MAAA,CAAA,IAAA,GAAQ,CAAC,MAAA,CAAO,EAAK,GAAA,KAAA,CAAA;AAC5B,IAAO,MAAA,CAAA,IAAA,GAAO,OAAO,IAAO,GAAA,KAAA,CAAA;AAC5B,IAAO,MAAA,CAAA,IAAA,GAAQ,CAAC,MAAA,CAAO,EAAK,GAAA,MAAA,CAAA;AAC5B,IAAO,MAAA,CAAA,IAAA,GAAO,OAAO,IAAO,GAAA,MAAA,CAAA;AAAA,GAChC;AACJ;;;;"}

25
node_modules/pixi.js/lib/scene/text-html/HTMLText.mjs generated vendored Normal file
View File

@@ -0,0 +1,25 @@
import { AbstractText, ensureOptions } from '../text/AbstractText.mjs';
import { HTMLTextStyle } from './HtmlTextStyle.mjs';
import { measureHtmlText } from './utils/measureHtmlText.mjs';
"use strict";
class HTMLText extends AbstractText {
constructor(...args) {
const options = ensureOptions(args, "HtmlText");
super(options, HTMLTextStyle);
this.renderPipeId = "htmlText";
}
_updateBounds() {
const bounds = this._bounds;
const anchor = this._anchor;
const htmlMeasurement = measureHtmlText(this.text, this._style);
const { width, height } = htmlMeasurement;
bounds.minX = -anchor._x * width;
bounds.maxX = bounds.minX + width;
bounds.minY = -anchor._y * height;
bounds.maxY = bounds.minY + height;
}
}
export { HTMLText };
//# sourceMappingURL=HTMLText.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"HTMLText.mjs","sources":["../../../src/scene/text-html/HTMLText.ts"],"sourcesContent":["import { AbstractText, ensureOptions } from '../text/AbstractText';\nimport { HTMLTextStyle } from './HtmlTextStyle';\nimport { measureHtmlText } from './utils/measureHtmlText';\n\nimport type { View } from '../../rendering/renderers/shared/view/View';\nimport type { TextOptions, TextString } from '../text/AbstractText';\nimport type { HTMLTextStyleOptions } from './HtmlTextStyle';\n\n/**\n * Constructor options used for `HTMLText` instances.\n * @property {string} [text=''] - The string that you would like the text to display.\n * @property {text.HTMLTextStyle | text.HTMLTextStyleOptions} [style] - The style of the text.\n * @memberof text\n */\nexport type HTMLTextOptions = TextOptions<HTMLTextStyle, HTMLTextStyleOptions>;\n\n/**\n * A HTMLText Object will create a line or multiple lines of text.\n *\n * To split a line you can use '\\n' in your text string, or, on the `style` object,\n * change its `wordWrap` property to true and and give the `wordWrapWidth` property a value.\n *\n * HTMLText uses an svg foreignObject to render HTML text.\n *\n *\n * The primary advantages of this render mode are:\n *\n * - Supports [HTML tags](https://developer.mozilla.org/en-US/docs/Learn/HTML/Introduction_to_HTML/HTML_text_fundamentals)\n * for styling such as `<strong>`, or `<em>`, as well as `<span style=\"\">`\n *\n * - Better support for emojis and other HTML layout features, better compatibility with CSS\n * line-height and letter-spacing.\n *\n *\n * The primary disadvantages are:\n * - Unlike `text`, `html` rendering will vary slightly between platforms and browsers.\n * `html` uses SVG/DOM to render text and not Context2D's fillText like `text`.\n *\n * - Performance and memory usage is on-par with `text` (that is to say, slow and heavy)\n *\n * - Only works with browsers that support <foreignObject>.\n * @example\n * import { HTMLText } from 'pixi.js';\n *\n * const text = new HTMLText({\n * text: 'Hello Pixi!',\n * style: {\n * fontFamily: 'Arial',\n * fontSize: 24,\n * fill: 0xff1010,\n * align: 'center',\n * }\n * });\n * @memberof scene\n */\nexport class HTMLText extends AbstractText<HTMLTextStyle, HTMLTextStyleOptions> implements View\n{\n public readonly renderPipeId: string = 'htmlText';\n\n /**\n * @param {text.HTMLTextOptions} options - The options of the html text.\n */\n constructor(options?: HTMLTextOptions);\n /** @deprecated since 8.0.0 */\n constructor(text?: TextString, options?: Partial<HTMLTextStyle>);\n constructor(...args: [HTMLTextOptions?] | [TextString, Partial<HTMLTextStyle>])\n {\n const options = ensureOptions<HTMLTextStyle, HTMLTextStyleOptions>(args, 'HtmlText');\n\n super(options, HTMLTextStyle);\n }\n\n protected _updateBounds()\n {\n const bounds = this._bounds;\n const anchor = this._anchor;\n\n const htmlMeasurement = measureHtmlText(this.text, this._style as HTMLTextStyle);\n\n const { width, height } = htmlMeasurement;\n\n bounds.minX = (-anchor._x * width);\n bounds.maxX = bounds.minX + width;\n bounds.minY = (-anchor._y * height);\n bounds.maxY = bounds.minY + height;\n }\n}\n"],"names":[],"mappings":";;;;;AAuDO,MAAM,iBAAiB,YAC9B,CAAA;AAAA,EASI,eAAe,IACf,EAAA;AACI,IAAM,MAAA,OAAA,GAAU,aAAmD,CAAA,IAAA,EAAM,UAAU,CAAA,CAAA;AAEnF,IAAA,KAAA,CAAM,SAAS,aAAa,CAAA,CAAA;AAZhC,IAAA,IAAA,CAAgB,YAAuB,GAAA,UAAA,CAAA;AAAA,GAavC;AAAA,EAEU,aACV,GAAA;AACI,IAAA,MAAM,SAAS,IAAK,CAAA,OAAA,CAAA;AACpB,IAAA,MAAM,SAAS,IAAK,CAAA,OAAA,CAAA;AAEpB,IAAA,MAAM,eAAkB,GAAA,eAAA,CAAgB,IAAK,CAAA,IAAA,EAAM,KAAK,MAAuB,CAAA,CAAA;AAE/E,IAAM,MAAA,EAAE,KAAO,EAAA,MAAA,EAAW,GAAA,eAAA,CAAA;AAE1B,IAAO,MAAA,CAAA,IAAA,GAAQ,CAAC,MAAA,CAAO,EAAK,GAAA,KAAA,CAAA;AAC5B,IAAO,MAAA,CAAA,IAAA,GAAO,OAAO,IAAO,GAAA,KAAA,CAAA;AAC5B,IAAO,MAAA,CAAA,IAAA,GAAQ,CAAC,MAAA,CAAO,EAAK,GAAA,MAAA,CAAA;AAC5B,IAAO,MAAA,CAAA,IAAA,GAAO,OAAO,IAAO,GAAA,MAAA,CAAA;AAAA,GAChC;AACJ;;;;"}

View File

@@ -0,0 +1,35 @@
import { ExtensionType } from '../../extensions/Extensions';
import { Texture } from '../../rendering/renderers/shared/texture/Texture';
import { BatchableSprite } from '../sprite/BatchableSprite';
import type { InstructionSet } from '../../rendering/renderers/shared/instructions/InstructionSet';
import type { RenderPipe } from '../../rendering/renderers/shared/instructions/RenderPipe';
import type { Renderer } from '../../rendering/renderers/types';
import type { HTMLText } from './HTMLText';
export declare class HTMLTextPipe implements RenderPipe<HTMLText> {
/** @ignore */
static extension: {
readonly type: readonly [ExtensionType.WebGLPipes, ExtensionType.WebGPUPipes, ExtensionType.CanvasPipes];
readonly name: "htmlText";
};
private _renderer;
private _gpuText;
private readonly _destroyRenderableBound;
constructor(renderer: Renderer);
resolutionChange(): void;
validateRenderable(htmlText: HTMLText): boolean;
addRenderable(htmlText: HTMLText, instructionSet: InstructionSet): void;
updateRenderable(htmlText: HTMLText): void;
destroyRenderable(htmlText: HTMLText): void;
private _destroyRenderableById;
private _updateText;
private _updateGpuText;
private _getGpuText;
initGpuText(htmlText: HTMLText): {
textureNeedsUploading: boolean;
generatingTexture: boolean;
texture: Texture<import("../..").TextureSource<any>>;
currentKey: string;
batchableSprite: BatchableSprite;
};
destroy(): void;
}

View File

@@ -0,0 +1,145 @@
'use strict';
var Extensions = require('../../extensions/Extensions.js');
var Texture = require('../../rendering/renderers/shared/texture/Texture.js');
var updateQuadBounds = require('../../utils/data/updateQuadBounds.js');
var PoolGroup = require('../../utils/pool/PoolGroup.js');
var BatchableSprite = require('../sprite/BatchableSprite.js');
"use strict";
class HTMLTextPipe {
constructor(renderer) {
this._gpuText = /* @__PURE__ */ Object.create(null);
this._destroyRenderableBound = this.destroyRenderable.bind(this);
this._renderer = renderer;
this._renderer.runners.resolutionChange.add(this);
}
resolutionChange() {
for (const i in this._gpuText) {
const gpuText = this._gpuText[i];
if (!gpuText)
continue;
const text = gpuText.batchableSprite.renderable;
if (text._autoResolution) {
text._resolution = this._renderer.resolution;
text.onViewUpdate();
}
}
}
validateRenderable(htmlText) {
const gpuText = this._getGpuText(htmlText);
const newKey = htmlText._getKey();
if (gpuText.textureNeedsUploading) {
gpuText.textureNeedsUploading = false;
return true;
}
if (gpuText.currentKey !== newKey) {
return true;
}
return false;
}
addRenderable(htmlText, instructionSet) {
const gpuText = this._getGpuText(htmlText);
const batchableSprite = gpuText.batchableSprite;
if (htmlText._didTextUpdate) {
this._updateText(htmlText);
}
this._renderer.renderPipes.batch.addToBatch(batchableSprite, instructionSet);
}
updateRenderable(htmlText) {
const gpuText = this._getGpuText(htmlText);
const batchableSprite = gpuText.batchableSprite;
if (htmlText._didTextUpdate) {
this._updateText(htmlText);
}
batchableSprite._batcher.updateElement(batchableSprite);
}
destroyRenderable(htmlText) {
htmlText.off("destroyed", this._destroyRenderableBound);
this._destroyRenderableById(htmlText.uid);
}
_destroyRenderableById(htmlTextUid) {
const gpuText = this._gpuText[htmlTextUid];
this._renderer.htmlText.decreaseReferenceCount(gpuText.currentKey);
PoolGroup.BigPool.return(gpuText.batchableSprite);
this._gpuText[htmlTextUid] = null;
}
_updateText(htmlText) {
const newKey = htmlText._getKey();
const gpuText = this._getGpuText(htmlText);
const batchableSprite = gpuText.batchableSprite;
if (gpuText.currentKey !== newKey) {
this._updateGpuText(htmlText).catch((e) => {
console.error(e);
});
}
htmlText._didTextUpdate = false;
const padding = htmlText._style.padding;
updateQuadBounds.updateQuadBounds(batchableSprite.bounds, htmlText._anchor, batchableSprite.texture, padding);
}
async _updateGpuText(htmlText) {
htmlText._didTextUpdate = false;
const gpuText = this._getGpuText(htmlText);
if (gpuText.generatingTexture)
return;
const newKey = htmlText._getKey();
this._renderer.htmlText.decreaseReferenceCount(gpuText.currentKey);
gpuText.generatingTexture = true;
gpuText.currentKey = newKey;
const resolution = htmlText.resolution ?? this._renderer.resolution;
const texture = await this._renderer.htmlText.getManagedTexture(
htmlText.text,
resolution,
htmlText._style,
htmlText._getKey()
);
const batchableSprite = gpuText.batchableSprite;
batchableSprite.texture = gpuText.texture = texture;
gpuText.generatingTexture = false;
gpuText.textureNeedsUploading = true;
htmlText.onViewUpdate();
const padding = htmlText._style.padding;
updateQuadBounds.updateQuadBounds(batchableSprite.bounds, htmlText._anchor, batchableSprite.texture, padding);
}
_getGpuText(htmlText) {
return this._gpuText[htmlText.uid] || this.initGpuText(htmlText);
}
initGpuText(htmlText) {
const gpuTextData = {
texture: Texture.Texture.EMPTY,
currentKey: "--",
batchableSprite: PoolGroup.BigPool.get(BatchableSprite.BatchableSprite),
textureNeedsUploading: false,
generatingTexture: false
};
const batchableSprite = gpuTextData.batchableSprite;
batchableSprite.renderable = htmlText;
batchableSprite.transform = htmlText.groupTransform;
batchableSprite.texture = Texture.Texture.EMPTY;
batchableSprite.bounds = { minX: 0, maxX: 1, minY: 0, maxY: 0 };
batchableSprite.roundPixels = this._renderer._roundPixels | htmlText._roundPixels;
htmlText._resolution = htmlText._autoResolution ? this._renderer.resolution : htmlText.resolution;
this._gpuText[htmlText.uid] = gpuTextData;
htmlText.on("destroyed", this._destroyRenderableBound);
return gpuTextData;
}
destroy() {
for (const i in this._gpuText) {
this._destroyRenderableById(i);
}
this._gpuText = null;
this._renderer = null;
}
}
/** @ignore */
HTMLTextPipe.extension = {
type: [
Extensions.ExtensionType.WebGLPipes,
Extensions.ExtensionType.WebGPUPipes,
Extensions.ExtensionType.CanvasPipes
],
name: "htmlText"
};
exports.HTMLTextPipe = HTMLTextPipe;
//# sourceMappingURL=HTMLTextPipe.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,143 @@
import { ExtensionType } from '../../extensions/Extensions.mjs';
import { Texture } from '../../rendering/renderers/shared/texture/Texture.mjs';
import { updateQuadBounds } from '../../utils/data/updateQuadBounds.mjs';
import { BigPool } from '../../utils/pool/PoolGroup.mjs';
import { BatchableSprite } from '../sprite/BatchableSprite.mjs';
"use strict";
class HTMLTextPipe {
constructor(renderer) {
this._gpuText = /* @__PURE__ */ Object.create(null);
this._destroyRenderableBound = this.destroyRenderable.bind(this);
this._renderer = renderer;
this._renderer.runners.resolutionChange.add(this);
}
resolutionChange() {
for (const i in this._gpuText) {
const gpuText = this._gpuText[i];
if (!gpuText)
continue;
const text = gpuText.batchableSprite.renderable;
if (text._autoResolution) {
text._resolution = this._renderer.resolution;
text.onViewUpdate();
}
}
}
validateRenderable(htmlText) {
const gpuText = this._getGpuText(htmlText);
const newKey = htmlText._getKey();
if (gpuText.textureNeedsUploading) {
gpuText.textureNeedsUploading = false;
return true;
}
if (gpuText.currentKey !== newKey) {
return true;
}
return false;
}
addRenderable(htmlText, instructionSet) {
const gpuText = this._getGpuText(htmlText);
const batchableSprite = gpuText.batchableSprite;
if (htmlText._didTextUpdate) {
this._updateText(htmlText);
}
this._renderer.renderPipes.batch.addToBatch(batchableSprite, instructionSet);
}
updateRenderable(htmlText) {
const gpuText = this._getGpuText(htmlText);
const batchableSprite = gpuText.batchableSprite;
if (htmlText._didTextUpdate) {
this._updateText(htmlText);
}
batchableSprite._batcher.updateElement(batchableSprite);
}
destroyRenderable(htmlText) {
htmlText.off("destroyed", this._destroyRenderableBound);
this._destroyRenderableById(htmlText.uid);
}
_destroyRenderableById(htmlTextUid) {
const gpuText = this._gpuText[htmlTextUid];
this._renderer.htmlText.decreaseReferenceCount(gpuText.currentKey);
BigPool.return(gpuText.batchableSprite);
this._gpuText[htmlTextUid] = null;
}
_updateText(htmlText) {
const newKey = htmlText._getKey();
const gpuText = this._getGpuText(htmlText);
const batchableSprite = gpuText.batchableSprite;
if (gpuText.currentKey !== newKey) {
this._updateGpuText(htmlText).catch((e) => {
console.error(e);
});
}
htmlText._didTextUpdate = false;
const padding = htmlText._style.padding;
updateQuadBounds(batchableSprite.bounds, htmlText._anchor, batchableSprite.texture, padding);
}
async _updateGpuText(htmlText) {
htmlText._didTextUpdate = false;
const gpuText = this._getGpuText(htmlText);
if (gpuText.generatingTexture)
return;
const newKey = htmlText._getKey();
this._renderer.htmlText.decreaseReferenceCount(gpuText.currentKey);
gpuText.generatingTexture = true;
gpuText.currentKey = newKey;
const resolution = htmlText.resolution ?? this._renderer.resolution;
const texture = await this._renderer.htmlText.getManagedTexture(
htmlText.text,
resolution,
htmlText._style,
htmlText._getKey()
);
const batchableSprite = gpuText.batchableSprite;
batchableSprite.texture = gpuText.texture = texture;
gpuText.generatingTexture = false;
gpuText.textureNeedsUploading = true;
htmlText.onViewUpdate();
const padding = htmlText._style.padding;
updateQuadBounds(batchableSprite.bounds, htmlText._anchor, batchableSprite.texture, padding);
}
_getGpuText(htmlText) {
return this._gpuText[htmlText.uid] || this.initGpuText(htmlText);
}
initGpuText(htmlText) {
const gpuTextData = {
texture: Texture.EMPTY,
currentKey: "--",
batchableSprite: BigPool.get(BatchableSprite),
textureNeedsUploading: false,
generatingTexture: false
};
const batchableSprite = gpuTextData.batchableSprite;
batchableSprite.renderable = htmlText;
batchableSprite.transform = htmlText.groupTransform;
batchableSprite.texture = Texture.EMPTY;
batchableSprite.bounds = { minX: 0, maxX: 1, minY: 0, maxY: 0 };
batchableSprite.roundPixels = this._renderer._roundPixels | htmlText._roundPixels;
htmlText._resolution = htmlText._autoResolution ? this._renderer.resolution : htmlText.resolution;
this._gpuText[htmlText.uid] = gpuTextData;
htmlText.on("destroyed", this._destroyRenderableBound);
return gpuTextData;
}
destroy() {
for (const i in this._gpuText) {
this._destroyRenderableById(i);
}
this._gpuText = null;
this._renderer = null;
}
}
/** @ignore */
HTMLTextPipe.extension = {
type: [
ExtensionType.WebGLPipes,
ExtensionType.WebGPUPipes,
ExtensionType.CanvasPipes
],
name: "htmlText"
};
export { HTMLTextPipe };
//# sourceMappingURL=HTMLTextPipe.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,12 @@
import type { CanvasAndContext } from '../../rendering/renderers/shared/texture/CanvasPool';
export declare const nssvg = "http://www.w3.org/2000/svg";
export declare const nsxhtml = "http://www.w3.org/1999/xhtml";
export declare class HTMLTextRenderData {
svgRoot: SVGSVGElement;
foreignObject: SVGForeignObjectElement;
domElement: HTMLElement;
styleElement: HTMLElement;
image: HTMLImageElement;
canvasAndContext?: CanvasAndContext;
constructor();
}

View File

@@ -0,0 +1,26 @@
'use strict';
"use strict";
const nssvg = "http://www.w3.org/2000/svg";
const nsxhtml = "http://www.w3.org/1999/xhtml";
class HTMLTextRenderData {
constructor() {
this.svgRoot = document.createElementNS(nssvg, "svg");
this.foreignObject = document.createElementNS(nssvg, "foreignObject");
this.domElement = document.createElementNS(nsxhtml, "div");
this.styleElement = document.createElementNS(nsxhtml, "style");
this.image = new Image();
const { foreignObject, svgRoot, styleElement, domElement } = this;
foreignObject.setAttribute("width", "10000");
foreignObject.setAttribute("height", "10000");
foreignObject.style.overflow = "hidden";
svgRoot.appendChild(foreignObject);
foreignObject.appendChild(styleElement);
foreignObject.appendChild(domElement);
}
}
exports.HTMLTextRenderData = HTMLTextRenderData;
exports.nssvg = nssvg;
exports.nsxhtml = nsxhtml;
//# sourceMappingURL=HTMLTextRenderData.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"HTMLTextRenderData.js","sources":["../../../src/scene/text-html/HTMLTextRenderData.ts"],"sourcesContent":["import type { CanvasAndContext } from '../../rendering/renderers/shared/texture/CanvasPool';\n\nexport const nssvg = 'http://www.w3.org/2000/svg';\nexport const nsxhtml = 'http://www.w3.org/1999/xhtml';\n\nexport class HTMLTextRenderData\n{\n public svgRoot = document.createElementNS(nssvg, 'svg');\n public foreignObject = document.createElementNS(nssvg, 'foreignObject');\n public domElement = document.createElementNS(nsxhtml, 'div');\n public styleElement = document.createElementNS(nsxhtml, 'style');\n public image = new Image();\n public canvasAndContext?: CanvasAndContext;\n\n constructor()\n {\n const { foreignObject, svgRoot, styleElement, domElement } = this;\n // Arbitrary max size\n\n foreignObject.setAttribute('width', '10000');\n foreignObject.setAttribute('height', '10000');\n foreignObject.style.overflow = 'hidden';\n\n svgRoot.appendChild(foreignObject);\n\n foreignObject.appendChild(styleElement);\n foreignObject.appendChild(domElement);\n }\n}\n"],"names":[],"mappings":";;;AAEO,MAAM,KAAQ,GAAA,6BAAA;AACd,MAAM,OAAU,GAAA,+BAAA;AAEhB,MAAM,kBACb,CAAA;AAAA,EAQI,WACA,GAAA;AARA,IAAA,IAAA,CAAO,OAAU,GAAA,QAAA,CAAS,eAAgB,CAAA,KAAA,EAAO,KAAK,CAAA,CAAA;AACtD,IAAA,IAAA,CAAO,aAAgB,GAAA,QAAA,CAAS,eAAgB,CAAA,KAAA,EAAO,eAAe,CAAA,CAAA;AACtE,IAAA,IAAA,CAAO,UAAa,GAAA,QAAA,CAAS,eAAgB,CAAA,OAAA,EAAS,KAAK,CAAA,CAAA;AAC3D,IAAA,IAAA,CAAO,YAAe,GAAA,QAAA,CAAS,eAAgB,CAAA,OAAA,EAAS,OAAO,CAAA,CAAA;AAC/D,IAAO,IAAA,CAAA,KAAA,GAAQ,IAAI,KAAM,EAAA,CAAA;AAKrB,IAAA,MAAM,EAAE,aAAA,EAAe,OAAS,EAAA,YAAA,EAAc,YAAe,GAAA,IAAA,CAAA;AAG7D,IAAc,aAAA,CAAA,YAAA,CAAa,SAAS,OAAO,CAAA,CAAA;AAC3C,IAAc,aAAA,CAAA,YAAA,CAAa,UAAU,OAAO,CAAA,CAAA;AAC5C,IAAA,aAAA,CAAc,MAAM,QAAW,GAAA,QAAA,CAAA;AAE/B,IAAA,OAAA,CAAQ,YAAY,aAAa,CAAA,CAAA;AAEjC,IAAA,aAAA,CAAc,YAAY,YAAY,CAAA,CAAA;AACtC,IAAA,aAAA,CAAc,YAAY,UAAU,CAAA,CAAA;AAAA,GACxC;AACJ;;;;;;"}

View File

@@ -0,0 +1,22 @@
"use strict";
const nssvg = "http://www.w3.org/2000/svg";
const nsxhtml = "http://www.w3.org/1999/xhtml";
class HTMLTextRenderData {
constructor() {
this.svgRoot = document.createElementNS(nssvg, "svg");
this.foreignObject = document.createElementNS(nssvg, "foreignObject");
this.domElement = document.createElementNS(nsxhtml, "div");
this.styleElement = document.createElementNS(nsxhtml, "style");
this.image = new Image();
const { foreignObject, svgRoot, styleElement, domElement } = this;
foreignObject.setAttribute("width", "10000");
foreignObject.setAttribute("height", "10000");
foreignObject.style.overflow = "hidden";
svgRoot.appendChild(foreignObject);
foreignObject.appendChild(styleElement);
foreignObject.appendChild(domElement);
}
}
export { HTMLTextRenderData, nssvg, nsxhtml };
//# sourceMappingURL=HTMLTextRenderData.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"HTMLTextRenderData.mjs","sources":["../../../src/scene/text-html/HTMLTextRenderData.ts"],"sourcesContent":["import type { CanvasAndContext } from '../../rendering/renderers/shared/texture/CanvasPool';\n\nexport const nssvg = 'http://www.w3.org/2000/svg';\nexport const nsxhtml = 'http://www.w3.org/1999/xhtml';\n\nexport class HTMLTextRenderData\n{\n public svgRoot = document.createElementNS(nssvg, 'svg');\n public foreignObject = document.createElementNS(nssvg, 'foreignObject');\n public domElement = document.createElementNS(nsxhtml, 'div');\n public styleElement = document.createElementNS(nsxhtml, 'style');\n public image = new Image();\n public canvasAndContext?: CanvasAndContext;\n\n constructor()\n {\n const { foreignObject, svgRoot, styleElement, domElement } = this;\n // Arbitrary max size\n\n foreignObject.setAttribute('width', '10000');\n foreignObject.setAttribute('height', '10000');\n foreignObject.style.overflow = 'hidden';\n\n svgRoot.appendChild(foreignObject);\n\n foreignObject.appendChild(styleElement);\n foreignObject.appendChild(domElement);\n }\n}\n"],"names":[],"mappings":";AAEO,MAAM,KAAQ,GAAA,6BAAA;AACd,MAAM,OAAU,GAAA,+BAAA;AAEhB,MAAM,kBACb,CAAA;AAAA,EAQI,WACA,GAAA;AARA,IAAA,IAAA,CAAO,OAAU,GAAA,QAAA,CAAS,eAAgB,CAAA,KAAA,EAAO,KAAK,CAAA,CAAA;AACtD,IAAA,IAAA,CAAO,aAAgB,GAAA,QAAA,CAAS,eAAgB,CAAA,KAAA,EAAO,eAAe,CAAA,CAAA;AACtE,IAAA,IAAA,CAAO,UAAa,GAAA,QAAA,CAAS,eAAgB,CAAA,OAAA,EAAS,KAAK,CAAA,CAAA;AAC3D,IAAA,IAAA,CAAO,YAAe,GAAA,QAAA,CAAS,eAAgB,CAAA,OAAA,EAAS,OAAO,CAAA,CAAA;AAC/D,IAAO,IAAA,CAAA,KAAA,GAAQ,IAAI,KAAM,EAAA,CAAA;AAKrB,IAAA,MAAM,EAAE,aAAA,EAAe,OAAS,EAAA,YAAA,EAAc,YAAe,GAAA,IAAA,CAAA;AAG7D,IAAc,aAAA,CAAA,YAAA,CAAa,SAAS,OAAO,CAAA,CAAA;AAC3C,IAAc,aAAA,CAAA,YAAA,CAAa,UAAU,OAAO,CAAA,CAAA;AAC5C,IAAA,aAAA,CAAc,MAAM,QAAW,GAAA,QAAA,CAAA;AAE/B,IAAA,OAAA,CAAQ,YAAY,aAAa,CAAA,CAAA;AAEjC,IAAA,aAAA,CAAc,YAAY,YAAY,CAAA,CAAA;AACtC,IAAA,aAAA,CAAc,YAAY,UAAU,CAAA,CAAA;AAAA,GACxC;AACJ;;;;"}

View File

@@ -0,0 +1,36 @@
import { ExtensionType } from '../../extensions/Extensions';
import { type Renderer } from '../../rendering/renderers/types';
import { HTMLTextStyle } from './HtmlTextStyle';
import type { System } from '../../rendering/renderers/shared/system/System';
import type { Texture } from '../../rendering/renderers/shared/texture/Texture';
import type { HTMLTextOptions } from './HTMLText';
import type { FontCSSStyleOptions } from './utils/loadFontCSS';
/**
* System plugin to the renderer to manage HTMLText
* @memberof rendering
*/
export declare class HTMLTextSystem implements System {
/** @ignore */
static extension: {
readonly type: readonly [ExtensionType.WebGLSystem, ExtensionType.WebGPUSystem, ExtensionType.CanvasSystem];
readonly name: "htmlText";
};
static defaultFontOptions: FontCSSStyleOptions;
private _activeTextures;
/**
* WebGPU has a cors issue when uploading an image that is an SVGImage
* To get around this we need to create a canvas draw the image to it and upload that instead.
* Bit of a shame.. but no other work around just yet!
*/
private readonly _createCanvas;
private readonly _renderer;
constructor(renderer: Renderer);
getTexture(options: HTMLTextOptions): Promise<Texture>;
getManagedTexture(text: string, resolution: number, style: HTMLTextStyle, textKey: string): Promise<Texture>;
private _buildTexturePromise;
private _increaseReferenceCount;
decreaseReferenceCount(textKey: string): void;
private _cleanUp;
getReferenceCount(textKey: string): number;
destroy(): void;
}

View File

@@ -0,0 +1,132 @@
'use strict';
var Extensions = require('../../extensions/Extensions.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 HtmlTextStyle = require('./HtmlTextStyle.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');
"use strict";
class HTMLTextSystem {
constructor(renderer) {
this._activeTextures = {};
this._renderer = renderer;
this._createCanvas = renderer.type === types.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 = PoolGroup.BigPool.get(HTMLTextRenderData.HTMLTextRenderData);
const fontFamilies = extractFontFamilies.extractFontFamilies(text, style);
const fontCSS = await getFontCss.getFontCss(
fontFamilies,
style,
HtmlTextStyle.HTMLTextStyle.defaultTextStyle
);
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);
let resource = image;
if (this._createCanvas) {
resource = getTemporaryCanvasFromImage.getTemporaryCanvasFromImage(image, resolution);
}
const texture = getPo2TextureFromSource.getPo2TextureFromSource(
resource,
image.width - uvSafeOffset,
image.height - uvSafeOffset,
resolution
);
if (this._createCanvas) {
this._renderer.texture.initSource(texture.source);
}
PoolGroup.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.warn("HTMLTextSystem: Failed to clean texture");
});
}
this._activeTextures[textKey] = null;
}
}
_cleanUp(activeTexture) {
TexturePool.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: [
Extensions.ExtensionType.WebGLSystem,
Extensions.ExtensionType.WebGPUSystem,
Extensions.ExtensionType.CanvasSystem
],
name: "htmlText"
};
HTMLTextSystem.defaultFontOptions = {
fontFamily: "Arial",
fontStyle: "normal",
fontWeight: "normal"
};
exports.HTMLTextSystem = HTMLTextSystem;
//# sourceMappingURL=HTMLTextSystem.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,130 @@
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

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,77 @@
import { TextStyle } from '../text/TextStyle';
import type { FillInput, StrokeInput } from '../graphics/shared/FillTypes';
import type { TextStyleOptions } from '../text/TextStyle';
/**
* Options for HTML text style, extends {@link TextStyle}.
* @memberof text
* @extends text.TextStyleOptions
* @property {string[]} [cssOverrides] - CSS style(s) to add.
* @property {Record<string, text.HTMLTextStyleOptions>} [tagStyles] - Tag styles.
*/
export interface HTMLTextStyleOptions extends Omit<TextStyleOptions, 'leading' | 'textBaseline' | 'trim'> {
cssOverrides?: string[];
tagStyles?: Record<string, HTMLTextStyleOptions>;
}
/**
* A TextStyle object rendered by the HTMLTextSystem.
* @memberof text
*/
export declare class HTMLTextStyle extends TextStyle {
private _cssOverrides;
private _cssStyle;
/**
* List of styles per tag.
* @example
* new HTMLText({
* text:'<red>Red</red>,<blue>Blue</blue>,<green>Green</green>',
* style:{
* fontFamily: 'DM Sans',
* fill: 'white',
* fontSize:100,
* tagStyles:{
* red:{
* fill:'red',
* },
* blue:{
* fill:'blue',
* },
* green:{
* fill:'green',
* }
* }
* }
* );
*/
tagStyles: Record<string, HTMLTextStyleOptions>;
constructor(options?: HTMLTextStyleOptions);
/** List of style overrides that will be applied to the HTML text. */
set cssOverrides(value: string | string[]);
get cssOverrides(): string[];
protected _generateKey(): string;
update(): void;
/**
* Creates a new HTMLTextStyle object with the same values as this one.
* @returns New cloned HTMLTextStyle object
*/
clone(): HTMLTextStyle;
get cssStyle(): string;
/**
* Add a style override, this can be any CSS property
* it will override any built-in style. This is the
* property and the value as a string (e.g., `color: red`).
* This will override any other internal style.
* @param {string} value - CSS style(s) to add.
* @example
* style.addOverride('background-color: red');
*/
addOverride(...value: string[]): void;
/**
* Remove any overrides that match the value.
* @param {string} value - CSS style to remove.
* @example
* style.removeOverride('background-color: red');
*/
removeOverride(...value: string[]): void;
set fill(value: FillInput);
set stroke(value: StrokeInput);
}

View File

@@ -0,0 +1,107 @@
'use strict';
var warn = require('../../utils/logging/warn.js');
var TextStyle = require('../text/TextStyle.js');
var generateTextStyleKey = require('../text/utils/generateTextStyleKey.js');
var textStyleToCSS = require('./utils/textStyleToCSS.js');
"use strict";
class HTMLTextStyle extends TextStyle.TextStyle {
constructor(options = {}) {
super(options);
this._cssOverrides = [];
this.cssOverrides ?? (this.cssOverrides = options.cssOverrides);
this.tagStyles = options.tagStyles ?? {};
}
/** List of style overrides that will be applied to the HTML text. */
set cssOverrides(value) {
this._cssOverrides = value instanceof Array ? value : [value];
this.update();
}
get cssOverrides() {
return this._cssOverrides;
}
_generateKey() {
this._styleKey = generateTextStyleKey.generateTextStyleKey(this) + this._cssOverrides.join("-");
return this._styleKey;
}
update() {
this._cssStyle = null;
super.update();
}
/**
* Creates a new HTMLTextStyle object with the same values as this one.
* @returns New cloned HTMLTextStyle object
*/
clone() {
return new HTMLTextStyle({
align: this.align,
breakWords: this.breakWords,
dropShadow: this.dropShadow ? { ...this.dropShadow } : null,
fill: this._fill,
fontFamily: this.fontFamily,
fontSize: this.fontSize,
fontStyle: this.fontStyle,
fontVariant: this.fontVariant,
fontWeight: this.fontWeight,
letterSpacing: this.letterSpacing,
lineHeight: this.lineHeight,
padding: this.padding,
stroke: this._stroke,
whiteSpace: this.whiteSpace,
wordWrap: this.wordWrap,
wordWrapWidth: this.wordWrapWidth,
cssOverrides: this.cssOverrides
});
}
get cssStyle() {
if (!this._cssStyle) {
this._cssStyle = textStyleToCSS.textStyleToCSS(this);
}
return this._cssStyle;
}
/**
* Add a style override, this can be any CSS property
* it will override any built-in style. This is the
* property and the value as a string (e.g., `color: red`).
* This will override any other internal style.
* @param {string} value - CSS style(s) to add.
* @example
* style.addOverride('background-color: red');
*/
addOverride(...value) {
const toAdd = value.filter((v) => !this.cssOverrides.includes(v));
if (toAdd.length > 0) {
this.cssOverrides.push(...toAdd);
this.update();
}
}
/**
* Remove any overrides that match the value.
* @param {string} value - CSS style to remove.
* @example
* style.removeOverride('background-color: red');
*/
removeOverride(...value) {
const toRemove = value.filter((v) => this.cssOverrides.includes(v));
if (toRemove.length > 0) {
this.cssOverrides = this.cssOverrides.filter((v) => !toRemove.includes(v));
this.update();
}
}
set fill(value) {
if (typeof value !== "string" && typeof value !== "number") {
warn.warn("[HTMLTextStyle] only color fill is not supported by HTMLText");
}
super.fill = value;
}
set stroke(value) {
if (value && typeof value !== "string" && typeof value !== "number") {
warn.warn("[HTMLTextStyle] only color stroke is not supported by HTMLText");
}
super.stroke = value;
}
}
exports.HTMLTextStyle = HTMLTextStyle;
//# sourceMappingURL=HtmlTextStyle.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,105 @@
import { warn } from '../../utils/logging/warn.mjs';
import { TextStyle } from '../text/TextStyle.mjs';
import { generateTextStyleKey } from '../text/utils/generateTextStyleKey.mjs';
import { textStyleToCSS } from './utils/textStyleToCSS.mjs';
"use strict";
class HTMLTextStyle extends TextStyle {
constructor(options = {}) {
super(options);
this._cssOverrides = [];
this.cssOverrides ?? (this.cssOverrides = options.cssOverrides);
this.tagStyles = options.tagStyles ?? {};
}
/** List of style overrides that will be applied to the HTML text. */
set cssOverrides(value) {
this._cssOverrides = value instanceof Array ? value : [value];
this.update();
}
get cssOverrides() {
return this._cssOverrides;
}
_generateKey() {
this._styleKey = generateTextStyleKey(this) + this._cssOverrides.join("-");
return this._styleKey;
}
update() {
this._cssStyle = null;
super.update();
}
/**
* Creates a new HTMLTextStyle object with the same values as this one.
* @returns New cloned HTMLTextStyle object
*/
clone() {
return new HTMLTextStyle({
align: this.align,
breakWords: this.breakWords,
dropShadow: this.dropShadow ? { ...this.dropShadow } : null,
fill: this._fill,
fontFamily: this.fontFamily,
fontSize: this.fontSize,
fontStyle: this.fontStyle,
fontVariant: this.fontVariant,
fontWeight: this.fontWeight,
letterSpacing: this.letterSpacing,
lineHeight: this.lineHeight,
padding: this.padding,
stroke: this._stroke,
whiteSpace: this.whiteSpace,
wordWrap: this.wordWrap,
wordWrapWidth: this.wordWrapWidth,
cssOverrides: this.cssOverrides
});
}
get cssStyle() {
if (!this._cssStyle) {
this._cssStyle = textStyleToCSS(this);
}
return this._cssStyle;
}
/**
* Add a style override, this can be any CSS property
* it will override any built-in style. This is the
* property and the value as a string (e.g., `color: red`).
* This will override any other internal style.
* @param {string} value - CSS style(s) to add.
* @example
* style.addOverride('background-color: red');
*/
addOverride(...value) {
const toAdd = value.filter((v) => !this.cssOverrides.includes(v));
if (toAdd.length > 0) {
this.cssOverrides.push(...toAdd);
this.update();
}
}
/**
* Remove any overrides that match the value.
* @param {string} value - CSS style to remove.
* @example
* style.removeOverride('background-color: red');
*/
removeOverride(...value) {
const toRemove = value.filter((v) => this.cssOverrides.includes(v));
if (toRemove.length > 0) {
this.cssOverrides = this.cssOverrides.filter((v) => !toRemove.includes(v));
this.update();
}
}
set fill(value) {
if (typeof value !== "string" && typeof value !== "number") {
warn("[HTMLTextStyle] only color fill is not supported by HTMLText");
}
super.fill = value;
}
set stroke(value) {
if (value && typeof value !== "string" && typeof value !== "number") {
warn("[HTMLTextStyle] only color stroke is not supported by HTMLText");
}
super.stroke = value;
}
}
export { HTMLTextStyle };
//# sourceMappingURL=HtmlTextStyle.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,16 @@
declare global
{
namespace PixiMixins
{
interface RendererSystems
{
htmlText: import('./HTMLTextSystem').HTMLTextSystem;
}
interface RendererPipes
{
htmlText: import('./HTMLTextPipe').HTMLTextPipe;
}
}
}
export {};

1
node_modules/pixi.js/lib/scene/text-html/init.d.ts generated vendored Normal file
View File

@@ -0,0 +1 @@
export {};

10
node_modules/pixi.js/lib/scene/text-html/init.js generated vendored Normal file
View File

@@ -0,0 +1,10 @@
'use strict';
var Extensions = require('../../extensions/Extensions.js');
var HTMLTextPipe = require('./HTMLTextPipe.js');
var HTMLTextSystem = require('./HTMLTextSystem.js');
"use strict";
Extensions.extensions.add(HTMLTextSystem.HTMLTextSystem);
Extensions.extensions.add(HTMLTextPipe.HTMLTextPipe);
//# sourceMappingURL=init.js.map

1
node_modules/pixi.js/lib/scene/text-html/init.js.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"init.js","sources":["../../../src/scene/text-html/init.ts"],"sourcesContent":["import { extensions } from '../../extensions/Extensions';\nimport { HTMLTextPipe } from './HTMLTextPipe';\nimport { HTMLTextSystem } from './HTMLTextSystem';\n\nextensions.add(HTMLTextSystem);\nextensions.add(HTMLTextPipe);\n"],"names":["extensions","HTMLTextSystem","HTMLTextPipe"],"mappings":";;;;;;;AAIAA,qBAAA,CAAW,IAAIC,6BAAc,CAAA,CAAA;AAC7BD,qBAAA,CAAW,IAAIE,yBAAY,CAAA;;"}

8
node_modules/pixi.js/lib/scene/text-html/init.mjs generated vendored Normal file
View File

@@ -0,0 +1,8 @@
import { extensions } from '../../extensions/Extensions.mjs';
import { HTMLTextPipe } from './HTMLTextPipe.mjs';
import { HTMLTextSystem } from './HTMLTextSystem.mjs';
"use strict";
extensions.add(HTMLTextSystem);
extensions.add(HTMLTextPipe);
//# sourceMappingURL=init.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"init.mjs","sources":["../../../src/scene/text-html/init.ts"],"sourcesContent":["import { extensions } from '../../extensions/Extensions';\nimport { HTMLTextPipe } from './HTMLTextPipe';\nimport { HTMLTextSystem } from './HTMLTextSystem';\n\nextensions.add(HTMLTextSystem);\nextensions.add(HTMLTextPipe);\n"],"names":[],"mappings":";;;;;AAIA,UAAA,CAAW,IAAI,cAAc,CAAA,CAAA;AAC7B,UAAA,CAAW,IAAI,YAAY,CAAA"}

View File

@@ -0,0 +1,9 @@
import type { HTMLTextStyle } from '../HtmlTextStyle';
/**
* Extracts font families from text. It will extract font families from the style, tagStyles and any font families
* embedded in the text. It should also strip out duplicates as it goes.
* @param text - The text to extract font families from
* @param style - The style to extract font families from
* @returns {string[]} - The font families as an array of strings
*/
export declare function extractFontFamilies(text: string, style: HTMLTextStyle): string[];

View File

@@ -0,0 +1,37 @@
'use strict';
"use strict";
function extractFontFamilies(text, style) {
const fontFamily = style.fontFamily;
const fontFamilies = [];
const dedupe = {};
const regex = /font-family:([^;"\s]+)/g;
const matches = text.match(regex);
function addFontFamily(fontFamily2) {
if (!dedupe[fontFamily2]) {
fontFamilies.push(fontFamily2);
dedupe[fontFamily2] = true;
}
}
if (Array.isArray(fontFamily)) {
for (let i = 0; i < fontFamily.length; i++) {
addFontFamily(fontFamily[i]);
}
} else {
addFontFamily(fontFamily);
}
if (matches) {
matches.forEach((match) => {
const fontFamily2 = match.split(":")[1].trim();
addFontFamily(fontFamily2);
});
}
for (const i in style.tagStyles) {
const fontFamily2 = style.tagStyles[i].fontFamily;
addFontFamily(fontFamily2);
}
return fontFamilies;
}
exports.extractFontFamilies = extractFontFamilies;
//# sourceMappingURL=extractFontFamilies.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"extractFontFamilies.js","sources":["../../../../src/scene/text-html/utils/extractFontFamilies.ts"],"sourcesContent":["import type { HTMLTextStyle } from '../HtmlTextStyle';\n\n/**\n * Extracts font families from text. It will extract font families from the style, tagStyles and any font families\n * embedded in the text. It should also strip out duplicates as it goes.\n * @param text - The text to extract font families from\n * @param style - The style to extract font families from\n * @returns {string[]} - The font families as an array of strings\n */\nexport function extractFontFamilies(text: string, style: HTMLTextStyle): string[]\n{\n const fontFamily = style.fontFamily;\n const fontFamilies: string[] = [];\n const dedupe: Record<string, boolean> = {};\n\n // first ensure fonts are loaded inline..\n // find any font..\n const regex = /font-family:([^;\"\\s]+)/g;\n\n const matches = text.match(regex);\n\n function addFontFamily(fontFamily: string)\n {\n if (!dedupe[fontFamily])\n {\n fontFamilies.push(fontFamily);\n\n dedupe[fontFamily] = true;\n }\n }\n\n if (Array.isArray(fontFamily))\n {\n for (let i = 0; i < fontFamily.length; i++)\n {\n addFontFamily(fontFamily[i]);\n }\n }\n else\n {\n addFontFamily(fontFamily);\n }\n\n if (matches)\n {\n matches.forEach((match) =>\n {\n const fontFamily = match.split(':')[1].trim();\n\n addFontFamily(fontFamily);\n });\n }\n\n for (const i in style.tagStyles)\n {\n const fontFamily = style.tagStyles[i].fontFamily;\n\n addFontFamily(fontFamily as string);\n }\n\n return fontFamilies;\n}\n"],"names":["fontFamily"],"mappings":";;;AASgB,SAAA,mBAAA,CAAoB,MAAc,KAClD,EAAA;AACI,EAAA,MAAM,aAAa,KAAM,CAAA,UAAA,CAAA;AACzB,EAAA,MAAM,eAAyB,EAAC,CAAA;AAChC,EAAA,MAAM,SAAkC,EAAC,CAAA;AAIzC,EAAA,MAAM,KAAQ,GAAA,yBAAA,CAAA;AAEd,EAAM,MAAA,OAAA,GAAU,IAAK,CAAA,KAAA,CAAM,KAAK,CAAA,CAAA;AAEhC,EAAA,SAAS,cAAcA,WACvB,EAAA;AACI,IAAI,IAAA,CAAC,MAAOA,CAAAA,WAAU,CACtB,EAAA;AACI,MAAA,YAAA,CAAa,KAAKA,WAAU,CAAA,CAAA;AAE5B,MAAA,MAAA,CAAOA,WAAU,CAAI,GAAA,IAAA,CAAA;AAAA,KACzB;AAAA,GACJ;AAEA,EAAI,IAAA,KAAA,CAAM,OAAQ,CAAA,UAAU,CAC5B,EAAA;AACI,IAAA,KAAA,IAAS,CAAI,GAAA,CAAA,EAAG,CAAI,GAAA,UAAA,CAAW,QAAQ,CACvC,EAAA,EAAA;AACI,MAAc,aAAA,CAAA,UAAA,CAAW,CAAC,CAAC,CAAA,CAAA;AAAA,KAC/B;AAAA,GAGJ,MAAA;AACI,IAAA,aAAA,CAAc,UAAU,CAAA,CAAA;AAAA,GAC5B;AAEA,EAAA,IAAI,OACJ,EAAA;AACI,IAAQ,OAAA,CAAA,OAAA,CAAQ,CAAC,KACjB,KAAA;AACI,MAAA,MAAMA,cAAa,KAAM,CAAA,KAAA,CAAM,GAAG,CAAE,CAAA,CAAC,EAAE,IAAK,EAAA,CAAA;AAE5C,MAAA,aAAA,CAAcA,WAAU,CAAA,CAAA;AAAA,KAC3B,CAAA,CAAA;AAAA,GACL;AAEA,EAAW,KAAA,MAAA,CAAA,IAAK,MAAM,SACtB,EAAA;AACI,IAAA,MAAMA,WAAa,GAAA,KAAA,CAAM,SAAU,CAAA,CAAC,CAAE,CAAA,UAAA,CAAA;AAEtC,IAAA,aAAA,CAAcA,WAAoB,CAAA,CAAA;AAAA,GACtC;AAEA,EAAO,OAAA,YAAA,CAAA;AACX;;;;"}

View File

@@ -0,0 +1,35 @@
"use strict";
function extractFontFamilies(text, style) {
const fontFamily = style.fontFamily;
const fontFamilies = [];
const dedupe = {};
const regex = /font-family:([^;"\s]+)/g;
const matches = text.match(regex);
function addFontFamily(fontFamily2) {
if (!dedupe[fontFamily2]) {
fontFamilies.push(fontFamily2);
dedupe[fontFamily2] = true;
}
}
if (Array.isArray(fontFamily)) {
for (let i = 0; i < fontFamily.length; i++) {
addFontFamily(fontFamily[i]);
}
} else {
addFontFamily(fontFamily);
}
if (matches) {
matches.forEach((match) => {
const fontFamily2 = match.split(":")[1].trim();
addFontFamily(fontFamily2);
});
}
for (const i in style.tagStyles) {
const fontFamily2 = style.tagStyles[i].fontFamily;
addFontFamily(fontFamily2);
}
return fontFamilies;
}
export { extractFontFamilies };
//# sourceMappingURL=extractFontFamilies.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"extractFontFamilies.mjs","sources":["../../../../src/scene/text-html/utils/extractFontFamilies.ts"],"sourcesContent":["import type { HTMLTextStyle } from '../HtmlTextStyle';\n\n/**\n * Extracts font families from text. It will extract font families from the style, tagStyles and any font families\n * embedded in the text. It should also strip out duplicates as it goes.\n * @param text - The text to extract font families from\n * @param style - The style to extract font families from\n * @returns {string[]} - The font families as an array of strings\n */\nexport function extractFontFamilies(text: string, style: HTMLTextStyle): string[]\n{\n const fontFamily = style.fontFamily;\n const fontFamilies: string[] = [];\n const dedupe: Record<string, boolean> = {};\n\n // first ensure fonts are loaded inline..\n // find any font..\n const regex = /font-family:([^;\"\\s]+)/g;\n\n const matches = text.match(regex);\n\n function addFontFamily(fontFamily: string)\n {\n if (!dedupe[fontFamily])\n {\n fontFamilies.push(fontFamily);\n\n dedupe[fontFamily] = true;\n }\n }\n\n if (Array.isArray(fontFamily))\n {\n for (let i = 0; i < fontFamily.length; i++)\n {\n addFontFamily(fontFamily[i]);\n }\n }\n else\n {\n addFontFamily(fontFamily);\n }\n\n if (matches)\n {\n matches.forEach((match) =>\n {\n const fontFamily = match.split(':')[1].trim();\n\n addFontFamily(fontFamily);\n });\n }\n\n for (const i in style.tagStyles)\n {\n const fontFamily = style.tagStyles[i].fontFamily;\n\n addFontFamily(fontFamily as string);\n }\n\n return fontFamilies;\n}\n"],"names":["fontFamily"],"mappings":";AASgB,SAAA,mBAAA,CAAoB,MAAc,KAClD,EAAA;AACI,EAAA,MAAM,aAAa,KAAM,CAAA,UAAA,CAAA;AACzB,EAAA,MAAM,eAAyB,EAAC,CAAA;AAChC,EAAA,MAAM,SAAkC,EAAC,CAAA;AAIzC,EAAA,MAAM,KAAQ,GAAA,yBAAA,CAAA;AAEd,EAAM,MAAA,OAAA,GAAU,IAAK,CAAA,KAAA,CAAM,KAAK,CAAA,CAAA;AAEhC,EAAA,SAAS,cAAcA,WACvB,EAAA;AACI,IAAI,IAAA,CAAC,MAAOA,CAAAA,WAAU,CACtB,EAAA;AACI,MAAA,YAAA,CAAa,KAAKA,WAAU,CAAA,CAAA;AAE5B,MAAA,MAAA,CAAOA,WAAU,CAAI,GAAA,IAAA,CAAA;AAAA,KACzB;AAAA,GACJ;AAEA,EAAI,IAAA,KAAA,CAAM,OAAQ,CAAA,UAAU,CAC5B,EAAA;AACI,IAAA,KAAA,IAAS,CAAI,GAAA,CAAA,EAAG,CAAI,GAAA,UAAA,CAAW,QAAQ,CACvC,EAAA,EAAA;AACI,MAAc,aAAA,CAAA,UAAA,CAAW,CAAC,CAAC,CAAA,CAAA;AAAA,KAC/B;AAAA,GAGJ,MAAA;AACI,IAAA,aAAA,CAAc,UAAU,CAAA,CAAA;AAAA,GAC5B;AAEA,EAAA,IAAI,OACJ,EAAA;AACI,IAAQ,OAAA,CAAA,OAAA,CAAQ,CAAC,KACjB,KAAA;AACI,MAAA,MAAMA,cAAa,KAAM,CAAA,KAAA,CAAM,GAAG,CAAE,CAAA,CAAC,EAAE,IAAK,EAAA,CAAA;AAE5C,MAAA,aAAA,CAAcA,WAAU,CAAA,CAAA;AAAA,KAC3B,CAAA,CAAA;AAAA,GACL;AAEA,EAAW,KAAA,MAAA,CAAA,IAAK,MAAM,SACtB,EAAA;AACI,IAAA,MAAMA,WAAa,GAAA,KAAA,CAAM,SAAU,CAAA,CAAC,CAAE,CAAA,UAAA,CAAA;AAEtC,IAAA,aAAA,CAAcA,WAAoB,CAAA,CAAA;AAAA,GACtC;AAEA,EAAO,OAAA,YAAA,CAAA;AACX;;;;"}

View File

@@ -0,0 +1,16 @@
import type { FontCSSStyleOptions } from './loadFontCSS';
export declare const FontStylePromiseCache: Map<string, Promise<string>>;
/**
* takes the font families and returns a css string that can be injected into a style tag
* It will contain the font families and the font urls encoded as base64
* @param fontFamilies - The font families to load
* @param style - The FontCSSStyleOptions to load the font with (used for the first font family)
* @param defaultOptions - The default options to load the font with (used for the rest of the font families)
* @param defaultOptions.fontWeight - The default font weight
* @param defaultOptions.fontStyle - The default font style
* @returns - The css string
*/
export declare function getFontCss(fontFamilies: string[], style: FontCSSStyleOptions, defaultOptions: {
fontWeight: string;
fontStyle: string;
}): Promise<string>;

View File

@@ -0,0 +1,33 @@
'use strict';
var Cache = require('../../../assets/cache/Cache.js');
var loadFontCSS = require('./loadFontCSS.js');
"use strict";
const FontStylePromiseCache = /* @__PURE__ */ new Map();
async function getFontCss(fontFamilies, style, defaultOptions) {
const fontPromises = fontFamilies.filter((fontFamily) => Cache.Cache.has(`${fontFamily}-and-url`)).map((fontFamily, i) => {
if (!FontStylePromiseCache.has(fontFamily)) {
const { url } = Cache.Cache.get(`${fontFamily}-and-url`);
if (i === 0) {
FontStylePromiseCache.set(fontFamily, loadFontCSS.loadFontCSS({
fontWeight: style.fontWeight,
fontStyle: style.fontStyle,
fontFamily
}, url));
} else {
FontStylePromiseCache.set(fontFamily, loadFontCSS.loadFontCSS({
fontWeight: defaultOptions.fontWeight,
fontStyle: defaultOptions.fontStyle,
fontFamily
}, url));
}
}
return FontStylePromiseCache.get(fontFamily);
});
return (await Promise.all(fontPromises)).join("\n");
}
exports.FontStylePromiseCache = FontStylePromiseCache;
exports.getFontCss = getFontCss;
//# sourceMappingURL=getFontCss.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"getFontCss.js","sources":["../../../../src/scene/text-html/utils/getFontCss.ts"],"sourcesContent":["import { Cache } from '../../../assets/cache/Cache';\nimport { loadFontCSS } from './loadFontCSS';\n\nimport type { FontCSSStyleOptions } from './loadFontCSS';\n\nexport const FontStylePromiseCache = new Map<string, Promise<string>>();\n\n/**\n * takes the font families and returns a css string that can be injected into a style tag\n * It will contain the font families and the font urls encoded as base64\n * @param fontFamilies - The font families to load\n * @param style - The FontCSSStyleOptions to load the font with (used for the first font family)\n * @param defaultOptions - The default options to load the font with (used for the rest of the font families)\n * @param defaultOptions.fontWeight - The default font weight\n * @param defaultOptions.fontStyle - The default font style\n * @returns - The css string\n */\nexport async function getFontCss(\n fontFamilies: string[],\n style: FontCSSStyleOptions,\n defaultOptions: {fontWeight: string, fontStyle: string}\n)\n{\n const fontPromises = fontFamilies\n .filter((fontFamily) => Cache.has(`${fontFamily}-and-url`))\n .map((fontFamily, i) =>\n {\n if (!FontStylePromiseCache.has(fontFamily))\n {\n const { url } = Cache.get(`${fontFamily}-and-url`);\n\n if (i === 0)\n {\n FontStylePromiseCache.set(fontFamily, loadFontCSS({\n fontWeight: style.fontWeight,\n fontStyle: style.fontStyle,\n fontFamily,\n }, url));\n }\n\n else\n {\n FontStylePromiseCache.set(fontFamily, loadFontCSS({\n fontWeight: defaultOptions.fontWeight,\n fontStyle: defaultOptions.fontStyle,\n fontFamily,\n }, url));\n }\n }\n\n return FontStylePromiseCache.get(fontFamily);\n });\n\n return (await Promise.all(fontPromises)).join('\\n');\n}\n"],"names":["Cache","loadFontCSS"],"mappings":";;;;;;AAKa,MAAA,qBAAA,uBAA4B,GAA6B,GAAA;AAYhD,eAAA,UAAA,CAClB,YACA,EAAA,KAAA,EACA,cAEJ,EAAA;AACI,EAAA,MAAM,YAAe,GAAA,YAAA,CAChB,MAAO,CAAA,CAAC,eAAeA,WAAM,CAAA,GAAA,CAAI,CAAG,EAAA,UAAU,UAAU,CAAC,CAAA,CACzD,GAAI,CAAA,CAAC,YAAY,CAClB,KAAA;AACI,IAAA,IAAI,CAAC,qBAAA,CAAsB,GAAI,CAAA,UAAU,CACzC,EAAA;AACI,MAAA,MAAM,EAAE,GAAI,EAAA,GAAIA,YAAM,GAAI,CAAA,CAAA,EAAG,UAAU,CAAU,QAAA,CAAA,CAAA,CAAA;AAEjD,MAAA,IAAI,MAAM,CACV,EAAA;AACI,QAAsB,qBAAA,CAAA,GAAA,CAAI,YAAYC,uBAAY,CAAA;AAAA,UAC9C,YAAY,KAAM,CAAA,UAAA;AAAA,UAClB,WAAW,KAAM,CAAA,SAAA;AAAA,UACjB,UAAA;AAAA,SACJ,EAAG,GAAG,CAAC,CAAA,CAAA;AAAA,OAIX,MAAA;AACI,QAAsB,qBAAA,CAAA,GAAA,CAAI,YAAYA,uBAAY,CAAA;AAAA,UAC9C,YAAY,cAAe,CAAA,UAAA;AAAA,UAC3B,WAAW,cAAe,CAAA,SAAA;AAAA,UAC1B,UAAA;AAAA,SACJ,EAAG,GAAG,CAAC,CAAA,CAAA;AAAA,OACX;AAAA,KACJ;AAEA,IAAO,OAAA,qBAAA,CAAsB,IAAI,UAAU,CAAA,CAAA;AAAA,GAC9C,CAAA,CAAA;AAEL,EAAA,OAAA,CAAQ,MAAM,OAAQ,CAAA,GAAA,CAAI,YAAY,CAAA,EAAG,KAAK,IAAI,CAAA,CAAA;AACtD;;;;;"}

View File

@@ -0,0 +1,30 @@
import { Cache } from '../../../assets/cache/Cache.mjs';
import { loadFontCSS } from './loadFontCSS.mjs';
"use strict";
const FontStylePromiseCache = /* @__PURE__ */ new Map();
async function getFontCss(fontFamilies, style, defaultOptions) {
const fontPromises = fontFamilies.filter((fontFamily) => Cache.has(`${fontFamily}-and-url`)).map((fontFamily, i) => {
if (!FontStylePromiseCache.has(fontFamily)) {
const { url } = Cache.get(`${fontFamily}-and-url`);
if (i === 0) {
FontStylePromiseCache.set(fontFamily, loadFontCSS({
fontWeight: style.fontWeight,
fontStyle: style.fontStyle,
fontFamily
}, url));
} else {
FontStylePromiseCache.set(fontFamily, loadFontCSS({
fontWeight: defaultOptions.fontWeight,
fontStyle: defaultOptions.fontStyle,
fontFamily
}, url));
}
}
return FontStylePromiseCache.get(fontFamily);
});
return (await Promise.all(fontPromises)).join("\n");
}
export { FontStylePromiseCache, getFontCss };
//# sourceMappingURL=getFontCss.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"getFontCss.mjs","sources":["../../../../src/scene/text-html/utils/getFontCss.ts"],"sourcesContent":["import { Cache } from '../../../assets/cache/Cache';\nimport { loadFontCSS } from './loadFontCSS';\n\nimport type { FontCSSStyleOptions } from './loadFontCSS';\n\nexport const FontStylePromiseCache = new Map<string, Promise<string>>();\n\n/**\n * takes the font families and returns a css string that can be injected into a style tag\n * It will contain the font families and the font urls encoded as base64\n * @param fontFamilies - The font families to load\n * @param style - The FontCSSStyleOptions to load the font with (used for the first font family)\n * @param defaultOptions - The default options to load the font with (used for the rest of the font families)\n * @param defaultOptions.fontWeight - The default font weight\n * @param defaultOptions.fontStyle - The default font style\n * @returns - The css string\n */\nexport async function getFontCss(\n fontFamilies: string[],\n style: FontCSSStyleOptions,\n defaultOptions: {fontWeight: string, fontStyle: string}\n)\n{\n const fontPromises = fontFamilies\n .filter((fontFamily) => Cache.has(`${fontFamily}-and-url`))\n .map((fontFamily, i) =>\n {\n if (!FontStylePromiseCache.has(fontFamily))\n {\n const { url } = Cache.get(`${fontFamily}-and-url`);\n\n if (i === 0)\n {\n FontStylePromiseCache.set(fontFamily, loadFontCSS({\n fontWeight: style.fontWeight,\n fontStyle: style.fontStyle,\n fontFamily,\n }, url));\n }\n\n else\n {\n FontStylePromiseCache.set(fontFamily, loadFontCSS({\n fontWeight: defaultOptions.fontWeight,\n fontStyle: defaultOptions.fontStyle,\n fontFamily,\n }, url));\n }\n }\n\n return FontStylePromiseCache.get(fontFamily);\n });\n\n return (await Promise.all(fontPromises)).join('\\n');\n}\n"],"names":[],"mappings":";;;;AAKa,MAAA,qBAAA,uBAA4B,GAA6B,GAAA;AAYhD,eAAA,UAAA,CAClB,YACA,EAAA,KAAA,EACA,cAEJ,EAAA;AACI,EAAA,MAAM,YAAe,GAAA,YAAA,CAChB,MAAO,CAAA,CAAC,eAAe,KAAM,CAAA,GAAA,CAAI,CAAG,EAAA,UAAU,UAAU,CAAC,CAAA,CACzD,GAAI,CAAA,CAAC,YAAY,CAClB,KAAA;AACI,IAAA,IAAI,CAAC,qBAAA,CAAsB,GAAI,CAAA,UAAU,CACzC,EAAA;AACI,MAAA,MAAM,EAAE,GAAI,EAAA,GAAI,MAAM,GAAI,CAAA,CAAA,EAAG,UAAU,CAAU,QAAA,CAAA,CAAA,CAAA;AAEjD,MAAA,IAAI,MAAM,CACV,EAAA;AACI,QAAsB,qBAAA,CAAA,GAAA,CAAI,YAAY,WAAY,CAAA;AAAA,UAC9C,YAAY,KAAM,CAAA,UAAA;AAAA,UAClB,WAAW,KAAM,CAAA,SAAA;AAAA,UACjB,UAAA;AAAA,SACJ,EAAG,GAAG,CAAC,CAAA,CAAA;AAAA,OAIX,MAAA;AACI,QAAsB,qBAAA,CAAA,GAAA,CAAI,YAAY,WAAY,CAAA;AAAA,UAC9C,YAAY,cAAe,CAAA,UAAA;AAAA,UAC3B,WAAW,cAAe,CAAA,SAAA;AAAA,UAC1B,UAAA;AAAA,SACJ,EAAG,GAAG,CAAC,CAAA,CAAA;AAAA,OACX;AAAA,KACJ;AAEA,IAAO,OAAA,qBAAA,CAAsB,IAAI,UAAU,CAAA,CAAA;AAAA,GAC9C,CAAA,CAAA;AAEL,EAAA,OAAA,CAAQ,MAAM,OAAQ,CAAA,GAAA,CAAI,YAAY,CAAA,EAAG,KAAK,IAAI,CAAA,CAAA;AACtD;;;;"}

View File

@@ -0,0 +1,12 @@
import type { HTMLTextRenderData } from '../HTMLTextRenderData';
import type { HTMLTextStyle } from '../HtmlTextStyle';
/**
* takes all the data and returns a svg url string can be loaded by an image element
* @param text - The text to measure
* @param style - The style to use
* @param resolution - The resolution to use
* @param fontCSS - The font css to use
* @param htmlTextData - The HTMLTextRenderData to write the SVG to
* @returns - The SVG as a url string
*/
export declare function getSVGUrl(text: string, style: HTMLTextStyle, resolution: number, fontCSS: string, htmlTextData: HTMLTextRenderData): string;

View File

@@ -0,0 +1,16 @@
'use strict';
"use strict";
function getSVGUrl(text, style, resolution, fontCSS, htmlTextData) {
const { domElement, styleElement, svgRoot } = htmlTextData;
domElement.innerHTML = `<style>${style.cssStyle}</style><div style='padding:0;'>${text}</div>`;
domElement.setAttribute("style", `transform: scale(${resolution});transform-origin: top left; display: inline-block`);
styleElement.textContent = fontCSS;
const { width, height } = htmlTextData.image;
svgRoot.setAttribute("width", width.toString());
svgRoot.setAttribute("height", height.toString());
return new XMLSerializer().serializeToString(svgRoot);
}
exports.getSVGUrl = getSVGUrl;
//# sourceMappingURL=getSVGUrl.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"getSVGUrl.js","sources":["../../../../src/scene/text-html/utils/getSVGUrl.ts"],"sourcesContent":["import type { HTMLTextRenderData } from '../HTMLTextRenderData';\nimport type { HTMLTextStyle } from '../HtmlTextStyle';\n\n/**\n * takes all the data and returns a svg url string can be loaded by an image element\n * @param text - The text to measure\n * @param style - The style to use\n * @param resolution - The resolution to use\n * @param fontCSS - The font css to use\n * @param htmlTextData - The HTMLTextRenderData to write the SVG to\n * @returns - The SVG as a url string\n */\nexport function getSVGUrl(\n text: string,\n style: HTMLTextStyle,\n resolution: number,\n fontCSS: string,\n htmlTextData: HTMLTextRenderData\n)\n{\n const { domElement, styleElement, svgRoot } = htmlTextData;\n\n domElement.innerHTML = `<style>${style.cssStyle}</style><div style='padding:0;'>${text}</div>`;\n domElement.setAttribute('style', `transform: scale(${resolution});transform-origin: top left; display: inline-block`);\n styleElement.textContent = fontCSS;\n\n const { width, height } = htmlTextData.image;\n\n svgRoot.setAttribute('width', width.toString());\n svgRoot.setAttribute('height', height.toString());\n\n return new XMLSerializer().serializeToString(svgRoot);\n}\n"],"names":[],"mappings":";;;AAYO,SAAS,SACZ,CAAA,IAAA,EACA,KACA,EAAA,UAAA,EACA,SACA,YAEJ,EAAA;AACI,EAAA,MAAM,EAAE,UAAA,EAAY,YAAc,EAAA,OAAA,EAAY,GAAA,YAAA,CAAA;AAE9C,EAAA,UAAA,CAAW,SAAY,GAAA,CAAA,OAAA,EAAU,KAAM,CAAA,QAAQ,mCAAmC,IAAI,CAAA,MAAA,CAAA,CAAA;AACtF,EAAA,UAAA,CAAW,YAAa,CAAA,OAAA,EAAS,CAAoB,iBAAA,EAAA,UAAU,CAAqD,mDAAA,CAAA,CAAA,CAAA;AACpH,EAAA,YAAA,CAAa,WAAc,GAAA,OAAA,CAAA;AAE3B,EAAA,MAAM,EAAE,KAAA,EAAO,MAAO,EAAA,GAAI,YAAa,CAAA,KAAA,CAAA;AAEvC,EAAA,OAAA,CAAQ,YAAa,CAAA,OAAA,EAAS,KAAM,CAAA,QAAA,EAAU,CAAA,CAAA;AAC9C,EAAA,OAAA,CAAQ,YAAa,CAAA,QAAA,EAAU,MAAO,CAAA,QAAA,EAAU,CAAA,CAAA;AAEhD,EAAA,OAAO,IAAI,aAAA,EAAgB,CAAA,iBAAA,CAAkB,OAAO,CAAA,CAAA;AACxD;;;;"}

View File

@@ -0,0 +1,14 @@
"use strict";
function getSVGUrl(text, style, resolution, fontCSS, htmlTextData) {
const { domElement, styleElement, svgRoot } = htmlTextData;
domElement.innerHTML = `<style>${style.cssStyle}</style><div style='padding:0;'>${text}</div>`;
domElement.setAttribute("style", `transform: scale(${resolution});transform-origin: top left; display: inline-block`);
styleElement.textContent = fontCSS;
const { width, height } = htmlTextData.image;
svgRoot.setAttribute("width", width.toString());
svgRoot.setAttribute("height", height.toString());
return new XMLSerializer().serializeToString(svgRoot);
}
export { getSVGUrl };
//# sourceMappingURL=getSVGUrl.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"getSVGUrl.mjs","sources":["../../../../src/scene/text-html/utils/getSVGUrl.ts"],"sourcesContent":["import type { HTMLTextRenderData } from '../HTMLTextRenderData';\nimport type { HTMLTextStyle } from '../HtmlTextStyle';\n\n/**\n * takes all the data and returns a svg url string can be loaded by an image element\n * @param text - The text to measure\n * @param style - The style to use\n * @param resolution - The resolution to use\n * @param fontCSS - The font css to use\n * @param htmlTextData - The HTMLTextRenderData to write the SVG to\n * @returns - The SVG as a url string\n */\nexport function getSVGUrl(\n text: string,\n style: HTMLTextStyle,\n resolution: number,\n fontCSS: string,\n htmlTextData: HTMLTextRenderData\n)\n{\n const { domElement, styleElement, svgRoot } = htmlTextData;\n\n domElement.innerHTML = `<style>${style.cssStyle}</style><div style='padding:0;'>${text}</div>`;\n domElement.setAttribute('style', `transform: scale(${resolution});transform-origin: top left; display: inline-block`);\n styleElement.textContent = fontCSS;\n\n const { width, height } = htmlTextData.image;\n\n svgRoot.setAttribute('width', width.toString());\n svgRoot.setAttribute('height', height.toString());\n\n return new XMLSerializer().serializeToString(svgRoot);\n}\n"],"names":[],"mappings":";AAYO,SAAS,SACZ,CAAA,IAAA,EACA,KACA,EAAA,UAAA,EACA,SACA,YAEJ,EAAA;AACI,EAAA,MAAM,EAAE,UAAA,EAAY,YAAc,EAAA,OAAA,EAAY,GAAA,YAAA,CAAA;AAE9C,EAAA,UAAA,CAAW,SAAY,GAAA,CAAA,OAAA,EAAU,KAAM,CAAA,QAAQ,mCAAmC,IAAI,CAAA,MAAA,CAAA,CAAA;AACtF,EAAA,UAAA,CAAW,YAAa,CAAA,OAAA,EAAS,CAAoB,iBAAA,EAAA,UAAU,CAAqD,mDAAA,CAAA,CAAA,CAAA;AACpH,EAAA,YAAA,CAAa,WAAc,GAAA,OAAA,CAAA;AAE3B,EAAA,MAAM,EAAE,KAAA,EAAO,MAAO,EAAA,GAAI,YAAa,CAAA,KAAA,CAAA;AAEvC,EAAA,OAAA,CAAQ,YAAa,CAAA,OAAA,EAAS,KAAM,CAAA,QAAA,EAAU,CAAA,CAAA;AAC9C,EAAA,OAAA,CAAQ,YAAa,CAAA,QAAA,EAAU,MAAO,CAAA,QAAA,EAAU,CAAA,CAAA;AAEhD,EAAA,OAAO,IAAI,aAAA,EAAgB,CAAA,iBAAA,CAAkB,OAAO,CAAA,CAAA;AACxD;;;;"}

View File

@@ -0,0 +1,12 @@
/**
* This function converts an image to a canvas, and returns the canvas.
* It is used to convert images to canvases to work around a CORS issue where WebGPU cannot
* upload an SVGImage to a texture.
*
* It uses the CanvasPool to get an optimal canvas and context, and then draws the image onto it.
* This canvas is immediately returned to the CanvasPool for reuse, so use the result straight away!
* (eg upload it to the GPU!)
* @param image - The image to convert to a canvas.
* @param resolution - The resolution of the canvas.
*/
export declare function getTemporaryCanvasFromImage(image: HTMLImageElement, resolution: number): HTMLCanvasElement;

View File

@@ -0,0 +1,20 @@
'use strict';
var CanvasPool = require('../../../rendering/renderers/shared/texture/CanvasPool.js');
"use strict";
function getTemporaryCanvasFromImage(image, resolution) {
const canvasAndContext = CanvasPool.CanvasPool.getOptimalCanvasAndContext(
image.width,
image.height,
resolution
);
const { context } = canvasAndContext;
context.clearRect(0, 0, image.width, image.height);
context.drawImage(image, 0, 0);
CanvasPool.CanvasPool.returnCanvasAndContext(canvasAndContext);
return canvasAndContext.canvas;
}
exports.getTemporaryCanvasFromImage = getTemporaryCanvasFromImage;
//# sourceMappingURL=getTemporaryCanvasFromImage.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"getTemporaryCanvasFromImage.js","sources":["../../../../src/scene/text-html/utils/getTemporaryCanvasFromImage.ts"],"sourcesContent":["import { CanvasPool } from '../../../rendering/renderers/shared/texture/CanvasPool';\n\n/**\n * This function converts an image to a canvas, and returns the canvas.\n * It is used to convert images to canvases to work around a CORS issue where WebGPU cannot\n * upload an SVGImage to a texture.\n *\n * It uses the CanvasPool to get an optimal canvas and context, and then draws the image onto it.\n * This canvas is immediately returned to the CanvasPool for reuse, so use the result straight away!\n * (eg upload it to the GPU!)\n * @param image - The image to convert to a canvas.\n * @param resolution - The resolution of the canvas.\n */\nexport function getTemporaryCanvasFromImage(image: HTMLImageElement, resolution: number): HTMLCanvasElement\n{\n // Get an optimal canvas and context from the CanvasPool, based on the\n // dimensions of the image and the desired resolution.\n const canvasAndContext = CanvasPool.getOptimalCanvasAndContext(\n image.width,\n image.height,\n resolution\n );\n\n // Clear the context of the canvas, and draw the image onto it.\n const { context } = canvasAndContext;\n\n context.clearRect(0, 0, image.width, image.height);\n context.drawImage(image, 0, 0);\n\n // Return the canvas and context to the CanvasPool.\n CanvasPool.returnCanvasAndContext(canvasAndContext);\n\n // Return the canvas.\n return canvasAndContext.canvas as HTMLCanvasElement;\n}\n\n"],"names":["CanvasPool"],"mappings":";;;;;AAagB,SAAA,2BAAA,CAA4B,OAAyB,UACrE,EAAA;AAGI,EAAA,MAAM,mBAAmBA,qBAAW,CAAA,0BAAA;AAAA,IAChC,KAAM,CAAA,KAAA;AAAA,IACN,KAAM,CAAA,MAAA;AAAA,IACN,UAAA;AAAA,GACJ,CAAA;AAGA,EAAM,MAAA,EAAE,SAAY,GAAA,gBAAA,CAAA;AAEpB,EAAA,OAAA,CAAQ,UAAU,CAAG,EAAA,CAAA,EAAG,KAAM,CAAA,KAAA,EAAO,MAAM,MAAM,CAAA,CAAA;AACjD,EAAQ,OAAA,CAAA,SAAA,CAAU,KAAO,EAAA,CAAA,EAAG,CAAC,CAAA,CAAA;AAG7B,EAAAA,qBAAA,CAAW,uBAAuB,gBAAgB,CAAA,CAAA;AAGlD,EAAA,OAAO,gBAAiB,CAAA,MAAA,CAAA;AAC5B;;;;"}

View File

@@ -0,0 +1,18 @@
import { CanvasPool } from '../../../rendering/renderers/shared/texture/CanvasPool.mjs';
"use strict";
function getTemporaryCanvasFromImage(image, resolution) {
const canvasAndContext = CanvasPool.getOptimalCanvasAndContext(
image.width,
image.height,
resolution
);
const { context } = canvasAndContext;
context.clearRect(0, 0, image.width, image.height);
context.drawImage(image, 0, 0);
CanvasPool.returnCanvasAndContext(canvasAndContext);
return canvasAndContext.canvas;
}
export { getTemporaryCanvasFromImage };
//# sourceMappingURL=getTemporaryCanvasFromImage.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"getTemporaryCanvasFromImage.mjs","sources":["../../../../src/scene/text-html/utils/getTemporaryCanvasFromImage.ts"],"sourcesContent":["import { CanvasPool } from '../../../rendering/renderers/shared/texture/CanvasPool';\n\n/**\n * This function converts an image to a canvas, and returns the canvas.\n * It is used to convert images to canvases to work around a CORS issue where WebGPU cannot\n * upload an SVGImage to a texture.\n *\n * It uses the CanvasPool to get an optimal canvas and context, and then draws the image onto it.\n * This canvas is immediately returned to the CanvasPool for reuse, so use the result straight away!\n * (eg upload it to the GPU!)\n * @param image - The image to convert to a canvas.\n * @param resolution - The resolution of the canvas.\n */\nexport function getTemporaryCanvasFromImage(image: HTMLImageElement, resolution: number): HTMLCanvasElement\n{\n // Get an optimal canvas and context from the CanvasPool, based on the\n // dimensions of the image and the desired resolution.\n const canvasAndContext = CanvasPool.getOptimalCanvasAndContext(\n image.width,\n image.height,\n resolution\n );\n\n // Clear the context of the canvas, and draw the image onto it.\n const { context } = canvasAndContext;\n\n context.clearRect(0, 0, image.width, image.height);\n context.drawImage(image, 0, 0);\n\n // Return the canvas and context to the CanvasPool.\n CanvasPool.returnCanvasAndContext(canvasAndContext);\n\n // Return the canvas.\n return canvasAndContext.canvas as HTMLCanvasElement;\n}\n\n"],"names":[],"mappings":";;;AAagB,SAAA,2BAAA,CAA4B,OAAyB,UACrE,EAAA;AAGI,EAAA,MAAM,mBAAmB,UAAW,CAAA,0BAAA;AAAA,IAChC,KAAM,CAAA,KAAA;AAAA,IACN,KAAM,CAAA,MAAA;AAAA,IACN,UAAA;AAAA,GACJ,CAAA;AAGA,EAAM,MAAA,EAAE,SAAY,GAAA,gBAAA,CAAA;AAEpB,EAAA,OAAA,CAAQ,UAAU,CAAG,EAAA,CAAA,EAAG,KAAM,CAAA,KAAA,EAAO,MAAM,MAAM,CAAA,CAAA;AACjD,EAAQ,OAAA,CAAA,SAAA,CAAU,KAAO,EAAA,CAAA,EAAG,CAAC,CAAA,CAAA;AAG7B,EAAA,UAAA,CAAW,uBAAuB,gBAAgB,CAAA,CAAA;AAGlD,EAAA,OAAO,gBAAiB,CAAA,MAAA,CAAA;AAC5B;;;;"}

View File

@@ -0,0 +1,6 @@
/**
* Resolves a font url to a base64 string
* @param url - The url to load the font from
* @returns - The font as a base64 string
*/
export declare function loadFontAsBase64(url: string): Promise<string>;

View File

@@ -0,0 +1,19 @@
'use strict';
var adapter = require('../../../environment/adapter.js');
"use strict";
async function loadFontAsBase64(url) {
const response = await adapter.DOMAdapter.get().fetch(url);
const blob = await response.blob();
const reader = new FileReader();
const dataSrc = await new Promise((resolve, reject) => {
reader.onloadend = () => resolve(reader.result);
reader.onerror = reject;
reader.readAsDataURL(blob);
});
return dataSrc;
}
exports.loadFontAsBase64 = loadFontAsBase64;
//# sourceMappingURL=loadFontAsBase64.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"loadFontAsBase64.js","sources":["../../../../src/scene/text-html/utils/loadFontAsBase64.ts"],"sourcesContent":["import { DOMAdapter } from '../../../environment/adapter';\n\n/**\n * Resolves a font url to a base64 string\n * @param url - The url to load the font from\n * @returns - The font as a base64 string\n */\nexport async function loadFontAsBase64(url: string): Promise<string>\n{\n const response = await DOMAdapter.get().fetch(url);\n\n const blob = await response.blob();\n\n const reader = new FileReader();\n\n const dataSrc: string = await new Promise((resolve, reject) =>\n {\n reader.onloadend = () => resolve(reader.result as string);\n reader.onerror = reject;\n reader.readAsDataURL(blob);\n });\n\n return dataSrc;\n}\n"],"names":["DOMAdapter"],"mappings":";;;;;AAOA,eAAsB,iBAAiB,GACvC,EAAA;AACI,EAAA,MAAM,WAAW,MAAMA,kBAAA,CAAW,GAAI,EAAA,CAAE,MAAM,GAAG,CAAA,CAAA;AAEjD,EAAM,MAAA,IAAA,GAAO,MAAM,QAAA,CAAS,IAAK,EAAA,CAAA;AAEjC,EAAM,MAAA,MAAA,GAAS,IAAI,UAAW,EAAA,CAAA;AAE9B,EAAA,MAAM,UAAkB,MAAM,IAAI,OAAQ,CAAA,CAAC,SAAS,MACpD,KAAA;AACI,IAAA,MAAA,CAAO,SAAY,GAAA,MAAM,OAAQ,CAAA,MAAA,CAAO,MAAgB,CAAA,CAAA;AACxD,IAAA,MAAA,CAAO,OAAU,GAAA,MAAA,CAAA;AACjB,IAAA,MAAA,CAAO,cAAc,IAAI,CAAA,CAAA;AAAA,GAC5B,CAAA,CAAA;AAED,EAAO,OAAA,OAAA,CAAA;AACX;;;;"}

View File

@@ -0,0 +1,17 @@
import { DOMAdapter } from '../../../environment/adapter.mjs';
"use strict";
async function loadFontAsBase64(url) {
const response = await DOMAdapter.get().fetch(url);
const blob = await response.blob();
const reader = new FileReader();
const dataSrc = await new Promise((resolve, reject) => {
reader.onloadend = () => resolve(reader.result);
reader.onerror = reject;
reader.readAsDataURL(blob);
});
return dataSrc;
}
export { loadFontAsBase64 };
//# sourceMappingURL=loadFontAsBase64.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"loadFontAsBase64.mjs","sources":["../../../../src/scene/text-html/utils/loadFontAsBase64.ts"],"sourcesContent":["import { DOMAdapter } from '../../../environment/adapter';\n\n/**\n * Resolves a font url to a base64 string\n * @param url - The url to load the font from\n * @returns - The font as a base64 string\n */\nexport async function loadFontAsBase64(url: string): Promise<string>\n{\n const response = await DOMAdapter.get().fetch(url);\n\n const blob = await response.blob();\n\n const reader = new FileReader();\n\n const dataSrc: string = await new Promise((resolve, reject) =>\n {\n reader.onloadend = () => resolve(reader.result as string);\n reader.onerror = reject;\n reader.readAsDataURL(blob);\n });\n\n return dataSrc;\n}\n"],"names":[],"mappings":";;;AAOA,eAAsB,iBAAiB,GACvC,EAAA;AACI,EAAA,MAAM,WAAW,MAAM,UAAA,CAAW,GAAI,EAAA,CAAE,MAAM,GAAG,CAAA,CAAA;AAEjD,EAAM,MAAA,IAAA,GAAO,MAAM,QAAA,CAAS,IAAK,EAAA,CAAA;AAEjC,EAAM,MAAA,MAAA,GAAS,IAAI,UAAW,EAAA,CAAA;AAE9B,EAAA,MAAM,UAAkB,MAAM,IAAI,OAAQ,CAAA,CAAC,SAAS,MACpD,KAAA;AACI,IAAA,MAAA,CAAO,SAAY,GAAA,MAAM,OAAQ,CAAA,MAAA,CAAO,MAAgB,CAAA,CAAA;AACxD,IAAA,MAAA,CAAO,OAAU,GAAA,MAAA,CAAA;AACjB,IAAA,MAAA,CAAO,cAAc,IAAI,CAAA,CAAA;AAAA,GAC5B,CAAA,CAAA;AAED,EAAO,OAAA,OAAA,CAAA;AACX;;;;"}

View File

@@ -0,0 +1,13 @@
export interface FontCSSStyleOptions {
fontFamily: string | string[];
fontWeight: string;
fontStyle: string;
}
/**
* This will take a font url and a style and return a css string that can be injected into a style tag
* This will contain inlined base64 font and the font family information
* @param style - the style to generate the css for
* @param url - The url to load the font from
* @returns - The css string
*/
export declare function loadFontCSS(style: FontCSSStyleOptions, url: string): Promise<string>;

View File

@@ -0,0 +1,17 @@
'use strict';
var loadFontAsBase64 = require('./loadFontAsBase64.js');
"use strict";
async function loadFontCSS(style, url) {
const dataSrc = await loadFontAsBase64.loadFontAsBase64(url);
return `@font-face {
font-family: "${style.fontFamily}";
src: url('${dataSrc}');
font-weight: ${style.fontWeight};
font-style: ${style.fontStyle};
}`;
}
exports.loadFontCSS = loadFontCSS;
//# sourceMappingURL=loadFontCSS.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"loadFontCSS.js","sources":["../../../../src/scene/text-html/utils/loadFontCSS.ts"],"sourcesContent":["import { loadFontAsBase64 } from './loadFontAsBase64';\n\nexport interface FontCSSStyleOptions\n{\n fontFamily: string | string[]\n fontWeight: string\n fontStyle: string\n}\n\n/**\n * This will take a font url and a style and return a css string that can be injected into a style tag\n * This will contain inlined base64 font and the font family information\n * @param style - the style to generate the css for\n * @param url - The url to load the font from\n * @returns - The css string\n */\nexport async function loadFontCSS(style: FontCSSStyleOptions, url: string): Promise<string>\n{\n const dataSrc = await loadFontAsBase64(url);\n\n return `@font-face {\n font-family: \"${style.fontFamily}\";\n src: url('${dataSrc}');\n font-weight: ${style.fontWeight};\n font-style: ${style.fontStyle};\n }`;\n}\n"],"names":["loadFontAsBase64"],"mappings":";;;;;AAgBsB,eAAA,WAAA,CAAY,OAA4B,GAC9D,EAAA;AACI,EAAM,MAAA,OAAA,GAAU,MAAMA,iCAAA,CAAiB,GAAG,CAAA,CAAA;AAE1C,EAAO,OAAA,CAAA;AAAA,sBAAA,EACa,MAAM,UAAU,CAAA;AAAA,kBAAA,EACpB,OAAO,CAAA;AAAA,qBAAA,EACJ,MAAM,UAAU,CAAA;AAAA,oBAAA,EACjB,MAAM,SAAS,CAAA;AAAA,KAAA,CAAA,CAAA;AAErC;;;;"}

View File

@@ -0,0 +1,15 @@
import { loadFontAsBase64 } from './loadFontAsBase64.mjs';
"use strict";
async function loadFontCSS(style, url) {
const dataSrc = await loadFontAsBase64(url);
return `@font-face {
font-family: "${style.fontFamily}";
src: url('${dataSrc}');
font-weight: ${style.fontWeight};
font-style: ${style.fontStyle};
}`;
}
export { loadFontCSS };
//# sourceMappingURL=loadFontCSS.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"loadFontCSS.mjs","sources":["../../../../src/scene/text-html/utils/loadFontCSS.ts"],"sourcesContent":["import { loadFontAsBase64 } from './loadFontAsBase64';\n\nexport interface FontCSSStyleOptions\n{\n fontFamily: string | string[]\n fontWeight: string\n fontStyle: string\n}\n\n/**\n * This will take a font url and a style and return a css string that can be injected into a style tag\n * This will contain inlined base64 font and the font family information\n * @param style - the style to generate the css for\n * @param url - The url to load the font from\n * @returns - The css string\n */\nexport async function loadFontCSS(style: FontCSSStyleOptions, url: string): Promise<string>\n{\n const dataSrc = await loadFontAsBase64(url);\n\n return `@font-face {\n font-family: \"${style.fontFamily}\";\n src: url('${dataSrc}');\n font-weight: ${style.fontWeight};\n font-style: ${style.fontStyle};\n }`;\n}\n"],"names":[],"mappings":";;;AAgBsB,eAAA,WAAA,CAAY,OAA4B,GAC9D,EAAA;AACI,EAAM,MAAA,OAAA,GAAU,MAAM,gBAAA,CAAiB,GAAG,CAAA,CAAA;AAE1C,EAAO,OAAA,CAAA;AAAA,sBAAA,EACa,MAAM,UAAU,CAAA;AAAA,kBAAA,EACpB,OAAO,CAAA;AAAA,qBAAA,EACJ,MAAM,UAAU,CAAA;AAAA,oBAAA,EACjB,MAAM,SAAS,CAAA;AAAA,KAAA,CAAA,CAAA;AAErC;;;;"}

View File

@@ -0,0 +1,11 @@
/**
* This function loads an SVG image into an HTMLImageElement.
* The image can then be uploaded as texture to the GPU.
* iOS has a bug where embedded fonts are not available immediately after the image loads,
* so we wait an arbitrary amount of time before resolving the promise.
* @param image - The image to load the SVG into
* @param url - The url to load the SVG from
* @param delay - Whether to delay the load
* @returns - A promise that resolves when the image has loaded
*/
export declare function loadSVGImage(image: HTMLImageElement, url: string, delay: boolean): Promise<void>;

View File

@@ -0,0 +1,18 @@
'use strict';
"use strict";
function loadSVGImage(image, url, delay) {
return new Promise(async (resolve) => {
if (delay) {
await new Promise((resolve2) => setTimeout(resolve2, 100));
}
image.onload = () => {
resolve();
};
image.src = `data:image/svg+xml;charset=utf8,${encodeURIComponent(url)}`;
image.crossOrigin = "anonymous";
});
}
exports.loadSVGImage = loadSVGImage;
//# sourceMappingURL=loadSVGImage.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"loadSVGImage.js","sources":["../../../../src/scene/text-html/utils/loadSVGImage.ts"],"sourcesContent":["/**\n * This function loads an SVG image into an HTMLImageElement.\n * The image can then be uploaded as texture to the GPU.\n * iOS has a bug where embedded fonts are not available immediately after the image loads,\n * so we wait an arbitrary amount of time before resolving the promise.\n * @param image - The image to load the SVG into\n * @param url - The url to load the SVG from\n * @param delay - Whether to delay the load\n * @returns - A promise that resolves when the image has loaded\n */\nexport function loadSVGImage(image: HTMLImageElement, url: string, delay: boolean)\n{\n return new Promise<void>(async (resolve) =>\n {\n // Safari has a known bug where embedded fonts are not available\n // immediately after the image loads, to compensate we wait an\n // arbitrary amount of time\n // @see https://bugs.webkit.org/show_bug.cgi?id=219770\n if (delay)\n {\n await new Promise<void>((resolve) => setTimeout(resolve, 100));\n }\n\n image.onload = () =>\n {\n resolve();\n };\n\n image.src = `data:image/svg+xml;charset=utf8,${encodeURIComponent(url)}`;\n image.crossOrigin = 'anonymous';\n });\n}\n"],"names":["resolve"],"mappings":";;;AAUgB,SAAA,YAAA,CAAa,KAAyB,EAAA,GAAA,EAAa,KACnE,EAAA;AACI,EAAO,OAAA,IAAI,OAAc,CAAA,OAAO,OAChC,KAAA;AAKI,IAAA,IAAI,KACJ,EAAA;AACI,MAAA,MAAM,IAAI,OAAc,CAAA,CAACA,aAAY,UAAWA,CAAAA,QAAAA,EAAS,GAAG,CAAC,CAAA,CAAA;AAAA,KACjE;AAEA,IAAA,KAAA,CAAM,SAAS,MACf;AACI,MAAQ,OAAA,EAAA,CAAA;AAAA,KACZ,CAAA;AAEA,IAAA,KAAA,CAAM,GAAM,GAAA,CAAA,gCAAA,EAAmC,kBAAmB,CAAA,GAAG,CAAC,CAAA,CAAA,CAAA;AACtE,IAAA,KAAA,CAAM,WAAc,GAAA,WAAA,CAAA;AAAA,GACvB,CAAA,CAAA;AACL;;;;"}

View File

@@ -0,0 +1,16 @@
"use strict";
function loadSVGImage(image, url, delay) {
return new Promise(async (resolve) => {
if (delay) {
await new Promise((resolve2) => setTimeout(resolve2, 100));
}
image.onload = () => {
resolve();
};
image.src = `data:image/svg+xml;charset=utf8,${encodeURIComponent(url)}`;
image.crossOrigin = "anonymous";
});
}
export { loadSVGImage };
//# sourceMappingURL=loadSVGImage.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"loadSVGImage.mjs","sources":["../../../../src/scene/text-html/utils/loadSVGImage.ts"],"sourcesContent":["/**\n * This function loads an SVG image into an HTMLImageElement.\n * The image can then be uploaded as texture to the GPU.\n * iOS has a bug where embedded fonts are not available immediately after the image loads,\n * so we wait an arbitrary amount of time before resolving the promise.\n * @param image - The image to load the SVG into\n * @param url - The url to load the SVG from\n * @param delay - Whether to delay the load\n * @returns - A promise that resolves when the image has loaded\n */\nexport function loadSVGImage(image: HTMLImageElement, url: string, delay: boolean)\n{\n return new Promise<void>(async (resolve) =>\n {\n // Safari has a known bug where embedded fonts are not available\n // immediately after the image loads, to compensate we wait an\n // arbitrary amount of time\n // @see https://bugs.webkit.org/show_bug.cgi?id=219770\n if (delay)\n {\n await new Promise<void>((resolve) => setTimeout(resolve, 100));\n }\n\n image.onload = () =>\n {\n resolve();\n };\n\n image.src = `data:image/svg+xml;charset=utf8,${encodeURIComponent(url)}`;\n image.crossOrigin = 'anonymous';\n });\n}\n"],"names":["resolve"],"mappings":";AAUgB,SAAA,YAAA,CAAa,KAAyB,EAAA,GAAA,EAAa,KACnE,EAAA;AACI,EAAO,OAAA,IAAI,OAAc,CAAA,OAAO,OAChC,KAAA;AAKI,IAAA,IAAI,KACJ,EAAA;AACI,MAAA,MAAM,IAAI,OAAc,CAAA,CAACA,aAAY,UAAWA,CAAAA,QAAAA,EAAS,GAAG,CAAC,CAAA,CAAA;AAAA,KACjE;AAEA,IAAA,KAAA,CAAM,SAAS,MACf;AACI,MAAQ,OAAA,EAAA,CAAA;AAAA,KACZ,CAAA;AAEA,IAAA,KAAA,CAAM,GAAM,GAAA,CAAA,gCAAA,EAAmC,kBAAmB,CAAA,GAAG,CAAC,CAAA,CAAA,CAAA;AACtE,IAAA,KAAA,CAAM,WAAc,GAAA,WAAA,CAAA;AAAA,GACvB,CAAA,CAAA;AACL;;;;"}

View File

@@ -0,0 +1,13 @@
import { HTMLTextRenderData } from '../HTMLTextRenderData';
import type { Size } from '../../../maths/misc/Size';
import type { HTMLTextStyle } from '../HtmlTextStyle';
/**
* Measures the HTML text without actually generating an image.
* This is used to calculate the size of the text.
* @param text - The text to measure
* @param style - The style to use
* @param fontStyleCSS - The font css to use
* @param htmlTextRenderData - The HTMLTextRenderData to write the SVG to
* @returns - The size of the text
*/
export declare function measureHtmlText(text: string, style: HTMLTextStyle, fontStyleCSS?: string, htmlTextRenderData?: HTMLTextRenderData): Size;

View File

@@ -0,0 +1,28 @@
'use strict';
var CanvasTextMetrics = require('../../text/canvas/CanvasTextMetrics.js');
var HTMLTextRenderData = require('../HTMLTextRenderData.js');
"use strict";
let tempHTMLTextRenderData;
function measureHtmlText(text, style, fontStyleCSS, htmlTextRenderData) {
htmlTextRenderData = htmlTextRenderData || tempHTMLTextRenderData || (tempHTMLTextRenderData = new HTMLTextRenderData.HTMLTextRenderData());
const { domElement, styleElement, svgRoot } = htmlTextRenderData;
domElement.innerHTML = `<style>${style.cssStyle};</style><div style='padding:0'>${text}</div>`;
domElement.setAttribute("style", "transform-origin: top left; display: inline-block");
if (fontStyleCSS) {
styleElement.textContent = fontStyleCSS;
}
document.body.appendChild(svgRoot);
const contentBounds = domElement.getBoundingClientRect();
svgRoot.remove();
const descenderPadding = CanvasTextMetrics.CanvasTextMetrics.measureFont(style.fontStyle).descent;
const doublePadding = style.padding * 2;
return {
width: contentBounds.width - doublePadding,
height: contentBounds.height + descenderPadding - doublePadding
};
}
exports.measureHtmlText = measureHtmlText;
//# sourceMappingURL=measureHtmlText.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"measureHtmlText.js","sources":["../../../../src/scene/text-html/utils/measureHtmlText.ts"],"sourcesContent":["import { CanvasTextMetrics } from '../../text/canvas/CanvasTextMetrics';\nimport { HTMLTextRenderData } from '../HTMLTextRenderData';\n\nimport type { Size } from '../../../maths/misc/Size';\nimport type { HTMLTextStyle } from '../HtmlTextStyle';\n\nlet tempHTMLTextRenderData: HTMLTextRenderData;\n\n/**\n * Measures the HTML text without actually generating an image.\n * This is used to calculate the size of the text.\n * @param text - The text to measure\n * @param style - The style to use\n * @param fontStyleCSS - The font css to use\n * @param htmlTextRenderData - The HTMLTextRenderData to write the SVG to\n * @returns - The size of the text\n */\nexport function measureHtmlText(\n text: string,\n style: HTMLTextStyle,\n fontStyleCSS?: string,\n htmlTextRenderData?: HTMLTextRenderData\n): Size\n{\n htmlTextRenderData = htmlTextRenderData || tempHTMLTextRenderData || (tempHTMLTextRenderData = new HTMLTextRenderData());\n\n const { domElement, styleElement, svgRoot } = htmlTextRenderData;\n\n domElement.innerHTML = `<style>${style.cssStyle};</style><div style='padding:0'>${text}</div>`;\n\n domElement.setAttribute('style', 'transform-origin: top left; display: inline-block');\n\n if (fontStyleCSS)\n {\n styleElement.textContent = fontStyleCSS;\n }\n\n // Measure the contents using the shadow DOM\n document.body.appendChild(svgRoot);\n\n const contentBounds = domElement.getBoundingClientRect();\n\n svgRoot.remove();\n\n const descenderPadding = CanvasTextMetrics.measureFont(style.fontStyle).descent;\n\n // padding is included in the CSS calculation, so we need to remove it here\n const doublePadding = style.padding * 2;\n\n return {\n width: contentBounds.width - doublePadding,\n height: contentBounds.height + descenderPadding - doublePadding,\n };\n}\n"],"names":["HTMLTextRenderData","CanvasTextMetrics"],"mappings":";;;;;;AAMA,IAAI,sBAAA,CAAA;AAWG,SAAS,eACZ,CAAA,IAAA,EACA,KACA,EAAA,YAAA,EACA,kBAEJ,EAAA;AACI,EAAA,kBAAA,GAAqB,kBAAsB,IAAA,sBAAA,KAA2B,sBAAyB,GAAA,IAAIA,qCAAmB,EAAA,CAAA,CAAA;AAEtH,EAAA,MAAM,EAAE,UAAA,EAAY,YAAc,EAAA,OAAA,EAAY,GAAA,kBAAA,CAAA;AAE9C,EAAA,UAAA,CAAW,SAAY,GAAA,CAAA,OAAA,EAAU,KAAM,CAAA,QAAQ,mCAAmC,IAAI,CAAA,MAAA,CAAA,CAAA;AAEtF,EAAW,UAAA,CAAA,YAAA,CAAa,SAAS,mDAAmD,CAAA,CAAA;AAEpF,EAAA,IAAI,YACJ,EAAA;AACI,IAAA,YAAA,CAAa,WAAc,GAAA,YAAA,CAAA;AAAA,GAC/B;AAGA,EAAS,QAAA,CAAA,IAAA,CAAK,YAAY,OAAO,CAAA,CAAA;AAEjC,EAAM,MAAA,aAAA,GAAgB,WAAW,qBAAsB,EAAA,CAAA;AAEvD,EAAA,OAAA,CAAQ,MAAO,EAAA,CAAA;AAEf,EAAA,MAAM,gBAAmB,GAAAC,mCAAA,CAAkB,WAAY,CAAA,KAAA,CAAM,SAAS,CAAE,CAAA,OAAA,CAAA;AAGxE,EAAM,MAAA,aAAA,GAAgB,MAAM,OAAU,GAAA,CAAA,CAAA;AAEtC,EAAO,OAAA;AAAA,IACH,KAAA,EAAO,cAAc,KAAQ,GAAA,aAAA;AAAA,IAC7B,MAAA,EAAQ,aAAc,CAAA,MAAA,GAAS,gBAAmB,GAAA,aAAA;AAAA,GACtD,CAAA;AACJ;;;;"}

View File

@@ -0,0 +1,26 @@
import { CanvasTextMetrics } from '../../text/canvas/CanvasTextMetrics.mjs';
import { HTMLTextRenderData } from '../HTMLTextRenderData.mjs';
"use strict";
let tempHTMLTextRenderData;
function measureHtmlText(text, style, fontStyleCSS, htmlTextRenderData) {
htmlTextRenderData = htmlTextRenderData || tempHTMLTextRenderData || (tempHTMLTextRenderData = new HTMLTextRenderData());
const { domElement, styleElement, svgRoot } = htmlTextRenderData;
domElement.innerHTML = `<style>${style.cssStyle};</style><div style='padding:0'>${text}</div>`;
domElement.setAttribute("style", "transform-origin: top left; display: inline-block");
if (fontStyleCSS) {
styleElement.textContent = fontStyleCSS;
}
document.body.appendChild(svgRoot);
const contentBounds = domElement.getBoundingClientRect();
svgRoot.remove();
const descenderPadding = CanvasTextMetrics.measureFont(style.fontStyle).descent;
const doublePadding = style.padding * 2;
return {
width: contentBounds.width - doublePadding,
height: contentBounds.height + descenderPadding - doublePadding
};
}
export { measureHtmlText };
//# sourceMappingURL=measureHtmlText.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"measureHtmlText.mjs","sources":["../../../../src/scene/text-html/utils/measureHtmlText.ts"],"sourcesContent":["import { CanvasTextMetrics } from '../../text/canvas/CanvasTextMetrics';\nimport { HTMLTextRenderData } from '../HTMLTextRenderData';\n\nimport type { Size } from '../../../maths/misc/Size';\nimport type { HTMLTextStyle } from '../HtmlTextStyle';\n\nlet tempHTMLTextRenderData: HTMLTextRenderData;\n\n/**\n * Measures the HTML text without actually generating an image.\n * This is used to calculate the size of the text.\n * @param text - The text to measure\n * @param style - The style to use\n * @param fontStyleCSS - The font css to use\n * @param htmlTextRenderData - The HTMLTextRenderData to write the SVG to\n * @returns - The size of the text\n */\nexport function measureHtmlText(\n text: string,\n style: HTMLTextStyle,\n fontStyleCSS?: string,\n htmlTextRenderData?: HTMLTextRenderData\n): Size\n{\n htmlTextRenderData = htmlTextRenderData || tempHTMLTextRenderData || (tempHTMLTextRenderData = new HTMLTextRenderData());\n\n const { domElement, styleElement, svgRoot } = htmlTextRenderData;\n\n domElement.innerHTML = `<style>${style.cssStyle};</style><div style='padding:0'>${text}</div>`;\n\n domElement.setAttribute('style', 'transform-origin: top left; display: inline-block');\n\n if (fontStyleCSS)\n {\n styleElement.textContent = fontStyleCSS;\n }\n\n // Measure the contents using the shadow DOM\n document.body.appendChild(svgRoot);\n\n const contentBounds = domElement.getBoundingClientRect();\n\n svgRoot.remove();\n\n const descenderPadding = CanvasTextMetrics.measureFont(style.fontStyle).descent;\n\n // padding is included in the CSS calculation, so we need to remove it here\n const doublePadding = style.padding * 2;\n\n return {\n width: contentBounds.width - doublePadding,\n height: contentBounds.height + descenderPadding - doublePadding,\n };\n}\n"],"names":[],"mappings":";;;;AAMA,IAAI,sBAAA,CAAA;AAWG,SAAS,eACZ,CAAA,IAAA,EACA,KACA,EAAA,YAAA,EACA,kBAEJ,EAAA;AACI,EAAA,kBAAA,GAAqB,kBAAsB,IAAA,sBAAA,KAA2B,sBAAyB,GAAA,IAAI,kBAAmB,EAAA,CAAA,CAAA;AAEtH,EAAA,MAAM,EAAE,UAAA,EAAY,YAAc,EAAA,OAAA,EAAY,GAAA,kBAAA,CAAA;AAE9C,EAAA,UAAA,CAAW,SAAY,GAAA,CAAA,OAAA,EAAU,KAAM,CAAA,QAAQ,mCAAmC,IAAI,CAAA,MAAA,CAAA,CAAA;AAEtF,EAAW,UAAA,CAAA,YAAA,CAAa,SAAS,mDAAmD,CAAA,CAAA;AAEpF,EAAA,IAAI,YACJ,EAAA;AACI,IAAA,YAAA,CAAa,WAAc,GAAA,YAAA,CAAA;AAAA,GAC/B;AAGA,EAAS,QAAA,CAAA,IAAA,CAAK,YAAY,OAAO,CAAA,CAAA;AAEjC,EAAM,MAAA,aAAA,GAAgB,WAAW,qBAAsB,EAAA,CAAA;AAEvD,EAAA,OAAA,CAAQ,MAAO,EAAA,CAAA;AAEf,EAAA,MAAM,gBAAmB,GAAA,iBAAA,CAAkB,WAAY,CAAA,KAAA,CAAM,SAAS,CAAE,CAAA,OAAA,CAAA;AAGxE,EAAM,MAAA,aAAA,GAAgB,MAAM,OAAU,GAAA,CAAA,CAAA;AAEtC,EAAO,OAAA;AAAA,IACH,KAAA,EAAO,cAAc,KAAQ,GAAA,aAAA;AAAA,IAC7B,MAAA,EAAQ,aAAc,CAAA,MAAA,GAAS,gBAAmB,GAAA,aAAA;AAAA,GACtD,CAAA;AACJ;;;;"}

View File

@@ -0,0 +1,7 @@
import type { HTMLTextStyle } from '../HtmlTextStyle';
/**
* Internally converts all of the style properties into CSS equivalents.
* @param style
* @returns The CSS style string, for setting `style` property of root HTMLElement.
*/
export declare function textStyleToCSS(style: HTMLTextStyle): string;

View File

@@ -0,0 +1,87 @@
'use strict';
var Color = require('../../../color/Color.js');
"use strict";
function textStyleToCSS(style) {
const stroke = style._stroke;
const fill = style._fill;
const cssStyleString = [
`color: ${Color.Color.shared.setValue(fill.color).toHex()}`,
`font-size: ${style.fontSize}px`,
`font-family: ${style.fontFamily}`,
`font-weight: ${style.fontWeight}`,
`font-style: ${style.fontStyle}`,
`font-variant: ${style.fontVariant}`,
`letter-spacing: ${style.letterSpacing}px`,
`text-align: ${style.align}`,
`padding: ${style.padding}px`,
`white-space: ${style.whiteSpace === "pre" && style.wordWrap ? "pre-wrap" : style.whiteSpace}`,
...style.lineHeight ? [`line-height: ${style.lineHeight}px`] : [],
...style.wordWrap ? [
`word-wrap: ${style.breakWords ? "break-all" : "break-word"}`,
`max-width: ${style.wordWrapWidth}px`
] : [],
...stroke ? [strokeToCSS(stroke)] : [],
...style.dropShadow ? [dropShadowToCSS(style.dropShadow)] : [],
...style.cssOverrides
].join(";");
const cssStyles = [`div { ${cssStyleString} }`];
tagStyleToCSS(style.tagStyles, cssStyles);
return cssStyles.join(" ");
}
function dropShadowToCSS(dropShadowStyle) {
const color = Color.Color.shared.setValue(dropShadowStyle.color).setAlpha(dropShadowStyle.alpha).toHexa();
const x = Math.round(Math.cos(dropShadowStyle.angle) * dropShadowStyle.distance);
const y = Math.round(Math.sin(dropShadowStyle.angle) * dropShadowStyle.distance);
const position = `${x}px ${y}px`;
if (dropShadowStyle.blur > 0) {
return `text-shadow: ${position} ${dropShadowStyle.blur}px ${color}`;
}
return `text-shadow: ${position} ${color}`;
}
function strokeToCSS(stroke) {
return [
`-webkit-text-stroke-width: ${stroke.width}px`,
`-webkit-text-stroke-color: ${Color.Color.shared.setValue(stroke.color).toHex()}`,
`text-stroke-width: ${stroke.width}px`,
`text-stroke-color: ${Color.Color.shared.setValue(stroke.color).toHex()}`,
"paint-order: stroke"
].join(";");
}
const templates = {
fontSize: `font-size: {{VALUE}}px`,
fontFamily: `font-family: {{VALUE}}`,
fontWeight: `font-weight: {{VALUE}}`,
fontStyle: `font-style: {{VALUE}}`,
fontVariant: `font-variant: {{VALUE}}`,
letterSpacing: `letter-spacing: {{VALUE}}px`,
align: `text-align: {{VALUE}}`,
padding: `padding: {{VALUE}}px`,
whiteSpace: `white-space: {{VALUE}}`,
lineHeight: `line-height: {{VALUE}}px`,
wordWrapWidth: `max-width: {{VALUE}}px`
};
const transform = {
fill: (value) => `color: ${Color.Color.shared.setValue(value).toHex()}`,
breakWords: (value) => `word-wrap: ${value ? "break-all" : "break-word"}`,
stroke: strokeToCSS,
dropShadow: dropShadowToCSS
};
function tagStyleToCSS(tagStyles, out) {
for (const i in tagStyles) {
const tagStyle = tagStyles[i];
const cssTagStyle = [];
for (const j in tagStyle) {
if (transform[j]) {
cssTagStyle.push(transform[j](tagStyle[j]));
} else if (templates[j]) {
cssTagStyle.push(templates[j].replace("{{VALUE}}", tagStyle[j]));
}
}
out.push(`${i} { ${cssTagStyle.join(";")} }`);
}
}
exports.textStyleToCSS = textStyleToCSS;
//# sourceMappingURL=textStyleToCSS.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,85 @@
import { Color } from '../../../color/Color.mjs';
"use strict";
function textStyleToCSS(style) {
const stroke = style._stroke;
const fill = style._fill;
const cssStyleString = [
`color: ${Color.shared.setValue(fill.color).toHex()}`,
`font-size: ${style.fontSize}px`,
`font-family: ${style.fontFamily}`,
`font-weight: ${style.fontWeight}`,
`font-style: ${style.fontStyle}`,
`font-variant: ${style.fontVariant}`,
`letter-spacing: ${style.letterSpacing}px`,
`text-align: ${style.align}`,
`padding: ${style.padding}px`,
`white-space: ${style.whiteSpace === "pre" && style.wordWrap ? "pre-wrap" : style.whiteSpace}`,
...style.lineHeight ? [`line-height: ${style.lineHeight}px`] : [],
...style.wordWrap ? [
`word-wrap: ${style.breakWords ? "break-all" : "break-word"}`,
`max-width: ${style.wordWrapWidth}px`
] : [],
...stroke ? [strokeToCSS(stroke)] : [],
...style.dropShadow ? [dropShadowToCSS(style.dropShadow)] : [],
...style.cssOverrides
].join(";");
const cssStyles = [`div { ${cssStyleString} }`];
tagStyleToCSS(style.tagStyles, cssStyles);
return cssStyles.join(" ");
}
function dropShadowToCSS(dropShadowStyle) {
const color = Color.shared.setValue(dropShadowStyle.color).setAlpha(dropShadowStyle.alpha).toHexa();
const x = Math.round(Math.cos(dropShadowStyle.angle) * dropShadowStyle.distance);
const y = Math.round(Math.sin(dropShadowStyle.angle) * dropShadowStyle.distance);
const position = `${x}px ${y}px`;
if (dropShadowStyle.blur > 0) {
return `text-shadow: ${position} ${dropShadowStyle.blur}px ${color}`;
}
return `text-shadow: ${position} ${color}`;
}
function strokeToCSS(stroke) {
return [
`-webkit-text-stroke-width: ${stroke.width}px`,
`-webkit-text-stroke-color: ${Color.shared.setValue(stroke.color).toHex()}`,
`text-stroke-width: ${stroke.width}px`,
`text-stroke-color: ${Color.shared.setValue(stroke.color).toHex()}`,
"paint-order: stroke"
].join(";");
}
const templates = {
fontSize: `font-size: {{VALUE}}px`,
fontFamily: `font-family: {{VALUE}}`,
fontWeight: `font-weight: {{VALUE}}`,
fontStyle: `font-style: {{VALUE}}`,
fontVariant: `font-variant: {{VALUE}}`,
letterSpacing: `letter-spacing: {{VALUE}}px`,
align: `text-align: {{VALUE}}`,
padding: `padding: {{VALUE}}px`,
whiteSpace: `white-space: {{VALUE}}`,
lineHeight: `line-height: {{VALUE}}px`,
wordWrapWidth: `max-width: {{VALUE}}px`
};
const transform = {
fill: (value) => `color: ${Color.shared.setValue(value).toHex()}`,
breakWords: (value) => `word-wrap: ${value ? "break-all" : "break-word"}`,
stroke: strokeToCSS,
dropShadow: dropShadowToCSS
};
function tagStyleToCSS(tagStyles, out) {
for (const i in tagStyles) {
const tagStyle = tagStyles[i];
const cssTagStyle = [];
for (const j in tagStyle) {
if (transform[j]) {
cssTagStyle.push(transform[j](tagStyle[j]));
} else if (templates[j]) {
cssTagStyle.push(templates[j].replace("{{VALUE}}", tagStyle[j]));
}
}
out.push(`${i} { ${cssTagStyle.join(";")} }`);
}
}
export { textStyleToCSS };
//# sourceMappingURL=textStyleToCSS.mjs.map

File diff suppressed because one or more lines are too long