src/video/SDL_rect.c
changeset 2994 7563b99e9a49
parent 2920 cdb01906cb7e
child 2997 e4f025078c1c
equal deleted inserted replaced
2993:2fad80c77c17 2994:7563b99e9a49
   146     if (x1 >= rectx1 && x1 <= rectx2 && x2 >= rectx1 && x2 <= rectx2 &&
   146     if (x1 >= rectx1 && x1 <= rectx2 && x2 >= rectx1 && x2 <= rectx2 &&
   147         y1 >= recty1 && y1 <= recty2 && y2 >= recty1 && y2 <= recty2) {
   147         y1 >= recty1 && y1 <= recty2 && y2 >= recty1 && y2 <= recty2) {
   148         return SDL_TRUE;
   148         return SDL_TRUE;
   149     }
   149     }
   150 
   150 
   151     /* Check to see if entire line is outside rect */
   151     /* Check to see if entire line is to one side of rect */
   152     if ((x1 < rectx1 && x2 < rectx1) || (x1 > rectx2 && x2 > rectx2) ||
   152     if ((x1 < rectx1 && x2 < rectx1) || (x1 > rectx2 && x2 > rectx2) ||
   153         (y1 < recty1 && y2 < recty2) || (y1 > recty2 && y2 > recty2)) {
   153         (y1 < recty1 && y2 < recty2) || (y1 > recty2 && y2 > recty2)) {
   154         return SDL_FALSE;
   154         return SDL_FALSE;
   155     }
   155     }
   156 
   156 
   157     if (y1 = y2) {
   157     if (y1 == y2) {
   158         /* Horizontal line, easy to clip */
   158         /* Horizontal line, easy to clip */
   159         if (x1 < rectx1) {
   159         if (x1 < rectx1) {
   160             *X1 = rectx1;
   160             *X1 = rectx1;
   161         } else if (x1 > rectx2) {
   161         } else if (x1 > rectx2) {
   162             *X1 = rectx2;
   162             *X1 = rectx2;
   182             *Y2 = recty2;
   182             *Y2 = recty2;
   183         }
   183         }
   184         return SDL_TRUE;
   184         return SDL_TRUE;
   185     }
   185     }
   186 
   186 
   187     /* FIXME: need code to clip diagonal line to rect */
   187     else
       
   188     {
       
   189     /* The task of clipping a line with finite slope ratios in a fixed-
       
   190      * precision coordinate space is not as immediately simple as it is
       
   191      * with coordinates of arbitrary precision. If the ratio of slopes
       
   192      * between the input line segment and the result line segment is not
       
   193      * a whole number, you have in fact *moved* the line segment a bit,
       
   194      * and there can be no avoiding it without more precision
       
   195      */
       
   196         int *x_result_[] = {X1, X2, NULL}, **x_result = x_result_;
       
   197         int *y_result_[] = {Y1, Y2, NULL}, **y_result = y_result_;
       
   198         SDL_bool intersection = SDL_FALSE;
       
   199         double b, m, left, right, bottom, top;
       
   200         int xl, xh, yl, yh;
       
   201 
       
   202         /* solve mx+b line formula */
       
   203         m = (double)(y1-y2) / (double)(x1-x2);
       
   204         b = y2 - m * (double) x2;
       
   205 
       
   206         /* find some linear intersections */
       
   207         left = (m * (double) rectx1) + b;
       
   208         right = (m * (double) rectx2) + b;
       
   209         top = (recty1 - b) / m;
       
   210         bottom = (recty2 - b) / m;
       
   211 
       
   212         /* sort end-points' x and y components individually */
       
   213         if (x1 < x2) {
       
   214             xl = x1;
       
   215             xh = x2;
       
   216         } else {
       
   217             xl = x2;
       
   218             xh = x1;
       
   219         }
       
   220         if (y1 < y2) {
       
   221             yl = y1;
       
   222             yh = y2;
       
   223         } else {
       
   224             yl = y2;
       
   225             yh = y1;
       
   226         }
       
   227 
       
   228 #define RISING(a, b, c) (((a)<=(b))&&((b)<=(c)))
       
   229 
       
   230         /* check for a point that's entirely inside the rect */
       
   231         if (RISING(rectx1, x1, rectx2) && RISING(recty1, y1, recty2)) {
       
   232             x_result++;
       
   233             y_result++;
       
   234             intersection = SDL_TRUE;
       
   235         } else /* it was determined earlier that *both* end-points are not contained */
       
   236 
       
   237         if (RISING(rectx1, x2, rectx2) && RISING(recty1, y2, recty2)) {
       
   238             **(x_result++) = x2;
       
   239             **(y_result++) = y2;
       
   240             intersection = SDL_TRUE;
       
   241         }
       
   242 
       
   243         if (RISING(recty1, left, recty2) && RISING(xl, rectx1, xh)) {
       
   244             **(x_result++) = rectx1;
       
   245             **(y_result++) = (int) left;
       
   246             intersection = SDL_TRUE;
       
   247         }
       
   248 
       
   249         if (*x_result == NULL) return intersection;
       
   250         if (RISING(recty1, right, recty2) && RISING(xl, rectx2, xh)) {
       
   251             **(x_result++) = rectx2;
       
   252             **(y_result++) = (int) right;
       
   253             intersection = SDL_TRUE;
       
   254         }
       
   255 
       
   256         if (*x_result == NULL) return intersection;
       
   257         if (RISING(rectx1, top, rectx2) && RISING(yl, recty1, yh)) {
       
   258             **(x_result++) = (int) top;
       
   259             **(y_result++) = recty1;
       
   260             intersection = SDL_TRUE;
       
   261         }
       
   262 
       
   263         if (*x_result == NULL) return intersection;
       
   264         if (RISING(rectx1, bottom, rectx2) && RISING(yl, recty2, yh)) {
       
   265             **(x_result++) = (int) bottom;
       
   266             **(y_result++) = recty2;
       
   267             intersection = SDL_TRUE;
       
   268         }
       
   269 
       
   270         return intersection;
       
   271     }
       
   272 
   188     return SDL_FALSE;
   273     return SDL_FALSE;
   189 }
   274 }
   190 
   275 
   191 void
   276 void
   192 SDL_AddDirtyRect(SDL_DirtyRectList * list, const SDL_Rect * rect)
   277 SDL_AddDirtyRect(SDL_DirtyRectList * list, const SDL_Rect * rect)