Chrome headless PDF printing does not honour @page { size } for sheet size
Reported by
mika.rau...@gmail.com,
May 18 2017
|
||||||||||
Issue description
UserAgent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36
Steps to reproduce the problem:
1. Print the attached file test.html to PDF using --print-to-pdf or the remote debugging protocol.
What is the expected behavior?
A PDF file with one square page measuring 3.125" x 3.125" (300px x 300px) should be produced, identical to the attached file desktop.pdf which was created with the same Chrome build in desktop mode.
What went wrong?
The attached PDF headless.pdf is produced. The sheet size is not set according to the @page {size} at-rule in the HTML file. Instead, the sheet size is always US Letter, or the dimensions given in paperWidth and paperHeight if those were supplied in the printToPDF() call.
Did this work before? N/A
Does this work in other browsers? N/A
Chrome version: 60.0.3104.0 build 472783 Channel: dev
OS Version: LMDE2
Flash Version:
headless.pdf was created with printToPDF({displayHeaderFooter: false, printBackground: true})
desktop.pdf was created with the same Chrome build in desktop mode, with "Print > Save as PDF".
As the red body background area is still 300px x 300px in headless.pdf, it seems that Chrome headless sets the size of the print area according to @page {size} instead of setting the sheet size as it should.
,
Jun 8 2017
,
Jun 8 2017
Looking at test.html ... ah my eyes! X_X
,
Jun 14 2017
I am running into the same issue, pageHeight and pageWidth are not respected and neither is @page size
,
Jul 17 2017
,
Jul 17 2017
#4 Did you get it working (except for @page size of course)? If you are actually using pageHeight and pageWidth in your code (and not just a typo in your comment), please note the correct parameters are paperHeight and paperWidth. For me, the following code does indeed produce a 10.5" x 5.5" page:
Page.printToPDF({displayHeaderFooter: false, printBackground: true, marginTop: 0, marginBottom: 0, marginLeft: 0, marginRight: 0, paperWidth: 10.5, paperHeight: 5.5})
,
Jul 17 2017
paperWidth/Height should be respected, @page size isn't yet. It seems the latter is because the print_scaling_option is set to kWebPrintScalingOptionFitToPrintableArea in the PrintWebViewHelper: https://cs.chromium.org/chromium/src/components/printing/renderer/print_web_view_helper.cc?l=1694
,
Sep 7 2017
,
Sep 21 2017
Took a look at this. Headless Mode follows the "basic printing" (b) code path, AKA printing using the system dialog. Whereas on the desktop, users generally use the print preview code path. (a) (a1) With print preview, the "Save as PDF" target is special, in that it is Chromium's always available, built in PDF writer. (a2) Since Chromium knows it is not a (virtual) printer, Chromium can do special things like output PDFs of arbitrary size. (b1) Without print preview, Chromium assumes it is going to talk to printers selected via the system dialog. (b2) Printers, real or virtual, have page sizes, so the output cannot be an arbitrary size specified by CSS. It has to end up fitting some page size. (b3) Thus the output PDF looks like it is made for a printer with some paper size. To fix this, a few things need to happen: 1) At the devtools level, the printToPDF command needs to have some way of conveying prioritizing @page size. e.g. - New parameter to explicitly tell the browser to do this. - If the parameters does not contain paperWidth or paperHeight, use that as a hint to prioritize @page size. 2) Use whatever method in (1) to tell PrintWebFrameHelper what to do. Then in PrintWebFrameHelper's basic printing code path, make it choose kWebPrintScalingOptionSourceSize over kWebPrintScalingOptionFitToPrintableArea when appropriate.
,
Sep 21 2017
Issue 766858 has been merged into this issue.
,
Sep 25 2017
Cool. Erik are you still working on this or do you want me to come up with a CL? We probably want an explicit param so that pages without CSS page dimensions could fall back to the specified printer paper dimensions. I guess for communicating with PrintRenderFrameHelper a new parameter in the settings struct(s) would be easiest? (Just how many printer setting structs are there... including devtools I counted 4!)
,
Sep 26 2017
Feel free to grab it :) I think my conclusions were similar to thestig@'s. An explicit param in the DevTools command makes sense - and if there's no corresponding param in (I'm guessing) the PrintMsg_PrintPages_Params yet, I guess we'll have to add one.
,
Oct 4 2017
,
Dec 14 2017
Going to try to do this now.
,
Jan 17 2018
,
Jan 30 2018
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/665cdea2f5f29e166ad455b5021154456944fcbc commit 665cdea2f5f29e166ad455b5021154456944fcbc Author: Hidy Han <hidyhan@chromium.org> Date: Tue Jan 30 18:46:12 2018 Let print-to-pdf obey source size scaling option in headless mode. Bug: 724160 Change-Id: I9ede628f60f2ff32d09bcec9ef365db9246f4c98 Reviewed-on: https://chromium-review.googlesource.com/871046 Commit-Queue: Hidy Han <hidyhan@chromium.org> Reviewed-by: Lei Zhang <thestig@chromium.org> Reviewed-by: Mustafa Emre Acer <meacer@chromium.org> Reviewed-by: Eric Seckler <eseckler@chromium.org> Reviewed-by: Dmitry Gozman <dgozman@chromium.org> Cr-Commit-Position: refs/heads/master@{#532965} [modify] https://crrev.com/665cdea2f5f29e166ad455b5021154456944fcbc/components/printing/common/print_messages.cc [modify] https://crrev.com/665cdea2f5f29e166ad455b5021154456944fcbc/components/printing/common/print_messages.h [modify] https://crrev.com/665cdea2f5f29e166ad455b5021154456944fcbc/components/printing/renderer/print_render_frame_helper.cc [modify] https://crrev.com/665cdea2f5f29e166ad455b5021154456944fcbc/content/browser/devtools/protocol/page_handler.cc [modify] https://crrev.com/665cdea2f5f29e166ad455b5021154456944fcbc/content/browser/devtools/protocol/page_handler.h [modify] https://crrev.com/665cdea2f5f29e166ad455b5021154456944fcbc/headless/app/headless_shell.cc [modify] https://crrev.com/665cdea2f5f29e166ad455b5021154456944fcbc/headless/lib/browser/headless_devtools_manager_delegate.cc [modify] https://crrev.com/665cdea2f5f29e166ad455b5021154456944fcbc/headless/lib/browser/headless_print_manager.cc [modify] https://crrev.com/665cdea2f5f29e166ad455b5021154456944fcbc/headless/lib/browser/headless_print_manager.h [modify] https://crrev.com/665cdea2f5f29e166ad455b5021154456944fcbc/headless/lib/browser/headless_printing_unittest.cc [modify] https://crrev.com/665cdea2f5f29e166ad455b5021154456944fcbc/third_party/WebKit/Source/core/inspector/browser_protocol.json [modify] https://crrev.com/665cdea2f5f29e166ad455b5021154456944fcbc/third_party/WebKit/Source/core/inspector/browser_protocol.pdl
,
Jan 30 2018
,
Feb 2 2018
Tried this with build 534058. Everything seems to work great, except:
I'm seeing weird behaviour if the page size is defined in CSS and I pass a scale parameter to Page.printToPDF: the content is scaled down (as expected), but the page is also scaled UP by the same factor.
In other words: a 6x6" with full page content rendered with {scale: 0.5} will give a 12x12" page with 3x3" content.
I don't think the page scaling should happen; instead I should get the same output as if I had rendered with {paperWidth: 6, paperHeight: 6, scale: 0.5, preferCssPageSize: false} : a 6x6" page with 3x3" content.
Should I file this as a new issue?
,
Feb 6 2018
We can continue investigation in this bug if the fix had unwanted side effects. BTW what is the easiest way to issue DevTools commands? I was using chrome-remote-interface, but it seems Page.printToPDF() always returns a blank page for local files. I tried Page.setDocumentContent with test.html but still no luck.
,
Feb 6 2018
One way to debug headless related issues is to build and run headless_shell [1]. This includes some PDF functionality, so should be possible to use and/or modify as needed for testing this bug. For example: $ ninja -C out/Debug headless_shell $ out/Debug/headless_shell --print-to-pdf http://localhost:8000/my_awesome_webpage_about_owls.html (Note: I think a file:// URL will work with the above command, but if not "python -m SimpleHTTPServer" can be used from a directory with HTML to spin up a very simple webserver). [1] headless/app/headless_shell.cc
,
Feb 7 2018
Yeah a file:// URL works with the above command. It also works with the remote debugging protocol (if I open localhost:9222 I can see the correct page), but somehow just not with Page.printToPDF(). Seems to be known issue https://github.com/cyrus-and/chrome-remote-interface/issues/95#issuecomment-293945313. I can set the parameters in the headless shell until a more handy solution comes up that does not require me to do a build every time...
,
Feb 7 2018
Would some PHP that calls the chrome dev tools with the right params be useful? If not, I can probably whip up some node as well. I'm afraid Python is not my strength.
,
Feb 7 2018
#21 I'm testing with GoogleChrome/rendertron. Maybe that would work for you too? I made a quick fork to make it accept file: URLs and create PDFs: https://github.com/mikaraunio/rendertron/tree/hack-pdf-and-file The actual Page.printToPDF call is on line 293 in src/renderer.js Actually, it looks like the official rendertron also has a printToPDF branch which is cleaner, but you'd have to add the file: support and a Print PDF button to the front page.
,
Feb 10 2018
Thanks for the suggestions! The cause is https://cs.chromium.org/chromium/src/components/printing/renderer/print_render_frame_helper.cc?sq=package:chromium&dr&l=483. We need to consider prefer_css_page_size as well. (Not sure why scaling_factor is divided in https://cs.chromium.org/chromium/src/components/printing/renderer/print_render_frame_helper.cc?sq=package:chromium&dr&l=455, but I bet there is a reason). Let me just look at other functions to make sure I don't miss something!
,
Feb 12 2018
I had a look at the scaling in print_render_frame_helper.cc, and this made me wonder whether there are plans to support fit_to_page (automatic scaling) in Page.printToPDF and if so, would this be a good occasion to tackle that as well? For comparison: on the desktop, Print > Save as PDF automatically scales the content to the (CSS-defined or user-selected) page size, and it actually looks like there's no easy way to disable this. Could make sense to have this option available in printToPDF as well, for parity?
,
Feb 22 2018
An observation: the page scaling with preferCssPageSize and scale happens even when CSS doesn't actually specify a page size (the default Letter page is then scaled).
,
Mar 1 2018
Sounds like we need some input from printing experts on this issue. Off to thestig@ for feedback. |
||||||||||
►
Sign in to add a comment |
||||||||||
Comment 1 by skyos...@chromium.org
, May 18 2017Components: Internals>Headless
Status: Available (was: Unconfirmed)