Skip to content

Fix for round joins

Christian Rohlfs requested to merge chrohlfs/cairo:round-join into master

#520

Hi. Some time ago I've commented on the issue in the Inkscape's GitLab. There are two comments from me describing my research on the issue. Let me quote here the conclusion.

Scaling line width according to CTM does solve the problem. One additional detail is that scaled half line width must be greater or equal to tolerance value. Otherwise no round joins needed and we can set spline_cusp_tolerance to just -1 which will skip rounding.

Patched files I could reach: cairo-path-stroke-polygon.c and cairo-path-stroke-traps.c. Main change is this part (reference lines):

    double scaled_hlw = hypot(stroker.half_line_width * ctm->xx,
                              stroker.half_line_width * ctm->yx);

    if (scaled_hlw <= tolerance) {
        stroker.spline_cusp_tolerance = -1.0;
    } else {
        stroker.spline_cusp_tolerance = 1 - tolerance / scaled_hlw;
        stroker.spline_cusp_tolerance *= stroker.spline_cusp_tolerance;
        stroker.spline_cusp_tolerance *= 2;
        stroker.spline_cusp_tolerance -= 1;
    }

I also tried to patch cairo-path-stroke.c but unsuccessfully: some other code produces nan for a segment slope and calculation of the cos(psi) fails with crash on some tests.

This MR also changes miter join to bevel if tolerance condition is not met (if segments is being joined without rounding), for cairo-path-stroke-polygon.c. This is done to simplify computations.

Thank you.

Merge request reports