/*
* 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;
VALUE vangle, vzoom, vsmooth;
rb_scan_args(argc, argv, "21", &vangle, &vzoom, &vsmooth);
Data_Get_Struct(self,SDL_Surface,src);
angle = NUM2DBL(vangle);
smooth = RTEST(vsmooth) ? 1 : 0;
switch( TYPE(vzoom) )
{
case T_ARRAY: {
/* separate X and Y factors */
#ifdef HAVE_ROTOZOOMXY
/* Do the real function. */
zoomx = NUM2DBL(rb_ary_entry(vzoom,0));
zoomy = NUM2DBL(rb_ary_entry(vzoom,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
break;
}
case T_FLOAT:
case T_FIXNUM: {
/* uniform factor for both X and Y */
zoomx = NUM2DBL(vzoom);
#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());
break;
}
default: {
rb_raise(rb_eArgError,
"wrong zoom factor type (expected Array or Numeric)");
break;
}
}
return Data_Wrap_Struct(cSurface,0,SDL_FreeSurface,dst);
}