SDL 2.0
SDL_shape.c
Go to the documentation of this file.
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2019 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
33SDL_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) {
38 if (SDL_GetVideoDevice()->shape_driver.CreateShaper == NULL) {
40 return NULL;
41 }
43 if(result->shaper != NULL) {
44 result->shaper->userx = x;
45 result->shaper->usery = y;
46 result->shaper->mode.mode = ShapeModeDefault;
47 result->shaper->mode.parameters.binarizationCutoff = 1;
48 result->shaper->hasshape = SDL_FALSE;
49 return result;
50 }
51 else {
53 return NULL;
54 }
55 }
56 else
57 return NULL;
58}
59
62{
63 if(window == NULL)
64 return SDL_FALSE;
65 else
66 return (SDL_bool)(window->shaper != NULL);
67}
68
69/* REQUIRES that bitmap point to a w-by-h bitmap with ppb pixels-per-byte. */
70void
72{
73 int x = 0;
74 int y = 0;
75 Uint8 r = 0,g = 0,b = 0,alpha = 0;
76 Uint8* pixel = NULL;
77 Uint32 pixel_value = 0,mask_value = 0;
78 int bytes_per_scanline = (shape->w + (ppb - 1)) / ppb;
79 Uint8 *bitmap_scanline;
81 if(SDL_MUSTLOCK(shape))
82 SDL_LockSurface(shape);
83 for(y = 0;y<shape->h;y++) {
84 bitmap_scanline = bitmap + y * bytes_per_scanline;
85 for(x=0;x<shape->w;x++) {
86 alpha = 0;
87 pixel_value = 0;
88 pixel = (Uint8 *)(shape->pixels) + (y*shape->pitch) + (x*shape->format->BytesPerPixel);
89 switch(shape->format->BytesPerPixel) {
90 case(1):
91 pixel_value = *(Uint8*)pixel;
92 break;
93 case(2):
94 pixel_value = *(Uint16*)pixel;
95 break;
96 case(3):
97 pixel_value = *(Uint32*)pixel & (~shape->format->Amask);
98 break;
99 case(4):
100 pixel_value = *(Uint32*)pixel;
101 break;
102 }
103 SDL_GetRGBA(pixel_value,shape->format,&r,&g,&b,&alpha);
104 switch(mode.mode) {
105 case(ShapeModeDefault):
106 mask_value = (alpha >= 1 ? 1 : 0);
107 break;
109 mask_value = (alpha >= mode.parameters.binarizationCutoff ? 1 : 0);
110 break;
112 mask_value = (alpha <= mode.parameters.binarizationCutoff ? 1 : 0);
113 break;
114 case(ShapeModeColorKey):
115 key = mode.parameters.colorKey;
116 mask_value = ((key.r != r || key.g != g || key.b != b) ? 1 : 0);
117 break;
118 }
119 bitmap_scanline[x / ppb] |= mask_value << (x % ppb);
120 }
121 }
122 if(SDL_MUSTLOCK(shape))
123 SDL_UnlockSurface(shape);
124}
125
126static SDL_ShapeTree*
128 int x = 0,y = 0;
129 Uint8* pixel = NULL;
130 Uint32 pixel_value = 0;
131 Uint8 r = 0,g = 0,b = 0,a = 0;
132 SDL_bool pixel_opaque = SDL_FALSE;
133 int last_opaque = -1;
136 SDL_Rect next = {0,0,0,0};
137
138 for(y=dimensions.y;y<dimensions.y + dimensions.h;y++) {
139 for(x=dimensions.x;x<dimensions.x + dimensions.w;x++) {
140 pixel_value = 0;
141 pixel = (Uint8 *)(mask->pixels) + (y*mask->pitch) + (x*mask->format->BytesPerPixel);
142 switch(mask->format->BytesPerPixel) {
143 case(1):
144 pixel_value = *(Uint8*)pixel;
145 break;
146 case(2):
147 pixel_value = *(Uint16*)pixel;
148 break;
149 case(3):
150 pixel_value = *(Uint32*)pixel & (~mask->format->Amask);
151 break;
152 case(4):
153 pixel_value = *(Uint32*)pixel;
154 break;
155 }
156 SDL_GetRGBA(pixel_value,mask->format,&r,&g,&b,&a);
157 switch(mode.mode) {
158 case(ShapeModeDefault):
159 pixel_opaque = (a >= 1 ? SDL_TRUE : SDL_FALSE);
160 break;
162 pixel_opaque = (a >= mode.parameters.binarizationCutoff ? SDL_TRUE : SDL_FALSE);
163 break;
165 pixel_opaque = (a <= mode.parameters.binarizationCutoff ? SDL_TRUE : SDL_FALSE);
166 break;
167 case(ShapeModeColorKey):
168 key = mode.parameters.colorKey;
169 pixel_opaque = ((key.r != r || key.g != g || key.b != b) ? SDL_TRUE : SDL_FALSE);
170 break;
171 }
172 if(last_opaque == -1)
173 last_opaque = pixel_opaque;
174 if(last_opaque != pixel_opaque) {
175 const int halfwidth = dimensions.w / 2;
176 const int halfheight = dimensions.h / 2;
177
178 result->kind = QuadShape;
179
180 next.x = dimensions.x;
181 next.y = dimensions.y;
182 next.w = halfwidth;
183 next.h = halfheight;
184 result->data.children.upleft = (struct SDL_ShapeTree *)RecursivelyCalculateShapeTree(mode,mask,next);
185
186 next.x = dimensions.x + halfwidth;
187 next.w = dimensions.w - halfwidth;
188 result->data.children.upright = (struct SDL_ShapeTree *)RecursivelyCalculateShapeTree(mode,mask,next);
189
190 next.x = dimensions.x;
191 next.w = halfwidth;
192 next.y = dimensions.y + halfheight;
193 next.h = dimensions.h - halfheight;
194 result->data.children.downleft = (struct SDL_ShapeTree *)RecursivelyCalculateShapeTree(mode,mask,next);
195
196 next.x = dimensions.x + halfwidth;
197 next.w = dimensions.w - halfwidth;
198 result->data.children.downright = (struct SDL_ShapeTree *)RecursivelyCalculateShapeTree(mode,mask,next);
199
200 return result;
201 }
202 }
203 }
204
205
206 /* If we never recursed, all the pixels in this quadrant have the same "value". */
207 result->kind = (last_opaque == SDL_TRUE ? OpaqueShape : TransparentShape);
208 result->data.shape = dimensions;
209 return result;
210}
211
214{
215 SDL_Rect dimensions;
217
218 dimensions.x = 0;
219 dimensions.y = 0;
220 dimensions.w = shape->w;
221 dimensions.h = shape->h;
222
223 if(SDL_MUSTLOCK(shape))
224 SDL_LockSurface(shape);
225 result = RecursivelyCalculateShapeTree(mode,shape,dimensions);
226 if(SDL_MUSTLOCK(shape))
227 SDL_UnlockSurface(shape);
228 return result;
229}
230
231void
233{
234 SDL_assert(tree != NULL);
235 if(tree->kind == QuadShape) {
236 SDL_TraverseShapeTree((SDL_ShapeTree *)tree->data.children.upleft,function,closure);
237 SDL_TraverseShapeTree((SDL_ShapeTree *)tree->data.children.upright,function,closure);
238 SDL_TraverseShapeTree((SDL_ShapeTree *)tree->data.children.downleft,function,closure);
239 SDL_TraverseShapeTree((SDL_ShapeTree *)tree->data.children.downright,function,closure);
240 }
241 else
242 function(tree,closure);
243}
244
245void
247{
248 if((*shape_tree)->kind == QuadShape) {
249 SDL_FreeShapeTree((SDL_ShapeTree **)(char*)&(*shape_tree)->data.children.upleft);
250 SDL_FreeShapeTree((SDL_ShapeTree **)(char*)&(*shape_tree)->data.children.upright);
251 SDL_FreeShapeTree((SDL_ShapeTree **)(char*)&(*shape_tree)->data.children.downleft);
252 SDL_FreeShapeTree((SDL_ShapeTree **)(char*)&(*shape_tree)->data.children.downright);
253 }
254 SDL_free(*shape_tree);
255 *shape_tree = NULL;
256}
257
258int
260{
261 int result;
263 /* The window given was not a shapeable window. */
265 if(shape == NULL)
266 /* Invalid shape argument. */
268
269 if(shape_mode != NULL)
270 window->shaper->mode = *shape_mode;
271 result = SDL_GetVideoDevice()->shape_driver.SetWindowShape(window->shaper,shape,shape_mode);
272 window->shaper->hasshape = SDL_TRUE;
273 if(window->shaper->userx != 0 && window->shaper->usery != 0) {
274 SDL_SetWindowPosition(window,window->shaper->userx,window->shaper->usery);
275 window->shaper->userx = 0;
276 window->shaper->usery = 0;
277 }
278 return result;
279}
280
281static SDL_bool
283{
285 return SDL_FALSE;
286 return window->shaper->hasshape;
287}
288
289int
291{
293 if(shape_mode == NULL) {
295 /* The window given has a shape. */
296 return 0;
297 else
298 /* The window given is shapeable but lacks a shape. */
300 }
301 else {
302 *shape_mode = window->shaper->mode;
303 return 0;
304 }
305 }
306 else
307 /* The window given is not a valid shapeable window. */
309}
#define SDL_assert(condition)
Definition: SDL_assert.h:169
#define SDL_DestroyWindow
#define SDL_CreateWindow
#define SDL_SetWindowPosition
#define SDL_malloc
#define SDL_UnlockSurface
#define SDL_free
#define SDL_LockSurface
#define SDL_GetRGBA
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
GLdouble GLdouble GLdouble r
Definition: SDL_opengl.h:2079
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
GLboolean GLboolean GLboolean b
GLenum mode
GLuint64EXT * result
GLsizei GLfixed GLfixed GLfixed GLfixed const GLubyte * bitmap
GLboolean GLboolean GLboolean GLboolean a
GLboolean GLboolean g
GLbitfield flags
GLfloat GLfloat GLfloat alpha
GLenum GLint GLuint mask
GLfloat GLfloat GLfloat GLfloat h
GLubyte GLubyte GLubyte GLubyte w
static SDL_bool SDL_WindowHasAShape(SDL_Window *window)
Definition: SDL_shape.c:282
int SDL_GetShapedWindowMode(SDL_Window *window, SDL_WindowShapeMode *shape_mode)
Get the shape parameters of a shaped window.
Definition: SDL_shape.c:290
SDL_ShapeTree * SDL_CalculateShapeTree(SDL_WindowShapeMode mode, SDL_Surface *shape)
Definition: SDL_shape.c:213
void SDL_TraverseShapeTree(SDL_ShapeTree *tree, SDL_TraversalFunction function, void *closure)
Definition: SDL_shape.c:232
void SDL_CalculateShapeBitmap(SDL_WindowShapeMode mode, SDL_Surface *shape, Uint8 *bitmap, Uint8 ppb)
Definition: SDL_shape.c:71
void SDL_FreeShapeTree(SDL_ShapeTree **shape_tree)
Definition: SDL_shape.c:246
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
static SDL_ShapeTree * RecursivelyCalculateShapeTree(SDL_WindowShapeMode mode, SDL_Surface *mask, SDL_Rect dimensions)
Definition: SDL_shape.c:127
SDL_bool SDL_IsShapedWindow(const SDL_Window *window)
Return whether the given window is a shaped window.
Definition: SDL_shape.c:61
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:259
#define SDL_INVALID_SHAPE_ARGUMENT
Definition: SDL_shape.h:43
#define SDL_NONSHAPEABLE_WINDOW
Definition: SDL_shape.h:42
@ ShapeModeBinarizeAlpha
A binarized alpha cutoff with a given integer value.
Definition: SDL_shape.h:84
@ ShapeModeColorKey
A color key is applied.
Definition: SDL_shape.h:88
@ ShapeModeDefault
The default mode, a binarized alpha cutoff of 1.
Definition: SDL_shape.h:82
@ ShapeModeReverseBinarizeAlpha
A binarized alpha cutoff with a given integer value, but with the opposite comparison.
Definition: SDL_shape.h:86
#define SDL_WINDOW_LACKS_SHAPE
Definition: SDL_shape.h:44
@ QuadShape
@ TransparentShape
@ OpaqueShape
void(* SDL_TraversalFunction)(SDL_ShapeTree *, void *)
SDL_bool
Definition: SDL_stdinc.h:162
@ SDL_TRUE
Definition: SDL_stdinc.h:164
@ SDL_FALSE
Definition: SDL_stdinc.h:163
uint32_t Uint32
Definition: SDL_stdinc.h:203
uint16_t Uint16
Definition: SDL_stdinc.h:191
uint8_t Uint8
Definition: SDL_stdinc.h:179
#define SDL_MUSTLOCK(S)
Definition: SDL_surface.h:62
SDL_VideoDevice * SDL_GetVideoDevice(void)
Definition: SDL_video.c:583
@ SDL_WINDOW_RESIZABLE
Definition: SDL_video.h:105
@ SDL_WINDOW_FULLSCREEN
Definition: SDL_video.h:100
@ SDL_WINDOW_BORDERLESS
Definition: SDL_video.h:104
#define NULL
Definition: begin_code.h:167
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
GLuint64 key
Definition: gl2ext.h:2192
Uint8 BytesPerPixel
Definition: SDL_pixels.h:320
struct SDL_ShapeTree * downright
struct SDL_ShapeTree * upleft
struct SDL_ShapeTree * downleft
struct SDL_ShapeTree * upright
A rectangle, with the origin at the upper left (integer).
Definition: SDL_rect.h:78
int h
Definition: SDL_rect.h:80
int w
Definition: SDL_rect.h:80
int y
Definition: SDL_rect.h:79
int x
Definition: SDL_rect.h:79
SDL_WindowShaper *(* CreateShaper)(SDL_Window *window)
Definition: SDL_sysvideo.h:60
int(* SetWindowShape)(SDL_WindowShaper *shaper, SDL_Surface *shape, SDL_WindowShapeMode *shape_mode)
Definition: SDL_sysvideo.h:61
SDL_ShapeKind kind
SDL_ShapeUnion data
A collection of pixels used in software blitting.
Definition: SDL_surface.h:71
SDL_PixelFormat * format
Definition: SDL_surface.h:73
void * pixels
Definition: SDL_surface.h:76
SDL_ShapeDriver shape_driver
Definition: SDL_sysvideo.h:245
The type used to identify a window.
Definition: SDL_sysvideo.h:74
A struct that tags the SDL_WindowShapeParams union with an enum describing the type of its contents.
Definition: SDL_shape.h:101
WindowShapeMode mode
The mode of these window-shape parameters.
Definition: SDL_shape.h:103
SDL_QuadTreeChildren children