Summary: | Bézier curve is not rendered correctly | ||
---|---|---|---|
Product: | cairo | Reporter: | Martin Horák <horakm> |
Component: | general | Assignee: | Carl Worth <cworth> |
Status: | RESOLVED FIXED | QA Contact: | cairo-bugs mailing list <cairo-bugs> |
Severity: | normal | ||
Priority: | medium | ||
Version: | 1.8.0 | ||
Hardware: | All | ||
OS: | All | ||
Whiteboard: | |||
i915 platform: | i915 features: | ||
Attachments: |
Rendered output
Zoomed in, with nodes Program to generate the zoomed image |
The wrong rendering also occurs under Linux, so I suppose it is not a platform specific issue Created attachment 37785 [details] Zoomed in, with nodes (In reply to comment #1) > The wrong rendering also occurs under Linux, so I suppose it is not a platform > specific issue The problem is in cairo stroking code, but it is also present in other libraries (quartz fails in a different way when stroking the same curve, but fails anyway). In the attached image, the bezier nodes are red, green, blue, cyan. It can be seen that the bezier curve ends with the tangent directed downwards, but the stroker isn't able to get it correct, thus this seems to be a precision/accuracy problem in the stroker. The (future, not yet working, expecially for degenerate cases) stroke-to-path code will hopefully be able to handle this situations. Created attachment 37786 [details]
Program to generate the zoomed image
I briefly take a look at the code and it seems the problem in this specific case lies in incorrect decomposition of bézier curve into the separate (thick) line segments for stroking operation. The implemented decomposition algorithm (widely used and robust Casteljau) focuses on finding points on a bézier curve. In each subdivision, the difference from curve to ideal zero-thick line segment is evaluated. If the line segment diference to curve falls below a tolerance threshold, the line segment is outputted as a curve approximation. In this sense, there is nothing wrong and I assume that for filling operations, the current implementation works perfectly. However, when this decomposition (with the same error criteria) is used for stroking operation, it may miss some part of curve, where tangent is changed rapidly, although a curve approximation by an ideal line is almost perfect. In my opinion, for fixing this issue, there is no need to change the stroker or decomposition algorithm, but just update the error criteria to take into account a tangent of two points on the curve (in case the decomposition itself serves as an input to the stroking operation). 1.10 produces output like https://bugs.freedesktop.org/attachment.cgi?id=37785 which is correct. Please reopen if you can reproduce your problem with the new version. |
Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.
Created attachment 37737 [details] Rendered output Below is a code snippet and the result is attached as png file. cairo_new_sub_path( cr ); cairo_move_to( cr, 667.00, 287.75 ); cairo_curve_to( cr, 667.00, 270.50 643.50, 253.75, 643.75, 255.00 ); cairo_set_line_width( cr, 12.0 ); cairo_stroke( cr );