@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.
@@ -28,8 +28,8 @@ import {
28
28
  thresholdImage,
29
29
  tintImage,
30
30
  trimImage
31
- } from "../safe-bash/command-chunks/chunk-QLYJUVVM.js";
32
- import "../safe-bash/command-chunks/chunk-3444RZLY.js";
31
+ } from "../safe-bash/command-chunks/chunk-GBHSE6ZO.js";
32
+ import "../safe-bash/command-chunks/chunk-GZXLPWT5.js";
33
33
  import {
34
34
  init_buffer
35
35
  } from "../safe-bash/command-chunks/chunk-HX3SHTCE.js";
@@ -2,11 +2,11 @@ import {
2
2
  createPandocCommand,
3
3
  createPandocCommands,
4
4
  pandocCommands
5
- } from "../safe-bash/command-chunks/chunk-ZY6PMCW5.js";
5
+ } from "../safe-bash/command-chunks/chunk-ADBFNLLK.js";
6
6
  import "../safe-bash/command-chunks/chunk-MKQVQMXO.js";
7
7
  import "../safe-bash/command-chunks/chunk-RDV7UCYZ.js";
8
- import "../safe-bash/command-chunks/chunk-QLYJUVVM.js";
9
- import "../safe-bash/command-chunks/chunk-3444RZLY.js";
8
+ import "../safe-bash/command-chunks/chunk-GBHSE6ZO.js";
9
+ import "../safe-bash/command-chunks/chunk-GZXLPWT5.js";
10
10
  import "../safe-bash/command-chunks/chunk-Y2KHC6TZ.js";
11
11
  import "../safe-bash/command-chunks/chunk-YGYOVXTO.js";
12
12
  import "../safe-bash/command-chunks/chunk-I5GLTNVH.js";
@@ -21,11 +21,11 @@ import {
21
21
  readDocument,
22
22
  resolveConversionArgs,
23
23
  writeDocument
24
- } from "../safe-bash/command-chunks/chunk-ZY6PMCW5.js";
24
+ } from "../safe-bash/command-chunks/chunk-ADBFNLLK.js";
25
25
  import "../safe-bash/command-chunks/chunk-MKQVQMXO.js";
26
26
  import "../safe-bash/command-chunks/chunk-RDV7UCYZ.js";
27
- import "../safe-bash/command-chunks/chunk-QLYJUVVM.js";
28
- import "../safe-bash/command-chunks/chunk-3444RZLY.js";
27
+ import "../safe-bash/command-chunks/chunk-GBHSE6ZO.js";
28
+ import "../safe-bash/command-chunks/chunk-GZXLPWT5.js";
29
29
  import {
30
30
  createLuaFilterCapability
31
31
  } from "../safe-bash/command-chunks/chunk-Y2KHC6TZ.js";
@@ -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),
@@ -38782,6 +38798,7 @@ function evaluateContentStreamToDisplayList(params) {
38782
38798
  };
38783
38799
  const initialState = {
38784
38800
  ctm: [1, 0, 0, 1, 0, 0],
38801
+ initialCtm: [1, 0, 0, 1, 0, 0],
38785
38802
  strokeColor: { r: 0, g: 0, b: 0 },
38786
38803
  fillColor: { r: 0, g: 0, b: 0 },
38787
38804
  strokeAlpha: 1,
@@ -39079,6 +39096,116 @@ function evaluateContentStreamToDisplayList(params) {
39079
39096
  ] }], void 0, void 0, resources, activeFonts, depth);
39080
39097
  stateStack.pop();
39081
39098
  };
