pixel-data-js 0.23.1 → 0.24.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 (66) hide show
  1. package/dist/index.dev.cjs +1024 -596
  2. package/dist/index.dev.cjs.map +1 -1
  3. package/dist/index.dev.js +1010 -592
  4. package/dist/index.dev.js.map +1 -1
  5. package/dist/index.prod.cjs +1024 -596
  6. package/dist/index.prod.cjs.map +1 -1
  7. package/dist/index.prod.d.ts +280 -165
  8. package/dist/index.prod.js +1010 -592
  9. package/dist/index.prod.js.map +1 -1
  10. package/package.json +3 -2
  11. package/src/Canvas/CanvasFrameRenderer.ts +57 -0
  12. package/src/Canvas/ReusableCanvas.ts +60 -11
  13. package/src/History/HistoryAction.ts +38 -0
  14. package/src/History/HistoryManager.ts +4 -8
  15. package/src/History/PixelAccumulator.ts +95 -80
  16. package/src/History/PixelEngineConfig.ts +18 -6
  17. package/src/History/PixelMutator/mutatorApplyAlphaMask.ts +6 -6
  18. package/src/History/PixelMutator/mutatorApplyBinaryMask.ts +6 -6
  19. package/src/History/PixelMutator/mutatorApplyCircleBrushStroke.ts +6 -5
  20. package/src/History/PixelMutator/mutatorApplyCirclePencil.ts +22 -22
  21. package/src/History/PixelMutator/mutatorApplyCirclePencilStroke.ts +6 -5
  22. package/src/History/PixelMutator/mutatorApplyRectBrush.ts +19 -19
  23. package/src/History/PixelMutator/mutatorApplyRectBrushStroke.ts +6 -4
  24. package/src/History/PixelMutator/mutatorApplyRectPencil.ts +20 -20
  25. package/src/History/PixelMutator/mutatorApplyRectPencilStroke.ts +6 -4
  26. package/src/History/PixelMutator/mutatorBlendColor.ts +8 -5
  27. package/src/History/PixelMutator/mutatorBlendColorCircleMask.ts +71 -0
  28. package/src/History/PixelMutator/mutatorBlendPixel.ts +22 -26
  29. package/src/History/PixelMutator/mutatorBlendPixelData.ts +5 -3
  30. package/src/History/PixelMutator/mutatorBlendPixelDataAlphaMask.ts +5 -3
  31. package/src/History/PixelMutator/mutatorBlendPixelDataBinaryMask.ts +5 -3
  32. package/src/History/PixelMutator/mutatorClear.ts +6 -5
  33. package/src/History/PixelMutator/mutatorFill.ts +34 -9
  34. package/src/History/PixelMutator/mutatorFillBinaryMask.ts +4 -2
  35. package/src/History/PixelMutator/mutatorInvert.ts +8 -4
  36. package/src/History/PixelMutator.ts +4 -3
  37. package/src/History/PixelPatchTiles.ts +3 -15
  38. package/src/History/PixelWriter.ts +29 -33
  39. package/src/ImageData/ReusableImageData.ts +3 -5
  40. package/src/Mask/{CircleBrushAlphaMask.ts → CircleAlphaMask.ts} +2 -2
  41. package/src/Mask/{CircleBrushBinaryMask.ts → CircleBinaryMask.ts} +2 -2
  42. package/src/PixelData/PixelData.ts +1 -27
  43. package/src/PixelData/applyAlphaMaskToPixelData.ts +19 -9
  44. package/src/PixelData/applyBinaryMaskToPixelData.ts +24 -17
  45. package/src/PixelData/applyRectBrushToPixelData.ts +18 -5
  46. package/src/PixelData/blendColorPixelData.ts +31 -7
  47. package/src/PixelData/blendColorPixelDataAlphaMask.ts +16 -6
  48. package/src/PixelData/blendColorPixelDataBinaryMask.ts +16 -7
  49. package/src/PixelData/{applyCircleBrushToPixelData.ts → blendColorPixelDataCircleMask.ts} +11 -10
  50. package/src/PixelData/blendPixel.ts +47 -0
  51. package/src/PixelData/blendPixelData.ts +14 -4
  52. package/src/PixelData/blendPixelDataAlphaMask.ts +12 -4
  53. package/src/PixelData/blendPixelDataBinaryMask.ts +13 -4
  54. package/src/PixelData/blendPixelDataPaintBuffer.ts +37 -0
  55. package/src/PixelData/clearPixelData.ts +2 -2
  56. package/src/PixelData/fillPixelData.ts +26 -16
  57. package/src/PixelData/fillPixelDataBinaryMask.ts +12 -4
  58. package/src/PixelData/fillPixelDataFast.ts +94 -0
  59. package/src/PixelData/invertPixelData.ts +4 -2
  60. package/src/PixelTile/PaintBuffer.ts +122 -0
  61. package/src/PixelTile/PaintBufferRenderer.ts +40 -0
  62. package/src/PixelTile/PixelTile.ts +21 -0
  63. package/src/PixelTile/PixelTilePool.ts +63 -0
  64. package/src/_types.ts +9 -9
  65. package/src/index.ts +16 -6
  66. package/src/History/PixelMutator/mutatorApplyCircleBrush.ts +0 -78
