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

◆ MIN

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

Definition at line 27 of file SDL_rotate.h.

Function Documentation

◆ SDLgfx_rotateSurface()

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 417 of file SDL_rotate.c.

418 {
419  SDL_Surface *rz_dst;
420  int is8bit, angle90;
421  int i;
422  SDL_BlendMode blendmode;
423  Uint32 colorkey = 0;
424  int colorKeyAvailable = SDL_FALSE;
425  double sangleinv, cangleinv;
426 
427  /* Sanity check */
428  if (src == NULL)
429  return NULL;
430 
431  if (SDL_HasColorKey(src)) {
432  if (SDL_GetColorKey(src, &colorkey) == 0) {
433  colorKeyAvailable = SDL_TRUE;
434  }
435  }
436 
437  /* This function requires a 32-bit surface or 8-bit surface with a colorkey */
438  is8bit = src->format->BitsPerPixel == 8 && colorKeyAvailable;
439  if (!(is8bit || (src->format->BitsPerPixel == 32 && src->format->Amask)))
440  return NULL;
441 
442  /* Calculate target factors from sin/cos and zoom */
443  sangleinv = sangle*65536.0;
444  cangleinv = cangle*65536.0;
445 
446  /* Alloc space to completely contain the rotated surface */
447  rz_dst = NULL;
448  if (is8bit) {
449  /* Target surface is 8 bit */
450  rz_dst = SDL_CreateRGBSurface(0, dstwidth, dstheight + GUARD_ROWS, 8, 0, 0, 0, 0);
451  if (rz_dst != NULL) {
452  for (i = 0; i < src->format->palette->ncolors; i++) {
453  rz_dst->format->palette->colors[i] = src->format->palette->colors[i];
454  }
455  rz_dst->format->palette->ncolors = src->format->palette->ncolors;
456  }
457  } else {
458  /* Target surface is 32 bit with source RGBA ordering */
459  rz_dst = SDL_CreateRGBSurface(0, dstwidth, dstheight + GUARD_ROWS, 32,
460  src->format->Rmask, src->format->Gmask,
461  src->format->Bmask, src->format->Amask);
462  }
463 
464  /* Check target */
465  if (rz_dst == NULL)
466  return NULL;
467 
468  /* Adjust for guard rows */
469  rz_dst->h = dstheight;
470 
471  SDL_GetSurfaceBlendMode(src, &blendmode);
472 
473  if (colorKeyAvailable == SDL_TRUE) {
474  /* If available, the colorkey will be used to discard the pixels that are outside of the rotated area. */
475  SDL_SetColorKey(rz_dst, SDL_TRUE, colorkey);
476  SDL_FillRect(rz_dst, NULL, colorkey);
477  } else if (blendmode == SDL_BLENDMODE_NONE) {
478  blendmode = SDL_BLENDMODE_BLEND;
479  } else if (blendmode == SDL_BLENDMODE_MOD || blendmode == SDL_BLENDMODE_MUL) {
480  /* Without a colorkey, the target texture has to be white for the MOD and MUL blend mode so
481  * that the pixels outside the rotated area don't affect the destination surface.
482  */
483  colorkey = SDL_MapRGBA(rz_dst->format, 255, 255, 255, 0);
484  SDL_FillRect(rz_dst, NULL, colorkey);
485  /* Setting a white colorkey for the destination surface makes the final blit discard
486  * all pixels outside of the rotated area. This doesn't interfere with anything because
487  * white pixels are already a no-op and the MOD blend mode does not interact with alpha.
488  */
489  SDL_SetColorKey(rz_dst, SDL_TRUE, colorkey);
490  }
491 
492  SDL_SetSurfaceBlendMode(rz_dst, blendmode);
493 
494  /* Lock source surface */
495  if (SDL_MUSTLOCK(src)) {
497  }
498 
499  /* check if the rotation is a multiple of 90 degrees so we can take a fast path and also somewhat reduce
500  * the off-by-one problem in _transformSurfaceRGBA that expresses itself when the rotation is near
501  * multiples of 90 degrees.
502  */
503  angle90 = (int)(angle/90);
504  if (angle90 == angle/90) {
505  angle90 %= 4;
506  if (angle90 < 0) angle90 += 4; /* 0:0 deg, 1:90 deg, 2:180 deg, 3:270 deg */
507  } else {
508  angle90 = -1;
509  }
510 
511  if (is8bit) {
512  /* Call the 8-bit transformation routine to do the rotation */
513  if(angle90 >= 0) {
514  transformSurfaceY90(src, rz_dst, angle90, flipx, flipy);
515  } else {
516  transformSurfaceY(src, rz_dst, centerx, centery, (int)sangleinv, (int)cangleinv,
517  flipx, flipy);
518  }
519  } else {
520  /* Call the 32-bit transformation routine to do the rotation */
521  if (angle90 >= 0) {
522  transformSurfaceRGBA90(src, rz_dst, angle90, flipx, flipy);
523  } else {
524  _transformSurfaceRGBA(src, rz_dst, centerx, centery, (int)sangleinv, (int)cangleinv,
525  flipx, flipy, smooth);
526  }
527  }
528 
529  /* Unlock source surface */
530  if (SDL_MUSTLOCK(src)) {
532  }
533 
534  /* Return rotated surface */
535  return rz_dst;
536 }

