@lightningjs/renderer 0.3.0 → 0.3.2
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/NOTICE +1 -2
- package/dist/exports/core-api.js +1 -1
- package/dist/exports/main-api.js +1 -1
- package/dist/exports/utils.js +1 -1
- package/dist/src/common/CommonTypes.js +1 -1
- package/dist/src/common/EventEmitter.js +1 -1
- package/dist/src/common/IAnimationController.js +1 -1
- package/dist/src/core/CoreExtension.js +1 -1
- package/dist/src/core/CoreNode.d.ts +5 -1
- package/dist/src/core/CoreNode.js +9 -2
- package/dist/src/core/CoreNode.js.map +1 -1
- package/dist/src/core/CoreTextNode.d.ts +2 -1
- package/dist/src/core/CoreTextNode.js +3 -3
- package/dist/src/core/CoreTextNode.js.map +1 -1
- package/dist/src/core/CoreTextureManager.js +1 -1
- package/dist/src/core/Matrix2DContext.js +1 -1
- package/dist/src/core/Stage.d.ts +2 -1
- package/dist/src/core/Stage.js +20 -6
- package/dist/src/core/Stage.js.map +1 -1
- package/dist/src/core/animations/AnimationManager.js +1 -1
- package/dist/src/core/animations/CoreAnimation.js +1 -1
- package/dist/src/core/animations/CoreAnimationController.js +1 -1
- package/dist/src/core/lib/glm/common.js +1 -1
- package/dist/src/core/lib/glm/index.js +1 -1
- package/dist/src/core/lib/glm/mat2.js +1 -1
- package/dist/src/core/lib/glm/mat2d.js +1 -1
- package/dist/src/core/lib/glm/mat3.js +1 -1
- package/dist/src/core/lib/glm/mat4.js +1 -1
- package/dist/src/core/lib/glm/quat.js +1 -1
- package/dist/src/core/lib/glm/quat2.js +1 -1
- package/dist/src/core/lib/glm/vec2.js +1 -1
- package/dist/src/core/lib/glm/vec3.js +1 -1
- package/dist/src/core/lib/glm/vec4.js +1 -1
- package/dist/src/core/lib/utils.d.ts +1 -0
- package/dist/src/core/lib/utils.js +10 -1
- package/dist/src/core/lib/utils.js.map +1 -1
- package/dist/src/core/platform.js +1 -1
- package/dist/src/core/renderers/CoreContextTexture.js +1 -1
- package/dist/src/core/renderers/CoreRenderOp.js +1 -1
- package/dist/src/core/renderers/CoreRenderer.d.ts +2 -0
- package/dist/src/core/renderers/CoreRenderer.js +1 -1
- package/dist/src/core/renderers/CoreRenderer.js.map +1 -1
- package/dist/src/core/renderers/CoreShader.d.ts +2 -2
- package/dist/src/core/renderers/CoreShader.js +1 -1
- package/dist/src/core/renderers/CoreShader.js.map +1 -1
- package/dist/src/core/renderers/webgl/WebGlCoreCtxSubTexture.js +1 -1
- package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js +1 -1
- package/dist/src/core/renderers/webgl/WebGlCoreRenderOp.d.ts +4 -1
- package/dist/src/core/renderers/webgl/WebGlCoreRenderOp.js +22 -4
- package/dist/src/core/renderers/webgl/WebGlCoreRenderOp.js.map +1 -1
- package/dist/src/core/renderers/webgl/WebGlCoreRenderer.d.ts +2 -2
- package/dist/src/core/renderers/webgl/WebGlCoreRenderer.js +29 -15
- package/dist/src/core/renderers/webgl/WebGlCoreRenderer.js.map +1 -1
- package/dist/src/core/renderers/webgl/WebGlCoreShader.d.ts +46 -3
- package/dist/src/core/renderers/webgl/WebGlCoreShader.js +44 -9
- package/dist/src/core/renderers/webgl/WebGlCoreShader.js.map +1 -1
- package/dist/src/core/renderers/webgl/internal/BufferCollection.js +1 -1
- package/dist/src/core/renderers/webgl/internal/RendererUtils.js +1 -1
- package/dist/src/core/renderers/webgl/internal/ShaderUtils.js +1 -1
- package/dist/src/core/renderers/webgl/internal/WebGlUtils.js +1 -1
- package/dist/src/core/renderers/webgl/shaders/DefaultShader.js +1 -1
- package/dist/src/core/renderers/webgl/shaders/DefaultShaderBatched.js +1 -1
- package/dist/src/core/renderers/webgl/shaders/DynamicShader.d.ts +8 -6
- package/dist/src/core/renderers/webgl/shaders/DynamicShader.js +20 -13
- package/dist/src/core/renderers/webgl/shaders/DynamicShader.js.map +1 -1
- package/dist/src/core/renderers/webgl/shaders/RoundedRectangle.d.ts +5 -6
- package/dist/src/core/renderers/webgl/shaders/RoundedRectangle.js +12 -11
- package/dist/src/core/renderers/webgl/shaders/RoundedRectangle.js.map +1 -1
- package/dist/src/core/renderers/webgl/shaders/SdfShader.d.ts +1 -1
- package/dist/src/core/renderers/webgl/shaders/SdfShader.js +1 -1
- package/dist/src/core/renderers/webgl/shaders/SdfShader.js.map +1 -1
- package/dist/src/core/renderers/webgl/shaders/effects/BorderBottomEffect.d.ts +16 -0
- package/dist/src/core/renderers/webgl/shaders/effects/BorderBottomEffect.js +5 -2
- package/dist/src/core/renderers/webgl/shaders/effects/BorderBottomEffect.js.map +1 -1
- package/dist/src/core/renderers/webgl/shaders/effects/BorderEffect.d.ts +16 -0
- package/dist/src/core/renderers/webgl/shaders/effects/BorderEffect.js +5 -2
- package/dist/src/core/renderers/webgl/shaders/effects/BorderEffect.js.map +1 -1
- package/dist/src/core/renderers/webgl/shaders/effects/BorderLeftEffect.d.ts +16 -0
- package/dist/src/core/renderers/webgl/shaders/effects/BorderLeftEffect.js +5 -2
- package/dist/src/core/renderers/webgl/shaders/effects/BorderLeftEffect.js.map +1 -1
- package/dist/src/core/renderers/webgl/shaders/effects/BorderRightEffect.d.ts +16 -0
- package/dist/src/core/renderers/webgl/shaders/effects/BorderRightEffect.js +5 -2
- package/dist/src/core/renderers/webgl/shaders/effects/BorderRightEffect.js.map +1 -1
- package/dist/src/core/renderers/webgl/shaders/effects/BorderTopEffect.d.ts +16 -0
- package/dist/src/core/renderers/webgl/shaders/effects/BorderTopEffect.js +5 -2
- package/dist/src/core/renderers/webgl/shaders/effects/BorderTopEffect.js.map +1 -1
- package/dist/src/core/renderers/webgl/shaders/effects/EffectUtils.js +1 -1
- package/dist/src/core/renderers/webgl/shaders/effects/FadeOutEffect.d.ts +12 -0
- package/dist/src/core/renderers/webgl/shaders/effects/FadeOutEffect.js +100 -0
- package/dist/src/core/renderers/webgl/shaders/effects/FadeOutEffect.js.map +1 -0
- package/dist/src/core/renderers/webgl/shaders/effects/GlitchEffect.d.ts +28 -0
- package/dist/src/core/renderers/webgl/shaders/effects/GlitchEffect.js +3 -0
- package/dist/src/core/renderers/webgl/shaders/effects/GlitchEffect.js.map +1 -1
- package/dist/src/core/renderers/webgl/shaders/effects/GrayscaleEffect.d.ts +3 -0
- package/dist/src/core/renderers/webgl/shaders/effects/GrayscaleEffect.js +4 -1
- package/dist/src/core/renderers/webgl/shaders/effects/GrayscaleEffect.js.map +1 -1
- package/dist/src/core/renderers/webgl/shaders/effects/LinearGradientEffect.d.ts +19 -0
- package/dist/src/core/renderers/webgl/shaders/effects/LinearGradientEffect.js +5 -2
- package/dist/src/core/renderers/webgl/shaders/effects/LinearGradientEffect.js.map +1 -1
- package/dist/src/core/renderers/webgl/shaders/effects/RadialGradientEffect.d.ts +38 -0
- package/dist/src/core/renderers/webgl/shaders/effects/RadialGradientEffect.js +116 -0
- package/dist/src/core/renderers/webgl/shaders/effects/RadialGradientEffect.js.map +1 -0
- package/dist/src/core/renderers/webgl/shaders/effects/RadiusEffect.d.ts +11 -0
- package/dist/src/core/renderers/webgl/shaders/effects/RadiusEffect.js +4 -1
- package/dist/src/core/renderers/webgl/shaders/effects/RadiusEffect.js.map +1 -1
- package/dist/src/core/scene/Scene.js +1 -1
- package/dist/src/core/text-rendering/TextTextureRendererUtils.js +1 -1
- package/dist/src/core/text-rendering/TrFontManager.js +1 -1
- package/dist/src/core/text-rendering/font-face-types/SdfTrFontFace/SdfTrFontFace.js +1 -1
- package/dist/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/FontShaper.js +1 -1
- package/dist/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/SdfFontShaper.js +1 -1
- package/dist/src/core/text-rendering/font-face-types/TrFontFace.js +1 -1
- package/dist/src/core/text-rendering/font-face-types/WebTrFontFace.js +1 -1
- package/dist/src/core/text-rendering/renderers/CanvasTextRenderer.d.ts +2 -2
- package/dist/src/core/text-rendering/renderers/CanvasTextRenderer.js +5 -2
- package/dist/src/core/text-rendering/renderers/CanvasTextRenderer.js.map +1 -1
- package/dist/src/core/text-rendering/renderers/LightningTextTextureRenderer.js +1 -1
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.d.ts +2 -2
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js +3 -3
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js.map +1 -1
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/PeekableGenerator.js +1 -1
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/SpecialCodepoints.js +1 -1
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/constants.js +1 -1
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/getStartConditions.js +1 -1
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/getUnicodeCodepoints.js +1 -1
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText.js +1 -1
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/makeRenderWindow.js +1 -1
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/measureText.js +1 -1
- package/dist/src/core/text-rendering/renderers/TextRenderer.d.ts +2 -1
- package/dist/src/core/text-rendering/renderers/TextRenderer.js +1 -1
- package/dist/src/core/text-rendering/renderers/TextRenderer.js.map +1 -1
- package/dist/src/core/textures/ColorTexture.js +1 -1
- package/dist/src/core/textures/ImageTexture.js +1 -1
- package/dist/src/core/textures/NoiseTexture.js +1 -1
- package/dist/src/core/textures/SubTexture.js +1 -1
- package/dist/src/core/textures/Texture.js +1 -1
- package/dist/src/core/utils.js +1 -1
- package/dist/src/main-api/INode.d.ts +19 -0
- package/dist/src/main-api/INode.js +1 -1
- package/dist/src/main-api/IRenderDriver.js +1 -1
- package/dist/src/main-api/RendererMain.d.ts +1 -1
- package/dist/src/main-api/RendererMain.js +2 -1
- package/dist/src/main-api/RendererMain.js.map +1 -1
- package/dist/src/main-api/TextureRegistry.d.ts +33 -0
- package/dist/src/main-api/TextureRegistry.js +97 -0
- package/dist/src/main-api/TextureRegistry.js.map +1 -0
- package/dist/src/main-api/TextureUsageRegistry/TextureRegistry.d.ts +33 -0
- package/dist/src/main-api/TextureUsageRegistry/TextureRegistry.js +97 -0
- package/dist/src/main-api/TextureUsageRegistry/TextureRegistry.js.map +1 -0
- package/dist/src/main-api/texture-usage-trackers/FinalizationRegistryTextureUsageTracker.d.ts +9 -0
- package/dist/src/main-api/texture-usage-trackers/FinalizationRegistryTextureUsageTracker.js +38 -0
- package/dist/src/main-api/texture-usage-trackers/FinalizationRegistryTextureUsageTracker.js.map +1 -0
- package/dist/src/main-api/texture-usage-trackers/ManualCountTextureUsageTracker.d.ts +56 -0
- package/dist/src/main-api/texture-usage-trackers/ManualCountTextureUsageTracker.js +101 -0
- package/dist/src/main-api/texture-usage-trackers/ManualCountTextureUsageTracker.js.map +1 -0
- package/dist/src/main-api/texture-usage-trackers/TextureUsageTracker.d.ts +32 -0
- package/dist/src/main-api/texture-usage-trackers/TextureUsageTracker.js +28 -0
- package/dist/src/main-api/texture-usage-trackers/TextureUsageTracker.js.map +1 -0
- package/dist/src/render-drivers/main/MainOnlyNode.d.ts +2 -0
- package/dist/src/render-drivers/main/MainOnlyNode.js +8 -1
- package/dist/src/render-drivers/main/MainOnlyNode.js.map +1 -1
- package/dist/src/render-drivers/main/MainOnlyTextNode.js +2 -1
- package/dist/src/render-drivers/main/MainOnlyTextNode.js.map +1 -1
- package/dist/src/render-drivers/main/MainRenderDriver.js +1 -1
- package/dist/src/render-drivers/threadx/NodeStruct.d.ts +3 -0
- package/dist/src/render-drivers/threadx/NodeStruct.js +10 -1
- package/dist/src/render-drivers/threadx/NodeStruct.js.map +1 -1
- package/dist/src/render-drivers/threadx/SharedNode.d.ts +1 -0
- package/dist/src/render-drivers/threadx/SharedNode.js +2 -1
- package/dist/src/render-drivers/threadx/SharedNode.js.map +1 -1
- package/dist/src/render-drivers/threadx/TextNodeStruct.js +1 -1
- package/dist/src/render-drivers/threadx/ThreadXMainAnimationController.js +1 -1
- package/dist/src/render-drivers/threadx/ThreadXMainNode.js +1 -1
- package/dist/src/render-drivers/threadx/ThreadXMainTextNode.js +1 -1
- package/dist/src/render-drivers/threadx/ThreadXRenderDriver.js +3 -1
- package/dist/src/render-drivers/threadx/ThreadXRenderDriver.js.map +1 -1
- package/dist/src/render-drivers/threadx/ThreadXRendererMessage.js +1 -1
- package/dist/src/render-drivers/threadx/worker/ThreadXRendererNode.js +2 -1
- package/dist/src/render-drivers/threadx/worker/ThreadXRendererNode.js.map +1 -1
- package/dist/src/render-drivers/threadx/worker/ThreadXRendererTextNode.js +2 -1
- package/dist/src/render-drivers/threadx/worker/ThreadXRendererTextNode.js.map +1 -1
- package/dist/src/render-drivers/threadx/worker/renderer.js +2 -1
- package/dist/src/render-drivers/threadx/worker/renderer.js.map +1 -1
- package/dist/src/utils.d.ts +10 -2
- package/dist/src/utils.js +13 -3
- package/dist/src/utils.js.map +1 -1
- package/dist/tsconfig.dist.tsbuildinfo +1 -1
- package/package.json +6 -5
- package/src/common/CommonTypes.ts +70 -0
- package/src/common/EventEmitter.ts +77 -0
- package/src/common/IAnimationController.ts +29 -0
- package/src/core/CoreExtension.ts +32 -0
- package/src/core/CoreNode.ts +700 -0
- package/src/core/CoreShaderManager.ts +111 -0
- package/src/core/CoreTextNode.ts +342 -0
- package/src/core/CoreTextureManager.ts +323 -0
- package/src/core/Matrix2DContext.ts +52 -0
- package/src/core/Stage.ts +280 -0
- package/src/core/animations/AnimationManager.ts +38 -0
- package/src/core/animations/CoreAnimation.ts +139 -0
- package/src/core/animations/CoreAnimationController.ts +117 -0
- package/src/core/lib/glm/common.ts +231 -0
- package/src/core/lib/glm/index.ts +31 -0
- package/src/core/lib/glm/mat2.ts +499 -0
- package/src/core/lib/glm/mat2d.ts +547 -0
- package/src/core/lib/glm/mat3.ts +849 -0
- package/src/core/lib/glm/mat4.ts +2169 -0
- package/src/core/lib/glm/quat.ts +828 -0
- package/src/core/lib/glm/quat2.ts +951 -0
- package/src/core/lib/glm/vec2.ts +671 -0
- package/src/core/lib/glm/vec3.ts +859 -0
- package/src/core/lib/glm/vec4.ts +708 -0
- package/src/core/lib/utils.ts +144 -0
- package/src/core/platform.ts +40 -0
- package/src/core/renderers/CoreContextTexture.ts +30 -0
- package/src/core/renderers/CoreRenderOp.ts +22 -0
- package/src/core/renderers/CoreRenderer.ts +66 -0
- package/src/core/renderers/CoreShader.ts +41 -0
- package/src/core/renderers/webgl/WebGlCoreCtxSubTexture.ts +36 -0
- package/src/core/renderers/webgl/WebGlCoreCtxTexture.ts +208 -0
- package/src/core/renderers/webgl/WebGlCoreRenderOp.ts +111 -0
- package/src/core/renderers/webgl/WebGlCoreRenderer.ts +567 -0
- package/src/core/renderers/webgl/WebGlCoreShader.ts +328 -0
- package/src/core/renderers/webgl/internal/BufferCollection.ts +54 -0
- package/src/core/renderers/webgl/internal/RendererUtils.ts +134 -0
- package/src/core/renderers/webgl/internal/ShaderUtils.ts +135 -0
- package/src/core/renderers/webgl/internal/WebGlUtils.ts +35 -0
- package/src/core/renderers/webgl/shaders/DefaultShader.ts +95 -0
- package/src/core/renderers/webgl/shaders/DefaultShaderBatched.ts +132 -0
- package/src/core/renderers/webgl/shaders/DynamicShader.ts +430 -0
- package/src/core/renderers/webgl/shaders/RoundedRectangle.ts +168 -0
- package/src/core/renderers/webgl/shaders/SdfShader.ts +165 -0
- package/src/core/renderers/webgl/shaders/effects/BorderBottomEffect.ts +101 -0
- package/src/core/renderers/webgl/shaders/effects/BorderEffect.ts +86 -0
- package/src/core/renderers/webgl/shaders/effects/BorderLeftEffect.ts +101 -0
- package/src/core/renderers/webgl/shaders/effects/BorderRightEffect.ts +101 -0
- package/src/core/renderers/webgl/shaders/effects/BorderTopEffect.ts +101 -0
- package/src/core/renderers/webgl/shaders/effects/EffectUtils.ts +33 -0
- package/src/core/renderers/webgl/shaders/effects/FadeOutEffect.ts +111 -0
- package/src/core/renderers/webgl/shaders/effects/GlitchEffect.ts +145 -0
- package/src/core/renderers/webgl/shaders/effects/GrayscaleEffect.ts +37 -0
- package/src/core/renderers/webgl/shaders/effects/LinearGradientEffect.ts +182 -0
- package/src/core/renderers/webgl/shaders/effects/RadialGradientEffect.ts +159 -0
- package/src/core/renderers/webgl/shaders/effects/RadiusEffect.ts +106 -0
- package/src/core/renderers/webgl/shaders/effects/ShaderEffect.ts +114 -0
- package/src/core/scene/Scene.ts +120 -0
- package/src/core/text-rendering/TextTextureRendererUtils.ts +189 -0
- package/src/core/text-rendering/TrFontManager.ts +96 -0
- package/src/core/text-rendering/font-face-types/SdfTrFontFace/SdfTrFontFace.ts +128 -0
- package/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/FontShaper.ts +139 -0
- package/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/SdfFontShaper.test.ts +159 -0
- package/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/SdfFontShaper.ts +164 -0
- package/src/core/text-rendering/font-face-types/TrFontFace.ts +105 -0
- package/src/core/text-rendering/font-face-types/WebTrFontFace.ts +77 -0
- package/src/core/text-rendering/renderers/CanvasTextRenderer.ts +634 -0
- package/src/core/text-rendering/renderers/LightningTextTextureRenderer.ts +705 -0
- package/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.ts +647 -0
- package/src/core/text-rendering/renderers/SdfTextRenderer/internal/PeekableGenerator.test.ts +48 -0
- package/src/core/text-rendering/renderers/SdfTextRenderer/internal/PeekableGenerator.ts +66 -0
- package/src/core/text-rendering/renderers/SdfTextRenderer/internal/SpecialCodepoints.ts +52 -0
- package/src/core/text-rendering/renderers/SdfTextRenderer/internal/constants.ts +32 -0
- package/src/core/text-rendering/renderers/SdfTextRenderer/internal/getStartConditions.ts +76 -0
- package/src/core/text-rendering/renderers/SdfTextRenderer/internal/getUnicodeCodepoints.test.ts +133 -0
- package/src/core/text-rendering/renderers/SdfTextRenderer/internal/getUnicodeCodepoints.ts +38 -0
- package/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText.ts +381 -0
- package/src/core/text-rendering/renderers/SdfTextRenderer/internal/makeRenderWindow.test.ts +136 -0
- package/src/core/text-rendering/renderers/SdfTextRenderer/internal/makeRenderWindow.ts +64 -0
- package/src/core/text-rendering/renderers/SdfTextRenderer/internal/measureText.test.ts +41 -0
- package/src/core/text-rendering/renderers/SdfTextRenderer/internal/measureText.ts +51 -0
- package/src/core/text-rendering/renderers/TextRenderer.ts +371 -0
- package/src/core/textures/ColorTexture.ts +85 -0
- package/src/core/textures/ImageTexture.ts +113 -0
- package/src/core/textures/NoiseTexture.ts +96 -0
- package/src/core/textures/SubTexture.ts +140 -0
- package/src/core/textures/Texture.ts +162 -0
- package/src/core/utils.ts +222 -0
- package/src/main-api/INode.ts +443 -0
- package/src/main-api/IRenderDriver.ts +58 -0
- package/src/main-api/RendererMain.ts +451 -0
- package/src/render-drivers/main/MainOnlyNode.ts +429 -0
- package/src/render-drivers/main/MainOnlyTextNode.ts +220 -0
- package/src/render-drivers/main/MainRenderDriver.ts +117 -0
- package/src/render-drivers/threadx/NodeStruct.ts +290 -0
- package/src/render-drivers/threadx/SharedNode.ts +95 -0
- package/src/render-drivers/threadx/TextNodeStruct.ts +166 -0
- package/src/render-drivers/threadx/ThreadXMainAnimationController.ts +99 -0
- package/src/render-drivers/threadx/ThreadXMainNode.ts +151 -0
- package/src/render-drivers/threadx/ThreadXMainTextNode.ts +75 -0
- package/src/render-drivers/threadx/ThreadXRenderDriver.ts +247 -0
- package/src/render-drivers/threadx/ThreadXRendererMessage.ts +82 -0
- package/src/render-drivers/threadx/worker/ThreadXRendererNode.ts +232 -0
- package/src/render-drivers/threadx/worker/ThreadXRendererTextNode.ts +146 -0
- package/src/render-drivers/threadx/worker/renderer.ts +138 -0
- package/src/render-drivers/utils.ts +57 -0
- package/src/utils.ts +202 -0
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* If not stated otherwise in this file or this component's LICENSE file the
|
|
3
|
+
* following copyright and licenses apply:
|
|
4
|
+
*
|
|
5
|
+
* Copyright 2023 Comcast Cable Communications Management, LLC.
|
|
6
|
+
*
|
|
7
|
+
* Licensed under the Apache License, Version 2.0 (the License);
|
|
8
|
+
* you may not use this file except in compliance with the License.
|
|
9
|
+
* You may obtain a copy of the License at
|
|
10
|
+
*
|
|
11
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
*
|
|
13
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
* See the License for the specific language governing permissions and
|
|
17
|
+
* limitations under the License.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { assertTruthy } from '../../../../../utils.js';
|
|
21
|
+
import type {
|
|
22
|
+
FontShaperProps,
|
|
23
|
+
MappedGlyphInfo,
|
|
24
|
+
UnmappedCharacterInfo,
|
|
25
|
+
} from '../../../font-face-types/SdfTrFontFace/internal/FontShaper.js';
|
|
26
|
+
import type { TrProps, TextRendererState } from '../../TextRenderer.js';
|
|
27
|
+
import type { SdfTextRendererState } from '../SdfTextRenderer.js';
|
|
28
|
+
import { PeekableIterator } from './PeekableGenerator.js';
|
|
29
|
+
import { FLOATS_PER_GLYPH } from './constants.js';
|
|
30
|
+
import { getUnicodeCodepoints } from './getUnicodeCodepoints.js';
|
|
31
|
+
import { measureText } from './measureText.js';
|
|
32
|
+
|
|
33
|
+
export function layoutText(
|
|
34
|
+
curLineIndex: number,
|
|
35
|
+
startX: number,
|
|
36
|
+
startY: number,
|
|
37
|
+
text: TrProps['text'],
|
|
38
|
+
textAlign: TrProps['textAlign'],
|
|
39
|
+
width: TrProps['width'],
|
|
40
|
+
height: TrProps['height'],
|
|
41
|
+
fontSize: TrProps['fontSize'],
|
|
42
|
+
letterSpacing: TrProps['letterSpacing'],
|
|
43
|
+
/**
|
|
44
|
+
* Mutated
|
|
45
|
+
*/
|
|
46
|
+
vertexBuffer: NonNullable<SdfTextRendererState['vertexBuffer']>,
|
|
47
|
+
contain: TrProps['contain'],
|
|
48
|
+
/**
|
|
49
|
+
* Mutated
|
|
50
|
+
*/
|
|
51
|
+
lineCache: SdfTextRendererState['lineCache'],
|
|
52
|
+
renderWindow: SdfTextRendererState['renderWindow'],
|
|
53
|
+
trFontFace: SdfTextRendererState['trFontFace'],
|
|
54
|
+
forceFullLayoutCalc: TextRendererState['forceFullLayoutCalc'],
|
|
55
|
+
scrollable: TrProps['scrollable'],
|
|
56
|
+
): {
|
|
57
|
+
bufferNumFloats: number;
|
|
58
|
+
bufferNumQuads: number;
|
|
59
|
+
layoutNumCharacters: number;
|
|
60
|
+
fullyProcessed: boolean;
|
|
61
|
+
maxX: number;
|
|
62
|
+
maxY: number;
|
|
63
|
+
} {
|
|
64
|
+
assertTruthy(trFontFace, 'Font face must be loaded');
|
|
65
|
+
assertTruthy(trFontFace.loaded, 'Font face must be loaded');
|
|
66
|
+
assertTruthy(trFontFace.data, 'Font face must be loaded');
|
|
67
|
+
assertTruthy(trFontFace.shaper, 'Font face must be loaded');
|
|
68
|
+
|
|
69
|
+
// Regardless of fontSize (or other scaling properties), we layout the vertices of each glyph
|
|
70
|
+
// using the fixed coordinate space determined by font size used to produce the atlas.
|
|
71
|
+
// Scaling for display is handled by shader uniforms inexpensively.
|
|
72
|
+
// So we have:
|
|
73
|
+
// - vertex space: the space in which the vertices of each glyph are laid out
|
|
74
|
+
// - screen space: the screen pixel space
|
|
75
|
+
// Input properties such as x, y, w, fontSize, letterSpacing, etc. are all expressed in screen space.
|
|
76
|
+
// We convert these to the vertex space by dividing them the `fontSizeRatio` factor.
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* `lineHeight` in vertex coordinates
|
|
80
|
+
*/
|
|
81
|
+
const vertexLineHeight = trFontFace.data.info.size;
|
|
82
|
+
/**
|
|
83
|
+
* See above
|
|
84
|
+
*/
|
|
85
|
+
const fontSizeRatio = fontSize / vertexLineHeight;
|
|
86
|
+
/**
|
|
87
|
+
* `w` in vertex coordinates
|
|
88
|
+
*/
|
|
89
|
+
const vertexW = width / fontSizeRatio;
|
|
90
|
+
/**
|
|
91
|
+
* `letterSpacing` in vertex coordinates
|
|
92
|
+
*/
|
|
93
|
+
const vertexLSpacing = letterSpacing / fontSizeRatio;
|
|
94
|
+
|
|
95
|
+
const startingLineCacheEntry = lineCache[curLineIndex];
|
|
96
|
+
const startingCodepointIndex = startingLineCacheEntry?.codepointIndex || 0;
|
|
97
|
+
const startingMaxX = startingLineCacheEntry?.maxX || 0;
|
|
98
|
+
const startingMaxY = startingLineCacheEntry?.maxY || 0;
|
|
99
|
+
|
|
100
|
+
let maxX = startingMaxX;
|
|
101
|
+
let maxY = startingMaxY;
|
|
102
|
+
let curX = startX;
|
|
103
|
+
let curY = startY;
|
|
104
|
+
|
|
105
|
+
let bufferOffset = 0;
|
|
106
|
+
/**
|
|
107
|
+
* Buffer offset to last word boundry. This is -1 when we aren't in a word boundry.
|
|
108
|
+
*/
|
|
109
|
+
const lastWord: {
|
|
110
|
+
codepointIndex: number;
|
|
111
|
+
bufferOffset: number;
|
|
112
|
+
xStart: number;
|
|
113
|
+
} = {
|
|
114
|
+
codepointIndex: -1,
|
|
115
|
+
bufferOffset: -1,
|
|
116
|
+
xStart: -1,
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
120
|
+
const shaper = trFontFace.shaper;
|
|
121
|
+
|
|
122
|
+
const shaperProps: FontShaperProps = {
|
|
123
|
+
letterSpacing: vertexLSpacing,
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
// Get glyphs
|
|
127
|
+
let glyphs = shaper.shapeText(
|
|
128
|
+
shaperProps,
|
|
129
|
+
new PeekableIterator(
|
|
130
|
+
getUnicodeCodepoints(text, startingCodepointIndex),
|
|
131
|
+
startingCodepointIndex,
|
|
132
|
+
),
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
let glyphResult:
|
|
136
|
+
| IteratorResult<MappedGlyphInfo | UnmappedCharacterInfo, void>
|
|
137
|
+
| undefined;
|
|
138
|
+
|
|
139
|
+
let curLineBufferStart = -1;
|
|
140
|
+
|
|
141
|
+
const bufferLineInfos: {
|
|
142
|
+
bufferStart: number;
|
|
143
|
+
bufferEnd: number;
|
|
144
|
+
}[] = [];
|
|
145
|
+
|
|
146
|
+
const truncateSeq = '...';
|
|
147
|
+
const vertexTruncateHeight = height / fontSizeRatio;
|
|
148
|
+
const truncateSeqVertexWidth = measureText(truncateSeq, shaperProps, shaper);
|
|
149
|
+
|
|
150
|
+
// Line-by-line layout
|
|
151
|
+
let moreLines = true;
|
|
152
|
+
while (moreLines) {
|
|
153
|
+
const nextLineWillFit =
|
|
154
|
+
contain !== 'both' ||
|
|
155
|
+
scrollable ||
|
|
156
|
+
curY + vertexLineHeight + vertexLineHeight <= vertexTruncateHeight;
|
|
157
|
+
const lineVertexW = nextLineWillFit
|
|
158
|
+
? vertexW
|
|
159
|
+
: vertexW - truncateSeqVertexWidth;
|
|
160
|
+
/**
|
|
161
|
+
* Vertex X position to the beginning of the last word boundary. This becomes -1 when we start traversing a word.
|
|
162
|
+
*/
|
|
163
|
+
let xStartLastWordBoundary = 0;
|
|
164
|
+
// Layout glyphs in this line
|
|
165
|
+
// Any break statements in this while loop will trigger a line break
|
|
166
|
+
while ((glyphResult = glyphs.next()) && !glyphResult.done) {
|
|
167
|
+
const glyph = glyphResult.value;
|
|
168
|
+
|
|
169
|
+
if (curLineIndex === lineCache.length) {
|
|
170
|
+
lineCache.push({
|
|
171
|
+
codepointIndex: glyph.cluster,
|
|
172
|
+
maxY,
|
|
173
|
+
maxX,
|
|
174
|
+
});
|
|
175
|
+
} else if (curLineIndex > lineCache.length) {
|
|
176
|
+
throw new Error('Unexpected lineCache length');
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// If we encounter a word boundary (white space or newline) we invalidate
|
|
180
|
+
// the lastWord and set the xStartLastWordBoundary if we haven't already.
|
|
181
|
+
if (glyph.codepoint === 32 || glyph.codepoint === 10) {
|
|
182
|
+
if (lastWord.codepointIndex !== -1) {
|
|
183
|
+
lastWord.codepointIndex = -1;
|
|
184
|
+
xStartLastWordBoundary = curX;
|
|
185
|
+
}
|
|
186
|
+
} else if (lastWord.codepointIndex === -1) {
|
|
187
|
+
lastWord.codepointIndex = glyph.cluster;
|
|
188
|
+
lastWord.bufferOffset = bufferOffset;
|
|
189
|
+
lastWord.xStart = xStartLastWordBoundary;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (glyph.mapped) {
|
|
193
|
+
// Mapped glyph
|
|
194
|
+
const charEndX = curX + glyph.xOffset + glyph.width;
|
|
195
|
+
// Word wrap check
|
|
196
|
+
if (
|
|
197
|
+
// We are containing the text
|
|
198
|
+
contain !== 'none' &&
|
|
199
|
+
// The current glyph reaches outside the contained width
|
|
200
|
+
charEndX >= lineVertexW &&
|
|
201
|
+
// There is a last word that we can break to the next line
|
|
202
|
+
lastWord.codepointIndex !== -1 &&
|
|
203
|
+
// We have advanced at least one character since the last word started
|
|
204
|
+
lastWord.codepointIndex < glyph.cluster &&
|
|
205
|
+
// Prevents infinite loop when a single word is longer than the width
|
|
206
|
+
lastWord.xStart > 0
|
|
207
|
+
) {
|
|
208
|
+
// The current word is about to go off the edge of the container width
|
|
209
|
+
// Reinitialize the iterator starting at the last word
|
|
210
|
+
// and proceeding to the next line
|
|
211
|
+
if (nextLineWillFit) {
|
|
212
|
+
glyphs = shaper.shapeText(
|
|
213
|
+
shaperProps,
|
|
214
|
+
new PeekableIterator(
|
|
215
|
+
getUnicodeCodepoints(text, lastWord.codepointIndex),
|
|
216
|
+
lastWord.codepointIndex,
|
|
217
|
+
),
|
|
218
|
+
);
|
|
219
|
+
bufferOffset = lastWord.bufferOffset;
|
|
220
|
+
break;
|
|
221
|
+
} else {
|
|
222
|
+
glyphs = shaper.shapeText(
|
|
223
|
+
shaperProps,
|
|
224
|
+
new PeekableIterator(getUnicodeCodepoints(truncateSeq, 0), 0),
|
|
225
|
+
);
|
|
226
|
+
curX = lastWord.xStart;
|
|
227
|
+
bufferOffset = lastWord.bufferOffset;
|
|
228
|
+
}
|
|
229
|
+
} else {
|
|
230
|
+
// This glyph fits, so we can add it to the buffer
|
|
231
|
+
const quadX = curX + glyph.xOffset;
|
|
232
|
+
const quadY = curY + glyph.yOffset;
|
|
233
|
+
|
|
234
|
+
const lineIsBelowWindowTop = renderWindow
|
|
235
|
+
? curY + vertexLineHeight >= renderWindow.y1 / fontSizeRatio
|
|
236
|
+
: true;
|
|
237
|
+
const lineIsAboveWindowBottom = renderWindow
|
|
238
|
+
? curY <= renderWindow.y2 / fontSizeRatio
|
|
239
|
+
: true;
|
|
240
|
+
|
|
241
|
+
// Only add to buffer for rendering if the line is within the render window
|
|
242
|
+
if (lineIsBelowWindowTop && lineIsAboveWindowBottom) {
|
|
243
|
+
if (curLineBufferStart === -1) {
|
|
244
|
+
curLineBufferStart = bufferOffset;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
const atlasEntry = trFontFace.getAtlasEntry(glyph.glyphId);
|
|
248
|
+
|
|
249
|
+
// Add texture coordinates
|
|
250
|
+
const u = atlasEntry.x / trFontFace.data.common.scaleW;
|
|
251
|
+
const v = atlasEntry.y / trFontFace.data.common.scaleH;
|
|
252
|
+
const uvWidth = atlasEntry.width / trFontFace.data.common.scaleW;
|
|
253
|
+
const uvHeight = atlasEntry.height / trFontFace.data.common.scaleH;
|
|
254
|
+
|
|
255
|
+
// TODO: (Performance) We can optimize this by using ELEMENT_ARRAY_BUFFER
|
|
256
|
+
// eliminating the need to duplicate vertices
|
|
257
|
+
|
|
258
|
+
// Top-left
|
|
259
|
+
vertexBuffer[bufferOffset++] = quadX;
|
|
260
|
+
vertexBuffer[bufferOffset++] = quadY;
|
|
261
|
+
vertexBuffer[bufferOffset++] = u;
|
|
262
|
+
vertexBuffer[bufferOffset++] = v;
|
|
263
|
+
|
|
264
|
+
// Top-right
|
|
265
|
+
vertexBuffer[bufferOffset++] = quadX + glyph.width;
|
|
266
|
+
vertexBuffer[bufferOffset++] = quadY;
|
|
267
|
+
vertexBuffer[bufferOffset++] = u + uvWidth;
|
|
268
|
+
vertexBuffer[bufferOffset++] = v;
|
|
269
|
+
|
|
270
|
+
// Bottom-left
|
|
271
|
+
vertexBuffer[bufferOffset++] = quadX;
|
|
272
|
+
vertexBuffer[bufferOffset++] = quadY + glyph.height;
|
|
273
|
+
vertexBuffer[bufferOffset++] = u;
|
|
274
|
+
vertexBuffer[bufferOffset++] = v + uvHeight;
|
|
275
|
+
|
|
276
|
+
// Bottom-right
|
|
277
|
+
vertexBuffer[bufferOffset++] = quadX + glyph.width;
|
|
278
|
+
vertexBuffer[bufferOffset++] = quadY + glyph.height;
|
|
279
|
+
vertexBuffer[bufferOffset++] = u + uvWidth;
|
|
280
|
+
vertexBuffer[bufferOffset++] = v + uvHeight;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
maxY = Math.max(maxY, quadY + glyph.height);
|
|
284
|
+
curX += glyph.xAdvance;
|
|
285
|
+
maxX = Math.max(maxX, curX);
|
|
286
|
+
}
|
|
287
|
+
} else {
|
|
288
|
+
// Unmapped character
|
|
289
|
+
|
|
290
|
+
// Handle newlines
|
|
291
|
+
if (glyph.codepoint === 10) {
|
|
292
|
+
break;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// Prepare for the next line...
|
|
298
|
+
if (curLineBufferStart !== -1) {
|
|
299
|
+
bufferLineInfos.push({
|
|
300
|
+
bufferStart: curLineBufferStart,
|
|
301
|
+
bufferEnd: bufferOffset,
|
|
302
|
+
});
|
|
303
|
+
curLineBufferStart = -1;
|
|
304
|
+
}
|
|
305
|
+
curX = 0;
|
|
306
|
+
curY += vertexLineHeight;
|
|
307
|
+
curLineIndex++;
|
|
308
|
+
lastWord.codepointIndex = -1;
|
|
309
|
+
xStartLastWordBoundary = 0;
|
|
310
|
+
|
|
311
|
+
// Figure out if there are any more lines to render...
|
|
312
|
+
if (
|
|
313
|
+
!forceFullLayoutCalc &&
|
|
314
|
+
contain === 'both' &&
|
|
315
|
+
renderWindow &&
|
|
316
|
+
curY > renderWindow.y2 / fontSizeRatio
|
|
317
|
+
) {
|
|
318
|
+
// Stop layout calculation early (for performance purposes) if:
|
|
319
|
+
// - We're not forcing a full layout calculation (for width/height calculation)
|
|
320
|
+
// - ...and we're containing the text vertically+horizontally (contain === 'both')
|
|
321
|
+
// - ...and we have a render window
|
|
322
|
+
// - ...and the next line is below the bottom of the render window
|
|
323
|
+
moreLines = false;
|
|
324
|
+
} else if (glyphResult && glyphResult.done) {
|
|
325
|
+
// If we've reached the end of the text, we know we're done
|
|
326
|
+
moreLines = false;
|
|
327
|
+
} else if (contain === 'both' && !scrollable && !nextLineWillFit) {
|
|
328
|
+
// If we're contained vertically+horizontally (contain === 'both')
|
|
329
|
+
// but not scrollable and the next line won't fit, we're done.
|
|
330
|
+
moreLines = false;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// Use textAlign to determine if we need to adjust the x position of the text
|
|
335
|
+
// in the buffer line by line
|
|
336
|
+
if (textAlign === 'center') {
|
|
337
|
+
const vertexTextW = contain === 'none' ? maxX : vertexW;
|
|
338
|
+
|
|
339
|
+
for (let i = 0; i < bufferLineInfos.length; i++) {
|
|
340
|
+
const line = bufferLineInfos[i]!;
|
|
341
|
+
// - 4 = the x position of a rightmost vertex
|
|
342
|
+
const lineWidth =
|
|
343
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
344
|
+
vertexBuffer[line.bufferEnd - 4]! - vertexBuffer[line.bufferStart]!;
|
|
345
|
+
|
|
346
|
+
const xOffset = (vertexTextW - lineWidth) / 2;
|
|
347
|
+
for (let j = line.bufferStart; j < line.bufferEnd; j += 4) {
|
|
348
|
+
vertexBuffer[j] += xOffset;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
} else if (textAlign === 'right') {
|
|
352
|
+
const vertexTextW = contain === 'none' ? maxX : vertexW;
|
|
353
|
+
|
|
354
|
+
for (let i = 0; i < bufferLineInfos.length; i++) {
|
|
355
|
+
const line = bufferLineInfos[i]!;
|
|
356
|
+
const lineWidth =
|
|
357
|
+
line.bufferEnd === line.bufferStart
|
|
358
|
+
? 0
|
|
359
|
+
: // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
360
|
+
vertexBuffer[line.bufferEnd - 4]! - vertexBuffer[line.bufferStart]!;
|
|
361
|
+
|
|
362
|
+
const xOffset = vertexTextW - lineWidth;
|
|
363
|
+
for (let j = line.bufferStart; j < line.bufferEnd; j += 4) {
|
|
364
|
+
vertexBuffer[j] += xOffset;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
assertTruthy(glyphResult);
|
|
370
|
+
|
|
371
|
+
return {
|
|
372
|
+
bufferNumFloats: bufferOffset,
|
|
373
|
+
bufferNumQuads: bufferOffset / 16,
|
|
374
|
+
layoutNumCharacters: glyphResult.done
|
|
375
|
+
? text.length - startingCodepointIndex
|
|
376
|
+
: glyphResult.value.cluster - startingCodepointIndex + 1,
|
|
377
|
+
fullyProcessed: !!glyphResult.done,
|
|
378
|
+
maxX,
|
|
379
|
+
maxY,
|
|
380
|
+
};
|
|
381
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* If not stated otherwise in this file or this component's LICENSE file the
|
|
3
|
+
* following copyright and licenses apply:
|
|
4
|
+
*
|
|
5
|
+
* Copyright 2023 Comcast Cable Communications Management, LLC.
|
|
6
|
+
*
|
|
7
|
+
* Licensed under the Apache License, Version 2.0 (the License);
|
|
8
|
+
* you may not use this file except in compliance with the License.
|
|
9
|
+
* You may obtain a copy of the License at
|
|
10
|
+
*
|
|
11
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
*
|
|
13
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
* See the License for the specific language governing permissions and
|
|
17
|
+
* limitations under the License.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { expect, describe, it } from 'vitest';
|
|
21
|
+
import { makeRenderWindow } from './makeRenderWindow.js';
|
|
22
|
+
|
|
23
|
+
describe('makeRenderWindow', () => {
|
|
24
|
+
it('should return a empty window when all inputs are zero / empty', () => {
|
|
25
|
+
expect(
|
|
26
|
+
makeRenderWindow(0, 0, 0, 0, 0, { x1: 0, y1: 0, x2: 0, y2: 0 }),
|
|
27
|
+
).toEqual({
|
|
28
|
+
x1: 0,
|
|
29
|
+
y1: 0,
|
|
30
|
+
x2: 0,
|
|
31
|
+
y2: 0,
|
|
32
|
+
});
|
|
33
|
+
// Visible window is empty
|
|
34
|
+
expect(
|
|
35
|
+
makeRenderWindow(0, 0, 0, 0, 0, { x1: 100, y1: 100, x2: 100, y2: 100 }),
|
|
36
|
+
).toEqual({
|
|
37
|
+
x1: 0,
|
|
38
|
+
y1: 0,
|
|
39
|
+
x2: 0,
|
|
40
|
+
y2: 0,
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('should return an empty window when the visible window is empty regardless of other inputs', () => {
|
|
45
|
+
expect(
|
|
46
|
+
makeRenderWindow(100, 200, 300, 10, 3, { x1: 0, y1: 0, x2: 0, y2: 0 }),
|
|
47
|
+
).toEqual({
|
|
48
|
+
x1: 0,
|
|
49
|
+
y1: 0,
|
|
50
|
+
x2: 0,
|
|
51
|
+
y2: 0,
|
|
52
|
+
});
|
|
53
|
+
expect(
|
|
54
|
+
makeRenderWindow(400, 500, 100, 20, 2, {
|
|
55
|
+
x1: 100,
|
|
56
|
+
y1: 100,
|
|
57
|
+
x2: 100,
|
|
58
|
+
y2: 100,
|
|
59
|
+
}),
|
|
60
|
+
).toEqual({
|
|
61
|
+
x1: 0,
|
|
62
|
+
y1: 0,
|
|
63
|
+
x2: 0,
|
|
64
|
+
y2: 0,
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('should return a window with no margin around the visible area if lineHeight and/or numExtraLines set are zero', () => {
|
|
69
|
+
expect(
|
|
70
|
+
makeRenderWindow(0, 0, 0, 0, 0, { x1: 0, y1: 0, x2: 100, y2: 100 }),
|
|
71
|
+
).toEqual({
|
|
72
|
+
x1: 0,
|
|
73
|
+
y1: 0,
|
|
74
|
+
x2: 100,
|
|
75
|
+
y2: 100,
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
expect(
|
|
79
|
+
makeRenderWindow(0, 0, 0, 10, 0, { x1: 0, y1: 0, x2: 100, y2: 100 }),
|
|
80
|
+
).toEqual({
|
|
81
|
+
x1: 0,
|
|
82
|
+
y1: 0,
|
|
83
|
+
x2: 100,
|
|
84
|
+
y2: 100,
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
expect(
|
|
88
|
+
makeRenderWindow(0, 0, 0, 0, 2, { x1: 0, y1: 0, x2: 100, y2: 100 }),
|
|
89
|
+
).toEqual({
|
|
90
|
+
x1: 0,
|
|
91
|
+
y1: 0,
|
|
92
|
+
x2: 100,
|
|
93
|
+
y2: 100,
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it('should return a window with a margin around the visible area (if lineHeight/numExtraLines set)', () => {
|
|
98
|
+
expect(
|
|
99
|
+
makeRenderWindow(0, 0, 0, 10, 1, { x1: 0, y1: 0, x2: 100, y2: 100 }),
|
|
100
|
+
).toEqual({
|
|
101
|
+
x1: 0,
|
|
102
|
+
y1: -10,
|
|
103
|
+
x2: 100,
|
|
104
|
+
y2: 110,
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
expect(
|
|
108
|
+
makeRenderWindow(0, 0, 0, 5, 3, { x1: 0, y1: 0, x2: 100, y2: 100 }),
|
|
109
|
+
).toEqual({
|
|
110
|
+
x1: 0,
|
|
111
|
+
y1: -15,
|
|
112
|
+
x2: 100,
|
|
113
|
+
y2: 115,
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it('should return a window scrolled to scrollY when set', () => {
|
|
118
|
+
expect(
|
|
119
|
+
makeRenderWindow(0, 0, 100, 10, 1, { x1: 0, y1: 0, x2: 100, y2: 100 }),
|
|
120
|
+
).toEqual({
|
|
121
|
+
x1: 0,
|
|
122
|
+
y1: 90,
|
|
123
|
+
x2: 100,
|
|
124
|
+
y2: 210,
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
expect(
|
|
128
|
+
makeRenderWindow(0, 0, 200, 10, 1, { x1: 0, y1: 0, x2: 100, y2: 100 }),
|
|
129
|
+
).toEqual({
|
|
130
|
+
x1: 0,
|
|
131
|
+
y1: 190,
|
|
132
|
+
x2: 100,
|
|
133
|
+
y2: 310,
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
});
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* If not stated otherwise in this file or this component's LICENSE file the
|
|
3
|
+
* following copyright and licenses apply:
|
|
4
|
+
*
|
|
5
|
+
* Copyright 2023 Comcast Cable Communications Management, LLC.
|
|
6
|
+
*
|
|
7
|
+
* Licensed under the Apache License, Version 2.0 (the License);
|
|
8
|
+
* you may not use this file except in compliance with the License.
|
|
9
|
+
* You may obtain a copy of the License at
|
|
10
|
+
*
|
|
11
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
*
|
|
13
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
* See the License for the specific language governing permissions and
|
|
17
|
+
* limitations under the License.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { isBoundPositive, type Bound } from '../../../../lib/utils.js';
|
|
21
|
+
import type { TrProps } from '../../TextRenderer.js';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Create a render window from the given parameters.
|
|
25
|
+
*
|
|
26
|
+
* @remarks
|
|
27
|
+
* The render window is a rectangle that defines the area of the text that
|
|
28
|
+
* should be rendered. It is used to skip rendering parts of the text that
|
|
29
|
+
* are outside of the render window. The render window is relative to the
|
|
30
|
+
* text's top left corner of the overrall text.
|
|
31
|
+
*
|
|
32
|
+
* @param x The x coordinate of the text element's top left corner relative to the screen.
|
|
33
|
+
* @param y The y coordinate of the text element's top left corner relative to the screen.
|
|
34
|
+
* @param scrollY The amount of pixels to scroll the text vertically.
|
|
35
|
+
* @param lineHeight The height of a single line of text.
|
|
36
|
+
* @param numExtraLines The number of extra lines to render above and below the visible window.
|
|
37
|
+
* @param visibleWindow The visible window of the text element relative to the screen
|
|
38
|
+
* @returns
|
|
39
|
+
*/
|
|
40
|
+
export function makeRenderWindow(
|
|
41
|
+
x: TrProps['x'],
|
|
42
|
+
y: TrProps['y'],
|
|
43
|
+
scrollY: TrProps['scrollY'],
|
|
44
|
+
lineHeight: number,
|
|
45
|
+
numExtraLines: number,
|
|
46
|
+
visibleWindow: Bound,
|
|
47
|
+
): Bound {
|
|
48
|
+
const bufferMargin = lineHeight * numExtraLines;
|
|
49
|
+
const x1 = visibleWindow.x1 - x;
|
|
50
|
+
const y1 = visibleWindow.y1 - y;
|
|
51
|
+
return isBoundPositive(visibleWindow)
|
|
52
|
+
? {
|
|
53
|
+
x1: x1,
|
|
54
|
+
y1: y1 + scrollY - bufferMargin,
|
|
55
|
+
x2: x1 + (visibleWindow.x2 - visibleWindow.x1),
|
|
56
|
+
y2: y1 + scrollY + (visibleWindow.y2 - visibleWindow.y1) + bufferMargin,
|
|
57
|
+
}
|
|
58
|
+
: {
|
|
59
|
+
x1: 0,
|
|
60
|
+
y1: 0,
|
|
61
|
+
x2: 0,
|
|
62
|
+
y2: 0,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* If not stated otherwise in this file or this component's LICENSE file the
|
|
3
|
+
* following copyright and licenses apply:
|
|
4
|
+
*
|
|
5
|
+
* Copyright 2023 Comcast Cable Communications Management, LLC.
|
|
6
|
+
*
|
|
7
|
+
* Licensed under the Apache License, Version 2.0 (the License);
|
|
8
|
+
* you may not use this file except in compliance with the License.
|
|
9
|
+
* You may obtain a copy of the License at
|
|
10
|
+
*
|
|
11
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
*
|
|
13
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
* See the License for the specific language governing permissions and
|
|
17
|
+
* limitations under the License.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { expect, describe, it } from 'vitest';
|
|
21
|
+
import { measureText } from './measureText.js';
|
|
22
|
+
import sdfData from 'test/mockdata/Ubuntu-Bold.msdf.json';
|
|
23
|
+
import {
|
|
24
|
+
SdfFontShaper,
|
|
25
|
+
type SdfFontData,
|
|
26
|
+
} from '../../../font-face-types/SdfTrFontFace/internal/SdfFontShaper.js';
|
|
27
|
+
|
|
28
|
+
describe('measureText', () => {
|
|
29
|
+
it('should measure text width', () => {
|
|
30
|
+
const PERIOD_WIDTH = 10.332;
|
|
31
|
+
const shaper = new SdfFontShaper(sdfData as unknown as SdfFontData);
|
|
32
|
+
expect(measureText('', { letterSpacing: 0 }, shaper)).toBe(0);
|
|
33
|
+
expect(measureText('.', { letterSpacing: 0 }, shaper)).toBe(PERIOD_WIDTH);
|
|
34
|
+
expect(measureText('..', { letterSpacing: 0 }, shaper)).toBeCloseTo(
|
|
35
|
+
PERIOD_WIDTH * 2,
|
|
36
|
+
);
|
|
37
|
+
expect(measureText('..', { letterSpacing: 5 }, shaper)).toBeCloseTo(
|
|
38
|
+
PERIOD_WIDTH * 2 + 5,
|
|
39
|
+
);
|
|
40
|
+
});
|
|
41
|
+
});
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* If not stated otherwise in this file or this component's LICENSE file the
|
|
3
|
+
* following copyright and licenses apply:
|
|
4
|
+
*
|
|
5
|
+
* Copyright 2023 Comcast Cable Communications Management, LLC.
|
|
6
|
+
*
|
|
7
|
+
* Licensed under the Apache License, Version 2.0 (the License);
|
|
8
|
+
* you may not use this file except in compliance with the License.
|
|
9
|
+
* You may obtain a copy of the License at
|
|
10
|
+
*
|
|
11
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
*
|
|
13
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
* See the License for the specific language governing permissions and
|
|
17
|
+
* limitations under the License.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import type {
|
|
21
|
+
FontShaper,
|
|
22
|
+
FontShaperProps,
|
|
23
|
+
} from '../../../font-face-types/SdfTrFontFace/internal/FontShaper.js';
|
|
24
|
+
import { PeekableIterator } from './PeekableGenerator.js';
|
|
25
|
+
import { getUnicodeCodepoints } from './getUnicodeCodepoints.js';
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Measures a single-line of text width ignoring any unmapped glyphs including line breaks
|
|
29
|
+
*
|
|
30
|
+
* @param text
|
|
31
|
+
* @param shaperProps
|
|
32
|
+
* @param shaper
|
|
33
|
+
* @returns
|
|
34
|
+
*/
|
|
35
|
+
export function measureText(
|
|
36
|
+
text: string,
|
|
37
|
+
shaperProps: FontShaperProps,
|
|
38
|
+
shaper: FontShaper,
|
|
39
|
+
): number {
|
|
40
|
+
const glyphs = shaper.shapeText(
|
|
41
|
+
shaperProps,
|
|
42
|
+
new PeekableIterator(getUnicodeCodepoints(text, 0), 0),
|
|
43
|
+
);
|
|
44
|
+
let width = 0;
|
|
45
|
+
for (const glyph of glyphs) {
|
|
46
|
+
if (glyph.mapped) {
|
|
47
|
+
width += glyph.xAdvance;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return width;
|
|
51
|
+
}
|