Commit b6eeb0d2 authored by egottlieb's avatar egottlieb

Switched over to poly-polygon region building and shape-tree traversal for Win32.

parent f294cf6a
...@@ -42,22 +42,40 @@ Win32_CreateShaper(SDL_Window * window) { ...@@ -42,22 +42,40 @@ Win32_CreateShaper(SDL_Window * window) {
return result; return result;
} }
typedef struct {
POINT corners[4];
void* next;
} SDL_ShapeRect;
void void
CombineRectRegions(SDL_ShapeTree* node, void* closure) { CombineRectRegions(SDL_ShapeTree* node,void* closure) {
HRGN* mask_region = (HRGN *)closure; SDL_ShapeRect* rect_list = *((SDL_ShapeRect**)closure);
if(node->kind == OpaqueShape) { if(node->kind == OpaqueShape) {
HRGN temp_region = CreateRectRgn(node->data.shape.x,node->data.shape.y,node->data.shape.w,node->data.shape.h); SDL_ShapeRect* rect = SDL_malloc(sizeof(SDL_ShapeRect));
CombineRgn(*mask_region,*mask_region,temp_region, RGN_OR); rect->corners[0].x = node->data.shape.x; rect->corners[0].y = node->data.shape.y;
DeleteObject(temp_region); 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 int
Win32_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shapeMode) { Win32_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shapeMode) {
SDL_ShapeData *data; SDL_ShapeData *data;
HRGN mask_region; HRGN mask_region;
SDL_WindowData *windowdata; SDL_ShapeRect* rects = NULL,*old = NULL;
HWND hwnd; Uint16 num_rects = 0,i = 0;
int* polygonVertexNumbers = NULL;
POINT* polygons = NULL;
if (shaper == NULL || shape == NULL) if (shaper == NULL || shape == NULL)
return SDL_INVALID_SHAPE_ARGUMENT; return SDL_INVALID_SHAPE_ARGUMENT;
...@@ -67,21 +85,31 @@ Win32_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShape ...@@ -67,21 +85,31 @@ Win32_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShape
data = (SDL_ShapeData*)shaper->driverdata; data = (SDL_ShapeData*)shaper->driverdata;
if(data->mask_tree != NULL) if(data->mask_tree != NULL)
SDL_FreeShapeTree(&data->mask_tree); 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;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 * Set the new region mask for the window
*/ */
windowdata=(SDL_WindowData *)(shaper->window->driverdata); mask_region = CreatePolyPolygonRgn(polygons,polygonVertexNumbers,num_rects,WINDING);
hwnd = windowdata->hwnd; SetWindowRgn(((SDL_WindowData *)(shaper->window->driverdata))->hwnd, mask_region, TRUE);
SetWindowRgn(hwnd, mask_region, TRUE);
SDL_free(polygons);
SDL_free(polygonVertexNumbers);
return 0; return 0;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment