8.8 Rendering Pages
To render a page, you first need to know how big it is. This can be discovered by
calling fz_bound_page, passing a fz_rect in to be populated:
/* fz_bound_page: Determine the size of a page at 72 dpi. Does not throw exceptions. */ fz_rect *fz_bound_page(fz_context *ctx, fz_page *page, fz_rect *rect);
MuPDF operates on page contents (and annotations) by processing them to a
Device. There are various different devices in MuPDF (and you can implement your
own). See chapter 9 The Device interface for more information. For now, just
consider devices to be things that are called with each of the graphical items on the
page in turn.
The simplest way to process a page is to call fz_run_page:
/* fz_run_page: Run a page through a device. page: Page obtained from fz_load_page. dev: Device obtained from fz_new_*_device. transform: Transform to apply to page. May include for example scaling and rotation, see fz_scale, fz_rotate and fz_concat. Set to fz_identity if no transformation is desired. cookie: Communication mechanism between caller and library rendering the page. Intended for multi-threaded applications, while single-threaded applications set cookie to NULL. The caller may abort an ongoing rendering of a page. Cookie also communicates progress information back to the caller. The fields inside cookie are continually updated while the page is rendering. */ void fz_run_page(fz_context *ctx, fz_page *page, fz_device *dev, const fz_matrix *transform, fz_cookie *cookie);
This will cause each graphical object from the page contents and annotations in turn
to be transformed, and fed to the device.
For finer control, you may wish to run the page contents, and the annotations
separately:
/* fz_run_page_contents: Run a page through a device. Just the main page content, without the annotations, if any. page: Page obtained from fz_load_page. dev: Device obtained from fz_new_*_device. transform: Transform to apply to page. May include for example scaling and rotation, see fz_scale, fz_rotate and fz_concat. Set to fz_identity if no transformation is desired. cookie: Communication mechanism between caller and library rendering the page. Intended for multi-threaded applications, while single-threaded applications set cookie to NULL. The caller may abort an ongoing rendering of a page. Cookie also communicates progress information back to the caller. The fields inside cookie are continually updated while the page is rendering. */ void fz_run_page_contents(fz_context *ctx, fz_page *page, fz_device *dev, const fz_matrix *transform, fz_cookie *cookie); /* fz_run_annot: Run an annotation through a device. page: Page obtained from fz_load_page. annot: an annotation. dev: Device obtained from fz_new_*_device. transform: Transform to apply to page. May include for example scaling and rotation, see fz_scale, fz_rotate and fz_concat. Set to fz_identity if no transformation is desired. cookie: Communication mechanism between caller and library rendering the page. Intended for multi-threaded applications, while single-threaded applications set cookie to NULL. The caller may abort an ongoing rendering of a page. Cookie also communicates progress information back to the caller. The fields inside cookie are continually updated while the page is rendering. */ void fz_run_annot(fz_context *ctx, fz_annot *annot, fz_device *dev, const fz_matrix *transform, fz_cookie *cookie);
These functions enable viewer applications to generate separate display lists for page
contents and annotations. This can be useful if annotations are frequently changed,
as it allows regeneration/redraw to happen on a per-annotation rather than per-page
level.
All three of these functions (fz_run_page, fz_run_page_contents, fz_run_annot)
take a fz_cookie pointer. The Cookie is a lightweight way of controlling the
processing of the page. For more details, see section 9.3 Cookie. For most simple
cases this can be NULL.