I am unclear about gecko's dpi handling while printing.
I need to have the webpage rendered with 600 dpi, i.e. an image with 600 pixels width should print with 1 inch width. Currently, the engines assumes web-like 100 dpi and prints in 6 inches.
In my case, it's not a static <img>, but about a <div> that's built by JS. When the JS on the webpage asks about the size of the <div> in px, it must get 3000px as answer, but the <div> must print in say 21cm, printing these 3000px in these 21cm width.
pref("layout.css.dpi", 600); (I'm in XULRunner) sounds like what I need, but it doesn't help.
I tried <container style="width: 20cm"><div style="3000px">...</div></container>, but that doesn't work, it causes overflow.
Also, printSettings.shrinkToFit = true; and printFrame.markupDocumentViewer.fullZoom = 10; don't help.
I lack background knowledge about the layout engine to know how to approach this problem. Can somebody please point me in the right direction?
> I am unclear about gecko's dpi handling while printing.
> I need to have the webpage rendered with 600 dpi, i.e. an image with 600 pixels width should print with 1 inch width.
> Currently, the engines assumes web-like 100 dpi and prints in 6 inches.
> In my case, it's not a static <img>, but about a <div> that's built by JS. When the JS on the webpage asks about the size of
> the <div> in px, it must get 3000px as answer, but the <div> must print in say 21cm, printing these 3000px in these 21cm width.
> pref("layout.css.dpi", 600); (I'm in XULRunner) sounds like what I need, but it doesn't help.
> I tried <container style="width: 20cm"><div style="3000px">...</div></container>, but that doesn't work, it causes overflow.
> Also, printSettings.shrinkToFit = true; and printFrame.markupDocumentViewer.fullZoom = 10; don't help.
> I lack background knowledge about the layout engine to know how to approach this problem. Can somebody please point me in the
> right direction?
In CSS, the ratio of px to cm is fixed, so for a 600px image you want printed at 600dpi,
size your image as 1in, rather than as 600px, and it should print properly.
> so for a 600px image you want printed at 600dpi, size your image as > 1in, rather than as 600px, and it should print properly.
Well, it's not as simple as one image, it's a Javascript library that generates the output. The JS lib must get "4920px" as width from DOM/style APIs, and that must print as 21cm width in 600 dpi. That would solve it, and I *should* be able to set this via CSS rules.
> In CSS, the ratio of px to cm is fixed
Well, that's the problem, then. It's inherently wrong.
1. Set device resolution to 600 dpi (or 1200 dpi)
2. Set device pixels per CSS pixels to 1:1
3. Make sure the page is rendered with these settings, including the
DOM "load" event.
It seems that 1. and 2. already have prefs, namely pref("layout.css.dpi", 600) and pref("layout.css.devPixelsPerPx", 1.0);, but they are ignored for print, print assumes a hardcoded 72dpi (on non-Windows), see <http://mxr.mozilla.org/comm-central/source/mozilla/gfx/src/nsDeviceCo...>, but even if that were reasonable settings for most pages, I fail to see why I can't override it, at least in prefs, but better yet in the page via CSS rules.
As-is, the print output is more than 10 times less the resolution than the printer normally does, making the output completely unusable and useless, because I can't read anything.
Of course, I can hack the JS lib (OpenLayers for map rendering in my case), but it's a big lib and that's a major undertaking, as it's using images in a grid, SVG, canvas etc., and I'd have to teach it to use more than one output pixel for each CSS pixel. I can try, but...
I think this is a general problem in Mozilla. If I could just tell Mozilla to do the 3 things above, it would be solved cleanly for all pages.
> On 28.06.2012 08:16, fantasai wrote:
>> so for a 600px image you want printed at 600dpi, size your image as 1in, rather than as 600px, and it should print properly.
> Well, it's not as simple as one image, it's a Javascript library that generates the output. The JS lib must get "4920px" as
> width from DOM/style APIs, and that must print as 21cm width in 600 dpi. That would solve it, and I *should* be able to set
> this via CSS rules.
>> In CSS, the ratio of px to cm is fixed
> Well, that's the problem, then. It's inherently wrong.
Yes, we realize that. Unfortunately, the correct behavior (which is described in
older revisions of CSS2.1) turned out to not be Web-compatible: the Web assumes
everyone is running 96dpi and that therefore 'width: 1in' is equal to 'width: 96px'.
And so after a lot of debate (hundreds of messages worth), the CSSWG resolved
on the text here:
http://www.w3.org/TR/CSS21/syndata.html#x39
> On 06/28/2012 07:10 AM, Ben Bucksch wrote:
>> Thanks fantasai :-), for the answer.
>> On 28.06.2012 08:16, fantasai wrote:
>>> so for a 600px image you want printed at 600dpi, size your image as >>> 1in, rather than as 600px, and it should print properly.
>> Well, it's not as simple as one image, it's a Javascript library that >> generates the output. The JS lib must get "4920px" as
>> width from DOM/style APIs, and that must print as 21cm width in 600 >> dpi. That would solve it, and I *should* be able to set
>> this via CSS rules.
>>> In CSS, the ratio of px to cm is fixed
>> Well, that's the problem, then. It's inherently wrong.
> Yes, we realize that. Unfortunately, the correct behavior (which is > described in
> older revisions of CSS2.1) turned out to not be Web-compatible: the > Web assumes
> everyone is running 96dpi and that therefore 'width: 1in' is equal to > 'width: 96px'.
Yes, sure, I know that part. I understand and agree. I don't object for this to be the default.
I'm just saying that if I make a page specifically for print, I must be able to explicitly say "I don't want this 'make it look like on the screen' hack, I want the full device resolution, render the page with this". I need a (document-wide) CSS rule that sets device pixel == CSS pixel, or alternatively a concrete dpi value that affects CSS pixels.
I just want my page to use the full printer resolution, I want 4920 CSS pixel width for a printed DIN A4 page, that's all. That must be possible.
> I just want my page to use the full printer resolution, I want 4920 > CSS pixel width for a printed DIN A4 page, that's all. That must be > possible.
I tried that now, changing above function to use pref "layout.css.api" = 600 even for print. A printf() confirms that it's invoked and indeed always 600 dpi with 1 device pixel per CSS pixel, even when I click "Print".
If you just want to print something that's 600px wide so that it takes up 1
inch on paper, one way is to add a CSS transform:scale(0.16).
Another approach would be set the print scale factor to 0.16.
Rob
-- “You have heard that it was said, ‘Love your neighbor and hate your enemy.’
But I tell you, love your enemies and pray for those who persecute you,
that you may be children of your Father in heaven. ... If you love those
who love you, what reward will you get? Are not even the tax collectors
doing that? And if you greet only your own people, what are you doing more
than others?" [Matthew 5:43-47]
> That may be transform-origin messing with you. By default the center of
> the element stays in the same place. Try -moz-transform-origin:top left.
Exactly. I had just found that. Thanks.
Very unintuitive. I think it should default to center for rotate, but to top left for scale, if that's possible.
I'm *very* grateful for this CSS transform tip. Thanks a lot!
More generally, shouldn't we allow to set the dpi page-wide, so that 1 CSAS "px" and 1 image pixel = 1 device pixel, but "cm" is still physical size, and "pt" still works (like in MS Word) in relation to cm? While this trick works for me and is exactly what I need, because I need to rotate, too, I think it should be easier to make webpages specifically for print with high-res than it is now. (It took me about 3 full days so far.) I'm thinking of @page { resolution: 600dpi }.