source@mandoc.bsd.lv
 help / color / mirror / Atom feed
* mdocml: Rounding rules for horizontal scaling widths are more
@ 2015-04-04 17:47 schwarze
  0 siblings, 0 replies; only message in thread
From: schwarze @ 2015-04-04 17:47 UTC (permalink / raw)
  To: source

Log Message:
-----------
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).

Modified Files:
--------------
    mdocml:
        man_term.c
        mdoc_term.c
        term.c
        term.h
        term_ascii.c
        term_ps.c

Revision Data
-------------
Index: term.h
===================================================================
RCS file: /home/cvs/mdocml/mdocml/term.h,v
retrieving revision 1.112
retrieving revision 1.113
diff -Lterm.h -Lterm.h -u -p -r1.112 -r1.113
--- term.h
+++ term.h
@@ -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;
Index: man_term.c
===================================================================
RCS file: /home/cvs/mdocml/mdocml/man_term.c,v
retrieving revision 1.174
retrieving revision 1.175
diff -Lman_term.c -Lman_term.c -u -p -r1.174 -r1.175
--- man_term.c
+++ man_term.c
@@ -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)
Index: term_ascii.c
===================================================================
RCS file: /home/cvs/mdocml/mdocml/term_ascii.c,v
retrieving revision 1.44
retrieving revision 1.45
diff -Lterm_ascii.c -Lterm_ascii.c -u -p -r1.44 -r1.45
--- term_ascii.c
+++ 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
 }
 
 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 le
 		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 *
Index: term.c
===================================================================
RCS file: /home/cvs/mdocml/mdocml/term.c,v
retrieving revision 1.246
retrieving revision 1.247
diff -Lterm.c -Lterm.c -u -p -r1.246 -r1.247
--- term.c
+++ term.c
@@ -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 
 	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));
 }
Index: term_ps.c
===================================================================
RCS file: /home/cvs/mdocml/mdocml/term_ps.c,v
retrieving revision 1.73
retrieving revision 1.74
diff -Lterm_ps.c -Lterm_ps.c -u -p -r1.73 -r1.74
--- term_ps.c
+++ term_ps.c
@@ -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
 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,
 }
 
 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, si
 	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 st
 		break;
 	}
 
-	return(r);
+	return(r * 24.0);
 }
 
 static void
Index: mdoc_term.c
===================================================================
RCS file: /home/cvs/mdocml/mdocml/mdoc_term.c,v
retrieving revision 1.316
retrieving revision 1.317
diff -Lmdoc_term.c -Lmdoc_term.c -u -p -r1.316 -r1.317
--- mdoc_term.c
+++ mdoc_term.c
@@ -533,7 +533,7 @@ a2width(const struct termp *p, const cha
 		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);
 }
 
 /*
--
 To unsubscribe send an email to source+unsubscribe@mdocml.bsd.lv

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2015-04-04 17:47 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-04-04 17:47 mdocml: Rounding rules for horizontal scaling widths are more schwarze

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).