@zephyr3d/device 0.2.5 → 0.2.7

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.
Files changed (41) hide show
  1. package/dist/base_types.js +12 -13
  2. package/dist/base_types.js.map +1 -1
  3. package/dist/builder/ast.js +34 -48
  4. package/dist/builder/ast.js.map +1 -1
  5. package/dist/builder/base.js +6 -2
  6. package/dist/builder/base.js.map +1 -1
  7. package/dist/builder/builtinfunc.js +42 -6
  8. package/dist/builder/builtinfunc.js.map +1 -1
  9. package/dist/builder/constructors.js +2 -0
  10. package/dist/builder/constructors.js.map +1 -1
  11. package/dist/builder/errors.js +4 -4
  12. package/dist/builder/errors.js.map +1 -1
  13. package/dist/builder/misc.js +1 -1
  14. package/dist/builder/misc.js.map +1 -1
  15. package/dist/builder/programbuilder.js +18 -27
  16. package/dist/builder/programbuilder.js.map +1 -1
  17. package/dist/builder/reflection.js +1 -1
  18. package/dist/builder/reflection.js.map +1 -1
  19. package/dist/builder/types.js +7 -6
  20. package/dist/builder/types.js.map +1 -1
  21. package/dist/device.js +148 -39
  22. package/dist/device.js.map +1 -1
  23. package/dist/gpuobject.js +2 -1
  24. package/dist/gpuobject.js.map +1 -1
  25. package/dist/helpers/drawtext.js +29 -25
  26. package/dist/helpers/drawtext.js.map +1 -1
  27. package/dist/helpers/font.js.map +1 -1
  28. package/dist/helpers/glyphmanager.js +26 -8
  29. package/dist/helpers/glyphmanager.js.map +1 -1
  30. package/dist/helpers/textureatlas.js +7 -3
  31. package/dist/helpers/textureatlas.js.map +1 -1
  32. package/dist/index.d.ts +290 -266
  33. package/dist/pool.js +15 -6
  34. package/dist/pool.js.map +1 -1
  35. package/dist/timer.js +3 -2
  36. package/dist/timer.js.map +1 -1
  37. package/dist/uniformdata.js +1 -1
  38. package/dist/uniformdata.js.map +1 -1
  39. package/dist/vertexdata.js +2 -2
  40. package/dist/vertexdata.js.map +1 -1
  41. package/package.json +80 -80
@@ -20,10 +20,12 @@ const MAX_GLYPH_COUNT = 1024;
20
20
  /** @internal */ static font = null;
21
21
  /** @internal */ static vertexCache = null;
22
22
  /** @internal */ static colorValue = new Vector4();
