diff options
author | egottlieb <none@none> | 2010-08-10 15:39:46 -0400 |
---|---|---|
committer | egottlieb <none@none> | 2010-08-10 15:39:46 -0400 |
commit | f3f20e2df19ad51f71a320bb03c407fdd7037094 (patch) | |
tree | b70c9f1ddd9323e4d7fd299689cdb6350ef8206e /src | |
parent | b60c431a34d43cecb5abd8e869a447148e1aed17 (diff) |
Switched over to poly-polygon region building and shape-tree traversal for Win32.
Diffstat (limited to 'src')
-rw-r--r-- | src/video/win32/SDL_win32shape.c | 64 |
1 files changed, 46 insertions, 18 deletions
diff --git a/src/video/win32/SDL_win32shape.c b/src/video/win32/SDL_win32shape.c index 89fc59c317..747635c570 100644 --- a/src/video/win32/SDL_win32shape.c +++ b/src/video/win32/SDL_win32shape.c @@ -42,22 +42,40 @@ Win32_CreateShaper(SDL_Window * window) { 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 @@ Win32_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShape data = (SDL_ShapeData*)shaper->driverdata; if(data->mask_tree != NULL) SDL_FreeShapeTree(&data->mask_tree); - data->mask_tree = SDL_CalculateShapeTree(*shapeMode,shape,SDL_FALSE); - - /* - * Start with empty region - */ - mask_region = CreateRectRgn(0, 0, 0, 0); - - SDL_TraverseShapeTree(data->mask_tree,&CombineRectRegions,&mask_region); + data->mask_tree = SDL_CalculateShapeTree(*shapeMode,shape); + SDL_TraverseShapeTree(data->mask_tree,&CombineRectRegions,&rects); + num_rects = num_shape_rects(rects); + polygonVertexNumbers = (int*)SDL_malloc(sizeof(int)*num_rects); + for(i=0;i<num_rects;i++) + polygonVertexNumbers[i] = 4; + polygons = (POINT*)SDL_malloc(sizeof(POINT)*4*num_rects); + for(i=0;i<num_rects*4;i++) { + polygons[i] = rects[i / 4].corners[i % 4]; + if(i % 4 == 3) { + old = rects; + rects = rects->next; + 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; } |