Comment 148 for bug 179988

Revision history for this message
Adrian Johnson (ajohnson-redneon) wrote : Re: [Bug 179988] Re: no printing from Windows

Rygle wrote:
> Just did a build with the fallback set at 300dpi and it prints almost
> exactly the same as leaving the fallback unpatched. 40.4Kb and very
> pixelated
>
> Printed it out and on the giraffe I can literally count how many pixels
> are in an inch (well 2.54cm) because it has a constantly changing colour
> that makes successive pixels different colours. It's printing at about
> 18 or 19 dpi. It's like playing a game on a commodore 64 emulator.
>
> This leads me to think the default fallback is still 300dpi, as there is
> no difference between unpatched fallback and patched with hard 300dpi,
> but there's something else going wrong. Could it be the scale command
> that scaled this up from the tiny print that we were getting before?
>
>
I've found the bug in cairo that is causing this. The problem is we are
scaling the Windows DC from
the default 1 unit = 1 printer pixel to 1 unit = 1/72" with this code

+ SetGraphicsMode (hdc, GM_ADVANCED);
+ xform.eM11 = x_dpi/72.0;
+ xform.eM12 = 0;
+ xform.eM21 = 0;
+ xform.eM22 = y_dpi/72.0;
+ xform.eDx = -x_off;
+ xform.eDy = -y_off;
+ SetWorldTransform (hdc, &xform);

However this is causing a cairo to reduce the resolution of the fallback
images by a factor of dpi/72.
I'll have a look at what it will take to fix the problem in cairo. There
are couple of workarounds that
Inkscape can use. One workaround is to remove the above code and instead
scale the cairo content;

eg
cr = cairo_create (surface);
cairo_scale (cr, x_dpi/72.0, y_dpi/72.0);

The other, and likely the simpler, workaround is to scale up the
fallback resolution by dpi/72.

eg
  surface = cairo_win32_printing_surface_create (hdc);
  cairo_surface_set_fallback_resolution (surface, (x_dpi/72.0) * x_dpi,
(y_dpi/72.0) * y_dpi);

or to use a fixed 300 dpi:
  surface = cairo_win32_printing_surface_create (hdc);
  cairo_surface_set_fallback_resolution (surface, (x_dpi/72.0) * 300,
(y_dpi/72.0) * 300);