pixel-data-js 0.36.0 → 0.38.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 (73) hide show
  1. package/dist/index.prod.cjs +376 -305
  2. package/dist/index.prod.cjs.map +1 -1
  3. package/dist/index.prod.d.ts +109 -67
  4. package/dist/index.prod.js +372 -304
  5. package/dist/index.prod.js.map +1 -1
  6. package/package.json +2 -2
  7. package/src/Algorithm/floodFillSelection.ts +3 -2
  8. package/src/BlendModes/blend-modes-fast.ts +2 -1
  9. package/src/BlendModes/blend-modes-perfect.ts +2 -1
  10. package/src/Canvas/ReusableCanvas.ts +0 -5
  11. package/src/Color/_color-types.ts +8 -0
  12. package/src/Color/colorDistance.ts +9 -0
  13. package/src/Color/convert-color.ts +43 -0
  14. package/src/Color/lerpColor32.ts +44 -0
  15. package/src/Color/pack-color.ts +38 -0
  16. package/src/History/HistoryAction.ts +2 -2
  17. package/src/History/PixelAccumulator.ts +13 -15
  18. package/src/History/PixelMutator/mutatorBlendColor.ts +2 -1
  19. package/src/History/PixelMutator/mutatorBlendColorPaintAlphaMask.ts +1 -1
  20. package/src/History/PixelMutator/mutatorBlendColorPaintBinaryMask.ts +1 -1
  21. package/src/History/PixelMutator/mutatorBlendColorPaintMask.ts +23 -8
  22. package/src/History/PixelMutator/mutatorBlendColorPaintRect.ts +2 -1
  23. package/src/History/PixelMutator/mutatorBlendPixel.ts +2 -1
  24. package/src/History/PixelMutator/mutatorClear.ts +1 -1
  25. package/src/History/PixelMutator/mutatorFill.ts +1 -1
  26. package/src/History/PixelMutator/mutatorFillBinaryMask.ts +1 -1
  27. package/src/History/PixelWriter.ts +5 -5
  28. package/src/ImageData/serialization.ts +7 -2
  29. package/src/IndexedImage/IndexedImage.ts +1 -1
  30. package/src/IndexedImage/indexedImageToAverageColor.ts +3 -2
  31. package/src/Mask/_mask-types.ts +9 -0
  32. package/src/Paint/AlphaMaskPaintBuffer.ts +26 -26
  33. package/src/Paint/BinaryMaskPaintBuffer.ts +19 -19
  34. package/src/Paint/ColorPaintBuffer.ts +40 -42
  35. package/src/Paint/Commit/AlphaMaskPaintBufferCommitter.ts +1 -1
  36. package/src/Paint/Commit/AlphaMaskPaintBufferManager.ts +6 -7
  37. package/src/Paint/Commit/BinaryMaskPaintBufferCommitter.ts +1 -1
  38. package/src/Paint/Commit/BinaryMaskPaintBufferManager.ts +6 -7
  39. package/src/Paint/Commit/ColorPaintBufferManager.ts +6 -7
  40. package/src/Paint/Commit/commitColorPaintBuffer.ts +2 -6
  41. package/src/Paint/Commit/commitMaskPaintBuffer.ts +3 -7
  42. package/src/Paint/Render/AlphaMaskPaintBufferCanvasRenderer.ts +42 -25
  43. package/src/Paint/Render/BinaryMaskPaintBufferCanvasRenderer.ts +40 -24
  44. package/src/Paint/Render/ColorPaintBufferCanvasRenderer.ts +21 -21
  45. package/src/Paint/Render/PaintCursorRenderer.ts +3 -2
  46. package/src/Paint/eachTileInBounds.ts +9 -10
  47. package/src/PixelData/blendColorPixelData.ts +2 -1
  48. package/src/PixelData/blendColorPixelDataAlphaMask.ts +2 -1
  49. package/src/PixelData/blendColorPixelDataBinaryMask.ts +2 -1
  50. package/src/PixelData/blendColorPixelDataMask.ts +2 -1
  51. package/src/PixelData/blendColorPixelDataPaintAlphaMask.ts +1 -1
  52. package/src/PixelData/blendColorPixelDataPaintBinaryMask.ts +1 -1
  53. package/src/PixelData/blendColorPixelDataPaintMask.ts +19 -8
  54. package/src/PixelData/blendPixel.ts +2 -1
  55. package/src/PixelData/blendPixelData.ts +2 -1
  56. package/src/PixelData/blendPixelDataAlphaMask.ts +2 -1
  57. package/src/PixelData/blendPixelDataBinaryMask.ts +2 -1
  58. package/src/PixelData/blendPixelDataPaintBuffer.ts +2 -3
  59. package/src/PixelData/clearPixelDataFast.ts +1 -1
  60. package/src/PixelData/fillPixelData.ts +1 -1
  61. package/src/PixelData/fillPixelDataBinaryMask.ts +1 -1
  62. package/src/PixelData/fillPixelDataFast.ts +1 -1
  63. package/src/PixelData/writePaintBufferToPixelData.ts +1 -5
  64. package/src/Tile/MaskTile.ts +4 -0
  65. package/src/Tile/PixelTile.ts +2 -0
  66. package/src/Tile/TilePool.ts +9 -8
  67. package/src/Tile/TileTargetConfig.ts +27 -0
  68. package/src/Tile/_tile-types.ts +16 -0
  69. package/src/_types.ts +1 -6
  70. package/src/index.ts +7 -3
  71. package/src/History/PixelEngineConfig.ts +0 -28
  72. package/src/Internal/_constants.ts +0 -3
  73. package/src/color.ts +0 -112
