=================================================================== RCS file: /cvs/mandoc/roff_term.c,v retrieving revision 1.10 retrieving revision 1.24 diff -u -p -r1.10 -r1.24 --- mandoc/roff_term.c 2017/06/08 12:54:58 1.10 +++ mandoc/roff_term.c 2021/09/19 18:07:09 1.24 @@ -1,6 +1,6 @@ -/* $Id: roff_term.c,v 1.10 2017/06/08 12:54:58 schwarze Exp $ */ +/* $OpenBSD: roff_term.c,v 1.24 2021/09/19 18:07:09 schwarze Exp $ */ /* - * Copyright (c) 2010, 2014, 2015, 2017 Ingo Schwarze + * Copyright (c) 2010,2014,2015,2017-2020 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,11 +14,15 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "config.h" + #include #include -#include +#include +#include +#include "mandoc.h" #include "roff.h" #include "out.h" #include "term.h" @@ -32,6 +36,7 @@ static void roff_term_pre_ce(ROFF_TERM_ARGS); static void roff_term_pre_ft(ROFF_TERM_ARGS); static void roff_term_pre_ll(ROFF_TERM_ARGS); static void roff_term_pre_mc(ROFF_TERM_ARGS); +static void roff_term_pre_po(ROFF_TERM_ARGS); static void roff_term_pre_sp(ROFF_TERM_ARGS); static void roff_term_pre_ta(ROFF_TERM_ARGS); static void roff_term_pre_ti(ROFF_TERM_ARGS); @@ -39,9 +44,13 @@ static void roff_term_pre_ti(ROFF_TERM_ARGS); static const roff_term_pre_fp roff_term_pre_acts[ROFF_MAX] = { roff_term_pre_br, /* br */ roff_term_pre_ce, /* ce */ + roff_term_pre_br, /* fi */ roff_term_pre_ft, /* ft */ roff_term_pre_ll, /* ll */ roff_term_pre_mc, /* mc */ + roff_term_pre_br, /* nf */ + roff_term_pre_po, /* po */ + roff_term_pre_ce, /* rj */ roff_term_pre_sp, /* sp */ roff_term_pre_ta, /* ta */ roff_term_pre_ti, /* ti */ @@ -62,66 +71,62 @@ roff_term_pre_br(ROFF_TERM_ARGS) if (p->flags & TERMP_BRIND) { p->tcol->offset = p->tcol->rmargin; p->tcol->rmargin = p->maxrmargin; + p->trailspace = 0; p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND); + p->flags |= TERMP_NOSPACE; } } static void roff_term_pre_ce(ROFF_TERM_ARGS) { - const struct roff_node *nch; - size_t len, lm; + const struct roff_node *nc1, *nc2; roff_term_pre_br(p, n); - lm = p->tcol->offset; - n = n->child->next; - while (n != NULL) { - nch = n; - len = 0; + p->flags |= n->tok == ROFF_ce ? TERMP_CENTER : TERMP_RIGHT; + nc1 = n->child->next; + while (nc1 != NULL) { + nc2 = nc1; do { - if (n->type == ROFFT_TEXT) { - if (len) - len++; - len += term_strlen(p, nch->string); - } - nch = nch->next; - } while (nch != NULL && (n->type != ROFFT_TEXT || - (n->flags & NODE_LINE) == 0)); - p->tcol->offset = len >= p->tcol->rmargin ? 0 : - lm + len >= p->tcol->rmargin ? p->tcol->rmargin - len : - (lm + p->tcol->rmargin - len) / 2; - while (n != nch) { - if (n->type == ROFFT_TEXT) - term_word(p, n->string); + nc2 = nc2->next; + } while (nc2 != NULL && (nc2->type != ROFFT_TEXT || + (nc2->flags & NODE_LINE) == 0)); + while (nc1 != nc2) { + if (nc1->type == ROFFT_TEXT) + term_word(p, nc1->string); else - roff_term_pre(p, n); - n = n->next; + roff_term_pre(p, nc1); + nc1 = nc1->next; } p->flags |= TERMP_NOSPACE; term_flushln(p); } - p->tcol->offset = lm; + p->flags &= ~(TERMP_CENTER | TERMP_RIGHT); } static void roff_term_pre_ft(ROFF_TERM_ARGS) { - switch (*n->child->string) { - case '4': - case '3': - case 'B': + const char *cp; + + cp = n->child->string; + switch (mandoc_font(cp, (int)strlen(cp))) { + case ESCAPE_FONTBOLD: + case ESCAPE_FONTCB: term_fontrepl(p, TERMFONT_BOLD); break; - case '2': - case 'I': + case ESCAPE_FONTITALIC: + case ESCAPE_FONTCI: term_fontrepl(p, TERMFONT_UNDER); break; - case 'P': + case ESCAPE_FONTBI: + term_fontrepl(p, TERMFONT_BI); + break; + case ESCAPE_FONTPREV: term_fontlast(p); break; - case '1': - case 'C': - case 'R': + case ESCAPE_FONTROMAN: + case ESCAPE_FONTCR: term_fontrepl(p, TERMFONT_NONE); break; default: @@ -151,6 +156,36 @@ roff_term_pre_mc(ROFF_TERM_ARGS) } static void +roff_term_pre_po(ROFF_TERM_ARGS) +{ + struct roffsu su; + static int po, pouse, polast; + int ponew; + + /* Revert the currently active page offset. */ + p->tcol->offset -= pouse; + + /* Determine the requested page offset. */ + if (n->child != NULL && + a2roffsu(n->child->string, &su, SCALE_EM) != NULL) { + ponew = term_hen(p, &su); + if (*n->child->string == '+' || + *n->child->string == '-') + ponew += po; + } else + ponew = polast; + + /* Remeber both the previous and the newly requested offset. */ + polast = po; + po = ponew; + + /* Truncate to the range [-offset, 60], remember, and apply it. */ + pouse = po >= 60 ? 60 : + po < -(int)p->tcol->offset ? -(int)p->tcol->offset : po; + p->tcol->offset += pouse; +} + +static void roff_term_pre_sp(ROFF_TERM_ARGS) { struct roffsu su; @@ -185,6 +220,7 @@ roff_term_pre_ti(ROFF_TERM_ARGS) { struct roffsu su; const char *cp; + const size_t maxoff = 72; int len, sign; roff_term_pre_br(p, n); @@ -203,19 +239,28 @@ roff_term_pre_ti(ROFF_TERM_ARGS) if (a2roffsu(cp, &su, SCALE_EM) == NULL) return; - len = term_hspan(p, &su) / 24; + len = term_hen(p, &su); - if (sign == 0) { + switch (sign) { + case 1: + if (p->tcol->offset + len <= maxoff) + p->ti = len; + else if (p->tcol->offset < maxoff) + p->ti = maxoff - p->tcol->offset; + else + p->ti = 0; + break; + case -1: + if ((size_t)len < p->tcol->offset) + p->ti = -len; + else + p->ti = -p->tcol->offset; + break; + default: + if ((size_t)len > maxoff) + len = maxoff; p->ti = len - p->tcol->offset; - p->tcol->offset = len; - } else if (sign == 1) { - p->ti = len; - p->tcol->offset += len; - } else if ((size_t)len < p->tcol->offset) { - p->ti = -len; - p->tcol->offset -= len; - } else { - p->ti = -p->tcol->offset; - p->tcol->offset = 0; + break; } + p->tcol->offset += p->ti; }