Bug 696466 - Line caps render differently in GS and Adobe Reader
Summary: Line caps render differently in GS and Adobe Reader
Status: NOTIFIED FIXED
Alias: None
Product: Ghostscript
Classification: Unclassified
Component: Graphics Library (show other bugs)
Version: 9.18
Hardware: PC Windows NT
: P2 normal
Assignee: Robin Watts
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-12-17 12:53 UTC by Zoltán
Modified: 2016-02-20 07:37 UTC (History)
0 users

See Also:
Customer: 885
Word Size: ---


Attachments
Simplified test file (454.78 KB, application/pdf)
2015-12-17 12:53 UTC, Zoltán
Details
The tiff output, note the line caps (270.73 KB, application/x-zip-compressed)
2015-12-17 12:55 UTC, Zoltán
Details
PDF with a wide stroke (4.01 KB, application/pdf)
2015-12-17 13:17 UTC, Ken Sharp
Details
PDF with a narrow stroke (4.01 KB, application/pdf)
2015-12-17 13:17 UTC, Ken Sharp
Details
three example files (1.85 KB, application/octet-stream)
2015-12-19 02:27 UTC, Ken Sharp
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Zoltán 2015-12-17 12:53:16 UTC
Created attachment 12189 [details]
Simplified test file

I’ve managed to isolate an object in this job which renders much differently compared to e.g. Acrobat Reader, presumable there should be line cap and miter problems mut I haven’t enough time now to pay more attention for the PDF-s internal structure, please check what could happen here.

The problem can be replicated on any resolutions, using trivial drivers like tiff24nc.
Comment 1 Zoltán 2015-12-17 12:55:49 UTC
Created attachment 12190 [details]
The tiff output, note the line caps
Comment 2 Marcos H. Woehrmann 2015-12-17 13:10:06 UTC
Other PDF viewers I tried, muPDF and Apple Preview, match Acrobat's output.

BTW, here's the command line I'm using for testing:

  bin/gs -sDEVICE=tiff24nc -o test.tif -r300 ./Prueba_Stroke.pdf
Comment 3 Ken Sharp 2015-12-17 13:17:11 UTC
Doesn't appear to be anything to do with line caps or miter as such (possibly we may be hitting a miter limit when we should not though). The path is drawn with a 'B' operation which means stroke and fill the path, and it uses quite a wide stroke to do so.

I've attached 2 smaller files which uses the same path but only stroke it, one uses a narrow stroke width, the other uses a wide stroke (as per the original). This clearly shows that its the width of the stroke which is being clipped, rather than the path itself.

The other possibility is that its the line join which is causing a problem.
Comment 4 Ken Sharp 2015-12-17 13:17:37 UTC
Created attachment 12191 [details]
PDF with a wide stroke
Comment 5 Ken Sharp 2015-12-17 13:17:59 UTC
Created attachment 12192 [details]
PDF with a narrow stroke
Comment 6 Marcos H. Woehrmann 2015-12-17 13:20:21 UTC
This is a regression, from 2006!

commit 19c690660efa28c2ad05b1f92bfd07a321159e75
Author:     Ray Johnston <ray.johnston@artifex.com>
AuthorDate: Thu Mar 23 19:32:06 2006 +0000
Commit:     Ray Johnston <ray.johnston@artifex.com>
CommitDate: Thu Mar 23 19:32:06 2006 +0000

    Change PDF curve rendering to use 'accurate' curves. PostScript method
    is retained for Adobe CPSI compatibility. Bug 688434.
Comment 7 Ken Sharp 2015-12-19 02:27:38 UTC
Created attachment 12193 [details]
three example files

The attached Zip contains 3 example files. There is the PostScript from Bug #688434, a very simplified example (1 lineto and a curveto) in PostScript from this report, and a PDF created from that PostScript by Ghostscript.

