src/video/SDL_rect.c
author Sam Lantinga <slouken@libsdl.org>
Sun, 14 Jul 2013 11:28:44 -0700
changeset 7776 d4a39491577f
parent 7191 75360622e65f
child 7868 f92ba4923dcd
permissions -rw-r--r--
Added the platform specific messagebox function to the video function list
slouken@1895
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@6885
     3
  Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
slouken@1895
     4
slouken@5535
     5
  This software is provided 'as-is', without any express or implied
slouken@5535
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     7
  arising from the use of this software.
slouken@1895
     8
slouken@5535
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
    10
  including commercial applications, and to alter it and redistribute it
slouken@5535
    11
  freely, subject to the following restrictions:
slouken@1895
    12
slouken@5535
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@5535
    14
     claim that you wrote the original software. If you use this software
slouken@5535
    15
     in a product, an acknowledgment in the product documentation would be
slouken@5535
    16
     appreciated but is not required.
slouken@5535
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@5535
    18
     misrepresented as being the original software.
slouken@5535
    19
  3. This notice may not be removed or altered from any source distribution.
slouken@1895
    20
*/
slouken@1895
    21
#include "SDL_config.h"
slouken@1895
    22
slouken@5154
    23
#include "SDL_rect.h"
slouken@6044
    24
#include "SDL_rect_c.h"
slouken@1895
    25
slouken@5294
    26
slouken@1895
    27
SDL_bool
slouken@1895
    28
SDL_HasIntersection(const SDL_Rect * A, const SDL_Rect * B)
slouken@1895
    29
{
slouken@1895
    30
    int Amin, Amax, Bmin, Bmax;
slouken@1895
    31
aschiffler@7074
    32
    if (!A) {
aschiffler@7074
    33
        SDL_InvalidParamError("A");
aschiffler@7074
    34
        return SDL_FALSE;
aschiffler@7074
    35
    }
aschiffler@7074
    36
aschiffler@7074
    37
    if (!B) {
aschiffler@7074
    38
        SDL_InvalidParamError("B");
aschiffler@5869
    39
        return SDL_FALSE;
aschiffler@5869
    40
    }
aschiffler@5869
    41
aschiffler@5950
    42
    /* Special cases for empty rects */
aschiffler@5950
    43
    if (SDL_RectEmpty(A) || SDL_RectEmpty(B)) {
aschiffler@5950
    44
        return SDL_FALSE;
aschiffler@5950
    45
    }
aschiffler@5950
    46
slouken@1895
    47
    /* Horizontal intersection */
slouken@1895
    48
    Amin = A->x;
slouken@1895
    49
    Amax = Amin + A->w;
slouken@1895
    50
    Bmin = B->x;
slouken@1895
    51
    Bmax = Bmin + B->w;
slouken@1895
    52
    if (Bmin > Amin)
slouken@1895
    53
        Amin = Bmin;
slouken@1895
    54
    if (Bmax < Amax)
slouken@1895
    55
        Amax = Bmax;
slouken@1895
    56
    if (Amax <= Amin)
slouken@1895
    57
        return SDL_FALSE;
slouken@1895
    58
slouken@1895
    59
    /* Vertical intersection */
slouken@1895
    60
    Amin = A->y;
slouken@1895
    61
    Amax = Amin + A->h;
slouken@1895
    62
    Bmin = B->y;
slouken@1895
    63
    Bmax = Bmin + B->h;
slouken@1895
    64
    if (Bmin > Amin)
slouken@1895
    65
        Amin = Bmin;
slouken@1895
    66
    if (Bmax < Amax)
slouken@1895
    67
        Amax = Bmax;
slouken@1895
    68
    if (Amax <= Amin)
slouken@1895
    69
        return SDL_FALSE;
slouken@1895
    70
slouken@1895
    71
    return SDL_TRUE;
slouken@1895
    72
}
slouken@1895
    73
slouken@1895
    74
SDL_bool
slouken@1895
    75
