From ea308dc521305636f3c5cc31f4ec244f993d2a69 Mon Sep 17 00:00:00 2001 From: Ken Rogoway Date: Mon, 14 Feb 2011 11:50:18 -0600 Subject: [PATCH] Software scaling support. Not very fast, but it seems to work. --- include/SDL_surface.h | 11 +++++++ src/render/software/SDL_render_sw.c | 7 ++++- src/video/SDL_surface.c | 45 +++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 1 deletion(-) diff --git a/include/SDL_surface.h b/include/SDL_surface.h index dbff402f5..7ab8a665c 100644 --- a/include/SDL_surface.h +++ b/include/SDL_surface.h @@ -464,6 +464,17 @@ extern DECLSPEC int SDLCALL SDL_SoftStretch(SDL_Surface * src, SDL_Surface * dst, const SDL_Rect * dstrect); +/** + * \brief Perform a fast, low quality, stretch blit between two surfaces of the + * different pixel formats. + * + * \note This function calls SDL_SoftStretch or SDL_LowerBlit. + */ +extern DECLSPEC int SDLCALL SDL_BlitScaled + (SDL_Surface * src, const SDL_Rect * srcrect, + SDL_Surface * dst, const SDL_Rect * dstrect); + + /* Ends C function definitions when using C++ */ #ifdef __cplusplus /* *INDENT-OFF* */ diff --git a/src/render/software/SDL_render_sw.c b/src/render/software/SDL_render_sw.c index df75ac35b..082814c44 100644 --- a/src/render/software/SDL_render_sw.c +++ b/src/render/software/SDL_render_sw.c @@ -364,7 +364,12 @@ SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, if (!surface) { return -1; } - return SDL_BlitSurface(src, srcrect, surface, &final_rect); + + if ( srcrect->w == final_rect.w && srcrect->h == final_rect.h ) { + return SDL_BlitSurface(src, srcrect, surface, &final_rect); + } else { + return SDL_BlitScaled(src, srcrect, surface, &final_rect); + } } static int diff --git a/src/video/SDL_surface.c b/src/video/SDL_surface.c index 73cca3b60..48d2ee7b7 100644 --- a/src/video/SDL_surface.c +++ b/src/video/SDL_surface.c @@ -639,6 +639,51 @@ SDL_UpperBlit(SDL_Surface * src, const SDL_Rect * srcrect, return 0; } +/* + * Scale and blit a surface +*/ +int +SDL_BlitScaled(SDL_Surface * src, const SDL_Rect * srcrect, + SDL_Surface * dst, const SDL_Rect * dstrect) +{ + /* Save off the original dst width, height */ + int dstW = dstrect->w; + int dstH = dstrect->h; + SDL_Rect final_dst = *dstrect; + SDL_Rect final_src = *srcrect; + + /* Clip the dst surface to the dstrect */ + SDL_SetClipRect( dst, &final_dst ); + + /* If the dest was clipped to a zero sized rect then exit */ + if ( dst->clip_rect.w <= 0 || dst->clip_rect.h <= 0 ) { + return -1; + } + + /* Did the dst width change? */ + if ( dstW != dst->clip_rect.w ) { + /* scale the src width appropriately */ + final_src.w = final_src.w * dst->clip_rect.w / dstW; + } + + /* Did the dst height change? */ + if ( dstH != dst->clip_rect.h ) { + /* scale the src width appropriately */ + final_src.h = final_src.h * dst->clip_rect.h / dstH; + } + + /* Clip the src surface to the srcrect */ + SDL_SetClipRect( src, &final_src ); + + src->map->info.flags |= SDL_COPY_NEAREST; + + if ( src->format->format == dst->format->format && !SDL_ISPIXELFORMAT_INDEXED(src->format->format) ) { + return SDL_SoftStretch( src, &final_src, dst, &final_dst ); + } else { + return SDL_LowerBlit( src, &final_src, dst, &final_dst ); + } +} + /* * Lock a surface to directly access the pixels */