Closed Bug 103145 Opened 23 years ago Closed 22 years ago

[ps][FIX]Images don't print correctly; each pixel scaled to ~20x20 pt

Categories

(Core :: Printing: Output, defect, P1)

x86
Linux
defect

Tracking

()

VERIFIED FIXED
mozilla1.0

People

(Reporter: deven, Assigned: bzbarsky)

References

()

Details

Attachments

(2 files)

From Bugzilla Helper:
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:0.9.4+) Gecko/20011003
BuildID:    2001100321

Any image printed from Mozilla seems to be scaled extremely large -- they are
printing with each individual pixel from the image scaled to approximately 20
points by 20 points, or about 1/4 inch by 1/4 inch.  (Somewhere right around
there; it's not an exact measurement.)

Google's home page seems like a good test page, because it shows the problem
clearly without wasting a lot of toner.  Slashdot prints most of the page as
solid black!

This bug was introduced in the last two months or so; it was NOT present in the
2001073106 build, which prints images fine.  This bug was present in the
2001092106 build (as well as the current build).  I didn't try any other builds
between 7/31 and 9/21, but the bug had to be introduced somewhere in that time
frame.

Reproducible: Always
Steps to Reproduce:
1. Load an HTML page with inline images.
2. Print the page.

Actual Results:  Images are scaled to an enormous size on the printout.

Expected Results:  Images should print normally and look the same as they do on
the screen, with proper layout and scaling.

Can anyone out there running builds between 7/31 and 9/21 narrow the time frame
of when the bug was introduced?
seems to print fine for me on Win98 and Linux using 10/4 builds...I don't notice
a visible difference. I could be wrong though...can someone else confirm/verify
this?
I don't know why you didn't see it on Linux, unless it just happens to have been
fixed sometime today since the 2001100321 build I'm running now...

In any event, so you can see what I see, I've done a "print to file" and
captured the incorrectly-generated Postscript, and uploaded it as an attachment
to this bug.  You can see the problem quite clearly by viewing the Postscript
file in "gv" or by printing it on a Postscript printer.  Perhaps some of the
details of the generated Postscript itself may shed some light on the problem...

I've just done some comparison against the Postscript generated by 2001073106
(which doesn't exhibit the bug) -- the problem seems to lie in the generated
"translate" and "scale" calls used before displaying each image.

Here's the (working) translate/scale call pairs generated by 2001073106:

203 690.9 translate
119 59 scale
--
321 690.9 translate
38 59 scale
--
359 690.9 translate
51 59 scale
--
321 666.9 translate
38 24 scale
--
119 646.9 translate
1 1 scale
--
252 547.9 translate
26 36 scale

Here's the (broken) corresponding calls generated by 2001100321:

168 -812.1 translate
3160 1560 scale
--
326 -812.1 translate
1000 1560 scale
--
376 -812.1 translate
1360 1560 scale
--
326 29.9 translate
1000 640 scale
--
56 591.9 translate
20 20 scale
--
230 -431.1 translate
680 960 scale

Obviously, 2001100321 is using completely unreasonable values here.  But why?
Same problem here: Linux/2.4.4 Mozilla 2001100308 (mozilla profile ranges from
late 2000 to current)

Steps to fix:
 -rename/remove ~/.mozilla
 -start mozilla (to create a fresh profile)
 -visit a page with inline images
 -print that page (to postscript)

Results:
 Images print at an appropriate size (but transparent GIFs have black
backgrounds in spite of being in a white-background document; probably another
bug or worthy of being one).

If anyone knows which specific file in the profile is responsible for this, I
can give my mod. date on that file.

I've postscript output from before and after the fix, if they'd help; I won't
post them unless asked.
Adding self to CCs
I just downloaded the most recently nightly for Linux, 2001101606.  This bug
remains in the current build.
I've tried to narrow the time range further.  Unfortunately, the older nightly
builds seem to have been deleted -- the oldest nightly I see now is from 9/16,
which does exhibit the bug.  Release 0.9.5 also exhibits the bug.  Release 0.9.4
does not exhibit this bug.  It appears to have been introduced somewhere between
9/4 (when 0.9.4 branched) and 9/16 (bad trunk build).  I'm currently checking
out a tree from CVS for 9/10, which I will compile and test.  I'll have to do a
crude binary search, I guess...  (At least we're down to a 12-day range instead
of 6 weeks!)
I've narrowed the range from 12 days to 12 hours so far.  I found older copies
of the nightly builds on the SourceForge FTP mirror -- the 2001090406 trunk
build does not exhibit the bug, but the 2001090506 trunk build does.  I'm
narrowing the range further by building it myself from CVS -- CVS builds from
06:00 and 18:00 on 4-Sep-2001 do not exhibit the bug, but 06:00 on 5-Sep-2001
does.  I'm working on narrowing the range further, then I'll try to find the
relevant code changes which caused this bug...
Okay, my binary search nailed it down.  I got the time range down to 15 minutes,
between 23:15 and 23:30 on 4-Sep-2001.  The only update during this timeframe
was from revision 1.79 to revision 1.80 of gfx/src/gtk/nsDeviceContextGTK.cpp,
in the function nsDeviceContextGTK::Init(nsNativeWidget aNativeWidget), which
changed from always calling SetDPI(prefVal) [in revision 1.79] to calling
SetDPI(prefVal) the first time and SetDPI(mDpi) thereafter [in revision 1.80].

The really weird thing here is that both seem to call SetDPI(72), according to
debugging printf's, and it doesn't seem to get called during the print function.

What's going on here?
Deven, did you check for libpr0n checkins in that time period?  Those don't show
up in SeamonkeyAll on Bonsai (if you used Bonsai to find all the affected files).
Actually, it didn't occur to me to check Bonsai.  I used CVS itself -- every
time I rebuilt with a new timestamp, I watched for the notifications from CVS
that indicated that a file had to be patched.  It finally got down to a point
where only that one file was being patched.  In fact, a build at 23:15 doesn't
exhibit the bug, but a build from 23:16 (one minute later) does.  The revision
in question was checked in at 23:15:55 EDT (or 3:15:55 GMT).  (Those of you in
other timezones would have to adjust your timestamps to replicate my results.)

To be exact, the mechanism I used to perform the binary search was a build
command like this:

     make -f client.mk MOZ_CO_FLAGS="-D '4-Sep-2001 23:15'"

In order to be 100% sure, I've just tried making the changes in that one file
manually, and rebuilding several times with the same 23:15 timestamp that would
normally work.  When I've got local modifications to the file equivalent to the
changes in revision 1.80, the bug appears.  When I reverse the changes, the bug
disappears.  I don't understand why it's doing what it's doing, but it's got to
be related to that code change somehow.

I added debugging printf() statements to both versions to see what's different.

With revision 1.79, SetDPI(prefVal) is always called -- but only the first call
actually has the value 72 in prefVal -- the remaining calls have prefVal set to
-1 instead.  So, it calls SetDPI(72) once, and SetDPI(-1) six times.  (There are
a total of seven calls to SetDPI() when I launch Mozilla from scratch and load
and print my homepage, www.google.com.)

Here's what my debugging printf's showed for revision 1.79, which worked:

SetDPI(prefVal = 72)
nsDeviceContextGTK::SetDPI(aPrefDPI) called...
  aPrefDPI = 72
  ::gdk_screen_width_mm() = 433
  screenWidthIn = 17.0472
  mWidthFloat = 1280
  OSVal = 75
  aPrefDPI > 0; mDpi = aPrefDPI
  mDpi = 72
  mPixelsToTwips = 20
  mTwipsToPixels = 0.05
nsDeviceContextGTK::SetDPI() finished.

SetDPI(prefVal = -1)
nsDeviceContextGTK::SetDPI(aPrefDPI) called...
  aPrefDPI = -1
  ::gdk_screen_width_mm() = 433
  screenWidthIn = 17.0472
  mWidthFloat = 1280
  OSVal = 75
  aPrefDPI < 0 && OSVal <= 96; mDpi = 96
  mDpi = 96
  mPixelsToTwips = 15
  mTwipsToPixels = 0.0666667
nsDeviceContextGTK::SetDPI() finished.

[The next five calls are identical to the second call.]

Here's the corresponding information for revision 1.80, which exhibits the bug:

SetDPI(prefVal = 72)
nsDeviceContextGTK::SetDPI(aPrefDPI) called...
  aPrefDPI = 72
  ::gdk_screen_width_mm() = 433
  screenWidthIn = 17.0472
  mWidthFloat = 1280
  OSVal = 75
  aPrefDPI > 0; mDpi = aPrefDPI
  mDpi = 72
  mPixelsToTwips = 20
  mTwipsToPixels = 0.05
nsDeviceContextGTK::SetDPI() finished.

SetDPI(mDpi = 72)
nsDeviceContextGTK::SetDPI(aPrefDPI) called...
  aPrefDPI = 72
  ::gdk_screen_width_mm() = 433
  screenWidthIn = 17.0472
  mWidthFloat = 1280
  OSVal = 75
  aPrefDPI > 0; mDpi = aPrefDPI
  mDpi = 72
  mPixelsToTwips = 20
  mTwipsToPixels = 0.05
nsDeviceContextGTK::SetDPI() finished.

[Again, the next five calls are identical to the second call.]

This code is the ONLY code changing between a working build and a broken build. 
While it doesn't seem to make sense, this is the information I have at the
moment.  While it seems that the working version of the code ends up using 96
dpi (except initially) and the broken version always uses 72 dpi, such a small
difference can't explain the seriously overscaled pixels I'm seeing in printed
images, which seem to be about 3.6 dpi, not 72 or 96 dpi...

The comment from revision 1.80 of nsDeviceContextGTK.cpp was:

     Make the "browser.display.screen_resolution" pref work again.  b=69205
     r=bryner  sr=waterson

My prefs.js file does have browser.display.screen_resolution set to 72, so from
the perspective of what SetDPI() is getting called with, it would seem to be
working as intended, at least on the surface.  And yet, while the parameters for
SetDPI() seem reasonable, the results are not.  It doesn't make sense.

To make 100% sure I found the offending code change, I made a new build from
current CVS sources (with the -A option to drop the sticky date from previous
builds) -- the current version in CVS exhibits this bug.  Modifying the SetDPI()
calls back to the way they were done in revision 1.79 of that module DID stop
the bug from occurring.  I don't understand why it works, but it does.

Here's the code patch I made that "fixed" this bug:

RCS file: /cvsroot/mozilla/gfx/src/gtk/nsDeviceContextGTK.cpp,v
retrieving revision 1.88
diff -c -r1.88 nsDeviceContextGTK.cpp
*** nsDeviceContextGTK.cpp	2001/10/02 03:10:34	1.88
--- nsDeviceContextGTK.cpp	2001/10/22 17:31:48
***************
*** 217,227 ****
        prefs->RegisterCallback("browser.display.screen_resolution",
prefChanged,
                                (void *)this);
      }
- 
-     SetDPI(prefVal);
-   } else {
-     SetDPI(mDpi); // to setup p2t and t2p
    }
  
    sb = gtk_vscrollbar_new(NULL);
    gtk_widget_ref(sb);
