tech@mandoc.bsd.lv
 help / color / mirror / Atom feed
From: Ingo Schwarze <schwarze@usta.de>
To: Kristaps Dzonsons <kristaps@bsd.lv>
Cc: tech@mdocml.bsd.lv
Subject: Re: \w'blah'u issues (really: 'u' scaling width)
Date: Sat, 9 Aug 2014 22:41:26 +0200	[thread overview]
Message-ID: <20140809204126.GG30999@iris.usta.de> (raw)
In-Reply-To: <53E653F4.2030402@bsd.lv>

Hi Kristaps,

my suspicion is that some cleanup is required with respect to scaling
units.  So far, i never looked closely at that part.

Kristaps Dzonsons wrote on Sat, Aug 09, 2014 at 07:01:40PM +0200:

> Earlier I mentioned, as an aside, that OpenGL manuals look bad.  Try
> rendering gluPerspective to see what I mean.  (Attached.)
> 
> I tracked this down to the following:
> 
> .SH PARAMETERS
> .TP \w'\fIaspect\fP\ \ 'u
> \f2fovy\fP
> Specifies the field of view angle, in degrees, in the \f2y\fP direction.
> .TP
> \f2aspect\fP
> 
> Note that the width of the TP head is being set to the contents of
> \w'xxx'.  So this should be interpreted as
> 
> .Tp <width of "aspect  ">u
> 
> which should amount to 8 character widths.
> 
> However, in roff.c:630, we multiply this width by 24.  As a result,
> everything's wonky.  (8 * 24 = a long line)
> 
> At first I thought that we should just yank the 24.  But in running
> a little test, it seems that the \w'' doesn't calculate the string
> width in characters, but in magic internal units.

The terminus technicus is "basic unit", see the Heirloom manual for
details.  It is device-specific, defined by the "res" entry in the
DESC file.  For all terminal devices, including -Tascii, -Tlatin,
-Tutf8, -Tlocale, -Thtml, -Txhtml, 240 basic units = 1 inch.
For -Tps and -Tpdf, 72000 basic units = 1 inch.

> So it's not that we shouldn't multiply by 24,

With the current architecture, roff.c cannot do the right thing
since it doesn't know about the output device and mustn't care.
On the other hand, it cannot defer expansion to the formatters
because \w can be used in numerical expressions, register
assignments and .if conditionals, which the formatters do not
have access to.

So the best thing roff.c can do is assume terminal output.
In that case, 10n = 1in hence 1n = 24u, yes.

> but instead that the "u" scaling unit should *divide* by 24.

Looking at ascii_hspan() in term_ascii.c, i must say the comment
about eyeballing is scary.  We want to convert from various units
to "n".  Why not just put the exact numbers?  That would be:

  /* inch-based */
  SCALE_IN:  * 10.0        /* ok */
  SCALE_PC:  * 10.0/6.0    /* ok */
  SCALE_PT:  * 10.0/72.0   /* ok */
  SCALE_BU:  * 10.0/240.0  /* missing indeed */
  SCALE_CM:  * 10.0/2.54   /* slightly off */

  /* character-based */
  SCALE_EN:  * 1.0         /* ok */
  SCALE_EM:  * 1.0         /* ok */
  SCALE_MM:  * 1.0/100.0   /* completely wrong */

The function ps_hspan() wants to convert various units to points.
The exact values are:

  SCALE_IN:  * 72.0        /* ok */
  SCALE_PC:  * 12.0        /* ok */
  SCALE_PT:  * 1.0         /* completely wrong */
  SCALE_BU:  * 72.0/240.0  /* missing; *0.3, not /3.0 as you suggest */
  SCALE_CM:  * 72.0/2.54   /* approximately right */

The case SCALE_MM must be the same as SCALE_EM, but with an
additional factor of * 100.0.  MM is *not* millimeter!

Summarizing in-line:

