From 217dd8b7b13aac76e2a5dbcfc66af5806938ada2 Mon Sep 17 00:00:00 2001 From: Eli Gottlieb Date: Thu, 22 Jul 2010 23:11:01 -0400 Subject: [PATCH] Added color-key mode and redid the code to work with it. --- include/SDL_shape.h | 7 +++++- src/video/SDL_shape.c | 43 ++++++++++++++++---------------- src/video/SDL_sysvideo.h | 5 ++-- src/video/win32/SDL_win32shape.c | 8 +++--- src/video/x11/SDL_x11shape.c | 7 ++++-- 5 files changed, 40 insertions(+), 30 deletions(-) diff --git a/include/SDL_shape.h b/include/SDL_shape.h index f5e7ec66d..830052638 100644 --- a/include/SDL_shape.h +++ b/include/SDL_shape.h @@ -83,12 +83,17 @@ typedef enum { /** \brief The default mode, a binarized alpha cutoff of 1. */ ShapeModeDefault, /** \brief A binarized alpha cutoff with a given integer value. */ - ShapeModeBinarizeAlpha + ShapeModeBinarizeAlpha, + /** \brief A binarized alpha cutoff with a given integer value, but with the opposite comparison. */ + ShapeModeReverseBinarizeAlpha, + /** \brief A color key is applied. */ + ShapeModeColorKey } WindowShapeMode; /** \brief A union containing parameters for shaped windows. */ typedef union { /** \brief a cutoff alpha value for binarization of the window shape's alpha channel. */ Uint8 binarizationCutoff; + SDL_Color colorKey; } SDL_WindowShapeParams; /** \brief A struct that tags the SDL_WindowShapeParams union with an enum describing the type of its contents. */ diff --git a/src/video/SDL_shape.c b/src/video/SDL_shape.c index 9a6d04d9e..ac3edf991 100644 --- a/src/video/SDL_shape.c +++ b/src/video/SDL_shape.c @@ -34,7 +34,8 @@ SDL_Window* SDL_CreateShapedWindow(const char *title,unsigned int x,unsigned int result->shaper = result->display->device->shape_driver.CreateShaper(result); if(result->shaper != NULL) { result->shaper->usershownflag = flags & SDL_WINDOW_SHOWN; - result->shaper->alphacutoff = 1; + result->shaper->mode.mode = ShapeModeDefault; + result->shaper->mode.parameters.binarizationCutoff = 1; result->shaper->hasshape = SDL_FALSE; return result; } @@ -55,12 +56,13 @@ SDL_bool SDL_IsShapedWindow(const SDL_Window *window) { } /* REQUIRES that bitmap point to a w-by-h bitmap with 1bpp. */ -void SDL_CalculateShapeBitmap(Uint8 alphacutoff,SDL_Surface *shape,Uint8* bitmap,Uint8 ppb,Uint8 value) { +void SDL_CalculateShapeBitmap(SDL_WindowShapeMode mode,SDL_Surface *shape,Uint8* bitmap,Uint8 ppb,Uint8 value) { int x = 0; int y = 0; Uint8 r = 0,g = 0,b = 0,alpha = 0; Uint8* pixel = NULL; Uint32 bitmap_pixel,pixel_value = 0; + SDL_Color key; if(SDL_MUSTLOCK(shape)) SDL_LockSurface(shape); pixel = (Uint8*)shape->pixels; @@ -82,7 +84,21 @@ void SDL_CalculateShapeBitmap(Uint8 alphacutoff,SDL_Surface *shape,Uint8* bitmap } SDL_GetRGBA(pixel_value,shape->format,&r,&g,&b,&alpha); bitmap_pixel = y*shape->w + x; - bitmap[bitmap_pixel / ppb] |= (alpha >= alphacutoff ? value : 0) << ((ppb - 1) - (bitmap_pixel % ppb)); + switch(mode.mode) { + case(ShapeModeDefault): + bitmap[bitmap_pixel / ppb] |= (alpha >= 1 ? value : 0) << ((ppb - 1) - (bitmap_pixel % ppb)); + break; + case(ShapeModeBinarizeAlpha): + bitmap[bitmap_pixel / ppb] |= (alpha >= mode.parameters.binarizationCutoff ? value : 0) << ((ppb - 1) - (bitmap_pixel % ppb)); + break; + case(ShapeModeReverseBinarizeAlpha): + bitmap[bitmap_pixel / ppb] |= (alpha <= mode.parameters.binarizationCutoff ? value : 0) << ((ppb - 1) - (bitmap_pixel % ppb)); + break; + case(ShapeModeColorKey): + key = mode.parameters.colorKey; + bitmap[bitmap_pixel / ppb] |= (key.r == r && key.g == g && key.b == b ? value : 0) << ((ppb - 1) - (bitmap_pixel % ppb)); + break; + } } } if(SDL_MUSTLOCK(shape)) @@ -98,18 +114,8 @@ int SDL_SetWindowShape(SDL_Window *window,SDL_Surface *shape,SDL_WindowShapeMode //Invalid shape argument. return SDL_INVALID_SHAPE_ARGUMENT; - if(shapeMode != NULL) { - switch(shapeMode->mode) { - case ShapeModeDefault: { - window->shaper->alphacutoff = 1; - break; - } - case ShapeModeBinarizeAlpha: { - window->shaper->alphacutoff = shapeMode->parameters.binarizationCutoff; - break; - } - } - } + if(shapeMode != NULL) + window->shaper->mode = *shapeMode; //TODO: Platform-specific implementations of SetWindowShape. X11 is finished. Win32 is finished. Debugging is in progress on both. result = window->display->device->shape_driver.SetWindowShape(window->shaper,shape,shapeMode); window->shaper->hasshape = SDL_TRUE; @@ -137,12 +143,7 @@ int SDL_GetShapedWindowMode(SDL_Window *window,SDL_WindowShapeMode *shapeMode) { return SDL_WINDOW_LACKS_SHAPE; } else { - if(window->shaper->alphacutoff != 1) { - shapeMode->mode = ShapeModeBinarizeAlpha; - shapeMode->parameters.binarizationCutoff = window->shaper->alphacutoff; - } - else - shapeMode->mode = ShapeModeDefault; + *shapeMode = window->shaper->mode; return 0; } } diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index 2e4980048..b8508740a 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -144,9 +144,8 @@ struct SDL_WindowShaper /* The user's specified SDL_WINDOW_SHOWN flag, for use once the user gives the window a shape. */ Uint32 usershownflag; - /* The cutoff value for alpha-channel binarization. When alpha is greater-than-or-equal-to this value in the shape - image, the corresponding pixel of the actual window will be considered part of the window's shape. */ - Uint8 alphacutoff; + /* The parameters for shape calculation. */ + SDL_WindowShapeMode mode; /* Has this window been assigned a shape? */ SDL_bool hasshape; diff --git a/src/video/win32/SDL_win32shape.c b/src/video/win32/SDL_win32shape.c index c062d3bcc..4c3d202ca 100644 --- a/src/video/win32/SDL_win32shape.c +++ b/src/video/win32/SDL_win32shape.c @@ -26,7 +26,8 @@ SDL_WindowShaper* Win32_CreateShaper(SDL_Window * window) { SDL_WindowShaper* result = malloc(sizeof(SDL_WindowShaper)); result->window = window; - result->alphacutoff = 0; + result->mode.mode = ShapeModeDefault; + result->mode.parameters.binarizationCutoff = 1; result->usershownflag = 0; //Put some driver-data here. window->shaper = result; @@ -42,7 +43,6 @@ int Win32_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowS if(shape->w != shaper->window->w || shape->h != shaper->window->h) return -3; - /* Assume that shaper->alphacutoff already has a value, because SDL_SetWindowShape() should have given it one. */ /* * Start with empty region */ @@ -57,7 +57,7 @@ int Win32_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowS /* * Transfer binarized mask image into workbuffer */ - SDL_CalculateShapeBitmap(shaper->alphacutoff,shape,data->shapebuffer,1,0xff); + SDL_CalculateShapeBitmap(shaper->mode,shape,data->shapebuffer,1,0xff); //Move code over to here from AW_windowShape.c Uint8 *pos1 = data->shapebuffer + width - 1; @@ -338,6 +338,8 @@ int Win32_ResizeWindowShape(SDL_Window *window) { return -1; } } + else + memset(data->shapebuffer,0,data->buffersize); window->shaper->usershownflag |= window->flags & SDL_WINDOW_SHOWN; diff --git a/src/video/x11/SDL_x11shape.c b/src/video/x11/SDL_x11shape.c index ffe064f3a..36d5fa2e2 100644 --- a/src/video/x11/SDL_x11shape.c +++ b/src/video/x11/SDL_x11shape.c @@ -32,7 +32,8 @@ SDL_WindowShaper* X11_CreateShaper(SDL_Window* window) { if (SDL_X11_HAVE_XSHAPE) { /* Make sure X server supports it. */ result = malloc(sizeof(SDL_WindowShaper)); result->window = window; - result->alphacutoff = 0; + result->mode.mode = ShapeModeDefault; + result->mode.parameters.binarizationCutoff = 1; result->usershownflag = 0; SDL_ShapeData* data = malloc(sizeof(SDL_ShapeData)); result->driverdata = data; @@ -65,6 +66,8 @@ int X11_ResizeWindowShape(SDL_Window* window) { return -1; } } + else + memset(data->bitmap,0,data->bitmapsize); window->shaper->usershownflag |= window->flags & SDL_WINDOW_SHOWN; @@ -83,7 +86,7 @@ int X11_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowSha SDL_ShapeData *data = shaper->driverdata; /* Assume that shaper->alphacutoff already has a value, because SDL_SetWindowShape() should have given it one. */ - SDL_CalculateShapeBitmap(shaper->alphacutoff,shape,data->bitmap,8,1); + SDL_CalculateShapeBitmap(shaper->mode,shape,data->bitmap,8,1); SDL_WindowData *windowdata = (SDL_WindowData*)(shaper->window->driverdata); Pixmap shapemask = XCreateBitmapFromData(windowdata->videodata->display,windowdata->xwindow,data->bitmap,shaper->window->w,shaper->window->h);