--- 217,225 ----
        prefs->RegisterCallback("browser.display.screen_resolution",
prefChanged,
                                (void *)this);
      }
    }
+ 
+   SetDPI(prefVal);
  
    sb = gtk_vscrollbar_new(NULL);
    gtk_widget_ref(sb);

As far as I can see, this shouldn't fix the bug, yet it does.  (Or, more likely,
masks a deeper underlying bug of some sort...)  Of course, this patch probably
breaks bug 69205 again...

Can someone explain what's going on here?  These results don't make sense...
Blocks: 69205
ccing dbaron, status to NEW.  Deven, thanks a ton for doing all that!
Status: UNCONFIRMED → NEW
Ever confirmed: true
If the difference you're seeing is that the resulting DPI is 72dpi vs 96dpi,
then it seems there's some other underlying bug.  Still, I'd think we'd want to
be doing something different for printing, except that printing should be going
through the nsDeviceContextPS.cpp or nsDeviceContextXP.cpp code, which is
entirely different.
WORKAROUND: On a hunch, I tried editing "prefs.js" manually and set
"browser.display.screen_resolution" to -1.  With this setting, it probably
defaults to 96 dpi, but it DOES print images correctly.  This is NOT a proper
fix for this problem (obviously -1 dpi is invalid), but it's a temporary
workaround.  I'm hoping a proper fix can be found soon...
David, I agree that nsDeviceContextGTK shouldn't affect PostScript printing, yet
somehow it does.  This sort of cross-dependency is bizarre, and I imagine that
it's indicative of some deeper problem which is very subtle.  I was certainly
surprised to discover that the SetDPI() changes in nsDeviceContextGTK affect
PostScript printing; I would have expected them to be entirely independent...

