summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authoregottlieb <none@none>2010-08-10 15:39:46 -0400
committeregottlieb <none@none>2010-08-10 15:39:46 -0400
commitf3f20e2df19ad51f71a320bb03c407fdd7037094 (patch)
treeb70c9f1ddd9323e4d7fd299689cdb6350ef8206e /src
parentb60c431a34d43cecb5abd8e869a447148e1aed17 (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.c64
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;
}