[cairo] patch [1/1] invert image in _cairo_gl_surrface_map_to_image

Henry (Yu) Song - SISA hsong at sisa.samsung.com
Wed Jan 4 09:32:09 PST 2012


Hi, Swati

Assume you already have two image surfaces, img_surface  is image surface of 200x200 and dst_surface is of size 400x400.  You want to paint img_surface to dst_surface, you can do this

/* prepare cairo for drawing img_surface to dst_surface */
cairo_t *cr = cairo_create (dst_surface);

/* set img surface to paint from (100, 100) to (300, 300) */
cairo_set_source_surface (cr, img_surface, 100, 100);

/* paint it */
cairo_paint (cr);

/* dump dst_surface to png file for exam */
cairo_surface_write_to_png (dst_surface, "png file");

/* cleanup */
cairo_destroy (cr);

Hope this helps

Henry

From: swati upadhyaya [mailto:swatiupadhyaya at gmail.com]
Sent: Wednesday, January 04, 2012 5:56 AM
To: Andrea Canciani
Cc: Henry (Yu) Song - SISA; cairo at cairographics.org
Subject: Re: [cairo] patch [1/1] invert image in _cairo_gl_surrface_map_to_image

Hi Henry and Andrea,

First of all thanks for reply [cid:image001.png at 01CCCAC3.C209D700]

                                  I didn't get what you people mentioned as I am new to cairo lib [cid:image002.png at 01CCCAC3.C209D700] . Let me explain my problem briefly, Suppose I have a device with screen width and height as 400 x 400. And I have an image with 200 x 200. Now in my device for this image start of x=100 and end of x = 300. Now I have to draw the line from 100 to 300..I am using the API
surface = cairo_image_surface_create_for _data(unsigned char *buff,CAIRO_FORMAT_ARGB32,width,height,cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32,width))
where width is image width = 200
height is image height = 200.
Then I am doing
cr = cairo_create(surface);

Now the problem is as the surface starts from top left only so it will go from 0 to 200 but I want to draw form 100 to 300. So
1) what can I do to shift the origin of the surface fom 0 to 100 ? So that it will draw on the same..
 I am using elementary API(like evas,efl). And on mouse move callback I am drawing the line...
2) I have tried giving whole the width and height as my devise that is width = height = 400. But in this case while saving the image some scaling factor occur and line drawn become thin and position is also shifted. This is because we are capturing 400 x 400 to 200 x 200 image.

First time I am using cairo lib thats why not familiar of everything.
for the image with the width and height same as screen its working fine..as for that surface as well as image both starts from 0.


Please let me know how to solve this problem(how to shift the origin of the surface so that I can draw exactly from where I want to draw)...




On Wed, Jan 4, 2012 at 2:13 PM, Andrea Canciani <ranma42 at gmail.com<mailto:ranma42 at gmail.com>> wrote:
On Wed, Jan 4, 2012 at 1:56 AM, Henry (Yu) Song - SISA
<hsong at sisa.samsung.com<mailto:hsong at sisa.samsung.com>> wrote:
> Date:   Fri Dec 30 11:24:54 2011 -0800
>
>    gl: Add support to invert non texture gl surface image that does not have
>    GL_MESA_pack_invert when map from gl surface to image surface
>
> diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c
> index 8f69033..8b8f196 100644
>
> --- a/src/cairo-gl-surface.c
> +++ b/src/cairo-gl-surface.c
> @@ -1001,6 +1001,10 @@ _cairo_gl_surface_map_to_image (void      *abstract_surface,
>     unsigned int cpp;
>     cairo_bool_t invert;
>     cairo_status_t status;
> +    cairo_t *inv_cr = NULL;
> +    cairo_image_surface_t *inv_image = NULL;
> +    cairo_pattern_t *inv_pattern = NULL;
> +    cairo_matrix_t inv_matrix;
>
>     /* Want to use a switch statement here but the compiler gets whiny. */
>     if (surface->base.content == CAIRO_CONTENT_COLOR_ALPHA) {
> @@ -1093,6 +1097,50 @@ _cairo_gl_surface_map_to_image (void      *abstract_surface,
>        image = (cairo_image_surface_t *)
>            _cairo_surface_create_in_error (status);
>     }
> +
> +    /*
> +     * FIXME: we must invert the image if it is non texture surface,
> +     * and it does not have GL_MESA_pack_invert.
> +     * Is there more efficient way to invert image?
Using negative stride might be more efficient, but some backends might
not (yet) support them correctly.

Side note:
It is already possible to create negative stride images.
Should we add a test trying to use them and support them?
Unless I get feedback, I'll try to write the test this weekend.

> +     */
> +
> +    if (! _cairo_gl_surface_is_texture (surface) && ! invert) {
> +        inv_image = (cairo_image_surface_t*)
> +       _cairo_image_surface_create_with_pixman_format (NULL,
> +                                                       pixman_format,
> +                                                       extents->width,
> +                                                       extents->height,
> +                                                       -1);
> +       if (unlikely (inv_image->base.status)) {
> +           goto CLEAR_IMAGE;
> +       }
> +
> +       image->base.is_clear = FALSE;
> +       inv_pattern = cairo_pattern_create_for_surface (&image->base);
> +       if (unlikely (inv_pattern->status)) {
> +           goto CLEAR_PATTERN;
> +       }
> +       cairo_matrix_init_scale (&inv_matrix, 1.0, -1.0);
> +       cairo_matrix_translate (&inv_matrix, 0, -(extents->height));
> +       cairo_pattern_set_matrix (inv_pattern, &inv_matrix);
> +
> +       inv_cr = cairo_create (&inv_image->base);
> +       if (unlikely (inv_cr->status)) {
> +           goto CLEAR_CAIRO;
> +       }
> +       cairo_set_source (inv_cr, inv_pattern);
> +       cairo_set_operator (inv_cr, CAIRO_OPERATOR_SOURCE);
> +       cairo_paint (inv_cr);
You're using the same surface as source and as destination.
This results in undefined behavior.
If you want to flip the image like this, you should use two independent surfaces


> +       cairo_surface_destroy (&image->base);
> +       image = (cairo_image_surface_t *)cairo_surface_reference (&inv_image->base);
> +    }
> +
> +CLEAR_CAIRO:
> +    cairo_destroy (inv_cr);
> +CLEAR_PATTERN:
> +    cairo_pattern_destroy (inv_pattern);
> +CLEAR_IMAGE:
> +    cairo_surface_destroy (&inv_image->base);
>
>     return &image->base;
>  }
> --
> cairo mailing list
> cairo at cairographics.org<mailto:cairo at cairographics.org>
> http://lists.cairographics.org/mailman/listinfo/cairo
--
cairo mailing list
cairo at cairographics.org<mailto:cairo at cairographics.org>
http://lists.cairographics.org/mailman/listinfo/cairo



--
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.cairographics.org/archives/cairo/attachments/20120104/8a43c04a/attachment.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image001.png
Type: image/png
Size: 645 bytes
Desc: image001.png
URL: <http://lists.cairographics.org/archives/cairo/attachments/20120104/8a43c04a/attachment-0002.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image002.png
Type: image/png
Size: 612 bytes
Desc: image002.png
URL: <http://lists.cairographics.org/archives/cairo/attachments/20120104/8a43c04a/attachment-0003.png>


More information about the cairo mailing list