As for 72dpi vs. 96dpi, it doesn't seem to matter.  I tried changing the setting
to 96dpi, and the same result occurred when printing.  (But the print dialog was
now larger than I wanted it to be!)  Only setting the value to "-1" helped, but
defeats the purpose of having that configuration parameter.

David, if you haven't viewed attachment 52090 [details], I'd recommend you take a look at
it, and try printing it on a PostScript printer, or viewing it with "gv".  The
error in scaling the images is not a minor difference like 72dpi vs. 96 dpi --
it's a glaring difference, with each pixel of the image scaling to a 20pt x 20pt
block on the page, about 3.6 dpi!

I wish I had a comprehensive answer to why this bug occurs, but I don't.  I've
already spent a number of hours tracking it this far, and it's getting to a
point where I've concluded that something may be amiss deep in the internal data
structures, but I can't follow what's going on very easily...
Okay, on closer inspection, 72dpi vs. 96dpi DOES matter.  I tried moving aside
my .mozilla directory entirely, and my .netscape directory, and had it create a
new profile from scratch.  The images print correctly.  I went to Preferences
and changed the display resolution from "System setting" (the default, which
seems equivalent to the manual -1 which I tried earlier) to 96 dpi.  I quit and
relaunched Mozilla, it still prints fine.  I then changed the display resolution
to 72 dpi, and quit and relaunched Mozilla -- now the images print with this
scaling bug.  I changed back to 96 dpi and relaunched, images print normally
again.  If I launched at 72 dpi and change to 96 dpi, the bug still appears if
using the same browser window as before, which is what confused me earlier.

