# HG changeset patch # User egottlieb # Date 1281469186 14400 # Node ID c4f5bcaf75729f38b490c9d61a9c7d382e056f13 # Parent 0998d1b5dd23e8481947617105922aec54b002b2 Switched over to poly-polygon region building and shape-tree traversal for Win32. diff -r 0998d1b5dd23 -r c4f5bcaf7572 src/video/win32/SDL_win32shape.c --- a/src/video/win32/SDL_win32shape.c Mon Aug 09 20:32:15 2010 -0400 +++ b/src/video/win32/SDL_win32shape.c Tue Aug 10 15:39:46 2010 -0400 @@ -42,22 +42,40 @@ return result; } +typedef struct { + POINT corners[4]; + void* next; +} SDL_ShapeRect; + void -CombineRectRegions(SDL_ShapeTree* node, void* closure) { - HRGN* mask_region = (HRGN *)closure; +CombineRectRegions(SDL_ShapeTree* node,void* closure) { + SDL_ShapeRect* rect_list = *((SDL_ShapeRect**)closure); if(node->kind == OpaqueShape) { - HRGN temp_region = CreateRectRgn(node->data.shape.x,node->data.shape.y,node->data.shape.w,node->data.shape.h); - CombineRgn(*mask_region,*mask_region,temp_region, RGN_OR); - DeleteObject(temp_region); + SDL_ShapeRect* rect = SDL_malloc(sizeof(SDL_ShapeRect)); + rect->corners[0].x = node->data.shape.x; rect->corners[0].y = node->data.shape.y; + rect->corners[1].x = node->data.shape.x + node->data.shape.w; rect->corners[1].y = node->data.shape.y; + rect->corners[2].x = node->data.shape.x + node->data.shape.w; rect->corners[2].y = node->data.shape.y + node->data.shape.h; + rect->corners[3].x = node->data.shape.x; rect->corners[3].y = node->data.shape.y + node->data.shape.h; + rect->next = *((SDL_ShapeRect**)closure); + *((SDL_ShapeRect**)closure) = rect; } } +Uint32 num_shape_rects(SDL_ShapeRect* rect) { + if(rect == NULL) + return 0; + else + return 1 + num_shape_rects(rect->next); +} + int Win32_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shapeMode) { SDL_ShapeData *data; HRGN mask_region; - SDL_WindowData *windowdata; - HWND hwnd; + SDL_ShapeRect* rects = NULL,*old = NULL; + Uint16 num_rects = 0,i = 0; + int* polygonVertexNumbers = NULL; + POINT* polygons = NULL; if (shaper == NULL || shape == NULL) return SDL_INVALID_SHAPE_ARGUMENT; @@ -67,21 +85,31 @@ data = (SDL_ShapeData*)shaper->driverdata; if(data->mask_tree != NULL) SDL_FreeShapeTree(&data->mask_tree); - data->mask_tree = SDL_CalculateShapeTree(*shapeMode,shape,SDL_FALSE); + data->mask_tree = SDL_CalculateShapeTree(*shapeMode,shape); - /* - * Start with empty region - */ - mask_region = CreateRectRgn(0, 0, 0, 0); - - SDL_TraverseShapeTree(data->mask_tree,&CombineRectRegions,&mask_region); - + SDL_TraverseShapeTree(data->mask_tree,&CombineRectRegions,&rects); + num_rects = num_shape_rects(rects); + polygonVertexNumbers = (int*)SDL_malloc(sizeof(int)*num_rects); + for(i=0;inext; + SDL_free(old); + } + } + /* * Set the new region mask for the window */ - windowdata=(SDL_WindowData *)(shaper->window->driverdata); - hwnd = windowdata->hwnd; - SetWindowRgn(hwnd, mask_region, TRUE); + mask_region = CreatePolyPolygonRgn(polygons,polygonVertexNumbers,num_rects,WINDING); + SetWindowRgn(((SDL_WindowData *)(shaper->window->driverdata))->hwnd, mask_region, TRUE); + + SDL_free(polygons); + SDL_free(polygonVertexNumbers); return 0; }