SDL  2.0
SDL_surface.c File Reference
#include "../SDL_internal.h"
#include "SDL_video.h"
#include "SDL_sysvideo.h"
#include "SDL_blit.h"
#include "SDL_RLEaccel_c.h"
#include "SDL_pixels_c.h"
#include "SDL_yuv_c.h"
+ Include dependency graph for SDL_surface.c:

Go to the source code of this file.

Functions

 SDL_COMPILE_TIME_ASSERT (surface_size_assumptions, sizeof(int)==sizeof(Sint32)&&sizeof(size_t) >=sizeof(Sint32))
static int SDL_CalculatePitch (Uint32 format, int width)
SDL_SurfaceSDL_CreateRGBSurfaceWithFormat (Uint32 flags, int width, int height, int depth, Uint32 format)
SDL_SurfaceSDL_CreateRGBSurface (Uint32 flags, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
SDL_SurfaceSDL_CreateRGBSurfaceFrom (void *pixels, int width, int height, int depth, int pitch, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
SDL_SurfaceSDL_CreateRGBSurfaceWithFormatFrom (void *pixels, int width, int height, int depth, int pitch, Uint32 format)
int SDL_SetSurfacePalette (SDL_Surface *surface, SDL_Palette *palette)
 Set the palette used by a surface.
int SDL_SetSurfaceRLE (SDL_Surface *surface, int flag)
 Sets the RLE acceleration hint for a surface.
int SDL_SetColorKey (SDL_Surface *surface, int flag, Uint32 key)
 Sets the color key (transparent pixel) in a blittable surface.
SDL_bool SDL_HasColorKey (SDL_Surface *surface)
 Returns whether the surface has a color key.
int SDL_GetColorKey (SDL_Surface *surface, Uint32 *key)
 Gets the color key (transparent pixel) in a blittable surface.
static void SDL_ConvertColorkeyToAlpha (SDL_Surface *surface)
int SDL_SetSurfaceColorMod (SDL_Surface *surface, Uint8 r, Uint8 g, Uint8 b)
 Set an additional color value used in blit operations.
int SDL_GetSurfaceColorMod (SDL_Surface *surface, Uint8 *r, Uint8 *g, Uint8 *b)
 Get the additional color value used in blit operations.
int SDL_SetSurfaceAlphaMod (SDL_Surface *surface, Uint8 alpha)
 Set an additional alpha value used in blit operations.
int SDL_GetSurfaceAlphaMod (SDL_Surface *surface, Uint8 *alpha)
 Get the additional alpha value used in blit operations.
int SDL_SetSurfaceBlendMode (SDL_Surface *surface, SDL_BlendMode blendMode)
 Set the blend mode used for blit operations.
int SDL_GetSurfaceBlendMode (SDL_Surface *surface, SDL_BlendMode *blendMode)
 Get the blend mode used for blit operations.
SDL_bool SDL_SetClipRect (SDL_Surface *surface, const SDL_Rect *rect)
void SDL_GetClipRect (SDL_Surface *surface, SDL_Rect *rect)
int SDL_LowerBlit (SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect)
int SDL_UpperBlit (SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect)
int SDL_UpperBlitScaled (SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect)
int SDL_LowerBlitScaled (SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect)
int SDL_LockSurface (SDL_Surface *surface)
 Sets up a surface for directly accessing the pixels.
void SDL_UnlockSurface (SDL_Surface *surface)
SDL_SurfaceSDL_DuplicateSurface (SDL_Surface *surface)
SDL_SurfaceSDL_ConvertSurface (SDL_Surface *surface, const SDL_PixelFormat *format, Uint32 flags)
SDL_SurfaceSDL_ConvertSurfaceFormat (SDL_Surface *surface, Uint32 pixel_format, Uint32 flags)
static SDL_INLINE SDL_bool SDL_CreateSurfaceOnStack (int width, int height, Uint32 pixel_format, void *pixels, int pitch, SDL_Surface *surface, SDL_PixelFormat *format, SDL_BlitMap *blitmap)
int SDL_ConvertPixels (int width, int height, Uint32 src_format, const void *src, int src_pitch, Uint32 dst_format, void *dst, int dst_pitch)
 Copy a block of pixels of one format to another format.
void SDL_FreeSurface (SDL_Surface *surface)

Function Documentation

static int SDL_CalculatePitch ( Uint32  format,
int  width 
)
static

Definition at line 41 of file SDL_surface.c.

References SDL_BITSPERPIXEL, and SDL_BYTESPERPIXEL.

Referenced by SDL_CreateRGBSurfaceWithFormat().

{
int pitch;
/* Surface should be 4-byte aligned for speed */
case 1:
pitch = (pitch + 7) / 8;
break;
case 4:
pitch = (pitch + 1) / 2;
break;
default:
break;
}
pitch = (pitch + 3) & ~3; /* 4-byte aligning */
return pitch;
}
SDL_COMPILE_TIME_ASSERT ( surface_size_assumptions  ,
sizeof(int)  = =sizeof(Sint32)&&sizeof(size_t) >=sizeof(Sint32) 
)
static void SDL_ConvertColorkeyToAlpha ( SDL_Surface surface)
static

Definition at line 328 of file SDL_surface.c.

References SDL_PixelFormat::Amask, SDL_PixelFormat::BytesPerPixel, SDL_BlitInfo::colorkey, SDL_BlitInfo::flags, SDL_Surface::format, SDL_Surface::h, SDL_BlitMap::info, SDL_Surface::map, SDL_Surface::pitch, SDL_Surface::pixels, SDL_BLENDMODE_BLEND, SDL_COPY_COLORKEY, SDL_LockSurface, SDL_SetColorKey, SDL_SetSurfaceBlendMode, SDL_UnlockSurface, and SDL_Surface::w.

Referenced by SDL_ConvertSurface().

{
int x, y;
if (!surface) {
return;
}
if (!(surface->map->info.flags & SDL_COPY_COLORKEY) ||
!surface->format->Amask) {
return;
}
SDL_LockSurface(surface);
switch (surface->format->BytesPerPixel) {
case 2:
{
Uint16 *row, *spot;
Uint16 ckey = (Uint16) surface->map->info.colorkey;
Uint16 mask = (Uint16) (~surface->format->Amask);
/* Ignore alpha in colorkey comparison */
ckey &= mask;
row = (Uint16 *) surface->pixels;
for (y = surface->h; y--;) {
spot = row;
for (x = surface->w; x--;) {
if ((*spot & mask) == ckey) {
*spot &= mask;
}
++spot;
}
row += surface->pitch / 2;
}
}
break;
case 3:
/* FIXME */
break;
case 4:
{
Uint32 *row, *spot;
Uint32 ckey = surface->map->info.colorkey;
Uint32 mask = ~surface->format->Amask;
/* Ignore alpha in colorkey comparison */
ckey &= mask;
row = (Uint32 *) surface->pixels;
for (y = surface->h; y--;) {
spot = row;
for (x = surface->w; x--;) {
if ((*spot & mask) == ckey) {
*spot &= mask;
}
++spot;
}
row += surface->pitch / 4;
}
}
break;
}
SDL_SetColorKey(surface, 0, 0);
}
int SDL_ConvertPixels ( int  width,
int  height,
Uint32  src_format,
const void src,
int  src_pitch,
Uint32  dst_format,
void dst,
int  dst_pitch 
)

Copy a block of pixels of one format to another format.

Returns
0 on success, or -1 if there was an error

Definition at line 1152 of file SDL_surface.c.

References SDL_Rect::h, i, rect, SDL_BYTESPERPIXEL, SDL_ConvertPixels_RGB_to_YUV(), SDL_ConvertPixels_YUV_to_RGB(), SDL_ConvertPixels_YUV_to_YUV(), SDL_CreateSurfaceOnStack(), SDL_InvalidParamError, SDL_ISPIXELFORMAT_FOURCC, SDL_LowerBlit, SDL_memcpy, SDL_Rect::w, SDL_Rect::x, and SDL_Rect::y.

{
SDL_Surface src_surface, dst_surface;
SDL_PixelFormat src_fmt, dst_fmt;
SDL_BlitMap src_blitmap, dst_blitmap;
void *nonconst_src = (void *) src;
/* Check to make sure we are blitting somewhere, so we don't crash */
if (!dst) {
return SDL_InvalidParamError("dst");
}
if (!dst_pitch) {
return SDL_InvalidParamError("dst_pitch");
}
if (SDL_ISPIXELFORMAT_FOURCC(src_format) && SDL_ISPIXELFORMAT_FOURCC(dst_format)) {
return SDL_ConvertPixels_YUV_to_YUV(width, height, src_format, src, src_pitch, dst_format, dst, dst_pitch);
} else if (SDL_ISPIXELFORMAT_FOURCC(src_format)) {
return SDL_ConvertPixels_YUV_to_RGB(width, height, src_format, src, src_pitch, dst_format, dst, dst_pitch);
} else if (SDL_ISPIXELFORMAT_FOURCC(dst_format)) {
return SDL_ConvertPixels_RGB_to_YUV(width, height, src_format, src, src_pitch, dst_format, dst, dst_pitch);
}
/* Fast path for same format copy */
if (src_format == dst_format) {
int i;
const int bpp = SDL_BYTESPERPIXEL(src_format);
width *= bpp;
for (i = height; i--;) {
src = (const Uint8*)src + src_pitch;
dst = (Uint8*)dst + dst_pitch;
}
return 0;
}
if (!SDL_CreateSurfaceOnStack(width, height, src_format, nonconst_src,
src_pitch,
&src_surface, &src_fmt, &src_blitmap)) {
return -1;
}
if (!SDL_CreateSurfaceOnStack(width, height, dst_format, dst, dst_pitch,
&dst_surface, &dst_fmt, &dst_blitmap)) {
return -1;
}
/* Set up the rect and go! */
rect.x = 0;
rect.y = 0;
rect.w = width;
rect.h = height;
return SDL_LowerBlit(&src_surface, &rect, &dst_surface, &rect);
}
SDL_Surface* SDL_ConvertSurface ( SDL_Surface src,
const SDL_PixelFormat fmt,
Uint32  flags 
)

Creates a new surface of the specified format, and then copies and maps the given surface to it so the blit of the converted surface will be as fast as possible. If this function fails, it returns NULL.

The flags parameter is passed to SDL_CreateRGBSurface() and has those semantics. You can also pass SDL_RLEACCEL in the flags parameter and SDL will try to RLE accelerate colorkey and alpha blits in the resulting surface.

Definition at line 939 of file SDL_surface.c.

References SDL_BlitInfo::a, SDL_Color::a, SDL_PixelFormat::Amask, SDL_BlitInfo::b, SDL_Color::b, SDL_PixelFormat::BitsPerPixel, SDL_PixelFormat::Bmask, SDL_PixelFormat::BytesPerPixel, SDL_Surface::clip_rect, SDL_BlitInfo::colorkey, SDL_Palette::colors, SDL_BlitInfo::flags, SDL_Surface::format, SDL_BlitInfo::g, SDL_Color::g, SDL_PixelFormat::Gmask, SDL_Rect::h, SDL_Surface::h, i, SDL_BlitMap::info, SDL_Surface::map, SDL_Palette::ncolors, NULL, SDL_PixelFormat::palette, SDL_Surface::pixels, SDL_BlitInfo::r, SDL_Color::r, SDL_PixelFormat::Rmask, SDL_BLENDMODE_BLEND, SDL_ConvertColorkeyToAlpha(), SDL_ConvertSurface, SDL_COPY_BLEND, SDL_COPY_COLORKEY, SDL_COPY_MODULATE_ALPHA, SDL_COPY_RLE_ALPHAKEY, SDL_COPY_RLE_COLORKEY, SDL_COPY_RLE_DESIRED, SDL_CreateRGBSurface, SDL_FALSE, SDL_FillRect, SDL_FreeSurface, SDL_InvalidateMap(), SDL_InvalidParamError, SDL_LowerBlit, SDL_memcmp, SDL_memcpy, SDL_RLEACCEL, SDL_SetClipRect, SDL_SetColorKey, SDL_SetError, SDL_SetSurfaceBlendMode, SDL_SetSurfacePalette, SDL_SetSurfaceRLE, SDL_TRUE, SDL_Rect::w, SDL_Surface::w, SDL_Rect::x, and SDL_Rect::y.

{
SDL_Surface *convert;
Uint32 copy_flags;
SDL_Color copy_color;
SDL_Rect bounds;
if (!surface) {
return NULL;
}
if (!format) {
return NULL;
}
/* Check for empty destination palette! (results in empty image) */
if (format->palette != NULL) {
int i;
for (i = 0; i < format->palette->ncolors; ++i) {
if ((format->palette->colors[i].r != 0xFF) ||
(format->palette->colors[i].g != 0xFF) ||
(format->palette->colors[i].b != 0xFF))
break;
}
if (i == format->palette->ncolors) {
SDL_SetError("Empty destination palette");
return (NULL);
}
}
/* Create a new surface with the desired format */
convert = SDL_CreateRGBSurface(flags, surface->w, surface->h,
format->BitsPerPixel, format->Rmask,
format->Gmask, format->Bmask,
format->Amask);
if (convert == NULL) {
return (NULL);
}
/* Copy the palette if any */
if (format->palette && convert->format->palette) {
format->palette->colors,
format->palette->ncolors * sizeof(SDL_Color));
convert->format->palette->ncolors = format->palette->ncolors;
}
/* Save the original copy flags */
copy_flags = surface->map->info.flags;
copy_color.r = surface->map->info.r;
copy_color.g = surface->map->info.g;
copy_color.b = surface->map->info.b;
copy_color.a = surface->map->info.a;
surface->map->info.r = 0xFF;
surface->map->info.g = 0xFF;
surface->map->info.b = 0xFF;
surface->map->info.a = 0xFF;
surface->map->info.flags = 0;
/* Copy over the image data */
bounds.x = 0;
bounds.y = 0;
bounds.w = surface->w;
bounds.h = surface->h;
SDL_LowerBlit(surface, &bounds, convert, &bounds);
/* Clean up the original surface, and update converted surface */
convert->map->info.r = copy_color.r;
convert->map->info.g = copy_color.g;
convert->map->info.b = copy_color.b;
convert->map->info.a = copy_color.a;
convert->map->info.flags =
(copy_flags &
surface->map->info.r = copy_color.r;
surface->map->info.g = copy_color.g;
surface->map->info.b = copy_color.b;
surface->map->info.a = copy_color.a;
surface->map->info.flags = copy_flags;
if (copy_flags & SDL_COPY_COLORKEY) {
SDL_bool set_colorkey_by_color = SDL_FALSE;
if (surface->format->palette) {
if (format->palette &&
surface->format->palette->ncolors <= format->palette->ncolors &&
(SDL_memcmp(surface->format->palette->colors, format->palette->colors,
surface->format->palette->ncolors * sizeof(SDL_Color)) == 0)) {
/* The palette is identical, just set the same colorkey */
SDL_SetColorKey(convert, 1, surface->map->info.colorkey);
} else if (format->Amask) {
/* The alpha was set in the destination from the palette */
} else {
set_colorkey_by_color = SDL_TRUE;
}
} else {
set_colorkey_by_color = SDL_TRUE;
}
if (set_colorkey_by_color) {
SDL_Surface *tmp2;
int converted_colorkey = 0;
/* Create a dummy surface to get the colorkey converted */
tmp = SDL_CreateRGBSurface(0, 1, 1,
surface->format->BitsPerPixel, surface->format->Rmask,
surface->format->Gmask, surface->format->Bmask,
surface->format->Amask);
/* Share the palette, if any */
if (surface->format->palette) {
}
SDL_FillRect(tmp, NULL, surface->map->info.colorkey);
tmp->map->info.flags &= ~SDL_COPY_COLORKEY;
/* Convertion of the colorkey */
tmp2 = SDL_ConvertSurface(tmp, format, 0);
/* Get the converted colorkey */
SDL_memcpy(&converted_colorkey, tmp2->pixels, tmp2->format->BytesPerPixel);
/* Set the converted colorkey on the new surface */
SDL_SetColorKey(convert, 1, converted_colorkey);
/* This is needed when converting for 3D texture upload */
}
}
SDL_SetClipRect(convert, &surface->clip_rect);
/* Enable alpha blending by default if the new surface has an
* alpha channel or alpha modulation */
if ((surface->format->Amask && format->Amask) ||
(copy_flags & SDL_COPY_MODULATE_ALPHA)) {
}
if ((copy_flags & SDL_COPY_RLE_DESIRED) || (flags & SDL_RLEACCEL)) {
SDL_SetSurfaceRLE(convert, SDL_RLEACCEL);
}
/* We're ready to go! */
return (convert);
}
SDL_Surface* SDL_ConvertSurfaceFormat ( SDL_Surface surface,
Uint32  pixel_format,
Uint32  flags 
)

Definition at line 1096 of file SDL_surface.c.

References NULL, SDL_AllocFormat, SDL_ConvertSurface, and SDL_FreeFormat.

{
SDL_Surface *convert = NULL;
fmt = SDL_AllocFormat(pixel_format);
if (fmt) {
convert = SDL_ConvertSurface(surface, fmt, flags);
}
return convert;
}
SDL_Surface* SDL_CreateRGBSurface ( Uint32  flags,
int  width,
int  height,
int  depth,
Uint32  Rmask,
Uint32  Gmask,
Uint32  Bmask,
Uint32  Amask 
)

Allocate and free an RGB surface.

If the depth is 4 or 8 bits, an empty palette is allocated for the surface. If the depth is greater than 8 bits, the pixel format is set using the flags '[RGB]mask'.

If the function runs out of memory, it will return NULL.

Parameters
flagsThe flags are obsolete and should be set to 0.
widthThe width in pixels of the surface to create.
heightThe height in pixels of the surface to create.
depthThe depth in bits of the surface to create.
RmaskThe red mask of the surface to create.
GmaskThe green mask of the surface to create.
BmaskThe blue mask of the surface to create.
AmaskThe alpha mask of the surface to create.

Definition at line 153 of file SDL_surface.c.

References NULL, SDL_CreateRGBSurfaceWithFormat, SDL_MasksToPixelFormatEnum, SDL_PIXELFORMAT_UNKNOWN, and SDL_SetError.

{
/* Get the pixel format */
format = SDL_MasksToPixelFormatEnum(depth, Rmask, Gmask, Bmask, Amask);
if (format == SDL_PIXELFORMAT_UNKNOWN) {
SDL_SetError("Unknown pixel format");
return NULL;
}
}
SDL_Surface* SDL_CreateRGBSurfaceFrom ( void pixels,
int  width,
int  height,
int  depth,
int  pitch,
Uint32  Rmask,
Uint32  Gmask,
Uint32  Bmask,
Uint32  Amask 
)

Definition at line 173 of file SDL_surface.c.

References SDL_Surface::flags, SDL_Surface::h, NULL, SDL_Surface::pitch, SDL_Surface::pixels, SDL_CreateRGBSurface, SDL_PREALLOC, SDL_SetClipRect, and SDL_Surface::w.

{
surface = SDL_CreateRGBSurface(0, 0, 0, depth, Rmask, Gmask, Bmask, Amask);
if (surface != NULL) {
surface->flags |= SDL_PREALLOC;
surface->pixels = pixels;
surface->w = width;
surface->h = height;
surface->pitch = pitch;
SDL_SetClipRect(surface, NULL);
}
return surface;
}
SDL_Surface* SDL_CreateRGBSurfaceWithFormat ( Uint32  flags,
int  width,
int  height,
int  depth,
Uint32  format 
)

Definition at line 66 of file SDL_surface.c.

References SDL_PixelFormat::Amask, SDL_Color::b, SDL_PixelFormat::BitsPerPixel, SDL_Palette::colors, SDL_Surface::format, SDL_PixelFormat::format, SDL_Color::g, SDL_Surface::h, SDL_Surface::map, SDL_Palette::ncolors, NULL, SDL_Surface::pitch, SDL_Surface::pixels, SDL_Color::r, SDL_Surface::refcount, SDL_AllocBlitMap(), SDL_AllocFormat, SDL_AllocPalette, SDL_BLENDMODE_BLEND, SDL_CalculatePitch(), SDL_calloc, SDL_FreePalette, SDL_FreeSurface, SDL_ISPIXELFORMAT_INDEXED, SDL_malloc, SDL_MAX_SINT32, SDL_memset, SDL_OutOfMemory, SDL_SetClipRect, SDL_SetSurfaceBlendMode, SDL_SetSurfacePalette, void, and SDL_Surface::w.

{
/* The flags are no longer used, make the compiler happy */
/* Allocate the surface */
surface = (SDL_Surface *) SDL_calloc(1, sizeof(*surface));
if (surface == NULL) {
return NULL;
}
if (!surface->format) {
SDL_FreeSurface(surface);
return NULL;
}
surface->w = width;
surface->h = height;
SDL_SetClipRect(surface, NULL);
SDL_Palette *palette =
if (!palette) {
SDL_FreeSurface(surface);
return NULL;
}
if (palette->ncolors == 2) {
/* Create a black and white bitmap palette */
palette->colors[0].r = 0xFF;
palette->colors[0].g = 0xFF;
palette->colors[0].b = 0xFF;
palette->colors[1].r = 0x00;
palette->colors[1].g = 0x00;
palette->colors[1].b = 0x00;
}
SDL_SetSurfacePalette(surface, palette);
SDL_FreePalette(palette);
}
/* Get the pixels */
if (surface->w && surface->h) {
/* Assumptions checked in surface_size_assumptions assert above */
Sint64 size = ((Sint64)surface->h * surface->pitch);
/* Overflow... */
SDL_FreeSurface(surface);
return NULL;
}
surface->pixels = SDL_malloc((size_t)size);
if (!surface->pixels) {
SDL_FreeSurface(surface);
return NULL;
}
/* This is important for bitmaps */
SDL_memset(surface->pixels, 0, surface->h * surface->pitch);
}
/* Allocate an empty mapping */
surface->map = SDL_AllocBlitMap();
if (!surface->map) {
SDL_FreeSurface(surface);
return NULL;
}
/* By default surface with an alpha mask are set up for blending */
if (surface->format->Amask) {
}
/* The surface is ready to go */
surface->refcount = 1;
return surface;
}
SDL_Surface* SDL_CreateRGBSurfaceWithFormatFrom ( void pixels,
int  width,
int  height,
int  depth,
int  pitch,
Uint32  format 
)

