Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Commit

Permalink
Switched over to poly-polygon region building and shape-tree traversa…
Browse files Browse the repository at this point in the history
…l for Win32.
  • Loading branch information
egottlieb committed Aug 10, 2010
1 parent 5280bdb commit 27bf3ec
Showing 1 changed file with 46 additions and 18 deletions.
64 changes: 46 additions & 18 deletions src/video/win32/SDL_win32shape.c
Expand Up @@ -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;
Expand All @@ -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;
}
Expand Down

0 comments on commit 27bf3ec

Please sign in to comment.