pixel-data-js 0.27.0 → 0.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -2
- package/dist/index.prod.cjs +2355 -1124
- package/dist/index.prod.cjs.map +1 -1
- package/dist/index.prod.d.ts +558 -424
- package/dist/index.prod.js +2304 -1115
- package/dist/index.prod.js.map +1 -1
- package/package.json +11 -11
- package/src/Algorithm/floodFillSelection.ts +8 -6
- package/src/Algorithm/forEachLinePoint.ts +6 -6
- package/src/{Internal/resample32.ts → Algorithm/resampleUint32Array.ts} +11 -21
- package/src/BlendModes/blend-modes-fast.ts +169 -0
- package/src/BlendModes/blend-modes-perfect.ts +207 -0
- package/src/BlendModes/blend-modes.ts +9 -0
- package/src/Canvas/CanvasFrameRenderer.ts +20 -28
- package/src/Canvas/CanvasPixelDataRenderer.ts +23 -0
- package/src/Canvas/PixelCanvas.ts +2 -7
- package/src/Canvas/ReusableCanvas.ts +4 -12
- package/src/Canvas/_canvas-types.ts +26 -0
- package/src/History/PixelAccumulator.ts +17 -17
- package/src/History/PixelEngineConfig.ts +3 -3
- package/src/History/PixelMutator/mutatorApplyAlphaMask.ts +4 -3
- package/src/History/PixelMutator/mutatorApplyBinaryMask.ts +4 -3
- package/src/History/PixelMutator/mutatorApplyMask.ts +4 -3
- package/src/History/PixelMutator/mutatorBlendAlphaMask.ts +6 -4
- package/src/History/PixelMutator/mutatorBlendBinaryMask.ts +6 -4
- package/src/History/PixelMutator/mutatorBlendColor.ts +2 -2
- package/src/History/PixelMutator/mutatorBlendColorPaintAlphaMask.ts +2 -1
- package/src/History/PixelMutator/mutatorBlendColorPaintBinaryMask.ts +2 -1
- package/src/History/PixelMutator/mutatorBlendColorPaintMask.ts +3 -1
- package/src/History/PixelMutator/mutatorBlendColorPaintRect.ts +3 -3
- package/src/History/PixelMutator/mutatorBlendMask.ts +6 -4
- package/src/History/PixelMutator/mutatorBlendPixelData.ts +5 -4
- package/src/History/PixelMutator/mutatorClear.ts +4 -3
- package/src/History/PixelMutator/mutatorFill.ts +5 -4
- package/src/History/PixelMutator/mutatorFillBinaryMask.ts +2 -1
- package/src/History/PixelMutator/mutatorInvert.ts +2 -2
- package/src/History/PixelMutator.ts +1 -1
- package/src/History/PixelPatchTiles.ts +7 -7
- package/src/History/PixelWriter.ts +12 -63
- package/src/ImageData/ImageDataLike.ts +1 -1
- package/src/ImageData/_ImageData-types.ts +13 -0
- package/src/ImageData/copyImageData.ts +1 -1
- package/src/ImageData/extractImageDataBuffer.ts +3 -2
- package/src/ImageData/imageDataToUint32Array.ts +18 -0
- package/src/ImageData/resampleImageData.ts +3 -3
- package/src/ImageData/resizeImageData.ts +1 -1
- package/src/ImageData/serialization.ts +1 -1
- package/src/ImageData/uInt32ArrayToImageData.ts +1 -1
- package/src/ImageData/writeImageData.ts +2 -2
- package/src/ImageData/writeImageDataBuffer.ts +2 -2
- package/src/IndexedImage/IndexedImage.ts +56 -98
- package/src/IndexedImage/_indexedImage-types.ts +18 -0
- package/src/IndexedImage/getIndexedImageColorCounts.ts +3 -3
- package/src/IndexedImage/indexedImageToAverageColor.ts +1 -1
- package/src/IndexedImage/indexedImageToImageData.ts +4 -6
- package/src/IndexedImage/resampleIndexedImage.ts +7 -15
- package/src/Input/fileToImageData.ts +1 -1
- package/src/Internal/_constants.ts +3 -0
- package/src/Internal/_errors.ts +2 -0
- package/src/Internal/macros.ts +14 -0
- package/src/Mask/AlphaMask.ts +1 -1
- package/src/Mask/BinaryMask/makeBinaryMaskFromAlphaMask.ts +23 -0
- package/src/Mask/BinaryMask/makeBinaryMaskOutline.ts +88 -0
- package/src/Mask/BinaryMask/makeCircleBinaryMaskOutline.ts +104 -0
- package/src/Mask/BinaryMask/makeRectBinaryMaskOutline.ts +34 -0
- package/src/Mask/BinaryMask.ts +1 -1
- package/src/Mask/_mask-types.ts +73 -0
- package/src/Mask/applyBinaryMaskToAlphaMask.ts +2 -1
- package/src/Mask/copyMask.ts +1 -1
- package/src/Mask/extractMask.ts +2 -1
- package/src/Mask/extractMaskBuffer.ts +1 -1
- package/src/Mask/mergeAlphaMasks.ts +6 -3
- package/src/Mask/mergeBinaryMasks.ts +2 -1
- package/src/Mask/setMaskData.ts +1 -1
- package/src/MaskRect/merge2BinaryMaskRects.ts +2 -2
- package/src/MaskRect/mergeBinaryMaskRects.ts +1 -1
- package/src/MaskRect/subtractBinaryMaskRects.ts +1 -1
- package/src/Paint/AlphaMaskPaintBuffer.ts +283 -0
- package/src/Paint/BinaryMaskPaintBuffer.ts +198 -0
- package/src/Paint/{PaintBuffer.ts → ColorPaintBuffer.ts} +95 -77
- package/src/Paint/Commit/AlphaMaskPaintBufferCommitter.ts +26 -0
- package/src/Paint/Commit/AlphaMaskPaintBufferManager.ts +34 -0
- package/src/Paint/Commit/BinaryMaskPaintBufferCommitter.ts +26 -0
- package/src/Paint/Commit/BinaryMaskPaintBufferManager.ts +31 -0
- package/src/Paint/Commit/ColorPaintBufferCommitter.ts +23 -0
- package/src/Paint/Commit/ColorPaintBufferManager.ts +34 -0
- package/src/Paint/Commit/commitColorPaintBuffer.ts +55 -0
- package/src/Paint/Commit/commitMaskPaintBuffer.ts +78 -0
- package/src/Paint/Render/AlphaMaskPaintBufferCanvasRenderer.ts +78 -0
- package/src/Paint/Render/BinaryMaskPaintBufferCanvasRenderer.ts +67 -0
- package/src/Paint/{PaintBufferCanvasRenderer.ts → Render/ColorPaintBufferCanvasRenderer.ts} +13 -14
- package/src/Paint/Render/PaintCursorRenderer.ts +118 -0
- package/src/Paint/_paint-types.ts +22 -0
- package/src/Paint/eachTileInBounds.ts +45 -0
- package/src/Paint/makeCirclePaintMask.ts +74 -0
- package/src/Paint/makePaintMask.ts +5 -2
- package/src/Paint/makeRectFalloffPaintAlphaMask.ts +4 -2
- package/src/PixelData/PixelData.ts +15 -19
- package/src/PixelData/ReusablePixelData.ts +36 -0
- package/src/PixelData/_pixelData-types.ts +17 -0
- package/src/PixelData/applyAlphaMaskToPixelData.ts +80 -43
- package/src/PixelData/applyBinaryMaskToPixelData.ts +10 -8
- package/src/PixelData/applyMaskToPixelData.ts +4 -9
- package/src/PixelData/blendColorPixelData.ts +9 -8
- package/src/PixelData/blendColorPixelDataAlphaMask.ts +9 -7
- package/src/PixelData/blendColorPixelDataBinaryMask.ts +9 -7
- package/src/PixelData/blendColorPixelDataMask.ts +4 -2
- package/src/PixelData/blendColorPixelDataPaintAlphaMask.ts +4 -2
- package/src/PixelData/blendColorPixelDataPaintBinaryMask.ts +4 -2
- package/src/PixelData/blendColorPixelDataPaintMask.ts +5 -2
- package/src/PixelData/blendPixel.ts +6 -5
- package/src/PixelData/blendPixelData.ts +14 -13
- package/src/PixelData/blendPixelDataAlphaMask.ts +15 -13
- package/src/PixelData/blendPixelDataBinaryMask.ts +15 -13
- package/src/PixelData/blendPixelDataMask.ts +5 -3
- package/src/PixelData/blendPixelDataPaintBuffer.ts +5 -4
- package/src/PixelData/clearPixelDataFast.ts +4 -2
- package/src/PixelData/copyPixelData.ts +14 -0
- package/src/PixelData/extractPixelData.ts +8 -7
- package/src/PixelData/extractPixelDataBuffer.ts +9 -8
- package/src/PixelData/fillPixelData.ts +16 -14
- package/src/PixelData/fillPixelDataBinaryMask.ts +10 -8
- package/src/PixelData/fillPixelDataFast.ts +16 -14
- package/src/PixelData/invertPixelData.ts +9 -8
- package/src/PixelData/pixelDataToAlphaMask.ts +9 -8
- package/src/PixelData/reflectPixelData.ts +9 -9
- package/src/PixelData/resamplePixelData.ts +20 -9
- package/src/PixelData/rotatePixelData.ts +8 -7
- package/src/PixelData/uInt32ArrayToPixelData.ts +15 -0
- package/src/PixelData/writePaintBufferToPixelData.ts +5 -5
- package/src/PixelData/writePixelDataBuffer.ts +10 -9
- package/src/Rect/_rect-types.ts +7 -0
- package/src/Rect/getRectsBounds.ts +1 -1
- package/src/Rect/trimMaskRectBounds.ts +2 -1
- package/src/Rect/trimRectBounds.ts +1 -1
- package/src/Tile/MaskTile.ts +40 -0
- package/src/Tile/PixelTile.ts +23 -0
- package/src/{PixelTile/PixelTilePool.ts → Tile/TilePool.ts} +9 -9
- package/src/Tile/_tile-types.ts +33 -0
- package/src/_errors.ts +1 -0
- package/src/_types.ts +2 -118
- package/src/index.ts +57 -21
- package/src/ImageData/imageDataToUInt32Array.ts +0 -13
- package/src/Internal/helpers.ts +0 -5
- package/src/Paint/makeCirclePaintAlphaMask.ts +0 -41
- package/src/Paint/makeCirclePaintBinaryMask.ts +0 -29
- package/src/PixelTile/PixelTile.ts +0 -21
- /package/src/{Internal → Rect}/resolveClipping.ts +0 -0
package/dist/index.prod.js
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __export = (target, all) => {
|
|
3
|
+
for (var name in all)
|
|
4
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
// src/Internal/_errors.ts
|
|
8
|
+
var errors_exports = {};
|
|
9
|
+
__export(errors_exports, {
|
|
10
|
+
CANVAS_CTX_FAILED: () => CANVAS_CTX_FAILED,
|
|
11
|
+
OFFSCREEN_CANVAS_CTX_FAILED: () => OFFSCREEN_CANVAS_CTX_FAILED
|
|
12
|
+
});
|
|
13
|
+
var OFFSCREEN_CANVAS_CTX_FAILED = "Failed to create OffscreenCanvas context";
|
|
14
|
+
var CANVAS_CTX_FAILED = "Failed to create Canvas context";
|
|
7
15
|
|
|
8
16
|
// src/color.ts
|
|
9
17
|
function packColor(r, g, b, a) {
|
|
@@ -78,7 +86,7 @@ function color32ToCssRGBA(color) {
|
|
|
78
86
|
return `rgba(${r},${g},${b},${alpha})`;
|
|
79
87
|
}
|
|
80
88
|
|
|
81
|
-
// src/
|
|
89
|
+
// src/Rect/resolveClipping.ts
|
|
82
90
|
var makeClippedRect = () => ({
|
|
83
91
|
x: 0,
|
|
84
92
|
y: 0,
|
|
@@ -196,6 +204,13 @@ function extractImageDataBuffer(imageData, _x, _y, _w, _h) {
|
|
|
196
204
|
return out;
|
|
197
205
|
}
|
|
198
206
|
|
|
207
|
+
// src/Mask/_mask-types.ts
|
|
208
|
+
var MaskType = /* @__PURE__ */ ((MaskType2) => {
|
|
209
|
+
MaskType2[MaskType2["ALPHA"] = 0] = "ALPHA";
|
|
210
|
+
MaskType2[MaskType2["BINARY"] = 1] = "BINARY";
|
|
211
|
+
return MaskType2;
|
|
212
|
+
})(MaskType || {});
|
|
213
|
+
|
|
199
214
|
// src/Mask/extractMaskBuffer.ts
|
|
200
215
|
function extractMaskBuffer(maskBuffer, maskWidth, xOrRect, y, w, h) {
|
|
201
216
|
let finalX;
|
|
@@ -298,9 +313,9 @@ function trimMaskRectBounds(target, bounds) {
|
|
|
298
313
|
|
|
299
314
|
// src/Algorithm/floodFillSelection.ts
|
|
300
315
|
function floodFillSelection(target, startX, startY, contiguous = true, tolerance = 0, bounds, out) {
|
|
301
|
-
const data32 = target.
|
|
302
|
-
const width = target.
|
|
303
|
-
const height = target.
|
|
316
|
+
const data32 = target.data;
|
|
317
|
+
const width = target.w;
|
|
318
|
+
const height = target.h;
|
|
304
319
|
const lx = bounds?.x ?? 0;
|
|
305
320
|
const ly = bounds?.y ?? 0;
|
|
306
321
|
const lw = bounds?.w ?? width;
|
|
@@ -414,13 +429,13 @@ function floodFillSelection(target, startX, startY, contiguous = true, tolerance
|
|
|
414
429
|
|
|
415
430
|
// src/Algorithm/forEachLinePoint.ts
|
|
416
431
|
function forEachLinePoint(x0, y0, x1, y1, callback) {
|
|
417
|
-
|
|
418
|
-
const dy = y1 - y0;
|
|
419
|
-
const steps = Math.max(Math.abs(dx), Math.abs(dy));
|
|
420
|
-
if (steps === 0) {
|
|
432
|
+
if (x0 === x1 && y0 === y1) {
|
|
421
433
|
callback(x0, y0);
|
|
422
434
|
return;
|
|
423
435
|
}
|
|
436
|
+
const dx = x1 - x0;
|
|
437
|
+
const dy = y1 - y0;
|
|
438
|
+
const steps = Math.max(Math.abs(dx), Math.abs(dy));
|
|
424
439
|
const xInc = dx / steps;
|
|
425
440
|
const yInc = dy / steps;
|
|
426
441
|
let curX = x0;
|
|
@@ -432,6 +447,66 @@ function forEachLinePoint(x0, y0, x1, y1, callback) {
|
|
|
432
447
|
}
|
|
433
448
|
}
|
|
434
449
|
|
|
450
|
+
// src/Algorithm/resampleUint32Array.ts
|
|
451
|
+
function resampleUint32Array(srcData32, srcW, srcH, factor, out) {
|
|
452
|
+
const dstW = Math.max(1, srcW * factor | 0);
|
|
453
|
+
const dstH = Math.max(1, srcH * factor | 0);
|
|
454
|
+
const dstData = new Uint32Array(dstW * dstH);
|
|
455
|
+
const scaleX = srcW / dstW;
|
|
456
|
+
const scaleY = srcH / dstH;
|
|
457
|
+
for (let y = 0; y < dstH; y++) {
|
|
458
|
+
const srcY = Math.min(srcH - 1, y * scaleY | 0);
|
|
459
|
+
const srcRowOffset = srcY * srcW;
|
|
460
|
+
const dstRowOffset = y * dstW;
|
|
461
|
+
for (let x = 0; x < dstW; x++) {
|
|
462
|
+
const srcX = Math.min(srcW - 1, x * scaleX | 0);
|
|
463
|
+
dstData[dstRowOffset + x] = srcData32[srcRowOffset + srcX];
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
out = out ?? {};
|
|
467
|
+
out.data = dstData;
|
|
468
|
+
out.w = dstW;
|
|
469
|
+
out.h = dstH;
|
|
470
|
+
return out;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
// src/BlendModes/blend-modes.ts
|
|
474
|
+
var BaseBlendMode = {
|
|
475
|
+
overwrite: 0,
|
|
476
|
+
sourceOver: 1,
|
|
477
|
+
darken: 2,
|
|
478
|
+
multiply: 3,
|
|
479
|
+
colorBurn: 4,
|
|
480
|
+
linearBurn: 5,
|
|
481
|
+
darkerColor: 6,
|
|
482
|
+
lighten: 7,
|
|
483
|
+
screen: 8,
|
|
484
|
+
colorDodge: 9,
|
|
485
|
+
linearDodge: 10,
|
|
486
|
+
lighterColor: 11,
|
|
487
|
+
overlay: 12,
|
|
488
|
+
softLight: 13,
|
|
489
|
+
hardLight: 14,
|
|
490
|
+
vividLight: 15,
|
|
491
|
+
linearLight: 16,
|
|
492
|
+
pinLight: 17,
|
|
493
|
+
hardMix: 18,
|
|
494
|
+
difference: 19,
|
|
495
|
+
exclusion: 20,
|
|
496
|
+
subtract: 21,
|
|
497
|
+
divide: 22,
|
|
498
|
+
sourceIn: 23,
|
|
499
|
+
sourceOut: 24,
|
|
500
|
+
sourceAtop: 25,
|
|
501
|
+
destinationOver: 26,
|
|
502
|
+
destinationIn: 27,
|
|
503
|
+
destinationOut: 28,
|
|
504
|
+
destinationAtop: 29,
|
|
505
|
+
xor: 30
|
|
506
|
+
};
|
|
507
|
+
var overwriteBase = (src, _dst) => src;
|
|
508
|
+
overwriteBase.isOverwrite = true;
|
|
509
|
+
|
|
435
510
|
// src/BlendModes/BlendModeRegistry.ts
|
|
436
511
|
function makeBlendModeRegistry(blendModes, initialEntries, registryName = "anonymous") {
|
|
437
512
|
const blendToName = /* @__PURE__ */ new Map();
|
|
@@ -471,37 +546,134 @@ function makeBlendModeRegistry(blendModes, initialEntries, registryName = "anony
|
|
|
471
546
|
};
|
|
472
547
|
}
|
|
473
548
|
|
|
474
|
-
// src/BlendModes/blend-modes.ts
|
|
475
|
-
var BaseBlendMode = {
|
|
476
|
-
overwrite: 0,
|
|
477
|
-
sourceOver: 1,
|
|
478
|
-
darken: 2,
|
|
479
|
-
multiply: 3,
|
|
480
|
-
colorBurn: 4,
|
|
481
|
-
linearBurn: 5,
|
|
482
|
-
darkerColor: 6,
|
|
483
|
-
lighten: 7,
|
|
484
|
-
screen: 8,
|
|
485
|
-
colorDodge: 9,
|
|
486
|
-
linearDodge: 10,
|
|
487
|
-
lighterColor: 11,
|
|
488
|
-
overlay: 12,
|
|
489
|
-
softLight: 13,
|
|
490
|
-
hardLight: 14,
|
|
491
|
-
vividLight: 15,
|
|
492
|
-
linearLight: 16,
|
|
493
|
-
pinLight: 17,
|
|
494
|
-
hardMix: 18,
|
|
495
|
-
difference: 19,
|
|
496
|
-
exclusion: 20,
|
|
497
|
-
subtract: 21,
|
|
498
|
-
divide: 22
|
|
499
|
-
};
|
|
500
|
-
var overwriteBase = (src, _dst) => src;
|
|
501
|
-
overwriteBase.isOverwrite = true;
|
|
502
|
-
|
|
503
549
|
// src/BlendModes/blend-modes-fast.ts
|
|
504
550
|
var overwriteFast = overwriteBase;
|
|
551
|
+
var sourceInFast = (src, dst) => {
|
|
552
|
+
const da = dst >>> 24 & 255;
|
|
553
|
+
if (da === 0) return 0;
|
|
554
|
+
if (da === 255) return src;
|
|
555
|
+
const sa = src >>> 24 & 255;
|
|
556
|
+
const sr = src & 255;
|
|
557
|
+
const sg = src >>> 8 & 255;
|
|
558
|
+
const sb = src >>> 16 & 255;
|
|
559
|
+
const r = sr * da >> 8;
|
|
560
|
+
const g = sg * da >> 8;
|
|
561
|
+
const b = sb * da >> 8;
|
|
562
|
+
const a = sa * da >> 8;
|
|
563
|
+
return (a << 24 | b << 16 | g << 8 | r) >>> 0;
|
|
564
|
+
};
|
|
565
|
+
var sourceOutFast = (src, dst) => {
|
|
566
|
+
const da = dst >>> 24 & 255;
|
|
567
|
+
if (da === 255) return 0;
|
|
568
|
+
if (da === 0) return src;
|
|
569
|
+
const sa = src >>> 24 & 255;
|
|
570
|
+
const sr = src & 255;
|
|
571
|
+
const sg = src >>> 8 & 255;
|
|
572
|
+
const sb = src >>> 16 & 255;
|
|
573
|
+
const invDa = 255 - da;
|
|
574
|
+
const r = sr * invDa >> 8;
|
|
575
|
+
const g = sg * invDa >> 8;
|
|
576
|
+
const b = sb * invDa >> 8;
|
|
577
|
+
const a = sa * invDa >> 8;
|
|
578
|
+
return (a << 24 | b << 16 | g << 8 | r) >>> 0;
|
|
579
|
+
};
|
|
580
|
+
var sourceAtopFast = (src, dst) => {
|
|
581
|
+
const sa = src >>> 24 & 255;
|
|
582
|
+
const da = dst >>> 24 & 255;
|
|
583
|
+
if (da === 0) return 0;
|
|
584
|
+
const sr = src & 255;
|
|
585
|
+
const sg = src >>> 8 & 255;
|
|
586
|
+
const sb = src >>> 16 & 255;
|
|
587
|
+
const dr = dst & 255;
|
|
588
|
+
const dg = dst >>> 8 & 255;
|
|
589
|
+
const db = dst >>> 16 & 255;
|
|
590
|
+
const invSa = 255 - sa;
|
|
591
|
+
const r = sr * da + dr * invSa >> 8;
|
|
592
|
+
const g = sg * da + dg * invSa >> 8;
|
|
593
|
+
const b = sb * da + db * invSa >> 8;
|
|
594
|
+
return (da << 24 | b << 16 | g << 8 | r) >>> 0;
|
|
595
|
+
};
|
|
596
|
+
var destinationOverFast = (src, dst) => {
|
|
597
|
+
const da = dst >>> 24 & 255;
|
|
598
|
+
if (da === 255) return dst;
|
|
599
|
+
if (da === 0) return src;
|
|
600
|
+
const sa = src >>> 24 & 255;
|
|
601
|
+
const sr = src & 255;
|
|
602
|
+
const sg = src >>> 8 & 255;
|
|
603
|
+
const sb = src >>> 16 & 255;
|
|
604
|
+
const dr = dst & 255;
|
|
605
|
+
const dg = dst >>> 8 & 255;
|
|
606
|
+
const db = dst >>> 16 & 255;
|
|
607
|
+
const invDa = 255 - da;
|
|
608
|
+
const r = dr * 255 + sr * invDa >> 8;
|
|
609
|
+
const g = dg * 255 + sg * invDa >> 8;
|
|
610
|
+
const b = db * 255 + sb * invDa >> 8;
|
|
611
|
+
const a = da * 255 + sa * invDa >> 8;
|
|
612
|
+
return (a << 24 | b << 16 | g << 8 | r) >>> 0;
|
|
613
|
+
};
|
|
614
|
+
var destinationInFast = (src, dst) => {
|
|
615
|
+
const sa = src >>> 24 & 255;
|
|
616
|
+
if (sa === 0) return 0;
|
|
617
|
+
if (sa === 255) return dst;
|
|
618
|
+
const da = dst >>> 24 & 255;
|
|
619
|
+
const dr = dst & 255;
|
|
620
|
+
const dg = dst >>> 8 & 255;
|
|
621
|
+
const db = dst >>> 16 & 255;
|
|
622
|
+
const r = dr * sa >> 8;
|
|
623
|
+
const g = dg * sa >> 8;
|
|
624
|
+
const b = db * sa >> 8;
|
|
625
|
+
const a = da * sa >> 8;
|
|
626
|
+
return (a << 24 | b << 16 | g << 8 | r) >>> 0;
|
|
627
|
+
};
|
|
628
|
+
var destinationOutFast = (src, dst) => {
|
|
629
|
+
const sa = src >>> 24 & 255;
|
|
630
|
+
if (sa === 255) return 0;
|
|
631
|
+
if (sa === 0) return dst;
|
|
632
|
+
const da = dst >>> 24 & 255;
|
|
633
|
+
const dr = dst & 255;
|
|
634
|
+
const dg = dst >>> 8 & 255;
|
|
635
|
+
const db = dst >>> 16 & 255;
|
|
636
|
+
const invSa = 255 - sa;
|
|
637
|
+
const r = dr * invSa >> 8;
|
|
638
|
+
const g = dg * invSa >> 8;
|
|
639
|
+
const b = db * invSa >> 8;
|
|
640
|
+
const a = da * invSa >> 8;
|
|
641
|
+
return (a << 24 | b << 16 | g << 8 | r) >>> 0;
|
|
642
|
+
};
|
|
643
|
+
var destinationAtopFast = (src, dst) => {
|
|
644
|
+
const sa = src >>> 24 & 255;
|
|
645
|
+
if (sa === 0) return 0;
|
|
646
|
+
const da = dst >>> 24 & 255;
|
|
647
|
+
if (da === 0) return 0;
|
|
648
|
+
const sr = src & 255;
|
|
649
|
+
const sg = src >>> 8 & 255;
|
|
650
|
+
const sb = src >>> 16 & 255;
|
|
651
|
+
const dr = dst & 255;
|
|
652
|
+
const dg = dst >>> 8 & 255;
|
|
653
|
+
const db = dst >>> 16 & 255;
|
|
654
|
+
const invDa = 255 - da;
|
|
655
|
+
const r = dr * sa + sr * invDa >> 8;
|
|
656
|
+
const g = dg * sa + sg * invDa >> 8;
|
|
657
|
+
const b = db * sa + sb * invDa >> 8;
|
|
658
|
+
return (sa << 24 | b << 16 | g << 8 | r) >>> 0;
|
|
659
|
+
};
|
|
660
|
+
var xorFast = (src, dst) => {
|
|
661
|
+
const sa = src >>> 24 & 255;
|
|
662
|
+
const da = dst >>> 24 & 255;
|
|
663
|
+
const sr = src & 255;
|
|
664
|
+
const sg = src >>> 8 & 255;
|
|
665
|
+
const sb = src >>> 16 & 255;
|
|
666
|
+
const dr = dst & 255;
|
|
667
|
+
const dg = dst >>> 8 & 255;
|
|
668
|
+
const db = dst >>> 16 & 255;
|
|
669
|
+
const invDa = 255 - da;
|
|
670
|
+
const invSa = 255 - sa;
|
|
671
|
+
const r = sr * invDa + dr * invSa >> 8;
|
|
672
|
+
const g = sg * invDa + dg * invSa >> 8;
|
|
673
|
+
const b = sb * invDa + db * invSa >> 8;
|
|
674
|
+
const a = sa * invDa + da * invSa >> 8;
|
|
675
|
+
return (a << 24 | b << 16 | g << 8 | r) >>> 0;
|
|
676
|
+
};
|
|
505
677
|
var sourceOverFast = (src, dst) => {
|
|
506
678
|
const sa = src >>> 24 & 255;
|
|
507
679
|
if (sa === 255) return src;
|
|
@@ -887,6 +1059,14 @@ var divideFast = (src, dst) => {
|
|
|
887
1059
|
};
|
|
888
1060
|
var BASE_FAST_BLEND_MODE_FUNCTIONS = {
|
|
889
1061
|
[BaseBlendMode.overwrite]: overwriteFast,
|
|
1062
|
+
[BaseBlendMode.sourceIn]: sourceInFast,
|
|
1063
|
+
[BaseBlendMode.sourceOut]: sourceOutFast,
|
|
1064
|
+
[BaseBlendMode.sourceAtop]: sourceAtopFast,
|
|
1065
|
+
[BaseBlendMode.destinationOver]: destinationOverFast,
|
|
1066
|
+
[BaseBlendMode.destinationIn]: destinationInFast,
|
|
1067
|
+
[BaseBlendMode.destinationOut]: destinationOutFast,
|
|
1068
|
+
[BaseBlendMode.destinationAtop]: destinationAtopFast,
|
|
1069
|
+
[BaseBlendMode.xor]: xorFast,
|
|
890
1070
|
[BaseBlendMode.sourceOver]: sourceOverFast,
|
|
891
1071
|
[BaseBlendMode.darken]: darkenFast,
|
|
892
1072
|
[BaseBlendMode.multiply]: multiplyFast,
|
|
@@ -916,115 +1096,271 @@ function makeFastBlendModeRegistry(name = "fast") {
|
|
|
916
1096
|
|
|
917
1097
|
// src/BlendModes/blend-modes-perfect.ts
|
|
918
1098
|
var overwritePerfect = overwriteBase;
|
|
919
|
-
var
|
|
920
|
-
const sa = src >>> 24 & 255;
|
|
921
|
-
if (sa === 255) return src;
|
|
922
|
-
if (sa === 0) return dst;
|
|
1099
|
+
var sourceInPerfect = (src, dst) => {
|
|
923
1100
|
const da = dst >>> 24 & 255;
|
|
924
|
-
if (da === 0) return
|
|
925
|
-
|
|
926
|
-
const
|
|
927
|
-
const
|
|
928
|
-
const
|
|
1101
|
+
if (da === 0) return 0;
|
|
1102
|
+
if (da === 255) return src;
|
|
1103
|
+
const sa = src >>> 24 & 255;
|
|
1104
|
+
const sr = src & 255;
|
|
1105
|
+
const sg = src >>> 8 & 255;
|
|
1106
|
+
const sb = src >>> 16 & 255;
|
|
1107
|
+
const tR = sr * da;
|
|
929
1108
|
const r = tR + 1 + (tR >> 8) >> 8;
|
|
930
|
-
const tG = sg *
|
|
1109
|
+
const tG = sg * da;
|
|
931
1110
|
const g = tG + 1 + (tG >> 8) >> 8;
|
|
932
|
-
const tB = sb *
|
|
1111
|
+
const tB = sb * da;
|
|
933
1112
|
const b = tB + 1 + (tB >> 8) >> 8;
|
|
934
|
-
const tA =
|
|
1113
|
+
const tA = sa * da;
|
|
935
1114
|
const a = tA + 1 + (tA >> 8) >> 8;
|
|
936
1115
|
return (a << 24 | b << 16 | g << 8 | r) >>> 0;
|
|
937
1116
|
};
|
|
938
|
-
var
|
|
939
|
-
const sa = src >>> 24 & 255;
|
|
940
|
-
if (sa === 0) return dst;
|
|
941
|
-
const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
|
|
942
|
-
const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
|
|
943
|
-
const br = sr < dr ? sr : dr;
|
|
944
|
-
const bg = sg < dg ? sg : dg;
|
|
945
|
-
const bb = sb < db ? sb : db;
|
|
946
|
-
if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
|
|
947
|
-
const invA = 255 - sa;
|
|
1117
|
+
var sourceOutPerfect = (src, dst) => {
|
|
948
1118
|
const da = dst >>> 24 & 255;
|
|
949
|
-
|
|
1119
|
+
if (da === 255) return 0;
|
|
1120
|
+
if (da === 0) return src;
|
|
1121
|
+
const sa = src >>> 24 & 255;
|
|
1122
|
+
const sr = src & 255;
|
|
1123
|
+
const sg = src >>> 8 & 255;
|
|
1124
|
+
const sb = src >>> 16 & 255;
|
|
1125
|
+
const invDa = 255 - da;
|
|
1126
|
+
const tR = sr * invDa;
|
|
950
1127
|
const r = tR + 1 + (tR >> 8) >> 8;
|
|
951
|
-
const tG =
|
|
1128
|
+
const tG = sg * invDa;
|
|
952
1129
|
const g = tG + 1 + (tG >> 8) >> 8;
|
|
953
|
-
const tB =
|
|
1130
|
+
const tB = sb * invDa;
|
|
954
1131
|
const b = tB + 1 + (tB >> 8) >> 8;
|
|
955
|
-
const tA =
|
|
1132
|
+
const tA = sa * invDa;
|
|
956
1133
|
const a = tA + 1 + (tA >> 8) >> 8;
|
|
957
1134
|
return (a << 24 | b << 16 | g << 8 | r) >>> 0;
|
|
958
1135
|
};
|
|
959
|
-
var
|
|
1136
|
+
var sourceAtopPerfect = (src, dst) => {
|
|
960
1137
|
const sa = src >>> 24 & 255;
|
|
961
|
-
|
|
1138
|
+
const da = dst >>> 24 & 255;
|
|
1139
|
+
if (da === 0) return 0;
|
|
1140
|
+
const sr = src & 255;
|
|
1141
|
+
const sg = src >>> 8 & 255;
|
|
1142
|
+
const sb = src >>> 16 & 255;
|
|
962
1143
|
const dr = dst & 255;
|
|
963
1144
|
const dg = dst >>> 8 & 255;
|
|
964
1145
|
const db = dst >>> 16 & 255;
|
|
1146
|
+
const invSa = 255 - sa;
|
|
1147
|
+
const tR = sr * da + dr * invSa;
|
|
1148
|
+
const r = tR + 1 + (tR >> 8) >> 8;
|
|
1149
|
+
const tG = sg * da + dg * invSa;
|
|
1150
|
+
const g = tG + 1 + (tG >> 8) >> 8;
|
|
1151
|
+
const tB = sb * da + db * invSa;
|
|
1152
|
+
const b = tB + 1 + (tB >> 8) >> 8;
|
|
1153
|
+
return (da << 24 | b << 16 | g << 8 | r) >>> 0;
|
|
1154
|
+
};
|
|
1155
|
+
var destinationOverPerfect = (src, dst) => {
|
|
965
1156
|
const da = dst >>> 24 & 255;
|
|
1157
|
+
if (da === 255) return dst;
|
|
1158
|
+
if (da === 0) return src;
|
|
1159
|
+
const sa = src >>> 24 & 255;
|
|
966
1160
|
const sr = src & 255;
|
|
967
1161
|
const sg = src >>> 8 & 255;
|
|
968
1162
|
const sb = src >>> 16 & 255;
|
|
969
|
-
const
|
|
970
|
-
const
|
|
971
|
-
const
|
|
972
|
-
const
|
|
973
|
-
const
|
|
974
|
-
const bb = mB + 1 + (mB >> 8) >> 8;
|
|
975
|
-
if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
|
|
976
|
-
const invA = 255 - sa;
|
|
977
|
-
const tR = br * sa + dr * invA;
|
|
1163
|
+
const dr = dst & 255;
|
|
1164
|
+
const dg = dst >>> 8 & 255;
|
|
1165
|
+
const db = dst >>> 16 & 255;
|
|
1166
|
+
const invDa = 255 - da;
|
|
1167
|
+
const tR = dr * 255 + sr * invDa;
|
|
978
1168
|
const r = tR + 1 + (tR >> 8) >> 8;
|
|
979
|
-
const tG =
|
|
1169
|
+
const tG = dg * 255 + sg * invDa;
|
|
980
1170
|
const g = tG + 1 + (tG >> 8) >> 8;
|
|
981
|
-
const tB =
|
|
1171
|
+
const tB = db * 255 + sb * invDa;
|
|
982
1172
|
const b = tB + 1 + (tB >> 8) >> 8;
|
|
983
|
-
const tA =
|
|
1173
|
+
const tA = da * 255 + sa * invDa;
|
|
984
1174
|
const a = tA + 1 + (tA >> 8) >> 8;
|
|
985
1175
|
return (a << 24 | b << 16 | g << 8 | r) >>> 0;
|
|
986
1176
|
};
|
|
987
|
-
var
|
|
1177
|
+
var destinationInPerfect = (src, dst) => {
|
|
988
1178
|
const sa = src >>> 24 & 255;
|
|
989
|
-
if (sa === 0) return
|
|
1179
|
+
if (sa === 0) return 0;
|
|
1180
|
+
if (sa === 255) return dst;
|
|
1181
|
+
const da = dst >>> 24 & 255;
|
|
990
1182
|
const dr = dst & 255;
|
|
991
1183
|
const dg = dst >>> 8 & 255;
|
|
992
1184
|
const db = dst >>> 16 & 255;
|
|
993
|
-
const
|
|
994
|
-
const sg = src >>> 8 & 255;
|
|
995
|
-
const sb = src >>> 16 & 255;
|
|
996
|
-
const resR = dr === 255 ? 255 : sr === 0 ? 0 : 255 - ((255 - dr) * 255 / sr | 0);
|
|
997
|
-
const br = resR < 0 ? 0 : resR;
|
|
998
|
-
const resG = dg === 255 ? 255 : sg === 0 ? 0 : 255 - ((255 - dg) * 255 / sg | 0);
|
|
999
|
-
const bg = resG < 0 ? 0 : resG;
|
|
1000
|
-
const resB = db === 255 ? 255 : sb === 0 ? 0 : 255 - ((255 - db) * 255 / sb | 0);
|
|
1001
|
-
const bb = resB < 0 ? 0 : resB;
|
|
1002
|
-
if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
|
|
1003
|
-
const invA = 255 - sa;
|
|
1004
|
-
const da = dst >>> 24 & 255;
|
|
1005
|
-
const tR = br * sa + dr * invA;
|
|
1185
|
+
const tR = dr * sa;
|
|
1006
1186
|
const r = tR + 1 + (tR >> 8) >> 8;
|
|
1007
|
-
const tG =
|
|
1187
|
+
const tG = dg * sa;
|
|
1008
1188
|
const g = tG + 1 + (tG >> 8) >> 8;
|
|
1009
|
-
const tB =
|
|
1189
|
+
const tB = db * sa;
|
|
1010
1190
|
const b = tB + 1 + (tB >> 8) >> 8;
|
|
1011
|
-
const tA =
|
|
1191
|
+
const tA = da * sa;
|
|
1012
1192
|
const a = tA + 1 + (tA >> 8) >> 8;
|
|
1013
1193
|
return (a << 24 | b << 16 | g << 8 | r) >>> 0;
|
|
1014
1194
|
};
|
|
1015
|
-
var
|
|
1195
|
+
var destinationOutPerfect = (src, dst) => {
|
|
1016
1196
|
const sa = src >>> 24 & 255;
|
|
1197
|
+
if (sa === 255) return 0;
|
|
1017
1198
|
if (sa === 0) return dst;
|
|
1018
|
-
const
|
|
1019
|
-
const
|
|
1020
|
-
const
|
|
1021
|
-
const
|
|
1022
|
-
const
|
|
1023
|
-
const
|
|
1024
|
-
const
|
|
1025
|
-
const
|
|
1026
|
-
|
|
1027
|
-
const
|
|
1199
|
+
const da = dst >>> 24 & 255;
|
|
1200
|
+
const dr = dst & 255;
|
|
1201
|
+
const dg = dst >>> 8 & 255;
|
|
1202
|
+
const db = dst >>> 16 & 255;
|
|
1203
|
+
const invSa = 255 - sa;
|
|
1204
|
+
const tR = dr * invSa;
|
|
1205
|
+
const r = tR + 1 + (tR >> 8) >> 8;
|
|
1206
|
+
const tG = dg * invSa;
|
|
1207
|
+
const g = tG + 1 + (tG >> 8) >> 8;
|
|
1208
|
+
const tB = db * invSa;
|
|
1209
|
+
const b = tB + 1 + (tB >> 8) >> 8;
|
|
1210
|
+
const tA = da * invSa;
|
|
1211
|
+
const a = tA + 1 + (tA >> 8) >> 8;
|
|
1212
|
+
return (a << 24 | b << 16 | g << 8 | r) >>> 0;
|
|
1213
|
+
};
|
|
1214
|
+
var destinationAtopPerfect = (src, dst) => {
|
|
1215
|
+
const sa = src >>> 24 & 255;
|
|
1216
|
+
if (sa === 0) return 0;
|
|
1217
|
+
const da = dst >>> 24 & 255;
|
|
1218
|
+
if (da === 0) return 0;
|
|
1219
|
+
const sr = src & 255;
|
|
1220
|
+
const sg = src >>> 8 & 255;
|
|
1221
|
+
const sb = src >>> 16 & 255;
|
|
1222
|
+
const dr = dst & 255;
|
|
1223
|
+
const dg = dst >>> 8 & 255;
|
|
1224
|
+
const db = dst >>> 16 & 255;
|
|
1225
|
+
const invDa = 255 - da;
|
|
1226
|
+
const tR = dr * sa + sr * invDa;
|
|
1227
|
+
const r = tR + 1 + (tR >> 8) >> 8;
|
|
1228
|
+
const tG = dg * sa + sg * invDa;
|
|
1229
|
+
const g = tG + 1 + (tG >> 8) >> 8;
|
|
1230
|
+
const tB = db * sa + sb * invDa;
|
|
1231
|
+
const b = tB + 1 + (tB >> 8) >> 8;
|
|
1232
|
+
return (sa << 24 | b << 16 | g << 8 | r) >>> 0;
|
|
1233
|
+
};
|
|
1234
|
+
var xorPerfect = (src, dst) => {
|
|
1235
|
+
const sa = src >>> 24 & 255;
|
|
1236
|
+
const da = dst >>> 24 & 255;
|
|
1237
|
+
const sr = src & 255;
|
|
1238
|
+
const sg = src >>> 8 & 255;
|
|
1239
|
+
const sb = src >>> 16 & 255;
|
|
1240
|
+
const dr = dst & 255;
|
|
1241
|
+
const dg = dst >>> 8 & 255;
|
|
1242
|
+
const db = dst >>> 16 & 255;
|
|
1243
|
+
const invDa = 255 - da;
|
|
1244
|
+
const invSa = 255 - sa;
|
|
1245
|
+
const tR = sr * invDa + dr * invSa;
|
|
1246
|
+
const r = tR + 1 + (tR >> 8) >> 8;
|
|
1247
|
+
const tG = sg * invDa + dg * invSa;
|
|
1248
|
+
const g = tG + 1 + (tG >> 8) >> 8;
|
|
1249
|
+
const tB = sb * invDa + db * invSa;
|
|
1250
|
+
const b = tB + 1 + (tB >> 8) >> 8;
|
|
1251
|
+
const tA = sa * invDa + da * invSa;
|
|
1252
|
+
const a = tA + 1 + (tA >> 8) >> 8;
|
|
1253
|
+
return (a << 24 | b << 16 | g << 8 | r) >>> 0;
|
|
1254
|
+
};
|
|
1255
|
+
var sourceOverPerfect = (src, dst) => {
|
|
1256
|
+
const sa = src >>> 24 & 255;
|
|
1257
|
+
if (sa === 255) return src;
|
|
1258
|
+
if (sa === 0) return dst;
|
|
1259
|
+
const da = dst >>> 24 & 255;
|
|
1260
|
+
if (da === 0) return src;
|
|
1261
|
+
const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
|
|
1262
|
+
const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
|
|
1263
|
+
const invA = 255 - sa;
|
|
1264
|
+
const tR = sr * sa + dr * invA;
|
|
1265
|
+
const r = tR + 1 + (tR >> 8) >> 8;
|
|
1266
|
+
const tG = sg * sa + dg * invA;
|
|
1267
|
+
const g = tG + 1 + (tG >> 8) >> 8;
|
|
1268
|
+
const tB = sb * sa + db * invA;
|
|
1269
|
+
const b = tB + 1 + (tB >> 8) >> 8;
|
|
1270
|
+
const tA = 255 * sa + da * invA;
|
|
1271
|
+
const a = tA + 1 + (tA >> 8) >> 8;
|
|
1272
|
+
return (a << 24 | b << 16 | g << 8 | r) >>> 0;
|
|
1273
|
+
};
|
|
1274
|
+
var darkenPerfect = (src, dst) => {
|
|
1275
|
+
const sa = src >>> 24 & 255;
|
|
1276
|
+
if (sa === 0) return dst;
|
|
1277
|
+
const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
|
|
1278
|
+
const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
|
|
1279
|
+
const br = sr < dr ? sr : dr;
|
|
1280
|
+
const bg = sg < dg ? sg : dg;
|
|
1281
|
+
const bb = sb < db ? sb : db;
|
|
1282
|
+
if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
|
|
1283
|
+
const invA = 255 - sa;
|
|
1284
|
+
const da = dst >>> 24 & 255;
|
|
1285
|
+
const tR = br * sa + dr * invA;
|
|
1286
|
+
const r = tR + 1 + (tR >> 8) >> 8;
|
|
1287
|
+
const tG = bg * sa + dg * invA;
|
|
1288
|
+
const g = tG + 1 + (tG >> 8) >> 8;
|
|
1289
|
+
const tB = bb * sa + db * invA;
|
|
1290
|
+
const b = tB + 1 + (tB >> 8) >> 8;
|
|
1291
|
+
const tA = 255 * sa + da * invA;
|
|
1292
|
+
const a = tA + 1 + (tA >> 8) >> 8;
|
|
1293
|
+
return (a << 24 | b << 16 | g << 8 | r) >>> 0;
|
|
1294
|
+
};
|
|
1295
|
+
var multiplyPerfect = (src, dst) => {
|
|
1296
|
+
const sa = src >>> 24 & 255;
|
|
1297
|
+
if (sa === 0) return dst;
|
|
1298
|
+
const dr = dst & 255;
|
|
1299
|
+
const dg = dst >>> 8 & 255;
|
|
1300
|
+
const db = dst >>> 16 & 255;
|
|
1301
|
+
const da = dst >>> 24 & 255;
|
|
1302
|
+
const sr = src & 255;
|
|
1303
|
+
const sg = src >>> 8 & 255;
|
|
1304
|
+
const sb = src >>> 16 & 255;
|
|
1305
|
+
const mR = sr * dr;
|
|
1306
|
+
const br = mR + 1 + (mR >> 8) >> 8;
|
|
1307
|
+
const mG = sg * dg;
|
|
1308
|
+
const bg = mG + 1 + (mG >> 8) >> 8;
|
|
1309
|
+
const mB = sb * db;
|
|
1310
|
+
const bb = mB + 1 + (mB >> 8) >> 8;
|
|
1311
|
+
if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
|
|
1312
|
+
const invA = 255 - sa;
|
|
1313
|
+
const tR = br * sa + dr * invA;
|
|
1314
|
+
const r = tR + 1 + (tR >> 8) >> 8;
|
|
1315
|
+
const tG = bg * sa + dg * invA;
|
|
1316
|
+
const g = tG + 1 + (tG >> 8) >> 8;
|
|
1317
|
+
const tB = bb * sa + db * invA;
|
|
1318
|
+
const b = tB + 1 + (tB >> 8) >> 8;
|
|
1319
|
+
const tA = 255 * sa + da * invA;
|
|
1320
|
+
const a = tA + 1 + (tA >> 8) >> 8;
|
|
1321
|
+
return (a << 24 | b << 16 | g << 8 | r) >>> 0;
|
|
1322
|
+
};
|
|
1323
|
+
var colorBurnPerfect = (src, dst) => {
|
|
1324
|
+
const sa = src >>> 24 & 255;
|
|
1325
|
+
if (sa === 0) return dst;
|
|
1326
|
+
const dr = dst & 255;
|
|
1327
|
+
const dg = dst >>> 8 & 255;
|
|
1328
|
+
const db = dst >>> 16 & 255;
|
|
1329
|
+
const sr = src & 255;
|
|
1330
|
+
const sg = src >>> 8 & 255;
|
|
1331
|
+
const sb = src >>> 16 & 255;
|
|
1332
|
+
const resR = dr === 255 ? 255 : sr === 0 ? 0 : 255 - ((255 - dr) * 255 / sr | 0);
|
|
1333
|
+
const br = resR < 0 ? 0 : resR;
|
|
1334
|
+
const resG = dg === 255 ? 255 : sg === 0 ? 0 : 255 - ((255 - dg) * 255 / sg | 0);
|
|
1335
|
+
const bg = resG < 0 ? 0 : resG;
|
|
1336
|
+
const resB = db === 255 ? 255 : sb === 0 ? 0 : 255 - ((255 - db) * 255 / sb | 0);
|
|
1337
|
+
const bb = resB < 0 ? 0 : resB;
|
|
1338
|
+
if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
|
|
1339
|
+
const invA = 255 - sa;
|
|
1340
|
+
const da = dst >>> 24 & 255;
|
|
1341
|
+
const tR = br * sa + dr * invA;
|
|
1342
|
+
const r = tR + 1 + (tR >> 8) >> 8;
|
|
1343
|
+
const tG = bg * sa + dg * invA;
|
|
1344
|
+
const g = tG + 1 + (tG >> 8) >> 8;
|
|
1345
|
+
const tB = bb * sa + db * invA;
|
|
1346
|
+
const b = tB + 1 + (tB >> 8) >> 8;
|
|
1347
|
+
const tA = 255 * sa + da * invA;
|
|
1348
|
+
const a = tA + 1 + (tA >> 8) >> 8;
|
|
1349
|
+
return (a << 24 | b << 16 | g << 8 | r) >>> 0;
|
|
1350
|
+
};
|
|
1351
|
+
var linearBurnPerfect = (src, dst) => {
|
|
1352
|
+
const sa = src >>> 24 & 255;
|
|
1353
|
+
if (sa === 0) return dst;
|
|
1354
|
+
const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
|
|
1355
|
+
const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
|
|
1356
|
+
const brU = dr + sr - 255;
|
|
1357
|
+
const br = brU < 0 ? 0 : brU;
|
|
1358
|
+
const bgU = dg + sg - 255;
|
|
1359
|
+
const bg = bgU < 0 ? 0 : bgU;
|
|
1360
|
+
const bbU = db + sb - 255;
|
|
1361
|
+
const bb = bbU < 0 ? 0 : bbU;
|
|
1362
|
+
if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
|
|
1363
|
+
const invA = 255 - sa;
|
|
1028
1364
|
const da = dst >>> 24 & 255;
|
|
1029
1365
|
const tR = br * sa + dr * invA;
|
|
1030
1366
|
const r = tR + 1 + (tR >> 8) >> 8;
|
|
@@ -1443,6 +1779,14 @@ var dividePerfect = (src, dst) => {
|
|
|
1443
1779
|
};
|
|
1444
1780
|
var BASE_PERFECT_BLEND_MODE_FUNCTIONS = {
|
|
1445
1781
|
[BaseBlendMode.overwrite]: overwritePerfect,
|
|
1782
|
+
[BaseBlendMode.sourceIn]: sourceInPerfect,
|
|
1783
|
+
[BaseBlendMode.sourceOut]: sourceOutPerfect,
|
|
1784
|
+
[BaseBlendMode.sourceAtop]: sourceAtopPerfect,
|
|
1785
|
+
[BaseBlendMode.destinationOver]: destinationOverPerfect,
|
|
1786
|
+
[BaseBlendMode.destinationIn]: destinationInPerfect,
|
|
1787
|
+
[BaseBlendMode.destinationOut]: destinationOutPerfect,
|
|
1788
|
+
[BaseBlendMode.destinationAtop]: destinationAtopPerfect,
|
|
1789
|
+
[BaseBlendMode.xor]: xorPerfect,
|
|
1446
1790
|
[BaseBlendMode.sourceOver]: sourceOverPerfect,
|
|
1447
1791
|
[BaseBlendMode.darken]: darkenPerfect,
|
|
1448
1792
|
[BaseBlendMode.multiply]: multiplyPerfect,
|
|
@@ -1505,9 +1849,23 @@ var getKeyByValue = (obj, value) => {
|
|
|
1505
1849
|
}
|
|
1506
1850
|
};
|
|
1507
1851
|
|
|
1508
|
-
//
|
|
1509
|
-
var
|
|
1510
|
-
|
|
1852
|
+
// src/Canvas/canvas-blend-modes.ts
|
|
1853
|
+
var CANVAS_COMPOSITE_MAP = {
|
|
1854
|
+
[BaseBlendMode.overwrite]: "copy",
|
|
1855
|
+
[BaseBlendMode.sourceOver]: "source-over",
|
|
1856
|
+
[BaseBlendMode.darken]: "darken",
|
|
1857
|
+
[BaseBlendMode.multiply]: "multiply",
|
|
1858
|
+
[BaseBlendMode.colorBurn]: "color-burn",
|
|
1859
|
+
[BaseBlendMode.lighten]: "lighten",
|
|
1860
|
+
[BaseBlendMode.screen]: "screen",
|
|
1861
|
+
[BaseBlendMode.colorDodge]: "color-dodge",
|
|
1862
|
+
[BaseBlendMode.linearDodge]: "lighter",
|
|
1863
|
+
[BaseBlendMode.overlay]: "overlay",
|
|
1864
|
+
[BaseBlendMode.softLight]: "soft-light",
|
|
1865
|
+
[BaseBlendMode.hardLight]: "hard-light",
|
|
1866
|
+
[BaseBlendMode.difference]: "difference",
|
|
1867
|
+
[BaseBlendMode.exclusion]: "exclusion"
|
|
1868
|
+
};
|
|
1511
1869
|
|
|
1512
1870
|
// src/Canvas/ReusableCanvas.ts
|
|
1513
1871
|
function makeReusableCanvas() {
|
|
@@ -1560,37 +1918,38 @@ function makeReusableCanvasMeta(factory) {
|
|
|
1560
1918
|
}
|
|
1561
1919
|
|
|
1562
1920
|
// src/Canvas/CanvasFrameRenderer.ts
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
};
|
|
1566
|
-
function makeCanvasFrameRenderer(deps = defaults) {
|
|
1567
|
-
const {
|
|
1568
|
-
makeReusableCanvas: makeReusableCanvas2 = defaults.makeReusableCanvas
|
|
1569
|
-
} = deps;
|
|
1570
|
-
const bufferCanvas = makeReusableCanvas2();
|
|
1921
|
+
function makeCanvasFrameRenderer(reusableCanvasFactory = makeReusableOffscreenCanvas) {
|
|
1922
|
+
const getBuffer = reusableCanvasFactory();
|
|
1571
1923
|
return function renderCanvasFrame(pixelCanvas, scale, getImageData, drawPixelLayer, drawScreenLayer) {
|
|
1572
|
-
const
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
const
|
|
1577
|
-
ctx: pxCtx,
|
|
1578
|
-
canvas: pxCanvas
|
|
1579
|
-
} = bufferCanvas(canvas.width, canvas.height);
|
|
1924
|
+
const canvas = pixelCanvas.canvas;
|
|
1925
|
+
const ctx = pixelCanvas.ctx;
|
|
1926
|
+
const w = canvas.width;
|
|
1927
|
+
const h = canvas.height;
|
|
1928
|
+
const buffer = getBuffer(w, h);
|
|
1580
1929
|
const img = getImageData();
|
|
1581
1930
|
if (img) {
|
|
1582
|
-
|
|
1931
|
+
buffer.ctx.putImageData(img, 0, 0);
|
|
1583
1932
|
}
|
|
1584
|
-
drawPixelLayer?.(
|
|
1933
|
+
drawPixelLayer?.(buffer.ctx);
|
|
1585
1934
|
ctx.setTransform(1, 0, 0, 1, 0, 0);
|
|
1586
|
-
ctx.clearRect(0, 0,
|
|
1935
|
+
ctx.clearRect(0, 0, w, h);
|
|
1587
1936
|
ctx.setTransform(scale, 0, 0, scale, 0, 0);
|
|
1588
|
-
ctx.drawImage(
|
|
1937
|
+
ctx.drawImage(buffer.canvas, 0, 0);
|
|
1589
1938
|
ctx.setTransform(1, 0, 0, 1, 0, 0);
|
|
1590
1939
|
drawScreenLayer?.(ctx, scale);
|
|
1591
1940
|
};
|
|
1592
1941
|
}
|
|
1593
1942
|
|
|
1943
|
+
// src/Canvas/CanvasPixelDataRenderer.ts
|
|
1944
|
+
function makeCanvasPixelDataRenderer(reusableCanvasFactory = makeReusableOffscreenCanvas) {
|
|
1945
|
+
const bufferCanvas = reusableCanvasFactory();
|
|
1946
|
+
return function drawPixelData(targetCtx, pixelData, x = 0, y = 0) {
|
|
1947
|
+
const buffer = bufferCanvas(pixelData.w, pixelData.h);
|
|
1948
|
+
buffer.ctx.putImageData(pixelData.imageData, 0, 0);
|
|
1949
|
+
targetCtx.drawImage(buffer.canvas, x, y);
|
|
1950
|
+
};
|
|
1951
|
+
}
|
|
1952
|
+
|
|
1594
1953
|
// src/Canvas/PixelCanvas.ts
|
|
1595
1954
|
function makePixelCanvas(canvas) {
|
|
1596
1955
|
const ctx = canvas.getContext("2d");
|
|
@@ -1607,24 +1966,6 @@ function makePixelCanvas(canvas) {
|
|
|
1607
1966
|
};
|
|
1608
1967
|
}
|
|
1609
1968
|
|
|
1610
|
-
// src/Canvas/canvas-blend-modes.ts
|
|
1611
|
-
var CANVAS_COMPOSITE_MAP = {
|
|
1612
|
-
[BaseBlendMode.overwrite]: "copy",
|
|
1613
|
-
[BaseBlendMode.sourceOver]: "source-over",
|
|
1614
|
-
[BaseBlendMode.darken]: "darken",
|
|
1615
|
-
[BaseBlendMode.multiply]: "multiply",
|
|
1616
|
-
[BaseBlendMode.colorBurn]: "color-burn",
|
|
1617
|
-
[BaseBlendMode.lighten]: "lighten",
|
|
1618
|
-
[BaseBlendMode.screen]: "screen",
|
|
1619
|
-
[BaseBlendMode.colorDodge]: "color-dodge",
|
|
1620
|
-
[BaseBlendMode.linearDodge]: "lighter",
|
|
1621
|
-
[BaseBlendMode.overlay]: "overlay",
|
|
1622
|
-
[BaseBlendMode.softLight]: "soft-light",
|
|
1623
|
-
[BaseBlendMode.hardLight]: "hard-light",
|
|
1624
|
-
[BaseBlendMode.difference]: "difference",
|
|
1625
|
-
[BaseBlendMode.exclusion]: "exclusion"
|
|
1626
|
-
};
|
|
1627
|
-
|
|
1628
1969
|
// src/ImageData/imgBlobToImageData.ts
|
|
1629
1970
|
async function imgBlobToImageData(blob) {
|
|
1630
1971
|
let bitmap = null;
|
|
@@ -1689,10 +2030,10 @@ function applyPatchTiles(target, tiles, tileSize) {
|
|
|
1689
2030
|
for (let i = 0; i < tiles.length; i++) {
|
|
1690
2031
|
const tile = tiles[i];
|
|
1691
2032
|
if (!tile) continue;
|
|
1692
|
-
const dst = target.
|
|
1693
|
-
const src = tile.
|
|
1694
|
-
const dstWidth = target.
|
|
1695
|
-
const dstHeight = target.
|
|
2033
|
+
const dst = target.data;
|
|
2034
|
+
const src = tile.data;
|
|
2035
|
+
const dstWidth = target.w;
|
|
2036
|
+
const dstHeight = target.h;
|
|
1696
2037
|
const startX = tile.tx * tileSize;
|
|
1697
2038
|
const startY = tile.ty * tileSize;
|
|
1698
2039
|
const copyWidth = Math.max(0, Math.min(tileSize, dstWidth - startX));
|
|
@@ -1787,17 +2128,17 @@ var HistoryManager = class {
|
|
|
1787
2128
|
|
|
1788
2129
|
// src/History/PixelAccumulator.ts
|
|
1789
2130
|
var PixelAccumulator = class {
|
|
1790
|
-
constructor(config,
|
|
2131
|
+
constructor(config, pixelTilePool) {
|
|
1791
2132
|
this.config = config;
|
|
1792
|
-
this.
|
|
2133
|
+
this.pixelTilePool = pixelTilePool;
|
|
1793
2134
|
this.lookup = [];
|
|
1794
2135
|
this.beforeTiles = [];
|
|
1795
2136
|
}
|
|
1796
2137
|
lookup;
|
|
1797
2138
|
beforeTiles;
|
|
1798
2139
|
recyclePatch(patch) {
|
|
1799
|
-
this.
|
|
1800
|
-
this.
|
|
2140
|
+
this.pixelTilePool.releaseTiles(patch.beforeTiles);
|
|
2141
|
+
this.pixelTilePool.releaseTiles(patch.afterTiles);
|
|
1801
2142
|
}
|
|
1802
2143
|
/**
|
|
1803
2144
|
* @param x pixel x coordinate
|
|
@@ -1812,7 +2153,7 @@ var PixelAccumulator = class {
|
|
|
1812
2153
|
let tile = this.lookup[id];
|
|
1813
2154
|
let added = false;
|
|
1814
2155
|
if (!tile) {
|
|
1815
|
-
tile = this.
|
|
2156
|
+
tile = this.pixelTilePool.getTile(id, tx, ty);
|
|
1816
2157
|
this.extractState(tile);
|
|
1817
2158
|
this.lookup[id] = tile;
|
|
1818
2159
|
this.beforeTiles.push(tile);
|
|
@@ -1822,7 +2163,7 @@ var PixelAccumulator = class {
|
|
|
1822
2163
|
if (!didChange && added) {
|
|
1823
2164
|
this.beforeTiles.pop();
|
|
1824
2165
|
this.lookup[id] = void 0;
|
|
1825
|
-
this.
|
|
2166
|
+
this.pixelTilePool.releaseTile(tile);
|
|
1826
2167
|
}
|
|
1827
2168
|
return didChange;
|
|
1828
2169
|
};
|
|
@@ -1846,7 +2187,7 @@ var PixelAccumulator = class {
|
|
|
1846
2187
|
const id = ty * columns + tx;
|
|
1847
2188
|
let tile = this.lookup[id];
|
|
1848
2189
|
if (!tile) {
|
|
1849
|
-
tile = this.
|
|
2190
|
+
tile = this.pixelTilePool.getTile(id, tx, ty);
|
|
1850
2191
|
this.extractState(tile);
|
|
1851
2192
|
this.lookup[id] = tile;
|
|
1852
2193
|
this.beforeTiles.push(tile);
|
|
@@ -1860,7 +2201,7 @@ var PixelAccumulator = class {
|
|
|
1860
2201
|
let t = this.beforeTiles[i];
|
|
1861
2202
|
if (t) {
|
|
1862
2203
|
this.lookup[t.id] = void 0;
|
|
1863
|
-
this.
|
|
2204
|
+
this.pixelTilePool.releaseTile(t);
|
|
1864
2205
|
}
|
|
1865
2206
|
}
|
|
1866
2207
|
this.beforeTiles.length = startIndex;
|
|
@@ -1872,7 +2213,7 @@ var PixelAccumulator = class {
|
|
|
1872
2213
|
let tile = this.lookup[id];
|
|
1873
2214
|
let added = false;
|
|
1874
2215
|
if (!tile) {
|
|
1875
|
-
tile = this.
|
|
2216
|
+
tile = this.pixelTilePool.getTile(id, tx, ty);
|
|
1876
2217
|
this.extractState(tile);
|
|
1877
2218
|
this.lookup[id] = tile;
|
|
1878
2219
|
this.beforeTiles.push(tile);
|
|
@@ -1882,7 +2223,7 @@ var PixelAccumulator = class {
|
|
|
1882
2223
|
if (!didChange && added) {
|
|
1883
2224
|
this.beforeTiles.pop();
|
|
1884
2225
|
this.lookup[id] = void 0;
|
|
1885
|
-
this.
|
|
2226
|
+
this.pixelTilePool.releaseTile(tile);
|
|
1886
2227
|
}
|
|
1887
2228
|
return didChange;
|
|
1888
2229
|
};
|
|
@@ -1890,12 +2231,12 @@ var PixelAccumulator = class {
|
|
|
1890
2231
|
extractState(tile) {
|
|
1891
2232
|
const target = this.config.target;
|
|
1892
2233
|
const TILE_SIZE = this.config.tileSize;
|
|
1893
|
-
const dst = tile.
|
|
1894
|
-
const src = target.
|
|
2234
|
+
const dst = tile.data;
|
|
2235
|
+
const src = target.data;
|
|
1895
2236
|
const startX = tile.tx * TILE_SIZE;
|
|
1896
2237
|
const startY = tile.ty * TILE_SIZE;
|
|
1897
|
-
const targetWidth = target.
|
|
1898
|
-
const targetHeight = target.
|
|
2238
|
+
const targetWidth = target.w;
|
|
2239
|
+
const targetHeight = target.h;
|
|
1899
2240
|
if (startX >= targetWidth || startX + TILE_SIZE <= 0 || startY >= targetHeight || startY + TILE_SIZE <= 0) {
|
|
1900
2241
|
dst.fill(0);
|
|
1901
2242
|
return;
|
|
@@ -1926,7 +2267,7 @@ var PixelAccumulator = class {
|
|
|
1926
2267
|
for (let i = 0; i < length; i++) {
|
|
1927
2268
|
let beforeTile = this.beforeTiles[i];
|
|
1928
2269
|
if (beforeTile) {
|
|
1929
|
-
let afterTile = this.
|
|
2270
|
+
let afterTile = this.pixelTilePool.getTile(beforeTile.id, beforeTile.tx, beforeTile.ty);
|
|
1930
2271
|
this.extractState(afterTile);
|
|
1931
2272
|
afterTiles.push(afterTile);
|
|
1932
2273
|
}
|
|
@@ -1948,7 +2289,7 @@ var PixelAccumulator = class {
|
|
|
1948
2289
|
let tile = this.beforeTiles[i];
|
|
1949
2290
|
if (tile) {
|
|
1950
2291
|
this.lookup[tile.id] = void 0;
|
|
1951
|
-
this.
|
|
2292
|
+
this.pixelTilePool.releaseTile(tile);
|
|
1952
2293
|
}
|
|
1953
2294
|
}
|
|
1954
2295
|
this.beforeTiles.length = 0;
|
|
@@ -1976,8 +2317,8 @@ var PixelEngineConfig = class {
|
|
|
1976
2317
|
this.tileMask = tileSize - 1;
|
|
1977
2318
|
this.tileArea = tileSize * tileSize;
|
|
1978
2319
|
this.target = target;
|
|
1979
|
-
this.targetColumns = target.
|
|
1980
|
-
this.targetRows = target.
|
|
2320
|
+
this.targetColumns = target.w + this.tileMask >> this.tileShift;
|
|
2321
|
+
this.targetRows = target.h + this.tileMask >> this.tileShift;
|
|
1981
2322
|
}
|
|
1982
2323
|
};
|
|
1983
2324
|
|
|
@@ -1985,8 +2326,8 @@ var PixelEngineConfig = class {
|
|
|
1985
2326
|
function applyAlphaMaskToPixelData(target, mask, opts) {
|
|
1986
2327
|
const targetX = opts?.x ?? 0;
|
|
1987
2328
|
const targetY = opts?.y ?? 0;
|
|
1988
|
-
const width = opts?.w ?? target.
|
|
1989
|
-
const height = opts?.h ?? target.
|
|
2329
|
+
const width = opts?.w ?? target.w;
|
|
2330
|
+
const height = opts?.h ?? target.h;
|
|
1990
2331
|
const globalAlpha = opts?.alpha ?? 255;
|
|
1991
2332
|
const mx = opts?.mx ?? 0;
|
|
1992
2333
|
const my = opts?.my ?? 0;
|
|
@@ -2004,8 +2345,8 @@ function applyAlphaMaskToPixelData(target, mask, opts) {
|
|
|
2004
2345
|
h += y;
|
|
2005
2346
|
y = 0;
|
|
2006
2347
|
}
|
|
2007
|
-
w = Math.min(w, target.
|
|
2008
|
-
h = Math.min(h, target.
|
|
2348
|
+
w = Math.min(w, target.w - x);
|
|
2349
|
+
h = Math.min(h, target.h - y);
|
|
2009
2350
|
if (w <= 0) return false;
|
|
2010
2351
|
if (h <= 0) return false;
|
|
2011
2352
|
const mPitch = mask.w;
|
|
@@ -2022,49 +2363,82 @@ function applyAlphaMaskToPixelData(target, mask, opts) {
|
|
|
2022
2363
|
if (finalH <= 0) return false;
|
|
2023
2364
|
const xShift = sX0 - startX;
|
|
2024
2365
|
const yShift = sY0 - startY;
|
|
2025
|
-
const dst32 = target.
|
|
2026
|
-
const dw = target.
|
|
2366
|
+
const dst32 = target.data;
|
|
2367
|
+
const dw = target.w;
|
|
2027
2368
|
const dStride = dw - finalW;
|
|
2028
2369
|
const mStride = mPitch - finalW;
|
|
2029
2370
|
const maskData = mask.data;
|
|
2030
2371
|
let dIdx = (y + yShift) * dw + (x + xShift);
|
|
2031
2372
|
let mIdx = sY0 * mPitch + sX0;
|
|
2032
2373
|
let didChange = false;
|
|
2033
|
-
|
|
2034
|
-
for (let
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2374
|
+
if (invertMask) {
|
|
2375
|
+
for (let iy = 0; iy < finalH; iy++) {
|
|
2376
|
+
for (let ix = 0; ix < finalW; ix++) {
|
|
2377
|
+
const effectiveM = 255 - maskData[mIdx];
|
|
2378
|
+
if (effectiveM === 0) {
|
|
2379
|
+
const current = dst32[dIdx];
|
|
2380
|
+
const next = (current & 16777215) >>> 0;
|
|
2381
|
+
if (current !== next) {
|
|
2382
|
+
dst32[dIdx] = next;
|
|
2383
|
+
didChange = true;
|
|
2384
|
+
}
|
|
2385
|
+
} else {
|
|
2386
|
+
const t1 = effectiveM * globalAlpha + 128;
|
|
2387
|
+
const weight = t1 + (t1 >> 8) >> 8;
|
|
2388
|
+
if (weight < 255) {
|
|
2389
|
+
const current = dst32[dIdx];
|
|
2390
|
+
const da = current >>> 24;
|
|
2391
|
+
if (da !== 0) {
|
|
2392
|
+
const t2 = da * weight + 128;
|
|
2393
|
+
const finalAlpha = t2 + (t2 >> 8) >> 8;
|
|
2394
|
+
const next = (current & 16777215 | finalAlpha << 24) >>> 0;
|
|
2395
|
+
if (current !== next) {
|
|
2396
|
+
dst32[dIdx] = next;
|
|
2397
|
+
didChange = true;
|
|
2398
|
+
}
|
|
2399
|
+
}
|
|
2400
|
+
}
|
|
2401
|
+
}
|
|
2402
|
+
dIdx++;
|
|
2403
|
+
mIdx++;
|
|
2046
2404
|
}
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2405
|
+
dIdx += dStride;
|
|
2406
|
+
mIdx += mStride;
|
|
2407
|
+
}
|
|
2408
|
+
} else {
|
|
2409
|
+
for (let iy = 0; iy < finalH; iy++) {
|
|
2410
|
+
for (let ix = 0; ix < finalW; ix++) {
|
|
2411
|
+
const effectiveM = maskData[mIdx];
|
|
2412
|
+
if (effectiveM === 0) {
|
|
2055
2413
|
const current = dst32[dIdx];
|
|
2056
|
-
const next = (
|
|
2414
|
+
const next = (current & 16777215) >>> 0;
|
|
2057
2415
|
if (current !== next) {
|
|
2058
2416
|
dst32[dIdx] = next;
|
|
2059
2417
|
didChange = true;
|
|
2060
2418
|
}
|
|
2419
|
+
} else {
|
|
2420
|
+
const t1 = effectiveM * globalAlpha + 128;
|
|
2421
|
+
const weight = t1 + (t1 >> 8) >> 8;
|
|
2422
|
+
if (weight < 255) {
|
|
2423
|
+
const current = dst32[dIdx];
|
|
2424
|
+
const da = current >>> 24;
|
|
2425
|
+
if (da !== 0) {
|
|
2426
|
+
const t2 = da * weight + 128;
|
|
2427
|
+
const finalAlpha = t2 + (t2 >> 8) >> 8;
|
|
2428
|
+
const next = (current & 16777215 | finalAlpha << 24) >>> 0;
|
|
2429
|
+
if (current !== next) {
|
|
2430
|
+
dst32[dIdx] = next;
|
|
2431
|
+
didChange = true;
|
|
2432
|
+
}
|
|
2433
|
+
}
|
|
2434
|
+
}
|
|
2061
2435
|
}
|
|
2436
|
+
dIdx++;
|
|
2437
|
+
mIdx++;
|
|
2062
2438
|
}
|
|
2063
|
-
dIdx
|
|
2064
|
-
mIdx
|
|
2439
|
+
dIdx += dStride;
|
|
2440
|
+
mIdx += mStride;
|
|
2065
2441
|
}
|
|
2066
|
-
dIdx += dStride;
|
|
2067
|
-
mIdx += mStride;
|
|
2068
2442
|
}
|
|
2069
2443
|
return didChange;
|
|
2070
2444
|
}
|
|
@@ -2098,338 +2472,77 @@ function resizeImageData(target, newWidth, newHeight, offsetX = 0, offsetY = 0)
|
|
|
2098
2472
|
return result;
|
|
2099
2473
|
}
|
|
2100
2474
|
|
|
2101
|
-
// src/
|
|
2102
|
-
function
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2475
|
+
// src/PixelData/PixelData.ts
|
|
2476
|
+
function makePixelData(imageData) {
|
|
2477
|
+
return {
|
|
2478
|
+
data: new Uint32Array(
|
|
2479
|
+
imageData.data.buffer,
|
|
2480
|
+
imageData.data.byteOffset,
|
|
2481
|
+
// Shift right by 2 is a fast bitwise division by 4.
|
|
2482
|
+
imageData.data.byteLength >> 2
|
|
2483
|
+
),
|
|
2484
|
+
imageData,
|
|
2485
|
+
w: imageData.width,
|
|
2486
|
+
h: imageData.height
|
|
2108
2487
|
};
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2488
|
+
}
|
|
2489
|
+
function setPixelData(target, imageData) {
|
|
2490
|
+
;
|
|
2491
|
+
target.data = new Uint32Array(
|
|
2492
|
+
imageData.data.buffer,
|
|
2493
|
+
imageData.data.byteOffset,
|
|
2494
|
+
// Shift right by 2 is a fast bitwise division by 4.
|
|
2495
|
+
imageData.data.byteLength >> 2
|
|
2496
|
+
);
|
|
2497
|
+
target.imageData = imageData;
|
|
2498
|
+
target.w = imageData.width;
|
|
2499
|
+
target.h = imageData.height;
|
|
2118
2500
|
}
|
|
2119
2501
|
|
|
2120
|
-
// src/
|
|
2121
|
-
var
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
}
|
|
2127
|
-
lookup;
|
|
2128
|
-
scratchBounds = {
|
|
2129
|
-
x: 0,
|
|
2130
|
-
y: 0,
|
|
2131
|
-
w: 0,
|
|
2132
|
-
h: 0
|
|
2133
|
-
};
|
|
2134
|
-
eachTileInBounds(bounds, callback) {
|
|
2135
|
-
const {
|
|
2136
|
-
tileShift,
|
|
2137
|
-
targetColumns,
|
|
2138
|
-
targetRows,
|
|
2139
|
-
tileSize
|
|
2140
|
-
} = this.config;
|
|
2141
|
-
const x1 = Math.max(0, bounds.x >> tileShift);
|
|
2142
|
-
const y1 = Math.max(0, bounds.y >> tileShift);
|
|
2143
|
-
const x2 = Math.min(targetColumns - 1, bounds.x + bounds.w - 1 >> tileShift);
|
|
2144
|
-
const y2 = Math.min(targetRows - 1, bounds.y + bounds.h - 1 >> tileShift);
|
|
2145
|
-
if (x1 > x2 || y1 > y2) return;
|
|
2146
|
-
const lookup = this.lookup;
|
|
2147
|
-
const tilePool = this.tilePool;
|
|
2148
|
-
for (let ty = y1; ty <= y2; ty++) {
|
|
2149
|
-
const rowOffset = ty * targetColumns;
|
|
2150
|
-
const tileTop = ty << tileShift;
|
|
2151
|
-
for (let tx = x1; tx <= x2; tx++) {
|
|
2152
|
-
const id = rowOffset + tx;
|
|
2153
|
-
const tile = lookup[id] ?? (lookup[id] = tilePool.getTile(id, tx, ty));
|
|
2154
|
-
const tileLeft = tx << tileShift;
|
|
2155
|
-
const startX = bounds.x > tileLeft ? bounds.x : tileLeft;
|
|
2156
|
-
const startY = bounds.y > tileTop ? bounds.y : tileTop;
|
|
2157
|
-
const maskEndX = bounds.x + bounds.w;
|
|
2158
|
-
const tileEndX = tileLeft + tileSize;
|
|
2159
|
-
const endX = maskEndX < tileEndX ? maskEndX : tileEndX;
|
|
2160
|
-
const maskEndY = bounds.y + bounds.h;
|
|
2161
|
-
const tileEndY = tileTop + tileSize;
|
|
2162
|
-
const endY = maskEndY < tileEndY ? maskEndY : tileEndY;
|
|
2163
|
-
callback(tile, startX, startY, endX - startX, endY - startY);
|
|
2164
|
-
}
|
|
2165
|
-
}
|
|
2166
|
-
}
|
|
2167
|
-
writePaintAlphaMaskStroke(color, brush, x0, y0, x1, y1) {
|
|
2168
|
-
const cA = color >>> 24;
|
|
2169
|
-
if (cA === 0) return false;
|
|
2170
|
-
const {
|
|
2171
|
-
tileShift,
|
|
2172
|
-
tileMask,
|
|
2173
|
-
target
|
|
2174
|
-
} = this.config;
|
|
2175
|
-
const {
|
|
2176
|
-
w: bW,
|
|
2177
|
-
h: bH,
|
|
2178
|
-
data: bD,
|
|
2179
|
-
centerOffsetX,
|
|
2180
|
-
centerOffsetY
|
|
2181
|
-
} = brush;
|
|
2182
|
-
const cRGB = color & 16777215;
|
|
2183
|
-
const scratch = this.scratchBounds;
|
|
2184
|
-
let changed = false;
|
|
2185
|
-
forEachLinePoint(x0, y0, x1, y1, (px, py) => {
|
|
2186
|
-
const topLeftX = Math.floor(px + centerOffsetX);
|
|
2187
|
-
const topLeftY = Math.floor(py + centerOffsetY);
|
|
2188
|
-
trimRectBounds(topLeftX, topLeftY, bW, bH, target.width, target.height, scratch);
|
|
2189
|
-
if (scratch.w <= 0 || scratch.h <= 0) return;
|
|
2190
|
-
this.eachTileInBounds(scratch, (tile, bX, bY, bW_t, bH_t) => {
|
|
2191
|
-
const d32 = tile.data32;
|
|
2192
|
-
let tileChanged = false;
|
|
2193
|
-
for (let i = 0; i < bH_t; i++) {
|
|
2194
|
-
const canvasY = bY + i;
|
|
2195
|
-
const bOff = (canvasY - topLeftY) * bW;
|
|
2196
|
-
const tOff = (canvasY & tileMask) << tileShift;
|
|
2197
|
-
const dS = tOff + (bX & tileMask);
|
|
2198
|
-
for (let j = 0; j < bW_t; j++) {
|
|
2199
|
-
const canvasX = bX + j;
|
|
2200
|
-
const brushA = bD[bOff + (canvasX - topLeftX)];
|
|
2201
|
-
if (brushA === 0) continue;
|
|
2202
|
-
const t = cA * brushA + 128;
|
|
2203
|
-
const blendedA = t + (t >> 8) >> 8;
|
|
2204
|
-
const idx = dS + j;
|
|
2205
|
-
const cur = d32[idx];
|
|
2206
|
-
if (brushA > cur >>> 24) {
|
|
2207
|
-
const next = (cRGB | blendedA << 24) >>> 0;
|
|
2208
|
-
if (cur !== next) {
|
|
2209
|
-
d32[idx] = next;
|
|
2210
|
-
tileChanged = true;
|
|
2211
|
-
}
|
|
2212
|
-
}
|
|
2213
|
-
}
|
|
2214
|
-
}
|
|
2215
|
-
if (tileChanged) changed = true;
|
|
2216
|
-
});
|
|
2217
|
-
});
|
|
2218
|
-
return changed;
|
|
2219
|
-
}
|
|
2220
|
-
writePaintBinaryMaskStroke(color, brush, x0, y0, x1, y1) {
|
|
2221
|
-
const alphaIsZero = color >>> 24 === 0;
|
|
2222
|
-
if (alphaIsZero) return false;
|
|
2223
|
-
const {
|
|
2224
|
-
tileShift,
|
|
2225
|
-
tileMask,
|
|
2226
|
-
target
|
|
2227
|
-
} = this.config;
|
|
2228
|
-
const {
|
|
2229
|
-
w: bW,
|
|
2230
|
-
h: bH,
|
|
2231
|
-
data: bD,
|
|
2232
|
-
centerOffsetX,
|
|
2233
|
-
centerOffsetY
|
|
2234
|
-
} = brush;
|
|
2235
|
-
const scratch = this.scratchBounds;
|
|
2236
|
-
let changed = false;
|
|
2237
|
-
forEachLinePoint(x0, y0, x1, y1, (px, py) => {
|
|
2238
|
-
const topLeftX = Math.floor(px + centerOffsetX);
|
|
2239
|
-
const topLeftY = Math.floor(py + centerOffsetY);
|
|
2240
|
-
trimRectBounds(topLeftX, topLeftY, bW, bH, target.width, target.height, scratch);
|
|
2241
|
-
if (scratch.w <= 0 || scratch.h <= 0) return;
|
|
2242
|
-
this.eachTileInBounds(scratch, (tile, bX, bY, bW_t, bH_t) => {
|
|
2243
|
-
const d32 = tile.data32;
|
|
2244
|
-
let tileChanged = false;
|
|
2245
|
-
for (let i = 0; i < bH_t; i++) {
|
|
2246
|
-
const canvasY = bY + i;
|
|
2247
|
-
const bOff = (canvasY - topLeftY) * bW;
|
|
2248
|
-
const tOff = (canvasY & tileMask) << tileShift;
|
|
2249
|
-
const dS = tOff + (bX & tileMask);
|
|
2250
|
-
for (let j = 0; j < bW_t; j++) {
|
|
2251
|
-
const canvasX = bX + j;
|
|
2252
|
-
if (bD[bOff + (canvasX - topLeftX)]) {
|
|
2253
|
-
const idx = dS + j;
|
|
2254
|
-
if (d32[idx] !== color) {
|
|
2255
|
-
d32[idx] = color;
|
|
2256
|
-
tileChanged = true;
|
|
2257
|
-
}
|
|
2258
|
-
}
|
|
2259
|
-
}
|
|
2260
|
-
}
|
|
2261
|
-
if (tileChanged) changed = true;
|
|
2262
|
-
});
|
|
2263
|
-
});
|
|
2264
|
-
return changed;
|
|
2265
|
-
}
|
|
2266
|
-
writeRectStroke(color, brushWidth, brushHeight, x0, y0, x1, y1) {
|
|
2267
|
-
const alphaIsZero = color >>> 24 === 0;
|
|
2268
|
-
if (alphaIsZero) return false;
|
|
2269
|
-
const config = this.config;
|
|
2270
|
-
const tileShift = config.tileShift;
|
|
2271
|
-
const tileMask = config.tileMask;
|
|
2272
|
-
const target = config.target;
|
|
2273
|
-
const scratch = this.scratchBounds;
|
|
2274
|
-
const centerOffsetX = -(brushWidth - 1 >> 1);
|
|
2275
|
-
const centerOffsetY = -(brushHeight - 1 >> 1);
|
|
2276
|
-
let changed = false;
|
|
2277
|
-
forEachLinePoint(x0, y0, x1, y1, (px, py) => {
|
|
2278
|
-
const topLeftX = Math.floor(px + centerOffsetX);
|
|
2279
|
-
const topLeftY = Math.floor(py + centerOffsetY);
|
|
2280
|
-
trimRectBounds(topLeftX, topLeftY, brushWidth, brushHeight, target.width, target.height, scratch);
|
|
2281
|
-
if (scratch.w <= 0 || scratch.h <= 0) return;
|
|
2282
|
-
this.eachTileInBounds(scratch, (tile, bX, bY, bW_t, bH_t) => {
|
|
2283
|
-
const d32 = tile.data32;
|
|
2284
|
-
let tileChanged = false;
|
|
2285
|
-
for (let i = 0; i < bH_t; i++) {
|
|
2286
|
-
const canvasY = bY + i;
|
|
2287
|
-
const tOff = (canvasY & tileMask) << tileShift;
|
|
2288
|
-
const dS = tOff + (bX & tileMask);
|
|
2289
|
-
for (let j = 0; j < bW_t; j++) {
|
|
2290
|
-
const idx = dS + j;
|
|
2291
|
-
if (d32[idx] !== color) {
|
|
2292
|
-
d32[idx] = color;
|
|
2293
|
-
tileChanged = true;
|
|
2294
|
-
}
|
|
2295
|
-
}
|
|
2296
|
-
}
|
|
2297
|
-
if (tileChanged) {
|
|
2298
|
-
changed = true;
|
|
2299
|
-
}
|
|
2300
|
-
});
|
|
2301
|
-
});
|
|
2302
|
-
return changed;
|
|
2303
|
-
}
|
|
2304
|
-
clear() {
|
|
2305
|
-
this.tilePool.releaseTiles(this.lookup);
|
|
2306
|
-
}
|
|
2307
|
-
};
|
|
2502
|
+
// src/Tile/_tile-types.ts
|
|
2503
|
+
var TileType = /* @__PURE__ */ ((TileType2) => {
|
|
2504
|
+
TileType2[TileType2["PIXEL"] = 0] = "PIXEL";
|
|
2505
|
+
TileType2[TileType2["MASK"] = 1] = "MASK";
|
|
2506
|
+
return TileType2;
|
|
2507
|
+
})(TileType || {});
|
|
2308
2508
|
|
|
2309
|
-
// src/
|
|
2310
|
-
function
|
|
2311
|
-
const
|
|
2312
|
-
const
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
let sy = sourceY;
|
|
2324
|
-
let w = width;
|
|
2325
|
-
let h = height;
|
|
2326
|
-
if (sx < 0) {
|
|
2327
|
-
x -= sx;
|
|
2328
|
-
w += sx;
|
|
2329
|
-
sx = 0;
|
|
2330
|
-
}
|
|
2331
|
-
if (sy < 0) {
|
|
2332
|
-
y -= sy;
|
|
2333
|
-
h += sy;
|
|
2334
|
-
sy = 0;
|
|
2335
|
-
}
|
|
2336
|
-
w = Math.min(w, src.width - sx);
|
|
2337
|
-
h = Math.min(h, src.height - sy);
|
|
2338
|
-
if (x < 0) {
|
|
2339
|
-
sx -= x;
|
|
2340
|
-
w += x;
|
|
2341
|
-
x = 0;
|
|
2342
|
-
}
|
|
2343
|
-
if (y < 0) {
|
|
2344
|
-
sy -= y;
|
|
2345
|
-
h += y;
|
|
2346
|
-
y = 0;
|
|
2347
|
-
}
|
|
2348
|
-
const actualW = Math.min(w, target.width - x);
|
|
2349
|
-
const actualH = Math.min(h, target.height - y);
|
|
2350
|
-
if (actualW <= 0 || actualH <= 0) return false;
|
|
2351
|
-
const dst32 = target.data32;
|
|
2352
|
-
const src32 = src.data32;
|
|
2353
|
-
const dw = target.width;
|
|
2354
|
-
const sw = src.width;
|
|
2355
|
-
let dIdx = y * dw + x | 0;
|
|
2356
|
-
let sIdx = sy * sw + sx | 0;
|
|
2357
|
-
const dStride = dw - actualW | 0;
|
|
2358
|
-
const sStride = sw - actualW | 0;
|
|
2359
|
-
const isOpaque = globalAlpha === 255;
|
|
2360
|
-
const isOverwrite = blendFn.isOverwrite;
|
|
2361
|
-
let didChange = false;
|
|
2362
|
-
for (let iy = 0; iy < actualH; iy++) {
|
|
2363
|
-
for (let ix = 0; ix < actualW; ix++) {
|
|
2364
|
-
const srcCol = src32[sIdx];
|
|
2365
|
-
const srcAlpha = srcCol >>> 24;
|
|
2366
|
-
if (srcAlpha === 0 && !isOverwrite) {
|
|
2367
|
-
dIdx++;
|
|
2368
|
-
sIdx++;
|
|
2369
|
-
continue;
|
|
2370
|
-
}
|
|
2371
|
-
let finalCol = srcCol;
|
|
2372
|
-
if (!isOpaque) {
|
|
2373
|
-
const a = srcAlpha * globalAlpha + 128 >> 8;
|
|
2374
|
-
if (a === 0 && !isOverwrite) {
|
|
2375
|
-
dIdx++;
|
|
2376
|
-
sIdx++;
|
|
2377
|
-
continue;
|
|
2378
|
-
}
|
|
2379
|
-
finalCol = (srcCol & 16777215 | a << 24) >>> 0;
|
|
2380
|
-
}
|
|
2381
|
-
const current = dst32[dIdx];
|
|
2382
|
-
const next = blendFn(finalCol, dst32[dIdx]);
|
|
2383
|
-
if (current !== next) {
|
|
2384
|
-
dst32[dIdx] = next;
|
|
2385
|
-
didChange = true;
|
|
2386
|
-
}
|
|
2387
|
-
dIdx++;
|
|
2388
|
-
sIdx++;
|
|
2389
|
-
}
|
|
2390
|
-
dIdx += dStride;
|
|
2391
|
-
sIdx += sStride;
|
|
2392
|
-
}
|
|
2393
|
-
return didChange;
|
|
2509
|
+
// src/Tile/PixelTile.ts
|
|
2510
|
+
function makePixelTile(id, tx, ty, tileSize, tileArea) {
|
|
2511
|
+
const data32 = new Uint32Array(tileArea);
|
|
2512
|
+
const data8 = new Uint8ClampedArray(data32.buffer);
|
|
2513
|
+
return {
|
|
2514
|
+
tileType: 0 /* PIXEL */,
|
|
2515
|
+
id,
|
|
2516
|
+
tx,
|
|
2517
|
+
ty,
|
|
2518
|
+
w: tileSize,
|
|
2519
|
+
h: tileSize,
|
|
2520
|
+
data: data32,
|
|
2521
|
+
imageData: new ImageData(data8, tileSize, tileSize)
|
|
2522
|
+
};
|
|
2394
2523
|
}
|
|
2395
2524
|
|
|
2396
|
-
// src/
|
|
2397
|
-
var
|
|
2398
|
-
constructor(
|
|
2399
|
-
this.
|
|
2400
|
-
this.tx = tx;
|
|
2401
|
-
this.ty = ty;
|
|
2402
|
-
this.width = this.height = tileSize;
|
|
2403
|
-
this.data32 = new Uint32Array(tileArea);
|
|
2404
|
-
const data8 = new Uint8ClampedArray(this.data32.buffer);
|
|
2405
|
-
this.imageData = new ImageData(data8, tileSize, tileSize);
|
|
2406
|
-
}
|
|
2407
|
-
data32;
|
|
2408
|
-
width;
|
|
2409
|
-
height;
|
|
2410
|
-
imageData;
|
|
2411
|
-
};
|
|
2412
|
-
|
|
2413
|
-
// src/PixelTile/PixelTilePool.ts
|
|
2414
|
-
var PixelTilePool = class {
|
|
2415
|
-
pool;
|
|
2416
|
-
tileSize;
|
|
2417
|
-
tileArea;
|
|
2418
|
-
constructor(config) {
|
|
2525
|
+
// src/Tile/TilePool.ts
|
|
2526
|
+
var TilePool = class {
|
|
2527
|
+
constructor(config, tileFactory) {
|
|
2528
|
+
this.tileFactory = tileFactory;
|
|
2419
2529
|
this.pool = [];
|
|
2420
2530
|
this.tileSize = config.tileSize;
|
|
2421
2531
|
this.tileArea = config.tileArea;
|
|
2422
2532
|
}
|
|
2533
|
+
pool;
|
|
2534
|
+
tileSize;
|
|
2535
|
+
tileArea;
|
|
2423
2536
|
getTile(id, tx, ty) {
|
|
2424
2537
|
let tile = this.pool.pop();
|
|
2425
2538
|
if (tile) {
|
|
2426
2539
|
tile.id = id;
|
|
2427
2540
|
tile.tx = tx;
|
|
2428
2541
|
tile.ty = ty;
|
|
2429
|
-
tile.
|
|
2542
|
+
tile.data.fill(0);
|
|
2430
2543
|
return tile;
|
|
2431
2544
|
}
|
|
2432
|
-
return
|
|
2545
|
+
return this.tileFactory(id, tx, ty, this.tileSize, this.tileArea);
|
|
2433
2546
|
}
|
|
2434
2547
|
releaseTile(tile) {
|
|
2435
2548
|
this.pool.push(tile);
|
|
@@ -2453,16 +2566,7 @@ var PixelWriter = class {
|
|
|
2453
2566
|
historyActionFactory;
|
|
2454
2567
|
config;
|
|
2455
2568
|
pixelTilePool;
|
|
2456
|
-
paintBuffer;
|
|
2457
2569
|
mutator;
|
|
2458
|
-
blendPixelDataOpts = {
|
|
2459
|
-
alpha: 255,
|
|
2460
|
-
blendFn: sourceOverPerfect,
|
|
2461
|
-
x: 0,
|
|
2462
|
-
y: 0,
|
|
2463
|
-
w: 0,
|
|
2464
|
-
h: 0
|
|
2465
|
-
};
|
|
2466
2570
|
_inProgress = false;
|
|
2467
2571
|
constructor(target, mutatorFactory, options) {
|
|
2468
2572
|
const tileSize = options?.tileSize ?? 256;
|
|
@@ -2470,10 +2574,9 @@ var PixelWriter = class {
|
|
|
2470
2574
|
this.config = new PixelEngineConfig(tileSize, target);
|
|
2471
2575
|
this.historyManager = options?.historyManager ?? new HistoryManager(maxHistorySteps);
|
|
2472
2576
|
this.historyActionFactory = options?.historyActionFactory ?? makeHistoryAction;
|
|
2473
|
-
this.pixelTilePool = options?.pixelTilePool ?? new
|
|
2577
|
+
this.pixelTilePool = options?.pixelTilePool ?? new TilePool(this.config, makePixelTile);
|
|
2474
2578
|
this.accumulator = options?.accumulator ?? new PixelAccumulator(this.config, this.pixelTilePool);
|
|
2475
2579
|
this.mutator = mutatorFactory(this);
|
|
2476
|
-
this.paintBuffer = new PaintBuffer(this.config, this.pixelTilePool);
|
|
2477
2580
|
}
|
|
2478
2581
|
/**
|
|
2479
2582
|
* Executes `transaction` and commits the resulting pixel changes as a single
|
|
@@ -2519,59 +2622,37 @@ var PixelWriter = class {
|
|
|
2519
2622
|
const target = config.target;
|
|
2520
2623
|
const beforeImageData = target.imageData;
|
|
2521
2624
|
const afterImageData = resizeImageDataFn(beforeImageData, newWidth, newHeight, offsetX, offsetY);
|
|
2522
|
-
target
|
|
2625
|
+
setPixelData(target, afterImageData);
|
|
2523
2626
|
this.historyManager.commit({
|
|
2524
2627
|
undo: () => {
|
|
2525
|
-
target
|
|
2628
|
+
setPixelData(target, beforeImageData);
|
|
2526
2629
|
afterUndo?.(beforeImageData);
|
|
2527
2630
|
after?.(beforeImageData);
|
|
2528
2631
|
},
|
|
2529
2632
|
redo: () => {
|
|
2530
|
-
target
|
|
2633
|
+
setPixelData(target, afterImageData);
|
|
2531
2634
|
afterRedo?.(afterImageData);
|
|
2532
2635
|
after?.(afterImageData);
|
|
2533
2636
|
}
|
|
2534
2637
|
});
|
|
2535
2638
|
}
|
|
2536
|
-
commitPaintBuffer(alpha = 255, blendFn = sourceOverPerfect, blendPixelDataFn = blendPixelData) {
|
|
2537
|
-
const paintBuffer = this.paintBuffer;
|
|
2538
|
-
const tileShift = paintBuffer.config.tileShift;
|
|
2539
|
-
const lookup = paintBuffer.lookup;
|
|
2540
|
-
const opts = this.blendPixelDataOpts;
|
|
2541
|
-
opts.alpha = alpha;
|
|
2542
|
-
opts.blendFn = blendFn;
|
|
2543
|
-
for (let i = 0; i < lookup.length; i++) {
|
|
2544
|
-
const tile = lookup[i];
|
|
2545
|
-
if (tile) {
|
|
2546
|
-
const didChange = this.accumulator.storeTileBeforeState(tile.id, tile.tx, tile.ty);
|
|
2547
|
-
const dx = tile.tx << tileShift;
|
|
2548
|
-
const dy = tile.ty << tileShift;
|
|
2549
|
-
opts.x = dx;
|
|
2550
|
-
opts.y = dy;
|
|
2551
|
-
opts.w = tile.width;
|
|
2552
|
-
opts.h = tile.height;
|
|
2553
|
-
didChange(blendPixelDataFn(this.config.target, tile, opts));
|
|
2554
|
-
}
|
|
2555
|
-
}
|
|
2556
|
-
paintBuffer.clear();
|
|
2557
|
-
}
|
|
2558
2639
|
};
|
|
2559
2640
|
|
|
2560
2641
|
// src/History/PixelMutator/mutatorApplyAlphaMask.ts
|
|
2561
|
-
var
|
|
2642
|
+
var defaults = {
|
|
2562
2643
|
applyAlphaMaskToPixelData
|
|
2563
2644
|
};
|
|
2564
|
-
var mutatorApplyAlphaMask = ((writer, deps =
|
|
2645
|
+
var mutatorApplyAlphaMask = ((writer, deps = defaults) => {
|
|
2565
2646
|
const {
|
|
2566
|
-
applyAlphaMaskToPixelData: applyAlphaMaskToPixelData2 =
|
|
2647
|
+
applyAlphaMaskToPixelData: applyAlphaMaskToPixelData2 = defaults.applyAlphaMaskToPixelData
|
|
2567
2648
|
} = deps;
|
|
2568
2649
|
return {
|
|
2569
2650
|
applyAlphaMask(mask, opts) {
|
|
2570
2651
|
const target = writer.config.target;
|
|
2571
2652
|
const x = opts?.x ?? 0;
|
|
2572
2653
|
const y = opts?.y ?? 0;
|
|
2573
|
-
const w = opts?.w ?? target.
|
|
2574
|
-
const h = opts?.h ?? target.
|
|
2654
|
+
const w = opts?.w ?? target.w;
|
|
2655
|
+
const h = opts?.h ?? target.h;
|
|
2575
2656
|
const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h);
|
|
2576
2657
|
return didChange(applyAlphaMaskToPixelData2(target, mask, opts));
|
|
2577
2658
|
}
|
|
@@ -2582,8 +2663,8 @@ var mutatorApplyAlphaMask = ((writer, deps = defaults2) => {
|
|
|
2582
2663
|
function applyBinaryMaskToPixelData(target, mask, opts) {
|
|
2583
2664
|
const targetX = opts?.x ?? 0;
|
|
2584
2665
|
const targetY = opts?.y ?? 0;
|
|
2585
|
-
const width = opts?.w ?? target.
|
|
2586
|
-
const height = opts?.h ?? target.
|
|
2666
|
+
const width = opts?.w ?? target.w;
|
|
2667
|
+
const height = opts?.h ?? target.h;
|
|
2587
2668
|
const globalAlpha = opts?.alpha ?? 255;
|
|
2588
2669
|
const mx = opts?.mx ?? 0;
|
|
2589
2670
|
const my = opts?.my ?? 0;
|
|
@@ -2601,8 +2682,8 @@ function applyBinaryMaskToPixelData(target, mask, opts) {
|
|
|
2601
2682
|
h += y;
|
|
2602
2683
|
y = 0;
|
|
2603
2684
|
}
|
|
2604
|
-
w = Math.min(w, target.
|
|
2605
|
-
h = Math.min(h, target.
|
|
2685
|
+
w = Math.min(w, target.w - x);
|
|
2686
|
+
h = Math.min(h, target.h - y);
|
|
2606
2687
|
if (w <= 0 || h <= 0) return false;
|
|
2607
2688
|
const mPitch = mask.w;
|
|
2608
2689
|
if (mPitch <= 0) return false;
|
|
@@ -2619,8 +2700,8 @@ function applyBinaryMaskToPixelData(target, mask, opts) {
|
|
|
2619
2700
|
}
|
|
2620
2701
|
const xShift = sX0 - startX;
|
|
2621
2702
|
const yShift = sY0 - startY;
|
|
2622
|
-
const dst32 = target.
|
|
2623
|
-
const dw = target.
|
|
2703
|
+
const dst32 = target.data;
|
|
2704
|
+
const dw = target.w;
|
|
2624
2705
|
const dStride = dw - finalW;
|
|
2625
2706
|
const mStride = mPitch - finalW;
|
|
2626
2707
|
const maskData = mask.data;
|
|
@@ -2660,20 +2741,20 @@ function applyBinaryMaskToPixelData(target, mask, opts) {
|
|
|
2660
2741
|
}
|
|
2661
2742
|
|
|
2662
2743
|
// src/History/PixelMutator/mutatorApplyBinaryMask.ts
|
|
2663
|
-
var
|
|
2744
|
+
var defaults2 = {
|
|
2664
2745
|
applyBinaryMaskToPixelData
|
|
2665
2746
|
};
|
|
2666
|
-
var mutatorApplyBinaryMask = ((writer, deps =
|
|
2747
|
+
var mutatorApplyBinaryMask = ((writer, deps = defaults2) => {
|
|
2667
2748
|
const {
|
|
2668
|
-
applyBinaryMaskToPixelData: applyBinaryMaskToPixelData2 =
|
|
2749
|
+
applyBinaryMaskToPixelData: applyBinaryMaskToPixelData2 = defaults2.applyBinaryMaskToPixelData
|
|
2669
2750
|
} = deps;
|
|
2670
2751
|
return {
|
|
2671
2752
|
applyBinaryMask(mask, opts) {
|
|
2672
2753
|
const target = writer.config.target;
|
|
2673
2754
|
const x = opts?.x ?? 0;
|
|
2674
2755
|
const y = opts?.y ?? 0;
|
|
2675
|
-
const w = opts?.w ?? target.
|
|
2676
|
-
const h = opts?.h ?? target.
|
|
2756
|
+
const w = opts?.w ?? target.w;
|
|
2757
|
+
const h = opts?.h ?? target.h;
|
|
2677
2758
|
const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h);
|
|
2678
2759
|
return didChange(applyBinaryMaskToPixelData2(target, mask, opts));
|
|
2679
2760
|
}
|
|
@@ -2681,22 +2762,22 @@ var mutatorApplyBinaryMask = ((writer, deps = defaults3) => {
|
|
|
2681
2762
|
});
|
|
2682
2763
|
|
|
2683
2764
|
// src/History/PixelMutator/mutatorApplyMask.ts
|
|
2684
|
-
var
|
|
2765
|
+
var defaults3 = {
|
|
2685
2766
|
applyBinaryMaskToPixelData,
|
|
2686
2767
|
applyAlphaMaskToPixelData
|
|
2687
2768
|
};
|
|
2688
|
-
var mutatorApplyMask = ((writer, deps =
|
|
2769
|
+
var mutatorApplyMask = ((writer, deps = defaults3) => {
|
|
2689
2770
|
const {
|
|
2690
|
-
applyBinaryMaskToPixelData: applyBinaryMaskToPixelData2 =
|
|
2691
|
-
applyAlphaMaskToPixelData: applyAlphaMaskToPixelData2 =
|
|
2771
|
+
applyBinaryMaskToPixelData: applyBinaryMaskToPixelData2 = defaults3.applyBinaryMaskToPixelData,
|
|
2772
|
+
applyAlphaMaskToPixelData: applyAlphaMaskToPixelData2 = defaults3.applyAlphaMaskToPixelData
|
|
2692
2773
|
} = deps;
|
|
2693
2774
|
return {
|
|
2694
2775
|
applyMask(mask, opts) {
|
|
2695
2776
|
const target = writer.config.target;
|
|
2696
2777
|
const x = opts?.x ?? 0;
|
|
2697
2778
|
const y = opts?.y ?? 0;
|
|
2698
|
-
const w = opts?.w ?? target.
|
|
2699
|
-
const h = opts?.h ?? target.
|
|
2779
|
+
const w = opts?.w ?? target.w;
|
|
2780
|
+
const h = opts?.h ?? target.h;
|
|
2700
2781
|
const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h);
|
|
2701
2782
|
if (mask.type === 1 /* BINARY */) {
|
|
2702
2783
|
return didChange(applyBinaryMaskToPixelData2(target, mask, opts));
|
|
@@ -2713,8 +2794,8 @@ function blendPixelDataAlphaMask(target, src, alphaMask, opts) {
|
|
|
2713
2794
|
const targetY = opts?.y ?? 0;
|
|
2714
2795
|
const sourceX = opts?.sx ?? 0;
|
|
2715
2796
|
const sourceY = opts?.sy ?? 0;
|
|
2716
|
-
const width = opts?.w ?? src.
|
|
2717
|
-
const height = opts?.h ?? src.
|
|
2797
|
+
const width = opts?.w ?? src.w;
|
|
2798
|
+
const height = opts?.h ?? src.h;
|
|
2718
2799
|
const globalAlpha = opts?.alpha ?? 255;
|
|
2719
2800
|
const blendFn = opts?.blendFn ?? sourceOverPerfect;
|
|
2720
2801
|
const mx = opts?.mx ?? 0;
|
|
@@ -2737,8 +2818,8 @@ function blendPixelDataAlphaMask(target, src, alphaMask, opts) {
|
|
|
2737
2818
|
h += sy;
|
|
2738
2819
|
sy = 0;
|
|
2739
2820
|
}
|
|
2740
|
-
w = Math.min(w, src.
|
|
2741
|
-
h = Math.min(h, src.
|
|
2821
|
+
w = Math.min(w, src.w - sx);
|
|
2822
|
+
h = Math.min(h, src.h - sy);
|
|
2742
2823
|
if (x < 0) {
|
|
2743
2824
|
sx -= x;
|
|
2744
2825
|
w += x;
|
|
@@ -2749,17 +2830,17 @@ function blendPixelDataAlphaMask(target, src, alphaMask, opts) {
|
|
|
2749
2830
|
h += y;
|
|
2750
2831
|
y = 0;
|
|
2751
2832
|
}
|
|
2752
|
-
const actualW = Math.min(w, target.
|
|
2753
|
-
const actualH = Math.min(h, target.
|
|
2833
|
+
const actualW = Math.min(w, target.w - x);
|
|
2834
|
+
const actualH = Math.min(h, target.h - y);
|
|
2754
2835
|
if (actualW <= 0 || actualH <= 0) return false;
|
|
2755
|
-
const dw = target.
|
|
2756
|
-
const sw = src.
|
|
2836
|
+
const dw = target.w;
|
|
2837
|
+
const sw = src.w;
|
|
2757
2838
|
const mPitch = alphaMask.w;
|
|
2758
2839
|
const maskData = alphaMask.data;
|
|
2759
2840
|
const dx = x - targetX | 0;
|
|
2760
2841
|
const dy = y - targetY | 0;
|
|
2761
|
-
const dst32 = target.
|
|
2762
|
-
const src32 = src.
|
|
2842
|
+
const dst32 = target.data;
|
|
2843
|
+
const src32 = src.data;
|
|
2763
2844
|
let dIdx = y * dw + x | 0;
|
|
2764
2845
|
let sIdx = sy * sw + sx | 0;
|
|
2765
2846
|
let mIdx = (my + dy) * mPitch + (mx + dx) | 0;
|
|
@@ -2828,19 +2909,19 @@ function blendPixelDataAlphaMask(target, src, alphaMask, opts) {
|
|
|
2828
2909
|
}
|
|
2829
2910
|
|
|
2830
2911
|
// src/History/PixelMutator/mutatorBlendAlphaMask.ts
|
|
2831
|
-
var
|
|
2912
|
+
var defaults4 = {
|
|
2832
2913
|
blendPixelDataAlphaMask
|
|
2833
2914
|
};
|
|
2834
|
-
var mutatorBlendAlphaMask = ((writer, deps =
|
|
2915
|
+
var mutatorBlendAlphaMask = ((writer, deps = defaults4) => {
|
|
2835
2916
|
const {
|
|
2836
|
-
blendPixelDataAlphaMask: blendPixelDataAlphaMask2 =
|
|
2917
|
+
blendPixelDataAlphaMask: blendPixelDataAlphaMask2 = defaults4.blendPixelDataAlphaMask
|
|
2837
2918
|
} = deps;
|
|
2838
2919
|
return {
|
|
2839
2920
|
blendAlphaMask(src, mask, opts) {
|
|
2840
2921
|
const x = opts?.x ?? 0;
|
|
2841
2922
|
const y = opts?.y ?? 0;
|
|
2842
|
-
const w = opts?.w ?? src.
|
|
2843
|
-
const h = opts?.h ?? src.
|
|
2923
|
+
const w = opts?.w ?? src.w;
|
|
2924
|
+
const h = opts?.h ?? src.h;
|
|
2844
2925
|
const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h);
|
|
2845
2926
|
return didChange(blendPixelDataAlphaMask2(writer.config.target, src, mask, opts));
|
|
2846
2927
|
}
|
|
@@ -2853,8 +2934,8 @@ function blendPixelDataBinaryMask(target, src, binaryMask, opts) {
|
|
|
2853
2934
|
const targetY = opts?.y ?? 0;
|
|
2854
2935
|
const sourceX = opts?.sx ?? 0;
|
|
2855
2936
|
const sourceY = opts?.sy ?? 0;
|
|
2856
|
-
const width = opts?.w ?? src.
|
|
2857
|
-
const height = opts?.h ?? src.
|
|
2937
|
+
const width = opts?.w ?? src.w;
|
|
2938
|
+
const height = opts?.h ?? src.h;
|
|
2858
2939
|
const globalAlpha = opts?.alpha ?? 255;
|
|
2859
2940
|
const blendFn = opts?.blendFn ?? sourceOverPerfect;
|
|
2860
2941
|
const mx = opts?.mx ?? 0;
|
|
@@ -2877,8 +2958,8 @@ function blendPixelDataBinaryMask(target, src, binaryMask, opts) {
|
|
|
2877
2958
|
h += sy;
|
|
2878
2959
|
sy = 0;
|
|
2879
2960
|
}
|
|
2880
|
-
w = Math.min(w, src.
|
|
2881
|
-
h = Math.min(h, src.
|
|
2961
|
+
w = Math.min(w, src.w - sx);
|
|
2962
|
+
h = Math.min(h, src.h - sy);
|
|
2882
2963
|
if (x < 0) {
|
|
2883
2964
|
sx -= x;
|
|
2884
2965
|
w += x;
|
|
@@ -2889,15 +2970,15 @@ function blendPixelDataBinaryMask(target, src, binaryMask, opts) {
|
|
|
2889
2970
|
h += y;
|
|
2890
2971
|
y = 0;
|
|
2891
2972
|
}
|
|
2892
|
-
const actualW = Math.min(w, target.
|
|
2893
|
-
const actualH = Math.min(h, target.
|
|
2973
|
+
const actualW = Math.min(w, target.w - x);
|
|
2974
|
+
const actualH = Math.min(h, target.h - y);
|
|
2894
2975
|
if (actualW <= 0 || actualH <= 0) return false;
|
|
2895
2976
|
const dx = x - targetX | 0;
|
|
2896
2977
|
const dy = y - targetY | 0;
|
|
2897
|
-
const dst32 = target.
|
|
2898
|
-
const src32 = src.
|
|
2899
|
-
const dw = target.
|
|
2900
|
-
const sw = src.
|
|
2978
|
+
const dst32 = target.data;
|
|
2979
|
+
const src32 = src.data;
|
|
2980
|
+
const dw = target.w;
|
|
2981
|
+
const sw = src.w;
|
|
2901
2982
|
const mPitch = binaryMask.w;
|
|
2902
2983
|
const maskData = binaryMask.data;
|
|
2903
2984
|
let dIdx = y * dw + x | 0;
|
|
@@ -2955,19 +3036,19 @@ function blendPixelDataBinaryMask(target, src, binaryMask, opts) {
|
|
|
2955
3036
|
}
|
|
2956
3037
|
|
|
2957
3038
|
// src/History/PixelMutator/mutatorBlendBinaryMask.ts
|
|
2958
|
-
var
|
|
3039
|
+
var defaults5 = {
|
|
2959
3040
|
blendPixelDataBinaryMask
|
|
2960
3041
|
};
|
|
2961
|
-
var mutatorBlendBinaryMask = ((writer, deps =
|
|
3042
|
+
var mutatorBlendBinaryMask = ((writer, deps = defaults5) => {
|
|
2962
3043
|
const {
|
|
2963
|
-
blendPixelDataBinaryMask: blendPixelDataBinaryMask2 =
|
|
3044
|
+
blendPixelDataBinaryMask: blendPixelDataBinaryMask2 = defaults5.blendPixelDataBinaryMask
|
|
2964
3045
|
} = deps;
|
|
2965
3046
|
return {
|
|
2966
3047
|
blendBinaryMask(src, mask, opts) {
|
|
2967
3048
|
const x = opts?.x ?? 0;
|
|
2968
3049
|
const y = opts?.y ?? 0;
|
|
2969
|
-
const w = opts?.w ?? src.
|
|
2970
|
-
const h = opts?.h ?? src.
|
|
3050
|
+
const w = opts?.w ?? src.w;
|
|
3051
|
+
const h = opts?.h ?? src.h;
|
|
2971
3052
|
const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h);
|
|
2972
3053
|
return didChange(blendPixelDataBinaryMask2(writer.config.target, src, mask, opts));
|
|
2973
3054
|
}
|
|
@@ -2978,8 +3059,8 @@ var mutatorBlendBinaryMask = ((writer, deps = defaults6) => {
|
|
|
2978
3059
|
function blendColorPixelData(target, color, opts) {
|
|
2979
3060
|
const targetX = opts?.x ?? 0;
|
|
2980
3061
|
const targetY = opts?.y ?? 0;
|
|
2981
|
-
const width = opts?.w ?? target.
|
|
2982
|
-
const height = opts?.h ?? target.
|
|
3062
|
+
const width = opts?.w ?? target.w;
|
|
3063
|
+
const height = opts?.h ?? target.h;
|
|
2983
3064
|
const globalAlpha = opts?.alpha ?? 255;
|
|
2984
3065
|
const blendFn = opts?.blendFn ?? sourceOverPerfect;
|
|
2985
3066
|
if (globalAlpha === 0) return false;
|
|
@@ -2998,8 +3079,8 @@ function blendColorPixelData(target, color, opts) {
|
|
|
2998
3079
|
h += y;
|
|
2999
3080
|
y = 0;
|
|
3000
3081
|
}
|
|
3001
|
-
const actualW = Math.min(w, target.
|
|
3002
|
-
const actualH = Math.min(h, target.
|
|
3082
|
+
const actualW = Math.min(w, target.w - x);
|
|
3083
|
+
const actualH = Math.min(h, target.h - y);
|
|
3003
3084
|
if (actualW <= 0 || actualH <= 0) return false;
|
|
3004
3085
|
let finalSrcColor = color;
|
|
3005
3086
|
if (globalAlpha < 255) {
|
|
@@ -3007,8 +3088,8 @@ function blendColorPixelData(target, color, opts) {
|
|
|
3007
3088
|
if (a === 0 && !isOverwrite) return false;
|
|
3008
3089
|
finalSrcColor = (color & 16777215 | a << 24) >>> 0;
|
|
3009
3090
|
}
|
|
3010
|
-
const dst32 = target.
|
|
3011
|
-
const dw = target.
|
|
3091
|
+
const dst32 = target.data;
|
|
3092
|
+
const dw = target.w;
|
|
3012
3093
|
let dIdx = y * dw + x | 0;
|
|
3013
3094
|
const dStride = dw - actualW | 0;
|
|
3014
3095
|
let didChange = false;
|
|
@@ -3028,20 +3109,20 @@ function blendColorPixelData(target, color, opts) {
|
|
|
3028
3109
|
}
|
|
3029
3110
|
|
|
3030
3111
|
// src/History/PixelMutator/mutatorBlendColor.ts
|
|
3031
|
-
var
|
|
3112
|
+
var defaults6 = {
|
|
3032
3113
|
blendColorPixelData
|
|
3033
3114
|
};
|
|
3034
|
-
var mutatorBlendColor = ((writer, deps =
|
|
3115
|
+
var mutatorBlendColor = ((writer, deps = defaults6) => {
|
|
3035
3116
|
const {
|
|
3036
|
-
blendColorPixelData: blendColorPixelData2 =
|
|
3117
|
+
blendColorPixelData: blendColorPixelData2 = defaults6.blendColorPixelData
|
|
3037
3118
|
} = deps;
|
|
3038
3119
|
return {
|
|
3039
3120
|
blendColor(color, opts) {
|
|
3040
3121
|
const target = writer.config.target;
|
|
3041
3122
|
const x = opts?.x ?? 0;
|
|
3042
3123
|
const y = opts?.y ?? 0;
|
|
3043
|
-
const w = opts?.w ?? target.
|
|
3044
|
-
const h = opts?.h ?? target.
|
|
3124
|
+
const w = opts?.w ?? target.w;
|
|
3125
|
+
const h = opts?.h ?? target.h;
|
|
3045
3126
|
const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h);
|
|
3046
3127
|
return didChange(blendColorPixelData2(target, color, opts));
|
|
3047
3128
|
}
|
|
@@ -3075,13 +3156,13 @@ function blendColorPixelDataAlphaMask(target, color, mask, opts) {
|
|
|
3075
3156
|
actualH += y;
|
|
3076
3157
|
y = 0;
|
|
3077
3158
|
}
|
|
3078
|
-
actualW = Math.min(actualW, target.
|
|
3079
|
-
actualH = Math.min(actualH, target.
|
|
3159
|
+
actualW = Math.min(actualW, target.w - x);
|
|
3160
|
+
actualH = Math.min(actualH, target.h - y);
|
|
3080
3161
|
if (actualW <= 0 || actualH <= 0) return false;
|
|
3081
3162
|
const dx = x - targetX | 0;
|
|
3082
3163
|
const dy = y - targetY | 0;
|
|
3083
|
-
const dst32 = target.
|
|
3084
|
-
const dw = target.
|
|
3164
|
+
const dst32 = target.data;
|
|
3165
|
+
const dw = target.w;
|
|
3085
3166
|
const mPitch = mask.w;
|
|
3086
3167
|
const maskData = mask.data;
|
|
3087
3168
|
let dIdx = y * dw + x | 0;
|
|
@@ -3137,12 +3218,12 @@ function blendColorPixelDataAlphaMask(target, color, mask, opts) {
|
|
|
3137
3218
|
}
|
|
3138
3219
|
|
|
3139
3220
|
// src/History/PixelMutator/mutatorBlendColorPaintAlphaMask.ts
|
|
3140
|
-
var
|
|
3221
|
+
var defaults7 = {
|
|
3141
3222
|
blendColorPixelDataAlphaMask
|
|
3142
3223
|
};
|
|
3143
|
-
var mutatorBlendColorPaintAlphaMask = ((writer, deps =
|
|
3224
|
+
var mutatorBlendColorPaintAlphaMask = ((writer, deps = defaults7) => {
|
|
3144
3225
|
const {
|
|
3145
|
-
blendColorPixelDataAlphaMask: blendColorPixelDataAlphaMask2 =
|
|
3226
|
+
blendColorPixelDataAlphaMask: blendColorPixelDataAlphaMask2 = defaults7.blendColorPixelDataAlphaMask
|
|
3146
3227
|
} = deps;
|
|
3147
3228
|
const OPTS = {
|
|
3148
3229
|
x: 0,
|
|
@@ -3189,8 +3270,8 @@ function blendColorPixelDataBinaryMask(target, color, mask, opts) {
|
|
|
3189
3270
|
h += y;
|
|
3190
3271
|
y = 0;
|
|
3191
3272
|
}
|
|
3192
|
-
const actualW = Math.min(w, target.
|
|
3193
|
-
const actualH = Math.min(h, target.
|
|
3273
|
+
const actualW = Math.min(w, target.w - x);
|
|
3274
|
+
const actualH = Math.min(h, target.h - y);
|
|
3194
3275
|
if (actualW <= 0 || actualH <= 0) return false;
|
|
3195
3276
|
let baseColorWithGlobalAlpha = color;
|
|
3196
3277
|
if (globalAlpha < 255) {
|
|
@@ -3200,8 +3281,8 @@ function blendColorPixelDataBinaryMask(target, color, mask, opts) {
|
|
|
3200
3281
|
}
|
|
3201
3282
|
const dx = x - targetX | 0;
|
|
3202
3283
|
const dy = y - targetY | 0;
|
|
3203
|
-
const dst32 = target.
|
|
3204
|
-
const dw = target.
|
|
3284
|
+
const dst32 = target.data;
|
|
3285
|
+
const dw = target.w;
|
|
3205
3286
|
const mPitch = mask.w;
|
|
3206
3287
|
const maskData = mask.data;
|
|
3207
3288
|
let dIdx = y * dw + x | 0;
|
|
@@ -3233,12 +3314,12 @@ function blendColorPixelDataBinaryMask(target, color, mask, opts) {
|
|
|
3233
3314
|
}
|
|
3234
3315
|
|
|
3235
3316
|
// src/History/PixelMutator/mutatorBlendColorPaintBinaryMask.ts
|
|
3236
|
-
var
|
|
3317
|
+
var defaults8 = {
|
|
3237
3318
|
blendColorPixelDataBinaryMask
|
|
3238
3319
|
};
|
|
3239
|
-
var mutatorBlendColorPaintBinaryMask = ((writer, deps =
|
|
3320
|
+
var mutatorBlendColorPaintBinaryMask = ((writer, deps = defaults8) => {
|
|
3240
3321
|
const {
|
|
3241
|
-
blendColorPixelDataBinaryMask: blendColorPixelDataBinaryMask2 =
|
|
3322
|
+
blendColorPixelDataBinaryMask: blendColorPixelDataBinaryMask2 = defaults8.blendColorPixelDataBinaryMask
|
|
3242
3323
|
} = deps;
|
|
3243
3324
|
const OPTS = {
|
|
3244
3325
|
x: 0,
|
|
@@ -3261,14 +3342,14 @@ var mutatorBlendColorPaintBinaryMask = ((writer, deps = defaults9) => {
|
|
|
3261
3342
|
});
|
|
3262
3343
|
|
|
3263
3344
|
// src/History/PixelMutator/mutatorBlendColorPaintMask.ts
|
|
3264
|
-
var
|
|
3345
|
+
var defaults9 = {
|
|
3265
3346
|
blendColorPixelDataAlphaMask,
|
|
3266
3347
|
blendColorPixelDataBinaryMask
|
|
3267
3348
|
};
|
|
3268
|
-
var mutatorBlendColorPaintMask = ((writer, deps =
|
|
3349
|
+
var mutatorBlendColorPaintMask = ((writer, deps = defaults9) => {
|
|
3269
3350
|
const {
|
|
3270
|
-
blendColorPixelDataBinaryMask: blendColorPixelDataBinaryMask2 =
|
|
3271
|
-
blendColorPixelDataAlphaMask: blendColorPixelDataAlphaMask2 =
|
|
3351
|
+
blendColorPixelDataBinaryMask: blendColorPixelDataBinaryMask2 = defaults9.blendColorPixelDataBinaryMask,
|
|
3352
|
+
blendColorPixelDataAlphaMask: blendColorPixelDataAlphaMask2 = defaults9.blendColorPixelDataAlphaMask
|
|
3272
3353
|
} = deps;
|
|
3273
3354
|
const OPTS = {
|
|
3274
3355
|
x: 0,
|
|
@@ -3294,39 +3375,13 @@ var mutatorBlendColorPaintMask = ((writer, deps = defaults10) => {
|
|
|
3294
3375
|
};
|
|
3295
3376
|
});
|
|
3296
3377
|
|
|
3297
|
-
// src/History/PixelMutator/mutatorBlendMask.ts
|
|
3298
|
-
var defaults11 = {
|
|
3299
|
-
blendPixelDataAlphaMask,
|
|
3300
|
-
blendPixelDataBinaryMask
|
|
3301
|
-
};
|
|
3302
|
-
var mutatorBlendMask = ((writer, deps = defaults11) => {
|
|
3303
|
-
const {
|
|
3304
|
-
blendPixelDataAlphaMask: blendPixelDataAlphaMask2 = defaults11.blendPixelDataAlphaMask,
|
|
3305
|
-
blendPixelDataBinaryMask: blendPixelDataBinaryMask2 = defaults11.blendPixelDataBinaryMask
|
|
3306
|
-
} = deps;
|
|
3307
|
-
return {
|
|
3308
|
-
blendMask(src, mask, opts) {
|
|
3309
|
-
const x = opts?.x ?? 0;
|
|
3310
|
-
const y = opts?.y ?? 0;
|
|
3311
|
-
const w = opts?.w ?? src.width;
|
|
3312
|
-
const h = opts?.h ?? src.height;
|
|
3313
|
-
const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h);
|
|
3314
|
-
if (mask.type === 1 /* BINARY */) {
|
|
3315
|
-
return didChange(blendPixelDataBinaryMask2(writer.config.target, src, mask, opts));
|
|
3316
|
-
} else {
|
|
3317
|
-
return didChange(blendPixelDataAlphaMask2(writer.config.target, src, mask, opts));
|
|
3318
|
-
}
|
|
3319
|
-
}
|
|
3320
|
-
};
|
|
3321
|
-
});
|
|
3322
|
-
|
|
3323
3378
|
// src/History/PixelMutator/mutatorBlendColorPaintRect.ts
|
|
3324
|
-
var
|
|
3379
|
+
var defaults10 = {
|
|
3325
3380
|
blendColorPixelData
|
|
3326
3381
|
};
|
|
3327
|
-
var mutatorBlendColorPaintRect = ((writer, deps =
|
|
3382
|
+
var mutatorBlendColorPaintRect = ((writer, deps = defaults10) => {
|
|
3328
3383
|
const {
|
|
3329
|
-
blendColorPixelData: blendColorPixelData2 =
|
|
3384
|
+
blendColorPixelData: blendColorPixelData2 = defaults10.blendColorPixelData
|
|
3330
3385
|
} = deps;
|
|
3331
3386
|
const OPTS = {
|
|
3332
3387
|
x: 0,
|
|
@@ -3353,16 +3408,42 @@ var mutatorBlendColorPaintRect = ((writer, deps = defaults12) => {
|
|
|
3353
3408
|
};
|
|
3354
3409
|
});
|
|
3355
3410
|
|
|
3411
|
+
// src/History/PixelMutator/mutatorBlendMask.ts
|
|
3412
|
+
var defaults11 = {
|
|
3413
|
+
blendPixelDataAlphaMask,
|
|
3414
|
+
blendPixelDataBinaryMask
|
|
3415
|
+
};
|
|
3416
|
+
var mutatorBlendMask = ((writer, deps = defaults11) => {
|
|
3417
|
+
const {
|
|
3418
|
+
blendPixelDataAlphaMask: blendPixelDataAlphaMask2 = defaults11.blendPixelDataAlphaMask,
|
|
3419
|
+
blendPixelDataBinaryMask: blendPixelDataBinaryMask2 = defaults11.blendPixelDataBinaryMask
|
|
3420
|
+
} = deps;
|
|
3421
|
+
return {
|
|
3422
|
+
blendMask(src, mask, opts) {
|
|
3423
|
+
const x = opts?.x ?? 0;
|
|
3424
|
+
const y = opts?.y ?? 0;
|
|
3425
|
+
const w = opts?.w ?? src.w;
|
|
3426
|
+
const h = opts?.h ?? src.h;
|
|
3427
|
+
const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h);
|
|
3428
|
+
if (mask.type === 1 /* BINARY */) {
|
|
3429
|
+
return didChange(blendPixelDataBinaryMask2(writer.config.target, src, mask, opts));
|
|
3430
|
+
} else {
|
|
3431
|
+
return didChange(blendPixelDataAlphaMask2(writer.config.target, src, mask, opts));
|
|
3432
|
+
}
|
|
3433
|
+
}
|
|
3434
|
+
};
|
|
3435
|
+
});
|
|
3436
|
+
|
|
3356
3437
|
// src/PixelData/blendPixel.ts
|
|
3357
3438
|
function blendPixel(target, x, y, color, alpha = 255, blendFn = sourceOverPerfect) {
|
|
3358
3439
|
if (alpha === 0) return false;
|
|
3359
|
-
let width = target.
|
|
3360
|
-
let height = target.
|
|
3440
|
+
let width = target.w;
|
|
3441
|
+
let height = target.h;
|
|
3361
3442
|
if (x < 0 || x >= width || y < 0 || y >= height) return false;
|
|
3362
3443
|
let srcAlpha = color >>> 24;
|
|
3363
3444
|
let isOverwrite = blendFn.isOverwrite;
|
|
3364
3445
|
if (srcAlpha === 0 && !isOverwrite) return false;
|
|
3365
|
-
let dst32 = target.
|
|
3446
|
+
let dst32 = target.data;
|
|
3366
3447
|
let index = y * width + x;
|
|
3367
3448
|
let finalColor = color;
|
|
3368
3449
|
if (alpha !== 255) {
|
|
@@ -3380,12 +3461,12 @@ function blendPixel(target, x, y, color, alpha = 255, blendFn = sourceOverPerfec
|
|
|
3380
3461
|
}
|
|
3381
3462
|
|
|
3382
3463
|
// src/History/PixelMutator/mutatorBlendPixel.ts
|
|
3383
|
-
var
|
|
3464
|
+
var defaults12 = {
|
|
3384
3465
|
blendPixel
|
|
3385
3466
|
};
|
|
3386
|
-
var mutatorBlendPixel = ((writer, deps =
|
|
3467
|
+
var mutatorBlendPixel = ((writer, deps = defaults12) => {
|
|
3387
3468
|
const {
|
|
3388
|
-
blendPixel: blendPixel2 =
|
|
3469
|
+
blendPixel: blendPixel2 = defaults12.blendPixel
|
|
3389
3470
|
} = deps;
|
|
3390
3471
|
return {
|
|
3391
3472
|
blendPixel(x, y, color, alpha, blendFn) {
|
|
@@ -3395,20 +3476,107 @@ var mutatorBlendPixel = ((writer, deps = defaults13) => {
|
|
|
3395
3476
|
};
|
|
3396
3477
|
});
|
|
3397
3478
|
|
|
3479
|
+
// src/PixelData/blendPixelData.ts
|
|
3480
|
+
function blendPixelData(target, src, opts) {
|
|
3481
|
+
const targetX = opts?.x ?? 0;
|
|
3482
|
+
const targetY = opts?.y ?? 0;
|
|
3483
|
+
const sourceX = opts?.sx ?? 0;
|
|
3484
|
+
const sourceY = opts?.sy ?? 0;
|
|
3485
|
+
const width = opts?.w ?? src.w;
|
|
3486
|
+
const height = opts?.h ?? src.h;
|
|
3487
|
+
const globalAlpha = opts?.alpha ?? 255;
|
|
3488
|
+
const blendFn = opts?.blendFn ?? sourceOverPerfect;
|
|
3489
|
+
if (globalAlpha === 0) return false;
|
|
3490
|
+
let x = targetX;
|
|
3491
|
+
let y = targetY;
|
|
3492
|
+
let sx = sourceX;
|
|
3493
|
+
let sy = sourceY;
|
|
3494
|
+
let w = width;
|
|
3495
|
+
let h = height;
|
|
3496
|
+
if (sx < 0) {
|
|
3497
|
+
x -= sx;
|
|
3498
|
+
w += sx;
|
|
3499
|
+
sx = 0;
|
|
3500
|
+
}
|
|
3501
|
+
if (sy < 0) {
|
|
3502
|
+
y -= sy;
|
|
3503
|
+
h += sy;
|
|
3504
|
+
sy = 0;
|
|
3505
|
+
}
|
|
3506
|
+
w = Math.min(w, src.w - sx);
|
|
3507
|
+
h = Math.min(h, src.h - sy);
|
|
3508
|
+
if (x < 0) {
|
|
3509
|
+
sx -= x;
|
|
3510
|
+
w += x;
|
|
3511
|
+
x = 0;
|
|
3512
|
+
}
|
|
3513
|
+
if (y < 0) {
|
|
3514
|
+
sy -= y;
|
|
3515
|
+
h += y;
|
|
3516
|
+
y = 0;
|
|
3517
|
+
}
|
|
3518
|
+
const actualW = Math.min(w, target.w - x);
|
|
3519
|
+
const actualH = Math.min(h, target.h - y);
|
|
3520
|
+
if (actualW <= 0 || actualH <= 0) return false;
|
|
3521
|
+
const dst32 = target.data;
|
|
3522
|
+
const src32 = src.data;
|
|
3523
|
+
const dw = target.w;
|
|
3524
|
+
const sw = src.w;
|
|
3525
|
+
let dIdx = y * dw + x | 0;
|
|
3526
|
+
let sIdx = sy * sw + sx | 0;
|
|
3527
|
+
const dStride = dw - actualW | 0;
|
|
3528
|
+
const sStride = sw - actualW | 0;
|
|
3529
|
+
const isOpaque = globalAlpha === 255;
|
|
3530
|
+
const isOverwrite = blendFn.isOverwrite;
|
|
3531
|
+
let didChange = false;
|
|
3532
|
+
for (let iy = 0; iy < actualH; iy++) {
|
|
3533
|
+
for (let ix = 0; ix < actualW; ix++) {
|
|
3534
|
+
const srcCol = src32[sIdx];
|
|
3535
|
+
const srcAlpha = srcCol >>> 24;
|
|
3536
|
+
if (srcAlpha === 0 && !isOverwrite) {
|
|
3537
|
+
dIdx++;
|
|
3538
|
+
sIdx++;
|
|
3539
|
+
continue;
|
|
3540
|
+
}
|
|
3541
|
+
let finalCol = srcCol;
|
|
3542
|
+
if (!isOpaque) {
|
|
3543
|
+
const a = srcAlpha * globalAlpha + 128 >> 8;
|
|
3544
|
+
if (a === 0 && !isOverwrite) {
|
|
3545
|
+
dIdx++;
|
|
3546
|
+
sIdx++;
|
|
3547
|
+
continue;
|
|
3548
|
+
}
|
|
3549
|
+
finalCol = (srcCol & 16777215 | a << 24) >>> 0;
|
|
3550
|
+
}
|
|
3551
|
+
const current = dst32[dIdx];
|
|
3552
|
+
const next = blendFn(finalCol, dst32[dIdx]);
|
|
3553
|
+
if (current !== next) {
|
|
3554
|
+
dst32[dIdx] = next;
|
|
3555
|
+
didChange = true;
|
|
3556
|
+
}
|
|
3557
|
+
dIdx++;
|
|
3558
|
+
sIdx++;
|
|
3559
|
+
}
|
|
3560
|
+
dIdx += dStride;
|
|
3561
|
+
sIdx += sStride;
|
|
3562
|
+
}
|
|
3563
|
+
return didChange;
|
|
3564
|
+
}
|
|
3565
|
+
|
|
3398
3566
|
// src/History/PixelMutator/mutatorBlendPixelData.ts
|
|
3399
|
-
var
|
|
3567
|
+
var defaults13 = {
|
|
3400
3568
|
blendPixelData
|
|
3401
3569
|
};
|
|
3402
|
-
var mutatorBlendPixelData = ((writer, deps =
|
|
3570
|
+
var mutatorBlendPixelData = ((writer, deps = defaults13) => {
|
|
3403
3571
|
const {
|
|
3404
|
-
blendPixelData: blendPixelData2 =
|
|
3572
|
+
blendPixelData: blendPixelData2 = defaults13.blendPixelData
|
|
3405
3573
|
} = deps;
|
|
3406
3574
|
return {
|
|
3407
3575
|
blendPixelData(src, opts) {
|
|
3408
3576
|
const x = opts?.x ?? 0;
|
|
3409
3577
|
const y = opts?.y ?? 0;
|
|
3410
|
-
const w = opts?.w ?? src.
|
|
3411
|
-
const h = opts?.h ?? src.
|
|
3578
|
+
const w = opts?.w ?? src.w;
|
|
3579
|
+
const h = opts?.h ?? src.h;
|
|
3412
3580
|
const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h);
|
|
3413
3581
|
return didChange(blendPixelData2(writer.config.target, src, opts));
|
|
3414
3582
|
}
|
|
@@ -3425,8 +3593,8 @@ function fillPixelData(dst, color, _x, _y, _w, _h) {
|
|
|
3425
3593
|
if (typeof _x === "object") {
|
|
3426
3594
|
x = _x.x ?? 0;
|
|
3427
3595
|
y = _x.y ?? 0;
|
|
3428
|
-
w = _x.w ?? dst.
|
|
3429
|
-
h = _x.h ?? dst.
|
|
3596
|
+
w = _x.w ?? dst.w;
|
|
3597
|
+
h = _x.h ?? dst.h;
|
|
3430
3598
|
} else if (typeof _x === "number") {
|
|
3431
3599
|
x = _x;
|
|
3432
3600
|
y = _y;
|
|
@@ -3435,10 +3603,10 @@ function fillPixelData(dst, color, _x, _y, _w, _h) {
|
|
|
3435
3603
|
} else {
|
|
3436
3604
|
x = 0;
|
|
3437
3605
|
y = 0;
|
|
3438
|
-
w = dst.
|
|
3439
|
-
h = dst.
|
|
3606
|
+
w = dst.w;
|
|
3607
|
+
h = dst.h;
|
|
3440
3608
|
}
|
|
3441
|
-
const clip = resolveRectClipping(x, y, w, h, dst.
|
|
3609
|
+
const clip = resolveRectClipping(x, y, w, h, dst.w, dst.h, SCRATCH_RECT);
|
|
3442
3610
|
if (!clip.inBounds) return false;
|
|
3443
3611
|
const {
|
|
3444
3612
|
x: finalX,
|
|
@@ -3446,8 +3614,8 @@ function fillPixelData(dst, color, _x, _y, _w, _h) {
|
|
|
3446
3614
|
w: actualW,
|
|
3447
3615
|
h: actualH
|
|
3448
3616
|
} = clip;
|
|
3449
|
-
const dst32 = dst.
|
|
3450
|
-
const dw = dst.
|
|
3617
|
+
const dst32 = dst.data;
|
|
3618
|
+
const dw = dst.w;
|
|
3451
3619
|
let hasChanged = false;
|
|
3452
3620
|
for (let iy = 0; iy < actualH; iy++) {
|
|
3453
3621
|
const rowOffset = (finalY + iy) * dw;
|
|
@@ -3464,20 +3632,20 @@ function fillPixelData(dst, color, _x, _y, _w, _h) {
|
|
|
3464
3632
|
}
|
|
3465
3633
|
|
|
3466
3634
|
// src/History/PixelMutator/mutatorClear.ts
|
|
3467
|
-
var
|
|
3635
|
+
var defaults14 = {
|
|
3468
3636
|
fillPixelData
|
|
3469
3637
|
};
|
|
3470
|
-
var mutatorClear = ((writer, deps =
|
|
3638
|
+
var mutatorClear = ((writer, deps = defaults14) => {
|
|
3471
3639
|
const {
|
|
3472
|
-
fillPixelData: fillPixelData2 =
|
|
3640
|
+
fillPixelData: fillPixelData2 = defaults14.fillPixelData
|
|
3473
3641
|
} = deps;
|
|
3474
3642
|
return {
|
|
3475
3643
|
clear(rect) {
|
|
3476
3644
|
const target = writer.config.target;
|
|
3477
3645
|
const x = rect?.x ?? 0;
|
|
3478
3646
|
const y = rect?.y ?? 0;
|
|
3479
|
-
const w = rect?.w ?? target.
|
|
3480
|
-
const h = rect?.h ?? target.
|
|
3647
|
+
const w = rect?.w ?? target.w;
|
|
3648
|
+
const h = rect?.h ?? target.h;
|
|
3481
3649
|
const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h);
|
|
3482
3650
|
return didChange(fillPixelData2(target, 0, x, y, w, h));
|
|
3483
3651
|
}
|
|
@@ -3485,24 +3653,24 @@ var mutatorClear = ((writer, deps = defaults15) => {
|
|
|
3485
3653
|
});
|
|
3486
3654
|
|
|
3487
3655
|
// src/History/PixelMutator/mutatorFill.ts
|
|
3488
|
-
var
|
|
3656
|
+
var defaults15 = {
|
|
3489
3657
|
fillPixelData
|
|
3490
3658
|
};
|
|
3491
|
-
var mutatorFill = ((writer, deps =
|
|
3659
|
+
var mutatorFill = ((writer, deps = defaults15) => {
|
|
3492
3660
|
const {
|
|
3493
|
-
fillPixelData: fillPixelData2 =
|
|
3661
|
+
fillPixelData: fillPixelData2 = defaults15.fillPixelData
|
|
3494
3662
|
} = deps;
|
|
3495
3663
|
return {
|
|
3496
|
-
fill(color, x = 0, y = 0, w = writer.config.target.
|
|
3664
|
+
fill(color, x = 0, y = 0, w = writer.config.target.w, h = writer.config.target.h) {
|
|
3497
3665
|
const target = writer.config.target;
|
|
3498
3666
|
const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h);
|
|
3499
3667
|
return didChange(fillPixelData2(target, color, x, y, w, h));
|
|
3500
3668
|
}
|
|
3501
3669
|
};
|
|
3502
3670
|
});
|
|
3503
|
-
var mutatorFillRect = ((writer, deps =
|
|
3671
|
+
var mutatorFillRect = ((writer, deps = defaults15) => {
|
|
3504
3672
|
const {
|
|
3505
|
-
fillPixelData: fillPixelData2 =
|
|
3673
|
+
fillPixelData: fillPixelData2 = defaults15.fillPixelData
|
|
3506
3674
|
} = deps;
|
|
3507
3675
|
return {
|
|
3508
3676
|
fillRect(color, rect) {
|
|
@@ -3518,7 +3686,7 @@ var SCRATCH_RECT2 = makeClippedRect();
|
|
|
3518
3686
|
function fillPixelDataBinaryMask(target, color, mask, x = 0, y = 0) {
|
|
3519
3687
|
const maskW = mask.w;
|
|
3520
3688
|
const maskH = mask.h;
|
|
3521
|
-
const clip = resolveRectClipping(x, y, maskW, maskH, target.
|
|
3689
|
+
const clip = resolveRectClipping(x, y, maskW, maskH, target.w, target.h, SCRATCH_RECT2);
|
|
3522
3690
|
if (!clip.inBounds) return false;
|
|
3523
3691
|
const {
|
|
3524
3692
|
x: finalX,
|
|
@@ -3527,8 +3695,8 @@ function fillPixelDataBinaryMask(target, color, mask, x = 0, y = 0) {
|
|
|
3527
3695
|
h: actualH
|
|
3528
3696
|
} = clip;
|
|
3529
3697
|
const maskData = mask.data;
|
|
3530
|
-
const dst32 = target.
|
|
3531
|
-
const dw = target.
|
|
3698
|
+
const dst32 = target.data;
|
|
3699
|
+
const dw = target.w;
|
|
3532
3700
|
let hasChanged = false;
|
|
3533
3701
|
for (let iy = 0; iy < actualH; iy++) {
|
|
3534
3702
|
const currentY = finalY + iy;
|
|
@@ -3552,12 +3720,12 @@ function fillPixelDataBinaryMask(target, color, mask, x = 0, y = 0) {
|
|
|
3552
3720
|
}
|
|
3553
3721
|
|
|
3554
3722
|
// src/History/PixelMutator/mutatorFillBinaryMask.ts
|
|
3555
|
-
var
|
|
3723
|
+
var defaults16 = {
|
|
3556
3724
|
fillPixelDataBinaryMask
|
|
3557
3725
|
};
|
|
3558
|
-
var mutatorFillBinaryMask = ((writer, deps =
|
|
3726
|
+
var mutatorFillBinaryMask = ((writer, deps = defaults16) => {
|
|
3559
3727
|
const {
|
|
3560
|
-
fillPixelDataBinaryMask: fillPixelDataBinaryMask2 =
|
|
3728
|
+
fillPixelDataBinaryMask: fillPixelDataBinaryMask2 = defaults16.fillPixelDataBinaryMask
|
|
3561
3729
|
} = deps;
|
|
3562
3730
|
return {
|
|
3563
3731
|
fillBinaryMask(color, mask, x = 0, y = 0) {
|
|
@@ -3575,10 +3743,10 @@ function invertPixelData(target, opts) {
|
|
|
3575
3743
|
const targetY = opts?.y ?? 0;
|
|
3576
3744
|
const mx = opts?.mx ?? 0;
|
|
3577
3745
|
const my = opts?.my ?? 0;
|
|
3578
|
-
const width = opts?.w ?? target.
|
|
3579
|
-
const height = opts?.h ?? target.
|
|
3746
|
+
const width = opts?.w ?? target.w;
|
|
3747
|
+
const height = opts?.h ?? target.h;
|
|
3580
3748
|
const invertMask = opts?.invertMask ?? false;
|
|
3581
|
-
const clip = resolveRectClipping(targetX, targetY, width, height, target.
|
|
3749
|
+
const clip = resolveRectClipping(targetX, targetY, width, height, target.w, target.h, SCRATCH_RECT3);
|
|
3582
3750
|
if (!clip.inBounds) return false;
|
|
3583
3751
|
const {
|
|
3584
3752
|
x,
|
|
@@ -3586,8 +3754,8 @@ function invertPixelData(target, opts) {
|
|
|
3586
3754
|
w: actualW,
|
|
3587
3755
|
h: actualH
|
|
3588
3756
|
} = clip;
|
|
3589
|
-
const dst32 = target.
|
|
3590
|
-
const dw = target.
|
|
3757
|
+
const dst32 = target.data;
|
|
3758
|
+
const dw = target.w;
|
|
3591
3759
|
const mPitch = mask?.w ?? width;
|
|
3592
3760
|
const dx = x - targetX;
|
|
3593
3761
|
const dy = y - targetY;
|
|
@@ -3623,20 +3791,20 @@ function invertPixelData(target, opts) {
|
|
|
3623
3791
|
}
|
|
3624
3792
|
|
|
3625
3793
|
// src/History/PixelMutator/mutatorInvert.ts
|
|
3626
|
-
var
|
|
3794
|
+
var defaults17 = {
|
|
3627
3795
|
invertPixelData
|
|
3628
3796
|
};
|
|
3629
|
-
var mutatorInvert = ((writer, deps =
|
|
3797
|
+
var mutatorInvert = ((writer, deps = defaults17) => {
|
|
3630
3798
|
const {
|
|
3631
|
-
invertPixelData: invertPixelData2 =
|
|
3799
|
+
invertPixelData: invertPixelData2 = defaults17.invertPixelData
|
|
3632
3800
|
} = deps;
|
|
3633
3801
|
return {
|
|
3634
3802
|
invert(opts) {
|
|
3635
3803
|
const target = writer.config.target;
|
|
3636
3804
|
const x = opts?.x ?? 0;
|
|
3637
3805
|
const y = opts?.y ?? 0;
|
|
3638
|
-
const w = opts?.w ?? target.
|
|
3639
|
-
const h = opts?.h ?? target.
|
|
3806
|
+
const w = opts?.w ?? target.w;
|
|
3807
|
+
const h = opts?.h ?? target.h;
|
|
3640
3808
|
const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h);
|
|
3641
3809
|
return didChange(invertPixelData2(target, opts));
|
|
3642
3810
|
}
|
|
@@ -3668,30 +3836,6 @@ function makeFullPixelMutator(writer) {
|
|
|
3668
3836
|
};
|
|
3669
3837
|
}
|
|
3670
3838
|
|
|
3671
|
-
// src/ImageData/ImageDataLike.ts
|
|
3672
|
-
function makeImageDataLike(width, height, data) {
|
|
3673
|
-
const size = width * height * 4;
|
|
3674
|
-
const buffer = data ? new Uint8ClampedArray(data.buffer, data.byteOffset, size) : new Uint8ClampedArray(size);
|
|
3675
|
-
return {
|
|
3676
|
-
width,
|
|
3677
|
-
height,
|
|
3678
|
-
data: buffer
|
|
3679
|
-
};
|
|
3680
|
-
}
|
|
3681
|
-
|
|
3682
|
-
// src/ImageData/ReusableImageData.ts
|
|
3683
|
-
function makeReusableImageData() {
|
|
3684
|
-
let imageData = null;
|
|
3685
|
-
return function getReusableImageData(width, height) {
|
|
3686
|
-
if (imageData === null || imageData.width !== width || imageData.height !== height) {
|
|
3687
|
-
imageData = new ImageData(width, height);
|
|
3688
|
-
} else {
|
|
3689
|
-
imageData.data.fill(0);
|
|
3690
|
-
}
|
|
3691
|
-
return imageData;
|
|
3692
|
-
};
|
|
3693
|
-
}
|
|
3694
|
-
|
|
3695
3839
|
// src/ImageData/copyImageData.ts
|
|
3696
3840
|
function copyImageData({
|
|
3697
3841
|
data,
|
|
@@ -3712,6 +3856,17 @@ function copyImageDataLike({
|
|
|
3712
3856
|
};
|
|
3713
3857
|
}
|
|
3714
3858
|
|
|
3859
|
+
// src/ImageData/ImageDataLike.ts
|
|
3860
|
+
function makeImageDataLike(width, height, data) {
|
|
3861
|
+
const size = width * height * 4;
|
|
3862
|
+
const buffer = data ? new Uint8ClampedArray(data.buffer, data.byteOffset, size) : new Uint8ClampedArray(size);
|
|
3863
|
+
return {
|
|
3864
|
+
width,
|
|
3865
|
+
height,
|
|
3866
|
+
data: buffer
|
|
3867
|
+
};
|
|
3868
|
+
}
|
|
3869
|
+
|
|
3715
3870
|
// src/ImageData/imageDataToAlphaMaskBuffer.ts
|
|
3716
3871
|
function imageDataToAlphaMaskBuffer(imageData) {
|
|
3717
3872
|
const {
|
|
@@ -3741,8 +3896,8 @@ function imageDataToDataUrl(imageData) {
|
|
|
3741
3896
|
}
|
|
3742
3897
|
imageDataToDataUrl.reset = get.reset;
|
|
3743
3898
|
|
|
3744
|
-
// src/ImageData/
|
|
3745
|
-
function
|
|
3899
|
+
// src/ImageData/imageDataToUint32Array.ts
|
|
3900
|
+
function imageDataToUint32Array(imageData) {
|
|
3746
3901
|
return new Uint32Array(
|
|
3747
3902
|
imageData.data.buffer,
|
|
3748
3903
|
imageData.data.byteOffset,
|
|
@@ -3763,43 +3918,29 @@ function invertImageData(imageData) {
|
|
|
3763
3918
|
return imageData;
|
|
3764
3919
|
}
|
|
3765
3920
|
|
|
3766
|
-
// src/Internal/resample32.ts
|
|
3767
|
-
var resample32Scratch = {
|
|
3768
|
-
data: null,
|
|
3769
|
-
width: 0,
|
|
3770
|
-
height: 0
|
|
3771
|
-
};
|
|
3772
|
-
function resample32(srcData32, srcW, srcH, factor) {
|
|
3773
|
-
const dstW = Math.max(1, srcW * factor | 0);
|
|
3774
|
-
const dstH = Math.max(1, srcH * factor | 0);
|
|
3775
|
-
const dstData = new Int32Array(dstW * dstH);
|
|
3776
|
-
const scaleX = srcW / dstW;
|
|
3777
|
-
const scaleY = srcH / dstH;
|
|
3778
|
-
for (let y = 0; y < dstH; y++) {
|
|
3779
|
-
const srcY = Math.min(srcH - 1, y * scaleY | 0);
|
|
3780
|
-
const srcRowOffset = srcY * srcW;
|
|
3781
|
-
const dstRowOffset = y * dstW;
|
|
3782
|
-
for (let x = 0; x < dstW; x++) {
|
|
3783
|
-
const srcX = Math.min(srcW - 1, x * scaleX | 0);
|
|
3784
|
-
dstData[dstRowOffset + x] = srcData32[srcRowOffset + srcX];
|
|
3785
|
-
}
|
|
3786
|
-
}
|
|
3787
|
-
resample32Scratch.data = dstData;
|
|
3788
|
-
resample32Scratch.width = dstW;
|
|
3789
|
-
resample32Scratch.height = dstH;
|
|
3790
|
-
return resample32Scratch;
|
|
3791
|
-
}
|
|
3792
|
-
|
|
3793
3921
|
// src/ImageData/resampleImageData.ts
|
|
3794
3922
|
function resampleImageData(source, factor) {
|
|
3795
3923
|
const src32 = new Uint32Array(source.data.buffer);
|
|
3796
3924
|
const {
|
|
3797
3925
|
data,
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
} =
|
|
3926
|
+
w,
|
|
3927
|
+
h
|
|
3928
|
+
} = resampleUint32Array(src32, source.width, source.height, factor);
|
|
3801
3929
|
const uint8ClampedArray = new Uint8ClampedArray(data.buffer);
|
|
3802
|
-
return new ImageData(uint8ClampedArray,
|
|
3930
|
+
return new ImageData(uint8ClampedArray, w, h);
|
|
3931
|
+
}
|
|
3932
|
+
|
|
3933
|
+
// src/ImageData/ReusableImageData.ts
|
|
3934
|
+
function makeReusableImageData() {
|
|
3935
|
+
let imageData = null;
|
|
3936
|
+
return function getReusableImageData(width, height) {
|
|
3937
|
+
if (imageData === null || imageData.width !== width || imageData.height !== height) {
|
|
3938
|
+
imageData = new ImageData(width, height);
|
|
3939
|
+
} else {
|
|
3940
|
+
imageData.data.fill(0);
|
|
3941
|
+
}
|
|
3942
|
+
return imageData;
|
|
3943
|
+
};
|
|
3803
3944
|
}
|
|
3804
3945
|
|
|
3805
3946
|
// src/ImageData/serialization.ts
|
|
@@ -3956,89 +4097,11 @@ function writeImageDataBuffer(target, data, _x, _y, _w, _h) {
|
|
|
3956
4097
|
}
|
|
3957
4098
|
}
|
|
3958
4099
|
|
|
3959
|
-
// src/IndexedImage/IndexedImage.ts
|
|
3960
|
-
var IndexedImage = class _IndexedImage {
|
|
3961
|
-
/** The width of the image in pixels. */
|
|
3962
|
-
width;
|
|
3963
|
-
/** The height of the image in pixels. */
|
|
3964
|
-
height;
|
|
3965
|
-
/** Flat array of palette indices. Index = x + (y * width). */
|
|
3966
|
-
data;
|
|
3967
|
-
/** The palette of unique 32-bit colors (ABGR/RGBA packed) found in the image. */
|
|
3968
|
-
palette;
|
|
3969
|
-
/** The specific index in the palette reserved for fully transparent pixels. */
|
|
3970
|
-
transparentPalletIndex;
|
|
3971
|
-
/**
|
|
3972
|
-
* @param width - Image width.
|
|
3973
|
-
* @param height - Image height.
|
|
3974
|
-
* @param data - The indexed pixel data.
|
|
3975
|
-
* @param palette - The array of packed colors.
|
|
3976
|
-
* @param transparentPalletIndex - The index representing alpha 0.
|
|
3977
|
-
*/
|
|
3978
|
-
constructor(width, height, data, palette, transparentPalletIndex) {
|
|
3979
|
-
this.width = width;
|
|
3980
|
-
this.height = height;
|
|
3981
|
-
this.data = data;
|
|
3982
|
-
this.palette = palette;
|
|
3983
|
-
this.transparentPalletIndex = transparentPalletIndex;
|
|
3984
|
-
}
|
|
3985
|
-
/**
|
|
3986
|
-
* Creates an IndexedImage from standard browser ImageData.
|
|
3987
|
-
* @param imageData - The source ImageData to convert.
|
|
3988
|
-
* @returns A new IndexedImage instance.
|
|
3989
|
-
*/
|
|
3990
|
-
static fromImageData(imageData) {
|
|
3991
|
-
return _IndexedImage.fromRaw(imageData.data, imageData.width, imageData.height);
|
|
3992
|
-
}
|
|
3993
|
-
/**
|
|
3994
|
-
* Creates an IndexedImage from a raw byte buffer and dimensions.
|
|
3995
|
-
* Any pixel with an alpha channel of 0 is normalized to the transparent palette index.
|
|
3996
|
-
* @param data - Raw RGBA byte data.
|
|
3997
|
-
* @param width - Image width.
|
|
3998
|
-
* @param height - Image height.
|
|
3999
|
-
* @returns A new IndexedImage instance.
|
|
4000
|
-
*/
|
|
4001
|
-
static fromRaw(data, width, height) {
|
|
4002
|
-
const buffer = data.buffer;
|
|
4003
|
-
const rawData = new Uint32Array(buffer);
|
|
4004
|
-
const indexedData = new Int32Array(rawData.length);
|
|
4005
|
-
const colorMap = /* @__PURE__ */ new Map();
|
|
4006
|
-
const transparentColor = 0;
|
|
4007
|
-
const transparentPalletIndex = 0;
|
|
4008
|
-
colorMap.set(transparentColor, transparentPalletIndex);
|
|
4009
|
-
for (let i = 0; i < rawData.length; i++) {
|
|
4010
|
-
const pixel = rawData[i];
|
|
4011
|
-
const alpha = pixel >>> 24 & 255;
|
|
4012
|
-
const isTransparent = alpha === 0;
|
|
4013
|
-
const colorKey = isTransparent ? transparentColor : pixel >>> 0;
|
|
4014
|
-
let id = colorMap.get(colorKey);
|
|
4015
|
-
if (id === void 0) {
|
|
4016
|
-
id = colorMap.size;
|
|
4017
|
-
colorMap.set(colorKey, id);
|
|
4018
|
-
}
|
|
4019
|
-
indexedData[i] = id;
|
|
4020
|
-
}
|
|
4021
|
-
const palette = Uint32Array.from(colorMap.keys());
|
|
4022
|
-
return new _IndexedImage(width, height, indexedData, palette, transparentPalletIndex);
|
|
4023
|
-
}
|
|
4024
|
-
/**
|
|
4025
|
-
* Retrieves the 32-bit packed color value at the given coordinates.
|
|
4026
|
-
* @param x - X coordinate.
|
|
4027
|
-
* @param y - Y coordinate.
|
|
4028
|
-
* @returns The packed color from the palette.
|
|
4029
|
-
*/
|
|
4030
|
-
getColorAt(x, y) {
|
|
4031
|
-
const index = x + y * this.width;
|
|
4032
|
-
const paletteIndex = this.data[index];
|
|
4033
|
-
return this.palette[paletteIndex];
|
|
4034
|
-
}
|
|
4035
|
-
};
|
|
4036
|
-
|
|
4037
4100
|
// src/IndexedImage/getIndexedImageColorCounts.ts
|
|
4038
4101
|
function getIndexedImageColorCounts(indexedImage) {
|
|
4039
4102
|
const data = indexedImage.data;
|
|
4040
4103
|
const palette = indexedImage.palette;
|
|
4041
|
-
const frequencies = new
|
|
4104
|
+
const frequencies = new Uint32Array(palette.length);
|
|
4042
4105
|
for (let i = 0; i < data.length; i++) {
|
|
4043
4106
|
const colorIndex = data[i];
|
|
4044
4107
|
frequencies[colorIndex]++;
|
|
@@ -4046,6 +4109,48 @@ function getIndexedImageColorCounts(indexedImage) {
|
|
|
4046
4109
|
return frequencies;
|
|
4047
4110
|
}
|
|
4048
4111
|
|
|
4112
|
+
// src/IndexedImage/IndexedImage.ts
|
|
4113
|
+
function makeIndexedImage(width, height, data, palette, transparentPalletIndex) {
|
|
4114
|
+
return {
|
|
4115
|
+
w: width,
|
|
4116
|
+
h: height,
|
|
4117
|
+
data,
|
|
4118
|
+
palette,
|
|
4119
|
+
transparentPalletIndex
|
|
4120
|
+
};
|
|
4121
|
+
}
|
|
4122
|
+
function makeIndexedImageFromImageDataRaw(data, width, height) {
|
|
4123
|
+
const buffer = data.buffer;
|
|
4124
|
+
const rawData = new Uint32Array(buffer);
|
|
4125
|
+
const indexedData = new Uint32Array(rawData.length);
|
|
4126
|
+
const colorMap = /* @__PURE__ */ new Map();
|
|
4127
|
+
const transparentColor = 0;
|
|
4128
|
+
const transparentPalletIndex = 0;
|
|
4129
|
+
colorMap.set(transparentColor, transparentPalletIndex);
|
|
4130
|
+
for (let i = 0; i < rawData.length; i++) {
|
|
4131
|
+
const pixel = rawData[i];
|
|
4132
|
+
const alpha = pixel >>> 24 & 255;
|
|
4133
|
+
const isTransparent = alpha === 0;
|
|
4134
|
+
const colorKey = isTransparent ? transparentColor : pixel >>> 0;
|
|
4135
|
+
let id = colorMap.get(colorKey);
|
|
4136
|
+
if (id === void 0) {
|
|
4137
|
+
id = colorMap.size;
|
|
4138
|
+
colorMap.set(colorKey, id);
|
|
4139
|
+
}
|
|
4140
|
+
indexedData[i] = id;
|
|
4141
|
+
}
|
|
4142
|
+
const palette = Uint32Array.from(colorMap.keys());
|
|
4143
|
+
return makeIndexedImage(width, height, indexedData, palette, transparentPalletIndex);
|
|
4144
|
+
}
|
|
4145
|
+
function makeIndexedImageFromImageData(imageData) {
|
|
4146
|
+
return makeIndexedImageFromImageDataRaw(imageData.data, imageData.width, imageData.height);
|
|
4147
|
+
}
|
|
4148
|
+
function getIndexedImageColor(target, x, y) {
|
|
4149
|
+
const index = x + y * target.w;
|
|
4150
|
+
const paletteIndex = target.data[index];
|
|
4151
|
+
return target.palette[paletteIndex];
|
|
4152
|
+
}
|
|
4153
|
+
|
|
4049
4154
|
// src/IndexedImage/indexedImageToAverageColor.ts
|
|
4050
4155
|
function indexedImageToAverageColor(indexedImage, includeTransparent = false) {
|
|
4051
4156
|
const {
|
|
@@ -4095,29 +4200,27 @@ function indexedImageToAverageColor(indexedImage, includeTransparent = false) {
|
|
|
4095
4200
|
// src/IndexedImage/indexedImageToImageData.ts
|
|
4096
4201
|
function indexedImageToImageData(indexedImage) {
|
|
4097
4202
|
const {
|
|
4098
|
-
|
|
4099
|
-
|
|
4203
|
+
w,
|
|
4204
|
+
h,
|
|
4100
4205
|
data,
|
|
4101
4206
|
palette
|
|
4102
4207
|
} = indexedImage;
|
|
4103
|
-
const result = new ImageData(
|
|
4208
|
+
const result = new ImageData(w, h);
|
|
4104
4209
|
const data32 = new Uint32Array(result.data.buffer);
|
|
4105
4210
|
for (let i = 0; i < data.length; i++) {
|
|
4106
4211
|
const paletteIndex = data[i];
|
|
4107
|
-
|
|
4108
|
-
data32[i] = color;
|
|
4212
|
+
data32[i] = palette[paletteIndex];
|
|
4109
4213
|
}
|
|
4110
4214
|
return result;
|
|
4111
4215
|
}
|
|
4112
4216
|
|
|
4113
4217
|
// src/IndexedImage/resampleIndexedImage.ts
|
|
4114
4218
|
function resampleIndexedImage(source, factor) {
|
|
4115
|
-
const {
|
|
4116
|
-
|
|
4117
|
-
|
|
4118
|
-
|
|
4119
|
-
|
|
4120
|
-
return new IndexedImage(width, height, data, source.palette, source.transparentPalletIndex);
|
|
4219
|
+
const output = {
|
|
4220
|
+
palette: source.palette,
|
|
4221
|
+
transparentPalletIndex: source.transparentPalletIndex
|
|
4222
|
+
};
|
|
4223
|
+
return resampleUint32Array(source.data, source.w, source.h, factor, output);
|
|
4121
4224
|
}
|
|
4122
4225
|
|
|
4123
4226
|
// src/Input/fileInputChangeToImageData.ts
|
|
@@ -4193,16 +4296,6 @@ function makeAlphaMask(w, h, data) {
|
|
|
4193
4296
|
};
|
|
4194
4297
|
}
|
|
4195
4298
|
|
|
4196
|
-
// src/Mask/BinaryMask.ts
|
|
4197
|
-
function makeBinaryMask(w, h, data) {
|
|
4198
|
-
return {
|
|
4199
|
-
type: 1 /* BINARY */,
|
|
4200
|
-
data: data ?? new Uint8Array(w * h),
|
|
4201
|
-
w,
|
|
4202
|
-
h
|
|
4203
|
-
};
|
|
4204
|
-
}
|
|
4205
|
-
|
|
4206
4299
|
// src/Mask/applyBinaryMaskToAlphaMask.ts
|
|
4207
4300
|
function applyBinaryMaskToAlphaMask(alphaMaskDst, binaryMaskSrc, opts) {
|
|
4208
4301
|
const targetX = opts?.x ?? 0;
|
|
@@ -4272,6 +4365,215 @@ function applyBinaryMaskToAlphaMask(alphaMaskDst, binaryMaskSrc, opts) {
|
|
|
4272
4365
|
}
|
|
4273
4366
|
}
|
|
4274
4367
|
|
|
4368
|
+
// src/Mask/BinaryMask.ts
|
|
4369
|
+
function makeBinaryMask(w, h, data) {
|
|
4370
|
+
return {
|
|
4371
|
+
type: 1 /* BINARY */,
|
|
4372
|
+
data: data ?? new Uint8Array(w * h),
|
|
4373
|
+
w,
|
|
4374
|
+
h
|
|
4375
|
+
};
|
|
4376
|
+
}
|
|
4377
|
+
|
|
4378
|
+
// src/Mask/BinaryMask/makeBinaryMaskFromAlphaMask.ts
|
|
4379
|
+
function makeBinaryMaskFromAlphaMask(mask, threshold, out) {
|
|
4380
|
+
const w = mask.w;
|
|
4381
|
+
const h = mask.h;
|
|
4382
|
+
const alphaData = mask.data;
|
|
4383
|
+
const area = w * h;
|
|
4384
|
+
const binaryData = new Uint8Array(area);
|
|
4385
|
+
for (let i = 0; i < area; i++) {
|
|
4386
|
+
if (alphaData[i] >= threshold) {
|
|
4387
|
+
binaryData[i] = 1;
|
|
4388
|
+
}
|
|
4389
|
+
}
|
|
4390
|
+
out = out ?? {
|
|
4391
|
+
type: 1 /* BINARY */
|
|
4392
|
+
};
|
|
4393
|
+
out.data = binaryData;
|
|
4394
|
+
out.w = w;
|
|
4395
|
+
out.h = h;
|
|
4396
|
+
return out;
|
|
4397
|
+
}
|
|
4398
|
+
|
|
4399
|
+
// src/Mask/BinaryMask/makeBinaryMaskOutline.ts
|
|
4400
|
+
function makeBinaryMaskOutline(mask, scale = 1) {
|
|
4401
|
+
const w = mask.w;
|
|
4402
|
+
const h = mask.h;
|
|
4403
|
+
const maskData = mask.data;
|
|
4404
|
+
const size = w * scale + 2;
|
|
4405
|
+
const outData = new Uint8Array(size * size);
|
|
4406
|
+
for (let iy = 0; iy < h; iy++) {
|
|
4407
|
+
for (let ix = 0; ix < w; ix++) {
|
|
4408
|
+
const i = iy * w + ix;
|
|
4409
|
+
if (maskData[i] === 0) continue;
|
|
4410
|
+
const lx = ix * scale + 1;
|
|
4411
|
+
const ly = iy * scale + 1;
|
|
4412
|
+
const top = iy === 0 || maskData[i - w] === 0;
|
|
4413
|
+
const bottom = iy === h - 1 || maskData[i + w] === 0;
|
|
4414
|
+
const left = ix === 0 || maskData[i - 1] === 0;
|
|
4415
|
+
const right = ix === w - 1 || maskData[i + 1] === 0;
|
|
4416
|
+
const topLeft = iy === 0 || ix === 0 || maskData[i - w - 1] === 0;
|
|
4417
|
+
const topRight = iy === 0 || ix === w - 1 || maskData[i - w + 1] === 0;
|
|
4418
|
+
const bottomLeft = iy === h - 1 || ix === 0 || maskData[i + w - 1] === 0;
|
|
4419
|
+
const bottomRight = iy === h - 1 || ix === w - 1 || maskData[i + w + 1] === 0;
|
|
4420
|
+
if (top) {
|
|
4421
|
+
for (let sx = 0; sx < scale; sx++) {
|
|
4422
|
+
const outIdx = (ly - 1) * size + (lx + sx);
|
|
4423
|
+
outData[outIdx] = 1;
|
|
4424
|
+
}
|
|
4425
|
+
}
|
|
4426
|
+
if (bottom) {
|
|
4427
|
+
for (let sx = 0; sx < scale; sx++) {
|
|
4428
|
+
const outIdx = (ly + scale) * size + (lx + sx);
|
|
4429
|
+
outData[outIdx] = 1;
|
|
4430
|
+
}
|
|
4431
|
+
}
|
|
4432
|
+
if (left) {
|
|
4433
|
+
for (let sy = 0; sy < scale; sy++) {
|
|
4434
|
+
const outIdx = (ly + sy) * size + (lx - 1);
|
|
4435
|
+
outData[outIdx] = 1;
|
|
4436
|
+
}
|
|
4437
|
+
}
|
|
4438
|
+
if (right) {
|
|
4439
|
+
for (let sy = 0; sy < scale; sy++) {
|
|
4440
|
+
const outIdx = (ly + sy) * size + (lx + scale);
|
|
4441
|
+
outData[outIdx] = 1;
|
|
4442
|
+
}
|
|
4443
|
+
}
|
|
4444
|
+
if (topLeft) {
|
|
4445
|
+
const outIdx = (ly - 1) * size + (lx - 1);
|
|
4446
|
+
outData[outIdx] = 1;
|
|
4447
|
+
}
|
|
4448
|
+
if (topRight) {
|
|
4449
|
+
const outIdx = (ly - 1) * size + (lx + scale);
|
|
4450
|
+
outData[outIdx] = 1;
|
|
4451
|
+
}
|
|
4452
|
+
if (bottomLeft) {
|
|
4453
|
+
const outIdx = (ly + scale) * size + (lx - 1);
|
|
4454
|
+
outData[outIdx] = 1;
|
|
4455
|
+
}
|
|
4456
|
+
if (bottomRight) {
|
|
4457
|
+
const outIdx = (ly + scale) * size + (lx + scale);
|
|
4458
|
+
outData[outIdx] = 1;
|
|
4459
|
+
}
|
|
4460
|
+
}
|
|
4461
|
+
}
|
|
4462
|
+
return {
|
|
4463
|
+
type: 1 /* BINARY */,
|
|
4464
|
+
w: size,
|
|
4465
|
+
h: size,
|
|
4466
|
+
data: outData
|
|
4467
|
+
};
|
|
4468
|
+
}
|
|
4469
|
+
|
|
4470
|
+
// src/Mask/BinaryMask/makeCircleBinaryMaskOutline.ts
|
|
4471
|
+
function makeCircleBinaryMaskOutline(size, scale) {
|
|
4472
|
+
const outSize = size * scale + 2;
|
|
4473
|
+
const outArea = outSize * outSize;
|
|
4474
|
+
const data = new Uint8Array(outArea);
|
|
4475
|
+
const radius = size / 2;
|
|
4476
|
+
const r2 = radius * radius;
|
|
4477
|
+
let prevMinX = -1;
|
|
4478
|
+
let prevMaxX = -1;
|
|
4479
|
+
let currMinX = -1;
|
|
4480
|
+
let currMaxX = -1;
|
|
4481
|
+
const initialDy = 0 - radius + 0.5;
|
|
4482
|
+
const initialDy2 = initialDy * initialDy;
|
|
4483
|
+
if (initialDy2 <= r2) {
|
|
4484
|
+
const dx = Math.sqrt(r2 - initialDy2);
|
|
4485
|
+
currMinX = Math.ceil(radius - 0.5 - dx);
|
|
4486
|
+
currMaxX = Math.floor(radius - 0.5 + dx);
|
|
4487
|
+
}
|
|
4488
|
+
for (let iy = 0; iy < size; iy++) {
|
|
4489
|
+
let nextMinX = -1;
|
|
4490
|
+
let nextMaxX = -1;
|
|
4491
|
+
if (iy + 1 < size) {
|
|
4492
|
+
const ny = iy + 1 - radius + 0.5;
|
|
4493
|
+
const ny2 = ny * ny;
|
|
4494
|
+
if (ny2 <= r2) {
|
|
4495
|
+
const dx = Math.sqrt(r2 - ny2);
|
|
4496
|
+
nextMinX = Math.ceil(radius - 0.5 - dx);
|
|
4497
|
+
nextMaxX = Math.floor(radius - 0.5 + dx);
|
|
4498
|
+
}
|
|
4499
|
+
}
|
|
4500
|
+
if (currMinX !== -1) {
|
|
4501
|
+
for (let ix = currMinX; ix <= currMaxX; ix++) {
|
|
4502
|
+
const sx = ix * scale + 1;
|
|
4503
|
+
const sy = iy * scale + 1;
|
|
4504
|
+
const isTop = prevMinX === -1 || ix < prevMinX || ix > prevMaxX;
|
|
4505
|
+
const isBottom = nextMinX === -1 || ix < nextMinX || ix > nextMaxX;
|
|
4506
|
+
const isLeft = ix === currMinX;
|
|
4507
|
+
const isRight = ix === currMaxX;
|
|
4508
|
+
if (isTop) {
|
|
4509
|
+
const leftOut = prevMinX === -1 || ix - 1 < prevMinX || ix - 1 > prevMaxX;
|
|
4510
|
+
const rightOut = prevMinX === -1 || ix + 1 < prevMinX || ix + 1 > prevMaxX;
|
|
4511
|
+
const startX = leftOut ? sx - 1 : sx;
|
|
4512
|
+
const endX = rightOut ? sx + scale : sx + scale - 1;
|
|
4513
|
+
for (let x = startX; x <= endX; x++) {
|
|
4514
|
+
const index = (sy - 1) * outSize + x;
|
|
4515
|
+
data[index] = 1;
|
|
4516
|
+
}
|
|
4517
|
+
}
|
|
4518
|
+
if (isBottom) {
|
|
4519
|
+
const leftOut = nextMinX === -1 || ix - 1 < nextMinX || ix - 1 > nextMaxX;
|
|
4520
|
+
const rightOut = nextMinX === -1 || ix + 1 < nextMinX || ix + 1 > nextMaxX;
|
|
4521
|
+
const startX = leftOut ? sx - 1 : sx;
|
|
4522
|
+
const endX = rightOut ? sx + scale : sx + scale - 1;
|
|
4523
|
+
for (let x = startX; x <= endX; x++) {
|
|
4524
|
+
const index = (sy + scale) * outSize + x;
|
|
4525
|
+
data[index] = 1;
|
|
4526
|
+
}
|
|
4527
|
+
}
|
|
4528
|
+
if (isLeft) {
|
|
4529
|
+
for (let y = sy; y < sy + scale; y++) {
|
|
4530
|
+
const index = y * outSize + (sx - 1);
|
|
4531
|
+
data[index] = 1;
|
|
4532
|
+
}
|
|
4533
|
+
}
|
|
4534
|
+
if (isRight) {
|
|
4535
|
+
for (let y = sy; y < sy + scale; y++) {
|
|
4536
|
+
const index = y * outSize + (sx + scale);
|
|
4537
|
+
data[index] = 1;
|
|
4538
|
+
}
|
|
4539
|
+
}
|
|
4540
|
+
}
|
|
4541
|
+
}
|
|
4542
|
+
prevMinX = currMinX;
|
|
4543
|
+
prevMaxX = currMaxX;
|
|
4544
|
+
currMinX = nextMinX;
|
|
4545
|
+
currMaxX = nextMaxX;
|
|
4546
|
+
}
|
|
4547
|
+
return {
|
|
4548
|
+
type: 1 /* BINARY */,
|
|
4549
|
+
w: outSize,
|
|
4550
|
+
h: outSize,
|
|
4551
|
+
data
|
|
4552
|
+
};
|
|
4553
|
+
}
|
|
4554
|
+
|
|
4555
|
+
// src/Mask/BinaryMask/makeRectBinaryMaskOutline.ts
|
|
4556
|
+
function makeRectBinaryMaskOutline(w, h, scale = 1) {
|
|
4557
|
+
const rw = w * scale;
|
|
4558
|
+
const rh = h * scale;
|
|
4559
|
+
const outW = rw + 2;
|
|
4560
|
+
const outH = rh + 2;
|
|
4561
|
+
const outData = new Uint8Array(outW * outH);
|
|
4562
|
+
outData.fill(1, 0, outW);
|
|
4563
|
+
outData.fill(1, (outH - 1) * outW, outH * outW);
|
|
4564
|
+
for (let iy = 1; iy < outH - 1; iy++) {
|
|
4565
|
+
const rowStart = iy * outW;
|
|
4566
|
+
outData[rowStart] = 1;
|
|
4567
|
+
outData[rowStart + outW - 1] = 1;
|
|
4568
|
+
}
|
|
4569
|
+
return {
|
|
4570
|
+
type: 1 /* BINARY */,
|
|
4571
|
+
w: outW,
|
|
4572
|
+
h: outH,
|
|
4573
|
+
data: outData
|
|
4574
|
+
};
|
|
4575
|
+
}
|
|
4576
|
+
|
|
4275
4577
|
// src/Mask/copyMask.ts
|
|
4276
4578
|
function copyMask(src) {
|
|
4277
4579
|
return {
|
|
@@ -4379,7 +4681,8 @@ function mergeAlphaMasks(dst, src, opts) {
|
|
|
4379
4681
|
} else if (globalAlpha === 255) {
|
|
4380
4682
|
weight = effectiveM;
|
|
4381
4683
|
} else {
|
|
4382
|
-
|
|
4684
|
+
const t = effectiveM * globalAlpha + 128;
|
|
4685
|
+
weight = t + (t >> 8) >> 8;
|
|
4383
4686
|
}
|
|
4384
4687
|
if (weight !== 255) {
|
|
4385
4688
|
if (weight === 0) {
|
|
@@ -4389,7 +4692,8 @@ function mergeAlphaMasks(dst, src, opts) {
|
|
|
4389
4692
|
if (da === 255) {
|
|
4390
4693
|
dstData[dIdx] = weight;
|
|
4391
4694
|
} else if (da !== 0) {
|
|
4392
|
-
|
|
4695
|
+
const t = da * weight + 128;
|
|
4696
|
+
dstData[dIdx] = t + (t >> 8) >> 8;
|
|
4393
4697
|
}
|
|
4394
4698
|
}
|
|
4395
4699
|
}
|
|
@@ -4634,189 +4938,1007 @@ function pushPiece(dest, r, x, y, w, h) {
|
|
|
4634
4938
|
});
|
|
4635
4939
|
}
|
|
4636
4940
|
|
|
4637
|
-
// src/Paint/
|
|
4638
|
-
|
|
4639
|
-
|
|
4640
|
-
|
|
4641
|
-
|
|
4642
|
-
|
|
4643
|
-
|
|
4644
|
-
const ctx = canvas.getContext("2d");
|
|
4645
|
-
if (!ctx) throw new Error(CANVAS_CTX_FAILED);
|
|
4646
|
-
ctx.imageSmoothingEnabled = false;
|
|
4647
|
-
return function drawPaintBuffer(targetCtx, alpha = 255, compOperation = "source-over") {
|
|
4648
|
-
targetCtx.globalAlpha = alpha / 255;
|
|
4649
|
-
targetCtx.globalCompositeOperation = compOperation;
|
|
4650
|
-
for (let i = 0; i < lookup.length; i++) {
|
|
4651
|
-
const tile = lookup[i];
|
|
4652
|
-
if (tile) {
|
|
4653
|
-
const dx = tile.tx << tileShift;
|
|
4654
|
-
const dy = tile.ty << tileShift;
|
|
4655
|
-
ctx.putImageData(tile.imageData, 0, 0);
|
|
4656
|
-
targetCtx.drawImage(canvas, dx, dy);
|
|
4657
|
-
}
|
|
4658
|
-
}
|
|
4659
|
-
targetCtx.globalAlpha = 1;
|
|
4660
|
-
targetCtx.globalCompositeOperation = "source-over";
|
|
4661
|
-
};
|
|
4662
|
-
}
|
|
4941
|
+
// src/Paint/_paint-types.ts
|
|
4942
|
+
var PaintMaskOutline = /* @__PURE__ */ ((PaintMaskOutline2) => {
|
|
4943
|
+
PaintMaskOutline2[PaintMaskOutline2["MASKED"] = 0] = "MASKED";
|
|
4944
|
+
PaintMaskOutline2[PaintMaskOutline2["CIRCLE"] = 1] = "CIRCLE";
|
|
4945
|
+
PaintMaskOutline2[PaintMaskOutline2["RECT"] = 2] = "RECT";
|
|
4946
|
+
return PaintMaskOutline2;
|
|
4947
|
+
})(PaintMaskOutline || {});
|
|
4663
4948
|
|
|
4664
|
-
// src/
|
|
4665
|
-
function
|
|
4666
|
-
const
|
|
4667
|
-
|
|
4668
|
-
|
|
4669
|
-
|
|
4670
|
-
|
|
4671
|
-
for (let y = 0; y < size; y++) {
|
|
4672
|
-
const rowOffset = y * size;
|
|
4673
|
-
const dy = y - radius + 0.5;
|
|
4674
|
-
const dy2 = dy * dy;
|
|
4675
|
-
for (let x = 0; x < size; x++) {
|
|
4676
|
-
const dx = x - radius + 0.5;
|
|
4677
|
-
const distSqr = dx * dx + dy2;
|
|
4678
|
-
if (distSqr <= radius * radius) {
|
|
4679
|
-
const dist = Math.sqrt(distSqr) * invR;
|
|
4680
|
-
const strength = fallOff(1 - dist);
|
|
4681
|
-
if (strength > 0) {
|
|
4682
|
-
const intensity = strength * 255 | 0;
|
|
4683
|
-
data[rowOffset + x] = Math.max(0, Math.min(255, intensity));
|
|
4684
|
-
}
|
|
4685
|
-
}
|
|
4686
|
-
}
|
|
4687
|
-
}
|
|
4688
|
-
return {
|
|
4689
|
-
type: 0 /* ALPHA */,
|
|
4690
|
-
data,
|
|
4691
|
-
w: size,
|
|
4692
|
-
h: size,
|
|
4693
|
-
centerOffsetX: centerOffset,
|
|
4694
|
-
centerOffsetY: centerOffset
|
|
4949
|
+
// src/Rect/trimRectBounds.ts
|
|
4950
|
+
function trimRectBounds(x, y, w, h, targetWidth, targetHeight, out) {
|
|
4951
|
+
const res = out ?? {
|
|
4952
|
+
x: 0,
|
|
4953
|
+
y: 0,
|
|
4954
|
+
w: 0,
|
|
4955
|
+
h: 0
|
|
4695
4956
|
};
|
|
4957
|
+
const left = Math.max(0, x);
|
|
4958
|
+
const top = Math.max(0, y);
|
|
4959
|
+
const right = Math.min(targetWidth, x + w);
|
|
4960
|
+
const bottom = Math.min(targetHeight, y + h);
|
|
4961
|
+
res.x = left;
|
|
4962
|
+
res.y = top;
|
|
4963
|
+
res.w = Math.max(0, right - left);
|
|
4964
|
+
res.h = Math.max(0, bottom - top);
|
|
4965
|
+
return res;
|
|
4696
4966
|
}
|
|
4697
4967
|
|
|
4698
|
-
// src/Paint/
|
|
4699
|
-
function
|
|
4700
|
-
const
|
|
4701
|
-
|
|
4702
|
-
|
|
4703
|
-
|
|
4704
|
-
|
|
4705
|
-
|
|
4706
|
-
|
|
4707
|
-
|
|
4708
|
-
|
|
4709
|
-
|
|
4710
|
-
|
|
4711
|
-
|
|
4968
|
+
// src/Paint/eachTileInBounds.ts
|
|
4969
|
+
function eachTileInBounds(config, lookup, tilePool, bounds, callback) {
|
|
4970
|
+
const {
|
|
4971
|
+
tileShift,
|
|
4972
|
+
targetColumns,
|
|
4973
|
+
targetRows,
|
|
4974
|
+
tileSize
|
|
4975
|
+
} = config;
|
|
4976
|
+
const x1 = Math.max(0, bounds.x >> tileShift);
|
|
4977
|
+
const y1 = Math.max(0, bounds.y >> tileShift);
|
|
4978
|
+
const x2 = Math.min(targetColumns - 1, bounds.x + bounds.w - 1 >> tileShift);
|
|
4979
|
+
const y2 = Math.min(targetRows - 1, bounds.y + bounds.h - 1 >> tileShift);
|
|
4980
|
+
if (x1 > x2 || y1 > y2) return;
|
|
4981
|
+
for (let ty = y1; ty <= y2; ty++) {
|
|
4982
|
+
const rowOffset = ty * targetColumns;
|
|
4983
|
+
const tileTop = ty << tileShift;
|
|
4984
|
+
for (let tx = x1; tx <= x2; tx++) {
|
|
4985
|
+
const id = rowOffset + tx;
|
|
4986
|
+
const tile = lookup[id] ?? (lookup[id] = tilePool.getTile(id, tx, ty));
|
|
4987
|
+
const tileLeft = tx << tileShift;
|
|
4988
|
+
const startX = bounds.x > tileLeft ? bounds.x : tileLeft;
|
|
4989
|
+
const startY = bounds.y > tileTop ? bounds.y : tileTop;
|
|
4990
|
+
const maskEndX = bounds.x + bounds.w;
|
|
4991
|
+
const tileEndX = tileLeft + tileSize;
|
|
4992
|
+
const endX = maskEndX < tileEndX ? maskEndX : tileEndX;
|
|
4993
|
+
const maskEndY = bounds.y + bounds.h;
|
|
4994
|
+
const tileEndY = tileTop + tileSize;
|
|
4995
|
+
const endY = maskEndY < tileEndY ? maskEndY : tileEndY;
|
|
4996
|
+
callback(tile, startX, startY, endX - startX, endY - startY);
|
|
4712
4997
|
}
|
|
4713
4998
|
}
|
|
4714
|
-
return {
|
|
4715
|
-
type: 1 /* BINARY */,
|
|
4716
|
-
data,
|
|
4717
|
-
w: size,
|
|
4718
|
-
h: size,
|
|
4719
|
-
centerOffsetX: centerOffset,
|
|
4720
|
-
centerOffsetY: centerOffset
|
|
4721
|
-
};
|
|
4722
|
-
}
|
|
4723
|
-
|
|
4724
|
-
// src/Paint/makePaintMask.ts
|
|
4725
|
-
function makePaintBinaryMask(mask) {
|
|
4726
|
-
return {
|
|
4727
|
-
type: 1 /* BINARY */,
|
|
4728
|
-
data: mask.data,
|
|
4729
|
-
w: mask.w,
|
|
4730
|
-
h: mask.h,
|
|
4731
|
-
centerOffsetX: -(mask.w >> 1),
|
|
4732
|
-
centerOffsetY: -(mask.h >> 1)
|
|
4733
|
-
};
|
|
4734
|
-
}
|
|
4735
|
-
function makePaintAlphaMask(mask) {
|
|
4736
|
-
return {
|
|
4737
|
-
type: 0 /* ALPHA */,
|
|
4738
|
-
data: mask.data,
|
|
4739
|
-
w: mask.w,
|
|
4740
|
-
h: mask.h,
|
|
4741
|
-
centerOffsetX: -(mask.w >> 1),
|
|
4742
|
-
centerOffsetY: -(mask.h >> 1)
|
|
4743
|
-
};
|
|
4744
4999
|
}
|
|
4745
5000
|
|
|
4746
|
-
// src/Paint/
|
|
4747
|
-
|
|
4748
|
-
|
|
4749
|
-
|
|
4750
|
-
|
|
4751
|
-
|
|
4752
|
-
const offX = width % 2 === 0 ? 0.5 : 0;
|
|
4753
|
-
const offY = height % 2 === 0 ? 0.5 : 0;
|
|
4754
|
-
const area = width * height;
|
|
4755
|
-
const data = new Uint8Array(area);
|
|
4756
|
-
for (let y = 0; y < height; y++) {
|
|
4757
|
-
const dy = Math.abs(y - fPy + offY) * invHalfH;
|
|
4758
|
-
const rowOffset = y * width;
|
|
4759
|
-
for (let x = 0; x < width; x++) {
|
|
4760
|
-
const dx = Math.abs(x - fPx + offX) * invHalfW;
|
|
4761
|
-
const dist = dx > dy ? dx : dy;
|
|
4762
|
-
const strength = fallOff(1 - dist);
|
|
4763
|
-
if (strength > 0) {
|
|
4764
|
-
const intensity = strength * 255 | 0;
|
|
4765
|
-
data[rowOffset + x] = Math.max(0, Math.min(255, intensity));
|
|
4766
|
-
}
|
|
4767
|
-
}
|
|
5001
|
+
// src/Paint/AlphaMaskPaintBuffer.ts
|
|
5002
|
+
var AlphaMaskPaintBuffer = class {
|
|
5003
|
+
constructor(config, tilePool) {
|
|
5004
|
+
this.config = config;
|
|
5005
|
+
this.tilePool = tilePool;
|
|
5006
|
+
this.lookup = [];
|
|
4768
5007
|
}
|
|
4769
|
-
|
|
4770
|
-
|
|
4771
|
-
|
|
4772
|
-
|
|
4773
|
-
|
|
4774
|
-
|
|
4775
|
-
|
|
5008
|
+
lookup;
|
|
5009
|
+
scratchBounds = {
|
|
5010
|
+
x: 0,
|
|
5011
|
+
y: 0,
|
|
5012
|
+
w: 0,
|
|
5013
|
+
h: 0
|
|
5014
|
+
};
|
|
5015
|
+
forEachLinePointFn = forEachLinePoint;
|
|
5016
|
+
trimRectBoundsFn = trimRectBounds;
|
|
5017
|
+
eachTileInBoundsFn = eachTileInBounds;
|
|
5018
|
+
paintAlphaMask(brush, x0, y0, x1 = x0, y1 = y0) {
|
|
5019
|
+
const scratch = this.scratchBounds;
|
|
5020
|
+
const lookup = this.lookup;
|
|
5021
|
+
const tilePool = this.tilePool;
|
|
5022
|
+
const config = this.config;
|
|
5023
|
+
const tileShift = config.tileShift;
|
|
5024
|
+
const tileMask = config.tileMask;
|
|
5025
|
+
const target = config.target;
|
|
5026
|
+
const {
|
|
5027
|
+
w: bW,
|
|
5028
|
+
h: bH,
|
|
5029
|
+
data: bD,
|
|
5030
|
+
centerOffsetX,
|
|
5031
|
+
centerOffsetY
|
|
5032
|
+
} = brush;
|
|
5033
|
+
let changed = false;
|
|
5034
|
+
const eachTileInBoundsFn = this.eachTileInBoundsFn;
|
|
5035
|
+
const trimRectBoundsFn = this.trimRectBoundsFn;
|
|
5036
|
+
this.forEachLinePointFn(x0, y0, x1, y1, (px, py) => {
|
|
5037
|
+
const topLeftX = Math.floor(px + centerOffsetX);
|
|
5038
|
+
const topLeftY = Math.floor(py + centerOffsetY);
|
|
5039
|
+
trimRectBoundsFn(topLeftX, topLeftY, bW, bH, target.w, target.h, scratch);
|
|
5040
|
+
if (scratch.w <= 0 || scratch.h <= 0) return;
|
|
5041
|
+
eachTileInBoundsFn(config, lookup, tilePool, scratch, (tile, bX, bY, bW_t, bH_t) => {
|
|
5042
|
+
const data = tile.data;
|
|
5043
|
+
let tileChanged = false;
|
|
5044
|
+
for (let i = 0; i < bH_t; i++) {
|
|
5045
|
+
const canvasY = bY + i;
|
|
5046
|
+
const bOff = (canvasY - topLeftY) * bW;
|
|
5047
|
+
const tOff = (canvasY & tileMask) << tileShift;
|
|
5048
|
+
const dS = tOff + (bX & tileMask);
|
|
5049
|
+
for (let j = 0; j < bW_t; j++) {
|
|
5050
|
+
const canvasX = bX + j;
|
|
5051
|
+
const brushA = bD[bOff + (canvasX - topLeftX)];
|
|
5052
|
+
if (brushA === 0) continue;
|
|
5053
|
+
const idx = dS + j;
|
|
5054
|
+
if (brushA > data[idx]) {
|
|
5055
|
+
data[idx] = brushA;
|
|
5056
|
+
tileChanged = true;
|
|
5057
|
+
}
|
|
5058
|
+
}
|
|
5059
|
+
}
|
|
5060
|
+
if (tileChanged) changed = true;
|
|
5061
|
+
});
|
|
5062
|
+
});
|
|
5063
|
+
return changed;
|
|
5064
|
+
}
|
|
5065
|
+
paintBinaryMask(brush, alpha, x0, y0, x1 = x0, y1 = y0) {
|
|
5066
|
+
if (alpha === 0) return false;
|
|
5067
|
+
const scratch = this.scratchBounds;
|
|
5068
|
+
const lookup = this.lookup;
|
|
5069
|
+
const tilePool = this.tilePool;
|
|
5070
|
+
const config = this.config;
|
|
5071
|
+
const tileShift = config.tileShift;
|
|
5072
|
+
const tileMask = config.tileMask;
|
|
5073
|
+
const target = config.target;
|
|
5074
|
+
const {
|
|
5075
|
+
w: bW,
|
|
5076
|
+
h: bH,
|
|
5077
|
+
data: bD,
|
|
5078
|
+
centerOffsetX,
|
|
5079
|
+
centerOffsetY
|
|
5080
|
+
} = brush;
|
|
5081
|
+
let changed = false;
|
|
5082
|
+
const trimRectBoundsFn = this.trimRectBoundsFn;
|
|
5083
|
+
const eachTileInBoundsFn = this.eachTileInBoundsFn;
|
|
5084
|
+
this.forEachLinePointFn(x0, y0, x1, y1, (px, py) => {
|
|
5085
|
+
const topLeftX = Math.floor(px + centerOffsetX);
|
|
5086
|
+
const topLeftY = Math.floor(py + centerOffsetY);
|
|
5087
|
+
trimRectBoundsFn(topLeftX, topLeftY, bW, bH, target.w, target.h, scratch);
|
|
5088
|
+
if (scratch.w <= 0 || scratch.h <= 0) return;
|
|
5089
|
+
eachTileInBoundsFn(config, lookup, tilePool, scratch, (tile, bX, bY, bW_t, bH_t) => {
|
|
5090
|
+
const data = tile.data;
|
|
5091
|
+
let tileChanged = false;
|
|
5092
|
+
for (let i = 0; i < bH_t; i++) {
|
|
5093
|
+
const canvasY = bY + i;
|
|
5094
|
+
const bOff = (canvasY - topLeftY) * bW;
|
|
5095
|
+
const tOff = (canvasY & tileMask) << tileShift;
|
|
5096
|
+
const dS = tOff + (bX & tileMask);
|
|
5097
|
+
for (let j = 0; j < bW_t; j++) {
|
|
5098
|
+
const canvasX = bX + j;
|
|
5099
|
+
if (bD[bOff + (canvasX - topLeftX)]) {
|
|
5100
|
+
const idx = dS + j;
|
|
5101
|
+
if (data[idx] < alpha) {
|
|
5102
|
+
data[idx] = alpha;
|
|
5103
|
+
tileChanged = true;
|
|
5104
|
+
}
|
|
5105
|
+
}
|
|
5106
|
+
}
|
|
5107
|
+
}
|
|
5108
|
+
if (tileChanged) changed = true;
|
|
5109
|
+
});
|
|
5110
|
+
});
|
|
5111
|
+
return changed;
|
|
5112
|
+
}
|
|
5113
|
+
paintRect(alpha, brushWidth, brushHeight, x0, y0, x1 = x0, y1 = y0) {
|
|
5114
|
+
const scratch = this.scratchBounds;
|
|
5115
|
+
const lookup = this.lookup;
|
|
5116
|
+
const tilePool = this.tilePool;
|
|
5117
|
+
const config = this.config;
|
|
5118
|
+
const tileShift = config.tileShift;
|
|
5119
|
+
const tileMask = config.tileMask;
|
|
5120
|
+
const target = config.target;
|
|
5121
|
+
const centerOffsetX = -(brushWidth - 1 >> 1);
|
|
5122
|
+
const centerOffsetY = -(brushHeight - 1 >> 1);
|
|
5123
|
+
const trimRectBoundsFn = this.trimRectBoundsFn;
|
|
5124
|
+
const eachTileInBoundsFn = this.eachTileInBoundsFn;
|
|
5125
|
+
let changed = false;
|
|
5126
|
+
this.forEachLinePointFn(x0, y0, x1, y1, (px, py) => {
|
|
5127
|
+
const topLeftX = Math.floor(px + centerOffsetX);
|
|
5128
|
+
const topLeftY = Math.floor(py + centerOffsetY);
|
|
5129
|
+
trimRectBoundsFn(topLeftX, topLeftY, brushWidth, brushHeight, target.w, target.h, scratch);
|
|
5130
|
+
if (scratch.w <= 0 || scratch.h <= 0) return;
|
|
5131
|
+
eachTileInBoundsFn(config, lookup, tilePool, scratch, (tile, bX, bY, bW_t, bH_t) => {
|
|
5132
|
+
const data = tile.data;
|
|
5133
|
+
let tileChanged = false;
|
|
5134
|
+
for (let i = 0; i < bH_t; i++) {
|
|
5135
|
+
const canvasY = bY + i;
|
|
5136
|
+
const tOff = (canvasY & tileMask) << tileShift;
|
|
5137
|
+
const dS = tOff + (bX & tileMask);
|
|
5138
|
+
for (let j = 0; j < bW_t; j++) {
|
|
5139
|
+
const idx = dS + j;
|
|
5140
|
+
if (alpha > data[idx]) {
|
|
5141
|
+
data[idx] = alpha;
|
|
5142
|
+
tileChanged = true;
|
|
5143
|
+
}
|
|
5144
|
+
}
|
|
5145
|
+
}
|
|
5146
|
+
if (tileChanged) {
|
|
5147
|
+
changed = true;
|
|
5148
|
+
}
|
|
5149
|
+
});
|
|
5150
|
+
});
|
|
5151
|
+
return changed;
|
|
5152
|
+
}
|
|
5153
|
+
clear() {
|
|
5154
|
+
this.tilePool.releaseTiles(this.lookup);
|
|
5155
|
+
}
|
|
5156
|
+
};
|
|
5157
|
+
|
|
5158
|
+
// src/Paint/BinaryMaskPaintBuffer.ts
|
|
5159
|
+
var BinaryMaskPaintBuffer = class {
|
|
5160
|
+
constructor(config, tilePool) {
|
|
5161
|
+
this.config = config;
|
|
5162
|
+
this.tilePool = tilePool;
|
|
5163
|
+
this.lookup = [];
|
|
5164
|
+
}
|
|
5165
|
+
lookup;
|
|
5166
|
+
scratchBounds = {
|
|
5167
|
+
x: 0,
|
|
5168
|
+
y: 0,
|
|
5169
|
+
w: 0,
|
|
5170
|
+
h: 0
|
|
5171
|
+
};
|
|
5172
|
+
forEachLinePointFn = forEachLinePoint;
|
|
5173
|
+
trimRectBoundsFn = trimRectBounds;
|
|
5174
|
+
eachTileInBoundsFn = eachTileInBounds;
|
|
5175
|
+
paintBinaryMask(brush, x0, y0, x1 = x0, y1 = y0) {
|
|
5176
|
+
const scratch = this.scratchBounds;
|
|
5177
|
+
const lookup = this.lookup;
|
|
5178
|
+
const tilePool = this.tilePool;
|
|
5179
|
+
const config = this.config;
|
|
5180
|
+
const tileShift = config.tileShift;
|
|
5181
|
+
const tileMask = config.tileMask;
|
|
5182
|
+
const target = config.target;
|
|
5183
|
+
const {
|
|
5184
|
+
w: bW,
|
|
5185
|
+
h: bH,
|
|
5186
|
+
data: bD,
|
|
5187
|
+
centerOffsetX,
|
|
5188
|
+
centerOffsetY
|
|
5189
|
+
} = brush;
|
|
5190
|
+
let changed = false;
|
|
5191
|
+
const trimRectBoundsFn = this.trimRectBoundsFn;
|
|
5192
|
+
const eachTileInBoundsFn = this.eachTileInBoundsFn;
|
|
5193
|
+
this.forEachLinePointFn(x0, y0, x1, y1, (px, py) => {
|
|
5194
|
+
const topLeftX = Math.floor(px + centerOffsetX);
|
|
5195
|
+
const topLeftY = Math.floor(py + centerOffsetY);
|
|
5196
|
+
trimRectBoundsFn(topLeftX, topLeftY, bW, bH, target.w, target.h, scratch);
|
|
5197
|
+
if (scratch.w <= 0 || scratch.h <= 0) return;
|
|
5198
|
+
eachTileInBoundsFn(config, lookup, tilePool, scratch, (tile, bX, bY, bW_t, bH_t) => {
|
|
5199
|
+
const data = tile.data;
|
|
5200
|
+
let tileChanged = false;
|
|
5201
|
+
for (let i = 0; i < bH_t; i++) {
|
|
5202
|
+
const canvasY = bY + i;
|
|
5203
|
+
const bOff = (canvasY - topLeftY) * bW;
|
|
5204
|
+
const tOff = (canvasY & tileMask) << tileShift;
|
|
5205
|
+
const dS = tOff + (bX & tileMask);
|
|
5206
|
+
for (let j = 0; j < bW_t; j++) {
|
|
5207
|
+
const canvasX = bX + j;
|
|
5208
|
+
if (bD[bOff + (canvasX - topLeftX)]) {
|
|
5209
|
+
const idx = dS + j;
|
|
5210
|
+
if (data[idx] === 0) {
|
|
5211
|
+
data[idx] = 1;
|
|
5212
|
+
tileChanged = true;
|
|
5213
|
+
}
|
|
5214
|
+
}
|
|
5215
|
+
}
|
|
5216
|
+
}
|
|
5217
|
+
if (tileChanged) changed = true;
|
|
5218
|
+
});
|
|
5219
|
+
});
|
|
5220
|
+
return changed;
|
|
5221
|
+
}
|
|
5222
|
+
paintRect(brushWidth, brushHeight, x0, y0, x1 = x0, y1 = y0) {
|
|
5223
|
+
const scratch = this.scratchBounds;
|
|
5224
|
+
const lookup = this.lookup;
|
|
5225
|
+
const tilePool = this.tilePool;
|
|
5226
|
+
const config = this.config;
|
|
5227
|
+
const tileShift = config.tileShift;
|
|
5228
|
+
const tileMask = config.tileMask;
|
|
5229
|
+
const target = config.target;
|
|
5230
|
+
const centerOffsetX = -(brushWidth - 1 >> 1);
|
|
5231
|
+
const centerOffsetY = -(brushHeight - 1 >> 1);
|
|
5232
|
+
const trimRectBoundsFn = this.trimRectBoundsFn;
|
|
5233
|
+
const eachTileInBoundsFn = this.eachTileInBoundsFn;
|
|
5234
|
+
let changed = false;
|
|
5235
|
+
this.forEachLinePointFn(x0, y0, x1, y1, (px, py) => {
|
|
5236
|
+
const topLeftX = Math.floor(px + centerOffsetX);
|
|
5237
|
+
const topLeftY = Math.floor(py + centerOffsetY);
|
|
5238
|
+
trimRectBoundsFn(topLeftX, topLeftY, brushWidth, brushHeight, target.w, target.h, scratch);
|
|
5239
|
+
if (scratch.w <= 0 || scratch.h <= 0) return;
|
|
5240
|
+
eachTileInBoundsFn(config, lookup, tilePool, scratch, (tile, bX, bY, bW_t, bH_t) => {
|
|
5241
|
+
const data = tile.data;
|
|
5242
|
+
let tileChanged = false;
|
|
5243
|
+
for (let i = 0; i < bH_t; i++) {
|
|
5244
|
+
const canvasY = bY + i;
|
|
5245
|
+
const tOff = (canvasY & tileMask) << tileShift;
|
|
5246
|
+
const dS = tOff + (bX & tileMask);
|
|
5247
|
+
for (let j = 0; j < bW_t; j++) {
|
|
5248
|
+
const idx = dS + j;
|
|
5249
|
+
if (data[idx] === 0) {
|
|
5250
|
+
data[idx] = 1;
|
|
5251
|
+
tileChanged = true;
|
|
5252
|
+
}
|
|
5253
|
+
}
|
|
5254
|
+
}
|
|
5255
|
+
if (tileChanged) {
|
|
5256
|
+
changed = true;
|
|
5257
|
+
}
|
|
5258
|
+
});
|
|
5259
|
+
});
|
|
5260
|
+
return changed;
|
|
5261
|
+
}
|
|
5262
|
+
clear() {
|
|
5263
|
+
this.tilePool.releaseTiles(this.lookup);
|
|
5264
|
+
}
|
|
5265
|
+
};
|
|
5266
|
+
|
|
5267
|
+
// src/Paint/ColorPaintBuffer.ts
|
|
5268
|
+
var ColorPaintBuffer = class {
|
|
5269
|
+
constructor(config, tilePool) {
|
|
5270
|
+
this.config = config;
|
|
5271
|
+
this.tilePool = tilePool;
|
|
5272
|
+
this.lookup = [];
|
|
5273
|
+
}
|
|
5274
|
+
lookup;
|
|
5275
|
+
scratchBounds = {
|
|
5276
|
+
x: 0,
|
|
5277
|
+
y: 0,
|
|
5278
|
+
w: 0,
|
|
5279
|
+
h: 0
|
|
5280
|
+
};
|
|
5281
|
+
paintAlphaMask(color, brush, x0, y0, x1 = x0, y1 = y0) {
|
|
5282
|
+
const cA = color >>> 24;
|
|
5283
|
+
if (cA === 0) return false;
|
|
5284
|
+
const scratch = this.scratchBounds;
|
|
5285
|
+
const lookup = this.lookup;
|
|
5286
|
+
const tilePool = this.tilePool;
|
|
5287
|
+
const config = this.config;
|
|
5288
|
+
const tileShift = config.tileShift;
|
|
5289
|
+
const tileMask = config.tileMask;
|
|
5290
|
+
const target = config.target;
|
|
5291
|
+
const {
|
|
5292
|
+
w: bW,
|
|
5293
|
+
h: bH,
|
|
5294
|
+
data: bD,
|
|
5295
|
+
centerOffsetX,
|
|
5296
|
+
centerOffsetY
|
|
5297
|
+
} = brush;
|
|
5298
|
+
const cRGB = color & 16777215;
|
|
5299
|
+
let changed = false;
|
|
5300
|
+
forEachLinePoint(x0, y0, x1, y1, (px, py) => {
|
|
5301
|
+
const topLeftX = Math.floor(px + centerOffsetX);
|
|
5302
|
+
const topLeftY = Math.floor(py + centerOffsetY);
|
|
5303
|
+
trimRectBounds(topLeftX, topLeftY, bW, bH, target.w, target.h, scratch);
|
|
5304
|
+
if (scratch.w <= 0 || scratch.h <= 0) return;
|
|
5305
|
+
eachTileInBounds(config, lookup, tilePool, scratch, (tile, bX, bY, bW_t, bH_t) => {
|
|
5306
|
+
const d32 = tile.data;
|
|
5307
|
+
let tileChanged = false;
|
|
5308
|
+
for (let i = 0; i < bH_t; i++) {
|
|
5309
|
+
const canvasY = bY + i;
|
|
5310
|
+
const bOff = (canvasY - topLeftY) * bW;
|
|
5311
|
+
const tOff = (canvasY & tileMask) << tileShift;
|
|
5312
|
+
const dS = tOff + (bX & tileMask);
|
|
5313
|
+
for (let j = 0; j < bW_t; j++) {
|
|
5314
|
+
const canvasX = bX + j;
|
|
5315
|
+
const brushA = bD[bOff + (canvasX - topLeftX)];
|
|
5316
|
+
if (brushA === 0) continue;
|
|
5317
|
+
const t = cA * brushA + 128;
|
|
5318
|
+
const blendedA = t + (t >> 8) >> 8;
|
|
5319
|
+
const idx = dS + j;
|
|
5320
|
+
const cur = d32[idx];
|
|
5321
|
+
if (brushA > cur >>> 24) {
|
|
5322
|
+
const next = (cRGB | blendedA << 24) >>> 0;
|
|
5323
|
+
if (cur !== next) {
|
|
5324
|
+
d32[idx] = next;
|
|
5325
|
+
tileChanged = true;
|
|
5326
|
+
}
|
|
5327
|
+
}
|
|
5328
|
+
}
|
|
5329
|
+
}
|
|
5330
|
+
if (tileChanged) changed = true;
|
|
5331
|
+
});
|
|
5332
|
+
});
|
|
5333
|
+
return changed;
|
|
5334
|
+
}
|
|
5335
|
+
paintBinaryMask(color, brush, x0, y0, x1 = x0, y1 = y0) {
|
|
5336
|
+
const alphaIsZero = color >>> 24 === 0;
|
|
5337
|
+
if (alphaIsZero) return false;
|
|
5338
|
+
const scratch = this.scratchBounds;
|
|
5339
|
+
const lookup = this.lookup;
|
|
5340
|
+
const tilePool = this.tilePool;
|
|
5341
|
+
const config = this.config;
|
|
5342
|
+
const tileShift = config.tileShift;
|
|
5343
|
+
const tileMask = config.tileMask;
|
|
5344
|
+
const target = config.target;
|
|
5345
|
+
const {
|
|
5346
|
+
w: bW,
|
|
5347
|
+
h: bH,
|
|
5348
|
+
data: bD,
|
|
5349
|
+
centerOffsetX,
|
|
5350
|
+
centerOffsetY
|
|
5351
|
+
} = brush;
|
|
5352
|
+
let changed = false;
|
|
5353
|
+
forEachLinePoint(x0, y0, x1, y1, (px, py) => {
|
|
5354
|
+
const topLeftX = Math.floor(px + centerOffsetX);
|
|
5355
|
+
const topLeftY = Math.floor(py + centerOffsetY);
|
|
5356
|
+
trimRectBounds(topLeftX, topLeftY, bW, bH, target.w, target.h, scratch);
|
|
5357
|
+
if (scratch.w <= 0 || scratch.h <= 0) return;
|
|
5358
|
+
eachTileInBounds(config, lookup, tilePool, scratch, (tile, bX, bY, bW_t, bH_t) => {
|
|
5359
|
+
const d32 = tile.data;
|
|
5360
|
+
let tileChanged = false;
|
|
5361
|
+
for (let i = 0; i < bH_t; i++) {
|
|
5362
|
+
const canvasY = bY + i;
|
|
5363
|
+
const bOff = (canvasY - topLeftY) * bW;
|
|
5364
|
+
const tOff = (canvasY & tileMask) << tileShift;
|
|
5365
|
+
const dS = tOff + (bX & tileMask);
|
|
5366
|
+
for (let j = 0; j < bW_t; j++) {
|
|
5367
|
+
const canvasX = bX + j;
|
|
5368
|
+
if (bD[bOff + (canvasX - topLeftX)]) {
|
|
5369
|
+
const idx = dS + j;
|
|
5370
|
+
if (d32[idx] !== color) {
|
|
5371
|
+
d32[idx] = color;
|
|
5372
|
+
tileChanged = true;
|
|
5373
|
+
}
|
|
5374
|
+
}
|
|
5375
|
+
}
|
|
5376
|
+
}
|
|
5377
|
+
if (tileChanged) changed = true;
|
|
5378
|
+
});
|
|
5379
|
+
});
|
|
5380
|
+
return changed;
|
|
5381
|
+
}
|
|
5382
|
+
paintRect(color, brushWidth, brushHeight, x0, y0, x1 = x0, y1 = y0) {
|
|
5383
|
+
const alphaIsZero = color >>> 24 === 0;
|
|
5384
|
+
if (alphaIsZero) return false;
|
|
5385
|
+
const scratch = this.scratchBounds;
|
|
5386
|
+
const lookup = this.lookup;
|
|
5387
|
+
const tilePool = this.tilePool;
|
|
5388
|
+
const config = this.config;
|
|
5389
|
+
const tileShift = config.tileShift;
|
|
5390
|
+
const tileMask = config.tileMask;
|
|
5391
|
+
const target = config.target;
|
|
5392
|
+
const centerOffsetX = -(brushWidth - 1 >> 1);
|
|
5393
|
+
const centerOffsetY = -(brushHeight - 1 >> 1);
|
|
5394
|
+
let changed = false;
|
|
5395
|
+
forEachLinePoint(x0, y0, x1, y1, (px, py) => {
|
|
5396
|
+
const topLeftX = Math.floor(px + centerOffsetX);
|
|
5397
|
+
const topLeftY = Math.floor(py + centerOffsetY);
|
|
5398
|
+
trimRectBounds(topLeftX, topLeftY, brushWidth, brushHeight, target.w, target.h, scratch);
|
|
5399
|
+
if (scratch.w <= 0 || scratch.h <= 0) return;
|
|
5400
|
+
eachTileInBounds(config, lookup, tilePool, scratch, (tile, bX, bY, bW_t, bH_t) => {
|
|
5401
|
+
const d32 = tile.data;
|
|
5402
|
+
let tileChanged = false;
|
|
5403
|
+
for (let i = 0; i < bH_t; i++) {
|
|
5404
|
+
const canvasY = bY + i;
|
|
5405
|
+
const tOff = (canvasY & tileMask) << tileShift;
|
|
5406
|
+
const dS = tOff + (bX & tileMask);
|
|
5407
|
+
for (let j = 0; j < bW_t; j++) {
|
|
5408
|
+
const idx = dS + j;
|
|
5409
|
+
if (d32[idx] !== color) {
|
|
5410
|
+
d32[idx] = color;
|
|
5411
|
+
tileChanged = true;
|
|
5412
|
+
}
|
|
5413
|
+
}
|
|
5414
|
+
}
|
|
5415
|
+
if (tileChanged) {
|
|
5416
|
+
changed = true;
|
|
5417
|
+
}
|
|
5418
|
+
});
|
|
5419
|
+
});
|
|
5420
|
+
return changed;
|
|
5421
|
+
}
|
|
5422
|
+
clear() {
|
|
5423
|
+
this.tilePool.releaseTiles(this.lookup);
|
|
5424
|
+
}
|
|
5425
|
+
};
|
|
5426
|
+
|
|
5427
|
+
// src/Paint/Commit/commitMaskPaintBuffer.ts
|
|
5428
|
+
var SCRATCH_OPTS = {
|
|
5429
|
+
alpha: 255,
|
|
5430
|
+
blendFn: sourceOverPerfect,
|
|
5431
|
+
x: 0,
|
|
5432
|
+
y: 0,
|
|
5433
|
+
w: 0,
|
|
5434
|
+
h: 0
|
|
5435
|
+
};
|
|
5436
|
+
function commitMaskPaintBuffer(accumulator, paintBuffer, color, alpha = 255, blendFn = sourceOverPerfect, blendColorPixelDataMaskFn) {
|
|
5437
|
+
const config = accumulator.config;
|
|
5438
|
+
const tileShift = config.tileShift;
|
|
5439
|
+
const lookup = paintBuffer.lookup;
|
|
5440
|
+
SCRATCH_OPTS.alpha = alpha;
|
|
5441
|
+
SCRATCH_OPTS.blendFn = blendFn;
|
|
5442
|
+
for (let i = 0; i < lookup.length; i++) {
|
|
5443
|
+
const tile = lookup[i];
|
|
5444
|
+
if (tile) {
|
|
5445
|
+
const didChange = accumulator.storeTileBeforeState(tile.id, tile.tx, tile.ty);
|
|
5446
|
+
const dx = tile.tx << tileShift;
|
|
5447
|
+
const dy = tile.ty << tileShift;
|
|
5448
|
+
SCRATCH_OPTS.x = dx;
|
|
5449
|
+
SCRATCH_OPTS.y = dy;
|
|
5450
|
+
SCRATCH_OPTS.w = tile.w;
|
|
5451
|
+
SCRATCH_OPTS.h = tile.h;
|
|
5452
|
+
didChange(blendColorPixelDataMaskFn(config.target, color, tile, SCRATCH_OPTS));
|
|
5453
|
+
}
|
|
5454
|
+
}
|
|
5455
|
+
paintBuffer.clear();
|
|
5456
|
+
}
|
|
5457
|
+
|
|
5458
|
+
// src/Paint/Commit/AlphaMaskPaintBufferCommitter.ts
|
|
5459
|
+
function makeAlphaMaskPaintBufferCommitter(accumulator, paintBuffer) {
|
|
5460
|
+
return function commitAlphaMaskPaintBufferToAccumulator(color, alpha = 255, blendFn = sourceOverPerfect) {
|
|
5461
|
+
return commitMaskPaintBuffer(accumulator, paintBuffer, color, alpha, blendFn, blendColorPixelDataAlphaMask);
|
|
5462
|
+
};
|
|
5463
|
+
}
|
|
5464
|
+
|
|
5465
|
+
// src/Internal/_constants.ts
|
|
5466
|
+
var DEFAULT_CANVAS_FACTORY = (w, h) => new OffscreenCanvas(w, h);
|
|
5467
|
+
|
|
5468
|
+
// src/Tile/MaskTile.ts
|
|
5469
|
+
var makeAlphaMaskTile = (id, tx, ty, tileSize, tileArea) => {
|
|
5470
|
+
return {
|
|
5471
|
+
tileType: 1 /* MASK */,
|
|
5472
|
+
type: 0 /* ALPHA */,
|
|
5473
|
+
data: new Uint8Array(tileArea),
|
|
5474
|
+
w: tileSize,
|
|
5475
|
+
h: tileSize,
|
|
5476
|
+
id,
|
|
5477
|
+
tx,
|
|
5478
|
+
ty
|
|
5479
|
+
};
|
|
5480
|
+
};
|
|
5481
|
+
var makeBinaryMaskTile = (id, tx, ty, tileSize, tileArea) => {
|
|
5482
|
+
return {
|
|
5483
|
+
tileType: 1 /* MASK */,
|
|
5484
|
+
type: 1 /* BINARY */,
|
|
5485
|
+
data: new Uint8Array(tileArea),
|
|
5486
|
+
w: tileSize,
|
|
5487
|
+
h: tileSize,
|
|
5488
|
+
id,
|
|
5489
|
+
tx,
|
|
5490
|
+
ty
|
|
5491
|
+
};
|
|
5492
|
+
};
|
|
5493
|
+
|
|
5494
|
+
// src/Paint/Render/AlphaMaskPaintBufferCanvasRenderer.ts
|
|
5495
|
+
function makeAlphaMaskPaintBufferCanvasRenderer(paintBuffer, canvasFactory = DEFAULT_CANVAS_FACTORY) {
|
|
5496
|
+
const config = paintBuffer.config;
|
|
5497
|
+
const tileSize = config.tileSize;
|
|
5498
|
+
const tileShift = config.tileShift;
|
|
5499
|
+
const tileArea = config.tileArea;
|
|
5500
|
+
const lookup = paintBuffer.lookup;
|
|
5501
|
+
const canvas = canvasFactory(tileSize, tileSize);
|
|
5502
|
+
const ctx = canvas.getContext("2d");
|
|
5503
|
+
if (!ctx) throw new Error(CANVAS_CTX_FAILED);
|
|
5504
|
+
ctx.imageSmoothingEnabled = false;
|
|
5505
|
+
const bridge = makePixelData(new ImageData(tileSize, tileSize));
|
|
5506
|
+
const view32 = bridge.data;
|
|
5507
|
+
return function drawPaintBuffer(targetCtx, color, alpha = 255, compOperation = "source-over") {
|
|
5508
|
+
if (alpha === 0) return;
|
|
5509
|
+
const baseSrcAlpha = color >>> 24;
|
|
5510
|
+
const colorRGB = color & 16777215;
|
|
5511
|
+
if (baseSrcAlpha === 0) return;
|
|
5512
|
+
targetCtx.globalAlpha = alpha / 255;
|
|
5513
|
+
targetCtx.globalCompositeOperation = compOperation;
|
|
5514
|
+
for (let i = 0; i < lookup.length; i++) {
|
|
5515
|
+
const tile = lookup[i];
|
|
5516
|
+
if (tile) {
|
|
5517
|
+
const data8 = tile.data;
|
|
5518
|
+
view32.fill(0);
|
|
5519
|
+
for (let p = 0; p < tileArea; p++) {
|
|
5520
|
+
const maskA = data8[p];
|
|
5521
|
+
if (maskA === 0) continue;
|
|
5522
|
+
if (maskA === 255) {
|
|
5523
|
+
view32[p] = color;
|
|
5524
|
+
} else {
|
|
5525
|
+
const t = baseSrcAlpha * maskA + 128;
|
|
5526
|
+
const finalA = t + (t >> 8) >> 8;
|
|
5527
|
+
view32[p] = (colorRGB | finalA << 24) >>> 0;
|
|
5528
|
+
}
|
|
5529
|
+
}
|
|
5530
|
+
const dx = tile.tx << tileShift;
|
|
5531
|
+
const dy = tile.ty << tileShift;
|
|
5532
|
+
ctx.putImageData(bridge.imageData, 0, 0);
|
|
5533
|
+
targetCtx.drawImage(canvas, dx, dy);
|
|
5534
|
+
}
|
|
5535
|
+
}
|
|
5536
|
+
targetCtx.globalAlpha = 1;
|
|
5537
|
+
targetCtx.globalCompositeOperation = "source-over";
|
|
5538
|
+
};
|
|
5539
|
+
}
|
|
5540
|
+
|
|
5541
|
+
// src/Paint/Commit/AlphaMaskPaintBufferManager.ts
|
|
5542
|
+
function makeAlphaMaskPaintBufferManager(writer, canvasFactory = DEFAULT_CANVAS_FACTORY) {
|
|
5543
|
+
const pool = new TilePool(writer.config, makeAlphaMaskTile);
|
|
5544
|
+
const buffer = new AlphaMaskPaintBuffer(writer.config, pool);
|
|
5545
|
+
const draw = makeAlphaMaskPaintBufferCanvasRenderer(buffer, canvasFactory);
|
|
5546
|
+
return {
|
|
5547
|
+
clear: buffer.clear.bind(buffer),
|
|
5548
|
+
paintRect: buffer.paintRect.bind(buffer),
|
|
5549
|
+
paintAlphaMask: buffer.paintAlphaMask.bind(buffer),
|
|
5550
|
+
paintBinaryMask: buffer.paintBinaryMask.bind(buffer),
|
|
5551
|
+
commit: makeAlphaMaskPaintBufferCommitter(writer.accumulator, buffer),
|
|
5552
|
+
draw
|
|
5553
|
+
};
|
|
5554
|
+
}
|
|
5555
|
+
|
|
5556
|
+
// src/Paint/Commit/BinaryMaskPaintBufferCommitter.ts
|
|
5557
|
+
function makeBinaryMaskPaintBufferCommitter(accumulator, paintBuffer) {
|
|
5558
|
+
return function commitBinaryMaskPaintBufferToAccumulator(color, alpha = 255, blendFn = sourceOverPerfect) {
|
|
5559
|
+
return commitMaskPaintBuffer(accumulator, paintBuffer, color, alpha, blendFn, blendColorPixelDataBinaryMask);
|
|
5560
|
+
};
|
|
5561
|
+
}
|
|
5562
|
+
|
|
5563
|
+
// src/Paint/Render/BinaryMaskPaintBufferCanvasRenderer.ts
|
|
5564
|
+
function makeBinaryMaskPaintBufferCanvasRenderer(paintBuffer, canvasFactory = DEFAULT_CANVAS_FACTORY) {
|
|
5565
|
+
const config = paintBuffer.config;
|
|
5566
|
+
const tileSize = config.tileSize;
|
|
5567
|
+
const tileShift = config.tileShift;
|
|
5568
|
+
const tileArea = config.tileArea;
|
|
5569
|
+
const lookup = paintBuffer.lookup;
|
|
5570
|
+
const canvas = canvasFactory(tileSize, tileSize);
|
|
5571
|
+
const ctx = canvas.getContext("2d");
|
|
5572
|
+
if (!ctx) throw new Error(CANVAS_CTX_FAILED);
|
|
5573
|
+
ctx.imageSmoothingEnabled = false;
|
|
5574
|
+
const bridge = makePixelData(new ImageData(tileSize, tileSize));
|
|
5575
|
+
const view32 = bridge.data;
|
|
5576
|
+
return function drawPaintBuffer(targetCtx, color, alpha = 255, compOperation = "source-over") {
|
|
5577
|
+
if (alpha === 0) return;
|
|
5578
|
+
const baseSrcAlpha = color >>> 24;
|
|
5579
|
+
if (baseSrcAlpha === 0) return;
|
|
5580
|
+
targetCtx.globalAlpha = alpha / 255;
|
|
5581
|
+
targetCtx.globalCompositeOperation = compOperation;
|
|
5582
|
+
for (let i = 0; i < lookup.length; i++) {
|
|
5583
|
+
const tile = lookup[i];
|
|
5584
|
+
if (tile) {
|
|
5585
|
+
const data8 = tile.data;
|
|
5586
|
+
view32.fill(0);
|
|
5587
|
+
for (let p = 0; p < tileArea; p++) {
|
|
5588
|
+
if (data8[p] === 1) {
|
|
5589
|
+
view32[p] = color;
|
|
5590
|
+
}
|
|
5591
|
+
}
|
|
5592
|
+
const dx = tile.tx << tileShift;
|
|
5593
|
+
const dy = tile.ty << tileShift;
|
|
5594
|
+
ctx.putImageData(bridge.imageData, 0, 0);
|
|
5595
|
+
targetCtx.drawImage(canvas, dx, dy);
|
|
5596
|
+
}
|
|
5597
|
+
}
|
|
5598
|
+
targetCtx.globalAlpha = 1;
|
|
5599
|
+
targetCtx.globalCompositeOperation = "source-over";
|
|
5600
|
+
};
|
|
5601
|
+
}
|
|
5602
|
+
|
|
5603
|
+
// src/Paint/Commit/BinaryMaskPaintBufferManager.ts
|
|
5604
|
+
function makeBinaryMaskPaintBufferManager(writer, canvasFactory = DEFAULT_CANVAS_FACTORY) {
|
|
5605
|
+
const pool = new TilePool(writer.config, makeBinaryMaskTile);
|
|
5606
|
+
const buffer = new BinaryMaskPaintBuffer(writer.config, pool);
|
|
5607
|
+
const draw = makeBinaryMaskPaintBufferCanvasRenderer(buffer, canvasFactory);
|
|
5608
|
+
return {
|
|
5609
|
+
clear: buffer.clear.bind(buffer),
|
|
5610
|
+
paintRect: buffer.paintRect.bind(buffer),
|
|
5611
|
+
paintBinaryMask: buffer.paintBinaryMask.bind(buffer),
|
|
5612
|
+
commit: makeBinaryMaskPaintBufferCommitter(writer.accumulator, buffer),
|
|
5613
|
+
draw
|
|
4776
5614
|
};
|
|
4777
5615
|
}
|
|
4778
5616
|
|
|
4779
|
-
// src/
|
|
4780
|
-
var
|
|
4781
|
-
|
|
4782
|
-
|
|
4783
|
-
|
|
4784
|
-
|
|
4785
|
-
|
|
4786
|
-
|
|
4787
|
-
|
|
4788
|
-
|
|
4789
|
-
|
|
4790
|
-
|
|
4791
|
-
|
|
4792
|
-
|
|
4793
|
-
|
|
4794
|
-
|
|
4795
|
-
|
|
4796
|
-
|
|
4797
|
-
|
|
4798
|
-
|
|
4799
|
-
|
|
4800
|
-
|
|
4801
|
-
|
|
4802
|
-
|
|
4803
|
-
|
|
4804
|
-
|
|
4805
|
-
|
|
4806
|
-
}
|
|
4807
|
-
|
|
4808
|
-
|
|
4809
|
-
|
|
4810
|
-
|
|
4811
|
-
|
|
4812
|
-
|
|
4813
|
-
|
|
4814
|
-
|
|
4815
|
-
|
|
4816
|
-
|
|
4817
|
-
|
|
5617
|
+
// src/Paint/Commit/commitColorPaintBuffer.ts
|
|
5618
|
+
var SCRATCH_OPTS2 = {
|
|
5619
|
+
alpha: 255,
|
|
5620
|
+
blendFn: sourceOverPerfect,
|
|
5621
|
+
x: 0,
|
|
5622
|
+
y: 0,
|
|
5623
|
+
w: 0,
|
|
5624
|
+
h: 0
|
|
5625
|
+
};
|
|
5626
|
+
function commitColorPaintBuffer(accumulator, paintBuffer, alpha = 255, blendFn = sourceOverPerfect, blendPixelDataFn = blendPixelData) {
|
|
5627
|
+
const config = accumulator.config;
|
|
5628
|
+
const tileShift = config.tileShift;
|
|
5629
|
+
const lookup = paintBuffer.lookup;
|
|
5630
|
+
SCRATCH_OPTS2.alpha = alpha;
|
|
5631
|
+
SCRATCH_OPTS2.blendFn = blendFn;
|
|
5632
|
+
for (let i = 0; i < lookup.length; i++) {
|
|
5633
|
+
const tile = lookup[i];
|
|
5634
|
+
if (tile) {
|
|
5635
|
+
const didChange = accumulator.storeTileBeforeState(tile.id, tile.tx, tile.ty);
|
|
5636
|
+
const dx = tile.tx << tileShift;
|
|
5637
|
+
const dy = tile.ty << tileShift;
|
|
5638
|
+
SCRATCH_OPTS2.x = dx;
|
|
5639
|
+
SCRATCH_OPTS2.y = dy;
|
|
5640
|
+
SCRATCH_OPTS2.w = tile.w;
|
|
5641
|
+
SCRATCH_OPTS2.h = tile.h;
|
|
5642
|
+
didChange(blendPixelDataFn(config.target, tile, SCRATCH_OPTS2));
|
|
5643
|
+
}
|
|
5644
|
+
}
|
|
5645
|
+
paintBuffer.clear();
|
|
5646
|
+
}
|
|
5647
|
+
|
|
5648
|
+
// src/Paint/Commit/ColorPaintBufferCommitter.ts
|
|
5649
|
+
function makeColorPaintBufferCommitter(accumulator, paintBuffer) {
|
|
5650
|
+
return function commitColorPaintBufferToAccumulator(alpha = 255, blendFn = sourceOverPerfect) {
|
|
5651
|
+
return commitColorPaintBuffer(accumulator, paintBuffer, alpha, blendFn, blendPixelData);
|
|
5652
|
+
};
|
|
5653
|
+
}
|
|
5654
|
+
|
|
5655
|
+
// src/Paint/Render/ColorPaintBufferCanvasRenderer.ts
|
|
5656
|
+
function makeColorPaintBufferCanvasRenderer(paintBuffer, canvasFactory = DEFAULT_CANVAS_FACTORY) {
|
|
5657
|
+
const config = paintBuffer.config;
|
|
5658
|
+
const tileSize = config.tileSize;
|
|
5659
|
+
const tileShift = config.tileShift;
|
|
5660
|
+
const lookup = paintBuffer.lookup;
|
|
5661
|
+
const canvas = canvasFactory(tileSize, tileSize);
|
|
5662
|
+
const ctx = canvas.getContext("2d");
|
|
5663
|
+
if (!ctx) throw new Error(CANVAS_CTX_FAILED);
|
|
5664
|
+
ctx.imageSmoothingEnabled = false;
|
|
5665
|
+
return function drawPaintBuffer(targetCtx, alpha = 255, compOperation = "source-over") {
|
|
5666
|
+
targetCtx.globalAlpha = alpha / 255;
|
|
5667
|
+
targetCtx.globalCompositeOperation = compOperation;
|
|
5668
|
+
for (let i = 0; i < lookup.length; i++) {
|
|
5669
|
+
const tile = lookup[i];
|
|
5670
|
+
if (tile) {
|
|
5671
|
+
const dx = tile.tx << tileShift;
|
|
5672
|
+
const dy = tile.ty << tileShift;
|
|
5673
|
+
ctx.putImageData(tile.imageData, 0, 0);
|
|
5674
|
+
targetCtx.drawImage(canvas, dx, dy);
|
|
5675
|
+
}
|
|
5676
|
+
}
|
|
5677
|
+
targetCtx.globalAlpha = 1;
|
|
5678
|
+
targetCtx.globalCompositeOperation = "source-over";
|
|
5679
|
+
};
|
|
5680
|
+
}
|
|
5681
|
+
|
|
5682
|
+
// src/Paint/Commit/ColorPaintBufferManager.ts
|
|
5683
|
+
function makeColorPaintBufferManager(writer, canvasFactory = DEFAULT_CANVAS_FACTORY) {
|
|
5684
|
+
const pool = new TilePool(writer.config, makePixelTile);
|
|
5685
|
+
const buffer = new ColorPaintBuffer(writer.config, pool);
|
|
5686
|
+
const draw = makeColorPaintBufferCanvasRenderer(buffer, canvasFactory);
|
|
5687
|
+
return {
|
|
5688
|
+
clear: buffer.clear.bind(buffer),
|
|
5689
|
+
paintRect: buffer.paintRect.bind(buffer),
|
|
5690
|
+
paintAlphaMask: buffer.paintAlphaMask.bind(buffer),
|
|
5691
|
+
paintBinaryMask: buffer.paintBinaryMask.bind(buffer),
|
|
5692
|
+
commit: makeColorPaintBufferCommitter(writer.accumulator, buffer),
|
|
5693
|
+
draw
|
|
5694
|
+
};
|
|
5695
|
+
}
|
|
5696
|
+
|
|
5697
|
+
// src/Paint/makeCirclePaintMask.ts
|
|
5698
|
+
function makeCirclePaintAlphaMask(size, fallOff = (d) => d) {
|
|
5699
|
+
const area = size * size;
|
|
5700
|
+
const data = new Uint8Array(area);
|
|
5701
|
+
const radius = size / 2;
|
|
5702
|
+
const invR = 1 / radius;
|
|
5703
|
+
const centerOffset = -Math.ceil(radius - 0.5);
|
|
5704
|
+
for (let y = 0; y < size; y++) {
|
|
5705
|
+
const rowOffset = y * size;
|
|
5706
|
+
const dy = y - radius + 0.5;
|
|
5707
|
+
const dy2 = dy * dy;
|
|
5708
|
+
for (let x = 0; x < size; x++) {
|
|
5709
|
+
const dx = x - radius + 0.5;
|
|
5710
|
+
const distSqr = dx * dx + dy2;
|
|
5711
|
+
if (distSqr <= radius * radius) {
|
|
5712
|
+
const dist = Math.sqrt(distSqr) * invR;
|
|
5713
|
+
const strength = fallOff(1 - dist);
|
|
5714
|
+
if (strength > 0) {
|
|
5715
|
+
const intensity = strength * 255 | 0;
|
|
5716
|
+
data[rowOffset + x] = Math.max(0, Math.min(255, intensity));
|
|
5717
|
+
}
|
|
5718
|
+
}
|
|
5719
|
+
}
|
|
5720
|
+
}
|
|
5721
|
+
return {
|
|
5722
|
+
type: 0 /* ALPHA */,
|
|
5723
|
+
outlineType: 1 /* CIRCLE */,
|
|
5724
|
+
data,
|
|
5725
|
+
w: size,
|
|
5726
|
+
h: size,
|
|
5727
|
+
centerOffsetX: centerOffset,
|
|
5728
|
+
centerOffsetY: centerOffset
|
|
5729
|
+
};
|
|
5730
|
+
}
|
|
5731
|
+
function makeCirclePaintBinaryMask(size) {
|
|
5732
|
+
const area = size * size;
|
|
5733
|
+
const data = new Uint8Array(area);
|
|
5734
|
+
const radius = size / 2;
|
|
5735
|
+
const r2 = radius * radius;
|
|
5736
|
+
for (let y = 0; y < size; y++) {
|
|
5737
|
+
for (let x = 0; x < size; x++) {
|
|
5738
|
+
const dx = x - radius + 0.5;
|
|
5739
|
+
const dy = y - radius + 0.5;
|
|
5740
|
+
const distSqr = dx * dx + dy * dy;
|
|
5741
|
+
if (distSqr <= r2) {
|
|
5742
|
+
data[y * size + x] = 1;
|
|
5743
|
+
}
|
|
5744
|
+
}
|
|
5745
|
+
}
|
|
5746
|
+
const centerOffset = -Math.ceil(radius - 0.5);
|
|
5747
|
+
return {
|
|
5748
|
+
type: 1 /* BINARY */,
|
|
5749
|
+
outlineType: 1 /* CIRCLE */,
|
|
5750
|
+
w: size,
|
|
5751
|
+
h: size,
|
|
5752
|
+
data,
|
|
5753
|
+
centerOffsetX: centerOffset,
|
|
5754
|
+
centerOffsetY: centerOffset
|
|
5755
|
+
};
|
|
5756
|
+
}
|
|
5757
|
+
|
|
5758
|
+
// src/Paint/makePaintMask.ts
|
|
5759
|
+
function makePaintBinaryMask(mask) {
|
|
5760
|
+
return {
|
|
5761
|
+
type: 1 /* BINARY */,
|
|
5762
|
+
outlineType: 0 /* MASKED */,
|
|
5763
|
+
data: mask.data,
|
|
5764
|
+
w: mask.w,
|
|
5765
|
+
h: mask.h,
|
|
5766
|
+
centerOffsetX: -(mask.w >> 1),
|
|
5767
|
+
centerOffsetY: -(mask.h >> 1)
|
|
5768
|
+
};
|
|
5769
|
+
}
|
|
5770
|
+
function makePaintAlphaMask(mask) {
|
|
5771
|
+
return {
|
|
5772
|
+
type: 0 /* ALPHA */,
|
|
5773
|
+
outlineType: 0 /* MASKED */,
|
|
5774
|
+
data: mask.data,
|
|
5775
|
+
w: mask.w,
|
|
5776
|
+
h: mask.h,
|
|
5777
|
+
centerOffsetX: -(mask.w >> 1),
|
|
5778
|
+
centerOffsetY: -(mask.h >> 1)
|
|
5779
|
+
};
|
|
5780
|
+
}
|
|
5781
|
+
|
|
5782
|
+
// src/Paint/makeRectFalloffPaintAlphaMask.ts
|
|
5783
|
+
function makeRectFalloffPaintAlphaMask(width, height, fallOff = (d) => d) {
|
|
5784
|
+
const fPx = Math.floor(width / 2);
|
|
5785
|
+
const fPy = Math.floor(height / 2);
|
|
5786
|
+
const invHalfW = 2 / width;
|
|
5787
|
+
const invHalfH = 2 / height;
|
|
5788
|
+
const offX = width % 2 === 0 ? 0.5 : 0;
|
|
5789
|
+
const offY = height % 2 === 0 ? 0.5 : 0;
|
|
5790
|
+
const area = width * height;
|
|
5791
|
+
const data = new Uint8Array(area);
|
|
5792
|
+
for (let y = 0; y < height; y++) {
|
|
5793
|
+
const dy = Math.abs(y - fPy + offY) * invHalfH;
|
|
5794
|
+
const rowOffset = y * width;
|
|
5795
|
+
for (let x = 0; x < width; x++) {
|
|
5796
|
+
const dx = Math.abs(x - fPx + offX) * invHalfW;
|
|
5797
|
+
const dist = dx > dy ? dx : dy;
|
|
5798
|
+
const strength = fallOff(1 - dist);
|
|
5799
|
+
if (strength > 0) {
|
|
5800
|
+
const intensity = strength * 255 | 0;
|
|
5801
|
+
data[rowOffset + x] = Math.max(0, Math.min(255, intensity));
|
|
5802
|
+
}
|
|
5803
|
+
}
|
|
5804
|
+
}
|
|
5805
|
+
return {
|
|
5806
|
+
type: 0 /* ALPHA */,
|
|
5807
|
+
outlineType: 2 /* RECT */,
|
|
5808
|
+
data,
|
|
5809
|
+
w: width,
|
|
5810
|
+
h: height,
|
|
5811
|
+
centerOffsetX: -(width >> 1),
|
|
5812
|
+
centerOffsetY: -(height >> 1)
|
|
5813
|
+
};
|
|
5814
|
+
}
|
|
5815
|
+
|
|
5816
|
+
// src/PixelData/ReusablePixelData.ts
|
|
5817
|
+
function makeReusablePixelData() {
|
|
5818
|
+
const pixelData = {
|
|
5819
|
+
w: 0,
|
|
5820
|
+
h: 0,
|
|
5821
|
+
data: null,
|
|
5822
|
+
imageData: null
|
|
5823
|
+
};
|
|
5824
|
+
return function getReusablePixelData(width, height) {
|
|
5825
|
+
if (pixelData.w !== width || pixelData.h !== height) {
|
|
5826
|
+
setPixelData(pixelData, new ImageData(width, height));
|
|
5827
|
+
} else {
|
|
5828
|
+
pixelData.data.fill(0);
|
|
5829
|
+
}
|
|
5830
|
+
return pixelData;
|
|
5831
|
+
};
|
|
5832
|
+
}
|
|
5833
|
+
|
|
5834
|
+
// src/Paint/Render/PaintCursorRenderer.ts
|
|
5835
|
+
function makePaintCursorRenderer(reusableCanvasFactory) {
|
|
5836
|
+
const factory = reusableCanvasFactory ?? makeReusableOffscreenCanvas;
|
|
5837
|
+
const updateBuffer = factory();
|
|
5838
|
+
const {
|
|
5839
|
+
canvas,
|
|
5840
|
+
ctx
|
|
5841
|
+
} = updateBuffer(1, 1);
|
|
5842
|
+
const getPixelData = makeReusablePixelData();
|
|
5843
|
+
let _color = packColor(0, 255, 255, 255);
|
|
5844
|
+
let _scale = 1;
|
|
5845
|
+
let currentMask = {
|
|
5846
|
+
type: 1 /* BINARY */,
|
|
5847
|
+
outlineType: 2 /* RECT */,
|
|
5848
|
+
w: 1,
|
|
5849
|
+
h: 1,
|
|
5850
|
+
centerOffsetX: -(10 - 1 >> 1),
|
|
5851
|
+
centerOffsetY: -(10 - 1 >> 1)
|
|
5852
|
+
};
|
|
5853
|
+
let outline;
|
|
5854
|
+
function update(paintMask, scale, color, alphaThreshold = 127) {
|
|
5855
|
+
currentMask = paintMask ?? currentMask;
|
|
5856
|
+
_scale = scale ?? _scale;
|
|
5857
|
+
_color = color ?? _color;
|
|
5858
|
+
updateBuffer(currentMask.w * _scale + 2 * _scale, currentMask.h * _scale + 2 * _scale);
|
|
5859
|
+
if (currentMask.type === 1 /* BINARY */) {
|
|
5860
|
+
if (currentMask.outlineType === 1 /* CIRCLE */) {
|
|
5861
|
+
outline = makeCircleBinaryMaskOutline(currentMask.w, _scale);
|
|
5862
|
+
} else if (currentMask.outlineType === 2 /* RECT */) {
|
|
5863
|
+
outline = makeRectBinaryMaskOutline(currentMask.w, currentMask.h, _scale);
|
|
5864
|
+
} else if (currentMask.outlineType === 0 /* MASKED */) {
|
|
5865
|
+
outline = makeBinaryMaskOutline(currentMask, _scale);
|
|
5866
|
+
}
|
|
5867
|
+
} else if (currentMask.type === 0 /* ALPHA */) {
|
|
5868
|
+
const mask = makeBinaryMaskFromAlphaMask(currentMask, alphaThreshold);
|
|
5869
|
+
outline = makeBinaryMaskOutline(mask, _scale);
|
|
5870
|
+
}
|
|
5871
|
+
const pixelData = getPixelData(outline.w, outline.h);
|
|
5872
|
+
fillPixelDataBinaryMask(pixelData, _color, outline);
|
|
5873
|
+
ctx.putImageData(pixelData.imageData, 0, 0);
|
|
5874
|
+
}
|
|
5875
|
+
const boundsScratch = {
|
|
5876
|
+
x: 0,
|
|
5877
|
+
y: 0,
|
|
5878
|
+
w: 0,
|
|
5879
|
+
h: 0
|
|
5880
|
+
};
|
|
5881
|
+
function getBounds(centerX, centerY) {
|
|
5882
|
+
boundsScratch.x = centerX + currentMask.centerOffsetX;
|
|
5883
|
+
boundsScratch.y = centerY + currentMask.centerOffsetY;
|
|
5884
|
+
boundsScratch.w = currentMask.w;
|
|
5885
|
+
boundsScratch.h = currentMask.h;
|
|
5886
|
+
return boundsScratch;
|
|
5887
|
+
}
|
|
5888
|
+
const boundsScaledScratch = {
|
|
5889
|
+
x: 0,
|
|
5890
|
+
y: 0,
|
|
5891
|
+
w: 0,
|
|
5892
|
+
h: 0
|
|
5893
|
+
};
|
|
5894
|
+
function getOutlineBoundsScaled(centerX, centerY) {
|
|
5895
|
+
boundsScaledScratch.x = centerX * _scale + currentMask.centerOffsetX * _scale - 1;
|
|
5896
|
+
boundsScaledScratch.y = centerY * _scale + currentMask.centerOffsetY * _scale - 1;
|
|
5897
|
+
boundsScaledScratch.w = currentMask.w * _scale;
|
|
5898
|
+
boundsScaledScratch.h = currentMask.h * _scale;
|
|
5899
|
+
return boundsScaledScratch;
|
|
5900
|
+
}
|
|
5901
|
+
function draw(drawCtx, centerX, centerY) {
|
|
5902
|
+
const dx = centerX * _scale + currentMask.centerOffsetX * _scale - 1;
|
|
5903
|
+
const dy = centerY * _scale + currentMask.centerOffsetY * _scale - 1;
|
|
5904
|
+
drawCtx.drawImage(canvas, Math.floor(dx), Math.floor(dy));
|
|
5905
|
+
}
|
|
5906
|
+
function getSettings() {
|
|
5907
|
+
return {
|
|
5908
|
+
color: _color,
|
|
5909
|
+
scale: _scale,
|
|
5910
|
+
currentMask
|
|
5911
|
+
};
|
|
5912
|
+
}
|
|
5913
|
+
return {
|
|
5914
|
+
update,
|
|
5915
|
+
getBounds,
|
|
5916
|
+
getBoundsScaled: getOutlineBoundsScaled,
|
|
5917
|
+
draw,
|
|
5918
|
+
getSettings
|
|
5919
|
+
};
|
|
5920
|
+
}
|
|
5921
|
+
|
|
5922
|
+
// src/PixelData/applyMaskToPixelData.ts
|
|
5923
|
+
function applyMaskToPixelData(dst, mask, opts) {
|
|
5924
|
+
if (mask.type === 1 /* BINARY */) {
|
|
5925
|
+
return applyBinaryMaskToPixelData(dst, mask, opts);
|
|
5926
|
+
} else {
|
|
5927
|
+
return applyAlphaMaskToPixelData(dst, mask, opts);
|
|
5928
|
+
}
|
|
5929
|
+
}
|
|
5930
|
+
|
|
5931
|
+
// src/PixelData/blendColorPixelDataMask.ts
|
|
5932
|
+
function blendColorPixelDataMask(dst, color, mask, opts) {
|
|
5933
|
+
if (mask.type === 1 /* BINARY */) {
|
|
5934
|
+
return blendColorPixelDataBinaryMask(dst, color, mask, opts);
|
|
5935
|
+
} else {
|
|
5936
|
+
return blendColorPixelDataAlphaMask(dst, color, mask, opts);
|
|
5937
|
+
}
|
|
5938
|
+
}
|
|
5939
|
+
|
|
4818
5940
|
// src/PixelData/blendColorPixelDataPaintAlphaMask.ts
|
|
4819
|
-
var
|
|
5941
|
+
var SCRATCH_OPTS3 = {
|
|
4820
5942
|
x: 0,
|
|
4821
5943
|
y: 0,
|
|
4822
5944
|
alpha: 255,
|
|
@@ -4825,15 +5947,15 @@ var SCRATCH_OPTS = {
|
|
|
4825
5947
|
function blendColorPixelDataPaintAlphaMask(dst, color, mask, x, y, alpha = 255, blendFn = sourceOverPerfect) {
|
|
4826
5948
|
const tx = x + mask.centerOffsetX;
|
|
4827
5949
|
const ty = y + mask.centerOffsetY;
|
|
4828
|
-
|
|
4829
|
-
|
|
4830
|
-
|
|
4831
|
-
|
|
4832
|
-
return blendColorPixelDataAlphaMask(dst, color, mask,
|
|
5950
|
+
SCRATCH_OPTS3.x = tx;
|
|
5951
|
+
SCRATCH_OPTS3.y = ty;
|
|
5952
|
+
SCRATCH_OPTS3.alpha = alpha;
|
|
5953
|
+
SCRATCH_OPTS3.blendFn = blendFn;
|
|
5954
|
+
return blendColorPixelDataAlphaMask(dst, color, mask, SCRATCH_OPTS3);
|
|
4833
5955
|
}
|
|
4834
5956
|
|
|
4835
5957
|
// src/PixelData/blendColorPixelDataPaintBinaryMask.ts
|
|
4836
|
-
var
|
|
5958
|
+
var SCRATCH_OPTS4 = {
|
|
4837
5959
|
x: 0,
|
|
4838
5960
|
y: 0,
|
|
4839
5961
|
alpha: 255,
|
|
@@ -4842,15 +5964,15 @@ var SCRATCH_OPTS2 = {
|
|
|
4842
5964
|
function blendColorPixelDataPaintBinaryMask(dst, color, mask, x, y, alpha = 255, blendFn = sourceOverPerfect) {
|
|
4843
5965
|
const tx = x + mask.centerOffsetX;
|
|
4844
5966
|
const ty = y + mask.centerOffsetY;
|
|
4845
|
-
|
|
4846
|
-
|
|
4847
|
-
|
|
4848
|
-
|
|
4849
|
-
return blendColorPixelDataBinaryMask(dst, color, mask,
|
|
5967
|
+
SCRATCH_OPTS4.x = tx;
|
|
5968
|
+
SCRATCH_OPTS4.y = ty;
|
|
5969
|
+
SCRATCH_OPTS4.alpha = alpha;
|
|
5970
|
+
SCRATCH_OPTS4.blendFn = blendFn;
|
|
5971
|
+
return blendColorPixelDataBinaryMask(dst, color, mask, SCRATCH_OPTS4);
|
|
4850
5972
|
}
|
|
4851
5973
|
|
|
4852
5974
|
// src/PixelData/blendColorPixelDataPaintMask.ts
|
|
4853
|
-
var
|
|
5975
|
+
var SCRATCH_OPTS5 = {
|
|
4854
5976
|
x: 0,
|
|
4855
5977
|
y: 0,
|
|
4856
5978
|
alpha: 255,
|
|
@@ -4859,14 +5981,14 @@ var SCRATCH_OPTS3 = {
|
|
|
4859
5981
|
function blendColorPixelDataPaintMask(dst, color, mask, x, y, alpha = 255, blendFn = sourceOverPerfect) {
|
|
4860
5982
|
const tx = x + mask.centerOffsetX;
|
|
4861
5983
|
const ty = y + mask.centerOffsetY;
|
|
4862
|
-
|
|
4863
|
-
|
|
4864
|
-
|
|
4865
|
-
|
|
5984
|
+
SCRATCH_OPTS5.x = tx;
|
|
5985
|
+
SCRATCH_OPTS5.y = ty;
|
|
5986
|
+
SCRATCH_OPTS5.alpha = alpha;
|
|
5987
|
+
SCRATCH_OPTS5.blendFn = blendFn;
|
|
4866
5988
|
if (mask.type === 1 /* BINARY */) {
|
|
4867
|
-
return blendColorPixelDataBinaryMask(dst, color, mask,
|
|
5989
|
+
return blendColorPixelDataBinaryMask(dst, color, mask, SCRATCH_OPTS5);
|
|
4868
5990
|
} else {
|
|
4869
|
-
return blendColorPixelDataAlphaMask(dst, color, mask,
|
|
5991
|
+
return blendColorPixelDataAlphaMask(dst, color, mask, SCRATCH_OPTS5);
|
|
4870
5992
|
}
|
|
4871
5993
|
}
|
|
4872
5994
|
|
|
@@ -4880,7 +6002,7 @@ function blendPixelDataMask(target, src, mask, opts) {
|
|
|
4880
6002
|
}
|
|
4881
6003
|
|
|
4882
6004
|
// src/PixelData/blendPixelDataPaintBuffer.ts
|
|
4883
|
-
var
|
|
6005
|
+
var SCRATCH_OPTS6 = {
|
|
4884
6006
|
x: 0,
|
|
4885
6007
|
y: 0,
|
|
4886
6008
|
alpha: 255,
|
|
@@ -4894,11 +6016,11 @@ function blendPixelDataPaintBuffer(target, paintBuffer, alpha = 255, blendFn, bl
|
|
|
4894
6016
|
if (tile) {
|
|
4895
6017
|
const x = tile.tx << tileShift;
|
|
4896
6018
|
const y = tile.ty << tileShift;
|
|
4897
|
-
|
|
4898
|
-
|
|
4899
|
-
|
|
4900
|
-
|
|
4901
|
-
blendPixelDataFn(target, tile,
|
|
6019
|
+
SCRATCH_OPTS6.x = x;
|
|
6020
|
+
SCRATCH_OPTS6.y = y;
|
|
6021
|
+
SCRATCH_OPTS6.alpha = alpha;
|
|
6022
|
+
SCRATCH_OPTS6.blendFn = blendFn;
|
|
6023
|
+
blendPixelDataFn(target, tile, SCRATCH_OPTS6);
|
|
4902
6024
|
}
|
|
4903
6025
|
}
|
|
4904
6026
|
}
|
|
@@ -4913,8 +6035,8 @@ function fillPixelDataFast(dst, color, _x, _y, _w, _h) {
|
|
|
4913
6035
|
if (typeof _x === "object") {
|
|
4914
6036
|
x = _x.x ?? 0;
|
|
4915
6037
|
y = _x.y ?? 0;
|
|
4916
|
-
w = _x.w ?? dst.
|
|
4917
|
-
h = _x.h ?? dst.
|
|
6038
|
+
w = _x.w ?? dst.w;
|
|
6039
|
+
h = _x.h ?? dst.h;
|
|
4918
6040
|
} else if (typeof _x === "number") {
|
|
4919
6041
|
x = _x;
|
|
4920
6042
|
y = _y;
|
|
@@ -4923,10 +6045,10 @@ function fillPixelDataFast(dst, color, _x, _y, _w, _h) {
|
|
|
4923
6045
|
} else {
|
|
4924
6046
|
x = 0;
|
|
4925
6047
|
y = 0;
|
|
4926
|
-
w = dst.
|
|
4927
|
-
h = dst.
|
|
6048
|
+
w = dst.w;
|
|
6049
|
+
h = dst.h;
|
|
4928
6050
|
}
|
|
4929
|
-
const clip = resolveRectClipping(x, y, w, h, dst.
|
|
6051
|
+
const clip = resolveRectClipping(x, y, w, h, dst.w, dst.h, SCRATCH_RECT4);
|
|
4930
6052
|
if (!clip.inBounds) return;
|
|
4931
6053
|
const {
|
|
4932
6054
|
x: finalX,
|
|
@@ -4934,9 +6056,9 @@ function fillPixelDataFast(dst, color, _x, _y, _w, _h) {
|
|
|
4934
6056
|
w: actualW,
|
|
4935
6057
|
h: actualH
|
|
4936
6058
|
} = clip;
|
|
4937
|
-
const dst32 = dst.
|
|
4938
|
-
const dw = dst.
|
|
4939
|
-
if (actualW === dw && actualH === dst.
|
|
6059
|
+
const dst32 = dst.data;
|
|
6060
|
+
const dw = dst.w;
|
|
6061
|
+
if (actualW === dw && actualH === dst.h && finalX === 0 && finalY === 0) {
|
|
4940
6062
|
dst32.fill(color);
|
|
4941
6063
|
return;
|
|
4942
6064
|
}
|
|
@@ -4952,6 +6074,13 @@ function clearPixelDataFast(dst, rect) {
|
|
|
4952
6074
|
fillPixelDataFast(dst, 0, rect);
|
|
4953
6075
|
}
|
|
4954
6076
|
|
|
6077
|
+
// src/PixelData/copyPixelData.ts
|
|
6078
|
+
function copyPixelData(target) {
|
|
6079
|
+
const data = target.imageData.data;
|
|
6080
|
+
const buffer = new Uint8ClampedArray(data);
|
|
6081
|
+
return makePixelData(new ImageData(buffer, target.w, target.h));
|
|
6082
|
+
}
|
|
6083
|
+
|
|
4955
6084
|
// src/PixelData/extractPixelDataBuffer.ts
|
|
4956
6085
|
var SCRATCH_BLIT4 = makeClippedBlit();
|
|
4957
6086
|
function extractPixelDataBuffer(source, _x, _y, _w, _h) {
|
|
@@ -4966,9 +6095,9 @@ function extractPixelDataBuffer(source, _x, _y, _w, _h) {
|
|
|
4966
6095
|
w: _w,
|
|
4967
6096
|
h: _h
|
|
4968
6097
|
};
|
|
4969
|
-
const srcW = source.
|
|
4970
|
-
const srcH = source.
|
|
4971
|
-
const srcData = source.
|
|
6098
|
+
const srcW = source.w;
|
|
6099
|
+
const srcH = source.h;
|
|
6100
|
+
const srcData = source.data;
|
|
4972
6101
|
if (w <= 0 || h <= 0) {
|
|
4973
6102
|
return new Uint32Array(0);
|
|
4974
6103
|
}
|
|
@@ -5005,24 +6134,24 @@ function extractPixelData(source, _x, _y, _w, _h) {
|
|
|
5005
6134
|
w: _w,
|
|
5006
6135
|
h: _h
|
|
5007
6136
|
};
|
|
5008
|
-
const result =
|
|
6137
|
+
const result = makePixelData(new ImageData(w, h));
|
|
5009
6138
|
const buffer = extractPixelDataBuffer(source, x, y, w, h);
|
|
5010
|
-
result.
|
|
6139
|
+
result.data.set(buffer);
|
|
5011
6140
|
return result;
|
|
5012
6141
|
}
|
|
5013
6142
|
|
|
5014
6143
|
// src/PixelData/pixelDataToAlphaMask.ts
|
|
5015
6144
|
function pixelDataToAlphaMask(pixelData) {
|
|
5016
6145
|
const {
|
|
5017
|
-
|
|
5018
|
-
|
|
5019
|
-
|
|
6146
|
+
data,
|
|
6147
|
+
w,
|
|
6148
|
+
h
|
|
5020
6149
|
} = pixelData;
|
|
5021
|
-
const len =
|
|
5022
|
-
const mask = makeAlphaMask(
|
|
6150
|
+
const len = data.length;
|
|
6151
|
+
const mask = makeAlphaMask(w, h);
|
|
5023
6152
|
const maskData = mask.data;
|
|
5024
6153
|
for (let i = 0; i < len; i++) {
|
|
5025
|
-
const val =
|
|
6154
|
+
const val = data[i];
|
|
5026
6155
|
maskData[i] = val >>> 24 & 255;
|
|
5027
6156
|
}
|
|
5028
6157
|
return mask;
|
|
@@ -5030,9 +6159,9 @@ function pixelDataToAlphaMask(pixelData) {
|
|
|
5030
6159
|
|
|
5031
6160
|
// src/PixelData/reflectPixelData.ts
|
|
5032
6161
|
function reflectPixelDataHorizontal(pixelData) {
|
|
5033
|
-
const width = pixelData.
|
|
5034
|
-
const height = pixelData.
|
|
5035
|
-
const data = pixelData.
|
|
6162
|
+
const width = pixelData.w;
|
|
6163
|
+
const height = pixelData.h;
|
|
6164
|
+
const data = pixelData.data;
|
|
5036
6165
|
const halfWidth = Math.floor(width / 2);
|
|
5037
6166
|
for (let y = 0; y < height; y++) {
|
|
5038
6167
|
const rowOffset = y * width;
|
|
@@ -5046,9 +6175,9 @@ function reflectPixelDataHorizontal(pixelData) {
|
|
|
5046
6175
|
}
|
|
5047
6176
|
}
|
|
5048
6177
|
function reflectPixelDataVertical(pixelData) {
|
|
5049
|
-
const width = pixelData.
|
|
5050
|
-
const height = pixelData.
|
|
5051
|
-
const data = pixelData.
|
|
6178
|
+
const width = pixelData.w;
|
|
6179
|
+
const height = pixelData.h;
|
|
6180
|
+
const data = pixelData.data;
|
|
5052
6181
|
const halfHeight = Math.floor(height / 2);
|
|
5053
6182
|
for (let y = 0; y < halfHeight; y++) {
|
|
5054
6183
|
const topRowOffset = y * width;
|
|
@@ -5065,19 +6194,21 @@ function reflectPixelDataVertical(pixelData) {
|
|
|
5065
6194
|
|
|
5066
6195
|
// src/PixelData/resamplePixelData.ts
|
|
5067
6196
|
function resamplePixelData(pixelData, factor) {
|
|
5068
|
-
const {
|
|
5069
|
-
|
|
5070
|
-
|
|
5071
|
-
|
|
5072
|
-
|
|
5073
|
-
|
|
6197
|
+
const output = {};
|
|
6198
|
+
const resampled = resampleUint32Array(pixelData.data, pixelData.w, pixelData.h, factor, output);
|
|
6199
|
+
resampled.imageData = uInt32ArrayToImageData(resampled.data, resampled.w, resampled.h);
|
|
6200
|
+
return resampled;
|
|
6201
|
+
}
|
|
6202
|
+
function resamplePixelDataInPlace(pixelData, factor) {
|
|
6203
|
+
const resampled = resampleUint32Array(pixelData.data, pixelData.w, pixelData.h, factor, pixelData);
|
|
6204
|
+
resampled.imageData = uInt32ArrayToImageData(resampled.data, resampled.w, resampled.h);
|
|
5074
6205
|
}
|
|
5075
6206
|
|
|
5076
6207
|
// src/PixelData/rotatePixelData.ts
|
|
5077
6208
|
function rotatePixelData(pixelData) {
|
|
5078
|
-
const width = pixelData.
|
|
5079
|
-
const height = pixelData.
|
|
5080
|
-
const data = pixelData.
|
|
6209
|
+
const width = pixelData.w;
|
|
6210
|
+
const height = pixelData.h;
|
|
6211
|
+
const data = pixelData.data;
|
|
5081
6212
|
if (width === height) {
|
|
5082
6213
|
rotateSquareInPlace(pixelData);
|
|
5083
6214
|
return;
|
|
@@ -5095,11 +6226,11 @@ function rotatePixelData(pixelData) {
|
|
|
5095
6226
|
}
|
|
5096
6227
|
}
|
|
5097
6228
|
const newImageData = new ImageData(new Uint8ClampedArray(newData32.buffer), newWidth, newHeight);
|
|
5098
|
-
pixelData
|
|
6229
|
+
setPixelData(pixelData, newImageData);
|
|
5099
6230
|
}
|
|
5100
6231
|
function rotateSquareInPlace(pixelData) {
|
|
5101
|
-
const n = pixelData.
|
|
5102
|
-
const data = pixelData.
|
|
6232
|
+
const n = pixelData.w;
|
|
6233
|
+
const data = pixelData.data;
|
|
5103
6234
|
for (let i = 0; i < n / 2; i++) {
|
|
5104
6235
|
for (let j = i; j < n - i - 1; j++) {
|
|
5105
6236
|
const top = i * n + j;
|
|
@@ -5115,6 +6246,16 @@ function rotateSquareInPlace(pixelData) {
|
|
|
5115
6246
|
}
|
|
5116
6247
|
}
|
|
5117
6248
|
|
|
6249
|
+
// src/PixelData/uInt32ArrayToPixelData.ts
|
|
6250
|
+
function uInt32ArrayToPixelData(data, width, height) {
|
|
6251
|
+
const buffer = data.buffer;
|
|
6252
|
+
const byteOffset = data.byteOffset;
|
|
6253
|
+
const byteLength = data.byteLength;
|
|
6254
|
+
const clampedArray = new Uint8ClampedArray(buffer, byteOffset, byteLength);
|
|
6255
|
+
const imageData = new ImageData(clampedArray, width, height);
|
|
6256
|
+
return makePixelData(imageData);
|
|
6257
|
+
}
|
|
6258
|
+
|
|
5118
6259
|
// src/PixelData/writePixelDataBuffer.ts
|
|
5119
6260
|
var SCRATCH_BLIT5 = makeClippedBlit();
|
|
5120
6261
|
function writePixelDataBuffer(target, data, _x, _y, _w, _h) {
|
|
@@ -5129,9 +6270,9 @@ function writePixelDataBuffer(target, data, _x, _y, _w, _h) {
|
|
|
5129
6270
|
w: _w,
|
|
5130
6271
|
h: _h
|
|
5131
6272
|
};
|
|
5132
|
-
const dstW = target.
|
|
5133
|
-
const dstH = target.
|
|
5134
|
-
const dstData = target.
|
|
6273
|
+
const dstW = target.w;
|
|
6274
|
+
const dstH = target.h;
|
|
6275
|
+
const dstData = target.data;
|
|
5135
6276
|
const clip = resolveBlitClipping(x, y, 0, 0, w, h, dstW, dstH, w, h, SCRATCH_BLIT5);
|
|
5136
6277
|
if (!clip.inBounds) return;
|
|
5137
6278
|
const {
|
|
@@ -5158,25 +6299,27 @@ function writePaintBufferToPixelData(target, paintBuffer, writePixelDataBufferFn
|
|
|
5158
6299
|
if (tile) {
|
|
5159
6300
|
const dx = tile.tx << tileShift;
|
|
5160
6301
|
const dy = tile.ty << tileShift;
|
|
5161
|
-
writePixelDataBufferFn(target, tile.
|
|
6302
|
+
writePixelDataBufferFn(target, tile.data, dx, dy, tile.w, tile.h);
|
|
5162
6303
|
}
|
|
5163
6304
|
}
|
|
5164
6305
|
}
|
|
5165
6306
|
export {
|
|
6307
|
+
AlphaMaskPaintBuffer,
|
|
5166
6308
|
BASE_FAST_BLEND_MODE_FUNCTIONS,
|
|
5167
6309
|
BASE_PERFECT_BLEND_MODE_FUNCTIONS,
|
|
5168
6310
|
BaseBlendMode,
|
|
6311
|
+
BinaryMaskPaintBuffer,
|
|
5169
6312
|
CANVAS_COMPOSITE_MAP,
|
|
6313
|
+
ColorPaintBuffer,
|
|
6314
|
+
errors_exports as ERRORS,
|
|
5170
6315
|
HistoryManager,
|
|
5171
|
-
IndexedImage,
|
|
5172
6316
|
MaskType,
|
|
5173
|
-
|
|
6317
|
+
PaintMaskOutline,
|
|
5174
6318
|
PixelAccumulator,
|
|
5175
|
-
PixelData,
|
|
5176
6319
|
PixelEngineConfig,
|
|
5177
|
-
PixelTile,
|
|
5178
|
-
PixelTilePool,
|
|
5179
6320
|
PixelWriter,
|
|
6321
|
+
TilePool,
|
|
6322
|
+
TileType,
|
|
5180
6323
|
UnsupportedFormatError,
|
|
5181
6324
|
applyAlphaMaskToPixelData,
|
|
5182
6325
|
applyBinaryMaskToAlphaMask,
|
|
@@ -5206,9 +6349,12 @@ export {
|
|
|
5206
6349
|
colorDistance,
|
|
5207
6350
|
colorDodgeFast,
|
|
5208
6351
|
colorDodgePerfect,
|
|
6352
|
+
commitColorPaintBuffer,
|
|
6353
|
+
commitMaskPaintBuffer,
|
|
5209
6354
|
copyImageData,
|
|
5210
6355
|
copyImageDataLike,
|
|
5211
6356
|
copyMask,
|
|
6357
|
+
copyPixelData,
|
|
5212
6358
|
darkenFast,
|
|
5213
6359
|
darkenPerfect,
|
|
5214
6360
|
darkerFast,
|
|
@@ -5216,10 +6362,19 @@ export {
|
|
|
5216
6362
|
deserializeImageData,
|
|
5217
6363
|
deserializeNullableImageData,
|
|
5218
6364
|
deserializeRawImageData,
|
|
6365
|
+
destinationAtopFast,
|
|
6366
|
+
destinationAtopPerfect,
|
|
6367
|
+
destinationInFast,
|
|
6368
|
+
destinationInPerfect,
|
|
6369
|
+
destinationOutFast,
|
|
6370
|
+
destinationOutPerfect,
|
|
6371
|
+
destinationOverFast,
|
|
6372
|
+
destinationOverPerfect,
|
|
5219
6373
|
differenceFast,
|
|
5220
6374
|
differencePerfect,
|
|
5221
6375
|
divideFast,
|
|
5222
6376
|
dividePerfect,
|
|
6377
|
+
eachTileInBounds,
|
|
5223
6378
|
exclusionFast,
|
|
5224
6379
|
exclusionPerfect,
|
|
5225
6380
|
extractImageDataBuffer,
|
|
@@ -5235,6 +6390,7 @@ export {
|
|
|
5235
6390
|
floodFillSelection,
|
|
5236
6391
|
forEachLinePoint,
|
|
5237
6392
|
getImageDataFromClipboard,
|
|
6393
|
+
getIndexedImageColor,
|
|
5238
6394
|
getIndexedImageColorCounts,
|
|
5239
6395
|
getRectsBounds,
|
|
5240
6396
|
getSupportedPixelFormats,
|
|
@@ -5245,7 +6401,7 @@ export {
|
|
|
5245
6401
|
imageDataToAlphaMaskBuffer,
|
|
5246
6402
|
imageDataToDataUrl,
|
|
5247
6403
|
imageDataToImgBlob,
|
|
5248
|
-
|
|
6404
|
+
imageDataToUint32Array,
|
|
5249
6405
|
imgBlobToImageData,
|
|
5250
6406
|
indexedImageToAverageColor,
|
|
5251
6407
|
indexedImageToImageData,
|
|
@@ -5266,26 +6422,48 @@ export {
|
|
|
5266
6422
|
linearLightFast,
|
|
5267
6423
|
linearLightPerfect,
|
|
5268
6424
|
makeAlphaMask,
|
|
6425
|
+
makeAlphaMaskPaintBufferCanvasRenderer,
|
|
6426
|
+
makeAlphaMaskPaintBufferCommitter,
|
|
6427
|
+
makeAlphaMaskPaintBufferManager,
|
|
6428
|
+
makeAlphaMaskTile,
|
|
5269
6429
|
makeBinaryMask,
|
|
6430
|
+
makeBinaryMaskFromAlphaMask,
|
|
6431
|
+
makeBinaryMaskOutline,
|
|
6432
|
+
makeBinaryMaskPaintBufferCanvasRenderer,
|
|
6433
|
+
makeBinaryMaskPaintBufferCommitter,
|
|
6434
|
+
makeBinaryMaskPaintBufferManager,
|
|
6435
|
+
makeBinaryMaskTile,
|
|
5270
6436
|
makeBlendModeRegistry,
|
|
5271
6437
|
makeCanvasFrameRenderer,
|
|
6438
|
+
makeCanvasPixelDataRenderer,
|
|
6439
|
+
makeCircleBinaryMaskOutline,
|
|
5272
6440
|
makeCirclePaintAlphaMask,
|
|
5273
6441
|
makeCirclePaintBinaryMask,
|
|
5274
6442
|
makeClippedBlit,
|
|
5275
6443
|
makeClippedRect,
|
|
6444
|
+
makeColorPaintBufferCanvasRenderer,
|
|
6445
|
+
makeColorPaintBufferCommitter,
|
|
6446
|
+
makeColorPaintBufferManager,
|
|
5276
6447
|
makeFastBlendModeRegistry,
|
|
5277
6448
|
makeFullPixelMutator,
|
|
5278
6449
|
makeHistoryAction,
|
|
5279
6450
|
makeImageDataLike,
|
|
6451
|
+
makeIndexedImage,
|
|
6452
|
+
makeIndexedImageFromImageData,
|
|
6453
|
+
makeIndexedImageFromImageDataRaw,
|
|
5280
6454
|
makePaintAlphaMask,
|
|
5281
6455
|
makePaintBinaryMask,
|
|
5282
|
-
|
|
6456
|
+
makePaintCursorRenderer,
|
|
5283
6457
|
makePerfectBlendModeRegistry,
|
|
5284
6458
|
makePixelCanvas,
|
|
6459
|
+
makePixelData,
|
|
6460
|
+
makePixelTile,
|
|
6461
|
+
makeRectBinaryMaskOutline,
|
|
5285
6462
|
makeRectFalloffPaintAlphaMask,
|
|
5286
6463
|
makeReusableCanvas,
|
|
5287
6464
|
makeReusableImageData,
|
|
5288
6465
|
makeReusableOffscreenCanvas,
|
|
6466
|
+
makeReusablePixelData,
|
|
5289
6467
|
merge2BinaryMaskRects,
|
|
5290
6468
|
mergeAlphaMasks,
|
|
5291
6469
|
mergeBinaryMaskRects,
|
|
@@ -5322,10 +6500,11 @@ export {
|
|
|
5322
6500
|
pixelDataToAlphaMask,
|
|
5323
6501
|
reflectPixelDataHorizontal,
|
|
5324
6502
|
reflectPixelDataVertical,
|
|
5325
|
-
resample32,
|
|
5326
6503
|
resampleImageData,
|
|
5327
6504
|
resampleIndexedImage,
|
|
5328
6505
|
resamplePixelData,
|
|
6506
|
+
resamplePixelDataInPlace,
|
|
6507
|
+
resampleUint32Array,
|
|
5329
6508
|
resizeImageData,
|
|
5330
6509
|
resolveBlitClipping,
|
|
5331
6510
|
resolveRectClipping,
|
|
@@ -5335,8 +6514,15 @@ export {
|
|
|
5335
6514
|
serializeImageData,
|
|
5336
6515
|
serializeNullableImageData,
|
|
5337
6516
|
setMaskData,
|
|
6517
|
+
setPixelData,
|
|
5338
6518
|
softLightFast,
|
|
5339
6519
|
softLightPerfect,
|
|
6520
|
+
sourceAtopFast,
|
|
6521
|
+
sourceAtopPerfect,
|
|
6522
|
+
sourceInFast,
|
|
6523
|
+
sourceInPerfect,
|
|
6524
|
+
sourceOutFast,
|
|
6525
|
+
sourceOutPerfect,
|
|
5340
6526
|
sourceOverFast,
|
|
5341
6527
|
sourceOverPerfect,
|
|
5342
6528
|
subtractBinaryMaskRects,
|
|
@@ -5347,6 +6533,7 @@ export {
|
|
|
5347
6533
|
trimRectBounds,
|
|
5348
6534
|
uInt32ArrayToImageData,
|
|
5349
6535
|
uInt32ArrayToImageDataLike,
|
|
6536
|
+
uInt32ArrayToPixelData,
|
|
5350
6537
|
unpackAlpha,
|
|
5351
6538
|
unpackBlue,
|
|
5352
6539
|
unpackColor,
|
|
@@ -5360,6 +6547,8 @@ export {
|
|
|
5360
6547
|
writeImageDataToClipboard,
|
|
5361
6548
|
writeImgBlobToClipboard,
|
|
5362
6549
|
writePaintBufferToPixelData,
|
|
5363
|
-
writePixelDataBuffer
|
|
6550
|
+
writePixelDataBuffer,
|
|
6551
|
+
xorFast,
|
|
6552
|
+
xorPerfect
|
|
5364
6553
|
};
|
|
5365
6554
|
//# sourceMappingURL=index.prod.js.map
|