SDL_IntersectRect(const SDL_Rect * A, const SDL_Rect * B, SDL_Rect * result)
slouken@1895
    76
{
slouken@1895
    77
    int Amin, Amax, Bmin, Bmax;
slouken@1895
    78
aschiffler@7074
    79
    if (!A) {
aschiffler@7074
    80
        SDL_InvalidParamError("A");
aschiffler@7074
    81
        return SDL_FALSE;
aschiffler@7074
    82
    }
aschiffler@7074
    83
aschiffler@7074
    84
    if (!B) {
aschiffler@7074
    85
        SDL_InvalidParamError("B");
aschiffler@7074
    86
        return SDL_FALSE;
aschiffler@7074
    87
    }
slouken@7191
    88
aschiffler@7074
    89
    if (!result) {
aschiffler@7074
    90
        SDL_InvalidParamError("result");
aschiffler@5869
    91
        return SDL_FALSE;
aschiffler@5869
    92
    }
aschiffler@5869
    93
aschiffler@5950
    94
    /* Special cases for empty rects */
aschiffler@5950
    95
    if (SDL_RectEmpty(A) || SDL_RectEmpty(B)) {
aschiffler@7074
    96
        result->w = 0;
aschiffler@7074
    97
        result->h = 0;
aschiffler@5950
    98
        return SDL_FALSE;
aschiffler@5950
    99
    }
slouken@7191
   100
slouken@1895
   101
    /* Horizontal intersection */
slouken@1895
   102
    Amin = A->x;
slouken@1895
   103
    Amax = Amin + A->w;
slouken@1895
   104
    Bmin = B->x;
slouken@1895
   105
    Bmax = Bmin + B->w;
slouken@1895
   106
    if (Bmin > Amin)
slouken@1895
   107
        Amin = Bmin;
slouken@1895
   108
    result->x = Amin;
slouken@1895
   109
    if (Bmax < Amax)
slouken@1895
   110
        Amax = Bmax;
slouken@1895
   111
    result->w = Amax - Amin;
slouken@1895
   112
slouken@1895
   113
    /* Vertical intersection */
slouken@1895
   114
    Amin = A->y;
slouken@1895
   115
    Amax = Amin + A->h;
slouken@1895
   116
    Bmin = B->y;
slouken@1895
   117
    Bmax = Bmin + B->h;
slouken@1895
   118
    if (Bmin > Amin)
slouken@1895
   119
        Amin = Bmin;
slouken@1895
   120
    result->y = Amin;
slouken@1895
   121
    if (Bmax < Amax)
slouken@1895
   122
        Amax = Bmax;
slouken@1895
   123
    result->h = Amax - Amin;
slouken@1895
   124
slouken@1895
   125
    return !SDL_RectEmpty(result);
slouken@1895
   126
}
slouken@1895
   127
slouken@1895
   128
void
slouken@1895
   129
