[Date Prev][Date Next][Thread Prev][Thread Next][Thread Index]

RE: [XaraXtreme-dev] Printing

I'm only going to comment on the general printing mechanism rather than
the UI...

In the general case on Windows, Camelot expects to be printing to a
non-postscript printer. It renders using an OSRenderRegion (with the
complex parts being handled as bitmaps generated through a
GRenderRegion, and blitted back to the OSRenderRegion) - this is
described in detail here and here. The OSRenderRegion renders into a
Windows printer DC, which (via GDI) produces output on the printer. 

An exception is made when the printer is Postscript (possibly unless the
entire page is to be printed as a bitmap). Here, Camelot generates its
own Postscript output, and inserts it into the output stream.
Documentation can be found here. It is not too clear when Camelot uses
the OSRenderRegion to plot during postscript printing. The suggestion is
that this is used only for printing text as exporting the relevant fonts
etc. is too hard, though this explanation does not entirely stack up
when the same code exports text as EPS in a perfectly satisfactory

This isn't strictly true. In the general case on Windows, Camelot
doesn't care in the slightest what sort of printer it is printing to. 

When the print method is set to bitmap or anti-aliased bitmap, it
creates a GRenderRegion of the area to be rendered so the document is
rendered via GDraw and is then "blitted" into whatever DC is provided by
the OS.  It doesn't care what happens to it after that point.  It will
get converted into whatever data is necessary for the particular
printer.  For a PS printer, GDI and the printer driver will create the
necessary postscript to get the bitmap onto the page and the same will
happen for non-PS printers (except it will generate whatever printer
language is required for the printer).

When the print method is normal/postscript (i.e. not bitmap or aabitmap)
then we either create a PrintPSRenderRegion or an OSRenderRegion so that
some of the document can be passed to the OS provided device as vectors
and then we use the optimal render loop mechanism to rasterise those
parts that require it.  The only time we would use an OSRenderRegion to
print to a postscript printer would be if the printer device doesn't
support the insertion of our own postscript.

The code that creates the relevant RenderRegion is in

To do decent postscript printing we have to be able to insert our own
postscript.  There are lots of reasons for this but the most obvious one
is that we want to be able to send precise CMYK colours and have them
come out exactly as intended in the postscript.  With standard OS
rendering this is not (or at least definitely was not) possible and
everything would convert via RGB.

As you mention, when doing postscript printing, the code claims to use
the text rendering of the OS provided device because this is much easier
than writing all the different levels of postscript text handling.  I'm
not convinced that this is actually true but regardless, it never uses
an OSRenderRegion.  It either asks our postscript DC to render the text
or it asks the base RenderRegion class to do it (which results in it
being rendered as paths).  An OSRenderRegion is basically a generic
RenderRegion that renders using whatever features are provided by an OS
provided DC.

So, to sum up, I believe that, to get "correct" postscript output, we
absolutely require the ability to insert our own postscript and the
decision as to whether we use an OSRenderRegion or a PrintPSRenderRegion
depends on whether the OS provided device supports postscript injection.

For portability reasons we should keep as much of the current system as
possible, e.g. we should still support printing to devices that don't
allow postscript injection (either because they just don't support it or
because they are not postscript based at all) because on Windows (at
least) we will be passed OS provided DCs like this.