src/video/SDL_rect.c
author Sam Lantinga
Fri, 27 Jan 2017 21:23:27 -0800
changeset 10861 71d8f9afb690
parent 10737 3406a0f8b041
child 11811 5d94cb6b24d3
permissions -rw-r--r--
Fixed bug 3569 - GL_UpdateViewport leaves PROJECTION matrix selected

Tom Seddon

GL_ActivateRenderer may call GL_UpdateViewport, which leaves the GL_PROJECTION matrix selected. But after GL_ResetState, the GL_MODELVIEW matrix is selected, suggesting that's the intended default state.

It seems at least like these should be consistent. Presumably GL_UpdateViewport should be doing a glMatrixMode(GL_MODELVIEW) before it finishes.
slouken@1895
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@10737
     3
  Copyright (C) 1997-2017 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
*/
icculus@8093
    21
#include "../SDL_internal.h"
slouken@1895
    22
slouken@5154
    23
#include "SDL_rect.h"
slouken@6044
    24
#include "SDL_rect_c.h"
icculus@10650
    25
#include "SDL_assert.h"
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@7868
   299
static int
slouken@7868
   300
ComputeOutCode(const SDL_Rect * rect, int x, int y)
slouken@3541
   301
{
slouken@3541
   302
    int code = 0;
slouken@7868
   303
    if (y < rect->y) {
slouken@3541
   304
        code |= CODE_TOP;
slouken@3541
   305
    } else if (y >= rect->y + rect->h) {
slouken@3541
   306
        code |= CODE_BOTTOM;
slouken@3541
   307
    }
slouken@7868
   308
    if (x < rect->x) {
slouken@3541
   309
        code |= CODE_LEFT;
slouken@3541
   310
    } else if (x >= rect->x + rect->w) {
slouken@3541
   311
        code |= CODE_RIGHT;
slouken@3541
   312
    }
slouken@3541
   313
    return code;
slouken@3541
   314
}
slouken@3541
   315
slouken@3536
   316
SDL_bool
slouken@2920
   317
SDL_IntersectRectAndLine(const SDL_Rect * rect, int *X1, int *Y1, int *X2,
slouken@2920
   318
                         int *Y2)