SDL_UnionRect(const SDL_Rect * A, const SDL_Rect * B, SDL_Rect * result)
slouken@1895
   130
{
slouken@1895
   131
    int Amin, Amax, Bmin, Bmax;
slouken@1895
   132
aschiffler@7074
   133
    if (!A) {
aschiffler@7074
   134
        SDL_InvalidParamError("A");
aschiffler@7074
   135
        return;
aschiffler@7074
   136
    }
aschiffler@7074
   137
aschiffler@7074
   138
    if (!B) {
aschiffler@7074
   139
        SDL_InvalidParamError("B");
aschiffler@7074
   140
        return;
aschiffler@7074
   141
    }
slouken@7191
   142
aschiffler@7074
   143
    if (!result) {
aschiffler@7074
   144
        SDL_InvalidParamError("result");
aschiffler@5869
   145
        return;
aschiffler@5869
   146
    }
aschiffler@5869
   147
aschiffler@5950
   148
    /* Special cases for empty Rects */
aschiffler@5950
   149
    if (SDL_RectEmpty(A)) {
aschiffler@5950
   150
      if (SDL_RectEmpty(B)) {
aschiffler@5950
   151
       /* A and B empty */
aschiffler@5950
   152
       return;
aschiffler@5950
   153
      } else {
aschiffler@5950
   154
       /* A empty, B not empty */
aschiffler@5950
   155
       *result = *B;
aschiffler@5950
   156
       return;
aschiffler@5950
   157
      }
slouken@7191
   158
    } else {
aschiffler@5950
   159
      if (SDL_RectEmpty(B)) {
aschiffler@5950
   160
       /* A not empty, B empty */
aschiffler@5950
   161
       *result = *A;
aschiffler@5950
   162
       return;
slouken@7191
   163
      }
aschiffler@5950
   164
    }
slouken@7191
   165
slouken@1895
   166
    /* Horizontal union */
slouken@1895
   167
    Amin = A->x;
slouken@1895
   168
    Amax = Amin + A->w;
slouken@1895
   169
    Bmin = B->x;
slouken@1895
   170
    Bmax = Bmin + B->w;
slouken@1895
   171
    if (Bmin < Amin)
slouken@1895
   172
        Amin = Bmin;
slouken@1895
   173
    result->x = Amin;
slouken@1895
   174
    if (Bmax > Amax)
slouken@1895
   175
        Amax = Bmax;
slouken@1895
   176
    result->w = Amax - Amin;
slouken@1895
   177
aschiffler@5950
   178
    /* Vertical union */
slouken@1895
   179
    Amin = A->y;
slouken@1895
   180
    Amax = Amin + A->h;
slouken@1895
   181
    Bmin = B->y;
slouken@1895
   182
    Bmax = Bmin + B->h;
slouken@1895
   183
    if (Bmin < Amin)
slouken@1895
   184
        Amin = Bmin;
slouken@1895
   185
    result->y = Amin;
slouken@1895
   186
    if (Bmax > Amax)
slouken@1895
   187
        Amax = Bmax;
slouken@1895
   188
    result->h = Amax - Amin;
slouken@1895
   189
}
slouken@1895
   190
slouken@2909
   191
SDL_bool
slouken@3536
   192
SDL_EnclosePoints(const SDL_Point * points, int count, const SDL_Rect * clip,
slouken@3536
   193
                  SDL_Rect * result)
