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/dist/index.prod.cjs +297 -245
- package/dist/index.prod.cjs.map +1 -1
- package/dist/index.prod.d.ts +43 -34
- package/dist/index.prod.js +289 -245
- package/dist/index.prod.js.map +1 -1
- package/package.json +1 -1
- package/src/Canvas/CanvasFrameRenderer.ts +2 -2
- package/src/History/HistoryAction.ts +4 -7
- package/src/Internal/_constants.ts +3 -0
- package/src/Paint/AlphaMaskPaintBuffer.ts +0 -56
- package/src/Paint/BinaryMaskPaintBuffer.ts +0 -56
- package/src/Paint/ColorPaintBuffer.ts +0 -53
- package/src/Paint/Commit/AlphaMaskPaintBufferCommitter.ts +26 -0
- package/src/Paint/Commit/AlphaMaskPaintBufferManager.ts +34 -0
- package/src/Paint/Commit/BinaryMaskPaintBufferCommitter.ts +26 -0
- package/src/Paint/Commit/BinaryMaskPaintBufferManager.ts +31 -0
- package/src/Paint/Commit/ColorPaintBufferCommitter.ts +23 -0
- package/src/Paint/Commit/ColorPaintBufferManager.ts +34 -0
- package/src/Paint/Commit/commitColorPaintBuffer.ts +55 -0
- package/src/Paint/Commit/commitMaskPaintBuffer.ts +78 -0
- package/src/Paint/{AlphaMaskPaintBufferCanvasRenderer.ts → Render/AlphaMaskPaintBufferCanvasRenderer.ts} +9 -9
- package/src/Paint/{BinaryMaskPaintBufferCanvasRenderer.ts → Render/BinaryMaskPaintBufferCanvasRenderer.ts} +9 -9
- package/src/Paint/{ColorPaintBufferCanvasRenderer.ts → Render/ColorPaintBufferCanvasRenderer.ts} +8 -10
- package/src/Paint/{PaintCursorRenderer.ts → Render/PaintCursorRenderer.ts} +23 -22
- package/src/index.ts +15 -4
package/package.json
CHANGED
|
@@ -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
|
|
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 =
|
|
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
|
-
|
|
18
|
-
|
|
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
|
}
|
|
@@ -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 '
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
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
|
-
|
|
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 =
|
|
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',
|