pixel-data-js 0.27.0 → 0.28.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/README.md +12 -2
- package/dist/index.prod.cjs +2222 -1045
- package/dist/index.prod.cjs.map +1 -1
- package/dist/index.prod.d.ts +542 -417
- package/dist/index.prod.js +2167 -1024
- package/dist/index.prod.js.map +1 -1
- package/package.json +11 -11
- package/src/Algorithm/floodFillSelection.ts +8 -6
- package/src/Algorithm/forEachLinePoint.ts +6 -6
- package/src/{Internal/resample32.ts → Algorithm/resampleUint32Array.ts} +11 -21
- package/src/BlendModes/blend-modes-fast.ts +169 -0
- package/src/BlendModes/blend-modes-perfect.ts +207 -0
- package/src/BlendModes/blend-modes.ts +9 -0
- package/src/Canvas/CanvasFrameRenderer.ts +20 -28
- package/src/Canvas/CanvasPixelDataRenderer.ts +23 -0
- package/src/Canvas/PixelCanvas.ts +2 -7
- package/src/Canvas/ReusableCanvas.ts +4 -12
- package/src/Canvas/_canvas-types.ts +26 -0
- package/src/History/PixelAccumulator.ts +17 -17
- package/src/History/PixelEngineConfig.ts +3 -3
- package/src/History/PixelMutator/mutatorApplyAlphaMask.ts +4 -3
- package/src/History/PixelMutator/mutatorApplyBinaryMask.ts +4 -3
- package/src/History/PixelMutator/mutatorApplyMask.ts +4 -3
- package/src/History/PixelMutator/mutatorBlendAlphaMask.ts +6 -4
- package/src/History/PixelMutator/mutatorBlendBinaryMask.ts +6 -4
- package/src/History/PixelMutator/mutatorBlendColor.ts +2 -2
- package/src/History/PixelMutator/mutatorBlendColorPaintAlphaMask.ts +2 -1
- package/src/History/PixelMutator/mutatorBlendColorPaintBinaryMask.ts +2 -1
- package/src/History/PixelMutator/mutatorBlendColorPaintMask.ts +3 -1
- package/src/History/PixelMutator/mutatorBlendColorPaintRect.ts +3 -3
- package/src/History/PixelMutator/mutatorBlendMask.ts +6 -4
- package/src/History/PixelMutator/mutatorBlendPixelData.ts +5 -4
- package/src/History/PixelMutator/mutatorClear.ts +4 -3
- package/src/History/PixelMutator/mutatorFill.ts +5 -4
- package/src/History/PixelMutator/mutatorFillBinaryMask.ts +2 -1
- package/src/History/PixelMutator/mutatorInvert.ts +2 -2
- package/src/History/PixelMutator.ts +1 -1
- package/src/History/PixelPatchTiles.ts +7 -7
- package/src/History/PixelWriter.ts +12 -63
- package/src/ImageData/ImageDataLike.ts +1 -1
- package/src/ImageData/_ImageData-types.ts +13 -0
- package/src/ImageData/copyImageData.ts +1 -1
- package/src/ImageData/extractImageDataBuffer.ts +3 -2
- package/src/ImageData/imageDataToUint32Array.ts +18 -0
- package/src/ImageData/resampleImageData.ts +3 -3
- package/src/ImageData/resizeImageData.ts +1 -1
- package/src/ImageData/serialization.ts +1 -1
- package/src/ImageData/uInt32ArrayToImageData.ts +1 -1
- package/src/ImageData/writeImageData.ts +2 -2
- package/src/ImageData/writeImageDataBuffer.ts +2 -2
- package/src/IndexedImage/IndexedImage.ts +56 -98
- package/src/IndexedImage/_indexedImage-types.ts +18 -0
- package/src/IndexedImage/getIndexedImageColorCounts.ts +3 -3
- package/src/IndexedImage/indexedImageToAverageColor.ts +1 -1
- package/src/IndexedImage/indexedImageToImageData.ts +4 -6
- package/src/IndexedImage/resampleIndexedImage.ts +7 -15
- package/src/Input/fileToImageData.ts +1 -1
- package/src/Internal/_errors.ts +2 -0
- package/src/Internal/macros.ts +14 -0
- package/src/Mask/AlphaMask.ts +1 -1
- package/src/Mask/BinaryMask/makeBinaryMaskFromAlphaMask.ts +23 -0
- package/src/Mask/BinaryMask/makeBinaryMaskOutline.ts +88 -0
- package/src/Mask/BinaryMask/makeCircleBinaryMaskOutline.ts +104 -0
- package/src/Mask/BinaryMask/makeRectBinaryMaskOutline.ts +34 -0
- package/src/Mask/BinaryMask.ts +1 -1
- package/src/Mask/_mask-types.ts +73 -0
- package/src/Mask/applyBinaryMaskToAlphaMask.ts +2 -1
- package/src/Mask/copyMask.ts +1 -1
- package/src/Mask/extractMask.ts +2 -1
- package/src/Mask/extractMaskBuffer.ts +1 -1
- package/src/Mask/mergeAlphaMasks.ts +6 -3
- package/src/Mask/mergeBinaryMasks.ts +2 -1
- package/src/Mask/setMaskData.ts +1 -1
- package/src/MaskRect/merge2BinaryMaskRects.ts +2 -2
- package/src/MaskRect/mergeBinaryMaskRects.ts +1 -1
- package/src/MaskRect/subtractBinaryMaskRects.ts +1 -1
- package/src/Paint/AlphaMaskPaintBuffer.ts +339 -0
- package/src/Paint/AlphaMaskPaintBufferCanvasRenderer.ts +78 -0
- package/src/Paint/BinaryMaskPaintBuffer.ts +254 -0
- package/src/Paint/BinaryMaskPaintBufferCanvasRenderer.ts +67 -0
- package/src/Paint/{PaintBuffer.ts → ColorPaintBuffer.ts} +148 -77
- package/src/Paint/{PaintBufferCanvasRenderer.ts → ColorPaintBufferCanvasRenderer.ts} +6 -5
- package/src/Paint/PaintCursorRenderer.ts +117 -0
- package/src/Paint/_paint-types.ts +22 -0
- package/src/Paint/eachTileInBounds.ts +45 -0
- package/src/Paint/makeCirclePaintMask.ts +74 -0
- package/src/Paint/makePaintMask.ts +5 -2
- package/src/Paint/makeRectFalloffPaintAlphaMask.ts +4 -2
- package/src/PixelData/PixelData.ts +15 -19
- package/src/PixelData/ReusablePixelData.ts +36 -0
- package/src/PixelData/_pixelData-types.ts +17 -0
- package/src/PixelData/applyAlphaMaskToPixelData.ts +80 -43
- package/src/PixelData/applyBinaryMaskToPixelData.ts +10 -8
- package/src/PixelData/applyMaskToPixelData.ts +4 -9
- package/src/PixelData/blendColorPixelData.ts +9 -8
- package/src/PixelData/blendColorPixelDataAlphaMask.ts +9 -7
- package/src/PixelData/blendColorPixelDataBinaryMask.ts +9 -7
- package/src/PixelData/blendColorPixelDataMask.ts +4 -2
- package/src/PixelData/blendColorPixelDataPaintAlphaMask.ts +4 -2
- package/src/PixelData/blendColorPixelDataPaintBinaryMask.ts +4 -2
- package/src/PixelData/blendColorPixelDataPaintMask.ts +5 -2
- package/src/PixelData/blendPixel.ts +6 -5
- package/src/PixelData/blendPixelData.ts +14 -13
- package/src/PixelData/blendPixelDataAlphaMask.ts +15 -13
- package/src/PixelData/blendPixelDataBinaryMask.ts +15 -13
- package/src/PixelData/blendPixelDataMask.ts +5 -3
- package/src/PixelData/blendPixelDataPaintBuffer.ts +5 -4
- package/src/PixelData/clearPixelDataFast.ts +4 -2
- package/src/PixelData/copyPixelData.ts +14 -0
- package/src/PixelData/extractPixelData.ts +8 -7
- package/src/PixelData/extractPixelDataBuffer.ts +9 -8
- package/src/PixelData/fillPixelData.ts +16 -14
- package/src/PixelData/fillPixelDataBinaryMask.ts +10 -8
- package/src/PixelData/fillPixelDataFast.ts +16 -14
- package/src/PixelData/invertPixelData.ts +9 -8
- package/src/PixelData/pixelDataToAlphaMask.ts +9 -8
- package/src/PixelData/reflectPixelData.ts +9 -9
- package/src/PixelData/resamplePixelData.ts +20 -9
- package/src/PixelData/rotatePixelData.ts +8 -7
- package/src/PixelData/uInt32ArrayToPixelData.ts +15 -0
- package/src/PixelData/writePaintBufferToPixelData.ts +5 -5
- package/src/PixelData/writePixelDataBuffer.ts +10 -9
- package/src/Rect/_rect-types.ts +7 -0
- package/src/Rect/getRectsBounds.ts +1 -1
- package/src/Rect/trimMaskRectBounds.ts +2 -1
- package/src/Rect/trimRectBounds.ts +1 -1
- package/src/Tile/MaskTile.ts +40 -0
- package/src/Tile/PixelTile.ts +23 -0
- package/src/{PixelTile/PixelTilePool.ts → Tile/TilePool.ts} +9 -9
- package/src/Tile/_tile-types.ts +33 -0
- package/src/_errors.ts +1 -0
- package/src/_types.ts +2 -118
- package/src/index.ts +46 -21
- package/src/ImageData/imageDataToUInt32Array.ts +0 -13
- package/src/Internal/helpers.ts +0 -5
- package/src/Paint/makeCirclePaintAlphaMask.ts +0 -41
- package/src/Paint/makeCirclePaintBinaryMask.ts +0 -29
- package/src/PixelTile/PixelTile.ts +0 -21
- /package/src/{Internal → Rect}/resolveClipping.ts +0 -0
|
@@ -1,10 +1,5 @@
|
|
|
1
|
-
import { CANVAS_CTX_FAILED } from '
|
|
2
|
-
|
|
3
|
-
export type PixelCanvas = {
|
|
4
|
-
readonly canvas: HTMLCanvasElement,
|
|
5
|
-
readonly ctx: CanvasRenderingContext2D,
|
|
6
|
-
readonly resize: (w: number, h: number) => void
|
|
7
|
-
}
|
|
1
|
+
import { CANVAS_CTX_FAILED } from '../Internal/_errors'
|
|
2
|
+
import type { PixelCanvas } from './_canvas-types'
|
|
8
3
|
|
|
9
4
|
/**
|
|
10
5
|
* Ensures the canvas ctx is always set to imageSmoothingEnabled = false.
|
|
@@ -1,13 +1,5 @@
|
|
|
1
|
-
import { CANVAS_CTX_FAILED } from '
|
|
2
|
-
|
|
3
|
-
export type CanvasContext<T> = T extends HTMLCanvasElement
|
|
4
|
-
? CanvasRenderingContext2D
|
|
5
|
-
: OffscreenCanvasRenderingContext2D
|
|
6
|
-
|
|
7
|
-
export type ReusableCanvas<T extends HTMLCanvasElement | OffscreenCanvas> = {
|
|
8
|
-
readonly canvas: T
|
|
9
|
-
readonly ctx: CanvasContext<T>
|
|
10
|
-
}
|
|
1
|
+
import { CANVAS_CTX_FAILED } from '../Internal/_errors'
|
|
2
|
+
import type { CanvasContext, CanvasObjectFactory, ReusableCanvas, ReusableCanvasFactory } from './_canvas-types'
|
|
11
3
|
|
|
12
4
|
/**
|
|
13
5
|
* Creates a reusable HTMLCanvasElement and context that are not part of the DOM.
|
|
@@ -37,8 +29,8 @@ export function makeReusableOffscreenCanvas() {
|
|
|
37
29
|
}
|
|
38
30
|
|
|
39
31
|
function makeReusableCanvasMeta<T extends HTMLCanvasElement | OffscreenCanvas>(
|
|
40
|
-
factory:
|
|
41
|
-
) {
|
|
32
|
+
factory: CanvasObjectFactory<T>,
|
|
33
|
+
): ReusableCanvasFactory<T> {
|
|
42
34
|
let canvas: T | null = null
|
|
43
35
|
let ctx: CanvasContext<T> | null = null
|
|
44
36
|
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type CanvasContext<T> = T extends HTMLCanvasElement
|
|
2
|
+
? CanvasRenderingContext2D
|
|
3
|
+
: OffscreenCanvasRenderingContext2D
|
|
4
|
+
|
|
5
|
+
export interface ReusableCanvas<T extends HTMLCanvasElement | OffscreenCanvas> {
|
|
6
|
+
readonly canvas: T
|
|
7
|
+
readonly ctx: CanvasContext<T>
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export type ReusableCanvasFactory<T extends HTMLCanvasElement | OffscreenCanvas> = {
|
|
11
|
+
(w: number, h: number): ReusableCanvas<T>,
|
|
12
|
+
reset(): void
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export type DrawPixelLayer<T extends HTMLCanvasElement | OffscreenCanvas> =
|
|
16
|
+
(ctx: CanvasContext<T>) => void
|
|
17
|
+
|
|
18
|
+
export type DrawScreenLayer = (ctx: CanvasRenderingContext2D, scale: number) => void
|
|
19
|
+
|
|
20
|
+
export interface PixelCanvas {
|
|
21
|
+
readonly canvas: HTMLCanvasElement,
|
|
22
|
+
readonly ctx: CanvasRenderingContext2D,
|
|
23
|
+
readonly resize: (w: number, h: number) => void
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export type CanvasObjectFactory<T extends HTMLCanvasElement | OffscreenCanvas> = (w: number, h: number) => T
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { PixelTile } from '../
|
|
2
|
-
import type {
|
|
1
|
+
import type { PixelTile } from '../Tile/_tile-types'
|
|
2
|
+
import type { TilePool } from '../Tile/TilePool'
|
|
3
3
|
import type { PixelEngineConfig } from './PixelEngineConfig'
|
|
4
4
|
import { applyPatchTiles, type PixelPatchTiles } from './PixelPatchTiles'
|
|
5
5
|
|
|
@@ -11,15 +11,15 @@ export class PixelAccumulator {
|
|
|
11
11
|
|
|
12
12
|
constructor(
|
|
13
13
|
readonly config: PixelEngineConfig,
|
|
14
|
-
readonly
|
|
14
|
+
readonly pixelTilePool: TilePool<PixelTile>,
|
|
15
15
|
) {
|
|
16
16
|
this.lookup = []
|
|
17
17
|
this.beforeTiles = []
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
recyclePatch(patch: PixelPatchTiles) {
|
|
21
|
-
this.
|
|
22
|
-
this.
|
|
21
|
+
this.pixelTilePool.releaseTiles(patch.beforeTiles)
|
|
22
|
+
this.pixelTilePool.releaseTiles(patch.afterTiles)
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
/**
|
|
@@ -37,7 +37,7 @@ export class PixelAccumulator {
|
|
|
37
37
|
let added = false
|
|
38
38
|
|
|
39
39
|
if (!tile) {
|
|
40
|
-
tile = this.
|
|
40
|
+
tile = this.pixelTilePool.getTile(id, tx, ty)
|
|
41
41
|
|
|
42
42
|
this.extractState(tile)
|
|
43
43
|
this.lookup[id] = tile
|
|
@@ -49,7 +49,7 @@ export class PixelAccumulator {
|
|
|
49
49
|
if (!didChange && added) {
|
|
50
50
|
this.beforeTiles.pop()
|
|
51
51
|
this.lookup[id] = undefined
|
|
52
|
-
this.
|
|
52
|
+
this.pixelTilePool.releaseTile(tile!)
|
|
53
53
|
}
|
|
54
54
|
return didChange
|
|
55
55
|
}
|
|
@@ -83,7 +83,7 @@ export class PixelAccumulator {
|
|
|
83
83
|
let tile = this.lookup[id]
|
|
84
84
|
|
|
85
85
|
if (!tile) {
|
|
86
|
-
tile = this.
|
|
86
|
+
tile = this.pixelTilePool.getTile(id, tx, ty)
|
|
87
87
|
|
|
88
88
|
this.extractState(tile)
|
|
89
89
|
this.lookup[id] = tile
|
|
@@ -101,7 +101,7 @@ export class PixelAccumulator {
|
|
|
101
101
|
|
|
102
102
|
if (t) {
|
|
103
103
|
this.lookup[t.id] = undefined
|
|
104
|
-
this.
|
|
104
|
+
this.pixelTilePool.releaseTile(t)
|
|
105
105
|
}
|
|
106
106
|
}
|
|
107
107
|
|
|
@@ -116,7 +116,7 @@ export class PixelAccumulator {
|
|
|
116
116
|
let added = false
|
|
117
117
|
|
|
118
118
|
if (!tile) {
|
|
119
|
-
tile = this.
|
|
119
|
+
tile = this.pixelTilePool.getTile(id, tx, ty)
|
|
120
120
|
|
|
121
121
|
this.extractState(tile)
|
|
122
122
|
this.lookup[id] = tile
|
|
@@ -128,7 +128,7 @@ export class PixelAccumulator {
|
|
|
128
128
|
if (!didChange && added) {
|
|
129
129
|
this.beforeTiles.pop()
|
|
130
130
|
this.lookup[id] = undefined
|
|
131
|
-
this.
|
|
131
|
+
this.pixelTilePool.releaseTile(tile!)
|
|
132
132
|
}
|
|
133
133
|
return didChange
|
|
134
134
|
}
|
|
@@ -137,12 +137,12 @@ export class PixelAccumulator {
|
|
|
137
137
|
extractState(tile: PixelTile) {
|
|
138
138
|
const target = this.config.target
|
|
139
139
|
const TILE_SIZE = this.config.tileSize
|
|
140
|
-
const dst = tile.
|
|
141
|
-
const src = target.
|
|
140
|
+
const dst = tile.data
|
|
141
|
+
const src = target.data
|
|
142
142
|
const startX = tile.tx * TILE_SIZE
|
|
143
143
|
const startY = tile.ty * TILE_SIZE
|
|
144
|
-
const targetWidth = target.
|
|
145
|
-
const targetHeight = target.
|
|
144
|
+
const targetWidth = target.w
|
|
145
|
+
const targetHeight = target.h
|
|
146
146
|
|
|
147
147
|
// If the tile is completely outside the canvas, zero it out.
|
|
148
148
|
if (startX >= targetWidth || startX + TILE_SIZE <= 0 || startY >= targetHeight || startY + TILE_SIZE <= 0) {
|
|
@@ -190,7 +190,7 @@ export class PixelAccumulator {
|
|
|
190
190
|
let beforeTile = this.beforeTiles[i]
|
|
191
191
|
|
|
192
192
|
if (beforeTile) {
|
|
193
|
-
let afterTile = this.
|
|
193
|
+
let afterTile = this.pixelTilePool.getTile(beforeTile.id, beforeTile.tx, beforeTile.ty)
|
|
194
194
|
|
|
195
195
|
this.extractState(afterTile)
|
|
196
196
|
afterTiles.push(afterTile)
|
|
@@ -219,7 +219,7 @@ export class PixelAccumulator {
|
|
|
219
219
|
|
|
220
220
|
if (tile) {
|
|
221
221
|
this.lookup[tile.id] = undefined
|
|
222
|
-
this.
|
|
222
|
+
this.pixelTilePool.releaseTile(tile)
|
|
223
223
|
}
|
|
224
224
|
}
|
|
225
225
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { PixelData } from '../PixelData/
|
|
1
|
+
import type { PixelData } from '../PixelData/_pixelData-types'
|
|
2
2
|
|
|
3
3
|
export class PixelEngineConfig {
|
|
4
4
|
readonly tileSize: number
|
|
@@ -22,7 +22,7 @@ export class PixelEngineConfig {
|
|
|
22
22
|
this.tileMask = tileSize - 1
|
|
23
23
|
this.tileArea = tileSize * tileSize
|
|
24
24
|
this.target = target
|
|
25
|
-
this.targetColumns = (target.
|
|
26
|
-
this.targetRows = (target.
|
|
25
|
+
this.targetColumns = (target.w + this.tileMask) >> this.tileShift
|
|
26
|
+
this.targetRows = (target.h + this.tileMask) >> this.tileShift
|
|
27
27
|
}
|
|
28
28
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type ApplyMaskToPixelDataOptions } from '../../_types'
|
|
2
|
+
import type { AlphaMask } from '../../Mask/_mask-types'
|
|
2
3
|
import { applyAlphaMaskToPixelData } from '../../PixelData/applyAlphaMaskToPixelData'
|
|
3
4
|
import { type HistoryMutator, PixelWriter } from '../PixelWriter'
|
|
4
5
|
|
|
@@ -21,8 +22,8 @@ export const mutatorApplyAlphaMask = ((writer: PixelWriter<any>, deps: Deps = de
|
|
|
21
22
|
const target = writer.config.target
|
|
22
23
|
const x = opts?.x ?? 0
|
|
23
24
|
const y = opts?.y ?? 0
|
|
24
|
-
const w = opts?.w ?? target.
|
|
25
|
-
const h = opts?.h ?? target.
|
|
25
|
+
const w = opts?.w ?? target.w
|
|
26
|
+
const h = opts?.h ?? target.h
|
|
26
27
|
|
|
27
28
|
const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h)
|
|
28
29
|
return didChange(applyAlphaMaskToPixelData(target, mask, opts))
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { type ApplyMaskToPixelDataOptions
|
|
1
|
+
import { type ApplyMaskToPixelDataOptions } from '../../_types'
|
|
2
|
+
import type { BinaryMask } from '../../Mask/_mask-types'
|
|
2
3
|
import { applyBinaryMaskToPixelData } from '../../PixelData/applyBinaryMaskToPixelData'
|
|
3
4
|
import { type HistoryMutator, PixelWriter } from '../PixelWriter'
|
|
4
5
|
|
|
@@ -21,8 +22,8 @@ export const mutatorApplyBinaryMask = ((writer: PixelWriter<any>, deps: Deps = d
|
|
|
21
22
|
const target = writer.config.target
|
|
22
23
|
const x = opts?.x ?? 0
|
|
23
24
|
const y = opts?.y ?? 0
|
|
24
|
-
const w = opts?.w ?? target.
|
|
25
|
-
const h = opts?.h ?? target.
|
|
25
|
+
const w = opts?.w ?? target.w
|
|
26
|
+
const h = opts?.h ?? target.h
|
|
26
27
|
|
|
27
28
|
const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h)
|
|
28
29
|
return didChange(applyBinaryMaskToPixelData(target, mask, opts))
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { type ApplyMaskToPixelDataOptions
|
|
1
|
+
import { type ApplyMaskToPixelDataOptions } from '../../_types'
|
|
2
|
+
import { type Mask, MaskType } from '../../Mask/_mask-types'
|
|
2
3
|
import { applyAlphaMaskToPixelData } from '../../PixelData/applyAlphaMaskToPixelData'
|
|
3
4
|
import { applyBinaryMaskToPixelData } from '../../PixelData/applyBinaryMaskToPixelData'
|
|
4
5
|
import { type HistoryMutator, PixelWriter } from '../PixelWriter'
|
|
@@ -24,8 +25,8 @@ export const mutatorApplyMask = ((writer: PixelWriter<any>, deps: Deps = default
|
|
|
24
25
|
const target = writer.config.target
|
|
25
26
|
const x = opts?.x ?? 0
|
|
26
27
|
const y = opts?.y ?? 0
|
|
27
|
-
const w = opts?.w ?? target.
|
|
28
|
-
const h = opts?.h ?? target.
|
|
28
|
+
const w = opts?.w ?? target.w
|
|
29
|
+
const h = opts?.h ?? target.h
|
|
29
30
|
|
|
30
31
|
const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h)
|
|
31
32
|
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { PixelBlendMaskOptions } from '../../_types'
|
|
2
|
+
import type { AlphaMask } from '../../Mask/_mask-types'
|
|
3
|
+
import type { PixelData32 } from '../../PixelData/_pixelData-types'
|
|
2
4
|
import { blendPixelDataAlphaMask } from '../../PixelData/blendPixelDataAlphaMask'
|
|
3
5
|
import { type HistoryMutator, PixelWriter } from '../PixelWriter'
|
|
4
6
|
|
|
@@ -15,14 +17,14 @@ export const mutatorBlendAlphaMask = ((writer: PixelWriter<any>, deps: Partial<D
|
|
|
15
17
|
|
|
16
18
|
return {
|
|
17
19
|
blendAlphaMask(
|
|
18
|
-
src:
|
|
20
|
+
src: PixelData32,
|
|
19
21
|
mask: AlphaMask,
|
|
20
22
|
opts?: PixelBlendMaskOptions,
|
|
21
23
|
): boolean {
|
|
22
24
|
const x = opts?.x ?? 0
|
|
23
25
|
const y = opts?.y ?? 0
|
|
24
|
-
const w = opts?.w ?? src.
|
|
25
|
-
const h = opts?.h ?? src.
|
|
26
|
+
const w = opts?.w ?? src.w
|
|
27
|
+
const h = opts?.h ?? src.h
|
|
26
28
|
|
|
27
29
|
const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h)
|
|
28
30
|
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { PixelBlendMaskOptions } from '../../_types'
|
|
2
|
+
import type { BinaryMask } from '../../Mask/_mask-types'
|
|
3
|
+
import type { PixelData32 } from '../../PixelData/_pixelData-types'
|
|
2
4
|
import { blendPixelDataBinaryMask } from '../../PixelData/blendPixelDataBinaryMask'
|
|
3
5
|
import { type HistoryMutator, PixelWriter } from '../PixelWriter'
|
|
4
6
|
|
|
@@ -15,14 +17,14 @@ export const mutatorBlendBinaryMask = ((writer: PixelWriter<any>, deps: Partial<
|
|
|
15
17
|
|
|
16
18
|
return {
|
|
17
19
|
blendBinaryMask(
|
|
18
|
-
src:
|
|
20
|
+
src: PixelData32,
|
|
19
21
|
mask: BinaryMask,
|
|
20
22
|
opts?: PixelBlendMaskOptions,
|
|
21
23
|
): boolean {
|
|
22
24
|
const x = opts?.x ?? 0
|
|
23
25
|
const y = opts?.y ?? 0
|
|
24
|
-
const w = opts?.w ?? src.
|
|
25
|
-
const h = opts?.h ?? src.
|
|
26
|
+
const w = opts?.w ?? src.w
|
|
27
|
+
const h = opts?.h ?? src.h
|
|
26
28
|
|
|
27
29
|
const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h)
|
|
28
30
|
|
|
@@ -21,8 +21,8 @@ export const mutatorBlendColor = ((writer: PixelWriter<any>, deps: Deps = defaul
|
|
|
21
21
|
const target = writer.config.target
|
|
22
22
|
const x = opts?.x ?? 0
|
|
23
23
|
const y = opts?.y ?? 0
|
|
24
|
-
const w = opts?.w ?? target.
|
|
25
|
-
const h = opts?.h ?? target.
|
|
24
|
+
const w = opts?.w ?? target.w
|
|
25
|
+
const h = opts?.h ?? target.h
|
|
26
26
|
|
|
27
27
|
const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h)
|
|
28
28
|
return didChange(
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { type Color32
|
|
1
|
+
import { type Color32 } from '../../_types'
|
|
2
2
|
import { sourceOverPerfect } from '../../BlendModes/blend-modes-perfect'
|
|
3
|
+
import type { PaintAlphaMask } from '../../Paint/_paint-types'
|
|
3
4
|
import { blendColorPixelDataAlphaMask } from '../../PixelData/blendColorPixelDataAlphaMask'
|
|
4
5
|
import { type HistoryMutator, PixelWriter } from '../PixelWriter'
|
|
5
6
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { type Color32
|
|
1
|
+
import { type Color32 } from '../../_types'
|
|
2
2
|
import { sourceOverPerfect } from '../../BlendModes/blend-modes-perfect'
|
|
3
|
+
import type { PaintBinaryMask } from '../../Paint/_paint-types'
|
|
3
4
|
import { blendColorPixelDataBinaryMask } from '../../PixelData/blendColorPixelDataBinaryMask'
|
|
4
5
|
import { type HistoryMutator, PixelWriter } from '../PixelWriter'
|
|
5
6
|
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { type Color32
|
|
1
|
+
import { type Color32 } from '../../_types'
|
|
2
2
|
import { sourceOverPerfect } from '../../BlendModes/blend-modes-perfect'
|
|
3
|
+
import { MaskType } from '../../Mask/_mask-types'
|
|
4
|
+
import type { PaintMask } from '../../Paint/_paint-types'
|
|
3
5
|
import { blendColorPixelDataAlphaMask } from '../../PixelData/blendColorPixelDataAlphaMask'
|
|
4
6
|
import { blendColorPixelDataBinaryMask } from '../../PixelData/blendColorPixelDataBinaryMask'
|
|
5
7
|
import { type HistoryMutator, PixelWriter } from '../PixelWriter'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { BlendColor32, Color32 } from '../../_types'
|
|
2
2
|
import { sourceOverPerfect } from '../../BlendModes/blend-modes-perfect'
|
|
3
|
-
import { _macro_paintRectCenterOffset } from '../../Internal/
|
|
3
|
+
import { _macro_paintRectCenterOffset } from '../../Internal/macros'
|
|
4
4
|
import { blendColorPixelData } from '../../PixelData/blendColorPixelData'
|
|
5
5
|
import { type HistoryMutator, PixelWriter } from '../PixelWriter'
|
|
6
6
|
|
|
@@ -32,8 +32,8 @@ export const mutatorBlendColorPaintRect = ((writer: PixelWriter<any>, deps: Deps
|
|
|
32
32
|
): boolean {
|
|
33
33
|
const target = writer.config.target
|
|
34
34
|
|
|
35
|
-
const topLeftX = centerX +
|
|
36
|
-
const topLeftY = centerY +
|
|
35
|
+
const topLeftX = centerX + _macro_paintRectCenterOffset(brushWidth)
|
|
36
|
+
const topLeftY = centerY + _macro_paintRectCenterOffset(brushHeight)
|
|
37
37
|
|
|
38
38
|
OPTS.x = topLeftX
|
|
39
39
|
OPTS.y = topLeftY
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type PixelBlendMaskOptions } from '../../_types'
|
|
2
|
+
import { type Mask, MaskType } from '../../Mask/_mask-types'
|
|
3
|
+
import type { PixelData32 } from '../../PixelData/_pixelData-types'
|
|
2
4
|
import { blendPixelDataAlphaMask } from '../../PixelData/blendPixelDataAlphaMask'
|
|
3
5
|
import { blendPixelDataBinaryMask } from '../../PixelData/blendPixelDataBinaryMask'
|
|
4
6
|
import { type HistoryMutator, PixelWriter } from '../PixelWriter'
|
|
@@ -17,14 +19,14 @@ export const mutatorBlendMask = ((writer: PixelWriter<any>, deps: Partial<Deps>
|
|
|
17
19
|
|
|
18
20
|
return {
|
|
19
21
|
blendMask(
|
|
20
|
-
src:
|
|
22
|
+
src: PixelData32,
|
|
21
23
|
mask: Mask,
|
|
22
24
|
opts?: PixelBlendMaskOptions,
|
|
23
25
|
): boolean {
|
|
24
26
|
const x = opts?.x ?? 0
|
|
25
27
|
const y = opts?.y ?? 0
|
|
26
|
-
const w = opts?.w ?? src.
|
|
27
|
-
const h = opts?.h ?? src.
|
|
28
|
+
const w = opts?.w ?? src.w
|
|
29
|
+
const h = opts?.h ?? src.h
|
|
28
30
|
|
|
29
31
|
const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h)
|
|
30
32
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { PixelBlendOptions } from '../../_types'
|
|
2
|
+
import type { PixelData32 } from '../../PixelData/_pixelData-types'
|
|
2
3
|
import { blendPixelData } from '../../PixelData/blendPixelData'
|
|
3
4
|
import { type HistoryMutator, PixelWriter } from '../PixelWriter'
|
|
4
5
|
|
|
@@ -15,13 +16,13 @@ export const mutatorBlendPixelData = ((writer: PixelWriter<any>, deps: Partial<D
|
|
|
15
16
|
|
|
16
17
|
return {
|
|
17
18
|
blendPixelData(
|
|
18
|
-
src:
|
|
19
|
+
src: PixelData32,
|
|
19
20
|
opts?: PixelBlendOptions,
|
|
20
21
|
): boolean {
|
|
21
22
|
const x = opts?.x ?? 0
|
|
22
23
|
const y = opts?.y ?? 0
|
|
23
|
-
const w = opts?.w ?? src.
|
|
24
|
-
const h = opts?.h ?? src.
|
|
24
|
+
const w = opts?.w ?? src.w
|
|
25
|
+
const h = opts?.h ?? src.h
|
|
25
26
|
|
|
26
27
|
const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h)
|
|
27
28
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type { Color32
|
|
1
|
+
import type { Color32 } from '../../_types'
|
|
2
2
|
import { fillPixelData } from '../../PixelData/fillPixelData'
|
|
3
|
+
import type { Rect } from '../../Rect/_rect-types'
|
|
3
4
|
import { type HistoryMutator, PixelWriter } from '../PixelWriter'
|
|
4
5
|
|
|
5
6
|
const defaults = { fillPixelData }
|
|
@@ -21,8 +22,8 @@ export const mutatorClear = ((writer: PixelWriter<any>, deps: Deps = defaults) =
|
|
|
21
22
|
const target = writer.config.target
|
|
22
23
|
const x = rect?.x ?? 0
|
|
23
24
|
const y = rect?.y ?? 0
|
|
24
|
-
const w = rect?.w ?? target.
|
|
25
|
-
const h = rect?.h ?? target.
|
|
25
|
+
const w = rect?.w ?? target.w
|
|
26
|
+
const h = rect?.h ?? target.h
|
|
26
27
|
|
|
27
28
|
const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h)
|
|
28
29
|
return didChange(
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type { Color32
|
|
1
|
+
import type { Color32 } from '../../_types'
|
|
2
2
|
import { fillPixelData } from '../../PixelData/fillPixelData'
|
|
3
|
+
import type { Rect } from '../../Rect/_rect-types'
|
|
3
4
|
import { type HistoryMutator, PixelWriter } from '../PixelWriter'
|
|
4
5
|
|
|
5
6
|
const defaults = { fillPixelData }
|
|
@@ -18,8 +19,8 @@ export const mutatorFill = ((writer: PixelWriter<any>, deps: Deps = defaults) =>
|
|
|
18
19
|
color: Color32,
|
|
19
20
|
x = 0,
|
|
20
21
|
y = 0,
|
|
21
|
-
w = writer.config.target.
|
|
22
|
-
h = writer.config.target.
|
|
22
|
+
w = writer.config.target.w,
|
|
23
|
+
h = writer.config.target.h,
|
|
23
24
|
) {
|
|
24
25
|
const target = writer.config.target
|
|
25
26
|
|
|
@@ -48,7 +49,7 @@ export const mutatorFillRect = ((writer: PixelWriter<any>, deps: Deps = defaults
|
|
|
48
49
|
|
|
49
50
|
const didChange = writer.accumulator.storeRegionBeforeState(rect.x, rect.y, rect.w, rect.h)
|
|
50
51
|
return didChange(
|
|
51
|
-
fillPixelData(target, color, rect.x, rect.y, rect.w, rect.h)
|
|
52
|
+
fillPixelData(target, color, rect.x, rect.y, rect.w, rect.h),
|
|
52
53
|
)
|
|
53
54
|
},
|
|
54
55
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Color32 } from '../../_types'
|
|
2
|
+
import type { BinaryMask } from '../../Mask/_mask-types'
|
|
2
3
|
import { fillPixelDataBinaryMask } from '../../PixelData/fillPixelDataBinaryMask'
|
|
3
4
|
import { type HistoryMutator, PixelWriter } from '../PixelWriter'
|
|
4
5
|
|
|
@@ -18,8 +18,8 @@ export const mutatorInvert = ((writer: PixelWriter<any>, deps: Deps = defaults)
|
|
|
18
18
|
const target = writer.config.target
|
|
19
19
|
const x = opts?.x ?? 0
|
|
20
20
|
const y = opts?.y ?? 0
|
|
21
|
-
const w = opts?.w ?? target.
|
|
22
|
-
const h = opts?.h ?? target.
|
|
21
|
+
const w = opts?.w ?? target.w
|
|
22
|
+
const h = opts?.h ?? target.h
|
|
23
23
|
|
|
24
24
|
const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h)
|
|
25
25
|
|
|
@@ -7,8 +7,8 @@ import { mutatorBlendColor } from './PixelMutator/mutatorBlendColor'
|
|
|
7
7
|
import { mutatorBlendColorPaintAlphaMask } from './PixelMutator/mutatorBlendColorPaintAlphaMask'
|
|
8
8
|
import { mutatorBlendColorPaintBinaryMask } from './PixelMutator/mutatorBlendColorPaintBinaryMask'
|
|
9
9
|
import { mutatorBlendColorPaintMask } from './PixelMutator/mutatorBlendColorPaintMask'
|
|
10
|
-
import { mutatorBlendMask } from './PixelMutator/mutatorBlendMask'
|
|
11
10
|
import { mutatorBlendColorPaintRect } from './PixelMutator/mutatorBlendColorPaintRect'
|
|
11
|
+
import { mutatorBlendMask } from './PixelMutator/mutatorBlendMask'
|
|
12
12
|
import { mutatorBlendPixel } from './PixelMutator/mutatorBlendPixel'
|
|
13
13
|
import { mutatorBlendPixelData } from './PixelMutator/mutatorBlendPixelData'
|
|
14
14
|
import { mutatorClear } from './PixelMutator/mutatorClear'
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import { PixelTile } from '../
|
|
1
|
+
import type { PixelData32 } from '../PixelData/_pixelData-types'
|
|
2
|
+
import type { PixelTile } from '../Tile/_tile-types'
|
|
3
3
|
|
|
4
4
|
export type PixelPatchTiles = {
|
|
5
5
|
beforeTiles: PixelTile[]
|
|
6
6
|
afterTiles: PixelTile[]
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
export function applyPatchTiles(target:
|
|
9
|
+
export function applyPatchTiles(target: PixelData32, tiles: PixelTile[], tileSize: number) {
|
|
10
10
|
for (let i = 0; i < tiles.length; i++) {
|
|
11
11
|
const tile = tiles[i]
|
|
12
12
|
|
|
13
13
|
if (!tile) continue
|
|
14
14
|
|
|
15
|
-
const dst = target.
|
|
16
|
-
const src = tile.
|
|
17
|
-
const dstWidth = target.
|
|
18
|
-
const dstHeight = target.
|
|
15
|
+
const dst = target.data
|
|
16
|
+
const src = tile.data
|
|
17
|
+
const dstWidth = target.w
|
|
18
|
+
const dstHeight = target.h
|
|
19
19
|
const startX = tile.tx * tileSize
|
|
20
20
|
const startY = tile.ty * tileSize
|
|
21
21
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { sourceOverPerfect } from '../BlendModes/blend-modes-perfect'
|
|
2
1
|
import { resizeImageData } from '../ImageData/resizeImageData'
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import type {
|
|
6
|
-
import {
|
|
2
|
+
import type { PixelData } from '../PixelData/_pixelData-types'
|
|
3
|
+
import { setPixelData } from '../PixelData/PixelData'
|
|
4
|
+
import type { PixelTile } from '../Tile/_tile-types'
|
|
5
|
+
import { makePixelTile } from '../Tile/PixelTile'
|
|
6
|
+
import { TilePool } from '../Tile/TilePool'
|
|
7
7
|
import { type HistoryActionFactory, makeHistoryAction } from './HistoryAction'
|
|
8
8
|
import { HistoryManager } from './HistoryManager'
|
|
9
9
|
import { PixelAccumulator } from './PixelAccumulator'
|
|
@@ -14,7 +14,7 @@ export interface PixelWriterOptions {
|
|
|
14
14
|
tileSize?: number
|
|
15
15
|
historyManager?: HistoryManager
|
|
16
16
|
historyActionFactory?: HistoryActionFactory
|
|
17
|
-
pixelTilePool?:
|
|
17
|
+
pixelTilePool?: TilePool<PixelTile>,
|
|
18
18
|
accumulator?: PixelAccumulator
|
|
19
19
|
}
|
|
20
20
|
|
|
@@ -44,19 +44,9 @@ export class PixelWriter<M> {
|
|
|
44
44
|
readonly accumulator: PixelAccumulator
|
|
45
45
|
readonly historyActionFactory: HistoryActionFactory
|
|
46
46
|
readonly config: PixelEngineConfig
|
|
47
|
-
readonly pixelTilePool:
|
|
48
|
-
readonly paintBuffer: PaintBuffer
|
|
47
|
+
readonly pixelTilePool: TilePool<PixelTile>
|
|
49
48
|
readonly mutator: M
|
|
50
49
|
|
|
51
|
-
private blendPixelDataOpts = {
|
|
52
|
-
alpha: 255,
|
|
53
|
-
blendFn: sourceOverPerfect,
|
|
54
|
-
x: 0,
|
|
55
|
-
y: 0,
|
|
56
|
-
w: 0,
|
|
57
|
-
h: 0,
|
|
58
|
-
}
|
|
59
|
-
|
|
60
50
|
private _inProgress = false
|
|
61
51
|
|
|
62
52
|
constructor(target: PixelData, mutatorFactory: (writer: PixelWriter<any>) => M, options?: PixelWriterOptions) {
|
|
@@ -66,10 +56,9 @@ export class PixelWriter<M> {
|
|
|
66
56
|
this.config = new PixelEngineConfig(tileSize, target)
|
|
67
57
|
this.historyManager = options?.historyManager ?? new HistoryManager(maxHistorySteps)
|
|
68
58
|
this.historyActionFactory = options?.historyActionFactory ?? makeHistoryAction
|
|
69
|
-
this.pixelTilePool = options?.pixelTilePool ?? new
|
|
59
|
+
this.pixelTilePool = options?.pixelTilePool ?? new TilePool(this.config, makePixelTile)
|
|
70
60
|
this.accumulator = options?.accumulator ?? new PixelAccumulator(this.config, this.pixelTilePool)
|
|
71
61
|
this.mutator = mutatorFactory(this)
|
|
72
|
-
this.paintBuffer = new PaintBuffer(this.config, this.pixelTilePool)
|
|
73
62
|
}
|
|
74
63
|
|
|
75
64
|
/**
|
|
@@ -139,62 +128,22 @@ export class PixelWriter<M> {
|
|
|
139
128
|
const beforeImageData = target.imageData
|
|
140
129
|
const afterImageData = resizeImageDataFn(beforeImageData, newWidth, newHeight, offsetX, offsetY)
|
|
141
130
|
|
|
142
|
-
target
|
|
131
|
+
setPixelData(target, afterImageData)
|
|
143
132
|
|
|
144
133
|
this.historyManager.commit({
|
|
145
134
|
undo: () => {
|
|
146
|
-
target
|
|
135
|
+
setPixelData(target, beforeImageData)
|
|
147
136
|
afterUndo?.(beforeImageData)
|
|
148
137
|
after?.(beforeImageData)
|
|
149
138
|
},
|
|
150
139
|
redo: () => {
|
|
151
|
-
target
|
|
140
|
+
setPixelData(target, afterImageData)
|
|
152
141
|
afterRedo?.(afterImageData)
|
|
153
142
|
after?.(afterImageData)
|
|
154
143
|
},
|
|
155
144
|
})
|
|
156
145
|
}
|
|
157
|
-
|
|
158
|
-
commitPaintBuffer(
|
|
159
|
-
alpha = 255,
|
|
160
|
-
blendFn = sourceOverPerfect,
|
|
161
|
-
blendPixelDataFn = blendPixelData,
|
|
162
|
-
) {
|
|
163
|
-
const paintBuffer = this.paintBuffer
|
|
164
|
-
const tileShift = paintBuffer.config.tileShift
|
|
165
|
-
const lookup = paintBuffer.lookup
|
|
166
|
-
|
|
167
|
-
const opts = this.blendPixelDataOpts
|
|
168
|
-
|
|
169
|
-
opts.alpha = alpha
|
|
170
|
-
opts.blendFn = blendFn
|
|
171
|
-
|
|
172
|
-
for (let i = 0; i < lookup.length; i++) {
|
|
173
|
-
const tile = lookup[i]
|
|
174
|
-
|
|
175
|
-
if (tile) {
|
|
176
|
-
const didChange = this.accumulator.storeTileBeforeState(tile.id, tile.tx, tile.ty)
|
|
177
|
-
|
|
178
|
-
const dx = tile.tx << tileShift
|
|
179
|
-
const dy = tile.ty << tileShift
|
|
180
|
-
|
|
181
|
-
opts.x = dx
|
|
182
|
-
opts.y = dy
|
|
183
|
-
opts.w = tile.width
|
|
184
|
-
opts.h = tile.height
|
|
185
|
-
|
|
186
|
-
didChange(
|
|
187
|
-
blendPixelDataFn(
|
|
188
|
-
this.config.target,
|
|
189
|
-
tile,
|
|
190
|
-
opts,
|
|
191
|
-
),
|
|
192
|
-
)
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
paintBuffer.clear()
|
|
197
|
-
}
|
|
198
146
|
}
|
|
199
147
|
|
|
200
148
|
export type HistoryMutator<T extends {}, D extends {}> = (writer: PixelWriter<any>, deps?: Partial<D>) => T
|
|
149
|
+
|