xref: /illumos-gate/usr/src/cmd/troff/n9.c (revision e5190c10)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate /*
237c478bd9Sstevel@tonic-gate  * Copyright 1989 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
287c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate /*
317c478bd9Sstevel@tonic-gate  * University Copyright- Copyright (c) 1982, 1986, 1988
327c478bd9Sstevel@tonic-gate  * The Regents of the University of California
337c478bd9Sstevel@tonic-gate  * All Rights Reserved
347c478bd9Sstevel@tonic-gate  *
357c478bd9Sstevel@tonic-gate  * University Acknowledgment- Portions of this document are derived from
367c478bd9Sstevel@tonic-gate  * software developed by the University of California, Berkeley, and its
377c478bd9Sstevel@tonic-gate  * contributors.
387c478bd9Sstevel@tonic-gate  */
397c478bd9Sstevel@tonic-gate 
40*e5190c10Smuffin #pragma ident	"%Z%%M%	%I%	%E% SMI"
41*e5190c10Smuffin 
427c478bd9Sstevel@tonic-gate #include <libintl.h>
437c478bd9Sstevel@tonic-gate #include <stdlib.h>
447c478bd9Sstevel@tonic-gate 
457c478bd9Sstevel@tonic-gate #include "tdef.h"
467c478bd9Sstevel@tonic-gate #ifdef NROFF
477c478bd9Sstevel@tonic-gate #include "tw.h"
487c478bd9Sstevel@tonic-gate #endif
497c478bd9Sstevel@tonic-gate #include "ext.h"
507c478bd9Sstevel@tonic-gate #ifdef EUC
517c478bd9Sstevel@tonic-gate #include <locale.h>
527c478bd9Sstevel@tonic-gate #include <wctype.h>
537c478bd9Sstevel@tonic-gate #include <langinfo.h>
547c478bd9Sstevel@tonic-gate 
557c478bd9Sstevel@tonic-gate #define	ISO646	"646"
567c478bd9Sstevel@tonic-gate 
577c478bd9Sstevel@tonic-gate int	multi_locale;
587c478bd9Sstevel@tonic-gate int	(*wdbdg)(wchar_t, wchar_t, int);
597c478bd9Sstevel@tonic-gate wchar_t	*(*wddlm)(wchar_t, wchar_t, int);
607c478bd9Sstevel@tonic-gate 
617c478bd9Sstevel@tonic-gate int	csi_width[4] = {
627c478bd9Sstevel@tonic-gate 	1,
637c478bd9Sstevel@tonic-gate 	1,
647c478bd9Sstevel@tonic-gate 	2,
657c478bd9Sstevel@tonic-gate 	3,
667c478bd9Sstevel@tonic-gate };
677c478bd9Sstevel@tonic-gate #endif /* EUC */
687c478bd9Sstevel@tonic-gate 
697c478bd9Sstevel@tonic-gate /*
707c478bd9Sstevel@tonic-gate  * troff9.c
717c478bd9Sstevel@tonic-gate  *
727c478bd9Sstevel@tonic-gate  * misc functions
737c478bd9Sstevel@tonic-gate  */
747c478bd9Sstevel@tonic-gate 
757c478bd9Sstevel@tonic-gate tchar setz()
767c478bd9Sstevel@tonic-gate {
777c478bd9Sstevel@tonic-gate 	tchar i;
787c478bd9Sstevel@tonic-gate 
797c478bd9Sstevel@tonic-gate 	if (!ismot(i = getch()))
807c478bd9Sstevel@tonic-gate 		i |= ZBIT;
817c478bd9Sstevel@tonic-gate 	return(i);
827c478bd9Sstevel@tonic-gate }
837c478bd9Sstevel@tonic-gate 
84*e5190c10Smuffin int
857c478bd9Sstevel@tonic-gate setline()
867c478bd9Sstevel@tonic-gate {
87*e5190c10Smuffin 	tchar *i;
887c478bd9Sstevel@tonic-gate 	tchar c;
897c478bd9Sstevel@tonic-gate 	int	length;
907c478bd9Sstevel@tonic-gate 	int	w, cnt, delim, rem, temp;
917c478bd9Sstevel@tonic-gate 	tchar linebuf[NC];
927c478bd9Sstevel@tonic-gate 
937c478bd9Sstevel@tonic-gate 	if (ismot(c = getch()))
94*e5190c10Smuffin 		return (0);
957c478bd9Sstevel@tonic-gate 	delim = cbits(c);
967c478bd9Sstevel@tonic-gate 	vflag = 0;
977c478bd9Sstevel@tonic-gate 	dfact = EM;
987c478bd9Sstevel@tonic-gate 	length = quant(atoi(), HOR);
997c478bd9Sstevel@tonic-gate 	dfact = 1;
1007c478bd9Sstevel@tonic-gate 	if (!length) {
1017c478bd9Sstevel@tonic-gate 		eat(delim);
102*e5190c10Smuffin 		return (0);
1037c478bd9Sstevel@tonic-gate 	}
1047c478bd9Sstevel@tonic-gate s0:
1057c478bd9Sstevel@tonic-gate 	if ((cbits(c = getch())) == delim) {
1067c478bd9Sstevel@tonic-gate 		ch = c;
1077c478bd9Sstevel@tonic-gate 		c = RULE | chbits;
1087c478bd9Sstevel@tonic-gate 	} else if (cbits(c) == FILLER)
1097c478bd9Sstevel@tonic-gate 		goto s0;
1107c478bd9Sstevel@tonic-gate 	w = width(c);
1117c478bd9Sstevel@tonic-gate 	i = linebuf;
1127c478bd9Sstevel@tonic-gate 	if (length < 0) {
1137c478bd9Sstevel@tonic-gate 		*i++ = makem(length);
1147c478bd9Sstevel@tonic-gate 		length = -length;
1157c478bd9Sstevel@tonic-gate 	}
1167c478bd9Sstevel@tonic-gate 	if (!(cnt = length / w)) {
1177c478bd9Sstevel@tonic-gate 		*i++ = makem(-(temp = ((w - length) / 2)));
1187c478bd9Sstevel@tonic-gate 		*i++ = c;
1197c478bd9Sstevel@tonic-gate 		*i++ = makem(-(w - length - temp));
1207c478bd9Sstevel@tonic-gate 		goto s1;
1217c478bd9Sstevel@tonic-gate 	}
1227c478bd9Sstevel@tonic-gate 	if (rem = length % w) {
1237c478bd9Sstevel@tonic-gate 		if (cbits(c) == RULE || cbits(c) == UNDERLINE || cbits(c) == ROOTEN)
1247c478bd9Sstevel@tonic-gate 			*i++ = c | ZBIT;
1257c478bd9Sstevel@tonic-gate 		*i++ = makem(rem);
1267c478bd9Sstevel@tonic-gate 	}
1277c478bd9Sstevel@tonic-gate 	if (cnt) {
1287c478bd9Sstevel@tonic-gate 		*i++ = RPT;
1297c478bd9Sstevel@tonic-gate 		*i++ = cnt;
1307c478bd9Sstevel@tonic-gate 		*i++ = c;
1317c478bd9Sstevel@tonic-gate 	}
1327c478bd9Sstevel@tonic-gate s1:
1337c478bd9Sstevel@tonic-gate 	*i++ = 0;
1347c478bd9Sstevel@tonic-gate 	eat(delim);
1357c478bd9Sstevel@tonic-gate 	pushback(linebuf);
136*e5190c10Smuffin 
137*e5190c10Smuffin 	return (0);
1387c478bd9Sstevel@tonic-gate }
1397c478bd9Sstevel@tonic-gate 
1407c478bd9Sstevel@tonic-gate 
141*e5190c10Smuffin int
1427c478bd9Sstevel@tonic-gate eat(c)
143*e5190c10Smuffin int	c;
1447c478bd9Sstevel@tonic-gate {
145*e5190c10Smuffin 	int	i;
1467c478bd9Sstevel@tonic-gate 
1477c478bd9Sstevel@tonic-gate 	while ((i = cbits(getch())) != c &&  (i != '\n'))
1487c478bd9Sstevel@tonic-gate 		;
1497c478bd9Sstevel@tonic-gate 	return(i);
1507c478bd9Sstevel@tonic-gate }
1517c478bd9Sstevel@tonic-gate 
1527c478bd9Sstevel@tonic-gate 
153*e5190c10Smuffin int
1547c478bd9Sstevel@tonic-gate setov()
1557c478bd9Sstevel@tonic-gate {
156*e5190c10Smuffin 	int	j, k;
1577c478bd9Sstevel@tonic-gate 	tchar i, o[NOV];
1587c478bd9Sstevel@tonic-gate 	int delim, w[NOV];
1597c478bd9Sstevel@tonic-gate 
1607c478bd9Sstevel@tonic-gate 	if (ismot(i = getch()))
161*e5190c10Smuffin 		return (0);
1627c478bd9Sstevel@tonic-gate 	delim = cbits(i);
1637c478bd9Sstevel@tonic-gate 	for (k = 0; (k < NOV) && ((j = cbits(i = getch())) != delim) &&  (j != '\n'); k++) {
1647c478bd9Sstevel@tonic-gate 		o[k] = i;
1657c478bd9Sstevel@tonic-gate 		w[k] = width(i);
1667c478bd9Sstevel@tonic-gate 	}
1677c478bd9Sstevel@tonic-gate 	o[k] = w[k] = 0;
1687c478bd9Sstevel@tonic-gate 	if (o[0])
1697c478bd9Sstevel@tonic-gate 		for (j = 1; j; ) {
1707c478bd9Sstevel@tonic-gate 			j = 0;
1717c478bd9Sstevel@tonic-gate 			for (k = 1; o[k] ; k++) {
1727c478bd9Sstevel@tonic-gate 				if (w[k-1] < w[k]) {
1737c478bd9Sstevel@tonic-gate 					j++;
1747c478bd9Sstevel@tonic-gate 					i = w[k];
1757c478bd9Sstevel@tonic-gate 					w[k] = w[k-1];
1767c478bd9Sstevel@tonic-gate 					w[k-1] = i;
1777c478bd9Sstevel@tonic-gate 					i = o[k];
1787c478bd9Sstevel@tonic-gate 					o[k] = o[k-1];
1797c478bd9Sstevel@tonic-gate 					o[k-1] = i;
1807c478bd9Sstevel@tonic-gate 				}
1817c478bd9Sstevel@tonic-gate 			}
1827c478bd9Sstevel@tonic-gate 		}
1837c478bd9Sstevel@tonic-gate 	else
184*e5190c10Smuffin 		return (0);
1857c478bd9Sstevel@tonic-gate 	*pbp++ = makem(w[0] / 2);
1867c478bd9Sstevel@tonic-gate 	for (k = 0; o[k]; k++)
1877c478bd9Sstevel@tonic-gate 		;
1887c478bd9Sstevel@tonic-gate 	while (k>0) {
1897c478bd9Sstevel@tonic-gate 		k--;
1907c478bd9Sstevel@tonic-gate 		*pbp++ = makem(-((w[k] + w[k+1]) / 2));
1917c478bd9Sstevel@tonic-gate 		*pbp++ = o[k];
1927c478bd9Sstevel@tonic-gate 	}
193*e5190c10Smuffin 
194*e5190c10Smuffin 	return (0);
1957c478bd9Sstevel@tonic-gate }
1967c478bd9Sstevel@tonic-gate 
1977c478bd9Sstevel@tonic-gate 
198*e5190c10Smuffin int
1997c478bd9Sstevel@tonic-gate setbra()
2007c478bd9Sstevel@tonic-gate {
201*e5190c10Smuffin 	int	k;
2027c478bd9Sstevel@tonic-gate 	tchar i, *j, dwn;
2037c478bd9Sstevel@tonic-gate 	int	cnt, delim;
2047c478bd9Sstevel@tonic-gate 	tchar brabuf[NC];
2057c478bd9Sstevel@tonic-gate 
2067c478bd9Sstevel@tonic-gate 	if (ismot(i = getch()))
207*e5190c10Smuffin 		return (0);
2087c478bd9Sstevel@tonic-gate 	delim = cbits(i);
2097c478bd9Sstevel@tonic-gate 	j = brabuf + 1;
2107c478bd9Sstevel@tonic-gate 	cnt = 0;
2117c478bd9Sstevel@tonic-gate #ifdef NROFF
2127c478bd9Sstevel@tonic-gate 	dwn = (2 * t.Halfline) | MOT | VMOT;
2137c478bd9Sstevel@tonic-gate #endif
2147c478bd9Sstevel@tonic-gate #ifndef NROFF
2157c478bd9Sstevel@tonic-gate 	dwn = EM | MOT | VMOT;
2167c478bd9Sstevel@tonic-gate #endif
2177c478bd9Sstevel@tonic-gate 	while (((k = cbits(i = getch())) != delim) && (k != '\n') &&  (j <= (brabuf + NC - 4))) {
2187c478bd9Sstevel@tonic-gate 		*j++ = i | ZBIT;
2197c478bd9Sstevel@tonic-gate 		*j++ = dwn;
2207c478bd9Sstevel@tonic-gate 		cnt++;
2217c478bd9Sstevel@tonic-gate 	}
2227c478bd9Sstevel@tonic-gate 	if (--cnt < 0)
223*e5190c10Smuffin 		return (0);
2247c478bd9Sstevel@tonic-gate 	else if (!cnt) {
2257c478bd9Sstevel@tonic-gate 		ch = *(j - 2);
226*e5190c10Smuffin 		return (0);
2277c478bd9Sstevel@tonic-gate 	}
2287c478bd9Sstevel@tonic-gate 	*j = 0;
2297c478bd9Sstevel@tonic-gate #ifdef NROFF
2307c478bd9Sstevel@tonic-gate 	*--j = *brabuf = (cnt * t.Halfline) | MOT | NMOT | VMOT;
2317c478bd9Sstevel@tonic-gate #endif
2327c478bd9Sstevel@tonic-gate #ifndef NROFF
2337c478bd9Sstevel@tonic-gate 	*--j = *brabuf = (cnt * EM) / 2 | MOT | NMOT | VMOT;
2347c478bd9Sstevel@tonic-gate #endif
2357c478bd9Sstevel@tonic-gate 	*--j &= ~ZBIT;
2367c478bd9Sstevel@tonic-gate 	pushback(brabuf);
237*e5190c10Smuffin 
238*e5190c10Smuffin 	return (0);
2397c478bd9Sstevel@tonic-gate }
2407c478bd9Sstevel@tonic-gate 
2417c478bd9Sstevel@tonic-gate 
242*e5190c10Smuffin int
2437c478bd9Sstevel@tonic-gate setvline()
2447c478bd9Sstevel@tonic-gate {
245*e5190c10Smuffin 	int	i;
2467c478bd9Sstevel@tonic-gate 	tchar c, rem, ver, neg;
2477c478bd9Sstevel@tonic-gate 	int	cnt, delim, v;
2487c478bd9Sstevel@tonic-gate 	tchar vlbuf[NC];
249*e5190c10Smuffin 	tchar *vlp;
2507c478bd9Sstevel@tonic-gate 
2517c478bd9Sstevel@tonic-gate 	if (ismot(c = getch()))
252*e5190c10Smuffin 		return (0);
2537c478bd9Sstevel@tonic-gate 	delim = cbits(c);
2547c478bd9Sstevel@tonic-gate 	dfact = lss;
2557c478bd9Sstevel@tonic-gate 	vflag++;
2567c478bd9Sstevel@tonic-gate 	i = quant(atoi(), VERT);
2577c478bd9Sstevel@tonic-gate 	dfact = 1;
2587c478bd9Sstevel@tonic-gate 	if (!i) {
2597c478bd9Sstevel@tonic-gate 		eat(delim);
2607c478bd9Sstevel@tonic-gate 		vflag = 0;
261*e5190c10Smuffin 		return (0);
2627c478bd9Sstevel@tonic-gate 	}
2637c478bd9Sstevel@tonic-gate 	if ((cbits(c = getch())) == delim) {
2647c478bd9Sstevel@tonic-gate 		c = BOXRULE | chbits;	/*default box rule*/
2657c478bd9Sstevel@tonic-gate 	} else
2667c478bd9Sstevel@tonic-gate 		getch();
2677c478bd9Sstevel@tonic-gate 	c |= ZBIT;
2687c478bd9Sstevel@tonic-gate 	neg = 0;
2697c478bd9Sstevel@tonic-gate 	if (i < 0) {
2707c478bd9Sstevel@tonic-gate 		i = -i;
2717c478bd9Sstevel@tonic-gate 		neg = NMOT;
2727c478bd9Sstevel@tonic-gate 	}
2737c478bd9Sstevel@tonic-gate #ifdef NROFF
2747c478bd9Sstevel@tonic-gate 	v = 2 * t.Halfline;
2757c478bd9Sstevel@tonic-gate #endif
2767c478bd9Sstevel@tonic-gate #ifndef NROFF
2777c478bd9Sstevel@tonic-gate 	v = EM;
2787c478bd9Sstevel@tonic-gate #endif
2797c478bd9Sstevel@tonic-gate 	cnt = i / v;
2807c478bd9Sstevel@tonic-gate 	rem = makem(i % v) | neg;
2817c478bd9Sstevel@tonic-gate 	ver = makem(v) | neg;
2827c478bd9Sstevel@tonic-gate 	vlp = vlbuf;
2837c478bd9Sstevel@tonic-gate 	if (!neg)
2847c478bd9Sstevel@tonic-gate 		*vlp++ = ver;
2857c478bd9Sstevel@tonic-gate 	if (absmot(rem) != 0) {
2867c478bd9Sstevel@tonic-gate 		*vlp++ = c;
2877c478bd9Sstevel@tonic-gate 		*vlp++ = rem;
2887c478bd9Sstevel@tonic-gate 	}
2897c478bd9Sstevel@tonic-gate 	while ((vlp < (vlbuf + NC - 3)) && cnt--) {
2907c478bd9Sstevel@tonic-gate 		*vlp++ = c;
2917c478bd9Sstevel@tonic-gate 		*vlp++ = ver;
2927c478bd9Sstevel@tonic-gate 	}
2937c478bd9Sstevel@tonic-gate 	*(vlp - 2) &= ~ZBIT;
2947c478bd9Sstevel@tonic-gate 	if (!neg)
2957c478bd9Sstevel@tonic-gate 		vlp--;
2967c478bd9Sstevel@tonic-gate 	*vlp++ = 0;
2977c478bd9Sstevel@tonic-gate 	pushback(vlbuf);
2987c478bd9Sstevel@tonic-gate 	vflag = 0;
299*e5190c10Smuffin 
300*e5190c10Smuffin 	return (0);
3017c478bd9Sstevel@tonic-gate }
3027c478bd9Sstevel@tonic-gate 
3037c478bd9Sstevel@tonic-gate #define	NPAIR	(NC/2-6)	/* max pairs in spline, etc. */
3047c478bd9Sstevel@tonic-gate 
305*e5190c10Smuffin int
3067c478bd9Sstevel@tonic-gate setdraw()	/* generate internal cookies for a drawing function */
3077c478bd9Sstevel@tonic-gate {
3087c478bd9Sstevel@tonic-gate 	int i, j, k, dx[NPAIR], dy[NPAIR], delim, type;
3097c478bd9Sstevel@tonic-gate 	tchar c, drawbuf[NC];
3107c478bd9Sstevel@tonic-gate 
3117c478bd9Sstevel@tonic-gate 	/* input is \D'f dx dy dx dy ... c' (or at least it had better be) */
3127c478bd9Sstevel@tonic-gate 	/* this does drawing function f with character c and the */
3137c478bd9Sstevel@tonic-gate 	/* specified dx,dy pairs interpreted as appropriate */
3147c478bd9Sstevel@tonic-gate 	/* pairs are deltas from last point, except for radii */
3157c478bd9Sstevel@tonic-gate 
3167c478bd9Sstevel@tonic-gate 	/* l dx dy:	line from here by dx,dy */
3177c478bd9Sstevel@tonic-gate 	/* c x:		circle of diameter x, left side here */
3187c478bd9Sstevel@tonic-gate 	/* e x y:	ellipse of diameters x,y, left side here */
3197c478bd9Sstevel@tonic-gate 	/* a dx1 dy1 dx2 dy2:
3207c478bd9Sstevel@tonic-gate 			ccw arc: ctr at dx1,dy1, then end at dx2,dy2 from there */
3217c478bd9Sstevel@tonic-gate 	/* ~ dx1 dy1 dx2 dy2...:
3227c478bd9Sstevel@tonic-gate 			spline to dx1,dy1 to dx2,dy2 ... */
3237c478bd9Sstevel@tonic-gate 	/* f dx dy ...:	f is any other char:  like spline */
3247c478bd9Sstevel@tonic-gate 
3257c478bd9Sstevel@tonic-gate 	if (ismot(c = getch()))
326*e5190c10Smuffin 		return (0);
3277c478bd9Sstevel@tonic-gate 	delim = cbits(c);
3287c478bd9Sstevel@tonic-gate 	type = cbits(getch());
3297c478bd9Sstevel@tonic-gate 	for (i = 0; i < NPAIR ; i++) {
3307c478bd9Sstevel@tonic-gate 		c = getch();
3317c478bd9Sstevel@tonic-gate 		if (cbits(c) == delim)
3327c478bd9Sstevel@tonic-gate 			break;
3337c478bd9Sstevel@tonic-gate 	/* ought to pick up optional drawing character */
3347c478bd9Sstevel@tonic-gate 		if (cbits(c) != ' ')
3357c478bd9Sstevel@tonic-gate 			ch = c;
3367c478bd9Sstevel@tonic-gate 		vflag = 0;
3377c478bd9Sstevel@tonic-gate 		dfact = EM;
3387c478bd9Sstevel@tonic-gate 		dx[i] = quant(atoi(), HOR);
3397c478bd9Sstevel@tonic-gate 		if (dx[i] > MAXMOT)
3407c478bd9Sstevel@tonic-gate 			dx[i] = MAXMOT;
3417c478bd9Sstevel@tonic-gate 		else if (dx[i] < -MAXMOT)
3427c478bd9Sstevel@tonic-gate 			dx[i] = -MAXMOT;
3437c478bd9Sstevel@tonic-gate 		if (cbits((c = getch())) == delim) {	/* spacer */
3447c478bd9Sstevel@tonic-gate 			dy[i++] = 0;
3457c478bd9Sstevel@tonic-gate 			break;
3467c478bd9Sstevel@tonic-gate 		}
3477c478bd9Sstevel@tonic-gate 		vflag = 1;
3487c478bd9Sstevel@tonic-gate 		dfact = lss;
3497c478bd9Sstevel@tonic-gate 		dy[i] = quant(atoi(), VERT);
3507c478bd9Sstevel@tonic-gate 		if (dy[i] > MAXMOT)
3517c478bd9Sstevel@tonic-gate 			dy[i] = MAXMOT;
3527c478bd9Sstevel@tonic-gate 		else if (dy[i] < -MAXMOT)
3537c478bd9Sstevel@tonic-gate 			dy[i] = -MAXMOT;
3547c478bd9Sstevel@tonic-gate 	}
3557c478bd9Sstevel@tonic-gate 	dfact = 1;
3567c478bd9Sstevel@tonic-gate 	vflag = 0;
3577c478bd9Sstevel@tonic-gate #ifndef NROFF
3587c478bd9Sstevel@tonic-gate 	drawbuf[0] = DRAWFCN | chbits | ZBIT;
3597c478bd9Sstevel@tonic-gate 	drawbuf[1] = type | chbits | ZBIT;
3607c478bd9Sstevel@tonic-gate 	drawbuf[2] = '.' | chbits | ZBIT;	/* use default drawing character */
3617c478bd9Sstevel@tonic-gate 	for (k = 0, j = 3; k < i; k++) {
3627c478bd9Sstevel@tonic-gate 		drawbuf[j++] = MOT | ((dx[k] >= 0) ? dx[k] : (NMOT | -dx[k]));
3637c478bd9Sstevel@tonic-gate 		drawbuf[j++] = MOT | VMOT | ((dy[k] >= 0) ? dy[k] : (NMOT | -dy[k]));
3647c478bd9Sstevel@tonic-gate 	}
3657c478bd9Sstevel@tonic-gate 	if (type == DRAWELLIPSE) {
3667c478bd9Sstevel@tonic-gate 		drawbuf[5] = drawbuf[4] | NMOT;	/* so the net vertical is zero */
3677c478bd9Sstevel@tonic-gate 		j = 6;
3687c478bd9Sstevel@tonic-gate 	}
3697c478bd9Sstevel@tonic-gate 	drawbuf[j++] = DRAWFCN | chbits | ZBIT;	/* marks end for ptout */
3707c478bd9Sstevel@tonic-gate 	drawbuf[j] = 0;
3717c478bd9Sstevel@tonic-gate 	pushback(drawbuf);
3727c478bd9Sstevel@tonic-gate #endif
373*e5190c10Smuffin 	return (0);
3747c478bd9Sstevel@tonic-gate }
3757c478bd9Sstevel@tonic-gate 
3767c478bd9Sstevel@tonic-gate 
377*e5190c10Smuffin int
3787c478bd9Sstevel@tonic-gate casefc()
3797c478bd9Sstevel@tonic-gate {
380*e5190c10Smuffin 	int	i;
3817c478bd9Sstevel@tonic-gate 	tchar j;
3827c478bd9Sstevel@tonic-gate 
3837c478bd9Sstevel@tonic-gate 	gchtab[fc] &= ~FCBIT;
3847c478bd9Sstevel@tonic-gate 	fc = IMP;
3857c478bd9Sstevel@tonic-gate 	padc = ' ';
3867c478bd9Sstevel@tonic-gate 	if (skip() || ismot(j = getch()) || (i = cbits(j)) == '\n')
387*e5190c10Smuffin 		return (0);
3887c478bd9Sstevel@tonic-gate 	fc = i;
3897c478bd9Sstevel@tonic-gate 	gchtab[fc] |= FCBIT;
3907c478bd9Sstevel@tonic-gate 	if (skip() || ismot(ch) || (ch = cbits(ch)) == fc)
391*e5190c10Smuffin 		return (0);
3927c478bd9Sstevel@tonic-gate 	padc = ch;
393*e5190c10Smuffin 
394*e5190c10Smuffin 	return (0);
3957c478bd9Sstevel@tonic-gate }
3967c478bd9Sstevel@tonic-gate 
3977c478bd9Sstevel@tonic-gate 
3987c478bd9Sstevel@tonic-gate tchar
3997c478bd9Sstevel@tonic-gate setfield(x)
4007c478bd9Sstevel@tonic-gate int	x;
4017c478bd9Sstevel@tonic-gate {
402*e5190c10Smuffin 	tchar ii, jj, *fp;
403*e5190c10Smuffin 	int	i, j;
4047c478bd9Sstevel@tonic-gate 	int length, ws, npad, temp, type;
4057c478bd9Sstevel@tonic-gate 	tchar **pp, *padptr[NPP];
4067c478bd9Sstevel@tonic-gate 	tchar fbuf[FBUFSZ];
4077c478bd9Sstevel@tonic-gate 	int savfc, savtc, savlc;
4087c478bd9Sstevel@tonic-gate 	tchar rchar;
4097c478bd9Sstevel@tonic-gate 	int savepos;
4107c478bd9Sstevel@tonic-gate 
4117c478bd9Sstevel@tonic-gate 	if (x == tabch)
4127c478bd9Sstevel@tonic-gate 		rchar = tabc | chbits;
4137c478bd9Sstevel@tonic-gate 	else if (x ==  ldrch)
4147c478bd9Sstevel@tonic-gate 		rchar = dotc | chbits;
4157c478bd9Sstevel@tonic-gate 	temp = npad = ws = 0;
4167c478bd9Sstevel@tonic-gate 	savfc = fc;
4177c478bd9Sstevel@tonic-gate 	savtc = tabch;
4187c478bd9Sstevel@tonic-gate 	savlc = ldrch;
4197c478bd9Sstevel@tonic-gate 	tabch = ldrch = fc = IMP;
4207c478bd9Sstevel@tonic-gate 	savepos = numtab[HP].val;
4217c478bd9Sstevel@tonic-gate 	gchtab[tabch] &= ~TABBIT;
4227c478bd9Sstevel@tonic-gate 	gchtab[ldrch] &= ~LDRBIT;
4237c478bd9Sstevel@tonic-gate 	gchtab[fc] &= ~FCBIT;
4247c478bd9Sstevel@tonic-gate 	gchtab[IMP] |= TABBIT|LDRBIT|FCBIT;
4257c478bd9Sstevel@tonic-gate 	for (j = 0; ; j++) {
4267c478bd9Sstevel@tonic-gate 		if ((tabtab[j] & TABMASK) == 0) {
4277c478bd9Sstevel@tonic-gate 			if (x == savfc)
4287c478bd9Sstevel@tonic-gate 				errprint(gettext("zero field width."));
4297c478bd9Sstevel@tonic-gate 			jj = 0;
4307c478bd9Sstevel@tonic-gate 			goto rtn;
4317c478bd9Sstevel@tonic-gate 		}
4327c478bd9Sstevel@tonic-gate 		if ((length = ((tabtab[j] & TABMASK) - numtab[HP].val)) > 0 )
4337c478bd9Sstevel@tonic-gate 			break;
4347c478bd9Sstevel@tonic-gate 	}
4357c478bd9Sstevel@tonic-gate 	type = tabtab[j] & (~TABMASK);
4367c478bd9Sstevel@tonic-gate 	fp = fbuf;
4377c478bd9Sstevel@tonic-gate 	pp = padptr;
4387c478bd9Sstevel@tonic-gate 	if (x == savfc) {
4397c478bd9Sstevel@tonic-gate 		while (1) {
4407c478bd9Sstevel@tonic-gate 			j = cbits(ii = getch());
4417c478bd9Sstevel@tonic-gate 			jj = width(ii);
4427c478bd9Sstevel@tonic-gate 			widthp = jj;
4437c478bd9Sstevel@tonic-gate 			numtab[HP].val += jj;
4447c478bd9Sstevel@tonic-gate 			if (j == padc) {
4457c478bd9Sstevel@tonic-gate 				npad++;
4467c478bd9Sstevel@tonic-gate 				*pp++ = fp;
4477c478bd9Sstevel@tonic-gate 				if (pp > (padptr + NPP - 1))
4487c478bd9Sstevel@tonic-gate 					break;
4497c478bd9Sstevel@tonic-gate 				goto s1;
4507c478bd9Sstevel@tonic-gate 			} else if (j == savfc)
4517c478bd9Sstevel@tonic-gate 				break;
4527c478bd9Sstevel@tonic-gate 			else if (j == '\n') {
4537c478bd9Sstevel@tonic-gate 				temp = j;
4547c478bd9Sstevel@tonic-gate 				nlflg = 0;
4557c478bd9Sstevel@tonic-gate 				break;
4567c478bd9Sstevel@tonic-gate 			}
4577c478bd9Sstevel@tonic-gate 			ws += jj;
4587c478bd9Sstevel@tonic-gate s1:
4597c478bd9Sstevel@tonic-gate 			*fp++ = ii;
4607c478bd9Sstevel@tonic-gate 			if (fp > (fbuf + FBUFSZ - 3))
4617c478bd9Sstevel@tonic-gate 				break;
4627c478bd9Sstevel@tonic-gate 		}
4637c478bd9Sstevel@tonic-gate 		if (!npad) {
4647c478bd9Sstevel@tonic-gate 			npad++;
4657c478bd9Sstevel@tonic-gate 			*pp++ = fp;
4667c478bd9Sstevel@tonic-gate 			*fp++ = 0;
4677c478bd9Sstevel@tonic-gate 		}
4687c478bd9Sstevel@tonic-gate 		*fp++ = temp;
4697c478bd9Sstevel@tonic-gate 		*fp++ = 0;
4707c478bd9Sstevel@tonic-gate 		temp = i = (j = length - ws) / npad;
4717c478bd9Sstevel@tonic-gate 		i = (i / HOR) * HOR;
4727c478bd9Sstevel@tonic-gate 		if ((j -= i * npad) < 0)
4737c478bd9Sstevel@tonic-gate 			j = -j;
4747c478bd9Sstevel@tonic-gate 		ii = makem(i);
4757c478bd9Sstevel@tonic-gate 		if (temp < 0)
4767c478bd9Sstevel@tonic-gate 			ii |= NMOT;
4777c478bd9Sstevel@tonic-gate 		for (; npad > 0; npad--) {
4787c478bd9Sstevel@tonic-gate 			*(*--pp) = ii;
4797c478bd9Sstevel@tonic-gate 			if (j) {
4807c478bd9Sstevel@tonic-gate 				j -= HOR;
4817c478bd9Sstevel@tonic-gate 				(*(*pp)) += HOR;
4827c478bd9Sstevel@tonic-gate 			}
4837c478bd9Sstevel@tonic-gate 		}
4847c478bd9Sstevel@tonic-gate 		pushback(fbuf);
4857c478bd9Sstevel@tonic-gate 		jj = 0;
4867c478bd9Sstevel@tonic-gate 	} else if (type == 0) {
4877c478bd9Sstevel@tonic-gate 		/*plain tab or leader*/
4887c478bd9Sstevel@tonic-gate 		if ((j = width(rchar)) > 0) {
4897c478bd9Sstevel@tonic-gate 			int nchar = length / j;
4907c478bd9Sstevel@tonic-gate 			while (nchar-->0 && pbp < &pbbuf[NC-3]) {
4917c478bd9Sstevel@tonic-gate 				numtab[HP].val += j;
4927c478bd9Sstevel@tonic-gate 				widthp = j;
4937c478bd9Sstevel@tonic-gate 				*pbp++ = rchar;
4947c478bd9Sstevel@tonic-gate 			}
4957c478bd9Sstevel@tonic-gate 			length %= j;
4967c478bd9Sstevel@tonic-gate 		}
4977c478bd9Sstevel@tonic-gate 		if (length)
4987c478bd9Sstevel@tonic-gate 			jj = length | MOT;
4997c478bd9Sstevel@tonic-gate 		else
5007c478bd9Sstevel@tonic-gate 			jj = getch0();
5017c478bd9Sstevel@tonic-gate 	} else {
5027c478bd9Sstevel@tonic-gate 		/*center tab*/
5037c478bd9Sstevel@tonic-gate 		/*right tab*/
5047c478bd9Sstevel@tonic-gate 		while (((j = cbits(ii = getch())) != savtc) &&  (j != '\n') && (j != savlc)) {
5057c478bd9Sstevel@tonic-gate 			jj = width(ii);
5067c478bd9Sstevel@tonic-gate 			ws += jj;
5077c478bd9Sstevel@tonic-gate 			numtab[HP].val += jj;
5087c478bd9Sstevel@tonic-gate 			widthp = jj;
5097c478bd9Sstevel@tonic-gate 			*fp++ = ii;
5107c478bd9Sstevel@tonic-gate 			if (fp > (fbuf + FBUFSZ - 3))
5117c478bd9Sstevel@tonic-gate 				break;
5127c478bd9Sstevel@tonic-gate 		}
5137c478bd9Sstevel@tonic-gate 		*fp++ = ii;
5147c478bd9Sstevel@tonic-gate 		*fp++ = 0;
5157c478bd9Sstevel@tonic-gate 		if (type == RTAB)
5167c478bd9Sstevel@tonic-gate 			length -= ws;
5177c478bd9Sstevel@tonic-gate 		else
5187c478bd9Sstevel@tonic-gate 			length -= ws / 2; /*CTAB*/
5197c478bd9Sstevel@tonic-gate 		pushback(fbuf);
5207c478bd9Sstevel@tonic-gate 		if ((j = width(rchar)) != 0 && length > 0) {
5217c478bd9Sstevel@tonic-gate 			int nchar = length / j;
5227c478bd9Sstevel@tonic-gate 			while (nchar-- > 0 && pbp < &pbbuf[NC-3])
5237c478bd9Sstevel@tonic-gate 				*pbp++ = rchar;
5247c478bd9Sstevel@tonic-gate 			length %= j;
5257c478bd9Sstevel@tonic-gate 		}
5267c478bd9Sstevel@tonic-gate 		length = (length / HOR) * HOR;
5277c478bd9Sstevel@tonic-gate 		jj = makem(length);
5287c478bd9Sstevel@tonic-gate 		nlflg = 0;
5297c478bd9Sstevel@tonic-gate 	}
5307c478bd9Sstevel@tonic-gate rtn:
5317c478bd9Sstevel@tonic-gate 	gchtab[fc] &= ~FCBIT;
5327c478bd9Sstevel@tonic-gate 	gchtab[tabch] &= ~TABBIT;
5337c478bd9Sstevel@tonic-gate 	gchtab[ldrch] &= ~LDRBIT;
5347c478bd9Sstevel@tonic-gate 	fc = savfc;
5357c478bd9Sstevel@tonic-gate 	tabch = savtc;
5367c478bd9Sstevel@tonic-gate 	ldrch = savlc;
5377c478bd9Sstevel@tonic-gate 	gchtab[fc] |= FCBIT;
5387c478bd9Sstevel@tonic-gate 	gchtab[tabch] = TABBIT;
5397c478bd9Sstevel@tonic-gate 	gchtab[ldrch] |= LDRBIT;
5407c478bd9Sstevel@tonic-gate 	numtab[HP].val = savepos;
5417c478bd9Sstevel@tonic-gate 	return(jj);
5427c478bd9Sstevel@tonic-gate }
5437c478bd9Sstevel@tonic-gate 
5447c478bd9Sstevel@tonic-gate 
5457c478bd9Sstevel@tonic-gate #ifdef EUC
5467c478bd9Sstevel@tonic-gate #ifdef NROFF
5477c478bd9Sstevel@tonic-gate /* locale specific initialization */
5487c478bd9Sstevel@tonic-gate int localize()
5497c478bd9Sstevel@tonic-gate {
5507c478bd9Sstevel@tonic-gate 	extern int	wdbindf();
5517c478bd9Sstevel@tonic-gate 	extern wchar_t	*wddelim();
5527c478bd9Sstevel@tonic-gate 	char	*codeset;
5537c478bd9Sstevel@tonic-gate 
5547c478bd9Sstevel@tonic-gate 	codeset = nl_langinfo(CODESET);
5557c478bd9Sstevel@tonic-gate 
5567c478bd9Sstevel@tonic-gate 	if (MB_CUR_MAX > 1)
5577c478bd9Sstevel@tonic-gate 		multi_locale = 1;
5587c478bd9Sstevel@tonic-gate 	else {
5597c478bd9Sstevel@tonic-gate 		if (*codeset == '\0' ||
5607c478bd9Sstevel@tonic-gate 			(strcmp(codeset, ISO646) == 0)) {
5617c478bd9Sstevel@tonic-gate 			/*
5627c478bd9Sstevel@tonic-gate 			 * if codeset is an empty string
5637c478bd9Sstevel@tonic-gate 			 * assumes this is C locale (7-bit) locale.
5647c478bd9Sstevel@tonic-gate 			 * This happens in 2.5, 2.5.1, and 2.6 system
5657c478bd9Sstevel@tonic-gate 			 * Or, if codeset is "646"
5667c478bd9Sstevel@tonic-gate 			 * this is 7-bit locale.
5677c478bd9Sstevel@tonic-gate 			 */
5687c478bd9Sstevel@tonic-gate 			multi_locale = 0;
5697c478bd9Sstevel@tonic-gate 		} else {
5707c478bd9Sstevel@tonic-gate 			/* 8-bit locale */
5717c478bd9Sstevel@tonic-gate 			multi_locale = 1;
5727c478bd9Sstevel@tonic-gate 		}
5737c478bd9Sstevel@tonic-gate 
5747c478bd9Sstevel@tonic-gate 	}
5757c478bd9Sstevel@tonic-gate 	wdbdg = wdbindf;
5767c478bd9Sstevel@tonic-gate 	wddlm = wddelim;
577*e5190c10Smuffin 
578*e5190c10Smuffin 	return (0);
5797c478bd9Sstevel@tonic-gate }
5807c478bd9Sstevel@tonic-gate #endif /* EUC */
5817c478bd9Sstevel@tonic-gate #endif /* NROFF */
582