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
@@ -13,43 +13,7 @@ __export(errors_exports, {
13
13
  var OFFSCREEN_CANVAS_CTX_FAILED = "Failed to create OffscreenCanvas context";
14
14
  var CANVAS_CTX_FAILED = "Failed to create Canvas context";
15
15
 
16
- // src/color.ts
17
- function packColor(r, g, b, a) {
18
- return (a << 24 | b << 16 | g << 8 | r) >>> 0;
19
- }
20
- function packRGBA({
21
- r,
22
- g,
23
- b,
24
- a
25
- }) {
26
- return (a << 24 | b << 16 | g << 8 | r) >>> 0;
27
- }
28
- var unpackRed = (packed) => packed >>> 0 & 255;
29
- var unpackGreen = (packed) => packed >>> 8 & 255;
30
- var unpackBlue = (packed) => packed >>> 16 & 255;
31
- var unpackAlpha = (packed) => packed >>> 24 & 255;
32
- function unpackColor(packed) {
33
- return {
34
- r: packed >>> 0 & 255,
35
- g: packed >>> 8 & 255,
36
- b: packed >>> 16 & 255,
37
- a: packed >>> 24 & 255
38
- };
39
- }
40
- var SCRATCH_RGBA = {
41
- r: 0,
42
- g: 0,
43
- b: 0,
44
- a: 0
45
- };
46
- function unpackColorTo(packed, scratch = SCRATCH_RGBA) {
47
- scratch.r = packed >>> 0 & 255;
48
- scratch.g = packed >>> 8 & 255;
49
- scratch.b = packed >>> 16 & 255;
50
- scratch.a = packed >>> 24 & 255;
51
- return scratch;
52
- }
16
+ // src/Color/colorDistance.ts
53
17
  function colorDistance(a, b) {
54
18
  const dr = (a & 255) - (b & 255);
55
19
  const dg = (a >>> 8 & 255) - (b >>> 8 & 255);
@@ -57,34 +21,6 @@ function colorDistance(a, b) {
57
21
  const da = (a >>> 24 & 255) - (b >>> 24 & 255);
58
22
  return dr * dr + dg * dg + db * db + da * da;
59
23
  }
60
- function lerpColor32(a, b, t) {
61
- const r = (a & 255) + t * ((b & 255) - (a & 255));
62
- const g = (a >>> 8 & 255) + t * ((b >>> 8 & 255) - (a >>> 8 & 255));
63
- const b_ = (a >>> 16 & 255) + t * ((b >>> 16 & 255) - (a >>> 16 & 255));
64
- const a_ = (a >>> 24 & 255) + t * ((b >>> 24 & 255) - (a >>> 24 & 255));
65
- return (a_ << 24 | b_ << 16 | g << 8 | r) >>> 0;
66
- }
67
- function lerpColor32Fast(src, dst, w) {
68
- const invA = 255 - w;
69
- const rb = (src & 16711935) * w + (dst & 16711935) * invA >>> 8 & 16711935;
70
- const ga = (src >>> 8 & 16711935) * w + (dst >>> 8 & 16711935) * invA >>> 8 & 16711935;
71
- return (rb | ga << 8) >>> 0;
72
- }
73
- function color32ToHex(color) {
74
- const r = (color & 255).toString(16).padStart(2, "0");
75
- const g = (color >>> 8 & 255).toString(16).padStart(2, "0");
76
- const b = (color >>> 16 & 255).toString(16).padStart(2, "0");
77
- const a = (color >>> 24 & 255).toString(16).padStart(2, "0");
78
- return `#${r}${g}${b}${a}`;
79
- }
80
- function color32ToCssRGBA(color) {
81
- const r = color & 255;
82
- const g = color >>> 8 & 255;
83
- const b = color >>> 16 & 255;
84
- const a = color >>> 24 & 255;
85
- const alpha = Number((a / 255).toFixed(3));
86
- return `rgba(${r},${g},${b},${alpha})`;
87
- }
88
24
 
89
25
  // src/ImageData/extractImageDataBuffer.ts
90
26
  function extractImageDataBuffer(imageData, _x, _y, _w, _h) {
@@ -1845,9 +1781,6 @@ function makeReusableCanvasMeta(factory) {
1845
1781
  canvas.width = width;
1846
1782
  canvas.height = height;
1847
1783
  ctx.imageSmoothingEnabled = false;
1848
- } else {
1849
- ctx.setTransform(1, 0, 0, 1, 0, 0);
1850
- ctx.clearRect(0, 0, width, height);
1851
1784
  }
1852
1785
  return result;
1853
1786
  }
@@ -1968,6 +1901,96 @@ async function writeImageDataToClipboard(imageData) {
1968
1901
  return writeImgBlobToClipboard(blob);
1969
1902
  }
1970
1903
 
1904
+ // src/Color/lerpColor32.ts
1905
+ function lerpColor32(a, b, t) {
1906
+ const r = (a & 255) + t * ((b & 255) - (a & 255));
1907
+ const g = (a >>> 8 & 255) + t * ((b >>> 8 & 255) - (a >>> 8 & 255));
1908
+ const b_ = (a >>> 16 & 255) + t * ((b >>> 16 & 255) - (a >>> 16 & 255));
1909
+ const a_ = (a >>> 24 & 255) + t * ((b >>> 24 & 255) - (a >>> 24 & 255));
1910
+ return (a_ << 24 | b_ << 16 | g << 8 | r) >>> 0;
1911
+ }
1912
+ function lerpColor32Fast(src, dst, w) {
1913
+ const invA = 255 - w;
1914
+ const rb = (src & 16711935) * w + (dst & 16711935) * invA >>> 8 & 16711935;
1915
+ const ga = (src >>> 8 & 16711935) * w + (dst >>> 8 & 16711935) * invA >>> 8 & 16711935;
1916
+ return (rb | ga << 8) >>> 0;
1917
+ }
1918
+
1919
+ // src/Color/convert-color.ts
1920
+ function color32ToHex(color) {
1921
+ const r = (color & 255).toString(16).padStart(2, "0");
1922
+ const g = (color >>> 8 & 255).toString(16).padStart(2, "0");
1923
+ const b = (color >>> 16 & 255).toString(16).padStart(2, "0");
1924
+ const a = (color >>> 24 & 255).toString(16).padStart(2, "0");
1925
+ return `#${r}${g}${b}${a}`;
1926
+ }
1927
+ function color32ToCssRGBAString(color) {
1928
+ const r = color & 255;
1929
+ const g = color >>> 8 & 255;
1930
+ const b = color >>> 16 & 255;
1931
+ const a = color >>> 24 & 255;
1932
+ const alpha = Number((a / 255).toFixed(3));
1933
+ return `rgba(${r},${g},${b},${alpha})`;
1934
+ }
1935
+ function color32ToCssRGBA(color) {
1936
+ const r = color & 255;
1937
+ const g = color >>> 8 & 255;
1938
+ const b = color >>> 16 & 255;
1939
+ const a = color >>> 24 & 255;
1940
+ return {
1941
+ r,
1942
+ g,
1943
+ b,
1944
+ a: a / 255
1945
+ };
1946
+ }
1947
+ function cssRGBAToColor32({
1948
+ r,
1949
+ g,
1950
+ b,
1951
+ a
1952
+ }) {
1953
+ return (a * 255 << 24 | b << 16 | g << 8 | r) >>> 0;
1954
+ }
1955
+
1956
+ // src/Color/pack-color.ts
1957
+ function packColor(r, g, b, a) {
1958
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
1959
+ }
1960
+ function packRGBA({
1961
+ r,
1962
+ g,
1963
+ b,
1964
+ a
1965
+ }) {
1966
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
1967
+ }
1968
+ var unpackRed = (packed) => packed >>> 0 & 255;
1969
+ var unpackGreen = (packed) => packed >>> 8 & 255;
1970
+ var unpackBlue = (packed) => packed >>> 16 & 255;
1971
+ var unpackAlpha = (packed) => packed >>> 24 & 255;
1972
+ function unpackColor(packed) {
1973
+ return {
1974
+ r: packed >>> 0 & 255,
1975
+ g: packed >>> 8 & 255,
1976
+ b: packed >>> 16 & 255,
1977
+ a: packed >>> 24 & 255
1978
+ };
1979
+ }
1980
+ var SCRATCH_RGBA = {
1981
+ r: 0,
1982
+ g: 0,
1983
+ b: 0,
1984
+ a: 0
1985
+ };
1986
+ function unpackColorTo(packed, scratch = SCRATCH_RGBA) {
1987
+ scratch.r = packed >>> 0 & 255;
1988
+ scratch.g = packed >>> 8 & 255;
1989
+ scratch.b = packed >>> 16 & 255;
1990
+ scratch.a = packed >>> 24 & 255;
1991
+ return scratch;
1992
+ }
1993
+
1971
1994
  // src/Control/BatchedQueue.ts
1972
1995
  function makeBatchedQueue(processor, queue) {
1973
1996
  let activeSet = /* @__PURE__ */ new Set();
@@ -2147,15 +2170,14 @@ var PixelAccumulator = class {
2147
2170
  * @param y pixel y coordinate
2148
2171
  */
2149
2172
  storePixelBeforeState(x, y) {
2150
- const shift = this.config.tileShift;
2151
2173
  const columns = this.config.targetColumns;
2152
- const targetWidth = this.config.target.w;
2153
- const targetHeight = this.config.target.h;
2174
+ const targetWidth = this.config.targetWidth;
2175
+ const targetHeight = this.config.targetHeight;
2154
2176
  if (x < 0 || x >= targetWidth || y < 0 || y >= targetHeight) {
2155
2177
  return null;
2156
2178
  }
2157
- const tx = x >> shift;
2158
- const ty = y >> shift;
2179
+ const tx = x * this.config.invTileSize | 0;
2180
+ const ty = y * this.config.invTileSize | 0;
2159
2181
  const id = ty * columns + tx;
2160
2182
  let tile = this.lookup[id];
2161
2183
  let added = false;
@@ -2182,10 +2204,10 @@ var PixelAccumulator = class {
2182
2204
  * @param h pixel height
2183
2205
  */
2184
2206
  storeRegionBeforeState(x, y, w, h) {
2185
- const shift = this.config.tileShift;
2186
2207
  const columns = this.config.targetColumns;
2187
- const targetWidth = this.config.target.w;
2188
- const targetHeight = this.config.target.h;
2208
+ const targetWidth = this.config.targetWidth;
2209
+ const targetHeight = this.config.targetHeight;
2210
+ const invTileSize = this.config.invTileSize;
2189
2211
  const clipX1 = Math.max(0, x);
2190
2212
  const clipY1 = Math.max(0, y);
2191
2213
  const clipX2 = Math.min(targetWidth - 1, x + w - 1);
@@ -2193,10 +2215,10 @@ var PixelAccumulator = class {
2193
2215
  if (clipX2 < clipX1 || clipY2 < clipY1) {
2194
2216
  return null;
2195
2217
  }
2196
- const startX = clipX1 >> shift;
2197
- const startY = clipY1 >> shift;
2198
- const endX = clipX2 >> shift;
2199
- const endY = clipY2 >> shift;
2218
+ const startX = clipX1 * invTileSize | 0;
2219
+ const startY = clipY1 * invTileSize | 0;
2220
+ const endX = clipX2 * invTileSize | 0;
2221
+ const endY = clipY2 * invTileSize | 0;
2200
2222
  const startIndex = this.beforeTiles.length;
2201
2223
  for (let ty = startY; ty <= endY; ty++) {
2202
2224
  for (let tx = startX; tx <= endX; tx++) {
@@ -2313,31 +2335,6 @@ var PixelAccumulator = class {
2313
2335
  }
2314
2336
  };
2315
2337
 
2316
- // src/History/PixelEngineConfig.ts
2317
- var PixelEngineConfig = class {
2318
- tileSize;
2319
- // pixelX = tileX << tileShift
2320
- // pixelY = tileY << tileShift
2321
- tileShift;
2322
- tileMask;
2323
- tileArea;
2324
- target;
2325
- targetColumns = 0;
2326
- targetRows = 0;
2327
- constructor(tileSize, target) {
2328
- if ((tileSize & tileSize - 1) !== 0) {
2329
- throw new Error("tileSize must be a power of 2");
2330
- }
2331
- this.tileSize = tileSize;
2332
- this.tileShift = 31 - Math.clz32(tileSize);
2333
- this.tileMask = tileSize - 1;
2334
- this.tileArea = tileSize * tileSize;
2335
- this.target = target;
2336
- this.targetColumns = target.w + this.tileMask >> this.tileShift;
2337
- this.targetRows = target.h + this.tileMask >> this.tileShift;
2338
- }
2339
- };
2340
-
2341
2338
  // src/PixelData/applyAlphaMaskToPixelData.ts
2342
2339
  function applyAlphaMaskToPixelData(target, mask, opts) {
2343
2340
  const targetX = opts?.x ?? 0;
@@ -2531,6 +2528,8 @@ function makePixelTile(id, tx, ty, tileSize, tileArea) {
2531
2528
  id,
2532
2529
  tx,
2533
2530
  ty,
2531
+ x: tx * tileSize,
2532
+ y: ty * tileSize,
2534
2533
  w: tileSize,
2535
2534
  h: tileSize,
2536
2535
  data: data32,
@@ -2540,25 +2539,28 @@ function makePixelTile(id, tx, ty, tileSize, tileArea) {
2540
2539
 
2541
2540
  // src/Tile/TilePool.ts
2542
2541
  var TilePool = class {
2543
- constructor(config, tileFactory) {
2542
+ constructor(tileSize, tileFactory) {
2543
+ this.tileSize = tileSize;
2544
2544
  this.tileFactory = tileFactory;
2545
2545
  this.pool = [];
2546
- this.tileSize = config.tileSize;
2547
- this.tileArea = config.tileArea;
2546
+ this.tileSize = tileSize;
2547
+ this.tileArea = tileSize * tileSize;
2548
2548
  }
2549
2549
  pool;
2550
- tileSize;
2551
2550
  tileArea;
2552
2551
  getTile(id, tx, ty) {
2553
2552
  let tile = this.pool.pop();
2553
+ const tileSize = this.tileSize;
2554
2554
  if (tile) {
2555
2555
  tile.id = id;
2556
2556
  tile.tx = tx;
2557
2557
  tile.ty = ty;
2558
+ tile.x = tx * tileSize;
2559
+ tile.y = ty * tileSize;
2558
2560
  tile.data.fill(0);
2559
2561
  return tile;
2560
2562
  }
2561
- return this.tileFactory(id, tx, ty, this.tileSize, this.tileArea);
2563
+ return this.tileFactory(id, tx, ty, tileSize, this.tileArea);
2562
2564
  }
2563
2565
  releaseTile(tile) {
2564
2566
  this.pool.push(tile);
@@ -2575,6 +2577,25 @@ var TilePool = class {
2575
2577
  }
2576
2578
  };
2577
2579
 
2580
+ // src/Tile/TileTargetConfig.ts
2581
+ function makeTileTargetConfig(tileSize, target) {
2582
+ return {
2583
+ target,
2584
+ ...makeTileTargetMeta(tileSize, target)
2585
+ };
2586
+ }
2587
+ function makeTileTargetMeta(tileSize, target) {
2588
+ return {
2589
+ targetWidth: target.w,
2590
+ targetHeight: target.h,
2591
+ tileSize,
2592
+ invTileSize: 1 / tileSize,
2593
+ tileArea: tileSize * tileSize,
2594
+ targetColumns: Math.ceil(target.w / tileSize),
2595
+ targetRows: Math.ceil(target.h / tileSize)
2596
+ };
2597
+ }
2598
+
2578
2599
  // src/History/PixelWriter.ts
2579
2600
  var PixelWriter = class {
2580
2601
  historyManager;
@@ -2587,10 +2608,10 @@ var PixelWriter = class {
2587
2608
  constructor(target, mutatorFactory, options) {
2588
2609
  const tileSize = options?.tileSize ?? 256;
2589
2610
  const maxHistorySteps = options?.maxHistorySteps ?? 50;
2590
- this.config = new PixelEngineConfig(tileSize, target);
2611
+ this.config = makeTileTargetConfig(tileSize, target);
2591
2612
  this.historyManager = options?.historyManager ?? new HistoryManager(maxHistorySteps);
2592
2613
  this.historyActionFactory = options?.historyActionFactory ?? makeHistoryAction;
2593
- this.pixelTilePool = options?.pixelTilePool ?? new TilePool(this.config, makePixelTile);
2614
+ this.pixelTilePool = options?.pixelTilePool ?? new TilePool(this.config.tileSize, makePixelTile);
2594
2615
  this.accumulator = options?.accumulator ?? new PixelAccumulator(this.config, this.pixelTilePool);
2595
2616
  this.mutator = mutatorFactory(this);
2596
2617
  }
@@ -3369,18 +3390,22 @@ var mutatorBlendColorPaintBinaryMask = ((writer, deps = defaults8) => {
3369
3390
  // src/History/PixelMutator/mutatorBlendColorPaintMask.ts
3370
3391
  var defaults9 = {
3371
3392
  blendColorPixelDataAlphaMask,
3372
- blendColorPixelDataBinaryMask
3393
+ blendColorPixelDataBinaryMask,
3394
+ blendColorPixelData
3373
3395
  };
3374
3396
  var mutatorBlendColorPaintMask = ((writer, deps = defaults9) => {
3375
3397
  const {
3376
3398
  blendColorPixelDataBinaryMask: blendColorPixelDataBinaryMask2 = defaults9.blendColorPixelDataBinaryMask,
3377
- blendColorPixelDataAlphaMask: blendColorPixelDataAlphaMask2 = defaults9.blendColorPixelDataAlphaMask
3399
+ blendColorPixelDataAlphaMask: blendColorPixelDataAlphaMask2 = defaults9.blendColorPixelDataAlphaMask,
3400
+ blendColorPixelData: blendColorPixelData2 = defaults9.blendColorPixelData
3378
3401
  } = deps;
3379
3402
  const OPTS = {
3380
3403
  x: 0,
3381
3404
  y: 0,
3382
3405
  blendFn: sourceOverPerfect,
3383
- alpha: 255
3406
+ alpha: 255,
3407
+ w: void 0,
3408
+ h: void 0
3384
3409
  };
3385
3410
  return {
3386
3411
  blendColorPaintMask(color, mask, x, y, alpha = 255, blendFn = sourceOverPerfect) {
@@ -3392,11 +3417,17 @@ var mutatorBlendColorPaintMask = ((writer, deps = defaults9) => {
3392
3417
  OPTS.y = ty;
3393
3418
  OPTS.alpha = alpha;
3394
3419
  OPTS.blendFn = blendFn;
3395
- if (mask.type === 1 /* BINARY */) {
3396
- return didChange(blendColorPixelDataBinaryMask2(writer.config.target, color, mask, OPTS));
3397
- } else {
3420
+ OPTS.w = void 0;
3421
+ OPTS.h = void 0;
3422
+ if (mask.data) {
3423
+ if (mask.type === 1 /* BINARY */) {
3424
+ return didChange(blendColorPixelDataBinaryMask2(writer.config.target, color, mask, OPTS));
3425
+ }
3398
3426
  return didChange(blendColorPixelDataAlphaMask2(writer.config.target, color, mask, OPTS));
3399
3427
  }
3428
+ OPTS.w = mask.w;
3429
+ OPTS.h = mask.h;
3430
+ return didChange(blendColorPixelData2(writer.config.target, color, OPTS));
3400
3431
  }
3401
3432
  };
3402
3433
  });
@@ -4043,8 +4074,10 @@ function makeReusableImageData() {
4043
4074
  // src/ImageData/serialization.ts
4044
4075
  function base64EncodeArrayBuffer(buffer) {
4045
4076
  const uint8 = new Uint8Array(buffer);
4046
- const decoder = new TextDecoder("latin1");
4047
- const binary = decoder.decode(uint8);
4077
+ let binary = "";
4078
+ for (let i = 0; i < uint8.length; i++) {
4079
+ binary += String.fromCharCode(uint8[i]);
4080
+ }
4048
4081
  return btoa(binary);
4049
4082
  }
4050
4083
  function base64DecodeArrayBuffer(encoded) {
@@ -5085,26 +5118,55 @@ function trimRectBounds(x, y, w, h, targetWidth, targetHeight, out) {
5085
5118
  return res;
5086
5119
  }
5087
5120
 
5121
+ // src/Tile/MaskTile.ts
5122
+ var makeAlphaMaskTile = (id, tx, ty, tileSize, tileArea) => {
5123
+ return {
5124
+ tileType: 1 /* MASK */,
5125
+ type: 0 /* ALPHA */,
5126
+ data: new Uint8Array(tileArea),
5127
+ w: tileSize,
5128
+ h: tileSize,
5129
+ x: tx * tileSize,
5130
+ y: ty * tileSize,
5131
+ id,
5132
+ tx,
5133
+ ty
5134
+ };
5135
+ };
5136
+ var makeBinaryMaskTile = (id, tx, ty, tileSize, tileArea) => {
5137
+ return {
5138
+ tileType: 1 /* MASK */,
5139
+ type: 1 /* BINARY */,
5140
+ data: new Uint8Array(tileArea),
5141
+ w: tileSize,
5142
+ h: tileSize,
5143
+ x: tx * tileSize,
5144
+ y: ty * tileSize,
5145
+ id,
5146
+ tx,
5147
+ ty
5148
+ };
5149
+ };
5150
+
5088
5151
  // src/Paint/eachTileInBounds.ts
5089
5152
  function eachTileInBounds(config, lookup, tilePool, bounds, callback) {
5090
5153
  const {
5091
- tileShift,
5092
- targetColumns,
5093
5154
  targetRows,
5155
+ targetColumns,
5094
5156
  tileSize
5095
5157
  } = config;
5096
- const x1 = Math.max(0, bounds.x >> tileShift);
5097
- const y1 = Math.max(0, bounds.y >> tileShift);
5098
- const x2 = Math.min(targetColumns - 1, bounds.x + bounds.w - 1 >> tileShift);
5099
- const y2 = Math.min(targetRows - 1, bounds.y + bounds.h - 1 >> tileShift);
5158
+ const x1 = Math.max(0, Math.floor(bounds.x / tileSize));
5159
+ const y1 = Math.max(0, Math.floor(bounds.y / tileSize));
5160
+ const x2 = Math.min(targetColumns - 1, Math.floor((bounds.x + bounds.w - 1) / tileSize));
5161
+ const y2 = Math.min(targetRows - 1, Math.floor((bounds.y + bounds.h - 1) / tileSize));
5100
5162
  if (x1 > x2 || y1 > y2) return;
5101
5163
  for (let ty = y1; ty <= y2; ty++) {
5102
5164
  const rowOffset = ty * targetColumns;
5103
- const tileTop = ty << tileShift;
5165
+ const tileTop = ty * tileSize;
5104
5166
  for (let tx = x1; tx <= x2; tx++) {
5105
5167
  const id = rowOffset + tx;
5106
5168
  const tile = lookup[id] ?? (lookup[id] = tilePool.getTile(id, tx, ty));
5107
- const tileLeft = tx << tileShift;
5169
+ const tileLeft = tx * tileSize;
5108
5170
  const startX = bounds.x > tileLeft ? bounds.x : tileLeft;
5109
5171
  const startY = bounds.y > tileTop ? bounds.y : tileTop;
5110
5172
  const maskEndX = bounds.x + bounds.w;
@@ -5120,7 +5182,7 @@ function eachTileInBounds(config, lookup, tilePool, bounds, callback) {
5120
5182
 
5121
5183
  // src/Paint/AlphaMaskPaintBuffer.ts
5122
5184
  var AlphaMaskPaintBuffer = class {
5123
- constructor(config, tilePool) {
5185
+ constructor(config, tilePool = new TilePool(config.tileSize, makeAlphaMaskTile)) {
5124
5186
  this.config = config;
5125
5187
  this.tilePool = tilePool;
5126
5188
  this.lookup = [];
@@ -5140,9 +5202,9 @@ var AlphaMaskPaintBuffer = class {
5140
5202
  const lookup = this.lookup;
5141
5203
  const tilePool = this.tilePool;
5142
5204
  const config = this.config;
5143
- const tileShift = config.tileShift;
5144
- const tileMask = config.tileMask;
5145
- const target = config.target;
5205
+ const targetW = config.targetWidth;
5206
+ const targetH = config.targetHeight;
5207
+ const tileSize = config.tileSize;
5146
5208
  const {
5147
5209
  w: bW,
5148
5210
  h: bH,
@@ -5156,7 +5218,7 @@ var AlphaMaskPaintBuffer = class {
5156
5218
  this.forEachLinePointFn(x0, y0, x1, y1, (px, py) => {
5157
5219
  const topLeftX = Math.floor(px + centerOffsetX);
5158
5220
  const topLeftY = Math.floor(py + centerOffsetY);
5159
- trimRectBoundsFn(topLeftX, topLeftY, bW, bH, target.w, target.h, scratch);
5221
+ trimRectBoundsFn(topLeftX, topLeftY, bW, bH, targetW, targetH, scratch);
5160
5222
  if (scratch.w <= 0 || scratch.h <= 0) return;
5161
5223
  eachTileInBoundsFn(config, lookup, tilePool, scratch, (tile, bX, bY, bW_t, bH_t) => {
5162
5224
  const data = tile.data;
@@ -5164,8 +5226,8 @@ var AlphaMaskPaintBuffer = class {
5164
5226
  for (let i = 0; i < bH_t; i++) {
5165
5227
  const canvasY = bY + i;
5166
5228
  const bOff = (canvasY - topLeftY) * bW;
5167
- const tOff = (canvasY & tileMask) << tileShift;
5168
- const dS = tOff + (bX & tileMask);
5229
+ const tOff = (canvasY - tile.y) * tileSize;
5230
+ const dS = tOff + (bX - tile.x);
5169
5231
  for (let j = 0; j < bW_t; j++) {
5170
5232
  const canvasX = bX + j;
5171
5233
  const brushA = bD[bOff + (canvasX - topLeftX)];
@@ -5188,9 +5250,9 @@ var AlphaMaskPaintBuffer = class {
5188
5250
  const lookup = this.lookup;
5189
5251
  const tilePool = this.tilePool;
5190
5252
  const config = this.config;
5191
- const tileShift = config.tileShift;
5192
- const tileMask = config.tileMask;
5193
- const target = config.target;
5253
+ const targetW = config.targetWidth;
5254
+ const targetH = config.targetHeight;
5255
+ const tileSize = config.tileSize;
5194
5256
  const {
5195
5257
  w: bW,
5196
5258
  h: bH,
@@ -5204,7 +5266,7 @@ var AlphaMaskPaintBuffer = class {
5204
5266
  this.forEachLinePointFn(x0, y0, x1, y1, (px, py) => {
5205
5267
  const topLeftX = Math.floor(px + centerOffsetX);
5206
5268
  const topLeftY = Math.floor(py + centerOffsetY);
5207
- trimRectBoundsFn(topLeftX, topLeftY, bW, bH, target.w, target.h, scratch);
5269
+ trimRectBoundsFn(topLeftX, topLeftY, bW, bH, targetW, targetH, scratch);
5208
5270
  if (scratch.w <= 0 || scratch.h <= 0) return;
5209
5271
  eachTileInBoundsFn(config, lookup, tilePool, scratch, (tile, bX, bY, bW_t, bH_t) => {
5210
5272
  const data = tile.data;
@@ -5212,8 +5274,8 @@ var AlphaMaskPaintBuffer = class {
5212
5274
  for (let i = 0; i < bH_t; i++) {
5213
5275
  const canvasY = bY + i;
5214
5276
  const bOff = (canvasY - topLeftY) * bW;
5215
- const tOff = (canvasY & tileMask) << tileShift;
5216
- const dS = tOff + (bX & tileMask);
5277
+ const tOff = (canvasY - tile.y) * tileSize;
5278
+ const dS = tOff + (bX - tile.x);
5217
5279
  for (let j = 0; j < bW_t; j++) {
5218
5280
  const canvasX = bX + j;
5219
5281
  if (bD[bOff + (canvasX - topLeftX)]) {
@@ -5235,9 +5297,9 @@ var AlphaMaskPaintBuffer = class {
5235
5297
  const lookup = this.lookup;
5236
5298
  const tilePool = this.tilePool;
5237
5299
  const config = this.config;
5238
- const tileShift = config.tileShift;
5239
- const tileMask = config.tileMask;
5240
- const target = config.target;
5300
+ const targetW = config.targetWidth;
5301
+ const targetH = config.targetHeight;
5302
+ const tileSize = config.tileSize;
5241
5303
  const brushWidth = brush.w;
5242
5304
  const brushHeight = brush.h;
5243
5305
  const centerOffsetX = brush.centerOffsetX;
@@ -5248,15 +5310,15 @@ var AlphaMaskPaintBuffer = class {
5248
5310
  this.forEachLinePointFn(x0, y0, x1, y1, (px, py) => {
5249
5311
  const topLeftX = Math.floor(px + centerOffsetX);
5250
5312
  const topLeftY = Math.floor(py + centerOffsetY);
5251
- trimRectBoundsFn(topLeftX, topLeftY, brushWidth, brushHeight, target.w, target.h, scratch);
5313
+ trimRectBoundsFn(topLeftX, topLeftY, brushWidth, brushHeight, targetW, targetH, scratch);
5252
5314
  if (scratch.w <= 0 || scratch.h <= 0) return;
5253
5315
  eachTileInBoundsFn(config, lookup, tilePool, scratch, (tile, bX, bY, bW_t, bH_t) => {
5254
5316
  const data = tile.data;
5255
5317
  let tileChanged = false;
5256
5318
  for (let i = 0; i < bH_t; i++) {
5257
5319
  const canvasY = bY + i;
5258
- const tOff = (canvasY & tileMask) << tileShift;
5259
- const dS = tOff + (bX & tileMask);
5320
+ const tOff = (canvasY - tile.y) * tileSize;
5321
+ const dS = tOff + (bX - tile.x);
5260
5322
  for (let j = 0; j < bW_t; j++) {
5261
5323
  const idx = dS + j;
5262
5324
  if (alpha > data[idx]) {
@@ -5279,7 +5341,7 @@ var AlphaMaskPaintBuffer = class {
5279
5341
 
5280
5342
  // src/Paint/BinaryMaskPaintBuffer.ts
5281
5343
  var BinaryMaskPaintBuffer = class {
5282
- constructor(config, tilePool) {
5344
+ constructor(config, tilePool = new TilePool(config.tileSize, makeBinaryMaskTile)) {
5283
5345
  this.config = config;
5284
5346
  this.tilePool = tilePool;
5285
5347
  this.lookup = [];
@@ -5299,9 +5361,9 @@ var BinaryMaskPaintBuffer = class {
5299
5361
  const lookup = this.lookup;
5300
5362
  const tilePool = this.tilePool;
5301
5363
  const config = this.config;
5302
- const tileShift = config.tileShift;
5303
- const tileMask = config.tileMask;
5304
- const target = config.target;
5364
+ const targetW = config.targetWidth;
5365
+ const targetH = config.targetHeight;
5366
+ const tileSize = config.tileSize;
5305
5367
  const {
5306
5368
  w: bW,
5307
5369
  h: bH,
@@ -5315,7 +5377,7 @@ var BinaryMaskPaintBuffer = class {
5315
5377
  this.forEachLinePointFn(x0, y0, x1, y1, (px, py) => {
5316
5378
  const topLeftX = Math.floor(px + centerOffsetX);
5317
5379
  const topLeftY = Math.floor(py + centerOffsetY);
5318
- trimRectBoundsFn(topLeftX, topLeftY, bW, bH, target.w, target.h, scratch);
5380
+ trimRectBoundsFn(topLeftX, topLeftY, bW, bH, targetW, targetH, scratch);
5319
5381
  if (scratch.w <= 0 || scratch.h <= 0) return;
5320
5382
  eachTileInBoundsFn(config, lookup, tilePool, scratch, (tile, bX, bY, bW_t, bH_t) => {
5321
5383
  const data = tile.data;
@@ -5323,8 +5385,8 @@ var BinaryMaskPaintBuffer = class {
5323
5385
  for (let i = 0; i < bH_t; i++) {
5324
5386
  const canvasY = bY + i;
5325
5387
  const bOff = (canvasY - topLeftY) * bW;
5326
- const tOff = (canvasY & tileMask) << tileShift;
5327
- const dS = tOff + (bX & tileMask);
5388
+ const tOff = (canvasY - tile.y) * tileSize;
5389
+ const dS = tOff + (bX - tile.x);
5328
5390
  for (let j = 0; j < bW_t; j++) {
5329
5391
  const canvasX = bX + j;
5330
5392
  if (bD[bOff + (canvasX - topLeftX)]) {
@@ -5346,9 +5408,9 @@ var BinaryMaskPaintBuffer = class {
5346
5408
  const lookup = this.lookup;
5347
5409
  const tilePool = this.tilePool;
5348
5410
  const config = this.config;
5349
- const tileShift = config.tileShift;
5350
- const tileMask = config.tileMask;
5351
- const target = config.target;
5411
+ const targetW = config.targetWidth;
5412
+ const targetH = config.targetHeight;
5413
+ const tileSize = config.tileSize;
5352
5414
  const brushWidth = brush.w;
5353
5415
  const brushHeight = brush.h;
5354
5416
  const centerOffsetX = brush.centerOffsetX;
@@ -5359,15 +5421,15 @@ var BinaryMaskPaintBuffer = class {
5359
5421
  this.forEachLinePointFn(x0, y0, x1, y1, (px, py) => {
5360
5422
  const topLeftX = Math.floor(px + centerOffsetX);
5361
5423
  const topLeftY = Math.floor(py + centerOffsetY);
5362
- trimRectBoundsFn(topLeftX, topLeftY, brushWidth, brushHeight, target.w, target.h, scratch);
5424
+ trimRectBoundsFn(topLeftX, topLeftY, brushWidth, brushHeight, targetW, targetH, scratch);
5363
5425
  if (scratch.w <= 0 || scratch.h <= 0) return;
5364
5426
  eachTileInBoundsFn(config, lookup, tilePool, scratch, (tile, bX, bY, bW_t, bH_t) => {
5365
5427
  const data = tile.data;
5366
5428
  let tileChanged = false;
5367
5429
  for (let i = 0; i < bH_t; i++) {
5368
5430
  const canvasY = bY + i;
5369
- const tOff = (canvasY & tileMask) << tileShift;
5370
- const dS = tOff + (bX & tileMask);
5431
+ const tOff = (canvasY - tile.y) * tileSize;
5432
+ const dS = tOff + (bX - tile.x);
5371
5433
  for (let j = 0; j < bW_t; j++) {
5372
5434
  const idx = dS + j;
5373
5435
  if (data[idx] === 0) {
@@ -5409,9 +5471,9 @@ var ColorPaintBuffer = class {
5409
5471
  const lookup = this.lookup;
5410
5472
  const tilePool = this.tilePool;
5411
5473
  const config = this.config;
5412
- const tileShift = config.tileShift;
5413
- const tileMask = config.tileMask;
5414
- const target = config.target;
5474
+ const tileSize = config.tileSize;
5475
+ const targetW = config.targetWidth;
5476
+ const targetH = config.targetHeight;
5415
5477
  const {
5416
5478
  w: bW,
5417
5479
  h: bH,
@@ -5424,7 +5486,7 @@ var ColorPaintBuffer = class {
5424
5486
  forEachLinePoint(x0, y0, x1, y1, (px, py) => {
5425
5487
  const topLeftX = Math.floor(px + centerOffsetX);
5426
5488
  const topLeftY = Math.floor(py + centerOffsetY);
5427
- trimRectBounds(topLeftX, topLeftY, bW, bH, target.w, target.h, scratch);
5489
+ trimRectBounds(topLeftX, topLeftY, bW, bH, targetW, targetH, scratch);
5428
5490
  if (scratch.w <= 0 || scratch.h <= 0) return;
5429
5491
  eachTileInBounds(config, lookup, tilePool, scratch, (tile, bX, bY, bW_t, bH_t) => {
5430
5492
  const d32 = tile.data;
@@ -5432,8 +5494,8 @@ var ColorPaintBuffer = class {
5432
5494
  for (let i = 0; i < bH_t; i++) {
5433
5495
  const canvasY = bY + i;
5434
5496
  const bOff = (canvasY - topLeftY) * bW;
5435
- const tOff = (canvasY & tileMask) << tileShift;
5436
- const dS = tOff + (bX & tileMask);
5497
+ const tOff = (canvasY - tile.y) * tileSize;
5498
+ const dS = tOff + (bX - tile.x);
5437
5499
  for (let j = 0; j < bW_t; j++) {
5438
5500
  const canvasX = bX + j;
5439
5501
  const brushA = bD[bOff + (canvasX - topLeftX)];
@@ -5463,9 +5525,9 @@ var ColorPaintBuffer = class {
5463
5525
  const lookup = this.lookup;
5464
5526
  const tilePool = this.tilePool;
5465
5527
  const config = this.config;
5466
- const tileShift = config.tileShift;
5467
- const tileMask = config.tileMask;
5468
- const target = config.target;
5528
+ const tileSize = config.tileSize;
5529
+ const targetW = config.targetWidth;
5530
+ const targetH = config.targetHeight;
5469
5531
  const {
5470
5532
  w: bW,
5471
5533
  h: bH,
@@ -5477,7 +5539,7 @@ var ColorPaintBuffer = class {
5477
5539
  forEachLinePoint(x0, y0, x1, y1, (px, py) => {
5478
5540
  const topLeftX = Math.floor(px + centerOffsetX);
5479
5541
  const topLeftY = Math.floor(py + centerOffsetY);
5480
- trimRectBounds(topLeftX, topLeftY, bW, bH, target.w, target.h, scratch);
5542
+ trimRectBounds(topLeftX, topLeftY, bW, bH, targetW, targetH, scratch);
5481
5543
  if (scratch.w <= 0 || scratch.h <= 0) return;
5482
5544
  eachTileInBounds(config, lookup, tilePool, scratch, (tile, bX, bY, bW_t, bH_t) => {
5483
5545
  const d32 = tile.data;
@@ -5485,8 +5547,8 @@ var ColorPaintBuffer = class {
5485
5547
  for (let i = 0; i < bH_t; i++) {
5486
5548
  const canvasY = bY + i;
5487
5549
  const bOff = (canvasY - topLeftY) * bW;
5488
- const tOff = (canvasY & tileMask) << tileShift;
5489
- const dS = tOff + (bX & tileMask);
5550
+ const tOff = (canvasY - tile.y) * tileSize;
5551
+ const dS = tOff + (bX - tile.x);
5490
5552
  for (let j = 0; j < bW_t; j++) {
5491
5553
  const canvasX = bX + j;
5492
5554
  if (bD[bOff + (canvasX - topLeftX)]) {
@@ -5510,9 +5572,9 @@ var ColorPaintBuffer = class {
5510
5572
  const lookup = this.lookup;
5511
5573
  const tilePool = this.tilePool;
5512
5574
  const config = this.config;
5513
- const tileShift = config.tileShift;
5514
- const tileMask = config.tileMask;
5515
- const target = config.target;
5575
+ const targetW = config.targetWidth;
5576
+ const targetH = config.targetHeight;
5577
+ const tileSize = config.tileSize;
5516
5578
  const brushWidth = brush.w;
5517
5579
  const brushHeight = brush.h;
5518
5580
  const centerOffsetX = brush.centerOffsetX;
@@ -5521,15 +5583,15 @@ var ColorPaintBuffer = class {
5521
5583
  forEachLinePoint(x0, y0, x1, y1, (px, py) => {
5522
5584
  const topLeftX = Math.floor(px + centerOffsetX);
5523
5585
  const topLeftY = Math.floor(py + centerOffsetY);
5524
- trimRectBounds(topLeftX, topLeftY, brushWidth, brushHeight, target.w, target.h, scratch);
5586
+ trimRectBounds(topLeftX, topLeftY, brushWidth, brushHeight, targetW, targetH, scratch);
5525
5587
  if (scratch.w <= 0 || scratch.h <= 0) return;
5526
5588
  eachTileInBounds(config, lookup, tilePool, scratch, (tile, bX, bY, bW_t, bH_t) => {
5527
5589
  const d32 = tile.data;
5528
5590
  let tileChanged = false;
5529
5591
  for (let i = 0; i < bH_t; i++) {
5530
5592
  const canvasY = bY + i;
5531
- const tOff = (canvasY & tileMask) << tileShift;
5532
- const dS = tOff + (bX & tileMask);
5593
+ const tOff = (canvasY - tile.y) * tileSize;
5594
+ const dS = tOff + (bX - tile.x);
5533
5595
  for (let j = 0; j < bW_t; j++) {
5534
5596
  const idx = dS + j;
5535
5597
  if (d32[idx] !== color) {
@@ -5561,7 +5623,6 @@ var SCRATCH_OPTS = {
5561
5623
  };
5562
5624
  function commitMaskPaintBuffer(accumulator, paintBuffer, color, alpha = 255, blendFn = sourceOverPerfect, blendColorPixelDataMaskFn) {
5563
5625
  const config = accumulator.config;
5564
- const tileShift = config.tileShift;
5565
5626
  const lookup = paintBuffer.lookup;
5566
5627
  SCRATCH_OPTS.alpha = alpha;
5567
5628
  SCRATCH_OPTS.blendFn = blendFn;
@@ -5569,10 +5630,8 @@ function commitMaskPaintBuffer(accumulator, paintBuffer, color, alpha = 255, ble
5569
5630
  const tile = lookup[i];
5570
5631
  if (tile) {
5571
5632
  const didChange = accumulator.storeTileBeforeState(tile.id, tile.tx, tile.ty);
5572
- const dx = tile.tx << tileShift;
5573
- const dy = tile.ty << tileShift;
5574
- SCRATCH_OPTS.x = dx;
5575
- SCRATCH_OPTS.y = dy;
5633
+ SCRATCH_OPTS.x = tile.x;
5634
+ SCRATCH_OPTS.y = tile.y;
5576
5635
  SCRATCH_OPTS.w = tile.w;
5577
5636
  SCRATCH_OPTS.h = tile.h;
5578
5637
  didChange(blendColorPixelDataMaskFn(config.target, color, tile, SCRATCH_OPTS));
@@ -5588,49 +5647,51 @@ function makeAlphaMaskPaintBufferCommitter(accumulator, paintBuffer) {
5588
5647
  };
5589
5648
  }
5590
5649
 
5591
- // src/Internal/_constants.ts
5592
- var DEFAULT_CANVAS_FACTORY = (w, h) => new OffscreenCanvas(w, h);
5593
-
5594
- // src/Tile/MaskTile.ts
5595
- var makeAlphaMaskTile = (id, tx, ty, tileSize, tileArea) => {
5596
- return {
5597
- tileType: 1 /* MASK */,
5598
- type: 0 /* ALPHA */,
5599
- data: new Uint8Array(tileArea),
5600
- w: tileSize,
5601
- h: tileSize,
5602
- id,
5603
- tx,
5604
- ty
5650
+ // src/PixelData/ReusablePixelData.ts
5651
+ function makeReusablePixelData() {
5652
+ const pixelData = {
5653
+ w: 0,
5654
+ h: 0,
5655
+ data: null,
5656
+ imageData: null
5605
5657
  };
5606
- };
5607
- var makeBinaryMaskTile = (id, tx, ty, tileSize, tileArea) => {
5608
- return {
5609
- tileType: 1 /* MASK */,
5610
- type: 1 /* BINARY */,
5611
- data: new Uint8Array(tileArea),
5612
- w: tileSize,
5613
- h: tileSize,
5614
- id,
5615
- tx,
5616
- ty
5658
+ return function getReusablePixelData(width, height) {
5659
+ if (pixelData.w !== width || pixelData.h !== height) {
5660
+ setPixelData(pixelData, new ImageData(width, height));
5661
+ } else {
5662
+ pixelData.data.fill(0);
5663
+ }
5664
+ return pixelData;
5617
5665
  };
5618
- };
5666
+ }
5619
5667
 
5620
5668
  // src/Paint/Render/AlphaMaskPaintBufferCanvasRenderer.ts
5621
- function makeAlphaMaskPaintBufferCanvasRenderer(paintBuffer, canvasFactory = DEFAULT_CANVAS_FACTORY) {
5622
- const config = paintBuffer.config;
5623
- const tileSize = config.tileSize;
5624
- const tileShift = config.tileShift;
5625
- const tileArea = config.tileArea;
5626
- const lookup = paintBuffer.lookup;
5627
- const canvas = canvasFactory(tileSize, tileSize);
5628
- const ctx = canvas.getContext("2d");
5629
- if (!ctx) throw new Error(CANVAS_CTX_FAILED);
5630
- ctx.imageSmoothingEnabled = false;
5631
- const bridge = makePixelData(new ImageData(tileSize, tileSize));
5632
- const view32 = bridge.data;
5633
- return function drawPaintBuffer(targetCtx, color, alpha = 255, compOperation = "source-over") {
5669
+ function makeAlphaMaskPaintBufferCanvasRenderer(paintBuffer, reusableCanvasFactory) {
5670
+ const factory = reusableCanvasFactory ?? makeReusableOffscreenCanvas;
5671
+ const getBuffer = factory();
5672
+ const getBridge = makeReusablePixelData();
5673
+ let config;
5674
+ let tileSize;
5675
+ let tileArea;
5676
+ let lookup;
5677
+ let view32;
5678
+ let bridge;
5679
+ let canvas;
5680
+ let ctx;
5681
+ setBuffer(paintBuffer);
5682
+ function setBuffer(value) {
5683
+ paintBuffer = value;
5684
+ config = paintBuffer.config;
5685
+ tileSize = config.tileSize;
5686
+ tileArea = config.tileArea;
5687
+ lookup = paintBuffer.lookup;
5688
+ bridge = getBridge(tileSize, tileSize);
5689
+ view32 = bridge.data;
5690
+ const buff = getBuffer(tileSize, tileSize);
5691
+ canvas = buff.canvas;
5692
+ ctx = buff.ctx;
5693
+ }
5694
+ function draw(targetCtx, color, alpha = 255, compOperation = "source-over") {
5634
5695
  if (alpha === 0) return;
5635
5696
  const baseSrcAlpha = color >>> 24;
5636
5697
  const colorRGB = color & 16777215;
@@ -5653,29 +5714,31 @@ function makeAlphaMaskPaintBufferCanvasRenderer(paintBuffer, canvasFactory = DEF
5653
5714
  view32[p] = (colorRGB | finalA << 24) >>> 0;
5654
5715
  }
5655
5716
  }
5656
- const dx = tile.tx << tileShift;
5657
- const dy = tile.ty << tileShift;
5658
5717
  ctx.putImageData(bridge.imageData, 0, 0);
5659
- targetCtx.drawImage(canvas, dx, dy);
5718
+ targetCtx.drawImage(canvas, tile.x, tile.y);
5660
5719
  }
5661
5720
  }
5662
5721
  targetCtx.globalAlpha = 1;
5663
5722
  targetCtx.globalCompositeOperation = "source-over";
5723
+ }
5724
+ return {
5725
+ draw,
5726
+ setBuffer
5664
5727
  };
5665
5728
  }
5666
5729
 
5667
5730
  // src/Paint/Commit/AlphaMaskPaintBufferManager.ts
5668
- function makeAlphaMaskPaintBufferManager(writer, canvasFactory = DEFAULT_CANVAS_FACTORY) {
5669
- const pool = new TilePool(writer.config, makeAlphaMaskTile);
5731
+ function makeAlphaMaskPaintBufferManager(writer, reusableCanvasFactory) {
5732
+ const pool = new TilePool(writer.config.tileSize, makeAlphaMaskTile);
5670
5733
  const buffer = new AlphaMaskPaintBuffer(writer.config, pool);
5671
- const draw = makeAlphaMaskPaintBufferCanvasRenderer(buffer, canvasFactory);
5734
+ const renderer = makeAlphaMaskPaintBufferCanvasRenderer(buffer, reusableCanvasFactory);
5672
5735
  return {
5673
5736
  clear: buffer.clear.bind(buffer),
5674
5737
  paintRect: buffer.paintRect.bind(buffer),
5675
5738
  paintAlphaMask: buffer.paintAlphaMask.bind(buffer),
5676
5739
  paintBinaryMask: buffer.paintBinaryMask.bind(buffer),
5677
5740
  commit: makeAlphaMaskPaintBufferCommitter(writer.accumulator, buffer),
5678
- draw
5741
+ renderer
5679
5742
  };
5680
5743
  }
5681
5744
 
@@ -5687,19 +5750,32 @@ function makeBinaryMaskPaintBufferCommitter(accumulator, paintBuffer) {
5687
5750
  }
5688
5751
 
5689
5752
  // src/Paint/Render/BinaryMaskPaintBufferCanvasRenderer.ts
5690
- function makeBinaryMaskPaintBufferCanvasRenderer(paintBuffer, canvasFactory = DEFAULT_CANVAS_FACTORY) {
5691
- const config = paintBuffer.config;
5692
- const tileSize = config.tileSize;
5693
- const tileShift = config.tileShift;
5694
- const tileArea = config.tileArea;
5695
- const lookup = paintBuffer.lookup;
5696
- const canvas = canvasFactory(tileSize, tileSize);
5697
- const ctx = canvas.getContext("2d");
5698
- if (!ctx) throw new Error(CANVAS_CTX_FAILED);
5699
- ctx.imageSmoothingEnabled = false;
5700
- const bridge = makePixelData(new ImageData(tileSize, tileSize));
5701
- const view32 = bridge.data;
5702
- return function drawPaintBuffer(targetCtx, color, alpha = 255, compOperation = "source-over") {
5753
+ function makeBinaryMaskPaintBufferCanvasRenderer(paintBuffer, reusableCanvasFactory) {
5754
+ const factory = reusableCanvasFactory ?? makeReusableOffscreenCanvas;
5755
+ const getBuffer = factory();
5756
+ const getBridge = makeReusablePixelData();
5757
+ let config;
5758
+ let tileSize;
5759
+ let tileArea;
5760
+ let lookup;
5761
+ let view32;
5762
+ let bridge;
5763
+ let canvas;
5764
+ let ctx;
5765
+ setBuffer(paintBuffer);
5766
+ function setBuffer(value) {
5767
+ paintBuffer = value;
5768
+ config = paintBuffer.config;
5769
+ tileSize = config.tileSize;
5770
+ tileArea = config.tileArea;
5771
+ lookup = paintBuffer.lookup;
5772
+ bridge = getBridge(tileSize, tileSize);
5773
+ view32 = bridge.data;
5774
+ const buff = getBuffer(tileSize, tileSize);
5775
+ canvas = buff.canvas;
5776
+ ctx = buff.ctx;
5777
+ }
5778
+ function draw(targetCtx, color, alpha = 255, compOperation = "source-over") {
5703
5779
  if (alpha === 0) return;
5704
5780
  const baseSrcAlpha = color >>> 24;
5705
5781
  if (baseSrcAlpha === 0) return;
@@ -5715,28 +5791,30 @@ function makeBinaryMaskPaintBufferCanvasRenderer(paintBuffer, canvasFactory = DE
5715
5791
  view32[p] = color;
5716
5792
  }
5717
5793
  }
5718
- const dx = tile.tx << tileShift;
5719
- const dy = tile.ty << tileShift;
5720
5794
  ctx.putImageData(bridge.imageData, 0, 0);
5721
- targetCtx.drawImage(canvas, dx, dy);
5795
+ targetCtx.drawImage(canvas, tile.x, tile.y);
5722
5796
  }
5723
5797
  }
5724
5798
  targetCtx.globalAlpha = 1;
5725
5799
  targetCtx.globalCompositeOperation = "source-over";
5800
+ }
5801
+ return {
5802
+ draw,
5803
+ setBuffer
5726
5804
  };
5727
5805
  }
5728
5806
 
5729
5807
  // src/Paint/Commit/BinaryMaskPaintBufferManager.ts
5730
- function makeBinaryMaskPaintBufferManager(writer, canvasFactory = DEFAULT_CANVAS_FACTORY) {
5731
- const pool = new TilePool(writer.config, makeBinaryMaskTile);
5808
+ function makeBinaryMaskPaintBufferManager(writer, reusableCanvasFactory) {
5809
+ const pool = new TilePool(writer.config.tileSize, makeBinaryMaskTile);
5732
5810
  const buffer = new BinaryMaskPaintBuffer(writer.config, pool);
5733
- const draw = makeBinaryMaskPaintBufferCanvasRenderer(buffer, canvasFactory);
5811
+ const renderer = makeBinaryMaskPaintBufferCanvasRenderer(buffer, reusableCanvasFactory);
5734
5812
  return {
5735
5813
  clear: buffer.clear.bind(buffer),
5736
5814
  paintRect: buffer.paintRect.bind(buffer),
5737
5815
  paintBinaryMask: buffer.paintBinaryMask.bind(buffer),
5738
5816
  commit: makeBinaryMaskPaintBufferCommitter(writer.accumulator, buffer),
5739
- draw
5817
+ renderer
5740
5818
  };
5741
5819
  }
5742
5820
 
@@ -5751,7 +5829,6 @@ var SCRATCH_OPTS2 = {
5751
5829
  };
5752
5830
  function commitColorPaintBuffer(accumulator, paintBuffer, alpha = 255, blendFn = sourceOverPerfect, blendPixelDataFn = blendPixelData) {
5753
5831
  const config = accumulator.config;
5754
- const tileShift = config.tileShift;
5755
5832
  const lookup = paintBuffer.lookup;
5756
5833
  SCRATCH_OPTS2.alpha = alpha;
5757
5834
  SCRATCH_OPTS2.blendFn = blendFn;
@@ -5759,10 +5836,8 @@ function commitColorPaintBuffer(accumulator, paintBuffer, alpha = 255, blendFn =
5759
5836
  const tile = lookup[i];
5760
5837
  if (tile) {
5761
5838
  const didChange = accumulator.storeTileBeforeState(tile.id, tile.tx, tile.ty);
5762
- const dx = tile.tx << tileShift;
5763
- const dy = tile.ty << tileShift;
5764
- SCRATCH_OPTS2.x = dx;
5765
- SCRATCH_OPTS2.y = dy;
5839
+ SCRATCH_OPTS2.x = tile.x;
5840
+ SCRATCH_OPTS2.y = tile.y;
5766
5841
  SCRATCH_OPTS2.w = tile.w;
5767
5842
  SCRATCH_OPTS2.h = tile.h;
5768
5843
  didChange(blendPixelDataFn(config.target, tile, SCRATCH_OPTS2));
@@ -5779,44 +5854,47 @@ function makeColorPaintBufferCommitter(accumulator, paintBuffer) {
5779
5854
  }
5780
5855
 
5781
5856
  // src/Paint/Render/ColorPaintBufferCanvasRenderer.ts
5782
- function makeColorPaintBufferCanvasRenderer(paintBuffer, canvasFactory = DEFAULT_CANVAS_FACTORY) {
5783
- const config = paintBuffer.config;
5784
- const tileSize = config.tileSize;
5785
- const tileShift = config.tileShift;
5786
- const lookup = paintBuffer.lookup;
5787
- const canvas = canvasFactory(tileSize, tileSize);
5788
- const ctx = canvas.getContext("2d");
5789
- if (!ctx) throw new Error(CANVAS_CTX_FAILED);
5790
- ctx.imageSmoothingEnabled = false;
5791
- return function drawPaintBuffer(targetCtx, alpha = 255, compOperation = "source-over") {
5857
+ function makeColorPaintBufferCanvasRenderer(paintBuffer, reusableCanvasFactory) {
5858
+ const factory = reusableCanvasFactory ?? makeReusableOffscreenCanvas;
5859
+ const getBuffer = factory();
5860
+ function draw(targetCtx, alpha = 255, compOperation = "source-over") {
5861
+ const buff = getBuffer(paintBuffer.config.tileSize, paintBuffer.config.tileSize);
5862
+ const lookup = paintBuffer.lookup;
5863
+ const length = lookup.length;
5864
+ const ctx = buff.ctx;
5865
+ const canvas = buff.canvas;
5792
5866
  targetCtx.globalAlpha = alpha / 255;
5793
5867
  targetCtx.globalCompositeOperation = compOperation;
5794
- for (let i = 0; i < lookup.length; i++) {
5868
+ for (let i = 0; i < length; i++) {
5795
5869
  const tile = lookup[i];
5796
5870
  if (tile) {
5797
- const dx = tile.tx << tileShift;
5798
- const dy = tile.ty << tileShift;
5799
5871
  ctx.putImageData(tile.imageData, 0, 0);
5800
- targetCtx.drawImage(canvas, dx, dy);
5872
+ targetCtx.drawImage(canvas, tile.x, tile.y);
5801
5873
  }
5802
5874
  }
5803
5875
  targetCtx.globalAlpha = 1;
5804
5876
  targetCtx.globalCompositeOperation = "source-over";
5877
+ }
5878
+ return {
5879
+ draw,
5880
+ setBuffer(value) {
5881
+ paintBuffer = value;
5882
+ }
5805
5883
  };
5806
5884
  }
5807
5885
 
5808
5886
  // src/Paint/Commit/ColorPaintBufferManager.ts
5809
- function makeColorPaintBufferManager(writer, canvasFactory = DEFAULT_CANVAS_FACTORY) {
5810
- const pool = new TilePool(writer.config, makePixelTile);
5887
+ function makeColorPaintBufferManager(writer, reusableCanvasFactory) {
5888
+ const pool = new TilePool(writer.config.tileSize, makePixelTile);
5811
5889
  const buffer = new ColorPaintBuffer(writer.config, pool);
5812
- const draw = makeColorPaintBufferCanvasRenderer(buffer, canvasFactory);
5890
+ const renderer = makeColorPaintBufferCanvasRenderer(buffer, reusableCanvasFactory);
5813
5891
  return {
5814
5892
  clear: buffer.clear.bind(buffer),
5815
5893
  paintRect: buffer.paintRect.bind(buffer),
5816
5894
  paintAlphaMask: buffer.paintAlphaMask.bind(buffer),
5817
5895
  paintBinaryMask: buffer.paintBinaryMask.bind(buffer),
5818
5896
  commit: makeColorPaintBufferCommitter(writer.accumulator, buffer),
5819
- draw
5897
+ renderer
5820
5898
  };
5821
5899
  }
5822
5900
 
@@ -5952,24 +6030,6 @@ function makePaintRect(w, h) {
5952
6030
  };
5953
6031
  }
5954
6032
 
5955
- // src/PixelData/ReusablePixelData.ts
5956
- function makeReusablePixelData() {
5957
- const pixelData = {
5958
- w: 0,
5959
- h: 0,
5960
- data: null,
5961
- imageData: null
5962
- };
5963
- return function getReusablePixelData(width, height) {
5964
- if (pixelData.w !== width || pixelData.h !== height) {
5965
- setPixelData(pixelData, new ImageData(width, height));
5966
- } else {
5967
- pixelData.data.fill(0);
5968
- }
5969
- return pixelData;
5970
- };
5971
- }
5972
-
5973
6033
  // src/Paint/Render/PaintCursorRenderer.ts
5974
6034
  function makePaintCursorRenderer(reusableCanvasFactory) {
5975
6035
  const factory = reusableCanvasFactory ?? makeReusableOffscreenCanvas;
@@ -6122,20 +6182,29 @@ var SCRATCH_OPTS5 = {
6122
6182
  x: 0,
6123
6183
  y: 0,
6124
6184
  alpha: 255,
6125
- blendFn: sourceOverPerfect
6185
+ blendFn: sourceOverPerfect,
6186
+ w: void 0,
6187
+ h: void 0
6126
6188
  };
6127
- function blendColorPixelDataPaintMask(dst, color, mask, x, y, alpha = 255, blendFn = sourceOverPerfect) {
6189
+ function blendColorPixelDataPaintMask(target, color, mask, x, y, alpha = 255, blendFn = sourceOverPerfect) {
6128
6190
  const tx = x + mask.centerOffsetX;
6129
6191
  const ty = y + mask.centerOffsetY;
6130
6192
  SCRATCH_OPTS5.x = tx;
6131
6193
  SCRATCH_OPTS5.y = ty;
6132
6194
  SCRATCH_OPTS5.alpha = alpha;
6133
6195
  SCRATCH_OPTS5.blendFn = blendFn;
6134
- if (mask.type === 1 /* BINARY */) {
6135
- return blendColorPixelDataBinaryMask(dst, color, mask, SCRATCH_OPTS5);
6136
- } else {
6137
- return blendColorPixelDataAlphaMask(dst, color, mask, SCRATCH_OPTS5);
6196
+ SCRATCH_OPTS5.w = void 0;
6197
+ SCRATCH_OPTS5.h = void 0;
6198
+ if (mask.data) {
6199
+ if (mask.type === 1 /* BINARY */) {
6200
+ return blendColorPixelDataBinaryMask(target, color, mask, SCRATCH_OPTS5);
6201
+ } else {
6202
+ return blendColorPixelDataAlphaMask(target, color, mask, SCRATCH_OPTS5);
6203
+ }
6138
6204
  }
6205
+ SCRATCH_OPTS5.w = mask.w;
6206
+ SCRATCH_OPTS5.h = mask.h;
6207
+ return blendColorPixelData(target, color, SCRATCH_OPTS5);
6139
6208
  }
6140
6209
 
6141
6210
  // src/PixelData/blendPixelDataMask.ts
@@ -6155,13 +6224,12 @@ var SCRATCH_OPTS6 = {
6155
6224
  blendFn: void 0
6156
6225
  };
6157
6226
  function blendPixelDataPaintBuffer(target, paintBuffer, alpha = 255, blendFn, blendPixelDataFn = blendPixelData) {
6158
- const tileShift = paintBuffer.config.tileShift;
6159
6227
  const lookup = paintBuffer.lookup;
6160
6228
  for (let i = 0; i < lookup.length; i++) {
6161
6229
  const tile = lookup[i];
6162
6230
  if (tile) {
6163
- const x = tile.tx << tileShift;
6164
- const y = tile.ty << tileShift;
6231
+ const x = tile.x;
6232
+ const y = tile.y;
6165
6233
  SCRATCH_OPTS6.x = x;
6166
6234
  SCRATCH_OPTS6.y = y;
6167
6235
  SCRATCH_OPTS6.alpha = alpha;
@@ -6580,14 +6648,11 @@ function writePixelDataBuffer(target, data, _x, _y, _w, _h) {
6580
6648
 
6581
6649
  // src/PixelData/writePaintBufferToPixelData.ts
6582
6650
  function writePaintBufferToPixelData(target, paintBuffer, writePixelDataBufferFn = writePixelDataBuffer) {
6583
- const tileShift = paintBuffer.config.tileShift;
6584
6651
  const lookup = paintBuffer.lookup;
6585
6652
  for (let i = 0; i < lookup.length; i++) {
6586
6653
  const tile = lookup[i];
6587
6654
  if (tile) {
6588
- const dx = tile.tx << tileShift;
6589
- const dy = tile.ty << tileShift;
6590
- writePixelDataBufferFn(target, tile.data, dx, dy, tile.w, tile.h);
6655
+ writePixelDataBufferFn(target, tile.data, tile.x, tile.y, tile.w, tile.h);
6591
6656
  }
6592
6657
  }
6593
6658
  }
@@ -6639,7 +6704,6 @@ export {
6639
6704
  MaskType,
6640
6705
  PaintMaskOutline,
6641
6706
  PixelAccumulator,
6642
- PixelEngineConfig,
6643
6707
  PixelWriter,
6644
6708
  TilePool,
6645
6709
  TileType,
@@ -6666,6 +6730,7 @@ export {
6666
6730
  blendPixelDataPaintBuffer,
6667
6731
  clearPixelDataFast,
6668
6732
  color32ToCssRGBA,
6733
+ color32ToCssRGBAString,
6669
6734
  color32ToHex,
6670
6735
  colorBurnFast,
6671
6736
  colorBurnPerfect,
@@ -6679,6 +6744,7 @@ export {
6679
6744
  copyMask,
6680
6745
  copyPixelData,
6681
6746
  cropPixelData,
6747
+ cssRGBAToColor32,
6682
6748
  darkenFast,
6683
6749
  darkenPerfect,
6684
6750
  darkerFast,
@@ -6791,6 +6857,8 @@ export {
6791
6857
  makeReusableImageData,
6792
6858
  makeReusableOffscreenCanvas,
6793
6859
  makeReusablePixelData,
6860
+ makeTileTargetConfig,
6861
+ makeTileTargetMeta,
6794
6862
  merge2BinaryMaskRects,
6795
6863
  mergeAlphaMasks,
6796
6864
  mergeBinaryMaskRects,