Skip to content

Commit a1f3804

Browse files
committed
fix(page): resolve Contents ref before appending content streams
When a page's /Contents is a reference to an array (not a single stream), the append/prepend methods need to expand the array items into the new contents array. Previously, the indirect reference to the array was kept, causing PDF viewers to fail rendering the original page content.
1 parent 9778a85 commit a1f3804

File tree

1 file changed

+44
-3
lines changed

1 file changed

+44
-3
lines changed

src/api/pdf-page.ts

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2200,8 +2200,27 @@ export class PDFPage {
22002200
}
22012201

22022202
if (existingContents instanceof PdfRef) {
2203-
// Reference to a stream - wrap in array with our content first
2204-
this.dict.set("Contents", new PdfArray([newContent, existingContents]));
2203+
// Resolve the reference to check if it's an array or a stream
2204+
const resolved = this.ctx.resolve(existingContents);
2205+
2206+
if (resolved instanceof PdfArray) {
2207+
// Reference points to an array of streams - prepend our stream to a new array
2208+
// containing all items from the resolved array
2209+
const newArray = new PdfArray([newContent]);
2210+
2211+
for (let i = 0; i < resolved.length; i++) {
2212+
const item = resolved.at(i);
2213+
2214+
if (item) {
2215+
newArray.push(item);
2216+
}
2217+
}
2218+
2219+
this.dict.set("Contents", newArray);
2220+
} else {
2221+
// Reference points to a single stream - wrap in array with our content first
2222+
this.dict.set("Contents", new PdfArray([newContent, existingContents]));
2223+
}
22052224

22062225
// Mark as modified to prevent double-wrapping in appendContent
22072226
this._contentWrapped = true;
@@ -2260,7 +2279,29 @@ export class PDFPage {
22602279
const QStream = this.createContentStream("\nQ");
22612280

22622281
if (existingContents instanceof PdfRef) {
2263-
this.dict.set("Contents", new PdfArray([qStream, existingContents, QStream, newContent]));
2282+
// Resolve the reference to check if it's an array or a stream
2283+
const resolved = this.ctx.resolve(existingContents);
2284+
2285+
if (resolved instanceof PdfArray) {
2286+
// Reference points to an array of streams - expand it
2287+
const newArray = new PdfArray([qStream]);
2288+
2289+
for (let i = 0; i < resolved.length; i++) {
2290+
const item = resolved.at(i);
2291+
2292+
if (item) {
2293+
newArray.push(item);
2294+
}
2295+
}
2296+
2297+
newArray.push(QStream);
2298+
newArray.push(newContent);
2299+
2300+
this.dict.set("Contents", newArray);
2301+
} else {
2302+
// Reference points to a single stream
2303+
this.dict.set("Contents", new PdfArray([qStream, existingContents, QStream, newContent]));
2304+
}
22642305

22652306
return;
22662307
}

0 commit comments

Comments
 (0)