/* * call-seq: * rotozoom( angle, zoom, smooth=false ) -> Surface * * Return a rotated and/or zoomed version of the given surface. Note that * rotating a Surface anything other than a multiple of 90 degrees will * cause the new surface to be larger than the original to accomodate the * corners (which would otherwise extend beyond the surface). * * If Rubygame was compiled with SDL_gfx-2.0.13 or greater, +zoom+ can be * an Array of 2 Numerics for separate X and Y scaling. Also, it can be * negative to indicate flipping horizontally or vertically. * * Will raise SDLError if you attempt to use separate X and Y zoom factors * or negative zoom factors with an unsupported version of SDL_gfx. * * This method takes these arguments: * angle:: degrees to rotate counter-clockwise (negative for clockwise). * zoom:: scaling factor(s). A single positive Numeric, unless you have * SDL_gfx-2.0.13 or greater (see above). * smooth:: whether to anti-alias the new surface. * By the way, if true, the new surface will be 32bit RGBA. */ VALUE rbgm_transform_rotozoom(int argc, VALUE *argv, VALUE self) { SDL_Surface *src, *dst; double angle, zoomx, zoomy; int smooth = 0; if(argc < 2) /* smooth is optional, so only 2 required*/ rb_raise(rb_eArgError,"wrong number of arguments (%d for 2)",argc); /* argv[0], the source surface. */ Data_Get_Struct(self,SDL_Surface,src); /* argv[1], the angle of rotation. */ angle = NUM2DBL(argv[0]); /* Parsing of argv[2] is delayed until below, because its type affects which function we call. */ /* argv[3] (optional), rotozoom smoothly? */ if(argc > 2) smooth = argv[2]; /* argv[1], the zoom factor(s) */ if(TYPE(argv[1])==T_ARRAY) /* if we got separate X and Y factors */ { #ifdef HAVE_ROTOZOOMXY /* Do the real function. */ zoomx = NUM2DBL(rb_ary_entry(argv[1],0)); zoomy = NUM2DBL(rb_ary_entry(argv[1],1)); dst = rotozoomSurfaceXY(src, angle, zoomx, zoomy, smooth); if(dst == NULL) rb_raise(eSDLError,"Could not rotozoom surface: %s",SDL_GetError()); #else /* Raise SDLError. You should have checked first! */ rb_raise(eSDLError,"Separate X/Y rotozoom scale factors is not supported by your version of SDL_gfx (%d,%d,%d). Please upgrade to 2.0.13 or later.", SDL_GFXPRIMITIVES_MAJOR, SDL_GFXPRIMITIVES_MINOR, SDL_GFXPRIMITIVES_MICRO); return Qnil; #endif } /* If we got 1 zoom factor for both X and Y */ else if(FIXNUM_P(argv[1]) || TYPE(argv[1])==T_FLOAT) { zoomx = NUM2DBL(argv[1]); #ifndef HAVE_ROTOZOOMXY if(zoomx < 0) /* negative zoom (for flipping) */ { /* Raise SDLError. You should have checked first! */ rb_raise(eSDLError,"Negative rotozoom scale factor is not supported by your version of SDL_gfx (%d,%d,%d). Please upgrade to 2.0.13 or later.", SDL_GFXPRIMITIVES_MAJOR, SDL_GFXPRIMITIVES_MINOR, SDL_GFXPRIMITIVES_MICRO); } #endif dst = rotozoomSurface(src, angle, zoomx, smooth); if(dst == NULL) rb_raise(eSDLError,"Could not rotozoom surface: %s",SDL_GetError()); } else rb_raise(rb_eArgError,"wrong zoom factor type (expected Array or Numeric)"); return Data_Wrap_Struct(cSurface,0,SDL_FreeSurface,dst); }