Repository navigation
Description
Prerequisites
- I have written a descriptive issue title
- I have verified that I am running the latest version of ImageSharp.Drawing
- I have verified if the problem exist in both
DEBUGandRELEASEmode - I have searched open and closed issues to ensure it has not already been reported
ImageSharp.Drawing version
3.1.3
Other ImageSharp packages and versions
SixLabors.ImageSharp 4.1.3 (SixLabors.Fonts 3.2.0, SixLabors.PolygonClipper 1.0.2 via dependencies)
Environment (Operating system, version and so on)
Windows 11 x64
.NET Framework version
.NET 10 (SDK 10.0.401)
Description
A PatternPen with the four-value pattern [4, 2, 1, 2] and LineJoin.Miter draws an EllipsePolygon as an almost continuous line: the ink is 97 % of a solid pen with the same options, where about 56–60 % is expected. Only one gap remains visible.
The same pattern is correct on a closed square polygon. A two-value pattern [3, 2] is correct on the same ellipse. With the default join (Bevel) the four-value pattern is also correct on the ellipse (60 %), and with LineJoin.Round it is 66 %. So the combination of a short dash/gap pattern on a densely flattened curve with miter (and to a lesser extent round) joins seems to fill the gaps.
In ImageSharp.Drawing 2.1.6 the same drawing (with JointStyle.Miter, EndCapStyle.Butt) was dashed as expected.
| Join, cap | [3, 2] |
[4, 2, 1, 2] |
|---|---|---|
| default (Bevel, Butt) | 60 % | 60 % |
| Miter, Butt | 60 % | 97 % |
| Round, Butt | 60 % | 66 % |
| Miter, Round | 74 % | 101 % |
(ink as a share of a solid pen with the same StrokeOptions; circle of 200 px diameter, pen width 2, 256 × 256 image)
Steps to Reproduce
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Drawing;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
IPath circle = new EllipsePolygon(128, 128, 200, 200);
double Ink(Pen pen)
{
using var image = new Image<Rgba32>(256, 256, Color.White.ToPixel<Rgba32>());
image.Mutate(ctx => ctx.Paint(canvas => canvas.Draw(pen, circle)));
double ink = 0;
image.ProcessPixelRows(rows =>
{
for (var y = 0; y < rows.Height; y++)
foreach (var p in rows.GetRowSpan(y))
ink += (255 - p.R) / 255.0;
});
return ink;
}
var stroke = new StrokeOptions { LineJoin = LineJoin.Miter, LineCap = LineCap.Butt };
var solid = Ink(new SolidPen(new PenOptions(Color.Black, 2, []) { StrokeOptions = stroke }));
var dashed = Ink(new PatternPen(new PenOptions(Color.Black, 2, [4f, 2f, 1f, 2f]) { StrokeOptions = stroke }));
Console.WriteLine($"{dashed / solid:P0}"); // 97 %, expected about 56–60 %Images
The arc is drawn as a continuous line with a single gap, instead of dash, gap, dot, gap.
Activity