Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot increase height with certain pdf files (sample included) #399

Closed
mugli opened this issue Apr 8, 2020 · 4 comments
Closed

Cannot increase height with certain pdf files (sample included) #399

mugli opened this issue Apr 8, 2020 · 4 comments

Comments

@mugli
Copy link

mugli commented Apr 8, 2020

I'm trying to increase the height of a page to add "header" to pdf files using pdf-lib. The code works for most of the files but also doesn't work with certain files. It's not clear why it doesn't work, there is no error. This looks like a bug in the library, but I could be wrong.

I have added a demo repository for demonstrating this with both working and not-working samples here: https://github.com/mugli/demo-adding-header-to-pdf

Please let me know if there's a better way to achieve this or if there's any workaround.

@mugli mugli changed the title Cannot increase height with certain pdf files Cannot increase height with certain pdf files (sample included) Apr 8, 2020
@Hopding
Copy link
Owner

Hopding commented Apr 8, 2020

Hello @mugli!

In the example you shared the page height is being set by the following line:

page.setHeight(height + headerHeight);

This method abstracts away a lot of annoying little PDF details and works well for most documents. However, the abstraction does break for certain documents, like the one you shared. The PDF spec defines 5 different boxes that control the positioning and clipping of content on a page (MediaBox, CropBox, BleedBox, TrimBox, and ArtBox). However, the setHeight() method only modifies the MediaBox:

pdf-lib/src/api/PDFPage.ts

Lines 159 to 166 in 3c15aa5

setSize(width: number, height: number): void {
assertIs(width, 'width', ['number']);
assertIs(height, 'height', ['number']);
const mediaBox = this.node.MediaBox().clone();
mediaBox.set(2, this.doc.context.obj(width));
mediaBox.set(3, this.doc.context.obj(height));
this.node.set(PDFName.of('MediaBox'), mediaBox);
}

The input-problematic.pdf file that you shared defines both a MediaBox and a CropBox. So even though the MediaBox is properly updated to reflect the new height, the CropBox remains untouched. This results in your context being clipped to the original page size.

Instead of calling the setHeight() method, we can manually set the MediaBox and CropBox ourselves as follows:

const mediaBox = page.node.MediaBox();
const cropBox = page.node.CropBox();

const newMediaBox = mediaBox.clone();
newMediaBox.set(3, doc.context.obj(height + headerHeight));
page.node.set(PDFName.of('MediaBox'), newMediaBox);

if (cropBox) {
  const newCropBox = cropBox.clone();
  newCropBox.set(3, doc.context.obj(height + headerHeight));
  page.node.set(PDFName.of('CropBox'), newCropBox);
}

This results in the page height being successfully updated for both documents that you shared.

I hope this is helpful. Please let me know if you have any additional questions!

@Hopding
Copy link
Owner

Hopding commented Apr 8, 2020

I would like for the setHeight() method to handle situations like this automagically. I'm still thinking about the best way to do that, though. It's a bit tricky because sometimes the values for each of the 5 boxes are supposed to be different. So forcing them all to be the same value whenever setHeight() is called may or may not be a good solution.

@mugli
Copy link
Author

mugli commented Apr 9, 2020

Thank you so much. This does fix my problem for now. I'm going with the sample code you provided here. If I find any more pdf files not working with this, I'll refer to this issue again with new samples. You can close it for now if you want. Have a nice day!

@Hopding
Copy link
Owner

Hopding commented Apr 26, 2020

Version 1.5.0 is now published. It contains a fix for this issue. The full release notes are available here.

You can install this new version with npm:

npm install pdf-lib@1.5.0

It's also available on unpkg:

As well as jsDelivr:

@Hopding Hopding closed this as completed Apr 26, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants