pixel-data-js 0.28.0 → 0.29.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.
@@ -65,6 +65,8 @@ __export(src_exports, {
65
65
  colorDistance: () => colorDistance,
66
66
  colorDodgeFast: () => colorDodgeFast,
67
67
  colorDodgePerfect: () => colorDodgePerfect,
68
+ commitColorPaintBuffer: () => commitColorPaintBuffer,
69
+ commitMaskPaintBuffer: () => commitMaskPaintBuffer,
68
70
  copyImageData: () => copyImageData,
69
71
  copyImageDataLike: () => copyImageDataLike,
70
72
  copyMask: () => copyMask,
@@ -137,11 +139,15 @@ __export(src_exports, {
137
139
  linearLightPerfect: () => linearLightPerfect,
138
140
  makeAlphaMask: () => makeAlphaMask,
139
141
  makeAlphaMaskPaintBufferCanvasRenderer: () => makeAlphaMaskPaintBufferCanvasRenderer,
142
+ makeAlphaMaskPaintBufferCommitter: () => makeAlphaMaskPaintBufferCommitter,
143
+ makeAlphaMaskPaintBufferManager: () => makeAlphaMaskPaintBufferManager,
140
144
  makeAlphaMaskTile: () => makeAlphaMaskTile,
141
145
  makeBinaryMask: () => makeBinaryMask,
142
146
  makeBinaryMaskFromAlphaMask: () => makeBinaryMaskFromAlphaMask,
143
147
  makeBinaryMaskOutline: () => makeBinaryMaskOutline,
144
148
  makeBinaryMaskPaintBufferCanvasRenderer: () => makeBinaryMaskPaintBufferCanvasRenderer,
149
+ makeBinaryMaskPaintBufferCommitter: () => makeBinaryMaskPaintBufferCommitter,
150
+ makeBinaryMaskPaintBufferManager: () => makeBinaryMaskPaintBufferManager,
145
151
  makeBinaryMaskTile: () => makeBinaryMaskTile,
146
152
  makeBlendModeRegistry: () => makeBlendModeRegistry,
147
153
  makeCanvasFrameRenderer: () => makeCanvasFrameRenderer,
@@ -152,6 +158,8 @@ __export(src_exports, {
152
158
  makeClippedBlit: () => makeClippedBlit,
153
159
  makeClippedRect: () => makeClippedRect,
154
160
  makeColorPaintBufferCanvasRenderer: () => makeColorPaintBufferCanvasRenderer,
161
+ makeColorPaintBufferCommitter: () => makeColorPaintBufferCommitter,
162
+ makeColorPaintBufferManager: () => makeColorPaintBufferManager,
155
163
  makeFastBlendModeRegistry: () => makeFastBlendModeRegistry,
156
164
  makeFullPixelMutator: () => makeFullPixelMutator,
157
165
  makeHistoryAction: () => makeHistoryAction,
@@ -2176,13 +2184,13 @@ function makeReusableCanvasMeta(factory) {
2176
2184
 
2177
2185
  // src/Canvas/CanvasFrameRenderer.ts
2178
2186
  function makeCanvasFrameRenderer(reusableCanvasFactory = makeReusableOffscreenCanvas) {
2179
- const bufferCanvas = reusableCanvasFactory();
2187
+ const getBuffer = reusableCanvasFactory();
2180
2188
  return function renderCanvasFrame(pixelCanvas, scale, getImageData, drawPixelLayer, drawScreenLayer) {
2181
2189
  const canvas = pixelCanvas.canvas;
2182
2190
  const ctx = pixelCanvas.ctx;
2183
2191
  const w = canvas.width;
2184
2192
  const h = canvas.height;
2185
- const buffer = bufferCanvas(w, h);
2193
+ const buffer = getBuffer(w, h);
2186
2194
  const img = getImageData();
2187
2195
  if (img) {
2188
2196
  buffer.ctx.putImageData(img, 0, 0);
@@ -5269,7 +5277,6 @@ var AlphaMaskPaintBuffer = class {
5269
5277
  w: 0,
5270
5278
  h: 0
5271
5279
  };
5272
- blendColorPixelDataAlphaMaskFn = blendColorPixelDataAlphaMask;
5273
5280
  forEachLinePointFn = forEachLinePoint;
5274
5281
  trimRectBoundsFn = trimRectBounds;
5275
5282
  eachTileInBoundsFn = eachTileInBounds;
@@ -5408,88 +5415,11 @@ var AlphaMaskPaintBuffer = class {
5408
5415
  });
5409
5416
  return changed;
5410
5417
  }
5411
- opts = {
5412
- alpha: 255,
5413
- blendFn: sourceOverPerfect,
5414
- x: 0,
5415
- y: 0,
5416
- w: 0,
5417
- h: 0
5418
- };
5419
- commit(accumulator, color, alpha = 255, blendFn = sourceOverPerfect) {
5420
- const blendColorPixelDataAlphaMaskFn = this.blendColorPixelDataAlphaMaskFn;
5421
- const tileShift = this.config.tileShift;
5422
- const lookup = this.lookup;
5423
- const opts = this.opts;
5424
- opts.alpha = alpha;
5425
- opts.blendFn = blendFn;
5426
- for (let i = 0; i < lookup.length; i++) {
5427
- const tile = lookup[i];
5428
- if (tile) {
5429
- const didChange = accumulator.storeTileBeforeState(tile.id, tile.tx, tile.ty);
5430
- const dx = tile.tx << tileShift;
5431
- const dy = tile.ty << tileShift;
5432
- opts.x = dx;
5433
- opts.y = dy;
5434
- opts.w = tile.w;
5435
- opts.h = tile.h;
5436
- didChange(blendColorPixelDataAlphaMaskFn(this.config.target, color, tile, opts));
5437
- }
5438
- }
5439
- this.clear();
5440
- }
5441
5418
  clear() {
5442
5419
  this.tilePool.releaseTiles(this.lookup);
5443
5420
  }
5444
5421
  };
5445
5422
 
5446
- // src/Paint/AlphaMaskPaintBufferCanvasRenderer.ts
5447
- function makeAlphaMaskPaintBufferCanvasRenderer(paintBuffer, offscreenCanvasClass = OffscreenCanvas) {
5448
- const config = paintBuffer.config;
5449
- const tileSize = config.tileSize;
5450
- const tileShift = config.tileShift;
5451
- const tileArea = config.tileArea;
5452
- const lookup = paintBuffer.lookup;
5453
- const canvas = new offscreenCanvasClass(tileSize, tileSize);
5454
- const ctx = canvas.getContext("2d");
5455
- if (!ctx) throw new Error(CANVAS_CTX_FAILED);
5456
- ctx.imageSmoothingEnabled = false;
5457
- const bridge = makePixelData(new ImageData(tileSize, tileSize));
5458
- const view32 = bridge.data;
5459
- return function drawPaintBuffer(targetCtx, color, alpha = 255, compOperation = "source-over") {
5460
- if (alpha === 0) return;
5461
- const baseSrcAlpha = color >>> 24;
5462
- const colorRGB = color & 16777215;
5463
- if (baseSrcAlpha === 0) return;
5464
- targetCtx.globalAlpha = alpha / 255;
5465
- targetCtx.globalCompositeOperation = compOperation;
5466
- for (let i = 0; i < lookup.length; i++) {
5467
- const tile = lookup[i];
5468
- if (tile) {
5469
- const data8 = tile.data;
5470
- view32.fill(0);
5471
- for (let p = 0; p < tileArea; p++) {
5472
- const maskA = data8[p];
5473
- if (maskA === 0) continue;
5474
- if (maskA === 255) {
5475
- view32[p] = color;
5476
- } else {
5477
- const t = baseSrcAlpha * maskA + 128;
5478
- const finalA = t + (t >> 8) >> 8;
5479
- view32[p] = (colorRGB | finalA << 24) >>> 0;
5480
- }
5481
- }
5482
- const dx = tile.tx << tileShift;
5483
- const dy = tile.ty << tileShift;
5484
- ctx.putImageData(bridge.imageData, 0, 0);
5485
- targetCtx.drawImage(canvas, dx, dy);
5486
- }
5487
- }
5488
- targetCtx.globalAlpha = 1;
5489
- targetCtx.globalCompositeOperation = "source-over";
5490
- };
5491
- }
5492
-
5493
5423
  // src/Paint/BinaryMaskPaintBuffer.ts
5494
5424
  var BinaryMaskPaintBuffer = class {
5495
5425
  constructor(config, tilePool) {
@@ -5504,7 +5434,6 @@ var BinaryMaskPaintBuffer = class {
5504
5434
  w: 0,
5505
5435
  h: 0
5506
5436
  };
5507
- blendColorPixelDataBinaryMaskFn = blendColorPixelDataBinaryMask;
5508
5437
  forEachLinePointFn = forEachLinePoint;
5509
5438
  trimRectBoundsFn = trimRectBounds;
5510
5439
  eachTileInBoundsFn = eachTileInBounds;
@@ -5595,87 +5524,16 @@ var BinaryMaskPaintBuffer = class {
5595
5524
  });
5596
5525
  return changed;
5597
5526
  }
5598
- opts = {
5599
- alpha: 255,
5600
- blendFn: sourceOverPerfect,
5601
- x: 0,
5602
- y: 0,
5603
- w: 0,
5604
- h: 0
5605
- };
5606
- commit(accumulator, color, alpha = 255, blendFn = sourceOverPerfect) {
5607
- const blendColorPixelDataBinaryMaskFn = this.blendColorPixelDataBinaryMaskFn;
5608
- const tileShift = this.config.tileShift;
5609
- const lookup = this.lookup;
5610
- const opts = this.opts;
5611
- opts.alpha = alpha;
5612
- opts.blendFn = blendFn;
5613
- for (let i = 0; i < lookup.length; i++) {
5614
- const tile = lookup[i];
5615
- if (tile) {
5616
- const didChange = accumulator.storeTileBeforeState(tile.id, tile.tx, tile.ty);
5617
- const dx = tile.tx << tileShift;
5618
- const dy = tile.ty << tileShift;
5619
- opts.x = dx;
5620
- opts.y = dy;
5621
- opts.w = tile.w;
5622
- opts.h = tile.h;
5623
- didChange(blendColorPixelDataBinaryMaskFn(this.config.target, color, tile, opts));
5624
- }
5625
- }
5626
- this.clear();
5627
- }
5628
5527
  clear() {
5629
5528
  this.tilePool.releaseTiles(this.lookup);
5630
5529
  }
5631
5530
  };
5632
5531
 
5633
- // src/Paint/BinaryMaskPaintBufferCanvasRenderer.ts
5634
- function makeBinaryMaskPaintBufferCanvasRenderer(paintBuffer, offscreenCanvasClass = OffscreenCanvas) {
5635
- const config = paintBuffer.config;
5636
- const tileSize = config.tileSize;
5637
- const tileShift = config.tileShift;
5638
- const tileArea = config.tileArea;
5639
- const lookup = paintBuffer.lookup;
5640
- const canvas = new offscreenCanvasClass(tileSize, tileSize);
5641
- const ctx = canvas.getContext("2d");
5642
- if (!ctx) throw new Error(CANVAS_CTX_FAILED);
5643
- ctx.imageSmoothingEnabled = false;
5644
- const bridge = makePixelData(new ImageData(tileSize, tileSize));
5645
- const view32 = bridge.data;
5646
- return function drawPaintBuffer(targetCtx, color, alpha = 255, compOperation = "source-over") {
5647
- if (alpha === 0) return;
5648
- const baseSrcAlpha = color >>> 24;
5649
- if (baseSrcAlpha === 0) return;
5650
- targetCtx.globalAlpha = alpha / 255;
5651
- targetCtx.globalCompositeOperation = compOperation;
5652
- for (let i = 0; i < lookup.length; i++) {
5653
- const tile = lookup[i];
5654
- if (tile) {
5655
- const data8 = tile.data;
5656
- view32.fill(0);
5657
- for (let p = 0; p < tileArea; p++) {
5658
- if (data8[p] === 1) {
5659
- view32[p] = color;
5660
- }
5661
- }
5662
- const dx = tile.tx << tileShift;
5663
- const dy = tile.ty << tileShift;
5664
- ctx.putImageData(bridge.imageData, 0, 0);
5665
- targetCtx.drawImage(canvas, dx, dy);
5666
- }
5667
- }
5668
- targetCtx.globalAlpha = 1;
5669
- targetCtx.globalCompositeOperation = "source-over";
5670
- };
5671
- }
5672
-
5673
5532
  // src/Paint/ColorPaintBuffer.ts
5674
5533
  var ColorPaintBuffer = class {
5675
- constructor(config, tilePool, blendPixelDataFn = blendPixelData) {
5534
+ constructor(config, tilePool) {
5676
5535
  this.config = config;
5677
5536
  this.tilePool = tilePool;
5678
- this.blendPixelDataFn = blendPixelDataFn;
5679
5537
  this.lookup = [];
5680
5538
  }
5681
5539
  lookup;
@@ -5826,48 +5684,246 @@ var ColorPaintBuffer = class {
5826
5684
  });
5827
5685
  return changed;
5828
5686
  }
5829
- opts = {
5830
- alpha: 255,
5831
- blendFn: sourceOverPerfect,
5832
- x: 0,
5833
- y: 0,
5834
- w: 0,
5835
- h: 0
5687
+ clear() {
5688
+ this.tilePool.releaseTiles(this.lookup);
5689
+ }
5690
+ };
5691
+
5692
+ // src/Paint/Commit/commitMaskPaintBuffer.ts
5693
+ var SCRATCH_OPTS = {
5694
+ alpha: 255,
5695
+ blendFn: sourceOverPerfect,
5696
+ x: 0,
5697
+ y: 0,
5698
+ w: 0,
5699
+ h: 0
5700
+ };
5701
+ function commitMaskPaintBuffer(accumulator, paintBuffer, color, alpha = 255, blendFn = sourceOverPerfect, blendColorPixelDataMaskFn) {
5702
+ const config = accumulator.config;
5703
+ const tileShift = config.tileShift;
5704
+ const lookup = paintBuffer.lookup;
5705
+ SCRATCH_OPTS.alpha = alpha;
5706
+ SCRATCH_OPTS.blendFn = blendFn;
5707
+ for (let i = 0; i < lookup.length; i++) {
5708
+ const tile = lookup[i];
5709
+ if (tile) {
5710
+ const didChange = accumulator.storeTileBeforeState(tile.id, tile.tx, tile.ty);
5711
+ const dx = tile.tx << tileShift;
5712
+ const dy = tile.ty << tileShift;
5713
+ SCRATCH_OPTS.x = dx;
5714
+ SCRATCH_OPTS.y = dy;
5715
+ SCRATCH_OPTS.w = tile.w;
5716
+ SCRATCH_OPTS.h = tile.h;
5717
+ didChange(blendColorPixelDataMaskFn(config.target, color, tile, SCRATCH_OPTS));
5718
+ }
5719
+ }
5720
+ paintBuffer.clear();
5721
+ }
5722
+
5723
+ // src/Paint/Commit/AlphaMaskPaintBufferCommitter.ts
5724
+ function makeAlphaMaskPaintBufferCommitter(accumulator, paintBuffer) {
5725
+ return function commitAlphaMaskPaintBufferToAccumulator(color, alpha = 255, blendFn = sourceOverPerfect) {
5726
+ return commitMaskPaintBuffer(accumulator, paintBuffer, color, alpha, blendFn, blendColorPixelDataAlphaMask);
5836
5727
  };
5837
- commit(accumulator, alpha = 255, blendFn = sourceOverPerfect) {
5838
- const tileShift = this.config.tileShift;
5839
- const lookup = this.lookup;
5840
- const opts = this.opts;
5841
- const blendPixelDataFn = this.blendPixelDataFn;
5842
- opts.alpha = alpha;
5843
- opts.blendFn = blendFn;
5728
+ }
5729
+
5730
+ // src/Internal/_constants.ts
5731
+ var DEFAULT_CANVAS_FACTORY = (w, h) => new OffscreenCanvas(w, h);
5732
+
5733
+ // src/Tile/MaskTile.ts
5734
+ var makeAlphaMaskTile = (id, tx, ty, tileSize, tileArea) => {
5735
+ return {
5736
+ tileType: 1 /* MASK */,
5737
+ type: 0 /* ALPHA */,
5738
+ data: new Uint8Array(tileArea),
5739
+ w: tileSize,
5740
+ h: tileSize,
5741
+ id,
5742
+ tx,
5743
+ ty
5744
+ };
5745
+ };
5746
+ var makeBinaryMaskTile = (id, tx, ty, tileSize, tileArea) => {
5747
+ return {
5748
+ tileType: 1 /* MASK */,
5749
+ type: 1 /* BINARY */,
5750
+ data: new Uint8Array(tileArea),
5751
+ w: tileSize,
5752
+ h: tileSize,
5753
+ id,
5754
+ tx,
5755
+ ty
5756
+ };
5757
+ };
5758
+
5759
+ // src/Paint/Render/AlphaMaskPaintBufferCanvasRenderer.ts
5760
+ function makeAlphaMaskPaintBufferCanvasRenderer(paintBuffer, canvasFactory = DEFAULT_CANVAS_FACTORY) {
5761
+ const config = paintBuffer.config;
5762
+ const tileSize = config.tileSize;
5763
+ const tileShift = config.tileShift;
5764
+ const tileArea = config.tileArea;
5765
+ const lookup = paintBuffer.lookup;
5766
+ const canvas = canvasFactory(tileSize, tileSize);
5767
+ const ctx = canvas.getContext("2d");
5768
+ if (!ctx) throw new Error(CANVAS_CTX_FAILED);
5769
+ ctx.imageSmoothingEnabled = false;
5770
+ const bridge = makePixelData(new ImageData(tileSize, tileSize));
5771
+ const view32 = bridge.data;
5772
+ return function drawPaintBuffer(targetCtx, color, alpha = 255, compOperation = "source-over") {
5773
+ if (alpha === 0) return;
5774
+ const baseSrcAlpha = color >>> 24;
5775
+ const colorRGB = color & 16777215;
5776
+ if (baseSrcAlpha === 0) return;
5777
+ targetCtx.globalAlpha = alpha / 255;
5778
+ targetCtx.globalCompositeOperation = compOperation;
5844
5779
  for (let i = 0; i < lookup.length; i++) {
5845
5780
  const tile = lookup[i];
5846
5781
  if (tile) {
5847
- const didChange = accumulator.storeTileBeforeState(tile.id, tile.tx, tile.ty);
5782
+ const data8 = tile.data;
5783
+ view32.fill(0);
5784
+ for (let p = 0; p < tileArea; p++) {
5785
+ const maskA = data8[p];
5786
+ if (maskA === 0) continue;
5787
+ if (maskA === 255) {
5788
+ view32[p] = color;
5789
+ } else {
5790
+ const t = baseSrcAlpha * maskA + 128;
5791
+ const finalA = t + (t >> 8) >> 8;
5792
+ view32[p] = (colorRGB | finalA << 24) >>> 0;
5793
+ }
5794
+ }
5848
5795
  const dx = tile.tx << tileShift;
5849
5796
  const dy = tile.ty << tileShift;
5850
- opts.x = dx;
5851
- opts.y = dy;
5852
- opts.w = tile.w;
5853
- opts.h = tile.h;
5854
- didChange(blendPixelDataFn(this.config.target, tile, opts));
5797
+ ctx.putImageData(bridge.imageData, 0, 0);
5798
+ targetCtx.drawImage(canvas, dx, dy);
5855
5799
  }
5856
5800
  }
5857
- this.clear();
5858
- }
5859
- clear() {
5860
- this.tilePool.releaseTiles(this.lookup);
5861
- }
5801
+ targetCtx.globalAlpha = 1;
5802
+ targetCtx.globalCompositeOperation = "source-over";
5803
+ };
5804
+ }
5805
+
5806
+ // src/Paint/Commit/AlphaMaskPaintBufferManager.ts
5807
+ function makeAlphaMaskPaintBufferManager(writer, canvasFactory = DEFAULT_CANVAS_FACTORY) {
5808
+ const pool = new TilePool(writer.config, makeAlphaMaskTile);
5809
+ const buffer = new AlphaMaskPaintBuffer(writer.config, pool);
5810
+ const draw = makeAlphaMaskPaintBufferCanvasRenderer(buffer, canvasFactory);
5811
+ return {
5812
+ clear: buffer.clear.bind(buffer),
5813
+ paintRect: buffer.paintRect.bind(buffer),
5814
+ paintAlphaMask: buffer.paintAlphaMask.bind(buffer),
5815
+ paintBinaryMask: buffer.paintBinaryMask.bind(buffer),
5816
+ commit: makeAlphaMaskPaintBufferCommitter(writer.accumulator, buffer),
5817
+ draw
5818
+ };
5819
+ }
5820
+
5821
+ // src/Paint/Commit/BinaryMaskPaintBufferCommitter.ts
5822
+ function makeBinaryMaskPaintBufferCommitter(accumulator, paintBuffer) {
5823
+ return function commitBinaryMaskPaintBufferToAccumulator(color, alpha = 255, blendFn = sourceOverPerfect) {
5824
+ return commitMaskPaintBuffer(accumulator, paintBuffer, color, alpha, blendFn, blendColorPixelDataBinaryMask);
5825
+ };
5826
+ }
5827
+
5828
+ // src/Paint/Render/BinaryMaskPaintBufferCanvasRenderer.ts
5829
+ function makeBinaryMaskPaintBufferCanvasRenderer(paintBuffer, canvasFactory = DEFAULT_CANVAS_FACTORY) {
5830
+ const config = paintBuffer.config;
5831
+ const tileSize = config.tileSize;
5832
+ const tileShift = config.tileShift;
5833
+ const tileArea = config.tileArea;
5834
+ const lookup = paintBuffer.lookup;
5835
+ const canvas = canvasFactory(tileSize, tileSize);
5836
+ const ctx = canvas.getContext("2d");
5837
+ if (!ctx) throw new Error(CANVAS_CTX_FAILED);
5838
+ ctx.imageSmoothingEnabled = false;
5839
+ const bridge = makePixelData(new ImageData(tileSize, tileSize));
5840
+ const view32 = bridge.data;
5841
+ return function drawPaintBuffer(targetCtx, color, alpha = 255, compOperation = "source-over") {
5842
+ if (alpha === 0) return;
5843
+ const baseSrcAlpha = color >>> 24;
5844
+ if (baseSrcAlpha === 0) return;
5845
+ targetCtx.globalAlpha = alpha / 255;
5846
+ targetCtx.globalCompositeOperation = compOperation;
5847
+ for (let i = 0; i < lookup.length; i++) {
5848
+ const tile = lookup[i];
5849
+ if (tile) {
5850
+ const data8 = tile.data;
5851
+ view32.fill(0);
5852
+ for (let p = 0; p < tileArea; p++) {
5853
+ if (data8[p] === 1) {
5854
+ view32[p] = color;
5855
+ }
5856
+ }
5857
+ const dx = tile.tx << tileShift;
5858
+ const dy = tile.ty << tileShift;
5859
+ ctx.putImageData(bridge.imageData, 0, 0);
5860
+ targetCtx.drawImage(canvas, dx, dy);
5861
+ }
5862
+ }
5863
+ targetCtx.globalAlpha = 1;
5864
+ targetCtx.globalCompositeOperation = "source-over";
5865
+ };
5866
+ }
5867
+
5868
+ // src/Paint/Commit/BinaryMaskPaintBufferManager.ts
5869
+ function makeBinaryMaskPaintBufferManager(writer, canvasFactory = DEFAULT_CANVAS_FACTORY) {
5870
+ const pool = new TilePool(writer.config, makeBinaryMaskTile);
5871
+ const buffer = new BinaryMaskPaintBuffer(writer.config, pool);
5872
+ const draw = makeBinaryMaskPaintBufferCanvasRenderer(buffer, canvasFactory);
5873
+ return {
5874
+ clear: buffer.clear.bind(buffer),
5875
+ paintRect: buffer.paintRect.bind(buffer),
5876
+ paintBinaryMask: buffer.paintBinaryMask.bind(buffer),
5877
+ commit: makeBinaryMaskPaintBufferCommitter(writer.accumulator, buffer),
5878
+ draw
5879
+ };
5880
+ }
5881
+
5882
+ // src/Paint/Commit/commitColorPaintBuffer.ts
5883
+ var SCRATCH_OPTS2 = {
5884
+ alpha: 255,
5885
+ blendFn: sourceOverPerfect,
5886
+ x: 0,
5887
+ y: 0,
5888
+ w: 0,
5889
+ h: 0
5862
5890
  };
5891
+ function commitColorPaintBuffer(accumulator, paintBuffer, alpha = 255, blendFn = sourceOverPerfect, blendPixelDataFn = blendPixelData) {
5892
+ const config = accumulator.config;
5893
+ const tileShift = config.tileShift;
5894
+ const lookup = paintBuffer.lookup;
5895
+ SCRATCH_OPTS2.alpha = alpha;
5896
+ SCRATCH_OPTS2.blendFn = blendFn;
5897
+ for (let i = 0; i < lookup.length; i++) {
5898
+ const tile = lookup[i];
5899
+ if (tile) {
5900
+ const didChange = accumulator.storeTileBeforeState(tile.id, tile.tx, tile.ty);
5901
+ const dx = tile.tx << tileShift;
5902
+ const dy = tile.ty << tileShift;
5903
+ SCRATCH_OPTS2.x = dx;
5904
+ SCRATCH_OPTS2.y = dy;
5905
+ SCRATCH_OPTS2.w = tile.w;
5906
+ SCRATCH_OPTS2.h = tile.h;
5907
+ didChange(blendPixelDataFn(config.target, tile, SCRATCH_OPTS2));
5908
+ }
5909
+ }
5910
+ paintBuffer.clear();
5911
+ }
5863
5912
 
5864
- // src/Paint/ColorPaintBufferCanvasRenderer.ts
5865
- function makeColorPaintBufferCanvasRenderer(paintBuffer, offscreenCanvasClass = OffscreenCanvas) {
5913
+ // src/Paint/Commit/ColorPaintBufferCommitter.ts
5914
+ function makeColorPaintBufferCommitter(accumulator, paintBuffer) {
5915
+ return function commitColorPaintBufferToAccumulator(alpha = 255, blendFn = sourceOverPerfect) {
5916
+ return commitColorPaintBuffer(accumulator, paintBuffer, alpha, blendFn, blendPixelData);
5917
+ };
5918
+ }
5919
+
5920
+ // src/Paint/Render/ColorPaintBufferCanvasRenderer.ts
5921
+ function makeColorPaintBufferCanvasRenderer(paintBuffer, canvasFactory = DEFAULT_CANVAS_FACTORY) {
5866
5922
  const config = paintBuffer.config;
5867
5923
  const tileSize = config.tileSize;
5868
5924
  const tileShift = config.tileShift;
5869
5925
  const lookup = paintBuffer.lookup;
5870
- const canvas = new offscreenCanvasClass(tileSize, tileSize);
5926
+ const canvas = canvasFactory(tileSize, tileSize);
5871
5927
  const ctx = canvas.getContext("2d");
5872
5928
  if (!ctx) throw new Error(CANVAS_CTX_FAILED);
5873
5929
  ctx.imageSmoothingEnabled = false;
@@ -5888,6 +5944,21 @@ function makeColorPaintBufferCanvasRenderer(paintBuffer, offscreenCanvasClass =
5888
5944
  };
5889
5945
  }
5890
5946
 
5947
+ // src/Paint/Commit/ColorPaintBufferManager.ts
5948
+ function makeColorPaintBufferManager(writer, canvasFactory = DEFAULT_CANVAS_FACTORY) {
5949
+ const pool = new TilePool(writer.config, makePixelTile);
5950
+ const buffer = new ColorPaintBuffer(writer.config, pool);
5951
+ const draw = makeColorPaintBufferCanvasRenderer(buffer, canvasFactory);
5952
+ return {
5953
+ clear: buffer.clear.bind(buffer),
5954
+ paintRect: buffer.paintRect.bind(buffer),
5955
+ paintAlphaMask: buffer.paintAlphaMask.bind(buffer),
5956
+ paintBinaryMask: buffer.paintBinaryMask.bind(buffer),
5957
+ commit: makeColorPaintBufferCommitter(writer.accumulator, buffer),
5958
+ draw
5959
+ };
5960
+ }
5961
+
5891
5962
  // src/Paint/makeCirclePaintMask.ts
5892
5963
  function makeCirclePaintAlphaMask(size, fallOff = (d) => d) {
5893
5964
  const area = size * size;
@@ -6025,12 +6096,14 @@ function makeReusablePixelData() {
6025
6096
  };
6026
6097
  }
6027
6098
 
6028
- // src/Paint/PaintCursorRenderer.ts
6029
- function makePaintCursorRenderer(factory = (w, h) => new OffscreenCanvas(w, h)) {
6030
- const canvas = factory(1, 1);
6031
- const ctx = canvas.getContext("2d");
6032
- if (!ctx) throw new Error(CANVAS_CTX_FAILED);
6033
- ctx.imageSmoothingEnabled = false;
6099
+ // src/Paint/Render/PaintCursorRenderer.ts
6100
+ function makePaintCursorRenderer(reusableCanvasFactory) {
6101
+ const factory = reusableCanvasFactory ?? makeReusableOffscreenCanvas;
6102
+ const updateBuffer = factory();
6103
+ const {
6104
+ canvas,
6105
+ ctx
6106
+ } = updateBuffer(1, 1);
6034
6107
  const getPixelData = makeReusablePixelData();
6035
6108
  let _color = packColor(0, 255, 255, 255);
6036
6109
  let _scale = 1;
@@ -6047,8 +6120,7 @@ function makePaintCursorRenderer(factory = (w, h) => new OffscreenCanvas(w, h))
6047
6120
  currentMask = paintMask ?? currentMask;
6048
6121
  _scale = scale ?? _scale;
6049
6122
  _color = color ?? _color;
6050
- canvas.width = currentMask.w * _scale + 2 * _scale;
6051
- canvas.height = currentMask.h * _scale + 2 * _scale;
6123
+ updateBuffer(currentMask.w * _scale + 2 * _scale, currentMask.h * _scale + 2 * _scale);
6052
6124
  if (currentMask.type === 1 /* BINARY */) {
6053
6125
  if (currentMask.outlineType === 1 /* CIRCLE */) {
6054
6126
  outline = makeCircleBinaryMaskOutline(currentMask.w, _scale);
@@ -6131,7 +6203,7 @@ function blendColorPixelDataMask(dst, color, mask, opts) {
6131
6203
  }
6132
6204
 
6133
6205
  // src/PixelData/blendColorPixelDataPaintAlphaMask.ts
6134
- var SCRATCH_OPTS = {
6206
+ var SCRATCH_OPTS3 = {
6135
6207
  x: 0,
6136
6208
  y: 0,
6137
6209
  alpha: 255,
@@ -6140,15 +6212,15 @@ var SCRATCH_OPTS = {
6140
6212
  function blendColorPixelDataPaintAlphaMask(dst, color, mask, x, y, alpha = 255, blendFn = sourceOverPerfect) {
6141
6213
  const tx = x + mask.centerOffsetX;
6142
6214
  const ty = y + mask.centerOffsetY;
6143
- SCRATCH_OPTS.x = tx;
6144
- SCRATCH_OPTS.y = ty;
6145
- SCRATCH_OPTS.alpha = alpha;
6146
- SCRATCH_OPTS.blendFn = blendFn;
6147
- return blendColorPixelDataAlphaMask(dst, color, mask, SCRATCH_OPTS);
6215
+ SCRATCH_OPTS3.x = tx;
6216
+ SCRATCH_OPTS3.y = ty;
6217
+ SCRATCH_OPTS3.alpha = alpha;
6218
+ SCRATCH_OPTS3.blendFn = blendFn;
6219
+ return blendColorPixelDataAlphaMask(dst, color, mask, SCRATCH_OPTS3);
6148
6220
  }
6149
6221
 
6150
6222
  // src/PixelData/blendColorPixelDataPaintBinaryMask.ts
6151
- var SCRATCH_OPTS2 = {
6223
+ var SCRATCH_OPTS4 = {
6152
6224
  x: 0,
6153
6225
  y: 0,
6154
6226
  alpha: 255,
@@ -6157,15 +6229,15 @@ var SCRATCH_OPTS2 = {
6157
6229
  function blendColorPixelDataPaintBinaryMask(dst, color, mask, x, y, alpha = 255, blendFn = sourceOverPerfect) {
6158
6230
  const tx = x + mask.centerOffsetX;
6159
6231
  const ty = y + mask.centerOffsetY;
6160
- SCRATCH_OPTS2.x = tx;
6161
- SCRATCH_OPTS2.y = ty;
6162
- SCRATCH_OPTS2.alpha = alpha;
6163
- SCRATCH_OPTS2.blendFn = blendFn;
6164
- return blendColorPixelDataBinaryMask(dst, color, mask, SCRATCH_OPTS2);
6232
+ SCRATCH_OPTS4.x = tx;
6233
+ SCRATCH_OPTS4.y = ty;
6234
+ SCRATCH_OPTS4.alpha = alpha;
6235
+ SCRATCH_OPTS4.blendFn = blendFn;
6236
+ return blendColorPixelDataBinaryMask(dst, color, mask, SCRATCH_OPTS4);
6165
6237
  }
6166
6238
 
6167
6239
  // src/PixelData/blendColorPixelDataPaintMask.ts
6168
- var SCRATCH_OPTS3 = {
6240
+ var SCRATCH_OPTS5 = {
6169
6241
  x: 0,
6170
6242
  y: 0,
6171
6243
  alpha: 255,
@@ -6174,14 +6246,14 @@ var SCRATCH_OPTS3 = {
6174
6246
  function blendColorPixelDataPaintMask(dst, color, mask, x, y, alpha = 255, blendFn = sourceOverPerfect) {
6175
6247
  const tx = x + mask.centerOffsetX;
6176
6248
  const ty = y + mask.centerOffsetY;
6177
- SCRATCH_OPTS3.x = tx;
6178
- SCRATCH_OPTS3.y = ty;
6179
- SCRATCH_OPTS3.alpha = alpha;
6180
- SCRATCH_OPTS3.blendFn = blendFn;
6249
+ SCRATCH_OPTS5.x = tx;
6250
+ SCRATCH_OPTS5.y = ty;
6251
+ SCRATCH_OPTS5.alpha = alpha;
6252
+ SCRATCH_OPTS5.blendFn = blendFn;
6181
6253
  if (mask.type === 1 /* BINARY */) {
6182
- return blendColorPixelDataBinaryMask(dst, color, mask, SCRATCH_OPTS3);
6254
+ return blendColorPixelDataBinaryMask(dst, color, mask, SCRATCH_OPTS5);
6183
6255
  } else {
6184
- return blendColorPixelDataAlphaMask(dst, color, mask, SCRATCH_OPTS3);
6256
+ return blendColorPixelDataAlphaMask(dst, color, mask, SCRATCH_OPTS5);
6185
6257
  }
6186
6258
  }
6187
6259
 
@@ -6195,7 +6267,7 @@ function blendPixelDataMask(target, src, mask, opts) {
6195
6267
  }
6196
6268
 
6197
6269
  // src/PixelData/blendPixelDataPaintBuffer.ts
6198
- var SCRATCH_OPTS4 = {
6270
+ var SCRATCH_OPTS6 = {
6199
6271
  x: 0,
6200
6272
  y: 0,
6201
6273
  alpha: 255,
@@ -6209,11 +6281,11 @@ function blendPixelDataPaintBuffer(target, paintBuffer, alpha = 255, blendFn, bl
6209
6281
  if (tile) {
6210
6282
  const x = tile.tx << tileShift;
6211
6283
  const y = tile.ty << tileShift;
6212
- SCRATCH_OPTS4.x = x;
6213
- SCRATCH_OPTS4.y = y;
6214
- SCRATCH_OPTS4.alpha = alpha;
6215
- SCRATCH_OPTS4.blendFn = blendFn;
6216
- blendPixelDataFn(target, tile, SCRATCH_OPTS4);
6284
+ SCRATCH_OPTS6.x = x;
6285
+ SCRATCH_OPTS6.y = y;
6286
+ SCRATCH_OPTS6.alpha = alpha;
6287
+ SCRATCH_OPTS6.blendFn = blendFn;
6288
+ blendPixelDataFn(target, tile, SCRATCH_OPTS6);
6217
6289
  }
6218
6290
  }
6219
6291
  }
@@ -6496,32 +6568,6 @@ function writePaintBufferToPixelData(target, paintBuffer, writePixelDataBufferFn
6496
6568
  }
6497
6569
  }
6498
6570
  }
6499
-
6500
- // src/Tile/MaskTile.ts
6501
- var makeAlphaMaskTile = (id, tx, ty, tileSize, tileArea) => {
6502
- return {
6503
- tileType: 1 /* MASK */,
6504
- type: 0 /* ALPHA */,
6505
- data: new Uint8Array(tileArea),
6506
- w: tileSize,
6507
- h: tileSize,
6508
- id,
6509
- tx,
6510
- ty
6511
- };
6512
- };
6513
- var makeBinaryMaskTile = (id, tx, ty, tileSize, tileArea) => {
6514
- return {
6515
- tileType: 1 /* MASK */,
6516
- type: 1 /* BINARY */,
6517
- data: new Uint8Array(tileArea),
6518
- w: tileSize,
6519
- h: tileSize,
6520
- id,
6521
- tx,
6522
- ty
6523
- };
6524
- };
6525
6571
  // Annotate the CommonJS export names for ESM import in node:
6526
6572
  0 && (module.exports = {
6527
6573
  AlphaMaskPaintBuffer,
@@ -6569,6 +6615,8 @@ var makeBinaryMaskTile = (id, tx, ty, tileSize, tileArea) => {
6569
6615
  colorDistance,
6570
6616
  colorDodgeFast,
6571
6617
  colorDodgePerfect,
6618
+ commitColorPaintBuffer,
6619
+ commitMaskPaintBuffer,
6572
6620
  copyImageData,
6573
6621
  copyImageDataLike,
6574
6622
  copyMask,
@@ -6641,11 +6689,15 @@ var makeBinaryMaskTile = (id, tx, ty, tileSize, tileArea) => {
6641
6689
  linearLightPerfect,
6642
6690
  makeAlphaMask,
6643
6691
  makeAlphaMaskPaintBufferCanvasRenderer,
6692
+ makeAlphaMaskPaintBufferCommitter,
6693
+ makeAlphaMaskPaintBufferManager,
6644
6694
  makeAlphaMaskTile,
6645
6695
  makeBinaryMask,
6646
6696
  makeBinaryMaskFromAlphaMask,
6647
6697
  makeBinaryMaskOutline,
6648
6698
  makeBinaryMaskPaintBufferCanvasRenderer,
6699
+ makeBinaryMaskPaintBufferCommitter,
6700
+ makeBinaryMaskPaintBufferManager,
6649
6701
  makeBinaryMaskTile,
6650
6702
  makeBlendModeRegistry,
6651
6703
  makeCanvasFrameRenderer,
@@ -6656,6 +6708,8 @@ var makeBinaryMaskTile = (id, tx, ty, tileSize, tileArea) => {
6656
6708
  makeClippedBlit,
6657
6709
  makeClippedRect,
6658
6710
  makeColorPaintBufferCanvasRenderer,
6711
+ makeColorPaintBufferCommitter,
6712
+ makeColorPaintBufferManager,
6659
6713
  makeFastBlendModeRegistry,
6660
6714
  makeFullPixelMutator,
6661
6715
  makeHistoryAction,