zenilib: zenilib/jni/external/sdl/src/video/SDL_rect.c Source File

zenilib 0.5.3.0

- Main Page
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SDL_rect.c
Go to the documentation of this file.
1 /*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2013 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_config.h"
22
23 #include "SDL_rect.h"
24 #include "SDL_rect_c.h"
25
26
27 SDL_bool
28 SDL_HasIntersection(const SDL_Rect * A, const SDL_Rect * B)
29 {
30 int Amin, Amax, Bmin, Bmax;
31
32 if (!A) {
33 SDL_InvalidParamError("A");
34 return SDL_FALSE;
35 }
36
37 if (!B) {
38 SDL_InvalidParamError("B");
39 return SDL_FALSE;
40 }
41
42 /* Special cases for empty rects */
43 if (SDL_RectEmpty(A) || SDL_RectEmpty(B)) {
44 return SDL_FALSE;
45 }
46
47 /* Horizontal intersection */
48 Amin = A->x;
49 Amax = Amin + A->w;
50 Bmin = B->x;
51 Bmax = Bmin + B->w;
52 if (Bmin > Amin)
53 Amin = Bmin;
54 if (Bmax < Amax)
55 Amax = Bmax;
56 if (Amax <= Amin)
57 return SDL_FALSE;
58
59 /* Vertical intersection */
60 Amin = A->y;
61 Amax = Amin + A->h;
62 Bmin = B->y;
63 Bmax = Bmin + B->h;
64 if (Bmin > Amin)
65 Amin = Bmin;
66 if (Bmax < Amax)
67 Amax = Bmax;
68 if (Amax <= Amin)
69 return SDL_FALSE;
70
71 return SDL_TRUE;
72 }
73
74 SDL_bool
75 SDL_IntersectRect(const SDL_Rect * A, const SDL_Rect * B, SDL_Rect * result)
76 {
77 int Amin, Amax, Bmin, Bmax;
78
79 if (!A) {
80 SDL_InvalidParamError("A");
81 return SDL_FALSE;
82 }
83
84 if (!B) {
85 SDL_InvalidParamError("B");
86 return SDL_FALSE;
87 }
88
89 if (!result) {
90 SDL_InvalidParamError("result");
91 return SDL_FALSE;
92 }
93
94 /* Special cases for empty rects */
95 if (SDL_RectEmpty(A) || SDL_RectEmpty(B)) {
96 result->w = 0;
97 result->h = 0;
98 return SDL_FALSE;
99 }
100
101 /* Horizontal intersection */
102 Amin = A->x;
103 Amax = Amin + A->w;
104 Bmin = B->x;
105 Bmax = Bmin + B->w;
106 if (Bmin > Amin)
107 Amin = Bmin;
108 result->x = Amin;
109 if (Bmax < Amax)
110 Amax = Bmax;
111 result->w = Amax - Amin;
112
113 /* Vertical intersection */
114 Amin = A->y;
115 Amax = Amin + A->h;
116 Bmin = B->y;
117 Bmax = Bmin + B->h;
118 if (Bmin > Amin)
119 Amin = Bmin;
120 result->y = Amin;
121 if (Bmax < Amax)
122 Amax = Bmax;
123 result->h = Amax - Amin;
124
125 return !SDL_RectEmpty(result);
126 }
127
128 void
129 SDL_UnionRect(const SDL_Rect * A, const SDL_Rect * B, SDL_Rect * result)
130 {
131 int Amin, Amax, Bmin, Bmax;
132
133 if (!A) {
134 SDL_InvalidParamError("A");
135 return;
136 }
137
138 if (!B) {
139 SDL_InvalidParamError("B");
140 return;
141 }
142
143 if (!result) {
144 SDL_InvalidParamError("result");
145 return;
146 }
147
148 /* Special cases for empty Rects */
149 if (SDL_RectEmpty(A)) {
150 if (SDL_RectEmpty(B)) {
151 /* A and B empty */
152 return;
153 } else {
154 /* A empty, B not empty */
155 *result = *B;
156 return;
157 }
158 } else {
159 if (SDL_RectEmpty(B)) {
160 /* A not empty, B empty */
161 *result = *A;
162 return;
163 }
164 }
165
166 /* Horizontal union */
167 Amin = A->x;
168 Amax = Amin + A->w;
169 Bmin = B->x;
170 Bmax = Bmin + B->w;
171 if (Bmin < Amin)
172 Amin = Bmin;
173 result->x = Amin;
174 if (Bmax > Amax)
175 Amax = Bmax;
176 result->w = Amax - Amin;
177
178 /* Vertical union */
179 Amin = A->y;
180 Amax = Amin + A->h;
181 Bmin = B->y;
182 Bmax = Bmin + B->h;
183 if (Bmin < Amin)
184 Amin = Bmin;
185 result->y = Amin;
186 if (Bmax > Amax)
187 Amax = Bmax;
188 result->h = Amax - Amin;
189 }
190
191 SDL_bool
192 SDL_EnclosePoints(const SDL_Point * points, int count, const SDL_Rect * clip,
193 SDL_Rect * result)
194 {
195 int minx = 0;
196 int miny = 0;
197 int maxx = 0;
198 int maxy = 0;
199 int x, y, i;
200
201 if (!points) {
202 SDL_InvalidParamError("points");
203 return SDL_FALSE;
204 }
205
206 if (count < 1) {
207 SDL_InvalidParamError("count");
208 return SDL_FALSE;
209 }
210
211 if (clip) {
212 SDL_bool added = SDL_FALSE;
213 const int clip_minx = clip->x;
214 const int clip_miny = clip->y;
215 const int clip_maxx = clip->x+clip->w-1;
216 const int clip_maxy = clip->y+clip->h-1;
217
218 /* Special case for empty rectangle */
219 if (SDL_RectEmpty(clip)) {
220 return SDL_FALSE;
221 }
222
223 for (i = 0; i < count; ++i) {
224 x = points[i].x;
225 y = points[i].y;
226
227 if (x < clip_minx || x > clip_maxx ||
228 y < clip_miny || y > clip_maxy) {
229 continue;
230 }
231 if (!added) {
232 /* Special case: if no result was requested, we are done */
233 if (result == NULL) {
234 return SDL_TRUE;
235 }
236
237 /* First point added */
238 minx = maxx = x;
239 miny = maxy = y;
240 added = SDL_TRUE;
241 continue;
242 }
243 if (x < minx) {
244 minx = x;
245 } else if (x > maxx) {
246 maxx = x;
247 }
248 if (y < miny) {
249 miny = y;
250 } else if (y > maxy) {
251 maxy = y;
252 }
253 }
254 if (!added) {
255 return SDL_FALSE;
256 }
257 } else {
258 /* Special case: if no result was requested, we are done */
259 if (result == NULL) {
260 return SDL_TRUE;
261 }
262
263 /* No clipping, always add the first point */
264 minx = maxx = points[0].x;
265 miny = maxy = points[0].y;
266
267 for (i = 1; i < count; ++i) {
268 x = points[i].x;
269 y = points[i].y;
270
271 if (x < minx) {
272 minx = x;
273 } else if (x > maxx) {
274 maxx = x;
275 }
276 if (y < miny) {
277 miny = y;
278 } else if (y > maxy) {
279 maxy = y;
280 }
281 }
282 }
283
284 if (result) {
285 result->x = minx;
286 result->y = miny;
287 result->w = (maxx-minx)+1;
288 result->h = (maxy-miny)+1;
289 }
290 return SDL_TRUE;
291 }
292
293 /* Use the Cohen-Sutherland algorithm for line clipping */
294 #define CODE_BOTTOM 1
295 #define CODE_TOP 2
296 #define CODE_LEFT 4
297 #define CODE_RIGHT 8
298
299 static int ComputeOutCode(const SDL_Rect * rect, int x, int y)
300 {
301 int code = 0;
302 if (y < 0) {
303 code |= CODE_TOP;
304 } else if (y >= rect->y + rect->h) {
305 code |= CODE_BOTTOM;
306 }
307 if (x < 0) {
308 code |= CODE_LEFT;
309 } else if (x >= rect->x + rect->w) {
310 code |= CODE_RIGHT;
311 }
312 return code;
313 }
314
315 SDL_bool
316 SDL_IntersectRectAndLine(const SDL_Rect * rect, int *X1, int *Y1, int *X2,
317 int *Y2)
318 {
319 int x = 0;
320 int y = 0;
321 int x1, y1;
322 int x2, y2;
323 int rectx1;
324 int recty1;
325 int rectx2;
326 int recty2;
327 int outcode1, outcode2;
328
329 if (!rect) {
330 SDL_InvalidParamError("rect");
331 return SDL_FALSE;
332 }
333
334 if (!X1) {
335 SDL_InvalidParamError("X1");
336 return SDL_FALSE;
337 }
338
339 if (!Y1) {
340 SDL_InvalidParamError("Y1");
341 return SDL_FALSE;
342 }
343
344 if (!X2) {
345 SDL_InvalidParamError("X2");
346 return SDL_FALSE;
347 }
348
349 if (!Y2) {
350 SDL_InvalidParamError("Y2");
351 return SDL_FALSE;
352 }
353
354 /* Special case for empty rect */
355 if (SDL_RectEmpty(rect)) {
356 return SDL_FALSE;
357 }
358
359 x1 = *X1;
360 y1 = *Y1;
361 x2 = *X2;
362 y2 = *Y2;
363 rectx1 = rect->x;
364 recty1 = rect->y;
365 rectx2 = rect->x + rect->w - 1;
366 recty2 = rect->y + rect->h - 1;
367
368 /* Check to see if entire line is inside rect */
369 if (x1 >= rectx1 && x1 <= rectx2 && x2 >= rectx1 && x2 <= rectx2 &&
370 y1 >= recty1 && y1 <= recty2 && y2 >= recty1 && y2 <= recty2) {
371 return SDL_TRUE;
372 }
373
374 /* Check to see if entire line is to one side of rect */
375 if ((x1 < rectx1 && x2 < rectx1) || (x1 > rectx2 && x2 > rectx2) ||
376 (y1 < recty1 && y2 < recty1) || (y1 > recty2 && y2 > recty2)) {
377 return SDL_FALSE;
378 }
379
380 if (y1 == y2) {
381 /* Horizontal line, easy to clip */
382 if (x1 < rectx1) {
383 *X1 = rectx1;
384 } else if (x1 > rectx2) {
385 *X1 = rectx2;
386 }
387 if (x2 < rectx1) {
388 *X2 = rectx1;
389 } else if (x2 > rectx2) {
390 *X2 = rectx2;
391 }
392 return SDL_TRUE;
393 }
394
395 if (x1 == x2) {
396 /* Vertical line, easy to clip */
397 if (y1 < recty1) {
398 *Y1 = recty1;
399 } else if (y1 > recty2) {
400 *Y1 = recty2;
401 }
402 if (y2 < recty1) {
403 *Y2 = recty1;
404 } else if (y2 > recty2) {
405 *Y2 = recty2;
406 }
407 return SDL_TRUE;
408 }
409
410 /* More complicated Cohen-Sutherland algorithm */
411 outcode1 = ComputeOutCode(rect, x1, y1);
412 outcode2 = ComputeOutCode(rect, x2, y2);
413 while (outcode1 || outcode2) {
414 if (outcode1 & outcode2) {
415 return SDL_FALSE;
416 }
417
418 if (outcode1) {
419 if (outcode1 & CODE_TOP) {
420 y = recty1;
421 x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1);
422 } else if (outcode1 & CODE_BOTTOM) {
423 y = recty2;
424 x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1);
425 } else if (outcode1 & CODE_LEFT) {
426 x = rectx1;
427 y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1);
428 } else if (outcode1 & CODE_RIGHT) {
429 x = rectx2;
430 y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1);
431 }
432 x1 = x;
433 y1 = y;
434 outcode1 = ComputeOutCode(rect, x, y);
435 } else {
436 if (outcode2 & CODE_TOP) {
437 y = recty1;
438 x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1);
439 } else if (outcode2 & CODE_BOTTOM) {
440 y = recty2;
441 x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1);
442 } else if (outcode2 & CODE_LEFT) {
443 x = rectx1;
444 y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1);
445 } else if (outcode2 & CODE_RIGHT) {
446 x = rectx2;
447 y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1);
448 }
449 x2 = x;
450 y2 = y;
451 outcode2 = ComputeOutCode(rect, x, y);
452 }
453 }
454 *X1 = x1;
455 *Y1 = y1;
456 *X2 = x2;
457 *Y2 = y2;
458 return SDL_TRUE;
459 }
460
461 SDL_bool
462 SDL_GetSpanEnclosingRect(int width, int height,
463 int numrects, const SDL_Rect * rects, SDL_Rect *span)
464 {
465 int i;
466 int span_y1, span_y2;
467 int rect_y1, rect_y2;
468
469 if (width < 1) {
470 SDL_InvalidParamError("width");
471 return SDL_FALSE;
472 }
473
474 if (height < 1) {
475 SDL_InvalidParamError("height");
476 return SDL_FALSE;
477 }
478
479 if (!rects) {
480 SDL_InvalidParamError("rects");
481 return SDL_FALSE;
482 }
483
484 if (!span) {
485 SDL_InvalidParamError("span");
486 return SDL_FALSE;
487 }
488
489 if (numrects < 1) {
490 SDL_InvalidParamError("numrects");
491 return SDL_FALSE;
492 }
493
494 /* Initialize to empty rect */
495 span_y1 = height;
496 span_y2 = 0;
497
498 for (i = 0; i < numrects; ++i) {
499 rect_y1 = rects[i].y;
500 rect_y2 = rect_y1 + rects[i].h;
501
502 /* Clip out of bounds rectangles, and expand span rect */
503 if (rect_y1 < 0) {
504 span_y1 = 0;
505 } else if (rect_y1 < span_y1) {
506 span_y1 = rect_y1;
507 }
508 if (rect_y2 > height) {
509 span_y2 = height;
510 } else if (rect_y2 > span_y2) {
511 span_y2 = rect_y2;
512 }
513 }
514 if (span_y2 > span_y1) {
515 span->x = 0;
516 span->y = span_y1;
517 span->w = width;
518 span->h = (span_y2 - span_y1);
519 return SDL_TRUE;
520 }
521 return SDL_FALSE;
522 }
523
524 /* vi: set ts=4 sw=4 expandtab: */
SDL_IntersectRectAndLine
DECLSPEC SDL_bool SDLCALL SDL_IntersectRectAndLine(const SDL_Rect *rect, int *X1, int *Y1, int *X2, int *Y2)
Calculate the intersection of a rectangle and line segment.
Definition: SDL_rect.c:316
CODE_TOP
#define CODE_TOP
Definition: SDL_rect.c:295
NULL
#define NULL
Definition: ftobjs.h:61
SDL_bool
SDL_bool
Definition: SDL_stdinc.h:116
SDL_rect_c.h
CODE_RIGHT
#define CODE_RIGHT
Definition: SDL_rect.c:297
SDL_TRUE
Definition: SDL_stdinc.h:119
x
EGLSurface EGLint x
Definition: eglext.h:293
SDL_Point
The structure that defines a point.
Definition: SDL_rect.h:47
height
EGLSurface EGLint EGLint EGLint EGLint height
Definition: eglext.h:293
CODE_BOTTOM
#define CODE_BOTTOM
Definition: SDL_rect.c:294
ComputeOutCode
static int ComputeOutCode(const SDL_Rect *rect, int x, int y)
Definition: SDL_rect.c:299
SDL_EnclosePoints
DECLSPEC SDL_bool SDLCALL SDL_EnclosePoints(const SDL_Point *points, int count, const SDL_Rect *clip, SDL_Rect *result)
Calculate a minimal rectangle enclosing a set of points.
Definition: SDL_rect.c:192
SDL_InvalidParamError
#define SDL_InvalidParamError(param)
Definition: SDL_error.h:54
SDL_FALSE
Definition: SDL_stdinc.h:118
y1
GLuint GLfloat GLfloat GLfloat GLfloat y1
Definition: glew.h:11582
y2
GLfixed GLfixed GLfixed y2
Definition: glext.h:4559
SDL_RectEmpty
SDL_FORCE_INLINE SDL_bool SDL_RectEmpty(const SDL_Rect *r)
Returns true if the rectangle has no area.
Definition: SDL_rect.h:72
SDL_config.h
SDL_Point::x
int x
Definition: SDL_rect.h:49
result
GLuint64EXT * result
Definition: glew.h:12708
SDL_UnionRect
DECLSPEC void SDLCALL SDL_UnionRect(const SDL_Rect *A, const SDL_Rect *B, SDL_Rect *result)
Calculate the union of two rectangles.
Definition: SDL_rect.c:129
SDL_IntersectRect
DECLSPEC SDL_bool SDLCALL SDL_IntersectRect(const SDL_Rect *A, const SDL_Rect *B, SDL_Rect *result)
Calculate the intersection of two rectangles.
Definition: SDL_rect.c:75
SDL_Point::y
int y
Definition: SDL_rect.h:50
width
EGLSurface EGLint EGLint EGLint width
Definition: eglext.h:293
count
GLint GLsizei count
Definition: gl2ext.h:1011
SDL_HasIntersection
DECLSPEC SDL_bool SDLCALL SDL_HasIntersection(const SDL_Rect *A, const SDL_Rect *B)
Determine whether two rectangles intersect.
Definition: SDL_rect.c:28
CODE_LEFT
#define CODE_LEFT
Definition: SDL_rect.c:296
SDL_Rect::x
int x
Definition: SDL_rect.h:65
SDL_Rect::w
int w
Definition: SDL_rect.h:66
x1
GLuint GLfloat GLfloat GLfloat x1
Definition: glew.h:11582
code
Definition: inftrees.h:24
y
EGLSurface EGLint EGLint y
Definition: eglext.h:293
SDL_Rect::h
int h
Definition: SDL_rect.h:66
x2
GLfixed GLfixed x2
Definition: glext.h:4559
points
GLuint GLdouble GLdouble GLint GLint const GLdouble * points
Definition: glew.h:3337
i
int i
Definition: pngrutil.c:1377
span
GLenum GLenum GLvoid GLvoid GLvoid * span
Definition: glew.h:4447
SDL_Rect::y
int y
Definition: SDL_rect.h:65
SDL_Rect
A rectangle, with the origin at the upper left.
Definition: SDL_rect.h:63
SDL_GetSpanEnclosingRect
SDL_bool SDL_GetSpanEnclosingRect(int width, int height, int numrects, const SDL_Rect *rects, SDL_Rect *span)
Definition: SDL_rect.c:462
SDL_rect.h