References _transformSurfaceRGBA(), SDL_Palette::colors, SDL_Surface::format, GUARD_ROWS, SDL_Surface::h, i, SDL_Palette::ncolors, NULL, SDL_PixelFormat::palette, SDL_BLENDMODE_BLEND, SDL_BLENDMODE_MOD, SDL_BLENDMODE_MUL, 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().

◆ SDLgfx_rotozoomSurfaceSizeTrig()

void SDLgfx_rotozoomSurfaceSizeTrig ( int  width,
int  height,
double  angle,
int *  dstwidth,
int *  dstheight,
double *  cangle,
double *  sangle 
)

Definition at line 108 of file SDL_rotate.c.

111 {
112  /* The trig code below gets the wrong size (due to FP inaccuracy?) when angle is a multiple of 90 degrees */
113  int angle90 = (int)(angle/90);
114  if(angle90 == angle/90) { /* if the angle is a multiple of 90 degrees */
115  angle90 %= 4;
116  if(angle90 < 0) angle90 += 4; /* 0:0 deg, 1:90 deg, 2:180 deg, 3:270 deg */
117  if(angle90 & 1) {
118  *dstwidth = height;
119  *dstheight = width;
120  *cangle = 0;
121  *sangle = angle90 == 1 ? -1 : 1; /* reversed because our rotations are clockwise */
122  } else {
123  *dstwidth = width;
124  *dstheight = height;
125  *cangle = angle90 == 0 ? 1 : -1;
126  *sangle = 0;
127  }
128  } else {
129  double x, y, cx, cy, sx, sy;
130  double radangle;
131  int dstwidthhalf, dstheighthalf;
132  /*
133  * Determine destination width and height by rotating a centered source box
134  */
135  radangle = angle * (M_PI / -180.0); /* reverse the angle because our rotations are clockwise */
136  *sangle = SDL_sin(radangle);
137  *cangle = SDL_cos(radangle);
138  x = (double)(width / 2);
139  y = (double)(height / 2);
140  cx = *cangle * x;
141  cy = *cangle * y;
142  sx = *sangle * x;
143  sy = *sangle * y;
144 
145  dstwidthhalf = MAX((int)
146  SDL_ceil(MAX(MAX(MAX(SDL_fabs(cx + sy), SDL_fabs(cx - sy)), SDL_fabs(-cx + sy)), SDL_fabs(-cx - sy))), 1);
147  dstheighthalf = MAX((int)
148  SDL_ceil(MAX(MAX(MAX(SDL_fabs(sx + cy), SDL_fabs(sx - cy)), SDL_fabs(-sx + cy)), SDL_fabs(-sx - cy))), 1);
149  *dstwidth = 2 * dstwidthhalf;
150  *dstheight = 2 * dstheighthalf;
151  }
152 }

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

Referenced by SW_RenderCopyEx().

