Created attachment 38813 [details] Blurry output, from attached sample code As first mentioned via http://lists.cairographics.org/archives/cairo/2010-September/020864.html , there seems to be an undesirable result when copying AND SCALING an existing surface to another one. In this workflow, I've created+populated a PDF surface, and am trying to extract a high-resolution image of a portion of it. Unfortunately, the end result is extremely blurry, as if a low-resolution image was simply stretched. It's not at all what I'd expect given the source surface was PDF (vector). Doing a straight "no-scale" copy produces quality results, but as soon as a scaling factor is introduced, the results don't match what one would have expected, assuming that vector instructions were simply 'replayed' on the final image surface at a different scale. After some discussions on IRC, ranma42 acknowledged it as a valid Cairo problem that could/should be fixed (Hence this bug). In the meantime, I've been struggling to find a workaround that will produce the desired results using the existing Cairo interfaces, but to no avail. Ideally, I'd like to find some sort of solution that could work with the existing 1.8.x API, if possible (irregardless of performance, etc).
Created attachment 38814 [details] Sample program attempting to copy+scale PDF to Image
Created attachment 38846 [details] Sample program showing workaround Attached is a (more extensive) sample, containing a work-around that seems to be working. As suggested by ranma42 (IRC), performing the scaling onto a second vector/PDF surface, and then copying the PDF to the Image for rasterization (with a 1-1 scaling) almost works. The final key is to set the filtering to CAIRO_FILTER_NEAREST, when scaling the source PDF to the temporary PDF. Admittedly, setting the filtering seems like it should be unnecessary, since it should be copying vector to vector (ie: lossless). However, that is probably the crux of the Cairo problem. Hopefully in the future version of Cairo, a 1-step copy will 'just work', and this 2-step workaround won't be needed.
Actually, after looking closer, this isn't actually working as I would have hoped/expected... It seems that what looks like a 'pixel' in the final image is much bigger than an single image pixel. In my example, the surface is scaled by 11. Unfortunately, when examining the final image, each visual 'pixel' that has been rendered is actually made up of 11x11 individual image pixels. In other words, the result is far coarser and pixelated than it should be.
I wanted to create a pattern from an SVG file to be use for repeatedly drawing, and ranm47 on #cairo warned me I might hit this problem. The code I came up with: RsvgHandle *handle = rsvg_handle_new_from_file(filename, &error); cairo_surface_t *surface = cairo_svg_surface_create_for_stream (NULL, NULL, width, height); cairo_t *cr = cairo_create(surface); rsvg_handle_render_cairo(handle, cr); rsvg_handle_close(handle, NULL); g_object_unref(handle); cairo_pattern_t *pattern = cairo_pattern_create_for_surface (surface); certainly seems to give a blurry result when I use pattern as a mask for rendering to the final surface. If this is not another example of the same thing, please let me know!
This is similar to the fallback resolution bug where images acquired from the recording surface it at a fixed resolution. With the fallback resolution bug now fixed it should not be hard to fix this. I have an experimental patch here http://cgit.freedesktop.org/~ajohnson/cairo/commit/?h=fix-blurry-copy-from-pdf-surface&id=6de38c2a32095296fa23c21dd8720936e57aebb1 that makes your test case work. However it causes a few test failures in the test suite that will need investigating.
The sample program in comment 1 works with cairo 1.11.4 if you change the pdf surface to a recording surface. I'm not sure why it is still not working for paginated surfaces.
I believe Adrian tricked me into fixing this for releasing 1.12. ;-) Please do test.
Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.