Definition at line 197 of file SDL_surface.c.

References SDL_Surface::flags, SDL_Surface::h, NULL, SDL_Surface::pitch, SDL_Surface::pixels, SDL_CreateRGBSurfaceWithFormat, SDL_PREALLOC, SDL_SetClipRect, and SDL_Surface::w.

{
if (surface != NULL) {
surface->flags |= SDL_PREALLOC;
surface->pixels = pixels;
surface->w = width;
surface->h = height;
surface->pitch = pitch;
SDL_SetClipRect(surface, NULL);
}
return surface;
}
static SDL_INLINE SDL_bool SDL_CreateSurfaceOnStack ( int  width,
int  height,
Uint32  pixel_format,
void pixels,
int  pitch,
SDL_Surface surface,
SDL_PixelFormat format,
SDL_BlitMap blitmap 
)
static

Definition at line 1114 of file SDL_surface.c.

References SDL_BlitInfo::a, SDL_BlitInfo::b, SDL_Surface::flags, SDL_Surface::format, SDL_BlitInfo::g, SDL_Surface::h, SDL_BlitMap::info, SDL_Surface::map, SDL_Surface::pitch, SDL_Surface::pixels, SDL_BlitInfo::r, SDL_Surface::refcount, SDL_FALSE, SDL_InitFormat(), SDL_ISPIXELFORMAT_INDEXED, SDL_PREALLOC, SDL_SetError, SDL_TRUE, SDL_zerop, and SDL_Surface::w.

