Added SDL_ScaleSurface()

This commit is contained in:
Sam Lantinga 2024-08-01 10:18:29 -07:00
parent 15f68a86ff
commit 22ffb487d0
5 changed files with 104 additions and 1 deletions

View file

@ -691,6 +691,24 @@ extern SDL_DECLSPEC int SDLCALL SDL_FlipSurface(SDL_Surface *surface, SDL_FlipMo
*/
extern SDL_DECLSPEC SDL_Surface * SDLCALL SDL_DuplicateSurface(SDL_Surface *surface);
/**
* Creates a new surface identical to the existing surface, scaled to the desired size.
*
* The returned surface should be freed with SDL_DestroySurface().
*
* \param surface the surface to duplicate and scale.
* \param width the width of the new surface.
* \param height the height of the new surface.
* \param scaleMode the SDL_ScaleMode to be used.
* \returns a copy of the surface or NULL on failure; call SDL_GetError() for
* more information.
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_DestroySurface
*/
extern SDL_DECLSPEC SDL_Surface * SDLCALL SDL_ScaleSurface(SDL_Surface *surface, int width, int height, SDL_ScaleMode scaleMode);
/**
* Copy an existing surface to a new surface of the specified format.
*
@ -1031,7 +1049,7 @@ extern SDL_DECLSPEC int SDLCALL SDL_BlitSurfaceScaled(SDL_Surface *src, const SD
* \param dst the SDL_Surface structure that is the blit target.
* \param dstrect the SDL_Rect structure representing the target rectangle in
* the destination surface, may not be NULL.
* \param scaleMode scale algorithm to be used.
* \param scaleMode the SDL_ScaleMode to be used.
* \returns 0 on success or a negative error code on failure; call
* SDL_GetError() for more information.
*

View file

@ -687,6 +687,7 @@ SDL3_0.0.0 {
SDL_RunHapticEffect;
SDL_SaveBMP;
SDL_SaveBMP_IO;
SDL_ScaleSurface;
SDL_ScreenKeyboardShown;
SDL_ScreenSaverEnabled;
SDL_SeekIO;

View file

@ -712,6 +712,7 @@
#define SDL_RunHapticEffect SDL_RunHapticEffect_REAL
#define SDL_SaveBMP SDL_SaveBMP_REAL
#define SDL_SaveBMP_IO SDL_SaveBMP_IO_REAL
#define SDL_ScaleSurface SDL_ScaleSurface_REAL
#define SDL_ScreenKeyboardShown SDL_ScreenKeyboardShown_REAL
#define SDL_ScreenSaverEnabled SDL_ScreenSaverEnabled_REAL
#define SDL_SeekIO SDL_SeekIO_REAL

View file

@ -723,6 +723,7 @@ SDL_DYNAPI_PROC(int,SDL_RunApp,(int a, char *b[], SDL_main_func c, void *d),(a,b
SDL_DYNAPI_PROC(int,SDL_RunHapticEffect,(SDL_Haptic *a, int b, Uint32 c),(a,b,c),return)
SDL_DYNAPI_PROC(int,SDL_SaveBMP,(SDL_Surface *a, const char *b),(a,b),return)
SDL_DYNAPI_PROC(int,SDL_SaveBMP_IO,(SDL_Surface *a, SDL_IOStream *b, SDL_bool c),(a,b,c),return)
SDL_DYNAPI_PROC(SDL_Surface*,SDL_ScaleSurface,(SDL_Surface *a, int b, int c, SDL_ScaleMode d),(a,b,c,d),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_ScreenKeyboardShown,(SDL_Window *a),(a),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_ScreenSaverEnabled,(void),(),return)
SDL_DYNAPI_PROC(Sint64,SDL_SeekIO,(SDL_IOStream *a, Sint64 b, SDL_IOWhence c),(a,b,c),return)

View file

@ -1968,6 +1968,88 @@ SDL_Surface *SDL_DuplicateSurface(SDL_Surface *surface)
return SDL_ConvertSurfaceAndColorspace(surface, surface->format, surface->internal->palette, surface->internal->colorspace, surface->internal->props);
}
SDL_Surface *SDL_ScaleSurface(SDL_Surface *surface, int width, int height, SDL_ScaleMode scaleMode)
{
SDL_Surface *convert = NULL;
Uint32 copy_flags;
SDL_Color copy_color;
int ret;
if (!SDL_SurfaceValid(surface)) {
SDL_InvalidParamError("surface");
goto error;
}
if (SDL_ISPIXELFORMAT_FOURCC(surface->format)) {
// We can't directly scale a YUV surface (yet!)
SDL_Surface *tmp = SDL_CreateSurface(surface->w, surface->h, SDL_PIXELFORMAT_ARGB8888);
if (!tmp) {
return NULL;
}
SDL_Surface *scaled = SDL_ScaleSurface(tmp, width, height, scaleMode);
SDL_DestroySurface(tmp);
if (!scaled) {
return NULL;
}
tmp = scaled;
SDL_Surface *result = SDL_ConvertSurfaceAndColorspace(tmp, surface->format, NULL, surface->internal->colorspace, surface->internal->props);
SDL_DestroySurface(tmp);
return result;
}
/* Create a new surface with the desired size */
convert = SDL_CreateSurface(width, height, surface->format);
if (!convert) {
goto error;
}
SDL_SetSurfacePalette(convert, surface->internal->palette);
SDL_SetSurfaceColorspace(convert, surface->internal->colorspace);
/* Save the original copy flags */
copy_flags = surface->internal->map.info.flags;
copy_color.r = surface->internal->map.info.r;
copy_color.g = surface->internal->map.info.g;
copy_color.b = surface->internal->map.info.b;
copy_color.a = surface->internal->map.info.a;
surface->internal->map.info.r = 0xFF;
surface->internal->map.info.g = 0xFF;
surface->internal->map.info.b = 0xFF;
surface->internal->map.info.a = 0xFF;
surface->internal->map.info.flags = (copy_flags & (SDL_COPY_RLE_COLORKEY | SDL_COPY_RLE_ALPHAKEY));
SDL_InvalidateMap(&surface->internal->map);
ret = SDL_BlitSurfaceScaled(surface, NULL, convert, NULL, scaleMode);
/* Clean up the original surface, and update converted surface */
convert->internal->map.info.r = copy_color.r;
convert->internal->map.info.g = copy_color.g;
convert->internal->map.info.b = copy_color.b;
convert->internal->map.info.a = copy_color.a;
convert->internal->map.info.flags = (copy_flags & ~(SDL_COPY_RLE_COLORKEY | SDL_COPY_RLE_ALPHAKEY));
surface->internal->map.info.r = copy_color.r;
surface->internal->map.info.g = copy_color.g;
surface->internal->map.info.b = copy_color.b;
surface->internal->map.info.a = copy_color.a;
surface->internal->map.info.flags = copy_flags;
SDL_InvalidateMap(&surface->internal->map);
/* SDL_BlitSurfaceScaled failed, and so the conversion */
if (ret < 0) {
goto error;
}
/* We're ready to go! */
return convert;
error:
if (convert) {
SDL_DestroySurface(convert);
}
return NULL;
}
SDL_Surface *SDL_ConvertSurface(SDL_Surface *surface, SDL_PixelFormat format)
{
if (!SDL_SurfaceValid(surface)) {