Bug 30282

Summary: Blurry results when scaling+copying a vector surface to an image surface
Product: cairo Reporter: Ian Britten <britten>
Component: generalAssignee: Carl Worth <cworth>
Status: RESOLVED FIXED QA Contact: cairo-bugs mailing list <cairo-bugs>
Severity: normal    
Priority: medium    
Version: 1.8.6   
Hardware: All   
OS: All   
Whiteboard:
i915 platform: i915 features:
Attachments: Blurry output, from attached sample code
Sample program attempting to copy+scale PDF to Image
Sample program showing workaround

Description Ian Britten 2010-09-20 08:15:27 UTC
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).
Comment 1 Ian Britten 2010-09-20 08:16:28 UTC
Created attachment 38814 [details]
Sample program attempting to copy+scale PDF to Image
Comment 2 Ian Britten 2010-09-21 10:13:14 UTC
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.
Comment 3 Ian Britten 2010-09-30 09:08:41 UTC
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.
Comment 4 rshann 2010-11-20 08:59:22 UTC
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!
Comment 5 Adrian Johnson 2010-11-27 09:30:11 UTC
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.
Comment 6 Adrian Johnson 2012-03-15 03:35:23 UTC
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.
Comment 7 Chris Wilson 2012-04-14 07:31:23 UTC
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.