Added color-key mode and redid the code to work with it.
authorEli Gottlieb <eligottlieb@gmail.com>
Thu, 22 Jul 2010 23:11:01 -0400
changeset 4807c9eb95f29770
parent 4806 007567dbb8c1
child 4808 2ae79ed78a5a
Added color-key mode and redid the code to work with it.
include/SDL_shape.h
src/video/SDL_shape.c
src/video/SDL_sysvideo.h
src/video/win32/SDL_win32shape.c
src/video/x11/SDL_x11shape.c
     1.1 --- a/include/SDL_shape.h	Tue Jul 20 12:42:43 2010 -0400
     1.2 +++ b/include/SDL_shape.h	Thu Jul 22 23:11:01 2010 -0400
     1.3 @@ -83,12 +83,17 @@
     1.4  	/** \brief The default mode, a binarized alpha cutoff of 1. */
     1.5  	ShapeModeDefault,
     1.6  	/** \brief A binarized alpha cutoff with a given integer value. */
     1.7 -	ShapeModeBinarizeAlpha
     1.8 +	ShapeModeBinarizeAlpha,
     1.9 +	/** \brief A binarized alpha cutoff with a given integer value, but with the opposite comparison. */
    1.10 +	ShapeModeReverseBinarizeAlpha,
    1.11 +	/** \brief A color key is applied. */
    1.12 +	ShapeModeColorKey
    1.13  } WindowShapeMode;
    1.14  /** \brief A union containing parameters for shaped windows. */
    1.15  typedef union {
    1.16  	/** \brief a cutoff alpha value for binarization of the window shape's alpha channel. */
    1.17  	Uint8 binarizationCutoff;
    1.18 +	SDL_Color colorKey;
    1.19  } SDL_WindowShapeParams;
    1.20  
    1.21  /** \brief A struct that tags the SDL_WindowShapeParams union with an enum describing the type of its contents. */
     2.1 --- a/src/video/SDL_shape.c	Tue Jul 20 12:42:43 2010 -0400
     2.2 +++ b/src/video/SDL_shape.c	Thu Jul 22 23:11:01 2010 -0400
     2.3 @@ -34,7 +34,8 @@
     2.4  		result->shaper = result->display->device->shape_driver.CreateShaper(result);
     2.5  		if(result->shaper != NULL) {
     2.6  			result->shaper->usershownflag = flags & SDL_WINDOW_SHOWN;
     2.7 -			result->shaper->alphacutoff = 1;
     2.8 +			result->shaper->mode.mode = ShapeModeDefault;
     2.9 +			result->shaper->mode.parameters.binarizationCutoff = 1;
    2.10  			result->shaper->hasshape = SDL_FALSE;
    2.11  			return result;
    2.12  		}
    2.13 @@ -55,12 +56,13 @@
    2.14  }
    2.15  
    2.16  /* REQUIRES that bitmap point to a w-by-h bitmap with 1bpp. */
    2.17 -void SDL_CalculateShapeBitmap(Uint8 alphacutoff,SDL_Surface *shape,Uint8* bitmap,Uint8 ppb,Uint8 value) {
    2.18 +void SDL_CalculateShapeBitmap(SDL_WindowShapeMode mode,SDL_Surface *shape,Uint8* bitmap,Uint8 ppb,Uint8 value) {
    2.19  	int x = 0;
    2.20  	int y = 0;
    2.21  	Uint8 r = 0,g = 0,b = 0,alpha = 0;
    2.22  	Uint8* pixel = NULL;
    2.23  	Uint32 bitmap_pixel,pixel_value = 0;
    2.24 +	SDL_Color key;
    2.25  	if(SDL_MUSTLOCK(shape))
    2.26  		SDL_LockSurface(shape);
    2.27  	pixel = (Uint8*)shape->pixels;
    2.28 @@ -82,7 +84,21 @@
    2.29  			}
    2.30  			SDL_GetRGBA(pixel_value,shape->format,&r,&g,&b,&alpha);
    2.31  			bitmap_pixel = y*shape->w + x;
    2.32 -			bitmap[bitmap_pixel / ppb] |= (alpha >= alphacutoff ? value : 0) << ((ppb - 1) - (bitmap_pixel % ppb));
    2.33 +			switch(mode.mode) {
    2.34 +				case(ShapeModeDefault):
    2.35 +					bitmap[bitmap_pixel / ppb] |= (alpha >= 1 ? value : 0) << ((ppb - 1) - (bitmap_pixel % ppb));
    2.36 +					break;
    2.37 +				case(ShapeModeBinarizeAlpha):
    2.38 +					bitmap[bitmap_pixel / ppb] |= (alpha >= mode.parameters.binarizationCutoff ? value : 0) << ((ppb - 1) - (bitmap_pixel % ppb));
    2.39 +					break;
    2.40 +				case(ShapeModeReverseBinarizeAlpha):
    2.41 +					bitmap[bitmap_pixel / ppb] |= (alpha <= mode.parameters.binarizationCutoff ? value : 0) << ((ppb - 1) - (bitmap_pixel % ppb));
    2.42 +					break;
    2.43 +				case(ShapeModeColorKey):
    2.44 +					key = mode.parameters.colorKey;
    2.45 +					bitmap[bitmap_pixel / ppb] |= (key.r == r && key.g == g && key.b == b ? value : 0) << ((ppb - 1) - (bitmap_pixel % ppb));
    2.46 +					break;
    2.47 +			}
    2.48  		}
    2.49  	}
    2.50  	if(SDL_MUSTLOCK(shape))
    2.51 @@ -98,18 +114,8 @@
    2.52  		//Invalid shape argument.
    2.53  		return SDL_INVALID_SHAPE_ARGUMENT;
    2.54  	
    2.55 -	if(shapeMode != NULL) {
    2.56 -		switch(shapeMode->mode) {
    2.57 -			case ShapeModeDefault: {
    2.58 -				window->shaper->alphacutoff = 1;
    2.59 -				break;
    2.60 -			}
    2.61 -			case ShapeModeBinarizeAlpha: {
    2.62 -				window->shaper->alphacutoff = shapeMode->parameters.binarizationCutoff;
    2.63 -				break;
    2.64 -			}
    2.65 -		}
    2.66 -	}
    2.67 +	if(shapeMode != NULL)
    2.68 +		window->shaper->mode = *shapeMode;
    2.69  	//TODO: Platform-specific implementations of SetWindowShape.  X11 is finished.  Win32 is finished.  Debugging is in progress on both.
    2.70  	result = window->display->device->shape_driver.SetWindowShape(window->shaper,shape,shapeMode);
    2.71  	window->shaper->hasshape = SDL_TRUE;
    2.72 @@ -137,12 +143,7 @@
    2.73  				return SDL_WINDOW_LACKS_SHAPE;
    2.74  		}
    2.75  		else {
    2.76 -			if(window->shaper->alphacutoff != 1) {
    2.77 -				shapeMode->mode = ShapeModeBinarizeAlpha;
    2.78 -				shapeMode->parameters.binarizationCutoff = window->shaper->alphacutoff;
    2.79 -			}
    2.80 -			else
    2.81 -				shapeMode->mode = ShapeModeDefault;
    2.82 +			*shapeMode = window->shaper->mode;
    2.83  			return 0;
    2.84  		}
    2.85  	}
     3.1 --- a/src/video/SDL_sysvideo.h	Tue Jul 20 12:42:43 2010 -0400
     3.2 +++ b/src/video/SDL_sysvideo.h	Thu Jul 22 23:11:01 2010 -0400
     3.3 @@ -144,9 +144,8 @@
     3.4      /* The user's specified SDL_WINDOW_SHOWN flag, for use once the user gives the window a shape. */
     3.5      Uint32 usershownflag;
     3.6      
     3.7 -    /* The cutoff value for alpha-channel binarization.  When alpha is greater-than-or-equal-to this value in the shape
     3.8 -       image, the corresponding pixel of the actual window will be considered part of the window's shape. */
     3.9 -    Uint8 alphacutoff;
    3.10 +    /* The parameters for shape calculation. */
    3.11 +    SDL_WindowShapeMode mode;
    3.12      
    3.13      /* Has this window been assigned a shape? */
    3.14      SDL_bool hasshape;
     4.1 --- a/src/video/win32/SDL_win32shape.c	Tue Jul 20 12:42:43 2010 -0400
     4.2 +++ b/src/video/win32/SDL_win32shape.c	Thu Jul 22 23:11:01 2010 -0400
     4.3 @@ -26,7 +26,8 @@
     4.4  SDL_WindowShaper* Win32_CreateShaper(SDL_Window * window) {
     4.5  	SDL_WindowShaper* result = malloc(sizeof(SDL_WindowShaper));
     4.6  	result->window = window;
     4.7 -	result->alphacutoff = 0;
     4.8 +	result->mode.mode = ShapeModeDefault;
     4.9 +	result->mode.parameters.binarizationCutoff = 1;
    4.10  	result->usershownflag = 0;
    4.11  	//Put some driver-data here.
    4.12  	window->shaper = result;
    4.13 @@ -42,7 +43,6 @@
    4.14  	if(shape->w != shaper->window->w || shape->h != shaper->window->h)
    4.15  		return -3;
    4.16  	
    4.17 -	/* Assume that shaper->alphacutoff already has a value, because SDL_SetWindowShape() should have given it one. */
    4.18  	/*
    4.19  	 * Start with empty region 
    4.20  	 */
    4.21 @@ -57,7 +57,7 @@
    4.22  	/*
    4.23  	 * Transfer binarized mask image into workbuffer 
    4.24  	 */
    4.25 -	SDL_CalculateShapeBitmap(shaper->alphacutoff,shape,data->shapebuffer,1,0xff);
    4.26 +	SDL_CalculateShapeBitmap(shaper->mode,shape,data->shapebuffer,1,0xff);
    4.27  	
    4.28  	//Move code over to here from AW_windowShape.c
    4.29  	Uint8 *pos1 = data->shapebuffer + width - 1;
    4.30 @@ -338,6 +338,8 @@
    4.31  			return -1;
    4.32  		}
    4.33  	}
    4.34 +	else
    4.35 +		memset(data->shapebuffer,0,data->buffersize);
    4.36  	
    4.37  	window->shaper->usershownflag |= window->flags & SDL_WINDOW_SHOWN;
    4.38  	
     5.1 --- a/src/video/x11/SDL_x11shape.c	Tue Jul 20 12:42:43 2010 -0400
     5.2 +++ b/src/video/x11/SDL_x11shape.c	Thu Jul 22 23:11:01 2010 -0400
     5.3 @@ -32,7 +32,8 @@
     5.4  	if (SDL_X11_HAVE_XSHAPE) {  /* Make sure X server supports it. */
     5.5  		result = malloc(sizeof(SDL_WindowShaper));
     5.6  		result->window = window;
     5.7 -		result->alphacutoff = 0;
     5.8 +		result->mode.mode = ShapeModeDefault;
     5.9 +		result->mode.parameters.binarizationCutoff = 1;
    5.10  		result->usershownflag = 0;
    5.11  		SDL_ShapeData* data = malloc(sizeof(SDL_ShapeData));
    5.12  		result->driverdata = data;
    5.13 @@ -65,6 +66,8 @@
    5.14  			return -1;
    5.15  		}
    5.16  	}
    5.17 +	else
    5.18 +		memset(data->bitmap,0,data->bitmapsize);
    5.19  	
    5.20  	window->shaper->usershownflag |= window->flags & SDL_WINDOW_SHOWN;
    5.21  	
    5.22 @@ -83,7 +86,7 @@
    5.23  	SDL_ShapeData *data = shaper->driverdata;
    5.24  	
    5.25  	/* Assume that shaper->alphacutoff already has a value, because SDL_SetWindowShape() should have given it one. */
    5.26 -	SDL_CalculateShapeBitmap(shaper->alphacutoff,shape,data->bitmap,8,1);
    5.27 +	SDL_CalculateShapeBitmap(shaper->mode,shape,data->bitmap,8,1);
    5.28  		
    5.29  	SDL_WindowData *windowdata = (SDL_WindowData*)(shaper->window->driverdata);
    5.30  	Pixmap shapemask = XCreateBitmapFromData(windowdata->videodata->display,windowdata->xwindow,data->bitmap,shaper->window->w,shaper->window->h);