123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636 |
- /***********************************************************
- Copyright 1987, 1998 The Open Group
- Permission to use, copy, modify, distribute, and sell this software and its
- documentation for any purpose is hereby granted without fee, provided that
- the above copyright notice appear in all copies and that both that
- copyright notice and this permission notice appear in supporting
- documentation.
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- Except as contained in this notice, the name of The Open Group shall not be
- used in advertising or otherwise to promote the sale, use or other dealings
- in this Software without prior written authorization from The Open Group.
- Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
- All Rights Reserved
- Permission to use, copy, modify, and distribute this software and its
- documentation for any purpose and without fee is hereby granted,
- provided that the above copyright notice appear in all copies and that
- both that copyright notice and this permission notice appear in
- supporting documentation, and that the name of Digital not be
- used in advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
- DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
- ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
- DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
- ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- SOFTWARE.
- ******************************************************************/
- #ifdef HAVE_DIX_CONFIG_H
- #include <dix-config.h>
- #endif
- #include <X11/X.h>
- #include "misc.h"
- #include "scrnintstr.h"
- #include "gcstruct.h"
- #include "windowstr.h"
- #include "pixmap.h"
- #include "mi.h"
- #include "miline.h"
- /*
- The bresenham error equation used in the mi/mfb/cfb line routines is:
- e = error
- dx = difference in raw X coordinates
- dy = difference in raw Y coordinates
- M = # of steps in X direction
- N = # of steps in Y direction
- B = 0 to prefer diagonal steps in a given octant,
- 1 to prefer axial steps in a given octant
- For X major lines:
- e = 2Mdy - 2Ndx - dx - B
- -2dx <= e < 0
- For Y major lines:
- e = 2Ndx - 2Mdy - dy - B
- -2dy <= e < 0
- At the start of the line, we have taken 0 X steps and 0 Y steps,
- so M = 0 and N = 0:
- X major e = 2Mdy - 2Ndx - dx - B
- = -dx - B
- Y major e = 2Ndx - 2Mdy - dy - B
- = -dy - B
- At the end of the line, we have taken dx X steps and dy Y steps,
- so M = dx and N = dy:
- X major e = 2Mdy - 2Ndx - dx - B
- = 2dxdy - 2dydx - dx - B
- = -dx - B
- Y major e = 2Ndx - 2Mdy - dy - B
- = 2dydx - 2dxdy - dy - B
- = -dy - B
- Thus, the error term is the same at the start and end of the line.
- Let us consider clipping an X coordinate. There are 4 cases which
- represent the two independent cases of clipping the start vs. the
- end of the line and an X major vs. a Y major line. In any of these
- cases, we know the number of X steps (M) and we wish to find the
- number of Y steps (N). Thus, we will solve our error term equation.
- If we are clipping the start of the line, we will find the smallest
- N that satisfies our error term inequality. If we are clipping the
- end of the line, we will find the largest number of Y steps that
- satisfies the inequality. In that case, since we are representing
- the Y steps as (dy - N), we will actually want to solve for the
- smallest N in that equation.
- Case 1: X major, starting X coordinate moved by M steps
- -2dx <= 2Mdy - 2Ndx - dx - B < 0
- 2Ndx <= 2Mdy - dx - B + 2dx 2Ndx > 2Mdy - dx - B
- 2Ndx <= 2Mdy + dx - B N > (2Mdy - dx - B) / 2dx
- N <= (2Mdy + dx - B) / 2dx
- Since we are trying to find the smallest N that satisfies these
- equations, we should use the > inequality to find the smallest:
- N = floor((2Mdy - dx - B) / 2dx) + 1
- = floor((2Mdy - dx - B + 2dx) / 2dx)
- = floor((2Mdy + dx - B) / 2dx)
- Case 1b: X major, ending X coordinate moved to M steps
- Same derivations as Case 1, but we want the largest N that satisfies
- the equations, so we use the <= inequality:
- N = floor((2Mdy + dx - B) / 2dx)
- Case 2: X major, ending X coordinate moved by M steps
- -2dx <= 2(dx - M)dy - 2(dy - N)dx - dx - B < 0
- -2dx <= 2dxdy - 2Mdy - 2dxdy + 2Ndx - dx - B < 0
- -2dx <= 2Ndx - 2Mdy - dx - B < 0
- 2Ndx >= 2Mdy + dx + B - 2dx 2Ndx < 2Mdy + dx + B
- 2Ndx >= 2Mdy - dx + B N < (2Mdy + dx + B) / 2dx
- N >= (2Mdy - dx + B) / 2dx
- Since we are trying to find the highest number of Y steps that
- satisfies these equations, we need to find the smallest N, so
- we should use the >= inequality to find the smallest:
- N = ceiling((2Mdy - dx + B) / 2dx)
- = floor((2Mdy - dx + B + 2dx - 1) / 2dx)
- = floor((2Mdy + dx + B - 1) / 2dx)
- Case 2b: X major, starting X coordinate moved to M steps from end
- Same derivations as Case 2, but we want the smallest number of Y
- steps, so we want the highest N, so we use the < inequality:
- N = ceiling((2Mdy + dx + B) / 2dx) - 1
- = floor((2Mdy + dx + B + 2dx - 1) / 2dx) - 1
- = floor((2Mdy + dx + B + 2dx - 1 - 2dx) / 2dx)
- = floor((2Mdy + dx + B - 1) / 2dx)
- Case 3: Y major, starting X coordinate moved by M steps
- -2dy <= 2Ndx - 2Mdy - dy - B < 0
- 2Ndx >= 2Mdy + dy + B - 2dy 2Ndx < 2Mdy + dy + B
- 2Ndx >= 2Mdy - dy + B N < (2Mdy + dy + B) / 2dx
- N >= (2Mdy - dy + B) / 2dx
- Since we are trying to find the smallest N that satisfies these
- equations, we should use the >= inequality to find the smallest:
- N = ceiling((2Mdy - dy + B) / 2dx)
- = floor((2Mdy - dy + B + 2dx - 1) / 2dx)
- = floor((2Mdy - dy + B - 1) / 2dx) + 1
- Case 3b: Y major, ending X coordinate moved to M steps
- Same derivations as Case 3, but we want the largest N that satisfies
- the equations, so we use the < inequality:
- N = ceiling((2Mdy + dy + B) / 2dx) - 1
- = floor((2Mdy + dy + B + 2dx - 1) / 2dx) - 1
- = floor((2Mdy + dy + B + 2dx - 1 - 2dx) / 2dx)
- = floor((2Mdy + dy + B - 1) / 2dx)
- Case 4: Y major, ending X coordinate moved by M steps
- -2dy <= 2(dy - N)dx - 2(dx - M)dy - dy - B < 0
- -2dy <= 2dxdy - 2Ndx - 2dxdy + 2Mdy - dy - B < 0
- -2dy <= 2Mdy - 2Ndx - dy - B < 0
- 2Ndx <= 2Mdy - dy - B + 2dy 2Ndx > 2Mdy - dy - B
- 2Ndx <= 2Mdy + dy - B N > (2Mdy - dy - B) / 2dx
- N <= (2Mdy + dy - B) / 2dx
- Since we are trying to find the highest number of Y steps that
- satisfies these equations, we need to find the smallest N, so
- we should use the > inequality to find the smallest:
- N = floor((2Mdy - dy - B) / 2dx) + 1
- Case 4b: Y major, starting X coordinate moved to M steps from end
- Same analysis as Case 4, but we want the smallest number of Y steps
- which means the largest N, so we use the <= inequality:
- N = floor((2Mdy + dy - B) / 2dx)
- Now let's try the Y coordinates, we have the same 4 cases.
- Case 5: X major, starting Y coordinate moved by N steps
- -2dx <= 2Mdy - 2Ndx - dx - B < 0
- 2Mdy >= 2Ndx + dx + B - 2dx 2Mdy < 2Ndx + dx + B
- 2Mdy >= 2Ndx - dx + B M < (2Ndx + dx + B) / 2dy
- M >= (2Ndx - dx + B) / 2dy
- Since we are trying to find the smallest M, we use the >= inequality:
- M = ceiling((2Ndx - dx + B) / 2dy)
- = floor((2Ndx - dx + B + 2dy - 1) / 2dy)
- = floor((2Ndx - dx + B - 1) / 2dy) + 1
- Case 5b: X major, ending Y coordinate moved to N steps
- Same derivations as Case 5, but we want the largest M that satisfies
- the equations, so we use the < inequality:
- M = ceiling((2Ndx + dx + B) / 2dy) - 1
- = floor((2Ndx + dx + B + 2dy - 1) / 2dy) - 1
- = floor((2Ndx + dx + B + 2dy - 1 - 2dy) / 2dy)
- = floor((2Ndx + dx + B - 1) / 2dy)
- Case 6: X major, ending Y coordinate moved by N steps
- -2dx <= 2(dx - M)dy - 2(dy - N)dx - dx - B < 0
- -2dx <= 2dxdy - 2Mdy - 2dxdy + 2Ndx - dx - B < 0
- -2dx <= 2Ndx - 2Mdy - dx - B < 0
- 2Mdy <= 2Ndx - dx - B + 2dx 2Mdy > 2Ndx - dx - B
- 2Mdy <= 2Ndx + dx - B M > (2Ndx - dx - B) / 2dy
- M <= (2Ndx + dx - B) / 2dy
- Largest # of X steps means smallest M, so use the > inequality:
- M = floor((2Ndx - dx - B) / 2dy) + 1
- Case 6b: X major, starting Y coordinate moved to N steps from end
- Same derivations as Case 6, but we want the smallest # of X steps
- which means the largest M, so use the <= inequality:
- M = floor((2Ndx + dx - B) / 2dy)
- Case 7: Y major, starting Y coordinate moved by N steps
- -2dy <= 2Ndx - 2Mdy - dy - B < 0
- 2Mdy <= 2Ndx - dy - B + 2dy 2Mdy > 2Ndx - dy - B
- 2Mdy <= 2Ndx + dy - B M > (2Ndx - dy - B) / 2dy
- M <= (2Ndx + dy - B) / 2dy
- To find the smallest M, use the > inequality:
- M = floor((2Ndx - dy - B) / 2dy) + 1
- = floor((2Ndx - dy - B + 2dy) / 2dy)
- = floor((2Ndx + dy - B) / 2dy)
- Case 7b: Y major, ending Y coordinate moved to N steps
- Same derivations as Case 7, but we want the largest M that satisfies
- the equations, so use the <= inequality:
- M = floor((2Ndx + dy - B) / 2dy)
- Case 8: Y major, ending Y coordinate moved by N steps
- -2dy <= 2(dy - N)dx - 2(dx - M)dy - dy - B < 0
- -2dy <= 2dxdy - 2Ndx - 2dxdy + 2Mdy - dy - B < 0
- -2dy <= 2Mdy - 2Ndx - dy - B < 0
- 2Mdy >= 2Ndx + dy + B - 2dy 2Mdy < 2Ndx + dy + B
- 2Mdy >= 2Ndx - dy + B M < (2Ndx + dy + B) / 2dy
- M >= (2Ndx - dy + B) / 2dy
- To find the highest X steps, find the smallest M, use the >= inequality:
- M = ceiling((2Ndx - dy + B) / 2dy)
- = floor((2Ndx - dy + B + 2dy - 1) / 2dy)
- = floor((2Ndx + dy + B - 1) / 2dy)
- Case 8b: Y major, starting Y coordinate moved to N steps from the end
- Same derivations as Case 8, but we want to find the smallest # of X
- steps which means the largest M, so we use the < inequality:
- M = ceiling((2Ndx + dy + B) / 2dy) - 1
- = floor((2Ndx + dy + B + 2dy - 1) / 2dy) - 1
- = floor((2Ndx + dy + B + 2dy - 1 - 2dy) / 2dy)
- = floor((2Ndx + dy + B - 1) / 2dy)
- So, our equations are:
- 1: X major move x1 to x1+M floor((2Mdy + dx - B) / 2dx)
- 1b: X major move x2 to x1+M floor((2Mdy + dx - B) / 2dx)
- 2: X major move x2 to x2-M floor((2Mdy + dx + B - 1) / 2dx)
- 2b: X major move x1 to x2-M floor((2Mdy + dx + B - 1) / 2dx)
- 3: Y major move x1 to x1+M floor((2Mdy - dy + B - 1) / 2dx) + 1
- 3b: Y major move x2 to x1+M floor((2Mdy + dy + B - 1) / 2dx)
- 4: Y major move x2 to x2-M floor((2Mdy - dy - B) / 2dx) + 1
- 4b: Y major move x1 to x2-M floor((2Mdy + dy - B) / 2dx)
- 5: X major move y1 to y1+N floor((2Ndx - dx + B - 1) / 2dy) + 1
- 5b: X major move y2 to y1+N floor((2Ndx + dx + B - 1) / 2dy)
- 6: X major move y2 to y2-N floor((2Ndx - dx - B) / 2dy) + 1
- 6b: X major move y1 to y2-N floor((2Ndx + dx - B) / 2dy)
- 7: Y major move y1 to y1+N floor((2Ndx + dy - B) / 2dy)
- 7b: Y major move y2 to y1+N floor((2Ndx + dy - B) / 2dy)
- 8: Y major move y2 to y2-N floor((2Ndx + dy + B - 1) / 2dy)
- 8b: Y major move y1 to y2-N floor((2Ndx + dy + B - 1) / 2dy)
- We have the following constraints on all of the above terms:
- 0 < M,N <= 2^15 2^15 can be imposed by miZeroClipLine
- 0 <= dx/dy <= 2^16 - 1
- 0 <= B <= 1
- The floor in all of the above equations can be accomplished with a
- simple C divide operation provided that both numerator and denominator
- are positive.
- Since dx,dy >= 0 and since moving an X coordinate implies that dx != 0
- and moving a Y coordinate implies dy != 0, we know that the denominators
- are all > 0.
- For all lines, (-B) and (B-1) are both either 0 or -1, depending on the
- bias. Thus, we have to show that the 2MNdxy +/- dxy terms are all >= 1
- or > 0 to prove that the numerators are positive (or zero).
- For X Major lines we know that dx > 0 and since 2Mdy is >= 0 due to the
- constraints, the first four equations all have numerators >= 0.
- For the second four equations, M > 0, so 2Mdy >= 2dy so (2Mdy - dy) >= dy
- So (2Mdy - dy) > 0, since they are Y major lines. Also, (2Mdy + dy) >= 3dy
- or (2Mdy + dy) > 0. So all of their numerators are >= 0.
- For the third set of four equations, N > 0, so 2Ndx >= 2dx so (2Ndx - dx)
- >= dx > 0. Similarly (2Ndx + dx) >= 3dx > 0. So all numerators >= 0.
- For the fourth set of equations, dy > 0 and 2Ndx >= 0, so all numerators
- are > 0.
- To consider overflow, consider the case of 2 * M,N * dx,dy + dx,dy. This
- is bounded <= 2 * 2^15 * (2^16 - 1) + (2^16 - 1)
- <= 2^16 * (2^16 - 1) + (2^16 - 1)
- <= 2^32 - 2^16 + 2^16 - 1
- <= 2^32 - 1
- Since the (-B) and (B-1) terms are all 0 or -1, the maximum value of
- the numerator is therefore (2^32 - 1), which does not overflow an unsigned
- 32 bit variable.
- */
- /* Bit codes for the terms of the 16 clipping equations defined below. */
- #define T_2NDX (1 << 0)
- #define T_2MDY (0) /* implicit term */
- #define T_DXNOTY (1 << 1)
- #define T_DYNOTX (0) /* implicit term */
- #define T_SUBDXORY (1 << 2)
- #define T_ADDDX (T_DXNOTY) /* composite term */
- #define T_SUBDX (T_DXNOTY | T_SUBDXORY) /* composite term */
- #define T_ADDDY (T_DYNOTX) /* composite term */
- #define T_SUBDY (T_DYNOTX | T_SUBDXORY) /* composite term */
- #define T_BIASSUBONE (1 << 3)
- #define T_SUBBIAS (0) /* implicit term */
- #define T_DIV2DX (1 << 4)
- #define T_DIV2DY (0) /* implicit term */
- #define T_ADDONE (1 << 5)
- /* Bit masks defining the 16 equations used in miZeroClipLine. */
- #define EQN1 (T_2MDY | T_ADDDX | T_SUBBIAS | T_DIV2DX)
- #define EQN1B (T_2MDY | T_ADDDX | T_SUBBIAS | T_DIV2DX)
- #define EQN2 (T_2MDY | T_ADDDX | T_BIASSUBONE | T_DIV2DX)
- #define EQN2B (T_2MDY | T_ADDDX | T_BIASSUBONE | T_DIV2DX)
- #define EQN3 (T_2MDY | T_SUBDY | T_BIASSUBONE | T_DIV2DX | T_ADDONE)
- #define EQN3B (T_2MDY | T_ADDDY | T_BIASSUBONE | T_DIV2DX)
- #define EQN4 (T_2MDY | T_SUBDY | T_SUBBIAS | T_DIV2DX | T_ADDONE)
- #define EQN4B (T_2MDY | T_ADDDY | T_SUBBIAS | T_DIV2DX)
- #define EQN5 (T_2NDX | T_SUBDX | T_BIASSUBONE | T_DIV2DY | T_ADDONE)
- #define EQN5B (T_2NDX | T_ADDDX | T_BIASSUBONE | T_DIV2DY)
- #define EQN6 (T_2NDX | T_SUBDX | T_SUBBIAS | T_DIV2DY | T_ADDONE)
- #define EQN6B (T_2NDX | T_ADDDX | T_SUBBIAS | T_DIV2DY)
- #define EQN7 (T_2NDX | T_ADDDY | T_SUBBIAS | T_DIV2DY)
- #define EQN7B (T_2NDX | T_ADDDY | T_SUBBIAS | T_DIV2DY)
- #define EQN8 (T_2NDX | T_ADDDY | T_BIASSUBONE | T_DIV2DY)
- #define EQN8B (T_2NDX | T_ADDDY | T_BIASSUBONE | T_DIV2DY)
- /* miZeroClipLine
- *
- * returns: 1 for partially clipped line
- * -1 for completely clipped line
- *
- */
- _X_EXPORT int
- miZeroClipLine(xmin, ymin, xmax, ymax,
- new_x1, new_y1, new_x2, new_y2,
- adx, ady,
- pt1_clipped, pt2_clipped, octant, bias, oc1, oc2)
- int xmin, ymin, xmax, ymax;
- int *new_x1, *new_y1, *new_x2, *new_y2;
- int *pt1_clipped, *pt2_clipped;
- unsigned int adx, ady;
- int octant;
- unsigned int bias;
- int oc1, oc2;
- {
- int swapped = 0;
- int clipDone = 0;
- CARD32 utmp = 0;
- int clip1, clip2;
- int x1, y1, x2, y2;
- int x1_orig, y1_orig, x2_orig, y2_orig;
- int xmajor;
- int negslope = 0, anchorval = 0;
- unsigned int eqn = 0;
- x1 = x1_orig = *new_x1;
- y1 = y1_orig = *new_y1;
- x2 = x2_orig = *new_x2;
- y2 = y2_orig = *new_y2;
- clip1 = 0;
- clip2 = 0;
- xmajor = IsXMajorOctant(octant);
- bias = ((bias >> octant) & 1);
- while (1)
- {
- if ((oc1 & oc2) != 0) /* trivial reject */
- {
- clipDone = -1;
- clip1 = oc1;
- clip2 = oc2;
- break;
- }
- else if ((oc1 | oc2) == 0) /* trivial accept */
- {
- clipDone = 1;
- if (swapped)
- {
- SWAPINT_PAIR(x1, y1, x2, y2);
- SWAPINT(clip1, clip2);
- }
- break;
- }
- else /* have to clip */
- {
- /* only clip one point at a time */
- if (oc1 == 0)
- {
- SWAPINT_PAIR(x1, y1, x2, y2);
- SWAPINT_PAIR(x1_orig, y1_orig, x2_orig, y2_orig);
- SWAPINT(oc1, oc2);
- SWAPINT(clip1, clip2);
- swapped = !swapped;
- }
- clip1 |= oc1;
- if (oc1 & OUT_LEFT)
- {
- negslope = IsYDecreasingOctant(octant);
- utmp = xmin - x1_orig;
- if (utmp <= 32767) /* clip based on near endpt */
- {
- if (xmajor)
- eqn = (swapped) ? EQN2 : EQN1;
- else
- eqn = (swapped) ? EQN4 : EQN3;
- anchorval = y1_orig;
- }
- else /* clip based on far endpt */
- {
- utmp = x2_orig - xmin;
- if (xmajor)
- eqn = (swapped) ? EQN1B : EQN2B;
- else
- eqn = (swapped) ? EQN3B : EQN4B;
- anchorval = y2_orig;
- negslope = !negslope;
- }
- x1 = xmin;
- }
- else if (oc1 & OUT_ABOVE)
- {
- negslope = IsXDecreasingOctant(octant);
- utmp = ymin - y1_orig;
- if (utmp <= 32767) /* clip based on near endpt */
- {
- if (xmajor)
- eqn = (swapped) ? EQN6 : EQN5;
- else
- eqn = (swapped) ? EQN8 : EQN7;
- anchorval = x1_orig;
- }
- else /* clip based on far endpt */
- {
- utmp = y2_orig - ymin;
- if (xmajor)
- eqn = (swapped) ? EQN5B : EQN6B;
- else
- eqn = (swapped) ? EQN7B : EQN8B;
- anchorval = x2_orig;
- negslope = !negslope;
- }
- y1 = ymin;
- }
- else if (oc1 & OUT_RIGHT)
- {
- negslope = IsYDecreasingOctant(octant);
- utmp = x1_orig - xmax;
- if (utmp <= 32767) /* clip based on near endpt */
- {
- if (xmajor)
- eqn = (swapped) ? EQN2 : EQN1;
- else
- eqn = (swapped) ? EQN4 : EQN3;
- anchorval = y1_orig;
- }
- else /* clip based on far endpt */
- {
- /*
- * Technically since the equations can handle
- * utmp == 32768, this overflow code isn't
- * needed since X11 protocol can't generate
- * a line which goes more than 32768 pixels
- * to the right of a clip rectangle.
- */
- utmp = xmax - x2_orig;
- if (xmajor)
- eqn = (swapped) ? EQN1B : EQN2B;
- else
- eqn = (swapped) ? EQN3B : EQN4B;
- anchorval = y2_orig;
- negslope = !negslope;
- }
- x1 = xmax;
- }
- else if (oc1 & OUT_BELOW)
- {
- negslope = IsXDecreasingOctant(octant);
- utmp = y1_orig - ymax;
- if (utmp <= 32767) /* clip based on near endpt */
- {
- if (xmajor)
- eqn = (swapped) ? EQN6 : EQN5;
- else
- eqn = (swapped) ? EQN8 : EQN7;
- anchorval = x1_orig;
- }
- else /* clip based on far endpt */
- {
- /*
- * Technically since the equations can handle
- * utmp == 32768, this overflow code isn't
- * needed since X11 protocol can't generate
- * a line which goes more than 32768 pixels
- * below the bottom of a clip rectangle.
- */
- utmp = ymax - y2_orig;
- if (xmajor)
- eqn = (swapped) ? EQN5B : EQN6B;
- else
- eqn = (swapped) ? EQN7B : EQN8B;
- anchorval = x2_orig;
- negslope = !negslope;
- }
- y1 = ymax;
- }
- if (swapped)
- negslope = !negslope;
- utmp <<= 1; /* utmp = 2N or 2M */
- if (eqn & T_2NDX)
- utmp = (utmp * adx);
- else /* (eqn & T_2MDY) */
- utmp = (utmp * ady);
- if (eqn & T_DXNOTY)
- if (eqn & T_SUBDXORY)
- utmp -= adx;
- else
- utmp += adx;
- else /* (eqn & T_DYNOTX) */
- if (eqn & T_SUBDXORY)
- utmp -= ady;
- else
- utmp += ady;
- if (eqn & T_BIASSUBONE)
- utmp += bias - 1;
- else /* (eqn & T_SUBBIAS) */
- utmp -= bias;
- if (eqn & T_DIV2DX)
- utmp /= (adx << 1);
- else /* (eqn & T_DIV2DY) */
- utmp /= (ady << 1);
- if (eqn & T_ADDONE)
- utmp++;
- if (negslope)
- utmp = -utmp;
- if (eqn & T_2NDX) /* We are calculating X steps */
- x1 = anchorval + utmp;
- else /* else, Y steps */
- y1 = anchorval + utmp;
- oc1 = 0;
- MIOUTCODES(oc1, x1, y1, xmin, ymin, xmax, ymax);
- }
- }
- *new_x1 = x1;
- *new_y1 = y1;
- *new_x2 = x2;
- *new_y2 = y2;
- *pt1_clipped = clip1;
- *pt2_clipped = clip2;
- return clipDone;
- }
|