I've dumped out some of the Cairo calls to see how Inkscape is drawing the rectangle. It is using a series of lineto's. Converting the rectangle to a path gives exactly the same calls (as expected).
I then wrote a small C program that used the same Cairo calls. I see a change in behavior between a stroke width of 0.6 and 0.7. At 0.6, rounded corners are drawn as bevels while at 0.7 they are rendered rounded. Cairo may be attempting to optimize drawing the corners (if the two ends of the outer offset paths are less than a given distance apart, draw a bevel). This is confirmed by examining the source code (cairo-stroke-path.c). Changing the 'tolerance' from the default 0.1 to 0.05 (cairo_set_tolernace()) results in rounded corners when the stroke width is 0.5.
In Inkscape, converting the rectangle to a path and then dragging one of the adjacent corners (so that the enclosed angle changes) results in the join being drawn round when the angle is more acute... which makes the two ends of the offset paths be farther apart.
With the small C program all corners are effected, not just at the start of the path. I cannot reproduce the behavior in Inkscape where only the start/stop corner is incorrect. Using 'cairo_rectangle' instead of a path, the behavior is the same.
I've changed the default value of 'tolerance' inside Inkscape. If I increase the value to 0.5 or decrease the value to 0.05 the start/end corner is rendered correctly. The default value of 0.1 yields a bad corner. There is probably a subtle bug in Cairo.
I've attached a cleaned up test case.
Here is a snip-it of the Cairo code for the test image with scaling of 4000% (and with some debugging output):
I've dumped out some of the Cairo calls to see how Inkscape is drawing the rectangle. It is using a series of lineto's. Converting the rectangle to a path gives exactly the same calls (as expected).
I then wrote a small C program that used the same Cairo calls. I see a change in behavior between a stroke width of 0.6 and 0.7. At 0.6, rounded corners are drawn as bevels while at 0.7 they are rendered rounded. Cairo may be attempting to optimize drawing the corners (if the two ends of the outer offset paths are less than a given distance apart, draw a bevel). This is confirmed by examining the source code (cairo- stroke- path.c) . Changing the 'tolerance' from the default 0.1 to 0.05 (cairo_ set_tolernace( )) results in rounded corners when the stroke width is 0.5.
In Inkscape, converting the rectangle to a path and then dragging one of the adjacent corners (so that the enclosed angle changes) results in the join being drawn round when the angle is more acute... which makes the two ends of the offset paths be farther apart.
With the small C program all corners are effected, not just at the start of the path. I cannot reproduce the behavior in Inkscape where only the start/stop corner is incorrect. Using 'cairo_rectangle' instead of a path, the behavior is the same.
I've changed the default value of 'tolerance' inside Inkscape. If I increase the value to 0.5 or decrease the value to 0.05 the start/end corner is rendered correctly. The default value of 0.1 yields a bad corner. There is probably a subtle bug in Cairo.
I've attached a cleaned up test case.
Here is a snip-it of the Cairo code for the test image with scaling of 4000% (and with some debugging output):
// Inkscape Path ------- ------- ------- ------- ------- ----- :path _to_cairo: entrance set_line_ width( c, 0.5); set_line_ join( c, 1); stroke_ preserve( c );
cairo_matrix_t cm;
cm.xx = 40;
cm.xy = 0;
cm.x0 = 0;
cm.yx = 0;
cm.yy = 40;
cm.y0 = -160;
cairo_transform( c, &cm ); // ink_cairo_transform
// calling prepareStroke()
// called prepareStroke()
// DrawingContext:
// feed_pathvector
// feed_path_to_cairo: entrance
// cairo_rectangle( c, 0.25, 0.25, 3, 2 );
cairo_move_to( c, 0.25, 1.25);
cairo_line_to( c, 3.75, 1.25); // Not optimized
cairo_line_to( c, 3.75, 3.75); // Not optimized
cairo_line_to( c, 0.25, 3.75); // Not optimized
cairo_close_path( c );
// has_stroke... calling applyStroke()
cairo_
cairo_
// has_stroke... called applyStroke()
cairo_
cairo_new_path( c );