=================================================================== RCS file: /cvs/mandoc/term.c,v retrieving revision 1.248 retrieving revision 1.260 diff -u -p -r1.248 -r1.260 --- mandoc/term.c 2015/04/29 18:35:00 1.248 +++ mandoc/term.c 2017/05/07 17:31:45 1.260 @@ -1,7 +1,7 @@ -/* $Id: term.c,v 1.248 2015/04/29 18:35:00 schwarze Exp $ */ +/* $Id: term.c,v 1.260 2017/05/07 17:31:45 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons - * Copyright (c) 2010-2015 Ingo Schwarze + * Copyright (c) 2010-2017 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 @@ -78,6 +78,8 @@ term_end(struct termp *p) * the next column. However, if less than p->trailspace blanks, * which can be 0, 1, or 2, remain to the right margin, the line * will be broken. + * - TERMP_BRTRSP: Consider trailing whitespace significant + * when deciding whether the chunk fits or not. * - TERMP_BRIND: If the chunk does not fit and the output line has * to be broken, start the next line at the right margin instead * of at the offset. Used together with TERMP_NOBREAK for the tags @@ -139,8 +141,8 @@ term_flushln(struct termp *p) * subsequent tabs into a single huge set of spaces. */ ntab = 0; - while (i < p->col && '\t' == p->buf[i]) { - vend = (vis / p->tabwidth + 1) * p->tabwidth; + while (i < p->col && p->buf[i] == '\t') { + vend = term_tab_next(vis); vbl += vend - vis; vis = vend; ntab++; @@ -158,7 +160,7 @@ term_flushln(struct termp *p) if (' ' == p->buf[j] || '\t' == p->buf[j]) break; - /* Back over the the last printed character. */ + /* Back over the last printed character. */ if (8 == p->buf[j]) { assert(j); vend -= (*p->width)(p, p->buf[j - 1]); @@ -190,18 +192,21 @@ term_flushln(struct termp *p) vend -= vis; (*p->endline)(p); p->viscol = 0; - if (TERMP_BRIND & p->flags) { - vbl = p->rmargin; - vend += p->rmargin; - vend -= p->offset; - } else - vbl = p->offset; - /* use pending tabs on the new line */ + /* Use pending tabs on the new line. */ - if (0 < ntab) - vbl += ntab * p->tabwidth; + vbl = 0; + while (ntab--) + vbl = term_tab_next(vbl); + /* Re-establish indentation. */ + + if (p->flags & TERMP_BRIND) { + vbl += p->rmargin; + vend += p->rmargin - p->offset; + } else + vbl += p->offset; + /* * Remove the p->overstep width. * Again, if p->overstep is negative, @@ -291,6 +296,10 @@ term_flushln(struct termp *p) } else if (TERMP_DANGLE & p->flags) return; + /* Trailing whitespace is significant in some columns. */ + if (vis && vbl && (TERMP_BRTRSP & p->flags)) + vis += vbl; + /* If the column was overrun, break the line. */ if (maxvis < vis + p->trailspace * (*p->width)(p, ' ')) { (*p->endline)(p); @@ -359,7 +368,7 @@ term_fontpush(struct termp *p, enum termfont f) if (++p->fonti == p->fontsz) { p->fontsz += 8; p->fontq = mandoc_reallocarray(p->fontq, - p->fontsz, sizeof(enum termfont *)); + p->fontsz, sizeof(*p->fontq)); } p->fontq[p->fonti] = f; } @@ -448,12 +457,11 @@ term_word(struct termp *p, const char *word) break; case ESCAPE_SPECIAL: if (p->enc == TERMENC_ASCII) { - cp = mchars_spec2str(p->symtab, - seq, sz, &ssz); + cp = mchars_spec2str(seq, sz, &ssz); if (cp != NULL) encode(p, cp, ssz); } else { - uc = mchars_spec2cp(p->symtab, seq, sz); + uc = mchars_spec2cp(seq, sz); if (uc > 0) encode1(p, uc); } @@ -468,7 +476,6 @@ term_word(struct termp *p, const char *word) term_fontrepl(p, TERMFONT_BI); continue; case ESCAPE_FONT: - /* FALLTHROUGH */ case ESCAPE_FONTROMAN: term_fontrepl(p, TERMFONT_NONE); continue; @@ -499,6 +506,11 @@ term_word(struct termp *p, const char *word) p->flags |= TERMP_BACKBEFORE; } } + /* Trim trailing backspace/blank pair. */ + if (p->col > 2 && + (p->buf[p->col - 1] == ' ' || + p->buf[p->col - 1] == '\t')) + p->col -= 2; continue; default: continue; @@ -557,11 +569,14 @@ encode1(struct termp *p, int c) if (p->col + 7 >= p->maxcols) adjbuf(p, p->col + 7); - f = (c == ASCII_HYPH || isgraph(c)) ? + f = (c == ASCII_HYPH || c > 127 || isgraph(c)) ? p->fontq[p->fonti] : TERMFONT_NONE; if (p->flags & TERMP_BACKBEFORE) { - p->buf[p->col++] = 8; + if (p->buf[p->col - 1] == ' ' || p->buf[p->col - 1] == '\t') + p->col--; + else + p->buf[p->col++] = 8; p->flags &= ~TERMP_BACKBEFORE; } if (TERMFONT_UNDER == f || TERMFONT_BI == f) { @@ -594,8 +609,20 @@ encode(struct termp *p, const char *word, size_t sz) if (ASCII_HYPH == word[i] || isgraph((unsigned char)word[i])) encode1(p, word[i]); - else + else { p->buf[p->col++] = word[i]; + + /* + * Postpone the effect of \z while handling + * an overstrike sequence from ascii_uc2str(). + */ + + if (word[i] == '\b' && + (p->flags & TERMP_BACKBEFORE)) { + p->flags &= ~TERMP_BACKBEFORE; + p->flags |= TERMP_BACKAFTER; + } + } } } @@ -632,7 +659,7 @@ size_t term_len(const struct termp *p, size_t sz) { - return((*p->width)(p, ' ') * sz); + return (*p->width)(p, ' ') * sz; } static size_t @@ -641,9 +668,9 @@ cond_width(const struct termp *p, int c, int *skip) if (*skip) { (*skip) = 0; - return(0); + return 0; } else - return((*p->width)(p, c)); + return (*p->width)(p, c); } size_t @@ -689,13 +716,11 @@ term_strlen(const struct termp *p, const char *cp) break; case ESCAPE_SPECIAL: if (p->enc == TERMENC_ASCII) { - rhs = mchars_spec2str(p->symtab, - seq, ssz, &rsz); + rhs = mchars_spec2str(seq, ssz, &rsz); if (rhs != NULL) break; } else { - uc = mchars_spec2cp(p->symtab, - seq, ssz); + uc = mchars_spec2cp(seq, ssz); if (uc > 0) sz += cond_width(p, uc, &skip); } @@ -759,15 +784,13 @@ term_strlen(const struct termp *p, const char *cp) case ASCII_HYPH: sz += cond_width(p, '-', &skip); cp++; - /* FALLTHROUGH */ - case ASCII_BREAK: break; default: break; } } - return(sz); + return sz; } int @@ -799,7 +822,6 @@ term_vspan(const struct termp *p, const struct roffsu r = su->scale / 12.0; break; case SCALE_EN: - /* FALLTHROUGH */ case SCALE_EM: r = su->scale * 0.6; break; @@ -808,10 +830,9 @@ term_vspan(const struct termp *p, const struct roffsu break; default: abort(); - /* NOTREACHED */ } ri = r > 0.0 ? r + 0.4995 : r - 0.4995; - return(ri < 66 ? ri : 1); + return ri < 66 ? ri : 1; } /* @@ -821,5 +842,5 @@ int term_hspan(const struct termp *p, const struct roffsu *su) { - return((*p->hspan)(p, su)); + return (*p->hspan)(p, su); }