[cairo] Endless loop in _cairo_stroker_line_to_dashed()

Hans Breuer hans at breuer.org
Sun Jun 28 04:32:27 PDT 2009

At 28.06.2009 12:24, Chris Wilson wrote:
> On Sun, 2009-06-28 at 12:00 +0200, Hans Breuer wrote:
>> The loop "while (remain)" is only left if 'remain' evaluates to exactly 
>> zero, but in the given case it never gets closer than 5.3172935301562e-315.
>> Furher loop cycles don't modify that value anymore. 
>> _cairo_stroker_add_sub_edge() adds no edge due to p1==p2 (in cairo fixed 
>> oordinates). The patch below adds an additional check to leave the loop but 
>> I'm uncertain if this is the right way to fix the issue.
> Well I'm confused. If we exclude the possibility of precision-loss (it
> uses doubles through out, though still that is no guarantee) 
I think the precision-loss is exactly the problem, thus I would avoid the 
comparsion comparion of a double result to zero.

> then the
> loop should always terminate, as it essentially does:
>   while (remain) {
isn't this "while (remain!=0.0) {" ?

>     step_length = MIN (remain, dash_remain);

>     remain -= step_length;

>     dash_remain -= step_length;
no effect when subtracting two very small numbers?

>     if (dash_remain <= 0.) dash_remain=dashes[dash++];
>   }
> It would be good to have a test case for this bug. 
Yes, definitely.

> Have you managed to
> replicate this whilst tracing? I think you will need to add
> CAIRO_TRACE_FLUSH=1 to your environment to capture the last operation
> before the infinite loop. 
cairo-trace --no-file /opt/bin/dia

[... - last output on the console]

% cairo_set_line_width() called by set_linewidth() [diacairo-renderer.c:183]
0 set-line-width
% cairo_set_dash() called by set_linestyle() [diacairo-renderer.c:275]
[0.000000000000000014 0.000000000000000014] 0 set-dash
% cairo_set_line_cap() called by line_draw() [line.c:349]
//LINE_CAP_BUTT set-line-cap
% cairo_set_source_rgba() called by draw_line() [diacairo-renderer.c:357]
0.498039 0.498039 0.498039 1 set-source-rgba
28 26 m 39 26 l % cairo_stroke() called by draw_line_with_arrows() 

> (Or you can provide instructions on how I can
> reproduce this bug myself using dia, and I'll create a test case.)
Unfortunately I was not yet able to create a further reduced version of the 
   proprietary file which still enters the endless loop. But maybe the 
above is enough?


-------- Hans "at" Breuer "dot" Org -----------
Tell me what you need, and I'll tell you how to
get along without it.                -- Dilbert

More information about the cairo mailing list