@pixerate/editor 0.213.0 → 0.215.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/{chunk-UOGKSVRQ.cjs → chunk-B46UQUDC.cjs} +770 -733
  2. package/dist/{chunk-W3TOZTL7.js → chunk-F7Z2MKY2.js} +115 -4
  3. package/dist/{chunk-YBJXCQTR.js → chunk-QXY4YTRI.js} +738 -701
  4. package/dist/{chunk-H65IBXFI.cjs → chunk-S55JFWDA.cjs} +350 -239
  5. package/dist/{chunk-QYLWG22N.cjs → chunk-SS53NNZO.cjs} +304 -1
  6. package/dist/{chunk-LQ5SALHK.js → chunk-U7C655AM.js} +5 -311
  7. package/dist/{chunk-L52VMQZS.cjs → chunk-UC3PWFM3.cjs} +68 -374
  8. package/dist/{chunk-L3G23N5Y.js → chunk-ZNA3IQZF.js} +304 -1
  9. package/dist/image-editor/controller.d.cts +44 -0
  10. package/dist/image-editor/controller.d.ts +44 -0
  11. package/dist/image-editor/index.cjs +1768 -1140
  12. package/dist/image-editor/index.d.cts +1 -0
  13. package/dist/image-editor/index.d.ts +1 -0
  14. package/dist/image-editor/index.js +660 -32
  15. package/dist/image-editor/layers/edge-color.d.cts +27 -0
  16. package/dist/image-editor/layers/edge-color.d.ts +27 -0
  17. package/dist/image-editor/layers/serialize.d.cts +13 -0
  18. package/dist/image-editor/layers/serialize.d.ts +13 -0
  19. package/dist/image-editor/selection/index.d.cts +1 -0
  20. package/dist/image-editor/selection/index.d.ts +1 -0
  21. package/dist/image-editor/selection/inspect.d.cts +70 -0
  22. package/dist/image-editor/selection/inspect.d.ts +70 -0
  23. package/dist/image-editor/selection-worker.cjs +4 -4
  24. package/dist/image-editor/selection-worker.js +2 -2
  25. package/dist/paint-editor/index.cjs +79 -79
  26. package/dist/paint-editor/index.js +3 -3
  27. package/dist/raster/compositor.d.cts +10 -1
  28. package/dist/raster/compositor.d.ts +10 -1
  29. package/dist/raster/deep-compositor.d.cts +1 -1
  30. package/dist/raster/deep-compositor.d.ts +1 -1
  31. package/dist/raster/index.cjs +4 -2
  32. package/dist/raster/index.js +3 -1
  33. package/dist/raster/layers.d.cts +16 -0
  34. package/dist/raster/layers.d.ts +16 -0
  35. package/package.json +1 -1
  36. package/skills/pixerate-image-editor/SKILL.md +9 -6
  37. package/skills/pixerate-image-editor/references/paths.md +12 -0
  38. package/skills/pixerate-image-selection-masking/SKILL.md +17 -17
@@ -29,7 +29,7 @@ import { type BlendMode } from './blend.js';
29
29
  import { type GlobalLight, type LayerEffects } from './effects/model.js';
30
30
  import { type EffectPattern } from './effects/patterns.js';
31
31
  import { type EffectCompositeInput } from './effects/render.js';
32
- import type { RasterMask, RasterNode } from './layers.js';
32
+ import type { RasterMask, RasterNode, LayerEdgeColor } from './layers.js';
33
33
  import { type PixelSurface, type RasterRect, type TileKey, type TiledSurface } from './surface.js';
34
34
  /** What the compositor needs from its host besides the layers. */