@@ -1,10 +1,10 @@
1
- import type { BlendColor32, CircleBrushMask, Color32, HistoryMutator, Rect } from '../../_types'
2
- import { applyCircleBrushToPixelData } from '../../PixelData/applyCircleBrushToPixelData'
1
+ import type { BlendColor32, CircleMask, Color32, HistoryMutator, Rect } from '../../_types'
2
+ import { blendColorPixelDataCircleMask } from '../../PixelData/blendColorPixelDataCircleMask'
3
3
  import { getCircleBrushOrPencilBounds } from '../../Rect/getCircleBrushOrPencilBounds'
4
4
  import { PixelWriter } from '../PixelWriter'
5
5
 
6
6
  const defaults = {
7
- applyCircleBrushToPixelData,
7
+ applyCircleMaskToPixelData: blendColorPixelDataCircleMask,
8
8
  getCircleBrushOrPencilBounds,
9
9
  }
10
10
 
@@ -15,7 +15,7 @@ type Deps = Partial<typeof defaults>
15
15
  **/
16
16
  export const mutatorApplyCirclePencil = ((writer: PixelWriter<any>, deps: Deps = defaults) => {
17
17
  const {
18
- applyCircleBrushToPixelData = defaults.applyCircleBrushToPixelData,
18
+ applyCircleMaskToPixelData = defaults.applyCircleMaskToPixelData,
19
19
  getCircleBrushOrPencilBounds = defaults.getCircleBrushOrPencilBounds,
20
20
  } = deps
21
21
 
@@ -26,33 +26,33 @@ export const mutatorApplyCirclePencil = ((writer: PixelWriter<any>, deps: Deps =
26
26
  color: Color32,
27
27
  centerX: number,
28
28
  centerY: number,
29
- brush: CircleBrushMask,
29
+ brush: CircleMask,
30
30
  alpha = 255,
31
31
  blendFn?: BlendColor32,
32
- ) {
32
+ ): boolean {
33
33
 
34
- const bounds = getCircleBrushOrPencilBounds(
34
+ const target = writer.config.target
35
+ const b = getCircleBrushOrPencilBounds(
35
36
  centerX,
36
37
  centerY,
37
38
  brush.size,
38
- writer.target.width,
39
- writer.target.height,
39
+ target.width,
40
+ target.height,
40
41
  boundsOut,
41
42
  )
42
43
 
43
- const { x, y, w, h } = bounds
44
-
45
- writer.accumulator.storeRegionBeforeState(x, y, w, h)
46
-
47
- applyCircleBrushToPixelData(
48
- writer.target,
49
- color,
50
- centerX,
51
- centerY,
52
- brush,
53
- alpha,
54
- blendFn,
55
- bounds,
44
+ const didChange = writer.accumulator.storeRegionBeforeState(b.x, b.y, b.w, b.h)
45
+ return didChange(
46
+ applyCircleMaskToPixelData(
47
+ target,
48
+ color,
49
+ centerX,
50
+ centerY,
51
+ brush,
52
+ alpha,
53
+ blendFn,
54
+ b,
55
+ ),
56
56
  )
57
57
  },
58
58
  }
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  type BinaryMask,
3
3
  type BlendColor32,
4
- type CircleBrushBinaryMask,
4
+ type CircleBinaryMask,
5
5
  type Color32,
6
6
  type ColorBlendMaskOptions,
7
7
  type HistoryMutator,
@@ -72,7 +72,7 @@ export const mutatorApplyCirclePencilStroke = ((writer: PixelWriter<any>, deps:
72
72
  y0: number,
73
73
  x1: number,
74
74
  y1: number,
75
- brush: CircleBrushBinaryMask,
75
+ brush: CircleBinaryMask,
76
76
  alpha = 255,
77
77
  blendFn: BlendColor32 = sourceOverPerfect,
78
78
  ) {
@@ -97,8 +97,9 @@ export const mutatorApplyCirclePencilStroke = ((writer: PixelWriter<any>, deps:
97
97
  mask.h = bh
98
98
 
99
99
  const maskData = mask.data
100
- const targetWidth = writer.target.width
101
- const targetHeight = writer.target.height
100
+ const target = writer.config.target
101
+ const targetWidth = target.width
102
+ const targetHeight = target.height
102
103
 
103
104
  forEachLinePoint(
104
105
  x0,
@@ -161,7 +162,7 @@ export const mutatorApplyCirclePencilStroke = ((writer: PixelWriter<any>, deps:
161
162
  blendColorPixelOptions.h = bh
162
163
 
163
164
  blendColorPixelDataBinaryMask(
164
- writer.target,
165
+ target,
165
166
  color,
166
167
  mask as BinaryMask,
167
168
  blendColorPixelOptions,
@@ -31,33 +31,33 @@ export const mutatorApplyRectBrush = ((writer: PixelWriter<any>, deps: Deps = de
31
31
  alpha = 255,
32
32
  fallOff: (dist: number) => number,
33
33
  blendFn?: BlendColor32,
34
- ) {
34
+ ): boolean {
35
35
 
36
- const bounds = getRectBrushOrPencilBounds(
36
+ const target = writer.config.target
37
+ const b = getRectBrushOrPencilBounds(
37
38
  centerX,
38
39
  centerY,
39
40
  brushWidth,
40
41
  brushHeight,
41
- writer.target.width,
42
- writer.target.height,
42
+ target.width,
43
+ target.height,
43
44
  boundsOut,
44
45
  )
45
46
 
46
- const { x, y, w, h } = bounds
47
-
48
- writer.accumulator.storeRegionBeforeState(x, y, w, h)
49
-
50
- applyRectBrushToPixelData(
51
- writer.target,
52
- color,
53
- centerX,
54
- centerY,
55
- brushWidth,
56
- brushHeight,
57
- alpha,
58
- fallOff,
59
- blendFn,
60
- bounds,
47
+ const didChange = writer.accumulator.storeRegionBeforeState(b.x, b.y, b.w, b.h)
48
+ return didChange(
49
+ applyRectBrushToPixelData(
50
+ target,
51
+ color,
52
+ centerX,
53
+ centerY,
54
+ brushWidth,
55
+ brushHeight,
56
+ alpha,
57
+ fallOff,
58
+ blendFn,
59
+ b,
60
+ ),
61
61
  )
62
62
  },
63
63
  }
@@ -3,7 +3,8 @@ import {
3
3
  type BlendColor32,
4
4
  type Color32,
5
5
  type ColorBlendOptions,
6
- type HistoryMutator, MaskType,
6
+ type HistoryMutator,
7
+ MaskType,
7
8
  type Rect,
8
9
  } from '../../_types'
9
10
  import { forEachLinePoint } from '../../Algorithm/forEachLinePoint'
@@ -107,8 +108,9 @@ export const mutatorApplyRectBrushStroke = ((writer: PixelWriter<any>, deps: Dep
107
108
  const centerOffsetX = (brushWidth % 2 === 0) ? 0.5 : 0
108
109
  const centerOffsetY = (brushHeight % 2 === 0) ? 0.5 : 0
109
110
 
110
- const targetWidth = writer.target.width
111
- const targetHeight = writer.target.height
111
+ const target = writer.config.target
112
+ const targetWidth = target.width
113
+ const targetHeight = target.height
112
114
 
113
115
  forEachLinePoint(x0, y0, x1, y1, (px, py) => {
114
116
  const {
@@ -172,7 +174,7 @@ export const mutatorApplyRectBrushStroke = ((writer: PixelWriter<any>, deps: Dep
172
174
  blendColorPixelOptions.h = bh
173
175
 
174
176
  blendColorPixelDataAlphaMask(
175
- writer.target,
177
+ target,
176
178
  color,
177
179
  mask as AlphaMask,
178
180
  blendColorPixelOptions,
@@ -18,7 +18,7 @@ export const mutatorApplyRectPencil = ((writer: PixelWriter<any>, deps: Deps = d
18
18
  const {
19
19
  applyRectBrushToPixelData = defaults.applyRectBrushToPixelData,
20
20
  getRectBrushOrPencilBounds = defaults.getRectBrushOrPencilBounds,
21
- fallOff = defaults.fallOff
21
+ fallOff = defaults.fallOff,
22
22
  } = deps
23
23
 
24
24
  const boundsOut: Rect = { x: 0, y: 0, w: 0, h: 0 }
@@ -32,33 +32,33 @@ export const mutatorApplyRectPencil = ((writer: PixelWriter<any>, deps: Deps = d
32
32
  brushHeight: number,
33
33
  alpha = 255,
34
34
  blendFn?: BlendColor32,
35
- ) {
35
+ ): boolean {
36
36
 
37
- const bounds = getRectBrushOrPencilBounds(
37
+ const target = writer.config.target
38
+ const b = getRectBrushOrPencilBounds(
38
39
  centerX,
39
40
  centerY,
40
41
  brushWidth,
41
42
  brushHeight,
42
- writer.target.width,
43
- writer.target.height,
43
+ target.width,
44
+ target.height,
44
45
  boundsOut,
45
46
  )
46
47
 
47
- const { x, y, w, h } = bounds
48
-
49
- writer.accumulator.storeRegionBeforeState(x, y, w, h)
50
-
51
- applyRectBrushToPixelData(
52
- writer.target,
53
- color,
54
- centerX,
55
- centerY,
56
- brushWidth,
57
- brushHeight,
58
- alpha,
59
- fallOff,
60
- blendFn,
61
- bounds,
48
+ const didChange = writer.accumulator.storeRegionBeforeState(b.x, b.y, b.w, b.h)
49
+ return didChange(
50
+ applyRectBrushToPixelData(
51
+ target,
52
+ color,
53
+ centerX,
54
+ centerY,
55
+ brushWidth,
56
+ brushHeight,
57
+ alpha,
58
+ fallOff,
59
+ blendFn,
60
+ b,
61
+ ),
62
62
  )
63
63
  },
64
64
  }
@@ -3,7 +3,8 @@ import {
3
3
  type BlendColor32,
4
4
  type Color32,
5
5
  type ColorBlendOptions,
6
- type HistoryMutator, MaskType,
6
+ type HistoryMutator,
7
+ MaskType,
7
8
  type Rect,
8
9
  } from '../../_types'
9
10
  import { forEachLinePoint } from '../../Algorithm/forEachLinePoint'
@@ -102,8 +103,9 @@ export const mutatorApplyRectPencilStroke = ((writer: PixelWriter<any>, deps: De
102
103
  const halfH = brushHeight / 2
103
104
  const centerOffset = (brushWidth % 2 === 0) ? 0.5 : 0
104
105
 
105
- const targetWidth = writer.target.width
106
- const targetHeight = writer.target.height
106
+ const target = writer.config.target
107
+ const targetWidth = target.width
108
+ const targetHeight = target.height
107
109
 
108
110
  forEachLinePoint(x0, y0, x1, y1, (px, py) => {
109
111
  const {
@@ -158,7 +160,7 @@ export const mutatorApplyRectPencilStroke = ((writer: PixelWriter<any>, deps: De
158
160
  blendColorPixelOptions.w = bw
159
161
  blendColorPixelOptions.h = bh
160
162
 
161
- blendColorPixelDataBinaryMask(writer.target, color, mask as BinaryMask, blendColorPixelOptions)
163
+ blendColorPixelDataBinaryMask(target, color, mask as BinaryMask, blendColorPixelOptions)
162
164
  },
163
165
  }
164
166
  }) satisfies HistoryMutator<any, Deps>
@@ -17,15 +17,18 @@ export const mutatorBlendColor = ((writer: PixelWriter<any>, deps: Deps = defaul
17
17
  blendColor(
18
18
  color: Color32,
19
19
  opts: ColorBlendOptions = {},
20
- ) {
20
+ ): boolean {
21
+ const target = writer.config.target
21
22
  const {
22
23
  x = 0,
23
24
  y = 0,
24
- w = writer.target.width,
25
- h = writer.target.height,
25
+ w = target.width,
26
+ h = target.height,
26
27
  } = opts
27
- writer.accumulator.storeRegionBeforeState(x, y, w, h)
28
- blendColorPixelData(writer.target, color, opts)
28
+ const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h)
29
+ return didChange(
30
+ blendColorPixelData(target, color, opts),
31
+ )
29
32
  },
30
33
  }
31
34
  }) satisfies HistoryMutator<any, Deps>
@@ -0,0 +1,71 @@
1
+ import type { BlendColor32, CircleMask, Color32, ColorBlendMaskOptions, HistoryMutator, Rect } from '../../_types'
2
+ import { sourceOverPerfect } from '../../BlendModes/blend-modes-perfect'
3
+ import { blendColorPixelDataCircleMask } from '../../PixelData/blendColorPixelDataCircleMask'
4
+ import { getCircleBrushOrPencilBounds } from '../../Rect/getCircleBrushOrPencilBounds'
5
+ import { PixelWriter } from '../PixelWriter'
6
+
7
+ const defaults = {
8
+ blendColorPixelDataCircleMask,
9
+ getCircleBrushOrPencilBounds,
10
+ }
11
+
12
+ type Deps = Partial<typeof defaults>
13
+
14
+ /**
15
+ * @param deps - @hidden
16
+ */
17
+ export const mutatorBlendColorCircleMask = ((writer: PixelWriter<any>, deps: Deps = defaults) => {
18
+ const {
19
+ blendColorPixelDataCircleMask = defaults.blendColorPixelDataCircleMask,
20
+ getCircleBrushOrPencilBounds = defaults.getCircleBrushOrPencilBounds,
21
+
22
+ } = deps
23
+
24
+ const boundsOut: Rect = { x: 0, y: 0, w: 0, h: 0 }
25
+
26
+ const blendColorPixelOptions: ColorBlendMaskOptions = {
27
+ alpha: 255,
28
+ blendFn: sourceOverPerfect,
29
+ x: 0,
30
+ y: 0,
31
+ w: 0,
32
+ h: 0,
33
+ }
34
+
35
+ return {
36
+ applyCircleMask(
37
+ color: Color32,
38
+ centerX: number,
39
+ centerY: number,
40
+ brush: CircleMask,
41
+ alpha = 255,
42
+ blendFn?: BlendColor32,
43
+ ): boolean {
44
+
45
+ const target = writer.config.target
46
+ const b = getCircleBrushOrPencilBounds(
47
+ centerX,
48
+ centerY,
49
+ brush.size,
50
+ target.width,
51
+ target.height,
52
+ boundsOut,
53
+ )
54
+
55
+ const didChange = writer.accumulator.storeRegionBeforeState(b.x, b.y, b.w, b.h)
56
+ return didChange(
57
+ blendColorPixelDataCircleMask(
58
+ target,
59
+ color,
60
+ centerX,
61
+ centerY,
62
+ brush,
63
+ alpha,
64
+ blendFn,
65
+ blendColorPixelOptions,
66
+ b,
67
+ ),
68
+ )
69
+ },
70
+ }
71
+ }) satisfies HistoryMutator<any, Deps>
@@ -1,37 +1,33 @@
1
- import type { BlendColor32, Color32 } from '../../_types'
2
- import { overwriteFast } from '../../BlendModes/blend-modes-fast'
1
+ import type { BlendColor32, Color32, HistoryMutator } from '../../_types'
2
+ import { blendPixel } from '../../PixelData/blendPixel'
3
3
  import { PixelWriter } from '../PixelWriter'
4
4
 
5
- export function mutatorBlendPixel(writer: PixelWriter<any>) {
5
+ const defaults = { blendPixel }
6
+ type Deps = Partial<typeof defaults>
7
+
8
+ /**
9
+ * @param deps - @hidden
10
+ */
11
+ export const mutatorBlendPixel = ((writer: PixelWriter<any>, deps: Partial<Deps> = defaults) => {
12
+ const {
13
+ blendPixel = defaults.blendPixel,
14
+ } = deps
15
+
6
16
  return {
7
17
  blendPixel(
8
18
  x: number,
9
19
  y: number,
10
20
  color: Color32,
11
- alpha: number = 255,
12
- blendFn: BlendColor32 = overwriteFast,
13
- ) {
14
- let target = writer.target
15
- let width = target.width
16
- let height = target.height
17
-
18
- if (x < 0 || x >= width || y < 0 || y >= height) return
19
-
20
- writer.accumulator.storeTileBeforeState(x, y)
21
+ alpha?: number,
22
+ blendFn?: BlendColor32,
23
+ ): boolean {
21
24
 
22
- let index = y * width + x
23
- let bg = target.data32[index] as Color32
25
+ const didChange = writer.accumulator.storePixelBeforeState(x, y)
24
26
 
25
- let finalColor = color
26
-
27
- if (alpha < 255) {
28
- let baseSrcAlpha = color >>> 24
29
- let finalAlpha = (baseSrcAlpha * alpha + 128) >> 8
30
-
31
- finalColor = (((color & 0x00ffffff) | (finalAlpha << 24)) >>> 0) as Color32
32
- }
33
-
34
- target.data32[index] = blendFn(finalColor, bg)
27
+ return didChange(
28
+ blendPixel(writer.config.target, x, y, color, alpha, blendFn),
29
+ )
35
30
  },
36
31
  }
37
- }
32
+ }) satisfies HistoryMutator<any, Deps>
33
+
@@ -17,16 +17,18 @@ export const mutatorBlendPixelData = ((writer: PixelWriter<any>, deps: Partial<D
17
17
  blendPixelData(
18
18
  src: IPixelData,
19
19
  opts: PixelBlendOptions = {},
20
- ) {
20
+ ): boolean {
21
21
  const {
22
22
  x = 0,
23
23
  y = 0,
24
24
  w = src.width,
25
25
  h = src.height,
26
26
  } = opts
27
- writer.accumulator.storeRegionBeforeState(x, y, w, h)
27
+ const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h)
28
28
 
29
- blendPixelData(writer.target, src, opts)
29
+ return didChange(
30
+ blendPixelData(writer.config.target, src, opts),
31
+ )
30
32
  },
31
33
  }
32
34
  }) satisfies HistoryMutator<any, Deps>
@@ -18,15 +18,17 @@ export const mutatorBlendPixelDataAlphaMask = ((writer: PixelWriter<any>, deps:
18
18
  src: IPixelData,
19
19
  mask: AlphaMask,
20
20
  opts: PixelBlendMaskOptions = {},
21
- ) {
21
+ ): boolean {
22
22
  const x = opts.x ?? 0
23
23
  const y = opts.y ?? 0
24
24
  const w = opts.w ?? src.width
25
25
  const h = opts.h ?? src.height
26
26
 
27
- writer.accumulator.storeRegionBeforeState(x, y, w, h)
27
+ const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h)
28
28
 
29
- blendPixelDataAlphaMask(writer.target, src, mask, opts)
29
+ return didChange(
30
+ blendPixelDataAlphaMask(writer.config.target, src, mask, opts),
31
+ )
30
32
  },
31
33
  }
32
34
  }) satisfies HistoryMutator<any, Deps>
@@ -18,15 +18,17 @@ export const mutatorBlendPixelDataBinaryMask = ((writer: PixelWriter<any>, deps:
18
18
  src: IPixelData,
19
19
  mask: BinaryMask,
20
20
  opts: PixelBlendMaskOptions = {},
21
- ) {
21
+ ): boolean {
22
22
  const x = opts.x ?? 0
23
23
  const y = opts.y ?? 0
24
24
  const w = opts.w ?? src.width
25
25
  const h = opts.h ?? src.height
26
26
 
27
- writer.accumulator.storeRegionBeforeState(x, y, w, h)
27
+ const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h)
28
28
 
29
- blendPixelDataBinaryMask(writer.target, src, mask, opts)
29
+ return didChange(
30
+ blendPixelDataBinaryMask(writer.config.target, src, mask, opts),
31
+ )
30
32
  },
31
33
  }
32
34
  }) satisfies HistoryMutator<any, Deps>
@@ -1,8 +1,8 @@
1
1
  import type { Color32, HistoryMutator, Rect } from '../../_types'
2
- import { fillPixelData } from '../../PixelData/fillPixelData'
2
+ import { fillPixelDataFast } from '../../PixelData/fillPixelDataFast'
3
3
  import { PixelWriter } from '../PixelWriter'
4
4
 
5
- const defaults = { fillPixelData }
5
+ const defaults = { fillPixelData: fillPixelDataFast }
6
6
 
7
7
  type Deps = Partial<typeof defaults>
8
8
 
@@ -18,13 +18,14 @@ export const mutatorClear = ((writer: PixelWriter<any>, deps: Deps = defaults) =
18
18
  clear(
19
19
  rect: Partial<Rect> = {},
20
20
  ) {
21
+ const target = writer.config.target
21
22
  const x = rect.x ?? 0
22
23
  const y = rect.y ?? 0
23
- const w = rect.w ?? writer.target.width
24
- const h = rect.h ?? writer.target.height
24
+ const w = rect.w ?? target.width
25
+ const h = rect.h ?? target.height
25
26
 
26
27
  writer.accumulator.storeRegionBeforeState(x, y, w, h)
27
- fillPixelData(writer.target, 0 as Color32, x, y, w, h)
28
+ fillPixelData(target, 0 as Color32, x, y, w, h)
28
29
  },
29
30
  }
30
31
  }) satisfies HistoryMutator<any, Deps>
@@ -16,16 +16,41 @@ export const mutatorFill = ((writer: PixelWriter<any>, deps: Deps = defaults) =>
16
16
  return {
17
17
  fill(
18
18
  color: Color32,
19
- rect: Partial<Rect> = {},
19
+ x = 0,
20
+ y = 0,
21
+ w = writer.config.target.width,
22
+ h = writer.config.target.height,
20
23
  ) {
21
- const {
22
- x = 0,
23
- y = 0,
24
- w = writer.target.width,
25
- h = writer.target.height,
26
- } = rect
27
- writer.accumulator.storeRegionBeforeState(x, y, w, h)
28
- fillPixelData(writer.target, color, x, y, w, h)
24
+ const target = writer.config.target
25
+
26
+ const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h)
27
+ return didChange(
28
+ fillPixelData(target, color, x, y, w, h),
29
+ )
29
30
  },
30
31
  }
31
32
  }) satisfies HistoryMutator<any, Deps>
33
+
34
+ /**
35
+ * @param deps - @hidden
36
+ */
37
+ export const mutatorFillRect = ((writer: PixelWriter<any>, deps: Deps = defaults) => {
38
+ const {
39
+ fillPixelData = defaults.fillPixelData,
40
+ } = deps
41
+
42
+ return {
43
+ fillRect(
44
+ color: Color32,
45
+ rect: Rect,
46
+ ) {
47
+ const target = writer.config.target
48
+
49
+ const didChange = writer.accumulator.storeRegionBeforeState(rect.x, rect.y, rect.w, rect.h)
50
+ return didChange(
51
+ fillPixelData(target, color, rect.x, rect.y, rect.w, rect.h)
52
+ )
53
+ },
54
+ }
55
+ }) satisfies HistoryMutator<any, Deps>
56
+
@@ -21,8 +21,10 @@ export const mutatorFillBinaryMask = ((writer: PixelWriter<any>, deps: Deps = de
21
21
  x = 0,
22
22
  y = 0,
23
23
  ) {
24
- writer.accumulator.storeRegionBeforeState(x, y, mask.w, mask.h)
25
- fillPixelDataBinaryMask(writer.target, color, mask, alpha, x, y)
24
+ const didChange = writer.accumulator.storeRegionBeforeState(x, y, mask.w, mask.h)
25
+ return didChange(
26
+ fillPixelDataBinaryMask(writer.config.target, color, mask, alpha, x, y),
27
+ )
26
28
  },
27
29
  }
28
30
  }) satisfies HistoryMutator<any, Deps>
@@ -15,14 +15,18 @@ export const mutatorInvert = ((writer: PixelWriter<any>, deps: Deps = defaults)
15
15
 
16
16
  return {
17
17
  invert(opts: PixelMutateOptions = {}) {
18
+ const target = writer.config.target
18
19
  const {
19
20
  x = 0,
20
21
  y = 0,
21
- w = writer.target.width,
22
- h = writer.target.height,
22
+ w = target.width,
23
+ h = target.height,
23
24
  } = opts
24
- writer.accumulator.storeRegionBeforeState(x, y, w, h)
25
- invertPixelData(writer.target, opts)
25
+ const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h)
26
+
27
+ return didChange(
28
+ invertPixelData(target, opts),
29
+ )
26
30
  },
27
31
  }
28
32
  }) satisfies HistoryMutator<any, Deps>
@@ -1,7 +1,7 @@
1
1
  import { mutatorApplyAlphaMask } from './PixelMutator/mutatorApplyAlphaMask'
2
2
  import { mutatorApplyBinaryMask } from './PixelMutator/mutatorApplyBinaryMask'
3
- import { mutatorApplyCircleBrush } from './PixelMutator/mutatorApplyCircleBrush'
4
3
  import { mutatorApplyCircleBrushStroke } from './PixelMutator/mutatorApplyCircleBrushStroke'
4
+ import { mutatorBlendColorCircleMask } from './PixelMutator/mutatorBlendColorCircleMask'
5
5
  import { mutatorApplyCirclePencil } from './PixelMutator/mutatorApplyCirclePencil'
6
6
  import { mutatorApplyCirclePencilStroke } from './PixelMutator/mutatorApplyCirclePencilStroke'
7
7
  import { mutatorApplyRectBrush } from './PixelMutator/mutatorApplyRectBrush'
@@ -14,7 +14,7 @@ import { mutatorBlendPixelData } from './PixelMutator/mutatorBlendPixelData'
14
14
  import { mutatorBlendPixelDataAlphaMask } from './PixelMutator/mutatorBlendPixelDataAlphaMask'
15
15
  import { mutatorBlendPixelDataBinaryMask } from './PixelMutator/mutatorBlendPixelDataBinaryMask'
16
16
  import { mutatorClear } from './PixelMutator/mutatorClear'
17
- import { mutatorFill } from './PixelMutator/mutatorFill'
17
+ import { mutatorFill, mutatorFillRect } from './PixelMutator/mutatorFill'
18
18
  import { mutatorFillBinaryMask } from './PixelMutator/mutatorFillBinaryMask'
19
19
  import { mutatorInvert } from './PixelMutator/mutatorInvert'
20
20
  import type { PixelWriter } from './PixelWriter'
@@ -24,7 +24,6 @@ export function makeFullPixelMutator(writer: PixelWriter<any>) {
24
24
  // @sort
25
25
  ...mutatorApplyAlphaMask(writer),
26
26
  ...mutatorApplyBinaryMask(writer),
27
- ...mutatorApplyCircleBrush(writer),
28
27
  ...mutatorApplyCircleBrushStroke(writer),
29
28
  ...mutatorApplyCirclePencil(writer),
30
29
  ...mutatorApplyCirclePencilStroke(writer),
@@ -33,6 +32,7 @@ export function makeFullPixelMutator(writer: PixelWriter<any>) {
33
32
  ...mutatorApplyRectPencil(writer),
34
33
  ...mutatorApplyRectPencilStroke(writer),
35
34
  ...mutatorBlendColor(writer),
35
+ ...mutatorBlendColorCircleMask(writer),
36
36
  ...mutatorBlendPixel(writer),
37
37
  ...mutatorBlendPixelData(writer),
38
38
  ...mutatorBlendPixelDataAlphaMask(writer),
@@ -40,6 +40,7 @@ export function makeFullPixelMutator(writer: PixelWriter<any>) {
40
40
  ...mutatorClear(writer),
41
41
  ...mutatorFill(writer),
42
42
  ...mutatorFillBinaryMask(writer),
43
+ ...mutatorFillRect(writer),
43
44
  ...mutatorInvert(writer),
44
45
  }
45
46
  }