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

Andrew McRae amcrae at employees.org
Sun Dec 3 22:34:59 PST 2006

On Fri, 2006-12-01 at 15:21 -0500, Behdad Esfahbod wrote:
> On Mon, 2006-11-27 at 12:52 +1100, Andrew McRae wrote:
> > 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.

Yes, very true.

> 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.

I understand what you are getting at, but to me it's a little
meaningless to say `same size' when we are talking about
PDF surfaces vs X surface, since the units are different.
I'm not saying the model is wrong, just that to achieve the
end goal may need a slightly different approach.

> 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.

The cairo device unit for PDF being a point is a
little arbitrary (that's
my point, if you get what I mean), in that currently there's
no way to represent images in PDF in any better resolution
than 72 DPI (if there is, please outline it to me).

> 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.

Hmmm... OK, though to me `one inch' is not very meaningful
as a measurement of a pixel based image, so I don't think
this approach is that useful.

> 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.

I think you have highlighted my point, that we are talking
about different kinds of spaces, and it's not easy to treat
them all the same. The problem I'm trying to solve is how
to generate a high(er) resolution PDF than 72 DPI for
images painted into the surface. All we have done is
arbitrarily locked one point as the equivalent of
a pixel (in terms of when we use images in the PDF surface),
and it is this mapping that I think I'd like to be able to vary.
I do think it is useful to still address PDF surfaces
using points as dimensions, since this is the natural
unit for this kind of surface.

> Instead, what you can do is to kindly do a cairo_scale() yourself to
> bring all your _user_ spaces in line with each other.

Perhaps my ignorance is showing here, but wouldn't
doing a cairo_scale() simple scale my image down
so that it is the right size, but lower resolution?
Perhaps I'm wrong (when originally looking at this, I was
using 1.2.6, and couldn't see how cairo_scale would help me).

> Hope this makes some sense :)

I does, and I do ask for patience in working this through with me.

It occurs to me that an alternative approach is to perhaps
specify as part of the PDF surface create some kind of
resolution indication e.g:

  cairo_pdf_surface_create(file, width_in_points, height_in_points,
                           double resolution_dpi);

Then the drawing model is exactly the same, since you address
the surface in exactly the same way, and the only difference
is the way the surface backend processes objects that are
not dimensionable via points, such as images. Wouldn't
this work? Would this be an acceptable approach?
However I agree that it is still problematic to
mix-n-match images with PDF surfaces, since to me
images are inherently pixel based as opposed to vector backends.

More information about the cairo mailing list