pixel-data-js 0.30.0 → 0.32.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.
@@ -93,6 +93,7 @@ __export(src_exports, {
93
93
  eachTileInBounds: () => eachTileInBounds,
94
94
  exclusionFast: () => exclusionFast,
95
95
  exclusionPerfect: () => exclusionPerfect,
96
+ extractImageData: () => extractImageData,
96
97
  extractImageDataBuffer: () => extractImageDataBuffer,
97
98
  extractMask: () => extractMask,
98
99
  extractMaskBuffer: () => extractMaskBuffer,
@@ -142,6 +143,7 @@ __export(src_exports, {
142
143
  makeAlphaMaskPaintBufferCommitter: () => makeAlphaMaskPaintBufferCommitter,
143
144
  makeAlphaMaskPaintBufferManager: () => makeAlphaMaskPaintBufferManager,
144
145
  makeAlphaMaskTile: () => makeAlphaMaskTile,
146
+ makeBatchedQueue: () => makeBatchedQueue,
145
147
  makeBinaryMask: () => makeBinaryMask,
146
148
  makeBinaryMaskFromAlphaMask: () => makeBinaryMaskFromAlphaMask,
147
149
  makeBinaryMaskOutline: () => makeBinaryMaskOutline,
@@ -155,8 +157,6 @@ __export(src_exports, {
155
157
  makeCircleBinaryMaskOutline: () => makeCircleBinaryMaskOutline,
156
158
  makeCirclePaintAlphaMask: () => makeCirclePaintAlphaMask,
157
159
  makeCirclePaintBinaryMask: () => makeCirclePaintBinaryMask,
158
- makeClippedBlit: () => makeClippedBlit,
159
- makeClippedRect: () => makeClippedRect,
160
160
  makeColorPaintBufferCanvasRenderer: () => makeColorPaintBufferCanvasRenderer,
161
161
  makeColorPaintBufferCommitter: () => makeColorPaintBufferCommitter,
162
162
  makeColorPaintBufferManager: () => makeColorPaintBufferManager,
@@ -176,6 +176,7 @@ __export(src_exports, {
176
176
  makePixelTile: () => makePixelTile,
177
177
  makeRectBinaryMaskOutline: () => makeRectBinaryMaskOutline,
178
178
  makeRectFalloffPaintAlphaMask: () => makeRectFalloffPaintAlphaMask,
179
+ makeRenderQueue: () => makeRenderQueue,
179
180
  makeReusableCanvas: () => makeReusableCanvas,
180
181
  makeReusableImageData: () => makeReusableImageData,
181
182
  makeReusableOffscreenCanvas: () => makeReusableOffscreenCanvas,
@@ -222,8 +223,7 @@ __export(src_exports, {
222
223
  resamplePixelDataInPlace: () => resamplePixelDataInPlace,
223
224
  resampleUint32Array: () => resampleUint32Array,
224
225
  resizeImageData: () => resizeImageData,
225
- resolveBlitClipping: () => resolveBlitClipping,
226
- resolveRectClipping: () => resolveRectClipping,
226
+ resizePixelData: () => resizePixelData,
227
227
  rotatePixelData: () => rotatePixelData,
228
228
  screenFast: () => screenFast,
229
229
  screenPerfect: () => screenPerfect,
@@ -351,86 +351,7 @@ function color32ToCssRGBA(color) {
351
351
  return `rgba(${r},${g},${b},${alpha})`;
352
352
  }
353
353
 
354
- // src/Rect/resolveClipping.ts
355
- var makeClippedRect = () => ({
356
- x: 0,
357
- y: 0,
358
- w: 0,
359
- h: 0,
360
- inBounds: false
361
- });
362
- var makeClippedBlit = () => ({
363
- x: 0,
364
- y: 0,
365
- sx: 0,
366
- sy: 0,
367
- w: 0,
368
- h: 0,
369
- inBounds: false
370
- });
371
- function resolveRectClipping(x, y, w, h, boundaryW, boundaryH, out) {
372
- if (x < 0) {
373
- w += x;
374
- x = 0;
375
- }
376
- if (y < 0) {
377
- h += y;
378
- y = 0;
379
- }
380
- const actualW = Math.min(w, boundaryW - x);
381
- const actualH = Math.min(h, boundaryH - y);
382
- if (actualW <= 0 || actualH <= 0) {
383
- out.inBounds = false;
384
- return out;
385
- }
386
- out.x = x;
387
- out.y = y;
388
- out.w = actualW;
389
- out.h = actualH;
390
- out.inBounds = true;
391
- return out;
392
- }
393
- function resolveBlitClipping(x, y, sx, sy, w, h, dstW, dstH, srcW, srcH, out) {
394
- if (sx < 0) {
395
- x -= sx;
396
- w += sx;
397
- sx = 0;
398
- }
399
- if (sy < 0) {
400
- y -= sy;
401
- h += sy;
402
- sy = 0;
403
- }
404
- w = Math.min(w, srcW - sx);
405
- h = Math.min(h, srcH - sy);
406
- if (x < 0) {
407
- sx -= x;
408
- w += x;
409
- x = 0;
410
- }
411
- if (y < 0) {
412
- sy -= y;
413
- h += y;
414
- y = 0;
415
- }
416
- const actualW = Math.min(w, dstW - x);
417
- const actualH = Math.min(h, dstH - y);
418
- if (actualW <= 0 || actualH <= 0) {
419
- out.inBounds = false;
420
- return out;
421
- }
422
- out.x = x;
423
- out.y = y;
424
- out.sx = sx;
425
- out.sy = sy;
426
- out.w = actualW;
427
- out.h = actualH;
428
- out.inBounds = true;
429
- return out;
430
- }
431
-
432
354
  // src/ImageData/extractImageDataBuffer.ts
433
- var SCRATCH_BLIT = makeClippedBlit();
434
355
  function extractImageDataBuffer(imageData, _x, _y, _w, _h) {
435
356
  const {
436
357
  x,
@@ -443,28 +364,52 @@ function extractImageDataBuffer(imageData, _x, _y, _w, _h) {
443
364
  w: _w,
444
365
  h: _h
445
366
  };
446
- const {
447
- width: srcW,
448
- height: srcH,
449
- data: src
450
- } = imageData;
451
- if (w <= 0 || h <= 0) return new Uint8ClampedArray(0);
452
- const out = new Uint8ClampedArray(w * h * 4);
453
- const clip = resolveBlitClipping(0, 0, x, y, w, h, w, h, srcW, srcH, SCRATCH_BLIT);
454
- if (!clip.inBounds) return out;
455
- const {
456
- x: dstX,
457
- y: dstY,
458
- sx: srcX,
459
- sy: srcY,
460
- w: copyW,
461
- h: copyH
462
- } = clip;
463
- const rowLen = copyW * 4;
464
- for (let row = 0; row < copyH; row++) {
465
- const srcStart = ((srcY + row) * srcW + srcX) * 4;
466
- const dstStart = ((dstY + row) * w + dstX) * 4;
467
- out.set(src.subarray(srcStart, srcStart + rowLen), dstStart);
367
+ if (w <= 0) return new Uint8ClampedArray(0);
368
+ if (h <= 0) return new Uint8ClampedArray(0);
369
+ const srcW = imageData.width;
370
+ const srcH = imageData.height;
371
+ const src = imageData.data;
372
+ const outLen = w * h * 4;
373
+ const out = new Uint8ClampedArray(outLen);
374
+ let srcX = x;
375
+ let srcY = y;
376
+ let dstX = 0;
377
+ let dstY = 0;
378
+ let copyW = w;
379
+ let copyH = h;
380
+ if (srcX < 0) {
381
+ dstX = -srcX;
382
+ copyW += srcX;
383
+ srcX = 0;
384
+ }
385
+ if (srcY < 0) {
386
+ dstY = -srcY;
387
+ copyH += srcY;
388
+ srcY = 0;
389
+ }
390
+ copyW = Math.min(copyW, srcW - srcX);
391
+ copyH = Math.min(copyH, srcH - srcY);
392
+ if (copyW <= 0) return out;
393
+ if (copyH <= 0) return out;
394
+ const isAligned = src.byteOffset % 4 === 0;
395
+ if (isAligned) {
396
+ const srcLen32 = src.byteLength / 4;
397
+ const src32 = new Uint32Array(src.buffer, src.byteOffset, srcLen32);
398
+ const out32 = new Uint32Array(out.buffer);
399
+ for (let row = 0; row < copyH; row++) {
400
+ const srcStart = (srcY + row) * srcW + srcX;
401
+ const dstStart = (dstY + row) * w + dstX;
402
+ const chunk = src32.subarray(srcStart, srcStart + copyW);
403
+ out32.set(chunk, dstStart);
404
+ }
405
+ } else {
406
+ const rowLen = copyW * 4;
407
+ for (let row = 0; row < copyH; row++) {
408
+ const srcStart = ((srcY + row) * srcW + srcX) * 4;
409
+ const dstStart = ((dstY + row) * w + dstX) * 4;
410
+ const chunk = src.subarray(srcStart, srcStart + rowLen);
411
+ out.set(chunk, dstStart);
412
+ }
468
413
  }
469
414
  return out;
470
415
  }
@@ -2290,6 +2235,67 @@ async function writeImageDataToClipboard(imageData) {
2290
2235
  return writeImgBlobToClipboard(blob);
2291
2236
  }
2292
2237
 
2238
+ // src/Control/BatchedQueue.ts
2239
+ function makeBatchedQueue(processor, queue) {
2240
+ let activeSet = /* @__PURE__ */ new Set();
2241
+ let processingSet = /* @__PURE__ */ new Set();
2242
+ let scheduled = false;
2243
+ const flush = () => {
2244
+ const current = activeSet;
2245
+ activeSet = processingSet;
2246
+ processingSet = current;
2247
+ scheduled = false;
2248
+ try {
2249
+ processor(processingSet);
2250
+ } finally {
2251
+ processingSet.clear();
2252
+ }
2253
+ };
2254
+ function markDirty(item) {
2255
+ activeSet.add(item);
2256
+ if (!scheduled) {
2257
+ scheduled = true;
2258
+ queue(flush);
2259
+ }
2260
+ }
2261
+ function markMultipleDirty(items) {
2262
+ let len = items.length;
2263
+ if (len === 0) return;
2264
+ for (let i = 0; i < len; i++) {
2265
+ activeSet.add(items[i]);
2266
+ }
2267
+ if (!scheduled) {
2268
+ scheduled = true;
2269
+ queue(flush);
2270
+ }
2271
+ }
2272
+ return {
2273
+ markDirty,
2274
+ markMultipleDirty
2275
+ };
2276
+ }
2277
+
2278
+ // src/Control/RenderQueue.ts
2279
+ function makeRenderQueue(cb) {
2280
+ let needsRender = false;
2281
+ let frameId = 0;
2282
+ const trigger = () => {
2283
+ if (needsRender) return;
2284
+ needsRender = true;
2285
+ frameId = requestAnimationFrame(() => {
2286
+ needsRender = false;
2287
+ cb();
2288
+ });
2289
+ };
2290
+ trigger.cancel = () => {
2291
+ if (needsRender) {
2292
+ cancelAnimationFrame(frameId);
2293
+ needsRender = false;
2294
+ }
2295
+ };
2296
+ return trigger;
2297
+ }
2298
+
2293
2299
  // src/History/PixelPatchTiles.ts
2294
2300
  function applyPatchTiles(target, tiles, tileSize) {
2295
2301
  for (let i = 0; i < tiles.length; i++) {
@@ -2852,11 +2858,10 @@ var PixelWriter = class {
2852
2858
  * throw immediately to prevent silent data loss from a nested extractPatch.
2853
2859
  *
2854
2860
  * @param transaction Callback to be executed inside the transaction.
2855
- * @param after Called after both undo and redo — use for generic change notifications.
2856
- * @param afterUndo Called after undo only — use for dimension or state changes specific to undo.
2861
+ * @param afterUndo Called after undo only.
2857
2862
  * @param afterRedo Called after redo only.
2858
2863
  */
2859
- withHistory(transaction, after, afterUndo, afterRedo) {
2864
+ withHistory(transaction, afterUndo, afterRedo) {
2860
2865
  if (this._inProgress) {
2861
2866
  throw new Error("withHistory is not re-entrant \u2014 commit or rollback the current operation first");
2862
2867
  }
@@ -2871,10 +2876,10 @@ var PixelWriter = class {
2871
2876
  }
2872
2877
  if (this.accumulator.beforeTiles.length === 0) return;
2873
2878
  const patch = this.accumulator.extractPatch();
2874
- const action = this.historyActionFactory(this.config, this.accumulator, patch, after, afterUndo, afterRedo);
2879
+ const action = this.historyActionFactory(this.config, this.accumulator, patch, afterUndo, afterRedo);
2875
2880
  this.historyManager.commit(action);
2876
2881
  }
2877
- resize(newWidth, newHeight, offsetX = 0, offsetY = 0, after, afterUndo, afterRedo, resizeImageDataFn = resizeImageData) {
2882
+ resize(newWidth, newHeight, offsetX = 0, offsetY = 0, afterUndo, afterRedo, resizeImageDataFn = resizeImageData) {
2878
2883
  if (this._inProgress) {
2879
2884
  throw new Error("Cannot resize inside a withHistory callback");
2880
2885
  }
@@ -2890,12 +2895,10 @@ var PixelWriter = class {
2890
2895
  undo: () => {
2891
2896
  setPixelData(target, beforeImageData);
2892
2897
  afterUndo?.(beforeImageData);
2893
- after?.(beforeImageData);
2894
2898
  },
2895
2899
  redo: () => {
2896
2900
  setPixelData(target, afterImageData);
2897
2901
  afterRedo?.(afterImageData);
2898
- after?.(afterImageData);
2899
2902
  }
2900
2903
  });
2901
2904
  }
@@ -3847,8 +3850,9 @@ var mutatorBlendPixelData = ((writer, deps = defaults13) => {
3847
3850
  });
3848
3851
 
3849
3852
  // src/PixelData/fillPixelData.ts
3850
- var SCRATCH_RECT = makeClippedRect();
3851
3853
  function fillPixelData(dst, color, _x, _y, _w, _h) {
3854
+ const dstW = dst.w;
3855
+ const dstH = dst.h;
3852
3856
  let x;
3853
3857
  let y;
3854
3858
  let w;
@@ -3856,8 +3860,8 @@ function fillPixelData(dst, color, _x, _y, _w, _h) {
3856
3860
  if (typeof _x === "object") {
3857
3861
  x = _x.x ?? 0;
3858
3862
  y = _x.y ?? 0;
3859
- w = _x.w ?? dst.w;
3860
- h = _x.h ?? dst.h;
3863
+ w = _x.w ?? dstW;
3864
+ h = _x.h ?? dstH;
3861
3865
  } else if (typeof _x === "number") {
3862
3866
  x = _x;
3863
3867
  y = _y;
@@ -3866,24 +3870,42 @@ function fillPixelData(dst, color, _x, _y, _w, _h) {
3866
3870
  } else {
3867
3871
  x = 0;
3868
3872
  y = 0;
3869
- w = dst.w;
3870
- h = dst.h;
3871
- }
3872
- const clip = resolveRectClipping(x, y, w, h, dst.w, dst.h, SCRATCH_RECT);
3873
- if (!clip.inBounds) return false;
3874
- const {
3875
- x: finalX,
3876
- y: finalY,
3877
- w: actualW,
3878
- h: actualH
3879
- } = clip;
3873
+ w = dstW;
3874
+ h = dstH;
3875
+ }
3876
+ let dstX = x;
3877
+ let dstY = y;
3878
+ let fillW = w;
3879
+ let fillH = h;
3880
+ if (dstX < 0) {
3881
+ fillW += dstX;
3882
+ dstX = 0;
3883
+ }
3884
+ if (dstY < 0) {
3885
+ fillH += dstY;
3886
+ dstY = 0;
3887
+ }
3888
+ fillW = Math.min(fillW, dstW - dstX);
3889
+ fillH = Math.min(fillH, dstH - dstY);
3890
+ if (fillW <= 0) return false;
3891
+ if (fillH <= 0) return false;
3880
3892
  const dst32 = dst.data;
3881
- const dw = dst.w;
3882
3893
  let hasChanged = false;
3883
- for (let iy = 0; iy < actualH; iy++) {
3884
- const rowOffset = (finalY + iy) * dw;
3885
- const start = rowOffset + finalX;
3886
- const end = start + actualW;
3894
+ if (dstX === 0 && fillW === dstW) {
3895
+ const start = dstY * dstW;
3896
+ const end = start + fillW * fillH;
3897
+ for (let i = start; i < end; i++) {
3898
+ if (dst32[i] !== color) {
3899
+ dst32[i] = color;
3900
+ hasChanged = true;
3901
+ }
3902
+ }
3903
+ return hasChanged;
3904
+ }
3905
+ for (let iy = 0; iy < fillH; iy++) {
3906
+ const rowOffset = (dstY + iy) * dstW;
3907
+ const start = rowOffset + dstX;
3908
+ const end = start + fillW;
3887
3909
  for (let i = start; i < end; i++) {
3888
3910
  if (dst32[i] !== color) {
3889
3911
  dst32[i] = color;
@@ -3945,39 +3967,48 @@ var mutatorFillRect = ((writer, deps = defaults15) => {
3945
3967
  });
3946
3968
 
3947
3969
  // src/PixelData/fillPixelDataBinaryMask.ts
3948
- var SCRATCH_RECT2 = makeClippedRect();
3949
3970
  function fillPixelDataBinaryMask(target, color, mask, x = 0, y = 0) {
3971
+ const targetW = target.w;
3972
+ const targetH = target.h;
3950
3973
  const maskW = mask.w;
3951
3974
  const maskH = mask.h;
3952
- const clip = resolveRectClipping(x, y, maskW, maskH, target.w, target.h, SCRATCH_RECT2);
3953
- if (!clip.inBounds) return false;
3954
- const {
3955
- x: finalX,
3956
- y: finalY,
3957
- w: actualW,
3958
- h: actualH
3959
- } = clip;
3975
+ let dstX = x;
3976
+ let dstY = y;
3977
+ let actualW = maskW;
3978
+ let actualH = maskH;
3979
+ if (dstX < 0) {
3980
+ actualW += dstX;
3981
+ dstX = 0;
3982
+ }
3983
+ if (dstY < 0) {
3984
+ actualH += dstY;
3985
+ dstY = 0;
3986
+ }
3987
+ actualW = Math.min(actualW, targetW - dstX);
3988
+ actualH = Math.min(actualH, targetH - dstY);
3989
+ if (actualW <= 0 || actualH <= 0) return false;
3960
3990
  const maskData = mask.data;
3961
3991
  const dst32 = target.data;
3962
- const dw = target.w;
3992
+ const mx = dstX - x;
3993
+ const my = dstY - y;
3963
3994
  let hasChanged = false;
3995
+ let dIdx = dstY * targetW + dstX;
3996
+ let mIdx = my * maskW + mx;
3997
+ const dStride = targetW - actualW;
3998
+ const mStride = maskW - actualW;
3964
3999
  for (let iy = 0; iy < actualH; iy++) {
3965
- const currentY = finalY + iy;
3966
- const maskY = currentY - y;
3967
- const maskOffset = maskY * maskW;
3968
- const dstRowOffset = currentY * dw;
3969
4000
  for (let ix = 0; ix < actualW; ix++) {
3970
- const currentX = finalX + ix;
3971
- const maskX = currentX - x;
3972
- const maskIndex = maskOffset + maskX;
3973
- if (maskData[maskIndex]) {
3974
- const current = dst32[dstRowOffset + currentX];
3975
- if (current !== color) {
3976
- dst32[dstRowOffset + currentX] = color;
4001
+ if (maskData[mIdx]) {
4002
+ if (dst32[dIdx] !== color) {
4003
+ dst32[dIdx] = color;
3977
4004
  hasChanged = true;
3978
4005
  }
3979
4006
  }
4007
+ dIdx++;
4008
+ mIdx++;
3980
4009
  }
4010
+ dIdx += dStride;
4011
+ mIdx += mStride;
3981
4012
  }
3982
4013
  return hasChanged;
3983
4014
  }
@@ -3999,35 +4030,43 @@ var mutatorFillBinaryMask = ((writer, deps = defaults16) => {
3999
4030
  });
4000
4031
 
4001
4032
  // src/PixelData/invertPixelData.ts
4002
- var SCRATCH_RECT3 = makeClippedRect();
4003
4033
  function invertPixelData(target, opts) {
4034
+ const targetW = target.w;
4035
+ const targetH = target.h;
4004
4036
  const mask = opts?.mask;
4037
+ const invertMask = opts?.invertMask ?? false;
4005
4038
  const targetX = opts?.x ?? 0;
4006
4039
  const targetY = opts?.y ?? 0;
4007
4040
  const mx = opts?.mx ?? 0;
4008
4041
  const my = opts?.my ?? 0;
4009
- const width = opts?.w ?? target.w;
4010
- const height = opts?.h ?? target.h;
4011
- const invertMask = opts?.invertMask ?? false;
4012
- const clip = resolveRectClipping(targetX, targetY, width, height, target.w, target.h, SCRATCH_RECT3);
4013
- if (!clip.inBounds) return false;
4014
- const {
4015
- x,
4016
- y,
4017
- w: actualW,
4018
- h: actualH
4019
- } = clip;
4042
+ const w = opts?.w ?? targetW;
4043
+ const h = opts?.h ?? targetH;
4044
+ let x = targetX;
4045
+ let y = targetY;
4046
+ let actualW = w;
4047
+ let actualH = h;
4048
+ if (x < 0) {
4049
+ actualW += x;
4050
+ x = 0;
4051
+ }
4052
+ if (y < 0) {
4053
+ actualH += y;
4054
+ y = 0;
4055
+ }
4056
+ actualW = Math.min(actualW, targetW - x);
4057
+ actualH = Math.min(actualH, targetH - y);
4058
+ if (actualW <= 0 || actualH <= 0) return false;
4020
4059
  const dst32 = target.data;
4021
- const dw = target.w;
4022
- const mPitch = mask?.w ?? width;
4060
+ const dw = targetW;
4023
4061
  const dx = x - targetX;
4024
4062
  const dy = y - targetY;
4025
4063
  let dIdx = y * dw + x;
4026
- let mIdx = (my + dy) * mPitch + (mx + dx);
4027
4064
  const dStride = dw - actualW;
4028
- const mStride = mPitch - actualW;
4029
4065
  if (mask) {
4030
4066
  const maskData = mask.data;
4067
+ const mPitch = mask.w;
4068
+ let mIdx = (my + dy) * mPitch + (mx + dx);
4069
+ const mStride = mPitch - actualW;
4031
4070
  for (let iy = 0; iy < actualH; iy++) {
4032
4071
  for (let ix = 0; ix < actualW; ix++) {
4033
4072
  const mVal = maskData[mIdx];
@@ -4119,6 +4158,27 @@ function copyImageDataLike({
4119
4158
  };
4120
4159
  }
4121
4160
 
4161
+ // src/ImageData/extractImageData.ts
4162
+ function extractImageData(imageData, _x, _y, _w, _h) {
4163
+ const {
4164
+ x,
4165
+ y,
4166
+ w,
4167
+ h
4168
+ } = typeof _x === "object" ? _x : {
4169
+ x: _x,
4170
+ y: _y,
4171
+ w: _w,
4172
+ h: _h
4173
+ };
4174
+ if (w <= 0) return null;
4175
+ if (h <= 0) return null;
4176
+ const result = new ImageData(w, h);
4177
+ const buffer = extractImageDataBuffer(imageData, x, y, w, h);
4178
+ result.data.set(buffer);
4179
+ return result;
4180
+ }
4181
+
4122
4182
  // src/ImageData/ImageDataLike.ts
4123
4183
  function makeImageDataLike(width, height, data) {
4124
4184
  const size = width * height * 4;
@@ -4269,94 +4329,120 @@ function uInt32ArrayToImageDataLike(data, width, height) {
4269
4329
  }
4270
4330
 
4271
4331
  // src/ImageData/writeImageData.ts
4272
- var SCRATCH_BLIT2 = makeClippedBlit();
4273
- function writeImageData(target, source, x, y, sx = 0, sy = 0, sw = source.width, sh = source.height, mask = null, maskType = 1 /* BINARY */) {
4332
+ function writeImageData(target, source, x, y) {
4274
4333
  const dstW = target.width;
4275
4334
  const dstH = target.height;
4276
- const dstData = target.data;
4335
+ const dst = target.data;
4277
4336
  const srcW = source.width;
4278
- const srcData = source.data;
4279
- const clip = resolveBlitClipping(x, y, sx, sy, sw, sh, dstW, dstH, srcW, source.height, SCRATCH_BLIT2);
4280
- if (!clip.inBounds) return;
4281
- const {
4282
- x: dstX,
4283
- y: dstY,
4284
- sx: srcX,
4285
- sy: srcY,
4286
- w: copyW,
4287
- h: copyH
4288
- } = clip;
4289
- const useMask = !!mask;
4290
- for (let row = 0; row < copyH; row++) {
4291
- const currentDstY = dstY + row;
4292
- const currentSrcY = srcY + row;
4293
- const dstStart = (currentDstY * dstW + dstX) * 4;
4294
- const srcStart = (currentSrcY * srcW + srcX) * 4;
4295
- if (useMask && mask) {
4296
- for (let ix = 0; ix < copyW; ix++) {
4297
- const mi = currentSrcY * srcW + (srcX + ix);
4298
- const alpha = mask[mi];
4299
- if (alpha === 0) {
4300
- continue;
4301
- }
4302
- const di = dstStart + ix * 4;
4303
- const si = srcStart + ix * 4;
4304
- if (maskType === 1 /* BINARY */ || alpha === 255) {
4305
- dstData[di] = srcData[si];
4306
- dstData[di + 1] = srcData[si + 1];
4307
- dstData[di + 2] = srcData[si + 2];
4308
- dstData[di + 3] = srcData[si + 3];
4309
- } else {
4310
- const a = alpha / 255;
4311
- const invA = 1 - a;
4312
- dstData[di] = srcData[si] * a + dstData[di] * invA;
4313
- dstData[di + 1] = srcData[si + 1] * a + dstData[di + 1] * invA;
4314
- dstData[di + 2] = srcData[si + 2] * a + dstData[di + 2] * invA;
4315
- dstData[di + 3] = srcData[si + 3] * a + dstData[di + 3] * invA;
4316
- }
4317
- }
4318
- } else {
4319
- const byteLen = copyW * 4;
4320
- const sub = srcData.subarray(srcStart, srcStart + byteLen);
4321
- dstData.set(sub, dstStart);
4337
+ const srcH = source.height;
4338
+ const src = source.data;
4339
+ let dstX = x;
4340
+ let dstY = y;
4341
+ let srcX = 0;
4342
+ let srcY = 0;
4343
+ let copyW = srcW;
4344
+ let copyH = srcH;
4345
+ if (dstX < 0) {
4346
+ srcX = -dstX;
4347
+ copyW += dstX;
4348
+ dstX = 0;
4349
+ }
4350
+ if (dstY < 0) {
4351
+ srcY = -dstY;
4352
+ copyH += dstY;
4353
+ dstY = 0;
4354
+ }
4355
+ copyW = Math.min(copyW, dstW - dstX);
4356
+ copyH = Math.min(copyH, dstH - dstY);
4357
+ if (copyW <= 0) return;
4358
+ if (copyH <= 0) return;
4359
+ const isDstAligned = dst.byteOffset % 4 === 0;
4360
+ const isSrcAligned = src.byteOffset % 4 === 0;
4361
+ if (isDstAligned && isSrcAligned) {
4362
+ const dstLen32 = dst.byteLength / 4;
4363
+ const dst32 = new Uint32Array(dst.buffer, dst.byteOffset, dstLen32);
4364
+ const srcLen32 = src.byteLength / 4;
4365
+ const src32 = new Uint32Array(src.buffer, src.byteOffset, srcLen32);
4366
+ for (let row = 0; row < copyH; row++) {
4367
+ const dstStart = (dstY + row) * dstW + dstX;
4368
+ const srcStart = (srcY + row) * srcW + srcX;
4369
+ const chunk = src32.subarray(srcStart, srcStart + copyW);
4370
+ dst32.set(chunk, dstStart);
4371
+ }
4372
+ } else {
4373
+ const rowLen = copyW * 4;
4374
+ for (let row = 0; row < copyH; row++) {
4375
+ const dstStart = ((dstY + row) * dstW + dstX) * 4;
4376
+ const srcStart = ((srcY + row) * srcW + srcX) * 4;
4377
+ const chunk = src.subarray(srcStart, srcStart + rowLen);
4378
+ dst.set(chunk, dstStart);
4322
4379
  }
4323
4380
  }
4324
4381
  }
4325
4382
 
4326
4383
  // src/ImageData/writeImageDataBuffer.ts
4327
- var SCRATCH_BLIT3 = makeClippedBlit();
4328
4384
  function writeImageDataBuffer(target, data, _x, _y, _w, _h) {
4329
- const {
4330
- x,
4331
- y,
4332
- w,
4333
- h
4334
- } = typeof _x === "object" ? _x : {
4335
- x: _x,
4336
- y: _y,
4337
- w: _w,
4338
- h: _h
4339
- };
4340
- const {
4341
- width: dstW,
4342
- height: dstH,
4343
- data: dst
4344
- } = target;
4345
- const clip = resolveBlitClipping(x, y, 0, 0, w, h, dstW, dstH, w, h, SCRATCH_BLIT3);
4346
- if (!clip.inBounds) return;
4347
- const {
4348
- x: dstX,
4349
- y: dstY,
4350
- sx: srcX,
4351
- sy: srcY,
4352
- w: copyW,
4353
- h: copyH
4354
- } = clip;
4355
- const rowLen = copyW * 4;
4356
- for (let row = 0; row < copyH; row++) {
4357
- const dstStart = ((dstY + row) * dstW + dstX) * 4;
4358
- const srcStart = ((srcY + row) * w + srcX) * 4;
4359
- dst.set(data.subarray(srcStart, srcStart + rowLen), dstStart);
4385
+ let x;
4386
+ let y;
4387
+ let w;
4388
+ let h;
4389
+ if (typeof _x === "object") {
4390
+ x = _x.x;
4391
+ y = _x.y;
4392
+ w = _x.w;
4393
+ h = _x.h;
4394
+ } else {
4395
+ x = _x;
4396
+ y = _y;
4397
+ w = _w;
4398
+ h = _h;
4399
+ }
4400
+ if (w <= 0) return;
4401
+ if (h <= 0) return;
4402
+ const dstW = target.width;
4403
+ const dstH = target.height;
4404
+ const dst = target.data;
4405
+ let dstX = x;
4406
+ let dstY = y;
4407
+ let srcX = 0;
4408
+ let srcY = 0;
4409
+ let copyW = w;
4410
+ let copyH = h;
4411
+ if (dstX < 0) {
4412
+ srcX = -dstX;
4413
+ copyW += dstX;
4414
+ dstX = 0;
4415
+ }
4416
+ if (dstY < 0) {
4417
+ srcY = -dstY;
4418
+ copyH += dstY;
4419
+ dstY = 0;
4420
+ }
4421
+ copyW = Math.min(copyW, dstW - dstX);
4422
+ copyH = Math.min(copyH, dstH - dstY);
4423
+ if (copyW <= 0) return;
4424
+ if (copyH <= 0) return;
4425
+ const isDstAligned = dst.byteOffset % 4 === 0;
4426
+ const isSrcAligned = data.byteOffset % 4 === 0;
4427
+ if (isDstAligned && isSrcAligned) {
4428
+ const dstLen32 = dst.byteLength / 4;
4429
+ const dst32 = new Uint32Array(dst.buffer, dst.byteOffset, dstLen32);
4430
+ const srcLen32 = data.byteLength / 4;
4431
+ const src32 = new Uint32Array(data.buffer, data.byteOffset, srcLen32);
4432
+ for (let row = 0; row < copyH; row++) {
4433
+ const dstStart = (dstY + row) * dstW + dstX;
4434
+ const srcStart = (srcY + row) * w + srcX;
4435
+ const chunk = src32.subarray(srcStart, srcStart + copyW);
4436
+ dst32.set(chunk, dstStart);
4437
+ }
4438
+ } else {
4439
+ const rowLen = copyW * 4;
4440
+ for (let row = 0; row < copyH; row++) {
4441
+ const dstStart = ((dstY + row) * dstW + dstX) * 4;
4442
+ const srcStart = ((srcY + row) * w + srcX) * 4;
4443
+ const chunk = data.subarray(srcStart, srcStart + rowLen);
4444
+ dst.set(chunk, dstStart);
4445
+ }
4360
4446
  }
4361
4447
  }
4362
4448
 
@@ -6289,8 +6375,9 @@ function blendPixelDataPaintBuffer(target, paintBuffer, alpha = 255, blendFn, bl
6289
6375
  }
6290
6376
 
6291
6377
  // src/PixelData/fillPixelDataFast.ts
6292
- var SCRATCH_RECT4 = makeClippedRect();
6293
6378
  function fillPixelDataFast(dst, color, _x, _y, _w, _h) {
6379
+ const dstW = dst.w;
6380
+ const dstH = dst.h;
6294
6381
  let x;
6295
6382
  let y;
6296
6383
  let w;
@@ -6311,23 +6398,31 @@ function fillPixelDataFast(dst, color, _x, _y, _w, _h) {
6311
6398
  w = dst.w;
6312
6399
  h = dst.h;
6313
6400
  }
6314
- const clip = resolveRectClipping(x, y, w, h, dst.w, dst.h, SCRATCH_RECT4);
6315
- if (!clip.inBounds) return;
6316
- const {
6317
- x: finalX,
6318
- y: finalY,
6319
- w: actualW,
6320
- h: actualH
6321
- } = clip;
6401
+ let dstX = x;
6402
+ let dstY = y;
6403
+ let fillW = w;
6404
+ let fillH = h;
6405
+ if (dstX < 0) {
6406
+ fillW += dstX;
6407
+ dstX = 0;
6408
+ }
6409
+ if (dstY < 0) {
6410
+ fillH += dstY;
6411
+ dstY = 0;
6412
+ }
6413
+ fillW = Math.min(fillW, dstW - dstX);
6414
+ fillH = Math.min(fillH, dstH - dstY);
6415
+ if (fillW <= 0) return;
6416
+ if (fillH <= 0) return;
6322
6417
  const dst32 = dst.data;
6323
6418
  const dw = dst.w;
6324
- if (actualW === dw && actualH === dst.h && finalX === 0 && finalY === 0) {
6419
+ if (fillW === dw && fillH === dst.h && dstX === 0 && dstY === 0) {
6325
6420
  dst32.fill(color);
6326
6421
  return;
6327
6422
  }
6328
- for (let iy = 0; iy < actualH; iy++) {
6329
- const start = (finalY + iy) * dw + finalX;
6330
- const end = start + actualW;
6423
+ for (let iy = 0; iy < fillH; iy++) {
6424
+ const start = (dstY + iy) * dw + dstX;
6425
+ const end = start + fillW;
6331
6426
  dst32.fill(color, start, end);
6332
6427
  }
6333
6428
  }
@@ -6345,36 +6440,48 @@ function copyPixelData(target) {
6345
6440
  }
6346
6441
 
6347
6442
  // src/PixelData/extractPixelDataBuffer.ts
6348
- var SCRATCH_BLIT4 = makeClippedBlit();
6349
6443
  function extractPixelDataBuffer(source, _x, _y, _w, _h) {
6350
- const {
6351
- x,
6352
- y,
6353
- w,
6354
- h
6355
- } = typeof _x === "object" ? _x : {
6356
- x: _x,
6357
- y: _y,
6358
- w: _w,
6359
- h: _h
6360
- };
6444
+ let x;
6445
+ let y;
6446
+ let w;
6447
+ let h;
6448
+ if (typeof _x === "object") {
6449
+ x = _x.x;
6450
+ y = _x.y;
6451
+ w = _x.w;
6452
+ h = _x.h;
6453
+ } else {
6454
+ x = _x;
6455
+ y = _y;
6456
+ w = _w;
6457
+ h = _h;
6458
+ }
6361
6459
  const srcW = source.w;
6362
6460
  const srcH = source.h;
6363
6461
  const srcData = source.data;
6364
- if (w <= 0 || h <= 0) {
6365
- return new Uint32Array(0);
6366
- }
6462
+ if (w <= 0) return new Uint32Array(0);
6463
+ if (h <= 0) return new Uint32Array(0);
6367
6464
  const dstData = new Uint32Array(w * h);
6368
- const clip = resolveBlitClipping(0, 0, x, y, w, h, w, h, srcW, srcH, SCRATCH_BLIT4);
6369
- if (!clip.inBounds) return dstData;
6370
- const {
6371
- x: dstX,
6372
- y: dstY,
6373
- sx: srcX,
6374
- sy: srcY,
6375
- w: copyW,
6376
- h: copyH
6377
- } = clip;
6465
+ let srcX = x;
6466
+ let srcY = y;
6467
+ let dstX = 0;
6468
+ let dstY = 0;
6469
+ let copyW = w;
6470
+ let copyH = h;
6471
+ if (srcX < 0) {
6472
+ dstX = -srcX;
6473
+ copyW += srcX;
6474
+ srcX = 0;
6475
+ }
6476
+ if (srcY < 0) {
6477
+ dstY = -srcY;
6478
+ copyH += srcY;
6479
+ srcY = 0;
6480
+ }
6481
+ copyW = Math.min(copyW, srcW - srcX);
6482
+ copyH = Math.min(copyH, srcH - srcY);
6483
+ if (copyW <= 0) return dstData;
6484
+ if (copyH <= 0) return dstData;
6378
6485
  for (let row = 0; row < copyH; row++) {
6379
6486
  const srcStart = (srcY + row) * srcW + srcX;
6380
6487
  const dstStart = (dstY + row) * w + dstX;
@@ -6467,6 +6574,46 @@ function resamplePixelDataInPlace(pixelData, factor) {
6467
6574
  resampled.imageData = uInt32ArrayToImageData(resampled.data, resampled.w, resampled.h);
6468
6575
  }
6469
6576
 
6577
+ // src/PixelData/resizePixelData.ts
6578
+ function resizePixelData(target, newWidth, newHeight, offsetX = 0, offsetY = 0, out) {
6579
+ const newData = new Uint32Array(newWidth * newHeight);
6580
+ const {
6581
+ w: oldW,
6582
+ h: oldH,
6583
+ data: oldData
6584
+ } = target;
6585
+ const result = out ?? {};
6586
+ result.w = newWidth;
6587
+ result.h = newHeight;
6588
+ result.data = newData;
6589
+ const x0 = Math.max(0, offsetX);
6590
+ const y0 = Math.max(0, offsetY);
6591
+ const x1 = Math.min(newWidth, offsetX + oldW);
6592
+ const y1 = Math.min(newHeight, offsetY + oldH);
6593
+ if (x1 <= x0 || y1 <= y0) {
6594
+ return result;
6595
+ }
6596
+ const copyW = x1 - x0;
6597
+ const copyH = y1 - y0;
6598
+ if (copyW === oldW && copyW === newWidth && offsetX === 0) {
6599
+ const srcStart = (y0 - offsetY) * oldW;
6600
+ const dstStart = y0 * newWidth;
6601
+ const len = copyW * copyH;
6602
+ newData.set(oldData.subarray(srcStart, srcStart + len), dstStart);
6603
+ return result;
6604
+ }
6605
+ for (let row = 0; row < copyH; row++) {
6606
+ const dstY = y0 + row;
6607
+ const srcY = dstY - offsetY;
6608
+ const srcX = x0 - offsetX;
6609
+ const dstStart = dstY * newWidth + x0;
6610
+ const srcStart = srcY * oldW + srcX;
6611
+ const chunk = oldData.subarray(srcStart, srcStart + copyW);
6612
+ newData.set(chunk, dstStart);
6613
+ }
6614
+ return result;
6615
+ }
6616
+
6470
6617
  // src/PixelData/rotatePixelData.ts
6471
6618
  function rotatePixelData(pixelData) {
6472
6619
  const width = pixelData.w;
@@ -6520,36 +6667,50 @@ function uInt32ArrayToPixelData(data, width, height) {
6520
6667
  }
6521
6668
 
6522
6669
  // src/PixelData/writePixelDataBuffer.ts
6523
- var SCRATCH_BLIT5 = makeClippedBlit();
6524
6670
  function writePixelDataBuffer(target, data, _x, _y, _w, _h) {
6525
- const {
6526
- x,
6527
- y,
6528
- w,
6529
- h
6530
- } = typeof _x === "object" ? _x : {
6531
- x: _x,
6532
- y: _y,
6533
- w: _w,
6534
- h: _h
6535
- };
6671
+ let x;
6672
+ let y;
6673
+ let w;
6674
+ let h;
6675
+ if (typeof _x === "object") {
6676
+ x = _x.x;
6677
+ y = _x.y;
6678
+ w = _x.w;
6679
+ h = _x.h;
6680
+ } else {
6681
+ x = _x;
6682
+ y = _y;
6683
+ w = _w;
6684
+ h = _h;
6685
+ }
6686
+ if (w <= 0 || h <= 0) return;
6536
6687
  const dstW = target.w;
6537
6688
  const dstH = target.h;
6538
6689
  const dstData = target.data;
6539
- const clip = resolveBlitClipping(x, y, 0, 0, w, h, dstW, dstH, w, h, SCRATCH_BLIT5);
6540
- if (!clip.inBounds) return;
6541
- const {
6542
- x: dstX,
6543
- y: dstY,
6544
- sx: srcX,
6545
- sy: srcY,
6546
- w: copyW,
6547
- h: copyH
6548
- } = clip;
6690
+ let dstX = x;
6691
+ let dstY = y;
6692
+ let srcX = 0;
6693
+ let srcY = 0;
6694
+ let copyW = w;
6695
+ let copyH = h;
6696
+ if (dstX < 0) {
6697
+ srcX = -dstX;
6698
+ copyW += dstX;
6699
+ dstX = 0;
6700
+ }
6701
+ if (dstY < 0) {
6702
+ srcY = -dstY;
6703
+ copyH += dstY;
6704
+ dstY = 0;
6705
+ }
6706
+ copyW = Math.min(copyW, dstW - dstX);
6707
+ copyH = Math.min(copyH, dstH - dstY);
6708
+ if (copyW <= 0 || copyH <= 0) return;
6549
6709
  for (let row = 0; row < copyH; row++) {
6550
6710
  const dstStart = (dstY + row) * dstW + dstX;
6551
6711
  const srcStart = (srcY + row) * w + srcX;
6552
- dstData.set(data.subarray(srcStart, srcStart + copyW), dstStart);
6712
+ const chunk = data.subarray(srcStart, srcStart + copyW);
6713
+ dstData.set(chunk, dstStart);
6553
6714
  }
6554
6715
  }
6555
6716
 
@@ -6641,6 +6802,7 @@ function writePaintBufferToPixelData(target, paintBuffer, writePixelDataBufferFn
6641
6802
  eachTileInBounds,
6642
6803
  exclusionFast,
6643
6804
  exclusionPerfect,
6805
+ extractImageData,
6644
6806
  extractImageDataBuffer,
6645
6807
  extractMask,
6646
6808
  extractMaskBuffer,
@@ -6690,6 +6852,7 @@ function writePaintBufferToPixelData(target, paintBuffer, writePixelDataBufferFn
6690
6852
  makeAlphaMaskPaintBufferCommitter,
6691
6853
  makeAlphaMaskPaintBufferManager,
6692
6854
  makeAlphaMaskTile,
6855
+ makeBatchedQueue,
6693
6856
  makeBinaryMask,
6694
6857
  makeBinaryMaskFromAlphaMask,
6695
6858
  makeBinaryMaskOutline,
@@ -6703,8 +6866,6 @@ function writePaintBufferToPixelData(target, paintBuffer, writePixelDataBufferFn
6703
6866
  makeCircleBinaryMaskOutline,
6704
6867
  makeCirclePaintAlphaMask,
6705
6868
  makeCirclePaintBinaryMask,
6706
- makeClippedBlit,
6707
- makeClippedRect,
6708
6869
  makeColorPaintBufferCanvasRenderer,
6709
6870
  makeColorPaintBufferCommitter,
6710
6871
  makeColorPaintBufferManager,
@@ -6724,6 +6885,7 @@ function writePaintBufferToPixelData(target, paintBuffer, writePixelDataBufferFn
6724
6885
  makePixelTile,
6725
6886
  makeRectBinaryMaskOutline,
6726
6887
  makeRectFalloffPaintAlphaMask,
6888
+ makeRenderQueue,
6727
6889
  makeReusableCanvas,
6728
6890
  makeReusableImageData,
6729
6891
  makeReusableOffscreenCanvas,
@@ -6770,8 +6932,7 @@ function writePaintBufferToPixelData(target, paintBuffer, writePixelDataBufferFn
6770
6932
  resamplePixelDataInPlace,
6771
6933
  resampleUint32Array,
6772
6934
  resizeImageData,
6773
- resolveBlitClipping,
6774
- resolveRectClipping,
6935
+ resizePixelData,
6775
6936
  rotatePixelData,
6776
6937
  screenFast,
6777
6938
  screenPerfect,