pixel-data-js 0.21.0 → 0.23.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.dev.cjs +1129 -717
- package/dist/index.dev.cjs.map +1 -1
- package/dist/index.dev.js +1114 -716
- package/dist/index.dev.js.map +1 -1
- package/dist/index.prod.cjs +1129 -717
- package/dist/index.prod.cjs.map +1 -1
- package/dist/index.prod.d.ts +317 -136
- package/dist/index.prod.js +1114 -716
- package/dist/index.prod.js.map +1 -1
- package/package.json +1 -1
- package/src/Algorithm/floodFillSelection.ts +12 -14
- package/src/BlendModes/toBlendModeIndexAndName.ts +0 -7
- package/src/Clipboard/writeImgBlobToClipboard.ts +1 -1
- package/src/History/PixelMutator/mutatorApplyAlphaMask.ts +3 -0
- package/src/History/PixelMutator/mutatorApplyBinaryMask.ts +3 -0
- package/src/History/PixelMutator/mutatorApplyCircleBrush.ts +25 -6
- package/src/History/PixelMutator/mutatorApplyCircleBrushStroke.ts +89 -46
- package/src/History/PixelMutator/mutatorApplyCirclePencil.ts +7 -7
- package/src/History/PixelMutator/mutatorApplyCirclePencilStroke.ts +81 -41
- package/src/History/PixelMutator/mutatorApplyRectBrush.ts +3 -0
- package/src/History/PixelMutator/mutatorApplyRectBrushStroke.ts +18 -5
- package/src/History/PixelMutator/mutatorApplyRectPencil.ts +3 -0
- package/src/History/PixelMutator/mutatorApplyRectPencilStroke.ts +19 -4
- package/src/History/PixelMutator/mutatorBlendColor.ts +4 -0
- package/src/History/PixelMutator/mutatorBlendPixelData.ts +5 -1
- package/src/History/PixelMutator/mutatorBlendPixelDataAlphaMask.ts +33 -0
- package/src/History/PixelMutator/mutatorBlendPixelDataBinaryMask.ts +33 -0
- package/src/History/PixelMutator/mutatorClear.ts +12 -10
- package/src/History/PixelMutator/mutatorFill.ts +7 -4
- package/src/History/PixelMutator/mutatorFillBinaryMask.ts +28 -0
- package/src/History/PixelMutator/mutatorInvert.ts +3 -0
- package/src/History/PixelMutator.ts +14 -11
- package/src/ImageData/extractImageDataBuffer.ts +3 -3
- package/src/ImageData/{imageDataToAlphaMask.ts → imageDataToAlphaMaskBuffer.ts} +3 -4
- package/src/ImageData/resizeImageData.ts +3 -5
- package/src/ImageData/writeImageDataBuffer.ts +7 -7
- package/src/Mask/AlphaMask.ts +16 -0
- package/src/Mask/BinaryMask.ts +16 -0
- package/src/Mask/CircleBrushAlphaMask.ts +32 -0
- package/src/Mask/CircleBrushBinaryMask.ts +30 -0
- package/src/Mask/applyBinaryMaskToAlphaMask.ts +12 -9
- package/src/Mask/copyMask.ts +9 -3
- package/src/Mask/extractMask.ts +33 -31
- package/src/Mask/extractMaskBuffer.ts +87 -0
- package/src/Mask/invertMask.ts +6 -4
- package/src/Mask/mergeAlphaMasks.ts +11 -10
- package/src/Mask/mergeBinaryMasks.ts +10 -9
- package/src/Mask/setMaskData.ts +7 -0
- package/src/MaskRect/merge2BinaryMaskRects.ts +81 -0
- package/src/MaskRect/mergeBinaryMaskRects.ts +39 -0
- package/src/MaskRect/subtractBinaryMaskRects.ts +80 -0
- package/src/PixelData/applyAlphaMaskToPixelData.ts +8 -5
- package/src/PixelData/applyBinaryMaskToPixelData.ts +8 -9
- package/src/PixelData/applyCircleBrushToPixelData.ts +54 -62
- package/src/PixelData/blendColorPixelDataAlphaMask.ts +35 -25
- package/src/PixelData/blendColorPixelDataBinaryMask.ts +26 -19
- package/src/PixelData/blendPixelData.ts +1 -1
- package/src/PixelData/blendPixelDataAlphaMask.ts +3 -3
- package/src/PixelData/blendPixelDataBinaryMask.ts +4 -4
- package/src/PixelData/fillPixelData.ts +15 -42
- package/src/PixelData/fillPixelDataBinaryMask.ts +79 -0
- package/src/PixelData/invertPixelData.ts +3 -3
- package/src/PixelData/pixelDataToAlphaMask.ts +4 -2
- package/src/PixelData/writePixelDataBuffer.ts +2 -3
- package/src/Rect/getRectsBounds.ts +22 -0
- package/src/Rect/trimRectBounds.ts +20 -17
- package/src/_types.ts +55 -29
- package/src/index.ts +18 -1
package/dist/index.dev.cjs
CHANGED
|
@@ -75,11 +75,13 @@ __export(src_exports, {
|
|
|
75
75
|
exclusionPerfect: () => exclusionPerfect,
|
|
76
76
|
extractImageDataBuffer: () => extractImageDataBuffer,
|
|
77
77
|
extractMask: () => extractMask,
|
|
78
|
+
extractMaskBuffer: () => extractMaskBuffer,
|
|
78
79
|
extractPixelData: () => extractPixelData,
|
|
79
80
|
extractPixelDataBuffer: () => extractPixelDataBuffer,
|
|
80
81
|
fileInputChangeToImageData: () => fileInputChangeToImageData,
|
|
81
82
|
fileToImageData: () => fileToImageData,
|
|
82
83
|
fillPixelData: () => fillPixelData,
|
|
84
|
+
fillPixelDataBinaryMask: () => fillPixelDataBinaryMask,
|
|
83
85
|
floodFillSelection: () => floodFillSelection,
|
|
84
86
|
forEachLinePoint: () => forEachLinePoint,
|
|
85
87
|
getCircleBrushOrPencilBounds: () => getCircleBrushOrPencilBounds,
|
|
@@ -88,12 +90,13 @@ __export(src_exports, {
|
|
|
88
90
|
getIndexedImageColorCounts: () => getIndexedImageColorCounts,
|
|
89
91
|
getRectBrushOrPencilBounds: () => getRectBrushOrPencilBounds,
|
|
90
92
|
getRectBrushOrPencilStrokeBounds: () => getRectBrushOrPencilStrokeBounds,
|
|
93
|
+
getRectsBounds: () => getRectsBounds,
|
|
91
94
|
getSupportedPixelFormats: () => getSupportedPixelFormats,
|
|
92
95
|
hardLightFast: () => hardLightFast,
|
|
93
96
|
hardLightPerfect: () => hardLightPerfect,
|
|
94
97
|
hardMixFast: () => hardMixFast,
|
|
95
98
|
hardMixPerfect: () => hardMixPerfect,
|
|
96
|
-
|
|
99
|
+
imageDataToAlphaMaskBuffer: () => imageDataToAlphaMaskBuffer,
|
|
97
100
|
imageDataToDataUrl: () => imageDataToDataUrl,
|
|
98
101
|
imageDataToImgBlob: () => imageDataToImgBlob,
|
|
99
102
|
imageDataToUInt32Array: () => imageDataToUInt32Array,
|
|
@@ -116,7 +119,11 @@ __export(src_exports, {
|
|
|
116
119
|
linearDodgePerfect: () => linearDodgePerfect,
|
|
117
120
|
linearLightFast: () => linearLightFast,
|
|
118
121
|
linearLightPerfect: () => linearLightPerfect,
|
|
122
|
+
makeAlphaMask: () => makeAlphaMask,
|
|
123
|
+
makeBinaryMask: () => makeBinaryMask,
|
|
119
124
|
makeBlendModeRegistry: () => makeBlendModeRegistry,
|
|
125
|
+
makeCircleBrushAlphaMask: () => makeCircleBrushAlphaMask,
|
|
126
|
+
makeCircleBrushBinaryMask: () => makeCircleBrushBinaryMask,
|
|
120
127
|
makeFastBlendModeRegistry: () => makeFastBlendModeRegistry,
|
|
121
128
|
makeFullPixelMutator: () => makeFullPixelMutator,
|
|
122
129
|
makeImageDataLike: () => makeImageDataLike,
|
|
@@ -124,7 +131,9 @@ __export(src_exports, {
|
|
|
124
131
|
makePixelCanvas: () => makePixelCanvas,
|
|
125
132
|
makeReusableCanvas: () => makeReusableCanvas,
|
|
126
133
|
makeReusableImageData: () => makeReusableImageData,
|
|
134
|
+
merge2BinaryMaskRects: () => merge2BinaryMaskRects,
|
|
127
135
|
mergeAlphaMasks: () => mergeAlphaMasks,
|
|
136
|
+
mergeBinaryMaskRects: () => mergeBinaryMaskRects,
|
|
128
137
|
mergeBinaryMasks: () => mergeBinaryMasks,
|
|
129
138
|
multiplyFast: () => multiplyFast,
|
|
130
139
|
multiplyPerfect: () => multiplyPerfect,
|
|
@@ -141,8 +150,11 @@ __export(src_exports, {
|
|
|
141
150
|
mutatorBlendColor: () => mutatorBlendColor,
|
|
142
151
|
mutatorBlendPixel: () => mutatorBlendPixel,
|
|
143
152
|
mutatorBlendPixelData: () => mutatorBlendPixelData,
|
|
153
|
+
mutatorBlendPixelDataAlphaMask: () => mutatorBlendPixelDataAlphaMask,
|
|
154
|
+
mutatorBlendPixelDataBinaryMask: () => mutatorBlendPixelDataBinaryMask,
|
|
144
155
|
mutatorClear: () => mutatorClear,
|
|
145
156
|
mutatorFill: () => mutatorFill,
|
|
157
|
+
mutatorFillBinaryMask: () => mutatorFillBinaryMask,
|
|
146
158
|
mutatorInvert: () => mutatorInvert,
|
|
147
159
|
overlayFast: () => overlayFast,
|
|
148
160
|
overlayPerfect: () => overlayPerfect,
|
|
@@ -165,10 +177,12 @@ __export(src_exports, {
|
|
|
165
177
|
screenPerfect: () => screenPerfect,
|
|
166
178
|
serializeImageData: () => serializeImageData,
|
|
167
179
|
serializeNullableImageData: () => serializeNullableImageData,
|
|
180
|
+
setMaskData: () => setMaskData,
|
|
168
181
|
softLightFast: () => softLightFast,
|
|
169
182
|
softLightPerfect: () => softLightPerfect,
|
|
170
183
|
sourceOverFast: () => sourceOverFast,
|
|
171
184
|
sourceOverPerfect: () => sourceOverPerfect,
|
|
185
|
+
subtractBinaryMaskRects: () => subtractBinaryMaskRects,
|
|
172
186
|
subtractFast: () => subtractFast,
|
|
173
187
|
subtractPerfect: () => subtractPerfect,
|
|
174
188
|
toBlendModeIndexAndName: () => toBlendModeIndexAndName,
|
|
@@ -389,8 +403,8 @@ function extractImageDataBuffer(imageData, _x, _y, _w, _h) {
|
|
|
389
403
|
return out;
|
|
390
404
|
}
|
|
391
405
|
|
|
392
|
-
// src/Mask/
|
|
393
|
-
function
|
|
406
|
+
// src/Mask/extractMaskBuffer.ts
|
|
407
|
+
function extractMaskBuffer(maskBuffer, maskWidth, xOrRect, y, w, h) {
|
|
394
408
|
let finalX;
|
|
395
409
|
let finalY;
|
|
396
410
|
let finalW;
|
|
@@ -407,7 +421,7 @@ function extractMask(mask, maskWidth, xOrRect, y, w, h) {
|
|
|
407
421
|
finalH = h;
|
|
408
422
|
}
|
|
409
423
|
const out = new Uint8Array(finalW * finalH);
|
|
410
|
-
const srcH =
|
|
424
|
+
const srcH = maskBuffer.length / maskWidth;
|
|
411
425
|
for (let row = 0; row < finalH; row++) {
|
|
412
426
|
const currentSrcY = finalY + row;
|
|
413
427
|
if (currentSrcY < 0 || currentSrcY >= srcH) {
|
|
@@ -419,7 +433,7 @@ function extractMask(mask, maskWidth, xOrRect, y, w, h) {
|
|
|
419
433
|
const srcOffset = currentSrcY * maskWidth + start;
|
|
420
434
|
const dstOffset = row * finalW + (start - finalX);
|
|
421
435
|
const count = end - start;
|
|
422
|
-
out.set(
|
|
436
|
+
out.set(maskBuffer.subarray(srcOffset, srcOffset + count), dstOffset);
|
|
423
437
|
}
|
|
424
438
|
}
|
|
425
439
|
return out;
|
|
@@ -437,8 +451,8 @@ function trimRectBounds(target, bounds) {
|
|
|
437
451
|
if (intersectedMaxX <= intersectedX || intersectedMaxY <= intersectedY) {
|
|
438
452
|
target.w = 0;
|
|
439
453
|
target.h = 0;
|
|
440
|
-
if ("
|
|
441
|
-
target.
|
|
454
|
+
if ("data" in target && target.data) {
|
|
455
|
+
target.data = new Uint8Array(0);
|
|
442
456
|
}
|
|
443
457
|
return;
|
|
444
458
|
}
|
|
@@ -450,15 +464,15 @@ function trimRectBounds(target, bounds) {
|
|
|
450
464
|
target.y = intersectedY;
|
|
451
465
|
target.w = intersectedW;
|
|
452
466
|
target.h = intersectedH;
|
|
453
|
-
if ("
|
|
454
|
-
const
|
|
467
|
+
if ("data" in target && target.data) {
|
|
468
|
+
const currentMaskBuffer = extractMaskBuffer(target.data, originalW, offsetX, offsetY, intersectedW, intersectedH);
|
|
455
469
|
let minX = intersectedW;
|
|
456
470
|
let maxX = -1;
|
|
457
471
|
let minY = intersectedH;
|
|
458
472
|
let maxY = -1;
|
|
459
473
|
for (let y = 0; y < intersectedH; y++) {
|
|
460
474
|
for (let x = 0; x < intersectedW; x++) {
|
|
461
|
-
if (
|
|
475
|
+
if (currentMaskBuffer[y * intersectedW + x] !== 0) {
|
|
462
476
|
if (x < minX) minX = x;
|
|
463
477
|
if (x > maxX) maxX = x;
|
|
464
478
|
if (y < minY) minY = y;
|
|
@@ -469,19 +483,22 @@ function trimRectBounds(target, bounds) {
|
|
|
469
483
|
if (maxX === -1) {
|
|
470
484
|
target.w = 0;
|
|
471
485
|
target.h = 0;
|
|
472
|
-
target.
|
|
486
|
+
target.data = new Uint8Array(0);
|
|
473
487
|
return;
|
|
474
488
|
}
|
|
475
489
|
const finalW = maxX - minX + 1;
|
|
476
490
|
const finalH = maxY - minY + 1;
|
|
477
491
|
if (finalW !== intersectedW || finalH !== intersectedH) {
|
|
478
|
-
|
|
492
|
+
const newMaskBuffer = extractMaskBuffer(currentMaskBuffer, intersectedW, minX, minY, finalW, finalH);
|
|
479
493
|
target.x += minX;
|
|
480
494
|
target.y += minY;
|
|
481
495
|
target.w = finalW;
|
|
482
496
|
target.h = finalH;
|
|
497
|
+
target.data = newMaskBuffer;
|
|
483
498
|
} else {
|
|
484
|
-
target.
|
|
499
|
+
target.w = finalW;
|
|
500
|
+
target.h = finalH;
|
|
501
|
+
target.data = currentMaskBuffer;
|
|
485
502
|
}
|
|
486
503
|
}
|
|
487
504
|
}
|
|
@@ -591,17 +608,19 @@ function floodFillSelection(img, startX, startY, {
|
|
|
591
608
|
if (matchCount === 0) {
|
|
592
609
|
return null;
|
|
593
610
|
}
|
|
611
|
+
const w = maxX - minX + 1;
|
|
612
|
+
const h = maxY - minY + 1;
|
|
594
613
|
const selectionRect = {
|
|
595
614
|
x: minX,
|
|
596
615
|
y: minY,
|
|
597
|
-
w
|
|
598
|
-
h
|
|
599
|
-
|
|
600
|
-
|
|
616
|
+
w,
|
|
617
|
+
h,
|
|
618
|
+
data: new Uint8Array(w * h),
|
|
619
|
+
type: 1 /* BINARY */
|
|
601
620
|
};
|
|
602
621
|
const sw = selectionRect.w;
|
|
603
622
|
const sh = selectionRect.h;
|
|
604
|
-
const finalMask = selectionRect.
|
|
623
|
+
const finalMask = selectionRect.data;
|
|
605
624
|
for (let i = 0; i < matchCount; i++) {
|
|
606
625
|
const mx = matchX[i] - selectionRect.x;
|
|
607
626
|
const my = matchY[i] - selectionRect.y;
|
|
@@ -1676,16 +1695,7 @@ function toBlendModeIndexAndName(input) {
|
|
|
1676
1695
|
const num = Number(trimmed);
|
|
1677
1696
|
const isNumeric = trimmed !== "" && !Number.isNaN(num);
|
|
1678
1697
|
if (isNumeric && Number.isInteger(num)) {
|
|
1679
|
-
console.log({
|
|
1680
|
-
trimmed,
|
|
1681
|
-
num,
|
|
1682
|
-
isNumeric,
|
|
1683
|
-
isInt: Number.isInteger(num)
|
|
1684
|
-
});
|
|
1685
1698
|
const name = getKeyByValue(BaseBlendMode, num);
|
|
1686
|
-
console.log({
|
|
1687
|
-
name
|
|
1688
|
-
});
|
|
1689
1699
|
if (name === void 0) throw new Error(`Invalid index: ${num}`);
|
|
1690
1700
|
return {
|
|
1691
1701
|
blendIndex: num,
|
|
@@ -2059,7 +2069,6 @@ function applyAlphaMaskToPixelData(dst, mask, opts = {}) {
|
|
|
2059
2069
|
w: width = dst.width,
|
|
2060
2070
|
h: height = dst.height,
|
|
2061
2071
|
alpha: globalAlpha = 255,
|
|
2062
|
-
mw,
|
|
2063
2072
|
mx = 0,
|
|
2064
2073
|
my = 0,
|
|
2065
2074
|
invertMask = false
|
|
@@ -2081,15 +2090,14 @@ function applyAlphaMaskToPixelData(dst, mask, opts = {}) {
|
|
|
2081
2090
|
h = Math.min(h, dst.height - y);
|
|
2082
2091
|
if (w <= 0) return;
|
|
2083
2092
|
if (h <= 0) return;
|
|
2084
|
-
const mPitch =
|
|
2093
|
+
const mPitch = mask.w;
|
|
2085
2094
|
if (mPitch <= 0) return;
|
|
2086
|
-
const maskHeight = mask.length / mPitch | 0;
|
|
2087
2095
|
const startX = mx + (x - targetX);
|
|
2088
2096
|
const startY = my + (y - targetY);
|
|
2089
2097
|
const sX0 = Math.max(0, startX);
|
|
2090
2098
|
const sY0 = Math.max(0, startY);
|
|
2091
2099
|
const sX1 = Math.min(mPitch, startX + w);
|
|
2092
|
-
const sY1 = Math.min(
|
|
2100
|
+
const sY1 = Math.min(mask.h, startY + h);
|
|
2093
2101
|
const finalW = sX1 - sX0;
|
|
2094
2102
|
const finalH = sY1 - sY0;
|
|
2095
2103
|
if (finalW <= 0) return;
|
|
@@ -2100,11 +2108,12 @@ function applyAlphaMaskToPixelData(dst, mask, opts = {}) {
|
|
|
2100
2108
|
const dw = dst.width;
|
|
2101
2109
|
const dStride = dw - finalW;
|
|
2102
2110
|
const mStride = mPitch - finalW;
|
|
2111
|
+
const maskData = mask.data;
|
|
2103
2112
|
let dIdx = (y + yShift) * dw + (x + xShift);
|
|
2104
2113
|
let mIdx = sY0 * mPitch + sX0;
|
|
2105
2114
|
for (let iy = 0; iy < h; iy++) {
|
|
2106
2115
|
for (let ix = 0; ix < w; ix++) {
|
|
2107
|
-
const mVal =
|
|
2116
|
+
const mVal = maskData[mIdx];
|
|
2108
2117
|
const effectiveM = invertMask ? 255 - mVal : mVal;
|
|
2109
2118
|
let weight = 0;
|
|
2110
2119
|
if (effectiveM === 0) {
|
|
@@ -2164,13 +2173,12 @@ function applyBinaryMaskToPixelData(dst, mask, opts = {}) {
|
|
|
2164
2173
|
y: targetY = 0,
|
|
2165
2174
|
w: width = dst.width,
|
|
2166
2175
|
h: height = dst.height,
|
|
2167
|
-
alpha = 255,
|
|
2168
|
-
mw,
|
|
2176
|
+
alpha: globalAlpha = 255,
|
|
2169
2177
|
mx = 0,
|
|
2170
2178
|
my = 0,
|
|
2171
2179
|
invertMask = false
|
|
2172
2180
|
} = opts;
|
|
2173
|
-
if (
|
|
2181
|
+
if (globalAlpha === 0) return;
|
|
2174
2182
|
let x = targetX;
|
|
2175
2183
|
let y = targetY;
|
|
2176
2184
|
let w = width;
|
|
@@ -2187,15 +2195,14 @@ function applyBinaryMaskToPixelData(dst, mask, opts = {}) {
|
|
|
2187
2195
|
h = Math.min(h, dst.height - y);
|
|
2188
2196
|
if (w <= 0) return;
|
|
2189
2197
|
if (h <= 0) return;
|
|
2190
|
-
const mPitch =
|
|
2198
|
+
const mPitch = mask.w;
|
|
2191
2199
|
if (mPitch <= 0) return;
|
|
2192
|
-
const maskHeight = mask.length / mPitch | 0;
|
|
2193
2200
|
const startX = mx + (x - targetX);
|
|
2194
2201
|
const startY = my + (y - targetY);
|
|
2195
2202
|
const sX0 = Math.max(0, startX);
|
|
2196
2203
|
const sY0 = Math.max(0, startY);
|
|
2197
2204
|
const sX1 = Math.min(mPitch, startX + w);
|
|
2198
|
-
const sY1 = Math.min(
|
|
2205
|
+
const sY1 = Math.min(mask.h, startY + h);
|
|
2199
2206
|
const finalW = sX1 - sX0;
|
|
2200
2207
|
const finalH = sY1 - sY0;
|
|
2201
2208
|
if (finalW <= 0) return;
|
|
@@ -2206,19 +2213,20 @@ function applyBinaryMaskToPixelData(dst, mask, opts = {}) {
|
|
|
2206
2213
|
const dw = dst.width;
|
|
2207
2214
|
const dStride = dw - finalW;
|
|
2208
2215
|
const mStride = mPitch - finalW;
|
|
2216
|
+
const maskData = mask.data;
|
|
2209
2217
|
let dIdx = (y + yShift) * dw + (x + xShift);
|
|
2210
2218
|
let mIdx = sY0 * mPitch + sX0;
|
|
2211
2219
|
for (let iy = 0; iy < h; iy++) {
|
|
2212
2220
|
for (let ix = 0; ix < w; ix++) {
|
|
2213
|
-
const mVal =
|
|
2221
|
+
const mVal = maskData[mIdx];
|
|
2214
2222
|
const isMaskedOut = invertMask ? mVal !== 0 : mVal === 0;
|
|
2215
2223
|
if (isMaskedOut) {
|
|
2216
2224
|
dst32[dIdx] = (dst32[dIdx] & 16777215) >>> 0;
|
|
2217
|
-
} else if (
|
|
2225
|
+
} else if (globalAlpha !== 255) {
|
|
2218
2226
|
const d = dst32[dIdx];
|
|
2219
2227
|
const da = d >>> 24;
|
|
2220
2228
|
if (da !== 0) {
|
|
2221
|
-
const finalAlpha = da === 255 ?
|
|
2229
|
+
const finalAlpha = da === 255 ? globalAlpha : da * globalAlpha + 128 >> 8;
|
|
2222
2230
|
dst32[dIdx] = (d & 16777215 | finalAlpha << 24) >>> 0;
|
|
2223
2231
|
}
|
|
2224
2232
|
}
|
|
@@ -2281,144 +2289,42 @@ function getCircleBrushOrPencilBounds(centerX, centerY, brushSize, targetWidth,
|
|
|
2281
2289
|
return res;
|
|
2282
2290
|
}
|
|
2283
2291
|
|
|
2284
|
-
// src/PixelData/applyCircleBrushToPixelData.ts
|
|
2285
|
-
function applyCircleBrushToPixelData(target, color, centerX, centerY, brushSize, alpha = 255, fallOff, blendFn = sourceOverPerfect, bounds) {
|
|
2286
|
-
const targetWidth = target.width;
|
|
2287
|
-
const targetHeight = target.height;
|
|
2288
|
-
const b = bounds ?? getCircleBrushOrPencilBounds(centerX, centerY, brushSize, targetWidth, targetHeight);
|
|
2289
|
-
if (b.w <= 0 || b.h <= 0) return;
|
|
2290
|
-
const data32 = target.data32;
|
|
2291
|
-
const r = brushSize / 2;
|
|
2292
|
-
const rSqr = r * r;
|
|
2293
|
-
const invR = 1 / r;
|
|
2294
|
-
const centerOffset = brushSize % 2 === 0 ? 0.5 : 0;
|
|
2295
|
-
const endX = b.x + b.w;
|
|
2296
|
-
const endY = b.y + b.h;
|
|
2297
|
-
const fCenterX = Math.floor(centerX);
|
|
2298
|
-
const fCenterY = Math.floor(centerY);
|
|
2299
|
-
const baseSrcAlpha = color >>> 24;
|
|
2300
|
-
const colorRGB = color & 16777215;
|
|
2301
|
-
const isOpaque = alpha === 255;
|
|
2302
|
-
const isOverwrite = blendFn.isOverwrite;
|
|
2303
|
-
for (let cy = b.y; cy < endY; cy++) {
|
|
2304
|
-
const relY = cy - fCenterY + centerOffset;
|
|
2305
|
-
const dySqr = relY * relY;
|
|
2306
|
-
const rowOffset = cy * targetWidth;
|
|
2307
|
-
for (let cx = b.x; cx < endX; cx++) {
|
|
2308
|
-
const relX = cx - fCenterX + centerOffset;
|
|
2309
|
-
const dSqr = relX * relX + dySqr;
|
|
2310
|
-
if (dSqr <= rSqr) {
|
|
2311
|
-
const idx = rowOffset + cx;
|
|
2312
|
-
let weight = alpha;
|
|
2313
|
-
const strength = fallOff(1 - Math.sqrt(dSqr) * invR);
|
|
2314
|
-
const maskVal = strength * 255 | 0;
|
|
2315
|
-
if (maskVal === 0) continue;
|
|
2316
|
-
if (isOpaque) {
|
|
2317
|
-
weight = maskVal;
|
|
2318
|
-
} else if (maskVal !== 255) {
|
|
2319
|
-
weight = maskVal * alpha + 128 >> 8;
|
|
2320
|
-
}
|
|
2321
|
-
let finalCol = color;
|
|
2322
|
-
if (weight < 255) {
|
|
2323
|
-
const a = baseSrcAlpha * weight + 128 >> 8;
|
|
2324
|
-
if (a === 0 && !isOverwrite) continue;
|
|
2325
|
-
finalCol = (colorRGB | a << 24) >>> 0;
|
|
2326
|
-
}
|
|
2327
|
-
data32[idx] = blendFn(finalCol, data32[idx]);
|
|
2328
|
-
}
|
|
2329
|
-
}
|
|
2330
|
-
}
|
|
2331
|
-
}
|
|
2332
|
-
|
|
2333
|
-
// src/History/PixelMutator/mutatorApplyCircleBrush.ts
|
|
2334
|
-
var defaults3 = {
|
|
2335
|
-
applyCircleBrushToPixelData,
|
|
2336
|
-
getCircleBrushOrPencilBounds
|
|
2337
|
-
};
|
|
2338
|
-
var mutatorApplyCircleBrush = ((writer, deps = defaults3) => {
|
|
2339
|
-
const {
|
|
2340
|
-
applyCircleBrushToPixelData: applyCircleBrushToPixelData2 = defaults3.applyCircleBrushToPixelData,
|
|
2341
|
-
getCircleBrushOrPencilBounds: getCircleBrushOrPencilBounds2 = defaults3.getCircleBrushOrPencilBounds
|
|
2342
|
-
} = deps;
|
|
2343
|
-
const boundsOut = {
|
|
2344
|
-
x: 0,
|
|
2345
|
-
y: 0,
|
|
2346
|
-
w: 0,
|
|
2347
|
-
h: 0
|
|
2348
|
-
};
|
|
2349
|
-
return {
|
|
2350
|
-
applyCircleBrush(color, centerX, centerY, brushSize, alpha = 255, fallOff, blendFn) {
|
|
2351
|
-
const bounds = getCircleBrushOrPencilBounds2(centerX, centerY, brushSize, writer.target.width, writer.target.height, boundsOut);
|
|
2352
|
-
const {
|
|
2353
|
-
x,
|
|
2354
|
-
y,
|
|
2355
|
-
w,
|
|
2356
|
-
h
|
|
2357
|
-
} = bounds;
|
|
2358
|
-
writer.accumulator.storeRegionBeforeState(x, y, w, h);
|
|
2359
|
-
applyCircleBrushToPixelData2(writer.target, color, centerX, centerY, brushSize, alpha, fallOff, blendFn, bounds);
|
|
2360
|
-
}
|
|
2361
|
-
};
|
|
2362
|
-
});
|
|
2363
|
-
|
|
2364
|
-
// src/Algorithm/forEachLinePoint.ts
|
|
2365
|
-
function forEachLinePoint(x0, y0, x1, y1, callback) {
|
|
2366
|
-
const dx = x1 - x0;
|
|
2367
|
-
const dy = y1 - y0;
|
|
2368
|
-
const steps = Math.max(Math.abs(dx), Math.abs(dy));
|
|
2369
|
-
if (steps === 0) {
|
|
2370
|
-
callback(x0, y0);
|
|
2371
|
-
return;
|
|
2372
|
-
}
|
|
2373
|
-
const xInc = dx / steps;
|
|
2374
|
-
const yInc = dy / steps;
|
|
2375
|
-
let curX = x0;
|
|
2376
|
-
let curY = y0;
|
|
2377
|
-
for (let i = 0; i <= steps; i++) {
|
|
2378
|
-
callback(curX, curY);
|
|
2379
|
-
curX += xInc;
|
|
2380
|
-
curY += yInc;
|
|
2381
|
-
}
|
|
2382
|
-
}
|
|
2383
|
-
|
|
2384
2292
|
// src/PixelData/blendColorPixelDataAlphaMask.ts
|
|
2385
|
-
function blendColorPixelDataAlphaMask(dst, color, mask, opts) {
|
|
2386
|
-
const
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
invertMask = false
|
|
2397
|
-
} = opts;
|
|
2398
|
-
if (globalAlpha === 0 || !mask) return;
|
|
2293
|
+
function blendColorPixelDataAlphaMask(dst, color, mask, opts = {}) {
|
|
2294
|
+
const targetX = opts.x ?? 0;
|
|
2295
|
+
const targetY = opts.y ?? 0;
|
|
2296
|
+
const w = opts.w ?? mask.w;
|
|
2297
|
+
const h = opts.h ?? mask.h;
|
|
2298
|
+
const globalAlpha = opts.alpha ?? 255;
|
|
2299
|
+
const blendFn = opts.blendFn ?? sourceOverPerfect;
|
|
2300
|
+
const mx = opts.mx ?? 0;
|
|
2301
|
+
const my = opts.my ?? 0;
|
|
2302
|
+
const invertMask = opts.invertMask ?? false;
|
|
2303
|
+
if (globalAlpha === 0) return;
|
|
2399
2304
|
const baseSrcAlpha = color >>> 24;
|
|
2400
2305
|
const isOverwrite = blendFn.isOverwrite || false;
|
|
2401
2306
|
if (baseSrcAlpha === 0 && !isOverwrite) return;
|
|
2402
2307
|
let x = targetX;
|
|
2403
2308
|
let y = targetY;
|
|
2404
|
-
let
|
|
2405
|
-
let
|
|
2309
|
+
let actualW = w;
|
|
2310
|
+
let actualH = h;
|
|
2406
2311
|
if (x < 0) {
|
|
2407
|
-
|
|
2312
|
+
actualW += x;
|
|
2408
2313
|
x = 0;
|
|
2409
2314
|
}
|
|
2410
2315
|
if (y < 0) {
|
|
2411
|
-
|
|
2316
|
+
actualH += y;
|
|
2412
2317
|
y = 0;
|
|
2413
2318
|
}
|
|
2414
|
-
|
|
2415
|
-
|
|
2319
|
+
actualW = Math.min(actualW, dst.width - x);
|
|
2320
|
+
actualH = Math.min(actualH, dst.height - y);
|
|
2416
2321
|
if (actualW <= 0 || actualH <= 0) return;
|
|
2417
2322
|
const dx = x - targetX | 0;
|
|
2418
2323
|
const dy = y - targetY | 0;
|
|
2419
2324
|
const dst32 = dst.data32;
|
|
2420
2325
|
const dw = dst.width;
|
|
2421
|
-
const mPitch =
|
|
2326
|
+
const mPitch = mask.w;
|
|
2327
|
+
const maskData = mask.data;
|
|
2422
2328
|
let dIdx = y * dw + x | 0;
|
|
2423
2329
|
let mIdx = (my + dy) * mPitch + (mx + dx) | 0;
|
|
2424
2330
|
const dStride = dw - actualW | 0;
|
|
@@ -2427,7 +2333,7 @@ function blendColorPixelDataAlphaMask(dst, color, mask, opts) {
|
|
|
2427
2333
|
const colorRGB = color & 16777215;
|
|
2428
2334
|
for (let iy = 0; iy < actualH; iy++) {
|
|
2429
2335
|
for (let ix = 0; ix < actualW; ix++) {
|
|
2430
|
-
const mVal =
|
|
2336
|
+
const mVal = maskData[mIdx];
|
|
2431
2337
|
const effM = invertMask ? 255 - mVal : mVal;
|
|
2432
2338
|
if (effM === 0) {
|
|
2433
2339
|
dIdx++;
|
|
@@ -2464,6 +2370,155 @@ function blendColorPixelDataAlphaMask(dst, color, mask, opts) {
|
|
|
2464
2370
|
}
|
|
2465
2371
|
}
|
|
2466
2372
|
|
|
2373
|
+
// src/PixelData/blendColorPixelDataBinaryMask.ts
|
|
2374
|
+
function blendColorPixelDataBinaryMask(dst, color, mask, opts = {}) {
|
|
2375
|
+
const targetX = opts.x ?? 0;
|
|
2376
|
+
const targetY = opts.y ?? 0;
|
|
2377
|
+
let w = opts.w ?? mask.w;
|
|
2378
|
+
let h = opts.h ?? mask.h;
|
|
2379
|
+
const globalAlpha = opts.alpha ?? 255;
|
|
2380
|
+
const blendFn = opts.blendFn ?? sourceOverPerfect;
|
|
2381
|
+
const mx = opts.mx ?? 0;
|
|
2382
|
+
const my = opts.my ?? 0;
|
|
2383
|
+
const invertMask = opts.invertMask ?? false;
|
|
2384
|
+
if (globalAlpha === 0) return;
|
|
2385
|
+
const baseSrcAlpha = color >>> 24;
|
|
2386
|
+
const isOverwrite = blendFn.isOverwrite || false;
|
|
2387
|
+
if (baseSrcAlpha === 0 && !isOverwrite) return;
|
|
2388
|
+
let x = targetX;
|
|
2389
|
+
let y = targetY;
|
|
2390
|
+
if (x < 0) {
|
|
2391
|
+
w += x;
|
|
2392
|
+
x = 0;
|
|
2393
|
+
}
|
|
2394
|
+
if (y < 0) {
|
|
2395
|
+
h += y;
|
|
2396
|
+
y = 0;
|
|
2397
|
+
}
|
|
2398
|
+
const actualW = Math.min(w, dst.width - x);
|
|
2399
|
+
const actualH = Math.min(h, dst.height - y);
|
|
2400
|
+
if (actualW <= 0 || actualH <= 0) return;
|
|
2401
|
+
let baseColorWithGlobalAlpha = color;
|
|
2402
|
+
if (globalAlpha < 255) {
|
|
2403
|
+
const a = baseSrcAlpha * globalAlpha + 128 >> 8;
|
|
2404
|
+
if (a === 0 && !isOverwrite) return;
|
|
2405
|
+
baseColorWithGlobalAlpha = (color & 16777215 | a << 24) >>> 0;
|
|
2406
|
+
}
|
|
2407
|
+
const dx = x - targetX | 0;
|
|
2408
|
+
const dy = y - targetY | 0;
|
|
2409
|
+
const dst32 = dst.data32;
|
|
2410
|
+
const dw = dst.width;
|
|
2411
|
+
const mPitch = mask.w;
|
|
2412
|
+
const maskData = mask.data;
|
|
2413
|
+
let dIdx = y * dw + x | 0;
|
|
2414
|
+
let mIdx = (my + dy) * mPitch + (mx + dx) | 0;
|
|
2415
|
+
const dStride = dw - actualW | 0;
|
|
2416
|
+
const mStride = mPitch - actualW | 0;
|
|
2417
|
+
const skipVal = invertMask ? 1 : 0;
|
|
2418
|
+
for (let iy = 0; iy < actualH; iy++) {
|
|
2419
|
+
for (let ix = 0; ix < actualW; ix++) {
|
|
2420
|
+
if (maskData[mIdx] === skipVal) {
|
|
2421
|
+
dIdx++;
|
|
2422
|
+
mIdx++;
|
|
2423
|
+
continue;
|
|
2424
|
+
}
|
|
2425
|
+
dst32[dIdx] = blendFn(baseColorWithGlobalAlpha, dst32[dIdx]);
|
|
2426
|
+
dIdx++;
|
|
2427
|
+
mIdx++;
|
|
2428
|
+
}
|
|
2429
|
+
dIdx += dStride;
|
|
2430
|
+
mIdx += mStride;
|
|
2431
|
+
}
|
|
2432
|
+
}
|
|
2433
|
+
|
|
2434
|
+
// src/PixelData/applyCircleBrushToPixelData.ts
|
|
2435
|
+
function applyCircleBrushToPixelData(target, color, centerX, centerY, brush, alpha = 255, blendFn = sourceOverPerfect, scratchOptions = {}, bounds) {
|
|
2436
|
+
const b = bounds ?? getCircleBrushOrPencilBounds(centerX, centerY, brush.size, target.width, target.height);
|
|
2437
|
+
if (b.w <= 0 || b.h <= 0) return;
|
|
2438
|
+
const unclippedStartX = Math.floor(centerX + brush.minOffset);
|
|
2439
|
+
const unclippedStartY = Math.floor(centerY + brush.minOffset);
|
|
2440
|
+
const ix = Math.max(unclippedStartX, b.x);
|
|
2441
|
+
const iy = Math.max(unclippedStartY, b.y);
|
|
2442
|
+
const ir = Math.min(unclippedStartX + brush.w, b.x + b.w);
|
|
2443
|
+
const ib = Math.min(unclippedStartY + brush.h, b.y + b.h);
|
|
2444
|
+
const iw = ir - ix;
|
|
2445
|
+
const ih = ib - iy;
|
|
2446
|
+
if (iw <= 0 || ih <= 0) return;
|
|
2447
|
+
scratchOptions.x = ix;
|
|
2448
|
+
scratchOptions.y = iy;
|
|
2449
|
+
scratchOptions.w = iw;
|
|
2450
|
+
scratchOptions.h = ih;
|
|
2451
|
+
scratchOptions.mx = ix - unclippedStartX;
|
|
2452
|
+
scratchOptions.my = iy - unclippedStartY;
|
|
2453
|
+
scratchOptions.alpha = alpha;
|
|
2454
|
+
scratchOptions.blendFn = blendFn;
|
|
2455
|
+
if (brush.type === 0 /* ALPHA */) {
|
|
2456
|
+
blendColorPixelDataAlphaMask(target, color, brush, scratchOptions);
|
|
2457
|
+
}
|
|
2458
|
+
if (brush.type === 1 /* BINARY */) {
|
|
2459
|
+
blendColorPixelDataBinaryMask(target, color, brush, scratchOptions);
|
|
2460
|
+
}
|
|
2461
|
+
}
|
|
2462
|
+
|
|
2463
|
+
// src/History/PixelMutator/mutatorApplyCircleBrush.ts
|
|
2464
|
+
var defaults3 = {
|
|
2465
|
+
applyCircleBrushToPixelData,
|
|
2466
|
+
getCircleBrushOrPencilBounds
|
|
2467
|
+
};
|
|
2468
|
+
var mutatorApplyCircleBrush = ((writer, deps = defaults3) => {
|
|
2469
|
+
const {
|
|
2470
|
+
applyCircleBrushToPixelData: applyCircleBrushToPixelData2 = defaults3.applyCircleBrushToPixelData,
|
|
2471
|
+
getCircleBrushOrPencilBounds: getCircleBrushOrPencilBounds2 = defaults3.getCircleBrushOrPencilBounds
|
|
2472
|
+
} = deps;
|
|
2473
|
+
const boundsOut = {
|
|
2474
|
+
x: 0,
|
|
2475
|
+
y: 0,
|
|
2476
|
+
w: 0,
|
|
2477
|
+
h: 0
|
|
2478
|
+
};
|
|
2479
|
+
const blendColorPixelOptions = {
|
|
2480
|
+
alpha: 255,
|
|
2481
|
+
blendFn: sourceOverPerfect,
|
|
2482
|
+
x: 0,
|
|
2483
|
+
y: 0,
|
|
2484
|
+
w: 0,
|
|
2485
|
+
h: 0
|
|
2486
|
+
};
|
|
2487
|
+
return {
|
|
2488
|
+
applyCircleBrush(color, centerX, centerY, brush, alpha = 255, blendFn) {
|
|
2489
|
+
const bounds = getCircleBrushOrPencilBounds2(centerX, centerY, brush.size, writer.target.width, writer.target.height, boundsOut);
|
|
2490
|
+
const {
|
|
2491
|
+
x,
|
|
2492
|
+
y,
|
|
2493
|
+
w,
|
|
2494
|
+
h
|
|
2495
|
+
} = bounds;
|
|
2496
|
+
writer.accumulator.storeRegionBeforeState(x, y, w, h);
|
|
2497
|
+
applyCircleBrushToPixelData2(writer.target, color, centerX, centerY, brush, alpha, blendFn, blendColorPixelOptions, bounds);
|
|
2498
|
+
}
|
|
2499
|
+
};
|
|
2500
|
+
});
|
|
2501
|
+
|
|
2502
|
+
// src/Algorithm/forEachLinePoint.ts
|
|
2503
|
+
function forEachLinePoint(x0, y0, x1, y1, callback) {
|
|
2504
|
+
const dx = x1 - x0;
|
|
2505
|
+
const dy = y1 - y0;
|
|
2506
|
+
const steps = Math.max(Math.abs(dx), Math.abs(dy));
|
|
2507
|
+
if (steps === 0) {
|
|
2508
|
+
callback(x0, y0);
|
|
2509
|
+
return;
|
|
2510
|
+
}
|
|
2511
|
+
const xInc = dx / steps;
|
|
2512
|
+
const yInc = dy / steps;
|
|
2513
|
+
let curX = x0;
|
|
2514
|
+
let curY = y0;
|
|
2515
|
+
for (let i = 0; i <= steps; i++) {
|
|
2516
|
+
callback(curX, curY);
|
|
2517
|
+
curX += xInc;
|
|
2518
|
+
curY += yInc;
|
|
2519
|
+
}
|
|
2520
|
+
}
|
|
2521
|
+
|
|
2467
2522
|
// src/Rect/getCircleBrushOrPencilStrokeBounds.ts
|
|
2468
2523
|
function getCircleBrushOrPencilStrokeBounds(x0, y0, x1, y1, brushSize, result) {
|
|
2469
2524
|
const r = Math.ceil(brushSize / 2);
|
|
@@ -2512,8 +2567,15 @@ var mutatorApplyCircleBrushStroke = ((writer, deps = defaults4) => {
|
|
|
2512
2567
|
w: 0,
|
|
2513
2568
|
h: 0
|
|
2514
2569
|
};
|
|
2570
|
+
const mask = {
|
|
2571
|
+
type: 0 /* ALPHA */,
|
|
2572
|
+
data: null,
|
|
2573
|
+
w: 0,
|
|
2574
|
+
h: 0
|
|
2575
|
+
};
|
|
2515
2576
|
return {
|
|
2516
|
-
applyCircleBrushStroke(color, x0, y0, x1, y1,
|
|
2577
|
+
applyCircleBrushStroke(color, x0, y0, x1, y1, brush, alpha = 255, blendFn = sourceOverPerfect) {
|
|
2578
|
+
const brushSize = brush.size;
|
|
2517
2579
|
const {
|
|
2518
2580
|
x: bx,
|
|
2519
2581
|
y: by,
|
|
@@ -2521,11 +2583,12 @@ var mutatorApplyCircleBrushStroke = ((writer, deps = defaults4) => {
|
|
|
2521
2583
|
h: bh
|
|
2522
2584
|
} = getCircleBrushOrPencilStrokeBounds2(x0, y0, x1, y1, brushSize, strokeBoundsOut);
|
|
2523
2585
|
if (bw <= 0 || bh <= 0) return;
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
const
|
|
2528
|
-
const
|
|
2586
|
+
mask.data = new Uint8Array(bw * bh);
|
|
2587
|
+
mask.w = bw;
|
|
2588
|
+
mask.h = bh;
|
|
2589
|
+
const maskData = mask.data;
|
|
2590
|
+
const brushData = brush.data;
|
|
2591
|
+
const minOffset = brush.minOffset;
|
|
2529
2592
|
const targetWidth = writer.target.width;
|
|
2530
2593
|
const targetHeight = writer.target.height;
|
|
2531
2594
|
forEachLinePoint2(x0, y0, x1, y1, (px, py) => {
|
|
@@ -2540,21 +2603,20 @@ var mutatorApplyCircleBrushStroke = ((writer, deps = defaults4) => {
|
|
|
2540
2603
|
const startY = Math.max(by, cby);
|
|
2541
2604
|
const endX = Math.min(bx + bw, cbx + cbw);
|
|
2542
2605
|
const endY = Math.min(by + bh, cby + cbh);
|
|
2543
|
-
const
|
|
2544
|
-
const
|
|
2606
|
+
const unclippedStartX = Math.floor(px + minOffset);
|
|
2607
|
+
const unclippedStartY = Math.floor(py + minOffset);
|
|
2545
2608
|
for (let my = startY; my < endY; my++) {
|
|
2546
|
-
const
|
|
2547
|
-
const
|
|
2548
|
-
const
|
|
2609
|
+
const strokeMaskY = my - by;
|
|
2610
|
+
const strokeMaskRowOffset = strokeMaskY * bw;
|
|
2611
|
+
const brushY = my - unclippedStartY;
|
|
2612
|
+
const brushRowOffset = brushY * brushSize;
|
|
2549
2613
|
for (let mx = startX; mx < endX; mx++) {
|
|
2550
|
-
const
|
|
2551
|
-
const
|
|
2552
|
-
if (
|
|
2553
|
-
const
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
if (intensity > mask[maskIdx]) {
|
|
2557
|
-
mask[maskIdx] = intensity;
|
|
2614
|
+
const brushX = mx - unclippedStartX;
|
|
2615
|
+
const brushVal = brushData[brushRowOffset + brushX];
|
|
2616
|
+
if (brushVal > 0) {
|
|
2617
|
+
const strokeMaskIdx = strokeMaskRowOffset + (mx - bx);
|
|
2618
|
+
if (brushVal > maskData[strokeMaskIdx]) {
|
|
2619
|
+
maskData[strokeMaskIdx] = brushVal;
|
|
2558
2620
|
}
|
|
2559
2621
|
}
|
|
2560
2622
|
}
|
|
@@ -2571,84 +2633,50 @@ var mutatorApplyCircleBrushStroke = ((writer, deps = defaults4) => {
|
|
|
2571
2633
|
};
|
|
2572
2634
|
});
|
|
2573
2635
|
|
|
2574
|
-
// src/
|
|
2575
|
-
|
|
2636
|
+
// src/History/PixelMutator/mutatorApplyCirclePencil.ts
|
|
2637
|
+
var defaults5 = {
|
|
2638
|
+
applyCircleBrushToPixelData,
|
|
2639
|
+
getCircleBrushOrPencilBounds
|
|
2640
|
+
};
|
|
2641
|
+
var mutatorApplyCirclePencil = ((writer, deps = defaults5) => {
|
|
2576
2642
|
const {
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
w += x;
|
|
2598
|
-
x = 0;
|
|
2599
|
-
}
|
|
2600
|
-
if (y < 0) {
|
|
2601
|
-
h += y;
|
|
2602
|
-
y = 0;
|
|
2603
|
-
}
|
|
2604
|
-
const actualW = Math.min(w, dst.width - x);
|
|
2605
|
-
const actualH = Math.min(h, dst.height - y);
|
|
2606
|
-
if (actualW <= 0 || actualH <= 0) return;
|
|
2607
|
-
let baseColorWithGlobalAlpha = color;
|
|
2608
|
-
if (globalAlpha < 255) {
|
|
2609
|
-
const a = baseSrcAlpha * globalAlpha + 128 >> 8;
|
|
2610
|
-
if (a === 0 && !isOverwrite) return;
|
|
2611
|
-
baseColorWithGlobalAlpha = (color & 16777215 | a << 24) >>> 0;
|
|
2612
|
-
}
|
|
2613
|
-
const dx = x - targetX | 0;
|
|
2614
|
-
const dy = y - targetY | 0;
|
|
2615
|
-
const dst32 = dst.data32;
|
|
2616
|
-
const dw = dst.width;
|
|
2617
|
-
const mPitch = mw;
|
|
2618
|
-
let dIdx = y * dw + x | 0;
|
|
2619
|
-
let mIdx = (my + dy) * mPitch + (mx + dx) | 0;
|
|
2620
|
-
const dStride = dw - actualW | 0;
|
|
2621
|
-
const mStride = mPitch - actualW | 0;
|
|
2622
|
-
const skipVal = invertMask ? 1 : 0;
|
|
2623
|
-
for (let iy = 0; iy < actualH; iy++) {
|
|
2624
|
-
for (let ix = 0; ix < actualW; ix++) {
|
|
2625
|
-
if (mask[mIdx] === skipVal) {
|
|
2626
|
-
dIdx++;
|
|
2627
|
-
mIdx++;
|
|
2628
|
-
continue;
|
|
2629
|
-
}
|
|
2630
|
-
dst32[dIdx] = blendFn(baseColorWithGlobalAlpha, dst32[dIdx]);
|
|
2631
|
-
dIdx++;
|
|
2632
|
-
mIdx++;
|
|
2643
|
+
applyCircleBrushToPixelData: applyCircleBrushToPixelData2 = defaults5.applyCircleBrushToPixelData,
|
|
2644
|
+
getCircleBrushOrPencilBounds: getCircleBrushOrPencilBounds2 = defaults5.getCircleBrushOrPencilBounds
|
|
2645
|
+
} = deps;
|
|
2646
|
+
const boundsOut = {
|
|
2647
|
+
x: 0,
|
|
2648
|
+
y: 0,
|
|
2649
|
+
w: 0,
|
|
2650
|
+
h: 0
|
|
2651
|
+
};
|
|
2652
|
+
return {
|
|
2653
|
+
applyCirclePencil(color, centerX, centerY, brush, alpha = 255, blendFn) {
|
|
2654
|
+
const bounds = getCircleBrushOrPencilBounds2(centerX, centerY, brush.size, writer.target.width, writer.target.height, boundsOut);
|
|
2655
|
+
const {
|
|
2656
|
+
x,
|
|
2657
|
+
y,
|
|
2658
|
+
w,
|
|
2659
|
+
h
|
|
2660
|
+
} = bounds;
|
|
2661
|
+
writer.accumulator.storeRegionBeforeState(x, y, w, h);
|
|
2662
|
+
applyCircleBrushToPixelData2(writer.target, color, centerX, centerY, brush, alpha, blendFn, bounds);
|
|
2633
2663
|
}
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
}
|
|
2637
|
-
}
|
|
2664
|
+
};
|
|
2665
|
+
});
|
|
2638
2666
|
|
|
2639
2667
|
// src/History/PixelMutator/mutatorApplyCirclePencilStroke.ts
|
|
2640
|
-
var
|
|
2668
|
+
var defaults6 = {
|
|
2641
2669
|
forEachLinePoint,
|
|
2642
2670
|
blendColorPixelDataBinaryMask,
|
|
2643
2671
|
getCircleBrushOrPencilBounds,
|
|
2644
2672
|
getCircleBrushOrPencilStrokeBounds
|
|
2645
2673
|
};
|
|
2646
|
-
var mutatorApplyCirclePencilStroke = ((writer, deps =
|
|
2674
|
+
var mutatorApplyCirclePencilStroke = ((writer, deps = defaults6) => {
|
|
2647
2675
|
const {
|
|
2648
|
-
forEachLinePoint: forEachLinePoint2 =
|
|
2649
|
-
blendColorPixelDataBinaryMask: blendColorPixelDataBinaryMask2 =
|
|
2650
|
-
getCircleBrushOrPencilStrokeBounds: getCircleBrushOrPencilStrokeBounds2 =
|
|
2651
|
-
getCircleBrushOrPencilBounds: getCircleBrushOrPencilBounds2 =
|
|
2676
|
+
forEachLinePoint: forEachLinePoint2 = defaults6.forEachLinePoint,
|
|
2677
|
+
blendColorPixelDataBinaryMask: blendColorPixelDataBinaryMask2 = defaults6.blendColorPixelDataBinaryMask,
|
|
2678
|
+
getCircleBrushOrPencilStrokeBounds: getCircleBrushOrPencilStrokeBounds2 = defaults6.getCircleBrushOrPencilStrokeBounds,
|
|
2679
|
+
getCircleBrushOrPencilBounds: getCircleBrushOrPencilBounds2 = defaults6.getCircleBrushOrPencilBounds
|
|
2652
2680
|
} = deps;
|
|
2653
2681
|
const strokeBoundsOut = {
|
|
2654
2682
|
x: 0,
|
|
@@ -2670,19 +2698,25 @@ var mutatorApplyCirclePencilStroke = ((writer, deps = defaults5) => {
|
|
|
2670
2698
|
w: 0,
|
|
2671
2699
|
h: 0
|
|
2672
2700
|
};
|
|
2701
|
+
const mask = {
|
|
2702
|
+
type: 1 /* BINARY */,
|
|
2703
|
+
data: null,
|
|
2704
|
+
w: 0,
|
|
2705
|
+
h: 0
|
|
2706
|
+
};
|
|
2673
2707
|
return {
|
|
2674
|
-
applyCirclePencilStroke(color, x0, y0, x1, y1,
|
|
2708
|
+
applyCirclePencilStroke(color, x0, y0, x1, y1, brush, alpha = 255, blendFn = sourceOverPerfect) {
|
|
2675
2709
|
const {
|
|
2676
2710
|
x: bx,
|
|
2677
2711
|
y: by,
|
|
2678
2712
|
w: bw,
|
|
2679
2713
|
h: bh
|
|
2680
|
-
} = getCircleBrushOrPencilStrokeBounds2(x0, y0, x1, y1,
|
|
2714
|
+
} = getCircleBrushOrPencilStrokeBounds2(x0, y0, x1, y1, brush.size, strokeBoundsOut);
|
|
2681
2715
|
if (bw <= 0 || bh <= 0) return;
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
const
|
|
2716
|
+
mask.data = new Uint8Array(bw * bh);
|
|
2717
|
+
mask.w = bw;
|
|
2718
|
+
mask.h = bh;
|
|
2719
|
+
const maskData = mask.data;
|
|
2686
2720
|
const targetWidth = writer.target.width;
|
|
2687
2721
|
const targetHeight = writer.target.height;
|
|
2688
2722
|
forEachLinePoint2(x0, y0, x1, y1, (px, py) => {
|
|
@@ -2691,24 +2725,24 @@ var mutatorApplyCirclePencilStroke = ((writer, deps = defaults5) => {
|
|
|
2691
2725
|
y: cby,
|
|
2692
2726
|
w: cbw,
|
|
2693
2727
|
h: cbh
|
|
2694
|
-
} = getCircleBrushOrPencilBounds2(px, py,
|
|
2728
|
+
} = getCircleBrushOrPencilBounds2(px, py, brush.size, targetWidth, targetHeight, circlePencilBounds);
|
|
2695
2729
|
writer.accumulator.storeRegionBeforeState(cbx, cby, cbw, cbh);
|
|
2696
|
-
const
|
|
2697
|
-
const
|
|
2698
|
-
const
|
|
2699
|
-
const
|
|
2700
|
-
const
|
|
2701
|
-
const
|
|
2730
|
+
const unclippedStartX = Math.floor(px + brush.minOffset);
|
|
2731
|
+
const unclippedStartY = Math.floor(py + brush.minOffset);
|
|
2732
|
+
const startX = Math.max(bx, unclippedStartX);
|
|
2733
|
+
const startY = Math.max(by, unclippedStartY);
|
|
2734
|
+
const endX = Math.min(bx + bw, unclippedStartX + brush.w);
|
|
2735
|
+
const endY = Math.min(by + bh, unclippedStartY + brush.h);
|
|
2702
2736
|
for (let my = startY; my < endY; my++) {
|
|
2703
|
-
const
|
|
2704
|
-
const dySqr = dy * dy;
|
|
2737
|
+
const brushY = my - unclippedStartY;
|
|
2705
2738
|
const maskRowOffset = (my - by) * bw;
|
|
2739
|
+
const brushRowOffset = brushY * brush.w;
|
|
2706
2740
|
for (let mx = startX; mx < endX; mx++) {
|
|
2707
|
-
const
|
|
2708
|
-
const
|
|
2709
|
-
if (
|
|
2741
|
+
const brushX = mx - unclippedStartX;
|
|
2742
|
+
const brushAlpha = brush.data[brushRowOffset + brushX];
|
|
2743
|
+
if (brushAlpha > 0) {
|
|
2710
2744
|
const maskIdx = maskRowOffset + (mx - bx);
|
|
2711
|
-
|
|
2745
|
+
maskData[maskIdx] = brushAlpha;
|
|
2712
2746
|
}
|
|
2713
2747
|
}
|
|
2714
2748
|
}
|
|
@@ -2796,14 +2830,14 @@ function applyRectBrushToPixelData(target, color, centerX, centerY, brushWidth,
|
|
|
2796
2830
|
}
|
|
2797
2831
|
|
|
2798
2832
|
// src/History/PixelMutator/mutatorApplyRectBrush.ts
|
|
2799
|
-
var
|
|
2833
|
+
var defaults7 = {
|
|
2800
2834
|
applyRectBrushToPixelData,
|
|
2801
2835
|
getRectBrushOrPencilBounds
|
|
2802
2836
|
};
|
|
2803
|
-
var mutatorApplyRectBrush = ((writer, deps =
|
|
2837
|
+
var mutatorApplyRectBrush = ((writer, deps = defaults7) => {
|
|
2804
2838
|
const {
|
|
2805
|
-
applyRectBrushToPixelData: applyRectBrushToPixelData2 =
|
|
2806
|
-
getRectBrushOrPencilBounds: getRectBrushOrPencilBounds2 =
|
|
2839
|
+
applyRectBrushToPixelData: applyRectBrushToPixelData2 = defaults7.applyRectBrushToPixelData,
|
|
2840
|
+
getRectBrushOrPencilBounds: getRectBrushOrPencilBounds2 = defaults7.getRectBrushOrPencilBounds
|
|
2807
2841
|
} = deps;
|
|
2808
2842
|
const boundsOut = {
|
|
2809
2843
|
x: 0,
|
|
@@ -2842,18 +2876,18 @@ function getRectBrushOrPencilStrokeBounds(x0, y0, x1, y1, brushWidth, brushHeigh
|
|
|
2842
2876
|
}
|
|
2843
2877
|
|
|
2844
2878
|
// src/History/PixelMutator/mutatorApplyRectBrushStroke.ts
|
|
2845
|
-
var
|
|
2879
|
+
var defaults8 = {
|
|
2846
2880
|
forEachLinePoint,
|
|
2847
2881
|
blendColorPixelDataAlphaMask,
|
|
2848
2882
|
getRectBrushOrPencilBounds,
|
|
2849
2883
|
getRectBrushOrPencilStrokeBounds
|
|
2850
2884
|
};
|
|
2851
|
-
var mutatorApplyRectBrushStroke = ((writer, deps =
|
|
2885
|
+
var mutatorApplyRectBrushStroke = ((writer, deps = defaults8) => {
|
|
2852
2886
|
const {
|
|
2853
|
-
forEachLinePoint: forEachLinePoint2 =
|
|
2854
|
-
blendColorPixelDataAlphaMask: blendColorPixelDataAlphaMask2 =
|
|
2855
|
-
getRectBrushOrPencilBounds: getRectBrushOrPencilBounds2 =
|
|
2856
|
-
getRectBrushOrPencilStrokeBounds: getRectBrushOrPencilStrokeBounds2 =
|
|
2887
|
+
forEachLinePoint: forEachLinePoint2 = defaults8.forEachLinePoint,
|
|
2888
|
+
blendColorPixelDataAlphaMask: blendColorPixelDataAlphaMask2 = defaults8.blendColorPixelDataAlphaMask,
|
|
2889
|
+
getRectBrushOrPencilBounds: getRectBrushOrPencilBounds2 = defaults8.getRectBrushOrPencilBounds,
|
|
2890
|
+
getRectBrushOrPencilStrokeBounds: getRectBrushOrPencilStrokeBounds2 = defaults8.getRectBrushOrPencilStrokeBounds
|
|
2857
2891
|
} = deps;
|
|
2858
2892
|
const strokeBoundsOut = {
|
|
2859
2893
|
x: 0,
|
|
@@ -2875,6 +2909,12 @@ var mutatorApplyRectBrushStroke = ((writer, deps = defaults7) => {
|
|
|
2875
2909
|
w: 0,
|
|
2876
2910
|
h: 0
|
|
2877
2911
|
};
|
|
2912
|
+
const mask = {
|
|
2913
|
+
type: 0 /* ALPHA */,
|
|
2914
|
+
data: null,
|
|
2915
|
+
w: 0,
|
|
2916
|
+
h: 0
|
|
2917
|
+
};
|
|
2878
2918
|
return {
|
|
2879
2919
|
applyRectBrushStroke(color, x0, y0, x1, y1, brushWidth, brushHeight, alpha = 255, fallOff, blendFn = sourceOverPerfect) {
|
|
2880
2920
|
const {
|
|
@@ -2884,7 +2924,10 @@ var mutatorApplyRectBrushStroke = ((writer, deps = defaults7) => {
|
|
|
2884
2924
|
h: bh
|
|
2885
2925
|
} = getRectBrushOrPencilStrokeBounds2(x0, y0, x1, y1, brushWidth, brushHeight, strokeBoundsOut);
|
|
2886
2926
|
if (bw <= 0 || bh <= 0) return;
|
|
2887
|
-
|
|
2927
|
+
mask.data = new Uint8Array(bw * bh);
|
|
2928
|
+
mask.w = bw;
|
|
2929
|
+
mask.h = bh;
|
|
2930
|
+
const maskData = mask.data;
|
|
2888
2931
|
const halfW = brushWidth / 2;
|
|
2889
2932
|
const halfH = brushHeight / 2;
|
|
2890
2933
|
const invHalfW = 1 / halfW;
|
|
@@ -2917,8 +2960,8 @@ var mutatorApplyRectBrushStroke = ((writer, deps = defaults7) => {
|
|
|
2917
2960
|
const strength = fallOff(dist);
|
|
2918
2961
|
if (strength > 0) {
|
|
2919
2962
|
const intensity = strength * 255 | 0;
|
|
2920
|
-
if (intensity >
|
|
2921
|
-
|
|
2963
|
+
if (intensity > maskData[maskIdx]) {
|
|
2964
|
+
maskData[maskIdx] = intensity;
|
|
2922
2965
|
}
|
|
2923
2966
|
}
|
|
2924
2967
|
}
|
|
@@ -2936,16 +2979,16 @@ var mutatorApplyRectBrushStroke = ((writer, deps = defaults7) => {
|
|
|
2936
2979
|
});
|
|
2937
2980
|
|
|
2938
2981
|
// src/History/PixelMutator/mutatorApplyRectPencil.ts
|
|
2939
|
-
var
|
|
2982
|
+
var defaults9 = {
|
|
2940
2983
|
applyRectBrushToPixelData,
|
|
2941
2984
|
getRectBrushOrPencilBounds,
|
|
2942
2985
|
fallOff: () => 1
|
|
2943
2986
|
};
|
|
2944
|
-
var mutatorApplyRectPencil = ((writer, deps =
|
|
2987
|
+
var mutatorApplyRectPencil = ((writer, deps = defaults9) => {
|
|
2945
2988
|
const {
|
|
2946
|
-
applyRectBrushToPixelData: applyRectBrushToPixelData2 =
|
|
2947
|
-
getRectBrushOrPencilBounds: getRectBrushOrPencilBounds2 =
|
|
2948
|
-
fallOff =
|
|
2989
|
+
applyRectBrushToPixelData: applyRectBrushToPixelData2 = defaults9.applyRectBrushToPixelData,
|
|
2990
|
+
getRectBrushOrPencilBounds: getRectBrushOrPencilBounds2 = defaults9.getRectBrushOrPencilBounds,
|
|
2991
|
+
fallOff = defaults9.fallOff
|
|
2949
2992
|
} = deps;
|
|
2950
2993
|
const boundsOut = {
|
|
2951
2994
|
x: 0,
|
|
@@ -2969,18 +3012,18 @@ var mutatorApplyRectPencil = ((writer, deps = defaults8) => {
|
|
|
2969
3012
|
});
|
|
2970
3013
|
|
|
2971
3014
|
// src/History/PixelMutator/mutatorApplyRectPencilStroke.ts
|
|
2972
|
-
var
|
|
3015
|
+
var defaults10 = {
|
|
2973
3016
|
forEachLinePoint,
|
|
2974
3017
|
getRectBrushOrPencilBounds,
|
|
2975
3018
|
getRectBrushOrPencilStrokeBounds,
|
|
2976
3019
|
blendColorPixelDataBinaryMask
|
|
2977
3020
|
};
|
|
2978
|
-
var mutatorApplyRectPencilStroke = ((writer, deps =
|
|
3021
|
+
var mutatorApplyRectPencilStroke = ((writer, deps = defaults10) => {
|
|
2979
3022
|
const {
|
|
2980
|
-
forEachLinePoint: forEachLinePoint2 =
|
|
2981
|
-
blendColorPixelDataBinaryMask: blendColorPixelDataBinaryMask2 =
|
|
2982
|
-
getRectBrushOrPencilBounds: getRectBrushOrPencilBounds2 =
|
|
2983
|
-
getRectBrushOrPencilStrokeBounds: getRectBrushOrPencilStrokeBounds2 =
|
|
3023
|
+
forEachLinePoint: forEachLinePoint2 = defaults10.forEachLinePoint,
|
|
3024
|
+
blendColorPixelDataBinaryMask: blendColorPixelDataBinaryMask2 = defaults10.blendColorPixelDataBinaryMask,
|
|
3025
|
+
getRectBrushOrPencilBounds: getRectBrushOrPencilBounds2 = defaults10.getRectBrushOrPencilBounds,
|
|
3026
|
+
getRectBrushOrPencilStrokeBounds: getRectBrushOrPencilStrokeBounds2 = defaults10.getRectBrushOrPencilStrokeBounds
|
|
2984
3027
|
} = deps;
|
|
2985
3028
|
const strokeBoundsOut = {
|
|
2986
3029
|
x: 0,
|
|
@@ -3002,6 +3045,12 @@ var mutatorApplyRectPencilStroke = ((writer, deps = defaults9) => {
|
|
|
3002
3045
|
w: 0,
|
|
3003
3046
|
h: 0
|
|
3004
3047
|
};
|
|
3048
|
+
const mask = {
|
|
3049
|
+
type: 1 /* BINARY */,
|
|
3050
|
+
data: null,
|
|
3051
|
+
w: 0,
|
|
3052
|
+
h: 0
|
|
3053
|
+
};
|
|
3005
3054
|
return {
|
|
3006
3055
|
applyRectPencilStroke(color, x0, y0, x1, y1, brushWidth, brushHeight, alpha = 255, blendFn = sourceOverPerfect) {
|
|
3007
3056
|
const {
|
|
@@ -3011,7 +3060,10 @@ var mutatorApplyRectPencilStroke = ((writer, deps = defaults9) => {
|
|
|
3011
3060
|
h: bh
|
|
3012
3061
|
} = getRectBrushOrPencilStrokeBounds2(x0, y0, x1, y1, brushWidth, brushHeight, strokeBoundsOut);
|
|
3013
3062
|
if (bw <= 0 || bh <= 0) return;
|
|
3014
|
-
|
|
3063
|
+
mask.data = new Uint8Array(bw * bh);
|
|
3064
|
+
mask.w = bw;
|
|
3065
|
+
mask.h = bh;
|
|
3066
|
+
const maskData = mask.data;
|
|
3015
3067
|
const halfW = brushWidth / 2;
|
|
3016
3068
|
const halfH = brushHeight / 2;
|
|
3017
3069
|
const centerOffset = brushWidth % 2 === 0 ? 0.5 : 0;
|
|
@@ -3038,7 +3090,7 @@ var mutatorApplyRectPencilStroke = ((writer, deps = defaults9) => {
|
|
|
3038
3090
|
const dx = Math.abs(mx - fPx + centerOffset);
|
|
3039
3091
|
const maskIdx = maskRowOffset + (mx - bx);
|
|
3040
3092
|
if (dx <= halfW && dy <= halfH) {
|
|
3041
|
-
|
|
3093
|
+
maskData[maskIdx] = 1;
|
|
3042
3094
|
}
|
|
3043
3095
|
}
|
|
3044
3096
|
}
|
|
@@ -3100,12 +3152,12 @@ function blendColorPixelData(dst, color, opts = {}) {
|
|
|
3100
3152
|
}
|
|
3101
3153
|
|
|
3102
3154
|
// src/History/PixelMutator/mutatorBlendColor.ts
|
|
3103
|
-
var
|
|
3155
|
+
var defaults11 = {
|
|
3104
3156
|
blendColorPixelData
|
|
3105
3157
|
};
|
|
3106
|
-
var mutatorBlendColor = ((writer, deps =
|
|
3158
|
+
var mutatorBlendColor = ((writer, deps = defaults11) => {
|
|
3107
3159
|
const {
|
|
3108
|
-
blendColorPixelData: blendColorPixelData2 =
|
|
3160
|
+
blendColorPixelData: blendColorPixelData2 = defaults11.blendColorPixelData
|
|
3109
3161
|
} = deps;
|
|
3110
3162
|
return {
|
|
3111
3163
|
blendColor(color, opts = {}) {
|
|
@@ -3144,7 +3196,7 @@ function mutatorBlendPixel(writer) {
|
|
|
3144
3196
|
}
|
|
3145
3197
|
|
|
3146
3198
|
// src/PixelData/blendPixelData.ts
|
|
3147
|
-
function blendPixelData(dst, src, opts) {
|
|
3199
|
+
function blendPixelData(dst, src, opts = {}) {
|
|
3148
3200
|
const {
|
|
3149
3201
|
x: targetX = 0,
|
|
3150
3202
|
y: targetY = 0,
|
|
@@ -3226,15 +3278,15 @@ function blendPixelData(dst, src, opts) {
|
|
|
3226
3278
|
}
|
|
3227
3279
|
|
|
3228
3280
|
// src/History/PixelMutator/mutatorBlendPixelData.ts
|
|
3229
|
-
var
|
|
3281
|
+
var defaults12 = {
|
|
3230
3282
|
blendPixelData
|
|
3231
3283
|
};
|
|
3232
|
-
var mutatorBlendPixelData = ((writer, deps =
|
|
3284
|
+
var mutatorBlendPixelData = ((writer, deps = defaults12) => {
|
|
3233
3285
|
const {
|
|
3234
|
-
blendPixelData: blendPixelData2 =
|
|
3286
|
+
blendPixelData: blendPixelData2 = defaults12.blendPixelData
|
|
3235
3287
|
} = deps;
|
|
3236
3288
|
return {
|
|
3237
|
-
blendPixelData(src, opts) {
|
|
3289
|
+
blendPixelData(src, opts = {}) {
|
|
3238
3290
|
const {
|
|
3239
3291
|
x = 0,
|
|
3240
3292
|
y = 0,
|
|
@@ -3247,143 +3299,430 @@ var mutatorBlendPixelData = ((writer, deps = defaults11) => {
|
|
|
3247
3299
|
};
|
|
3248
3300
|
});
|
|
3249
3301
|
|
|
3250
|
-
// src/PixelData/
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
|
|
3258
|
-
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
}
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3302
|
+
// src/PixelData/blendPixelDataAlphaMask.ts
|
|
3303
|
+
function blendPixelDataAlphaMask(dst, src, alphaMask, opts = {}) {
|
|
3304
|
+
const {
|
|
3305
|
+
x: targetX = 0,
|
|
3306
|
+
y: targetY = 0,
|
|
3307
|
+
sx: sourceX = 0,
|
|
3308
|
+
sy: sourceY = 0,
|
|
3309
|
+
w: width = src.width,
|
|
3310
|
+
h: height = src.height,
|
|
3311
|
+
alpha: globalAlpha = 255,
|
|
3312
|
+
blendFn = sourceOverPerfect,
|
|
3313
|
+
mx = 0,
|
|
3314
|
+
my = 0,
|
|
3315
|
+
invertMask = false
|
|
3316
|
+
} = opts;
|
|
3317
|
+
if (globalAlpha === 0) return;
|
|
3318
|
+
let x = targetX;
|
|
3319
|
+
let y = targetY;
|
|
3320
|
+
let sx = sourceX;
|
|
3321
|
+
let sy = sourceY;
|
|
3322
|
+
let w = width;
|
|
3323
|
+
let h = height;
|
|
3324
|
+
if (sx < 0) {
|
|
3325
|
+
x -= sx;
|
|
3326
|
+
w += sx;
|
|
3327
|
+
sx = 0;
|
|
3328
|
+
}
|
|
3329
|
+
if (sy < 0) {
|
|
3330
|
+
y -= sy;
|
|
3331
|
+
h += sy;
|
|
3332
|
+
sy = 0;
|
|
3333
|
+
}
|
|
3334
|
+
w = Math.min(w, src.width - sx);
|
|
3335
|
+
h = Math.min(h, src.height - sy);
|
|
3336
|
+
if (x < 0) {
|
|
3337
|
+
sx -= x;
|
|
3338
|
+
w += x;
|
|
3271
3339
|
x = 0;
|
|
3340
|
+
}
|
|
3341
|
+
if (y < 0) {
|
|
3342
|
+
sy -= y;
|
|
3343
|
+
h += y;
|
|
3272
3344
|
y = 0;
|
|
3273
|
-
w = dst.width;
|
|
3274
|
-
h = dst.height;
|
|
3275
3345
|
}
|
|
3276
|
-
const
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
x: finalX,
|
|
3280
|
-
y: finalY,
|
|
3281
|
-
w: actualW,
|
|
3282
|
-
h: actualH
|
|
3283
|
-
} = clip;
|
|
3284
|
-
const dst32 = dst.data32;
|
|
3346
|
+
const actualW = Math.min(w, dst.width - x);
|
|
3347
|
+
const actualH = Math.min(h, dst.height - y);
|
|
3348
|
+
if (actualW <= 0 || actualH <= 0) return;
|
|
3285
3349
|
const dw = dst.width;
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
3350
|
+
const sw = src.width;
|
|
3351
|
+
const mPitch = alphaMask.w;
|
|
3352
|
+
const maskData = alphaMask.data;
|
|
3353
|
+
const dx = x - targetX | 0;
|
|
3354
|
+
const dy = y - targetY | 0;
|
|
3355
|
+
const dst32 = dst.data32;
|
|
3356
|
+
const src32 = src.data32;
|
|
3357
|
+
let dIdx = y * dw + x | 0;
|
|
3358
|
+
let sIdx = sy * sw + sx | 0;
|
|
3359
|
+
let mIdx = (my + dy) * mPitch + (mx + dx) | 0;
|
|
3360
|
+
const dStride = dw - actualW | 0;
|
|
3361
|
+
const sStride = sw - actualW | 0;
|
|
3362
|
+
const mStride = mPitch - actualW | 0;
|
|
3363
|
+
const isOpaque = globalAlpha === 255;
|
|
3364
|
+
const isOverwrite = blendFn.isOverwrite || false;
|
|
3365
|
+
for (let iy = 0; iy < actualH; iy++) {
|
|
3366
|
+
for (let ix = 0; ix < actualW; ix++) {
|
|
3367
|
+
const mVal = maskData[mIdx];
|
|
3368
|
+
const effM = invertMask ? 255 - mVal : mVal;
|
|
3369
|
+
if (effM === 0) {
|
|
3370
|
+
dIdx++;
|
|
3371
|
+
sIdx++;
|
|
3372
|
+
mIdx++;
|
|
3373
|
+
continue;
|
|
3374
|
+
}
|
|
3375
|
+
const srcCol = src32[sIdx];
|
|
3376
|
+
const srcAlpha = srcCol >>> 24;
|
|
3377
|
+
if (srcAlpha === 0 && !isOverwrite) {
|
|
3378
|
+
dIdx++;
|
|
3379
|
+
sIdx++;
|
|
3380
|
+
mIdx++;
|
|
3381
|
+
continue;
|
|
3382
|
+
}
|
|
3383
|
+
let weight = globalAlpha;
|
|
3384
|
+
if (isOpaque) {
|
|
3385
|
+
weight = effM;
|
|
3386
|
+
} else if (effM !== 255) {
|
|
3387
|
+
weight = effM * globalAlpha + 128 >> 8;
|
|
3388
|
+
}
|
|
3389
|
+
if (weight === 0) {
|
|
3390
|
+
dIdx++;
|
|
3391
|
+
sIdx++;
|
|
3392
|
+
mIdx++;
|
|
3393
|
+
continue;
|
|
3394
|
+
}
|
|
3395
|
+
let finalCol = srcCol;
|
|
3396
|
+
if (weight < 255) {
|
|
3397
|
+
const a = srcAlpha * weight + 128 >> 8;
|
|
3398
|
+
if (a === 0 && !isOverwrite) {
|
|
3399
|
+
dIdx++;
|
|
3400
|
+
sIdx++;
|
|
3401
|
+
mIdx++;
|
|
3402
|
+
continue;
|
|
3303
3403
|
}
|
|
3404
|
+
finalCol = (srcCol & 16777215 | a << 24) >>> 0;
|
|
3304
3405
|
}
|
|
3406
|
+
dst32[dIdx] = blendFn(finalCol, dst32[dIdx]);
|
|
3407
|
+
dIdx++;
|
|
3408
|
+
sIdx++;
|
|
3409
|
+
mIdx++;
|
|
3305
3410
|
}
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
const end = start + actualW;
|
|
3310
|
-
dst32.fill(color, start, end);
|
|
3311
|
-
}
|
|
3411
|
+
dIdx += dStride;
|
|
3412
|
+
sIdx += sStride;
|
|
3413
|
+
mIdx += mStride;
|
|
3312
3414
|
}
|
|
3313
3415
|
}
|
|
3314
3416
|
|
|
3315
|
-
// src/History/PixelMutator/
|
|
3316
|
-
var defaults12 = {
|
|
3317
|
-
fillPixelData
|
|
3318
|
-
};
|
|
3319
|
-
var mutatorClear = ((writer, deps = defaults12) => {
|
|
3320
|
-
const {
|
|
3321
|
-
fillPixelData: fillPixelData2 = defaults12.fillPixelData
|
|
3322
|
-
} = deps;
|
|
3323
|
-
return {
|
|
3324
|
-
clear(rect = {}) {
|
|
3325
|
-
const {
|
|
3326
|
-
x = 0,
|
|
3327
|
-
y = 0,
|
|
3328
|
-
w = writer.target.width,
|
|
3329
|
-
h = writer.target.height,
|
|
3330
|
-
mask = void 0
|
|
3331
|
-
} = rect;
|
|
3332
|
-
writer.accumulator.storeRegionBeforeState(x, y, w, h);
|
|
3333
|
-
fillPixelData2(writer.target, 0, x, y, w, h, mask);
|
|
3334
|
-
}
|
|
3335
|
-
};
|
|
3336
|
-
});
|
|
3337
|
-
|
|
3338
|
-
// src/History/PixelMutator/mutatorFill.ts
|
|
3417
|
+
// src/History/PixelMutator/mutatorBlendPixelDataAlphaMask.ts
|
|
3339
3418
|
var defaults13 = {
|
|
3340
|
-
|
|
3419
|
+
blendPixelDataAlphaMask
|
|
3341
3420
|
};
|
|
3342
|
-
var
|
|
3421
|
+
var mutatorBlendPixelDataAlphaMask = ((writer, deps = defaults13) => {
|
|
3343
3422
|
const {
|
|
3344
|
-
|
|
3423
|
+
blendPixelDataAlphaMask: blendPixelDataAlphaMask2 = defaults13.blendPixelDataAlphaMask
|
|
3345
3424
|
} = deps;
|
|
3346
3425
|
return {
|
|
3347
|
-
|
|
3348
|
-
const
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
h = writer.target.height,
|
|
3353
|
-
mask = void 0
|
|
3354
|
-
} = rect;
|
|
3426
|
+
blendPixelDataAlphaMask(src, mask, opts = {}) {
|
|
3427
|
+
const x = opts.x ?? 0;
|
|
3428
|
+
const y = opts.y ?? 0;
|
|
3429
|
+
const w = opts.w ?? src.width;
|
|
3430
|
+
const h = opts.h ?? src.height;
|
|
3355
3431
|
writer.accumulator.storeRegionBeforeState(x, y, w, h);
|
|
3356
|
-
|
|
3432
|
+
blendPixelDataAlphaMask2(writer.target, src, mask, opts);
|
|
3357
3433
|
}
|
|
3358
3434
|
};
|
|
3359
3435
|
});
|
|
3360
3436
|
|
|
3361
|
-
// src/PixelData/
|
|
3362
|
-
|
|
3363
|
-
function invertPixelData(pixelData, opts = {}) {
|
|
3364
|
-
const dst = pixelData;
|
|
3437
|
+
// src/PixelData/blendPixelDataBinaryMask.ts
|
|
3438
|
+
function blendPixelDataBinaryMask(dst, src, binaryMask, opts = {}) {
|
|
3365
3439
|
const {
|
|
3366
3440
|
x: targetX = 0,
|
|
3367
3441
|
y: targetY = 0,
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
|
|
3371
|
-
|
|
3442
|
+
sx: sourceX = 0,
|
|
3443
|
+
sy: sourceY = 0,
|
|
3444
|
+
w: width = src.width,
|
|
3445
|
+
h: height = src.height,
|
|
3446
|
+
alpha: globalAlpha = 255,
|
|
3447
|
+
blendFn = sourceOverPerfect,
|
|
3372
3448
|
mx = 0,
|
|
3373
3449
|
my = 0,
|
|
3374
3450
|
invertMask = false
|
|
3375
3451
|
} = opts;
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
|
|
3379
|
-
|
|
3452
|
+
if (globalAlpha === 0) return;
|
|
3453
|
+
let x = targetX;
|
|
3454
|
+
let y = targetY;
|
|
3455
|
+
let sx = sourceX;
|
|
3456
|
+
let sy = sourceY;
|
|
3457
|
+
let w = width;
|
|
3458
|
+
let h = height;
|
|
3459
|
+
if (sx < 0) {
|
|
3460
|
+
x -= sx;
|
|
3461
|
+
w += sx;
|
|
3462
|
+
sx = 0;
|
|
3463
|
+
}
|
|
3464
|
+
if (sy < 0) {
|
|
3465
|
+
y -= sy;
|
|
3466
|
+
h += sy;
|
|
3467
|
+
sy = 0;
|
|
3468
|
+
}
|
|
3469
|
+
w = Math.min(w, src.width - sx);
|
|
3470
|
+
h = Math.min(h, src.height - sy);
|
|
3471
|
+
if (x < 0) {
|
|
3472
|
+
sx -= x;
|
|
3473
|
+
w += x;
|
|
3474
|
+
x = 0;
|
|
3475
|
+
}
|
|
3476
|
+
if (y < 0) {
|
|
3477
|
+
sy -= y;
|
|
3478
|
+
h += y;
|
|
3479
|
+
y = 0;
|
|
3480
|
+
}
|
|
3481
|
+
const actualW = Math.min(w, dst.width - x);
|
|
3482
|
+
const actualH = Math.min(h, dst.height - y);
|
|
3483
|
+
if (actualW <= 0 || actualH <= 0) return;
|
|
3484
|
+
const dx = x - targetX | 0;
|
|
3485
|
+
const dy = y - targetY | 0;
|
|
3486
|
+
const dst32 = dst.data32;
|
|
3487
|
+
const src32 = src.data32;
|
|
3488
|
+
const dw = dst.width;
|
|
3489
|
+
const sw = src.width;
|
|
3490
|
+
const mPitch = binaryMask.w;
|
|
3491
|
+
const maskData = binaryMask.data;
|
|
3492
|
+
let dIdx = y * dw + x | 0;
|
|
3493
|
+
let sIdx = sy * sw + sx | 0;
|
|
3494
|
+
let mIdx = (my + dy) * mPitch + (mx + dx) | 0;
|
|
3495
|
+
const dStride = dw - actualW | 0;
|
|
3496
|
+
const sStride = sw - actualW | 0;
|
|
3497
|
+
const mStride = mPitch - actualW | 0;
|
|
3498
|
+
const skipVal = invertMask ? 1 : 0;
|
|
3499
|
+
const isOpaque = globalAlpha === 255;
|
|
3500
|
+
const isOverwrite = blendFn.isOverwrite || false;
|
|
3501
|
+
for (let iy = 0; iy < actualH; iy++) {
|
|
3502
|
+
for (let ix = 0; ix < actualW; ix++) {
|
|
3503
|
+
if (maskData[mIdx] === skipVal) {
|
|
3504
|
+
dIdx++;
|
|
3505
|
+
sIdx++;
|
|
3506
|
+
mIdx++;
|
|
3507
|
+
continue;
|
|
3508
|
+
}
|
|
3509
|
+
const srcCol = src32[sIdx];
|
|
3510
|
+
const srcAlpha = srcCol >>> 24;
|
|
3511
|
+
if (srcAlpha === 0 && !isOverwrite) {
|
|
3512
|
+
dIdx++;
|
|
3513
|
+
sIdx++;
|
|
3514
|
+
mIdx++;
|
|
3515
|
+
continue;
|
|
3516
|
+
}
|
|
3517
|
+
let finalCol = srcCol;
|
|
3518
|
+
if (!isOpaque) {
|
|
3519
|
+
const a = srcAlpha * globalAlpha + 128 >> 8;
|
|
3520
|
+
if (a === 0 && !isOverwrite) {
|
|
3521
|
+
dIdx++;
|
|
3522
|
+
sIdx++;
|
|
3523
|
+
mIdx++;
|
|
3524
|
+
continue;
|
|
3525
|
+
}
|
|
3526
|
+
finalCol = (srcCol & 16777215 | a << 24) >>> 0;
|
|
3527
|
+
}
|
|
3528
|
+
dst32[dIdx] = blendFn(finalCol, dst32[dIdx]);
|
|
3529
|
+
dIdx++;
|
|
3530
|
+
sIdx++;
|
|
3531
|
+
mIdx++;
|
|
3532
|
+
}
|
|
3533
|
+
dIdx += dStride;
|
|
3534
|
+
sIdx += sStride;
|
|
3535
|
+
mIdx += mStride;
|
|
3536
|
+
}
|
|
3537
|
+
}
|
|
3538
|
+
|
|
3539
|
+
// src/History/PixelMutator/mutatorBlendPixelDataBinaryMask.ts
|
|
3540
|
+
var defaults14 = {
|
|
3541
|
+
blendPixelDataBinaryMask
|
|
3542
|
+
};
|
|
3543
|
+
var mutatorBlendPixelDataBinaryMask = ((writer, deps = defaults14) => {
|
|
3544
|
+
const {
|
|
3545
|
+
blendPixelDataBinaryMask: blendPixelDataBinaryMask2 = defaults14.blendPixelDataBinaryMask
|
|
3546
|
+
} = deps;
|
|
3547
|
+
return {
|
|
3548
|
+
blendPixelDataBinaryMask(src, mask, opts = {}) {
|
|
3549
|
+
const x = opts.x ?? 0;
|
|
3550
|
+
const y = opts.y ?? 0;
|
|
3551
|
+
const w = opts.w ?? src.width;
|
|
3552
|
+
const h = opts.h ?? src.height;
|
|
3553
|
+
writer.accumulator.storeRegionBeforeState(x, y, w, h);
|
|
3554
|
+
blendPixelDataBinaryMask2(writer.target, src, mask, opts);
|
|
3555
|
+
}
|
|
3556
|
+
};
|
|
3557
|
+
});
|
|
3558
|
+
|
|
3559
|
+
// src/PixelData/fillPixelData.ts
|
|
3560
|
+
var SCRATCH_RECT = makeClippedRect();
|
|
3561
|
+
function fillPixelData(dst, color, _x, _y, _w, _h) {
|
|
3562
|
+
let x;
|
|
3563
|
+
let y;
|
|
3564
|
+
let w;
|
|
3565
|
+
let h;
|
|
3566
|
+
if (typeof _x === "object") {
|
|
3567
|
+
x = _x.x ?? 0;
|
|
3568
|
+
y = _x.y ?? 0;
|
|
3569
|
+
w = _x.w ?? dst.width;
|
|
3570
|
+
h = _x.h ?? dst.height;
|
|
3571
|
+
} else if (typeof _x === "number") {
|
|
3572
|
+
x = _x;
|
|
3573
|
+
y = _y;
|
|
3574
|
+
w = _w;
|
|
3575
|
+
h = _h;
|
|
3576
|
+
} else {
|
|
3577
|
+
x = 0;
|
|
3578
|
+
y = 0;
|
|
3579
|
+
w = dst.width;
|
|
3580
|
+
h = dst.height;
|
|
3581
|
+
}
|
|
3582
|
+
const clip = resolveRectClipping(x, y, w, h, dst.width, dst.height, SCRATCH_RECT);
|
|
3583
|
+
if (!clip.inBounds) return;
|
|
3584
|
+
const {
|
|
3585
|
+
x: finalX,
|
|
3586
|
+
y: finalY,
|
|
3587
|
+
w: actualW,
|
|
3588
|
+
h: actualH
|
|
3589
|
+
} = clip;
|
|
3590
|
+
const dst32 = dst.data32;
|
|
3591
|
+
const dw = dst.width;
|
|
3592
|
+
if (actualW === dw && actualH === dst.height && finalX === 0 && finalY === 0) {
|
|
3593
|
+
dst32.fill(color);
|
|
3594
|
+
return;
|
|
3595
|
+
}
|
|
3596
|
+
for (let iy = 0; iy < actualH; iy++) {
|
|
3597
|
+
const start = (finalY + iy) * dw + finalX;
|
|
3598
|
+
const end = start + actualW;
|
|
3599
|
+
dst32.fill(color, start, end);
|
|
3600
|
+
}
|
|
3601
|
+
}
|
|
3602
|
+
|
|
3603
|
+
// src/History/PixelMutator/mutatorClear.ts
|
|
3604
|
+
var defaults15 = {
|
|
3605
|
+
fillPixelData
|
|
3606
|
+
};
|
|
3607
|
+
var mutatorClear = ((writer, deps = defaults15) => {
|
|
3608
|
+
const {
|
|
3609
|
+
fillPixelData: fillPixelData2 = defaults15.fillPixelData
|
|
3610
|
+
} = deps;
|
|
3611
|
+
return {
|
|
3612
|
+
clear(rect = {}) {
|
|
3613
|
+
const x = rect.x ?? 0;
|
|
3614
|
+
const y = rect.y ?? 0;
|
|
3615
|
+
const w = rect.w ?? writer.target.width;
|
|
3616
|
+
const h = rect.h ?? writer.target.height;
|
|
3617
|
+
writer.accumulator.storeRegionBeforeState(x, y, w, h);
|
|
3618
|
+
fillPixelData2(writer.target, 0, x, y, w, h);
|
|
3619
|
+
}
|
|
3620
|
+
};
|
|
3621
|
+
});
|
|
3622
|
+
|
|
3623
|
+
// src/History/PixelMutator/mutatorFill.ts
|
|
3624
|
+
var defaults16 = {
|
|
3625
|
+
fillPixelData
|
|
3626
|
+
};
|
|
3627
|
+
var mutatorFill = ((writer, deps = defaults16) => {
|
|
3628
|
+
const {
|
|
3629
|
+
fillPixelData: fillPixelData2 = defaults16.fillPixelData
|
|
3630
|
+
} = deps;
|
|
3631
|
+
return {
|
|
3632
|
+
fill(color, rect = {}) {
|
|
3633
|
+
const {
|
|
3634
|
+
x = 0,
|
|
3635
|
+
y = 0,
|
|
3636
|
+
w = writer.target.width,
|
|
3637
|
+
h = writer.target.height
|
|
3638
|
+
} = rect;
|
|
3639
|
+
writer.accumulator.storeRegionBeforeState(x, y, w, h);
|
|
3640
|
+
fillPixelData2(writer.target, color, x, y, w, h);
|
|
3641
|
+
}
|
|
3642
|
+
};
|
|
3643
|
+
});
|
|
3644
|
+
|
|
3645
|
+
// src/PixelData/fillPixelDataBinaryMask.ts
|
|
3646
|
+
var SCRATCH_RECT2 = makeClippedRect();
|
|
3647
|
+
function fillPixelDataBinaryMask(dst, color, mask, alpha = 255, x = 0, y = 0) {
|
|
3648
|
+
if (alpha === 0) return;
|
|
3649
|
+
const maskW = mask.w;
|
|
3650
|
+
const maskH = mask.h;
|
|
3651
|
+
const clip = resolveRectClipping(x, y, maskW, maskH, dst.width, dst.height, SCRATCH_RECT2);
|
|
3652
|
+
if (!clip.inBounds) return;
|
|
3653
|
+
const {
|
|
3654
|
+
x: finalX,
|
|
3655
|
+
y: finalY,
|
|
3656
|
+
w: actualW,
|
|
3657
|
+
h: actualH
|
|
3658
|
+
} = clip;
|
|
3659
|
+
const maskData = mask.data;
|
|
3660
|
+
const dst32 = dst.data32;
|
|
3661
|
+
const dw = dst.width;
|
|
3662
|
+
let finalCol = color;
|
|
3663
|
+
if (alpha < 255) {
|
|
3664
|
+
const baseSrcAlpha = color >>> 24;
|
|
3665
|
+
const colorRGB = color & 16777215;
|
|
3666
|
+
const a = baseSrcAlpha * alpha + 128 >> 8;
|
|
3667
|
+
finalCol = (colorRGB | a << 24) >>> 0;
|
|
3668
|
+
}
|
|
3669
|
+
for (let iy = 0; iy < actualH; iy++) {
|
|
3670
|
+
const currentY = finalY + iy;
|
|
3671
|
+
const maskY = currentY - y;
|
|
3672
|
+
const maskOffset = maskY * maskW;
|
|
3673
|
+
const dstRowOffset = currentY * dw;
|
|
3674
|
+
for (let ix = 0; ix < actualW; ix++) {
|
|
3675
|
+
const currentX = finalX + ix;
|
|
3676
|
+
const maskX = currentX - x;
|
|
3677
|
+
const maskIndex = maskOffset + maskX;
|
|
3678
|
+
if (maskData[maskIndex]) {
|
|
3679
|
+
dst32[dstRowOffset + currentX] = finalCol;
|
|
3680
|
+
}
|
|
3681
|
+
}
|
|
3682
|
+
}
|
|
3683
|
+
}
|
|
3684
|
+
|
|
3685
|
+
// src/History/PixelMutator/mutatorFillBinaryMask.ts
|
|
3686
|
+
var defaults17 = {
|
|
3687
|
+
fillPixelDataBinaryMask
|
|
3688
|
+
};
|
|
3689
|
+
var mutatorFillBinaryMask = ((writer, deps = defaults17) => {
|
|
3690
|
+
const {
|
|
3691
|
+
fillPixelDataBinaryMask: fillPixelDataBinaryMask2 = defaults17.fillPixelDataBinaryMask
|
|
3692
|
+
} = deps;
|
|
3693
|
+
return {
|
|
3694
|
+
fillBinaryMask(color, mask, alpha = 255, x = 0, y = 0) {
|
|
3695
|
+
writer.accumulator.storeRegionBeforeState(x, y, mask.w, mask.h);
|
|
3696
|
+
fillPixelDataBinaryMask2(writer.target, color, mask, alpha, x, y);
|
|
3697
|
+
}
|
|
3698
|
+
};
|
|
3699
|
+
});
|
|
3700
|
+
|
|
3701
|
+
// src/PixelData/invertPixelData.ts
|
|
3702
|
+
var SCRATCH_RECT3 = makeClippedRect();
|
|
3703
|
+
function invertPixelData(pixelData, opts = {}) {
|
|
3704
|
+
const dst = pixelData;
|
|
3705
|
+
const {
|
|
3706
|
+
x: targetX = 0,
|
|
3707
|
+
y: targetY = 0,
|
|
3708
|
+
w: width = pixelData.width,
|
|
3709
|
+
h: height = pixelData.height,
|
|
3710
|
+
mask,
|
|
3711
|
+
mx = 0,
|
|
3712
|
+
my = 0,
|
|
3713
|
+
invertMask = false
|
|
3714
|
+
} = opts;
|
|
3715
|
+
const clip = resolveRectClipping(targetX, targetY, width, height, dst.width, dst.height, SCRATCH_RECT3);
|
|
3716
|
+
if (!clip.inBounds) return;
|
|
3717
|
+
const {
|
|
3718
|
+
x,
|
|
3380
3719
|
y,
|
|
3381
3720
|
w: actualW,
|
|
3382
3721
|
h: actualH
|
|
3383
3722
|
} = clip;
|
|
3384
3723
|
const dst32 = dst.data32;
|
|
3385
3724
|
const dw = dst.width;
|
|
3386
|
-
const mPitch =
|
|
3725
|
+
const mPitch = mask?.w ?? width;
|
|
3387
3726
|
const dx = x - targetX;
|
|
3388
3727
|
const dy = y - targetY;
|
|
3389
3728
|
let dIdx = y * dw + x;
|
|
@@ -3391,9 +3730,10 @@ function invertPixelData(pixelData, opts = {}) {
|
|
|
3391
3730
|
const dStride = dw - actualW;
|
|
3392
3731
|
const mStride = mPitch - actualW;
|
|
3393
3732
|
if (mask) {
|
|
3733
|
+
const maskData = mask.data;
|
|
3394
3734
|
for (let iy = 0; iy < actualH; iy++) {
|
|
3395
3735
|
for (let ix = 0; ix < actualW; ix++) {
|
|
3396
|
-
const mVal =
|
|
3736
|
+
const mVal = maskData[mIdx];
|
|
3397
3737
|
const isHit = invertMask ? mVal === 0 : mVal === 1;
|
|
3398
3738
|
if (isHit) {
|
|
3399
3739
|
dst32[dIdx] = dst32[dIdx] ^ 16777215;
|
|
@@ -3416,12 +3756,12 @@ function invertPixelData(pixelData, opts = {}) {
|
|
|
3416
3756
|
}
|
|
3417
3757
|
|
|
3418
3758
|
// src/History/PixelMutator/mutatorInvert.ts
|
|
3419
|
-
var
|
|
3759
|
+
var defaults18 = {
|
|
3420
3760
|
invertPixelData
|
|
3421
3761
|
};
|
|
3422
|
-
var mutatorInvert = ((writer, deps =
|
|
3762
|
+
var mutatorInvert = ((writer, deps = defaults18) => {
|
|
3423
3763
|
const {
|
|
3424
|
-
invertPixelData: invertPixelData2 =
|
|
3764
|
+
invertPixelData: invertPixelData2 = defaults18.invertPixelData
|
|
3425
3765
|
} = deps;
|
|
3426
3766
|
return {
|
|
3427
3767
|
invert(opts = {}) {
|
|
@@ -3440,21 +3780,26 @@ var mutatorInvert = ((writer, deps = defaults14) => {
|
|
|
3440
3780
|
// src/History/PixelMutator.ts
|
|
3441
3781
|
function makeFullPixelMutator(writer) {
|
|
3442
3782
|
return {
|
|
3783
|
+
// @sort
|
|
3443
3784
|
...mutatorApplyAlphaMask(writer),
|
|
3444
3785
|
...mutatorApplyBinaryMask(writer),
|
|
3445
|
-
...mutatorBlendPixelData(writer),
|
|
3446
|
-
...mutatorBlendColor(writer),
|
|
3447
|
-
...mutatorBlendPixel(writer),
|
|
3448
|
-
...mutatorFill(writer),
|
|
3449
|
-
...mutatorInvert(writer),
|
|
3450
3786
|
...mutatorApplyCircleBrush(writer),
|
|
3451
3787
|
...mutatorApplyCircleBrushStroke(writer),
|
|
3788
|
+
...mutatorApplyCirclePencil(writer),
|
|
3452
3789
|
...mutatorApplyCirclePencilStroke(writer),
|
|
3453
3790
|
...mutatorApplyRectBrush(writer),
|
|
3454
3791
|
...mutatorApplyRectBrushStroke(writer),
|
|
3455
3792
|
...mutatorApplyRectPencil(writer),
|
|
3456
3793
|
...mutatorApplyRectPencilStroke(writer),
|
|
3457
|
-
...
|
|
3794
|
+
...mutatorBlendColor(writer),
|
|
3795
|
+
...mutatorBlendPixel(writer),
|
|
3796
|
+
...mutatorBlendPixelData(writer),
|
|
3797
|
+
...mutatorBlendPixelDataAlphaMask(writer),
|
|
3798
|
+
...mutatorBlendPixelDataBinaryMask(writer),
|
|
3799
|
+
...mutatorClear(writer),
|
|
3800
|
+
...mutatorFill(writer),
|
|
3801
|
+
...mutatorFillBinaryMask(writer),
|
|
3802
|
+
...mutatorInvert(writer)
|
|
3458
3803
|
};
|
|
3459
3804
|
}
|
|
3460
3805
|
|
|
@@ -3501,39 +3846,6 @@ var PixelWriter = class {
|
|
|
3501
3846
|
}
|
|
3502
3847
|
};
|
|
3503
3848
|
|
|
3504
|
-
// src/History/PixelMutator/mutatorApplyCirclePencil.ts
|
|
3505
|
-
var defaults15 = {
|
|
3506
|
-
applyCircleBrushToPixelData,
|
|
3507
|
-
getCircleBrushOrPencilBounds,
|
|
3508
|
-
fallOff: () => 1
|
|
3509
|
-
};
|
|
3510
|
-
var mutatorApplyCirclePencil = ((writer, deps = defaults15) => {
|
|
3511
|
-
const {
|
|
3512
|
-
applyCircleBrushToPixelData: applyCircleBrushToPixelData2 = defaults15.applyCircleBrushToPixelData,
|
|
3513
|
-
getCircleBrushOrPencilBounds: getCircleBrushOrPencilBounds2 = defaults15.getCircleBrushOrPencilBounds,
|
|
3514
|
-
fallOff = defaults15.fallOff
|
|
3515
|
-
} = deps;
|
|
3516
|
-
const boundsOut = {
|
|
3517
|
-
x: 0,
|
|
3518
|
-
y: 0,
|
|
3519
|
-
w: 0,
|
|
3520
|
-
h: 0
|
|
3521
|
-
};
|
|
3522
|
-
return {
|
|
3523
|
-
applyCirclePencil(color, centerX, centerY, brushSize, alpha = 255, blendFn) {
|
|
3524
|
-
const bounds = getCircleBrushOrPencilBounds2(centerX, centerY, brushSize, writer.target.width, writer.target.height, boundsOut);
|
|
3525
|
-
const {
|
|
3526
|
-
x,
|
|
3527
|
-
y,
|
|
3528
|
-
w,
|
|
3529
|
-
h
|
|
3530
|
-
} = bounds;
|
|
3531
|
-
writer.accumulator.storeRegionBeforeState(x, y, w, h);
|
|
3532
|
-
applyCircleBrushToPixelData2(writer.target, color, centerX, centerY, brushSize, alpha, fallOff, blendFn, bounds);
|
|
3533
|
-
}
|
|
3534
|
-
};
|
|
3535
|
-
});
|
|
3536
|
-
|
|
3537
3849
|
// src/ImageData/copyImageData.ts
|
|
3538
3850
|
function copyImageData({
|
|
3539
3851
|
data,
|
|
@@ -3565,8 +3877,8 @@ function makeImageDataLike(width, height, data) {
|
|
|
3565
3877
|
};
|
|
3566
3878
|
}
|
|
3567
3879
|
|
|
3568
|
-
// src/ImageData/
|
|
3569
|
-
function
|
|
3880
|
+
// src/ImageData/imageDataToAlphaMaskBuffer.ts
|
|
3881
|
+
function imageDataToAlphaMaskBuffer(imageData) {
|
|
3570
3882
|
const {
|
|
3571
3883
|
width,
|
|
3572
3884
|
height,
|
|
@@ -3656,13 +3968,13 @@ function resampleImageData(source, factor) {
|
|
|
3656
3968
|
}
|
|
3657
3969
|
|
|
3658
3970
|
// src/ImageData/resizeImageData.ts
|
|
3659
|
-
function resizeImageData(
|
|
3971
|
+
function resizeImageData(target, newWidth, newHeight, offsetX = 0, offsetY = 0) {
|
|
3660
3972
|
const result = new ImageData(newWidth, newHeight);
|
|
3661
3973
|
const {
|
|
3662
3974
|
width: oldW,
|
|
3663
3975
|
height: oldH,
|
|
3664
3976
|
data: oldData
|
|
3665
|
-
} =
|
|
3977
|
+
} = target;
|
|
3666
3978
|
const newData = result.data;
|
|
3667
3979
|
const x0 = Math.max(0, offsetX);
|
|
3668
3980
|
const y0 = Math.max(0, offsetY);
|
|
@@ -3817,7 +4129,7 @@ function writeImageData(target, source, x, y, sx = 0, sy = 0, sw = source.width,
|
|
|
3817
4129
|
|
|
3818
4130
|
// src/ImageData/writeImageDataBuffer.ts
|
|
3819
4131
|
var SCRATCH_BLIT3 = makeClippedBlit();
|
|
3820
|
-
function writeImageDataBuffer(
|
|
4132
|
+
function writeImageDataBuffer(target, data, _x, _y, _w, _h) {
|
|
3821
4133
|
const {
|
|
3822
4134
|
x,
|
|
3823
4135
|
y,
|
|
@@ -3833,7 +4145,7 @@ function writeImageDataBuffer(imageData, data, _x, _y, _w, _h) {
|
|
|
3833
4145
|
width: dstW,
|
|
3834
4146
|
height: dstH,
|
|
3835
4147
|
data: dst
|
|
3836
|
-
} =
|
|
4148
|
+
} = target;
|
|
3837
4149
|
const clip = resolveBlitClipping(x, y, 0, 0, w, h, dstW, dstH, w, h, SCRATCH_BLIT3);
|
|
3838
4150
|
if (!clip.inBounds) return;
|
|
3839
4151
|
const {
|
|
@@ -4079,22 +4391,100 @@ async function getSupportedPixelFormats(rasterMimes = defaultRasterMimes) {
|
|
|
4079
4391
|
return formatsPromise;
|
|
4080
4392
|
}
|
|
4081
4393
|
|
|
4082
|
-
// src/Mask/
|
|
4083
|
-
function
|
|
4084
|
-
|
|
4085
|
-
|
|
4086
|
-
|
|
4087
|
-
w
|
|
4088
|
-
h
|
|
4089
|
-
|
|
4090
|
-
|
|
4091
|
-
|
|
4092
|
-
|
|
4093
|
-
|
|
4094
|
-
|
|
4095
|
-
|
|
4096
|
-
|
|
4097
|
-
|
|
4394
|
+
// src/Mask/AlphaMask.ts
|
|
4395
|
+
function makeAlphaMask(w, h, data) {
|
|
4396
|
+
return {
|
|
4397
|
+
type: 0 /* ALPHA */,
|
|
4398
|
+
data: data ?? new Uint8Array(w * h),
|
|
4399
|
+
w,
|
|
4400
|
+
h
|
|
4401
|
+
};
|
|
4402
|
+
}
|
|
4403
|
+
|
|
4404
|
+
// src/Mask/BinaryMask.ts
|
|
4405
|
+
function makeBinaryMask(w, h, data) {
|
|
4406
|
+
return {
|
|
4407
|
+
type: 1 /* BINARY */,
|
|
4408
|
+
data: data ?? new Uint8Array(w * h),
|
|
4409
|
+
w,
|
|
4410
|
+
h
|
|
4411
|
+
};
|
|
4412
|
+
}
|
|
4413
|
+
|
|
4414
|
+
// src/Mask/CircleBrushAlphaMask.ts
|
|
4415
|
+
function makeCircleBrushAlphaMask(size, fallOff = () => 1) {
|
|
4416
|
+
const area = size * size;
|
|
4417
|
+
const data = new Uint8Array(area);
|
|
4418
|
+
const radius = size / 2;
|
|
4419
|
+
const invR = 1 / radius;
|
|
4420
|
+
const minOffset = -Math.ceil(radius - 0.5);
|
|
4421
|
+
for (let y = 0; y < size; y++) {
|
|
4422
|
+
for (let x = 0; x < size; x++) {
|
|
4423
|
+
const dx = x - radius + 0.5;
|
|
4424
|
+
const dy = y - radius + 0.5;
|
|
4425
|
+
const distSqr = dx * dx + dy * dy;
|
|
4426
|
+
if (distSqr <= radius * radius) {
|
|
4427
|
+
const dist = Math.sqrt(distSqr);
|
|
4428
|
+
data[y * size + x] = fallOff(1 - dist * invR) * 255 | 0;
|
|
4429
|
+
}
|
|
4430
|
+
}
|
|
4431
|
+
}
|
|
4432
|
+
return {
|
|
4433
|
+
type: 0 /* ALPHA */,
|
|
4434
|
+
data,
|
|
4435
|
+
w: size,
|
|
4436
|
+
h: size,
|
|
4437
|
+
radius,
|
|
4438
|
+
size,
|
|
4439
|
+
minOffset
|
|
4440
|
+
};
|
|
4441
|
+
}
|
|
4442
|
+
|
|
4443
|
+
// src/Mask/CircleBrushBinaryMask.ts
|
|
4444
|
+
function makeCircleBrushBinaryMask(size) {
|
|
4445
|
+
const area = size * size;
|
|
4446
|
+
const data = new Uint8Array(area);
|
|
4447
|
+
const radius = size / 2;
|
|
4448
|
+
const minOffset = -Math.ceil(radius - 0.5);
|
|
4449
|
+
for (let y = 0; y < size; y++) {
|
|
4450
|
+
for (let x = 0; x < size; x++) {
|
|
4451
|
+
const dx = x - radius + 0.5;
|
|
4452
|
+
const dy = y - radius + 0.5;
|
|
4453
|
+
const distSqr = dx * dx + dy * dy;
|
|
4454
|
+
if (distSqr <= radius * radius) {
|
|
4455
|
+
data[y * size + x] = 1;
|
|
4456
|
+
}
|
|
4457
|
+
}
|
|
4458
|
+
}
|
|
4459
|
+
return {
|
|
4460
|
+
type: 1 /* BINARY */,
|
|
4461
|
+
data,
|
|
4462
|
+
w: size,
|
|
4463
|
+
h: size,
|
|
4464
|
+
radius,
|
|
4465
|
+
size,
|
|
4466
|
+
minOffset
|
|
4467
|
+
};
|
|
4468
|
+
}
|
|
4469
|
+
|
|
4470
|
+
// src/Mask/applyBinaryMaskToAlphaMask.ts
|
|
4471
|
+
function applyBinaryMaskToAlphaMask(alphaMaskDst, binaryMaskSrc, opts = {}) {
|
|
4472
|
+
const {
|
|
4473
|
+
x: targetX = 0,
|
|
4474
|
+
y: targetY = 0,
|
|
4475
|
+
w: reqWidth = 0,
|
|
4476
|
+
h: reqHeight = 0,
|
|
4477
|
+
mx = 0,
|
|
4478
|
+
my = 0,
|
|
4479
|
+
invertMask = false
|
|
4480
|
+
} = opts;
|
|
4481
|
+
const dstWidth = alphaMaskDst.w;
|
|
4482
|
+
if (dstWidth <= 0) return;
|
|
4483
|
+
if (binaryMaskSrc.data.length === 0) return;
|
|
4484
|
+
const srcWidth = binaryMaskSrc.w;
|
|
4485
|
+
if (srcWidth <= 0) return;
|
|
4486
|
+
const dstHeight = alphaMaskDst.data.length / dstWidth | 0;
|
|
4487
|
+
const srcHeight = binaryMaskSrc.data.length / srcWidth | 0;
|
|
4098
4488
|
if (dstHeight <= 0) return;
|
|
4099
4489
|
if (srcHeight <= 0) return;
|
|
4100
4490
|
const dstX0 = Math.max(0, targetX);
|
|
@@ -4111,6 +4501,8 @@ function applyBinaryMaskToAlphaMask(alphaMaskDst, dstWidth, binaryMaskSrc, srcWi
|
|
|
4111
4501
|
if (srcY0 + (dstY1 - dstY0) <= 0) return;
|
|
4112
4502
|
const iterW = Math.min(dstX1 - dstX0, srcWidth - srcX0);
|
|
4113
4503
|
const iterH = Math.min(dstY1 - dstY0, srcHeight - srcY0);
|
|
4504
|
+
const srcData = binaryMaskSrc.data;
|
|
4505
|
+
const dstData = alphaMaskDst.data;
|
|
4114
4506
|
let dstIdx = dstY0 * dstWidth + dstX0;
|
|
4115
4507
|
let srcIdx = srcY0 * srcWidth + srcX0;
|
|
4116
4508
|
if (invertMask) {
|
|
@@ -4119,8 +4511,8 @@ function applyBinaryMaskToAlphaMask(alphaMaskDst, dstWidth, binaryMaskSrc, srcWi
|
|
|
4119
4511
|
let d = dstIdx;
|
|
4120
4512
|
let s = srcIdx;
|
|
4121
4513
|
while (d < dstEnd) {
|
|
4122
|
-
if (
|
|
4123
|
-
|
|
4514
|
+
if (srcData[s] !== 0) {
|
|
4515
|
+
dstData[d] = 0;
|
|
4124
4516
|
}
|
|
4125
4517
|
d++;
|
|
4126
4518
|
s++;
|
|
@@ -4134,8 +4526,8 @@ function applyBinaryMaskToAlphaMask(alphaMaskDst, dstWidth, binaryMaskSrc, srcWi
|
|
|
4134
4526
|
let d = dstIdx;
|
|
4135
4527
|
let s = srcIdx;
|
|
4136
4528
|
while (d < dstEnd) {
|
|
4137
|
-
if (
|
|
4138
|
-
|
|
4529
|
+
if (srcData[s] === 0) {
|
|
4530
|
+
dstData[d] = 0;
|
|
4139
4531
|
}
|
|
4140
4532
|
d++;
|
|
4141
4533
|
s++;
|
|
@@ -4148,25 +4540,72 @@ function applyBinaryMaskToAlphaMask(alphaMaskDst, dstWidth, binaryMaskSrc, srcWi
|
|
|
4148
4540
|
|
|
4149
4541
|
// src/Mask/copyMask.ts
|
|
4150
4542
|
function copyMask(src) {
|
|
4151
|
-
return
|
|
4543
|
+
return {
|
|
4544
|
+
type: src.type,
|
|
4545
|
+
data: src.data.slice(),
|
|
4546
|
+
w: src.w,
|
|
4547
|
+
h: src.h
|
|
4548
|
+
};
|
|
4549
|
+
}
|
|
4550
|
+
|
|
4551
|
+
// src/Mask/extractMask.ts
|
|
4552
|
+
function extractMask(mask, xOrRect, y, w, h) {
|
|
4553
|
+
let finalX;
|
|
4554
|
+
let finalY;
|
|
4555
|
+
let finalW;
|
|
4556
|
+
let finalH;
|
|
4557
|
+
if (typeof xOrRect === "object") {
|
|
4558
|
+
finalX = xOrRect.x;
|
|
4559
|
+
finalY = xOrRect.y;
|
|
4560
|
+
finalW = xOrRect.w;
|
|
4561
|
+
finalH = xOrRect.h;
|
|
4562
|
+
} else {
|
|
4563
|
+
finalX = xOrRect;
|
|
4564
|
+
finalY = y;
|
|
4565
|
+
finalW = w;
|
|
4566
|
+
finalH = h;
|
|
4567
|
+
}
|
|
4568
|
+
const out = {
|
|
4569
|
+
type: mask.type,
|
|
4570
|
+
w: finalW,
|
|
4571
|
+
h: finalH,
|
|
4572
|
+
data: new Uint8Array(finalW * finalH)
|
|
4573
|
+
};
|
|
4574
|
+
const srcH = mask.h;
|
|
4575
|
+
const stride = mask.w;
|
|
4576
|
+
for (let row = 0; row < finalH; row++) {
|
|
4577
|
+
const currentSrcY = finalY + row;
|
|
4578
|
+
if (currentSrcY < 0 || currentSrcY >= srcH) continue;
|
|
4579
|
+
const start = Math.max(0, finalX);
|
|
4580
|
+
const end = Math.min(stride, finalX + finalW);
|
|
4581
|
+
if (start < end) {
|
|
4582
|
+
const srcOffset = currentSrcY * stride + start;
|
|
4583
|
+
const dstOffset = row * finalW + (start - finalX);
|
|
4584
|
+
const count = end - start;
|
|
4585
|
+
out.data.set(mask.data.subarray(srcOffset, srcOffset + count), dstOffset);
|
|
4586
|
+
}
|
|
4587
|
+
}
|
|
4588
|
+
return out;
|
|
4152
4589
|
}
|
|
4153
4590
|
|
|
4154
4591
|
// src/Mask/invertMask.ts
|
|
4155
4592
|
function invertBinaryMask(dst) {
|
|
4156
|
-
const
|
|
4593
|
+
const data = dst.data;
|
|
4594
|
+
const len = data.length;
|
|
4157
4595
|
for (let i = 0; i < len; i++) {
|
|
4158
|
-
|
|
4596
|
+
data[i] = data[i] === 0 ? 1 : 0;
|
|
4159
4597
|
}
|
|
4160
4598
|
}
|
|
4161
4599
|
function invertAlphaMask(dst) {
|
|
4162
|
-
const
|
|
4600
|
+
const data = dst.data;
|
|
4601
|
+
const len = data.length;
|
|
4163
4602
|
for (let i = 0; i < len; i++) {
|
|
4164
|
-
|
|
4603
|
+
data[i] = 255 - data[i];
|
|
4165
4604
|
}
|
|
4166
4605
|
}
|
|
4167
4606
|
|
|
4168
4607
|
// src/Mask/mergeAlphaMasks.ts
|
|
4169
|
-
function mergeAlphaMasks(dst,
|
|
4608
|
+
function mergeAlphaMasks(dst, src, opts) {
|
|
4170
4609
|
const {
|
|
4171
4610
|
x: targetX = 0,
|
|
4172
4611
|
y: targetY = 0,
|
|
@@ -4177,15 +4616,17 @@ function mergeAlphaMasks(dst, dstWidth, src, srcWidth, opts) {
|
|
|
4177
4616
|
my = 0,
|
|
4178
4617
|
invertMask = false
|
|
4179
4618
|
} = opts;
|
|
4180
|
-
const dstHeight = dst.length / dstWidth | 0;
|
|
4181
|
-
const srcHeight = src.length / srcWidth | 0;
|
|
4182
4619
|
if (width <= 0) return;
|
|
4183
4620
|
if (height <= 0) return;
|
|
4184
4621
|
if (globalAlpha === 0) return;
|
|
4622
|
+
const dstData = dst.data;
|
|
4623
|
+
const srcData = src.data;
|
|
4624
|
+
const srcWidth = src.w;
|
|
4625
|
+
const dstWidth = dst.w;
|
|
4185
4626
|
const startX = Math.max(0, -targetX, -mx);
|
|
4186
4627
|
const startY = Math.max(0, -targetY, -my);
|
|
4187
4628
|
const endX = Math.min(width, dstWidth - targetX, srcWidth - mx);
|
|
4188
|
-
const endY = Math.min(height,
|
|
4629
|
+
const endY = Math.min(height, dst.h - targetY, src.h - my);
|
|
4189
4630
|
if (startX >= endX) return;
|
|
4190
4631
|
if (startY >= endY) return;
|
|
4191
4632
|
for (let iy = startY; iy < endY; iy++) {
|
|
@@ -4194,7 +4635,7 @@ function mergeAlphaMasks(dst, dstWidth, src, srcWidth, opts) {
|
|
|
4194
4635
|
let dIdx = dy * dstWidth + targetX + startX;
|
|
4195
4636
|
let sIdx = sy * srcWidth + mx + startX;
|
|
4196
4637
|
for (let ix = startX; ix < endX; ix++) {
|
|
4197
|
-
const rawM =
|
|
4638
|
+
const rawM = srcData[sIdx];
|
|
4198
4639
|
const effectiveM = invertMask ? 255 - rawM : rawM;
|
|
4199
4640
|
let weight = 0;
|
|
4200
4641
|
if (effectiveM === 0) {
|
|
@@ -4208,13 +4649,13 @@ function mergeAlphaMasks(dst, dstWidth, src, srcWidth, opts) {
|
|
|
4208
4649
|
}
|
|
4209
4650
|
if (weight !== 255) {
|
|
4210
4651
|
if (weight === 0) {
|
|
4211
|
-
|
|
4652
|
+
dstData[dIdx] = 0;
|
|
4212
4653
|
} else {
|
|
4213
|
-
const da =
|
|
4654
|
+
const da = dstData[dIdx];
|
|
4214
4655
|
if (da === 255) {
|
|
4215
|
-
|
|
4656
|
+
dstData[dIdx] = weight;
|
|
4216
4657
|
} else if (da !== 0) {
|
|
4217
|
-
|
|
4658
|
+
dstData[dIdx] = da * weight + 128 >> 8;
|
|
4218
4659
|
}
|
|
4219
4660
|
}
|
|
4220
4661
|
}
|
|
@@ -4225,7 +4666,7 @@ function mergeAlphaMasks(dst, dstWidth, src, srcWidth, opts) {
|
|
|
4225
4666
|
}
|
|
4226
4667
|
|
|
4227
4668
|
// src/Mask/mergeBinaryMasks.ts
|
|
4228
|
-
function mergeBinaryMasks(dst,
|
|
4669
|
+
function mergeBinaryMasks(dst, src, opts) {
|
|
4229
4670
|
const {
|
|
4230
4671
|
x: targetX = 0,
|
|
4231
4672
|
y: targetY = 0,
|
|
@@ -4235,10 +4676,12 @@ function mergeBinaryMasks(dst, dstWidth, src, srcWidth, opts) {
|
|
|
4235
4676
|
my = 0,
|
|
4236
4677
|
invertMask = false
|
|
4237
4678
|
} = opts;
|
|
4679
|
+
const dstData = dst.data;
|
|
4680
|
+
const srcData = src.data;
|
|
4681
|
+
const srcWidth = src.w;
|
|
4682
|
+
const dstWidth = dst.w;
|
|
4238
4683
|
if (dstWidth <= 0) return;
|
|
4239
4684
|
if (srcWidth <= 0) return;
|
|
4240
|
-
const dstHeight = dst.length / dstWidth | 0;
|
|
4241
|
-
const srcHeight = src.length / srcWidth | 0;
|
|
4242
4685
|
let x = targetX;
|
|
4243
4686
|
let y = targetY;
|
|
4244
4687
|
let w = width;
|
|
@@ -4252,7 +4695,7 @@ function mergeBinaryMasks(dst, dstWidth, src, srcWidth, opts) {
|
|
|
4252
4695
|
y = 0;
|
|
4253
4696
|
}
|
|
4254
4697
|
w = Math.min(w, dstWidth - x);
|
|
4255
|
-
h = Math.min(h,
|
|
4698
|
+
h = Math.min(h, dst.h - y);
|
|
4256
4699
|
if (w <= 0) return;
|
|
4257
4700
|
if (h <= 0) return;
|
|
4258
4701
|
const startX = mx + (x - targetX);
|
|
@@ -4260,7 +4703,7 @@ function mergeBinaryMasks(dst, dstWidth, src, srcWidth, opts) {
|
|
|
4260
4703
|
const sX0 = Math.max(0, startX);
|
|
4261
4704
|
const sY0 = Math.max(0, startY);
|
|
4262
4705
|
const sX1 = Math.min(srcWidth, startX + w);
|
|
4263
|
-
const sY1 = Math.min(
|
|
4706
|
+
const sY1 = Math.min(src.h, startY + h);
|
|
4264
4707
|
const finalW = sX1 - sX0;
|
|
4265
4708
|
const finalH = sY1 - sY0;
|
|
4266
4709
|
if (finalW <= 0) return;
|
|
@@ -4273,10 +4716,10 @@ function mergeBinaryMasks(dst, dstWidth, src, srcWidth, opts) {
|
|
|
4273
4716
|
let sIdx = sY0 * srcWidth + sX0;
|
|
4274
4717
|
for (let iy = 0; iy < finalH; iy++) {
|
|
4275
4718
|
for (let ix = 0; ix < finalW; ix++) {
|
|
4276
|
-
const mVal =
|
|
4719
|
+
const mVal = srcData[sIdx];
|
|
4277
4720
|
const isMaskedOut = invertMask ? mVal !== 0 : mVal === 0;
|
|
4278
4721
|
if (isMaskedOut) {
|
|
4279
|
-
|
|
4722
|
+
dstData[dIdx] = 0;
|
|
4280
4723
|
}
|
|
4281
4724
|
dIdx++;
|
|
4282
4725
|
sIdx++;
|
|
@@ -4286,6 +4729,177 @@ function mergeBinaryMasks(dst, dstWidth, src, srcWidth, opts) {
|
|
|
4286
4729
|
}
|
|
4287
4730
|
}
|
|
4288
4731
|
|
|
4732
|
+
// src/Mask/setMaskData.ts
|
|
4733
|
+
function setMaskData(mask, width, height, data) {
|
|
4734
|
+
;
|
|
4735
|
+
mask.w = width;
|
|
4736
|
+
mask.h = height;
|
|
4737
|
+
mask.data = data;
|
|
4738
|
+
}
|
|
4739
|
+
|
|
4740
|
+
// src/MaskRect/subtractBinaryMaskRects.ts
|
|
4741
|
+
function subtractBinaryMaskRects(current, subtracting) {
|
|
4742
|
+
let result = [...current];
|
|
4743
|
+
for (const sub of subtracting) {
|
|
4744
|
+
const next = [];
|
|
4745
|
+
for (const r of result) {
|
|
4746
|
+
const ix = Math.max(r.x, sub.x);
|
|
4747
|
+
const iy = Math.max(r.y, sub.y);
|
|
4748
|
+
const ix2 = Math.min(r.x + r.w, sub.x + sub.w);
|
|
4749
|
+
const iy2 = Math.min(r.y + r.h, sub.y + sub.h);
|
|
4750
|
+
if (ix >= ix2 || iy >= iy2) {
|
|
4751
|
+
next.push(r);
|
|
4752
|
+
continue;
|
|
4753
|
+
}
|
|
4754
|
+
if (r.y < iy) pushPiece(next, r, r.x, r.y, r.w, iy - r.y);
|
|
4755
|
+
if (iy2 < r.y + r.h) pushPiece(next, r, r.x, iy2, r.w, r.y + r.h - iy2);
|
|
4756
|
+
if (r.x < ix) pushPiece(next, r, r.x, iy, ix - r.x, iy2 - iy);
|
|
4757
|
+
if (ix2 < r.x + r.w) pushPiece(next, r, ix2, iy, r.x + r.w - ix2, iy2 - iy);
|
|
4758
|
+
}
|
|
4759
|
+
result = next;
|
|
4760
|
+
}
|
|
4761
|
+
return result;
|
|
4762
|
+
}
|
|
4763
|
+
function pushPiece(dest, r, x, y, w, h) {
|
|
4764
|
+
if (r.data === null || r.data === void 0) {
|
|
4765
|
+
dest.push({
|
|
4766
|
+
x,
|
|
4767
|
+
y,
|
|
4768
|
+
w,
|
|
4769
|
+
h,
|
|
4770
|
+
data: null,
|
|
4771
|
+
type: null
|
|
4772
|
+
});
|
|
4773
|
+
return;
|
|
4774
|
+
}
|
|
4775
|
+
const lx = x - r.x;
|
|
4776
|
+
const ly = y - r.y;
|
|
4777
|
+
const data = new Uint8Array(w * h);
|
|
4778
|
+
for (let row = 0; row < h; row++) {
|
|
4779
|
+
data.set(r.data.subarray((ly + row) * r.w + lx, (ly + row) * r.w + lx + w), row * w);
|
|
4780
|
+
}
|
|
4781
|
+
dest.push({
|
|
4782
|
+
x,
|
|
4783
|
+
y,
|
|
4784
|
+
w,
|
|
4785
|
+
h,
|
|
4786
|
+
data,
|
|
4787
|
+
type: 1 /* BINARY */
|
|
4788
|
+
});
|
|
4789
|
+
}
|
|
4790
|
+
|
|
4791
|
+
// src/Rect/getRectsBounds.ts
|
|
4792
|
+
function getRectsBounds(rects) {
|
|
4793
|
+
if (rects.length === 1) return {
|
|
4794
|
+
...rects[0]
|
|
4795
|
+
};
|
|
4796
|
+
let minX = Infinity, minY = Infinity;
|
|
4797
|
+
let maxX = -Infinity, maxY = -Infinity;
|
|
4798
|
+
for (let i = 0; i < rects.length; i++) {
|
|
4799
|
+
const r = rects[i];
|
|
4800
|
+
const x1 = r.x;
|
|
4801
|
+
const y1 = r.y;
|
|
4802
|
+
const x2 = x1 + r.w;
|
|
4803
|
+
const y2 = y1 + r.h;
|
|
4804
|
+
if (x1 < minX) minX = x1;
|
|
4805
|
+
if (y1 < minY) minY = y1;
|
|
4806
|
+
if (x2 > maxX) maxX = x2;
|
|
4807
|
+
if (y2 > maxY) maxY = y2;
|
|
4808
|
+
}
|
|
4809
|
+
return {
|
|
4810
|
+
x: minX,
|
|
4811
|
+
y: minY,
|
|
4812
|
+
w: maxX - minX,
|
|
4813
|
+
h: maxY - minY
|
|
4814
|
+
};
|
|
4815
|
+
}
|
|
4816
|
+
|
|
4817
|
+
// src/MaskRect/merge2BinaryMaskRects.ts
|
|
4818
|
+
function merge2BinaryMaskRects(a, b) {
|
|
4819
|
+
const bounds = getRectsBounds([a, b]);
|
|
4820
|
+
if ((a.data === null || a.data === void 0) && (b.data === null || b.data === void 0)) {
|
|
4821
|
+
const ix = Math.max(a.x, b.x);
|
|
4822
|
+
const iy = Math.max(a.y, b.y);
|
|
4823
|
+
const ir = Math.min(a.x + a.w, b.x + b.w);
|
|
4824
|
+
const ib = Math.min(a.y + a.h, b.y + b.h);
|
|
4825
|
+
const iw = Math.max(0, ir - ix);
|
|
4826
|
+
const ih = Math.max(0, ib - iy);
|
|
4827
|
+
const intersectionArea = iw * ih;
|
|
4828
|
+
const areaA = a.w * a.h;
|
|
4829
|
+
const areaB = b.w * b.h;
|
|
4830
|
+
const boundsArea = bounds.w * bounds.h;
|
|
4831
|
+
if (boundsArea === areaA + areaB - intersectionArea) {
|
|
4832
|
+
return {
|
|
4833
|
+
...bounds,
|
|
4834
|
+
data: null,
|
|
4835
|
+
type: null
|
|
4836
|
+
};
|
|
4837
|
+
}
|
|
4838
|
+
}
|
|
4839
|
+
const maskData = new Uint8Array(bounds.w * bounds.h);
|
|
4840
|
+
const aOffY = a.y - bounds.y;
|
|
4841
|
+
const aOffX = a.x - bounds.x;
|
|
4842
|
+
if (a.data === void 0 || a.data === null) {
|
|
4843
|
+
for (let ay = 0; ay < a.h; ay++) {
|
|
4844
|
+
const destRow = (aOffY + ay) * bounds.w + aOffX;
|
|
4845
|
+
maskData.fill(1, destRow, destRow + a.w);
|
|
4846
|
+
}
|
|
4847
|
+
} else {
|
|
4848
|
+
for (let ay = 0; ay < a.h; ay++) {
|
|
4849
|
+
const srcRow = ay * a.w;
|
|
4850
|
+
const destRow = (aOffY + ay) * bounds.w + aOffX;
|
|
4851
|
+
maskData.set(a.data.subarray(srcRow, srcRow + a.w), destRow);
|
|
4852
|
+
}
|
|
4853
|
+
}
|
|
4854
|
+
const bOffY = b.y - bounds.y;
|
|
4855
|
+
const bOffX = b.x - bounds.x;
|
|
4856
|
+
if (b.data === void 0 || b.data === null) {
|
|
4857
|
+
for (let by = 0; by < b.h; by++) {
|
|
4858
|
+
const destRow = (bOffY + by) * bounds.w + bOffX;
|
|
4859
|
+
maskData.fill(1, destRow, destRow + b.w);
|
|
4860
|
+
}
|
|
4861
|
+
} else {
|
|
4862
|
+
for (let by = 0; by < b.h; by++) {
|
|
4863
|
+
const srcRow = by * b.w;
|
|
4864
|
+
const destRow = (bOffY + by) * bounds.w + bOffX;
|
|
4865
|
+
for (let bx = 0; bx < b.w; bx++) {
|
|
4866
|
+
maskData[destRow + bx] |= b.data[srcRow + bx];
|
|
4867
|
+
}
|
|
4868
|
+
}
|
|
4869
|
+
}
|
|
4870
|
+
return {
|
|
4871
|
+
...bounds,
|
|
4872
|
+
data: maskData,
|
|
4873
|
+
type: 1 /* BINARY */
|
|
4874
|
+
};
|
|
4875
|
+
}
|
|
4876
|
+
|
|
4877
|
+
// src/MaskRect/mergeBinaryMaskRects.ts
|
|
4878
|
+
function mergeBinaryMaskRects(current, adding) {
|
|
4879
|
+
const rects = [...current, ...adding];
|
|
4880
|
+
let changed = true;
|
|
4881
|
+
while (changed) {
|
|
4882
|
+
changed = false;
|
|
4883
|
+
const next = [];
|
|
4884
|
+
for (const r of rects) {
|
|
4885
|
+
let merged = false;
|
|
4886
|
+
for (let i = 0; i < next.length; i++) {
|
|
4887
|
+
const n = next[i];
|
|
4888
|
+
const overlap = r.x <= n.x + n.w && r.x + r.w >= n.x && r.y <= n.y + n.h && r.y + r.h >= n.y;
|
|
4889
|
+
if (overlap) {
|
|
4890
|
+
next[i] = merge2BinaryMaskRects(n, r);
|
|
4891
|
+
merged = true;
|
|
4892
|
+
changed = true;
|
|
4893
|
+
break;
|
|
4894
|
+
}
|
|
4895
|
+
}
|
|
4896
|
+
if (!merged) next.push(r);
|
|
4897
|
+
}
|
|
4898
|
+
rects.splice(0, rects.length, ...next);
|
|
4899
|
+
}
|
|
4900
|
+
return rects;
|
|
4901
|
+
}
|
|
4902
|
+
|
|
4289
4903
|
// src/PixelData/PixelData.ts
|
|
4290
4904
|
var PixelData = class _PixelData {
|
|
4291
4905
|
data32;
|
|
@@ -4326,223 +4940,6 @@ var PixelData = class _PixelData {
|
|
|
4326
4940
|
}
|
|
4327
4941
|
};
|
|
4328
4942
|
|
|
4329
|
-
// src/PixelData/blendPixelDataAlphaMask.ts
|
|
4330
|
-
function blendPixelDataAlphaMask(dst, src, alphaMask, opts = {}) {
|
|
4331
|
-
const {
|
|
4332
|
-
x: targetX = 0,
|
|
4333
|
-
y: targetY = 0,
|
|
4334
|
-
sx: sourceX = 0,
|
|
4335
|
-
sy: sourceY = 0,
|
|
4336
|
-
w: width = src.width,
|
|
4337
|
-
h: height = src.height,
|
|
4338
|
-
alpha: globalAlpha = 255,
|
|
4339
|
-
blendFn = sourceOverPerfect,
|
|
4340
|
-
mw = src.width,
|
|
4341
|
-
mx = 0,
|
|
4342
|
-
my = 0,
|
|
4343
|
-
invertMask = false
|
|
4344
|
-
} = opts;
|
|
4345
|
-
if (globalAlpha === 0) return;
|
|
4346
|
-
let x = targetX;
|
|
4347
|
-
let y = targetY;
|
|
4348
|
-
let sx = sourceX;
|
|
4349
|
-
let sy = sourceY;
|
|
4350
|
-
let w = width;
|
|
4351
|
-
let h = height;
|
|
4352
|
-
if (sx < 0) {
|
|
4353
|
-
x -= sx;
|
|
4354
|
-
w += sx;
|
|
4355
|
-
sx = 0;
|
|
4356
|
-
}
|
|
4357
|
-
if (sy < 0) {
|
|
4358
|
-
y -= sy;
|
|
4359
|
-
h += sy;
|
|
4360
|
-
sy = 0;
|
|
4361
|
-
}
|
|
4362
|
-
w = Math.min(w, src.width - sx);
|
|
4363
|
-
h = Math.min(h, src.height - sy);
|
|
4364
|
-
if (x < 0) {
|
|
4365
|
-
sx -= x;
|
|
4366
|
-
w += x;
|
|
4367
|
-
x = 0;
|
|
4368
|
-
}
|
|
4369
|
-
if (y < 0) {
|
|
4370
|
-
sy -= y;
|
|
4371
|
-
h += y;
|
|
4372
|
-
y = 0;
|
|
4373
|
-
}
|
|
4374
|
-
const actualW = Math.min(w, dst.width - x);
|
|
4375
|
-
const actualH = Math.min(h, dst.height - y);
|
|
4376
|
-
if (actualW <= 0 || actualH <= 0) return;
|
|
4377
|
-
const dw = dst.width;
|
|
4378
|
-
const sw = src.width;
|
|
4379
|
-
const mPitch = mw;
|
|
4380
|
-
const dx = x - targetX | 0;
|
|
4381
|
-
const dy = y - targetY | 0;
|
|
4382
|
-
const dst32 = dst.data32;
|
|
4383
|
-
const src32 = src.data32;
|
|
4384
|
-
let dIdx = y * dw + x | 0;
|
|
4385
|
-
let sIdx = sy * sw + sx | 0;
|
|
4386
|
-
let mIdx = (my + dy) * mPitch + (mx + dx) | 0;
|
|
4387
|
-
const dStride = dw - actualW | 0;
|
|
4388
|
-
const sStride = sw - actualW | 0;
|
|
4389
|
-
const mStride = mPitch - actualW | 0;
|
|
4390
|
-
const isOpaque = globalAlpha === 255;
|
|
4391
|
-
const isOverwrite = blendFn.isOverwrite || false;
|
|
4392
|
-
for (let iy = 0; iy < actualH; iy++) {
|
|
4393
|
-
for (let ix = 0; ix < actualW; ix++) {
|
|
4394
|
-
const mVal = alphaMask[mIdx];
|
|
4395
|
-
const effM = invertMask ? 255 - mVal : mVal;
|
|
4396
|
-
if (effM === 0) {
|
|
4397
|
-
dIdx++;
|
|
4398
|
-
sIdx++;
|
|
4399
|
-
mIdx++;
|
|
4400
|
-
continue;
|
|
4401
|
-
}
|
|
4402
|
-
const srcCol = src32[sIdx];
|
|
4403
|
-
const srcAlpha = srcCol >>> 24;
|
|
4404
|
-
if (srcAlpha === 0 && !isOverwrite) {
|
|
4405
|
-
dIdx++;
|
|
4406
|
-
sIdx++;
|
|
4407
|
-
mIdx++;
|
|
4408
|
-
continue;
|
|
4409
|
-
}
|
|
4410
|
-
let weight = globalAlpha;
|
|
4411
|
-
if (isOpaque) {
|
|
4412
|
-
weight = effM;
|
|
4413
|
-
} else if (effM !== 255) {
|
|
4414
|
-
weight = effM * globalAlpha + 128 >> 8;
|
|
4415
|
-
}
|
|
4416
|
-
if (weight === 0) {
|
|
4417
|
-
dIdx++;
|
|
4418
|
-
sIdx++;
|
|
4419
|
-
mIdx++;
|
|
4420
|
-
continue;
|
|
4421
|
-
}
|
|
4422
|
-
let finalCol = srcCol;
|
|
4423
|
-
if (weight < 255) {
|
|
4424
|
-
const a = srcAlpha * weight + 128 >> 8;
|
|
4425
|
-
if (a === 0 && !isOverwrite) {
|
|
4426
|
-
dIdx++;
|
|
4427
|
-
sIdx++;
|
|
4428
|
-
mIdx++;
|
|
4429
|
-
continue;
|
|
4430
|
-
}
|
|
4431
|
-
finalCol = (srcCol & 16777215 | a << 24) >>> 0;
|
|
4432
|
-
}
|
|
4433
|
-
dst32[dIdx] = blendFn(finalCol, dst32[dIdx]);
|
|
4434
|
-
dIdx++;
|
|
4435
|
-
sIdx++;
|
|
4436
|
-
mIdx++;
|
|
4437
|
-
}
|
|
4438
|
-
dIdx += dStride;
|
|
4439
|
-
sIdx += sStride;
|
|
4440
|
-
mIdx += mStride;
|
|
4441
|
-
}
|
|
4442
|
-
}
|
|
4443
|
-
|
|
4444
|
-
// src/PixelData/blendPixelDataBinaryMask.ts
|
|
4445
|
-
function blendPixelDataBinaryMask(dst, src, binaryMask, opts) {
|
|
4446
|
-
const {
|
|
4447
|
-
x: targetX = 0,
|
|
4448
|
-
y: targetY = 0,
|
|
4449
|
-
sx: sourceX = 0,
|
|
4450
|
-
sy: sourceY = 0,
|
|
4451
|
-
w: width = src.width,
|
|
4452
|
-
h: height = src.height,
|
|
4453
|
-
alpha: globalAlpha = 255,
|
|
4454
|
-
blendFn = sourceOverPerfect,
|
|
4455
|
-
mw = src.width,
|
|
4456
|
-
mx = 0,
|
|
4457
|
-
my = 0,
|
|
4458
|
-
invertMask = false
|
|
4459
|
-
} = opts;
|
|
4460
|
-
if (globalAlpha === 0) return;
|
|
4461
|
-
let x = targetX;
|
|
4462
|
-
let y = targetY;
|
|
4463
|
-
let sx = sourceX;
|
|
4464
|
-
let sy = sourceY;
|
|
4465
|
-
let w = width;
|
|
4466
|
-
let h = height;
|
|
4467
|
-
if (sx < 0) {
|
|
4468
|
-
x -= sx;
|
|
4469
|
-
w += sx;
|
|
4470
|
-
sx = 0;
|
|
4471
|
-
}
|
|
4472
|
-
if (sy < 0) {
|
|
4473
|
-
y -= sy;
|
|
4474
|
-
h += sy;
|
|
4475
|
-
sy = 0;
|
|
4476
|
-
}
|
|
4477
|
-
w = Math.min(w, src.width - sx);
|
|
4478
|
-
h = Math.min(h, src.height - sy);
|
|
4479
|
-
if (x < 0) {
|
|
4480
|
-
sx -= x;
|
|
4481
|
-
w += x;
|
|
4482
|
-
x = 0;
|
|
4483
|
-
}
|
|
4484
|
-
if (y < 0) {
|
|
4485
|
-
sy -= y;
|
|
4486
|
-
h += y;
|
|
4487
|
-
y = 0;
|
|
4488
|
-
}
|
|
4489
|
-
const actualW = Math.min(w, dst.width - x);
|
|
4490
|
-
const actualH = Math.min(h, dst.height - y);
|
|
4491
|
-
if (actualW <= 0 || actualH <= 0) return;
|
|
4492
|
-
const dx = x - targetX | 0;
|
|
4493
|
-
const dy = y - targetY | 0;
|
|
4494
|
-
const dst32 = dst.data32;
|
|
4495
|
-
const src32 = src.data32;
|
|
4496
|
-
const dw = dst.width;
|
|
4497
|
-
const sw = src.width;
|
|
4498
|
-
const mPitch = mw;
|
|
4499
|
-
let dIdx = y * dw + x | 0;
|
|
4500
|
-
let sIdx = sy * sw + sx | 0;
|
|
4501
|
-
let mIdx = (my + dy) * mPitch + (mx + dx) | 0;
|
|
4502
|
-
const dStride = dw - actualW | 0;
|
|
4503
|
-
const sStride = sw - actualW | 0;
|
|
4504
|
-
const mStride = mPitch - actualW | 0;
|
|
4505
|
-
const skipVal = invertMask ? 1 : 0;
|
|
4506
|
-
const isOpaque = globalAlpha === 255;
|
|
4507
|
-
const isOverwrite = blendFn.isOverwrite || false;
|
|
4508
|
-
for (let iy = 0; iy < actualH; iy++) {
|
|
4509
|
-
for (let ix = 0; ix < actualW; ix++) {
|
|
4510
|
-
if (binaryMask[mIdx] === skipVal) {
|
|
4511
|
-
dIdx++;
|
|
4512
|
-
sIdx++;
|
|
4513
|
-
mIdx++;
|
|
4514
|
-
continue;
|
|
4515
|
-
}
|
|
4516
|
-
const srcCol = src32[sIdx];
|
|
4517
|
-
const srcAlpha = srcCol >>> 24;
|
|
4518
|
-
if (srcAlpha === 0 && !isOverwrite) {
|
|
4519
|
-
dIdx++;
|
|
4520
|
-
sIdx++;
|
|
4521
|
-
mIdx++;
|
|
4522
|
-
continue;
|
|
4523
|
-
}
|
|
4524
|
-
let finalCol = srcCol;
|
|
4525
|
-
if (!isOpaque) {
|
|
4526
|
-
const a = srcAlpha * globalAlpha + 128 >> 8;
|
|
4527
|
-
if (a === 0 && !isOverwrite) {
|
|
4528
|
-
dIdx++;
|
|
4529
|
-
sIdx++;
|
|
4530
|
-
mIdx++;
|
|
4531
|
-
continue;
|
|
4532
|
-
}
|
|
4533
|
-
finalCol = (srcCol & 16777215 | a << 24) >>> 0;
|
|
4534
|
-
}
|
|
4535
|
-
dst32[dIdx] = blendFn(finalCol, dst32[dIdx]);
|
|
4536
|
-
dIdx++;
|
|
4537
|
-
sIdx++;
|
|
4538
|
-
mIdx++;
|
|
4539
|
-
}
|
|
4540
|
-
dIdx += dStride;
|
|
4541
|
-
sIdx += sStride;
|
|
4542
|
-
mIdx += mStride;
|
|
4543
|
-
}
|
|
4544
|
-
}
|
|
4545
|
-
|
|
4546
4943
|
// src/PixelData/clearPixelData.ts
|
|
4547
4944
|
function clearPixelData(dst, rect) {
|
|
4548
4945
|
fillPixelData(dst, 0, rect);
|
|
@@ -4635,10 +5032,11 @@ function pixelDataToAlphaMask(pixelData) {
|
|
|
4635
5032
|
height
|
|
4636
5033
|
} = pixelData;
|
|
4637
5034
|
const len = data32.length;
|
|
4638
|
-
const mask =
|
|
5035
|
+
const mask = makeAlphaMask(width, height);
|
|
5036
|
+
const maskData = mask.data;
|
|
4639
5037
|
for (let i = 0; i < len; i++) {
|
|
4640
5038
|
const val = data32[i];
|
|
4641
|
-
|
|
5039
|
+
maskData[i] = val >>> 24 & 255;
|
|
4642
5040
|
}
|
|
4643
5041
|
return mask;
|
|
4644
5042
|
}
|
|
@@ -4820,11 +5218,13 @@ function writePixelDataBuffer(target, data, _x, _y, _w, _h) {
|
|
|
4820
5218
|
exclusionPerfect,
|
|
4821
5219
|
extractImageDataBuffer,
|
|
4822
5220
|
extractMask,
|
|
5221
|
+
extractMaskBuffer,
|
|
4823
5222
|
extractPixelData,
|
|
4824
5223
|
extractPixelDataBuffer,
|
|
4825
5224
|
fileInputChangeToImageData,
|
|
4826
5225
|
fileToImageData,
|
|
4827
5226
|
fillPixelData,
|
|
5227
|
+
fillPixelDataBinaryMask,
|
|
4828
5228
|
floodFillSelection,
|
|
4829
5229
|
forEachLinePoint,
|
|
4830
5230
|
getCircleBrushOrPencilBounds,
|
|
@@ -4833,12 +5233,13 @@ function writePixelDataBuffer(target, data, _x, _y, _w, _h) {
|
|
|
4833
5233
|
getIndexedImageColorCounts,
|
|
4834
5234
|
getRectBrushOrPencilBounds,
|
|
4835
5235
|
getRectBrushOrPencilStrokeBounds,
|
|
5236
|
+
getRectsBounds,
|
|
4836
5237
|
getSupportedPixelFormats,
|
|
4837
5238
|
hardLightFast,
|
|
4838
5239
|
hardLightPerfect,
|
|
4839
5240
|
hardMixFast,
|
|
4840
5241
|
hardMixPerfect,
|
|
4841
|
-
|
|
5242
|
+
imageDataToAlphaMaskBuffer,
|
|
4842
5243
|
imageDataToDataUrl,
|
|
4843
5244
|
imageDataToImgBlob,
|
|
4844
5245
|
imageDataToUInt32Array,
|
|
@@ -4861,7 +5262,11 @@ function writePixelDataBuffer(target, data, _x, _y, _w, _h) {
|
|
|
4861
5262
|
linearDodgePerfect,
|
|
4862
5263
|
linearLightFast,
|
|
4863
5264
|
linearLightPerfect,
|
|
5265
|
+
makeAlphaMask,
|
|
5266
|
+
makeBinaryMask,
|
|
4864
5267
|
makeBlendModeRegistry,
|
|
5268
|
+
makeCircleBrushAlphaMask,
|
|
5269
|
+
makeCircleBrushBinaryMask,
|
|
4865
5270
|
makeFastBlendModeRegistry,
|
|
4866
5271
|
makeFullPixelMutator,
|
|
4867
5272
|
makeImageDataLike,
|
|
@@ -4869,7 +5274,9 @@ function writePixelDataBuffer(target, data, _x, _y, _w, _h) {
|
|
|
4869
5274
|
makePixelCanvas,
|
|
4870
5275
|
makeReusableCanvas,
|
|
4871
5276
|
makeReusableImageData,
|
|
5277
|
+
merge2BinaryMaskRects,
|
|
4872
5278
|
mergeAlphaMasks,
|
|
5279
|
+
mergeBinaryMaskRects,
|
|
4873
5280
|
mergeBinaryMasks,
|
|
4874
5281
|
multiplyFast,
|
|
4875
5282
|
multiplyPerfect,
|
|
@@ -4886,8 +5293,11 @@ function writePixelDataBuffer(target, data, _x, _y, _w, _h) {
|
|
|
4886
5293
|
mutatorBlendColor,
|
|
4887
5294
|
mutatorBlendPixel,
|
|
4888
5295
|
mutatorBlendPixelData,
|
|
5296
|
+
mutatorBlendPixelDataAlphaMask,
|
|
5297
|
+
mutatorBlendPixelDataBinaryMask,
|
|
4889
5298
|
mutatorClear,
|
|
4890
5299
|
mutatorFill,
|
|
5300
|
+
mutatorFillBinaryMask,
|
|
4891
5301
|
mutatorInvert,
|
|
4892
5302
|
overlayFast,
|
|
4893
5303
|
overlayPerfect,
|
|
@@ -4910,10 +5320,12 @@ function writePixelDataBuffer(target, data, _x, _y, _w, _h) {
|
|
|
4910
5320
|
screenPerfect,
|
|
4911
5321
|
serializeImageData,
|
|
4912
5322
|
serializeNullableImageData,
|
|
5323
|
+
setMaskData,
|
|
4913
5324
|
softLightFast,
|
|
4914
5325
|
softLightPerfect,
|
|
4915
5326
|
sourceOverFast,
|
|
4916
5327
|
sourceOverPerfect,
|
|
5328
|
+
subtractBinaryMaskRects,
|
|
4917
5329
|
subtractFast,
|
|
4918
5330
|
subtractPerfect,
|
|
4919
5331
|
toBlendModeIndexAndName,
|