slouken@2909
   319
{
slouken@4456
   320
    int x = 0;
slouken@4456
   321
    int y = 0;
slouken@2909
   322
    int x1, y1;
slouken@2909
   323
    int x2, y2;
slouken@2909
   324
    int rectx1;
slouken@2909
   325
    int recty1;
slouken@2909
   326
    int rectx2;
slouken@2909
   327
    int recty2;
slouken@3541
   328
    int outcode1, outcode2;
slouken@2909
   329
aschiffler@7074
   330
    if (!rect) {
aschiffler@7074
   331
        SDL_InvalidParamError("rect");
aschiffler@7074
   332
        return SDL_FALSE;
aschiffler@7074
   333
    }
slouken@7191
   334
aschiffler@7074
   335
    if (!X1) {
aschiffler@7074
   336
        SDL_InvalidParamError("X1");
aschiffler@7074
   337
        return SDL_FALSE;
aschiffler@7074
   338
    }
slouken@7191
   339
aschiffler@7074
   340
    if (!Y1) {
aschiffler@7074
   341
        SDL_InvalidParamError("Y1");
aschiffler@7074
   342
        return SDL_FALSE;
aschiffler@7074
   343
    }
slouken@7191
   344
aschiffler@7074
   345
    if (!X2) {
aschiffler@7074
   346
        SDL_InvalidParamError("X2");
aschiffler@7074
   347
        return SDL_FALSE;
aschiffler@7074
   348
    }
slouken@7191
   349
aschiffler@7074
   350
    if (!Y2) {
aschiffler@7074
   351
        SDL_InvalidParamError("Y2");
slouken@3046
   352
        return SDL_FALSE;
slouken@2909
   353
    }
slouken@2909
   354
aschiffler@5950
   355
    /* Special case for empty rect */
aschiffler@5950
   356
    if (SDL_RectEmpty(rect)) {
aschiffler@5950
   357
        return SDL_FALSE;
aschiffler@5950
   358
    }
slouken@7191
   359
slouken@2909
   360
    x1 = *X1;
slouken@2909
   361
    y1 = *Y1;
slouken@2909
   362
    x2 = *X2;
slouken@2909
   363
    y2 = *Y2;
slouken@2909
   364
    rectx1 = rect->x;
slouken@2909
   365
    recty1 = rect->y;
slouken@2909
   366
    rectx2 = rect->x + rect->w - 1;
slouken@2909
   367
    recty2 = rect->y + rect->h - 1;
slouken@2909
   368
slouken@2909
   369
    /* Check to see if entire line is inside rect */
slouken@2909
   370
    if (x1 >= rectx1 && x1 <= rectx2 && x2 >= rectx1 && x2 <= rectx2 &&
slouken@2909
   371
        y1 >= recty1 && y1 <= recty2 && y2 >= recty1 && y2 <= recty2) {
slouken@2909
   372
        return SDL_TRUE;
slouken@2909
   373
    }
slouken@2909
   374
slouken@2994
   375
    /* Check to see if entire line is to one side of rect */
slouken@2909
   376
    if ((x1 < rectx1 && x2 < rectx1) || (x1 > rectx2 && x2 > rectx2) ||
slouken@3004
   377
        (y1 < recty1 && y2 < recty1) || (y1 > recty2 && y2 > recty2)) {
slouken@2909
   378
        return SDL_FALSE;
slouken@2909
   379
    }
slouken@2909
   380
slouken@2994
   381
    if (y1 == y2) {
slouken@2909
   382
        /* Horizontal line, easy to clip */
slouken@2909
   383
        if (x1 < rectx1) {
slouken@2909
   384
            *X1 = rectx1;
slouken@2909
   385
        } else if (x1 > rectx2) {
slouken@2909
   386
            *X1 = rectx2;
slouken@2909
   387
        }
slouken@2909
   388
        if (x2 < rectx1) {
slouken@2909
   389
            *X2 = rectx1;
slouken@2909
   390
        } else if (x2 > rectx2) {
slouken@2909
   391
            *X2 = rectx2;
slouken@2909
   392
        }
slouken@2909
   393
        return SDL_TRUE;
slouken@2909
   394
    }
slouken@2909
   395
slouken@2909
   396
    if (x1 == x2) {
slouken@2909
   397
        /* Vertical line, easy to clip */
slouken@2909
   398
        if (y1 < recty1) {
slouken@2909
   399
            *Y1 = recty1;
slouken@2909
   400
        } else if (y1 > recty2) {
slouken@2909
   401
            *Y1 = recty2;
slouken@2909
   402
        }
slouken@2909
   403
        if (y2 < recty1) {
slouken@2909
   404
            *Y2 = recty1;
slouken@2909
   405
        } else if (y2 > recty2) {
slouken@2909
   406
            *Y2 = recty2;
slouken@2909
   407
        }
slouken@2909
   408
        return SDL_TRUE;
slouken@2909
   409
    }
slouken@2909
   410
slouken@3541
   411
    /* More complicated Cohen-Sutherland algorithm */
slouken@3541
   412
    outcode1 = ComputeOutCode(rect, x1, y1);
slouken@3541
   413
    outcode2 = ComputeOutCode(rect, x2, y2);
slouken@3541
   414
    while (outcode1 || outcode2) {
slouken@3541
   415
        if (outcode1 & outcode2) {
slouken@3541
   416
            return SDL_FALSE;
slouken@2994
   417
        }
slouken@2994
   418
slouken@3541
   419
        if (outcode1) {
slouken@3541
   420
            if (outcode1 & CODE_TOP) {
slouken@3541
   421
                y = recty1;
slouken@3541
   422
                x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1);
slouken@3541
   423
            } else if (outcode1 & CODE_BOTTOM) {
slouken@3541
   424
                y = recty2;
slouken@3541
   425
                x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1);
slouken@3541
   426
            } else if (outcode1 & CODE_LEFT) {
slouken@3541
   427
                x = rectx1;
slouken@3541
   428
                y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1);
slouken@3541
   429
            } else if (outcode1 & CODE_RIGHT) {
slouken@3541
   430
                x = rectx2;
slouken@3541
   431
                y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1);
slouken@3541
   432
            }
slouken@3541
   433
            x1 = x;
slouken@3541
   434
            y1 = y;
slouken@3541
   435
            outcode1 = ComputeOutCode(rect, x, y);
slouken@3542
   436
        } else {
slouken@3541
   437
            if (outcode2 & CODE_TOP) {
slouken@3541
   438
                y = recty1;
slouken@3541
   439
                x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1);
slouken@3541
   440
            } else if (outcode2 & CODE_BOTTOM) {
slouken@3541
   441
                y = recty2;
slouken@3541
   442
                x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1);
slouken@3541
   443
            } else if (outcode2 & CODE_LEFT) {
icculus@10650
   444
                /* If this assertion ever fires, here's the static analysis that warned about it:
icculus@10650
   445
                   http://buildbot.libsdl.org/sdl-static-analysis/sdl-macosx-static-analysis/sdl-macosx-static-analysis-1101/report-b0d01a.html#EndPath */
icculus@10650
   446
                SDL_assert(x2 != x1);  /* if equal: division by zero. */
slouken@3541
   447
                x = rectx1;
slouken@3541
   448
                y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1);
