@react-x11/components 0.9.0 → 0.10.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/README.md +10 -4
- package/dist/charts/node.d.ts +11 -1
- package/dist/charts/node.d.ts.map +1 -1
- package/dist/charts/node.js +44 -14
- package/dist/charts/node.js.map +1 -1
- package/dist/charts/render.d.ts +12 -3
- package/dist/charts/render.d.ts.map +1 -1
- package/dist/charts/render.js +94 -25
- package/dist/charts/render.js.map +1 -1
- package/dist/code/index.d.ts.map +1 -1
- package/dist/code/index.js +3 -1
- package/dist/code/index.js.map +1 -1
- package/dist/code-editor/completion.d.ts.map +1 -1
- package/dist/code-editor/completion.js +3 -2
- package/dist/code-editor/completion.js.map +1 -1
- package/dist/code-editor/index.d.ts.map +1 -1
- package/dist/code-editor/index.js +19 -0
- package/dist/code-editor/index.js.map +1 -1
- package/dist/code-editor/node.d.ts +177 -7
- package/dist/code-editor/node.d.ts.map +1 -1
- package/dist/code-editor/node.js +1329 -164
- package/dist/code-editor/node.js.map +1 -1
- package/dist/code-language/languages/glsl.d.ts.map +1 -1
- package/dist/code-language/languages/glsl.js +10 -2
- package/dist/code-language/languages/glsl.js.map +1 -1
- package/dist/code-language/languages/javascript.d.ts.map +1 -1
- package/dist/code-language/languages/javascript.js +18 -3
- package/dist/code-language/languages/javascript.js.map +1 -1
- package/dist/code-language/languages/json.d.ts.map +1 -1
- package/dist/code-language/languages/json.js +10 -2
- package/dist/code-language/languages/json.js.map +1 -1
- package/dist/code-language/languages/shell.d.ts.map +1 -1
- package/dist/code-language/languages/shell.js +10 -2
- package/dist/code-language/languages/shell.js.map +1 -1
- package/dist/code-language/languages/sql.d.ts.map +1 -1
- package/dist/code-language/languages/sql.js +20 -2
- package/dist/code-language/languages/sql.js.map +1 -1
- package/dist/code-language/stream.d.ts +22 -0
- package/dist/code-language/stream.d.ts.map +1 -1
- package/dist/code-language/stream.js +259 -9
- package/dist/code-language/stream.js.map +1 -1
- package/dist/code-language/types.d.ts +5 -4
- package/dist/code-language/types.d.ts.map +1 -1
- package/dist/codeblock/index.d.ts +13 -2
- package/dist/codeblock/index.d.ts.map +1 -1
- package/dist/codeblock/index.js +20 -3
- package/dist/codeblock/index.js.map +1 -1
- package/dist/flow/draw.d.ts +50 -0
- package/dist/flow/draw.d.ts.map +1 -1
- package/dist/flow/draw.js +132 -33
- package/dist/flow/draw.js.map +1 -1
- package/dist/flow/gl/color.d.ts +13 -0
- package/dist/flow/gl/color.d.ts.map +1 -0
- package/dist/flow/gl/color.js +82 -0
- package/dist/flow/gl/color.js.map +1 -0
- package/dist/flow/gl/index.d.ts +60 -0
- package/dist/flow/gl/index.d.ts.map +1 -0
- package/dist/flow/gl/index.js +283 -0
- package/dist/flow/gl/index.js.map +1 -0
- package/dist/flow/gl/pack.d.ts +133 -0
- package/dist/flow/gl/pack.d.ts.map +1 -0
- package/dist/flow/gl/pack.js +408 -0
- package/dist/flow/gl/pack.js.map +1 -0
- package/dist/flow/gl/renderer.d.ts +95 -0
- package/dist/flow/gl/renderer.d.ts.map +1 -0
- package/dist/flow/gl/renderer.js +459 -0
- package/dist/flow/gl/renderer.js.map +1 -0
- package/dist/flow/gl/shaders.d.ts +79 -0
- package/dist/flow/gl/shaders.d.ts.map +1 -0
- package/dist/flow/gl/shaders.js +346 -0
- package/dist/flow/gl/shaders.js.map +1 -0
- package/dist/flow/gl/text.d.ts +318 -0
- package/dist/flow/gl/text.d.ts.map +1 -0
- package/dist/flow/gl/text.js +1103 -0
- package/dist/flow/gl/text.js.map +1 -0
- package/dist/flow/index.d.ts +1 -1
- package/dist/flow/index.d.ts.map +1 -1
- package/dist/flow/index.js +619 -64
- package/dist/flow/index.js.map +1 -1
- package/dist/flow/node.d.ts +621 -72
- package/dist/flow/node.d.ts.map +1 -1
- package/dist/flow/node.js +2253 -1018
- package/dist/flow/node.js.map +1 -1
- package/dist/flow/paint.d.ts +35 -0
- package/dist/flow/paint.d.ts.map +1 -0
- package/dist/flow/paint.js +393 -0
- package/dist/flow/paint.js.map +1 -0
- package/dist/flow/paths.d.ts +14 -0
- package/dist/flow/paths.d.ts.map +1 -1
- package/dist/flow/paths.js +45 -19
- package/dist/flow/paths.js.map +1 -1
- package/dist/flow/scene.d.ts +584 -0
- package/dist/flow/scene.d.ts.map +1 -0
- package/dist/flow/scene.js +1453 -0
- package/dist/flow/scene.js.map +1 -0
- package/dist/flow/types.d.ts +111 -1
- package/dist/flow/types.d.ts.map +1 -1
- package/dist/html/controls.d.ts +28 -0
- package/dist/html/controls.d.ts.map +1 -1
- package/dist/html/controls.js +52 -2
- package/dist/html/controls.js.map +1 -1
- package/dist/html/css/calc.d.ts +14 -0
- package/dist/html/css/calc.d.ts.map +1 -0
- package/dist/html/css/calc.js +344 -0
- package/dist/html/css/calc.js.map +1 -0
- package/dist/html/css/cascade.d.ts +240 -6
- package/dist/html/css/cascade.d.ts.map +1 -1
- package/dist/html/css/cascade.js +1327 -66
- package/dist/html/css/cascade.js.map +1 -1
- package/dist/html/css/color.d.ts +23 -0
- package/dist/html/css/color.d.ts.map +1 -0
- package/dist/html/css/color.js +740 -0
- package/dist/html/css/color.js.map +1 -0
- package/dist/html/css/content.d.ts +92 -0
- package/dist/html/css/content.d.ts.map +1 -0
- package/dist/html/css/content.js +388 -0
- package/dist/html/css/content.js.map +1 -0
- package/dist/html/css/counter-styles.d.ts +76 -0
- package/dist/html/css/counter-styles.d.ts.map +1 -0
- package/dist/html/css/counter-styles.js +893 -0
- package/dist/html/css/counter-styles.js.map +1 -0
- package/dist/html/css/decode.d.ts +12 -0
- package/dist/html/css/decode.d.ts.map +1 -0
- package/dist/html/css/decode.js +116 -0
- package/dist/html/css/decode.js.map +1 -0
- package/dist/html/css/parse.d.ts +110 -10
- package/dist/html/css/parse.d.ts.map +1 -1
- package/dist/html/css/parse.js +1473 -180
- package/dist/html/css/parse.js.map +1 -1
- package/dist/html/css/style.d.ts +498 -15
- package/dist/html/css/style.d.ts.map +1 -1
- package/dist/html/css/style.js +3698 -206
- package/dist/html/css/style.js.map +1 -1
- package/dist/html/css/ua.d.ts.map +1 -1
- package/dist/html/css/ua.js +57 -11
- package/dist/html/css/ua.js.map +1 -1
- package/dist/html/css/values.d.ts +37 -3
- package/dist/html/css/values.d.ts.map +1 -1
- package/dist/html/css/values.js +122 -48
- package/dist/html/css/values.js.map +1 -1
- package/dist/html/css/vars.d.ts +52 -0
- package/dist/html/css/vars.d.ts.map +1 -0
- package/dist/html/css/vars.js +358 -0
- package/dist/html/css/vars.js.map +1 -0
- package/dist/html/dom.d.ts +30 -4
- package/dist/html/dom.d.ts.map +1 -1
- package/dist/html/dom.js +278 -17
- package/dist/html/dom.js.map +1 -1
- package/dist/html/fonts.d.ts +106 -0
- package/dist/html/fonts.d.ts.map +1 -0
- package/dist/html/fonts.js +565 -0
- package/dist/html/fonts.js.map +1 -0
- package/dist/html/gif.d.ts +15 -0
- package/dist/html/gif.d.ts.map +1 -0
- package/dist/html/gif.js +229 -0
- package/dist/html/gif.js.map +1 -0
- package/dist/html/index.d.ts +50 -11
- package/dist/html/index.d.ts.map +1 -1
- package/dist/html/index.js +115 -9
- package/dist/html/index.js.map +1 -1
- package/dist/html/layout/block.d.ts +226 -3
- package/dist/html/layout/block.d.ts.map +1 -1
- package/dist/html/layout/block.js +2937 -197
- package/dist/html/layout/block.js.map +1 -1
- package/dist/html/layout/boxes.d.ts +340 -17
- package/dist/html/layout/boxes.d.ts.map +1 -1
- package/dist/html/layout/boxes.js +1714 -182
- package/dist/html/layout/boxes.js.map +1 -1
- package/dist/html/layout/cache.d.ts +58 -0
- package/dist/html/layout/cache.d.ts.map +1 -0
- package/dist/html/layout/cache.js +224 -0
- package/dist/html/layout/cache.js.map +1 -0
- package/dist/html/layout/collapse.d.ts +45 -0
- package/dist/html/layout/collapse.d.ts.map +1 -0
- package/dist/html/layout/collapse.js +246 -0
- package/dist/html/layout/collapse.js.map +1 -0
- package/dist/html/layout/css-grid.d.ts +7 -0
- package/dist/html/layout/css-grid.d.ts.map +1 -0
- package/dist/html/layout/css-grid.js +900 -0
- package/dist/html/layout/css-grid.js.map +1 -0
- package/dist/html/layout/flex.d.ts.map +1 -1
- package/dist/html/layout/flex.js +1025 -89
- package/dist/html/layout/flex.js.map +1 -1
- package/dist/html/layout/floats.d.ts +45 -6
- package/dist/html/layout/floats.d.ts.map +1 -1
- package/dist/html/layout/floats.js +113 -14
- package/dist/html/layout/floats.js.map +1 -1
- package/dist/html/layout/grid-lines.d.ts +39 -0
- package/dist/html/layout/grid-lines.d.ts.map +1 -0
- package/dist/html/layout/grid-lines.js +119 -0
- package/dist/html/layout/grid-lines.js.map +1 -0
- package/dist/html/layout/grid.d.ts +53 -0
- package/dist/html/layout/grid.d.ts.map +1 -0
- package/dist/html/layout/grid.js +153 -0
- package/dist/html/layout/grid.js.map +1 -0
- package/dist/html/layout/inline.d.ts +151 -1
- package/dist/html/layout/inline.d.ts.map +1 -1
- package/dist/html/layout/inline.js +3375 -174
- package/dist/html/layout/inline.js.map +1 -1
- package/dist/html/layout/shaping.d.ts +6 -0
- package/dist/html/layout/shaping.d.ts.map +1 -0
- package/dist/html/layout/shaping.js +100 -0
- package/dist/html/layout/shaping.js.map +1 -0
- package/dist/html/layout/table.d.ts +3 -0
- package/dist/html/layout/table.d.ts.map +1 -1
- package/dist/html/layout/table.js +681 -175
- package/dist/html/layout/table.js.map +1 -1
- package/dist/html/layout/tracks.d.ts +44 -0
- package/dist/html/layout/tracks.d.ts.map +1 -0
- package/dist/html/layout/tracks.js +349 -0
- package/dist/html/layout/tracks.js.map +1 -0
- package/dist/html/node.d.ts +169 -4
- package/dist/html/node.d.ts.map +1 -1
- package/dist/html/node.js +1331 -100
- package/dist/html/node.js.map +1 -1
- package/dist/html/paint.d.ts +92 -3
- package/dist/html/paint.d.ts.map +1 -1
- package/dist/html/paint.js +3503 -141
- package/dist/html/paint.js.map +1 -1
- package/dist/html/resources.d.ts +60 -14
- package/dist/html/resources.d.ts.map +1 -1
- package/dist/html/resources.js +122 -36
- package/dist/html/resources.js.map +1 -1
- package/dist/html/surfaces.d.ts +23 -0
- package/dist/html/surfaces.d.ts.map +1 -0
- package/dist/html/surfaces.js +68 -0
- package/dist/html/surfaces.js.map +1 -0
- package/dist/html/svg.d.ts +80 -0
- package/dist/html/svg.d.ts.map +1 -0
- package/dist/html/svg.js +435 -0
- package/dist/html/svg.js.map +1 -0
- package/dist/html/url.d.ts +23 -0
- package/dist/html/url.d.ts.map +1 -0
- package/dist/html/url.js +80 -0
- package/dist/html/url.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/internal/collate.d.ts +3 -0
- package/dist/internal/collate.d.ts.map +1 -0
- package/dist/internal/collate.js +11 -0
- package/dist/internal/collate.js.map +1 -0
- package/dist/internal/markdown/ast.d.ts +11 -0
- package/dist/internal/markdown/ast.d.ts.map +1 -1
- package/dist/internal/markdown/parse.d.ts.map +1 -1
- package/dist/internal/markdown/parse.js +109 -8
- package/dist/internal/markdown/parse.js.map +1 -1
- package/dist/internal/prewarm.d.ts +18 -0
- package/dist/internal/prewarm.d.ts.map +1 -0
- package/dist/internal/prewarm.js +42 -0
- package/dist/internal/prewarm.js.map +1 -0
- package/dist/internal/sdf.d.ts +20 -0
- package/dist/internal/sdf.d.ts.map +1 -0
- package/dist/internal/sdf.js +216 -0
- package/dist/internal/sdf.js.map +1 -0
- package/dist/internal/splice.d.ts +12 -0
- package/dist/internal/splice.d.ts.map +1 -0
- package/dist/internal/splice.js +23 -0
- package/dist/internal/splice.js.map +1 -0
- package/dist/internal/window.d.ts +12 -0
- package/dist/internal/window.d.ts.map +1 -1
- package/dist/internal/window.js +23 -6
- package/dist/internal/window.js.map +1 -1
- package/dist/maps/anchors.d.ts +6 -1
- package/dist/maps/anchors.d.ts.map +1 -1
- package/dist/maps/anchors.js +260 -1
- package/dist/maps/anchors.js.map +1 -1
- package/dist/maps/controller.d.ts +57 -0
- package/dist/maps/controller.d.ts.map +1 -1
- package/dist/maps/controller.js +97 -18
- package/dist/maps/controller.js.map +1 -1
- package/dist/maps/gl/buckets.d.ts +5 -1
- package/dist/maps/gl/buckets.d.ts.map +1 -1
- package/dist/maps/gl/buckets.js +5 -2
- package/dist/maps/gl/buckets.js.map +1 -1
- package/dist/maps/gl/build-worker.d.ts +2 -0
- package/dist/maps/gl/build-worker.d.ts.map +1 -1
- package/dist/maps/gl/build-worker.js +1 -1
- package/dist/maps/gl/build-worker.js.map +1 -1
- package/dist/maps/gl/cover.d.ts +23 -4
- package/dist/maps/gl/cover.d.ts.map +1 -1
- package/dist/maps/gl/cover.js +61 -48
- package/dist/maps/gl/cover.js.map +1 -1
- package/dist/maps/gl/placement.d.ts +21 -8
- package/dist/maps/gl/placement.d.ts.map +1 -1
- package/dist/maps/gl/placement.js +133 -58
- package/dist/maps/gl/placement.js.map +1 -1
- package/dist/maps/gl/renderer.d.ts +36 -4
- package/dist/maps/gl/renderer.d.ts.map +1 -1
- package/dist/maps/gl/renderer.js +81 -24
- package/dist/maps/gl/renderer.js.map +1 -1
- package/dist/maps/gl/shaders.d.ts +18 -17
- package/dist/maps/gl/shaders.d.ts.map +1 -1
- package/dist/maps/gl/shaders.js +34 -32
- package/dist/maps/gl/shaders.js.map +1 -1
- package/dist/maps/gl/store.d.ts +10 -0
- package/dist/maps/gl/store.d.ts.map +1 -1
- package/dist/maps/gl/store.js +47 -4
- package/dist/maps/gl/store.js.map +1 -1
- package/dist/maps/gl/text.d.ts +153 -24
- package/dist/maps/gl/text.d.ts.map +1 -1
- package/dist/maps/gl/text.js +379 -63
- package/dist/maps/gl/text.js.map +1 -1
- package/dist/maps/gl/view.d.ts +293 -2
- package/dist/maps/gl/view.d.ts.map +1 -1
- package/dist/maps/gl/view.js +317 -82
- package/dist/maps/gl/view.js.map +1 -1
- package/dist/maps/icons.d.ts +32 -0
- package/dist/maps/icons.d.ts.map +1 -0
- package/dist/maps/icons.js +151 -0
- package/dist/maps/icons.js.map +1 -0
- package/dist/maps/index.d.ts +2 -0
- package/dist/maps/index.d.ts.map +1 -1
- package/dist/maps/index.js +2 -0
- package/dist/maps/index.js.map +1 -1
- package/dist/maps/labels.d.ts +56 -4
- package/dist/maps/labels.d.ts.map +1 -1
- package/dist/maps/labels.js +213 -46
- package/dist/maps/labels.js.map +1 -1
- package/dist/maps/node.d.ts +17 -0
- package/dist/maps/node.d.ts.map +1 -1
- package/dist/maps/node.js +64 -30
- package/dist/maps/node.js.map +1 -1
- package/dist/maps/proj.d.ts +48 -0
- package/dist/maps/proj.d.ts.map +1 -1
- package/dist/maps/proj.js +73 -0
- package/dist/maps/proj.js.map +1 -1
- package/dist/maps/sources.d.ts +5 -3
- package/dist/maps/sources.d.ts.map +1 -1
- package/dist/maps/sources.js +5 -3
- package/dist/maps/sources.js.map +1 -1
- package/dist/maps/style.d.ts +35 -0
- package/dist/maps/style.d.ts.map +1 -1
- package/dist/maps/style.js.map +1 -1
- package/dist/maps/styles.d.ts +12 -0
- package/dist/maps/styles.d.ts.map +1 -1
- package/dist/maps/styles.js +120 -6
- package/dist/maps/styles.js.map +1 -1
- package/dist/maps/tiles.d.ts +31 -11
- package/dist/maps/tiles.d.ts.map +1 -1
- package/dist/maps/tiles.js +61 -27
- package/dist/maps/tiles.js.map +1 -1
- package/dist/maps/types.d.ts +28 -4
- package/dist/maps/types.d.ts.map +1 -1
- package/dist/markdown/index.d.ts.map +1 -1
- package/dist/markdown/index.js +112 -43
- package/dist/markdown/index.js.map +1 -1
- package/dist/markdown/spans.d.ts.map +1 -1
- package/dist/markdown/spans.js +6 -0
- package/dist/markdown/spans.js.map +1 -1
- package/dist/qml/containers.d.ts.map +1 -1
- package/dist/qml/containers.js +6 -1
- package/dist/qml/containers.js.map +1 -1
- package/dist/qml/interaction.d.ts.map +1 -1
- package/dist/qml/interaction.js +38 -5
- package/dist/qml/interaction.js.map +1 -1
- package/dist/qml/layouts.d.ts.map +1 -1
- package/dist/qml/layouts.js +21 -6
- package/dist/qml/layouts.js.map +1 -1
- package/dist/qml/qtquick.d.ts.map +1 -1
- package/dist/qml/qtquick.js +9 -2
- package/dist/qml/qtquick.js.map +1 -1
- package/dist/qml/react.d.ts.map +1 -1
- package/dist/qml/react.js +9 -7
- package/dist/qml/react.js.map +1 -1
- package/dist/reorder/clock.d.ts +7 -0
- package/dist/reorder/clock.d.ts.map +1 -0
- package/dist/reorder/clock.js +26 -0
- package/dist/reorder/clock.js.map +1 -0
- package/dist/reorder/index.d.ts +25 -3
- package/dist/reorder/index.d.ts.map +1 -1
- package/dist/reorder/index.js +64 -19
- package/dist/reorder/index.js.map +1 -1
- package/dist/rich-text-editor/index.d.ts +0 -11
- package/dist/rich-text-editor/index.d.ts.map +1 -1
- package/dist/rich-text-editor/index.js +35 -1
- package/dist/rich-text-editor/index.js.map +1 -1
- package/dist/rich-text-editor/keymap.d.ts.map +1 -1
- package/dist/rich-text-editor/keymap.js +2 -1
- package/dist/rich-text-editor/keymap.js.map +1 -1
- package/dist/rich-text-editor/keys.d.ts +17 -6
- package/dist/rich-text-editor/keys.d.ts.map +1 -1
- package/dist/rich-text-editor/keys.js +135 -26
- package/dist/rich-text-editor/keys.js.map +1 -1
- package/dist/rich-text-editor/marks.d.ts +9 -0
- package/dist/rich-text-editor/marks.d.ts.map +1 -0
- package/dist/rich-text-editor/marks.js +83 -0
- package/dist/rich-text-editor/marks.js.map +1 -0
- package/dist/rich-text-editor/render.d.ts.map +1 -1
- package/dist/rich-text-editor/render.js +28 -10
- package/dist/rich-text-editor/render.js.map +1 -1
- package/dist/rich-text-editor/toolbar.d.ts.map +1 -1
- package/dist/rich-text-editor/toolbar.js +1 -1
- package/dist/rich-text-editor/toolbar.js.map +1 -1
- package/dist/rich-text-editor/virtual.d.ts.map +1 -1
- package/dist/rich-text-editor/virtual.js +17 -0
- package/dist/rich-text-editor/virtual.js.map +1 -1
- package/dist/richtext/node.d.ts +46 -2
- package/dist/richtext/node.d.ts.map +1 -1
- package/dist/richtext/node.js +187 -4
- package/dist/richtext/node.js.map +1 -1
- package/dist/richtext/runs.d.ts +13 -8
- package/dist/richtext/runs.d.ts.map +1 -1
- package/dist/richtext/runs.js +18 -8
- package/dist/richtext/runs.js.map +1 -1
- package/dist/table/index.d.ts.map +1 -1
- package/dist/table/index.js +23 -0
- package/dist/table/index.js.map +1 -1
- package/dist/table/rows.d.ts +3 -2
- package/dist/table/rows.d.ts.map +1 -1
- package/dist/table/rows.js +20 -6
- package/dist/table/rows.js.map +1 -1
- package/dist/terminal/index.d.ts.map +1 -1
- package/dist/terminal/index.js +4 -0
- package/dist/terminal/index.js.map +1 -1
- package/dist/terminal/vt/pty.d.ts +13 -2
- package/dist/terminal/vt/pty.d.ts.map +1 -1
- package/dist/terminal/vt/pty.js +18 -3
- package/dist/terminal/vt/pty.js.map +1 -1
- package/dist/terminal-output/index.d.ts.map +1 -1
- package/dist/terminal-output/index.js +6 -1
- package/dist/terminal-output/index.js.map +1 -1
- package/dist/three/canvas.d.ts.map +1 -1
- package/dist/three/canvas.js +85 -7
- package/dist/three/canvas.js.map +1 -1
- package/dist/three/events.d.ts +22 -4
- package/dist/three/events.d.ts.map +1 -1
- package/dist/three/events.js +34 -4
- package/dist/three/events.js.map +1 -1
- package/dist/tree/index.d.ts.map +1 -1
- package/dist/tree/index.js +17 -0
- package/dist/tree/index.js.map +1 -1
- package/package.json +42 -33
- package/src/charts/node.ts +62 -26
- package/src/charts/render.ts +120 -30
- package/src/code/index.ts +3 -1
- package/src/code-editor/completion.ts +3 -2
- package/src/code-editor/index.ts +19 -0
- package/src/code-editor/node.ts +1574 -184
- package/src/code-language/languages/glsl.ts +12 -2
- package/src/code-language/languages/javascript.ts +21 -4
- package/src/code-language/languages/json.ts +12 -2
- package/src/code-language/languages/shell.ts +12 -2
- package/src/code-language/languages/sql.ts +22 -2
- package/src/code-language/stream.ts +257 -17
- package/src/code-language/types.ts +5 -4
- package/src/codeblock/index.ts +20 -3
- package/src/flow/draw.ts +167 -41
- package/src/flow/gl/color.ts +85 -0
- package/src/flow/gl/index.ts +342 -0
- package/src/flow/gl/pack.ts +585 -0
- package/src/flow/gl/renderer.ts +679 -0
- package/src/flow/gl/shaders.ts +371 -0
- package/src/flow/gl/text.ts +1295 -0
- package/src/flow/index.ts +794 -67
- package/src/flow/node.ts +2496 -1256
- package/src/flow/paint.ts +511 -0
- package/src/flow/paths.ts +80 -15
- package/src/flow/scene.ts +2199 -0
- package/src/flow/types.ts +113 -1
- package/src/html/controls.ts +73 -2
- package/src/html/css/calc.ts +385 -0
- package/src/html/css/cascade.ts +1403 -62
- package/src/html/css/color.ts +755 -0
- package/src/html/css/content.ts +417 -0
- package/src/html/css/counter-styles.ts +973 -0
- package/src/html/css/decode.ts +130 -0
- package/src/html/css/parse.ts +1514 -160
- package/src/html/css/style.ts +4102 -222
- package/src/html/css/ua.ts +58 -12
- package/src/html/css/values.ts +150 -50
- package/src/html/css/vars.ts +348 -0
- package/src/html/dom.ts +284 -17
- package/src/html/fonts.ts +641 -0
- package/src/html/gif.ts +233 -0
- package/src/html/index.ts +180 -20
- package/src/html/layout/block.ts +3456 -230
- package/src/html/layout/boxes.ts +2100 -190
- package/src/html/layout/cache.ts +289 -0
- package/src/html/layout/collapse.ts +317 -0
- package/src/html/layout/css-grid.ts +1063 -0
- package/src/html/layout/flex.ts +1115 -106
- package/src/html/layout/floats.ts +128 -14
- package/src/html/layout/grid-lines.ts +141 -0
- package/src/html/layout/grid.ts +181 -0
- package/src/html/layout/inline.ts +3943 -192
- package/src/html/layout/shaping.ts +140 -0
- package/src/html/layout/table.ts +696 -186
- package/src/html/layout/tracks.ts +437 -0
- package/src/html/node.ts +1481 -118
- package/src/html/paint.ts +4293 -169
- package/src/html/resources.ts +161 -50
- package/src/html/surfaces.ts +81 -0
- package/src/html/svg.ts +493 -0
- package/src/html/url.ts +86 -0
- package/src/index.ts +2 -0
- package/src/internal/collate.ts +12 -0
- package/src/internal/markdown/ast.ts +11 -0
- package/src/internal/markdown/parse.ts +154 -11
- package/src/internal/prewarm.ts +45 -0
- package/src/internal/sdf.ts +227 -0
- package/src/internal/splice.ts +25 -0
- package/src/internal/window.ts +36 -5
- package/src/maps/anchors.ts +307 -1
- package/src/maps/controller.ts +116 -31
- package/src/maps/gl/buckets.ts +5 -1
- package/src/maps/gl/build-worker.ts +13 -2
- package/src/maps/gl/cover.ts +79 -44
- package/src/maps/gl/placement.ts +221 -69
- package/src/maps/gl/renderer.ts +104 -20
- package/src/maps/gl/shaders.ts +35 -32
- package/src/maps/gl/store.ts +66 -17
- package/src/maps/gl/text.ts +444 -71
- package/src/maps/gl/view.ts +361 -96
- package/src/maps/icons.ts +183 -0
- package/src/maps/index.ts +4 -0
- package/src/maps/labels.ts +269 -49
- package/src/maps/node.ts +82 -49
- package/src/maps/proj.ts +87 -0
- package/src/maps/sources.ts +5 -3
- package/src/maps/style.ts +32 -0
- package/src/maps/styles.ts +215 -4
- package/src/maps/tiles.ts +64 -31
- package/src/maps/types.ts +28 -4
- package/src/markdown/index.ts +149 -67
- package/src/markdown/spans.ts +5 -0
- package/src/qml/containers.tsx +6 -1
- package/src/qml/interaction.tsx +42 -5
- package/src/qml/layouts.tsx +21 -6
- package/src/qml/qtquick.tsx +9 -2
- package/src/qml/react.tsx +7 -5
- package/src/reorder/clock.ts +27 -0
- package/src/reorder/index.ts +100 -27
- package/src/rich-text-editor/index.ts +34 -1
- package/src/rich-text-editor/keymap.ts +1 -1
- package/src/rich-text-editor/keys.ts +135 -26
- package/src/rich-text-editor/marks.ts +101 -0
- package/src/rich-text-editor/render.ts +49 -12
- package/src/rich-text-editor/toolbar.ts +1 -1
- package/src/rich-text-editor/virtual.ts +25 -0
- package/src/richtext/node.ts +235 -14
- package/src/richtext/runs.ts +23 -12
- package/src/table/index.ts +29 -0
- package/src/table/rows.ts +18 -8
- package/src/terminal/index.ts +4 -0
- package/src/terminal/vt/pty.ts +16 -2
- package/src/terminal-output/index.ts +6 -1
- package/src/three/canvas.ts +102 -8
- package/src/three/events.ts +49 -9
- package/src/tree/index.ts +19 -0
package/src/maps/gl/text.ts
CHANGED
|
@@ -13,30 +13,54 @@
|
|
|
13
13
|
// A label is rasterized **whole**, not glyph by glyph: placement sets every
|
|
14
14
|
// line label on a straight stretch, so a label is one rigid piece of type —
|
|
15
15
|
// one textured quad, rotated as a unit — and shaping, kerning and scripts
|
|
16
|
-
// stay the text engine's business.
|
|
17
|
-
//
|
|
18
|
-
//
|
|
19
|
-
//
|
|
16
|
+
// stay the text engine's business.
|
|
17
|
+
//
|
|
18
|
+
// **One raster per string, at every size.** The engine sets a string once,
|
|
19
|
+
// at the atlas's `base` size, as coverage; what is stored is its signed
|
|
20
|
+
// distance field (`src/internal/sdf.ts`), one byte a texel. A name drawn at 11 pixels
|
|
21
|
+
// and the same name at 20 are one raster scaled, so a zoom ramp that grows
|
|
22
|
+
// the type asks for nothing new, and a halo of any width is a threshold on
|
|
23
|
+
// the same distances. Colour and halo are the shader's (see `./shaders.ts`),
|
|
24
|
+
// so one raster serves every palette and a light-to-dark switch
|
|
25
|
+
// re-rasterizes nothing. What it costs is the engine's hinting — the text
|
|
26
|
+
// is its outline, scaled — which at map-label sizes is the right trade:
|
|
27
|
+
// one shaping and one readback per name for the life of the atlas.
|
|
28
|
+
//
|
|
29
|
+
// An icon's two pieces (`../icons.ts`) are fields here too, drawn as
|
|
30
|
+
// coverage from the same paths the retained renderer fills, at the same
|
|
31
|
+
// base size, and coloured by the same shader.
|
|
20
32
|
import { Surface } from 'react-x11/ntk';
|
|
21
33
|
|
|
34
|
+
import { traceGlyph, tracePlate } from '../icons.js';
|
|
35
|
+
import type { IconPathContext, MapIcon } from '../icons.js';
|
|
36
|
+
import { SDF_EDGE, distanceField } from '../../internal/sdf.js';
|
|
37
|
+
|
|
22
38
|
/** A set string's box, in device pixels. */
|
|
23
39
|
export interface TextBox {
|
|
24
40
|
width: number;
|
|
25
41
|
height: number;
|
|
26
42
|
}
|
|
27
43
|
|
|
28
|
-
/**
|
|
44
|
+
/** Which of an icon's two single-colour rasters. */
|
|
45
|
+
export type IconPart = 'plate' | 'glyph';
|
|
46
|
+
|
|
47
|
+
/** One string to set, at `size` device pixels — or, with `icon`, one piece
|
|
48
|
+
* of an icon `size` pixels across, and `text` empty. */
|
|
29
49
|
export interface TextItem {
|
|
30
50
|
text: string;
|
|
31
51
|
size: number;
|
|
52
|
+
icon?: { name: MapIcon; part: IconPart };
|
|
32
53
|
}
|
|
33
54
|
|
|
34
|
-
/** A rasterized string
|
|
35
|
-
*
|
|
55
|
+
/** A rasterized string, `pad` pixels of clear margin included: RGBA as
|
|
56
|
+
* read back, coverage in alpha — or, with `stride` 1, the text engine's own
|
|
57
|
+
* coverage, one byte a pixel. */
|
|
36
58
|
export interface TextRaster {
|
|
37
59
|
width: number;
|
|
38
60
|
height: number;
|
|
39
61
|
pixels: Uint8Array;
|
|
62
|
+
/** Bytes a pixel: 4 (the default) for a readback, 1 for coverage. */
|
|
63
|
+
stride?: 1 | 4;
|
|
40
64
|
}
|
|
41
65
|
|
|
42
66
|
/** What the atlas asks of a text engine. */
|
|
@@ -52,6 +76,13 @@ export interface TextEngine {
|
|
|
52
76
|
items: readonly TextItem[],
|
|
53
77
|
pad: number,
|
|
54
78
|
): Promise<(TextRaster | null | undefined)[]>;
|
|
79
|
+
/**
|
|
80
|
+
* One item set now, synchronously, where the engine can: a raster;
|
|
81
|
+
* `null` for one that can never be drawn; `undefined` for one it can only
|
|
82
|
+
* set through {@link rasterize} (an icon's paths, or an engine whose
|
|
83
|
+
* layouts answer no coverage of their own). Optional.
|
|
84
|
+
*/
|
|
85
|
+
rasterizeNow?(item: TextItem, pad: number): TextRaster | null | undefined;
|
|
55
86
|
dispose(): void;
|
|
56
87
|
}
|
|
57
88
|
|
|
@@ -64,6 +95,12 @@ interface FontsLike {
|
|
|
64
95
|
width: number;
|
|
65
96
|
height: number;
|
|
66
97
|
draw(ctx: unknown, x: number, y: number): void;
|
|
98
|
+
/** The engine's own coverage of the layout, one byte a pixel, with
|
|
99
|
+
* `pad` round its box — where the engine answers it
|
|
100
|
+
* (sidorares/react-x11#673). */
|
|
101
|
+
coverage?(options?: {
|
|
102
|
+
pad?: number;
|
|
103
|
+
}): { width: number; height: number; data: Uint8Array } | null;
|
|
67
104
|
};
|
|
68
105
|
}
|
|
69
106
|
|
|
@@ -73,9 +110,22 @@ interface ImageLike {
|
|
|
73
110
|
height: number;
|
|
74
111
|
}
|
|
75
112
|
|
|
76
|
-
interface ContextLike {
|
|
113
|
+
interface ContextLike extends Partial<IconPathContext> {
|
|
77
114
|
getImageData(x: number, y: number, w: number, h: number): Promise<ImageLike>;
|
|
78
115
|
destroy?(): void;
|
|
116
|
+
fillStyle?: unknown;
|
|
117
|
+
fill?(): void;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/** Whether a context can fill a path — what an icon is drawn with. */
|
|
121
|
+
function fills(
|
|
122
|
+
ctx: ContextLike,
|
|
123
|
+
): ctx is ContextLike & IconPathContext & { fill(): void } {
|
|
124
|
+
return (
|
|
125
|
+
typeof ctx.beginPath === 'function' &&
|
|
126
|
+
typeof ctx.arc === 'function' &&
|
|
127
|
+
typeof ctx.fill === 'function'
|
|
128
|
+
);
|
|
79
129
|
}
|
|
80
130
|
|
|
81
131
|
interface SurfaceLike {
|
|
@@ -104,6 +154,9 @@ export class SurfaceTextEngine implements TextEngine {
|
|
|
104
154
|
>();
|
|
105
155
|
private _surface: SurfaceLike | null = null;
|
|
106
156
|
private _ctx: ContextLike | null = null;
|
|
157
|
+
/** Whether the layouts answer their own coverage: unknown until a string
|
|
158
|
+
* asks, and false for good once one does not. */
|
|
159
|
+
private _coverage: boolean | null = null;
|
|
107
160
|
|
|
108
161
|
constructor(app: unknown, fonts: FontsLike, family: string) {
|
|
109
162
|
this._app = app;
|
|
@@ -143,9 +196,64 @@ export class SurfaceTextEngine implements TextEngine {
|
|
|
143
196
|
return { width: Math.ceil(layout.width), height: Math.ceil(layout.height) };
|
|
144
197
|
}
|
|
145
198
|
|
|
199
|
+
/**
|
|
200
|
+
* Strings the layouts set themselves, where the engine answers a layout's
|
|
201
|
+
* coverage (react-x11#673): no staging surface and no readback. The rest —
|
|
202
|
+
* icons, which are paths, and every string on an engine that cannot — go
|
|
203
|
+
* through the surface.
|
|
204
|
+
*/
|
|
205
|
+
/**
|
|
206
|
+
* A string the layout sets itself, synchronously, where the engine
|
|
207
|
+
* answers a layout's coverage — no surface, no readback, nothing to wait
|
|
208
|
+
* for. `undefined` for an icon, and for every string once the engine has
|
|
209
|
+
* shown it cannot.
|
|
210
|
+
*/
|
|
211
|
+
rasterizeNow(item: TextItem, pad: number): TextRaster | null | undefined {
|
|
212
|
+
if (item.icon || this._coverage === false) return undefined;
|
|
213
|
+
const coverage =
|
|
214
|
+
this._layout(item.text, item.size).coverage?.({ pad }) ?? null;
|
|
215
|
+
if (!coverage) {
|
|
216
|
+
if (this._coverage === null) this._coverage = false;
|
|
217
|
+
return undefined;
|
|
218
|
+
}
|
|
219
|
+
this._coverage = true;
|
|
220
|
+
return coverage.width > STAGING_WIDTH || coverage.height > STAGING_HEIGHT
|
|
221
|
+
? null // wider than the surface could set: never drawn, as there
|
|
222
|
+
: {
|
|
223
|
+
width: coverage.width,
|
|
224
|
+
height: coverage.height,
|
|
225
|
+
pixels: coverage.data,
|
|
226
|
+
stride: 1,
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
|
|
146
230
|
async rasterize(
|
|
147
231
|
items: readonly TextItem[],
|
|
148
232
|
pad: number,
|
|
233
|
+
): Promise<(TextRaster | null | undefined)[]> {
|
|
234
|
+
if (this._coverage === false) return this._stage(items, pad);
|
|
235
|
+
const out: (TextRaster | null | undefined)[] = new Array(items.length);
|
|
236
|
+
const rest: number[] = [];
|
|
237
|
+
items.forEach((item, i) => {
|
|
238
|
+
const raster = this.rasterizeNow(item, pad);
|
|
239
|
+
if (raster === undefined) {
|
|
240
|
+
rest.push(i);
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
out[i] = raster;
|
|
244
|
+
});
|
|
245
|
+
if (rest.length === 0) return out;
|
|
246
|
+
const staged = await this._stage(
|
|
247
|
+
rest.map((i) => items[i]),
|
|
248
|
+
pad,
|
|
249
|
+
);
|
|
250
|
+
rest.forEach((i, k) => (out[i] = staged[k]));
|
|
251
|
+
return out;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
private async _stage(
|
|
255
|
+
items: readonly TextItem[],
|
|
256
|
+
pad: number,
|
|
149
257
|
): Promise<(TextRaster | null | undefined)[]> {
|
|
150
258
|
const places: (
|
|
151
259
|
{ x: number; y: number; w: number; h: number } | null | undefined
|
|
@@ -154,7 +262,9 @@ export class SurfaceTextEngine implements TextEngine {
|
|
|
154
262
|
let y = 0;
|
|
155
263
|
let row = 0;
|
|
156
264
|
for (const item of items) {
|
|
157
|
-
const box =
|
|
265
|
+
const box = item.icon
|
|
266
|
+
? { width: Math.ceil(item.size), height: Math.ceil(item.size) }
|
|
267
|
+
: this.measure(item.text, item.size);
|
|
158
268
|
const w = box.width + pad * 2;
|
|
159
269
|
const h = box.height + pad * 2;
|
|
160
270
|
if (w > STAGING_WIDTH || h > STAGING_HEIGHT) {
|
|
@@ -191,22 +301,48 @@ export class SurfaceTextEngine implements TextEngine {
|
|
|
191
301
|
const started = now();
|
|
192
302
|
// The rows drawn into: what is read back, and no more.
|
|
193
303
|
let used = 0;
|
|
304
|
+
let drawn = 0;
|
|
194
305
|
items.forEach((item, i) => {
|
|
195
306
|
const place = places[i];
|
|
196
307
|
if (!place) return;
|
|
197
308
|
// Drawing is this thread's time; past the budget the rest wait for
|
|
198
|
-
// the next batch.
|
|
199
|
-
|
|
309
|
+
// the next batch — all but the first. A pause before it, a collection
|
|
310
|
+
// or a slow runner, deferred every string: nothing drawn, a readback of
|
|
311
|
+
// no rows, and a throw out of the frame; and a machine that slow would
|
|
312
|
+
// never have set one.
|
|
313
|
+
if (drawn > 0 && now() - started > DRAW_BUDGET_MS) {
|
|
200
314
|
places[i] = undefined;
|
|
201
315
|
return;
|
|
202
316
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
317
|
+
if (item.icon) {
|
|
318
|
+
// White, like the strings: coverage, coloured by the shader.
|
|
319
|
+
if (!fills(ctx)) {
|
|
320
|
+
places[i] = null;
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
const half = item.size / 2;
|
|
324
|
+
const cx = place.x + pad + half;
|
|
325
|
+
const cy = place.y + pad + half;
|
|
326
|
+
ctx.fillStyle = '#ffffff';
|
|
327
|
+
ctx.beginPath();
|
|
328
|
+
if (item.icon.part === 'plate') tracePlate(ctx, cx, cy, item.size);
|
|
329
|
+
else traceGlyph(ctx, item.icon.name, cx, cy, item.size);
|
|
330
|
+
ctx.fill();
|
|
331
|
+
} else {
|
|
332
|
+
this._layout(item.text, item.size).draw(
|
|
333
|
+
ctx,
|
|
334
|
+
place.x + pad,
|
|
335
|
+
place.y + pad,
|
|
336
|
+
);
|
|
337
|
+
}
|
|
208
338
|
used = Math.max(used, place.y + place.h);
|
|
339
|
+
drawn += 1;
|
|
209
340
|
});
|
|
341
|
+
// nothing drawn — every icon here had nothing to fill with — is nothing
|
|
342
|
+
// to read back
|
|
343
|
+
if (drawn === 0) {
|
|
344
|
+
return places.map((p) => (p === null ? null : undefined));
|
|
345
|
+
}
|
|
210
346
|
const image = await ctx.getImageData(0, 0, STAGING_WIDTH, used);
|
|
211
347
|
return places.map((place) => {
|
|
212
348
|
if (!place) return place;
|
|
@@ -238,8 +374,8 @@ export interface AtlasEntry {
|
|
|
238
374
|
y: number;
|
|
239
375
|
width: number;
|
|
240
376
|
height: number;
|
|
241
|
-
/** The
|
|
242
|
-
* into the texture of a new context. */
|
|
377
|
+
/** The distance field, one byte a texel — kept to upload again, after a
|
|
378
|
+
* compaction moves it or into the texture of a new context. */
|
|
243
379
|
pixels: Uint8Array;
|
|
244
380
|
/** In the texture where it is now; only then is it drawn. Set by the
|
|
245
381
|
* renderer that uploads it. */
|
|
@@ -248,18 +384,37 @@ export interface AtlasEntry {
|
|
|
248
384
|
used: number;
|
|
249
385
|
}
|
|
250
386
|
|
|
251
|
-
|
|
387
|
+
/** A string's key: the text alone, because one field serves every size. */
|
|
388
|
+
const keyOf = (text: string): string => `|${text}`;
|
|
389
|
+
/** An icon piece's key: `#` where a string's has `|`, so no string can
|
|
390
|
+
* be taken for one. */
|
|
391
|
+
const iconKey = (name: MapIcon, part: IconPart): string => `#${part}:${name}`;
|
|
252
392
|
|
|
253
393
|
/**
|
|
254
|
-
*
|
|
255
|
-
*
|
|
256
|
-
*
|
|
257
|
-
* margin and never reach a neighbour's.
|
|
394
|
+
* Texels the drawn quad leaves off each side of a field: bilinear samples
|
|
395
|
+
* at its edge then stay inside the field's own margin, never reaching the
|
|
396
|
+
* shelf's unwritten rows or a neighbour.
|
|
258
397
|
*/
|
|
259
|
-
export const
|
|
260
|
-
Math.max(0, Math.floor((pad - 2) / 2));
|
|
398
|
+
export const QUAD_INSET = 1;
|
|
261
399
|
|
|
262
|
-
|
|
400
|
+
/**
|
|
401
|
+
* How far past the glyphs' edge a field can see, in its own texels — the
|
|
402
|
+
* widest halo it holds, and the reach of its distances before they
|
|
403
|
+
* saturate — for a field set with `pad` texels of margin and `pad` of
|
|
404
|
+
* spread. Scale by the drawn size over the base for screen pixels.
|
|
405
|
+
*/
|
|
406
|
+
export const fieldReach = (pad: number): number =>
|
|
407
|
+
Math.max(0, Math.min(pad * SDF_EDGE, pad - QUAD_INSET) - 0.5);
|
|
408
|
+
|
|
409
|
+
/** The base size a display scale sets fields at, in device pixels: 16 at
|
|
410
|
+
* 1x, 32 at 2x — the size most map labels are drawn at or just under, so
|
|
411
|
+
* a field is mostly sampled down, where it is sharpest. */
|
|
412
|
+
export const fieldBase = (scale: number): number =>
|
|
413
|
+
Math.round(16 * Math.min(2, Math.max(1, scale)));
|
|
414
|
+
|
|
415
|
+
/** A field's margin and spread at a base size: room for a halo of a
|
|
416
|
+
* quarter of the type's height. */
|
|
417
|
+
export const fieldPad = (base: number): number => Math.ceil(base * 0.375);
|
|
263
418
|
|
|
264
419
|
/** Strings a frame measures however little budget it has left, so a frame
|
|
265
420
|
* that starts late still makes progress. One: on X11 a string's first
|
|
@@ -294,8 +449,11 @@ const KEEP_FRAMES = 120;
|
|
|
294
449
|
*/
|
|
295
450
|
export class LabelAtlas {
|
|
296
451
|
readonly size: number;
|
|
297
|
-
/**
|
|
298
|
-
*
|
|
452
|
+
/** The device-pixel size every string and icon is set at: a label drawn
|
|
453
|
+
* at `size` scales its field by `size / base`. */
|
|
454
|
+
readonly base: number;
|
|
455
|
+
/** The margin set around every field, in its texels, which is also the
|
|
456
|
+
* distance its values span — what a halo grows into. */
|
|
299
457
|
readonly pad: number;
|
|
300
458
|
/** A frame's measuring ran out of budget: there is more to place. */
|
|
301
459
|
starved = false;
|
|
@@ -304,8 +462,15 @@ export class LabelAtlas {
|
|
|
304
462
|
private readonly _entries = new Map<string, AtlasEntry>();
|
|
305
463
|
/** Entries the texture does not have where they are, oldest first. */
|
|
306
464
|
private _uploads: AtlasEntry[] = [];
|
|
465
|
+
/** Drawable entries a compaction moved: all of them go up in the next
|
|
466
|
+
* frame, ahead of any cap, before it draws. */
|
|
467
|
+
private _moved: AtlasEntry[] = [];
|
|
307
468
|
private readonly _wanted = new Map<string, TextItem>();
|
|
308
469
|
private readonly _failed = new Set<string>();
|
|
470
|
+
/** Rasters read back and waiting for their fields, oldest first — asked
|
|
471
|
+
* for as much as anything in `_wanted`, so a frame never asks again. */
|
|
472
|
+
private _fieldQueue: { key: string; raster: TextRaster }[] = [];
|
|
473
|
+
private readonly _queued = new Set<string>();
|
|
309
474
|
private readonly _measured = new Map<string, TextBox>();
|
|
310
475
|
private _busy = false;
|
|
311
476
|
private _shelves: { y: number; height: number; x: number }[] = [];
|
|
@@ -316,16 +481,18 @@ export class LabelAtlas {
|
|
|
316
481
|
|
|
317
482
|
constructor(
|
|
318
483
|
engine: TextEngine | null,
|
|
319
|
-
options: { size?: number; pad
|
|
484
|
+
options: { size?: number; base?: number; pad?: number } = {},
|
|
320
485
|
) {
|
|
321
486
|
this._engine = engine;
|
|
322
487
|
this.size = options.size ?? 2048;
|
|
323
|
-
this.
|
|
488
|
+
this.base = options.base ?? fieldBase(1);
|
|
489
|
+
this.pad = options.pad ?? fieldPad(this.base);
|
|
324
490
|
}
|
|
325
491
|
|
|
326
|
-
/** Strings asked for and not yet
|
|
492
|
+
/** Strings asked for and not yet set: waiting, being read back, or
|
|
493
|
+
* waiting for their fields. */
|
|
327
494
|
get pending(): boolean {
|
|
328
|
-
return this._busy || this._wanted.size > 0;
|
|
495
|
+
return this._busy || this._wanted.size > 0 || this._fieldQueue.length > 0;
|
|
329
496
|
}
|
|
330
497
|
|
|
331
498
|
/** Rasters waiting for the texture. */
|
|
@@ -345,45 +512,82 @@ export class LabelAtlas {
|
|
|
345
512
|
this.starved = false;
|
|
346
513
|
}
|
|
347
514
|
|
|
348
|
-
/** The box a string sets in
|
|
515
|
+
/** The box a string sets in at `size`, or null when this frame's budget
|
|
516
|
+
* is spent. Measured once, at the base size, and scaled — the same
|
|
517
|
+
* arithmetic that scales its field, so the box placement collides and
|
|
518
|
+
* the quad the frame draws are one size. */
|
|
349
519
|
measure(text: string, size: number): TextBox | null {
|
|
350
|
-
const key = keyOf(text
|
|
351
|
-
|
|
352
|
-
if (
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
520
|
+
const key = keyOf(text);
|
|
521
|
+
let box = this._measured.get(key);
|
|
522
|
+
if (!box) {
|
|
523
|
+
const engine = this._engine;
|
|
524
|
+
if (!engine) return null;
|
|
525
|
+
if (this._measures >= MIN_MEASURES && now() > this._deadline) {
|
|
526
|
+
this.starved = true;
|
|
527
|
+
return null;
|
|
528
|
+
}
|
|
529
|
+
this._measures++;
|
|
530
|
+
box = engine.measure(text, this.base);
|
|
531
|
+
if (this._measured.size > 20000) this._measured.clear();
|
|
532
|
+
this._measured.set(key, box);
|
|
358
533
|
}
|
|
359
|
-
this.
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
534
|
+
const k = size / this.base;
|
|
535
|
+
return { width: box.width * k, height: box.height * k };
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
/** The string's field, once the texture has it; null until then —
|
|
539
|
+
* asking is what gets it set. One field whatever size it is drawn at. */
|
|
540
|
+
entry(text: string): AtlasEntry | null {
|
|
541
|
+
return this._lookup(keyOf(text), text, null, 'plate');
|
|
364
542
|
}
|
|
365
543
|
|
|
366
|
-
/**
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
544
|
+
/** One piece of an icon, as {@link entry} answers for a string. */
|
|
545
|
+
icon(name: MapIcon, part: IconPart): AtlasEntry | null {
|
|
546
|
+
return this._lookup(iconKey(name, part), '', name, part);
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
private _lookup(
|
|
550
|
+
key: string,
|
|
551
|
+
text: string,
|
|
552
|
+
icon: MapIcon | null,
|
|
553
|
+
part: IconPart,
|
|
554
|
+
): AtlasEntry | null {
|
|
370
555
|
const entry = this._entries.get(key);
|
|
371
556
|
if (entry) {
|
|
372
557
|
entry.used = this._frame;
|
|
373
558
|
return entry.ready ? entry : null;
|
|
374
559
|
}
|
|
375
|
-
if (
|
|
376
|
-
this.
|
|
560
|
+
if (
|
|
561
|
+
!this._failed.has(key) &&
|
|
562
|
+
!this._wanted.has(key) &&
|
|
563
|
+
!this._queued.has(key)
|
|
564
|
+
) {
|
|
565
|
+
const size = this.base;
|
|
566
|
+
this._wanted.set(
|
|
567
|
+
key,
|
|
568
|
+
icon ? { text, size, icon: { name: icon, part } } : { text, size },
|
|
569
|
+
);
|
|
377
570
|
}
|
|
378
571
|
return null;
|
|
379
572
|
}
|
|
380
573
|
|
|
574
|
+
/** Whether an icon can never be drawn — the engine has no path to fill
|
|
575
|
+
* it with. A name set beside it is then set alone. */
|
|
576
|
+
iconFailed(name: MapIcon): boolean {
|
|
577
|
+
return (
|
|
578
|
+
this._failed.has(iconKey(name, 'plate')) ||
|
|
579
|
+
this._failed.has(iconKey(name, 'glyph'))
|
|
580
|
+
);
|
|
581
|
+
}
|
|
582
|
+
|
|
381
583
|
/** Start rasterizing what has been asked for, unless a batch is out. */
|
|
382
584
|
pump(): void {
|
|
383
585
|
const engine = this._engine;
|
|
384
586
|
if (!engine || this._busy || this._wanted.size === 0) return;
|
|
587
|
+
const keys: string[] = [];
|
|
385
588
|
const batch: TextItem[] = [];
|
|
386
|
-
for (const item of this._wanted
|
|
589
|
+
for (const [key, item] of this._wanted) {
|
|
590
|
+
keys.push(key);
|
|
387
591
|
batch.push(item);
|
|
388
592
|
if (batch.length >= BATCH) break;
|
|
389
593
|
}
|
|
@@ -393,10 +597,22 @@ export class LabelAtlas {
|
|
|
393
597
|
this._busy = false;
|
|
394
598
|
rasters.forEach((raster, i) => {
|
|
395
599
|
if (raster === undefined) return;
|
|
396
|
-
const key =
|
|
600
|
+
const key = keys[i];
|
|
397
601
|
this._wanted.delete(key);
|
|
398
|
-
|
|
602
|
+
// A string with no raster never will have one; a raster with no
|
|
603
|
+
// room is a fact about this moment, and the string is asked for
|
|
604
|
+
// again by the next frame that still shows it.
|
|
605
|
+
if (raster === null) {
|
|
606
|
+
this._failed.add(key);
|
|
607
|
+
} else {
|
|
608
|
+
this._fieldQueue.push({ key, raster });
|
|
609
|
+
this._queued.add(key);
|
|
610
|
+
}
|
|
399
611
|
});
|
|
612
|
+
// The staging surface is free again as soon as the pixels are
|
|
613
|
+
// copied out, so the next batch is read back while this one waits
|
|
614
|
+
// for its fields; and a frame is asked for, to make them.
|
|
615
|
+
this.pump();
|
|
400
616
|
this.onChange?.();
|
|
401
617
|
},
|
|
402
618
|
() => {
|
|
@@ -410,42 +626,138 @@ export class LabelAtlas {
|
|
|
410
626
|
);
|
|
411
627
|
}
|
|
412
628
|
|
|
413
|
-
/**
|
|
414
|
-
* each `ready` once it
|
|
629
|
+
/** Rasters for the texture: every one a compaction moved, then up to
|
|
630
|
+
* `max` new ones, oldest first. The renderer marks each `ready` once it
|
|
631
|
+
* is uploaded — a moved one already is, because the frame that takes it
|
|
632
|
+
* draws after taking it. */
|
|
415
633
|
takeUploads(max: number): AtlasEntry[] {
|
|
416
|
-
|
|
634
|
+
const moved = this._moved;
|
|
635
|
+
this._moved = [];
|
|
636
|
+
return moved.length > 0
|
|
637
|
+
? moved.concat(this._uploads.splice(0, max))
|
|
638
|
+
: this._uploads.splice(0, max);
|
|
417
639
|
}
|
|
418
640
|
|
|
419
641
|
/** The texture is new, and has none of it: everything goes up again. */
|
|
420
642
|
restart(): void {
|
|
421
643
|
for (const entry of this._entries.values()) entry.ready = false;
|
|
422
644
|
this._uploads = [...this._entries.values()];
|
|
645
|
+
this._moved = [];
|
|
423
646
|
}
|
|
424
647
|
|
|
425
648
|
dispose(): void {
|
|
426
649
|
this._engine?.dispose();
|
|
427
650
|
this._engine = null;
|
|
651
|
+
this._fieldQueue = [];
|
|
652
|
+
this._queued.clear();
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
/** Read back and waiting for their fields: another frame is worth
|
|
656
|
+
* drawing, to make them. */
|
|
657
|
+
get fielding(): boolean {
|
|
658
|
+
return this._fieldQueue.length > 0;
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
/**
|
|
662
|
+
* Make fields for what has been read back until `deadline` — at least
|
|
663
|
+
* one — in the frame, whose own draw then takes them into the texture.
|
|
664
|
+
*
|
|
665
|
+
* A field is about 0.2 ms. A batch of them made as it landed was 4-9 ms
|
|
666
|
+
* beside the frames, measured as event-loop stalls on a jump to a view
|
|
667
|
+
* whose every name was new; slices on timers of their own each waited
|
|
668
|
+
* behind a frame, and names arrived late. In the frame, on a budget,
|
|
669
|
+
* they are made at a known cost and drawn the frame after.
|
|
670
|
+
*/
|
|
671
|
+
/**
|
|
672
|
+
* Set what placement asked for, in the frame, until `deadline` (at least
|
|
673
|
+
* one): what was read back already, then every string the engine can set
|
|
674
|
+
* synchronously. What is set here is drawable in this frame — it goes
|
|
675
|
+
* into the texture ahead of any cap, before this frame draws (the
|
|
676
|
+
* `labelsWhileMoving` path, `view.ts`). Icons, and an engine with no
|
|
677
|
+
* synchronous path, still go through {@link pump}.
|
|
678
|
+
*/
|
|
679
|
+
setNow(deadline: number): void {
|
|
680
|
+
const engine = this._engine;
|
|
681
|
+
if (!engine) return;
|
|
682
|
+
let made = 0;
|
|
683
|
+
while (this._fieldQueue.length > 0 && (made === 0 || now() < deadline)) {
|
|
684
|
+
const { key, raster } = this._fieldQueue.shift()!;
|
|
685
|
+
this._queued.delete(key);
|
|
686
|
+
this._add(key, raster.width, raster.height, this._field(raster), true);
|
|
687
|
+
made++;
|
|
688
|
+
}
|
|
689
|
+
if (!engine.rasterizeNow) return;
|
|
690
|
+
for (const [key, item] of this._wanted) {
|
|
691
|
+
if (made > 0 && now() >= deadline) {
|
|
692
|
+
this.starved = true;
|
|
693
|
+
break;
|
|
694
|
+
}
|
|
695
|
+
const raster = engine.rasterizeNow(item, this.pad);
|
|
696
|
+
if (raster === undefined) continue;
|
|
697
|
+
this._wanted.delete(key);
|
|
698
|
+
if (raster === null) {
|
|
699
|
+
this._failed.add(key);
|
|
700
|
+
continue;
|
|
701
|
+
}
|
|
702
|
+
this._add(key, raster.width, raster.height, this._field(raster), true);
|
|
703
|
+
made++;
|
|
704
|
+
}
|
|
428
705
|
}
|
|
429
706
|
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
707
|
+
makeFields(deadline: number): void {
|
|
708
|
+
if (!this._engine) return;
|
|
709
|
+
let made = 0;
|
|
710
|
+
while (this._fieldQueue.length > 0 && (made === 0 || now() < deadline)) {
|
|
711
|
+
const { key, raster } = this._fieldQueue.shift()!;
|
|
712
|
+
this._queued.delete(key);
|
|
713
|
+
this._add(key, raster.width, raster.height, this._field(raster));
|
|
714
|
+
made++;
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
/** A raster's coverage as its distance field. The coverage is the
|
|
719
|
+
* readback's alpha; the field spans `pad` texels either side of the
|
|
720
|
+
* edge, which is the margin the engine set it with. */
|
|
721
|
+
private _field(raster: TextRaster): Uint8Array {
|
|
722
|
+
const stride = raster.stride ?? 4;
|
|
723
|
+
return distanceField(
|
|
724
|
+
raster.pixels,
|
|
725
|
+
raster.width,
|
|
726
|
+
raster.height,
|
|
727
|
+
this.pad,
|
|
728
|
+
stride,
|
|
729
|
+
stride === 4 ? 3 : 0,
|
|
730
|
+
);
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
private _add(
|
|
734
|
+
key: string,
|
|
735
|
+
width: number,
|
|
736
|
+
height: number,
|
|
737
|
+
pixels: Uint8Array,
|
|
738
|
+
/** Drawable in this frame: uploaded ahead of any cap before it draws. */
|
|
739
|
+
immediate = false,
|
|
740
|
+
): boolean {
|
|
741
|
+
let place =
|
|
742
|
+
this._allocate(width, height) ?? this._reuseShelf(width, height);
|
|
743
|
+
if (!place && this._compactable()) {
|
|
433
744
|
this._compact();
|
|
434
|
-
place = this._allocate(
|
|
745
|
+
place = this._allocate(width, height);
|
|
435
746
|
}
|
|
436
747
|
if (!place) return false;
|
|
437
748
|
const entry: AtlasEntry = {
|
|
438
749
|
key,
|
|
439
750
|
x: place.x,
|
|
440
751
|
y: place.y,
|
|
441
|
-
width
|
|
442
|
-
height
|
|
443
|
-
pixels
|
|
444
|
-
ready:
|
|
752
|
+
width,
|
|
753
|
+
height,
|
|
754
|
+
pixels,
|
|
755
|
+
ready: immediate,
|
|
445
756
|
used: this._frame,
|
|
446
757
|
};
|
|
447
758
|
this._entries.set(key, entry);
|
|
448
|
-
this.
|
|
759
|
+
if (immediate) this._moved.push(entry);
|
|
760
|
+
else this._uploads.push(entry);
|
|
449
761
|
return true;
|
|
450
762
|
}
|
|
451
763
|
|
|
@@ -468,9 +780,69 @@ export class LabelAtlas {
|
|
|
468
780
|
return { x: 0, y: shelf.y };
|
|
469
781
|
}
|
|
470
782
|
|
|
783
|
+
/**
|
|
784
|
+
* Room made in place: the shelf of this height whose rasters were drawn
|
|
785
|
+
* longest ago, emptied and filled again from its left.
|
|
786
|
+
*
|
|
787
|
+
* **Nothing that stays moves.** A compaction moves every raster it keeps,
|
|
788
|
+
* and a moved raster is not drawn until it is in the texture again — at
|
|
789
|
+
* {@link takeUploads}' pace, so every label on screen went out together
|
|
790
|
+
* and came back over the next few frames, at full opacity. A full atlas
|
|
791
|
+
* is the ordinary state of a session (a thousand strings at 1x, a quarter
|
|
792
|
+
* of that at 2x), so that was a flash of the whole label layer at the end
|
|
793
|
+
* of most settles. A shelf any label of the last two frames stands on is not
|
|
794
|
+
* taken: what is dropped is off screen, and asked for again if it
|
|
795
|
+
* returns.
|
|
796
|
+
*/
|
|
797
|
+
private _reuseShelf(w: number, h: number): { x: number; y: number } | null {
|
|
798
|
+
if (w > this.size) return null;
|
|
799
|
+
const height = Math.ceil(h / 8) * 8;
|
|
800
|
+
const newest = new Map<number, number>();
|
|
801
|
+
for (const entry of this._entries.values()) {
|
|
802
|
+
const seen = newest.get(entry.y);
|
|
803
|
+
if (seen === undefined || entry.used > seen)
|
|
804
|
+
newest.set(entry.y, entry.used);
|
|
805
|
+
}
|
|
806
|
+
let shelf: { y: number; height: number; x: number } | null = null;
|
|
807
|
+
// Not a shelf any label of this frame or the last stands on: fields can
|
|
808
|
+
// be made before a frame's labels are batched (`setNow`), when a label
|
|
809
|
+
// still fading out has not been asked for yet.
|
|
810
|
+
let oldest = this._frame - 1;
|
|
811
|
+
for (const candidate of this._shelves) {
|
|
812
|
+
if (candidate.height !== height) continue;
|
|
813
|
+
const used = newest.get(candidate.y) ?? -Infinity;
|
|
814
|
+
if (used < oldest) {
|
|
815
|
+
oldest = used;
|
|
816
|
+
shelf = candidate;
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
if (!shelf) return null;
|
|
820
|
+
const y = shelf.y;
|
|
821
|
+
for (const [key, entry] of this._entries) {
|
|
822
|
+
if (entry.y === y) this._entries.delete(key);
|
|
823
|
+
}
|
|
824
|
+
this._uploads = this._uploads.filter((entry) => entry.y !== y);
|
|
825
|
+
this._moved = this._moved.filter((entry) => entry.y !== y);
|
|
826
|
+
shelf.x = w;
|
|
827
|
+
return { x: 0, y };
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
/** Whether a compaction would free anything: something kept past its
|
|
831
|
+
* last use. One that keeps everything only moves it — every label on
|
|
832
|
+
* screen out of the texture for the frames its upload takes, for no
|
|
833
|
+
* room at all. */
|
|
834
|
+
private _compactable(): boolean {
|
|
835
|
+
for (const entry of this._entries.values()) {
|
|
836
|
+
if (entry.used < this._frame - KEEP_FRAMES) return true;
|
|
837
|
+
}
|
|
838
|
+
return false;
|
|
839
|
+
}
|
|
840
|
+
|
|
471
841
|
/** Drop what has not been drawn for a while and pack the rest again,
|
|
472
|
-
* tallest first
|
|
473
|
-
*
|
|
842
|
+
* tallest first — the last resort, when no shelf of the height wanted
|
|
843
|
+
* can be taken in place. What was drawable stays drawable: it is
|
|
844
|
+
* uploaded where it now is, all of it, by the next frame before that
|
|
845
|
+
* frame draws ({@link takeUploads}); what was waiting still waits. */
|
|
474
846
|
private _compact(): void {
|
|
475
847
|
const keep = [...this._entries.values()]
|
|
476
848
|
.filter((e) => e.used >= this._frame - KEEP_FRAMES)
|
|
@@ -479,14 +851,15 @@ export class LabelAtlas {
|
|
|
479
851
|
this._shelves = [];
|
|
480
852
|
this._top = 0;
|
|
481
853
|
this._uploads = [];
|
|
854
|
+
this._moved = [];
|
|
482
855
|
for (const entry of keep) {
|
|
483
856
|
const place = this._allocate(entry.width, entry.height);
|
|
484
857
|
if (!place) continue;
|
|
485
858
|
entry.x = place.x;
|
|
486
859
|
entry.y = place.y;
|
|
487
|
-
entry.ready = false;
|
|
488
860
|
this._entries.set(entry.key, entry);
|
|
489
|
-
this.
|
|
861
|
+
if (entry.ready) this._moved.push(entry);
|
|
862
|
+
else this._uploads.push(entry);
|
|
490
863
|
}
|
|
491
864
|
}
|
|
492
865
|
}
|