Mercurial > sdl-ios-xcode
comparison src/video/win32/SDL_win32shape.c @ 4850:14870d46ee2d
Mostly seem to have fixed SDL_CalculateShapeTree. Mostly. There still seem to be some rendering artifacts, stepping effects, and such on Windows -- which indicates subtle logic errors in SDL_CalculateShapeTree().
Oh well, back into the salt mine.
author | egottlieb |
---|---|
date | Sat, 14 Aug 2010 20:29:51 -0400 |
parents | 0b918c186938 |
children | 5624fb0190b5 |
comparison
equal
deleted
inserted
replaced
4849:0b918c186938 | 4850:14870d46ee2d |
---|---|
19 Eli Gottlieb | 19 Eli Gottlieb |
20 eligottlieb@gmail.com | 20 eligottlieb@gmail.com |
21 */ | 21 */ |
22 | 22 |
23 #include <stdio.h> | 23 #include <stdio.h> |
24 #include "SDL_assert.h" | |
24 #include "SDL_win32shape.h" | 25 #include "SDL_win32shape.h" |
25 #include "SDL_win32video.h" | 26 #include "SDL_win32video.h" |
26 | 27 |
27 SDL_WindowShaper* | 28 SDL_WindowShaper* |
28 Win32_CreateShaper(SDL_Window * window) { | 29 Win32_CreateShaper(SDL_Window * window) { |
41 return NULL; | 42 return NULL; |
42 | 43 |
43 return result; | 44 return result; |
44 } | 45 } |
45 | 46 |
46 typedef struct { | |
47 POINT corners[4]; | |
48 void* next; | |
49 } SDL_ShapeRect; | |
50 | |
51 void | 47 void |
52 CombineRectRegions(SDL_ShapeTree* node,void* closure) { | 48 CombineRectRegions(SDL_ShapeTree* node,void* closure) { |
53 char debug_str[200]; | 49 char debug_str[200]; |
54 SDL_ShapeRect* rect_list = *((SDL_ShapeRect**)closure); | 50 HRGN mask_region = *((HRGN*)closure),temp_region = NULL; |
55 if(node->kind == OpaqueShape) { | 51 if(node->kind == OpaqueShape) { |
56 SDL_ShapeRect* rect = SDL_malloc(sizeof(SDL_ShapeRect)); | 52 //Win32 API regions exclude their outline, so we widen the region by one pixel in each direction to include the real outline. |
57 sprintf_s(&debug_str[0],200,"x: %u y: %u, x+w: %u, y+h: %u\n", | 53 sprintf_s(&debug_str[0],200,"x: %u y: %u, x+w: %u, y+h: %u\n", |
58 node->data.shape.x,node->data.shape.y, | 54 node->data.shape.x,node->data.shape.y, |
59 node->data.shape.x + node->data.shape.w,node->data.shape.y + node->data.shape.h); | 55 node->data.shape.x + node->data.shape.w,node->data.shape.y + node->data.shape.h); |
60 OutputDebugStringA(debug_str); | 56 OutputDebugStringA(debug_str); |
61 OutputDebugStringA("Converting SDL_ShapeTree opaque node to Windows rectangle.\n"); | 57 OutputDebugStringA("Converting SDL_ShapeTree opaque node to Windows rectangle.\n"); |
62 rect->corners[0].x = node->data.shape.x; rect->corners[0].y = node->data.shape.y; | 58 temp_region = CreateRectRgn(node->data.shape.x - 1,node->data.shape.y - 1,node->data.shape.x + node->data.shape.w + 1,node->data.shape.y + node->data.shape.h + 1); |
63 rect->corners[1].x = node->data.shape.x + node->data.shape.w; rect->corners[1].y = node->data.shape.y; | 59 if(mask_region != NULL) { |
64 rect->corners[2].x = node->data.shape.x + node->data.shape.w; rect->corners[2].y = node->data.shape.y + node->data.shape.h; | 60 CombineRgn(mask_region,mask_region,temp_region,RGN_OR); |
65 rect->corners[3].x = node->data.shape.x; rect->corners[3].y = node->data.shape.y + node->data.shape.h; | 61 DeleteObject(temp_region); |
66 rect->next = *((SDL_ShapeRect**)closure); | 62 } |
67 *((SDL_ShapeRect**)closure) = rect; | 63 else |
68 } | 64 *((HRGN*)closure) = temp_region; |
69 } | 65 } |
70 | |
71 Uint32 num_shape_rects(SDL_ShapeRect* rect) { | |
72 if(rect == NULL) | |
73 return 0; | |
74 else | |
75 return 1 + num_shape_rects(rect->next); | |
76 } | 66 } |
77 | 67 |
78 int | 68 int |
79 Win32_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shape_mode) { | 69 Win32_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shape_mode) { |
80 SDL_ShapeData *data; | 70 SDL_ShapeData *data; |
81 HRGN mask_region; | 71 HRGN mask_region = NULL; |
82 SDL_ShapeRect* rects = NULL,*old = NULL; | |
83 Uint16 num_rects = 0,i = 0; | |
84 int* polygonVertexNumbers = NULL; | |
85 POINT* polygons = NULL; | |
86 char debug_str[200]; | |
87 | 72 |
88 if (shaper == NULL || shape == NULL) | 73 if (shaper == NULL || shape == NULL) |
89 return SDL_INVALID_SHAPE_ARGUMENT; | 74 return SDL_INVALID_SHAPE_ARGUMENT; |
90 if(shape->format->Amask == 0 && shape_mode->mode != ShapeModeColorKey || shape->w != shaper->window->w || shape->h != shaper->window->h) | 75 if(shape->format->Amask == 0 && shape_mode->mode != ShapeModeColorKey || shape->w != shaper->window->w || shape->h != shaper->window->h) |
91 return SDL_INVALID_SHAPE_ARGUMENT; | 76 return SDL_INVALID_SHAPE_ARGUMENT; |
93 data = (SDL_ShapeData*)shaper->driverdata; | 78 data = (SDL_ShapeData*)shaper->driverdata; |
94 if(data->mask_tree != NULL) | 79 if(data->mask_tree != NULL) |
95 SDL_FreeShapeTree(&data->mask_tree); | 80 SDL_FreeShapeTree(&data->mask_tree); |
96 data->mask_tree = SDL_CalculateShapeTree(*shape_mode,shape); | 81 data->mask_tree = SDL_CalculateShapeTree(*shape_mode,shape); |
97 | 82 |
98 SDL_TraverseShapeTree(data->mask_tree,&CombineRectRegions,&rects); | 83 SDL_TraverseShapeTree(data->mask_tree,&CombineRectRegions,&mask_region); |
99 num_rects = num_shape_rects(rects); | 84 SDL_assert(mask_region != NULL); |
100 polygonVertexNumbers = (int*)SDL_malloc(sizeof(int)*num_rects); | |
101 for(i=0;i<num_rects;i++) | |
102 polygonVertexNumbers[i] = 4; | |
103 polygons = (POINT*)SDL_malloc(sizeof(POINT)*4*num_rects); | |
104 for(i=0;i<num_rects*4;i++) { | |
105 polygons[i] = rects->corners[i % 4]; | |
106 if(i % 4 == 3) { | |
107 sprintf_s(&debug_str[0],200,"x: %u y: %u, x+w: %u, y+h: %u\n", | |
108 rects->corners[0].x,rects->corners[0].y, | |
109 rects->corners[2].x,rects->corners[2].y); | |
110 OutputDebugStringA(debug_str); | |
111 old = rects; | |
112 rects = rects->next; | |
113 SDL_free(old); | |
114 } | |
115 } | |
116 | 85 |
117 /* | |
118 * Set the new region mask for the window | |
119 */ | |
120 mask_region = CreatePolyPolygonRgn(polygons,polygonVertexNumbers,num_rects,WINDING); | |
121 SetWindowRgn(((SDL_WindowData *)(shaper->window->driverdata))->hwnd, mask_region, TRUE); | 86 SetWindowRgn(((SDL_WindowData *)(shaper->window->driverdata))->hwnd, mask_region, TRUE); |
122 | |
123 SDL_free(polygons); | |
124 SDL_free(polygonVertexNumbers); | |
125 | 87 |
126 return 0; | 88 return 0; |
127 } | 89 } |
128 | 90 |
129 int | 91 int |