pixel-data-js 0.28.0 → 0.30.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.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pixel-data-js",
3
3
  "type": "module",
4
- "version": "0.28.0",
4
+ "version": "0.30.0",
5
5
  "packageManager": "pnpm@10.33.0",
6
6
  "description": "JS Pixel and ImageData operations",
7
7
  "author": {
@@ -7,7 +7,7 @@ export type CanvasFrameRenderer<T extends HTMLCanvasElement | OffscreenCanvas =
7
7
  export function makeCanvasFrameRenderer<T extends HTMLCanvasElement | OffscreenCanvas = OffscreenCanvas>(
8
8
  reusableCanvasFactory: () => ReusableCanvasFactory<T> = makeReusableOffscreenCanvas as unknown as () => ReusableCanvasFactory<T>,
9
9
  ) {
10
- const bufferCanvas = reusableCanvasFactory()
10
+ const getBuffer = reusableCanvasFactory()
11
11
 
12
12
  return function renderCanvasFrame(
13
13
  pixelCanvas: PixelCanvas,
@@ -23,7 +23,7 @@ export function makeCanvasFrameRenderer<T extends HTMLCanvasElement | OffscreenC
23
23
  const h = canvas.height
24
24
 
25
25
  // 1. Clear pixel buffer
26
- const buffer = bufferCanvas(w, h)
26
+ const buffer = getBuffer(w, h)
27
27
 
28
28
  // 2. Draw pixel data into pixel buffer
29
29
  const img = getImageData()
@@ -14,9 +14,8 @@ export function makeHistoryAction(
14
14
  config: PixelEngineConfig,
15
15
  accumulator: PixelAccumulator,
16
16
  patch: PixelPatchTiles,
17
- after?: () => void,
18
- afterUndo?: () => void,
19
- afterRedo?: () => void,
17
+ afterUndo?: (patch: PixelPatchTiles) => void,
18
+ afterRedo?: (patch: PixelPatchTiles) => void,
20
19
  applyPatchTilesFn = applyPatchTiles,
21
20
  ): HistoryAction {
22
21
 
@@ -26,13 +25,11 @@ export function makeHistoryAction(
26
25
  return {
27
26
  undo: () => {
28
27
  applyPatchTilesFn(target, patch.beforeTiles, tileSize)
29
- afterUndo?.()
30
- after?.()
28
+ afterUndo?.(patch)
31
29
  },
32
30
  redo: () => {
33
31
  applyPatchTilesFn(target, patch.afterTiles, tileSize)
34
- afterRedo?.()
35
- after?.()
32
+ afterRedo?.(patch)
36
33
  },
37
34
  dispose: () => accumulator.recyclePatch(patch),
38
35
  }
@@ -0,0 +1,3 @@
1
+ import type { CanvasObjectFactory } from '../Canvas/_canvas-types'
2
+
3
+ export const DEFAULT_CANVAS_FACTORY: CanvasObjectFactory<any> = (w, h) => new OffscreenCanvas(w, h)
@@ -1,10 +1,6 @@
1
- import { type Color32 } from '../_types'
2
1
  import { forEachLinePoint } from '../Algorithm/forEachLinePoint'
3
- import { sourceOverPerfect } from '../BlendModes/blend-modes-perfect'
4
- import type { PixelAccumulator } from '../History/PixelAccumulator'
5
2
  import type { PixelEngineConfig } from '../History/PixelEngineConfig'
6
3
  import { _macro_paintRectCenterOffset } from '../Internal/macros'
7
- import { blendColorPixelDataAlphaMask } from '../PixelData/blendColorPixelDataAlphaMask'
8
4
  import type { Rect } from '../Rect/_rect-types'
9
5
  import { trimRectBounds } from '../Rect/trimRectBounds'
10
6
  import type { AlphaMaskTile } from '../Tile/_tile-types'
@@ -16,7 +12,6 @@ export class AlphaMaskPaintBuffer {
16
12
  readonly lookup: (AlphaMaskTile | undefined)[]
17
13
  private readonly scratchBounds: Rect = { x: 0, y: 0, w: 0, h: 0 }
18
14
 
19
- private blendColorPixelDataAlphaMaskFn = blendColorPixelDataAlphaMask
20
15
  private forEachLinePointFn = forEachLinePoint
21
16
  private trimRectBoundsFn = trimRectBounds
22
17
  private eachTileInBoundsFn = eachTileInBounds
@@ -282,57 +277,6 @@ export class AlphaMaskPaintBuffer {
282
277
  return changed
283
278
  }
284
279
 
285
- private opts = {
286
- alpha: 255,
287
- blendFn: sourceOverPerfect,
288
- x: 0,
289
- y: 0,
290
- w: 0,
291
- h: 0,
292
- }
293
-
294
- commit(
295
- accumulator: PixelAccumulator,
296
- color: Color32,
297
- alpha = 255,
298
- blendFn = sourceOverPerfect,
299
- ) {
300
- const blendColorPixelDataAlphaMaskFn = this.blendColorPixelDataAlphaMaskFn
301
- const tileShift = this.config.tileShift
302
- const lookup = this.lookup
303
- const opts = this.opts
304
-
305
- opts.alpha = alpha
306
- opts.blendFn = blendFn
307
-
308
- for (let i = 0; i < lookup.length; i++) {
309
- const tile = lookup[i]
310
-
311
- if (tile) {
312
- const didChange = accumulator.storeTileBeforeState(tile.id, tile.tx, tile.ty)
313
-
314
- const dx = tile.tx << tileShift
315
- const dy = tile.ty << tileShift
316
-
317
- opts.x = dx
318
- opts.y = dy
319
- opts.w = tile.w
320
- opts.h = tile.h
321
-
322
- didChange(
323
- blendColorPixelDataAlphaMaskFn(
324
- this.config.target,
325
- color,
326
- tile,
327
- opts,
328
- ),
329
- )
330
- }
331
- }
332
-
333
- this.clear()
334
- }
335
-
336
280
  clear(): void {
337
281
  this.tilePool.releaseTiles(this.lookup)
338
282
  }
@@ -1,10 +1,6 @@
1
- import { type Color32 } from '../_types'
2
1
  import { forEachLinePoint } from '../Algorithm/forEachLinePoint'
3
- import { sourceOverPerfect } from '../BlendModes/blend-modes-perfect'
4
- import type { PixelAccumulator } from '../History/PixelAccumulator'
5
2
  import type { PixelEngineConfig } from '../History/PixelEngineConfig'
6
3
  import { _macro_paintRectCenterOffset } from '../Internal/macros'
7
- import { blendColorPixelDataBinaryMask } from '../PixelData/blendColorPixelDataBinaryMask'
8
4
  import type { Rect } from '../Rect/_rect-types'
9
5
  import { trimRectBounds } from '../Rect/trimRectBounds'
10
6
  import type { BinaryMaskTile } from '../Tile/_tile-types'
@@ -16,7 +12,6 @@ export class BinaryMaskPaintBuffer {
16
12
  readonly lookup: (BinaryMaskTile | undefined)[]
17
13
  private readonly scratchBounds: Rect = { x: 0, y: 0, w: 0, h: 0 }
18
14
 
19
- private blendColorPixelDataBinaryMaskFn = blendColorPixelDataBinaryMask
20
15
  private forEachLinePointFn = forEachLinePoint
21
16
  private trimRectBoundsFn = trimRectBounds
22
17
  private eachTileInBoundsFn = eachTileInBounds
@@ -197,57 +192,6 @@ export class BinaryMaskPaintBuffer {
197
192
  return changed
198
193
  }
199
194
 
200
- private opts = {
201
- alpha: 255,
202
- blendFn: sourceOverPerfect,
203
- x: 0,
204
- y: 0,
205
- w: 0,
206
- h: 0,
207
- }
208
-
209
- commit(
210
- accumulator: PixelAccumulator,
211
- color: Color32,
212
- alpha = 255,
213
- blendFn = sourceOverPerfect,
214
- ) {
215
- const blendColorPixelDataBinaryMaskFn = this.blendColorPixelDataBinaryMaskFn
216
- const tileShift = this.config.tileShift
217
- const lookup = this.lookup
218
- const opts = this.opts
219
-
220
- opts.alpha = alpha
221
- opts.blendFn = blendFn
222
-
223
- for (let i = 0; i < lookup.length; i++) {
224
- const tile = lookup[i]
225
-
226
- if (tile) {
227
- const didChange = accumulator.storeTileBeforeState(tile.id, tile.tx, tile.ty)
228
-
229
- const dx = tile.tx << tileShift
230
- const dy = tile.ty << tileShift
231
-
232
- opts.x = dx
233
- opts.y = dy
234
- opts.w = tile.w
235
- opts.h = tile.h
236
-
237
- didChange(
238
- blendColorPixelDataBinaryMaskFn(
239
- this.config.target,
240
- color,
241
- tile,
242
- opts,
243
- ),
244
- )
245
- }
246
- }
247
-
248
- this.clear()
249
- }
250
-
251
195
  clear(): void {
252
196
  this.tilePool.releaseTiles(this.lookup)
253
197
  }
@@ -1,10 +1,7 @@
1
1
  import type { Color32 } from '../_types'
2
2
  import { forEachLinePoint } from '../Algorithm/forEachLinePoint'
3
- import { sourceOverPerfect } from '../BlendModes/blend-modes-perfect'
4
- import type { PixelAccumulator } from '../History/PixelAccumulator'
5
3
  import type { PixelEngineConfig } from '../History/PixelEngineConfig'
6
4
  import { _macro_paintRectCenterOffset } from '../Internal/macros'
7
- import { blendPixelData } from '../PixelData/blendPixelData'
8
5
  import type { Rect } from '../Rect/_rect-types'
9
6
  import { trimRectBounds } from '../Rect/trimRectBounds'
10
7
  import type { PixelTile } from '../Tile/_tile-types'
@@ -19,7 +16,6 @@ export class ColorPaintBuffer {
19
16
  constructor(
20
17
  readonly config: PixelEngineConfig,
21
18
  readonly tilePool: TilePool<PixelTile>,
22
- private blendPixelDataFn = blendPixelData,
23
19
  ) {
24
20
  this.lookup = []
25
21
  }
@@ -285,55 +281,6 @@ export class ColorPaintBuffer {
285
281
  return changed
286
282
  }
287
283
 
288
- private opts = {
289
- alpha: 255,
290
- blendFn: sourceOverPerfect,
291
- x: 0,
292
- y: 0,
293
- w: 0,
294
- h: 0,
295
- }
296
-
297
- commit(
298
- accumulator: PixelAccumulator,
299
- alpha = 255,
300
- blendFn = sourceOverPerfect,
301
- ) {
302
- const tileShift = this.config.tileShift
303
- const lookup = this.lookup
304
- const opts = this.opts
305
-
306
- const blendPixelDataFn = this.blendPixelDataFn
307
- opts.alpha = alpha
308
- opts.blendFn = blendFn
309
-
310
- for (let i = 0; i < lookup.length; i++) {
311
- const tile = lookup[i]
312
-
313
- if (tile) {
314
- const didChange = accumulator.storeTileBeforeState(tile.id, tile.tx, tile.ty)
315
-
316
- const dx = tile.tx << tileShift
317
- const dy = tile.ty << tileShift
318
-
319
- opts.x = dx
320
- opts.y = dy
321
- opts.w = tile.w
322
- opts.h = tile.h
323
-
324
- didChange(
325
- blendPixelDataFn(
326
- this.config.target,
327
- tile,
328
- opts,
329
- ),
330
- )
331
- }
332
- }
333
-
334
- this.clear()
335
- }
336
-
337
284
  clear(): void {
338
285
  this.tilePool.releaseTiles(this.lookup)
339
286
  }
@@ -0,0 +1,26 @@
1
+ import type { Color32 } from '../../_types'
2
+ import { sourceOverPerfect } from '../../BlendModes/blend-modes-perfect'
3
+ import type { PixelAccumulator } from '../../History/PixelAccumulator'
4
+ import { blendColorPixelDataAlphaMask } from '../../PixelData/blendColorPixelDataAlphaMask'
5
+ import type { AlphaMaskPaintBuffer } from '../AlphaMaskPaintBuffer'
6
+ import { commitMaskPaintBuffer } from './commitMaskPaintBuffer'
7
+
8
+ export function makeAlphaMaskPaintBufferCommitter(
9
+ accumulator: PixelAccumulator,
10
+ paintBuffer: AlphaMaskPaintBuffer,
11
+ ) {
12
+ return function commitAlphaMaskPaintBufferToAccumulator(
13
+ color: Color32,
14
+ alpha = 255,
15
+ blendFn = sourceOverPerfect,
16
+ ) {
17
+ return commitMaskPaintBuffer(
18
+ accumulator,
19
+ paintBuffer,
20
+ color,
21
+ alpha,
22
+ blendFn,
23
+ blendColorPixelDataAlphaMask,
24
+ )
25
+ }
26
+ }
@@ -0,0 +1,34 @@
1
+ import type { CanvasObjectFactory } from '../../Canvas/_canvas-types'
2
+ import type { PixelWriter } from '../../History/PixelWriter'
3
+ import { DEFAULT_CANVAS_FACTORY } from '../../Internal/_constants'
4
+ import { makeAlphaMaskTile } from '../../Tile/MaskTile'
5
+ import { TilePool } from '../../Tile/TilePool'
6
+ import { AlphaMaskPaintBuffer } from '../AlphaMaskPaintBuffer'
7
+ import { makeAlphaMaskPaintBufferCanvasRenderer } from '../Render/AlphaMaskPaintBufferCanvasRenderer'
8
+ import { makeAlphaMaskPaintBufferCommitter } from './AlphaMaskPaintBufferCommitter'
9
+
10
+ export type AlphaMaskPaintBufferManager =
11
+ Pick<AlphaMaskPaintBuffer, 'paintAlphaMask' | 'paintBinaryMask' | 'paintRect'>
12
+ & {
13
+ commit: ReturnType<typeof makeAlphaMaskPaintBufferCommitter>
14
+ draw: ReturnType<typeof makeAlphaMaskPaintBufferCanvasRenderer>
15
+ clear: () => void
16
+ }
17
+
18
+ export function makeAlphaMaskPaintBufferManager(
19
+ writer: Pick<PixelWriter<any>, 'accumulator' | 'config'>,
20
+ canvasFactory: CanvasObjectFactory<any> = DEFAULT_CANVAS_FACTORY,
21
+ ): AlphaMaskPaintBufferManager {
22
+ const pool = new TilePool(writer.config, makeAlphaMaskTile)
23
+ const buffer = new AlphaMaskPaintBuffer(writer.config, pool)
24
+ const draw = makeAlphaMaskPaintBufferCanvasRenderer(buffer, canvasFactory)
25
+
26
+ return {
27
+ clear: buffer.clear.bind(buffer),
28
+ paintRect: buffer.paintRect.bind(buffer),
29
+ paintAlphaMask: buffer.paintAlphaMask.bind(buffer),
30
+ paintBinaryMask: buffer.paintBinaryMask.bind(buffer),
31
+ commit: makeAlphaMaskPaintBufferCommitter(writer.accumulator, buffer),
32
+ draw,
33
+ }
34
+ }
@@ -0,0 +1,26 @@
1
+ import type { Color32 } from '../../_types'
2
+ import { sourceOverPerfect } from '../../BlendModes/blend-modes-perfect'
3
+ import type { PixelAccumulator } from '../../History/PixelAccumulator'
4
+ import { blendColorPixelDataBinaryMask } from '../../PixelData/blendColorPixelDataBinaryMask'
5
+ import type { BinaryMaskPaintBuffer } from '../BinaryMaskPaintBuffer'
6
+ import { commitMaskPaintBuffer } from './commitMaskPaintBuffer'
7
+
8
+ export function makeBinaryMaskPaintBufferCommitter(
9
+ accumulator: PixelAccumulator,
10
+ paintBuffer: BinaryMaskPaintBuffer,
11
+ ) {
12
+ return function commitBinaryMaskPaintBufferToAccumulator(
13
+ color: Color32,
14
+ alpha = 255,
15
+ blendFn = sourceOverPerfect,
16
+ ) {
17
+ return commitMaskPaintBuffer(
18
+ accumulator,
19
+ paintBuffer,
20
+ color,
21
+ alpha,
22
+ blendFn,
23
+ blendColorPixelDataBinaryMask,
24
+ )
25
+ }
26
+ }
@@ -0,0 +1,31 @@
1
+ import type { CanvasObjectFactory } from '../../Canvas/_canvas-types'
2
+ import type { PixelWriter } from '../../History/PixelWriter'
3
+ import { DEFAULT_CANVAS_FACTORY } from '../../Internal/_constants'
4
+ import { makeBinaryMaskTile } from '../../Tile/MaskTile'
5
+ import { TilePool } from '../../Tile/TilePool'
6
+ import { BinaryMaskPaintBuffer } from '../BinaryMaskPaintBuffer'
7
+ import { makeBinaryMaskPaintBufferCanvasRenderer } from '../Render/BinaryMaskPaintBufferCanvasRenderer'
8
+ import { makeBinaryMaskPaintBufferCommitter } from './BinaryMaskPaintBufferCommitter'
9
+
10
+ export type BinaryMaskPaintBufferManager = Pick<BinaryMaskPaintBuffer, 'paintBinaryMask' | 'paintRect'> & {
11
+ commit: ReturnType<typeof makeBinaryMaskPaintBufferCommitter>
12
+ draw: ReturnType<typeof makeBinaryMaskPaintBufferCanvasRenderer>
13
+ clear: () => void
14
+ }
15
+
16
+ export function makeBinaryMaskPaintBufferManager(
17
+ writer: Pick<PixelWriter<any>, 'accumulator' | 'config'>,
18
+ canvasFactory: CanvasObjectFactory<any> = DEFAULT_CANVAS_FACTORY,
19
+ ): BinaryMaskPaintBufferManager {
20
+ const pool = new TilePool(writer.config, makeBinaryMaskTile)
21
+ const buffer = new BinaryMaskPaintBuffer(writer.config, pool)
22
+ const draw = makeBinaryMaskPaintBufferCanvasRenderer(buffer, canvasFactory)
23
+
24
+ return {
25
+ clear: buffer.clear.bind(buffer),
26
+ paintRect: buffer.paintRect.bind(buffer),
27
+ paintBinaryMask: buffer.paintBinaryMask.bind(buffer),
28
+ commit: makeBinaryMaskPaintBufferCommitter(writer.accumulator, buffer),
29
+ draw,
30
+ }
31
+ }
@@ -0,0 +1,23 @@
1
+ import { sourceOverPerfect } from '../../BlendModes/blend-modes-perfect'
2
+ import type { PixelAccumulator } from '../../History/PixelAccumulator'
3
+ import { blendPixelData } from '../../PixelData/blendPixelData'
4
+ import type { ColorPaintBuffer } from '../ColorPaintBuffer'
5
+ import { commitColorPaintBuffer } from './commitColorPaintBuffer'
6
+
7
+ export function makeColorPaintBufferCommitter(
8
+ accumulator: PixelAccumulator,
9
+ paintBuffer: ColorPaintBuffer,
10
+ ) {
11
+ return function commitColorPaintBufferToAccumulator(
12
+ alpha = 255,
13
+ blendFn = sourceOverPerfect,
14
+ ) {
15
+ return commitColorPaintBuffer(
16
+ accumulator,
17
+ paintBuffer,
18
+ alpha,
19
+ blendFn,
20
+ blendPixelData,
21
+ )
22
+ }
23
+ }
@@ -0,0 +1,34 @@
1
+ import type { CanvasObjectFactory } from '../../Canvas/_canvas-types'
2
+ import type { PixelWriter } from '../../History/PixelWriter'
3
+ import { DEFAULT_CANVAS_FACTORY } from '../../Internal/_constants'
4
+ import { makePixelTile } from '../../Tile/PixelTile'
5
+ import { TilePool } from '../../Tile/TilePool'
6
+ import { ColorPaintBuffer } from '../ColorPaintBuffer'
7
+ import { makeColorPaintBufferCanvasRenderer } from '../Render/ColorPaintBufferCanvasRenderer'
8
+ import { makeColorPaintBufferCommitter } from './ColorPaintBufferCommitter'
9
+
10
+ export type ColorPaintBufferManager =
11
+ Pick<ColorPaintBuffer, 'paintAlphaMask' | 'paintBinaryMask' | 'paintRect'>
12
+ & {
13
+ commit: ReturnType<typeof makeColorPaintBufferCommitter>
14
+ draw: ReturnType<typeof makeColorPaintBufferCanvasRenderer>
15
+ clear: () => void
16
+ }
17
+
18
+ export function makeColorPaintBufferManager(
19
+ writer: Pick<PixelWriter<any>, 'accumulator' | 'config'>,
20
+ canvasFactory: CanvasObjectFactory<any> = DEFAULT_CANVAS_FACTORY,
21
+ ): ColorPaintBufferManager {
22
+ const pool = new TilePool(writer.config, makePixelTile)
23
+ const buffer = new ColorPaintBuffer(writer.config, pool)
24
+ const draw = makeColorPaintBufferCanvasRenderer(buffer, canvasFactory)
25
+
26
+ return {
27
+ clear: buffer.clear.bind(buffer),
28
+ paintRect: buffer.paintRect.bind(buffer),
29
+ paintAlphaMask: buffer.paintAlphaMask.bind(buffer),
30
+ paintBinaryMask: buffer.paintBinaryMask.bind(buffer),
31
+ commit: makeColorPaintBufferCommitter(writer.accumulator, buffer),
32
+ draw,
33
+ }
34
+ }
@@ -0,0 +1,55 @@
1
+ import { sourceOverPerfect } from '../../BlendModes/blend-modes-perfect'
2
+ import type { PixelAccumulator } from '../../History/PixelAccumulator'
3
+ import { blendPixelData } from '../../PixelData/blendPixelData'
4
+ import type { ColorPaintBuffer } from '../ColorPaintBuffer'
5
+
6
+ const SCRATCH_OPTS = {
7
+ alpha: 255,
8
+ blendFn: sourceOverPerfect,
9
+ x: 0,
10
+ y: 0,
11
+ w: 0,
12
+ h: 0,
13
+ }
14
+
15
+ export function commitColorPaintBuffer(
16
+ accumulator: PixelAccumulator,
17
+ paintBuffer: ColorPaintBuffer,
18
+ alpha = 255,
19
+ blendFn = sourceOverPerfect,
20
+ blendPixelDataFn = blendPixelData,
21
+ ) {
22
+ const config = accumulator.config
23
+ const tileShift = config.tileShift
24
+ const lookup = paintBuffer.lookup
25
+
26
+ SCRATCH_OPTS.alpha = alpha
27
+ SCRATCH_OPTS.blendFn = blendFn
28
+
29
+ for (let i = 0; i < lookup.length; i++) {
30
+ const tile = lookup[i]
31
+
32
+ if (tile) {
33
+ const didChange = accumulator.storeTileBeforeState(tile.id, tile.tx, tile.ty)
34
+
35
+ const dx = tile.tx << tileShift
36
+ const dy = tile.ty << tileShift
37
+
38
+ SCRATCH_OPTS.x = dx
39
+ SCRATCH_OPTS.y = dy
40
+ SCRATCH_OPTS.w = tile.w
41
+ SCRATCH_OPTS.h = tile.h
42
+
43
+ didChange(
44
+ blendPixelDataFn(
45
+ config.target,
46
+ tile,
47
+ SCRATCH_OPTS,
48
+ ),
49
+ )
50
+ }
51
+ }
52
+
53
+ paintBuffer.clear()
54
+ }
55
+
@@ -0,0 +1,78 @@
1
+ import { type Color32 } from '../../_types'
2
+ import { sourceOverPerfect } from '../../BlendModes/blend-modes-perfect'
3
+ import type { PixelAccumulator } from '../../History/PixelAccumulator'
4
+ import { blendColorPixelDataAlphaMask } from '../../PixelData/blendColorPixelDataAlphaMask'
5
+ import { blendColorPixelDataBinaryMask } from '../../PixelData/blendColorPixelDataBinaryMask'
6
+ import type { AlphaMaskPaintBuffer } from '../AlphaMaskPaintBuffer'
7
+ import type { BinaryMaskPaintBuffer } from '../BinaryMaskPaintBuffer'
8
+
9
+ const SCRATCH_OPTS = {
10
+ alpha: 255,
11
+ blendFn: sourceOverPerfect,
12
+ x: 0,
13
+ y: 0,
14
+ w: 0,
15
+ h: 0,
16
+ }
17
+
18
+ export function commitMaskPaintBuffer(
19
+ accumulator: PixelAccumulator,
20
+ paintBuffer: BinaryMaskPaintBuffer,
21
+ color: Color32,
22
+ alpha: number | undefined,
23
+ blendFn: typeof sourceOverPerfect | undefined,
24
+ blendColorPixelDataMaskFn: typeof blendColorPixelDataBinaryMask,
25
+ ): void
26
+
27
+ export function commitMaskPaintBuffer(
28
+ accumulator: PixelAccumulator,
29
+ paintBuffer: AlphaMaskPaintBuffer,
30
+ color: Color32,
31
+ alpha: number | undefined,
32
+ blendFn: typeof sourceOverPerfect | undefined,
33
+ blendColorPixelDataMaskFn: typeof blendColorPixelDataAlphaMask,
34
+ ): void
35
+
36
+ export function commitMaskPaintBuffer(
37
+ accumulator: PixelAccumulator,
38
+ paintBuffer: any,
39
+ color: Color32,
40
+ alpha = 255,
41
+ blendFn = sourceOverPerfect,
42
+ blendColorPixelDataMaskFn: any,
43
+ ) {
44
+ const config = accumulator.config
45
+ const tileShift = config.tileShift
46
+ const lookup = paintBuffer.lookup
47
+
48
+ SCRATCH_OPTS.alpha = alpha
49
+ SCRATCH_OPTS.blendFn = blendFn
50
+
51
+ for (let i = 0; i < lookup.length; i++) {
52
+ const tile = lookup[i]
53
+
54
+ if (tile) {
55
+ const didChange = accumulator.storeTileBeforeState(tile.id, tile.tx, tile.ty)
56
+
57
+ const dx = tile.tx << tileShift
58
+ const dy = tile.ty << tileShift
59
+
60
+ SCRATCH_OPTS.x = dx
61
+ SCRATCH_OPTS.y = dy
62
+ SCRATCH_OPTS.w = tile.w
63
+ SCRATCH_OPTS.h = tile.h
64
+
65
+ didChange(
66
+ blendColorPixelDataMaskFn(
67
+ config.target,
68
+ color,
69
+ tile,
70
+ SCRATCH_OPTS,
71
+ ),
72
+ )
73
+ }
74
+ }
75
+
76
+ paintBuffer.clear()
77
+ }
78
+
@@ -1,13 +1,15 @@
1
- import type { Color32 } from '../_types'
2
- import { CANVAS_CTX_FAILED } from '../Internal/_errors'
3
- import { makePixelData } from '../PixelData/PixelData'
4
- import type { AlphaMaskPaintBuffer } from './AlphaMaskPaintBuffer'
1
+ import type { Color32 } from '../../_types'
2
+ import type { CanvasObjectFactory } from '../../Canvas/_canvas-types'
3
+ import { DEFAULT_CANVAS_FACTORY } from '../../Internal/_constants'
4
+ import { CANVAS_CTX_FAILED } from '../../Internal/_errors'
5
+ import { makePixelData } from '../../PixelData/PixelData'
6
+ import type { AlphaMaskPaintBuffer } from '../AlphaMaskPaintBuffer'
5
7
 
6
8
  export type AlphaMaskPaintBufferCanvasRenderer = ReturnType<typeof makeAlphaMaskPaintBufferCanvasRenderer>
7
9
 
8
10
  export function makeAlphaMaskPaintBufferCanvasRenderer(
9
11
  paintBuffer: AlphaMaskPaintBuffer,
10
- offscreenCanvasClass = OffscreenCanvas,
12
+ canvasFactory: CanvasObjectFactory<any> = DEFAULT_CANVAS_FACTORY,
11
13
  ) {
12
14
  const config = paintBuffer.config
13
15
  const tileSize = config.tileSize
@@ -15,18 +17,16 @@ export function makeAlphaMaskPaintBufferCanvasRenderer(
15
17
  const tileArea = config.tileArea
16
18
  const lookup = paintBuffer.lookup
17
19
 
18
- const canvas = new offscreenCanvasClass(tileSize, tileSize)
20
+ const canvas = canvasFactory(tileSize, tileSize)
19
21
  const ctx = canvas.getContext('2d')
20
-
21
22
  if (!ctx) throw new Error(CANVAS_CTX_FAILED)
22
-
23
23
  ctx.imageSmoothingEnabled = false
24
24
 
25
25
  const bridge = makePixelData(new ImageData(tileSize, tileSize))
26
26
  const view32 = bridge.data
27
27
 
28
28
  return function drawPaintBuffer(
29
- targetCtx: CanvasRenderingContext2D,
29
+ targetCtx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,
30
30
  color: Color32,
31
31
  alpha = 255,
32
32
  compOperation: GlobalCompositeOperation = 'source-over',