[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