xref: /illumos-gate/usr/src/cmd/troff/n9.c (revision c5fe87b8)
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
5e6eefa9cSas  * Common Development and Distribution License (the "License").
6e6eefa9cSas  * 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 /*
22e6eefa9cSas  * 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 
397c478bd9Sstevel@tonic-gate #include <libintl.h>
407c478bd9Sstevel@tonic-gate #include <stdlib.h>
417c478bd9Sstevel@tonic-gate 
427c478bd9Sstevel@tonic-gate #include "tdef.h"
437c478bd9Sstevel@tonic-gate #ifdef NROFF
447c478bd9Sstevel@tonic-gate #include "tw.h"
457c478bd9Sstevel@tonic-gate #endif
467c478bd9Sstevel@tonic-gate #include "ext.h"
477c478bd9Sstevel@tonic-gate #ifdef EUC
487c478bd9Sstevel@tonic-gate #include <locale.h>
497c478bd9Sstevel@tonic-gate #include <wctype.h>
507c478bd9Sstevel@tonic-gate #include <langinfo.h>
517c478bd9Sstevel@tonic-gate 
527c478bd9Sstevel@tonic-gate #define	ISO646	"646"
537c478bd9Sstevel@tonic-gate 
547c478bd9Sstevel@tonic-gate int	multi_locale;
557c478bd9Sstevel@tonic-gate int	(*wdbdg)(wchar_t, wchar_t, int);
567c478bd9Sstevel@tonic-gate wchar_t	*(*wddlm)(wchar_t, wchar_t, int);
577c478bd9Sstevel@tonic-gate 
587c478bd9Sstevel@tonic-gate int	csi_width[4] = {
597c478bd9Sstevel@tonic-gate 	1,
607c478bd9Sstevel@tonic-gate 	1,
617c478bd9Sstevel@tonic-gate 	2,
627c478bd9Sstevel@tonic-gate 	3,
637c478bd9Sstevel@tonic-gate };
647c478bd9Sstevel@tonic-gate #endif /* EUC */
657c478bd9Sstevel@tonic-gate 
667c478bd9Sstevel@tonic-gate /*
677c478bd9Sstevel@tonic-gate  * troff9.c
68e6eefa9cSas  *
697c478bd9Sstevel@tonic-gate  * misc functions
707c478bd9Sstevel@tonic-gate  */
717c478bd9Sstevel@tonic-gate 
72e6eefa9cSas tchar
setz(void)73*c5fe87b8SToomas Soome setz(void)
747c478bd9Sstevel@tonic-gate {
757c478bd9Sstevel@tonic-gate 	tchar i;
767c478bd9Sstevel@tonic-gate 
777c478bd9Sstevel@tonic-gate 	if (!ismot(i = getch()))
787c478bd9Sstevel@tonic-gate 		i |= ZBIT;
79e6eefa9cSas 	return (i);
807c478bd9Sstevel@tonic-gate }
817c478bd9Sstevel@tonic-gate 
82e5190c10Smuffin int
setline(void)83*c5fe87b8SToomas Soome setline(void)
847c478bd9Sstevel@tonic-gate {
85e5190c10Smuffin 	tchar *i;
867c478bd9Sstevel@tonic-gate 	tchar c;
877c478bd9Sstevel@tonic-gate 	int	length;
887c478bd9Sstevel@tonic-gate 	int	w, cnt, delim, rem, temp;
897c478bd9Sstevel@tonic-gate 	tchar linebuf[NC];
907c478bd9Sstevel@tonic-gate 
917c478bd9Sstevel@tonic-gate 	if (ismot(c = getch()))
92e5190c10Smuffin 		return (0);
937c478bd9Sstevel@tonic-gate 	delim = cbits(c);
947c478bd9Sstevel@tonic-gate 	vflag = 0;
957c478bd9Sstevel@tonic-gate 	dfact = EM;
967c478bd9Sstevel@tonic-gate 	length = quant(atoi(), HOR);
977c478bd9Sstevel@tonic-gate 	dfact = 1;
987c478bd9Sstevel@tonic-gate 	if (!length) {
997c478bd9Sstevel@tonic-gate 		eat(delim);
100e5190c10Smuffin 		return (0);
1017c478bd9Sstevel@tonic-gate 	}
1027c478bd9Sstevel@tonic-gate s0:
1037c478bd9Sstevel@tonic-gate 	if ((cbits(c = getch())) == delim) {
1047c478bd9Sstevel@tonic-gate 		ch = c;
1057c478bd9Sstevel@tonic-gate 		c = RULE | chbits;
1067c478bd9Sstevel@tonic-gate 	} else if (cbits(c) == FILLER)
1077c478bd9Sstevel@tonic-gate 		goto s0;
1087c478bd9Sstevel@tonic-gate 	w = width(c);
1097c478bd9Sstevel@tonic-gate 	i = linebuf;
1107c478bd9Sstevel@tonic-gate 	if (length < 0) {
1117c478bd9Sstevel@tonic-gate 		*i++ = makem(length);
1127c478bd9Sstevel@tonic-gate 		length = -length;
1137c478bd9Sstevel@tonic-gate 	}
1147c478bd9Sstevel@tonic-gate 	if (!(cnt = length / w)) {
1157c478bd9Sstevel@tonic-gate 		*i++ = makem(-(temp = ((w - length) / 2)));
1167c478bd9Sstevel@tonic-gate 		*i++ = c;
1177c478bd9Sstevel@tonic-gate 		*i++ = makem(-(w - length - temp));
1187c478bd9Sstevel@tonic-gate 		goto s1;
1197c478bd9Sstevel@tonic-gate 	}
1207c478bd9Sstevel@tonic-gate 	if (rem = length % w) {
121e6eefa9cSas 		if (cbits(c) == RULE || cbits(c) == UNDERLINE ||
122e6eefa9cSas 		    cbits(c) == ROOTEN)
1237c478bd9Sstevel@tonic-gate 			*i++ = c | ZBIT;
1247c478bd9Sstevel@tonic-gate 		*i++ = makem(rem);
1257c478bd9Sstevel@tonic-gate 	}
1267c478bd9Sstevel@tonic-gate 	if (cnt) {
1277c478bd9Sstevel@tonic-gate 		*i++ = RPT;
1287c478bd9Sstevel@tonic-gate 		*i++ = cnt;
1297c478bd9Sstevel@tonic-gate 		*i++ = c;
1307c478bd9Sstevel@tonic-gate 	}
1317c478bd9Sstevel@tonic-gate s1:
1327c478bd9Sstevel@tonic-gate 	*i++ = 0;
1337c478bd9Sstevel@tonic-gate 	eat(delim);
1347c478bd9Sstevel@tonic-gate 	pushback(linebuf);
135e5190c10Smuffin 
136e5190c10Smuffin 	return (0);
1377c478bd9Sstevel@tonic-gate }
1387c478bd9Sstevel@tonic-gate 
1397c478bd9Sstevel@tonic-gate 
140e5190c10Smuffin int
eat(int c)141*c5fe87b8SToomas Soome eat(int c)
1427c478bd9Sstevel@tonic-gate {
143e5190c10Smuffin 	int	i;
1447c478bd9Sstevel@tonic-gate 
145e6eefa9cSas 	while ((i = cbits(getch())) != c && (i != '\n'))
1467c478bd9Sstevel@tonic-gate 		;
147e6eefa9cSas 	return (i);
1487c478bd9Sstevel@tonic-gate }
1497c478bd9Sstevel@tonic-gate 
1507c478bd9Sstevel@tonic-gate 
151e5190c10Smuffin int
setov(void)152*c5fe87b8SToomas Soome setov(void)
1537c478bd9Sstevel@tonic-gate {
154e5190c10Smuffin 	int	j, k;
1557c478bd9Sstevel@tonic-gate 	tchar i, o[NOV];
1567c478bd9Sstevel@tonic-gate 	int delim, w[NOV];
1577c478bd9Sstevel@tonic-gate 
1587c478bd9Sstevel@tonic-gate 	if (ismot(i = getch()))
159e5190c10Smuffin 		return (0);
1607c478bd9Sstevel@tonic-gate 	delim = cbits(i);
161e6eefa9cSas 	for (k = 0; (k < NOV) && ((j = cbits(i = getch())) != delim) &&
162e6eefa9cSas 	    (j != '\n'); k++) {
1637c478bd9Sstevel@tonic-gate 		o[k] = i;
1647c478bd9Sstevel@tonic-gate 		w[k] = width(i);
1657c478bd9Sstevel@tonic-gate 	}
166e6eefa9cSas 	if (k >= NOV) {
167e6eefa9cSas 		k = NOV - 1;
168e6eefa9cSas 	}
1697c478bd9Sstevel@tonic-gate 	o[k] = w[k] = 0;
1707c478bd9Sstevel@tonic-gate 	if (o[0])
1717c478bd9Sstevel@tonic-gate 		for (j = 1; j; ) {
1727c478bd9Sstevel@tonic-gate 			j = 0;
173e6eefa9cSas 			for (k = 1; o[k]; k++) {
1747c478bd9Sstevel@tonic-gate 				if (w[k-1] < w[k]) {
1757c478bd9Sstevel@tonic-gate 					j++;
1767c478bd9Sstevel@tonic-gate 					i = w[k];
1777c478bd9Sstevel@tonic-gate 					w[k] = w[k-1];
1787c478bd9Sstevel@tonic-gate 					w[k-1] = i;
1797c478bd9Sstevel@tonic-gate 					i = o[k];
1807c478bd9Sstevel@tonic-gate 					o[k] = o[k-1];
1817c478bd9Sstevel@tonic-gate 					o[k-1] = i;
1827c478bd9Sstevel@tonic-gate 				}
1837c478bd9Sstevel@tonic-gate 			}
1847c478bd9Sstevel@tonic-gate 		}
185e6eefa9cSas 	else
186e5190c10Smuffin 		return (0);
1877c478bd9Sstevel@tonic-gate 	*pbp++ = makem(w[0] / 2);
1887c478bd9Sstevel@tonic-gate 	for (k = 0; o[k]; k++)
1897c478bd9Sstevel@tonic-gate 		;
190e6eefa9cSas 	while (k > 0) {
1917c478bd9Sstevel@tonic-gate 		k--;
1927c478bd9Sstevel@tonic-gate 		*pbp++ = makem(-((w[k] + w[k+1]) / 2));
1937c478bd9Sstevel@tonic-gate 		*pbp++ = o[k];
1947c478bd9Sstevel@tonic-gate 	}
195e5190c10Smuffin 
196e5190c10Smuffin 	return (0);
1977c478bd9Sstevel@tonic-gate }
1987c478bd9Sstevel@tonic-gate 
1997c478bd9Sstevel@tonic-gate 
200e5190c10Smuffin int
setbra(void)201*c5fe87b8SToomas Soome setbra(void)
2027c478bd9Sstevel@tonic-gate {
203e5190c10Smuffin 	int	k;
2047c478bd9Sstevel@tonic-gate 	tchar i, *j, dwn;
2057c478bd9Sstevel@tonic-gate 	int	cnt, delim;
2067c478bd9Sstevel@tonic-gate 	tchar brabuf[NC];
2077c478bd9Sstevel@tonic-gate 
2087c478bd9Sstevel@tonic-gate 	if (ismot(i = getch()))
209e5190c10Smuffin 		return (0);
2107c478bd9Sstevel@tonic-gate 	delim = cbits(i);
2117c478bd9Sstevel@tonic-gate 	j = brabuf + 1;
2127c478bd9Sstevel@tonic-gate 	cnt = 0;
2137c478bd9Sstevel@tonic-gate #ifdef NROFF
2147c478bd9Sstevel@tonic-gate 	dwn = (2 * t.Halfline) | MOT | VMOT;
2157c478bd9Sstevel@tonic-gate #endif
2167c478bd9Sstevel@tonic-gate #ifndef NROFF
2177c478bd9Sstevel@tonic-gate 	dwn = EM | MOT | VMOT;
2187c478bd9Sstevel@tonic-gate #endif
219e6eefa9cSas 	while (((k = cbits(i = getch())) != delim) && (k != '\n') &&
220e6eefa9cSas 	    (j <= (brabuf + NC - 4))) {
2217c478bd9Sstevel@tonic-gate 		*j++ = i | ZBIT;
2227c478bd9Sstevel@tonic-gate 		*j++ = dwn;
2237c478bd9Sstevel@tonic-gate 		cnt++;
2247c478bd9Sstevel@tonic-gate 	}
2257c478bd9Sstevel@tonic-gate 	if (--cnt < 0)
226e5190c10Smuffin 		return (0);
2277c478bd9Sstevel@tonic-gate 	else if (!cnt) {
2287c478bd9Sstevel@tonic-gate 		ch = *(j - 2);
229e5190c10Smuffin 		return (0);
2307c478bd9Sstevel@tonic-gate 	}
2317c478bd9Sstevel@tonic-gate 	*j = 0;
2327c478bd9Sstevel@tonic-gate #ifdef NROFF
2337c478bd9Sstevel@tonic-gate 	*--j = *brabuf = (cnt * t.Halfline) | MOT | NMOT | VMOT;
2347c478bd9Sstevel@tonic-gate #endif
2357c478bd9Sstevel@tonic-gate #ifndef NROFF
2367c478bd9Sstevel@tonic-gate 	*--j = *brabuf = (cnt * EM) / 2 | MOT | NMOT | VMOT;
2377c478bd9Sstevel@tonic-gate #endif
2387c478bd9Sstevel@tonic-gate 	*--j &= ~ZBIT;
2397c478bd9Sstevel@tonic-gate 	pushback(brabuf);
240e5190c10Smuffin 
241e5190c10Smuffin 	return (0);
2427c478bd9Sstevel@tonic-gate }
2437c478bd9Sstevel@tonic-gate 
2447c478bd9Sstevel@tonic-gate 
245e5190c10Smuffin int
setvline(void)246*c5fe87b8SToomas Soome setvline(void)
2477c478bd9Sstevel@tonic-gate {
248e5190c10Smuffin 	int	i;
2497c478bd9Sstevel@tonic-gate 	tchar c, rem, ver, neg;
2507c478bd9Sstevel@tonic-gate 	int	cnt, delim, v;
2517c478bd9Sstevel@tonic-gate 	tchar vlbuf[NC];
252e5190c10Smuffin 	tchar *vlp;
2537c478bd9Sstevel@tonic-gate 
2547c478bd9Sstevel@tonic-gate 	if (ismot(c = getch()))
255e5190c10Smuffin 		return (0);
2567c478bd9Sstevel@tonic-gate 	delim = cbits(c);
2577c478bd9Sstevel@tonic-gate 	dfact = lss;
2587c478bd9Sstevel@tonic-gate 	vflag++;
2597c478bd9Sstevel@tonic-gate 	i = quant(atoi(), VERT);
2607c478bd9Sstevel@tonic-gate 	dfact = 1;
2617c478bd9Sstevel@tonic-gate 	if (!i) {
2627c478bd9Sstevel@tonic-gate 		eat(delim);
2637c478bd9Sstevel@tonic-gate 		vflag = 0;
264e5190c10Smuffin 		return (0);
2657c478bd9Sstevel@tonic-gate 	}
2667c478bd9Sstevel@tonic-gate 	if ((cbits(c = getch())) == delim) {
267e6eefa9cSas 		c = BOXRULE | chbits;	/* default box rule */
268e6eefa9cSas 	} else
2697c478bd9Sstevel@tonic-gate 		getch();
2707c478bd9Sstevel@tonic-gate 	c |= ZBIT;
2717c478bd9Sstevel@tonic-gate 	neg = 0;
2727c478bd9Sstevel@tonic-gate 	if (i < 0) {
2737c478bd9Sstevel@tonic-gate 		i = -i;
2747c478bd9Sstevel@tonic-gate 		neg = NMOT;
2757c478bd9Sstevel@tonic-gate 	}
2767c478bd9Sstevel@tonic-gate #ifdef NROFF
2777c478bd9Sstevel@tonic-gate 	v = 2 * t.Halfline;
2787c478bd9Sstevel@tonic-gate #endif
2797c478bd9Sstevel@tonic-gate #ifndef NROFF
2807c478bd9Sstevel@tonic-gate 	v = EM;
2817c478bd9Sstevel@tonic-gate #endif
2827c478bd9Sstevel@tonic-gate 	cnt = i / v;
2837c478bd9Sstevel@tonic-gate 	rem = makem(i % v) | neg;
2847c478bd9Sstevel@tonic-gate 	ver = makem(v) | neg;
2857c478bd9Sstevel@tonic-gate 	vlp = vlbuf;
2867c478bd9Sstevel@tonic-gate 	if (!neg)
2877c478bd9Sstevel@tonic-gate 		*vlp++ = ver;
2887c478bd9Sstevel@tonic-gate 	if (absmot(rem) != 0) {
2897c478bd9Sstevel@tonic-gate 		*vlp++ = c;
2907c478bd9Sstevel@tonic-gate 		*vlp++ = rem;
2917c478bd9Sstevel@tonic-gate 	}
2927c478bd9Sstevel@tonic-gate 	while ((vlp < (vlbuf + NC - 3)) && cnt--) {
2937c478bd9Sstevel@tonic-gate 		*vlp++ = c;
2947c478bd9Sstevel@tonic-gate 		*vlp++ = ver;
2957c478bd9Sstevel@tonic-gate 	}
2967c478bd9Sstevel@tonic-gate 	*(vlp - 2) &= ~ZBIT;
2977c478bd9Sstevel@tonic-gate 	if (!neg)
2987c478bd9Sstevel@tonic-gate 		vlp--;
2997c478bd9Sstevel@tonic-gate 	*vlp++ = 0;
3007c478bd9Sstevel@tonic-gate 	pushback(vlbuf);
3017c478bd9Sstevel@tonic-gate 	vflag = 0;
302e5190c10Smuffin 
303e5190c10Smuffin 	return (0);
3047c478bd9Sstevel@tonic-gate }
3057c478bd9Sstevel@tonic-gate 
3067c478bd9Sstevel@tonic-gate #define	NPAIR	(NC/2-6)	/* max pairs in spline, etc. */
3077c478bd9Sstevel@tonic-gate 
308*c5fe87b8SToomas Soome /*
309*c5fe87b8SToomas Soome  * Generate internal cookies for a drawing function.
310*c5fe87b8SToomas Soome  */
311e5190c10Smuffin int
setdraw(void)312*c5fe87b8SToomas Soome setdraw(void)
3137c478bd9Sstevel@tonic-gate {
314*c5fe87b8SToomas Soome 	int i, j, k, dx[NPAIR], dy[NPAIR], delim, type __unused;
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 */
325e6eefa9cSas 	/*
326e6eefa9cSas 	 * a dx1 dy1 dx2 dy2:	ccw arc: ctr at dx1,dy1,
327e6eefa9cSas 	 * then end at dx2,dy2 from there
328e6eefa9cSas 	 */
329e6eefa9cSas 	/*
330e6eefa9cSas 	 * ~ dx1 dy1 dx2 dy2...:
331e6eefa9cSas 	 * spline to dx1,dy1 to dx2,dy2 ...
332e6eefa9cSas 	 */
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());
339e6eefa9cSas 	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;
370e6eefa9cSas 	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]));
373e6eefa9cSas 		drawbuf[j++] = MOT | VMOT | ((dy[k] >= 0) ?
374e6eefa9cSas 		    dy[k] : (NMOT | -dy[k]));
3757c478bd9Sstevel@tonic-gate 	}
3767c478bd9Sstevel@tonic-gate 	if (type == DRAWELLIPSE) {
377e6eefa9cSas 		/* so the net vertical is zero */
378e6eefa9cSas 		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
casefc(void)390*c5fe87b8SToomas Soome casefc(void)
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
setfield(int x)411*c5fe87b8SToomas Soome setfield(int x)
4127c478bd9Sstevel@tonic-gate {
413e5190c10Smuffin 	tchar ii, jj, *fp;
414e5190c10Smuffin 	int	i, j;
4157c478bd9Sstevel@tonic-gate 	int length, ws, npad, temp, type;
4167c478bd9Sstevel@tonic-gate 	tchar **pp, *padptr[NPP];
4177c478bd9Sstevel@tonic-gate 	tchar fbuf[FBUFSZ];
4187c478bd9Sstevel@tonic-gate 	int savfc, savtc, savlc;
4197c478bd9Sstevel@tonic-gate 	tchar rchar;
4207c478bd9Sstevel@tonic-gate 	int savepos;
4217c478bd9Sstevel@tonic-gate 
422e6eefa9cSas 	if (x == tabch)
4237c478bd9Sstevel@tonic-gate 		rchar = tabc | chbits;
424e6eefa9cSas 	else if (x ==  ldrch)
4257c478bd9Sstevel@tonic-gate 		rchar = dotc | chbits;
4267c478bd9Sstevel@tonic-gate 	temp = npad = ws = 0;
4277c478bd9Sstevel@tonic-gate 	savfc = fc;
4287c478bd9Sstevel@tonic-gate 	savtc = tabch;
4297c478bd9Sstevel@tonic-gate 	savlc = ldrch;
4307c478bd9Sstevel@tonic-gate 	tabch = ldrch = fc = IMP;
4317c478bd9Sstevel@tonic-gate 	savepos = numtab[HP].val;
4327c478bd9Sstevel@tonic-gate 	gchtab[tabch] &= ~TABBIT;
4337c478bd9Sstevel@tonic-gate 	gchtab[ldrch] &= ~LDRBIT;
4347c478bd9Sstevel@tonic-gate 	gchtab[fc] &= ~FCBIT;
4357c478bd9Sstevel@tonic-gate 	gchtab[IMP] |= TABBIT|LDRBIT|FCBIT;
4367c478bd9Sstevel@tonic-gate 	for (j = 0; ; j++) {
4377c478bd9Sstevel@tonic-gate 		if ((tabtab[j] & TABMASK) == 0) {
4387c478bd9Sstevel@tonic-gate 			if (x == savfc)
4397c478bd9Sstevel@tonic-gate 				errprint(gettext("zero field width."));
4407c478bd9Sstevel@tonic-gate 			jj = 0;
4417c478bd9Sstevel@tonic-gate 			goto rtn;
4427c478bd9Sstevel@tonic-gate 		}
443e6eefa9cSas 		if ((length = ((tabtab[j] & TABMASK) - numtab[HP].val)) > 0)
4447c478bd9Sstevel@tonic-gate 			break;
4457c478bd9Sstevel@tonic-gate 	}
4467c478bd9Sstevel@tonic-gate 	type = tabtab[j] & (~TABMASK);
4477c478bd9Sstevel@tonic-gate 	fp = fbuf;
4487c478bd9Sstevel@tonic-gate 	pp = padptr;
4497c478bd9Sstevel@tonic-gate 	if (x == savfc) {
4507c478bd9Sstevel@tonic-gate 		while (1) {
4517c478bd9Sstevel@tonic-gate 			j = cbits(ii = getch());
4527c478bd9Sstevel@tonic-gate 			jj = width(ii);
4537c478bd9Sstevel@tonic-gate 			widthp = jj;
4547c478bd9Sstevel@tonic-gate 			numtab[HP].val += jj;
4557c478bd9Sstevel@tonic-gate 			if (j == padc) {
4567c478bd9Sstevel@tonic-gate 				npad++;
4577c478bd9Sstevel@tonic-gate 				*pp++ = fp;
4587c478bd9Sstevel@tonic-gate 				if (pp > (padptr + NPP - 1))
4597c478bd9Sstevel@tonic-gate 					break;
4607c478bd9Sstevel@tonic-gate 				goto s1;
461e6eefa9cSas 			} else if (j == savfc)
4627c478bd9Sstevel@tonic-gate 				break;
4637c478bd9Sstevel@tonic-gate 			else if (j == '\n') {
4647c478bd9Sstevel@tonic-gate 				temp = j;
4657c478bd9Sstevel@tonic-gate 				nlflg = 0;
4667c478bd9Sstevel@tonic-gate 				break;
4677c478bd9Sstevel@tonic-gate 			}
4687c478bd9Sstevel@tonic-gate 			ws += jj;
4697c478bd9Sstevel@tonic-gate s1:
4707c478bd9Sstevel@tonic-gate 			*fp++ = ii;
4717c478bd9Sstevel@tonic-gate 			if (fp > (fbuf + FBUFSZ - 3))
4727c478bd9Sstevel@tonic-gate 				break;
4737c478bd9Sstevel@tonic-gate 		}
4747c478bd9Sstevel@tonic-gate 		if (!npad) {
4757c478bd9Sstevel@tonic-gate 			npad++;
4767c478bd9Sstevel@tonic-gate 			*pp++ = fp;
4777c478bd9Sstevel@tonic-gate 			*fp++ = 0;
4787c478bd9Sstevel@tonic-gate 		}
4797c478bd9Sstevel@tonic-gate 		*fp++ = temp;
4807c478bd9Sstevel@tonic-gate 		*fp++ = 0;
4817c478bd9Sstevel@tonic-gate 		temp = i = (j = length - ws) / npad;
4827c478bd9Sstevel@tonic-gate 		i = (i / HOR) * HOR;
4837c478bd9Sstevel@tonic-gate 		if ((j -= i * npad) < 0)
4847c478bd9Sstevel@tonic-gate 			j = -j;
4857c478bd9Sstevel@tonic-gate 		ii = makem(i);
4867c478bd9Sstevel@tonic-gate 		if (temp < 0)
4877c478bd9Sstevel@tonic-gate 			ii |= NMOT;
4887c478bd9Sstevel@tonic-gate 		for (; npad > 0; npad--) {
4897c478bd9Sstevel@tonic-gate 			*(*--pp) = ii;
4907c478bd9Sstevel@tonic-gate 			if (j) {
4917c478bd9Sstevel@tonic-gate 				j -= HOR;
4927c478bd9Sstevel@tonic-gate 				(*(*pp)) += HOR;
4937c478bd9Sstevel@tonic-gate 			}
4947c478bd9Sstevel@tonic-gate 		}
4957c478bd9Sstevel@tonic-gate 		pushback(fbuf);
4967c478bd9Sstevel@tonic-gate 		jj = 0;
4977c478bd9Sstevel@tonic-gate 	} else if (type == 0) {
498e6eefa9cSas 		/* plain tab or leader */
4997c478bd9Sstevel@tonic-gate 		if ((j = width(rchar)) > 0) {
5007c478bd9Sstevel@tonic-gate 			int nchar = length / j;
5017c478bd9Sstevel@tonic-gate 			while (nchar-->0 && pbp < &pbbuf[NC-3]) {
5027c478bd9Sstevel@tonic-gate 				numtab[HP].val += j;
5037c478bd9Sstevel@tonic-gate 				widthp = j;
5047c478bd9Sstevel@tonic-gate 				*pbp++ = rchar;
5057c478bd9Sstevel@tonic-gate 			}
5067c478bd9Sstevel@tonic-gate 			length %= j;
5077c478bd9Sstevel@tonic-gate 		}
5087c478bd9Sstevel@tonic-gate 		if (length)
5097c478bd9Sstevel@tonic-gate 			jj = length | MOT;
510e6eefa9cSas 		else
5117c478bd9Sstevel@tonic-gate 			jj = getch0();
5127c478bd9Sstevel@tonic-gate 	} else {
513e6eefa9cSas 		/* center tab */
514e6eefa9cSas 		/* right tab */
515e6eefa9cSas 		while (((j = cbits(ii = getch())) != savtc) &&
516e6eefa9cSas 		    (j != '\n') && (j != savlc)) {
5177c478bd9Sstevel@tonic-gate 			jj = width(ii);
5187c478bd9Sstevel@tonic-gate 			ws += jj;
5197c478bd9Sstevel@tonic-gate 			numtab[HP].val += jj;
5207c478bd9Sstevel@tonic-gate 			widthp = jj;
5217c478bd9Sstevel@tonic-gate 			*fp++ = ii;
522e6eefa9cSas 			if (fp > (fbuf + FBUFSZ - 3))
5237c478bd9Sstevel@tonic-gate 				break;
5247c478bd9Sstevel@tonic-gate 		}
5257c478bd9Sstevel@tonic-gate 		*fp++ = ii;
5267c478bd9Sstevel@tonic-gate 		*fp++ = 0;
5277c478bd9Sstevel@tonic-gate 		if (type == RTAB)
5287c478bd9Sstevel@tonic-gate 			length -= ws;
529e6eefa9cSas 		else
530e6eefa9cSas 			length -= ws / 2; /* CTAB */
5317c478bd9Sstevel@tonic-gate 		pushback(fbuf);
5327c478bd9Sstevel@tonic-gate 		if ((j = width(rchar)) != 0 && length > 0) {
5337c478bd9Sstevel@tonic-gate 			int nchar = length / j;
5347c478bd9Sstevel@tonic-gate 			while (nchar-- > 0 && pbp < &pbbuf[NC-3])
5357c478bd9Sstevel@tonic-gate 				*pbp++ = rchar;
5367c478bd9Sstevel@tonic-gate 			length %= j;
5377c478bd9Sstevel@tonic-gate 		}
5387c478bd9Sstevel@tonic-gate 		length = (length / HOR) * HOR;
5397c478bd9Sstevel@tonic-gate 		jj = makem(length);
5407c478bd9Sstevel@tonic-gate 		nlflg = 0;
5417c478bd9Sstevel@tonic-gate 	}
5427c478bd9Sstevel@tonic-gate rtn:
5437c478bd9Sstevel@tonic-gate 	gchtab[fc] &= ~FCBIT;
5447c478bd9Sstevel@tonic-gate 	gchtab[tabch] &= ~TABBIT;
5457c478bd9Sstevel@tonic-gate 	gchtab[ldrch] &= ~LDRBIT;
5467c478bd9Sstevel@tonic-gate 	fc = savfc;
5477c478bd9Sstevel@tonic-gate 	tabch = savtc;
5487c478bd9Sstevel@tonic-gate 	ldrch = savlc;
5497c478bd9Sstevel@tonic-gate 	gchtab[fc] |= FCBIT;
5507c478bd9Sstevel@tonic-gate 	gchtab[tabch] = TABBIT;
5517c478bd9Sstevel@tonic-gate 	gchtab[ldrch] |= LDRBIT;
5527c478bd9Sstevel@tonic-gate 	numtab[HP].val = savepos;
553e6eefa9cSas 	return (jj);
5547c478bd9Sstevel@tonic-gate }
5557c478bd9Sstevel@tonic-gate 
5567c478bd9Sstevel@tonic-gate 
5577c478bd9Sstevel@tonic-gate #ifdef EUC
5587c478bd9Sstevel@tonic-gate #ifdef NROFF
5597c478bd9Sstevel@tonic-gate /* locale specific initialization */
560e6eefa9cSas int
localize(void)561*c5fe87b8SToomas Soome localize(void)
5627c478bd9Sstevel@tonic-gate {
5637c478bd9Sstevel@tonic-gate 	extern int	wdbindf();
5647c478bd9Sstevel@tonic-gate 	extern wchar_t	*wddelim();
5657c478bd9Sstevel@tonic-gate 	char	*codeset;
5667c478bd9Sstevel@tonic-gate 
5677c478bd9Sstevel@tonic-gate 	codeset = nl_langinfo(CODESET);
5687c478bd9Sstevel@tonic-gate 
5697c478bd9Sstevel@tonic-gate 	if (MB_CUR_MAX > 1)
5707c478bd9Sstevel@tonic-gate 		multi_locale = 1;
5717c478bd9Sstevel@tonic-gate 	else {
5727c478bd9Sstevel@tonic-gate 		if (*codeset == '\0' ||
573*c5fe87b8SToomas Soome 		    (strcmp(codeset, ISO646) == 0)) {
5747c478bd9Sstevel@tonic-gate 			/*
5757c478bd9Sstevel@tonic-gate 			 * if codeset is an empty string
5767c478bd9Sstevel@tonic-gate 			 * assumes this is C locale (7-bit) locale.
5777c478bd9Sstevel@tonic-gate 			 * This happens in 2.5, 2.5.1, and 2.6 system
5787c478bd9Sstevel@tonic-gate 			 * Or, if codeset is "646"
5797c478bd9Sstevel@tonic-gate 			 * this is 7-bit locale.
5807c478bd9Sstevel@tonic-gate 			 */
5817c478bd9Sstevel@tonic-gate 			multi_locale = 0;
5827c478bd9Sstevel@tonic-gate 		} else {
5837c478bd9Sstevel@tonic-gate 			/* 8-bit locale */
5847c478bd9Sstevel@tonic-gate 			multi_locale = 1;
5857c478bd9Sstevel@tonic-gate 		}
5867c478bd9Sstevel@tonic-gate 
5877c478bd9Sstevel@tonic-gate 	}
5887c478bd9Sstevel@tonic-gate 	wdbdg = wdbindf;
5897c478bd9Sstevel@tonic-gate 	wddlm = wddelim;
590e5190c10Smuffin 
591e5190c10Smuffin 	return (0);
5927c478bd9Sstevel@tonic-gate }
5937c478bd9Sstevel@tonic-gate #endif /* EUC */
5947c478bd9Sstevel@tonic-gate #endif /* NROFF */
595