The original bug (688434) stated that our handling of the ellipse start and end was 'compatible to CPSI'. While that may be true, I don't think its a reasonable standpoint, it doesn't look like what was intended by the PostScript (the start and end points are co-incident). This is an artefact of curve flattening.

Turning on 'setaccuratecurves' resolves this, but introduces the clipping problem with the large stroke width.

IMO setaccuratecurves probably ought to default true (maybe false for CPSIMode), and this bug with the mitre should be fixed.

I tried this on another PostScript RIP and it was able to close the ellipse *and* correctly draw the mitres here. I believe we should do so as well, with PostScript *and* PDF input.
Comment 8 Robin Watts 2016-01-20 05:01:18 UTC
Ok, so several issues seem to be being raised in this bug.

Firstly, the issue shown with bug688434.pdf. This is an unclosed ellipse, where the ends are coincident (at the extreme left hand side).

The tangents to the curves forming the elipse are vertical at that point, hence a 'true' rendering of that curve should have the ends of the curves as being horizontal, hence giving the proper appearance of a closed path.

When the curves are flattened of course, the lines deviate from vertical, and so the ends of the curve tilt away from the horizontal, giving the gap seen in the current rendering.

The solution to this is to ensure that when stroking, the tangent at the ends of the curves always reflects the true direction. This is exactly what the setaccuratecurves option does, and hence I am in agreement with Ken that this should be enabled by default.

In fact, setaccuratecurves is actually more than we need. We do not require that this additional processing be done for EVERY curve we render as part of a stroke, but rather only the start/end of strokes (or dashes). If setaccuratecurves turns out to be too much of a CPU killer, then we could investigate tweaking the code so that we only do the additional processing at the end of strokes/dashes.
Comment 9 Robin Watts 2016-01-22 03:17:51 UTC
Fixed in the following commits:

commit fd63655e199fbfcda8e52c873b3a28bf27914c93
Author: Robin Watts <robin.watts@artifex.com>
Date:   Thu Jan 21 10:48:54 2016 +0000

    Enable "accurate curves" by default.

    This helps to address bug 696466 (and it's earlier related
    bug 688434).

commit e25594f98886a164f4465505595691aca8136deb
Author: Robin Watts <robin.watts@artifex.com>
Date:   Thu Jan 21 18:09:09 2016 +0000

    Bug 696466: Preliminary work on setaccuratecurves.

    If accurate curves are enabled, and the same path is filled
    and then stroked, we can get very different results when the
    flatness is high.

    This can look very odd. Ensure that we flatten paths in the
    same way for both fills and strokes when accurate curves is
    enabled.

commit 064559beaa05329b1d9e6283e6d17a8c87765e7f
Author: Robin Watts <robin.watts@artifex.com>
Date:   Wed Jan 20 20:15:42 2016 +0000

    Bug 696466: Fix incorrect line joins in strokes.

    When we flatten a path for stroking, we keep 'notes' on each
    line to tell us whether each line was present in the original
    path, or whether it was generated by the flattening process.

    We further note which lines were generated by the flattening
    process, and are NOT the first one in a given curve. We do this
    so that we can apply the 'curve join' to the start of such line
    segments.

    The "curve_join" is an optimisation to speed path drawing. When
    we've flattened a curve, it makes no sense to draw (say) a round
    join between each flattened line, because they will be almost
    parallel, and the join will be visually indistinguishable from
    a simple bevel (in most cases).

    It's still important that we draw the correct curve between any
    preceeding line and the first line in the curve though.

    Sometimes, (especially when setaccuratecurves is turned on), the
    first line in a flattened curve may be degenerate (i.e. 0 length).
    The stroker spots degenerate sections and skips them. Unfortunately
    that means it also skips the note about it being the first line
    from a curve, and the wrong join is used.

    The fix implemented here is to alter the stroker so that when
    it skips a degenerate section, it checks for the 'first line
    from an arc' flag and carries it forwards.

Only the last one is needed for the attached file to render correctly.