src/render/software/SDL_drawline.c
author Ryan C. Gordon
Sun, 31 Mar 2013 12:48:50 -0400
changeset 7037 3fedf1f25b94
parent 6885 700f1b25f77f
child 7191 75360622e65f
permissions -rw-r--r--
Make SDL_SetError and friends unconditionally return -1.

This lets us change things like this...

if (Failed) {
SDL_SetError("We failed");
return -1;
}

...into this...

if (Failed) {
return SDL_SetError("We failed");
}


Fixes Bugzilla #1778.
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
     4 
     5   This software is provided 'as-is', without any express or implied
     6   warranty.  In no event will the authors be held liable for any damages
     7   arising from the use of this software.
     8 
     9   Permission is granted to anyone to use this software for any purpose,
    10   including commercial applications, and to alter it and redistribute it
    11   freely, subject to the following restrictions:
    12 
    13   1. The origin of this software must not be misrepresented; you must not
    14      claim that you wrote the original software. If you use this software
    15      in a product, an acknowledgment in the product documentation would be
    16      appreciated but is not required.
    17   2. Altered source versions must be plainly marked as such, and must not be
    18      misrepresented as being the original software.
    19   3. This notice may not be removed or altered from any source distribution.
    20 */
    21 #include "SDL_config.h"
    22 
    23 #if !SDL_RENDER_DISABLED
    24 
    25 #include "SDL_draw.h"
    26 #include "SDL_drawline.h"
    27 #include "SDL_drawpoint.h"
    28 
    29 
    30 static void
    31 SDL_DrawLine1(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color,
    32               SDL_bool draw_end)
    33 {
    34     if (y1 == y2) {
    35         //HLINE(Uint8, DRAW_FASTSETPIXEL1, draw_end);
    36         int length;
    37         int pitch = (dst->pitch / dst->format->BytesPerPixel);
    38         Uint8 *pixel;
    39         if (x1 <= x2) {
    40             pixel = (Uint8 *)dst->pixels + y1 * pitch + x1;
    41             length = draw_end ? (x2-x1+1) : (x2-x1);
    42         } else {
    43             pixel = (Uint8 *)dst->pixels + y1 * pitch + x2;
    44             if (!draw_end) {
    45                 ++pixel;
    46             }
    47             length = draw_end ? (x1-x2+1) : (x1-x2);
    48         }
    49         SDL_memset(pixel, color, length);
    50     } else if (x1 == x2) {
    51         VLINE(Uint8, DRAW_FASTSETPIXEL1, draw_end);
    52     } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
    53         DLINE(Uint8, DRAW_FASTSETPIXEL1, draw_end);
    54     } else {
    55         BLINE(x1, y1, x2, y2, DRAW_FASTSETPIXELXY1, draw_end);
    56     }
    57 }
    58 
    59 static void
    60 SDL_DrawLine2(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color,
    61               SDL_bool draw_end)
    62 {
    63     if (y1 == y2) {
    64         HLINE(Uint16, DRAW_FASTSETPIXEL2, draw_end);
    65     } else if (x1 == x2) {
    66         VLINE(Uint16, DRAW_FASTSETPIXEL2, draw_end);
    67     } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
    68         DLINE(Uint16, DRAW_FASTSETPIXEL2, draw_end);
    69     } else {
    70         Uint8 _r, _g, _b, _a;
    71         const SDL_PixelFormat * fmt = dst->format;
    72         SDL_GetRGBA(color, fmt, &_r, &_g, &_b, &_a);
    73         if (fmt->Rmask == 0x7C00) {
    74             AALINE(x1, y1, x2, y2,
    75                    DRAW_FASTSETPIXELXY2, DRAW_SETPIXELXY_BLEND_RGB555,
    76                    draw_end);
    77         } else if (fmt->Rmask == 0xF800) {
    78             AALINE(x1, y1, x2, y2,
    79                    DRAW_FASTSETPIXELXY2, DRAW_SETPIXELXY_BLEND_RGB565,
    80                    draw_end);
    81         } else {
    82             AALINE(x1, y1, x2, y2,
    83                    DRAW_FASTSETPIXELXY2, DRAW_SETPIXELXY2_BLEND_RGB,
    84                    draw_end);
    85         }
    86     }
    87 }
    88 
    89 static void
    90 SDL_DrawLine4(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color,
    91               SDL_bool draw_end)
    92 {
    93     if (y1 == y2) {
    94         HLINE(Uint32, DRAW_FASTSETPIXEL4, draw_end);
    95     } else if (x1 == x2) {
    96         VLINE(Uint32, DRAW_FASTSETPIXEL4, draw_end);
    97     } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
    98         DLINE(Uint32, DRAW_FASTSETPIXEL4, draw_end);
    99     } else {
   100         Uint8 _r, _g, _b, _a;
   101         const SDL_PixelFormat * fmt = dst->format;
   102         SDL_GetRGBA(color, fmt, &_r, &_g, &_b, &_a);
   103         if (fmt->Rmask == 0x00FF0000) {
   104             if (!fmt->Amask) {
   105                 AALINE(x1, y1, x2, y2,
   106                        DRAW_FASTSETPIXELXY4, DRAW_SETPIXELXY_BLEND_RGB888,
   107                        draw_end);
   108             } else {
   109                 AALINE(x1, y1, x2, y2,
   110                        DRAW_FASTSETPIXELXY4, DRAW_SETPIXELXY_BLEND_ARGB8888,
   111                        draw_end);
   112             }
   113         } else {
   114             AALINE(x1, y1, x2, y2,
   115                    DRAW_FASTSETPIXELXY4, DRAW_SETPIXELXY4_BLEND_RGB,
   116                    draw_end);
   117         }
   118     }
   119 }
   120 
   121 typedef void (*DrawLineFunc) (SDL_Surface * dst,
   122                               int x1, int y1, int x2, int y2,
   123                               Uint32 color, SDL_bool draw_end);
   124 
   125 static DrawLineFunc
   126 SDL_CalculateDrawLineFunc(const SDL_PixelFormat * fmt)
   127 {
   128     switch (fmt->BytesPerPixel) {
   129     case 1:
   130         if (fmt->BitsPerPixel < 8) {
   131             break;
   132         }
   133         return SDL_DrawLine1;
   134     case 2:
   135         return SDL_DrawLine2;
   136     case 4:
   137         return SDL_DrawLine4;
   138     }
   139     return NULL;
   140 }
   141 
   142 int
   143 SDL_DrawLine(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color)
   144 {
   145     DrawLineFunc func;
   146 
   147     if (!dst) {
   148         return SDL_SetError("SDL_DrawLine(): Passed NULL destination surface");
   149     }
   150 
   151     func = SDL_CalculateDrawLineFunc(dst->format);
   152     if (!func) {
   153         return SDL_SetError("SDL_DrawLine(): Unsupported surface format");
   154     }
   155 
   156     /* Perform clipping */
   157     /* FIXME: We don't actually want to clip, as it may change line slope */
   158     if (!SDL_IntersectRectAndLine(&dst->clip_rect, &x1, &y1, &x2, &y2)) {
   159         return 0;
   160     }
   161 
   162     func(dst, x1, y1, x2, y2, color, SDL_TRUE);
   163     return 0;
   164 }
   165 
   166 int
   167 SDL_DrawLines(SDL_Surface * dst, const SDL_Point * points, int count,
   168               Uint32 color)
   169 {
   170     int i;
   171     int x1, y1;
   172     int x2, y2;
   173     SDL_bool draw_end;
   174     DrawLineFunc func;
   175 
   176     if (!dst) {
   177         return SDL_SetError("SDL_DrawLines(): Passed NULL destination surface");
   178     }
   179 
   180     func = SDL_CalculateDrawLineFunc(dst->format);
   181     if (!func) {
   182         return SDL_SetError("SDL_DrawLines(): Unsupported surface format");
   183     }
   184 
   185     for (i = 1; i < count; ++i) {
   186         x1 = points[i-1].x;
   187         y1 = points[i-1].y;
   188         x2 = points[i].x;
   189         y2 = points[i].y;
   190 
   191         /* Perform clipping */
   192         /* FIXME: We don't actually want to clip, as it may change line slope */
   193         if (!SDL_IntersectRectAndLine(&dst->clip_rect, &x1, &y1, &x2, &y2)) {
   194             continue;
   195         }
   196 
   197         /* Draw the end if it was clipped */
   198         draw_end = (x2 != points[i].x || y2 != points[i].y);
   199 
   200         func(dst, x1, y1, x2, y2, color, draw_end);
   201     }
   202     if (points[0].x != points[count-1].x || points[0].y != points[count-1].y) {
   203         SDL_DrawPoint(dst, points[count-1].x, points[count-1].y, color);
   204     }
   205     return 0;
   206 }
   207 
   208 #endif /* !SDL_RENDER_DISABLED */
   209 
   210 /* vi: set ts=4 sw=4 expandtab: */