Commit c005267fb19f2fdd224ff91d68664483f22447b1

Sylvain Becker 2021-01-02T09:38:19

SDL_BlitScaled: better and safer fix clipping bug #2687 And re-use SDL_round(), since it's been re-added (remove in https://hg.libsdl.org/SDL/rev/34043108b7e4 )

diff --git a/src/video/SDL_surface.c b/src/video/SDL_surface.c
index 994094c..feb5649 100644
--- a/src/video/SDL_surface.c
+++ b/src/video/SDL_surface.c
@@ -874,23 +874,32 @@ SDL_PrivateUpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect,
     dst_y0 += dst->clip_rect.y;
     dst_y1 += dst->clip_rect.y;
 
-    final_src.x = (int)SDL_floor(src_x0 + 0.5);
-    final_src.y = (int)SDL_floor(src_y0 + 0.5);
-    final_src.w = (int)SDL_floor(src_x1 + 0.5) - (int)SDL_floor(src_x0 + 0.5);
-    final_src.h = (int)SDL_floor(src_y1 + 0.5) - (int)SDL_floor(src_y0 + 0.5);
-
-    final_dst.x = (int)SDL_floor(dst_x0 + 0.5);
-    final_dst.y = (int)SDL_floor(dst_y0 + 0.5);
-    final_dst.w = (int)SDL_floor(dst_x1 - dst_x0 + 0.5);
-    final_dst.h = (int)SDL_floor(dst_y1 - dst_y0 + 0.5);
-
-    if (final_dst.w < 0)
-        final_dst.w = 0;
-    if (final_dst.h < 0)
-        final_dst.h = 0;
-
-    if (dstrect)
+    final_src.x = (int)SDL_round(src_x0);
+    final_src.y = (int)SDL_round(src_y0);
+    final_src.w = (int)SDL_round(src_x1 - src_x0);
+    final_src.h = (int)SDL_round(src_y1 - src_y0);
+
+    final_dst.x = (int)SDL_round(dst_x0);
+    final_dst.y = (int)SDL_round(dst_y0);
+    final_dst.w = (int)SDL_round(dst_x1 - dst_x0);
+    final_dst.h = (int)SDL_round(dst_y1 - dst_y0);
+
+    /* Clip again */
+    {
+        SDL_Rect tmp;
+        tmp.x = 0;
+        tmp.y = 0;
+        tmp.w = src->w;
+        tmp.h = src->h;
+        SDL_IntersectRect(&tmp, &final_src, &final_src);
+    }
+
+    /* Clip again */
+    SDL_IntersectRect(&dst->clip_rect, &final_dst, &final_dst);
+
+    if (dstrect) {
         *dstrect = final_dst;
+    }
 
     if (final_dst.w == 0 || final_dst.h == 0 ||
         final_src.w <= 0 || final_src.h <= 0) {