@@ -32,7 +32,6 @@ __export(src_exports, {
32
32
  MaskType: () => MaskType,
33
33
  PaintMaskOutline: () => PaintMaskOutline,
34
34
  PixelAccumulator: () => PixelAccumulator,
35
- PixelEngineConfig: () => PixelEngineConfig,
36
35
  PixelWriter: () => PixelWriter,
37
36
  TilePool: () => TilePool,
38
37
  TileType: () => TileType,
@@ -59,6 +58,7 @@ __export(src_exports, {
59
58
  blendPixelDataPaintBuffer: () => blendPixelDataPaintBuffer,
60
59
  clearPixelDataFast: () => clearPixelDataFast,
61
60
  color32ToCssRGBA: () => color32ToCssRGBA,
61
+ color32ToCssRGBAString: () => color32ToCssRGBAString,
62
62
  color32ToHex: () => color32ToHex,
63
63
  colorBurnFast: () => colorBurnFast,
64
64
  colorBurnPerfect: () => colorBurnPerfect,
@@ -72,6 +72,7 @@ __export(src_exports, {
72
72
  copyMask: () => copyMask,
73
73
  copyPixelData: () => copyPixelData,
74
74
  cropPixelData: () => cropPixelData,
75
+ cssRGBAToColor32: () => cssRGBAToColor32,
75
76
  darkenFast: () => darkenFast,
76
77
  darkenPerfect: () => darkenPerfect,
77
78
  darkerFast: () => darkerFast,
@@ -184,6 +185,8 @@ __export(src_exports, {
184
185
  makeReusableImageData: () => makeReusableImageData,
185
186
  makeReusableOffscreenCanvas: () => makeReusableOffscreenCanvas,
186
187
  makeReusablePixelData: () => makeReusablePixelData,
188
+ makeTileTargetConfig: () => makeTileTargetConfig,
189
+ makeTileTargetMeta: () => makeTileTargetMeta,
187
190
  merge2BinaryMaskRects: () => merge2BinaryMaskRects,
188
191
  mergeAlphaMasks: () => mergeAlphaMasks,
189
192
  mergeBinaryMaskRects: () => mergeBinaryMaskRects,
@@ -283,43 +286,7 @@ __export(errors_exports, {
283
286
  var OFFSCREEN_CANVAS_CTX_FAILED = "Failed to create OffscreenCanvas context";
284
287
  var CANVAS_CTX_FAILED = "Failed to create Canvas context";
285
288
 
286
- // src/color.ts
287
- function packColor(r, g, b, a) {
288
- return (a << 24 | b << 16 | g << 8 | r) >>> 0;
289
- }
290
- function packRGBA({
291
- r,
292
- g,
293
- b,
294
- a
295
- }) {
296
- return (a << 24 | b << 16 | g << 8 | r) >>> 0;
297
- }
298
- var unpackRed = (packed) => packed >>> 0 & 255;
299
- var unpackGreen = (packed) => packed >>> 8 & 255;
300
- var unpackBlue = (packed) => packed >>> 16 & 255;
301
- var unpackAlpha = (packed) => packed >>> 24 & 255;
302
- function unpackColor(packed) {
303
- return {
304
- r: packed >>> 0 & 255,
305
- g: packed >>> 8 & 255,
306
- b: packed >>> 16 & 255,
307
- a: packed >>> 24 & 255
308
- };
309
- }
310
- var SCRATCH_RGBA = {
311
- r: 0,
312
- g: 0,
313
- b: 0,
314
- a: 0
315
- };
316
- function unpackColorTo(packed, scratch = SCRATCH_RGBA) {
317
- scratch.r = packed >>> 0 & 255;
318
- scratch.g = packed >>> 8 & 255;
319
- scratch.b = packed >>> 16 & 255;
320
- scratch.a = packed >>> 24 & 255;
321
- return scratch;
322
- }
289
+ // src/Color/colorDistance.ts
323
290
  function colorDistance(a, b) {
324
291
  const dr = (a & 255) - (b & 255);
325
292
  const dg = (a >>> 8 & 255) - (b >>> 8 & 255);
@@ -327,34 +294,6 @@ function colorDistance(a, b) {
327
294
  const da = (a >>> 24 & 255) - (b >>> 24 & 255);
328
295
  return dr * dr + dg * dg + db * db + da * da;
329
296
  }
330
- function lerpColor32(a, b, t) {
331
- const r = (a & 255) + t * ((b & 255) - (a & 255));
332
- const g = (a >>> 8 & 255) + t * ((b >>> 8 & 255) - (a >>> 8 & 255));
333
- const b_ = (a >>> 16 & 255) + t * ((b >>> 16 & 255) - (a >>> 16 & 255));
334
- const a_ = (a >>> 24 & 255) + t * ((b >>> 24 & 255) - (a >>> 24 & 255));
335
- return (a_ << 24 | b_ << 16 | g << 8 | r) >>> 0;
336
- }
337
- function lerpColor32Fast(src, dst, w) {
338
- const invA = 255 - w;
339
- const rb = (src & 16711935) * w + (dst & 16711935) * invA >>> 8 & 16711935;
340
- const ga = (src >>> 8 & 16711935) * w + (dst >>> 8 & 16711935) * invA >>> 8 & 16711935;
341
- return (rb | ga << 8) >>> 0;
342
- }
343
- function color32ToHex(color) {
344
- const r = (color & 255).toString(16).padStart(2, "0");
345
- const g = (color >>> 8 & 255).toString(16).padStart(2, "0");
346
- const b = (color >>> 16 & 255).toString(16).padStart(2, "0");
347
- const a = (color >>> 24 & 255).toString(16).padStart(2, "0");
348
- return `#${r}${g}${b}${a}`;
349
- }
350
- function color32ToCssRGBA(color) {
351
- const r = color & 255;
352
- const g = color >>> 8 & 255;
353
- const b = color >>> 16 & 255;
354
- const a = color >>> 24 & 255;
355
- const alpha = Number((a / 255).toFixed(3));
356
- return `rgba(${r},${g},${b},${alpha})`;
357
- }
358
297
 
359
298
  // src/ImageData/extractImageDataBuffer.ts
360
299
  function extractImageDataBuffer(imageData, _x, _y, _w, _h) {
@@ -2115,9 +2054,6 @@ function makeReusableCanvasMeta(factory) {
2115
2054
  canvas.width = width;
2116
2055
  canvas.height = height;
2117
2056
  ctx.imageSmoothingEnabled = false;
2118
- } else {
2119
- ctx.setTransform(1, 0, 0, 1, 0, 0);
2120
- ctx.clearRect(0, 0, width, height);
2121
2057
  }
2122
2058
  return result;
2123
2059
  }
@@ -2238,6 +2174,96 @@ async function writeImageDataToClipboard(imageData) {
2238
2174
  return writeImgBlobToClipboard(blob);
2239
2175
  }
2240
2176
 
2177
+ // src/Color/lerpColor32.ts
2178
+ function lerpColor32(a, b, t) {
2179
+ const r = (a & 255) + t * ((b & 255) - (a & 255));
2180
+ const g = (a >>> 8 & 255) + t * ((b >>> 8 & 255) - (a >>> 8 & 255));
2181
+ const b_ = (a >>> 16 & 255) + t * ((b >>> 16 & 255) - (a >>> 16 & 255));
2182
+ const a_ = (a >>> 24 & 255) + t * ((b >>> 24 & 255) - (a >>> 24 & 255));
2183
+ return (a_ << 24 | b_ << 16 | g << 8 | r) >>> 0;
2184
+ }
2185
+ function lerpColor32Fast(src, dst, w) {
2186
+ const invA = 255 - w;
2187
+ const rb = (src & 16711935) * w + (dst & 16711935) * invA >>> 8 & 16711935;
2188
+ const ga = (src >>> 8 & 16711935) * w + (dst >>> 8 & 16711935) * invA >>> 8 & 16711935;
2189
+ return (rb | ga << 8) >>> 0;
2190
+ }
2191
+
2192
+ // src/Color/convert-color.ts
2193
+ function color32ToHex(color) {
2194
+ const r = (color & 255).toString(16).padStart(2, "0");
2195
+ const g = (color >>> 8 & 255).toString(16).padStart(2, "0");
2196
+ const b = (color >>> 16 & 255).toString(16).padStart(2, "0");
2197
+ const a = (color >>> 24 & 255).toString(16).padStart(2, "0");
2198
+ return `#${r}${g}${b}${a}`;
2199
+ }
2200
+ function color32ToCssRGBAString(color) {
2201
+ const r = color & 255;
2202
+ const g = color >>> 8 & 255;
2203
+ const b = color >>> 16 & 255;
2204
+ const a = color >>> 24 & 255;
2205
+ const alpha = Number((a / 255).toFixed(3));
2206
+ return `rgba(${r},${g},${b},${alpha})`;
2207
+ }
2208
+ function color32ToCssRGBA(color) {
2209
+ const r = color & 255;
2210
+ const g = color >>> 8 & 255;
2211
+ const b = color >>> 16 & 255;
2212
+ const a = color >>> 24 & 255;
2213
+ return {
2214
+ r,
2215
+ g,
2216
+ b,
2217
+ a: a / 255
2218
+ };
2219
+ }
2220
+ function cssRGBAToColor32({
2221
+ r,
2222
+ g,
2223
+ b,
2224
+ a
2225
+ }) {
2226
+ return (a * 255 << 24 | b << 16 | g << 8 | r) >>> 0;
2227
+ }
2228
+
2229
+ // src/Color/pack-color.ts
2230
+ function packColor(r, g, b, a) {
2231
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
2232
+ }
2233
+ function packRGBA({
2234
+ r,
2235
+ g,
2236
+ b,
2237
+ a
2238
+ }) {
2239
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
2240
+ }
2241
+ var unpackRed = (packed) => packed >>> 0 & 255;
2242
+ var unpackGreen = (packed) => packed >>> 8 & 255;
2243
+ var unpackBlue = (packed) => packed >>> 16 & 255;
2244
+ var unpackAlpha = (packed) => packed >>> 24 & 255;
2245
+ function unpackColor(packed) {
2246
+ return {
2247
+ r: packed >>> 0 & 255,
2248
+ g: packed >>> 8 & 255,
2249
+ b: packed >>> 16 & 255,
2250
+ a: packed >>> 24 & 255
2251
+ };
2252
+ }
2253
+ var SCRATCH_RGBA = {
2254
+ r: 0,
2255
+ g: 0,
2256
+ b: 0,
2257
+ a: 0
2258
+ };
2259
+ function unpackColorTo(packed, scratch = SCRATCH_RGBA) {
2260
+ scratch.r = packed >>> 0 & 255;
2261
+ scratch.g = packed >>> 8 & 255;
2262
+ scratch.b = packed >>> 16 & 255;
2263
+ scratch.a = packed >>> 24 & 255;
2264
+ return scratch;
2265
+ }
2266
+
2241
2267
  // src/Control/BatchedQueue.ts
2242
2268
  function makeBatchedQueue(processor, queue) {
2243
2269
  let activeSet = /* @__PURE__ */ new Set();
@@ -2417,15 +2443,14 @@ var PixelAccumulator = class {
2417
2443
  * @param y pixel y coordinate
2418
2444
  */
2419
2445
  storePixelBeforeState(x, y) {
2420
- const shift = this.config.tileShift;
2421
2446
  const columns = this.config.targetColumns;
2422
- const targetWidth = this.config.target.w;
2423
- const targetHeight = this.config.target.h;
2447
+ const targetWidth = this.config.targetWidth;
2448
+ const targetHeight = this.config.targetHeight;
2424
2449
  if (x < 0 || x >= targetWidth || y < 0 || y >= targetHeight) {
2425
2450
  return null;
2426
2451
  }
2427
- const tx = x >> shift;
2428
- const ty = y >> shift;
2452
+ const tx = x * this.config.invTileSize | 0;
2453
+ const ty = y * this.config.invTileSize | 0;
2429
2454
  const id = ty * columns + tx;
2430
2455
  let tile = this.lookup[id];
2431
2456
  let added = false;
@@ -2452,10 +2477,10 @@ var PixelAccumulator = class {
2452
2477
  * @param h pixel height
2453
2478
  */
2454
2479
  storeRegionBeforeState(x, y, w, h) {
2455
- const shift = this.config.tileShift;
2456
2480
  const columns = this.config.targetColumns;
2457
- const targetWidth = this.config.target.w;
2458
- const targetHeight = this.config.target.h;
2481
+ const targetWidth = this.config.targetWidth;
2482
+ const targetHeight = this.config.targetHeight;
2483
+ const invTileSize = this.config.invTileSize;
2459
2484
  const clipX1 = Math.max(0, x);
2460
2485
  const clipY1 = Math.max(0, y);
2461
2486
  const clipX2 = Math.min(targetWidth - 1, x + w - 1);
@@ -2463,10 +2488,10 @@ var PixelAccumulator = class {
2463
2488
  if (clipX2 < clipX1 || clipY2 < clipY1) {
2464
2489
  return null;
2465
2490
  }
2466
- const startX = clipX1 >> shift;
2467
- const startY = clipY1 >> shift;
2468
- const endX = clipX2 >> shift;
2469
- const endY = clipY2 >> shift;
2491
+ const startX = clipX1 * invTileSize | 0;
2492
+ const startY = clipY1 * invTileSize | 0;
2493
+ const endX = clipX2 * invTileSize | 0;
2494
+ const endY = clipY2 * invTileSize | 0;
2470
2495
  const startIndex = this.beforeTiles.length;
2471
2496
  for (let ty = startY; ty <= endY; ty++) {
2472
2497
  for (let tx = startX; tx <= endX; tx++) {
@@ -2583,31 +2608,6 @@ var PixelAccumulator = class {
2583
2608
  }
2584
2609
  };
2585
2610
 
2586
- // src/History/PixelEngineConfig.ts
2587
- var PixelEngineConfig = class {
2588
- tileSize;
2589
- // pixelX = tileX << tileShift
2590
- // pixelY = tileY << tileShift
2591
- tileShift;
2592
- tileMask;
2593
- tileArea;
2594
- target;
2595
- targetColumns = 0;
2596
- targetRows = 0;
2597
- constructor(tileSize, target) {
2598
- if ((tileSize & tileSize - 1) !== 0) {
2599
- throw new Error("tileSize must be a power of 2");
2600
- }
2601
- this.tileSize = tileSize;
2602
- this.tileShift = 31 - Math.clz32(tileSize);
2603
- this.tileMask = tileSize - 1;
2604
- this.tileArea = tileSize * tileSize;
2605
- this.target = target;
2606
- this.targetColumns = target.w + this.tileMask >> this.tileShift;
2607
- this.targetRows = target.h + this.tileMask >> this.tileShift;
2608
- }
2609
- };
2610
-
2611
2611
  // src/PixelData/applyAlphaMaskToPixelData.ts
2612
2612
  function applyAlphaMaskToPixelData(target, mask, opts) {
2613
2613
  const targetX = opts?.x ?? 0;
@@ -2801,6 +2801,8 @@ function makePixelTile(id, tx, ty, tileSize, tileArea) {
2801
2801
  id,
2802
2802
  tx,
2803
2803
  ty,
2804
+ x: tx * tileSize,
2805
+ y: ty * tileSize,
2804
2806
  w: tileSize,
2805
2807
  h: tileSize,
2806
2808
  data: data32,
@@ -2810,25 +2812,28 @@ function makePixelTile(id, tx, ty, tileSize, tileArea) {
2810
2812
 
2811
2813
  // src/Tile/TilePool.ts
2812
2814
  var TilePool = class {
2813
- constructor(config, tileFactory) {
2815
+ constructor(tileSize, tileFactory) {
2816
+ this.tileSize = tileSize;
2814
2817
  this.tileFactory = tileFactory;
2815
2818
  this.pool = [];
2816
- this.tileSize = config.tileSize;
2817
- this.tileArea = config.tileArea;
2819
+ this.tileSize = tileSize;
2820
+ this.tileArea = tileSize * tileSize;
2818
2821
  }
2819
2822
  pool;
2820
- tileSize;
2821
2823
  tileArea;
2822
2824
  getTile(id, tx, ty) {
2823
2825
  let tile = this.pool.pop();
2826
+ const tileSize = this.tileSize;
2824
2827
  if (tile) {
2825
2828
  tile.id = id;
2826
2829
  tile.tx = tx;
2827
2830
  tile.ty = ty;
2831
+ tile.x = tx * tileSize;
2832
+ tile.y = ty * tileSize;
2828
2833
  tile.data.fill(0);
2829
2834
  return tile;
2830
2835
  }
2831
- return this.tileFactory(id, tx, ty, this.tileSize, this.tileArea);
2836
+ return this.tileFactory(id, tx, ty, tileSize, this.tileArea);
2832
2837
  }
2833
2838
  releaseTile(tile) {
2834
2839
  this.pool.push(tile);
@@ -2845,6 +2850,25 @@ var TilePool = class {
2845
2850
  }
2846
2851
  };
2847
2852
 
2853
+ // src/Tile/TileTargetConfig.ts
2854
+ function makeTileTargetConfig(tileSize, target) {
2855
+ return {
2856
+ target,
2857
+ ...makeTileTargetMeta(tileSize, target)
2858
+ };
2859
+ }
2860
+ function makeTileTargetMeta(tileSize, target) {
2861
+ return {
2862
+ targetWidth: target.w,
2863
+ targetHeight: target.h,
2864
+ tileSize,
2865
+ invTileSize: 1 / tileSize,
2866
+ tileArea: tileSize * tileSize,
2867
+ targetColumns: Math.ceil(target.w / tileSize),
2868
+ targetRows: Math.ceil(target.h / tileSize)
2869
+ };
2870
+ }
2871
+
2848
2872
  // src/History/PixelWriter.ts
2849
2873
  var PixelWriter = class {
2850
2874
  historyManager;
@@ -2857,10 +2881,10 @@ var PixelWriter = class {
2857
2881
  constructor(target, mutatorFactory, options) {
2858
2882
  const tileSize = options?.tileSize ?? 256;
2859
2883
  const maxHistorySteps = options?.maxHistorySteps ?? 50;
2860
- this.config = new PixelEngineConfig(tileSize, target);
2884
+ this.config = makeTileTargetConfig(tileSize, target);
2861
2885
  this.historyManager = options?.historyManager ?? new HistoryManager(maxHistorySteps);
2862
2886
  this.historyActionFactory = options?.historyActionFactory ?? makeHistoryAction;
2863
- this.pixelTilePool = options?.pixelTilePool ?? new TilePool(this.config, makePixelTile);
2887
+ this.pixelTilePool = options?.pixelTilePool ?? new TilePool(this.config.tileSize, makePixelTile);
2864
2888
  this.accumulator = options?.accumulator ?? new PixelAccumulator(this.config, this.pixelTilePool);
2865
2889
  this.mutator = mutatorFactory(this);
2866
2890
  }
@@ -3639,18 +3663,22 @@ var mutatorBlendColorPaintBinaryMask = ((writer, deps = defaults8) => {
3639
3663
  // src/History/PixelMutator/mutatorBlendColorPaintMask.ts
3640
3664
  var defaults9 = {
3641
3665
  blendColorPixelDataAlphaMask,
3642
- blendColorPixelDataBinaryMask
3666
+ blendColorPixelDataBinaryMask,
3667
+ blendColorPixelData
3643
3668
  };
3644
3669
  var mutatorBlendColorPaintMask = ((writer, deps = defaults9) => {
3645
3670
  const {
3646
3671
  blendColorPixelDataBinaryMask: blendColorPixelDataBinaryMask2 = defaults9.blendColorPixelDataBinaryMask,
3647
- blendColorPixelDataAlphaMask: blendColorPixelDataAlphaMask2 = defaults9.blendColorPixelDataAlphaMask
3672
+ blendColorPixelDataAlphaMask: blendColorPixelDataAlphaMask2 = defaults9.blendColorPixelDataAlphaMask,
3673
+ blendColorPixelData: blendColorPixelData2 = defaults9.blendColorPixelData
3648
3674
  } = deps;
3649
3675
  const OPTS = {
3650
3676
  x: 0,
3651
3677
  y: 0,
3652
3678
  blendFn: sourceOverPerfect,
3653
- alpha: 255
3679
+ alpha: 255,
3680
+ w: void 0,
3681
+ h: void 0
3654
3682
  };
3655
3683
  return {
3656
3684
  blendColorPaintMask(color, mask, x, y, alpha = 255, blendFn = sourceOverPerfect) {
@@ -3662,11 +3690,17 @@ var mutatorBlendColorPaintMask = ((writer, deps = defaults9) => {
3662
3690
  OPTS.y = ty;
3663
3691
  OPTS.alpha = alpha;
3664
3692
  OPTS.blendFn = blendFn;
3665
- if (mask.type === 1 /* BINARY */) {
3666
- return didChange(blendColorPixelDataBinaryMask2(writer.config.target, color, mask, OPTS));
3667
- } else {
3693
+ OPTS.w = void 0;
3694
+ OPTS.h = void 0;
3695
+ if (mask.data) {
3696
+ if (mask.type === 1 /* BINARY */) {
3697
+ return didChange(blendColorPixelDataBinaryMask2(writer.config.target, color, mask, OPTS));
3698
+ }
3668
3699
  return didChange(blendColorPixelDataAlphaMask2(writer.config.target, color, mask, OPTS));
3669
3700
  }
3701
+ OPTS.w = mask.w;
3702
+ OPTS.h = mask.h;
3703
+ return didChange(blendColorPixelData2(writer.config.target, color, OPTS));
3670
3704
  }
3671
3705
  };
3672
3706
  });
@@ -4313,8 +4347,10 @@ function makeReusableImageData() {
4313
4347
  // src/ImageData/serialization.ts
4314
4348
  function base64EncodeArrayBuffer(buffer) {
4315
4349
  const uint8 = new Uint8Array(buffer);
4316
- const decoder = new TextDecoder("latin1");
4317
- const binary = decoder.decode(uint8);
4350
+ let binary = "";
4351
+ for (let i = 0; i < uint8.length; i++) {
4352
+ binary += String.fromCharCode(uint8[i]);
4353
+ }
4318
4354
  return btoa(binary);
4319
4355
  }
4320
4356
  function base64DecodeArrayBuffer(encoded) {
@@ -5355,26 +5391,55 @@ function trimRectBounds(x, y, w, h, targetWidth, targetHeight, out) {
5355
5391
  return res;
5356
5392
  }
5357
5393
 
5394
+ // src/Tile/MaskTile.ts
5395
+ var makeAlphaMaskTile = (id, tx, ty, tileSize, tileArea) => {
5396
+ return {
5397
+ tileType: 1 /* MASK */,
5398
+ type: 0 /* ALPHA */,
5399
+ data: new Uint8Array(tileArea),
5400
+ w: tileSize,
5401
+ h: tileSize,
5402
+ x: tx * tileSize,
5403
+ y: ty * tileSize,
5404
+ id,
5405
+ tx,
5406
+ ty
5407
+ };
5408
+ };
5409
+ var makeBinaryMaskTile = (id, tx, ty, tileSize, tileArea) => {
5410
+ return {
5411
+ tileType: 1 /* MASK */,
5412
+ type: 1 /* BINARY */,
5413
+ data: new Uint8Array(tileArea),
5414
+ w: tileSize,
5415
+ h: tileSize,
5416
+ x: tx * tileSize,
5417
+ y: ty * tileSize,
5418
+ id,
5419
+ tx,
5420
+ ty
5421
+ };
5422
+ };
5423
+
5358
5424
  // src/Paint/eachTileInBounds.ts
5359
5425
  function eachTileInBounds(config, lookup, tilePool, bounds, callback) {
5360
5426
  const {
5361
- tileShift,
5362
- targetColumns,
5363
5427
  targetRows,
5428
+ targetColumns,
5364
5429
  tileSize
5365
5430
  } = config;
5366
- const x1 = Math.max(0, bounds.x >> tileShift);
5367
- const y1 = Math.max(0, bounds.y >> tileShift);
5368
- const x2 = Math.min(targetColumns - 1, bounds.x + bounds.w - 1 >> tileShift);
5369
- const y2 = Math.min(targetRows - 1, bounds.y + bounds.h - 1 >> tileShift);
5431
+ const x1 = Math.max(0, Math.floor(bounds.x / tileSize));
5432
+ const y1 = Math.max(0, Math.floor(bounds.y / tileSize));
5433
+ const x2 = Math.min(targetColumns - 1, Math.floor((bounds.x + bounds.w - 1) / tileSize));
5434
+ const y2 = Math.min(targetRows - 1, Math.floor((bounds.y + bounds.h - 1) / tileSize));
5370
5435
  if (x1 > x2 || y1 > y2) return;
5371
5436
  for (let ty = y1; ty <= y2; ty++) {
5372
5437
  const rowOffset = ty * targetColumns;
5373
- const tileTop = ty << tileShift;
5438
+ const tileTop = ty * tileSize;
5374
5439
  for (let tx = x1; tx <= x2; tx++) {
5375
5440
  const id = rowOffset + tx;
5376
5441
  const tile = lookup[id] ?? (lookup[id] = tilePool.getTile(id, tx, ty));
5377
- const tileLeft = tx << tileShift;
5442
+ const tileLeft = tx * tileSize;
5378
5443
  const startX = bounds.x > tileLeft ? bounds.x : tileLeft;
5379
5444
  const startY = bounds.y > tileTop ? bounds.y : tileTop;
5380
5445
  const maskEndX = bounds.x + bounds.w;
@@ -5390,7 +5455,7 @@ function eachTileInBounds(config, lookup, tilePool, bounds, callback) {
5390
5455
 
5391
5456
  // src/Paint/AlphaMaskPaintBuffer.ts
5392
5457
  var AlphaMaskPaintBuffer = class {
5393
- constructor(config, tilePool) {
5458
+ constructor(config, tilePool = new TilePool(config.tileSize, makeAlphaMaskTile)) {
5394
5459
  this.config = config;
5395
5460
  this.tilePool = tilePool;
5396
5461
  this.lookup = [];
@@ -5410,9 +5475,9 @@ var AlphaMaskPaintBuffer = class {
5410
5475
  const lookup = this.lookup;
5411
5476
  const tilePool = this.tilePool;
5412
5477
  const config = this.config;
5413
- const tileShift = config.tileShift;
5414
- const tileMask = config.tileMask;
5415
- const target = config.target;
5478
+ const targetW = config.targetWidth;
5479
+ const targetH = config.targetHeight;
5480
+ const tileSize = config.tileSize;
5416
5481
  const {
5417
5482
  w: bW,
5418
5483
  h: bH,
@@ -5426,7 +5491,7 @@ var AlphaMaskPaintBuffer = class {
5426
5491
  this.forEachLinePointFn(x0, y0, x1, y1, (px, py) => {
5427
5492
  const topLeftX = Math.floor(px + centerOffsetX);
5428
5493
  const topLeftY = Math.floor(py + centerOffsetY);
5429
- trimRectBoundsFn(topLeftX, topLeftY, bW, bH, target.w, target.h, scratch);
5494
+ trimRectBoundsFn(topLeftX, topLeftY, bW, bH, targetW, targetH, scratch);
5430
5495
  if (scratch.w <= 0 || scratch.h <= 0) return;
5431
5496
  eachTileInBoundsFn(config, lookup, tilePool, scratch, (tile, bX, bY, bW_t, bH_t) => {
5432
5497
  const data = tile.data;
@@ -5434,8 +5499,8 @@ var AlphaMaskPaintBuffer = class {
5434
5499
  for (let i = 0; i < bH_t; i++) {
5435
5500
  const canvasY = bY + i;
5436
5501
  const bOff = (canvasY - topLeftY) * bW;
5437
- const tOff = (canvasY & tileMask) << tileShift;
5438
- const dS = tOff + (bX & tileMask);
5502
+ const tOff = (canvasY - tile.y) * tileSize;
5503
+ const dS = tOff + (bX - tile.x);
5439
5504
  for (let j = 0; j < bW_t; j++) {
5440
5505
  const canvasX = bX + j;
5441
5506
  const brushA = bD[bOff + (canvasX - topLeftX)];
@@ -5458,9 +5523,9 @@ var AlphaMaskPaintBuffer = class {
5458
5523
  const lookup = this.lookup;
5459
5524
  const tilePool = this.tilePool;
5460
5525
  const config = this.config;
5461
- const tileShift = config.tileShift;
5462
- const tileMask = config.tileMask;
5463
- const target = config.target;
5526
+ const targetW = config.targetWidth;
5527
+ const targetH = config.targetHeight;
5528
+ const tileSize = config.tileSize;
5464
5529
  const {
5465
5530
  w: bW,
5466
5531
  h: bH,
@@ -5474,7 +5539,7 @@ var AlphaMaskPaintBuffer = class {
5474
5539
  this.forEachLinePointFn(x0, y0, x1, y1, (px, py) => {
5475
5540
  const topLeftX = Math.floor(px + centerOffsetX);
5476
5541
  const topLeftY = Math.floor(py + centerOffsetY);
5477
- trimRectBoundsFn(topLeftX, topLeftY, bW, bH, target.w, target.h, scratch);
5542
+ trimRectBoundsFn(topLeftX, topLeftY, bW, bH, targetW, targetH, scratch);
5478
5543
  if (scratch.w <= 0 || scratch.h <= 0) return;
5479
5544
  eachTileInBoundsFn(config, lookup, tilePool, scratch, (tile, bX, bY, bW_t, bH_t) => {
5480
5545
  const data = tile.data;
@@ -5482,8 +5547,8 @@ var AlphaMaskPaintBuffer = class {
5482
5547
  for (let i = 0; i < bH_t; i++) {
5483
5548
  const canvasY = bY + i;
5484
5549
  const bOff = (canvasY - topLeftY) * bW;
5485
- const tOff = (canvasY & tileMask) << tileShift;
5486
- const dS = tOff + (bX & tileMask);
5550
+ const tOff = (canvasY - tile.y) * tileSize;
5551
+ const dS = tOff + (bX - tile.x);
5487
5552
  for (let j = 0; j < bW_t; j++) {
5488
5553
  const canvasX = bX + j;
5489
5554
  if (bD[bOff + (canvasX - topLeftX)]) {
@@ -5505,9 +5570,9 @@ var AlphaMaskPaintBuffer = class {
5505
5570
  const lookup = this.lookup;
5506
5571
  const tilePool = this.tilePool;
5507
5572
  const config = this.config;
5508
- const tileShift = config.tileShift;
5509
- const tileMask = config.tileMask;
5510
- const target = config.target;
5573
+ const targetW = config.targetWidth;
5574
+ const targetH = config.targetHeight;
5575
+ const tileSize = config.tileSize;
5511
5576
  const brushWidth = brush.w;
5512
5577
  const brushHeight = brush.h;
5513
5578
  const centerOffsetX = brush.centerOffsetX;
@@ -5518,15 +5583,15 @@ var AlphaMaskPaintBuffer = class {
5518
5583
  this.forEachLinePointFn(x0, y0, x1, y1, (px, py) => {
5519
5584
  const topLeftX = Math.floor(px + centerOffsetX);
5520
5585
  const topLeftY = Math.floor(py + centerOffsetY);
5521
- trimRectBoundsFn(topLeftX, topLeftY, brushWidth, brushHeight, target.w, target.h, scratch);
5586
+ trimRectBoundsFn(topLeftX, topLeftY, brushWidth, brushHeight, targetW, targetH, scratch);
5522
5587
  if (scratch.w <= 0 || scratch.h <= 0) return;
5523
5588
  eachTileInBoundsFn(config, lookup, tilePool, scratch, (tile, bX, bY, bW_t, bH_t) => {
5524
5589
  const data = tile.data;
5525
5590
  let tileChanged = false;
5526
5591
  for (let i = 0; i < bH_t; i++) {
5527
5592
  const canvasY = bY + i;
5528
- const tOff = (canvasY & tileMask) << tileShift;
5529
- const dS = tOff + (bX & tileMask);
5593
+ const tOff = (canvasY - tile.y) * tileSize;
5594
+ const dS = tOff + (bX - tile.x);
5530
5595
  for (let j = 0; j < bW_t; j++) {
5531
5596
  const idx = dS + j;
5532
5597
  if (alpha > data[idx]) {
@@ -5549,7 +5614,7 @@ var AlphaMaskPaintBuffer = class {
5549
5614
 
5550
5615
  // src/Paint/BinaryMaskPaintBuffer.ts
5551
5616
  var BinaryMaskPaintBuffer = class {
5552
- constructor(config, tilePool) {
5617
+ constructor(config, tilePool = new TilePool(config.tileSize, makeBinaryMaskTile)) {
5553
5618
  this.config = config;
5554
5619
  this.tilePool = tilePool;
5555
5620
  this.lookup = [];
@@ -5569,9 +5634,9 @@ var BinaryMaskPaintBuffer = class {
5569
5634
  const lookup = this.lookup;
5570
5635
  const tilePool = this.tilePool;
5571
5636
  const config = this.config;
5572
- const tileShift = config.tileShift;
5573
- const tileMask = config.tileMask;
5574
- const target = config.target;
5637
+ const targetW = config.targetWidth;
5638
+ const targetH = config.targetHeight;
5639
+ const tileSize = config.tileSize;
5575
5640
  const {
5576
5641
  w: bW,
5577
5642
  h: bH,
@@ -5585,7 +5650,7 @@ var BinaryMaskPaintBuffer = class {
5585
5650
  this.forEachLinePointFn(x0, y0, x1, y1, (px, py) => {
5586
5651
  const topLeftX = Math.floor(px + centerOffsetX);
5587
5652
  const topLeftY = Math.floor(py + centerOffsetY);
5588
- trimRectBoundsFn(topLeftX, topLeftY, bW, bH, target.w, target.h, scratch);
5653
+ trimRectBoundsFn(topLeftX, topLeftY, bW, bH, targetW, targetH, scratch);
5589
5654
  if (scratch.w <= 0 || scratch.h <= 0) return;
5590
5655
  eachTileInBoundsFn(config, lookup, tilePool, scratch, (tile, bX, bY, bW_t, bH_t) => {
5591
5656
  const data = tile.data;
@@ -5593,8 +5658,8 @@ var BinaryMaskPaintBuffer = class {
5593
5658
  for (let i = 0; i < bH_t; i++) {
5594
5659
  const canvasY = bY + i;
5595
5660
  const bOff = (canvasY - topLeftY) * bW;
5596
- const tOff = (canvasY & tileMask) << tileShift;
5597
- const dS = tOff + (bX & tileMask);
5661
+ const tOff = (canvasY - tile.y) * tileSize;
5662
+ const dS = tOff + (bX - tile.x);
5598
5663
  for (let j = 0; j < bW_t; j++) {
5599
5664
  const canvasX = bX + j;
5600
5665
  if (bD[bOff + (canvasX - topLeftX)]) {
@@ -5616,9 +5681,9 @@ var BinaryMaskPaintBuffer = class {
5616
5681
  const lookup = this.lookup;
5617
5682
  const tilePool = this.tilePool;
5618
5683
  const config = this.config;
5619
- const tileShift = config.tileShift;
5620
- const tileMask = config.tileMask;
5621
- const target = config.target;
5684
+ const targetW = config.targetWidth;
5685
+ const targetH = config.targetHeight;
5686
+ const tileSize = config.tileSize;
5622
5687
  const brushWidth = brush.w;
5623
5688
  const brushHeight = brush.h;
5624
5689
  const centerOffsetX = brush.centerOffsetX;
@@ -5629,15 +5694,15 @@ var BinaryMaskPaintBuffer = class {
5629
5694
  this.forEachLinePointFn(x0, y0, x1, y1, (px, py) => {
5630
5695
  const topLeftX = Math.floor(px + centerOffsetX);
5631
5696
  const topLeftY = Math.floor(py + centerOffsetY);
5632
- trimRectBoundsFn(topLeftX, topLeftY, brushWidth, brushHeight, target.w, target.h, scratch);
5697
+ trimRectBoundsFn(topLeftX, topLeftY, brushWidth, brushHeight, targetW, targetH, scratch);
5633
5698
  if (scratch.w <= 0 || scratch.h <= 0) return;
5634
5699
  eachTileInBoundsFn(config, lookup, tilePool, scratch, (tile, bX, bY, bW_t, bH_t) => {
5635
5700
  const data = tile.data;
5636
5701
  let tileChanged = false;
5637
5702
  for (let i = 0; i < bH_t; i++) {
5638
5703
  const canvasY = bY + i;
5639
- const tOff = (canvasY & tileMask) << tileShift;
5640
- const dS = tOff + (bX & tileMask);
5704
+ const tOff = (canvasY - tile.y) * tileSize;
5705
+ const dS = tOff + (bX - tile.x);
5641
5706
  for (let j = 0; j < bW_t; j++) {
5642
5707
  const idx = dS + j;
5643
5708
  if (data[idx] === 0) {
@@ -5679,9 +5744,9 @@ var ColorPaintBuffer = class {
5679
5744
  const lookup = this.lookup;
5680
5745
  const tilePool = this.tilePool;
5681
5746
  const config = this.config;
5682
- const tileShift = config.tileShift;
5683
- const tileMask = config.tileMask;
5684
- const target = config.target;
5747
+ const tileSize = config.tileSize;
5748
+ const targetW = config.targetWidth;
5749
+ const targetH = config.targetHeight;
5685
5750
  const {
5686
5751
  w: bW,
5687
5752
  h: bH,
@@ -5694,7 +5759,7 @@ var ColorPaintBuffer = class {
5694
5759
  forEachLinePoint(x0, y0, x1, y1, (px, py) => {
5695
5760
  const topLeftX = Math.floor(px + centerOffsetX);
5696
5761
  const topLeftY = Math.floor(py + centerOffsetY);
5697
- trimRectBounds(topLeftX, topLeftY, bW, bH, target.w, target.h, scratch);
5762
+ trimRectBounds(topLeftX, topLeftY, bW, bH, targetW, targetH, scratch);
5698
5763
  if (scratch.w <= 0 || scratch.h <= 0) return;
5699
5764
  eachTileInBounds(config, lookup, tilePool, scratch, (tile, bX, bY, bW_t, bH_t) => {
5700
5765
  const d32 = tile.data;
@@ -5702,8 +5767,8 @@ var ColorPaintBuffer = class {
5702
5767
  for (let i = 0; i < bH_t; i++) {
5703
5768
  const canvasY = bY + i;
5704
5769
  const bOff = (canvasY - topLeftY) * bW;
5705
- const tOff = (canvasY & tileMask) << tileShift;
5706
- const dS = tOff + (bX & tileMask);
5770
+ const tOff = (canvasY - tile.y) * tileSize;
5771
+ const dS = tOff + (bX - tile.x);
5707
5772
  for (let j = 0; j < bW_t; j++) {
5708
5773
  const canvasX = bX + j;
5709
5774
  const brushA = bD[bOff + (canvasX - topLeftX)];
@@ -5733,9 +5798,9 @@ var ColorPaintBuffer = class {
5733
5798
  const lookup = this.lookup;
5734
5799
  const tilePool = this.tilePool;
5735
5800
  const config = this.config;
5736
- const tileShift = config.tileShift;
5737
- const tileMask = config.tileMask;
5738
- const target = config.target;
5801
+ const tileSize = config.tileSize;
5802
+ const targetW = config.targetWidth;
5803
+ const targetH = config.targetHeight;
5739
5804
  const {
5740
5805
  w: bW,
5741
5806
  h: bH,
@@ -5747,7 +5812,7 @@ var ColorPaintBuffer = class {
5747
5812
  forEachLinePoint(x0, y0, x1, y1, (px, py) => {
5748
5813
  const topLeftX = Math.floor(px + centerOffsetX);
5749
5814
  const topLeftY = Math.floor(py + centerOffsetY);
5750
- trimRectBounds(topLeftX, topLeftY, bW, bH, target.w, target.h, scratch);
5815
+ trimRectBounds(topLeftX, topLeftY, bW, bH, targetW, targetH, scratch);
5751
5816
  if (scratch.w <= 0 || scratch.h <= 0) return;
5752
5817
  eachTileInBounds(config, lookup, tilePool, scratch, (tile, bX, bY, bW_t, bH_t) => {
5753
5818
  const d32 = tile.data;
@@ -5755,8 +5820,8 @@ var ColorPaintBuffer = class {
5755
5820
  for (let i = 0; i < bH_t; i++) {
5756
5821
  const canvasY = bY + i;
5757
5822
  const bOff = (canvasY - topLeftY) * bW;
5758
- const tOff = (canvasY & tileMask) << tileShift;
5759
- const dS = tOff + (bX & tileMask);
5823
+ const tOff = (canvasY - tile.y) * tileSize;
5824
+ const dS = tOff + (bX - tile.x);
5760
5825
  for (let j = 0; j < bW_t; j++) {
5761
5826
  const canvasX = bX + j;
5762
5827
  if (bD[bOff + (canvasX - topLeftX)]) {
@@ -5780,9 +5845,9 @@ var ColorPaintBuffer = class {
5780
5845
  const lookup = this.lookup;
5781
5846
  const tilePool = this.tilePool;
5782
5847
  const config = this.config;
5783
- const tileShift = config.tileShift;
5784
- const tileMask = config.tileMask;
5785
- const target = config.target;
5848
+ const targetW = config.targetWidth;
5849
+ const targetH = config.targetHeight;
5850
+ const tileSize = config.tileSize;
5786
5851
  const brushWidth = brush.w;
5787
5852
  const brushHeight = brush.h;
5788
5853
  const centerOffsetX = brush.centerOffsetX;
@@ -5791,15 +5856,15 @@ var ColorPaintBuffer = class {
5791
5856
  forEachLinePoint(x0, y0, x1, y1, (px, py) => {
5792
5857
  const topLeftX = Math.floor(px + centerOffsetX);
5793
5858
  const topLeftY = Math.floor(py + centerOffsetY);
5794
- trimRectBounds(topLeftX, topLeftY, brushWidth, brushHeight, target.w, target.h, scratch);
5859
+ trimRectBounds(topLeftX, topLeftY, brushWidth, brushHeight, targetW, targetH, scratch);
5795
5860
  if (scratch.w <= 0 || scratch.h <= 0) return;
5796
5861
  eachTileInBounds(config, lookup, tilePool, scratch, (tile, bX, bY, bW_t, bH_t) => {
5797
5862
  const d32 = tile.data;
5798
5863
  let tileChanged = false;
5799
5864
  for (let i = 0; i < bH_t; i++) {
5800
5865
  const canvasY = bY + i;
5801
- const tOff = (canvasY & tileMask) << tileShift;
5802
- const dS = tOff + (bX & tileMask);
5866
+ const tOff = (canvasY - tile.y) * tileSize;
5867
+ const dS = tOff + (bX - tile.x);
5803
5868
  for (let j = 0; j < bW_t; j++) {
5804
5869
  const idx = dS + j;
5805
5870
  if (d32[idx] !== color) {
@@ -5831,7 +5896,6 @@ var SCRATCH_OPTS = {
5831
5896
  };
5832
5897
  function commitMaskPaintBuffer(accumulator, paintBuffer, color, alpha = 255, blendFn = sourceOverPerfect, blendColorPixelDataMaskFn) {
5833
5898
  const config = accumulator.config;
5834
- const tileShift = config.tileShift;
5835
5899
  const lookup = paintBuffer.lookup;
5836
5900
  SCRATCH_OPTS.alpha = alpha;
5837
5901
  SCRATCH_OPTS.blendFn = blendFn;
@@ -5839,10 +5903,8 @@ function commitMaskPaintBuffer(accumulator, paintBuffer, color, alpha = 255, ble
5839
5903
  const tile = lookup[i];
5840
5904
  if (tile) {
5841
5905
  const didChange = accumulator.storeTileBeforeState(tile.id, tile.tx, tile.ty);
5842
- const dx = tile.tx << tileShift;
5843
- const dy = tile.ty << tileShift;
5844
- SCRATCH_OPTS.x = dx;
5845
- SCRATCH_OPTS.y = dy;
5906
+ SCRATCH_OPTS.x = tile.x;
5907
+ SCRATCH_OPTS.y = tile.y;
5846
5908
  SCRATCH_OPTS.w = tile.w;
5847
5909
  SCRATCH_OPTS.h = tile.h;
5848
5910
  didChange(blendColorPixelDataMaskFn(config.target, color, tile, SCRATCH_OPTS));
@@ -5858,49 +5920,51 @@ function makeAlphaMaskPaintBufferCommitter(accumulator, paintBuffer) {
5858
5920
  };
5859
5921
  }
5860
5922
 
5861
- // src/Internal/_constants.ts
5862
- var DEFAULT_CANVAS_FACTORY = (w, h) => new OffscreenCanvas(w, h);
5863
-
5864
- // src/Tile/MaskTile.ts
5865
- var makeAlphaMaskTile = (id, tx, ty, tileSize, tileArea) => {
5866
- return {
5867
- tileType: 1 /* MASK */,
5868
- type: 0 /* ALPHA */,
5869
- data: new Uint8Array(tileArea),
5870
- w: tileSize,
5871
- h: tileSize,
5872
- id,
5873
- tx,
5874
- ty
5923
+ // src/PixelData/ReusablePixelData.ts
5924
+ function makeReusablePixelData() {
5925
+ const pixelData = {
5926
+ w: 0,
5927
+ h: 0,
5928
+ data: null,
5929
+ imageData: null
5875
5930
  };
5876
- };
5877
- var makeBinaryMaskTile = (id, tx, ty, tileSize, tileArea) => {
5878
- return {
5879
- tileType: 1 /* MASK */,
5880
- type: 1 /* BINARY */,
5881
- data: new Uint8Array(tileArea),
5882
- w: tileSize,
5883
- h: tileSize,
5884
- id,
5885
- tx,
5886
- ty
5931
+ return function getReusablePixelData(width, height) {
5932
+ if (pixelData.w !== width || pixelData.h !== height) {
5933
+ setPixelData(pixelData, new ImageData(width, height));
5934
+ } else {
5935
+ pixelData.data.fill(0);
5936
+ }
5937
+ return pixelData;
5887
5938
  };
5888
- };
5939
+ }
5889
5940
 
5890
5941
  // src/Paint/Render/AlphaMaskPaintBufferCanvasRenderer.ts
5891
- function makeAlphaMaskPaintBufferCanvasRenderer(paintBuffer, canvasFactory = DEFAULT_CANVAS_FACTORY) {
5892
- const config = paintBuffer.config;
5893
- const tileSize = config.tileSize;
5894
- const tileShift = config.tileShift;
5895
- const tileArea = config.tileArea;
5896
- const lookup = paintBuffer.lookup;
5897
- const canvas = canvasFactory(tileSize, tileSize);
5898
- const ctx = canvas.getContext("2d");
5899
- if (!ctx) throw new Error(CANVAS_CTX_FAILED);
5900
- ctx.imageSmoothingEnabled = false;
5901
- const bridge = makePixelData(new ImageData(tileSize, tileSize));
5902
- const view32 = bridge.data;
5903
- return function drawPaintBuffer(targetCtx, color, alpha = 255, compOperation = "source-over") {
5942
+ function makeAlphaMaskPaintBufferCanvasRenderer(paintBuffer, reusableCanvasFactory) {
5943
+ const factory = reusableCanvasFactory ?? makeReusableOffscreenCanvas;
5944
+ const getBuffer = factory();
5945
+ const getBridge = makeReusablePixelData();
5946
+ let config;
5947
+ let tileSize;
5948
+ let tileArea;
5949
+ let lookup;
5950
+ let view32;
5951
+ let bridge;
5952
+ let canvas;
5953
+ let ctx;
5954
+ setBuffer(paintBuffer);
5955
+ function setBuffer(value) {
5956
+ paintBuffer = value;
5957
+ config = paintBuffer.config;
5958
+ tileSize = config.tileSize;
5959
+ tileArea = config.tileArea;
5960
+ lookup = paintBuffer.lookup;
5961
+ bridge = getBridge(tileSize, tileSize);
5962
+ view32 = bridge.data;
5963
+ const buff = getBuffer(tileSize, tileSize);
5964
+ canvas = buff.canvas;
5965
+ ctx = buff.ctx;
5966
+ }
5967
+ function draw(targetCtx, color, alpha = 255, compOperation = "source-over") {
5904
5968
  if (alpha === 0) return;
5905
5969
  const baseSrcAlpha = color >>> 24;
5906
5970
  const colorRGB = color & 16777215;
@@ -5923,29 +5987,31 @@ function makeAlphaMaskPaintBufferCanvasRenderer(paintBuffer, canvasFactory = DEF
5923
5987
  view32[p] = (colorRGB | finalA << 24) >>> 0;
5924
5988
  }
5925
5989
  }
5926
- const dx = tile.tx << tileShift;
5927
- const dy = tile.ty << tileShift;
5928
5990
  ctx.putImageData(bridge.imageData, 0, 0);
5929
- targetCtx.drawImage(canvas, dx, dy);
5991
+ targetCtx.drawImage(canvas, tile.x, tile.y);
5930
5992
  }
5931
5993
  }
5932
5994
  targetCtx.globalAlpha = 1;
5933
5995
  targetCtx.globalCompositeOperation = "source-over";
5996
+ }
5997
+ return {
5998
+ draw,
5999
+ setBuffer
5934
6000
  };
5935
6001
  }
5936
6002
 
5937
6003
  // src/Paint/Commit/AlphaMaskPaintBufferManager.ts
5938
- function makeAlphaMaskPaintBufferManager(writer, canvasFactory = DEFAULT_CANVAS_FACTORY) {
5939
- const pool = new TilePool(writer.config, makeAlphaMaskTile);
6004
+ function makeAlphaMaskPaintBufferManager(writer, reusableCanvasFactory) {
6005
+ const pool = new TilePool(writer.config.tileSize, makeAlphaMaskTile);
5940
6006
  const buffer = new AlphaMaskPaintBuffer(writer.config, pool);
5941
- const draw = makeAlphaMaskPaintBufferCanvasRenderer(buffer, canvasFactory);
6007
+ const renderer = makeAlphaMaskPaintBufferCanvasRenderer(buffer, reusableCanvasFactory);
5942
6008
  return {
5943
6009
  clear: buffer.clear.bind(buffer),
5944
6010
  paintRect: buffer.paintRect.bind(buffer),
5945
6011
  paintAlphaMask: buffer.paintAlphaMask.bind(buffer),
5946
6012
  paintBinaryMask: buffer.paintBinaryMask.bind(buffer),
5947
6013
  commit: makeAlphaMaskPaintBufferCommitter(writer.accumulator, buffer),
5948
- draw
6014
+ renderer
5949
6015
  };
5950
6016
  }
5951
6017
 
@@ -5957,19 +6023,32 @@ function makeBinaryMaskPaintBufferCommitter(accumulator, paintBuffer) {
5957
6023
  }
5958
6024
 
5959
6025
  // src/Paint/Render/BinaryMaskPaintBufferCanvasRenderer.ts
5960
- function makeBinaryMaskPaintBufferCanvasRenderer(paintBuffer, canvasFactory = DEFAULT_CANVAS_FACTORY) {
5961
- const config = paintBuffer.config;
5962
- const tileSize = config.tileSize;
5963
- const tileShift = config.tileShift;
5964
- const tileArea = config.tileArea;
5965
- const lookup = paintBuffer.lookup;
5966
- const canvas = canvasFactory(tileSize, tileSize);
5967
- const ctx = canvas.getContext("2d");
5968
- if (!ctx) throw new Error(CANVAS_CTX_FAILED);
5969
- ctx.imageSmoothingEnabled = false;
5970
- const bridge = makePixelData(new ImageData(tileSize, tileSize));
5971
- const view32 = bridge.data;
5972
- return function drawPaintBuffer(targetCtx, color, alpha = 255, compOperation = "source-over") {
6026
+ function makeBinaryMaskPaintBufferCanvasRenderer(paintBuffer, reusableCanvasFactory) {
6027
+ const factory = reusableCanvasFactory ?? makeReusableOffscreenCanvas;
6028
+ const getBuffer = factory();
6029
+ const getBridge = makeReusablePixelData();
6030
+ let config;
6031
+ let tileSize;
6032
+ let tileArea;
6033
+ let lookup;
6034
+ let view32;
6035
+ let bridge;
6036
+ let canvas;
6037
+ let ctx;
6038
+ setBuffer(paintBuffer);
6039
+ function setBuffer(value) {
6040
+ paintBuffer = value;
6041
+ config = paintBuffer.config;
6042
+ tileSize = config.tileSize;
6043
+ tileArea = config.tileArea;
6044
+ lookup = paintBuffer.lookup;
6045
+ bridge = getBridge(tileSize, tileSize);
6046
+ view32 = bridge.data;
6047
+ const buff = getBuffer(tileSize, tileSize);
6048
+ canvas = buff.canvas;
6049
+ ctx = buff.ctx;
6050
+ }
6051
+ function draw(targetCtx, color, alpha = 255, compOperation = "source-over") {
5973
6052
  if (alpha === 0) return;
5974
6053
  const baseSrcAlpha = color >>> 24;
5975
6054
  if (baseSrcAlpha === 0) return;
@@ -5985,28 +6064,30 @@ function makeBinaryMaskPaintBufferCanvasRenderer(paintBuffer, canvasFactory = DE
5985
6064
  view32[p] = color;
5986
6065
  }
5987
6066
  }
5988
- const dx = tile.tx << tileShift;
5989
- const dy = tile.ty << tileShift;
5990
6067
  ctx.putImageData(bridge.imageData, 0, 0);
5991
- targetCtx.drawImage(canvas, dx, dy);
6068
+ targetCtx.drawImage(canvas, tile.x, tile.y);
5992
6069
  }
5993
6070
  }
5994
6071
  targetCtx.globalAlpha = 1;
5995
6072
  targetCtx.globalCompositeOperation = "source-over";
6073
+ }
6074
+ return {
6075
+ draw,
6076
+ setBuffer
5996
6077
  };
5997
6078
  }
5998
6079
 
5999
6080
  // src/Paint/Commit/BinaryMaskPaintBufferManager.ts
6000
- function makeBinaryMaskPaintBufferManager(writer, canvasFactory = DEFAULT_CANVAS_FACTORY) {
6001
- const pool = new TilePool(writer.config, makeBinaryMaskTile);
6081
+ function makeBinaryMaskPaintBufferManager(writer, reusableCanvasFactory) {
6082
+ const pool = new TilePool(writer.config.tileSize, makeBinaryMaskTile);
6002
6083
  const buffer = new BinaryMaskPaintBuffer(writer.config, pool);
6003
- const draw = makeBinaryMaskPaintBufferCanvasRenderer(buffer, canvasFactory);
6084
+ const renderer = makeBinaryMaskPaintBufferCanvasRenderer(buffer, reusableCanvasFactory);
6004
6085
  return {
6005
6086
  clear: buffer.clear.bind(buffer),
6006
6087
  paintRect: buffer.paintRect.bind(buffer),
6007
6088
  paintBinaryMask: buffer.paintBinaryMask.bind(buffer),
6008
6089
  commit: makeBinaryMaskPaintBufferCommitter(writer.accumulator, buffer),
6009
- draw
6090
+ renderer
6010
6091
  };
6011
6092
  }
6012
6093
 
@@ -6021,7 +6102,6 @@ var SCRATCH_OPTS2 = {
6021
6102
  };
6022
6103
  function commitColorPaintBuffer(accumulator, paintBuffer, alpha = 255, blendFn = sourceOverPerfect, blendPixelDataFn = blendPixelData) {
6023
6104
  const config = accumulator.config;
6024
- const tileShift = config.tileShift;
6025
6105
  const lookup = paintBuffer.lookup;
6026
6106
  SCRATCH_OPTS2.alpha = alpha;
6027
6107
  SCRATCH_OPTS2.blendFn = blendFn;
@@ -6029,10 +6109,8 @@ function commitColorPaintBuffer(accumulator, paintBuffer, alpha = 255, blendFn =
6029
6109
  const tile = lookup[i];
6030
6110
  if (tile) {
6031
6111
  const didChange = accumulator.storeTileBeforeState(tile.id, tile.tx, tile.ty);
6032
- const dx = tile.tx << tileShift;
6033
- const dy = tile.ty << tileShift;
6034
- SCRATCH_OPTS2.x = dx;
6035
- SCRATCH_OPTS2.y = dy;
6112
+ SCRATCH_OPTS2.x = tile.x;
6113
+ SCRATCH_OPTS2.y = tile.y;
6036
6114
  SCRATCH_OPTS2.w = tile.w;
6037
6115
  SCRATCH_OPTS2.h = tile.h;
6038
6116
  didChange(blendPixelDataFn(config.target, tile, SCRATCH_OPTS2));
@@ -6049,44 +6127,47 @@ function makeColorPaintBufferCommitter(accumulator, paintBuffer) {
6049
6127
  }
6050
6128
 
6051
6129
  // src/Paint/Render/ColorPaintBufferCanvasRenderer.ts
6052
- function makeColorPaintBufferCanvasRenderer(paintBuffer, canvasFactory = DEFAULT_CANVAS_FACTORY) {
6053
- const config = paintBuffer.config;
6054
- const tileSize = config.tileSize;
6055
- const tileShift = config.tileShift;
6056
- const lookup = paintBuffer.lookup;
6057
- const canvas = canvasFactory(tileSize, tileSize);
6058
- const ctx = canvas.getContext("2d");
6059
- if (!ctx) throw new Error(CANVAS_CTX_FAILED);
6060
- ctx.imageSmoothingEnabled = false;
6061
- return function drawPaintBuffer(targetCtx, alpha = 255, compOperation = "source-over") {
6130
+ function makeColorPaintBufferCanvasRenderer(paintBuffer, reusableCanvasFactory) {
6131
+ const factory = reusableCanvasFactory ?? makeReusableOffscreenCanvas;
6132
+ const getBuffer = factory();
6133
+ function draw(targetCtx, alpha = 255, compOperation = "source-over") {
6134
+ const buff = getBuffer(paintBuffer.config.tileSize, paintBuffer.config.tileSize);
6135
+ const lookup = paintBuffer.lookup;
6136
+ const length = lookup.length;
6137
+ const ctx = buff.ctx;
6138
+ const canvas = buff.canvas;
6062
6139
  targetCtx.globalAlpha = alpha / 255;
6063
6140
  targetCtx.globalCompositeOperation = compOperation;
6064
- for (let i = 0; i < lookup.length; i++) {
6141
+ for (let i = 0; i < length; i++) {
6065
6142
  const tile = lookup[i];
6066
6143
  if (tile) {
6067
- const dx = tile.tx << tileShift;
6068
- const dy = tile.ty << tileShift;
6069
6144
  ctx.putImageData(tile.imageData, 0, 0);
6070
- targetCtx.drawImage(canvas, dx, dy);
6145
+ targetCtx.drawImage(canvas, tile.x, tile.y);
6071
6146
  }
6072
6147
  }
6073
6148
  targetCtx.globalAlpha = 1;
6074
6149
  targetCtx.globalCompositeOperation = "source-over";
6150
+ }
6151
+ return {
6152
+ draw,
6153
+ setBuffer(value) {
6154
+ paintBuffer = value;
6155
+ }
6075
6156
  };
6076
6157
  }
6077
6158
 
6078
6159
  // src/Paint/Commit/ColorPaintBufferManager.ts
6079
- function makeColorPaintBufferManager(writer, canvasFactory = DEFAULT_CANVAS_FACTORY) {
6080
- const pool = new TilePool(writer.config, makePixelTile);
6160
+ function makeColorPaintBufferManager(writer, reusableCanvasFactory) {
6161
+ const pool = new TilePool(writer.config.tileSize, makePixelTile);
6081
6162
  const buffer = new ColorPaintBuffer(writer.config, pool);
6082
- const draw = makeColorPaintBufferCanvasRenderer(buffer, canvasFactory);
6163
+ const renderer = makeColorPaintBufferCanvasRenderer(buffer, reusableCanvasFactory);
6083
6164
  return {
6084
6165
  clear: buffer.clear.bind(buffer),
6085
6166
  paintRect: buffer.paintRect.bind(buffer),
6086
6167
  paintAlphaMask: buffer.paintAlphaMask.bind(buffer),
6087
6168
  paintBinaryMask: buffer.paintBinaryMask.bind(buffer),
6088
6169
  commit: makeColorPaintBufferCommitter(writer.accumulator, buffer),
6089
- draw
6170
+ renderer
6090
6171
  };
6091
6172
  }
6092
6173
 
@@ -6222,24 +6303,6 @@ function makePaintRect(w, h) {
6222
6303
  };
6223
6304
  }
6224
6305
 
6225
- // src/PixelData/ReusablePixelData.ts
6226
- function makeReusablePixelData() {
6227
- const pixelData = {
6228
- w: 0,
6229
- h: 0,
6230
- data: null,
6231
- imageData: null
6232
- };
6233
- return function getReusablePixelData(width, height) {
6234
- if (pixelData.w !== width || pixelData.h !== height) {
6235
- setPixelData(pixelData, new ImageData(width, height));
6236
- } else {
6237
- pixelData.data.fill(0);
6238
- }
6239
- return pixelData;
6240
- };
6241
- }
6242
-
6243
6306
  // src/Paint/Render/PaintCursorRenderer.ts
6244
6307
  function makePaintCursorRenderer(reusableCanvasFactory) {
6245
6308
  const factory = reusableCanvasFactory ?? makeReusableOffscreenCanvas;
@@ -6392,20 +6455,29 @@ var SCRATCH_OPTS5 = {
6392
6455
  x: 0,
6393
6456
  y: 0,
6394
6457
  alpha: 255,
6395
- blendFn: sourceOverPerfect
6458
+ blendFn: sourceOverPerfect,
6459
+ w: void 0,
6460
+ h: void 0
6396
6461
  };
6397
- function blendColorPixelDataPaintMask(dst, color, mask, x, y, alpha = 255, blendFn = sourceOverPerfect) {
6462
+ function blendColorPixelDataPaintMask(target, color, mask, x, y, alpha = 255, blendFn = sourceOverPerfect) {
6398
6463
  const tx = x + mask.centerOffsetX;
6399
6464
  const ty = y + mask.centerOffsetY;
6400
6465
  SCRATCH_OPTS5.x = tx;
6401
6466
  SCRATCH_OPTS5.y = ty;
6402
6467
  SCRATCH_OPTS5.alpha = alpha;
6403
6468
  SCRATCH_OPTS5.blendFn = blendFn;
6404
- if (mask.type === 1 /* BINARY */) {
6405
- return blendColorPixelDataBinaryMask(dst, color, mask, SCRATCH_OPTS5);
6406
- } else {
6407
- return blendColorPixelDataAlphaMask(dst, color, mask, SCRATCH_OPTS5);
6469
+ SCRATCH_OPTS5.w = void 0;
6470
+ SCRATCH_OPTS5.h = void 0;
6471
+ if (mask.data) {
6472
+ if (mask.type === 1 /* BINARY */) {
6473
+ return blendColorPixelDataBinaryMask(target, color, mask, SCRATCH_OPTS5);
6474
+ } else {
6475
+ return blendColorPixelDataAlphaMask(target, color, mask, SCRATCH_OPTS5);
6476
+ }
6408
6477
  }
6478
+ SCRATCH_OPTS5.w = mask.w;
6479
+ SCRATCH_OPTS5.h = mask.h;
6480
+ return blendColorPixelData(target, color, SCRATCH_OPTS5);
6409
6481
  }
6410
6482
 
6411
6483
  // src/PixelData/blendPixelDataMask.ts
@@ -6425,13 +6497,12 @@ var SCRATCH_OPTS6 = {
6425
6497
  blendFn: void 0
6426
6498
  };
6427
6499
  function blendPixelDataPaintBuffer(target, paintBuffer, alpha = 255, blendFn, blendPixelDataFn = blendPixelData) {
6428
- const tileShift = paintBuffer.config.tileShift;
6429
6500
  const lookup = paintBuffer.lookup;
6430
6501
  for (let i = 0; i < lookup.length; i++) {
6431
6502
  const tile = lookup[i];
6432
6503
  if (tile) {
6433
- const x = tile.tx << tileShift;
6434
- const y = tile.ty << tileShift;
6504
+ const x = tile.x;
6505
+ const y = tile.y;
6435
6506
  SCRATCH_OPTS6.x = x;
6436
6507
  SCRATCH_OPTS6.y = y;
6437
6508
  SCRATCH_OPTS6.alpha = alpha;
@@ -6850,14 +6921,11 @@ function writePixelDataBuffer(target, data, _x, _y, _w, _h) {
6850
6921
 
6851
6922
  // src/PixelData/writePaintBufferToPixelData.ts
6852
6923
  function writePaintBufferToPixelData(target, paintBuffer, writePixelDataBufferFn = writePixelDataBuffer) {
6853
- const tileShift = paintBuffer.config.tileShift;
6854
6924
  const lookup = paintBuffer.lookup;
6855
6925
  for (let i = 0; i < lookup.length; i++) {
6856
6926
  const tile = lookup[i];
6857
6927
  if (tile) {
6858
- const dx = tile.tx << tileShift;
6859
- const dy = tile.ty << tileShift;
6860
- writePixelDataBufferFn(target, tile.data, dx, dy, tile.w, tile.h);
6928
+ writePixelDataBufferFn(target, tile.data, tile.x, tile.y, tile.w, tile.h);
6861
6929
  }
6862
6930
  }
6863
6931
  }
@@ -6910,7 +6978,6 @@ function writePixelData(target, source, x = 0, y = 0) {
6910
6978
  MaskType,
6911
6979
  PaintMaskOutline,
6912
6980
  PixelAccumulator,
6913
- PixelEngineConfig,
6914
6981
  PixelWriter,
6915
6982
  TilePool,
6916
6983
  TileType,
@@ -6937,6 +7004,7 @@ function writePixelData(target, source, x = 0, y = 0) {
6937
7004
  blendPixelDataPaintBuffer,
6938
7005
  clearPixelDataFast,
6939
7006
  color32ToCssRGBA,
7007
+ color32ToCssRGBAString,
6940
7008
  color32ToHex,
6941
7009
  colorBurnFast,
6942
7010
  colorBurnPerfect,
@@ -6950,6 +7018,7 @@ function writePixelData(target, source, x = 0, y = 0) {
6950
7018
  copyMask,
6951
7019
  copyPixelData,
6952
7020
  cropPixelData,
7021
+ cssRGBAToColor32,
6953
7022
  darkenFast,
6954
7023
  darkenPerfect,
6955
7024
  darkerFast,
@@ -7062,6 +7131,8 @@ function writePixelData(target, source, x = 0, y = 0) {
7062
7131
  makeReusableImageData,
7063
7132
  makeReusableOffscreenCanvas,
7064
7133
  makeReusablePixelData,
7134
+ makeTileTargetConfig,
7135
+ makeTileTargetMeta,
7065
7136
  merge2BinaryMaskRects,
7066
7137
  mergeAlphaMasks,
7067
7138
  mergeBinaryMaskRects,