From 9476867e79b56f051ff343af7fe661b401f9cff1 Mon Sep 17 00:00:00 2001 From: Eli Gottlieb Date: Tue, 6 Jul 2010 22:05:22 -0400 Subject: [PATCH] Updated test code, updated win32 code a bit (still not complete, but hopefully tonight), and removed the last vestiges of ellipse and polygon drawing support. --- include/SDL_ellipse.h | 92 -------------------------- include/SDL_poly.h | 110 ------------------------------- include/SDL_video.h | 2 - src/video/SDL_shape.c | 6 +- src/video/win32/SDL_win32shape.c | 63 +++++++++++++++++- src/video/x11/SDL_x11shape.c | 5 +- test/testeyes.c | 35 ++++++---- 7 files changed, 88 insertions(+), 225 deletions(-) delete mode 100644 include/SDL_ellipse.h delete mode 100644 include/SDL_poly.h diff --git a/include/SDL_ellipse.h b/include/SDL_ellipse.h deleted file mode 100644 index bfa0f0402..000000000 --- a/include/SDL_ellipse.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 2010 Eli Gottlieb - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Eli Gottlieb - eligottlieb@gmail.com -*/ - -/** - * \file SDL_ellipse.h - * - * Header file for SDL_ellipse definition and management functions. - */ - -#ifndef _SDL_ellipse_h -#define _SDL_ellipse_h - -#include "SDL_stdinc.h" -#include "SDL_error.h" -#include "SDL_pixels.h" -#include "SDL_rwops.h" - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -/* *INDENT-OFF* */ -extern "C" { -/* *INDENT-ON* */ -#endif - -/** - * \brief The structure that defines an ellipse. - * - * \sa SDL_EllipseEmpty - * \sa SDL_EllipseEquals - * \sa SDL_EllipsesIntersect - * \sa SDL_IntersectEllipseAndLine - */ -typedef struct SDL_Ellipse { - int x,y; - int a,b; - int r; -} SDL_Ellipse; - -/** - * \brief Returns true if the ellipse has no area. - */ -#define SDL_EllipseEmpty(X) ((X)->r <= 0) - -/** - * \brief Returns true if the two ellipses are equal. - */ -#define SDL_EllipseEquals(A, B) (((A)->x == (B)->x) && ((A)->y == (B)->y) && \ - ((A)->a == (B)->a) && ((A)->b == (B)->b) && ((A)->r == (B)->r)) - -/** - * \brief Determine whether two ellipses intersect. - * - * \return SDL_TRUE if there is an intersection, SDL_FALSE otherwise. - */ -extern DECLSPEC SDL_bool SDLCALL SDL_EllipsesIntersect(const SDL_Ellipse * A,const SDL_Ellipse * B); - -/** - * \brief Calculate the intersection of an ellipse and line segment. - * - * \return SDL_TRUE if there is an intersection, SDL_FALSE otherwise. - */ -extern DECLSPEC SDL_bool SDLCALL SDL_IntersectEllipseAndLine(const SDL_Ellipse *ellipse,int *X1,int *Y1,int *X2,int *Y2); - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -/* *INDENT-OFF* */ -} -/* *INDENT-ON* */ -#endif -#include "close_code.h" - -#endif /* _SDL_ellipse_h */ diff --git a/include/SDL_poly.h b/include/SDL_poly.h deleted file mode 100644 index 1192daf95..000000000 --- a/include/SDL_poly.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 2010 Eli Gottlieb - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Eli Gottlieb - eligottlieb@gmail.com -*/ - -/** - * \file SDL_poly.h - * - * Header file for SDL_poly definition and management functions. - */ - -#ifndef _SDL_poly_h -#define _SDL_poly_h - -#include "SDL_stdinc.h" -#include "SDL_error.h" -#include "SDL_pixels.h" -#include "SDL_rwops.h" -#include "SDL_rect.h" - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -/* *INDENT-OFF* */ -extern "C" { -/* *INDENT-ON* */ -#endif - -/** - * \brief The structure that defines an polygon. - * - * \sa SDL_PolyEmpty - * \sa SDL_PolyEquals - * \sa SDL_PolysIntersect - * \sa SDL_IntersectPoly - * \sa SDL_WrapPoints - * \sa SDL_IntersectPolyAndLine - */ -typedef struct SDL_Poly { - SDL_Point *vertices; - int count; -} SDL_Poly; - -/** - * \brief Returns true if the polygon has no area. - */ -#define SDL_PolyEmpty(X) (((X)->vertices == NULL) || ((X)->count <= 2)) - -/** - * \brief Determine whether two polygons are equal. - * - * \return SDL_TRUE if the polygons are equal, SDL_FALSE otherwise. - */ -extern DECLSPEC SDL_bool SDLCALL SDL_PolyEquals(const SDL_Poly *A,const SDL_Poly *B); - -/** - * \brief Determine whether two rectangles intersect. - * - * \return SDL_TRUE if there is an intersection, SDL_FALSE otherwise. - */ -extern DECLSPEC SDL_bool SDLCALL SDL_PolysIntersect(const SDL_Poly * A,const SDL_Poly * B); - -/** - * \brief Calculate the intersection of two rectangles. - * - * \return SDL_TRUE if there is an intersection, SDL_FALSE otherwise. - */ -extern DECLSPEC SDL_bool SDLCALL SDL_IntersectPoly(const SDL_Poly * A,const SDL_Poly * B,SDL_Poly * result); - -/** - * \brief Calculate a minimal polygon wrapping a set of points - * - * \return 0 on success, -1 if the parameters were invalid, and -2 if an insufficient number of points were supplied - * in the output polygon. - */ -extern DECLSPEC int SDLCALL SDL_WrapPoints(const SDL_Point * points,int count,SDL_Poly *result); - -/** - * \brief Calculate the intersection of a polygon and line segment. - * - * \return SDL_TRUE if there is an intersection, SDL_FALSE otherwise. - */ -extern DECLSPEC SDL_bool SDLCALL SDL_IntersectPolyAndLine(const SDL_Poly *poly,int *X1,int *Y1,int *X2,int *Y2); - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -/* *INDENT-OFF* */ -} -/* *INDENT-ON* */ -#endif -#include "close_code.h" - -#endif /* _SDL_poly_h */ diff --git a/include/SDL_video.h b/include/SDL_video.h index 0ca914b38..a0db406cd 100644 --- a/include/SDL_video.h +++ b/include/SDL_video.h @@ -32,8 +32,6 @@ #include "SDL_stdinc.h" #include "SDL_pixels.h" #include "SDL_rect.h" -#include "SDL_ellipse.h" -#include "SDL_poly.h" #include "SDL_surface.h" #include "begin_code.h" diff --git a/src/video/SDL_shape.c b/src/video/SDL_shape.c index 2d65619da..6c00a25e3 100644 --- a/src/video/SDL_shape.c +++ b/src/video/SDL_shape.c @@ -45,7 +45,7 @@ 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) { +void SDL_CalculateShapeBitmap(Uint8 alphacutoff,SDL_Surface *shape,Uint8* bitmap,Uint8 ppb,Uint8 value) { if(SDL_MUSTLOCK(shape)) SDL_LockSurface(shape); int x = 0,y = 0; @@ -55,7 +55,7 @@ void SDL_CalculateShapeBitmap(Uint8 alphacutoff,SDL_Surface *shape,Uint8* bitmap Uint8 alpha = 0; SDL_GetRGBA(*(Uint32*)pixel,shape->format,NULL,NULL,NULL,&alpha); Uint32 bitmap_pixel = y*shape->w + x; - bitmap[bitmap_pixel / 8] |= (alpha >= alphacutoff ? 1 : 0) << (8 - (bitmap_pixel % 8)); + bitmap[bitmap_pixel / ppb] |= (alpha >= alphacutoff ? value : 0) << ((ppb - 1) - (bitmap_pixel % ppb)); } if(SDL_MUSTLOCK(shape)) SDL_UnlockSurface(shape); @@ -81,7 +81,7 @@ int SDL_SetWindowShape(SDL_Window *window,SDL_Surface *shape,SDL_WindowShapeMode } } } - //TODO: Platform-specific implementations of SetWindowShape. X11 is in-progress. + //TODO: Platform-specific implementations of SetWindowShape. X11 is finished. Win32 is in progress. int result = window->display->device->shape_driver.SetWindowShape(window->shaper,shape,shapeMode); window->shaper->hasshape = SDL_TRUE; if(window->shaper->usershownflag & SDL_WINDOW_SHOWN == SDL_WINDOW_SHOWN) { diff --git a/src/video/win32/SDL_win32shape.c b/src/video/win32/SDL_win32shape.c index 1a27e8478..960095be9 100644 --- a/src/video/win32/SDL_win32shape.c +++ b/src/video/win32/SDL_win32shape.c @@ -20,6 +20,65 @@ eligottlieb@gmail.com */ -#include "SDL_shape.h" +#include +#include "SDL_win32shape.h" -/* Functions implementing shaped windows for Win32 will be implemented when the API is set. */ +SDL_WindowShaper* Win32_CreateShaper(SDL_Window * window) { + SDL_WindowShaper* result = malloc(sizeof(SDL_WindowShaper)); + result->window = window; + result->alphacutoff = 0; + result->usershownflag = 0; + //Put some driver-data here. + window->shaper = result; + int resized_properly = X11ResizeWindowShape(window); + assert(resized_properly == 0); + return result; +} + +int Win32_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shapeMode) { + assert(shaper != NULL && shape != NULL); + if(!SDL_ISPIXELFORMAT_ALPHA(SDL_MasksToPixelFormatEnum(shape->format->BitsPerPixel,shape->format->Rmask,shape->format->Gmask,shape->format->Bmask,shape->format->Amask))) + return -2; + 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 + */ + HRGN MaskRegion = CreateRectRgn(0, 0, 0, 0); + + unsigned int pitch = shape->pitch; + unsigned int width = shape->width; + unsigned int height = shape->height; + unsigned int dy = pitch - width; + + SDL_ShapeData *data = (SDL_ShapeData*)shaper->driverdata; + /* + * Transfer binarized mask image into workbuffer + */ + SDL_CalculateShapeBitmap(shaper->alphacutoff,shape,data->shapebuffer,1,0xff); + //Move code over to here from AW_windowShape.c + +} + +int Win32_ResizeWindowShape(SDL_Window *window) { + SDL_ShapeData* data = window->shaper->driverdata; + assert(data != NULL); + + unsigned int buffersize = window->w * window->h; + if(data->buffersize != buffersize || data->shapebuffer == NULL) { + data->buffersize = buffersize; + if(data->shapebuffer != NULL) + free(data->shapebuffer); + data->shapebuffer = malloc(data->buffersize); + if(data->shapebuffer == NULL) { + SDL_SetError("Could not allocate memory for shaped-window bitmap."); + return -1; + } + } + + window->shaper->usershownflag = window->flags & SDL_WINDOW_SHOWN; + + return 0; +} diff --git a/src/video/x11/SDL_x11shape.c b/src/video/x11/SDL_x11shape.c index 432ddc722..9336c18cd 100644 --- a/src/video/x11/SDL_x11shape.c +++ b/src/video/x11/SDL_x11shape.c @@ -62,6 +62,7 @@ int X11_ResizeWindowShape(SDL_Window* window) { } int X11_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shapeMode) { + assert(shaper != NULL && shape != NULL); if(!SDL_ISPIXELFORMAT_ALPHA(SDL_MasksToPixelFormatEnum(shape->format->BitsPerPixel,shape->format->Rmask,shape->format->Gmask,shape->format->Bmask,shape->format->Amask))) return -2; if(shape->w != shaper->window->w || shape->h != shaper->window->h) @@ -69,8 +70,8 @@ int X11_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowSha SDL_ShapeData *data = shaper->driverdata; assert(data != NULL); - /* Assume that shaper->alphacutoff already has a value. */ - SDL_CalculateShapeBitmap(shaper->alphacutoff,shape,data->bitmap); + /* 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_WindowData *windowdata = (SDL_WindowData*)(shaper->window->driverdata); Pixmap shapemask = XCreateBitmapFromData(windowdata->videodata->display,windowdata->xwindow,data->bitmap,shaper->window->w,shaper->window->h); diff --git a/test/testeyes.c b/test/testeyes.c index 66e73a0f7..c70fdb614 100644 --- a/test/testeyes.c +++ b/test/testeyes.c @@ -143,7 +143,7 @@ int main(int argc,char** argv) { exit(-3); } - SDL_Color bnw_palette[2] = {{0,0,0,0},{255,255,255,255}}; + SDL_Color bnw_palette[2] = {{0,0,0,255},{255,255,255,255}}; SDL_Texture *eyes_texture = SDL_CreateTexture(SDL_PIXELFORMAT_INDEX1LSB,SDL_TEXTUREACCESS_STREAMING,eyes_width,eyes_height); if(eyes_texture == NULL) { SDL_DestroyRenderer(window); @@ -162,8 +162,11 @@ int main(int argc,char** argv) { memcpy(pixels+pitch*row,eyes_bits+(eyes_width/8)*row,eyes_width/8); SDL_UnlockTexture(eyes_texture); - SDL_Texture *mask_texture = SDL_CreateTexture(SDL_PIXELFORMAT_INDEX1LSB,SDL_TEXTUREACCESS_STREAMING,eyesmask_width,eyesmask_height); - if(mask_texture == NULL) { + int bpp = 0; + Uint32 r = 0,g = 0,b = 0,a = 0; + SDL_PixelFormatEnumToMasks(SDL_PIXELFORMAT_ARGB4444,&bpp,&r,&g,&b,&a); + SDL_Surface *mask = SDL_CreateRGBSurface(0,eyesmask_width,eyesmask_height,bpp,r,g,b,a); + if(mask == NULL) { SDL_DestroyTexture(eyes_texture); SDL_DestroyRenderer(window); SDL_DestroyWindow(window); @@ -171,19 +174,20 @@ int main(int argc,char** argv) { printf("Could not create shape mask texture.\n"); exit(-5); } - SDL_SetTexturePalette(mask_texture,bnw_palette,0,2); - rect.x = rect.y = 0; - rect.w = eyesmask_width; - rect.h = eyesmask_height; - SDL_LockTexture(mask_texture,&rect,1,&pixels,&pitch); - for(int row = 0;rowpixels; + for(int y=0;yformat,0,0,0,alpha); + } + if(SDL_MUSTLOCK(mask)) + SDL_UnlockSurface(mask); - SDL_SelectShapeRenderer(window); - SDL_RenderCopy(mask_texture,&rect,&rect); - SDL_RenderPresent(); + SDL_WindowShapeMode mode = {ShapeModeDefault,1}; + SDL_SetWindowShape(window,mask,&mode); SDL_Event event; int event_pending = 0; @@ -203,6 +207,9 @@ int main(int argc,char** argv) { event_pending = SDL_PollEvent(&event); } + SDL_FreeSurface(mask); + SDL_DestroyTexture(eyes_texture); + SDL_DestroyWindow(window); //Call SDL_VideoQuit() before quitting. SDL_VideoQuit(); }