Switched over to poly-polygon region building and shape-tree traversal for Win32.
This commit is contained in:
parent
f294cf6a4c
commit
b6eeb0d250
1 changed files with 46 additions and 18 deletions
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue