xref: /illumos-gate/usr/src/cmd/troff/n9.c (revision e6eefa9c)
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
5*e6eefa9cSas  * Common Development and Distribution License (the "License").
6*e6eefa9cSas  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*e6eefa9cSas  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
277c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate /*
307c478bd9Sstevel@tonic-gate  * University Copyright- Copyright (c) 1982, 1986, 1988
317c478bd9Sstevel@tonic-gate  * The Regents of the University of California
327c478bd9Sstevel@tonic-gate  * All Rights Reserved
337c478bd9Sstevel@tonic-gate  *
347c478bd9Sstevel@tonic-gate  * University Acknowledgment- Portions of this document are derived from
357c478bd9Sstevel@tonic-gate  * software developed by the University of California, Berkeley, and its
367c478bd9Sstevel@tonic-gate  * contributors.
377c478bd9Sstevel@tonic-gate  */
387c478bd9Sstevel@tonic-gate 
39e5190c10Smuffin #pragma ident	"%Z%%M%	%I%	%E% SMI"
40e5190c10Smuffin 
417c478bd9Sstevel@tonic-gate #include <libintl.h>
427c478bd9Sstevel@tonic-gate #include <stdlib.h>
437c478bd9Sstevel@tonic-gate 
447c478bd9Sstevel@tonic-gate #include "tdef.h"
457c478bd9Sstevel@tonic-gate #ifdef NROFF
467c478bd9Sstevel@tonic-gate #include "tw.h"
477c478bd9Sstevel@tonic-gate #endif
487c478bd9Sstevel@tonic-gate #include "ext.h"
497c478bd9Sstevel@tonic-gate #ifdef EUC
507c478bd9Sstevel@tonic-gate #include <locale.h>
517c478bd9Sstevel@tonic-gate #include <wctype.h>
527c478bd9Sstevel@tonic-gate #include <langinfo.h>
537c478bd9Sstevel@tonic-gate 
547c478bd9Sstevel@tonic-gate #define	ISO646	"646"
557c478bd9Sstevel@tonic-gate 
567c478bd9Sstevel@tonic-gate int	multi_locale;
577c478bd9Sstevel@tonic-gate int	(*wdbdg)(wchar_t, wchar_t, int);
587c478bd9Sstevel@tonic-gate wchar_t	*(*wddlm)(wchar_t, wchar_t, int);
597c478bd9Sstevel@tonic-gate 
607c478bd9Sstevel@tonic-gate int	csi_width[4] = {
617c478bd9Sstevel@tonic-gate 	1,
627c478bd9Sstevel@tonic-gate 	1,
637c478bd9Sstevel@tonic-gate 	2,
647c478bd9Sstevel@tonic-gate 	3,
657c478bd9Sstevel@tonic-gate };
667c478bd9Sstevel@tonic-gate #endif /* EUC */
677c478bd9Sstevel@tonic-gate 
687c478bd9Sstevel@tonic-gate /*
697c478bd9Sstevel@tonic-gate  * troff9.c
70*e6eefa9cSas  *
717c478bd9Sstevel@tonic-gate  * misc functions
727c478bd9Sstevel@tonic-gate  */
737c478bd9Sstevel@tonic-gate 
74*e6eefa9cSas tchar
75*e6eefa9cSas setz()
767c478bd9Sstevel@tonic-gate {
777c478bd9Sstevel@tonic-gate 	tchar i;
787c478bd9Sstevel@tonic-gate 
797c478bd9Sstevel@tonic-gate 	if (!ismot(i = getch()))
807c478bd9Sstevel@tonic-gate 		i |= ZBIT;
81*e6eefa9cSas 	return (i);
827c478bd9Sstevel@tonic-gate }
837c478bd9Sstevel@tonic-gate 
84e5190c10Smuffin int
857c478bd9Sstevel@tonic-gate setline()
867c478bd9Sstevel@tonic-gate {
87e5190c10Smuffin 	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()))
94e5190c10Smuffin 		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);
102e5190c10Smuffin 		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) {
123*e6eefa9cSas 		if (cbits(c) == RULE || cbits(c) == UNDERLINE ||
124*e6eefa9cSas 		    cbits(c) == ROOTEN)
1257c478bd9Sstevel@tonic-gate 			*i++ = c | ZBIT;
1267c478bd9Sstevel@tonic-gate 		*i++ = makem(rem);
1277c478bd9Sstevel@tonic-gate 	}
1287c478bd9Sstevel@tonic-gate 	if (cnt) {
1297c478bd9Sstevel@tonic-gate 		*i++ = RPT;
1307c478bd9Sstevel@tonic-gate 		*i++ = cnt;
1317c478bd9Sstevel@tonic-gate 		*i++ = c;
1327c478bd9Sstevel@tonic-gate 	}
1337c478bd9Sstevel@tonic-gate s1:
1347c478bd9Sstevel@tonic-gate 	*i++ = 0;
1357c478bd9Sstevel@tonic-gate 	eat(delim);
1367c478bd9Sstevel@tonic-gate 	pushback(linebuf);
137e5190c10Smuffin 
138e5190c10Smuffin 	return (0);
1397c478bd9Sstevel@tonic-gate }
1407c478bd9Sstevel@tonic-gate 
1417c478bd9Sstevel@tonic-gate 
142e5190c10Smuffin int
1437c478bd9Sstevel@tonic-gate eat(c)
144e5190c10Smuffin int	c;
1457c478bd9Sstevel@tonic-gate {
146e5190c10Smuffin 	int	i;
1477c478bd9Sstevel@tonic-gate 
148*e6eefa9cSas 	while ((i = cbits(getch())) != c && (i != '\n'))
1497c478bd9Sstevel@tonic-gate 		;
150*e6eefa9cSas 	return (i);
1517c478bd9Sstevel@tonic-gate }
1527c478bd9Sstevel@tonic-gate 
1537c478bd9Sstevel@tonic-gate 
154e5190c10Smuffin int
1557c478bd9Sstevel@tonic-gate setov()
1567c478bd9Sstevel@tonic-gate {
157e5190c10Smuffin 	int	j, k;
1587c478bd9Sstevel@tonic-gate 	tchar i, o[NOV];
1597c478bd9Sstevel@tonic-gate 	int delim, w[NOV];
1607c478bd9Sstevel@tonic-gate 
1617c478bd9Sstevel@tonic-gate 	if (ismot(i = getch()))
162e5190c10Smuffin 		return (0);
1637c478bd9Sstevel@tonic-gate 	delim = cbits(i);
164*e6eefa9cSas 	for (k = 0; (k < NOV) && ((j = cbits(i = getch())) != delim) &&
165*e6eefa9cSas 	    (j != '\n'); k++) {
1667c478bd9Sstevel@tonic-gate 		o[k] = i;
1677c478bd9Sstevel@tonic-gate 		w[k] = width(i);
1687c478bd9Sstevel@tonic-gate 	}
169*e6eefa9cSas 	if (k >= NOV) {
170*e6eefa9cSas 		k = NOV - 1;
171*e6eefa9cSas 	}
1727c478bd9Sstevel@tonic-gate 	o[k] = w[k] = 0;
1737c478bd9Sstevel@tonic-gate 	if (o[0])
1747c478bd9Sstevel@tonic-gate 		for (j = 1; j; ) {
1757c478bd9Sstevel@tonic-gate 			j = 0;
176*e6eefa9cSas 			for (k = 1; o[k]; k++) {
1777c478bd9Sstevel@tonic-gate 				if (w[k-1] < w[k]) {
1787c478bd9Sstevel@tonic-gate 					j++;
1797c478bd9Sstevel@tonic-gate 					i = w[k];
1807c478bd9Sstevel@tonic-gate 					w[k] = w[k-1];
1817c478bd9Sstevel@tonic-gate 					w[k-1] = i;
1827c478bd9Sstevel@tonic-gate 					i = o[k];
1837c478bd9Sstevel@tonic-gate 					o[k] = o[k-1];
1847c478bd9Sstevel@tonic-gate 					o[k-1] = i;
1857c478bd9Sstevel@tonic-gate 				}
1867c478bd9Sstevel@tonic-gate 			}
1877c478bd9Sstevel@tonic-gate 		}
188*e6eefa9cSas 	else
189e5190c10Smuffin 		return (0);
1907c478bd9Sstevel@tonic-gate 	*pbp++ = makem(w[0] / 2);
1917c478bd9Sstevel@tonic-gate 	for (k = 0; o[k]; k++)
1927c478bd9Sstevel@tonic-gate 		;
193*e6eefa9cSas 	while (k > 0) {
1947c478bd9Sstevel@tonic-gate 		k--;
1957c478bd9Sstevel@tonic-gate 		*pbp++ = makem(-((w[k] + w[k+1]) / 2));
1967c478bd9Sstevel@tonic-gate 		*pbp++ = o[k];
1977c478bd9Sstevel@tonic-gate 	}
198e5190c10Smuffin 
199e5190c10Smuffin 	return (0);
2007c478bd9Sstevel@tonic-gate }
2017c478bd9Sstevel@tonic-gate 
2027c478bd9Sstevel@tonic-gate 
203e5190c10Smuffin int
2047c478bd9Sstevel@tonic-gate setbra()
2057c478bd9Sstevel@tonic-gate {
206e5190c10Smuffin 	int	k;
2077c478bd9Sstevel@tonic-gate 	tchar i, *j, dwn;
2087c478bd9Sstevel@tonic-gate 	int	cnt, delim;
2097c478bd9Sstevel@tonic-gate 	tchar brabuf[NC];
2107c478bd9Sstevel@tonic-gate 
2117c478bd9Sstevel@tonic-gate 	if (ismot(i = getch()))
212e5190c10Smuffin 		return (0);
2137c478bd9Sstevel@tonic-gate 	delim = cbits(i);
2147c478bd9Sstevel@tonic-gate 	j = brabuf + 1;
2157c478bd9Sstevel@tonic-gate 	cnt = 0;
2167c478bd9Sstevel@tonic-gate #ifdef NROFF
2177c478bd9Sstevel@tonic-gate 	dwn = (2 * t.Halfline) | MOT | VMOT;
2187c478bd9Sstevel@tonic-gate #endif
2197c478bd9Sstevel@tonic-gate #ifndef NROFF
2207c478bd9Sstevel@tonic-gate 	dwn = EM | MOT | VMOT;
2217c478bd9Sstevel@tonic-gate #endif
222*e6eefa9cSas 	while (((k = cbits(i = getch())) != delim) && (k != '\n') &&
223*e6eefa9cSas 	    (j <= (brabuf + NC - 4))) {
2247c478bd9Sstevel@tonic-gate 		*j++ = i | ZBIT;
2257c478bd9Sstevel@tonic-gate 		*j++ = dwn;
2267c478bd9Sstevel@tonic-gate 		cnt++;
2277c478bd9Sstevel@tonic-gate 	}
2287c478bd9Sstevel@tonic-gate 	if (--cnt < 0)
229e5190c10Smuffin 		return (0);
2307c478bd9Sstevel@tonic-gate 	else if (!cnt) {
2317c478bd9Sstevel@tonic-gate 		ch = *(j - 2);
232e5190c10Smuffin 		return (0);
2337c478bd9Sstevel@tonic-gate 	}
2347c478bd9Sstevel@tonic-gate 	*j = 0;
2357c478bd9Sstevel@tonic-gate #ifdef NROFF
2367c478bd9Sstevel@tonic-gate 	*--j = *brabuf = (cnt * t.Halfline) | MOT | NMOT | VMOT;
2377c478bd9Sstevel@tonic-gate #endif
2387c478bd9Sstevel@tonic-gate #ifndef NROFF
2397c478bd9Sstevel@tonic-gate 	*--j = *brabuf = (cnt * EM) / 2 | MOT | NMOT | VMOT;
2407c478bd9Sstevel@tonic-gate #endif
2417c478bd9Sstevel@tonic-gate 	*--j &= ~ZBIT;
2427c478bd9Sstevel@tonic-gate 	pushback(brabuf);
243e5190c10Smuffin 
244e5190c10Smuffin 	return (0);
2457c478bd9Sstevel@tonic-gate }
2467c478bd9Sstevel@tonic-gate 
2477c478bd9Sstevel@tonic-gate 
248e5190c10Smuffin int
2497c478bd9Sstevel@tonic-gate setvline()
2507c478bd9Sstevel@tonic-gate {
251e5190c10Smuffin 	int	i;
2527c478bd9Sstevel@tonic-gate 	tchar c, rem, ver, neg;
2537c478bd9Sstevel@tonic-gate 	int	cnt, delim, v;
2547c478bd9Sstevel@tonic-gate 	tchar vlbuf[NC];
255e5190c10Smuffin 	tchar *vlp;
2567c478bd9Sstevel@tonic-gate 
2577c478bd9Sstevel@tonic-gate 	if (ismot(c = getch()))
258e5190c10Smuffin 		return (0);
2597c478bd9Sstevel@tonic-gate 	delim = cbits(c);
2607c478bd9Sstevel@tonic-gate 	dfact = lss;
2617c478bd9Sstevel@tonic-gate 	vflag++;
2627c478bd9Sstevel@tonic-gate 	i = quant(atoi(), VERT);
2637c478bd9Sstevel@tonic-gate 	dfact = 1;
2647c478bd9Sstevel@tonic-gate 	if (!i) {
2657c478bd9Sstevel@tonic-gate 		eat(delim);
2667c478bd9Sstevel@tonic-gate 		vflag = 0;
267e5190c10Smuffin 		return (0);
2687c478bd9Sstevel@tonic-gate 	}
2697c478bd9Sstevel@tonic-gate 	if ((cbits(c = getch())) == delim) {
270*e6eefa9cSas 		c = BOXRULE | chbits;	/* default box rule */
271*e6eefa9cSas 	} else
2727c478bd9Sstevel@tonic-gate 		getch();
2737c478bd9Sstevel@tonic-gate 	c |= ZBIT;
2747c478bd9Sstevel@tonic-gate 	neg = 0;
2757c478bd9Sstevel@tonic-gate 	if (i < 0) {
2767c478bd9Sstevel@tonic-gate 		i = -i;
2777c478bd9Sstevel@tonic-gate 		neg = NMOT;
2787c478bd9Sstevel@tonic-gate 	}
2797c478bd9Sstevel@tonic-gate #ifdef NROFF
2807c478bd9Sstevel@tonic-gate 	v = 2 * t.Halfline;
2817c478bd9Sstevel@tonic-gate #endif
2827c478bd9Sstevel@tonic-gate #ifndef NROFF
2837c478bd9Sstevel@tonic-gate 	v = EM;
2847c478bd9Sstevel@tonic-gate #endif
2857c478bd9Sstevel@tonic-gate 	cnt = i / v;
2867c478bd9Sstevel@tonic-gate 	rem = makem(i % v) | neg;
2877c478bd9Sstevel@tonic-gate 	ver = makem(v) | neg;
2887c478bd9Sstevel@tonic-gate 	vlp = vlbuf;
2897c478bd9Sstevel@tonic-gate 	if (!neg)
2907c478bd9Sstevel@tonic-gate 		*vlp++ = ver;
2917c478bd9Sstevel@tonic-gate 	if (absmot(rem) != 0) {
2927c478bd9Sstevel@tonic-gate 		*vlp++ = c;
2937c478bd9Sstevel@tonic-gate 		*vlp++ = rem;
2947c478bd9Sstevel@tonic-gate 	}
2957c478bd9Sstevel@tonic-gate 	while ((vlp < (vlbuf + NC - 3)) && cnt--) {
2967c478bd9Sstevel@tonic-gate 		*vlp++ = c;
2977c478bd9Sstevel@tonic-gate 		*vlp++ = ver;
2987c478bd9Sstevel@tonic-gate 	}
2997c478bd9Sstevel@tonic-gate 	*(vlp - 2) &= ~ZBIT;
3007c478bd9Sstevel@tonic-gate 	if (!neg)
3017c478bd9Sstevel@tonic-gate 		vlp--;
3027c478bd9Sstevel@tonic-gate 	*vlp++ = 0;
3037c478bd9Sstevel@tonic-gate 	pushback(vlbuf);
3047c478bd9Sstevel@tonic-gate 	vflag = 0;
305e5190c10Smuffin 
306e5190c10Smuffin 	return (0);
3077c478bd9Sstevel@tonic-gate }
3087c478bd9Sstevel@tonic-gate 
3097c478bd9Sstevel@tonic-gate #define	NPAIR	(NC/2-6)	/* max pairs in spline, etc. */
3107c478bd9Sstevel@tonic-gate 
311e5190c10Smuffin int
3127c478bd9Sstevel@tonic-gate setdraw()	/* generate internal cookies for a drawing function */
3137c478bd9Sstevel@tonic-gate {
3147c478bd9Sstevel@tonic-gate 	int i, j, k, dx[NPAIR], dy[NPAIR], delim, type;
3157c478bd9Sstevel@tonic-gate 	tchar c, drawbuf[NC];
3167c478bd9Sstevel@tonic-gate 
3177c478bd9Sstevel@tonic-gate 	/* input is \D'f dx dy dx dy ... c' (or at least it had better be) */
3187c478bd9Sstevel@tonic-gate 	/* this does drawing function f with character c and the */
3197c478bd9Sstevel@tonic-gate 	/* specified dx,dy pairs interpreted as appropriate */
3207c478bd9Sstevel@tonic-gate 	/* pairs are deltas from last point, except for radii */
3217c478bd9Sstevel@tonic-gate 
3227c478bd9Sstevel@tonic-gate 	/* l dx dy:	line from here by dx,dy */
3237c478bd9Sstevel@tonic-gate 	/* c x:		circle of diameter x, left side here */
3247c478bd9Sstevel@tonic-gate 	/* e x y:	ellipse of diameters x,y, left side here */
325*e6eefa9cSas 	/*
326*e6eefa9cSas 	 * a dx1 dy1 dx2 dy2:	ccw arc: ctr at dx1,dy1,
327*e6eefa9cSas 	 * then end at dx2,dy2 from there
328*e6eefa9cSas 	 */
329*e6eefa9cSas 	/*
330*e6eefa9cSas 	 * ~ dx1 dy1 dx2 dy2...:
331*e6eefa9cSas 	 * spline to dx1,dy1 to dx2,dy2 ...
332*e6eefa9cSas 	 */
3337c478bd9Sstevel@tonic-gate 	/* f dx dy ...:	f is any other char:  like spline */
3347c478bd9Sstevel@tonic-gate 
3357c478bd9Sstevel@tonic-gate 	if (ismot(c = getch()))
336e5190c10Smuffin 		return (0);
3377c478bd9Sstevel@tonic-gate 	delim = cbits(c);
3387c478bd9Sstevel@tonic-gate 	type = cbits(getch());
339*e6eefa9cSas 	for (i = 0; i < NPAIR; i++) {
3407c478bd9Sstevel@tonic-gate 		c = getch();
3417c478bd9Sstevel@tonic-gate 		if (cbits(c) == delim)
3427c478bd9Sstevel@tonic-gate 			break;
3437c478bd9Sstevel@tonic-gate 	/* ought to pick up optional drawing character */
3447c478bd9Sstevel@tonic-gate 		if (cbits(c) != ' ')
3457c478bd9Sstevel@tonic-gate 			ch = c;
3467c478bd9Sstevel@tonic-gate 		vflag = 0;
3477c478bd9Sstevel@tonic-gate 		dfact = EM;
3487c478bd9Sstevel@tonic-gate 		dx[i] = quant(atoi(), HOR);
3497c478bd9Sstevel@tonic-gate 		if (dx[i] > MAXMOT)
3507c478bd9Sstevel@tonic-gate 			dx[i] = MAXMOT;
3517c478bd9Sstevel@tonic-gate 		else if (dx[i] < -MAXMOT)
3527c478bd9Sstevel@tonic-gate 			dx[i] = -MAXMOT;
3537c478bd9Sstevel@tonic-gate 		if (cbits((c = getch())) == delim) {	/* spacer */
3547c478bd9Sstevel@tonic-gate 			dy[i++] = 0;
3557c478bd9Sstevel@tonic-gate 			break;
3567c478bd9Sstevel@tonic-gate 		}
3577c478bd9Sstevel@tonic-gate 		vflag = 1;
3587c478bd9Sstevel@tonic-gate 		dfact = lss;
3597c478bd9Sstevel@tonic-gate 		dy[i] = quant(atoi(), VERT);
3607c478bd9Sstevel@tonic-gate 		if (dy[i] > MAXMOT)
3617c478bd9Sstevel@tonic-gate 			dy[i] = MAXMOT;
3627c478bd9Sstevel@tonic-gate 		else if (dy[i] < -MAXMOT)
3637c478bd9Sstevel@tonic-gate 			dy[i] = -MAXMOT;
3647c478bd9Sstevel@tonic-gate 	}
3657c478bd9Sstevel@tonic-gate 	dfact = 1;
3667c478bd9Sstevel@tonic-gate 	vflag = 0;
3677c478bd9Sstevel@tonic-gate #ifndef NROFF
3687c478bd9Sstevel@tonic-gate 	drawbuf[0] = DRAWFCN | chbits | ZBIT;
3697c478bd9Sstevel@tonic-gate 	drawbuf[1] = type | chbits | ZBIT;
370*e6eefa9cSas 	drawbuf[2] = '.' | chbits | ZBIT; /* use default drawing character */
3717c478bd9Sstevel@tonic-gate 	for (k = 0, j = 3; k < i; k++) {
3727c478bd9Sstevel@tonic-gate 		drawbuf[j++] = MOT | ((dx[k] >= 0) ? dx[k] : (NMOT | -dx[k]));
373*e6eefa9cSas 		drawbuf[j++] = MOT | VMOT | ((dy[k] >= 0) ?
374*e6eefa9cSas 		    dy[k] : (NMOT | -dy[k]));
3757c478bd9Sstevel@tonic-gate 	}
3767c478bd9Sstevel@tonic-gate 	if (type == DRAWELLIPSE) {
377*e6eefa9cSas 		/* so the net vertical is zero */
378*e6eefa9cSas 		drawbuf[5] = drawbuf[4] | NMOT;
3797c478bd9Sstevel@tonic-gate 		j = 6;
3807c478bd9Sstevel@tonic-gate 	}
3817c478bd9Sstevel@tonic-gate 	drawbuf[j++] = DRAWFCN | chbits | ZBIT;	/* marks end for ptout */
3827c478bd9Sstevel@tonic-gate 	drawbuf[j] = 0;
3837c478bd9Sstevel@tonic-gate 	pushback(drawbuf);
3847c478bd9Sstevel@tonic-gate #endif
385e5190c10Smuffin 	return (0);
3867c478bd9Sstevel@tonic-gate }
3877c478bd9Sstevel@tonic-gate 
3887c478bd9Sstevel@tonic-gate 
389e5190c10Smuffin int
3907c478bd9Sstevel@tonic-gate casefc()
3917c478bd9Sstevel@tonic-gate {
392e5190c10Smuffin 	int	i;
3937c478bd9Sstevel@tonic-gate 	tchar j;
3947c478bd9Sstevel@tonic-gate 
3957c478bd9Sstevel@tonic-gate 	gchtab[fc] &= ~FCBIT;
3967c478bd9Sstevel@tonic-gate 	fc = IMP;
3977c478bd9Sstevel@tonic-gate 	padc = ' ';
3987c478bd9Sstevel@tonic-gate 	if (skip() || ismot(j = getch()) || (i = cbits(j)) == '\n')
399e5190c10Smuffin 		return (0);
4007c478bd9Sstevel@tonic-gate 	fc = i;
4017c478bd9Sstevel@tonic-gate 	gchtab[fc] |= FCBIT;
4027c478bd9Sstevel@tonic-gate 	if (skip() || ismot(ch) || (ch = cbits(ch)) == fc)
403e5190c10Smuffin 		return (0);
4047c478bd9Sstevel@tonic-gate 	padc = ch;
405e5190c10Smuffin 
406e5190c10Smuffin 	return (0);
4077c478bd9Sstevel@tonic-gate }
4087c478bd9Sstevel@tonic-gate 
4097c478bd9Sstevel@tonic-gate 
4107c478bd9Sstevel@tonic-gate tchar
4117c478bd9Sstevel@tonic-gate setfield(x)
4127c478bd9Sstevel@tonic-gate int	x;
4137c478bd9Sstevel@tonic-gate {
414e5190c10Smuffin 	tchar ii, jj, *fp;
415e5190c10Smuffin 	int	i, j;
4167c478bd9Sstevel@tonic-gate 	int length, ws, npad, temp, type;
4177c478bd9Sstevel@tonic-gate 	tchar **pp, *padptr[NPP];
4187c478bd9Sstevel@tonic-gate 	tchar fbuf[FBUFSZ];
4197c478bd9Sstevel@tonic-gate 	int savfc, savtc, savlc;
4207c478bd9Sstevel@tonic-gate 	tchar rchar;
4217c478bd9Sstevel@tonic-gate 	int savepos;
4227c478bd9Sstevel@tonic-gate 
423*e6eefa9cSas 	if (x == tabch)
4247c478bd9Sstevel@tonic-gate 		rchar = tabc | chbits;
425*e6eefa9cSas 	else if (x ==  ldrch)
4267c478bd9Sstevel@tonic-gate 		rchar = dotc | chbits;
4277c478bd9Sstevel@tonic-gate 	temp = npad = ws = 0;
4287c478bd9Sstevel@tonic-gate 	savfc = fc;
4297c478bd9Sstevel@tonic-gate 	savtc = tabch;
4307c478bd9Sstevel@tonic-gate 	savlc = ldrch;
4317c478bd9Sstevel@tonic-gate 	tabch = ldrch = fc = IMP;
4327c478bd9Sstevel@tonic-gate 	savepos = numtab[HP].val;
4337c478bd9Sstevel@tonic-gate 	gchtab[tabch] &= ~TABBIT;
4347c478bd9Sstevel@tonic-gate 	gchtab[ldrch] &= ~LDRBIT;
4357c478bd9Sstevel@tonic-gate 	gchtab[fc] &= ~FCBIT;
4367c478bd9Sstevel@tonic-gate 	gchtab[IMP] |= TABBIT|LDRBIT|FCBIT;
4377c478bd9Sstevel@tonic-gate 	for (j = 0; ; j++) {
4387c478bd9Sstevel@tonic-gate 		if ((tabtab[j] & TABMASK) == 0) {
4397c478bd9Sstevel@tonic-gate 			if (x == savfc)
4407c478bd9Sstevel@tonic-gate 				errprint(gettext("zero field width."));
4417c478bd9Sstevel@tonic-gate 			jj = 0;
4427c478bd9Sstevel@tonic-gate 			goto rtn;
4437c478bd9Sstevel@tonic-gate 		}
444*e6eefa9cSas 		if ((length = ((tabtab[j] & TABMASK) - numtab[HP].val)) > 0)
4457c478bd9Sstevel@tonic-gate 			break;
4467c478bd9Sstevel@tonic-gate 	}
4477c478bd9Sstevel@tonic-gate 	type = tabtab[j] & (~TABMASK);
4487c478bd9Sstevel@tonic-gate 	fp = fbuf;
4497c478bd9Sstevel@tonic-gate 	pp = padptr;
4507c478bd9Sstevel@tonic-gate 	if (x == savfc) {
4517c478bd9Sstevel@tonic-gate 		while (1) {
4527c478bd9Sstevel@tonic-gate 			j = cbits(ii = getch());
4537c478bd9Sstevel@tonic-gate 			jj = width(ii);
4547c478bd9Sstevel@tonic-gate 			widthp = jj;
4557c478bd9Sstevel@tonic-gate 			numtab[HP].val += jj;
4567c478bd9Sstevel@tonic-gate 			if (j == padc) {
4577c478bd9Sstevel@tonic-gate 				npad++;
4587c478bd9Sstevel@tonic-gate 				*pp++ = fp;
4597c478bd9Sstevel@tonic-gate 				if (pp > (padptr + NPP - 1))
4607c478bd9Sstevel@tonic-gate 					break;
4617c478bd9Sstevel@tonic-gate 				goto s1;
462*e6eefa9cSas 			} else if (j == savfc)
4637c478bd9Sstevel@tonic-gate 				break;
4647c478bd9Sstevel@tonic-gate 			else if (j == '\n') {
4657c478bd9Sstevel@tonic-gate 				temp = j;
4667c478bd9Sstevel@tonic-gate 				nlflg = 0;
4677c478bd9Sstevel@tonic-gate 				break;
4687c478bd9Sstevel@tonic-gate 			}
4697c478bd9Sstevel@tonic-gate 			ws += jj;
4707c478bd9Sstevel@tonic-gate s1:
4717c478bd9Sstevel@tonic-gate 			*fp++ = ii;
4727c478bd9Sstevel@tonic-gate 			if (fp > (fbuf + FBUFSZ - 3))
4737c478bd9Sstevel@tonic-gate 				break;
4747c478bd9Sstevel@tonic-gate 		}
4757c478bd9Sstevel@tonic-gate 		if (!npad) {
4767c478bd9Sstevel@tonic-gate 			npad++;
4777c478bd9Sstevel@tonic-gate 			*pp++ = fp;
4787c478bd9Sstevel@tonic-gate 			*fp++ = 0;
4797c478bd9Sstevel@tonic-gate 		}
4807c478bd9Sstevel@tonic-gate 		*fp++ = temp;
4817c478bd9Sstevel@tonic-gate 		*fp++ = 0;
4827c478bd9Sstevel@tonic-gate 		temp = i = (j = length - ws) / npad;
4837c478bd9Sstevel@tonic-gate 		i = (i / HOR) * HOR;
4847c478bd9Sstevel@tonic-gate 		if ((j -= i * npad) < 0)
4857c478bd9Sstevel@tonic-gate 			j = -j;
4867c478bd9Sstevel@tonic-gate 		ii = makem(i);
4877c478bd9Sstevel@tonic-gate 		if (temp < 0)
4887c478bd9Sstevel@tonic-gate 			ii |= NMOT;
4897c478bd9Sstevel@tonic-gate 		for (; npad > 0; npad--) {
4907c478bd9Sstevel@tonic-gate 			*(*--pp) = ii;
4917c478bd9Sstevel@tonic-gate 			if (j) {
4927c478bd9Sstevel@tonic-gate 				j -= HOR;
4937c478bd9Sstevel@tonic-gate 				(*(*pp)) += HOR;
4947c478bd9Sstevel@tonic-gate 			}
4957c478bd9Sstevel@tonic-gate 		}
4967c478bd9Sstevel@tonic-gate 		pushback(fbuf);
4977c478bd9Sstevel@tonic-gate 		jj = 0;
4987c478bd9Sstevel@tonic-gate 	} else if (type == 0) {
499*e6eefa9cSas 		/* plain tab or leader */
5007c478bd9Sstevel@tonic-gate 		if ((j = width(rchar)) > 0) {
5017c478bd9Sstevel@tonic-gate 			int nchar = length / j;
5027c478bd9Sstevel@tonic-gate 			while (nchar-->0 && pbp < &pbbuf[NC-3]) {
5037c478bd9Sstevel@tonic-gate 				numtab[HP].val += j;
5047c478bd9Sstevel@tonic-gate 				widthp = j;
5057c478bd9Sstevel@tonic-gate 				*pbp++ = rchar;
5067c478bd9Sstevel@tonic-gate 			}
5077c478bd9Sstevel@tonic-gate 			length %= j;
5087c478bd9Sstevel@tonic-gate 		}
5097c478bd9Sstevel@tonic-gate 		if (length)
5107c478bd9Sstevel@tonic-gate 			jj = length | MOT;
511*e6eefa9cSas 		else
5127c478bd9Sstevel@tonic-gate 			jj = getch0();
5137c478bd9Sstevel@tonic-gate 	} else {
514*e6eefa9cSas 		/* center tab */
515*e6eefa9cSas 		/* right tab */
516*e6eefa9cSas 		while (((j = cbits(ii = getch())) != savtc) &&
517*e6eefa9cSas 		    (j != '\n') && (j != savlc)) {
5187c478bd9Sstevel@tonic-gate 			jj = width(ii);
5197c478bd9Sstevel@tonic-gate 			ws += jj;
5207c478bd9Sstevel@tonic-gate 			numtab[HP].val += jj;
5217c478bd9Sstevel@tonic-gate 			widthp = jj;
5227c478bd9Sstevel@tonic-gate 			*fp++ = ii;
523*e6eefa9cSas 			if (fp > (fbuf + FBUFSZ - 3))
5247c478bd9Sstevel@tonic-gate 				break;
5257c478bd9Sstevel@tonic-gate 		}
5267c478bd9Sstevel@tonic-gate 		*fp++ = ii;
5277c478bd9Sstevel@tonic-gate 		*fp++ = 0;
5287c478bd9Sstevel@tonic-gate 		if (type == RTAB)
5297c478bd9Sstevel@tonic-gate 			length -= ws;
530*e6eefa9cSas 		else
531*e6eefa9cSas 			length -= ws / 2; /* CTAB */
5327c478bd9Sstevel@tonic-gate 		pushback(fbuf);
5337c478bd9Sstevel@tonic-gate 		if ((j = width(rchar)) != 0 && length > 0) {
5347c478bd9Sstevel@tonic-gate 			int nchar = length / j;
5357c478bd9Sstevel@tonic-gate 			while (nchar-- > 0 && pbp < &pbbuf[NC-3])
5367c478bd9Sstevel@tonic-gate 				*pbp++ = rchar;
5377c478bd9Sstevel@tonic-gate 			length %= j;
5387c478bd9Sstevel@tonic-gate 		}
5397c478bd9Sstevel@tonic-gate 		length = (length / HOR) * HOR;
5407c478bd9Sstevel@tonic-gate 		jj = makem(length);
5417c478bd9Sstevel@tonic-gate 		nlflg = 0;
5427c478bd9Sstevel@tonic-gate 	}
5437c478bd9Sstevel@tonic-gate rtn:
5447c478bd9Sstevel@tonic-gate 	gchtab[fc] &= ~FCBIT;
5457c478bd9Sstevel@tonic-gate 	gchtab[tabch] &= ~TABBIT;
5467c478bd9Sstevel@tonic-gate 	gchtab[ldrch] &= ~LDRBIT;
5477c478bd9Sstevel@tonic-gate 	fc = savfc;
5487c478bd9Sstevel@tonic-gate 	tabch = savtc;
5497c478bd9Sstevel@tonic-gate 	ldrch = savlc;
5507c478bd9Sstevel@tonic-gate 	gchtab[fc] |= FCBIT;
5517c478bd9Sstevel@tonic-gate 	gchtab[tabch] = TABBIT;
5527c478bd9Sstevel@tonic-gate 	gchtab[ldrch] |= LDRBIT;
5537c478bd9Sstevel@tonic-gate 	numtab[HP].val = savepos;
554*e6eefa9cSas 	return (jj);
5557c478bd9Sstevel@tonic-gate }
5567c478bd9Sstevel@tonic-gate 
5577c478bd9Sstevel@tonic-gate 
5587c478bd9Sstevel@tonic-gate #ifdef EUC
5597c478bd9Sstevel@tonic-gate #ifdef NROFF
5607c478bd9Sstevel@tonic-gate /* locale specific initialization */
561*e6eefa9cSas int
562*e6eefa9cSas localize()
5637c478bd9Sstevel@tonic-gate {
5647c478bd9Sstevel@tonic-gate 	extern int	wdbindf();
5657c478bd9Sstevel@tonic-gate 	extern wchar_t	*wddelim();
5667c478bd9Sstevel@tonic-gate 	char	*codeset;
5677c478bd9Sstevel@tonic-gate 
5687c478bd9Sstevel@tonic-gate 	codeset = nl_langinfo(CODESET);
5697c478bd9Sstevel@tonic-gate 
5707c478bd9Sstevel@tonic-gate 	if (MB_CUR_MAX > 1)
5717c478bd9Sstevel@tonic-gate 		multi_locale = 1;
5727c478bd9Sstevel@tonic-gate 	else {
5737c478bd9Sstevel@tonic-gate 		if (*codeset == '\0' ||
5747c478bd9Sstevel@tonic-gate 			(strcmp(codeset, ISO646) == 0)) {
5757c478bd9Sstevel@tonic-gate 			/*
5767c478bd9Sstevel@tonic-gate 			 * if codeset is an empty string
5777c478bd9Sstevel@tonic-gate 			 * assumes this is C locale (7-bit) locale.
5787c478bd9Sstevel@tonic-gate 			 * This happens in 2.5, 2.5.1, and 2.6 system
5797c478bd9Sstevel@tonic-gate 			 * Or, if codeset is "646"
5807c478bd9Sstevel@tonic-gate 			 * this is 7-bit locale.
5817c478bd9Sstevel@tonic-gate 			 */
5827c478bd9Sstevel@tonic-gate 			multi_locale = 0;
5837c478bd9Sstevel@tonic-gate 		} else {
5847c478bd9Sstevel@tonic-gate 			/* 8-bit locale */
5857c478bd9Sstevel@tonic-gate 			multi_locale = 1;
5867c478bd9Sstevel@tonic-gate 		}
5877c478bd9Sstevel@tonic-gate 
5887c478bd9Sstevel@tonic-gate 	}
5897c478bd9Sstevel@tonic-gate 	wdbdg = wdbindf;
5907c478bd9Sstevel@tonic-gate 	wddlm = wddelim;
591e5190c10Smuffin 
592e5190c10Smuffin 	return (0);
5937c478bd9Sstevel@tonic-gate }
5947c478bd9Sstevel@tonic-gate #endif /* EUC */
5957c478bd9Sstevel@tonic-gate #endif /* NROFF */
596