Thick stroke join bug

Post any defects you find in the released or beta versions of the ImageMagick software here. Include the ImageMagick version, OS, and any command-line required to reproduce the problem. Got a patch for a bug? Post it here.
Post Reply
loris

Thick stroke join bug

Post by loris »

I think I've found a bug with drawing joins. I've searched and not seen any previous mention, so it may be new, or alternatively I may not have been using the right search words.

IM reports its version as:
Version: ImageMagick 6.3.0 11/30/06 Q16

Here is demo code:

Code: Select all

#!/usr/bin/perl -w
#demo of thick line corner drawing bug

use Image::Magick;
$image=Image::Magick->new;
$width=200;$height=200;
$image->Set(size=>"${width}x$height");
$image->ReadImage('xc:white');

$points="M40 40 H140 c80 40 -80 80 0 120H 40";
        $image->Draw(primitive=>'path',points=>$points,
            stroke=>'blue',
            strokewidth=>20,
            antialias=>'true');

$filename = "image.gif";
open(IMAGE, ">$filename");
$image->Write(file=>\*IMAGE, filename=>$filename);
close(IMAGE);
undef $image;
exit(0);
The error is at the bottom right, on the concave side of the join.
What I think is happening is that the line angles are being read from the apex of the lines to form the mitre.
The lines are then assumed to be straight, so the next line segment is drawn off parallel to this.
If the line curves away, this is a problem, it ought to track the shape.

The issue is symmetrical in that it doesn't matter which way through the join the path goes.

I hope that makes sense.

I understand that the line drawing code is particularly hairy, and also the drawing commands are a fairly low priority for you, but hope that reporting bugs is still useful.
Last edited by loris on 2007-05-24T08:59:51-07:00, edited 1 time in total.
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: Thick stroke join bug

Post by magick »

Fixing drawing problems is a priority its just one tough area to fix bugs. We'll take a look at the problem but do not have an ETA when you can expect a patch.
loris

Re: Thick stroke join bug

Post by loris »

OK, well thanks for looking.
Please let me know if you can't reproduce the problem - it occurs to me it might be affected by defaults for stroke-linejoin and/or stroke-miterlimit. I can upload a picture if necessary.

As a workaround, I was wondering about changing these settings. As you can see I'm using Perl so can't specify them directly. But is there a configuration file or something which could be modified to set these globally?
loris

Re: Thick stroke join bug

Post by loris »

Fixing drawing problems is a priority its just one tough area to fix bugs. We'll take a look at the problem but do not have an ETA when you can expect a patch.
After much consideration, I think I've found a work-around for this bug, for my purposes. I'll describe it here as it might be of use to others in the mean-time.

Basically the mitred join rendering is quite fragile. The trick is to persuade IM not to render mitres for the affected join. (The mitre settings are not accessible through the PerlMagick API.)

Generally, the answer seems to be to draw very short straight lines between your two lines.
Quite how you do this depends on your case.
I found lines shorter than 0.5 (pixels) have no effect, but I don't think relative sub-pixel position matters. You can't move away and then back again, this knackers the join.

For the code I gave above, the shape can be fixed by changing the points string to:

Code: Select all

$points="M40 40 H140 c80 40 -80 80 0 119.5 v0.5 H 40";
Edit:
It appears I spoke too soon about my case, which can have the curved lines approaching from a range of about 90 degrees. After more head-scratching, I've got another solution. Basically, draw the two lines separately, or with moves in between, which will replace the mitres by circular end-caps.
I found that IM will essentially ignore zero-length moves, sometimes even if they are absolute coordinates. So I now draw the various lines such that the two line segments of each problematic join are drawn with other line segments in between. (ie I used to do move-base, right, top, left now I do base, move-top, move-right, move-left.) Of course a fill needs to be drawn separately, beforehand.
Post Reply