Comment 91 for bug 179988

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

Ulferikson wrote:
>> I am puzzled why saving to ps via Cairo produces clean
>> vectors with no white blocks.
>
> With save as ps you ask cairo to produce the postscript. With print to a
> postscript printer I think cairo produces a windows meta file and the
> printer driver will translate that to a postscript. The white blocks
> have been said to come because gtk asks cairo for the wrong sort of meta
> file. at least that is my understanding

The reason for the white blocks is because gtk is using
cairo_win32_surface instead of cairo_win32_printing_surface for printing.

The difference is:

cairo_win32_surface_create() accepts a DC supplied by the application.
It will call the GDI functions for a small number of operations where
the GDI rendering matches cairo rendering. Mostly just text and
filling/stroking of rectangles that are on integer coordinates with
solid colors. For anything else cairo reads and writes a bitmap
associated with the DC. This does not work well with DCs for printers
where there is no bitmap that can be accessed.

cairo_win32_printing_surface_create() also accepts a DC however it
restricts itself to only calling the GDI functions for
fill/stroke/text/drawing images. At printer resolutions antialiasing is
not required. The cairo_win32_printing_surface shares the same code as
the PostScript backend for supporting transparency. ie it generates
fallback images and paints them onto the DC after all the vector drawing
has completed.

When printing, Windows writes all the GDI functions called on the
printer DC out to an EMF file (the spool file) then replays this to the
printer driver. The printer driver will generate PostScript, PCL, or
whatever the printer supports and send it to the printer.

So you can see that when printing Windows records all the GDI function
calls to a spool file however cairo_win32_surface is writing to a bitmap
in memory associated with the DC. All the drawing to the in memory
bitmap cairo does will not end up in the spool file.

That is why I wrote the cairo_win32_printing_surface. It was simply not
possible to fix cairo_win32_surface to better support printing. The
win32_surface was designed to be fast when drawing on the screen while
the win32_printing_surface was designed to be careful to only use GDI
function calls for drawing and never try to read image data back from
the DC.