Referenced by SDL_ConvertPixels().

{
if (SDL_ISPIXELFORMAT_INDEXED(pixel_format)) {
SDL_SetError("Indexed pixel formats not supported");
return SDL_FALSE;
}
if (SDL_InitFormat(format, pixel_format) < 0) {
return SDL_FALSE;
}
SDL_zerop(surface);
surface->flags = SDL_PREALLOC;
surface->format = format;
surface->pixels = pixels;
surface->w = width;
surface->h = height;
surface->pitch = pitch;
/* We don't actually need to set up the clip rect for our purposes */
/* SDL_SetClipRect(surface, NULL); */
/* Allocate an empty mapping */
SDL_zerop(blitmap);
blitmap->info.r = 0xFF;
blitmap->info.g = 0xFF;
blitmap->info.b = 0xFF;
blitmap->info.a = 0xFF;
surface->map = blitmap;
/* The surface is ready to go */
surface->refcount = 1;
return SDL_TRUE;
}
SDL_Surface* SDL_DuplicateSurface ( SDL_Surface surface)

Definition at line 930 of file SDL_surface.c.

References SDL_Surface::flags, SDL_Surface::format, and SDL_ConvertSurface.

{
return SDL_ConvertSurface(surface, surface->format, surface->flags);
}
void SDL_FreeSurface ( SDL_Surface surface)

