pixel-data-js 0.24.0 → 0.25.2

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 (72) hide show
  1. package/dist/index.dev.cjs +1476 -1834
  2. package/dist/index.dev.cjs.map +1 -1
  3. package/dist/index.dev.js +1465 -1816
  4. package/dist/index.dev.js.map +1 -1
  5. package/dist/index.prod.cjs +1475 -1833
  6. package/dist/index.prod.cjs.map +1 -1
  7. package/dist/index.prod.d.ts +233 -310
  8. package/dist/index.prod.js +1465 -1816
  9. package/dist/index.prod.js.map +1 -1
  10. package/package.json +1 -1
  11. package/src/Algorithm/floodFillSelection.ts +2 -2
  12. package/src/Canvas/canvas-blend-modes.ts +28 -0
  13. package/src/History/PixelAccumulator.ts +52 -29
  14. package/src/History/PixelEngineConfig.ts +7 -9
  15. package/src/History/PixelMutator/mutatorBlendPaintMask.ts +60 -0
  16. package/src/History/PixelMutator/mutatorBlendPixelData.ts +2 -2
  17. package/src/History/PixelMutator/mutatorBlendPixelDataAlphaMask.ts +2 -2
  18. package/src/History/PixelMutator/mutatorBlendPixelDataBinaryMask.ts +2 -2
  19. package/src/History/PixelMutator.ts +0 -20
  20. package/src/History/PixelPatchTiles.ts +2 -2
  21. package/src/History/PixelWriter.ts +132 -9
  22. package/src/Internal/helpers.ts +2 -0
  23. package/src/Paint/PaintBuffer.ts +269 -0
  24. package/src/{PixelTile/PaintBufferRenderer.ts → Paint/PaintBufferCanvasRenderer.ts} +13 -5
  25. package/src/Paint/makeCirclePaintAlphaMask.ts +41 -0
  26. package/src/{Mask/CircleBinaryMask.ts → Paint/makeCirclePaintBinaryMask.ts} +5 -6
  27. package/src/Paint/makePaintMask.ts +28 -0
  28. package/src/Paint/makeRectFalloffPaintAlphaMask.ts +47 -0
  29. package/src/PixelData/PixelBuffer32.ts +2 -2
  30. package/src/PixelData/PixelData.ts +1 -1
  31. package/src/PixelData/applyAlphaMaskToPixelData.ts +2 -2
  32. package/src/PixelData/applyBinaryMaskToPixelData.ts +2 -2
  33. package/src/PixelData/blendColorPixelData.ts +2 -2
  34. package/src/PixelData/blendColorPixelDataAlphaMask.ts +3 -3
  35. package/src/PixelData/blendColorPixelDataBinaryMask.ts +3 -3
  36. package/src/PixelData/blendPixel.ts +2 -2
  37. package/src/PixelData/blendPixelData.ts +3 -3
  38. package/src/PixelData/blendPixelDataAlphaMask.ts +3 -3
  39. package/src/PixelData/blendPixelDataBinaryMask.ts +3 -3
  40. package/src/PixelData/blendPixelDataPaintBuffer.ts +3 -3
  41. package/src/PixelData/clearPixelData.ts +2 -2
  42. package/src/PixelData/extractPixelData.ts +4 -4
  43. package/src/PixelData/extractPixelDataBuffer.ts +4 -4
  44. package/src/PixelData/fillPixelData.ts +5 -5
  45. package/src/PixelData/fillPixelDataBinaryMask.ts +3 -3
  46. package/src/PixelData/fillPixelDataFast.ts +5 -5
  47. package/src/PixelData/invertPixelData.ts +2 -2
  48. package/src/PixelData/pixelDataToAlphaMask.ts +2 -2
  49. package/src/PixelData/reflectPixelData.ts +3 -3
  50. package/src/PixelData/resamplePixelData.ts +2 -2
  51. package/src/PixelData/writePaintBufferToPixelData.ts +26 -0
  52. package/src/PixelData/writePixelDataBuffer.ts +5 -5
  53. package/src/Rect/trimMaskRectBounds.ts +121 -0
  54. package/src/Rect/trimRectBounds.ts +25 -116
  55. package/src/_types.ts +16 -15
  56. package/src/index.ts +11 -24
  57. package/src/History/PixelMutator/mutatorApplyCircleBrushStroke.ts +0 -182
  58. package/src/History/PixelMutator/mutatorApplyCirclePencil.ts +0 -59
  59. package/src/History/PixelMutator/mutatorApplyCirclePencilStroke.ts +0 -172
  60. package/src/History/PixelMutator/mutatorApplyRectBrush.ts +0 -64
  61. package/src/History/PixelMutator/mutatorApplyRectBrushStroke.ts +0 -184
  62. package/src/History/PixelMutator/mutatorApplyRectPencil.ts +0 -65
  63. package/src/History/PixelMutator/mutatorApplyRectPencilStroke.ts +0 -166
  64. package/src/History/PixelMutator/mutatorBlendColorCircleMask.ts +0 -71
  65. package/src/Mask/CircleAlphaMask.ts +0 -32
  66. package/src/PixelData/applyRectBrushToPixelData.ts +0 -98
  67. package/src/PixelData/blendColorPixelDataCircleMask.ts +0 -92
  68. package/src/PixelTile/PaintBuffer.ts +0 -122
  69. package/src/Rect/getCircleBrushOrPencilBounds.ts +0 -43
  70. package/src/Rect/getCircleBrushOrPencilStrokeBounds.ts +0 -24
  71. package/src/Rect/getRectBrushOrPencilBounds.ts +0 -38
  72. package/src/Rect/getRectBrushOrPencilStrokeBounds.ts +0 -26
