@zephyr3d/scene 0.9.3 → 0.9.4

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 (129) hide show
  1. package/dist/animation/spring/spring_particle.js +4 -4
  2. package/dist/animation/spring/spring_particle.js.map +1 -1
  3. package/dist/app/engine.js +119 -71
  4. package/dist/app/engine.js.map +1 -1
  5. package/dist/asset/assetmanager.js +296 -244
  6. package/dist/asset/assetmanager.js.map +1 -1
  7. package/dist/asset/loaders/gltf/gltf_loader.js +1 -0
  8. package/dist/asset/loaders/gltf/gltf_loader.js.map +1 -1
  9. package/dist/asset/model.js +57 -57
  10. package/dist/asset/model.js.map +1 -1
  11. package/dist/index.d.ts +684 -33
  12. package/dist/index.js +10 -1
  13. package/dist/index.js.map +1 -1
  14. package/dist/material/material.js +1 -1
  15. package/dist/material/material.js.map +1 -1
  16. package/dist/material/msdf_text.js +180 -0
  17. package/dist/material/msdf_text.js.map +1 -0
  18. package/dist/material/msdf_text_sprite.js +64 -0
  19. package/dist/material/msdf_text_sprite.js.map +1 -0
  20. package/dist/material/pbrblueprint.js +123 -108
  21. package/dist/material/pbrblueprint.js.map +1 -1
  22. package/dist/material/shader/helper.js +277 -277
  23. package/dist/material/shader/helper.js.map +1 -1
  24. package/dist/material/sprite_sdf.js +106 -0
  25. package/dist/material/sprite_sdf.js.map +1 -0
  26. package/dist/posteffect/ssr.js +1 -0
  27. package/dist/posteffect/ssr.js.map +1 -1
  28. package/dist/render/abuffer_oit.js +1 -0
  29. package/dist/render/abuffer_oit.js.map +1 -1
  30. package/dist/render/cluster_light.js.map +1 -1
  31. package/dist/render/cull_visitor.js +28 -0
  32. package/dist/render/cull_visitor.js.map +1 -1
  33. package/dist/render/drawable.js.map +1 -1
  34. package/dist/render/drawable_mixin.js +1 -0
  35. package/dist/render/drawable_mixin.js.map +1 -1
  36. package/dist/render/fbm_wavegenerator.js +1 -0
  37. package/dist/render/fbm_wavegenerator.js.map +1 -1
  38. package/dist/render/gerstner_wavegenerator.js +1 -0
  39. package/dist/render/gerstner_wavegenerator.js.map +1 -1
  40. package/dist/render/globalbindgroup_allocator.js +1 -0
  41. package/dist/render/globalbindgroup_allocator.js.map +1 -1
  42. package/dist/render/render_queue.js +1 -0
  43. package/dist/render/render_queue.js.map +1 -1
  44. package/dist/scene/basesprite.js +1 -5
  45. package/dist/scene/basesprite.js.map +1 -1
  46. package/dist/scene/batchgroup.js +29 -17
  47. package/dist/scene/batchgroup.js.map +1 -1
  48. package/dist/scene/environment.js +1 -0
  49. package/dist/scene/environment.js.map +1 -1
  50. package/dist/scene/mesh.js +86 -87
  51. package/dist/scene/mesh.js.map +1 -1
  52. package/dist/scene/meshdrawable.js +96 -0
  53. package/dist/scene/meshdrawable.js.map +1 -0
  54. package/dist/scene/msdftext.js +341 -0
  55. package/dist/scene/msdftext.js.map +1 -0
  56. package/dist/scene/msdftextsprite.js +349 -0
  57. package/dist/scene/msdftextsprite.js.map +1 -0
  58. package/dist/scene/particlesys.js +1 -0
  59. package/dist/scene/particlesys.js.map +1 -1
  60. package/dist/scene/scene.js +1 -0
  61. package/dist/scene/scene.js.map +1 -1
  62. package/dist/scene/scene_node.js +234 -228
  63. package/dist/scene/scene_node.js.map +1 -1
  64. package/dist/scene/sdftextsprite.js +322 -0
  65. package/dist/scene/sdftextsprite.js.map +1 -0
  66. package/dist/scene/terrain-cm/grass.js +1 -0
  67. package/dist/scene/terrain-cm/grass.js.map +1 -1
  68. package/dist/scene/terrain-cm/grassmaterial.js +1 -0
  69. package/dist/scene/terrain-cm/grassmaterial.js.map +1 -1
  70. package/dist/scene/terrain-cm/terrain-cm.js +1 -0
  71. package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
  72. package/dist/scene/textsprite.js +120 -0
  73. package/dist/scene/textsprite.js.map +1 -0
  74. package/dist/scene/water.js +1 -0
  75. package/dist/scene/water.js.map +1 -1
  76. package/dist/shadow/shader.js +1 -0
  77. package/dist/shadow/shader.js.map +1 -1
  78. package/dist/text/font/font_asset.js +884 -0
  79. package/dist/text/font/font_asset.js.map +1 -0
  80. package/dist/text/font/sfnt_reader.js +43 -0
  81. package/dist/text/font/sfnt_reader.js.map +1 -0
  82. package/dist/text/msdf/generator.js +417 -0
  83. package/dist/text/msdf/generator.js.map +1 -0
  84. package/dist/text/msdf/shape.js +143 -0
  85. package/dist/text/msdf/shape.js.map +1 -0
  86. package/dist/text/runtime/msdf_glyph_atlas.js +146 -0
  87. package/dist/text/runtime/msdf_glyph_atlas.js.map +1 -0
  88. package/dist/text/runtime/msdf_text_atlas_manager.js +47 -0
  89. package/dist/text/runtime/msdf_text_atlas_manager.js.map +1 -0
  90. package/dist/text/runtime/text_layout.js +96 -0
  91. package/dist/text/runtime/text_layout.js.map +1 -0
  92. package/dist/utility/blueprint/material/inputs.js +1275 -1091
  93. package/dist/utility/blueprint/material/inputs.js.map +1 -1
  94. package/dist/utility/blueprint/material/ir.js +16 -1
  95. package/dist/utility/blueprint/material/ir.js.map +1 -1
  96. package/dist/utility/blueprint/material/pbr.js +32 -0
  97. package/dist/utility/blueprint/material/pbr.js.map +1 -1
  98. package/dist/utility/serialization/manager.js +321 -277
  99. package/dist/utility/serialization/manager.js.map +1 -1
  100. package/dist/utility/serialization/scene/animation.js +2 -0
  101. package/dist/utility/serialization/scene/animation.js.map +1 -1
  102. package/dist/utility/serialization/scene/batch.js +2 -0
  103. package/dist/utility/serialization/scene/batch.js.map +1 -1
  104. package/dist/utility/serialization/scene/camera.js +2 -0
  105. package/dist/utility/serialization/scene/camera.js.map +1 -1
  106. package/dist/utility/serialization/scene/light.js +2 -0
  107. package/dist/utility/serialization/scene/light.js.map +1 -1
  108. package/dist/utility/serialization/scene/material.js +1 -0
  109. package/dist/utility/serialization/scene/material.js.map +1 -1
  110. package/dist/utility/serialization/scene/mesh.js +2 -0
  111. package/dist/utility/serialization/scene/mesh.js.map +1 -1
  112. package/dist/utility/serialization/scene/node.js +2 -0
  113. package/dist/utility/serialization/scene/node.js.map +1 -1
  114. package/dist/utility/serialization/scene/particle.js +2 -0
  115. package/dist/utility/serialization/scene/particle.js.map +1 -1
  116. package/dist/utility/serialization/scene/primitive.js +1 -0
  117. package/dist/utility/serialization/scene/primitive.js.map +1 -1
  118. package/dist/utility/serialization/scene/sprite.js +2 -0
  119. package/dist/utility/serialization/scene/sprite.js.map +1 -1
  120. package/dist/utility/serialization/scene/terrain.js +2 -0
  121. package/dist/utility/serialization/scene/terrain.js.map +1 -1
  122. package/dist/utility/serialization/scene/text.js +516 -0
  123. package/dist/utility/serialization/scene/text.js.map +1 -0
  124. package/dist/utility/serialization/scene/water.js +2 -0
  125. package/dist/utility/serialization/scene/water.js.map +1 -1
  126. package/dist/utility/serialization/types.js.map +1 -1
  127. package/dist/values.js +48 -48
  128. package/dist/values.js.map +1 -1
  129. package/package.json +3 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generator.js","sources":["../../../src/text/msdf/generator.ts"],"sourcesContent":["import { clamp } from '@zephyr3d/base';\r\nimport type { GlyphData } from '../font';\r\nimport { buildMSDFShape } from './shape';\r\nimport type { ColoredEdge, MSDFBitmap, MSDFOptions } from './types';\r\n\r\nconst DEFAULT_PADDING = 1;\r\nconst CHANNEL_MASKS = [1, 2, 4] as const;\r\nconst EPSILON = 1e-8;\r\nconst CONTOUR_PROBE_DISTANCES = [1, 4, 16] as const;\r\n\r\ntype DistanceSample = {\r\n distance: number;\r\n absDistance: number;\r\n dot: number;\r\n};\r\n\r\n/**\r\n * Generate a runtime RGB(A) distance field bitmap from a parsed glyph.\r\n *\r\n * Distances are encoded in output texel units, which matches the shader-side\r\n * `distanceRange` logic and keeps the field scale-invariant across font sizes.\r\n *\r\n * @public\r\n */\r\nexport function generateMSDF(glyph: GlyphData, options: MSDFOptions): MSDFBitmap {\r\n const shape = buildMSDFShape(glyph.contours);\r\n const width = Math.max(1, options.width | 0);\r\n const height = Math.max(1, options.height | 0);\r\n const padding = options.padding ?? DEFAULT_PADDING;\r\n const boundsWidth = Math.max(1, glyph.xMax - glyph.xMin);\r\n const boundsHeight = Math.max(1, glyph.yMax - glyph.yMin);\r\n const drawableWidth = Math.max(1, width - padding * 2);\r\n const drawableHeight = Math.max(1, height - padding * 2);\r\n const scale = Math.min(drawableWidth / boundsWidth, drawableHeight / boundsHeight);\r\n const placedWidth = boundsWidth * scale;\r\n const placedHeight = boundsHeight * scale;\r\n const translateX = padding + (drawableWidth - placedWidth) * 0.5 - glyph.xMin * scale;\r\n const translateY = padding + (drawableHeight - placedHeight) * 0.5 + glyph.yMax * scale;\r\n const contourInsideSigns = shape.contours.map((contour) => determineContourInsideSign(contour, shape.contours));\r\n const fields = new Float32Array(width * height * 4);\r\n\r\n for (let y = 0; y < height; y++) {\r\n for (let x = 0; x < width; x++) {\r\n const sourceX = (x + 0.5 - translateX) / scale;\r\n const sourceY = -(y + 0.5 - translateY) / scale;\r\n const inside = pointInShape(sourceX, sourceY, shape.contours);\r\n let minDistance = Number.POSITIVE_INFINITY;\r\n const channelSamples: [DistanceSample | null, DistanceSample | null, DistanceSample | null] = [\r\n null,\r\n null,\r\n null\r\n ];\r\n for (let contourIndex = 0; contourIndex < shape.contours.length; contourIndex++) {\r\n const contour = shape.contours[contourIndex];\r\n const insideSign = contourInsideSigns[contourIndex];\r\n for (const edge of contour) {\r\n const sample = sampleEdge(edge, sourceX, sourceY, insideSign);\r\n if (sample.absDistance < minDistance) {\r\n minDistance = sample.absDistance;\r\n }\r\n for (let channelIndex = 0; channelIndex < CHANNEL_MASKS.length; channelIndex++) {\r\n if ((edge.color & CHANNEL_MASKS[channelIndex]) !== 0 && betterSample(sample, channelSamples[channelIndex])) {\r\n channelSamples[channelIndex] = sample;\r\n }\r\n }\r\n }\r\n }\r\n if (!Number.isFinite(minDistance)) {\r\n minDistance = 0;\r\n }\r\n const sdfDistance = (inside ? minDistance : -minDistance) * scale;\r\n const base = (y * width + x) * 4;\r\n fields[base + 0] = (channelSamples[0]?.distance ?? (inside ? minDistance : -minDistance)) * scale;\r\n fields[base + 1] = (channelSamples[1]?.distance ?? (inside ? minDistance : -minDistance)) * scale;\r\n fields[base + 2] = (channelSamples[2]?.distance ?? (inside ? minDistance : -minDistance)) * scale;\r\n fields[base + 3] = sdfDistance;\r\n }\r\n }\r\n\r\n applyMedianCorrection(fields, width, height, options.range);\r\n\r\n const pixels = new Uint8Array(width * height * 4);\r\n for (let i = 0; i < width * height; i++) {\r\n const base = i * 4;\r\n pixels[base + 0] = encodeDistance(fields[base + 0], options.range);\r\n pixels[base + 1] = encodeDistance(fields[base + 1], options.range);\r\n pixels[base + 2] = encodeDistance(fields[base + 2], options.range);\r\n pixels[base + 3] = encodeDistance(fields[base + 3], options.range);\r\n }\r\n\r\n return {\r\n width,\r\n height,\r\n pixels,\r\n scale,\r\n translateX,\r\n translateY\r\n };\r\n}\r\n\r\nfunction encodeDistance(distance: number, range: number) {\r\n return Math.round(clamp(0.5 + distance / (2 * Math.max(range, 1e-6)), 0, 1) * 255);\r\n}\r\n\r\nfunction betterSample(next: DistanceSample, current: DistanceSample | null) {\r\n return (\r\n !current ||\r\n next.absDistance < current.absDistance - 1e-6 ||\r\n (Math.abs(next.absDistance - current.absDistance) <= 1e-6 && next.dot < current.dot)\r\n );\r\n}\r\n\r\nfunction sampleEdge(edge: ColoredEdge, x: number, y: number, insideSign: number): DistanceSample {\r\n return edge.kind === 'line'\r\n ? sampleLineEdge(edge, x, y, insideSign)\r\n : sampleQuadraticEdge(edge, x, y, insideSign);\r\n}\r\n\r\nfunction sampleLineEdge(edge: Extract<ColoredEdge, { kind: 'line' }>, x: number, y: number, insideSign: number) {\r\n const dx = edge.p1.x - edge.p0.x;\r\n const dy = edge.p1.y - edge.p0.y;\r\n const lenSq = dx * dx + dy * dy;\r\n if (lenSq <= EPSILON) {\r\n return sampleEndpoint(edge.p0.x, edge.p0.y, 1, 0, x, y, insideSign);\r\n }\r\n const qx = x - edge.p0.x;\r\n const qy = y - edge.p0.y;\r\n const t = (qx * dx + qy * dy) / lenSq;\r\n if (t <= 0) {\r\n return sampleEndpoint(edge.p0.x, edge.p0.y, dx, dy, x, y, insideSign);\r\n }\r\n if (t >= 1) {\r\n return sampleEndpoint(edge.p1.x, edge.p1.y, dx, dy, x, y, insideSign);\r\n }\r\n const cx = edge.p0.x + dx * t;\r\n const cy = edge.p0.y + dy * t;\r\n const deltaX = x - cx;\r\n const deltaY = y - cy;\r\n const absDistance = Math.hypot(deltaX, deltaY);\r\n return {\r\n distance: signedPerpendicularDistance(dx, dy, deltaX, deltaY, insideSign),\r\n absDistance,\r\n dot: directionDot(deltaX, deltaY, dx, dy, absDistance)\r\n };\r\n}\r\n\r\nfunction sampleQuadraticEdge(\r\n edge: Extract<ColoredEdge, { kind: 'quadratic' }>,\r\n x: number,\r\n y: number,\r\n insideSign: number\r\n) {\r\n const t = findNearestQuadraticParameter(edge, x, y);\r\n if (t <= EPSILON) {\r\n const tangent = quadraticEndpointTangent(edge, true);\r\n return sampleEndpoint(edge.p0.x, edge.p0.y, tangent.x, tangent.y, x, y, insideSign);\r\n }\r\n if (t >= 1 - EPSILON) {\r\n const tangent = quadraticEndpointTangent(edge, false);\r\n return sampleEndpoint(edge.p2.x, edge.p2.y, tangent.x, tangent.y, x, y, insideSign);\r\n }\r\n const point = evaluateQuadratic(edge, t);\r\n const tangent = quadraticTangent(edge, t);\r\n const deltaX = x - point.x;\r\n const deltaY = y - point.y;\r\n const absDistance = Math.hypot(deltaX, deltaY);\r\n return {\r\n distance: signedPerpendicularDistance(tangent.x, tangent.y, deltaX, deltaY, insideSign),\r\n absDistance,\r\n dot: directionDot(deltaX, deltaY, tangent.x, tangent.y, absDistance)\r\n };\r\n}\r\n\r\nfunction sampleEndpoint(\r\n px: number,\r\n py: number,\r\n tx: number,\r\n ty: number,\r\n x: number,\r\n y: number,\r\n insideSign: number\r\n): DistanceSample {\r\n const deltaX = x - px;\r\n const deltaY = y - py;\r\n const absDistance = Math.hypot(deltaX, deltaY);\r\n return {\r\n distance: signedPerpendicularDistance(tx, ty, deltaX, deltaY, insideSign),\r\n absDistance,\r\n dot: directionDot(deltaX, deltaY, tx, ty, absDistance)\r\n };\r\n}\r\n\r\nfunction signedPerpendicularDistance(tx: number, ty: number, dx: number, dy: number, insideSign: number) {\r\n const tangentLength = Math.hypot(tx, ty);\r\n if (tangentLength <= EPSILON) {\r\n return 0;\r\n }\r\n return (insideSign * cross(tx, ty, dx, dy)) / tangentLength;\r\n}\r\n\r\nfunction directionDot(dx: number, dy: number, tx: number, ty: number, absDistance: number) {\r\n const tangentLength = Math.hypot(tx, ty);\r\n if (absDistance <= EPSILON || tangentLength <= EPSILON) {\r\n return 0;\r\n }\r\n return Math.abs((dx * tx + dy * ty) / (absDistance * tangentLength));\r\n}\r\n\r\nfunction findNearestQuadraticParameter(edge: Extract<ColoredEdge, { kind: 'quadratic' }>, x: number, y: number) {\r\n const ax = edge.p0.x - 2 * edge.p1.x + edge.p2.x;\r\n const ay = edge.p0.y - 2 * edge.p1.y + edge.p2.y;\r\n const bx = 2 * (edge.p1.x - edge.p0.x);\r\n const by = 2 * (edge.p1.y - edge.p0.y);\r\n const cx = edge.p0.x - x;\r\n const cy = edge.p0.y - y;\r\n const roots = solveCubic(\r\n 2 * dot(ax, ay, ax, ay),\r\n 3 * dot(ax, ay, bx, by),\r\n dot(bx, by, bx, by) + 2 * dot(ax, ay, cx, cy),\r\n dot(bx, by, cx, cy)\r\n );\r\n let nearestT = 0;\r\n let minDistanceSq = Number.POSITIVE_INFINITY;\r\n for (const candidate of [0, ...roots, 1]) {\r\n const t = clamp(candidate, 0, 1);\r\n const point = evaluateQuadratic(edge, t);\r\n const distX = x - point.x;\r\n const distY = y - point.y;\r\n const distanceSq = distX * distX + distY * distY;\r\n if (distanceSq < minDistanceSq - 1e-6) {\r\n minDistanceSq = distanceSq;\r\n nearestT = t;\r\n }\r\n }\r\n return nearestT;\r\n}\r\n\r\nfunction evaluateQuadratic(edge: Extract<ColoredEdge, { kind: 'quadratic' }>, t: number) {\r\n const mt = 1 - t;\r\n return {\r\n x: mt * mt * edge.p0.x + 2 * mt * t * edge.p1.x + t * t * edge.p2.x,\r\n y: mt * mt * edge.p0.y + 2 * mt * t * edge.p1.y + t * t * edge.p2.y\r\n };\r\n}\r\n\r\nfunction quadraticTangent(edge: Extract<ColoredEdge, { kind: 'quadratic' }>, t: number) {\r\n const x = 2 * ((1 - t) * (edge.p1.x - edge.p0.x) + t * (edge.p2.x - edge.p1.x));\r\n const y = 2 * ((1 - t) * (edge.p1.y - edge.p0.y) + t * (edge.p2.y - edge.p1.y));\r\n if (Math.hypot(x, y) > EPSILON) {\r\n return { x, y };\r\n }\r\n return quadraticEndpointTangent(edge, t < 0.5);\r\n}\r\n\r\nfunction quadraticEndpointTangent(edge: Extract<ColoredEdge, { kind: 'quadratic' }>, atStart: boolean) {\r\n const tx = atStart ? edge.p1.x - edge.p0.x : edge.p2.x - edge.p1.x;\r\n const ty = atStart ? edge.p1.y - edge.p0.y : edge.p2.y - edge.p1.y;\r\n if (Math.hypot(tx, ty) > EPSILON) {\r\n return { x: tx, y: ty };\r\n }\r\n const fallbackX = edge.p2.x - edge.p0.x;\r\n const fallbackY = edge.p2.y - edge.p0.y;\r\n if (Math.hypot(fallbackX, fallbackY) > EPSILON) {\r\n return { x: fallbackX, y: fallbackY };\r\n }\r\n return { x: 1, y: 0 };\r\n}\r\n\r\nfunction solveCubic(a: number, b: number, c: number, d: number): number[] {\r\n if (Math.abs(a) <= EPSILON) {\r\n return solveQuadratic(b, c, d);\r\n }\r\n const invA = 1 / a;\r\n const B = b * invA;\r\n const C = c * invA;\r\n const D = d * invA;\r\n const p = C - (B * B) / 3;\r\n const q = (2 * B * B * B) / 27 - (B * C) / 3 + D;\r\n const disc = (q * q) / 4 + (p * p * p) / 27;\r\n const shift = -B / 3;\r\n if (disc > EPSILON) {\r\n const sqrtDisc = Math.sqrt(disc);\r\n return [Math.cbrt(-q / 2 + sqrtDisc) + Math.cbrt(-q / 2 - sqrtDisc) + shift];\r\n }\r\n if (disc < -EPSILON) {\r\n const acosArg = clamp(-q / 2 / Math.sqrt((-p * p * p) / 27), -1, 1);\r\n const theta = Math.acos(acosArg);\r\n const rho = 2 * Math.sqrt(-p / 3);\r\n return dedupeRoots([\r\n rho * Math.cos(theta / 3) + shift,\r\n rho * Math.cos((theta + 2 * Math.PI) / 3) + shift,\r\n rho * Math.cos((theta + 4 * Math.PI) / 3) + shift\r\n ]);\r\n }\r\n const u = Math.cbrt(-q / 2);\r\n return dedupeRoots([2 * u + shift, -u + shift]);\r\n}\r\n\r\nfunction solveQuadratic(a: number, b: number, c: number): number[] {\r\n if (Math.abs(a) <= EPSILON) {\r\n return Math.abs(b) <= EPSILON ? [] : [-c / b];\r\n }\r\n const disc = b * b - 4 * a * c;\r\n if (disc < -EPSILON) {\r\n return [];\r\n }\r\n if (Math.abs(disc) <= EPSILON) {\r\n return [-b / (2 * a)];\r\n }\r\n const sqrtDisc = Math.sqrt(Math.max(disc, 0));\r\n return dedupeRoots([(-b - sqrtDisc) / (2 * a), (-b + sqrtDisc) / (2 * a)]);\r\n}\r\n\r\nfunction dedupeRoots(values: number[]) {\r\n const roots: number[] = [];\r\n for (const value of values) {\r\n if (!roots.some((root) => Math.abs(root - value) <= 1e-7)) {\r\n roots.push(value);\r\n }\r\n }\r\n return roots;\r\n}\r\n\r\nfunction determineContourInsideSign(contour: ColoredEdge[], allContours: ColoredEdge[][]) {\r\n for (const edge of contour) {\r\n const probe = edgeProbe(edge);\r\n const tangentLength = Math.hypot(probe.tangent.x, probe.tangent.y);\r\n if (tangentLength <= EPSILON) {\r\n continue;\r\n }\r\n const normalX = -probe.tangent.y / tangentLength;\r\n const normalY = probe.tangent.x / tangentLength;\r\n for (const distance of CONTOUR_PROBE_DISTANCES) {\r\n const leftInside = pointInShape(probe.point.x + normalX * distance, probe.point.y + normalY * distance, allContours);\r\n const rightInside = pointInShape(\r\n probe.point.x - normalX * distance,\r\n probe.point.y - normalY * distance,\r\n allContours\r\n );\r\n if (leftInside !== rightInside) {\r\n return leftInside ? 1 : -1;\r\n }\r\n }\r\n }\r\n return approximateContourSign(contour);\r\n}\r\n\r\nfunction edgeProbe(edge: ColoredEdge) {\r\n if (edge.kind === 'line') {\r\n return {\r\n point: {\r\n x: (edge.p0.x + edge.p1.x) * 0.5,\r\n y: (edge.p0.y + edge.p1.y) * 0.5\r\n },\r\n tangent: {\r\n x: edge.p1.x - edge.p0.x,\r\n y: edge.p1.y - edge.p0.y\r\n }\r\n };\r\n }\r\n return {\r\n point: evaluateQuadratic(edge, 0.5),\r\n tangent: quadraticTangent(edge, 0.5)\r\n };\r\n}\r\n\r\nfunction approximateContourSign(contour: ColoredEdge[]) {\r\n let area = 0;\r\n for (const edge of contour) {\r\n if (edge.kind === 'line') {\r\n area += cross(edge.p0.x, edge.p0.y, edge.p1.x, edge.p1.y);\r\n } else {\r\n area += cross(edge.p0.x, edge.p0.y, edge.p1.x, edge.p1.y);\r\n area += cross(edge.p1.x, edge.p1.y, edge.p2.x, edge.p2.y);\r\n }\r\n }\r\n return area >= 0 ? 1 : -1;\r\n}\r\n\r\nfunction applyMedianCorrection(fields: Float32Array, width: number, height: number, range: number) {\r\n const correctionThreshold = 1;\r\n const edgeThreshold = Math.max(range + 1, 1);\r\n for (let i = 0; i < width * height; i++) {\r\n const base = i * 4;\r\n const median = median3(fields[base + 0], fields[base + 1], fields[base + 2]);\r\n const sdf = fields[base + 3];\r\n if (Math.abs(sdf) <= edgeThreshold && Math.abs(median - sdf) > correctionThreshold) {\r\n fields[base + 0] = sdf;\r\n fields[base + 1] = sdf;\r\n fields[base + 2] = sdf;\r\n }\r\n }\r\n}\r\n\r\nfunction pointInShape(x: number, y: number, contours: ColoredEdge[][]) {\r\n let winding = 0;\r\n for (const contour of contours) {\r\n winding += contourWinding(x, y, contour);\r\n }\r\n return winding !== 0;\r\n}\r\n\r\nfunction contourWinding(x: number, y: number, contour: ColoredEdge[]) {\r\n let winding = 0;\r\n for (const edge of contour) {\r\n if (edge.kind === 'line') {\r\n winding += windingContribution(x, y, edge.p0.x, edge.p0.y, edge.p1.x, edge.p1.y);\r\n } else {\r\n let prevX = edge.p0.x;\r\n let prevY = edge.p0.y;\r\n const steps = 16;\r\n for (let i = 1; i <= steps; i++) {\r\n const t = i / steps;\r\n const point = evaluateQuadratic(edge, t);\r\n winding += windingContribution(x, y, prevX, prevY, point.x, point.y);\r\n prevX = point.x;\r\n prevY = point.y;\r\n }\r\n }\r\n }\r\n return winding;\r\n}\r\n\r\nfunction windingContribution(px: number, py: number, x0: number, y0: number, x1: number, y1: number) {\r\n if (y0 <= py) {\r\n if (y1 > py && cross(x1 - x0, y1 - y0, px - x0, py - y0) > 0) {\r\n return 1;\r\n }\r\n } else if (y1 <= py && cross(x1 - x0, y1 - y0, px - x0, py - y0) < 0) {\r\n return -1;\r\n }\r\n return 0;\r\n}\r\n\r\nfunction median3(a: number, b: number, c: number) {\r\n return a + b + c - Math.min(a, b, c) - Math.max(a, b, c);\r\n}\r\n\r\nfunction cross(ax: number, ay: number, bx: number, by: number) {\r\n return ax * by - ay * bx;\r\n}\r\n\r\nfunction dot(ax: number, ay: number, bx: number, by: number) {\r\n return ax * bx + ay * by;\r\n}\r\n"],"names":["DEFAULT_PADDING","CHANNEL_MASKS","EPSILON","CONTOUR_PROBE_DISTANCES","generateMSDF","glyph","options","shape","buildMSDFShape","contours","width","Math","max","height","padding","boundsWidth","xMax","xMin","boundsHeight","yMax","yMin","drawableWidth","drawableHeight","scale","min","placedWidth","placedHeight","translateX","translateY","contourInsideSigns","map","contour","determineContourInsideSign","fields","Float32Array","y","x","sourceX","sourceY","inside","pointInShape","minDistance","Number","POSITIVE_INFINITY","channelSamples","contourIndex","length","insideSign","edge","sample","sampleEdge","absDistance","channelIndex","color","betterSample","isFinite","sdfDistance","base","distance","applyMedianCorrection","range","pixels","Uint8Array","i","encodeDistance","round","clamp","next","current","abs","dot","kind","sampleLineEdge","sampleQuadraticEdge","dx","p1","p0","dy","lenSq","sampleEndpoint","qx","qy","t","cx","cy","deltaX","deltaY","hypot","signedPerpendicularDistance","directionDot","findNearestQuadraticParameter","tangent","quadraticEndpointTangent","p2","point","evaluateQuadratic","quadraticTangent","px","py","tx","ty","tangentLength","cross","ax","ay","bx","by","roots","solveCubic","nearestT","minDistanceSq","candidate","distX","distY","distanceSq","mt","atStart","fallbackX","fallbackY","a","b","c","d","solveQuadratic","invA","B","C","D","p","q","disc","shift","sqrtDisc","sqrt","cbrt","acosArg","theta","acos","rho","dedupeRoots","cos","PI","u","values","value","some","root","push","allContours","probe","edgeProbe","normalX","normalY","leftInside","rightInside","approximateContourSign","area","correctionThreshold","edgeThreshold","median","median3","sdf","winding","contourWinding","windingContribution","prevX","prevY","steps","x0","y0","x1","y1"],"mappings":"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"}