slouken@3536
   194
{
slouken@4456
   195
    int minx = 0;
slouken@4456
   196
    int miny = 0;
slouken@4456
   197
    int maxx = 0;
slouken@4456
   198
    int maxy = 0;
slouken@3536
   199
    int x, y, i;
slouken@3536
   200
aschiffler@5902
   201
    if (!points) {
aschiffler@7074
   202
        SDL_InvalidParamError("points");
aschiffler@5869
   203
        return SDL_FALSE;
aschiffler@5869
   204
    }
aschiffler@5869
   205
slouken@3536
   206
    if (count < 1) {
aschiffler@7074
   207
        SDL_InvalidParamError("count");
slouken@3536
   208
        return SDL_FALSE;
slouken@3536
   209
    }
slouken@3536
   210
slouken@3536
   211
    if (clip) {
icculus@5953
   212
        SDL_bool added = SDL_FALSE;
icculus@5953
   213
        const int clip_minx = clip->x;
icculus@5953
   214
        const int clip_miny = clip->y;
icculus@5953
   215
        const int clip_maxx = clip->x+clip->w-1;
icculus@5953
   216
        const int clip_maxy = clip->y+clip->h-1;
icculus@5953
   217
aschiffler@5950
   218
        /* Special case for empty rectangle */
aschiffler@5950
   219
        if (SDL_RectEmpty(clip)) {
aschiffler@5950
   220
            return SDL_FALSE;
aschiffler@5950
   221
        }
slouken@7191
   222
slouken@3536
   223
        for (i = 0; i < count; ++i) {
slouken@3536
   224
            x = points[i].x;
slouken@3536
   225
            y = points[i].y;
slouken@3536
   226
slouken@3536
   227
            if (x < clip_minx || x > clip_maxx ||
slouken@3536
   228
                y < clip_miny || y > clip_maxy) {
slouken@3536
   229
                continue;
slouken@3536
   230
            }
slouken@3536
   231
            if (!added) {
aschiffler@5902
   232
                /* Special case: if no result was requested, we are done */
aschiffler@5902
   233
                if (result == NULL) {
aschiffler@5902
   234
                    return SDL_TRUE;
aschiffler@5902
   235
                }
aschiffler@5902
   236
aschiffler@5902
   237
                /* First point added */
slouken@3536
   238
                minx = maxx = x;
slouken@3536
   239
                miny = maxy = y;
slouken@3536
   240
                added = SDL_TRUE;
slouken@3536
   241
                continue;
slouken@3536
   242
            }
slouken@3536
   243
            if (x < minx) {
slouken@3536
   244
                minx = x;
slouken@3536
   245
            } else if (x > maxx) {
slouken@3536
   246
                maxx = x;
slouken@3536
   247
            }
slouken@3536
   248
            if (y < miny) {
slouken@3536
   249
                miny = y;
slouken@3536
   250
            } else if (y > maxy) {
slouken@3536
   251
                maxy = y;
slouken@3536
   252
            }
slouken@3536
   253
        }
slouken@3536
   254
        if (!added) {
slouken@3536
   255
            return SDL_FALSE;
slouken@3536
   256
        }
slouken@3536
   257
    } else {
aschiffler@5902
   258
        /* Special case: if no result was requested, we are done */
aschiffler@5902
   259
        if (result == NULL) {
aschiffler@5902
   260
            return SDL_TRUE;
aschiffler@5902
   261
        }
slouken@7191
   262
slouken@3536
   263
        /* No clipping, always add the first point */
slouken@3536
   264
        minx = maxx = points[0].x;
slouken@3536
   265
        miny = maxy = points[0].y;
slouken@3536
   266
slouken@3536
   267
        for (i = 1; i < count; ++i) {
slouken@3536
   268
            x = points[i].x;
slouken@3536
   269
            y = points[i].y;
slouken@3536
   270
slouken@3536
   271
            if (x < minx) {
slouken@3536
   272
                minx = x;
slouken@3536
   273
            } else if (x > maxx) {
slouken@3536
   274
                maxx = x;
slouken@3536
   275
            }
slouken@3536
   276
            if (y < miny) {
slouken@3536
   277
                miny = y;
slouken@3536
   278
            } else if (y > maxy) {
slouken@3536
   279
                maxy = y;
slouken@3536
   280
            }
slouken@3536
   281
        }
slouken@3536
   282
    }
slouken@3536
   283
slouken@3536
   284
    if (result) {
slouken@3536
   285
        result->x = minx;
slouken@3536
   286
        result->y = miny;
slouken@3536
   287
        result->w = (maxx-minx)+1;
slouken@3536
   288
        result->h = (maxy-miny)+1;
slouken@3536
   289
    }
slouken@3536
   290
    return SDL_TRUE;
slouken@3536
   291
}
slouken@3536
   292
slouken@3541
   293
/* Use the Cohen-Sutherland algorithm for line clipping */
slouken@3541
   294
#define CODE_BOTTOM 1
slouken@3541
   295
#define CODE_TOP    2
slouken@3541
   296
#define CODE_LEFT   4
slouken@3541
   297
#define CODE_RIGHT  8
slouken@3541
   298
slouken@3541
   299