slouken@3541
   449
            } else if (outcode2 & CODE_RIGHT) {
icculus@10650
   450
                /* If this assertion ever fires, here's the static analysis that warned about it:
icculus@10650
   451
                   http://buildbot.libsdl.org/sdl-static-analysis/sdl-macosx-static-analysis/sdl-macosx-static-analysis-1101/report-39b114.html#EndPath */
icculus@10650
   452
                SDL_assert(x2 != x1);  /* if equal: division by zero. */
slouken@3541
   453
                x = rectx2;
slouken@3541
   454
                y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1);
slouken@3541
   455
            }
slouken@3541
   456
            x2 = x;
slouken@3541
   457
            y2 = y;
slouken@3541
   458
            outcode2 = ComputeOutCode(rect, x, y);
slouken@2994
   459
        }
slouken@2994
   460
    }
slouken@3541
   461
    *X1 = x1;
slouken@3541
   462
    *Y1 = y1;
slouken@3541
   463
    *X2 = x2;
slouken@3541
   464
    *Y2 = y2;
slouken@3541
   465
    return SDL_TRUE;
slouken@2909
   466
}
slouken@2909
   467
slouken@5294
   468
SDL_bool
slouken@5294
   469
SDL_GetSpanEnclosingRect(int width, int height,
slouken@7014
   470
                         int numrects, const SDL_Rect * rects, SDL_Rect *span)
slouken@5294
   471
{
slouken@5294
   472
    int i;
slouken@5294
   473
    int span_y1, span_y2;
slouken@5294
   474
    int rect_y1, rect_y2;
slouken@5294
   475
aschiffler@7074
   476
    if (width < 1) {
aschiffler@7074
   477
        SDL_InvalidParamError("width");
aschiffler@5869
   478
        return SDL_FALSE;
aschiffler@5869
   479
    }
aschiffler@5869
   480
aschiffler@7074
   481
    if (height < 1) {
aschiffler@7074
   482
        SDL_InvalidParamError("height");
aschiffler@7074
   483
        return SDL_FALSE;
aschiffler@7074
   484
    }
aschiffler@7074
   485
aschiffler@7074
   486
    if (!rects) {
aschiffler@7074
   487
        SDL_InvalidParamError("rects");
aschiffler@7074
   488
        return SDL_FALSE;
aschiffler@7074
   489
    }
aschiffler@7074
   490
aschiffler@7074
   491
    if (!span) {
aschiffler@7074
   492
        SDL_InvalidParamError("span");
aschiffler@5869
   493
        return SDL_FALSE;
aschiffler@5869
   494
    }
aschiffler@5869
   495
aschiffler@5869
   496
    if (numrects < 1) {
aschiffler@7074
   497
        SDL_InvalidParamError("numrects");
aschiffler@5869
   498
        return SDL_FALSE;
aschiffler@5869
   499
    }
aschiffler@5869
   500
slouken@5294
   501
    /* Initialize to empty rect */
slouken@5294
   502
    span_y1 = height;
slouken@5294
   503
    span_y2 = 0;
slouken@5294
   504
slouken@5294
   505
    for (i = 0; i < numrects; ++i) {
slouken@5294
   506
        rect_y1 = rects[i].y;
slouken@5294
   507
        rect_y2 = rect_y1 + rects[i].h;
slouken@5294
   508
slouken@5294
   509
        /* Clip out of bounds rectangles, and expand span rect */
slouken@5294
   510
        if (rect_y1 < 0) {
slouken@5294
   511
            span_y1 = 0;
slouken@5294
   512
        } else if (rect_y1 < span_y1) {
slouken@5294
   513
            span_y1 = rect_y1;
slouken@5294
   514
        }
slouken@5294
   515
        if (rect_y2 > height) {
slouken@5294
   516
            span_y2 = height;
slouken@5294
   517
        } else if (rect_y2 > span_y2) {
slouken@5294
   518
            span_y2 = rect_y2;
slouken@5294
   519
        }
slouken@5294
   520
    }
slouken@5294
   521
    if (span_y2 > span_y1) {
slouken@5294
   522
        span->x = 0;
slouken@5294
   523
        span->y = span_y1;
slouken@5294
   524
        span->w = width;
slouken@5294
   525
        span->h = (span_y2 - span_y1);
slouken@5294
   526
        return SDL_TRUE;
slouken@5294
   527
    }
slouken@5294
   528
    return SDL_FALSE;
slouken@5294
   529
}
slouken@5294
   530
slouken@1895
   531
/* vi: set ts=4 sw=4 expandtab: */