@@ -0,0 +1,143 @@
1
+ function buildMSDFShape(contours) {
2
+ return {
3
+ sourceContours: contours.map((contour)=>contour.map(clonePoint)),
4
+ contours: contours.map((contour)=>colorizeContour(buildContourEdges(contour)))
5
+ };
6
+ }
7
+ function clonePoint(point) {
8
+ return {
9
+ x: point.x,
10
+ y: point.y,
11
+ onCurve: point.onCurve
12
+ };
13
+ }
14
+ function buildContourEdges(contour) {
15
+ contour = normalizeContourStart(contour);
16
+ if (contour.length < 2) {
17
+ return [];
18
+ }
19
+ const edges = [];
20
+ let i = 0;
21
+ while(i < contour.length){
22
+ const p0 = contour[i];
23
+ const p1 = contour[(i + 1) % contour.length];
24
+ if (p0.onCurve && p1.onCurve) {
25
+ edges.push({
26
+ kind: 'line',
27
+ color: 7,
28
+ p0: {
29
+ x: p0.x,
30
+ y: p0.y
31
+ },
32
+ p1: {
33
+ x: p1.x,
34
+ y: p1.y
35
+ }
36
+ });
37
+ i += 1;
38
+ continue;
39
+ }
40
+ if (p0.onCurve && !p1.onCurve) {
41
+ const p2 = contour[(i + 2) % contour.length];
42
+ if (!p2.onCurve) {
43
+ throw new Error('Implicit midpoint contours must be expanded before MSDF conversion');
44
+ }
45
+ edges.push({
46
+ kind: 'quadratic',
47
+ color: 7,
48
+ p0: {
49
+ x: p0.x,
50
+ y: p0.y
51
+ },
52
+ p1: {
53
+ x: p1.x,
54
+ y: p1.y
55
+ },
56
+ p2: {
57
+ x: p2.x,
58
+ y: p2.y
59
+ }
60
+ });
61
+ i += 2;
62
+ continue;
63
+ }
64
+ throw new Error('MSDF contour must start edge on an on-curve point');
65
+ }
66
+ return edges;
67
+ }
68
+ function normalizeContourStart(contour) {
69
+ if (contour.length === 0) {
70
+ return contour;
71
+ }
72
+ const firstOnCurve = contour.findIndex((point)=>point.onCurve);
73
+ if (firstOnCurve < 0 || firstOnCurve === 0) {
74
+ return contour;
75
+ }
76
+ return contour.slice(firstOnCurve).concat(contour.slice(0, firstOnCurve));
77
+ }
78
+ function colorizeContour(edges) {
79
+ if (edges.length === 0) {
80
+ return edges;
81
+ }
82
+ const corners = detectCorners(edges);
83
+ if (corners.length === 0) {
84
+ for(let i = 0; i < edges.length; i++){
85
+ edges[i].color = 7;
86
+ }
87
+ return edges;
88
+ }
89
+ let color = 5;
90
+ const cornerSet = new Set(corners);
91
+ for(let i = 0; i < edges.length; i++){
92
+ edges[i].color = color;
93
+ if (cornerSet.has((i + 1) % edges.length)) {
94
+ color = color === 3 ? 6 : 3;
95
+ }
96
+ }
97
+ return edges;
98
+ }
99
+ function detectCorners(edges) {
100
+ const result = [];
101
+ for(let i = 0; i < edges.length; i++){
102
+ const prev = edges[(i + edges.length - 1) % edges.length];
103
+ const curr = edges[i];
104
+ const prevDir = normalize(getEdgeEndDirection(prev));
105
+ const currDir = normalize(getEdgeStartDirection(curr));
106
+ const dot = prevDir.x * currDir.x + prevDir.y * currDir.y;
107
+ if (dot < 0.35) {
108
+ result.push(i);
109
+ }
110
+ }
111
+ return result;
112
+ }
113
+ function getEdgeStartDirection(edge) {
114
+ return edge.kind === 'quadratic' ? {
115
+ x: edge.p1.x - edge.p0.x,
116
+ y: edge.p1.y - edge.p0.y
117
+ } : {
118
+ x: edge.p1.x - edge.p0.x,
119
+ y: edge.p1.y - edge.p0.y
120
+ };
121
+ }
122
+ function getEdgeEndDirection(edge) {
123
+ return edge.kind === 'quadratic' ? {
124
+ x: edge.p2.x - edge.p1.x,
125
+ y: edge.p2.y - edge.p1.y
126
+ } : {
127
+ x: edge.p1.x - edge.p0.x,
128
+ y: edge.p1.y - edge.p0.y
129
+ };
130
+ }
131
+ function normalize(v) {
132
+ const len = Math.hypot(v.x, v.y);
133
+ return len > 1e-8 ? {
134
+ x: v.x / len,
135
+ y: v.y / len
136
+ } : {
137
+ x: 1,
138
+ y: 0
139
+ };
140
+ }
141
+
142
+ export { buildMSDFShape };
143
+ //# sourceMappingURL=shape.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shape.js","sources":["../../../src/text/msdf/shape.ts"],"sourcesContent":["import type { GlyphContour, GlyphPoint } from '../font';\r\nimport type { ColoredEdge, EdgeColor, MSDFShape } from './types';\r\n\r\nexport function buildMSDFShape(contours: GlyphContour[]): MSDFShape {\r\n return {\r\n sourceContours: contours.map((contour) => contour.map(clonePoint)),\r\n contours: contours.map((contour) => colorizeContour(buildContourEdges(contour)))\r\n };\r\n}\r\n\r\nfunction clonePoint(point: GlyphPoint) {\r\n return { x: point.x, y: point.y, onCurve: point.onCurve };\r\n}\r\n\r\nfunction buildContourEdges(contour: GlyphContour): ColoredEdge[] {\r\n contour = normalizeContourStart(contour);\r\n if (contour.length < 2) {\r\n return [];\r\n }\r\n const edges: ColoredEdge[] = [];\r\n let i = 0;\r\n while (i < contour.length) {\r\n const p0 = contour[i];\r\n const p1 = contour[(i + 1) % contour.length];\r\n if (p0.onCurve && p1.onCurve) {\r\n edges.push({\r\n kind: 'line',\r\n color: 7,\r\n p0: { x: p0.x, y: p0.y },\r\n p1: { x: p1.x, y: p1.y }\r\n });\r\n i += 1;\r\n continue;\r\n }\r\n if (p0.onCurve && !p1.onCurve) {\r\n const p2 = contour[(i + 2) % contour.length];\r\n if (!p2.onCurve) {\r\n throw new Error('Implicit midpoint contours must be expanded before MSDF conversion');\r\n }\r\n edges.push({\r\n kind: 'quadratic',\r\n color: 7,\r\n p0: { x: p0.x, y: p0.y },\r\n p1: { x: p1.x, y: p1.y },\r\n p2: { x: p2.x, y: p2.y }\r\n });\r\n i += 2;\r\n continue;\r\n }\r\n throw new Error('MSDF contour must start edge on an on-curve point');\r\n }\r\n return edges;\r\n}\r\n\r\nfunction normalizeContourStart(contour: GlyphContour) {\r\n if (contour.length === 0) {\r\n return contour;\r\n }\r\n const firstOnCurve = contour.findIndex((point) => point.onCurve);\r\n if (firstOnCurve < 0 || firstOnCurve === 0) {\r\n return contour;\r\n }\r\n return contour.slice(firstOnCurve).concat(contour.slice(0, firstOnCurve));\r\n}\r\n\r\nfunction colorizeContour(edges: ColoredEdge[]) {\r\n if (edges.length === 0) {\r\n return edges;\r\n }\r\n const corners = detectCorners(edges);\r\n if (corners.length === 0) {\r\n for (let i = 0; i < edges.length; i++) {\r\n edges[i].color = 7;\r\n }\r\n return edges;\r\n }\r\n let color: EdgeColor = 5;\r\n const cornerSet = new Set(corners);\r\n for (let i = 0; i < edges.length; i++) {\r\n edges[i].color = color;\r\n if (cornerSet.has((i + 1) % edges.length)) {\r\n color = color === 3 ? 6 : 3;\r\n }\r\n }\r\n return edges;\r\n}\r\n\r\nfunction detectCorners(edges: ColoredEdge[]) {\r\n const result: number[] = [];\r\n for (let i = 0; i < edges.length; i++) {\r\n const prev = edges[(i + edges.length - 1) % edges.length];\r\n const curr = edges[i];\r\n const prevDir = normalize(getEdgeEndDirection(prev));\r\n const currDir = normalize(getEdgeStartDirection(curr));\r\n const dot = prevDir.x * currDir.x + prevDir.y * currDir.y;\r\n if (dot < 0.35) {\r\n result.push(i);\r\n }\r\n }\r\n return result;\r\n}\r\n\r\nfunction getEdgeStartDirection(edge: ColoredEdge) {\r\n return edge.kind === 'quadratic'\r\n ? { x: edge.p1.x - edge.p0.x, y: edge.p1.y - edge.p0.y }\r\n : { x: edge.p1.x - edge.p0.x, y: edge.p1.y - edge.p0.y };\r\n}\r\n\r\nfunction getEdgeEndDirection(edge: ColoredEdge) {\r\n return edge.kind === 'quadratic'\r\n ? { x: edge.p2!.x - edge.p1.x, y: edge.p2!.y - edge.p1.y }\r\n : { x: edge.p1.x - edge.p0.x, y: edge.p1.y - edge.p0.y };\r\n}\r\n\r\nfunction normalize(v: { x: number; y: number }) {\r\n const len = Math.hypot(v.x, v.y);\r\n return len > 1e-8 ? { x: v.x / len, y: v.y / len } : { x: 1, y: 0 };\r\n}\r\n"],"names":["buildMSDFShape","contours","sourceContours","map","contour","clonePoint","colorizeContour","buildContourEdges","point","x","y","onCurve","normalizeContourStart","length","edges","i","p0","p1","push","kind","color","p2","Error","firstOnCurve","findIndex","slice","concat","corners","detectCorners","cornerSet","Set","has","result","prev","curr","prevDir","normalize","getEdgeEndDirection","currDir","getEdgeStartDirection","dot","edge","v","len","Math","hypot"],"mappings":"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"}
@@ -0,0 +1,146 @@
1
+ import { TextureAtlasManager } from '@zephyr3d/device';
2
+ import { generateMSDF } from '../msdf/generator.js';
3
+
4
+ const ATLAS_GUTTER = 1;
5
+ /**
6
+ * Runtime dynamic MSDF glyph atlas.
7
+ *
8
+ * @public
9
+ */ class MSDFGlyphAtlas extends TextureAtlasManager {
10
+ _font;
11
+ _glyphs;
12
+ _range;
13
+ _glyphSize;
14
+ _padding;
15
+ constructor(device, font, glyphSize = 64, atlasSize = 1024, range = 6, padding = 2){
16
+ super(device, atlasSize, atlasSize, 0, true);
17
+ this._font = font;
18
+ this._glyphs = new Map();
19
+ this._range = range;
20
+ this._glyphSize = glyphSize;
21
+ this._padding = padding;
22
+ this.atlasTextureRestoreHandler = async ()=>{
23
+ const glyphs = [
24
+ ...this._glyphs.values()
25
+ ];
26
+ this._glyphs.clear();
27
+ if (!this.isEmpty()) {
28
+ this.clear();
29
+ }
30
+ for (const glyph of glyphs){
31
+ this.ensureGlyph(glyph.glyphIndex);
32
+ }
33
+ };
34
+ }
35
+ get font() {
36
+ return this._font;
37
+ }
38
+ get glyphSize() {
39
+ return this._glyphSize;
40
+ }
41
+ get distanceRange() {
42
+ return this._range;
43
+ }
44
+ getAtlasTexture(index) {
45
+ return super.getAtlasTexture(index);
46
+ }
47
+ ensureGlyph(glyphIndex) {
48
+ const key = String(glyphIndex);
49
+ const cached = this._glyphs.get(key);
50
+ if (cached) {
51
+ return cached;
52
+ }
53
+ const glyph = this._font.getGlyph(glyphIndex);
54
+ if (!glyph) {
55
+ return null;
56
+ }
57
+ if (glyph.contours.length === 0 || glyph.xMax <= glyph.xMin || glyph.yMax <= glyph.yMin) {
58
+ return null;
59
+ }
60
+ try {
61
+ const info = this.createGlyph(glyph);
62
+ this._glyphs.set(key, info);
63
+ return info;
64
+ } catch {
65
+ return null;
66
+ }
67
+ }
68
+ createGlyph(glyph) {
69
+ if (glyph.contours.length === 0 || glyph.xMax <= glyph.xMin || glyph.yMax <= glyph.yMin) {
70
+ throw new Error(`Invalid glyph outline for glyph ${glyph.glyphIndex}`);
71
+ }
72
+ const targetScale = this._glyphSize / this._font.metrics.unitsPerEm;
73
+ const bitmapWidth = Math.max(8, Math.ceil((glyph.xMax - glyph.xMin) * targetScale) + this._padding * 2);
74
+ const bitmapHeight = Math.max(8, Math.ceil((glyph.yMax - glyph.yMin) * targetScale) + this._padding * 2);
75
+ const bitmap = generateMSDF(glyph, {
76
+ width: bitmapWidth,
77
+ height: bitmapHeight,
78
+ range: this._range,
79
+ padding: this._padding
80
+ });
81
+ const atlasBitmap = addBitmapGutter(bitmap, ATLAS_GUTTER);
82
+ const atlasInfo = this.pushBitmap(String(glyph.glyphIndex), new ImageData(atlasBitmap.pixels, atlasBitmap.width, atlasBitmap.height));
83
+ if (!atlasInfo) {
84
+ throw new Error(`MSDF glyph atlas is full for glyph ${glyph.glyphIndex}`);
85
+ }
86
+ const xShift = glyph.leftSideBearing - glyph.xMin;
87
+ const uBase = atlasInfo.uMin;
88
+ const vBase = atlasInfo.vMin;
89
+ const atlasBinWidth = getAtlasBinWidth(this);
90
+ const atlasBinHeight = getAtlasBinHeight(this);
91
+ const uInsetMin = (ATLAS_GUTTER + 0.5) / atlasBinWidth;
92
+ const vInsetMin = (ATLAS_GUTTER + 0.5) / atlasBinHeight;
93
+ const uInsetMax = (ATLAS_GUTTER + bitmap.width - 0.5) / atlasBinWidth;
94
+ const vInsetMax = (ATLAS_GUTTER + bitmap.height - 0.5) / atlasBinHeight;
95
+ return {
96
+ glyphIndex: glyph.glyphIndex,
97
+ advanceWidth: glyph.advanceWidth,
98
+ leftSideBearing: glyph.leftSideBearing,
99
+ atlasIndex: atlasInfo.atlasIndex,
100
+ width: bitmap.width,
101
+ height: bitmap.height,
102
+ uMin: uBase + uInsetMin,
103
+ vMin: vBase + vInsetMin,
104
+ uMax: uBase + uInsetMax,
105
+ vMax: vBase + vInsetMax,
106
+ planeLeft: (-bitmap.translateX + 0.5) / bitmap.scale + xShift,
107
+ planeBottom: -(bitmap.height - bitmap.translateY - 0.5) / bitmap.scale,
108
+ planeRight: (bitmap.width - bitmap.translateX - 0.5) / bitmap.scale + xShift,
109
+ planeTop: (bitmap.translateY - 0.5) / bitmap.scale
110
+ };
111
+ }
112
+ }
113
+ function addBitmapGutter(bitmap, gutter) {
114
+ const width = bitmap.width + gutter * 2;
115
+ const height = bitmap.height + gutter * 2;
116
+ const pixels = new Uint8ClampedArray(width * height * 4);
117
+ for(let y = 0; y < height; y++){
118
+ const sy = clampIndex(y - gutter, bitmap.height);
119
+ for(let x = 0; x < width; x++){
120
+ const sx = clampIndex(x - gutter, bitmap.width);
121
+ const src = (sy * bitmap.width + sx) * 4;
122
+ const dst = (y * width + x) * 4;
123
+ pixels[dst + 0] = bitmap.pixels[src + 0];
124
+ pixels[dst + 1] = bitmap.pixels[src + 1];
125
+ pixels[dst + 2] = bitmap.pixels[src + 2];
126
+ pixels[dst + 3] = bitmap.pixels[src + 3];
127
+ }
128
+ }
129
+ return {
130
+ width,
131
+ height,
132
+ pixels
133
+ };
134
+ }
135
+ function clampIndex(value, size) {
136
+ return value < 0 ? 0 : value >= size ? size - 1 : value;
137
+ }
138
+ function getAtlasBinWidth(atlas) {
139
+ return atlas.binWidth;
140
+ }
141
+ function getAtlasBinHeight(atlas) {
142
+ return atlas.binHeight;
143
+ }
144
+
145
+ export { MSDFGlyphAtlas };
146
+ //# sourceMappingURL=msdf_glyph_atlas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"msdf_glyph_atlas.js","sources":["../../../src/text/runtime/msdf_glyph_atlas.ts"],"sourcesContent":["import { TextureAtlasManager } from '@zephyr3d/device';\r\nimport type { AbstractDevice, Texture2D } from '@zephyr3d/device';\r\nimport type { FontAsset, GlyphData } from '../font';\r\nimport { generateMSDF } from '../msdf';\r\n\r\nconst ATLAS_GUTTER = 1;\r\n\r\nexport type MSDFGlyphInfo = {\r\n glyphIndex: number;\r\n advanceWidth: number;\r\n leftSideBearing: number;\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 planeLeft: number;\r\n planeBottom: number;\r\n planeRight: number;\r\n planeTop: number;\r\n};\r\n\r\n/**\r\n * Runtime dynamic MSDF glyph atlas.\r\n *\r\n * @public\r\n */\r\nexport class MSDFGlyphAtlas extends TextureAtlasManager {\r\n private readonly _font: FontAsset;\r\n private readonly _glyphs: Map<string, MSDFGlyphInfo>;\r\n private readonly _range: number;\r\n private readonly _glyphSize: number;\r\n private readonly _padding: number;\r\n constructor(\r\n device: AbstractDevice,\r\n font: FontAsset,\r\n glyphSize = 64,\r\n atlasSize = 1024,\r\n range = 6,\r\n padding = 2\r\n ) {\r\n super(device, atlasSize, atlasSize, 0, true);\r\n this._font = font;\r\n this._glyphs = new Map();\r\n this._range = range;\r\n this._glyphSize = glyphSize;\r\n this._padding = padding;\r\n this.atlasTextureRestoreHandler = async () => {\r\n const glyphs = [...this._glyphs.values()];\r\n this._glyphs.clear();\r\n if (!this.isEmpty()) {\r\n this.clear();\r\n }\r\n for (const glyph of glyphs) {\r\n this.ensureGlyph(glyph.glyphIndex);\r\n }\r\n };\r\n }\r\n get font() {\r\n return this._font;\r\n }\r\n get glyphSize() {\r\n return this._glyphSize;\r\n }\r\n get distanceRange() {\r\n return this._range;\r\n }\r\n getAtlasTexture(index: number): Texture2D | undefined {\r\n return super.getAtlasTexture(index);\r\n }\r\n ensureGlyph(glyphIndex: number) {\r\n const key = String(glyphIndex);\r\n const cached = this._glyphs.get(key);\r\n if (cached) {\r\n return cached;\r\n }\r\n const glyph = this._font.getGlyph(glyphIndex);\r\n if (!glyph) {\r\n return null;\r\n }\r\n if (glyph.contours.length === 0 || glyph.xMax <= glyph.xMin || glyph.yMax <= glyph.yMin) {\r\n return null;\r\n }\r\n try {\r\n const info = this.createGlyph(glyph);\r\n this._glyphs.set(key, info);\r\n return info;\r\n } catch {\r\n return null;\r\n }\r\n }\r\n private createGlyph(glyph: GlyphData): MSDFGlyphInfo {\r\n if (glyph.contours.length === 0 || glyph.xMax <= glyph.xMin || glyph.yMax <= glyph.yMin) {\r\n throw new Error(`Invalid glyph outline for glyph ${glyph.glyphIndex}`);\r\n }\r\n const targetScale = this._glyphSize / this._font.metrics.unitsPerEm;\r\n const bitmapWidth = Math.max(8, Math.ceil((glyph.xMax - glyph.xMin) * targetScale) + this._padding * 2);\r\n const bitmapHeight = Math.max(8, Math.ceil((glyph.yMax - glyph.yMin) * targetScale) + this._padding * 2);\r\n const bitmap = generateMSDF(glyph, {\r\n width: bitmapWidth,\r\n height: bitmapHeight,\r\n range: this._range,\r\n padding: this._padding\r\n });\r\n const atlasBitmap = addBitmapGutter(bitmap, ATLAS_GUTTER);\r\n const atlasInfo = this.pushBitmap(\r\n String(glyph.glyphIndex),\r\n new ImageData(atlasBitmap.pixels, atlasBitmap.width, atlasBitmap.height)\r\n );\r\n if (!atlasInfo) {\r\n throw new Error(`MSDF glyph atlas is full for glyph ${glyph.glyphIndex}`);\r\n }\r\n const xShift = glyph.leftSideBearing - glyph.xMin;\r\n const uBase = atlasInfo.uMin;\r\n const vBase = atlasInfo.vMin;\r\n const atlasBinWidth = getAtlasBinWidth(this);\r\n const atlasBinHeight = getAtlasBinHeight(this);\r\n const uInsetMin = (ATLAS_GUTTER + 0.5) / atlasBinWidth;\r\n const vInsetMin = (ATLAS_GUTTER + 0.5) / atlasBinHeight;\r\n const uInsetMax = (ATLAS_GUTTER + bitmap.width - 0.5) / atlasBinWidth;\r\n const vInsetMax = (ATLAS_GUTTER + bitmap.height - 0.5) / atlasBinHeight;\r\n return {\r\n glyphIndex: glyph.glyphIndex,\r\n advanceWidth: glyph.advanceWidth,\r\n leftSideBearing: glyph.leftSideBearing,\r\n atlasIndex: atlasInfo.atlasIndex,\r\n width: bitmap.width,\r\n height: bitmap.height,\r\n uMin: uBase + uInsetMin,\r\n vMin: vBase + vInsetMin,\r\n uMax: uBase + uInsetMax,\r\n vMax: vBase + vInsetMax,\r\n planeLeft: (-bitmap.translateX + 0.5) / bitmap.scale + xShift,\r\n planeBottom: -(bitmap.height - bitmap.translateY - 0.5) / bitmap.scale,\r\n planeRight: (bitmap.width - bitmap.translateX - 0.5) / bitmap.scale + xShift,\r\n planeTop: (bitmap.translateY - 0.5) / bitmap.scale\r\n };\r\n }\r\n}\r\n\r\nfunction addBitmapGutter(\r\n bitmap: ReturnType<typeof generateMSDF>,\r\n gutter: number\r\n): { width: number; height: number; pixels: Uint8ClampedArray<ArrayBuffer> } {\r\n if (gutter <= 0) {\r\n return {\r\n width: bitmap.width,\r\n height: bitmap.height,\r\n pixels: new Uint8ClampedArray(bitmap.pixels.buffer.slice(0))\r\n };\r\n }\r\n const width = bitmap.width + gutter * 2;\r\n const height = bitmap.height + gutter * 2;\r\n const pixels = new Uint8ClampedArray(width * height * 4);\r\n for (let y = 0; y < height; y++) {\r\n const sy = clampIndex(y - gutter, bitmap.height);\r\n for (let x = 0; x < width; x++) {\r\n const sx = clampIndex(x - gutter, bitmap.width);\r\n const src = (sy * bitmap.width + sx) * 4;\r\n const dst = (y * width + x) * 4;\r\n pixels[dst + 0] = bitmap.pixels[src + 0];\r\n pixels[dst + 1] = bitmap.pixels[src + 1];\r\n pixels[dst + 2] = bitmap.pixels[src + 2];\r\n pixels[dst + 3] = bitmap.pixels[src + 3];\r\n }\r\n }\r\n return { width, height, pixels };\r\n}\r\n\r\nfunction clampIndex(value: number, size: number) {\r\n return value < 0 ? 0 : value >= size ? size - 1 : value;\r\n}\r\n\r\nfunction getAtlasBinWidth(atlas: MSDFGlyphAtlas) {\r\n return (atlas as MSDFGlyphAtlas & { binWidth: number }).binWidth;\r\n}\r\n\r\nfunction getAtlasBinHeight(atlas: MSDFGlyphAtlas) {\r\n return (atlas as MSDFGlyphAtlas & { binHeight: number }).binHeight;\r\n}\r\n"],"names":["ATLAS_GUTTER","MSDFGlyphAtlas","TextureAtlasManager","_font","_glyphs","_range","_glyphSize","_padding","device","font","glyphSize","atlasSize","range","padding","Map","atlasTextureRestoreHandler","glyphs","values","clear","isEmpty","glyph","ensureGlyph","glyphIndex","distanceRange","getAtlasTexture","index","key","String","cached","get","getGlyph","contours","length","xMax","xMin","yMax","yMin","info","createGlyph","set","Error","targetScale","metrics","unitsPerEm","bitmapWidth","Math","max","ceil","bitmapHeight","bitmap","generateMSDF","width","height","atlasBitmap","addBitmapGutter","atlasInfo","pushBitmap","ImageData","pixels","xShift","leftSideBearing","uBase","uMin","vBase","vMin","atlasBinWidth","getAtlasBinWidth","atlasBinHeight","getAtlasBinHeight","uInsetMin","vInsetMin","uInsetMax","vInsetMax","advanceWidth","atlasIndex","uMax","vMax","planeLeft","translateX","scale","planeBottom","translateY","planeRight","planeTop","gutter","Uint8ClampedArray","y","sy","clampIndex","x","sx","src","dst","value","size","atlas","binWidth","binHeight"],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ import { getDevice } from '../../app/api.js';
2
+ import { MSDFGlyphAtlas } from './msdf_glyph_atlas.js';
3
+
4
+ const DEFAULT_DISTANCE_RANGE = 8;
5
+ const DEFAULT_PADDING = 6;
6
+ class MSDFTextAtlasManager {
7
+ _atlases;
8
+ constructor(){
9
+ this._atlases = new Map();
10
+ }
11
+ getAtlas(font) {
12
+ let atlas = this._atlases.get(font);
13
+ if (!atlas) {
14
+ atlas = new MSDFGlyphAtlas(getDevice(), font, font.msdfGlyphSize, font.msdfAtlasPageSize, DEFAULT_DISTANCE_RANGE, DEFAULT_PADDING);
15
+ this._atlases.set(font, atlas);
16
+ }
17
+ return atlas;
18
+ }
19
+ configureAtlas(font, glyphSize, atlasSize, distanceRange = DEFAULT_DISTANCE_RANGE, padding = DEFAULT_PADDING) {
20
+ let atlas = this._atlases.get(font);
21
+ if (atlas) {
22
+ atlas.clear();
23
+ this._atlases.delete(font);
24
+ }
25
+ atlas = new MSDFGlyphAtlas(getDevice(), font, glyphSize, atlasSize, distanceRange, padding);
26
+ this._atlases.set(font, atlas);
27
+ return atlas;
28
+ }
29
+ releaseAtlas(font) {
30
+ const atlas = this._atlases.get(font);
31
+ if (atlas) {
32
+ atlas.clear();
33
+ this._atlases.delete(font);
34
+ return true;
35
+ }
36
+ return false;
37
+ }
38
+ clear() {
39
+ for (const atlas of this._atlases.values()){
40
+ atlas.clear();
41
+ }
42
+ this._atlases.clear();
43
+ }
44
+ }
45
+
46
+ export { MSDFTextAtlasManager };
47
+ //# sourceMappingURL=msdf_text_atlas_manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"msdf_text_atlas_manager.js","sources":["../../../src/text/runtime/msdf_text_atlas_manager.ts"],"sourcesContent":["import { getDevice } from '../../app/api';\r\nimport type { FontAsset } from '../font';\r\nimport { MSDFGlyphAtlas } from './msdf_glyph_atlas';\r\n\r\nconst DEFAULT_DISTANCE_RANGE = 8;\r\nconst DEFAULT_PADDING = 6;\r\n\r\nexport class MSDFTextAtlasManager {\r\n private readonly _atlases: Map<FontAsset, MSDFGlyphAtlas>;\r\n constructor() {\r\n this._atlases = new Map();\r\n }\r\n getAtlas(font: FontAsset) {\r\n let atlas = this._atlases.get(font);\r\n if (!atlas) {\r\n atlas = new MSDFGlyphAtlas(\r\n getDevice(),\r\n font,\r\n font.msdfGlyphSize,\r\n font.msdfAtlasPageSize,\r\n DEFAULT_DISTANCE_RANGE,\r\n DEFAULT_PADDING\r\n );\r\n this._atlases.set(font, atlas);\r\n }\r\n return atlas;\r\n }\r\n configureAtlas(\r\n font: FontAsset,\r\n glyphSize: number,\r\n atlasSize: number,\r\n distanceRange = DEFAULT_DISTANCE_RANGE,\r\n padding = DEFAULT_PADDING\r\n ) {\r\n let atlas = this._atlases.get(font);\r\n if (atlas) {\r\n atlas.clear();\r\n this._atlases.delete(font);\r\n }\r\n atlas = new MSDFGlyphAtlas(getDevice(), font, glyphSize, atlasSize, distanceRange, padding);\r\n this._atlases.set(font, atlas);\r\n return atlas;\r\n }\r\n releaseAtlas(font: FontAsset) {\r\n const atlas = this._atlases.get(font);\r\n if (atlas) {\r\n atlas.clear();\r\n this._atlases.delete(font);\r\n return true;\r\n }\r\n return false;\r\n }\r\n clear() {\r\n for (const atlas of this._atlases.values()) {\r\n atlas.clear();\r\n }\r\n this._atlases.clear();\r\n }\r\n}\r\n"],"names":["DEFAULT_DISTANCE_RANGE","DEFAULT_PADDING","MSDFTextAtlasManager","_atlases","Map","getAtlas","font","atlas","get","MSDFGlyphAtlas","getDevice","msdfGlyphSize","msdfAtlasPageSize","set","configureAtlas","glyphSize","atlasSize","distanceRange","padding","clear","delete","releaseAtlas","values"],"mappings":";;;AAIA,MAAMA,sBAAyB,GAAA,CAAA;AAC/B,MAAMC,eAAkB,GAAA,CAAA;AAEjB,MAAMC,oBAAAA,CAAAA;IACMC,QAAyC;IAC1D,WAAc,EAAA;QACZ,IAAI,CAACA,QAAQ,GAAG,IAAIC,GAAAA,EAAAA;AACtB;AACAC,IAAAA,QAAAA,CAASC,IAAe,EAAE;AACxB,QAAA,IAAIC,QAAQ,IAAI,CAACJ,QAAQ,CAACK,GAAG,CAACF,IAAAA,CAAAA;AAC9B,QAAA,IAAI,CAACC,KAAO,EAAA;YACVA,KAAQ,GAAA,IAAIE,cACVC,CAAAA,SAAAA,EAAAA,EACAJ,IACAA,EAAAA,IAAAA,CAAKK,aAAa,EAClBL,IAAAA,CAAKM,iBAAiB,EACtBZ,sBACAC,EAAAA,eAAAA,CAAAA;AAEF,YAAA,IAAI,CAACE,QAAQ,CAACU,GAAG,CAACP,IAAMC,EAAAA,KAAAA,CAAAA;AAC1B;QACA,OAAOA,KAAAA;AACT;IACAO,cACER,CAAAA,IAAe,EACfS,SAAiB,EACjBC,SAAiB,EACjBC,aAAAA,GAAgBjB,sBAAsB,EACtCkB,OAAUjB,GAAAA,eAAe,EACzB;AACA,QAAA,IAAIM,QAAQ,IAAI,CAACJ,QAAQ,CAACK,GAAG,CAACF,IAAAA,CAAAA;AAC9B,QAAA,IAAIC,KAAO,EAAA;AACTA,YAAAA,KAAAA,CAAMY,KAAK,EAAA;AACX,YAAA,IAAI,CAAChB,QAAQ,CAACiB,MAAM,CAACd,IAAAA,CAAAA;AACvB;AACAC,QAAAA,KAAAA,GAAQ,IAAIE,cAAeC,CAAAA,SAAAA,EAAAA,EAAaJ,IAAMS,EAAAA,SAAAA,EAAWC,WAAWC,aAAeC,EAAAA,OAAAA,CAAAA;AACnF,QAAA,IAAI,CAACf,QAAQ,CAACU,GAAG,CAACP,IAAMC,EAAAA,KAAAA,CAAAA;QACxB,OAAOA,KAAAA;AACT;AACAc,IAAAA,YAAAA,CAAaf,IAAe,EAAE;AAC5B,QAAA,MAAMC,QAAQ,IAAI,CAACJ,QAAQ,CAACK,GAAG,CAACF,IAAAA,CAAAA;AAChC,QAAA,IAAIC,KAAO,EAAA;AACTA,YAAAA,KAAAA,CAAMY,KAAK,EAAA;AACX,YAAA,IAAI,CAAChB,QAAQ,CAACiB,MAAM,CAACd,IAAAA,CAAAA;YACrB,OAAO,IAAA;AACT;QACA,OAAO,KAAA;AACT;IACAa,KAAQ,GAAA;AACN,QAAA,KAAK,MAAMZ,KAAS,IAAA,IAAI,CAACJ,QAAQ,CAACmB,MAAM,EAAI,CAAA;AAC1Cf,YAAAA,KAAAA,CAAMY,KAAK,EAAA;AACb;QACA,IAAI,CAAChB,QAAQ,CAACgB,KAAK,EAAA;AACrB;AACF;;;;"}
@@ -0,0 +1,96 @@
1
+ import { splitStringByGraphemes } from '@zephyr3d/base';
2
+
3
+ function layoutText(atlas, font, text, fontSize, maxWidth = 0) {
4
+ const scale = fontSize / font.metrics.unitsPerEm;
5
+ const lineHeight = (font.metrics.ascent - font.metrics.descent + font.metrics.lineGap) * scale;
6
+ const glyphs = [];
7
+ const lines = [];
8
+ let x = 0;
9
+ let y = 0;
10
+ let maxLineWidth = 0;
11
+ let prevGlyphIndex = 0;
12
+ let lineIndex = 0;
13
+ let lineStartGlyph = 0;
14
+ const chars = splitStringByGraphemes(text);
15
+ for (const ch of chars){
16
+ if (ch === '\n') {
17
+ maxLineWidth = Math.max(maxLineWidth, x);
18
+ lines.push({
19
+ width: x,
20
+ glyphStart: lineStartGlyph,
21
+ glyphEnd: glyphs.length
22
+ });
23
+ x = 0;
24
+ y += lineHeight;
25
+ prevGlyphIndex = 0;
26
+ lineIndex++;
27
+ lineStartGlyph = glyphs.length;
28
+ continue;
29
+ }
30
+ const codePoint = ch.codePointAt(0);
31
+ if (typeof codePoint !== 'number') {
32
+ continue;
33
+ }
34
+ const glyphIndex = font.getGlyphIndex(codePoint);
35
+ if (glyphIndex === 0) {
36
+ prevGlyphIndex = 0;
37
+ continue;
38
+ }
39
+ const glyph = font.getGlyph(glyphIndex);
40
+ if (!glyph) {
41
+ prevGlyphIndex = 0;
42
+ continue;
43
+ }
44
+ const atlasGlyph = atlas.ensureGlyph(glyphIndex);
45
+ const pairAdjustment = prevGlyphIndex ? font.getPairAdjustment(prevGlyphIndex, glyphIndex) : null;
46
+ const kerning = prevGlyphIndex ? font.getKerning(prevGlyphIndex, glyphIndex) * scale : 0;
47
+ const xOffset = pairAdjustment ? pairAdjustment.secondXPlacement * scale : 0;
48
+ const advance = glyph.advanceWidth * scale;
49
+ if (maxWidth > 0 && x > 0 && x + kerning + advance > maxWidth) {
50
+ maxLineWidth = Math.max(maxLineWidth, x);
51
+ lines.push({
52
+ width: x,
53
+ glyphStart: lineStartGlyph,
54
+ glyphEnd: glyphs.length
55
+ });
56
+ x = 0;
57
+ y += lineHeight;
58
+ prevGlyphIndex = 0;
59
+ lineIndex++;
60
+ lineStartGlyph = glyphs.length;
61
+ } else {
62
+ x += kerning;
63
+ }
64
+ if (atlasGlyph) {
65
+ glyphs.push({
66
+ char: ch,
67
+ glyphIndex,
68
+ atlasGlyph,
69
+ lineIndex,
70
+ x,
71
+ y,
72
+ xOffset,
73
+ advance
74
+ });
75
+ }
76
+ x += advance;
77
+ prevGlyphIndex = glyphIndex;
78
+ }
79
+ maxLineWidth = Math.max(maxLineWidth, x);
80
+ lines.push({
81
+ width: x,
82
+ glyphStart: lineStartGlyph,
83
+ glyphEnd: glyphs.length
84
+ });
85
+ return {
86
+ glyphs,
87
+ width: maxLineWidth,
88
+ boxWidth: maxWidth > 0 ? Math.max(maxLineWidth, maxWidth) : maxLineWidth,
89
+ height: Math.max(lineHeight, y + lineHeight),
90
+ lineHeight,
91
+ lines
92
+ };
93
+ }
94
+
95
+ export { layoutText };
96
+ //# sourceMappingURL=text_layout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text_layout.js","sources":["../../../src/text/runtime/text_layout.ts"],"sourcesContent":["import { splitStringByGraphemes } from '@zephyr3d/base';\r\nimport type { FontAsset } from '../font';\r\nimport type { MSDFGlyphAtlas, MSDFGlyphInfo } from './msdf_glyph_atlas';\r\n\r\nexport type TextAlign = 'left' | 'center' | 'right';\r\n\r\nexport type LayoutGlyph = {\r\n char: string;\r\n glyphIndex: number;\r\n atlasGlyph: MSDFGlyphInfo;\r\n lineIndex: number;\r\n x: number;\r\n y: number;\r\n xOffset: number;\r\n advance: number;\r\n};\r\n\r\nexport type TextLayoutLine = {\r\n width: number;\r\n glyphStart: number;\r\n glyphEnd: number;\r\n};\r\n\r\nexport type TextLayoutResult = {\r\n glyphs: LayoutGlyph[];\r\n width: number;\r\n boxWidth: number;\r\n height: number;\r\n lineHeight: number;\r\n lines: TextLayoutLine[];\r\n};\r\n\r\nexport function layoutText(\r\n atlas: MSDFGlyphAtlas,\r\n font: FontAsset,\r\n text: string,\r\n fontSize: number,\r\n maxWidth = 0\r\n) {\r\n const scale = fontSize / font.metrics.unitsPerEm;\r\n const lineHeight = (font.metrics.ascent - font.metrics.descent + font.metrics.lineGap) * scale;\r\n const glyphs: LayoutGlyph[] = [];\r\n const lines: TextLayoutLine[] = [];\r\n let x = 0;\r\n let y = 0;\r\n let maxLineWidth = 0;\r\n let prevGlyphIndex = 0;\r\n let lineIndex = 0;\r\n let lineStartGlyph = 0;\r\n const chars = splitStringByGraphemes(text);\r\n for (const ch of chars) {\r\n if (ch === '\\n') {\r\n maxLineWidth = Math.max(maxLineWidth, x);\r\n lines.push({\r\n width: x,\r\n glyphStart: lineStartGlyph,\r\n glyphEnd: glyphs.length\r\n });\r\n x = 0;\r\n y += lineHeight;\r\n prevGlyphIndex = 0;\r\n lineIndex++;\r\n lineStartGlyph = glyphs.length;\r\n continue;\r\n }\r\n const codePoint = ch.codePointAt(0);\r\n if (typeof codePoint !== 'number') {\r\n continue;\r\n }\r\n const glyphIndex = font.getGlyphIndex(codePoint);\r\n if (glyphIndex === 0) {\r\n prevGlyphIndex = 0;\r\n continue;\r\n }\r\n const glyph = font.getGlyph(glyphIndex);\r\n if (!glyph) {\r\n prevGlyphIndex = 0;\r\n continue;\r\n }\r\n const atlasGlyph = atlas.ensureGlyph(glyphIndex);\r\n const pairAdjustment = prevGlyphIndex ? font.getPairAdjustment(prevGlyphIndex, glyphIndex) : null;\r\n const kerning = prevGlyphIndex ? font.getKerning(prevGlyphIndex, glyphIndex) * scale : 0;\r\n const xOffset = pairAdjustment ? pairAdjustment.secondXPlacement * scale : 0;\r\n const advance = glyph.advanceWidth * scale;\r\n if (maxWidth > 0 && x > 0 && x + kerning + advance > maxWidth) {\r\n maxLineWidth = Math.max(maxLineWidth, x);\r\n lines.push({\r\n width: x,\r\n glyphStart: lineStartGlyph,\r\n glyphEnd: glyphs.length\r\n });\r\n x = 0;\r\n y += lineHeight;\r\n prevGlyphIndex = 0;\r\n lineIndex++;\r\n lineStartGlyph = glyphs.length;\r\n } else {\r\n x += kerning;\r\n }\r\n if (atlasGlyph) {\r\n glyphs.push({\r\n char: ch,\r\n glyphIndex,\r\n atlasGlyph,\r\n lineIndex,\r\n x,\r\n y,\r\n xOffset,\r\n advance\r\n });\r\n }\r\n x += advance;\r\n prevGlyphIndex = glyphIndex;\r\n }\r\n maxLineWidth = Math.max(maxLineWidth, x);\r\n lines.push({\r\n width: x,\r\n glyphStart: lineStartGlyph,\r\n glyphEnd: glyphs.length\r\n });\r\n return {\r\n glyphs,\r\n width: maxLineWidth,\r\n boxWidth: maxWidth > 0 ? Math.max(maxLineWidth, maxWidth) : maxLineWidth,\r\n height: Math.max(lineHeight, y + lineHeight),\r\n lineHeight,\r\n lines\r\n } satisfies TextLayoutResult;\r\n}\r\n"],"names":["layoutText","atlas","font","text","fontSize","maxWidth","scale","metrics","unitsPerEm","lineHeight","ascent","descent","lineGap","glyphs","lines","x","y","maxLineWidth","prevGlyphIndex","lineIndex","lineStartGlyph","chars","splitStringByGraphemes","ch","Math","max","push","width","glyphStart","glyphEnd","length","codePoint","codePointAt","glyphIndex","getGlyphIndex","glyph","getGlyph","atlasGlyph","ensureGlyph","pairAdjustment","getPairAdjustment","kerning","getKerning","xOffset","secondXPlacement","advance","advanceWidth","char","boxWidth","height"],"mappings":"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"}