src/render/software/SDL_blendline.c
author Sam Lantinga
Thu, 03 Feb 2011 15:49:37 -0800
changeset 5166 4d39eeaad00b
parent 5163 d72793305335
child 5184 d976b67150c5
permissions -rwxr-xr-x
Added a way to get a framebuffer interface for a window, and also a way to create a software renderer for an arbitrary surface.
The software renderer has been re-routed to use the framebuffer interface, which makes it possible to have software rendering available even on simple ports.
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2010 Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Lesser General Public
     7     License as published by the Free Software Foundation; either
     8     version 2.1 of the License, or (at your option) any later version.
     9 
    10     This library is distributed in the hope that it will be useful,
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13     Lesser General Public License for more details.
    14 
    15     You should have received a copy of the GNU Lesser General Public
    16     License along with this library; if not, write to the Free Software
    17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 #include "SDL_config.h"
    23 
    24 #include "SDL_draw.h"
    25 #include "SDL_blendline.h"
    26 #include "SDL_blendpoint.h"
    27 
    28 
    29 static void
    30 SDL_BlendLine_RGB2(SDL_Surface * dst, int x1, int y1, int x2, int y2,
    31                    SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a,
    32                    SDL_bool draw_end)
    33 {
    34     const SDL_PixelFormat *fmt = dst->format;
    35     unsigned r, g, b, a, inva;
    36 
    37     if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
    38         r = DRAW_MUL(_r, _a);
    39         g = DRAW_MUL(_g, _a);
    40         b = DRAW_MUL(_b, _a);
    41         a = _a;
    42     } else {
    43         r = _r;
    44         g = _g;
    45         b = _b;
    46         a = _a;
    47     }
    48     inva = (a ^ 0xff);
    49 
    50     if (y1 == y2) {
    51         switch (blendMode) {
    52         case SDL_BLENDMODE_BLEND:
    53             HLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB, draw_end);
    54             break;
    55         case SDL_BLENDMODE_ADD:
    56             HLINE(Uint16, DRAW_SETPIXEL_ADD_RGB, draw_end);
    57             break;
    58         default:
    59             HLINE(Uint16, DRAW_SETPIXEL_RGB, draw_end);
    60             break;
    61         }
    62     } else if (x1 == x2) {
    63         switch (blendMode) {
    64         case SDL_BLENDMODE_BLEND:
    65             VLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB, draw_end);
    66             break;
    67         case SDL_BLENDMODE_ADD:
    68             VLINE(Uint16, DRAW_SETPIXEL_ADD_RGB, draw_end);
    69             break;
    70         default:
    71             VLINE(Uint16, DRAW_SETPIXEL_RGB, draw_end);
    72             break;
    73         }
    74     } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
    75         switch (blendMode) {
    76         case SDL_BLENDMODE_BLEND:
    77             DLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB, draw_end);
    78             break;
    79         case SDL_BLENDMODE_ADD:
    80             DLINE(Uint16, DRAW_SETPIXEL_ADD_RGB, draw_end);
    81             break;
    82         default:
    83             DLINE(Uint16, DRAW_SETPIXEL_RGB, draw_end);
    84             break;
    85         }
    86     } else {
    87         switch (blendMode) {
    88         case SDL_BLENDMODE_BLEND:
    89             AALINE(x1, y1, x2, y2,
    90                    DRAW_SETPIXELXY2_BLEND_RGB, DRAW_SETPIXELXY2_BLEND_RGB,
    91                    draw_end);
    92             break;
    93         case SDL_BLENDMODE_ADD:
    94             AALINE(x1, y1, x2, y2,
    95                    DRAW_SETPIXELXY2_ADD_RGB, DRAW_SETPIXELXY2_ADD_RGB,
    96                    draw_end);
    97             break;
    98         default:
    99             AALINE(x1, y1, x2, y2,
   100                    DRAW_SETPIXELXY2_RGB, DRAW_SETPIXELXY2_BLEND_RGB,
   101                    draw_end);
   102             break;
   103         }
   104     }
   105 }
   106 
   107 static void
   108 SDL_BlendLine_RGB555(SDL_Surface * dst, int x1, int y1, int x2, int y2,
   109                      SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a,
   110                      SDL_bool draw_end)
   111 {
   112     const SDL_PixelFormat *fmt = dst->format;
   113     unsigned r, g, b, a, inva;
   114 
   115     if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
   116         r = DRAW_MUL(_r, _a);
   117         g = DRAW_MUL(_g, _a);
   118         b = DRAW_MUL(_b, _a);
   119         a = _a;
   120     } else {
   121         r = _r;
   122         g = _g;
   123         b = _b;
   124         a = _a;
   125     }
   126     inva = (a ^ 0xff);
   127 
   128     if (y1 == y2) {
   129         switch (blendMode) {
   130         case SDL_BLENDMODE_BLEND:
   131             HLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB555, draw_end);
   132             break;
   133         case SDL_BLENDMODE_ADD:
   134             HLINE(Uint16, DRAW_SETPIXEL_ADD_RGB555, draw_end);
   135             break;
   136         default:
   137             HLINE(Uint16, DRAW_SETPIXEL_RGB555, draw_end);
   138             break;
   139         }
   140     } else if (x1 == x2) {
   141         switch (blendMode) {
   142         case SDL_BLENDMODE_BLEND:
   143             VLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB555, draw_end);
   144             break;
   145         case SDL_BLENDMODE_ADD:
   146             VLINE(Uint16, DRAW_SETPIXEL_ADD_RGB555, draw_end);
   147             break;
   148         default:
   149             VLINE(Uint16, DRAW_SETPIXEL_RGB555, draw_end);
   150             break;
   151         }
   152     } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
   153         switch (blendMode) {
   154         case SDL_BLENDMODE_BLEND:
   155             DLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB555, draw_end);
   156             break;
   157         case SDL_BLENDMODE_ADD:
   158             DLINE(Uint16, DRAW_SETPIXEL_ADD_RGB555, draw_end);
   159             break;
   160         default:
   161             DLINE(Uint16, DRAW_SETPIXEL_RGB555, draw_end);
   162             break;
   163         }
   164     } else {
   165         switch (blendMode) {
   166         case SDL_BLENDMODE_BLEND:
   167             AALINE(x1, y1, x2, y2,
   168                    DRAW_SETPIXELXY_BLEND_RGB555, DRAW_SETPIXELXY_BLEND_RGB555,
   169                    draw_end);
   170             break;
   171         case SDL_BLENDMODE_ADD:
   172             AALINE(x1, y1, x2, y2,
   173                    DRAW_SETPIXELXY_ADD_RGB555, DRAW_SETPIXELXY_ADD_RGB555,
   174                    draw_end);
   175             break;
   176         default:
   177             AALINE(x1, y1, x2, y2,
   178                    DRAW_SETPIXELXY_RGB555, DRAW_SETPIXELXY_BLEND_RGB555,
   179                    draw_end);
   180             break;
   181         }
   182     }
   183 }
   184 
   185 static void
   186 SDL_BlendLine_RGB565(SDL_Surface * dst, int x1, int y1, int x2, int y2,
   187                      SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a,
   188                      SDL_bool draw_end)
   189 {
   190     const SDL_PixelFormat *fmt = dst->format;
   191     unsigned r, g, b, a, inva;
   192 
   193     if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
   194         r = DRAW_MUL(_r, _a);
   195         g = DRAW_MUL(_g, _a);
   196         b = DRAW_MUL(_b, _a);
   197         a = _a;
   198     } else {
   199         r = _r;
   200         g = _g;
   201         b = _b;
   202         a = _a;
   203     }
   204     inva = (a ^ 0xff);
   205 
   206     if (y1 == y2) {
   207         switch (blendMode) {
   208         case SDL_BLENDMODE_BLEND:
   209             HLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB565, draw_end);
   210             break;
   211         case SDL_BLENDMODE_ADD:
   212             HLINE(Uint16, DRAW_SETPIXEL_ADD_RGB565, draw_end);
   213             break;
   214         default:
   215             HLINE(Uint16, DRAW_SETPIXEL_RGB565, draw_end);
   216             break;
   217         }
   218     } else if (x1 == x2) {
   219         switch (blendMode) {
   220         case SDL_BLENDMODE_BLEND:
   221             VLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB565, draw_end);
   222             break;
   223         case SDL_BLENDMODE_ADD:
   224             VLINE(Uint16, DRAW_SETPIXEL_ADD_RGB565, draw_end);
   225             break;
   226         default:
   227             VLINE(Uint16, DRAW_SETPIXEL_RGB565, draw_end);
   228             break;
   229         }
   230     } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
   231         switch (blendMode) {
   232         case SDL_BLENDMODE_BLEND:
   233             DLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB565, draw_end);
   234             break;
   235         case SDL_BLENDMODE_ADD:
   236             DLINE(Uint16, DRAW_SETPIXEL_ADD_RGB565, draw_end);
   237             break;
   238         default:
   239             DLINE(Uint16, DRAW_SETPIXEL_RGB565, draw_end);
   240             break;
   241         }
   242     } else {
   243         switch (blendMode) {
   244         case SDL_BLENDMODE_BLEND:
   245             AALINE(x1, y1, x2, y2,
   246                    DRAW_SETPIXELXY_BLEND_RGB565, DRAW_SETPIXELXY_BLEND_RGB565,
   247                    draw_end);
   248             break;
   249         case SDL_BLENDMODE_ADD:
   250             AALINE(x1, y1, x2, y2,
   251                    DRAW_SETPIXELXY_ADD_RGB565, DRAW_SETPIXELXY_ADD_RGB565,
   252                    draw_end);
   253             break;
   254         default:
   255             AALINE(x1, y1, x2, y2,
   256                    DRAW_SETPIXELXY_RGB565, DRAW_SETPIXELXY_BLEND_RGB565,
   257                    draw_end);
   258             break;
   259         }
   260     }
   261 }
   262 
   263 static void
   264 SDL_BlendLine_RGB4(SDL_Surface * dst, int x1, int y1, int x2, int y2,
   265                    SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a,
   266                    SDL_bool draw_end)
   267 {
   268     const SDL_PixelFormat *fmt = dst->format;
   269     unsigned r, g, b, a, inva;
   270 
   271     if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
   272         r = DRAW_MUL(_r, _a);
   273         g = DRAW_MUL(_g, _a);
   274         b = DRAW_MUL(_b, _a);
   275         a = _a;
   276     } else {
   277         r = _r;
   278         g = _g;
   279         b = _b;
   280         a = _a;
   281     }
   282     inva = (a ^ 0xff);
   283 
   284     if (y1 == y2) {
   285         switch (blendMode) {
   286         case SDL_BLENDMODE_BLEND:
   287             HLINE(Uint32, DRAW_SETPIXEL_BLEND_RGB, draw_end);
   288             break;
   289         case SDL_BLENDMODE_ADD:
   290             HLINE(Uint32, DRAW_SETPIXEL_ADD_RGB, draw_end);
   291             break;
   292         default:
   293             HLINE(Uint32, DRAW_SETPIXEL_RGB, draw_end);
   294             break;
   295         }
   296     } else if (x1 == x2) {
   297         switch (blendMode) {
   298         case SDL_BLENDMODE_BLEND:
   299             VLINE(Uint32, DRAW_SETPIXEL_BLEND_RGB, draw_end);
   300             break;
   301         case SDL_BLENDMODE_ADD:
   302             VLINE(Uint32, DRAW_SETPIXEL_ADD_RGB, draw_end);
   303             break;
   304         default:
   305             VLINE(Uint32, DRAW_SETPIXEL_RGB, draw_end);
   306             break;
   307         }
   308     } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
   309         switch (blendMode) {
   310         case SDL_BLENDMODE_BLEND:
   311             DLINE(Uint32, DRAW_SETPIXEL_BLEND_RGB, draw_end);
   312             break;
   313         case SDL_BLENDMODE_ADD:
   314             DLINE(Uint32, DRAW_SETPIXEL_ADD_RGB, draw_end);
   315             break;
   316         default:
   317             DLINE(Uint32, DRAW_SETPIXEL_RGB, draw_end);
   318             break;
   319         }
   320     } else {
   321         switch (blendMode) {
   322         case SDL_BLENDMODE_BLEND:
   323             AALINE(x1, y1, x2, y2,
   324                    DRAW_SETPIXELXY4_BLEND_RGB, DRAW_SETPIXELXY4_BLEND_RGB,
   325                    draw_end);
   326             break;
   327         case SDL_BLENDMODE_ADD:
   328             AALINE(x1, y1, x2, y2,
   329                    DRAW_SETPIXELXY4_ADD_RGB, DRAW_SETPIXELXY4_ADD_RGB,
   330                    draw_end);
   331             break;
   332         default:
   333             AALINE(x1, y1, x2, y2,
   334                    DRAW_SETPIXELXY4_RGB, DRAW_SETPIXELXY4_BLEND_RGB,
   335                    draw_end);
   336             break;
   337         }
   338     }
   339 }
   340 
   341 static void
   342 SDL_BlendLine_RGBA4(SDL_Surface * dst, int x1, int y1, int x2, int y2,
   343                     SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a,
   344                     SDL_bool draw_end)
   345 {
   346     const SDL_PixelFormat *fmt = dst->format;
   347     unsigned r, g, b, a, inva;
   348 
   349     if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
   350         r = DRAW_MUL(_r, _a);
   351         g = DRAW_MUL(_g, _a);
   352         b = DRAW_MUL(_b, _a);
   353         a = _a;
   354     } else {
   355         r = _r;
   356         g = _g;
   357         b = _b;
   358         a = _a;
   359     }
   360     inva = (a ^ 0xff);
   361 
   362     if (y1 == y2) {
   363         switch (blendMode) {
   364         case SDL_BLENDMODE_BLEND:
   365             HLINE(Uint32, DRAW_SETPIXEL_BLEND_RGBA, draw_end);
   366             break;
   367         case SDL_BLENDMODE_ADD:
   368             HLINE(Uint32, DRAW_SETPIXEL_ADD_RGBA, draw_end);
   369             break;
   370         default:
   371             HLINE(Uint32, DRAW_SETPIXEL_RGBA, draw_end);
   372             break;
   373         }
   374     } else if (x1 == x2) {
   375         switch (blendMode) {
   376         case SDL_BLENDMODE_BLEND:
   377             VLINE(Uint32, DRAW_SETPIXEL_BLEND_RGBA, draw_end);
   378             break;
   379         case SDL_BLENDMODE_ADD:
   380             VLINE(Uint32, DRAW_SETPIXEL_ADD_RGBA, draw_end);
   381             break;
   382         default:
   383             VLINE(Uint32, DRAW_SETPIXEL_RGBA, draw_end);
   384             break;
   385         }
   386     } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
   387         switch (blendMode) {
   388         case SDL_BLENDMODE_BLEND:
   389             DLINE(Uint32, DRAW_SETPIXEL_BLEND_RGBA, draw_end);
   390             break;
   391         case SDL_BLENDMODE_ADD:
   392             DLINE(Uint32, DRAW_SETPIXEL_ADD_RGBA, draw_end);
   393             break;
   394         default:
   395             DLINE(Uint32, DRAW_SETPIXEL_RGBA, draw_end);
   396             break;
   397         }
   398     } else {
   399         switch (blendMode) {
   400         case SDL_BLENDMODE_BLEND:
   401             AALINE(x1, y1, x2, y2,
   402                    DRAW_SETPIXELXY4_BLEND_RGBA, DRAW_SETPIXELXY4_BLEND_RGBA,
   403                    draw_end);
   404             break;
   405         case SDL_BLENDMODE_ADD:
   406             AALINE(x1, y1, x2, y2,
   407                    DRAW_SETPIXELXY4_ADD_RGBA, DRAW_SETPIXELXY4_ADD_RGBA,
   408                    draw_end);
   409             break;
   410         default:
   411             AALINE(x1, y1, x2, y2,
   412                    DRAW_SETPIXELXY4_RGBA, DRAW_SETPIXELXY4_BLEND_RGBA,
   413                    draw_end);
   414             break;
   415         }
   416     }
   417 }
   418 
   419 static void
   420 SDL_BlendLine_RGB888(SDL_Surface * dst, int x1, int y1, int x2, int y2,
   421                      SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a,
   422                      SDL_bool draw_end)
   423 {
   424     const SDL_PixelFormat *fmt = dst->format;
   425     unsigned r, g, b, a, inva;
   426 
   427     if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
   428         r = DRAW_MUL(_r, _a);
   429         g = DRAW_MUL(_g, _a);
   430         b = DRAW_MUL(_b, _a);
   431         a = _a;
   432     } else {
   433         r = _r;
   434         g = _g;
   435         b = _b;
   436         a = _a;
   437     }
   438     inva = (a ^ 0xff);
   439 
   440     if (y1 == y2) {
   441         switch (blendMode) {
   442         case SDL_BLENDMODE_BLEND:
   443             HLINE(Uint32, DRAW_SETPIXEL_BLEND_RGB888, draw_end);
   444             break;
   445         case SDL_BLENDMODE_ADD:
   446             HLINE(Uint32, DRAW_SETPIXEL_ADD_RGB888, draw_end);
   447             break;
   448         default:
   449             HLINE(Uint32, DRAW_SETPIXEL_RGB888, draw_end);
   450             break;
   451         }
   452     } else if (x1 == x2) {
   453         switch (blendMode) {
   454         case SDL_BLENDMODE_BLEND:
   455             VLINE(Uint32, DRAW_SETPIXEL_BLEND_RGB888, draw_end);
   456             break;
   457         case SDL_BLENDMODE_ADD:
   458             VLINE(Uint32, DRAW_SETPIXEL_ADD_RGB888, draw_end);
   459             break;
   460         default:
   461             VLINE(Uint32, DRAW_SETPIXEL_RGB888, draw_end);
   462             break;
   463         }
   464     } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
   465         switch (blendMode) {
   466         case SDL_BLENDMODE_BLEND:
   467             DLINE(Uint32, DRAW_SETPIXEL_BLEND_RGB888, draw_end);
   468             break;
   469         case SDL_BLENDMODE_ADD:
   470             DLINE(Uint32, DRAW_SETPIXEL_ADD_RGB888, draw_end);
   471             break;
   472         default:
   473             DLINE(Uint32, DRAW_SETPIXEL_RGB888, draw_end);
   474             break;
   475         }
   476     } else {
   477         switch (blendMode) {
   478         case SDL_BLENDMODE_BLEND:
   479             AALINE(x1, y1, x2, y2,
   480                    DRAW_SETPIXELXY_BLEND_RGB888, DRAW_SETPIXELXY_BLEND_RGB888,
   481                    draw_end);
   482             break;
   483         case SDL_BLENDMODE_ADD:
   484             AALINE(x1, y1, x2, y2,
   485                    DRAW_SETPIXELXY_ADD_RGB888, DRAW_SETPIXELXY_ADD_RGB888,
   486                    draw_end);
   487             break;
   488         default:
   489             AALINE(x1, y1, x2, y2,
   490                    DRAW_SETPIXELXY_RGB888, DRAW_SETPIXELXY_BLEND_RGB888,
   491                    draw_end);
   492             break;
   493         }
   494     }
   495 }
   496 
   497 static void
   498 SDL_BlendLine_ARGB8888(SDL_Surface * dst, int x1, int y1, int x2, int y2,
   499                        SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a,
   500                        SDL_bool draw_end)
   501 {
   502     const SDL_PixelFormat *fmt = dst->format;
   503     unsigned r, g, b, a, inva;
   504 
   505     if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
   506         r = DRAW_MUL(_r, _a);
   507         g = DRAW_MUL(_g, _a);
   508         b = DRAW_MUL(_b, _a);
   509         a = _a;
   510     } else {
   511         r = _r;
   512         g = _g;
   513         b = _b;
   514         a = _a;
   515     }
   516     inva = (a ^ 0xff);
   517 
   518     if (y1 == y2) {
   519         switch (blendMode) {
   520         case SDL_BLENDMODE_BLEND:
   521             HLINE(Uint32, DRAW_SETPIXEL_BLEND_ARGB8888, draw_end);
   522             break;
   523         case SDL_BLENDMODE_ADD:
   524             HLINE(Uint32, DRAW_SETPIXEL_ADD_ARGB8888, draw_end);
   525             break;
   526         default:
   527             HLINE(Uint32, DRAW_SETPIXEL_ARGB8888, draw_end);
   528             break;
   529         }
   530     } else if (x1 == x2) {
   531         switch (blendMode) {
   532         case SDL_BLENDMODE_BLEND:
   533             VLINE(Uint32, DRAW_SETPIXEL_BLEND_ARGB8888, draw_end);
   534             break;
   535         case SDL_BLENDMODE_ADD:
   536             VLINE(Uint32, DRAW_SETPIXEL_ADD_ARGB8888, draw_end);
   537             break;
   538         default:
   539             VLINE(Uint32, DRAW_SETPIXEL_ARGB8888, draw_end);
   540             break;
   541         }
   542     } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
   543         switch (blendMode) {
   544         case SDL_BLENDMODE_BLEND:
   545             DLINE(Uint32, DRAW_SETPIXEL_BLEND_ARGB8888, draw_end);
   546             break;
   547         case SDL_BLENDMODE_ADD:
   548             DLINE(Uint32, DRAW_SETPIXEL_ADD_ARGB8888, draw_end);
   549             break;
   550         default:
   551             DLINE(Uint32, DRAW_SETPIXEL_ARGB8888, draw_end);
   552             break;
   553         }
   554     } else {
   555         switch (blendMode) {
   556         case SDL_BLENDMODE_BLEND:
   557             AALINE(x1, y1, x2, y2,
   558                    DRAW_SETPIXELXY_BLEND_ARGB8888, DRAW_SETPIXELXY_BLEND_ARGB8888,
   559                    draw_end);
   560             break;
   561         case SDL_BLENDMODE_ADD:
   562             AALINE(x1, y1, x2, y2,
   563                    DRAW_SETPIXELXY_ADD_ARGB8888, DRAW_SETPIXELXY_ADD_ARGB8888,
   564                    draw_end);
   565             break;
   566         default:
   567             AALINE(x1, y1, x2, y2,
   568                    DRAW_SETPIXELXY_ARGB8888, DRAW_SETPIXELXY_BLEND_ARGB8888,
   569                    draw_end);
   570             break;
   571         }
   572     }
   573 }
   574 
   575 typedef void (*BlendLineFunc) (SDL_Surface * dst,
   576                                int x1, int y1, int x2, int y2,
   577                                SDL_BlendMode blendMode,
   578                                Uint8 r, Uint8 g, Uint8 b, Uint8 a,
   579                                SDL_bool draw_end);
   580 
   581 static BlendLineFunc
   582 SDL_CalculateBlendLineFunc(const SDL_PixelFormat * fmt)
   583 {
   584     switch (fmt->BytesPerPixel) {
   585     case 2:
   586         if (fmt->Rmask == 0x7C00) {
   587             return SDL_BlendLine_RGB555;
   588         } else if (fmt->Rmask == 0xF800) {
   589             return SDL_BlendLine_RGB565;
   590         } else {
   591             return SDL_BlendLine_RGB2;
   592         }
   593         break;
   594     case 4:
   595         if (fmt->Rmask == 0x00FF0000) {
   596             if (fmt->Amask) {
   597                 return SDL_BlendLine_ARGB8888;
   598             } else {
   599                 return SDL_BlendLine_RGB888;
   600             }
   601         } else {
   602             if (fmt->Amask) {
   603                 return SDL_BlendLine_RGBA4;
   604             } else {
   605                 return SDL_BlendLine_RGB4;
   606             }
   607         }
   608     }
   609     return NULL;
   610 }
   611 
   612 int
   613 SDL_BlendLine(SDL_Surface * dst, int x1, int y1, int x2, int y2,
   614               SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
   615 {
   616     BlendLineFunc func;
   617 
   618     if (!dst) {
   619         SDL_SetError("SDL_BlendLine(): Passed NULL destination surface");
   620         return -1;
   621     }
   622 
   623     func = SDL_CalculateBlendLineFunc(dst->format);
   624     if (!func) {
   625         SDL_SetError("SDL_BlendLine(): Unsupported surface format");
   626         return -1;
   627     }
   628 
   629     /* Perform clipping */
   630     /* FIXME: We don't actually want to clip, as it may change line slope */
   631     if (!SDL_IntersectRectAndLine(&dst->clip_rect, &x1, &y1, &x2, &y2)) {
   632         return 0;
   633     }
   634 
   635     func(dst, x1, y1, x2, y2, blendMode, r, g, b, a, SDL_TRUE);
   636     return 0;
   637 }
   638 
   639 int
   640 SDL_BlendLines(SDL_Surface * dst, const SDL_Point * points, int count,
   641                SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
   642 {
   643     int i;
   644     int x1, y1;
   645     int x2, y2;
   646     SDL_bool draw_end;
   647     BlendLineFunc func;
   648 
   649     if (!dst) {
   650         SDL_SetError("SDL_BlendLines(): Passed NULL destination surface");
   651         return -1;
   652     }
   653 
   654     func = SDL_CalculateBlendLineFunc(dst->format);
   655     if (!func) {
   656         SDL_SetError("SDL_BlendLines(): Unsupported surface format");
   657         return -1;
   658     }
   659 
   660     for (i = 1; i < count; ++i) {
   661         x1 = points[i-1].x;
   662         y1 = points[i-1].y;
   663         x2 = points[i].x;
   664         y2 = points[i].y;
   665 
   666         /* Perform clipping */
   667         /* FIXME: We don't actually want to clip, as it may change line slope */
   668         if (!SDL_IntersectRectAndLine(&dst->clip_rect, &x1, &y1, &x2, &y2)) {
   669             continue;
   670         }
   671 
   672         /* Draw the end if it was clipped */
   673         draw_end = (x2 != points[i].x || y2 != points[i].y);
   674 
   675         func(dst, x1, y1, x2, y2, blendMode, r, g, b, a, draw_end);
   676     }
   677     if (points[0].x != points[count-1].x || points[0].y != points[count-1].y) {
   678         SDL_BlendPoint(dst, points[count-1].x, points[count-1].y,
   679                        blendMode, r, g, b, a);
   680     }
   681     return 0;
   682 }
   683 
   684 /* vi: set ts=4 sw=4 expandtab: */