From 17989940f2866ca8ded34ce291e1f53fe517f0fb Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Fri, 10 Oct 2025 08:36:41 -0700
Subject: [PATCH] Fixed SDL_BlitSurfaceTiledWithScale() with very small scale
(thanks @bleeqer!)
---
src/video/SDL_surface.c | 10 +++++++---
test/testautomation_surface.c | 7 +++++++
2 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/src/video/SDL_surface.c b/src/video/SDL_surface.c
index 82a24c60ebadd..7c455a9b424f9 100644
--- a/src/video/SDL_surface.c
+++ b/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)) {
return SDL_SetError("Surfaces must not be locked during blit");
}
- CHECK_PARAM(scale <= 0.0f) {
+ CHECK_PARAM(scale < 0.0f) {
return SDL_InvalidParamError("scale");
}
@@ -1521,8 +1521,12 @@ bool SDL_BlitSurfaceTiledWithScale(SDL_Surface *src, const SDL_Rect *srcrect, fl
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 cols = r_dst.w / tile_width;
int remaining_dst_w = (r_dst.w - cols * tile_width);
diff --git a/test/testautomation_surface.c b/test/testautomation_surface.c
index 13b979a12e585..e1713dbd4af32 100644
--- a/test/testautomation_surface.c
+++ b/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);
}
+ /* 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. */
SDL_DestroySurface(face);
SDL_DestroySurface(testSurface2x);