[cairo] Proposal: cairo_document_t

David Malcolm dmalcolm at redhat.com
Fri Dec 3 10:46:19 PST 2004

On Fri, 2004-12-03 at 00:56 -0500, Kristian Høgsberg wrote:
> Hi,
> I've been having some trouble trying to shoe-horn the multi page
> nature of PDF documents into the cairo API.  Consider drawing to a
> surface, calling show page, drawing some more.  What would it mean to
> use that surface as a pattern fill?
> I was planning to break some of the state in cairo_pdf_surface_t out
> into a cairo_pdf_document_t.  I wanted to do this internally in the
> PDF backend, but the more I think about it, the more I think it makes
> sense to expose this in the user API.
> So, what I propose is that we add a new object to the public API:
>      cairo_document_t
> A cairo document is a separate object from a cairo surface.  A cairo
> document consists of a number of pages, each of which is just a cairo
> surface.  A cairo surface doesn't necessarily correspond to a page in
> the file, it can be an auxiliary surface used for e.g. a watermark or
> pattern fill.
> This simplifies the concepts: a surface isn't implicitly also a PDF
> document or a collection of pages, a surface is just a canvas that you
> paint on.  All surfaces are equal, instead of now where one of them
> magically is the PDF file.  A page is just another surface and could
> be used as a fill pattern on a later page if that is what you want.
> This change implicitly divides the backends into two groups: paginated
> backends (PDF, Postscript, SVG?) and simple backends (image, png, X).
> Paginated backends should implement the corresponding document type, 
> while simple backends do not have a corresponding document type.
> At a glance this seems to complicate the API: more objects, more
> functions, but I'd argue that it actually simplifies it.  For simple
> backends, the API is the same, except we remove cairo_show_page() and
> cairo_copy_page().  Thus, the API is smaller and we keep pagination
> out of the backends where it doesn't make sense.  On the other hand,
> if you are using a paginated backend, the document object is an
> intuitive and explicit representation of the document you are
> generating, and makes a good home for the pagination functionality.
> The API I would like to propose has a function for creating documents
> for each paginated backend.  For PDF it would be:
>      cairo_document_t *
>      cairo_pdf_document_create (FILE	*file,
> 			       double	width_inches,
> 			       double	height_inches,
> 			       double	x_pixels_per_inch,
> 			       double	y_pixels_per_inch);

Can different pages have different sizes within a document?  What would
the different backends actually support?  IIRC, XSL:FO allows a document
to have multiple page sizes within it,  I don't know about PDF and PS

> Creating a PDF surface takes a reference to the document it is part
> of:
>      cairo_surface_t *
>      cairo_pdf_surface_create (cairo_document_t 	*document,
> 			      double		width,
> 			      double		height);
> This is in line with the other surface creating functions, but the
> document should work as a surface factory so drawing code can add a
> new page without knowledge of the backend in use:
>      cairo_surface_t *
>      cairo_document_create_page (cairo_document_t	*document);
> A page is just a regular surface and can be used as the target surface
> using cairo_set_target_surface ().  To actually add the page to the
> document page sequence use
>      cairo_status_t
>      cairo_document_add_page (cairo_document_t	*document,
> 			     cairo_surface_t	*page);
> Just like we have cairo_set_target_png() and similar convenience
> functions there could be:
>      cairo_status_t
>      cairo_set_target_new_page (cairo_t		*cr,
> 			       cairo_document_t	*doc);
> which does:
>      page = cairo_document_create_page (doc);
>      cairo_set_target_surface (cr, page);
>      cairo_document_add_page (doc, page);
>      cairo_surface_destroy (page);
> I think this makes pretty good sense, and I have a good idea of how to
> implement it in the PDF backend.  Except for removing the show_page()
> and copy_page() functions, there would be no changes to existing
> backends.
> Comments?
> cheers,
> Kristian
> _______________________________________________
> cairo mailing list
> cairo at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/cairo

More information about the cairo mailing list