Fixed bug 3827 - issue with MapRGB, palette and colorkey
authorSylvain Becker <sylvain.becker@gmail.com>
Mon, 21 Jan 2019 18:45:15 +0100
changeset 12566884f99b039f0
parent 12561 d4d5e1272239
child 12567 92b9d6f10a29
Fixed bug 3827 - issue with MapRGB, palette and colorkey

For a palettized surface, prevent SDL_MapRGB() value to change whether colorkey is set or not.
src/video/SDL_surface.c
     1.1 --- a/src/video/SDL_surface.c	Sat Jan 19 16:47:43 2019 +0100
     1.2 +++ b/src/video/SDL_surface.c	Mon Jan 21 18:45:15 2019 +0100
     1.3 @@ -268,21 +268,7 @@
     1.4      if (flag) {
     1.5          surface->map->info.flags |= SDL_COPY_COLORKEY;
     1.6          surface->map->info.colorkey = key;
     1.7 -        if (surface->format->palette) {
     1.8 -            surface->format->palette->colors[surface->map->info.colorkey].a = SDL_ALPHA_TRANSPARENT;
     1.9 -            ++surface->format->palette->version;
    1.10 -            if (!surface->format->palette->version) {
    1.11 -                surface->format->palette->version = 1;
    1.12 -            }
    1.13 -        }
    1.14      } else {
    1.15 -        if (surface->format->palette) {
    1.16 -            surface->format->palette->colors[surface->map->info.colorkey].a = SDL_ALPHA_OPAQUE;
    1.17 -            ++surface->format->palette->version;
    1.18 -            if (!surface->format->palette->version) {
    1.19 -                surface->format->palette->version = 1;
    1.20 -            }
    1.21 -        }
    1.22          surface->map->info.flags &= ~SDL_COPY_COLORKEY;
    1.23      }
    1.24      if (surface->map->info.flags != flags) {
    1.25 @@ -325,7 +311,7 @@
    1.26  
    1.27  /* This is a fairly slow function to switch from colorkey to alpha */
    1.28  static void
    1.29 -SDL_ConvertColorkeyToAlpha(SDL_Surface * surface)
    1.30 +SDL_ConvertColorkeyToAlpha(SDL_Surface * surface, SDL_bool ignore_alpha)
    1.31  {
    1.32      int x, y;
    1.33  
    1.34 @@ -347,18 +333,32 @@
    1.35              Uint16 ckey = (Uint16) surface->map->info.colorkey;
    1.36              Uint16 mask = (Uint16) (~surface->format->Amask);
    1.37  
    1.38 -            /* Ignore alpha in colorkey comparison */
    1.39 -            ckey &= mask;
    1.40 -            row = (Uint16 *) surface->pixels;
    1.41 -            for (y = surface->h; y--;) {
    1.42 -                spot = row;
    1.43 -                for (x = surface->w; x--;) {
    1.44 -                    if ((*spot & mask) == ckey) {
    1.45 -                        *spot &= mask;
    1.46 +            /* Ignore, or not, alpha in colorkey comparison */
    1.47 +            if (ignore_alpha) {
    1.48 +                ckey &= mask;
    1.49 +                row = (Uint16 *) surface->pixels;
    1.50 +                for (y = surface->h; y--;) {
    1.51 +                    spot = row;
    1.52 +                    for (x = surface->w; x--;) {
    1.53 +                        if ((*spot & mask) == ckey) {
    1.54 +                            *spot &= mask;
    1.55 +                        }
    1.56 +                        ++spot;
    1.57                      }
    1.58 -                    ++spot;
    1.59 +                    row += surface->pitch / 2;
    1.60                  }
    1.61 -                row += surface->pitch / 2;
    1.62 +            } else {
    1.63 +                row = (Uint16 *) surface->pixels;
    1.64 +                for (y = surface->h; y--;) {
    1.65 +                    spot = row;
    1.66 +                    for (x = surface->w; x--;) {
    1.67 +                        if (*spot == ckey) {
    1.68 +                            *spot &= mask;
    1.69 +                        }
    1.70 +                        ++spot;
    1.71 +                    }
    1.72 +                    row += surface->pitch / 2;
    1.73 +                }
    1.74              }
    1.75          }
    1.76          break;
    1.77 @@ -371,18 +371,32 @@
    1.78              Uint32 ckey = surface->map->info.colorkey;
    1.79              Uint32 mask = ~surface->format->Amask;
    1.80  
    1.81 -            /* Ignore alpha in colorkey comparison */
    1.82 -            ckey &= mask;
    1.83 -            row = (Uint32 *) surface->pixels;
    1.84 -            for (y = surface->h; y--;) {
    1.85 -                spot = row;
    1.86 -                for (x = surface->w; x--;) {
    1.87 -                    if ((*spot & mask) == ckey) {
    1.88 -                        *spot &= mask;
    1.89 +            /* Ignore, or not, alpha in colorkey comparison */
    1.90 +            if (ignore_alpha) {
    1.91 +                ckey &= mask;
    1.92 +                row = (Uint32 *) surface->pixels;
    1.93 +                for (y = surface->h; y--;) {
    1.94 +                    spot = row;
    1.95 +                    for (x = surface->w; x--;) {
    1.96 +                        if ((*spot & mask) == ckey) {
    1.97 +                            *spot &= mask;
    1.98 +                        }
    1.99 +                        ++spot;
   1.100                      }
   1.101 -                    ++spot;
   1.102 +                    row += surface->pitch / 4;
   1.103                  }
   1.104 -                row += surface->pitch / 4;
   1.105 +            } else {
   1.106 +                row = (Uint32 *) surface->pixels;
   1.107 +                for (y = surface->h; y--;) {
   1.108 +                    spot = row;
   1.109 +                    for (x = surface->w; x--;) {
   1.110 +                        if (*spot == ckey) {
   1.111 +                            *spot &= mask;
   1.112 +                        }
   1.113 +                        ++spot;
   1.114 +                    }
   1.115 +                    row += surface->pitch / 4;
   1.116 +                }
   1.117              }
   1.118          }
   1.119          break;
   1.120 @@ -1023,6 +1037,7 @@
   1.121      SDL_InvalidateMap(surface->map);
   1.122      if (copy_flags & SDL_COPY_COLORKEY) {
   1.123          SDL_bool set_colorkey_by_color = SDL_FALSE;
   1.124 +        SDL_bool ignore_alpha          = SDL_TRUE;  /* Ignore, or not, alpha in colorkey comparison */
   1.125  
   1.126          if (surface->format->palette) {
   1.127              if (format->palette &&
   1.128 @@ -1032,7 +1047,8 @@
   1.129                  /* The palette is identical, just set the same colorkey */
   1.130                  SDL_SetColorKey(convert, 1, surface->map->info.colorkey);
   1.131              } else if (format->Amask) {
   1.132 -                /* The alpha was set in the destination from the palette */
   1.133 +                set_colorkey_by_color = SDL_TRUE;
   1.134 +                ignore_alpha = SDL_FALSE;
   1.135              } else {
   1.136                  set_colorkey_by_color = SDL_TRUE;
   1.137              }
   1.138 @@ -1055,7 +1071,7 @@
   1.139              if (surface->format->palette) {
   1.140                  SDL_SetSurfacePalette(tmp, surface->format->palette);
   1.141              }
   1.142 -            
   1.143 +
   1.144              SDL_FillRect(tmp, NULL, surface->map->info.colorkey);
   1.145  
   1.146              tmp->map->info.flags &= ~SDL_COPY_COLORKEY;
   1.147 @@ -1073,7 +1089,7 @@
   1.148              SDL_SetColorKey(convert, 1, converted_colorkey);
   1.149  
   1.150              /* This is needed when converting for 3D texture upload */
   1.151 -            SDL_ConvertColorkeyToAlpha(convert);
   1.152 +            SDL_ConvertColorkeyToAlpha(convert, ignore_alpha);
   1.153          }
   1.154      }
   1.155      SDL_SetClipRect(convert, &surface->clip_rect);