pixel-data-js 0.18.0 → 0.19.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 +6 -1
- package/dist/index.dev.cjs +2723 -1487
- package/dist/index.dev.cjs.map +1 -1
- package/dist/index.dev.js +2690 -1481
- package/dist/index.dev.js.map +1 -1
- package/dist/index.prod.cjs +2723 -1487
- package/dist/index.prod.cjs.map +1 -1
- package/dist/index.prod.d.ts +400 -246
- package/dist/index.prod.js +2690 -1481
- package/dist/index.prod.js.map +1 -1
- package/package.json +21 -6
- package/src/Algorithm/forEachLinePoint.ts +36 -0
- package/src/BlendModes/BlendModeRegistry.ts +2 -0
- package/src/BlendModes/blend-modes-fast.ts +2 -2
- package/src/BlendModes/blend-modes-perfect.ts +5 -4
- package/src/BlendModes/toBlendModeIndexAndName.ts +41 -0
- package/src/History/PixelAccumulator.ts +2 -2
- package/src/History/PixelMutator/mutatorApplyAlphaMask.ts +30 -0
- package/src/History/PixelMutator/mutatorApplyBinaryMask.ts +30 -0
- package/src/History/PixelMutator/mutatorApplyCircleBrush.ts +23 -9
- package/src/History/PixelMutator/mutatorApplyCircleBrushStroke.ts +138 -0
- package/src/History/PixelMutator/mutatorApplyCirclePencil.ts +59 -0
- package/src/History/PixelMutator/mutatorApplyCirclePencilStroke.ts +131 -0
- package/src/History/PixelMutator/mutatorApplyRectBrush.ts +20 -7
- package/src/History/PixelMutator/mutatorApplyRectBrushStroke.ts +169 -0
- package/src/History/PixelMutator/mutatorApplyRectPencil.ts +62 -0
- package/src/History/PixelMutator/mutatorApplyRectPencilStroke.ts +149 -0
- package/src/History/PixelMutator/mutatorBlendColor.ts +9 -4
- package/src/History/PixelMutator/mutatorBlendPixelData.ts +10 -5
- package/src/History/PixelMutator/mutatorClear.ts +27 -0
- package/src/History/PixelMutator/{mutatorFillPixelData.ts → mutatorFill.ts} +9 -3
- package/src/History/PixelMutator/mutatorInvert.ts +10 -3
- package/src/History/PixelMutator.ts +23 -3
- package/src/History/PixelPatchTiles.ts +2 -2
- package/src/History/PixelWriter.ts +3 -3
- package/src/ImageData/ImageDataLike.ts +13 -0
- package/src/ImageData/extractImageDataBuffer.ts +22 -15
- package/src/ImageData/serialization.ts +4 -4
- package/src/ImageData/uInt32ArrayToImageData.ts +29 -0
- package/src/ImageData/writeImageData.ts +26 -18
- package/src/ImageData/writeImageDataBuffer.ts +30 -18
- package/src/IndexedImage/indexedImageToAverageColor.ts +1 -1
- package/src/Internal/resolveClipping.ts +140 -0
- package/src/Mask/applyBinaryMaskToAlphaMask.ts +89 -0
- package/src/Mask/copyMask.ts +1 -3
- package/src/Mask/mergeAlphaMasks.ts +81 -0
- package/src/Mask/mergeBinaryMasks.ts +89 -0
- package/src/PixelData/PixelBuffer32.ts +28 -0
- package/src/PixelData/PixelData.ts +38 -33
- package/src/PixelData/applyAlphaMaskToPixelData.ts +119 -0
- package/src/PixelData/applyBinaryMaskToPixelData.ts +111 -0
- package/src/PixelData/applyCircleBrushToPixelData.ts +31 -56
- package/src/PixelData/applyRectBrushToPixelData.ts +39 -71
- package/src/PixelData/blendColorPixelData.ts +18 -111
- package/src/PixelData/blendColorPixelDataAlphaMask.ts +111 -0
- package/src/PixelData/blendColorPixelDataBinaryMask.ts +89 -0
- package/src/PixelData/blendPixelData.ts +19 -107
- package/src/PixelData/blendPixelDataAlphaMask.ts +149 -0
- package/src/PixelData/blendPixelDataBinaryMask.ts +133 -0
- package/src/PixelData/clearPixelData.ts +2 -3
- package/src/PixelData/extractPixelData.ts +4 -4
- package/src/PixelData/extractPixelDataBuffer.ts +38 -26
- package/src/PixelData/fillPixelData.ts +18 -20
- package/src/PixelData/invertPixelData.ts +13 -21
- package/src/PixelData/pixelDataToAlphaMask.ts +2 -3
- package/src/PixelData/reflectPixelData.ts +3 -3
- package/src/PixelData/resamplePixelData.ts +2 -6
- package/src/PixelData/writePixelDataBuffer.ts +34 -20
- package/src/Rect/getCircleBrushOrPencilBounds.ts +43 -0
- package/src/Rect/getCircleBrushOrPencilStrokeBounds.ts +24 -0
- package/src/Rect/getRectBrushOrPencilBounds.ts +38 -0
- package/src/Rect/getRectBrushOrPencilStrokeBounds.ts +26 -0
- package/src/_types.ts +49 -33
- package/src/index.ts +47 -11
- package/src/History/PixelMutator/mutatorApplyMask.ts +0 -20
- package/src/Mask/mergeMasks.ts +0 -100
- package/src/PixelData/applyMaskToPixelData.ts +0 -129
package/src/_types.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { PixelWriter, sourceOverPerfect } from './index'
|
|
2
2
|
|
|
3
3
|
/** ALL values are 0-255 (including alpha which in CSS is 0-1) */
|
|
4
4
|
export type RGBA = { r: number, g: number, b: number, a: number }
|
|
@@ -23,6 +23,14 @@ export type ImageDataLike = {
|
|
|
23
23
|
data: Uint8ClampedArray<ArrayBufferLike>
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
export type ImageDataLikeConstructor<T extends ImageDataLike = ImageDataLike> = {
|
|
27
|
+
new(
|
|
28
|
+
data: Uint8ClampedArray,
|
|
29
|
+
width: number,
|
|
30
|
+
height: number,
|
|
31
|
+
): T
|
|
32
|
+
}
|
|
33
|
+
|
|
26
34
|
export type SerializedImageData = {
|
|
27
35
|
width: number
|
|
28
36
|
height: number
|
|
@@ -66,7 +74,7 @@ export type AnyMask = BinaryMask | AlphaMask
|
|
|
66
74
|
* Configuration for pixel manipulation operations.
|
|
67
75
|
* Designed to be used by spreading a Rect object ({x, y, w, h}) directly.
|
|
68
76
|
*/
|
|
69
|
-
export interface
|
|
77
|
+
export interface PixelRect {
|
|
70
78
|
/**
|
|
71
79
|
* The starting X coordinate in the destination buffer.
|
|
72
80
|
* @default 0
|
|
@@ -80,26 +88,19 @@ export interface PixelRectOptions {
|
|
|
80
88
|
y?: number
|
|
81
89
|
|
|
82
90
|
/**
|
|
83
|
-
* The width of the region
|
|
91
|
+
* The width of the region in the destination buffer.
|
|
84
92
|
* @default Source width.
|
|
85
93
|
*/
|
|
86
94
|
w?: number
|
|
87
95
|
|
|
88
96
|
/**
|
|
89
|
-
* The height of the region
|
|
97
|
+
* The height of the region in the destination buffer.
|
|
90
98
|
* @default Source height.
|
|
91
99
|
*/
|
|
92
100
|
h?: number
|
|
93
101
|
}
|
|
94
102
|
|
|
95
|
-
export interface
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Mask width.
|
|
99
|
-
* @default value of `w`
|
|
100
|
-
*/
|
|
101
|
-
mw?: number
|
|
102
|
-
|
|
103
|
+
export interface MaskOffset {
|
|
103
104
|
/**
|
|
104
105
|
* X offset into the mask buffer.
|
|
105
106
|
* @default 0
|
|
@@ -113,7 +114,15 @@ export interface PixelMaskRectOptions {
|
|
|
113
114
|
my?: number
|
|
114
115
|
}
|
|
115
116
|
|
|
116
|
-
export interface
|
|
117
|
+
export interface MaskOffsetWidth {
|
|
118
|
+
/**
|
|
119
|
+
* Mask width.
|
|
120
|
+
* @default value of `w`
|
|
121
|
+
*/
|
|
122
|
+
mw?: number
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export interface InvertMask {
|
|
117
126
|
|
|
118
127
|
/**
|
|
119
128
|
* If true the inverse of the mask will be applied
|
|
@@ -122,27 +131,22 @@ export interface PixelMaskInvertOptions {
|
|
|
122
131
|
invertMask?: boolean
|
|
123
132
|
}
|
|
124
133
|
|
|
125
|
-
|
|
126
|
-
* Configuration for pixel manipulation operations.
|
|
127
|
-
* Designed to be used by spreading a Rect object ({x, y, w, h}) directly.
|
|
128
|
-
*/
|
|
129
|
-
export interface PixelOptions extends PixelRectOptions, PixelMaskRectOptions, PixelMaskInvertOptions {
|
|
134
|
+
export interface Alpha {
|
|
130
135
|
/**
|
|
131
136
|
* Overall layer opacity 0-255.
|
|
132
137
|
* @default 255
|
|
133
138
|
*/
|
|
134
139
|
alpha?: number
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export interface ApplyMaskToPixelDataOptions extends PixelRect, Alpha, MaskOffsetWidth, MaskOffset, InvertMask {
|
|
143
|
+
}
|
|
135
144
|
|
|
136
|
-
|
|
137
|
-
mask?: AnyMask | null
|
|
145
|
+
export interface MergeAlphaMasksOptions extends PixelRect, Alpha, MaskOffset, InvertMask {
|
|
138
146
|
|
|
139
|
-
/** The interpretation logic for the provided mask.
|
|
140
|
-
* @default {@link MaskType.ALPHA}
|
|
141
|
-
*/
|
|
142
|
-
maskType?: MaskType
|
|
143
147
|
}
|
|
144
148
|
|
|
145
|
-
export interface PixelMutateOptions extends
|
|
149
|
+
export interface PixelMutateOptions extends PixelRect, MaskOffset, MaskOffsetWidth, InvertMask {
|
|
146
150
|
/** An optional mask to restrict where pixels are mutated. */
|
|
147
151
|
mask?: BinaryMask | null
|
|
148
152
|
}
|
|
@@ -150,7 +154,8 @@ export interface PixelMutateOptions extends PixelRectOptions, PixelMaskRectOptio
|
|
|
150
154
|
/**
|
|
151
155
|
* Configuration for blitting (copying/blending) one image into another.
|
|
152
156
|
*/
|
|
153
|
-
|
|
157
|
+
|
|
158
|
+
export interface BasePixelBlendOptions {
|
|
154
159
|
/**
|
|
155
160
|
* The source rectangle x-coordinate
|
|
156
161
|
* @default 0
|
|
@@ -165,23 +170,31 @@ export interface PixelBlendOptions extends PixelOptions {
|
|
|
165
170
|
|
|
166
171
|
/**
|
|
167
172
|
* The blending algorithm to use for blending pixels.
|
|
168
|
-
* @default {@link
|
|
173
|
+
* @default {@link sourceOverPerfect}
|
|
169
174
|
*/
|
|
170
175
|
blendFn?: BlendColor32
|
|
171
176
|
}
|
|
172
177
|
|
|
178
|
+
export interface PixelBlendOptions extends PixelRect, Alpha, BasePixelBlendOptions {
|
|
179
|
+
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export interface PixelBlendMaskOptions extends PixelRect, Alpha, MaskOffsetWidth, MaskOffset, InvertMask, BasePixelBlendOptions {
|
|
183
|
+
}
|
|
184
|
+
|
|
173
185
|
/**
|
|
174
186
|
* Configuration for operations that require color blending.
|
|
175
187
|
*/
|
|
176
|
-
export interface ColorBlendOptions extends
|
|
188
|
+
export interface ColorBlendOptions extends PixelRect, Alpha {
|
|
177
189
|
/**
|
|
178
190
|
* The blending algorithm to use for blending pixels.
|
|
179
|
-
* @default {@link
|
|
191
|
+
* @default {@link sourceOverPerfect}
|
|
180
192
|
*/
|
|
181
193
|
blendFn?: BlendColor32
|
|
182
194
|
}
|
|
183
195
|
|
|
184
|
-
export
|
|
196
|
+
export interface ColorBlendMaskOptions extends ColorBlendOptions, MaskOffset, MaskOffsetWidth, InvertMask {
|
|
197
|
+
}
|
|
185
198
|
|
|
186
199
|
export type SelectionRect = Rect & ({
|
|
187
200
|
mask: Uint8Array,
|
|
@@ -191,7 +204,10 @@ export type SelectionRect = Rect & ({
|
|
|
191
204
|
maskType?: null,
|
|
192
205
|
})
|
|
193
206
|
|
|
194
|
-
export type
|
|
195
|
-
|
|
196
|
-
|
|
207
|
+
export type HistoryMutator<T extends {}, D extends {}> = (writer: PixelWriter<any>, deps?: Partial<D>) => T
|
|
208
|
+
|
|
209
|
+
export interface IPixelData {
|
|
210
|
+
readonly data32: Uint32Array
|
|
211
|
+
readonly width: number
|
|
212
|
+
readonly height: number
|
|
197
213
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
|
+
// @sort-all
|
|
1
2
|
export * from './_types'
|
|
2
3
|
export * from './color'
|
|
3
4
|
|
|
4
5
|
export * from './Algorithm/floodFillSelection'
|
|
5
6
|
|
|
6
|
-
export * from './BlendModes/BlendModeRegistry'
|
|
7
|
-
export * from './BlendModes/blend-modes'
|
|
8
7
|
export * from './BlendModes/blend-modes-fast'
|
|
9
8
|
export * from './BlendModes/blend-modes-perfect'
|
|
9
|
+
export * from './BlendModes/blend-modes'
|
|
10
|
+
export * from './BlendModes/BlendModeRegistry'
|
|
11
|
+
export * from './BlendModes/toBlendModeIndexAndName'
|
|
10
12
|
|
|
13
|
+
export * from './Canvas/_constants'
|
|
11
14
|
export * from './Canvas/PixelCanvas'
|
|
12
15
|
export * from './Canvas/ReusableCanvas'
|
|
13
16
|
|
|
@@ -15,23 +18,38 @@ export * from './Clipboard/getImageDataFromClipboard'
|
|
|
15
18
|
export * from './Clipboard/writeImageDataToClipboard'
|
|
16
19
|
export * from './Clipboard/writeImgBlobToClipboard'
|
|
17
20
|
|
|
18
|
-
export * from './History/PixelAccumulator'
|
|
19
21
|
export * from './History/HistoryManager'
|
|
22
|
+
export * from './History/PixelAccumulator'
|
|
20
23
|
export * from './History/PixelEngineConfig'
|
|
21
24
|
export * from './History/PixelMutator'
|
|
22
25
|
export * from './History/PixelPatchTiles'
|
|
23
26
|
export * from './History/PixelWriter'
|
|
24
27
|
|
|
25
|
-
export * from './History/PixelMutator/
|
|
28
|
+
export * from './History/PixelMutator/mutatorApplyAlphaMask'
|
|
29
|
+
export * from './History/PixelMutator/mutatorApplyBinaryMask'
|
|
30
|
+
|
|
31
|
+
export * from './History/PixelMutator/mutatorApplyCircleBrush'
|
|
32
|
+
export * from './History/PixelMutator/mutatorApplyCircleBrushStroke'
|
|
33
|
+
|
|
34
|
+
export * from './History/PixelMutator/mutatorApplyCirclePencil'
|
|
35
|
+
export * from './History/PixelMutator/mutatorApplyCirclePencilStroke'
|
|
36
|
+
|
|
37
|
+
export * from './History/PixelMutator/mutatorApplyRectPencil'
|
|
38
|
+
export * from './History/PixelMutator/mutatorApplyRectPencilStroke'
|
|
39
|
+
|
|
40
|
+
export * from './History/PixelMutator/mutatorApplyRectBrush'
|
|
41
|
+
export * from './History/PixelMutator/mutatorApplyRectBrushStroke'
|
|
42
|
+
|
|
26
43
|
export * from './History/PixelMutator/mutatorBlendColor'
|
|
27
44
|
export * from './History/PixelMutator/mutatorBlendPixel'
|
|
28
45
|
export * from './History/PixelMutator/mutatorBlendPixelData'
|
|
29
|
-
export * from './History/PixelMutator/
|
|
46
|
+
export * from './History/PixelMutator/mutatorClear'
|
|
47
|
+
export * from './History/PixelMutator/mutatorFill'
|
|
30
48
|
export * from './History/PixelMutator/mutatorInvert'
|
|
31
49
|
|
|
32
|
-
export * from './ImageData/ReusableImageData'
|
|
33
50
|
export * from './ImageData/copyImageData'
|
|
34
51
|
export * from './ImageData/extractImageDataBuffer'
|
|
52
|
+
export * from './ImageData/ImageDataLike'
|
|
35
53
|
export * from './ImageData/imageDataToAlphaMask'
|
|
36
54
|
export * from './ImageData/imageDataToDataUrl'
|
|
37
55
|
export * from './ImageData/imageDataToImgBlob'
|
|
@@ -40,40 +58,58 @@ export * from './ImageData/imgBlobToImageData'
|
|
|
40
58
|
export * from './ImageData/invertImageData'
|
|
41
59
|
export * from './ImageData/resampleImageData'
|
|
42
60
|
export * from './ImageData/resizeImageData'
|
|
61
|
+
export * from './ImageData/ReusableImageData'
|
|
43
62
|
export * from './ImageData/serialization'
|
|
63
|
+
export * from './ImageData/uInt32ArrayToImageData'
|
|
44
64
|
export * from './ImageData/writeImageData'
|
|
45
65
|
export * from './ImageData/writeImageDataBuffer'
|
|
46
66
|
|
|
47
|
-
export * from './IndexedImage/IndexedImage'
|
|
48
67
|
export * from './IndexedImage/getIndexedImageColorCounts'
|
|
68
|
+
export * from './IndexedImage/IndexedImage'
|
|
49
69
|
export * from './IndexedImage/indexedImageToAverageColor'
|
|
50
|
-
export * from './IndexedImage/resampleIndexedImage'
|
|
51
70
|
export * from './IndexedImage/indexedImageToImageData'
|
|
71
|
+
export * from './IndexedImage/resampleIndexedImage'
|
|
52
72
|
|
|
53
73
|
export * from './Input/fileInputChangeToImageData'
|
|
54
74
|
export * from './Input/fileToImageData'
|
|
55
75
|
export * from './Input/getSupportedRasterFormats'
|
|
56
76
|
|
|
77
|
+
export * from './Mask/applyBinaryMaskToAlphaMask'
|
|
57
78
|
export * from './Mask/copyMask'
|
|
58
79
|
export * from './Mask/extractMask'
|
|
59
80
|
export * from './Mask/invertMask'
|
|
60
|
-
export * from './Mask/
|
|
81
|
+
export * from './Mask/mergeAlphaMasks'
|
|
82
|
+
export * from './Mask/mergeBinaryMasks'
|
|
61
83
|
|
|
62
|
-
export * from './PixelData/
|
|
84
|
+
export * from './PixelData/applyAlphaMaskToPixelData'
|
|
85
|
+
export * from './PixelData/applyBinaryMaskToPixelData'
|
|
63
86
|
export * from './PixelData/applyCircleBrushToPixelData'
|
|
64
|
-
export * from './PixelData/
|
|
87
|
+
export * from './PixelData/PixelData'
|
|
88
|
+
|
|
65
89
|
export * from './PixelData/applyRectBrushToPixelData'
|
|
66
90
|
export * from './PixelData/blendColorPixelData'
|
|
91
|
+
export * from './PixelData/blendColorPixelDataAlphaMask'
|
|
92
|
+
export * from './PixelData/blendColorPixelDataBinaryMask'
|
|
67
93
|
export * from './PixelData/blendPixelData'
|
|
94
|
+
export * from './PixelData/blendPixelDataAlphaMask'
|
|
95
|
+
export * from './PixelData/blendPixelDataBinaryMask'
|
|
96
|
+
|
|
68
97
|
export * from './PixelData/clearPixelData'
|
|
69
98
|
export * from './PixelData/extractPixelData'
|
|
70
99
|
export * from './PixelData/extractPixelDataBuffer'
|
|
71
100
|
export * from './PixelData/fillPixelData'
|
|
72
101
|
export * from './PixelData/invertPixelData'
|
|
102
|
+
export * from './PixelData/PixelBuffer32'
|
|
73
103
|
export * from './PixelData/pixelDataToAlphaMask'
|
|
74
104
|
export * from './PixelData/reflectPixelData'
|
|
75
105
|
export * from './PixelData/resamplePixelData'
|
|
76
106
|
export * from './PixelData/rotatePixelData'
|
|
77
107
|
export * from './PixelData/writePixelDataBuffer'
|
|
78
108
|
|
|
109
|
+
export * from './Rect/getCircleBrushOrPencilBounds'
|
|
110
|
+
export * from './Rect/getCircleBrushOrPencilStrokeBounds'
|
|
111
|
+
export * from './Rect/getRectBrushOrPencilBounds'
|
|
112
|
+
export * from './Rect/getRectBrushOrPencilStrokeBounds'
|
|
79
113
|
export * from './Rect/trimRectBounds'
|
|
114
|
+
|
|
115
|
+
export * from './Algorithm/forEachLinePoint'
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { type AnyMask, type ApplyMaskOptions } from '../../_types'
|
|
2
|
-
import { applyMaskToPixelData } from '../../PixelData/applyMaskToPixelData'
|
|
3
|
-
import { PixelWriter } from '../PixelWriter'
|
|
4
|
-
|
|
5
|
-
export function mutatorApplyMask(writer: PixelWriter<any>) {
|
|
6
|
-
return {
|
|
7
|
-
applyMask: (mask: AnyMask, opts: ApplyMaskOptions = {}) => {
|
|
8
|
-
let target = writer.target
|
|
9
|
-
const {
|
|
10
|
-
x = 0,
|
|
11
|
-
y = 0,
|
|
12
|
-
w = writer.target.width,
|
|
13
|
-
h = writer.target.height,
|
|
14
|
-
} = opts
|
|
15
|
-
|
|
16
|
-
writer.accumulator.storeRegionBeforeState(x, y, w, h)
|
|
17
|
-
applyMaskToPixelData(target, mask, opts)
|
|
18
|
-
},
|
|
19
|
-
}
|
|
20
|
-
}
|
package/src/Mask/mergeMasks.ts
DELETED
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
import { type AlphaMask, type AnyMask, type ApplyMaskOptions, MaskType } from '../_types'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Merges a source mask into a destination AlphaMask.
|
|
5
|
-
*/
|
|
6
|
-
export function mergeMasks(
|
|
7
|
-
dst: AlphaMask,
|
|
8
|
-
dstWidth: number,
|
|
9
|
-
src: AnyMask,
|
|
10
|
-
opts: ApplyMaskOptions,
|
|
11
|
-
): void {
|
|
12
|
-
const {
|
|
13
|
-
x: targetX = 0,
|
|
14
|
-
y: targetY = 0,
|
|
15
|
-
w: width = 0,
|
|
16
|
-
h: height = 0,
|
|
17
|
-
alpha: globalAlpha = 255,
|
|
18
|
-
maskType = MaskType.ALPHA,
|
|
19
|
-
mw,
|
|
20
|
-
mx = 0,
|
|
21
|
-
my = 0,
|
|
22
|
-
invertMask = false,
|
|
23
|
-
} = opts
|
|
24
|
-
|
|
25
|
-
if (width <= 0 || height <= 0 || globalAlpha === 0) {
|
|
26
|
-
return
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const sPitch = mw ?? width
|
|
30
|
-
const isAlpha = maskType === MaskType.ALPHA
|
|
31
|
-
|
|
32
|
-
for (let iy = 0; iy < height; iy++) {
|
|
33
|
-
const dy = targetY + iy
|
|
34
|
-
const sy = my + iy
|
|
35
|
-
|
|
36
|
-
if (dy < 0 || sy < 0) {
|
|
37
|
-
continue
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
for (let ix = 0; ix < width; ix++) {
|
|
41
|
-
const dx = targetX + ix
|
|
42
|
-
const sx = mx + ix
|
|
43
|
-
|
|
44
|
-
if (dx < 0 || dx >= dstWidth || sx < 0 || sx >= sPitch) {
|
|
45
|
-
continue
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const dIdx = dy * dstWidth + dx
|
|
49
|
-
const sIdx = sy * sPitch + sx
|
|
50
|
-
const mVal = src[sIdx]
|
|
51
|
-
let weight = globalAlpha
|
|
52
|
-
|
|
53
|
-
if (isAlpha) {
|
|
54
|
-
const effectiveM = invertMask
|
|
55
|
-
? 255 - mVal
|
|
56
|
-
: mVal
|
|
57
|
-
|
|
58
|
-
if (effectiveM === 0) {
|
|
59
|
-
dst[dIdx] = 0
|
|
60
|
-
continue
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
weight = globalAlpha === 255
|
|
64
|
-
? effectiveM
|
|
65
|
-
: (effectiveM * globalAlpha + 128) >> 8
|
|
66
|
-
} else {
|
|
67
|
-
// Strict Binary 1/0 Logic
|
|
68
|
-
const isHit = invertMask
|
|
69
|
-
? mVal === 0
|
|
70
|
-
: mVal === 1
|
|
71
|
-
|
|
72
|
-
if (!isHit) {
|
|
73
|
-
dst[dIdx] = 0
|
|
74
|
-
continue
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// If binary hit, weight is just the global alpha
|
|
78
|
-
weight = globalAlpha
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
if (weight === 0) {
|
|
82
|
-
dst[dIdx] = 0
|
|
83
|
-
continue
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
const da = dst[dIdx]
|
|
87
|
-
|
|
88
|
-
if (da === 0) {
|
|
89
|
-
// Already transparent
|
|
90
|
-
} else if (weight === 255) {
|
|
91
|
-
// Identity: keep da
|
|
92
|
-
} else if (da === 255) {
|
|
93
|
-
// Identity: result is weight
|
|
94
|
-
dst[dIdx] = weight
|
|
95
|
-
} else {
|
|
96
|
-
dst[dIdx] = (da * weight + 128) >> 8
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
import { type AnyMask, type ApplyMaskOptions, MaskType } from '../_types'
|
|
2
|
-
import type { PixelData } from './PixelData'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Directly applies a mask to a region of PixelData,
|
|
6
|
-
* modifying the destination's alpha channel in-place.
|
|
7
|
-
*/
|
|
8
|
-
export function applyMaskToPixelData(
|
|
9
|
-
dst: PixelData,
|
|
10
|
-
mask: AnyMask,
|
|
11
|
-
opts: ApplyMaskOptions = {},
|
|
12
|
-
): void {
|
|
13
|
-
const {
|
|
14
|
-
x: targetX = 0,
|
|
15
|
-
y: targetY = 0,
|
|
16
|
-
w: width = dst.width,
|
|
17
|
-
h: height = dst.height,
|
|
18
|
-
alpha: globalAlpha = 255,
|
|
19
|
-
maskType = MaskType.ALPHA,
|
|
20
|
-
mw,
|
|
21
|
-
mx = 0,
|
|
22
|
-
my = 0,
|
|
23
|
-
invertMask = false,
|
|
24
|
-
} = opts
|
|
25
|
-
|
|
26
|
-
let x = targetX
|
|
27
|
-
let y = targetY
|
|
28
|
-
let w = width
|
|
29
|
-
let h = height
|
|
30
|
-
|
|
31
|
-
// Clipping Logic
|
|
32
|
-
if (x < 0) {
|
|
33
|
-
w += x
|
|
34
|
-
x = 0
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
if (y < 0) {
|
|
38
|
-
h += y
|
|
39
|
-
y = 0
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const actualW = Math.min(w, dst.width - x)
|
|
43
|
-
const actualH = Math.min(h, dst.height - y)
|
|
44
|
-
|
|
45
|
-
if (actualW <= 0 || actualH <= 0 || globalAlpha === 0) {
|
|
46
|
-
return
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const dst32 = dst.data32
|
|
50
|
-
const dw = dst.width
|
|
51
|
-
const mPitch = mw ?? width
|
|
52
|
-
const isAlpha = maskType === MaskType.ALPHA
|
|
53
|
-
const dx = x - targetX
|
|
54
|
-
const dy = y - targetY
|
|
55
|
-
|
|
56
|
-
let dIdx = y * dw + x
|
|
57
|
-
let mIdx = (my + dy) * mPitch + (mx + dx)
|
|
58
|
-
|
|
59
|
-
const dStride = dw - actualW
|
|
60
|
-
const mStride = mPitch - actualW
|
|
61
|
-
|
|
62
|
-
for (let iy = 0; iy < actualH; iy++) {
|
|
63
|
-
for (let ix = 0; ix < actualW; ix++) {
|
|
64
|
-
const mVal = mask[mIdx]
|
|
65
|
-
let weight = globalAlpha
|
|
66
|
-
|
|
67
|
-
if (isAlpha) {
|
|
68
|
-
const effectiveM = invertMask
|
|
69
|
-
? 255 - mVal
|
|
70
|
-
: mVal
|
|
71
|
-
|
|
72
|
-
// Short-circuit: if source is 0, destination alpha becomes 0
|
|
73
|
-
if (effectiveM === 0) {
|
|
74
|
-
dst32[dIdx] = (dst32[dIdx] & 0x00ffffff) >>> 0
|
|
75
|
-
dIdx++
|
|
76
|
-
mIdx++
|
|
77
|
-
continue
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
weight = globalAlpha === 255
|
|
81
|
-
? effectiveM
|
|
82
|
-
: (effectiveM * globalAlpha + 128) >> 8
|
|
83
|
-
} else {
|
|
84
|
-
// Strict Binary 1/0 Logic
|
|
85
|
-
const isHit = invertMask
|
|
86
|
-
? mVal === 0
|
|
87
|
-
: mVal === 1
|
|
88
|
-
|
|
89
|
-
if (!isHit) {
|
|
90
|
-
dst32[dIdx] = (dst32[dIdx] & 0x00ffffff) >>> 0
|
|
91
|
-
dIdx++
|
|
92
|
-
mIdx++
|
|
93
|
-
continue
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
weight = globalAlpha
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// If calculated weight is 0, clear alpha
|
|
100
|
-
if (weight === 0) {
|
|
101
|
-
dst32[dIdx] = (dst32[dIdx] & 0x00ffffff) >>> 0
|
|
102
|
-
} else {
|
|
103
|
-
const d = dst32[dIdx]
|
|
104
|
-
const da = (d >>> 24)
|
|
105
|
-
|
|
106
|
-
let finalAlpha = da
|
|
107
|
-
|
|
108
|
-
if (da === 0) {
|
|
109
|
-
// Already transparent
|
|
110
|
-
} else if (weight === 255) {
|
|
111
|
-
// Identity: keep original da
|
|
112
|
-
} else if (da === 255) {
|
|
113
|
-
// Identity: result is just the weight
|
|
114
|
-
finalAlpha = weight
|
|
115
|
-
} else {
|
|
116
|
-
finalAlpha = (da * weight + 128) >> 8
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
dst32[dIdx] = ((d & 0x00ffffff) | (finalAlpha << 24)) >>> 0
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
dIdx++
|
|
123
|
-
mIdx++
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
dIdx += dStride
|
|
127
|
-
mIdx += mStride
|
|
128
|
-
}
|
|
129
|
-
}
|