瀏覽代碼

Fixed SDL_BlitSurfaceTiledWithScale() with very small scale (thanks @bleeqer!)

Sam Lantinga 1 天之前
父節點
當前提交
17989940f2
共有 2 個文件被更改,包括 14 次插入3 次删除
  1. 7 3
      src/video/SDL_surface.c
  2. 7 0
      test/testautomation_surface.c

+ 7 - 3
src/video/SDL_surface.c

@@ -1475,7 +1475,7 @@ bool SDL_BlitSurfaceTiledWithScale(SDL_Surface *src, const SDL_Rect *srcrect, fl
     CHECK_PARAM((src->flags & SDL_SURFACE_LOCKED) || (dst->flags & SDL_SURFACE_LOCKED)) {
     CHECK_PARAM((src->flags & SDL_SURFACE_LOCKED) || (dst->flags & SDL_SURFACE_LOCKED)) {
         return SDL_SetError("Surfaces must not be locked during blit");
         return SDL_SetError("Surfaces must not be locked during blit");
     }
     }
-    CHECK_PARAM(scale <= 0.0f) {
+    CHECK_PARAM(scale < 0.0f) {
         return SDL_InvalidParamError("scale");
         return SDL_InvalidParamError("scale");
     }
     }
 
 
@@ -1521,8 +1521,12 @@ bool SDL_BlitSurfaceTiledWithScale(SDL_Surface *src, const SDL_Rect *srcrect, fl
         SDL_InvalidateMap(&src->map);
         SDL_InvalidateMap(&src->map);
     }
     }
 
 
-    int tile_width = (int)(r_src.w * scale);
-    int tile_height = (int)(r_src.h * scale);
+    int tile_width = (int)SDL_roundf(r_src.w * scale);
+    int tile_height = (int)SDL_roundf(r_src.h * scale);
+    if (tile_width <= 0 || tile_height <= 0) {
+        // Nothing to do
+        return true;
+    }
     int rows = r_dst.h / tile_height;
     int rows = r_dst.h / tile_height;
     int cols = r_dst.w / tile_width;
     int cols = r_dst.w / tile_width;
     int remaining_dst_w = (r_dst.w - cols * tile_width);
     int remaining_dst_w = (r_dst.w - cols * tile_width);

+ 7 - 0
test/testautomation_surface.c

@@ -442,6 +442,13 @@ static int SDLCALL surface_testBlitTiled(void *arg)
         SDLTest_AssertCheck(ret == 0, "Validate result from SDLTest_CompareSurfaces, expected: 0, got: %i", ret);
         SDLTest_AssertCheck(ret == 0, "Validate result from SDLTest_CompareSurfaces, expected: 0, got: %i", ret);
     }
     }
 
 
+    /* Tiled blit - very small scale */
+    {
+        float tiny_scale = 0.01f;
+        ret = SDL_BlitSurfaceTiledWithScale(face, NULL, tiny_scale, SDL_SCALEMODE_NEAREST, testSurface, NULL);
+        SDLTest_AssertCheck(ret == true, "Expected SDL_BlitSurfaceTiledWithScale to succeed with very small scale: %f, got: %i", tiny_scale, ret);
+    }
+
     /* Clean up. */
     /* Clean up. */
     SDL_DestroySurface(face);
     SDL_DestroySurface(face);
     SDL_DestroySurface(testSurface2x);
     SDL_DestroySurface(testSurface2x);