@poe-platform/safe-bash 0.1.780 → 0.1.782

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.
@@ -26566,7 +26566,7 @@ function cosString(value, span) {
26566
26566
  if (typeof value === "string") {
26567
26567
  let needsUtf16 = false;
26568
26568
  for (let i = 0; i < value.length; i++) {
26569
- if (value.charCodeAt(i) > 255) {
26569
+ if (!PDF_DOC_ENCODING_REVERSE.has(value.charCodeAt(i))) {
26570
26570
  needsUtf16 = true;
26571
26571
  break;
26572
26572
  }
@@ -26584,7 +26584,7 @@ function cosString(value, span) {
26584
26584
  }
26585
26585
  const bytes = new Uint8Array(value.length);
26586
26586
  for (let i = 0; i < value.length; i++) {
26587
- bytes[i] = value.charCodeAt(i) & 255;
26587
+ bytes[i] = PDF_DOC_ENCODING_REVERSE.get(value.charCodeAt(i));
26588
26588
  }
26589
26589
  return { kind: "string", format: "literal", bytes, span };
26590
26590
  }
@@ -26731,6 +26731,9 @@ var PDF_DOC_ENCODING_MAP = {
26731
26731
  160: 8364,
26732
26732
  173: 65533
26733
26733
  };
26734
+ var PDF_DOC_ENCODING_REVERSE = new Map(
26735
+ Array.from({ length: 256 }, (_, byte) => [PDF_DOC_ENCODING_MAP[byte] ?? byte, byte])
26736
+ );
26734
26737
  function decodeUtf16UnitsWithSurrogateCheck(units) {
26735
26738
  let out = "";
26736
26739
  for (let i = 0; i < units.length; i++) {
@@ -27022,6 +27025,7 @@ var CosByteLexer = class {
27022
27025
  const start = this.pos;
27023
27026
  this.pos++;
27024
27027
  let depth = 1;
27028
+ let recovery;
27025
27029
  const out = [];
27026
27030
  while (this.pos < this.end && depth > 0) {
27027
27031
  const b = this.bytes[this.pos++];
@@ -27056,7 +27060,15 @@ var CosByteLexer = class {
27056
27060
  out.push(b);
27057
27061
  } else if (b === 41) {
27058
27062
  depth--;
27059
- if (depth > 0) out.push(b);
27063
+ if (depth > 0) {
27064
+ const next = this.bytes[this.pos];
27065
+ const afterLine = next === 13 && this.bytes[this.pos + 1] === 10 ? this.pos + 2 : this.pos + 1;
27066
+ const delimiter = this.bytes[afterLine];
27067
+ if (!recovery && this.pos + 2 < this.end && (next === 10 || next === 13) && (delimiter === 47 || delimiter === 62)) {
27068
+ recovery = { offset: this.pos, length: out.length };
27069
+ }
27070
+ out.push(b);
27071
+ }
27060
27072
  } else if (b === 13) {
27061
27073
  if (this.pos < this.end && this.bytes[this.pos] === 10) this.pos++;
27062
27074
  out.push(10);
@@ -27067,6 +27079,10 @@ var CosByteLexer = class {
27067
27079
  throw new PdfError("E_LIMIT", "PDF literal string exceeds maximum byte length");
27068
27080
  }
27069
27081
  }
27082
+ if (depth > 0 && recovery) {
27083
+ this.pos = recovery.offset;
27084
+ out.length = recovery.length;
27085
+ }
27070
27086
  return {
27071
27087
  kind: "string",
27072
27088
  bytes: Uint8Array.from(out),
@@ -38437,6 +38453,7 @@ function evaluateContentStreamToDisplayList(params) {
38437
38453
  };
38438
38454
  const initialState = {
38439
38455
  ctm: [1, 0, 0, 1, 0, 0],
38456
+ initialCtm: [1, 0, 0, 1, 0, 0],
38440
38457
  strokeColor: { r: 0, g: 0, b: 0 },
38441
38458
  fillColor: { r: 0, g: 0, b: 0 },
38442
38459
  strokeAlpha: 1,
@@ -38734,6 +38751,116 @@ function evaluateContentStreamToDisplayList(params) {
38734
38751
  ] }], void 0, void 0, resources, activeFonts, depth);
38735
38752
  stateStack.pop();
38736
38753
  };
38754
+ const paintPattern = (segments, fillRule, resources, activeFonts, depth, mcid, actualText) => {
38755
+ const st = curState(), doc = params.cosDoc;
38756
+ if (!st.fillPatternName || !doc || !resources) return false;
38757
+ if (depth >= 8) throw new PdfError("E_LIMIT", "Pattern nesting exceeds the form depth limit");
38758
+ const patterns = doc.resolveDict(dictGet(resources, "Pattern"));
38759
+ const pattern = patterns && doc.resolve(dictGet(patterns, st.fillPatternName));
38760
+ const dict = pattern?.kind === "stream" ? pattern.dict : pattern?.kind === "dict" ? pattern : void 0;
38761
+ if (!dict) return false;
38762
+ const nums = (key, fallback) => {
38763
+ const array = doc.resolveArray(dictGet(dict, key));
38764
+ return array ? array.items.map((item, i) => {
38765
+ const value = doc.resolve(item);
38766
+ return value?.kind === "number" ? value.value : fallback[i] ?? 0;
38767
+ }) : fallback;
38768
+ };
38769
+ let x0 = Infinity, y0 = Infinity, x1 = -Infinity, y1 = -Infinity;
38770
+ const include = (x, y) => {
38771
+ x0 = Math.min(x0, x);
38772
+ y0 = Math.min(y0, y);
38773
+ x1 = Math.max(x1, x);
38774
+ y1 = Math.max(y1, y);
38775
+ };
38776
+ for (const segment of segments) {
38777
+ if (segment.kind === "close") continue;
38778
+ include(segment.x, segment.y);
38779
+ if (segment.kind === "cubic") {
38780
+ include(segment.x1, segment.y1);
38781
+ include(segment.x2, segment.y2);
38782
+ }
38783
+ if (segment.kind === "rect") include(segment.x + segment.width, segment.y + segment.height);
38784
+ }
38785
+ const [originX, originY] = params.origin ?? [0, 0];
38786
+ const clip = st.clipRect ?? [originX, originY, originX + params.width, originY + params.height];
38787
+ const bounds = [Math.max(x0, clip[0]), Math.max(y0, clip[1]), Math.min(x1, clip[2]), Math.min(y1, clip[3])];
38788
+ if (!(bounds[2] > bounds[0] && bounds[3] > bounds[1])) return true;
38789
+ const matrix = multiplyMatrices(nums("Matrix", [1, 0, 0, 1, 0, 0]), st.initialCtm);
38790
+ const type = doc.resolve(dictGet(dict, "PatternType"));
38791
+ stateStack.push({ ...st, clipRect: bounds, clipPaths: [...st.clipPaths ?? [], { segments, fillRule }] });
38792
+ try {
38793
+ if (type?.kind === "number" && type.value === 2) {
38794
+ const shading = doc.resolve(dictGet(dict, "Shading"));
38795
+ const shadingDict = shading?.kind === "stream" ? shading.dict : shading?.kind === "dict" ? shading : void 0;
38796
+ if (!shadingDict) return false;
38797
+ const image = renderShadingDictToImage(
38798
+ doc,
38799
+ shadingDict,
38800
+ matrix,
38801
+ bounds,
38802
+ st.fillAlpha,
38803
+ "PatternShading_" + st.fillPatternName,
38804
+ bounds,
38805
+ shading?.kind === "stream" ? shading : void 0,
38806
+ st.blendMode
38807
+ );
38808
+ if (image) emit({ kind: "image", value: image });
38809
+ return !!image;
38810
+ }
38811
+ if (pattern?.kind !== "stream") return false;
38812
+ const xStepNode = doc.resolve(dictGet(dict, "XStep"));
38813
+ const yStepNode = doc.resolve(dictGet(dict, "YStep"));
38814
+ const xStep = xStepNode?.kind === "number" ? Math.abs(xStepNode.value) : 0;
38815
+ const yStep = yStepNode?.kind === "number" ? Math.abs(yStepNode.value) : 0;
38816
+ const determinant = matrix[0] * matrix[3] - matrix[1] * matrix[2];
38817
+ if (!xStep || !yStep || !determinant) return true;
38818
+ const inverse = [
38819
+ matrix[3] / determinant,
38820
+ -matrix[1] / determinant,
38821
+ -matrix[2] / determinant,
38822
+ matrix[0] / determinant,
38823
+ (matrix[2] * matrix[5] - matrix[3] * matrix[4]) / determinant,
38824
+ (matrix[1] * matrix[4] - matrix[0] * matrix[5]) / determinant
38825
+ ];
38826
+ const corners = [[bounds[0], bounds[1]], [bounds[2], bounds[1]], [bounds[2], bounds[3]], [bounds[0], bounds[3]]].map(([x, y]) => transformPoint(inverse, x, y));
38827
+ const box = nums("BBox", [0, 0, xStep, yStep]);
38828
+ const ix0 = Math.floor((Math.min(...corners.map((p) => p[0])) - box[2]) / xStep) + 1;
38829
+ const ix1 = Math.ceil((Math.max(...corners.map((p) => p[0])) - box[0]) / xStep) - 1;
38830
+ const iy0 = Math.floor((Math.min(...corners.map((p) => p[1])) - box[3]) / yStep) + 1;
38831
+ const iy1 = Math.ceil((Math.max(...corners.map((p) => p[1])) - box[1]) / yStep) - 1;
38832
+ if ((ix1 - ix0 + 1) * (iy1 - iy0 + 1) > 2e4) throw new PdfError("E_LIMIT", "Pattern tile count exceeds 20000");
38833
+ const nodes = parseContentStream(doc.decodeStream(pattern));
38834
+ const patternResources = doc.resolveDict(dictGet(dict, "Resources")) ?? resources;
38835
+ const patternFonts = new Map(activeFonts);
38836
+ for (const [key, font] of resolvePageFonts(doc, patternResources)) patternFonts.set(key, font);
38837
+ for (let iy = iy0; iy <= iy1; iy++) {
38838
+ for (let ix = ix0; ix <= ix1; ix++) {
38839
+ const tileCtm = multiplyMatrices([1, 0, 0, 1, ix * xStep, iy * yStep], matrix);
38840
+ 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));
38841
+ const tileClip = [
38842
+ ...points.map(([x, y], i) => ({ kind: i === 0 ? "move" : "line", x, y })),
38843
+ { kind: "close" }
38844
+ ];
38845
+ stateStack.push({
38846
+ ...curState(),
38847
+ fillPatternName: void 0,
38848
+ ctm: tileCtm,
38849
+ initialCtm: tileCtm,
38850
+ clipPaths: [...curState().clipPaths ?? [], tileClip]
38851
+ });
38852
+ try {
38853
+ walkNodes(nodes, mcid, actualText, patternResources, patternFonts, depth + 1);
38854
+ } finally {
38855
+ stateStack.pop();
38856
+ }
38857
+ }
38858
+ }
38859
+ return true;
38860
+ } finally {
38861
+ stateStack.pop();
38862
+ }
38863
+ };
38737
38864
  const paintForm = (form, activeResources, activeFonts, depth, mcid, actualText, maskGroup = false) => {
38738
38865
  const st = curState();
38739
38866
  const group = params.cosDoc.resolveDict(dictGet(form.dict, "Group"));
@@ -38792,7 +38919,7 @@ function evaluateContentStreamToDisplayList(params) {
38792
38919
  }
38793
38920
  const parentOperations = capturedOperations;
38794
38921
  const children = [];
38795
- const nextState = { ...st, ctm: nextCtm };
38922
+ const nextState = { ...st, ctm: nextCtm, initialCtm: nextCtm };
38796
38923
  if (compositeGroup) {
38797
38924
  capturedOperations = children;
38798
38925
  nextState.fillAlpha = nextState.strokeAlpha = 1;
@@ -38950,136 +39077,15 @@ function evaluateContentStreamToDisplayList(params) {
38950
39077
  }
38951
39078
  const isFill = ["f", "F", "f*", "B", "B*", "b", "b*"].includes(node.paint);
38952
39079
  const isStroke = ["S", "s", "B", "B*", "b", "b*"].includes(node.paint);
38953
- let evaluatedFillPattern = false;
38954
- if (isFill && st.fillPatternName && params.cosDoc && activeResources && depth < 6) {
38955
- const patMap = params.cosDoc.resolveDict(dictGet(activeResources, "Pattern"));
38956
- const patNode = patMap ? params.cosDoc.resolve(dictGet(patMap, st.fillPatternName)) : void 0;
38957
- const patDict = patNode?.kind === "stream" ? patNode.dict : patNode?.kind === "dict" ? patNode : void 0;
38958
- const patTypeNode = patDict && params.cosDoc ? params.cosDoc.resolve(dictGet(patDict, "PatternType")) : void 0;
38959
- const patType = patTypeNode?.kind === "number" ? patTypeNode.value : patNode?.kind === "stream" ? 1 : 0;
38960
- if (patDict && patType === 2 && params.cosDoc) {
38961
- let pMinX = Infinity, pMinY = Infinity, pMaxX = -Infinity, pMaxY = -Infinity;
38962
- for (const s of transformedSegments) {
38963
- if (s.kind === "move" || s.kind === "line") {
38964
- pMinX = Math.min(pMinX, s.x);
38965
- pMinY = Math.min(pMinY, s.y);
38966
- pMaxX = Math.max(pMaxX, s.x);
38967
- pMaxY = Math.max(pMaxY, s.y);
38968
- } else if (s.kind === "cubic") {
38969
- pMinX = Math.min(pMinX, s.x1, s.x2, s.x);
38970
- pMinY = Math.min(pMinY, s.y1, s.y2, s.y);
38971
- pMaxX = Math.max(pMaxX, s.x1, s.x2, s.x);
38972
- pMaxY = Math.max(pMaxY, s.y1, s.y2, s.y);
38973
- } else if (s.kind === "rect") {
38974
- pMinX = Math.min(pMinX, s.x);
38975
- pMinY = Math.min(pMinY, s.y);
38976
- pMaxX = Math.max(pMaxX, s.x + s.width);
38977
- pMaxY = Math.max(pMaxY, s.y + s.height);
38978
- }
38979
- }
38980
- if (Number.isFinite(pMinX) && Number.isFinite(pMinY) && pMaxX > pMinX && pMaxY > pMinY) {
38981
- const shading = params.cosDoc.resolve(dictGet(patDict, "Shading"));
38982
- const shDict = shading?.kind === "stream" ? shading.dict : shading?.kind === "dict" ? shading : void 0;
38983
- if (shDict) {
38984
- let patMatrix = [1, 0, 0, 1, 0, 0];
38985
- const pmArr = params.cosDoc.resolveArray(dictGet(patDict, "Matrix"));
38986
- if (pmArr && pmArr.items.length >= 6) {
38987
- const mn = (idx, fb = 0) => {
38988
- const r = params.cosDoc.resolve(pmArr.items[idx]);
38989
- return r?.kind === "number" ? r.value : fb;
38990
- };
38991
- patMatrix = [mn(0, 1), mn(1, 0), mn(2, 0), mn(3, 1), mn(4, 0), mn(5, 0)];
38992
- }
38993
- const patClip = st.clipRect ? [
38994
- Math.max(st.clipRect[0], pMinX),
38995
- Math.max(st.clipRect[1], pMinY),
38996
- Math.min(st.clipRect[2], pMaxX),
38997
- Math.min(st.clipRect[3], pMaxY)
38998
- ] : [pMinX, pMinY, pMaxX, pMaxY];
38999
- const shImg = renderShadingDictToImage(
39000
- params.cosDoc,
39001
- shDict,
39002
- patMatrix,
39003
- patClip,
39004
- st.fillAlpha,
39005
- "PatternShading_" + st.fillPatternName,
39006
- patClip,
39007
- shading?.kind === "stream" ? shading : void 0,
39008
- st.blendMode
39009
- );
39010
- if (shImg) {
39011
- emit({ kind: "image", value: shImg });
39012
- evaluatedFillPattern = true;
39013
- }
39014
- }
39015
- }
39016
- } else if (patNode?.kind === "stream") {
39017
- let pMinX = Infinity, pMinY = Infinity, pMaxX = -Infinity, pMaxY = -Infinity;
39018
- for (const s of transformedSegments) {
39019
- if (s.kind === "move" || s.kind === "line") {
39020
- pMinX = Math.min(pMinX, s.x);
39021
- pMinY = Math.min(pMinY, s.y);
39022
- pMaxX = Math.max(pMaxX, s.x);
39023
- pMaxY = Math.max(pMaxY, s.y);
39024
- } else if (s.kind === "cubic") {
39025
- pMinX = Math.min(pMinX, s.x1, s.x2, s.x);
39026
- pMinY = Math.min(pMinY, s.y1, s.y2, s.y);
39027
- pMaxX = Math.max(pMaxX, s.x1, s.x2, s.x);
39028
- pMaxY = Math.max(pMaxY, s.y1, s.y2, s.y);
39029
- } else if (s.kind === "rect") {
39030
- pMinX = Math.min(pMinX, s.x);
39031
- pMinY = Math.min(pMinY, s.y);
39032
- pMaxX = Math.max(pMaxX, s.x + s.width);
39033
- pMaxY = Math.max(pMaxY, s.y + s.height);
39034
- }
39035
- }
39036
- if (Number.isFinite(pMinX) && Number.isFinite(pMinY) && pMaxX > pMinX && pMaxY > pMinY) {
39037
- const xsNode = params.cosDoc.resolve(dictGet(patNode.dict, "XStep"));
39038
- const ysNode = params.cosDoc.resolve(dictGet(patNode.dict, "YStep"));
39039
- const xStep = xsNode?.kind === "number" && Math.abs(xsNode.value) > 1e-3 ? Math.abs(xsNode.value) : 40;
39040
- const yStep = ysNode?.kind === "number" && Math.abs(ysNode.value) > 1e-3 ? Math.abs(ysNode.value) : 40;
39041
- let patMatrix = [1, 0, 0, 1, 0, 0];
39042
- const pmArr = params.cosDoc.resolveArray(dictGet(patNode.dict, "Matrix"));
39043
- if (pmArr && pmArr.items.length >= 6) {
39044
- const mn = (idx, fb = 0) => {
39045
- const r = params.cosDoc.resolve(pmArr.items[idx]);
39046
- return r?.kind === "number" ? r.value : fb;
39047
- };
39048
- patMatrix = [mn(0, 1), mn(1, 0), mn(2, 0), mn(3, 1), mn(4, 0), mn(5, 0)];
39049
- }
39050
- const tileClip = st.clipRect ? [
39051
- Math.max(st.clipRect[0], pMinX),
39052
- Math.max(st.clipRect[1], pMinY),
39053
- Math.min(st.clipRect[2], pMaxX),
39054
- Math.min(st.clipRect[3], pMaxY)
39055
- ] : [pMinX, pMinY, pMaxX, pMaxY];
39056
- const patNodes = parseContentStream(params.cosDoc.decodeStream(patNode));
39057
- const patResDict = params.cosDoc.resolveDict(dictGet(patNode.dict, "Resources")) ?? activeResources;
39058
- const patFonts = new Map(activeFonts);
39059
- for (const [fk, fv] of resolvePageFonts(params.cosDoc, patResDict).entries()) {
39060
- patFonts.set(fk, fv);
39061
- }
39062
- const ixStart = Math.floor(pMinX / xStep);
39063
- const ixEnd = Math.min(ixStart + 8, Math.ceil(pMaxX / xStep) - 1);
39064
- const iyStart = Math.floor(pMinY / yStep);
39065
- const iyEnd = Math.min(iyStart + 8, Math.ceil(pMaxY / yStep) - 1);
39066
- for (let iy = iyStart; iy <= iyEnd; iy++) {
39067
- for (let ix = ixStart; ix <= ixEnd; ix++) {
39068
- const tileCtm = multiplyMatrices([1, 0, 0, 1, ix * xStep, iy * yStep], patMatrix);
39069
- stateStack.push({
39070
- ...st,
39071
- fillPatternName: void 0,
39072
- ctm: tileCtm,
39073
- clipRect: tileClip
39074
- });
39075
- walkNodes(patNodes, mcid, actualText, patResDict, patFonts, depth + 1);
39076
- if (stateStack.length > 1) stateStack.pop();
39077
- }
39078
- }
39079
- evaluatedFillPattern = true;
39080
- }
39081
- }
39082
- }
39080
+ const evaluatedFillPattern = isFill && paintPattern(
39081
+ transformedSegments,
39082
+ node.paint.includes("*") ? "evenodd" : "nonzero",
39083
+ activeResources,
39084
+ activeFonts,
39085
+ depth,
39086
+ mcid,
39087
+ actualText
39088
+ );
39083
39089
  if (evaluatedFillPattern && !isStroke) {
39084
39090
  applyClip();
39085
39091
  break;
@@ -39280,10 +39286,19 @@ function evaluateContentStreamToDisplayList(params) {
39280
39286
  if (st.textRenderMode >= 4 && st.textRenderMode <= 7) pendingTextClip.push(...transformedGlyphSegs);
39281
39287
  const isFillGlyph = st.textRenderMode === 0 || st.textRenderMode === 2 || st.textRenderMode === 4 || st.textRenderMode === 6;
39282
39288
  const isStrokeGlyph = st.textRenderMode === 1 || st.textRenderMode === 2 || st.textRenderMode === 5 || st.textRenderMode === 6;
39289
+ const patterned = isFillGlyph && paintPattern(
39290
+ transformedGlyphSegs,
39291
+ "nonzero",
39292
+ activeResources,
39293
+ activeFonts,
39294
+ depth,
39295
+ mcid,
39296
+ actualText
39297
+ );
39283
39298
  const paint = {
39284
39299
  segments: transformedGlyphSegs,
39285
- fillColor: isFillGlyph ? st.fillColor : void 0,
39286
- fillAlpha: isFillGlyph ? st.fillAlpha : void 0,
39300
+ fillColor: isFillGlyph && !patterned ? st.fillColor : void 0,
39301
+ fillAlpha: isFillGlyph && !patterned ? st.fillAlpha : void 0,
39287
39302
  strokeColor: isStrokeGlyph ? st.strokeColor : void 0,
39288
39303
  strokeAlpha: isStrokeGlyph ? st.strokeAlpha : void 0,
39289
39304
  strokeWidth: isStrokeGlyph ? st.strokeWidth : 0,
@@ -42637,10 +42652,14 @@ function computePdfBlendRgb(cbR, cbG, cbB, csR, csG, csB, mode) {
42637
42652
  blendChannelSeparable(cbB, csB, mode)
42638
42653
  ];
42639
42654
  }
42640
- function blendPixel(rgba, width, height, px, py, color, alpha, blendMode, clipMask) {
42655
+ function blendPixel(rgba, width, height, px, py, color, alpha, blendMode, clipMask, groupAlpha) {
42641
42656
  if (px < 0 || py < 0 || px >= width || py >= height || alpha <= 0) return;
42642
42657
  const a = Math.min(1, Math.max(0, alpha)) * (clipMask ? clipMask[(py * width + px) * 4 + 3] / 255 : 1);
42643
42658
  const idx = (py * width + px) * 4;
42659
+ if (groupAlpha) {
42660
+ const pixel = py * width + px;
42661
+ groupAlpha[pixel] = a + groupAlpha[pixel] * (1 - a);
42662
+ }
42644
42663
  const csR = Math.min(1, Math.max(0, color.r));
42645
42664
  const csG = Math.min(1, Math.max(0, color.g));
42646
42665
  const csB = Math.min(1, Math.max(0, color.b));
@@ -42772,7 +42791,7 @@ function pathsToEdges(paths, closeSubpaths = false) {
42772
42791
  }
42773
42792
  return edges;
42774
42793
  }
42775
- function fillEdgesScanline4x4(rgba, width, height, edges, color, alpha = 1, fillRule = "nonzero", clipScreen, antialias = true, blendMode, clipMask) {
42794
+ function fillEdgesScanline4x4(rgba, width, height, edges, color, alpha = 1, fillRule = "nonzero", clipScreen, antialias = true, blendMode, clipMask, groupAlpha) {
42776
42795
  if (edges.length === 0) return;
42777
42796
  let minY = Infinity;
42778
42797
  let maxY = -Infinity;
@@ -42838,7 +42857,7 @@ function fillEdgesScanline4x4(rgba, width, height, edges, color, alpha = 1, fill
42838
42857
  const count = rowCounts[px];
42839
42858
  if (count > 0) {
42840
42859
  const cov = antialias ? count / 16 : count >= 8 ? 1 : 0;
42841
- blendPixel(rgba, width, height, px, py, color, cov * alpha, blendMode, clipMask);
42860
+ blendPixel(rgba, width, height, px, py, color, cov * alpha, blendMode, clipMask, groupAlpha);
42842
42861
  }
42843
42862
  }
42844
42863
  }
@@ -42917,19 +42936,16 @@ function hasCompositingEffects(operations, includeSoftMasks = false) {
42917
42936
  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));
42918
42937
  }
42919
42938
  function needsGroupBackdrop(group) {
42920
- return group.isolated === false && !!group.softMask && hasCompositingEffects(group.operations, true);
42939
+ return group.isolated === false && hasCompositingEffects(group.operations, true);
42921
42940
  }
42922
- function renderDisplayListToBitmap(displayList, options = {}) {
42923
- const baseScale = options.scale ?? (options.dpi ? options.dpi / 72 : 1.5);
42924
- const scaleX = options.dpiX !== void 0 ? options.dpiX / 72 : baseScale;
42925
- const scaleY = options.dpiY !== void 0 ? options.dpiY / 72 : baseScale;
42926
- const scale = scaleX;
42941
+ function renderDisplayListLayer(displayList, options, scale, backdrop) {
42927
42942
  const [originX, originY] = displayList.origin ?? [0, 0];
42928
42943
  const pageTop = originY + displayList.height;
42929
42944
  const toScreen = (x, y) => [(x - originX) * scale, (pageTop - y) * scale];
42930
42945
  const width = Math.max(1, Math.round(displayList.width * scale));
42931
42946
  const height = Math.max(1, Math.round(displayList.height * scale));
42932
- const rgba = new Uint8Array(width * height * 4);
42947
+ const rgba = backdrop ? backdrop.slice() : new Uint8Array(width * height * 4);
42948
+ const groupAlpha = backdrop ? new Float32Array(width * height) : void 0;
42933
42949
  const deferBackground = !options.transparent && hasCompositingEffects(paintOperations(displayList));
42934
42950
  const transparent = options.transparent || deferBackground;
42935
42951
  const bg = options.background ?? { r: 1, g: 1, b: 1 };
@@ -42937,7 +42953,7 @@ function renderDisplayListToBitmap(displayList, options = {}) {
42937
42953
  const bgG = transparent ? 0 : Math.round(bg.g * 255);
42938
42954
  const bgB = transparent ? 0 : Math.round(bg.b * 255);
42939
42955
  const bgA = transparent ? 0 : 255;
42940
- for (let i = 0; i < width * height; i++) {
42956
+ for (let i = 0; !backdrop && i < width * height; i++) {
42941
42957
  rgba[i * 4] = bgR;
42942
42958
  rgba[i * 4 + 1] = bgG;
42943
42959
  rgba[i * 4 + 2] = bgB;
@@ -42955,20 +42971,12 @@ function renderDisplayListToBitmap(displayList, options = {}) {
42955
42971
  let operation = original.kind === "glyph" ? { kind: "path", value: glyphPaint(original.value) } : original;
42956
42972
  if (operation.kind === "group") {
42957
42973
  const group = operation.value;
42958
- let operations = group.operations;
42959
- if (needsGroupBackdrop(group)) {
42960
- operations = [{ kind: "image", value: {
42961
- name: "GroupBackdrop",
42962
- width,
42963
- height,
42964
- decodedRgba: rgba.slice(),
42965
- matrix: [width / scale, 0, 0, height / scale, originX, pageTop - height / scale],
42966
- colorSpace: "DeviceRGB",
42967
- bitsPerComponent: 8,
42968
- ...group.bboxClip ? { clipPaths: [group.bboxClip] } : {}
42969
- } }, ...operations];
42970
- }
42971
- const bitmap = renderDisplayListToBitmap({ ...displayList, rotation: 0, operations }, { ...options, scale, dpiX: void 0, dpiY: void 0, cropRect: void 0, useCropBox: false, transparent: true });
42974
+ const bitmap = renderDisplayListLayer(
42975
+ { ...displayList, operations: group.operations },
42976
+ { ...options, transparent: true },
42977
+ scale,
42978
+ needsGroupBackdrop(group) ? rgba : void 0
42979
+ );
42972
42980
  for (let i = 3; i < bitmap.data.length; i += 4) bitmap.data[i] = Math.round(bitmap.data[i] * group.alpha);
42973
42981
  operation = { kind: "image", value: {
42974
42982
  name: "TransparencyGroup",
@@ -43038,7 +43046,7 @@ function renderDisplayListToBitmap(displayList, options = {}) {
43038
43046
  if (path.fillColor) {
43039
43047
  const edges = pathsToEdges(segmentsToScreenPaths(path.segments, displayList.height, scale, toScreen), true);
43040
43048
  const clipScreen = path.clipRect ? [(path.clipRect[0] - originX) * scale, (pageTop - path.clipRect[3]) * scale, (path.clipRect[2] - originX) * scale, (pageTop - path.clipRect[1]) * scale] : void 0;
43041
- fillEdgesScanline4x4(rgba, width, height, edges, path.fillColor, path.fillAlpha ?? 1, path.fillRule ?? "nonzero", clipScreen, original.kind === "glyph" ? aaTxt : aaVec, path.blendMode, clipMask);
43049
+ fillEdgesScanline4x4(rgba, width, height, edges, path.fillColor, path.fillAlpha ?? 1, path.fillRule ?? "nonzero", clipScreen, original.kind === "glyph" ? aaTxt : aaVec, path.blendMode, clipMask, groupAlpha);
43042
43050
  }
43043
43051
  if (path.strokeColor) {
43044
43052
  const rawSw = path.strokeWidth * scale * (path.strokeMatrix ? Math.hypot(path.strokeMatrix[0], path.strokeMatrix[1]) : 1);
@@ -43056,7 +43064,8 @@ function renderDisplayListToBitmap(displayList, options = {}) {
43056
43064
  clipScreen,
43057
43065
  original.kind === "glyph" ? aaTxt : aaVec,
43058
43066
  path.blendMode,
43059
- clipMask
43067
+ clipMask,
43068
+ groupAlpha
43060
43069
  );
43061
43070
  }
43062
43071
  } else if (operation.kind === "image") {
@@ -43120,12 +43129,31 @@ function renderDisplayListToBitmap(displayList, options = {}) {
43120
43129
  },
43121
43130
  sample[3] / 255,
43122
43131
  img.blendMode,
43123
- clipMask
43132
+ clipMask,
43133
+ groupAlpha
43124
43134
  );
43125
43135
  }
43126
43136
  }
43127
43137
  }
43128
43138
  }
43139
+ if (backdrop && groupAlpha) {
43140
+ for (let i = 0; i < rgba.length; i += 4) {
43141
+ const alpha = groupAlpha[i / 4];
43142
+ if (alpha === 0) {
43143
+ rgba.fill(0, i, i + 4);
43144
+ continue;
43145
+ }
43146
+ const factor = backdrop[i + 3] / 255 * (1 / alpha - 1);
43147
+ for (let channel = 0; channel < 3; channel++) {
43148
+ const color = rgba[i + channel];
43149
+ rgba[i + channel] = Math.max(0, Math.min(
43150
+ 255,
43151
+ Math.round(color + (color - backdrop[i + channel]) * factor)
43152
+ ));
43153
+ }
43154
+ rgba[i + 3] = Math.round(alpha * 255);
43155
+ }
43156
+ }
43129
43157
  if (deferBackground) {
43130
43158
  for (let i = 0; i < rgba.length; i += 4) {
43131
43159
  const alpha = rgba[i + 3] / 255;
@@ -43135,7 +43163,14 @@ function renderDisplayListToBitmap(displayList, options = {}) {
43135
43163
  rgba[i + 3] = 255;
43136
43164
  }
43137
43165
  }
43138
- let result = { width, height, data: rgba };
43166
+ return { width, height, data: rgba };
43167
+ }
43168
+ function renderDisplayListToBitmap(displayList, options = {}) {
43169
+ const baseScale = options.scale ?? (options.dpi ? options.dpi / 72 : 1.5);
43170
+ const scaleX = options.dpiX !== void 0 ? options.dpiX / 72 : baseScale;
43171
+ const scaleY = options.dpiY !== void 0 ? options.dpiY / 72 : baseScale;
43172
+ let result = renderDisplayListLayer(displayList, options, scaleX);
43173
+ const { width, height, data: rgba } = result;
43139
43174
  if (Math.abs(scaleX - scaleY) > 1e-6) {
43140
43175
  const targetW = Math.max(1, Math.round(displayList.width * scaleX));
43141
43176
  const targetH = Math.max(1, Math.round(displayList.height * scaleY));
@@ -11,8 +11,8 @@ import {
11
11
  readImageMetadata,
12
12
  resizeImage,
13
13
  rotateImage
14
- } from "../safe-bash/command-chunks/chunk-QLYJUVVM.js";
15
- import "../safe-bash/command-chunks/chunk-3444RZLY.js";
14
+ } from "../safe-bash/command-chunks/chunk-GBHSE6ZO.js";
15
+ import "../safe-bash/command-chunks/chunk-GZXLPWT5.js";
16
16
  import {
17
17
  init_buffer
18
18
  } from "../safe-bash/command-chunks/chunk-HX3SHTCE.js";
@@ -31,7 +31,7 @@ import {
31
31
  PdfDocument,
32
32
  decodeFlate,
33
33
  rgb
34
- } from "../safe-bash/command-chunks/chunk-3444RZLY.js";
34
+ } from "../safe-bash/command-chunks/chunk-GZXLPWT5.js";
35
35
  import {
36
36
  init_buffer
37
37
  } from "../safe-bash/command-chunks/chunk-HX3SHTCE.js";