Definition at line 1213 of file SDL_surface.c.

References SDL_Surface::flags, SDL_Surface::format, SDL_Surface::locked, SDL_Surface::map, NULL, SDL_Surface::pixels, SDL_Surface::refcount, SDL_DONTFREE, SDL_free, SDL_FreeBlitMap(), SDL_FreeFormat, SDL_InvalidateMap(), SDL_PREALLOC, SDL_RLEACCEL, SDL_SetSurfacePalette, SDL_UnlockSurface, and SDL_UnRLESurface().

{
if (surface == NULL) {
return;
}
if (surface->flags & SDL_DONTFREE) {
return;
}
if (--surface->refcount > 0) {
return;
}
while (surface->locked > 0) {
}
if (surface->flags & SDL_RLEACCEL) {
SDL_UnRLESurface(surface, 0);
}
if (surface->format) {
surface->format = NULL;
}
if (!(surface->flags & SDL_PREALLOC)) {
SDL_free(surface->pixels);
}
if (surface->map) {
SDL_FreeBlitMap(surface->map);
}
SDL_free(surface);
}
void SDL_GetClipRect ( SDL_Surface surface,
SDL_Rect rect 
)

Gets the clipping rectangle for the destination surface in a blit.

rect must be a pointer to a valid rectangle which will be filled with the correct values.

