# HG changeset patch # User Sam Lantinga # Date 1229998998 0 # Node ID 3da0bb421d83d36210f73771e47186db3aee4307 # Parent aa6ba38c17142901cbffbf5bb4013255835da08a Added line clipping diff -r aa6ba38c1714 -r 3da0bb421d83 include/SDL_rect.h --- a/include/SDL_rect.h Tue Dec 23 01:28:06 2008 +0000 +++ b/include/SDL_rect.h Tue Dec 23 02:23:18 2008 +0000 @@ -104,6 +104,18 @@ const SDL_Rect * B, SDL_Rect * result); +/** + * \fn SDL_bool SDL_IntersectRectAndLine(const SDL_Rect *rect, int *X1, int *Y1, int *X2, int *Y2) + * + * \brief Calculate the intersection of a rectangle and line segment. + * + * \return SDL_TRUE if there is an intersection, SDL_FALSE otherwise. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IntersectRectAndLine(const SDL_Rect * + rect, int *X1, + int *Y1, int *X2, + int *Y2); + /* Ends C function definitions when using C++ */ #ifdef __cplusplus /* *INDENT-OFF* */ diff -r aa6ba38c1714 -r 3da0bb421d83 src/video/SDL_blendline.c --- a/src/video/SDL_blendline.c Tue Dec 23 01:28:06 2008 +0000 +++ b/src/video/SDL_blendline.c Tue Dec 23 02:23:18 2008 +0000 @@ -204,11 +204,10 @@ } /* Perform clipping */ - /* FIXME - if (!SDL_IntersectRect(dstrect, &dst->clip_rect, dstrect)) { - return (0); - } - */ + if (!SDL_IntersectRectAndLine(&dst->clip_rect, &x1, &x2, &y1, &y2)) { + return (0); + } + if ((blendMode == SDL_BLENDMODE_BLEND) || (blendMode == SDL_BLENDMODE_ADD)) { diff -r aa6ba38c1714 -r 3da0bb421d83 src/video/SDL_drawline.c --- a/src/video/SDL_drawline.c Tue Dec 23 01:28:06 2008 +0000 +++ b/src/video/SDL_drawline.c Tue Dec 23 02:23:18 2008 +0000 @@ -34,11 +34,9 @@ } /* Perform clipping */ - /* FIXME - if (!SDL_IntersectRect(dstrect, &dst->clip_rect, dstrect)) { - return (0); - } - */ + if (!SDL_IntersectRectAndLine(&dst->clip_rect, &x1, &x2, &y1, &y2)) { + return (0); + } switch (dst->format->BytesPerPixel) { case 1: diff -r aa6ba38c1714 -r 3da0bb421d83 src/video/SDL_rect.c --- a/src/video/SDL_rect.c Tue Dec 23 01:28:06 2008 +0000 +++ b/src/video/SDL_rect.c Tue Dec 23 02:23:18 2008 +0000 @@ -118,6 +118,75 @@ result->h = Amax - Amin; } +SDL_bool +SDL_IntersectRectAndLine(const SDL_Rect *rect, int *X1, int *Y1, int *X2, int *Y2) +{ + int x1, y1; + int x2, y2; + int rectx1; + int recty1; + int rectx2; + int recty2; + + if (!rect || !X1 || !Y1 || !X2 || !Y2) { + SDL_FALSE; + } + + x1 = *X1; + y1 = *Y1; + x2 = *X2; + y2 = *Y2; + rectx1 = rect->x; + recty1 = rect->y; + rectx2 = rect->x + rect->w - 1; + recty2 = rect->y + rect->h - 1; + + /* Check to see if entire line is inside rect */ + if (x1 >= rectx1 && x1 <= rectx2 && x2 >= rectx1 && x2 <= rectx2 && + y1 >= recty1 && y1 <= recty2 && y2 >= recty1 && y2 <= recty2) { + return SDL_TRUE; + } + + /* Check to see if entire line is outside rect */ + if ((x1 < rectx1 && x2 < rectx1) || (x1 > rectx2 && x2 > rectx2) || + (y1 < recty1 && y2 < recty2) || (y1 > recty2 && y2 > recty2)) { + return SDL_FALSE; + } + + if (y1 = y2) { + /* Horizontal line, easy to clip */ + if (x1 < rectx1) { + *X1 = rectx1; + } else if (x1 > rectx2) { + *X1 = rectx2; + } + if (x2 < rectx1) { + *X2 = rectx1; + } else if (x2 > rectx2) { + *X2 = rectx2; + } + return SDL_TRUE; + } + + if (x1 == x2) { + /* Vertical line, easy to clip */ + if (y1 < recty1) { + *Y1 = recty1; + } else if (y1 > recty2) { + *Y1 = recty2; + } + if (y2 < recty1) { + *Y2 = recty1; + } else if (y2 > recty2) { + *Y2 = recty2; + } + return SDL_TRUE; + } + + /* FIXME: need code to clip diagonal line to rect */ + return SDL_FALSE; +} + void SDL_AddDirtyRect(SDL_DirtyRectList * list, const SDL_Rect * rect) { diff -r aa6ba38c1714 -r 3da0bb421d83 src/video/SDL_video.c --- a/src/video/SDL_video.c Tue Dec 23 01:28:06 2008 +0000 +++ b/src/video/SDL_video.c Tue Dec 23 02:23:18 2008 +0000 @@ -2119,19 +2119,15 @@ SDL_Unsupported(); return -1; } -#if 0 - //FIXME: Need line intersect routine window = SDL_GetWindowFromID(renderer->window); + real_rect.x = 0; real_rect.y = 0; real_rect.w = window->w; real_rect.h = window->h; - if (rect) { - if (!SDL_IntersectRect(rect, &real_rect, &real_rect)) { - return 0; - } + if (!SDL_IntersectRectAndLine(&real_rect, &x1, &x2, &y1, &y2)) { + return (0); } -#endif return renderer->RenderLine(renderer, x1, y1, x2, y2); }