Fix: set to opaque when a palette surface is converted to an alpha format.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
diff --git a/src/video/SDL_surface.c b/src/video/SDL_surface.c
index d108415..2285370 100644
--- a/src/video/SDL_surface.c
+++ b/src/video/SDL_surface.c
@@ -402,6 +402,64 @@ SDL_ConvertColorkeyToAlpha(SDL_Surface * surface, SDL_bool ignore_alpha)
SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_BLEND);
}
+
+static void
+SDL_ConvertSetOpaque(SDL_Surface * surface)
+{
+ int x, y;
+
+ if (!surface) {
+ return;
+ }
+
+ if (!surface->format->Amask) {
+ return;
+ }
+
+ SDL_LockSurface(surface);
+
+ switch (surface->format->BytesPerPixel) {
+ case 2:
+ {
+ Uint16 *row, *spot;
+ Uint16 mask = (Uint16) (surface->format->Amask);
+
+ row = (Uint16 *) surface->pixels;
+ for (y = surface->h; y--;) {
+ spot = row;
+ for (x = surface->w; x--;) {
+ *spot |= mask;
+ ++spot;
+ }
+ row += surface->pitch / 2;
+ }
+ }
+ break;
+ case 3:
+ /* FIXME */
+ break;
+ case 4:
+ {
+ Uint32 *row, *spot;
+ Uint32 mask = surface->format->Amask;
+
+ row = (Uint32 *) surface->pixels;
+ for (y = surface->h; y--;) {
+ spot = row;
+ for (x = surface->w; x--;) {
+ *spot |= mask;
+ ++spot;
+ }
+ row += surface->pitch / 4;
+ }
+ }
+ break;
+ }
+
+ SDL_UnlockSurface(surface);
+}
+
+
int
SDL_SetSurfaceColorMod(SDL_Surface * surface, Uint8 r, Uint8 g, Uint8 b)
{
@@ -962,9 +1020,9 @@ SDL_ConvertSurface(SDL_Surface * surface, const SDL_PixelFormat * format,
SDL_Color copy_color;
SDL_Rect bounds;
int ret;
- int palette_ck_transform = 0;
+ SDL_bool palette_ck_transform = SDL_FALSE;
int palette_ck_value = 0;
- int palette_has_alpha = SDL_FALSE;
+ SDL_bool palette_has_alpha = SDL_FALSE;
if (!surface) {
SDL_InvalidParamError("surface");
@@ -1029,7 +1087,7 @@ SDL_ConvertSurface(SDL_Surface * surface, const SDL_PixelFormat * format,
/* Transform colorkey to alpha. for cases where source palette has duplicate values, and colorkey is one of them */
if (copy_flags & SDL_COPY_COLORKEY) {
if (surface->format->palette && !format->palette) {
- palette_ck_transform = 1;
+ palette_ck_transform = SDL_TRUE;
palette_has_alpha = SDL_TRUE;
palette_ck_value = surface->format->palette->colors[surface->map->info.colorkey].a;
surface->format->palette->colors[surface->map->info.colorkey].a = SDL_ALPHA_TRANSPARENT;
@@ -1135,6 +1193,26 @@ SDL_ConvertSurface(SDL_Surface * surface, const SDL_PixelFormat * format,
}
}
+ /* Source surface has a palette with no alpha nor colorkey.
+ * Destination format has alpha.
+ * We may need to set the alpha channel to opaque. */
+ if (surface->format->palette && format->Amask && palette_has_alpha == SDL_FALSE) {
+ SDL_bool need_opaque = SDL_FALSE;
+ int i;
+ for (i = 0; i < surface->format->palette->ncolors; i++) {
+ Uint8 alpha_value = surface->format->palette->colors[i].a;
+ if (alpha_value == 0) {
+ need_opaque = SDL_TRUE;
+ break;
+ }
+ }
+
+ if (need_opaque) {
+ SDL_ConvertSetOpaque(convert);
+ }
+ }
+
+
/* Enable alpha blending by default if the new surface has an
* alpha channel or alpha modulation */
if ((surface->format->Amask && format->Amask) ||