I've tried "72 dpi", "96 dpi" and "System setting" -- this bug only exhibits
when launched with 72 dpi as the existing setting.  It doesn't show up when
launched with 96 dpi as the existing setting.  I didn't try custom settings.

Does this illuminate anything for anyone?
Stranger and stranger.  Armed with the knowledge that specific dpi values
matter, I set out to try a variety of them.  None of the settings appeared to
affect the on-screen display (except that very low ones like 10-20 dpi failed to
render the window properly) -- but all of the variations affected the size of
the PostScript output, which was always scaled relative to the resolution value.

In any event, I have ONLY been able to replicate this problem with the following
values:

     user_pref("browser.display.screen_resolution", 71);
     user_pref("browser.display.screen_resolution", 72);
     user_pref("browser.display.screen_resolution", 73);

Values up to 70 dpi seemed to print correctly, and values from 74 dpi and up
also seemed to print correctly.  I can only replicate this bug at 71-73 dpi!

On a separate note, should this value even be affecting the scaling in
PostScript in the first place?
There's no need to duplicate all your comments on bug 69205 -- this is a
separate bug.  Thanks.
I only added the last comment under bug 69205 to explain why bug 103145 didn't
appear until the patch for bug 69205 was applied.  How was that not relevant to
bug 69205?
bug 69205 is about making the DPI pref work, not what other code breaks when the
DPI is set to certain values.

But now we're cluttering up this bug with useless information...
I hope you're not suggesting that those who fix one bug shouldn't be concerned
with other bugs that may be caused by that fix?  Anyway, let's not argue...