Definition at line 569 of file SDL_surface.c.

References SDL_Surface::clip_rect.

{
if (surface && rect) {
*rect = surface->clip_rect;
}
}
int SDL_GetColorKey ( SDL_Surface surface,
Uint32 key 
)

Gets the color key (transparent pixel) in a blittable surface.

Parameters
surfaceThe surface to update
keyA pointer filled in with the transparent pixel in the native surface format
Returns
0 on success, or -1 if the surface is not valid or colorkey is not enabled.

Definition at line 310 of file SDL_surface.c.

References SDL_BlitInfo::colorkey, SDL_BlitInfo::flags, SDL_BlitMap::info, SDL_Surface::map, SDL_COPY_COLORKEY, SDL_InvalidParamError, and SDL_SetError.

{
if (!surface) {
return SDL_InvalidParamError("surface");
}
if (!(surface->map->info.flags & SDL_COPY_COLORKEY)) {
return SDL_SetError("Surface doesn't have a colorkey");
}
if (key) {
*key = surface->map->info.colorkey;
}
return 0;
}
int SDL_GetSurfaceAlphaMod ( SDL_Surface surface,
Uint8 alpha 
)

Get the additional alpha value used in blit operations.

Parameters
surfaceThe surface to query.
alphaA pointer filled in with the current alpha value.
Returns
0 on success, or -1 if the surface is not valid.
See Also
SDL_SetSurfaceAlphaMod()

Definition at line 466 of file SDL_surface.c.

References SDL_BlitInfo::a, SDL_BlitMap::info, and SDL_Surface::map.

{
if (!surface) {
return -1;
}
if (alpha) {
*alpha = surface->map->info.a;
}
return 0;
}
int SDL_GetSurfaceBlendMode ( SDL_Surface surface,
SDL_BlendMode blendMode 
)

Get the blend mode used for blit operations.

Parameters
surfaceThe surface to query.
blendModeA pointer filled in with the current blend mode.
Returns
0 on success, or -1 if the surface is not valid.
See Also
SDL_SetSurfaceBlendMode()

Definition at line 516 of file SDL_surface.c.

References SDL_Surface::map, SDL_BLENDMODE_ADD, SDL_BLENDMODE_BLEND, SDL_BLENDMODE_MOD, SDL_BLENDMODE_NONE, SDL_COPY_ADD, SDL_COPY_BLEND, and SDL_COPY_MOD.

{
if (!surface) {
return -1;
}
if (!blendMode) {
return 0;
}
switch (surface->map->
break;
break;
break;
default:
break;
}
return 0;
}
int SDL_GetSurfaceColorMod ( SDL_Surface surface,
Uint8 r,
Uint8 g,
Uint8 b 
)

Get the additional color value used in blit operations.

Parameters
surfaceThe surface to query.
rA pointer filled in with the current red color value.
gA pointer filled in with the current green color value.
bA pointer filled in with the current blue color value.
Returns
0 on success, or -1 if the surface is not valid.
See Also
SDL_SetSurfaceColorMod()

Definition at line 424 of file SDL_surface.c.

References SDL_BlitInfo::b, SDL_BlitInfo::g, SDL_BlitMap::info, SDL_Surface::map, and SDL_BlitInfo::r.

{
if (!surface) {
return -1;
}
if (r) {
*r = surface->map->info.r;
}
if (g) {
*g = surface->map->info.g;
}
if (b) {
*b = surface->map->info.b;
}
return 0;
}
SDL_bool SDL_HasColorKey ( SDL_Surface surface)

Returns whether the surface has a color key.

Returns
SDL_TRUE if the surface has a color key, or SDL_FALSE if the surface is NULL or has no color key

Definition at line 296 of file SDL_surface.c.

References SDL_BlitInfo::flags, SDL_BlitMap::info, SDL_Surface::map, SDL_COPY_COLORKEY, SDL_FALSE, and SDL_TRUE.

{
if (!surface) {
return SDL_FALSE;
}
if (!(surface->map->info.flags & SDL_COPY_COLORKEY)) {
return SDL_FALSE;
}
return SDL_TRUE;
}
int SDL_LockSurface ( SDL_Surface surface)

Sets up a surface for directly accessing the pixels.

Between calls to SDL_LockSurface() / SDL_UnlockSurface(), you can write to and read from surface->pixels, using the pixel format stored in surface->format. Once you are done accessing the surface, you should use SDL_UnlockSurface() to release it.

Not all surfaces require locking. If SDL_MUSTLOCK(surface) evaluates to 0, then you can read and write to the surface at any time, and the pixel format of the surface will not change.

No operating system or library calls should be made between lock/unlock pairs, as critical system locks may be held during this time.

SDL_LockSurface() returns 0, or -1 if the surface couldn't be locked.

See Also
SDL_UnlockSurface()

Definition at line 891 of file SDL_surface.c.

References SDL_Surface::flags, SDL_Surface::locked, SDL_RLEACCEL, and SDL_UnRLESurface().

{
if (!surface->locked) {
/* Perform the lock */
if (surface->flags & SDL_RLEACCEL) {
SDL_UnRLESurface(surface, 1);
surface->flags |= SDL_RLEACCEL; /* save accel'd state */
}
}
/* Increment the surface lock count, for recursive locks */
++surface->locked;
/* Ready to go.. */
return (0);
}
int SDL_LowerBlit ( SDL_Surface src,
SDL_Rect srcrect,
SDL_Surface dst,
SDL_Rect dstrect 
)

