Added interfaces for batch drawing of points, lines and rects:
authorSam Lantinga <slouken@libsdl.org>
Wed, 09 Dec 2009 15:56:56 +0000
changeset 35360267b8b1595c
parent 3535 b403f790df65
child 3537 e897a4a9f578
Added interfaces for batch drawing of points, lines and rects:
SDL_DrawPoints()
SDL_BlendPoints()
SDL_BlendLines()
SDL_DrawLines()
SDL_FillRects()
SDL_BlendRects()
SDL_RenderPoints()
SDL_RenderLines()
SDL_RenderRects()
Renamed SDL_RenderFill() to SDL_RenderRect()
include/SDL_compat.h
include/SDL_rect.h
include/SDL_surface.h
include/SDL_video.h
src/video/SDL_blendline.c
src/video/SDL_blendpoint.c
src/video/SDL_blendrect.c
src/video/SDL_draw.h
src/video/SDL_drawline.c
src/video/SDL_drawpoint.c
src/video/SDL_fillrect.c
src/video/SDL_rect.c
src/video/SDL_renderer_gl.c
src/video/SDL_renderer_gles.c
src/video/SDL_renderer_sw.c
src/video/SDL_sysvideo.h
src/video/SDL_video.c
src/video/dummy/SDL_nullrender.c
src/video/win32/SDL_d3drender.c
src/video/win32/SDL_gdirender.c
test/automated/render/render.c
test/testdraw2.c
test/testintersections.c
test/testnative.c
test/testsprite2.c
test/testspriteminimal.c
     1.1 --- a/include/SDL_compat.h	Mon Dec 07 10:08:24 2009 +0000
     1.2 +++ b/include/SDL_compat.h	Wed Dec 09 15:56:56 2009 +0000
     1.3 @@ -350,6 +350,8 @@
     1.4  extern DECLSPEC void SDLCALL SDL_GetKeyRepeat(int *delay, int *interval);
     1.5  extern DECLSPEC int SDLCALL SDL_EnableUNICODE(int enable);
     1.6  
     1.7 +#define SDL_RenderFill  SDL_RenderRect
     1.8 +
     1.9  /*@}*//*Compatibility*/
    1.10  
    1.11  /* Ends C function definitions when using C++ */
     2.1 --- a/include/SDL_rect.h	Mon Dec 07 10:08:24 2009 +0000
     2.2 +++ b/include/SDL_rect.h	Wed Dec 09 15:56:56 2009 +0000
     2.3 @@ -43,6 +43,17 @@
     2.4  #endif
     2.5  
     2.6  /**
     2.7 + *  \brief  The structure that defines a point
     2.8 + *
     2.9 + *  \sa SDL_EnclosePoints
    2.10 + */
    2.11 +typedef struct
    2.12 +{
    2.13 +    int x;
    2.14 +    int y;
    2.15 +} SDL_Point;
    2.16 +
    2.17 +/**
    2.18   *  \brief A rectangle, with the origin at the upper left.
    2.19   *  
    2.20   *  \sa SDL_RectEmpty
    2.21 @@ -50,6 +61,7 @@
    2.22   *  \sa SDL_HasIntersection
    2.23   *  \sa SDL_IntersectRect
    2.24   *  \sa SDL_UnionRect
    2.25 + *  \sa SDL_EnclosePoints
    2.26   */
    2.27  typedef struct SDL_Rect
    2.28  {
    2.29 @@ -93,6 +105,16 @@
    2.30                                             SDL_Rect * result);
    2.31  
    2.32  /**
    2.33 + *  \brief Calculate a minimal rectangle enclosing a set of points
    2.34 + *
    2.35 + *  \return SDL_TRUE if any points were within the clipping rect
    2.36 + */
    2.37 +extern DECLSPEC SDL_bool SDLCALL SDL_EnclosePoints(const SDL_Point * points,
    2.38 +                                                   int count,
    2.39 +                                                   const SDL_Rect * clip,
    2.40 +                                                   SDL_Rect * result);
    2.41 +
    2.42 +/**
    2.43   *  \brief Calculate the intersection of a rectangle and line segment.
    2.44   *  
    2.45   *  \return SDL_TRUE if there is an intersection, SDL_FALSE otherwise.
     3.1 --- a/include/SDL_surface.h	Mon Dec 07 10:08:24 2009 +0000
     3.2 +++ b/include/SDL_surface.h	Wed Dec 09 15:56:56 2009 +0000
     3.3 @@ -405,6 +405,8 @@
     3.4   */
     3.5  extern DECLSPEC int SDLCALL SDL_DrawPoint
     3.6      (SDL_Surface * dst, int x, int y, Uint32 color);
     3.7 +extern DECLSPEC int SDLCALL SDL_DrawPoints
     3.8 +    (SDL_Surface * dst, const SDL_Point * points, int count, Uint32 color);
     3.9  
    3.10  /**
    3.11   *  Blends a point with an RGBA value.
    3.12 @@ -415,8 +417,11 @@
    3.13   *  \return 0 on success, or -1 on error.
    3.14   */
    3.15  extern DECLSPEC int SDLCALL SDL_BlendPoint
    3.16 -    (SDL_Surface * dst, int x, int y, int blendMode,
    3.17 -     Uint8 r, Uint8 g, Uint8 b, Uint8 a);
    3.18 +    (SDL_Surface * dst, int x, int y,
    3.19 +     int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
    3.20 +extern DECLSPEC int SDLCALL SDL_BlendPoints
    3.21 +    (SDL_Surface * dst, const SDL_Point * points, int count,
    3.22 +     int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
    3.23  
    3.24  /**
    3.25   *  Draws a line with \c color.
    3.26 @@ -428,6 +433,8 @@
    3.27   */
    3.28  extern DECLSPEC int SDLCALL SDL_DrawLine
    3.29      (SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color);
    3.30 +extern DECLSPEC int SDLCALL SDL_DrawLines
    3.31 +    (SDL_Surface * dst, const SDL_Point * points, int count, Uint32 color);
    3.32  
    3.33  /**
    3.34   *  Blends an RGBA value along a line.
    3.35 @@ -435,16 +442,16 @@
    3.36   *  \return 0 on success, or -1 on error.
    3.37   */
    3.38  extern DECLSPEC int SDLCALL SDL_BlendLine
    3.39 -    (SDL_Surface * dst, int x1, int y1, int x2, int y2, int blendMode,
    3.40 -     Uint8 r, Uint8 g, Uint8 b, Uint8 a);
    3.41 +    (SDL_Surface * dst, int x1, int y1, int x2, int y2,
    3.42 +     int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
    3.43 +extern DECLSPEC int SDLCALL SDL_BlendLines
    3.44 +    (SDL_Surface * dst, const SDL_Point * points, int count,
    3.45 +     int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
    3.46  
    3.47  /**
    3.48   *  Performs a fast fill of the given rectangle with \c color.
    3.49   *  
    3.50 - *  The given rectangle is clipped to the destination surface clip area
    3.51 - *  and the final fill rectangle is saved in the passed in pointer.
    3.52 - *  
    3.53 - *  If \c dstrect is NULL, the whole surface will be filled with \c color.
    3.54 + *  If \c rect is NULL, the whole surface will be filled with \c color.
    3.55   *  
    3.56   *  The color should be a pixel of the format used by the surface, and 
    3.57   *  can be generated by the SDL_MapRGB() function.
    3.58 @@ -452,21 +459,23 @@
    3.59   *  \return 0 on success, or -1 on error.
    3.60   */
    3.61  extern DECLSPEC int SDLCALL SDL_FillRect
    3.62 -    (SDL_Surface * dst, SDL_Rect * dstrect, Uint32 color);
    3.63 +    (SDL_Surface * dst, const SDL_Rect * rect, Uint32 color);
    3.64 +extern DECLSPEC int SDLCALL SDL_FillRects
    3.65 +    (SDL_Surface * dst, const SDL_Rect ** rects, int count, Uint32 color);
    3.66  
    3.67  /**
    3.68   *  Blends an RGBA value into the given rectangle.
    3.69   *  
    3.70 - *  The given rectangle is clipped to the destination surface clip area
    3.71 - *  and the final fill rectangle is saved in the passed in pointer.
    3.72 - *  
    3.73 - *  If \c dstrect is NULL, the whole surface will be filled with \c color.
    3.74 + *  If \c rect is NULL, the whole surface will be filled with \c color.
    3.75   *  
    3.76   *  \return This function returns 0 on success, or -1 on error.
    3.77   */
    3.78  extern DECLSPEC int SDLCALL SDL_BlendRect
    3.79 -    (SDL_Surface * dst, SDL_Rect * dstrect, int blendMode, Uint8 r, Uint8 g,
    3.80 -     Uint8 b, Uint8 a);
    3.81 +    (SDL_Surface * dst, const SDL_Rect * rect,
    3.82 +     int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
    3.83 +extern DECLSPEC int SDLCALL SDL_BlendRects
    3.84 +    (SDL_Surface * dst, const SDL_Rect ** rects, int count,
    3.85 +     int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
    3.86  
    3.87  /**
    3.88   *  Performs a fast blit from the source surface to the destination surface.
     4.1 --- a/include/SDL_video.h	Mon Dec 07 10:08:24 2009 +0000
     4.2 +++ b/include/SDL_video.h	Wed Dec 09 15:56:56 2009 +0000
     4.3 @@ -1148,6 +1148,17 @@
     4.4  extern DECLSPEC int SDLCALL SDL_RenderPoint(int x, int y);
     4.5  
     4.6  /**
     4.7 + *  \brief Draw some number of points on the current rendering target.
     4.8 + *  
     4.9 + *  \param points The points to draw
    4.10 + *  \param count The number of points to draw
    4.11 + *  
    4.12 + *  \return 0 on success, or -1 if there is no rendering context current.
    4.13 + */
    4.14 +extern DECLSPEC int SDLCALL SDL_RenderPoints(const SDL_Point * points,
    4.15 +                                             int count);
    4.16 +
    4.17 +/**
    4.18   *  \brief Draw a line on the current rendering target.
    4.19   *  
    4.20   *  \param x1 The x coordinate of the start point.
    4.21 @@ -1160,6 +1171,17 @@
    4.22  extern DECLSPEC int SDLCALL SDL_RenderLine(int x1, int y1, int x2, int y2);
    4.23  
    4.24  /**
    4.25 + *  \brief Draw a series of connected lines on the current rendering target.
    4.26 + *  
    4.27 + *  \param points The points along the lines
    4.28 + *  \param count The number of points, drawing count-1 lines
    4.29 + *  
    4.30 + *  \return 0 on success, or -1 if there is no rendering context current.
    4.31 + */
    4.32 +extern DECLSPEC int SDLCALL SDL_RenderLines(const SDL_Point * points,
    4.33 +                                            int count);
    4.34 +
    4.35 +/**
    4.36   *  \brief Fill the current rendering target with the drawing color.
    4.37   *  
    4.38   *  \param rect A pointer to the destination rectangle, or NULL for the entire 
    4.39 @@ -1167,7 +1189,17 @@
    4.40   *  
    4.41   *  \return 0 on success, or -1 if there is no rendering context current.
    4.42   */
    4.43 -extern DECLSPEC int SDLCALL SDL_RenderFill(const SDL_Rect * rect);
    4.44 +extern DECLSPEC int SDLCALL SDL_RenderRect(const SDL_Rect * rect);
    4.45 +
    4.46 +/**
    4.47 + *  \brief Fill some number of rectangles in the current rendering target with the drawing color.
    4.48 + *  
    4.49 + *  \param rects A pointer to an array of destination rectangles.
    4.50 + *  \param count The number of rectangles.
    4.51 + *  
    4.52 + *  \return 0 on success, or -1 if there is no rendering context current.
    4.53 + */
    4.54 +extern DECLSPEC int SDLCALL SDL_RenderRects(const SDL_Rect ** rect, int count);
    4.55  
    4.56  /**
    4.57   *  \brief Copy a portion of the texture to the current rendering target.
     5.1 --- a/src/video/SDL_blendline.c	Mon Dec 07 10:08:24 2009 +0000
     5.2 +++ b/src/video/SDL_blendline.c	Wed Dec 09 15:56:56 2009 +0000
     5.3 @@ -195,8 +195,6 @@
     5.4  SDL_BlendLine(SDL_Surface * dst, int x1, int y1, int x2, int y2,
     5.5                int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
     5.6  {
     5.7 -    SDL_PixelFormat *fmt = dst->format;
     5.8 -
     5.9      /* This function doesn't work on surfaces < 8 bpp */
    5.10      if (dst->format->BitsPerPixel < 8) {
    5.11          SDL_SetError("SDL_BlendLine(): Unsupported surface format");
    5.12 @@ -209,32 +207,31 @@
    5.13      }
    5.14  
    5.15  
    5.16 -    if ((blendMode == SDL_BLENDMODE_BLEND)
    5.17 -        || (blendMode == SDL_BLENDMODE_ADD)) {
    5.18 +    if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
    5.19          r = DRAW_MUL(r, a);
    5.20          g = DRAW_MUL(g, a);
    5.21          b = DRAW_MUL(b, a);
    5.22      }
    5.23  
    5.24 -    switch (fmt->BitsPerPixel) {
    5.25 +    switch (dst->format->BitsPerPixel) {
    5.26      case 15:
    5.27 -        switch (fmt->Rmask) {
    5.28 +        switch (dst->format->Rmask) {
    5.29          case 0x7C00:
    5.30              return SDL_BlendLine_RGB555(dst, x1, y1, x2, y2, blendMode, r, g,
    5.31                                          b, a);
    5.32          }
    5.33          break;
    5.34      case 16:
    5.35 -        switch (fmt->Rmask) {
    5.36 +        switch (dst->format->Rmask) {
    5.37          case 0xF800:
    5.38              return SDL_BlendLine_RGB565(dst, x1, y1, x2, y2, blendMode, r, g,
    5.39                                          b, a);
    5.40          }
    5.41          break;
    5.42      case 32:
    5.43 -        switch (fmt->Rmask) {
    5.44 +        switch (dst->format->Rmask) {
    5.45          case 0x00FF0000:
    5.46 -            if (!fmt->Amask) {
    5.47 +            if (!dst->format->Amask) {
    5.48                  return SDL_BlendLine_RGB888(dst, x1, y1, x2, y2, blendMode, r,
    5.49                                              g, b, a);
    5.50              } else {
    5.51 @@ -243,15 +240,97 @@
    5.52              }
    5.53              break;
    5.54          }
    5.55 +        break;
    5.56      default:
    5.57          break;
    5.58      }
    5.59  
    5.60 -    if (!fmt->Amask) {
    5.61 +    if (!dst->format->Amask) {
    5.62          return SDL_BlendLine_RGB(dst, x1, y1, x2, y2, blendMode, r, g, b, a);
    5.63      } else {
    5.64          return SDL_BlendLine_RGBA(dst, x1, y1, x2, y2, blendMode, r, g, b, a);
    5.65      }
    5.66  }
    5.67  
    5.68 +int
    5.69 +SDL_BlendLines(SDL_Surface * dst, const SDL_Point * points, int count,
    5.70 +               int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
    5.71 +{
    5.72 +    int i;
    5.73 +    int x1, y1;
    5.74 +    int x2, y2;
    5.75 +    int (*func)(SDL_Surface * dst, int x1, int y1, int x2, int y2,
    5.76 +                int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) = NULL;
    5.77 +    int status = 0;
    5.78 +
    5.79 +    if (!dst) {
    5.80 +        SDL_SetError("Passed NULL destination surface");
    5.81 +        return -1;
    5.82 +    }
    5.83 +
    5.84 +    /* This function doesn't work on surfaces < 8 bpp */
    5.85 +    if (dst->format->BitsPerPixel < 8) {
    5.86 +        SDL_SetError("SDL_BlendLines(): Unsupported surface format");
    5.87 +        return -1;
    5.88 +    }
    5.89 +
    5.90 +    if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
    5.91 +        r = DRAW_MUL(r, a);
    5.92 +        g = DRAW_MUL(g, a);
    5.93 +        b = DRAW_MUL(b, a);
    5.94 +    }
    5.95 +
    5.96 +    /* FIXME: Does this function pointer slow things down significantly? */
    5.97 +    switch (dst->format->BitsPerPixel) {
    5.98 +    case 15:
    5.99 +        switch (dst->format->Rmask) {
   5.100 +        case 0x7C00:
   5.101 +            func = SDL_BlendLine_RGB555;
   5.102 +        }
   5.103 +        break;
   5.104 +    case 16:
   5.105 +        switch (dst->format->Rmask) {
   5.106 +        case 0xF800:
   5.107 +            func = SDL_BlendLine_RGB565;
   5.108 +        }
   5.109 +        break;
   5.110 +    case 32:
   5.111 +        switch (dst->format->Rmask) {
   5.112 +        case 0x00FF0000:
   5.113 +            if (!dst->format->Amask) {
   5.114 +                func = SDL_BlendLine_RGB888;
   5.115 +            } else {
   5.116 +                func = SDL_BlendLine_ARGB8888;
   5.117 +            }
   5.118 +            break;
   5.119 +        }
   5.120 +    default:
   5.121 +        break;
   5.122 +    }
   5.123 +
   5.124 +    if (!func) {
   5.125 +        if (!dst->format->Amask) {
   5.126 +            func = SDL_BlendLine_RGB;
   5.127 +        } else {
   5.128 +            func = SDL_BlendLine_RGBA;
   5.129 +        }
   5.130 +    }
   5.131 +
   5.132 +    for (i = 1; i < count; ++i) {
   5.133 +        x1 = points[i-1].x;
   5.134 +        y1 = points[i-1].y;
   5.135 +        x2 = points[i].x;
   5.136 +        y2 = points[i].y;
   5.137 +
   5.138 +        /* Perform clipping */
   5.139 +        /* FIXME: We don't actually want to clip, as it may change line slope */
   5.140 +        if (!SDL_IntersectRectAndLine(&dst->clip_rect, &x1, &y1, &x2, &y2)) {
   5.141 +            continue;
   5.142 +        }
   5.143 +
   5.144 +        status = func(dst, x1, y1, x2, y2, blendMode, r, g, b, a);
   5.145 +    }
   5.146 +    return status;
   5.147 +}
   5.148 +
   5.149  /* vi: set ts=4 sw=4 expandtab: */
     6.1 --- a/src/video/SDL_blendpoint.c	Mon Dec 07 10:08:24 2009 +0000
     6.2 +++ b/src/video/SDL_blendpoint.c	Wed Dec 09 15:56:56 2009 +0000
     6.3 @@ -195,12 +195,15 @@
     6.4  SDL_BlendPoint(SDL_Surface * dst, int x, int y, int blendMode, Uint8 r,
     6.5                 Uint8 g, Uint8 b, Uint8 a)
     6.6  {
     6.7 -    SDL_PixelFormat *fmt = dst->format;
     6.8 +    if (!dst) {
     6.9 +        SDL_SetError("Passed NULL destination surface");
    6.10 +        return -1;
    6.11 +    }
    6.12  
    6.13      /* This function doesn't work on surfaces < 8 bpp */
    6.14      if (dst->format->BitsPerPixel < 8) {
    6.15          SDL_SetError("SDL_BlendPoint(): Unsupported surface format");
    6.16 -        return (-1);
    6.17 +        return -1;
    6.18      }
    6.19  
    6.20      /* Perform clipping */
    6.21 @@ -210,30 +213,29 @@
    6.22          return 0;
    6.23      }
    6.24  
    6.25 -    if ((blendMode == SDL_BLENDMODE_BLEND)
    6.26 -        || (blendMode == SDL_BLENDMODE_ADD)) {
    6.27 +    if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
    6.28          r = DRAW_MUL(r, a);
    6.29          g = DRAW_MUL(g, a);
    6.30          b = DRAW_MUL(b, a);
    6.31      }
    6.32  
    6.33 -    switch (fmt->BitsPerPixel) {
    6.34 +    switch (dst->format->BitsPerPixel) {
    6.35      case 15:
    6.36 -        switch (fmt->Rmask) {
    6.37 +        switch (dst->format->Rmask) {
    6.38          case 0x7C00:
    6.39              return SDL_BlendPoint_RGB555(dst, x, y, blendMode, r, g, b, a);
    6.40          }
    6.41          break;
    6.42      case 16:
    6.43 -        switch (fmt->Rmask) {
    6.44 +        switch (dst->format->Rmask) {
    6.45          case 0xF800:
    6.46              return SDL_BlendPoint_RGB565(dst, x, y, blendMode, r, g, b, a);
    6.47          }
    6.48          break;
    6.49      case 32:
    6.50 -        switch (fmt->Rmask) {
    6.51 +        switch (dst->format->Rmask) {
    6.52          case 0x00FF0000:
    6.53 -            if (!fmt->Amask) {
    6.54 +            if (!dst->format->Amask) {
    6.55                  return SDL_BlendPoint_RGB888(dst, x, y, blendMode, r, g, b,
    6.56                                               a);
    6.57              } else {
    6.58 @@ -242,15 +244,101 @@
    6.59              }
    6.60              break;
    6.61          }
    6.62 +        break;
    6.63      default:
    6.64          break;
    6.65      }
    6.66  
    6.67 -    if (!fmt->Amask) {
    6.68 +    if (!dst->format->Amask) {
    6.69          return SDL_BlendPoint_RGB(dst, x, y, blendMode, r, g, b, a);
    6.70      } else {
    6.71          return SDL_BlendPoint_RGBA(dst, x, y, blendMode, r, g, b, a);
    6.72      }
    6.73  }
    6.74  
    6.75 +int
    6.76 +SDL_BlendPoints(SDL_Surface * dst, const SDL_Point * points, int count,
    6.77 +                int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
    6.78 +{
    6.79 +    int minx, miny;
    6.80 +    int maxx, maxy;
    6.81 +    int i;
    6.82 +    int x, y;
    6.83 +    int (*func)(SDL_Surface * dst, int x, int y,
    6.84 +                int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) = NULL;
    6.85 +    int status = 0;
    6.86 +
    6.87 +    if (!dst) {
    6.88 +        SDL_SetError("Passed NULL destination surface");
    6.89 +        return -1;
    6.90 +    }
    6.91 +
    6.92 +    /* This function doesn't work on surfaces < 8 bpp */
    6.93 +    if (dst->format->BitsPerPixel < 8) {
    6.94 +        SDL_SetError("SDL_BlendPoints(): Unsupported surface format");
    6.95 +        return (-1);
    6.96 +    }
    6.97 +
    6.98 +    if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
    6.99 +        r = DRAW_MUL(r, a);
   6.100 +        g = DRAW_MUL(g, a);
   6.101 +        b = DRAW_MUL(b, a);
   6.102 +    }
   6.103 +
   6.104 +    /* FIXME: Does this function pointer slow things down significantly? */
   6.105 +    switch (dst->format->BitsPerPixel) {
   6.106 +    case 15:
   6.107 +        switch (dst->format->Rmask) {
   6.108 +        case 0x7C00:
   6.109 +            func = SDL_BlendPoint_RGB555;
   6.110 +            break;
   6.111 +        }
   6.112 +        break;
   6.113 +    case 16:
   6.114 +        switch (dst->format->Rmask) {
   6.115 +        case 0xF800:
   6.116 +            func = SDL_BlendPoint_RGB565;
   6.117 +            break;
   6.118 +        }
   6.119 +        break;
   6.120 +    case 32:
   6.121 +        switch (dst->format->Rmask) {
   6.122 +        case 0x00FF0000:
   6.123 +            if (!dst->format->Amask) {
   6.124 +                func = SDL_BlendPoint_RGB888;
   6.125 +            } else {
   6.126 +                func = SDL_BlendPoint_ARGB8888;
   6.127 +            }
   6.128 +            break;
   6.129 +        }
   6.130 +        break;
   6.131 +    default:
   6.132 +        break;
   6.133 +    }
   6.134 +
   6.135 +    if (!func) {
   6.136 +        if (!dst->format->Amask) {
   6.137 +            func = SDL_BlendPoint_RGB;
   6.138 +        } else {
   6.139 +            func = SDL_BlendPoint_RGBA;
   6.140 +        }
   6.141 +    }
   6.142 +
   6.143 +    minx = dst->clip_rect.x;
   6.144 +    maxx = dst->clip_rect.x + dst->clip_rect.w - 1;
   6.145 +    miny = dst->clip_rect.y;
   6.146 +    maxy = dst->clip_rect.y + dst->clip_rect.h - 1;
   6.147 +
   6.148 +    for (i = 0; i < count; ++i) {
   6.149 +        x = points[i].x;
   6.150 +        y = points[i].y;
   6.151 +
   6.152 +        if (x < minx || x > maxx || y < miny || y > maxy) {
   6.153 +            continue;
   6.154 +        }
   6.155 +        status = func(dst, x, y, blendMode, r, g, b, a);
   6.156 +    }
   6.157 +    return status;
   6.158 +}
   6.159 +
   6.160  /* vi: set ts=4 sw=4 expandtab: */
     7.1 --- a/src/video/SDL_blendrect.c	Mon Dec 07 10:08:24 2009 +0000
     7.2 +++ b/src/video/SDL_blendrect.c	Wed Dec 09 15:56:56 2009 +0000
     7.3 @@ -25,7 +25,7 @@
     7.4  #include "SDL_draw.h"
     7.5  
     7.6  static int
     7.7 -SDL_BlendRect_RGB555(SDL_Surface * dst, SDL_Rect * dstrect, int blendMode,
     7.8 +SDL_BlendRect_RGB555(SDL_Surface * dst, const SDL_Rect * rect, int blendMode,
     7.9                       Uint8 r, Uint8 g, Uint8 b, Uint8 a)
    7.10  {
    7.11      unsigned inva = 0xff - a;
    7.12 @@ -48,7 +48,7 @@
    7.13  }
    7.14  
    7.15  static int
    7.16 -SDL_BlendRect_RGB565(SDL_Surface * dst, SDL_Rect * dstrect, int blendMode,
    7.17 +SDL_BlendRect_RGB565(SDL_Surface * dst, const SDL_Rect * rect, int blendMode,
    7.18                       Uint8 r, Uint8 g, Uint8 b, Uint8 a)
    7.19  {
    7.20      unsigned inva = 0xff - a;
    7.21 @@ -71,7 +71,7 @@
    7.22  }
    7.23  
    7.24  static int
    7.25 -SDL_BlendRect_RGB888(SDL_Surface * dst, SDL_Rect * dstrect, int blendMode,
    7.26 +SDL_BlendRect_RGB888(SDL_Surface * dst, const SDL_Rect * rect, int blendMode,
    7.27                       Uint8 r, Uint8 g, Uint8 b, Uint8 a)
    7.28  {
    7.29      unsigned inva = 0xff - a;
    7.30 @@ -94,7 +94,7 @@
    7.31  }
    7.32  
    7.33  static int
    7.34 -SDL_BlendRect_ARGB8888(SDL_Surface * dst, SDL_Rect * dstrect, int blendMode,
    7.35 +SDL_BlendRect_ARGB8888(SDL_Surface * dst, const SDL_Rect * rect, int blendMode,
    7.36                         Uint8 r, Uint8 g, Uint8 b, Uint8 a)
    7.37  {
    7.38      unsigned inva = 0xff - a;
    7.39 @@ -117,7 +117,7 @@
    7.40  }
    7.41  
    7.42  static int
    7.43 -SDL_BlendRect_RGB(SDL_Surface * dst, SDL_Rect * dstrect, int blendMode,
    7.44 +SDL_BlendRect_RGB(SDL_Surface * dst, const SDL_Rect * rect, int blendMode,
    7.45                    Uint8 r, Uint8 g, Uint8 b, Uint8 a)
    7.46  {
    7.47      SDL_PixelFormat *fmt = dst->format;
    7.48 @@ -163,7 +163,7 @@
    7.49  }
    7.50  
    7.51  static int
    7.52 -SDL_BlendRect_RGBA(SDL_Surface * dst, SDL_Rect * dstrect, int blendMode,
    7.53 +SDL_BlendRect_RGBA(SDL_Surface * dst, const SDL_Rect * rect, int blendMode,
    7.54                     Uint8 r, Uint8 g, Uint8 b, Uint8 a)
    7.55  {
    7.56      SDL_PixelFormat *fmt = dst->format;
    7.57 @@ -193,68 +193,155 @@
    7.58  }
    7.59  
    7.60  int
    7.61 -SDL_BlendRect(SDL_Surface * dst, SDL_Rect * dstrect, int blendMode, Uint8 r,
    7.62 -              Uint8 g, Uint8 b, Uint8 a)
    7.63 +SDL_BlendRect(SDL_Surface * dst, const SDL_Rect * rect,
    7.64 +              int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
    7.65  {
    7.66 -    SDL_PixelFormat *fmt = dst->format;
    7.67 +    SDL_Rect clipped;
    7.68 +
    7.69 +    if (!dst) {
    7.70 +        SDL_SetError("Passed NULL destination surface");
    7.71 +        return -1;
    7.72 +    }
    7.73  
    7.74      /* This function doesn't work on surfaces < 8 bpp */
    7.75 -    if (fmt->BitsPerPixel < 8) {
    7.76 +    if (dst->format->BitsPerPixel < 8) {
    7.77          SDL_SetError("SDL_BlendRect(): Unsupported surface format");
    7.78 -        return (-1);
    7.79 +        return -1;
    7.80      }
    7.81  
    7.82 -    /* If 'dstrect' == NULL, then fill the whole surface */
    7.83 -    if (dstrect) {
    7.84 +    /* If 'rect' == NULL, then fill the whole surface */
    7.85 +    if (rect) {
    7.86          /* Perform clipping */
    7.87 -        if (!SDL_IntersectRect(dstrect, &dst->clip_rect, dstrect)) {
    7.88 -            return (0);
    7.89 +        if (!SDL_IntersectRect(rect, &dst->clip_rect, &clipped)) {
    7.90 +            return 0;
    7.91          }
    7.92 +        rect = &clipped;
    7.93      } else {
    7.94 -        dstrect = &dst->clip_rect;
    7.95 +        rect = &dst->clip_rect;
    7.96      }
    7.97  
    7.98 -    if ((blendMode == SDL_BLENDMODE_BLEND)
    7.99 -        || (blendMode == SDL_BLENDMODE_ADD)) {
   7.100 +    if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
   7.101          r = DRAW_MUL(r, a);
   7.102          g = DRAW_MUL(g, a);
   7.103          b = DRAW_MUL(b, a);
   7.104      }
   7.105  
   7.106 -    switch (fmt->BitsPerPixel) {
   7.107 +    switch (dst->format->BitsPerPixel) {
   7.108      case 15:
   7.109 -        switch (fmt->Rmask) {
   7.110 +        switch (dst->format->Rmask) {
   7.111          case 0x7C00:
   7.112 -            return SDL_BlendRect_RGB555(dst, dstrect, blendMode, r, g, b, a);
   7.113 +            return SDL_BlendRect_RGB555(dst, rect, blendMode, r, g, b, a);
   7.114          }
   7.115          break;
   7.116      case 16:
   7.117 -        switch (fmt->Rmask) {
   7.118 +        switch (dst->format->Rmask) {
   7.119          case 0xF800:
   7.120 -            return SDL_BlendRect_RGB565(dst, dstrect, blendMode, r, g, b, a);
   7.121 +            return SDL_BlendRect_RGB565(dst, rect, blendMode, r, g, b, a);
   7.122          }
   7.123          break;
   7.124      case 32:
   7.125 -        switch (fmt->Rmask) {
   7.126 +        switch (dst->format->Rmask) {
   7.127          case 0x00FF0000:
   7.128 -            if (!fmt->Amask) {
   7.129 -                return SDL_BlendRect_RGB888(dst, dstrect, blendMode, r, g, b,
   7.130 -                                            a);
   7.131 +            if (!dst->format->Amask) {
   7.132 +                return SDL_BlendRect_RGB888(dst, rect, blendMode, r, g, b, a);
   7.133              } else {
   7.134 -                return SDL_BlendRect_ARGB8888(dst, dstrect, blendMode, r, g,
   7.135 -                                              b, a);
   7.136 +                return SDL_BlendRect_ARGB8888(dst, rect, blendMode, r, g, b, a);
   7.137              }
   7.138              break;
   7.139          }
   7.140 +        break;
   7.141      default:
   7.142          break;
   7.143      }
   7.144  
   7.145 -    if (!fmt->Amask) {
   7.146 -        return SDL_BlendRect_RGB(dst, dstrect, blendMode, r, g, b, a);
   7.147 +    if (!dst->format->Amask) {
   7.148 +        return SDL_BlendRect_RGB(dst, rect, blendMode, r, g, b, a);
   7.149      } else {
   7.150 -        return SDL_BlendRect_RGBA(dst, dstrect, blendMode, r, g, b, a);
   7.151 +        return SDL_BlendRect_RGBA(dst, rect, blendMode, r, g, b, a);
   7.152      }
   7.153  }
   7.154  
   7.155 +int
   7.156 +SDL_BlendRects(SDL_Surface * dst, const SDL_Rect ** rects, int count,
   7.157 +               int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
   7.158 +{
   7.159 +    SDL_Rect clipped;
   7.160 +    int i;
   7.161 +    int (*func)(SDL_Surface * dst, const SDL_Rect * rect,
   7.162 +                int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) = NULL;
   7.163 +    int status = 0;
   7.164 +
   7.165 +    if (!dst) {
   7.166 +        SDL_SetError("Passed NULL destination surface");
   7.167 +        return -1;
   7.168 +    }
   7.169 +
   7.170 +    /* This function doesn't work on surfaces < 8 bpp */
   7.171 +    if (dst->format->BitsPerPixel < 8) {
   7.172 +        SDL_SetError("SDL_BlendRects(): Unsupported surface format");
   7.173 +        return -1;
   7.174 +    }
   7.175 +
   7.176 +    if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
   7.177 +        r = DRAW_MUL(r, a);
   7.178 +        g = DRAW_MUL(g, a);
   7.179 +        b = DRAW_MUL(b, a);
   7.180 +    }
   7.181 +
   7.182 +    /* FIXME: Does this function pointer slow things down significantly? */
   7.183 +    switch (dst->format->BitsPerPixel) {
   7.184 +    case 15:
   7.185 +        switch (dst->format->Rmask) {
   7.186 +        case 0x7C00:
   7.187 +            func = SDL_BlendRect_RGB555;
   7.188 +        }
   7.189 +        break;
   7.190 +    case 16:
   7.191 +        switch (dst->format->Rmask) {
   7.192 +        case 0xF800:
   7.193 +            func = SDL_BlendRect_RGB565;
   7.194 +        }
   7.195 +        break;
   7.196 +    case 32:
   7.197 +        switch (dst->format->Rmask) {
   7.198 +        case 0x00FF0000:
   7.199 +            if (!dst->format->Amask) {
   7.200 +                func = SDL_BlendRect_RGB888;
   7.201 +            } else {
   7.202 +                func = SDL_BlendRect_ARGB8888;
   7.203 +            }
   7.204 +            break;
   7.205 +        }
   7.206 +        break;
   7.207 +    default:
   7.208 +        break;
   7.209 +    }
   7.210 +
   7.211 +    if (!func) {
   7.212 +        if (!dst->format->Amask) {
   7.213 +            func = SDL_BlendRect_RGB;
   7.214 +        } else {
   7.215 +            func = SDL_BlendRect_RGBA;
   7.216 +        }
   7.217 +    }
   7.218 +
   7.219 +    for (i = 0; i < count; ++i) {
   7.220 +        const SDL_Rect * rect = rects[i];
   7.221 +
   7.222 +        /* If 'rect' == NULL, then fill the whole surface */
   7.223 +        if (rect) {
   7.224 +            /* Perform clipping */
   7.225 +            if (!SDL_IntersectRect(rect, &dst->clip_rect, &clipped)) {
   7.226 +                continue;
   7.227 +            }
   7.228 +            rect = &clipped;
   7.229 +        } else {
   7.230 +            rect = &dst->clip_rect;
   7.231 +        }
   7.232 +
   7.233 +        status = func(dst, rect, blendMode, r, g, b, a);
   7.234 +    }
   7.235 +    return status;
   7.236 +}
   7.237 +
   7.238  /* vi: set ts=4 sw=4 expandtab: */
     8.1 --- a/src/video/SDL_draw.h	Mon Dec 07 10:08:24 2009 +0000
     8.2 +++ b/src/video/SDL_draw.h	Wed Dec 09 15:56:56 2009 +0000
     8.3 @@ -346,11 +346,11 @@
     8.4  
     8.5  #define FILLRECT(type, op) \
     8.6  do { \
     8.7 -    int width = dstrect->w; \
     8.8 -    int height = dstrect->h; \
     8.9 +    int width = rect->w; \
    8.10 +    int height = rect->h; \
    8.11      int pitch = (dst->pitch / dst->format->BytesPerPixel); \
    8.12      int skip = pitch - width; \
    8.13 -    type *pixel = (type *)dst->pixels + dstrect->y * pitch + dstrect->x; \
    8.14 +    type *pixel = (type *)dst->pixels + rect->y * pitch + rect->x; \
    8.15      while (height--) { \
    8.16          { int n = (width+3)/4; \
    8.17              switch (width & 3) { \
     9.1 --- a/src/video/SDL_drawline.c	Mon Dec 07 10:08:24 2009 +0000
     9.2 +++ b/src/video/SDL_drawline.c	Wed Dec 09 15:56:56 2009 +0000
     9.3 @@ -27,13 +27,19 @@
     9.4  int
     9.5  SDL_DrawLine(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color)
     9.6  {
     9.7 +    if (!dst) {
     9.8 +        SDL_SetError("Passed NULL destination surface");
     9.9 +        return -1;
    9.10 +    }
    9.11 +
    9.12      /* This function doesn't work on surfaces < 8 bpp */
    9.13      if (dst->format->BitsPerPixel < 8) {
    9.14          SDL_SetError("SDL_DrawLine(): Unsupported surface format");
    9.15 -        return (-1);
    9.16 +        return -1;
    9.17      }
    9.18  
    9.19      /* Perform clipping */
    9.20 +    /* FIXME: We don't actually want to clip, as it may change line slope */
    9.21      if (!SDL_IntersectRectAndLine(&dst->clip_rect, &x1, &y1, &x2, &y2)) {
    9.22          return (0);
    9.23      }
    9.24 @@ -55,4 +61,55 @@
    9.25      return 0;
    9.26  }
    9.27  
    9.28 +int
    9.29 +SDL_DrawLines(SDL_Surface * dst, const SDL_Point * points, int count,
    9.30 +              Uint32 color)
    9.31 +{
    9.32 +    int i;
    9.33 +
    9.34 +    if (!dst) {
    9.35 +        SDL_SetError("Passed NULL destination surface");
    9.36 +        return -1;
    9.37 +    }
    9.38 +
    9.39 +    /* This function doesn't work on surfaces < 8 bpp */
    9.40 +    if (dst->format->BitsPerPixel < 8) {
    9.41 +        SDL_SetError("SDL_DrawLine(): Unsupported surface format");
    9.42 +        return -1;
    9.43 +    }
    9.44 +
    9.45 +    if (count < 2) {
    9.46 +        return 0;
    9.47 +    }
    9.48 +
    9.49 +    for (i = 1; i < count; ++i) {
    9.50 +        int x1 = points[i-1].x;
    9.51 +        int y1 = points[i-1].y;
    9.52 +        int x2 = points[i].x;
    9.53 +        int y2 = points[i].y;
    9.54 +
    9.55 +        /* Perform clipping */
    9.56 +        /* FIXME: We don't actually want to clip, as it may change line slope */
    9.57 +        if (!SDL_IntersectRectAndLine(&dst->clip_rect, &x1, &y1, &x2, &y2)) {
    9.58 +            continue;
    9.59 +        }
    9.60 +
    9.61 +        switch (dst->format->BytesPerPixel) {
    9.62 +        case 1:
    9.63 +            DRAWLINE(x1, y1, x2, y2, DRAW_FASTSETPIXEL1);
    9.64 +            break;
    9.65 +        case 2:
    9.66 +            DRAWLINE(x1, y1, x2, y2, DRAW_FASTSETPIXEL2);
    9.67 +            break;
    9.68 +        case 3:
    9.69 +            SDL_Unsupported();
    9.70 +            return -1;
    9.71 +        case 4:
    9.72 +            DRAWLINE(x1, y1, x2, y2, DRAW_FASTSETPIXEL4);
    9.73 +            break;
    9.74 +        }
    9.75 +    }
    9.76 +    return 0;
    9.77 +}
    9.78 +
    9.79  /* vi: set ts=4 sw=4 expandtab: */
    10.1 --- a/src/video/SDL_drawpoint.c	Mon Dec 07 10:08:24 2009 +0000
    10.2 +++ b/src/video/SDL_drawpoint.c	Wed Dec 09 15:56:56 2009 +0000
    10.3 @@ -27,10 +27,15 @@
    10.4  int
    10.5  SDL_DrawPoint(SDL_Surface * dst, int x, int y, Uint32 color)
    10.6  {
    10.7 +    if (!dst) {
    10.8 +        SDL_SetError("Passed NULL destination surface");
    10.9 +        return -1;
   10.10 +    }
   10.11 +
   10.12      /* This function doesn't work on surfaces < 8 bpp */
   10.13      if (dst->format->BitsPerPixel < 8) {
   10.14          SDL_SetError("SDL_DrawPoint(): Unsupported surface format");
   10.15 -        return (-1);
   10.16 +        return -1;
   10.17      }
   10.18  
   10.19      /* Perform clipping */
   10.20 @@ -57,4 +62,55 @@
   10.21      return 0;
   10.22  }
   10.23  
   10.24 +int
   10.25 +SDL_DrawPoints(SDL_Surface * dst, const SDL_Point * points, int count,
   10.26 +               Uint32 color)
   10.27 +{
   10.28 +    int minx, miny;
   10.29 +    int maxx, maxy;
   10.30 +    int i;
   10.31 +    int x, y;
   10.32 +
   10.33 +    if (!dst) {
   10.34 +        SDL_SetError("Passed NULL destination surface");
   10.35 +        return -1;
   10.36 +    }
   10.37 +
   10.38 +    /* This function doesn't work on surfaces < 8 bpp */
   10.39 +    if (dst->format->BitsPerPixel < 8) {
   10.40 +        SDL_SetError("SDL_DrawPoints(): Unsupported surface format");
   10.41 +        return -1;
   10.42 +    }
   10.43 +
   10.44 +    minx = dst->clip_rect.x;
   10.45 +    maxx = dst->clip_rect.x + dst->clip_rect.w - 1;
   10.46 +    miny = dst->clip_rect.y;
   10.47 +    maxy = dst->clip_rect.y + dst->clip_rect.h - 1;
   10.48 +
   10.49 +    for (i = 0; i < count; ++i) {
   10.50 +        x = points[i].x;
   10.51 +        y = points[i].y;
   10.52 +
   10.53 +        if (x < minx || x > maxx || y < miny || y > maxy) {
   10.54 +            continue;
   10.55 +        }
   10.56 +
   10.57 +        switch (dst->format->BytesPerPixel) {
   10.58 +        case 1:
   10.59 +            DRAW_FASTSETPIXEL1(x, y);
   10.60 +            break;
   10.61 +        case 2:
   10.62 +            DRAW_FASTSETPIXEL2(x, y);
   10.63 +            break;
   10.64 +        case 3:
   10.65 +            SDL_Unsupported();
   10.66 +            return -1;
   10.67 +        case 4:
   10.68 +            DRAW_FASTSETPIXEL4(x, y);
   10.69 +            break;
   10.70 +        }
   10.71 +    }
   10.72 +    return 0;
   10.73 +}
   10.74 +
   10.75  /* vi: set ts=4 sw=4 expandtab: */
    11.1 --- a/src/video/SDL_fillrect.c	Mon Dec 07 10:08:24 2009 +0000
    11.2 +++ b/src/video/SDL_fillrect.c	Wed Dec 09 15:56:56 2009 +0000
    11.3 @@ -310,24 +310,31 @@
    11.4   * This function performs a fast fill of the given rectangle with 'color'
    11.5   */
    11.6  int
    11.7 -SDL_FillRect(SDL_Surface * dst, SDL_Rect * dstrect, Uint32 color)
    11.8 +SDL_FillRect(SDL_Surface * dst, const SDL_Rect * rect, Uint32 color)
    11.9  {
   11.10 +    SDL_Rect clipped;
   11.11      Uint8 *pixels;
   11.12  
   11.13 +    if (!dst) {
   11.14 +        SDL_SetError("Passed NULL destination surface");
   11.15 +        return -1;
   11.16 +    }
   11.17 +
   11.18      /* This function doesn't work on surfaces < 8 bpp */
   11.19      if (dst->format->BitsPerPixel < 8) {
   11.20          SDL_SetError("SDL_FillRect(): Unsupported surface format");
   11.21 -        return (-1);
   11.22 +        return -1;
   11.23      }
   11.24  
   11.25 -    /* If 'dstrect' == NULL, then fill the whole surface */
   11.26 -    if (dstrect) {
   11.27 +    /* If 'rect' == NULL, then fill the whole surface */
   11.28 +    if (rect) {
   11.29          /* Perform clipping */
   11.30 -        if (!SDL_IntersectRect(dstrect, &dst->clip_rect, dstrect)) {
   11.31 -            return (0);
   11.32 +        if (!SDL_IntersectRect(rect, &dst->clip_rect, &clipped)) {
   11.33 +            return 0;
   11.34          }
   11.35 +        rect = &clipped;
   11.36      } else {
   11.37 -        dstrect = &dst->clip_rect;
   11.38 +        rect = &dst->clip_rect;
   11.39      }
   11.40  
   11.41      /* Perform software fill */
   11.42 @@ -336,9 +343,8 @@
   11.43          return (-1);
   11.44      }
   11.45  
   11.46 -    pixels =
   11.47 -        (Uint8 *) dst->pixels + dstrect->y * dst->pitch +
   11.48 -        dstrect->x * dst->format->BytesPerPixel;
   11.49 +    pixels = (Uint8 *) dst->pixels + rect->y * dst->pitch +
   11.50 +                                     rect->x * dst->format->BytesPerPixel;
   11.51  
   11.52      switch (dst->format->BytesPerPixel) {
   11.53      case 1:
   11.54 @@ -347,19 +353,17 @@
   11.55              color |= (color << 16);
   11.56  #ifdef __SSE__
   11.57              if (SDL_HasSSE()) {
   11.58 -                SDL_FillRect1SSE(pixels, dst->pitch, color, dstrect->w,
   11.59 -                                 dstrect->h);
   11.60 +                SDL_FillRect1SSE(pixels, dst->pitch, color, rect->w, rect->h);
   11.61                  break;
   11.62              }
   11.63  #endif
   11.64  #ifdef __MMX__
   11.65              if (SDL_HasMMX()) {
   11.66 -                SDL_FillRect1MMX(pixels, dst->pitch, color, dstrect->w,
   11.67 -                                 dstrect->h);
   11.68 +                SDL_FillRect1MMX(pixels, dst->pitch, color, rect->w, rect->h);
   11.69                  break;
   11.70              }
   11.71  #endif
   11.72 -            SDL_FillRect1(pixels, dst->pitch, color, dstrect->w, dstrect->h);
   11.73 +            SDL_FillRect1(pixels, dst->pitch, color, rect->w, rect->h);
   11.74              break;
   11.75          }
   11.76  
   11.77 @@ -368,26 +372,24 @@
   11.78              color |= (color << 16);
   11.79  #ifdef __SSE__
   11.80              if (SDL_HasSSE()) {
   11.81 -                SDL_FillRect2SSE(pixels, dst->pitch, color, dstrect->w,
   11.82 -                                 dstrect->h);
   11.83 +                SDL_FillRect2SSE(pixels, dst->pitch, color, rect->w, rect->h);
   11.84                  break;
   11.85              }
   11.86  #endif
   11.87  #ifdef __MMX__
   11.88              if (SDL_HasMMX()) {
   11.89 -                SDL_FillRect2MMX(pixels, dst->pitch, color, dstrect->w,
   11.90 -                                 dstrect->h);
   11.91 +                SDL_FillRect2MMX(pixels, dst->pitch, color, rect->w, rect->h);
   11.92                  break;
   11.93              }
   11.94  #endif
   11.95 -            SDL_FillRect2(pixels, dst->pitch, color, dstrect->w, dstrect->h);
   11.96 +            SDL_FillRect2(pixels, dst->pitch, color, rect->w, rect->h);
   11.97              break;
   11.98          }
   11.99  
  11.100      case 3:
  11.101          /* 24-bit RGB is a slow path, at least for now. */
  11.102          {
  11.103 -            SDL_FillRect3(pixels, dst->pitch, color, dstrect->w, dstrect->h);
  11.104 +            SDL_FillRect3(pixels, dst->pitch, color, rect->w, rect->h);
  11.105              break;
  11.106          }
  11.107  
  11.108 @@ -395,25 +397,36 @@
  11.109          {
  11.110  #ifdef __SSE__
  11.111              if (SDL_HasSSE()) {
  11.112 -                SDL_FillRect4SSE(pixels, dst->pitch, color, dstrect->w,
  11.113 -                                 dstrect->h);
  11.114 +                SDL_FillRect4SSE(pixels, dst->pitch, color, rect->w, rect->h);
  11.115                  break;
  11.116              }
  11.117  #endif
  11.118  #ifdef __MMX__
  11.119              if (SDL_HasMMX()) {
  11.120 -                SDL_FillRect4MMX(pixels, dst->pitch, color, dstrect->w,
  11.121 -                                 dstrect->h);
  11.122 +                SDL_FillRect4MMX(pixels, dst->pitch, color, rect->w, rect->h);
  11.123                  break;
  11.124              }
  11.125  #endif
  11.126 -            SDL_FillRect4(pixels, dst->pitch, color, dstrect->w, dstrect->h);
  11.127 +            SDL_FillRect4(pixels, dst->pitch, color, rect->w, rect->h);
  11.128              break;
  11.129          }
  11.130      }
  11.131  
  11.132      /* We're done! */
  11.133 -    return (0);
  11.134 +    return 0;
  11.135 +}
  11.136 +
  11.137 +int
  11.138 +SDL_FillRects(SDL_Surface * dst, const SDL_Rect ** rects, int count,
  11.139 +              Uint32 color)
  11.140 +{
  11.141 +    int i;
  11.142 +    int status = 0;
  11.143 +
  11.144 +    for (i = 0; i < count; ++i) {
  11.145 +        status = SDL_FillRect(dst, rects[i], color);
  11.146 +    }
  11.147 +    return status;
  11.148  }
  11.149  
  11.150  /* vi: set ts=4 sw=4 expandtab: */
    12.1 --- a/src/video/SDL_rect.c	Mon Dec 07 10:08:24 2009 +0000
    12.2 +++ b/src/video/SDL_rect.c	Wed Dec 09 15:56:56 2009 +0000
    12.3 @@ -119,6 +119,84 @@
    12.4  }
    12.5  
    12.6  SDL_bool
    12.7 +SDL_EnclosePoints(const SDL_Point * points, int count, const SDL_Rect * clip,
    12.8 +                  SDL_Rect * result)
    12.9 +{
   12.10 +    int minx, miny;
   12.11 +    int maxx, maxy;
   12.12 +    int x, y, i;
   12.13 +
   12.14 +    if (count < 1) {
   12.15 +        return SDL_FALSE;
   12.16 +    }
   12.17 +
   12.18 +    if (clip) {
   12.19 +        SDL_bool added = SDL_FALSE;
   12.20 +        int clip_minx = clip->x;
   12.21 +        int clip_miny = clip->y;
   12.22 +        int clip_maxx = clip->x+clip->w-1;
   12.23 +        int clip_maxy = clip->y+clip->h-1;
   12.24 +
   12.25 +        for (i = 0; i < count; ++i) {
   12.26 +            x = points[i].x;
   12.27 +            y = points[i].y;
   12.28 +
   12.29 +            if (x < clip_minx || x > clip_maxx ||
   12.30 +                y < clip_miny || y > clip_maxy) {
   12.31 +                continue;
   12.32 +            }
   12.33 +            if (!added) {
   12.34 +                minx = maxx = x;
   12.35 +                miny = maxy = y;
   12.36 +                added = SDL_TRUE;
   12.37 +                continue;
   12.38 +            }
   12.39 +            if (x < minx) {
   12.40 +                minx = x;
   12.41 +            } else if (x > maxx) {
   12.42 +                maxx = x;
   12.43 +            }
   12.44 +            if (y < miny) {
   12.45 +                miny = y;
   12.46 +            } else if (y > maxy) {
   12.47 +                maxy = y;
   12.48 +            }
   12.49 +        }
   12.50 +        if (!added) {
   12.51 +            return SDL_FALSE;
   12.52 +        }
   12.53 +    } else {
   12.54 +        /* No clipping, always add the first point */
   12.55 +        minx = maxx = points[0].x;
   12.56 +        miny = maxy = points[0].y;
   12.57 +
   12.58 +        for (i = 1; i < count; ++i) {
   12.59 +            x = points[i].x;
   12.60 +            y = points[i].y;
   12.61 +
   12.62 +            if (x < minx) {
   12.63 +                minx = x;
   12.64 +            } else if (x > maxx) {
   12.65 +                maxx = x;
   12.66 +            }
   12.67 +            if (y < miny) {
   12.68 +                miny = y;
   12.69 +            } else if (y > maxy) {
   12.70 +                maxy = y;
   12.71 +            }
   12.72 +        }
   12.73 +    }
   12.74 +
   12.75 +    if (result) {
   12.76 +        result->x = minx;
   12.77 +        result->y = miny;
   12.78 +        result->w = (maxx-minx)+1;
   12.79 +        result->h = (maxy-miny)+1;
   12.80 +    }
   12.81 +    return SDL_TRUE;
   12.82 +}
   12.83 +
   12.84 +SDL_bool
   12.85  SDL_IntersectRectAndLine(const SDL_Rect * rect, int *X1, int *Y1, int *X2,
   12.86                           int *Y2)
   12.87  {
    13.1 --- a/src/video/SDL_renderer_gl.c	Mon Dec 07 10:08:24 2009 +0000
    13.2 +++ b/src/video/SDL_renderer_gl.c	Wed Dec 09 15:56:56 2009 +0000
    13.3 @@ -96,10 +96,12 @@
    13.4  static void GL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
    13.5  static void GL_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture,
    13.6                              int numrects, const SDL_Rect * rects);
    13.7 -static int GL_RenderPoint(SDL_Renderer * renderer, int x, int y);
    13.8 -static int GL_RenderLine(SDL_Renderer * renderer, int x1, int y1, int x2,
    13.9 -                         int y2);
   13.10 -static int GL_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect);
   13.11 +static int GL_RenderPoints(SDL_Renderer * renderer, const SDL_Point * points,
   13.12 +                           int count);
   13.13 +static int GL_RenderLines(SDL_Renderer * renderer, const SDL_Point * points,
   13.14 +                          int count);
   13.15 +static int GL_RenderRects(SDL_Renderer * renderer, const SDL_Rect ** rects,
   13.16 +                          int count);
   13.17  static int GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
   13.18                           const SDL_Rect * srcrect, const SDL_Rect * dstrect);
   13.19  static int GL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
   13.20 @@ -304,9 +306,9 @@
   13.21      renderer->LockTexture = GL_LockTexture;
   13.22      renderer->UnlockTexture = GL_UnlockTexture;
   13.23      renderer->DirtyTexture = GL_DirtyTexture;
   13.24 -    renderer->RenderPoint = GL_RenderPoint;
   13.25 -    renderer->RenderLine = GL_RenderLine;
   13.26 -    renderer->RenderFill = GL_RenderFill;
   13.27 +    renderer->RenderPoints = GL_RenderPoints;
   13.28 +    renderer->RenderLines = GL_RenderLines;
   13.29 +    renderer->RenderRects = GL_RenderRects;
   13.30      renderer->RenderCopy = GL_RenderCopy;
   13.31      renderer->RenderReadPixels = GL_RenderReadPixels;
   13.32      renderer->RenderWritePixels = GL_RenderWritePixels;
   13.33 @@ -1112,9 +1114,10 @@
   13.34  }
   13.35  
   13.36  static int
   13.37 -GL_RenderPoint(SDL_Renderer * renderer, int x, int y)
   13.38 +GL_RenderPoints(SDL_Renderer * renderer, const SDL_Point * points, int count)
   13.39  {
   13.40      GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
   13.41 +    int i;
   13.42  
   13.43      GL_SetBlendMode(data, renderer->blendMode, 1);
   13.44  
   13.45 @@ -1124,16 +1127,19 @@
   13.46                      (GLfloat) renderer->a * inv255f);
   13.47  
   13.48      data->glBegin(GL_POINTS);
   13.49 -    data->glVertex2f(0.5f + x, 0.5f + y);
   13.50 +    for (i = 0; i < count; ++i) {
   13.51 +        data->glVertex2f(0.5f + points[i].x, 0.5f + points[i].y);
   13.52 +    }
   13.53      data->glEnd();
   13.54  
   13.55      return 0;
   13.56  }
   13.57  
   13.58  static int
   13.59 -GL_RenderLine(SDL_Renderer * renderer, int x1, int y1, int x2, int y2)
   13.60 +GL_RenderLines(SDL_Renderer * renderer, const SDL_Point * points, int count)
   13.61  {
   13.62      GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
   13.63 +    int i;
   13.64  
   13.65      GL_SetBlendMode(data, renderer->blendMode, 1);
   13.66  
   13.67 @@ -1142,43 +1148,61 @@
   13.68                      (GLfloat) renderer->b * inv255f,
   13.69                      (GLfloat) renderer->a * inv255f);
   13.70  
   13.71 -    data->glBegin(GL_LINES);
   13.72 -    data->glVertex2f(0.5f + x1, 0.5f + y1);
   13.73 -    data->glVertex2f(0.5f + x2, 0.5f + y2);
   13.74 -    data->glEnd();
   13.75 +    if (count > 2 && 
   13.76 +        points[0].x == points[count-1].x && points[0].y == points[count-1].y) {
   13.77 +        data->glBegin(GL_LINE_LOOP);
   13.78 +        /* GL_LINE_LOOP takes care of the final segment */
   13.79 +        --count;
   13.80 +        for (i = 0; i < count; ++i) {
   13.81 +            data->glVertex2f(0.5f + points[i].x, 0.5f + points[i].y);
   13.82 +        }
   13.83 +        data->glEnd();
   13.84 +    } else {
   13.85 +        data->glBegin(GL_LINE_STRIP);
   13.86 +        for (i = 0; i < count; ++i) {
   13.87 +            data->glVertex2f(0.5f + points[i].x, 0.5f + points[i].y);
   13.88 +        }
   13.89 +        data->glEnd();
   13.90  
   13.91 -    /* The line is half open, so we need one more point to complete the line.
   13.92 -     * http://www.opengl.org/documentation/specs/version1.1/glspec1.1/node47.html
   13.93 -     * If we have to, we can use vertical line and horizontal line textures
   13.94 -     * for vertical and horizontal lines, and then create custom textures
   13.95 -     * for diagonal lines and software render those.  It's terrible, but at
   13.96 -     * least it would be pixel perfect.
   13.97 -     */
   13.98 -    data->glBegin(GL_POINTS);
   13.99 +        /* The line is half open, so we need one more point to complete it.
  13.100 +         * http://www.opengl.org/documentation/specs/version1.1/glspec1.1/node47.html
  13.101 +         * If we have to, we can use vertical line and horizontal line textures
  13.102 +         * for vertical and horizontal lines, and then create custom textures
  13.103 +         * for diagonal lines and software render those.  It's terrible, but at
  13.104 +         * least it would be pixel perfect.
  13.105 +         */
  13.106 +        data->glBegin(GL_POINTS);
  13.107  #if defined(__APPLE__) || defined(__WIN32__)
  13.108 -    /* Mac OS X and Windows seem to always leave the second point open */
  13.109 -    data->glVertex2f(0.5f + x2, 0.5f + y2);
  13.110 +        /* Mac OS X and Windows seem to always leave the second point open */
  13.111 +        data->glVertex2f(0.5f + points[count-1].x, 0.5f + points[count-1].y);
  13.112  #else
  13.113 -    /* Linux seems to leave the right-most or bottom-most point open */
  13.114 -    if (x1 > x2) {
  13.115 -        data->glVertex2f(0.5f + x1, 0.5f + y1);
  13.116 -    } else if (x2 > x1) {
  13.117 -        data->glVertex2f(0.5f + x2, 0.5f + y2);
  13.118 -    } else if (y1 > y2) {
  13.119 -        data->glVertex2f(0.5f + x1, 0.5f + y1);
  13.120 -    } else if (y2 > y1) {
  13.121 -        data->glVertex2f(0.5f + x2, 0.5f + y2);
  13.122 +        /* Linux seems to leave the right-most or bottom-most point open */
  13.123 +        int x1 = points[0].x;
  13.124 +        int y1 = points[0].y;
  13.125 +        int x2 = points[count-1].x;
  13.126 +        int y2 = points[count-1].y;
  13.127 +
  13.128 +        if (x1 > x2) {
  13.129 +            data->glVertex2f(0.5f + x1, 0.5f + y1);
  13.130 +        } else if (x2 > x1) {
  13.131 +            data->glVertex2f(0.5f + x2, 0.5f + y2);
  13.132 +        } else if (y1 > y2) {
  13.133 +            data->glVertex2f(0.5f + x1, 0.5f + y1);
  13.134 +        } else if (y2 > y1) {
  13.135 +            data->glVertex2f(0.5f + x2, 0.5f + y2);
  13.136 +        }
  13.137 +#endif
  13.138 +        data->glEnd();
  13.139      }
  13.140 -#endif
  13.141 -    data->glEnd();
  13.142  
  13.143      return 0;
  13.144  }
  13.145  
  13.146  static int
  13.147 -GL_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect)
  13.148 +GL_RenderRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count)
  13.149  {
  13.150      GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
  13.151 +    int i;
  13.152  
  13.153      GL_SetBlendMode(data, renderer->blendMode, 1);
  13.154  
  13.155 @@ -1187,7 +1211,11 @@
  13.156                      (GLfloat) renderer->b * inv255f,
  13.157                      (GLfloat) renderer->a * inv255f);
  13.158  
  13.159 -    data->glRecti(rect->x, rect->y, rect->x + rect->w, rect->y + rect->h);
  13.160 +    for (i = 0; i < count; ++i) {
  13.161 +        const SDL_Rect *rect = rects[i];
  13.162 +
  13.163 +        data->glRecti(rect->x, rect->y, rect->x + rect->w, rect->y + rect->h);
  13.164 +    }
  13.165  
  13.166      return 0;
  13.167  }
    14.1 --- a/src/video/SDL_renderer_gles.c	Mon Dec 07 10:08:24 2009 +0000
    14.2 +++ b/src/video/SDL_renderer_gles.c	Wed Dec 09 15:56:56 2009 +0000
    14.3 @@ -85,10 +85,12 @@
    14.4                                 SDL_Texture * texture);
    14.5  static void GLES_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture,
    14.6                                int numrects, const SDL_Rect * rects);
    14.7 -static int GLES_RenderPoint(SDL_Renderer * renderer, int x, int y);
    14.8 -static int GLES_RenderLine(SDL_Renderer * renderer, int x1, int y1, int x2,
    14.9 -                           int y2);
   14.10 -static int GLES_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect);
   14.11 +static int GLES_RenderPoints(SDL_Renderer * renderer, const SDL_Point * points,
   14.12 +                             int count);
   14.13 +static int GLES_RenderLines(SDL_Renderer * renderer, const SDL_Point * points,
   14.14 +                            int count);
   14.15 +static int GLES_RenderRects(SDL_Renderer * renderer, const SDL_Rect ** rects,
   14.16 +                            int count);
   14.17  static int GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
   14.18                             const SDL_Rect * srcrect,
   14.19                             const SDL_Rect * dstrect);
   14.20 @@ -242,9 +244,9 @@
   14.21      renderer->LockTexture = GLES_LockTexture;
   14.22      renderer->UnlockTexture = GLES_UnlockTexture;
   14.23      renderer->DirtyTexture = GLES_DirtyTexture;
   14.24 -    renderer->RenderPoint = GLES_RenderPoint;
   14.25 -    renderer->RenderLine = GLES_RenderLine;
   14.26 -    renderer->RenderFill = GLES_RenderFill;
   14.27 +    renderer->RenderPoints = GLES_RenderPoints;
   14.28 +    renderer->RenderLines = GLES_RenderLines;
   14.29 +    renderer->RenderRects = GLES_RenderRects;
   14.30      renderer->RenderCopy = GLES_RenderCopy;
   14.31      renderer->RenderPresent = GLES_RenderPresent;
   14.32      renderer->DestroyTexture = GLES_DestroyTexture;
   14.33 @@ -641,7 +643,7 @@
   14.34  }
   14.35  
   14.36  static int
   14.37 -GLES_RenderPoint(SDL_Renderer * renderer, int x, int y)
   14.38 +GLES_RenderPoints(SDL_Renderer * renderer, const SDL_Point * points, int count)
   14.39  {
   14.40      GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
   14.41  
   14.42 @@ -652,20 +654,16 @@
   14.43                      (GLfloat) renderer->b * inv255f,
   14.44                      (GLfloat) renderer->a * inv255f);
   14.45  
   14.46 -    GLshort vertices[2];
   14.47 -    vertices[0] = x;
   14.48 -    vertices[1] = y;
   14.49 -
   14.50 -    data->glVertexPointer(2, GL_SHORT, 0, vertices);
   14.51 +    data->glVertexPointer(2, GL_INT, 0, points);
   14.52      data->glEnableClientState(GL_VERTEX_ARRAY);
   14.53 -    data->glDrawArrays(GL_POINTS, 0, 1);
   14.54 +    data->glDrawArrays(GL_POINTS, 0, count);
   14.55      data->glDisableClientState(GL_VERTEX_ARRAY);
   14.56  
   14.57      return 0;
   14.58  }
   14.59  
   14.60  static int
   14.61 -GLES_RenderLine(SDL_Renderer * renderer, int x1, int y1, int x2, int y2)
   14.62 +GLES_RenderLines(SDL_Renderer * renderer, const SDL_Point * points, int count)
   14.63  {
   14.64      GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
   14.65  
   14.66 @@ -676,24 +674,26 @@
   14.67                      (GLfloat) renderer->b * inv255f,
   14.68                      (GLfloat) renderer->a * inv255f);
   14.69  
   14.70 -    GLshort vertices[4];
   14.71 -    vertices[0] = x1;
   14.72 -    vertices[1] = y1;
   14.73 -    vertices[2] = x2;
   14.74 -    vertices[3] = y2;
   14.75 -
   14.76 -    data->glVertexPointer(2, GL_SHORT, 0, vertices);
   14.77 +    data->glVertexPointer(2, GL_INT, 0, points);
   14.78      data->glEnableClientState(GL_VERTEX_ARRAY);
   14.79 -    data->glDrawArrays(GL_LINES, 0, 2);
   14.80 +    if (count > 2 && 
   14.81 +        points[0].x == points[count-1].x && points[0].y == points[count-1].y) {
   14.82 +        /* GL_LINE_LOOP takes care of the final segment */
   14.83 +        --count;
   14.84 +        data->glDrawArrays(GL_LINE_LOOP, 0, count);
   14.85 +    } else {
   14.86 +        data->glDrawArrays(GL_LINE_STRIP, 0, count);
   14.87 +    }
   14.88      data->glDisableClientState(GL_VERTEX_ARRAY);
   14.89  
   14.90      return 0;
   14.91  }
   14.92  
   14.93  static int
   14.94 -GLES_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect)
   14.95 +GLES_RenderRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count)
   14.96  {
   14.97      GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
   14.98 +    int i;
   14.99  
  14.100      GLES_SetBlendMode(data, renderer->blendMode, 1);
  14.101  
  14.102 @@ -702,24 +702,26 @@
  14.103                      (GLfloat) renderer->b * inv255f,
  14.104                      (GLfloat) renderer->a * inv255f);
  14.105  
  14.106 -    GLshort minx = rect->x;
  14.107 -    GLshort maxx = rect->x + rect->w;
  14.108 -    GLshort miny = rect->y;
  14.109 -    GLshort maxy = rect->y + rect->h;
  14.110 +    data->glEnableClientState(GL_VERTEX_ARRAY);
  14.111 +    for (i = 0; i < count; ++i) {
  14.112 +        const SDL_Rect *rect = rects[i];
  14.113 +        GLshort minx = rect->x;
  14.114 +        GLshort maxx = rect->x + rect->w;
  14.115 +        GLshort miny = rect->y;
  14.116 +        GLshort maxy = rect->y + rect->h;
  14.117 +        GLshort vertices[8];
  14.118 +        vertices[0] = minx;
  14.119 +        vertices[1] = miny;
  14.120 +        vertices[2] = maxx;
  14.121 +        vertices[3] = miny;
  14.122 +        vertices[4] = minx;
  14.123 +        vertices[5] = maxy;
  14.124 +        vertices[6] = maxx;
  14.125 +        vertices[7] = maxy;
  14.126  
  14.127 -    GLshort vertices[8];
  14.128 -    vertices[0] = minx;
  14.129 -    vertices[1] = miny;
  14.130 -    vertices[2] = maxx;
  14.131 -    vertices[3] = miny;
  14.132 -    vertices[4] = minx;
  14.133 -    vertices[5] = maxy;
  14.134 -    vertices[6] = maxx;
  14.135 -    vertices[7] = maxy;
  14.136 -
  14.137 -    data->glVertexPointer(2, GL_SHORT, 0, vertices);
  14.138 -    data->glEnableClientState(GL_VERTEX_ARRAY);
  14.139 -    data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  14.140 +        data->glVertexPointer(2, GL_SHORT, 0, vertices);
  14.141 +        data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  14.142 +    }
  14.143      data->glDisableClientState(GL_VERTEX_ARRAY);
  14.144  
  14.145      return 0;
    15.1 --- a/src/video/SDL_renderer_sw.c	Mon Dec 07 10:08:24 2009 +0000
    15.2 +++ b/src/video/SDL_renderer_sw.c	Wed Dec 09 15:56:56 2009 +0000
    15.3 @@ -59,10 +59,12 @@
    15.4                            const SDL_Rect * rect, int markDirty, void **pixels,
    15.5                            int *pitch);
    15.6  static void SW_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
    15.7 -static int SW_RenderPoint(SDL_Renderer * renderer, int x, int y);
    15.8 -static int SW_RenderLine(SDL_Renderer * renderer, int x1, int y1, int x2,
    15.9 -                         int y2);
   15.10 -static int SW_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect);
   15.11 +static int SW_RenderPoints(SDL_Renderer * renderer, const SDL_Point * points,
   15.12 +                           int count);
   15.13 +static int SW_RenderLines(SDL_Renderer * renderer, const SDL_Point * points,
   15.14 +                          int count);
   15.15 +static int SW_RenderRects(SDL_Renderer * renderer, const SDL_Rect ** rects,
   15.16 +                          int count);
   15.17  static int SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
   15.18                           const SDL_Rect * srcrect, const SDL_Rect * dstrect);
   15.19  static int SW_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
   15.20 @@ -228,9 +230,9 @@
   15.21      renderer->ActivateRenderer = SW_ActivateRenderer;
   15.22      renderer->DisplayModeChanged = SW_DisplayModeChanged;
   15.23  
   15.24 -    renderer->RenderPoint = SW_RenderPoint;
   15.25 -    renderer->RenderLine = SW_RenderLine;
   15.26 -    renderer->RenderFill = SW_RenderFill;
   15.27 +    renderer->RenderPoints = SW_RenderPoints;
   15.28 +    renderer->RenderLines = SW_RenderLines;
   15.29 +    renderer->RenderRects = SW_RenderRects;
   15.30      renderer->RenderCopy = SW_RenderCopy;
   15.31      renderer->RenderReadPixels = SW_RenderReadPixels;
   15.32      renderer->RenderWritePixels = SW_RenderWritePixels;
   15.33 @@ -537,156 +539,189 @@
   15.34  }
   15.35  
   15.36  static int
   15.37 -SW_RenderPoint(SDL_Renderer * renderer, int x, int y)
   15.38 +SW_RenderPoints(SDL_Renderer * renderer, const SDL_Point * points, int count)
   15.39  {
   15.40      SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
   15.41 +    SDL_Texture *texture = data->texture[data->current_texture];
   15.42      SDL_Rect rect;
   15.43 -    int status;
   15.44 +    int i;
   15.45 +    int x, y;
   15.46 +    int status = 0;
   15.47  
   15.48 -    rect.x = x;
   15.49 -    rect.y = y;
   15.50 -    rect.w = 1;
   15.51 -    rect.h = 1;
   15.52 -
   15.53 -    if (data->renderer->info.flags & SDL_RENDERER_PRESENTCOPY) {
   15.54 -        SDL_AddDirtyRect(&data->dirty, &rect);
   15.55 -    }
   15.56 -
   15.57 -    if (data->renderer->LockTexture(data->renderer,
   15.58 -                                    data->texture[data->current_texture],
   15.59 -                                    &rect, 1,
   15.60 -                                    &data->surface.pixels,
   15.61 -                                    &data->surface.pitch) < 0) {
   15.62 -        return -1;
   15.63 -    }
   15.64 -
   15.65 -    data->surface.w = 1;
   15.66 -    data->surface.h = 1;
   15.67 -    data->surface.clip_rect.w = 1;
   15.68 -    data->surface.clip_rect.h = 1;
   15.69 -
   15.70 -    if (renderer->blendMode == SDL_BLENDMODE_NONE ||
   15.71 -        renderer->blendMode == SDL_BLENDMODE_MASK) {
   15.72 -        Uint32 color =
   15.73 -            SDL_MapRGBA(data->surface.format, renderer->r, renderer->g,
   15.74 -                        renderer->b, renderer->a);
   15.75 -
   15.76 -        status = SDL_DrawPoint(&data->surface, 0, 0, color);
   15.77 -    } else {
   15.78 -        status =
   15.79 -            SDL_BlendPoint(&data->surface, 0, 0, renderer->blendMode,
   15.80 -                           renderer->r, renderer->g, renderer->b,
   15.81 -                           renderer->a);
   15.82 -    }
   15.83 -
   15.84 -    data->renderer->UnlockTexture(data->renderer,
   15.85 -                                  data->texture[data->current_texture]);
   15.86 -    return status;
   15.87 -}
   15.88 -
   15.89 -static int
   15.90 -SW_RenderLine(SDL_Renderer * renderer, int x1, int y1, int x2, int y2)
   15.91 -{
   15.92 -    SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
   15.93 -    SDL_Rect rect;
   15.94 -    int status;
   15.95 -
   15.96 -    if (x1 < x2) {
   15.97 -        rect.x = x1;
   15.98 -        rect.w = (x2 - x1) + 1;
   15.99 -        x2 -= x1;
  15.100 -        x1 = 0;
  15.101 -    } else {
  15.102 -        rect.x = x2;
  15.103 -        rect.w = (x1 - x2) + 1;
  15.104 -        x1 -= x2;
  15.105 -        x2 = 0;
  15.106 -    }
  15.107 -    if (y1 < y2) {
  15.108 -        rect.y = y1;
  15.109 -        rect.h = (y2 - y1) + 1;
  15.110 -        y2 -= y1;
  15.111 -        y1 = 0;
  15.112 -    } else {
  15.113 -        rect.y = y2;
  15.114 -        rect.h = (y1 - y2) + 1;
  15.115 -        y1 -= y2;
  15.116 -        y2 = 0;
  15.117 +    /* Get the smallest rectangle that contains everything */
  15.118 +    rect.x = 0;
  15.119 +    rect.y = 0;
  15.120 +    rect.w = texture->w;
  15.121 +    rect.h = texture->h;
  15.122 +    if (!SDL_EnclosePoints(points, count, &rect, &rect)) {
  15.123 +        /* Nothing to draw */
  15.124 +        return 0;
  15.125      }
  15.126  
  15.127      if (data->renderer->info.flags & SDL_RENDERER_PRESENTCOPY) {
  15.128          SDL_AddDirtyRect(&data->dirty, &rect);
  15.129      }
  15.130  
  15.131 -    if (data->renderer->LockTexture(data->renderer,
  15.132 -                                    data->texture[data->current_texture],
  15.133 -                                    &rect, 1,
  15.134 +    if (data->renderer->LockTexture(data->renderer, texture, &rect, 1,
  15.135                                      &data->surface.pixels,
  15.136                                      &data->surface.pitch) < 0) {
  15.137          return -1;
  15.138      }
  15.139  
  15.140 -    data->surface.w = rect.w;
  15.141 -    data->surface.h = rect.h;
  15.142 -    data->surface.clip_rect.w = rect.w;
  15.143 -    data->surface.clip_rect.h = rect.h;
  15.144 +    data->surface.clip_rect.w = data->surface.w = rect.w;
  15.145 +    data->surface.clip_rect.h = data->surface.h = rect.h;
  15.146  
  15.147 +    /* Draw the points! */
  15.148      if (renderer->blendMode == SDL_BLENDMODE_NONE ||
  15.149          renderer->blendMode == SDL_BLENDMODE_MASK) {
  15.150 -        Uint32 color =
  15.151 -            SDL_MapRGBA(data->surface.format, renderer->r, renderer->g,
  15.152 -                        renderer->b, renderer->a);
  15.153 +        Uint32 color = SDL_MapRGBA(data->surface.format,
  15.154 +                                   renderer->r, renderer->g, renderer->b,
  15.155 +                                   renderer->a);
  15.156  
  15.157 -        status = SDL_DrawLine(&data->surface, x1, y1, x2, y2, color);
  15.158 +        for (i = 0; i < count; ++i) {
  15.159 +            x = points[i].x - rect.x;
  15.160 +            y = points[i].y - rect.y;
  15.161 +
  15.162 +            status = SDL_DrawPoint(&data->surface, x, y, color);
  15.163 +        }
  15.164      } else {
  15.165 -        status =
  15.166 -            SDL_BlendLine(&data->surface, x1, y1, x2, y2, renderer->blendMode,
  15.167 -                          renderer->r, renderer->g, renderer->b, renderer->a);
  15.168 +        for (i = 0; i < count; ++i) {
  15.169 +            x = points[i].x - rect.x;
  15.170 +            y = points[i].y - rect.y;
  15.171 +
  15.172 +            status = SDL_BlendPoint(&data->surface, x, y,
  15.173 +                                    renderer->blendMode,
  15.174 +                                    renderer->r, renderer->g, renderer->b,
  15.175 +                                    renderer->a);
  15.176 +        }
  15.177      }
  15.178  
  15.179 -    data->renderer->UnlockTexture(data->renderer,
  15.180 -                                  data->texture[data->current_texture]);
  15.181 +    data->renderer->UnlockTexture(data->renderer, texture);
  15.182 +
  15.183      return status;
  15.184  }
  15.185  
  15.186  static int
  15.187 -SW_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect)
  15.188 +SW_RenderLines(SDL_Renderer * renderer, const SDL_Point * points, int count)
  15.189  {
  15.190      SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
  15.191 -    SDL_Rect real_rect;
  15.192 -    int status;
  15.193 +    SDL_Texture *texture = data->texture[data->current_texture];
  15.194 +    SDL_Rect clip, rect;
  15.195 +    int i;
  15.196 +    int x1, y1, x2, y2;
  15.197 +    int status = 0;
  15.198 +
  15.199 +    /* Get the smallest rectangle that contains everything */
  15.200 +    clip.x = 0;
  15.201 +    clip.y = 0;
  15.202 +    clip.w = texture->w;
  15.203 +    clip.h = texture->h;
  15.204 +    SDL_EnclosePoints(points, count, NULL, &rect);
  15.205 +    if (!SDL_IntersectRect(&rect, &clip, &rect)) {
  15.206 +        /* Nothing to draw */
  15.207 +        return 0;
  15.208 +    }
  15.209  
  15.210      if (data->renderer->info.flags & SDL_RENDERER_PRESENTCOPY) {
  15.211 -        SDL_AddDirtyRect(&data->dirty, rect);
  15.212 +        SDL_AddDirtyRect(&data->dirty, &rect);
  15.213      }
  15.214  
  15.215 -    if (data->renderer->LockTexture(data->renderer,
  15.216 -                                    data->texture[data->current_texture],
  15.217 -                                    rect, 1, &data->surface.pixels,
  15.218 +    if (data->renderer->LockTexture(data->renderer, texture, &rect, 1,
  15.219 +                                    &data->surface.pixels,
  15.220                                      &data->surface.pitch) < 0) {
  15.221          return -1;
  15.222      }
  15.223  
  15.224 -    data->surface.w = rect->w;
  15.225 -    data->surface.h = rect->h;
  15.226 -    data->surface.clip_rect.w = rect->w;
  15.227 -    data->surface.clip_rect.h = rect->h;
  15.228 -    real_rect = data->surface.clip_rect;
  15.229 +    data->surface.clip_rect.w = data->surface.w = rect.w;
  15.230 +    data->surface.clip_rect.h = data->surface.h = rect.h;
  15.231  
  15.232 -    if (renderer->blendMode == SDL_BLENDMODE_NONE) {
  15.233 -        Uint32 color =
  15.234 -            SDL_MapRGBA(data->surface.format, renderer->r, renderer->g,
  15.235 -                        renderer->b, renderer->a);
  15.236 +    /* Draw the points! */
  15.237 +    if (renderer->blendMode == SDL_BLENDMODE_NONE ||
  15.238 +        renderer->blendMode == SDL_BLENDMODE_MASK) {
  15.239 +        Uint32 color = SDL_MapRGBA(data->surface.format,
  15.240 +                                   renderer->r, renderer->g, renderer->b,
  15.241 +                                   renderer->a);
  15.242  
  15.243 -        status = SDL_FillRect(&data->surface, &real_rect, color);
  15.244 +        for (i = 1; i < count; ++i) {
  15.245 +            x1 = points[i-1].x - rect.x;
  15.246 +            y1 = points[i-1].y - rect.y;
  15.247 +            x2 = points[i].x - rect.x;
  15.248 +            y2 = points[i].y - rect.y;
  15.249 +
  15.250 +            status = SDL_DrawLine(&data->surface, x1, y1, x2, y2, color);
  15.251 +        }
  15.252      } else {
  15.253 -        status =
  15.254 -            SDL_BlendRect(&data->surface, &real_rect, renderer->blendMode,
  15.255 -                          renderer->r, renderer->g, renderer->b, renderer->a);
  15.256 +        for (i = 1; i < count; ++i) {
  15.257 +            x1 = points[i-1].x - rect.x;
  15.258 +            y1 = points[i-1].y - rect.y;
  15.259 +            x2 = points[i].x - rect.x;
  15.260 +            y2 = points[i].y - rect.y;
  15.261 +
  15.262 +            status = SDL_BlendLine(&data->surface, x1, y1, x2, y2,
  15.263 +                                   renderer->blendMode,
  15.264 +                                   renderer->r, renderer->g, renderer->b,
  15.265 +                                   renderer->a);
  15.266 +        }
  15.267      }
  15.268  
  15.269 -    data->renderer->UnlockTexture(data->renderer,
  15.270 -                                  data->texture[data->current_texture]);
  15.271 +    data->renderer->UnlockTexture(data->renderer, texture);
  15.272 +
  15.273 +    return status;
  15.274 +}
  15.275 +
  15.276 +static int
  15.277 +SW_RenderRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count)
  15.278 +{
  15.279 +    SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
  15.280 +    SDL_Texture *texture = data->texture[data->current_texture];
  15.281 +    SDL_Rect clip, rect;
  15.282 +    Uint32 color = 0;
  15.283 +    int i;
  15.284 +    int status = 0;
  15.285 +
  15.286 +    clip.x = 0;
  15.287 +    clip.y = 0;
  15.288 +    clip.w = texture->w;
  15.289 +    clip.h = texture->h;
  15.290 +
  15.291 +    if (renderer->blendMode == SDL_BLENDMODE_NONE ||
  15.292 +        renderer->blendMode == SDL_BLENDMODE_MASK) {
  15.293 +        color = SDL_MapRGBA(data->surface.format,
  15.294 +                            renderer->r, renderer->g, renderer->b,
  15.295 +                            renderer->a);
  15.296 +    }
  15.297 +
  15.298 +    for (i = 0; i < count; ++i) {
  15.299 +        if (!SDL_IntersectRect(rects[i], &clip, &rect)) {
  15.300 +            /* Nothing to draw */
  15.301 +            continue;
  15.302 +        }
  15.303 +
  15.304 +        if (data->renderer->info.flags & SDL_RENDERER_PRESENTCOPY) {
  15.305 +            SDL_AddDirtyRect(&data->dirty, &rect);
  15.306 +        }
  15.307 +
  15.308 +        if (data->renderer->LockTexture(data->renderer, texture, &rect, 1,
  15.309 +                                        &data->surface.pixels,
  15.310 +                                        &data->surface.pitch) < 0) {
  15.311 +            return -1;
  15.312 +        }
  15.313 +
  15.314 +        data->surface.clip_rect.w = data->surface.w = rect.w;
  15.315 +        data->surface.clip_rect.h = data->surface.h = rect.h;
  15.316 +
  15.317 +        if (renderer->blendMode == SDL_BLENDMODE_NONE ||
  15.318 +            renderer->blendMode == SDL_BLENDMODE_MASK) {
  15.319 +            status = SDL_FillRect(&data->surface, NULL, color);
  15.320 +        } else {
  15.321 +            status = SDL_BlendRect(&data->surface, NULL,
  15.322 +                                   renderer->blendMode,
  15.323 +                                   renderer->r, renderer->g, renderer->b,
  15.324 +                                   renderer->a);
  15.325 +        }
  15.326 +
  15.327 +        data->renderer->UnlockTexture(data->renderer, texture);
  15.328 +    }
  15.329      return status;
  15.330  }
  15.331  
    16.1 --- a/src/video/SDL_sysvideo.h	Mon Dec 07 10:08:24 2009 +0000
    16.2 +++ b/src/video/SDL_sysvideo.h	Wed Dec 09 15:56:56 2009 +0000
    16.3 @@ -90,10 +90,12 @@
    16.4                            int numrects, const SDL_Rect * rects);
    16.5      int (*SetDrawColor) (SDL_Renderer * renderer);
    16.6      int (*SetDrawBlendMode) (SDL_Renderer * renderer);
    16.7 -    int (*RenderPoint) (SDL_Renderer * renderer, int x, int y);
    16.8 -    int (*RenderLine) (SDL_Renderer * renderer, int x1, int y1, int x2,
    16.9 -                       int y2);
   16.10 -    int (*RenderFill) (SDL_Renderer * renderer, const SDL_Rect * rect);
   16.11 +    int (*RenderPoints) (SDL_Renderer * renderer, const SDL_Point * points,
   16.12 +                         int count);
   16.13 +    int (*RenderLines) (SDL_Renderer * renderer, const SDL_Point * points,
   16.14 +                        int count);
   16.15 +    int (*RenderRects) (SDL_Renderer * renderer, const SDL_Rect ** rects,
   16.16 +                        int count);
   16.17      int (*RenderCopy) (SDL_Renderer * renderer, SDL_Texture * texture,
   16.18                         const SDL_Rect * srcrect, const SDL_Rect * dstrect);
   16.19      int (*RenderReadPixels) (SDL_Renderer * renderer, const SDL_Rect * rect,
    17.1 --- a/src/video/SDL_video.c	Mon Dec 07 10:08:24 2009 +0000
    17.2 +++ b/src/video/SDL_video.c	Wed Dec 09 15:56:56 2009 +0000
    17.3 @@ -2485,82 +2485,118 @@
    17.4  int
    17.5  SDL_RenderPoint(int x, int y)
    17.6  {
    17.7 +    SDL_Point point;
    17.8 +
    17.9 +    point.x = x;
   17.10 +    point.y = y;
   17.11 +    return SDL_RenderPoints(&point, 1);
   17.12 +}
   17.13 +
   17.14 +int
   17.15 +SDL_RenderPoints(const SDL_Point * points, int count)
   17.16 +{
   17.17      SDL_Renderer *renderer;
   17.18 -    SDL_Window *window;
   17.19 +
   17.20 +    if (!points) {
   17.21 +        SDL_SetError("SDL_RenderPoints(): Passed NULL points");
   17.22 +        return -1;
   17.23 +    }
   17.24  
   17.25      renderer = SDL_GetCurrentRenderer(SDL_TRUE);
   17.26      if (!renderer) {
   17.27          return -1;
   17.28      }
   17.29 -    if (!renderer->RenderPoint) {
   17.30 +    if (!renderer->RenderPoints) {
   17.31          SDL_Unsupported();
   17.32          return -1;
   17.33      }
   17.34 -    window = SDL_GetWindowFromID(renderer->window);
   17.35 -    if (x < 0 || y < 0 || x >= window->w || y >= window->h) {
   17.36 +    if (count < 1) {
   17.37          return 0;
   17.38      }
   17.39 -    return renderer->RenderPoint(renderer, x, y);
   17.40 +    return renderer->RenderPoints(renderer, points, count);
   17.41  }
   17.42  
   17.43  int
   17.44  SDL_RenderLine(int x1, int y1, int x2, int y2)
   17.45  {
   17.46 +    SDL_Point points[2];
   17.47 +
   17.48 +    points[0].x = x1;
   17.49 +    points[0].y = y1;
   17.50 +    points[1].x = x2;
   17.51 +    points[1].y = y2;
   17.52 +    return SDL_RenderLines(points, 2);
   17.53 +}
   17.54 +
   17.55 +int
   17.56 +SDL_RenderLines(const SDL_Point * points, int count)
   17.57 +{
   17.58      SDL_Renderer *renderer;
   17.59 -    SDL_Window *window;
   17.60 -    SDL_Rect real_rect;
   17.61 -
   17.62 -    if (x1 == x2 && y1 == y2) {
   17.63 -        return SDL_RenderPoint(x1, y1);
   17.64 +
   17.65 +    if (!points) {
   17.66 +        SDL_SetError("SDL_RenderLines(): Passed NULL points");
   17.67 +        return -1;
   17.68      }
   17.69  
   17.70      renderer = SDL_GetCurrentRenderer(SDL_TRUE);
   17.71      if (!renderer) {
   17.72          return -1;
   17.73      }
   17.74 -    if (!renderer->RenderLine) {
   17.75 +    if (!renderer->RenderLines) {
   17.76          SDL_Unsupported();
   17.77          return -1;
   17.78      }
   17.79 -    window = SDL_GetWindowFromID(renderer->window);
   17.80 -
   17.81 -    real_rect.x = 0;
   17.82 -    real_rect.y = 0;
   17.83 -    real_rect.w = window->w;
   17.84 -    real_rect.h = window->h;
   17.85 -    if (!SDL_IntersectRectAndLine(&real_rect, &x1, &y1, &x2, &y2)) {
   17.86 -        return (0);
   17.87 -    }
   17.88 -    return renderer->RenderLine(renderer, x1, y1, x2, y2);
   17.89 +    if (count < 2) {
   17.90 +        return 0;
   17.91 +    }
   17.92 +    return renderer->RenderLines(renderer, points, count);
   17.93  }
   17.94  
   17.95  int
   17.96 -SDL_RenderFill(const SDL_Rect * rect)
   17.97 +SDL_RenderRect(const SDL_Rect * rect)
   17.98 +{
   17.99 +    return SDL_RenderRects(&rect, 1);
  17.100 +}
  17.101 +
  17.102 +int
  17.103 +SDL_RenderRects(const SDL_Rect ** rects, int count)
  17.104  {
  17.105      SDL_Renderer *renderer;
  17.106 -    SDL_Window *window;
  17.107 -    SDL_Rect real_rect;
  17.108 +    int i;
  17.109 +
  17.110 +    if (!rects) {
  17.111 +        SDL_SetError("SDL_RenderRects(): Passed NULL rects");
  17.112 +        return -1;
  17.113 +    }
  17.114  
  17.115      renderer = SDL_GetCurrentRenderer(SDL_TRUE);
  17.116      if (!renderer) {
  17.117          return -1;
  17.118      }
  17.119 -    if (!renderer->RenderFill) {
  17.120 +    if (!renderer->RenderRects) {
  17.121          SDL_Unsupported();
  17.122          return -1;
  17.123      }
  17.124 -    window = SDL_GetWindowFromID(renderer->window);
  17.125 -
  17.126 -    real_rect.x = 0;
  17.127 -    real_rect.y = 0;
  17.128 -    real_rect.w = window->w;
  17.129 -    real_rect.h = window->h;
  17.130 -    if (rect) {
  17.131 -        if (!SDL_IntersectRect(rect, &real_rect, &real_rect)) {
  17.132 -            return 0;
  17.133 +    if (count < 1) {
  17.134 +        return 0;
  17.135 +    }
  17.136 +    /* Check for NULL rect, which means fill entire window */
  17.137 +    for (i = 0; i < count; ++i) {
  17.138 +        if (rects[i] == NULL) {
  17.139 +            SDL_Window *window;
  17.140 +            SDL_Rect full_rect;
  17.141 +            SDL_Rect *rect;
  17.142 +
  17.143 +            window = SDL_GetWindowFromID(renderer->window);
  17.144 +            full_rect.x = 0;
  17.145 +            full_rect.y = 0;
  17.146 +            full_rect.w = window->w;
  17.147 +            full_rect.h = window->h;
  17.148 +            rect = &full_rect;
  17.149 +            return renderer->RenderRects(renderer, &rect, 1);
  17.150          }
  17.151      }
  17.152 -    return renderer->RenderFill(renderer, &real_rect);
  17.153 +    return renderer->RenderRects(renderer, rects, count);
  17.154  }
  17.155  
  17.156  int
    18.1 --- a/src/video/dummy/SDL_nullrender.c	Mon Dec 07 10:08:24 2009 +0000
    18.2 +++ b/src/video/dummy/SDL_nullrender.c	Wed Dec 09 15:56:56 2009 +0000
    18.3 @@ -31,11 +31,12 @@
    18.4  
    18.5  static SDL_Renderer *SDL_DUMMY_CreateRenderer(SDL_Window * window,
    18.6                                                Uint32 flags);
    18.7 -static int SDL_DUMMY_RenderPoint(SDL_Renderer * renderer, int x, int y);
    18.8 -static int SDL_DUMMY_RenderLine(SDL_Renderer * renderer, int x1, int y1,
    18.9 -                                int x2, int y2);
   18.10 -static int SDL_DUMMY_RenderFill(SDL_Renderer * renderer,
   18.11 -                                const SDL_Rect * rect);
   18.12 +static int SDL_DUMMY_RenderPoints(SDL_Renderer * renderer,
   18.13 +                                  const SDL_Point * points, int count);
   18.14 +static int SDL_DUMMY_RenderLines(SDL_Renderer * renderer,
   18.15 +                                 const SDL_Point * points, int count);
   18.16 +static int SDL_DUMMY_RenderRects(SDL_Renderer * renderer,
   18.17 +                                 const SDL_Rect ** rects, int count);
   18.18  static int SDL_DUMMY_RenderCopy(SDL_Renderer * renderer,
   18.19                                  SDL_Texture * texture,
   18.20                                  const SDL_Rect * srcrect,
   18.21 @@ -99,9 +100,9 @@
   18.22      }
   18.23      SDL_zerop(data);
   18.24  
   18.25 -    renderer->RenderPoint = SDL_DUMMY_RenderPoint;
   18.26 -    renderer->RenderLine = SDL_DUMMY_RenderLine;
   18.27 -    renderer->RenderFill = SDL_DUMMY_RenderFill;
   18.28 +    renderer->RenderPoints = SDL_DUMMY_RenderPoints;
   18.29 +    renderer->RenderLines = SDL_DUMMY_RenderLines;
   18.30 +    renderer->RenderRects = SDL_DUMMY_RenderRects;
   18.31      renderer->RenderCopy = SDL_DUMMY_RenderCopy;
   18.32      renderer->RenderReadPixels = SDL_DUMMY_RenderReadPixels;
   18.33      renderer->RenderWritePixels = SDL_DUMMY_RenderWritePixels;
   18.34 @@ -139,72 +140,70 @@
   18.35  }
   18.36  
   18.37  static int
   18.38 -SDL_DUMMY_RenderPoint(SDL_Renderer * renderer, int x, int y)
   18.39 +SDL_DUMMY_RenderPoints(SDL_Renderer * renderer,
   18.40 +                       const SDL_Point * points, int count)
   18.41  {
   18.42      SDL_DUMMY_RenderData *data =
   18.43          (SDL_DUMMY_RenderData *) renderer->driverdata;
   18.44      SDL_Surface *target = data->screens[data->current_screen];
   18.45 -    int status;
   18.46  
   18.47      if (renderer->blendMode == SDL_BLENDMODE_NONE ||
   18.48          renderer->blendMode == SDL_BLENDMODE_MASK) {
   18.49 -        Uint32 color =
   18.50 -            SDL_MapRGBA(target->format, renderer->r, renderer->g, renderer->b,
   18.51 -                        renderer->a);
   18.52 +        Uint32 color = SDL_MapRGBA(target->format,
   18.53 +                                   renderer->r, renderer->g, renderer->b,
   18.54 +                                   renderer->a);
   18.55  
   18.56 -        status = SDL_DrawPoint(target, x, y, color);
   18.57 +        return SDL_DrawPoints(target, points, count, color);
   18.58      } else {
   18.59 -        status =
   18.60 -            SDL_BlendPoint(target, x, y, renderer->blendMode, renderer->r,
   18.61 -                           renderer->g, renderer->b, renderer->a);
   18.62 +        return SDL_BlendPoints(target, points, count, renderer->blendMode,
   18.63 +                               renderer->r, renderer->g, renderer->b,
   18.64 +                               renderer->a);
   18.65      }
   18.66 -    return status;
   18.67  }
   18.68  
   18.69  static int
   18.70 -SDL_DUMMY_RenderLine(SDL_Renderer * renderer, int x1, int y1, int x2, int y2)
   18.71 +SDL_DUMMY_RenderLines(SDL_Renderer * renderer,
   18.72 +                      const SDL_Point * points, int count)
   18.73  {
   18.74      SDL_DUMMY_RenderData *data =
   18.75          (SDL_DUMMY_RenderData *) renderer->driverdata;
   18.76      SDL_Surface *target = data->screens[data->current_screen];
   18.77 -    int status;
   18.78  
   18.79      if (renderer->blendMode == SDL_BLENDMODE_NONE ||
   18.80          renderer->blendMode == SDL_BLENDMODE_MASK) {
   18.81 -        Uint32 color =
   18.82 -            SDL_MapRGBA(target->format, renderer->r, renderer->g, renderer->b,
   18.83 -                        renderer->a);
   18.84 +        Uint32 color = SDL_MapRGBA(target->format,
   18.85 +                                   renderer->r, renderer->g, renderer->b,
   18.86 +                                   renderer->a);
   18.87  
   18.88 -        status = SDL_DrawLine(target, x1, y1, x2, y2, color);
   18.89 +        return SDL_DrawLines(target, points, count, color);
   18.90      } else {
   18.91 -        status =
   18.92 -            SDL_BlendLine(target, x1, y1, x2, y2, renderer->blendMode,
   18.93 -                          renderer->r, renderer->g, renderer->b, renderer->a);
   18.94 +        return SDL_BlendLines(target, points, count, renderer->blendMode,
   18.95 +                              renderer->r, renderer->g, renderer->b,
   18.96 +                              renderer->a);
   18.97      }
   18.98 -    return status;
   18.99  }
  18.100  
  18.101  static int
  18.102 -SDL_DUMMY_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect)
  18.103 +SDL_DUMMY_RenderRects(SDL_Renderer * renderer, const SDL_Rect ** rects,
  18.104 +                      int count)
  18.105  {
  18.106      SDL_DUMMY_RenderData *data =
  18.107          (SDL_DUMMY_RenderData *) renderer->driverdata;
  18.108      SDL_Surface *target = data->screens[data->current_screen];
  18.109 -    SDL_Rect real_rect = *rect;
  18.110 -    int status;
  18.111  
  18.112 -    if (renderer->blendMode == SDL_BLENDMODE_NONE) {
  18.113 -        Uint32 color =
  18.114 -            SDL_MapRGBA(target->format, renderer->r, renderer->g, renderer->b,
  18.115 -                        renderer->a);
  18.116 +    if (renderer->blendMode == SDL_BLENDMODE_NONE ||
  18.117 +        renderer->blendMode == SDL_BLENDMODE_MASK) {
  18.118 +        Uint32 color = SDL_MapRGBA(target->format,
  18.119 +                                   renderer->r, renderer->g, renderer->b,
  18.120 +                                   renderer->a);
  18.121  
  18.122 -        status = SDL_FillRect(target, &real_rect, color);
  18.123 +        return SDL_FillRects(target, rects, count, color);
  18.124      } else {
  18.125 -        status =
  18.126 -            SDL_BlendRect(target, &real_rect, renderer->blendMode,
  18.127 -                          renderer->r, renderer->g, renderer->b, renderer->a);
  18.128 +        return SDL_BlendRects(target, rects, count,
  18.129 +                              renderer->blendMode,
  18.130 +                              renderer->r, renderer->g, renderer->b,
  18.131 +                              renderer->a);
  18.132      }
  18.133 -    return status;
  18.134  }
  18.135  
  18.136  static int
    19.1 --- a/src/video/win32/SDL_d3drender.c	Mon Dec 07 10:08:24 2009 +0000
    19.2 +++ b/src/video/win32/SDL_d3drender.c	Wed Dec 09 15:56:56 2009 +0000
    19.3 @@ -66,10 +66,12 @@
    19.4  static void D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
    19.5  static void D3D_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture,
    19.6                               int numrects, const SDL_Rect * rects);
    19.7 -static int D3D_RenderPoint(SDL_Renderer * renderer, int x, int y);
    19.8 -static int D3D_RenderLine(SDL_Renderer * renderer, int x1, int y1, int x2,
    19.9 -                          int y2);
   19.10 -static int D3D_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect);
   19.11 +static int D3D_RenderPoints(SDL_Renderer * renderer, const SDL_Point * points,
   19.12 +                            int count);
   19.13 +static int D3D_RenderLines(SDL_Renderer * renderer, const SDL_Point * points,
   19.14 +                           int count);
   19.15 +static int D3D_RenderRects(SDL_Renderer * renderer, const SDL_Rect ** rects,
   19.16 +                           int count);
   19.17  static int D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
   19.18                            const SDL_Rect * srcrect, const SDL_Rect * dstrect);
   19.19  static int D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
   19.20 @@ -407,9 +409,9 @@
   19.21      renderer->LockTexture = D3D_LockTexture;
   19.22      renderer->UnlockTexture = D3D_UnlockTexture;
   19.23      renderer->DirtyTexture = D3D_DirtyTexture;
   19.24 -    renderer->RenderPoint = D3D_RenderPoint;
   19.25 -    renderer->RenderLine = D3D_RenderLine;
   19.26 -    renderer->RenderFill = D3D_RenderFill;
   19.27 +    renderer->RenderPoints = D3D_RenderPoints;
   19.28 +    renderer->RenderLines = D3D_RenderLines;
   19.29 +    renderer->RenderRects = D3D_RenderRects;
   19.30      renderer->RenderCopy = D3D_RenderCopy;
   19.31      renderer->RenderReadPixels = D3D_RenderReadPixels;
   19.32      renderer->RenderWritePixels = D3D_RenderWritePixels;
   19.33 @@ -927,11 +929,12 @@
   19.34  }
   19.35  
   19.36  static int
   19.37 -D3D_RenderPoint(SDL_Renderer * renderer, int x, int y)
   19.38 +D3D_RenderPoints(SDL_Renderer * renderer, const SDL_Point * points, int count)
   19.39  {
   19.40      D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
   19.41      DWORD color;
   19.42 -    Vertex vertices[1];
   19.43 +    Vertex *vertices;
   19.44 +    int i;
   19.45      HRESULT result;
   19.46  
   19.47      if (data->beginScene) {
   19.48 @@ -939,16 +942,6 @@
   19.49          data->beginScene = SDL_FALSE;
   19.50      }
   19.51  
   19.52 -    color = D3DCOLOR_ARGB(renderer->a, renderer->r, renderer->g, renderer->b);
   19.53 -
   19.54 -    vertices[0].x = (float) x;
   19.55 -    vertices[0].y = (float) y;
   19.56 -    vertices[0].z = 0.0f;
   19.57 -    vertices[0].rhw = 1.0f;
   19.58 -    vertices[0].color = color;
   19.59 -    vertices[0].u = 0.0f;
   19.60 -    vertices[0].v = 0.0f;
   19.61 -
   19.62      D3D_SetBlendMode(data, renderer->blendMode);
   19.63  
   19.64      result =
   19.65 @@ -958,9 +951,23 @@
   19.66          D3D_SetError("SetTexture()", result);
   19.67          return -1;
   19.68      }
   19.69 +
   19.70 +    color = D3DCOLOR_ARGB(renderer->a, renderer->r, renderer->g, renderer->b);
   19.71 +
   19.72 +    vertices = SDL_stack_alloc(Vertex, count);
   19.73 +    for (i = 0; i < count; ++i) {
   19.74 +        vertices[i].x = (float) points[i].x;
   19.75 +        vertices[i].y = (float) points[i].y;
   19.76 +        vertices[i].z = 0.0f;
   19.77 +        vertices[i].rhw = 1.0f;
   19.78 +        vertices[i].color = color;
   19.79 +        vertices[i].u = 0.0f;
   19.80 +        vertices[i].v = 0.0f;
   19.81 +    }
   19.82      result =
   19.83 -        IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_POINTLIST, 1,
   19.84 +        IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_POINTLIST, count,
   19.85                                           vertices, sizeof(*vertices));
   19.86 +    SDL_stack_free(vertices);
   19.87      if (FAILED(result)) {
   19.88          D3D_SetError("DrawPrimitiveUP()", result);
   19.89          return -1;
   19.90 @@ -969,11 +976,12 @@
   19.91  }
   19.92  
   19.93  static int
   19.94 -D3D_RenderLine(SDL_Renderer * renderer, int x1, int y1, int x2, int y2)
   19.95 +D3D_RenderLines(SDL_Renderer * renderer, const SDL_Point * points, int count)
   19.96  {
   19.97      D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
   19.98      DWORD color;
   19.99 -    Vertex vertices[2];
  19.100 +    Vertex *vertices;
  19.101 +    int i;
  19.102      HRESULT result;
  19.103  
  19.104      if (data->beginScene) {
  19.105 @@ -981,24 +989,6 @@
  19.106          data->beginScene = SDL_FALSE;
  19.107      }
  19.108  
  19.109 -    color = D3DCOLOR_ARGB(renderer->a, renderer->r, renderer->g, renderer->b);
  19.110 -
  19.111 -    vertices[0].x = (float) x1;
  19.112 -    vertices[0].y = (float) y1;
  19.113 -    vertices[0].z = 0.0f;
  19.114 -    vertices[0].rhw = 1.0f;
  19.115 -    vertices[0].color = color;
  19.116 -    vertices[0].u = 0.0f;
  19.117 -    vertices[0].v = 0.0f;
  19.118 -
  19.119 -    vertices[1].x = (float) x2;
  19.120 -    vertices[1].y = (float) y2;
  19.121 -    vertices[1].z = 0.0f;
  19.122 -    vertices[1].rhw = 1.0f;
  19.123 -    vertices[1].color = color;
  19.124 -    vertices[1].u = 0.0f;
  19.125 -    vertices[1].v = 0.0f;
  19.126 -
  19.127      D3D_SetBlendMode(data, renderer->blendMode);
  19.128  
  19.129      result =
  19.130 @@ -1008,9 +998,23 @@
  19.131          D3D_SetError("SetTexture()", result);
  19.132          return -1;
  19.133      }
  19.134 +
  19.135 +    color = D3DCOLOR_ARGB(renderer->a, renderer->r, renderer->g, renderer->b);
  19.136 +
  19.137 +    vertices = SDL_stack_alloc(Vertex, count);
  19.138 +    for (i = 0; i < count; ++i) {
  19.139 +        vertices[i].x = (float) points[i].x;
  19.140 +        vertices[i].y = (float) points[i].y;
  19.141 +        vertices[i].z = 0.0f;
  19.142 +        vertices[i].rhw = 1.0f;
  19.143 +        vertices[i].color = color;
  19.144 +        vertices[i].u = 0.0f;
  19.145 +        vertices[i].v = 0.0f;
  19.146 +    }
  19.147      result =
  19.148 -        IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_LINELIST, 1,
  19.149 +        IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_LINESTRIP, count,
  19.150                                           vertices, sizeof(*vertices));
  19.151 +    SDL_stack_free(vertices);
  19.152      if (FAILED(result)) {
  19.153          D3D_SetError("DrawPrimitiveUP()", result);
  19.154          return -1;
  19.155 @@ -1019,11 +1023,12 @@
  19.156  }
  19.157  
  19.158  static int
  19.159 -D3D_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect)
  19.160 +D3D_RenderRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count)
  19.161  {
  19.162      D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
  19.163 +    DWORD color;
  19.164 +    int i;
  19.165      float minx, miny, maxx, maxy;
  19.166 -    DWORD color;
  19.167      Vertex vertices[4];
  19.168      HRESULT result;
  19.169  
  19.170 @@ -1032,45 +1037,6 @@
  19.171          data->beginScene = SDL_FALSE;
  19.172      }
  19.173  
  19.174 -    minx = (float) rect->x;
  19.175 -    miny = (float) rect->y;
  19.176 -    maxx = (float) rect->x + rect->w;
  19.177 -    maxy = (float) rect->y + rect->h;
  19.178 -
  19.179 -    color = D3DCOLOR_ARGB(renderer->a, renderer->r, renderer->g, renderer->b);
  19.180 -
  19.181 -    vertices[0].x = minx;
  19.182 -    vertices[0].y = miny;
  19.183 -    vertices[0].z = 0.0f;
  19.184 -    vertices[0].rhw = 1.0f;
  19.185 -    vertices[0].color = color;
  19.186 -    vertices[0].u = 0.0f;
  19.187 -    vertices[0].v = 0.0f;
  19.188 -
  19.189 -    vertices[1].x = maxx;
  19.190 -    vertices[1].y = miny;
  19.191 -    vertices[1].z = 0.0f;
  19.192 -    vertices[1].rhw = 1.0f;
  19.193 -    vertices[1].color = color;
  19.194 -    vertices[1].u = 0.0f;
  19.195 -    vertices[1].v = 0.0f;
  19.196 -
  19.197 -    vertices[2].x = maxx;
  19.198 -    vertices[2].y = maxy;
  19.199 -    vertices[2].z = 0.0f;
  19.200 -    vertices[2].rhw = 1.0f;
  19.201 -    vertices[2].color = color;
  19.202 -    vertices[2].u = 0.0f;
  19.203 -    vertices[2].v = 0.0f;
  19.204 -
  19.205 -    vertices[3].x = minx;
  19.206 -    vertices[3].y = maxy;
  19.207 -    vertices[3].z = 0.0f;
  19.208 -    vertices[3].rhw = 1.0f;
  19.209 -    vertices[3].color = color;
  19.210 -    vertices[3].u = 0.0f;
  19.211 -    vertices[3].v = 0.0f;
  19.212 -
  19.213      D3D_SetBlendMode(data, renderer->blendMode);
  19.214  
  19.215      result =
  19.216 @@ -1080,12 +1046,56 @@
  19.217          D3D_SetError("SetTexture()", result);
  19.218          return -1;
  19.219      }
  19.220 -    result =
  19.221 -        IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_TRIANGLEFAN, 2,
  19.222 -                                         vertices, sizeof(*vertices));
  19.223 -    if (FAILED(result)) {
  19.224 -        D3D_SetError("DrawPrimitiveUP()", result);
  19.225 -        return -1;
  19.226 +
  19.227 +    color = D3DCOLOR_ARGB(renderer->a, renderer->r, renderer->g, renderer->b);
  19.228 +
  19.229 +    for (i = 0; i < count; ++i) {
  19.230 +        const SDL_Rect *rect = rects[i];
  19.231 +
  19.232 +        minx = (float) rect->x;
  19.233 +        miny = (float) rect->y;
  19.234 +        maxx = (float) rect->x + rect->w;
  19.235 +        maxy = (float) rect->y + rect->h;
  19.236 +
  19.237 +        vertices[0].x = minx;
  19.238 +        vertices[0].y = miny;
  19.239 +        vertices[0].z = 0.0f;
  19.240 +        vertices[0].rhw = 1.0f;
  19.241 +        vertices[0].color = color;
  19.242 +        vertices[0].u = 0.0f;
  19.243 +        vertices[0].v = 0.0f;
  19.244 +
  19.245 +        vertices[1].x = maxx;
  19.246 +        vertices[1].y = miny;
  19.247 +        vertices[1].z = 0.0f;
  19.248 +        vertices[1].rhw = 1.0f;
  19.249 +        vertices[1].color = color;
  19.250 +        vertices[1].u = 0.0f;
  19.251 +        vertices[1].v = 0.0f;
  19.252 +
  19.253 +        vertices[2].x = maxx;
  19.254 +        vertices[2].y = maxy;
  19.255 +        vertices[2].z = 0.0f;
  19.256 +        vertices[2].rhw = 1.0f;
  19.257 +        vertices[2].color = color;
  19.258 +        vertices[2].u = 0.0f;
  19.259 +        vertices[2].v = 0.0f;
  19.260 +
  19.261 +        vertices[3].x = minx;
  19.262 +        vertices[3].y = maxy;
  19.263 +        vertices[3].z = 0.0f;
  19.264 +        vertices[3].rhw = 1.0f;
  19.265 +        vertices[3].color = color;
  19.266 +        vertices[3].u = 0.0f;
  19.267 +        vertices[3].v = 0.0f;
  19.268 +
  19.269 +        result =
  19.270 +            IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_TRIANGLEFAN,
  19.271 +                                             2, vertices, sizeof(*vertices));
  19.272 +        if (FAILED(result)) {
  19.273 +            D3D_SetError("DrawPrimitiveUP()", result);
  19.274 +            return -1;
  19.275 +        }
  19.276      }
  19.277      return 0;
  19.278  }
    20.1 --- a/src/video/win32/SDL_gdirender.c	Mon Dec 07 10:08:24 2009 +0000
    20.2 +++ b/src/video/win32/SDL_gdirender.c	Wed Dec 09 15:56:56 2009 +0000
    20.3 @@ -61,10 +61,12 @@
    20.4                             void **pixels, int *pitch);
    20.5  static void GDI_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
    20.6  static int GDI_SetDrawBlendMode(SDL_Renderer * renderer);
    20.7 -static int GDI_RenderPoint(SDL_Renderer * renderer, int x, int y);
    20.8 -static int GDI_RenderLine(SDL_Renderer * renderer, int x1, int y1, int x2,
    20.9 -                          int y2);
   20.10 -static int GDI_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect);
   20.11 +static int GDI_RenderPoints(SDL_Renderer * renderer, const SDL_Point * points,
   20.12 +                            int count);
   20.13 +static int GDI_RenderLines(SDL_Renderer * renderer, const SDL_Point * points,
   20.14 +                           int count);
   20.15 +static int GDI_RenderRects(SDL_Renderer * renderer, const SDL_Rect ** rects,
   20.16 +                           int count);
   20.17  static int GDI_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
   20.18                            const SDL_Rect * srcrect, const SDL_Rect * dstrect);
   20.19  static int GDI_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
   20.20 @@ -192,9 +194,9 @@
   20.21      renderer->LockTexture = GDI_LockTexture;
   20.22      renderer->UnlockTexture = GDI_UnlockTexture;
   20.23      renderer->SetDrawBlendMode = GDI_SetDrawBlendMode;
   20.24 -    renderer->RenderPoint = GDI_RenderPoint;
   20.25 -    renderer->RenderLine = GDI_RenderLine;
   20.26 -    renderer->RenderFill = GDI_RenderFill;
   20.27 +    renderer->RenderPoints = GDI_RenderPoints;
   20.28 +    renderer->RenderLines = GDI_RenderLines;
   20.29 +    renderer->RenderRects = GDI_RenderRects;
   20.30      renderer->RenderCopy = GDI_RenderCopy;
   20.31      renderer->RenderReadPixels = GDI_RenderReadPixels;
   20.32      renderer->RenderWritePixels = GDI_RenderWritePixels;
   20.33 @@ -685,96 +687,128 @@
   20.34  }
   20.35  
   20.36  static int
   20.37 -GDI_RenderPoint(SDL_Renderer * renderer, int x, int y)
   20.38 +GDI_RenderPoints(SDL_Renderer * renderer, const SDL_Point * points, int count)
   20.39  {
   20.40      GDI_RenderData *data = (GDI_RenderData *) renderer->driverdata;
   20.41 +    int i;
   20.42 +    COLORREF color;
   20.43  
   20.44      if (data->makedirty) {
   20.45 +        /* Get the smallest rectangle that contains everything */
   20.46 +        SDL_Window *window = SDL_GetWindowFromID(renderer->window);
   20.47          SDL_Rect rect;
   20.48  
   20.49 -        rect.x = x;
   20.50 -        rect.y = y;
   20.51 -        rect.w = 1;
   20.52 -        rect.h = 1;
   20.53 +        rect.x = 0;
   20.54 +        rect.y = 0;
   20.55 +        rect.w = window->w;
   20.56 +        rect.h = window->h;
   20.57 +        if (!SDL_EnclosePoints(points, count, &rect, &rect)) {
   20.58 +            /* Nothing to draw */
   20.59 +            return 0;
   20.60 +        }
   20.61  
   20.62          SDL_AddDirtyRect(&data->dirty, &rect);
   20.63      }
   20.64  
   20.65 -    SetPixel(data->current_hdc, x, y,
   20.66 -             RGB(renderer->r, renderer->g, renderer->b));
   20.67 +    color = RGB(renderer->r, renderer->g, renderer->b);
   20.68 +    for (i = 0; i < count; ++i) {
   20.69 +        SetPixel(data->current_hdc, points[i].x, points[i].y, color);
   20.70 +    }
   20.71 +
   20.72      return 0;
   20.73  }
   20.74  
   20.75  static int
   20.76 -GDI_RenderLine(SDL_Renderer * renderer, int x1, int y1, int x2, int y2)
   20.77 +GDI_RenderLines(SDL_Renderer * renderer, const SDL_Point * points, int count)
   20.78  {
   20.79      GDI_RenderData *data = (GDI_RenderData *) renderer->driverdata;
   20.80 -    POINT points[2];
   20.81      HPEN pen;
   20.82      BOOL status;
   20.83  
   20.84      if (data->makedirty) {
   20.85 -        SDL_Rect rect;
   20.86 +        /* Get the smallest rectangle that contains everything */
   20.87 +        SDL_Window *window = SDL_GetWindowFromID(renderer->window);
   20.88 +        SDL_Rect clip, rect;
   20.89  
   20.90 -        if (x1 < x2) {
   20.91 -            rect.x = x1;
   20.92 -            rect.w = (x2 - x1) + 1;
   20.93 -        } else {
   20.94 -            rect.x = x2;
   20.95 -            rect.w = (x1 - x2) + 1;
   20.96 +        clip.x = 0;
   20.97 +        clip.y = 0;
   20.98 +        clip.w = window->w;
   20.99 +        clip.h = window->h;
  20.100 +        SDL_EnclosePoints(points, count, NULL, &rect);
  20.101 +        if (!SDL_IntersectRect(&rect, &clip, &rect)) {
  20.102 +            /* Nothing to draw */
  20.103 +            return 0;
  20.104          }
  20.105 -        if (y1 < y2) {
  20.106 -            rect.y = y1;
  20.107 -            rect.h = (y2 - y1) + 1;
  20.108 -        } else {
  20.109 -            rect.y = y2;
  20.110 -            rect.h = (y1 - y2) + 1;
  20.111 -        }
  20.112 +
  20.113          SDL_AddDirtyRect(&data->dirty, &rect);
  20.114      }
  20.115  
  20.116      /* Should we cache the pen? .. it looks like GDI does for us. :) */
  20.117      pen = CreatePen(PS_SOLID, 1, RGB(renderer->r, renderer->g, renderer->b));
  20.118      SelectObject(data->current_hdc, pen);
  20.119 -    points[0].x = x1;
  20.120 -    points[0].y = y1;
  20.121 -    points[1].x = x2;
  20.122 -    points[1].y = y2;
  20.123 -    status = Polyline(data->current_hdc, points, 2);
  20.124 +    {
  20.125 +        LPPOINT p = SDL_stack_alloc(POINT, count);
  20.126 +        int i;
  20.127 +
  20.128 +        for (i = 0; i < count; ++i) {
  20.129 +            p[i].x = points[i].x;
  20.130 +            p[i].y = points[i].y;
  20.131 +        }
  20.132 +        status = Polyline(data->current_hdc, p, count);
  20.133 +        SDL_stack_free(p);
  20.134 +    }
  20.135      DeleteObject(pen);
  20.136  
  20.137      /* Need to close the endpoint of the line */
  20.138 -    SetPixel(data->current_hdc, x2, y2,
  20.139 -             RGB(renderer->r, renderer->g, renderer->b));
  20.140 +    if (points[0].x != points[count-1].x || points[0].y != points[count-1].y) {
  20.141 +        SetPixel(data->current_hdc, points[count-1].x, points[count-1].y,
  20.142 +                 RGB(renderer->r, renderer->g, renderer->b));
  20.143 +    }
  20.144  
  20.145      if (!status) {
  20.146 -        WIN_SetError("FillRect()");
  20.147 +        WIN_SetError("Polyline()");
  20.148          return -1;
  20.149      }
  20.150      return 0;
  20.151  }
  20.152  
  20.153  static int
  20.154 -GDI_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect)
  20.155 +GDI_RenderRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count)
  20.156  {
  20.157      GDI_RenderData *data = (GDI_RenderData *) renderer->driverdata;
  20.158      RECT rc;
  20.159      HBRUSH brush;
  20.160 -    int status;
  20.161 +    int i, status = 1;
  20.162  
  20.163      if (data->makedirty) {
  20.164 -        SDL_AddDirtyRect(&data->dirty, rect);
  20.165 +        SDL_Window *window = SDL_GetWindowFromID(renderer->window);
  20.166 +        SDL_Rect clip, rect;
  20.167 +
  20.168 +        clip.x = 0;
  20.169 +        clip.y = 0;
  20.170 +        clip.w = window->w;
  20.171 +        clip.h = window->h;
  20.172 +
  20.173 +        for (i = 0; i < count; ++i) {
  20.174 +            if (SDL_IntersectRect(rects[i], &clip, &rect)) {
  20.175 +                SDL_AddDirtyRect(&data->dirty, &rect);
  20.176 +            }
  20.177 +        }
  20.178      }
  20.179  
  20.180 -    rc.left = rect->x;
  20.181 -    rc.top = rect->y;
  20.182 -    rc.right = rect->x + rect->w;
  20.183 -    rc.bottom = rect->y + rect->h;
  20.184 -
  20.185      /* Should we cache the brushes? .. it looks like GDI does for us. :) */
  20.186      brush = CreateSolidBrush(RGB(renderer->r, renderer->g, renderer->b));
  20.187      SelectObject(data->current_hdc, brush);
  20.188 -    status = FillRect(data->current_hdc, &rc, brush);
  20.189 +    for (i = 0; i < count; ++i) {
  20.190 +        const SDL_Rect *rect = rects[i];
  20.191 +
  20.192 +        rc.left = rect->x;
  20.193 +        rc.top = rect->y;
  20.194 +        rc.right = rect->x + rect->w;
  20.195 +        rc.bottom = rect->y + rect->h;
  20.196 +
  20.197 +        status &= FillRect(data->current_hdc, &rc, brush);
  20.198 +    }
  20.199      DeleteObject(brush);
  20.200  
  20.201      if (!status) {
    21.1 --- a/test/automated/render/render.c	Mon Dec 07 10:08:24 2009 +0000
    21.2 +++ b/test/automated/render/render.c	Wed Dec 09 15:56:56 2009 +0000
    21.3 @@ -340,9 +340,9 @@
    21.4     */
    21.5  
    21.6     /* Clear screen. */
    21.7 -   ret = SDL_RenderFill( NULL );
    21.8 +   ret = SDL_RenderRect( NULL );
    21.9     /*
   21.10 -   if (SDL_ATassert( "SDL_RenderFill", ret == 0))
   21.11 +   if (SDL_ATassert( "SDL_RenderRect", ret == 0))
   21.12        return -1;
   21.13     */
   21.14  
   21.15 @@ -387,7 +387,7 @@
   21.16     ret = SDL_SetRenderDrawColor( 13, 73, 200, SDL_ALPHA_OPAQUE );
   21.17     if (SDL_ATassert( "SDL_SetRenderDrawColor", ret == 0))
   21.18        return -1;
   21.19 -   ret = SDL_RenderFill( &rect );
   21.20 +   ret = SDL_RenderRect( &rect );
   21.21     if (SDL_ATassert( "SDL_RenderRect", ret == 0))
   21.22        return -1;
   21.23  
   21.24 @@ -399,7 +399,7 @@
   21.25     ret = SDL_SetRenderDrawColor( 200, 0, 100, SDL_ALPHA_OPAQUE );
   21.26     if (SDL_ATassert( "SDL_SetRenderDrawColor", ret == 0))
   21.27        return -1;
   21.28 -   ret = SDL_RenderFill( &rect );
   21.29 +   ret = SDL_RenderRect( &rect );
   21.30     if (SDL_ATassert( "SDL_RenderRect", ret == 0))
   21.31        return -1;
   21.32  
   21.33 @@ -480,8 +480,8 @@
   21.34     ret = SDL_SetRenderDrawBlendMode( SDL_BLENDMODE_NONE );
   21.35     if (SDL_ATassert( "SDL_SetRenderDrawBlendMode", ret == 0))
   21.36        return -1;
   21.37 -   ret = SDL_RenderFill( NULL );
   21.38 -   if (SDL_ATassert( "SDL_RenderFill", ret == 0))
   21.39 +   ret = SDL_RenderRect( NULL );
   21.40 +   if (SDL_ATassert( "SDL_RenderRect", ret == 0))
   21.41        return -1;
   21.42     rect.x = 10;
   21.43     rect.y = 25;
   21.44 @@ -493,8 +493,8 @@
   21.45     ret = SDL_SetRenderDrawBlendMode( SDL_BLENDMODE_ADD );
   21.46     if (SDL_ATassert( "SDL_SetRenderDrawBlendMode", ret == 0))
   21.47        return -1;
   21.48 -   ret = SDL_RenderFill( &rect );
   21.49 -   if (SDL_ATassert( "SDL_RenderFill", ret == 0))
   21.50 +   ret = SDL_RenderRect( &rect );
   21.51 +   if (SDL_ATassert( "SDL_RenderRect", ret == 0))
   21.52        return -1;
   21.53     rect.x = 30;
   21.54     rect.y = 40;
   21.55 @@ -506,8 +506,8 @@
   21.56     ret = SDL_SetRenderDrawBlendMode( SDL_BLENDMODE_BLEND );
   21.57     if (SDL_ATassert( "SDL_SetRenderDrawBlendMode", ret == 0))
   21.58        return -1;
   21.59 -   ret = SDL_RenderFill( &rect );
   21.60 -   if (SDL_ATassert( "SDL_RenderFill", ret == 0))
   21.61 +   ret = SDL_RenderRect( &rect );
   21.62 +   if (SDL_ATassert( "SDL_RenderRect", ret == 0))
   21.63        return -1;
   21.64     rect.x = 25;
   21.65     rect.y = 25;
   21.66 @@ -519,8 +519,8 @@
   21.67     ret = SDL_SetRenderDrawBlendMode( SDL_BLENDMODE_MOD );
   21.68     if (SDL_ATassert( "SDL_SetRenderDrawBlendMode", ret == 0))
   21.69        return -1;
   21.70 -   ret = SDL_RenderFill( &rect );
   21.71 -   if (SDL_ATassert( "SDL_RenderFill", ret == 0))
   21.72 +   ret = SDL_RenderRect( &rect );
   21.73 +   if (SDL_ATassert( "SDL_RenderRect", ret == 0))
   21.74        return -1;
   21.75  
   21.76     /* Draw blended lines, lines for everyone. */
    22.1 --- a/test/testdraw2.c	Mon Dec 07 10:08:24 2009 +0000
    22.2 +++ b/test/testdraw2.c	Wed Dec 09 15:56:56 2009 +0000
    22.3 @@ -159,7 +159,7 @@
    22.4          rect.h = rand() % (window_h / 2);
    22.5          rect.x = (rand() % window_w) - (rect.w / 2);
    22.6          rect.y = (rand() % window_w) - (rect.h / 2);
    22.7 -        SDL_RenderFill(&rect);
    22.8 +        SDL_RenderRect(&rect);
    22.9      }
   22.10      SDL_SetRenderDrawBlendMode(SDL_BLENDMODE_NONE);
   22.11  }
   22.12 @@ -231,7 +231,7 @@
   22.13      for (i = 0; i < state->num_windows; ++i) {
   22.14          SDL_SelectRenderer(state->windows[i]);
   22.15          SDL_SetRenderDrawColor(0xA0, 0xA0, 0xA0, 0xFF);
   22.16 -        SDL_RenderFill(NULL);
   22.17 +        SDL_RenderRect(NULL);
   22.18      }
   22.19  
   22.20      srand(time(NULL));
   22.21 @@ -251,7 +251,7 @@
   22.22                  case SDL_WINDOWEVENT_EXPOSED:
   22.23                      SDL_SelectRenderer(event.window.windowID);
   22.24                      SDL_SetRenderDrawColor(0xA0, 0xA0, 0xA0, 0xFF);
   22.25 -                    SDL_RenderFill(NULL);
   22.26 +                    SDL_RenderRect(NULL);
   22.27                      break;
   22.28                  }
   22.29                  break;
   22.30 @@ -262,7 +262,7 @@
   22.31          for (i = 0; i < state->num_windows; ++i) {
   22.32              SDL_SelectRenderer(state->windows[i]);
   22.33              SDL_SetRenderDrawColor(0xA0, 0xA0, 0xA0, 0xFF);
   22.34 -            SDL_RenderFill(NULL);
   22.35 +            SDL_RenderRect(NULL);
   22.36  
   22.37              DrawRects(state->windows[i]);
   22.38              DrawLines(state->windows[i]);
    23.1 --- a/test/testintersections.c	Mon Dec 07 10:08:24 2009 +0000
    23.2 +++ b/test/testintersections.c	Wed Dec 09 15:56:56 2009 +0000
    23.3 @@ -150,7 +150,7 @@
    23.4      SDL_SetRenderDrawBlendMode(SDL_BLENDMODE_NONE);
    23.5      for (i = 0; i < num_rects; ++i) {
    23.6          SDL_SetRenderDrawColor(255, 127, 0, 255);
    23.7 -        SDL_RenderFill(&rects[i]);
    23.8 +        SDL_RenderRect(&rects[i]);
    23.9      }
   23.10      SDL_SetRenderDrawBlendMode(SDL_BLENDMODE_NONE);
   23.11  }
   23.12 @@ -197,7 +197,7 @@
   23.13              SDL_Rect r;
   23.14              if (SDL_IntersectRect(&rects[i], &rects[j], &r)) {
   23.15                  SDL_SetRenderDrawColor(255, 200, 0, 255);
   23.16 -                SDL_RenderFill(&r);
   23.17 +                SDL_RenderRect(&r);
   23.18              }
   23.19          }
   23.20  
   23.21 @@ -272,7 +272,7 @@
   23.22      for (i = 0; i < state->num_windows; ++i) {
   23.23          SDL_SelectRenderer(state->windows[i]);
   23.24          SDL_SetRenderDrawColor(0xA0, 0xA0, 0xA0, 0xFF);
   23.25 -        SDL_RenderFill(NULL);
   23.26 +        SDL_RenderRect(NULL);
   23.27      }
   23.28  
   23.29      srand(time(NULL));
   23.30 @@ -326,7 +326,7 @@
   23.31                  case SDL_WINDOWEVENT_EXPOSED:
   23.32                      SDL_SelectRenderer(event.window.windowID);
   23.33                      SDL_SetRenderDrawColor(0xA0, 0xA0, 0xA0, 0xFF);
   23.34 -                    SDL_RenderFill(NULL);
   23.35 +                    SDL_RenderRect(NULL);
   23.36                      break;
   23.37                  }
   23.38                  break;
   23.39 @@ -337,7 +337,7 @@
   23.40          for (i = 0; i < state->num_windows; ++i) {
   23.41              SDL_SelectRenderer(state->windows[i]);
   23.42              SDL_SetRenderDrawColor(0xA0, 0xA0, 0xA0, 0xFF);
   23.43 -            SDL_RenderFill(NULL);
   23.44 +            SDL_RenderRect(NULL);
   23.45  
   23.46              DrawRects(state->windows[i]);
   23.47              DrawPoints(state->windows[i]);
    24.1 --- a/test/testnative.c	Mon Dec 07 10:08:24 2009 +0000
    24.2 +++ b/test/testnative.c	Wed Dec 09 15:56:56 2009 +0000
    24.3 @@ -83,7 +83,7 @@
    24.4      /* Move the sprite, bounce at the wall, and draw */
    24.5      n = 0;
    24.6      SDL_SetRenderDrawColor(0xA0, 0xA0, 0xA0, 0xFF);
    24.7 -    SDL_RenderFill(NULL);
    24.8 +    SDL_RenderRect(NULL);
    24.9      for (i = 0; i < NUM_SPRITES; ++i) {
   24.10          position = &positions[i];
   24.11          velocity = &velocities[i];
   24.12 @@ -158,7 +158,7 @@
   24.13      /* Clear the window, load the sprite and go! */
   24.14      SDL_SelectRenderer(window);
   24.15      SDL_SetRenderDrawColor(0xA0, 0xA0, 0xA0, 0xFF);
   24.16 -    SDL_RenderFill(NULL);
   24.17 +    SDL_RenderRect(NULL);
   24.18  
   24.19      sprite = LoadSprite(window, "icon.bmp");
   24.20      if (!sprite) {
   24.21 @@ -199,7 +199,7 @@
   24.22                  case SDL_WINDOWEVENT_EXPOSED:
   24.23                      SDL_SelectRenderer(event.window.windowID);
   24.24                      SDL_SetRenderDrawColor(0xA0, 0xA0, 0xA0, 0xFF);
   24.25 -                    SDL_RenderFill(NULL);
   24.26 +                    SDL_RenderRect(NULL);
   24.27                      break;
   24.28                  }
   24.29                  break;
    25.1 --- a/test/testsprite2.c	Mon Dec 07 10:08:24 2009 +0000
    25.2 +++ b/test/testsprite2.c	Wed Dec 09 15:56:56 2009 +0000
    25.3 @@ -141,7 +141,7 @@
    25.4  
    25.5      /* Draw a gray background */
    25.6      SDL_SetRenderDrawColor(0xA0, 0xA0, 0xA0, 0xFF);
    25.7 -    SDL_RenderFill(NULL);
    25.8 +    SDL_RenderRect(NULL);
    25.9  
   25.10      /* Test points */
   25.11      SDL_SetRenderDrawColor(0xFF, 0x00, 0x00, 0xFF);
   25.12 @@ -163,25 +163,25 @@
   25.13      temp.y = 1;
   25.14      temp.w = sprite_w;
   25.15      temp.h = sprite_h;
   25.16 -    SDL_RenderFill(&temp);
   25.17 +    SDL_RenderRect(&temp);
   25.18      SDL_RenderCopy(sprite, NULL, &temp);
   25.19      temp.x = window_w-sprite_w-1;
   25.20      temp.y = 1;
   25.21      temp.w = sprite_w;
   25.22      temp.h = sprite_h;
   25.23 -    SDL_RenderFill(&temp);
   25.24 +    SDL_RenderRect(&temp);
   25.25      SDL_RenderCopy(sprite, NULL, &temp);
   25.26      temp.x = 1;
   25.27      temp.y = window_h-sprite_h-1;
   25.28      temp.w = sprite_w;
   25.29      temp.h = sprite_h;
   25.30 -    SDL_RenderFill(&temp);
   25.31 +    SDL_RenderRect(&temp);
   25.32      SDL_RenderCopy(sprite, NULL, &temp);
   25.33      temp.x = window_w-sprite_w-1;
   25.34      temp.y = window_h-sprite_h-1;
   25.35      temp.w = sprite_w;
   25.36      temp.h = sprite_h;
   25.37 -    SDL_RenderFill(&temp);
   25.38 +    SDL_RenderRect(&temp);
   25.39      SDL_RenderCopy(sprite, NULL, &temp);
   25.40  
   25.41      /* Test diagonal lines */
   25.42 @@ -304,7 +304,7 @@
   25.43      for (i = 0; i < state->num_windows; ++i) {
   25.44          SDL_SelectRenderer(state->windows[i]);
   25.45          SDL_SetRenderDrawColor(0xA0, 0xA0, 0xA0, 0xFF);
   25.46 -        SDL_RenderFill(NULL);
   25.47 +        SDL_RenderRect(NULL);
   25.48      }
   25.49      if (LoadSprite("icon.bmp") < 0) {
   25.50          quit(2);
   25.51 @@ -350,7 +350,7 @@
   25.52                  case SDL_WINDOWEVENT_EXPOSED:
   25.53                      SDL_SelectRenderer(event.window.windowID);
   25.54                      SDL_SetRenderDrawColor(0xA0, 0xA0, 0xA0, 0xFF);
   25.55 -                    SDL_RenderFill(NULL);
   25.56 +                    SDL_RenderRect(NULL);
   25.57                      break;
   25.58                  }
   25.59                  break;
    26.1 --- a/test/testspriteminimal.c	Mon Dec 07 10:08:24 2009 +0000
    26.2 +++ b/test/testspriteminimal.c	Wed Dec 09 15:56:56 2009 +0000
    26.3 @@ -87,7 +87,7 @@
    26.4  
    26.5      /* Draw a gray background */
    26.6      SDL_SetRenderDrawColor(0xA0, 0xA0, 0xA0, 0xFF);
    26.7 -    SDL_RenderFill(NULL);
    26.8 +    SDL_RenderRect(NULL);
    26.9  
   26.10      /* Move the sprite, bounce at the wall, and draw */
   26.11      for (i = 0; i < NUM_SPRITES; ++i) {