1 /* $Id: roff_term.c,v 1.10 2017/06/08 12:54:58 schwarze Exp $ */
3 * Copyright (c) 2010, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 #include <sys/types.h>
26 #define ROFF_TERM_ARGS struct termp *p, const struct roff_node *n
28 typedef void (*roff_term_pre_fp)(ROFF_TERM_ARGS);
30 static void roff_term_pre_br(ROFF_TERM_ARGS);
31 static void roff_term_pre_ce(ROFF_TERM_ARGS);
32 static void roff_term_pre_ft(ROFF_TERM_ARGS);
33 static void roff_term_pre_ll(ROFF_TERM_ARGS);
34 static void roff_term_pre_mc(ROFF_TERM_ARGS);
35 static void roff_term_pre_sp(ROFF_TERM_ARGS);
36 static void roff_term_pre_ta(ROFF_TERM_ARGS);
37 static void roff_term_pre_ti(ROFF_TERM_ARGS);
39 static const roff_term_pre_fp roff_term_pre_acts[ROFF_MAX] = {
40 roff_term_pre_br, /* br */
41 roff_term_pre_ce, /* ce */
42 roff_term_pre_ft, /* ft */
43 roff_term_pre_ll, /* ll */
44 roff_term_pre_mc, /* mc */
45 roff_term_pre_sp, /* sp */
46 roff_term_pre_ta, /* ta */
47 roff_term_pre_ti, /* ti */
52 roff_term_pre(struct termp *p, const struct roff_node *n)
54 assert(n->tok < ROFF_MAX);
55 (*roff_term_pre_acts[n->tok])(p, n);
59 roff_term_pre_br(ROFF_TERM_ARGS)
62 if (p->flags & TERMP_BRIND) {
63 p->tcol->offset = p->tcol->rmargin;
64 p->tcol->rmargin = p->maxrmargin;
65 p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND);
70 roff_term_pre_ce(ROFF_TERM_ARGS)
72 const struct roff_node *nch;
75 roff_term_pre_br(p, n);
82 if (n->type == ROFFT_TEXT) {
85 len += term_strlen(p, nch->string);
88 } while (nch != NULL && (n->type != ROFFT_TEXT ||
89 (n->flags & NODE_LINE) == 0));
90 p->tcol->offset = len >= p->tcol->rmargin ? 0 :
91 lm + len >= p->tcol->rmargin ? p->tcol->rmargin - len :
92 (lm + p->tcol->rmargin - len) / 2;
94 if (n->type == ROFFT_TEXT)
95 term_word(p, n->string);
100 p->flags |= TERMP_NOSPACE;
103 p->tcol->offset = lm;
107 roff_term_pre_ft(ROFF_TERM_ARGS)
109 switch (*n->child->string) {
113 term_fontrepl(p, TERMFONT_BOLD);
117 term_fontrepl(p, TERMFONT_UNDER);
125 term_fontrepl(p, TERMFONT_NONE);
133 roff_term_pre_ll(ROFF_TERM_ARGS)
135 term_setwidth(p, n->child != NULL ? n->child->string : NULL);
139 roff_term_pre_mc(ROFF_TERM_ARGS)
142 p->flags |= TERMP_NOBREAK;
144 p->flags &= ~(TERMP_NOBREAK | TERMP_NOSPACE);
146 if (n->child != NULL) {
147 p->mc = n->child->string;
148 p->flags |= TERMP_NEWMC;
150 p->flags |= TERMP_ENDMC;
154 roff_term_pre_sp(ROFF_TERM_ARGS)
159 if (n->child != NULL) {
160 if (a2roffsu(n->child->string, &su, SCALE_VS) == NULL)
162 len = term_vspan(p, &su);
172 roff_term_pre_br(p, n);
176 roff_term_pre_ta(ROFF_TERM_ARGS)
178 term_tab_set(p, NULL);
179 for (n = n->child; n != NULL; n = n->next)
180 term_tab_set(p, n->string);
184 roff_term_pre_ti(ROFF_TERM_ARGS)
190 roff_term_pre_br(p, n);
192 if (n->child == NULL)
194 cp = n->child->string;
198 } else if (*cp == '-') {
204 if (a2roffsu(cp, &su, SCALE_EM) == NULL)
206 len = term_hspan(p, &su) / 24;
209 p->ti = len - p->tcol->offset;
210 p->tcol->offset = len;
211 } else if (sign == 1) {
213 p->tcol->offset += len;
214 } else if ((size_t)len < p->tcol->offset) {
216 p->tcol->offset -= len;
218 p->ti = -p->tcol->offset;