pixel-data-js 0.25.2 → 0.26.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 +1696 -1526
- package/dist/index.prod.cjs.map +1 -1
- package/dist/index.prod.d.ts +414 -311
- package/dist/index.prod.js +1676 -1519
- package/dist/index.prod.js.map +1 -1
- package/package.json +8 -9
- package/src/Algorithm/floodFillSelection.ts +49 -80
- package/src/Canvas/PixelCanvas.ts +1 -1
- package/src/Canvas/ReusableCanvas.ts +1 -1
- package/src/History/HistoryAction.ts +6 -5
- package/src/History/PixelMutator/mutatorApplyAlphaMask.ts +8 -10
- package/src/History/PixelMutator/mutatorApplyBinaryMask.ts +8 -10
- package/src/History/PixelMutator/mutatorApplyMask.ts +39 -0
- package/src/History/PixelMutator/{mutatorBlendPixelDataAlphaMask.ts → mutatorBlendAlphaMask.ts} +9 -9
- package/src/History/PixelMutator/{mutatorBlendPixelDataBinaryMask.ts → mutatorBlendBinaryMask.ts} +9 -9
- package/src/History/PixelMutator/mutatorBlendColor.ts +8 -9
- package/src/History/PixelMutator/mutatorBlendColorPaintAlphaMask.ts +51 -0
- package/src/History/PixelMutator/mutatorBlendColorPaintBinaryMask.ts +51 -0
- package/src/History/PixelMutator/{mutatorBlendPaintMask.ts → mutatorBlendColorPaintMask.ts} +3 -3
- package/src/History/PixelMutator/mutatorBlendMask.ts +43 -0
- package/src/History/PixelMutator/mutatorBlendPaintRect.ts +55 -0
- package/src/History/PixelMutator/mutatorBlendPixel.ts +2 -2
- package/src/History/PixelMutator/mutatorBlendPixelData.ts +8 -9
- package/src/History/PixelMutator/mutatorClear.ts +13 -11
- package/src/History/PixelMutator/mutatorFill.ts +2 -2
- package/src/History/PixelMutator/mutatorFillBinaryMask.ts +3 -4
- package/src/History/PixelMutator/mutatorInvert.ts +8 -9
- package/src/History/PixelMutator.ts +20 -4
- package/src/History/PixelWriter.ts +11 -13
- package/src/Input/fileToImageData.ts +1 -1
- package/src/Internal/helpers.ts +4 -1
- package/src/Mask/applyBinaryMaskToAlphaMask.ts +8 -10
- package/src/Paint/PaintBuffer.ts +3 -3
- package/src/Paint/PaintBufferCanvasRenderer.ts +1 -1
- package/src/Paint/makePaintMask.ts +5 -5
- package/src/Paint/makeRectFalloffPaintAlphaMask.ts +3 -3
- package/src/PixelData/applyAlphaMaskToPixelData.ts +14 -16
- package/src/PixelData/applyBinaryMaskToPixelData.ts +14 -16
- package/src/PixelData/applyMaskToPixelData.ts +22 -0
- package/src/PixelData/blendColorPixelData.ts +12 -15
- package/src/PixelData/blendColorPixelDataAlphaMask.ts +16 -16
- package/src/PixelData/blendColorPixelDataBinaryMask.ts +16 -16
- package/src/PixelData/blendColorPixelDataMask.ts +16 -0
- package/src/PixelData/blendColorPixelDataPaintAlphaMask.ts +30 -0
- package/src/PixelData/blendColorPixelDataPaintBinaryMask.ts +30 -0
- package/src/PixelData/blendColorPixelDataPaintMask.ts +35 -0
- package/src/PixelData/blendPixelData.ts +14 -16
- package/src/PixelData/blendPixelDataAlphaMask.ts +17 -19
- package/src/PixelData/blendPixelDataBinaryMask.ts +17 -19
- package/src/PixelData/blendPixelDataMask.ts +16 -0
- package/src/PixelData/blendPixelDataPaintBuffer.ts +1 -1
- package/src/PixelData/{clearPixelData.ts → clearPixelDataFast.ts} +2 -2
- package/src/PixelData/fillPixelDataBinaryMask.ts +8 -22
- package/src/PixelData/fillPixelDataFast.ts +2 -2
- package/src/PixelData/invertPixelData.ts +13 -16
- package/src/_types.ts +8 -7
- package/src/index.ts +41 -31
- package/dist/index.dev.cjs +0 -5419
- package/dist/index.dev.cjs.map +0 -1
- package/dist/index.dev.js +0 -5208
- package/dist/index.dev.js.map +0 -1
- package/src/Canvas/_constants.ts +0 -2
- package/src/PixelData/PixelBuffer32.ts +0 -28
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { BlendColor32, Color32 } from '../../_types'
|
|
2
|
+
import { sourceOverPerfect } from '../../BlendModes/blend-modes-perfect'
|
|
3
|
+
import { _macro_paintRectCenterOffset } from '../../Internal/helpers'
|
|
4
|
+
import { blendColorPixelData } from '../../PixelData/blendColorPixelData'
|
|
5
|
+
import { type HistoryMutator, PixelWriter } from '../PixelWriter'
|
|
6
|
+
|
|
7
|
+
const defaults = {
|
|
8
|
+
blendColorPixelData,
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
type Deps = Partial<typeof defaults>
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @param deps - @hidden
|
|
15
|
+
*/
|
|
16
|
+
export const mutatorBlendPaintRect = ((writer: PixelWriter<any>, deps: Deps = defaults) => {
|
|
17
|
+
const {
|
|
18
|
+
blendColorPixelData = defaults.blendColorPixelData,
|
|
19
|
+
} = deps
|
|
20
|
+
|
|
21
|
+
const OPTS = { x: 0, y: 0, w: 0, h: 0, blendFn: sourceOverPerfect, alpha: 255 }
|
|
22
|
+
|
|
23
|
+
return {
|
|
24
|
+
blendPaintRect(
|
|
25
|
+
color: Color32,
|
|
26
|
+
centerX: number,
|
|
27
|
+
centerY: number,
|
|
28
|
+
brushWidth: number,
|
|
29
|
+
brushHeight: number,
|
|
30
|
+
alpha = 255,
|
|
31
|
+
blendFn: BlendColor32 = sourceOverPerfect,
|
|
32
|
+
): boolean {
|
|
33
|
+
const target = writer.config.target
|
|
34
|
+
|
|
35
|
+
const topLeftX = centerX + -_macro_paintRectCenterOffset(brushWidth)
|
|
36
|
+
const topLeftY = centerY + -_macro_paintRectCenterOffset(brushHeight)
|
|
37
|
+
|
|
38
|
+
OPTS.x = topLeftX
|
|
39
|
+
OPTS.y = topLeftY
|
|
40
|
+
OPTS.w = brushWidth
|
|
41
|
+
OPTS.h = brushHeight
|
|
42
|
+
OPTS.blendFn = blendFn
|
|
43
|
+
OPTS.alpha = alpha
|
|
44
|
+
|
|
45
|
+
const didChange = writer.accumulator.storeRegionBeforeState(topLeftX, topLeftY, brushWidth, brushHeight)
|
|
46
|
+
return didChange(
|
|
47
|
+
blendColorPixelData(
|
|
48
|
+
target,
|
|
49
|
+
color,
|
|
50
|
+
OPTS,
|
|
51
|
+
),
|
|
52
|
+
)
|
|
53
|
+
},
|
|
54
|
+
}
|
|
55
|
+
}) satisfies HistoryMutator<any, Deps>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { BlendColor32, Color32
|
|
1
|
+
import type { BlendColor32, Color32 } from '../../_types'
|
|
2
2
|
import { blendPixel } from '../../PixelData/blendPixel'
|
|
3
|
-
import { PixelWriter } from '../PixelWriter'
|
|
3
|
+
import { type HistoryMutator, PixelWriter } from '../PixelWriter'
|
|
4
4
|
|
|
5
5
|
const defaults = { blendPixel }
|
|
6
6
|
type Deps = Partial<typeof defaults>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { IPixelData32, PixelBlendOptions } from '../../_types'
|
|
2
2
|
import { blendPixelData } from '../../PixelData/blendPixelData'
|
|
3
|
-
import { PixelWriter } from '../PixelWriter'
|
|
3
|
+
import { type HistoryMutator, PixelWriter } from '../PixelWriter'
|
|
4
4
|
|
|
5
5
|
const defaults = { blendPixelData }
|
|
6
6
|
type Deps = Partial<typeof defaults>
|
|
@@ -16,14 +16,13 @@ export const mutatorBlendPixelData = ((writer: PixelWriter<any>, deps: Partial<D
|
|
|
16
16
|
return {
|
|
17
17
|
blendPixelData(
|
|
18
18
|
src: IPixelData32,
|
|
19
|
-
opts
|
|
19
|
+
opts?: PixelBlendOptions,
|
|
20
20
|
): boolean {
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
} = opts
|
|
21
|
+
const x = opts?.x ?? 0
|
|
22
|
+
const y = opts?.y ?? 0
|
|
23
|
+
const w = opts?.w ?? src.width
|
|
24
|
+
const h = opts?.h ?? src.height
|
|
25
|
+
|
|
27
26
|
const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h)
|
|
28
27
|
|
|
29
28
|
return didChange(
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { Color32,
|
|
2
|
-
import {
|
|
3
|
-
import { PixelWriter } from '../PixelWriter'
|
|
1
|
+
import type { Color32, Rect } from '../../_types'
|
|
2
|
+
import { fillPixelData } from '../../PixelData/fillPixelData'
|
|
3
|
+
import { type HistoryMutator, PixelWriter } from '../PixelWriter'
|
|
4
4
|
|
|
5
|
-
const defaults = { fillPixelData
|
|
5
|
+
const defaults = { fillPixelData }
|
|
6
6
|
|
|
7
7
|
type Deps = Partial<typeof defaults>
|
|
8
8
|
|
|
@@ -16,16 +16,18 @@ export const mutatorClear = ((writer: PixelWriter<any>, deps: Deps = defaults) =
|
|
|
16
16
|
|
|
17
17
|
return {
|
|
18
18
|
clear(
|
|
19
|
-
rect
|
|
19
|
+
rect?: Partial<Rect>,
|
|
20
20
|
) {
|
|
21
21
|
const target = writer.config.target
|
|
22
|
-
const x = rect
|
|
23
|
-
const y = rect
|
|
24
|
-
const w = rect
|
|
25
|
-
const h = rect
|
|
22
|
+
const x = rect?.x ?? 0
|
|
23
|
+
const y = rect?.y ?? 0
|
|
24
|
+
const w = rect?.w ?? target.width
|
|
25
|
+
const h = rect?.h ?? target.height
|
|
26
26
|
|
|
27
|
-
writer.accumulator.storeRegionBeforeState(x, y, w, h)
|
|
28
|
-
|
|
27
|
+
const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h)
|
|
28
|
+
return didChange(
|
|
29
|
+
fillPixelData(target, 0 as Color32, x, y, w, h),
|
|
30
|
+
)
|
|
29
31
|
},
|
|
30
32
|
}
|
|
31
33
|
}) satisfies HistoryMutator<any, Deps>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { Color32,
|
|
1
|
+
import type { Color32, Rect } from '../../_types'
|
|
2
2
|
import { fillPixelData } from '../../PixelData/fillPixelData'
|
|
3
|
-
import { PixelWriter } from '../PixelWriter'
|
|
3
|
+
import { type HistoryMutator, PixelWriter } from '../PixelWriter'
|
|
4
4
|
|
|
5
5
|
const defaults = { fillPixelData }
|
|
6
6
|
type Deps = Partial<typeof defaults>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { BinaryMask, Color32
|
|
1
|
+
import type { BinaryMask, Color32 } from '../../_types'
|
|
2
2
|
import { fillPixelDataBinaryMask } from '../../PixelData/fillPixelDataBinaryMask'
|
|
3
|
-
import { PixelWriter } from '../PixelWriter'
|
|
3
|
+
import { type HistoryMutator, PixelWriter } from '../PixelWriter'
|
|
4
4
|
|
|
5
5
|
const defaults = { fillPixelDataBinaryMask }
|
|
6
6
|
type Deps = Partial<typeof defaults>
|
|
@@ -17,13 +17,12 @@ export const mutatorFillBinaryMask = ((writer: PixelWriter<any>, deps: Deps = de
|
|
|
17
17
|
fillBinaryMask(
|
|
18
18
|
color: Color32,
|
|
19
19
|
mask: BinaryMask,
|
|
20
|
-
alpha = 255,
|
|
21
20
|
x = 0,
|
|
22
21
|
y = 0,
|
|
23
22
|
) {
|
|
24
23
|
const didChange = writer.accumulator.storeRegionBeforeState(x, y, mask.w, mask.h)
|
|
25
24
|
return didChange(
|
|
26
|
-
fillPixelDataBinaryMask(writer.config.target, color, mask,
|
|
25
|
+
fillPixelDataBinaryMask(writer.config.target, color, mask, x, y),
|
|
27
26
|
)
|
|
28
27
|
},
|
|
29
28
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { PixelMutateOptions } from '../../_types'
|
|
2
2
|
import { invertPixelData } from '../../PixelData/invertPixelData'
|
|
3
|
-
import { PixelWriter } from '../PixelWriter'
|
|
3
|
+
import { type HistoryMutator, PixelWriter } from '../PixelWriter'
|
|
4
4
|
|
|
5
5
|
const defaults = { invertPixelData }
|
|
6
6
|
type Deps = Partial<typeof defaults>
|
|
@@ -14,14 +14,13 @@ export const mutatorInvert = ((writer: PixelWriter<any>, deps: Deps = defaults)
|
|
|
14
14
|
} = deps
|
|
15
15
|
|
|
16
16
|
return {
|
|
17
|
-
invert(opts
|
|
17
|
+
invert(opts?: PixelMutateOptions) {
|
|
18
18
|
const target = writer.config.target
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
} = opts
|
|
19
|
+
const x = opts?.x ?? 0
|
|
20
|
+
const y = opts?.y ?? 0
|
|
21
|
+
const w = opts?.w ?? target.width
|
|
22
|
+
const h = opts?.h ?? target.height
|
|
23
|
+
|
|
25
24
|
const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h)
|
|
26
25
|
|
|
27
26
|
return didChange(
|
|
@@ -1,8 +1,16 @@
|
|
|
1
|
+
import { mutatorApplyAlphaMask } from './PixelMutator/mutatorApplyAlphaMask'
|
|
2
|
+
import { mutatorApplyBinaryMask } from './PixelMutator/mutatorApplyBinaryMask'
|
|
3
|
+
import { mutatorApplyMask } from './PixelMutator/mutatorApplyMask'
|
|
4
|
+
import { mutatorBlendAlphaMask } from './PixelMutator/mutatorBlendAlphaMask'
|
|
5
|
+
import { mutatorBlendBinaryMask } from './PixelMutator/mutatorBlendBinaryMask'
|
|
1
6
|
import { mutatorBlendColor } from './PixelMutator/mutatorBlendColor'
|
|
7
|
+
import { mutatorBlendColorPaintAlphaMask } from './PixelMutator/mutatorBlendColorPaintAlphaMask'
|
|
8
|
+
import { mutatorBlendColorPaintBinaryMask } from './PixelMutator/mutatorBlendColorPaintBinaryMask'
|
|
9
|
+
import { mutatorBlendColorPaintMask } from './PixelMutator/mutatorBlendColorPaintMask'
|
|
10
|
+
import { mutatorBlendMask } from './PixelMutator/mutatorBlendMask'
|
|
11
|
+
import { mutatorBlendPaintRect } from './PixelMutator/mutatorBlendPaintRect'
|
|
2
12
|
import { mutatorBlendPixel } from './PixelMutator/mutatorBlendPixel'
|
|
3
13
|
import { mutatorBlendPixelData } from './PixelMutator/mutatorBlendPixelData'
|
|
4
|
-
import { mutatorBlendPixelDataAlphaMask } from './PixelMutator/mutatorBlendPixelDataAlphaMask'
|
|
5
|
-
import { mutatorBlendPixelDataBinaryMask } from './PixelMutator/mutatorBlendPixelDataBinaryMask'
|
|
6
14
|
import { mutatorClear } from './PixelMutator/mutatorClear'
|
|
7
15
|
import { mutatorFill, mutatorFillRect } from './PixelMutator/mutatorFill'
|
|
8
16
|
import { mutatorFillBinaryMask } from './PixelMutator/mutatorFillBinaryMask'
|
|
@@ -12,11 +20,19 @@ import type { PixelWriter } from './PixelWriter'
|
|
|
12
20
|
export function makeFullPixelMutator(writer: PixelWriter<any>) {
|
|
13
21
|
return {
|
|
14
22
|
// @sort
|
|
23
|
+
...mutatorApplyAlphaMask(writer),
|
|
24
|
+
...mutatorApplyBinaryMask(writer),
|
|
25
|
+
...mutatorApplyMask(writer),
|
|
26
|
+
...mutatorBlendAlphaMask(writer),
|
|
27
|
+
...mutatorBlendBinaryMask(writer),
|
|
15
28
|
...mutatorBlendColor(writer),
|
|
29
|
+
...mutatorBlendColorPaintAlphaMask(writer),
|
|
30
|
+
...mutatorBlendColorPaintBinaryMask(writer),
|
|
31
|
+
...mutatorBlendColorPaintMask(writer),
|
|
32
|
+
...mutatorBlendMask(writer),
|
|
33
|
+
...mutatorBlendPaintRect(writer),
|
|
16
34
|
...mutatorBlendPixel(writer),
|
|
17
35
|
...mutatorBlendPixelData(writer),
|
|
18
|
-
...mutatorBlendPixelDataAlphaMask(writer),
|
|
19
|
-
...mutatorBlendPixelDataBinaryMask(writer),
|
|
20
36
|
...mutatorClear(writer),
|
|
21
37
|
...mutatorFill(writer),
|
|
22
38
|
...mutatorFillBinaryMask(writer),
|
|
@@ -59,19 +59,15 @@ export class PixelWriter<M> {
|
|
|
59
59
|
|
|
60
60
|
private _inProgress = false
|
|
61
61
|
|
|
62
|
-
constructor(target: PixelData, mutatorFactory: (writer: PixelWriter<any>) => M, {
|
|
63
|
-
tileSize = 256
|
|
64
|
-
maxHistorySteps = 50
|
|
65
|
-
|
|
66
|
-
historyActionFactory = makeHistoryAction,
|
|
67
|
-
pixelTilePool,
|
|
68
|
-
accumulator,
|
|
69
|
-
}: PixelWriterOptions = {}) {
|
|
62
|
+
constructor(target: PixelData, mutatorFactory: (writer: PixelWriter<any>) => M, options?: PixelWriterOptions) {
|
|
63
|
+
const tileSize = options?.tileSize ?? 256
|
|
64
|
+
const maxHistorySteps = options?.maxHistorySteps ?? 50
|
|
65
|
+
|
|
70
66
|
this.config = new PixelEngineConfig(tileSize, target)
|
|
71
|
-
this.historyManager = historyManager
|
|
72
|
-
this.
|
|
73
|
-
this.
|
|
74
|
-
this.
|
|
67
|
+
this.historyManager = options?.historyManager ?? new HistoryManager(maxHistorySteps)
|
|
68
|
+
this.historyActionFactory = options?.historyActionFactory ?? makeHistoryAction
|
|
69
|
+
this.pixelTilePool = options?.pixelTilePool ?? new PixelTilePool(this.config)
|
|
70
|
+
this.accumulator = options?.accumulator ?? new PixelAccumulator(this.config, this.pixelTilePool)
|
|
75
71
|
this.mutator = mutatorFactory(this)
|
|
76
72
|
this.paintBuffer = new PaintBuffer(this.config, this.pixelTilePool)
|
|
77
73
|
}
|
|
@@ -115,7 +111,7 @@ export class PixelWriter<M> {
|
|
|
115
111
|
if (this.accumulator.beforeTiles.length === 0) return
|
|
116
112
|
|
|
117
113
|
const patch = this.accumulator.extractPatch()
|
|
118
|
-
const action = this.historyActionFactory(this, patch, after, afterUndo, afterRedo)
|
|
114
|
+
const action = this.historyActionFactory(this.config, this.accumulator, patch, after, afterUndo, afterRedo)
|
|
119
115
|
|
|
120
116
|
this.historyManager.commit(action)
|
|
121
117
|
}
|
|
@@ -200,3 +196,5 @@ export class PixelWriter<M> {
|
|
|
200
196
|
paintBuffer.clear()
|
|
201
197
|
}
|
|
202
198
|
}
|
|
199
|
+
|
|
200
|
+
export type HistoryMutator<T extends {}, D extends {}> = (writer: PixelWriter<any>, deps?: Partial<D>) => T
|
package/src/Internal/helpers.ts
CHANGED
|
@@ -3,17 +3,15 @@ import type { AlphaMask, ApplyMaskToPixelDataOptions, BinaryMask } from '../_typ
|
|
|
3
3
|
export function applyBinaryMaskToAlphaMask(
|
|
4
4
|
alphaMaskDst: AlphaMask,
|
|
5
5
|
binaryMaskSrc: BinaryMask,
|
|
6
|
-
opts
|
|
6
|
+
opts?: ApplyMaskToPixelDataOptions,
|
|
7
7
|
): void {
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
invertMask = false,
|
|
16
|
-
} = opts
|
|
8
|
+
const targetX = opts?.x ?? 0
|
|
9
|
+
const targetY = opts?.y ?? 0
|
|
10
|
+
const reqWidth = opts?.w ?? 0
|
|
11
|
+
const reqHeight = opts?.h ?? 0
|
|
12
|
+
const mx = opts?.mx ?? 0
|
|
13
|
+
const my = opts?.my ?? 0
|
|
14
|
+
const invertMask = opts?.invertMask ?? false
|
|
17
15
|
|
|
18
16
|
const dstWidth = alphaMaskDst.w
|
|
19
17
|
if (dstWidth <= 0) return
|
package/src/Paint/PaintBuffer.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Color32, PaintAlphaMask, PaintBinaryMask, Rect } from '../_types'
|
|
2
2
|
import { forEachLinePoint } from '../Algorithm/forEachLinePoint'
|
|
3
3
|
import type { PixelEngineConfig } from '../History/PixelEngineConfig'
|
|
4
|
-
import {
|
|
4
|
+
import { _macro_paintRectCenterOffset } from '../Internal/helpers'
|
|
5
5
|
import type { PixelTile } from '../PixelTile/PixelTile'
|
|
6
6
|
import type { PixelTilePool } from '../PixelTile/PixelTilePool'
|
|
7
7
|
import { trimRectBounds } from '../Rect/trimRectBounds'
|
|
@@ -205,8 +205,8 @@ export class PaintBuffer {
|
|
|
205
205
|
const target = config.target
|
|
206
206
|
const scratch = this.scratchBounds
|
|
207
207
|
|
|
208
|
-
const centerOffsetX =
|
|
209
|
-
const centerOffsetY =
|
|
208
|
+
const centerOffsetX = -_macro_paintRectCenterOffset(brushWidth)
|
|
209
|
+
const centerOffsetY = -_macro_paintRectCenterOffset(brushHeight)
|
|
210
210
|
|
|
211
211
|
let changed = false
|
|
212
212
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type AlphaMask, type BinaryMask, MaskType, type PaintAlphaMask, type PaintBinaryMask } from '../_types'
|
|
2
|
-
import {
|
|
2
|
+
import { _macro_halfAndFloor } from '../Internal/helpers'
|
|
3
3
|
|
|
4
4
|
export function makePaintBinaryMask(
|
|
5
5
|
mask: BinaryMask,
|
|
@@ -9,8 +9,8 @@ export function makePaintBinaryMask(
|
|
|
9
9
|
data: mask.data,
|
|
10
10
|
w: mask.w,
|
|
11
11
|
h: mask.h,
|
|
12
|
-
centerOffsetX: -
|
|
13
|
-
centerOffsetY: -
|
|
12
|
+
centerOffsetX: -_macro_halfAndFloor(mask.w),
|
|
13
|
+
centerOffsetY: -_macro_halfAndFloor(mask.h),
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
|
|
@@ -22,7 +22,7 @@ export function makePaintAlphaMask(
|
|
|
22
22
|
data: mask.data,
|
|
23
23
|
w: mask.w,
|
|
24
24
|
h: mask.h,
|
|
25
|
-
centerOffsetX: -
|
|
26
|
-
centerOffsetY: -
|
|
25
|
+
centerOffsetX: -_macro_halfAndFloor(mask.w),
|
|
26
|
+
centerOffsetY: -_macro_halfAndFloor(mask.h),
|
|
27
27
|
}
|
|
28
28
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { MaskType, type PaintAlphaMask } from '../_types'
|
|
2
|
-
import {
|
|
2
|
+
import { _macro_halfAndFloor } from '../Internal/helpers'
|
|
3
3
|
|
|
4
4
|
export function makeRectFalloffPaintAlphaMask(
|
|
5
5
|
width: number,
|
|
@@ -41,7 +41,7 @@ export function makeRectFalloffPaintAlphaMask(
|
|
|
41
41
|
data: data,
|
|
42
42
|
w: width,
|
|
43
43
|
h: height,
|
|
44
|
-
centerOffsetX: -
|
|
45
|
-
centerOffsetY: -
|
|
44
|
+
centerOffsetX: -_macro_halfAndFloor(width),
|
|
45
|
+
centerOffsetY: -_macro_halfAndFloor(height),
|
|
46
46
|
}
|
|
47
47
|
}
|
|
@@ -6,20 +6,18 @@ 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
|
-
|
|
9
|
+
target: IPixelData32,
|
|
10
10
|
mask: AlphaMask,
|
|
11
|
-
opts
|
|
11
|
+
opts?: ApplyMaskToPixelDataOptions,
|
|
12
12
|
): boolean {
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
invertMask = false,
|
|
22
|
-
} = opts
|
|
13
|
+
const targetX = opts?.x ?? 0
|
|
14
|
+
const targetY = opts?.y ?? 0
|
|
15
|
+
const width = opts?.w ?? target.width
|
|
16
|
+
const height = opts?.h ?? target.height
|
|
17
|
+
const globalAlpha = opts?.alpha ?? 255
|
|
18
|
+
const mx = opts?.mx ?? 0
|
|
19
|
+
const my = opts?.my ?? 0
|
|
20
|
+
const invertMask = opts?.invertMask ?? false
|
|
23
21
|
|
|
24
22
|
if (globalAlpha === 0) return false
|
|
25
23
|
|
|
@@ -39,8 +37,8 @@ export function applyAlphaMaskToPixelData(
|
|
|
39
37
|
y = 0
|
|
40
38
|
}
|
|
41
39
|
|
|
42
|
-
w = Math.min(w,
|
|
43
|
-
h = Math.min(h,
|
|
40
|
+
w = Math.min(w, target.width - x)
|
|
41
|
+
h = Math.min(h, target.height - y)
|
|
44
42
|
|
|
45
43
|
if (w <= 0) return false
|
|
46
44
|
if (h <= 0) return false
|
|
@@ -72,8 +70,8 @@ export function applyAlphaMaskToPixelData(
|
|
|
72
70
|
const xShift = sX0 - startX
|
|
73
71
|
const yShift = sY0 - startY
|
|
74
72
|
|
|
75
|
-
const dst32 =
|
|
76
|
-
const dw =
|
|
73
|
+
const dst32 = target.data32
|
|
74
|
+
const dw = target.width
|
|
77
75
|
const dStride = dw - finalW
|
|
78
76
|
const mStride = mPitch - finalW
|
|
79
77
|
const maskData = mask.data
|
|
@@ -6,20 +6,18 @@ import { type ApplyMaskToPixelDataOptions, type BinaryMask, type IPixelData32 }
|
|
|
6
6
|
* @returns true if any pixels were actually modified.
|
|
7
7
|
*/
|
|
8
8
|
export function applyBinaryMaskToPixelData(
|
|
9
|
-
|
|
9
|
+
target: IPixelData32,
|
|
10
10
|
mask: BinaryMask,
|
|
11
|
-
opts
|
|
11
|
+
opts?: ApplyMaskToPixelDataOptions,
|
|
12
12
|
): boolean {
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
invertMask = false,
|
|
22
|
-
} = opts
|
|
13
|
+
const targetX = opts?.x ?? 0
|
|
14
|
+
const targetY = opts?.y ?? 0
|
|
15
|
+
const width = opts?.w ?? target.width
|
|
16
|
+
const height = opts?.h ?? target.height
|
|
17
|
+
const globalAlpha = opts?.alpha ?? 255
|
|
18
|
+
const mx = opts?.mx ?? 0
|
|
19
|
+
const my = opts?.my ?? 0
|
|
20
|
+
const invertMask = opts?.invertMask ?? false
|
|
23
21
|
|
|
24
22
|
if (globalAlpha === 0) return false
|
|
25
23
|
|
|
@@ -38,8 +36,8 @@ export function applyBinaryMaskToPixelData(
|
|
|
38
36
|
y = 0
|
|
39
37
|
}
|
|
40
38
|
|
|
41
|
-
w = Math.min(w,
|
|
42
|
-
h = Math.min(h,
|
|
39
|
+
w = Math.min(w, target.width - x)
|
|
40
|
+
h = Math.min(h, target.height - y)
|
|
43
41
|
|
|
44
42
|
if (w <= 0 || h <= 0) return false
|
|
45
43
|
|
|
@@ -69,8 +67,8 @@ export function applyBinaryMaskToPixelData(
|
|
|
69
67
|
const xShift = sX0 - startX
|
|
70
68
|
const yShift = sY0 - startY
|
|
71
69
|
|
|
72
|
-
const dst32 =
|
|
73
|
-
const dw =
|
|
70
|
+
const dst32 = target.data32
|
|
71
|
+
const dw = target.width
|
|
74
72
|
const dStride = dw - finalW
|
|
75
73
|
const mStride = mPitch - finalW
|
|
76
74
|
const maskData = mask.data
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type AlphaMask,
|
|
3
|
+
type ApplyMaskToPixelDataOptions,
|
|
4
|
+
type BinaryMask,
|
|
5
|
+
type IPixelData32,
|
|
6
|
+
type Mask,
|
|
7
|
+
MaskType,
|
|
8
|
+
} from '../_types'
|
|
9
|
+
import { applyAlphaMaskToPixelData } from './applyAlphaMaskToPixelData'
|
|
10
|
+
import { applyBinaryMaskToPixelData } from './applyBinaryMaskToPixelData'
|
|
11
|
+
|
|
12
|
+
export function applyMaskToPixelData(
|
|
13
|
+
dst: IPixelData32,
|
|
14
|
+
mask: Mask,
|
|
15
|
+
opts?: ApplyMaskToPixelDataOptions,
|
|
16
|
+
): boolean {
|
|
17
|
+
if (mask.type === MaskType.BINARY) {
|
|
18
|
+
return applyBinaryMaskToPixelData(dst, mask as BinaryMask, opts)
|
|
19
|
+
} else {
|
|
20
|
+
return applyAlphaMaskToPixelData(dst, mask as AlphaMask, opts)
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -6,19 +6,16 @@ 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
|
-
|
|
9
|
+
target: IPixelData32,
|
|
10
10
|
color: Color32,
|
|
11
|
-
opts
|
|
11
|
+
opts?: ColorBlendOptions,
|
|
12
12
|
): boolean {
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
blendFn = sourceOverPerfect,
|
|
20
|
-
} = opts
|
|
21
|
-
|
|
13
|
+
const targetX = opts?.x ?? 0
|
|
14
|
+
const targetY = opts?.y ?? 0
|
|
15
|
+
const width = opts?.w ?? target.width
|
|
16
|
+
const height = opts?.h ?? target.height
|
|
17
|
+
const globalAlpha = opts?.alpha ?? 255
|
|
18
|
+
const blendFn = opts?.blendFn ?? sourceOverPerfect
|
|
22
19
|
if (globalAlpha === 0) return false
|
|
23
20
|
|
|
24
21
|
const baseSrcAlpha = (color >>> 24)
|
|
@@ -42,8 +39,8 @@ export function blendColorPixelData(
|
|
|
42
39
|
y = 0
|
|
43
40
|
}
|
|
44
41
|
|
|
45
|
-
const actualW = Math.min(w,
|
|
46
|
-
const actualH = Math.min(h,
|
|
42
|
+
const actualW = Math.min(w, target.width - x)
|
|
43
|
+
const actualH = Math.min(h, target.height - y)
|
|
47
44
|
|
|
48
45
|
if (actualW <= 0 || actualH <= 0) return false
|
|
49
46
|
|
|
@@ -56,8 +53,8 @@ export function blendColorPixelData(
|
|
|
56
53
|
finalSrcColor = ((color & 0x00ffffff) | (a << 24)) >>> 0 as Color32
|
|
57
54
|
}
|
|
58
55
|
|
|
59
|
-
const dst32 =
|
|
60
|
-
const dw =
|
|
56
|
+
const dst32 = target.data32
|
|
57
|
+
const dw = target.width
|
|
61
58
|
let dIdx = (y * dw + x) | 0
|
|
62
59
|
const dStride = (dw - actualW) | 0
|
|
63
60
|
let didChange = false
|
|
@@ -8,27 +8,27 @@ 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
|
|
11
|
+
* @param target - 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
|
-
|
|
18
|
+
target: IPixelData32,
|
|
19
19
|
color: Color32,
|
|
20
20
|
mask: AlphaMask,
|
|
21
|
-
opts
|
|
21
|
+
opts?: ColorBlendMaskOptions,
|
|
22
22
|
): boolean {
|
|
23
|
-
const targetX = opts
|
|
24
|
-
const targetY = opts
|
|
25
|
-
const w = opts
|
|
26
|
-
const h = opts
|
|
27
|
-
const globalAlpha = opts
|
|
28
|
-
const blendFn = opts
|
|
29
|
-
const mx = opts
|
|
30
|
-
const my = opts
|
|
31
|
-
const invertMask = opts
|
|
23
|
+
const targetX = opts?.x ?? 0
|
|
24
|
+
const targetY = opts?.y ?? 0
|
|
25
|
+
const w = opts?.w ?? mask.w
|
|
26
|
+
const h = opts?.h ?? mask.h
|
|
27
|
+
const globalAlpha = opts?.alpha ?? 255
|
|
28
|
+
const blendFn = opts?.blendFn ?? sourceOverPerfect
|
|
29
|
+
const mx = opts?.mx ?? 0
|
|
30
|
+
const my = opts?.my ?? 0
|
|
31
|
+
const invertMask = opts?.invertMask ?? false
|
|
32
32
|
|
|
33
33
|
if (globalAlpha === 0) return false
|
|
34
34
|
|
|
@@ -52,16 +52,16 @@ export function blendColorPixelDataAlphaMask(
|
|
|
52
52
|
y = 0
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
actualW = Math.min(actualW,
|
|
56
|
-
actualH = Math.min(actualH,
|
|
55
|
+
actualW = Math.min(actualW, target.width - x)
|
|
56
|
+
actualH = Math.min(actualH, target.height - y)
|
|
57
57
|
|
|
58
58
|
if (actualW <= 0 || actualH <= 0) return false
|
|
59
59
|
|
|
60
60
|
const dx = (x - targetX) | 0
|
|
61
61
|
const dy = (y - targetY) | 0
|
|
62
62
|
|
|
63
|
-
const dst32 =
|
|
64
|
-
const dw =
|
|
63
|
+
const dst32 = target.data32
|
|
64
|
+
const dw = target.width
|
|
65
65
|
const mPitch = mask.w
|
|
66
66
|
const maskData = mask.data
|
|
67
67
|
|