@zephyr3d/device 0.2.7 → 0.2.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/base_types.js.map +1 -1
- package/dist/builder/types.js +2 -2
- package/dist/builder/types.js.map +1 -1
- package/dist/device.js +18 -4
- package/dist/device.js.map +1 -1
- package/dist/helpers/drawtext.js +204 -40
- package/dist/helpers/drawtext.js.map +1 -1
- package/dist/helpers/textureatlas.js +21 -6
- package/dist/helpers/textureatlas.js.map +1 -1
- package/dist/index.d.ts +71 -8
- package/dist/pool.js +2 -2
- package/dist/pool.js.map +1 -1
- package/package.json +2 -2
package/dist/helpers/drawtext.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Matrix4x4, Vector4, Vector3, parseColor } from '@zephyr3d/base';
|
|
1
|
+
import { Matrix4x4, Vector4, Vector3, parseColor, splitStringByGraphemes } from '@zephyr3d/base';
|
|
2
2
|
import { Font } from './font.js';
|
|
3
3
|
import { GlyphManager } from './glyphmanager.js';
|
|
4
4
|
|
|
@@ -18,11 +18,17 @@ const MAX_GLYPH_COUNT = 1024;
|
|
|
18
18
|
/** @internal */ static textOffset = 0;
|
|
19
19
|
/** @internal */ static textMatrix = new Matrix4x4();
|
|
20
20
|
/** @internal */ static font = null;
|
|
21
|
+
/** @internal */ static overrideRenderStates = null;
|
|
21
22
|
/** @internal */ static vertexCache = null;
|
|
22
23
|
/** @internal */ static colorValue = new Vector4();
|
|
23
|
-
/** @internal */ static
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
/** @internal */ static defaultLayoutOptions = {
|
|
25
|
+
halign: 'left',
|
|
26
|
+
valign: 'top',
|
|
27
|
+
wordWrap: false
|
|
28
|
+
};
|
|
29
|
+
/** @internal */ static calculateTextMatrix(device, matrix) {
|
|
30
|
+
const viewportWidth = device.getViewport().width;
|
|
31
|
+
const viewportHeight = device.getViewport().height;
|
|
26
32
|
matrix.identity();
|
|
27
33
|
const projectionMatrix = Matrix4x4.ortho(0, viewportWidth, 0, viewportHeight, 1, 100);
|
|
28
34
|
const flipMatrix = Matrix4x4.translation(new Vector3(0, viewportHeight, 0)).scaleRight(new Vector3(1, -1, 1));
|
|
@@ -34,48 +40,88 @@ const MAX_GLYPH_COUNT = 1024;
|
|
|
34
40
|
* @param name - The font name
|
|
35
41
|
*/ static setFont(device, name) {
|
|
36
42
|
const scale = device.getScaleY();
|
|
37
|
-
this.font = Font.fetchFont(name, scale)
|
|
43
|
+
this.font = name ? Font.fetchFont(name, scale) : Font.fetchFont('12px arial', scale);
|
|
38
44
|
}
|
|
39
45
|
/**
|
|
40
|
-
*
|
|
41
|
-
* @param
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
if (
|
|
46
|
+
* Set render states to be used when drawing text. If not set, default states will be used.
|
|
47
|
+
* @param renderStates - The render states to use when drawing text. If null, default states will be used.
|
|
48
|
+
*/ static setRenderStates(renderStates) {
|
|
49
|
+
this.overrideRenderStates = renderStates ?? null;
|
|
50
|
+
}
|
|
51
|
+
static drawText(device, text, color, xOrRect, yOrOptions) {
|
|
52
|
+
this.colorToVec4(color, this.colorValue);
|
|
53
|
+
if (typeof xOrRect === 'number') {
|
|
54
|
+
if (text.length > 0) {
|
|
55
|
+
device.pushDeviceStates();
|
|
56
|
+
try {
|
|
57
|
+
this.beginDrawText(device);
|
|
58
|
+
this.drawPreparedText(device, text, xOrRect, yOrOptions);
|
|
59
|
+
} finally{
|
|
60
|
+
device.popDeviceStates();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
this.drawTextRect(device, text, xOrRect, yOrOptions);
|
|
66
|
+
}
|
|
67
|
+
/** @internal */ static drawTextRect(device, text, rect, options) {
|
|
68
|
+
if (text.length > 0 && rect.width > 0 && rect.height > 0) {
|
|
48
69
|
device.pushDeviceStates();
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
try {
|
|
71
|
+
this.beginDrawText(device);
|
|
72
|
+
const viewport = device.getViewport();
|
|
73
|
+
const resolved = this.resolveLayoutOptions(options);
|
|
74
|
+
const lines = this.layoutText(text, rect.width, resolved.wordWrap);
|
|
75
|
+
if (lines.length === 0) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const lineHeight = this.font.maxHeight;
|
|
79
|
+
const blockHeight = lines.length * lineHeight;
|
|
80
|
+
let startY = rect.y;
|
|
81
|
+
if (resolved.valign === 'center') {
|
|
82
|
+
startY += (rect.height - blockHeight) * 0.5;
|
|
83
|
+
} else if (resolved.valign === 'bottom') {
|
|
84
|
+
startY += rect.height - blockHeight;
|
|
85
|
+
}
|
|
86
|
+
const absoluteScissorRect = {
|
|
87
|
+
x: viewport.x + rect.x,
|
|
88
|
+
y: viewport.y + viewport.height - rect.y - rect.height,
|
|
89
|
+
width: rect.width,
|
|
90
|
+
height: rect.height
|
|
91
|
+
};
|
|
92
|
+
const currentScissor = device.getScissor();
|
|
93
|
+
const clipX = Math.max(absoluteScissorRect.x, currentScissor.x);
|
|
94
|
+
const clipY = Math.max(absoluteScissorRect.y, currentScissor.y);
|
|
95
|
+
const clipRight = Math.min(absoluteScissorRect.x + absoluteScissorRect.width, currentScissor.x + currentScissor.width);
|
|
96
|
+
const clipBottom = Math.min(absoluteScissorRect.y + absoluteScissorRect.height, currentScissor.y + currentScissor.height);
|
|
97
|
+
const clipWidth = Math.max(0, clipRight - clipX);
|
|
98
|
+
const clipHeight = Math.max(0, clipBottom - clipY);
|
|
99
|
+
if (clipWidth <= 0 || clipHeight <= 0) {
|
|
100
|
+
return;
|
|
72
101
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
102
|
+
device.setScissor([
|
|
103
|
+
clipX,
|
|
104
|
+
clipY,
|
|
105
|
+
clipWidth,
|
|
106
|
+
clipHeight
|
|
107
|
+
]);
|
|
108
|
+
for(let i = 0; i < lines.length; i++){
|
|
109
|
+
const line = lines[i];
|
|
110
|
+
const lineY = startY + i * lineHeight;
|
|
111
|
+
if (lineY + lineHeight <= rect.y || lineY >= rect.y + rect.height) {
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
let lineX = rect.x;
|
|
115
|
+
if (resolved.halign === 'center') {
|
|
116
|
+
lineX += (rect.width - line.width) * 0.5;
|
|
117
|
+
} else if (resolved.halign === 'right') {
|
|
118
|
+
lineX += rect.width - line.width;
|
|
119
|
+
}
|
|
120
|
+
this.drawPreparedText(device, line.text, lineX, lineY);
|
|
76
121
|
}
|
|
122
|
+
} finally{
|
|
123
|
+
device.popDeviceStates();
|
|
77
124
|
}
|
|
78
|
-
device.popDeviceStates();
|
|
79
125
|
}
|
|
80
126
|
}
|
|
81
127
|
/** @internal */ static drawTextNoOverflow(device, text, start, count, x, y) {
|
|
@@ -116,6 +162,124 @@ const MAX_GLYPH_COUNT = 1024;
|
|
|
116
162
|
device.draw('triangle-list', (this.textOffset + drawn) * 6, (i - drawn) * 6);
|
|
117
163
|
return x;
|
|
118
164
|
}
|
|
165
|
+
/** @internal */ static colorToVec4(color, out) {
|
|
166
|
+
if (typeof color === 'string') {
|
|
167
|
+
const colorValue = parseColor(color);
|
|
168
|
+
out.setXYZW(colorValue.r, colorValue.g, colorValue.b, colorValue.a);
|
|
169
|
+
} else if (color instanceof Vector3) {
|
|
170
|
+
out.setXYZW(color.x, color.y, color.z, 1);
|
|
171
|
+
} else {
|
|
172
|
+
out.set(color);
|
|
173
|
+
}
|
|
174
|
+
return out;
|
|
175
|
+
}
|
|
176
|
+
/** @internal */ static beginDrawText(device) {
|
|
177
|
+
this.prepareDrawText(device);
|
|
178
|
+
this.calculateTextMatrix(device, this.textMatrix);
|
|
179
|
+
this.textBindGroup.setValue('flip', device.type === 'webgpu' && device.getFramebuffer() ? 1 : 0);
|
|
180
|
+
this.textBindGroup.setValue('srgbOut', device.getFramebuffer() ? 0 : 1);
|
|
181
|
+
this.textBindGroup.setValue('textMatrix', this.textMatrix);
|
|
182
|
+
this.textBindGroup.setValue('textColor', this.colorValue);
|
|
183
|
+
device.setProgram(this.textProgram);
|
|
184
|
+
device.setVertexLayout(this.textVertexLayout);
|
|
185
|
+
device.setRenderStates(this.overrideRenderStates ?? this.textRenderStates);
|
|
186
|
+
device.setBindGroup(0, this.textBindGroup);
|
|
187
|
+
}
|
|
188
|
+
/** @internal */ static drawPreparedText(device, text, x, y) {
|
|
189
|
+
let drawn = 0;
|
|
190
|
+
const splitted = splitStringByGraphemes(text);
|
|
191
|
+
const total = splitted.length;
|
|
192
|
+
while(drawn < total){
|
|
193
|
+
const count = Math.min(total - drawn, this.GLYPH_COUNT - this.textOffset);
|
|
194
|
+
if (count > 0) {
|
|
195
|
+
x = this.drawTextNoOverflow(device, splitted, drawn, count, x, y);
|
|
196
|
+
drawn += count;
|
|
197
|
+
this.textOffset += count;
|
|
198
|
+
}
|
|
199
|
+
if (this.GLYPH_COUNT === this.textOffset) {
|
|
200
|
+
this.textOffset = 0;
|
|
201
|
+
device.flush();
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
/** @internal */ static resolveLayoutOptions(options) {
|
|
206
|
+
return {
|
|
207
|
+
halign: options?.halign ?? this.defaultLayoutOptions.halign,
|
|
208
|
+
valign: options?.valign ?? this.defaultLayoutOptions.valign,
|
|
209
|
+
wordWrap: options?.wordWrap ?? this.defaultLayoutOptions.wordWrap
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
/** @internal */ static layoutText(text, maxWidth, wordWrap) {
|
|
213
|
+
const result = [];
|
|
214
|
+
const paragraphs = text.split(/\r\n|\r|\n/);
|
|
215
|
+
for (const paragraph of paragraphs){
|
|
216
|
+
if (!wordWrap) {
|
|
217
|
+
result.push({
|
|
218
|
+
text: paragraph,
|
|
219
|
+
width: this.measureLineWidth(paragraph)
|
|
220
|
+
});
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
this.layoutWrappedParagraph(paragraph, maxWidth, result);
|
|
224
|
+
}
|
|
225
|
+
return result;
|
|
226
|
+
}
|
|
227
|
+
/** @internal */ static layoutWrappedParagraph(text, maxWidth, out) {
|
|
228
|
+
if (text.length === 0) {
|
|
229
|
+
out.push({
|
|
230
|
+
text: '',
|
|
231
|
+
width: 0
|
|
232
|
+
});
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
const chars = splitStringByGraphemes(text);
|
|
236
|
+
let start = 0;
|
|
237
|
+
while(start < chars.length){
|
|
238
|
+
let width = 0;
|
|
239
|
+
let breakPos = start;
|
|
240
|
+
let lastWhitespaceBreak = -1;
|
|
241
|
+
while(breakPos < chars.length){
|
|
242
|
+
const ch = chars[breakPos];
|
|
243
|
+
const charWidth = this.glyphManager.getCharWidth(ch, this.font);
|
|
244
|
+
if (breakPos > start && width + charWidth > maxWidth) {
|
|
245
|
+
break;
|
|
246
|
+
}
|
|
247
|
+
width += charWidth;
|
|
248
|
+
breakPos++;
|
|
249
|
+
if (/^\s$/u.test(ch)) {
|
|
250
|
+
lastWhitespaceBreak = breakPos;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
if (breakPos < chars.length && lastWhitespaceBreak > start) {
|
|
254
|
+
const lineText = chars.slice(start, lastWhitespaceBreak).join('').replace(/\s+$/u, '');
|
|
255
|
+
out.push({
|
|
256
|
+
text: lineText,
|
|
257
|
+
width: this.measureLineWidth(lineText)
|
|
258
|
+
});
|
|
259
|
+
start = lastWhitespaceBreak;
|
|
260
|
+
while(start < chars.length && /^\s$/u.test(chars[start])){
|
|
261
|
+
start++;
|
|
262
|
+
}
|
|
263
|
+
} else {
|
|
264
|
+
const lineText = chars.slice(start, breakPos).join('');
|
|
265
|
+
out.push({
|
|
266
|
+
text: lineText,
|
|
267
|
+
width
|
|
268
|
+
});
|
|
269
|
+
start = Math.max(breakPos, start + 1);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
/** @internal */ static measureLineWidth(text) {
|
|
274
|
+
if (!text) {
|
|
275
|
+
return 0;
|
|
276
|
+
}
|
|
277
|
+
let width = 0;
|
|
278
|
+
for (const ch of splitStringByGraphemes(text)){
|
|
279
|
+
width += this.glyphManager.getCharWidth(ch, this.font);
|
|
280
|
+
}
|
|
281
|
+
return width;
|
|
282
|
+
}
|
|
119
283
|
/** @internal */ static prepareDrawText(device) {
|
|
120
284
|
if (!this.prepared) {
|
|
121
285
|
this.prepared = true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drawtext.js","sources":["../../src/helpers/drawtext.ts"],"sourcesContent":["import type { Immutable, Nullable } from '@zephyr3d/base';\r\nimport { Matrix4x4, parseColor, Vector3, Vector4 } from '@zephyr3d/base';\r\nimport { Font } from './font';\r\nimport { GlyphManager } from './glyphmanager';\r\nimport type { RenderStateSet } from '../render_states';\r\nimport type { AbstractDevice } from '../base_types';\r\nimport type { BindGroup, GPUProgram, StructuredBuffer, VertexLayout } from '../gpuobject';\r\n\r\nconst MAX_GLYPH_COUNT = 1024;\r\n\r\n/**\r\n * Helper class to draw some text onto the screen\r\n * @public\r\n */\r\nexport class DrawText {\r\n /** @internal */\r\n private static readonly GLYPH_COUNT = MAX_GLYPH_COUNT;\r\n /** @internal */\r\n private static glyphManager: Nullable<GlyphManager> = null;\r\n /** @internal */\r\n private static prepared = false;\r\n /** @internal */\r\n private static textVertexBuffer: Nullable<StructuredBuffer> = null;\r\n /** @internal */\r\n private static textVertexLayout: Nullable<VertexLayout> = null;\r\n /** @internal */\r\n private static textProgram: Nullable<GPUProgram> = null;\r\n /** @internal */\r\n private static textBindGroup: Nullable<BindGroup> = null;\r\n /** @internal */\r\n private static textRenderStates: Nullable<RenderStateSet> = null;\r\n /** @internal */\r\n private static textOffset = 0;\r\n /** @internal */\r\n private static readonly textMatrix = new Matrix4x4();\r\n /** @internal */\r\n private static font: Nullable<Font> = null;\r\n /** @internal */\r\n private static vertexCache: Nullable<Float32Array<ArrayBuffer>> = null;\r\n /** @internal */\r\n private static readonly colorValue: Vector4 = new Vector4();\r\n /** @internal */\r\n private static calculateTextMatrix(\r\n device: AbstractDevice,\r\n matrix: Matrix4x4,\r\n viewport?: Immutable<number[]>\r\n ) {\r\n const viewportWidth = viewport ? viewport[2] : device.getViewport().width;\r\n const viewportHeight = viewport ? viewport[3] : device.getViewport().height;\r\n matrix.identity();\r\n const projectionMatrix = Matrix4x4.ortho(0, viewportWidth, 0, viewportHeight, 1, 100);\r\n const flipMatrix = Matrix4x4.translation(new Vector3(0, viewportHeight, 0)).scaleRight(\r\n new Vector3(1, -1, 1)\r\n );\r\n Matrix4x4.multiply(projectionMatrix, flipMatrix, matrix);\r\n }\r\n /**\r\n * Set the font that will be used to draw strings\r\n * @param device - The render device\r\n * @param name - The font name\r\n */\r\n static setFont(device: AbstractDevice, name: string) {\r\n const scale = device.getScaleY();\r\n this.font = Font.fetchFont(name, scale) || Font.fetchFont('12px arial', scale);\r\n }\r\n /**\r\n * Draw text onto the screen\r\n * @param device - The render device\r\n * @param text - The text to be drawn\r\n * @param color - The text color\r\n * @param x - X coordinate of the text\r\n * @param y - Y coordinate of the text\r\n */\r\n static drawText(\r\n device: AbstractDevice,\r\n text: string,\r\n color: string,\r\n x: number,\r\n y: number,\r\n viewport?: Immutable<number[]>\r\n ) {\r\n if (text.length > 0) {\r\n device.pushDeviceStates();\r\n this.prepareDrawText(device);\r\n this.calculateTextMatrix(device, this.textMatrix, viewport);\r\n const colorValue = parseColor(color);\r\n this.colorValue.x = colorValue.r;\r\n this.colorValue.y = colorValue.g;\r\n this.colorValue.z = colorValue.b;\r\n this.colorValue.w = colorValue.a;\r\n this.textBindGroup!.setValue('flip', device.type === 'webgpu' && device.getFramebuffer() ? 1 : 0);\r\n this.textBindGroup!.setValue('srgbOut', device.getFramebuffer() ? 0 : 1);\r\n this.textBindGroup!.setValue('textMatrix', this.textMatrix);\r\n this.textBindGroup!.setValue('textColor', this.colorValue);\r\n device.setProgram(this.textProgram!);\r\n device.setVertexLayout(this.textVertexLayout!);\r\n device.setRenderStates(this.textRenderStates!);\r\n device.setBindGroup(0, this.textBindGroup!);\r\n let drawn = 0;\r\n const total = text.length;\r\n while (drawn < total) {\r\n const count = Math.min(total - drawn, this.GLYPH_COUNT - this.textOffset);\r\n if (count > 0) {\r\n x = this.drawTextNoOverflow(device, text, drawn, count, x, y);\r\n drawn += count;\r\n this.textOffset += count;\r\n }\r\n if (this.GLYPH_COUNT === this.textOffset) {\r\n this.textOffset = 0;\r\n device.flush();\r\n }\r\n }\r\n device.popDeviceStates();\r\n }\r\n }\r\n /** @internal */\r\n private static drawTextNoOverflow(\r\n device: AbstractDevice,\r\n text: string,\r\n start: number,\r\n count: number,\r\n x: number,\r\n y: number\r\n ) {\r\n let drawn = 0;\r\n let atlasIndex = -1;\r\n let i = 0;\r\n const vertexCache = this.vertexCache!;\r\n for (; i < count; i++) {\r\n const glyph =\r\n this.glyphManager!.getGlyphInfo(text[i + start], this.font!) ||\r\n this.glyphManager!.getGlyphInfo('?', this.font!)!;\r\n if (atlasIndex >= 0 && glyph.atlasIndex !== atlasIndex) {\r\n this.textVertexBuffer!.bufferSubData(\r\n (this.textOffset + drawn) * 16 * 4,\r\n this.vertexCache!,\r\n (this.textOffset + drawn) * 16,\r\n (i - drawn) * 16\r\n );\r\n this.textBindGroup!.setTexture('tex', this.glyphManager!.getAtlasTexture(atlasIndex)!);\r\n device.draw('triangle-list', (this.textOffset + drawn) * 6, (i - drawn) * 6);\r\n drawn = i;\r\n }\r\n atlasIndex = glyph.atlasIndex;\r\n const base = (this.textOffset + i) * 16;\r\n vertexCache[base + 0] = x;\r\n vertexCache[base + 1] = y;\r\n vertexCache[base + 2] = glyph.uMin;\r\n vertexCache[base + 3] = glyph.vMin;\r\n vertexCache[base + 4] = x + glyph.width;\r\n vertexCache[base + 5] = y;\r\n vertexCache[base + 6] = glyph.uMax;\r\n vertexCache[base + 7] = glyph.vMin;\r\n vertexCache[base + 8] = x + glyph.width;\r\n vertexCache[base + 9] = y + glyph.height;\r\n vertexCache[base + 10] = glyph.uMax;\r\n vertexCache[base + 11] = glyph.vMax;\r\n vertexCache[base + 12] = x;\r\n vertexCache[base + 13] = y + glyph.height;\r\n vertexCache[base + 14] = glyph.uMin;\r\n vertexCache[base + 15] = glyph.vMax;\r\n x += glyph.width;\r\n }\r\n this.textVertexBuffer!.bufferSubData(\r\n (this.textOffset + drawn) * 16 * 4,\r\n vertexCache,\r\n (this.textOffset + drawn) * 16,\r\n (i - drawn) * 16\r\n );\r\n this.textBindGroup!.setTexture('tex', this.glyphManager!.getAtlasTexture(atlasIndex)!);\r\n device.draw('triangle-list', (this.textOffset + drawn) * 6, (i - drawn) * 6);\r\n return x;\r\n }\r\n /** @internal */\r\n private static prepareDrawText(device: AbstractDevice) {\r\n if (!this.prepared) {\r\n this.prepared = true;\r\n this.font = this.font || Font.fetchFont('12px arial', device.getScaleY());\r\n this.glyphManager = new GlyphManager(device, 1024, 1024, 1);\r\n this.vertexCache = new Float32Array(this.GLYPH_COUNT * 16);\r\n this.textVertexBuffer = device.createInterleavedVertexBuffer(\r\n ['position_f32x2', 'tex0_f32x2'],\r\n this.vertexCache,\r\n {\r\n dynamic: true\r\n }\r\n );\r\n const indices = new Uint16Array(this.GLYPH_COUNT * 6);\r\n for (let i = 0; i < this.GLYPH_COUNT; i++) {\r\n const base = i * 4;\r\n indices[i * 6 + 0] = base + 0;\r\n indices[i * 6 + 1] = base + 1;\r\n indices[i * 6 + 2] = base + 2;\r\n indices[i * 6 + 3] = base + 0;\r\n indices[i * 6 + 4] = base + 2;\r\n indices[i * 6 + 5] = base + 3;\r\n }\r\n const textIndexBuffer = device.createIndexBuffer(indices);\r\n this.textVertexLayout = device.createVertexLayout({\r\n vertexBuffers: [{ buffer: this.textVertexBuffer! }],\r\n indexBuffer: textIndexBuffer\r\n });\r\n this.textOffset = 0;\r\n this.textProgram = device.buildRenderProgram({\r\n vertex(pb) {\r\n this.$inputs.pos = pb.vec2().attrib('position');\r\n this.$inputs.uv = pb.vec2().attrib('texCoord0');\r\n this.$outputs.uv = pb.vec2();\r\n this.flip = pb.int(0).uniform(0);\r\n this.textMatrix = pb.mat4().uniform(0);\r\n pb.main(function () {\r\n this.$builtins.position = pb.mul(this.textMatrix, pb.vec4(this.$inputs.pos, -50, 1));\r\n this.$if(pb.notEqual(this.flip, 0), function () {\r\n this.$builtins.position.y = pb.neg(this.$builtins.position.y);\r\n });\r\n this.$outputs.uv = this.$inputs.uv;\r\n });\r\n },\r\n fragment(pb) {\r\n this.$outputs.color = pb.vec4();\r\n this.textColor = pb.vec4().uniform(0);\r\n this.tex = pb.tex2D().uniform(0);\r\n this.srgbOut = pb.int().uniform(0);\r\n pb.main(function () {\r\n this.alpha = pb.mul(pb.textureSample(this.tex, this.$inputs.uv).a, this.textColor.a);\r\n this.$if(pb.notEqual(this.srgbOut, 0), function () {\r\n this.$outputs.color = pb.vec4(\r\n pb.mul(pb.pow(this.textColor.rgb, pb.vec3(1 / 2.2)), this.alpha),\r\n this.alpha\r\n );\r\n }).$else(function () {\r\n this.$outputs.color = pb.vec4(pb.mul(this.textColor.rgb, this.alpha), this.alpha);\r\n });\r\n });\r\n }\r\n });\r\n this.textProgram!.name = '@DrawText';\r\n this.textBindGroup = device.createBindGroup(this.textProgram!.bindGroupLayouts[0]);\r\n this.textRenderStates = device.createRenderStateSet();\r\n this.textRenderStates\r\n .useBlendingState()\r\n .enable(true)\r\n .setBlendFuncRGB('one', 'inv-src-alpha')\r\n .setBlendFuncAlpha('zero', 'one');\r\n this.textRenderStates.useDepthState().enableTest(false).enableWrite(false);\r\n this.textRenderStates.useRasterizerState().setCullMode('none');\r\n }\r\n }\r\n}\r\n"],"names":["MAX_GLYPH_COUNT","DrawText","GLYPH_COUNT","glyphManager","prepared","textVertexBuffer","textVertexLayout","textProgram","textBindGroup","textRenderStates","textOffset","textMatrix","Matrix4x4","font","vertexCache","colorValue","Vector4","calculateTextMatrix","device","matrix","viewport","viewportWidth","getViewport","width","viewportHeight","height","identity","projectionMatrix","ortho","flipMatrix","translation","Vector3","scaleRight","multiply","setFont","name","scale","getScaleY","Font","fetchFont","drawText","text","color","x","y","length","pushDeviceStates","prepareDrawText","parseColor","r","g","z","b","w","a","setValue","type","getFramebuffer","setProgram","setVertexLayout","setRenderStates","setBindGroup","drawn","total","count","Math","min","drawTextNoOverflow","flush","popDeviceStates","start","atlasIndex","i","glyph","getGlyphInfo","bufferSubData","setTexture","getAtlasTexture","draw","base","uMin","vMin","uMax","vMax","GlyphManager","Float32Array","createInterleavedVertexBuffer","dynamic","indices","Uint16Array","textIndexBuffer","createIndexBuffer","createVertexLayout","vertexBuffers","buffer","indexBuffer","buildRenderProgram","vertex","pb","$inputs","pos","vec2","attrib","uv","$outputs","flip","int","uniform","mat4","main","$builtins","position","mul","vec4","$if","notEqual","neg","fragment","textColor","tex","tex2D","srgbOut","alpha","textureSample","pow","rgb","vec3","$else","createBindGroup","bindGroupLayouts","createRenderStateSet","useBlendingState","enable","setBlendFuncRGB","setBlendFuncAlpha","useDepthState","enableTest","enableWrite","useRasterizerState","setCullMode"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"drawtext.js","sources":["../../src/helpers/drawtext.ts"],"sourcesContent":["import type { Immutable, Nullable, Rect } from '@zephyr3d/base';\r\nimport { Matrix4x4, parseColor, splitStringByGraphemes, Vector3, Vector4 } from '@zephyr3d/base';\r\nimport { Font } from './font';\r\nimport { GlyphManager } from './glyphmanager';\r\nimport type { RenderStateSet } from '../render_states';\r\nimport type {\r\n AbstractDevice,\r\n DrawTextLayoutOptions,\r\n TextHorizontalAlignment,\r\n TextVerticalAlignment\r\n} from '../base_types';\r\nimport type { BindGroup, GPUProgram, StructuredBuffer, VertexLayout } from '../gpuobject';\r\n\r\nconst MAX_GLYPH_COUNT = 1024;\r\n\r\ntype TextLayoutLine = {\r\n text: string;\r\n width: number;\r\n};\r\n\r\ntype ResolvedTextLayoutOptions = {\r\n halign: TextHorizontalAlignment;\r\n valign: TextVerticalAlignment;\r\n wordWrap: boolean;\r\n};\r\n\r\n/**\r\n * Helper class to draw some text onto the screen\r\n * @public\r\n */\r\nexport class DrawText {\r\n /** @internal */\r\n private static readonly GLYPH_COUNT = MAX_GLYPH_COUNT;\r\n /** @internal */\r\n private static glyphManager: Nullable<GlyphManager> = null;\r\n /** @internal */\r\n private static prepared = false;\r\n /** @internal */\r\n private static textVertexBuffer: Nullable<StructuredBuffer> = null;\r\n /** @internal */\r\n private static textVertexLayout: Nullable<VertexLayout> = null;\r\n /** @internal */\r\n private static textProgram: Nullable<GPUProgram> = null;\r\n /** @internal */\r\n private static textBindGroup: Nullable<BindGroup> = null;\r\n /** @internal */\r\n private static textRenderStates: Nullable<RenderStateSet> = null;\r\n /** @internal */\r\n private static textOffset = 0;\r\n /** @internal */\r\n private static readonly textMatrix = new Matrix4x4();\r\n /** @internal */\r\n private static font: Nullable<Font> = null;\r\n /** @internal */\r\n private static overrideRenderStates: Nullable<RenderStateSet> = null;\r\n /** @internal */\r\n private static vertexCache: Nullable<Float32Array<ArrayBuffer>> = null;\r\n /** @internal */\r\n private static readonly colorValue: Vector4 = new Vector4();\r\n /** @internal */\r\n private static readonly defaultLayoutOptions: ResolvedTextLayoutOptions = {\r\n halign: 'left',\r\n valign: 'top',\r\n wordWrap: false\r\n };\r\n /** @internal */\r\n private static calculateTextMatrix(device: AbstractDevice, matrix: Matrix4x4) {\r\n const viewportWidth = device.getViewport().width;\r\n const viewportHeight = device.getViewport().height;\r\n matrix.identity();\r\n const projectionMatrix = Matrix4x4.ortho(0, viewportWidth, 0, viewportHeight, 1, 100);\r\n const flipMatrix = Matrix4x4.translation(new Vector3(0, viewportHeight, 0)).scaleRight(\r\n new Vector3(1, -1, 1)\r\n );\r\n Matrix4x4.multiply(projectionMatrix, flipMatrix, matrix);\r\n }\r\n /**\r\n * Set the font that will be used to draw strings\r\n * @param device - The render device\r\n * @param name - The font name\r\n */\r\n static setFont(device: AbstractDevice, name: Nullable<string>) {\r\n const scale = device.getScaleY();\r\n this.font = name ? Font.fetchFont(name, scale) : Font.fetchFont('12px arial', scale);\r\n }\r\n /**\r\n * Set render states to be used when drawing text. If not set, default states will be used.\r\n * @param renderStates - The render states to use when drawing text. If null, default states will be used.\r\n */\r\n static setRenderStates(renderStates: Nullable<RenderStateSet>) {\r\n this.overrideRenderStates = renderStates ?? null;\r\n }\r\n /**\r\n * Draw text onto the screen\r\n * @param device - The render device\r\n * @param text - The text to be drawn\r\n * @param color - The text color\r\n * @param x - X coordinate of the text\r\n * @param y - Y coordinate of the text\r\n */\r\n static drawText(\r\n device: AbstractDevice,\r\n text: string,\r\n color: string | Vector3 | Vector4,\r\n x: number,\r\n y: number\r\n ): void;\r\n /**\r\n * Draw text inside a rectangle with layout and clipping\r\n * @param device - The render device\r\n * @param text - The text to be drawn\r\n * @param color - The text color\r\n * @param rect - The layout rectangle\r\n * @param options - Layout options\r\n */\r\n static drawText(\r\n device: AbstractDevice,\r\n text: string,\r\n color: string | Vector3 | Vector4,\r\n rect: Immutable<Rect>,\r\n options?: DrawTextLayoutOptions\r\n ): void;\r\n static drawText(\r\n device: AbstractDevice,\r\n text: string,\r\n color: string | Vector3 | Vector4,\r\n xOrRect: number | Immutable<Rect>,\r\n yOrOptions?: number | DrawTextLayoutOptions\r\n ) {\r\n this.colorToVec4(color, this.colorValue);\r\n if (typeof xOrRect === 'number') {\r\n if (text.length > 0) {\r\n device.pushDeviceStates();\r\n try {\r\n this.beginDrawText(device);\r\n this.drawPreparedText(device, text, xOrRect, yOrOptions as number);\r\n } finally {\r\n device.popDeviceStates();\r\n }\r\n }\r\n return;\r\n }\r\n this.drawTextRect(device, text, xOrRect, yOrOptions as DrawTextLayoutOptions);\r\n }\r\n /** @internal */\r\n private static drawTextRect(\r\n device: AbstractDevice,\r\n text: string,\r\n rect: Immutable<Rect>,\r\n options?: DrawTextLayoutOptions\r\n ) {\r\n if (text.length > 0 && rect.width > 0 && rect.height > 0) {\r\n device.pushDeviceStates();\r\n try {\r\n this.beginDrawText(device);\r\n const viewport = device.getViewport();\r\n const resolved = this.resolveLayoutOptions(options);\r\n const lines = this.layoutText(text, rect.width, resolved.wordWrap);\r\n if (lines.length === 0) {\r\n return;\r\n }\r\n const lineHeight = this.font!.maxHeight;\r\n const blockHeight = lines.length * lineHeight;\r\n let startY = rect.y;\r\n if (resolved.valign === 'center') {\r\n startY += (rect.height - blockHeight) * 0.5;\r\n } else if (resolved.valign === 'bottom') {\r\n startY += rect.height - blockHeight;\r\n }\r\n const absoluteScissorRect = {\r\n x: viewport.x + rect.x,\r\n y: viewport.y + viewport.height - rect.y - rect.height,\r\n width: rect.width,\r\n height: rect.height\r\n };\r\n const currentScissor = device.getScissor();\r\n const clipX = Math.max(absoluteScissorRect.x, currentScissor.x);\r\n const clipY = Math.max(absoluteScissorRect.y, currentScissor.y);\r\n const clipRight = Math.min(\r\n absoluteScissorRect.x + absoluteScissorRect.width,\r\n currentScissor.x + currentScissor.width\r\n );\r\n const clipBottom = Math.min(\r\n absoluteScissorRect.y + absoluteScissorRect.height,\r\n currentScissor.y + currentScissor.height\r\n );\r\n const clipWidth = Math.max(0, clipRight - clipX);\r\n const clipHeight = Math.max(0, clipBottom - clipY);\r\n if (clipWidth <= 0 || clipHeight <= 0) {\r\n return;\r\n }\r\n device.setScissor([clipX, clipY, clipWidth, clipHeight]);\r\n for (let i = 0; i < lines.length; i++) {\r\n const line = lines[i];\r\n const lineY = startY + i * lineHeight;\r\n if (lineY + lineHeight <= rect.y || lineY >= rect.y + rect.height) {\r\n continue;\r\n }\r\n let lineX = rect.x;\r\n if (resolved.halign === 'center') {\r\n lineX += (rect.width - line.width) * 0.5;\r\n } else if (resolved.halign === 'right') {\r\n lineX += rect.width - line.width;\r\n }\r\n this.drawPreparedText(device, line.text, lineX, lineY);\r\n }\r\n } finally {\r\n device.popDeviceStates();\r\n }\r\n }\r\n }\r\n /** @internal */\r\n private static drawTextNoOverflow(\r\n device: AbstractDevice,\r\n text: string[],\r\n start: number,\r\n count: number,\r\n x: number,\r\n y: number\r\n ) {\r\n let drawn = 0;\r\n let atlasIndex = -1;\r\n let i = 0;\r\n const vertexCache = this.vertexCache!;\r\n for (; i < count; i++) {\r\n const glyph =\r\n this.glyphManager!.getGlyphInfo(text[i + start], this.font!) ||\r\n this.glyphManager!.getGlyphInfo('?', this.font!)!;\r\n if (atlasIndex >= 0 && glyph.atlasIndex !== atlasIndex) {\r\n this.textVertexBuffer!.bufferSubData(\r\n (this.textOffset + drawn) * 16 * 4,\r\n this.vertexCache!,\r\n (this.textOffset + drawn) * 16,\r\n (i - drawn) * 16\r\n );\r\n this.textBindGroup!.setTexture('tex', this.glyphManager!.getAtlasTexture(atlasIndex)!);\r\n device.draw('triangle-list', (this.textOffset + drawn) * 6, (i - drawn) * 6);\r\n drawn = i;\r\n }\r\n atlasIndex = glyph.atlasIndex;\r\n const base = (this.textOffset + i) * 16;\r\n vertexCache[base + 0] = x;\r\n vertexCache[base + 1] = y;\r\n vertexCache[base + 2] = glyph.uMin;\r\n vertexCache[base + 3] = glyph.vMin;\r\n vertexCache[base + 4] = x + glyph.width;\r\n vertexCache[base + 5] = y;\r\n vertexCache[base + 6] = glyph.uMax;\r\n vertexCache[base + 7] = glyph.vMin;\r\n vertexCache[base + 8] = x + glyph.width;\r\n vertexCache[base + 9] = y + glyph.height;\r\n vertexCache[base + 10] = glyph.uMax;\r\n vertexCache[base + 11] = glyph.vMax;\r\n vertexCache[base + 12] = x;\r\n vertexCache[base + 13] = y + glyph.height;\r\n vertexCache[base + 14] = glyph.uMin;\r\n vertexCache[base + 15] = glyph.vMax;\r\n x += glyph.width;\r\n }\r\n this.textVertexBuffer!.bufferSubData(\r\n (this.textOffset + drawn) * 16 * 4,\r\n vertexCache,\r\n (this.textOffset + drawn) * 16,\r\n (i - drawn) * 16\r\n );\r\n this.textBindGroup!.setTexture('tex', this.glyphManager!.getAtlasTexture(atlasIndex)!);\r\n device.draw('triangle-list', (this.textOffset + drawn) * 6, (i - drawn) * 6);\r\n return x;\r\n }\r\n /** @internal */\r\n private static colorToVec4(color: string | Vector3 | Vector4, out: Vector4): Vector4 {\r\n if (typeof color === 'string') {\r\n const colorValue = parseColor(color);\r\n out.setXYZW(colorValue.r, colorValue.g, colorValue.b, colorValue.a);\r\n } else if (color instanceof Vector3) {\r\n out.setXYZW(color.x, color.y, color.z, 1);\r\n } else {\r\n out.set(color);\r\n }\r\n return out;\r\n }\r\n /** @internal */\r\n private static beginDrawText(device: AbstractDevice) {\r\n this.prepareDrawText(device);\r\n this.calculateTextMatrix(device, this.textMatrix);\r\n this.textBindGroup!.setValue('flip', device.type === 'webgpu' && device.getFramebuffer() ? 1 : 0);\r\n this.textBindGroup!.setValue('srgbOut', device.getFramebuffer() ? 0 : 1);\r\n this.textBindGroup!.setValue('textMatrix', this.textMatrix);\r\n this.textBindGroup!.setValue('textColor', this.colorValue);\r\n device.setProgram(this.textProgram!);\r\n device.setVertexLayout(this.textVertexLayout!);\r\n device.setRenderStates(this.overrideRenderStates ?? this.textRenderStates!);\r\n device.setBindGroup(0, this.textBindGroup!);\r\n }\r\n /** @internal */\r\n private static drawPreparedText(device: AbstractDevice, text: string, x: number, y: number) {\r\n let drawn = 0;\r\n const splitted = splitStringByGraphemes(text);\r\n const total = splitted.length;\r\n while (drawn < total) {\r\n const count = Math.min(total - drawn, this.GLYPH_COUNT - this.textOffset);\r\n if (count > 0) {\r\n x = this.drawTextNoOverflow(device, splitted, drawn, count, x, y);\r\n drawn += count;\r\n this.textOffset += count;\r\n }\r\n if (this.GLYPH_COUNT === this.textOffset) {\r\n this.textOffset = 0;\r\n device.flush();\r\n }\r\n }\r\n }\r\n /** @internal */\r\n private static resolveLayoutOptions(options?: DrawTextLayoutOptions): ResolvedTextLayoutOptions {\r\n return {\r\n halign: options?.halign ?? this.defaultLayoutOptions.halign,\r\n valign: options?.valign ?? this.defaultLayoutOptions.valign,\r\n wordWrap: options?.wordWrap ?? this.defaultLayoutOptions.wordWrap\r\n };\r\n }\r\n /** @internal */\r\n private static layoutText(text: string, maxWidth: number, wordWrap: boolean): TextLayoutLine[] {\r\n const result: TextLayoutLine[] = [];\r\n const paragraphs = text.split(/\\r\\n|\\r|\\n/);\r\n for (const paragraph of paragraphs) {\r\n if (!wordWrap) {\r\n result.push({\r\n text: paragraph,\r\n width: this.measureLineWidth(paragraph)\r\n });\r\n continue;\r\n }\r\n this.layoutWrappedParagraph(paragraph, maxWidth, result);\r\n }\r\n return result;\r\n }\r\n /** @internal */\r\n private static layoutWrappedParagraph(text: string, maxWidth: number, out: TextLayoutLine[]) {\r\n if (text.length === 0) {\r\n out.push({ text: '', width: 0 });\r\n return;\r\n }\r\n const chars = splitStringByGraphemes(text);\r\n let start = 0;\r\n while (start < chars.length) {\r\n let width = 0;\r\n let breakPos = start;\r\n let lastWhitespaceBreak = -1;\r\n while (breakPos < chars.length) {\r\n const ch = chars[breakPos];\r\n const charWidth = this.glyphManager!.getCharWidth(ch, this.font!);\r\n if (breakPos > start && width + charWidth > maxWidth) {\r\n break;\r\n }\r\n width += charWidth;\r\n breakPos++;\r\n if (/^\\s$/u.test(ch)) {\r\n lastWhitespaceBreak = breakPos;\r\n }\r\n }\r\n if (breakPos < chars.length && lastWhitespaceBreak > start) {\r\n const lineText = chars.slice(start, lastWhitespaceBreak).join('').replace(/\\s+$/u, '');\r\n out.push({\r\n text: lineText,\r\n width: this.measureLineWidth(lineText)\r\n });\r\n start = lastWhitespaceBreak;\r\n while (start < chars.length && /^\\s$/u.test(chars[start])) {\r\n start++;\r\n }\r\n } else {\r\n const lineText = chars.slice(start, breakPos).join('');\r\n out.push({\r\n text: lineText,\r\n width\r\n });\r\n start = Math.max(breakPos, start + 1);\r\n }\r\n }\r\n }\r\n /** @internal */\r\n private static measureLineWidth(text: string) {\r\n if (!text) {\r\n return 0;\r\n }\r\n let width = 0;\r\n for (const ch of splitStringByGraphemes(text)) {\r\n width += this.glyphManager!.getCharWidth(ch, this.font!);\r\n }\r\n return width;\r\n }\r\n /** @internal */\r\n private static prepareDrawText(device: AbstractDevice) {\r\n if (!this.prepared) {\r\n this.prepared = true;\r\n this.font = this.font || Font.fetchFont('12px arial', device.getScaleY());\r\n this.glyphManager = new GlyphManager(device, 1024, 1024, 1);\r\n this.vertexCache = new Float32Array(this.GLYPH_COUNT * 16);\r\n this.textVertexBuffer = device.createInterleavedVertexBuffer(\r\n ['position_f32x2', 'tex0_f32x2'],\r\n this.vertexCache,\r\n {\r\n dynamic: true\r\n }\r\n );\r\n const indices = new Uint16Array(this.GLYPH_COUNT * 6);\r\n for (let i = 0; i < this.GLYPH_COUNT; i++) {\r\n const base = i * 4;\r\n indices[i * 6 + 0] = base + 0;\r\n indices[i * 6 + 1] = base + 1;\r\n indices[i * 6 + 2] = base + 2;\r\n indices[i * 6 + 3] = base + 0;\r\n indices[i * 6 + 4] = base + 2;\r\n indices[i * 6 + 5] = base + 3;\r\n }\r\n const textIndexBuffer = device.createIndexBuffer(indices);\r\n this.textVertexLayout = device.createVertexLayout({\r\n vertexBuffers: [{ buffer: this.textVertexBuffer! }],\r\n indexBuffer: textIndexBuffer\r\n });\r\n this.textOffset = 0;\r\n this.textProgram = device.buildRenderProgram({\r\n vertex(pb) {\r\n this.$inputs.pos = pb.vec2().attrib('position');\r\n this.$inputs.uv = pb.vec2().attrib('texCoord0');\r\n this.$outputs.uv = pb.vec2();\r\n this.flip = pb.int(0).uniform(0);\r\n this.textMatrix = pb.mat4().uniform(0);\r\n pb.main(function () {\r\n this.$builtins.position = pb.mul(this.textMatrix, pb.vec4(this.$inputs.pos, -50, 1));\r\n this.$if(pb.notEqual(this.flip, 0), function () {\r\n this.$builtins.position.y = pb.neg(this.$builtins.position.y);\r\n });\r\n this.$outputs.uv = this.$inputs.uv;\r\n });\r\n },\r\n fragment(pb) {\r\n this.$outputs.color = pb.vec4();\r\n this.textColor = pb.vec4().uniform(0);\r\n this.tex = pb.tex2D().uniform(0);\r\n this.srgbOut = pb.int().uniform(0);\r\n pb.main(function () {\r\n this.alpha = pb.mul(pb.textureSample(this.tex, this.$inputs.uv).a, this.textColor.a);\r\n this.$if(pb.notEqual(this.srgbOut, 0), function () {\r\n this.$outputs.color = pb.vec4(\r\n pb.mul(pb.pow(this.textColor.rgb, pb.vec3(1 / 2.2)), this.alpha),\r\n this.alpha\r\n );\r\n }).$else(function () {\r\n this.$outputs.color = pb.vec4(pb.mul(this.textColor.rgb, this.alpha), this.alpha);\r\n });\r\n });\r\n }\r\n });\r\n this.textProgram!.name = '@DrawText';\r\n this.textBindGroup = device.createBindGroup(this.textProgram!.bindGroupLayouts[0]);\r\n this.textRenderStates = device.createRenderStateSet();\r\n this.textRenderStates\r\n .useBlendingState()\r\n .enable(true)\r\n .setBlendFuncRGB('one', 'inv-src-alpha')\r\n .setBlendFuncAlpha('zero', 'one');\r\n this.textRenderStates.useDepthState().enableTest(false).enableWrite(false);\r\n this.textRenderStates.useRasterizerState().setCullMode('none');\r\n }\r\n }\r\n}\r\n"],"names":["MAX_GLYPH_COUNT","DrawText","GLYPH_COUNT","glyphManager","prepared","textVertexBuffer","textVertexLayout","textProgram","textBindGroup","textRenderStates","textOffset","textMatrix","Matrix4x4","font","overrideRenderStates","vertexCache","colorValue","Vector4","defaultLayoutOptions","halign","valign","wordWrap","calculateTextMatrix","device","matrix","viewportWidth","getViewport","width","viewportHeight","height","identity","projectionMatrix","ortho","flipMatrix","translation","Vector3","scaleRight","multiply","setFont","name","scale","getScaleY","Font","fetchFont","setRenderStates","renderStates","drawText","text","color","xOrRect","yOrOptions","colorToVec4","length","pushDeviceStates","beginDrawText","drawPreparedText","popDeviceStates","drawTextRect","rect","options","viewport","resolved","resolveLayoutOptions","lines","layoutText","lineHeight","maxHeight","blockHeight","startY","y","absoluteScissorRect","x","currentScissor","getScissor","clipX","Math","max","clipY","clipRight","min","clipBottom","clipWidth","clipHeight","setScissor","i","line","lineY","lineX","drawTextNoOverflow","start","count","drawn","atlasIndex","glyph","getGlyphInfo","bufferSubData","setTexture","getAtlasTexture","draw","base","uMin","vMin","uMax","vMax","out","parseColor","setXYZW","r","g","b","a","z","set","prepareDrawText","setValue","type","getFramebuffer","setProgram","setVertexLayout","setBindGroup","splitted","splitStringByGraphemes","total","flush","maxWidth","result","paragraphs","split","paragraph","push","measureLineWidth","layoutWrappedParagraph","chars","breakPos","lastWhitespaceBreak","ch","charWidth","getCharWidth","test","lineText","slice","join","replace","GlyphManager","Float32Array","createInterleavedVertexBuffer","dynamic","indices","Uint16Array","textIndexBuffer","createIndexBuffer","createVertexLayout","vertexBuffers","buffer","indexBuffer","buildRenderProgram","vertex","pb","$inputs","pos","vec2","attrib","uv","$outputs","flip","int","uniform","mat4","main","$builtins","position","mul","vec4","$if","notEqual","neg","fragment","textColor","tex","tex2D","srgbOut","alpha","textureSample","pow","rgb","vec3","$else","createBindGroup","bindGroupLayouts","createRenderStateSet","useBlendingState","enable","setBlendFuncRGB","setBlendFuncAlpha","useDepthState","enableTest","enableWrite","useRasterizerState","setCullMode"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RectsPacker } from '@zephyr3d/base';
|
|
1
|
+
import { RectsPacker, DRef } from '@zephyr3d/base';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Texture atlas manager
|
|
@@ -47,7 +47,22 @@ import { RectsPacker } from '@zephyr3d/base';
|
|
|
47
47
|
* @param index - Index of the atlas bin
|
|
48
48
|
* @returns Atlas texture for given index
|
|
49
49
|
*/ getAtlasTexture(index) {
|
|
50
|
-
return this._atlasList[index];
|
|
50
|
+
return this._atlasList[index]?.get() ?? undefined;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Width of each atlas bin in texels.
|
|
54
|
+
*/ get binWidth() {
|
|
55
|
+
return this._binWidth;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Height of each atlas bin in texels.
|
|
59
|
+
*/ get binHeight() {
|
|
60
|
+
return this._binHeight;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Border reserved around each packed rectangle in texels.
|
|
64
|
+
*/ get rectBorderWidth() {
|
|
65
|
+
return this._rectBorderWidth;
|
|
51
66
|
}
|
|
52
67
|
/**
|
|
53
68
|
* Gets the information about specified atlas
|
|
@@ -145,9 +160,9 @@ import { RectsPacker } from '@zephyr3d/base';
|
|
|
145
160
|
let textureAtlas;
|
|
146
161
|
if (atlasIndex === this._atlasList.length) {
|
|
147
162
|
textureAtlas = this._createAtlasTexture();
|
|
148
|
-
this._atlasList.push(textureAtlas);
|
|
163
|
+
this._atlasList.push(new DRef(textureAtlas));
|
|
149
164
|
} else {
|
|
150
|
-
textureAtlas = this._atlasList[atlasIndex];
|
|
165
|
+
textureAtlas = this._atlasList[atlasIndex].get();
|
|
151
166
|
}
|
|
152
167
|
textureAtlas.updateFromElement(ctx.canvas, x, y, xOffset, yOffset, w, h);
|
|
153
168
|
}
|
|
@@ -155,9 +170,9 @@ import { RectsPacker } from '@zephyr3d/base';
|
|
|
155
170
|
let textureAtlas;
|
|
156
171
|
if (atlasIndex === this._atlasList.length) {
|
|
157
172
|
textureAtlas = this._createAtlasTexture();
|
|
158
|
-
this._atlasList.push(textureAtlas);
|
|
173
|
+
this._atlasList.push(new DRef(textureAtlas));
|
|
159
174
|
} else {
|
|
160
|
-
textureAtlas = this._atlasList[atlasIndex];
|
|
175
|
+
textureAtlas = this._atlasList[atlasIndex].get();
|
|
161
176
|
}
|
|
162
177
|
if (bitmap instanceof ImageBitmap) {
|
|
163
178
|
textureAtlas.updateFromElement(bitmap, x, y, 0, 0, bitmap.width, bitmap.height);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"textureatlas.js","sources":["../../src/helpers/textureatlas.ts"],"sourcesContent":["import type { Nullable } from '@zephyr3d/base';\r\nimport { RectsPacker } from '@zephyr3d/base';\r\nimport type { AbstractDevice, TextureFormat } from '../base_types';\r\nimport type { BaseTexture, Texture2D } from '../gpuobject';\r\n\r\n/**\r\n * Information of a texture atlas\r\n * @public\r\n */\r\nexport interface AtlasInfo {\r\n atlasIndex: number;\r\n width: number;\r\n height: number;\r\n uMin: number;\r\n vMin: number;\r\n uMax: number;\r\n vMax: number;\r\n}\r\n\r\n/**\r\n * Texture atlas manager\r\n * @public\r\n */\r\nexport class TextureAtlasManager {\r\n /** @internal */\r\n protected static readonly ATLAS_WIDTH = 1024;\r\n /** @internal */\r\n protected static readonly ATLAS_HEIGHT = 1024;\r\n /** @internal */\r\n protected _packer: RectsPacker;\r\n /** @internal */\r\n protected _device: AbstractDevice;\r\n /** @internal */\r\n protected _binWidth: number;\r\n /** @internal */\r\n protected _binHeight: number;\r\n /** @internal */\r\n protected _rectBorderWidth: number;\r\n /** @internal */\r\n protected _linearSpace: boolean;\r\n /** @internal */\r\n protected _atlasList: Partial<Texture2D[]>;\r\n /** @internal */\r\n protected _atlasInfoMap: Partial<Record<string, AtlasInfo>>;\r\n /** @internal */\r\n protected _atlasRestoreHandler: Nullable<(tex: BaseTexture) => void>;\r\n /**\r\n * Creates a new texture atlas manager instance\r\n * @param device - The render device\r\n * @param binWidth - Width of an atlas bin\r\n * @param binHeight - Height of an atlas bin\r\n * @param rectBorderWidth - Border width of an atlas\r\n * @param linearSpace - true if the texture space is linear\r\n */\r\n constructor(\r\n device: AbstractDevice,\r\n binWidth: number,\r\n binHeight: number,\r\n rectBorderWidth: number,\r\n linearSpace?: boolean\r\n ) {\r\n this._device = device;\r\n this._binWidth = binWidth;\r\n this._binHeight = binHeight;\r\n this._rectBorderWidth = rectBorderWidth;\r\n this._linearSpace = !!linearSpace;\r\n this._packer = new RectsPacker(this._binWidth, this._binHeight);\r\n this._atlasList = [];\r\n this._atlasInfoMap = {};\r\n this._atlasRestoreHandler = null;\r\n }\r\n /**\r\n * The texture restore handler callback function\r\n * This callback function will be called whenever the device has been restored\r\n */\r\n get atlasTextureRestoreHandler() {\r\n return this._atlasRestoreHandler;\r\n }\r\n set atlasTextureRestoreHandler(f) {\r\n this._atlasRestoreHandler = f;\r\n }\r\n /**\r\n * Gets the atlas texture of a given index\r\n * @param index - Index of the atlas bin\r\n * @returns Atlas texture for given index\r\n */\r\n getAtlasTexture(index: number) {\r\n return this._atlasList[index];\r\n }\r\n /**\r\n * Gets the information about specified atlas\r\n * @param key - Key of the atlas\r\n * @returns Information of the atlas\r\n */\r\n getAtlasInfo(key: string) {\r\n return this._atlasInfoMap[key] || null;\r\n }\r\n /**\r\n * Check if no atlas has been created\r\n * @returns true if no atlas has been created\r\n */\r\n isEmpty() {\r\n return this._atlasList.length === 0;\r\n }\r\n /**\r\n * Removes all created atlases\r\n */\r\n clear() {\r\n this._packer.clear();\r\n for (const tex of this._atlasList) {\r\n tex!.dispose();\r\n }\r\n this._atlasList = [];\r\n this._atlasInfoMap = {};\r\n }\r\n /**\r\n * Inserts a rectangle of a canvas to the atlas texture\r\n * @param key - Key of the atlas\r\n * @param ctx - The canvas context\r\n * @param x - x offset of the rectangle\r\n * @param y - y offset of the rectangle\r\n * @param w - width of the rectangle\r\n * @param h - height of the rectangle\r\n * @returns The atals info or null if insert failed\r\n */\r\n pushCanvas(key: string, ctx: CanvasRenderingContext2D, x: number, y: number, w: number, h: number) {\r\n const rc = this._packer.insert(w + 2 * this._rectBorderWidth, h + 2 * this._rectBorderWidth);\r\n if (rc) {\r\n const atlasX = rc.x + this._rectBorderWidth;\r\n const atlasY = rc.y + this._rectBorderWidth;\r\n this._updateAtlasTextureCanvas(rc.binIndex, ctx, atlasX, atlasY, w, h, x, y);\r\n const info: AtlasInfo = {\r\n atlasIndex: rc.binIndex,\r\n uMin: atlasX / this._binWidth,\r\n vMin: atlasY / this._binHeight,\r\n uMax: (atlasX + w) / this._binWidth,\r\n vMax: (atlasY + h) / this._binHeight,\r\n width: w,\r\n height: h\r\n };\r\n this._atlasInfoMap[key] = info;\r\n return info;\r\n }\r\n return null;\r\n }\r\n /**\r\n * Inserts a bitmap to the atlas texture\r\n * @param key - Key of the atlas\r\n * @param bitmap - The bitmap object\r\n * @returns The atals info or null if insert failed\r\n */\r\n pushBitmap(key: string, bitmap: ImageData | ImageBitmap) {\r\n const rc = this._packer.insert(\r\n bitmap.width + 2 * this._rectBorderWidth,\r\n bitmap.height + 2 * this._rectBorderWidth\r\n );\r\n if (rc) {\r\n const atlasX = rc.x + this._rectBorderWidth;\r\n const atlasY = rc.y + this._rectBorderWidth;\r\n this._updateAtlasTexture(rc.binIndex, bitmap, atlasX, atlasY);\r\n const info: AtlasInfo = {\r\n atlasIndex: rc.binIndex,\r\n uMin: atlasX / this._binWidth,\r\n vMin: atlasY / this._binHeight,\r\n uMax: (atlasX + bitmap.width) / this._binWidth,\r\n vMax: (atlasY + bitmap.height) / this._binHeight,\r\n width: bitmap.width,\r\n height: bitmap.height\r\n };\r\n this._atlasInfoMap[key] = info;\r\n return info;\r\n }\r\n return null;\r\n }\r\n /** @internal */\r\n protected _createAtlasTexture() {\r\n const format: TextureFormat = 'rgba8unorm';\r\n const tex = this._device.createTexture2D(format, this._binWidth, this._binHeight, {\r\n mipmapping: false\r\n });\r\n if (!tex) {\r\n throw new Error(`Create 2D texture failed: ${format}-${this._binWidth}x${this._binHeight}`);\r\n }\r\n tex.update(new Uint8Array(tex.width * tex.height * 4), 0, 0, tex.width, tex.height);\r\n tex.restoreHandler = () => {\r\n tex.update(new Uint8Array(tex.width * tex.height * 4), 0, 0, tex.width, tex.height);\r\n this._atlasRestoreHandler?.(tex);\r\n };\r\n return tex;\r\n }\r\n /** @internal */\r\n private _updateAtlasTextureCanvas(\r\n atlasIndex: number,\r\n ctx: CanvasRenderingContext2D,\r\n x: number,\r\n y: number,\r\n w: number,\r\n h: number,\r\n xOffset: number,\r\n yOffset: number\r\n ) {\r\n let textureAtlas: Texture2D;\r\n if (atlasIndex === this._atlasList.length) {\r\n textureAtlas = this._createAtlasTexture();\r\n this._atlasList.push(textureAtlas);\r\n } else {\r\n textureAtlas = this._atlasList[atlasIndex]!;\r\n }\r\n textureAtlas.updateFromElement(ctx.canvas, x, y, xOffset, yOffset, w, h);\r\n }\r\n /** @internal */\r\n private _updateAtlasTexture(atlasIndex: number, bitmap: ImageData | ImageBitmap, x: number, y: number) {\r\n let textureAtlas: Texture2D;\r\n if (atlasIndex === this._atlasList.length) {\r\n textureAtlas = this._createAtlasTexture();\r\n this._atlasList.push(textureAtlas);\r\n } else {\r\n textureAtlas = this._atlasList[atlasIndex]!;\r\n }\r\n if (bitmap instanceof ImageBitmap) {\r\n textureAtlas.updateFromElement(bitmap, x, y, 0, 0, bitmap.width, bitmap.height);\r\n } else {\r\n const originValues = new Uint8Array(bitmap.data.buffer);\r\n textureAtlas.update(originValues, x, y, bitmap.width, bitmap.height);\r\n }\r\n }\r\n}\r\n"],"names":["TextureAtlasManager","ATLAS_WIDTH","ATLAS_HEIGHT","device","binWidth","binHeight","rectBorderWidth","linearSpace","_device","_binWidth","_binHeight","_rectBorderWidth","_linearSpace","_packer","RectsPacker","_atlasList","_atlasInfoMap","_atlasRestoreHandler","atlasTextureRestoreHandler","f","getAtlasTexture","index","getAtlasInfo","key","isEmpty","length","clear","tex","dispose","pushCanvas","ctx","x","y","w","h","rc","insert","atlasX","atlasY","_updateAtlasTextureCanvas","binIndex","info","atlasIndex","uMin","vMin","uMax","vMax","width","height","pushBitmap","bitmap","_updateAtlasTexture","format","createTexture2D","mipmapping","Error","update","Uint8Array","restoreHandler","xOffset","yOffset","textureAtlas","_createAtlasTexture","push","updateFromElement","canvas","ImageBitmap","originValues","data","buffer"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"textureatlas.js","sources":["../../src/helpers/textureatlas.ts"],"sourcesContent":["import type { Nullable } from '@zephyr3d/base';\r\nimport { DRef } from '@zephyr3d/base';\r\nimport { RectsPacker } from '@zephyr3d/base';\r\nimport type { AbstractDevice, TextureFormat } from '../base_types';\r\nimport type { BaseTexture, Texture2D } from '../gpuobject';\r\n\r\n/**\r\n * Information of a texture atlas\r\n * @public\r\n */\r\nexport interface AtlasInfo {\r\n atlasIndex: number;\r\n width: number;\r\n height: number;\r\n uMin: number;\r\n vMin: number;\r\n uMax: number;\r\n vMax: number;\r\n}\r\n\r\n/**\r\n * Texture atlas manager\r\n * @public\r\n */\r\nexport class TextureAtlasManager {\r\n /** @internal */\r\n protected static readonly ATLAS_WIDTH = 1024;\r\n /** @internal */\r\n protected static readonly ATLAS_HEIGHT = 1024;\r\n /** @internal */\r\n protected _packer: RectsPacker;\r\n /** @internal */\r\n protected _device: AbstractDevice;\r\n /** @internal */\r\n protected _binWidth: number;\r\n /** @internal */\r\n protected _binHeight: number;\r\n /** @internal */\r\n protected _rectBorderWidth: number;\r\n /** @internal */\r\n protected _linearSpace: boolean;\r\n /** @internal */\r\n protected _atlasList: DRef<Texture2D>[];\r\n /** @internal */\r\n protected _atlasInfoMap: Partial<Record<string, AtlasInfo>>;\r\n /** @internal */\r\n protected _atlasRestoreHandler: Nullable<(tex: BaseTexture) => void>;\r\n /**\r\n * Creates a new texture atlas manager instance\r\n * @param device - The render device\r\n * @param binWidth - Width of an atlas bin\r\n * @param binHeight - Height of an atlas bin\r\n * @param rectBorderWidth - Border width of an atlas\r\n * @param linearSpace - true if the texture space is linear\r\n */\r\n constructor(\r\n device: AbstractDevice,\r\n binWidth: number,\r\n binHeight: number,\r\n rectBorderWidth: number,\r\n linearSpace?: boolean\r\n ) {\r\n this._device = device;\r\n this._binWidth = binWidth;\r\n this._binHeight = binHeight;\r\n this._rectBorderWidth = rectBorderWidth;\r\n this._linearSpace = !!linearSpace;\r\n this._packer = new RectsPacker(this._binWidth, this._binHeight);\r\n this._atlasList = [];\r\n this._atlasInfoMap = {};\r\n this._atlasRestoreHandler = null;\r\n }\r\n /**\r\n * The texture restore handler callback function\r\n * This callback function will be called whenever the device has been restored\r\n */\r\n get atlasTextureRestoreHandler() {\r\n return this._atlasRestoreHandler;\r\n }\r\n set atlasTextureRestoreHandler(f) {\r\n this._atlasRestoreHandler = f;\r\n }\r\n /**\r\n * Gets the atlas texture of a given index\r\n * @param index - Index of the atlas bin\r\n * @returns Atlas texture for given index\r\n */\r\n getAtlasTexture(index: number) {\r\n return this._atlasList[index]?.get() ?? undefined;\r\n }\r\n /**\r\n * Width of each atlas bin in texels.\r\n */\r\n get binWidth() {\r\n return this._binWidth;\r\n }\r\n /**\r\n * Height of each atlas bin in texels.\r\n */\r\n get binHeight() {\r\n return this._binHeight;\r\n }\r\n /**\r\n * Border reserved around each packed rectangle in texels.\r\n */\r\n get rectBorderWidth() {\r\n return this._rectBorderWidth;\r\n }\r\n /**\r\n * Gets the information about specified atlas\r\n * @param key - Key of the atlas\r\n * @returns Information of the atlas\r\n */\r\n getAtlasInfo(key: string) {\r\n return this._atlasInfoMap[key] || null;\r\n }\r\n /**\r\n * Check if no atlas has been created\r\n * @returns true if no atlas has been created\r\n */\r\n isEmpty() {\r\n return this._atlasList.length === 0;\r\n }\r\n /**\r\n * Removes all created atlases\r\n */\r\n clear() {\r\n this._packer.clear();\r\n for (const tex of this._atlasList) {\r\n tex!.dispose();\r\n }\r\n this._atlasList = [];\r\n this._atlasInfoMap = {};\r\n }\r\n /**\r\n * Inserts a rectangle of a canvas to the atlas texture\r\n * @param key - Key of the atlas\r\n * @param ctx - The canvas context\r\n * @param x - x offset of the rectangle\r\n * @param y - y offset of the rectangle\r\n * @param w - width of the rectangle\r\n * @param h - height of the rectangle\r\n * @returns The atals info or null if insert failed\r\n */\r\n pushCanvas(key: string, ctx: CanvasRenderingContext2D, x: number, y: number, w: number, h: number) {\r\n const rc = this._packer.insert(w + 2 * this._rectBorderWidth, h + 2 * this._rectBorderWidth);\r\n if (rc) {\r\n const atlasX = rc.x + this._rectBorderWidth;\r\n const atlasY = rc.y + this._rectBorderWidth;\r\n this._updateAtlasTextureCanvas(rc.binIndex, ctx, atlasX, atlasY, w, h, x, y);\r\n const info: AtlasInfo = {\r\n atlasIndex: rc.binIndex,\r\n uMin: atlasX / this._binWidth,\r\n vMin: atlasY / this._binHeight,\r\n uMax: (atlasX + w) / this._binWidth,\r\n vMax: (atlasY + h) / this._binHeight,\r\n width: w,\r\n height: h\r\n };\r\n this._atlasInfoMap[key] = info;\r\n return info;\r\n }\r\n return null;\r\n }\r\n /**\r\n * Inserts a bitmap to the atlas texture\r\n * @param key - Key of the atlas\r\n * @param bitmap - The bitmap object\r\n * @returns The atals info or null if insert failed\r\n */\r\n pushBitmap(key: string, bitmap: ImageData | ImageBitmap) {\r\n const rc = this._packer.insert(\r\n bitmap.width + 2 * this._rectBorderWidth,\r\n bitmap.height + 2 * this._rectBorderWidth\r\n );\r\n if (rc) {\r\n const atlasX = rc.x + this._rectBorderWidth;\r\n const atlasY = rc.y + this._rectBorderWidth;\r\n this._updateAtlasTexture(rc.binIndex, bitmap, atlasX, atlasY);\r\n const info: AtlasInfo = {\r\n atlasIndex: rc.binIndex,\r\n uMin: atlasX / this._binWidth,\r\n vMin: atlasY / this._binHeight,\r\n uMax: (atlasX + bitmap.width) / this._binWidth,\r\n vMax: (atlasY + bitmap.height) / this._binHeight,\r\n width: bitmap.width,\r\n height: bitmap.height\r\n };\r\n this._atlasInfoMap[key] = info;\r\n return info;\r\n }\r\n return null;\r\n }\r\n /** @internal */\r\n protected _createAtlasTexture() {\r\n const format: TextureFormat = 'rgba8unorm';\r\n const tex = this._device.createTexture2D(format, this._binWidth, this._binHeight, {\r\n mipmapping: false\r\n });\r\n if (!tex) {\r\n throw new Error(`Create 2D texture failed: ${format}-${this._binWidth}x${this._binHeight}`);\r\n }\r\n tex.update(new Uint8Array(tex.width * tex.height * 4), 0, 0, tex.width, tex.height);\r\n tex.restoreHandler = () => {\r\n tex.update(new Uint8Array(tex.width * tex.height * 4), 0, 0, tex.width, tex.height);\r\n this._atlasRestoreHandler?.(tex);\r\n };\r\n return tex;\r\n }\r\n /** @internal */\r\n private _updateAtlasTextureCanvas(\r\n atlasIndex: number,\r\n ctx: CanvasRenderingContext2D,\r\n x: number,\r\n y: number,\r\n w: number,\r\n h: number,\r\n xOffset: number,\r\n yOffset: number\r\n ) {\r\n let textureAtlas: Texture2D;\r\n if (atlasIndex === this._atlasList.length) {\r\n textureAtlas = this._createAtlasTexture();\r\n this._atlasList.push(new DRef(textureAtlas));\r\n } else {\r\n textureAtlas = this._atlasList[atlasIndex]!.get()!;\r\n }\r\n textureAtlas.updateFromElement(ctx.canvas, x, y, xOffset, yOffset, w, h);\r\n }\r\n /** @internal */\r\n private _updateAtlasTexture(atlasIndex: number, bitmap: ImageData | ImageBitmap, x: number, y: number) {\r\n let textureAtlas: Texture2D;\r\n if (atlasIndex === this._atlasList.length) {\r\n textureAtlas = this._createAtlasTexture();\r\n this._atlasList.push(new DRef(textureAtlas));\r\n } else {\r\n textureAtlas = this._atlasList[atlasIndex]!.get()!;\r\n }\r\n if (bitmap instanceof ImageBitmap) {\r\n textureAtlas.updateFromElement(bitmap, x, y, 0, 0, bitmap.width, bitmap.height);\r\n } else {\r\n const originValues = new Uint8Array(bitmap.data.buffer);\r\n textureAtlas.update(originValues, x, y, bitmap.width, bitmap.height);\r\n }\r\n }\r\n}\r\n"],"names":["TextureAtlasManager","ATLAS_WIDTH","ATLAS_HEIGHT","device","binWidth","binHeight","rectBorderWidth","linearSpace","_device","_binWidth","_binHeight","_rectBorderWidth","_linearSpace","_packer","RectsPacker","_atlasList","_atlasInfoMap","_atlasRestoreHandler","atlasTextureRestoreHandler","f","getAtlasTexture","index","get","undefined","getAtlasInfo","key","isEmpty","length","clear","tex","dispose","pushCanvas","ctx","x","y","w","h","rc","insert","atlasX","atlasY","_updateAtlasTextureCanvas","binIndex","info","atlasIndex","uMin","vMin","uMax","vMax","width","height","pushBitmap","bitmap","_updateAtlasTexture","format","createTexture2D","mipmapping","Error","update","Uint8Array","restoreHandler","xOffset","yOffset","textureAtlas","_createAtlasTexture","push","DRef","updateFromElement","canvas","ImageBitmap","originValues","data","buffer"],"mappings":"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"}
|