static int ComputeOutCode(const SDL_Rect * rect, int x, int y)
slouken@3541
   300
{
slouken@3541
   301
    int code = 0;
slouken@3541
   302
    if (y < 0) {
slouken@3541
   303
        code |= CODE_TOP;
slouken@3541
   304
    } else if (y >= rect->y + rect->h) {
slouken@3541
   305
        code |= CODE_BOTTOM;
slouken@3541
   306
    }
slouken@3541
   307
    if (x < 0) {
slouken@3541
   308
        code |= CODE_LEFT;
slouken@3541
   309
    } else if (x >= rect->x + rect->w) {
slouken@3541
   310
        code |= CODE_RIGHT;
slouken@3541
   311
    }
slouken@3541
   312
    return code;
slouken@3541
   313
}
slouken@3541
   314
slouken@3536
   315
SDL_bool
slouken@2920
   316
SDL_IntersectRectAndLine(const SDL_Rect * rect, int *X1, int *Y1, int *X2,
slouken@2920
   317
                         int *Y2)
slouken@2909
   318
{
slouken@4456
   319
    int x = 0;
slouken@4456
   320
    int y = 0;
slouken@2909
   321
    int x1, y1;
slouken@2909
   322
    int x2, y2;
slouken@2909
   323
    int rectx1;
slouken@2909
   324
    int recty1;
slouken@2909
   325
    int rectx2;
slouken@2909
   326
    int recty2;
slouken@3541
   327
    int outcode1, outcode2;
slouken@2909
   328
aschiffler@7074
   329
    if (!rect) {
aschiffler@7074
   330
        SDL_InvalidParamError("rect");
aschiffler@7074
   331
        return SDL_FALSE;
aschiffler@7074
   332
    }
slouken@7191
   333
aschiffler@7074
   334
    if (!X1) {
aschiffler@7074
   335
        SDL_InvalidParamError("X1");
aschiffler@7074
   336
        return SDL_FALSE;
aschiffler@7074
   337
    }
slouken@7191
   338
aschiffler@7074
   339
    if (!Y1) {
aschiffler@7074
   340
        SDL_InvalidParamError("Y1");
aschiffler@7074
   341
        return SDL_FALSE;
aschiffler@7074
   342
    }
slouken@7191
   343
aschiffler@7074
   344
    if (!X2) {
aschiffler@7074
   345
        SDL_InvalidParamError("X2");
aschiffler@7074
   346
        return SDL_FALSE;
aschiffler@7074
   347
    }
slouken@7191
   348
aschiffler@7074
   349
    if (!Y2) {
aschiffler@7074
   350
        SDL_InvalidParamError("Y2");
slouken@3046
   351
        return SDL_FALSE;
slouken@2909
   352
    }
slouken@2909
   353
aschiffler@5950
   354
    /* Special case for empty rect */
aschiffler@5950
   355
    if (SDL_RectEmpty(rect)) {
aschiffler@5950
   356
        return SDL_FALSE;
aschiffler@5950
   357
    }
slouken@7191
   358
slouken@2909
   359
    x1 = *X1;
slouken@2909
   360
    y1 = *Y1;
slouken@2909
   361
    x2 = *X2;
slouken@2909
   362
    y2 = *Y2;
slouken@2909
   363
    rectx1 = rect->x;
slouken@2909
   364
    recty1 = rect->y;
slouken@2909
   365
    rectx2 = rect->x + rect->w - 1;
slouken@2909
   366
    recty2 = rect->y + rect->h - 1;
slouken@2909
   367
slouken@2909
   368
    /* Check to see if entire line is inside rect */
slouken@2909
   369
    if (x1 >= rectx1 && x1 <= rectx2 && x2 >= rectx1 && x2 <= rectx2 &&
slouken@2909
   370
        y1 >= recty1 && y1 <= recty2 && y2 >= recty1 && y2 <= recty2) {
slouken@2909
   371
        return SDL_TRUE;
slouken@2909
   372
    }
slouken@2909
   373
slouken@2994
   374
    /* Check to see if entire line is to one side of rect */
slouken@2909
   375
    if ((x1 < rectx1 && x2 < rectx1) || (x1 > rectx2 && x2 > rectx2) ||
slouken@3004
   376
        (y1 < recty1 && y2 < recty1) || (y1 > recty2 && y2 > recty2)) {
slouken@2909
   377
        return SDL_FALSE;
slouken@2909
   378
    }
slouken@2909
   379
slouken@2994
   380
    if (y1 == y2) {
slouken@2909
   381
        /* Horizontal line, easy to clip */
slouken@2909
   382
        if (x1 < rectx1) {
slouken@2909
   383
            *X1 = rectx1;
slouken@2909
   384
        } else if (x1 > rectx2) {
slouken@2909
   385
            *X1 = rectx2;
slouken@2909
   386
        }
slouken@2909
   387
        if (x2 < rectx1) {
slouken@2909
   388
            *X2 = rectx1;
slouken@2909
   389
        } else if (x2 > rectx2) {
slouken@2909
   390
            *X2 = rectx2;
slouken@2909
   391
        }
slouken@2909
   392
        return SDL_TRUE;
slouken@2909
   393
    }
slouken@2909
   394
slouken@2909
   395
    if (x1 == x2) {
slouken@2909
   396
        /* Vertical line, easy to clip */
slouken@2909
   397
        if (y1 < recty1) {
slouken@2909
   398
            *Y1 = recty1;
slouken@2909
   399
        } else if (y1 > recty2) {
slouken@2909
   400
            *Y1 = recty2;
slouken@2909
   401
        }
slouken@2909
   402
        if (y2 < recty1) {
slouken@2909
   403
            *Y2 = recty1;
slouken@2909
   404
        } else if (y2 > recty2) {
slouken@2909
   405
            *Y2 = recty2;
slouken@2909
   406
        }
slouken@2909
   407
        return SDL_TRUE;
slouken@2909
   408
    }
slouken@2909
   409
slouken@3541
   410
    /* More complicated Cohen-Sutherland algorithm */
slouken@3541
   411
    outcode1 = ComputeOutCode(rect, x1, y1);
slouken@3541
   412
    outcode2 = ComputeOutCode(rect, x2, y2);
slouken@3541
   413
    while (outcode1 || outcode2) {
slouken@3541
   414
        if (outcode1 & outcode2) {
slouken@3541
   415
            return SDL_FALSE;
slouken@2994
   416
        }
slouken@2994
   417
slouken@3541
   418
        if (outcode1) {
slouken@3541
   419
            if (outcode1 & CODE_TOP) {
slouken@3541
   420
                y = recty1;
slouken@3541
   421
                x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1);
slouken@3541
   422
            } else if (outcode1 & CODE_BOTTOM) {
slouken@3541
   423
                y = recty2;
slouken@3541
   424
                x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1);
slouken@3541
   425
            } else if (outcode1 & CODE_LEFT) {
slouken@3541
   426
                x = rectx1;
slouken@3541
   427
                y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1);
slouken@3541
   428
            } else if (outcode1 & CODE_RIGHT) {
slouken@3541
   429
                x = rectx2;
slouken@3541
   430
                y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1);
