[cairo] Unsymmetrical rotation

Blagoj Kupev bkupev at gmail.com
Sat Mar 9 15:08:36 PST 2013


Hello,

I finally found some time to go deeper in understanding how the
translations for my case work.

For the one's that are interested in the solution:

static void event_to_update(GtkWidget *widget, gpointer input_data)
{
  cairo_t *cr;
  int w, h;
  int x_origin, y_origin;
  cairo_matrix_t new_matrix;
  int *angle_s = input_data;

  //Load an image from a file
  cairo_surface_t *surf1 =
cairo_image_surface_create_from_png("./images/Untitled-1c.png");
  w = cairo_image_surface_get_width (surf1);
  h = cairo_image_surface_get_height (surf1);

  //Create the cairo context
  cr = gdk_cairo_create (widget->window);

  //Initialize the image to black transparent
  cairo_set_source_rgba(cr, 0, 0, 0, 1);
  cairo_paint(cr);

  x_origin = w/2;
  y_origin = h/2;

  cairo_translate (cr, x_origin, y_origin);
  cairo_rotate (cr, (2*3.14*angle_s/360));
  cairo_translate (cr, -x_origin, -y_origin);

  // ADD OFFSET. NOTE: The offset is upper left corner of the image.
  cairo_get_matrix(cr, &new_matrix);
  new_matrix.x0 += 100; //Add the x offset.
  new_matrix.y0 += 100; //Add the y offset.
  cairo_set_matrix(cr, &new_matrix);

  cairo_set_source_surface(cr,surf1, 0, 0);
  cairo_paint(cr);

  //Destroy the cairo context
  cairo_destroy(cr);

  cairo_surface_destroy(surf1);
}

Best regards,
Blagoj

On Tue, Mar 5, 2013 at 10:32 PM, Milan Sreckovic <msreckovic at mozilla.com>wrote:

> translate(-50,-50)
> rotate(angle)
> translate(320,160)
> set source surface(0,0)
>
> Milan
>
> On 2013-03-05, at 4:24 PM, Blagoj Kupev <bkupev at gmail.com> wrote:
>
> Hello,
> I might have problems describing what i'm trying to achieve, so let my try
> to explain it using some graphics. What i need to do is to place a gauge
> instrument at display that i'd like to rotate according to the input value.
> So i'm using a simple png image:
> +-------+
> |---o    |
> +-------+
> image 1
>
> The image 1 is with size of 100x100 pixels. Please note that the corners
> are invisible, so only the arrow is visible. What i'd like to achieve is to
> put it on window with size of 640x320 (fixed size) on bottom middle part of
> the window. When i tried to do this I'm noticing that the arrow image is
> not placed always at same place and the placement is dependent of the
> rotation angle.
> It seem that regardless of the placement of the origin of the image prior
> and after the rotation, cairo is using original image when
> cairo_set_source_surface is applied.
>
> This would mean that when the rotation is applied, the second
> cairo_transform is still calculated according to the original image and
> then the offset will be according to top-left corner of the original image.
>
> So now I'm wondering is there a simple method to rotate and place the
> original image at predefined offsets in the window or i should make complex
> CTM that will do this?
>
> Thanks,
> Blagoj
>
> On Tue, Mar 5, 2013 at 9:05 PM, Bill Spitzak <spitzak at gmail.com> wrote:
>
>> On 03/04/2013 11:15 PM, Carlos López González wrote:
>>
>>> Hi Blagoj,
>>> I don't think it is a bug I think that you need to do one extra step:
>>> If alpha is the angle (ccw), origin is the rotation center (in device
>>> units) and w,h are the final image dimensions you have to do this:
>>>
>>> cairo_translate(cr, origin.x, origin.y);
>>>
>>> cairo_rotate(cr, -1.0*angle);
>>>
>>> cairo_translate(cr, -origin.x, -origin.y);
>>>
>>> cairo_set_source_surface(cr, source, x, y);
>>>
>>> where x and y are the result of the minimum x and minimum y of the
>>> clockwise rotated corners
>>> of the source surface top_left(0,0), top_right(w, 0), bottom_left(0, h)
>>> and bottom_right(w, h).
>>>
>>
>> So you are saying the xy arguments for cairo_set_source_surface are the
>> location to put the top-left corner of the bounding box of the transformed
>> image? That's totally useless and very hard to believe! The only way to get
>> a predictable result is for both Cairo and the caller to do the exact same
>> bounding box calculation, thus they both have to do the transform?
>>
>> I'm pretty certain the xy cause a translation from some location that
>> Cairo considers "natural" and that it is either in the source surface space
>> (that might be useful) or in the CTM (in which case another cairo_translate
>> would do the same thing). I know I have gotten correct transforms out of
>> Cairo, though it is not easy. I think this was done by passing 0,0 for the
>> x,y.
>>
>>
>> --
>> cairo mailing list
>> cairo at cairographics.org
>> http://lists.cairographics.**org/mailman/listinfo/cairo<http://lists.cairographics.org/mailman/listinfo/cairo>
>>
>
> --
> cairo mailing list
> 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/20130310/7f658e03/attachment.html>


More information about the cairo mailing list