Any idea what's so special about 71-73 dpi?  And whether a "screen resolution"
setting should affect PostScript scaling in the first place?
I'm concerned with it, yes, but I don't know how we print images, and I don't
really want to find out.  This bug is really pretty much unrelated to the other
bug -- it's just some really odd side-effect of having that pref working, which
is a good thing.  And since the pref isn't fully working, the other bug is still
to be used to discuss how to get the pref fully working, not how bizarrely the
image printing code handles the pref when it shouldn't be affected at all.
(Though I suspect the problem may be due to misuse of one of the hardcoded "72"s
in gfx/src/ps/.)
(In particular, nsDeviceContextPS sets its mPixelsToTwips and mTwipsToPixels
based on 72dpi.  This is right for how to interpret a logical pixel when
printing, but it's not right for handling images.)
Well, the PostScript language defines the initial graphics state to be exactly
72dpi, so it seems a reasonable thing to hardcode.  That is, when you're talking
about "points" in PostScript (and the PLRM states that printer's "points" aren't
precisely 72dpi, but in PostScript they are).  Whether each pixel in an image
should be one "point" is a separate question entirely.

It probably shouldn't -- 8.5 x 11 paper would only give you 612 points across,
before you remove margins.  I'm thinking more like 1/2 point per image pixel
would be more like it.  With 1/2-inch margins, you could fit an image 1080
pixels wide on the page, which seems reasonable.

Is the PostScript code deliberately looking at the GTK settings for DPI?  That
might be done to try to get the printout to look as close as possible to what
might display on the screen.  Otherwise, why would the GTK settings cause ANY
change in the PostScript output?  Seems like nsDeviceContextPS ought to be the
only controlling factor...
Target Milestone: --- → mozilla0.9.8
*** Bug 107967 has been marked as a duplicate of this bug. ***
*** Bug 111838 has been marked as a duplicate of this bug. ***
*** Bug 113364 has been marked as a duplicate of this bug. ***
*** Bug 114805 has been marked as a duplicate of this bug. ***
Depends on: 106083
Target Milestone: mozilla0.9.8 → mozilla0.9.9
Target Milestone: mozilla0.9.9 → mozilla1.1
*** Bug 126649 has been marked as a duplicate of this bug. ***
As a user, I am surprised that this bug still is not fixed.  Indeed, it is worse than I remember it from when I filled out a dupicate report (#10769 on 11-1-01).  I had to go to the unix.js and change the resolution to somewhere out of the range 71-73 dpi.  In the "Edit > Preferences > Fonts" submenu, changing this is no longer intuitive for regular users like me.  You have to choose "Other" and then measure the number of centimeters in the line.  Somewhere, even for ordinary users, it ought to be explained that if you choose a lower dpi, you will get larger type on printout (I prefer larger type because I prefer to print 2 pages per sheet with a2ps)  Also note, the changes in unix.js do take effect until one reboots.  Somehow, I do not remember having to do this when I originally confronted the a couple of versions ago in November.I am using: Mozilla 0.9.8Mozilla/5.0 (X11; U; Linux i686; en-US; rv:0.9.8) Gecko/20020204Sincerely,Daniel Wolkwolk@netcomp.net
nominating
Keywords: mozilla1.0, nsbeta1
*** Bug 128362 has been marked as a duplicate of this bug. ***
OK... So here is what a bit of investigation shows:

1)  When the dpi for screen is 72dpi, drawing typical images uses
    nsRenderingContextPS::DrawImage
2)  When the dpi is something else, drawing typical images uses
    nsRenderingContextPS::DrawScaledImage

Now the issue is that nsRenderingContextPS::DrawImage never applies a
transformation to the width of the image.  The problem with this is that as far
as I can tell the width as it comes in is in twips while the width as we want to
use it is in pixels.  Depending on the exact system configuration there are
around 20 twips to a pixel.  So we end up drawing the image about 20 times
larger than we want (as the summary says).

Making the following change in nsRenderingContextPS::DrawImage makes this bug a
lot better.

   sr.x = aSrcRect->x;
   sr.y = aSrcRect->y;
 #endif
-  mTranMatrix->TransformNoXLateCoord(&sr.x, &sr.y);
+  mTranMatrix->TransformCoord(&sr.x, &sr.y, &sr.width, &sr.height);
 
   nsCOMPtr<gfxIImageFrame> iframe;
   aImage->GetCurrentFrame(getter_AddRefs(iframe));

Make sure that you do this in the nsRenderingContextPS::DrawImage that is
preceded by the comment "/* [noscript] void drawImage (in imgIContainer aImage,
[const] in nsRect aSrcRect, [const] in nsPoint aDestPoint); */"

Could someone familiar with the whole thing check this out?  One thing that
bothers me is that the source rect and the dest rect actually have different
sizes in DrawScaledImage, so the output of DrawImage and DrawScaledImage is
still different, even with my change.  The only difference is that we'll be off
by a factor of 1.4 instead of a factor of 20.