This is a semi-private blit function and it performs low-level surface blitting only.

Definition at line 588 of file SDL_surface.c.

References SDL_BlitMap::blit, SDL_BlitMap::dst, SDL_BlitMap::dst_palette_version, SDL_Surface::format, SDL_Surface::map, SDL_PixelFormat::palette, SDL_MapSurface(), SDL_BlitMap::src_palette_version, and SDL_Palette::version.

{
/* Check to make sure the blit mapping is valid */
if ((src->map->dst != dst) ||
(dst->format->palette &&
(src->format->palette &&
if (SDL_MapSurface(src, dst) < 0) {
return (-1);
}
/* just here for debugging */
/* printf */
/* ("src = 0x%08X src->flags = %08X src->map->info.flags = %08x\ndst = 0x%08X dst->flags = %08X dst->map->info.flags = %08X\nsrc->map->blit = 0x%08x\n", */
/* src, dst->flags, src->map->info.flags, dst, dst->flags, */
/* dst->map->info.flags, src->map->blit); */
}
return (src->map->blit(src, srcrect, dst, dstrect));
}
int SDL_LowerBlitScaled ( SDL_Surface src,
SDL_Rect srcrect,
SDL_Surface dst,
SDL_Rect dstrect 
)

This is a semi-private blit function and it performs low-level surface scaled blitting only.

Definition at line 864 of file SDL_surface.c.

References SDL_BlitInfo::flags, SDL_Surface::format, SDL_PixelFormat::format, SDL_BlitMap::info, SDL_Surface::map, SDL_COPY_ADD, SDL_COPY_BLEND, SDL_COPY_COLORKEY, SDL_COPY_MOD, SDL_COPY_MODULATE_ALPHA, SDL_COPY_MODULATE_COLOR, SDL_COPY_NEAREST, SDL_InvalidateMap(), SDL_ISPIXELFORMAT_INDEXED, SDL_LowerBlit, and SDL_SoftStretch.

{
static const Uint32 complex_copy_flags = (
);
if (!(src->map->info.flags & SDL_COPY_NEAREST)) {
}
if ( !(src->map->info.flags & complex_copy_flags) &&
src->format->format == dst->format->format &&
return SDL_SoftStretch( src, srcrect, dst, dstrect );
} else {
return SDL_LowerBlit( src, srcrect, dst, dstrect );
}
}
SDL_bool SDL_SetClipRect ( SDL_Surface surface,
const SDL_Rect rect 
)

Sets the clipping rectangle for the destination surface in a blit.

If the clip rectangle is NULL, clipping will be disabled.

If the clip rectangle doesn't intersect the surface, the function will return SDL_FALSE and blits will be completely clipped. Otherwise the function returns SDL_TRUE and blits to the surface will be clipped to the intersection of the surface area and the clipping rectangle.

Note that blits are automatically clipped to the edges of the source and destination surfaces.

Definition at line 545 of file SDL_surface.c.

References SDL_Surface::clip_rect, SDL_Rect::h, SDL_Surface::h, SDL_FALSE, SDL_IntersectRect, SDL_TRUE, SDL_Rect::w, SDL_Surface::w, SDL_Rect::x, and SDL_Rect::y.

{
SDL_Rect full_rect;
/* Don't do anything if there's no surface to act on */
if (!surface) {
return SDL_FALSE;
}
/* Set up the full surface rectangle */
full_rect.x = 0;
full_rect.y = 0;
full_rect.w = surface->w;
full_rect.h = surface->h;
/* Set the clipping rectangle */
if (!rect) {
surface->clip_rect = full_rect;
return SDL_TRUE;
}
return SDL_IntersectRect(rect, &full_rect, &surface->clip_rect);
}
int SDL_SetColorKey ( SDL_Surface surface,
int  flag,
Uint32  key 
)

Sets the color key (transparent pixel) in a blittable surface.

Parameters
surfaceThe surface to update
flagNon-zero to enable colorkey and 0 to disable colorkey
keyThe transparent pixel in the native surface format
Returns
0 on success, or -1 if the surface is not valid

You can pass SDL_RLEACCEL to enable RLE accelerated blits.

Definition at line 251 of file SDL_surface.c.

References SDL_Color::a, SDL_BlitInfo::colorkey, SDL_Palette::colors, SDL_BlitInfo::flags, SDL_Surface::format, SDL_BlitMap::info, SDL_Surface::map, SDL_Palette::ncolors, SDL_PixelFormat::palette, SDL_ALPHA_OPAQUE, SDL_ALPHA_TRANSPARENT, SDL_COPY_COLORKEY, SDL_InvalidateMap(), SDL_InvalidParamError, SDL_RLEACCEL, SDL_SetSurfaceRLE, and SDL_Palette::version.

{
int flags;
if (!surface) {
return SDL_InvalidParamError("surface");
}
if (surface->format->palette && key >= ((Uint32) surface->format->palette->ncolors)) {
return SDL_InvalidParamError("key");
}
if (flag & SDL_RLEACCEL) {
SDL_SetSurfaceRLE(surface, 1);
}
flags = surface->map->info.flags;
if (flag) {
surface->map->info.colorkey = key;
if (surface->format->palette) {
++surface->format->palette->version;
if (!surface->format->palette->version) {
surface->format->palette->version = 1;
}
}
} else {
if (surface->format->palette) {
++surface->format->palette->version;
if (!surface->format->palette->version) {
surface->format->palette->version = 1;
}
}
}
if (surface->map->info.flags != flags) {
}
return 0;
}
int SDL_SetSurfaceAlphaMod ( SDL_Surface surface,
Uint8  alpha 
)

Set an additional alpha value used in blit operations.

Parameters
surfaceThe surface to update.
alphaThe alpha value multiplied into blit operations.
Returns
0 on success, or -1 if the surface is not valid.
See Also
SDL_GetSurfaceAlphaMod()

Definition at line 443 of file SDL_surface.c.

References SDL_BlitInfo::a, SDL_BlitInfo::flags, SDL_BlitMap::info, SDL_Surface::map, SDL_COPY_MODULATE_ALPHA, and SDL_InvalidateMap().

{
int flags;
if (!surface) {
return -1;
}
surface->map->info.a = alpha;
flags = surface->map->info.flags;
if (alpha != 0xFF) {
} else {
}
if (surface->map->info.flags != flags) {
}
return 0;
}
int SDL_SetSurfaceBlendMode ( SDL_Surface surface,
SDL_BlendMode  blendMode 
)

Set the blend mode used for blit operations.

Parameters
surfaceThe surface to update.
blendModeSDL_BlendMode to use for blit blending.
Returns
0 on success, or -1 if the parameters are not valid.
See Also
SDL_GetSurfaceBlendMode()

Definition at line 479 of file SDL_surface.c.

References SDL_BlitInfo::flags, SDL_BlitMap::info, SDL_Surface::map, SDL_BLENDMODE_ADD, SDL_BLENDMODE_BLEND, SDL_BLENDMODE_MOD, SDL_BLENDMODE_NONE, SDL_COPY_ADD, SDL_COPY_BLEND, SDL_COPY_MOD, SDL_InvalidateMap(), and SDL_Unsupported.

{
int flags, status;
if (!surface) {
return -1;
}
status = 0;
flags = surface->map->info.flags;
surface->map->info.flags &=
switch (blendMode) {
break;
surface->map->info.flags |= SDL_COPY_BLEND;
break;
surface->map->info.flags |= SDL_COPY_ADD;
break;
surface->map->info.flags |= SDL_COPY_MOD;
break;
default:
status = SDL_Unsupported();
break;
}
if (surface->map->info.flags != flags) {
}
return status;
}
int SDL_SetSurfaceColorMod ( SDL_Surface surface,
Uint8  r,
Uint8  g,
Uint8  b 
)

Set an additional color value used in blit operations.

Parameters
surfaceThe surface to update.
rThe red color value multiplied into blit operations.
gThe green color value multiplied into blit operations.
bThe blue color value multiplied into blit operations.
Returns
0 on success, or -1 if the surface is not valid.
See Also
SDL_GetSurfaceColorMod()

Definition at line 398 of file SDL_surface.c.

References SDL_BlitInfo::b, SDL_BlitInfo::flags, SDL_BlitInfo::g, SDL_BlitMap::info, SDL_Surface::map, SDL_BlitInfo::r, SDL_COPY_MODULATE_COLOR, and SDL_InvalidateMap().

{
int flags;
if (!surface) {
return -1;
}
surface->map->info.r = r;
surface->map->info.g = g;
surface->map->info.b = b;
flags = surface->map->info.flags;
if (r != 0xFF || g != 0xFF || b != 0xFF) {
} else {
}
if (surface->map->info.flags != flags) {
}
return 0;
}
int SDL_SetSurfacePalette ( SDL_Surface surface,
SDL_Palette palette 
)

Set the palette used by a surface.

Returns
0, or -1 if the surface format doesn't use a palette.
Note
A single palette can be shared with many surfaces.

Definition at line 216 of file SDL_surface.c.

References SDL_Surface::format, SDL_Surface::map, SDL_InvalidateMap(), SDL_SetError, and SDL_SetPixelFormatPalette.

{
if (!surface) {
return SDL_SetError("SDL_SetSurfacePalette() passed a NULL surface");
}
if (SDL_SetPixelFormatPalette(surface->format, palette) < 0) {
return -1;
}
return 0;
}
int SDL_SetSurfaceRLE ( SDL_Surface surface,
int  flag 
)

Sets the RLE acceleration hint for a surface.

Returns
0 on success, or -1 if the surface is not valid
Note
If RLE is enabled, colorkey and alpha blending blits are much faster, but the surface must be locked before directly accessing the pixels.

Definition at line 230 of file SDL_surface.c.

References SDL_BlitInfo::flags, SDL_BlitMap::info, SDL_Surface::map, SDL_COPY_RLE_DESIRED, and SDL_InvalidateMap().

{
int flags;
if (!surface) {
return -1;
}
flags = surface->map->info.flags;
if (flag) {
} else {
}
if (surface->map->info.flags != flags) {
}
return 0;
}
void SDL_UnlockSurface ( SDL_Surface surface)
See Also
SDL_LockSurface()

Definition at line 912 of file SDL_surface.c.

References SDL_Surface::flags, SDL_Surface::locked, SDL_RLEACCEL, and SDL_RLESurface().

{
/* Only perform an unlock if we are locked */
if (!surface->locked || (--surface->locked > 0)) {
return;
}
/* Update RLE encoded surface with new data */
if ((surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL) {
surface->flags &= ~SDL_RLEACCEL; /* stop lying */
SDL_RLESurface(surface);
}
}
int SDL_UpperBlit ( SDL_Surface src,
const SDL_Rect srcrect,
SDL_Surface dst,
SDL_Rect dstrect 
)

This is the public blit function, SDL_BlitSurface(), and it performs rectangle validation and clipping before passing it to SDL_LowerBlit()

Definition at line 611 of file SDL_surface.c.

References SDL_Surface::clip_rect, SDL_BlitInfo::flags, SDL_Rect::h, SDL_Surface::h, SDL_BlitMap::info, SDL_Surface::locked, SDL_Surface::map, NULL, SDL_COPY_NEAREST, SDL_InvalidateMap(), SDL_LowerBlit, SDL_SetError, SDL_Rect::w, SDL_Surface::w, SDL_Rect::x, and SDL_Rect::y.

{
SDL_Rect fulldst;
int srcx, srcy, w, h;
/* Make sure the surfaces aren't locked */
if (!src || !dst) {
return SDL_SetError("SDL_UpperBlit: passed a NULL surface");
}
if (src->locked || dst->locked) {
return SDL_SetError("Surfaces must not be locked during blit");
}
/* If the destination rectangle is NULL, use the entire dest surface */
if (dstrect == NULL) {
fulldst.x = fulldst.y = 0;
fulldst.w = dst->w;
fulldst.h = dst->h;
dstrect = &fulldst;
}
/* clip the source rectangle to the source surface */
if (srcrect) {
int maxw, maxh;
srcx = srcrect->x;
w = srcrect->w;
if (srcx < 0) {
w += srcx;
dstrect->x -= srcx;
srcx = 0;
}
maxw = src->w - srcx;
if (maxw < w)
w = maxw;
srcy = srcrect->y;
h = srcrect->h;
if (srcy < 0) {
h += srcy;
dstrect->y -= srcy;
srcy = 0;
}
maxh = src->h - srcy;
if (maxh < h)
h = maxh;
} else {
srcx = srcy = 0;
w = src->w;
h = src->h;
}
/* clip the destination rectangle against the clip rectangle */
{
SDL_Rect *clip = &dst->clip_rect;
int dx, dy;
dx = clip->x - dstrect->x;
if (dx > 0) {
w -= dx;
dstrect->x += dx;
srcx += dx;
}
dx = dstrect->x + w - clip->x - clip->w;
if (dx > 0)
w -= dx;
dy = clip->y - dstrect->y;
if (dy > 0) {
h -= dy;
dstrect->y += dy;
srcy += dy;
}
dy = dstrect->y + h - clip->y - clip->h;
if (dy > 0)
h -= dy;
}
/* Switch back to a fast blit if we were previously stretching */
if (src->map->info.flags & SDL_COPY_NEAREST) {
}
if (w > 0 && h > 0) {
sr.x = srcx;
sr.y = srcy;
sr.w = dstrect->w = w;
sr.h = dstrect->h = h;
return SDL_LowerBlit(src, &sr, dst, dstrect);
}
dstrect->w = dstrect->h = 0;
return 0;
}
int SDL_UpperBlitScaled ( SDL_Surface src,
const SDL_Rect srcrect,
SDL_Surface dst,
SDL_Rect dstrect 
)

This is the public scaled blit function, SDL_BlitScaled(), and it performs rectangle validation and clipping before passing it to SDL_LowerBlitScaled()

Definition at line 710 of file SDL_surface.c.

References SDL_Surface::clip_rect, SDL_Rect::h, SDL_Surface::h, SDL_Surface::locked, NULL, SDL_BlitSurface, SDL_floor, SDL_LowerBlitScaled, SDL_SetError, SDL_Rect::w, SDL_Surface::w, SDL_Rect::x, and SDL_Rect::y.

{
double src_x0, src_y0, src_x1, src_y1;
double dst_x0, dst_y0, dst_x1, dst_y1;
SDL_Rect final_src, final_dst;
double scaling_w, scaling_h;
int src_w, src_h;
int dst_w, dst_h;
/* Make sure the surfaces aren't locked */
if (!src || !dst) {
return SDL_SetError("SDL_UpperBlitScaled: passed a NULL surface");
}
if (src->locked || dst->locked) {
return SDL_SetError("Surfaces must not be locked during blit");
}
if (NULL == srcrect) {
src_w = src->w;
src_h = src->h;
} else {
src_w = srcrect->w;
src_h = srcrect->h;
}
if (NULL == dstrect) {
dst_w = dst->w;
dst_h = dst->h;
} else {
dst_w = dstrect->w;
dst_h = dstrect->h;
}
if (dst_w == src_w && dst_h == src_h) {
/* No scaling, defer to regular blit */
return SDL_BlitSurface(src, srcrect, dst, dstrect);
}
scaling_w = (double)dst_w / src_w;
scaling_h = (double)dst_h / src_h;
if (NULL == dstrect) {
dst_x0 = 0;
dst_y0 = 0;
dst_x1 = dst_w - 1;
dst_y1 = dst_h - 1;
} else {
dst_x0 = dstrect->x;
dst_y0 = dstrect->y;
dst_x1 = dst_x0 + dst_w - 1;
dst_y1 = dst_y0 + dst_h - 1;
}
if (NULL == srcrect) {
src_x0 = 0;
src_y0 = 0;
src_x1 = src_w - 1;
src_y1 = src_h - 1;
} else {
src_x0 = srcrect->x;
src_y0 = srcrect->y;
src_x1 = src_x0 + src_w - 1;
src_y1 = src_y0 + src_h - 1;
/* Clip source rectangle to the source surface */
if (src_x0 < 0) {
dst_x0 -= src_x0 * scaling_w;
src_x0 = 0;
}
if (src_x1 >= src->w) {
dst_x1 -= (src_x1 - src->w + 1) * scaling_w;
src_x1 = src->w - 1;
}
if (src_y0 < 0) {
dst_y0 -= src_y0 * scaling_h;
src_y0 = 0;
}
if (src_y1 >= src->h) {
dst_y1 -= (src_y1 - src->h + 1) * scaling_h;
src_y1 = src->h - 1;
}
}
/* Clip destination rectangle to the clip rectangle */
/* Translate to clip space for easier calculations */
dst_x0 -= dst->clip_rect.x;
dst_x1 -= dst->clip_rect.x;
dst_y0 -= dst->clip_rect.y;
dst_y1 -= dst->clip_rect.y;
if (dst_x0 < 0) {
src_x0 -= dst_x0 / scaling_w;
dst_x0 = 0;
}
if (dst_x1 >= dst->clip_rect.w) {
src_x1 -= (dst_x1 - dst->clip_rect.w + 1) / scaling_w;
dst_x1 = dst->clip_rect.w - 1;
}
if (dst_y0 < 0) {
src_y0 -= dst_y0 / scaling_h;
dst_y0 = 0;
}
if (dst_y1 >= dst->clip_rect.h) {
src_y1 -= (dst_y1 - dst->clip_rect.h + 1) / scaling_h;
dst_y1 = dst->clip_rect.h - 1;
}
/* Translate back to surface coordinates */
dst_x0 += dst->clip_rect.x;
dst_x1 += dst->clip_rect.x;
dst_y0 += dst->clip_rect.y;
dst_y1 += dst->clip_rect.y;
final_src.x = (int)SDL_floor(src_x0 + 0.5);
final_src.y = (int)SDL_floor(src_y0 + 0.5);
final_src.w = (int)SDL_floor(src_x1 + 1 + 0.5) - (int)SDL_floor(src_x0 + 0.5);
final_src.h = (int)SDL_floor(src_y1 + 1 + 0.5) - (int)SDL_floor(src_y0 + 0.5);
final_dst.x = (int)SDL_floor(dst_x0 + 0.5);
final_dst.y = (int)SDL_floor(dst_y0 + 0.5);
final_dst.w = (int)SDL_floor(dst_x1 - dst_x0 + 1.5);
final_dst.h = (int)SDL_floor(dst_y1 - dst_y0 + 1.5);
if (final_dst.w < 0)
final_dst.w = 0;
if (final_dst.h < 0)
final_dst.h = 0;
if (dstrect)
*dstrect = final_dst;
if (final_dst.w == 0 || final_dst.h == 0 ||
final_src.w <= 0 || final_src.h <= 0) {
/* No-op. */
return 0;
}
return SDL_LowerBlitScaled(src, &final_src, dst, &final_dst);
}