diff options
author | Ingo Schwarze <schwarze@openbsd.org> | 2015-04-04 17:47:18 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@openbsd.org> | 2015-04-04 17:47:18 +0000 |
commit | 11d090857365b38952fcebea7015e2d8b3bcf3e9 (patch) | |
tree | 28e4ba261ce74b17ecacf6a8079735596f69116f /term_ascii.c | |
parent | 1eb78526299027f34b6c7cc779729565d0c752aa (diff) | |
download | mandoc-11d090857365b38952fcebea7015e2d8b3bcf3e9.tar.gz |
Rounding rules for horizontal scaling widths are more complicated.
There is a first rounding to basic units on the input side.
After that, rounding rules differ between requests and macros.
Requests round to the nearest possible character position.
Macros round to the next character position to the left.
Implement that by changing the return value of term_hspan()
to basic units and leaving the second scaling and rounding stage
to the formatters instead of doing it in the terminal handler.
Improves for example argtable2(3).
Diffstat (limited to 'term_ascii.c')
-rw-r--r-- | term_ascii.c | 42 |
1 files changed, 18 insertions, 24 deletions
diff --git a/term_ascii.c b/term_ascii.c index cbc9c9ea..908f3182 100644 --- a/term_ascii.c +++ b/term_ascii.c @@ -40,7 +40,7 @@ static struct termp *ascii_init(enum termenc, const struct mchars *, const struct manoutput *); -static double ascii_hspan(const struct termp *, +static int ascii_hspan(const struct termp *, const struct roffsu *); static size_t ascii_width(const struct termp *, int); static void ascii_advance(struct termp *, size_t); @@ -48,7 +48,7 @@ static void ascii_begin(struct termp *); static void ascii_end(struct termp *); static void ascii_endline(struct termp *); static void ascii_letter(struct termp *, int); -static void ascii_setwidth(struct termp *, int, size_t); +static void ascii_setwidth(struct termp *, int, int); #if HAVE_WCHAR static void locale_advance(struct termp *, size_t); @@ -137,15 +137,16 @@ locale_alloc(const struct mchars *mchars, const struct manoutput *outopts) } static void -ascii_setwidth(struct termp *p, int iop, size_t width) +ascii_setwidth(struct termp *p, int iop, int width) { + width /= 24; p->rmargin = p->defrmargin; if (iop > 0) p->defrmargin += width; else if (iop == 0) - p->defrmargin = width ? width : p->lastrmargin; - else if (p->defrmargin > width) + p->defrmargin = width ? (size_t)width : p->lastrmargin; + else if (p->defrmargin > (size_t)width) p->defrmargin -= width; else p->defrmargin = 0; @@ -218,52 +219,45 @@ ascii_advance(struct termp *p, size_t len) putchar(' '); } -static double +static int ascii_hspan(const struct termp *p, const struct roffsu *su) { double r; - /* - * Approximate based on character width. - * None of these will be actually correct given that an inch on - * the screen depends on character size, terminal, etc., etc. - */ switch (su->unit) { case SCALE_BU: - r = su->scale * 10.0 / 240.0; + r = su->scale; break; case SCALE_CM: - r = su->scale * 10.0 / 2.54; + r = su->scale * 240.0 / 2.54; break; case SCALE_FS: - r = su->scale * 2730.666; + r = su->scale * 65536.0; break; case SCALE_IN: - r = su->scale * 10.0; + r = su->scale * 240.0; break; case SCALE_MM: - r = su->scale / 100.0; + r = su->scale * 0.24; break; + case SCALE_VS: + /* FALLTHROUGH */ case SCALE_PC: - r = su->scale * 10.0 / 6.0; + r = su->scale * 40.0; break; case SCALE_PT: - r = su->scale * 10.0 / 72.0; - break; - case SCALE_VS: - r = su->scale * 2.0 - 1.0; + r = su->scale * 10.0 / 3.0; break; case SCALE_EN: /* FALLTHROUGH */ case SCALE_EM: - r = su->scale; + r = su->scale * 24.0; break; default: abort(); /* NOTREACHED */ } - - return(r); + return(r > 0.0 ? r + 0.01 : r - 0.01); } const char * |