23
- /** @internal */ static calculateTextMatrix(device, matrix) {
24
- const viewport = device.getViewport();
25
- const projectionMatrix = Matrix4x4.ortho(0, viewport.width, 0, viewport.height, 1, 100);
26
- const flipMatrix = Matrix4x4.translation(new Vector3(0, viewport.height, 0)).scaleRight(new Vector3(1, -1, 1));
23
+ /** @internal */ static calculateTextMatrix(device, matrix, viewport) {
24
+ const viewportWidth = viewport ? viewport[2] : device.getViewport().width;
25
+ const viewportHeight = viewport ? viewport[3] : device.getViewport().height;
26
+ matrix.identity();
27
+ const projectionMatrix = Matrix4x4.ortho(0, viewportWidth, 0, viewportHeight, 1, 100);
28
+ const flipMatrix = Matrix4x4.translation(new Vector3(0, viewportHeight, 0)).scaleRight(new Vector3(1, -1, 1));
27
29
  Matrix4x4.multiply(projectionMatrix, flipMatrix, matrix);
28
30
  }
29
31
  /**
@@ -31,7 +33,8 @@ const MAX_GLYPH_COUNT = 1024;
31
33
  * @param device - The render device
32
34
  * @param name - The font name
33
35
  */ static setFont(device, name) {
34
- this.font = Font.fetchFont(name, device.getScale()) || Font.fetchFont('12px arial', device.getScale());
36
+ const scale = device.getScaleY();
37
+ this.font = Font.fetchFont(name, scale) || Font.fetchFont('12px arial', scale);
35
38
  }
36
39
  /**
37
40
  * Draw text onto the screen
@@ -40,11 +43,11 @@ const MAX_GLYPH_COUNT = 1024;
40
43
  * @param color - The text color
41
44
  * @param x - X coordinate of the text
42
45
  * @param y - Y coordinate of the text
43
- */ static drawText(device, text, color, x, y) {
46
+ */ static drawText(device, text, color, x, y, viewport) {
44
47
  if (text.length > 0) {
45
48
  device.pushDeviceStates();
46
49
  this.prepareDrawText(device);
47
- this.calculateTextMatrix(device, this.textMatrix);
50
+ this.calculateTextMatrix(device, this.textMatrix, viewport);
48
51
  const colorValue = parseColor(color);
49
52
  this.colorValue.x = colorValue.r;
50
53
  this.colorValue.y = colorValue.g;
@@ -79,6 +82,7 @@ const MAX_GLYPH_COUNT = 1024;
79
82
  let drawn = 0;
80
83
  let atlasIndex = -1;
81
84
  let i = 0;
85
+ const vertexCache = this.vertexCache;
82
86
  for(; i < count; i++){
83
87
  const glyph = this.glyphManager.getGlyphInfo(text[i + start], this.font) || this.glyphManager.getGlyphInfo('?', this.font);
84
88
  if (atlasIndex >= 0 && glyph.atlasIndex !== atlasIndex) {
@@ -89,25 +93,25 @@ const MAX_GLYPH_COUNT = 1024;
89
93
  }
90
94
  atlasIndex = glyph.atlasIndex;
91
95
  const base = (this.textOffset + i) * 16;
92
- this.vertexCache[base + 0] = x;
93
- this.vertexCache[base + 1] = y;
94
- this.vertexCache[base + 2] = glyph.uMin;
95
- this.vertexCache[base + 3] = glyph.vMin;
96
- this.vertexCache[base + 4] = x + glyph.width;
97
- this.vertexCache[base + 5] = y;
98
- this.vertexCache[base + 6] = glyph.uMax;
99
- this.vertexCache[base + 7] = glyph.vMin;
100
- this.vertexCache[base + 8] = x + glyph.width;
101
- this.vertexCache[base + 9] = y + glyph.height;
102
- this.vertexCache[base + 10] = glyph.uMax;
103
- this.vertexCache[base + 11] = glyph.vMax;
104
- this.vertexCache[base + 12] = x;
105
- this.vertexCache[base + 13] = y + glyph.height;
106
- this.vertexCache[base + 14] = glyph.uMin;
107
- this.vertexCache[base + 15] = glyph.vMax;
96
+ vertexCache[base + 0] = x;
97
+ vertexCache[base + 1] = y;
98
+ vertexCache[base + 2] = glyph.uMin;
99
+ vertexCache[base + 3] = glyph.vMin;
100
+ vertexCache[base + 4] = x + glyph.width;
101
+ vertexCache[base + 5] = y;
102
+ vertexCache[base + 6] = glyph.uMax;
103
+ vertexCache[base + 7] = glyph.vMin;
104
+ vertexCache[base + 8] = x + glyph.width;
105
+ vertexCache[base + 9] = y + glyph.height;
106
+ vertexCache[base + 10] = glyph.uMax;
107
+ vertexCache[base + 11] = glyph.vMax;
108
+ vertexCache[base + 12] = x;
109
+ vertexCache[base + 13] = y + glyph.height;
110
+ vertexCache[base + 14] = glyph.uMin;
111
+ vertexCache[base + 15] = glyph.vMax;
108
112
  x += glyph.width;
109
113
  }
110
- this.textVertexBuffer.bufferSubData((this.textOffset + drawn) * 16 * 4, this.vertexCache, (this.textOffset + drawn) * 16, (i - drawn) * 16);
114
+ this.textVertexBuffer.bufferSubData((this.textOffset + drawn) * 16 * 4, vertexCache, (this.textOffset + drawn) * 16, (i - drawn) * 16);
111
115
  this.textBindGroup.setTexture('tex', this.glyphManager.getAtlasTexture(atlasIndex));
112
116
  device.draw('triangle-list', (this.textOffset + drawn) * 6, (i - drawn) * 6);
113
117
  return x;
@@ -115,7 +119,7 @@ const MAX_GLYPH_COUNT = 1024;
115
119
  /** @internal */ static prepareDrawText(device) {
116
120
  if (!this.prepared) {
117
121
  this.prepared = true;
118
- this.font = this.font || Font.fetchFont('16px arial', device.getScale());
122
+ this.font = this.font || Font.fetchFont('12px arial', device.getScaleY());
119
123
  this.glyphManager = new GlyphManager(device, 1024, 1024, 1);
120
124
  this.vertexCache = new Float32Array(this.GLYPH_COUNT * 16);
121
125
  this.textVertexBuffer = device.createInterleavedVertexBuffer([
@@ -1 +1 @@
1
- {"version":3,"file":"drawtext.js","sources":["../../src/helpers/drawtext.ts"],"sourcesContent":["import { 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: GlyphManager = null;\r\n /** @internal */\r\n private static prepared = false;\r\n /** @internal */\r\n private static textVertexBuffer: StructuredBuffer = null;\r\n /** @internal */\r\n private static textVertexLayout: VertexLayout = null;\r\n /** @internal */\r\n private static textProgram: GPUProgram = null;\r\n /** @internal */\r\n private static textBindGroup: BindGroup = null;\r\n /** @internal */\r\n private static textRenderStates: 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: Font = null;\r\n /** @internal */\r\n private static vertexCache: Float32Array<ArrayBuffer> = null;\r\n /** @internal */\r\n private static readonly colorValue: Vector4 = new Vector4();\r\n /** @internal */\r\n private static calculateTextMatrix(device: AbstractDevice, matrix: Matrix4x4): void {\r\n const viewport = device.getViewport();\r\n const projectionMatrix = Matrix4x4.ortho(0, viewport.width, 0, viewport.height, 1, 100);\r\n const flipMatrix = Matrix4x4.translation(new Vector3(0, viewport.height, 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): void {\r\n this.font = Font.fetchFont(name, device.getScale()) || Font.fetchFont('12px arial', device.getScale());\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(device: AbstractDevice, text: string, color: string, x: number, y: number): void {\r\n if (text.length > 0) {\r\n device.pushDeviceStates();\r\n this.prepareDrawText(device);\r\n this.calculateTextMatrix(device, this.textMatrix);\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 ): number {\r\n let drawn = 0;\r\n let atlasIndex = -1;\r\n let i = 0;\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 this.vertexCache[base + 0] = x;\r\n this.vertexCache[base + 1] = y;\r\n this.vertexCache[base + 2] = glyph.uMin;\r\n this.vertexCache[base + 3] = glyph.vMin;\r\n this.vertexCache[base + 4] = x + glyph.width;\r\n this.vertexCache[base + 5] = y;\r\n this.vertexCache[base + 6] = glyph.uMax;\r\n this.vertexCache[base + 7] = glyph.vMin;\r\n this.vertexCache[base + 8] = x + glyph.width;\r\n this.vertexCache[base + 9] = y + glyph.height;\r\n this.vertexCache[base + 10] = glyph.uMax;\r\n this.vertexCache[base + 11] = glyph.vMax;\r\n this.vertexCache[base + 12] = x;\r\n this.vertexCache[base + 13] = y + glyph.height;\r\n this.vertexCache[base + 14] = glyph.uMin;\r\n this.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 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 return x;\r\n }\r\n /** @internal */\r\n private static prepareDrawText(device: AbstractDevice): void {\r\n if (!this.prepared) {\r\n this.prepared = true;\r\n this.font = this.font || Font.fetchFont('16px arial', device.getScale());\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","getViewport","projectionMatrix","ortho","width","height","flipMatrix","translation","Vector3","scaleRight","multiply","setFont","name","Font","fetchFont","getScale","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 } 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 +1 @@
1
- {"version":3,"file":"font.js","sources":["../../src/helpers/font.ts"],"sourcesContent":["/** @internal */\r\nexport class FontCanvas {\r\n private static _canvas: HTMLCanvasElement = null;\r\n private static _context: CanvasRenderingContext2D = null;\r\n static get canvas(): HTMLCanvasElement {\r\n this._realize();\r\n return this._canvas;\r\n }\r\n static get context(): CanvasRenderingContext2D {\r\n this._realize();\r\n return this._context;\r\n }\r\n static get font(): string {\r\n return this.context.font;\r\n }\r\n static set font(font: string) {\r\n this.context.font = font;\r\n }\r\n private static _realize(): void {\r\n if (!this._canvas) {\r\n this._canvas = document.createElement('canvas');\r\n this._canvas.width = 512;\r\n this._canvas.height = 512;\r\n this._canvas.style.left = '-10000px';\r\n this._canvas.style.position = 'absolute';\r\n //document.body.appendChild(this._canvas);\r\n this._context = this._canvas.getContext('2d', {\r\n willReadFrequently: true\r\n });\r\n this._context.textBaseline = 'top';\r\n this._context.textAlign = 'left';\r\n this._context.fillStyle = 'transparent';\r\n this._context.fillRect(0, 0, this._canvas.width, this._canvas.height);\r\n this._context.fillStyle = '#ffffff';\r\n this._context.imageSmoothingEnabled = true;\r\n this._context.imageSmoothingQuality = 'high';\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * The font class\r\n * @public\r\n */\r\nexport class Font {\r\n /** @internal */\r\n private static fontCache: {\r\n [name: string]: {\r\n [scale: number]: Font;\r\n };\r\n } = {};\r\n /** @internal */\r\n private _name: string;\r\n /** @internal */\r\n private _nameScaled: string;\r\n /** @internal */\r\n private readonly _scale: number;\r\n /** @internal */\r\n private _size: number;\r\n /** @internal */\r\n private _family: string;\r\n /** @internal */\r\n private _top: number;\r\n /** @internal */\r\n private _bottom: number;\r\n /** @internal */\r\n private _topScaled: number;\r\n /** @internal */\r\n private _bottomScaled: number;\r\n /** @internal */\r\n private readonly _div: HTMLDivElement;\r\n /**\r\n * Creates a instance of font class from font name and the scale value\r\n * @param name - The font name\r\n * @param scale - The scale value\r\n */\r\n constructor(name: string, scale: number) {\r\n this._top = 0;\r\n this._bottom = 0;\r\n this._size = 0;\r\n this._topScaled = 0;\r\n this._bottomScaled = 0;\r\n this._family = '';\r\n this._scale = scale;\r\n this._name = name;\r\n this._nameScaled = null;\r\n this._div = document.createElement('div');\r\n if (this._name) {\r\n this._normalizeFont();\r\n }\r\n }\r\n /**\r\n * Fetch a font from cache\r\n * @param name - The font name\r\n * @param scale - The scale value\r\n * @returns The font object\r\n */\r\n static fetchFont(name: string, scale: number): Font {\r\n let fontlist = this.fontCache[name];\r\n if (!fontlist) {\r\n fontlist = {};\r\n this.fontCache[name] = fontlist;\r\n }\r\n let font = fontlist[scale];\r\n if (!font) {\r\n font = new Font(name, scale);\r\n fontlist[scale] = font;\r\n }\r\n return font;\r\n }\r\n /** Gets the font name */\r\n get fontName(): string {\r\n return this._name;\r\n }\r\n set fontName(name: string) {\r\n this._name = name;\r\n this._normalizeFont();\r\n }\r\n /** Gets the scaled font name */\r\n get fontNameScaled(): string {\r\n return this._nameScaled;\r\n }\r\n /** Gets the font size */\r\n get size(): number {\r\n return this._size;\r\n }\r\n /** Gets the font family */\r\n get family(): string {\r\n return this._family;\r\n }\r\n /** Gets top position of the font */\r\n get top(): number {\r\n return this._top;\r\n }\r\n /** Gets the bottom position of the font */\r\n get bottom(): number {\r\n return this._bottom;\r\n }\r\n /** Gets the scaled top position of the font */\r\n get topScaled(): number {\r\n return this._topScaled;\r\n }\r\n /** Gets the scaled bottom position of the font */\r\n get bottomScaled(): number {\r\n return this._bottomScaled;\r\n }\r\n /** Gets the maximum height of the font */\r\n get maxHeight(): number {\r\n return this._bottom - this._top + 1;\r\n }\r\n /** Gets the scaled maximum height of the font */\r\n get maxHeightScaled(): number {\r\n return this._bottomScaled - this._topScaled + 1;\r\n }\r\n /** Tests if two fonts are the same */\r\n equalTo(other: Font): boolean {\r\n return this._size === other._size && this._family === other._family;\r\n }\r\n /** @internal */\r\n private _measureFontHeight(fontName: string): {\r\n size: number;\r\n family: string;\r\n top: number;\r\n bottom: number;\r\n } {\r\n const oldFont = FontCanvas.context.font;\r\n const oldTextBaseline = FontCanvas.context.textBaseline;\r\n const oldFillStyle = FontCanvas.context.fillStyle;\r\n\r\n FontCanvas.context.font = fontName;\r\n this._div.style.font = FontCanvas.context.font;\r\n const fontSize = this._div.style.fontSize;\r\n const size = parseInt(fontSize.substring(0, fontSize.length - 2));\r\n const family = this._div.style.fontFamily;\r\n\r\n const testString = 'bdfghijklpq国美|_~';\r\n const metric = FontCanvas.context.measureText(testString);\r\n let top: number, bottom: number;\r\n top = 0;\r\n bottom = size - 1;\r\n const extra = 10;\r\n const halfExtra = extra >> 1;\r\n const maxWidth = Math.ceil(metric.width) + extra;\r\n const maxHeight = size + extra;\r\n FontCanvas.context.clearRect(0, 0, maxWidth, maxHeight);\r\n FontCanvas.context.textBaseline = 'top';\r\n FontCanvas.context.fillStyle = '#ffffff';\r\n FontCanvas.context.fillText(testString, halfExtra, halfExtra);\r\n const bitmap = FontCanvas.context.getImageData(0, 0, maxWidth, maxHeight);\r\n const pixels = bitmap.data;\r\n for (let i = 0; i < maxWidth * maxHeight; i++) {\r\n if (pixels[i * 4 + 3] > 0) {\r\n top = Math.floor(i / maxWidth);\r\n break;\r\n }\r\n }\r\n for (let i = maxWidth * maxHeight - 1; i >= 0; i--) {\r\n if (pixels[i * 4 + 3] > 0) {\r\n bottom = Math.floor(i / maxWidth);\r\n break;\r\n }\r\n }\r\n top -= halfExtra;\r\n bottom -= halfExtra;\r\n FontCanvas.context.font = oldFont;\r\n FontCanvas.context.textBaseline = oldTextBaseline;\r\n FontCanvas.context.fillStyle = oldFillStyle;\r\n\r\n return { size, family, top, bottom };\r\n }\r\n /** @internal */\r\n private _normalizeFont(): void {\r\n const info = this._measureFontHeight(this._name);\r\n this._nameScaled = `${Math.round(info.size * this._scale)}px ${info.family}`;\r\n const infoScaled = this._measureFontHeight(this._nameScaled);\r\n this._size = info.size;\r\n this._family = info.family;\r\n this._top = info.top;\r\n this._bottom = info.bottom;\r\n this._topScaled = infoScaled.top;\r\n this._bottomScaled = infoScaled.bottom;\r\n }\r\n}\r\n"],"names":["FontCanvas","_canvas","_context","canvas","_realize","context","font","document","createElement","width","height","style","left","position","getContext","willReadFrequently","textBaseline","textAlign","fillStyle","fillRect","imageSmoothingEnabled","imageSmoothingQuality","Font","fontCache","name","scale","_top","_bottom","_size","_topScaled","_bottomScaled","_family","_scale","_name","_nameScaled","_div","_normalizeFont","fetchFont","fontlist","fontName","fontNameScaled","size","family","top","bottom","topScaled","bottomScaled","maxHeight","maxHeightScaled","equalTo","other","_measureFontHeight","oldFont","oldTextBaseline","oldFillStyle","fontSize","parseInt","substring","length","fontFamily","testString","metric","measureText","extra","halfExtra","maxWidth","Math","ceil","clearRect","fillText","bitmap","getImageData","pixels","data","i","floor","info","round","infoScaled"],"mappings":"AAAA,iBACO,MAAMA,UAAAA,CAAAA;AACX,IAAA,OAAeC,UAA6B,IAAK;AACjD,IAAA,OAAeC,WAAqC,IAAK;AACzD,IAAA,WAAWC,MAA4B,GAAA;AACrC,QAAA,IAAI,CAACC,QAAQ,EAAA;QACb,OAAO,IAAI,CAACH,OAAO;AACrB;AACA,IAAA,WAAWI,OAAoC,GAAA;AAC7C,QAAA,IAAI,CAACD,QAAQ,EAAA;QACb,OAAO,IAAI,CAACF,QAAQ;AACtB;AACA,IAAA,WAAWI,IAAe,GAAA;AACxB,QAAA,OAAO,IAAI,CAACD,OAAO,CAACC,IAAI;AAC1B;IACA,WAAWA,IAAAA,CAAKA,IAAY,EAAE;AAC5B,QAAA,IAAI,CAACD,OAAO,CAACC,IAAI,GAAGA,IAAAA;AACtB;AACA,IAAA,OAAeF,QAAiB,GAAA;AAC9B,QAAA,IAAI,CAAC,IAAI,CAACH,OAAO,EAAE;AACjB,YAAA,IAAI,CAACA,OAAO,GAAGM,QAAAA,CAASC,aAAa,CAAC,QAAA,CAAA;AACtC,YAAA,IAAI,CAACP,OAAO,CAACQ,KAAK,GAAG,GAAA;AACrB,YAAA,IAAI,CAACR,OAAO,CAACS,MAAM,GAAG,GAAA;AACtB,YAAA,IAAI,CAACT,OAAO,CAACU,KAAK,CAACC,IAAI,GAAG,UAAA;AAC1B,YAAA,IAAI,CAACX,OAAO,CAACU,KAAK,CAACE,QAAQ,GAAG,UAAA;;YAE9B,IAAI,CAACX,QAAQ,GAAG,IAAI,CAACD,OAAO,CAACa,UAAU,CAAC,IAAM,EAAA;gBAC5CC,kBAAoB,EAAA;AACtB,aAAA,CAAA;AACA,YAAA,IAAI,CAACb,QAAQ,CAACc,YAAY,GAAG,KAAA;AAC7B,YAAA,IAAI,CAACd,QAAQ,CAACe,SAAS,GAAG,MAAA;AAC1B,YAAA,IAAI,CAACf,QAAQ,CAACgB,SAAS,GAAG,aAAA;AAC1B,YAAA,IAAI,CAAChB,QAAQ,CAACiB,QAAQ,CAAC,GAAG,CAAG,EAAA,IAAI,CAAClB,OAAO,CAACQ,KAAK,EAAE,IAAI,CAACR,OAAO,CAACS,MAAM,CAAA;AACpE,YAAA,IAAI,CAACR,QAAQ,CAACgB,SAAS,GAAG,SAAA;AAC1B,YAAA,IAAI,CAAChB,QAAQ,CAACkB,qBAAqB,GAAG,IAAA;AACtC,YAAA,IAAI,CAAClB,QAAQ,CAACmB,qBAAqB,GAAG,MAAA;AACxC;AACF;AACF;AAEA;;;AAGC,IACM,MAAMC,IAAAA,CAAAA;AACX,qBACA,OAAeC,SAIX,GAAA,EAAG;qBAEP,KAAsB;qBAEtB,WAA4B;qBAE5B,MAAgC;qBAEhC,KAAsB;qBAEtB,OAAwB;qBAExB,IAAqB;qBAErB,OAAwB;qBAExB,UAA2B;qBAE3B,aAA8B;qBAE9B,IAAsC;AACtC;;;;AAIC,MACD,WAAYC,CAAAA,IAAY,EAAEC,KAAa,CAAE;QACvC,IAAI,CAACC,IAAI,GAAG,CAAA;QACZ,IAAI,CAACC,OAAO,GAAG,CAAA;QACf,IAAI,CAACC,KAAK,GAAG,CAAA;QACb,IAAI,CAACC,UAAU,GAAG,CAAA;QAClB,IAAI,CAACC,aAAa,GAAG,CAAA;QACrB,IAAI,CAACC,OAAO,GAAG,EAAA;QACf,IAAI,CAACC,MAAM,GAAGP,KAAAA;QACd,IAAI,CAACQ,KAAK,GAAGT,IAAAA;QACb,IAAI,CAACU,WAAW,GAAG,IAAA;AACnB,QAAA,IAAI,CAACC,IAAI,GAAG5B,QAAAA,CAASC,aAAa,CAAC,KAAA,CAAA;QACnC,IAAI,IAAI,CAACyB,KAAK,EAAE;AACd,YAAA,IAAI,CAACG,cAAc,EAAA;AACrB;AACF;AACA;;;;;AAKC,MACD,OAAOC,SAAAA,CAAUb,IAAY,EAAEC,KAAa,EAAQ;AAClD,QAAA,IAAIa,QAAW,GAAA,IAAI,CAACf,SAAS,CAACC,IAAK,CAAA;AACnC,QAAA,IAAI,CAACc,QAAU,EAAA;AACbA,YAAAA,QAAAA,GAAW,EAAC;AACZ,YAAA,IAAI,CAACf,SAAS,CAACC,IAAAA,CAAK,GAAGc,QAAAA;AACzB;QACA,IAAIhC,IAAAA,GAAOgC,QAAQ,CAACb,KAAM,CAAA;AAC1B,QAAA,IAAI,CAACnB,IAAM,EAAA;YACTA,IAAO,GAAA,IAAIgB,KAAKE,IAAMC,EAAAA,KAAAA,CAAAA;YACtBa,QAAQ,CAACb,MAAM,GAAGnB,IAAAA;AACpB;QACA,OAAOA,IAAAA;AACT;8BAEA,IAAIiC,QAAmB,GAAA;QACrB,OAAO,IAAI,CAACN,KAAK;AACnB;IACA,IAAIM,QAAAA,CAASf,IAAY,EAAE;QACzB,IAAI,CAACS,KAAK,GAAGT,IAAAA;AACb,QAAA,IAAI,CAACY,cAAc,EAAA;AACrB;qCAEA,IAAII,cAAyB,GAAA;QAC3B,OAAO,IAAI,CAACN,WAAW;AACzB;8BAEA,IAAIO,IAAe,GAAA;QACjB,OAAO,IAAI,CAACb,KAAK;AACnB;gCAEA,IAAIc,MAAiB,GAAA;QACnB,OAAO,IAAI,CAACX,OAAO;AACrB;yCAEA,IAAIY,GAAc,GAAA;QAChB,OAAO,IAAI,CAACjB,IAAI;AAClB;gDAEA,IAAIkB,MAAiB,GAAA;QACnB,OAAO,IAAI,CAACjB,OAAO;AACrB;oDAEA,IAAIkB,SAAoB,GAAA;QACtB,OAAO,IAAI,CAAChB,UAAU;AACxB;uDAEA,IAAIiB,YAAuB,GAAA;QACzB,OAAO,IAAI,CAAChB,aAAa;AAC3B;+CAEA,IAAIiB,SAAoB,GAAA;AACtB,QAAA,OAAO,IAAI,CAACpB,OAAO,GAAG,IAAI,CAACD,IAAI,GAAG,CAAA;AACpC;sDAEA,IAAIsB,eAA0B,GAAA;AAC5B,QAAA,OAAO,IAAI,CAAClB,aAAa,GAAG,IAAI,CAACD,UAAU,GAAG,CAAA;AAChD;2CAEAoB,OAAQC,CAAAA,KAAW,EAAW;AAC5B,QAAA,OAAO,IAAI,CAACtB,KAAK,KAAKsB,KAAMtB,CAAAA,KAAK,IAAI,IAAI,CAACG,OAAO,KAAKmB,KAAAA,CAAMnB,OAAO;AACrE;AACA,qBACQoB,kBAAmBZ,CAAAA,QAAgB,EAKzC;AACA,QAAA,MAAMa,OAAUpD,GAAAA,UAAAA,CAAWK,OAAO,CAACC,IAAI;AACvC,QAAA,MAAM+C,eAAkBrD,GAAAA,UAAAA,CAAWK,OAAO,CAACW,YAAY;AACvD,QAAA,MAAMsC,YAAetD,GAAAA,UAAAA,CAAWK,OAAO,CAACa,SAAS;QAEjDlB,UAAWK,CAAAA,OAAO,CAACC,IAAI,GAAGiC,QAAAA;QAC1B,IAAI,CAACJ,IAAI,CAACxB,KAAK,CAACL,IAAI,GAAGN,UAAAA,CAAWK,OAAO,CAACC,IAAI;AAC9C,QAAA,MAAMiD,WAAW,IAAI,CAACpB,IAAI,CAACxB,KAAK,CAAC4C,QAAQ;QACzC,MAAMd,IAAAA,GAAOe,SAASD,QAASE,CAAAA,SAAS,CAAC,CAAGF,EAAAA,QAAAA,CAASG,MAAM,GAAG,CAAA,CAAA,CAAA;AAC9D,QAAA,MAAMhB,SAAS,IAAI,CAACP,IAAI,CAACxB,KAAK,CAACgD,UAAU;AAEzC,QAAA,MAAMC,UAAa,GAAA,kBAAA;AACnB,QAAA,MAAMC,MAAS7D,GAAAA,UAAAA,CAAWK,OAAO,CAACyD,WAAW,CAACF,UAAAA,CAAAA;AAC9C,QAAA,IAAIjB,GAAaC,EAAAA,MAAAA;QACjBD,GAAM,GAAA,CAAA;AACNC,QAAAA,MAAAA,GAASH,IAAO,GAAA,CAAA;AAChB,QAAA,MAAMsB,KAAQ,GAAA,EAAA;AACd,QAAA,MAAMC,YAAYD,KAAS,IAAA,CAAA;AAC3B,QAAA,MAAME,WAAWC,IAAKC,CAAAA,IAAI,CAACN,MAAAA,CAAOpD,KAAK,CAAIsD,GAAAA,KAAAA;AAC3C,QAAA,MAAMhB,YAAYN,IAAOsB,GAAAA,KAAAA;AACzB/D,QAAAA,UAAAA,CAAWK,OAAO,CAAC+D,SAAS,CAAC,CAAA,EAAG,GAAGH,QAAUlB,EAAAA,SAAAA,CAAAA;QAC7C/C,UAAWK,CAAAA,OAAO,CAACW,YAAY,GAAG,KAAA;QAClChB,UAAWK,CAAAA,OAAO,CAACa,SAAS,GAAG,SAAA;AAC/BlB,QAAAA,UAAAA,CAAWK,OAAO,CAACgE,QAAQ,CAACT,YAAYI,SAAWA,EAAAA,SAAAA,CAAAA;QACnD,MAAMM,MAAAA,GAAStE,WAAWK,OAAO,CAACkE,YAAY,CAAC,CAAA,EAAG,GAAGN,QAAUlB,EAAAA,SAAAA,CAAAA;QAC/D,MAAMyB,MAAAA,GAASF,OAAOG,IAAI;AAC1B,QAAA,IAAK,IAAIC,CAAI,GAAA,CAAA,EAAGA,CAAIT,GAAAA,QAAAA,GAAWlB,WAAW2B,CAAK,EAAA,CAAA;AAC7C,YAAA,IAAIF,MAAM,CAACE,CAAAA,GAAI,CAAI,GAAA,CAAA,CAAE,GAAG,CAAG,EAAA;gBACzB/B,GAAMuB,GAAAA,IAAAA,CAAKS,KAAK,CAACD,CAAIT,GAAAA,QAAAA,CAAAA;AACrB,gBAAA;AACF;AACF;AACA,QAAA,IAAK,IAAIS,CAAIT,GAAAA,QAAAA,GAAWlB,YAAY,CAAG2B,EAAAA,CAAAA,IAAK,GAAGA,CAAK,EAAA,CAAA;AAClD,YAAA,IAAIF,MAAM,CAACE,CAAAA,GAAI,CAAI,GAAA,CAAA,CAAE,GAAG,CAAG,EAAA;gBACzB9B,MAASsB,GAAAA,IAAAA,CAAKS,KAAK,CAACD,CAAIT,GAAAA,QAAAA,CAAAA;AACxB,gBAAA;AACF;AACF;QACAtB,GAAOqB,IAAAA,SAAAA;QACPpB,MAAUoB,IAAAA,SAAAA;QACVhE,UAAWK,CAAAA,OAAO,CAACC,IAAI,GAAG8C,OAAAA;QAC1BpD,UAAWK,CAAAA,OAAO,CAACW,YAAY,GAAGqC,eAAAA;QAClCrD,UAAWK,CAAAA,OAAO,CAACa,SAAS,GAAGoC,YAAAA;QAE/B,OAAO;AAAEb,YAAAA,IAAAA;AAAMC,YAAAA,MAAAA;AAAQC,YAAAA,GAAAA;AAAKC,YAAAA;AAAO,SAAA;AACrC;qBAEA,cAA+B,GAAA;AAC7B,QAAA,MAAMgC,OAAO,IAAI,CAACzB,kBAAkB,CAAC,IAAI,CAAClB,KAAK,CAAA;AAC/C,QAAA,IAAI,CAACC,WAAW,GAAG,GAAGgC,IAAKW,CAAAA,KAAK,CAACD,IAAKnC,CAAAA,IAAI,GAAG,IAAI,CAACT,MAAM,CAAA,CAAE,GAAG,EAAE4C,IAAAA,CAAKlC,MAAM,CAAE,CAAA;AAC5E,QAAA,MAAMoC,aAAa,IAAI,CAAC3B,kBAAkB,CAAC,IAAI,CAACjB,WAAW,CAAA;AAC3D,QAAA,IAAI,CAACN,KAAK,GAAGgD,IAAAA,CAAKnC,IAAI;AACtB,QAAA,IAAI,CAACV,OAAO,GAAG6C,IAAAA,CAAKlC,MAAM;AAC1B,QAAA,IAAI,CAAChB,IAAI,GAAGkD,IAAAA,CAAKjC,GAAG;AACpB,QAAA,IAAI,CAAChB,OAAO,GAAGiD,IAAAA,CAAKhC,MAAM;AAC1B,QAAA,IAAI,CAACf,UAAU,GAAGiD,UAAAA,CAAWnC,GAAG;AAChC,QAAA,IAAI,CAACb,aAAa,GAAGgD,UAAAA,CAAWlC,MAAM;AACxC;AACF;;;;"}
1
+ {"version":3,"file":"font.js","sources":["../../src/helpers/font.ts"],"sourcesContent":["import type { Nullable } from '@zephyr3d/base';\r\n\r\n/** @internal */\r\nexport class FontCanvas {\r\n private static _canvas: Nullable<HTMLCanvasElement> = null;\r\n private static _context: Nullable<CanvasRenderingContext2D> = null;\r\n static get canvas() {\r\n this._realize();\r\n return this._canvas!;\r\n }\r\n static get context() {\r\n this._realize();\r\n return this._context!;\r\n }\r\n static get font() {\r\n return this.context.font;\r\n }\r\n static set font(font) {\r\n this.context.font = font;\r\n }\r\n private static _realize() {\r\n if (!this._canvas) {\r\n this._canvas = document.createElement('canvas');\r\n this._canvas.width = 512;\r\n this._canvas.height = 512;\r\n this._canvas.style.left = '-10000px';\r\n this._canvas.style.position = 'absolute';\r\n //document.body.appendChild(this._canvas);\r\n this._context = this._canvas.getContext('2d', {\r\n willReadFrequently: true\r\n })!;\r\n this._context.textBaseline = 'top';\r\n this._context.textAlign = 'left';\r\n this._context.fillStyle = 'transparent';\r\n this._context.fillRect(0, 0, this._canvas.width, this._canvas.height);\r\n this._context.fillStyle = '#ffffff';\r\n this._context.imageSmoothingEnabled = true;\r\n this._context.imageSmoothingQuality = 'high';\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * The font class\r\n * @public\r\n */\r\nexport class Font {\r\n /** @internal */\r\n private static fontCache: {\r\n [name: string]: {\r\n [scale: number]: Font;\r\n };\r\n } = {};\r\n /** @internal */\r\n private _name: string;\r\n /** @internal */\r\n private _nameScaled: Nullable<string>;\r\n /** @internal */\r\n private readonly _scale: number;\r\n /** @internal */\r\n private _size: number;\r\n /** @internal */\r\n private _family: string;\r\n /** @internal */\r\n private _top: number;\r\n /** @internal */\r\n private _bottom: number;\r\n /** @internal */\r\n private _topScaled: number;\r\n /** @internal */\r\n private _bottomScaled: number;\r\n /** @internal */\r\n private readonly _div: HTMLDivElement;\r\n /**\r\n * Creates a instance of font class from font name and the scale value\r\n * @param name - The font name\r\n * @param scale - The scale value\r\n */\r\n constructor(name: string, scale: number) {\r\n this._top = 0;\r\n this._bottom = 0;\r\n this._size = 0;\r\n this._topScaled = 0;\r\n this._bottomScaled = 0;\r\n this._family = '';\r\n this._scale = scale;\r\n this._name = name;\r\n this._nameScaled = null;\r\n this._div = document.createElement('div');\r\n if (this._name) {\r\n this._normalizeFont();\r\n }\r\n }\r\n /**\r\n * Fetch a font from cache\r\n * @param name - The font name\r\n * @param scale - The scale value\r\n * @returns The font object\r\n */\r\n static fetchFont(name: string, scale: number) {\r\n let fontlist = this.fontCache[name];\r\n if (!fontlist) {\r\n fontlist = {};\r\n this.fontCache[name] = fontlist;\r\n }\r\n let font = fontlist[scale];\r\n if (!font) {\r\n font = new Font(name, scale);\r\n fontlist[scale] = font;\r\n }\r\n return font;\r\n }\r\n /** Gets the font name */\r\n get fontName() {\r\n return this._name;\r\n }\r\n set fontName(name) {\r\n this._name = name;\r\n this._normalizeFont();\r\n }\r\n /** Gets the scaled font name */\r\n get fontNameScaled() {\r\n return this._nameScaled!;\r\n }\r\n /** Gets the font size */\r\n get size() {\r\n return this._size;\r\n }\r\n /** Gets the font family */\r\n get family() {\r\n return this._family;\r\n }\r\n /** Gets top position of the font */\r\n get top() {\r\n return this._top;\r\n }\r\n /** Gets the bottom position of the font */\r\n get bottom() {\r\n return this._bottom;\r\n }\r\n /** Gets the scaled top position of the font */\r\n get topScaled() {\r\n return this._topScaled;\r\n }\r\n /** Gets the scaled bottom position of the font */\r\n get bottomScaled() {\r\n return this._bottomScaled;\r\n }\r\n /** Gets the maximum height of the font */\r\n get maxHeight() {\r\n return this._bottom - this._top + 1;\r\n }\r\n /** Gets the scaled maximum height of the font */\r\n get maxHeightScaled() {\r\n return this._bottomScaled - this._topScaled + 1;\r\n }\r\n /** Tests if two fonts are the same */\r\n equalTo(other: Font) {\r\n return this._size === other._size && this._family === other._family;\r\n }\r\n /** @internal */\r\n private _measureFontHeight(fontName: string) {\r\n const oldFont = FontCanvas.context.font;\r\n const oldTextBaseline = FontCanvas.context.textBaseline;\r\n const oldFillStyle = FontCanvas.context.fillStyle;\r\n\r\n FontCanvas.context.font = fontName;\r\n this._div.style.font = FontCanvas.context.font;\r\n const fontSize = this._div.style.fontSize;\r\n const size = parseInt(fontSize.substring(0, fontSize.length - 2));\r\n const family = this._div.style.fontFamily;\r\n\r\n const testString = 'bdfghijklpq国美|_~';\r\n const metric = FontCanvas.context.measureText(testString);\r\n let top: number, bottom: number;\r\n top = 0;\r\n bottom = size - 1;\r\n const extra = 10;\r\n const halfExtra = extra >> 1;\r\n const maxWidth = Math.ceil(metric.width) + extra;\r\n const maxHeight = size + extra;\r\n FontCanvas.context.clearRect(0, 0, maxWidth, maxHeight);\r\n FontCanvas.context.textBaseline = 'top';\r\n FontCanvas.context.fillStyle = '#ffffff';\r\n FontCanvas.context.fillText(testString, halfExtra, halfExtra);\r\n const bitmap = FontCanvas.context.getImageData(0, 0, maxWidth, maxHeight);\r\n const pixels = bitmap.data;\r\n for (let i = 0; i < maxWidth * maxHeight; i++) {\r\n if (pixels[i * 4 + 3] > 0) {\r\n top = Math.floor(i / maxWidth);\r\n break;\r\n }\r\n }\r\n for (let i = maxWidth * maxHeight - 1; i >= 0; i--) {\r\n if (pixels[i * 4 + 3] > 0) {\r\n bottom = Math.floor(i / maxWidth);\r\n break;\r\n }\r\n }\r\n top -= halfExtra;\r\n bottom -= halfExtra;\r\n FontCanvas.context.font = oldFont;\r\n FontCanvas.context.textBaseline = oldTextBaseline;\r\n FontCanvas.context.fillStyle = oldFillStyle;\r\n\r\n return { size, family, top, bottom };\r\n }\r\n /** @internal */\r\n private _normalizeFont() {\r\n const info = this._measureFontHeight(this._name);\r\n this._nameScaled = `${Math.round(info.size * this._scale)}px ${info.family}`;\r\n const infoScaled = this._measureFontHeight(this._nameScaled);\r\n this._size = info.size;\r\n this._family = info.family;\r\n this._top = info.top;\r\n this._bottom = info.bottom;\r\n this._topScaled = infoScaled.top;\r\n this._bottomScaled = infoScaled.bottom;\r\n }\r\n}\r\n"],"names":["FontCanvas","_canvas","_context","canvas","_realize","context","font","document","createElement","width","height","style","left","position","getContext","willReadFrequently","textBaseline","textAlign","fillStyle","fillRect","imageSmoothingEnabled","imageSmoothingQuality","Font","fontCache","name","scale","_top","_bottom","_size","_topScaled","_bottomScaled","_family","_scale","_name","_nameScaled","_div","_normalizeFont","fetchFont","fontlist","fontName","fontNameScaled","size","family","top","bottom","topScaled","bottomScaled","maxHeight","maxHeightScaled","equalTo","other","_measureFontHeight","oldFont","oldTextBaseline","oldFillStyle","fontSize","parseInt","substring","length","fontFamily","testString","metric","measureText","extra","halfExtra","maxWidth","Math","ceil","clearRect","fillText","bitmap","getImageData","pixels","data","i","floor","info","round","infoScaled"],"mappings":"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"}
@@ -20,19 +20,21 @@ import { TextureAtlasManager } from './textureatlas.js';
20
20
  };
21
21
  }
22
22
  /**
23
- * Gets the atlas information for given character
23
+ * Gets the size for given character
24
24
  * @param char - The character
25
25
  * @param font - Font of the character
26
- * @returns Atlas information for the glyph
27
- */ getGlyphInfo(char, font) {
28
- if (!char || !font) {
29
- return null;
30
- }
26
+ * @returns [width, height]
27
+ */ getGlyphSize(char, font) {
28
+ return this._getGlyphSize(char, font);
29
+ }
30
+ getGlyphInfo(char, font) {
31
31
  let glyphInfo = this.getAtlasInfo(this._hash(char, font));
32
32
  if (!glyphInfo) {
33
33
  glyphInfo = this._cacheGlyph(char, font);
34
- glyphInfo.width = Math.round(glyphInfo.width * (font.maxHeight / font.maxHeightScaled));
35
- glyphInfo.height = font.maxHeight;
34
+ if (glyphInfo) {
35
+ glyphInfo.width = Math.round(glyphInfo.width * (font.maxHeight / font.maxHeightScaled));
36
+ glyphInfo.height = font.maxHeight;
37
+ }
36
38
  }
37
39
  return glyphInfo;
38
40
  }
@@ -89,6 +91,22 @@ import { TextureAtlasManager } from './textureatlas.js';
89
91
  w = Math.round(w * (font.maxHeight / font.maxHeightScaled));
90
92
  return w;
91
93
  }
94
+ /** @internal */ _getGlyphSize(char, font) {
95
+ FontCanvas.font = font.fontNameScaled;
96
+ const metric = FontCanvas.context.measureText(char);
97
+ let w = metric.width;
98
+ if (w === 0) {
99
+ return null;
100
+ }
101
+ if (typeof metric.actualBoundingBoxRight === 'number') {
102
+ w = Math.floor(Math.max(w, metric.actualBoundingBoxRight) + 0.8);
103
+ }
104
+ const h = font.maxHeightScaled;
105
+ return [
106
+ w,
107
+ h
108
+ ];
109
+ }
92
110
  /** @internal */ _getGlyphBitmap(char, font) {
93
111
  if (!font) {
94
112
  return null;
@@ -1 +1 @@
1
- {"version":3,"file":"glyphmanager.js","sources":["../../src/helpers/glyphmanager.ts"],"sourcesContent":["import type { Font } from './font';\r\nimport { FontCanvas } from './font';\r\nimport type { AtlasInfo } from './textureatlas';\r\nimport { TextureAtlasManager } from './textureatlas';\r\nimport type { AbstractDevice } from '../base_types';\r\n\r\n/**\r\n * Manager of texture glyphs\r\n * @public\r\n */\r\nexport class GlyphManager extends TextureAtlasManager {\r\n /**\r\n * Creates a new glyph 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 border - Border width of an atlas\r\n */\r\n constructor(device: AbstractDevice, binWidth: number, binHeight: number, border: number) {\r\n super(device, binWidth, binHeight, border, true);\r\n this.atlasTextureRestoreHandler = async () => {\r\n if (!this.isEmpty()) {\r\n this.clear();\r\n }\r\n };\r\n }\r\n /**\r\n * Gets the atlas information for given character\r\n * @param char - The character\r\n * @param font - Font of the character\r\n * @returns Atlas information for the glyph\r\n */\r\n getGlyphInfo(char: string, font: Font): AtlasInfo {\r\n if (!char || !font) {\r\n return null;\r\n }\r\n let glyphInfo = this.getAtlasInfo(this._hash(char, font));\r\n if (!glyphInfo) {\r\n glyphInfo = this._cacheGlyph(char, font);\r\n glyphInfo.width = Math.round(glyphInfo.width * (font.maxHeight / font.maxHeightScaled));\r\n glyphInfo.height = font.maxHeight;\r\n }\r\n return glyphInfo;\r\n }\r\n /**\r\n * Measuring the width of a string\r\n * @param str - The string to be measured\r\n * @param charMargin - margin size between characters\r\n * @param font - Font of the string\r\n * @returns Width of the string\r\n */\r\n measureStringWidth(str: string, charMargin: number, font: Font): number {\r\n let w = 0;\r\n for (const ch of str) {\r\n w += charMargin + this.getCharWidth(ch, font);\r\n }\r\n return w;\r\n }\r\n /**\r\n * Clips a string so that it's width is not larger than the given value\r\n * @param str - The string to be clipped\r\n * @param width - The desired maximum width\r\n * @param charMargin - Margin size between characters\r\n * @param start - Start index of the string to be clipped\r\n * @param font - Font of the string\r\n * @returns\r\n */\r\n clipStringToWidth(str: string, width: number, charMargin: number, start: number, font: Font): number {\r\n let sum = 0;\r\n let i = start;\r\n for (; i < str.length; i++) {\r\n sum += charMargin + this.getCharWidth(str[i], font);\r\n if (sum > width) {\r\n break;\r\n }\r\n }\r\n return i - start;\r\n }\r\n /**\r\n * Measuring width of a character\r\n * @param char - The character to be measured\r\n * @param font - Font of the character\r\n * @returns Width of the character\r\n */\r\n getCharWidth(char: string, font: Font): number {\r\n if (!font) {\r\n return 0;\r\n }\r\n FontCanvas.font = font.fontNameScaled;\r\n const metric = FontCanvas.context.measureText(char);\r\n let w = metric.width;\r\n if (w === 0) {\r\n return 0;\r\n }\r\n if (typeof metric.actualBoundingBoxRight === 'number') {\r\n w = Math.floor(Math.max(w, metric.actualBoundingBoxRight) + 0.8);\r\n }\r\n w = Math.round(w * (font.maxHeight / font.maxHeightScaled));\r\n return w;\r\n }\r\n /** @internal */\r\n private _getGlyphBitmap(\r\n char: string,\r\n font: Font\r\n ): ImageData | { x: number; y: number; w: number; h: number } {\r\n if (!font) {\r\n return null;\r\n }\r\n FontCanvas.font = font.fontNameScaled;\r\n const metric = FontCanvas.context.measureText(char);\r\n let w = metric.width;\r\n if (w === 0) {\r\n return null;\r\n }\r\n if (typeof metric.actualBoundingBoxRight === 'number') {\r\n w = Math.floor(Math.max(w, metric.actualBoundingBoxRight) + 0.8);\r\n }\r\n const h = font.maxHeightScaled;\r\n FontCanvas.context.fillStyle = '#fff';\r\n FontCanvas.context.clearRect(0, 0, w + 2, h);\r\n FontCanvas.context.fillText(char, 0, -font.topScaled);\r\n return FontCanvas.context.getImageData(0, 0, w, h);\r\n }\r\n /** @internal */\r\n private _hash(char: string, font: Font): string {\r\n return `${font.family}@${font.size}&${char}`;\r\n }\r\n /** @internal */\r\n private _cacheGlyph(char: string, font: Font): AtlasInfo {\r\n const bitmap = this._getGlyphBitmap(char, font) as ImageData;\r\n return this.pushBitmap(this._hash(char, font), bitmap);\r\n }\r\n}\r\n"],"names":["GlyphManager","TextureAtlasManager","device","binWidth","binHeight","border","atlasTextureRestoreHandler","isEmpty","clear","getGlyphInfo","char","font","glyphInfo","getAtlasInfo","_hash","_cacheGlyph","width","Math","round","maxHeight","maxHeightScaled","height","measureStringWidth","str","charMargin","w","ch","getCharWidth","clipStringToWidth","start","sum","i","length","FontCanvas","fontNameScaled","metric","context","measureText","actualBoundingBoxRight","floor","max","_getGlyphBitmap","h","fillStyle","clearRect","fillText","topScaled","getImageData","family","size","bitmap","pushBitmap"],"mappings":"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"}
1
+ {"version":3,"file":"glyphmanager.js","sources":["../../src/helpers/glyphmanager.ts"],"sourcesContent":["import type { Font } from './font';\r\nimport { FontCanvas } from './font';\r\nimport { TextureAtlasManager } from './textureatlas';\r\nimport type { AbstractDevice } from '../base_types';\r\n\r\n/**\r\n * Manager of texture glyphs\r\n * @public\r\n */\r\nexport class GlyphManager extends TextureAtlasManager {\r\n /**\r\n * Creates a new glyph 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 border - Border width of an atlas\r\n */\r\n constructor(device: AbstractDevice, binWidth: number, binHeight: number, border: number) {\r\n super(device, binWidth, binHeight, border, true);\r\n this.atlasTextureRestoreHandler = async () => {\r\n if (!this.isEmpty()) {\r\n this.clear();\r\n }\r\n };\r\n }\r\n /**\r\n * Gets the size for given character\r\n * @param char - The character\r\n * @param font - Font of the character\r\n * @returns [width, height]\r\n */\r\n getGlyphSize(char: string, font: Font) {\r\n return this._getGlyphSize(char, font);\r\n }\r\n getGlyphInfo(char: string, font: Font) {\r\n let glyphInfo = this.getAtlasInfo(this._hash(char, font));\r\n if (!glyphInfo) {\r\n glyphInfo = this._cacheGlyph(char, font);\r\n if (glyphInfo) {\r\n glyphInfo.width = Math.round(glyphInfo.width * (font.maxHeight / font.maxHeightScaled));\r\n glyphInfo.height = font.maxHeight;\r\n }\r\n }\r\n return glyphInfo;\r\n }\r\n /**\r\n * Measuring the width of a string\r\n * @param str - The string to be measured\r\n * @param charMargin - margin size between characters\r\n * @param font - Font of the string\r\n * @returns Width of the string\r\n */\r\n measureStringWidth(str: string, charMargin: number, font: Font) {\r\n let w = 0;\r\n for (const ch of str) {\r\n w += charMargin + this.getCharWidth(ch, font);\r\n }\r\n return w;\r\n }\r\n /**\r\n * Clips a string so that it's width is not larger than the given value\r\n * @param str - The string to be clipped\r\n * @param width - The desired maximum width\r\n * @param charMargin - Margin size between characters\r\n * @param start - Start index of the string to be clipped\r\n * @param font - Font of the string\r\n * @returns\r\n */\r\n clipStringToWidth(str: string, width: number, charMargin: number, start: number, font: Font) {\r\n let sum = 0;\r\n let i = start;\r\n for (; i < str.length; i++) {\r\n sum += charMargin + this.getCharWidth(str[i], font);\r\n if (sum > width) {\r\n break;\r\n }\r\n }\r\n return i - start;\r\n }\r\n /**\r\n * Measuring width of a character\r\n * @param char - The character to be measured\r\n * @param font - Font of the character\r\n * @returns Width of the character\r\n */\r\n getCharWidth(char: string, font: Font) {\r\n if (!font) {\r\n return 0;\r\n }\r\n FontCanvas.font = font.fontNameScaled;\r\n const metric = FontCanvas.context.measureText(char);\r\n let w = metric.width;\r\n if (w === 0) {\r\n return 0;\r\n }\r\n if (typeof metric.actualBoundingBoxRight === 'number') {\r\n w = Math.floor(Math.max(w, metric.actualBoundingBoxRight) + 0.8);\r\n }\r\n w = Math.round(w * (font.maxHeight / font.maxHeightScaled));\r\n return w;\r\n }\r\n /** @internal */\r\n private _getGlyphSize(char: string, font: Font) {\r\n FontCanvas.font = font.fontNameScaled;\r\n const metric = FontCanvas.context.measureText(char);\r\n let w = metric.width;\r\n if (w === 0) {\r\n return null;\r\n }\r\n if (typeof metric.actualBoundingBoxRight === 'number') {\r\n w = Math.floor(Math.max(w, metric.actualBoundingBoxRight) + 0.8);\r\n }\r\n const h = font.maxHeightScaled;\r\n return [w, h];\r\n }\r\n /** @internal */\r\n private _getGlyphBitmap(char: string, font: Font) {\r\n if (!font) {\r\n return null;\r\n }\r\n FontCanvas.font = font.fontNameScaled;\r\n const metric = FontCanvas.context.measureText(char);\r\n let w = metric.width;\r\n if (w === 0) {\r\n return null;\r\n }\r\n if (typeof metric.actualBoundingBoxRight === 'number') {\r\n w = Math.floor(Math.max(w, metric.actualBoundingBoxRight) + 0.8);\r\n }\r\n const h = font.maxHeightScaled;\r\n FontCanvas.context.fillStyle = '#fff';\r\n FontCanvas.context.clearRect(0, 0, w + 2, h);\r\n FontCanvas.context.fillText(char, 0, -font.topScaled);\r\n return FontCanvas.context.getImageData(0, 0, w, h);\r\n }\r\n /** @internal */\r\n private _hash(char: string, font: Font) {\r\n return `${font.family}@${font.size}&${char}`;\r\n }\r\n /** @internal */\r\n private _cacheGlyph(char: string, font: Font) {\r\n const bitmap = this._getGlyphBitmap(char, font) as ImageData;\r\n return this.pushBitmap(this._hash(char, font), bitmap);\r\n }\r\n}\r\n"],"names":["GlyphManager","TextureAtlasManager","device","binWidth","binHeight","border","atlasTextureRestoreHandler","isEmpty","clear","getGlyphSize","char","font","_getGlyphSize","getGlyphInfo","glyphInfo","getAtlasInfo","_hash","_cacheGlyph","width","Math","round","maxHeight","maxHeightScaled","height","measureStringWidth","str","charMargin","w","ch","getCharWidth","clipStringToWidth","start","sum","i","length","FontCanvas","fontNameScaled","metric","context","measureText","actualBoundingBoxRight","floor","max","h","_getGlyphBitmap","fillStyle","clearRect","fillText","topScaled","getImageData","family","size","bitmap","pushBitmap"],"mappings":"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"}
@@ -127,9 +127,13 @@ import { RectsPacker } from '@zephyr3d/base';
127
127
  return null;
128
128
  }
129
129
  /** @internal */ _createAtlasTexture() {
130
- const tex = this._device.createTexture2D('rgba8unorm', this._binWidth, this._binHeight, {
130
+ const format = 'rgba8unorm';
131
+ const tex = this._device.createTexture2D(format, this._binWidth, this._binHeight, {
131
132
  mipmapping: false
132
133
  });
134
+ if (!tex) {
135
+ throw new Error(`Create 2D texture failed: ${format}-${this._binWidth}x${this._binHeight}`);
136
+ }
133
137
  tex.update(new Uint8Array(tex.width * tex.height * 4), 0, 0, tex.width, tex.height);
134
138
  tex.restoreHandler = ()=>{
135
139
  tex.update(new Uint8Array(tex.width * tex.height * 4), 0, 0, tex.width, tex.height);
@@ -138,7 +142,7 @@ import { RectsPacker } from '@zephyr3d/base';
138
142
  return tex;
139
143
  }
140
144
  /** @internal */ _updateAtlasTextureCanvas(atlasIndex, ctx, x, y, w, h, xOffset, yOffset) {
141
- let textureAtlas = null;
145
+ let textureAtlas;
142
146
  if (atlasIndex === this._atlasList.length) {
143
147
  textureAtlas = this._createAtlasTexture();
144
148
  this._atlasList.push(textureAtlas);
@@ -148,7 +152,7 @@ import { RectsPacker } from '@zephyr3d/base';
148
152
  textureAtlas.updateFromElement(ctx.canvas, x, y, xOffset, yOffset, w, h);
149
153
  }
150
154
  /** @internal */ _updateAtlasTexture(atlasIndex, bitmap, x, y) {
151
- let textureAtlas = null;
155
+ let textureAtlas;
152
156
  if (atlasIndex === this._atlasList.length) {
153
157
  textureAtlas = this._createAtlasTexture();
154
158
  this._atlasList.push(textureAtlas);
@@ -1 +1 @@
1
- {"version":3,"file":"textureatlas.js","sources":["../../src/helpers/textureatlas.ts"],"sourcesContent":["import { RectsPacker } from '@zephyr3d/base';\r\nimport type { AbstractDevice } 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: Texture2D[];\r\n /** @internal */\r\n protected _atlasInfoMap: Record<string, AtlasInfo>;\r\n /** @internal */\r\n protected _atlasRestoreHandler: (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(): (tex: BaseTexture) => void {\r\n return this._atlasRestoreHandler;\r\n }\r\n set atlasTextureRestoreHandler(f: (tex: BaseTexture) => void) {\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): Texture2D {\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): AtlasInfo {\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(): boolean {\r\n return this._atlasList.length === 0;\r\n }\r\n /**\r\n * Removes all created atlases\r\n */\r\n clear(): void {\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(\r\n key: string,\r\n ctx: CanvasRenderingContext2D,\r\n x: number,\r\n y: number,\r\n w: number,\r\n h: number\r\n ): AtlasInfo {\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): AtlasInfo {\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(): Texture2D {\r\n const tex = this._device.createTexture2D('rgba8unorm', this._binWidth, this._binHeight, {\r\n mipmapping: false\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 ): void {\r\n let textureAtlas: Texture2D = null;\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(\r\n atlasIndex: number,\r\n bitmap: ImageData | ImageBitmap,\r\n x: number,\r\n y: number\r\n ): void {\r\n let textureAtlas: Texture2D = null;\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","createTexture2D","mipmapping","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 { 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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"}