[cairo] Meta surface proposal

Owen Taylor otaylor at redhat.com
Tue Feb 8 08:45:36 PST 2005


On Sun, 2005-02-06 at 18:11 -0800, Keith Packard wrote:
> >  - Conversion of trapezoid lists into paths and back
> 
> The PDF file will contain only trapezoids...
> 
> >  - Serialization of images
> 
> We already have to do this for whatever metafile format we use -- for the 
> in-memory version, we may well have to keep many copies of source surfaces 
> in different states.

There's no need to serialize images, just copy (possible on-write).

> > - Embedding of fonts, including bitmap fonts
> 
> It's not the embedding that frightens me here -- we have to do that to 
> support PDF.  It's loading them back into FreeType which seems a terrible 
> waste.  We could investigate some mechanism for mapping the font in the 
> meta file back to a font file, but that seems obtuse.

Obtuse, but necessary. What you want is a reference to an in-memory
font object. If you want to write that to disk, then you need to figure
out how you are going to get that in-memory font object back. It's
possible to have fonts that Windows won't even let you embed but you
can still print to a printer.

> > To me it's a horrifyingly complex prospect for something that really
> > should be essentially pretty simple. There are 4, count them, 4,
> > functions in the surface vtable for drawing currently.
> 
> Any metafile format will need to capture all state related to external 
> objects for each rendering operation.  This seems like the hard part of 
> the metafile generation; optimizing cases where source images are re-used 
> unchanged and the like.  I agree there is a good chance to optimize this 
> into zero-copy if we have reasonable surface modification notification and 
> store the metafile purely in memory.

But there aren't really complicated external objects in the backend API.
What we have now are:

 - Patterns. Can just be copied ... they are only large if they contain
   surface references. See below.

 - Surfaces. Probably want a copy-on-write mechanism; another
   possibility that Kristian suggested was to do an immediate copy
   then have serial on the surface to see whether the previous copy
   could be used.

 - Fonts. Referencing the font object should be fine ... cairo_font_t 
   isn't mutable.

> > Can you create test cases where the in-memory buffer for rendering a 
> > single page becomes huge? Yes, you could. But in those cases I'd argue
> > that the final produced output file will also be huge.
> 
> I guess I disagree that the size of the output file is relevant here.
> Imagine a 'thumbnail' preview of a set of slides -- that captures all of 
> the graphics for an entire presentation onto a single page, something 
> which seems like a common operation and which encapsulates the rendering 
> operations for an entire presentation in a single page.

How is this going to be smaller in the final output file? (assume the
final output file is vector based ... doing all this work for a raster
output file seems silly.) 

> I also suggest we separate the format of the meta file data from the
> storage mechanism; there's really no reason a custom metafile format need
> be storable only in memory, nor is there any reason a PDF file need be
> stored on disk.

Well, the reason for the "metafile format" to be storable only in memory
is that we can avoid it being either a file or a format. It's just a 
data structure recording a drawing stream.

> > Plus, it's very much unclear to me how you'd do the image-vs-vector 
> > separation without having the entire page parsed in memory at once
> > anyways.
> 
> I don't know why you'd need to hold the whole page in memory for this;
> you're only interested in computing the portion of the page which cannot be
> drawn with the native graphics operations; that can be done by iterative
> scans of the metafile to find a fixed point for the region connected to
> undrawable objects.  That's doable in fixed storage if you didn't mind 
> the bounds being computed as a single rectangle.  Of course, optimizing 
> this to avoid quadratic behaviour would probably be a good idea, and that 
> might take some additional storage.

Well, first, for background-image-with-foreground-vector reasons, you 
might well want to do the scan over the page in reverse order ...

But in general, making multiple passes over a disk file rather than
just working in memory seems like a technique we should only resort
to when we know that we have multi-gigabyte pages in the output
file.

While writing polygons-as-traps to PDF or PS is a good way of producing
multi-gigabyte output files (and killing printers) I think reasonable
sized output files should be reasonable to work with in memory as
well.

[....]

> One alternative here is to publish this metafile format and create external
> metafile->printer conversion utilities; this would reduce the code needed
> within the cairo library itself and would ease the release engineering
> problems inherant in producing a single library with many
> mutually-incompatible pieces.

 - We need to be able reliably fork off helper programs from a library.
   Not simple on Unix (SIGCHLD handlers / waitpid() in the app can mess
   you up.) Not easy to do cross-platform.
 
 - Once someone has selected a printer and printer options (using
   whatever native scheme the platform has) we need to pass those
   to the helper programs.

 - We need to have two separate Win32 backends sharing some but not
   all code.

 - The fallback logic has to be duplicated in each such backend, or
   we'll need a libcairofallback.

I don't see how process separation helps code maintenance issues
and I don't think we are really talking about that much code ...
guessing code size in advance of writing it is hard, but the 
meta surface is probably about 1000 lines, with a similar number
added elsewhere in Cairo to support it.

Regards,
					Owen





More information about the cairo mailing list