Should we be _always_ calling DrawScaledImage() on the PostScript rendering
context?  Should the PostScript rendering context possibly use a different dpi
than 72, since it's obvious that it means something very different by that "72"
than other rendering contexts do?
Attached patch Patch to fixSplinter Review
OK, a look at nsRenderingContextImpl shows that all is as expected here except
that we need to transform the source rect as nsRenderingContextImpl does (if
nothing else, the source rect is in twips and we want pixels).

The different size for different DPI makes sense -- different DPI means
different physical size for images specified in pixel sizes, and it's the
physical size we're reflecting on paper.

Reviews, please?
As a note, this needs review from rods or dcone in addition to Roland's (since
apparently they're supposed to look at all changes to the PS code)....
Comment on attachment 72231 [details] [diff] [review]
Patch to fix

r=dcone
taking bug to get sr and check in
Assignee: dcone → bzbarsky
Priority: -- → P1
Summary: Images don't print correctly; each pixel scaled to ~20x20 pt → [FIX]Images don't print correctly; each pixel scaled to ~20x20 pt
Target Milestone: mozilla1.1 → mozilla1.0
Comment on attachment 72231 [details] [diff] [review]
Patch to fix

a=asa (on behalf of drivers) for checkin to the 1.0 trunk
Attachment #72231 - Flags: approval+
checked in on trunk
Status: NEW → RESOLVED
Closed: 23 years ago
Resolution: --- → FIXED
Can a few people on the cc: list try today's build out and
report back here on whether this looks fixed...thanks...
based on the feedback I receive, we will mark this VERIFIED-FIXED.
I will also test on my end...thanks.
I downloaded the nightly build from the /nightly/latest-0.9.9/ directory, and the 
problem still stands.

Daniel Wolk
REOPENING...I also compared output from today's build vs. yesterdays
build and I don't see any difference. I compared the netscape.com
home page on both builds(today and yesterday)
Status: RESOLVED → REOPENED
Resolution: FIXED → ---
Daniel Wolk wrote:
> I downloaded the nightly build from the /nightly/latest-0.9.9/ directory

Uhm, please read comment #43 - the fix was _ONLY_ checked into trunk - not the
0.9.9 branch.

Can anyone test a build from "latest-trunk", please ? :)
I just checked the 3/6 trunk build and I don't notice any difference
between today and yesterday.

I tried .../nightly/2002-03-06-07-trunk/mozilla-i686-pc-linux-gnu.tar.gz, 
and now this bug appears to be fixed.  Thanks.

Daniel Wolk
sujay, could you please retest?  I see a world of difference on netscape.com
between a 3/4 build and a 3/6 build.  Were you seeing the bug to start with? 
Were you printing on Linux?  (The bug is Linux-only.)
Ok I re-downloaded the trunk and I see the difference...

Status: REOPENED → RESOLVED
Closed: 23 years ago22 years ago
Resolution: --- → FIXED
verified.
Status: RESOLVED → VERIFIED
*** Bug 123552 has been marked as a duplicate of this bug. ***
I haven't been following this bug because I've been using Galeon for 6 months or
so, originally because of the tabbed browsing, but now more for the crash
recovery capability.

Nevertheless, I'm happy to see that the bug was finally tracked down and fixed,
considering the hours I put into narrowing it down.  Cool!

I noticed there's similar code in nsRenderingContextPS::DrawScaledImage -- is
there a possibility that it might need to change as well?  (I'm not prepared to
try to think it through at the moment! :-)

On a separate note, I'm still concerned that the *screen* DPI setting affects
the *printer* output scaling.  The printed page is a fixed size; why should the
size of my monitor have any effect on printouts?  This should be a separate bug
however; does such a bug already exist?
Deven, please file a separate bug on that issue..thanks.
Sujay, I was going to -- I was just asking if anyone knew of an existing bug for
that behavior, so I could avoid creating a duplicate.  As it happens, I just
found that bug 106083 exists about the problem, so I'll follow that one...
Summary: [FIX]Images don't print correctly; each pixel scaled to ~20x20 pt → [ps][FIX]Images don't print correctly; each pixel scaled to ~20x20 pt
> I noticed there's similar code in nsRenderingContextPS::DrawScaledImage

Yeah.  That code is as correct as any of this code is at the moment.  See
comment 35.
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: