pixel-data-js 0.27.0 → 0.28.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.
Files changed (139) hide show
  1. package/README.md +12 -2
  2. package/dist/index.prod.cjs +2222 -1045
  3. package/dist/index.prod.cjs.map +1 -1
  4. package/dist/index.prod.d.ts +542 -417
  5. package/dist/index.prod.js +2167 -1024
  6. package/dist/index.prod.js.map +1 -1
  7. package/package.json +11 -11
  8. package/src/Algorithm/floodFillSelection.ts +8 -6
  9. package/src/Algorithm/forEachLinePoint.ts +6 -6
  10. package/src/{Internal/resample32.ts → Algorithm/resampleUint32Array.ts} +11 -21
  11. package/src/BlendModes/blend-modes-fast.ts +169 -0
  12. package/src/BlendModes/blend-modes-perfect.ts +207 -0
  13. package/src/BlendModes/blend-modes.ts +9 -0
  14. package/src/Canvas/CanvasFrameRenderer.ts +20 -28
  15. package/src/Canvas/CanvasPixelDataRenderer.ts +23 -0
  16. package/src/Canvas/PixelCanvas.ts +2 -7
  17. package/src/Canvas/ReusableCanvas.ts +4 -12
  18. package/src/Canvas/_canvas-types.ts +26 -0
  19. package/src/History/PixelAccumulator.ts +17 -17
  20. package/src/History/PixelEngineConfig.ts +3 -3
  21. package/src/History/PixelMutator/mutatorApplyAlphaMask.ts +4 -3
  22. package/src/History/PixelMutator/mutatorApplyBinaryMask.ts +4 -3
  23. package/src/History/PixelMutator/mutatorApplyMask.ts +4 -3
  24. package/src/History/PixelMutator/mutatorBlendAlphaMask.ts +6 -4
  25. package/src/History/PixelMutator/mutatorBlendBinaryMask.ts +6 -4
  26. package/src/History/PixelMutator/mutatorBlendColor.ts +2 -2
  27. package/src/History/PixelMutator/mutatorBlendColorPaintAlphaMask.ts +2 -1
  28. package/src/History/PixelMutator/mutatorBlendColorPaintBinaryMask.ts +2 -1
  29. package/src/History/PixelMutator/mutatorBlendColorPaintMask.ts +3 -1
  30. package/src/History/PixelMutator/mutatorBlendColorPaintRect.ts +3 -3
  31. package/src/History/PixelMutator/mutatorBlendMask.ts +6 -4
  32. package/src/History/PixelMutator/mutatorBlendPixelData.ts +5 -4
  33. package/src/History/PixelMutator/mutatorClear.ts +4 -3
  34. package/src/History/PixelMutator/mutatorFill.ts +5 -4
  35. package/src/History/PixelMutator/mutatorFillBinaryMask.ts +2 -1
  36. package/src/History/PixelMutator/mutatorInvert.ts +2 -2
  37. package/src/History/PixelMutator.ts +1 -1
  38. package/src/History/PixelPatchTiles.ts +7 -7
  39. package/src/History/PixelWriter.ts +12 -63
  40. package/src/ImageData/ImageDataLike.ts +1 -1
  41. package/src/ImageData/_ImageData-types.ts +13 -0
  42. package/src/ImageData/copyImageData.ts +1 -1
  43. package/src/ImageData/extractImageDataBuffer.ts +3 -2
  44. package/src/ImageData/imageDataToUint32Array.ts +18 -0
  45. package/src/ImageData/resampleImageData.ts +3 -3
  46. package/src/ImageData/resizeImageData.ts +1 -1
  47. package/src/ImageData/serialization.ts +1 -1
  48. package/src/ImageData/uInt32ArrayToImageData.ts +1 -1
  49. package/src/ImageData/writeImageData.ts +2 -2
  50. package/src/ImageData/writeImageDataBuffer.ts +2 -2
  51. package/src/IndexedImage/IndexedImage.ts +56 -98
  52. package/src/IndexedImage/_indexedImage-types.ts +18 -0
  53. package/src/IndexedImage/getIndexedImageColorCounts.ts +3 -3
  54. package/src/IndexedImage/indexedImageToAverageColor.ts +1 -1
  55. package/src/IndexedImage/indexedImageToImageData.ts +4 -6
  56. package/src/IndexedImage/resampleIndexedImage.ts +7 -15
  57. package/src/Input/fileToImageData.ts +1 -1
  58. package/src/Internal/_errors.ts +2 -0
  59. package/src/Internal/macros.ts +14 -0
  60. package/src/Mask/AlphaMask.ts +1 -1
  61. package/src/Mask/BinaryMask/makeBinaryMaskFromAlphaMask.ts +23 -0
  62. package/src/Mask/BinaryMask/makeBinaryMaskOutline.ts +88 -0
  63. package/src/Mask/BinaryMask/makeCircleBinaryMaskOutline.ts +104 -0
  64. package/src/Mask/BinaryMask/makeRectBinaryMaskOutline.ts +34 -0
  65. package/src/Mask/BinaryMask.ts +1 -1
  66. package/src/Mask/_mask-types.ts +73 -0
  67. package/src/Mask/applyBinaryMaskToAlphaMask.ts +2 -1
  68. package/src/Mask/copyMask.ts +1 -1
  69. package/src/Mask/extractMask.ts +2 -1
  70. package/src/Mask/extractMaskBuffer.ts +1 -1
  71. package/src/Mask/mergeAlphaMasks.ts +6 -3
  72. package/src/Mask/mergeBinaryMasks.ts +2 -1
  73. package/src/Mask/setMaskData.ts +1 -1
  74. package/src/MaskRect/merge2BinaryMaskRects.ts +2 -2
  75. package/src/MaskRect/mergeBinaryMaskRects.ts +1 -1
  76. package/src/MaskRect/subtractBinaryMaskRects.ts +1 -1
  77. package/src/Paint/AlphaMaskPaintBuffer.ts +339 -0
  78. package/src/Paint/AlphaMaskPaintBufferCanvasRenderer.ts +78 -0
  79. package/src/Paint/BinaryMaskPaintBuffer.ts +254 -0
  80. package/src/Paint/BinaryMaskPaintBufferCanvasRenderer.ts +67 -0
  81. package/src/Paint/{PaintBuffer.ts → ColorPaintBuffer.ts} +148 -77
  82. package/src/Paint/{PaintBufferCanvasRenderer.ts → ColorPaintBufferCanvasRenderer.ts} +6 -5
  83. package/src/Paint/PaintCursorRenderer.ts +117 -0
  84. package/src/Paint/_paint-types.ts +22 -0
  85. package/src/Paint/eachTileInBounds.ts +45 -0
  86. package/src/Paint/makeCirclePaintMask.ts +74 -0
  87. package/src/Paint/makePaintMask.ts +5 -2
  88. package/src/Paint/makeRectFalloffPaintAlphaMask.ts +4 -2
  89. package/src/PixelData/PixelData.ts +15 -19
  90. package/src/PixelData/ReusablePixelData.ts +36 -0
  91. package/src/PixelData/_pixelData-types.ts +17 -0
  92. package/src/PixelData/applyAlphaMaskToPixelData.ts +80 -43
  93. package/src/PixelData/applyBinaryMaskToPixelData.ts +10 -8
  94. package/src/PixelData/applyMaskToPixelData.ts +4 -9
  95. package/src/PixelData/blendColorPixelData.ts +9 -8
  96. package/src/PixelData/blendColorPixelDataAlphaMask.ts +9 -7
  97. package/src/PixelData/blendColorPixelDataBinaryMask.ts +9 -7
  98. package/src/PixelData/blendColorPixelDataMask.ts +4 -2
  99. package/src/PixelData/blendColorPixelDataPaintAlphaMask.ts +4 -2
  100. package/src/PixelData/blendColorPixelDataPaintBinaryMask.ts +4 -2
  101. package/src/PixelData/blendColorPixelDataPaintMask.ts +5 -2
  102. package/src/PixelData/blendPixel.ts +6 -5
  103. package/src/PixelData/blendPixelData.ts +14 -13
  104. package/src/PixelData/blendPixelDataAlphaMask.ts +15 -13
  105. package/src/PixelData/blendPixelDataBinaryMask.ts +15 -13
  106. package/src/PixelData/blendPixelDataMask.ts +5 -3
  107. package/src/PixelData/blendPixelDataPaintBuffer.ts +5 -4
  108. package/src/PixelData/clearPixelDataFast.ts +4 -2
  109. package/src/PixelData/copyPixelData.ts +14 -0
  110. package/src/PixelData/extractPixelData.ts +8 -7
  111. package/src/PixelData/extractPixelDataBuffer.ts +9 -8
  112. package/src/PixelData/fillPixelData.ts +16 -14
  113. package/src/PixelData/fillPixelDataBinaryMask.ts +10 -8
  114. package/src/PixelData/fillPixelDataFast.ts +16 -14
  115. package/src/PixelData/invertPixelData.ts +9 -8
  116. package/src/PixelData/pixelDataToAlphaMask.ts +9 -8
  117. package/src/PixelData/reflectPixelData.ts +9 -9
  118. package/src/PixelData/resamplePixelData.ts +20 -9
  119. package/src/PixelData/rotatePixelData.ts +8 -7
  120. package/src/PixelData/uInt32ArrayToPixelData.ts +15 -0
  121. package/src/PixelData/writePaintBufferToPixelData.ts +5 -5
  122. package/src/PixelData/writePixelDataBuffer.ts +10 -9
  123. package/src/Rect/_rect-types.ts +7 -0
  124. package/src/Rect/getRectsBounds.ts +1 -1
  125. package/src/Rect/trimMaskRectBounds.ts +2 -1
  126. package/src/Rect/trimRectBounds.ts +1 -1
  127. package/src/Tile/MaskTile.ts +40 -0
  128. package/src/Tile/PixelTile.ts +23 -0
  129. package/src/{PixelTile/PixelTilePool.ts → Tile/TilePool.ts} +9 -9
  130. package/src/Tile/_tile-types.ts +33 -0
  131. package/src/_errors.ts +1 -0
  132. package/src/_types.ts +2 -118
  133. package/src/index.ts +46 -21
  134. package/src/ImageData/imageDataToUInt32Array.ts +0 -13
  135. package/src/Internal/helpers.ts +0 -5
  136. package/src/Paint/makeCirclePaintAlphaMask.ts +0 -41
  137. package/src/Paint/makeCirclePaintBinaryMask.ts +0 -29
  138. package/src/PixelTile/PixelTile.ts +0 -21
  139. /package/src/{Internal → Rect}/resolveClipping.ts +0 -0
@@ -20,20 +20,22 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var src_exports = {};
22
22
  __export(src_exports, {
23
+ AlphaMaskPaintBuffer: () => AlphaMaskPaintBuffer,
23
24
  BASE_FAST_BLEND_MODE_FUNCTIONS: () => BASE_FAST_BLEND_MODE_FUNCTIONS,
24
25
  BASE_PERFECT_BLEND_MODE_FUNCTIONS: () => BASE_PERFECT_BLEND_MODE_FUNCTIONS,
25
26
  BaseBlendMode: () => BaseBlendMode,
27
+ BinaryMaskPaintBuffer: () => BinaryMaskPaintBuffer,
26
28
  CANVAS_COMPOSITE_MAP: () => CANVAS_COMPOSITE_MAP,
29
+ ColorPaintBuffer: () => ColorPaintBuffer,
30
+ ERRORS: () => errors_exports,
27
31
  HistoryManager: () => HistoryManager,
28
- IndexedImage: () => IndexedImage,
29
32
  MaskType: () => MaskType,
30
- PaintBuffer: () => PaintBuffer,
33
+ PaintMaskOutline: () => PaintMaskOutline,
31
34
  PixelAccumulator: () => PixelAccumulator,
32
- PixelData: () => PixelData,
33
35
  PixelEngineConfig: () => PixelEngineConfig,
34
- PixelTile: () => PixelTile,
35
- PixelTilePool: () => PixelTilePool,
36
36
  PixelWriter: () => PixelWriter,
37
+ TilePool: () => TilePool,
38
+ TileType: () => TileType,
37
39
  UnsupportedFormatError: () => UnsupportedFormatError,
38
40
  applyAlphaMaskToPixelData: () => applyAlphaMaskToPixelData,
39
41
  applyBinaryMaskToAlphaMask: () => applyBinaryMaskToAlphaMask,
@@ -66,6 +68,7 @@ __export(src_exports, {
66
68
  copyImageData: () => copyImageData,
67
69
  copyImageDataLike: () => copyImageDataLike,
68
70
  copyMask: () => copyMask,
71
+ copyPixelData: () => copyPixelData,
69
72
  darkenFast: () => darkenFast,
70
73
  darkenPerfect: () => darkenPerfect,
71
74
  darkerFast: () => darkerFast,
@@ -73,10 +76,19 @@ __export(src_exports, {
73
76
  deserializeImageData: () => deserializeImageData,
74
77
  deserializeNullableImageData: () => deserializeNullableImageData,
75
78
  deserializeRawImageData: () => deserializeRawImageData,
79
+ destinationAtopFast: () => destinationAtopFast,
80
+ destinationAtopPerfect: () => destinationAtopPerfect,
81
+ destinationInFast: () => destinationInFast,
82
+ destinationInPerfect: () => destinationInPerfect,
83
+ destinationOutFast: () => destinationOutFast,
84
+ destinationOutPerfect: () => destinationOutPerfect,
85
+ destinationOverFast: () => destinationOverFast,
86
+ destinationOverPerfect: () => destinationOverPerfect,
76
87
  differenceFast: () => differenceFast,
77
88
  differencePerfect: () => differencePerfect,
78
89
  divideFast: () => divideFast,
79
90
  dividePerfect: () => dividePerfect,
91
+ eachTileInBounds: () => eachTileInBounds,
80
92
  exclusionFast: () => exclusionFast,
81
93
  exclusionPerfect: () => exclusionPerfect,
82
94
  extractImageDataBuffer: () => extractImageDataBuffer,
@@ -92,6 +104,7 @@ __export(src_exports, {
92
104
  floodFillSelection: () => floodFillSelection,
93
105
  forEachLinePoint: () => forEachLinePoint,
94
106
  getImageDataFromClipboard: () => getImageDataFromClipboard,
107
+ getIndexedImageColor: () => getIndexedImageColor,
95
108
  getIndexedImageColorCounts: () => getIndexedImageColorCounts,
96
109
  getRectsBounds: () => getRectsBounds,
97
110
  getSupportedPixelFormats: () => getSupportedPixelFormats,
@@ -102,7 +115,7 @@ __export(src_exports, {
102
115
  imageDataToAlphaMaskBuffer: () => imageDataToAlphaMaskBuffer,
103
116
  imageDataToDataUrl: () => imageDataToDataUrl,
104
117
  imageDataToImgBlob: () => imageDataToImgBlob,
105
- imageDataToUInt32Array: () => imageDataToUInt32Array,
118
+ imageDataToUint32Array: () => imageDataToUint32Array,
106
119
  imgBlobToImageData: () => imgBlobToImageData,
107
120
  indexedImageToAverageColor: () => indexedImageToAverageColor,
108
121
  indexedImageToImageData: () => indexedImageToImageData,
@@ -123,26 +136,42 @@ __export(src_exports, {
123
136
  linearLightFast: () => linearLightFast,
124
137
  linearLightPerfect: () => linearLightPerfect,
125
138
  makeAlphaMask: () => makeAlphaMask,
139
+ makeAlphaMaskPaintBufferCanvasRenderer: () => makeAlphaMaskPaintBufferCanvasRenderer,
140
+ makeAlphaMaskTile: () => makeAlphaMaskTile,
126
141
  makeBinaryMask: () => makeBinaryMask,
142
+ makeBinaryMaskFromAlphaMask: () => makeBinaryMaskFromAlphaMask,
143
+ makeBinaryMaskOutline: () => makeBinaryMaskOutline,
144
+ makeBinaryMaskPaintBufferCanvasRenderer: () => makeBinaryMaskPaintBufferCanvasRenderer,
145
+ makeBinaryMaskTile: () => makeBinaryMaskTile,
127
146
  makeBlendModeRegistry: () => makeBlendModeRegistry,
128
147
  makeCanvasFrameRenderer: () => makeCanvasFrameRenderer,
148
+ makeCanvasPixelDataRenderer: () => makeCanvasPixelDataRenderer,
149
+ makeCircleBinaryMaskOutline: () => makeCircleBinaryMaskOutline,
129
150
  makeCirclePaintAlphaMask: () => makeCirclePaintAlphaMask,
130
151
  makeCirclePaintBinaryMask: () => makeCirclePaintBinaryMask,
131
152
  makeClippedBlit: () => makeClippedBlit,
132
153
  makeClippedRect: () => makeClippedRect,
154
+ makeColorPaintBufferCanvasRenderer: () => makeColorPaintBufferCanvasRenderer,
133
155
  makeFastBlendModeRegistry: () => makeFastBlendModeRegistry,
134
156
  makeFullPixelMutator: () => makeFullPixelMutator,
135
157
  makeHistoryAction: () => makeHistoryAction,
136
158
  makeImageDataLike: () => makeImageDataLike,
159
+ makeIndexedImage: () => makeIndexedImage,
160
+ makeIndexedImageFromImageData: () => makeIndexedImageFromImageData,
161
+ makeIndexedImageFromImageDataRaw: () => makeIndexedImageFromImageDataRaw,
137
162
  makePaintAlphaMask: () => makePaintAlphaMask,
138
163
  makePaintBinaryMask: () => makePaintBinaryMask,
139
- makePaintBufferCanvasRenderer: () => makePaintBufferCanvasRenderer,
164
+ makePaintCursorRenderer: () => makePaintCursorRenderer,
140
165
  makePerfectBlendModeRegistry: () => makePerfectBlendModeRegistry,
141
166
  makePixelCanvas: () => makePixelCanvas,
167
+ makePixelData: () => makePixelData,
168
+ makePixelTile: () => makePixelTile,
169
+ makeRectBinaryMaskOutline: () => makeRectBinaryMaskOutline,
142
170
  makeRectFalloffPaintAlphaMask: () => makeRectFalloffPaintAlphaMask,
143
171
  makeReusableCanvas: () => makeReusableCanvas,
144
172
  makeReusableImageData: () => makeReusableImageData,
145
173
  makeReusableOffscreenCanvas: () => makeReusableOffscreenCanvas,
174
+ makeReusablePixelData: () => makeReusablePixelData,
146
175
  merge2BinaryMaskRects: () => merge2BinaryMaskRects,
147
176
  mergeAlphaMasks: () => mergeAlphaMasks,
148
177
  mergeBinaryMaskRects: () => mergeBinaryMaskRects,
@@ -179,10 +208,11 @@ __export(src_exports, {
179
208
  pixelDataToAlphaMask: () => pixelDataToAlphaMask,
180
209
  reflectPixelDataHorizontal: () => reflectPixelDataHorizontal,
181
210
  reflectPixelDataVertical: () => reflectPixelDataVertical,
182
- resample32: () => resample32,
183
211
  resampleImageData: () => resampleImageData,
184
212
  resampleIndexedImage: () => resampleIndexedImage,
185
213
  resamplePixelData: () => resamplePixelData,
214
+ resamplePixelDataInPlace: () => resamplePixelDataInPlace,
215
+ resampleUint32Array: () => resampleUint32Array,
186
216
  resizeImageData: () => resizeImageData,
187
217
  resolveBlitClipping: () => resolveBlitClipping,
188
218
  resolveRectClipping: () => resolveRectClipping,
@@ -192,8 +222,15 @@ __export(src_exports, {
192
222
  serializeImageData: () => serializeImageData,
193
223
  serializeNullableImageData: () => serializeNullableImageData,
194
224
  setMaskData: () => setMaskData,
225
+ setPixelData: () => setPixelData,
195
226
  softLightFast: () => softLightFast,
196
227
  softLightPerfect: () => softLightPerfect,
228
+ sourceAtopFast: () => sourceAtopFast,
229
+ sourceAtopPerfect: () => sourceAtopPerfect,
230
+ sourceInFast: () => sourceInFast,
231
+ sourceInPerfect: () => sourceInPerfect,
232
+ sourceOutFast: () => sourceOutFast,
233
+ sourceOutPerfect: () => sourceOutPerfect,
197
234
  sourceOverFast: () => sourceOverFast,
198
235
  sourceOverPerfect: () => sourceOverPerfect,
199
236
  subtractBinaryMaskRects: () => subtractBinaryMaskRects,
@@ -204,6 +241,7 @@ __export(src_exports, {
204
241
  trimRectBounds: () => trimRectBounds,
205
242
  uInt32ArrayToImageData: () => uInt32ArrayToImageData,
206
243
  uInt32ArrayToImageDataLike: () => uInt32ArrayToImageDataLike,
244
+ uInt32ArrayToPixelData: () => uInt32ArrayToPixelData,
207
245
  unpackAlpha: () => unpackAlpha,
208
246
  unpackBlue: () => unpackBlue,
209
247
  unpackColor: () => unpackColor,
@@ -217,16 +255,20 @@ __export(src_exports, {
217
255
  writeImageDataToClipboard: () => writeImageDataToClipboard,
218
256
  writeImgBlobToClipboard: () => writeImgBlobToClipboard,
219
257
  writePaintBufferToPixelData: () => writePaintBufferToPixelData,
220
- writePixelDataBuffer: () => writePixelDataBuffer
258
+ writePixelDataBuffer: () => writePixelDataBuffer,
259
+ xorFast: () => xorFast,
260
+ xorPerfect: () => xorPerfect
221
261
  });
222
262
  module.exports = __toCommonJS(src_exports);
223
263
 
224
- // src/_types.ts
225
- var MaskType = /* @__PURE__ */ ((MaskType2) => {
226
- MaskType2[MaskType2["ALPHA"] = 0] = "ALPHA";
227
- MaskType2[MaskType2["BINARY"] = 1] = "BINARY";
228
- return MaskType2;
229
- })(MaskType || {});
264
+ // src/Internal/_errors.ts
265
+ var errors_exports = {};
266
+ __export(errors_exports, {
267
+ CANVAS_CTX_FAILED: () => CANVAS_CTX_FAILED,
268
+ OFFSCREEN_CANVAS_CTX_FAILED: () => OFFSCREEN_CANVAS_CTX_FAILED
269
+ });
270
+ var OFFSCREEN_CANVAS_CTX_FAILED = "Failed to create OffscreenCanvas context";
271
+ var CANVAS_CTX_FAILED = "Failed to create Canvas context";
230
272
 
231
273
  // src/color.ts
232
274
  function packColor(r, g, b, a) {
@@ -301,7 +343,7 @@ function color32ToCssRGBA(color) {
301
343
  return `rgba(${r},${g},${b},${alpha})`;
302
344
  }
303
345
 
304
- // src/Internal/resolveClipping.ts
346
+ // src/Rect/resolveClipping.ts
305
347
  var makeClippedRect = () => ({
306
348
  x: 0,
307
349
  y: 0,
@@ -419,6 +461,13 @@ function extractImageDataBuffer(imageData, _x, _y, _w, _h) {
419
461
  return out;
420
462
  }
421
463
 
464
+ // src/Mask/_mask-types.ts
465
+ var MaskType = /* @__PURE__ */ ((MaskType2) => {
466
+ MaskType2[MaskType2["ALPHA"] = 0] = "ALPHA";
467
+ MaskType2[MaskType2["BINARY"] = 1] = "BINARY";
468
+ return MaskType2;
469
+ })(MaskType || {});
470
+
422
471
  // src/Mask/extractMaskBuffer.ts
423
472
  function extractMaskBuffer(maskBuffer, maskWidth, xOrRect, y, w, h) {
424
473
  let finalX;
@@ -521,9 +570,9 @@ function trimMaskRectBounds(target, bounds) {
521
570
 
522
571
  // src/Algorithm/floodFillSelection.ts
523
572
  function floodFillSelection(target, startX, startY, contiguous = true, tolerance = 0, bounds, out) {
524
- const data32 = target.data32;
525
- const width = target.width;
526
- const height = target.height;
573
+ const data32 = target.data;
574
+ const width = target.w;
575
+ const height = target.h;
527
576
  const lx = bounds?.x ?? 0;
528
577
  const ly = bounds?.y ?? 0;
529
578
  const lw = bounds?.w ?? width;
@@ -637,13 +686,13 @@ function floodFillSelection(target, startX, startY, contiguous = true, tolerance
637
686
 
638
687
  // src/Algorithm/forEachLinePoint.ts
639
688
  function forEachLinePoint(x0, y0, x1, y1, callback) {
640
- const dx = x1 - x0;
641
- const dy = y1 - y0;
642
- const steps = Math.max(Math.abs(dx), Math.abs(dy));
643
- if (steps === 0) {
689
+ if (x0 === x1 && y0 === y1) {
644
690
  callback(x0, y0);
645
691
  return;
646
692
  }
693
+ const dx = x1 - x0;
694
+ const dy = y1 - y0;
695
+ const steps = Math.max(Math.abs(dx), Math.abs(dy));
647
696
  const xInc = dx / steps;
648
697
  const yInc = dy / steps;
649
698
  let curX = x0;
@@ -655,6 +704,66 @@ function forEachLinePoint(x0, y0, x1, y1, callback) {
655
704
  }
656
705
  }
657
706
 
707
+ // src/Algorithm/resampleUint32Array.ts
708
+ function resampleUint32Array(srcData32, srcW, srcH, factor, out) {
709
+ const dstW = Math.max(1, srcW * factor | 0);
710
+ const dstH = Math.max(1, srcH * factor | 0);
711
+ const dstData = new Uint32Array(dstW * dstH);
712
+ const scaleX = srcW / dstW;
713
+ const scaleY = srcH / dstH;
714
+ for (let y = 0; y < dstH; y++) {
715
+ const srcY = Math.min(srcH - 1, y * scaleY | 0);
716
+ const srcRowOffset = srcY * srcW;
717
+ const dstRowOffset = y * dstW;
718
+ for (let x = 0; x < dstW; x++) {
719
+ const srcX = Math.min(srcW - 1, x * scaleX | 0);
720
+ dstData[dstRowOffset + x] = srcData32[srcRowOffset + srcX];
721
+ }
722
+ }
723
+ out = out ?? {};
724
+ out.data = dstData;
725
+ out.w = dstW;
726
+ out.h = dstH;
727
+ return out;
728
+ }
729
+
730
+ // src/BlendModes/blend-modes.ts
731
+ var BaseBlendMode = {
732
+ overwrite: 0,
733
+ sourceOver: 1,
734
+ darken: 2,
735
+ multiply: 3,
736
+ colorBurn: 4,
737
+ linearBurn: 5,
738
+ darkerColor: 6,
739
+ lighten: 7,
740
+ screen: 8,
741
+ colorDodge: 9,
742
+ linearDodge: 10,
743
+ lighterColor: 11,
744
+ overlay: 12,
745
+ softLight: 13,
746
+ hardLight: 14,
747
+ vividLight: 15,
748
+ linearLight: 16,
749
+ pinLight: 17,
750
+ hardMix: 18,
751
+ difference: 19,
752
+ exclusion: 20,
753
+ subtract: 21,
754
+ divide: 22,
755
+ sourceIn: 23,
756
+ sourceOut: 24,
757
+ sourceAtop: 25,
758
+ destinationOver: 26,
759
+ destinationIn: 27,
760
+ destinationOut: 28,
761
+ destinationAtop: 29,
762
+ xor: 30
763
+ };
764
+ var overwriteBase = (src, _dst) => src;
765
+ overwriteBase.isOverwrite = true;
766
+
658
767
  // src/BlendModes/BlendModeRegistry.ts
659
768
  function makeBlendModeRegistry(blendModes, initialEntries, registryName = "anonymous") {
660
769
  const blendToName = /* @__PURE__ */ new Map();
@@ -694,37 +803,134 @@ function makeBlendModeRegistry(blendModes, initialEntries, registryName = "anony
694
803
  };
695
804
  }
696
805
 
697
- // src/BlendModes/blend-modes.ts
698
- var BaseBlendMode = {
699
- overwrite: 0,
700
- sourceOver: 1,
701
- darken: 2,
702
- multiply: 3,
703
- colorBurn: 4,
704
- linearBurn: 5,
705
- darkerColor: 6,
706
- lighten: 7,
707
- screen: 8,
708
- colorDodge: 9,
709
- linearDodge: 10,
710
- lighterColor: 11,
711
- overlay: 12,
712
- softLight: 13,
713
- hardLight: 14,
714
- vividLight: 15,
715
- linearLight: 16,
716
- pinLight: 17,
717
- hardMix: 18,
718
- difference: 19,
719
- exclusion: 20,
720
- subtract: 21,
721
- divide: 22
722
- };
723
- var overwriteBase = (src, _dst) => src;
724
- overwriteBase.isOverwrite = true;
725
-
726
806
  // src/BlendModes/blend-modes-fast.ts
727
807
  var overwriteFast = overwriteBase;
808
+ var sourceInFast = (src, dst) => {
809
+ const da = dst >>> 24 & 255;
810
+ if (da === 0) return 0;
811
+ if (da === 255) return src;
812
+ const sa = src >>> 24 & 255;
813
+ const sr = src & 255;
814
+ const sg = src >>> 8 & 255;
815
+ const sb = src >>> 16 & 255;
816
+ const r = sr * da >> 8;
817
+ const g = sg * da >> 8;
818
+ const b = sb * da >> 8;
819
+ const a = sa * da >> 8;
820
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
821
+ };
822
+ var sourceOutFast = (src, dst) => {
823
+ const da = dst >>> 24 & 255;
824
+ if (da === 255) return 0;
825
+ if (da === 0) return src;
826
+ const sa = src >>> 24 & 255;
827
+ const sr = src & 255;
828
+ const sg = src >>> 8 & 255;
829
+ const sb = src >>> 16 & 255;
830
+ const invDa = 255 - da;
831
+ const r = sr * invDa >> 8;
832
+ const g = sg * invDa >> 8;
833
+ const b = sb * invDa >> 8;
834
+ const a = sa * invDa >> 8;
835
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
836
+ };
837
+ var sourceAtopFast = (src, dst) => {
838
+ const sa = src >>> 24 & 255;
839
+ const da = dst >>> 24 & 255;
840
+ if (da === 0) return 0;
841
+ const sr = src & 255;
842
+ const sg = src >>> 8 & 255;
843
+ const sb = src >>> 16 & 255;
844
+ const dr = dst & 255;
845
+ const dg = dst >>> 8 & 255;
846
+ const db = dst >>> 16 & 255;
847
+ const invSa = 255 - sa;
848
+ const r = sr * da + dr * invSa >> 8;
849
+ const g = sg * da + dg * invSa >> 8;
850
+ const b = sb * da + db * invSa >> 8;
851
+ return (da << 24 | b << 16 | g << 8 | r) >>> 0;
852
+ };
853
+ var destinationOverFast = (src, dst) => {
854
+ const da = dst >>> 24 & 255;
855
+ if (da === 255) return dst;
856
+ if (da === 0) return src;
857
+ const sa = src >>> 24 & 255;
858
+ const sr = src & 255;
859
+ const sg = src >>> 8 & 255;
860
+ const sb = src >>> 16 & 255;
861
+ const dr = dst & 255;
862
+ const dg = dst >>> 8 & 255;
863
+ const db = dst >>> 16 & 255;
864
+ const invDa = 255 - da;
865
+ const r = dr * 255 + sr * invDa >> 8;
866
+ const g = dg * 255 + sg * invDa >> 8;
867
+ const b = db * 255 + sb * invDa >> 8;
868
+ const a = da * 255 + sa * invDa >> 8;
869
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
870
+ };
871
+ var destinationInFast = (src, dst) => {
872
+ const sa = src >>> 24 & 255;
873
+ if (sa === 0) return 0;
874
+ if (sa === 255) return dst;
875
+ const da = dst >>> 24 & 255;
876
+ const dr = dst & 255;
877
+ const dg = dst >>> 8 & 255;
878
+ const db = dst >>> 16 & 255;
879
+ const r = dr * sa >> 8;
880
+ const g = dg * sa >> 8;
881
+ const b = db * sa >> 8;
882
+ const a = da * sa >> 8;
883
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
884
+ };
885
+ var destinationOutFast = (src, dst) => {
886
+ const sa = src >>> 24 & 255;
887
+ if (sa === 255) return 0;
888
+ if (sa === 0) return dst;
889
+ const da = dst >>> 24 & 255;
890
+ const dr = dst & 255;
891
+ const dg = dst >>> 8 & 255;
892
+ const db = dst >>> 16 & 255;
893
+ const invSa = 255 - sa;
894
+ const r = dr * invSa >> 8;
895
+ const g = dg * invSa >> 8;
896
+ const b = db * invSa >> 8;
897
+ const a = da * invSa >> 8;
898
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
899
+ };
900
+ var destinationAtopFast = (src, dst) => {
901
+ const sa = src >>> 24 & 255;
902
+ if (sa === 0) return 0;
903
+ const da = dst >>> 24 & 255;
904
+ if (da === 0) return 0;
905
+ const sr = src & 255;
906
+ const sg = src >>> 8 & 255;
907
+ const sb = src >>> 16 & 255;
908
+ const dr = dst & 255;
909
+ const dg = dst >>> 8 & 255;
910
+ const db = dst >>> 16 & 255;
911
+ const invDa = 255 - da;
912
+ const r = dr * sa + sr * invDa >> 8;
913
+ const g = dg * sa + sg * invDa >> 8;
914
+ const b = db * sa + sb * invDa >> 8;
915
+ return (sa << 24 | b << 16 | g << 8 | r) >>> 0;
916
+ };
917
+ var xorFast = (src, dst) => {
918
+ const sa = src >>> 24 & 255;
919
+ const da = dst >>> 24 & 255;
920
+ const sr = src & 255;
921
+ const sg = src >>> 8 & 255;
922
+ const sb = src >>> 16 & 255;
923
+ const dr = dst & 255;
924
+ const dg = dst >>> 8 & 255;
925
+ const db = dst >>> 16 & 255;
926
+ const invDa = 255 - da;
927
+ const invSa = 255 - sa;
928
+ const r = sr * invDa + dr * invSa >> 8;
929
+ const g = sg * invDa + dg * invSa >> 8;
930
+ const b = sb * invDa + db * invSa >> 8;
931
+ const a = sa * invDa + da * invSa >> 8;
932
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
933
+ };
728
934
  var sourceOverFast = (src, dst) => {
729
935
  const sa = src >>> 24 & 255;
730
936
  if (sa === 255) return src;
@@ -1110,6 +1316,14 @@ var divideFast = (src, dst) => {
1110
1316
  };
1111
1317
  var BASE_FAST_BLEND_MODE_FUNCTIONS = {
1112
1318
  [BaseBlendMode.overwrite]: overwriteFast,
1319
+ [BaseBlendMode.sourceIn]: sourceInFast,
1320
+ [BaseBlendMode.sourceOut]: sourceOutFast,
1321
+ [BaseBlendMode.sourceAtop]: sourceAtopFast,
1322
+ [BaseBlendMode.destinationOver]: destinationOverFast,
1323
+ [BaseBlendMode.destinationIn]: destinationInFast,
1324
+ [BaseBlendMode.destinationOut]: destinationOutFast,
1325
+ [BaseBlendMode.destinationAtop]: destinationAtopFast,
1326
+ [BaseBlendMode.xor]: xorFast,
1113
1327
  [BaseBlendMode.sourceOver]: sourceOverFast,
1114
1328
  [BaseBlendMode.darken]: darkenFast,
1115
1329
  [BaseBlendMode.multiply]: multiplyFast,
@@ -1139,118 +1353,274 @@ function makeFastBlendModeRegistry(name = "fast") {
1139
1353
 
1140
1354
  // src/BlendModes/blend-modes-perfect.ts
1141
1355
  var overwritePerfect = overwriteBase;
1142
- var sourceOverPerfect = (src, dst) => {
1143
- const sa = src >>> 24 & 255;
1144
- if (sa === 255) return src;
1145
- if (sa === 0) return dst;
1356
+ var sourceInPerfect = (src, dst) => {
1146
1357
  const da = dst >>> 24 & 255;
1147
- if (da === 0) return src;
1148
- const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
1149
- const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
1150
- const invA = 255 - sa;
1151
- const tR = sr * sa + dr * invA;
1358
+ if (da === 0) return 0;
1359
+ if (da === 255) return src;
1360
+ const sa = src >>> 24 & 255;
1361
+ const sr = src & 255;
1362
+ const sg = src >>> 8 & 255;
1363
+ const sb = src >>> 16 & 255;
1364
+ const tR = sr * da;
1152
1365
  const r = tR + 1 + (tR >> 8) >> 8;
1153
- const tG = sg * sa + dg * invA;
1366
+ const tG = sg * da;
1154
1367
  const g = tG + 1 + (tG >> 8) >> 8;
1155
- const tB = sb * sa + db * invA;
1368
+ const tB = sb * da;
1156
1369
  const b = tB + 1 + (tB >> 8) >> 8;
1157
- const tA = 255 * sa + da * invA;
1370
+ const tA = sa * da;
1158
1371
  const a = tA + 1 + (tA >> 8) >> 8;
1159
1372
  return (a << 24 | b << 16 | g << 8 | r) >>> 0;
1160
1373
  };
1161
- var darkenPerfect = (src, dst) => {
1162
- const sa = src >>> 24 & 255;
1163
- if (sa === 0) return dst;
1164
- const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
1165
- const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
1166
- const br = sr < dr ? sr : dr;
1167
- const bg = sg < dg ? sg : dg;
1168
- const bb = sb < db ? sb : db;
1169
- if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
1170
- const invA = 255 - sa;
1374
+ var sourceOutPerfect = (src, dst) => {
1171
1375
  const da = dst >>> 24 & 255;
1172
- const tR = br * sa + dr * invA;
1376
+ if (da === 255) return 0;
1377
+ if (da === 0) return src;
1378
+ const sa = src >>> 24 & 255;
1379
+ const sr = src & 255;
1380
+ const sg = src >>> 8 & 255;
1381
+ const sb = src >>> 16 & 255;
1382
+ const invDa = 255 - da;
1383
+ const tR = sr * invDa;
1173
1384
  const r = tR + 1 + (tR >> 8) >> 8;
1174
- const tG = bg * sa + dg * invA;
1385
+ const tG = sg * invDa;
1175
1386
  const g = tG + 1 + (tG >> 8) >> 8;
1176
- const tB = bb * sa + db * invA;
1387
+ const tB = sb * invDa;
1177
1388
  const b = tB + 1 + (tB >> 8) >> 8;
1178
- const tA = 255 * sa + da * invA;
1389
+ const tA = sa * invDa;
1179
1390
  const a = tA + 1 + (tA >> 8) >> 8;
1180
1391
  return (a << 24 | b << 16 | g << 8 | r) >>> 0;
1181
1392
  };
1182
- var multiplyPerfect = (src, dst) => {
1393
+ var sourceAtopPerfect = (src, dst) => {
1183
1394
  const sa = src >>> 24 & 255;
1184
- if (sa === 0) return dst;
1395
+ const da = dst >>> 24 & 255;
1396
+ if (da === 0) return 0;
1397
+ const sr = src & 255;
1398
+ const sg = src >>> 8 & 255;
1399
+ const sb = src >>> 16 & 255;
1185
1400
  const dr = dst & 255;
1186
1401
  const dg = dst >>> 8 & 255;
1187
1402
  const db = dst >>> 16 & 255;
1403
+ const invSa = 255 - sa;
1404
+ const tR = sr * da + dr * invSa;
1405
+ const r = tR + 1 + (tR >> 8) >> 8;
1406
+ const tG = sg * da + dg * invSa;
1407
+ const g = tG + 1 + (tG >> 8) >> 8;
1408
+ const tB = sb * da + db * invSa;
1409
+ const b = tB + 1 + (tB >> 8) >> 8;
1410
+ return (da << 24 | b << 16 | g << 8 | r) >>> 0;
1411
+ };
1412
+ var destinationOverPerfect = (src, dst) => {
1188
1413
  const da = dst >>> 24 & 255;
1414
+ if (da === 255) return dst;
1415
+ if (da === 0) return src;
1416
+ const sa = src >>> 24 & 255;
1189
1417
  const sr = src & 255;
1190
1418
  const sg = src >>> 8 & 255;
1191
1419
  const sb = src >>> 16 & 255;
1192
- const mR = sr * dr;
1193
- const br = mR + 1 + (mR >> 8) >> 8;
1194
- const mG = sg * dg;
1195
- const bg = mG + 1 + (mG >> 8) >> 8;
1196
- const mB = sb * db;
1197
- const bb = mB + 1 + (mB >> 8) >> 8;
1198
- if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
1199
- const invA = 255 - sa;
1200
- const tR = br * sa + dr * invA;
1420
+ const dr = dst & 255;
1421
+ const dg = dst >>> 8 & 255;
1422
+ const db = dst >>> 16 & 255;
1423
+ const invDa = 255 - da;
1424
+ const tR = dr * 255 + sr * invDa;
1201
1425
  const r = tR + 1 + (tR >> 8) >> 8;
1202
- const tG = bg * sa + dg * invA;
1426
+ const tG = dg * 255 + sg * invDa;
1203
1427
  const g = tG + 1 + (tG >> 8) >> 8;
1204
- const tB = bb * sa + db * invA;
1428
+ const tB = db * 255 + sb * invDa;
1205
1429
  const b = tB + 1 + (tB >> 8) >> 8;
1206
- const tA = 255 * sa + da * invA;
1430
+ const tA = da * 255 + sa * invDa;
1207
1431
  const a = tA + 1 + (tA >> 8) >> 8;
1208
1432
  return (a << 24 | b << 16 | g << 8 | r) >>> 0;
1209
1433
  };
1210
- var colorBurnPerfect = (src, dst) => {
1434
+ var destinationInPerfect = (src, dst) => {
1211
1435
  const sa = src >>> 24 & 255;
1212
- if (sa === 0) return dst;
1436
+ if (sa === 0) return 0;
1437
+ if (sa === 255) return dst;
1438
+ const da = dst >>> 24 & 255;
1213
1439
  const dr = dst & 255;
1214
1440
  const dg = dst >>> 8 & 255;
1215
1441
  const db = dst >>> 16 & 255;
1216
- const sr = src & 255;
1217
- const sg = src >>> 8 & 255;
1218
- const sb = src >>> 16 & 255;
1219
- const resR = dr === 255 ? 255 : sr === 0 ? 0 : 255 - ((255 - dr) * 255 / sr | 0);
1220
- const br = resR < 0 ? 0 : resR;
1221
- const resG = dg === 255 ? 255 : sg === 0 ? 0 : 255 - ((255 - dg) * 255 / sg | 0);
1222
- const bg = resG < 0 ? 0 : resG;
1223
- const resB = db === 255 ? 255 : sb === 0 ? 0 : 255 - ((255 - db) * 255 / sb | 0);
1224
- const bb = resB < 0 ? 0 : resB;
1225
- if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
1226
- const invA = 255 - sa;
1227
- const da = dst >>> 24 & 255;
1228
- const tR = br * sa + dr * invA;
1442
+ const tR = dr * sa;
1229
1443
  const r = tR + 1 + (tR >> 8) >> 8;
1230
- const tG = bg * sa + dg * invA;
1444
+ const tG = dg * sa;
1231
1445
  const g = tG + 1 + (tG >> 8) >> 8;
1232
- const tB = bb * sa + db * invA;
1446
+ const tB = db * sa;
1233
1447
  const b = tB + 1 + (tB >> 8) >> 8;
1234
- const tA = 255 * sa + da * invA;
1448
+ const tA = da * sa;
1235
1449
  const a = tA + 1 + (tA >> 8) >> 8;
1236
1450
  return (a << 24 | b << 16 | g << 8 | r) >>> 0;
1237
1451
  };
1238
- var linearBurnPerfect = (src, dst) => {
1452
+ var destinationOutPerfect = (src, dst) => {
1239
1453
  const sa = src >>> 24 & 255;
1454
+ if (sa === 255) return 0;
1240
1455
  if (sa === 0) return dst;
1241
- const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
1242
- const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
1243
- const brU = dr + sr - 255;
1244
- const br = brU < 0 ? 0 : brU;
1245
- const bgU = dg + sg - 255;
1246
- const bg = bgU < 0 ? 0 : bgU;
1247
- const bbU = db + sb - 255;
1248
- const bb = bbU < 0 ? 0 : bbU;
1249
- if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
1250
- const invA = 255 - sa;
1251
1456
  const da = dst >>> 24 & 255;
1252
- const tR = br * sa + dr * invA;
1253
- const r = tR + 1 + (tR >> 8) >> 8;
1457
+ const dr = dst & 255;
1458
+ const dg = dst >>> 8 & 255;
1459
+ const db = dst >>> 16 & 255;
1460
+ const invSa = 255 - sa;
1461
+ const tR = dr * invSa;
1462
+ const r = tR + 1 + (tR >> 8) >> 8;
1463
+ const tG = dg * invSa;
1464
+ const g = tG + 1 + (tG >> 8) >> 8;
1465
+ const tB = db * invSa;
1466
+ const b = tB + 1 + (tB >> 8) >> 8;
1467
+ const tA = da * invSa;
1468
+ const a = tA + 1 + (tA >> 8) >> 8;
1469
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
1470
+ };
1471
+ var destinationAtopPerfect = (src, dst) => {
1472
+ const sa = src >>> 24 & 255;
1473
+ if (sa === 0) return 0;
1474
+ const da = dst >>> 24 & 255;
1475
+ if (da === 0) return 0;
1476
+ const sr = src & 255;
1477
+ const sg = src >>> 8 & 255;
1478
+ const sb = src >>> 16 & 255;
1479
+ const dr = dst & 255;
1480
+ const dg = dst >>> 8 & 255;
1481
+ const db = dst >>> 16 & 255;
1482
+ const invDa = 255 - da;
1483
+ const tR = dr * sa + sr * invDa;
1484
+ const r = tR + 1 + (tR >> 8) >> 8;
1485
+ const tG = dg * sa + sg * invDa;
1486
+ const g = tG + 1 + (tG >> 8) >> 8;
1487
+ const tB = db * sa + sb * invDa;
1488
+ const b = tB + 1 + (tB >> 8) >> 8;
1489
+ return (sa << 24 | b << 16 | g << 8 | r) >>> 0;
1490
+ };
1491
+ var xorPerfect = (src, dst) => {
1492
+ const sa = src >>> 24 & 255;
1493
+ const da = dst >>> 24 & 255;
1494
+ const sr = src & 255;
1495
+ const sg = src >>> 8 & 255;
1496
+ const sb = src >>> 16 & 255;
1497
+ const dr = dst & 255;
1498
+ const dg = dst >>> 8 & 255;
1499
+ const db = dst >>> 16 & 255;
1500
+ const invDa = 255 - da;
1501
+ const invSa = 255 - sa;
1502
+ const tR = sr * invDa + dr * invSa;
1503
+ const r = tR + 1 + (tR >> 8) >> 8;
1504
+ const tG = sg * invDa + dg * invSa;
1505
+ const g = tG + 1 + (tG >> 8) >> 8;
1506
+ const tB = sb * invDa + db * invSa;
1507
+ const b = tB + 1 + (tB >> 8) >> 8;
1508
+ const tA = sa * invDa + da * invSa;
1509
+ const a = tA + 1 + (tA >> 8) >> 8;
1510
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
1511
+ };
1512
+ var sourceOverPerfect = (src, dst) => {
1513
+ const sa = src >>> 24 & 255;
1514
+ if (sa === 255) return src;
1515
+ if (sa === 0) return dst;
1516
+ const da = dst >>> 24 & 255;
1517
+ if (da === 0) return src;
1518
+ const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
1519
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
1520
+ const invA = 255 - sa;
1521
+ const tR = sr * sa + dr * invA;
1522
+ const r = tR + 1 + (tR >> 8) >> 8;
1523
+ const tG = sg * sa + dg * invA;
1524
+ const g = tG + 1 + (tG >> 8) >> 8;
1525
+ const tB = sb * sa + db * invA;
1526
+ const b = tB + 1 + (tB >> 8) >> 8;
1527
+ const tA = 255 * sa + da * invA;
1528
+ const a = tA + 1 + (tA >> 8) >> 8;
1529
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
1530
+ };
1531
+ var darkenPerfect = (src, dst) => {
1532
+ const sa = src >>> 24 & 255;
1533
+ if (sa === 0) return dst;
1534
+ const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
1535
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
1536
+ const br = sr < dr ? sr : dr;
1537
+ const bg = sg < dg ? sg : dg;
1538
+ const bb = sb < db ? sb : db;
1539
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
1540
+ const invA = 255 - sa;
1541
+ const da = dst >>> 24 & 255;
1542
+ const tR = br * sa + dr * invA;
1543
+ const r = tR + 1 + (tR >> 8) >> 8;
1544
+ const tG = bg * sa + dg * invA;
1545
+ const g = tG + 1 + (tG >> 8) >> 8;
1546
+ const tB = bb * sa + db * invA;
1547
+ const b = tB + 1 + (tB >> 8) >> 8;
1548
+ const tA = 255 * sa + da * invA;
1549
+ const a = tA + 1 + (tA >> 8) >> 8;
1550
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
1551
+ };
1552
+ var multiplyPerfect = (src, dst) => {
1553
+ const sa = src >>> 24 & 255;
1554
+ if (sa === 0) return dst;
1555
+ const dr = dst & 255;
1556
+ const dg = dst >>> 8 & 255;
1557
+ const db = dst >>> 16 & 255;
1558
+ const da = dst >>> 24 & 255;
1559
+ const sr = src & 255;
1560
+ const sg = src >>> 8 & 255;
1561
+ const sb = src >>> 16 & 255;
1562
+ const mR = sr * dr;
1563
+ const br = mR + 1 + (mR >> 8) >> 8;
1564
+ const mG = sg * dg;
1565
+ const bg = mG + 1 + (mG >> 8) >> 8;
1566
+ const mB = sb * db;
1567
+ const bb = mB + 1 + (mB >> 8) >> 8;
1568
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
1569
+ const invA = 255 - sa;
1570
+ const tR = br * sa + dr * invA;
1571
+ const r = tR + 1 + (tR >> 8) >> 8;
1572
+ const tG = bg * sa + dg * invA;
1573
+ const g = tG + 1 + (tG >> 8) >> 8;
1574
+ const tB = bb * sa + db * invA;
1575
+ const b = tB + 1 + (tB >> 8) >> 8;
1576
+ const tA = 255 * sa + da * invA;
1577
+ const a = tA + 1 + (tA >> 8) >> 8;
1578
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
1579
+ };
1580
+ var colorBurnPerfect = (src, dst) => {
1581
+ const sa = src >>> 24 & 255;
1582
+ if (sa === 0) return dst;
1583
+ const dr = dst & 255;
1584
+ const dg = dst >>> 8 & 255;
1585
+ const db = dst >>> 16 & 255;
1586
+ const sr = src & 255;
1587
+ const sg = src >>> 8 & 255;
1588
+ const sb = src >>> 16 & 255;
1589
+ const resR = dr === 255 ? 255 : sr === 0 ? 0 : 255 - ((255 - dr) * 255 / sr | 0);
1590
+ const br = resR < 0 ? 0 : resR;
1591
+ const resG = dg === 255 ? 255 : sg === 0 ? 0 : 255 - ((255 - dg) * 255 / sg | 0);
1592
+ const bg = resG < 0 ? 0 : resG;
1593
+ const resB = db === 255 ? 255 : sb === 0 ? 0 : 255 - ((255 - db) * 255 / sb | 0);
1594
+ const bb = resB < 0 ? 0 : resB;
1595
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
1596
+ const invA = 255 - sa;
1597
+ const da = dst >>> 24 & 255;
1598
+ const tR = br * sa + dr * invA;
1599
+ const r = tR + 1 + (tR >> 8) >> 8;
1600
+ const tG = bg * sa + dg * invA;
1601
+ const g = tG + 1 + (tG >> 8) >> 8;
1602
+ const tB = bb * sa + db * invA;
1603
+ const b = tB + 1 + (tB >> 8) >> 8;
1604
+ const tA = 255 * sa + da * invA;
1605
+ const a = tA + 1 + (tA >> 8) >> 8;
1606
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
1607
+ };
1608
+ var linearBurnPerfect = (src, dst) => {
1609
+ const sa = src >>> 24 & 255;
1610
+ if (sa === 0) return dst;
1611
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
1612
+ const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
1613
+ const brU = dr + sr - 255;
1614
+ const br = brU < 0 ? 0 : brU;
1615
+ const bgU = dg + sg - 255;
1616
+ const bg = bgU < 0 ? 0 : bgU;
1617
+ const bbU = db + sb - 255;
1618
+ const bb = bbU < 0 ? 0 : bbU;
1619
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
1620
+ const invA = 255 - sa;
1621
+ const da = dst >>> 24 & 255;
1622
+ const tR = br * sa + dr * invA;
1623
+ const r = tR + 1 + (tR >> 8) >> 8;
1254
1624
  const tG = bg * sa + dg * invA;
1255
1625
  const g = tG + 1 + (tG >> 8) >> 8;
1256
1626
  const tB = bb * sa + db * invA;
@@ -1666,6 +2036,14 @@ var dividePerfect = (src, dst) => {
1666
2036
  };
1667
2037
  var BASE_PERFECT_BLEND_MODE_FUNCTIONS = {
1668
2038
  [BaseBlendMode.overwrite]: overwritePerfect,
2039
+ [BaseBlendMode.sourceIn]: sourceInPerfect,
2040
+ [BaseBlendMode.sourceOut]: sourceOutPerfect,
2041
+ [BaseBlendMode.sourceAtop]: sourceAtopPerfect,
2042
+ [BaseBlendMode.destinationOver]: destinationOverPerfect,
2043
+ [BaseBlendMode.destinationIn]: destinationInPerfect,
2044
+ [BaseBlendMode.destinationOut]: destinationOutPerfect,
2045
+ [BaseBlendMode.destinationAtop]: destinationAtopPerfect,
2046
+ [BaseBlendMode.xor]: xorPerfect,
1669
2047
  [BaseBlendMode.sourceOver]: sourceOverPerfect,
1670
2048
  [BaseBlendMode.darken]: darkenPerfect,
1671
2049
  [BaseBlendMode.multiply]: multiplyPerfect,
@@ -1728,9 +2106,23 @@ var getKeyByValue = (obj, value) => {
1728
2106
  }
1729
2107
  };
1730
2108
 
1731
- // support/error-strings.ts
1732
- var OFFSCREEN_CANVAS_CTX_FAILED = "Failed to create OffscreenCanvas context";
1733
- var CANVAS_CTX_FAILED = "Failed to create Canvas context";
2109
+ // src/Canvas/canvas-blend-modes.ts
2110
+ var CANVAS_COMPOSITE_MAP = {
2111
+ [BaseBlendMode.overwrite]: "copy",
2112
+ [BaseBlendMode.sourceOver]: "source-over",
2113
+ [BaseBlendMode.darken]: "darken",
2114
+ [BaseBlendMode.multiply]: "multiply",
2115
+ [BaseBlendMode.colorBurn]: "color-burn",
2116
+ [BaseBlendMode.lighten]: "lighten",
2117
+ [BaseBlendMode.screen]: "screen",
2118
+ [BaseBlendMode.colorDodge]: "color-dodge",
2119
+ [BaseBlendMode.linearDodge]: "lighter",
2120
+ [BaseBlendMode.overlay]: "overlay",
2121
+ [BaseBlendMode.softLight]: "soft-light",
2122
+ [BaseBlendMode.hardLight]: "hard-light",
2123
+ [BaseBlendMode.difference]: "difference",
2124
+ [BaseBlendMode.exclusion]: "exclusion"
2125
+ };
1734
2126
 
1735
2127
  // src/Canvas/ReusableCanvas.ts
1736
2128
  function makeReusableCanvas() {
@@ -1783,37 +2175,38 @@ function makeReusableCanvasMeta(factory) {
1783
2175
  }
1784
2176
 
1785
2177
  // src/Canvas/CanvasFrameRenderer.ts
1786
- var defaults = {
1787
- makeReusableCanvas
1788
- };
1789
- function makeCanvasFrameRenderer(deps = defaults) {
1790
- const {
1791
- makeReusableCanvas: makeReusableCanvas2 = defaults.makeReusableCanvas
1792
- } = deps;
1793
- const bufferCanvas = makeReusableCanvas2();
2178
+ function makeCanvasFrameRenderer(reusableCanvasFactory = makeReusableOffscreenCanvas) {
2179
+ const bufferCanvas = reusableCanvasFactory();
1794
2180
  return function renderCanvasFrame(pixelCanvas, scale, getImageData, drawPixelLayer, drawScreenLayer) {
1795
- const {
1796
- canvas,
1797
- ctx
1798
- } = pixelCanvas;
1799
- const {
1800
- ctx: pxCtx,
1801
- canvas: pxCanvas
1802
- } = bufferCanvas(canvas.width, canvas.height);
2181
+ const canvas = pixelCanvas.canvas;
2182
+ const ctx = pixelCanvas.ctx;
2183
+ const w = canvas.width;
2184
+ const h = canvas.height;
2185
+ const buffer = bufferCanvas(w, h);
1803
2186
  const img = getImageData();
1804
2187
  if (img) {
1805
- pxCtx.putImageData(img, 0, 0);
2188
+ buffer.ctx.putImageData(img, 0, 0);
1806
2189
  }
1807
- drawPixelLayer?.(pxCtx);
2190
+ drawPixelLayer?.(buffer.ctx);
1808
2191
  ctx.setTransform(1, 0, 0, 1, 0, 0);
1809
- ctx.clearRect(0, 0, canvas.width, canvas.height);
2192
+ ctx.clearRect(0, 0, w, h);
1810
2193
  ctx.setTransform(scale, 0, 0, scale, 0, 0);
1811
- ctx.drawImage(pxCanvas, 0, 0);
2194
+ ctx.drawImage(buffer.canvas, 0, 0);
1812
2195
  ctx.setTransform(1, 0, 0, 1, 0, 0);
1813
2196
  drawScreenLayer?.(ctx, scale);
1814
2197
  };
1815
2198
  }
1816
2199
 
2200
+ // src/Canvas/CanvasPixelDataRenderer.ts
2201
+ function makeCanvasPixelDataRenderer(reusableCanvasFactory = makeReusableOffscreenCanvas) {
2202
+ const bufferCanvas = reusableCanvasFactory();
2203
+ return function drawPixelData(targetCtx, pixelData, x = 0, y = 0) {
2204
+ const buffer = bufferCanvas(pixelData.w, pixelData.h);
2205
+ buffer.ctx.putImageData(pixelData.imageData, 0, 0);
2206
+ targetCtx.drawImage(buffer.canvas, x, y);
2207
+ };
2208
+ }
2209
+
1817
2210
  // src/Canvas/PixelCanvas.ts
1818
2211
  function makePixelCanvas(canvas) {
1819
2212
  const ctx = canvas.getContext("2d");
@@ -1830,24 +2223,6 @@ function makePixelCanvas(canvas) {
1830
2223
  };
1831
2224
  }
1832
2225
 
1833
- // src/Canvas/canvas-blend-modes.ts
1834
- var CANVAS_COMPOSITE_MAP = {
1835
- [BaseBlendMode.overwrite]: "copy",
1836
- [BaseBlendMode.sourceOver]: "source-over",
1837
- [BaseBlendMode.darken]: "darken",
1838
- [BaseBlendMode.multiply]: "multiply",
1839
- [BaseBlendMode.colorBurn]: "color-burn",
1840
- [BaseBlendMode.lighten]: "lighten",
1841
- [BaseBlendMode.screen]: "screen",
1842
- [BaseBlendMode.colorDodge]: "color-dodge",
1843
- [BaseBlendMode.linearDodge]: "lighter",
1844
- [BaseBlendMode.overlay]: "overlay",
1845
- [BaseBlendMode.softLight]: "soft-light",
1846
- [BaseBlendMode.hardLight]: "hard-light",
1847
- [BaseBlendMode.difference]: "difference",
1848
- [BaseBlendMode.exclusion]: "exclusion"
1849
- };
1850
-
1851
2226
  // src/ImageData/imgBlobToImageData.ts
1852
2227
  async function imgBlobToImageData(blob) {
1853
2228
  let bitmap = null;
@@ -1912,10 +2287,10 @@ function applyPatchTiles(target, tiles, tileSize) {
1912
2287
  for (let i = 0; i < tiles.length; i++) {
1913
2288
  const tile = tiles[i];
1914
2289
  if (!tile) continue;
1915
- const dst = target.data32;
1916
- const src = tile.data32;
1917
- const dstWidth = target.width;
1918
- const dstHeight = target.height;
2290
+ const dst = target.data;
2291
+ const src = tile.data;
2292
+ const dstWidth = target.w;
2293
+ const dstHeight = target.h;
1919
2294
  const startX = tile.tx * tileSize;
1920
2295
  const startY = tile.ty * tileSize;
1921
2296
  const copyWidth = Math.max(0, Math.min(tileSize, dstWidth - startX));
@@ -2010,17 +2385,17 @@ var HistoryManager = class {
2010
2385
 
2011
2386
  // src/History/PixelAccumulator.ts
2012
2387
  var PixelAccumulator = class {
2013
- constructor(config, tilePool) {
2388
+ constructor(config, pixelTilePool) {
2014
2389
  this.config = config;
2015
- this.tilePool = tilePool;
2390
+ this.pixelTilePool = pixelTilePool;
2016
2391
  this.lookup = [];
2017
2392
  this.beforeTiles = [];
2018
2393
  }
2019
2394
  lookup;
2020
2395
  beforeTiles;
2021
2396
  recyclePatch(patch) {
2022
- this.tilePool.releaseTiles(patch.beforeTiles);
2023
- this.tilePool.releaseTiles(patch.afterTiles);
2397
+ this.pixelTilePool.releaseTiles(patch.beforeTiles);
2398
+ this.pixelTilePool.releaseTiles(patch.afterTiles);
2024
2399
  }
2025
2400
  /**
2026
2401
  * @param x pixel x coordinate
@@ -2035,7 +2410,7 @@ var PixelAccumulator = class {
2035
2410
  let tile = this.lookup[id];
2036
2411
  let added = false;
2037
2412
  if (!tile) {
2038
- tile = this.tilePool.getTile(id, tx, ty);
2413
+ tile = this.pixelTilePool.getTile(id, tx, ty);
2039
2414
  this.extractState(tile);
2040
2415
  this.lookup[id] = tile;
2041
2416
  this.beforeTiles.push(tile);
@@ -2045,7 +2420,7 @@ var PixelAccumulator = class {
2045
2420
  if (!didChange && added) {
2046
2421
  this.beforeTiles.pop();
2047
2422
  this.lookup[id] = void 0;
2048
- this.tilePool.releaseTile(tile);
2423
+ this.pixelTilePool.releaseTile(tile);
2049
2424
  }
2050
2425
  return didChange;
2051
2426
  };
@@ -2069,7 +2444,7 @@ var PixelAccumulator = class {
2069
2444
  const id = ty * columns + tx;
2070
2445
  let tile = this.lookup[id];
2071
2446
  if (!tile) {
2072
- tile = this.tilePool.getTile(id, tx, ty);
2447
+ tile = this.pixelTilePool.getTile(id, tx, ty);
2073
2448
  this.extractState(tile);
2074
2449
  this.lookup[id] = tile;
2075
2450
  this.beforeTiles.push(tile);
@@ -2083,7 +2458,7 @@ var PixelAccumulator = class {
2083
2458
  let t = this.beforeTiles[i];
2084
2459
  if (t) {
2085
2460
  this.lookup[t.id] = void 0;
2086
- this.tilePool.releaseTile(t);
2461
+ this.pixelTilePool.releaseTile(t);
2087
2462
  }
2088
2463
  }
2089
2464
  this.beforeTiles.length = startIndex;
@@ -2095,7 +2470,7 @@ var PixelAccumulator = class {
2095
2470
  let tile = this.lookup[id];
2096
2471
  let added = false;
2097
2472
  if (!tile) {
2098
- tile = this.tilePool.getTile(id, tx, ty);
2473
+ tile = this.pixelTilePool.getTile(id, tx, ty);
2099
2474
  this.extractState(tile);
2100
2475
  this.lookup[id] = tile;
2101
2476
  this.beforeTiles.push(tile);
@@ -2105,7 +2480,7 @@ var PixelAccumulator = class {
2105
2480
  if (!didChange && added) {
2106
2481
  this.beforeTiles.pop();
2107
2482
  this.lookup[id] = void 0;
2108
- this.tilePool.releaseTile(tile);
2483
+ this.pixelTilePool.releaseTile(tile);
2109
2484
  }
2110
2485
  return didChange;
2111
2486
  };
@@ -2113,12 +2488,12 @@ var PixelAccumulator = class {
2113
2488
  extractState(tile) {
2114
2489
  const target = this.config.target;
2115
2490
  const TILE_SIZE = this.config.tileSize;
2116
- const dst = tile.data32;
2117
- const src = target.data32;
2491
+ const dst = tile.data;
2492
+ const src = target.data;
2118
2493
  const startX = tile.tx * TILE_SIZE;
2119
2494
  const startY = tile.ty * TILE_SIZE;
2120
- const targetWidth = target.width;
2121
- const targetHeight = target.height;
2495
+ const targetWidth = target.w;
2496
+ const targetHeight = target.h;
2122
2497
  if (startX >= targetWidth || startX + TILE_SIZE <= 0 || startY >= targetHeight || startY + TILE_SIZE <= 0) {
2123
2498
  dst.fill(0);
2124
2499
  return;
@@ -2149,7 +2524,7 @@ var PixelAccumulator = class {
2149
2524
  for (let i = 0; i < length; i++) {
2150
2525
  let beforeTile = this.beforeTiles[i];
2151
2526
  if (beforeTile) {
2152
- let afterTile = this.tilePool.getTile(beforeTile.id, beforeTile.tx, beforeTile.ty);
2527
+ let afterTile = this.pixelTilePool.getTile(beforeTile.id, beforeTile.tx, beforeTile.ty);
2153
2528
  this.extractState(afterTile);
2154
2529
  afterTiles.push(afterTile);
2155
2530
  }
@@ -2171,7 +2546,7 @@ var PixelAccumulator = class {
2171
2546
  let tile = this.beforeTiles[i];
2172
2547
  if (tile) {
2173
2548
  this.lookup[tile.id] = void 0;
2174
- this.tilePool.releaseTile(tile);
2549
+ this.pixelTilePool.releaseTile(tile);
2175
2550
  }
2176
2551
  }
2177
2552
  this.beforeTiles.length = 0;
@@ -2199,8 +2574,8 @@ var PixelEngineConfig = class {
2199
2574
  this.tileMask = tileSize - 1;
2200
2575
  this.tileArea = tileSize * tileSize;
2201
2576
  this.target = target;
2202
- this.targetColumns = target.width + this.tileMask >> this.tileShift;
2203
- this.targetRows = target.height + this.tileMask >> this.tileShift;
2577
+ this.targetColumns = target.w + this.tileMask >> this.tileShift;
2578
+ this.targetRows = target.h + this.tileMask >> this.tileShift;
2204
2579
  }
2205
2580
  };
2206
2581
 
@@ -2208,8 +2583,8 @@ var PixelEngineConfig = class {
2208
2583
  function applyAlphaMaskToPixelData(target, mask, opts) {
2209
2584
  const targetX = opts?.x ?? 0;
2210
2585
  const targetY = opts?.y ?? 0;
2211
- const width = opts?.w ?? target.width;
2212
- const height = opts?.h ?? target.height;
2586
+ const width = opts?.w ?? target.w;
2587
+ const height = opts?.h ?? target.h;
2213
2588
  const globalAlpha = opts?.alpha ?? 255;
2214
2589
  const mx = opts?.mx ?? 0;
2215
2590
  const my = opts?.my ?? 0;
@@ -2227,8 +2602,8 @@ function applyAlphaMaskToPixelData(target, mask, opts) {
2227
2602
  h += y;
2228
2603
  y = 0;
2229
2604
  }
2230
- w = Math.min(w, target.width - x);
2231
- h = Math.min(h, target.height - y);
2605
+ w = Math.min(w, target.w - x);
2606
+ h = Math.min(h, target.h - y);
2232
2607
  if (w <= 0) return false;
2233
2608
  if (h <= 0) return false;
2234
2609
  const mPitch = mask.w;
@@ -2245,49 +2620,82 @@ function applyAlphaMaskToPixelData(target, mask, opts) {
2245
2620
  if (finalH <= 0) return false;
2246
2621
  const xShift = sX0 - startX;
2247
2622
  const yShift = sY0 - startY;
2248
- const dst32 = target.data32;
2249
- const dw = target.width;
2623
+ const dst32 = target.data;
2624
+ const dw = target.w;
2250
2625
  const dStride = dw - finalW;
2251
2626
  const mStride = mPitch - finalW;
2252
2627
  const maskData = mask.data;
2253
2628
  let dIdx = (y + yShift) * dw + (x + xShift);
2254
2629
  let mIdx = sY0 * mPitch + sX0;
2255
2630
  let didChange = false;
2256
- for (let iy = 0; iy < h; iy++) {
2257
- for (let ix = 0; ix < w; ix++) {
2258
- const mVal = maskData[mIdx];
2259
- const effectiveM = invertMask ? 255 - mVal : mVal;
2260
- let weight = 0;
2261
- if (effectiveM === 0) {
2262
- weight = 0;
2263
- } else if (effectiveM === 255) {
2264
- weight = globalAlpha;
2265
- } else if (globalAlpha === 255) {
2266
- weight = effectiveM;
2267
- } else {
2268
- weight = effectiveM * globalAlpha + 128 >> 8;
2631
+ if (invertMask) {
2632
+ for (let iy = 0; iy < finalH; iy++) {
2633
+ for (let ix = 0; ix < finalW; ix++) {
2634
+ const effectiveM = 255 - maskData[mIdx];
2635
+ if (effectiveM === 0) {
2636
+ const current = dst32[dIdx];
2637
+ const next = (current & 16777215) >>> 0;
2638
+ if (current !== next) {
2639
+ dst32[dIdx] = next;
2640
+ didChange = true;
2641
+ }
2642
+ } else {
2643
+ const t1 = effectiveM * globalAlpha + 128;
2644
+ const weight = t1 + (t1 >> 8) >> 8;
2645
+ if (weight < 255) {
2646
+ const current = dst32[dIdx];
2647
+ const da = current >>> 24;
2648
+ if (da !== 0) {
2649
+ const t2 = da * weight + 128;
2650
+ const finalAlpha = t2 + (t2 >> 8) >> 8;
2651
+ const next = (current & 16777215 | finalAlpha << 24) >>> 0;
2652
+ if (current !== next) {
2653
+ dst32[dIdx] = next;
2654
+ didChange = true;
2655
+ }
2656
+ }
2657
+ }
2658
+ }
2659
+ dIdx++;
2660
+ mIdx++;
2269
2661
  }
2270
- if (weight === 0) {
2271
- dst32[dIdx] = (dst32[dIdx] & 16777215) >>> 0;
2272
- didChange = true;
2273
- } else if (weight !== 255) {
2274
- const d = dst32[dIdx];
2275
- const da = d >>> 24;
2276
- if (da !== 0) {
2277
- const finalAlpha = da === 255 ? weight : da * weight + 128 >> 8;
2662
+ dIdx += dStride;
2663
+ mIdx += mStride;
2664
+ }
2665
+ } else {
2666
+ for (let iy = 0; iy < finalH; iy++) {
2667
+ for (let ix = 0; ix < finalW; ix++) {
2668
+ const effectiveM = maskData[mIdx];
2669
+ if (effectiveM === 0) {
2278
2670
  const current = dst32[dIdx];
2279
- const next = (d & 16777215 | finalAlpha << 24) >>> 0;
2671
+ const next = (current & 16777215) >>> 0;
2280
2672
  if (current !== next) {
2281
2673
  dst32[dIdx] = next;
2282
2674
  didChange = true;
2283
2675
  }
2676
+ } else {
2677
+ const t1 = effectiveM * globalAlpha + 128;
2678
+ const weight = t1 + (t1 >> 8) >> 8;
2679
+ if (weight < 255) {
2680
+ const current = dst32[dIdx];
2681
+ const da = current >>> 24;
2682
+ if (da !== 0) {
2683
+ const t2 = da * weight + 128;
2684
+ const finalAlpha = t2 + (t2 >> 8) >> 8;
2685
+ const next = (current & 16777215 | finalAlpha << 24) >>> 0;
2686
+ if (current !== next) {
2687
+ dst32[dIdx] = next;
2688
+ didChange = true;
2689
+ }
2690
+ }
2691
+ }
2284
2692
  }
2693
+ dIdx++;
2694
+ mIdx++;
2285
2695
  }
2286
- dIdx++;
2287
- mIdx++;
2696
+ dIdx += dStride;
2697
+ mIdx += mStride;
2288
2698
  }
2289
- dIdx += dStride;
2290
- mIdx += mStride;
2291
2699
  }
2292
2700
  return didChange;
2293
2701
  }
@@ -2321,338 +2729,77 @@ function resizeImageData(target, newWidth, newHeight, offsetX = 0, offsetY = 0)
2321
2729
  return result;
2322
2730
  }
2323
2731
 
2324
- // src/Rect/trimRectBounds.ts
2325
- function trimRectBounds(x, y, w, h, targetWidth, targetHeight, out) {
2326
- const res = out ?? {
2327
- x: 0,
2328
- y: 0,
2329
- w: 0,
2330
- h: 0
2732
+ // src/PixelData/PixelData.ts
2733
+ function makePixelData(imageData) {
2734
+ return {
2735
+ data: new Uint32Array(
2736
+ imageData.data.buffer,
2737
+ imageData.data.byteOffset,
2738
+ // Shift right by 2 is a fast bitwise division by 4.
2739
+ imageData.data.byteLength >> 2
2740
+ ),
2741
+ imageData,
2742
+ w: imageData.width,
2743
+ h: imageData.height
2331
2744
  };
2332
- const left = Math.max(0, x);
2333
- const top = Math.max(0, y);
2334
- const right = Math.min(targetWidth, x + w);
2335
- const bottom = Math.min(targetHeight, y + h);
2336
- res.x = left;
2337
- res.y = top;
2338
- res.w = Math.max(0, right - left);
2339
- res.h = Math.max(0, bottom - top);
2340
- return res;
2745
+ }
2746
+ function setPixelData(target, imageData) {
2747
+ ;
2748
+ target.data = new Uint32Array(
2749
+ imageData.data.buffer,
2750
+ imageData.data.byteOffset,
2751
+ // Shift right by 2 is a fast bitwise division by 4.
2752
+ imageData.data.byteLength >> 2
2753
+ );
2754
+ target.imageData = imageData;
2755
+ target.w = imageData.width;
2756
+ target.h = imageData.height;
2341
2757
  }
2342
2758
 
2343
- // src/Paint/PaintBuffer.ts
2344
- var PaintBuffer = class {
2345
- constructor(config, tilePool) {
2346
- this.config = config;
2347
- this.tilePool = tilePool;
2348
- this.lookup = [];
2349
- }
2350
- lookup;
2351
- scratchBounds = {
2352
- x: 0,
2353
- y: 0,
2354
- w: 0,
2355
- h: 0
2356
- };
2357
- eachTileInBounds(bounds, callback) {
2358
- const {
2359
- tileShift,
2360
- targetColumns,
2361
- targetRows,
2362
- tileSize
2363
- } = this.config;
2364
- const x1 = Math.max(0, bounds.x >> tileShift);
2365
- const y1 = Math.max(0, bounds.y >> tileShift);
2366
- const x2 = Math.min(targetColumns - 1, bounds.x + bounds.w - 1 >> tileShift);
2367
- const y2 = Math.min(targetRows - 1, bounds.y + bounds.h - 1 >> tileShift);
2368
- if (x1 > x2 || y1 > y2) return;
2369
- const lookup = this.lookup;
2370
- const tilePool = this.tilePool;
2371
- for (let ty = y1; ty <= y2; ty++) {
2372
- const rowOffset = ty * targetColumns;
2373
- const tileTop = ty << tileShift;
2374
- for (let tx = x1; tx <= x2; tx++) {
2375
- const id = rowOffset + tx;
2376
- const tile = lookup[id] ?? (lookup[id] = tilePool.getTile(id, tx, ty));
2377
- const tileLeft = tx << tileShift;
2378
- const startX = bounds.x > tileLeft ? bounds.x : tileLeft;
2379
- const startY = bounds.y > tileTop ? bounds.y : tileTop;
2380
- const maskEndX = bounds.x + bounds.w;
2381
- const tileEndX = tileLeft + tileSize;
2382
- const endX = maskEndX < tileEndX ? maskEndX : tileEndX;
2383
- const maskEndY = bounds.y + bounds.h;
2384
- const tileEndY = tileTop + tileSize;
2385
- const endY = maskEndY < tileEndY ? maskEndY : tileEndY;
2386
- callback(tile, startX, startY, endX - startX, endY - startY);
2387
- }
2388
- }
2389
- }
2390
- writePaintAlphaMaskStroke(color, brush, x0, y0, x1, y1) {
2391
- const cA = color >>> 24;
2392
- if (cA === 0) return false;
2393
- const {
2394
- tileShift,
2395
- tileMask,
2396
- target
2397
- } = this.config;
2398
- const {
2399
- w: bW,
2400
- h: bH,
2401
- data: bD,
2402
- centerOffsetX,
2403
- centerOffsetY
2404
- } = brush;
2405
- const cRGB = color & 16777215;
2406
- const scratch = this.scratchBounds;
2407
- let changed = false;
2408
- forEachLinePoint(x0, y0, x1, y1, (px, py) => {
2409
- const topLeftX = Math.floor(px + centerOffsetX);
2410
- const topLeftY = Math.floor(py + centerOffsetY);
2411
- trimRectBounds(topLeftX, topLeftY, bW, bH, target.width, target.height, scratch);
2412
- if (scratch.w <= 0 || scratch.h <= 0) return;
2413
- this.eachTileInBounds(scratch, (tile, bX, bY, bW_t, bH_t) => {
2414
- const d32 = tile.data32;
2415
- let tileChanged = false;
2416
- for (let i = 0; i < bH_t; i++) {
2417
- const canvasY = bY + i;
2418
- const bOff = (canvasY - topLeftY) * bW;
2419
- const tOff = (canvasY & tileMask) << tileShift;
2420
- const dS = tOff + (bX & tileMask);
2421
- for (let j = 0; j < bW_t; j++) {
2422
- const canvasX = bX + j;
2423
- const brushA = bD[bOff + (canvasX - topLeftX)];
2424
- if (brushA === 0) continue;
2425
- const t = cA * brushA + 128;
2426
- const blendedA = t + (t >> 8) >> 8;
2427
- const idx = dS + j;
2428
- const cur = d32[idx];
2429
- if (brushA > cur >>> 24) {
2430
- const next = (cRGB | blendedA << 24) >>> 0;
2431
- if (cur !== next) {
2432
- d32[idx] = next;
2433
- tileChanged = true;
2434
- }
2435
- }
2436
- }
2437
- }
2438
- if (tileChanged) changed = true;
2439
- });
2440
- });
2441
- return changed;
2442
- }
2443
- writePaintBinaryMaskStroke(color, brush, x0, y0, x1, y1) {
2444
- const alphaIsZero = color >>> 24 === 0;
2445
- if (alphaIsZero) return false;
2446
- const {
2447
- tileShift,
2448
- tileMask,
2449
- target
2450
- } = this.config;
2451
- const {
2452
- w: bW,
2453
- h: bH,
2454
- data: bD,
2455
- centerOffsetX,
2456
- centerOffsetY
2457
- } = brush;
2458
- const scratch = this.scratchBounds;
2459
- let changed = false;
2460
- forEachLinePoint(x0, y0, x1, y1, (px, py) => {
2461
- const topLeftX = Math.floor(px + centerOffsetX);
2462
- const topLeftY = Math.floor(py + centerOffsetY);
2463
- trimRectBounds(topLeftX, topLeftY, bW, bH, target.width, target.height, scratch);
2464
- if (scratch.w <= 0 || scratch.h <= 0) return;
2465
- this.eachTileInBounds(scratch, (tile, bX, bY, bW_t, bH_t) => {
2466
- const d32 = tile.data32;
2467
- let tileChanged = false;
2468
- for (let i = 0; i < bH_t; i++) {
2469
- const canvasY = bY + i;
2470
- const bOff = (canvasY - topLeftY) * bW;
2471
- const tOff = (canvasY & tileMask) << tileShift;
2472
- const dS = tOff + (bX & tileMask);
2473
- for (let j = 0; j < bW_t; j++) {
2474
- const canvasX = bX + j;
2475
- if (bD[bOff + (canvasX - topLeftX)]) {
2476
- const idx = dS + j;
2477
- if (d32[idx] !== color) {
2478
- d32[idx] = color;
2479
- tileChanged = true;
2480
- }
2481
- }
2482
- }
2483
- }
2484
- if (tileChanged) changed = true;
2485
- });
2486
- });
2487
- return changed;
2488
- }
2489
- writeRectStroke(color, brushWidth, brushHeight, x0, y0, x1, y1) {
2490
- const alphaIsZero = color >>> 24 === 0;
2491
- if (alphaIsZero) return false;
2492
- const config = this.config;
2493
- const tileShift = config.tileShift;
2494
- const tileMask = config.tileMask;
2495
- const target = config.target;
2496
- const scratch = this.scratchBounds;
2497
- const centerOffsetX = -(brushWidth - 1 >> 1);
2498
- const centerOffsetY = -(brushHeight - 1 >> 1);
2499
- let changed = false;
2500
- forEachLinePoint(x0, y0, x1, y1, (px, py) => {
2501
- const topLeftX = Math.floor(px + centerOffsetX);
2502
- const topLeftY = Math.floor(py + centerOffsetY);
2503
- trimRectBounds(topLeftX, topLeftY, brushWidth, brushHeight, target.width, target.height, scratch);
2504
- if (scratch.w <= 0 || scratch.h <= 0) return;
2505
- this.eachTileInBounds(scratch, (tile, bX, bY, bW_t, bH_t) => {
2506
- const d32 = tile.data32;
2507
- let tileChanged = false;
2508
- for (let i = 0; i < bH_t; i++) {
2509
- const canvasY = bY + i;
2510
- const tOff = (canvasY & tileMask) << tileShift;
2511
- const dS = tOff + (bX & tileMask);
2512
- for (let j = 0; j < bW_t; j++) {
2513
- const idx = dS + j;
2514
- if (d32[idx] !== color) {
2515
- d32[idx] = color;
2516
- tileChanged = true;
2517
- }
2518
- }
2519
- }
2520
- if (tileChanged) {
2521
- changed = true;
2522
- }
2523
- });
2524
- });
2525
- return changed;
2526
- }
2527
- clear() {
2528
- this.tilePool.releaseTiles(this.lookup);
2529
- }
2530
- };
2759
+ // src/Tile/_tile-types.ts
2760
+ var TileType = /* @__PURE__ */ ((TileType2) => {
2761
+ TileType2[TileType2["PIXEL"] = 0] = "PIXEL";
2762
+ TileType2[TileType2["MASK"] = 1] = "MASK";
2763
+ return TileType2;
2764
+ })(TileType || {});
2531
2765
 
2532
- // src/PixelData/blendPixelData.ts
2533
- function blendPixelData(target, src, opts) {
2534
- const targetX = opts?.x ?? 0;
2535
- const targetY = opts?.y ?? 0;
2536
- const sourceX = opts?.sx ?? 0;
2537
- const sourceY = opts?.sy ?? 0;
2538
- const width = opts?.w ?? src.width;
2539
- const height = opts?.h ?? src.height;
2540
- const globalAlpha = opts?.alpha ?? 255;
2541
- const blendFn = opts?.blendFn ?? sourceOverPerfect;
2542
- if (globalAlpha === 0) return false;
2543
- let x = targetX;
2544
- let y = targetY;
2545
- let sx = sourceX;
2546
- let sy = sourceY;
2547
- let w = width;
2548
- let h = height;
2549
- if (sx < 0) {
2550
- x -= sx;
2551
- w += sx;
2552
- sx = 0;
2553
- }
2554
- if (sy < 0) {
2555
- y -= sy;
2556
- h += sy;
2557
- sy = 0;
2558
- }
2559
- w = Math.min(w, src.width - sx);
2560
- h = Math.min(h, src.height - sy);
2561
- if (x < 0) {
2562
- sx -= x;
2563
- w += x;
2564
- x = 0;
2565
- }
2566
- if (y < 0) {
2567
- sy -= y;
2568
- h += y;
2569
- y = 0;
2570
- }
2571
- const actualW = Math.min(w, target.width - x);
2572
- const actualH = Math.min(h, target.height - y);
2573
- if (actualW <= 0 || actualH <= 0) return false;
2574
- const dst32 = target.data32;
2575
- const src32 = src.data32;
2576
- const dw = target.width;
2577
- const sw = src.width;
2578
- let dIdx = y * dw + x | 0;
2579
- let sIdx = sy * sw + sx | 0;
2580
- const dStride = dw - actualW | 0;
2581
- const sStride = sw - actualW | 0;
2582
- const isOpaque = globalAlpha === 255;
2583
- const isOverwrite = blendFn.isOverwrite;
2584
- let didChange = false;
2585
- for (let iy = 0; iy < actualH; iy++) {
2586
- for (let ix = 0; ix < actualW; ix++) {
2587
- const srcCol = src32[sIdx];
2588
- const srcAlpha = srcCol >>> 24;
2589
- if (srcAlpha === 0 && !isOverwrite) {
2590
- dIdx++;
2591
- sIdx++;
2592
- continue;
2593
- }
2594
- let finalCol = srcCol;
2595
- if (!isOpaque) {
2596
- const a = srcAlpha * globalAlpha + 128 >> 8;
2597
- if (a === 0 && !isOverwrite) {
2598
- dIdx++;
2599
- sIdx++;
2600
- continue;
2601
- }
2602
- finalCol = (srcCol & 16777215 | a << 24) >>> 0;
2603
- }
2604
- const current = dst32[dIdx];
2605
- const next = blendFn(finalCol, dst32[dIdx]);
2606
- if (current !== next) {
2607
- dst32[dIdx] = next;
2608
- didChange = true;
2609
- }
2610
- dIdx++;
2611
- sIdx++;
2612
- }
2613
- dIdx += dStride;
2614
- sIdx += sStride;
2615
- }
2616
- return didChange;
2766
+ // src/Tile/PixelTile.ts
2767
+ function makePixelTile(id, tx, ty, tileSize, tileArea) {
2768
+ const data32 = new Uint32Array(tileArea);
2769
+ const data8 = new Uint8ClampedArray(data32.buffer);
2770
+ return {
2771
+ tileType: 0 /* PIXEL */,
2772
+ id,
2773
+ tx,
2774
+ ty,
2775
+ w: tileSize,
2776
+ h: tileSize,
2777
+ data: data32,
2778
+ imageData: new ImageData(data8, tileSize, tileSize)
2779
+ };
2617
2780
  }
2618
2781
 
2619
- // src/PixelTile/PixelTile.ts
2620
- var PixelTile = class {
2621
- constructor(id, tx, ty, tileSize, tileArea) {
2622
- this.id = id;
2623
- this.tx = tx;
2624
- this.ty = ty;
2625
- this.width = this.height = tileSize;
2626
- this.data32 = new Uint32Array(tileArea);
2627
- const data8 = new Uint8ClampedArray(this.data32.buffer);
2628
- this.imageData = new ImageData(data8, tileSize, tileSize);
2629
- }
2630
- data32;
2631
- width;
2632
- height;
2633
- imageData;
2634
- };
2635
-
2636
- // src/PixelTile/PixelTilePool.ts
2637
- var PixelTilePool = class {
2638
- pool;
2639
- tileSize;
2640
- tileArea;
2641
- constructor(config) {
2782
+ // src/Tile/TilePool.ts
2783
+ var TilePool = class {
2784
+ constructor(config, tileFactory) {
2785
+ this.tileFactory = tileFactory;
2642
2786
  this.pool = [];
2643
2787
  this.tileSize = config.tileSize;
2644
2788
  this.tileArea = config.tileArea;
2645
2789
  }
2790
+ pool;
2791
+ tileSize;
2792
+ tileArea;
2646
2793
  getTile(id, tx, ty) {
2647
2794
  let tile = this.pool.pop();
2648
2795
  if (tile) {
2649
2796
  tile.id = id;
2650
2797
  tile.tx = tx;
2651
2798
  tile.ty = ty;
2652
- tile.data32.fill(0);
2799
+ tile.data.fill(0);
2653
2800
  return tile;
2654
2801
  }
2655
- return new PixelTile(id, tx, ty, this.tileSize, this.tileArea);
2802
+ return this.tileFactory(id, tx, ty, this.tileSize, this.tileArea);
2656
2803
  }
2657
2804
  releaseTile(tile) {
2658
2805
  this.pool.push(tile);
@@ -2676,16 +2823,7 @@ var PixelWriter = class {
2676
2823
  historyActionFactory;
2677
2824
  config;
2678
2825
  pixelTilePool;
2679
- paintBuffer;
2680
2826
  mutator;
2681
- blendPixelDataOpts = {
2682
- alpha: 255,
2683
- blendFn: sourceOverPerfect,
2684
- x: 0,
2685
- y: 0,
2686
- w: 0,
2687
- h: 0
2688
- };
2689
2827
  _inProgress = false;
2690
2828
  constructor(target, mutatorFactory, options) {
2691
2829
  const tileSize = options?.tileSize ?? 256;
@@ -2693,10 +2831,9 @@ var PixelWriter = class {
2693
2831
  this.config = new PixelEngineConfig(tileSize, target);
2694
2832
  this.historyManager = options?.historyManager ?? new HistoryManager(maxHistorySteps);
2695
2833
  this.historyActionFactory = options?.historyActionFactory ?? makeHistoryAction;
2696
- this.pixelTilePool = options?.pixelTilePool ?? new PixelTilePool(this.config);
2834
+ this.pixelTilePool = options?.pixelTilePool ?? new TilePool(this.config, makePixelTile);
2697
2835
  this.accumulator = options?.accumulator ?? new PixelAccumulator(this.config, this.pixelTilePool);
2698
2836
  this.mutator = mutatorFactory(this);
2699
- this.paintBuffer = new PaintBuffer(this.config, this.pixelTilePool);
2700
2837
  }
2701
2838
  /**
2702
2839
  * Executes `transaction` and commits the resulting pixel changes as a single
@@ -2742,59 +2879,37 @@ var PixelWriter = class {
2742
2879
  const target = config.target;
2743
2880
  const beforeImageData = target.imageData;
2744
2881
  const afterImageData = resizeImageDataFn(beforeImageData, newWidth, newHeight, offsetX, offsetY);
2745
- target.set(afterImageData);
2882
+ setPixelData(target, afterImageData);
2746
2883
  this.historyManager.commit({
2747
2884
  undo: () => {
2748
- target.set(beforeImageData);
2885
+ setPixelData(target, beforeImageData);
2749
2886
  afterUndo?.(beforeImageData);
2750
2887
  after?.(beforeImageData);
2751
2888
  },
2752
2889
  redo: () => {
2753
- target.set(afterImageData);
2890
+ setPixelData(target, afterImageData);
2754
2891
  afterRedo?.(afterImageData);
2755
2892
  after?.(afterImageData);
2756
2893
  }
2757
2894
  });
2758
2895
  }
2759
- commitPaintBuffer(alpha = 255, blendFn = sourceOverPerfect, blendPixelDataFn = blendPixelData) {
2760
- const paintBuffer = this.paintBuffer;
2761
- const tileShift = paintBuffer.config.tileShift;
2762
- const lookup = paintBuffer.lookup;
2763
- const opts = this.blendPixelDataOpts;
2764
- opts.alpha = alpha;
2765
- opts.blendFn = blendFn;
2766
- for (let i = 0; i < lookup.length; i++) {
2767
- const tile = lookup[i];
2768
- if (tile) {
2769
- const didChange = this.accumulator.storeTileBeforeState(tile.id, tile.tx, tile.ty);
2770
- const dx = tile.tx << tileShift;
2771
- const dy = tile.ty << tileShift;
2772
- opts.x = dx;
2773
- opts.y = dy;
2774
- opts.w = tile.width;
2775
- opts.h = tile.height;
2776
- didChange(blendPixelDataFn(this.config.target, tile, opts));
2777
- }
2778
- }
2779
- paintBuffer.clear();
2780
- }
2781
2896
  };
2782
2897
 
2783
2898
  // src/History/PixelMutator/mutatorApplyAlphaMask.ts
2784
- var defaults2 = {
2899
+ var defaults = {
2785
2900
  applyAlphaMaskToPixelData
2786
2901
  };
2787
- var mutatorApplyAlphaMask = ((writer, deps = defaults2) => {
2902
+ var mutatorApplyAlphaMask = ((writer, deps = defaults) => {
2788
2903
  const {
2789
- applyAlphaMaskToPixelData: applyAlphaMaskToPixelData2 = defaults2.applyAlphaMaskToPixelData
2904
+ applyAlphaMaskToPixelData: applyAlphaMaskToPixelData2 = defaults.applyAlphaMaskToPixelData
2790
2905
  } = deps;
2791
2906
  return {
2792
2907
  applyAlphaMask(mask, opts) {
2793
2908
  const target = writer.config.target;
2794
2909
  const x = opts?.x ?? 0;
2795
2910
  const y = opts?.y ?? 0;
2796
- const w = opts?.w ?? target.width;
2797
- const h = opts?.h ?? target.height;
2911
+ const w = opts?.w ?? target.w;
2912
+ const h = opts?.h ?? target.h;
2798
2913
  const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h);
2799
2914
  return didChange(applyAlphaMaskToPixelData2(target, mask, opts));
2800
2915
  }
@@ -2805,8 +2920,8 @@ var mutatorApplyAlphaMask = ((writer, deps = defaults2) => {
2805
2920
  function applyBinaryMaskToPixelData(target, mask, opts) {
2806
2921
  const targetX = opts?.x ?? 0;
2807
2922
  const targetY = opts?.y ?? 0;
2808
- const width = opts?.w ?? target.width;
2809
- const height = opts?.h ?? target.height;
2923
+ const width = opts?.w ?? target.w;
2924
+ const height = opts?.h ?? target.h;
2810
2925
  const globalAlpha = opts?.alpha ?? 255;
2811
2926
  const mx = opts?.mx ?? 0;
2812
2927
  const my = opts?.my ?? 0;
@@ -2824,8 +2939,8 @@ function applyBinaryMaskToPixelData(target, mask, opts) {
2824
2939
  h += y;
2825
2940
  y = 0;
2826
2941
  }
2827
- w = Math.min(w, target.width - x);
2828
- h = Math.min(h, target.height - y);
2942
+ w = Math.min(w, target.w - x);
2943
+ h = Math.min(h, target.h - y);
2829
2944
  if (w <= 0 || h <= 0) return false;
2830
2945
  const mPitch = mask.w;
2831
2946
  if (mPitch <= 0) return false;
@@ -2842,8 +2957,8 @@ function applyBinaryMaskToPixelData(target, mask, opts) {
2842
2957
  }
2843
2958
  const xShift = sX0 - startX;
2844
2959
  const yShift = sY0 - startY;
2845
- const dst32 = target.data32;
2846
- const dw = target.width;
2960
+ const dst32 = target.data;
2961
+ const dw = target.w;
2847
2962
  const dStride = dw - finalW;
2848
2963
  const mStride = mPitch - finalW;
2849
2964
  const maskData = mask.data;
@@ -2883,20 +2998,20 @@ function applyBinaryMaskToPixelData(target, mask, opts) {
2883
2998
  }
2884
2999
 
2885
3000
  // src/History/PixelMutator/mutatorApplyBinaryMask.ts
2886
- var defaults3 = {
3001
+ var defaults2 = {
2887
3002
  applyBinaryMaskToPixelData
2888
3003
  };
2889
- var mutatorApplyBinaryMask = ((writer, deps = defaults3) => {
3004
+ var mutatorApplyBinaryMask = ((writer, deps = defaults2) => {
2890
3005
  const {
2891
- applyBinaryMaskToPixelData: applyBinaryMaskToPixelData2 = defaults3.applyBinaryMaskToPixelData
3006
+ applyBinaryMaskToPixelData: applyBinaryMaskToPixelData2 = defaults2.applyBinaryMaskToPixelData
2892
3007
  } = deps;
2893
3008
  return {
2894
3009
  applyBinaryMask(mask, opts) {
2895
3010
  const target = writer.config.target;
2896
3011
  const x = opts?.x ?? 0;
2897
3012
  const y = opts?.y ?? 0;
2898
- const w = opts?.w ?? target.width;
2899
- const h = opts?.h ?? target.height;
3013
+ const w = opts?.w ?? target.w;
3014
+ const h = opts?.h ?? target.h;
2900
3015
  const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h);
2901
3016
  return didChange(applyBinaryMaskToPixelData2(target, mask, opts));
2902
3017
  }
@@ -2904,22 +3019,22 @@ var mutatorApplyBinaryMask = ((writer, deps = defaults3) => {
2904
3019
  });
2905
3020
 
2906
3021
  // src/History/PixelMutator/mutatorApplyMask.ts
2907
- var defaults4 = {
3022
+ var defaults3 = {
2908
3023
  applyBinaryMaskToPixelData,
2909
3024
  applyAlphaMaskToPixelData
2910
3025
  };
2911
- var mutatorApplyMask = ((writer, deps = defaults4) => {
3026
+ var mutatorApplyMask = ((writer, deps = defaults3) => {
2912
3027
  const {
2913
- applyBinaryMaskToPixelData: applyBinaryMaskToPixelData2 = defaults4.applyBinaryMaskToPixelData,
2914
- applyAlphaMaskToPixelData: applyAlphaMaskToPixelData2 = defaults4.applyAlphaMaskToPixelData
3028
+ applyBinaryMaskToPixelData: applyBinaryMaskToPixelData2 = defaults3.applyBinaryMaskToPixelData,
3029
+ applyAlphaMaskToPixelData: applyAlphaMaskToPixelData2 = defaults3.applyAlphaMaskToPixelData
2915
3030
  } = deps;
2916
3031
  return {
2917
3032
  applyMask(mask, opts) {
2918
3033
  const target = writer.config.target;
2919
3034
  const x = opts?.x ?? 0;
2920
3035
  const y = opts?.y ?? 0;
2921
- const w = opts?.w ?? target.width;
2922
- const h = opts?.h ?? target.height;
3036
+ const w = opts?.w ?? target.w;
3037
+ const h = opts?.h ?? target.h;
2923
3038
  const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h);
2924
3039
  if (mask.type === 1 /* BINARY */) {
2925
3040
  return didChange(applyBinaryMaskToPixelData2(target, mask, opts));
@@ -2936,8 +3051,8 @@ function blendPixelDataAlphaMask(target, src, alphaMask, opts) {
2936
3051
  const targetY = opts?.y ?? 0;
2937
3052
  const sourceX = opts?.sx ?? 0;
2938
3053
  const sourceY = opts?.sy ?? 0;
2939
- const width = opts?.w ?? src.width;
2940
- const height = opts?.h ?? src.height;
3054
+ const width = opts?.w ?? src.w;
3055
+ const height = opts?.h ?? src.h;
2941
3056
  const globalAlpha = opts?.alpha ?? 255;
2942
3057
  const blendFn = opts?.blendFn ?? sourceOverPerfect;
2943
3058
  const mx = opts?.mx ?? 0;
@@ -2960,8 +3075,8 @@ function blendPixelDataAlphaMask(target, src, alphaMask, opts) {
2960
3075
  h += sy;
2961
3076
  sy = 0;
2962
3077
  }
2963
- w = Math.min(w, src.width - sx);
2964
- h = Math.min(h, src.height - sy);
3078
+ w = Math.min(w, src.w - sx);
3079
+ h = Math.min(h, src.h - sy);
2965
3080
  if (x < 0) {
2966
3081
  sx -= x;
2967
3082
  w += x;
@@ -2972,17 +3087,17 @@ function blendPixelDataAlphaMask(target, src, alphaMask, opts) {
2972
3087
  h += y;
2973
3088
  y = 0;
2974
3089
  }
2975
- const actualW = Math.min(w, target.width - x);
2976
- const actualH = Math.min(h, target.height - y);
3090
+ const actualW = Math.min(w, target.w - x);
3091
+ const actualH = Math.min(h, target.h - y);
2977
3092
  if (actualW <= 0 || actualH <= 0) return false;
2978
- const dw = target.width;
2979
- const sw = src.width;
3093
+ const dw = target.w;
3094
+ const sw = src.w;
2980
3095
  const mPitch = alphaMask.w;
2981
3096
  const maskData = alphaMask.data;
2982
3097
  const dx = x - targetX | 0;
2983
3098
  const dy = y - targetY | 0;
2984
- const dst32 = target.data32;
2985
- const src32 = src.data32;
3099
+ const dst32 = target.data;
3100
+ const src32 = src.data;
2986
3101
  let dIdx = y * dw + x | 0;
2987
3102
  let sIdx = sy * sw + sx | 0;
2988
3103
  let mIdx = (my + dy) * mPitch + (mx + dx) | 0;
@@ -3051,19 +3166,19 @@ function blendPixelDataAlphaMask(target, src, alphaMask, opts) {
3051
3166
  }
3052
3167
 
3053
3168
  // src/History/PixelMutator/mutatorBlendAlphaMask.ts
3054
- var defaults5 = {
3169
+ var defaults4 = {
3055
3170
  blendPixelDataAlphaMask
3056
3171
  };
3057
- var mutatorBlendAlphaMask = ((writer, deps = defaults5) => {
3172
+ var mutatorBlendAlphaMask = ((writer, deps = defaults4) => {
3058
3173
  const {
3059
- blendPixelDataAlphaMask: blendPixelDataAlphaMask2 = defaults5.blendPixelDataAlphaMask
3174
+ blendPixelDataAlphaMask: blendPixelDataAlphaMask2 = defaults4.blendPixelDataAlphaMask
3060
3175
  } = deps;
3061
3176
  return {
3062
3177
  blendAlphaMask(src, mask, opts) {
3063
3178
  const x = opts?.x ?? 0;
3064
3179
  const y = opts?.y ?? 0;
3065
- const w = opts?.w ?? src.width;
3066
- const h = opts?.h ?? src.height;
3180
+ const w = opts?.w ?? src.w;
3181
+ const h = opts?.h ?? src.h;
3067
3182
  const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h);
3068
3183
  return didChange(blendPixelDataAlphaMask2(writer.config.target, src, mask, opts));
3069
3184
  }
@@ -3076,8 +3191,8 @@ function blendPixelDataBinaryMask(target, src, binaryMask, opts) {
3076
3191
  const targetY = opts?.y ?? 0;
3077
3192
  const sourceX = opts?.sx ?? 0;
3078
3193
  const sourceY = opts?.sy ?? 0;
3079
- const width = opts?.w ?? src.width;
3080
- const height = opts?.h ?? src.height;
3194
+ const width = opts?.w ?? src.w;
3195
+ const height = opts?.h ?? src.h;
3081
3196
  const globalAlpha = opts?.alpha ?? 255;
3082
3197
  const blendFn = opts?.blendFn ?? sourceOverPerfect;
3083
3198
  const mx = opts?.mx ?? 0;
@@ -3100,8 +3215,8 @@ function blendPixelDataBinaryMask(target, src, binaryMask, opts) {
3100
3215
  h += sy;
3101
3216
  sy = 0;
3102
3217
  }
3103
- w = Math.min(w, src.width - sx);
3104
- h = Math.min(h, src.height - sy);
3218
+ w = Math.min(w, src.w - sx);
3219
+ h = Math.min(h, src.h - sy);
3105
3220
  if (x < 0) {
3106
3221
  sx -= x;
3107
3222
  w += x;
@@ -3112,15 +3227,15 @@ function blendPixelDataBinaryMask(target, src, binaryMask, opts) {
3112
3227
  h += y;
3113
3228
  y = 0;
3114
3229
  }
3115
- const actualW = Math.min(w, target.width - x);
3116
- const actualH = Math.min(h, target.height - y);
3230
+ const actualW = Math.min(w, target.w - x);
3231
+ const actualH = Math.min(h, target.h - y);
3117
3232
  if (actualW <= 0 || actualH <= 0) return false;
3118
3233
  const dx = x - targetX | 0;
3119
3234
  const dy = y - targetY | 0;
3120
- const dst32 = target.data32;
3121
- const src32 = src.data32;
3122
- const dw = target.width;
3123
- const sw = src.width;
3235
+ const dst32 = target.data;
3236
+ const src32 = src.data;
3237
+ const dw = target.w;
3238
+ const sw = src.w;
3124
3239
  const mPitch = binaryMask.w;
3125
3240
  const maskData = binaryMask.data;
3126
3241
  let dIdx = y * dw + x | 0;
@@ -3178,19 +3293,19 @@ function blendPixelDataBinaryMask(target, src, binaryMask, opts) {
3178
3293
  }
3179
3294
 
3180
3295
  // src/History/PixelMutator/mutatorBlendBinaryMask.ts
3181
- var defaults6 = {
3296
+ var defaults5 = {
3182
3297
  blendPixelDataBinaryMask
3183
3298
  };
3184
- var mutatorBlendBinaryMask = ((writer, deps = defaults6) => {
3299
+ var mutatorBlendBinaryMask = ((writer, deps = defaults5) => {
3185
3300
  const {
3186
- blendPixelDataBinaryMask: blendPixelDataBinaryMask2 = defaults6.blendPixelDataBinaryMask
3301
+ blendPixelDataBinaryMask: blendPixelDataBinaryMask2 = defaults5.blendPixelDataBinaryMask
3187
3302
  } = deps;
3188
3303
  return {
3189
3304
  blendBinaryMask(src, mask, opts) {
3190
3305
  const x = opts?.x ?? 0;
3191
3306
  const y = opts?.y ?? 0;
3192
- const w = opts?.w ?? src.width;
3193
- const h = opts?.h ?? src.height;
3307
+ const w = opts?.w ?? src.w;
3308
+ const h = opts?.h ?? src.h;
3194
3309
  const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h);
3195
3310
  return didChange(blendPixelDataBinaryMask2(writer.config.target, src, mask, opts));
3196
3311
  }
@@ -3201,8 +3316,8 @@ var mutatorBlendBinaryMask = ((writer, deps = defaults6) => {
3201
3316
  function blendColorPixelData(target, color, opts) {
3202
3317
  const targetX = opts?.x ?? 0;
3203
3318
  const targetY = opts?.y ?? 0;
3204
- const width = opts?.w ?? target.width;
3205
- const height = opts?.h ?? target.height;
3319
+ const width = opts?.w ?? target.w;
3320
+ const height = opts?.h ?? target.h;
3206
3321
  const globalAlpha = opts?.alpha ?? 255;
3207
3322
  const blendFn = opts?.blendFn ?? sourceOverPerfect;
3208
3323
  if (globalAlpha === 0) return false;
@@ -3221,8 +3336,8 @@ function blendColorPixelData(target, color, opts) {
3221
3336
  h += y;
3222
3337
  y = 0;
3223
3338
  }
3224
- const actualW = Math.min(w, target.width - x);
3225
- const actualH = Math.min(h, target.height - y);
3339
+ const actualW = Math.min(w, target.w - x);
3340
+ const actualH = Math.min(h, target.h - y);
3226
3341
  if (actualW <= 0 || actualH <= 0) return false;
3227
3342
  let finalSrcColor = color;
3228
3343
  if (globalAlpha < 255) {
@@ -3230,8 +3345,8 @@ function blendColorPixelData(target, color, opts) {
3230
3345
  if (a === 0 && !isOverwrite) return false;
3231
3346
  finalSrcColor = (color & 16777215 | a << 24) >>> 0;
3232
3347
  }
3233
- const dst32 = target.data32;
3234
- const dw = target.width;
3348
+ const dst32 = target.data;
3349
+ const dw = target.w;
3235
3350
  let dIdx = y * dw + x | 0;
3236
3351
  const dStride = dw - actualW | 0;
3237
3352
  let didChange = false;
@@ -3251,20 +3366,20 @@ function blendColorPixelData(target, color, opts) {
3251
3366
  }
3252
3367
 
3253
3368
  // src/History/PixelMutator/mutatorBlendColor.ts
3254
- var defaults7 = {
3369
+ var defaults6 = {
3255
3370
  blendColorPixelData
3256
3371
  };
3257
- var mutatorBlendColor = ((writer, deps = defaults7) => {
3372
+ var mutatorBlendColor = ((writer, deps = defaults6) => {
3258
3373
  const {
3259
- blendColorPixelData: blendColorPixelData2 = defaults7.blendColorPixelData
3374
+ blendColorPixelData: blendColorPixelData2 = defaults6.blendColorPixelData
3260
3375
  } = deps;
3261
3376
  return {
3262
3377
  blendColor(color, opts) {
3263
3378
  const target = writer.config.target;
3264
3379
  const x = opts?.x ?? 0;
3265
3380
  const y = opts?.y ?? 0;
3266
- const w = opts?.w ?? target.width;
3267
- const h = opts?.h ?? target.height;
3381
+ const w = opts?.w ?? target.w;
3382
+ const h = opts?.h ?? target.h;
3268
3383
  const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h);
3269
3384
  return didChange(blendColorPixelData2(target, color, opts));
3270
3385
  }
@@ -3298,13 +3413,13 @@ function blendColorPixelDataAlphaMask(target, color, mask, opts) {
3298
3413
  actualH += y;
3299
3414
  y = 0;
3300
3415
  }
3301
- actualW = Math.min(actualW, target.width - x);
3302
- actualH = Math.min(actualH, target.height - y);
3416
+ actualW = Math.min(actualW, target.w - x);
3417
+ actualH = Math.min(actualH, target.h - y);
3303
3418
  if (actualW <= 0 || actualH <= 0) return false;
3304
3419
  const dx = x - targetX | 0;
3305
3420
  const dy = y - targetY | 0;
3306
- const dst32 = target.data32;
3307
- const dw = target.width;
3421
+ const dst32 = target.data;
3422
+ const dw = target.w;
3308
3423
  const mPitch = mask.w;
3309
3424
  const maskData = mask.data;
3310
3425
  let dIdx = y * dw + x | 0;
@@ -3360,12 +3475,12 @@ function blendColorPixelDataAlphaMask(target, color, mask, opts) {
3360
3475
  }
3361
3476
 
3362
3477
  // src/History/PixelMutator/mutatorBlendColorPaintAlphaMask.ts
3363
- var defaults8 = {
3478
+ var defaults7 = {
3364
3479
  blendColorPixelDataAlphaMask
3365
3480
  };
3366
- var mutatorBlendColorPaintAlphaMask = ((writer, deps = defaults8) => {
3481
+ var mutatorBlendColorPaintAlphaMask = ((writer, deps = defaults7) => {
3367
3482
  const {
3368
- blendColorPixelDataAlphaMask: blendColorPixelDataAlphaMask2 = defaults8.blendColorPixelDataAlphaMask
3483
+ blendColorPixelDataAlphaMask: blendColorPixelDataAlphaMask2 = defaults7.blendColorPixelDataAlphaMask
3369
3484
  } = deps;
3370
3485
  const OPTS = {
3371
3486
  x: 0,
@@ -3412,8 +3527,8 @@ function blendColorPixelDataBinaryMask(target, color, mask, opts) {
3412
3527
  h += y;
3413
3528
  y = 0;
3414
3529
  }
3415
- const actualW = Math.min(w, target.width - x);
3416
- const actualH = Math.min(h, target.height - y);
3530
+ const actualW = Math.min(w, target.w - x);
3531
+ const actualH = Math.min(h, target.h - y);
3417
3532
  if (actualW <= 0 || actualH <= 0) return false;
3418
3533
  let baseColorWithGlobalAlpha = color;
3419
3534
  if (globalAlpha < 255) {
@@ -3423,8 +3538,8 @@ function blendColorPixelDataBinaryMask(target, color, mask, opts) {
3423
3538
  }
3424
3539
  const dx = x - targetX | 0;
3425
3540
  const dy = y - targetY | 0;
3426
- const dst32 = target.data32;
3427
- const dw = target.width;
3541
+ const dst32 = target.data;
3542
+ const dw = target.w;
3428
3543
  const mPitch = mask.w;
3429
3544
  const maskData = mask.data;
3430
3545
  let dIdx = y * dw + x | 0;
@@ -3456,12 +3571,12 @@ function blendColorPixelDataBinaryMask(target, color, mask, opts) {
3456
3571
  }
3457
3572
 
3458
3573
  // src/History/PixelMutator/mutatorBlendColorPaintBinaryMask.ts
3459
- var defaults9 = {
3574
+ var defaults8 = {
3460
3575
  blendColorPixelDataBinaryMask
3461
3576
  };
3462
- var mutatorBlendColorPaintBinaryMask = ((writer, deps = defaults9) => {
3577
+ var mutatorBlendColorPaintBinaryMask = ((writer, deps = defaults8) => {
3463
3578
  const {
3464
- blendColorPixelDataBinaryMask: blendColorPixelDataBinaryMask2 = defaults9.blendColorPixelDataBinaryMask
3579
+ blendColorPixelDataBinaryMask: blendColorPixelDataBinaryMask2 = defaults8.blendColorPixelDataBinaryMask
3465
3580
  } = deps;
3466
3581
  const OPTS = {
3467
3582
  x: 0,
@@ -3484,14 +3599,14 @@ var mutatorBlendColorPaintBinaryMask = ((writer, deps = defaults9) => {
3484
3599
  });
3485
3600
 
3486
3601
  // src/History/PixelMutator/mutatorBlendColorPaintMask.ts
3487
- var defaults10 = {
3602
+ var defaults9 = {
3488
3603
  blendColorPixelDataAlphaMask,
3489
3604
  blendColorPixelDataBinaryMask
3490
3605
  };
3491
- var mutatorBlendColorPaintMask = ((writer, deps = defaults10) => {
3606
+ var mutatorBlendColorPaintMask = ((writer, deps = defaults9) => {
3492
3607
  const {
3493
- blendColorPixelDataBinaryMask: blendColorPixelDataBinaryMask2 = defaults10.blendColorPixelDataBinaryMask,
3494
- blendColorPixelDataAlphaMask: blendColorPixelDataAlphaMask2 = defaults10.blendColorPixelDataAlphaMask
3608
+ blendColorPixelDataBinaryMask: blendColorPixelDataBinaryMask2 = defaults9.blendColorPixelDataBinaryMask,
3609
+ blendColorPixelDataAlphaMask: blendColorPixelDataAlphaMask2 = defaults9.blendColorPixelDataAlphaMask
3495
3610
  } = deps;
3496
3611
  const OPTS = {
3497
3612
  x: 0,
@@ -3517,39 +3632,13 @@ var mutatorBlendColorPaintMask = ((writer, deps = defaults10) => {
3517
3632
  };
3518
3633
  });
3519
3634
 
3520
- // src/History/PixelMutator/mutatorBlendMask.ts
3521
- var defaults11 = {
3522
- blendPixelDataAlphaMask,
3523
- blendPixelDataBinaryMask
3524
- };
3525
- var mutatorBlendMask = ((writer, deps = defaults11) => {
3526
- const {
3527
- blendPixelDataAlphaMask: blendPixelDataAlphaMask2 = defaults11.blendPixelDataAlphaMask,
3528
- blendPixelDataBinaryMask: blendPixelDataBinaryMask2 = defaults11.blendPixelDataBinaryMask
3529
- } = deps;
3530
- return {
3531
- blendMask(src, mask, opts) {
3532
- const x = opts?.x ?? 0;
3533
- const y = opts?.y ?? 0;
3534
- const w = opts?.w ?? src.width;
3535
- const h = opts?.h ?? src.height;
3536
- const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h);
3537
- if (mask.type === 1 /* BINARY */) {
3538
- return didChange(blendPixelDataBinaryMask2(writer.config.target, src, mask, opts));
3539
- } else {
3540
- return didChange(blendPixelDataAlphaMask2(writer.config.target, src, mask, opts));
3541
- }
3542
- }
3543
- };
3544
- });
3545
-
3546
3635
  // src/History/PixelMutator/mutatorBlendColorPaintRect.ts
3547
- var defaults12 = {
3636
+ var defaults10 = {
3548
3637
  blendColorPixelData
3549
3638
  };
3550
- var mutatorBlendColorPaintRect = ((writer, deps = defaults12) => {
3639
+ var mutatorBlendColorPaintRect = ((writer, deps = defaults10) => {
3551
3640
  const {
3552
- blendColorPixelData: blendColorPixelData2 = defaults12.blendColorPixelData
3641
+ blendColorPixelData: blendColorPixelData2 = defaults10.blendColorPixelData
3553
3642
  } = deps;
3554
3643
  const OPTS = {
3555
3644
  x: 0,
@@ -3576,16 +3665,42 @@ var mutatorBlendColorPaintRect = ((writer, deps = defaults12) => {
3576
3665
  };
3577
3666
  });
3578
3667
 
3668
+ // src/History/PixelMutator/mutatorBlendMask.ts
3669
+ var defaults11 = {
3670
+ blendPixelDataAlphaMask,
3671
+ blendPixelDataBinaryMask
3672
+ };
3673
+ var mutatorBlendMask = ((writer, deps = defaults11) => {
3674
+ const {
3675
+ blendPixelDataAlphaMask: blendPixelDataAlphaMask2 = defaults11.blendPixelDataAlphaMask,
3676
+ blendPixelDataBinaryMask: blendPixelDataBinaryMask2 = defaults11.blendPixelDataBinaryMask
3677
+ } = deps;
3678
+ return {
3679
+ blendMask(src, mask, opts) {
3680
+ const x = opts?.x ?? 0;
3681
+ const y = opts?.y ?? 0;
3682
+ const w = opts?.w ?? src.w;
3683
+ const h = opts?.h ?? src.h;
3684
+ const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h);
3685
+ if (mask.type === 1 /* BINARY */) {
3686
+ return didChange(blendPixelDataBinaryMask2(writer.config.target, src, mask, opts));
3687
+ } else {
3688
+ return didChange(blendPixelDataAlphaMask2(writer.config.target, src, mask, opts));
3689
+ }
3690
+ }
3691
+ };
3692
+ });
3693
+
3579
3694
  // src/PixelData/blendPixel.ts
3580
3695
  function blendPixel(target, x, y, color, alpha = 255, blendFn = sourceOverPerfect) {
3581
3696
  if (alpha === 0) return false;
3582
- let width = target.width;
3583
- let height = target.height;
3697
+ let width = target.w;
3698
+ let height = target.h;
3584
3699
  if (x < 0 || x >= width || y < 0 || y >= height) return false;
3585
3700
  let srcAlpha = color >>> 24;
3586
3701
  let isOverwrite = blendFn.isOverwrite;
3587
3702
  if (srcAlpha === 0 && !isOverwrite) return false;
3588
- let dst32 = target.data32;
3703
+ let dst32 = target.data;
3589
3704
  let index = y * width + x;
3590
3705
  let finalColor = color;
3591
3706
  if (alpha !== 255) {
@@ -3603,12 +3718,12 @@ function blendPixel(target, x, y, color, alpha = 255, blendFn = sourceOverPerfec
3603
3718
  }
3604
3719
 
3605
3720
  // src/History/PixelMutator/mutatorBlendPixel.ts
3606
- var defaults13 = {
3721
+ var defaults12 = {
3607
3722
  blendPixel
3608
3723
  };
3609
- var mutatorBlendPixel = ((writer, deps = defaults13) => {
3724
+ var mutatorBlendPixel = ((writer, deps = defaults12) => {
3610
3725
  const {
3611
- blendPixel: blendPixel2 = defaults13.blendPixel
3726
+ blendPixel: blendPixel2 = defaults12.blendPixel
3612
3727
  } = deps;
3613
3728
  return {
3614
3729
  blendPixel(x, y, color, alpha, blendFn) {
@@ -3618,20 +3733,107 @@ var mutatorBlendPixel = ((writer, deps = defaults13) => {
3618
3733
  };
3619
3734
  });
3620
3735
 
3736
+ // src/PixelData/blendPixelData.ts
3737
+ function blendPixelData(target, src, opts) {
3738
+ const targetX = opts?.x ?? 0;
3739
+ const targetY = opts?.y ?? 0;
3740
+ const sourceX = opts?.sx ?? 0;
3741
+ const sourceY = opts?.sy ?? 0;
3742
+ const width = opts?.w ?? src.w;
3743
+ const height = opts?.h ?? src.h;
3744
+ const globalAlpha = opts?.alpha ?? 255;
3745
+ const blendFn = opts?.blendFn ?? sourceOverPerfect;
3746
+ if (globalAlpha === 0) return false;
3747
+ let x = targetX;
3748
+ let y = targetY;
3749
+ let sx = sourceX;
3750
+ let sy = sourceY;
3751
+ let w = width;
3752
+ let h = height;
3753
+ if (sx < 0) {
3754
+ x -= sx;
3755
+ w += sx;
3756
+ sx = 0;
3757
+ }
3758
+ if (sy < 0) {
3759
+ y -= sy;
3760
+ h += sy;
3761
+ sy = 0;
3762
+ }
3763
+ w = Math.min(w, src.w - sx);
3764
+ h = Math.min(h, src.h - sy);
3765
+ if (x < 0) {
3766
+ sx -= x;
3767
+ w += x;
3768
+ x = 0;
3769
+ }
3770
+ if (y < 0) {
3771
+ sy -= y;
3772
+ h += y;
3773
+ y = 0;
3774
+ }
3775
+ const actualW = Math.min(w, target.w - x);
3776
+ const actualH = Math.min(h, target.h - y);
3777
+ if (actualW <= 0 || actualH <= 0) return false;
3778
+ const dst32 = target.data;
3779
+ const src32 = src.data;
3780
+ const dw = target.w;
3781
+ const sw = src.w;
3782
+ let dIdx = y * dw + x | 0;
3783
+ let sIdx = sy * sw + sx | 0;
3784
+ const dStride = dw - actualW | 0;
3785
+ const sStride = sw - actualW | 0;
3786
+ const isOpaque = globalAlpha === 255;
3787
+ const isOverwrite = blendFn.isOverwrite;
3788
+ let didChange = false;
3789
+ for (let iy = 0; iy < actualH; iy++) {
3790
+ for (let ix = 0; ix < actualW; ix++) {
3791
+ const srcCol = src32[sIdx];
3792
+ const srcAlpha = srcCol >>> 24;
3793
+ if (srcAlpha === 0 && !isOverwrite) {
3794
+ dIdx++;
3795
+ sIdx++;
3796
+ continue;
3797
+ }
3798
+ let finalCol = srcCol;
3799
+ if (!isOpaque) {
3800
+ const a = srcAlpha * globalAlpha + 128 >> 8;
3801
+ if (a === 0 && !isOverwrite) {
3802
+ dIdx++;
3803
+ sIdx++;
3804
+ continue;
3805
+ }
3806
+ finalCol = (srcCol & 16777215 | a << 24) >>> 0;
3807
+ }
3808
+ const current = dst32[dIdx];
3809
+ const next = blendFn(finalCol, dst32[dIdx]);
3810
+ if (current !== next) {
3811
+ dst32[dIdx] = next;
3812
+ didChange = true;
3813
+ }
3814
+ dIdx++;
3815
+ sIdx++;
3816
+ }
3817
+ dIdx += dStride;
3818
+ sIdx += sStride;
3819
+ }
3820
+ return didChange;
3821
+ }
3822
+
3621
3823
  // src/History/PixelMutator/mutatorBlendPixelData.ts
3622
- var defaults14 = {
3824
+ var defaults13 = {
3623
3825
  blendPixelData
3624
3826
  };
3625
- var mutatorBlendPixelData = ((writer, deps = defaults14) => {
3827
+ var mutatorBlendPixelData = ((writer, deps = defaults13) => {
3626
3828
  const {
3627
- blendPixelData: blendPixelData2 = defaults14.blendPixelData
3829
+ blendPixelData: blendPixelData2 = defaults13.blendPixelData
3628
3830
  } = deps;
3629
3831
  return {
3630
3832
  blendPixelData(src, opts) {
3631
3833
  const x = opts?.x ?? 0;
3632
3834
  const y = opts?.y ?? 0;
3633
- const w = opts?.w ?? src.width;
3634
- const h = opts?.h ?? src.height;
3835
+ const w = opts?.w ?? src.w;
3836
+ const h = opts?.h ?? src.h;
3635
3837
  const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h);
3636
3838
  return didChange(blendPixelData2(writer.config.target, src, opts));
3637
3839
  }
@@ -3648,8 +3850,8 @@ function fillPixelData(dst, color, _x, _y, _w, _h) {
3648
3850
  if (typeof _x === "object") {
3649
3851
  x = _x.x ?? 0;
3650
3852
  y = _x.y ?? 0;
3651
- w = _x.w ?? dst.width;
3652
- h = _x.h ?? dst.height;
3853
+ w = _x.w ?? dst.w;
3854
+ h = _x.h ?? dst.h;
3653
3855
  } else if (typeof _x === "number") {
3654
3856
  x = _x;
3655
3857
  y = _y;
@@ -3658,10 +3860,10 @@ function fillPixelData(dst, color, _x, _y, _w, _h) {
3658
3860
  } else {
3659
3861
  x = 0;
3660
3862
  y = 0;
3661
- w = dst.width;
3662
- h = dst.height;
3863
+ w = dst.w;
3864
+ h = dst.h;
3663
3865
  }
3664
- const clip = resolveRectClipping(x, y, w, h, dst.width, dst.height, SCRATCH_RECT);
3866
+ const clip = resolveRectClipping(x, y, w, h, dst.w, dst.h, SCRATCH_RECT);
3665
3867
  if (!clip.inBounds) return false;
3666
3868
  const {
3667
3869
  x: finalX,
@@ -3669,8 +3871,8 @@ function fillPixelData(dst, color, _x, _y, _w, _h) {
3669
3871
  w: actualW,
3670
3872
  h: actualH
3671
3873
  } = clip;
3672
- const dst32 = dst.data32;
3673
- const dw = dst.width;
3874
+ const dst32 = dst.data;
3875
+ const dw = dst.w;
3674
3876
  let hasChanged = false;
3675
3877
  for (let iy = 0; iy < actualH; iy++) {
3676
3878
  const rowOffset = (finalY + iy) * dw;
@@ -3687,20 +3889,20 @@ function fillPixelData(dst, color, _x, _y, _w, _h) {
3687
3889
  }
3688
3890
 
3689
3891
  // src/History/PixelMutator/mutatorClear.ts
3690
- var defaults15 = {
3892
+ var defaults14 = {
3691
3893
  fillPixelData
3692
3894
  };
3693
- var mutatorClear = ((writer, deps = defaults15) => {
3895
+ var mutatorClear = ((writer, deps = defaults14) => {
3694
3896
  const {
3695
- fillPixelData: fillPixelData2 = defaults15.fillPixelData
3897
+ fillPixelData: fillPixelData2 = defaults14.fillPixelData
3696
3898
  } = deps;
3697
3899
  return {
3698
3900
  clear(rect) {
3699
3901
  const target = writer.config.target;
3700
3902
  const x = rect?.x ?? 0;
3701
3903
  const y = rect?.y ?? 0;
3702
- const w = rect?.w ?? target.width;
3703
- const h = rect?.h ?? target.height;
3904
+ const w = rect?.w ?? target.w;
3905
+ const h = rect?.h ?? target.h;
3704
3906
  const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h);
3705
3907
  return didChange(fillPixelData2(target, 0, x, y, w, h));
3706
3908
  }
@@ -3708,24 +3910,24 @@ var mutatorClear = ((writer, deps = defaults15) => {
3708
3910
  });
3709
3911
 
3710
3912
  // src/History/PixelMutator/mutatorFill.ts
3711
- var defaults16 = {
3913
+ var defaults15 = {
3712
3914
  fillPixelData
3713
3915
  };
3714
- var mutatorFill = ((writer, deps = defaults16) => {
3916
+ var mutatorFill = ((writer, deps = defaults15) => {
3715
3917
  const {
3716
- fillPixelData: fillPixelData2 = defaults16.fillPixelData
3918
+ fillPixelData: fillPixelData2 = defaults15.fillPixelData
3717
3919
  } = deps;
3718
3920
  return {
3719
- fill(color, x = 0, y = 0, w = writer.config.target.width, h = writer.config.target.height) {
3921
+ fill(color, x = 0, y = 0, w = writer.config.target.w, h = writer.config.target.h) {
3720
3922
  const target = writer.config.target;
3721
3923
  const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h);
3722
3924
  return didChange(fillPixelData2(target, color, x, y, w, h));
3723
3925
  }
3724
3926
  };
3725
3927
  });
3726
- var mutatorFillRect = ((writer, deps = defaults16) => {
3928
+ var mutatorFillRect = ((writer, deps = defaults15) => {
3727
3929
  const {
3728
- fillPixelData: fillPixelData2 = defaults16.fillPixelData
3930
+ fillPixelData: fillPixelData2 = defaults15.fillPixelData
3729
3931
  } = deps;
3730
3932
  return {
3731
3933
  fillRect(color, rect) {
@@ -3741,7 +3943,7 @@ var SCRATCH_RECT2 = makeClippedRect();
3741
3943
  function fillPixelDataBinaryMask(target, color, mask, x = 0, y = 0) {
3742
3944
  const maskW = mask.w;
3743
3945
  const maskH = mask.h;
3744
- const clip = resolveRectClipping(x, y, maskW, maskH, target.width, target.height, SCRATCH_RECT2);
3946
+ const clip = resolveRectClipping(x, y, maskW, maskH, target.w, target.h, SCRATCH_RECT2);
3745
3947
  if (!clip.inBounds) return false;
3746
3948
  const {
3747
3949
  x: finalX,
@@ -3750,8 +3952,8 @@ function fillPixelDataBinaryMask(target, color, mask, x = 0, y = 0) {
3750
3952
  h: actualH
3751
3953
  } = clip;
3752
3954
  const maskData = mask.data;
3753
- const dst32 = target.data32;
3754
- const dw = target.width;
3955
+ const dst32 = target.data;
3956
+ const dw = target.w;
3755
3957
  let hasChanged = false;
3756
3958
  for (let iy = 0; iy < actualH; iy++) {
3757
3959
  const currentY = finalY + iy;
@@ -3775,12 +3977,12 @@ function fillPixelDataBinaryMask(target, color, mask, x = 0, y = 0) {
3775
3977
  }
3776
3978
 
3777
3979
  // src/History/PixelMutator/mutatorFillBinaryMask.ts
3778
- var defaults17 = {
3980
+ var defaults16 = {
3779
3981
  fillPixelDataBinaryMask
3780
3982
  };
3781
- var mutatorFillBinaryMask = ((writer, deps = defaults17) => {
3983
+ var mutatorFillBinaryMask = ((writer, deps = defaults16) => {
3782
3984
  const {
3783
- fillPixelDataBinaryMask: fillPixelDataBinaryMask2 = defaults17.fillPixelDataBinaryMask
3985
+ fillPixelDataBinaryMask: fillPixelDataBinaryMask2 = defaults16.fillPixelDataBinaryMask
3784
3986
  } = deps;
3785
3987
  return {
3786
3988
  fillBinaryMask(color, mask, x = 0, y = 0) {
@@ -3798,10 +4000,10 @@ function invertPixelData(target, opts) {
3798
4000
  const targetY = opts?.y ?? 0;
3799
4001
  const mx = opts?.mx ?? 0;
3800
4002
  const my = opts?.my ?? 0;
3801
- const width = opts?.w ?? target.width;
3802
- const height = opts?.h ?? target.height;
4003
+ const width = opts?.w ?? target.w;
4004
+ const height = opts?.h ?? target.h;
3803
4005
  const invertMask = opts?.invertMask ?? false;
3804
- const clip = resolveRectClipping(targetX, targetY, width, height, target.width, target.height, SCRATCH_RECT3);
4006
+ const clip = resolveRectClipping(targetX, targetY, width, height, target.w, target.h, SCRATCH_RECT3);
3805
4007
  if (!clip.inBounds) return false;
3806
4008
  const {
3807
4009
  x,
@@ -3809,8 +4011,8 @@ function invertPixelData(target, opts) {
3809
4011
  w: actualW,
3810
4012
  h: actualH
3811
4013
  } = clip;
3812
- const dst32 = target.data32;
3813
- const dw = target.width;
4014
+ const dst32 = target.data;
4015
+ const dw = target.w;
3814
4016
  const mPitch = mask?.w ?? width;
3815
4017
  const dx = x - targetX;
3816
4018
  const dy = y - targetY;
@@ -3846,20 +4048,20 @@ function invertPixelData(target, opts) {
3846
4048
  }
3847
4049
 
3848
4050
  // src/History/PixelMutator/mutatorInvert.ts
3849
- var defaults18 = {
4051
+ var defaults17 = {
3850
4052
  invertPixelData
3851
4053
  };
3852
- var mutatorInvert = ((writer, deps = defaults18) => {
4054
+ var mutatorInvert = ((writer, deps = defaults17) => {
3853
4055
  const {
3854
- invertPixelData: invertPixelData2 = defaults18.invertPixelData
4056
+ invertPixelData: invertPixelData2 = defaults17.invertPixelData
3855
4057
  } = deps;
3856
4058
  return {
3857
4059
  invert(opts) {
3858
4060
  const target = writer.config.target;
3859
4061
  const x = opts?.x ?? 0;
3860
4062
  const y = opts?.y ?? 0;
3861
- const w = opts?.w ?? target.width;
3862
- const h = opts?.h ?? target.height;
4063
+ const w = opts?.w ?? target.w;
4064
+ const h = opts?.h ?? target.h;
3863
4065
  const didChange = writer.accumulator.storeRegionBeforeState(x, y, w, h);
3864
4066
  return didChange(invertPixelData2(target, opts));
3865
4067
  }
@@ -3891,30 +4093,6 @@ function makeFullPixelMutator(writer) {
3891
4093
  };
3892
4094
  }
3893
4095
 
3894
- // src/ImageData/ImageDataLike.ts
3895
- function makeImageDataLike(width, height, data) {
3896
- const size = width * height * 4;
3897
- const buffer = data ? new Uint8ClampedArray(data.buffer, data.byteOffset, size) : new Uint8ClampedArray(size);
3898
- return {
3899
- width,
3900
- height,
3901
- data: buffer
3902
- };
3903
- }
3904
-
3905
- // src/ImageData/ReusableImageData.ts
3906
- function makeReusableImageData() {
3907
- let imageData = null;
3908
- return function getReusableImageData(width, height) {
3909
- if (imageData === null || imageData.width !== width || imageData.height !== height) {
3910
- imageData = new ImageData(width, height);
3911
- } else {
3912
- imageData.data.fill(0);
3913
- }
3914
- return imageData;
3915
- };
3916
- }
3917
-
3918
4096
  // src/ImageData/copyImageData.ts
3919
4097
  function copyImageData({
3920
4098
  data,
@@ -3935,6 +4113,17 @@ function copyImageDataLike({
3935
4113
  };
3936
4114
  }
3937
4115
 
4116
+ // src/ImageData/ImageDataLike.ts
4117
+ function makeImageDataLike(width, height, data) {
4118
+ const size = width * height * 4;
4119
+ const buffer = data ? new Uint8ClampedArray(data.buffer, data.byteOffset, size) : new Uint8ClampedArray(size);
4120
+ return {
4121
+ width,
4122
+ height,
4123
+ data: buffer
4124
+ };
4125
+ }
4126
+
3938
4127
  // src/ImageData/imageDataToAlphaMaskBuffer.ts
3939
4128
  function imageDataToAlphaMaskBuffer(imageData) {
3940
4129
  const {
@@ -3964,8 +4153,8 @@ function imageDataToDataUrl(imageData) {
3964
4153
  }
3965
4154
  imageDataToDataUrl.reset = get.reset;
3966
4155
 
3967
- // src/ImageData/imageDataToUInt32Array.ts
3968
- function imageDataToUInt32Array(imageData) {
4156
+ // src/ImageData/imageDataToUint32Array.ts
4157
+ function imageDataToUint32Array(imageData) {
3969
4158
  return new Uint32Array(
3970
4159
  imageData.data.buffer,
3971
4160
  imageData.data.byteOffset,
@@ -3986,43 +4175,29 @@ function invertImageData(imageData) {
3986
4175
  return imageData;
3987
4176
  }
3988
4177
 
3989
- // src/Internal/resample32.ts
3990
- var resample32Scratch = {
3991
- data: null,
3992
- width: 0,
3993
- height: 0
3994
- };
3995
- function resample32(srcData32, srcW, srcH, factor) {
3996
- const dstW = Math.max(1, srcW * factor | 0);
3997
- const dstH = Math.max(1, srcH * factor | 0);
3998
- const dstData = new Int32Array(dstW * dstH);
3999
- const scaleX = srcW / dstW;
4000
- const scaleY = srcH / dstH;
4001
- for (let y = 0; y < dstH; y++) {
4002
- const srcY = Math.min(srcH - 1, y * scaleY | 0);
4003
- const srcRowOffset = srcY * srcW;
4004
- const dstRowOffset = y * dstW;
4005
- for (let x = 0; x < dstW; x++) {
4006
- const srcX = Math.min(srcW - 1, x * scaleX | 0);
4007
- dstData[dstRowOffset + x] = srcData32[srcRowOffset + srcX];
4008
- }
4009
- }
4010
- resample32Scratch.data = dstData;
4011
- resample32Scratch.width = dstW;
4012
- resample32Scratch.height = dstH;
4013
- return resample32Scratch;
4014
- }
4015
-
4016
4178
  // src/ImageData/resampleImageData.ts
4017
4179
  function resampleImageData(source, factor) {
4018
4180
  const src32 = new Uint32Array(source.data.buffer);
4019
4181
  const {
4020
4182
  data,
4021
- width,
4022
- height
4023
- } = resample32(src32, source.width, source.height, factor);
4183
+ w,
4184
+ h
4185
+ } = resampleUint32Array(src32, source.width, source.height, factor);
4024
4186
  const uint8ClampedArray = new Uint8ClampedArray(data.buffer);
4025
- return new ImageData(uint8ClampedArray, width, height);
4187
+ return new ImageData(uint8ClampedArray, w, h);
4188
+ }
4189
+
4190
+ // src/ImageData/ReusableImageData.ts
4191
+ function makeReusableImageData() {
4192
+ let imageData = null;
4193
+ return function getReusableImageData(width, height) {
4194
+ if (imageData === null || imageData.width !== width || imageData.height !== height) {
4195
+ imageData = new ImageData(width, height);
4196
+ } else {
4197
+ imageData.data.fill(0);
4198
+ }
4199
+ return imageData;
4200
+ };
4026
4201
  }
4027
4202
 
4028
4203
  // src/ImageData/serialization.ts
@@ -4179,89 +4354,11 @@ function writeImageDataBuffer(target, data, _x, _y, _w, _h) {
4179
4354
  }
4180
4355
  }
4181
4356
 
4182
- // src/IndexedImage/IndexedImage.ts
4183
- var IndexedImage = class _IndexedImage {
4184
- /** The width of the image in pixels. */
4185
- width;
4186
- /** The height of the image in pixels. */
4187
- height;
4188
- /** Flat array of palette indices. Index = x + (y * width). */
4189
- data;
4190
- /** The palette of unique 32-bit colors (ABGR/RGBA packed) found in the image. */
4191
- palette;
4192
- /** The specific index in the palette reserved for fully transparent pixels. */
4193
- transparentPalletIndex;
4194
- /**
4195
- * @param width - Image width.
4196
- * @param height - Image height.
4197
- * @param data - The indexed pixel data.
4198
- * @param palette - The array of packed colors.
4199
- * @param transparentPalletIndex - The index representing alpha 0.
4200
- */
4201
- constructor(width, height, data, palette, transparentPalletIndex) {
4202
- this.width = width;
4203
- this.height = height;
4204
- this.data = data;
4205
- this.palette = palette;
4206
- this.transparentPalletIndex = transparentPalletIndex;
4207
- }
4208
- /**
4209
- * Creates an IndexedImage from standard browser ImageData.
4210
- * @param imageData - The source ImageData to convert.
4211
- * @returns A new IndexedImage instance.
4212
- */
4213
- static fromImageData(imageData) {
4214
- return _IndexedImage.fromRaw(imageData.data, imageData.width, imageData.height);
4215
- }
4216
- /**
4217
- * Creates an IndexedImage from a raw byte buffer and dimensions.
4218
- * Any pixel with an alpha channel of 0 is normalized to the transparent palette index.
4219
- * @param data - Raw RGBA byte data.
4220
- * @param width - Image width.
4221
- * @param height - Image height.
4222
- * @returns A new IndexedImage instance.
4223
- */
4224
- static fromRaw(data, width, height) {
4225
- const buffer = data.buffer;
4226
- const rawData = new Uint32Array(buffer);
4227
- const indexedData = new Int32Array(rawData.length);
4228
- const colorMap = /* @__PURE__ */ new Map();
4229
- const transparentColor = 0;
4230
- const transparentPalletIndex = 0;
4231
- colorMap.set(transparentColor, transparentPalletIndex);
4232
- for (let i = 0; i < rawData.length; i++) {
4233
- const pixel = rawData[i];
4234
- const alpha = pixel >>> 24 & 255;
4235
- const isTransparent = alpha === 0;
4236
- const colorKey = isTransparent ? transparentColor : pixel >>> 0;
4237
- let id = colorMap.get(colorKey);
4238
- if (id === void 0) {
4239
- id = colorMap.size;
4240
- colorMap.set(colorKey, id);
4241
- }
4242
- indexedData[i] = id;
4243
- }
4244
- const palette = Uint32Array.from(colorMap.keys());
4245
- return new _IndexedImage(width, height, indexedData, palette, transparentPalletIndex);
4246
- }
4247
- /**
4248
- * Retrieves the 32-bit packed color value at the given coordinates.
4249
- * @param x - X coordinate.
4250
- * @param y - Y coordinate.
4251
- * @returns The packed color from the palette.
4252
- */
4253
- getColorAt(x, y) {
4254
- const index = x + y * this.width;
4255
- const paletteIndex = this.data[index];
4256
- return this.palette[paletteIndex];
4257
- }
4258
- };
4259
-
4260
4357
  // src/IndexedImage/getIndexedImageColorCounts.ts
4261
4358
  function getIndexedImageColorCounts(indexedImage) {
4262
4359
  const data = indexedImage.data;
4263
4360
  const palette = indexedImage.palette;
4264
- const frequencies = new Int32Array(palette.length);
4361
+ const frequencies = new Uint32Array(palette.length);
4265
4362
  for (let i = 0; i < data.length; i++) {
4266
4363
  const colorIndex = data[i];
4267
4364
  frequencies[colorIndex]++;
@@ -4269,19 +4366,61 @@ function getIndexedImageColorCounts(indexedImage) {
4269
4366
  return frequencies;
4270
4367
  }
4271
4368
 
4272
- // src/IndexedImage/indexedImageToAverageColor.ts
4273
- function indexedImageToAverageColor(indexedImage, includeTransparent = false) {
4274
- const {
4369
+ // src/IndexedImage/IndexedImage.ts
4370
+ function makeIndexedImage(width, height, data, palette, transparentPalletIndex) {
4371
+ return {
4372
+ w: width,
4373
+ h: height,
4275
4374
  data,
4276
4375
  palette,
4277
4376
  transparentPalletIndex
4278
- } = indexedImage;
4279
- const counts = new Uint32Array(palette.length);
4280
- for (let i = 0; i < data.length; i++) {
4281
- const id = data[i];
4282
- counts[id]++;
4283
- }
4284
- let rSum = 0;
4377
+ };
4378
+ }
4379
+ function makeIndexedImageFromImageDataRaw(data, width, height) {
4380
+ const buffer = data.buffer;
4381
+ const rawData = new Uint32Array(buffer);
4382
+ const indexedData = new Uint32Array(rawData.length);
4383
+ const colorMap = /* @__PURE__ */ new Map();
4384
+ const transparentColor = 0;
4385
+ const transparentPalletIndex = 0;
4386
+ colorMap.set(transparentColor, transparentPalletIndex);
4387
+ for (let i = 0; i < rawData.length; i++) {
4388
+ const pixel = rawData[i];
4389
+ const alpha = pixel >>> 24 & 255;
4390
+ const isTransparent = alpha === 0;
4391
+ const colorKey = isTransparent ? transparentColor : pixel >>> 0;
4392
+ let id = colorMap.get(colorKey);
4393
+ if (id === void 0) {
4394
+ id = colorMap.size;
4395
+ colorMap.set(colorKey, id);
4396
+ }
4397
+ indexedData[i] = id;
4398
+ }
4399
+ const palette = Uint32Array.from(colorMap.keys());
4400
+ return makeIndexedImage(width, height, indexedData, palette, transparentPalletIndex);
4401
+ }
4402
+ function makeIndexedImageFromImageData(imageData) {
4403
+ return makeIndexedImageFromImageDataRaw(imageData.data, imageData.width, imageData.height);
4404
+ }
4405
+ function getIndexedImageColor(target, x, y) {
4406
+ const index = x + y * target.w;
4407
+ const paletteIndex = target.data[index];
4408
+ return target.palette[paletteIndex];
4409
+ }
4410
+
4411
+ // src/IndexedImage/indexedImageToAverageColor.ts
4412
+ function indexedImageToAverageColor(indexedImage, includeTransparent = false) {
4413
+ const {
4414
+ data,
4415
+ palette,
4416
+ transparentPalletIndex
4417
+ } = indexedImage;
4418
+ const counts = new Uint32Array(palette.length);
4419
+ for (let i = 0; i < data.length; i++) {
4420
+ const id = data[i];
4421
+ counts[id]++;
4422
+ }
4423
+ let rSum = 0;
4285
4424
  let gSum = 0;
4286
4425
  let bSum = 0;
4287
4426
  let aSum = 0;
@@ -4318,29 +4457,27 @@ function indexedImageToAverageColor(indexedImage, includeTransparent = false) {
4318
4457
  // src/IndexedImage/indexedImageToImageData.ts
4319
4458
  function indexedImageToImageData(indexedImage) {
4320
4459
  const {
4321
- width,
4322
- height,
4460
+ w,
4461
+ h,
4323
4462
  data,
4324
4463
  palette
4325
4464
  } = indexedImage;
4326
- const result = new ImageData(width, height);
4465
+ const result = new ImageData(w, h);
4327
4466
  const data32 = new Uint32Array(result.data.buffer);
4328
4467
  for (let i = 0; i < data.length; i++) {
4329
4468
  const paletteIndex = data[i];
4330
- const color = palette[paletteIndex];
4331
- data32[i] = color;
4469
+ data32[i] = palette[paletteIndex];
4332
4470
  }
4333
4471
  return result;
4334
4472
  }
4335
4473
 
4336
4474
  // src/IndexedImage/resampleIndexedImage.ts
4337
4475
  function resampleIndexedImage(source, factor) {
4338
- const {
4339
- data,
4340
- width,
4341
- height
4342
- } = resample32(source.data, source.width, source.height, factor);
4343
- return new IndexedImage(width, height, data, source.palette, source.transparentPalletIndex);
4476
+ const output = {
4477
+ palette: source.palette,
4478
+ transparentPalletIndex: source.transparentPalletIndex
4479
+ };
4480
+ return resampleUint32Array(source.data, source.w, source.h, factor, output);
4344
4481
  }
4345
4482
 
4346
4483
  // src/Input/fileInputChangeToImageData.ts
@@ -4416,16 +4553,6 @@ function makeAlphaMask(w, h, data) {
4416
4553
  };
4417
4554
  }
4418
4555
 
4419
- // src/Mask/BinaryMask.ts
4420
- function makeBinaryMask(w, h, data) {
4421
- return {
4422
- type: 1 /* BINARY */,
4423
- data: data ?? new Uint8Array(w * h),
4424
- w,
4425
- h
4426
- };
4427
- }
4428
-
4429
4556
  // src/Mask/applyBinaryMaskToAlphaMask.ts
4430
4557
  function applyBinaryMaskToAlphaMask(alphaMaskDst, binaryMaskSrc, opts) {
4431
4558
  const targetX = opts?.x ?? 0;
@@ -4495,6 +4622,215 @@ function applyBinaryMaskToAlphaMask(alphaMaskDst, binaryMaskSrc, opts) {
4495
4622
  }
4496
4623
  }
4497
4624
 
4625
+ // src/Mask/BinaryMask.ts
4626
+ function makeBinaryMask(w, h, data) {
4627
+ return {
4628
+ type: 1 /* BINARY */,
4629
+ data: data ?? new Uint8Array(w * h),
4630
+ w,
4631
+ h
4632
+ };
4633
+ }
4634
+
4635
+ // src/Mask/BinaryMask/makeBinaryMaskFromAlphaMask.ts
4636
+ function makeBinaryMaskFromAlphaMask(mask, threshold, out) {
4637
+ const w = mask.w;
4638
+ const h = mask.h;
4639
+ const alphaData = mask.data;
4640
+ const area = w * h;
4641
+ const binaryData = new Uint8Array(area);
4642
+ for (let i = 0; i < area; i++) {
4643
+ if (alphaData[i] >= threshold) {
4644
+ binaryData[i] = 1;
4645
+ }
4646
+ }
4647
+ out = out ?? {
4648
+ type: 1 /* BINARY */
4649
+ };
4650
+ out.data = binaryData;
4651
+ out.w = w;
4652
+ out.h = h;
4653
+ return out;
4654
+ }
4655
+
4656
+ // src/Mask/BinaryMask/makeBinaryMaskOutline.ts
4657
+ function makeBinaryMaskOutline(mask, scale = 1) {
4658
+ const w = mask.w;
4659
+ const h = mask.h;
4660
+ const maskData = mask.data;
4661
+ const size = w * scale + 2;
4662
+ const outData = new Uint8Array(size * size);
4663
+ for (let iy = 0; iy < h; iy++) {
4664
+ for (let ix = 0; ix < w; ix++) {
4665
+ const i = iy * w + ix;
4666
+ if (maskData[i] === 0) continue;
4667
+ const lx = ix * scale + 1;
4668
+ const ly = iy * scale + 1;
4669
+ const top = iy === 0 || maskData[i - w] === 0;
4670
+ const bottom = iy === h - 1 || maskData[i + w] === 0;
4671
+ const left = ix === 0 || maskData[i - 1] === 0;
4672
+ const right = ix === w - 1 || maskData[i + 1] === 0;
4673
+ const topLeft = iy === 0 || ix === 0 || maskData[i - w - 1] === 0;
4674
+ const topRight = iy === 0 || ix === w - 1 || maskData[i - w + 1] === 0;
4675
+ const bottomLeft = iy === h - 1 || ix === 0 || maskData[i + w - 1] === 0;
4676
+ const bottomRight = iy === h - 1 || ix === w - 1 || maskData[i + w + 1] === 0;
4677
+ if (top) {
4678
+ for (let sx = 0; sx < scale; sx++) {
4679
+ const outIdx = (ly - 1) * size + (lx + sx);
4680
+ outData[outIdx] = 1;
4681
+ }
4682
+ }
4683
+ if (bottom) {
4684
+ for (let sx = 0; sx < scale; sx++) {
4685
+ const outIdx = (ly + scale) * size + (lx + sx);
4686
+ outData[outIdx] = 1;
4687
+ }
4688
+ }
4689
+ if (left) {
4690
+ for (let sy = 0; sy < scale; sy++) {
4691
+ const outIdx = (ly + sy) * size + (lx - 1);
4692
+ outData[outIdx] = 1;
4693
+ }
4694
+ }
4695
+ if (right) {
4696
+ for (let sy = 0; sy < scale; sy++) {
4697
+ const outIdx = (ly + sy) * size + (lx + scale);
4698
+ outData[outIdx] = 1;
4699
+ }
4700
+ }
4701
+ if (topLeft) {
4702
+ const outIdx = (ly - 1) * size + (lx - 1);
4703
+ outData[outIdx] = 1;
4704
+ }
4705
+ if (topRight) {
4706
+ const outIdx = (ly - 1) * size + (lx + scale);
4707
+ outData[outIdx] = 1;
4708
+ }
4709
+ if (bottomLeft) {
4710
+ const outIdx = (ly + scale) * size + (lx - 1);
4711
+ outData[outIdx] = 1;
4712
+ }
4713
+ if (bottomRight) {
4714
+ const outIdx = (ly + scale) * size + (lx + scale);
4715
+ outData[outIdx] = 1;
4716
+ }
4717
+ }
4718
+ }
4719
+ return {
4720
+ type: 1 /* BINARY */,
4721
+ w: size,
4722
+ h: size,
4723
+ data: outData
4724
+ };
4725
+ }
4726
+
4727
+ // src/Mask/BinaryMask/makeCircleBinaryMaskOutline.ts
4728
+ function makeCircleBinaryMaskOutline(size, scale) {
4729
+ const outSize = size * scale + 2;
4730
+ const outArea = outSize * outSize;
4731
+ const data = new Uint8Array(outArea);
4732
+ const radius = size / 2;
4733
+ const r2 = radius * radius;
4734
+ let prevMinX = -1;
4735
+ let prevMaxX = -1;
4736
+ let currMinX = -1;
4737
+ let currMaxX = -1;
4738
+ const initialDy = 0 - radius + 0.5;
4739
+ const initialDy2 = initialDy * initialDy;
4740
+ if (initialDy2 <= r2) {
4741
+ const dx = Math.sqrt(r2 - initialDy2);
4742
+ currMinX = Math.ceil(radius - 0.5 - dx);
4743
+ currMaxX = Math.floor(radius - 0.5 + dx);
4744
+ }
4745
+ for (let iy = 0; iy < size; iy++) {
4746
+ let nextMinX = -1;
4747
+ let nextMaxX = -1;
4748
+ if (iy + 1 < size) {
4749
+ const ny = iy + 1 - radius + 0.5;
4750
+ const ny2 = ny * ny;
4751
+ if (ny2 <= r2) {
4752
+ const dx = Math.sqrt(r2 - ny2);
4753
+ nextMinX = Math.ceil(radius - 0.5 - dx);
4754
+ nextMaxX = Math.floor(radius - 0.5 + dx);
4755
+ }
4756
+ }
4757
+ if (currMinX !== -1) {
4758
+ for (let ix = currMinX; ix <= currMaxX; ix++) {
4759
+ const sx = ix * scale + 1;
4760
+ const sy = iy * scale + 1;
4761
+ const isTop = prevMinX === -1 || ix < prevMinX || ix > prevMaxX;
4762
+ const isBottom = nextMinX === -1 || ix < nextMinX || ix > nextMaxX;
4763
+ const isLeft = ix === currMinX;
4764
+ const isRight = ix === currMaxX;
4765
+ if (isTop) {
4766
+ const leftOut = prevMinX === -1 || ix - 1 < prevMinX || ix - 1 > prevMaxX;
4767
+ const rightOut = prevMinX === -1 || ix + 1 < prevMinX || ix + 1 > prevMaxX;
4768
+ const startX = leftOut ? sx - 1 : sx;
4769
+ const endX = rightOut ? sx + scale : sx + scale - 1;
4770
+ for (let x = startX; x <= endX; x++) {
4771
+ const index = (sy - 1) * outSize + x;
4772
+ data[index] = 1;
4773
+ }
4774
+ }
4775
+ if (isBottom) {
4776
+ const leftOut = nextMinX === -1 || ix - 1 < nextMinX || ix - 1 > nextMaxX;
4777
+ const rightOut = nextMinX === -1 || ix + 1 < nextMinX || ix + 1 > nextMaxX;
4778
+ const startX = leftOut ? sx - 1 : sx;
4779
+ const endX = rightOut ? sx + scale : sx + scale - 1;
4780
+ for (let x = startX; x <= endX; x++) {
4781
+ const index = (sy + scale) * outSize + x;
4782
+ data[index] = 1;
4783
+ }
4784
+ }
4785
+ if (isLeft) {
4786
+ for (let y = sy; y < sy + scale; y++) {
4787
+ const index = y * outSize + (sx - 1);
4788
+ data[index] = 1;
4789
+ }
4790
+ }
4791
+ if (isRight) {
4792
+ for (let y = sy; y < sy + scale; y++) {
4793
+ const index = y * outSize + (sx + scale);
4794
+ data[index] = 1;
4795
+ }
4796
+ }
4797
+ }
4798
+ }
4799
+ prevMinX = currMinX;
4800
+ prevMaxX = currMaxX;
4801
+ currMinX = nextMinX;
4802
+ currMaxX = nextMaxX;
4803
+ }
4804
+ return {
4805
+ type: 1 /* BINARY */,
4806
+ w: outSize,
4807
+ h: outSize,
4808
+ data
4809
+ };
4810
+ }
4811
+
4812
+ // src/Mask/BinaryMask/makeRectBinaryMaskOutline.ts
4813
+ function makeRectBinaryMaskOutline(w, h, scale = 1) {
4814
+ const rw = w * scale;
4815
+ const rh = h * scale;
4816
+ const outW = rw + 2;
4817
+ const outH = rh + 2;
4818
+ const outData = new Uint8Array(outW * outH);
4819
+ outData.fill(1, 0, outW);
4820
+ outData.fill(1, (outH - 1) * outW, outH * outW);
4821
+ for (let iy = 1; iy < outH - 1; iy++) {
4822
+ const rowStart = iy * outW;
4823
+ outData[rowStart] = 1;
4824
+ outData[rowStart + outW - 1] = 1;
4825
+ }
4826
+ return {
4827
+ type: 1 /* BINARY */,
4828
+ w: outW,
4829
+ h: outH,
4830
+ data: outData
4831
+ };
4832
+ }
4833
+
4498
4834
  // src/Mask/copyMask.ts
4499
4835
  function copyMask(src) {
4500
4836
  return {
@@ -4602,7 +4938,8 @@ function mergeAlphaMasks(dst, src, opts) {
4602
4938
  } else if (globalAlpha === 255) {
4603
4939
  weight = effectiveM;
4604
4940
  } else {
4605
- weight = effectiveM * globalAlpha + 128 >> 8;
4941
+ const t = effectiveM * globalAlpha + 128;
4942
+ weight = t + (t >> 8) >> 8;
4606
4943
  }
4607
4944
  if (weight !== 255) {
4608
4945
  if (weight === 0) {
@@ -4612,7 +4949,8 @@ function mergeAlphaMasks(dst, src, opts) {
4612
4949
  if (da === 255) {
4613
4950
  dstData[dIdx] = weight;
4614
4951
  } else if (da !== 0) {
4615
- dstData[dIdx] = da * weight + 128 >> 8;
4952
+ const t = da * weight + 128;
4953
+ dstData[dIdx] = t + (t >> 8) >> 8;
4616
4954
  }
4617
4955
  }
4618
4956
  }
@@ -4773,92 +5111,758 @@ function merge2BinaryMaskRects(a, b) {
4773
5111
  }
4774
5112
  }
4775
5113
  }
4776
- return {
4777
- ...bounds,
4778
- data: maskData,
4779
- type: 1 /* BINARY */
4780
- };
4781
- }
4782
-
4783
- // src/MaskRect/mergeBinaryMaskRects.ts
4784
- function mergeBinaryMaskRects(current, adding) {
4785
- const rects = [...current, ...adding];
4786
- let changed = true;
4787
- while (changed) {
4788
- changed = false;
4789
- const next = [];
4790
- for (const r of rects) {
4791
- let merged = false;
4792
- for (let i = 0; i < next.length; i++) {
4793
- const n = next[i];
4794
- const overlap = r.x <= n.x + n.w && r.x + r.w >= n.x && r.y <= n.y + n.h && r.y + r.h >= n.y;
4795
- if (overlap) {
4796
- next[i] = merge2BinaryMaskRects(n, r);
4797
- merged = true;
5114
+ return {
5115
+ ...bounds,
5116
+ data: maskData,
5117
+ type: 1 /* BINARY */
5118
+ };
5119
+ }
5120
+
5121
+ // src/MaskRect/mergeBinaryMaskRects.ts
5122
+ function mergeBinaryMaskRects(current, adding) {
5123
+ const rects = [...current, ...adding];
5124
+ let changed = true;
5125
+ while (changed) {
5126
+ changed = false;
5127
+ const next = [];
5128
+ for (const r of rects) {
5129
+ let merged = false;
5130
+ for (let i = 0; i < next.length; i++) {
5131
+ const n = next[i];
5132
+ const overlap = r.x <= n.x + n.w && r.x + r.w >= n.x && r.y <= n.y + n.h && r.y + r.h >= n.y;
5133
+ if (overlap) {
5134
+ next[i] = merge2BinaryMaskRects(n, r);
5135
+ merged = true;
5136
+ changed = true;
5137
+ break;
5138
+ }
5139
+ }
5140
+ if (!merged) next.push(r);
5141
+ }
5142
+ rects.splice(0, rects.length, ...next);
5143
+ }
5144
+ return rects;
5145
+ }
5146
+
5147
+ // src/MaskRect/subtractBinaryMaskRects.ts
5148
+ function subtractBinaryMaskRects(current, subtracting) {
5149
+ let result = [...current];
5150
+ for (const sub of subtracting) {
5151
+ const next = [];
5152
+ for (const r of result) {
5153
+ const ix = Math.max(r.x, sub.x);
5154
+ const iy = Math.max(r.y, sub.y);
5155
+ const ix2 = Math.min(r.x + r.w, sub.x + sub.w);
5156
+ const iy2 = Math.min(r.y + r.h, sub.y + sub.h);
5157
+ if (ix >= ix2 || iy >= iy2) {
5158
+ next.push(r);
5159
+ continue;
5160
+ }
5161
+ if (r.y < iy) pushPiece(next, r, r.x, r.y, r.w, iy - r.y);
5162
+ if (iy2 < r.y + r.h) pushPiece(next, r, r.x, iy2, r.w, r.y + r.h - iy2);
5163
+ if (r.x < ix) pushPiece(next, r, r.x, iy, ix - r.x, iy2 - iy);
5164
+ if (ix2 < r.x + r.w) pushPiece(next, r, ix2, iy, r.x + r.w - ix2, iy2 - iy);
5165
+ }
5166
+ result = next;
5167
+ }
5168
+ return result;
5169
+ }
5170
+ function pushPiece(dest, r, x, y, w, h) {
5171
+ if (r.data === null || r.data === void 0) {
5172
+ dest.push({
5173
+ x,
5174
+ y,
5175
+ w,
5176
+ h,
5177
+ data: null,
5178
+ type: null
5179
+ });
5180
+ return;
5181
+ }
5182
+ const lx = x - r.x;
5183
+ const ly = y - r.y;
5184
+ const data = new Uint8Array(w * h);
5185
+ for (let row = 0; row < h; row++) {
5186
+ data.set(r.data.subarray((ly + row) * r.w + lx, (ly + row) * r.w + lx + w), row * w);
5187
+ }
5188
+ dest.push({
5189
+ x,
5190
+ y,
5191
+ w,
5192
+ h,
5193
+ data,
5194
+ type: 1 /* BINARY */
5195
+ });
5196
+ }
5197
+
5198
+ // src/Paint/_paint-types.ts
5199
+ var PaintMaskOutline = /* @__PURE__ */ ((PaintMaskOutline2) => {
5200
+ PaintMaskOutline2[PaintMaskOutline2["MASKED"] = 0] = "MASKED";
5201
+ PaintMaskOutline2[PaintMaskOutline2["CIRCLE"] = 1] = "CIRCLE";
5202
+ PaintMaskOutline2[PaintMaskOutline2["RECT"] = 2] = "RECT";
5203
+ return PaintMaskOutline2;
5204
+ })(PaintMaskOutline || {});
5205
+
5206
+ // src/Rect/trimRectBounds.ts
5207
+ function trimRectBounds(x, y, w, h, targetWidth, targetHeight, out) {
5208
+ const res = out ?? {
5209
+ x: 0,
5210
+ y: 0,
5211
+ w: 0,
5212
+ h: 0
5213
+ };
5214
+ const left = Math.max(0, x);
5215
+ const top = Math.max(0, y);
5216
+ const right = Math.min(targetWidth, x + w);
5217
+ const bottom = Math.min(targetHeight, y + h);
5218
+ res.x = left;
5219
+ res.y = top;
5220
+ res.w = Math.max(0, right - left);
5221
+ res.h = Math.max(0, bottom - top);
5222
+ return res;
5223
+ }
5224
+
5225
+ // src/Paint/eachTileInBounds.ts
5226
+ function eachTileInBounds(config, lookup, tilePool, bounds, callback) {
5227
+ const {
5228
+ tileShift,
5229
+ targetColumns,
5230
+ targetRows,
5231
+ tileSize
5232
+ } = config;
5233
+ const x1 = Math.max(0, bounds.x >> tileShift);
5234
+ const y1 = Math.max(0, bounds.y >> tileShift);
5235
+ const x2 = Math.min(targetColumns - 1, bounds.x + bounds.w - 1 >> tileShift);
5236
+ const y2 = Math.min(targetRows - 1, bounds.y + bounds.h - 1 >> tileShift);
5237
+ if (x1 > x2 || y1 > y2) return;
5238
+ for (let ty = y1; ty <= y2; ty++) {
5239
+ const rowOffset = ty * targetColumns;
5240
+ const tileTop = ty << tileShift;
5241
+ for (let tx = x1; tx <= x2; tx++) {
5242
+ const id = rowOffset + tx;
5243
+ const tile = lookup[id] ?? (lookup[id] = tilePool.getTile(id, tx, ty));
5244
+ const tileLeft = tx << tileShift;
5245
+ const startX = bounds.x > tileLeft ? bounds.x : tileLeft;
5246
+ const startY = bounds.y > tileTop ? bounds.y : tileTop;
5247
+ const maskEndX = bounds.x + bounds.w;
5248
+ const tileEndX = tileLeft + tileSize;
5249
+ const endX = maskEndX < tileEndX ? maskEndX : tileEndX;
5250
+ const maskEndY = bounds.y + bounds.h;
5251
+ const tileEndY = tileTop + tileSize;
5252
+ const endY = maskEndY < tileEndY ? maskEndY : tileEndY;
5253
+ callback(tile, startX, startY, endX - startX, endY - startY);
5254
+ }
5255
+ }
5256
+ }
5257
+
5258
+ // src/Paint/AlphaMaskPaintBuffer.ts
5259
+ var AlphaMaskPaintBuffer = class {
5260
+ constructor(config, tilePool) {
5261
+ this.config = config;
5262
+ this.tilePool = tilePool;
5263
+ this.lookup = [];
5264
+ }
5265
+ lookup;
5266
+ scratchBounds = {
5267
+ x: 0,
5268
+ y: 0,
5269
+ w: 0,
5270
+ h: 0
5271
+ };
5272
+ blendColorPixelDataAlphaMaskFn = blendColorPixelDataAlphaMask;
5273
+ forEachLinePointFn = forEachLinePoint;
5274
+ trimRectBoundsFn = trimRectBounds;
5275
+ eachTileInBoundsFn = eachTileInBounds;
5276
+ paintAlphaMask(brush, x0, y0, x1 = x0, y1 = y0) {
5277
+ const scratch = this.scratchBounds;
5278
+ const lookup = this.lookup;
5279
+ const tilePool = this.tilePool;
5280
+ const config = this.config;
5281
+ const tileShift = config.tileShift;
5282
+ const tileMask = config.tileMask;
5283
+ const target = config.target;
5284
+ const {
5285
+ w: bW,
5286
+ h: bH,
5287
+ data: bD,
5288
+ centerOffsetX,
5289
+ centerOffsetY
5290
+ } = brush;
5291
+ let changed = false;
5292
+ const eachTileInBoundsFn = this.eachTileInBoundsFn;
5293
+ const trimRectBoundsFn = this.trimRectBoundsFn;
5294
+ this.forEachLinePointFn(x0, y0, x1, y1, (px, py) => {
5295
+ const topLeftX = Math.floor(px + centerOffsetX);
5296
+ const topLeftY = Math.floor(py + centerOffsetY);
5297
+ trimRectBoundsFn(topLeftX, topLeftY, bW, bH, target.w, target.h, scratch);
5298
+ if (scratch.w <= 0 || scratch.h <= 0) return;
5299
+ eachTileInBoundsFn(config, lookup, tilePool, scratch, (tile, bX, bY, bW_t, bH_t) => {
5300
+ const data = tile.data;
5301
+ let tileChanged = false;
5302
+ for (let i = 0; i < bH_t; i++) {
5303
+ const canvasY = bY + i;
5304
+ const bOff = (canvasY - topLeftY) * bW;
5305
+ const tOff = (canvasY & tileMask) << tileShift;
5306
+ const dS = tOff + (bX & tileMask);
5307
+ for (let j = 0; j < bW_t; j++) {
5308
+ const canvasX = bX + j;
5309
+ const brushA = bD[bOff + (canvasX - topLeftX)];
5310
+ if (brushA === 0) continue;
5311
+ const idx = dS + j;
5312
+ if (brushA > data[idx]) {
5313
+ data[idx] = brushA;
5314
+ tileChanged = true;
5315
+ }
5316
+ }
5317
+ }
5318
+ if (tileChanged) changed = true;
5319
+ });
5320
+ });
5321
+ return changed;
5322
+ }
5323
+ paintBinaryMask(brush, alpha, x0, y0, x1 = x0, y1 = y0) {
5324
+ if (alpha === 0) return false;
5325
+ const scratch = this.scratchBounds;
5326
+ const lookup = this.lookup;
5327
+ const tilePool = this.tilePool;
5328
+ const config = this.config;
5329
+ const tileShift = config.tileShift;
5330
+ const tileMask = config.tileMask;
5331
+ const target = config.target;
5332
+ const {
5333
+ w: bW,
5334
+ h: bH,
5335
+ data: bD,
5336
+ centerOffsetX,
5337
+ centerOffsetY
5338
+ } = brush;
5339
+ let changed = false;
5340
+ const trimRectBoundsFn = this.trimRectBoundsFn;
5341
+ const eachTileInBoundsFn = this.eachTileInBoundsFn;
5342
+ this.forEachLinePointFn(x0, y0, x1, y1, (px, py) => {
5343
+ const topLeftX = Math.floor(px + centerOffsetX);
5344
+ const topLeftY = Math.floor(py + centerOffsetY);
5345
+ trimRectBoundsFn(topLeftX, topLeftY, bW, bH, target.w, target.h, scratch);
5346
+ if (scratch.w <= 0 || scratch.h <= 0) return;
5347
+ eachTileInBoundsFn(config, lookup, tilePool, scratch, (tile, bX, bY, bW_t, bH_t) => {
5348
+ const data = tile.data;
5349
+ let tileChanged = false;
5350
+ for (let i = 0; i < bH_t; i++) {
5351
+ const canvasY = bY + i;
5352
+ const bOff = (canvasY - topLeftY) * bW;
5353
+ const tOff = (canvasY & tileMask) << tileShift;
5354
+ const dS = tOff + (bX & tileMask);
5355
+ for (let j = 0; j < bW_t; j++) {
5356
+ const canvasX = bX + j;
5357
+ if (bD[bOff + (canvasX - topLeftX)]) {
5358
+ const idx = dS + j;
5359
+ if (data[idx] < alpha) {
5360
+ data[idx] = alpha;
5361
+ tileChanged = true;
5362
+ }
5363
+ }
5364
+ }
5365
+ }
5366
+ if (tileChanged) changed = true;
5367
+ });
5368
+ });
5369
+ return changed;
5370
+ }
5371
+ paintRect(alpha, brushWidth, brushHeight, x0, y0, x1 = x0, y1 = y0) {
5372
+ const scratch = this.scratchBounds;
5373
+ const lookup = this.lookup;
5374
+ const tilePool = this.tilePool;
5375
+ const config = this.config;
5376
+ const tileShift = config.tileShift;
5377
+ const tileMask = config.tileMask;
5378
+ const target = config.target;
5379
+ const centerOffsetX = -(brushWidth - 1 >> 1);
5380
+ const centerOffsetY = -(brushHeight - 1 >> 1);
5381
+ const trimRectBoundsFn = this.trimRectBoundsFn;
5382
+ const eachTileInBoundsFn = this.eachTileInBoundsFn;
5383
+ let changed = false;
5384
+ this.forEachLinePointFn(x0, y0, x1, y1, (px, py) => {
5385
+ const topLeftX = Math.floor(px + centerOffsetX);
5386
+ const topLeftY = Math.floor(py + centerOffsetY);
5387
+ trimRectBoundsFn(topLeftX, topLeftY, brushWidth, brushHeight, target.w, target.h, scratch);
5388
+ if (scratch.w <= 0 || scratch.h <= 0) return;
5389
+ eachTileInBoundsFn(config, lookup, tilePool, scratch, (tile, bX, bY, bW_t, bH_t) => {
5390
+ const data = tile.data;
5391
+ let tileChanged = false;
5392
+ for (let i = 0; i < bH_t; i++) {
5393
+ const canvasY = bY + i;
5394
+ const tOff = (canvasY & tileMask) << tileShift;
5395
+ const dS = tOff + (bX & tileMask);
5396
+ for (let j = 0; j < bW_t; j++) {
5397
+ const idx = dS + j;
5398
+ if (alpha > data[idx]) {
5399
+ data[idx] = alpha;
5400
+ tileChanged = true;
5401
+ }
5402
+ }
5403
+ }
5404
+ if (tileChanged) {
5405
+ changed = true;
5406
+ }
5407
+ });
5408
+ });
5409
+ return changed;
5410
+ }
5411
+ opts = {
5412
+ alpha: 255,
5413
+ blendFn: sourceOverPerfect,
5414
+ x: 0,
5415
+ y: 0,
5416
+ w: 0,
5417
+ h: 0
5418
+ };
5419
+ commit(accumulator, color, alpha = 255, blendFn = sourceOverPerfect) {
5420
+ const blendColorPixelDataAlphaMaskFn = this.blendColorPixelDataAlphaMaskFn;
5421
+ const tileShift = this.config.tileShift;
5422
+ const lookup = this.lookup;
5423
+ const opts = this.opts;
5424
+ opts.alpha = alpha;
5425
+ opts.blendFn = blendFn;
5426
+ for (let i = 0; i < lookup.length; i++) {
5427
+ const tile = lookup[i];
5428
+ if (tile) {
5429
+ const didChange = accumulator.storeTileBeforeState(tile.id, tile.tx, tile.ty);
5430
+ const dx = tile.tx << tileShift;
5431
+ const dy = tile.ty << tileShift;
5432
+ opts.x = dx;
5433
+ opts.y = dy;
5434
+ opts.w = tile.w;
5435
+ opts.h = tile.h;
5436
+ didChange(blendColorPixelDataAlphaMaskFn(this.config.target, color, tile, opts));
5437
+ }
5438
+ }
5439
+ this.clear();
5440
+ }
5441
+ clear() {
5442
+ this.tilePool.releaseTiles(this.lookup);
5443
+ }
5444
+ };
5445
+
5446
+ // src/Paint/AlphaMaskPaintBufferCanvasRenderer.ts
5447
+ function makeAlphaMaskPaintBufferCanvasRenderer(paintBuffer, offscreenCanvasClass = OffscreenCanvas) {
5448
+ const config = paintBuffer.config;
5449
+ const tileSize = config.tileSize;
5450
+ const tileShift = config.tileShift;
5451
+ const tileArea = config.tileArea;
5452
+ const lookup = paintBuffer.lookup;
5453
+ const canvas = new offscreenCanvasClass(tileSize, tileSize);
5454
+ const ctx = canvas.getContext("2d");
5455
+ if (!ctx) throw new Error(CANVAS_CTX_FAILED);
5456
+ ctx.imageSmoothingEnabled = false;
5457
+ const bridge = makePixelData(new ImageData(tileSize, tileSize));
5458
+ const view32 = bridge.data;
5459
+ return function drawPaintBuffer(targetCtx, color, alpha = 255, compOperation = "source-over") {
5460
+ if (alpha === 0) return;
5461
+ const baseSrcAlpha = color >>> 24;
5462
+ const colorRGB = color & 16777215;
5463
+ if (baseSrcAlpha === 0) return;
5464
+ targetCtx.globalAlpha = alpha / 255;
5465
+ targetCtx.globalCompositeOperation = compOperation;
5466
+ for (let i = 0; i < lookup.length; i++) {
5467
+ const tile = lookup[i];
5468
+ if (tile) {
5469
+ const data8 = tile.data;
5470
+ view32.fill(0);
5471
+ for (let p = 0; p < tileArea; p++) {
5472
+ const maskA = data8[p];
5473
+ if (maskA === 0) continue;
5474
+ if (maskA === 255) {
5475
+ view32[p] = color;
5476
+ } else {
5477
+ const t = baseSrcAlpha * maskA + 128;
5478
+ const finalA = t + (t >> 8) >> 8;
5479
+ view32[p] = (colorRGB | finalA << 24) >>> 0;
5480
+ }
5481
+ }
5482
+ const dx = tile.tx << tileShift;
5483
+ const dy = tile.ty << tileShift;
5484
+ ctx.putImageData(bridge.imageData, 0, 0);
5485
+ targetCtx.drawImage(canvas, dx, dy);
5486
+ }
5487
+ }
5488
+ targetCtx.globalAlpha = 1;
5489
+ targetCtx.globalCompositeOperation = "source-over";
5490
+ };
5491
+ }
5492
+
5493
+ // src/Paint/BinaryMaskPaintBuffer.ts
5494
+ var BinaryMaskPaintBuffer = class {
5495
+ constructor(config, tilePool) {
5496
+ this.config = config;
5497
+ this.tilePool = tilePool;
5498
+ this.lookup = [];
5499
+ }
5500
+ lookup;
5501
+ scratchBounds = {
5502
+ x: 0,
5503
+ y: 0,
5504
+ w: 0,
5505
+ h: 0
5506
+ };
5507
+ blendColorPixelDataBinaryMaskFn = blendColorPixelDataBinaryMask;
5508
+ forEachLinePointFn = forEachLinePoint;
5509
+ trimRectBoundsFn = trimRectBounds;
5510
+ eachTileInBoundsFn = eachTileInBounds;
5511
+ paintBinaryMask(brush, x0, y0, x1 = x0, y1 = y0) {
5512
+ const scratch = this.scratchBounds;
5513
+ const lookup = this.lookup;
5514
+ const tilePool = this.tilePool;
5515
+ const config = this.config;
5516
+ const tileShift = config.tileShift;
5517
+ const tileMask = config.tileMask;
5518
+ const target = config.target;
5519
+ const {
5520
+ w: bW,
5521
+ h: bH,
5522
+ data: bD,
5523
+ centerOffsetX,
5524
+ centerOffsetY
5525
+ } = brush;
5526
+ let changed = false;
5527
+ const trimRectBoundsFn = this.trimRectBoundsFn;
5528
+ const eachTileInBoundsFn = this.eachTileInBoundsFn;
5529
+ this.forEachLinePointFn(x0, y0, x1, y1, (px, py) => {
5530
+ const topLeftX = Math.floor(px + centerOffsetX);
5531
+ const topLeftY = Math.floor(py + centerOffsetY);
5532
+ trimRectBoundsFn(topLeftX, topLeftY, bW, bH, target.w, target.h, scratch);
5533
+ if (scratch.w <= 0 || scratch.h <= 0) return;
5534
+ eachTileInBoundsFn(config, lookup, tilePool, scratch, (tile, bX, bY, bW_t, bH_t) => {
5535
+ const data = tile.data;
5536
+ let tileChanged = false;
5537
+ for (let i = 0; i < bH_t; i++) {
5538
+ const canvasY = bY + i;
5539
+ const bOff = (canvasY - topLeftY) * bW;
5540
+ const tOff = (canvasY & tileMask) << tileShift;
5541
+ const dS = tOff + (bX & tileMask);
5542
+ for (let j = 0; j < bW_t; j++) {
5543
+ const canvasX = bX + j;
5544
+ if (bD[bOff + (canvasX - topLeftX)]) {
5545
+ const idx = dS + j;
5546
+ if (data[idx] === 0) {
5547
+ data[idx] = 1;
5548
+ tileChanged = true;
5549
+ }
5550
+ }
5551
+ }
5552
+ }
5553
+ if (tileChanged) changed = true;
5554
+ });
5555
+ });
5556
+ return changed;
5557
+ }
5558
+ paintRect(brushWidth, brushHeight, x0, y0, x1 = x0, y1 = y0) {
5559
+ const scratch = this.scratchBounds;
5560
+ const lookup = this.lookup;
5561
+ const tilePool = this.tilePool;
5562
+ const config = this.config;
5563
+ const tileShift = config.tileShift;
5564
+ const tileMask = config.tileMask;
5565
+ const target = config.target;
5566
+ const centerOffsetX = -(brushWidth - 1 >> 1);
5567
+ const centerOffsetY = -(brushHeight - 1 >> 1);
5568
+ const trimRectBoundsFn = this.trimRectBoundsFn;
5569
+ const eachTileInBoundsFn = this.eachTileInBoundsFn;
5570
+ let changed = false;
5571
+ this.forEachLinePointFn(x0, y0, x1, y1, (px, py) => {
5572
+ const topLeftX = Math.floor(px + centerOffsetX);
5573
+ const topLeftY = Math.floor(py + centerOffsetY);
5574
+ trimRectBoundsFn(topLeftX, topLeftY, brushWidth, brushHeight, target.w, target.h, scratch);
5575
+ if (scratch.w <= 0 || scratch.h <= 0) return;
5576
+ eachTileInBoundsFn(config, lookup, tilePool, scratch, (tile, bX, bY, bW_t, bH_t) => {
5577
+ const data = tile.data;
5578
+ let tileChanged = false;
5579
+ for (let i = 0; i < bH_t; i++) {
5580
+ const canvasY = bY + i;
5581
+ const tOff = (canvasY & tileMask) << tileShift;
5582
+ const dS = tOff + (bX & tileMask);
5583
+ for (let j = 0; j < bW_t; j++) {
5584
+ const idx = dS + j;
5585
+ if (data[idx] === 0) {
5586
+ data[idx] = 1;
5587
+ tileChanged = true;
5588
+ }
5589
+ }
5590
+ }
5591
+ if (tileChanged) {
5592
+ changed = true;
5593
+ }
5594
+ });
5595
+ });
5596
+ return changed;
5597
+ }
5598
+ opts = {
5599
+ alpha: 255,
5600
+ blendFn: sourceOverPerfect,
5601
+ x: 0,
5602
+ y: 0,
5603
+ w: 0,
5604
+ h: 0
5605
+ };
5606
+ commit(accumulator, color, alpha = 255, blendFn = sourceOverPerfect) {
5607
+ const blendColorPixelDataBinaryMaskFn = this.blendColorPixelDataBinaryMaskFn;
5608
+ const tileShift = this.config.tileShift;
5609
+ const lookup = this.lookup;
5610
+ const opts = this.opts;
5611
+ opts.alpha = alpha;
5612
+ opts.blendFn = blendFn;
5613
+ for (let i = 0; i < lookup.length; i++) {
5614
+ const tile = lookup[i];
5615
+ if (tile) {
5616
+ const didChange = accumulator.storeTileBeforeState(tile.id, tile.tx, tile.ty);
5617
+ const dx = tile.tx << tileShift;
5618
+ const dy = tile.ty << tileShift;
5619
+ opts.x = dx;
5620
+ opts.y = dy;
5621
+ opts.w = tile.w;
5622
+ opts.h = tile.h;
5623
+ didChange(blendColorPixelDataBinaryMaskFn(this.config.target, color, tile, opts));
5624
+ }
5625
+ }
5626
+ this.clear();
5627
+ }
5628
+ clear() {
5629
+ this.tilePool.releaseTiles(this.lookup);
5630
+ }
5631
+ };
5632
+
5633
+ // src/Paint/BinaryMaskPaintBufferCanvasRenderer.ts
5634
+ function makeBinaryMaskPaintBufferCanvasRenderer(paintBuffer, offscreenCanvasClass = OffscreenCanvas) {
5635
+ const config = paintBuffer.config;
5636
+ const tileSize = config.tileSize;
5637
+ const tileShift = config.tileShift;
5638
+ const tileArea = config.tileArea;
5639
+ const lookup = paintBuffer.lookup;
5640
+ const canvas = new offscreenCanvasClass(tileSize, tileSize);
5641
+ const ctx = canvas.getContext("2d");
5642
+ if (!ctx) throw new Error(CANVAS_CTX_FAILED);
5643
+ ctx.imageSmoothingEnabled = false;
5644
+ const bridge = makePixelData(new ImageData(tileSize, tileSize));
5645
+ const view32 = bridge.data;
5646
+ return function drawPaintBuffer(targetCtx, color, alpha = 255, compOperation = "source-over") {
5647
+ if (alpha === 0) return;
5648
+ const baseSrcAlpha = color >>> 24;
5649
+ if (baseSrcAlpha === 0) return;
5650
+ targetCtx.globalAlpha = alpha / 255;
5651
+ targetCtx.globalCompositeOperation = compOperation;
5652
+ for (let i = 0; i < lookup.length; i++) {
5653
+ const tile = lookup[i];
5654
+ if (tile) {
5655
+ const data8 = tile.data;
5656
+ view32.fill(0);
5657
+ for (let p = 0; p < tileArea; p++) {
5658
+ if (data8[p] === 1) {
5659
+ view32[p] = color;
5660
+ }
5661
+ }
5662
+ const dx = tile.tx << tileShift;
5663
+ const dy = tile.ty << tileShift;
5664
+ ctx.putImageData(bridge.imageData, 0, 0);
5665
+ targetCtx.drawImage(canvas, dx, dy);
5666
+ }
5667
+ }
5668
+ targetCtx.globalAlpha = 1;
5669
+ targetCtx.globalCompositeOperation = "source-over";
5670
+ };
5671
+ }
5672
+
5673
+ // src/Paint/ColorPaintBuffer.ts
5674
+ var ColorPaintBuffer = class {
5675
+ constructor(config, tilePool, blendPixelDataFn = blendPixelData) {
5676
+ this.config = config;
5677
+ this.tilePool = tilePool;
5678
+ this.blendPixelDataFn = blendPixelDataFn;
5679
+ this.lookup = [];
5680
+ }
5681
+ lookup;
5682
+ scratchBounds = {
5683
+ x: 0,
5684
+ y: 0,
5685
+ w: 0,
5686
+ h: 0
5687
+ };
5688
+ paintAlphaMask(color, brush, x0, y0, x1 = x0, y1 = y0) {
5689
+ const cA = color >>> 24;
5690
+ if (cA === 0) return false;
5691
+ const scratch = this.scratchBounds;
5692
+ const lookup = this.lookup;
5693
+ const tilePool = this.tilePool;
5694
+ const config = this.config;
5695
+ const tileShift = config.tileShift;
5696
+ const tileMask = config.tileMask;
5697
+ const target = config.target;
5698
+ const {
5699
+ w: bW,
5700
+ h: bH,
5701
+ data: bD,
5702
+ centerOffsetX,
5703
+ centerOffsetY
5704
+ } = brush;
5705
+ const cRGB = color & 16777215;
5706
+ let changed = false;
5707
+ forEachLinePoint(x0, y0, x1, y1, (px, py) => {
5708
+ const topLeftX = Math.floor(px + centerOffsetX);
5709
+ const topLeftY = Math.floor(py + centerOffsetY);
5710
+ trimRectBounds(topLeftX, topLeftY, bW, bH, target.w, target.h, scratch);
5711
+ if (scratch.w <= 0 || scratch.h <= 0) return;
5712
+ eachTileInBounds(config, lookup, tilePool, scratch, (tile, bX, bY, bW_t, bH_t) => {
5713
+ const d32 = tile.data;
5714
+ let tileChanged = false;
5715
+ for (let i = 0; i < bH_t; i++) {
5716
+ const canvasY = bY + i;
5717
+ const bOff = (canvasY - topLeftY) * bW;
5718
+ const tOff = (canvasY & tileMask) << tileShift;
5719
+ const dS = tOff + (bX & tileMask);
5720
+ for (let j = 0; j < bW_t; j++) {
5721
+ const canvasX = bX + j;
5722
+ const brushA = bD[bOff + (canvasX - topLeftX)];
5723
+ if (brushA === 0) continue;
5724
+ const t = cA * brushA + 128;
5725
+ const blendedA = t + (t >> 8) >> 8;
5726
+ const idx = dS + j;
5727
+ const cur = d32[idx];
5728
+ if (brushA > cur >>> 24) {
5729
+ const next = (cRGB | blendedA << 24) >>> 0;
5730
+ if (cur !== next) {
5731
+ d32[idx] = next;
5732
+ tileChanged = true;
5733
+ }
5734
+ }
5735
+ }
5736
+ }
5737
+ if (tileChanged) changed = true;
5738
+ });
5739
+ });
5740
+ return changed;
5741
+ }
5742
+ paintBinaryMask(color, brush, x0, y0, x1 = x0, y1 = y0) {
5743
+ const alphaIsZero = color >>> 24 === 0;
5744
+ if (alphaIsZero) return false;
5745
+ const scratch = this.scratchBounds;
5746
+ const lookup = this.lookup;
5747
+ const tilePool = this.tilePool;
5748
+ const config = this.config;
5749
+ const tileShift = config.tileShift;
5750
+ const tileMask = config.tileMask;
5751
+ const target = config.target;
5752
+ const {
5753
+ w: bW,
5754
+ h: bH,
5755
+ data: bD,
5756
+ centerOffsetX,
5757
+ centerOffsetY
5758
+ } = brush;
5759
+ let changed = false;
5760
+ forEachLinePoint(x0, y0, x1, y1, (px, py) => {
5761
+ const topLeftX = Math.floor(px + centerOffsetX);
5762
+ const topLeftY = Math.floor(py + centerOffsetY);
5763
+ trimRectBounds(topLeftX, topLeftY, bW, bH, target.w, target.h, scratch);
5764
+ if (scratch.w <= 0 || scratch.h <= 0) return;
5765
+ eachTileInBounds(config, lookup, tilePool, scratch, (tile, bX, bY, bW_t, bH_t) => {
5766
+ const d32 = tile.data;
5767
+ let tileChanged = false;
5768
+ for (let i = 0; i < bH_t; i++) {
5769
+ const canvasY = bY + i;
5770
+ const bOff = (canvasY - topLeftY) * bW;
5771
+ const tOff = (canvasY & tileMask) << tileShift;
5772
+ const dS = tOff + (bX & tileMask);
5773
+ for (let j = 0; j < bW_t; j++) {
5774
+ const canvasX = bX + j;
5775
+ if (bD[bOff + (canvasX - topLeftX)]) {
5776
+ const idx = dS + j;
5777
+ if (d32[idx] !== color) {
5778
+ d32[idx] = color;
5779
+ tileChanged = true;
5780
+ }
5781
+ }
5782
+ }
5783
+ }
5784
+ if (tileChanged) changed = true;
5785
+ });
5786
+ });
5787
+ return changed;
5788
+ }
5789
+ paintRect(color, brushWidth, brushHeight, x0, y0, x1 = x0, y1 = y0) {
5790
+ const alphaIsZero = color >>> 24 === 0;
5791
+ if (alphaIsZero) return false;
5792
+ const scratch = this.scratchBounds;
5793
+ const lookup = this.lookup;
5794
+ const tilePool = this.tilePool;
5795
+ const config = this.config;
5796
+ const tileShift = config.tileShift;
5797
+ const tileMask = config.tileMask;
5798
+ const target = config.target;
5799
+ const centerOffsetX = -(brushWidth - 1 >> 1);
5800
+ const centerOffsetY = -(brushHeight - 1 >> 1);
5801
+ let changed = false;
5802
+ forEachLinePoint(x0, y0, x1, y1, (px, py) => {
5803
+ const topLeftX = Math.floor(px + centerOffsetX);
5804
+ const topLeftY = Math.floor(py + centerOffsetY);
5805
+ trimRectBounds(topLeftX, topLeftY, brushWidth, brushHeight, target.w, target.h, scratch);
5806
+ if (scratch.w <= 0 || scratch.h <= 0) return;
5807
+ eachTileInBounds(config, lookup, tilePool, scratch, (tile, bX, bY, bW_t, bH_t) => {
5808
+ const d32 = tile.data;
5809
+ let tileChanged = false;
5810
+ for (let i = 0; i < bH_t; i++) {
5811
+ const canvasY = bY + i;
5812
+ const tOff = (canvasY & tileMask) << tileShift;
5813
+ const dS = tOff + (bX & tileMask);
5814
+ for (let j = 0; j < bW_t; j++) {
5815
+ const idx = dS + j;
5816
+ if (d32[idx] !== color) {
5817
+ d32[idx] = color;
5818
+ tileChanged = true;
5819
+ }
5820
+ }
5821
+ }
5822
+ if (tileChanged) {
4798
5823
  changed = true;
4799
- break;
4800
5824
  }
4801
- }
4802
- if (!merged) next.push(r);
4803
- }
4804
- rects.splice(0, rects.length, ...next);
5825
+ });
5826
+ });
5827
+ return changed;
4805
5828
  }
4806
- return rects;
4807
- }
4808
-
4809
- // src/MaskRect/subtractBinaryMaskRects.ts
4810
- function subtractBinaryMaskRects(current, subtracting) {
4811
- let result = [...current];
4812
- for (const sub of subtracting) {
4813
- const next = [];
4814
- for (const r of result) {
4815
- const ix = Math.max(r.x, sub.x);
4816
- const iy = Math.max(r.y, sub.y);
4817
- const ix2 = Math.min(r.x + r.w, sub.x + sub.w);
4818
- const iy2 = Math.min(r.y + r.h, sub.y + sub.h);
4819
- if (ix >= ix2 || iy >= iy2) {
4820
- next.push(r);
4821
- continue;
5829
+ opts = {
5830
+ alpha: 255,
5831
+ blendFn: sourceOverPerfect,
5832
+ x: 0,
5833
+ y: 0,
5834
+ w: 0,
5835
+ h: 0
5836
+ };
5837
+ commit(accumulator, alpha = 255, blendFn = sourceOverPerfect) {
5838
+ const tileShift = this.config.tileShift;
5839
+ const lookup = this.lookup;
5840
+ const opts = this.opts;
5841
+ const blendPixelDataFn = this.blendPixelDataFn;
5842
+ opts.alpha = alpha;
5843
+ opts.blendFn = blendFn;
5844
+ for (let i = 0; i < lookup.length; i++) {
5845
+ const tile = lookup[i];
5846
+ if (tile) {
5847
+ const didChange = accumulator.storeTileBeforeState(tile.id, tile.tx, tile.ty);
5848
+ const dx = tile.tx << tileShift;
5849
+ const dy = tile.ty << tileShift;
5850
+ opts.x = dx;
5851
+ opts.y = dy;
5852
+ opts.w = tile.w;
5853
+ opts.h = tile.h;
5854
+ didChange(blendPixelDataFn(this.config.target, tile, opts));
4822
5855
  }
4823
- if (r.y < iy) pushPiece(next, r, r.x, r.y, r.w, iy - r.y);
4824
- if (iy2 < r.y + r.h) pushPiece(next, r, r.x, iy2, r.w, r.y + r.h - iy2);
4825
- if (r.x < ix) pushPiece(next, r, r.x, iy, ix - r.x, iy2 - iy);
4826
- if (ix2 < r.x + r.w) pushPiece(next, r, ix2, iy, r.x + r.w - ix2, iy2 - iy);
4827
5856
  }
4828
- result = next;
4829
- }
4830
- return result;
4831
- }
4832
- function pushPiece(dest, r, x, y, w, h) {
4833
- if (r.data === null || r.data === void 0) {
4834
- dest.push({
4835
- x,
4836
- y,
4837
- w,
4838
- h,
4839
- data: null,
4840
- type: null
4841
- });
4842
- return;
5857
+ this.clear();
4843
5858
  }
4844
- const lx = x - r.x;
4845
- const ly = y - r.y;
4846
- const data = new Uint8Array(w * h);
4847
- for (let row = 0; row < h; row++) {
4848
- data.set(r.data.subarray((ly + row) * r.w + lx, (ly + row) * r.w + lx + w), row * w);
5859
+ clear() {
5860
+ this.tilePool.releaseTiles(this.lookup);
4849
5861
  }
4850
- dest.push({
4851
- x,
4852
- y,
4853
- w,
4854
- h,
4855
- data,
4856
- type: 1 /* BINARY */
4857
- });
4858
- }
5862
+ };
4859
5863
 
4860
- // src/Paint/PaintBufferCanvasRenderer.ts
4861
- function makePaintBufferCanvasRenderer(paintBuffer, offscreenCanvasClass = OffscreenCanvas) {
5864
+ // src/Paint/ColorPaintBufferCanvasRenderer.ts
5865
+ function makeColorPaintBufferCanvasRenderer(paintBuffer, offscreenCanvasClass = OffscreenCanvas) {
4862
5866
  const config = paintBuffer.config;
4863
5867
  const tileSize = config.tileSize;
4864
5868
  const tileShift = config.tileShift;
@@ -4884,7 +5888,7 @@ function makePaintBufferCanvasRenderer(paintBuffer, offscreenCanvasClass = Offsc
4884
5888
  };
4885
5889
  }
4886
5890
 
4887
- // src/Paint/makeCirclePaintAlphaMask.ts
5891
+ // src/Paint/makeCirclePaintMask.ts
4888
5892
  function makeCirclePaintAlphaMask(size, fallOff = (d) => d) {
4889
5893
  const area = size * size;
4890
5894
  const data = new Uint8Array(area);
@@ -4910,6 +5914,7 @@ function makeCirclePaintAlphaMask(size, fallOff = (d) => d) {
4910
5914
  }
4911
5915
  return {
4912
5916
  type: 0 /* ALPHA */,
5917
+ outlineType: 1 /* CIRCLE */,
4913
5918
  data,
4914
5919
  w: size,
4915
5920
  h: size,
@@ -4917,28 +5922,28 @@ function makeCirclePaintAlphaMask(size, fallOff = (d) => d) {
4917
5922
  centerOffsetY: centerOffset
4918
5923
  };
4919
5924
  }
4920
-
4921
- // src/Paint/makeCirclePaintBinaryMask.ts
4922
5925
  function makeCirclePaintBinaryMask(size) {
4923
5926
  const area = size * size;
4924
5927
  const data = new Uint8Array(area);
4925
5928
  const radius = size / 2;
4926
- const centerOffset = -Math.ceil(radius - 0.5);
5929
+ const r2 = radius * radius;
4927
5930
  for (let y = 0; y < size; y++) {
4928
5931
  for (let x = 0; x < size; x++) {
4929
5932
  const dx = x - radius + 0.5;
4930
5933
  const dy = y - radius + 0.5;
4931
5934
  const distSqr = dx * dx + dy * dy;
4932
- if (distSqr <= radius * radius) {
5935
+ if (distSqr <= r2) {
4933
5936
  data[y * size + x] = 1;
4934
5937
  }
4935
5938
  }
4936
5939
  }
5940
+ const centerOffset = -Math.ceil(radius - 0.5);
4937
5941
  return {
4938
5942
  type: 1 /* BINARY */,
4939
- data,
5943
+ outlineType: 1 /* CIRCLE */,
4940
5944
  w: size,
4941
5945
  h: size,
5946
+ data,
4942
5947
  centerOffsetX: centerOffset,
4943
5948
  centerOffsetY: centerOffset
4944
5949
  };
@@ -4948,6 +5953,7 @@ function makeCirclePaintBinaryMask(size) {
4948
5953
  function makePaintBinaryMask(mask) {
4949
5954
  return {
4950
5955
  type: 1 /* BINARY */,
5956
+ outlineType: 0 /* MASKED */,
4951
5957
  data: mask.data,
4952
5958
  w: mask.w,
4953
5959
  h: mask.h,
@@ -4958,6 +5964,7 @@ function makePaintBinaryMask(mask) {
4958
5964
  function makePaintAlphaMask(mask) {
4959
5965
  return {
4960
5966
  type: 0 /* ALPHA */,
5967
+ outlineType: 0 /* MASKED */,
4961
5968
  data: mask.data,
4962
5969
  w: mask.w,
4963
5970
  h: mask.h,
@@ -4991,6 +5998,7 @@ function makeRectFalloffPaintAlphaMask(width, height, fallOff = (d) => d) {
4991
5998
  }
4992
5999
  return {
4993
6000
  type: 0 /* ALPHA */,
6001
+ outlineType: 2 /* RECT */,
4994
6002
  data,
4995
6003
  w: width,
4996
6004
  h: height,
@@ -4999,26 +6007,110 @@ function makeRectFalloffPaintAlphaMask(width, height, fallOff = (d) => d) {
4999
6007
  };
5000
6008
  }
5001
6009
 
5002
- // src/PixelData/PixelData.ts
5003
- var PixelData = class {
5004
- data32;
5005
- imageData;
5006
- width;
5007
- height;
5008
- constructor(imageData) {
5009
- this.data32 = imageDataToUInt32Array(imageData);
5010
- this.imageData = imageData;
5011
- this.width = imageData.width;
5012
- this.height = imageData.height;
5013
- }
5014
- set(imageData) {
5015
- ;
5016
- this.imageData = imageData;
5017
- this.data32 = imageDataToUInt32Array(imageData);
5018
- this.width = imageData.width;
5019
- this.height = imageData.height;
6010
+ // src/PixelData/ReusablePixelData.ts
6011
+ function makeReusablePixelData() {
6012
+ const pixelData = {
6013
+ w: 0,
6014
+ h: 0,
6015
+ data: null,
6016
+ imageData: null
6017
+ };
6018
+ return function getReusablePixelData(width, height) {
6019
+ if (pixelData.w !== width || pixelData.h !== height) {
6020
+ setPixelData(pixelData, new ImageData(width, height));
6021
+ } else {
6022
+ pixelData.data.fill(0);
6023
+ }
6024
+ return pixelData;
6025
+ };
6026
+ }
6027
+
6028
+ // src/Paint/PaintCursorRenderer.ts
6029
+ function makePaintCursorRenderer(factory = (w, h) => new OffscreenCanvas(w, h)) {
6030
+ const canvas = factory(1, 1);
6031
+ const ctx = canvas.getContext("2d");
6032
+ if (!ctx) throw new Error(CANVAS_CTX_FAILED);
6033
+ ctx.imageSmoothingEnabled = false;
6034
+ const getPixelData = makeReusablePixelData();
6035
+ let _color = packColor(0, 255, 255, 255);
6036
+ let _scale = 1;
6037
+ let currentMask = {
6038
+ type: 1 /* BINARY */,
6039
+ outlineType: 2 /* RECT */,
6040
+ w: 1,
6041
+ h: 1,
6042
+ centerOffsetX: -(10 - 1 >> 1),
6043
+ centerOffsetY: -(10 - 1 >> 1)
6044
+ };
6045
+ let outline;
6046
+ function update(paintMask, scale, color, alphaThreshold = 127) {
6047
+ currentMask = paintMask ?? currentMask;
6048
+ _scale = scale ?? _scale;
6049
+ _color = color ?? _color;
6050
+ canvas.width = currentMask.w * _scale + 2 * _scale;
6051
+ canvas.height = currentMask.h * _scale + 2 * _scale;
6052
+ if (currentMask.type === 1 /* BINARY */) {
6053
+ if (currentMask.outlineType === 1 /* CIRCLE */) {
6054
+ outline = makeCircleBinaryMaskOutline(currentMask.w, _scale);
6055
+ } else if (currentMask.outlineType === 2 /* RECT */) {
6056
+ outline = makeRectBinaryMaskOutline(currentMask.w, currentMask.h, _scale);
6057
+ } else if (currentMask.outlineType === 0 /* MASKED */) {
6058
+ outline = makeBinaryMaskOutline(currentMask, _scale);
6059
+ }
6060
+ } else if (currentMask.type === 0 /* ALPHA */) {
6061
+ const mask = makeBinaryMaskFromAlphaMask(currentMask, alphaThreshold);
6062
+ outline = makeBinaryMaskOutline(mask, _scale);
6063
+ }
6064
+ const pixelData = getPixelData(outline.w, outline.h);
6065
+ fillPixelDataBinaryMask(pixelData, _color, outline);
6066
+ ctx.putImageData(pixelData.imageData, 0, 0);
5020
6067
  }
5021
- };
6068
+ const boundsScratch = {
6069
+ x: 0,
6070
+ y: 0,
6071
+ w: 0,
6072
+ h: 0
6073
+ };
6074
+ function getBounds(centerX, centerY) {
6075
+ boundsScratch.x = centerX + currentMask.centerOffsetX;
6076
+ boundsScratch.y = centerY + currentMask.centerOffsetY;
6077
+ boundsScratch.w = currentMask.w;
6078
+ boundsScratch.h = currentMask.h;
6079
+ return boundsScratch;
6080
+ }
6081
+ const boundsScaledScratch = {
6082
+ x: 0,
6083
+ y: 0,
6084
+ w: 0,
6085
+ h: 0
6086
+ };
6087
+ function getOutlineBoundsScaled(centerX, centerY) {
6088
+ boundsScaledScratch.x = centerX * _scale + currentMask.centerOffsetX * _scale - 1;
6089
+ boundsScaledScratch.y = centerY * _scale + currentMask.centerOffsetY * _scale - 1;
6090
+ boundsScaledScratch.w = currentMask.w * _scale;
6091
+ boundsScaledScratch.h = currentMask.h * _scale;
6092
+ return boundsScaledScratch;
6093
+ }
6094
+ function draw(drawCtx, centerX, centerY) {
6095
+ const dx = centerX * _scale + currentMask.centerOffsetX * _scale - 1;
6096
+ const dy = centerY * _scale + currentMask.centerOffsetY * _scale - 1;
6097
+ drawCtx.drawImage(canvas, Math.floor(dx), Math.floor(dy));
6098
+ }
6099
+ function getSettings() {
6100
+ return {
6101
+ color: _color,
6102
+ scale: _scale,
6103
+ currentMask
6104
+ };
6105
+ }
6106
+ return {
6107
+ update,
6108
+ getBounds,
6109
+ getBoundsScaled: getOutlineBoundsScaled,
6110
+ draw,
6111
+ getSettings
6112
+ };
6113
+ }
5022
6114
 
5023
6115
  // src/PixelData/applyMaskToPixelData.ts
5024
6116
  function applyMaskToPixelData(dst, mask, opts) {
@@ -5136,8 +6228,8 @@ function fillPixelDataFast(dst, color, _x, _y, _w, _h) {
5136
6228
  if (typeof _x === "object") {
5137
6229
  x = _x.x ?? 0;
5138
6230
  y = _x.y ?? 0;
5139
- w = _x.w ?? dst.width;
5140
- h = _x.h ?? dst.height;
6231
+ w = _x.w ?? dst.w;
6232
+ h = _x.h ?? dst.h;
5141
6233
  } else if (typeof _x === "number") {
5142
6234
  x = _x;
5143
6235
  y = _y;
@@ -5146,10 +6238,10 @@ function fillPixelDataFast(dst, color, _x, _y, _w, _h) {
5146
6238
  } else {
5147
6239
  x = 0;
5148
6240
  y = 0;
5149
- w = dst.width;
5150
- h = dst.height;
6241
+ w = dst.w;
6242
+ h = dst.h;
5151
6243
  }
5152
- const clip = resolveRectClipping(x, y, w, h, dst.width, dst.height, SCRATCH_RECT4);
6244
+ const clip = resolveRectClipping(x, y, w, h, dst.w, dst.h, SCRATCH_RECT4);
5153
6245
  if (!clip.inBounds) return;
5154
6246
  const {
5155
6247
  x: finalX,
@@ -5157,9 +6249,9 @@ function fillPixelDataFast(dst, color, _x, _y, _w, _h) {
5157
6249
  w: actualW,
5158
6250
  h: actualH
5159
6251
  } = clip;
5160
- const dst32 = dst.data32;
5161
- const dw = dst.width;
5162
- if (actualW === dw && actualH === dst.height && finalX === 0 && finalY === 0) {
6252
+ const dst32 = dst.data;
6253
+ const dw = dst.w;
6254
+ if (actualW === dw && actualH === dst.h && finalX === 0 && finalY === 0) {
5163
6255
  dst32.fill(color);
5164
6256
  return;
5165
6257
  }
@@ -5175,6 +6267,13 @@ function clearPixelDataFast(dst, rect) {
5175
6267
  fillPixelDataFast(dst, 0, rect);
5176
6268
  }
5177
6269
 
6270
+ // src/PixelData/copyPixelData.ts
6271
+ function copyPixelData(target) {
6272
+ const data = target.imageData.data;
6273
+ const buffer = new Uint8ClampedArray(data);
6274
+ return makePixelData(new ImageData(buffer, target.w, target.h));
6275
+ }
6276
+
5178
6277
  // src/PixelData/extractPixelDataBuffer.ts
5179
6278
  var SCRATCH_BLIT4 = makeClippedBlit();
5180
6279
  function extractPixelDataBuffer(source, _x, _y, _w, _h) {
@@ -5189,9 +6288,9 @@ function extractPixelDataBuffer(source, _x, _y, _w, _h) {
5189
6288
  w: _w,
5190
6289
  h: _h
5191
6290
  };
5192
- const srcW = source.width;
5193
- const srcH = source.height;
5194
- const srcData = source.data32;
6291
+ const srcW = source.w;
6292
+ const srcH = source.h;
6293
+ const srcData = source.data;
5195
6294
  if (w <= 0 || h <= 0) {
5196
6295
  return new Uint32Array(0);
5197
6296
  }
@@ -5228,24 +6327,24 @@ function extractPixelData(source, _x, _y, _w, _h) {
5228
6327
  w: _w,
5229
6328
  h: _h
5230
6329
  };
5231
- const result = new PixelData(new ImageData(w, h));
6330
+ const result = makePixelData(new ImageData(w, h));
5232
6331
  const buffer = extractPixelDataBuffer(source, x, y, w, h);
5233
- result.data32.set(buffer);
6332
+ result.data.set(buffer);
5234
6333
  return result;
5235
6334
  }
5236
6335
 
5237
6336
  // src/PixelData/pixelDataToAlphaMask.ts
5238
6337
  function pixelDataToAlphaMask(pixelData) {
5239
6338
  const {
5240
- data32,
5241
- width,
5242
- height
6339
+ data,
6340
+ w,
6341
+ h
5243
6342
  } = pixelData;
5244
- const len = data32.length;
5245
- const mask = makeAlphaMask(width, height);
6343
+ const len = data.length;
6344
+ const mask = makeAlphaMask(w, h);
5246
6345
  const maskData = mask.data;
5247
6346
  for (let i = 0; i < len; i++) {
5248
- const val = data32[i];
6347
+ const val = data[i];
5249
6348
  maskData[i] = val >>> 24 & 255;
5250
6349
  }
5251
6350
  return mask;
@@ -5253,9 +6352,9 @@ function pixelDataToAlphaMask(pixelData) {
5253
6352
 
5254
6353
  // src/PixelData/reflectPixelData.ts
5255
6354
  function reflectPixelDataHorizontal(pixelData) {
5256
- const width = pixelData.width;
5257
- const height = pixelData.height;
5258
- const data = pixelData.data32;
6355
+ const width = pixelData.w;
6356
+ const height = pixelData.h;
6357
+ const data = pixelData.data;
5259
6358
  const halfWidth = Math.floor(width / 2);
5260
6359
  for (let y = 0; y < height; y++) {
5261
6360
  const rowOffset = y * width;
@@ -5269,9 +6368,9 @@ function reflectPixelDataHorizontal(pixelData) {
5269
6368
  }
5270
6369
  }
5271
6370
  function reflectPixelDataVertical(pixelData) {
5272
- const width = pixelData.width;
5273
- const height = pixelData.height;
5274
- const data = pixelData.data32;
6371
+ const width = pixelData.w;
6372
+ const height = pixelData.h;
6373
+ const data = pixelData.data;
5275
6374
  const halfHeight = Math.floor(height / 2);
5276
6375
  for (let y = 0; y < halfHeight; y++) {
5277
6376
  const topRowOffset = y * width;
@@ -5288,19 +6387,21 @@ function reflectPixelDataVertical(pixelData) {
5288
6387
 
5289
6388
  // src/PixelData/resamplePixelData.ts
5290
6389
  function resamplePixelData(pixelData, factor) {
5291
- const {
5292
- data,
5293
- width,
5294
- height
5295
- } = resample32(pixelData.data32, pixelData.width, pixelData.height, factor);
5296
- return new PixelData(new ImageData(new Uint8ClampedArray(data.buffer), width, height));
6390
+ const output = {};
6391
+ const resampled = resampleUint32Array(pixelData.data, pixelData.w, pixelData.h, factor, output);
6392
+ resampled.imageData = uInt32ArrayToImageData(resampled.data, resampled.w, resampled.h);
6393
+ return resampled;
6394
+ }
6395
+ function resamplePixelDataInPlace(pixelData, factor) {
6396
+ const resampled = resampleUint32Array(pixelData.data, pixelData.w, pixelData.h, factor, pixelData);
6397
+ resampled.imageData = uInt32ArrayToImageData(resampled.data, resampled.w, resampled.h);
5297
6398
  }
5298
6399
 
5299
6400
  // src/PixelData/rotatePixelData.ts
5300
6401
  function rotatePixelData(pixelData) {
5301
- const width = pixelData.width;
5302
- const height = pixelData.height;
5303
- const data = pixelData.data32;
6402
+ const width = pixelData.w;
6403
+ const height = pixelData.h;
6404
+ const data = pixelData.data;
5304
6405
  if (width === height) {
5305
6406
  rotateSquareInPlace(pixelData);
5306
6407
  return;
@@ -5318,11 +6419,11 @@ function rotatePixelData(pixelData) {
5318
6419
  }
5319
6420
  }
5320
6421
  const newImageData = new ImageData(new Uint8ClampedArray(newData32.buffer), newWidth, newHeight);
5321
- pixelData.set(newImageData);
6422
+ setPixelData(pixelData, newImageData);
5322
6423
  }
5323
6424
  function rotateSquareInPlace(pixelData) {
5324
- const n = pixelData.width;
5325
- const data = pixelData.data32;
6425
+ const n = pixelData.w;
6426
+ const data = pixelData.data;
5326
6427
  for (let i = 0; i < n / 2; i++) {
5327
6428
  for (let j = i; j < n - i - 1; j++) {
5328
6429
  const top = i * n + j;
@@ -5338,6 +6439,16 @@ function rotateSquareInPlace(pixelData) {
5338
6439
  }
5339
6440
  }
5340
6441
 
6442
+ // src/PixelData/uInt32ArrayToPixelData.ts
6443
+ function uInt32ArrayToPixelData(data, width, height) {
6444
+ const buffer = data.buffer;
6445
+ const byteOffset = data.byteOffset;
6446
+ const byteLength = data.byteLength;
6447
+ const clampedArray = new Uint8ClampedArray(buffer, byteOffset, byteLength);
6448
+ const imageData = new ImageData(clampedArray, width, height);
6449
+ return makePixelData(imageData);
6450
+ }
6451
+
5341
6452
  // src/PixelData/writePixelDataBuffer.ts
5342
6453
  var SCRATCH_BLIT5 = makeClippedBlit();
5343
6454
  function writePixelDataBuffer(target, data, _x, _y, _w, _h) {
@@ -5352,9 +6463,9 @@ function writePixelDataBuffer(target, data, _x, _y, _w, _h) {
5352
6463
  w: _w,
5353
6464
  h: _h
5354
6465
  };
5355
- const dstW = target.width;
5356
- const dstH = target.height;
5357
- const dstData = target.data32;
6466
+ const dstW = target.w;
6467
+ const dstH = target.h;
6468
+ const dstData = target.data;
5358
6469
  const clip = resolveBlitClipping(x, y, 0, 0, w, h, dstW, dstH, w, h, SCRATCH_BLIT5);
5359
6470
  if (!clip.inBounds) return;
5360
6471
  const {
@@ -5381,26 +6492,54 @@ function writePaintBufferToPixelData(target, paintBuffer, writePixelDataBufferFn
5381
6492
  if (tile) {
5382
6493
  const dx = tile.tx << tileShift;
5383
6494
  const dy = tile.ty << tileShift;
5384
- writePixelDataBufferFn(target, tile.data32, dx, dy, tile.width, tile.height);
6495
+ writePixelDataBufferFn(target, tile.data, dx, dy, tile.w, tile.h);
5385
6496
  }
5386
6497
  }
5387
6498
  }
6499
+
6500
+ // src/Tile/MaskTile.ts
6501
+ var makeAlphaMaskTile = (id, tx, ty, tileSize, tileArea) => {
6502
+ return {
6503
+ tileType: 1 /* MASK */,
6504
+ type: 0 /* ALPHA */,
6505
+ data: new Uint8Array(tileArea),
6506
+ w: tileSize,
6507
+ h: tileSize,
6508
+ id,
6509
+ tx,
6510
+ ty
6511
+ };
6512
+ };
6513
+ var makeBinaryMaskTile = (id, tx, ty, tileSize, tileArea) => {
6514
+ return {
6515
+ tileType: 1 /* MASK */,
6516
+ type: 1 /* BINARY */,
6517
+ data: new Uint8Array(tileArea),
6518
+ w: tileSize,
6519
+ h: tileSize,
6520
+ id,
6521
+ tx,
6522
+ ty
6523
+ };
6524
+ };
5388
6525
  // Annotate the CommonJS export names for ESM import in node:
5389
6526
  0 && (module.exports = {
6527
+ AlphaMaskPaintBuffer,
5390
6528
  BASE_FAST_BLEND_MODE_FUNCTIONS,
5391
6529
  BASE_PERFECT_BLEND_MODE_FUNCTIONS,
5392
6530
  BaseBlendMode,
6531
+ BinaryMaskPaintBuffer,
5393
6532
  CANVAS_COMPOSITE_MAP,
6533
+ ColorPaintBuffer,
6534
+ ERRORS,
5394
6535
  HistoryManager,
5395
- IndexedImage,
5396
6536
  MaskType,
5397
- PaintBuffer,
6537
+ PaintMaskOutline,
5398
6538
  PixelAccumulator,
5399
- PixelData,
5400
6539
  PixelEngineConfig,
5401
- PixelTile,
5402
- PixelTilePool,
5403
6540
  PixelWriter,
6541
+ TilePool,
6542
+ TileType,
5404
6543
  UnsupportedFormatError,
5405
6544
  applyAlphaMaskToPixelData,
5406
6545
  applyBinaryMaskToAlphaMask,
@@ -5433,6 +6572,7 @@ function writePaintBufferToPixelData(target, paintBuffer, writePixelDataBufferFn
5433
6572
  copyImageData,
5434
6573
  copyImageDataLike,
5435
6574
  copyMask,
6575
+ copyPixelData,
5436
6576
  darkenFast,
5437
6577
  darkenPerfect,
5438
6578
  darkerFast,
@@ -5440,10 +6580,19 @@ function writePaintBufferToPixelData(target, paintBuffer, writePixelDataBufferFn
5440
6580
  deserializeImageData,
5441
6581
  deserializeNullableImageData,
5442
6582
  deserializeRawImageData,
6583
+ destinationAtopFast,
6584
+ destinationAtopPerfect,
6585
+ destinationInFast,
6586
+ destinationInPerfect,
6587
+ destinationOutFast,
6588
+ destinationOutPerfect,
6589
+ destinationOverFast,
6590
+ destinationOverPerfect,
5443
6591
  differenceFast,
5444
6592
  differencePerfect,
5445
6593
  divideFast,
5446
6594
  dividePerfect,
6595
+ eachTileInBounds,
5447
6596
  exclusionFast,
5448
6597
  exclusionPerfect,
5449
6598
  extractImageDataBuffer,
@@ -5459,6 +6608,7 @@ function writePaintBufferToPixelData(target, paintBuffer, writePixelDataBufferFn
5459
6608
  floodFillSelection,
5460
6609
  forEachLinePoint,
5461
6610
  getImageDataFromClipboard,
6611
+ getIndexedImageColor,
5462
6612
  getIndexedImageColorCounts,
5463
6613
  getRectsBounds,
5464
6614
  getSupportedPixelFormats,
@@ -5469,7 +6619,7 @@ function writePaintBufferToPixelData(target, paintBuffer, writePixelDataBufferFn
5469
6619
  imageDataToAlphaMaskBuffer,
5470
6620
  imageDataToDataUrl,
5471
6621
  imageDataToImgBlob,
5472
- imageDataToUInt32Array,
6622
+ imageDataToUint32Array,
5473
6623
  imgBlobToImageData,
5474
6624
  indexedImageToAverageColor,
5475
6625
  indexedImageToImageData,
@@ -5490,26 +6640,42 @@ function writePaintBufferToPixelData(target, paintBuffer, writePixelDataBufferFn
5490
6640
  linearLightFast,
5491
6641
  linearLightPerfect,
5492
6642
  makeAlphaMask,
6643
+ makeAlphaMaskPaintBufferCanvasRenderer,
6644
+ makeAlphaMaskTile,
5493
6645
  makeBinaryMask,
6646
+ makeBinaryMaskFromAlphaMask,
6647
+ makeBinaryMaskOutline,
6648
+ makeBinaryMaskPaintBufferCanvasRenderer,
6649
+ makeBinaryMaskTile,
5494
6650
  makeBlendModeRegistry,
5495
6651
  makeCanvasFrameRenderer,
6652
+ makeCanvasPixelDataRenderer,
6653
+ makeCircleBinaryMaskOutline,
5496
6654
  makeCirclePaintAlphaMask,
5497
6655
  makeCirclePaintBinaryMask,
5498
6656
  makeClippedBlit,
5499
6657
  makeClippedRect,
6658
+ makeColorPaintBufferCanvasRenderer,
5500
6659
  makeFastBlendModeRegistry,
5501
6660
  makeFullPixelMutator,
5502
6661
  makeHistoryAction,
5503
6662
  makeImageDataLike,
6663
+ makeIndexedImage,
6664
+ makeIndexedImageFromImageData,
6665
+ makeIndexedImageFromImageDataRaw,
5504
6666
  makePaintAlphaMask,
5505
6667
  makePaintBinaryMask,
5506
- makePaintBufferCanvasRenderer,
6668
+ makePaintCursorRenderer,
5507
6669
  makePerfectBlendModeRegistry,
5508
6670
  makePixelCanvas,
6671
+ makePixelData,
6672
+ makePixelTile,
6673
+ makeRectBinaryMaskOutline,
5509
6674
  makeRectFalloffPaintAlphaMask,
5510
6675
  makeReusableCanvas,
5511
6676
  makeReusableImageData,
5512
6677
  makeReusableOffscreenCanvas,
6678
+ makeReusablePixelData,
5513
6679
  merge2BinaryMaskRects,
5514
6680
  mergeAlphaMasks,
5515
6681
  mergeBinaryMaskRects,
@@ -5546,10 +6712,11 @@ function writePaintBufferToPixelData(target, paintBuffer, writePixelDataBufferFn
5546
6712
  pixelDataToAlphaMask,
5547
6713
  reflectPixelDataHorizontal,
5548
6714
  reflectPixelDataVertical,
5549
- resample32,
5550
6715
  resampleImageData,
5551
6716
  resampleIndexedImage,
5552
6717
  resamplePixelData,
6718
+ resamplePixelDataInPlace,
6719
+ resampleUint32Array,
5553
6720
  resizeImageData,
5554
6721
  resolveBlitClipping,
5555
6722
  resolveRectClipping,
@@ -5559,8 +6726,15 @@ function writePaintBufferToPixelData(target, paintBuffer, writePixelDataBufferFn
5559
6726
  serializeImageData,
5560
6727
  serializeNullableImageData,
5561
6728
  setMaskData,
6729
+ setPixelData,
5562
6730
  softLightFast,
5563
6731
  softLightPerfect,
6732
+ sourceAtopFast,
6733
+ sourceAtopPerfect,
6734
+ sourceInFast,
6735
+ sourceInPerfect,
6736
+ sourceOutFast,
6737
+ sourceOutPerfect,
5564
6738
  sourceOverFast,
5565
6739
  sourceOverPerfect,
5566
6740
  subtractBinaryMaskRects,
@@ -5571,6 +6745,7 @@ function writePaintBufferToPixelData(target, paintBuffer, writePixelDataBufferFn
5571
6745
  trimRectBounds,
5572
6746
  uInt32ArrayToImageData,
5573
6747
  uInt32ArrayToImageDataLike,
6748
+ uInt32ArrayToPixelData,
5574
6749
  unpackAlpha,
5575
6750
  unpackBlue,
5576
6751
  unpackColor,
@@ -5584,6 +6759,8 @@ function writePaintBufferToPixelData(target, paintBuffer, writePixelDataBufferFn
5584
6759
  writeImageDataToClipboard,
5585
6760
  writeImgBlobToClipboard,
5586
6761
  writePaintBufferToPixelData,
5587
- writePixelDataBuffer
6762
+ writePixelDataBuffer,
6763
+ xorFast,
6764
+ xorPerfect
5588
6765
  });
5589
6766
  //# sourceMappingURL=index.prod.cjs.map