mizerclip.c revision 706f2543
1/*********************************************************** 2 3Copyright 1987, 1998 The Open Group 4 5Permission to use, copy, modify, distribute, and sell this software and its 6documentation for any purpose is hereby granted without fee, provided that 7the above copyright notice appear in all copies and that both that 8copyright notice and this permission notice appear in supporting 9documentation. 10 11The above copyright notice and this permission notice shall be included in 12all copies or substantial portions of the Software. 13 14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 21Except as contained in this notice, the name of The Open Group shall not be 22used in advertising or otherwise to promote the sale, use or other dealings 23in this Software without prior written authorization from The Open Group. 24 25 26Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. 27 28 All Rights Reserved 29 30Permission to use, copy, modify, and distribute this software and its 31documentation for any purpose and without fee is hereby granted, 32provided that the above copyright notice appear in all copies and that 33both that copyright notice and this permission notice appear in 34supporting documentation, and that the name of Digital not be 35used in advertising or publicity pertaining to distribution of the 36software without specific, written prior permission. 37 38DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 39ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 40DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 41ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 42WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 43ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 44SOFTWARE. 45 46******************************************************************/ 47#ifdef HAVE_DIX_CONFIG_H 48#include <dix-config.h> 49#endif 50 51#include <X11/X.h> 52 53#include "misc.h" 54#include "scrnintstr.h" 55#include "gcstruct.h" 56#include "windowstr.h" 57#include "pixmap.h" 58#include "mi.h" 59#include "miline.h" 60 61/* 62 63The bresenham error equation used in the mi/mfb/cfb line routines is: 64 65 e = error 66 dx = difference in raw X coordinates 67 dy = difference in raw Y coordinates 68 M = # of steps in X direction 69 N = # of steps in Y direction 70 B = 0 to prefer diagonal steps in a given octant, 71 1 to prefer axial steps in a given octant 72 73 For X major lines: 74 e = 2Mdy - 2Ndx - dx - B 75 -2dx <= e < 0 76 77 For Y major lines: 78 e = 2Ndx - 2Mdy - dy - B 79 -2dy <= e < 0 80 81At the start of the line, we have taken 0 X steps and 0 Y steps, 82so M = 0 and N = 0: 83 84 X major e = 2Mdy - 2Ndx - dx - B 85 = -dx - B 86 87 Y major e = 2Ndx - 2Mdy - dy - B 88 = -dy - B 89 90At the end of the line, we have taken dx X steps and dy Y steps, 91so M = dx and N = dy: 92 93 X major e = 2Mdy - 2Ndx - dx - B 94 = 2dxdy - 2dydx - dx - B 95 = -dx - B 96 Y major e = 2Ndx - 2Mdy - dy - B 97 = 2dydx - 2dxdy - dy - B 98 = -dy - B 99 100Thus, the error term is the same at the start and end of the line. 101 102Let us consider clipping an X coordinate. There are 4 cases which 103represent the two independent cases of clipping the start vs. the 104end of the line and an X major vs. a Y major line. In any of these 105cases, we know the number of X steps (M) and we wish to find the 106number of Y steps (N). Thus, we will solve our error term equation. 107If we are clipping the start of the line, we will find the smallest 108N that satisfies our error term inequality. If we are clipping the 109end of the line, we will find the largest number of Y steps that 110satisfies the inequality. In that case, since we are representing 111the Y steps as (dy - N), we will actually want to solve for the 112smallest N in that equation. 113 114Case 1: X major, starting X coordinate moved by M steps 115 116 -2dx <= 2Mdy - 2Ndx - dx - B < 0 117 2Ndx <= 2Mdy - dx - B + 2dx 2Ndx > 2Mdy - dx - B 118 2Ndx <= 2Mdy + dx - B N > (2Mdy - dx - B) / 2dx 119 N <= (2Mdy + dx - B) / 2dx 120 121Since we are trying to find the smallest N that satisfies these 122equations, we should use the > inequality to find the smallest: 123 124 N = floor((2Mdy - dx - B) / 2dx) + 1 125 = floor((2Mdy - dx - B + 2dx) / 2dx) 126 = floor((2Mdy + dx - B) / 2dx) 127 128Case 1b: X major, ending X coordinate moved to M steps 129 130Same derivations as Case 1, but we want the largest N that satisfies 131the equations, so we use the <= inequality: 132 133 N = floor((2Mdy + dx - B) / 2dx) 134 135Case 2: X major, ending X coordinate moved by M steps 136 137 -2dx <= 2(dx - M)dy - 2(dy - N)dx - dx - B < 0 138 -2dx <= 2dxdy - 2Mdy - 2dxdy + 2Ndx - dx - B < 0 139 -2dx <= 2Ndx - 2Mdy - dx - B < 0 140 2Ndx >= 2Mdy + dx + B - 2dx 2Ndx < 2Mdy + dx + B 141 2Ndx >= 2Mdy - dx + B N < (2Mdy + dx + B) / 2dx 142 N >= (2Mdy - dx + B) / 2dx 143 144Since we are trying to find the highest number of Y steps that 145satisfies these equations, we need to find the smallest N, so 146we should use the >= inequality to find the smallest: 147 148 N = ceiling((2Mdy - dx + B) / 2dx) 149 = floor((2Mdy - dx + B + 2dx - 1) / 2dx) 150 = floor((2Mdy + dx + B - 1) / 2dx) 151 152Case 2b: X major, starting X coordinate moved to M steps from end 153 154Same derivations as Case 2, but we want the smallest number of Y 155steps, so we want the highest N, so we use the < inequality: 156 157 N = ceiling((2Mdy + dx + B) / 2dx) - 1 158 = floor((2Mdy + dx + B + 2dx - 1) / 2dx) - 1 159 = floor((2Mdy + dx + B + 2dx - 1 - 2dx) / 2dx) 160 = floor((2Mdy + dx + B - 1) / 2dx) 161 162Case 3: Y major, starting X coordinate moved by M steps 163 164 -2dy <= 2Ndx - 2Mdy - dy - B < 0 165 2Ndx >= 2Mdy + dy + B - 2dy 2Ndx < 2Mdy + dy + B 166 2Ndx >= 2Mdy - dy + B N < (2Mdy + dy + B) / 2dx 167 N >= (2Mdy - dy + B) / 2dx 168 169Since we are trying to find the smallest N that satisfies these 170equations, we should use the >= inequality to find the smallest: 171 172 N = ceiling((2Mdy - dy + B) / 2dx) 173 = floor((2Mdy - dy + B + 2dx - 1) / 2dx) 174 = floor((2Mdy - dy + B - 1) / 2dx) + 1 175 176Case 3b: Y major, ending X coordinate moved to M steps 177 178Same derivations as Case 3, but we want the largest N that satisfies 179the equations, so we use the < inequality: 180 181 N = ceiling((2Mdy + dy + B) / 2dx) - 1 182 = floor((2Mdy + dy + B + 2dx - 1) / 2dx) - 1 183 = floor((2Mdy + dy + B + 2dx - 1 - 2dx) / 2dx) 184 = floor((2Mdy + dy + B - 1) / 2dx) 185 186Case 4: Y major, ending X coordinate moved by M steps 187 188 -2dy <= 2(dy - N)dx - 2(dx - M)dy - dy - B < 0 189 -2dy <= 2dxdy - 2Ndx - 2dxdy + 2Mdy - dy - B < 0 190 -2dy <= 2Mdy - 2Ndx - dy - B < 0 191 2Ndx <= 2Mdy - dy - B + 2dy 2Ndx > 2Mdy - dy - B 192 2Ndx <= 2Mdy + dy - B N > (2Mdy - dy - B) / 2dx 193 N <= (2Mdy + dy - B) / 2dx 194 195Since we are trying to find the highest number of Y steps that 196satisfies these equations, we need to find the smallest N, so 197we should use the > inequality to find the smallest: 198 199 N = floor((2Mdy - dy - B) / 2dx) + 1 200 201Case 4b: Y major, starting X coordinate moved to M steps from end 202 203Same analysis as Case 4, but we want the smallest number of Y steps 204which means the largest N, so we use the <= inequality: 205 206 N = floor((2Mdy + dy - B) / 2dx) 207 208Now let's try the Y coordinates, we have the same 4 cases. 209 210Case 5: X major, starting Y coordinate moved by N steps 211 212 -2dx <= 2Mdy - 2Ndx - dx - B < 0 213 2Mdy >= 2Ndx + dx + B - 2dx 2Mdy < 2Ndx + dx + B 214 2Mdy >= 2Ndx - dx + B M < (2Ndx + dx + B) / 2dy 215 M >= (2Ndx - dx + B) / 2dy 216 217Since we are trying to find the smallest M, we use the >= inequality: 218 219 M = ceiling((2Ndx - dx + B) / 2dy) 220 = floor((2Ndx - dx + B + 2dy - 1) / 2dy) 221 = floor((2Ndx - dx + B - 1) / 2dy) + 1 222 223Case 5b: X major, ending Y coordinate moved to N steps 224 225Same derivations as Case 5, but we want the largest M that satisfies 226the equations, so we use the < inequality: 227 228 M = ceiling((2Ndx + dx + B) / 2dy) - 1 229 = floor((2Ndx + dx + B + 2dy - 1) / 2dy) - 1 230 = floor((2Ndx + dx + B + 2dy - 1 - 2dy) / 2dy) 231 = floor((2Ndx + dx + B - 1) / 2dy) 232 233Case 6: X major, ending Y coordinate moved by N steps 234 235 -2dx <= 2(dx - M)dy - 2(dy - N)dx - dx - B < 0 236 -2dx <= 2dxdy - 2Mdy - 2dxdy + 2Ndx - dx - B < 0 237 -2dx <= 2Ndx - 2Mdy - dx - B < 0 238 2Mdy <= 2Ndx - dx - B + 2dx 2Mdy > 2Ndx - dx - B 239 2Mdy <= 2Ndx + dx - B M > (2Ndx - dx - B) / 2dy 240 M <= (2Ndx + dx - B) / 2dy 241 242Largest # of X steps means smallest M, so use the > inequality: 243 244 M = floor((2Ndx - dx - B) / 2dy) + 1 245 246Case 6b: X major, starting Y coordinate moved to N steps from end 247 248Same derivations as Case 6, but we want the smallest # of X steps 249which means the largest M, so use the <= inequality: 250 251 M = floor((2Ndx + dx - B) / 2dy) 252 253Case 7: Y major, starting Y coordinate moved by N steps 254 255 -2dy <= 2Ndx - 2Mdy - dy - B < 0 256 2Mdy <= 2Ndx - dy - B + 2dy 2Mdy > 2Ndx - dy - B 257 2Mdy <= 2Ndx + dy - B M > (2Ndx - dy - B) / 2dy 258 M <= (2Ndx + dy - B) / 2dy 259 260To find the smallest M, use the > inequality: 261 262 M = floor((2Ndx - dy - B) / 2dy) + 1 263 = floor((2Ndx - dy - B + 2dy) / 2dy) 264 = floor((2Ndx + dy - B) / 2dy) 265 266Case 7b: Y major, ending Y coordinate moved to N steps 267 268Same derivations as Case 7, but we want the largest M that satisfies 269the equations, so use the <= inequality: 270 271 M = floor((2Ndx + dy - B) / 2dy) 272 273Case 8: Y major, ending Y coordinate moved by N steps 274 275 -2dy <= 2(dy - N)dx - 2(dx - M)dy - dy - B < 0 276 -2dy <= 2dxdy - 2Ndx - 2dxdy + 2Mdy - dy - B < 0 277 -2dy <= 2Mdy - 2Ndx - dy - B < 0 278 2Mdy >= 2Ndx + dy + B - 2dy 2Mdy < 2Ndx + dy + B 279 2Mdy >= 2Ndx - dy + B M < (2Ndx + dy + B) / 2dy 280 M >= (2Ndx - dy + B) / 2dy 281 282To find the highest X steps, find the smallest M, use the >= inequality: 283 284 M = ceiling((2Ndx - dy + B) / 2dy) 285 = floor((2Ndx - dy + B + 2dy - 1) / 2dy) 286 = floor((2Ndx + dy + B - 1) / 2dy) 287 288Case 8b: Y major, starting Y coordinate moved to N steps from the end 289 290Same derivations as Case 8, but we want to find the smallest # of X 291steps which means the largest M, so we use the < inequality: 292 293 M = ceiling((2Ndx + dy + B) / 2dy) - 1 294 = floor((2Ndx + dy + B + 2dy - 1) / 2dy) - 1 295 = floor((2Ndx + dy + B + 2dy - 1 - 2dy) / 2dy) 296 = floor((2Ndx + dy + B - 1) / 2dy) 297 298So, our equations are: 299 300 1: X major move x1 to x1+M floor((2Mdy + dx - B) / 2dx) 301 1b: X major move x2 to x1+M floor((2Mdy + dx - B) / 2dx) 302 2: X major move x2 to x2-M floor((2Mdy + dx + B - 1) / 2dx) 303 2b: X major move x1 to x2-M floor((2Mdy + dx + B - 1) / 2dx) 304 305 3: Y major move x1 to x1+M floor((2Mdy - dy + B - 1) / 2dx) + 1 306 3b: Y major move x2 to x1+M floor((2Mdy + dy + B - 1) / 2dx) 307 4: Y major move x2 to x2-M floor((2Mdy - dy - B) / 2dx) + 1 308 4b: Y major move x1 to x2-M floor((2Mdy + dy - B) / 2dx) 309 310 5: X major move y1 to y1+N floor((2Ndx - dx + B - 1) / 2dy) + 1 311 5b: X major move y2 to y1+N floor((2Ndx + dx + B - 1) / 2dy) 312 6: X major move y2 to y2-N floor((2Ndx - dx - B) / 2dy) + 1 313 6b: X major move y1 to y2-N floor((2Ndx + dx - B) / 2dy) 314 315 7: Y major move y1 to y1+N floor((2Ndx + dy - B) / 2dy) 316 7b: Y major move y2 to y1+N floor((2Ndx + dy - B) / 2dy) 317 8: Y major move y2 to y2-N floor((2Ndx + dy + B - 1) / 2dy) 318 8b: Y major move y1 to y2-N floor((2Ndx + dy + B - 1) / 2dy) 319 320We have the following constraints on all of the above terms: 321 322 0 < M,N <= 2^15 2^15 can be imposed by miZeroClipLine 323 0 <= dx/dy <= 2^16 - 1 324 0 <= B <= 1 325 326The floor in all of the above equations can be accomplished with a 327simple C divide operation provided that both numerator and denominator 328are positive. 329 330Since dx,dy >= 0 and since moving an X coordinate implies that dx != 0 331and moving a Y coordinate implies dy != 0, we know that the denominators 332are all > 0. 333 334For all lines, (-B) and (B-1) are both either 0 or -1, depending on the 335bias. Thus, we have to show that the 2MNdxy +/- dxy terms are all >= 1 336or > 0 to prove that the numerators are positive (or zero). 337 338For X Major lines we know that dx > 0 and since 2Mdy is >= 0 due to the 339constraints, the first four equations all have numerators >= 0. 340 341For the second four equations, M > 0, so 2Mdy >= 2dy so (2Mdy - dy) >= dy 342So (2Mdy - dy) > 0, since they are Y major lines. Also, (2Mdy + dy) >= 3dy 343or (2Mdy + dy) > 0. So all of their numerators are >= 0. 344 345For the third set of four equations, N > 0, so 2Ndx >= 2dx so (2Ndx - dx) 346>= dx > 0. Similarly (2Ndx + dx) >= 3dx > 0. So all numerators >= 0. 347 348For the fourth set of equations, dy > 0 and 2Ndx >= 0, so all numerators 349are > 0. 350 351To consider overflow, consider the case of 2 * M,N * dx,dy + dx,dy. This 352is bounded <= 2 * 2^15 * (2^16 - 1) + (2^16 - 1) 353 <= 2^16 * (2^16 - 1) + (2^16 - 1) 354 <= 2^32 - 2^16 + 2^16 - 1 355 <= 2^32 - 1 356Since the (-B) and (B-1) terms are all 0 or -1, the maximum value of 357the numerator is therefore (2^32 - 1), which does not overflow an unsigned 35832 bit variable. 359 360*/ 361 362/* Bit codes for the terms of the 16 clipping equations defined below. */ 363 364#define T_2NDX (1 << 0) 365#define T_2MDY (0) /* implicit term */ 366#define T_DXNOTY (1 << 1) 367#define T_DYNOTX (0) /* implicit term */ 368#define T_SUBDXORY (1 << 2) 369#define T_ADDDX (T_DXNOTY) /* composite term */ 370#define T_SUBDX (T_DXNOTY | T_SUBDXORY) /* composite term */ 371#define T_ADDDY (T_DYNOTX) /* composite term */ 372#define T_SUBDY (T_DYNOTX | T_SUBDXORY) /* composite term */ 373#define T_BIASSUBONE (1 << 3) 374#define T_SUBBIAS (0) /* implicit term */ 375#define T_DIV2DX (1 << 4) 376#define T_DIV2DY (0) /* implicit term */ 377#define T_ADDONE (1 << 5) 378 379/* Bit masks defining the 16 equations used in miZeroClipLine. */ 380 381#define EQN1 (T_2MDY | T_ADDDX | T_SUBBIAS | T_DIV2DX) 382#define EQN1B (T_2MDY | T_ADDDX | T_SUBBIAS | T_DIV2DX) 383#define EQN2 (T_2MDY | T_ADDDX | T_BIASSUBONE | T_DIV2DX) 384#define EQN2B (T_2MDY | T_ADDDX | T_BIASSUBONE | T_DIV2DX) 385 386#define EQN3 (T_2MDY | T_SUBDY | T_BIASSUBONE | T_DIV2DX | T_ADDONE) 387#define EQN3B (T_2MDY | T_ADDDY | T_BIASSUBONE | T_DIV2DX) 388#define EQN4 (T_2MDY | T_SUBDY | T_SUBBIAS | T_DIV2DX | T_ADDONE) 389#define EQN4B (T_2MDY | T_ADDDY | T_SUBBIAS | T_DIV2DX) 390 391#define EQN5 (T_2NDX | T_SUBDX | T_BIASSUBONE | T_DIV2DY | T_ADDONE) 392#define EQN5B (T_2NDX | T_ADDDX | T_BIASSUBONE | T_DIV2DY) 393#define EQN6 (T_2NDX | T_SUBDX | T_SUBBIAS | T_DIV2DY | T_ADDONE) 394#define EQN6B (T_2NDX | T_ADDDX | T_SUBBIAS | T_DIV2DY) 395 396#define EQN7 (T_2NDX | T_ADDDY | T_SUBBIAS | T_DIV2DY) 397#define EQN7B (T_2NDX | T_ADDDY | T_SUBBIAS | T_DIV2DY) 398#define EQN8 (T_2NDX | T_ADDDY | T_BIASSUBONE | T_DIV2DY) 399#define EQN8B (T_2NDX | T_ADDDY | T_BIASSUBONE | T_DIV2DY) 400 401/* miZeroClipLine 402 * 403 * returns: 1 for partially clipped line 404 * -1 for completely clipped line 405 * 406 */ 407int 408miZeroClipLine(int xmin, int ymin, int xmax, int ymax, 409 int *new_x1, int *new_y1, int *new_x2, int *new_y2, 410 unsigned int adx, unsigned int ady, 411 int *pt1_clipped, int *pt2_clipped, 412 int octant, unsigned int bias, 413 int oc1, int oc2) 414{ 415 int swapped = 0; 416 int clipDone = 0; 417 CARD32 utmp = 0; 418 int clip1, clip2; 419 int x1, y1, x2, y2; 420 int x1_orig, y1_orig, x2_orig, y2_orig; 421 int xmajor; 422 int negslope = 0, anchorval = 0; 423 unsigned int eqn = 0; 424 425 x1 = x1_orig = *new_x1; 426 y1 = y1_orig = *new_y1; 427 x2 = x2_orig = *new_x2; 428 y2 = y2_orig = *new_y2; 429 430 clip1 = 0; 431 clip2 = 0; 432 433 xmajor = IsXMajorOctant(octant); 434 bias = ((bias >> octant) & 1); 435 436 while (1) 437 { 438 if ((oc1 & oc2) != 0) /* trivial reject */ 439 { 440 clipDone = -1; 441 clip1 = oc1; 442 clip2 = oc2; 443 break; 444 } 445 else if ((oc1 | oc2) == 0) /* trivial accept */ 446 { 447 clipDone = 1; 448 if (swapped) 449 { 450 SWAPINT_PAIR(x1, y1, x2, y2); 451 SWAPINT(clip1, clip2); 452 } 453 break; 454 } 455 else /* have to clip */ 456 { 457 /* only clip one point at a time */ 458 if (oc1 == 0) 459 { 460 SWAPINT_PAIR(x1, y1, x2, y2); 461 SWAPINT_PAIR(x1_orig, y1_orig, x2_orig, y2_orig); 462 SWAPINT(oc1, oc2); 463 SWAPINT(clip1, clip2); 464 swapped = !swapped; 465 } 466 467 clip1 |= oc1; 468 if (oc1 & OUT_LEFT) 469 { 470 negslope = IsYDecreasingOctant(octant); 471 utmp = xmin - x1_orig; 472 if (utmp <= 32767) /* clip based on near endpt */ 473 { 474 if (xmajor) 475 eqn = (swapped) ? EQN2 : EQN1; 476 else 477 eqn = (swapped) ? EQN4 : EQN3; 478 anchorval = y1_orig; 479 } 480 else /* clip based on far endpt */ 481 { 482 utmp = x2_orig - xmin; 483 if (xmajor) 484 eqn = (swapped) ? EQN1B : EQN2B; 485 else 486 eqn = (swapped) ? EQN3B : EQN4B; 487 anchorval = y2_orig; 488 negslope = !negslope; 489 } 490 x1 = xmin; 491 } 492 else if (oc1 & OUT_ABOVE) 493 { 494 negslope = IsXDecreasingOctant(octant); 495 utmp = ymin - y1_orig; 496 if (utmp <= 32767) /* clip based on near endpt */ 497 { 498 if (xmajor) 499 eqn = (swapped) ? EQN6 : EQN5; 500 else 501 eqn = (swapped) ? EQN8 : EQN7; 502 anchorval = x1_orig; 503 } 504 else /* clip based on far endpt */ 505 { 506 utmp = y2_orig - ymin; 507 if (xmajor) 508 eqn = (swapped) ? EQN5B : EQN6B; 509 else 510 eqn = (swapped) ? EQN7B : EQN8B; 511 anchorval = x2_orig; 512 negslope = !negslope; 513 } 514 y1 = ymin; 515 } 516 else if (oc1 & OUT_RIGHT) 517 { 518 negslope = IsYDecreasingOctant(octant); 519 utmp = x1_orig - xmax; 520 if (utmp <= 32767) /* clip based on near endpt */ 521 { 522 if (xmajor) 523 eqn = (swapped) ? EQN2 : EQN1; 524 else 525 eqn = (swapped) ? EQN4 : EQN3; 526 anchorval = y1_orig; 527 } 528 else /* clip based on far endpt */ 529 { 530 /* 531 * Technically since the equations can handle 532 * utmp == 32768, this overflow code isn't 533 * needed since X11 protocol can't generate 534 * a line which goes more than 32768 pixels 535 * to the right of a clip rectangle. 536 */ 537 utmp = xmax - x2_orig; 538 if (xmajor) 539 eqn = (swapped) ? EQN1B : EQN2B; 540 else 541 eqn = (swapped) ? EQN3B : EQN4B; 542 anchorval = y2_orig; 543 negslope = !negslope; 544 } 545 x1 = xmax; 546 } 547 else if (oc1 & OUT_BELOW) 548 { 549 negslope = IsXDecreasingOctant(octant); 550 utmp = y1_orig - ymax; 551 if (utmp <= 32767) /* clip based on near endpt */ 552 { 553 if (xmajor) 554 eqn = (swapped) ? EQN6 : EQN5; 555 else 556 eqn = (swapped) ? EQN8 : EQN7; 557 anchorval = x1_orig; 558 } 559 else /* clip based on far endpt */ 560 { 561 /* 562 * Technically since the equations can handle 563 * utmp == 32768, this overflow code isn't 564 * needed since X11 protocol can't generate 565 * a line which goes more than 32768 pixels 566 * below the bottom of a clip rectangle. 567 */ 568 utmp = ymax - y2_orig; 569 if (xmajor) 570 eqn = (swapped) ? EQN5B : EQN6B; 571 else 572 eqn = (swapped) ? EQN7B : EQN8B; 573 anchorval = x2_orig; 574 negslope = !negslope; 575 } 576 y1 = ymax; 577 } 578 579 if (swapped) 580 negslope = !negslope; 581 582 utmp <<= 1; /* utmp = 2N or 2M */ 583 if (eqn & T_2NDX) 584 utmp = (utmp * adx); 585 else /* (eqn & T_2MDY) */ 586 utmp = (utmp * ady); 587 if (eqn & T_DXNOTY) 588 if (eqn & T_SUBDXORY) 589 utmp -= adx; 590 else 591 utmp += adx; 592 else /* (eqn & T_DYNOTX) */ 593 if (eqn & T_SUBDXORY) 594 utmp -= ady; 595 else 596 utmp += ady; 597 if (eqn & T_BIASSUBONE) 598 utmp += bias - 1; 599 else /* (eqn & T_SUBBIAS) */ 600 utmp -= bias; 601 if (eqn & T_DIV2DX) 602 utmp /= (adx << 1); 603 else /* (eqn & T_DIV2DY) */ 604 utmp /= (ady << 1); 605 if (eqn & T_ADDONE) 606 utmp++; 607 608 if (negslope) 609 utmp = -utmp; 610 611 if (eqn & T_2NDX) /* We are calculating X steps */ 612 x1 = anchorval + utmp; 613 else /* else, Y steps */ 614 y1 = anchorval + utmp; 615 616 oc1 = 0; 617 MIOUTCODES(oc1, x1, y1, xmin, ymin, xmax, ymax); 618 } 619 } 620 621 *new_x1 = x1; 622 *new_y1 = y1; 623 *new_x2 = x2; 624 *new_y2 = y2; 625 626 *pt1_clipped = clip1; 627 *pt2_clipped = clip2; 628 629 return clipDone; 630} 631