@@ -0,0 +1,269 @@
1
+ import type { Color32, PaintAlphaMask, PaintBinaryMask, Rect } from '../_types'
2
+ import { forEachLinePoint } from '../Algorithm/forEachLinePoint'
3
+ import type { PixelEngineConfig } from '../History/PixelEngineConfig'
4
+ import { macro_halfAndFloor } from '../Internal/helpers'
5
+ import type { PixelTile } from '../PixelTile/PixelTile'
6
+ import type { PixelTilePool } from '../PixelTile/PixelTilePool'
7
+ import { trimRectBounds } from '../Rect/trimRectBounds'
8
+
9
+ export class PaintBuffer {
10
+ readonly lookup: (PixelTile | undefined)[]
11
+ private readonly scratchBounds: Rect = { x: 0, y: 0, w: 0, h: 0 }
12
+
13
+ constructor(
14
+ readonly config: PixelEngineConfig,
15
+ readonly tilePool: PixelTilePool,
16
+ ) {
17
+ this.lookup = []
18
+ }
19
+
20
+ private eachTileInBounds(
21
+ bounds: Rect,
22
+ callback: (tile: PixelTile, bX: number, bY: number, bW: number, bH: number) => void,
23
+ ): void {
24
+ const { tileShift, targetColumns, targetRows, tileSize } = this.config
25
+
26
+ const x1 = Math.max(0, bounds.x >> tileShift)
27
+ const y1 = Math.max(0, bounds.y >> tileShift)
28
+ const x2 = Math.min(targetColumns - 1, (bounds.x + bounds.w - 1) >> tileShift)
29
+ const y2 = Math.min(targetRows - 1, (bounds.y + bounds.h - 1) >> tileShift)
30
+
31
+ if (x1 > x2 || y1 > y2) return
32
+
33
+ const lookup = this.lookup
34
+ const tilePool = this.tilePool
35
+
36
+ for (let ty = y1; ty <= y2; ty++) {
37
+ const rowOffset = ty * targetColumns
38
+ const tileTop = ty << tileShift
39
+
40
+ for (let tx = x1; tx <= x2; tx++) {
41
+ const id = rowOffset + tx
42
+ const tile = lookup[id] ?? (lookup[id] = tilePool.getTile(id, tx, ty))
43
+ const tileLeft = tx << tileShift
44
+
45
+ const startX = bounds.x > tileLeft ? bounds.x : tileLeft
46
+ const startY = bounds.y > tileTop ? bounds.y : tileTop
47
+
48
+ const maskEndX = bounds.x + bounds.w
49
+ const tileEndX = tileLeft + tileSize
50
+ const endX = maskEndX < tileEndX ? maskEndX : tileEndX
51
+
52
+ const maskEndY = bounds.y + bounds.h
53
+ const tileEndY = tileTop + tileSize
54
+ const endY = maskEndY < tileEndY ? maskEndY : tileEndY
55
+
56
+ callback(tile, startX, startY, endX - startX, endY - startY)
57
+ }
58
+ }
59
+ }
60
+
61
+ writePaintAlphaMaskStroke(
62
+ color: Color32,
63
+ brush: PaintAlphaMask,
64
+ x0: number,
65
+ y0: number,
66
+ x1: number,
67
+ y1: number,
68
+ ): boolean {
69
+ const cA = color >>> 24
70
+ if (cA === 0) return false
71
+
72
+ const { tileShift, tileMask, target } = this.config
73
+ const { w: bW, h: bH, data: bD, centerOffsetX, centerOffsetY } = brush
74
+ const cRGB = color & 0x00ffffff
75
+ const scratch = this.scratchBounds
76
+
77
+ let changed = false
78
+
79
+ forEachLinePoint(x0, y0, x1, y1, (px, py) => {
80
+
81
+ const topLeftX = Math.floor(px + centerOffsetX)
82
+ const topLeftY = Math.floor(py + centerOffsetY)
83
+ trimRectBounds(
84
+ topLeftX,
85
+ topLeftY,
86
+ bW,
87
+ bH,
88
+ target.width,
89
+ target.height,
90
+ scratch,
91
+ )
92
+
93
+ if (scratch.w <= 0 || scratch.h <= 0) return
94
+
95
+ this.eachTileInBounds(scratch, (tile, bX, bY, bW_t, bH_t) => {
96
+ const d32 = tile.data32
97
+ let tileChanged = false
98
+
99
+ for (let i = 0; i < bH_t; i++) {
100
+ const canvasY = bY + i
101
+ const bOff = (canvasY - topLeftY) * bW
102
+ const tOff = (canvasY & tileMask) << tileShift
103
+ const dS = tOff + (bX & tileMask)
104
+
105
+ for (let j = 0; j < bW_t; j++) {
106
+ const canvasX = bX + j
107
+ const brushA = bD[bOff + (canvasX - topLeftX)]
108
+ if (brushA === 0) continue
109
+
110
+ const t = cA * brushA + 128
111
+ const blendedA = (t + (t >> 8)) >> 8
112
+
113
+ const idx = dS + j
114
+ const cur = d32[idx]
115
+ if (brushA > (cur >>> 24)) {
116
+ const next = (cRGB | (blendedA << 24)) >>> 0
117
+ if (cur !== next) {
118
+ d32[idx] = next as Color32
119
+ tileChanged = true
120
+ }
121
+ }
122
+ }
123
+ }
124
+ if (tileChanged) changed = true
125
+ })
126
+ })
127
+ return changed
128
+ }
129
+
130
+ writePaintBinaryMaskStroke(
131
+ color: Color32,
132
+ brush: PaintBinaryMask,
133
+ x0: number,
134
+ y0: number,
135
+ x1: number,
136
+ y1: number,
137
+ ): boolean {
138
+ const alphaIsZero = (color >>> 24) === 0
139
+ if (alphaIsZero) return false
140
+
141
+ const { tileShift, tileMask, target } = this.config
142
+ const { w: bW, h: bH, data: bD, centerOffsetX, centerOffsetY } = brush
143
+ const scratch = this.scratchBounds
144
+ let changed = false
145
+
146
+ forEachLinePoint(x0, y0, x1, y1, (px, py) => {
147
+ const topLeftX = Math.floor(px + centerOffsetX)
148
+ const topLeftY = Math.floor(py + centerOffsetY)
149
+
150
+ trimRectBounds(
151
+ topLeftX,
152
+ topLeftY,
153
+ bW,
154
+ bH,
155
+ target.width,
156
+ target.height,
157
+ scratch,
158
+ )
159
+
160
+ if (scratch.w <= 0 || scratch.h <= 0) return
161
+
162
+ this.eachTileInBounds(scratch, (tile, bX, bY, bW_t, bH_t) => {
163
+ const d32 = tile.data32
164
+ let tileChanged = false
165
+
166
+ for (let i = 0; i < bH_t; i++) {
167
+ const canvasY = bY + i
168
+ const bOff = (canvasY - topLeftY) * bW
169
+ const tOff = (canvasY & tileMask) << tileShift
170
+ const dS = tOff + (bX & tileMask)
171
+
172
+ for (let j = 0; j < bW_t; j++) {
173
+ const canvasX = bX + j
174
+ if (bD[bOff + (canvasX - topLeftX)]) {
175
+ const idx = dS + j
176
+ if (d32[idx] !== color) {
177
+ d32[idx] = color
178
+ tileChanged = true
179
+ }
180
+ }
181
+ }
182
+ }
183
+ if (tileChanged) changed = true
184
+ })
185
+ })
186
+
187
+ return changed
188
+ }
189
+
190
+ writeRectStroke(
191
+ color: Color32,
192
+ brushWidth: number,
193
+ brushHeight: number,
194
+ x0: number,
195
+ y0: number,
196
+ x1: number,
197
+ y1: number,
198
+ ): boolean {
199
+ const alphaIsZero = (color >>> 24) === 0
200
+ if (alphaIsZero) return false
201
+
202
+ const config = this.config
203
+ const tileShift = config.tileShift
204
+ const tileMask = config.tileMask
205
+ const target = config.target
206
+ const scratch = this.scratchBounds
207
+
208
+ const centerOffsetX = macro_halfAndFloor(brushWidth - 1)
209
+ const centerOffsetY = macro_halfAndFloor(brushHeight - 1)
210
+
211
+ let changed = false
212
+
213
+ forEachLinePoint(
214
+ x0,
215
+ y0,
216
+ x1,
217
+ y1,
218
+ (px, py) => {
219
+ const topLeftX = Math.floor(px + centerOffsetX)
220
+ const topLeftY = Math.floor(py + centerOffsetY)
221
+
222
+ trimRectBounds(
223
+ topLeftX,
224
+ topLeftY,
225
+ brushWidth,
226
+ brushHeight,
227
+ target.width,
228
+ target.height,
229
+ scratch,
230
+ )
231
+
232
+ if (scratch.w <= 0 || scratch.h <= 0) return
233
+
234
+ this.eachTileInBounds(
235
+ scratch,
236
+ (tile, bX, bY, bW_t, bH_t) => {
237
+ const d32 = tile.data32
238
+ let tileChanged = false
239
+
240
+ for (let i = 0; i < bH_t; i++) {
241
+ const canvasY = bY + i
242
+ const tOff = (canvasY & tileMask) << tileShift
243
+ const dS = tOff + (bX & tileMask)
244
+
245
+ for (let j = 0; j < bW_t; j++) {
246
+ const idx = dS + j
247
+
248
+ if (d32[idx] !== color) {
249
+ d32[idx] = color
250
+ tileChanged = true
251
+ }
252
+ }
253
+ }
254
+
255
+ if (tileChanged) {
256
+ changed = true
257
+ }
258
+ },
259
+ )
260
+ },
261
+ )
262
+
263
+ return changed
264
+ }
265
+
266
+ clear(): void {
267
+ this.tilePool.releaseTiles(this.lookup)
268
+ }
269
+ }
@@ -1,14 +1,13 @@
1
1
  import { CANVAS_CTX_FAILED } from '../Canvas/_constants'
