comparison src/video/SDL_shape.c @ 4843:0998d1b5dd23

Fixed formatting of SDL_shape.c post-merge again.
author Eli Gottlieb <eligottlieb@gmail.com>
date Mon, 09 Aug 2010 20:32:15 -0400
parents 740e833b2c00
children 4f1573996a65
comparison
equal deleted inserted replaced
4842:c24f71246e5e 4843:0998d1b5dd23
28 #include "SDL_pixels.h" 28 #include "SDL_pixels.h"
29 #include "SDL_surface.h" 29 #include "SDL_surface.h"
30 #include "SDL_shape.h" 30 #include "SDL_shape.h"
31 #include "SDL_shape_internals.h" 31 #include "SDL_shape_internals.h"
32 32
33 SDL_Window* SDL_CreateShapedWindow(const char *title,unsigned int x,unsigned int y,unsigned int w,unsigned int h,Uint32 flags) { 33 SDL_Window*
34 SDL_Window *result = SDL_CreateWindow(title,x,y,w,h,SDL_WINDOW_BORDERLESS | flags & !SDL_WINDOW_FULLSCREEN & !SDL_WINDOW_SHOWN); 34 SDL_CreateShapedWindow(const char *title,unsigned int x,unsigned int y,unsigned int w,unsigned int h,Uint32 flags) {
35 if(result != NULL) { 35 SDL_Window *result = SDL_CreateWindow(title,x,y,w,h,SDL_WINDOW_BORDERLESS | flags & !SDL_WINDOW_FULLSCREEN & !SDL_WINDOW_SHOWN);
36 result->shaper = result->display->device->shape_driver.CreateShaper(result); 36 if(result != NULL) {
37 if(result->shaper != NULL) { 37 result->shaper = result->display->device->shape_driver.CreateShaper(result);
38 result->shaper->usershownflag = flags & SDL_WINDOW_SHOWN; 38 if(result->shaper != NULL) {
39 result->shaper->mode.mode = ShapeModeDefault; 39 result->shaper->usershownflag = flags & SDL_WINDOW_SHOWN;
40 result->shaper->mode.parameters.binarizationCutoff = 1; 40 result->shaper->mode.mode = ShapeModeDefault;
41 result->shaper->hasshape = SDL_FALSE; 41 result->shaper->mode.parameters.binarizationCutoff = 1;
42 return result; 42 result->shaper->hasshape = SDL_FALSE;
43 } 43 return result;
44 else { 44 }
45 SDL_DestroyWindow(result); 45 else {
46 return NULL; 46 SDL_DestroyWindow(result);
47 } 47 return NULL;
48 } 48 }
49 else 49 }
50 return NULL; 50 else
51 } 51 return NULL;
52 52 }
53 SDL_bool SDL_IsShapedWindow(const SDL_Window *window) { 53
54 if(window == NULL) 54 SDL_bool
55 return SDL_FALSE; 55 SDL_IsShapedWindow(const SDL_Window *window) {
56 else 56 if(window == NULL)
57 return (SDL_bool)(window->shaper != NULL); 57 return SDL_FALSE;
58 else
59 return (SDL_bool)(window->shaper != NULL);
58 } 60 }
59 61
60 /* REQUIRES that bitmap point to a w-by-h bitmap with ppb pixels-per-byte. */ 62 /* REQUIRES that bitmap point to a w-by-h bitmap with ppb pixels-per-byte. */
61 void SDL_CalculateShapeBitmap(SDL_WindowShapeMode mode,SDL_Surface *shape,Uint8* bitmap,Uint8 ppb) { 63 void
62 int x = 0; 64 SDL_CalculateShapeBitmap(SDL_WindowShapeMode mode,SDL_Surface *shape,Uint8* bitmap,Uint8 ppb) {
63 int y = 0; 65 int x = 0;
64 Uint8 r = 0,g = 0,b = 0,alpha = 0; 66 int y = 0;
65 Uint8* pixel = NULL; 67 Uint8 r = 0,g = 0,b = 0,alpha = 0;
66 Uint32 bitmap_pixel,pixel_value = 0,mask_value = 0; 68 Uint8* pixel = NULL;
67 SDL_Color key; 69 Uint32 bitmap_pixel,pixel_value = 0,mask_value = 0;
68 if(SDL_MUSTLOCK(shape)) 70 SDL_Color key;
69 SDL_LockSurface(shape); 71 if(SDL_MUSTLOCK(shape))
70 pixel = (Uint8*)shape->pixels; 72 SDL_LockSurface(shape);
71 for(y = 0;y<shape->h;y++) { 73 pixel = (Uint8*)shape->pixels;
72 for(x=0;x<shape->w;x++) { 74 for(y = 0;y<shape->h;y++) {
73 alpha = 0; 75 for(x=0;x<shape->w;x++) {
74 pixel_value = 0; 76 alpha = 0;
75 pixel = (Uint8 *)(shape->pixels) + (y*shape->pitch) + (x*shape->format->BytesPerPixel); 77 pixel_value = 0;
76 switch(shape->format->BytesPerPixel) { 78 pixel = (Uint8 *)(shape->pixels) + (y*shape->pitch) + (x*shape->format->BytesPerPixel);
77 case(1): 79 switch(shape->format->BytesPerPixel) {
78 pixel_value = *(Uint8*)pixel; 80 case(1):
79 break; 81 pixel_value = *(Uint8*)pixel;
80 case(2): 82 break;
81 pixel_value = *(Uint16*)pixel; 83 case(2):
82 break; 84 pixel_value = *(Uint16*)pixel;
83 case(3): 85 break;
84 pixel_value = *(Uint32*)pixel & (~shape->format->Amask); 86 case(3):
85 break; 87 pixel_value = *(Uint32*)pixel & (~shape->format->Amask);
86 case(4): 88 break;
87 pixel_value = *(Uint32*)pixel; 89 case(4):
88 break; 90 pixel_value = *(Uint32*)pixel;
89 } 91 break;
90 SDL_GetRGBA(pixel_value,shape->format,&r,&g,&b,&alpha); 92 }
91 bitmap_pixel = y*shape->w + x; 93 SDL_GetRGBA(pixel_value,shape->format,&r,&g,&b,&alpha);
92 switch(mode.mode) { 94 bitmap_pixel = y*shape->w + x;
93 case(ShapeModeDefault): 95 switch(mode.mode) {
94 mask_value = (alpha >= 1 ? 1 : 0); 96 case(ShapeModeDefault):
95 break; 97 mask_value = (alpha >= 1 ? 1 : 0);
96 case(ShapeModeBinarizeAlpha): 98 break;
97 mask_value = (alpha >= mode.parameters.binarizationCutoff ? 1 : 0); 99 case(ShapeModeBinarizeAlpha):
98 break; 100 mask_value = (alpha >= mode.parameters.binarizationCutoff ? 1 : 0);
99 case(ShapeModeReverseBinarizeAlpha): 101 break;
100 mask_value = (alpha <= mode.parameters.binarizationCutoff ? 1 : 0); 102 case(ShapeModeReverseBinarizeAlpha):
101 break; 103 mask_value = (alpha <= mode.parameters.binarizationCutoff ? 1 : 0);
102 case(ShapeModeColorKey): 104 break;
103 key = mode.parameters.colorKey; 105 case(ShapeModeColorKey):
104 mask_value = ((key.r != r && key.g != g && key.b != b) ? 1 : 0); 106 key = mode.parameters.colorKey;
105 break; 107 mask_value = ((key.r != r && key.g != g && key.b != b) ? 1 : 0);
106 } 108 break;
107 bitmap[bitmap_pixel / ppb] |= mask_value << (7 - ((ppb - 1) - (bitmap_pixel % ppb))); 109 }
108 } 110 bitmap[bitmap_pixel / ppb] |= mask_value << (7 - ((ppb - 1) - (bitmap_pixel % ppb)));
109 } 111 }
110 if(SDL_MUSTLOCK(shape)) 112 }
111 SDL_UnlockSurface(shape); 113 if(SDL_MUSTLOCK(shape))
112 } 114 SDL_UnlockSurface(shape);
113 115 }
114 SDL_ShapeTree* RecursivelyCalculateShapeTree(SDL_WindowShapeMode mode,SDL_Surface* mask,SDL_Rect dimensions) { 116
115 int x = 0,y = 0; 117 SDL_ShapeTree*
116 Uint8* pixel = NULL; 118 RecursivelyCalculateShapeTree(SDL_WindowShapeMode mode,SDL_Surface* mask,SDL_Rect dimensions) {
117 Uint32 pixel_value = 0; 119 int x = 0,y = 0;
118 Uint8 r = 0,g = 0,b = 0,a = 0; 120 Uint8* pixel = NULL;
119 SDL_bool pixel_opaque = SDL_FALSE; 121 Uint32 pixel_value = 0;
120 int last_opaque = -1; 122 Uint8 r = 0,g = 0,b = 0,a = 0;
121 SDL_Color key; 123 SDL_bool pixel_opaque = SDL_FALSE;
122 SDL_ShapeTree* result = (SDL_ShapeTree*)SDL_malloc(sizeof(SDL_ShapeTree)); 124 int last_opaque = -1;
123 SDL_Rect next = {0,0,0,0}; 125 SDL_Color key;
124 for(y=dimensions.y;y<dimensions.y + dimensions.h;y++) 126 SDL_ShapeTree* result = (SDL_ShapeTree*)SDL_malloc(sizeof(SDL_ShapeTree));
125 for(x=dimensions.x;x<dimensions.x + dimensions.w;x++) { 127 SDL_Rect next = {0,0,0,0};
126 pixel_value = 0; 128 for(y=dimensions.y;y<dimensions.y + dimensions.h;y++)
127 pixel = (Uint8 *)(mask->pixels) + (y*mask->pitch) + (x*mask->format->BytesPerPixel); 129 for(x=dimensions.x;x<dimensions.x + dimensions.w;x++) {
128 switch(mask->format->BytesPerPixel) { 130 pixel_value = 0;
129 case(1): 131 pixel = (Uint8 *)(mask->pixels) + (y*mask->pitch) + (x*mask->format->BytesPerPixel);
130 pixel_value = *(Uint8*)pixel; 132 switch(mask->format->BytesPerPixel) {
131 break; 133 case(1):
132 case(2): 134 pixel_value = *(Uint8*)pixel;
133 pixel_value = *(Uint16*)pixel; 135 break;
134 break; 136 case(2):
135 case(3): 137 pixel_value = *(Uint16*)pixel;
136 pixel_value = *(Uint32*)pixel & (~mask->format->Amask); 138 break;
137 break; 139 case(3):
138 case(4): 140 pixel_value = *(Uint32*)pixel & (~mask->format->Amask);
139 pixel_value = *(Uint32*)pixel; 141 break;
140 break; 142 case(4):
141 } 143 pixel_value = *(Uint32*)pixel;
142 SDL_GetRGBA(pixel_value,mask->format,&r,&g,&b,&a); 144 break;
143 switch(mode.mode) { 145 }
144 case(ShapeModeDefault): 146 SDL_GetRGBA(pixel_value,mask->format,&r,&g,&b,&a);
145 pixel_opaque = (a >= 1 ? SDL_TRUE : SDL_FALSE); 147 switch(mode.mode) {
146 break; 148 case(ShapeModeDefault):
147 case(ShapeModeBinarizeAlpha): 149 pixel_opaque = (a >= 1 ? SDL_TRUE : SDL_FALSE);
148 pixel_opaque = (a >= mode.parameters.binarizationCutoff ? SDL_TRUE : SDL_FALSE); 150 break;
149 break; 151 case(ShapeModeBinarizeAlpha):
150 case(ShapeModeReverseBinarizeAlpha): 152 pixel_opaque = (a >= mode.parameters.binarizationCutoff ? SDL_TRUE : SDL_FALSE);
151 pixel_opaque = (a <= mode.parameters.binarizationCutoff ? SDL_TRUE : SDL_FALSE); 153 break;
152 break; 154 case(ShapeModeReverseBinarizeAlpha):
153 case(ShapeModeColorKey): 155 pixel_opaque = (a <= mode.parameters.binarizationCutoff ? SDL_TRUE : SDL_FALSE);
154 key = mode.parameters.colorKey; 156 break;
155 pixel_opaque = ((key.r == r && key.g == g && key.b == b) ? SDL_TRUE : SDL_FALSE); 157 case(ShapeModeColorKey):
156 break; 158 key = mode.parameters.colorKey;
157 } 159 pixel_opaque = ((key.r == r && key.g == g && key.b == b) ? SDL_TRUE : SDL_FALSE);
158 if(last_opaque == -1) 160 break;
159 last_opaque = pixel_opaque; 161 }
160 if(last_opaque != pixel_opaque) { 162 if(last_opaque == -1)
161 result->kind = QuadShape; 163 last_opaque = pixel_opaque;
162 //These will stay the same. 164 if(last_opaque != pixel_opaque) {
163 next.w = dimensions.w / 2; 165 result->kind = QuadShape;
164 next.h = dimensions.h / 2; 166 //These will stay the same.
165 //These will change from recursion to recursion. 167 next.w = dimensions.w / 2;
166 next.x = dimensions.x; 168 next.h = dimensions.h / 2;
167 next.y = dimensions.y; 169 //These will change from recursion to recursion.
168 result->data.children.upleft = (struct SDL_ShapeTree *)RecursivelyCalculateShapeTree(mode,mask,next); 170 next.x = dimensions.x;
169 next.x = dimensions.w / 2; 171 next.y = dimensions.y;
170 //Unneeded: next.y = dimensions.y; 172 result->data.children.upleft = (struct SDL_ShapeTree *)RecursivelyCalculateShapeTree(mode,mask,next);
171 result->data.children.upright = (struct SDL_ShapeTree *)RecursivelyCalculateShapeTree(mode,mask,next); 173 next.x = dimensions.w / 2;
172 next.x = dimensions.x; 174 //Unneeded: next.y = dimensions.y;
173 next.y = dimensions.h / 2; 175 result->data.children.upright = (struct SDL_ShapeTree *)RecursivelyCalculateShapeTree(mode,mask,next);
174 result->data.children.downleft = (struct SDL_ShapeTree *)RecursivelyCalculateShapeTree(mode,mask,next); 176 next.x = dimensions.x;
175 next.x = dimensions.w / 2; 177 next.y = dimensions.h / 2;
176 //Unneeded: next.y = dimensions.h / 2 + 1; 178 result->data.children.downleft = (struct SDL_ShapeTree *)RecursivelyCalculateShapeTree(mode,mask,next);
177 result->data.children.downright = (struct SDL_ShapeTree *)RecursivelyCalculateShapeTree(mode,mask,next); 179 next.x = dimensions.w / 2;
178 return result; 180 //Unneeded: next.y = dimensions.h / 2 + 1;
179 } 181 result->data.children.downright = (struct SDL_ShapeTree *)RecursivelyCalculateShapeTree(mode,mask,next);
180 } 182 return result;
181 //If we never recursed, all the pixels in this quadrant have the same "value". 183 }
182 result->kind = (last_opaque == SDL_TRUE ? OpaqueShape : TransparentShape); 184 }
183 result->data.shape = dimensions; 185 //If we never recursed, all the pixels in this quadrant have the same "value".
184 return result; 186 result->kind = (last_opaque == SDL_TRUE ? OpaqueShape : TransparentShape);
185 } 187 result->data.shape = dimensions;
186 188 return result;
187 SDL_ShapeTree* SDL_CalculateShapeTree(SDL_WindowShapeMode mode,SDL_Surface* shape) { 189 }
188 SDL_Rect dimensions = {0,0,shape->w,shape->h}; 190
189 SDL_ShapeTree* result = NULL; 191 SDL_ShapeTree*
190 if(SDL_MUSTLOCK(shape)) 192 SDL_CalculateShapeTree(SDL_WindowShapeMode mode,SDL_Surface* shape) {
191 SDL_LockSurface(shape); 193 SDL_Rect dimensions = {0,0,shape->w,shape->h};
192 result = RecursivelyCalculateShapeTree(mode,shape,dimensions); 194 SDL_ShapeTree* result = NULL;
193 if(SDL_MUSTLOCK(shape)) 195 if(SDL_MUSTLOCK(shape))
194 SDL_UnlockSurface(shape); 196 SDL_LockSurface(shape);
195 return result; 197 result = RecursivelyCalculateShapeTree(mode,shape,dimensions);
196 } 198 if(SDL_MUSTLOCK(shape))
197 199 SDL_UnlockSurface(shape);
198 void SDL_TraverseShapeTree(SDL_ShapeTree *tree,SDL_TraversalFunction function,void* closure) { 200 return result;
199 SDL_assert(tree != NULL); 201 }
200 if(tree->kind == QuadShape) { 202
201 SDL_TraverseShapeTree((SDL_ShapeTree *)tree->data.children.upleft,function,closure); 203 void
202 SDL_TraverseShapeTree((SDL_ShapeTree *)tree->data.children.upright,function,closure); 204 SDL_TraverseShapeTree(SDL_ShapeTree *tree,SDL_TraversalFunction function,void* closure) {
203 SDL_TraverseShapeTree((SDL_ShapeTree *)tree->data.children.downleft,function,closure); 205 SDL_assert(tree != NULL);
204 SDL_TraverseShapeTree((SDL_ShapeTree *)tree->data.children.downright,function,closure); 206 if(tree->kind == QuadShape) {
205 } 207 SDL_TraverseShapeTree((SDL_ShapeTree *)tree->data.children.upleft,function,closure);
206 else 208 SDL_TraverseShapeTree((SDL_ShapeTree *)tree->data.children.upright,function,closure);
207 function(tree,closure); 209 SDL_TraverseShapeTree((SDL_ShapeTree *)tree->data.children.downleft,function,closure);
208 } 210 SDL_TraverseShapeTree((SDL_ShapeTree *)tree->data.children.downright,function,closure);
209 211 }
210 void SDL_FreeShapeTree(SDL_ShapeTree** shapeTree) { 212 else
211 if((*shapeTree)->kind == QuadShape) { 213 function(tree,closure);
212 SDL_FreeShapeTree((SDL_ShapeTree **)&(*shapeTree)->data.children.upleft); 214 }
213 SDL_FreeShapeTree((SDL_ShapeTree **)&(*shapeTree)->data.children.upright); 215
214 SDL_FreeShapeTree((SDL_ShapeTree **)&(*shapeTree)->data.children.downleft); 216 void
215 SDL_FreeShapeTree((SDL_ShapeTree **)&(*shapeTree)->data.children.downright); 217 SDL_FreeShapeTree(SDL_ShapeTree** shapeTree) {
216 } 218 if((*shapeTree)->kind == QuadShape) {
217 SDL_free(*shapeTree); 219 SDL_FreeShapeTree((SDL_ShapeTree **)&(*shapeTree)->data.children.upleft);
218 *shapeTree = NULL; 220 SDL_FreeShapeTree((SDL_ShapeTree **)&(*shapeTree)->data.children.upright);
219 } 221 SDL_FreeShapeTree((SDL_ShapeTree **)&(*shapeTree)->data.children.downleft);
220 222 SDL_FreeShapeTree((SDL_ShapeTree **)&(*shapeTree)->data.children.downright);
221 int SDL_SetWindowShape(SDL_Window *window,SDL_Surface *shape,SDL_WindowShapeMode *shapeMode) { 223 }
222 int result; 224 SDL_free(*shapeTree);
223 if(window == NULL || !SDL_IsShapedWindow(window)) 225 *shapeTree = NULL;
224 //The window given was not a shapeable window. 226 }
225 return SDL_NONSHAPEABLE_WINDOW; 227
226 if(shape == NULL) 228 int
227 //Invalid shape argument. 229 SDL_SetWindowShape(SDL_Window *window,SDL_Surface *shape,SDL_WindowShapeMode *shapeMode) {
228 return SDL_INVALID_SHAPE_ARGUMENT; 230 int result;
229 231 if(window == NULL || !SDL_IsShapedWindow(window))
230 if(shapeMode != NULL) 232 //The window given was not a shapeable window.
231 window->shaper->mode = *shapeMode; 233 return SDL_NONSHAPEABLE_WINDOW;
232 //TODO: Platform-specific implementations of SetWindowShape. X11 is finished. Win32 is finished. Debugging is in progress on both. 234 if(shape == NULL)
233 result = window->display->device->shape_driver.SetWindowShape(window->shaper,shape,shapeMode); 235 //Invalid shape argument.
234 window->shaper->hasshape = SDL_TRUE; 236 return SDL_INVALID_SHAPE_ARGUMENT;
235 if((window->shaper->usershownflag & SDL_WINDOW_SHOWN) == SDL_WINDOW_SHOWN) { 237
236 SDL_ShowWindow(window); 238 if(shapeMode != NULL)
237 window->shaper->usershownflag &= !SDL_WINDOW_SHOWN; 239 window->shaper->mode = *shapeMode;
238 } 240 //TODO: Platform-specific implementations of SetWindowShape. X11 is finished. Win32 is finished. Debugging is in progress on both.
239 return result; 241 result = window->display->device->shape_driver.SetWindowShape(window->shaper,shape,shapeMode);
240 } 242 window->shaper->hasshape = SDL_TRUE;
241 243 if((window->shaper->usershownflag & SDL_WINDOW_SHOWN) == SDL_WINDOW_SHOWN) {
242 SDL_bool SDL_WindowHasAShape(SDL_Window *window) { 244 SDL_ShowWindow(window);
243 if (window == NULL || !SDL_IsShapedWindow(window)) 245 window->shaper->usershownflag &= !SDL_WINDOW_SHOWN;
244 return SDL_FALSE; 246 }
245 return window->shaper->hasshape; 247 return result;
246 } 248 }
247 249
248 int SDL_GetShapedWindowMode(SDL_Window *window,SDL_WindowShapeMode *shapeMode) { 250 SDL_bool
249 if(window != NULL && SDL_IsShapedWindow(window)) { 251 SDL_WindowHasAShape(SDL_Window *window) {
250 if(shapeMode == NULL) { 252 if (window == NULL || !SDL_IsShapedWindow(window))
251 if(SDL_WindowHasAShape(window)) 253 return SDL_FALSE;
252 //The window given has a shape. 254 return window->shaper->hasshape;
253 return 0; 255 }
254 else 256
255 //The window given is shapeable but lacks a shape. 257 int
256 return SDL_WINDOW_LACKS_SHAPE; 258 SDL_GetShapedWindowMode(SDL_Window *window,SDL_WindowShapeMode *shapeMode) {
257 } 259 if(window != NULL && SDL_IsShapedWindow(window)) {
258 else { 260 if(shapeMode == NULL) {
259 *shapeMode = window->shaper->mode; 261 if(SDL_WindowHasAShape(window))
260 return 0; 262 //The window given has a shape.
261 } 263 return 0;
262 } 264 else
263 else 265 //The window given is shapeable but lacks a shape.
264 //The window given is not a valid shapeable window. 266 return SDL_WINDOW_LACKS_SHAPE;
265 return SDL_NONSHAPEABLE_WINDOW; 267 }
266 } 268 else {
269 *shapeMode = window->shaper->mode;
270 return 0;
271 }
272 }
273 else
274 //The window given is not a valid shapeable window.
275 return SDL_NONSHAPEABLE_WINDOW;
276 }