slouken@3541
   431
            }
slouken@3541
   432
            x1 = x;
slouken@3541
   433
            y1 = y;
slouken@3541
   434
            outcode1 = ComputeOutCode(rect, x, y);
slouken@3542
   435
        } else {
slouken@3541
   436
            if (outcode2 & CODE_TOP) {
slouken@3541
   437
                y = recty1;
slouken@3541
   438
                x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1);
slouken@3541
   439
            } else if (outcode2 & CODE_BOTTOM) {
slouken@3541
   440
                y = recty2;
slouken@3541
   441
                x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1);
slouken@3541
   442
            } else if (outcode2 & CODE_LEFT) {
slouken@3541
   443
                x = rectx1;
slouken@3541
   444
                y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1);
slouken@3541
   445
            } else if (outcode2 & CODE_RIGHT) {
slouken@3541
   446
                x = rectx2;
slouken@3541
   447
                y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1);
slouken@3541
   448
            }
slouken@3541
   449
            x2 = x;
slouken@3541
   450
            y2 = y;
slouken@3541
   451
            outcode2 = ComputeOutCode(rect, x, y);
slouken@2994
   452
        }
slouken@2994
   453
    }
slouken@3541
   454
    *X1 = x1;
slouken@3541
   455
    *Y1 = y1;
