SDL  2.0
SDL_rotate.h File Reference
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define MIN(a, b)   (((a) < (b)) ? (a) : (b))

Functions

SDL_SurfaceSDLgfx_rotateSurface (SDL_Surface *src, double angle, int centerx, int centery, int smooth, int flipx, int flipy, int dstwidth, int dstheight, double cangle, double sangle)
void SDLgfx_rotozoomSurfaceSizeTrig (int width, int height, double angle, int *dstwidth, int *dstheight, double *cangle, double *sangle)

Macro Definition Documentation

#define MIN (   a,
  b 
)    (((a) < (b)) ? (a) : (b))

Definition at line 26 of file SDL_rotate.h.

Referenced by SW_RenderCopyEx().

Function Documentation

SDL_Surface* SDLgfx_rotateSurface ( SDL_Surface src,
double  angle,
int  centerx,
int  centery,
int  smooth,
int  flipx,
int  flipy,
int  dstwidth,
int  dstheight,
double  cangle,
double  sangle 
)

Definition at line 415 of file SDL_rotate.c.

References _transformSurfaceRGBA(), SDL_PixelFormat::Amask, SDL_PixelFormat::BitsPerPixel, SDL_PixelFormat::Bmask, SDL_Palette::colors, SDL_Surface::format, SDL_PixelFormat::Gmask, GUARD_ROWS, SDL_Surface::h, i, SDL_Palette::ncolors, NULL, SDL_PixelFormat::palette, SDL_PixelFormat::Rmask, SDL_BLENDMODE_BLEND, SDL_BLENDMODE_MOD, SDL_BLENDMODE_NONE, SDL_CreateRGBSurface, SDL_FALSE, SDL_FillRect, SDL_GetColorKey, SDL_GetSurfaceBlendMode, SDL_HasColorKey, SDL_LockSurface, SDL_MapRGBA, SDL_MUSTLOCK, SDL_SetColorKey, SDL_SetSurfaceBlendMode, SDL_TRUE, SDL_UnlockSurface, transformSurfaceRGBA90(), transformSurfaceY(), and transformSurfaceY90().

Referenced by SW_RenderCopyEx().

{
SDL_Surface *rz_dst;
int is8bit, angle90;
int i;
SDL_BlendMode blendmode;
Uint32 colorkey = 0;
int colorKeyAvailable = SDL_FALSE;
double sangleinv, cangleinv;
/* Sanity check */
if (src == NULL)
return NULL;
if (SDL_HasColorKey(src)) {
if (SDL_GetColorKey(src, &colorkey) == 0) {
colorKeyAvailable = SDL_TRUE;
}
}
/* This function requires a 32-bit surface or 8-bit surface with a colorkey */
is8bit = src->format->BitsPerPixel == 8 && colorKeyAvailable;
if (!(is8bit || (src->format->BitsPerPixel == 32 && src->format->Amask)))
return NULL;
/* Calculate target factors from sin/cos and zoom */
sangleinv = sangle*65536.0;
cangleinv = cangle*65536.0;
/* Alloc space to completely contain the rotated surface */
rz_dst = NULL;
if (is8bit) {
/* Target surface is 8 bit */
rz_dst = SDL_CreateRGBSurface(0, dstwidth, dstheight + GUARD_ROWS, 8, 0, 0, 0, 0);
if (rz_dst != NULL) {
for (i = 0; i < src->format->palette->ncolors; i++) {
rz_dst->format->palette->colors[i] = src->format->palette->colors[i];
}
}
} else {
/* Target surface is 32 bit with source RGBA ordering */
rz_dst = SDL_CreateRGBSurface(0, dstwidth, dstheight + GUARD_ROWS, 32,
src->format->Rmask, src->format->Gmask,
src->format->Bmask, src->format->Amask);
}
/* Check target */
if (rz_dst == NULL)
return NULL;
/* Adjust for guard rows */
rz_dst->h = dstheight;
SDL_GetSurfaceBlendMode(src, &blendmode);
if (colorKeyAvailable == SDL_TRUE) {
/* If available, the colorkey will be used to discard the pixels that are outside of the rotated area. */
SDL_SetColorKey(rz_dst, SDL_TRUE, colorkey);
SDL_FillRect(rz_dst, NULL, colorkey);
} else if (blendmode == SDL_BLENDMODE_NONE) {
blendmode = SDL_BLENDMODE_BLEND;
} else if (blendmode == SDL_BLENDMODE_MOD) {
/* Without a colorkey, the target texture has to be white for the MOD blend mode so
* that the pixels outside the rotated area don't affect the destination surface.
*/
colorkey = SDL_MapRGBA(rz_dst->format, 255, 255, 255, 0);
SDL_FillRect(rz_dst, NULL, colorkey);
/* Setting a white colorkey for the destination surface makes the final blit discard
* all pixels outside of the rotated area. This doesn't interfere with anything because
* white pixels are already a no-op and the MOD blend mode does not interact with alpha.
*/
SDL_SetColorKey(rz_dst, SDL_TRUE, colorkey);
}
SDL_SetSurfaceBlendMode(rz_dst, blendmode);
/* Lock source surface */
if (SDL_MUSTLOCK(src)) {
}
/* check if the rotation is a multiple of 90 degrees so we can take a fast path and also somewhat reduce
* the off-by-one problem in _transformSurfaceRGBA that expresses itself when the rotation is near
* multiples of 90 degrees.
*/
angle90 = (int)(angle/90);
if (angle90 == angle/90) {
angle90 %= 4;
if (angle90 < 0) angle90 += 4; /* 0:0 deg, 1:90 deg, 2:180 deg, 3:270 deg */
} else {
angle90 = -1;
}
if (is8bit) {
/* Call the 8-bit transformation routine to do the rotation */
if(angle90 >= 0) {
transformSurfaceY90(src, rz_dst, angle90, flipx, flipy);
} else {
transformSurfaceY(src, rz_dst, centerx, centery, (int)sangleinv, (int)cangleinv,
flipx, flipy);
}
} else {
/* Call the 32-bit transformation routine to do the rotation */
if (angle90 >= 0) {
transformSurfaceRGBA90(src, rz_dst, angle90, flipx, flipy);
} else {
_transformSurfaceRGBA(src, rz_dst, centerx, centery, (int)sangleinv, (int)cangleinv,
flipx, flipy, smooth);
}
}
/* Unlock source surface */
if (SDL_MUSTLOCK(src)) {
}
/* Return rotated surface */
return rz_dst;
}
void SDLgfx_rotozoomSurfaceSizeTrig ( int  width,
int  height,
double  angle,
int *  dstwidth,
int *  dstheight,
double *  cangle,
double *  sangle 
)

Definition at line 106 of file SDL_rotate.c.

References MAX, SDL_ceil, SDL_cos, SDL_fabs, and SDL_sin.

Referenced by SW_RenderCopyEx().

{
/* The trig code below gets the wrong size (due to FP inaccuracy?) when angle is a multiple of 90 degrees */
int angle90 = (int)(angle/90);
if(angle90 == angle/90) { /* if the angle is a multiple of 90 degrees */
angle90 %= 4;
if(angle90 < 0) angle90 += 4; /* 0:0 deg, 1:90 deg, 2:180 deg, 3:270 deg */
if(angle90 & 1) {
*dstwidth = height;
*dstheight = width;
*cangle = 0;
*sangle = angle90 == 1 ? -1 : 1; /* reversed because our rotations are clockwise */
} else {
*dstwidth = width;
*dstheight = height;
*cangle = angle90 == 0 ? 1 : -1;
*sangle = 0;
}
} else {
double x, y, cx, cy, sx, sy;
double radangle;
int dstwidthhalf, dstheighthalf;
/*
* Determine destination width and height by rotating a centered source box
*/
radangle = angle * (M_PI / -180.0); /* reverse the angle because our rotations are clockwise */
*sangle = SDL_sin(radangle);
*cangle = SDL_cos(radangle);
x = (double)(width / 2);
y = (double)(height / 2);
cx = *cangle * x;
cy = *cangle * y;
sx = *sangle * x;
sy = *sangle * y;
dstwidthhalf = MAX((int)
SDL_ceil(MAX(MAX(MAX(SDL_fabs(cx + sy), SDL_fabs(cx - sy)), SDL_fabs(-cx + sy)), SDL_fabs(-cx - sy))), 1);
dstheighthalf = MAX((int)
SDL_ceil(MAX(MAX(MAX(SDL_fabs(sx + cy), SDL_fabs(sx - cy)), SDL_fabs(-sx + cy)), SDL_fabs(-sx - cy))), 1);
*dstwidth = 2 * dstwidthhalf;
*dstheight = 2 * dstheighthalf;
}
}