[cairo] Patch for cairo - high resolution images in PDF surface.

Behdad Esfahbod behdad at behdad.org
Fri Dec 1 12:21:55 PST 2006

On Mon, 2006-11-27 at 12:52 +1100, Andrew McRae wrote:
> The main advantage is that most existing operations on a PDF
> surface are well supported as vector operations without
> resorting to lower resolution images e.g lines, fonts,
> arcs etc. Where this falls down are bit-mapped images, which
> by default appear as 72 DPI images - the consideration is that
> this is one of the commonest operations, and so is useful in
> a large number of cases. Which other operations do you think
> it should be supported on?
> In some ways it doesn't really do anything to the cairo model
> itself, but to the PDF backend. I agree that it could be
> seen as a kludge, and am happy to hear suggestions as to how
> we could do this with alternative approachs (that is the
> underlying point of the email, really :-)
> The thing is that the client code has exposure
> already to the fact it is a PDF surface, so it
> didn't seem too much of a twist to do it this way.

The fact that the client can get the type of the surface is no excuse.
Cairo is designed to allow for the same drawing code to be used and
reproduce similar results using any of the various supported backends.
So, if painting an image to my surface takes half the width of the
surface, it should take the same half if I render it to a PDF surface of
the same size, or an X surface of the same size, etc.

Now this brings the next point, that in cairo, every surface has a
device space and so device units.  That's fine as long as you work with
the same surface all the time, but when you mix and match surfaces, you
will figure out the device units are pretty arbitrary values, and do not
necessary match your expectation.

In your example, a device unit for an image surface is one pixel.  A
device unit for a PDF surface is a point.  As a result, if you paint an
image surface to a PDF surface without any scale, you get a 72dpi image.
If the PDF surface instead used mm as it's device unit, you would have
got a 25.4dpi image.

Now from your email, I can make the following suggestion: Add API like
cairo_surface_set_resolution() that is used to set the dpi to a surface.
This can be used then to match device units of any two surfaces, such
that if you paint surface A to surface B, the painted A is resized such
that one inch of A is mapped to one inch of B.

While this may look interesting at first sight, you may want to note
that then it doesn't make sense to have different device units now.
What good is such dpi-matching between surfaces if a line of width 100
you draw in one surface is 1.3in, while it's just .5in on another
surface?  So then you want to apply such a scaling to all operations.
But at that point, you'll figure it's just like rescaling all device
units to be in points.  Making such a change breaks all the hell loose.
Instead, what you can do is to kindly do a cairo_scale() yourself to
bring all your _user_ spaces in line with each other.

Hope this makes some sense :)

> I think the wider issue is that it does highlight the fundamental
> difference between bitmapped and vector backends, and how much
> should cairo be concerned with hiding the details of each (at
> whatever cost that is).
> Cheers,
> AMc

"Those who would give up Essential Liberty to purchase a little
 Temporary Safety, deserve neither Liberty nor Safety."
        -- Benjamin Franklin, 1759

More information about the cairo mailing list