@poe-platform/safe-bash 0.1.762 → 0.1.764

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.
Files changed (35) hide show
  1. package/dist/image-ast/index.browser.js +454 -208
  2. package/dist/image-ast/index.js +454 -208
  3. package/dist/pdf-ast/ast.d.ts +23 -0
  4. package/dist/pdf-ast/index.js +543 -244
  5. package/dist/safe-bash/chunks/{chunk-CRQDMBQA.js → chunk-FSH7QRIC.js} +10 -1
  6. package/dist/safe-bash/command-chunks/{chunk-D4GXXV65.js → chunk-B7YLGJRF.js} +2 -2
  7. package/dist/safe-bash/command-chunks/{chunk-P3Q2QSCA.js → chunk-G3IIEU2N.js} +457 -208
  8. package/dist/safe-bash/command-chunks/{chunk-F7MJRXQ2.js → chunk-RDPJGIQF.js} +1 -1
  9. package/dist/safe-bash/commands/python/index.browser.js +1 -1
  10. package/dist/safe-bash/commands/python/llm-module.js +3 -1
  11. package/dist/safe-bash/commands/python/shell-module.js +7 -0
  12. package/dist/safe-bash/core.browser.js +33 -13
  13. package/dist/safe-bash/shell/runtime.js +44 -12
  14. package/dist/safe-bash-checksum-engine/index.d.ts +1 -1
  15. package/dist/safe-bash-checksum-engine/index.js +5 -1
  16. package/dist/safe-bash-command-ffmpeg/index.js +7476 -7338
  17. package/dist/safe-bash-command-gh/index.js +174 -105
  18. package/dist/safe-bash-command-imagemagick/index.js +2 -2
  19. package/dist/safe-bash-command-pandoc/command.js +3 -3
  20. package/dist/safe-bash-command-pandoc/index.js +3 -3
  21. package/dist/safe-bash-command-pdfimages/index.js +454 -208
  22. package/dist/safe-bash-command-pdfinfo/index.js +541 -244
  23. package/dist/safe-bash-command-pdftk/index.js +454 -208
  24. package/dist/safe-bash-command-pdftoppm/index.js +541 -244
  25. package/dist/safe-bash-command-pdftotext/index.js +454 -208
  26. package/dist/safe-bash-command-qpdf/index.js +454 -208
  27. package/dist/safe-bash-command-sips/index.js +2 -2
  28. package/dist/safe-bash-command-soffice/index.js +1 -1
  29. package/dist/safe-bash-command-ssconvert/index.js +514 -208
  30. package/dist/safe-bash-command-wkhtmltopdf/index.js +455 -208
  31. package/dist/safe-playwright-cloudflare/browser-snapshot-labels.d.ts +14 -0
  32. package/dist/safe-playwright-cloudflare/browser-snapshot-labels.js +62 -0
  33. package/dist/safe-playwright-cloudflare/browser-snapshot-scheduler.js +8 -1
  34. package/package.json +2 -2
  35. package/third-party/pdf-ast/THIRD_PARTY_NOTICES.md +27 -0
