SDL  2.0
SDL_shape.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "../SDL_internal.h"
22 
23 #include "SDL.h"
24 #include "SDL_assert.h"
25 #include "SDL_video.h"
26 #include "SDL_sysvideo.h"
27 #include "SDL_pixels.h"
28 #include "SDL_surface.h"
29 #include "SDL_shape.h"
30 #include "SDL_shape_internals.h"
31 
33 SDL_CreateShapedWindow(const char *title,unsigned int x,unsigned int y,unsigned int w,unsigned int h,Uint32 flags)
34 {
36  result = SDL_CreateWindow(title,-1000,-1000,w,h,(flags | SDL_WINDOW_BORDERLESS) & (~SDL_WINDOW_FULLSCREEN) & (~SDL_WINDOW_RESIZABLE) /* & (~SDL_WINDOW_SHOWN) */);
37  if(result != NULL) {
39  if(result->shaper != NULL) {
40  result->shaper->userx = x;
41  result->shaper->usery = y;
42  result->shaper->mode.mode = ShapeModeDefault;
44  result->shaper->hasshape = SDL_FALSE;
45  return result;
46  }
47  else {
48  SDL_DestroyWindow(result);
49  return NULL;
50  }
51  }
52  else
53  return NULL;
54 }
55 
58 {
59  if(window == NULL)
60  return SDL_FALSE;
61  else
62  return (SDL_bool)(window->shaper != NULL);
63 }
64 
65 /* REQUIRES that bitmap point to a w-by-h bitmap with ppb pixels-per-byte. */
66 void
68 {
69  int x = 0;
70  int y = 0;
71  Uint8 r = 0,g = 0,b = 0,alpha = 0;
72  Uint8* pixel = NULL;
73  Uint32 bitmap_pixel,pixel_value = 0,mask_value = 0;
74  SDL_Color key;
75  if(SDL_MUSTLOCK(shape))
76  SDL_LockSurface(shape);
77  for(y = 0;y<shape->h;y++) {
78  for(x=0;x<shape->w;x++) {
79  alpha = 0;
80  pixel_value = 0;
81  pixel = (Uint8 *)(shape->pixels) + (y*shape->pitch) + (x*shape->format->BytesPerPixel);
82  switch(shape->format->BytesPerPixel) {
83  case(1):
84  pixel_value = *(Uint8*)pixel;
85  break;
86  case(2):
87  pixel_value = *(Uint16*)pixel;
88  break;
89  case(3):
90  pixel_value = *(Uint32*)pixel & (~shape->format->Amask);
91  break;
92  case(4):
93  pixel_value = *(Uint32*)pixel;
94  break;
95  }
96  SDL_GetRGBA(pixel_value,shape->format,&r,&g,&b,&alpha);
97  bitmap_pixel = y*shape->w + x;
98  switch(mode.mode) {
99  case(ShapeModeDefault):
100  mask_value = (alpha >= 1 ? 1 : 0);
101  break;
103  mask_value = (alpha >= mode.parameters.binarizationCutoff ? 1 : 0);
104  break;
106  mask_value = (alpha <= mode.parameters.binarizationCutoff ? 1 : 0);
107  break;
108  case(ShapeModeColorKey):
109  key = mode.parameters.colorKey;
110  mask_value = ((key.r != r || key.g != g || key.b != b) ? 1 : 0);
111  break;
112  }
113  bitmap[bitmap_pixel / ppb] |= mask_value << (7 - ((ppb - 1) - (bitmap_pixel % ppb)));
114  }
115  }
116  if(SDL_MUSTLOCK(shape))
117  SDL_UnlockSurface(shape);
118 }
119 
120 static SDL_ShapeTree*
122  int x = 0,y = 0;
123  Uint8* pixel = NULL;
124  Uint32 pixel_value = 0;
125  Uint8 r = 0,g = 0,b = 0,a = 0;
126  SDL_bool pixel_opaque = SDL_FALSE;
127  int last_opaque = -1;
128  SDL_Color key;
130  SDL_Rect next = {0,0,0,0};
131 
132  for(y=dimensions.y;y<dimensions.y + dimensions.h;y++) {
133  for(x=dimensions.x;x<dimensions.x + dimensions.w;x++) {
134  pixel_value = 0;
135  pixel = (Uint8 *)(mask->pixels) + (y*mask->pitch) + (x*mask->format->BytesPerPixel);
136  switch(mask->format->BytesPerPixel) {
137  case(1):
138  pixel_value = *(Uint8*)pixel;
139  break;
140  case(2):
141  pixel_value = *(Uint16*)pixel;
142  break;
143  case(3):
144  pixel_value = *(Uint32*)pixel & (~mask->format->Amask);
145  break;
146  case(4):
147  pixel_value = *(Uint32*)pixel;
148  break;
149  }
150  SDL_GetRGBA(pixel_value,mask->format,&r,&g,&b,&a);
151  switch(mode.mode) {
152  case(ShapeModeDefault):
153  pixel_opaque = (a >= 1 ? SDL_TRUE : SDL_FALSE);
154  break;
156  pixel_opaque = (a >= mode.parameters.binarizationCutoff ? SDL_TRUE : SDL_FALSE);
157  break;
159  pixel_opaque = (a <= mode.parameters.binarizationCutoff ? SDL_TRUE : SDL_FALSE);
160  break;
161  case(ShapeModeColorKey):
162  key = mode.parameters.colorKey;
163  pixel_opaque = ((key.r != r || key.g != g || key.b != b) ? SDL_TRUE : SDL_FALSE);
164  break;
165  }
166  if(last_opaque == -1)
167  last_opaque = pixel_opaque;
168  if(last_opaque != pixel_opaque) {
169  const int halfwidth = dimensions.w / 2;
170  const int halfheight = dimensions.h / 2;
171 
172  result->kind = QuadShape;
173 
174  next.x = dimensions.x;
175  next.y = dimensions.y;
176  next.w = halfwidth;
177  next.h = halfheight;
178  result->data.children.upleft = (struct SDL_ShapeTree *)RecursivelyCalculateShapeTree(mode,mask,next);
179 
180  next.x = dimensions.x + halfwidth;
181  next.w = dimensions.w - halfwidth;
182  result->data.children.upright = (struct SDL_ShapeTree *)RecursivelyCalculateShapeTree(mode,mask,next);
183 
184  next.x = dimensions.x;
185  next.w = halfwidth;
186  next.y = dimensions.y + halfheight;
187  next.h = dimensions.h - halfheight;
188  result->data.children.downleft = (struct SDL_ShapeTree *)RecursivelyCalculateShapeTree(mode,mask,next);
189 
190  next.x = dimensions.x + halfwidth;
191  next.w = dimensions.w - halfwidth;
192  result->data.children.downright = (struct SDL_ShapeTree *)RecursivelyCalculateShapeTree(mode,mask,next);
193 
194  return result;
195  }
196  }
197  }
198 
199 
200  /* If we never recursed, all the pixels in this quadrant have the same "value". */
201  result->kind = (last_opaque == SDL_TRUE ? OpaqueShape : TransparentShape);
202  result->data.shape = dimensions;
203  return result;
204 }
205 
208 {
209  SDL_Rect dimensions = {0,0,shape->w,shape->h};
211  if(SDL_MUSTLOCK(shape))
212  SDL_LockSurface(shape);
213  result = RecursivelyCalculateShapeTree(mode,shape,dimensions);
214  if(SDL_MUSTLOCK(shape))
215  SDL_UnlockSurface(shape);
216  return result;
217 }
218 
219 void
221 {
222  SDL_assert(tree != NULL);
223  if(tree->kind == QuadShape) {
224  SDL_TraverseShapeTree((SDL_ShapeTree *)tree->data.children.upleft,function,closure);
225  SDL_TraverseShapeTree((SDL_ShapeTree *)tree->data.children.upright,function,closure);
226  SDL_TraverseShapeTree((SDL_ShapeTree *)tree->data.children.downleft,function,closure);
227  SDL_TraverseShapeTree((SDL_ShapeTree *)tree->data.children.downright,function,closure);
228  }
229  else
230  function(tree,closure);
231 }
232 
233 void
235 {
236  if((*shape_tree)->kind == QuadShape) {
237  SDL_FreeShapeTree((SDL_ShapeTree **)&(*shape_tree)->data.children.upleft);
238  SDL_FreeShapeTree((SDL_ShapeTree **)&(*shape_tree)->data.children.upright);
239  SDL_FreeShapeTree((SDL_ShapeTree **)&(*shape_tree)->data.children.downleft);
240  SDL_FreeShapeTree((SDL_ShapeTree **)&(*shape_tree)->data.children.downright);
241  }
242  SDL_free(*shape_tree);
243  *shape_tree = NULL;
244 }
245 
246 int
248 {
249  int result;
250  if(window == NULL || !SDL_IsShapedWindow(window))
251  /* The window given was not a shapeable window. */
253  if(shape == NULL)
254  /* Invalid shape argument. */
256 
257  if(shape_mode != NULL)
258  window->shaper->mode = *shape_mode;
259  result = SDL_GetVideoDevice()->shape_driver.SetWindowShape(window->shaper,shape,shape_mode);
260  window->shaper->hasshape = SDL_TRUE;
261  if(window->shaper->userx != 0 && window->shaper->usery != 0) {
262  SDL_SetWindowPosition(window,window->shaper->userx,window->shaper->usery);
263  window->shaper->userx = 0;
264  window->shaper->usery = 0;
265  }
266  return result;
267 }
268 
269 static SDL_bool
271 {
272  if (window == NULL || !SDL_IsShapedWindow(window))
273  return SDL_FALSE;
274  return window->shaper->hasshape;
275 }
276 
277 int
279 {
280  if(window != NULL && SDL_IsShapedWindow(window)) {
281  if(shape_mode == NULL) {
282  if(SDL_WindowHasAShape(window))
283  /* The window given has a shape. */
284  return 0;
285  else
286  /* The window given is shapeable but lacks a shape. */
287  return SDL_WINDOW_LACKS_SHAPE;
288  }
289  else {
290  *shape_mode = window->shaper->mode;
291  return 0;
292  }
293  }
294  else
295  /* The window given is not a valid shapeable window. */
297 }
GLsizei GLfixed GLfixed GLfixed GLfixed const GLubyte * bitmap
void SDL_FreeShapeTree(SDL_ShapeTree **shape_tree)
Definition: SDL_shape.c:234
int SDL_SetWindowShape(SDL_Window *window, SDL_Surface *shape, SDL_WindowShapeMode *shape_mode)
Set the shape and parameters of a shaped window.
Definition: SDL_shape.c:247
#define SDL_UnlockSurface
GLdouble GLdouble GLdouble r
Definition: SDL_opengl.h:2072
SDL_ShapeTree * SDL_CalculateShapeTree(SDL_WindowShapeMode mode, SDL_Surface *shape)
Definition: SDL_shape.c:207
GLuint64EXT * result
Uint8 g
Definition: SDL_pixels.h:296
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1567
Uint8 BytesPerPixel
Definition: SDL_pixels.h:318
struct SDL_ShapeTree * upright
static SDL_Window * window
SDL_bool hasshape
Definition: SDL_sysvideo.h:50
A collection of pixels used in software blitting.
Definition: SDL_surface.h:69
A color key is applied.
Definition: SDL_shape.h:87
SDL_bool SDL_IsShapedWindow(const SDL_Window *window)
Return whether the given window is a shaped window.
Definition: SDL_shape.c:57
int SDL_GetShapedWindowMode(SDL_Window *window, SDL_WindowShapeMode *shape_mode)
Get the shape parameters of a shaped window.
Definition: SDL_shape.c:278
Uint8 b
Definition: SDL_pixels.h:297
#define SDL_CreateWindow
SDL_ShapeUnion data
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:159
static SDL_bool SDL_WindowHasAShape(SDL_Window *window)
Definition: SDL_shape.c:270
GLfloat GLfloat GLfloat alpha
GLboolean GLboolean g
#define SDL_INVALID_SHAPE_ARGUMENT
Definition: SDL_shape.h:43
int(* SetWindowShape)(SDL_WindowShaper *shaper, SDL_Surface *shape, SDL_WindowShapeMode *shape_mode)
Definition: SDL_sysvideo.h:59
SDL_WindowShapeMode mode
Definition: SDL_sysvideo.h:47
Uint8 r
Definition: SDL_pixels.h:295
void(* SDL_TraversalFunction)(SDL_ShapeTree *, void *)
SDL_Window * SDL_CreateShapedWindow(const char *title, unsigned int x, unsigned int y, unsigned int w, unsigned int h, Uint32 flags)
Create a window that can be shaped with the specified position, dimensions, and flags.
Definition: SDL_shape.c:33
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1567
void * pixels
Definition: SDL_surface.h:75
SDL_WindowShaper * shaper
Definition: SDL_sysvideo.h:102
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:143
void SDL_free(void *mem)
#define SDL_NONSHAPEABLE_WINDOW
Definition: SDL_shape.h:42
GLenum mode
#define SDL_WINDOW_LACKS_SHAPE
Definition: SDL_shape.h:44
The default mode, a binarized alpha cutoff of 1.
Definition: SDL_shape.h:81
SDL_WindowShapeParams parameters
Window-shape parameters.
Definition: SDL_shape.h:104
int x
Definition: SDL_rect.h:66
int w
Definition: SDL_rect.h:67
GLenum GLint GLuint mask
#define SDL_GetRGBA
#define SDL_assert(condition)
Definition: SDL_assert.h:167
#define NULL
Definition: begin_code.h:143
SDL_bool
Definition: SDL_stdinc.h:130
A binarized alpha cutoff with a given integer value.
Definition: SDL_shape.h:83
SDL_PixelFormat * format
Definition: SDL_surface.h:72
#define SDL_LockSurface
SDL_WindowShaper *(* CreateShaper)(SDL_Window *window)
Definition: SDL_sysvideo.h:58
#define SDL_MUSTLOCK(S)
Definition: SDL_surface.h:61
int h
Definition: SDL_rect.h:67
SDL_Color colorKey
Definition: SDL_shape.h:96
A binarized alpha cutoff with a given integer value, but with the opposite comparison.
Definition: SDL_shape.h:85
The type used to identify a window.
Definition: SDL_sysvideo.h:71
void SDL_TraverseShapeTree(SDL_ShapeTree *tree, SDL_TraversalFunction function, void *closure)
Definition: SDL_shape.c:220
struct SDL_ShapeTree * upleft
uint16_t Uint16
An unsigned 16-bit integer type.
Definition: SDL_stdinc.h:151
SDL_VideoDevice * SDL_GetVideoDevice(void)
Definition: SDL_video.c:571
SDL_ShapeDriver shape_driver
Definition: SDL_sysvideo.h:237
Uint8 binarizationCutoff
a cutoff alpha value for binarization of the window shape&#39;s alpha channel.
Definition: SDL_shape.h:95
GLbitfield flags
#define SDL_malloc
A struct that tags the SDL_WindowShapeParams union with an enum describing the type of its contents...
Definition: SDL_shape.h:100
GLubyte GLubyte GLubyte GLubyte w
static SDL_ShapeTree * RecursivelyCalculateShapeTree(SDL_WindowShapeMode mode, SDL_Surface *mask, SDL_Rect dimensions)
Definition: SDL_shape.c:121
SDL_ShapeKind kind
WindowShapeMode mode
The mode of these window-shape parameters.
Definition: SDL_shape.h:102
GLboolean GLboolean GLboolean GLboolean a
#define SDL_DestroyWindow
GLboolean GLboolean GLboolean b
struct SDL_ShapeTree * downright
int y
Definition: SDL_rect.h:66
#define SDL_SetWindowPosition
SDL_QuadTreeChildren children
GLfloat GLfloat GLfloat GLfloat h
A rectangle, with the origin at the upper left.
Definition: SDL_rect.h:64
struct SDL_ShapeTree * downleft
void SDL_CalculateShapeBitmap(SDL_WindowShapeMode mode, SDL_Surface *shape, Uint8 *bitmap, Uint8 ppb)
Definition: SDL_shape.c:67