version 1.278, 2019/01/03 19:59:55 |
version 1.286, 2022/04/27 13:41:13 |
|
|
/* $Id$ */ |
/* $Id$ */ |
/* |
/* |
|
* Copyright (c) 2010-2022 Ingo Schwarze <schwarze@openbsd.org> |
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> |
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> |
* Copyright (c) 2010-2019 Ingo Schwarze <schwarze@openbsd.org> |
|
* |
* |
* Permission to use, copy, modify, and distribute this software for any |
* Permission to use, copy, modify, and distribute this software for any |
* purpose with or without fee is hereby granted, provided that the above |
* purpose with or without fee is hereby granted, provided that the above |
Line 38 static void bufferc(struct termp *, char); |
|
Line 38 static void bufferc(struct termp *, char); |
|
static void encode(struct termp *, const char *, size_t); |
static void encode(struct termp *, const char *, size_t); |
static void encode1(struct termp *, int); |
static void encode1(struct termp *, int); |
static void endline(struct termp *); |
static void endline(struct termp *); |
static void term_field(struct termp *, size_t, size_t, |
static void term_field(struct termp *, size_t, size_t); |
size_t, size_t); |
|
static void term_fill(struct termp *, size_t *, size_t *, |
static void term_fill(struct termp *, size_t *, size_t *, |
size_t); |
size_t); |
|
|
Line 59 term_setcol(struct termp *p, size_t maxtcol) |
|
Line 58 term_setcol(struct termp *p, size_t maxtcol) |
|
void |
void |
term_free(struct termp *p) |
term_free(struct termp *p) |
{ |
{ |
|
term_tab_free(); |
for (p->tcol = p->tcols; p->tcol < p->tcols + p->maxtcol; p->tcol++) |
for (p->tcol = p->tcols; p->tcol < p->tcols + p->maxtcol; p->tcol++) |
free(p->tcol->buf); |
free(p->tcol->buf); |
free(p->tcols); |
free(p->tcols); |
Line 127 term_flushln(struct termp *p) |
|
Line 127 term_flushln(struct termp *p) |
|
* and with the BRNEVER flag, never break it at all. |
* and with the BRNEVER flag, never break it at all. |
*/ |
*/ |
|
|
vtarget = p->flags & TERMP_BRNEVER ? SIZE_MAX : |
vtarget = (p->flags & TERMP_NOBREAK) == 0 ? vfield : |
(p->flags & TERMP_NOBREAK) == 0 ? vfield : |
|
p->maxrmargin > p->viscol + vbl ? |
p->maxrmargin > p->viscol + vbl ? |
p->maxrmargin - p->viscol - vbl : 0; |
p->maxrmargin - p->viscol - vbl : 0; |
|
|
/* |
/* |
* Figure out how much text will fit in the field. |
* Figure out how much text will fit in the field. |
* If there is whitespace only, print nothing. |
* If there is whitespace only, print nothing. |
* Otherwise, print the field content. |
|
*/ |
*/ |
|
|
term_fill(p, &nbr, &vbr, vtarget); |
term_fill(p, &nbr, &vbr, |
|
p->flags & TERMP_BRNEVER ? SIZE_MAX : vtarget); |
if (nbr == 0) |
if (nbr == 0) |
break; |
break; |
|
|
term_field(p, vbl, nbr, vbr, vtarget); |
/* |
|
* With the CENTER or RIGHT flag, increase the indentation |
|
* to center the text between the left and right margins |
|
* or to adjust it to the right margin, respectively. |
|
*/ |
|
|
|
if (vbr < vtarget) { |
|
if (p->flags & TERMP_CENTER) |
|
vbl += (vtarget - vbr) / 2; |
|
else if (p->flags & TERMP_RIGHT) |
|
vbl += vtarget - vbr; |
|
} |
|
|
|
/* Finally, print the field content. */ |
|
|
|
term_field(p, vbl, nbr); |
|
|
/* |
/* |
* If there is no text left in the field, exit the loop. |
* If there is no text left in the field, exit the loop. |
* If the BRTRSP flag is set, consider trailing |
* If the BRTRSP flag is set, consider trailing |
Line 267 term_fill(struct termp *p, size_t *nbr, size_t *vbr, s |
|
Line 281 term_fill(struct termp *p, size_t *nbr, size_t *vbr, s |
|
case ASCII_BREAK: |
case ASCII_BREAK: |
vn = vis; |
vn = vis; |
break; |
break; |
|
default: |
|
abort(); |
} |
} |
/* Can break at the end of a word. */ |
/* Can break at the end of a word. */ |
if (breakline || vn > vtarget) |
if (breakline || vn > vtarget) |
Line 329 term_fill(struct termp *p, size_t *nbr, size_t *vbr, s |
|
Line 345 term_fill(struct termp *p, size_t *nbr, size_t *vbr, s |
|
/* |
/* |
* Print the contents of one field |
* Print the contents of one field |
* with an indentation of vbl visual columns, |
* with an indentation of vbl visual columns, |
* an input string length of nbr characters, |
* and an input string length of nbr characters. |
* an output width of vbr visual columns, |
|
* and a desired field width of vtarget visual columns. |
|
*/ |
*/ |
static void |
static void |
term_field(struct termp *p, size_t vbl, size_t nbr, size_t vbr, size_t vtarget) |
term_field(struct termp *p, size_t vbl, size_t nbr) |
{ |
{ |
size_t ic; /* Character position in the input buffer. */ |
size_t ic; /* Character position in the input buffer. */ |
size_t vis; /* Visual position of the current character. */ |
size_t vis; /* Visual position of the current character. */ |
Line 360 term_field(struct termp *p, size_t vbl, size_t nbr, si |
|
Line 374 term_field(struct termp *p, size_t vbl, size_t nbr, si |
|
continue; |
continue; |
case ' ': |
case ' ': |
case ASCII_NBRSP: |
case ASCII_NBRSP: |
vbl++; |
dv = (*p->width)(p, ' '); |
vis++; |
vbl += dv; |
|
vis += dv; |
continue; |
continue; |
default: |
default: |
break; |
break; |
Line 575 term_word(struct termp *p, const char *word) |
|
Line 590 term_word(struct termp *p, const char *word) |
|
uc = *seq; |
uc = *seq; |
break; |
break; |
case ESCAPE_FONTBOLD: |
case ESCAPE_FONTBOLD: |
|
case ESCAPE_FONTCB: |
term_fontrepl(p, TERMFONT_BOLD); |
term_fontrepl(p, TERMFONT_BOLD); |
continue; |
continue; |
case ESCAPE_FONTITALIC: |
case ESCAPE_FONTITALIC: |
|
case ESCAPE_FONTCI: |
term_fontrepl(p, TERMFONT_UNDER); |
term_fontrepl(p, TERMFONT_UNDER); |
continue; |
continue; |
case ESCAPE_FONTBI: |
case ESCAPE_FONTBI: |
term_fontrepl(p, TERMFONT_BI); |
term_fontrepl(p, TERMFONT_BI); |
continue; |
continue; |
case ESCAPE_FONT: |
case ESCAPE_FONT: |
case ESCAPE_FONTCW: |
case ESCAPE_FONTCR: |
case ESCAPE_FONTROMAN: |
case ESCAPE_FONTROMAN: |
term_fontrepl(p, TERMFONT_NONE); |
term_fontrepl(p, TERMFONT_NONE); |
continue; |
continue; |
Line 611 term_word(struct termp *p, const char *word) |
|
Line 628 term_word(struct termp *p, const char *word) |
|
encode(p, "utf8", 4); |
encode(p, "utf8", 4); |
continue; |
continue; |
case ESCAPE_HORIZ: |
case ESCAPE_HORIZ: |
|
if (p->flags & TERMP_BACKAFTER) { |
|
p->flags &= ~TERMP_BACKAFTER; |
|
continue; |
|
} |
if (*seq == '|') { |
if (*seq == '|') { |
seq++; |
seq++; |
uc = -p->col; |
uc = -p->col; |
Line 619 term_word(struct termp *p, const char *word) |
|
Line 640 term_word(struct termp *p, const char *word) |
|
if (a2roffsu(seq, &su, SCALE_EM) == NULL) |
if (a2roffsu(seq, &su, SCALE_EM) == NULL) |
continue; |
continue; |
uc += term_hen(p, &su); |
uc += term_hen(p, &su); |
if (uc > 0) |
if (uc >= 0) { |
while (uc-- > 0) |
while (uc > 0) { |
bufferc(p, ASCII_NBRSP); |
uc -= term_len(p, 1); |
else if (p->col > (size_t)(-uc)) |
if (p->flags & TERMP_BACKBEFORE) |
|
p->flags &= ~TERMP_BACKBEFORE; |
|
else |
|
bufferc(p, ASCII_NBRSP); |
|
} |
|
continue; |
|
} |
|
if (p->flags & TERMP_BACKBEFORE) { |
|
p->flags &= ~TERMP_BACKBEFORE; |
|
assert(p->col > 0); |
|
p->col--; |
|
} |
|
if (p->col >= (size_t)(-uc)) { |
p->col += uc; |
p->col += uc; |
else { |
} else { |
uc += p->col; |
uc += p->col; |
p->col = 0; |
p->col = 0; |
if (p->tcol->offset > (size_t)(-uc)) { |
if (p->tcol->offset > (size_t)(-uc)) { |