Bug 103840

Summary: Bug rendering lines of a certain length
Product: cairo Reporter: Matthew Khouzam <matthew.khouzam>
Component: generalAssignee: Chris Wilson <chris>
Status: RESOLVED MOVED QA Contact: cairo-bugs mailing list <cairo-bugs>
Severity: normal    
Priority: medium    
Version: unspecified   
Hardware: x86-64 (AMD64)   
OS: Linux (All)   
Whiteboard:
i915 platform: i915 features:
Attachments: Example code to generate bug
Image of the result of the program

Description Matthew Khouzam 2017-11-22 04:13:05 UTC
Created attachment 135656 [details]
Example code to generate bug

Hi, I am trying to draw lines, and the width seems to get very large when certain lines coordinates are picked.

It appears to have been brought in with 



5bc1b1f6aac108d9a3963352ad774bb4fcd69e28 is the first bad commit
commit 5bc1b1f6aac108d9a3963352ad774bb4fcd69e28
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Fri Aug 24 17:22:34 2012 +0100

    stroke: Make the incremental trapezoid stroker optionally available again
    
    Whilst it cannot handle self-intersecting strokes (which includes the
    antialias region of neighbouring lines and joints), it is about 3x
    faster to use than the more robust algorithm. As some backends delegate
    the rendering, the quality may still be preserved and so they should be
    responsible for choosing the appropriate method for generation of the
    stroke geometry.
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

It affects the java bindings and the SWT library. Here is the eclipse bug describing the problem even further.

https://bugs.eclipse.org/bugs/show_bug.cgi?id=470115
Comment 1 Matthew Khouzam 2017-11-22 04:14:04 UTC
Created attachment 135657 [details]
Image of the result of the program

The line width is supposed to be 0.5 from what I understand.
Comment 2 Matthew Khouzam 2017-11-22 04:14:40 UTC
The problem also only appears to be in the GTK backend as png backends render well.
Comment 3 Matthew Khouzam 2017-11-22 04:16:56 UTC
Systems tested on:
Ubuntu 14.04 and 16.04 64 bit with Intel, Nvidia and AMD accelerators.
Comment 4 Uli Schlachter 2017-11-22 17:37:31 UTC
Your example code just opens a gray window here, but I guess that is the expected result with a line width of 0.5? I am on Debian testing, so cairo 1.15.8. Did you test with such a new cairo version?

> It appears to have been brought in with 
> 
> 5bc1b1f6aac108d9a3963352ad774bb4fcd69e28 is the first bad commit
> commit 5bc1b1f6aac108d9a3963352ad774bb4fcd69e28
> Author: Chris Wilson <chris@chris-wilson.co.uk>
> Date:   Fri Aug 24 17:22:34 2012 +0100

The above commit is from 2012. You set the Version field of this bug to 1.10.2. That's from 2010. How can a commit introduce a bug into a version that was released two years earlier?
Comment 5 Matthew Khouzam 2017-11-22 17:44:47 UTC
Excellent question: it fails on this

libcairo2:amd64                                                                         1.13.0~20140204-0ubuntu1.1                       amd64                                            The Cairo 2D vector graphics library
Comment 6 Uli Schlachter 2017-11-22 17:57:58 UTC
> 1.13.0~20140204-0ubuntu1.1 

That's not a cairo version. See e.g. https://www.cairographics.org/news/.
Assuming the above means Ubuntu just took a random git master version, shipped it and never bothered to use a release: The only git commit on that day that I can find is 4144307dbfbe7b297135d9ea4b080cae7e06b997. The changelog and the copyright link on packages.ubuntu.com just 404, so... No idea what Ubuntu might be doing there.

Also, let me ask again: Which cairo version(s) did you try this on? See comment #4:

> Your example code just opens a gray window here, but I guess that is the
> expected result with a line width of 0.5? I am on Debian testing, so cairo
> 1.15.8. Did you test with such a new cairo version?
Comment 7 Uli Schlachter 2017-11-22 17:59:49 UTC
> Your example code just opens a gray window here

Sorry, my fault. Compiling against Gtk2 does not work for this, it needs Gtk3. Then this becomes reproducable.
Comment 8 Uli Schlachter 2017-11-22 19:17:45 UTC
I found something. The problem seems to come from `composite_traps` in `cairo-xlib-render-compositor.c`. The X11 protocol uses a 16.16 representation for traps coordinates (32 bit fixed point with 16 bit fractional part). However, the numbers that are passed in are not representable in 16.16 format. There is code for handling that (`line_exceeds_16_16()` and `project_line_x_onto_16_16`), but apparently its precision is not all that great.

This trap is passed in (it's the main part of "what is going on"; there are two other traps generated by `_cairo_traps_tessellate_convex_quad()`, but they are outside of the visible area):

> left from (200000,-0.25) to (-200000,299.75)
> right from (200000,0.25) to (-200000,300.25)
> top=0.25
> bottom=299.75

and this is the computed, supposedly equivalent trap:

> left from (2725.33,0.25) to (-3392,299.75)
> right from (3392,0.25) to (-2725.33,299.75)
> top=0.25
> bottom=299.75

If my math (and my calculator) is not wrong, the left line of the first trap has an "anti-slope" (delta x / delta y) of 400000 while the result's left line has a slope of.... about 20?

@Matthew: Try adding cairo_set_antialias(cr, CAIRO_ANTIALIAS_BEST) to your test case (btw: thanks for the nice test case!) and drawing the line once before and once afterwards (e.g. in red and blue). The results look quite different.

Now we just need someone with the time (sorry, my time for now is up) and knowledge to figure out how to fix `project_line_onto_16_16`.
Comment 9 Matthew Khouzam 2017-11-22 23:37:48 UTC
I can see that the antialias is a valid workaround in c/c++ linking to Cairo directly. On the eclipse side, it doesn't work. 

My solution on the eclipse side was to apply a Cohen Sutherland (Programmatically clip the lines), it works well. It does introduce a performance regression though. I think I will push for my solution on eclipse, as we need to support people with older libs too.

Since it's 16.16, the solution makes sense since clipping it before drawing it clamps it to realistic values.
Comment 10 GitLab Migration User 2018-08-25 13:57:39 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/cairo/cairo/issues/289.

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.