slouken@3541
   456
    *X2 = x2;
slouken@3541
   457
    *Y2 = y2;
slouken@3541
   458
    return SDL_TRUE;
slouken@2909
   459
}
slouken@2909
   460
slouken@5294
   461
SDL_bool
slouken@5294
   462
SDL_GetSpanEnclosingRect(int width, int height,
slouken@7014
   463
                         int numrects, const SDL_Rect * rects, SDL_Rect *span)
slouken@5294
   464
{
slouken@5294
   465
    int i;
slouken@5294
   466
    int span_y1, span_y2;
slouken@5294
   467
    int rect_y1, rect_y2;
slouken@5294
   468
aschiffler@7074
   469
    if (width < 1) {
aschiffler@7074
   470
        SDL_InvalidParamError("width");
aschiffler@5869
   471
        return SDL_FALSE;
aschiffler@5869
   472
    }
aschiffler@5869
   473
aschiffler@7074
   474
    if (height < 1) {
aschiffler@7074
   475
        SDL_InvalidParamError("height");
aschiffler@7074
   476
        return SDL_FALSE;
aschiffler@7074
   477
    }
aschiffler@7074
   478
aschiffler@7074
   479
    if (!rects) {
aschiffler@7074
   480
        SDL_InvalidParamError("rects");
aschiffler@7074
   481
        return SDL_FALSE;
aschiffler@7074
   482
    }
aschiffler@7074
   483
aschiffler@7074
   484
    if (!span) {
aschiffler@7074
   485
        SDL_InvalidParamError("span");
aschiffler@5869
   486
        return SDL_FALSE;
aschiffler@5869
   487
    }
aschiffler@5869
   488
aschiffler@5869
   489
    if (numrects < 1) {
aschiffler@7074
   490
        SDL_InvalidParamError("numrects");
aschiffler@5869
   491
        return SDL_FALSE;
aschiffler@5869
   492
    }
aschiffler@5869
   493
slouken@5294
   494
    /* Initialize to empty rect */
slouken@5294
   495
    span_y1 = height;
slouken@5294
   496
    span_y2 = 0;
slouken@5294
   497
slouken@5294
   498
    for (i = 0; i < numrects; ++i) {
slouken@5294
   499
        rect_y1 = rects[i].y;
slouken@5294
   500
        rect_y2 = rect_y1 + rects[i].h;
slouken@5294
   501
slouken@5294
   502
        /* Clip out of bounds rectangles, and expand span rect */
slouken@5294
   503
        if (rect_y1 < 0) {
slouken@5294
   504
            span_y1 = 0;
slouken@5294
   505
        } else if (rect_y1 < span_y1) {
slouken@5294
   506
            span_y1 = rect_y1;
slouken@5294
   507
        }
slouken@5294
   508
        if (rect_y2 > height) {
slouken@5294
   509
            span_y2 = height;
slouken@5294
   510
        } else if (rect_y2 > span_y2) {
slouken@5294
   511
            span_y2 = rect_y2;
slouken@5294
   512
        }
slouken@5294
   513
    }
slouken@5294
   514
    if (span_y2 > span_y1) {
slouken@5294
   515
        span->x = 0;
slouken@5294
   516
        span->y = span_y1;
slouken@5294
   517
        span->w = width;
slouken@5294
   518
        span->h = (span_y2 - span_y1);
slouken@5294
   519
        return SDL_TRUE;
slouken@5294
   520
    }
slouken@5294
   521
    return SDL_FALSE;
slouken@5294
   522
}
slouken@5294
   523
slouken@1895
   524
/* vi: set ts=4 sw=4 expandtab: */