SDL_UnlockSurface
#define SDL_UnlockSurface
Definition: SDL_dynapi_overrides.h:449
SDL_Palette::ncolors
int ncolors
Definition: SDL_pixels.h:309
SDL_MapRGBA
#define SDL_MapRGBA
Definition: SDL_dynapi_overrides.h:287
SDL_Surface
A collection of pixels used in software blitting.
Definition: SDL_surface.h:71
SDL_fabs
#define SDL_fabs
Definition: SDL_dynapi_overrides.h:430
SDL_ceil
#define SDL_ceil
Definition: SDL_dynapi_overrides.h:426
NULL
#define NULL
Definition: begin_code.h:167
width
GLint GLint GLsizei width
Definition: SDL_opengl.h:1572
SDL_BLENDMODE_BLEND
@ SDL_BLENDMODE_BLEND
Definition: SDL_blendmode.h:44
MAX
#define MAX(a, b)
Definition: SDL_rotate.c:67
transformSurfaceRGBA90
static void transformSurfaceRGBA90(SDL_Surface *src, SDL_Surface *dst, int angle, int flipx, int flipy)
Definition: SDL_rotate.c:199
SDL_MUSTLOCK
#define SDL_MUSTLOCK(S)
Definition: SDL_surface.h:62
Uint32
uint32_t Uint32
Definition: SDL_stdinc.h:203
SDL_GetSurfaceBlendMode
#define SDL_GetSurfaceBlendMode
Definition: SDL_dynapi_overrides.h:460
GUARD_ROWS
#define GUARD_ROWS
Definition: SDL_rotate.c:79
SDL_Palette::colors
SDL_Color * colors
Definition: SDL_pixels.h:310
x
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
SDL_BLENDMODE_NONE
@ SDL_BLENDMODE_NONE
Definition: SDL_blendmode.h:42
height
GLint GLint GLsizei GLsizei height
Definition: SDL_opengl.h:1572
SDL_cos
#define SDL_cos
Definition: SDL_dynapi_overrides.h:428
_transformSurfaceRGBA
static void _transformSurfaceRGBA(SDL_Surface *src, SDL_Surface *dst, int cx, int cy, int isin, int icos, int flipx, int flipy, int smooth)
Definition: SDL_rotate.c:232
SDL_PixelFormat::palette
SDL_Palette * palette
Definition: SDL_pixels.h:321
SDL_SetColorKey
#define SDL_SetColorKey
Definition: SDL_dynapi_overrides.h:453
SDL_GetColorKey
#define SDL_GetColorKey
Definition: SDL_dynapi_overrides.h:454
SDL_TRUE
@ SDL_TRUE
Definition: SDL_stdinc.h:164
transformSurfaceY
static void transformSurfaceY(SDL_Surface *src, SDL_Surface *dst, int cx, int cy, int isin, int icos, int flipx, int flipy)
Definition: SDL_rotate.c:346
SDL_BLENDMODE_MUL
@ SDL_BLENDMODE_MUL
Definition: SDL_blendmode.h:53
y
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
SDL_LockSurface
#define SDL_LockSurface
Definition: SDL_dynapi_overrides.h:448
SDL_CreateRGBSurface
#define SDL_CreateRGBSurface
Definition: SDL_dynapi_overrides.h:444
SDL_Surface::h
int h
Definition: SDL_surface.h:74
transformSurfaceY90
static void transformSurfaceY90(SDL_Surface *src, SDL_Surface *dst, int angle, int flipx, int flipy)
Definition: SDL_rotate.c:205
src
GLenum src
Definition: SDL_opengl_glext.h:1740
SDL_SetSurfaceBlendMode
#define SDL_SetSurfaceBlendMode
Definition: SDL_dynapi_overrides.h:459
angle
GLfloat angle
Definition: SDL_opengl_glext.h:6100
SDL_FillRect
#define SDL_FillRect
Definition: SDL_dynapi_overrides.h:466
SDL_FALSE
@ SDL_FALSE
Definition: SDL_stdinc.h:163
SDL_sin
#define SDL_sin
Definition: SDL_dynapi_overrides.h:435
SDL_Surface::format
SDL_PixelFormat * format
Definition: SDL_surface.h:73
SDL_BLENDMODE_MOD
@ SDL_BLENDMODE_MOD
Definition: SDL_blendmode.h:50
i
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
SDL_HasColorKey
#define SDL_HasColorKey
Definition: SDL_dynapi_overrides.h:699
SDL_BlendMode
SDL_BlendMode
The blend mode used in SDL_RenderCopy() and drawing operations.
Definition: SDL_blendmode.h:41