@poe-platform/safe-bash 0.1.765 → 0.1.767
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.
- package/dist/image-ast/index.browser.js +42 -18
- package/dist/image-ast/index.js +42 -18
- package/dist/pdf-ast/ast.d.ts +1 -1
- package/dist/pdf-ast/index.js +56 -21
- package/dist/safe-bash/command-chunks/{chunk-KO4PXCNL.js → chunk-2JQONXIY.js} +42 -18
- package/dist/safe-bash/command-chunks/{chunk-SVL6HYQL.js → chunk-A5S6M37L.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-DT4MFWV4.js → chunk-G55GHZV2.js} +2 -2
- package/dist/safe-bash-command-ffmpeg/index.js +4494 -4480
- package/dist/safe-bash-command-imagemagick/index.js +2 -2
- package/dist/safe-bash-command-pandoc/command.js +3 -3
- package/dist/safe-bash-command-pandoc/index.js +3 -3
- package/dist/safe-bash-command-pdfimages/index.js +42 -18
- package/dist/safe-bash-command-pdfinfo/index.js +56 -21
- package/dist/safe-bash-command-pdftk/index.js +42 -18
- package/dist/safe-bash-command-pdftoppm/index.js +56 -21
- package/dist/safe-bash-command-pdftotext/index.js +42 -18
- package/dist/safe-bash-command-qpdf/index.js +42 -18
- package/dist/safe-bash-command-sips/index.js +2 -2
- package/dist/safe-bash-command-soffice/index.js +1 -1
- package/dist/safe-bash-command-ssconvert/index.js +48 -27
- package/dist/safe-bash-command-wkhtmltopdf/index.js +42 -18
- package/package.json +2 -2
- package/third-party/pdf-ast/THIRD_PARTY_NOTICES.md +12 -0
|
@@ -43838,10 +43838,11 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
43838
43838
|
const patArr = params.cosDoc.resolveArray(dArr.items[0]);
|
|
43839
43839
|
const phaseNode = params.cosDoc.resolve(dArr.items[1]);
|
|
43840
43840
|
if (patArr) {
|
|
43841
|
-
|
|
43841
|
+
const dashArray = patArr.items.map((it) => {
|
|
43842
43842
|
const r = params.cosDoc.resolve(it);
|
|
43843
43843
|
return r?.kind === "number" ? r.value : 0;
|
|
43844
|
-
}).filter((n) => n
|
|
43844
|
+
}).filter((n) => n >= 0);
|
|
43845
|
+
st.dashArray = dashArray.some((value) => value > 0) ? dashArray : void 0;
|
|
43845
43846
|
st.dashPhase = phaseNode?.kind === "number" ? phaseNode.value : 0;
|
|
43846
43847
|
}
|
|
43847
43848
|
}
|
|
@@ -43896,8 +43897,9 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
43896
43897
|
const st = curState();
|
|
43897
43898
|
const group = params.cosDoc.resolveDict(dictGet(form.dict, "Group"));
|
|
43898
43899
|
const groupType = group ? params.cosDoc.resolve(dictGet(group, "S")) : void 0;
|
|
43899
|
-
const
|
|
43900
|
-
const
|
|
43900
|
+
const isolation = group ? params.cosDoc.resolve(dictGet(group, "I")) : void 0;
|
|
43901
|
+
const isolated = isolation?.kind === "boolean" && isolation.value;
|
|
43902
|
+
const compositeGroup = !maskGroup && groupType?.kind === "name" && groupType.decoded === "Transparency" && (isolated || st.fillAlpha !== 1 || !!st.softMask || st.blendMode !== "Normal" && st.blendMode !== "Compatible");
|
|
43901
43903
|
const formStreamBytes = params.cosDoc.decodeStream(form);
|
|
43902
43904
|
const formNodes = parseContentStream(formStreamBytes);
|
|
43903
43905
|
const formResDict = params.cosDoc.resolveDict(dictGet(form.dict, "Resources")) ?? activeResources;
|
|
@@ -43915,8 +43917,8 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
43915
43917
|
const formMat = [mn(0, 1), mn(1, 0), mn(2, 0), mn(3, 1), mn(4, 0), mn(5, 0)];
|
|
43916
43918
|
nextCtm = multiplyMatrices(formMat, nextCtm);
|
|
43917
43919
|
}
|
|
43918
|
-
let nextClip = !
|
|
43919
|
-
let nextClipPaths =
|
|
43920
|
+
let nextClip = !compositeGroup && st.clipRect ? [...st.clipRect] : void 0;
|
|
43921
|
+
let nextClipPaths = compositeGroup ? void 0 : st.clipPaths;
|
|
43920
43922
|
const bboxArr = params.cosDoc.resolveArray(dictGet(form.dict, "BBox"));
|
|
43921
43923
|
if (bboxArr && bboxArr.items.length >= 4) {
|
|
43922
43924
|
const bn = (idx, fb = 0) => {
|
|
@@ -43950,7 +43952,7 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
43950
43952
|
const parentOperations = capturedOperations;
|
|
43951
43953
|
const children = [];
|
|
43952
43954
|
const nextState = { ...st, ctm: nextCtm };
|
|
43953
|
-
if (
|
|
43955
|
+
if (compositeGroup) {
|
|
43954
43956
|
capturedOperations = children;
|
|
43955
43957
|
nextState.fillAlpha = nextState.strokeAlpha = 1;
|
|
43956
43958
|
nextState.blendMode = "Normal";
|
|
@@ -43968,7 +43970,7 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
43968
43970
|
stateStack.pop();
|
|
43969
43971
|
capturedOperations = parentOperations;
|
|
43970
43972
|
}
|
|
43971
|
-
if (
|
|
43973
|
+
if (compositeGroup) emit({ kind: "group", value: { operations: children, alpha: st.fillAlpha, blendMode: st.blendMode, clipRect: st.clipRect } });
|
|
43972
43974
|
};
|
|
43973
43975
|
const walkNodes = (nodes, mcid, actualText, activeResources = params.resourcesDict, activeFonts = fonts, depth = 0) => {
|
|
43974
43976
|
for (const node of nodes) {
|
|
@@ -46845,7 +46847,7 @@ function dashSubpath(path, pattern, phase) {
|
|
|
46845
46847
|
while (remaining <= 0) {
|
|
46846
46848
|
if (++steps > MAX_STROKE_VERTICES) throw new PdfError("E_LIMIT", "Stroke dash expansion exceeds the vertex limit");
|
|
46847
46849
|
if (index % 2 === 0) {
|
|
46848
|
-
if (pattern[index] === 0) result.push({ points: [point, point], closed: false });
|
|
46850
|
+
if (pattern[index] === 0) result.push({ points: [point, point], closed: false, zeroLengthDash: true });
|
|
46849
46851
|
flush();
|
|
46850
46852
|
}
|
|
46851
46853
|
index = (index + 1) % pattern.length;
|
|
@@ -46860,7 +46862,7 @@ function dashSubpath(path, pattern, phase) {
|
|
|
46860
46862
|
throw new PdfError("E_LIMIT", "Stroke dash expansion exceeds the vertex limit");
|
|
46861
46863
|
}
|
|
46862
46864
|
let distance = 0;
|
|
46863
|
-
while (distance
|
|
46865
|
+
while (length - distance > 8 * Number.EPSILON * Math.max(1, length)) {
|
|
46864
46866
|
const point = [start[0] + dx * distance / length, start[1] + dy * distance / length];
|
|
46865
46867
|
advance(point);
|
|
46866
46868
|
const step = Math.min(remaining, length - distance);
|
|
@@ -46975,7 +46977,15 @@ function strokeOutlines(paths, width, cap, join, miterLimit, dashArray = [], das
|
|
|
46975
46977
|
let closed = subpath.closed;
|
|
46976
46978
|
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();
|
|
46977
46979
|
if (points.length < 3) closed = false;
|
|
46978
|
-
if (points.length === 1 &&
|
|
46980
|
+
if (points.length === 1 && cap === 2 && subpath.zeroLengthDash) {
|
|
46981
|
+
contour = [];
|
|
46982
|
+
const [x, y] = points[0];
|
|
46983
|
+
add(x - half, y - half);
|
|
46984
|
+
add(x + half, y - half);
|
|
46985
|
+
add(x + half, y + half);
|
|
46986
|
+
add(x - half, y + half);
|
|
46987
|
+
contours.push(contour);
|
|
46988
|
+
} else if (points.length === 1 && subpath.points.length > 1 && cap === 1) {
|
|
46979
46989
|
contour = [];
|
|
46980
46990
|
const [x, y] = points[0];
|
|
46981
46991
|
addCap([x, y], [x + 1, y]);
|
|
@@ -47767,7 +47777,7 @@ function prepareStroke(path, scale) {
|
|
|
47767
47777
|
}
|
|
47768
47778
|
return { matrix, width, dashArray, dashPhase };
|
|
47769
47779
|
}
|
|
47770
|
-
function
|
|
47780
|
+
function strokeContours(path, pageHeight, scale) {
|
|
47771
47781
|
const stroke = prepareStroke(path, scale);
|
|
47772
47782
|
if (!stroke) return [];
|
|
47773
47783
|
const inverse = inverseStrokeMatrix(stroke.matrix);
|
|
@@ -47791,7 +47801,7 @@ function strokeEdges(path, pageHeight, scale) {
|
|
|
47791
47801
|
stroke.dashArray?.map((value) => Math.max(0, value * strokeScale)),
|
|
47792
47802
|
stroke.dashPhase * strokeScale
|
|
47793
47803
|
);
|
|
47794
|
-
return
|
|
47804
|
+
return contours.map((points) => points.map(toScreen));
|
|
47795
47805
|
}
|
|
47796
47806
|
function pathsToEdges(paths, closeSubpaths = false) {
|
|
47797
47807
|
const edges = [];
|
|
@@ -47938,6 +47948,9 @@ function renderSoftMask(mask, displayList, scale) {
|
|
|
47938
47948
|
}
|
|
47939
47949
|
return bitmap;
|
|
47940
47950
|
}
|
|
47951
|
+
function hasBlendModes(operations) {
|
|
47952
|
+
return operations.some((operation) => !!operation.value.blendMode && operation.value.blendMode !== "Normal" && operation.value.blendMode !== "Compatible" || operation.kind === "group" && hasBlendModes(operation.value.operations));
|
|
47953
|
+
}
|
|
47941
47954
|
function renderDisplayListToBitmap(displayList, options = {}) {
|
|
47942
47955
|
const baseScale = options.scale ?? (options.dpi ? options.dpi / 72 : 1.5);
|
|
47943
47956
|
const scaleX = options.dpiX !== void 0 ? options.dpiX / 72 : baseScale;
|
|
@@ -47946,11 +47959,13 @@ function renderDisplayListToBitmap(displayList, options = {}) {
|
|
|
47946
47959
|
const width = Math.max(1, Math.round(displayList.width * scale));
|
|
47947
47960
|
const height = Math.max(1, Math.round(displayList.height * scale));
|
|
47948
47961
|
const rgba = new Uint8Array(width * height * 4);
|
|
47962
|
+
const deferBackground = !options.transparent && hasBlendModes(paintOperations(displayList));
|
|
47963
|
+
const transparent = options.transparent || deferBackground;
|
|
47949
47964
|
const bg = options.background ?? { r: 1, g: 1, b: 1 };
|
|
47950
|
-
const bgR =
|
|
47951
|
-
const bgG =
|
|
47952
|
-
const bgB =
|
|
47953
|
-
const bgA =
|
|
47965
|
+
const bgR = transparent ? 0 : Math.round(bg.r * 255);
|
|
47966
|
+
const bgG = transparent ? 0 : Math.round(bg.g * 255);
|
|
47967
|
+
const bgB = transparent ? 0 : Math.round(bg.b * 255);
|
|
47968
|
+
const bgA = transparent ? 0 : 255;
|
|
47954
47969
|
for (let i = 0; i < width * height; i++) {
|
|
47955
47970
|
rgba[i * 4] = bgR;
|
|
47956
47971
|
rgba[i * 4 + 1] = bgG;
|
|
@@ -48044,7 +48059,7 @@ function renderDisplayListToBitmap(displayList, options = {}) {
|
|
|
48044
48059
|
if (path.strokeColor) {
|
|
48045
48060
|
const rawSw = path.strokeWidth * scale * (path.strokeMatrix ? Math.hypot(path.strokeMatrix[0], path.strokeMatrix[1]) : 1);
|
|
48046
48061
|
const strokeAlpha = options.thinLineMode === "shape" && rawSw < 1 ? (path.strokeAlpha ?? 1) * Math.max(0.25, rawSw) : path.strokeAlpha ?? 1;
|
|
48047
|
-
const edges =
|
|
48062
|
+
const edges = pathsToEdges(strokeContours(path, displayList.height, scale).map((points) => ({ points, closed: true })));
|
|
48048
48063
|
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;
|
|
48049
48064
|
fillEdgesScanline4x4(
|
|
48050
48065
|
rgba,
|
|
@@ -48127,6 +48142,15 @@ function renderDisplayListToBitmap(displayList, options = {}) {
|
|
|
48127
48142
|
}
|
|
48128
48143
|
}
|
|
48129
48144
|
}
|
|
48145
|
+
if (deferBackground) {
|
|
48146
|
+
for (let i = 0; i < rgba.length; i += 4) {
|
|
48147
|
+
const alpha = rgba[i + 3] / 255;
|
|
48148
|
+
rgba[i] = Math.round(rgba[i] * alpha + bg.r * 255 * (1 - alpha));
|
|
48149
|
+
rgba[i + 1] = Math.round(rgba[i + 1] * alpha + bg.g * 255 * (1 - alpha));
|
|
48150
|
+
rgba[i + 2] = Math.round(rgba[i + 2] * alpha + bg.b * 255 * (1 - alpha));
|
|
48151
|
+
rgba[i + 3] = 255;
|
|
48152
|
+
}
|
|
48153
|
+
}
|
|
48130
48154
|
let result = { width, height, data: rgba };
|
|
48131
48155
|
if (Math.abs(scaleX - scaleY) > 1e-6) {
|
|
48132
48156
|
const targetW = Math.max(1, Math.round(displayList.width * scaleX));
|
package/dist/image-ast/index.js
CHANGED
|
@@ -43838,10 +43838,11 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
43838
43838
|
const patArr = params.cosDoc.resolveArray(dArr.items[0]);
|
|
43839
43839
|
const phaseNode = params.cosDoc.resolve(dArr.items[1]);
|
|
43840
43840
|
if (patArr) {
|
|
43841
|
-
|
|
43841
|
+
const dashArray = patArr.items.map((it) => {
|
|
43842
43842
|
const r = params.cosDoc.resolve(it);
|
|
43843
43843
|
return r?.kind === "number" ? r.value : 0;
|
|
43844
|
-
}).filter((n) => n
|
|
43844
|
+
}).filter((n) => n >= 0);
|
|
43845
|
+
st.dashArray = dashArray.some((value) => value > 0) ? dashArray : void 0;
|
|
43845
43846
|
st.dashPhase = phaseNode?.kind === "number" ? phaseNode.value : 0;
|
|
43846
43847
|
}
|
|
43847
43848
|
}
|
|
@@ -43896,8 +43897,9 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
43896
43897
|
const st = curState();
|
|
43897
43898
|
const group = params.cosDoc.resolveDict(dictGet(form.dict, "Group"));
|
|
43898
43899
|
const groupType = group ? params.cosDoc.resolve(dictGet(group, "S")) : void 0;
|
|
43899
|
-
const
|
|
43900
|
-
const
|
|
43900
|
+
const isolation = group ? params.cosDoc.resolve(dictGet(group, "I")) : void 0;
|
|
43901
|
+
const isolated = isolation?.kind === "boolean" && isolation.value;
|
|
43902
|
+
const compositeGroup = !maskGroup && groupType?.kind === "name" && groupType.decoded === "Transparency" && (isolated || st.fillAlpha !== 1 || !!st.softMask || st.blendMode !== "Normal" && st.blendMode !== "Compatible");
|
|
43901
43903
|
const formStreamBytes = params.cosDoc.decodeStream(form);
|
|
43902
43904
|
const formNodes = parseContentStream(formStreamBytes);
|
|
43903
43905
|
const formResDict = params.cosDoc.resolveDict(dictGet(form.dict, "Resources")) ?? activeResources;
|
|
@@ -43915,8 +43917,8 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
43915
43917
|
const formMat = [mn(0, 1), mn(1, 0), mn(2, 0), mn(3, 1), mn(4, 0), mn(5, 0)];
|
|
43916
43918
|
nextCtm = multiplyMatrices(formMat, nextCtm);
|
|
43917
43919
|
}
|
|
43918
|
-
let nextClip = !
|
|
43919
|
-
let nextClipPaths =
|
|
43920
|
+
let nextClip = !compositeGroup && st.clipRect ? [...st.clipRect] : void 0;
|
|
43921
|
+
let nextClipPaths = compositeGroup ? void 0 : st.clipPaths;
|
|
43920
43922
|
const bboxArr = params.cosDoc.resolveArray(dictGet(form.dict, "BBox"));
|
|
43921
43923
|
if (bboxArr && bboxArr.items.length >= 4) {
|
|
43922
43924
|
const bn = (idx, fb = 0) => {
|
|
@@ -43950,7 +43952,7 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
43950
43952
|
const parentOperations = capturedOperations;
|
|
43951
43953
|
const children = [];
|
|
43952
43954
|
const nextState = { ...st, ctm: nextCtm };
|
|
43953
|
-
if (
|
|
43955
|
+
if (compositeGroup) {
|
|
43954
43956
|
capturedOperations = children;
|
|
43955
43957
|
nextState.fillAlpha = nextState.strokeAlpha = 1;
|
|
43956
43958
|
nextState.blendMode = "Normal";
|
|
@@ -43968,7 +43970,7 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
43968
43970
|
stateStack.pop();
|
|
43969
43971
|
capturedOperations = parentOperations;
|
|
43970
43972
|
}
|
|
43971
|
-
if (
|
|
43973
|
+
if (compositeGroup) emit({ kind: "group", value: { operations: children, alpha: st.fillAlpha, blendMode: st.blendMode, clipRect: st.clipRect } });
|
|
43972
43974
|
};
|
|
43973
43975
|
const walkNodes = (nodes, mcid, actualText, activeResources = params.resourcesDict, activeFonts = fonts, depth = 0) => {
|
|
43974
43976
|
for (const node of nodes) {
|
|
@@ -46845,7 +46847,7 @@ function dashSubpath(path, pattern, phase) {
|
|
|
46845
46847
|
while (remaining <= 0) {
|
|
46846
46848
|
if (++steps > MAX_STROKE_VERTICES) throw new PdfError("E_LIMIT", "Stroke dash expansion exceeds the vertex limit");
|
|
46847
46849
|
if (index % 2 === 0) {
|
|
46848
|
-
if (pattern[index] === 0) result.push({ points: [point, point], closed: false });
|
|
46850
|
+
if (pattern[index] === 0) result.push({ points: [point, point], closed: false, zeroLengthDash: true });
|
|
46849
46851
|
flush();
|
|
46850
46852
|
}
|
|
46851
46853
|
index = (index + 1) % pattern.length;
|
|
@@ -46860,7 +46862,7 @@ function dashSubpath(path, pattern, phase) {
|
|
|
46860
46862
|
throw new PdfError("E_LIMIT", "Stroke dash expansion exceeds the vertex limit");
|
|
46861
46863
|
}
|
|
46862
46864
|
let distance = 0;
|
|
46863
|
-
while (distance
|
|
46865
|
+
while (length - distance > 8 * Number.EPSILON * Math.max(1, length)) {
|
|
46864
46866
|
const point = [start[0] + dx * distance / length, start[1] + dy * distance / length];
|
|
46865
46867
|
advance(point);
|
|
46866
46868
|
const step = Math.min(remaining, length - distance);
|
|
@@ -46975,7 +46977,15 @@ function strokeOutlines(paths, width, cap, join, miterLimit, dashArray = [], das
|
|
|
46975
46977
|
let closed = subpath.closed;
|
|
46976
46978
|
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();
|
|
46977
46979
|
if (points.length < 3) closed = false;
|
|
46978
|
-
if (points.length === 1 &&
|
|
46980
|
+
if (points.length === 1 && cap === 2 && subpath.zeroLengthDash) {
|
|
46981
|
+
contour = [];
|
|
46982
|
+
const [x, y] = points[0];
|
|
46983
|
+
add(x - half, y - half);
|
|
46984
|
+
add(x + half, y - half);
|
|
46985
|
+
add(x + half, y + half);
|
|
46986
|
+
add(x - half, y + half);
|
|
46987
|
+
contours.push(contour);
|
|
46988
|
+
} else if (points.length === 1 && subpath.points.length > 1 && cap === 1) {
|
|
46979
46989
|
contour = [];
|
|
46980
46990
|
const [x, y] = points[0];
|
|
46981
46991
|
addCap([x, y], [x + 1, y]);
|
|
@@ -47767,7 +47777,7 @@ function prepareStroke(path, scale) {
|
|
|
47767
47777
|
}
|
|
47768
47778
|
return { matrix, width, dashArray, dashPhase };
|
|
47769
47779
|
}
|
|
47770
|
-
function
|
|
47780
|
+
function strokeContours(path, pageHeight, scale) {
|
|
47771
47781
|
const stroke = prepareStroke(path, scale);
|
|
47772
47782
|
if (!stroke) return [];
|
|
47773
47783
|
const inverse = inverseStrokeMatrix(stroke.matrix);
|
|
@@ -47791,7 +47801,7 @@ function strokeEdges(path, pageHeight, scale) {
|
|
|
47791
47801
|
stroke.dashArray?.map((value) => Math.max(0, value * strokeScale)),
|
|
47792
47802
|
stroke.dashPhase * strokeScale
|
|
47793
47803
|
);
|
|
47794
|
-
return
|
|
47804
|
+
return contours.map((points) => points.map(toScreen));
|
|
47795
47805
|
}
|
|
47796
47806
|
function pathsToEdges(paths, closeSubpaths = false) {
|
|
47797
47807
|
const edges = [];
|
|
@@ -47938,6 +47948,9 @@ function renderSoftMask(mask, displayList, scale) {
|
|
|
47938
47948
|
}
|
|
47939
47949
|
return bitmap;
|
|
47940
47950
|
}
|
|
47951
|
+
function hasBlendModes(operations) {
|
|
47952
|
+
return operations.some((operation) => !!operation.value.blendMode && operation.value.blendMode !== "Normal" && operation.value.blendMode !== "Compatible" || operation.kind === "group" && hasBlendModes(operation.value.operations));
|
|
47953
|
+
}
|
|
47941
47954
|
function renderDisplayListToBitmap(displayList, options = {}) {
|
|
47942
47955
|
const baseScale = options.scale ?? (options.dpi ? options.dpi / 72 : 1.5);
|
|
47943
47956
|
const scaleX = options.dpiX !== void 0 ? options.dpiX / 72 : baseScale;
|
|
@@ -47946,11 +47959,13 @@ function renderDisplayListToBitmap(displayList, options = {}) {
|
|
|
47946
47959
|
const width = Math.max(1, Math.round(displayList.width * scale));
|
|
47947
47960
|
const height = Math.max(1, Math.round(displayList.height * scale));
|
|
47948
47961
|
const rgba = new Uint8Array(width * height * 4);
|
|
47962
|
+
const deferBackground = !options.transparent && hasBlendModes(paintOperations(displayList));
|
|
47963
|
+
const transparent = options.transparent || deferBackground;
|
|
47949
47964
|
const bg = options.background ?? { r: 1, g: 1, b: 1 };
|
|
47950
|
-
const bgR =
|
|
47951
|
-
const bgG =
|
|
47952
|
-
const bgB =
|
|
47953
|
-
const bgA =
|
|
47965
|
+
const bgR = transparent ? 0 : Math.round(bg.r * 255);
|
|
47966
|
+
const bgG = transparent ? 0 : Math.round(bg.g * 255);
|
|
47967
|
+
const bgB = transparent ? 0 : Math.round(bg.b * 255);
|
|
47968
|
+
const bgA = transparent ? 0 : 255;
|
|
47954
47969
|
for (let i = 0; i < width * height; i++) {
|
|
47955
47970
|
rgba[i * 4] = bgR;
|
|
47956
47971
|
rgba[i * 4 + 1] = bgG;
|
|
@@ -48044,7 +48059,7 @@ function renderDisplayListToBitmap(displayList, options = {}) {
|
|
|
48044
48059
|
if (path.strokeColor) {
|
|
48045
48060
|
const rawSw = path.strokeWidth * scale * (path.strokeMatrix ? Math.hypot(path.strokeMatrix[0], path.strokeMatrix[1]) : 1);
|
|
48046
48061
|
const strokeAlpha = options.thinLineMode === "shape" && rawSw < 1 ? (path.strokeAlpha ?? 1) * Math.max(0.25, rawSw) : path.strokeAlpha ?? 1;
|
|
48047
|
-
const edges =
|
|
48062
|
+
const edges = pathsToEdges(strokeContours(path, displayList.height, scale).map((points) => ({ points, closed: true })));
|
|
48048
48063
|
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;
|
|
48049
48064
|
fillEdgesScanline4x4(
|
|
48050
48065
|
rgba,
|
|
@@ -48127,6 +48142,15 @@ function renderDisplayListToBitmap(displayList, options = {}) {
|
|
|
48127
48142
|
}
|
|
48128
48143
|
}
|
|
48129
48144
|
}
|
|
48145
|
+
if (deferBackground) {
|
|
48146
|
+
for (let i = 0; i < rgba.length; i += 4) {
|
|
48147
|
+
const alpha = rgba[i + 3] / 255;
|
|
48148
|
+
rgba[i] = Math.round(rgba[i] * alpha + bg.r * 255 * (1 - alpha));
|
|
48149
|
+
rgba[i + 1] = Math.round(rgba[i + 1] * alpha + bg.g * 255 * (1 - alpha));
|
|
48150
|
+
rgba[i + 2] = Math.round(rgba[i + 2] * alpha + bg.b * 255 * (1 - alpha));
|
|
48151
|
+
rgba[i + 3] = 255;
|
|
48152
|
+
}
|
|
48153
|
+
}
|
|
48130
48154
|
let result = { width, height, data: rgba };
|
|
48131
48155
|
if (Math.abs(scaleX - scaleY) > 1e-6) {
|
|
48132
48156
|
const targetW = Math.max(1, Math.round(displayList.width * scaleX));
|
package/dist/pdf-ast/ast.d.ts
CHANGED
|
@@ -294,7 +294,7 @@ export type PdfPaintOperation = {
|
|
|
294
294
|
readonly kind: "group";
|
|
295
295
|
readonly value: PdfPaintGroup;
|
|
296
296
|
};
|
|
297
|
-
/**
|
|
297
|
+
/** A transparency Form, composited after painting its children. */
|
|
298
298
|
export interface PdfPaintGroup {
|
|
299
299
|
readonly operations: readonly PdfPaintOperation[];
|
|
300
300
|
readonly alpha: number;
|
package/dist/pdf-ast/index.js
CHANGED
|
@@ -36552,10 +36552,11 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36552
36552
|
const patArr = params.cosDoc.resolveArray(dArr.items[0]);
|
|
36553
36553
|
const phaseNode = params.cosDoc.resolve(dArr.items[1]);
|
|
36554
36554
|
if (patArr) {
|
|
36555
|
-
|
|
36555
|
+
const dashArray = patArr.items.map((it) => {
|
|
36556
36556
|
const r = params.cosDoc.resolve(it);
|
|
36557
36557
|
return r?.kind === "number" ? r.value : 0;
|
|
36558
|
-
}).filter((n) => n
|
|
36558
|
+
}).filter((n) => n >= 0);
|
|
36559
|
+
st.dashArray = dashArray.some((value) => value > 0) ? dashArray : void 0;
|
|
36559
36560
|
st.dashPhase = phaseNode?.kind === "number" ? phaseNode.value : 0;
|
|
36560
36561
|
}
|
|
36561
36562
|
}
|
|
@@ -36610,8 +36611,9 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36610
36611
|
const st = curState();
|
|
36611
36612
|
const group = params.cosDoc.resolveDict(dictGet(form.dict, "Group"));
|
|
36612
36613
|
const groupType = group ? params.cosDoc.resolve(dictGet(group, "S")) : void 0;
|
|
36613
|
-
const
|
|
36614
|
-
const
|
|
36614
|
+
const isolation = group ? params.cosDoc.resolve(dictGet(group, "I")) : void 0;
|
|
36615
|
+
const isolated = isolation?.kind === "boolean" && isolation.value;
|
|
36616
|
+
const compositeGroup = !maskGroup && groupType?.kind === "name" && groupType.decoded === "Transparency" && (isolated || st.fillAlpha !== 1 || !!st.softMask || st.blendMode !== "Normal" && st.blendMode !== "Compatible");
|
|
36615
36617
|
const formStreamBytes = params.cosDoc.decodeStream(form);
|
|
36616
36618
|
const formNodes = parseContentStream(formStreamBytes);
|
|
36617
36619
|
const formResDict = params.cosDoc.resolveDict(dictGet(form.dict, "Resources")) ?? activeResources;
|
|
@@ -36629,8 +36631,8 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36629
36631
|
const formMat = [mn(0, 1), mn(1, 0), mn(2, 0), mn(3, 1), mn(4, 0), mn(5, 0)];
|
|
36630
36632
|
nextCtm = multiplyMatrices(formMat, nextCtm);
|
|
36631
36633
|
}
|
|
36632
|
-
let nextClip = !
|
|
36633
|
-
let nextClipPaths =
|
|
36634
|
+
let nextClip = !compositeGroup && st.clipRect ? [...st.clipRect] : void 0;
|
|
36635
|
+
let nextClipPaths = compositeGroup ? void 0 : st.clipPaths;
|
|
36634
36636
|
const bboxArr = params.cosDoc.resolveArray(dictGet(form.dict, "BBox"));
|
|
36635
36637
|
if (bboxArr && bboxArr.items.length >= 4) {
|
|
36636
36638
|
const bn = (idx, fb = 0) => {
|
|
@@ -36664,7 +36666,7 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36664
36666
|
const parentOperations = capturedOperations;
|
|
36665
36667
|
const children = [];
|
|
36666
36668
|
const nextState = { ...st, ctm: nextCtm };
|
|
36667
|
-
if (
|
|
36669
|
+
if (compositeGroup) {
|
|
36668
36670
|
capturedOperations = children;
|
|
36669
36671
|
nextState.fillAlpha = nextState.strokeAlpha = 1;
|
|
36670
36672
|
nextState.blendMode = "Normal";
|
|
@@ -36682,7 +36684,7 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36682
36684
|
stateStack.pop();
|
|
36683
36685
|
capturedOperations = parentOperations;
|
|
36684
36686
|
}
|
|
36685
|
-
if (
|
|
36687
|
+
if (compositeGroup) emit({ kind: "group", value: { operations: children, alpha: st.fillAlpha, blendMode: st.blendMode, clipRect: st.clipRect } });
|
|
36686
36688
|
};
|
|
36687
36689
|
const walkNodes = (nodes, mcid, actualText, activeResources = params.resourcesDict, activeFonts = fonts, depth = 0) => {
|
|
36688
36690
|
for (const node of nodes) {
|
|
@@ -40254,7 +40256,7 @@ function dashSubpath(path, pattern, phase) {
|
|
|
40254
40256
|
while (remaining <= 0) {
|
|
40255
40257
|
if (++steps > MAX_STROKE_VERTICES) throw new PdfError("E_LIMIT", "Stroke dash expansion exceeds the vertex limit");
|
|
40256
40258
|
if (index % 2 === 0) {
|
|
40257
|
-
if (pattern[index] === 0) result.push({ points: [point, point], closed: false });
|
|
40259
|
+
if (pattern[index] === 0) result.push({ points: [point, point], closed: false, zeroLengthDash: true });
|
|
40258
40260
|
flush();
|
|
40259
40261
|
}
|
|
40260
40262
|
index = (index + 1) % pattern.length;
|
|
@@ -40269,7 +40271,7 @@ function dashSubpath(path, pattern, phase) {
|
|
|
40269
40271
|
throw new PdfError("E_LIMIT", "Stroke dash expansion exceeds the vertex limit");
|
|
40270
40272
|
}
|
|
40271
40273
|
let distance = 0;
|
|
40272
|
-
while (distance
|
|
40274
|
+
while (length - distance > 8 * Number.EPSILON * Math.max(1, length)) {
|
|
40273
40275
|
const point = [start[0] + dx * distance / length, start[1] + dy * distance / length];
|
|
40274
40276
|
advance(point);
|
|
40275
40277
|
const step = Math.min(remaining, length - distance);
|
|
@@ -40384,7 +40386,15 @@ function strokeOutlines(paths, width, cap, join, miterLimit, dashArray = [], das
|
|
|
40384
40386
|
let closed = subpath.closed;
|
|
40385
40387
|
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();
|
|
40386
40388
|
if (points.length < 3) closed = false;
|
|
40387
|
-
if (points.length === 1 &&
|
|
40389
|
+
if (points.length === 1 && cap === 2 && subpath.zeroLengthDash) {
|
|
40390
|
+
contour = [];
|
|
40391
|
+
const [x, y] = points[0];
|
|
40392
|
+
add(x - half, y - half);
|
|
40393
|
+
add(x + half, y - half);
|
|
40394
|
+
add(x + half, y + half);
|
|
40395
|
+
add(x - half, y + half);
|
|
40396
|
+
contours.push(contour);
|
|
40397
|
+
} else if (points.length === 1 && subpath.points.length > 1 && cap === 1) {
|
|
40388
40398
|
contour = [];
|
|
40389
40399
|
const [x, y] = points[0];
|
|
40390
40400
|
addCap([x, y], [x + 1, y]);
|
|
@@ -41574,7 +41584,7 @@ function prepareStroke(path, scale) {
|
|
|
41574
41584
|
}
|
|
41575
41585
|
return { matrix, width, dashArray, dashPhase };
|
|
41576
41586
|
}
|
|
41577
|
-
function
|
|
41587
|
+
function strokeContours(path, pageHeight, scale) {
|
|
41578
41588
|
const stroke = prepareStroke(path, scale);
|
|
41579
41589
|
if (!stroke) return [];
|
|
41580
41590
|
const inverse = inverseStrokeMatrix(stroke.matrix);
|
|
@@ -41598,7 +41608,7 @@ function strokeEdges(path, pageHeight, scale) {
|
|
|
41598
41608
|
stroke.dashArray?.map((value) => Math.max(0, value * strokeScale)),
|
|
41599
41609
|
stroke.dashPhase * strokeScale
|
|
41600
41610
|
);
|
|
41601
|
-
return
|
|
41611
|
+
return contours.map((points) => points.map(toScreen));
|
|
41602
41612
|
}
|
|
41603
41613
|
function pathsToEdges(paths, closeSubpaths = false) {
|
|
41604
41614
|
const edges = [];
|
|
@@ -41745,6 +41755,9 @@ function renderSoftMask(mask, displayList, scale) {
|
|
|
41745
41755
|
}
|
|
41746
41756
|
return bitmap;
|
|
41747
41757
|
}
|
|
41758
|
+
function hasBlendModes(operations) {
|
|
41759
|
+
return operations.some((operation) => !!operation.value.blendMode && operation.value.blendMode !== "Normal" && operation.value.blendMode !== "Compatible" || operation.kind === "group" && hasBlendModes(operation.value.operations));
|
|
41760
|
+
}
|
|
41748
41761
|
function renderDisplayListToBitmap(displayList, options = {}) {
|
|
41749
41762
|
const baseScale = options.scale ?? (options.dpi ? options.dpi / 72 : 1.5);
|
|
41750
41763
|
const scaleX = options.dpiX !== void 0 ? options.dpiX / 72 : baseScale;
|
|
@@ -41753,11 +41766,13 @@ function renderDisplayListToBitmap(displayList, options = {}) {
|
|
|
41753
41766
|
const width = Math.max(1, Math.round(displayList.width * scale));
|
|
41754
41767
|
const height = Math.max(1, Math.round(displayList.height * scale));
|
|
41755
41768
|
const rgba = new Uint8Array(width * height * 4);
|
|
41769
|
+
const deferBackground = !options.transparent && hasBlendModes(paintOperations(displayList));
|
|
41770
|
+
const transparent = options.transparent || deferBackground;
|
|
41756
41771
|
const bg = options.background ?? { r: 1, g: 1, b: 1 };
|
|
41757
|
-
const bgR =
|
|
41758
|
-
const bgG =
|
|
41759
|
-
const bgB =
|
|
41760
|
-
const bgA =
|
|
41772
|
+
const bgR = transparent ? 0 : Math.round(bg.r * 255);
|
|
41773
|
+
const bgG = transparent ? 0 : Math.round(bg.g * 255);
|
|
41774
|
+
const bgB = transparent ? 0 : Math.round(bg.b * 255);
|
|
41775
|
+
const bgA = transparent ? 0 : 255;
|
|
41761
41776
|
for (let i = 0; i < width * height; i++) {
|
|
41762
41777
|
rgba[i * 4] = bgR;
|
|
41763
41778
|
rgba[i * 4 + 1] = bgG;
|
|
@@ -41851,7 +41866,7 @@ function renderDisplayListToBitmap(displayList, options = {}) {
|
|
|
41851
41866
|
if (path.strokeColor) {
|
|
41852
41867
|
const rawSw = path.strokeWidth * scale * (path.strokeMatrix ? Math.hypot(path.strokeMatrix[0], path.strokeMatrix[1]) : 1);
|
|
41853
41868
|
const strokeAlpha = options.thinLineMode === "shape" && rawSw < 1 ? (path.strokeAlpha ?? 1) * Math.max(0.25, rawSw) : path.strokeAlpha ?? 1;
|
|
41854
|
-
const edges =
|
|
41869
|
+
const edges = pathsToEdges(strokeContours(path, displayList.height, scale).map((points) => ({ points, closed: true })));
|
|
41855
41870
|
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;
|
|
41856
41871
|
fillEdgesScanline4x4(
|
|
41857
41872
|
rgba,
|
|
@@ -41934,6 +41949,15 @@ function renderDisplayListToBitmap(displayList, options = {}) {
|
|
|
41934
41949
|
}
|
|
41935
41950
|
}
|
|
41936
41951
|
}
|
|
41952
|
+
if (deferBackground) {
|
|
41953
|
+
for (let i = 0; i < rgba.length; i += 4) {
|
|
41954
|
+
const alpha = rgba[i + 3] / 255;
|
|
41955
|
+
rgba[i] = Math.round(rgba[i] * alpha + bg.r * 255 * (1 - alpha));
|
|
41956
|
+
rgba[i + 1] = Math.round(rgba[i + 1] * alpha + bg.g * 255 * (1 - alpha));
|
|
41957
|
+
rgba[i + 2] = Math.round(rgba[i + 2] * alpha + bg.b * 255 * (1 - alpha));
|
|
41958
|
+
rgba[i + 3] = 255;
|
|
41959
|
+
}
|
|
41960
|
+
}
|
|
41937
41961
|
let result = { width, height, data: rgba };
|
|
41938
41962
|
if (Math.abs(scaleX - scaleY) > 1e-6) {
|
|
41939
41963
|
const targetW = Math.max(1, Math.round(displayList.width * scaleX));
|
|
@@ -42042,6 +42066,7 @@ function renderDisplayListToSvg(displayList, options = {}) {
|
|
|
42042
42066
|
if (!options.transparent) {
|
|
42043
42067
|
parts.push(` <rect x="${vbX}" y="${vbY}" width="${vbW}" height="${vbH}" fill="#ffffff"/>`);
|
|
42044
42068
|
}
|
|
42069
|
+
parts.push('<g style="isolation:isolate">');
|
|
42045
42070
|
if (displayList.rotation) {
|
|
42046
42071
|
const [a, b, c, d, e, f] = viewport.transform;
|
|
42047
42072
|
parts.push(`<g transform="matrix(${a} ${b} ${-c} ${-d} ${e + c * displayList.height} ${f + d * displayList.height})">`);
|
|
@@ -42093,6 +42118,7 @@ function renderDisplayListToSvg(displayList, options = {}) {
|
|
|
42093
42118
|
} else if (operation.kind === "path") {
|
|
42094
42119
|
const p = operation.value;
|
|
42095
42120
|
const prepared = p.strokeColor ? prepareStroke(p, Math.max(scaleX, scaleY)) : void 0;
|
|
42121
|
+
const outlineStroke = prepared && p.dashArray?.includes(0);
|
|
42096
42122
|
const matrix = prepared && (prepared.matrix[0] !== 1 || prepared.matrix[1] !== 0 || prepared.matrix[2] !== 0 || prepared.matrix[3] !== 1) ? prepared.matrix : void 0;
|
|
42097
42123
|
const inverse = matrix ? inverseStrokeMatrix(matrix) : void 0;
|
|
42098
42124
|
const pathData = svgPathData(p.segments, inverse ? 0 : displayList.height, inverse);
|
|
@@ -42107,10 +42133,18 @@ function renderDisplayListToSvg(displayList, options = {}) {
|
|
|
42107
42133
|
const lineCapAttr = p.lineCap === 1 ? ` stroke-linecap="round"` : p.lineCap === 2 ? ` stroke-linecap="square"` : "";
|
|
42108
42134
|
const lineJoinAttr = p.lineJoin === 1 ? ` stroke-linejoin="round"` : p.lineJoin === 2 ? ` stroke-linejoin="bevel"` : "";
|
|
42109
42135
|
const miterLimitAttr = p.miterLimit !== void 0 && p.miterLimit !== 10 ? ` stroke-miterlimit="${p.miterLimit}"` : "";
|
|
42110
|
-
const dashArrayAttr = prepared?.dashArray?.length ? ` stroke-dasharray="${prepared.dashArray.join(" ")}"` : "";
|
|
42111
|
-
const dashOffsetAttr = prepared?.dashPhase ? ` stroke-dashoffset="${prepared.dashPhase}"` : "";
|
|
42136
|
+
const dashArrayAttr = !outlineStroke && prepared?.dashArray?.length ? ` stroke-dasharray="${prepared.dashArray.join(" ")}"` : "";
|
|
42137
|
+
const dashOffsetAttr = !outlineStroke && prepared?.dashPhase ? ` stroke-dashoffset="${prepared.dashPhase}"` : "";
|
|
42112
42138
|
const labelAttr = original.kind === "glyph" ? ` aria-label="${escapeXmlText(original.value.unicode)}"` : "";
|
|
42113
|
-
|
|
42139
|
+
if (!outlineStroke || p.fillColor) {
|
|
42140
|
+
parts.push(` <path${labelAttr}${transformAttr} d="${pathData}" fill="${fill}"${fillRuleAttr}${fillOpacityAttr} stroke="${outlineStroke ? "none" : stroke}"${strokeOpacityAttr}${strokeWidthAttr}${lineCapAttr}${lineJoinAttr}${miterLimitAttr}${dashArrayAttr}${dashOffsetAttr}/>`);
|
|
42141
|
+
}
|
|
42142
|
+
if (outlineStroke) {
|
|
42143
|
+
const outlineScale = Math.max(scaleX, scaleY);
|
|
42144
|
+
const contours = strokeContours(p, displayList.height, outlineScale);
|
|
42145
|
+
const outlineData = contours.map((points) => points.map(([x, y], i) => `${i === 0 ? "M" : "L"} ${x / outlineScale} ${y / outlineScale}`).join(" ") + " Z").join(" ");
|
|
42146
|
+
if (outlineData) parts.push(` <path${labelAttr} d="${outlineData}" fill="${stroke}" fill-opacity="${p.strokeAlpha ?? 1}"/>`);
|
|
42147
|
+
}
|
|
42114
42148
|
}
|
|
42115
42149
|
} else if (operation.kind === "image") {
|
|
42116
42150
|
parts.push(` ${svgImage(operation.value, displayList.height)}`);
|
|
@@ -42120,6 +42154,7 @@ function renderDisplayListToSvg(displayList, options = {}) {
|
|
|
42120
42154
|
};
|
|
42121
42155
|
appendOperations(paintOperations(displayList));
|
|
42122
42156
|
if (displayList.rotation) parts.push("</g>");
|
|
42157
|
+
parts.push("</g>");
|
|
42123
42158
|
parts.push("</svg>\n");
|
|
42124
42159
|
return parts.join("\n");
|
|
42125
42160
|
}
|