39099
+ const paintPattern = (segments, fillRule, resources, activeFonts, depth, mcid, actualText) => {
39100
+ const st = curState(), doc = params.cosDoc;
39101
+ if (!st.fillPatternName || !doc || !resources) return false;
39102
+ if (depth >= 8) throw new PdfError("E_LIMIT", "Pattern nesting exceeds the form depth limit");
39103
+ const patterns = doc.resolveDict(dictGet(resources, "Pattern"));
39104
+ const pattern = patterns && doc.resolve(dictGet(patterns, st.fillPatternName));
39105
+ const dict = pattern?.kind === "stream" ? pattern.dict : pattern?.kind === "dict" ? pattern : void 0;
39106
+ if (!dict) return false;
39107
+ const nums = (key, fallback) => {
39108
+ const array = doc.resolveArray(dictGet(dict, key));
39109
+ return array ? array.items.map((item, i) => {
39110
+ const value = doc.resolve(item);
39111
+ return value?.kind === "number" ? value.value : fallback[i] ?? 0;
39112
+ }) : fallback;
39113
+ };
39114
+ let x0 = Infinity, y0 = Infinity, x1 = -Infinity, y1 = -Infinity;
39115
+ const include = (x, y) => {
39116
+ x0 = Math.min(x0, x);
39117
+ y0 = Math.min(y0, y);
39118
+ x1 = Math.max(x1, x);
39119
+ y1 = Math.max(y1, y);
39120
+ };
39121
+ for (const segment of segments) {
39122
+ if (segment.kind === "close") continue;
39123
+ include(segment.x, segment.y);
39124
+ if (segment.kind === "cubic") {
39125
+ include(segment.x1, segment.y1);
39126
+ include(segment.x2, segment.y2);
39127
+ }
39128
+ if (segment.kind === "rect") include(segment.x + segment.width, segment.y + segment.height);
39129
+ }
39130
+ const [originX, originY] = params.origin ?? [0, 0];
39131
+ const clip = st.clipRect ?? [originX, originY, originX + params.width, originY + params.height];
39132
+ const bounds = [Math.max(x0, clip[0]), Math.max(y0, clip[1]), Math.min(x1, clip[2]), Math.min(y1, clip[3])];
39133
+ if (!(bounds[2] > bounds[0] && bounds[3] > bounds[1])) return true;
39134
+ const matrix = multiplyMatrices(nums("Matrix", [1, 0, 0, 1, 0, 0]), st.initialCtm);
39135
+ const type = doc.resolve(dictGet(dict, "PatternType"));
39136
+ stateStack.push({ ...st, clipRect: bounds, clipPaths: [...st.clipPaths ?? [], { segments, fillRule }] });
39137
+ try {
39138
+ if (type?.kind === "number" && type.value === 2) {
39139
+ const shading = doc.resolve(dictGet(dict, "Shading"));
39140
+ const shadingDict = shading?.kind === "stream" ? shading.dict : shading?.kind === "dict" ? shading : void 0;
39141
+ if (!shadingDict) return false;
39142
+ const image = renderShadingDictToImage(
39143
+ doc,
39144
+ shadingDict,
39145
+ matrix,
39146
+ bounds,
39147
+ st.fillAlpha,
39148
+ "PatternShading_" + st.fillPatternName,
39149
+ bounds,
39150
+ shading?.kind === "stream" ? shading : void 0,
39151
+ st.blendMode
39152
+ );
39153
+ if (image) emit({ kind: "image", value: image });
39154
+ return !!image;
39155
+ }
39156
+ if (pattern?.kind !== "stream") return false;
39157
+ const xStepNode = doc.resolve(dictGet(dict, "XStep"));
39158
+ const yStepNode = doc.resolve(dictGet(dict, "YStep"));
39159
+ const xStep = xStepNode?.kind === "number" ? Math.abs(xStepNode.value) : 0;
39160
+ const yStep = yStepNode?.kind === "number" ? Math.abs(yStepNode.value) : 0;
39161
+ const determinant = matrix[0] * matrix[3] - matrix[1] * matrix[2];
39162
+ if (!xStep || !yStep || !determinant) return true;
39163
+ const inverse = [
39164
+ matrix[3] / determinant,
39165
+ -matrix[1] / determinant,
39166
+ -matrix[2] / determinant,
39167
+ matrix[0] / determinant,
39168
+ (matrix[2] * matrix[5] - matrix[3] * matrix[4]) / determinant,
39169
+ (matrix[1] * matrix[4] - matrix[0] * matrix[5]) / determinant
39170
+ ];
39171
+ 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));
39172
+ const box = nums("BBox", [0, 0, xStep, yStep]);
39173
+ const ix0 = Math.floor((Math.min(...corners.map((p) => p[0])) - box[2]) / xStep) + 1;
39174
+ const ix1 = Math.ceil((Math.max(...corners.map((p) => p[0])) - box[0]) / xStep) - 1;
39175
+ const iy0 = Math.floor((Math.min(...corners.map((p) => p[1])) - box[3]) / yStep) + 1;
39176
+ const iy1 = Math.ceil((Math.max(...corners.map((p) => p[1])) - box[1]) / yStep) - 1;
39177
+ if ((ix1 - ix0 + 1) * (iy1 - iy0 + 1) > 2e4) throw new PdfError("E_LIMIT", "Pattern tile count exceeds 20000");
39178
+ const nodes = parseContentStream(doc.decodeStream(pattern));
39179
+ const patternResources = doc.resolveDict(dictGet(dict, "Resources")) ?? resources;
39180
+ const patternFonts = new Map(activeFonts);
39181
+ for (const [key, font] of resolvePageFonts(doc, patternResources)) patternFonts.set(key, font);
39182
+ for (let iy = iy0; iy <= iy1; iy++) {
39183
+ for (let ix = ix0; ix <= ix1; ix++) {
39184
+ const tileCtm = multiplyMatrices([1, 0, 0, 1, ix * xStep, iy * yStep], matrix);
39185
+ 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));
39186
+ const tileClip = [
39187
+ ...points.map(([x, y], i) => ({ kind: i === 0 ? "move" : "line", x, y })),
39188
+ { kind: "close" }
39189
+ ];
39190
+ stateStack.push({
39191
+ ...curState(),
39192
+ fillPatternName: void 0,
39193
+ ctm: tileCtm,
39194
+ initialCtm: tileCtm,
39195
+ clipPaths: [...curState().clipPaths ?? [], tileClip]
39196
+ });
39197
+ try {
39198
+ walkNodes(nodes, mcid, actualText, patternResources, patternFonts, depth + 1);
39199
+ } finally {
39200
+ stateStack.pop();
39201
+ }
39202
+ }
39203
+ }
39204
+ return true;
39205
+ } finally {
39206
+ stateStack.pop();
39207
+ }
39208
+ };
39082
39209
  const paintForm = (form, activeResources, activeFonts, depth, mcid, actualText, maskGroup = false) => {
39083
39210
  const st = curState();
39084
39211
  const group = params.cosDoc.resolveDict(dictGet(form.dict, "Group"));
@@ -39137,7 +39264,7 @@ function evaluateContentStreamToDisplayList(params) {
39137
39264
  }
39138
39265
  const parentOperations = capturedOperations;
39139
39266
  const children = [];
39140
- const nextState = { ...st, ctm: nextCtm };
39267
+ const nextState = { ...st, ctm: nextCtm, initialCtm: nextCtm };
39141
39268
  if (compositeGroup) {
39142
39269
  capturedOperations = children;
39143
39270
  nextState.fillAlpha = nextState.strokeAlpha = 1;
@@ -39295,136 +39422,15 @@ function evaluateContentStreamToDisplayList(params) {
39295
39422
  }
39296
39423
  const isFill = ["f", "F", "f*", "B", "B*", "b", "b*"].includes(node.paint);
39297
39424
  const isStroke = ["S", "s", "B", "B*", "b", "b*"].includes(node.paint);
39298
- let evaluatedFillPattern = false;
39299
- if (isFill && st.fillPatternName && params.cosDoc && activeResources && depth < 6) {
39300
- const patMap = params.cosDoc.resolveDict(dictGet(activeResources, "Pattern"));
39301
- const patNode = patMap ? params.cosDoc.resolve(dictGet(patMap, st.fillPatternName)) : void 0;
39302
- const patDict = patNode?.kind === "stream" ? patNode.dict : patNode?.kind === "dict" ? patNode : void 0;
39303
- const patTypeNode = patDict && params.cosDoc ? params.cosDoc.resolve(dictGet(patDict, "PatternType")) : void 0;
39304
- const patType = patTypeNode?.kind === "number" ? patTypeNode.value : patNode?.kind === "stream" ? 1 : 0;
39305
- if (patDict && patType === 2 && params.cosDoc) {
39306
- let pMinX = Infinity, pMinY = Infinity, pMaxX = -Infinity, pMaxY = -Infinity;
39307
- for (const s of transformedSegments) {
39308
- if (s.kind === "move" || s.kind === "line") {
39309
- pMinX = Math.min(pMinX, s.x);
39310
- pMinY = Math.min(pMinY, s.y);
39311
- pMaxX = Math.max(pMaxX, s.x);
39312
- pMaxY = Math.max(pMaxY, s.y);
39313
- } else if (s.kind === "cubic") {
39314
- pMinX = Math.min(pMinX, s.x1, s.x2, s.x);
39315
- pMinY = Math.min(pMinY, s.y1, s.y2, s.y);
39316
- pMaxX = Math.max(pMaxX, s.x1, s.x2, s.x);
39317
- pMaxY = Math.max(pMaxY, s.y1, s.y2, s.y);
39318
- } else if (s.kind === "rect") {
39319
- pMinX = Math.min(pMinX, s.x);
39320
- pMinY = Math.min(pMinY, s.y);
39321
- pMaxX = Math.max(pMaxX, s.x + s.width);
39322
- pMaxY = Math.max(pMaxY, s.y + s.height);
39323
- }
39324
- }
39325
- if (Number.isFinite(pMinX) && Number.isFinite(pMinY) && pMaxX > pMinX && pMaxY > pMinY) {
39326
- const shading = params.cosDoc.resolve(dictGet(patDict, "Shading"));
39327
- const shDict = shading?.kind === "stream" ? shading.dict : shading?.kind === "dict" ? shading : void 0;
39328
- if (shDict) {
39329
- let patMatrix = [1, 0, 0, 1, 0, 0];
39330
- const pmArr = params.cosDoc.resolveArray(dictGet(patDict, "Matrix"));
39331
- if (pmArr && pmArr.items.length >= 6) {
39332
- const mn = (idx, fb = 0) => {
39333
- const r = params.cosDoc.resolve(pmArr.items[idx]);
39334
- return r?.kind === "number" ? r.value : fb;
39335
- };
39336
- patMatrix = [mn(0, 1), mn(1, 0), mn(2, 0), mn(3, 1), mn(4, 0), mn(5, 0)];
39337
- }
39338
- const patClip = st.clipRect ? [
39339
- Math.max(st.clipRect[0], pMinX),
39340
- Math.max(st.clipRect[1], pMinY),
39341
- Math.min(st.clipRect[2], pMaxX),
39342
- Math.min(st.clipRect[3], pMaxY)
39343
- ] : [pMinX, pMinY, pMaxX, pMaxY];
39344
- const shImg = renderShadingDictToImage(
39345
- params.cosDoc,
39346
- shDict,
39347
- patMatrix,
39348
- patClip,
39349
- st.fillAlpha,
39350
- "PatternShading_" + st.fillPatternName,
39351
- patClip,
39352
- shading?.kind === "stream" ? shading : void 0,
39353
- st.blendMode
39354
- );
39355
- if (shImg) {
39356
- emit({ kind: "image", value: shImg });
39357
- evaluatedFillPattern = true;
39358
- }
39359
- }
39360
- }
39361
- } else if (patNode?.kind === "stream") {
39362
- let pMinX = Infinity, pMinY = Infinity, pMaxX = -Infinity, pMaxY = -Infinity;
39363
- for (const s of transformedSegments) {
39364
- if (s.kind === "move" || s.kind === "line") {
39365
- pMinX = Math.min(pMinX, s.x);
39366
- pMinY = Math.min(pMinY, s.y);
39367
- pMaxX = Math.max(pMaxX, s.x);
39368
- pMaxY = Math.max(pMaxY, s.y);
39369
- } else if (s.kind === "cubic") {
39370
- pMinX = Math.min(pMinX, s.x1, s.x2, s.x);
39371
- pMinY = Math.min(pMinY, s.y1, s.y2, s.y);
39372
- pMaxX = Math.max(pMaxX, s.x1, s.x2, s.x);
39373
- pMaxY = Math.max(pMaxY, s.y1, s.y2, s.y);
39374
- } else if (s.kind === "rect") {
39375
- pMinX = Math.min(pMinX, s.x);
39376
- pMinY = Math.min(pMinY, s.y);
39377
- pMaxX = Math.max(pMaxX, s.x + s.width);
39378
- pMaxY = Math.max(pMaxY, s.y + s.height);
39379
- }
39380
- }
39381
- if (Number.isFinite(pMinX) && Number.isFinite(pMinY) && pMaxX > pMinX && pMaxY > pMinY) {
39382
- const xsNode = params.cosDoc.resolve(dictGet(patNode.dict, "XStep"));
39383
- const ysNode = params.cosDoc.resolve(dictGet(patNode.dict, "YStep"));
39384
- const xStep = xsNode?.kind === "number" && Math.abs(xsNode.value) > 1e-3 ? Math.abs(xsNode.value) : 40;
39385
- const yStep = ysNode?.kind === "number" && Math.abs(ysNode.value) > 1e-3 ? Math.abs(ysNode.value) : 40;
39386
- let patMatrix = [1, 0, 0, 1, 0, 0];
39387
- const pmArr = params.cosDoc.resolveArray(dictGet(patNode.dict, "Matrix"));
39388
- if (pmArr && pmArr.items.length >= 6) {
39389
- const mn = (idx, fb = 0) => {
39390
- const r = params.cosDoc.resolve(pmArr.items[idx]);
39391
- return r?.kind === "number" ? r.value : fb;
39392
- };
39393
- patMatrix = [mn(0, 1), mn(1, 0), mn(2, 0), mn(3, 1), mn(4, 0), mn(5, 0)];
39394
- }
39395
- const tileClip = st.clipRect ? [
39396
- Math.max(st.clipRect[0], pMinX),
39397
- Math.max(st.clipRect[1], pMinY),
39398
- Math.min(st.clipRect[2], pMaxX),
39399
- Math.min(st.clipRect[3], pMaxY)
39400
- ] : [pMinX, pMinY, pMaxX, pMaxY];
39401
- const patNodes = parseContentStream(params.cosDoc.decodeStream(patNode));
39402
- const patResDict = params.cosDoc.resolveDict(dictGet(patNode.dict, "Resources")) ?? activeResources;
39403
- const patFonts = new Map(activeFonts);
39404
- for (const [fk, fv] of resolvePageFonts(params.cosDoc, patResDict).entries()) {
39405
- patFonts.set(fk, fv);
39406
- }
39407
- const ixStart = Math.floor(pMinX / xStep);
39408
- const ixEnd = Math.min(ixStart + 8, Math.ceil(pMaxX / xStep) - 1);
39409
- const iyStart = Math.floor(pMinY / yStep);
39410
- const iyEnd = Math.min(iyStart + 8, Math.ceil(pMaxY / yStep) - 1);
39411
- for (let iy = iyStart; iy <= iyEnd; iy++) {
39412
- for (let ix = ixStart; ix <= ixEnd; ix++) {
39413
- const tileCtm = multiplyMatrices([1, 0, 0, 1, ix * xStep, iy * yStep], patMatrix);
39414
- stateStack.push({
39415
- ...st,
39416
- fillPatternName: void 0,
39417
- ctm: tileCtm,
39418
- clipRect: tileClip
39419
- });
39420
- walkNodes(patNodes, mcid, actualText, patResDict, patFonts, depth + 1);
39421
- if (stateStack.length > 1) stateStack.pop();
39422
- }
39423
- }
39424
- evaluatedFillPattern = true;
39425
- }
39426
- }
39427
- }
39425
+ const evaluatedFillPattern = isFill && paintPattern(
39426
+ transformedSegments,
39427
+ node.paint.includes("*") ? "evenodd" : "nonzero",
39428
+ activeResources,
39429
+ activeFonts,
39430
+ depth,
39431
+ mcid,
39432
+ actualText
39433
+ );
39428
39434
  if (evaluatedFillPattern && !isStroke) {
39429
39435
  applyClip();
39430
39436
  break;
@@ -39625,10 +39631,19 @@ function evaluateContentStreamToDisplayList(params) {
39625
39631
  if (st.textRenderMode >= 4 && st.textRenderMode <= 7) pendingTextClip.push(...transformedGlyphSegs);
39626
39632
  const isFillGlyph = st.textRenderMode === 0 || st.textRenderMode === 2 || st.textRenderMode === 4 || st.textRenderMode === 6;
39627
39633
  const isStrokeGlyph = st.textRenderMode === 1 || st.textRenderMode === 2 || st.textRenderMode === 5 || st.textRenderMode === 6;
39634
+ const patterned = isFillGlyph && paintPattern(
39635
+ transformedGlyphSegs,
39636
+ "nonzero",
39637
+ activeResources,
39638
+ activeFonts,
39639
+ depth,
39640
+ mcid,
39641
+ actualText
39642
+ );
39628
39643
  const paint = {
39629
39644
  segments: transformedGlyphSegs,
39630
- fillColor: isFillGlyph ? st.fillColor : void 0,
39631
- fillAlpha: isFillGlyph ? st.fillAlpha : void 0,
39645
+ fillColor: isFillGlyph && !patterned ? st.fillColor : void 0,
39646
+ fillAlpha: isFillGlyph && !patterned ? st.fillAlpha : void 0,
39632
39647
  strokeColor: isStrokeGlyph ? st.strokeColor : void 0,
39633
39648
  strokeAlpha: isStrokeGlyph ? st.strokeAlpha : void 0,
39634
39649
  strokeWidth: isStrokeGlyph ? st.strokeWidth : 0,
@@ -43026,10 +43041,14 @@ function computePdfBlendRgb(cbR, cbG, cbB, csR, csG, csB, mode) {
43026
43041
  blendChannelSeparable(cbB, csB, mode)
43027
43042
  ];
43028
43043
  }
43029
- function blendPixel(rgba, width, height, px, py, color, alpha, blendMode, clipMask) {
43044
+ function blendPixel(rgba, width, height, px, py, color, alpha, blendMode, clipMask, groupAlpha) {
43030
43045
  if (px < 0 || py < 0 || px >= width || py >= height || alpha <= 0) return;
43031
43046
  const a = Math.min(1, Math.max(0, alpha)) * (clipMask ? clipMask[(py * width + px) * 4 + 3] / 255 : 1);
43032
43047
  const idx = (py * width + px) * 4;
43048
+ if (groupAlpha) {
43049
+ const pixel = py * width + px;
43050
+ groupAlpha[pixel] = a + groupAlpha[pixel] * (1 - a);
43051
+ }
43033
43052
  const csR = Math.min(1, Math.max(0, color.r));
43034
43053
  const csG = Math.min(1, Math.max(0, color.g));
43035
43054
  const csB = Math.min(1, Math.max(0, color.b));
@@ -43161,7 +43180,7 @@ function pathsToEdges(paths, closeSubpaths = false) {
43161
43180
  }
43162
43181
  return edges;
43163
43182
  }
43164
- function fillEdgesScanline4x4(rgba, width, height, edges, color, alpha = 1, fillRule = "nonzero", clipScreen, antialias = true, blendMode, clipMask) {
43183
+ function fillEdgesScanline4x4(rgba, width, height, edges, color, alpha = 1, fillRule = "nonzero", clipScreen, antialias = true, blendMode, clipMask, groupAlpha) {
43165
43184
  if (edges.length === 0) return;
43166
43185
  let minY = Infinity;
43167
43186
  let maxY = -Infinity;
@@ -43227,7 +43246,7 @@ function fillEdgesScanline4x4(rgba, width, height, edges, color, alpha = 1, fill
43227
43246
  const count = rowCounts[px];
43228
43247
  if (count > 0) {
43229
43248
  const cov = antialias ? count / 16 : count >= 8 ? 1 : 0;
43230
- blendPixel(rgba, width, height, px, py, color, cov * alpha, blendMode, clipMask);
43249
+ blendPixel(rgba, width, height, px, py, color, cov * alpha, blendMode, clipMask, groupAlpha);
43231
43250
  }
43232
43251
  }
43233
43252
  }
@@ -43306,19 +43325,16 @@ function hasCompositingEffects(operations, includeSoftMasks = false) {
43306
43325
  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));
43307
43326
  }
43308
43327
  function needsGroupBackdrop(group) {
43309
- return group.isolated === false && !!group.softMask && hasCompositingEffects(group.operations, true);
43328
+ return group.isolated === false && hasCompositingEffects(group.operations, true);
43310
43329
  }
43311
- function renderDisplayListToBitmap(displayList, options = {}) {
43312
- const baseScale = options.scale ?? (options.dpi ? options.dpi / 72 : 1.5);
43313
- const scaleX = options.dpiX !== void 0 ? options.dpiX / 72 : baseScale;
43314
- const scaleY = options.dpiY !== void 0 ? options.dpiY / 72 : baseScale;
43315
- const scale = scaleX;
43330
+ function renderDisplayListLayer(displayList, options, scale, backdrop) {
43316
43331
  const [originX, originY] = displayList.origin ?? [0, 0];
43317
43332
  const pageTop = originY + displayList.height;
43318
43333
  const toScreen = (x, y) => [(x - originX) * scale, (pageTop - y) * scale];
43319
43334
  const width = Math.max(1, Math.round(displayList.width * scale));
43320
43335
  const height = Math.max(1, Math.round(displayList.height * scale));
43321
- const rgba = new Uint8Array(width * height * 4);
43336
+ const rgba = backdrop ? backdrop.slice() : new Uint8Array(width * height * 4);
43337
+ const groupAlpha = backdrop ? new Float32Array(width * height) : void 0;
43322
43338
  const deferBackground = !options.transparent && hasCompositingEffects(paintOperations(displayList));
43323
43339
  const transparent = options.transparent || deferBackground;
43324
43340
  const bg = options.background ?? { r: 1, g: 1, b: 1 };
@@ -43326,7 +43342,7 @@ function renderDisplayListToBitmap(displayList, options = {}) {
43326
43342
  const bgG = transparent ? 0 : Math.round(bg.g * 255);
43327
43343
  const bgB = transparent ? 0 : Math.round(bg.b * 255);
43328
43344
  const bgA = transparent ? 0 : 255;
43329
- for (let i = 0; i < width * height; i++) {
43345
+ for (let i = 0; !backdrop && i < width * height; i++) {
43330
43346
  rgba[i * 4] = bgR;
43331
43347
  rgba[i * 4 + 1] = bgG;
43332
43348
  rgba[i * 4 + 2] = bgB;
@@ -43344,20 +43360,12 @@ function renderDisplayListToBitmap(displayList, options = {}) {
43344
43360
  let operation = original.kind === "glyph" ? { kind: "path", value: glyphPaint(original.value) } : original;
43345
43361
  if (operation.kind === "group") {
43346
43362
  const group = operation.value;
43347
- let operations = group.operations;
43348
- if (needsGroupBackdrop(group)) {
43349
- operations = [{ kind: "image", value: {
43350
- name: "GroupBackdrop",
43351
- width,
43352
- height,
43353
- decodedRgba: rgba.slice(),
43354
- matrix: [width / scale, 0, 0, height / scale, originX, pageTop - height / scale],
43355
- colorSpace: "DeviceRGB",
43356
- bitsPerComponent: 8,
43357
- ...group.bboxClip ? { clipPaths: [group.bboxClip] } : {}
43358
- } }, ...operations];
43359
- }
43360
- const bitmap = renderDisplayListToBitmap({ ...displayList, rotation: 0, operations }, { ...options, scale, dpiX: void 0, dpiY: void 0, cropRect: void 0, useCropBox: false, transparent: true });
43363
+ const bitmap = renderDisplayListLayer(
43364
+ { ...displayList, operations: group.operations },
43365
+ { ...options, transparent: true },
43366
+ scale,
43367
+ needsGroupBackdrop(group) ? rgba : void 0
43368
+ );
43361
43369
  for (let i = 3; i < bitmap.data.length; i += 4) bitmap.data[i] = Math.round(bitmap.data[i] * group.alpha);
43362
43370
  operation = { kind: "image", value: {
43363
43371
  name: "TransparencyGroup",
@@ -43427,7 +43435,7 @@ function renderDisplayListToBitmap(displayList, options = {}) {
43427
43435
  if (path.fillColor) {
43428
43436
  const edges = pathsToEdges(segmentsToScreenPaths(path.segments, displayList.height, scale, toScreen), true);
43429
43437
  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;
43430
- fillEdgesScanline4x4(rgba, width, height, edges, path.fillColor, path.fillAlpha ?? 1, path.fillRule ?? "nonzero", clipScreen, original.kind === "glyph" ? aaTxt : aaVec, path.blendMode, clipMask);
43438
+ fillEdgesScanline4x4(rgba, width, height, edges, path.fillColor, path.fillAlpha ?? 1, path.fillRule ?? "nonzero", clipScreen, original.kind === "glyph" ? aaTxt : aaVec, path.blendMode, clipMask, groupAlpha);
43431
43439
  }
43432
43440
  if (path.strokeColor) {
43433
43441
  const rawSw = path.strokeWidth * scale * (path.strokeMatrix ? Math.hypot(path.strokeMatrix[0], path.strokeMatrix[1]) : 1);
@@ -43445,7 +43453,8 @@ function renderDisplayListToBitmap(displayList, options = {}) {
43445
43453
  clipScreen,
43446
43454
  original.kind === "glyph" ? aaTxt : aaVec,
43447
43455
  path.blendMode,
43448
- clipMask
43456
+ clipMask,
43457
+ groupAlpha
43449
43458
  );
43450
43459
  }
43451
43460
  } else if (operation.kind === "image") {
@@ -43509,12 +43518,31 @@ function renderDisplayListToBitmap(displayList, options = {}) {
43509
43518
  },
43510
43519
  sample[3] / 255,
43511
43520
  img.blendMode,
43512
- clipMask
43521
+ clipMask,
43522
+ groupAlpha
43513
43523
  );
43514
43524
  }
43515
43525
  }
43516
43526
  }
43517
43527
  }
43528
+ if (backdrop && groupAlpha) {
43529
+ for (let i = 0; i < rgba.length; i += 4) {
43530
+ const alpha = groupAlpha[i / 4];
43531
+ if (alpha === 0) {
43532
+ rgba.fill(0, i, i + 4);
43533
+ continue;
43534
+ }
43535
+ const factor = backdrop[i + 3] / 255 * (1 / alpha - 1);
43536
+ for (let channel = 0; channel < 3; channel++) {
43537
+ const color = rgba[i + channel];
43538
+ rgba[i + channel] = Math.max(0, Math.min(
43539
+ 255,
43540
+ Math.round(color + (color - backdrop[i + channel]) * factor)
43541
+ ));
43542
+ }
43543
+ rgba[i + 3] = Math.round(alpha * 255);
43544
+ }
43545
+ }
43518
43546
  if (deferBackground) {
43519
43547
  for (let i = 0; i < rgba.length; i += 4) {
43520
43548
  const alpha = rgba[i + 3] / 255;
@@ -43524,7 +43552,14 @@ function renderDisplayListToBitmap(displayList, options = {}) {
43524
43552
  rgba[i + 3] = 255;
43525
43553
  }
43526
43554
  }
43527
- let result = { width, height, data: rgba };
43555
+ return { width, height, data: rgba };
43556
+ }
43557
+ function renderDisplayListToBitmap(displayList, options = {}) {
43558
+ const baseScale = options.scale ?? (options.dpi ? options.dpi / 72 : 1.5);
43559
+ const scaleX = options.dpiX !== void 0 ? options.dpiX / 72 : baseScale;
43560
+ const scaleY = options.dpiY !== void 0 ? options.dpiY / 72 : baseScale;
43561
+ let result = renderDisplayListLayer(displayList, options, scaleX);
43562
+ const { width, height, data: rgba } = result;
43528
43563
  if (Math.abs(scaleX - scaleY) > 1e-6) {
43529
43564
  const targetW = Math.max(1, Math.round(displayList.width * scaleX));
43530
43565
  const targetH = Math.max(1, Math.round(displayList.height * scaleY));