@@ -11606,14 +11606,18 @@ function evaluateContentStreamToDisplayList(params) {
11606
11606
  const paths = [];
11607
11607
  const images = [];
11608
11608
  const operations = [];
11609
+ let capturedOperations;
11610
+ let insideSoftMask = false;
11609
11611
  const emit = (operation) => {
11610
- const { clipPaths, clipImages } = curState();
11611
- if (clipPaths || clipImages) operation = { ...operation, value: {
11612
+ const { clipPaths, clipImages, softMask } = curState();
11613
+ if (clipPaths || clipImages || softMask) operation = { ...operation, value: {
11612
11614
  ...operation.value,
11613
11615
  ...clipPaths ? { clipPaths } : {},
11614
- ...clipImages ? { clipImages } : {}
11616
+ ...clipImages ? { clipImages } : {},
11617
+ ...softMask ? { softMask } : {}
11615
11618
  } };
11616
- operations.push(operation);
11619
+ (capturedOperations ?? operations).push(operation);
11620
+ if (insideSoftMask) return;
11617
11621
  switch (operation.kind) {
11618
11622
  case "path":
11619
11623
  paths.push(operation.value);
@@ -11719,7 +11723,7 @@ function evaluateContentStreamToDisplayList(params) {
11719
11723
  );
11720
11724
  return { r: kClamp(r), g: kClamp(g), b: kClamp(b) };
11721
11725
  };
11722
- const applyStateOperator = (st, operator, ops, activeResources) => {
11726
+ const applyStateOperator = (st, operator, ops, activeResources, activeFonts, depth) => {
11723
11727
  const num = (i, fb = 0) => ops[i]?.kind === "number" ? ops[i].value : fb;
11724
11728
  if (operator === "cm") {
11725
11729
  const m = [num(0, 1), num(1, 0), num(2, 0), num(3, 1), num(4, 0), num(5, 0)];
@@ -11802,6 +11806,46 @@ function evaluateContentStreamToDisplayList(params) {
11802
11806
  const extDict = params.cosDoc.resolveDict(dictGet(activeResources, "ExtGState"));
11803
11807
  const gsDict = extDict ? params.cosDoc.resolveDict(dictGet(extDict, ops[0].decoded)) : void 0;
11804
11808
  if (gsDict) {
11809
+ const mask = params.cosDoc.resolve(dictGet(gsDict, "SMask"));
11810
+ if (mask?.kind === "name" && mask.decoded === "None") {
11811
+ st.softMask = void 0;
11812
+ } else if (mask?.kind === "dict") {
11813
+ const subtype = params.cosDoc.resolve(dictGet(mask, "S"));
11814
+ const form = params.cosDoc.resolve(dictGet(mask, "G"));
11815
+ if (form?.kind === "stream" && subtype?.kind === "name" && (subtype.decoded === "Alpha" || subtype.decoded === "Luminosity")) {
11816
+ if (depth >= 8) throw new PdfError("E_LIMIT", "Soft-mask nesting exceeds the form depth limit");
11817
+ const parentOperations = capturedOperations;
11818
+ const parentInsideSoftMask = insideSoftMask;
11819
+ const savedTextState = { pendingTextClip, hasTextClip, activeTm, activeTlm };
11820
+ const captured = [];
11821
+ capturedOperations = captured;
11822
+ insideSoftMask = true;
11823
+ const maskState = { ...st, softMask: void 0, fillAlpha: 1, strokeAlpha: 1, blendMode: "Normal" };
11824
+ delete maskState.clipPaths;
11825
+ delete maskState.clipImages;
11826
+ delete maskState.clipRect;
11827
+ stateStack.push(maskState);
11828
+ try {
11829
+ paintForm(form, activeResources, activeFonts, depth, void 0, void 0, true);
11830
+ } finally {
11831
+ stateStack.pop();
11832
+ capturedOperations = parentOperations;
11833
+ insideSoftMask = parentInsideSoftMask;
11834
+ ({ pendingTextClip, hasTextClip, activeTm, activeTlm } = savedTextState);
11835
+ }
11836
+ const group = params.cosDoc.resolveDict(dictGet(form.dict, "Group"));
11837
+ const colorSpace = group ? dictGet(group, "CS") : void 0;
11838
+ const bc = params.cosDoc.resolveArray(dictGet(mask, "BC"));
11839
+ const components = bc?.items.map((item) => {
11840
+ const value = params.cosDoc.resolve(item);
11841
+ return value?.kind === "number" ? value.value : 0;
11842
+ });
11843
+ const [r, g, b] = components ? convertColorSpaceComponentsToRgb(params.cosDoc, colorSpace, "DeviceRGB", components, activeResources) : [0, 0, 0];
11844
+ const transfer = params.cosDoc.resolve(dictGet(mask, "TR"));
11845
+ const transferMap = transfer?.kind === "dict" || transfer?.kind === "stream" ? Uint8Array.from({ length: 256 }, (_, i) => Math.floor(kClamp(Math.fround(evalShadingFunctionToComponents(params.cosDoc, transfer, Math.fround(i / 255))[0] ?? 0)) * 255)) : void 0;
11846
+ st.softMask = { subtype: subtype.decoded, operations: captured, backdrop: { r, g, b }, transferMap };
11847
+ }
11848
+ }
11805
11849
  const bmNode = params.cosDoc.resolve(dictGet(gsDict, "BM"));
11806
11850
  if (bmNode?.kind === "name") {
11807
11851
  st.blendMode = bmNode.decoded === "Compatible" ? "Normal" : bmNode.decoded;
@@ -11888,6 +11932,84 @@ function evaluateContentStreamToDisplayList(params) {
11888
11932
  ] }], void 0, void 0, resources, activeFonts, depth);
11889
11933
  stateStack.pop();
11890
11934
  };
11935
+ const paintForm = (form, activeResources, activeFonts, depth, mcid, actualText, maskGroup = false) => {
11936
+ const st = curState();
11937
+ const group = params.cosDoc.resolveDict(dictGet(form.dict, "Group"));
11938
+ const groupType = group ? params.cosDoc.resolve(dictGet(group, "S")) : void 0;
11939
+ const isolated = group ? params.cosDoc.resolve(dictGet(group, "I")) : void 0;
11940
+ const isolate = !maskGroup && groupType?.kind === "name" && groupType.decoded === "Transparency" && isolated?.kind === "boolean" && isolated.value;
11941
+ const formStreamBytes = params.cosDoc.decodeStream(form);
11942
+ const formNodes = parseContentStream(formStreamBytes);
11943
+ const formResDict = params.cosDoc.resolveDict(dictGet(form.dict, "Resources")) ?? activeResources;
11944
+ const formFonts = new Map(activeFonts);
11945
+ for (const [k, v] of resolvePageFonts(params.cosDoc, formResDict).entries()) {
11946
+ formFonts.set(k, v);
11947
+ }
11948
+ let nextCtm = [...st.ctm];
11949
+ const matArr = params.cosDoc.resolveArray(dictGet(form.dict, "Matrix"));
11950
+ if (matArr && matArr.items.length >= 6) {
11951
+ const mn = (idx, fb = 0) => {
11952
+ const resolved = params.cosDoc.resolve(matArr.items[idx]);
11953
+ return resolved?.kind === "number" ? resolved.value : fb;
11954
+ };
11955
+ const formMat = [mn(0, 1), mn(1, 0), mn(2, 0), mn(3, 1), mn(4, 0), mn(5, 0)];
11956
+ nextCtm = multiplyMatrices(formMat, nextCtm);
11957
+ }
11958
+ let nextClip = !isolate && st.clipRect ? [...st.clipRect] : void 0;
11959
+ let nextClipPaths = isolate ? void 0 : st.clipPaths;
11960
+ const bboxArr = params.cosDoc.resolveArray(dictGet(form.dict, "BBox"));
11961
+ if (bboxArr && bboxArr.items.length >= 4) {
11962
+ const bn = (idx, fb = 0) => {
11963
+ const resolved = params.cosDoc.resolve(bboxArr.items[idx]);
11964
+ return resolved?.kind === "number" ? resolved.value : fb;
11965
+ };
11966
+ const bx0 = bn(0, 0), by0 = bn(1, 0), bx1 = bn(2, 0), by1 = bn(3, 0);
11967
+ const pts = [
11968
+ transformPoint(nextCtm, bx0, by0),
11969
+ transformPoint(nextCtm, bx1, by0),
11970
+ transformPoint(nextCtm, bx1, by1),
11971
+ transformPoint(nextCtm, bx0, by1)
11972
+ ];
11973
+ nextClipPaths = [...nextClipPaths ?? [], [
11974
+ ...pts.map(([x, y], index) => ({ kind: index === 0 ? "move" : "line", x, y })),
11975
+ { kind: "close" }
11976
+ ]];
11977
+ const fMinX = Math.min(...pts.map((p) => p[0]));
11978
+ const fMinY = Math.min(...pts.map((p) => p[1]));
11979
+ const fMaxX = Math.max(...pts.map((p) => p[0]));
11980
+ const fMaxY = Math.max(...pts.map((p) => p[1]));
11981
+ if (fMaxX > fMinX && fMaxY > fMinY) {
11982
+ nextClip = nextClip ? [
11983
+ Math.max(nextClip[0], fMinX),
11984
+ Math.max(nextClip[1], fMinY),
11985
+ Math.min(nextClip[2], fMaxX),
11986
+ Math.min(nextClip[3], fMaxY)
11987
+ ] : [fMinX, fMinY, fMaxX, fMaxY];
11988
+ }
11989
+ }
11990
+ const parentOperations = capturedOperations;
11991
+ const children = [];
11992
+ const nextState = { ...st, ctm: nextCtm };
11993
+ if (isolate) {
11994
+ capturedOperations = children;
11995
+ nextState.fillAlpha = nextState.strokeAlpha = 1;
11996
+ nextState.blendMode = "Normal";
11997
+ nextState.softMask = void 0;
11998
+ delete nextState.clipImages;
11999
+ delete nextState.clipPaths;
12000
+ delete nextState.clipRect;
12001
+ }
12002
+ if (nextClip) nextState.clipRect = nextClip;
12003
+ if (nextClipPaths) nextState.clipPaths = nextClipPaths;
12004
+ stateStack.push(nextState);
12005
+ try {
12006
+ walkNodes(formNodes, mcid, actualText, formResDict, formFonts, depth + 1);
12007
+ } finally {
12008
+ stateStack.pop();
12009
+ capturedOperations = parentOperations;
12010
+ }
12011
+ if (isolate) emit({ kind: "group", value: { operations: children, alpha: st.fillAlpha, blendMode: st.blendMode, clipRect: st.clipRect } });
12012
+ };
11891
12013
  const walkNodes = (nodes, mcid, actualText, activeResources = params.resourcesDict, activeFonts = fonts, depth = 0) => {
11892
12014
  for (const node of nodes) {
11893
12015
  switch (node.kind) {
@@ -11932,7 +12054,7 @@ function evaluateContentStreamToDisplayList(params) {
11932
12054
  break;
11933
12055
  }
11934
12056
  case "state-op": {
11935
- applyStateOperator(curState(), node.operator, node.operands, activeResources);
12057
+ applyStateOperator(curState(), node.operator, node.operands, activeResources, activeFonts, depth);
11936
12058
  break;
11937
12059
  }
11938
12060
  case "path-op": {
@@ -12218,53 +12340,7 @@ function evaluateContentStreamToDisplayList(params) {
12218
12340
  ...st.clipRect ? { clipRect: [...st.clipRect] } : {}
12219
12341
  }, patternMask, activeResources, activeFonts, depth);
12220
12342
  } else if (sub === "Form" && depth < 8) {
12221
- const formStreamBytes = params.cosDoc.decodeStream(xobjNode);
12222
- const formNodes = parseContentStream(formStreamBytes);
12223
- const formResDict = params.cosDoc.resolveDict(dictGet(xobjNode.dict, "Resources")) ?? activeResources;
12224
- const formFonts = new Map(activeFonts);
12225
- for (const [k, v] of resolvePageFonts(params.cosDoc, formResDict).entries()) {
12226
- formFonts.set(k, v);
12227
- }
12228
- let nextCtm = [...st.ctm];
12229
- const matArr = params.cosDoc.resolveArray(dictGet(xobjNode.dict, "Matrix"));
12230
- if (matArr && matArr.items.length >= 6) {
12231
- const mn = (idx, fb = 0) => {
12232
- const resolved = params.cosDoc.resolve(matArr.items[idx]);
12233
- return resolved?.kind === "number" ? resolved.value : fb;
12234
- };
12235
- const formMat = [mn(0, 1), mn(1, 0), mn(2, 0), mn(3, 1), mn(4, 0), mn(5, 0)];
12236
- nextCtm = multiplyMatrices(formMat, nextCtm);
12237
- }
12238
- let nextClip = st.clipRect ? [...st.clipRect] : void 0;
12239
- const bboxArr = params.cosDoc.resolveArray(dictGet(xobjNode.dict, "BBox"));
12240
- if (bboxArr && bboxArr.items.length >= 4) {
12241
- const bn = (idx, fb = 0) => {
12242
- const resolved = params.cosDoc.resolve(bboxArr.items[idx]);
12243
- return resolved?.kind === "number" ? resolved.value : fb;
12244
- };
12245
- const bx0 = bn(0, 0), by0 = bn(1, 0), bx1 = bn(2, 0), by1 = bn(3, 0);
12246
- const pts = [
12247
- transformPoint(nextCtm, bx0, by0),
12248
- transformPoint(nextCtm, bx1, by0),
12249
- transformPoint(nextCtm, bx0, by1),
12250
- transformPoint(nextCtm, bx1, by1)
12251
- ];
12252
- const fMinX = Math.min(...pts.map((p) => p[0]));
12253
- const fMinY = Math.min(...pts.map((p) => p[1]));
12254
- const fMaxX = Math.max(...pts.map((p) => p[0]));
12255
- const fMaxY = Math.max(...pts.map((p) => p[1]));
12256
- if (fMaxX > fMinX && fMaxY > fMinY) {
12257
- nextClip = nextClip ? [
12258
- Math.max(nextClip[0], fMinX),
12259
- Math.max(nextClip[1], fMinY),
12260
- Math.min(nextClip[2], fMaxX),
12261
- Math.min(nextClip[3], fMaxY)
12262
- ] : [fMinX, fMinY, fMaxX, fMaxY];
12263
- }
12264
- }
12265
- stateStack.push({ ...st, ctm: nextCtm, ...nextClip ? { clipRect: nextClip } : {} });
12266
- walkNodes(formNodes, mcid, actualText, formResDict, formFonts, depth + 1);
12267
- if (stateStack.length > 1) stateStack.pop();
12343
+ paintForm(xobjNode, activeResources, activeFonts, depth, mcid, actualText);
12268
12344
  }
12269
12345
  }
12270
12346
  }
@@ -12483,7 +12559,7 @@ function evaluateContentStreamToDisplayList(params) {
12483
12559
  st.textRenderMode = cmd.mode;
12484
12560
  break;
12485
12561
  case "state-op":
12486
- applyStateOperator(st, cmd.operator, cmd.operands, activeResources);
12562
+ applyStateOperator(st, cmd.operator, cmd.operands, activeResources, activeFonts, depth);
12487
12563
  break;
12488
12564
  case "show-text":
12489
12565
  emitTokenBytes(cmd.token.bytes);
@@ -14002,6 +14078,183 @@ function downscaleImage(image, widthScale, heightScale) {
14002
14078
  }
14003
14079
  return image;
14004
14080
  }
14081
+ function dashSubpath(path, pattern, phase) {
14082
+ const cycle = pattern.reduce((sum, value) => sum + value, 0);
14083
+ if (!(cycle > 0)) return [path];
14084
+ let offset = (phase % cycle + cycle) % cycle, index = 0;
14085
+ while (offset > 0) {
14086
+ if (offset < pattern[index]) break;
14087
+ offset -= pattern[index];
14088
+ index = (index + 1) % pattern.length;
14089
+ }
14090
+ let remaining = pattern[index] - offset;
14091
+ const points = path.closed ? [...path.points, path.points[0]] : path.points;
14092
+ const result = [];
14093
+ let current = [];
14094
+ let steps = 0;
14095
+ const flush = () => {
14096
+ if (current.length) result.push({ points: current, closed: false });
14097
+ current = [];
14098
+ };
14099
+ const advance = (point) => {
14100
+ while (remaining <= 0) {
14101
+ if (++steps > MAX_STROKE_VERTICES) throw new PdfError("E_LIMIT", "Stroke dash expansion exceeds the vertex limit");
14102
+ if (index % 2 === 0) {
14103
+ if (pattern[index] === 0) result.push({ points: [point, point], closed: false });
14104
+ flush();
14105
+ }
14106
+ index = (index + 1) % pattern.length;
14107
+ remaining = pattern[index];
14108
+ }
14109
+ };
14110
+ for (let i = 1; i < points.length; i++) {
14111
+ const start = points[i - 1], end = points[i];
14112
+ const dx = end[0] - start[0], dy = end[1] - start[1];
14113
+ const length2 = Math.hypot(dx, dy);
14114
+ if (!Number.isFinite(length2) || length2 / cycle * pattern.length > MAX_STROKE_VERTICES) {
14115
+ throw new PdfError("E_LIMIT", "Stroke dash expansion exceeds the vertex limit");
14116
+ }
14117
+ let distance = 0;
14118
+ while (distance < length2) {
14119
+ const point = [start[0] + dx * distance / length2, start[1] + dy * distance / length2];
14120
+ advance(point);
14121
+ const step = Math.min(remaining, length2 - distance);
14122
+ if (distance + step === distance || ++steps > MAX_STROKE_VERTICES) throw new PdfError("E_LIMIT", "Stroke dash expansion exceeds the vertex limit");
14123
+ distance += step;
14124
+ remaining -= step;
14125
+ if (index % 2 === 0) {
14126
+ if (!current.length) current.push(point);
14127
+ current.push([start[0] + dx * distance / length2, start[1] + dy * distance / length2]);
14128
+ }
14129
+ }
14130
+ }
14131
+ flush();
14132
+ if (path.closed && result.length) {
14133
+ const first = result[0], last = result[result.length - 1];
14134
+ const start = path.points[0];
14135
+ const firstPoint = first.points[0], lastPoint = last.points[last.points.length - 1];
14136
+ if (firstPoint[0] === start[0] && firstPoint[1] === start[1] && lastPoint[0] === start[0] && lastPoint[1] === start[1]) {
14137
+ if (first === last) result[0] = { points: first.points, closed: true };
14138
+ else {
14139
+ result[0] = { points: [...last.points, ...first.points.slice(1)], closed: false };
14140
+ result.pop();
14141
+ }
14142
+ }
14143
+ }
14144
+ return result;
14145
+ }
14146
+ function strokeOutlines(paths, width, cap, join, miterLimit, dashArray = [], dashPhase = 0) {
14147
+ const half = width / 2;
14148
+ const contours = [];
14149
+ const pattern = dashArray.length % 2 ? [...dashArray, ...dashArray] : dashArray;
14150
+ let count = 0;
14151
+ let contour = [];
14152
+ const add = (x, y) => {
14153
+ if (++count > MAX_STROKE_VERTICES) throw new PdfError("E_LIMIT", "Stroke outline exceeds the vertex limit");
14154
+ contour.push([x, y]);
14155
+ };
14156
+ const arc = (point, dx1, dy1, dx2, dy2) => {
14157
+ let a1 = Math.atan2(dy1, dx1), a2 = Math.atan2(dy2, dx2);
14158
+ const ccw = a1 - a2 > 0 && a1 - a2 < Math.PI;
14159
+ const step = Math.acos(half / (half + 0.125)) * 2;
14160
+ add(point[0] + dx1, point[1] + dy1);
14161
+ if (step > 0) {
14162
+ if (!ccw) {
14163
+ if (a1 > a2) a2 += 2 * Math.PI;
14164
+ a2 -= step / 4;
14165
+ if ((a2 - a1) / step > MAX_STROKE_VERTICES - count) throw new PdfError("E_LIMIT", "Stroke arc exceeds the vertex limit");
14166
+ for (a1 += step; a1 < a2; a1 += step) add(point[0] + half * Math.cos(a1), point[1] + half * Math.sin(a1));
14167
+ } else {
14168
+ if (a1 < a2) a2 -= 2 * Math.PI;
14169
+ a2 += step / 4;
14170
+ if ((a1 - a2) / step > MAX_STROKE_VERTICES - count) throw new PdfError("E_LIMIT", "Stroke arc exceeds the vertex limit");
14171
+ for (a1 -= step; a1 > a2; a1 -= step) add(point[0] + half * Math.cos(a1), point[1] + half * Math.sin(a1));
14172
+ }
14173
+ }
14174
+ add(point[0] + dx2, point[1] + dy2);
14175
+ };
14176
+ const addCap = (point, next) => {
14177
+ const length2 = Math.hypot(next[0] - point[0], next[1] - point[1]);
14178
+ const dx = half * (next[1] - point[1]) / length2;
14179
+ const dy = half * (next[0] - point[0]) / length2;
14180
+ if (cap !== 1) {
14181
+ const sx = cap === 2 ? dy : 0, sy = cap === 2 ? dx : 0;
14182
+ add(point[0] - dx - sx, point[1] + dy - sy);
14183
+ add(point[0] + dx - sx, point[1] - dy - sy);
14184
+ } else {
14185
+ const angle = Math.atan2(dy, -dx);
14186
+ const step = Math.max(1e-3, Math.acos(half / (half + 0.125)) * 2);
14187
+ add(point[0] - dx, point[1] + dy);
14188
+ for (let a = angle + step; a < angle + Math.PI - step / 4; a += step) add(point[0] + half * Math.cos(a), point[1] + half * Math.sin(a));
14189
+ add(point[0] + dx, point[1] - dy);
14190
+ }
14191
+ };
14192
+ const addJoin = (prev, point, next) => {
14193
+ const len1 = Math.hypot(point[0] - prev[0], point[1] - prev[1]);
14194
+ const len2 = Math.hypot(next[0] - point[0], next[1] - point[1]);
14195
+ const dx1 = half * (point[1] - prev[1]) / len1, dy1 = half * (point[0] - prev[0]) / len1;
14196
+ const dx2 = half * (next[1] - point[1]) / len2, dy2 = half * (next[0] - point[0]) / len2;
14197
+ const inner = (next[0] - point[0]) * (point[1] - prev[1]) - (next[1] - point[1]) * (point[0] - prev[0]) > 0;
14198
+ if (!inner && join === 1) {
14199
+ arc(point, dx1, -dy1, dx2, -dy2);
14200
+ return;
14201
+ }
14202
+ if (inner || join === 0) {
14203
+ const ax = prev[0] + dx1, ay = prev[1] - dy1;
14204
+ const bx = point[0] + dx1, by = point[1] - dy1;
14205
+ const cx = point[0] + dx2, cy = point[1] - dy2;
14206
+ const dx = next[0] + dx2, dy = next[1] - dy2;
14207
+ const den = (bx - ax) * (dy - cy) - (by - ay) * (dx - cx);
14208
+ if (Math.abs(den) >= 1e-30) {
14209
+ const t = ((ay - cy) * (dx - cx) - (ax - cx) * (dy - cy)) / den;
14210
+ const x = ax + (bx - ax) * t, y = ay + (by - ay) * t;
14211
+ if (Math.hypot(x - point[0], y - point[1]) <= half * (inner ? 1.01 : miterLimit)) {
14212
+ add(x, y);
14213
+ return;
14214
+ }
14215
+ } else if ((bx - prev[0]) * dy1 - (prev[1] - by) * dx1 < 0 !== (bx - next[0]) * dy1 - (next[1] - by) * dx1 < 0) {
14216
+ add(bx, by);
14217
+ return;
14218
+ }
14219
+ }
14220
+ add(point[0] + dx1, point[1] - dy1);
14221
+ add(point[0] + dx2, point[1] - dy2);
14222
+ };
14223
+ for (const path of paths) {
14224
+ for (const subpath of pattern.length ? dashSubpath(path, pattern, dashPhase) : [path]) {
14225
+ const points = [];
14226
+ for (const point of subpath.points) {
14227
+ const prev = points[points.length - 1];
14228
+ if (!prev || Math.hypot(prev[0] - point[0], prev[1] - point[1]) > 1e-14) points.push(point);
14229
+ }
14230
+ let closed = subpath.closed;
14231
+ if (closed && points.length > 1 && Math.hypot(points[0][0] - points[points.length - 1][0], points[0][1] - points[points.length - 1][1]) <= 1e-14) points.pop();
14232
+ if (points.length < 3) closed = false;
14233
+ if (points.length === 1 && subpath.points.length > 1 && cap === 1) {
14234
+ contour = [];
14235
+ const [x, y] = points[0];
14236
+ addCap([x, y], [x + 1, y]);
14237
+ addCap([x, y], [x - 1, y]);
14238
+ contours.push(contour);
14239
+ } else if (points.length >= 2) {
14240
+ contour = [];
14241
+ if (!closed) addCap(points[0], points[1]);
14242
+ for (let i = closed ? 0 : 1; i < points.length - (closed ? 0 : 1); i++) {
14243
+ addJoin(points[(i + points.length - 1) % points.length], points[i], points[(i + 1) % points.length]);
14244
+ }
14245
+ if (closed) {
14246
+ contours.push(contour);
14247
+ contour = [];
14248
+ } else addCap(points[points.length - 1], points[points.length - 2]);
14249
+ for (let i = points.length - (closed ? 1 : 2); i >= (closed ? 0 : 1); i--) {
14250
+ addJoin(points[(i + 1) % points.length], points[i], points[(i + points.length - 1) % points.length]);
14251
+ }
14252
+ contours.push(contour);
14253
+ }
14254
+ }
14255
+ }
14256
+ return contours;
14257
+ }
14005
14258
  function decodePng(pngBytes) {
14006
14259
  if (pngBytes.length < 24 || pngBytes[0] !== 137 || pngBytes[1] !== 80 || pngBytes[2] !== 78 || pngBytes[3] !== 71) {
14007
14260
  throw new Error("Invalid PNG signature");
@@ -14384,111 +14637,60 @@ function blendPixel(rgba, width, height, px, py, color, alpha, blendMode, clipMa
14384
14637
  rgba[idx + 2] = Math.round((effB * a + cbB * dstA * (1 - a)) / outA * 255);
14385
14638
  rgba[idx + 3] = Math.round(outA * 255);
14386
14639
  }
14387
- function drawAntiAliasedSegment(rgba, width, height, x0, y0, x1, y1, strokeWidth, color, alpha = 1, lineCap = 0, antialias = true, blendMode, clipMask) {
14388
- const halfW = Math.max(0.6, strokeWidth * 0.5);
14389
- const dx = x1 - x0;
14390
- const dy = y1 - y0;
14391
- const lenSq = dx * dx + dy * dy;
14392
- const segLen = Math.sqrt(lenSq);
14393
- const pad = lineCap === 2 ? halfW + 2 : halfW + 1;
14394
- const minX = Math.max(0, Math.floor(Math.min(x0, x1) - pad));
14395
- const maxX = Math.min(width - 1, Math.ceil(Math.max(x0, x1) + pad));
14396
- const minY = Math.max(0, Math.floor(Math.min(y0, y1) - pad));
14397
- const maxY = Math.min(height - 1, Math.ceil(Math.max(y0, y1) + pad));
14398
- for (let py = minY; py <= maxY; py++) {
14399
- for (let px = minX; px <= maxX; px++) {
14400
- const cx = px + 0.5;
14401
- const cy = py + 0.5;
14402
- if (segLen > 1e-6 && (lineCap === 0 || lineCap === 2)) {
14403
- const ux = dx / segLen;
14404
- const uy = dy / segLen;
14405
- const along = (cx - x0) * ux + (cy - y0) * uy;
14406
- const perp = Math.abs(-(cx - x0) * uy + (cy - y0) * ux);
14407
- const minAlong = lineCap === 2 ? -halfW : 0;
14408
- const maxAlong = lineCap === 2 ? segLen + halfW : segLen;
14409
- const overAlong = along < minAlong ? minAlong - along : along > maxAlong ? along - maxAlong : 0;
14410
- const dist2 = overAlong > 0 ? Math.max(perp, halfW + overAlong) : perp;
14411
- if (dist2 <= halfW + 0.75) {
14412
- const cov = antialias ? Math.max(0, Math.min(1, halfW + 0.5 - dist2)) : dist2 <= halfW + 0.25 ? 1 : 0;
14413
- blendPixel(rgba, width, height, px, py, color, cov * alpha, blendMode, clipMask);
14414
- }
14415
- continue;
14416
- }
14417
- let t = lenSq > 1e-6 ? ((cx - x0) * dx + (cy - y0) * dy) / lenSq : 0;
14418
- t = Math.max(0, Math.min(1, t));
14419
- const projX = x0 + t * dx;
14420
- const projY = y0 + t * dy;
14421
- const dist = Math.hypot(cx - projX, cy - projY);
14422
- if (dist <= halfW + 0.75) {
14423
- const cov = antialias ? Math.max(0, Math.min(1, halfW + 0.5 - dist)) : dist <= halfW + 0.25 ? 1 : 0;
14424
- blendPixel(rgba, width, height, px, py, color, cov * alpha, blendMode, clipMask);
14425
- }
14426
- }
14427
- }
14428
- }
14429
- function segmentsToScreenEdges(segments, pageHeight, scale, closeSubpaths = false) {
14430
- const edges = [];
14431
- let curX = 0;
14432
- let curY = 0;
14433
- let startX = 0;
14434
- let startY = 0;
14435
- let hasOpenSubpath = false;
14640
+ function segmentsToScreenPaths(segments, pageHeight, scale) {
14641
+ const paths = [];
14642
+ let points = [];
14643
+ let current = [0, 0];
14436
14644
  const toScreen = (x, y) => [x * scale, (pageHeight - y) * scale];
14437
- for (const seg of segments) {
14438
- if (seg.kind === "move") {
14439
- if (closeSubpaths && hasOpenSubpath && (curX !== startX || curY !== startY)) {
14440
- edges.push({ x0: curX, y0: curY, x1: startX, y1: startY });
14441
- }
14442
- [curX, curY] = toScreen(seg.x, seg.y);
14443
- startX = curX;
14444
- startY = curY;
14445
- hasOpenSubpath = false;
14446
- } else if (seg.kind === "line") {
14447
- const [nx, ny] = toScreen(seg.x, seg.y);
14448
- edges.push({ x0: curX, y0: curY, x1: nx, y1: ny });
14449
- curX = nx;
14450
- curY = ny;
14451
- hasOpenSubpath = true;
14452
- } else if (seg.kind === "cubic") {
14453
- const [p1x, p1y] = toScreen(seg.x1, seg.y1);
14454
- const [p2x, p2y] = toScreen(seg.x2, seg.y2);
14455
- const [p3x, p3y] = toScreen(seg.x, seg.y);
14456
- const points = flattenCubic(curX, curY, p1x, p1y, p2x, p2y, p3x, p3y);
14457
- let px = curX;
14458
- let py = curY;
14459
- for (let i = 1; i < points.length; i++) {
14460
- const [qx, qy] = points[i];
14461
- edges.push({ x0: px, y0: py, x1: qx, y1: qy });
14462
- px = qx;
14463
- py = qy;
14464
- }
14465
- curX = p3x;
14466
- curY = p3y;
14467
- hasOpenSubpath = true;
14468
- } else if (seg.kind === "close") {
14469
- if (curX !== startX || curY !== startY) {
14470
- edges.push({ x0: curX, y0: curY, x1: startX, y1: startY });
14471
- curX = startX;
14472
- curY = startY;
14473
- }
14474
- hasOpenSubpath = false;
14475
- } else if (seg.kind === "rect") {
14476
- if (closeSubpaths && hasOpenSubpath && (curX !== startX || curY !== startY)) {
14477
- edges.push({ x0: curX, y0: curY, x1: startX, y1: startY });
14478
- }
14479
- const [rx0, ry0] = toScreen(seg.x, seg.y);
14480
- const [rx1, ry1] = toScreen(seg.x + seg.width, seg.y + seg.height);
14481
- edges.push(
14482
- { x0: rx0, y0: ry0, x1: rx1, y1: ry0 },
14483
- { x0: rx1, y0: ry0, x1: rx1, y1: ry1 },
14484
- { x0: rx1, y0: ry1, x1: rx0, y1: ry1 },
14485
- { x0: rx0, y0: ry1, x1: rx0, y1: ry0 }
14486
- );
14487
- hasOpenSubpath = false;
14645
+ for (const segment of segments) {
14646
+ if (segment.kind === "move") {
14647
+ if (points.length) paths.push({ points, closed: false });
14648
+ current = toScreen(segment.x, segment.y);
14649
+ points = [current];
14650
+ } else if (segment.kind === "line") {
14651
+ if (!points.length) points = [current];
14652
+ current = toScreen(segment.x, segment.y);
14653
+ points.push(current);
14654
+ } else if (segment.kind === "cubic") {
14655
+ if (!points.length) points = [current];
14656
+ const a = toScreen(segment.x1, segment.y1), b = toScreen(segment.x2, segment.y2);
14657
+ const end = toScreen(segment.x, segment.y);
14658
+ const curve = flattenCubic(current[0], current[1], a[0], a[1], b[0], b[1], end[0], end[1]);
14659
+ for (let i = 1; i < curve.length; i++) points.push(curve[i]);
14660
+ current = end;
14661
+ } else if (segment.kind === "close") {
14662
+ if (points.length) {
14663
+ paths.push({ points, closed: true });
14664
+ current = points[0];
14665
+ points = [];
14666
+ }
14667
+ } else if (segment.kind === "rect") {
14668
+ if (points.length) paths.push({ points, closed: false });
14669
+ const first = toScreen(segment.x, segment.y);
14670
+ paths.push({ points: [
14671
+ first,
14672
+ toScreen(segment.x + segment.width, segment.y),
14673
+ toScreen(segment.x + segment.width, segment.y + segment.height),
14674
+ toScreen(segment.x, segment.y + segment.height)
14675
+ ], closed: true });
14676
+ current = first;
14677
+ points = [];
14678
+ }
14679
+ }
14680
+ if (points.length) paths.push({ points, closed: false });
14681
+ return paths;
14682
+ }
14683
+ function pathsToEdges(paths, closeSubpaths = false) {
14684
+ const edges = [];
14685
+ for (const { points, closed } of paths) {
14686
+ for (let i = 1; i < points.length; i++) {
14687
+ const a = points[i - 1], b = points[i];
14688
+ edges.push({ x0: a[0], y0: a[1], x1: b[0], y1: b[1] });
14689
+ }
14690
+ if ((closed || closeSubpaths) && points.length > 1) {
14691
+ const a = points[points.length - 1], b = points[0];
14692
+ edges.push({ x0: a[0], y0: a[1], x1: b[0], y1: b[1] });
14488
14693
  }
14489
- }
14490
- if (closeSubpaths && hasOpenSubpath && (curX !== startX || curY !== startY)) {
14491
- edges.push({ x0: curX, y0: curY, x1: startX, y1: startY });
14492
14694
  }
14493
14695
  return edges;
14494
14696
  }
@@ -14599,6 +14801,30 @@ function paintOperations(displayList) {
14599
14801
  ...displayList.glyphs.map((value) => ({ kind: "glyph", value }))
14600
14802
  ];
14601
14803
  }
14804
+ function renderSoftMask(mask, displayList, scale) {
14805
+ const bitmap = renderDisplayListToBitmap({
14806
+ ...displayList,
14807
+ rotation: 0,
14808
+ glyphs: [],
14809
+ paths: [],
14810
+ images: [],
14811
+ operations: mask.operations
14812
+ }, { scale, transparent: true });
14813
+ const { data } = bitmap;
14814
+ for (let i = 0; i < data.length; i += 4) {
14815
+ let value = data[i + 3];
14816
+ if (mask.subtype === "Luminosity") {
14817
+ const alpha = value / 255;
14818
+ const r = Math.round(data[i] * alpha + mask.backdrop.r * 255 * (1 - alpha));
14819
+ const g = Math.round(data[i + 1] * alpha + mask.backdrop.g * 255 * (1 - alpha));
14820
+ const b = Math.round(data[i + 2] * alpha + mask.backdrop.b * 255 * (1 - alpha));
14821
+ value = Math.round(pdfLum(r, g, b));
14822
+ }
14823
+ data[i] = data[i + 1] = data[i + 2] = 0;
14824
+ data[i + 3] = mask.transferMap?.[value] ?? value;
14825
+ }
14826
+ return bitmap;
14827
+ }
14602
14828
  function renderDisplayListToBitmap(displayList, options = {}) {
14603
14829
  const baseScale = options.scale ?? (options.dpi ? options.dpi / 72 : 1.5);
14604
14830
  const scaleX = options.dpiX !== void 0 ? options.dpiX / 72 : baseScale;
@@ -14622,10 +14848,28 @@ function renderDisplayListToBitmap(displayList, options = {}) {
14622
14848
  const aaTxt = options.antialiasText !== false;
14623
14849
  let cachedClips;
14624
14850
  let cachedClipMask;
14851
+ let cachedSoftMask;
14852
+ let cachedSoftMaskPixels;
14625
14853
  const imageClipMasks = /* @__PURE__ */ new Map();
14626
14854
  for (const original of paintOperations(displayList)) {
14627
14855
  if (original.kind === "glyph" && (original.value.renderMode === 3 || !original.value.outline && !original.value.unicode.trim())) continue;
14628
- const operation = original.kind === "glyph" ? { kind: "path", value: glyphPaint(original.value) } : original;
14856
+ let operation = original.kind === "glyph" ? { kind: "path", value: glyphPaint(original.value) } : original;
14857
+ if (operation.kind === "group") {
14858
+ const group = operation.value;
14859
+ const bitmap = renderDisplayListToBitmap({ ...displayList, rotation: 0, operations: group.operations }, { ...options, scale, dpiX: void 0, dpiY: void 0, cropRect: void 0, transparent: true });
14860
+ for (let i = 3; i < bitmap.data.length; i += 4) bitmap.data[i] = Math.round(bitmap.data[i] * group.alpha);
14861
+ operation = { kind: "image", value: {
14862
+ name: "TransparencyGroup",
14863
+ width: bitmap.width,
14864
+ height: bitmap.height,
14865
+ decodedRgba: bitmap.data,
14866
+ matrix: [bitmap.width / scale, 0, 0, bitmap.height / scale, 0, displayList.height - bitmap.height / scale],
14867
+ colorSpace: "DeviceRGB",
14868
+ bitsPerComponent: 8,
14869
+ blendMode: group.blendMode,
14870
+ clipRect: group.clipRect
14871
+ } };
14872
+ }
14629
14873
  const clips = original.value.clipPaths;
14630
14874
  let clipMask = clips && clips === cachedClips ? cachedClipMask : void 0;
14631
14875
  if (clips && !clipMask) {
@@ -14633,12 +14877,25 @@ function renderDisplayListToBitmap(displayList, options = {}) {
14633
14877
  for (const clip of clips) {
14634
14878
  const { segments, fillRule } = "segments" in clip ? clip : { segments: clip, fillRule: "nonzero" };
14635
14879
  const layer = new Uint8Array(width * height * 4);
14636
- fillEdgesScanline4x4(layer, width, height, segmentsToScreenEdges(segments, displayList.height, scale, true), { r: 1, g: 1, b: 1 }, 1, fillRule);
14880
+ fillEdgesScanline4x4(layer, width, height, pathsToEdges(segmentsToScreenPaths(segments, displayList.height, scale), true), { r: 1, g: 1, b: 1 }, 1, fillRule);
14637
14881
  for (let i = 3; i < layer.length; i += 4) clipMask[i] = Math.round(clipMask[i] * layer[i] / 255);
14638
14882
  }
14639
14883
  cachedClips = clips;
14640
14884
  cachedClipMask = clipMask;
14641
14885
  }
14886
+ const softMask = original.value.softMask;
14887
+ if (softMask) {
14888
+ if (softMask !== cachedSoftMask) {
14889
+ cachedSoftMaskPixels = renderSoftMask(softMask, displayList, scale).data;
14890
+ cachedSoftMask = softMask;
14891
+ }
14892
+ if (clipMask) {
14893
+ clipMask = clipMask.slice();
14894
+ for (let i = 3; i < clipMask.length; i += 4) clipMask[i] = Math.round(clipMask[i] * cachedSoftMaskPixels[i] / 255);
14895
+ } else {
14896
+ clipMask = cachedSoftMaskPixels;
14897
+ }
14898
+ }
14642
14899
  const imageClips = original.value.clipImages;
14643
14900
  if (imageClips) {
14644
14901
  let imageMask = imageClipMasks.get(imageClips);
@@ -14667,62 +14924,38 @@ function renderDisplayListToBitmap(displayList, options = {}) {
14667
14924
  if (operation.kind === "path") {
14668
14925
  const path = operation.value;
14669
14926
  if (path.fillColor) {
14670
- const edges = segmentsToScreenEdges(path.segments, displayList.height, scale, true);
14927
+ const edges = pathsToEdges(segmentsToScreenPaths(path.segments, displayList.height, scale), true);
14671
14928
  const clipScreen = path.clipRect ? [path.clipRect[0] * scale, (displayList.height - path.clipRect[3]) * scale, path.clipRect[2] * scale, (displayList.height - path.clipRect[1]) * scale] : void 0;
14672
14929
  fillEdgesScanline4x4(rgba, width, height, edges, path.fillColor, path.fillAlpha ?? 1, path.fillRule ?? "nonzero", clipScreen, original.kind === "glyph" ? aaTxt : aaVec, path.blendMode, clipMask);
14673
14930
  }
14674
14931
  if (path.strokeColor) {
14675
- const edges = segmentsToScreenEdges(path.segments, displayList.height, scale, false);
14676
14932
  const rawSw = path.strokeWidth * scale;
14677
14933
  const sw = Math.max(1, rawSw);
14678
14934
  const strokeAlpha = options.thinLineMode === "shape" && rawSw < 1 ? (path.strokeAlpha ?? 1) * Math.max(0.25, rawSw) : path.strokeAlpha ?? 1;
14679
- const dashArr = path.dashArray && path.dashArray.length > 0 ? path.dashArray.map((d) => Math.max(0, d * scale)) : void 0;
14680
- const dashCycle = dashArr ? dashArr.reduce((a, b) => a + b, 0) : 0;
14681
- let dashDist = (path.dashPhase ?? 0) * scale % (dashCycle || 1);
14682
- if (dashDist < 0) dashDist += dashCycle;
14683
- for (const e of edges) {
14684
- if (!dashArr || dashCycle <= 1e-4) {
14685
- drawAntiAliasedSegment(rgba, width, height, e.x0, e.y0, e.x1, e.y1, sw, path.strokeColor, strokeAlpha, path.lineCap ?? 0, original.kind === "glyph" ? aaTxt : aaVec, path.blendMode, clipMask);
14686
- } else {
14687
- const dx = e.x1 - e.x0;
14688
- const dy = e.y1 - e.y0;
14689
- const edgeLen = Math.hypot(dx, dy);
14690
- if (edgeLen <= 1e-4) continue;
14691
- let pos = 0;
14692
- while (pos < edgeLen) {
14693
- let cycleRem = dashDist % dashCycle;
14694
- let dIdx = 0;
14695
- while (dIdx < dashArr.length - 1 && cycleRem >= dashArr[dIdx]) {
14696
- cycleRem -= dashArr[dIdx];
14697
- dIdx++;
14698
- }
14699
- const segRemainInDash = Math.max(1e-4, dashArr[dIdx] - cycleRem);
14700
- const step = Math.min(edgeLen - pos, segRemainInDash);
14701
- if (dIdx % 2 === 0) {
14702
- const t0 = pos / edgeLen;
14703
- const t1 = (pos + step) / edgeLen;
14704
- drawAntiAliasedSegment(
14705
- rgba,
14706
- width,
14707
- height,
14708
- e.x0 + dx * t0,
14709
- e.y0 + dy * t0,
14710
- e.x0 + dx * t1,
14711
- e.y0 + dy * t1,
14712
- sw,
14713
- path.strokeColor,
14714
- strokeAlpha,
14715
- path.lineCap ?? 0,
14716
- original.kind === "glyph" ? aaTxt : aaVec,
14717
- path.blendMode,
14718
- clipMask
14719
- );
14720
- }
14721
- pos += step;
14722
- dashDist = (dashDist + step) % dashCycle;
14723
- }
14724
- }
14725
- }
14935
+ const contours = strokeOutlines(
14936
+ segmentsToScreenPaths(path.segments, displayList.height, scale),
14937
+ sw,
14938
+ path.lineCap ?? 0,
14939
+ path.lineJoin ?? 0,
14940
+ path.miterLimit ?? 10,
14941
+ path.dashArray?.map((value) => Math.max(0, value * scale)),
14942
+ (path.dashPhase ?? 0) * scale
14943
+ );
14944
+ const edges = pathsToEdges(contours.map((points) => ({ points, closed: true })));
14945
+ const clipScreen = path.clipRect ? [path.clipRect[0] * scale, (displayList.height - path.clipRect[3]) * scale, path.clipRect[2] * scale, (displayList.height - path.clipRect[1]) * scale] : void 0;
14946
+ fillEdgesScanline4x4(
14947
+ rgba,
14948
+ width,
14949
+ height,
14950
+ edges,
14951
+ path.strokeColor,
14952
+ strokeAlpha,
14953
+ "nonzero",
14954
+ clipScreen,
14955
+ original.kind === "glyph" ? aaTxt : aaVec,
14956
+ path.blendMode,
14957
+ clipMask
14958
+ );
14726
14959
  }
14727
14960
  } else if (operation.kind === "image") {
14728
14961
  const img = operation.value;
@@ -15390,6 +15623,7 @@ var __webpack_exports__getVerbosityLevel;
15390
15623
  var __webpack_exports__setVerbosityLevel;
15391
15624
  var ACROFORM_FONT_ALIAS_MAP;
15392
15625
  var PdfPage;
15626
+ var MAX_STROKE_VERTICES;
15393
15627
  var STD_LUMINANCE_QUANT;
15394
15628
  var ZIGZAG_ORDER;
15395
15629
  var STD_DC_LUMA_NRCODES;
@@ -41323,6 +41557,7 @@ var init_dist = __esm({
41323
41557
  return renderDisplayListToPng(this.evaluateDisplayList(), options);
41324
41558
  }
41325
41559
  };
41560
+ MAX_STROKE_VERTICES = 1e6;
41326
41561
  STD_LUMINANCE_QUANT = new Uint8Array([
41327
41562
  16,
41328
41563
  11,
@@ -43406,3 +43641,15 @@ export {
43406
43641
  * Copyright 2012 Mozilla Foundation. Licensed under Apache-2.0.
43407
43642
  * See THIRD_PARTY_NOTICES.md for the source revision and adaptations.
43408
43643
  */
43644
+ /*!
43645
+ * Anti-Grain Geometry - Version 2.3
43646
+ * Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
43647
+ *
43648
+ * Permission to copy, use, modify, sell and distribute this software
43649
+ * is granted provided this copyright notice appears in all copies.
43650
+ * This software is provided "as is" without express or implied
43651
+ * warranty, and with no claim as to its suitability for any purpose.
43652
+ *
43653
+ * Adapted from PDFium agg_math_stroke.h and agg_vcgen_stroke.cpp.
43654
+ * See THIRD_PARTY_NOTICES.md for the source revision and adaptations.
43655
+ */