Added SDL_RotateSurface()

Fixes https://github.com/libsdl-org/SDL/issues/14269
This commit is contained in:
Sam Lantinga
2025-10-22 17:28:34 -07:00
parent a402af506c
commit e18d63a4e2
15 changed files with 286 additions and 33 deletions

View File

@@ -1267,6 +1267,7 @@ SDL3_0.0.0 {
SDL_GetSystemPageSize;
SDL_GetPenDeviceType;
SDL_CreateAnimatedCursor;
SDL_RotateSurface;
# extra symbols go here (don't modify this line)
local: *;
};

View File

@@ -1293,3 +1293,4 @@
#define SDL_GetSystemPageSize SDL_GetSystemPageSize_REAL
#define SDL_GetPenDeviceType SDL_GetPenDeviceType_REAL
#define SDL_CreateAnimatedCursor SDL_CreateAnimatedCursor_REAL
#define SDL_RotateSurface SDL_RotateSurface_REAL

View File

@@ -1301,3 +1301,4 @@ SDL_DYNAPI_PROC(bool,SDL_SavePNG,(SDL_Surface *a,const char *b),(a,b),return)
SDL_DYNAPI_PROC(int,SDL_GetSystemPageSize,(void),(),return)
SDL_DYNAPI_PROC(SDL_PenDeviceType,SDL_GetPenDeviceType,(SDL_PenID a),(a),return)
SDL_DYNAPI_PROC(SDL_Cursor*,SDL_CreateAnimatedCursor,(SDL_CursorFrameInfo *a,int b,int c,int d),(a,b,c,d),return)
SDL_DYNAPI_PROC(SDL_Surface*,SDL_RotateSurface,(SDL_Surface *a,float b),(a,b),return)

View File

@@ -31,9 +31,9 @@
#include "SDL_blendpoint.h"
#include "SDL_drawline.h"
#include "SDL_drawpoint.h"
#include "SDL_rotate.h"
#include "SDL_triangle.h"
#include "../../video/SDL_pixels_c.h"
#include "../../video/SDL_rotate.h"
// SDL surface based renderer implementation
@@ -406,7 +406,7 @@ static bool SW_RenderCopyEx(SDL_Renderer *renderer, SDL_Surface *surface, SDL_Te
SDL_GetSurfaceColorMod(src, &rMod, &gMod, &bMod);
// SDLgfx_rotateSurface only accepts 32-bit surfaces with a 8888 layout. Everything else has to be converted.
if (src->fmt->bits_per_pixel != 32 || SDL_PIXELLAYOUT(src->format) != SDL_PACKEDLAYOUT_8888 || !SDL_ISPIXELFORMAT_ALPHA(src->format)) {
if (!(SDL_BITSPERPIXEL(src->format) == 32 && SDL_PIXELLAYOUT(src->format) == SDL_PACKEDLAYOUT_8888)) {
blitRequired = true;
}

View File

@@ -30,16 +30,9 @@ Andreas Schiffler -- aschiffler at ferzkopp dot net
*/
#include "SDL_internal.h"
#ifdef SDL_VIDEO_RENDER_SW
#if defined(SDL_PLATFORM_WINDOWS)
#include "../../core/windows/SDL_windows.h"
#endif
#include "SDL_surface_c.h"
#include "SDL_rotate.h"
#include "../../video/SDL_surface_c.h"
// ---- Internally used structures
/**
@@ -506,8 +499,9 @@ SDL_Surface *SDLgfx_rotateSurface(SDL_Surface *src, double angle, int smooth, in
}
}
// This function requires a 32-bit surface or 8-bit surface with a colorkey
is8bit = src->fmt->bits_per_pixel == 8 && colorKeyAvailable;
if (!(is8bit || (src->fmt->bits_per_pixel == 32 && SDL_ISPIXELFORMAT_ALPHA(src->format)))) {
is8bit = (src->format == SDL_PIXELFORMAT_INDEX8) && colorKeyAvailable;
if (!is8bit &&
!(SDL_BITSPERPIXEL(src->format) == 32 && SDL_PIXELLAYOUT(src->format) == SDL_PACKEDLAYOUT_8888)) {
return NULL;
}
@@ -609,4 +603,3 @@ SDL_Surface *SDLgfx_rotateSurface(SDL_Surface *src, double angle, int smooth, in
return rz_dst;
}
#endif // SDL_VIDEO_RENDER_SW

View File

@@ -24,6 +24,7 @@
#include "SDL_video_c.h"
#include "SDL_RLEaccel_c.h"
#include "SDL_pixels_c.h"
#include "SDL_rotate.h"
#include "SDL_stb_c.h"
#include "SDL_yuv_c.h"
#include "../render/SDL_sysrender.h"
@@ -2167,6 +2168,38 @@ error:
return NULL;
}
SDL_Surface *SDL_RotateSurface(SDL_Surface *surface, float angle)
{
SDL_Surface *rotated = NULL;
CHECK_PARAM(!SDL_SurfaceValid(surface)) {
SDL_InvalidParamError("surface");
return NULL;
}
SDL_Rect rect_dest;
double cangle, sangle;
SDL_FPoint center = { surface->w * 0.5f, surface->h * 0.5f };
SDLgfx_rotozoomSurfaceSizeTrig(surface->w, surface->h, angle, &center, &rect_dest, &cangle, &sangle);
// This function requires a 32-bit surface or 8-bit surface with a colorkey
if ((SDL_BITSPERPIXEL(surface->format) == 32 && SDL_PIXELLAYOUT(surface->format) == SDL_PACKEDLAYOUT_8888) ||
(surface->format == SDL_PIXELFORMAT_INDEX8 && SDL_SurfaceHasColorKey(surface))) {
rotated = SDLgfx_rotateSurface(surface, angle, 1, 0, 0, &rect_dest, cangle, sangle, &center);
} else {
SDL_Surface *convert = SDL_ConvertSurface(surface, SDL_PIXELFORMAT_RGBA32);
if (convert) {
SDL_Surface *tmp = SDLgfx_rotateSurface(convert, angle, 1, 0, 0, &rect_dest, cangle, sangle, &center);
if (tmp) {
rotated = SDL_ConvertSurfaceAndColorspace(tmp, surface->format, surface->palette, surface->colorspace, surface->props);
SDL_DestroySurface(tmp);
}
SDL_DestroySurface(convert);
}
}
return rotated;
}
SDL_Surface *SDL_DuplicateSurface(SDL_Surface *surface)
{
CHECK_PARAM(!SDL_SurfaceValid(surface)) {