Changeset 474

Show
Ignore:
Timestamp:
03/07/2008 01:59:12 (6 months ago)
Author:
why
Message:
  • shoes/ruby.c: playing around with keeping a transformation matrix in images. will be useful when the image block syntax comes to be.
Location:
trunk/shoes
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • trunk/shoes/canvas.c

    r459 r474  
    310310 
    311311void 
     312shoes_apply_transformation(shoes_canvas *canvas, cairo_matrix_t *tf,  
     313  double x, double y, double w, double h, VALUE mode) 
     314{ 
     315  if (tf) 
     316  { 
     317    w /= 2.; h /= 2.; 
     318 
     319    if (mode == s_center) 
     320    { 
     321      cairo_translate(canvas->cr, w, h); 
     322      cairo_transform(canvas->cr, tf); 
     323    } 
     324    else 
     325    { 
     326      cairo_translate(canvas->cr, -x, -y); 
     327      cairo_transform(canvas->cr, tf); 
     328      cairo_translate(canvas->cr, x + w, y + h); 
     329    } 
     330  } 
     331} 
     332 
     333void 
    312334shoes_canvas_shape_do(shoes_canvas *canvas, double x, double y, double w, double h, unsigned char center) 
    313335{ 
     336  if (center) 
     337  { 
     338    w = 0.; h = 0.; 
     339  } 
     340 
    314341  cairo_save(canvas->cr); 
    315   if (center) 
    316   { 
    317     w = 0.; h = 0.; 
    318   } 
    319   else 
    320   { 
    321     w /= 2.; h /= 2.; 
    322   } 
    323  
    324   if (canvas->mode == s_center) 
    325   { 
    326     cairo_translate(canvas->cr, w, h); 
    327     cairo_transform(canvas->cr, canvas->tf); 
    328   } 
    329   else 
    330   { 
    331     cairo_transform(canvas->cr, canvas->tf); 
    332     cairo_translate(canvas->cr, x + w, y + h); 
    333   } 
     342  shoes_apply_transformation(canvas, canvas->tf, x, y, w, h, canvas->mode); 
    334343} 
    335344 
     
    806815    rb_hash_aset(attr, ID2SYM(s_click), rb_block_proc()); 
    807816  } 
    808   image = shoes_image_new(cImage, path, attr, self); 
     817  image = shoes_image_new(cImage, path, attr, self, canvas->tf, canvas->mode); 
    809818  if (!NIL_P(image)) 
    810819    rb_ary_push(canvas->contents, image); 
     
    913922 
    914923  cairo_curve_to(cr, x1, y1, x2, y2, x3, y3); 
    915   return self; 
    916 } 
    917  
    918 VALUE 
    919 shoes_canvas_transform(VALUE self, VALUE _m) 
    920 { 
    921   ID m = SYM2ID(_m); 
    922   SETUP(); 
    923  
    924   if (m == s_center || m == s_corner) 
    925   { 
    926     canvas->mode = m; 
    927   } 
    928   else 
    929   { 
    930     rb_raise(rb_eArgError, "transform must be called with either :center or :corner."); 
    931   } 
    932   return self; 
    933 } 
    934  
    935 VALUE 
    936 shoes_canvas_translate(VALUE self, VALUE _x, VALUE _y) 
    937 { 
    938   double x, y; 
    939   SETUP(); 
    940  
    941   x = NUM2DBL(_x); 
    942   y = NUM2DBL(_y); 
    943  
    944   cairo_matrix_translate(canvas->tf, x, y); 
    945   return self; 
    946 } 
    947  
    948 VALUE 
    949 shoes_canvas_rotate(VALUE self, VALUE _deg) 
    950 { 
    951   double rad; 
    952   SETUP(); 
    953  
    954   rad = NUM2DBL(_deg) * RAD2PI; 
    955  
    956   cairo_matrix_rotate(canvas->tf, -rad); 
    957   return self; 
    958 } 
    959  
    960 VALUE 
    961 shoes_canvas_scale(int argc, VALUE *argv, VALUE self) 
    962 { 
    963   VALUE _sx, _sy; 
    964   double sx, sy; 
    965   SETUP(); 
    966  
    967   rb_scan_args(argc, argv, "11", &_sx, &_sy); 
    968  
    969   sx = NUM2DBL(_sx); 
    970   if (NIL_P(_sy)) sy = sx; 
    971   else            sy = NUM2DBL(_sy); 
    972  
    973   cairo_matrix_scale(canvas->tf, sx, sy); 
    974   return self; 
    975 } 
    976  
    977 VALUE 
    978 shoes_canvas_skew(int argc, VALUE *argv, VALUE self) 
    979 { 
    980   cairo_matrix_t matrix; 
    981   VALUE _sx, _sy; 
    982   double sx, sy; 
    983   SETUP(); 
    984  
    985   rb_scan_args(argc, argv, "11", &_sx, &_sy); 
    986  
    987   sx = NUM2DBL(_sx) * RAD2PI; 
    988   sy = 0.0; 
    989   if (!NIL_P(_sy)) sy = NUM2DBL(_sy) * RAD2PI; 
    990  
    991   cairo_matrix_init(&matrix, 1.0, sy, sx, 1.0, 0.0, 0.0); 
    992   cairo_matrix_multiply(canvas->tf, canvas->tf, &matrix); 
    993924  return self; 
    994925} 
  • trunk/shoes/canvas.h

    r459 r474  
    123123typedef struct { 
    124124  cairo_surface_t *surface; 
     125  cairo_matrix_t *tf; 
     126  VALUE mode; 
    125127  shoes_place place; 
    126128  VALUE path; 
     
    261263shoes_canvas *shoes_canvas_init(VALUE, SHOES_SLOT_OS, VALUE, int, int); 
    262264void shoes_canvas_paint(VALUE); 
     265void shoes_apply_transformation(shoes_canvas *, cairo_matrix_t *,  
     266  double, double, double, double, VALUE); 
    263267void shoes_canvas_shape_do(shoes_canvas *, double, double, double, double, unsigned char); 
    264268VALUE shoes_canvas_style(int, VALUE *, VALUE); 
     
    406410void shoes_shape_send_release(VALUE, int, int, int); 
    407411 
    408 VALUE shoes_image_new(VALUE, VALUE, VALUE, VALUE); 
     412VALUE shoes_image_new(VALUE, VALUE, VALUE, VALUE, cairo_matrix_t *, VALUE); 
    409413VALUE shoes_image_alloc(VALUE); 
    410414VALUE shoes_image_draw(VALUE, VALUE, VALUE); 
  • trunk/shoes/ruby.c

    r469 r474  
    815815  rb_gc_mark_maybe(image->parent); 
    816816  rb_gc_mark_maybe(image->attr); 
     817  rb_gc_mark_maybe(image->mode); 
    817818} 
    818819 
     
    822823  if (image->surface != NULL) 
    823824    cairo_surface_destroy(image->surface); 
     825  SHOE_FREE(image->tf); 
    824826  RUBY_CRITICAL(SHOE_FREE(image)); 
    825827} 
    826828 
    827829VALUE 
    828 shoes_image_new(VALUE klass, VALUE path, VALUE attr, VALUE parent) 
     830shoes_image_new(VALUE klass, VALUE path, VALUE attr, VALUE parent, cairo_matrix_t *tf, VALUE mode) 
    829831{ 
    830832  GError *error = NULL; 
     
    839841    image->path = path; 
    840842    image->surface = surf; 
     843    cairo_matrix_init_identity(image->tf); 
     844    cairo_matrix_multiply(image->tf, image->tf, tf); 
     845    image->mode = mode; 
    841846    image->attr = attr; 
    842847    image->parent = parent; 
     
    854859  image->path = Qnil; 
    855860  image->surface = NULL; 
     861  image->tf = SHOE_ALLOC(cairo_matrix_t); 
     862  cairo_matrix_init_identity(image->tf); 
     863  image->mode = Qnil; 
    856864  image->attr = Qnil; 
    857865  image->parent = Qnil; 
     
    903911  if (RTEST(actual)) 
    904912  { 
    905     shoes_canvas_shape_do(canvas, place.ix, place.iy, place.iw, place.ih, FALSE); 
     913    cairo_save(canvas->cr); 
    906914    cairo_translate(canvas->cr, place.ix, place.iy); 
     915    shoes_apply_transformation(canvas, self_t->tf, place.ix, place.iy, place.iw, place.ih, self_t->mode); 
    907916    if (place.iw != imw || place.ih != imh) 
    908917    { 
     
    33913400  return self; 
    33923401} 
     3402 
     3403// 
     3404// Transformations 
     3405// 
     3406#define TRANS_COMMON(ele) \ 
     3407  VALUE \ 
     3408  shoes_##ele##_transform(VALUE self, VALUE _m) \ 
     3409  { \ 
     3410    GET_STRUCT(ele, self_t); \ 
     3411    ID m = SYM2ID(_m); \ 
     3412    if (m == s_center || m == s_corner) \ 
     3413    { \ 
     3414      self_t->mode = m; \ 
     3415    } \ 
     3416    else \ 
     3417    { \ 
     3418      rb_raise(rb_eArgError, "transform must be called with either :center or :corner."); \ 
     3419    } \ 
     3420    return self; \ 
     3421  } \ 
     3422  VALUE \ 
     3423  shoes_##ele##_translate(VALUE self, VALUE _x, VALUE _y) \ 
     3424  { \ 
     3425    GET_STRUCT(ele, self_t); \ 
     3426    double x, y; \ 
     3427    x = NUM2DBL(_x); \ 
     3428    y = NUM2DBL(_y); \ 
     3429    cairo_matrix_translate(self_t->tf, x, y); \ 
     3430    return self; \ 
     3431  } \ 
     3432  VALUE \ 
     3433  shoes_##ele##_rotate(VALUE self, VALUE _deg) \ 
     3434  { \ 
     3435    GET_STRUCT(ele, self_t); \ 
     3436    double rad; \ 
     3437    rad = NUM2DBL(_deg) * RAD2PI; \ 
     3438    cairo_matrix_rotate(self_t->tf, -rad); \ 
     3439    return self; \ 
     3440  } \ 
     3441  VALUE \ 
     3442  shoes_##ele##_scale(int argc, VALUE *argv, VALUE self) \ 
     3443  { \ 
     3444    VALUE _sx, _sy; \ 
     3445    double sx, sy; \ 
     3446    GET_STRUCT(ele, self_t); \ 
     3447    rb_scan_args(argc, argv, "11", &_sx, &_sy); \ 
     3448    sx = NUM2DBL(_sx); \ 
     3449    if (NIL_P(_sy)) sy = sx; \ 
     3450    else            sy = NUM2DBL(_sy); \ 
     3451    cairo_matrix_scale(self_t->tf, sx, sy); \ 
     3452    return self; \ 
     3453  } \ 
     3454  VALUE \ 
     3455  shoes_##ele##_skew(int argc, VALUE *argv, VALUE self) \ 
     3456  { \ 
     3457    cairo_matrix_t matrix; \ 
     3458    VALUE _sx, _sy; \ 
     3459    double sx, sy; \ 
     3460    GET_STRUCT(ele, self_t); \ 
     3461    rb_scan_args(argc, argv, "11", &_sx, &_sy); \ 
     3462    sx = NUM2DBL(_sx) * RAD2PI; \ 
     3463    sy = 0.0; \ 
     3464    if (!NIL_P(_sy)) sy = NUM2DBL(_sy) * RAD2PI; \ 
     3465    cairo_matrix_init(&matrix, 1.0, sy, sx, 1.0, 0.0, 0.0); \ 
     3466    cairo_matrix_multiply(self_t->tf, self_t->tf, &matrix); \ 
     3467    return self; \ 
     3468  } 
     3469 
     3470TRANS_COMMON(canvas); 
     3471TRANS_COMMON(image); 
    33933472 
    33943473// 
     
    39454024  rb_define_method(cImage, "size", CASTHOOK(shoes_image_size), 0); 
    39464025  rb_define_method(cImage, "move", CASTHOOK(shoes_image_move), 2); 
     4026  rb_define_method(cImage, "rotate", CASTHOOK(shoes_image_rotate), 1); 
     4027  rb_define_method(cImage, "scale", CASTHOOK(shoes_image_scale), -1); 
     4028  rb_define_method(cImage, "skew", CASTHOOK(shoes_image_skew), -1); 
     4029  rb_define_method(cImage, "transform", CASTHOOK(shoes_image_transform), 1); 
     4030  rb_define_method(cImage, "translate", CASTHOOK(shoes_image_translate), 2); 
    39474031  rb_define_method(cImage, "top", CASTHOOK(shoes_image_get_top), 0); 
    39484032  rb_define_method(cImage, "left", CASTHOOK(shoes_image_get_left), 0);