Software scaling support. Not very fast, but it seems to work.
authorKen Rogoway <ken@rogoway.com>
Mon, 14 Feb 2011 11:50:18 -0600
changeset 5296 48067bfc300c
parent 5295 b88d05603e4b
child 5297 1800dc39b74c
Software scaling support. Not very fast, but it seems to work.
include/SDL_surface.h
src/render/software/SDL_render_sw.c
src/video/SDL_surface.c
--- a/include/SDL_surface.h	Mon Feb 14 00:45:16 2011 -0800
+++ b/include/SDL_surface.h	Mon Feb 14 11:50:18 2011 -0600
@@ -464,6 +464,17 @@
                                             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* */
--- a/src/render/software/SDL_render_sw.c	Mon Feb 14 00:45:16 2011 -0800
+++ b/src/render/software/SDL_render_sw.c	Mon Feb 14 11:50:18 2011 -0600
@@ -364,7 +364,12 @@
     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
--- a/src/video/SDL_surface.c	Mon Feb 14 00:45:16 2011 -0800
+++ b/src/video/SDL_surface.c	Mon Feb 14 11:50:18 2011 -0600
@@ -640,6 +640,51 @@
 }
 
 /*
+ * 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
  */
 int