Fixed bug #189
authorSam Lantinga <slouken@libsdl.org>
Mon, 17 Apr 2006 05:38:33 +0000
changeset 1642 f1211a4b7380
parent 1641 5cf11b00b900
child 1643 51038e80ae59
Fixed bug #189 Clip the overlay destination rectangle to the screen area on X11
src/video/x11/SDL_x11yuv.c
test/testoverlay2.c
--- a/src/video/x11/SDL_x11yuv.c	Mon Apr 17 04:54:08 2006 +0000
+++ b/src/video/x11/SDL_x11yuv.c	Mon Apr 17 05:38:33 2006 +0000
@@ -357,20 +357,59 @@
 int X11_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *dstrect)
 {
 	struct private_yuvhwdata *hwdata;
+	int srcx, srcy, srcw, srch;
+	int dstx, dsty, dstw, dsth;
 
 	hwdata = overlay->hwdata;
+
+	/* Clip the rectangle to the screen area */
+	srcx = 0;
+	srcy = 0;
+	srcw = overlay->w;
+	srch = overlay->h;
+	dstx = dstrect->x;
+	dsty = dstrect->y;
+	dstw = dstrect->w;
+	dsth = dstrect->h;
+	if ( dstx < 0 ) {
+		srcw += (dstx * overlay->w) / dstrect->w;
+		dstw += dstx;
+		srcx -= (dstx * overlay->w) / dstrect->w;
+		dstx = 0;
+	}
+	if ( (dstx+dstw) > this->screen->w ) {
+		int extra = (dstx+dstw - this->screen->w);
+		srcw -= (extra * overlay->w) / dstrect->w;
+		dstw -= extra;
+	}
+	if ( dsty < 0 ) {
+		srch += (dsty * overlay->h) / dstrect->h;
+		dsth += dsty;
+		srcy -= (dsty * overlay->h) / dstrect->h;
+		dsty = 0;
+	}
+	if ( (dsty+dsth) > this->screen->h ) {
+		int extra = (dsty+dsth - this->screen->h);
+		srch -= (extra * overlay->h) / dstrect->h;
+		dsth -= extra;
+	}
+	if ( srcw <= 0 || srch <= 0 ||
+	     srch <= 0 || dsth <= 0 ) {
+		return;
+	}
+
 #ifndef NO_SHARED_MEMORY
 	if ( hwdata->yuv_use_mitshm ) {
 		SDL_NAME(XvShmPutImage)(GFX_Display, hwdata->port, SDL_Window, SDL_GC,
-	              hwdata->image, 0, 0, overlay->w, overlay->h,
-	              dstrect->x, dstrect->y, dstrect->w, dstrect->h, False);
+	              hwdata->image,
+		      srcx, srcy, srcw, srch, dstx, dsty, dstw, dsth, False);
 	}
 	else
 #endif
 	{
 		SDL_NAME(XvPutImage)(GFX_Display, hwdata->port, SDL_Window, SDL_GC,
-				     hwdata->image, 0, 0, overlay->w, overlay->h,
-				     dstrect->x, dstrect->y, dstrect->w, dstrect->h);
+				     hwdata->image,
+		                     srcx, srcy, srcw, srch, dstx, dsty, dstw, dsth);
 	}
 	XSync(GFX_Display, False);
 	return(0);
--- a/test/testoverlay2.c	Mon Apr 17 04:54:08 2006 +0000
+++ b/test/testoverlay2.c	Mon Apr 17 05:38:33 2006 +0000
@@ -526,6 +526,10 @@
                          resized=1;
                      }
                      break;
+                case SDL_MOUSEBUTTONDOWN:
+                     overlayrect.x = event.button.x - overlayrect.w/2;
+                     overlayrect.y = event.button.y - overlayrect.h/2;
+                     break;
                 case SDL_KEYDOWN:
                      if (event.key.keysym.sym == SDLK_SPACE)
                      {