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