@poe-platform/safe-bash 0.1.780 → 0.1.781

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.
@@ -200070,7 +200070,7 @@ function cosString(value3, span2) {
200070
200070
  if (typeof value3 === "string") {
200071
200071
  let needsUtf16 = false;
200072
200072
  for (let i = 0; i < value3.length; i++) {
200073
- if (value3.charCodeAt(i) > 255) {
200073
+ if (!PDF_DOC_ENCODING_REVERSE.has(value3.charCodeAt(i))) {
200074
200074
  needsUtf16 = true;
200075
200075
  break;
200076
200076
  }
@@ -200088,7 +200088,7 @@ function cosString(value3, span2) {
200088
200088
  }
200089
200089
  const bytes = new Uint8Array(value3.length);
200090
200090
  for (let i = 0; i < value3.length; i++) {
200091
- bytes[i] = value3.charCodeAt(i) & 255;
200091
+ bytes[i] = PDF_DOC_ENCODING_REVERSE.get(value3.charCodeAt(i));
200092
200092
  }
200093
200093
  return { kind: "string", format: "literal", bytes, span: span2 };
200094
200094
  }
@@ -200235,6 +200235,9 @@ var PDF_DOC_ENCODING_MAP = {
200235
200235
  160: 8364,
200236
200236
  173: 65533
200237
200237
  };
200238
+ var PDF_DOC_ENCODING_REVERSE = new Map(
200239
+ Array.from({ length: 256 }, (_, byte) => [PDF_DOC_ENCODING_MAP[byte] ?? byte, byte])
200240
+ );
200238
200241
  function decodeUtf16UnitsWithSurrogateCheck(units) {
200239
200242
  let out = "";
200240
200243
  for (let i = 0; i < units.length; i++) {
@@ -200526,6 +200529,7 @@ var CosByteLexer = class {
200526
200529
  const start = this.pos;
200527
200530
  this.pos++;
200528
200531
  let depth = 1;
200532
+ let recovery;
200529
200533
  const out = [];
200530
200534
  while (this.pos < this.end && depth > 0) {
200531
200535
  const b3 = this.bytes[this.pos++];
@@ -200560,7 +200564,15 @@ var CosByteLexer = class {
200560
200564
  out.push(b3);
200561
200565
  } else if (b3 === 41) {
200562
200566
  depth--;
200563
- if (depth > 0) out.push(b3);
200567
+ if (depth > 0) {
200568
+ const next = this.bytes[this.pos];
200569
+ const afterLine = next === 13 && this.bytes[this.pos + 1] === 10 ? this.pos + 2 : this.pos + 1;
200570
+ const delimiter = this.bytes[afterLine];
200571
+ if (!recovery && this.pos + 2 < this.end && (next === 10 || next === 13) && (delimiter === 47 || delimiter === 62)) {
200572
+ recovery = { offset: this.pos, length: out.length };
200573
+ }
200574
+ out.push(b3);
200575
+ }
200564
200576
  } else if (b3 === 13) {
200565
200577
  if (this.pos < this.end && this.bytes[this.pos] === 10) this.pos++;
200566
200578
  out.push(10);
@@ -200571,6 +200583,10 @@ var CosByteLexer = class {
200571
200583
  throw new PdfError2("E_LIMIT", "PDF literal string exceeds maximum byte length");
200572
200584
  }
200573
200585
  }
200586
+ if (depth > 0 && recovery) {
200587
+ this.pos = recovery.offset;
200588
+ out.length = recovery.length;
200589
+ }
200574
200590
  return {
200575
200591
  kind: "string",
200576
200592
  bytes: Uint8Array.from(out),
@@ -211941,6 +211957,7 @@ function evaluateContentStreamToDisplayList(params) {
211941
211957
  };
211942
211958
  const initialState = {
211943
211959
  ctm: [1, 0, 0, 1, 0, 0],
211960
+ initialCtm: [1, 0, 0, 1, 0, 0],
211944
211961
  strokeColor: { r: 0, g: 0, b: 0 },
211945
211962
  fillColor: { r: 0, g: 0, b: 0 },
211946
211963
  strokeAlpha: 1,
@@ -212238,6 +212255,116 @@ function evaluateContentStreamToDisplayList(params) {
212238
212255
  ] }], void 0, void 0, resources, activeFonts, depth);
212239
212256
  stateStack.pop();
212240
212257
  };
212258
+ const paintPattern = (segments, fillRule, resources, activeFonts, depth, mcid, actualText) => {
212259
+ const st = curState(), doc = params.cosDoc;
212260
+ if (!st.fillPatternName || !doc || !resources) return false;
212261
+ if (depth >= 8) throw new PdfError2("E_LIMIT", "Pattern nesting exceeds the form depth limit");
212262
+ const patterns3 = doc.resolveDict(dictGet(resources, "Pattern"));
212263
+ const pattern = patterns3 && doc.resolve(dictGet(patterns3, st.fillPatternName));
212264
+ const dict = pattern?.kind === "stream" ? pattern.dict : pattern?.kind === "dict" ? pattern : void 0;
212265
+ if (!dict) return false;
212266
+ const nums = (key, fallback) => {
212267
+ const array = doc.resolveArray(dictGet(dict, key));
212268
+ return array ? array.items.map((item, i) => {
212269
+ const value3 = doc.resolve(item);
212270
+ return value3?.kind === "number" ? value3.value : fallback[i] ?? 0;
212271
+ }) : fallback;
212272
+ };
212273
+ let x0 = Infinity, y0 = Infinity, x1 = -Infinity, y1 = -Infinity;
212274
+ const include = (x, y) => {
212275
+ x0 = Math.min(x0, x);
212276
+ y0 = Math.min(y0, y);
212277
+ x1 = Math.max(x1, x);
212278
+ y1 = Math.max(y1, y);
212279
+ };
212280
+ for (const segment of segments) {
212281
+ if (segment.kind === "close") continue;
212282
+ include(segment.x, segment.y);
212283
+ if (segment.kind === "cubic") {
212284
+ include(segment.x1, segment.y1);
212285
+ include(segment.x2, segment.y2);
212286
+ }
212287
+ if (segment.kind === "rect") include(segment.x + segment.width, segment.y + segment.height);
212288
+ }
212289
+ const [originX, originY] = params.origin ?? [0, 0];
212290
+ const clip2 = st.clipRect ?? [originX, originY, originX + params.width, originY + params.height];
212291
+ const bounds2 = [Math.max(x0, clip2[0]), Math.max(y0, clip2[1]), Math.min(x1, clip2[2]), Math.min(y1, clip2[3])];
212292
+ if (!(bounds2[2] > bounds2[0] && bounds2[3] > bounds2[1])) return true;
212293
+ const matrix2 = multiplyMatrices(nums("Matrix", [1, 0, 0, 1, 0, 0]), st.initialCtm);
212294
+ const type = doc.resolve(dictGet(dict, "PatternType"));
212295
+ stateStack.push({ ...st, clipRect: bounds2, clipPaths: [...st.clipPaths ?? [], { segments, fillRule }] });
212296
+ try {
212297
+ if (type?.kind === "number" && type.value === 2) {
212298
+ const shading = doc.resolve(dictGet(dict, "Shading"));
212299
+ const shadingDict = shading?.kind === "stream" ? shading.dict : shading?.kind === "dict" ? shading : void 0;
212300
+ if (!shadingDict) return false;
212301
+ const image = renderShadingDictToImage(
212302
+ doc,
212303
+ shadingDict,
212304
+ matrix2,
212305
+ bounds2,
212306
+ st.fillAlpha,
212307
+ "PatternShading_" + st.fillPatternName,
212308
+ bounds2,
212309
+ shading?.kind === "stream" ? shading : void 0,
212310
+ st.blendMode
212311
+ );
212312
+ if (image) emit({ kind: "image", value: image });
212313
+ return !!image;
212314
+ }
212315
+ if (pattern?.kind !== "stream") return false;
212316
+ const xStepNode = doc.resolve(dictGet(dict, "XStep"));
212317
+ const yStepNode = doc.resolve(dictGet(dict, "YStep"));
212318
+ const xStep = xStepNode?.kind === "number" ? Math.abs(xStepNode.value) : 0;
212319
+ const yStep = yStepNode?.kind === "number" ? Math.abs(yStepNode.value) : 0;
212320
+ const determinant = matrix2[0] * matrix2[3] - matrix2[1] * matrix2[2];
212321
+ if (!xStep || !yStep || !determinant) return true;
212322
+ const inverse2 = [
212323
+ matrix2[3] / determinant,
212324
+ -matrix2[1] / determinant,
212325
+ -matrix2[2] / determinant,
212326
+ matrix2[0] / determinant,
212327
+ (matrix2[2] * matrix2[5] - matrix2[3] * matrix2[4]) / determinant,
212328
+ (matrix2[1] * matrix2[4] - matrix2[0] * matrix2[5]) / determinant
212329
+ ];
212330
+ const corners = [[bounds2[0], bounds2[1]], [bounds2[2], bounds2[1]], [bounds2[2], bounds2[3]], [bounds2[0], bounds2[3]]].map(([x, y]) => transformPoint(inverse2, x, y));
212331
+ const box = nums("BBox", [0, 0, xStep, yStep]);
212332
+ const ix0 = Math.floor((Math.min(...corners.map((p2) => p2[0])) - box[2]) / xStep) + 1;
212333
+ const ix1 = Math.ceil((Math.max(...corners.map((p2) => p2[0])) - box[0]) / xStep) - 1;
212334
+ const iy0 = Math.floor((Math.min(...corners.map((p2) => p2[1])) - box[3]) / yStep) + 1;
212335
+ const iy1 = Math.ceil((Math.max(...corners.map((p2) => p2[1])) - box[1]) / yStep) - 1;
212336
+ if ((ix1 - ix0 + 1) * (iy1 - iy0 + 1) > 2e4) throw new PdfError2("E_LIMIT", "Pattern tile count exceeds 20000");
212337
+ const nodes = parseContentStream(doc.decodeStream(pattern));
212338
+ const patternResources = doc.resolveDict(dictGet(dict, "Resources")) ?? resources;
212339
+ const patternFonts = new Map(activeFonts);
212340
+ for (const [key, font2] of resolvePageFonts(doc, patternResources)) patternFonts.set(key, font2);
212341
+ for (let iy = iy0; iy <= iy1; iy++) {
212342
+ for (let ix = ix0; ix <= ix1; ix++) {
212343
+ const tileCtm = multiplyMatrices([1, 0, 0, 1, ix * xStep, iy * yStep], matrix2);
212344
+ const points = [[box[0], box[1]], [box[2], box[1]], [box[2], box[3]], [box[0], box[3]]].map(([x, y]) => transformPoint(tileCtm, x, y));
212345
+ const tileClip = [
212346
+ ...points.map(([x, y], i) => ({ kind: i === 0 ? "move" : "line", x, y })),
212347
+ { kind: "close" }
212348
+ ];
212349
+ stateStack.push({
212350
+ ...curState(),
212351
+ fillPatternName: void 0,
212352
+ ctm: tileCtm,
212353
+ initialCtm: tileCtm,
212354
+ clipPaths: [...curState().clipPaths ?? [], tileClip]
212355
+ });
212356
+ try {
212357
+ walkNodes(nodes, mcid, actualText, patternResources, patternFonts, depth + 1);
212358
+ } finally {
212359
+ stateStack.pop();
212360
+ }
212361
+ }
212362
+ }
212363
+ return true;
212364
+ } finally {
212365
+ stateStack.pop();
212366
+ }
212367
+ };
212241
212368
  const paintForm = (form, activeResources, activeFonts, depth, mcid, actualText, maskGroup = false) => {
212242
212369
  const st = curState();
212243
212370
  const group = params.cosDoc.resolveDict(dictGet(form.dict, "Group"));
@@ -212296,7 +212423,7 @@ function evaluateContentStreamToDisplayList(params) {
212296
212423
  }
212297
212424
  const parentOperations = capturedOperations;
212298
212425
  const children8 = [];
212299
- const nextState = { ...st, ctm: nextCtm };
212426
+ const nextState = { ...st, ctm: nextCtm, initialCtm: nextCtm };
212300
212427
  if (compositeGroup) {
212301
212428
  capturedOperations = children8;
212302
212429
  nextState.fillAlpha = nextState.strokeAlpha = 1;
@@ -212454,136 +212581,15 @@ function evaluateContentStreamToDisplayList(params) {
212454
212581
  }
212455
212582
  const isFill = ["f", "F", "f*", "B", "B*", "b", "b*"].includes(node3.paint);
212456
212583
  const isStroke = ["S", "s", "B", "B*", "b", "b*"].includes(node3.paint);
212457
- let evaluatedFillPattern = false;
212458
- if (isFill && st.fillPatternName && params.cosDoc && activeResources && depth < 6) {
212459
- const patMap = params.cosDoc.resolveDict(dictGet(activeResources, "Pattern"));
212460
- const patNode = patMap ? params.cosDoc.resolve(dictGet(patMap, st.fillPatternName)) : void 0;
212461
- const patDict = patNode?.kind === "stream" ? patNode.dict : patNode?.kind === "dict" ? patNode : void 0;
212462
- const patTypeNode = patDict && params.cosDoc ? params.cosDoc.resolve(dictGet(patDict, "PatternType")) : void 0;
212463
- const patType = patTypeNode?.kind === "number" ? patTypeNode.value : patNode?.kind === "stream" ? 1 : 0;
212464
- if (patDict && patType === 2 && params.cosDoc) {
212465
- let pMinX = Infinity, pMinY = Infinity, pMaxX = -Infinity, pMaxY = -Infinity;
212466
- for (const s of transformedSegments) {
212467
- if (s.kind === "move" || s.kind === "line") {
212468
- pMinX = Math.min(pMinX, s.x);
212469
- pMinY = Math.min(pMinY, s.y);
212470
- pMaxX = Math.max(pMaxX, s.x);
212471
- pMaxY = Math.max(pMaxY, s.y);
212472
- } else if (s.kind === "cubic") {
212473
- pMinX = Math.min(pMinX, s.x1, s.x2, s.x);
212474
- pMinY = Math.min(pMinY, s.y1, s.y2, s.y);
212475
- pMaxX = Math.max(pMaxX, s.x1, s.x2, s.x);
212476
- pMaxY = Math.max(pMaxY, s.y1, s.y2, s.y);
212477
- } else if (s.kind === "rect") {
212478
- pMinX = Math.min(pMinX, s.x);
212479
- pMinY = Math.min(pMinY, s.y);
212480
- pMaxX = Math.max(pMaxX, s.x + s.width);
212481
- pMaxY = Math.max(pMaxY, s.y + s.height);
212482
- }
212483
- }
212484
- if (Number.isFinite(pMinX) && Number.isFinite(pMinY) && pMaxX > pMinX && pMaxY > pMinY) {
212485
- const shading = params.cosDoc.resolve(dictGet(patDict, "Shading"));
212486
- const shDict = shading?.kind === "stream" ? shading.dict : shading?.kind === "dict" ? shading : void 0;
212487
- if (shDict) {
212488
- let patMatrix = [1, 0, 0, 1, 0, 0];
212489
- const pmArr = params.cosDoc.resolveArray(dictGet(patDict, "Matrix"));
212490
- if (pmArr && pmArr.items.length >= 6) {
212491
- const mn = (idx, fb = 0) => {
212492
- const r = params.cosDoc.resolve(pmArr.items[idx]);
212493
- return r?.kind === "number" ? r.value : fb;
212494
- };
212495
- patMatrix = [mn(0, 1), mn(1, 0), mn(2, 0), mn(3, 1), mn(4, 0), mn(5, 0)];
212496
- }
212497
- const patClip = st.clipRect ? [
212498
- Math.max(st.clipRect[0], pMinX),
212499
- Math.max(st.clipRect[1], pMinY),
212500
- Math.min(st.clipRect[2], pMaxX),
212501
- Math.min(st.clipRect[3], pMaxY)
212502
- ] : [pMinX, pMinY, pMaxX, pMaxY];
212503
- const shImg = renderShadingDictToImage(
212504
- params.cosDoc,
212505
- shDict,
212506
- patMatrix,
212507
- patClip,
212508
- st.fillAlpha,
212509
- "PatternShading_" + st.fillPatternName,
212510
- patClip,
212511
- shading?.kind === "stream" ? shading : void 0,
212512
- st.blendMode
212513
- );
212514
- if (shImg) {
212515
- emit({ kind: "image", value: shImg });
212516
- evaluatedFillPattern = true;
212517
- }
212518
- }
212519
- }
212520
- } else if (patNode?.kind === "stream") {
212521
- let pMinX = Infinity, pMinY = Infinity, pMaxX = -Infinity, pMaxY = -Infinity;
212522
- for (const s of transformedSegments) {
212523
- if (s.kind === "move" || s.kind === "line") {
212524
- pMinX = Math.min(pMinX, s.x);
212525
- pMinY = Math.min(pMinY, s.y);
212526
- pMaxX = Math.max(pMaxX, s.x);
212527
- pMaxY = Math.max(pMaxY, s.y);
212528
- } else if (s.kind === "cubic") {
212529
- pMinX = Math.min(pMinX, s.x1, s.x2, s.x);
212530
- pMinY = Math.min(pMinY, s.y1, s.y2, s.y);
212531
- pMaxX = Math.max(pMaxX, s.x1, s.x2, s.x);
212532
- pMaxY = Math.max(pMaxY, s.y1, s.y2, s.y);
212533
- } else if (s.kind === "rect") {
212534
- pMinX = Math.min(pMinX, s.x);
212535
- pMinY = Math.min(pMinY, s.y);
212536
- pMaxX = Math.max(pMaxX, s.x + s.width);
212537
- pMaxY = Math.max(pMaxY, s.y + s.height);
212538
- }
212539
- }
212540
- if (Number.isFinite(pMinX) && Number.isFinite(pMinY) && pMaxX > pMinX && pMaxY > pMinY) {
212541
- const xsNode = params.cosDoc.resolve(dictGet(patNode.dict, "XStep"));
212542
- const ysNode = params.cosDoc.resolve(dictGet(patNode.dict, "YStep"));
212543
- const xStep = xsNode?.kind === "number" && Math.abs(xsNode.value) > 1e-3 ? Math.abs(xsNode.value) : 40;
212544
- const yStep = ysNode?.kind === "number" && Math.abs(ysNode.value) > 1e-3 ? Math.abs(ysNode.value) : 40;
212545
- let patMatrix = [1, 0, 0, 1, 0, 0];
212546
- const pmArr = params.cosDoc.resolveArray(dictGet(patNode.dict, "Matrix"));
212547
- if (pmArr && pmArr.items.length >= 6) {
212548
- const mn = (idx, fb = 0) => {
212549
- const r = params.cosDoc.resolve(pmArr.items[idx]);
212550
- return r?.kind === "number" ? r.value : fb;
212551
- };
212552
- patMatrix = [mn(0, 1), mn(1, 0), mn(2, 0), mn(3, 1), mn(4, 0), mn(5, 0)];
212553
- }
212554
- const tileClip = st.clipRect ? [
212555
- Math.max(st.clipRect[0], pMinX),
212556
- Math.max(st.clipRect[1], pMinY),
212557
- Math.min(st.clipRect[2], pMaxX),
212558
- Math.min(st.clipRect[3], pMaxY)
212559
- ] : [pMinX, pMinY, pMaxX, pMaxY];
212560
- const patNodes = parseContentStream(params.cosDoc.decodeStream(patNode));
212561
- const patResDict = params.cosDoc.resolveDict(dictGet(patNode.dict, "Resources")) ?? activeResources;
212562
- const patFonts = new Map(activeFonts);
212563
- for (const [fk, fv] of resolvePageFonts(params.cosDoc, patResDict).entries()) {
212564
- patFonts.set(fk, fv);
212565
- }
212566
- const ixStart = Math.floor(pMinX / xStep);
212567
- const ixEnd = Math.min(ixStart + 8, Math.ceil(pMaxX / xStep) - 1);
212568
- const iyStart = Math.floor(pMinY / yStep);
212569
- const iyEnd = Math.min(iyStart + 8, Math.ceil(pMaxY / yStep) - 1);
212570
- for (let iy = iyStart; iy <= iyEnd; iy++) {
212571
- for (let ix = ixStart; ix <= ixEnd; ix++) {
212572
- const tileCtm = multiplyMatrices([1, 0, 0, 1, ix * xStep, iy * yStep], patMatrix);
212573
- stateStack.push({
212574
- ...st,
212575
- fillPatternName: void 0,
212576
- ctm: tileCtm,
212577
- clipRect: tileClip
212578
- });
212579
- walkNodes(patNodes, mcid, actualText, patResDict, patFonts, depth + 1);
212580
- if (stateStack.length > 1) stateStack.pop();
212581
- }
212582
- }
212583
- evaluatedFillPattern = true;
212584
- }
212585
- }
212586
- }
212584
+ const evaluatedFillPattern = isFill && paintPattern(
212585
+ transformedSegments,
212586
+ node3.paint.includes("*") ? "evenodd" : "nonzero",
212587
+ activeResources,
212588
+ activeFonts,
212589
+ depth,
212590
+ mcid,
212591
+ actualText
212592
+ );
212587
212593
  if (evaluatedFillPattern && !isStroke) {
212588
212594
  applyClip();
212589
212595
  break;
@@ -212784,10 +212790,19 @@ function evaluateContentStreamToDisplayList(params) {
212784
212790
  if (st.textRenderMode >= 4 && st.textRenderMode <= 7) pendingTextClip.push(...transformedGlyphSegs);
212785
212791
  const isFillGlyph = st.textRenderMode === 0 || st.textRenderMode === 2 || st.textRenderMode === 4 || st.textRenderMode === 6;
212786
212792
  const isStrokeGlyph = st.textRenderMode === 1 || st.textRenderMode === 2 || st.textRenderMode === 5 || st.textRenderMode === 6;
212793
+ const patterned = isFillGlyph && paintPattern(
212794
+ transformedGlyphSegs,
212795
+ "nonzero",
212796
+ activeResources,
212797
+ activeFonts,
212798
+ depth,
212799
+ mcid,
212800
+ actualText
212801
+ );
212787
212802
  const paint = {
212788
212803
  segments: transformedGlyphSegs,
212789
- fillColor: isFillGlyph ? st.fillColor : void 0,
212790
- fillAlpha: isFillGlyph ? st.fillAlpha : void 0,
212804
+ fillColor: isFillGlyph && !patterned ? st.fillColor : void 0,
212805
+ fillAlpha: isFillGlyph && !patterned ? st.fillAlpha : void 0,
212791
212806
  strokeColor: isStrokeGlyph ? st.strokeColor : void 0,
212792
212807
  strokeAlpha: isStrokeGlyph ? st.strokeAlpha : void 0,
212793
212808
  strokeWidth: isStrokeGlyph ? st.strokeWidth : 0,
@@ -216031,10 +216046,14 @@ function computePdfBlendRgb(cbR, cbG, cbB, csR, csG, csB, mode) {
216031
216046
  blendChannelSeparable(cbB, csB, mode)
216032
216047
  ];
216033
216048
  }
216034
- function blendPixel(rgba, width2, height, px, py, color5, alpha, blendMode, clipMask) {
216049
+ function blendPixel(rgba, width2, height, px, py, color5, alpha, blendMode, clipMask, groupAlpha) {
216035
216050
  if (px < 0 || py < 0 || px >= width2 || py >= height || alpha <= 0) return;
216036
216051
  const a3 = Math.min(1, Math.max(0, alpha)) * (clipMask ? clipMask[(py * width2 + px) * 4 + 3] / 255 : 1);
216037
216052
  const idx = (py * width2 + px) * 4;
216053
+ if (groupAlpha) {
216054
+ const pixel = py * width2 + px;
216055
+ groupAlpha[pixel] = a3 + groupAlpha[pixel] * (1 - a3);
216056
+ }
216038
216057
  const csR = Math.min(1, Math.max(0, color5.r));
216039
216058
  const csG = Math.min(1, Math.max(0, color5.g));
216040
216059
  const csB = Math.min(1, Math.max(0, color5.b));
@@ -216166,7 +216185,7 @@ function pathsToEdges(paths, closeSubpaths = false) {
216166
216185
  }
216167
216186
  return edges2;
216168
216187
  }
216169
- function fillEdgesScanline4x4(rgba, width2, height, edges2, color5, alpha = 1, fillRule = "nonzero", clipScreen, antialias = true, blendMode, clipMask) {
216188
+ function fillEdgesScanline4x4(rgba, width2, height, edges2, color5, alpha = 1, fillRule = "nonzero", clipScreen, antialias = true, blendMode, clipMask, groupAlpha) {
216170
216189
  if (edges2.length === 0) return;
216171
216190
  let minY = Infinity;
216172
216191
  let maxY = -Infinity;
@@ -216232,7 +216251,7 @@ function fillEdgesScanline4x4(rgba, width2, height, edges2, color5, alpha = 1, f
216232
216251
  const count = rowCounts[px];
216233
216252
  if (count > 0) {
216234
216253
  const cov = antialias ? count / 16 : count >= 8 ? 1 : 0;
216235
- blendPixel(rgba, width2, height, px, py, color5, cov * alpha, blendMode, clipMask);
216254
+ blendPixel(rgba, width2, height, px, py, color5, cov * alpha, blendMode, clipMask, groupAlpha);
216236
216255
  }
216237
216256
  }
216238
216257
  }
@@ -216311,19 +216330,16 @@ function hasCompositingEffects(operations, includeSoftMasks = false) {
216311
216330
  return operations.some((operation) => includeSoftMasks && !!operation.value.softMask || !!operation.value.blendMode && operation.value.blendMode !== "Normal" && operation.value.blendMode !== "Compatible" || operation.kind === "group" && hasCompositingEffects(operation.value.operations, includeSoftMasks));
216312
216331
  }
216313
216332
  function needsGroupBackdrop(group) {
216314
- return group.isolated === false && !!group.softMask && hasCompositingEffects(group.operations, true);
216333
+ return group.isolated === false && hasCompositingEffects(group.operations, true);
216315
216334
  }
216316
- function renderDisplayListToBitmap(displayList, options = {}) {
216317
- const baseScale = options.scale ?? (options.dpi ? options.dpi / 72 : 1.5);
216318
- const scaleX = options.dpiX !== void 0 ? options.dpiX / 72 : baseScale;
216319
- const scaleY = options.dpiY !== void 0 ? options.dpiY / 72 : baseScale;
216320
- const scale2 = scaleX;
216335
+ function renderDisplayListLayer(displayList, options, scale2, backdrop) {
216321
216336
  const [originX, originY] = displayList.origin ?? [0, 0];
216322
216337
  const pageTop = originY + displayList.height;
216323
216338
  const toScreen = (x, y) => [(x - originX) * scale2, (pageTop - y) * scale2];
216324
216339
  const width2 = Math.max(1, Math.round(displayList.width * scale2));
216325
216340
  const height = Math.max(1, Math.round(displayList.height * scale2));
216326
- const rgba = new Uint8Array(width2 * height * 4);
216341
+ const rgba = backdrop ? backdrop.slice() : new Uint8Array(width2 * height * 4);
216342
+ const groupAlpha = backdrop ? new Float32Array(width2 * height) : void 0;
216327
216343
  const deferBackground = !options.transparent && hasCompositingEffects(paintOperations(displayList));
216328
216344
  const transparent = options.transparent || deferBackground;
216329
216345
  const bg = options.background ?? { r: 1, g: 1, b: 1 };
@@ -216331,7 +216347,7 @@ function renderDisplayListToBitmap(displayList, options = {}) {
216331
216347
  const bgG = transparent ? 0 : Math.round(bg.g * 255);
216332
216348
  const bgB = transparent ? 0 : Math.round(bg.b * 255);
216333
216349
  const bgA = transparent ? 0 : 255;
216334
- for (let i = 0; i < width2 * height; i++) {
216350
+ for (let i = 0; !backdrop && i < width2 * height; i++) {
216335
216351
  rgba[i * 4] = bgR;
216336
216352
  rgba[i * 4 + 1] = bgG;
216337
216353
  rgba[i * 4 + 2] = bgB;
@@ -216349,20 +216365,12 @@ function renderDisplayListToBitmap(displayList, options = {}) {
216349
216365
  let operation = original.kind === "glyph" ? { kind: "path", value: glyphPaint(original.value) } : original;
216350
216366
  if (operation.kind === "group") {
216351
216367
  const group = operation.value;
216352
- let operations = group.operations;
216353
- if (needsGroupBackdrop(group)) {
216354
- operations = [{ kind: "image", value: {
216355
- name: "GroupBackdrop",
216356
- width: width2,
216357
- height,
216358
- decodedRgba: rgba.slice(),
216359
- matrix: [width2 / scale2, 0, 0, height / scale2, originX, pageTop - height / scale2],
216360
- colorSpace: "DeviceRGB",
216361
- bitsPerComponent: 8,
216362
- ...group.bboxClip ? { clipPaths: [group.bboxClip] } : {}
216363
- } }, ...operations];
216364
- }
216365
- const bitmap = renderDisplayListToBitmap({ ...displayList, rotation: 0, operations }, { ...options, scale: scale2, dpiX: void 0, dpiY: void 0, cropRect: void 0, useCropBox: false, transparent: true });
216368
+ const bitmap = renderDisplayListLayer(
216369
+ { ...displayList, operations: group.operations },
216370
+ { ...options, transparent: true },
216371
+ scale2,
216372
+ needsGroupBackdrop(group) ? rgba : void 0
216373
+ );
216366
216374
  for (let i = 3; i < bitmap.data.length; i += 4) bitmap.data[i] = Math.round(bitmap.data[i] * group.alpha);
216367
216375
  operation = { kind: "image", value: {
216368
216376
  name: "TransparencyGroup",
@@ -216432,7 +216440,7 @@ function renderDisplayListToBitmap(displayList, options = {}) {
216432
216440
  if (path2.fillColor) {
216433
216441
  const edges2 = pathsToEdges(segmentsToScreenPaths(path2.segments, displayList.height, scale2, toScreen), true);
216434
216442
  const clipScreen = path2.clipRect ? [(path2.clipRect[0] - originX) * scale2, (pageTop - path2.clipRect[3]) * scale2, (path2.clipRect[2] - originX) * scale2, (pageTop - path2.clipRect[1]) * scale2] : void 0;
216435
- fillEdgesScanline4x4(rgba, width2, height, edges2, path2.fillColor, path2.fillAlpha ?? 1, path2.fillRule ?? "nonzero", clipScreen, original.kind === "glyph" ? aaTxt : aaVec, path2.blendMode, clipMask);
216443
+ fillEdgesScanline4x4(rgba, width2, height, edges2, path2.fillColor, path2.fillAlpha ?? 1, path2.fillRule ?? "nonzero", clipScreen, original.kind === "glyph" ? aaTxt : aaVec, path2.blendMode, clipMask, groupAlpha);
216436
216444
  }
216437
216445
  if (path2.strokeColor) {
216438
216446
  const rawSw = path2.strokeWidth * scale2 * (path2.strokeMatrix ? Math.hypot(path2.strokeMatrix[0], path2.strokeMatrix[1]) : 1);
@@ -216450,7 +216458,8 @@ function renderDisplayListToBitmap(displayList, options = {}) {
216450
216458
  clipScreen,
216451
216459
  original.kind === "glyph" ? aaTxt : aaVec,
216452
216460
  path2.blendMode,
216453
- clipMask
216461
+ clipMask,
216462
+ groupAlpha
216454
216463
  );
216455
216464
  }
216456
216465
  } else if (operation.kind === "image") {
@@ -216514,12 +216523,31 @@ function renderDisplayListToBitmap(displayList, options = {}) {
216514
216523
  },
216515
216524
  sample2[3] / 255,
216516
216525
  img.blendMode,
216517
- clipMask
216526
+ clipMask,
216527
+ groupAlpha
216518
216528
  );
216519
216529
  }
216520
216530
  }
216521
216531
  }
216522
216532
  }
216533
+ if (backdrop && groupAlpha) {
216534
+ for (let i = 0; i < rgba.length; i += 4) {
216535
+ const alpha = groupAlpha[i / 4];
216536
+ if (alpha === 0) {
216537
+ rgba.fill(0, i, i + 4);
216538
+ continue;
216539
+ }
216540
+ const factor2 = backdrop[i + 3] / 255 * (1 / alpha - 1);
216541
+ for (let channel = 0; channel < 3; channel++) {
216542
+ const color5 = rgba[i + channel];
216543
+ rgba[i + channel] = Math.max(0, Math.min(
216544
+ 255,
216545
+ Math.round(color5 + (color5 - backdrop[i + channel]) * factor2)
216546
+ ));
216547
+ }
216548
+ rgba[i + 3] = Math.round(alpha * 255);
216549
+ }
216550
+ }
216523
216551
  if (deferBackground) {
216524
216552
  for (let i = 0; i < rgba.length; i += 4) {
216525
216553
  const alpha = rgba[i + 3] / 255;
@@ -216529,7 +216557,14 @@ function renderDisplayListToBitmap(displayList, options = {}) {
216529
216557
  rgba[i + 3] = 255;
216530
216558
  }
216531
216559
  }
216532
- let result2 = { width: width2, height, data: rgba };
216560
+ return { width: width2, height, data: rgba };
216561
+ }
216562
+ function renderDisplayListToBitmap(displayList, options = {}) {
216563
+ const baseScale = options.scale ?? (options.dpi ? options.dpi / 72 : 1.5);
216564
+ const scaleX = options.dpiX !== void 0 ? options.dpiX / 72 : baseScale;
216565
+ const scaleY = options.dpiY !== void 0 ? options.dpiY / 72 : baseScale;
216566
+ let result2 = renderDisplayListLayer(displayList, options, scaleX);
216567
+ const { width: width2, height, data: rgba } = result2;
216533
216568
  if (Math.abs(scaleX - scaleY) > 1e-6) {
216534
216569
  const targetW = Math.max(1, Math.round(displayList.width * scaleX));
216535
216570
  const targetH = Math.max(1, Math.round(displayList.height * scaleY));