> Index: term_ps.c
> ===================================================================
> RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/term_ps.c,v
> retrieving revision 1.62
> diff -u -p -r1.62 term_ps.c
> --- term_ps.c	1 Aug 2014 19:25:52 -0000	1.62
> +++ term_ps.c	9 Aug 2014 16:59:03 -0000
> @@ -1145,6 +1145,9 @@ ps_hspan(const struct termp *p, const st
>  	case SCALE_VS:
>  		r = su->scale * p->ps->lineheight;
>  		break;
> +	case SCALE_BU:
> +		r = PNT2AFM(p, su->scale / 3.0);

                r = PNT2AFM(p, su->scale * 0.3);

would seem right, and PT and CM should also be corrected.

> +		break;
>  	default:
>  		r = su->scale;
>  		break;
> Index: term_ascii.c
> ===================================================================
> RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/term_ascii.c,v
> retrieving revision 1.27
> diff -u -p -r1.27 term_ascii.c
> --- term_ascii.c	1 Aug 2014 19:25:52 -0000	1.27
> +++ term_ascii.c	9 Aug 2014 16:59:04 -0000
> @@ -255,6 +255,9 @@ ascii_hspan(const struct termp *p, const
>  	case SCALE_VS:
>  		r = su->scale * 2.0 - 1.0;
>  		break;
> +	case SCALE_BU:
> +		r = su->scale / 24.0;
> +		break;

Yes, and MM and CM should also be corrected.

>  	default:
>  		r = su->scale;
>  		break;
> Index: term.c
> ===================================================================
> RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/term.c,v
> retrieving revision 1.226
> diff -u -p -r1.226 term.c
> --- term.c	1 Aug 2014 19:38:29 -0000	1.226
> +++ term.c	9 Aug 2014 16:59:04 -0000
> @@ -786,6 +786,9 @@ term_vspan(const struct termp *p, const 
>  	case SCALE_VS:
>  		r = su->scale;
>  		break;
> +	case SCALE_BU:
> +		r = su->scale / 24.0;
> +		break;
>  	default:
>  		r = su->scale - 1.0;
>  		break;

No, here you want to convert to pica (1/6 inch, 12 points, 40u).
So that should be:

  /* inch-based */
  SCALE_IN:  * 6.0         /* ok */
  SCALE_PC:  * 1.0         /* ok */
  SCALE_PT:  / 12.0        /* wrong */
  SCALE_BU:  * 6.0/240.0   /* missing; /40.0, not /24.0 */
  SCALE_CM:  * 6.0/2.54    /* slightly off */

  /* character-based */
  SCALE_EN:  * 6.0/10.0    /* wrong */
  SCALE_EM:  * 6.0/10.0    /* wrong */
  SCALE_MM:  * 6.0/1000.0  /* completely wrong */

> Index: html.c
> ===================================================================
> RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/html.c,v
> retrieving revision 1.159
> diff -u -p -r1.159 html.c
> --- html.c	23 Jul 2014 15:00:08 -0000	1.159
> +++ html.c	9 Aug 2014 16:59:04 -0000
> @@ -761,6 +761,8 @@ bufcat_su(struct html *h, const char *p,
>  	v = su->scale;
>  	if (SCALE_MM == su->unit && 0.0 == (v /= 100.0))
>  		v = 1.0;
> +	if (SCALE_BU == su->unit)
> +		v /= 24.0;
>  
>  	bufcat_fmt(h, "%s: %.2f%s;", p, v, roffscales[su->unit]);
>  }

Yes.

Yours,
  Ingo
--
 To unsubscribe send an email to tech+unsubscribe@mdocml.bsd.lv

  reply	other threads:[~2014-08-09 20:42 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-08-09 17:01 Kristaps Dzonsons
2014-08-09 20:41 ` Ingo Schwarze [this message]
2014-08-12  1:04   ` Kristaps Dzonsons
2014-08-12  2:43     ` Ingo Schwarze

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20140809204126.GG30999@iris.usta.de \
    --to=schwarze@usta.de \
    --cc=kristaps@bsd.lv \
    --cc=tech@mdocml.bsd.lv \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).