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