4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 1989 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
31 * University Copyright- Copyright (c) 1982, 1986, 1988
32 * The Regents of the University of California
35 * University Acknowledgment- Portions of this document are derived from
36 * software developed by the University of California, Berkeley, and its
40 #pragma ident "%Z%%M% %I% %E% SMI"
44 #define PI 3.141592654
45 #define hmot(n) hpos += n
46 #define hgoto(n) hpos = n
47 #define vmot(n) vgoto(vpos + n)
53 extern int DX
; /* step size in x */
54 extern int DY
; /* step size in y */
55 extern int drawdot
; /* character to use when drawing */
56 extern int drawsize
; /* shrink point size by this facter */
58 int maxdots
= 32000; /* maximum number of dots in an object */
60 #define sgn(n) ((n > 0) ? 1 : ((n < 0) ? -1 : 0))
61 #define abs(n) ((n) >= 0 ? (n) : -(n))
62 #define max(x,y) ((x) > (y) ? (x) : (y))
63 #define min(x,y) ((x) < (y) ? (x) : (y))
64 #define arcmove(x,y) { hgoto(x); vmot(-vpos-(y)); }
67 drawline(dx
, dy
, s
) /* draw line from here to dx, dy using s */
75 int motincr
, perpincr
;
76 int ohpos
, ovpos
, osize
, ofont
;
79 int itemp
; /*temp. storage for value returned byint function sgn*/
81 setsize(t_size(pstab
[osize
-1] / drawsize
));
88 numdots
= min(numdots
, maxdots
);
89 motincr
= DX
* sgn (yd
);
90 for (i
= 0; i
< numdots
; i
++) {
100 motincr
= DX
* sgn (xd
);
101 for (i
= 0; i
< numdots
; i
++) {
109 if (abs (xd
) > abs (yd
)) {
110 val
= slope
= (float) xd
/yd
;
112 numdots
= min(numdots
, maxdots
);
115 motincr
= DX
* sgn (xd
);
116 perpincr
= DX
* sgn (yd
);
119 val
= slope
= (float) yd
/xd
;
121 numdots
= min(numdots
, maxdots
);
124 motincr
= DX
* sgn (yd
);
125 perpincr
= DX
* sgn (xd
);
127 incrway
= itemp
= sgn ((int) slope
);
128 for (i
= 0; i
< numdots
; i
++) {
134 if (val
* slope
< 0) {
151 drawwig(s
) /* draw wiggly line */
154 int x
[50], y
[50], xp
, yp
, pxp
, pyp
;
156 int i
, j
, numdots
, N
;
158 char temp
[50], *p
, *getstr();
161 setsize(t_size(pstab
[osize
-1] / drawsize
));
163 for (N
= 2; (p
=getstr(p
,temp
)) != NULL
&& N
< sizeof(x
)/sizeof(x
[0]); N
++) {
170 for (i
= 1; i
< N
; i
++) {
177 for (i
= 0; i
< N
-1; i
++) { /* interval */
178 numdots
= (dist(x
[i
],y
[i
], x
[i
+1],y
[i
+1]) + dist(x
[i
+1],y
[i
+1], x
[i
+2],y
[i
+2])) / 2;
180 numdots
= min(numdots
, maxdots
);
181 for (j
= 0; j
< numdots
; j
++) { /* points within */
182 w
= (float) j
/ numdots
;
188 xp
= t1
* x
[i
+2] + t2
* x
[i
+1] + t3
* x
[i
] + 0.5;
189 yp
= t1
* y
[i
+2] + t2
* y
[i
+1] + t3
* y
[i
] + 0.5;
190 if (xp
!= pxp
|| yp
!= pyp
) {
204 char *getstr(p
, temp
) /* copy next non-blank string from p to temp, update p */
207 while (*p
== ' ' || *p
== '\t' || *p
== '\n')
213 while (*p
!= ' ' && *p
!= '\t' && *p
!= '\n' && *p
!= '\0')
226 conicarc(hpos
+ d
/2, -vpos
, hpos
, -vpos
, hpos
, -vpos
, d
/2, d
/2);
227 hgoto(xc
+ d
); /* circle goes to right side */
234 dist(x1
, y1
, x2
, y2
) /* integer distance from x1,y1 to x2,y2 */
240 return sqrt(dx
*dx
+ dy
*dy
) + 0.5;
244 drawarc(dx1
, dy1
, dx2
, dy2
)
246 int x0
, y0
, x2
, y2
, r
;
248 x0
= hpos
+ dx1
; /* center */
250 x2
= x0
+ dx2
; /* "to" */
252 r
= sqrt((float) dx1
* dx1
+ (float) dy1
* dy1
) + 0.5;
253 conicarc(x0
, -y0
, hpos
, -vpos
, x2
, -y2
, r
, r
);
265 conicarc(hpos
+ a
/2, -vpos
, hpos
, -vpos
, hpos
, -vpos
, a
/2, b
/2);
272 #define sqr(x) (long int)(x)*(x)
275 conicarc(x
, y
, x0
, y0
, x1
, y1
, a
, b
)
277 /* based on Bresenham, CACM, Feb 77, pp 102-3 */
278 /* by Chris Van Wyk */
279 /* capitalized vars are an internal reference frame */
282 int xs
, ys
, xt
, yt
, Xs
, Ys
, qs
, Xt
, Yt
, qt
,
283 M1x
, M1y
, M2x
, M2y
, M3x
, M3y
,
292 setsize(t_size(pstab
[osize
-1] / drawsize
));
295 if (a
!= b
) /* an arc of an ellipse; internally, will still think of circle */
297 xstep
= (float)a
/ b
;
302 ystep
= (float)b
/ a
;
305 else { /* a circular arc; radius is computed from center and first point */
307 radius
= sqrt((float)(sqr(x0
- x
) + sqr(y0
- y
)));
313 /* now, use start and end point locations to figure out
314 the angle at which start and end happen; use these
315 angles with known radius to figure out where start
318 slope
= atan2((double)(y0
- y
), (double)(x0
- x
) );
319 if (slope
== 0.0 && x0
< x
)
321 x0
= x
+ radius
* cos(slope
) + 0.5;
322 y0
= y
+ radius
* sin(slope
) + 0.5;
323 slope
= atan2((double)(y1
- y
), (double)(x1
- x
));
324 if (slope
== 0.0 && x1
< x
)
326 x1
= x
+ radius
* cos(slope
) + 0.5;
327 y1
= y
+ radius
* sin(slope
) + 0.5;
328 /* step 2: translate to zero-centered circle */
333 /* step 3: normalize to first quadrant */
402 /* step 4: calculate number of quadrant crossings */
410 Q
= (4 + qt
- qs
) % 4 - 1;
411 /* step 5: calculate initial decision difference */
416 /* here begins the work of drawing
417 we hope it ends here too */
425 if (dotcount
++ % DX
== 0)
426 putdot((int)xc
, (int)yc
);
430 Ys
= Yc
= sqrt((float)(sqr(xs
) + sqr(ys
)));
431 delta
= sqr(Xs
+ 1) + sqr(Ys
- 1) - sqr(xs
) - sqr(ys
);
446 if (2 * delta
+ 2 * Yc
- 1 <= 0)
450 else if (2 * delta
- 2 * Xc
- 1 <= 0)
464 delta
+= 2 * Xc
- 2 * Yc
+ 2;
480 drawline((int)xc
-ox1
,(int)yc
-oy1
,".");