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,9 +3049,6 @@ function resizeImageData(target, newWidth, newHeight, offsetX = 0, offsetY = 0)
3029
3049
  return result;
3030
3050
  }
3031
3051
 
3032
- // src/Internal/helpers.ts
3033
- var macro_halfAndFloor = (value) => value >> 1;
3034
-
3035
3052
  // src/Rect/trimRectBounds.ts
3036
3053
  function trimRectBounds(x, y, w, h, targetWidth, targetHeight, out) {
3037
3054
  const res = out ?? {
@@ -3205,8 +3222,8 @@ var PaintBuffer = class {
3205
3222
  const tileMask = config.tileMask;
3206
3223
  const target = config.target;
3207
3224
  const scratch = this.scratchBounds;
3208
- const centerOffsetX = macro_halfAndFloor(brushWidth - 1);
3209
- const centerOffsetY = macro_halfAndFloor(brushHeight - 1);
3225
+ const centerOffsetX = brushWidth - 1 >> 1;
3226
+ const centerOffsetY = brushHeight - 1 >> 1;
3210
3227
  let changed = false;
3211
3228
  forEachLinePoint(x0, y0, x1, y1, (px, py) => {
3212
3229
  const topLeftX = Math.floor(px + centerOffsetX);
@@ -3628,6 +3645,196 @@ var mutatorApplyBinaryMask = ((writer, deps = defaults12) => {
3628
3645
  };
3629
3646
  });
3630
3647
 
3648
+ // src/PixelData/blendColorPixelDataAlphaMask.ts
3649
+ function blendColorPixelDataAlphaMask(dst, color, mask, opts = {}) {
3650
+ const targetX = opts.x ?? 0;
3651
+ const targetY = opts.y ?? 0;
3652
+ const w = opts.w ?? mask.w;
3653
+ const h = opts.h ?? mask.h;
3654
+ const globalAlpha = opts.alpha ?? 255;
3655
+ const blendFn = opts.blendFn ?? sourceOverPerfect;
3656
+ const mx = opts.mx ?? 0;
3657
+ const my = opts.my ?? 0;
3658
+ const invertMask = opts.invertMask ?? false;
3659
+ if (globalAlpha === 0) return false;
3660
+ const baseSrcAlpha = color >>> 24;
3661
+ const isOverwrite = blendFn.isOverwrite || false;
3662
+ if (baseSrcAlpha === 0 && !isOverwrite) return false;
3663
+ let x = targetX;
3664
+ let y = targetY;
3665
+ let actualW = w;
3666
+ let actualH = h;
3667
+ if (x < 0) {
3668
+ actualW += x;
3669
+ x = 0;
3670
+ }
3671
+ if (y < 0) {
3672
+ actualH += y;
3673
+ y = 0;
3674
+ }
3675
+ actualW = Math.min(actualW, dst.width - x);
3676
+ actualH = Math.min(actualH, dst.height - y);
3677
+ if (actualW <= 0 || actualH <= 0) return false;
3678
+ const dx = x - targetX | 0;
3679
+ const dy = y - targetY | 0;
3680
+ const dst32 = dst.data32;
3681
+ const dw = dst.width;
3682
+ const mPitch = mask.w;
3683
+ const maskData = mask.data;
3684
+ let dIdx = y * dw + x | 0;
3685
+ let mIdx = (my + dy) * mPitch + (mx + dx) | 0;
3686
+ const dStride = dw - actualW | 0;
3687
+ const mStride = mPitch - actualW | 0;
3688
+ const isOpaque = globalAlpha === 255;
3689
+ const colorRGB = color & 16777215;
3690
+ let didChange = false;
3691
+ for (let iy = 0; iy < actualH; iy++) {
3692
+ for (let ix = 0; ix < actualW; ix++) {
3693
+ const mVal = maskData[mIdx];
3694
+ const effM = invertMask ? 255 - mVal : mVal;
3695
+ if (effM === 0) {
3696
+ dIdx++;
3697
+ mIdx++;
3698
+ continue;
3699
+ }
3700
+ let weight = globalAlpha;
3701
+ if (isOpaque) {
3702
+ weight = effM;
3703
+ } else if (effM !== 255) {
3704
+ weight = effM * globalAlpha + 128 >> 8;
3705
+ }
3706
+ if (weight === 0) {
3707
+ dIdx++;
3708
+ mIdx++;
3709
+ continue;
3710
+ }
3711
+ let finalCol = color;
3712
+ if (weight < 255) {
3713
+ const a = baseSrcAlpha * weight + 128 >> 8;
3714
+ if (a === 0 && !isOverwrite) {
3715
+ dIdx++;
3716
+ mIdx++;
3717
+ continue;
3718
+ }
3719
+ finalCol = (colorRGB | a << 24) >>> 0;
3720
+ }
3721
+ const current = dst32[dIdx];
3722
+ const next = blendFn(finalCol, current);
3723
+ if (current !== next) {
3724
+ dst32[dIdx] = next;
3725
+ didChange = true;
3726
+ }
3727
+ dIdx++;
3728
+ mIdx++;
3729
+ }
3730
+ dIdx += dStride;
3731
+ mIdx += mStride;
3732
+ }
3733
+ return didChange;
3734
+ }
3735
+
3736
+ // src/PixelData/blendColorPixelDataBinaryMask.ts
3737
+ function blendColorPixelDataBinaryMask(dst, color, mask, opts = {}) {
3738
+ const targetX = opts.x ?? 0;
3739
+ const targetY = opts.y ?? 0;
3740
+ let w = opts.w ?? mask.w;
3741
+ let h = opts.h ?? mask.h;
3742
+ const globalAlpha = opts.alpha ?? 255;
3743
+ const blendFn = opts.blendFn ?? sourceOverPerfect;
3744
+ const mx = opts.mx ?? 0;
3745
+ const my = opts.my ?? 0;
3746
+ const invertMask = opts.invertMask ?? false;
3747
+ if (globalAlpha === 0) return false;
3748
+ const baseSrcAlpha = color >>> 24;
3749
+ const isOverwrite = blendFn.isOverwrite || false;
3750
+ if (baseSrcAlpha === 0 && !isOverwrite) return false;
3751
+ let x = targetX;
3752
+ let y = targetY;
3753
+ if (x < 0) {
3754
+ w += x;
3755
+ x = 0;
3756
+ }
3757
+ if (y < 0) {
3758
+ h += y;
3759
+ y = 0;
3760
+ }
3761
+ const actualW = Math.min(w, dst.width - x);
3762
+ const actualH = Math.min(h, dst.height - y);
3763
+ if (actualW <= 0 || actualH <= 0) return false;
3764
+ let baseColorWithGlobalAlpha = color;
3765
+ if (globalAlpha < 255) {
3766
+ const a = baseSrcAlpha * globalAlpha + 128 >> 8;
3767
+ if (a === 0 && !isOverwrite) return false;
3768
+ baseColorWithGlobalAlpha = (color & 16777215 | a << 24) >>> 0;
3769
+ }
3770
+ const dx = x - targetX | 0;
3771
+ const dy = y - targetY | 0;
3772
+ const dst32 = dst.data32;
3773
+ const dw = dst.width;
3774
+ const mPitch = mask.w;
3775
+ const maskData = mask.data;
3776
+ let dIdx = y * dw + x | 0;
3777
+ let mIdx = (my + dy) * mPitch + (mx + dx) | 0;
3778
+ const dStride = dw - actualW | 0;
3779
+ const mStride = mPitch - actualW | 0;
3780
+ const skipVal = invertMask ? 1 : 0;
3781
+ let didChange = false;
3782
+ for (let iy = 0; iy < actualH; iy++) {
3783
+ for (let ix = 0; ix < actualW; ix++) {
3784
+ if (maskData[mIdx] === skipVal) {
3785
+ dIdx++;
3786
+ mIdx++;
3787
+ continue;
3788
+ }
3789
+ const current = dst32[dIdx];
3790
+ const next = blendFn(baseColorWithGlobalAlpha, current);
3791
+ if (current !== next) {
3792
+ dst32[dIdx] = next;
3793
+ didChange = true;
3794
+ }
3795
+ dIdx++;
3796
+ mIdx++;
3797
+ }
3798
+ dIdx += dStride;
3799
+ mIdx += mStride;
3800
+ }
3801
+ return didChange;
3802
+ }
3803
+
3804
+ // src/History/PixelMutator/mutatorBlendPaintMask.ts
3805
+ var defaults13 = {
3806
+ blendColorPixelDataAlphaMask,
3807
+ blendColorPixelDataBinaryMask
3808
+ };
3809
+ var mutatorBlendPaintMask = ((writer, deps = defaults13) => {
3810
+ const {
3811
+ blendColorPixelDataBinaryMask: blendColorPixelDataBinaryMask2 = defaults13.blendColorPixelDataBinaryMask,
3812
+ blendColorPixelDataAlphaMask: blendColorPixelDataAlphaMask2 = defaults13.blendColorPixelDataAlphaMask
3813
+ } = deps;
3814
+ const OPTS = {
3815
+ x: 0,
3816
+ y: 0,
3817
+ blendFn: sourceOverPerfect,
3818
+ alpha: 255
3819
+ };
3820
+ return {
3821
+ blendColorPaintMask(color, mask, x, y, alpha = 255, blendFn = sourceOverPerfect) {
3822
+ const tx = x + mask.centerOffsetX;
3823
+ const ty = y + mask.centerOffsetY;
3824
+ const didChange = writer.accumulator.storeRegionBeforeState(tx, ty, mask.w, mask.h);
3825
+ OPTS.x = tx;
3826
+ OPTS.y = ty;
3827
+ OPTS.alpha = alpha;
3828
+ OPTS.blendFn = blendFn;
3829
+ if (mask.type === 1 /* BINARY */) {
3830
+ return didChange(blendColorPixelDataBinaryMask2(writer.config.target, color, mask, OPTS));
3831
+ } else {
3832
+ return didChange(blendColorPixelDataAlphaMask2(writer.config.target, color, mask, OPTS));
3833
+ }
3834
+ }
3835
+ };
3836
+ });
3837
+
3631
3838
  // src/ImageData/copyImageData.ts
3632
3839
  function copyImageData({
3633
3840
  data,
@@ -4617,162 +4824,6 @@ var PixelData = class {
4617
4824
  }
4618
4825
  };
4619
4826
 
4620
- // src/PixelData/blendColorPixelDataAlphaMask.ts
4621
- function blendColorPixelDataAlphaMask(dst, color, mask, opts = {}) {
4622
- const targetX = opts.x ?? 0;
4623
- const targetY = opts.y ?? 0;
4624
- const w = opts.w ?? mask.w;
4625
- const h = opts.h ?? mask.h;
4626
- const globalAlpha = opts.alpha ?? 255;
4627
- const blendFn = opts.blendFn ?? sourceOverPerfect;
4628
- const mx = opts.mx ?? 0;
4629
- const my = opts.my ?? 0;
4630
- const invertMask = opts.invertMask ?? false;
4631
- if (globalAlpha === 0) return false;
4632
- const baseSrcAlpha = color >>> 24;
4633
- const isOverwrite = blendFn.isOverwrite || false;
4634
- if (baseSrcAlpha === 0 && !isOverwrite) return false;
4635
- let x = targetX;
4636
- let y = targetY;
4637
- let actualW = w;
4638
- let actualH = h;
4639
- if (x < 0) {
4640
- actualW += x;
4641
- x = 0;
4642
- }
4643
- if (y < 0) {
4644
- actualH += y;
4645
- y = 0;
4646
- }
4647
- actualW = Math.min(actualW, dst.width - x);
4648
- actualH = Math.min(actualH, dst.height - y);
4649
- if (actualW <= 0 || actualH <= 0) return false;
4650
- const dx = x - targetX | 0;
4651
- const dy = y - targetY | 0;
4652
- const dst32 = dst.data32;
4653
- const dw = dst.width;
4654
- const mPitch = mask.w;
4655
- const maskData = mask.data;
4656
- let dIdx = y * dw + x | 0;
4657
- let mIdx = (my + dy) * mPitch + (mx + dx) | 0;
4658
- const dStride = dw - actualW | 0;
4659
- const mStride = mPitch - actualW | 0;
4660
- const isOpaque = globalAlpha === 255;
4661
- const colorRGB = color & 16777215;
4662
- let didChange = false;
4663
- for (let iy = 0; iy < actualH; iy++) {
4664
- for (let ix = 0; ix < actualW; ix++) {
4665
- const mVal = maskData[mIdx];
4666
- const effM = invertMask ? 255 - mVal : mVal;
4667
- if (effM === 0) {
4668
- dIdx++;
4669
- mIdx++;
4670
- continue;
4671
- }
4672
- let weight = globalAlpha;
4673
- if (isOpaque) {
4674
- weight = effM;
4675
- } else if (effM !== 255) {
4676
- weight = effM * globalAlpha + 128 >> 8;
4677
- }
4678
- if (weight === 0) {
4679
- dIdx++;
4680
- mIdx++;
4681
- continue;
4682
- }
4683
- let finalCol = color;
4684
- if (weight < 255) {
4685
- const a = baseSrcAlpha * weight + 128 >> 8;
4686
- if (a === 0 && !isOverwrite) {
4687
- dIdx++;
4688
- mIdx++;
4689
- continue;
4690
- }
4691
- finalCol = (colorRGB | a << 24) >>> 0;
4692
- }
4693
- const current = dst32[dIdx];
4694
- const next = blendFn(finalCol, current);
4695
- if (current !== next) {
4696
- dst32[dIdx] = next;
4697
- didChange = true;
4698
- }
4699
- dIdx++;
4700
- mIdx++;
4701
- }
4702
- dIdx += dStride;
4703
- mIdx += mStride;
4704
- }
4705
- return didChange;
4706
- }
4707
-
4708
- // src/PixelData/blendColorPixelDataBinaryMask.ts
4709
- function blendColorPixelDataBinaryMask(dst, color, mask, opts = {}) {
4710
- const targetX = opts.x ?? 0;
4711
- const targetY = opts.y ?? 0;
4712
- let w = opts.w ?? mask.w;
4713
- let h = opts.h ?? mask.h;
4714
- const globalAlpha = opts.alpha ?? 255;
4715
- const blendFn = opts.blendFn ?? sourceOverPerfect;
4716
- const mx = opts.mx ?? 0;
4717
- const my = opts.my ?? 0;
4718
- const invertMask = opts.invertMask ?? false;
4719
- if (globalAlpha === 0) return false;
4720
- const baseSrcAlpha = color >>> 24;
4721
- const isOverwrite = blendFn.isOverwrite || false;
4722
- if (baseSrcAlpha === 0 && !isOverwrite) return false;
4723
- let x = targetX;
4724
- let y = targetY;
4725
- if (x < 0) {
4726
- w += x;
4727
- x = 0;
4728
- }
4729
- if (y < 0) {
4730
- h += y;
4731
- y = 0;
4732
- }
4733
- const actualW = Math.min(w, dst.width - x);
4734
- const actualH = Math.min(h, dst.height - y);
4735
- if (actualW <= 0 || actualH <= 0) return false;
4736
- let baseColorWithGlobalAlpha = color;
4737
- if (globalAlpha < 255) {
4738
- const a = baseSrcAlpha * globalAlpha + 128 >> 8;
4739
- if (a === 0 && !isOverwrite) return false;
4740
- baseColorWithGlobalAlpha = (color & 16777215 | a << 24) >>> 0;
4741
- }
4742
- const dx = x - targetX | 0;
4743
- const dy = y - targetY | 0;
4744
- const dst32 = dst.data32;
4745
- const dw = dst.width;
4746
- const mPitch = mask.w;
4747
- const maskData = mask.data;
4748
- let dIdx = y * dw + x | 0;
4749
- let mIdx = (my + dy) * mPitch + (mx + dx) | 0;
4750
- const dStride = dw - actualW | 0;
4751
- const mStride = mPitch - actualW | 0;
4752
- const skipVal = invertMask ? 1 : 0;
4753
- let didChange = false;
4754
- for (let iy = 0; iy < actualH; iy++) {
4755
- for (let ix = 0; ix < actualW; ix++) {
4756
- if (maskData[mIdx] === skipVal) {
4757
- dIdx++;
4758
- mIdx++;
4759
- continue;
4760
- }
4761
- const current = dst32[dIdx];
4762
- const next = blendFn(baseColorWithGlobalAlpha, current);
4763
- if (current !== next) {
4764
- dst32[dIdx] = next;
4765
- didChange = true;
4766
- }
4767
- dIdx++;
4768
- mIdx++;
4769
- }
4770
- dIdx += dStride;
4771
- mIdx += mStride;
4772
- }
4773
- return didChange;
4774
- }
4775
-
4776
4827
  // src/PixelData/blendPixelDataPaintBuffer.ts
4777
4828
  var SCRATCH_OPTS = {
4778
4829
  x: 0,
@@ -5093,6 +5144,9 @@ function makeCirclePaintBinaryMask(size) {
5093
5144
  };
5094
5145
  }
5095
5146
 
5147
+ // src/Internal/helpers.ts
5148
+ var macro_halfAndFloor = (value) => value >> 1;
5149
+
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: -(mask.w >> 1),
5104
- centerOffsetY: -(mask.h >> 1)
5157
+ centerOffsetX: -macro_halfAndFloor(mask.w),
5158
+ centerOffsetY: -macro_halfAndFloor(mask.h)
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: -(mask.w >> 1),
5114
- centerOffsetY: -(mask.h >> 1)
5167
+ centerOffsetX: -macro_halfAndFloor(mask.w),
5168
+ centerOffsetY: -macro_halfAndFloor(mask.h)
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,