2
2
  import type { PaintBuffer } from './PaintBuffer'
3
3
 
4
- export type PaintBufferRenderer = ReturnType<typeof makePaintBufferRenderer>
4
+ export type PaintBufferCanvasRenderer = ReturnType<typeof makePaintBufferCanvasRenderer>
5
5
 
6
6
  /**
7
7
  *
8
- * @param paintBuffer
9
8
  * @param offscreenCanvasClass - @internal
10
9
  */
11
- export function makePaintBufferRenderer(
10
+ export function makePaintBufferCanvasRenderer(
12
11
  paintBuffer: PaintBuffer,
13
12
  offscreenCanvasClass = OffscreenCanvas,
14
13
  ) {
@@ -22,8 +21,14 @@ export function makePaintBufferRenderer(
22
21
  ctx.imageSmoothingEnabled = false
23
22
 
24
23
  return function drawPaintBuffer(
25
- target: CanvasRenderingContext2D,
24
+ targetCtx: CanvasRenderingContext2D,
25
+ alpha = 255,
26
+ compOperation: GlobalCompositeOperation = 'source-over',
26
27
  ): void {
28
+
29
+ targetCtx.globalAlpha = alpha / 255
30
+ targetCtx.globalCompositeOperation = compOperation
31
+
27
32
  for (let i = 0; i < lookup.length; i++) {
28
33
  const tile = lookup[i]
29
34
 
@@ -33,8 +38,11 @@ export function makePaintBufferRenderer(
33
38
 
34
39
  ctx.putImageData(tile.imageData, 0, 0)
35
40
 
36
- target.drawImage(canvas, dx, dy)
41
+ targetCtx.drawImage(canvas, dx, dy)
37
42
  }
38
43
  }
44
+
45
+ targetCtx.globalAlpha = 1
46
+ targetCtx.globalCompositeOperation = 'source-over'
39
47
  }
40
48
  }
@@ -0,0 +1,41 @@
1
+ import { MaskType, type PaintAlphaMask } from '../_types'
2
+
3
+ export function makeCirclePaintAlphaMask(size: number, fallOff: (d: number) => number = (d) => d): PaintAlphaMask {
4
+ const area = size * size
5
+ const data = new Uint8Array(area)
6
+ const radius = size / 2
7
+ const invR = 1 / radius
8
+
9
+ const centerOffset = -Math.ceil(radius - 0.5)
10
+
11
+ for (let y = 0; y < size; y++) {
12
+ const rowOffset = y * size
13
+ const dy = y - radius + 0.5
14
+ const dy2 = dy * dy
15
+
16
+ for (let x = 0; x < size; x++) {
17
+ const dx = x - radius + 0.5
18
+ const distSqr = dx * dx + dy2
19
+
20
+ if (distSqr <= (radius * radius)) {
21
+ const dist = Math.sqrt(distSqr) * invR
22
+
23
+ // Pass 1.0 at center, 0.0 at edge
24
+ const strength = fallOff(1 - dist)
25
+ if (strength > 0) {
26
+ const intensity = (strength * 255) | 0
27
+ data[rowOffset + x] = Math.max(0, Math.min(255, intensity))
28
+ }
29
+ }
30
+ }
31
+ }
32
+
33
+ return {
34
+ type: MaskType.ALPHA,
35
+ data,
36
+ w: size,
37
+ h: size,
38
+ centerOffsetX: centerOffset,
39
+ centerOffsetY: centerOffset
40
+ }
41
+ }
@@ -1,11 +1,11 @@
1
- import { type CircleBinaryMask, MaskType } from '../_types'
1
+ import { MaskType, type PaintBinaryMask } from '../_types'
2
2
 
3
- export function makeCircleBinaryMask(size: number): CircleBinaryMask {
3
+ export function makeCirclePaintBinaryMask(size: number): PaintBinaryMask {
4
4
  const area = size * size
5
5
  const data = new Uint8Array(area)
6
6
  const radius = size / 2
7
7
 
8
- const minOffset = -Math.ceil(radius - 0.5)
8
+ const centerOffset = -Math.ceil(radius - 0.5)
9
9
 
10
10
  for (let y = 0; y < size; y++) {
11
11
  for (let x = 0; x < size; x++) {
@@ -23,8 +23,7 @@ export function makeCircleBinaryMask(size: number): CircleBinaryMask {
23
23
  data,
24
24
  w: size,
25
25
  h: size,
26
- radius,
27
- size,
28
- minOffset,
26
+ centerOffsetX: centerOffset,
27
+ centerOffsetY: centerOffset,
29
28
  }
30
29
  }
@@ -0,0 +1,28 @@
1
+ import { type AlphaMask, type BinaryMask, MaskType, type PaintAlphaMask, type PaintBinaryMask } from '../_types'
2
+ import { macro_halfAndFloor } from '../Internal/helpers'
3
+
4
+ export function makePaintBinaryMask(
5
+ mask: BinaryMask,
6
+ ): PaintBinaryMask {
7
+ return {
8
+ type: MaskType.BINARY,
9
+ data: mask.data,
10
+ w: mask.w,
11
+ h: mask.h,
12
+ centerOffsetX: -macro_halfAndFloor(mask.w),
13
+ centerOffsetY: -macro_halfAndFloor(mask.h),
14
+ }
15
+ }
16
+
17
+ export function makePaintAlphaMask(
18
+ mask: AlphaMask,
19
+ ): PaintAlphaMask {
20
+ return {
21
+ type: MaskType.ALPHA,
22
+ data: mask.data,
23
+ w: mask.w,
24
+ h: mask.h,
25
+ centerOffsetX: -macro_halfAndFloor(mask.w),
26
+ centerOffsetY: -macro_halfAndFloor(mask.h),
27
+ }
28
+ }
@@ -0,0 +1,47 @@
1
+ import { MaskType, type PaintAlphaMask } from '../_types'
2
+ import { macro_halfAndFloor } from '../Internal/helpers'
3
+
4
+ export function makeRectFalloffPaintAlphaMask(
5
+ width: number,
6
+ height: number,
7
+ fallOff: (d: number) => number = (d) => d,
8
+ ): PaintAlphaMask {
9
+ const fPx = Math.floor(width / 2)
10
+ const fPy = Math.floor(height / 2)
11
+
12
+ const invHalfW = 2 / width
13
+ const invHalfH = 2 / height
14
+
15
+ const offX = (width % 2 === 0) ? 0.5 : 0
16
+ const offY = (height % 2 === 0) ? 0.5 : 0
17
+
18
+ const area = width * height
19
+ const data = new Uint8Array(area)
20
+
21
+ for (let y = 0; y < height; y++) {
22
+ const dy = Math.abs((y - fPy) + offY) * invHalfH
23
+ const rowOffset = y * width
24
+
25
+ for (let x = 0; x < width; x++) {
26
+ const dx = Math.abs((x - fPx) + offX) * invHalfW
27
+
28
+ // Chebyshev distance (square/rect shape)
29
+ const dist = dx > dy ? dx : dy
30
+ // Pass 1.0 at center, 0.0 at edge
31
+ const strength = fallOff(1 - dist)
32
+ if (strength > 0) {
33
+ const intensity = (strength * 255) | 0
34
+ data[rowOffset + x] = Math.max(0, Math.min(255, intensity))
35
+ }
36
+ }
37
+ }
38
+
39
+ return {
40
+ type: MaskType.ALPHA,
41
+ data: data,
42
+ w: width,
43
+ h: height,
44
+ centerOffsetX: -macro_halfAndFloor(width),
45
+ centerOffsetY: -macro_halfAndFloor(height),
46
+ }
47
+ }
@@ -1,6 +1,6 @@
1
- import type { IPixelData } from '../_types'
1
+ import type { IPixelData32 } from '../_types'
2
2
 
3
- export class PixelBuffer32 implements IPixelData {
3
+ export class PixelBuffer32 implements IPixelData32 {
4
4
  readonly data32: Uint32Array
5
5
 
6
6
  constructor(
@@ -1,7 +1,7 @@
1
1
  import type { ImageDataLike, IPixelData } from '../_types'
2
2
  import { imageDataToUInt32Array } from '../ImageData/imageDataToUInt32Array'
3
3
 
4
- export class PixelData<T extends ImageDataLike = ImageData> implements IPixelData {
4
+ export class PixelData<T extends ImageDataLike = ImageData> implements IPixelData<T> {
5
5
  readonly data32: Uint32Array
6
6
  readonly imageData: T
7
7
  readonly width: number
@@ -1,4 +1,4 @@
1
- import { type AlphaMask, type ApplyMaskToPixelDataOptions, type Color32, type IPixelData } from '../_types'
1
+ import { type AlphaMask, type ApplyMaskToPixelDataOptions, type Color32, type IPixelData32 } from '../_types'
2
2
 
3
3
  /**
4
4
  * Directly applies a mask to a region of PixelData,
@@ -6,7 +6,7 @@ import { type AlphaMask, type ApplyMaskToPixelDataOptions, type Color32, type IP
6
6
  * @returns true if any pixels were actually modified.
7
7
  */
8
8
  export function applyAlphaMaskToPixelData(
9
- dst: IPixelData,
9
+ dst: IPixelData32,
10
10
  mask: AlphaMask,
11
11
  opts: ApplyMaskToPixelDataOptions = {},
12
12
  ): boolean {
@@ -1,4 +1,4 @@
1
- import { type ApplyMaskToPixelDataOptions, type BinaryMask, type IPixelData } from '../_types'
1
+ import { type ApplyMaskToPixelDataOptions, type BinaryMask, type IPixelData32 } from '../_types'
2
2
 
3
3
  /**
4
4
  * Directly applies a mask to a region of PixelData,
@@ -6,7 +6,7 @@ import { type ApplyMaskToPixelDataOptions, type BinaryMask, type IPixelData } fr
6
6
  * @returns true if any pixels were actually modified.
7
7
  */
8
8
  export function applyBinaryMaskToPixelData(
9
- dst: IPixelData,
9
+ dst: IPixelData32,
10
10
  mask: BinaryMask,
11
11
  opts: ApplyMaskToPixelDataOptions = {},
12
12
  ): boolean {
@@ -1,4 +1,4 @@
1
- import { type Color32, type ColorBlendOptions, type IPixelData } from '../_types'
1
+ import { type Color32, type ColorBlendOptions, type IPixelData32 } from '../_types'
2
2
  import { sourceOverPerfect } from '../BlendModes/blend-modes-perfect'
3
3
 
4
4
  /**
@@ -6,7 +6,7 @@ import { sourceOverPerfect } from '../BlendModes/blend-modes-perfect'
6
6
  * @returns true if any pixels were actually modified.
7
7
  */
8
8
  export function blendColorPixelData(
9
- dst: IPixelData,
9
+ dst: IPixelData32,
10
10
  color: Color32,
11
11
  opts: ColorBlendOptions = {},
12
12
  ): boolean {
@@ -1,4 +1,4 @@
1
- import type { AlphaMask, Color32, ColorBlendMaskOptions, IPixelData } from '../_types'
1
+ import type { AlphaMask, Color32, ColorBlendMaskOptions, IPixelData32 } from '../_types'
2
2
  import { sourceOverPerfect } from '../BlendModes/blend-modes-perfect'
3
3
 
4
4
  /**
@@ -8,14 +8,14 @@ import { sourceOverPerfect } from '../BlendModes/blend-modes-perfect'
8
8
  * If the width (`w`) or height (`h`) are omitted from the options, they will safely
9
9
  * default to the dimensions of the provided mask to prevent out-of-bounds memory access.
10
10
  *
11
- * @param dst - The destination {@link IPixelData} buffer to modify.
11
+ * @param dst - The destination {@link IPixelData32} buffer to modify.
12
12
  * @param color - The solid color to apply.
13
13
  * @param mask - The mask defining the per-pixel opacity of the target area.
14
14
  * @param opts - Configuration options including placement coordinates, bounds, global alpha, and mask offsets.
15
15
  * @returns true if any pixels were actually modified.
16
16
  */
17
17
  export function blendColorPixelDataAlphaMask(
18
- dst: IPixelData,
18
+ dst: IPixelData32,
19
19
  color: Color32,
20
20
  mask: AlphaMask,
21
21
  opts: ColorBlendMaskOptions = {},
@@ -1,4 +1,4 @@
1
- import type { BinaryMask, Color32, ColorBlendMaskOptions, IPixelData } from '../_types'
1
+ import type { BinaryMask, Color32, ColorBlendMaskOptions, IPixelData32 } from '../_types'
2
2
  import { sourceOverPerfect } from '../BlendModes/blend-modes-perfect'
3
3
 
4
4
  /**
@@ -8,14 +8,14 @@ import { sourceOverPerfect } from '../BlendModes/blend-modes-perfect'
8
8
  * If the width (`w`) or height (`h`) are omitted from the options, they will safely
9
9
  * default to the dimensions of the provided mask to prevent out-of-bounds memory access.
10
10
  *
11
- * @param dst - The destination {@link IPixelData} buffer to modify.
11
+ * @param dst - The destination {@link IPixelData32} buffer to modify.
12
12
  * @param color - The solid color to apply.
13
13
  * @param mask - The mask defining the per-pixel opacity of the target area.
14
14
  * @param opts - Configuration options including placement coordinates, bounds, global alpha, and mask offsets.
15
15
  * @returns true if any pixels were actually modified.
16
16
  */
17
17
  export function blendColorPixelDataBinaryMask(
18
- dst: IPixelData,
18
+ dst: IPixelData32,
19
19
  color: Color32,
20
20
  mask: BinaryMask,
21
21
  opts: ColorBlendMaskOptions = {},
@@ -1,8 +1,8 @@
1
- import type { BlendColor32, Color32, IPixelData } from '../_types'
1
+ import type { BlendColor32, Color32, IPixelData32 } from '../_types'
2
2
  import { sourceOverPerfect } from '../BlendModes/blend-modes-perfect'
3
3
 
4
4
  export function blendPixel(
5
- target: IPixelData,
5
+ target: IPixelData32,
6
6
  x: number,
7
7
  y: number,
8
8
  color: Color32,
@@ -1,4 +1,4 @@
1
- import { type Color32, type IPixelData, type PixelBlendOptions } from '../_types'
1
+ import { type Color32, type IPixelData32, type PixelBlendOptions } from '../_types'
2
2
  import { sourceOverPerfect } from '../BlendModes/blend-modes-perfect'
3
3
 
4
4
  /**
@@ -16,8 +16,8 @@ import { sourceOverPerfect } from '../BlendModes/blend-modes-perfect'
16
16
  * });
17
17
  */
18
18
  export function blendPixelData(
19
- dst: IPixelData,
20
- src: IPixelData,
19
+ dst: IPixelData32,
20
+ src: IPixelData32,
21
21
  opts: PixelBlendOptions = {},
22
22
  ): boolean {
23
23
  const {
@@ -1,9 +1,9 @@
1
- import { type AlphaMask, type Color32, type IPixelData, type PixelBlendMaskOptions } from '../_types'
1
+ import { type AlphaMask, type Color32, type IPixelData32, type PixelBlendMaskOptions } from '../_types'
2
2
  import { sourceOverPerfect } from '../BlendModes/blend-modes-perfect'
3
3
 
4
4
  export function blendPixelDataAlphaMask(
5
- dst: IPixelData,
6
- src: IPixelData,
5
+ dst: IPixelData32,
6
+ src: IPixelData32,
7
7
  alphaMask: AlphaMask,
8
8
  opts: PixelBlendMaskOptions = {},
9
9
  ): boolean {
@@ -1,9 +1,9 @@
1
- import type { BinaryMask, Color32, IPixelData, PixelBlendMaskOptions } from '../_types'
1
+ import type { BinaryMask, Color32, IPixelData32, PixelBlendMaskOptions } from '../_types'
2
2
  import { sourceOverPerfect } from '../BlendModes/blend-modes-perfect'
3
3
 
4
4
  export function blendPixelDataBinaryMask(
5
- dst: IPixelData,
6
- src: IPixelData,
5
+ dst: IPixelData32,
6
+ src: IPixelData32,
7
7
  binaryMask: BinaryMask,
8
8
  opts: PixelBlendMaskOptions = {},
9
9
  ): boolean {
@@ -1,6 +1,6 @@
1
- import type { BlendColor32, IPixelData } from '../_types'
1
+ import type { BlendColor32, IPixelData32 } from '../_types'
2
2
  import { blendPixelData } from './blendPixelData'
3
- import type { PaintBuffer } from '../PixelTile/PaintBuffer'
3
+ import type { PaintBuffer } from '../Paint/PaintBuffer'
4
4
 
5
5
  const SCRATCH_OPTS = {
6
6
  x: 0,
@@ -11,7 +11,7 @@ const SCRATCH_OPTS = {
11
11
 
12
12
  export function blendPixelDataPaintBuffer(
13
13
  paintBuffer: PaintBuffer,
14
- target: IPixelData,
14
+ target: IPixelData32,
15
15
  alpha = 255,
16
16
  blendFn?: BlendColor32,
17
17
  blendPixelDataFn = blendPixelData,
@@ -1,4 +1,4 @@
1
- import type { BinaryMaskRect, Color32, IPixelData } from '../_types'
1
+ import type { BinaryMaskRect, Color32, IPixelData32 } from '../_types'
2
2
  import { fillPixelDataFast } from './fillPixelDataFast'
3
3
 
4
4
  /**
@@ -6,7 +6,7 @@ import { fillPixelDataFast } from './fillPixelDataFast'
6
6
  * Internally uses the optimized fillPixelData.
7
7
  */
8
8
  export function clearPixelData(
9
- dst: IPixelData,
9
+ dst: IPixelData32,
10
10
  rect?: Partial<BinaryMaskRect>,
11
11
  ): void {
12
12
  fillPixelDataFast(dst, 0 as Color32, rect)