[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [groff] gropdf(1) Has Ugly Thick Lines by Default.
From: |
Deri |
Subject: |
Re: [groff] gropdf(1) Has Ugly Thick Lines by Default. |
Date: |
Mon, 30 Jul 2018 16:57:29 +0100 |
On Monday, 30 July 2018 13:23:04 BST Ralph Corderoy wrote:
> Hi Deri,
>
> Thanks for the very prompt reply. Sorry if I seemed grumpy; just time
> pressure from deviating down another rabbit hole. :-)
>
Hi Ralph,
I did not notice the grumps, I'm still looking for Alice too! :-)
> > One difference between postscript and pdf is that ps has page origin
> > at the top left whereas pdf uses the bottom left. Since the page is A4
> > the top of the page is 842 points so gropdf using 837.5 is expected.
>
> An aside, is it understood that A4 is precisely 842 points at 1/72th
> inch in these file formats, that not being 297 mm?
>
I found this in ps.cpp:-
int ps_printer::media_width()
{
/*
* NOTE:
* Although paper size is defined as real numbers, it seems to be
* a common convention to round to the nearest postscript unit.
* For example, a4 is really 595.276 by 841.89 but we use 595 by 842.
*
* This is probably a good compromise, especially since the
* Postscript definition specifies that media
* matching should be done within a tolerance of 5 units.
*/
return int(user_paper_width ? user_paper_width*72.0 + 0.5
: font::paperwidth*72.0/font::res + 0.5);
}
So I took this to mean that whole points were Ok for paper sizes.
> >
> > It appears that the difference in coordinates is being introduced by
> > conversion from postscript to pdf!
>
> Yes. This is all groff 1.22.3-7, and ghostscript 9.23-1, I forgot to
> say.
>
> I did wonder if it was from the PDF to QDF by qpdf(1) so I slimmed down
> the table and used both `qpdf -qdf' and `mutool clean -d' to check,
> producing filenames that show the path taken.
>
> .TS
> l.
> _
> \(en
> .TE
> E
>
> grops by groff -dpaper=a4 -Tps
> line-grops.ps 77 4.5 72 4.5 DL
> line-grops-ps2pdf-pdf2ps.ps 720.25 8374.25 m 770.25
> 8374.25 l
> line-grops-ps2pdf-qpdf.qdf 720.25 8374.25 m 770.25
> 8374.25 l
> line-grops-ps2pdf-mutool.pdf 720.25 8374.25 m 770.25
> 8374.25 l
> line-grops-ps2pdf-pdf2ps-ps2pdf-mutool.pdf 720.25 8374.25 m 770.25
> 8374.25 l
>
> gropdf by groff -dpaper=a4 -Tpdf -P-d
> line-gropdf.pdf 72 837.5 m 77 837.5 l
> line-gropdf-pdf2ps.ps 720 8375 m 770 8375 l
> line-gropdf-qpdf.qdf 72 837.5 m 77 837.5 l
> line-gropdf-mutool.pdf 72 837.5 m 77 837.5 l
>
> 842 - 4.5 = 837.5 so both grops and gropdf get that right, but ps2pdf
> shifts it. Note the last grops item shows two ps2pdf steps, returning
> back to PostScript inbetween, and doesn't double-shift the line.
>
> And with a bit of guesswork, I get the same directly from the PDF from
> ps2pdf.
>
> $ LC_ALL=C egrep -boam2 '^stream|endstream' line-grops-ps2pdf.pdf
> 61:stream
> 185:endstream
> $
> $ python -c '
>
> > import zlib
> > f=open("line-grops-ps2pdf.pdf", "rb")
> > f.seek(61 + 6)
> > s=f.read(186 - (61 + 6))
> > print(zlib.decompress(s[3:], -15))
> > '
>
> ...
> 720.25 8374.25 m\n
> 770.25 8374.25 l\n
> ...
> '
> $
>
> > It does not seem to be associated with the linecaps, nor the length of
> > the line, since using a very wide (10pt) linewidth and longer line
> > does not alter the amount it is shifted.
>
> I think both grops and gropdf are consistent with their `1 setlinecap',
> round caps, and `1 setlinejoin', round corners.
>
> I altered the PostScript from grops to
>
> .4 LW
> 77 4.5 72 4.5 DL
> /F0 10/address@hidden SF<20>72 14 Q
>
> /s 20 string def
> ( ) show
> currentlinewidth s cvs show ( ) show
> currentlinecap s cvs show ( ) show
> currentlinejoin s cvs show ( ) show
>
> 0 setlinecap 0 setlinejoin
> 77 8.5 72 8.5 DL
>
> 0 Cg EP
>
> and it prints `0.4 1 1' with the two lines in a ps2pdf PDF at
>
> 720.25 8374.25 m 770.25 8374.25 l S
> 720.25 8334.25 m 770.25 8334.25 l S
>
> So setting cap and join to 0 doesn't affect the 0.25 offset.
>
> You mentioned switching from `s' to `S' to `closepath' the line. How
> does closing the path affect the rendering of a simple straight line
> that's not a `circuit'?
When the discussion on the list was concerning changing line caps within pic
using the postscript special command \X ps: exec 0 setlinecap, I tried this
using -T pdf, which is documented to recognise this "special", and it did not
work, but changing the pdf operator for a line to "S" caused the correct line
caps to appear, my assumption is that if a path is never closed, i.e. it is
only comprised of sub-paths, at some point, part of the clean up is to
stroke/fill any open sub paths, but using the graphics state at the time of the
clean up, i.e using the line caps active for the second sub path.
.
> Whilst editing the grops PostScript I noticed
>
> % x y x y -
> /DL{ SN moveto SN lineto stroke }bind def
>
> and wonder what SN was doing.
>
> % x y - x' y'
> /SN{
> transform
> .25 sub exch
> .25 sub exch
> round .25 add exch
> round .25 add exch
> itransform
> }bind def
>
> It seems odd to subtract 0.25 before rounding to the nearest integer
> rather than 0.5, but perhaps it's accomodating the transform?
>
> Another edit of the PostScript to see the values; the output is in the
> comments.
>
> .4 LW
> 77 4.5 72 4.5 DL
> /F0 10/address@hidden SF<20>72 14 Q
>
> /space { ( ) show } def
> /s 20 string def
> /printpair { exch s cvs show (,) show s cvs show } def
> space
> 1 1 transform printpair space % 1.20228,1.0135
> 77 4.5 SN printpair space % 76.7291,4.52372
> 72 4.5 SN printpair space % 71.7386,4.52372
>
> 0 Cg EP
>
> I'm now a bit bemused and confused from staring at it all for a while.
> I don't think I can hassle the GhostScript folks yet because
I too looked at SN and thought, I need Tadziu! (Much more knowledgeable on
postscript than me). I don't understand its purpose. I agree, the change in
values appears to be from the SN call in postscript, and gs is just executing
it as it should.
Cheers
Deri
> $ cat simple.ps
> %
>
> 0.4 setlinewidth 0 setlinecap 0 setlinejoin
> 100 100 moveto 100 0 rlineto stroke
> showpage
> $
> $ ps2pdf simple.ps
> $ qpdf -qdf simple.pdf simple.qdf
> $
>
> leaves simple.qdf spot on:
>
> stream
> q 0.1 0 0 0.1 0 0 cm
> /R7 gs
> 4 w
> 0 G
> 1000 1000 m
> 2000 1000 l
> S
> Q
> endstream