aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2015-04-04 17:47:18 +0000
committerIngo Schwarze <schwarze@openbsd.org>2015-04-04 17:47:18 +0000
commita203fd4e6f05d56d51d63d78b0357f1c67ffec39 (patch)
treeed23dfa1c237f1cd01f66b96ab8912beb1bcd018
parentec66e073f559e3a2d8c56fd67060b2ccde12788a (diff)
downloadmandoc-a203fd4e6f05d56d51d63d78b0357f1c67ffec39.tar.gz
mandoc-a203fd4e6f05d56d51d63d78b0357f1c67ffec39.tar.zst
mandoc-a203fd4e6f05d56d51d63d78b0357f1c67ffec39.zip
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).
-rw-r--r--man_term.c12
-rw-r--r--mdoc_term.c4
-rw-r--r--term.c12
-rw-r--r--term.h6
-rw-r--r--term_ascii.c44
-rw-r--r--term_ps.c16
6 files changed, 44 insertions, 50 deletions
diff --git a/man_term.c b/man_term.c
index 8272456c..93b664a9 100644
--- a/man_term.c
+++ b/man_term.c
@@ -1,4 +1,4 @@
-/* $Id: man_term.c,v 1.174 2015/04/04 11:44:43 schwarze Exp $ */
+/* $Id: man_term.c,v 1.175 2015/04/04 17:47:18 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -427,7 +427,7 @@ pre_in(DECL_ARGS)
if ( ! a2roffsu(++cp, &su, SCALE_EN))
return(0);
- v = term_hspan(p, &su);
+ v = (term_hspan(p, &su) + 11) / 24;
if (less < 0)
p->offset -= p->offset > v ? v : p->offset;
@@ -512,7 +512,7 @@ pre_HP(DECL_ARGS)
if ((nn = n->parent->head->child) != NULL &&
a2roffsu(nn->string, &su, SCALE_EN)) {
- len = term_hspan(p, &su);
+ len = term_hspan(p, &su) / 24;
if (len < 0 && (size_t)(-len) > mt->offset)
len = -mt->offset;
else if (len > SHRT_MAX)
@@ -597,7 +597,7 @@ pre_IP(DECL_ARGS)
if ((nn = n->parent->head->child) != NULL &&
(nn = nn->next) != NULL &&
a2roffsu(nn->string, &su, SCALE_EN)) {
- len = term_hspan(p, &su);
+ len = term_hspan(p, &su) / 24;
if (len < 0 && (size_t)(-len) > mt->offset)
len = -mt->offset;
else if (len > SHRT_MAX)
@@ -679,7 +679,7 @@ pre_TP(DECL_ARGS)
if ((nn = n->parent->head->child) != NULL &&
nn->string != NULL && ! (MAN_LINE & nn->flags) &&
a2roffsu(nn->string, &su, SCALE_EN)) {
- len = term_hspan(p, &su);
+ len = term_hspan(p, &su) / 24;
if (len < 0 && (size_t)(-len) > mt->offset)
len = -mt->offset;
else if (len > SHRT_MAX)
@@ -868,7 +868,7 @@ pre_RS(DECL_ARGS)
n = n->parent->head;
n->aux = SHRT_MAX + 1;
if (n->child != NULL && a2roffsu(n->child->string, &su, SCALE_EN))
- n->aux = term_hspan(p, &su);
+ n->aux = term_hspan(p, &su) / 24;
if (n->aux < 0 && (size_t)(-n->aux) > mt->offset)
n->aux = -mt->offset;
else if (n->aux > SHRT_MAX)
diff --git a/mdoc_term.c b/mdoc_term.c
index 44b03b5c..cd27731a 100644
--- a/mdoc_term.c
+++ b/mdoc_term.c
@@ -1,4 +1,4 @@
-/* $Id: mdoc_term.c,v 1.316 2015/04/02 23:48:20 schwarze Exp $ */
+/* $Id: mdoc_term.c,v 1.317 2015/04/04 17:47:18 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010, 2012-2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -533,7 +533,7 @@ a2width(const struct termp *p, const char *v)
SCALE_HS_INIT(&su, term_strlen(p, v));
su.scale /= term_strlen(p, "0");
}
- return(term_hspan(p, &su));
+ return(term_hspan(p, &su) / 24);
}
/*
diff --git a/term.c b/term.c
index 6476b0e7..68f3ea04 100644
--- a/term.c
+++ b/term.c
@@ -1,4 +1,4 @@
-/* $Id: term.c,v 1.246 2015/04/02 23:48:20 schwarze Exp $ */
+/* $Id: term.c,v 1.247 2015/04/04 17:47:18 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -619,8 +619,7 @@ void
term_setwidth(struct termp *p, const char *wstr)
{
struct roffsu su;
- size_t width;
- int iop;
+ int iop, width;
iop = 0;
width = 0;
@@ -831,11 +830,12 @@ term_vspan(const struct termp *p, const struct roffsu *su)
return(ri < 66 ? ri : 1);
}
+/*
+ * Convert a scaling width to basic units, rounding down.
+ */
int
term_hspan(const struct termp *p, const struct roffsu *su)
{
- double v;
- v = (*p->hspan)(p, su);
- return(v > 0.0 ? v + 0.0005 : v - 0.0005);
+ return((*p->hspan)(p, su));
}
diff --git a/term.h b/term.h
index ab34717b..bda7f7da 100644
--- a/term.h
+++ b/term.h
@@ -1,4 +1,4 @@
-/* $Id: term.h,v 1.112 2015/04/02 23:48:20 schwarze Exp $ */
+/* $Id: term.h,v 1.113 2015/04/04 17:47:18 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2011-2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -95,9 +95,9 @@ struct termp {
void (*end)(struct termp *);
void (*endline)(struct termp *);
void (*advance)(struct termp *, size_t);
- void (*setwidth)(struct termp *, int, size_t);
+ void (*setwidth)(struct termp *, int, int);
size_t (*width)(const struct termp *, int);
- double (*hspan)(const struct termp *,
+ int (*hspan)(const struct termp *,
const struct roffsu *);
const void *argf; /* arg for headf/footf */
struct termp_ps *ps;
diff --git a/term_ascii.c b/term_ascii.c
index f217b9a4..7abbb91f 100644
--- a/term_ascii.c
+++ b/term_ascii.c
@@ -1,4 +1,4 @@
-/* $Id: term_ascii.c,v 1.44 2015/03/27 21:33:20 schwarze Exp $ */
+/* $Id: term_ascii.c,v 1.45 2015/04/04 17:47:18 schwarze Exp $ */
/*
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -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 *
diff --git a/term_ps.c b/term_ps.c
index 961de1b0..bd86d791 100644
--- a/term_ps.c
+++ b/term_ps.c
@@ -1,4 +1,4 @@
-/* $Id: term_ps.c,v 1.73 2015/03/27 21:33:20 schwarze Exp $ */
+/* $Id: term_ps.c,v 1.74 2015/04/04 17:47:18 schwarze Exp $ */
/*
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -87,7 +87,7 @@ struct termp_ps {
size_t pdfobjsz; /* size of pdfobjs */
};
-static double ps_hspan(const struct termp *,
+static int ps_hspan(const struct termp *,
const struct roffsu *);
static size_t ps_width(const struct termp *, int);
static void ps_advance(struct termp *, size_t);
@@ -106,7 +106,7 @@ __attribute__((__format__ (__printf__, 2, 3)))
static void ps_printf(struct termp *, const char *, ...);
static void ps_putchar(struct termp *, char);
static void ps_setfont(struct termp *, enum termfont);
-static void ps_setwidth(struct termp *, int, size_t);
+static void ps_setwidth(struct termp *, int, int);
static struct termp *pspdf_alloc(const struct mchars *,
const struct manoutput *);
static void pdf_obj(struct termp *, size_t);
@@ -620,7 +620,7 @@ pspdf_alloc(const struct mchars *mchars, const struct manoutput *outopts)
}
static void
-ps_setwidth(struct termp *p, int iop, size_t width)
+ps_setwidth(struct termp *p, int iop, int width)
{
size_t lastwidth;
@@ -628,8 +628,8 @@ ps_setwidth(struct termp *p, int iop, size_t width)
if (iop > 0)
p->ps->width += width;
else if (iop == 0)
- p->ps->width = width ? width : p->ps->lastwidth;
- else if (p->ps->width > width)
+ p->ps->width = width ? (size_t)width : p->ps->lastwidth;
+ else if (p->ps->width > (size_t)width)
p->ps->width -= width;
else
p->ps->width = 0;
@@ -1273,7 +1273,7 @@ ps_width(const struct termp *p, int c)
return((size_t)fonts[(int)TERMFONT_NONE].gly[c].wx);
}
-static double
+static int
ps_hspan(const struct termp *p, const struct roffsu *su)
{
double r;
@@ -1325,7 +1325,7 @@ ps_hspan(const struct termp *p, const struct roffsu *su)
break;
}
- return(r);
+ return(r * 24.0);
}
static void