35
35
  export interface RasterSources {
@@ -61,9 +61,18 @@ export interface CompositorLayer extends RasterNode {
61
61
  fillOpacity?: number;
62
62
  /** Layer effects. */
63
63
  effects?: LayerEffects;
64
+ /** Edge colour; the engine applies `ambient` (the profile's pixel filters handle the rest). */
65
+ edge?: LayerEdgeColor;
64
66
  /** Groups. */
65
67
  children?: readonly CompositorLayer[];
66
68
  }
69
+ /**
70
+ * Live edge cast (`LayerEdgeColor.ambient`): pulls straight RGBA `content` toward `below` (the
71
+ * composite behind it, same size) or a fixed colour, by `amount × (1 − α)` where α is the content's
72
+ * alpha times `coverage` (its mask). Opaque and invisible pixels are unchanged. `max` is 255 for
73
+ * bytes or 1 for float samples; `color` is in the same units.
74
+ */
75
+ export declare function applyEdgeAmbient(content: Uint8ClampedArray | Float32Array, below: ArrayLike<number>, coverage: ArrayLike<number> | null, amount: number, color: readonly [number, number, number] | null, max: number): void;
67
76
  /** A pixel layer's filters as the engine runs them. */
68
77
  export interface PixelFilterSpec {
69
78
  /** Identifies the settings (part of the cache key). */
@@ -17,7 +17,7 @@
17
17
  * each is rendered alone at 8 bits, converted, and blended in float with its blend mode and
18
18
  * opacity.
19
19
  */
20
- import type { CompositorLayer, CompositorProfile, RasterCompositor, RasterSources } from './compositor.cjs';
20
+ import { type CompositorLayer, type CompositorProfile, type RasterCompositor, type RasterSources } from './compositor.cjs';
21
21
  import type { RasterRect } from './surface.cjs';
22
22
  /** Float hooks of an editor's own layer kinds (see `CompositorProfile`). */
23
23
  export interface DeepCompositorProfile<L extends CompositorLayer, S extends RasterSources> {
@@ -17,7 +17,7 @@
17
17
  * each is rendered alone at 8 bits, converted, and blended in float with its blend mode and
18
18
  * opacity.
19
19
  */
20
- import type { CompositorLayer, CompositorProfile, RasterCompositor, RasterSources } from './compositor.js';
20
+ import { type CompositorLayer, type CompositorProfile, type RasterCompositor, type RasterSources } from './compositor.js';
21
21
  import type { RasterRect } from './surface.js';
22
22
  /** Float hooks of an editor's own layer kinds (see `CompositorProfile`). */
23
23
  export interface DeepCompositorProfile<L extends CompositorLayer, S extends RasterSources> {
@@ -59,7 +59,8 @@
59
59
 
60
60
 
61
61
 
62
- var _chunkUOGKSVRQcjs = require('../chunk-UOGKSVRQ.cjs');
62
+
63
+ var _chunkB46UQUDCcjs = require('../chunk-B46UQUDC.cjs');
63
64
  require('../chunk-QT26RHKK.cjs');
64
65
 
65
66
 
@@ -514,4 +515,5 @@ function drawSurfaceToViewport(ctx, surface, mapping, view, options) {
514
515
 
515
516
 
516
517
 
517
- exports.BIT_DEPTHS = _chunkOLNIPTB3cjs.BIT_DEPTHS; exports.BLEND_MODES = _chunkOLNIPTB3cjs.BLEND_MODES; exports.CURVE_LUT_SIZE = _chunkUOGKSVRQcjs.CURVE_LUT_SIZE; exports.DEFAULT_GLOBAL_LIGHT = _chunkUOGKSVRQcjs.DEFAULT_GLOBAL_LIGHT; exports.DIRECT_GAUSSIAN_MAX_SIGMA = _chunkK6PXS6DOcjs.DIRECT_GAUSSIAN_MAX_SIGMA; exports.DeepCompositor = _chunkUOGKSVRQcjs.DeepCompositor; exports.INTERPOLATIONS = _chunkUOGKSVRQcjs.INTERPOLATIONS; exports.LAYER_EFFECT_KINDS = _chunkUOGKSVRQcjs.LAYER_EFFECT_KINDS; exports.LayerEffectError = _chunkUOGKSVRQcjs.LayerEffectError; exports.MAX_EFFECT_REACH = _chunkUOGKSVRQcjs.MAX_EFFECT_REACH; exports.MAX_TRANSFORM_PIXELS = _chunkUOGKSVRQcjs.MAX_TRANSFORM_PIXELS; exports.PAINTERLY_BLEND_MODES = _chunkOLNIPTB3cjs.PAINTERLY_BLEND_MODES; exports.PatternPlacement = _chunkUOGKSVRQcjs.PatternPlacement; exports.PatternTile = _chunkUOGKSVRQcjs.PatternTile; exports.RasterCompositor = _chunkUOGKSVRQcjs.RasterCompositor; exports.SHADOW_AMBIENT = _chunkOLNIPTB3cjs.SHADOW_AMBIENT; exports.STROKE_CHAMFER_MAX = _chunkUOGKSVRQcjs.STROKE_CHAMFER_MAX; exports.SurfaceDraft = _chunk474IQG74cjs.SurfaceDraft; exports.SurfaceViewportRenderer = SurfaceViewportRenderer; exports.TILE = _chunk474IQG74cjs.TILE; exports.TILE_SHIFT = _chunk474IQG74cjs.TILE_SHIFT; exports.TiledSurface = _chunk474IQG74cjs.TiledSurface; exports.TransformTooLargeError = _chunkUOGKSVRQcjs.TransformTooLargeError; exports.ZlibError = _chunkXFM3OCHUcjs.ZlibError; exports.activeEffectItems = _chunkUOGKSVRQcjs.activeEffectItems; exports.adler32 = _chunkXFM3OCHUcjs.adler32; exports.base64ToBytes = _chunkOLNIPTB3cjs.base64ToBytes; exports.blendChannel = _chunkOLNIPTB3cjs.blendChannel; exports.blendImageData = _chunkOLNIPTB3cjs.blendImageData; exports.blendLum = _chunkOLNIPTB3cjs.blendLum; exports.blendPixel = _chunkOLNIPTB3cjs.blendPixel; exports.blendRgb = _chunkOLNIPTB3cjs.blendRgb; exports.blendTile = _chunkUOGKSVRQcjs.blendTile; exports.buildEffectMaps = _chunkUOGKSVRQcjs.buildEffectMaps; exports.builtinPattern = _chunkUOGKSVRQcjs.builtinPattern; exports.builtinPatternIds = _chunkUOGKSVRQcjs.builtinPatternIds; exports.bytesToBase64 = _chunkOLNIPTB3cjs.bytesToBase64; exports.canvasCompositeOperation = _chunkOLNIPTB3cjs.canvasCompositeOperation; exports.changedTiles = _chunkUOGKSVRQcjs.changedTiles; exports.collectTiles = _chunk474IQG74cjs.collectTiles; exports.compositeLayerEffects = _chunkUOGKSVRQcjs.compositeLayerEffects; exports.compositeSurfaceOver = _chunkUOGKSVRQcjs.compositeSurfaceOver; exports.contentBounds = _chunk474IQG74cjs.contentBounds; exports.contourLut = _chunkUOGKSVRQcjs.contourLut; exports.convertSurfaceDepth = _chunkOLNIPTB3cjs.convertSurfaceDepth; exports.curveLut = _chunkUOGKSVRQcjs.curveLut; exports.decodePng = _chunkOLNIPTB3cjs.decodePng; exports.deepBytes = _chunkOLNIPTB3cjs.deepBytes; exports.deepTile = _chunkOLNIPTB3cjs.deepTile; exports.defaultEffectGradient = _chunkUOGKSVRQcjs.defaultEffectGradient; exports.defaultLayerEffect = _chunkUOGKSVRQcjs.defaultLayerEffect; exports.deflate = _chunkXFM3OCHUcjs.deflate; exports.deflateRaw = _chunkXFM3OCHUcjs.deflateRaw; exports.depthOf = _chunkOLNIPTB3cjs.depthOf; exports.drawSurfaceToViewport = drawSurfaceToViewport; exports.effectColorHex = _chunkUOGKSVRQcjs.effectColorHex; exports.effectFillColors = _chunkUOGKSVRQcjs.effectFillColors; exports.effectReach = _chunkUOGKSVRQcjs.effectReach; exports.effectsAreLocal = _chunkUOGKSVRQcjs.effectsAreLocal; exports.effectsFingerprint = _chunkUOGKSVRQcjs.effectsFingerprint; exports.effectsMargin = _chunkUOGKSVRQcjs.effectsMargin; exports.effectsScale = _chunkUOGKSVRQcjs.effectsScale; exports.emptySurface = _chunk474IQG74cjs.emptySurface; exports.encodePng = _chunkOLNIPTB3cjs.encodePng; exports.fillRect = _chunk474IQG74cjs.fillRect; exports.findLayer = _chunkUOGKSVRQcjs.findLayer; exports.finishTile = _chunk474IQG74cjs.finishTile; exports.flattenLayers = _chunkUOGKSVRQcjs.flattenLayers; exports.gaussianBlur = _chunkK6PXS6DOcjs.gaussianBlur; exports.gradientT = _chunkUOGKSVRQcjs.gradientT; exports.hasActiveEffects = _chunkUOGKSVRQcjs.hasActiveEffects; exports.hashNoise = _chunkUOGKSVRQcjs.hashNoise; exports.inflate = _chunkXFM3OCHUcjs.inflate; exports.inflateRaw = _chunkXFM3OCHUcjs.inflateRaw; exports.insertLayer = _chunkUOGKSVRQcjs.insertLayer; exports.isBitDepth = _chunkOLNIPTB3cjs.isBitDepth; exports.isBlendMode = _chunkOLNIPTB3cjs.isBlendMode; exports.isInterpolation = _chunkUOGKSVRQcjs.isInterpolation; exports.isLayerEffectKind = _chunkUOGKSVRQcjs.isLayerEffectKind; exports.isLayerLocked = _chunkUOGKSVRQcjs.isLayerLocked; exports.isPainterlyBlendMode = _chunkOLNIPTB3cjs.isPainterlyBlendMode; exports.isPng = _chunkOLNIPTB3cjs.isPng; exports.isSeparableBlendMode = _chunkOLNIPTB3cjs.isSeparableBlendMode; exports.keepDeepSamples = _chunkOLNIPTB3cjs.keepDeepSamples; exports.keysWeight = _chunkUOGKSVRQcjs.keysWeight; exports.layerEffectFields = _chunkUOGKSVRQcjs.layerEffectFields; exports.layerEffectLabel = _chunkUOGKSVRQcjs.layerEffectLabel; exports.mapLayer = _chunkUOGKSVRQcjs.mapLayer; exports.mergeLayerEffect = _chunkUOGKSVRQcjs.mergeLayerEffect; exports.mixPigment8 = _chunkOLNIPTB3cjs.mixPigment8; exports.mixPigmentRgb = _chunkOLNIPTB3cjs.mixPigmentRgb; exports.newEffectId = _chunkUOGKSVRQcjs.newEffectId; exports.normalizeBlendMode = _chunkOLNIPTB3cjs.normalizeBlendMode; exports.normalizeLayerEffects = _chunkUOGKSVRQcjs.normalizeLayerEffects; exports.packRgba = _chunk474IQG74cjs.packRgba; exports.parseDataUrl = _chunkOLNIPTB3cjs.parseDataUrl; exports.parseEffectColor = _chunkUOGKSVRQcjs.parseEffectColor; exports.patchEffectMaps = _chunkUOGKSVRQcjs.patchEffectMaps; exports.pigment8 = _chunkOLNIPTB3cjs.pigment8; exports.pngDataUrl = _chunkOLNIPTB3cjs.pngDataUrl; exports.proxyOf = _chunkOLNIPTB3cjs.proxyOf; exports.readDeepRegion = _chunkOLNIPTB3cjs.readDeepRegion; exports.readPixel = _chunk474IQG74cjs.readPixel; exports.readRegion = _chunk474IQG74cjs.readRegion; exports.reduceSurface = _chunkUOGKSVRQcjs.reduceSurface; exports.renderLayerEffects = _chunkUOGKSVRQcjs.renderLayerEffects; exports.scaleLayerEffect = _chunkUOGKSVRQcjs.scaleLayerEffect; exports.screenToWorld = screenToWorld; exports.setLum = _chunkOLNIPTB3cjs.setLum; exports.solidSurface = _chunk474IQG74cjs.solidSurface; exports.srgbDecode = _chunkOLNIPTB3cjs.srgbDecode; exports.srgbEncode = _chunkOLNIPTB3cjs.srgbEncode; exports.standardBlendMode = _chunkOLNIPTB3cjs.standardBlendMode; exports.surfaceBytes = _chunk474IQG74cjs.surfaceBytes; exports.surfaceDepth = _chunkOLNIPTB3cjs.surfaceDepth; exports.surfaceFromDeepPixels = _chunkOLNIPTB3cjs.surfaceFromDeepPixels; exports.surfaceFromPixels = _chunk474IQG74cjs.surfaceFromPixels; exports.surfaceMipLevel = surfaceMipLevel; exports.surfaceResolutionForZoom = surfaceResolutionForZoom; exports.surfaceToWorld = surfaceToWorld; exports.surfacesEqual = _chunk474IQG74cjs.surfacesEqual; exports.tileCoord = _chunk474IQG74cjs.tileCoord; exports.tileKey = _chunk474IQG74cjs.tileKey; exports.tileRect = _chunk474IQG74cjs.tileRect; exports.tileSamples = _chunkOLNIPTB3cjs.tileSamples; exports.tileSamples16 = _chunkOLNIPTB3cjs.tileSamples16; exports.tileSamples32 = _chunkOLNIPTB3cjs.tileSamples32; exports.tilesInRect = _chunk474IQG74cjs.tilesInRect; exports.to16From32 = _chunkOLNIPTB3cjs.to16From32; exports.to16From8 = _chunkOLNIPTB3cjs.to16From8; exports.to32From16 = _chunkOLNIPTB3cjs.to32From16; exports.to32From8 = _chunkOLNIPTB3cjs.to32From8; exports.to8From16 = _chunkOLNIPTB3cjs.to8From16; exports.to8From32 = _chunkOLNIPTB3cjs.to8From32; exports.transformSurface = _chunkUOGKSVRQcjs.transformSurface; exports.transformedBounds = _chunkUOGKSVRQcjs.transformedBounds; exports.translateSurface = _chunk474IQG74cjs.translateSurface; exports.uniformTile = _chunk474IQG74cjs.uniformTile; exports.validateEffectGradient = _chunkUOGKSVRQcjs.validateEffectGradient; exports.validateLayerEffect = _chunkUOGKSVRQcjs.validateLayerEffect; exports.validateLayerEffects = _chunkUOGKSVRQcjs.validateLayerEffects; exports.visibleSurfaceRect = visibleSurfaceRect; exports.visibleWorldRect = visibleWorldRect; exports.warpSurface = _chunkUOGKSVRQcjs.warpSurface; exports.workingToSamples = _chunkUOGKSVRQcjs.workingToSamples; exports.worldRectToSurface = worldRectToSurface; exports.worldToSurface = worldToSurface; exports.writeDeepRegion = _chunkOLNIPTB3cjs.writeDeepRegion; exports.writeRegion = _chunk474IQG74cjs.writeRegion;
518
+
519
+ exports.BIT_DEPTHS = _chunkOLNIPTB3cjs.BIT_DEPTHS; exports.BLEND_MODES = _chunkOLNIPTB3cjs.BLEND_MODES; exports.CURVE_LUT_SIZE = _chunkB46UQUDCcjs.CURVE_LUT_SIZE; exports.DEFAULT_GLOBAL_LIGHT = _chunkB46UQUDCcjs.DEFAULT_GLOBAL_LIGHT; exports.DIRECT_GAUSSIAN_MAX_SIGMA = _chunkK6PXS6DOcjs.DIRECT_GAUSSIAN_MAX_SIGMA; exports.DeepCompositor = _chunkB46UQUDCcjs.DeepCompositor; exports.INTERPOLATIONS = _chunkB46UQUDCcjs.INTERPOLATIONS; exports.LAYER_EFFECT_KINDS = _chunkB46UQUDCcjs.LAYER_EFFECT_KINDS; exports.LayerEffectError = _chunkB46UQUDCcjs.LayerEffectError; exports.MAX_EFFECT_REACH = _chunkB46UQUDCcjs.MAX_EFFECT_REACH; exports.MAX_TRANSFORM_PIXELS = _chunkB46UQUDCcjs.MAX_TRANSFORM_PIXELS; exports.PAINTERLY_BLEND_MODES = _chunkOLNIPTB3cjs.PAINTERLY_BLEND_MODES; exports.PatternPlacement = _chunkB46UQUDCcjs.PatternPlacement; exports.PatternTile = _chunkB46UQUDCcjs.PatternTile; exports.RasterCompositor = _chunkB46UQUDCcjs.RasterCompositor; exports.SHADOW_AMBIENT = _chunkOLNIPTB3cjs.SHADOW_AMBIENT; exports.STROKE_CHAMFER_MAX = _chunkB46UQUDCcjs.STROKE_CHAMFER_MAX; exports.SurfaceDraft = _chunk474IQG74cjs.SurfaceDraft; exports.SurfaceViewportRenderer = SurfaceViewportRenderer; exports.TILE = _chunk474IQG74cjs.TILE; exports.TILE_SHIFT = _chunk474IQG74cjs.TILE_SHIFT; exports.TiledSurface = _chunk474IQG74cjs.TiledSurface; exports.TransformTooLargeError = _chunkB46UQUDCcjs.TransformTooLargeError; exports.ZlibError = _chunkXFM3OCHUcjs.ZlibError; exports.activeEffectItems = _chunkB46UQUDCcjs.activeEffectItems; exports.adler32 = _chunkXFM3OCHUcjs.adler32; exports.applyEdgeAmbient = _chunkB46UQUDCcjs.applyEdgeAmbient; exports.base64ToBytes = _chunkOLNIPTB3cjs.base64ToBytes; exports.blendChannel = _chunkOLNIPTB3cjs.blendChannel; exports.blendImageData = _chunkOLNIPTB3cjs.blendImageData; exports.blendLum = _chunkOLNIPTB3cjs.blendLum; exports.blendPixel = _chunkOLNIPTB3cjs.blendPixel; exports.blendRgb = _chunkOLNIPTB3cjs.blendRgb; exports.blendTile = _chunkB46UQUDCcjs.blendTile; exports.buildEffectMaps = _chunkB46UQUDCcjs.buildEffectMaps; exports.builtinPattern = _chunkB46UQUDCcjs.builtinPattern; exports.builtinPatternIds = _chunkB46UQUDCcjs.builtinPatternIds; exports.bytesToBase64 = _chunkOLNIPTB3cjs.bytesToBase64; exports.canvasCompositeOperation = _chunkOLNIPTB3cjs.canvasCompositeOperation; exports.changedTiles = _chunkB46UQUDCcjs.changedTiles; exports.collectTiles = _chunk474IQG74cjs.collectTiles; exports.compositeLayerEffects = _chunkB46UQUDCcjs.compositeLayerEffects; exports.compositeSurfaceOver = _chunkB46UQUDCcjs.compositeSurfaceOver; exports.contentBounds = _chunk474IQG74cjs.contentBounds; exports.contourLut = _chunkB46UQUDCcjs.contourLut; exports.convertSurfaceDepth = _chunkOLNIPTB3cjs.convertSurfaceDepth; exports.curveLut = _chunkB46UQUDCcjs.curveLut; exports.decodePng = _chunkOLNIPTB3cjs.decodePng; exports.deepBytes = _chunkOLNIPTB3cjs.deepBytes; exports.deepTile = _chunkOLNIPTB3cjs.deepTile; exports.defaultEffectGradient = _chunkB46UQUDCcjs.defaultEffectGradient; exports.defaultLayerEffect = _chunkB46UQUDCcjs.defaultLayerEffect; exports.deflate = _chunkXFM3OCHUcjs.deflate; exports.deflateRaw = _chunkXFM3OCHUcjs.deflateRaw; exports.depthOf = _chunkOLNIPTB3cjs.depthOf; exports.drawSurfaceToViewport = drawSurfaceToViewport; exports.effectColorHex = _chunkB46UQUDCcjs.effectColorHex; exports.effectFillColors = _chunkB46UQUDCcjs.effectFillColors; exports.effectReach = _chunkB46UQUDCcjs.effectReach; exports.effectsAreLocal = _chunkB46UQUDCcjs.effectsAreLocal; exports.effectsFingerprint = _chunkB46UQUDCcjs.effectsFingerprint; exports.effectsMargin = _chunkB46UQUDCcjs.effectsMargin; exports.effectsScale = _chunkB46UQUDCcjs.effectsScale; exports.emptySurface = _chunk474IQG74cjs.emptySurface; exports.encodePng = _chunkOLNIPTB3cjs.encodePng; exports.fillRect = _chunk474IQG74cjs.fillRect; exports.findLayer = _chunkB46UQUDCcjs.findLayer; exports.finishTile = _chunk474IQG74cjs.finishTile; exports.flattenLayers = _chunkB46UQUDCcjs.flattenLayers; exports.gaussianBlur = _chunkK6PXS6DOcjs.gaussianBlur; exports.gradientT = _chunkB46UQUDCcjs.gradientT; exports.hasActiveEffects = _chunkB46UQUDCcjs.hasActiveEffects; exports.hashNoise = _chunkB46UQUDCcjs.hashNoise; exports.inflate = _chunkXFM3OCHUcjs.inflate; exports.inflateRaw = _chunkXFM3OCHUcjs.inflateRaw; exports.insertLayer = _chunkB46UQUDCcjs.insertLayer; exports.isBitDepth = _chunkOLNIPTB3cjs.isBitDepth; exports.isBlendMode = _chunkOLNIPTB3cjs.isBlendMode; exports.isInterpolation = _chunkB46UQUDCcjs.isInterpolation; exports.isLayerEffectKind = _chunkB46UQUDCcjs.isLayerEffectKind; exports.isLayerLocked = _chunkB46UQUDCcjs.isLayerLocked; exports.isPainterlyBlendMode = _chunkOLNIPTB3cjs.isPainterlyBlendMode; exports.isPng = _chunkOLNIPTB3cjs.isPng; exports.isSeparableBlendMode = _chunkOLNIPTB3cjs.isSeparableBlendMode; exports.keepDeepSamples = _chunkOLNIPTB3cjs.keepDeepSamples; exports.keysWeight = _chunkB46UQUDCcjs.keysWeight; exports.layerEffectFields = _chunkB46UQUDCcjs.layerEffectFields; exports.layerEffectLabel = _chunkB46UQUDCcjs.layerEffectLabel; exports.mapLayer = _chunkB46UQUDCcjs.mapLayer; exports.mergeLayerEffect = _chunkB46UQUDCcjs.mergeLayerEffect; exports.mixPigment8 = _chunkOLNIPTB3cjs.mixPigment8; exports.mixPigmentRgb = _chunkOLNIPTB3cjs.mixPigmentRgb; exports.newEffectId = _chunkB46UQUDCcjs.newEffectId; exports.normalizeBlendMode = _chunkOLNIPTB3cjs.normalizeBlendMode; exports.normalizeLayerEffects = _chunkB46UQUDCcjs.normalizeLayerEffects; exports.packRgba = _chunk474IQG74cjs.packRgba; exports.parseDataUrl = _chunkOLNIPTB3cjs.parseDataUrl; exports.parseEffectColor = _chunkB46UQUDCcjs.parseEffectColor; exports.patchEffectMaps = _chunkB46UQUDCcjs.patchEffectMaps; exports.pigment8 = _chunkOLNIPTB3cjs.pigment8; exports.pngDataUrl = _chunkOLNIPTB3cjs.pngDataUrl; exports.proxyOf = _chunkOLNIPTB3cjs.proxyOf; exports.readDeepRegion = _chunkOLNIPTB3cjs.readDeepRegion; exports.readPixel = _chunk474IQG74cjs.readPixel; exports.readRegion = _chunk474IQG74cjs.readRegion; exports.reduceSurface = _chunkB46UQUDCcjs.reduceSurface; exports.renderLayerEffects = _chunkB46UQUDCcjs.renderLayerEffects; exports.scaleLayerEffect = _chunkB46UQUDCcjs.scaleLayerEffect; exports.screenToWorld = screenToWorld; exports.setLum = _chunkOLNIPTB3cjs.setLum; exports.solidSurface = _chunk474IQG74cjs.solidSurface; exports.srgbDecode = _chunkOLNIPTB3cjs.srgbDecode; exports.srgbEncode = _chunkOLNIPTB3cjs.srgbEncode; exports.standardBlendMode = _chunkOLNIPTB3cjs.standardBlendMode; exports.surfaceBytes = _chunk474IQG74cjs.surfaceBytes; exports.surfaceDepth = _chunkOLNIPTB3cjs.surfaceDepth; exports.surfaceFromDeepPixels = _chunkOLNIPTB3cjs.surfaceFromDeepPixels; exports.surfaceFromPixels = _chunk474IQG74cjs.surfaceFromPixels; exports.surfaceMipLevel = surfaceMipLevel; exports.surfaceResolutionForZoom = surfaceResolutionForZoom; exports.surfaceToWorld = surfaceToWorld; exports.surfacesEqual = _chunk474IQG74cjs.surfacesEqual; exports.tileCoord = _chunk474IQG74cjs.tileCoord; exports.tileKey = _chunk474IQG74cjs.tileKey; exports.tileRect = _chunk474IQG74cjs.tileRect; exports.tileSamples = _chunkOLNIPTB3cjs.tileSamples; exports.tileSamples16 = _chunkOLNIPTB3cjs.tileSamples16; exports.tileSamples32 = _chunkOLNIPTB3cjs.tileSamples32; exports.tilesInRect = _chunk474IQG74cjs.tilesInRect; exports.to16From32 = _chunkOLNIPTB3cjs.to16From32; exports.to16From8 = _chunkOLNIPTB3cjs.to16From8; exports.to32From16 = _chunkOLNIPTB3cjs.to32From16; exports.to32From8 = _chunkOLNIPTB3cjs.to32From8; exports.to8From16 = _chunkOLNIPTB3cjs.to8From16; exports.to8From32 = _chunkOLNIPTB3cjs.to8From32; exports.transformSurface = _chunkB46UQUDCcjs.transformSurface; exports.transformedBounds = _chunkB46UQUDCcjs.transformedBounds; exports.translateSurface = _chunk474IQG74cjs.translateSurface; exports.uniformTile = _chunk474IQG74cjs.uniformTile; exports.validateEffectGradient = _chunkB46UQUDCcjs.validateEffectGradient; exports.validateLayerEffect = _chunkB46UQUDCcjs.validateLayerEffect; exports.validateLayerEffects = _chunkB46UQUDCcjs.validateLayerEffects; exports.visibleSurfaceRect = visibleSurfaceRect; exports.visibleWorldRect = visibleWorldRect; exports.warpSurface = _chunkB46UQUDCcjs.warpSurface; exports.workingToSamples = _chunkB46UQUDCcjs.workingToSamples; exports.worldRectToSurface = worldRectToSurface; exports.worldToSurface = worldToSurface; exports.writeDeepRegion = _chunkOLNIPTB3cjs.writeDeepRegion; exports.writeRegion = _chunk474IQG74cjs.writeRegion;
@@ -13,6 +13,7 @@ import {
13
13
  STROKE_CHAMFER_MAX,
14
14
  TransformTooLargeError,
15
15
  activeEffectItems,
16
+ applyEdgeAmbient,
16
17
  blendTile,
17
18
  buildEffectMaps,
18
19
  builtinPattern,
@@ -59,7 +60,7 @@ import {
59
60
  validateLayerEffects,
60
61
  warpSurface,
61
62
  workingToSamples
62
- } from "../chunk-YBJXCQTR.js";
63
+ } from "../chunk-QXY4YTRI.js";
63
64
  import "../chunk-OHKOFKBY.js";
64
65
  import {
65
66
  DIRECT_GAUSSIAN_MAX_SIGMA,
@@ -391,6 +392,7 @@ export {
391
392
  ZlibError,
392
393
  activeEffectItems,
393
394
  adler32,
395
+ applyEdgeAmbient,
394
396
  base64ToBytes,
395
397
  blendChannel,
396
398
  blendImageData,
@@ -44,6 +44,20 @@ export interface RasterMask<Source = unknown> {
44
44
  linked?: boolean;
45
45
  source?: Source;
46
46
  }
47
+ /**
48
+ * Colour corrections at a layer's soft edge, applied when compositing (nothing is baked). Amounts
49
+ * are 0..1; missing or 0 is off.
50
+ */
51
+ export interface LayerEdgeColor {
52
+ /** Replaces edge colour with the subject's own, unmixed from the old background (the pixels the layer's mask hides). */
53
+ decontaminate?: number;
54
+ /** Limits how much of the old background's hue the edge carries (a heuristic; bounced light is not removed). */
55
+ despill?: number;
56
+ /** Pulls edge colour toward what is behind the layer now, more where the edge is more transparent. */
57
+ ambient?: number;
58
+ /** sRGB 0..255 for `ambient`; missing: the composite behind the layer, sampled live. */
59
+ ambientColor?: [number, number, number];
60
+ }
47
61
  export interface RasterLayerBase {
48
62
  id: string;
49
63
  name: string;
@@ -57,6 +71,8 @@ export interface RasterLayerBase {
57
71
  locks?: LayerLocks;
58
72
  /** Live layer effects (drop shadow, stroke, …), rendered between the content and its blend. */
59
73
  effects?: LayerEffects;
74
+ /** Colour corrections at the layer's soft edge (see `LayerEdgeColor`). */
75
+ edge?: LayerEdgeColor;
60
76
  }
61
77
  export interface RasterPixelLayer extends RasterLayerBase {
62
78
  type: 'pixel';
@@ -44,6 +44,20 @@ export interface RasterMask<Source = unknown> {
44
44
  linked?: boolean;
45
45
  source?: Source;
46
46
  }
47
+ /**
48
+ * Colour corrections at a layer's soft edge, applied when compositing (nothing is baked). Amounts
49
+ * are 0..1; missing or 0 is off.
50
+ */
51
+ export interface LayerEdgeColor {
52
+ /** Replaces edge colour with the subject's own, unmixed from the old background (the pixels the layer's mask hides). */
53
+ decontaminate?: number;
54
+ /** Limits how much of the old background's hue the edge carries (a heuristic; bounced light is not removed). */
55
+ despill?: number;
56
+ /** Pulls edge colour toward what is behind the layer now, more where the edge is more transparent. */
57
+ ambient?: number;
58
+ /** sRGB 0..255 for `ambient`; missing: the composite behind the layer, sampled live. */
59
+ ambientColor?: [number, number, number];
60
+ }
47
61
  export interface RasterLayerBase {
48
62
  id: string;
49
63
  name: string;
@@ -57,6 +71,8 @@ export interface RasterLayerBase {
57
71
  locks?: LayerLocks;
58
72
  /** Live layer effects (drop shadow, stroke, …), rendered between the content and its blend. */
59
73
  effects?: LayerEffects;
74
+ /** Colour corrections at the layer's soft edge (see `LayerEdgeColor`). */
75
+ edge?: LayerEdgeColor;
60
76
  }
61
77
  export interface RasterPixelLayer extends RasterLayerBase {
62
78
  type: 'pixel';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pixerate/editor",
3
- "version": "0.213.0",
3
+ "version": "0.215.0",
4
4
  "description": "UI-agnostic rich text and media editing core library",
5
5
  "author": "Pixerate",
6
6
  "license": "MIT",
@@ -98,13 +98,11 @@ drawing or editing either.
98
98
 
99
99
  Live per-layer effects (shadows, glows, bevel, overlays, strokes): see `references/layer-effects.md`.
100
100
 
101
- ### Paths
101
+ ### Paths and cutout edges
102
102
 
103
- 1. **Keep outlines as paths**: `make_work_path` turns the selection into the Work Path (the next
104
- one replaces it; `rename_path` saves it), `add_path` adds one from geometry.
105
- 2. **Use them**: `path_to_selection` / `add_vector_mask` with `pathId`, `fill_path`, `stroke_path`.
106
- 3. **Edit anchors** as the Pen and Direct Selection tools do: `get_path` → change anchors and handles
107
- → `set_path_geometry` (one undo step); shapes `set_shape_component`, vector masks `set_vector_mask_path`.
103
+ Keep outlines as paths (`make_work_path`, `add_path`) and edit their anchors: see
104
+ [references/paths.md](references/paths.md). Fix a cutout's fringe live with `set_edge_decontamination`,
105
+ `set_edge_despill` and `set_edge_ambient` (see `pixerate-image-selection-masking`).
108
106
 
109
107
  ### Painting
110
108
 
@@ -210,6 +208,7 @@ in the source frame at the document's bit depth, colour mode and profile. Read
210
208
  | `get_adjustments` | Read the current state: `values` by control id, `process` version (1 or 2), and `layers` bottom to top with id, kind, params, opacity, blend, enabled and mask. Call first, and to find layer ids. |
211
209
  | `list_controls` | Get every base control (id, label, section, min, max, step, default, `requiresProcess`), each layer kind's settable controls (plus `opacity`), the blend mode ids and the `layers.<layerId>.<controlId>` path format. Call once per session before writing. |
212
210
  | `get_selection` | Read the active selection: `empty`, `bounds` (natural pixels), `area` in pixels, `percent` of the image and a description. Check it after every select or modify step and before masking: a wand that covered 90% of the image is the wrong selection. |
211
+ | `inspect_mask_edge` | Measure an edge without looking: the selection (default) or a layer's `layer-mask` / `vector-mask` (`layerId`). Returns `haloScore`, `edgeAlignment`, `jaggedness`, `softFraction`, `holes`, `islands`, `worst` regions for `capture_view` and `issues` with fixes. Inspect, fix, inspect again (see `pixerate-image-selection-masking`). |
213
212
  | `list_channels` | Read the alpha channels (saved selections): id, name, bounds, percent, overlay and visibility, and whether Quick Mask mode is on. |
214
213
  | `select_subject` | Select › Subject. With a host segmentation model, `target` describes what to select ("the dog", "the sky") and the model's outlines are selected (`maxSegments` 1 for one). Without one, the subject that stands out most is found classically; `target` can't choose it (`method: "saliency"`, `note`). Combined by `mode`. Returns the selection, `found` (label, bounds) and `method`; nothing found leaves the selection unchanged. |
215
214
  | `list_layers` | Read the layer stack bottom to top as a tree: id, type (`pixel`, `adjustment`, `group`, `shape`, `annotation`, `smart`; smart objects add their `contents`, `smartFilters` and `filterMask`; shapes a `shape` summary of component ops and kinds and paint types, and `annotation` when migrated from one), name, document `bounds` of pixel layers, visibility, opacity, `fillOpacity`, blend, `clipped`, locks, a `mask` summary, an `effects` summary (master switch, scale, effect ids and kinds), pixel-layer `filters` (the Background's `develop` filter is the base adjustments), adjustment `kind` and `params`, group `children`, and which layer is `active`. Call it to understand a document with more than the Background before changing it; adjustment layer ids work with every adjustment-layer tool. |
@@ -292,6 +291,10 @@ in the source frame at the document's bit depth, colour mode and profile. Read
292
291
  | `set_layer_mask_properties` | Change any layer mask's `density`, `feather`, `enabled` or `linked` (false: the mask stays put when the layer moves or transforms) without touching its pixels. |
293
292
  | `apply_layer_mask` | Bake a pixel layer's mask into its alpha and remove it. Destructive. |
294
293
  | `set_mask_view` | Show a layer's mask to check it (`view` `gray` alone, `overlay` red tint over what it hides, `off`; `layerId`, default active). View state only; look with `capture_view` `includeOverlays: true`, then `off`. Returns `{view, layerId}`. |
294
+ | `get_edge_color` | A layer's edge colour: `decontaminate`, `despill`, `ambient` (percent) and `ambientSource` (`auto` or `#rrggbb`). |
295
+ | `set_edge_decontamination` | Unmix the old background from a cutout's soft mask edge at composite time (`amount` %; 0 off; nothing baked). Needs a pixel layer whose mask has a soft band. Check with `inspect_mask_edge` `haloScore`. Returns the settings. |
296
+ | `set_edge_despill` | Take the old background's hue out of a soft edge (`amount` %), luminance kept; never changes fully covered pixels. A heuristic: bounced light stays. Same mask needs. Returns the settings. |
297
+ | `set_edge_ambient` | Tint a soft edge with what is behind the layer, live (`source` `auto`) or a fixed `#rrggbb` (`amount` %). For a subject moved onto a new background. Returns the settings. |
295
298
  | `remove_layer_mask` | Delete a mask without applying it; disable it instead to keep it. |
296
299
  | `layer_via_copy` | Copy the selected pixels of a pixel layer (default the active one) to a new layer above it; `cut: true` removes them from the source. Needs a selection. Returns the new layer. |
297
300
  | `rasterize_layer` | Turn a shape layer into a pixel layer showing the same pixels (same id, mask, effects, opacity, blend; the paths are gone), an annotation layer into pixels (browser only), a smart object into a pixel layer (as `rasterize_smart_object`), or bake a pixel layer's develop / blur filters into its pixels. Do it before painting over a shape or annotation, or when the user wants the filters fixed. Destructive. |
@@ -0,0 +1,12 @@
1
+ # Paths
2
+
3
+ Document paths are vector outlines kept with the document but on no layer (Photoshop's Paths
4
+ panel). The Work Path is the scratch path; saved paths stay until deleted.
5
+
6
+ 1. **Keep outlines as paths**: `make_work_path` turns the selection into the Work Path (the next
7
+ one replaces it; `rename_path` saves it), `add_path` adds one from geometry.
8
+ 2. **Use them**: `path_to_selection` / `add_vector_mask` with `pathId`, `fill_path`, `stroke_path`.
9
+ 3. **Edit anchors** as the Pen and Direct Selection tools do: `get_path` → change anchors and
10
+ handles → `set_path_geometry` (one undo step); shapes `set_shape_component`, vector masks
11
+ `set_vector_mask_path`.
12
+ 4. **Read first**: `list_paths` for ids, names and bounds; `get_path` for the `components` to edit.
@@ -44,10 +44,10 @@ This skill is the method. `pixerate-image-editor` has the full tool reference.
44
44
  what leaked, and `intersect` to limit it to a region (for example `select_rect` around the
45
45
  subject).
46
46
  **Check:** `bounds` hug the subject. A bounds as large as the image means a leak.
47
- 3. **Look at the edge.** Use `capture_view` with `region: "selection"` and `includeOverlays: true`,
48
- or `set_selection_display` `quickMask`, to see soft edges as a tint.
49
- **Check:** no holes in the subject, no islands in the background, and edges on the subject's
50
- outline.
47
+ 3. **Measure the edge, then look.** `inspect_mask_edge` scores it: `haloScore` ≥ 0.35 is old
48
+ background inside the edge, `edgeAlignment` < 0.5 is off the image's edges, `jaggedness` ≥ 15
49
+ zigzags; it counts `holes` and `islands`, `issues` names fixes, `worst` gives `capture_view` rects.
50
+ **Check:** `issues` is empty, or each one is intended (a deliberately soft edge or a second piece).
51
51
  4. **Clean it up.**
52
52
  - `modify_selection` `smooth` (2–4 px) removes wand speckle.
53
53
  - `grow_selection` (tolerance 10–30) picks up the shades a wand click missed;
@@ -89,7 +89,8 @@ This skill is the method. `pixerate-image-editor` has the full tool reference.
89
89
  writes the selection, a channel or a layer mask as a greyscale PNG; a matte that comes
90
90
  back goes into a channel with `load_channel_from_image` (or straight to the selection with
91
91
  `load_selection_from_image`).
92
- 7. **Verify.** `render_preview` at 1024 px or more, and `capture_view` on the edge at 2–8×.
92
+ 7. **Verify.** `inspect_mask_edge` again (`target: "layer-mask"` and `layerId` for a mask),
93
+ `render_preview` at 1024 px or more, and `capture_view` on `worst` regions at 2–8×.
93
94
  **Check:** no fringe of the old background colour, no stair-steps, no visible line where an
94
95
  adjustment ends. To judge a layer mask itself, `set_mask_view` `gray` (or `overlay`) and
95
96
  `capture_view` with `includeOverlays: true`; holes and stray grey show plainly there. Set it
@@ -120,12 +121,11 @@ This skill is the method. `pixerate-image-editor` has the full tool reference.
120
121
 
121
122
  ## Recipes
122
123
 
123
- - **Cut out a subject onto a new background:** select (table), then `refine_selection` with
124
- `output: "new-layer-with-mask"` (revisable) and, for hair or fur, `decontaminate` 50–100 so
125
- the old background's colour leaves the soft edge. Add the new background with
126
- `add_pixel_layer` and move it under the cutout (`move_layer`). `render_preview` and look for a
127
- halo; if there is one, raise `decontaminate`, or load the mask as a selection, `contract`
128
- 1 px, and output again.
124
+ - **Cut out a subject onto a new background:** select (table), `refine_selection` with `output:
125
+ "new-layer-with-mask"`, put the new background under it (`add_pixel_layer`, `move_layer`). Fix
126
+ the fringe live on the masked layer: `set_edge_decontamination` 80–100, `set_edge_despill` 50–100
127
+ for a coloured backdrop, `set_edge_ambient` 20–50 to take on the new scene's colour. Re-run
128
+ `inspect_mask_edge`; if `haloScore` stays high, `contract` the mask 1 px.
129
129
  - **Replace the sky:** `select_sky` (or `magic_wand` / `select_color_range` `preset: "blues"`
130
130
  if it finds none), `add` missed patches, `refine_selection` radius 8–16 along the horizon and trees, then
131
131
  `add_layer_mask` on the new sky layer. Match it with a clipped curves layer (`clipped: true`).
@@ -184,8 +184,8 @@ This skill is the method. `pixerate-image-editor` has the full tool reference.
184
184
  background, and drop `snapToEdges` where the edge is too faint.
185
185
  - **Over-feathering hard objects:** a 10 px feather on a product looks like a glow. Keep hard
186
186
  edges at 0–2 px and refine soft ones instead.
187
- - **Halo:** the old background shows as a light or dark fringe. `decontaminate` on a
188
- new-layer output for soft edges; for hard ones `contract` 1–2 px or
187
+ - **Halo:** the old background shows as a light or dark fringe. `set_edge_decontamination` on the
188
+ masked layer (live) for soft edges; for hard ones `contract` 1–2 px or
189
189
  `shiftEdge` negative before masking.
190
190
  - **Baking too early:** `apply_layer_mask`, `merge_down` and `layer_via_copy` with `cut: true`
191
191
  are hard to revise. Keep masks until the user is happy.
@@ -220,8 +220,7 @@ This skill is the method. `pixerate-image-editor` has the full tool reference.
220
220
  - `select_layer_transparency`: a layer's own pixels
221
221
  - `grow_selection`, `select_similar`: add similar colour, connected or anywhere
222
222
  - `reselect`: undo a deselect
223
- - `save_selection`, `load_selection_from_channel`, `list_channels`: keep selections as alpha channels
224
- - `set_channel_properties`, `duplicate_channel`, `delete_channel`: manage channels
223
+ - `save_selection`, `load_selection_from_channel`, `list_channels`, `set_channel_properties`, `duplicate_channel`, `delete_channel`: keep and manage selections as alpha channels
225
224
  - `export_mask_image`: a selection, channel or layer mask as a greyscale PNG
226
225
  - `load_channel_from_image`: a mask image into a new channel
227
226
  - `set_quick_mask`: paint the selection
@@ -240,8 +239,9 @@ This skill is the method. `pixerate-image-editor` has the full tool reference.
240
239
  - `modify_selection`: expand, contract, feather, border, smooth
241
240
  - `refine_selection`: snap the edge to the image
242
241
  - `transform_selection`: move or scale the outline only
243
- - `capture_view`: inspect the edge at pixel level
244
- - `render_preview`: check the result
242
+ - `inspect_mask_edge`: measured halo, alignment, jaggedness, softness, holes and islands of an edge
243
+ - `set_edge_decontamination`, `set_edge_despill`, `set_edge_ambient`, `get_edge_color`: live edge colour on a masked cutout
244
+ - `capture_view`, `render_preview`: look at the edge at pixel level; check the result
245
245
  - `apply_selection_as_mask`: a masked adjustment layer in one step
246
246
  - `add_layer_mask`, `set_layer_mask_properties`, `apply_layer_mask`, `remove_layer_mask`: layer masks
247
247
  - `set_smart_filter_mask`: limit smart filters