@weasel-js/core 1.9.2 → 1.9.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +393 -0
- package/README.md +2 -2
- package/dist/WeaselProvider.js +5 -5
- package/dist/affordances/composeAffordanceLayer.js +10 -20
- package/dist/affordances/composeAffordanceLayer.js.map +1 -1
- package/dist/affordances/cornerResize.js +25 -17
- package/dist/affordances/cornerResize.js.map +1 -1
- package/dist/affordances/hitAffordanceRegions.js +27 -20
- package/dist/affordances/hitAffordanceRegions.js.map +1 -1
- package/dist/affordances/rotationHandle.js +18 -18
- package/dist/affordances/rotationHandle.js.map +1 -1
- package/dist/animation/behaviors/momentum.js +93 -55
- package/dist/animation/behaviors/momentum.js.map +1 -1
- package/dist/animation/loop.js +10 -12
- package/dist/animation/loop.js.map +1 -1
- package/dist/animation/reflow.js +8 -8
- package/dist/animation/reflow.js.map +1 -1
- package/dist/animation/stagger.js +64 -56
- package/dist/animation/stagger.js.map +1 -1
- package/dist/animation/timeline/booking.js +62 -54
- package/dist/animation/timeline/booking.js.map +1 -1
- package/dist/animation/timeline/createTimeline.js +85 -76
- package/dist/animation/timeline/createTimeline.js.map +1 -1
- package/dist/animation/timeline/sampleTrack.js +13 -5
- package/dist/animation/timeline/sampleTrack.js.map +1 -1
- package/dist/animation/useAnimator.js +45 -35
- package/dist/animation/useAnimator.js.map +1 -1
- package/dist/animation/wrappers/animateLifecycle.js +31 -24
- package/dist/animation/wrappers/animateLifecycle.js.map +1 -1
- package/dist/animation/wrappers/animateOnSetPose.js +28 -26
- package/dist/animation/wrappers/animateOnSetPose.js.map +1 -1
- package/dist/animation/wrappers/instantPose.js +13 -0
- package/dist/animation/wrappers/instantPose.js.map +1 -0
- package/dist/{poseDescriptor-D-OH-tu5.d.ts → autoPoseDescriptor-Ct7yqivU.d.ts} +28 -3
- package/dist/barrel/chrome.js +16 -0
- package/dist/barrel/input.js +19 -0
- package/dist/barrel/interactions.js +42 -0
- package/dist/barrel/paint.js +18 -0
- package/dist/barrel/paths.js +19 -0
- package/dist/barrel/renderer.js +20 -0
- package/dist/barrel/routing.js +51 -0
- package/dist/barrel/text.js +18 -0
- package/dist/barrel/viewport.js +52 -0
- package/dist/builtins-DPcdghtB.d.ts +1223 -0
- package/dist/canvas/Canvas.js +363 -448
- package/dist/canvas/Canvas.js.map +1 -1
- package/dist/canvas/CanvasView.js +164 -165
- package/dist/canvas/CanvasView.js.map +1 -1
- package/dist/canvas/CursorCoordsHud.js +37 -32
- package/dist/canvas/CursorCoordsHud.js.map +1 -1
- package/dist/canvas/DrawCanvas.js +49 -43
- package/dist/canvas/DrawCanvas.js.map +1 -1
- package/dist/canvas/MinimapCanvas.js +26 -25
- package/dist/canvas/MinimapCanvas.js.map +1 -1
- package/dist/canvas/NodeShape.js +59 -377
- package/dist/canvas/NodeShape.js.map +1 -1
- package/dist/canvas/PickHud.js +50 -47
- package/dist/canvas/PickHud.js.map +1 -1
- package/dist/canvas/SceneCanvas/GestureDispatcherMounter.js +167 -0
- package/dist/canvas/SceneCanvas/GestureDispatcherMounter.js.map +1 -0
- package/dist/canvas/SceneCanvas/PointerProviderIfRoot.js +13 -13
- package/dist/canvas/SceneCanvas/StandardActionsRegistrar.js +67 -0
- package/dist/canvas/SceneCanvas/StandardActionsRegistrar.js.map +1 -0
- package/dist/canvas/SceneCanvas/ToolKeybindingsMounter.js +16 -0
- package/dist/canvas/SceneCanvas/ToolKeybindingsMounter.js.map +1 -0
- package/dist/canvas/SceneCanvas/coordTrace.js +10 -0
- package/dist/canvas/SceneCanvas/coordTrace.js.map +1 -0
- package/dist/canvas/SceneCanvas/defaultNodeProperties.js +146 -92
- package/dist/canvas/SceneCanvas/defaultNodeProperties.js.map +1 -1
- package/dist/canvas/SceneCanvas/defaultNodeRouting.js +9 -8
- package/dist/canvas/SceneCanvas/defaultNodeRouting.js.map +1 -1
- package/dist/canvas/SceneCanvas/features.js +1 -0
- package/dist/canvas/SceneCanvas/features.js.map +1 -1
- package/dist/canvas/SceneCanvas/isDev.js +12 -0
- package/dist/canvas/SceneCanvas/isDev.js.map +1 -0
- package/dist/canvas/SceneCanvas/poseGeometry.js +29 -28
- package/dist/canvas/SceneCanvas/poseGeometry.js.map +1 -1
- package/dist/canvas/SceneCanvas/poseRegistrars.js +13 -0
- package/dist/canvas/SceneCanvas/poseRegistrars.js.map +1 -0
- package/dist/canvas/SceneCanvas/props.js +38 -0
- package/dist/canvas/SceneCanvas/props.js.map +1 -0
- package/dist/canvas/SceneCanvas/useBuiltinShapeTools.js +21 -62
- package/dist/canvas/SceneCanvas/useBuiltinShapeTools.js.map +1 -1
- package/dist/canvas/SceneCanvas/useDispatcherOverlayLayer.js.map +1 -1
- package/dist/canvas/SceneCanvas/usePreviewGhostLayer.js +46 -48
- package/dist/canvas/SceneCanvas/usePreviewGhostLayer.js.map +1 -1
- package/dist/canvas/SceneCanvas/useSceneSelectTool.js +33 -33
- package/dist/canvas/SceneCanvas/useSceneSelectTool.js.map +1 -1
- package/dist/canvas/SceneCanvas.js +534 -788
- package/dist/canvas/SceneCanvas.js.map +1 -1
- package/dist/canvas/SceneViewCanvas.js +45 -43
- package/dist/canvas/SceneViewCanvas.js.map +1 -1
- package/dist/canvas/buildSceneLayer.js +91 -0
- package/dist/canvas/buildSceneLayer.js.map +1 -0
- package/dist/canvas/buildSceneTree.js +16 -19
- package/dist/canvas/buildSceneTree.js.map +1 -1
- package/dist/canvas/canvasRenderer.js +68 -52
- package/dist/canvas/canvasRenderer.js.map +1 -1
- package/dist/canvas/deps/changes.js +13 -0
- package/dist/canvas/deps/changes.js.map +1 -0
- package/dist/canvas/deps/editAnchors.js +28 -28
- package/dist/canvas/deps/insert.js +119 -91
- package/dist/canvas/deps/insert.js.map +1 -1
- package/dist/canvas/deps/slice.js +46 -45
- package/dist/canvas/deps/slice.js.map +1 -1
- package/dist/canvas/deps/textEdit.js +10 -9
- package/dist/canvas/deps/textEdit.js.map +1 -1
- package/dist/canvas/derivedPath.js +46 -23
- package/dist/canvas/derivedPath.js.map +1 -1
- package/dist/canvas/getNodeAtPoint.js +7 -7
- package/dist/canvas/getNodeAtPoint.js.map +1 -1
- package/dist/canvas/hud.module.js +1 -1
- package/dist/canvas/hud.module.js.map +1 -1
- package/dist/canvas/kitRequirements.js +2 -2
- package/dist/canvas/kitRequirements.js.map +1 -1
- package/dist/canvas/layerOrder.js +13 -6
- package/dist/canvas/layerOrder.js.map +1 -1
- package/dist/canvas/minimapMath.js +12 -10
- package/dist/canvas/minimapMath.js.map +1 -1
- package/dist/canvas/nodeShapes/derivedPainter.js +34 -0
- package/dist/canvas/nodeShapes/derivedPainter.js.map +1 -0
- package/dist/canvas/nodeShapes/imagePainter.js +87 -0
- package/dist/canvas/nodeShapes/imagePainter.js.map +1 -0
- package/dist/canvas/nodeShapes/memo.js +9 -0
- package/dist/canvas/nodeShapes/memo.js.map +1 -0
- package/dist/canvas/nodeShapes/nodePaint.js +57 -0
- package/dist/canvas/nodeShapes/nodePaint.js.map +1 -0
- package/dist/canvas/nodeShapes/pathPainter.js +38 -0
- package/dist/canvas/nodeShapes/pathPainter.js.map +1 -0
- package/dist/canvas/nodeShapes/poseBox.js +20 -0
- package/dist/canvas/nodeShapes/poseBox.js.map +1 -0
- package/dist/canvas/nodeShapes/rectFallbackPainter.js +38 -0
- package/dist/canvas/nodeShapes/rectFallbackPainter.js.map +1 -0
- package/dist/canvas/nodeShapes/shapePainter.js +72 -0
- package/dist/canvas/nodeShapes/shapePainter.js.map +1 -0
- package/dist/canvas/nodeShapes/textPainter.js +55 -0
- package/dist/canvas/nodeShapes/textPainter.js.map +1 -0
- package/dist/canvas/overlayRoleStrokes.js.map +1 -1
- package/dist/canvas/paintCull.js +10 -11
- package/dist/canvas/paintCull.js.map +1 -1
- package/dist/canvas/pickWalk.js +52 -63
- package/dist/canvas/pickWalk.js.map +1 -1
- package/dist/canvas/poseRotation.js +11 -23
- package/dist/canvas/poseRotation.js.map +1 -1
- package/dist/canvas/renderDebugSnapshot.js +5 -5
- package/dist/canvas/renderSceneToPixels.js +3 -1
- package/dist/canvas/renderSceneToPixels.js.map +1 -1
- package/dist/canvas/sceneAdapter.js +66 -148
- package/dist/canvas/sceneAdapter.js.map +1 -1
- package/dist/canvas/sceneClipboard.js +112 -0
- package/dist/canvas/sceneClipboard.js.map +1 -0
- package/dist/canvas/sceneSlotWiring.js +4 -4
- package/dist/canvas/sceneSlotWiring.js.map +1 -1
- package/dist/canvas/sceneViewRender.js +39 -40
- package/dist/canvas/sceneViewRender.js.map +1 -1
- package/dist/canvas/useCanvasRenderer.js +14 -6
- package/dist/canvas/useCanvasRenderer.js.map +1 -1
- package/dist/canvas/useCanvasView.js +58 -0
- package/dist/canvas/useCanvasView.js.map +1 -0
- package/dist/canvas/useFrameLoop.js +35 -26
- package/dist/canvas/useFrameLoop.js.map +1 -1
- package/dist/canvas/useSceneLayerList.js +21 -0
- package/dist/canvas/useSceneLayerList.js.map +1 -0
- package/dist/clipboard.d.ts +10 -6
- package/dist/clone.d.ts +4 -3
- package/dist/core/adapters/arrayAdapter.js +48 -39
- package/dist/core/adapters/arrayAdapter.js.map +1 -1
- package/dist/core/device/index.js +5 -4
- package/dist/core/device/useDeviceProfile.js +38 -44
- package/dist/core/device/useDeviceProfile.js.map +1 -1
- package/dist/core/device/watchDevicePixelRatio.js +17 -0
- package/dist/core/device/watchDevicePixelRatio.js.map +1 -0
- package/dist/core/fillInPoseFrame.js.map +1 -1
- package/dist/core/geometry/poseDescriptor.js +21 -19
- package/dist/core/geometry/poseDescriptor.js.map +1 -1
- package/dist/core/geometry/poseFrame.js +44 -0
- package/dist/core/geometry/poseFrame.js.map +1 -0
- package/dist/core/geometry/poseRotation.js.map +1 -1
- package/dist/core/geometry/regionHit.js +9 -10
- package/dist/core/geometry/regionHit.js.map +1 -1
- package/dist/core/geometry/unionBounds.js +31 -29
- package/dist/core/geometry/unionBounds.js.map +1 -1
- package/dist/core/isPlainObject.js +2 -11
- package/dist/core/ops/arrange.js +1 -0
- package/dist/core/ops/arrange.js.map +1 -1
- package/dist/core/ops/create.js +10 -5
- package/dist/core/ops/create.js.map +1 -1
- package/dist/core/ops/delete.js +12 -24
- package/dist/core/ops/delete.js.map +1 -1
- package/dist/core/ops/reorder/index.js +43 -40
- package/dist/core/ops/reorder/index.js.map +1 -1
- package/dist/core/ops/reorder/setChildOrder.js +34 -0
- package/dist/core/ops/reorder/setChildOrder.js.map +1 -0
- package/dist/core/paintKinds.js +5 -5
- package/dist/core/paintKinds.js.map +1 -1
- package/dist/core/scene/NodeProperties.js.map +1 -1
- package/dist/core/scene/appliedLog.js +37 -0
- package/dist/core/scene/appliedLog.js.map +1 -0
- package/dist/core/scene/arrivalWindow.js +101 -0
- package/dist/core/scene/arrivalWindow.js.map +1 -0
- package/dist/core/scene/derivedPath.js.map +1 -1
- package/dist/core/scene/historyFacade.js +84 -0
- package/dist/core/scene/historyFacade.js.map +1 -0
- package/dist/core/scene/kitOps.js +173 -0
- package/dist/core/scene/kitOps.js.map +1 -0
- package/dist/core/scene/layerStack.js +38 -0
- package/dist/core/scene/layerStack.js.map +1 -0
- package/dist/core/scene/lockGuard.js +37 -0
- package/dist/core/scene/lockGuard.js.map +1 -0
- package/dist/core/scene/nodeFnFields.js +5 -6
- package/dist/core/scene/nodeFnFields.js.map +1 -1
- package/dist/core/scene/nodeMemo.js +45 -19
- package/dist/core/scene/nodeMemo.js.map +1 -1
- package/dist/core/scene/nodeStore.js +126 -0
- package/dist/core/scene/nodeStore.js.map +1 -0
- package/dist/core/scene/pickability.js +6 -0
- package/dist/core/scene/pickability.js.map +1 -0
- package/dist/core/scene/poseFeed.js +38 -38
- package/dist/core/scene/poseFeed.js.map +1 -1
- package/dist/core/scene/poseOverrides.js +34 -38
- package/dist/core/scene/poseOverrides.js.map +1 -1
- package/dist/core/scene/renderOrder.js +84 -0
- package/dist/core/scene/renderOrder.js.map +1 -0
- package/dist/core/scene/scene.js +289 -866
- package/dist/core/scene/scene.js.map +1 -1
- package/dist/core/scene/serialization.js +68 -0
- package/dist/core/scene/serialization.js.map +1 -0
- package/dist/core/scene/treeOrder.js +13 -0
- package/dist/core/scene/treeOrder.js.map +1 -0
- package/dist/core/scene/types.js.map +1 -1
- package/dist/core/viewport/meanScale.js +1 -1
- package/dist/core/viewport/meanScale.js.map +1 -1
- package/dist/core/viewport/view.js +12 -12
- package/dist/core/viewport/view.js.map +1 -1
- package/dist/core/viewport/zoomBounds.js +10 -8
- package/dist/core/viewport/zoomBounds.js.map +1 -1
- package/dist/{cornerHandles-BCrDp_mH.d.ts → cornerHandles-CtCb8a3G.d.ts} +1 -1
- package/dist/debug/createDebugOverlayLayer.js +14 -14
- package/dist/debug/createDebugOverlayLayer.js.map +1 -1
- package/dist/debug/flag.js +2 -41
- package/dist/features/chrome-caps/useHoverTracking.js +22 -17
- package/dist/features/chrome-caps/useHoverTracking.js.map +1 -1
- package/dist/features/focus/gateLayer.js +3 -4
- package/dist/features/focus/gateLayer.js.map +1 -1
- package/dist/features/images/imageCache.js +19 -9
- package/dist/features/images/imageCache.js.map +1 -1
- package/dist/features/ingestion/contentHandlers.js +14 -11
- package/dist/features/ingestion/contentHandlers.js.map +1 -1
- package/dist/features/ingestion/index.js +1 -1
- package/dist/features/ingestion/registerKitHandlers.js +7 -7
- package/dist/features/ingestion/weaselJsonHandler.js +17 -14
- package/dist/features/ingestion/weaselJsonHandler.js.map +1 -1
- package/dist/features/meshPaint/lazyKind.js +201 -35
- package/dist/features/meshPaint/lazyKind.js.map +1 -1
- package/dist/features/meshPaint/meshPaint.js +82 -79
- package/dist/features/meshPaint/meshPaint.js.map +1 -1
- package/dist/features/minimap/createMinimapContribution.js +42 -42
- package/dist/features/minimap/layers.js +44 -62
- package/dist/features/minimap/layers.js.map +1 -1
- package/dist/features/parallax/createParallaxPlane.js +10 -14
- package/dist/features/parallax/createParallaxPlane.js.map +1 -1
- package/dist/features/paths/anchorEdits.js +19 -8
- package/dist/features/paths/anchorEdits.js.map +1 -1
- package/dist/features/paths/anchors.js +31 -26
- package/dist/features/paths/anchors.js.map +1 -1
- package/dist/features/paths/booleans.js +2 -2
- package/dist/features/paths/index.js +13 -11
- package/dist/features/paths/markerCommands.js +37 -36
- package/dist/features/paths/markerCommands.js.map +1 -1
- package/dist/features/paths/pathInWorld.js +19 -19
- package/dist/features/paths/pathInWorld.js.map +1 -1
- package/dist/features/paths/pathLayer.js.map +1 -1
- package/dist/features/paths/strokeToPath.js +40 -0
- package/dist/features/paths/strokeToPath.js.map +1 -0
- package/dist/features/paths/tessellate/stroke.js.map +1 -1
- package/dist/features/patterns/commandPaint.js +18 -0
- package/dist/features/patterns/commandPaint.js.map +1 -0
- package/dist/features/patterns/index.js +5 -17
- package/dist/features/patterns/index.js.map +1 -1
- package/dist/features/patterns/rasterizeTile.js +17 -0
- package/dist/features/patterns/rasterizeTile.js.map +1 -0
- package/dist/features/patterns/resolveSpec.js +52 -44
- package/dist/features/patterns/resolveSpec.js.map +1 -1
- package/dist/features/poseRun/usePoseRun.js +8 -3
- package/dist/features/poseRun/usePoseRun.js.map +1 -1
- package/dist/features/selection/SelectionContext.js +5 -0
- package/dist/features/selection/SelectionContext.js.map +1 -1
- package/dist/features/selection/overlay.js +18 -18
- package/dist/features/selection/overlay.js.map +1 -1
- package/dist/features/text/domOffsets.js +82 -0
- package/dist/features/text/domOffsets.js.map +1 -0
- package/dist/features/text/domRuns.js +103 -131
- package/dist/features/text/domRuns.js.map +1 -1
- package/dist/features/text/hitTest.js +5 -2
- package/dist/features/text/hitTest.js.map +1 -1
- package/dist/features/text/isTextData.js +8 -0
- package/dist/features/text/isTextData.js.map +1 -0
- package/dist/features/text/overlayDirection.js +15 -0
- package/dist/features/text/overlayDirection.js.map +1 -0
- package/dist/features/text/runs/rangeStyle.js +32 -34
- package/dist/features/text/runs/rangeStyle.js.map +1 -1
- package/dist/features/text/textCommand.js +34 -33
- package/dist/features/text/textCommand.js.map +1 -1
- package/dist/features/text/textToPath.js +40 -40
- package/dist/features/text/textToPath.js.map +1 -1
- package/dist/features/text/useSceneTextEdit.js +76 -82
- package/dist/features/text/useSceneTextEdit.js.map +1 -1
- package/dist/features/text/useTextEdit.js +184 -160
- package/dist/features/text/useTextEdit.js.map +1 -1
- package/dist/features/tiling/createTiledLayer.js +24 -22
- package/dist/features/tiling/createTiledLayer.js.map +1 -1
- package/dist/index.d.ts +11010 -7700
- package/dist/index.js +316 -309
- package/dist/input/keyState.js +42 -43
- package/dist/input/keyState.js.map +1 -1
- package/dist/input/useKeyModifiers.js +11 -0
- package/dist/input/useKeyModifiers.js.map +1 -0
- package/dist/interactions/actions/align/align.js +8 -8
- package/dist/interactions/actions/clipboard/clipboardOps.js +34 -32
- package/dist/interactions/actions/clipboard/clipboardOps.js.map +1 -1
- package/dist/interactions/actions/clipboard/materializePaste.js +10 -7
- package/dist/interactions/actions/clipboard/materializePaste.js.map +1 -1
- package/dist/interactions/actions/clipboard/wireFormat.js.map +1 -1
- package/dist/interactions/actions/clone/behaviors/cloneByAltDrag.js.map +1 -1
- package/dist/interactions/actions/defaultCommitAdapter.js +20 -18
- package/dist/interactions/actions/defaultCommitAdapter.js.map +1 -1
- package/dist/interactions/actions/defaults/align.js +9 -10
- package/dist/interactions/actions/defaults/align.js.map +1 -1
- package/dist/interactions/actions/defaults/anchorEditing.js +59 -81
- package/dist/interactions/actions/defaults/anchorEditing.js.map +1 -1
- package/dist/interactions/actions/defaults/areaSelect.js +35 -38
- package/dist/interactions/actions/defaults/areaSelect.js.map +1 -1
- package/dist/interactions/actions/defaults/clipboard.js +26 -10
- package/dist/interactions/actions/defaults/clipboard.js.map +1 -1
- package/dist/interactions/actions/defaults/clone.js +44 -60
- package/dist/interactions/actions/defaults/clone.js.map +1 -1
- package/dist/interactions/actions/defaults/copySubtree.js +40 -0
- package/dist/interactions/actions/defaults/copySubtree.js.map +1 -0
- package/dist/interactions/actions/defaults/distribute.js +14 -13
- package/dist/interactions/actions/defaults/distribute.js.map +1 -1
- package/dist/interactions/actions/defaults/duplicate.js +17 -57
- package/dist/interactions/actions/defaults/duplicate.js.map +1 -1
- package/dist/interactions/actions/defaults/editAnchors.js +18 -18
- package/dist/interactions/actions/defaults/enterTextEdit.js.map +1 -1
- package/dist/interactions/actions/defaults/flip.js +52 -46
- package/dist/interactions/actions/defaults/flip.js.map +1 -1
- package/dist/interactions/actions/defaults/group.js +43 -48
- package/dist/interactions/actions/defaults/group.js.map +1 -1
- package/dist/interactions/actions/defaults/ingest.js +35 -33
- package/dist/interactions/actions/defaults/ingest.js.map +1 -1
- package/dist/interactions/actions/defaults/insert.js +50 -51
- package/dist/interactions/actions/defaults/insert.js.map +1 -1
- package/dist/interactions/actions/defaults/insertPathAnchor.js +7 -7
- package/dist/interactions/actions/defaults/lassoSelect.js +67 -70
- package/dist/interactions/actions/defaults/lassoSelect.js.map +1 -1
- package/dist/interactions/actions/defaults/move.js +267 -249
- package/dist/interactions/actions/defaults/move.js.map +1 -1
- package/dist/interactions/actions/defaults/nudge.js +40 -68
- package/dist/interactions/actions/defaults/nudge.js.map +1 -1
- package/dist/interactions/actions/defaults/nudgeSteps.js +37 -0
- package/dist/interactions/actions/defaults/nudgeSteps.js.map +1 -0
- package/dist/interactions/actions/defaults/reorder.js +2 -0
- package/dist/interactions/actions/defaults/reorder.js.map +1 -1
- package/dist/interactions/actions/defaults/resize.js +104 -98
- package/dist/interactions/actions/defaults/resize.js.map +1 -1
- package/dist/interactions/actions/defaults/rotate.js +111 -110
- package/dist/interactions/actions/defaults/rotate.js.map +1 -1
- package/dist/interactions/actions/defaults/setFill.js +7 -7
- package/dist/interactions/actions/defaults/setFillOpacity.js +4 -4
- package/dist/interactions/actions/defaults/setStroke.js +12 -12
- package/dist/interactions/actions/defaults/setStrokeOpacity.js +6 -6
- package/dist/interactions/actions/defaults/sliceOps.js +19 -19
- package/dist/interactions/actions/defaults/viewportDragPan.js +37 -26
- package/dist/interactions/actions/defaults/viewportDragPan.js.map +1 -1
- package/dist/interactions/actions/edit-anchors/geometry.js +28 -23
- package/dist/interactions/actions/edit-anchors/geometry.js.map +1 -1
- package/dist/interactions/actions/flip/helpers.js +30 -17
- package/dist/interactions/actions/flip/helpers.js.map +1 -1
- package/dist/interactions/actions/hitSelection.js +8 -0
- package/dist/interactions/actions/hitSelection.js.map +1 -0
- package/dist/interactions/actions/lasso-select/behaviors/selectFromLasso.js +14 -18
- package/dist/interactions/actions/lasso-select/behaviors/selectFromLasso.js.map +1 -1
- package/dist/interactions/actions/move/behaviors/snapBackOrDelete.js +5 -5
- package/dist/interactions/actions/move/behaviors/snapBackOrDelete.js.map +1 -1
- package/dist/interactions/actions/move/behaviors/snapToContainer.js +32 -21
- package/dist/interactions/actions/move/behaviors/snapToContainer.js.map +1 -1
- package/dist/interactions/actions/move/gestureAdapter.js +32 -15
- package/dist/interactions/actions/move/gestureAdapter.js.map +1 -1
- package/dist/interactions/actions/move/landedDescendants.js +33 -0
- package/dist/interactions/actions/move/landedDescendants.js.map +1 -0
- package/dist/interactions/actions/outlines/createOutlines.js +18 -18
- package/dist/interactions/actions/poseDescriptorDep.js +16 -4
- package/dist/interactions/actions/poseDescriptorDep.js.map +1 -1
- package/dist/interactions/actions/poseFrame.js +11 -6
- package/dist/interactions/actions/poseFrame.js.map +1 -1
- package/dist/interactions/actions/previewOverrides.js +5 -5
- package/dist/interactions/actions/previewOverrides.js.map +1 -1
- package/dist/interactions/actions/selectionSubtree.js +69 -0
- package/dist/interactions/actions/selectionSubtree.js.map +1 -0
- package/dist/interactions/actions/useStandardActions.js +66 -62
- package/dist/interactions/actions/useStandardActions.js.map +1 -1
- package/dist/interactions/gestures/dragGesture/dragGesture.js +4 -7
- package/dist/interactions/gestures/dragGesture/dragGesture.js.map +1 -1
- package/dist/interactions/gestures/dragGesture/dragPointOf.js +23 -0
- package/dist/interactions/gestures/dragGesture/dragPointOf.js.map +1 -0
- package/dist/interactions/gestures/handleDrag/handleDrag.js +21 -26
- package/dist/interactions/gestures/handleDrag/handleDrag.js.map +1 -1
- package/dist/interactions/gestures/pointerDrag/pointerDrag.js +8 -6
- package/dist/interactions/gestures/pointerDrag/pointerDrag.js.map +1 -1
- package/dist/interactions/gestures/thresholdDrag/thresholdDrag.js +8 -4
- package/dist/interactions/gestures/thresholdDrag/thresholdDrag.js.map +1 -1
- package/dist/{math-Drrw4ewZ.d.ts → math-J-ACHyEg.d.ts} +1 -2
- package/dist/math.d.ts +2 -3
- package/dist/move.d.ts +12 -11
- package/dist/{originProjection-DEklpDc_.d.ts → originProjection-gHnOup4e.d.ts} +1 -1
- package/dist/{registerProgram-BMZRDgrh.d.ts → registerProgram-T9S_PfAX.d.ts} +18 -7
- package/dist/renderer/DrawCommand.js.map +1 -1
- package/dist/renderer/WeaselRenderer.js +75 -73
- package/dist/renderer/WeaselRenderer.js.map +1 -1
- package/dist/renderer/cache/GLImageCache.js +15 -5
- package/dist/renderer/cache/GLImageCache.js.map +1 -1
- package/dist/renderer/cache/GLMeshCache.js +23 -23
- package/dist/renderer/cache/GLMeshCache.js.map +1 -1
- package/dist/renderer/cache/GLTextureCache.js +18 -1
- package/dist/renderer/cache/GLTextureCache.js.map +1 -1
- package/dist/renderer/cache/cache.js.map +1 -1
- package/dist/renderer/cache/markerCommandCache.js.map +1 -1
- package/dist/renderer/cache/strokeMeshCache.js.map +1 -1
- package/dist/renderer/cullDrawCommands.js +11 -11
- package/dist/renderer/draw/batch.js +133 -0
- package/dist/renderer/draw/batch.js.map +1 -0
- package/dist/renderer/draw/clip.js +89 -0
- package/dist/renderer/draw/clip.js.map +1 -0
- package/dist/renderer/draw/customShader.js +230 -0
- package/dist/renderer/draw/customShader.js.map +1 -0
- package/dist/renderer/draw/drawTriangles.js +8 -0
- package/dist/renderer/draw/drawTriangles.js.map +1 -0
- package/dist/renderer/draw/effects.js +28 -0
- package/dist/renderer/draw/effects.js.map +1 -0
- package/dist/renderer/draw/flushBatch.js +35 -0
- package/dist/renderer/draw/flushBatch.js.map +1 -0
- package/dist/renderer/draw/gradient.js +90 -0
- package/dist/renderer/draw/gradient.js.map +1 -0
- package/dist/renderer/draw/image.js +38 -0
- package/dist/renderer/draw/image.js.map +1 -0
- package/dist/renderer/draw/mesh.js +16 -0
- package/dist/renderer/draw/mesh.js.map +1 -0
- package/dist/renderer/draw/paintBind.js +70 -0
- package/dist/renderer/draw/paintBind.js.map +1 -0
- package/dist/renderer/draw/pathPaint.js +142 -0
- package/dist/renderer/draw/pathPaint.js.map +1 -0
- package/dist/renderer/draw/scratchPass.js +83 -0
- package/dist/renderer/draw/scratchPass.js.map +1 -0
- package/dist/renderer/draw/stencil.js +28 -0
- package/dist/renderer/draw/stencil.js.map +1 -0
- package/dist/renderer/draw/text.js +167 -0
- package/dist/renderer/draw/text.js.map +1 -0
- package/dist/renderer/draw/uniforms.js +77 -0
- package/dist/renderer/draw/uniforms.js.map +1 -0
- package/dist/renderer/draw.js +60 -1116
- package/dist/renderer/draw.js.map +1 -1
- package/dist/renderer/effects/EffectTargets.js +3 -0
- package/dist/renderer/effects/EffectTargets.js.map +1 -1
- package/dist/renderer/effects/composite.js +7 -5
- package/dist/renderer/effects/composite.js.map +1 -1
- package/dist/renderer/index.js +18 -17
- package/dist/renderer/math/color.js +63 -83
- package/dist/renderer/math/color.js.map +1 -1
- package/dist/renderer/math/mat3.js +15 -11
- package/dist/renderer/math/mat3.js.map +1 -1
- package/dist/renderer/math/viewToMat3.js +1 -1
- package/dist/renderer/math/viewToMat3.js.map +1 -1
- package/dist/renderer/shaders/ShaderProgram.js +13 -13
- package/dist/renderer/shaders/ShaderProgram.js.map +1 -1
- package/dist/renderer/shaders/glyphPaint.js +3 -3
- package/dist/renderer/shaders/glyphPaint.js.map +1 -1
- package/dist/renderer/shaders/gradFill.js +2 -1
- package/dist/renderer/shaders/gradFill.js.map +1 -1
- package/dist/renderer/shaders/pathFill.js +2 -1
- package/dist/renderer/shaders/pathFill.js.map +1 -1
- package/dist/renderer/shaders/patternFill.js +2 -1
- package/dist/renderer/shaders/patternFill.js.map +1 -1
- package/dist/renderer/shaders/registerProgram.js.map +1 -1
- package/dist/renderer/strokeLengths.js.map +1 -1
- package/dist/renderer/textures/registerTexture.js +25 -5
- package/dist/renderer/textures/registerTexture.js.map +1 -1
- package/dist/renderer.d.ts +16 -15
- package/dist/renderer.js +17 -16
- package/dist/resize.d.ts +5 -6
- package/dist/resize.js +5 -5
- package/dist/style.css +1 -1
- package/dist/test-hook/install.js +12 -6
- package/dist/test-hook/install.js.map +1 -1
- package/dist/{test-seams-CuIxe0xY.d.ts → test-seams-DM2B87-g.d.ts} +4 -4
- package/dist/test-seams.d.ts +2 -2
- package/dist/tools/builtin/ellipse/useEllipseTool.js +1 -0
- package/dist/tools/builtin/ellipse/useEllipseTool.js.map +1 -1
- package/dist/tools/builtin/hand/useHandTool.js +1 -0
- package/dist/tools/builtin/hand/useHandTool.js.map +1 -1
- package/dist/tools/builtin/lasso/useLassoTool.js +11 -11
- package/dist/tools/builtin/lasso/useLassoTool.js.map +1 -1
- package/dist/tools/builtin/line/useLineTool.js +1 -0
- package/dist/tools/builtin/line/useLineTool.js.map +1 -1
- package/dist/tools/builtin/pen/usePenTool.js +153 -103
- package/dist/tools/builtin/pen/usePenTool.js.map +1 -1
- package/dist/tools/builtin/pencil/usePencilTool.js +1 -0
- package/dist/tools/builtin/pencil/usePencilTool.js.map +1 -1
- package/dist/tools/builtin/polygon/usePolygonTool.js +13 -8
- package/dist/tools/builtin/polygon/usePolygonTool.js.map +1 -1
- package/dist/tools/builtin/rect/useRectTool.js +1 -0
- package/dist/tools/builtin/rect/useRectTool.js.map +1 -1
- package/dist/tools/builtin/select/selectionContributions.js +24 -23
- package/dist/tools/builtin/select/selectionContributions.js.map +1 -1
- package/dist/tools/builtin/select/useSelectTool.js +51 -48
- package/dist/tools/builtin/select/useSelectTool.js.map +1 -1
- package/dist/tools/builtin/shared/pointerFollower.js +17 -0
- package/dist/tools/builtin/shared/pointerFollower.js.map +1 -0
- package/dist/tools/builtin/slice/useSliceTool.js +49 -54
- package/dist/tools/builtin/slice/useSliceTool.js.map +1 -1
- package/dist/tools/builtin/star/useStarTool.js +22 -16
- package/dist/tools/builtin/star/useStarTool.js.map +1 -1
- package/dist/tools/builtin/text/useTextTool.js +13 -2
- package/dist/tools/builtin/text/useTextTool.js.map +1 -1
- package/dist/tools/useKeybindings.js +14 -30
- package/dist/tools/useKeybindings.js.map +1 -1
- package/dist/{types-B_9g6hMM.d.ts → types-B4iJRHC3.d.ts} +5 -1
- package/dist/{types-A37hYkeR.d.ts → types-k-5Oqh-U.d.ts} +31 -7
- package/dist/util/color.js +3 -3
- package/dist/util/color.js.map +1 -1
- package/dist/util/paint.js.map +1 -1
- package/dist/version.js +1 -1
- package/package.json +20 -18
- package/dist/autoPoseDescriptor-vCdt55xm.d.ts +0 -27
- package/dist/builtins-C-VgUlWI.d.ts +0 -4514
- package/dist/core/isPlainObject.js.map +0 -1
- package/dist/debug/flag.js.map +0 -1
- package/dist/interactions/actions/defaults/freshNodeId.js +0 -10
- package/dist/interactions/actions/defaults/freshNodeId.js.map +0 -1
- package/dist/renderer/shaders/imageFill.js +0 -14
- package/dist/renderer/shaders/imageFill.js.map +0 -1
- package/dist/tools/prefs.js +0 -47
- package/dist/tools/prefs.js.map +0 -1
|
@@ -1,91 +1,71 @@
|
|
|
1
|
-
import { hslToSrgb as e } from "@weasel-js/paint";
|
|
1
|
+
import { hslToSrgb as e, parseHexBytes as t } from "@weasel-js/paint";
|
|
2
2
|
//#region src/renderer/math/color.ts
|
|
3
|
-
function
|
|
4
|
-
let t =
|
|
3
|
+
function n(e) {
|
|
4
|
+
let t = r.get(e);
|
|
5
5
|
if (t !== void 0) return t;
|
|
6
|
-
let
|
|
7
|
-
return
|
|
6
|
+
let n = a(e);
|
|
7
|
+
return r.size >= i && r.clear(), r.set(e, n), n;
|
|
8
8
|
}
|
|
9
|
-
var
|
|
10
|
-
function
|
|
9
|
+
var r = /* @__PURE__ */ new Map(), i = 1024;
|
|
10
|
+
function a(e) {
|
|
11
11
|
let t = e.trim();
|
|
12
|
-
if (t.startsWith("#")) return
|
|
13
|
-
let n = t.toLowerCase(), r =
|
|
12
|
+
if (t.startsWith("#")) return p(t);
|
|
13
|
+
let n = t.toLowerCase(), r = w[n];
|
|
14
14
|
if (r !== void 0) return r;
|
|
15
15
|
if (n.startsWith("rgb")) {
|
|
16
|
-
let e =
|
|
16
|
+
let e = v(n);
|
|
17
17
|
if (e) return e;
|
|
18
18
|
}
|
|
19
19
|
if (n.startsWith("hsl")) {
|
|
20
|
-
let e =
|
|
20
|
+
let e = y(n);
|
|
21
21
|
if (e) return e;
|
|
22
22
|
}
|
|
23
23
|
throw Error(`parseColor: unrecognized color "${e}"`);
|
|
24
24
|
}
|
|
25
|
-
var
|
|
26
|
-
function s(e) {
|
|
27
|
-
let n = o.get(e);
|
|
28
|
-
if (n) return n;
|
|
29
|
-
o.size >= a && o.clear();
|
|
30
|
-
let r = t(e);
|
|
31
|
-
return o.set(e, r), r;
|
|
32
|
-
}
|
|
25
|
+
var o = 1024, s = /* @__PURE__ */ new Map();
|
|
33
26
|
function c(e) {
|
|
34
|
-
let
|
|
27
|
+
let t = s.get(e);
|
|
28
|
+
if (t) return t;
|
|
29
|
+
s.size >= o && s.clear();
|
|
30
|
+
let r = n(e);
|
|
31
|
+
return s.set(e, r), r;
|
|
32
|
+
}
|
|
33
|
+
function l(e) {
|
|
34
|
+
let [t, r, i, a] = n(e);
|
|
35
35
|
return [
|
|
36
|
-
Math.round(
|
|
36
|
+
Math.round(t * 255),
|
|
37
37
|
Math.round(r * 255),
|
|
38
38
|
Math.round(i * 255),
|
|
39
39
|
Math.round(a * 255)
|
|
40
40
|
];
|
|
41
41
|
}
|
|
42
|
-
function l(e) {
|
|
43
|
-
let t = e.trim(), n = (t.startsWith("#") ? t.slice(1) : t).toLowerCase();
|
|
44
|
-
if (!/^[0-9a-f]+$/.test(n)) throw Error(`normalizeHex: invalid hex "${e}"`);
|
|
45
|
-
if (n.length === 3) return `#${n[0]}${n[0]}${n[1]}${n[1]}${n[2]}${n[2]}`;
|
|
46
|
-
if (n.length === 4) return `#${n[0]}${n[0]}${n[1]}${n[1]}${n[2]}${n[2]}${n[3]}${n[3]}`;
|
|
47
|
-
if (n.length === 6 || n.length === 8) return `#${n}`;
|
|
48
|
-
throw Error(`normalizeHex: invalid hex "${e}"`);
|
|
49
|
-
}
|
|
50
42
|
function u(e) {
|
|
51
|
-
|
|
43
|
+
let n = e.trim(), r = n.startsWith("#") ? n : `#${n}`, i = t(r);
|
|
44
|
+
if (!i) throw Error(`normalizeHex: invalid hex "${e}"`);
|
|
45
|
+
let a = i.map((e) => e.toString(16).padStart(2, "0")).join("");
|
|
46
|
+
return `#${r.length === 5 || r.length === 9 ? a : a.slice(0, 6)}`;
|
|
52
47
|
}
|
|
53
48
|
function d(e) {
|
|
49
|
+
return p(u(e));
|
|
50
|
+
}
|
|
51
|
+
function f(e) {
|
|
54
52
|
let [t, n, r] = e, i = e.length === 4 ? e[3] : 1, a = (e) => Math.max(0, Math.min(255, Math.round(e * 255))).toString(16).padStart(2, "0"), o = `#${a(t)}${a(n)}${a(r)}`;
|
|
55
53
|
return i >= 1 ? o : `${o}${a(i)}`;
|
|
56
54
|
}
|
|
57
|
-
function
|
|
58
|
-
let
|
|
59
|
-
if (
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
if (t.length === 4) return [
|
|
66
|
-
parseInt(t[0] + t[0], 16) / 255,
|
|
67
|
-
parseInt(t[1] + t[1], 16) / 255,
|
|
68
|
-
parseInt(t[2] + t[2], 16) / 255,
|
|
69
|
-
parseInt(t[3] + t[3], 16) / 255
|
|
70
|
-
];
|
|
71
|
-
if (t.length === 6) return [
|
|
72
|
-
parseInt(t.slice(0, 2), 16) / 255,
|
|
73
|
-
parseInt(t.slice(2, 4), 16) / 255,
|
|
74
|
-
parseInt(t.slice(4, 6), 16) / 255,
|
|
75
|
-
1
|
|
76
|
-
];
|
|
77
|
-
if (t.length === 8) return [
|
|
78
|
-
parseInt(t.slice(0, 2), 16) / 255,
|
|
79
|
-
parseInt(t.slice(2, 4), 16) / 255,
|
|
80
|
-
parseInt(t.slice(4, 6), 16) / 255,
|
|
81
|
-
parseInt(t.slice(6, 8), 16) / 255
|
|
55
|
+
function p(e) {
|
|
56
|
+
let n = t(e);
|
|
57
|
+
if (!n) throw Error(`parseColor: invalid hex "${e}"`);
|
|
58
|
+
return [
|
|
59
|
+
n[0] / 255,
|
|
60
|
+
n[1] / 255,
|
|
61
|
+
n[2] / 255,
|
|
62
|
+
n[3] / 255
|
|
82
63
|
];
|
|
83
|
-
throw Error(`parseColor: invalid hex "${e}"`);
|
|
84
64
|
}
|
|
85
|
-
function
|
|
65
|
+
function m(e, t) {
|
|
86
66
|
return !e.startsWith(t + "(") || !e.endsWith(")") ? null : e.slice(t.length + 1, -1).trim();
|
|
87
67
|
}
|
|
88
|
-
function
|
|
68
|
+
function h(e) {
|
|
89
69
|
if (e.includes(",")) {
|
|
90
70
|
let t = e.split(",").map((e) => e.trim());
|
|
91
71
|
return t.length !== 3 && t.length !== 4 ? null : {
|
|
@@ -107,68 +87,68 @@ function m(e) {
|
|
|
107
87
|
alpha: r
|
|
108
88
|
};
|
|
109
89
|
}
|
|
110
|
-
function
|
|
90
|
+
function g(e, t) {
|
|
111
91
|
if (e.endsWith("%")) {
|
|
112
92
|
let t = Number(e.slice(0, -1));
|
|
113
|
-
return Number.isFinite(t) ?
|
|
93
|
+
return Number.isFinite(t) ? C(t / 100) : null;
|
|
114
94
|
}
|
|
115
95
|
let n = Number(e);
|
|
116
|
-
return Number.isFinite(n) ?
|
|
96
|
+
return Number.isFinite(n) ? C(n / t) : null;
|
|
117
97
|
}
|
|
118
|
-
function
|
|
98
|
+
function _(e) {
|
|
119
99
|
if (e === null) return 1;
|
|
120
100
|
if (e.endsWith("%")) {
|
|
121
101
|
let t = Number(e.slice(0, -1));
|
|
122
|
-
return Number.isFinite(t) ?
|
|
102
|
+
return Number.isFinite(t) ? C(t / 100) : 1;
|
|
123
103
|
}
|
|
124
104
|
let t = Number(e);
|
|
125
|
-
return Number.isFinite(t) ?
|
|
105
|
+
return Number.isFinite(t) ? C(t) : 1;
|
|
126
106
|
}
|
|
127
|
-
function
|
|
128
|
-
let t =
|
|
107
|
+
function v(e) {
|
|
108
|
+
let t = m(e, "rgba") ?? m(e, "rgb");
|
|
129
109
|
if (t === null) return null;
|
|
130
|
-
let n =
|
|
110
|
+
let n = h(t);
|
|
131
111
|
if (!n) return null;
|
|
132
|
-
let r =
|
|
112
|
+
let r = g(n.rgb[0], 255), i = g(n.rgb[1], 255), a = g(n.rgb[2], 255);
|
|
133
113
|
return r === null || i === null || a === null ? null : [
|
|
134
114
|
r,
|
|
135
115
|
i,
|
|
136
116
|
a,
|
|
137
|
-
|
|
117
|
+
_(n.alpha)
|
|
138
118
|
];
|
|
139
119
|
}
|
|
140
|
-
function
|
|
141
|
-
let t =
|
|
120
|
+
function y(e) {
|
|
121
|
+
let t = m(e, "hsla") ?? m(e, "hsl");
|
|
142
122
|
if (t === null) return null;
|
|
143
|
-
let n =
|
|
123
|
+
let n = h(t);
|
|
144
124
|
if (!n) return null;
|
|
145
|
-
let r =
|
|
125
|
+
let r = b(n.rgb[0]), i = x(n.rgb[1]), a = x(n.rgb[2]);
|
|
146
126
|
if (r === null || i === null || a === null) return null;
|
|
147
|
-
let [o, s, c] =
|
|
127
|
+
let [o, s, c] = S(r, i, a);
|
|
148
128
|
return [
|
|
149
129
|
o,
|
|
150
130
|
s,
|
|
151
131
|
c,
|
|
152
|
-
|
|
132
|
+
_(n.alpha)
|
|
153
133
|
];
|
|
154
134
|
}
|
|
155
|
-
function
|
|
135
|
+
function b(e) {
|
|
156
136
|
let t;
|
|
157
137
|
return t = e.endsWith("deg") ? Number(e.slice(0, -3)) : e.endsWith("grad") ? Number(e.slice(0, -4)) * .9 : e.endsWith("rad") ? Number(e.slice(0, -3)) * (180 / Math.PI) : e.endsWith("turn") ? Number(e.slice(0, -4)) * 360 : Number(e), Number.isFinite(t) ? (t % 360 + 360) % 360 : null;
|
|
158
138
|
}
|
|
159
|
-
function
|
|
139
|
+
function x(e) {
|
|
160
140
|
if (e.endsWith("%")) {
|
|
161
141
|
let t = Number(e.slice(0, -1));
|
|
162
|
-
return Number.isFinite(t) ?
|
|
142
|
+
return Number.isFinite(t) ? C(t / 100) : null;
|
|
163
143
|
}
|
|
164
144
|
let t = Number(e);
|
|
165
|
-
return Number.isFinite(t) ?
|
|
145
|
+
return Number.isFinite(t) ? C(t) : null;
|
|
166
146
|
}
|
|
167
|
-
var
|
|
168
|
-
function
|
|
147
|
+
var S = e;
|
|
148
|
+
function C(e) {
|
|
169
149
|
return e < 0 ? 0 : e > 1 ? 1 : e;
|
|
170
150
|
}
|
|
171
|
-
var
|
|
151
|
+
var w = (() => {
|
|
172
152
|
let e = {
|
|
173
153
|
aliceblue: 15792383,
|
|
174
154
|
antiquewhite: 16444375,
|
|
@@ -336,6 +316,6 @@ var C = (() => {
|
|
|
336
316
|
return t;
|
|
337
317
|
})();
|
|
338
318
|
//#endregion
|
|
339
|
-
export {
|
|
319
|
+
export { d as hexToRgba, S as hslToRgb, u as normalizeHex, n as parseColor, l as parseColorToRgba255, c as resolveColor, f as rgbaToHex };
|
|
340
320
|
|
|
341
321
|
//# sourceMappingURL=color.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"color.js","names":["parseColor","cached","CACHE","input","result","parseColorUncached","CACHE_MAX","s","parseHex","lower","named","NAMED_COLORS","parsed","parseRgbFunction","parseHslFunction","RESOLVE_COLOR_CACHE_CAP","resolveColorCache","resolveColor","hit","frozen","parseColorToRgba255","r","g","b","normalizeHex","trimmed","body","hexToRgba","rgbaToHex","rgba","a","f","n","base","hex","unwrapFn","name","splitChannels","parts","p","slash","head","alpha","parseChannel","tok","clamp01","max","parseAlpha","channels","h","parseHue","sat","parsePercentOrNumber","lit","hslToRgb","hslToSrgb","out"],"sources":["../../../src/renderer/math/color.ts"],"sourcesContent":["import { hslToSrgb } from '@weasel-js/paint';\n\n/**\n * Parse a CSS color string into [r, g, b, a] with 0..1 components.\n *\n * Supported forms:\n * - Hex: `#rgb`, `#rgba`, `#rrggbb`, `#rrggbbaa` (any case)\n * - `rgb()` / `rgba()` with integer, float, or percent R/G/B; number or\n * percent alpha; commas or modern space-separated `R G B / A` syntax\n * - `hsl()` / `hsla()` with hue as a unitless number (deg) or with `deg`,\n * `rad`, `grad`, `turn` units; saturation/lightness as percent (or\n * unitless in the modern syntax); same alpha rules and separator rules\n * as `rgb()`\n * - The 148 CSS named colors plus `transparent`\n *\n * Not supported: `oklch()`, `lab()`, `color()`, `currentColor`, system\n * colors. Throws on anything unrecognized.\n *\n * Results are cached by input-string identity. Callers MUST treat the\n * returned tuple as read-only — mutation would corrupt the cache.\n */\nexport function parseColor(input: string): [number, number, number, number] {\n const cached = CACHE.get(input);\n if (cached !== undefined) return cached;\n const result = parseColorUncached(input);\n if (CACHE.size >= CACHE_MAX) CACHE.clear();\n CACHE.set(input, result);\n return result;\n}\n\nconst CACHE = new Map<string, [number, number, number, number]>();\nconst CACHE_MAX = 1024;\n\nfunction parseColorUncached(input: string): [number, number, number, number] {\n const s = input.trim();\n if (s.startsWith('#')) return parseHex(s);\n\n const lower = s.toLowerCase();\n\n // Named colors and `transparent` are checked before fn() forms because the\n // fn() regexes won't match them anyway and the lookup is cheaper than a\n // failed regex match.\n const named = NAMED_COLORS[lower];\n if (named !== undefined) return named;\n\n if (lower.startsWith('rgb')) {\n const parsed = parseRgbFunction(lower);\n if (parsed) return parsed;\n }\n if (lower.startsWith('hsl')) {\n const parsed = parseHslFunction(lower);\n if (parsed) return parsed;\n }\n\n throw new Error(`parseColor: unrecognized color \"${input}\"`);\n}\n\nconst RESOLVE_COLOR_CACHE_CAP = 1024;\nconst resolveColorCache = new Map<string, readonly [number, number, number, number]>();\n\n/** Cached `parseColor`. Use this from renderer hot paths (per-frame draw\n * callbacks, gradient ramp builds) so repeated color strings — which are\n * common when many objects share a fill — don't re-tokenize each frame.\n *\n * Cache is keyed by input-string identity, capped at ~1024 entries, and\n * cleared wholesale on overflow (no LRU tracking — simple is fine since\n * the working set in any one app is typically much smaller than the cap). */\nexport function resolveColor(input: string): readonly [number, number, number, number] {\n const hit = resolveColorCache.get(input);\n if (hit) return hit;\n if (resolveColorCache.size >= RESOLVE_COLOR_CACHE_CAP) {\n resolveColorCache.clear();\n }\n const parsed = parseColor(input);\n const frozen = parsed as readonly [number, number, number, number];\n resolveColorCache.set(input, frozen);\n return frozen;\n}\n\n/** @internal Test-only: drops the resolveColor memoization cache so tests\n * can assert behavior in isolation. Never call from production code. */\nexport function __resetResolveColorCache(): void {\n resolveColorCache.clear();\n}\n\n/** Same as `parseColor` but returns integer 0..255 components. */\nexport function parseColorToRgba255(input: string): [number, number, number, number] {\n const [r, g, b, a] = parseColor(input);\n return [\n Math.round(r * 255),\n Math.round(g * 255),\n Math.round(b * 255),\n Math.round(a * 255),\n ];\n}\n\n/**\n * Canonicalize a hex color string to lowercase `#rrggbb` or `#rrggbbaa`.\n *\n * Accepts: `#rgb`, `#rgba`, `#rrggbb`, `#rrggbbaa`, with or without the\n * leading `#`, any case. Throws on other inputs.\n */\nexport function normalizeHex(input: string): string {\n const trimmed = input.trim();\n const body = (trimmed.startsWith('#') ? trimmed.slice(1) : trimmed).toLowerCase();\n if (!/^[0-9a-f]+$/.test(body)) {\n throw new Error(`normalizeHex: invalid hex \"${input}\"`);\n }\n if (body.length === 3) {\n return `#${body[0]}${body[0]}${body[1]}${body[1]}${body[2]}${body[2]}`;\n }\n if (body.length === 4) {\n return `#${body[0]}${body[0]}${body[1]}${body[1]}${body[2]}${body[2]}${body[3]}${body[3]}`;\n }\n if (body.length === 6 || body.length === 8) {\n return `#${body}`;\n }\n throw new Error(`normalizeHex: invalid hex \"${input}\"`);\n}\n\n/**\n * Parse a hex color into [r, g, b, a] with 0..1 components. Accepts the same\n * forms as `normalizeHex`, including a missing leading `#`.\n */\nexport function hexToRgba(input: string): [number, number, number, number] {\n return parseHex(normalizeHex(input));\n}\n\n/**\n * Format [r, g, b, a] (0..1 components) as a hex string. Emits `#rrggbb` when\n * alpha is exactly 1 (or omitted), otherwise `#rrggbbaa`.\n */\nexport function rgbaToHex(rgba: readonly [number, number, number, number] | readonly [number, number, number]): string {\n const [r, g, b] = rgba;\n const a = rgba.length === 4 ? rgba[3] : 1;\n const f = (n: number) => Math.max(0, Math.min(255, Math.round(n * 255))).toString(16).padStart(2, '0');\n const base = `#${f(r)}${f(g)}${f(b)}`;\n return a >= 1 ? base : `${base}${f(a)}`;\n}\n\nfunction parseHex(s: string): [number, number, number, number] {\n const hex = s.slice(1);\n if (hex.length === 3) {\n return [\n parseInt(hex[0] + hex[0], 16) / 255,\n parseInt(hex[1] + hex[1], 16) / 255,\n parseInt(hex[2] + hex[2], 16) / 255,\n 1,\n ];\n }\n if (hex.length === 4) {\n return [\n parseInt(hex[0] + hex[0], 16) / 255,\n parseInt(hex[1] + hex[1], 16) / 255,\n parseInt(hex[2] + hex[2], 16) / 255,\n parseInt(hex[3] + hex[3], 16) / 255,\n ];\n }\n if (hex.length === 6) {\n return [\n parseInt(hex.slice(0, 2), 16) / 255,\n parseInt(hex.slice(2, 4), 16) / 255,\n parseInt(hex.slice(4, 6), 16) / 255,\n 1,\n ];\n }\n if (hex.length === 8) {\n return [\n parseInt(hex.slice(0, 2), 16) / 255,\n parseInt(hex.slice(2, 4), 16) / 255,\n parseInt(hex.slice(4, 6), 16) / 255,\n parseInt(hex.slice(6, 8), 16) / 255,\n ];\n }\n throw new Error(`parseColor: invalid hex \"${s}\"`);\n}\n\n/** Match `name( body )` and return the trimmed body, or null. */\nfunction unwrapFn(s: string, name: string): string | null {\n if (!s.startsWith(name + '(') || !s.endsWith(')')) return null;\n return s.slice(name.length + 1, -1).trim();\n}\n\n/**\n * Split a function body into the value tokens (3 channels + optional alpha).\n * Supports both legacy `r, g, b[, a]` and modern `r g b[ / a]` separators.\n * Returns null if the token count is wrong.\n */\nfunction splitChannels(body: string): { rgb: [string, string, string]; alpha: string | null } | null {\n if (body.includes(',')) {\n const parts = body.split(',').map((p) => p.trim());\n if (parts.length !== 3 && parts.length !== 4) return null;\n return {\n rgb: [parts[0], parts[1], parts[2]],\n alpha: parts.length === 4 ? parts[3] : null,\n };\n }\n // Modern syntax: whitespace-separated, with optional `/ alpha` tail.\n const slash = body.indexOf('/');\n const head = (slash === -1 ? body : body.slice(0, slash)).trim();\n const alpha = slash === -1 ? null : body.slice(slash + 1).trim();\n const parts = head.split(/\\s+/);\n if (parts.length !== 3) return null;\n if (alpha !== null && alpha === '') return null;\n return { rgb: [parts[0], parts[1], parts[2]], alpha };\n}\n\n/** Parse a channel value: integer, float, or percent. Returns 0..1 (with `max` as the integer scale). */\nfunction parseChannel(tok: string, max: number): number | null {\n if (tok.endsWith('%')) {\n const n = Number(tok.slice(0, -1));\n if (!Number.isFinite(n)) return null;\n return clamp01(n / 100);\n }\n const n = Number(tok);\n if (!Number.isFinite(n)) return null;\n return clamp01(n / max);\n}\n\n/** Alpha may be a number 0..1 or a percent. */\nfunction parseAlpha(tok: string | null): number {\n if (tok === null) return 1;\n if (tok.endsWith('%')) {\n const n = Number(tok.slice(0, -1));\n return Number.isFinite(n) ? clamp01(n / 100) : 1;\n }\n const n = Number(tok);\n return Number.isFinite(n) ? clamp01(n) : 1;\n}\n\nfunction parseRgbFunction(s: string): [number, number, number, number] | null {\n const body = unwrapFn(s, 'rgba') ?? unwrapFn(s, 'rgb');\n if (body === null) return null;\n const channels = splitChannels(body);\n if (!channels) return null;\n const r = parseChannel(channels.rgb[0], 255);\n const g = parseChannel(channels.rgb[1], 255);\n const b = parseChannel(channels.rgb[2], 255);\n if (r === null || g === null || b === null) return null;\n return [r, g, b, parseAlpha(channels.alpha)];\n}\n\nfunction parseHslFunction(s: string): [number, number, number, number] | null {\n const body = unwrapFn(s, 'hsla') ?? unwrapFn(s, 'hsl');\n if (body === null) return null;\n const channels = splitChannels(body);\n if (!channels) return null;\n const h = parseHue(channels.rgb[0]);\n const sat = parsePercentOrNumber(channels.rgb[1]);\n const lit = parsePercentOrNumber(channels.rgb[2]);\n if (h === null || sat === null || lit === null) return null;\n const [r, g, b] = hslToRgb(h, sat, lit);\n return [r, g, b, parseAlpha(channels.alpha)];\n}\n\n/** Parse a hue token: `<number>`, `<number>deg`, `<number>rad`, `<number>grad`, `<number>turn`. Returns degrees 0..360 (modulo). */\nfunction parseHue(tok: string): number | null {\n let n: number;\n if (tok.endsWith('deg')) n = Number(tok.slice(0, -3));\n else if (tok.endsWith('grad')) n = Number(tok.slice(0, -4)) * 0.9; // 400grad = 360deg\n else if (tok.endsWith('rad')) n = Number(tok.slice(0, -3)) * (180 / Math.PI);\n else if (tok.endsWith('turn')) n = Number(tok.slice(0, -4)) * 360;\n else n = Number(tok);\n if (!Number.isFinite(n)) return null;\n return ((n % 360) + 360) % 360;\n}\n\n/** Saturation/lightness may be percent (CSS Color 3) or unitless number 0..1 (modern). */\nfunction parsePercentOrNumber(tok: string): number | null {\n if (tok.endsWith('%')) {\n const n = Number(tok.slice(0, -1));\n return Number.isFinite(n) ? clamp01(n / 100) : null;\n }\n const n = Number(tok);\n return Number.isFinite(n) ? clamp01(n) : null;\n}\n\n/**\n * HSL → RGB, all components 0..1 except hue in degrees (0..360). paint's\n * `hslToSrgb` under the name this file's callers use.\n *\n * @internal Not part of the public API; not re-exported from the barrel.\n */\nexport const hslToRgb = hslToSrgb;\n\nfunction clamp01(n: number): number {\n return n < 0 ? 0 : n > 1 ? 1 : n;\n}\n\n// CSS Color Module Level 4 named colors. Stored as already-resolved tuples so\n// lookup is O(1) and avoids a second parse hop.\nconst NAMED_COLORS: Record<string, [number, number, number, number]> = (() => {\n const hex: Record<string, number> = {\n aliceblue: 0xf0f8ff, antiquewhite: 0xfaebd7, aqua: 0x00ffff, aquamarine: 0x7fffd4,\n azure: 0xf0ffff, beige: 0xf5f5dc, bisque: 0xffe4c4, black: 0x000000,\n blanchedalmond: 0xffebcd, blue: 0x0000ff, blueviolet: 0x8a2be2, brown: 0xa52a2a,\n burlywood: 0xdeb887, cadetblue: 0x5f9ea0, chartreuse: 0x7fff00, chocolate: 0xd2691e,\n coral: 0xff7f50, cornflowerblue: 0x6495ed, cornsilk: 0xfff8dc, crimson: 0xdc143c,\n cyan: 0x00ffff, darkblue: 0x00008b, darkcyan: 0x008b8b, darkgoldenrod: 0xb8860b,\n darkgray: 0xa9a9a9, darkgreen: 0x006400, darkgrey: 0xa9a9a9, darkkhaki: 0xbdb76b,\n darkmagenta: 0x8b008b, darkolivegreen: 0x556b2f, darkorange: 0xff8c00, darkorchid: 0x9932cc,\n darkred: 0x8b0000, darksalmon: 0xe9967a, darkseagreen: 0x8fbc8f, darkslateblue: 0x483d8b,\n darkslategray: 0x2f4f4f, darkslategrey: 0x2f4f4f, darkturquoise: 0x00ced1, darkviolet: 0x9400d3,\n deeppink: 0xff1493, deepskyblue: 0x00bfff, dimgray: 0x696969, dimgrey: 0x696969,\n dodgerblue: 0x1e90ff, firebrick: 0xb22222, floralwhite: 0xfffaf0, forestgreen: 0x228b22,\n fuchsia: 0xff00ff, gainsboro: 0xdcdcdc, ghostwhite: 0xf8f8ff, gold: 0xffd700,\n goldenrod: 0xdaa520, gray: 0x808080, green: 0x008000, greenyellow: 0xadff2f,\n grey: 0x808080, honeydew: 0xf0fff0, hotpink: 0xff69b4, indianred: 0xcd5c5c,\n indigo: 0x4b0082, ivory: 0xfffff0, khaki: 0xf0e68c, lavender: 0xe6e6fa,\n lavenderblush: 0xfff0f5, lawngreen: 0x7cfc00, lemonchiffon: 0xfffacd, lightblue: 0xadd8e6,\n lightcoral: 0xf08080, lightcyan: 0xe0ffff, lightgoldenrodyellow: 0xfafad2, lightgray: 0xd3d3d3,\n lightgreen: 0x90ee90, lightgrey: 0xd3d3d3, lightpink: 0xffb6c1, lightsalmon: 0xffa07a,\n lightseagreen: 0x20b2aa, lightskyblue: 0x87cefa, lightslategray: 0x778899, lightslategrey: 0x778899,\n lightsteelblue: 0xb0c4de, lightyellow: 0xffffe0, lime: 0x00ff00, limegreen: 0x32cd32,\n linen: 0xfaf0e6, magenta: 0xff00ff, maroon: 0x800000, mediumaquamarine: 0x66cdaa,\n mediumblue: 0x0000cd, mediumorchid: 0xba55d3, mediumpurple: 0x9370db, mediumseagreen: 0x3cb371,\n mediumslateblue: 0x7b68ee, mediumspringgreen: 0x00fa9a, mediumturquoise: 0x48d1cc, mediumvioletred: 0xc71585,\n midnightblue: 0x191970, mintcream: 0xf5fffa, mistyrose: 0xffe4e1, moccasin: 0xffe4b5,\n navajowhite: 0xffdead, navy: 0x000080, oldlace: 0xfdf5e6, olive: 0x808000,\n olivedrab: 0x6b8e23, orange: 0xffa500, orangered: 0xff4500, orchid: 0xda70d6,\n palegoldenrod: 0xeee8aa, palegreen: 0x98fb98, paleturquoise: 0xafeeee, palevioletred: 0xdb7093,\n papayawhip: 0xffefd5, peachpuff: 0xffdab9, peru: 0xcd853f, pink: 0xffc0cb,\n plum: 0xdda0dd, powderblue: 0xb0e0e6, purple: 0x800080, rebeccapurple: 0x663399,\n red: 0xff0000, rosybrown: 0xbc8f8f, royalblue: 0x4169e1, saddlebrown: 0x8b4513,\n salmon: 0xfa8072, sandybrown: 0xf4a460, seagreen: 0x2e8b57, seashell: 0xfff5ee,\n sienna: 0xa0522d, silver: 0xc0c0c0, skyblue: 0x87ceeb, slateblue: 0x6a5acd,\n slategray: 0x708090, slategrey: 0x708090, snow: 0xfffafa, springgreen: 0x00ff7f,\n steelblue: 0x4682b4, tan: 0xd2b48c, teal: 0x008080, thistle: 0xd8bfd8,\n tomato: 0xff6347, turquoise: 0x40e0d0, violet: 0xee82ee, wheat: 0xf5deb3,\n white: 0xffffff, whitesmoke: 0xf5f5f5, yellow: 0xffff00, yellowgreen: 0x9acd32,\n };\n const out: Record<string, [number, number, number, number]> = {\n transparent: [0, 0, 0, 0],\n };\n for (const name in hex) {\n const n = hex[name];\n out[name] = [((n >> 16) & 0xff) / 255, ((n >> 8) & 0xff) / 255, (n & 0xff) / 255, 1];\n }\n return out;\n})();\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"color.js","names":["parseColor","cached","CACHE","input","result","parseColorUncached","CACHE_MAX","s","parseHex","lower","named","NAMED_COLORS","parsed","parseRgbFunction","parseHslFunction","RESOLVE_COLOR_CACHE_CAP","resolveColorCache","resolveColor","hit","frozen","parseColorToRgba255","r","g","b","normalizeHex","trimmed","hashed","bytes","parseHexBytes","digits","n","hexToRgba","rgbaToHex","rgba","a","f","base","unwrapFn","name","splitChannels","body","parts","p","slash","head","alpha","parseChannel","tok","clamp01","max","parseAlpha","channels","h","parseHue","sat","parsePercentOrNumber","lit","hslToRgb","hslToSrgb","hex","out"],"sources":["../../../src/renderer/math/color.ts"],"sourcesContent":["import { hslToSrgb, parseHexBytes } from '@weasel-js/paint';\n\n/**\n * Parse a CSS color string into [r, g, b, a] with 0..1 components.\n *\n * Supported forms:\n * - Hex: `#rgb`, `#rgba`, `#rrggbb`, `#rrggbbaa` (any case)\n * - `rgb()` / `rgba()` with integer, float, or percent R/G/B; number or\n * percent alpha; commas or modern space-separated `R G B / A` syntax\n * - `hsl()` / `hsla()` with hue as a unitless number (deg) or with `deg`,\n * `rad`, `grad`, `turn` units; saturation/lightness as percent (or\n * unitless in the modern syntax); same alpha rules and separator rules\n * as `rgb()`\n * - The 148 CSS named colors plus `transparent`\n *\n * Not supported: `oklch()`, `lab()`, `color()`, `currentColor`, system\n * colors. Throws on anything unrecognized.\n *\n * Results are cached by input-string identity. Callers MUST treat the\n * returned tuple as read-only — mutation would corrupt the cache.\n */\nexport function parseColor(input: string): [number, number, number, number] {\n const cached = CACHE.get(input);\n if (cached !== undefined) return cached;\n const result = parseColorUncached(input);\n if (CACHE.size >= CACHE_MAX) CACHE.clear();\n CACHE.set(input, result);\n return result;\n}\n\nconst CACHE = new Map<string, [number, number, number, number]>();\nconst CACHE_MAX = 1024;\n\nfunction parseColorUncached(input: string): [number, number, number, number] {\n const s = input.trim();\n if (s.startsWith('#')) return parseHex(s);\n\n const lower = s.toLowerCase();\n\n // Named colors and `transparent` are checked before fn() forms because the\n // fn() regexes won't match them anyway and the lookup is cheaper than a\n // failed regex match.\n const named = NAMED_COLORS[lower];\n if (named !== undefined) return named;\n\n if (lower.startsWith('rgb')) {\n const parsed = parseRgbFunction(lower);\n if (parsed) return parsed;\n }\n if (lower.startsWith('hsl')) {\n const parsed = parseHslFunction(lower);\n if (parsed) return parsed;\n }\n\n throw new Error(`parseColor: unrecognized color \"${input}\"`);\n}\n\nconst RESOLVE_COLOR_CACHE_CAP = 1024;\nconst resolveColorCache = new Map<string, readonly [number, number, number, number]>();\n\n/** Cached `parseColor`. Use this from renderer hot paths (per-frame draw\n * callbacks, gradient ramp builds) so repeated color strings — which are\n * common when many objects share a fill — don't re-tokenize each frame.\n *\n * Cache is keyed by input-string identity, capped at ~1024 entries, and\n * cleared wholesale on overflow (no LRU tracking — simple is fine since\n * the working set in any one app is typically much smaller than the cap). */\nexport function resolveColor(input: string): readonly [number, number, number, number] {\n const hit = resolveColorCache.get(input);\n if (hit) return hit;\n if (resolveColorCache.size >= RESOLVE_COLOR_CACHE_CAP) {\n resolveColorCache.clear();\n }\n const parsed = parseColor(input);\n const frozen = parsed as readonly [number, number, number, number];\n resolveColorCache.set(input, frozen);\n return frozen;\n}\n\n/** @internal Test-only: drops the resolveColor memoization cache so tests\n * can assert behavior in isolation. Never call from production code. */\nexport function __resetResolveColorCache(): void {\n resolveColorCache.clear();\n}\n\n/** Same as `parseColor` but returns integer 0..255 components. */\nexport function parseColorToRgba255(input: string): [number, number, number, number] {\n const [r, g, b, a] = parseColor(input);\n return [\n Math.round(r * 255),\n Math.round(g * 255),\n Math.round(b * 255),\n Math.round(a * 255),\n ];\n}\n\n/**\n * Canonicalize a hex color string to lowercase `#rrggbb` or `#rrggbbaa`.\n *\n * Accepts: `#rgb`, `#rgba`, `#rrggbb`, `#rrggbbaa`, with or without the\n * leading `#`, any case. Throws on other inputs.\n */\nexport function normalizeHex(input: string): string {\n const trimmed = input.trim();\n const hashed = trimmed.startsWith('#') ? trimmed : `#${trimmed}`;\n const bytes = parseHexBytes(hashed);\n if (!bytes) throw new Error(`normalizeHex: invalid hex \"${input}\"`);\n const digits = bytes.map((n) => n.toString(16).padStart(2, '0')).join('');\n const namesAlpha = hashed.length === 5 || hashed.length === 9;\n return `#${namesAlpha ? digits : digits.slice(0, 6)}`;\n}\n\n/**\n * Parse a hex color into [r, g, b, a] with 0..1 components. Accepts the same\n * forms as `normalizeHex`, including a missing leading `#`.\n */\nexport function hexToRgba(input: string): [number, number, number, number] {\n return parseHex(normalizeHex(input));\n}\n\n/**\n * Format [r, g, b, a] (0..1 components) as a hex string. Emits `#rrggbb` when\n * alpha is exactly 1 (or omitted), otherwise `#rrggbbaa`.\n */\nexport function rgbaToHex(rgba: readonly [number, number, number, number] | readonly [number, number, number]): string {\n const [r, g, b] = rgba;\n const a = rgba.length === 4 ? rgba[3] : 1;\n const f = (n: number) => Math.max(0, Math.min(255, Math.round(n * 255))).toString(16).padStart(2, '0');\n const base = `#${f(r)}${f(g)}${f(b)}`;\n return a >= 1 ? base : `${base}${f(a)}`;\n}\n\nfunction parseHex(s: string): [number, number, number, number] {\n const bytes = parseHexBytes(s);\n if (!bytes) throw new Error(`parseColor: invalid hex \"${s}\"`);\n return [bytes[0] / 255, bytes[1] / 255, bytes[2] / 255, bytes[3] / 255];\n}\n\n/** Match `name( body )` and return the trimmed body, or null. */\nfunction unwrapFn(s: string, name: string): string | null {\n if (!s.startsWith(name + '(') || !s.endsWith(')')) return null;\n return s.slice(name.length + 1, -1).trim();\n}\n\n/**\n * Split a function body into the value tokens (3 channels + optional alpha).\n * Supports both legacy `r, g, b[, a]` and modern `r g b[ / a]` separators.\n * Returns null if the token count is wrong.\n */\nfunction splitChannels(body: string): { rgb: [string, string, string]; alpha: string | null } | null {\n if (body.includes(',')) {\n const parts = body.split(',').map((p) => p.trim());\n if (parts.length !== 3 && parts.length !== 4) return null;\n return {\n rgb: [parts[0], parts[1], parts[2]],\n alpha: parts.length === 4 ? parts[3] : null,\n };\n }\n // Modern syntax: whitespace-separated, with optional `/ alpha` tail.\n const slash = body.indexOf('/');\n const head = (slash === -1 ? body : body.slice(0, slash)).trim();\n const alpha = slash === -1 ? null : body.slice(slash + 1).trim();\n const parts = head.split(/\\s+/);\n if (parts.length !== 3) return null;\n if (alpha !== null && alpha === '') return null;\n return { rgb: [parts[0], parts[1], parts[2]], alpha };\n}\n\n/** Parse a channel value: integer, float, or percent. Returns 0..1 (with `max` as the integer scale). */\nfunction parseChannel(tok: string, max: number): number | null {\n if (tok.endsWith('%')) {\n const n = Number(tok.slice(0, -1));\n if (!Number.isFinite(n)) return null;\n return clamp01(n / 100);\n }\n const n = Number(tok);\n if (!Number.isFinite(n)) return null;\n return clamp01(n / max);\n}\n\n/** Alpha may be a number 0..1 or a percent. */\nfunction parseAlpha(tok: string | null): number {\n if (tok === null) return 1;\n if (tok.endsWith('%')) {\n const n = Number(tok.slice(0, -1));\n return Number.isFinite(n) ? clamp01(n / 100) : 1;\n }\n const n = Number(tok);\n return Number.isFinite(n) ? clamp01(n) : 1;\n}\n\nfunction parseRgbFunction(s: string): [number, number, number, number] | null {\n const body = unwrapFn(s, 'rgba') ?? unwrapFn(s, 'rgb');\n if (body === null) return null;\n const channels = splitChannels(body);\n if (!channels) return null;\n const r = parseChannel(channels.rgb[0], 255);\n const g = parseChannel(channels.rgb[1], 255);\n const b = parseChannel(channels.rgb[2], 255);\n if (r === null || g === null || b === null) return null;\n return [r, g, b, parseAlpha(channels.alpha)];\n}\n\nfunction parseHslFunction(s: string): [number, number, number, number] | null {\n const body = unwrapFn(s, 'hsla') ?? unwrapFn(s, 'hsl');\n if (body === null) return null;\n const channels = splitChannels(body);\n if (!channels) return null;\n const h = parseHue(channels.rgb[0]);\n const sat = parsePercentOrNumber(channels.rgb[1]);\n const lit = parsePercentOrNumber(channels.rgb[2]);\n if (h === null || sat === null || lit === null) return null;\n const [r, g, b] = hslToRgb(h, sat, lit);\n return [r, g, b, parseAlpha(channels.alpha)];\n}\n\n/** Parse a hue token: `<number>`, `<number>deg`, `<number>rad`, `<number>grad`, `<number>turn`. Returns degrees 0..360 (modulo). */\nfunction parseHue(tok: string): number | null {\n let n: number;\n if (tok.endsWith('deg')) n = Number(tok.slice(0, -3));\n else if (tok.endsWith('grad')) n = Number(tok.slice(0, -4)) * 0.9; // 400grad = 360deg\n else if (tok.endsWith('rad')) n = Number(tok.slice(0, -3)) * (180 / Math.PI);\n else if (tok.endsWith('turn')) n = Number(tok.slice(0, -4)) * 360;\n else n = Number(tok);\n if (!Number.isFinite(n)) return null;\n return ((n % 360) + 360) % 360;\n}\n\n/** Saturation/lightness may be percent (CSS Color 3) or unitless number 0..1 (modern). */\nfunction parsePercentOrNumber(tok: string): number | null {\n if (tok.endsWith('%')) {\n const n = Number(tok.slice(0, -1));\n return Number.isFinite(n) ? clamp01(n / 100) : null;\n }\n const n = Number(tok);\n return Number.isFinite(n) ? clamp01(n) : null;\n}\n\n/**\n * HSL → RGB, all components 0..1 except hue in degrees (0..360). paint's\n * `hslToSrgb` under the name this file's callers use.\n *\n * @internal Not part of the public API; not re-exported from the barrel.\n */\nexport const hslToRgb = hslToSrgb;\n\nfunction clamp01(n: number): number {\n return n < 0 ? 0 : n > 1 ? 1 : n;\n}\n\n// CSS Color Module Level 4 named colors. Stored as already-resolved tuples so\n// lookup is O(1) and avoids a second parse hop.\nconst NAMED_COLORS: Record<string, [number, number, number, number]> = (() => {\n const hex: Record<string, number> = {\n aliceblue: 0xf0f8ff, antiquewhite: 0xfaebd7, aqua: 0x00ffff, aquamarine: 0x7fffd4,\n azure: 0xf0ffff, beige: 0xf5f5dc, bisque: 0xffe4c4, black: 0x000000,\n blanchedalmond: 0xffebcd, blue: 0x0000ff, blueviolet: 0x8a2be2, brown: 0xa52a2a,\n burlywood: 0xdeb887, cadetblue: 0x5f9ea0, chartreuse: 0x7fff00, chocolate: 0xd2691e,\n coral: 0xff7f50, cornflowerblue: 0x6495ed, cornsilk: 0xfff8dc, crimson: 0xdc143c,\n cyan: 0x00ffff, darkblue: 0x00008b, darkcyan: 0x008b8b, darkgoldenrod: 0xb8860b,\n darkgray: 0xa9a9a9, darkgreen: 0x006400, darkgrey: 0xa9a9a9, darkkhaki: 0xbdb76b,\n darkmagenta: 0x8b008b, darkolivegreen: 0x556b2f, darkorange: 0xff8c00, darkorchid: 0x9932cc,\n darkred: 0x8b0000, darksalmon: 0xe9967a, darkseagreen: 0x8fbc8f, darkslateblue: 0x483d8b,\n darkslategray: 0x2f4f4f, darkslategrey: 0x2f4f4f, darkturquoise: 0x00ced1, darkviolet: 0x9400d3,\n deeppink: 0xff1493, deepskyblue: 0x00bfff, dimgray: 0x696969, dimgrey: 0x696969,\n dodgerblue: 0x1e90ff, firebrick: 0xb22222, floralwhite: 0xfffaf0, forestgreen: 0x228b22,\n fuchsia: 0xff00ff, gainsboro: 0xdcdcdc, ghostwhite: 0xf8f8ff, gold: 0xffd700,\n goldenrod: 0xdaa520, gray: 0x808080, green: 0x008000, greenyellow: 0xadff2f,\n grey: 0x808080, honeydew: 0xf0fff0, hotpink: 0xff69b4, indianred: 0xcd5c5c,\n indigo: 0x4b0082, ivory: 0xfffff0, khaki: 0xf0e68c, lavender: 0xe6e6fa,\n lavenderblush: 0xfff0f5, lawngreen: 0x7cfc00, lemonchiffon: 0xfffacd, lightblue: 0xadd8e6,\n lightcoral: 0xf08080, lightcyan: 0xe0ffff, lightgoldenrodyellow: 0xfafad2, lightgray: 0xd3d3d3,\n lightgreen: 0x90ee90, lightgrey: 0xd3d3d3, lightpink: 0xffb6c1, lightsalmon: 0xffa07a,\n lightseagreen: 0x20b2aa, lightskyblue: 0x87cefa, lightslategray: 0x778899, lightslategrey: 0x778899,\n lightsteelblue: 0xb0c4de, lightyellow: 0xffffe0, lime: 0x00ff00, limegreen: 0x32cd32,\n linen: 0xfaf0e6, magenta: 0xff00ff, maroon: 0x800000, mediumaquamarine: 0x66cdaa,\n mediumblue: 0x0000cd, mediumorchid: 0xba55d3, mediumpurple: 0x9370db, mediumseagreen: 0x3cb371,\n mediumslateblue: 0x7b68ee, mediumspringgreen: 0x00fa9a, mediumturquoise: 0x48d1cc, mediumvioletred: 0xc71585,\n midnightblue: 0x191970, mintcream: 0xf5fffa, mistyrose: 0xffe4e1, moccasin: 0xffe4b5,\n navajowhite: 0xffdead, navy: 0x000080, oldlace: 0xfdf5e6, olive: 0x808000,\n olivedrab: 0x6b8e23, orange: 0xffa500, orangered: 0xff4500, orchid: 0xda70d6,\n palegoldenrod: 0xeee8aa, palegreen: 0x98fb98, paleturquoise: 0xafeeee, palevioletred: 0xdb7093,\n papayawhip: 0xffefd5, peachpuff: 0xffdab9, peru: 0xcd853f, pink: 0xffc0cb,\n plum: 0xdda0dd, powderblue: 0xb0e0e6, purple: 0x800080, rebeccapurple: 0x663399,\n red: 0xff0000, rosybrown: 0xbc8f8f, royalblue: 0x4169e1, saddlebrown: 0x8b4513,\n salmon: 0xfa8072, sandybrown: 0xf4a460, seagreen: 0x2e8b57, seashell: 0xfff5ee,\n sienna: 0xa0522d, silver: 0xc0c0c0, skyblue: 0x87ceeb, slateblue: 0x6a5acd,\n slategray: 0x708090, slategrey: 0x708090, snow: 0xfffafa, springgreen: 0x00ff7f,\n steelblue: 0x4682b4, tan: 0xd2b48c, teal: 0x008080, thistle: 0xd8bfd8,\n tomato: 0xff6347, turquoise: 0x40e0d0, violet: 0xee82ee, wheat: 0xf5deb3,\n white: 0xffffff, whitesmoke: 0xf5f5f5, yellow: 0xffff00, yellowgreen: 0x9acd32,\n };\n const out: Record<string, [number, number, number, number]> = {\n transparent: [0, 0, 0, 0],\n };\n for (const name in hex) {\n const n = hex[name];\n out[name] = [((n >> 16) & 0xff) / 255, ((n >> 8) & 0xff) / 255, (n & 0xff) / 255, 1];\n }\n return out;\n})();\n"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { invert as e } from "@weasel-js/geom";
|
|
2
2
|
//#region src/renderer/math/mat3.ts
|
|
3
3
|
function t(e, t, n, r, i, a) {
|
|
4
|
-
return new
|
|
4
|
+
return new Float64Array([
|
|
5
5
|
e,
|
|
6
6
|
t,
|
|
7
7
|
0,
|
|
@@ -43,21 +43,24 @@ function c(t) {
|
|
|
43
43
|
let n = e(o(t));
|
|
44
44
|
return n && s(n);
|
|
45
45
|
}
|
|
46
|
-
function l(e
|
|
46
|
+
function l(e) {
|
|
47
|
+
return Float32Array.from(e);
|
|
48
|
+
}
|
|
49
|
+
function u(e, t, n) {
|
|
47
50
|
let r = e[0], i = e[1], a = e[3], o = e[4], s = e[6], c = e[7];
|
|
48
51
|
return [r * t + a * n + s, i * t + o * n + c];
|
|
49
52
|
}
|
|
50
|
-
function
|
|
53
|
+
function d(e, n) {
|
|
51
54
|
return t(2 / e, 0, 0, -2 / n, -1, 1);
|
|
52
55
|
}
|
|
53
|
-
function
|
|
56
|
+
function f(e) {
|
|
54
57
|
return Math.sqrt(Math.abs(e[0] * e[4] - e[1] * e[3]));
|
|
55
58
|
}
|
|
56
|
-
function
|
|
59
|
+
function p(e) {
|
|
57
60
|
let t = e[0] * e[0] + e[1] * e[1] + e[3] * e[3] + e[4] * e[4], n = e[0] * e[4] - e[1] * e[3];
|
|
58
61
|
return Math.sqrt(Math.max(0, (t - Math.sqrt(Math.max(0, t * t - 4 * n * n))) / 2));
|
|
59
62
|
}
|
|
60
|
-
var
|
|
63
|
+
var m = {
|
|
61
64
|
identity: n,
|
|
62
65
|
toAffine: o,
|
|
63
66
|
fromAffine: s,
|
|
@@ -65,12 +68,13 @@ var p = {
|
|
|
65
68
|
translated: i,
|
|
66
69
|
scaled: a,
|
|
67
70
|
invert: c,
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
71
|
+
toUniform: l,
|
|
72
|
+
apply: u,
|
|
73
|
+
screenToClip: d,
|
|
74
|
+
meanScaleOf: f,
|
|
75
|
+
minScaleOf: p
|
|
72
76
|
};
|
|
73
77
|
//#endregion
|
|
74
|
-
export {
|
|
78
|
+
export { m as mat3 };
|
|
75
79
|
|
|
76
80
|
//# sourceMappingURL=mat3.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mat3.js","names":["multiply","invert","invertAffine","create","a","b","c","d","tx","ty","identity","multiply$1","out","ma","m","mb","mc","md","mtx","mty","translated","scaled","sx","sy","toAffine","fromAffine","invert$1","inv","invert","apply","x","y","screenToClip","width","height","meanScaleOf","minScaleOf","sum","det","mat3"],"sources":["../../../src/renderer/math/mat3.ts"],"sourcesContent":["/**\n * 2D affine matrix utilities. Column-major 9
|
|
1
|
+
{"version":3,"file":"mat3.js","names":["multiply","invert","invertAffine","create","a","b","c","d","tx","ty","identity","multiply$1","out","ma","m","mb","mc","md","mtx","mty","translated","scaled","sx","sy","toAffine","fromAffine","invert$1","inv","invert","toUniform","apply","x","y","screenToClip","width","height","meanScaleOf","minScaleOf","sum","det","mat3"],"sources":["../../../src/renderer/math/mat3.ts"],"sourcesContent":["/**\n * 2D affine matrix utilities. Column-major 9 elements, matching\n * `WebGL2RenderingContext.uniformMatrix3fv` element order so an upload needs\n * no transpose flag.\n *\n * Layout (column-major):\n * [m00, m10, 0,\n * m01, m11, 0,\n * tx, ty, 1]\n *\n * `apply(m, x, y)` returns `[m * (x, y, 1)] = [m00*x + m01*y + tx,\n * m10*x + m11*y + ty]`.\n */\n\nimport { invert as invertAffine, type Mat3 as Affine } from '@weasel-js/geom';\n\n/**\n * A 2D affine transform as a column-major 9-element array, laid out as above.\n *\n * Every matrix the kit builds is a `Float64Array`: a view translation far\n * from the origin at high zoom needs more than a float32's 24 bits to hold a\n * fraction of a pixel. A `Float32Array` is accepted wherever one is read.\n * `mat3.toUniform` makes the float32 copy a GL uniform upload wants.\n */\nexport type GlMat3 = Float32Array | Float64Array;\n\nfunction create(a: number, b: number, c: number, d: number, tx: number, ty: number): GlMat3 {\n // Column-major:\n // col 0: (a, b, 0)\n // col 1: (c, d, 0)\n // col 2: (tx, ty, 1)\n return new Float64Array([a, b, 0, c, d, 0, tx, ty, 1]);\n}\n\nfunction identity(): GlMat3 {\n return create(1, 0, 0, 1, 0, 0);\n}\n\nfunction multiply(out: GlMat3, m: GlMat3): GlMat3 {\n // out := out · m (right-multiply by m).\n const a = out[0], b = out[1];\n const c = out[3], d = out[4];\n const tx = out[6], ty = out[7];\n const ma = m[0], mb = m[1];\n const mc = m[3], md = m[4];\n const mtx = m[6], mty = m[7];\n\n return create(\n a * ma + c * mb, // new a\n b * ma + d * mb, // new b\n a * mc + c * md, // new c\n b * mc + d * md, // new d\n a * mtx + c * mty + tx, // new tx\n b * mtx + d * mty + ty, // new ty\n );\n}\n\n/** `m · T(tx, ty)`: composes onto `m`, where `@weasel-js/geom`'s `translate`\n * constructs a fresh matrix. */\nfunction translated(m: GlMat3, tx: number, ty: number): GlMat3 {\n const t = create(1, 0, 0, 1, tx, ty);\n return multiply(m, t);\n}\n\n/** `m · S(sx, sy)`: composes onto `m`, where geom's `scale` constructs one. */\nfunction scaled(m: GlMat3, sx: number, sy: number): GlMat3 {\n const s = create(sx, 0, 0, sy, 0, 0);\n return multiply(m, s);\n}\n\n/** This layout read as the kernel's 6-element affine. The two carry the same\n * logical order, so the conversion is a repack and nothing else — it exists\n * so the repack has a name instead of appearing inline at each crossing. */\nfunction toAffine(m: GlMat3): Affine {\n return [m[0], m[1], m[3], m[4], m[6], m[7]];\n}\n\n/** The kernel's affine in this layout. The inverse of {@link toAffine}, and\n * what an `SvgGroupNode.transform` (also a kernel affine) becomes on its way\n * to a `GroupDrawCommand`. */\nfunction fromAffine(a: Affine): GlMat3 {\n return create(a[0], a[1], a[2], a[3], a[4], a[5]);\n}\n\n/** Inverse of an affine matrix, or `null` when `@weasel-js/geom`'s `invert`\n * finds it singular — the same rule, read through this layout. */\nfunction invert(m: GlMat3): GlMat3 | null {\n const inv = invertAffine(toAffine(m));\n return inv && fromAffine(inv);\n}\n\n/** A float32 copy of `m`, for `uniformMatrix3fv` or a shader uniform value. */\nfunction toUniform(m: GlMat3): Float32Array {\n return Float32Array.from(m);\n}\n\nfunction apply(m: GlMat3, x: number, y: number): [number, number] {\n const a = m[0], b = m[1];\n const c = m[3], d = m[4];\n const tx = m[6], ty = m[7];\n return [a * x + c * y + tx, b * x + d * y + ty];\n}\n\n/**\n * Map screen pixel coords (0..width on X, 0..height on Y, top-left origin)\n * into clip space (-1..1 on X, 1..-1 on Y — note Y flip so screen-down\n * matches clip-down).\n */\nfunction screenToClip(width: number, height: number): GlMat3 {\n return create(\n 2 / width, // a\n 0, // b\n 0, // c\n -2 / height, // d\n -1, // tx\n 1, // ty\n );\n}\n\n/**\n * Uniform-equivalent scale factor: the square root of the absolute\n * determinant of the linear part, i.e. the geometric mean of the two axis\n * scales. Rotation-invariant. Under non-uniform scale it is between the two\n * axes and exact on neither — the same compromise `meanScale` documents.\n */\nfunction meanScaleOf(m: GlMat3): number {\n return Math.sqrt(Math.abs(m[0] * m[4] - m[1] * m[3]));\n}\n\n/** The least any direction is scaled by the linear part — its smaller singular\n * value. What a screen length is worth in world units, at most. */\nfunction minScaleOf(m: GlMat3): number {\n const sum = m[0] * m[0] + m[1] * m[1] + m[3] * m[3] + m[4] * m[4];\n const det = m[0] * m[4] - m[1] * m[3];\n return Math.sqrt(Math.max(0, (sum - Math.sqrt(Math.max(0, sum * sum - 4 * det * det))) / 2));\n}\n\n/** The renderer's 3x3 matrix operations, as one namespace. These work on the\n * 9-element form the GL uniform upload wants — distinct from\n * `@weasel-js/geom`'s 6-element affine `GlMat3`, though the logical element\n * order is the same. */\nexport const mat3 = {\n identity,\n toAffine,\n fromAffine,\n multiply,\n translated,\n scaled,\n invert,\n toUniform,\n apply,\n screenToClip,\n meanScaleOf,\n minScaleOf,\n};\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"viewToMat3.js","names":["viewToMat3","sx","view","sy","tx","ty"],"sources":["../../../src/renderer/math/viewToMat3.ts"],"sourcesContent":["/**\n * View → GlMat3 helper for layer `draw` implementations on world-space layers.\n *\n * `View` is `@weasel-js/routing`'s, the one every viewport action is typed\n * in. A type-only import emits no runtime edge, so there is no reason for the\n * renderer to hold a second structurally-identical declaration and put it in\n * the emitted `.d.ts` anonymously.\n */\n\nimport type { View } from '@weasel-js/routing';\nimport type { GlMat3 } from './mat3';\n\nexport type { View };\n\n/**\n * Build the world→screen transform matrix for a `View`.\n * Use as the `transform` field of a `kind: 'group'` DrawCommand to wrap\n * world-space content emitted from a layer `draw` implementation.\n *\n * Mapping: `screen = (world − {view.x, view.y}) × {view.scale.x, view.scale.y}`.\n *\n * Column-major layout (matches `mat3.identity()`):\n * `[scale.x, 0, 0, 0, scale.y, 0, -view.x*scale.x, -view.y*scale.y, 1]`.\n */\nexport function viewToMat3(view: View): GlMat3 {\n const sx = view.scale.x;\n const sy = view.scale.y;\n // Add 0 to coerce -0 → 0, matching `mat3.identity()` for the {0,0,1} case.\n const tx = -view.x * sx + 0;\n const ty = -view.y * sy + 0;\n return new
|
|
1
|
+
{"version":3,"file":"viewToMat3.js","names":["viewToMat3","sx","view","sy","tx","ty"],"sources":["../../../src/renderer/math/viewToMat3.ts"],"sourcesContent":["/**\n * View → GlMat3 helper for layer `draw` implementations on world-space layers.\n *\n * `View` is `@weasel-js/routing`'s, the one every viewport action is typed\n * in. A type-only import emits no runtime edge, so there is no reason for the\n * renderer to hold a second structurally-identical declaration and put it in\n * the emitted `.d.ts` anonymously.\n */\n\nimport type { View } from '@weasel-js/routing';\nimport type { GlMat3 } from './mat3';\n\nexport type { View };\n\n/**\n * Build the world→screen transform matrix for a `View`.\n * Use as the `transform` field of a `kind: 'group'` DrawCommand to wrap\n * world-space content emitted from a layer `draw` implementation.\n *\n * Mapping: `screen = (world − {view.x, view.y}) × {view.scale.x, view.scale.y}`.\n *\n * Column-major layout (matches `mat3.identity()`):\n * `[scale.x, 0, 0, 0, scale.y, 0, -view.x*scale.x, -view.y*scale.y, 1]`.\n */\nexport function viewToMat3(view: View): GlMat3 {\n const sx = view.scale.x;\n const sy = view.scale.y;\n // Add 0 to coerce -0 → 0, matching `mat3.identity()` for the {0,0,1} case.\n const tx = -view.x * sx + 0;\n const ty = -view.y * sy + 0;\n return new Float64Array([\n sx, 0, 0,\n 0, sy, 0,\n tx, ty, 1,\n ]);\n}\n"],"mappings":";AAwBA,SAAgBA,EAAW,GAAoB;CAC7C,IAAMC,IAAKC,EAAK,MAAM,GAChBC,IAAKD,EAAK,MAAM,GAEhBE,IAAK,CAACF,EAAK,IAAID,IAAK,GACpBI,IAAK,CAACH,EAAK,IAAIC,IAAK;CAC1B,OAAO,IAAI,aAAa;EACtBF;EAAI;EAAG;EACP;EAAGE;EAAI;EACPC;EAAIC;EAAI;CACV,CAAC;AACH"}
|
|
@@ -5,27 +5,27 @@ var e = class extends Error {
|
|
|
5
5
|
constructor(e, t) {
|
|
6
6
|
super(`shader ${e} failure: ${t}`), this.stage = e, this.log = t, this.name = "ShaderCompileError";
|
|
7
7
|
}
|
|
8
|
-
}, t = class {
|
|
8
|
+
}, t = 0, n = class {
|
|
9
9
|
gl;
|
|
10
10
|
handle;
|
|
11
11
|
uniforms = /* @__PURE__ */ new Map();
|
|
12
12
|
arrays = /* @__PURE__ */ new Map();
|
|
13
13
|
attributes = /* @__PURE__ */ new Map();
|
|
14
|
-
constructor(
|
|
15
|
-
this.gl =
|
|
16
|
-
let
|
|
14
|
+
constructor(n, r, i) {
|
|
15
|
+
this.gl = n;
|
|
16
|
+
let a = this.compile(n.VERTEX_SHADER, r, "vertex"), o;
|
|
17
17
|
try {
|
|
18
|
-
|
|
18
|
+
o = this.compile(n.FRAGMENT_SHADER, i, "fragment");
|
|
19
19
|
} catch (e) {
|
|
20
|
-
throw
|
|
20
|
+
throw n.deleteShader(a), e;
|
|
21
21
|
}
|
|
22
|
-
let
|
|
23
|
-
if (!
|
|
24
|
-
if (
|
|
25
|
-
let
|
|
26
|
-
throw
|
|
22
|
+
let s = n.createProgram();
|
|
23
|
+
if (!s) throw n.deleteShader(a), n.deleteShader(o), Error("createProgram returned null");
|
|
24
|
+
if (n.attachShader(s, a), n.attachShader(s, o), n.bindAttribLocation(s, t, "a_position"), n.linkProgram(s), n.deleteShader(a), n.deleteShader(o), !n.getProgramParameter(s, n.LINK_STATUS)) {
|
|
25
|
+
let t = n.getProgramInfoLog(s) ?? "";
|
|
26
|
+
throw n.deleteProgram(s), new e("link", t);
|
|
27
27
|
}
|
|
28
|
-
this.handle =
|
|
28
|
+
this.handle = s;
|
|
29
29
|
}
|
|
30
30
|
compile(t, n, r) {
|
|
31
31
|
let i = this.gl, a = i.createShader(t);
|
|
@@ -69,6 +69,6 @@ var e = class extends Error {
|
|
|
69
69
|
}
|
|
70
70
|
};
|
|
71
71
|
//#endregion
|
|
72
|
-
export { e as ShaderCompileError,
|
|
72
|
+
export { t as POSITION_ATTRIBUTE_LOCATION, e as ShaderCompileError, n as ShaderProgram };
|
|
73
73
|
|
|
74
74
|
//# sourceMappingURL=ShaderProgram.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ShaderProgram.js","names":["ShaderCompileError","stage","log","ShaderProgram","gl","vs","vertSrc","fs","fragSrc","program","shader","type","source","name","names","loc","decls","base","location"],"sources":["../../../src/renderer/shaders/ShaderProgram.ts"],"sourcesContent":["/**\n * Minimal compile/link/lookup wrapper for a GL program. Throws\n * `ShaderCompileError` on compile or link failure with the GL info log\n * embedded in the error message — never returns a half-initialized program.\n *\n * Designed so test code can stub `getShaderParameter` / `getProgramParameter`\n * via the recorder Proxy without further special-casing.\n */\n\nexport type Stage = 'vertex' | 'fragment' | 'link';\n\n/** Thrown when a shader fails to compile or link, carrying which stage failed\n * and the driver's log. */\nexport class ShaderCompileError extends Error {\n constructor(public readonly stage: Stage, public readonly log: string) {\n super(`shader ${stage} failure: ${log}`);\n this.name = 'ShaderCompileError';\n }\n}\n\n/** An array uniform a program can be written as a whole: its element type as\n * declared, its declared length, and the location of slot 0. */\nexport interface UniformArray {\n readonly type: string;\n readonly size: number;\n readonly location: WebGLUniformLocation;\n}\n\n/** A linked GL program with its uniform and attribute locations cached by name. */\nexport class ShaderProgram {\n readonly handle: WebGLProgram;\n private readonly uniforms = new Map<string, WebGLUniformLocation>();\n private readonly arrays = new Map<string, UniformArray>();\n private readonly attributes = new Map<string, number>();\n\n constructor(\n private readonly gl: WebGL2RenderingContext,\n vertSrc: string,\n fragSrc: string,\n ) {\n const vs = this.compile(gl.VERTEX_SHADER, vertSrc, 'vertex');\n let fs: WebGLShader;\n try {\n fs = this.compile(gl.FRAGMENT_SHADER, fragSrc, 'fragment');\n } catch (e) {\n gl.deleteShader(vs);\n throw e;\n }\n const program = gl.createProgram();\n if (!program) {\n gl.deleteShader(vs);\n gl.deleteShader(fs);\n throw new Error('createProgram returned null');\n }\n gl.attachShader(program, vs);\n gl.attachShader(program, fs);\n gl.linkProgram(program);\n // Flagged for deletion, attached shaders live exactly as long as the\n // program, so `deleteProgram` frees them too.\n gl.deleteShader(vs);\n gl.deleteShader(fs);\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n const log = gl.getProgramInfoLog(program) ?? '';\n gl.deleteProgram(program);\n throw new ShaderCompileError('link', log);\n }\n this.handle = program;\n }\n\n private compile(type: number, source: string, stage: Stage): WebGLShader {\n const gl = this.gl;\n const shader = gl.createShader(type);\n if (!shader) throw new Error('createShader returned null');\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n const log = gl.getShaderInfoLog(shader) ?? '';\n gl.deleteShader(shader);\n throw new ShaderCompileError(stage, log);\n }\n return shader;\n }\n\n lookupUniforms(names: readonly string[]): void {\n for (const name of names) {\n const loc = this.gl.getUniformLocation(this.handle, name);\n if (loc !== null) this.uniforms.set(name, loc);\n }\n }\n\n /** Record each array's slot-0 location under its bare name. An array the\n * driver optimized away has no location and is left out. */\n lookupUniformArrays(decls: ReadonlyMap<string, { type: string; size: number }>): void {\n for (const [name, { type, size }] of decls) {\n const base = `${name}[0]`;\n const location = this.uniforms.get(base) ?? this.gl.getUniformLocation(this.handle, base);\n if (location !== null) this.arrays.set(name, { type, size, location });\n }\n }\n\n lookupAttributes(names: readonly string[]): void {\n for (const name of names) {\n const loc = this.gl.getAttribLocation(this.handle, name);\n if (loc >= 0) this.attributes.set(name, loc);\n }\n }\n\n uniform(name: string): WebGLUniformLocation | undefined {\n return this.uniforms.get(name);\n }\n\n uniformArray(name: string): UniformArray | undefined {\n return this.arrays.get(name);\n }\n\n attribute(name: string): number | undefined {\n return this.attributes.get(name);\n }\n}\n"],"mappings":";AAaA,IAAaA,IAAb,cAAwC,MAAM;CAChB;CAA8B;CAA1D,YAAY,GAA8B,GAA6B;EAErE,AADA,MAAM,UAAUC,EAAM,YAAYC,GAAK,GADb,KAAA,QAAAD,GAA8B,KAAA,MAAAC,GAExD,KAAK,OAAO;CACd;AACF,
|
|
1
|
+
{"version":3,"file":"ShaderProgram.js","names":["ShaderCompileError","stage","log","POSITION_ATTRIBUTE_LOCATION","ShaderProgram","gl","vs","vertSrc","fs","fragSrc","program","shader","type","source","name","names","loc","decls","base","location"],"sources":["../../../src/renderer/shaders/ShaderProgram.ts"],"sourcesContent":["/**\n * Minimal compile/link/lookup wrapper for a GL program. Throws\n * `ShaderCompileError` on compile or link failure with the GL info log\n * embedded in the error message — never returns a half-initialized program.\n *\n * Designed so test code can stub `getShaderParameter` / `getProgramParameter`\n * via the recorder Proxy without further special-casing.\n */\n\nexport type Stage = 'vertex' | 'fragment' | 'link';\n\n/** Thrown when a shader fails to compile or link, carrying which stage failed\n * and the driver's log. */\nexport class ShaderCompileError extends Error {\n constructor(public readonly stage: Stage, public readonly log: string) {\n super(`shader ${stage} failure: ${log}`);\n this.name = 'ShaderCompileError';\n }\n}\n\n/** An array uniform a program can be written as a whole: its element type as\n * declared, its declared length, and the location of slot 0. */\nexport interface UniformArray {\n readonly type: string;\n readonly size: number;\n readonly location: WebGLUniformLocation;\n}\n\n/** Where every program links `a_position`. A mesh VAO is built once and drawn\n * with whichever fill program its paint picks, so the location cannot be\n * left to each program's linker. */\nexport const POSITION_ATTRIBUTE_LOCATION = 0;\n\n/** A linked GL program with its uniform and attribute locations cached by name. */\nexport class ShaderProgram {\n readonly handle: WebGLProgram;\n private readonly uniforms = new Map<string, WebGLUniformLocation>();\n private readonly arrays = new Map<string, UniformArray>();\n private readonly attributes = new Map<string, number>();\n\n constructor(\n private readonly gl: WebGL2RenderingContext,\n vertSrc: string,\n fragSrc: string,\n ) {\n const vs = this.compile(gl.VERTEX_SHADER, vertSrc, 'vertex');\n let fs: WebGLShader;\n try {\n fs = this.compile(gl.FRAGMENT_SHADER, fragSrc, 'fragment');\n } catch (e) {\n gl.deleteShader(vs);\n throw e;\n }\n const program = gl.createProgram();\n if (!program) {\n gl.deleteShader(vs);\n gl.deleteShader(fs);\n throw new Error('createProgram returned null');\n }\n gl.attachShader(program, vs);\n gl.attachShader(program, fs);\n gl.bindAttribLocation(program, POSITION_ATTRIBUTE_LOCATION, 'a_position');\n gl.linkProgram(program);\n // Flagged for deletion, attached shaders live exactly as long as the\n // program, so `deleteProgram` frees them too.\n gl.deleteShader(vs);\n gl.deleteShader(fs);\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n const log = gl.getProgramInfoLog(program) ?? '';\n gl.deleteProgram(program);\n throw new ShaderCompileError('link', log);\n }\n this.handle = program;\n }\n\n private compile(type: number, source: string, stage: Stage): WebGLShader {\n const gl = this.gl;\n const shader = gl.createShader(type);\n if (!shader) throw new Error('createShader returned null');\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n const log = gl.getShaderInfoLog(shader) ?? '';\n gl.deleteShader(shader);\n throw new ShaderCompileError(stage, log);\n }\n return shader;\n }\n\n lookupUniforms(names: readonly string[]): void {\n for (const name of names) {\n const loc = this.gl.getUniformLocation(this.handle, name);\n if (loc !== null) this.uniforms.set(name, loc);\n }\n }\n\n /** Record each array's slot-0 location under its bare name. An array the\n * driver optimized away has no location and is left out. */\n lookupUniformArrays(decls: ReadonlyMap<string, { type: string; size: number }>): void {\n for (const [name, { type, size }] of decls) {\n const base = `${name}[0]`;\n const location = this.uniforms.get(base) ?? this.gl.getUniformLocation(this.handle, base);\n if (location !== null) this.arrays.set(name, { type, size, location });\n }\n }\n\n lookupAttributes(names: readonly string[]): void {\n for (const name of names) {\n const loc = this.gl.getAttribLocation(this.handle, name);\n if (loc >= 0) this.attributes.set(name, loc);\n }\n }\n\n uniform(name: string): WebGLUniformLocation | undefined {\n return this.uniforms.get(name);\n }\n\n uniformArray(name: string): UniformArray | undefined {\n return this.arrays.get(name);\n }\n\n attribute(name: string): number | undefined {\n return this.attributes.get(name);\n }\n}\n"],"mappings":";AAaA,IAAaA,IAAb,cAAwC,MAAM;CAChB;CAA8B;CAA1D,YAAY,GAA8B,GAA6B;EAErE,AADA,MAAM,UAAUC,EAAM,YAAYC,GAAK,GADb,KAAA,QAAAD,GAA8B,KAAA,MAAAC,GAExD,KAAK,OAAO;CACd;AACF,GAaaC,IAA8B,GAG9BC,IAAb,MAA2B;CAON;CANnB;CACA,2BAA4B,IAAI,IAAkC;CAClE,yBAA0B,IAAI,IAA0B;CACxD,6BAA8B,IAAI,IAAoB;CAEtD,YACE,GACA,GACA,GACA;EAHiB,KAAA,KAAAC;EAIjB,IAAMC,IAAK,KAAK,QAAQD,EAAG,eAAeE,GAAS,QAAQ,GACvDC;EACJ,IAAI;GACF,IAAK,KAAK,QAAQH,EAAG,iBAAiBI,GAAS,UAAU;EAC3D,SAAS,GAAG;GAEV,MADAJ,EAAG,aAAaC,CAAE,GACZ;EACR;EACA,IAAMI,IAAUL,EAAG,cAAc;EACjC,IAAI,CAACK,GAGH,MAFAL,EAAG,aAAaC,CAAE,GAClBD,EAAG,aAAaG,CAAE,GACR,MAAM,6BAA6B;EAU/C,IARAH,EAAG,aAAaK,GAASJ,CAAE,GAC3BD,EAAG,aAAaK,GAASF,CAAE,GAC3BH,EAAG,mBAAmBK,GAASP,GAA6B,YAAY,GACxEE,EAAG,YAAYK,CAAO,GAGtBL,EAAG,aAAaC,CAAE,GAClBD,EAAG,aAAaG,CAAE,GACd,CAACH,EAAG,oBAAoBK,GAASL,EAAG,WAAW,GAAG;GACpD,IAAMH,IAAMG,EAAG,kBAAkBK,CAAO,KAAK;GAE7C,MADAL,EAAG,cAAcK,CAAO,GAClB,IAAIV,EAAmB,QAAQE,CAAG;EAC1C;EACA,KAAK,SAASQ;CAChB;CAEA,QAAgB,GAAc,GAAgB,GAA2B;EACvE,IAAML,IAAK,KAAK,IACVM,IAASN,EAAG,aAAaO,CAAI;EACnC,IAAI,CAACD,GAAQ,MAAU,MAAM,4BAA4B;EAGzD,IAFAN,EAAG,aAAaM,GAAQE,CAAM,GAC9BR,EAAG,cAAcM,CAAM,GACnB,CAACN,EAAG,mBAAmBM,GAAQN,EAAG,cAAc,GAAG;GACrD,IAAMH,IAAMG,EAAG,iBAAiBM,CAAM,KAAK;GAE3C,MADAN,EAAG,aAAaM,CAAM,GAChB,IAAIX,EAAmBC,GAAOC,CAAG;EACzC;EACA,OAAOS;CACT;CAEA,eAAe,GAAgC;EAC7C,KAAK,IAAMG,KAAQC,GAAO;GACxB,IAAMC,IAAM,KAAK,GAAG,mBAAmB,KAAK,QAAQF,CAAI;GACxD,AAAIE,MAAQ,QAAM,KAAK,SAAS,IAAIF,GAAME,CAAG;EAC/C;CACF;CAIA,oBAAoB,GAAkE;EACpF,KAAK,IAAM,CAACF,GAAM,EAAE,SAAM,cAAWG,GAAO;GAC1C,IAAMC,IAAO,GAAGJ,EAAK,MACfK,IAAW,KAAK,SAAS,IAAID,CAAI,KAAK,KAAK,GAAG,mBAAmB,KAAK,QAAQA,CAAI;GACxF,AAAIC,MAAa,QAAM,KAAK,OAAO,IAAIL,GAAM;IAAE;IAAM;IAAM;GAAS,CAAC;EACvE;CACF;CAEA,iBAAiB,GAAgC;EAC/C,KAAK,IAAMA,KAAQC,GAAO;GACxB,IAAMC,IAAM,KAAK,GAAG,kBAAkB,KAAK,QAAQF,CAAI;GACvD,AAAIE,KAAO,KAAG,KAAK,WAAW,IAAIF,GAAME,CAAG;EAC7C;CACF;CAEA,QAAQ,GAAgD;EACtD,OAAO,KAAK,SAAS,IAAIF,CAAI;CAC/B;CAEA,aAAa,GAAwC;EACnD,OAAO,KAAK,OAAO,IAAIA,CAAI;CAC7B;CAEA,UAAU,GAAkC;EAC1C,OAAO,KAAK,WAAW,IAAIA,CAAI;CACjC;AACF"}
|
|
@@ -44,18 +44,18 @@ var u = "\nuniform sampler2D u_sampler;\nvec4 shadePaint(vec2 uv) {\n return te
|
|
|
44
44
|
"u_atlas",
|
|
45
45
|
"u_synthBold",
|
|
46
46
|
"u_fieldScale"
|
|
47
|
-
], h = [...i, ...m],
|
|
47
|
+
], h = (e) => e !== "u_origin", g = [...i.filter(h), ...m], _ = [...n.filter(h), ...m], v = [
|
|
48
48
|
"u_proj",
|
|
49
49
|
"u_model",
|
|
50
50
|
"u_worldInv",
|
|
51
51
|
"u_sampler",
|
|
52
52
|
...m
|
|
53
|
-
],
|
|
53
|
+
], y = [
|
|
54
54
|
"a_position",
|
|
55
55
|
"a_uv",
|
|
56
56
|
"a_texSlot"
|
|
57
57
|
];
|
|
58
58
|
//#endregion
|
|
59
|
-
export { f as GLYPH_GRAD_FRAG_SRC,
|
|
59
|
+
export { f as GLYPH_GRAD_FRAG_SRC, _ as GLYPH_GRAD_UNIFORMS, y as GLYPH_PAINT_ATTRIBUTES, c as GLYPH_PAINT_VERT_SRC, d as GLYPH_PATTERN_FRAG_SRC, g as GLYPH_PATTERN_UNIFORMS, p as GLYPH_TEXTURE_FRAG_SRC, v as GLYPH_TEXTURE_UNIFORMS };
|
|
60
60
|
|
|
61
61
|
//# sourceMappingURL=glyphPaint.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"glyphPaint.js","names":["L","BATCH_ATTRIBUTE_LOCATIONS","GLYPH_PAINT_VERT_SRC","BATCH_TEXTURE_SLOTS","fragSrc","paintGlsl","GLYPH_COVERAGE_GLSL","TEXTURE_PAINT_GLSL","GLYPH_PATTERN_FRAG_SRC","PATTERN_PAINT_GLSL","GLYPH_GRAD_FRAG_SRC","GRAD_PAINT_GLSL","GLYPH_TEXTURE_FRAG_SRC","GLYPH_UNIFORMS","GLYPH_PATTERN_UNIFORMS","PATTERN_FILL_UNIFORMS","GLYPH_GRAD_UNIFORMS","GRAD_FILL_UNIFORMS","GLYPH_TEXTURE_UNIFORMS","GLYPH_PAINT_ATTRIBUTES"],"sources":["../../../src/renderer/shaders/glyphPaint.ts"],"sourcesContent":["/**\n * GLSL ES 3.0 sources for atlas glyphs filled by a texture paint — a pattern, a\n * gradient or a registered kind — rather than one color.\n *\n * **The glyph is a mask over the paint.** The fragment takes its coverage from\n * the distance field exactly as the batch program does, and its color from the\n * same `shadePaint` the path program for that paint runs, at the same\n * paint-space point: `u_worldInv` applied to the screen position. An outline\n * glyph is a path, so it goes through that path program — which is what makes\n * a paint read the same on either side of the outline-tier threshold.\n *\n * **The vertices are the batch's.** A glyph run stages into `DrawBatch` as\n * usual and this program draws it in place of the batch program, so the\n * attribute locations are pinned to the batch shader's and one VAO serves\n * both. Positions arrive already in screen space, so `u_model` is identity.\n *\n * Coverage is taken before `shadePaint` runs, and outside any branch: `fwidth`\n * in non-uniform control flow is undefined. The gradient's branches are on a\n * uniform, so they could not make it so, but the order keeps it from mattering.\n *\n * Output: PREMULTIPLIED alpha, the paint's own scaled by coverage.\n */\n\nimport { GLYPH_COVERAGE_GLSL } from '@weasel-js/font';\nimport { BATCH_ATTRIBUTE_LOCATIONS, BATCH_TEXTURE_SLOTS } from './batchFill';\nimport { GRAD_FILL_UNIFORMS, GRAD_PAINT_GLSL } from './gradFill';\nimport { PATTERN_FILL_UNIFORMS, PATTERN_PAINT_GLSL } from './patternFill';\n\nconst L = BATCH_ATTRIBUTE_LOCATIONS;\n\nexport const GLYPH_PAINT_VERT_SRC = /* glsl */ `#version 300 es\nlayout(location = ${L.a_position}) in vec2 a_position;\nlayout(location = ${L.a_uv}) in vec2 a_uv;\nlayout(location = ${L.a_texSlot}) in float a_texSlot;\nuniform mat3 u_proj;\nuniform mat3 u_model;\nuniform mat3 u_worldInv;\nout vec2 v_world;\nout vec2 v_uv;\nflat out float v_glyphMode;\nvoid main() {\n vec3 screen = u_model * vec3(a_position, 1.0);\n vec3 clip = u_proj * vec3(screen.xy, 1.0);\n gl_Position = vec4(clip.xy, 0.0, 1.0);\n v_world = (u_worldInv * vec3(screen.xy, 1.0)).xy;\n v_uv = a_uv;\n v_glyphMode = float(int(a_texSlot + 0.5) / ${BATCH_TEXTURE_SLOTS});\n}\n`;\n\nfunction fragSrc(paintGlsl: string): string {\n return /* glsl */ `#version 300 es\nprecision highp float;\nin vec2 v_world;\nin vec2 v_uv;\nflat in float v_glyphMode;\nuniform sampler2D u_atlas;\nuniform float u_synthBold;\nuniform vec2 u_fieldScale;\n${paintGlsl}\n${GLYPH_COVERAGE_GLSL}\nout vec4 outColor;\nvoid main() {\n float coverage = glyphCoverage(texture(u_atlas, v_uv), v_glyphMode, u_synthBold, v_uv, u_fieldScale);\n outColor = shadePaint(v_world) * coverage;\n}\n`;\n}\n\n/**\n * A registered paint kind binds a whole program of its own, which nothing can\n * wrap in a mask, so it renders into an offscreen buffer first and the glyphs\n * sample that. `u_worldInv` takes the screen position straight to the\n * buffer's texture coordinate, and the texel is already premultiplied and\n * faded — the kind's own program did both.\n */\nconst TEXTURE_PAINT_GLSL = /* glsl */ `\nuniform sampler2D u_sampler;\nvec4 shadePaint(vec2 uv) {\n return texture(u_sampler, uv);\n}\n`;\n\nexport const GLYPH_PATTERN_FRAG_SRC = fragSrc(PATTERN_PAINT_GLSL);\nexport const GLYPH_GRAD_FRAG_SRC = fragSrc(GRAD_PAINT_GLSL);\nexport const GLYPH_TEXTURE_FRAG_SRC = fragSrc(TEXTURE_PAINT_GLSL);\n\nconst GLYPH_UNIFORMS = ['u_atlas', 'u_synthBold', 'u_fieldScale'] as const;\nexport const GLYPH_PATTERN_UNIFORMS = [...PATTERN_FILL_UNIFORMS, ...GLYPH_UNIFORMS]
|
|
1
|
+
{"version":3,"file":"glyphPaint.js","names":["L","BATCH_ATTRIBUTE_LOCATIONS","GLYPH_PAINT_VERT_SRC","BATCH_TEXTURE_SLOTS","fragSrc","paintGlsl","GLYPH_COVERAGE_GLSL","TEXTURE_PAINT_GLSL","GLYPH_PATTERN_FRAG_SRC","PATTERN_PAINT_GLSL","GLYPH_GRAD_FRAG_SRC","GRAD_PAINT_GLSL","GLYPH_TEXTURE_FRAG_SRC","GLYPH_UNIFORMS","notOrigin","name","GLYPH_PATTERN_UNIFORMS","PATTERN_FILL_UNIFORMS","GLYPH_GRAD_UNIFORMS","GRAD_FILL_UNIFORMS","GLYPH_TEXTURE_UNIFORMS","GLYPH_PAINT_ATTRIBUTES"],"sources":["../../../src/renderer/shaders/glyphPaint.ts"],"sourcesContent":["/**\n * GLSL ES 3.0 sources for atlas glyphs filled by a texture paint — a pattern, a\n * gradient or a registered kind — rather than one color.\n *\n * **The glyph is a mask over the paint.** The fragment takes its coverage from\n * the distance field exactly as the batch program does, and its color from the\n * same `shadePaint` the path program for that paint runs, at the same\n * paint-space point: `u_worldInv` applied to the screen position. An outline\n * glyph is a path, so it goes through that path program — which is what makes\n * a paint read the same on either side of the outline-tier threshold.\n *\n * **The vertices are the batch's.** A glyph run stages into `DrawBatch` as\n * usual and this program draws it in place of the batch program, so the\n * attribute locations are pinned to the batch shader's and one VAO serves\n * both. Positions arrive already in screen space, so `u_model` is identity.\n *\n * Coverage is taken before `shadePaint` runs, and outside any branch: `fwidth`\n * in non-uniform control flow is undefined. The gradient's branches are on a\n * uniform, so they could not make it so, but the order keeps it from mattering.\n *\n * Output: PREMULTIPLIED alpha, the paint's own scaled by coverage.\n */\n\nimport { GLYPH_COVERAGE_GLSL } from '@weasel-js/font';\nimport { BATCH_ATTRIBUTE_LOCATIONS, BATCH_TEXTURE_SLOTS } from './batchFill';\nimport { GRAD_FILL_UNIFORMS, GRAD_PAINT_GLSL } from './gradFill';\nimport { PATTERN_FILL_UNIFORMS, PATTERN_PAINT_GLSL } from './patternFill';\n\nconst L = BATCH_ATTRIBUTE_LOCATIONS;\n\nexport const GLYPH_PAINT_VERT_SRC = /* glsl */ `#version 300 es\nlayout(location = ${L.a_position}) in vec2 a_position;\nlayout(location = ${L.a_uv}) in vec2 a_uv;\nlayout(location = ${L.a_texSlot}) in float a_texSlot;\nuniform mat3 u_proj;\nuniform mat3 u_model;\nuniform mat3 u_worldInv;\nout vec2 v_world;\nout vec2 v_uv;\nflat out float v_glyphMode;\nvoid main() {\n vec3 screen = u_model * vec3(a_position, 1.0);\n vec3 clip = u_proj * vec3(screen.xy, 1.0);\n gl_Position = vec4(clip.xy, 0.0, 1.0);\n v_world = (u_worldInv * vec3(screen.xy, 1.0)).xy;\n v_uv = a_uv;\n v_glyphMode = float(int(a_texSlot + 0.5) / ${BATCH_TEXTURE_SLOTS});\n}\n`;\n\nfunction fragSrc(paintGlsl: string): string {\n return /* glsl */ `#version 300 es\nprecision highp float;\nin vec2 v_world;\nin vec2 v_uv;\nflat in float v_glyphMode;\nuniform sampler2D u_atlas;\nuniform float u_synthBold;\nuniform vec2 u_fieldScale;\n${paintGlsl}\n${GLYPH_COVERAGE_GLSL}\nout vec4 outColor;\nvoid main() {\n float coverage = glyphCoverage(texture(u_atlas, v_uv), v_glyphMode, u_synthBold, v_uv, u_fieldScale);\n outColor = shadePaint(v_world) * coverage;\n}\n`;\n}\n\n/**\n * A registered paint kind binds a whole program of its own, which nothing can\n * wrap in a mask, so it renders into an offscreen buffer first and the glyphs\n * sample that. `u_worldInv` takes the screen position straight to the\n * buffer's texture coordinate, and the texel is already premultiplied and\n * faded — the kind's own program did both.\n */\nconst TEXTURE_PAINT_GLSL = /* glsl */ `\nuniform sampler2D u_sampler;\nvec4 shadePaint(vec2 uv) {\n return texture(u_sampler, uv);\n}\n`;\n\nexport const GLYPH_PATTERN_FRAG_SRC = fragSrc(PATTERN_PAINT_GLSL);\nexport const GLYPH_GRAD_FRAG_SRC = fragSrc(GRAD_PAINT_GLSL);\nexport const GLYPH_TEXTURE_FRAG_SRC = fragSrc(TEXTURE_PAINT_GLSL);\n\nconst GLYPH_UNIFORMS = ['u_atlas', 'u_synthBold', 'u_fieldScale'] as const;\n// `u_origin` belongs to the path vertex stage, which these programs replace.\nconst notOrigin = (name: string): boolean => name !== 'u_origin';\nexport const GLYPH_PATTERN_UNIFORMS: readonly string[] = [\n ...PATTERN_FILL_UNIFORMS.filter(notOrigin), ...GLYPH_UNIFORMS,\n];\nexport const GLYPH_GRAD_UNIFORMS: readonly string[] = [\n ...GRAD_FILL_UNIFORMS.filter(notOrigin), ...GLYPH_UNIFORMS,\n];\nexport const GLYPH_TEXTURE_UNIFORMS = [\n 'u_proj', 'u_model', 'u_worldInv', 'u_sampler', ...GLYPH_UNIFORMS,\n] as const;\nexport const GLYPH_PAINT_ATTRIBUTES = ['a_position', 'a_uv', 'a_texSlot'] as const;\n"],"mappings":";;;;;AA4BA,IAAMA,IAAIC,GAEGC,IAAkC;oBAC3BF,EAAE,WAAW;oBACbA,EAAE,KAAK;oBACPA,EAAE,UAAU;;;;;;;;;;;;;+CAaeG,EAAoB;;;AAInE,SAASC,EAAQ,GAA2B;CAC1C,OAAkB;;;;;;;;EAQlBC,EAAU;EACVC,EAAoB;;;;;;;AAOtB;AASA,IAAMC,IAAgC,qGAOzBC,IAAyBJ,EAAQK,CAAkB,GACnDC,IAAsBN,EAAQO,CAAe,GAC7CC,IAAyBR,EAAQG,CAAkB,GAE1DM,IAAiB;CAAC;CAAW;CAAe;AAAc,GAE1DC,KAAa,MAA0BC,MAAS,YACzCC,IAA4C,CACvD,GAAGC,EAAsB,OAAOH,CAAS,GAAG,GAAGD,CACjD,GACaK,IAAyC,CACpD,GAAGC,EAAmB,OAAOL,CAAS,GAAG,GAAGD,CAC9C,GACaO,IAAyB;CACpC;CAAU;CAAW;CAAc;CAAa,GAAGP;AACrD,GACaQ,IAAyB;CAAC;CAAc;CAAQ;AAAW"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/renderer/shaders/gradFill.ts
|
|
2
|
-
var e = "#version 300 es\nin vec2 a_position;\nuniform mat3 u_proj;\nuniform mat3 u_model;\nuniform mat3 u_worldInv;\nout vec2 v_world;\nvoid main() {\n vec3 screen = u_model * vec3(a_position, 1.0);\n vec3 clip = u_proj * vec3(screen.xy, 1.0);\n gl_Position = vec4(clip.xy, 0.0, 1.0);\n vec3 world = u_worldInv * vec3(screen.xy, 1.0);\n v_world = world.xy;\n}\n", t = "\nuniform sampler2D u_ramp;\nuniform float u_rampV;\nuniform float u_alpha;\nuniform mat4 u_colorMatrix;\nuniform vec4 u_colorBias;\nuniform float u_opacity;\nuniform int u_gradKind;\nuniform vec2 u_gradP0;\nuniform vec2 u_gradDir;\nuniform float u_gradLen;\nuniform float u_gradRadius;\nuniform float u_gradAngle;\n\nconst float PI = 3.14159265358979323846;\n\nvec4 shadePaint(vec2 world) {\n float t;\n if (u_gradKind == 0) {\n vec2 d = world - u_gradP0;\n t = dot(d, u_gradDir) / max(u_gradLen, 0.0001);\n } else if (u_gradKind == 1) {\n t = length(world - u_gradP0) / max(u_gradRadius, 0.0001);\n } else {\n float a = atan(world.y - u_gradP0.y, world.x - u_gradP0.x) - u_gradAngle;\n t = fract(a / (2.0 * PI));\n }\n t = clamp(t, 0.0, 1.0);\n vec4 rampColor = texture(u_ramp, vec2(t, u_rampV));\n // Fill opacity into the alpha channel before the matrix, which is where the\n // batch program's vertex alpha sits. The two have to agree, since a linear\n // gradient goes through that one and a radial through this.\n vec4 src = vec4(rampColor.rgb, rampColor.a * u_opacity);\n vec4 mapped = clamp(u_colorMatrix * src + u_colorBias, 0.0, 1.0);\n float a = mapped.a * u_alpha;\n return vec4(mapped.rgb * a, a);\n}\n", n = `#version 300 es
|
|
2
|
+
var e = "#version 300 es\nin vec2 a_position;\nuniform mat3 u_proj;\nuniform mat3 u_model;\nuniform vec2 u_origin;\nuniform mat3 u_worldInv;\nout vec2 v_world;\nvoid main() {\n vec3 screen = u_model * vec3(a_position - u_origin, 1.0);\n vec3 clip = u_proj * vec3(screen.xy, 1.0);\n gl_Position = vec4(clip.xy, 0.0, 1.0);\n vec3 world = u_worldInv * vec3(screen.xy, 1.0);\n v_world = world.xy;\n}\n", t = "\nuniform sampler2D u_ramp;\nuniform float u_rampV;\nuniform float u_alpha;\nuniform mat4 u_colorMatrix;\nuniform vec4 u_colorBias;\nuniform float u_opacity;\nuniform int u_gradKind;\nuniform vec2 u_gradP0;\nuniform vec2 u_gradDir;\nuniform float u_gradLen;\nuniform float u_gradRadius;\nuniform float u_gradAngle;\n\nconst float PI = 3.14159265358979323846;\n\nvec4 shadePaint(vec2 world) {\n float t;\n if (u_gradKind == 0) {\n vec2 d = world - u_gradP0;\n t = dot(d, u_gradDir) / max(u_gradLen, 0.0001);\n } else if (u_gradKind == 1) {\n t = length(world - u_gradP0) / max(u_gradRadius, 0.0001);\n } else {\n float a = atan(world.y - u_gradP0.y, world.x - u_gradP0.x) - u_gradAngle;\n t = fract(a / (2.0 * PI));\n }\n t = clamp(t, 0.0, 1.0);\n vec4 rampColor = texture(u_ramp, vec2(t, u_rampV));\n // Fill opacity into the alpha channel before the matrix, which is where the\n // batch program's vertex alpha sits. The two have to agree, since a linear\n // gradient goes through that one and a radial through this.\n vec4 src = vec4(rampColor.rgb, rampColor.a * u_opacity);\n vec4 mapped = clamp(u_colorMatrix * src + u_colorBias, 0.0, 1.0);\n float a = mapped.a * u_alpha;\n return vec4(mapped.rgb * a, a);\n}\n", n = `#version 300 es
|
|
3
3
|
precision highp float;
|
|
4
4
|
in vec2 v_world;
|
|
5
5
|
${t}
|
|
@@ -10,6 +10,7 @@ void main() {
|
|
|
10
10
|
`, r = [
|
|
11
11
|
"u_proj",
|
|
12
12
|
"u_model",
|
|
13
|
+
"u_origin",
|
|
13
14
|
"u_worldInv",
|
|
14
15
|
"u_ramp",
|
|
15
16
|
"u_rampV",
|