Added line clipping
authorSam Lantinga <slouken@libsdl.org>
Tue, 23 Dec 2008 02:23:18 +0000
changeset 29093da0bb421d83
parent 2908 aa6ba38c1714
child 2910 27d8b12e0e8e
Added line clipping
include/SDL_rect.h
src/video/SDL_blendline.c
src/video/SDL_drawline.c
src/video/SDL_rect.c
src/video/SDL_video.c
     1.1 --- a/include/SDL_rect.h	Tue Dec 23 01:28:06 2008 +0000
     1.2 +++ b/include/SDL_rect.h	Tue Dec 23 02:23:18 2008 +0000
     1.3 @@ -104,6 +104,18 @@
     1.4                                             const SDL_Rect * B,
     1.5                                             SDL_Rect * result);
     1.6  
     1.7 +/**
     1.8 + * \fn SDL_bool SDL_IntersectRectAndLine(const SDL_Rect *rect, int *X1, int *Y1, int *X2, int *Y2)
     1.9 + *
    1.10 + * \brief Calculate the intersection of a rectangle and line segment.
    1.11 + *
    1.12 + * \return SDL_TRUE if there is an intersection, SDL_FALSE otherwise.
    1.13 + */
    1.14 +extern DECLSPEC SDL_bool SDLCALL SDL_IntersectRectAndLine(const SDL_Rect *
    1.15 +                                                          rect, int *X1,
    1.16 +                                                          int *Y1, int *X2,
    1.17 +                                                          int *Y2);
    1.18 +
    1.19  /* Ends C function definitions when using C++ */
    1.20  #ifdef __cplusplus
    1.21  /* *INDENT-OFF* */
     2.1 --- a/src/video/SDL_blendline.c	Tue Dec 23 01:28:06 2008 +0000
     2.2 +++ b/src/video/SDL_blendline.c	Tue Dec 23 02:23:18 2008 +0000
     2.3 @@ -204,11 +204,10 @@
     2.4      }
     2.5  
     2.6      /* Perform clipping */
     2.7 -    /* FIXME
     2.8 -       if (!SDL_IntersectRect(dstrect, &dst->clip_rect, dstrect)) {
     2.9 -       return (0);
    2.10 -       }
    2.11 -     */
    2.12 +    if (!SDL_IntersectRectAndLine(&dst->clip_rect, &x1, &x2, &y1, &y2)) {
    2.13 +        return (0);
    2.14 +    }
    2.15 +
    2.16  
    2.17      if ((blendMode == SDL_BLENDMODE_BLEND)
    2.18          || (blendMode == SDL_BLENDMODE_ADD)) {
     3.1 --- a/src/video/SDL_drawline.c	Tue Dec 23 01:28:06 2008 +0000
     3.2 +++ b/src/video/SDL_drawline.c	Tue Dec 23 02:23:18 2008 +0000
     3.3 @@ -34,11 +34,9 @@
     3.4      }
     3.5  
     3.6      /* Perform clipping */
     3.7 -    /* FIXME
     3.8 -       if (!SDL_IntersectRect(dstrect, &dst->clip_rect, dstrect)) {
     3.9 -       return (0);
    3.10 -       }
    3.11 -     */
    3.12 +    if (!SDL_IntersectRectAndLine(&dst->clip_rect, &x1, &x2, &y1, &y2)) {
    3.13 +        return (0);
    3.14 +    }
    3.15  
    3.16      switch (dst->format->BytesPerPixel) {
    3.17      case 1:
     4.1 --- a/src/video/SDL_rect.c	Tue Dec 23 01:28:06 2008 +0000
     4.2 +++ b/src/video/SDL_rect.c	Tue Dec 23 02:23:18 2008 +0000
     4.3 @@ -118,6 +118,75 @@
     4.4      result->h = Amax - Amin;
     4.5  }
     4.6  
     4.7 +SDL_bool
     4.8 +SDL_IntersectRectAndLine(const SDL_Rect *rect, int *X1, int *Y1, int *X2, int *Y2)
     4.9 +{
    4.10 +    int x1, y1;
    4.11 +    int x2, y2;
    4.12 +    int rectx1;
    4.13 +    int recty1;
    4.14 +    int rectx2;
    4.15 +    int recty2;
    4.16 +
    4.17 +    if (!rect || !X1 || !Y1 || !X2 || !Y2) {
    4.18 +        SDL_FALSE;
    4.19 +    }
    4.20 +
    4.21 +    x1 = *X1;
    4.22 +    y1 = *Y1;
    4.23 +    x2 = *X2;
    4.24 +    y2 = *Y2;
    4.25 +    rectx1 = rect->x;
    4.26 +    recty1 = rect->y;
    4.27 +    rectx2 = rect->x + rect->w - 1;
    4.28 +    recty2 = rect->y + rect->h - 1;
    4.29 +
    4.30 +    /* Check to see if entire line is inside rect */
    4.31 +    if (x1 >= rectx1 && x1 <= rectx2 && x2 >= rectx1 && x2 <= rectx2 &&
    4.32 +        y1 >= recty1 && y1 <= recty2 && y2 >= recty1 && y2 <= recty2) {
    4.33 +        return SDL_TRUE;
    4.34 +    }
    4.35 +
    4.36 +    /* Check to see if entire line is outside rect */
    4.37 +    if ((x1 < rectx1 && x2 < rectx1) || (x1 > rectx2 && x2 > rectx2) ||
    4.38 +        (y1 < recty1 && y2 < recty2) || (y1 > recty2 && y2 > recty2)) {
    4.39 +        return SDL_FALSE;
    4.40 +    }
    4.41 +
    4.42 +    if (y1 = y2) {
    4.43 +        /* Horizontal line, easy to clip */
    4.44 +        if (x1 < rectx1) {
    4.45 +            *X1 = rectx1;
    4.46 +        } else if (x1 > rectx2) {
    4.47 +            *X1 = rectx2;
    4.48 +        }
    4.49 +        if (x2 < rectx1) {
    4.50 +            *X2 = rectx1;
    4.51 +        } else if (x2 > rectx2) {
    4.52 +            *X2 = rectx2;
    4.53 +        }
    4.54 +        return SDL_TRUE;
    4.55 +    }
    4.56 +
    4.57 +    if (x1 == x2) {
    4.58 +        /* Vertical line, easy to clip */
    4.59 +        if (y1 < recty1) {
    4.60 +            *Y1 = recty1;
    4.61 +        } else if (y1 > recty2) {
    4.62 +            *Y1 = recty2;
    4.63 +        }
    4.64 +        if (y2 < recty1) {
    4.65 +            *Y2 = recty1;
    4.66 +        } else if (y2 > recty2) {
    4.67 +            *Y2 = recty2;
    4.68 +        }
    4.69 +        return SDL_TRUE;
    4.70 +    }
    4.71 +
    4.72 +    /* FIXME: need code to clip diagonal line to rect */
    4.73 +    return SDL_FALSE;
    4.74 +}
    4.75 +
    4.76  void
    4.77  SDL_AddDirtyRect(SDL_DirtyRectList * list, const SDL_Rect * rect)
    4.78  {
     5.1 --- a/src/video/SDL_video.c	Tue Dec 23 01:28:06 2008 +0000
     5.2 +++ b/src/video/SDL_video.c	Tue Dec 23 02:23:18 2008 +0000
     5.3 @@ -2119,19 +2119,15 @@
     5.4          SDL_Unsupported();
     5.5          return -1;
     5.6      }
     5.7 -#if 0
     5.8 -    //FIXME: Need line intersect routine
     5.9      window = SDL_GetWindowFromID(renderer->window);
    5.10 +
    5.11      real_rect.x = 0;
    5.12      real_rect.y = 0;
    5.13      real_rect.w = window->w;
    5.14      real_rect.h = window->h;
    5.15 -    if (rect) {
    5.16 -        if (!SDL_IntersectRect(rect, &real_rect, &real_rect)) {
    5.17 -            return 0;
    5.18 -        }
    5.19 +    if (!SDL_IntersectRectAndLine(&real_rect, &x1, &x2, &y1, &y2)) {
    5.20 +        return (0);
    5.21      }
    5.22 -#endif
    5.23      return renderer->RenderLine(renderer, x1, y1, x2, y2);
    5.24  }
    5.25