@solidtv/renderer 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/NOTICE +7 -0
- package/README.md +137 -0
- package/dist/exports/canvas-shaders.d.ts +10 -0
- package/dist/exports/canvas-shaders.js +11 -0
- package/dist/exports/canvas-shaders.js.map +1 -0
- package/dist/exports/canvas.d.ts +26 -0
- package/dist/exports/canvas.js +27 -0
- package/dist/exports/canvas.js.map +1 -0
- package/dist/exports/index.d.ts +50 -0
- package/dist/exports/index.js +40 -0
- package/dist/exports/index.js.map +1 -0
- package/dist/exports/inspector.d.ts +4 -0
- package/dist/exports/inspector.js +5 -0
- package/dist/exports/inspector.js.map +1 -0
- package/dist/exports/utils.d.ts +27 -0
- package/dist/exports/utils.js +28 -0
- package/dist/exports/utils.js.map +1 -0
- package/dist/exports/webgl-shaders.d.ts +11 -0
- package/dist/exports/webgl-shaders.js +12 -0
- package/dist/exports/webgl-shaders.js.map +1 -0
- package/dist/exports/webgl.d.ts +28 -0
- package/dist/exports/webgl.js +29 -0
- package/dist/exports/webgl.js.map +1 -0
- package/dist/src/common/CommonTypes.d.ts +110 -0
- package/dist/src/common/CommonTypes.js +2 -0
- package/dist/src/common/CommonTypes.js.map +1 -0
- package/dist/src/common/EventEmitter.d.ts +12 -0
- package/dist/src/common/EventEmitter.js +48 -0
- package/dist/src/common/EventEmitter.js.map +1 -0
- package/dist/src/common/IAnimationController.d.ts +58 -0
- package/dist/src/common/IAnimationController.js +2 -0
- package/dist/src/common/IAnimationController.js.map +1 -0
- package/dist/src/common/IEventEmitter.d.ts +8 -0
- package/dist/src/common/IEventEmitter.js +2 -0
- package/dist/src/common/IEventEmitter.js.map +1 -0
- package/dist/src/core/Autosizer.d.ts +35 -0
- package/dist/src/core/Autosizer.js +178 -0
- package/dist/src/core/Autosizer.js.map +1 -0
- package/dist/src/core/CoreNode.d.ts +908 -0
- package/dist/src/core/CoreNode.js +1837 -0
- package/dist/src/core/CoreNode.js.map +1 -0
- package/dist/src/core/CoreShaderManager.d.ts +38 -0
- package/dist/src/core/CoreShaderManager.js +123 -0
- package/dist/src/core/CoreShaderManager.js.map +1 -0
- package/dist/src/core/CoreTextNode.d.ts +91 -0
- package/dist/src/core/CoreTextNode.js +440 -0
- package/dist/src/core/CoreTextNode.js.map +1 -0
- package/dist/src/core/CoreTextureManager.d.ts +264 -0
- package/dist/src/core/CoreTextureManager.js +318 -0
- package/dist/src/core/CoreTextureManager.js.map +1 -0
- package/dist/src/core/Stage.d.ts +238 -0
- package/dist/src/core/Stage.js +804 -0
- package/dist/src/core/Stage.js.map +1 -0
- package/dist/src/core/TextureError.d.ts +11 -0
- package/dist/src/core/TextureError.js +37 -0
- package/dist/src/core/TextureError.js.map +1 -0
- package/dist/src/core/TextureMemoryManager.d.ts +150 -0
- package/dist/src/core/TextureMemoryManager.js +239 -0
- package/dist/src/core/TextureMemoryManager.js.map +1 -0
- package/dist/src/core/animations/AnimationManager.d.ts +33 -0
- package/dist/src/core/animations/AnimationManager.js +137 -0
- package/dist/src/core/animations/AnimationManager.js.map +1 -0
- package/dist/src/core/animations/CoreAnimation.d.ts +12 -0
- package/dist/src/core/animations/CoreAnimation.js +107 -0
- package/dist/src/core/animations/CoreAnimation.js.map +1 -0
- package/dist/src/core/lib/ContextSpy.d.ts +12 -0
- package/dist/src/core/lib/ContextSpy.js +20 -0
- package/dist/src/core/lib/ContextSpy.js.map +1 -0
- package/dist/src/core/lib/ImageWorker.d.ts +16 -0
- package/dist/src/core/lib/ImageWorker.js +202 -0
- package/dist/src/core/lib/ImageWorker.js.map +1 -0
- package/dist/src/core/lib/Matrix3d.d.ts +74 -0
- package/dist/src/core/lib/Matrix3d.js +218 -0
- package/dist/src/core/lib/Matrix3d.js.map +1 -0
- package/dist/src/core/lib/RenderCoords.d.ts +12 -0
- package/dist/src/core/lib/RenderCoords.js +35 -0
- package/dist/src/core/lib/RenderCoords.js.map +1 -0
- package/dist/src/core/lib/WebGlContextWrapper.d.ts +782 -0
- package/dist/src/core/lib/WebGlContextWrapper.js +1143 -0
- package/dist/src/core/lib/WebGlContextWrapper.js.map +1 -0
- package/dist/src/core/lib/collectionUtils.d.ts +5 -0
- package/dist/src/core/lib/collectionUtils.js +82 -0
- package/dist/src/core/lib/collectionUtils.js.map +1 -0
- package/dist/src/core/lib/colorCache.d.ts +1 -0
- package/dist/src/core/lib/colorCache.js +19 -0
- package/dist/src/core/lib/colorCache.js.map +1 -0
- package/dist/src/core/lib/colorParser.d.ts +21 -0
- package/dist/src/core/lib/colorParser.js +54 -0
- package/dist/src/core/lib/colorParser.js.map +1 -0
- package/dist/src/core/lib/textureCompression.d.ts +28 -0
- package/dist/src/core/lib/textureCompression.js +363 -0
- package/dist/src/core/lib/textureCompression.js.map +1 -0
- package/dist/src/core/lib/textureSvg.d.ts +16 -0
- package/dist/src/core/lib/textureSvg.js +45 -0
- package/dist/src/core/lib/textureSvg.js.map +1 -0
- package/dist/src/core/lib/utils.d.ts +66 -0
- package/dist/src/core/lib/utils.js +268 -0
- package/dist/src/core/lib/utils.js.map +1 -0
- package/dist/src/core/lib/validateImageBitmap.d.ts +7 -0
- package/dist/src/core/lib/validateImageBitmap.js +68 -0
- package/dist/src/core/lib/validateImageBitmap.js.map +1 -0
- package/dist/src/core/platforms/Platform.d.ts +42 -0
- package/dist/src/core/platforms/Platform.js +4 -0
- package/dist/src/core/platforms/Platform.js.map +1 -0
- package/dist/src/core/platforms/web/WebPlatform.d.ts +10 -0
- package/dist/src/core/platforms/web/WebPlatform.js +90 -0
- package/dist/src/core/platforms/web/WebPlatform.js.map +1 -0
- package/dist/src/core/renderers/CoreContextTexture.d.ts +13 -0
- package/dist/src/core/renderers/CoreContextTexture.js +16 -0
- package/dist/src/core/renderers/CoreContextTexture.js.map +1 -0
- package/dist/src/core/renderers/CoreRenderOp.d.ts +3 -0
- package/dist/src/core/renderers/CoreRenderOp.js +3 -0
- package/dist/src/core/renderers/CoreRenderOp.js.map +1 -0
- package/dist/src/core/renderers/CoreRenderer.d.ts +81 -0
- package/dist/src/core/renderers/CoreRenderer.js +14 -0
- package/dist/src/core/renderers/CoreRenderer.js.map +1 -0
- package/dist/src/core/renderers/CoreShaderNode.d.ts +69 -0
- package/dist/src/core/renderers/CoreShaderNode.js +130 -0
- package/dist/src/core/renderers/CoreShaderNode.js.map +1 -0
- package/dist/src/core/renderers/CoreShaderProgram.d.ts +4 -0
- package/dist/src/core/renderers/CoreShaderProgram.js +2 -0
- package/dist/src/core/renderers/CoreShaderProgram.js.map +1 -0
- package/dist/src/core/renderers/canvas/CanvasRenderer.d.ts +36 -0
- package/dist/src/core/renderers/canvas/CanvasRenderer.js +221 -0
- package/dist/src/core/renderers/canvas/CanvasRenderer.js.map +1 -0
- package/dist/src/core/renderers/canvas/CanvasShaderNode.d.ts +21 -0
- package/dist/src/core/renderers/canvas/CanvasShaderNode.js +42 -0
- package/dist/src/core/renderers/canvas/CanvasShaderNode.js.map +1 -0
- package/dist/src/core/renderers/canvas/CanvasTexture.d.ts +17 -0
- package/dist/src/core/renderers/canvas/CanvasTexture.js +110 -0
- package/dist/src/core/renderers/canvas/CanvasTexture.js.map +1 -0
- package/dist/src/core/renderers/webgl/SdfRenderOp.d.ts +41 -0
- package/dist/src/core/renderers/webgl/SdfRenderOp.js +88 -0
- package/dist/src/core/renderers/webgl/SdfRenderOp.js.map +1 -0
- package/dist/src/core/renderers/webgl/WebGlCtxRenderTexture.d.ts +14 -0
- package/dist/src/core/renderers/webgl/WebGlCtxRenderTexture.js +45 -0
- package/dist/src/core/renderers/webgl/WebGlCtxRenderTexture.js.map +1 -0
- package/dist/src/core/renderers/webgl/WebGlCtxSubTexture.d.ts +22 -0
- package/dist/src/core/renderers/webgl/WebGlCtxSubTexture.js +49 -0
- package/dist/src/core/renderers/webgl/WebGlCtxSubTexture.js.map +1 -0
- package/dist/src/core/renderers/webgl/WebGlCtxTexture.d.ts +67 -0
- package/dist/src/core/renderers/webgl/WebGlCtxTexture.js +259 -0
- package/dist/src/core/renderers/webgl/WebGlCtxTexture.js.map +1 -0
- package/dist/src/core/renderers/webgl/WebGlRenderer.d.ts +221 -0
- package/dist/src/core/renderers/webgl/WebGlRenderer.js +1015 -0
- package/dist/src/core/renderers/webgl/WebGlRenderer.js.map +1 -0
- package/dist/src/core/renderers/webgl/WebGlShaderNode.d.ts +213 -0
- package/dist/src/core/renderers/webgl/WebGlShaderNode.js +331 -0
- package/dist/src/core/renderers/webgl/WebGlShaderNode.js.map +1 -0
- package/dist/src/core/renderers/webgl/WebGlShaderProgram.d.ts +37 -0
- package/dist/src/core/renderers/webgl/WebGlShaderProgram.js +240 -0
- package/dist/src/core/renderers/webgl/WebGlShaderProgram.js.map +1 -0
- package/dist/src/core/renderers/webgl/internal/BufferCollection.d.ts +28 -0
- package/dist/src/core/renderers/webgl/internal/BufferCollection.js +39 -0
- package/dist/src/core/renderers/webgl/internal/BufferCollection.js.map +1 -0
- package/dist/src/core/renderers/webgl/internal/RendererUtils.d.ts +55 -0
- package/dist/src/core/renderers/webgl/internal/RendererUtils.js +88 -0
- package/dist/src/core/renderers/webgl/internal/RendererUtils.js.map +1 -0
- package/dist/src/core/renderers/webgl/internal/ShaderUtils.d.ts +74 -0
- package/dist/src/core/renderers/webgl/internal/ShaderUtils.js +83 -0
- package/dist/src/core/renderers/webgl/internal/ShaderUtils.js.map +1 -0
- package/dist/src/core/renderers/webgl/internal/WebGlUtils.d.ts +10 -0
- package/dist/src/core/renderers/webgl/internal/WebGlUtils.js +13 -0
- package/dist/src/core/renderers/webgl/internal/WebGlUtils.js.map +1 -0
- package/dist/src/core/shaders/canvas/Border.d.ts +15 -0
- package/dist/src/core/shaders/canvas/Border.js +83 -0
- package/dist/src/core/shaders/canvas/Border.js.map +1 -0
- package/dist/src/core/shaders/canvas/HolePunch.d.ts +7 -0
- package/dist/src/core/shaders/canvas/HolePunch.js +22 -0
- package/dist/src/core/shaders/canvas/HolePunch.js.map +1 -0
- package/dist/src/core/shaders/canvas/LinearGradient.d.ts +10 -0
- package/dist/src/core/shaders/canvas/LinearGradient.js +32 -0
- package/dist/src/core/shaders/canvas/LinearGradient.js.map +1 -0
- package/dist/src/core/shaders/canvas/RadialGradient.d.ts +11 -0
- package/dist/src/core/shaders/canvas/RadialGradient.js +54 -0
- package/dist/src/core/shaders/canvas/RadialGradient.js.map +1 -0
- package/dist/src/core/shaders/canvas/Rounded.d.ts +7 -0
- package/dist/src/core/shaders/canvas/Rounded.js +17 -0
- package/dist/src/core/shaders/canvas/Rounded.js.map +1 -0
- package/dist/src/core/shaders/canvas/RoundedWithBorder.d.ts +10 -0
- package/dist/src/core/shaders/canvas/RoundedWithBorder.js +57 -0
- package/dist/src/core/shaders/canvas/RoundedWithBorder.js.map +1 -0
- package/dist/src/core/shaders/canvas/RoundedWithBorderAndShadow.d.ts +7 -0
- package/dist/src/core/shaders/canvas/RoundedWithBorderAndShadow.js +61 -0
- package/dist/src/core/shaders/canvas/RoundedWithBorderAndShadow.js.map +1 -0
- package/dist/src/core/shaders/canvas/RoundedWithShadow.d.ts +7 -0
- package/dist/src/core/shaders/canvas/RoundedWithShadow.js +26 -0
- package/dist/src/core/shaders/canvas/RoundedWithShadow.js.map +1 -0
- package/dist/src/core/shaders/canvas/Shadow.d.ts +8 -0
- package/dist/src/core/shaders/canvas/Shadow.js +15 -0
- package/dist/src/core/shaders/canvas/Shadow.js.map +1 -0
- package/dist/src/core/shaders/canvas/utils/render.d.ts +5 -0
- package/dist/src/core/shaders/canvas/utils/render.js +81 -0
- package/dist/src/core/shaders/canvas/utils/render.js.map +1 -0
- package/dist/src/core/shaders/templates/BorderTemplate.d.ts +47 -0
- package/dist/src/core/shaders/templates/BorderTemplate.js +77 -0
- package/dist/src/core/shaders/templates/BorderTemplate.js.map +1 -0
- package/dist/src/core/shaders/templates/HolePunchTemplate.d.ts +46 -0
- package/dist/src/core/shaders/templates/HolePunchTemplate.js +19 -0
- package/dist/src/core/shaders/templates/HolePunchTemplate.js.map +1 -0
- package/dist/src/core/shaders/templates/LinearGradientTemplate.d.ts +23 -0
- package/dist/src/core/shaders/templates/LinearGradientTemplate.js +31 -0
- package/dist/src/core/shaders/templates/LinearGradientTemplate.js.map +1 -0
- package/dist/src/core/shaders/templates/RadialGradientTemplate.d.ts +33 -0
- package/dist/src/core/shaders/templates/RadialGradientTemplate.js +33 -0
- package/dist/src/core/shaders/templates/RadialGradientTemplate.js.map +1 -0
- package/dist/src/core/shaders/templates/RoundedTemplate.d.ts +29 -0
- package/dist/src/core/shaders/templates/RoundedTemplate.js +51 -0
- package/dist/src/core/shaders/templates/RoundedTemplate.js.map +1 -0
- package/dist/src/core/shaders/templates/RoundedWithBorderAndShadowTemplate.d.ts +7 -0
- package/dist/src/core/shaders/templates/RoundedWithBorderAndShadowTemplate.js +8 -0
- package/dist/src/core/shaders/templates/RoundedWithBorderAndShadowTemplate.js.map +1 -0
- package/dist/src/core/shaders/templates/RoundedWithBorderTemplate.d.ts +8 -0
- package/dist/src/core/shaders/templates/RoundedWithBorderTemplate.js +9 -0
- package/dist/src/core/shaders/templates/RoundedWithBorderTemplate.js.map +1 -0
- package/dist/src/core/shaders/templates/RoundedWithShadowTemplate.d.ts +6 -0
- package/dist/src/core/shaders/templates/RoundedWithShadowTemplate.js +7 -0
- package/dist/src/core/shaders/templates/RoundedWithShadowTemplate.js.map +1 -0
- package/dist/src/core/shaders/templates/ShadowTemplate.d.ts +34 -0
- package/dist/src/core/shaders/templates/ShadowTemplate.js +50 -0
- package/dist/src/core/shaders/templates/ShadowTemplate.js.map +1 -0
- package/dist/src/core/shaders/utils.d.ts +5 -0
- package/dist/src/core/shaders/utils.js +25 -0
- package/dist/src/core/shaders/utils.js.map +1 -0
- package/dist/src/core/shaders/webgl/Border.d.ts +3 -0
- package/dist/src/core/shaders/webgl/Border.js +153 -0
- package/dist/src/core/shaders/webgl/Border.js.map +1 -0
- package/dist/src/core/shaders/webgl/Default.d.ts +2 -0
- package/dist/src/core/shaders/webgl/Default.js +51 -0
- package/dist/src/core/shaders/webgl/Default.js.map +1 -0
- package/dist/src/core/shaders/webgl/HolePunch.d.ts +3 -0
- package/dist/src/core/shaders/webgl/HolePunch.js +49 -0
- package/dist/src/core/shaders/webgl/HolePunch.js.map +1 -0
- package/dist/src/core/shaders/webgl/LinearGradient.d.ts +3 -0
- package/dist/src/core/shaders/webgl/LinearGradient.js +114 -0
- package/dist/src/core/shaders/webgl/LinearGradient.js.map +1 -0
- package/dist/src/core/shaders/webgl/RadialGradient.d.ts +3 -0
- package/dist/src/core/shaders/webgl/RadialGradient.js +81 -0
- package/dist/src/core/shaders/webgl/RadialGradient.js.map +1 -0
- package/dist/src/core/shaders/webgl/Rounded.d.ts +7 -0
- package/dist/src/core/shaders/webgl/Rounded.js +88 -0
- package/dist/src/core/shaders/webgl/Rounded.js.map +1 -0
- package/dist/src/core/shaders/webgl/RoundedWithBorder.d.ts +3 -0
- package/dist/src/core/shaders/webgl/RoundedWithBorder.js +202 -0
- package/dist/src/core/shaders/webgl/RoundedWithBorder.js.map +1 -0
- package/dist/src/core/shaders/webgl/RoundedWithBorderAndShadow.d.ts +3 -0
- package/dist/src/core/shaders/webgl/RoundedWithBorderAndShadow.js +223 -0
- package/dist/src/core/shaders/webgl/RoundedWithBorderAndShadow.js.map +1 -0
- package/dist/src/core/shaders/webgl/RoundedWithShadow.d.ts +3 -0
- package/dist/src/core/shaders/webgl/RoundedWithShadow.js +123 -0
- package/dist/src/core/shaders/webgl/RoundedWithShadow.js.map +1 -0
- package/dist/src/core/shaders/webgl/SdfShader.d.ts +13 -0
- package/dist/src/core/shaders/webgl/SdfShader.js +72 -0
- package/dist/src/core/shaders/webgl/SdfShader.js.map +1 -0
- package/dist/src/core/shaders/webgl/Shadow.d.ts +3 -0
- package/dist/src/core/shaders/webgl/Shadow.js +115 -0
- package/dist/src/core/shaders/webgl/Shadow.js.map +1 -0
- package/dist/src/core/text-rendering/CanvasFontHandler.d.ts +59 -0
- package/dist/src/core/text-rendering/CanvasFontHandler.js +206 -0
- package/dist/src/core/text-rendering/CanvasFontHandler.js.map +1 -0
- package/dist/src/core/text-rendering/CanvasTextRenderer.d.ts +17 -0
- package/dist/src/core/text-rendering/CanvasTextRenderer.js +139 -0
- package/dist/src/core/text-rendering/CanvasTextRenderer.js.map +1 -0
- package/dist/src/core/text-rendering/SdfFontHandler.d.ts +167 -0
- package/dist/src/core/text-rendering/SdfFontHandler.js +371 -0
- package/dist/src/core/text-rendering/SdfFontHandler.js.map +1 -0
- package/dist/src/core/text-rendering/SdfTextRenderer.d.ts +17 -0
- package/dist/src/core/text-rendering/SdfTextRenderer.js +249 -0
- package/dist/src/core/text-rendering/SdfTextRenderer.js.map +1 -0
- package/dist/src/core/text-rendering/TextLayoutEngine.d.ts +18 -0
- package/dist/src/core/text-rendering/TextLayoutEngine.js +380 -0
- package/dist/src/core/text-rendering/TextLayoutEngine.js.map +1 -0
- package/dist/src/core/text-rendering/TextRenderer.d.ts +406 -0
- package/dist/src/core/text-rendering/TextRenderer.js +2 -0
- package/dist/src/core/text-rendering/TextRenderer.js.map +1 -0
- package/dist/src/core/text-rendering/Utils.d.ts +30 -0
- package/dist/src/core/text-rendering/Utils.js +66 -0
- package/dist/src/core/text-rendering/Utils.js.map +1 -0
- package/dist/src/core/textures/ColorTexture.d.ts +36 -0
- package/dist/src/core/textures/ColorTexture.js +57 -0
- package/dist/src/core/textures/ColorTexture.js.map +1 -0
- package/dist/src/core/textures/ImageTexture.d.ts +131 -0
- package/dist/src/core/textures/ImageTexture.js +211 -0
- package/dist/src/core/textures/ImageTexture.js.map +1 -0
- package/dist/src/core/textures/NoiseTexture.d.ts +43 -0
- package/dist/src/core/textures/NoiseTexture.js +50 -0
- package/dist/src/core/textures/NoiseTexture.js.map +1 -0
- package/dist/src/core/textures/RenderTexture.d.ts +29 -0
- package/dist/src/core/textures/RenderTexture.js +36 -0
- package/dist/src/core/textures/RenderTexture.js.map +1 -0
- package/dist/src/core/textures/SubTexture.d.ts +61 -0
- package/dist/src/core/textures/SubTexture.js +99 -0
- package/dist/src/core/textures/SubTexture.js.map +1 -0
- package/dist/src/core/textures/Texture.d.ts +275 -0
- package/dist/src/core/textures/Texture.js +326 -0
- package/dist/src/core/textures/Texture.js.map +1 -0
- package/dist/src/core/utils.d.ts +23 -0
- package/dist/src/core/utils.js +155 -0
- package/dist/src/core/utils.js.map +1 -0
- package/dist/src/main-api/INode.d.ts +65 -0
- package/dist/src/main-api/INode.js +2 -0
- package/dist/src/main-api/INode.js.map +1 -0
- package/dist/src/main-api/Inspector.d.ts +154 -0
- package/dist/src/main-api/Inspector.js +844 -0
- package/dist/src/main-api/Inspector.js.map +1 -0
- package/dist/src/main-api/Renderer.d.ts +629 -0
- package/dist/src/main-api/Renderer.js +471 -0
- package/dist/src/main-api/Renderer.js.map +1 -0
- package/dist/src/main-api/utils.d.ts +2 -0
- package/dist/src/main-api/utils.js +34 -0
- package/dist/src/main-api/utils.js.map +1 -0
- package/dist/src/utils.d.ts +123 -0
- package/dist/src/utils.js +234 -0
- package/dist/src/utils.js.map +1 -0
- package/dist/tsconfig.dist.tsbuildinfo +1 -0
- package/exports/canvas-shaders.ts +11 -0
- package/exports/canvas.ts +27 -0
- package/exports/index.ts +69 -0
- package/exports/inspector.ts +5 -0
- package/exports/utils.ts +32 -0
- package/exports/webgl-shaders.ts +12 -0
- package/exports/webgl.ts +33 -0
- package/package.json +99 -0
- package/src/common/CommonTypes.ts +145 -0
- package/src/common/EventEmitter.ts +58 -0
- package/src/common/IAnimationController.ts +65 -0
- package/src/common/IEventEmitter.ts +11 -0
- package/src/core/Autosizer.ts +205 -0
- package/src/core/CoreNode.test.ts +535 -0
- package/src/core/CoreNode.ts +2883 -0
- package/src/core/CoreShaderManager.ts +170 -0
- package/src/core/CoreTextNode.ts +573 -0
- package/src/core/CoreTextureManager.ts +552 -0
- package/src/core/Stage.ts +1037 -0
- package/src/core/TextureError.ts +46 -0
- package/src/core/TextureMemoryManager.ts +378 -0
- package/src/core/animations/AnimationManager.ts +178 -0
- package/src/core/animations/CoreAnimation.ts +138 -0
- package/src/core/lib/ContextSpy.ts +22 -0
- package/src/core/lib/ImageWorker.ts +292 -0
- package/src/core/lib/Matrix3d.ts +231 -0
- package/src/core/lib/RenderCoords.ts +55 -0
- package/src/core/lib/WebGlContextWrapper.ts +1448 -0
- package/src/core/lib/collectionUtils.ts +99 -0
- package/src/core/lib/colorCache.ts +20 -0
- package/src/core/lib/colorParser.ts +66 -0
- package/src/core/lib/textureCompression.ts +492 -0
- package/src/core/lib/textureSvg.ts +59 -0
- package/src/core/lib/utils.ts +400 -0
- package/src/core/lib/validateImageBitmap.ts +87 -0
- package/src/core/platforms/Platform.ts +64 -0
- package/src/core/platforms/web/WebPlatform.ts +132 -0
- package/src/core/renderers/CoreContextTexture.ts +25 -0
- package/src/core/renderers/CoreRenderOp.ts +3 -0
- package/src/core/renderers/CoreRenderer.ts +101 -0
- package/src/core/renderers/CoreShaderNode.ts +202 -0
- package/src/core/renderers/CoreShaderProgram.ts +4 -0
- package/src/core/renderers/canvas/CanvasRenderer.ts +274 -0
- package/src/core/renderers/canvas/CanvasShaderNode.ts +79 -0
- package/src/core/renderers/canvas/CanvasTexture.ts +141 -0
- package/src/core/renderers/webgl/SdfRenderOp.ts +103 -0
- package/src/core/renderers/webgl/WebGlCtxRenderTexture.ts +70 -0
- package/src/core/renderers/webgl/WebGlCtxSubTexture.ts +76 -0
- package/src/core/renderers/webgl/WebGlCtxTexture.ts +332 -0
- package/src/core/renderers/webgl/WebGlRenderer.ts +1323 -0
- package/src/core/renderers/webgl/WebGlShaderNode.ts +423 -0
- package/src/core/renderers/webgl/WebGlShaderProgram.ts +346 -0
- package/src/core/renderers/webgl/internal/BufferCollection.ts +46 -0
- package/src/core/renderers/webgl/internal/RendererUtils.ts +136 -0
- package/src/core/renderers/webgl/internal/ShaderUtils.ts +262 -0
- package/src/core/renderers/webgl/internal/WebGlUtils.ts +16 -0
- package/src/core/shaders/canvas/Border.ts +119 -0
- package/src/core/shaders/canvas/HolePunch.ts +38 -0
- package/src/core/shaders/canvas/LinearGradient.ts +54 -0
- package/src/core/shaders/canvas/RadialGradient.ts +82 -0
- package/src/core/shaders/canvas/Rounded.ts +38 -0
- package/src/core/shaders/canvas/RoundedWithBorder.ts +105 -0
- package/src/core/shaders/canvas/RoundedWithBorderAndShadow.ts +118 -0
- package/src/core/shaders/canvas/RoundedWithShadow.ts +56 -0
- package/src/core/shaders/canvas/Shadow.ts +35 -0
- package/src/core/shaders/canvas/utils/render.ts +143 -0
- package/src/core/shaders/templates/BorderTemplate.ts +128 -0
- package/src/core/shaders/templates/HolePunchTemplate.ts +65 -0
- package/src/core/shaders/templates/LinearGradientTemplate.ts +54 -0
- package/src/core/shaders/templates/RadialGradientTemplate.ts +66 -0
- package/src/core/shaders/templates/RoundedTemplate.ts +81 -0
- package/src/core/shaders/templates/RoundedWithBorderAndShadowTemplate.ts +21 -0
- package/src/core/shaders/templates/RoundedWithBorderTemplate.ts +23 -0
- package/src/core/shaders/templates/RoundedWithShadowTemplate.ts +18 -0
- package/src/core/shaders/templates/ShadowTemplate.ts +89 -0
- package/src/core/shaders/utils.ts +30 -0
- package/src/core/shaders/webgl/Border.ts +158 -0
- package/src/core/shaders/webgl/Default.ts +52 -0
- package/src/core/shaders/webgl/HolePunch.ts +58 -0
- package/src/core/shaders/webgl/LinearGradient.ts +119 -0
- package/src/core/shaders/webgl/RadialGradient.ts +91 -0
- package/src/core/shaders/webgl/Rounded.ts +97 -0
- package/src/core/shaders/webgl/RoundedWithBorder.ts +212 -0
- package/src/core/shaders/webgl/RoundedWithBorderAndShadow.ts +235 -0
- package/src/core/shaders/webgl/RoundedWithShadow.ts +132 -0
- package/src/core/shaders/webgl/SdfShader.ts +73 -0
- package/src/core/shaders/webgl/Shadow.ts +119 -0
- package/src/core/text-rendering/CanvasFontHandler.ts +285 -0
- package/src/core/text-rendering/CanvasTextRenderer.ts +236 -0
- package/src/core/text-rendering/SdfFontHandler.ts +566 -0
- package/src/core/text-rendering/SdfTextRenderer.ts +352 -0
- package/src/core/text-rendering/TextLayoutEngine.ts +672 -0
- package/src/core/text-rendering/TextRenderer.ts +449 -0
- package/src/core/text-rendering/Utils.ts +80 -0
- package/src/core/text-rendering/tests/TextLayoutEngine.test.ts +434 -0
- package/src/core/textures/ColorTexture.ts +85 -0
- package/src/core/textures/ImageTexture.ts +394 -0
- package/src/core/textures/NoiseTexture.ts +87 -0
- package/src/core/textures/RenderTexture.ts +68 -0
- package/src/core/textures/SubTexture.ts +165 -0
- package/src/core/textures/Texture.ts +505 -0
- package/src/core/utils.ts +210 -0
- package/src/env.d.ts +7 -0
- package/src/main-api/INode.ts +92 -0
- package/src/main-api/Inspector.ts +1267 -0
- package/src/main-api/Renderer.ts +1011 -0
- package/src/main-api/utils.ts +45 -0
- package/src/utils.ts +302 -0
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import { hasZeroWidthSpace } from './Utils.js';
|
|
2
|
+
import * as SdfFontHandler from './SdfFontHandler.js';
|
|
3
|
+
import { WebGlRenderer } from '../renderers/webgl/WebGlRenderer.js';
|
|
4
|
+
import { Sdf } from '../shaders/webgl/SdfShader.js';
|
|
5
|
+
import { isProductionEnvironment } from '../../utils.js';
|
|
6
|
+
import { mapTextLayout } from './TextLayoutEngine.js';
|
|
7
|
+
// Type definition to match interface
|
|
8
|
+
const type = 'sdf';
|
|
9
|
+
let sdfShader = null;
|
|
10
|
+
// Initialize the SDF text renderer
|
|
11
|
+
const init = (stage) => {
|
|
12
|
+
SdfFontHandler.init();
|
|
13
|
+
// Register SDF shader with the shader manager
|
|
14
|
+
stage.shManager.registerShaderType('Sdf', Sdf);
|
|
15
|
+
sdfShader = stage.shManager.createShader('Sdf');
|
|
16
|
+
};
|
|
17
|
+
const font = SdfFontHandler;
|
|
18
|
+
/**
|
|
19
|
+
* SDF text renderer using MSDF/SDF fonts with WebGL
|
|
20
|
+
*
|
|
21
|
+
* @param stage - Stage instance for font resolution
|
|
22
|
+
* @param props - Text rendering properties
|
|
23
|
+
* @returns Object containing ImageData and dimensions
|
|
24
|
+
*/
|
|
25
|
+
const renderText = (props) => {
|
|
26
|
+
// Early return if no text
|
|
27
|
+
if (props.text.length === 0) {
|
|
28
|
+
return {
|
|
29
|
+
width: 0,
|
|
30
|
+
height: 0,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
// Get font cache for this font family
|
|
34
|
+
const fontData = SdfFontHandler.getFontData(props.fontFamily);
|
|
35
|
+
if (fontData === undefined) {
|
|
36
|
+
// Font not loaded, return empty result
|
|
37
|
+
return {
|
|
38
|
+
width: 0,
|
|
39
|
+
height: 0,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
// Calculate text layout and generate glyph data for caching
|
|
43
|
+
const layout = generateTextLayout(props, fontData);
|
|
44
|
+
// For SDF renderer, ImageData is null since we render via WebGL
|
|
45
|
+
return {
|
|
46
|
+
remainingLines: 0,
|
|
47
|
+
hasRemainingText: false,
|
|
48
|
+
width: layout.width,
|
|
49
|
+
height: layout.height,
|
|
50
|
+
layout, // Cache layout for addQuads
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* addQuads is a no-op for the batched SDF path.
|
|
55
|
+
* Vertex data is now written directly into the shared SDF buffer
|
|
56
|
+
* by `WebGlRenderer.addSdfQuads` during `renderQuads`.
|
|
57
|
+
*/
|
|
58
|
+
const addQuads = (_layout) => {
|
|
59
|
+
return null;
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Submit SDF glyphs to the renderer's shared batched buffer.
|
|
63
|
+
*
|
|
64
|
+
* Two paths:
|
|
65
|
+
* 1. **Cache hit** — layout, transform, color, and alpha haven't changed.
|
|
66
|
+
* The cached pre-transformed Float32Array is mem-copied directly into the
|
|
67
|
+
* shared SDF buffer (no per-glyph matrix math).
|
|
68
|
+
* 2. **Cache miss** — re-computes per-glyph world-space vertices via
|
|
69
|
+
* `addSdfQuads`, then snapshots the result into the cache.
|
|
70
|
+
*/
|
|
71
|
+
const renderQuads = (renderer, layout, _vertexBuffer, renderProps) => {
|
|
72
|
+
const fontFamily = renderProps.fontFamily;
|
|
73
|
+
const atlasTexture = SdfFontHandler.getAtlas(fontFamily);
|
|
74
|
+
if (atlasTexture === null) {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
const webGlRenderer = renderer;
|
|
78
|
+
const cache = renderProps.sdfCache;
|
|
79
|
+
const ctxTexture = atlasTexture.ctxTexture;
|
|
80
|
+
// --- Cache-hit fast path ------------------------------------------------
|
|
81
|
+
if (cache !== undefined && cache.vertices !== null) {
|
|
82
|
+
const ct = cache.transform;
|
|
83
|
+
const t = renderProps.globalTransform;
|
|
84
|
+
if (cache.layoutRef === layout &&
|
|
85
|
+
cache.color === renderProps.color &&
|
|
86
|
+
cache.alpha === renderProps.worldAlpha &&
|
|
87
|
+
ct[0] === t[0] &&
|
|
88
|
+
ct[1] === t[1] &&
|
|
89
|
+
ct[2] === t[3] &&
|
|
90
|
+
ct[3] === t[4] &&
|
|
91
|
+
ct[4] === t[6] &&
|
|
92
|
+
ct[5] === t[7]) {
|
|
93
|
+
webGlRenderer.addSdfCachedQuads(cache.vertices, cache.glyphCount, ctxTexture,
|
|
94
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
95
|
+
renderProps.clippingRect, renderProps.worldAlpha, layout.width, layout.height, renderProps.parentHasRenderTexture,
|
|
96
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
97
|
+
renderProps.framebufferDimensions, sdfShader);
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// --- Cache-miss slow path -----------------------------------------------
|
|
102
|
+
const startIdx = webGlRenderer.sdfBufferIdx;
|
|
103
|
+
webGlRenderer.addSdfQuads(layout.glyphs, layout.fontScale, renderProps.globalTransform, renderProps.color, renderProps.worldAlpha, layout.distanceRange, ctxTexture,
|
|
104
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
105
|
+
renderProps.clippingRect, layout.width, layout.height, renderProps.parentHasRenderTexture,
|
|
106
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
107
|
+
renderProps.framebufferDimensions, sdfShader);
|
|
108
|
+
// Snapshot the written vertex data into the cache for future frames
|
|
109
|
+
if (cache !== undefined) {
|
|
110
|
+
const endIdx = webGlRenderer.sdfBufferIdx;
|
|
111
|
+
const len = endIdx - startIdx;
|
|
112
|
+
if (len > 0) {
|
|
113
|
+
if (cache.vertices === null || cache.vertices.length !== len) {
|
|
114
|
+
cache.vertices = new Float32Array(len);
|
|
115
|
+
}
|
|
116
|
+
cache.vertices.set(webGlRenderer.fSdfBuffer.subarray(startIdx, endIdx));
|
|
117
|
+
cache.glyphCount = layout.glyphs.length;
|
|
118
|
+
cache.color = renderProps.color;
|
|
119
|
+
cache.alpha = renderProps.worldAlpha;
|
|
120
|
+
cache.layoutRef = layout;
|
|
121
|
+
const t = renderProps.globalTransform;
|
|
122
|
+
const ct = cache.transform;
|
|
123
|
+
ct[0] = t[0];
|
|
124
|
+
ct[1] = t[1];
|
|
125
|
+
ct[2] = t[3];
|
|
126
|
+
ct[3] = t[4];
|
|
127
|
+
ct[4] = t[6];
|
|
128
|
+
ct[5] = t[7];
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return null;
|
|
132
|
+
};
|
|
133
|
+
/**
|
|
134
|
+
* Generate complete text layout with glyph positioning for caching
|
|
135
|
+
*/
|
|
136
|
+
const generateTextLayout = (props, fontCache) => {
|
|
137
|
+
const fontSize = props.fontSize;
|
|
138
|
+
const fontFamily = props.fontFamily;
|
|
139
|
+
const lineHeight = props.lineHeight;
|
|
140
|
+
const metrics = SdfFontHandler.getFontMetrics(fontFamily, fontSize);
|
|
141
|
+
const verticalAlign = props.verticalAlign;
|
|
142
|
+
const fontData = fontCache.data;
|
|
143
|
+
const commonFontData = fontData.common;
|
|
144
|
+
const designFontSize = fontData.info.size;
|
|
145
|
+
const atlasWidth = commonFontData.scaleW;
|
|
146
|
+
const atlasHeight = commonFontData.scaleH;
|
|
147
|
+
const invAtlasWidth = 1 / atlasWidth;
|
|
148
|
+
const invAtlasHeight = 1 / atlasHeight;
|
|
149
|
+
const glyphMap = fontCache.glyphMap;
|
|
150
|
+
const kernings = fontCache.kernings;
|
|
151
|
+
const fallbackGlyphId = isProductionEnvironment ? 32 : 63;
|
|
152
|
+
// Calculate the pixel scale from design units to pixels
|
|
153
|
+
const fontScale = fontSize / designFontSize;
|
|
154
|
+
const letterSpacing = props.letterSpacing / fontScale;
|
|
155
|
+
const maxWidth = props.maxWidth / fontScale;
|
|
156
|
+
const maxHeight = props.maxHeight;
|
|
157
|
+
const [lines, remainingLines, hasRemainingText, bareLineHeight, lineHeightPx, effectiveWidth, effectiveHeight,] = mapTextLayout(SdfFontHandler.measureText, metrics, props.text, props.textAlign, fontFamily, lineHeight, props.overflowSuffix, props.wordBreak, letterSpacing, props.maxLines, maxWidth, maxHeight);
|
|
158
|
+
const lineAmount = lines.length;
|
|
159
|
+
const glyphs = [];
|
|
160
|
+
let currentX = 0;
|
|
161
|
+
let currentY = 0;
|
|
162
|
+
for (let i = 0; i < lineAmount; i++) {
|
|
163
|
+
const line = lines[i];
|
|
164
|
+
const textLine = line[0];
|
|
165
|
+
const textLineLength = textLine.length;
|
|
166
|
+
let prevGlyphId = 0;
|
|
167
|
+
currentX = line[3];
|
|
168
|
+
//convert Y coord to vertex value
|
|
169
|
+
currentY = line[4] / fontScale;
|
|
170
|
+
for (let j = 0; j < textLineLength; j++) {
|
|
171
|
+
const codepoint = textLine.codePointAt(j);
|
|
172
|
+
if (codepoint > 0xffff) {
|
|
173
|
+
j++;
|
|
174
|
+
}
|
|
175
|
+
if (codepoint === 0x200b) {
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
const char = textLine[j];
|
|
179
|
+
if (hasZeroWidthSpace(char) === true) {
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
// Get glyph data from font handler
|
|
183
|
+
let glyph = glyphMap.get(codepoint);
|
|
184
|
+
if (glyph === undefined) {
|
|
185
|
+
glyph = glyphMap.get(fallbackGlyphId);
|
|
186
|
+
if (glyph === undefined) {
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
// Kerning offsets the current glyph relative to the previous glyph.
|
|
191
|
+
let kerning = 0;
|
|
192
|
+
// Add kerning if there's a previous character
|
|
193
|
+
if (prevGlyphId !== 0) {
|
|
194
|
+
const seconds = kernings[glyph.id];
|
|
195
|
+
if (seconds !== undefined) {
|
|
196
|
+
const amount = seconds[prevGlyphId];
|
|
197
|
+
if (amount !== undefined) {
|
|
198
|
+
kerning = amount;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
// Apply pair kerning before placing this glyph.
|
|
203
|
+
currentX += kerning;
|
|
204
|
+
// Calculate glyph position and atlas coordinates (in design units)
|
|
205
|
+
const glyphLayout = {
|
|
206
|
+
codepoint,
|
|
207
|
+
glyphId: glyph.id,
|
|
208
|
+
x: currentX + glyph.xoffset,
|
|
209
|
+
y: currentY + glyph.yoffset,
|
|
210
|
+
width: glyph.width,
|
|
211
|
+
height: glyph.height,
|
|
212
|
+
xOffset: glyph.xoffset,
|
|
213
|
+
yOffset: glyph.yoffset,
|
|
214
|
+
atlasX: glyph.x * invAtlasWidth,
|
|
215
|
+
atlasY: glyph.y * invAtlasHeight,
|
|
216
|
+
atlasWidth: glyph.width * invAtlasWidth,
|
|
217
|
+
atlasHeight: glyph.height * invAtlasHeight,
|
|
218
|
+
};
|
|
219
|
+
glyphs.push(glyphLayout);
|
|
220
|
+
// Advance position with letter spacing (in design units)
|
|
221
|
+
currentX += glyph.xadvance + letterSpacing;
|
|
222
|
+
prevGlyphId = glyph.id;
|
|
223
|
+
}
|
|
224
|
+
currentY += lineHeightPx;
|
|
225
|
+
}
|
|
226
|
+
// Convert final dimensions to pixel space for the layout
|
|
227
|
+
return {
|
|
228
|
+
glyphs,
|
|
229
|
+
distanceRange: fontScale * fontData.distanceField.distanceRange,
|
|
230
|
+
width: effectiveWidth * fontScale,
|
|
231
|
+
height: effectiveHeight,
|
|
232
|
+
fontScale: fontScale,
|
|
233
|
+
lineHeight: lineHeightPx,
|
|
234
|
+
fontFamily,
|
|
235
|
+
};
|
|
236
|
+
};
|
|
237
|
+
/**
|
|
238
|
+
* SDF Text Renderer - implements TextRenderer interface
|
|
239
|
+
*/
|
|
240
|
+
const SdfTextRenderer = {
|
|
241
|
+
type,
|
|
242
|
+
font,
|
|
243
|
+
renderText,
|
|
244
|
+
addQuads,
|
|
245
|
+
renderQuads,
|
|
246
|
+
init,
|
|
247
|
+
};
|
|
248
|
+
export default SdfTextRenderer;
|
|
249
|
+
//# sourceMappingURL=SdfTextRenderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SdfTextRenderer.js","sourceRoot":"","sources":["../../../../src/core/text-rendering/SdfTextRenderer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { FontMetrics, MeasureTextFn, NormalizedFontMetrics, TextLayoutStruct, TextLineStruct, WrappedLinesStruct } from './TextRenderer.js';
|
|
2
|
+
export declare const defaultFontMetrics: FontMetrics;
|
|
3
|
+
export declare const normalizeFontMetrics: (metrics: FontMetrics, fontSize: number) => NormalizedFontMetrics;
|
|
4
|
+
export declare const mapTextLayout: (measureText: MeasureTextFn, metrics: NormalizedFontMetrics, text: string, textAlign: string, fontFamily: string, lineHeight: number, overflowSuffix: string, wordBreak: string, letterSpacing: number, maxLines: number, maxWidth: number, maxHeight: number) => TextLayoutStruct;
|
|
5
|
+
export declare const measureLines: (measureText: MeasureTextFn, lines: string[], fontFamily: string, letterSpacing: number, maxLines: number) => WrappedLinesStruct;
|
|
6
|
+
export declare const wrapText: (measureText: MeasureTextFn, text: string, fontFamily: string, maxWidth: number, letterSpacing: number, overflowSuffix: string, wordBreak: string, maxLines: number) => WrappedLinesStruct;
|
|
7
|
+
export declare const wrapLine: (measureText: MeasureTextFn, line: string, fontFamily: string, maxWidth: number, letterSpacing: number, spaceWidth: number, overflowSuffix: string, overflowWidth: number, wordBreak: string, remainingLines: number) => WrappedLinesStruct;
|
|
8
|
+
/**
|
|
9
|
+
* Overflow wordBreak strategy, if a word partially fits add it to the line, start new line if necessary or add overflowSuffix.
|
|
10
|
+
*
|
|
11
|
+
* @remarks This strategy is similar to 'normal' in html/CSS. However
|
|
12
|
+
*/
|
|
13
|
+
export declare const overflow: (measureText: MeasureTextFn, word: string, wordWidth: number, fontFamily: string, letterSpacing: number, wrappedLines: TextLineStruct[], currentLine: string, currentLineWidth: number, remainingLines: number, remainingWord: string, maxWidth: number, space: string, spaceWidth: number, overflowSuffix: string, overflowWidth: number) => [string, number, string];
|
|
14
|
+
export declare const breakWord: (measureText: MeasureTextFn, word: string, wordWidth: number, fontFamily: string, letterSpacing: number, wrappedLines: TextLineStruct[], currentLine: string, currentLineWidth: number, remainingLines: number, remainingWord: string, maxWidth: number, space: string, spaceWidth: number, overflowSuffix: string, overflowWidth: number) => [string, number, string];
|
|
15
|
+
export declare const breakAll: (measureText: MeasureTextFn, word: string, wordWidth: number, fontFamily: string, letterSpacing: number, wrappedLines: TextLineStruct[], currentLine: string, currentLineWidth: number, remainingLines: number, remainingWord: string, maxWidth: number, space: string, spaceWidth: number, overflowSuffix: string, overflowWidth: number) => [string, number, string];
|
|
16
|
+
export declare const truncateLineEnd: (measureText: MeasureTextFn, fontFamily: string, letterSpacing: number, currentLine: string, currentLineWidth: number, remainingWord: string, maxWidth: number, overflowSuffix: string, overflowWidth: number) => [string, number, string];
|
|
17
|
+
export declare const truncateWord: (measureText: MeasureTextFn, word: string, wordWidth: number, maxWidth: number, fontFamily: string, letterSpacing: number, overflowSuffix: string, overflowWidth: number) => [string, string, number];
|
|
18
|
+
export declare const splitWord: (measureText: MeasureTextFn, word: string, wordWidth: number, maxWidth: number, fontFamily: string, letterSpacing: number) => [string, string, number];
|
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
// Use the same space regex as Canvas renderer to handle ZWSP
|
|
2
|
+
const spaceRegex = /[ \u200B]+/g;
|
|
3
|
+
export const defaultFontMetrics = {
|
|
4
|
+
ascender: 800,
|
|
5
|
+
descender: -200,
|
|
6
|
+
lineGap: 200,
|
|
7
|
+
unitsPerEm: 1000,
|
|
8
|
+
};
|
|
9
|
+
export const normalizeFontMetrics = (metrics, fontSize) => {
|
|
10
|
+
const scale = fontSize / metrics.unitsPerEm;
|
|
11
|
+
return {
|
|
12
|
+
ascender: metrics.ascender * scale,
|
|
13
|
+
descender: metrics.descender * scale,
|
|
14
|
+
lineGap: metrics.lineGap * scale,
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
export const mapTextLayout = (measureText, metrics, text, textAlign, fontFamily, lineHeight, overflowSuffix, wordBreak, letterSpacing, maxLines, maxWidth, maxHeight) => {
|
|
18
|
+
const ascPx = metrics.ascender;
|
|
19
|
+
const descPx = metrics.descender;
|
|
20
|
+
const bareLineHeight = ascPx - descPx;
|
|
21
|
+
const lineHeightPx = lineHeight <= 3 ? lineHeight * bareLineHeight : lineHeight;
|
|
22
|
+
const lineHeightDelta = lineHeightPx - bareLineHeight;
|
|
23
|
+
const halfDelta = lineHeightDelta * 0.5;
|
|
24
|
+
let effectiveMaxLines = maxLines;
|
|
25
|
+
if (maxHeight > 0) {
|
|
26
|
+
let maxFromHeight = Math.floor(maxHeight / lineHeightPx);
|
|
27
|
+
//ensure at least 1 line
|
|
28
|
+
if (maxFromHeight < 1) {
|
|
29
|
+
maxFromHeight = 1;
|
|
30
|
+
}
|
|
31
|
+
if (effectiveMaxLines === 0 || maxFromHeight < effectiveMaxLines) {
|
|
32
|
+
effectiveMaxLines = maxFromHeight;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//trim start/end whitespace
|
|
36
|
+
// text = text.trim();
|
|
37
|
+
const wrappedText = maxWidth > 0;
|
|
38
|
+
//wrapText or just measureLines based on maxWidth
|
|
39
|
+
const [lines, remainingLines, remainingText] = wrappedText === true
|
|
40
|
+
? wrapText(measureText, text, fontFamily, maxWidth, letterSpacing, overflowSuffix, wordBreak, effectiveMaxLines)
|
|
41
|
+
: measureLines(measureText, text.split('\n'), fontFamily, letterSpacing, effectiveMaxLines);
|
|
42
|
+
let effectiveLineAmount = lines.length;
|
|
43
|
+
let effectiveMaxWidth = 0;
|
|
44
|
+
if (effectiveLineAmount > 0) {
|
|
45
|
+
effectiveMaxWidth = lines[0][1];
|
|
46
|
+
//check for longest line
|
|
47
|
+
if (effectiveLineAmount > 1) {
|
|
48
|
+
for (let i = 1; i < effectiveLineAmount; i++) {
|
|
49
|
+
effectiveMaxWidth = Math.max(effectiveMaxWidth, lines[i][1]);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//update line x offsets
|
|
54
|
+
if (textAlign !== 'left') {
|
|
55
|
+
for (let i = 0; i < effectiveLineAmount; i++) {
|
|
56
|
+
const line = lines[i];
|
|
57
|
+
const w = line[1];
|
|
58
|
+
line[3] =
|
|
59
|
+
textAlign === 'right'
|
|
60
|
+
? effectiveMaxWidth - w
|
|
61
|
+
: (effectiveMaxWidth - w) / 2;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
const effectiveMaxHeight = effectiveLineAmount * lineHeightPx;
|
|
65
|
+
let firstBaseLine = halfDelta;
|
|
66
|
+
const startY = firstBaseLine;
|
|
67
|
+
for (let i = 0; i < effectiveLineAmount; i++) {
|
|
68
|
+
const line = lines[i];
|
|
69
|
+
line[4] = startY + lineHeightPx * i;
|
|
70
|
+
}
|
|
71
|
+
return [
|
|
72
|
+
lines,
|
|
73
|
+
remainingLines,
|
|
74
|
+
remainingText,
|
|
75
|
+
bareLineHeight,
|
|
76
|
+
lineHeightPx,
|
|
77
|
+
effectiveMaxWidth,
|
|
78
|
+
effectiveMaxHeight,
|
|
79
|
+
];
|
|
80
|
+
};
|
|
81
|
+
export const measureLines = (measureText, lines, fontFamily, letterSpacing, maxLines) => {
|
|
82
|
+
const measuredLines = [];
|
|
83
|
+
let remainingLines = maxLines > 0 ? maxLines : lines.length;
|
|
84
|
+
let i = 0;
|
|
85
|
+
while (remainingLines > 0) {
|
|
86
|
+
const line = lines[i];
|
|
87
|
+
i++;
|
|
88
|
+
remainingLines--;
|
|
89
|
+
if (line === undefined) {
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
const width = measureText(line, fontFamily, letterSpacing);
|
|
93
|
+
measuredLines.push([line, width, false, 0, 0]);
|
|
94
|
+
}
|
|
95
|
+
return [
|
|
96
|
+
measuredLines,
|
|
97
|
+
remainingLines,
|
|
98
|
+
maxLines > 0 ? lines.length - measuredLines.length > 0 : false,
|
|
99
|
+
];
|
|
100
|
+
};
|
|
101
|
+
export const wrapText = (measureText, text, fontFamily, maxWidth, letterSpacing, overflowSuffix, wordBreak, maxLines) => {
|
|
102
|
+
const lines = text.split('\n');
|
|
103
|
+
const wrappedLines = [];
|
|
104
|
+
// Calculate space width for line wrapping
|
|
105
|
+
const spaceWidth = measureText(' ', fontFamily, letterSpacing);
|
|
106
|
+
const overflowWidth = measureText(overflowSuffix, fontFamily, letterSpacing);
|
|
107
|
+
let wrappedLine = [];
|
|
108
|
+
let remainingLines = maxLines > 0 ? maxLines : 1000;
|
|
109
|
+
let hasRemainingText = true;
|
|
110
|
+
let hasMaxLines = maxLines > 0;
|
|
111
|
+
for (let i = 0; i < lines.length; i++) {
|
|
112
|
+
const line = lines[i];
|
|
113
|
+
if (line === undefined) {
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
[wrappedLine, remainingLines, hasRemainingText] =
|
|
117
|
+
line.length > 0
|
|
118
|
+
? wrapLine(measureText, line, fontFamily, maxWidth, letterSpacing, spaceWidth, overflowSuffix, overflowWidth, wordBreak, remainingLines)
|
|
119
|
+
: [[['', 0, false, 0, 0]], remainingLines, i < lines.length - 1];
|
|
120
|
+
remainingLines--;
|
|
121
|
+
wrappedLines.push(...wrappedLine);
|
|
122
|
+
if (hasMaxLines === true && remainingLines <= 0) {
|
|
123
|
+
const lastLine = wrappedLines[wrappedLines.length - 1];
|
|
124
|
+
if (i < lines.length - 1) {
|
|
125
|
+
//check if line is truncated already
|
|
126
|
+
if (lastLine[2] === false) {
|
|
127
|
+
let remainingText = '';
|
|
128
|
+
const [line, lineWidth] = truncateLineEnd(measureText, fontFamily, letterSpacing, lastLine[0], lastLine[1], remainingText, maxWidth, overflowSuffix, overflowWidth);
|
|
129
|
+
lastLine[0] = line;
|
|
130
|
+
lastLine[1] = lineWidth;
|
|
131
|
+
lastLine[2] = true;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return [wrappedLines, remainingLines, hasRemainingText];
|
|
138
|
+
};
|
|
139
|
+
export const wrapLine = (measureText, line, fontFamily, maxWidth, letterSpacing, spaceWidth, overflowSuffix, overflowWidth, wordBreak, remainingLines) => {
|
|
140
|
+
const words = line.split(spaceRegex);
|
|
141
|
+
const spaces = line.match(spaceRegex) || [];
|
|
142
|
+
const wrappedLines = [];
|
|
143
|
+
let currentLine = '';
|
|
144
|
+
let currentLineWidth = 0;
|
|
145
|
+
let hasRemainingText = true;
|
|
146
|
+
const wrapFn = getWrapStrategy(wordBreak);
|
|
147
|
+
while (words.length > 0 && remainingLines > 0) {
|
|
148
|
+
let word = words.shift();
|
|
149
|
+
let wordWidth = measureText(word, fontFamily, letterSpacing);
|
|
150
|
+
let remainingWord = '';
|
|
151
|
+
//handle first word of new line separately to avoid empty line issues
|
|
152
|
+
if (currentLineWidth === 0) {
|
|
153
|
+
// Word doesn't fit on current line
|
|
154
|
+
//if first word doesn't fit on empty line
|
|
155
|
+
if (wordWidth > maxWidth) {
|
|
156
|
+
remainingLines--;
|
|
157
|
+
//truncate word to fit
|
|
158
|
+
[word, remainingWord, wordWidth] =
|
|
159
|
+
remainingLines === 0
|
|
160
|
+
? truncateWord(measureText, word, wordWidth, maxWidth, fontFamily, letterSpacing, overflowSuffix, overflowWidth)
|
|
161
|
+
: splitWord(measureText, word, wordWidth, maxWidth, fontFamily, letterSpacing);
|
|
162
|
+
if (remainingWord.length > 0) {
|
|
163
|
+
words.unshift(remainingWord);
|
|
164
|
+
}
|
|
165
|
+
// first word doesn't fit on an empty line
|
|
166
|
+
wrappedLines.push([word, wordWidth, false, 0, 0]);
|
|
167
|
+
}
|
|
168
|
+
else if (wordWidth + spaceWidth >= maxWidth) {
|
|
169
|
+
remainingLines--;
|
|
170
|
+
// word with space doesn't fit, but word itself fits - put on new line
|
|
171
|
+
wrappedLines.push([word, wordWidth, false, 0, 0]);
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
currentLine = word;
|
|
175
|
+
currentLineWidth = wordWidth;
|
|
176
|
+
}
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
const space = spaces.shift() || '';
|
|
180
|
+
// For width calculation, treat ZWSP as having 0 width but regular space functionality
|
|
181
|
+
const effectiveSpaceWidth = space === '\u200B' ? 0 : spaceWidth;
|
|
182
|
+
const totalWidth = currentLineWidth + effectiveSpaceWidth + wordWidth;
|
|
183
|
+
if (totalWidth < maxWidth) {
|
|
184
|
+
currentLine += effectiveSpaceWidth > 0 ? space + word : word;
|
|
185
|
+
currentLineWidth = totalWidth;
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
// Will move to next line after loop finishes
|
|
189
|
+
remainingLines--;
|
|
190
|
+
if (totalWidth === maxWidth) {
|
|
191
|
+
currentLine += effectiveSpaceWidth > 0 ? space + word : word;
|
|
192
|
+
currentLineWidth = totalWidth;
|
|
193
|
+
wrappedLines.push([currentLine, currentLineWidth, false, 0, 0]);
|
|
194
|
+
currentLine = '';
|
|
195
|
+
currentLineWidth = 0;
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
[currentLine, currentLineWidth, remainingWord] = wrapFn(measureText, word, wordWidth, fontFamily, letterSpacing, wrappedLines, currentLine, currentLineWidth, remainingLines, remainingWord, maxWidth, space, spaceWidth, overflowSuffix, overflowWidth);
|
|
199
|
+
if (remainingWord.length > 0) {
|
|
200
|
+
words.unshift(remainingWord);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
if (currentLineWidth > 0 && remainingLines > 0) {
|
|
204
|
+
wrappedLines.push([currentLine, currentLineWidth, false, 0, 0]);
|
|
205
|
+
}
|
|
206
|
+
return [wrappedLines, remainingLines, hasRemainingText];
|
|
207
|
+
};
|
|
208
|
+
const getWrapStrategy = (wordBreak) => {
|
|
209
|
+
//** default so probably first out */
|
|
210
|
+
if (wordBreak === 'break-word') {
|
|
211
|
+
return breakWord;
|
|
212
|
+
}
|
|
213
|
+
//** second most used */
|
|
214
|
+
if (wordBreak === 'break-all') {
|
|
215
|
+
return breakAll;
|
|
216
|
+
}
|
|
217
|
+
//** most similar to html/CSS 'normal' not really used in TV apps */
|
|
218
|
+
if (wordBreak === 'overflow') {
|
|
219
|
+
return overflow;
|
|
220
|
+
}
|
|
221
|
+
//fallback
|
|
222
|
+
return breakWord;
|
|
223
|
+
};
|
|
224
|
+
//break strategies
|
|
225
|
+
/**
|
|
226
|
+
* Overflow wordBreak strategy, if a word partially fits add it to the line, start new line if necessary or add overflowSuffix.
|
|
227
|
+
*
|
|
228
|
+
* @remarks This strategy is similar to 'normal' in html/CSS. However
|
|
229
|
+
*/
|
|
230
|
+
export const overflow = (measureText, word, wordWidth, fontFamily, letterSpacing, wrappedLines, currentLine, currentLineWidth, remainingLines, remainingWord, maxWidth, space, spaceWidth, overflowSuffix, overflowWidth) => {
|
|
231
|
+
currentLine += space + word;
|
|
232
|
+
currentLineWidth += spaceWidth + wordWidth;
|
|
233
|
+
if (remainingLines === 0) {
|
|
234
|
+
currentLine += overflowSuffix;
|
|
235
|
+
currentLineWidth += overflowWidth;
|
|
236
|
+
}
|
|
237
|
+
wrappedLines.push([currentLine, currentLineWidth, true, 0, 0]);
|
|
238
|
+
return ['', 0, ''];
|
|
239
|
+
};
|
|
240
|
+
export const breakWord = (measureText, word, wordWidth, fontFamily, letterSpacing, wrappedLines, currentLine, currentLineWidth, remainingLines, remainingWord, maxWidth, space, spaceWidth, overflowSuffix, overflowWidth) => {
|
|
241
|
+
remainingWord = word;
|
|
242
|
+
if (remainingLines === 0) {
|
|
243
|
+
[currentLine, currentLineWidth, remainingWord] = truncateLineEnd(measureText, fontFamily, letterSpacing, currentLine, currentLineWidth, remainingWord, maxWidth, overflowSuffix, overflowWidth);
|
|
244
|
+
wrappedLines.push([currentLine, currentLineWidth, true, 0, 0]);
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
wrappedLines.push([currentLine, currentLineWidth, false, 0, 0]);
|
|
248
|
+
currentLine = '';
|
|
249
|
+
currentLineWidth = 0;
|
|
250
|
+
}
|
|
251
|
+
return [currentLine, currentLineWidth, remainingWord];
|
|
252
|
+
};
|
|
253
|
+
export const breakAll = (measureText, word, wordWidth, fontFamily, letterSpacing, wrappedLines, currentLine, currentLineWidth, remainingLines, remainingWord, maxWidth, space, spaceWidth, overflowSuffix, overflowWidth) => {
|
|
254
|
+
let remainingSpace = maxWidth - currentLineWidth;
|
|
255
|
+
if (currentLineWidth > 0) {
|
|
256
|
+
remainingSpace -= spaceWidth;
|
|
257
|
+
}
|
|
258
|
+
const truncate = remainingLines === 0;
|
|
259
|
+
[word, remainingWord, wordWidth] = truncate
|
|
260
|
+
? truncateWord(measureText, word, wordWidth, remainingSpace, fontFamily, letterSpacing, overflowSuffix, overflowWidth)
|
|
261
|
+
: splitWord(measureText, word, wordWidth, remainingSpace, fontFamily, letterSpacing);
|
|
262
|
+
currentLine += space + word;
|
|
263
|
+
currentLineWidth += spaceWidth + wordWidth;
|
|
264
|
+
// first word doesn't fit on an empty line
|
|
265
|
+
wrappedLines.push([currentLine, currentLineWidth, truncate, 0, 0]);
|
|
266
|
+
currentLine = '';
|
|
267
|
+
currentLineWidth = 0;
|
|
268
|
+
return [currentLine, currentLineWidth, remainingWord];
|
|
269
|
+
};
|
|
270
|
+
export const truncateLineEnd = (measureText, fontFamily, letterSpacing, currentLine, currentLineWidth, remainingWord, maxWidth, overflowSuffix, overflowWidth) => {
|
|
271
|
+
if (currentLineWidth + overflowWidth <= maxWidth) {
|
|
272
|
+
currentLine += overflowSuffix;
|
|
273
|
+
currentLineWidth += overflowWidth;
|
|
274
|
+
remainingWord = '';
|
|
275
|
+
return [currentLine, currentLineWidth, remainingWord];
|
|
276
|
+
}
|
|
277
|
+
let truncated = false;
|
|
278
|
+
for (let i = currentLine.length - 1; i > 0; i--) {
|
|
279
|
+
const char = currentLine.charAt(i);
|
|
280
|
+
const charWidth = measureText(char, fontFamily, letterSpacing);
|
|
281
|
+
currentLineWidth -= charWidth;
|
|
282
|
+
if (currentLineWidth + overflowWidth <= maxWidth) {
|
|
283
|
+
currentLine = currentLine.substring(0, i) + overflowSuffix;
|
|
284
|
+
currentLineWidth += overflowWidth;
|
|
285
|
+
remainingWord = currentLine.substring(i) + ' ' + remainingWord;
|
|
286
|
+
truncated = true;
|
|
287
|
+
break;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
if (truncated === false) {
|
|
291
|
+
currentLine = overflowSuffix;
|
|
292
|
+
currentLineWidth = overflowWidth;
|
|
293
|
+
remainingWord = currentLine;
|
|
294
|
+
}
|
|
295
|
+
return [currentLine, currentLineWidth, remainingWord];
|
|
296
|
+
};
|
|
297
|
+
export const truncateWord = (measureText, word, wordWidth, maxWidth, fontFamily, letterSpacing, overflowSuffix, overflowWidth) => {
|
|
298
|
+
const targetWidth = maxWidth - overflowWidth;
|
|
299
|
+
if (targetWidth <= 0) {
|
|
300
|
+
return ['', word, 0];
|
|
301
|
+
}
|
|
302
|
+
const excessWidth = wordWidth - targetWidth;
|
|
303
|
+
// If excess is small (< 50%), we're keeping most - start from back and remove
|
|
304
|
+
// If excess is large (>= 50%), we're removing most - start from front and add
|
|
305
|
+
const shouldStartFromBack = excessWidth < wordWidth / 2;
|
|
306
|
+
if (shouldStartFromBack === false) {
|
|
307
|
+
// Start from back - remove characters until it fits (keeping most of word)
|
|
308
|
+
let currentWidth = wordWidth;
|
|
309
|
+
for (let i = word.length - 1; i > 0; i--) {
|
|
310
|
+
const char = word.charAt(i);
|
|
311
|
+
const charWidth = measureText(char, fontFamily, letterSpacing);
|
|
312
|
+
currentWidth -= charWidth;
|
|
313
|
+
if (currentWidth <= targetWidth) {
|
|
314
|
+
const remainingWord = word.substring(i);
|
|
315
|
+
return [
|
|
316
|
+
word.substring(0, i) + overflowSuffix,
|
|
317
|
+
remainingWord,
|
|
318
|
+
currentWidth + overflowWidth,
|
|
319
|
+
];
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
// Even first character doesn't fit
|
|
323
|
+
return [overflowSuffix, word, overflowWidth];
|
|
324
|
+
}
|
|
325
|
+
// Start from front - add characters until we exceed limit (removing most of word)
|
|
326
|
+
let currentWidth = 0;
|
|
327
|
+
for (let i = 0; i < word.length; i++) {
|
|
328
|
+
const char = word.charAt(i);
|
|
329
|
+
const charWidth = measureText(char, fontFamily, letterSpacing);
|
|
330
|
+
if (currentWidth + charWidth > targetWidth) {
|
|
331
|
+
const remainingWord = word.substring(i);
|
|
332
|
+
return [
|
|
333
|
+
word.substring(0, i) + overflowSuffix,
|
|
334
|
+
remainingWord,
|
|
335
|
+
currentWidth + overflowWidth,
|
|
336
|
+
];
|
|
337
|
+
}
|
|
338
|
+
currentWidth += charWidth;
|
|
339
|
+
}
|
|
340
|
+
// Entire word fits (shouldn't happen, but safe fallback)
|
|
341
|
+
return [word + overflowSuffix, '', wordWidth + overflowWidth];
|
|
342
|
+
};
|
|
343
|
+
export const splitWord = (measureText, word, wordWidth, maxWidth, fontFamily, letterSpacing) => {
|
|
344
|
+
if (maxWidth <= 0) {
|
|
345
|
+
return ['', word, 0];
|
|
346
|
+
}
|
|
347
|
+
const excessWidth = wordWidth - maxWidth;
|
|
348
|
+
// If excess is small (< 50%), we're keeping most - start from back and remove
|
|
349
|
+
// If excess is large (>= 50%), we're removing most - start from front and add
|
|
350
|
+
const shouldStartFromBack = excessWidth < wordWidth / 2;
|
|
351
|
+
if (shouldStartFromBack === false) {
|
|
352
|
+
// Start from back - remove characters until it fits (keeping most of word)
|
|
353
|
+
let currentWidth = wordWidth;
|
|
354
|
+
for (let i = word.length - 1; i > 0; i--) {
|
|
355
|
+
const char = word.charAt(i);
|
|
356
|
+
const charWidth = measureText(char, fontFamily, letterSpacing);
|
|
357
|
+
currentWidth -= charWidth;
|
|
358
|
+
if (currentWidth <= maxWidth) {
|
|
359
|
+
const remainingWord = word.substring(i);
|
|
360
|
+
return [word.substring(0, i), remainingWord, currentWidth];
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
// Even first character doesn't fit
|
|
364
|
+
return ['', word, 0];
|
|
365
|
+
}
|
|
366
|
+
// Start from front - add characters until we exceed limit (removing most of word)
|
|
367
|
+
let currentWidth = 0;
|
|
368
|
+
for (let i = 0; i < word.length; i++) {
|
|
369
|
+
const char = word.charAt(i);
|
|
370
|
+
const charWidth = measureText(char, fontFamily, letterSpacing);
|
|
371
|
+
if (currentWidth + charWidth > maxWidth) {
|
|
372
|
+
const remainingWord = word.substring(i);
|
|
373
|
+
return [word.substring(0, i), remainingWord, currentWidth];
|
|
374
|
+
}
|
|
375
|
+
currentWidth += charWidth;
|
|
376
|
+
}
|
|
377
|
+
// Entire word fits (shouldn't happen, but safe fallback)
|
|
378
|
+
return [word, '', wordWidth];
|
|
379
|
+
};
|
|
380
|
+
//# sourceMappingURL=TextLayoutEngine.js.map
|