From 17989940f2866ca8ded34ce291e1f53fe517f0fb Mon Sep 17 00:00:00 2001 From: Sam Lantinga 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 82a24c60eb..7c455a9b42 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 13b979a12e..e1713dbd4a 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);