pixel-data-js 0.16.0 → 0.17.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 (33) hide show
  1. package/dist/index.dev.cjs +1648 -908
  2. package/dist/index.dev.cjs.map +1 -1
  3. package/dist/index.dev.js +1629 -906
  4. package/dist/index.dev.js.map +1 -1
  5. package/dist/index.prod.cjs +1648 -908
  6. package/dist/index.prod.cjs.map +1 -1
  7. package/dist/index.prod.d.ts +287 -67
  8. package/dist/index.prod.js +1629 -906
  9. package/dist/index.prod.js.map +1 -1
  10. package/package.json +1 -1
  11. package/src/BlendModes/BlendModeRegistry.ts +34 -50
  12. package/src/BlendModes/blend-modes-perfect.ts +313 -136
  13. package/src/BlendModes/blend-modes.ts +6 -0
  14. package/src/History/HistoryManager.ts +83 -0
  15. package/src/History/PixelAccumulator.ts +191 -0
  16. package/src/History/PixelEngineConfig.ts +18 -0
  17. package/src/History/PixelMutator/mutatorApplyMask.ts +20 -0
  18. package/src/History/PixelMutator/mutatorBlendColor.ts +22 -0
  19. package/src/History/PixelMutator/mutatorBlendPixel.ts +37 -0
  20. package/src/History/PixelMutator/mutatorBlendPixelData.ts +24 -0
  21. package/src/History/PixelMutator/mutatorFillPixelData.ts +21 -0
  22. package/src/History/PixelMutator/mutatorInvert.ts +18 -0
  23. package/src/History/PixelMutator.ts +18 -0
  24. package/src/History/PixelPatchTiles.ts +52 -0
  25. package/src/History/PixelWriter.ts +79 -0
  26. package/src/ImageData/{writeImageDataPixels.ts → writeImageDataBuffer.ts} +3 -3
  27. package/src/PixelData/applyCircleBrushToPixelData.ts +69 -0
  28. package/src/PixelData/applyMaskToPixelData.ts +1 -1
  29. package/src/PixelData/applyRectBrushToPixelData.ts +102 -0
  30. package/src/PixelData/invertPixelData.ts +74 -7
  31. package/src/PixelData/writePixelDataBuffer.ts +65 -0
  32. package/src/_types.ts +31 -11
  33. package/src/index.ts +18 -1
@@ -67,7 +67,7 @@ type AnyMask = BinaryMask | AlphaMask;
67
67
  * Configuration for pixel manipulation operations.
68
68
  * Designed to be used by spreading a Rect object ({x, y, w, h}) directly.
69
69
  */
