pixel-data-js 0.25.0 → 0.25.2

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.
@@ -23,6 +23,7 @@ __export(src_exports, {
23
23
  BASE_FAST_BLEND_MODE_FUNCTIONS: () => BASE_FAST_BLEND_MODE_FUNCTIONS,
24
24
  BASE_PERFECT_BLEND_MODE_FUNCTIONS: () => BASE_PERFECT_BLEND_MODE_FUNCTIONS,
25
25
  BaseBlendMode: () => BaseBlendMode,
26
+ CANVAS_COMPOSITE_MAP: () => CANVAS_COMPOSITE_MAP,
26
27
  CANVAS_CTX_FAILED: () => CANVAS_CTX_FAILED,
27
28
  HistoryManager: () => HistoryManager,
28
29
  IndexedImage: () => IndexedImage,
@@ -146,6 +147,7 @@ __export(src_exports, {
146
147
  mutatorApplyAlphaMask: () => mutatorApplyAlphaMask,
147
148
  mutatorApplyBinaryMask: () => mutatorApplyBinaryMask,
148
149
  mutatorBlendColor: () => mutatorBlendColor,
150
+ mutatorBlendPaintMask: () => mutatorBlendPaintMask,
149
151
  mutatorBlendPixel: () => mutatorBlendPixel,
150
152
  mutatorBlendPixelData: () => mutatorBlendPixelData,
151
153
  mutatorBlendPixelDataAlphaMask: () => mutatorBlendPixelDataAlphaMask,
@@ -1741,6 +1743,24 @@ var getKeyByValue = (obj, value) => {
1741
1743
  var OFFSCREEN_CANVAS_CTX_FAILED = "Failed to create OffscreenCanvas context";
1742
1744
  var CANVAS_CTX_FAILED = "Failed to create Canvas context";
1743
1745
 
1746
+ // src/Canvas/canvas-blend-modes.ts
1747
+ var CANVAS_COMPOSITE_MAP = {
1748
+ [BaseBlendMode.overwrite]: "copy",
1749
+ [BaseBlendMode.sourceOver]: "source-over",
1750
+ [BaseBlendMode.darken]: "darken",
1751
+ [BaseBlendMode.multiply]: "multiply",
1752
+ [BaseBlendMode.colorBurn]: "color-burn",
1753
+ [BaseBlendMode.lighten]: "lighten",
1754
+ [BaseBlendMode.screen]: "screen",
1755
+ [BaseBlendMode.colorDodge]: "color-dodge",
1756
+ [BaseBlendMode.linearDodge]: "lighter",
1757
+ [BaseBlendMode.overlay]: "overlay",
1758
+ [BaseBlendMode.softLight]: "soft-light",
1759
+ [BaseBlendMode.hardLight]: "hard-light",
1760
+ [BaseBlendMode.difference]: "difference",
1761
+ [BaseBlendMode.exclusion]: "exclusion"
1762
+ };
1763
+
1744
1764
  // src/Canvas/ReusableCanvas.ts
1745
1765
  function makeReusableCanvas() {
1746
1766
  return makeReusableCanvasMeta((w, h) => {
@@ -3029,6 +3049,9 @@ function resizeImageData(target, newWidth, newHeight, offsetX = 0, offsetY = 0)
3029
3049
  return result;
3030
3050
  }
3031
3051
 
3052
+ // src/Internal/helpers.ts
3053
+ var macro_halfAndFloor = (value) => value >> 1;
3054
+
3032
3055
  // src/Rect/trimRectBounds.ts
3033
3056
  function trimRectBounds(x, y, w, h, targetWidth, targetHeight, out) {
3034
3057
  const res = out ?? {
@@ -3202,8 +3225,8 @@ var PaintBuffer = class {
3202
3225
  const tileMask = config.tileMask;
3203
3226
  const target = config.target;
3204
3227
  const scratch = this.scratchBounds;
3205
- const centerOffsetX = brushWidth - 1 >> 1;
3206
- const centerOffsetY = brushHeight - 1 >> 1;
3228
+ const centerOffsetX = macro_halfAndFloor(brushWidth - 1);
3229
+ const centerOffsetY = macro_halfAndFloor(brushHeight - 1);
3207
3230
  let changed = false;
3208
3231
  forEachLinePoint(x0, y0, x1, y1, (px, py) => {
3209
3232
  const topLeftX = Math.floor(px + centerOffsetX);
@@ -3625,6 +3648,196 @@ var mutatorApplyBinaryMask = ((writer, deps = defaults12) => {
3625
3648
  };
3626
3649
  });
3627
3650
 
3651
+ // src/PixelData/blendColorPixelDataAlphaMask.ts
3652
+ function blendColorPixelDataAlphaMask(dst, color, mask, opts = {}) {
3653
+ const targetX = opts.x ?? 0;
3654
+ const targetY = opts.y ?? 0;
3655
+ const w = opts.w ?? mask.w;
3656
+ const h = opts.h ?? mask.h;
3657
+ const globalAlpha = opts.alpha ?? 255;
3658
+ const blendFn = opts.blendFn ?? sourceOverPerfect;
3659
+ const mx = opts.mx ?? 0;
3660
+ const my = opts.my ?? 0;
3661
+ const invertMask = opts.invertMask ?? false;
3662
+ if (globalAlpha === 0) return false;
3663
+ const baseSrcAlpha = color >>> 24;
3664
+ const isOverwrite = blendFn.isOverwrite || false;
3665
+ if (baseSrcAlpha === 0 && !isOverwrite) return false;
3666
+ let x = targetX;
3667
+ let y = targetY;
3668
+ let actualW = w;
3669
+ let actualH = h;
3670
+ if (x < 0) {
3671
+ actualW += x;
3672
+ x = 0;
3673
+ }
3674
+ if (y < 0) {
3675
+ actualH += y;
3676
+ y = 0;
3677
+ }
3678
+ actualW = Math.min(actualW, dst.width - x);
3679
+ actualH = Math.min(actualH, dst.height - y);
3680
+ if (actualW <= 0 || actualH <= 0) return false;
3681
+ const dx = x - targetX | 0;
3682
+ const dy = y - targetY | 0;
3683
+ const dst32 = dst.data32;
3684
+ const dw = dst.width;
3685
+ const mPitch = mask.w;
3686
+ const maskData = mask.data;
3687
+ let dIdx = y * dw + x | 0;
3688
+ let mIdx = (my + dy) * mPitch + (mx + dx) | 0;
3689
+ const dStride = dw - actualW | 0;
3690
+ const mStride = mPitch - actualW | 0;
3691
+ const isOpaque = globalAlpha === 255;
3692
+ const colorRGB = color & 16777215;
3693
+ let didChange = false;
3694
+ for (let iy = 0; iy < actualH; iy++) {
3695
+ for (let ix = 0; ix < actualW; ix++) {
3696
+ const mVal = maskData[mIdx];
3697
+ const effM = invertMask ? 255 - mVal : mVal;
3698
+ if (effM === 0) {
3699
+ dIdx++;
3700
+ mIdx++;
3701
+ continue;
3702
+ }
3703
+ let weight = globalAlpha;
3704
+ if (isOpaque) {
3705
+ weight = effM;
3706
+ } else if (effM !== 255) {
3707
+ weight = effM * globalAlpha + 128 >> 8;
3708
+ }
3709
+ if (weight === 0) {
3710
+ dIdx++;
3711
+ mIdx++;
3712
+ continue;
3713
+ }
3714
+ let finalCol = color;
3715
+ if (weight < 255) {
3716
+ const a = baseSrcAlpha * weight + 128 >> 8;
3717
+ if (a === 0 && !isOverwrite) {
3718
+ dIdx++;
3719
+ mIdx++;
3720
+ continue;
3721
+ }
3722
+ finalCol = (colorRGB | a << 24) >>> 0;
3723
+ }
3724
+ const current = dst32[dIdx];
3725
+ const next = blendFn(finalCol, current);
3726
+ if (current !== next) {
3727
+ dst32[dIdx] = next;
3728
+ didChange = true;
3729
+ }
3730
+ dIdx++;
3731
+ mIdx++;
3732
+ }
3733
+ dIdx += dStride;
3734
+ mIdx += mStride;
3735
+ }
3736
+ return didChange;
3737
+ }
3738
+
3739
+ // src/PixelData/blendColorPixelDataBinaryMask.ts
3740
+ function blendColorPixelDataBinaryMask(dst, color, mask, opts = {}) {
3741
+ const targetX = opts.x ?? 0;
3742
+ const targetY = opts.y ?? 0;
3743
+ let w = opts.w ?? mask.w;
3744
+ let h = opts.h ?? mask.h;
3745
+ const globalAlpha = opts.alpha ?? 255;
3746
+ const blendFn = opts.blendFn ?? sourceOverPerfect;
3747
+ const mx = opts.mx ?? 0;
3748
+ const my = opts.my ?? 0;
3749
+ const invertMask = opts.invertMask ?? false;
3750
+ if (globalAlpha === 0) return false;
3751
+ const baseSrcAlpha = color >>> 24;
3752
+ const isOverwrite = blendFn.isOverwrite || false;
3753
+ if (baseSrcAlpha === 0 && !isOverwrite) return false;
3754
+ let x = targetX;
3755
+ let y = targetY;
3756
+ if (x < 0) {
3757
+ w += x;
3758
+ x = 0;
3759
+ }
3760
+ if (y < 0) {
3761
+ h += y;
3762
+ y = 0;
3763
+ }
3764
+ const actualW = Math.min(w, dst.width - x);
3765
+ const actualH = Math.min(h, dst.height - y);
3766
+ if (actualW <= 0 || actualH <= 0) return false;
3767
+ let baseColorWithGlobalAlpha = color;
3768
+ if (globalAlpha < 255) {
3769
+ const a = baseSrcAlpha * globalAlpha + 128 >> 8;
3770
+ if (a === 0 && !isOverwrite) return false;
3771
+ baseColorWithGlobalAlpha = (color & 16777215 | a << 24) >>> 0;
3772
+ }
3773
+ const dx = x - targetX | 0;
3774
+ const dy = y - targetY | 0;
3775
+ const dst32 = dst.data32;
3776
+ const dw = dst.width;
3777
+ const mPitch = mask.w;
3778
+ const maskData = mask.data;
3779
+ let dIdx = y * dw + x | 0;
3780
+ let mIdx = (my + dy) * mPitch + (mx + dx) | 0;
3781
+ const dStride = dw - actualW | 0;
3782
+ const mStride = mPitch - actualW | 0;
3783
+ const skipVal = invertMask ? 1 : 0;
3784
+ let didChange = false;
3785
+ for (let iy = 0; iy < actualH; iy++) {
3786
+ for (let ix = 0; ix < actualW; ix++) {
3787
+ if (maskData[mIdx] === skipVal) {
3788
+ dIdx++;
3789
+ mIdx++;
3790
+ continue;
3791
+ }
3792
+ const current = dst32[dIdx];
3793
+ const next = blendFn(baseColorWithGlobalAlpha, current);
3794
+ if (current !== next) {
3795
+ dst32[dIdx] = next;
3796
+ didChange = true;
3797
+ }
3798
+ dIdx++;
3799
+ mIdx++;
3800
+ }
3801
+ dIdx += dStride;
3802
+ mIdx += mStride;
3803
+ }
3804
+ return didChange;
3805
+ }
3806
+
3807
+ // src/History/PixelMutator/mutatorBlendPaintMask.ts
3808
+ var defaults13 = {
3809
+ blendColorPixelDataAlphaMask,
3810
+ blendColorPixelDataBinaryMask
3811
+ };
3812
+ var mutatorBlendPaintMask = ((writer, deps = defaults13) => {
3813
+ const {
3814
+ blendColorPixelDataBinaryMask: blendColorPixelDataBinaryMask2 = defaults13.blendColorPixelDataBinaryMask,
3815
+ blendColorPixelDataAlphaMask: blendColorPixelDataAlphaMask2 = defaults13.blendColorPixelDataAlphaMask
3816
+ } = deps;
3817
+ const OPTS = {
3818
+ x: 0,
3819
+ y: 0,
3820
+ blendFn: sourceOverPerfect,
3821
+ alpha: 255
3822
+ };
3823
+ return {
3824
+ blendColorPaintMask(color, mask, x, y, alpha = 255, blendFn = sourceOverPerfect) {
3825
+ const tx = x + mask.centerOffsetX;
3826
+ const ty = y + mask.centerOffsetY;
3827
+ const didChange = writer.accumulator.storeRegionBeforeState(tx, ty, mask.w, mask.h);
3828
+ OPTS.x = tx;
3829
+ OPTS.y = ty;
3830
+ OPTS.alpha = alpha;
3831
+ OPTS.blendFn = blendFn;
3832
+ if (mask.type === 1 /* BINARY */) {
3833
+ return didChange(blendColorPixelDataBinaryMask2(writer.config.target, color, mask, OPTS));
3834
+ } else {
3835
+ return didChange(blendColorPixelDataAlphaMask2(writer.config.target, color, mask, OPTS));
3836
+ }
3837
+ }
3838
+ };
3839
+ });
3840
+
3628
3841
  // src/ImageData/copyImageData.ts
3629
3842
  function copyImageData({
3630
3843
  data,
@@ -4614,162 +4827,6 @@ var PixelData = class {
4614
4827
  }
4615
4828
  };
4616
4829
 
4617
- // src/PixelData/blendColorPixelDataAlphaMask.ts
4618
- function blendColorPixelDataAlphaMask(dst, color, mask, opts = {}) {
4619
- const targetX = opts.x ?? 0;
4620
- const targetY = opts.y ?? 0;
4621
- const w = opts.w ?? mask.w;
4622
- const h = opts.h ?? mask.h;
4623
- const globalAlpha = opts.alpha ?? 255;
4624
- const blendFn = opts.blendFn ?? sourceOverPerfect;
4625
- const mx = opts.mx ?? 0;
4626
- const my = opts.my ?? 0;
4627
- const invertMask = opts.invertMask ?? false;
4628
- if (globalAlpha === 0) return false;
4629
- const baseSrcAlpha = color >>> 24;
4630
- const isOverwrite = blendFn.isOverwrite || false;
4631
- if (baseSrcAlpha === 0 && !isOverwrite) return false;
4632
- let x = targetX;
4633
- let y = targetY;
4634
- let actualW = w;
4635
- let actualH = h;
4636
- if (x < 0) {
4637
- actualW += x;
4638
- x = 0;
4639
- }
4640
- if (y < 0) {
4641
- actualH += y;
4642
- y = 0;
4643
- }
4644
- actualW = Math.min(actualW, dst.width - x);
4645
- actualH = Math.min(actualH, dst.height - y);
4646
- if (actualW <= 0 || actualH <= 0) return false;
4647
- const dx = x - targetX | 0;
4648
- const dy = y - targetY | 0;
4649
- const dst32 = dst.data32;
4650
- const dw = dst.width;
4651
- const mPitch = mask.w;
4652
- const maskData = mask.data;
4653
- let dIdx = y * dw + x | 0;
4654
- let mIdx = (my + dy) * mPitch + (mx + dx) | 0;
4655
- const dStride = dw - actualW | 0;
4656
- const mStride = mPitch - actualW | 0;
4657
- const isOpaque = globalAlpha === 255;
4658
- const colorRGB = color & 16777215;
4659
- let didChange = false;
4660
- for (let iy = 0; iy < actualH; iy++) {
4661
- for (let ix = 0; ix < actualW; ix++) {
4662
- const mVal = maskData[mIdx];
4663
- const effM = invertMask ? 255 - mVal : mVal;
4664
- if (effM === 0) {
4665
- dIdx++;
4666
- mIdx++;
4667
- continue;
4668
- }
4669
- let weight = globalAlpha;
4670
- if (isOpaque) {
4671
- weight = effM;
4672
- } else if (effM !== 255) {
4673
- weight = effM * globalAlpha + 128 >> 8;
4674
- }
4675
- if (weight === 0) {
4676
- dIdx++;
4677
- mIdx++;
4678
- continue;
4679
- }
4680
- let finalCol = color;
4681
- if (weight < 255) {
4682
- const a = baseSrcAlpha * weight + 128 >> 8;
4683
- if (a === 0 && !isOverwrite) {
4684
- dIdx++;
4685
- mIdx++;
4686
- continue;
4687
- }
4688
- finalCol = (colorRGB | a << 24) >>> 0;
4689
- }
4690
- const current = dst32[dIdx];
4691
- const next = blendFn(finalCol, current);
4692
- if (current !== next) {
4693
- dst32[dIdx] = next;
4694
- didChange = true;
4695
- }
4696
- dIdx++;
4697
- mIdx++;
4698
- }
4699
- dIdx += dStride;
4700
- mIdx += mStride;
4701
- }
4702
- return didChange;
4703
- }
4704
-
4705
- // src/PixelData/blendColorPixelDataBinaryMask.ts
4706
- function blendColorPixelDataBinaryMask(dst, color, mask, opts = {}) {
4707
- const targetX = opts.x ?? 0;
4708
- const targetY = opts.y ?? 0;
4709
- let w = opts.w ?? mask.w;
4710
- let h = opts.h ?? mask.h;
4711
- const globalAlpha = opts.alpha ?? 255;
4712
- const blendFn = opts.blendFn ?? sourceOverPerfect;
4713
- const mx = opts.mx ?? 0;
4714
- const my = opts.my ?? 0;
4715
- const invertMask = opts.invertMask ?? false;
4716
- if (globalAlpha === 0) return false;
4717
- const baseSrcAlpha = color >>> 24;
4718
- const isOverwrite = blendFn.isOverwrite || false;
4719
- if (baseSrcAlpha === 0 && !isOverwrite) return false;
4720
- let x = targetX;
4721
- let y = targetY;
4722
- if (x < 0) {
4723
- w += x;
4724
- x = 0;
4725
- }
4726
- if (y < 0) {
4727
- h += y;
4728
- y = 0;
4729
- }
4730
- const actualW = Math.min(w, dst.width - x);
4731
- const actualH = Math.min(h, dst.height - y);
4732
- if (actualW <= 0 || actualH <= 0) return false;
4733
- let baseColorWithGlobalAlpha = color;
4734
- if (globalAlpha < 255) {
4735
- const a = baseSrcAlpha * globalAlpha + 128 >> 8;
4736
- if (a === 0 && !isOverwrite) return false;
4737
- baseColorWithGlobalAlpha = (color & 16777215 | a << 24) >>> 0;
4738
- }
4739
- const dx = x - targetX | 0;
4740
- const dy = y - targetY | 0;
4741
- const dst32 = dst.data32;
4742
- const dw = dst.width;
4743
- const mPitch = mask.w;
4744
- const maskData = mask.data;
4745
- let dIdx = y * dw + x | 0;
4746
- let mIdx = (my + dy) * mPitch + (mx + dx) | 0;
4747
- const dStride = dw - actualW | 0;
4748
- const mStride = mPitch - actualW | 0;
4749
- const skipVal = invertMask ? 1 : 0;
4750
- let didChange = false;
4751
- for (let iy = 0; iy < actualH; iy++) {
4752
- for (let ix = 0; ix < actualW; ix++) {
4753
- if (maskData[mIdx] === skipVal) {
4754
- dIdx++;
4755
- mIdx++;
4756
- continue;
4757
- }
4758
- const current = dst32[dIdx];
4759
- const next = blendFn(baseColorWithGlobalAlpha, current);
4760
- if (current !== next) {
4761
- dst32[dIdx] = next;
4762
- didChange = true;
4763
- }
4764
- dIdx++;
4765
- mIdx++;
4766
- }
4767
- dIdx += dStride;
4768
- mIdx += mStride;
4769
- }
4770
- return didChange;
4771
- }
4772
-
4773
4830
  // src/PixelData/blendPixelDataPaintBuffer.ts
4774
4831
  var SCRATCH_OPTS = {
4775
4832
  x: 0,
@@ -5090,9 +5147,6 @@ function makeCirclePaintBinaryMask(size) {
5090
5147
  };
5091
5148
  }
5092
5149
 
5093
- // src/Internal/helpers.ts
5094
- var macro_halfAndFloor = (value) => value >> 1;
5095
-
5096
5150
  // src/Paint/makePaintMask.ts
5097
5151
  function makePaintBinaryMask(mask) {
5098
5152
  return {
@@ -5100,8 +5154,8 @@ function makePaintBinaryMask(mask) {
5100
5154
  data: mask.data,
5101
5155
  w: mask.w,
5102
5156
  h: mask.h,
5103
- centerOffsetX: -macro_halfAndFloor(mask.w),
5104
- centerOffsetY: -macro_halfAndFloor(mask.h)
5157
+ centerOffsetX: -(mask.w >> 1),
5158
+ centerOffsetY: -(mask.h >> 1)
5105
5159
  };
5106
5160
  }
5107
5161
  function makePaintAlphaMask(mask) {
@@ -5110,8 +5164,8 @@ function makePaintAlphaMask(mask) {
5110
5164
  data: mask.data,
5111
5165
  w: mask.w,
5112
5166
  h: mask.h,
5113
- centerOffsetX: -macro_halfAndFloor(mask.w),
5114
- centerOffsetY: -macro_halfAndFloor(mask.h)
5167
+ centerOffsetX: -(mask.w >> 1),
5168
+ centerOffsetY: -(mask.h >> 1)
5115
5169
  };
5116
5170
  }
5117
5171
 
@@ -5179,6 +5233,7 @@ function makePaintBufferCanvasRenderer(paintBuffer, offscreenCanvasClass = Offsc
5179
5233
  BASE_FAST_BLEND_MODE_FUNCTIONS,
5180
5234
  BASE_PERFECT_BLEND_MODE_FUNCTIONS,
5181
5235
  BaseBlendMode,
5236
+ CANVAS_COMPOSITE_MAP,
5182
5237
  CANVAS_CTX_FAILED,
5183
5238
  HistoryManager,
5184
5239
  IndexedImage,
@@ -5302,6 +5357,7 @@ function makePaintBufferCanvasRenderer(paintBuffer, offscreenCanvasClass = Offsc
5302
5357
  mutatorApplyAlphaMask,
5303
5358
  mutatorApplyBinaryMask,
5304
5359
  mutatorBlendColor,
5360
+ mutatorBlendPaintMask,
5305
5361
  mutatorBlendPixel,
5306
5362
  mutatorBlendPixelData,
5307
5363
  mutatorBlendPixelDataAlphaMask,