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.prod.js
CHANGED
|
@@ -196,8 +196,8 @@ function extractImageDataBuffer(imageData, _x, _y, _w, _h) {
|
|
|
196
196
|
return out;
|
|
197
197
|
}
|
|
198
198
|
|
|
199
|
-
// src/Mask/
|
|
200
|
-
function
|
|
199
|
+
// src/Mask/extractMaskBuffer.ts
|
|
200
|
+
function extractMaskBuffer(maskBuffer, maskWidth, xOrRect, y, w, h) {
|
|
201
201
|
let finalX;
|
|
202
202
|
let finalY;
|
|
203
203
|
let finalW;
|
|
@@ -214,7 +214,7 @@ function extractMask(mask, maskWidth, xOrRect, y, w, h) {
|
|
|
214
214
|
finalH = h;
|
|
215
215
|
}
|
|
216
216
|
const out = new Uint8Array(finalW * finalH);
|
|
217
|
-
const srcH =
|
|
217
|
+
const srcH = maskBuffer.length / maskWidth;
|
|
218
218
|
for (let row = 0; row < finalH; row++) {
|
|
219
219
|
const currentSrcY = finalY + row;
|
|
220
220
|
if (currentSrcY < 0 || currentSrcY >= srcH) {
|
|
@@ -226,7 +226,7 @@ function extractMask(mask, maskWidth, xOrRect, y, w, h) {
|
|
|
226
226
|
const srcOffset = currentSrcY * maskWidth + start;
|
|
227
227
|
const dstOffset = row * finalW + (start - finalX);
|
|
228
228
|
const count = end - start;
|
|
229
|
-
out.set(
|
|
229
|
+
out.set(maskBuffer.subarray(srcOffset, srcOffset + count), dstOffset);
|
|
230
230
|
}
|
|
231
231
|
}
|
|
232
232
|
return out;
|
|
@@ -244,8 +244,8 @@ function trimRectBounds(target, bounds) {
|
|
|
244
244
|
if (intersectedMaxX <= intersectedX || intersectedMaxY <= intersectedY) {
|
|
245
245
|
target.w = 0;
|
|
246
246
|
target.h = 0;
|
|
247
|
-
if ("
|
|
248
|
-
target.
|
|
247
|
+
if ("data" in target && target.data) {
|
|
248
|
+
target.data = new Uint8Array(0);
|
|
249
249
|
}
|
|
250
250
|
return;
|
|
251
251
|
}
|
|
@@ -257,15 +257,15 @@ function trimRectBounds(target, bounds) {
|
|
|
257
257
|
target.y = intersectedY;
|
|
258
258
|
target.w = intersectedW;
|
|
259
259
|
target.h = intersectedH;
|
|
260
|
-
if ("
|
|
261
|
-
const
|
|
260
|
+
if ("data" in target && target.data) {
|
|
261
|
+
const currentMaskBuffer = extractMaskBuffer(target.data, originalW, offsetX, offsetY, intersectedW, intersectedH);
|
|
262
262
|
let minX = intersectedW;
|
|
263
263
|
let maxX = -1;
|
|
264
264
|
let minY = intersectedH;
|
|
265
265
|
let maxY = -1;
|
|
266
266
|
for (let y = 0; y < intersectedH; y++) {
|
|
267
267
|
for (let x = 0; x < intersectedW; x++) {
|
|
268
|
-
if (
|
|
268
|
+
if (currentMaskBuffer[y * intersectedW + x] !== 0) {
|
|
269
269
|
if (x < minX) minX = x;
|
|
270
270
|
if (x > maxX) maxX = x;
|
|
271
271
|
if (y < minY) minY = y;
|
|
@@ -276,19 +276,22 @@ function trimRectBounds(target, bounds) {
|
|
|
276
276
|
if (maxX === -1) {
|
|
277
277
|
target.w = 0;
|
|
278
278
|
target.h = 0;
|
|
279
|
-
target.
|
|
279
|
+
target.data = new Uint8Array(0);
|
|
280
280
|
return;
|
|
281
281
|
}
|
|
282
282
|
const finalW = maxX - minX + 1;
|
|
283
283
|
const finalH = maxY - minY + 1;
|
|
284
284
|
if (finalW !== intersectedW || finalH !== intersectedH) {
|
|
285
|
-
|
|
285
|
+
const newMaskBuffer = extractMaskBuffer(currentMaskBuffer, intersectedW, minX, minY, finalW, finalH);
|
|
286
286
|
target.x += minX;
|
|
287
287
|
target.y += minY;
|
|
288
288
|
target.w = finalW;
|
|
289
289
|
target.h = finalH;
|
|
290
|
+
target.data = newMaskBuffer;
|
|
290
291
|
} else {
|
|
291
|
-
target.
|
|
292
|
+
target.w = finalW;
|
|
293
|
+
target.h = finalH;
|
|
294
|
+
target.data = currentMaskBuffer;
|
|
292
295
|
}
|
|
293
296
|
}
|
|
294
297
|
}
|
|
@@ -398,17 +401,19 @@ function floodFillSelection(img, startX, startY, {
|
|
|
398
401
|
if (matchCount === 0) {
|
|
399
402
|
return null;
|
|
400
403
|
}
|
|
404
|
+
const w = maxX - minX + 1;
|
|
405
|
+
const h = maxY - minY + 1;
|
|
401
406
|
const selectionRect = {
|
|
402
407
|
x: minX,
|
|
403
408
|
y: minY,
|
|
404
|
-
w
|
|
405
|
-
h
|
|
406
|
-
|
|
407
|
-
|
|
409
|
+
w,
|
|
410
|
+
h,
|
|
411
|
+
data: new Uint8Array(w * h),
|
|
412
|
+
type: 1 /* BINARY */
|
|
408
413
|
};
|
|
409
414
|
const sw = selectionRect.w;
|
|
410
415
|
const sh = selectionRect.h;
|
|
411
|
-
const finalMask = selectionRect.
|
|
416
|
+
const finalMask = selectionRect.data;
|
|
412
417
|
for (let i = 0; i < matchCount; i++) {
|
|
413
418
|
const mx = matchX[i] - selectionRect.x;
|
|
414
419
|
const my = matchY[i] - selectionRect.y;
|
|
@@ -1483,16 +1488,7 @@ function toBlendModeIndexAndName(input) {
|
|
|
1483
1488
|
const num = Number(trimmed);
|
|
1484
1489
|
const isNumeric = trimmed !== "" && !Number.isNaN(num);
|
|
1485
1490
|
if (isNumeric && Number.isInteger(num)) {
|
|
1486
|
-
console.log({
|
|
1487
|
-
trimmed,
|
|
1488
|
-
num,
|
|
1489
|
-
isNumeric,
|
|
1490
|
-
isInt: Number.isInteger(num)
|
|
1491
|
-
});
|
|
1492
1491
|
const name = getKeyByValue(BaseBlendMode, num);
|
|
1493
|
-
console.log({
|
|
1494
|
-
name
|
|
1495
|
-
});
|
|
1496
1492
|
if (name === void 0) throw new Error(`Invalid index: ${num}`);
|
|
1497
1493
|
return {
|
|
1498
1494
|
blendIndex: num,
|
|
@@ -1866,7 +1862,6 @@ function applyAlphaMaskToPixelData(dst, mask, opts = {}) {
|
|
|
1866
1862
|
w: width = dst.width,
|
|
1867
1863
|
h: height = dst.height,
|
|
1868
1864
|
alpha: globalAlpha = 255,
|
|
1869
|
-
mw,
|
|
1870
1865
|
mx = 0,
|
|
1871
1866
|
my = 0,
|
|
1872
1867
|
invertMask = false
|
|
@@ -1888,15 +1883,14 @@ function applyAlphaMaskToPixelData(dst, mask, opts = {}) {
|
|
|
1888
1883
|
h = Math.min(h, dst.height - y);
|
|
1889
1884
|
if (w <= 0) return;
|
|
1890
1885
|
if (h <= 0) return;
|
|
1891
|
-
const mPitch =
|
|
1886
|
+
const mPitch = mask.w;
|
|
1892
1887
|
if (mPitch <= 0) return;
|
|
1893
|
-
const maskHeight = mask.length / mPitch | 0;
|
|
1894
1888
|
const startX = mx + (x - targetX);
|
|
1895
1889
|
const startY = my + (y - targetY);
|
|
1896
1890
|
const sX0 = Math.max(0, startX);
|
|
1897
1891
|
const sY0 = Math.max(0, startY);
|
|
1898
1892
|
const sX1 = Math.min(mPitch, startX + w);
|
|
1899
|
-
const sY1 = Math.min(
|
|
1893
|
+
const sY1 = Math.min(mask.h, startY + h);
|
|
1900
1894
|
const finalW = sX1 - sX0;
|
|
1901
1895
|
const finalH = sY1 - sY0;
|
|
1902
1896
|
if (finalW <= 0) return;
|
|
@@ -1907,11 +1901,12 @@ function applyAlphaMaskToPixelData(dst, mask, opts = {}) {
|
|
|
1907
1901
|
const dw = dst.width;
|
|
1908
1902
|
const dStride = dw - finalW;
|
|
1909
1903
|
const mStride = mPitch - finalW;
|
|
1904
|
+
const maskData = mask.data;
|
|
1910
1905
|
let dIdx = (y + yShift) * dw + (x + xShift);
|
|
1911
1906
|
let mIdx = sY0 * mPitch + sX0;
|
|
1912
1907
|
for (let iy = 0; iy < h; iy++) {
|
|
1913
1908
|
for (let ix = 0; ix < w; ix++) {
|
|
1914
|
-
const mVal =
|
|
1909
|
+
const mVal = maskData[mIdx];
|
|
1915
1910
|
const effectiveM = invertMask ? 255 - mVal : mVal;
|
|
1916
1911
|
let weight = 0;
|
|
1917
1912
|
if (effectiveM === 0) {
|
|
@@ -1971,13 +1966,12 @@ function applyBinaryMaskToPixelData(dst, mask, opts = {}) {
|
|
|
1971
1966
|
y: targetY = 0,
|
|
1972
1967
|
w: width = dst.width,
|
|
1973
1968
|
h: height = dst.height,
|
|
1974
|
-
alpha = 255,
|
|
1975
|
-
mw,
|
|
1969
|
+
alpha: globalAlpha = 255,
|
|
1976
1970
|
mx = 0,
|
|
1977
1971
|
my = 0,
|
|
1978
1972
|
invertMask = false
|
|
1979
1973
|
} = opts;
|
|
1980
|
-
if (
|
|
1974
|
+
if (globalAlpha === 0) return;
|
|
1981
1975
|
let x = targetX;
|
|
1982
1976
|
let y = targetY;
|
|
1983
1977
|
let w = width;
|
|
@@ -1994,15 +1988,14 @@ function applyBinaryMaskToPixelData(dst, mask, opts = {}) {
|
|
|
1994
1988
|
h = Math.min(h, dst.height - y);
|
|
1995
1989
|
if (w <= 0) return;
|
|
1996
1990
|
if (h <= 0) return;
|
|
1997
|
-
const mPitch =
|
|
1991
|
+
const mPitch = mask.w;
|
|
1998
1992
|
if (mPitch <= 0) return;
|
|
1999
|
-
const maskHeight = mask.length / mPitch | 0;
|
|
2000
1993
|
const startX = mx + (x - targetX);
|
|
2001
1994
|
const startY = my + (y - targetY);
|
|
2002
1995
|
const sX0 = Math.max(0, startX);
|
|
2003
1996
|
const sY0 = Math.max(0, startY);
|
|
2004
1997
|
const sX1 = Math.min(mPitch, startX + w);
|
|
2005
|
-
const sY1 = Math.min(
|
|
1998
|
+
const sY1 = Math.min(mask.h, startY + h);
|
|
2006
1999
|
const finalW = sX1 - sX0;
|
|
2007
2000
|
const finalH = sY1 - sY0;
|
|
2008
2001
|
if (finalW <= 0) return;
|
|
@@ -2013,19 +2006,20 @@ function applyBinaryMaskToPixelData(dst, mask, opts = {}) {
|
|
|
2013
2006
|
const dw = dst.width;
|
|
2014
2007
|
const dStride = dw - finalW;
|
|
2015
2008
|
const mStride = mPitch - finalW;
|
|
2009
|
+
const maskData = mask.data;
|
|
2016
2010
|
let dIdx = (y + yShift) * dw + (x + xShift);
|
|
2017
2011
|
let mIdx = sY0 * mPitch + sX0;
|
|
2018
2012
|
for (let iy = 0; iy < h; iy++) {
|
|
2019
2013
|
for (let ix = 0; ix < w; ix++) {
|
|
2020
|
-
const mVal =
|
|
2014
|
+
const mVal = maskData[mIdx];
|
|
2021
2015
|
const isMaskedOut = invertMask ? mVal !== 0 : mVal === 0;
|
|
2022
2016
|
if (isMaskedOut) {
|
|
2023
2017
|
dst32[dIdx] = (dst32[dIdx] & 16777215) >>> 0;
|
|
2024
|
-
} else if (
|
|
2018
|
+
} else if (globalAlpha !== 255) {
|
|
2025
2019
|
const d = dst32[dIdx];
|
|
2026
2020
|
const da = d >>> 24;
|
|
2027
2021
|
if (da !== 0) {
|
|
2028
|
-
const finalAlpha = da === 255 ?
|
|
2022
|
+
const finalAlpha = da === 255 ? globalAlpha : da * globalAlpha + 128 >> 8;
|
|
2029
2023
|
dst32[dIdx] = (d & 16777215 | finalAlpha << 24) >>> 0;
|
|
2030
2024
|
}
|
|
2031
2025
|
}
|
|
@@ -2088,144 +2082,42 @@ function getCircleBrushOrPencilBounds(centerX, centerY, brushSize, targetWidth,
|
|
|
2088
2082
|
return res;
|
|
2089
2083
|
}
|
|
2090
2084
|
|
|
2091
|
-
// src/PixelData/applyCircleBrushToPixelData.ts
|
|
2092
|
-
function applyCircleBrushToPixelData(target, color, centerX, centerY, brushSize, alpha = 255, fallOff, blendFn = sourceOverPerfect, bounds) {
|
|
2093
|
-
const targetWidth = target.width;
|
|
2094
|
-
const targetHeight = target.height;
|
|
2095
|
-
const b = bounds ?? getCircleBrushOrPencilBounds(centerX, centerY, brushSize, targetWidth, targetHeight);
|
|
2096
|
-
if (b.w <= 0 || b.h <= 0) return;
|
|
2097
|
-
const data32 = target.data32;
|
|
2098
|
-
const r = brushSize / 2;
|
|
2099
|
-
const rSqr = r * r;
|
|
2100
|
-
const invR = 1 / r;
|
|
2101
|
-
const centerOffset = brushSize % 2 === 0 ? 0.5 : 0;
|
|
2102
|
-
const endX = b.x + b.w;
|
|
2103
|
-
const endY = b.y + b.h;
|
|
2104
|
-
const fCenterX = Math.floor(centerX);
|
|
2105
|
-
const fCenterY = Math.floor(centerY);
|
|
2106
|
-
const baseSrcAlpha = color >>> 24;
|
|
2107
|
-
const colorRGB = color & 16777215;
|
|
2108
|
-
const isOpaque = alpha === 255;
|
|
2109
|
-
const isOverwrite = blendFn.isOverwrite;
|
|
2110
|
-
for (let cy = b.y; cy < endY; cy++) {
|
|
2111
|
-
const relY = cy - fCenterY + centerOffset;
|
|
2112
|
-
const dySqr = relY * relY;
|
|
2113
|
-
const rowOffset = cy * targetWidth;
|
|
2114
|
-
for (let cx = b.x; cx < endX; cx++) {
|
|
2115
|
-
const relX = cx - fCenterX + centerOffset;
|
|
2116
|
-
const dSqr = relX * relX + dySqr;
|
|
2117
|
-
if (dSqr <= rSqr) {
|
|
2118
|
-
const idx = rowOffset + cx;
|
|
2119
|
-
let weight = alpha;
|
|
2120
|
-
const strength = fallOff(1 - Math.sqrt(dSqr) * invR);
|
|
2121
|
-
const maskVal = strength * 255 | 0;
|
|
2122
|
-
if (maskVal === 0) continue;
|
|
2123
|
-
if (isOpaque) {
|
|
2124
|
-
weight = maskVal;
|
|
2125
|
-
} else if (maskVal !== 255) {
|
|
2126
|
-
weight = maskVal * alpha + 128 >> 8;
|
|
2127
|
-
}
|
|
2128
|
-
let finalCol = color;
|
|
2129
|
-
if (weight < 255) {
|
|
2130
|
-
const a = baseSrcAlpha * weight + 128 >> 8;
|
|
2131
|
-
if (a === 0 && !isOverwrite) continue;
|
|
2132
|
-
finalCol = (colorRGB | a << 24) >>> 0;
|
|
2133
|
-
}
|
|
2134
|
-
data32[idx] = blendFn(finalCol, data32[idx]);
|
|
2135
|
-
}
|
|
2136
|
-
}
|
|
2137
|
-
}
|
|
2138
|
-
}
|
|
2139
|
-
|
|
2140
|
-
// src/History/PixelMutator/mutatorApplyCircleBrush.ts
|
|
2141
|
-
var defaults3 = {
|
|
2142
|
-
applyCircleBrushToPixelData,
|
|
2143
|
-
getCircleBrushOrPencilBounds
|
|
2144
|
-
};
|
|
2145
|
-
var mutatorApplyCircleBrush = ((writer, deps = defaults3) => {
|
|
2146
|
-
const {
|
|
2147
|
-
applyCircleBrushToPixelData: applyCircleBrushToPixelData2 = defaults3.applyCircleBrushToPixelData,
|
|
2148
|
-
getCircleBrushOrPencilBounds: getCircleBrushOrPencilBounds2 = defaults3.getCircleBrushOrPencilBounds
|
|
2149
|
-
} = deps;
|
|
2150
|
-
const boundsOut = {
|
|
2151
|
-
x: 0,
|
|
2152
|
-
y: 0,
|
|
2153
|
-
w: 0,
|
|
2154
|
-
h: 0
|
|
2155
|
-
};
|
|
2156
|
-
return {
|
|
2157
|
-
applyCircleBrush(color, centerX, centerY, brushSize, alpha = 255, fallOff, blendFn) {
|
|
2158
|
-
const bounds = getCircleBrushOrPencilBounds2(centerX, centerY, brushSize, writer.target.width, writer.target.height, boundsOut);
|
|
2159
|
-
const {
|
|
2160
|
-
x,
|
|
2161
|
-
y,
|
|
2162
|
-
w,
|
|
2163
|
-
h
|
|
2164
|
-
} = bounds;
|
|
2165
|
-
writer.accumulator.storeRegionBeforeState(x, y, w, h);
|
|
2166
|
-
applyCircleBrushToPixelData2(writer.target, color, centerX, centerY, brushSize, alpha, fallOff, blendFn, bounds);
|
|
2167
|
-
}
|
|
2168
|
-
};
|
|
2169
|
-
});
|
|
2170
|
-
|
|
2171
|
-
// src/Algorithm/forEachLinePoint.ts
|
|
2172
|
-
function forEachLinePoint(x0, y0, x1, y1, callback) {
|
|
2173
|
-
const dx = x1 - x0;
|
|
2174
|
-
const dy = y1 - y0;
|
|
2175
|
-
const steps = Math.max(Math.abs(dx), Math.abs(dy));
|
|
2176
|
-
if (steps === 0) {
|
|
2177
|
-
callback(x0, y0);
|
|
2178
|
-
return;
|
|
2179
|
-
}
|
|
2180
|
-
const xInc = dx / steps;
|
|
2181
|
-
const yInc = dy / steps;
|
|
2182
|
-
let curX = x0;
|
|
2183
|
-
let curY = y0;
|
|
2184
|
-
for (let i = 0; i <= steps; i++) {
|
|
2185
|
-
callback(curX, curY);
|
|
2186
|
-
curX += xInc;
|
|
2187
|
-
curY += yInc;
|
|
2188
|
-
}
|
|
2189
|
-
}
|
|
2190
|
-
|
|
2191
2085
|
// src/PixelData/blendColorPixelDataAlphaMask.ts
|
|
2192
|
-
function blendColorPixelDataAlphaMask(dst, color, mask, opts) {
|
|
2193
|
-
const
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
invertMask = false
|
|
2204
|
-
} = opts;
|
|
2205
|
-
if (globalAlpha === 0 || !mask) return;
|
|
2086
|
+
function blendColorPixelDataAlphaMask(dst, color, mask, opts = {}) {
|
|
2087
|
+
const targetX = opts.x ?? 0;
|
|
2088
|
+
const targetY = opts.y ?? 0;
|
|
2089
|
+
const w = opts.w ?? mask.w;
|
|
2090
|
+
const h = opts.h ?? mask.h;
|
|
2091
|
+
const globalAlpha = opts.alpha ?? 255;
|
|
2092
|
+
const blendFn = opts.blendFn ?? sourceOverPerfect;
|
|
2093
|
+
const mx = opts.mx ?? 0;
|
|
2094
|
+
const my = opts.my ?? 0;
|
|
2095
|
+
const invertMask = opts.invertMask ?? false;
|
|
2096
|
+
if (globalAlpha === 0) return;
|
|
2206
2097
|
const baseSrcAlpha = color >>> 24;
|
|
2207
2098
|
const isOverwrite = blendFn.isOverwrite || false;
|
|
2208
2099
|
if (baseSrcAlpha === 0 && !isOverwrite) return;
|
|
2209
2100
|
let x = targetX;
|
|
2210
2101
|
let y = targetY;
|
|
2211
|
-
let
|
|
2212
|
-
let
|
|
2102
|
+
let actualW = w;
|
|
2103
|
+
let actualH = h;
|
|
2213
2104
|
if (x < 0) {
|
|
2214
|
-
|
|
2105
|
+
actualW += x;
|
|
2215
2106
|
x = 0;
|
|
2216
2107
|
}
|
|
2217
2108
|
if (y < 0) {
|
|
2218
|
-
|
|
2109
|
+
actualH += y;
|
|
2219
2110
|
y = 0;
|
|
2220
2111
|
}
|
|
2221
|
-
|
|
2222
|
-
|
|
2112
|
+
actualW = Math.min(actualW, dst.width - x);
|
|
2113
|
+
actualH = Math.min(actualH, dst.height - y);
|
|
2223
2114
|
if (actualW <= 0 || actualH <= 0) return;
|
|
2224
2115
|
const dx = x - targetX | 0;
|
|
2225
2116
|
const dy = y - targetY | 0;
|
|
2226
2117
|
const dst32 = dst.data32;
|
|
2227
2118
|
const dw = dst.width;
|
|
2228
|
-
const mPitch =
|
|
2119
|
+
const mPitch = mask.w;
|
|
2120
|
+
const maskData = mask.data;
|
|
2229
2121
|
let dIdx = y * dw + x | 0;
|
|
2230
2122
|
let mIdx = (my + dy) * mPitch + (mx + dx) | 0;
|
|
2231
2123
|
const dStride = dw - actualW | 0;
|
|
@@ -2234,7 +2126,7 @@ function blendColorPixelDataAlphaMask(dst, color, mask, opts) {
|
|
|
2234
2126
|
const colorRGB = color & 16777215;
|
|
2235
2127
|
for (let iy = 0; iy < actualH; iy++) {
|
|
2236
2128
|
for (let ix = 0; ix < actualW; ix++) {
|
|
2237
|
-
const mVal =
|
|
2129
|
+
const mVal = maskData[mIdx];
|
|
2238
2130
|
const effM = invertMask ? 255 - mVal : mVal;
|
|
2239
2131
|
if (effM === 0) {
|
|
2240
2132
|
dIdx++;
|
|
@@ -2271,6 +2163,155 @@ function blendColorPixelDataAlphaMask(dst, color, mask, opts) {
|
|
|
2271
2163
|
}
|
|
2272
2164
|
}
|
|
2273
2165
|
|
|
2166
|
+
// src/PixelData/blendColorPixelDataBinaryMask.ts
|
|
2167
|
+
function blendColorPixelDataBinaryMask(dst, color, mask, opts = {}) {
|
|
2168
|
+
const targetX = opts.x ?? 0;
|
|
2169
|
+
const targetY = opts.y ?? 0;
|
|
2170
|
+
let w = opts.w ?? mask.w;
|
|
2171
|
+
let h = opts.h ?? mask.h;
|
|
2172
|
+
const globalAlpha = opts.alpha ?? 255;
|
|
2173
|
+
const blendFn = opts.blendFn ?? sourceOverPerfect;
|
|
2174
|
+
const mx = opts.mx ?? 0;
|
|
2175
|
+
const my = opts.my ?? 0;
|
|
2176
|
+
const invertMask = opts.invertMask ?? false;
|
|
2177
|
+
if (globalAlpha === 0) return;
|
|
2178
|
+
const baseSrcAlpha = color >>> 24;
|
|
2179
|
+
const isOverwrite = blendFn.isOverwrite || false;
|
|
2180
|
+
if (baseSrcAlpha === 0 && !isOverwrite) return;
|
|
2181
|
+
let x = targetX;
|
|
2182
|
+
let y = targetY;
|
|
2183
|
+
if (x < 0) {
|
|
2184
|
+
w += x;
|
|
2185
|
+
x = 0;
|
|
2186
|
+
}
|
|
2187
|
+
if (y < 0) {
|
|
2188
|
+
h += y;
|
|
2189
|
+
y = 0;
|
|
2190
|
+
}
|
|
2191
|
+
const actualW = Math.min(w, dst.width - x);
|
|
2192
|
+
const actualH = Math.min(h, dst.height - y);
|
|
2193
|
+
if (actualW <= 0 || actualH <= 0) return;
|
|
2194
|
+
let baseColorWithGlobalAlpha = color;
|
|
2195
|
+
if (globalAlpha < 255) {
|
|
2196
|
+
const a = baseSrcAlpha * globalAlpha + 128 >> 8;
|
|
2197
|
+
if (a === 0 && !isOverwrite) return;
|
|
2198
|
+
baseColorWithGlobalAlpha = (color & 16777215 | a << 24) >>> 0;
|
|
2199
|
+
}
|
|
2200
|
+
const dx = x - targetX | 0;
|
|
2201
|
+
const dy = y - targetY | 0;
|
|
2202
|
+
const dst32 = dst.data32;
|
|
2203
|
+
const dw = dst.width;
|
|
2204
|
+
const mPitch = mask.w;
|
|
2205
|
+
const maskData = mask.data;
|
|
2206
|
+
let dIdx = y * dw + x | 0;
|
|
2207
|
+
let mIdx = (my + dy) * mPitch + (mx + dx) | 0;
|
|
2208
|
+
const dStride = dw - actualW | 0;
|
|
2209
|
+
const mStride = mPitch - actualW | 0;
|
|
2210
|
+
const skipVal = invertMask ? 1 : 0;
|
|
2211
|
+
for (let iy = 0; iy < actualH; iy++) {
|
|
2212
|
+
for (let ix = 0; ix < actualW; ix++) {
|
|
2213
|
+
if (maskData[mIdx] === skipVal) {
|
|
2214
|
+
dIdx++;
|
|
2215
|
+
mIdx++;
|
|
2216
|
+
continue;
|
|
2217
|
+
}
|
|
2218
|
+
dst32[dIdx] = blendFn(baseColorWithGlobalAlpha, dst32[dIdx]);
|
|
2219
|
+
dIdx++;
|
|
2220
|
+
mIdx++;
|
|
2221
|
+
}
|
|
2222
|
+
dIdx += dStride;
|
|
2223
|
+
mIdx += mStride;
|
|
2224
|
+
}
|
|
2225
|
+
}
|
|
2226
|
+
|
|
2227
|
+
// src/PixelData/applyCircleBrushToPixelData.ts
|
|
2228
|
+
function applyCircleBrushToPixelData(target, color, centerX, centerY, brush, alpha = 255, blendFn = sourceOverPerfect, scratchOptions = {}, bounds) {
|
|
2229
|
+
const b = bounds ?? getCircleBrushOrPencilBounds(centerX, centerY, brush.size, target.width, target.height);
|
|
2230
|
+
if (b.w <= 0 || b.h <= 0) return;
|
|
2231
|
+
const unclippedStartX = Math.floor(centerX + brush.minOffset);
|
|
2232
|
+
const unclippedStartY = Math.floor(centerY + brush.minOffset);
|
|
2233
|
+
const ix = Math.max(unclippedStartX, b.x);
|
|
2234
|
+
const iy = Math.max(unclippedStartY, b.y);
|
|
2235
|
+
const ir = Math.min(unclippedStartX + brush.w, b.x + b.w);
|
|
2236
|
+
const ib = Math.min(unclippedStartY + brush.h, b.y + b.h);
|
|
2237
|
+
const iw = ir - ix;
|
|
2238
|
+
const ih = ib - iy;
|
|
2239
|
+
if (iw <= 0 || ih <= 0) return;
|
|
2240
|
+
scratchOptions.x = ix;
|
|
2241
|
+
scratchOptions.y = iy;
|
|
2242
|
+
scratchOptions.w = iw;
|
|
2243
|
+
scratchOptions.h = ih;
|
|
2244
|
+
scratchOptions.mx = ix - unclippedStartX;
|
|
2245
|
+
scratchOptions.my = iy - unclippedStartY;
|
|
2246
|
+
scratchOptions.alpha = alpha;
|
|
2247
|
+
scratchOptions.blendFn = blendFn;
|
|
2248
|
+
if (brush.type === 0 /* ALPHA */) {
|
|
2249
|
+
blendColorPixelDataAlphaMask(target, color, brush, scratchOptions);
|
|
2250
|
+
}
|
|
2251
|
+
if (brush.type === 1 /* BINARY */) {
|
|
2252
|
+
blendColorPixelDataBinaryMask(target, color, brush, scratchOptions);
|
|
2253
|
+
}
|
|
2254
|
+
}
|
|
2255
|
+
|
|
2256
|
+
// src/History/PixelMutator/mutatorApplyCircleBrush.ts
|
|
2257
|
+
var defaults3 = {
|
|
2258
|
+
applyCircleBrushToPixelData,
|
|
2259
|
+
getCircleBrushOrPencilBounds
|
|
2260
|
+
};
|
|
2261
|
+
var mutatorApplyCircleBrush = ((writer, deps = defaults3) => {
|
|
2262
|
+
const {
|
|
2263
|
+
applyCircleBrushToPixelData: applyCircleBrushToPixelData2 = defaults3.applyCircleBrushToPixelData,
|
|
2264
|
+
getCircleBrushOrPencilBounds: getCircleBrushOrPencilBounds2 = defaults3.getCircleBrushOrPencilBounds
|
|
2265
|
+
} = deps;
|
|
2266
|
+
const boundsOut = {
|
|
2267
|
+
x: 0,
|
|
2268
|
+
y: 0,
|
|
2269
|
+
w: 0,
|
|
2270
|
+
h: 0
|
|
2271
|
+
};
|
|
2272
|
+
const blendColorPixelOptions = {
|
|
2273
|
+
alpha: 255,
|
|
2274
|
+
blendFn: sourceOverPerfect,
|
|
2275
|
+
x: 0,
|
|
2276
|
+
y: 0,
|
|
2277
|
+
w: 0,
|
|
2278
|
+
h: 0
|
|
2279
|
+
};
|
|
2280
|
+
return {
|
|
2281
|
+
applyCircleBrush(color, centerX, centerY, brush, alpha = 255, blendFn) {
|
|
2282
|
+
const bounds = getCircleBrushOrPencilBounds2(centerX, centerY, brush.size, writer.target.width, writer.target.height, boundsOut);
|
|
2283
|
+
const {
|
|
2284
|
+
x,
|
|
2285
|
+
y,
|
|
2286
|
+
w,
|
|
2287
|
+
h
|
|
2288
|
+
} = bounds;
|
|
2289
|
+
writer.accumulator.storeRegionBeforeState(x, y, w, h);
|
|
2290
|
+
applyCircleBrushToPixelData2(writer.target, color, centerX, centerY, brush, alpha, blendFn, blendColorPixelOptions, bounds);
|
|
2291
|
+
}
|
|
2292
|
+
};
|
|
2293
|
+
});
|
|
2294
|
+
|
|
2295
|
+
// src/Algorithm/forEachLinePoint.ts
|
|
2296
|
+
function forEachLinePoint(x0, y0, x1, y1, callback) {
|
|
2297
|
+
const dx = x1 - x0;
|
|
2298
|
+
const dy = y1 - y0;
|
|
2299
|
+
const steps = Math.max(Math.abs(dx), Math.abs(dy));
|
|
2300
|
+
if (steps === 0) {
|
|
2301
|
+
callback(x0, y0);
|
|
2302
|
+
return;
|
|
2303
|
+
}
|
|
2304
|
+
const xInc = dx / steps;
|
|
2305
|
+
const yInc = dy / steps;
|
|
2306
|
+
let curX = x0;
|
|
2307
|
+
let curY = y0;
|
|
2308
|
+
for (let i = 0; i <= steps; i++) {
|
|
2309
|
+
callback(curX, curY);
|
|
2310
|
+
curX += xInc;
|
|
2311
|
+
curY += yInc;
|
|
2312
|
+
}
|
|
2313
|
+
}
|
|
2314
|
+
|
|
2274
2315
|
// src/Rect/getCircleBrushOrPencilStrokeBounds.ts
|
|
2275
2316
|
function getCircleBrushOrPencilStrokeBounds(x0, y0, x1, y1, brushSize, result) {
|
|
2276
2317
|
const r = Math.ceil(brushSize / 2);
|
|
@@ -2319,8 +2360,15 @@ var mutatorApplyCircleBrushStroke = ((writer, deps = defaults4) => {
|
|
|
2319
2360
|
w: 0,
|
|
2320
2361
|
h: 0
|
|
2321
2362
|
};
|
|
2363
|
+
const mask = {
|
|
2364
|
+
type: 0 /* ALPHA */,
|
|
2365
|
+
data: null,
|
|
2366
|
+
w: 0,
|
|
2367
|
+
h: 0
|
|
2368
|
+
};
|
|
2322
2369
|
return {
|
|
2323
|
-
applyCircleBrushStroke(color, x0, y0, x1, y1,
|
|
2370
|
+
applyCircleBrushStroke(color, x0, y0, x1, y1, brush, alpha = 255, blendFn = sourceOverPerfect) {
|
|
2371
|
+
const brushSize = brush.size;
|
|
2324
2372
|
const {
|
|
2325
2373
|
x: bx,
|
|
2326
2374
|
y: by,
|
|
@@ -2328,11 +2376,12 @@ var mutatorApplyCircleBrushStroke = ((writer, deps = defaults4) => {
|
|
|
2328
2376
|
h: bh
|
|
2329
2377
|
} = getCircleBrushOrPencilStrokeBounds2(x0, y0, x1, y1, brushSize, strokeBoundsOut);
|
|
2330
2378
|
if (bw <= 0 || bh <= 0) return;
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
const
|
|
2335
|
-
const
|
|
2379
|
+
mask.data = new Uint8Array(bw * bh);
|
|
2380
|
+
mask.w = bw;
|
|
2381
|
+
mask.h = bh;
|
|
2382
|
+
const maskData = mask.data;
|
|
2383
|
+
const brushData = brush.data;
|
|
2384
|
+
const minOffset = brush.minOffset;
|
|
2336
2385
|
const targetWidth = writer.target.width;
|
|
2337
2386
|
const targetHeight = writer.target.height;
|
|
2338
2387
|
forEachLinePoint2(x0, y0, x1, y1, (px, py) => {
|
|
@@ -2347,21 +2396,20 @@ var mutatorApplyCircleBrushStroke = ((writer, deps = defaults4) => {
|
|
|
2347
2396
|
const startY = Math.max(by, cby);
|
|
2348
2397
|
const endX = Math.min(bx + bw, cbx + cbw);
|
|
2349
2398
|
const endY = Math.min(by + bh, cby + cbh);
|
|
2350
|
-
const
|
|
2351
|
-
const
|
|
2399
|
+
const unclippedStartX = Math.floor(px + minOffset);
|
|
2400
|
+
const unclippedStartY = Math.floor(py + minOffset);
|
|
2352
2401
|
for (let my = startY; my < endY; my++) {
|
|
2353
|
-
const
|
|
2354
|
-
const
|
|
2355
|
-
const
|
|
2402
|
+
const strokeMaskY = my - by;
|
|
2403
|
+
const strokeMaskRowOffset = strokeMaskY * bw;
|
|
2404
|
+
const brushY = my - unclippedStartY;
|
|
2405
|
+
const brushRowOffset = brushY * brushSize;
|
|
2356
2406
|
for (let mx = startX; mx < endX; mx++) {
|
|
2357
|
-
const
|
|
2358
|
-
const
|
|
2359
|
-
if (
|
|
2360
|
-
const
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
if (intensity > mask[maskIdx]) {
|
|
2364
|
-
mask[maskIdx] = intensity;
|
|
2407
|
+
const brushX = mx - unclippedStartX;
|
|
2408
|
+
const brushVal = brushData[brushRowOffset + brushX];
|
|
2409
|
+
if (brushVal > 0) {
|
|
2410
|
+
const strokeMaskIdx = strokeMaskRowOffset + (mx - bx);
|
|
2411
|
+
if (brushVal > maskData[strokeMaskIdx]) {
|
|
2412
|
+
maskData[strokeMaskIdx] = brushVal;
|
|
2365
2413
|
}
|
|
2366
2414
|
}
|
|
2367
2415
|
}
|
|
@@ -2378,84 +2426,50 @@ var mutatorApplyCircleBrushStroke = ((writer, deps = defaults4) => {
|
|
|
2378
2426
|
};
|
|
2379
2427
|
});
|
|
2380
2428
|
|
|
2381
|
-
// src/
|
|
2382
|
-
|
|
2429
|
+
// src/History/PixelMutator/mutatorApplyCirclePencil.ts
|
|
2430
|
+
var defaults5 = {
|
|
2431
|
+
applyCircleBrushToPixelData,
|
|
2432
|
+
getCircleBrushOrPencilBounds
|
|
2433
|
+
};
|
|
2434
|
+
var mutatorApplyCirclePencil = ((writer, deps = defaults5) => {
|
|
2383
2435
|
const {
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
w += x;
|
|
2405
|
-
x = 0;
|
|
2406
|
-
}
|
|
2407
|
-
if (y < 0) {
|
|
2408
|
-
h += y;
|
|
2409
|
-
y = 0;
|
|
2410
|
-
}
|
|
2411
|
-
const actualW = Math.min(w, dst.width - x);
|
|
2412
|
-
const actualH = Math.min(h, dst.height - y);
|
|
2413
|
-
if (actualW <= 0 || actualH <= 0) return;
|
|
2414
|
-
let baseColorWithGlobalAlpha = color;
|
|
2415
|
-
if (globalAlpha < 255) {
|
|
2416
|
-
const a = baseSrcAlpha * globalAlpha + 128 >> 8;
|
|
2417
|
-
if (a === 0 && !isOverwrite) return;
|
|
2418
|
-
baseColorWithGlobalAlpha = (color & 16777215 | a << 24) >>> 0;
|
|
2419
|
-
}
|
|
2420
|
-
const dx = x - targetX | 0;
|
|
2421
|
-
const dy = y - targetY | 0;
|
|
2422
|
-
const dst32 = dst.data32;
|
|
2423
|
-
const dw = dst.width;
|
|
2424
|
-
const mPitch = mw;
|
|
2425
|
-
let dIdx = y * dw + x | 0;
|
|
2426
|
-
let mIdx = (my + dy) * mPitch + (mx + dx) | 0;
|
|
2427
|
-
const dStride = dw - actualW | 0;
|
|
2428
|
-
const mStride = mPitch - actualW | 0;
|
|
2429
|
-
const skipVal = invertMask ? 1 : 0;
|
|
2430
|
-
for (let iy = 0; iy < actualH; iy++) {
|
|
2431
|
-
for (let ix = 0; ix < actualW; ix++) {
|
|
2432
|
-
if (mask[mIdx] === skipVal) {
|
|
2433
|
-
dIdx++;
|
|
2434
|
-
mIdx++;
|
|
2435
|
-
continue;
|
|
2436
|
-
}
|
|
2437
|
-
dst32[dIdx] = blendFn(baseColorWithGlobalAlpha, dst32[dIdx]);
|
|
2438
|
-
dIdx++;
|
|
2439
|
-
mIdx++;
|
|
2436
|
+
applyCircleBrushToPixelData: applyCircleBrushToPixelData2 = defaults5.applyCircleBrushToPixelData,
|
|
2437
|
+
getCircleBrushOrPencilBounds: getCircleBrushOrPencilBounds2 = defaults5.getCircleBrushOrPencilBounds
|
|
2438
|
+
} = deps;
|
|
2439
|
+
const boundsOut = {
|
|
2440
|
+
x: 0,
|
|
2441
|
+
y: 0,
|
|
2442
|
+
w: 0,
|
|
2443
|
+
h: 0
|
|
2444
|
+
};
|
|
2445
|
+
return {
|
|
2446
|
+
applyCirclePencil(color, centerX, centerY, brush, alpha = 255, blendFn) {
|
|
2447
|
+
const bounds = getCircleBrushOrPencilBounds2(centerX, centerY, brush.size, writer.target.width, writer.target.height, boundsOut);
|
|
2448
|
+
const {
|
|
2449
|
+
x,
|
|
2450
|
+
y,
|
|
2451
|
+
w,
|
|
2452
|
+
h
|
|
2453
|
+
} = bounds;
|
|
2454
|
+
writer.accumulator.storeRegionBeforeState(x, y, w, h);
|
|
2455
|
+
applyCircleBrushToPixelData2(writer.target, color, centerX, centerY, brush, alpha, blendFn, bounds);
|
|
2440
2456
|
}
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
}
|
|
2444
|
-
}
|
|
2457
|
+
};
|
|
2458
|
+
});
|
|
2445
2459
|
|
|
2446
2460
|
// src/History/PixelMutator/mutatorApplyCirclePencilStroke.ts
|
|
2447
|
-
var
|
|
2461
|
+
var defaults6 = {
|
|
2448
2462
|
forEachLinePoint,
|
|
2449
2463
|
blendColorPixelDataBinaryMask,
|
|
2450
2464
|
getCircleBrushOrPencilBounds,
|
|
2451
2465
|
getCircleBrushOrPencilStrokeBounds
|
|
2452
2466
|
};
|
|
2453
|
-
var mutatorApplyCirclePencilStroke = ((writer, deps =
|
|
2467
|
+
var mutatorApplyCirclePencilStroke = ((writer, deps = defaults6) => {
|
|
2454
2468
|
const {
|
|
2455
|
-
forEachLinePoint: forEachLinePoint2 =
|
|
2456
|
-
blendColorPixelDataBinaryMask: blendColorPixelDataBinaryMask2 =
|
|
2457
|
-
getCircleBrushOrPencilStrokeBounds: getCircleBrushOrPencilStrokeBounds2 =
|
|
2458
|
-
getCircleBrushOrPencilBounds: getCircleBrushOrPencilBounds2 =
|
|
2469
|
+
forEachLinePoint: forEachLinePoint2 = defaults6.forEachLinePoint,
|
|
2470
|
+
blendColorPixelDataBinaryMask: blendColorPixelDataBinaryMask2 = defaults6.blendColorPixelDataBinaryMask,
|
|
2471
|
+
getCircleBrushOrPencilStrokeBounds: getCircleBrushOrPencilStrokeBounds2 = defaults6.getCircleBrushOrPencilStrokeBounds,
|
|
2472
|
+
getCircleBrushOrPencilBounds: getCircleBrushOrPencilBounds2 = defaults6.getCircleBrushOrPencilBounds
|
|
2459
2473
|
} = deps;
|
|
2460
2474
|
const strokeBoundsOut = {
|
|
2461
2475
|
x: 0,
|
|
@@ -2477,19 +2491,25 @@ var mutatorApplyCirclePencilStroke = ((writer, deps = defaults5) => {
|
|
|
2477
2491
|
w: 0,
|
|
2478
2492
|
h: 0
|
|
2479
2493
|
};
|
|
2494
|
+
const mask = {
|
|
2495
|
+
type: 1 /* BINARY */,
|
|
2496
|
+
data: null,
|
|
2497
|
+
w: 0,
|
|
2498
|
+
h: 0
|
|
2499
|
+
};
|
|
2480
2500
|
return {
|
|
2481
|
-
applyCirclePencilStroke(color, x0, y0, x1, y1,
|
|
2501
|
+
applyCirclePencilStroke(color, x0, y0, x1, y1, brush, alpha = 255, blendFn = sourceOverPerfect) {
|
|
2482
2502
|
const {
|
|
2483
2503
|
x: bx,
|
|
2484
2504
|
y: by,
|
|
2485
2505
|
w: bw,
|
|
2486
2506
|
h: bh
|
|
2487
|
-
} = getCircleBrushOrPencilStrokeBounds2(x0, y0, x1, y1,
|
|
2507
|
+
} = getCircleBrushOrPencilStrokeBounds2(x0, y0, x1, y1, brush.size, strokeBoundsOut);
|
|
2488
2508
|
if (bw <= 0 || bh <= 0) return;
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
const
|
|
2509
|
+
mask.data = new Uint8Array(bw * bh);
|
|
2510
|
+
mask.w = bw;
|
|
2511
|
+
mask.h = bh;
|
|
2512
|
+
const maskData = mask.data;
|
|
2493
2513
|
const targetWidth = writer.target.width;
|
|
2494
2514
|
const targetHeight = writer.target.height;
|
|
2495
2515
|
forEachLinePoint2(x0, y0, x1, y1, (px, py) => {
|
|
@@ -2498,24 +2518,24 @@ var mutatorApplyCirclePencilStroke = ((writer, deps = defaults5) => {
|
|
|
2498
2518
|
y: cby,
|
|
2499
2519
|
w: cbw,
|
|
2500
2520
|
h: cbh
|
|
2501
|
-
} = getCircleBrushOrPencilBounds2(px, py,
|
|
2521
|
+
} = getCircleBrushOrPencilBounds2(px, py, brush.size, targetWidth, targetHeight, circlePencilBounds);
|
|
2502
2522
|
writer.accumulator.storeRegionBeforeState(cbx, cby, cbw, cbh);
|
|
2503
|
-
const
|
|
2504
|
-
const
|
|
2505
|
-
const
|
|
2506
|
-
const
|
|
2507
|
-
const
|
|
2508
|
-
const
|
|
2523
|
+
const unclippedStartX = Math.floor(px + brush.minOffset);
|
|
2524
|
+
const unclippedStartY = Math.floor(py + brush.minOffset);
|
|
2525
|
+
const startX = Math.max(bx, unclippedStartX);
|
|
2526
|
+
const startY = Math.max(by, unclippedStartY);
|
|
2527
|
+
const endX = Math.min(bx + bw, unclippedStartX + brush.w);
|
|
2528
|
+
const endY = Math.min(by + bh, unclippedStartY + brush.h);
|
|
2509
2529
|
for (let my = startY; my < endY; my++) {
|
|
2510
|
-
const
|
|
2511
|
-
const dySqr = dy * dy;
|
|
2530
|
+
const brushY = my - unclippedStartY;
|
|
2512
2531
|
const maskRowOffset = (my - by) * bw;
|
|
2532
|
+
const brushRowOffset = brushY * brush.w;
|
|
2513
2533
|
for (let mx = startX; mx < endX; mx++) {
|
|
2514
|
-
const
|
|
2515
|
-
const
|
|
2516
|
-
if (
|
|
2534
|
+
const brushX = mx - unclippedStartX;
|
|
2535
|
+
const brushAlpha = brush.data[brushRowOffset + brushX];
|
|
2536
|
+
if (brushAlpha > 0) {
|
|
2517
2537
|
const maskIdx = maskRowOffset + (mx - bx);
|
|
2518
|
-
|
|
2538
|
+
maskData[maskIdx] = brushAlpha;
|
|
2519
2539
|
}
|
|
2520
2540
|
}
|
|
2521
2541
|
}
|
|
@@ -2603,14 +2623,14 @@ function applyRectBrushToPixelData(target, color, centerX, centerY, brushWidth,
|
|
|
2603
2623
|
}
|
|
2604
2624
|
|
|
2605
2625
|
// src/History/PixelMutator/mutatorApplyRectBrush.ts
|
|
2606
|
-
var
|
|
2626
|
+
var defaults7 = {
|
|
2607
2627
|
applyRectBrushToPixelData,
|
|
2608
2628
|
getRectBrushOrPencilBounds
|
|
2609
2629
|
};
|
|
2610
|
-
var mutatorApplyRectBrush = ((writer, deps =
|
|
2630
|
+
var mutatorApplyRectBrush = ((writer, deps = defaults7) => {
|
|
2611
2631
|
const {
|
|
2612
|
-
applyRectBrushToPixelData: applyRectBrushToPixelData2 =
|
|
2613
|
-
getRectBrushOrPencilBounds: getRectBrushOrPencilBounds2 =
|
|
2632
|
+
applyRectBrushToPixelData: applyRectBrushToPixelData2 = defaults7.applyRectBrushToPixelData,
|
|
2633
|
+
getRectBrushOrPencilBounds: getRectBrushOrPencilBounds2 = defaults7.getRectBrushOrPencilBounds
|
|
2614
2634
|
} = deps;
|
|
2615
2635
|
const boundsOut = {
|
|
2616
2636
|
x: 0,
|
|
@@ -2649,18 +2669,18 @@ function getRectBrushOrPencilStrokeBounds(x0, y0, x1, y1, brushWidth, brushHeigh
|
|
|
2649
2669
|
}
|
|
2650
2670
|
|
|
2651
2671
|
// src/History/PixelMutator/mutatorApplyRectBrushStroke.ts
|
|
2652
|
-
var
|
|
2672
|
+
var defaults8 = {
|
|
2653
2673
|
forEachLinePoint,
|
|
2654
2674
|
blendColorPixelDataAlphaMask,
|
|
2655
2675
|
getRectBrushOrPencilBounds,
|
|
2656
2676
|
getRectBrushOrPencilStrokeBounds
|
|
2657
2677
|
};
|
|
2658
|
-
var mutatorApplyRectBrushStroke = ((writer, deps =
|
|
2678
|
+
var mutatorApplyRectBrushStroke = ((writer, deps = defaults8) => {
|
|
2659
2679
|
const {
|
|
2660
|
-
forEachLinePoint: forEachLinePoint2 =
|
|
2661
|
-
blendColorPixelDataAlphaMask: blendColorPixelDataAlphaMask2 =
|
|
2662
|
-
getRectBrushOrPencilBounds: getRectBrushOrPencilBounds2 =
|
|
2663
|
-
getRectBrushOrPencilStrokeBounds: getRectBrushOrPencilStrokeBounds2 =
|
|
2680
|
+
forEachLinePoint: forEachLinePoint2 = defaults8.forEachLinePoint,
|
|
2681
|
+
blendColorPixelDataAlphaMask: blendColorPixelDataAlphaMask2 = defaults8.blendColorPixelDataAlphaMask,
|
|
2682
|
+
getRectBrushOrPencilBounds: getRectBrushOrPencilBounds2 = defaults8.getRectBrushOrPencilBounds,
|
|
2683
|
+
getRectBrushOrPencilStrokeBounds: getRectBrushOrPencilStrokeBounds2 = defaults8.getRectBrushOrPencilStrokeBounds
|
|
2664
2684
|
} = deps;
|
|
2665
2685
|
const strokeBoundsOut = {
|
|
2666
2686
|
x: 0,
|
|
@@ -2682,6 +2702,12 @@ var mutatorApplyRectBrushStroke = ((writer, deps = defaults7) => {
|
|
|
2682
2702
|
w: 0,
|
|
2683
2703
|
h: 0
|
|
2684
2704
|
};
|
|
2705
|
+
const mask = {
|
|
2706
|
+
type: 0 /* ALPHA */,
|
|
2707
|
+
data: null,
|
|
2708
|
+
w: 0,
|
|
2709
|
+
h: 0
|
|
2710
|
+
};
|
|
2685
2711
|
return {
|
|
2686
2712
|
applyRectBrushStroke(color, x0, y0, x1, y1, brushWidth, brushHeight, alpha = 255, fallOff, blendFn = sourceOverPerfect) {
|
|
2687
2713
|
const {
|
|
@@ -2691,7 +2717,10 @@ var mutatorApplyRectBrushStroke = ((writer, deps = defaults7) => {
|
|
|
2691
2717
|
h: bh
|
|
2692
2718
|
} = getRectBrushOrPencilStrokeBounds2(x0, y0, x1, y1, brushWidth, brushHeight, strokeBoundsOut);
|
|
2693
2719
|
if (bw <= 0 || bh <= 0) return;
|
|
2694
|
-
|
|
2720
|
+
mask.data = new Uint8Array(bw * bh);
|
|
2721
|
+
mask.w = bw;
|
|
2722
|
+
mask.h = bh;
|
|
2723
|
+
const maskData = mask.data;
|
|
2695
2724
|
const halfW = brushWidth / 2;
|
|
2696
2725
|
const halfH = brushHeight / 2;
|
|
2697
2726
|
const invHalfW = 1 / halfW;
|
|
@@ -2724,8 +2753,8 @@ var mutatorApplyRectBrushStroke = ((writer, deps = defaults7) => {
|
|
|
2724
2753
|
const strength = fallOff(dist);
|
|
2725
2754
|
if (strength > 0) {
|
|
2726
2755
|
const intensity = strength * 255 | 0;
|
|
2727
|
-
if (intensity >
|
|
2728
|
-
|
|
2756
|
+
if (intensity > maskData[maskIdx]) {
|
|
2757
|
+
maskData[maskIdx] = intensity;
|
|
2729
2758
|
}
|
|
2730
2759
|
}
|
|
2731
2760
|
}
|
|
@@ -2743,16 +2772,16 @@ var mutatorApplyRectBrushStroke = ((writer, deps = defaults7) => {
|
|
|
2743
2772
|
});
|
|
2744
2773
|
|
|
2745
2774
|
// src/History/PixelMutator/mutatorApplyRectPencil.ts
|
|
2746
|
-
var
|
|
2775
|
+
var defaults9 = {
|
|
2747
2776
|
applyRectBrushToPixelData,
|
|
2748
2777
|
getRectBrushOrPencilBounds,
|
|
2749
2778
|
fallOff: () => 1
|
|
2750
2779
|
};
|
|
2751
|
-
var mutatorApplyRectPencil = ((writer, deps =
|
|
2780
|
+
var mutatorApplyRectPencil = ((writer, deps = defaults9) => {
|
|
2752
2781
|
const {
|
|
2753
|
-
applyRectBrushToPixelData: applyRectBrushToPixelData2 =
|
|
2754
|
-
getRectBrushOrPencilBounds: getRectBrushOrPencilBounds2 =
|
|
2755
|
-
fallOff =
|
|
2782
|
+
applyRectBrushToPixelData: applyRectBrushToPixelData2 = defaults9.applyRectBrushToPixelData,
|
|
2783
|
+
getRectBrushOrPencilBounds: getRectBrushOrPencilBounds2 = defaults9.getRectBrushOrPencilBounds,
|
|
2784
|
+
fallOff = defaults9.fallOff
|
|
2756
2785
|
} = deps;
|
|
2757
2786
|
const boundsOut = {
|
|
2758
2787
|
x: 0,
|
|
@@ -2776,18 +2805,18 @@ var mutatorApplyRectPencil = ((writer, deps = defaults8) => {
|
|
|
2776
2805
|
});
|
|
2777
2806
|
|
|
2778
2807
|
// src/History/PixelMutator/mutatorApplyRectPencilStroke.ts
|
|
2779
|
-
var
|
|
2808
|
+
var defaults10 = {
|
|
2780
2809
|
forEachLinePoint,
|
|
2781
2810
|
getRectBrushOrPencilBounds,
|
|
2782
2811
|
getRectBrushOrPencilStrokeBounds,
|
|
2783
2812
|
blendColorPixelDataBinaryMask
|
|
2784
2813
|
};
|
|
2785
|
-
var mutatorApplyRectPencilStroke = ((writer, deps =
|
|
2814
|
+
var mutatorApplyRectPencilStroke = ((writer, deps = defaults10) => {
|
|
2786
2815
|
const {
|
|
2787
|
-
forEachLinePoint: forEachLinePoint2 =
|
|
2788
|
-
blendColorPixelDataBinaryMask: blendColorPixelDataBinaryMask2 =
|
|
2789
|
-
getRectBrushOrPencilBounds: getRectBrushOrPencilBounds2 =
|
|
2790
|
-
getRectBrushOrPencilStrokeBounds: getRectBrushOrPencilStrokeBounds2 =
|
|
2816
|
+
forEachLinePoint: forEachLinePoint2 = defaults10.forEachLinePoint,
|
|
2817
|
+
blendColorPixelDataBinaryMask: blendColorPixelDataBinaryMask2 = defaults10.blendColorPixelDataBinaryMask,
|
|
2818
|
+
getRectBrushOrPencilBounds: getRectBrushOrPencilBounds2 = defaults10.getRectBrushOrPencilBounds,
|
|
2819
|
+
getRectBrushOrPencilStrokeBounds: getRectBrushOrPencilStrokeBounds2 = defaults10.getRectBrushOrPencilStrokeBounds
|
|
2791
2820
|
} = deps;
|
|
2792
2821
|
const strokeBoundsOut = {
|
|
2793
2822
|
x: 0,
|
|
@@ -2809,6 +2838,12 @@ var mutatorApplyRectPencilStroke = ((writer, deps = defaults9) => {
|
|
|
2809
2838
|
w: 0,
|
|
2810
2839
|
h: 0
|
|
2811
2840
|
};
|
|
2841
|
+
const mask = {
|
|
2842
|
+
type: 1 /* BINARY */,
|
|
2843
|
+
data: null,
|
|
2844
|
+
w: 0,
|
|
2845
|
+
h: 0
|
|
2846
|
+
};
|
|
2812
2847
|
return {
|
|
2813
2848
|
applyRectPencilStroke(color, x0, y0, x1, y1, brushWidth, brushHeight, alpha = 255, blendFn = sourceOverPerfect) {
|
|
2814
2849
|
const {
|
|
@@ -2818,7 +2853,10 @@ var mutatorApplyRectPencilStroke = ((writer, deps = defaults9) => {
|
|
|
2818
2853
|
h: bh
|
|
2819
2854
|
} = getRectBrushOrPencilStrokeBounds2(x0, y0, x1, y1, brushWidth, brushHeight, strokeBoundsOut);
|
|
2820
2855
|
if (bw <= 0 || bh <= 0) return;
|
|
2821
|
-
|
|
2856
|
+
mask.data = new Uint8Array(bw * bh);
|
|
2857
|
+
mask.w = bw;
|
|
2858
|
+
mask.h = bh;
|
|
2859
|
+
const maskData = mask.data;
|
|
2822
2860
|
const halfW = brushWidth / 2;
|
|
2823
2861
|
const halfH = brushHeight / 2;
|
|
2824
2862
|
const centerOffset = brushWidth % 2 === 0 ? 0.5 : 0;
|
|
@@ -2845,7 +2883,7 @@ var mutatorApplyRectPencilStroke = ((writer, deps = defaults9) => {
|
|
|
2845
2883
|
const dx = Math.abs(mx - fPx + centerOffset);
|
|
2846
2884
|
const maskIdx = maskRowOffset + (mx - bx);
|
|
2847
2885
|
if (dx <= halfW && dy <= halfH) {
|
|
2848
|
-
|
|
2886
|
+
maskData[maskIdx] = 1;
|
|
2849
2887
|
}
|
|
2850
2888
|
}
|
|
2851
2889
|
}
|
|
@@ -2907,12 +2945,12 @@ function blendColorPixelData(dst, color, opts = {}) {
|
|
|
2907
2945
|
}
|
|
2908
2946
|
|
|
2909
2947
|
// src/History/PixelMutator/mutatorBlendColor.ts
|
|
2910
|
-
var
|
|
2948
|
+
var defaults11 = {
|
|
2911
2949
|
blendColorPixelData
|
|
2912
2950
|
};
|
|
2913
|
-
var mutatorBlendColor = ((writer, deps =
|
|
2951
|
+
var mutatorBlendColor = ((writer, deps = defaults11) => {
|
|
2914
2952
|
const {
|
|
2915
|
-
blendColorPixelData: blendColorPixelData2 =
|
|
2953
|
+
blendColorPixelData: blendColorPixelData2 = defaults11.blendColorPixelData
|
|
2916
2954
|
} = deps;
|
|
2917
2955
|
return {
|
|
2918
2956
|
blendColor(color, opts = {}) {
|
|
@@ -2951,7 +2989,7 @@ function mutatorBlendPixel(writer) {
|
|
|
2951
2989
|
}
|
|
2952
2990
|
|
|
2953
2991
|
// src/PixelData/blendPixelData.ts
|
|
2954
|
-
function blendPixelData(dst, src, opts) {
|
|
2992
|
+
function blendPixelData(dst, src, opts = {}) {
|
|
2955
2993
|
const {
|
|
2956
2994
|
x: targetX = 0,
|
|
2957
2995
|
y: targetY = 0,
|
|
@@ -3033,15 +3071,15 @@ function blendPixelData(dst, src, opts) {
|
|
|
3033
3071
|
}
|
|
3034
3072
|
|
|
3035
3073
|
// src/History/PixelMutator/mutatorBlendPixelData.ts
|
|
3036
|
-
var
|
|
3074
|
+
var defaults12 = {
|
|
3037
3075
|
blendPixelData
|
|
3038
3076
|
};
|
|
3039
|
-
var mutatorBlendPixelData = ((writer, deps =
|
|
3077
|
+
var mutatorBlendPixelData = ((writer, deps = defaults12) => {
|
|
3040
3078
|
const {
|
|
3041
|
-
blendPixelData: blendPixelData2 =
|
|
3079
|
+
blendPixelData: blendPixelData2 = defaults12.blendPixelData
|
|
3042
3080
|
} = deps;
|
|
3043
3081
|
return {
|
|
3044
|
-
blendPixelData(src, opts) {
|
|
3082
|
+
blendPixelData(src, opts = {}) {
|
|
3045
3083
|
const {
|
|
3046
3084
|
x = 0,
|
|
3047
3085
|
y = 0,
|
|
@@ -3054,143 +3092,430 @@ var mutatorBlendPixelData = ((writer, deps = defaults11) => {
|
|
|
3054
3092
|
};
|
|
3055
3093
|
});
|
|
3056
3094
|
|
|
3057
|
-
// src/PixelData/
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
}
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3095
|
+
// src/PixelData/blendPixelDataAlphaMask.ts
|
|
3096
|
+
function blendPixelDataAlphaMask(dst, src, alphaMask, opts = {}) {
|
|
3097
|
+
const {
|
|
3098
|
+
x: targetX = 0,
|
|
3099
|
+
y: targetY = 0,
|
|
3100
|
+
sx: sourceX = 0,
|
|
3101
|
+
sy: sourceY = 0,
|
|
3102
|
+
w: width = src.width,
|
|
3103
|
+
h: height = src.height,
|
|
3104
|
+
alpha: globalAlpha = 255,
|
|
3105
|
+
blendFn = sourceOverPerfect,
|
|
3106
|
+
mx = 0,
|
|
3107
|
+
my = 0,
|
|
3108
|
+
invertMask = false
|
|
3109
|
+
} = opts;
|
|
3110
|
+
if (globalAlpha === 0) return;
|
|
3111
|
+
let x = targetX;
|
|
3112
|
+
let y = targetY;
|
|
3113
|
+
let sx = sourceX;
|
|
3114
|
+
let sy = sourceY;
|
|
3115
|
+
let w = width;
|
|
3116
|
+
let h = height;
|
|
3117
|
+
if (sx < 0) {
|
|
3118
|
+
x -= sx;
|
|
3119
|
+
w += sx;
|
|
3120
|
+
sx = 0;
|
|
3121
|
+
}
|
|
3122
|
+
if (sy < 0) {
|
|
3123
|
+
y -= sy;
|
|
3124
|
+
h += sy;
|
|
3125
|
+
sy = 0;
|
|
3126
|
+
}
|
|
3127
|
+
w = Math.min(w, src.width - sx);
|
|
3128
|
+
h = Math.min(h, src.height - sy);
|
|
3129
|
+
if (x < 0) {
|
|
3130
|
+
sx -= x;
|
|
3131
|
+
w += x;
|
|
3078
3132
|
x = 0;
|
|
3133
|
+
}
|
|
3134
|
+
if (y < 0) {
|
|
3135
|
+
sy -= y;
|
|
3136
|
+
h += y;
|
|
3079
3137
|
y = 0;
|
|
3080
|
-
w = dst.width;
|
|
3081
|
-
h = dst.height;
|
|
3082
3138
|
}
|
|
3083
|
-
const
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
x: finalX,
|
|
3087
|
-
y: finalY,
|
|
3088
|
-
w: actualW,
|
|
3089
|
-
h: actualH
|
|
3090
|
-
} = clip;
|
|
3091
|
-
const dst32 = dst.data32;
|
|
3139
|
+
const actualW = Math.min(w, dst.width - x);
|
|
3140
|
+
const actualH = Math.min(h, dst.height - y);
|
|
3141
|
+
if (actualW <= 0 || actualH <= 0) return;
|
|
3092
3142
|
const dw = dst.width;
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
|
|
3143
|
+
const sw = src.width;
|
|
3144
|
+
const mPitch = alphaMask.w;
|
|
3145
|
+
const maskData = alphaMask.data;
|
|
3146
|
+
const dx = x - targetX | 0;
|
|
3147
|
+
const dy = y - targetY | 0;
|
|
3148
|
+
const dst32 = dst.data32;
|
|
3149
|
+
const src32 = src.data32;
|
|
3150
|
+
let dIdx = y * dw + x | 0;
|
|
3151
|
+
let sIdx = sy * sw + sx | 0;
|
|
3152
|
+
let mIdx = (my + dy) * mPitch + (mx + dx) | 0;
|
|
3153
|
+
const dStride = dw - actualW | 0;
|
|
3154
|
+
const sStride = sw - actualW | 0;
|
|
3155
|
+
const mStride = mPitch - actualW | 0;
|
|
3156
|
+
const isOpaque = globalAlpha === 255;
|
|
3157
|
+
const isOverwrite = blendFn.isOverwrite || false;
|
|
3158
|
+
for (let iy = 0; iy < actualH; iy++) {
|
|
3159
|
+
for (let ix = 0; ix < actualW; ix++) {
|
|
3160
|
+
const mVal = maskData[mIdx];
|
|
3161
|
+
const effM = invertMask ? 255 - mVal : mVal;
|
|
3162
|
+
if (effM === 0) {
|
|
3163
|
+
dIdx++;
|
|
3164
|
+
sIdx++;
|
|
3165
|
+
mIdx++;
|
|
3166
|
+
continue;
|
|
3167
|
+
}
|
|
3168
|
+
const srcCol = src32[sIdx];
|
|
3169
|
+
const srcAlpha = srcCol >>> 24;
|
|
3170
|
+
if (srcAlpha === 0 && !isOverwrite) {
|
|
3171
|
+
dIdx++;
|
|
3172
|
+
sIdx++;
|
|
3173
|
+
mIdx++;
|
|
3174
|
+
continue;
|
|
3175
|
+
}
|
|
3176
|
+
let weight = globalAlpha;
|
|
3177
|
+
if (isOpaque) {
|
|
3178
|
+
weight = effM;
|
|
3179
|
+
} else if (effM !== 255) {
|
|
3180
|
+
weight = effM * globalAlpha + 128 >> 8;
|
|
3181
|
+
}
|
|
3182
|
+
if (weight === 0) {
|
|
3183
|
+
dIdx++;
|
|
3184
|
+
sIdx++;
|
|
3185
|
+
mIdx++;
|
|
3186
|
+
continue;
|
|
3187
|
+
}
|
|
3188
|
+
let finalCol = srcCol;
|
|
3189
|
+
if (weight < 255) {
|
|
3190
|
+
const a = srcAlpha * weight + 128 >> 8;
|
|
3191
|
+
if (a === 0 && !isOverwrite) {
|
|
3192
|
+
dIdx++;
|
|
3193
|
+
sIdx++;
|
|
3194
|
+
mIdx++;
|
|
3195
|
+
continue;
|
|
3110
3196
|
}
|
|
3197
|
+
finalCol = (srcCol & 16777215 | a << 24) >>> 0;
|
|
3111
3198
|
}
|
|
3199
|
+
dst32[dIdx] = blendFn(finalCol, dst32[dIdx]);
|
|
3200
|
+
dIdx++;
|
|
3201
|
+
sIdx++;
|
|
3202
|
+
mIdx++;
|
|
3112
3203
|
}
|
|
3113
|
-
|
|
3114
|
-
|
|
3115
|
-
|
|
3116
|
-
const end = start + actualW;
|
|
3117
|
-
dst32.fill(color, start, end);
|
|
3118
|
-
}
|
|
3204
|
+
dIdx += dStride;
|
|
3205
|
+
sIdx += sStride;
|
|
3206
|
+
mIdx += mStride;
|
|
3119
3207
|
}
|
|
3120
3208
|
}
|
|
3121
3209
|
|
|
3122
|
-
// src/History/PixelMutator/
|
|
3123
|
-
var defaults12 = {
|
|
3124
|
-
fillPixelData
|
|
3125
|
-
};
|
|
3126
|
-
var mutatorClear = ((writer, deps = defaults12) => {
|
|
3127
|
-
const {
|
|
3128
|
-
fillPixelData: fillPixelData2 = defaults12.fillPixelData
|
|
3129
|
-
} = deps;
|
|
3130
|
-
return {
|
|
3131
|
-
clear(rect = {}) {
|
|
3132
|
-
const {
|
|
3133
|
-
x = 0,
|
|
3134
|
-
y = 0,
|
|
3135
|
-
w = writer.target.width,
|
|
3136
|
-
h = writer.target.height,
|
|
3137
|
-
mask = void 0
|
|
3138
|
-
} = rect;
|
|
3139
|
-
writer.accumulator.storeRegionBeforeState(x, y, w, h);
|
|
3140
|
-
fillPixelData2(writer.target, 0, x, y, w, h, mask);
|
|
3141
|
-
}
|
|
3142
|
-
};
|
|
3143
|
-
});
|
|
3144
|
-
|
|
3145
|
-
// src/History/PixelMutator/mutatorFill.ts
|
|
3210
|
+
// src/History/PixelMutator/mutatorBlendPixelDataAlphaMask.ts
|
|
3146
3211
|
var defaults13 = {
|
|
3147
|
-
|
|
3212
|
+
blendPixelDataAlphaMask
|
|
3148
3213
|
};
|
|
3149
|
-
var
|
|
3214
|
+
var mutatorBlendPixelDataAlphaMask = ((writer, deps = defaults13) => {
|
|
3150
3215
|
const {
|
|
3151
|
-
|
|
3216
|
+
blendPixelDataAlphaMask: blendPixelDataAlphaMask2 = defaults13.blendPixelDataAlphaMask
|
|
3152
3217
|
} = deps;
|
|
3153
3218
|
return {
|
|
3154
|
-
|
|
3155
|
-
const
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
h = writer.target.height,
|
|
3160
|
-
mask = void 0
|
|
3161
|
-
} = rect;
|
|
3219
|
+
blendPixelDataAlphaMask(src, mask, opts = {}) {
|
|
3220
|
+
const x = opts.x ?? 0;
|
|
3221
|
+
const y = opts.y ?? 0;
|
|
3222
|
+
const w = opts.w ?? src.width;
|
|
3223
|
+
const h = opts.h ?? src.height;
|
|
3162
3224
|
writer.accumulator.storeRegionBeforeState(x, y, w, h);
|
|
3163
|
-
|
|
3225
|
+
blendPixelDataAlphaMask2(writer.target, src, mask, opts);
|
|
3164
3226
|
}
|
|
3165
3227
|
};
|
|
3166
3228
|
});
|
|
3167
3229
|
|
|
3168
|
-
// src/PixelData/
|
|
3169
|
-
|
|
3170
|
-
function invertPixelData(pixelData, opts = {}) {
|
|
3171
|
-
const dst = pixelData;
|
|
3230
|
+
// src/PixelData/blendPixelDataBinaryMask.ts
|
|
3231
|
+
function blendPixelDataBinaryMask(dst, src, binaryMask, opts = {}) {
|
|
3172
3232
|
const {
|
|
3173
3233
|
x: targetX = 0,
|
|
3174
3234
|
y: targetY = 0,
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3235
|
+
sx: sourceX = 0,
|
|
3236
|
+
sy: sourceY = 0,
|
|
3237
|
+
w: width = src.width,
|
|
3238
|
+
h: height = src.height,
|
|
3239
|
+
alpha: globalAlpha = 255,
|
|
3240
|
+
blendFn = sourceOverPerfect,
|
|
3179
3241
|
mx = 0,
|
|
3180
3242
|
my = 0,
|
|
3181
3243
|
invertMask = false
|
|
3182
3244
|
} = opts;
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3245
|
+
if (globalAlpha === 0) return;
|
|
3246
|
+
let x = targetX;
|
|
3247
|
+
let y = targetY;
|
|
3248
|
+
let sx = sourceX;
|
|
3249
|
+
let sy = sourceY;
|
|
3250
|
+
let w = width;
|
|
3251
|
+
let h = height;
|
|
3252
|
+
if (sx < 0) {
|
|
3253
|
+
x -= sx;
|
|
3254
|
+
w += sx;
|
|
3255
|
+
sx = 0;
|
|
3256
|
+
}
|
|
3257
|
+
if (sy < 0) {
|
|
3258
|
+
y -= sy;
|
|
3259
|
+
h += sy;
|
|
3260
|
+
sy = 0;
|
|
3261
|
+
}
|
|
3262
|
+
w = Math.min(w, src.width - sx);
|
|
3263
|
+
h = Math.min(h, src.height - sy);
|
|
3264
|
+
if (x < 0) {
|
|
3265
|
+
sx -= x;
|
|
3266
|
+
w += x;
|
|
3267
|
+
x = 0;
|
|
3268
|
+
}
|
|
3269
|
+
if (y < 0) {
|
|
3270
|
+
sy -= y;
|
|
3271
|
+
h += y;
|
|
3272
|
+
y = 0;
|
|
3273
|
+
}
|
|
3274
|
+
const actualW = Math.min(w, dst.width - x);
|
|
3275
|
+
const actualH = Math.min(h, dst.height - y);
|
|
3276
|
+
if (actualW <= 0 || actualH <= 0) return;
|
|
3277
|
+
const dx = x - targetX | 0;
|
|
3278
|
+
const dy = y - targetY | 0;
|
|
3279
|
+
const dst32 = dst.data32;
|
|
3280
|
+
const src32 = src.data32;
|
|
3281
|
+
const dw = dst.width;
|
|
3282
|
+
const sw = src.width;
|
|
3283
|
+
const mPitch = binaryMask.w;
|
|
3284
|
+
const maskData = binaryMask.data;
|
|
3285
|
+
let dIdx = y * dw + x | 0;
|
|
3286
|
+
let sIdx = sy * sw + sx | 0;
|
|
3287
|
+
let mIdx = (my + dy) * mPitch + (mx + dx) | 0;
|
|
3288
|
+
const dStride = dw - actualW | 0;
|
|
3289
|
+
const sStride = sw - actualW | 0;
|
|
3290
|
+
const mStride = mPitch - actualW | 0;
|
|
3291
|
+
const skipVal = invertMask ? 1 : 0;
|
|
3292
|
+
const isOpaque = globalAlpha === 255;
|
|
3293
|
+
const isOverwrite = blendFn.isOverwrite || false;
|
|
3294
|
+
for (let iy = 0; iy < actualH; iy++) {
|
|
3295
|
+
for (let ix = 0; ix < actualW; ix++) {
|
|
3296
|
+
if (maskData[mIdx] === skipVal) {
|
|
3297
|
+
dIdx++;
|
|
3298
|
+
sIdx++;
|
|
3299
|
+
mIdx++;
|
|
3300
|
+
continue;
|
|
3301
|
+
}
|
|
3302
|
+
const srcCol = src32[sIdx];
|
|
3303
|
+
const srcAlpha = srcCol >>> 24;
|
|
3304
|
+
if (srcAlpha === 0 && !isOverwrite) {
|
|
3305
|
+
dIdx++;
|
|
3306
|
+
sIdx++;
|
|
3307
|
+
mIdx++;
|
|
3308
|
+
continue;
|
|
3309
|
+
}
|
|
3310
|
+
let finalCol = srcCol;
|
|
3311
|
+
if (!isOpaque) {
|
|
3312
|
+
const a = srcAlpha * globalAlpha + 128 >> 8;
|
|
3313
|
+
if (a === 0 && !isOverwrite) {
|
|
3314
|
+
dIdx++;
|
|
3315
|
+
sIdx++;
|
|
3316
|
+
mIdx++;
|
|
3317
|
+
continue;
|
|
3318
|
+
}
|
|
3319
|
+
finalCol = (srcCol & 16777215 | a << 24) >>> 0;
|
|
3320
|
+
}
|
|
3321
|
+
dst32[dIdx] = blendFn(finalCol, dst32[dIdx]);
|
|
3322
|
+
dIdx++;
|
|
3323
|
+
sIdx++;
|
|
3324
|
+
mIdx++;
|
|
3325
|
+
}
|
|
3326
|
+
dIdx += dStride;
|
|
3327
|
+
sIdx += sStride;
|
|
3328
|
+
mIdx += mStride;
|
|
3329
|
+
}
|
|
3330
|
+
}
|
|
3331
|
+
|
|
3332
|
+
// src/History/PixelMutator/mutatorBlendPixelDataBinaryMask.ts
|
|
3333
|
+
var defaults14 = {
|
|
3334
|
+
blendPixelDataBinaryMask
|
|
3335
|
+
};
|
|
3336
|
+
var mutatorBlendPixelDataBinaryMask = ((writer, deps = defaults14) => {
|
|
3337
|
+
const {
|
|
3338
|
+
blendPixelDataBinaryMask: blendPixelDataBinaryMask2 = defaults14.blendPixelDataBinaryMask
|
|
3339
|
+
} = deps;
|
|
3340
|
+
return {
|
|
3341
|
+
blendPixelDataBinaryMask(src, mask, opts = {}) {
|
|
3342
|
+
const x = opts.x ?? 0;
|
|
3343
|
+
const y = opts.y ?? 0;
|
|
3344
|
+
const w = opts.w ?? src.width;
|
|
3345
|
+
const h = opts.h ?? src.height;
|
|
3346
|
+
writer.accumulator.storeRegionBeforeState(x, y, w, h);
|
|
3347
|
+
blendPixelDataBinaryMask2(writer.target, src, mask, opts);
|
|
3348
|
+
}
|
|
3349
|
+
};
|
|
3350
|
+
});
|
|
3351
|
+
|
|
3352
|
+
// src/PixelData/fillPixelData.ts
|
|
3353
|
+
var SCRATCH_RECT = makeClippedRect();
|
|
3354
|
+
function fillPixelData(dst, color, _x, _y, _w, _h) {
|
|
3355
|
+
let x;
|
|
3356
|
+
let y;
|
|
3357
|
+
let w;
|
|
3358
|
+
let h;
|
|
3359
|
+
if (typeof _x === "object") {
|
|
3360
|
+
x = _x.x ?? 0;
|
|
3361
|
+
y = _x.y ?? 0;
|
|
3362
|
+
w = _x.w ?? dst.width;
|
|
3363
|
+
h = _x.h ?? dst.height;
|
|
3364
|
+
} else if (typeof _x === "number") {
|
|
3365
|
+
x = _x;
|
|
3366
|
+
y = _y;
|
|
3367
|
+
w = _w;
|
|
3368
|
+
h = _h;
|
|
3369
|
+
} else {
|
|
3370
|
+
x = 0;
|
|
3371
|
+
y = 0;
|
|
3372
|
+
w = dst.width;
|
|
3373
|
+
h = dst.height;
|
|
3374
|
+
}
|
|
3375
|
+
const clip = resolveRectClipping(x, y, w, h, dst.width, dst.height, SCRATCH_RECT);
|
|
3376
|
+
if (!clip.inBounds) return;
|
|
3377
|
+
const {
|
|
3378
|
+
x: finalX,
|
|
3379
|
+
y: finalY,
|
|
3380
|
+
w: actualW,
|
|
3381
|
+
h: actualH
|
|
3382
|
+
} = clip;
|
|
3383
|
+
const dst32 = dst.data32;
|
|
3384
|
+
const dw = dst.width;
|
|
3385
|
+
if (actualW === dw && actualH === dst.height && finalX === 0 && finalY === 0) {
|
|
3386
|
+
dst32.fill(color);
|
|
3387
|
+
return;
|
|
3388
|
+
}
|
|
3389
|
+
for (let iy = 0; iy < actualH; iy++) {
|
|
3390
|
+
const start = (finalY + iy) * dw + finalX;
|
|
3391
|
+
const end = start + actualW;
|
|
3392
|
+
dst32.fill(color, start, end);
|
|
3393
|
+
}
|
|
3394
|
+
}
|
|
3395
|
+
|
|
3396
|
+
// src/History/PixelMutator/mutatorClear.ts
|
|
3397
|
+
var defaults15 = {
|
|
3398
|
+
fillPixelData
|
|
3399
|
+
};
|
|
3400
|
+
var mutatorClear = ((writer, deps = defaults15) => {
|
|
3401
|
+
const {
|
|
3402
|
+
fillPixelData: fillPixelData2 = defaults15.fillPixelData
|
|
3403
|
+
} = deps;
|
|
3404
|
+
return {
|
|
3405
|
+
clear(rect = {}) {
|
|
3406
|
+
const x = rect.x ?? 0;
|
|
3407
|
+
const y = rect.y ?? 0;
|
|
3408
|
+
const w = rect.w ?? writer.target.width;
|
|
3409
|
+
const h = rect.h ?? writer.target.height;
|
|
3410
|
+
writer.accumulator.storeRegionBeforeState(x, y, w, h);
|
|
3411
|
+
fillPixelData2(writer.target, 0, x, y, w, h);
|
|
3412
|
+
}
|
|
3413
|
+
};
|
|
3414
|
+
});
|
|
3415
|
+
|
|
3416
|
+
// src/History/PixelMutator/mutatorFill.ts
|
|
3417
|
+
var defaults16 = {
|
|
3418
|
+
fillPixelData
|
|
3419
|
+
};
|
|
3420
|
+
var mutatorFill = ((writer, deps = defaults16) => {
|
|
3421
|
+
const {
|
|
3422
|
+
fillPixelData: fillPixelData2 = defaults16.fillPixelData
|
|
3423
|
+
} = deps;
|
|
3424
|
+
return {
|
|
3425
|
+
fill(color, rect = {}) {
|
|
3426
|
+
const {
|
|
3427
|
+
x = 0,
|
|
3428
|
+
y = 0,
|
|
3429
|
+
w = writer.target.width,
|
|
3430
|
+
h = writer.target.height
|
|
3431
|
+
} = rect;
|
|
3432
|
+
writer.accumulator.storeRegionBeforeState(x, y, w, h);
|
|
3433
|
+
fillPixelData2(writer.target, color, x, y, w, h);
|
|
3434
|
+
}
|
|
3435
|
+
};
|
|
3436
|
+
});
|
|
3437
|
+
|
|
3438
|
+
// src/PixelData/fillPixelDataBinaryMask.ts
|
|
3439
|
+
var SCRATCH_RECT2 = makeClippedRect();
|
|
3440
|
+
function fillPixelDataBinaryMask(dst, color, mask, alpha = 255, x = 0, y = 0) {
|
|
3441
|
+
if (alpha === 0) return;
|
|
3442
|
+
const maskW = mask.w;
|
|
3443
|
+
const maskH = mask.h;
|
|
3444
|
+
const clip = resolveRectClipping(x, y, maskW, maskH, dst.width, dst.height, SCRATCH_RECT2);
|
|
3445
|
+
if (!clip.inBounds) return;
|
|
3446
|
+
const {
|
|
3447
|
+
x: finalX,
|
|
3448
|
+
y: finalY,
|
|
3449
|
+
w: actualW,
|
|
3450
|
+
h: actualH
|
|
3451
|
+
} = clip;
|
|
3452
|
+
const maskData = mask.data;
|
|
3453
|
+
const dst32 = dst.data32;
|
|
3454
|
+
const dw = dst.width;
|
|
3455
|
+
let finalCol = color;
|
|
3456
|
+
if (alpha < 255) {
|
|
3457
|
+
const baseSrcAlpha = color >>> 24;
|
|
3458
|
+
const colorRGB = color & 16777215;
|
|
3459
|
+
const a = baseSrcAlpha * alpha + 128 >> 8;
|
|
3460
|
+
finalCol = (colorRGB | a << 24) >>> 0;
|
|
3461
|
+
}
|
|
3462
|
+
for (let iy = 0; iy < actualH; iy++) {
|
|
3463
|
+
const currentY = finalY + iy;
|
|
3464
|
+
const maskY = currentY - y;
|
|
3465
|
+
const maskOffset = maskY * maskW;
|
|
3466
|
+
const dstRowOffset = currentY * dw;
|
|
3467
|
+
for (let ix = 0; ix < actualW; ix++) {
|
|
3468
|
+
const currentX = finalX + ix;
|
|
3469
|
+
const maskX = currentX - x;
|
|
3470
|
+
const maskIndex = maskOffset + maskX;
|
|
3471
|
+
if (maskData[maskIndex]) {
|
|
3472
|
+
dst32[dstRowOffset + currentX] = finalCol;
|
|
3473
|
+
}
|
|
3474
|
+
}
|
|
3475
|
+
}
|
|
3476
|
+
}
|
|
3477
|
+
|
|
3478
|
+
// src/History/PixelMutator/mutatorFillBinaryMask.ts
|
|
3479
|
+
var defaults17 = {
|
|
3480
|
+
fillPixelDataBinaryMask
|
|
3481
|
+
};
|
|
3482
|
+
var mutatorFillBinaryMask = ((writer, deps = defaults17) => {
|
|
3483
|
+
const {
|
|
3484
|
+
fillPixelDataBinaryMask: fillPixelDataBinaryMask2 = defaults17.fillPixelDataBinaryMask
|
|
3485
|
+
} = deps;
|
|
3486
|
+
return {
|
|
3487
|
+
fillBinaryMask(color, mask, alpha = 255, x = 0, y = 0) {
|
|
3488
|
+
writer.accumulator.storeRegionBeforeState(x, y, mask.w, mask.h);
|
|
3489
|
+
fillPixelDataBinaryMask2(writer.target, color, mask, alpha, x, y);
|
|
3490
|
+
}
|
|
3491
|
+
};
|
|
3492
|
+
});
|
|
3493
|
+
|
|
3494
|
+
// src/PixelData/invertPixelData.ts
|
|
3495
|
+
var SCRATCH_RECT3 = makeClippedRect();
|
|
3496
|
+
function invertPixelData(pixelData, opts = {}) {
|
|
3497
|
+
const dst = pixelData;
|
|
3498
|
+
const {
|
|
3499
|
+
x: targetX = 0,
|
|
3500
|
+
y: targetY = 0,
|
|
3501
|
+
w: width = pixelData.width,
|
|
3502
|
+
h: height = pixelData.height,
|
|
3503
|
+
mask,
|
|
3504
|
+
mx = 0,
|
|
3505
|
+
my = 0,
|
|
3506
|
+
invertMask = false
|
|
3507
|
+
} = opts;
|
|
3508
|
+
const clip = resolveRectClipping(targetX, targetY, width, height, dst.width, dst.height, SCRATCH_RECT3);
|
|
3509
|
+
if (!clip.inBounds) return;
|
|
3510
|
+
const {
|
|
3511
|
+
x,
|
|
3187
3512
|
y,
|
|
3188
3513
|
w: actualW,
|
|
3189
3514
|
h: actualH
|
|
3190
3515
|
} = clip;
|
|
3191
3516
|
const dst32 = dst.data32;
|
|
3192
3517
|
const dw = dst.width;
|
|
3193
|
-
const mPitch =
|
|
3518
|
+
const mPitch = mask?.w ?? width;
|
|
3194
3519
|
const dx = x - targetX;
|
|
3195
3520
|
const dy = y - targetY;
|
|
3196
3521
|
let dIdx = y * dw + x;
|
|
@@ -3198,9 +3523,10 @@ function invertPixelData(pixelData, opts = {}) {
|
|
|
3198
3523
|
const dStride = dw - actualW;
|
|
3199
3524
|
const mStride = mPitch - actualW;
|
|
3200
3525
|
if (mask) {
|
|
3526
|
+
const maskData = mask.data;
|
|
3201
3527
|
for (let iy = 0; iy < actualH; iy++) {
|
|
3202
3528
|
for (let ix = 0; ix < actualW; ix++) {
|
|
3203
|
-
const mVal =
|
|
3529
|
+
const mVal = maskData[mIdx];
|
|
3204
3530
|
const isHit = invertMask ? mVal === 0 : mVal === 1;
|
|
3205
3531
|
if (isHit) {
|
|
3206
3532
|
dst32[dIdx] = dst32[dIdx] ^ 16777215;
|
|
@@ -3223,12 +3549,12 @@ function invertPixelData(pixelData, opts = {}) {
|
|
|
3223
3549
|
}
|
|
3224
3550
|
|
|
3225
3551
|
// src/History/PixelMutator/mutatorInvert.ts
|
|
3226
|
-
var
|
|
3552
|
+
var defaults18 = {
|
|
3227
3553
|
invertPixelData
|
|
3228
3554
|
};
|
|
3229
|
-
var mutatorInvert = ((writer, deps =
|
|
3555
|
+
var mutatorInvert = ((writer, deps = defaults18) => {
|
|
3230
3556
|
const {
|
|
3231
|
-
invertPixelData: invertPixelData2 =
|
|
3557
|
+
invertPixelData: invertPixelData2 = defaults18.invertPixelData
|
|
3232
3558
|
} = deps;
|
|
3233
3559
|
return {
|
|
3234
3560
|
invert(opts = {}) {
|
|
@@ -3247,21 +3573,26 @@ var mutatorInvert = ((writer, deps = defaults14) => {
|
|
|
3247
3573
|
// src/History/PixelMutator.ts
|
|
3248
3574
|
function makeFullPixelMutator(writer) {
|
|
3249
3575
|
return {
|
|
3576
|
+
// @sort
|
|
3250
3577
|
...mutatorApplyAlphaMask(writer),
|
|
3251
3578
|
...mutatorApplyBinaryMask(writer),
|
|
3252
|
-
...mutatorBlendPixelData(writer),
|
|
3253
|
-
...mutatorBlendColor(writer),
|
|
3254
|
-
...mutatorBlendPixel(writer),
|
|
3255
|
-
...mutatorFill(writer),
|
|
3256
|
-
...mutatorInvert(writer),
|
|
3257
3579
|
...mutatorApplyCircleBrush(writer),
|
|
3258
3580
|
...mutatorApplyCircleBrushStroke(writer),
|
|
3581
|
+
...mutatorApplyCirclePencil(writer),
|
|
3259
3582
|
...mutatorApplyCirclePencilStroke(writer),
|
|
3260
3583
|
...mutatorApplyRectBrush(writer),
|
|
3261
3584
|
...mutatorApplyRectBrushStroke(writer),
|
|
3262
3585
|
...mutatorApplyRectPencil(writer),
|
|
3263
3586
|
...mutatorApplyRectPencilStroke(writer),
|
|
3264
|
-
...
|
|
3587
|
+
...mutatorBlendColor(writer),
|
|
3588
|
+
...mutatorBlendPixel(writer),
|
|
3589
|
+
...mutatorBlendPixelData(writer),
|
|
3590
|
+
...mutatorBlendPixelDataAlphaMask(writer),
|
|
3591
|
+
...mutatorBlendPixelDataBinaryMask(writer),
|
|
3592
|
+
...mutatorClear(writer),
|
|
3593
|
+
...mutatorFill(writer),
|
|
3594
|
+
...mutatorFillBinaryMask(writer),
|
|
3595
|
+
...mutatorInvert(writer)
|
|
3265
3596
|
};
|
|
3266
3597
|
}
|
|
3267
3598
|
|
|
@@ -3308,39 +3639,6 @@ var PixelWriter = class {
|
|
|
3308
3639
|
}
|
|
3309
3640
|
};
|
|
3310
3641
|
|
|
3311
|
-
// src/History/PixelMutator/mutatorApplyCirclePencil.ts
|
|
3312
|
-
var defaults15 = {
|
|
3313
|
-
applyCircleBrushToPixelData,
|
|
3314
|
-
getCircleBrushOrPencilBounds,
|
|
3315
|
-
fallOff: () => 1
|
|
3316
|
-
};
|
|
3317
|
-
var mutatorApplyCirclePencil = ((writer, deps = defaults15) => {
|
|
3318
|
-
const {
|
|
3319
|
-
applyCircleBrushToPixelData: applyCircleBrushToPixelData2 = defaults15.applyCircleBrushToPixelData,
|
|
3320
|
-
getCircleBrushOrPencilBounds: getCircleBrushOrPencilBounds2 = defaults15.getCircleBrushOrPencilBounds,
|
|
3321
|
-
fallOff = defaults15.fallOff
|
|
3322
|
-
} = deps;
|
|
3323
|
-
const boundsOut = {
|
|
3324
|
-
x: 0,
|
|
3325
|
-
y: 0,
|
|
3326
|
-
w: 0,
|
|
3327
|
-
h: 0
|
|
3328
|
-
};
|
|
3329
|
-
return {
|
|
3330
|
-
applyCirclePencil(color, centerX, centerY, brushSize, alpha = 255, blendFn) {
|
|
3331
|
-
const bounds = getCircleBrushOrPencilBounds2(centerX, centerY, brushSize, writer.target.width, writer.target.height, boundsOut);
|
|
3332
|
-
const {
|
|
3333
|
-
x,
|
|
3334
|
-
y,
|
|
3335
|
-
w,
|
|
3336
|
-
h
|
|
3337
|
-
} = bounds;
|
|
3338
|
-
writer.accumulator.storeRegionBeforeState(x, y, w, h);
|
|
3339
|
-
applyCircleBrushToPixelData2(writer.target, color, centerX, centerY, brushSize, alpha, fallOff, blendFn, bounds);
|
|
3340
|
-
}
|
|
3341
|
-
};
|
|
3342
|
-
});
|
|
3343
|
-
|
|
3344
3642
|
// src/ImageData/copyImageData.ts
|
|
3345
3643
|
function copyImageData({
|
|
3346
3644
|
data,
|
|
@@ -3372,8 +3670,8 @@ function makeImageDataLike(width, height, data) {
|
|
|
3372
3670
|
};
|
|
3373
3671
|
}
|
|
3374
3672
|
|
|
3375
|
-
// src/ImageData/
|
|
3376
|
-
function
|
|
3673
|
+
// src/ImageData/imageDataToAlphaMaskBuffer.ts
|
|
3674
|
+
function imageDataToAlphaMaskBuffer(imageData) {
|
|
3377
3675
|
const {
|
|
3378
3676
|
width,
|
|
3379
3677
|
height,
|
|
@@ -3463,13 +3761,13 @@ function resampleImageData(source, factor) {
|
|
|
3463
3761
|
}
|
|
3464
3762
|
|
|
3465
3763
|
// src/ImageData/resizeImageData.ts
|
|
3466
|
-
function resizeImageData(
|
|
3764
|
+
function resizeImageData(target, newWidth, newHeight, offsetX = 0, offsetY = 0) {
|
|
3467
3765
|
const result = new ImageData(newWidth, newHeight);
|
|
3468
3766
|
const {
|
|
3469
3767
|
width: oldW,
|
|
3470
3768
|
height: oldH,
|
|
3471
3769
|
data: oldData
|
|
3472
|
-
} =
|
|
3770
|
+
} = target;
|
|
3473
3771
|
const newData = result.data;
|
|
3474
3772
|
const x0 = Math.max(0, offsetX);
|
|
3475
3773
|
const y0 = Math.max(0, offsetY);
|
|
@@ -3624,7 +3922,7 @@ function writeImageData(target, source, x, y, sx = 0, sy = 0, sw = source.width,
|
|
|
3624
3922
|
|
|
3625
3923
|
// src/ImageData/writeImageDataBuffer.ts
|
|
3626
3924
|
var SCRATCH_BLIT3 = makeClippedBlit();
|
|
3627
|
-
function writeImageDataBuffer(
|
|
3925
|
+
function writeImageDataBuffer(target, data, _x, _y, _w, _h) {
|
|
3628
3926
|
const {
|
|
3629
3927
|
x,
|
|
3630
3928
|
y,
|
|
@@ -3640,7 +3938,7 @@ function writeImageDataBuffer(imageData, data, _x, _y, _w, _h) {
|
|
|
3640
3938
|
width: dstW,
|
|
3641
3939
|
height: dstH,
|
|
3642
3940
|
data: dst
|
|
3643
|
-
} =
|
|
3941
|
+
} = target;
|
|
3644
3942
|
const clip = resolveBlitClipping(x, y, 0, 0, w, h, dstW, dstH, w, h, SCRATCH_BLIT3);
|
|
3645
3943
|
if (!clip.inBounds) return;
|
|
3646
3944
|
const {
|
|
@@ -3886,22 +4184,100 @@ async function getSupportedPixelFormats(rasterMimes = defaultRasterMimes) {
|
|
|
3886
4184
|
return formatsPromise;
|
|
3887
4185
|
}
|
|
3888
4186
|
|
|
3889
|
-
// src/Mask/
|
|
3890
|
-
function
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
w
|
|
3895
|
-
h
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
|
|
4187
|
+
// src/Mask/AlphaMask.ts
|
|
4188
|
+
function makeAlphaMask(w, h, data) {
|
|
4189
|
+
return {
|
|
4190
|
+
type: 0 /* ALPHA */,
|
|
4191
|
+
data: data ?? new Uint8Array(w * h),
|
|
4192
|
+
w,
|
|
4193
|
+
h
|
|
4194
|
+
};
|
|
4195
|
+
}
|
|
4196
|
+
|
|
4197
|
+
// src/Mask/BinaryMask.ts
|
|
4198
|
+
function makeBinaryMask(w, h, data) {
|
|
4199
|
+
return {
|
|
4200
|
+
type: 1 /* BINARY */,
|
|
4201
|
+
data: data ?? new Uint8Array(w * h),
|
|
4202
|
+
w,
|
|
4203
|
+
h
|
|
4204
|
+
};
|
|
4205
|
+
}
|
|
4206
|
+
|
|
4207
|
+
// src/Mask/CircleBrushAlphaMask.ts
|
|
4208
|
+
function makeCircleBrushAlphaMask(size, fallOff = () => 1) {
|
|
4209
|
+
const area = size * size;
|
|
4210
|
+
const data = new Uint8Array(area);
|
|
4211
|
+
const radius = size / 2;
|
|
4212
|
+
const invR = 1 / radius;
|
|
4213
|
+
const minOffset = -Math.ceil(radius - 0.5);
|
|
4214
|
+
for (let y = 0; y < size; y++) {
|
|
4215
|
+
for (let x = 0; x < size; x++) {
|
|
4216
|
+
const dx = x - radius + 0.5;
|
|
4217
|
+
const dy = y - radius + 0.5;
|
|
4218
|
+
const distSqr = dx * dx + dy * dy;
|
|
4219
|
+
if (distSqr <= radius * radius) {
|
|
4220
|
+
const dist = Math.sqrt(distSqr);
|
|
4221
|
+
data[y * size + x] = fallOff(1 - dist * invR) * 255 | 0;
|
|
4222
|
+
}
|
|
4223
|
+
}
|
|
4224
|
+
}
|
|
4225
|
+
return {
|
|
4226
|
+
type: 0 /* ALPHA */,
|
|
4227
|
+
data,
|
|
4228
|
+
w: size,
|
|
4229
|
+
h: size,
|
|
4230
|
+
radius,
|
|
4231
|
+
size,
|
|
4232
|
+
minOffset
|
|
4233
|
+
};
|
|
4234
|
+
}
|
|
4235
|
+
|
|
4236
|
+
// src/Mask/CircleBrushBinaryMask.ts
|
|
4237
|
+
function makeCircleBrushBinaryMask(size) {
|
|
4238
|
+
const area = size * size;
|
|
4239
|
+
const data = new Uint8Array(area);
|
|
4240
|
+
const radius = size / 2;
|
|
4241
|
+
const minOffset = -Math.ceil(radius - 0.5);
|
|
4242
|
+
for (let y = 0; y < size; y++) {
|
|
4243
|
+
for (let x = 0; x < size; x++) {
|
|
4244
|
+
const dx = x - radius + 0.5;
|
|
4245
|
+
const dy = y - radius + 0.5;
|
|
4246
|
+
const distSqr = dx * dx + dy * dy;
|
|
4247
|
+
if (distSqr <= radius * radius) {
|
|
4248
|
+
data[y * size + x] = 1;
|
|
4249
|
+
}
|
|
4250
|
+
}
|
|
4251
|
+
}
|
|
4252
|
+
return {
|
|
4253
|
+
type: 1 /* BINARY */,
|
|
4254
|
+
data,
|
|
4255
|
+
w: size,
|
|
4256
|
+
h: size,
|
|
4257
|
+
radius,
|
|
4258
|
+
size,
|
|
4259
|
+
minOffset
|
|
4260
|
+
};
|
|
4261
|
+
}
|
|
4262
|
+
|
|
4263
|
+
// src/Mask/applyBinaryMaskToAlphaMask.ts
|
|
4264
|
+
function applyBinaryMaskToAlphaMask(alphaMaskDst, binaryMaskSrc, opts = {}) {
|
|
4265
|
+
const {
|
|
4266
|
+
x: targetX = 0,
|
|
4267
|
+
y: targetY = 0,
|
|
4268
|
+
w: reqWidth = 0,
|
|
4269
|
+
h: reqHeight = 0,
|
|
4270
|
+
mx = 0,
|
|
4271
|
+
my = 0,
|
|
4272
|
+
invertMask = false
|
|
4273
|
+
} = opts;
|
|
4274
|
+
const dstWidth = alphaMaskDst.w;
|
|
4275
|
+
if (dstWidth <= 0) return;
|
|
4276
|
+
if (binaryMaskSrc.data.length === 0) return;
|
|
4277
|
+
const srcWidth = binaryMaskSrc.w;
|
|
4278
|
+
if (srcWidth <= 0) return;
|
|
4279
|
+
const dstHeight = alphaMaskDst.data.length / dstWidth | 0;
|
|
4280
|
+
const srcHeight = binaryMaskSrc.data.length / srcWidth | 0;
|
|
3905
4281
|
if (dstHeight <= 0) return;
|
|
3906
4282
|
if (srcHeight <= 0) return;
|
|
3907
4283
|
const dstX0 = Math.max(0, targetX);
|
|
@@ -3918,6 +4294,8 @@ function applyBinaryMaskToAlphaMask(alphaMaskDst, dstWidth, binaryMaskSrc, srcWi
|
|
|
3918
4294
|
if (srcY0 + (dstY1 - dstY0) <= 0) return;
|
|
3919
4295
|
const iterW = Math.min(dstX1 - dstX0, srcWidth - srcX0);
|
|
3920
4296
|
const iterH = Math.min(dstY1 - dstY0, srcHeight - srcY0);
|
|
4297
|
+
const srcData = binaryMaskSrc.data;
|
|
4298
|
+
const dstData = alphaMaskDst.data;
|
|
3921
4299
|
let dstIdx = dstY0 * dstWidth + dstX0;
|
|
3922
4300
|
let srcIdx = srcY0 * srcWidth + srcX0;
|
|
3923
4301
|
if (invertMask) {
|
|
@@ -3926,8 +4304,8 @@ function applyBinaryMaskToAlphaMask(alphaMaskDst, dstWidth, binaryMaskSrc, srcWi
|
|
|
3926
4304
|
let d = dstIdx;
|
|
3927
4305
|
let s = srcIdx;
|
|
3928
4306
|
while (d < dstEnd) {
|
|
3929
|
-
if (
|
|
3930
|
-
|
|
4307
|
+
if (srcData[s] !== 0) {
|
|
4308
|
+
dstData[d] = 0;
|
|
3931
4309
|
}
|
|
3932
4310
|
d++;
|
|
3933
4311
|
s++;
|
|
@@ -3941,8 +4319,8 @@ function applyBinaryMaskToAlphaMask(alphaMaskDst, dstWidth, binaryMaskSrc, srcWi
|
|
|
3941
4319
|
let d = dstIdx;
|
|
3942
4320
|
let s = srcIdx;
|
|
3943
4321
|
while (d < dstEnd) {
|
|
3944
|
-
if (
|
|
3945
|
-
|
|
4322
|
+
if (srcData[s] === 0) {
|
|
4323
|
+
dstData[d] = 0;
|
|
3946
4324
|
}
|
|
3947
4325
|
d++;
|
|
3948
4326
|
s++;
|
|
@@ -3955,25 +4333,72 @@ function applyBinaryMaskToAlphaMask(alphaMaskDst, dstWidth, binaryMaskSrc, srcWi
|
|
|
3955
4333
|
|
|
3956
4334
|
// src/Mask/copyMask.ts
|
|
3957
4335
|
function copyMask(src) {
|
|
3958
|
-
return
|
|
4336
|
+
return {
|
|
4337
|
+
type: src.type,
|
|
4338
|
+
data: src.data.slice(),
|
|
4339
|
+
w: src.w,
|
|
4340
|
+
h: src.h
|
|
4341
|
+
};
|
|
4342
|
+
}
|
|
4343
|
+
|
|
4344
|
+
// src/Mask/extractMask.ts
|
|
4345
|
+
function extractMask(mask, xOrRect, y, w, h) {
|
|
4346
|
+
let finalX;
|
|
4347
|
+
let finalY;
|
|
4348
|
+
let finalW;
|
|
4349
|
+
let finalH;
|
|
4350
|
+
if (typeof xOrRect === "object") {
|
|
4351
|
+
finalX = xOrRect.x;
|
|
4352
|
+
finalY = xOrRect.y;
|
|
4353
|
+
finalW = xOrRect.w;
|
|
4354
|
+
finalH = xOrRect.h;
|
|
4355
|
+
} else {
|
|
4356
|
+
finalX = xOrRect;
|
|
4357
|
+
finalY = y;
|
|
4358
|
+
finalW = w;
|
|
4359
|
+
finalH = h;
|
|
4360
|
+
}
|
|
4361
|
+
const out = {
|
|
4362
|
+
type: mask.type,
|
|
4363
|
+
w: finalW,
|
|
4364
|
+
h: finalH,
|
|
4365
|
+
data: new Uint8Array(finalW * finalH)
|
|
4366
|
+
};
|
|
4367
|
+
const srcH = mask.h;
|
|
4368
|
+
const stride = mask.w;
|
|
4369
|
+
for (let row = 0; row < finalH; row++) {
|
|
4370
|
+
const currentSrcY = finalY + row;
|
|
4371
|
+
if (currentSrcY < 0 || currentSrcY >= srcH) continue;
|
|
4372
|
+
const start = Math.max(0, finalX);
|
|
4373
|
+
const end = Math.min(stride, finalX + finalW);
|
|
4374
|
+
if (start < end) {
|
|
4375
|
+
const srcOffset = currentSrcY * stride + start;
|
|
4376
|
+
const dstOffset = row * finalW + (start - finalX);
|
|
4377
|
+
const count = end - start;
|
|
4378
|
+
out.data.set(mask.data.subarray(srcOffset, srcOffset + count), dstOffset);
|
|
4379
|
+
}
|
|
4380
|
+
}
|
|
4381
|
+
return out;
|
|
3959
4382
|
}
|
|
3960
4383
|
|
|
3961
4384
|
// src/Mask/invertMask.ts
|
|
3962
4385
|
function invertBinaryMask(dst) {
|
|
3963
|
-
const
|
|
4386
|
+
const data = dst.data;
|
|
4387
|
+
const len = data.length;
|
|
3964
4388
|
for (let i = 0; i < len; i++) {
|
|
3965
|
-
|
|
4389
|
+
data[i] = data[i] === 0 ? 1 : 0;
|
|
3966
4390
|
}
|
|
3967
4391
|
}
|
|
3968
4392
|
function invertAlphaMask(dst) {
|
|
3969
|
-
const
|
|
4393
|
+
const data = dst.data;
|
|
4394
|
+
const len = data.length;
|
|
3970
4395
|
for (let i = 0; i < len; i++) {
|
|
3971
|
-
|
|
4396
|
+
data[i] = 255 - data[i];
|
|
3972
4397
|
}
|
|
3973
4398
|
}
|
|
3974
4399
|
|
|
3975
4400
|
// src/Mask/mergeAlphaMasks.ts
|
|
3976
|
-
function mergeAlphaMasks(dst,
|
|
4401
|
+
function mergeAlphaMasks(dst, src, opts) {
|
|
3977
4402
|
const {
|
|
3978
4403
|
x: targetX = 0,
|
|
3979
4404
|
y: targetY = 0,
|
|
@@ -3984,15 +4409,17 @@ function mergeAlphaMasks(dst, dstWidth, src, srcWidth, opts) {
|
|
|
3984
4409
|
my = 0,
|
|
3985
4410
|
invertMask = false
|
|
3986
4411
|
} = opts;
|
|
3987
|
-
const dstHeight = dst.length / dstWidth | 0;
|
|
3988
|
-
const srcHeight = src.length / srcWidth | 0;
|
|
3989
4412
|
if (width <= 0) return;
|
|
3990
4413
|
if (height <= 0) return;
|
|
3991
4414
|
if (globalAlpha === 0) return;
|
|
4415
|
+
const dstData = dst.data;
|
|
4416
|
+
const srcData = src.data;
|
|
4417
|
+
const srcWidth = src.w;
|
|
4418
|
+
const dstWidth = dst.w;
|
|
3992
4419
|
const startX = Math.max(0, -targetX, -mx);
|
|
3993
4420
|
const startY = Math.max(0, -targetY, -my);
|
|
3994
4421
|
const endX = Math.min(width, dstWidth - targetX, srcWidth - mx);
|
|
3995
|
-
const endY = Math.min(height,
|
|
4422
|
+
const endY = Math.min(height, dst.h - targetY, src.h - my);
|
|
3996
4423
|
if (startX >= endX) return;
|
|
3997
4424
|
if (startY >= endY) return;
|
|
3998
4425
|
for (let iy = startY; iy < endY; iy++) {
|
|
@@ -4001,7 +4428,7 @@ function mergeAlphaMasks(dst, dstWidth, src, srcWidth, opts) {
|
|
|
4001
4428
|
let dIdx = dy * dstWidth + targetX + startX;
|
|
4002
4429
|
let sIdx = sy * srcWidth + mx + startX;
|
|
4003
4430
|
for (let ix = startX; ix < endX; ix++) {
|
|
4004
|
-
const rawM =
|
|
4431
|
+
const rawM = srcData[sIdx];
|
|
4005
4432
|
const effectiveM = invertMask ? 255 - rawM : rawM;
|
|
4006
4433
|
let weight = 0;
|
|
4007
4434
|
if (effectiveM === 0) {
|
|
@@ -4015,13 +4442,13 @@ function mergeAlphaMasks(dst, dstWidth, src, srcWidth, opts) {
|
|
|
4015
4442
|
}
|
|
4016
4443
|
if (weight !== 255) {
|
|
4017
4444
|
if (weight === 0) {
|
|
4018
|
-
|
|
4445
|
+
dstData[dIdx] = 0;
|
|
4019
4446
|
} else {
|
|
4020
|
-
const da =
|
|
4447
|
+
const da = dstData[dIdx];
|
|
4021
4448
|
if (da === 255) {
|
|
4022
|
-
|
|
4449
|
+
dstData[dIdx] = weight;
|
|
4023
4450
|
} else if (da !== 0) {
|
|
4024
|
-
|
|
4451
|
+
dstData[dIdx] = da * weight + 128 >> 8;
|
|
4025
4452
|
}
|
|
4026
4453
|
}
|
|
4027
4454
|
}
|
|
@@ -4032,7 +4459,7 @@ function mergeAlphaMasks(dst, dstWidth, src, srcWidth, opts) {
|
|
|
4032
4459
|
}
|
|
4033
4460
|
|
|
4034
4461
|
// src/Mask/mergeBinaryMasks.ts
|
|
4035
|
-
function mergeBinaryMasks(dst,
|
|
4462
|
+
function mergeBinaryMasks(dst, src, opts) {
|
|
4036
4463
|
const {
|
|
4037
4464
|
x: targetX = 0,
|
|
4038
4465
|
y: targetY = 0,
|
|
@@ -4042,10 +4469,12 @@ function mergeBinaryMasks(dst, dstWidth, src, srcWidth, opts) {
|
|
|
4042
4469
|
my = 0,
|
|
4043
4470
|
invertMask = false
|
|
4044
4471
|
} = opts;
|
|
4472
|
+
const dstData = dst.data;
|
|
4473
|
+
const srcData = src.data;
|
|
4474
|
+
const srcWidth = src.w;
|
|
4475
|
+
const dstWidth = dst.w;
|
|
4045
4476
|
if (dstWidth <= 0) return;
|
|
4046
4477
|
if (srcWidth <= 0) return;
|
|
4047
|
-
const dstHeight = dst.length / dstWidth | 0;
|
|
4048
|
-
const srcHeight = src.length / srcWidth | 0;
|
|
4049
4478
|
let x = targetX;
|
|
4050
4479
|
let y = targetY;
|
|
4051
4480
|
let w = width;
|
|
@@ -4059,7 +4488,7 @@ function mergeBinaryMasks(dst, dstWidth, src, srcWidth, opts) {
|
|
|
4059
4488
|
y = 0;
|
|
4060
4489
|
}
|
|
4061
4490
|
w = Math.min(w, dstWidth - x);
|
|
4062
|
-
h = Math.min(h,
|
|
4491
|
+
h = Math.min(h, dst.h - y);
|
|
4063
4492
|
if (w <= 0) return;
|
|
4064
4493
|
if (h <= 0) return;
|
|
4065
4494
|
const startX = mx + (x - targetX);
|
|
@@ -4067,7 +4496,7 @@ function mergeBinaryMasks(dst, dstWidth, src, srcWidth, opts) {
|
|
|
4067
4496
|
const sX0 = Math.max(0, startX);
|
|
4068
4497
|
const sY0 = Math.max(0, startY);
|
|
4069
4498
|
const sX1 = Math.min(srcWidth, startX + w);
|
|
4070
|
-
const sY1 = Math.min(
|
|
4499
|
+
const sY1 = Math.min(src.h, startY + h);
|
|
4071
4500
|
const finalW = sX1 - sX0;
|
|
4072
4501
|
const finalH = sY1 - sY0;
|
|
4073
4502
|
if (finalW <= 0) return;
|
|
@@ -4080,10 +4509,10 @@ function mergeBinaryMasks(dst, dstWidth, src, srcWidth, opts) {
|
|
|
4080
4509
|
let sIdx = sY0 * srcWidth + sX0;
|
|
4081
4510
|
for (let iy = 0; iy < finalH; iy++) {
|
|
4082
4511
|
for (let ix = 0; ix < finalW; ix++) {
|
|
4083
|
-
const mVal =
|
|
4512
|
+
const mVal = srcData[sIdx];
|
|
4084
4513
|
const isMaskedOut = invertMask ? mVal !== 0 : mVal === 0;
|
|
4085
4514
|
if (isMaskedOut) {
|
|
4086
|
-
|
|
4515
|
+
dstData[dIdx] = 0;
|
|
4087
4516
|
}
|
|
4088
4517
|
dIdx++;
|
|
4089
4518
|
sIdx++;
|
|
@@ -4093,6 +4522,177 @@ function mergeBinaryMasks(dst, dstWidth, src, srcWidth, opts) {
|
|
|
4093
4522
|
}
|
|
4094
4523
|
}
|
|
4095
4524
|
|
|
4525
|
+
// src/Mask/setMaskData.ts
|
|
4526
|
+
function setMaskData(mask, width, height, data) {
|
|
4527
|
+
;
|
|
4528
|
+
mask.w = width;
|
|
4529
|
+
mask.h = height;
|
|
4530
|
+
mask.data = data;
|
|
4531
|
+
}
|
|
4532
|
+
|
|
4533
|
+
// src/MaskRect/subtractBinaryMaskRects.ts
|
|
4534
|
+
function subtractBinaryMaskRects(current, subtracting) {
|
|
4535
|
+
let result = [...current];
|
|
4536
|
+
for (const sub of subtracting) {
|
|
4537
|
+
const next = [];
|
|
4538
|
+
for (const r of result) {
|
|
4539
|
+
const ix = Math.max(r.x, sub.x);
|
|
4540
|
+
const iy = Math.max(r.y, sub.y);
|
|
4541
|
+
const ix2 = Math.min(r.x + r.w, sub.x + sub.w);
|
|
4542
|
+
const iy2 = Math.min(r.y + r.h, sub.y + sub.h);
|
|
4543
|
+
if (ix >= ix2 || iy >= iy2) {
|
|
4544
|
+
next.push(r);
|
|
4545
|
+
continue;
|
|
4546
|
+
}
|
|
4547
|
+
if (r.y < iy) pushPiece(next, r, r.x, r.y, r.w, iy - r.y);
|
|
4548
|
+
if (iy2 < r.y + r.h) pushPiece(next, r, r.x, iy2, r.w, r.y + r.h - iy2);
|
|
4549
|
+
if (r.x < ix) pushPiece(next, r, r.x, iy, ix - r.x, iy2 - iy);
|
|
4550
|
+
if (ix2 < r.x + r.w) pushPiece(next, r, ix2, iy, r.x + r.w - ix2, iy2 - iy);
|
|
4551
|
+
}
|
|
4552
|
+
result = next;
|
|
4553
|
+
}
|
|
4554
|
+
return result;
|
|
4555
|
+
}
|
|
4556
|
+
function pushPiece(dest, r, x, y, w, h) {
|
|
4557
|
+
if (r.data === null || r.data === void 0) {
|
|
4558
|
+
dest.push({
|
|
4559
|
+
x,
|
|
4560
|
+
y,
|
|
4561
|
+
w,
|
|
4562
|
+
h,
|
|
4563
|
+
data: null,
|
|
4564
|
+
type: null
|
|
4565
|
+
});
|
|
4566
|
+
return;
|
|
4567
|
+
}
|
|
4568
|
+
const lx = x - r.x;
|
|
4569
|
+
const ly = y - r.y;
|
|
4570
|
+
const data = new Uint8Array(w * h);
|
|
4571
|
+
for (let row = 0; row < h; row++) {
|
|
4572
|
+
data.set(r.data.subarray((ly + row) * r.w + lx, (ly + row) * r.w + lx + w), row * w);
|
|
4573
|
+
}
|
|
4574
|
+
dest.push({
|
|
4575
|
+
x,
|
|
4576
|
+
y,
|
|
4577
|
+
w,
|
|
4578
|
+
h,
|
|
4579
|
+
data,
|
|
4580
|
+
type: 1 /* BINARY */
|
|
4581
|
+
});
|
|
4582
|
+
}
|
|
4583
|
+
|
|
4584
|
+
// src/Rect/getRectsBounds.ts
|
|
4585
|
+
function getRectsBounds(rects) {
|
|
4586
|
+
if (rects.length === 1) return {
|
|
4587
|
+
...rects[0]
|
|
4588
|
+
};
|
|
4589
|
+
let minX = Infinity, minY = Infinity;
|
|
4590
|
+
let maxX = -Infinity, maxY = -Infinity;
|
|
4591
|
+
for (let i = 0; i < rects.length; i++) {
|
|
4592
|
+
const r = rects[i];
|
|
4593
|
+
const x1 = r.x;
|
|
4594
|
+
const y1 = r.y;
|
|
4595
|
+
const x2 = x1 + r.w;
|
|
4596
|
+
const y2 = y1 + r.h;
|
|
4597
|
+
if (x1 < minX) minX = x1;
|
|
4598
|
+
if (y1 < minY) minY = y1;
|
|
4599
|
+
if (x2 > maxX) maxX = x2;
|
|
4600
|
+
if (y2 > maxY) maxY = y2;
|
|
4601
|
+
}
|
|
4602
|
+
return {
|
|
4603
|
+
x: minX,
|
|
4604
|
+
y: minY,
|
|
4605
|
+
w: maxX - minX,
|
|
4606
|
+
h: maxY - minY
|
|
4607
|
+
};
|
|
4608
|
+
}
|
|
4609
|
+
|
|
4610
|
+
// src/MaskRect/merge2BinaryMaskRects.ts
|
|
4611
|
+
function merge2BinaryMaskRects(a, b) {
|
|
4612
|
+
const bounds = getRectsBounds([a, b]);
|
|
4613
|
+
if ((a.data === null || a.data === void 0) && (b.data === null || b.data === void 0)) {
|
|
4614
|
+
const ix = Math.max(a.x, b.x);
|
|
4615
|
+
const iy = Math.max(a.y, b.y);
|
|
4616
|
+
const ir = Math.min(a.x + a.w, b.x + b.w);
|
|
4617
|
+
const ib = Math.min(a.y + a.h, b.y + b.h);
|
|
4618
|
+
const iw = Math.max(0, ir - ix);
|
|
4619
|
+
const ih = Math.max(0, ib - iy);
|
|
4620
|
+
const intersectionArea = iw * ih;
|
|
4621
|
+
const areaA = a.w * a.h;
|
|
4622
|
+
const areaB = b.w * b.h;
|
|
4623
|
+
const boundsArea = bounds.w * bounds.h;
|
|
4624
|
+
if (boundsArea === areaA + areaB - intersectionArea) {
|
|
4625
|
+
return {
|
|
4626
|
+
...bounds,
|
|
4627
|
+
data: null,
|
|
4628
|
+
type: null
|
|
4629
|
+
};
|
|
4630
|
+
}
|
|
4631
|
+
}
|
|
4632
|
+
const maskData = new Uint8Array(bounds.w * bounds.h);
|
|
4633
|
+
const aOffY = a.y - bounds.y;
|
|
4634
|
+
const aOffX = a.x - bounds.x;
|
|
4635
|
+
if (a.data === void 0 || a.data === null) {
|
|
4636
|
+
for (let ay = 0; ay < a.h; ay++) {
|
|
4637
|
+
const destRow = (aOffY + ay) * bounds.w + aOffX;
|
|
4638
|
+
maskData.fill(1, destRow, destRow + a.w);
|
|
4639
|
+
}
|
|
4640
|
+
} else {
|
|
4641
|
+
for (let ay = 0; ay < a.h; ay++) {
|
|
4642
|
+
const srcRow = ay * a.w;
|
|
4643
|
+
const destRow = (aOffY + ay) * bounds.w + aOffX;
|
|
4644
|
+
maskData.set(a.data.subarray(srcRow, srcRow + a.w), destRow);
|
|
4645
|
+
}
|
|
4646
|
+
}
|
|
4647
|
+
const bOffY = b.y - bounds.y;
|
|
4648
|
+
const bOffX = b.x - bounds.x;
|
|
4649
|
+
if (b.data === void 0 || b.data === null) {
|
|
4650
|
+
for (let by = 0; by < b.h; by++) {
|
|
4651
|
+
const destRow = (bOffY + by) * bounds.w + bOffX;
|
|
4652
|
+
maskData.fill(1, destRow, destRow + b.w);
|
|
4653
|
+
}
|
|
4654
|
+
} else {
|
|
4655
|
+
for (let by = 0; by < b.h; by++) {
|
|
4656
|
+
const srcRow = by * b.w;
|
|
4657
|
+
const destRow = (bOffY + by) * bounds.w + bOffX;
|
|
4658
|
+
for (let bx = 0; bx < b.w; bx++) {
|
|
4659
|
+
maskData[destRow + bx] |= b.data[srcRow + bx];
|
|
4660
|
+
}
|
|
4661
|
+
}
|
|
4662
|
+
}
|
|
4663
|
+
return {
|
|
4664
|
+
...bounds,
|
|
4665
|
+
data: maskData,
|
|
4666
|
+
type: 1 /* BINARY */
|
|
4667
|
+
};
|
|
4668
|
+
}
|
|
4669
|
+
|
|
4670
|
+
// src/MaskRect/mergeBinaryMaskRects.ts
|
|
4671
|
+
function mergeBinaryMaskRects(current, adding) {
|
|
4672
|
+
const rects = [...current, ...adding];
|
|
4673
|
+
let changed = true;
|
|
4674
|
+
while (changed) {
|
|
4675
|
+
changed = false;
|
|
4676
|
+
const next = [];
|
|
4677
|
+
for (const r of rects) {
|
|
4678
|
+
let merged = false;
|
|
4679
|
+
for (let i = 0; i < next.length; i++) {
|
|
4680
|
+
const n = next[i];
|
|
4681
|
+
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;
|
|
4682
|
+
if (overlap) {
|
|
4683
|
+
next[i] = merge2BinaryMaskRects(n, r);
|
|
4684
|
+
merged = true;
|
|
4685
|
+
changed = true;
|
|
4686
|
+
break;
|
|
4687
|
+
}
|
|
4688
|
+
}
|
|
4689
|
+
if (!merged) next.push(r);
|
|
4690
|
+
}
|
|
4691
|
+
rects.splice(0, rects.length, ...next);
|
|
4692
|
+
}
|
|
4693
|
+
return rects;
|
|
4694
|
+
}
|
|
4695
|
+
|
|
4096
4696
|
// src/PixelData/PixelData.ts
|
|
4097
4697
|
var PixelData = class _PixelData {
|
|
4098
4698
|
data32;
|
|
@@ -4133,223 +4733,6 @@ var PixelData = class _PixelData {
|
|
|
4133
4733
|
}
|
|
4134
4734
|
};
|
|
4135
4735
|
|
|
4136
|
-
// src/PixelData/blendPixelDataAlphaMask.ts
|
|
4137
|
-
function blendPixelDataAlphaMask(dst, src, alphaMask, opts = {}) {
|
|
4138
|
-
const {
|
|
4139
|
-
x: targetX = 0,
|
|
4140
|
-
y: targetY = 0,
|
|
4141
|
-
sx: sourceX = 0,
|
|
4142
|
-
sy: sourceY = 0,
|
|
4143
|
-
w: width = src.width,
|
|
4144
|
-
h: height = src.height,
|
|
4145
|
-
alpha: globalAlpha = 255,
|
|
4146
|
-
blendFn = sourceOverPerfect,
|
|
4147
|
-
mw = src.width,
|
|
4148
|
-
mx = 0,
|
|
4149
|
-
my = 0,
|
|
4150
|
-
invertMask = false
|
|
4151
|
-
} = opts;
|
|
4152
|
-
if (globalAlpha === 0) return;
|
|
4153
|
-
let x = targetX;
|
|
4154
|
-
let y = targetY;
|
|
4155
|
-
let sx = sourceX;
|
|
4156
|
-
let sy = sourceY;
|
|
4157
|
-
let w = width;
|
|
4158
|
-
let h = height;
|
|
4159
|
-
if (sx < 0) {
|
|
4160
|
-
x -= sx;
|
|
4161
|
-
w += sx;
|
|
4162
|
-
sx = 0;
|
|
4163
|
-
}
|
|
4164
|
-
if (sy < 0) {
|
|
4165
|
-
y -= sy;
|
|
4166
|
-
h += sy;
|
|
4167
|
-
sy = 0;
|
|
4168
|
-
}
|
|
4169
|
-
w = Math.min(w, src.width - sx);
|
|
4170
|
-
h = Math.min(h, src.height - sy);
|
|
4171
|
-
if (x < 0) {
|
|
4172
|
-
sx -= x;
|
|
4173
|
-
w += x;
|
|
4174
|
-
x = 0;
|
|
4175
|
-
}
|
|
4176
|
-
if (y < 0) {
|
|
4177
|
-
sy -= y;
|
|
4178
|
-
h += y;
|
|
4179
|
-
y = 0;
|
|
4180
|
-
}
|
|
4181
|
-
const actualW = Math.min(w, dst.width - x);
|
|
4182
|
-
const actualH = Math.min(h, dst.height - y);
|
|
4183
|
-
if (actualW <= 0 || actualH <= 0) return;
|
|
4184
|
-
const dw = dst.width;
|
|
4185
|
-
const sw = src.width;
|
|
4186
|
-
const mPitch = mw;
|
|
4187
|
-
const dx = x - targetX | 0;
|
|
4188
|
-
const dy = y - targetY | 0;
|
|
4189
|
-
const dst32 = dst.data32;
|
|
4190
|
-
const src32 = src.data32;
|
|
4191
|
-
let dIdx = y * dw + x | 0;
|
|
4192
|
-
let sIdx = sy * sw + sx | 0;
|
|
4193
|
-
let mIdx = (my + dy) * mPitch + (mx + dx) | 0;
|
|
4194
|
-
const dStride = dw - actualW | 0;
|
|
4195
|
-
const sStride = sw - actualW | 0;
|
|
4196
|
-
const mStride = mPitch - actualW | 0;
|
|
4197
|
-
const isOpaque = globalAlpha === 255;
|
|
4198
|
-
const isOverwrite = blendFn.isOverwrite || false;
|
|
4199
|
-
for (let iy = 0; iy < actualH; iy++) {
|
|
4200
|
-
for (let ix = 0; ix < actualW; ix++) {
|
|
4201
|
-
const mVal = alphaMask[mIdx];
|
|
4202
|
-
const effM = invertMask ? 255 - mVal : mVal;
|
|
4203
|
-
if (effM === 0) {
|
|
4204
|
-
dIdx++;
|
|
4205
|
-
sIdx++;
|
|
4206
|
-
mIdx++;
|
|
4207
|
-
continue;
|
|
4208
|
-
}
|
|
4209
|
-
const srcCol = src32[sIdx];
|
|
4210
|
-
const srcAlpha = srcCol >>> 24;
|
|
4211
|
-
if (srcAlpha === 0 && !isOverwrite) {
|
|
4212
|
-
dIdx++;
|
|
4213
|
-
sIdx++;
|
|
4214
|
-
mIdx++;
|
|
4215
|
-
continue;
|
|
4216
|
-
}
|
|
4217
|
-
let weight = globalAlpha;
|
|
4218
|
-
if (isOpaque) {
|
|
4219
|
-
weight = effM;
|
|
4220
|
-
} else if (effM !== 255) {
|
|
4221
|
-
weight = effM * globalAlpha + 128 >> 8;
|
|
4222
|
-
}
|
|
4223
|
-
if (weight === 0) {
|
|
4224
|
-
dIdx++;
|
|
4225
|
-
sIdx++;
|
|
4226
|
-
mIdx++;
|
|
4227
|
-
continue;
|
|
4228
|
-
}
|
|
4229
|
-
let finalCol = srcCol;
|
|
4230
|
-
if (weight < 255) {
|
|
4231
|
-
const a = srcAlpha * weight + 128 >> 8;
|
|
4232
|
-
if (a === 0 && !isOverwrite) {
|
|
4233
|
-
dIdx++;
|
|
4234
|
-
sIdx++;
|
|
4235
|
-
mIdx++;
|
|
4236
|
-
continue;
|
|
4237
|
-
}
|
|
4238
|
-
finalCol = (srcCol & 16777215 | a << 24) >>> 0;
|
|
4239
|
-
}
|
|
4240
|
-
dst32[dIdx] = blendFn(finalCol, dst32[dIdx]);
|
|
4241
|
-
dIdx++;
|
|
4242
|
-
sIdx++;
|
|
4243
|
-
mIdx++;
|
|
4244
|
-
}
|
|
4245
|
-
dIdx += dStride;
|
|
4246
|
-
sIdx += sStride;
|
|
4247
|
-
mIdx += mStride;
|
|
4248
|
-
}
|
|
4249
|
-
}
|
|
4250
|
-
|
|
4251
|
-
// src/PixelData/blendPixelDataBinaryMask.ts
|
|
4252
|
-
function blendPixelDataBinaryMask(dst, src, binaryMask, opts) {
|
|
4253
|
-
const {
|
|
4254
|
-
x: targetX = 0,
|
|
4255
|
-
y: targetY = 0,
|
|
4256
|
-
sx: sourceX = 0,
|
|
4257
|
-
sy: sourceY = 0,
|
|
4258
|
-
w: width = src.width,
|
|
4259
|
-
h: height = src.height,
|
|
4260
|
-
alpha: globalAlpha = 255,
|
|
4261
|
-
blendFn = sourceOverPerfect,
|
|
4262
|
-
mw = src.width,
|
|
4263
|
-
mx = 0,
|
|
4264
|
-
my = 0,
|
|
4265
|
-
invertMask = false
|
|
4266
|
-
} = opts;
|
|
4267
|
-
if (globalAlpha === 0) return;
|
|
4268
|
-
let x = targetX;
|
|
4269
|
-
let y = targetY;
|
|
4270
|
-
let sx = sourceX;
|
|
4271
|
-
let sy = sourceY;
|
|
4272
|
-
let w = width;
|
|
4273
|
-
let h = height;
|
|
4274
|
-
if (sx < 0) {
|
|
4275
|
-
x -= sx;
|
|
4276
|
-
w += sx;
|
|
4277
|
-
sx = 0;
|
|
4278
|
-
}
|
|
4279
|
-
if (sy < 0) {
|
|
4280
|
-
y -= sy;
|
|
4281
|
-
h += sy;
|
|
4282
|
-
sy = 0;
|
|
4283
|
-
}
|
|
4284
|
-
w = Math.min(w, src.width - sx);
|
|
4285
|
-
h = Math.min(h, src.height - sy);
|
|
4286
|
-
if (x < 0) {
|
|
4287
|
-
sx -= x;
|
|
4288
|
-
w += x;
|
|
4289
|
-
x = 0;
|
|
4290
|
-
}
|
|
4291
|
-
if (y < 0) {
|
|
4292
|
-
sy -= y;
|
|
4293
|
-
h += y;
|
|
4294
|
-
y = 0;
|
|
4295
|
-
}
|
|
4296
|
-
const actualW = Math.min(w, dst.width - x);
|
|
4297
|
-
const actualH = Math.min(h, dst.height - y);
|
|
4298
|
-
if (actualW <= 0 || actualH <= 0) return;
|
|
4299
|
-
const dx = x - targetX | 0;
|
|
4300
|
-
const dy = y - targetY | 0;
|
|
4301
|
-
const dst32 = dst.data32;
|
|
4302
|
-
const src32 = src.data32;
|
|
4303
|
-
const dw = dst.width;
|
|
4304
|
-
const sw = src.width;
|
|
4305
|
-
const mPitch = mw;
|
|
4306
|
-
let dIdx = y * dw + x | 0;
|
|
4307
|
-
let sIdx = sy * sw + sx | 0;
|
|
4308
|
-
let mIdx = (my + dy) * mPitch + (mx + dx) | 0;
|
|
4309
|
-
const dStride = dw - actualW | 0;
|
|
4310
|
-
const sStride = sw - actualW | 0;
|
|
4311
|
-
const mStride = mPitch - actualW | 0;
|
|
4312
|
-
const skipVal = invertMask ? 1 : 0;
|
|
4313
|
-
const isOpaque = globalAlpha === 255;
|
|
4314
|
-
const isOverwrite = blendFn.isOverwrite || false;
|
|
4315
|
-
for (let iy = 0; iy < actualH; iy++) {
|
|
4316
|
-
for (let ix = 0; ix < actualW; ix++) {
|
|
4317
|
-
if (binaryMask[mIdx] === skipVal) {
|
|
4318
|
-
dIdx++;
|
|
4319
|
-
sIdx++;
|
|
4320
|
-
mIdx++;
|
|
4321
|
-
continue;
|
|
4322
|
-
}
|
|
4323
|
-
const srcCol = src32[sIdx];
|
|
4324
|
-
const srcAlpha = srcCol >>> 24;
|
|
4325
|
-
if (srcAlpha === 0 && !isOverwrite) {
|
|
4326
|
-
dIdx++;
|
|
4327
|
-
sIdx++;
|
|
4328
|
-
mIdx++;
|
|
4329
|
-
continue;
|
|
4330
|
-
}
|
|
4331
|
-
let finalCol = srcCol;
|
|
4332
|
-
if (!isOpaque) {
|
|
4333
|
-
const a = srcAlpha * globalAlpha + 128 >> 8;
|
|
4334
|
-
if (a === 0 && !isOverwrite) {
|
|
4335
|
-
dIdx++;
|
|
4336
|
-
sIdx++;
|
|
4337
|
-
mIdx++;
|
|
4338
|
-
continue;
|
|
4339
|
-
}
|
|
4340
|
-
finalCol = (srcCol & 16777215 | a << 24) >>> 0;
|
|
4341
|
-
}
|
|
4342
|
-
dst32[dIdx] = blendFn(finalCol, dst32[dIdx]);
|
|
4343
|
-
dIdx++;
|
|
4344
|
-
sIdx++;
|
|
4345
|
-
mIdx++;
|
|
4346
|
-
}
|
|
4347
|
-
dIdx += dStride;
|
|
4348
|
-
sIdx += sStride;
|
|
4349
|
-
mIdx += mStride;
|
|
4350
|
-
}
|
|
4351
|
-
}
|
|
4352
|
-
|
|
4353
4736
|
// src/PixelData/clearPixelData.ts
|
|
4354
4737
|
function clearPixelData(dst, rect) {
|
|
4355
4738
|
fillPixelData(dst, 0, rect);
|
|
@@ -4442,10 +4825,11 @@ function pixelDataToAlphaMask(pixelData) {
|
|
|
4442
4825
|
height
|
|
4443
4826
|
} = pixelData;
|
|
4444
4827
|
const len = data32.length;
|
|
4445
|
-
const mask =
|
|
4828
|
+
const mask = makeAlphaMask(width, height);
|
|
4829
|
+
const maskData = mask.data;
|
|
4446
4830
|
for (let i = 0; i < len; i++) {
|
|
4447
4831
|
const val = data32[i];
|
|
4448
|
-
|
|
4832
|
+
maskData[i] = val >>> 24 & 255;
|
|
4449
4833
|
}
|
|
4450
4834
|
return mask;
|
|
4451
4835
|
}
|
|
@@ -4626,11 +5010,13 @@ export {
|
|
|
4626
5010
|
exclusionPerfect,
|
|
4627
5011
|
extractImageDataBuffer,
|
|
4628
5012
|
extractMask,
|
|
5013
|
+
extractMaskBuffer,
|
|
4629
5014
|
extractPixelData,
|
|
4630
5015
|
extractPixelDataBuffer,
|
|
4631
5016
|
fileInputChangeToImageData,
|
|
4632
5017
|
fileToImageData,
|
|
4633
5018
|
fillPixelData,
|
|
5019
|
+
fillPixelDataBinaryMask,
|
|
4634
5020
|
floodFillSelection,
|
|
4635
5021
|
forEachLinePoint,
|
|
4636
5022
|
getCircleBrushOrPencilBounds,
|
|
@@ -4639,12 +5025,13 @@ export {
|
|
|
4639
5025
|
getIndexedImageColorCounts,
|
|
4640
5026
|
getRectBrushOrPencilBounds,
|
|
4641
5027
|
getRectBrushOrPencilStrokeBounds,
|
|
5028
|
+
getRectsBounds,
|
|
4642
5029
|
getSupportedPixelFormats,
|
|
4643
5030
|
hardLightFast,
|
|
4644
5031
|
hardLightPerfect,
|
|
4645
5032
|
hardMixFast,
|
|
4646
5033
|
hardMixPerfect,
|
|
4647
|
-
|
|
5034
|
+
imageDataToAlphaMaskBuffer,
|
|
4648
5035
|
imageDataToDataUrl,
|
|
4649
5036
|
imageDataToImgBlob,
|
|
4650
5037
|
imageDataToUInt32Array,
|
|
@@ -4667,7 +5054,11 @@ export {
|
|
|
4667
5054
|
linearDodgePerfect,
|
|
4668
5055
|
linearLightFast,
|
|
4669
5056
|
linearLightPerfect,
|
|
5057
|
+
makeAlphaMask,
|
|
5058
|
+
makeBinaryMask,
|
|
4670
5059
|
makeBlendModeRegistry,
|
|
5060
|
+
makeCircleBrushAlphaMask,
|
|
5061
|
+
makeCircleBrushBinaryMask,
|
|
4671
5062
|
makeFastBlendModeRegistry,
|
|
4672
5063
|
makeFullPixelMutator,
|
|
4673
5064
|
makeImageDataLike,
|
|
@@ -4675,7 +5066,9 @@ export {
|
|
|
4675
5066
|
makePixelCanvas,
|
|
4676
5067
|
makeReusableCanvas,
|
|
4677
5068
|
makeReusableImageData,
|
|
5069
|
+
merge2BinaryMaskRects,
|
|
4678
5070
|
mergeAlphaMasks,
|
|
5071
|
+
mergeBinaryMaskRects,
|
|
4679
5072
|
mergeBinaryMasks,
|
|
4680
5073
|
multiplyFast,
|
|
4681
5074
|
multiplyPerfect,
|
|
@@ -4692,8 +5085,11 @@ export {
|
|
|
4692
5085
|
mutatorBlendColor,
|
|
4693
5086
|
mutatorBlendPixel,
|
|
4694
5087
|
mutatorBlendPixelData,
|
|
5088
|
+
mutatorBlendPixelDataAlphaMask,
|
|
5089
|
+
mutatorBlendPixelDataBinaryMask,
|
|
4695
5090
|
mutatorClear,
|
|
4696
5091
|
mutatorFill,
|
|
5092
|
+
mutatorFillBinaryMask,
|
|
4697
5093
|
mutatorInvert,
|
|
4698
5094
|
overlayFast,
|
|
4699
5095
|
overlayPerfect,
|
|
@@ -4716,10 +5112,12 @@ export {
|
|
|
4716
5112
|
screenPerfect,
|
|
4717
5113
|
serializeImageData,
|
|
4718
5114
|
serializeNullableImageData,
|
|
5115
|
+
setMaskData,
|
|
4719
5116
|
softLightFast,
|
|
4720
5117
|
softLightPerfect,
|
|
4721
5118
|
sourceOverFast,
|
|
4722
5119
|
sourceOverPerfect,
|
|
5120
|
+
subtractBinaryMaskRects,
|
|
4723
5121
|
subtractFast,
|
|
4724
5122
|
subtractPerfect,
|
|
4725
5123
|
toBlendModeIndexAndName,
|