xref: /illumos-gate/usr/src/cmd/tbl/tu.c (revision fc910014e8a32a65612105835a10995f2c13d942)
1 /*
2  * Copyright 1990 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
7 /*	  All Rights Reserved  	*/
8 
9 /*
10  * Copyright (c) 1980 Regents of the University of California.
11  * All rights reserved. The Berkeley software License Agreement
12  * specifies the terms and conditions for redistribution.
13  */
14 
15  /* tu.c: draws horizontal lines */
16 # include "t..c"
17 
18 void	drawline(int, int, int, int, int, int);
19 
20 void
21 makeline(int i, int c, int lintype)
22 {
23 int cr, type, shortl;
24 type = thish(i,c);
25 if (type==0) return;
26 cr=c;
27 shortl = (table[i][c].col[0]=='\\');
28 if (c>0 && !shortl && thish(i,c-1) == type)return;
29 if (shortl==0)
30 	for(cr=c; cr < ncol && (ctype(i,cr)=='s'||type==thish(i,cr)); cr++);
31 else
32 	for(cr=c+1; cr<ncol && ctype(i,cr)=='s'; cr++);
33 drawline(i, c, cr-1, lintype, 0, shortl);
34 }
35 
36 void
37 fullwide(int i, int lintype)
38 {
39 int cr, cl;
40 if (!pr1403)
41 	fprintf(tabout, ".nr %d \\n(.v\n.vs \\n(.vu-\\n(.sp\n", SVS);
42 cr= 0;
43 while (cr<ncol)
44 	{
45 	cl=cr;
46 	while (i>0 && vspand(prev(i),cl,1))
47 		cl++;
48 	for(cr=cl; cr<ncol; cr++)
49 		if (i>0 && vspand(prev(i),cr,1))
50 			break;
51 	if (cl<ncol)
52 	drawline(i,cl,(cr<ncol?cr-1:cr),lintype,1,0);
53 	}
54 fprintf(tabout, "\n");
55 if (!pr1403)
56 	fprintf(tabout, ".vs \\n(%du\n", SVS);
57 }
58 
59 void
60 drawline(int i, int cl, int cr, int lintype, int noheight, int shortl)
61 {
62 	char *exhr, *exhl, *lnch;
63 	int lcount, ln, linpos, oldpos, nodata;
64 lcount=0;
65 exhr=exhl= "";
66 switch(lintype)
67 	{
68 	case '-': lcount=1;break;
69 	case '=': lcount = pr1403? 1 : 2; break;
70 	case SHORTLINE: lcount=1; break;
71 	}
72 if (lcount<=0) return;
73 nodata = cr-cl>=ncol || noheight || allh(i);
74 	if (!nodata)
75 		fprintf(tabout, "\\v'-.5m'");
76 for(ln=oldpos=0; ln<lcount; ln++)
77 	{
78 	linpos = 2*ln - lcount +1;
79 	if (linpos != oldpos)
80 		fprintf(tabout, "\\v'%dp'", linpos-oldpos);
81 	oldpos=linpos;
82 	if (shortl==0)
83 	{
84 	tohcol(cl);
85 	if (lcount>1)
86 		{
87 		switch(interv(i,cl))
88 			{
89 			case TOP: exhl = ln==0 ? "1p" : "-1p"; break;
90 			case BOT: exhl = ln==1 ? "1p" : "-1p"; break;
91 			case THRU: exhl = "1p"; break;
92 			}
93 		if (exhl[0])
94 		fprintf(tabout, "\\h'%s'", exhl);
95 		}
96 	else if (lcount==1)
97 		{
98 		switch(interv(i,cl))
99 			{
100 			case TOP: case BOT: exhl = "-1p"; break;
101 			case THRU: exhl = "1p"; break;
102 			}
103 		if (exhl[0])
104 		fprintf(tabout, "\\h'%s'", exhl);
105 		}
106 	if (lcount>1)
107 		{
108 		switch(interv(i,cr+1))
109 			{
110 			case TOP: exhr = ln==0 ? "-1p" : "+1p"; break;
111 			case BOT: exhr = ln==1 ? "-1p" : "+1p"; break;
112 			case THRU: exhr = "-1p"; break;
113 			}
114 		}
115 	else if (lcount==1)
116 		{
117 		switch(interv(i,cr+1))
118 			{
119 			case TOP: case BOT: exhr = "+1p"; break;
120 			case THRU: exhr = "-1p"; break;
121 			}
122 		}
123 	}
124 	else
125 		fprintf(tabout, "\\h'|\\n(%du'", cl+CLEFT);
126 	fprintf(tabout, "\\s\\n(%d",LSIZE);
127 	if (linsize)
128 		fprintf(tabout, "\\v'-\\n(%dp/6u'", LSIZE);
129 	if (shortl)
130 		fprintf(tabout, "\\l'|\\n(%du'", cr+CRIGHT);
131 	else
132 	{
133 	lnch = "\\(ul";
134 	if (pr1403)
135 		lnch = lintype==2 ? "=" : "\\(ru";
136 	if (cr+1>=ncol)
137 		fprintf(tabout, "\\l'|\\n(TWu%s%s'", exhr,lnch);
138 	else
139 		fprintf(tabout, "\\l'(|\\n(%du+|\\n(%du)/2u%s%s'", cr+CRIGHT,
140 			cr+1+CLEFT, exhr, lnch);
141 	}
142 	if (linsize)
143 		fprintf(tabout, "\\v'\\n(%dp/6u'", LSIZE);
144 	fprintf(tabout, "\\s0");
145 	}
146 if (oldpos!=0)
147 	fprintf(tabout, "\\v'%dp'", -oldpos);
148 if (!nodata)
149 	fprintf(tabout, "\\v'+.5m'");
150 }
151 
152 void
153 getstop(void)
154 {
155 int i,c,k,junk, stopp;
156 stopp=1;
157 for(i=0; i<MAXLIN; i++)
158 	linestop[i]=0;
159 for(i=0; i<nlin; i++)
160 	for(c=0; c<ncol; c++)
161 		{
162 		k = left(i,c,&junk);
163 		if (k>=0 && linestop[k]==0)
164 			linestop[k]= ++stopp;
165 		}
166 if (boxflg || allflg || dboxflg)
167 	linestop[0]=1;
168 }
169 
170 int
171 left(int i, int c, int *lwidp)
172 {
173 int kind, li, lj;
174 	/* returns -1 if no line to left */
175 	/* returns number of line where it starts */
176 	/* stores into lwid the kind of line */
177 *lwidp=0;
178 kind = lefdata(i,c);
179 if (kind==0) return(-1);
180 if (i+1<nlin)
181 if (lefdata(next(i),c)== kind) return(-1);
182 while (i>=0 && lefdata(i,c)==kind)
183 	i=prev(li=i);
184 if (prev(li)== -1) li=0;
185 *lwidp=kind;
186 for(lj= i+1; lj<li; lj++)
187 	if (instead[lj] && strcmp(instead[lj], ".TH")==0)
188 		return(li);
189 for(i= i+1; i<li; i++)
190 	if (fullbot[i])
191 		li=i;
192 return(li);
193 }
194 
195 int
196 lefdata(int i, int c)
197 {
198 int ck;
199 if (i>=nlin) i=nlin-1;
200 if (ctype(i,c) == 's')
201 	{
202 	for(ck=c; ctype(i,ck)=='s'; ck--);
203 	if (thish(i,ck)==0)
204 		return(0);
205 	}
206 i =stynum[i];
207 i = lefline[i][c];
208 if (i>0) return(i);
209 if (dboxflg && c==0) return(2);
210 if (allflg)return(1);
211 if (boxflg && c==0) return(1);
212 return(0);
213 }
214 
215 int
216 next(int i)
217 {
218 while (i+1 <nlin)
219 	{
220 	i++;
221 	if (!fullbot[i] && !instead[i]) break;
222 	}
223 return(i);
224 }
225 
226 int
227 prev(int i)
228 {
229 while (--i >=0  && (fullbot[i] || instead[i]))
230 	;
231 return(i);
232 }
233