8 static int ln_next(void)
10 return *ln_s
? (unsigned char) *ln_s
++ : -1;
13 static void ln_back(int c
)
18 static char *ln_push(char *s
)
25 static void ln_pop(char *s
)
30 static int cwid(char *c
)
32 struct glyph
*g
= dev_glyph(c
, n_f
);
33 return charwid(g
? g
->wid
: SC_DW
, n_s
);
36 static int hchar(char *c
)
41 return c
[1] == '_' || c
[1] == '-';
42 return (c
[2] == 'r' && c
[3] == 'u') || (c
[2] == 'u' && c
[3] == 'l') ||
43 (c
[2] == 'r' && c
[3] == 'n');
46 static int vchar(char *c
)
48 if (c
[0] != c_ec
|| c
[1] != '(')
50 return (c
[2] == 'b' && c
[3] == 'v') || (c
[2] == 'b' && c
[3] == 'r');
53 void ren_hline(struct wb
*wb
, char *arg
)
55 char lc
[GNLEN
] = {c_ec
, '(', 'r', 'u'};
57 l
= eval_up(&arg
, 'm');
60 if (arg
[0] == c_ec
&& arg
[1] == '&') /* \& can be used as a separator */
65 /* negative length; moving backwards */
72 /* length less than character width */
76 wb_hmov(wb
, -(w
- l
) / 2);
87 for (i
= 0; i
< n
; i
++)
91 wb_hmov(wb
, -(w
- l
+ 1) / 2);
94 void ren_vline(struct wb
*wb
, char *arg
)
96 char lc
[GNLEN
] = {c_ec
, '(', 'b', 'r'};
97 int w
, l
, n
, i
, rem
, hw
, neg
;
98 l
= eval_up(&arg
, 'v');
102 if (arg
[0] == c_ec
&& arg
[1] == '&') /* \& can be used as a separator */
106 w
= SC_HT
; /* character height */
107 hw
= cwid(lc
); /* character width */
108 /* negative length; moving backwards */
115 /* length less than character width */
119 wb_vmov(wb
, -w
+ l
/ 2);
121 /* the initial gap */
127 wb_vmov(wb
, rem
- w
);
132 for (i
= 0; i
< n
; i
++) {
145 void ren_bracket(struct wb
*wb
, char *arg
)
150 char *ln_prev
= ln_push(arg
);
155 ren_char(&wb2
, ln_next
, ln_back
);
156 if (wb_wid(&wb2
) > w
)
158 wb_hmov(&wb2
, -wb_wid(&wb2
));
159 wb_vmov(&wb2
, SC_HT
);
164 center
= -(n
* SC_HT
+ SC_EM
) / 2;
165 wb_vmov(wb
, center
+ SC_HT
);
172 void ren_over(struct wb
*wb
, char *arg
)
177 char *ln_prev
= ln_push(arg
);
183 ren_char(&wb3
, ln_next
, ln_back
);
187 wb_hmov(&wb2
, -wc
/ 2);
189 wb_hmov(&wb2
, -wc
/ 2);
200 static int tok_num(char **s
, int scale
)
206 while (**s
&& !isspace(**s
))
209 return eval(tok
, scale
);
212 void ren_draw(struct wb
*wb
, char *s
)
218 h1
= tok_num(&s
, 'm');
219 v1
= tok_num(&s
, 'v');
220 wb_drawl(wb
, h1
, v1
);
223 h1
= tok_num(&s
, 'm');
227 h1
= tok_num(&s
, 'm');
228 v1
= tok_num(&s
, 'v');
229 wb_drawe(wb
, h1
, v1
);
232 h1
= tok_num(&s
, 'm');
233 v1
= tok_num(&s
, 'v');
234 h2
= tok_num(&s
, 'm');
235 v2
= tok_num(&s
, 'v');
236 wb_drawa(wb
, h1
, v1
, h2
, v2
);
241 h1
= tok_num(&s
, 'm');
242 v1
= tok_num(&s
, 'v');
243 wb_drawxdot(wb
, h1
, v1
);