70
- interface PixelOptions {
70
+ interface PixelRectOptions {
71
71
  /**
72
72
  * The starting X coordinate in the destination buffer.
73
73
  * @default 0
@@ -88,11 +88,8 @@ interface PixelOptions {
88
88
  * @default Source height.
89
89
  */
90
90
  h?: number;
91
- /**
92
- * Overall layer opacity 0-255.
93
- * @default 255
94
- */
95
- alpha?: number;
91
+ }
92
+ interface PixelMaskRectOptions {
96
93
  /**
97
94
  * Mask width.
98
95
  * @default value of `w`
@@ -108,17 +105,34 @@ interface PixelOptions {
108
105
  * @default 0
109
106
  */
110
107
  my?: number;
108
+ }
109
+ interface PixelMaskInvertOptions {
110
+ /**
111
+ * If true the inverse of the mask will be applied
112
+ * @default false
113
+ */
114
+ invertMask?: boolean;
115
+ }
116
+ /**
117
+ * Configuration for pixel manipulation operations.
118
+ * Designed to be used by spreading a Rect object ({x, y, w, h}) directly.
119
+ */
120
+ interface PixelOptions extends PixelRectOptions, PixelMaskRectOptions, PixelMaskInvertOptions {
121
+ /**
122
+ * Overall layer opacity 0-255.
123
+ * @default 255
124
+ */
125
+ alpha?: number;
111
126
  /** An optional mask to restrict where pixels are written. */
112
127
  mask?: AnyMask | null;
113
128
  /** The interpretation logic for the provided mask.
114
129
  * @default {@link MaskType.ALPHA}
115
130
  */
116
131
  maskType?: MaskType;
117
- /**
118
- * If true the inverse of the mask will be applied
119
- * @default false
120
- */
121
- invertMask?: boolean;
132
+ }
133
+ interface PixelMutateOptions extends PixelRectOptions, PixelMaskRectOptions, PixelMaskInvertOptions {
134
+ /** An optional mask to restrict where pixels are mutated. */
135
+ mask?: BinaryMask | null;
122
136
  }
123
137
  /**
124
138
  * Configuration for blitting (copying/blending) one image into another.
@@ -262,45 +276,6 @@ type FloodFillResult = {
262
276
  */
263
277
  declare function floodFillSelection(img: ImageDataLike | PixelData, startX: number, startY: number, { contiguous, tolerance, bounds, }?: FloodFillImageDataOptions): FloodFillResult | null;
264
278
 
265
- type BlendModeRegistry = ReturnType<typeof makeBlendModeRegistry>;
266
- declare function makeBlendModeRegistry<BlendModes extends Record<string, number>, Name extends keyof BlendModes = keyof BlendModes, Index extends BlendModes[Name] = BlendModes[Name]>(blendModes: BlendModes, initialEntries: Record<Index, BlendColor32>): {
267
- modes: BlendColor32[];
268
- byName: Record<Name, BlendColor32>;
269
- toIndex: Map<BlendColor32, Index>;
270
- fromIndex: Map<Index, BlendColor32>;
271
- add: (name: Name, index: Index, blendFn: BlendColor32) => void;
272
- indexType: Index;
273
- nameType: Name;
274
- };
275
- /**
276
- * @internal
277
- */
278
- interface BaseBlendModeRegistry {
279
- overwrite: BlendColor32;
280
- sourceOver: BlendColor32;
281
- darken: BlendColor32;
282
- multiply: BlendColor32;
283
- colorBurn: BlendColor32;
284
- linearBurn: BlendColor32;
285
- darkerColor: BlendColor32;
286
- lighten: BlendColor32;
287
- screen: BlendColor32;
288
- colorDodge: BlendColor32;
289
- linearDodge: BlendColor32;
290
- lighterColor: BlendColor32;
291
- overlay: BlendColor32;
292
- softLight: BlendColor32;
293
- hardLight: BlendColor32;
294
- vividLight: BlendColor32;
295
- linearLight: BlendColor32;
296
- pinLight: BlendColor32;
297
- hardMix: BlendColor32;
298
- difference: BlendColor32;
299
- exclusion: BlendColor32;
300
- subtract: BlendColor32;
301
- divide: BlendColor32;
302
- }
303
-
304
279
  declare const BaseBlendMode: {
305
280
  readonly overwrite: 0;
306
281
  readonly sourceOver: 1;
@@ -326,8 +301,24 @@ declare const BaseBlendMode: {
326
301
  readonly subtract: 21;
327
302
  readonly divide: 22;
328
303
  };
304
+ interface RequiredBlendModes {
305
+ overwrite: 0;
306
+ }
307
+ type BaseBlendModes = RequiredBlendModes & Record<string, number>;
329
308
  declare const overwriteBase: BlendColor32;
330
309
 
310
+ type BlendModeRegistry<BlendModes extends BaseBlendModes = BaseBlendModes, Name extends keyof BlendModes = keyof BlendModes, Index extends BlendModes[Name] = BlendModes[Name]> = ReturnType<typeof makeBlendModeRegistry<BlendModes, Name, Index>>;
311
+ declare function makeBlendModeRegistry<BlendModes extends BaseBlendModes, Name extends keyof BlendModes = keyof BlendModes, Index extends BlendModes[Name] = BlendModes[Name]>(blendModes: BlendModes, initialEntries: Record<Index, BlendColor32>): {
312
+ nameToBlend: { [K in keyof BlendModes]: BlendColor32; };
313
+ nameToIndex: Record<Name, Index>;
314
+ blendToIndex: Map<BlendColor32, Index>;
315
+ blendToName: Map<BlendColor32, Name>;
316
+ indexToBlend: BlendColor32[];
317
+ indexToName: Name[];
318
+ indexType: Index;
319
+ nameType: Name;
320
+ };
321
+
331
322
  declare const overwriteFast: BlendColor32;
332
323
  declare const sourceOverFast: BlendColor32;
333
324
  declare const darkenFast: BlendColor32;
@@ -376,11 +367,36 @@ declare const subtractFast: BlendColor32;
376
367
  declare const divideFast: BlendColor32;
377
368
  declare const BASE_FAST_BLEND_MODE_FUNCTIONS: Record<number, BlendColor32>;
378
369
  declare function makeFastBlendModeRegistry(): {
379
- modes: BlendColor32[];
380
- byName: Record<"overwrite" | "sourceOver" | "darken" | "multiply" | "colorBurn" | "linearBurn" | "darkerColor" | "lighten" | "screen" | "colorDodge" | "linearDodge" | "lighterColor" | "overlay" | "softLight" | "hardLight" | "vividLight" | "linearLight" | "pinLight" | "hardMix" | "difference" | "exclusion" | "subtract" | "divide", BlendColor32>;
381
- toIndex: Map<BlendColor32, 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22>;
382
- fromIndex: Map<0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22, BlendColor32>;
383
- add: (name: "overwrite" | "sourceOver" | "darken" | "multiply" | "colorBurn" | "linearBurn" | "darkerColor" | "lighten" | "screen" | "colorDodge" | "linearDodge" | "lighterColor" | "overlay" | "softLight" | "hardLight" | "vividLight" | "linearLight" | "pinLight" | "hardMix" | "difference" | "exclusion" | "subtract" | "divide", index: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22, blendFn: BlendColor32) => void;
370
+ nameToBlend: {
371
+ readonly overwrite: BlendColor32;
372
+ readonly sourceOver: BlendColor32;
373
+ readonly darken: BlendColor32;
374
+ readonly multiply: BlendColor32;
375
+ readonly colorBurn: BlendColor32;
376
+ readonly linearBurn: BlendColor32;
377
+ readonly darkerColor: BlendColor32;
378
+ readonly lighten: BlendColor32;
379
+ readonly screen: BlendColor32;
380
+ readonly colorDodge: BlendColor32;
381
+ readonly linearDodge: BlendColor32;
382
+ readonly lighterColor: BlendColor32;
383
+ readonly overlay: BlendColor32;
384
+ readonly softLight: BlendColor32;
385
+ readonly hardLight: BlendColor32;
386
+ readonly vividLight: BlendColor32;
387
+ readonly linearLight: BlendColor32;
388
+ readonly pinLight: BlendColor32;
389
+ readonly hardMix: BlendColor32;
390
+ readonly difference: BlendColor32;
391
+ readonly exclusion: BlendColor32;
392
+ readonly subtract: BlendColor32;
393
+ readonly divide: BlendColor32;
394
+ };
395
+ nameToIndex: Record<"overwrite" | "sourceOver" | "darken" | "multiply" | "colorBurn" | "linearBurn" | "darkerColor" | "lighten" | "screen" | "colorDodge" | "linearDodge" | "lighterColor" | "overlay" | "softLight" | "hardLight" | "vividLight" | "linearLight" | "pinLight" | "hardMix" | "difference" | "exclusion" | "subtract" | "divide", 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22>;
396
+ blendToIndex: Map<BlendColor32, 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22>;
397
+ blendToName: Map<BlendColor32, "overwrite" | "sourceOver" | "darken" | "multiply" | "colorBurn" | "linearBurn" | "darkerColor" | "lighten" | "screen" | "colorDodge" | "linearDodge" | "lighterColor" | "overlay" | "softLight" | "hardLight" | "vividLight" | "linearLight" | "pinLight" | "hardMix" | "difference" | "exclusion" | "subtract" | "divide">;
398
+ indexToBlend: BlendColor32[];
399
+ indexToName: ("overwrite" | "sourceOver" | "darken" | "multiply" | "colorBurn" | "linearBurn" | "darkerColor" | "lighten" | "screen" | "colorDodge" | "linearDodge" | "lighterColor" | "overlay" | "softLight" | "hardLight" | "vividLight" | "linearLight" | "pinLight" | "hardMix" | "difference" | "exclusion" | "subtract" | "divide")[];
384
400
  indexType: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22;
385
401
  nameType: "overwrite" | "sourceOver" | "darken" | "multiply" | "colorBurn" | "linearBurn" | "darkerColor" | "lighten" | "screen" | "colorDodge" | "linearDodge" | "lighterColor" | "overlay" | "softLight" | "hardLight" | "vividLight" | "linearLight" | "pinLight" | "hardMix" | "difference" | "exclusion" | "subtract" | "divide";
386
402
  };
@@ -431,15 +447,38 @@ declare const exclusionPerfect: BlendColor32;
431
447
  declare const subtractPerfect: BlendColor32;
432
448
  /** sr === 0 ? 255 : Math.min(255, (dr << 8) / sr) */
433
449
  declare const dividePerfect: BlendColor32;
434
- interface PerfectBlendModes extends BaseBlendModeRegistry {
435
- }
436
450
  declare const BASE_PERFECT_BLEND_MODE_FUNCTIONS: Record<number, BlendColor32>;
437
451
  declare function makePerfectBlendModeRegistry(): {
438
- modes: BlendColor32[];
439
- byName: Record<"overwrite" | "sourceOver" | "darken" | "multiply" | "colorBurn" | "linearBurn" | "darkerColor" | "lighten" | "screen" | "colorDodge" | "linearDodge" | "lighterColor" | "overlay" | "softLight" | "hardLight" | "vividLight" | "linearLight" | "pinLight" | "hardMix" | "difference" | "exclusion" | "subtract" | "divide", BlendColor32>;
440
- toIndex: Map<BlendColor32, 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22>;
441
- fromIndex: Map<0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22, BlendColor32>;
442
- add: (name: "overwrite" | "sourceOver" | "darken" | "multiply" | "colorBurn" | "linearBurn" | "darkerColor" | "lighten" | "screen" | "colorDodge" | "linearDodge" | "lighterColor" | "overlay" | "softLight" | "hardLight" | "vividLight" | "linearLight" | "pinLight" | "hardMix" | "difference" | "exclusion" | "subtract" | "divide", index: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22, blendFn: BlendColor32) => void;
452
+ nameToBlend: {
453
+ readonly overwrite: BlendColor32;
454
+ readonly sourceOver: BlendColor32;
455
+ readonly darken: BlendColor32;
456
+ readonly multiply: BlendColor32;
457
+ readonly colorBurn: BlendColor32;
458
+ readonly linearBurn: BlendColor32;
459
+ readonly darkerColor: BlendColor32;
460
+ readonly lighten: BlendColor32;
461
+ readonly screen: BlendColor32;
462
+ readonly colorDodge: BlendColor32;
463
+ readonly linearDodge: BlendColor32;
464
+ readonly lighterColor: BlendColor32;
465
+ readonly overlay: BlendColor32;
466
+ readonly softLight: BlendColor32;
467
+ readonly hardLight: BlendColor32;
468
+ readonly vividLight: BlendColor32;
469
+ readonly linearLight: BlendColor32;
470
+ readonly pinLight: BlendColor32;
471
+ readonly hardMix: BlendColor32;
472
+ readonly difference: BlendColor32;
473
+ readonly exclusion: BlendColor32;
474
+ readonly subtract: BlendColor32;
475
+ readonly divide: BlendColor32;
476
+ };
477
+ nameToIndex: Record<"overwrite" | "sourceOver" | "darken" | "multiply" | "colorBurn" | "linearBurn" | "darkerColor" | "lighten" | "screen" | "colorDodge" | "linearDodge" | "lighterColor" | "overlay" | "softLight" | "hardLight" | "vividLight" | "linearLight" | "pinLight" | "hardMix" | "difference" | "exclusion" | "subtract" | "divide", 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22>;
478
+ blendToIndex: Map<BlendColor32, 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22>;
479
+ blendToName: Map<BlendColor32, "overwrite" | "sourceOver" | "darken" | "multiply" | "colorBurn" | "linearBurn" | "darkerColor" | "lighten" | "screen" | "colorDodge" | "linearDodge" | "lighterColor" | "overlay" | "softLight" | "hardLight" | "vividLight" | "linearLight" | "pinLight" | "hardMix" | "difference" | "exclusion" | "subtract" | "divide">;
480
+ indexToBlend: BlendColor32[];
481
+ indexToName: ("overwrite" | "sourceOver" | "darken" | "multiply" | "colorBurn" | "linearBurn" | "darkerColor" | "lighten" | "screen" | "colorDodge" | "linearDodge" | "lighterColor" | "overlay" | "softLight" | "hardLight" | "vividLight" | "linearLight" | "pinLight" | "hardMix" | "difference" | "exclusion" | "subtract" | "divide")[];
443
482
  indexType: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22;
444
483
  nameType: "overwrite" | "sourceOver" | "darken" | "multiply" | "colorBurn" | "linearBurn" | "darkerColor" | "lighten" | "screen" | "colorDodge" | "linearDodge" | "lighterColor" | "overlay" | "softLight" | "hardLight" | "vividLight" | "linearLight" | "pinLight" | "hardMix" | "difference" | "exclusion" | "subtract" | "divide";
445
484
  };
@@ -522,6 +561,144 @@ declare function writeImageDataToClipboard(imageData: ImageData): Promise<void>;
522
561
  */
523
562
  declare function writeImgBlobToClipboard(blob: Blob): Promise<void>;
524
563
 
564
+ declare class PixelEngineConfig {
565
+ readonly tileSize: number;
566
+ readonly tileShift: number;
567
+ readonly tileMask: number;
568
+ readonly tileArea: number;
569
+ constructor(tileSize?: number);
570
+ }
571
+
572
+ type PixelPatchTiles = {
573
+ beforeTiles: PixelTile[];
574
+ afterTiles: PixelTile[];
575
+ };
576
+ declare class PixelTile {
577
+ id: number;
578
+ tx: number;
579
+ ty: number;
580
+ data32: Uint32Array;
581
+ constructor(id: number, tx: number, ty: number, tileArea: number);
582
+ }
583
+ declare function applyPatchTiles(target: PixelData, tiles: PixelTile[], tileSize?: number): void;
584
+
585
+ declare class PixelAccumulator {
586
+ target: PixelData;
587
+ readonly config: PixelEngineConfig;
588
+ lookup: (PixelTile | undefined)[];
589
+ beforeTiles: PixelTile[];
590
+ pool: PixelTile[];
591
+ constructor(target: PixelData, config: PixelEngineConfig);
592
+ getTile(id: number, tx: number, ty: number): PixelTile;
593
+ recyclePatch(patch: PixelPatchTiles): void;
594
+ /**
595
+ * @param x pixel x coordinate
596
+ * @param y pixel y coordinate
597
+ */
598
+ storeTileBeforeState(x: number, y: number): void;
599
+ /**
600
+ *
601
+ * @param x pixel x coordinate
602
+ * @param y pixel y coordinate
603
+ * @param w pixel width
604
+ * @param h pixel height
605
+ */
606
+ storeRegionBeforeState(x: number, y: number, w: number, h: number): void;
607
+ extractState(tile: PixelTile): void;
608
+ extractAfterTiles(): PixelTile[];
609
+ reset(): void;
610
+ }
611
+
612
+ interface HistoryAction {
613
+ undo: () => void;
614
+ redo: () => void;
615
+ dispose?: () => void;
616
+ }
617
+ declare class HistoryManager {
618
+ maxSteps: number;
619
+ undoStack: HistoryAction[];
620
+ redoStack: HistoryAction[];
621
+ listeners: Set<() => void>;
622
+ constructor(maxSteps?: number);
623
+ get canUndo(): boolean;
624
+ get canRedo(): boolean;
625
+ subscribe(fn: () => void): () => boolean;
626
+ notify(): void;
627
+ commit(action: HistoryAction): void;
628
+ undo(): void;
629
+ redo(): void;
630
+ clearRedoStack(): void;
631
+ }
632
+
633
+ interface PixelWriterOptions {
634
+ maxHistorySteps?: number;
635
+ tileSize?: number;
636
+ historyManager?: HistoryManager;
637
+ }
638
+ /**
639
+ * @example
640
+ * const targ = new PixelData(new ImageData(10, 10))
641
+ * const writer = new PixelWriter(targ, (writer) => {
642
+ * return {
643
+ * ...mutatorApplyMask(writer),
644
+ * ...mutatorBlendPixelData(writer),
645
+ * ...mutatorBlendColor(writer),
646
+ * ...mutatorBlendPixel(writer),
647
+ * ...mutatorFill(writer),
648
+ * }
649
+ * })
650
+ *
651
+ * // to import all mutator functions
652
+ * const writer = new PixelWriter(targ, makeFullPixelMutator)
653
+ *
654
+ * writer.withHistory((mutator) => {
655
+ * mutator.applyMask()
656
+ * mutator.blendPixelData()
657
+ * })
658
+ */
659
+ declare class PixelWriter<M> {
660
+ target: PixelData;
661
+ historyManager: HistoryManager;
662
+ accumulator: PixelAccumulator;
663
+ protected config: PixelEngineConfig;
664
+ private mutator;
665
+ constructor(target: PixelData, mutatorFactory: (writer: PixelWriter<any>) => M, { tileSize, maxHistorySteps, historyManager, }?: PixelWriterOptions);
666
+ withHistory(cb: (mutator: M) => void): void;
667
+ }
668
+
669
+ declare function makeFullPixelMutator(writer: PixelWriter<any>): {
670
+ invert(opts?: PixelMutateOptions): void;
671
+ fill(color: Color32, rect?: Partial<Rect>): void;
672
+ blendPixel(x: number, y: number, color: Color32, alpha?: number, blendFn?: BlendColor32): void;
673
+ blendColor(color: Color32, opts?: ColorBlendOptions): void;
674
+ blendPixelData(src: PixelData, opts: PixelBlendOptions): void;
675
+ applyMask: (mask: AnyMask, opts?: ApplyMaskOptions) => void;
676
+ };
677
+
678
+ declare function mutatorApplyMask(writer: PixelWriter<any>): {
679
+ applyMask: (mask: AnyMask, opts?: ApplyMaskOptions) => void;
680
+ };
681
+
682
+ declare function mutatorBlendColor(writer: PixelWriter<any>): {
683
+ blendColor(color: Color32, opts?: ColorBlendOptions): void;
684
+ };
685
+
686
+ declare function mutatorBlendPixel(writer: PixelWriter<any>): {
687
+ blendPixel(x: number, y: number, color: Color32, alpha?: number, blendFn?: BlendColor32): void;
688
+ };
689
+
690
+ declare function mutatorBlendPixelData(writer: PixelWriter<any>): {
691
+ blendPixelData(src: PixelData, opts: PixelBlendOptions): void;
692
+ };
693
+
694
+ declare function mutatorFill(writer: PixelWriter<any>): {
695
+ fill(color: Color32, rect?: Partial<Rect>): void;
696
+ };
697
+
698
+ declare function mutatorInvert(writer: PixelWriter<any>): {
699
+ invert(opts?: PixelMutateOptions): void;
700
+ };
701
+
525
702
  type ReusableImageData = ReturnType<typeof makeReusableImageData>;
526
703
  /**
527
704
  * Creates a factory function that manages a single, reusable ImageData instance.
@@ -712,7 +889,7 @@ declare function writeImageData(target: ImageData, source: ImageData, x: number,
712
889
  * @param data - The source pixel data (RGBA).
713
890
  * @param rect - A {@link Rect} object defining the destination region.
714
891
  */
715
- declare function writeImageDataPixels(imageData: ImageData, data: Uint8ClampedArray, rect: Rect): void;
892
+ declare function writeImageDataBuffer(imageData: ImageData, data: Uint8ClampedArray, rect: Rect): void;
716
893
  /**
717
894
  * @param imageData - The target {@link ImageData} to write into.
718
895
  * @param data - The source pixel data (RGBA). Must match the width/height.
@@ -721,7 +898,7 @@ declare function writeImageDataPixels(imageData: ImageData, data: Uint8ClampedAr
721
898
  * @param w - The width of the region to write.
722
899
  * @param h - The height of the region to write.
723
900
  */
724
- declare function writeImageDataPixels(imageData: ImageData, data: Uint8ClampedArray, x: number, y: number, w: number, h: number): void;
901
+ declare function writeImageDataBuffer(imageData: ImageData, data: Uint8ClampedArray, x: number, y: number, w: number, h: number): void;
725
902
 
726
903
  /**
727
904
  * Represents an image using a palette-based indexing system.
@@ -934,11 +1111,45 @@ declare function invertAlphaMask(dst: AlphaMask): void;
934
1111
  */
935
1112
  declare function mergeMasks(dst: AlphaMask, dstWidth: number, src: AnyMask, opts: ApplyMaskOptions): void;
936
1113
 
1114
+ /**
1115
+ * Applies a circular brush to pixel data, blending a color with optional falloff.
1116
+ *
1117
+ * @param target The PixelData to modify.
1118
+ * @param color The brush color.
1119
+ * @param centerX The center x-coordinate of the brush.
1120
+ * @param centerY The center y-coordinate of the brush.
1121
+ * @param brushSize The diameter of the brush.
1122
+ * @param alpha The overall opacity of the brush (0-255).
1123
+ * @default 255
1124
+ * @param fallOff A function that returns an alpha multiplier (0-1) based on the normalized distance (0-1) from the circle's center.
1125
+ * @param blendFn
1126
+ * @default sourceOverPerfect
1127
+ */
1128
+ declare function applyCircleBrushToPixelData(target: PixelData, color: Color32, centerX: number, centerY: number, brushSize: number, alpha?: number, fallOff?: (dist: number) => number, blendFn?: BlendColor32): void;
1129
+
937
1130
  /**
938
1131
  * Directly applies a mask to a region of PixelData,
939
1132
  * modifying the destination's alpha channel in-place.
940
1133
  */
941
- declare function applyMaskToPixelData(dst: PixelData, mask: AnyMask, opts: ApplyMaskOptions): void;
1134
+ declare function applyMaskToPixelData(dst: PixelData, mask: AnyMask, opts?: ApplyMaskOptions): void;
1135
+
1136
+ /**
1137
+ * Applies a rectangular brush to pixel data, blending a color with optional falloff.
1138
+ *
1139
+ * @param target The PixelData to modify.
1140
+ * @param color The brush color.
1141
+ * @param centerX The center x-coordinate of the brush.
1142
+ * @param centerY The center y-coordinate of the brush.
1143
+ * @param brushWidth
1144
+ * @param brushHeight
1145
+ * @param alpha The overall opacity of the brush (0-255).
1146
+ * @default 255
1147
+ * @param fallOff A function that returns an alpha multiplier (0-1) based on the normalized distance (0-1) from the circle's center.
1148
+ * @param blendFn
1149
+ * @default sourceOverPerfect
1150
+ */
1151
+ declare function applyRectBrushToPixelData(target: PixelData, color: Color32, centerX: number, centerY: number, brushWidth: number, brushHeight: number, alpha?: number, fallOff?: (dist: number) => number, blendFn?: BlendColor32): void;
1152
+ declare function getRectBrushBounds(centerX: number, centerY: number, brushWidth: number, brushHeight: number, targetWidth?: number, targetHeight?: number): Rect;
942
1153
 
943
1154
  /**
944
1155
  * Fills a rectangle in the destination PixelData with a single color,
@@ -1001,7 +1212,7 @@ declare function fillPixelData(dst: PixelData, color: Color32, rect?: Partial<Re
1001
1212
  */
1002
1213
  declare function fillPixelData(dst: PixelData, color: Color32, x: number, y: number, w: number, h: number): void;
1003
1214
 
1004
- declare function invertPixelData(pixelData: PixelData): PixelData;
1215
+ declare function invertPixelData(pixelData: PixelData, opts?: PixelMutateOptions): void;
1005
1216
 
1006
1217
  /**
1007
1218
  * Extracts the alpha channel from PixelData into a single-channel mask.
@@ -1030,6 +1241,15 @@ declare function resamplePixelData(pixelData: PixelData, factor: number): PixelD
1030
1241
  */
1031
1242
  declare function rotatePixelData(pixelData: PixelData): void;
1032
1243
 
1244
+ /**
1245
+ * Copies a pixel buffer into a specific region of a {@link PixelData} object.
1246
+ *
1247
+ * This function performs a direct memory copy from a {@link Uint32Array}
1248
+ * into the target {@link PixelData} buffer.
1249
+ */
1250
+ declare function writePixelDataBuffer(target: PixelData, data: Uint32Array, rect: Rect): void;
1251
+ declare function writePixelDataBuffer(target: PixelData, data: Uint32Array, x: number, y: number, w: number, h: number): void;
1252
+
1033
1253
  /**
1034
1254
  * Intersects a target rectangle with a boundary, trimming dimensions and masks in-place.
1035
1255
  * This utility calculates the axis-aligned intersection between the `target` and `bounds`.
@@ -1046,4 +1266,4 @@ declare function rotatePixelData(pixelData: PixelData): void;
1046
1266
  */
1047
1267
  declare function trimRectBounds<T extends Rect | SelectionRect>(target: T, bounds: Rect): void;
1048
1268
 
1049
- export { type AlphaMask, type AnyMask, type ApplyMaskOptions, BASE_FAST_BLEND_MODE_FUNCTIONS, BASE_PERFECT_BLEND_MODE_FUNCTIONS, type Base64EncodedUInt8Array, BaseBlendMode, type BaseBlendModeRegistry, type BinaryMask, type BlendColor32, type BlendModeRegistry, type Color32, type ColorBlendOptions, type FloodFillImageDataOptions, type FloodFillResult, type ImageDataLike, IndexedImage, MaskType, type PerfectBlendModes, type PixelBlendOptions, type PixelCanvas, PixelData, type PixelOptions, type Point, type RGBA, type Rect, type ReusableCanvas, type ReusableImageData, type SelectionRect, type SerializedImageData, UnsupportedFormatError, applyMaskToPixelData, base64DecodeArrayBuffer, base64EncodeArrayBuffer, blendColorPixelData, blendPixelData, clearPixelData, color32ToCssRGBA, color32ToHex, colorBurnFast, colorBurnPerfect, colorDistance, colorDodgeFast, colorDodgePerfect, copyImageData, copyImageDataLike, copyMask, darkenFast, darkenPerfect, darkerFast, darkerPerfect, deserializeImageData, deserializeNullableImageData, deserializeRawImageData, differenceFast, differencePerfect, divideFast, dividePerfect, exclusionFast, exclusionPerfect, extractImageDataBuffer, extractMask, extractPixelData, extractPixelDataBuffer, fileInputChangeToImageData, fileToImageData, fillPixelData, floodFillSelection, getImageDataFromClipboard, getIndexedImageColorCounts, getSupportedPixelFormats, hardLightFast, hardLightPerfect, hardMixFast, hardMixPerfect, imageDataToAlphaMask, imageDataToDataUrl, imageDataToImgBlob, imageDataToUInt32Array, imgBlobToImageData, indexedImageToAverageColor, indexedImageToImageData, invertAlphaMask, invertBinaryMask, invertImageData, invertPixelData, lerpColor32, lerpColor32Fast, lightenFast, lightenPerfect, lighterFast, lighterPerfect, linearBurnFast, linearBurnPerfect, linearDodgeFast, linearDodgePerfect, linearLightFast, linearLightPerfect, makeBlendModeRegistry, makeFastBlendModeRegistry, makePerfectBlendModeRegistry, makePixelCanvas, makeReusableCanvas, makeReusableImageData, mergeMasks, multiplyFast, multiplyPerfect, overlayFast, overlayPerfect, overwriteBase, overwriteFast, overwritePerfect, packColor, packRGBA, pinLightFast, pinLightPerfect, pixelDataToAlphaMask, reflectPixelDataHorizontal, reflectPixelDataVertical, resampleImageData, resampleIndexedImage, resamplePixelData, resizeImageData, rotatePixelData, screenFast, screenPerfect, serializeImageData, serializeNullableImageData, softLightFast, softLightPerfect, sourceOverFast, sourceOverPerfect, subtractFast, subtractPerfect, trimRectBounds, unpackAlpha, unpackBlue, unpackColor, unpackColorTo, unpackGreen, unpackRed, vividLightFast, vividLightPerfect, writeImageData, writeImageDataPixels, writeImageDataToClipboard, writeImgBlobToClipboard };
1269
+ export { type AlphaMask, type AnyMask, type ApplyMaskOptions, BASE_FAST_BLEND_MODE_FUNCTIONS, BASE_PERFECT_BLEND_MODE_FUNCTIONS, type Base64EncodedUInt8Array, BaseBlendMode, type BaseBlendModes, type BinaryMask, type BlendColor32, type BlendModeRegistry, type Color32, type ColorBlendOptions, type FloodFillImageDataOptions, type FloodFillResult, type HistoryAction, HistoryManager, type ImageDataLike, IndexedImage, MaskType, PixelAccumulator, type PixelBlendOptions, type PixelCanvas, PixelData, PixelEngineConfig, type PixelMaskInvertOptions, type PixelMaskRectOptions, type PixelMutateOptions, type PixelOptions, type PixelPatchTiles, type PixelRectOptions, PixelTile, PixelWriter, type PixelWriterOptions, type Point, type RGBA, type Rect, type RequiredBlendModes, type ReusableCanvas, type ReusableImageData, type SelectionRect, type SerializedImageData, UnsupportedFormatError, applyCircleBrushToPixelData, applyMaskToPixelData, applyPatchTiles, applyRectBrushToPixelData, base64DecodeArrayBuffer, base64EncodeArrayBuffer, blendColorPixelData, blendPixelData, clearPixelData, color32ToCssRGBA, color32ToHex, colorBurnFast, colorBurnPerfect, colorDistance, colorDodgeFast, colorDodgePerfect, copyImageData, copyImageDataLike, copyMask, darkenFast, darkenPerfect, darkerFast, darkerPerfect, deserializeImageData, deserializeNullableImageData, deserializeRawImageData, differenceFast, differencePerfect, divideFast, dividePerfect, exclusionFast, exclusionPerfect, extractImageDataBuffer, extractMask, extractPixelData, extractPixelDataBuffer, fileInputChangeToImageData, fileToImageData, fillPixelData, floodFillSelection, getImageDataFromClipboard, getIndexedImageColorCounts, getRectBrushBounds, getSupportedPixelFormats, hardLightFast, hardLightPerfect, hardMixFast, hardMixPerfect, imageDataToAlphaMask, imageDataToDataUrl, imageDataToImgBlob, imageDataToUInt32Array, imgBlobToImageData, indexedImageToAverageColor, indexedImageToImageData, invertAlphaMask, invertBinaryMask, invertImageData, invertPixelData, lerpColor32, lerpColor32Fast, lightenFast, lightenPerfect, lighterFast, lighterPerfect, linearBurnFast, linearBurnPerfect, linearDodgeFast, linearDodgePerfect, linearLightFast, linearLightPerfect, makeBlendModeRegistry, makeFastBlendModeRegistry, makeFullPixelMutator, makePerfectBlendModeRegistry, makePixelCanvas, makeReusableCanvas, makeReusableImageData, mergeMasks, multiplyFast, multiplyPerfect, mutatorApplyMask, mutatorBlendColor, mutatorBlendPixel, mutatorBlendPixelData, mutatorFill, mutatorInvert, overlayFast, overlayPerfect, overwriteBase, overwriteFast, overwritePerfect, packColor, packRGBA, pinLightFast, pinLightPerfect, pixelDataToAlphaMask, reflectPixelDataHorizontal, reflectPixelDataVertical, resampleImageData, resampleIndexedImage, resamplePixelData, resizeImageData, rotatePixelData, screenFast, screenPerfect, serializeImageData, serializeNullableImageData, softLightFast, softLightPerfect, sourceOverFast, sourceOverPerfect, subtractFast, subtractPerfect, trimRectBounds, unpackAlpha, unpackBlue, unpackColor, unpackColorTo, unpackGreen, unpackRed, vividLightFast, vividLightPerfect, writeImageData, writeImageDataBuffer, writeImageDataToClipboard, writeImgBlobToClipboard, writePixelDataBuffer };