How rendering works¶
To render Page objects graphically, a Page class should implement three
methods: paint()
, print()
and image()
.
paint()
is used to paint the image in the View, in page coordinates. If painting is expensive, this method should return immediately and schedule a pixmap to be drawn in a background thread (see below).print()
is used to paint the image to a QPainter on any QPaintDevice, in original coordinates (i.e. the used QPainter has already been transformed to the original page size without rotation).image()
is used to get a rendered QImage.
Most Page classes depend on a Renderer
that
implements the actual rendering. The base Renderer class has functionality for
caching and for tile-based rendering in a background thread, so when you zoom
in very far, only a small portion of the original page is drawn on a pixmap to
be displayed on the screen.
Awaiting the rendering, the View scales another image from the cache of the same region (if available) to display instead.
It is not necessary to specify a renderer directly, although it can be useful.
All builtin page classes install a default renderer. Page types that use a
renderer inherit from page.AbstractRenderedPage
.
Available Page types¶
These are the currently available Page types, and their corresponding Document types:
Module |
Page type |
Document type |
Displays |
---|---|---|---|
all image formats supported by QImage |
|||
SVG images, one file per page |
|||
PDF documents, multiple pages per file |
|||
color composites other pages of any type |
Implementing a new page type¶
If you study the source of the svg
module, you can see
that there is only very little code needed to implement a rendered Page type.
For the rendered Page, Page.paint()
calls Renderer.paint()
, which schedules
an image to be generated. The image is generated by Renderer.render()
, which by default calls
Renderer.draw()
, which does the actual
drawing work. Also Page.print()
calls
Renderer.draw()
directly, while
Page.image()
simply calls
Renderer.image()
, which also calls
Renderer.render()
, which in turns
calls Renderer.draw()
.
So you actually only need to implement Renderer.draw()
:-) But, depending on the characteristics of
the underlying graphics type, other strategies may be combined to achieve a
well-working Page type.