Mercurial > sdl-ios-xcode
comparison src/video/win32/SDL_win32shape.c @ 4787:e25ad8d97027
Ported over, to the best of my ability, the code for Win32 shaped windows and patched in the correct C syntax and coding conventions of SDL.
author | Eli Gottlieb <eligottlieb@gmail.com> |
---|---|
date | Thu, 08 Jul 2010 22:52:49 -0400 |
parents | ef8b32ef9793 |
children | f14a8c05f5bb |
comparison
equal
deleted
inserted
replaced
4786:175da36d1342 | 4787:e25ad8d97027 |
---|---|
56 SDL_ShapeData *data = (SDL_ShapeData*)shaper->driverdata; | 56 SDL_ShapeData *data = (SDL_ShapeData*)shaper->driverdata; |
57 /* | 57 /* |
58 * Transfer binarized mask image into workbuffer | 58 * Transfer binarized mask image into workbuffer |
59 */ | 59 */ |
60 SDL_CalculateShapeBitmap(shaper->alphacutoff,shape,data->shapebuffer,1,0xff); | 60 SDL_CalculateShapeBitmap(shaper->alphacutoff,shape,data->shapebuffer,1,0xff); |
61 | |
61 //Move code over to here from AW_windowShape.c | 62 //Move code over to here from AW_windowShape.c |
62 | 63 Uint8 *pos1 = data->shapebuffer + width - 1; |
64 Uint8 *pos2 = (Uint8*) pos1 + 1; | |
65 int x = 0,y = 0; | |
66 int visible = 0; | |
67 int vxmin = shape->width - 1; | |
68 int vxmax = -1; | |
69 int vymin = shape->height - 1; | |
70 int vymax = -1; | |
71 for (y = 0; y <height; y++) { | |
72 Uint8 inside = 0; | |
73 for (x = -1; x <width; x++) { | |
74 int newtargetcount; | |
75 POINT newtarget[5]; | |
76 /* | |
77 * Define local variables | |
78 */ | |
79 int newtargetcount; | |
80 POINT newtarget[5]; | |
81 | |
82 | |
83 /* | |
84 * Update visible region | |
85 */ | |
86 if (*curpos) | |
87 visible = 1; | |
88 /* | |
89 * Determine visible bounds | |
90 */ | |
91 if (x < vxmin) | |
92 vxmin = x; | |
93 if (x > vxmax) | |
94 vxmax = x; | |
95 if (y < vxymin) | |
96 vxymin = y; | |
97 if (y > vymax) | |
98 vymax = y; | |
99 | |
100 /* | |
101 * Check for starting point | |
102 */ | |
103 Uint8 *TL, *TR, *BL, *BR; | |
104 int target_x, target_y, lasttarget_x, lasttarget_y; | |
105 if (((!*curpos) && (*curpos2 == 0xFF)) || ((!*curpos2) && (*curpos == 0xFF))) { | |
106 if (!*curpos) { | |
107 BR = curpos2; | |
108 BL = (Uint8 *) (BR - 1); | |
109 TR = (Uint8 *) (BR - width); | |
110 TL = (Uint8 *) (TR - 1); | |
111 target_x = x; | |
112 target_y = y; | |
113 } | |
114 else { | |
115 BR = curpos2 + 1; | |
116 BL = (Uint8 *) (BR - 1); | |
117 TR = (Uint8 *) (BR - width); | |
118 TL = (Uint8 *) (TR - 1); | |
119 target_x = x + 1; | |
120 target_y = y; | |
121 } | |
122 | |
123 lasttarget_x = 0; | |
124 lasttarget_y = 0; | |
125 int firsttime = 1; | |
126 pos_array_pos = 0; | |
127 | |
128 while ((target_x != x) || (target_y != y) || firsttime) { | |
129 /* | |
130 * New array index | |
131 */ | |
132 firsttime = 0; | |
133 pos_array_pos++; | |
134 /* | |
135 * Check array index | |
136 */ | |
137 if (pos_array_pos >= 4096) { | |
138 SDL_SetError("Exceeded maximum number of polygon points."); | |
139 pos_array_pos--; | |
140 } | |
141 | |
142 /* | |
143 * Store point in array | |
144 */ | |
145 pos_array[pos_array_pos].x = target_x + 1; | |
146 pos_array[pos_array_pos].y = target_y; | |
147 | |
148 /* | |
149 * Mark the four poles as visited | |
150 */ | |
151 if (*TL) | |
152 *TL = 0x99; | |
153 if (*BL) | |
154 *BL = 0x99; | |
155 if (*TR) | |
156 *TR = 0x99; | |
157 if (*BR) | |
158 *BR = 0x99; | |
159 | |
160 newtargetcount = 0; | |
161 if ((*TL || *TR) && (*TL != *TR)) { | |
162 newtargetcount++; | |
163 newtarget[newtargetcount].x = 0; | |
164 newtarget[newtargetcount].y = -1; | |
165 } | |
166 | |
167 if ((*TR || *BR) && (*TR != *BR)) { | |
168 newtargetcount++; | |
169 newtarget[newtargetcount].x = 1; | |
170 newtarget[newtargetcount].y = 0; | |
171 } | |
172 | |
173 if ((*BL || *BR) && (*BL != *BR)) { | |
174 newtargetcount++; | |
175 newtarget[newtargetcount].x = 0; | |
176 newtarget[newtargetcount].y = 1; | |
177 } | |
178 | |
179 if ((*TL || *BL) && (*TL != *BL)) { | |
180 newtargetcount++; | |
181 newtarget[newtargetcount].x = -1; | |
182 newtarget[newtargetcount].y = 0; | |
183 } | |
184 | |
185 switch (newtargetcount) { | |
186 case 1: | |
187 SDL_SetError("Cropping error - Newtargetcount=1."); | |
188 return (-1); | |
189 break; | |
190 | |
191 case 2: | |
192 if ((target_x + newtarget[1].x != lasttarget_x) || (target_y + newtarget[1].y != lasttarget_y)) { | |
193 lasttarget_x = target_x; | |
194 lasttarget_y = target_y; | |
195 target_x = target_x + newtarget[1].x; | |
196 target_y = target_y + newtarget[1].y; | |
197 } | |
198 else { | |
199 lasttarget_x = target_x; | |
200 lasttarget_y = target_y; | |
201 target_x = target_x + newtarget[2].x; | |
202 target_y = target_y + newtarget[2].y; | |
203 } | |
204 break; | |
205 | |
206 case 3: | |
207 SDL_SetError("Cropping error - Newtargetcount=3."); | |
208 return (-1); | |
209 break; | |
210 | |
211 case 4: | |
212 if (lasttarget_x > target_x) { | |
213 lasttarget_x = target_x; | |
214 lasttarget_y = target_y; | |
215 if (*TR != 0x00) | |
216 target_y--; | |
217 else | |
218 target_y++; | |
219 } | |
220 else if (lasttarget_y > target_y) { | |
221 lasttarget_x = target_x; | |
222 lasttarget_y = target_y; | |
223 if (*BL != 0x00) | |
224 target_x--; | |
225 else | |
226 target_x++; | |
227 } | |
228 else if (lasttarget_x < target_x) { | |
229 lasttarget_x = target_x; | |
230 lasttarget_y = target_y; | |
231 if (*TL != 0x00) | |
232 target_y--; | |
233 else | |
234 target_y++; | |
235 } | |
236 else if (lasttarget_y < target_y) { | |
237 lasttarget_x = target_x; | |
238 lasttarget_y = target_y; | |
239 if (*TL != 0x00) | |
240 target_x--; | |
241 else | |
242 target_x++; | |
243 } | |
244 else { | |
245 SDL_SetError("Cropping error - no possible targets on newtargetcount=4."); | |
246 return (-1); | |
247 } | |
248 break; | |
249 | |
250 default: | |
251 SDL_SetError("Cropping error - Newtargetcount invalid."); | |
252 return (-1); | |
253 break; | |
254 } | |
255 | |
256 if (target_x > lasttarget_x) | |
257 TL = (Uint8 *) (TL + 1); | |
258 else if (target_x < lasttarget_x) | |
259 TL = (Uint8 *) (TL - 1); | |
260 else if (target_y > lasttarget_y) | |
261 TL = (Uint8 *) (TL + width); | |
262 else if (target_y < lasttarget_y) | |
263 TL = (Uint8 *) (TL - width); | |
264 else { | |
265 SDL_SetError("Cropping error - no new target."); | |
266 return (-1); | |
267 } | |
268 | |
269 BL = (Uint8 *) (TL + width); | |
270 TR = (Uint8 *) (TL + 1); | |
271 BR = (Uint8 *) (BL + 1); | |
272 } // End of while loop | |
273 | |
274 /* | |
275 * Apply the mask to the cropping region | |
276 */ | |
277 if (pos_array_pos >= 4) { | |
278 TempRegion = CreatePolygonRgn(&(pos_array[1]), pos_array_pos, WINDING); | |
279 if (TempRegion == NULL) { | |
280 SDL_SetError("Cropping error - unable to create polygon."); | |
281 return (-1); | |
282 } | |
283 | |
284 /* | |
285 * Add current region to final mask region | |
286 */ | |
287 if (inside) | |
288 CombineRgn(MaskRegion, MaskRegion, TempRegion, RGN_DIFF); | |
289 else | |
290 CombineRgn(MaskRegion, MaskRegion, TempRegion, RGN_OR); | |
291 | |
292 /* | |
293 * Remove temporary region | |
294 */ | |
295 DeleteObject(TempRegion); | |
296 } | |
297 | |
298 /* | |
299 * Switch sides | |
300 */ | |
301 inside = !inside; | |
302 } | |
303 else if ((*curpos) && (!*curpos2)) | |
304 inside = !inside; | |
305 else if ((!*curpos) && (*curpos2)) | |
306 inside = !inside; | |
307 | |
308 curpos++; | |
309 curpos2++; | |
310 } | |
311 curpos = (Uint8 *) (curpos + 2 * enlarge_mask - 1); | |
312 curpos2 = (Uint8 *) (curpos + 1); | |
313 } | |
314 | |
315 /* | |
316 * Set the new region mask for the window | |
317 */ | |
318 SetWindowRgn((SDL_WindowData*)(shaper->window->driverdata)->hwnd, MaskRegion, TRUE); | |
319 | |
320 /* | |
321 * Return value | |
322 */ | |
323 return (0); | |
63 } | 324 } |
64 | 325 |
65 int Win32_ResizeWindowShape(SDL_Window *window) { | 326 int Win32_ResizeWindowShape(SDL_Window *window) { |
66 SDL_ShapeData* data = window->shaper->driverdata; | 327 SDL_ShapeData* data = window->shaper->driverdata; |
67 assert(data != NULL); | 328 assert(data != NULL); |