out: use em / 3 as the default char width
[neatroff.git] / line.c
blob041eea6f4c9d05666d61459c0093a0fba64f477b
1 #include <stdlib.h>
2 #include <string.h>
3 #include "xroff.h"
5 /* horizontal and vertical line characters */
6 static char *hs[] = {"_", "\\_", "\\-", "\\(ru", "\\(ul", "\\(rn", NULL};
7 static char *vs[] = {"\\(bv", "\\(br", "|", NULL};
9 static int cwid(char *c)
11 struct glyph *g = dev_glyph(c, n_f);
12 return charwid(g ? g->wid : SC_DW, n_s);
15 static int lchar(char *c, char **cs)
17 while (*cs)
18 if (!strcmp(*cs++, c))
19 return 1;
20 return 0;
23 static void vmov(struct adj *adj, int w)
25 adj_put(adj, w, "\\v'%du'", w);
28 static void hmov(struct adj *adj, int w)
30 adj_put(adj, w, "\\h'%du'", w);
33 void ren_hline(struct adj *adj, char *arg)
35 char *lc = "\\(ru";
36 int w, l, n, i, rem;
37 l = eval_up(&arg, 0, 'm');
38 if (!l)
39 return;
40 if (arg[0] == '\\' && arg[1] == '&') /* \& can be used as a separator */
41 arg += 2;
42 if (*arg)
43 lc = arg;
44 w = cwid(lc);
45 /* negative length; moving backwards */
46 if (l < 0) {
47 hmov(adj, l);
48 l = -l;
50 n = l / w;
51 rem = l % w;
52 /* length less than character width */
53 if (l < w) {
54 n = 1;
55 rem = 0;
56 hmov(adj, -(w - l) / 2);
58 /* the initial gap */
59 if (rem) {
60 if (lchar(lc, hs)) {
61 adj_put(adj, w, "%s", lc);
62 hmov(adj, rem - w);
63 } else {
64 hmov(adj, rem);
67 for (i = 0; i < n; i++)
68 adj_put(adj, w, lc);
69 /* moving back */
70 if (l < w)
71 hmov(adj, -(w - l + 1) / 2);
74 void ren_vline(struct adj *adj, char *arg)
76 char *lc = "\\(br";
77 int w, l, n, i, rem, hw, neg;
78 l = eval_up(&arg, 0, 'm');
79 if (!l)
80 return;
81 neg = l < 0;
82 if (arg[0] == '\\' && arg[1] == '&') /* \& can be used as a separator */
83 arg += 2;
84 if (*arg)
85 lc = arg;
86 w = n_s * SC_PT; /* character height */
87 hw = cwid(lc); /* character width */
88 /* negative length; moving backwards */
89 if (l < 0) {
90 vmov(adj, l);
91 l = -l;
93 n = l / w;
94 rem = l % w;
95 /* length less than character width */
96 if (l < w) {
97 n = 1;
98 rem = 0;
99 vmov(adj, -w + l / 2);
101 /* the initial gap */
102 if (rem) {
103 if (lchar(lc, vs)) {
104 vmov(adj, w);
105 adj_put(adj, hw, "%s", lc);
106 hmov(adj, -hw);
107 vmov(adj, rem - w);
108 } else {
109 vmov(adj, rem);
112 for (i = 0; i < n; i++) {
113 vmov(adj, w);
114 adj_put(adj, hw, lc);
115 hmov(adj, -hw);
117 /* moving back */
118 if (l < w)
119 vmov(adj, l / 2);
120 if (neg)
121 vmov(adj, -l);
122 hmov(adj, hw);