зеркало из https://github.com/SixLabors/Shapes.git
Merge pull request #62 from SixLabors/outliner-styles
Add joint and cap styles to outliner
This commit is contained in:
Коммит
4f12a19a60
|
@ -12,7 +12,7 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-dev001425" />
|
||||
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-dev002362" />
|
||||
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
|
||||
<PackageReference Include="System.Runtime.Numerics" Version="4.3.0" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -4,7 +4,6 @@ using System.Numerics;
|
|||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
using SixLabors.ImageSharp.Processing;
|
||||
using SixLabors.ImageSharp.Processing.Drawing;
|
||||
|
||||
namespace SixLabors.Shapes.DrawShapesWithImageSharp
|
||||
{
|
||||
|
|
|
@ -6,7 +6,6 @@ using System.Linq;
|
|||
using System.Numerics;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
using SixLabors.ImageSharp.Processing;
|
||||
using SixLabors.ImageSharp.Processing.Drawing;
|
||||
|
||||
namespace SixLabors.Shapes.DrawShapesWithImageSharp
|
||||
{
|
||||
|
@ -22,6 +21,14 @@ namespace SixLabors.Shapes.DrawShapesWithImageSharp
|
|||
|
||||
private static void OutputStars()
|
||||
{
|
||||
OutputStarOutline(5, 150, 250, width: 20, jointStyle: JointStyle.Miter);
|
||||
OutputStarOutline(5, 150, 250, width: 20, jointStyle: JointStyle.Round);
|
||||
OutputStarOutline(5, 150, 250, width: 20, jointStyle: JointStyle.Square);
|
||||
|
||||
OutputStarOutlineDashed(5, 150, 250, width: 20, jointStyle: JointStyle.Square, cap: EndCapStyle.Butt);
|
||||
OutputStarOutlineDashed(5, 150, 250, width: 20, jointStyle: JointStyle.Round, cap: EndCapStyle.Round);
|
||||
OutputStarOutlineDashed(5, 150, 250, width: 20, jointStyle: JointStyle.Square, cap: EndCapStyle.Square);
|
||||
|
||||
OutputStar(3, 5);
|
||||
OutputStar(4);
|
||||
OutputStar(5);
|
||||
|
@ -39,7 +46,7 @@ namespace SixLabors.Shapes.DrawShapesWithImageSharp
|
|||
DrawFatL();
|
||||
|
||||
DrawText("Hello World");
|
||||
DrawText("Hello World Hello World Hello World Hello World Hello World Hello World Hello World", new Path(new CubicBezierLineSegment(
|
||||
DrawText("Hello World Hello World Hello World Hello World Hello World Hello World Hello World", new Path(new CubicBezierLineSegment(
|
||||
new Vector2(0, 0),
|
||||
new Vector2(150, -150),
|
||||
new Vector2(250, -150),
|
||||
|
@ -174,6 +181,25 @@ namespace SixLabors.Shapes.DrawShapesWithImageSharp
|
|||
sb.Build().Translate(0, 10).Scale(10).SaveImage("drawing", $"HourGlass.png");
|
||||
}
|
||||
|
||||
private static void OutputStarOutline(int points, float inner = 10, float outer = 20, float width = 5, JointStyle jointStyle = JointStyle.Miter)
|
||||
{
|
||||
// center the shape outerRadii + 10 px away from edges
|
||||
float offset = outer + 10;
|
||||
|
||||
Star star = new Star(offset, offset, points, inner, outer);
|
||||
var outline = Outliner.GenerateOutline(star, width, jointStyle);
|
||||
outline.SaveImage("Stars", $"StarOutline_{points}_{jointStyle}.png");
|
||||
}
|
||||
private static void OutputStarOutlineDashed(int points, float inner = 10, float outer = 20, float width = 5, JointStyle jointStyle = JointStyle.Miter, EndCapStyle cap = EndCapStyle.Butt)
|
||||
{
|
||||
// center the shape outerRadii + 10 px away from edges
|
||||
float offset = outer + 10;
|
||||
|
||||
Star star = new Star(offset, offset, points, inner, outer);
|
||||
var outline = Outliner.GenerateOutline(star, width, new float[] { 3, 3 }, false, jointStyle, cap);
|
||||
outline.SaveImage("Stars", $"StarOutlineDashed_{points}_{jointStyle}_{cap}.png");
|
||||
}
|
||||
|
||||
private static void OutputStar(int points, float inner = 10, float outer = 20)
|
||||
{
|
||||
// center the shape outerRadii + 10 px away from edges
|
||||
|
@ -228,7 +254,7 @@ namespace SixLabors.Shapes.DrawShapesWithImageSharp
|
|||
{
|
||||
new PathCollection(shape).SaveImage(width, height, path);
|
||||
}
|
||||
public static void SaveImage(this IPathCollection shape, int width, int height, params string[] path)
|
||||
public static void SaveImage(this IPathCollection shape, int width, int height, params string[] path)
|
||||
{
|
||||
string fullPath = System.IO.Path.GetFullPath(System.IO.Path.Combine("Output", System.IO.Path.Combine(path)));
|
||||
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
// Copyright (c) Six Labors and contributors.
|
||||
// Licensed under the Apache License, Version 2.0.
|
||||
|
||||
namespace SixLabors.Shapes
|
||||
{
|
||||
/// <summary>
|
||||
/// The style to apply to the end cap when generating an outline.
|
||||
/// </summary>
|
||||
public enum EndCapStyle
|
||||
{
|
||||
/// <summary>
|
||||
/// The outline stops exactly at the end of the path.
|
||||
/// </summary>
|
||||
Butt = 0,
|
||||
|
||||
/// <summary>
|
||||
/// The outline extends with a rounded style passed the end of the path.
|
||||
/// </summary>
|
||||
Round = 1,
|
||||
|
||||
/// <summary>
|
||||
/// The outlines ends squared off passed the end of the path.
|
||||
/// </summary>
|
||||
Square = 2,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
// Copyright (c) Six Labors and contributors.
|
||||
// Licensed under the Apache License, Version 2.0.
|
||||
|
||||
namespace SixLabors.Shapes
|
||||
{
|
||||
/// <summary>
|
||||
/// The style we use to generate the joints when outlining.
|
||||
/// </summary>
|
||||
public enum JointStyle
|
||||
{
|
||||
/// <summary>
|
||||
/// Joints will generate to a long point unless the end of the point will exceed 20 times the width then we generate the joint using <see cref="JointStyle.Square"/>.
|
||||
/// </summary>
|
||||
Miter = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Rounded joints. Joints generate with a rounded profile.
|
||||
/// </summary>
|
||||
Round = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Joints are squared off 1 width distance from the corner.
|
||||
/// </summary>
|
||||
Square = 0
|
||||
}
|
||||
}
|
|
@ -15,6 +15,7 @@ namespace SixLabors.Shapes
|
|||
/// </summary>
|
||||
public static class Outliner
|
||||
{
|
||||
private const double MiterOffsetDelta = 20;
|
||||
private const float ScalingFactor = 1000.0f;
|
||||
|
||||
/// <summary>
|
||||
|
@ -59,15 +60,34 @@ namespace SixLabors.Shapes
|
|||
/// <param name="startOff">Weather the first item in the pattern is on or off.</param>
|
||||
/// <returns>A new path representing the outline.</returns>
|
||||
public static IPath GenerateOutline(this IPath path, float width, ReadOnlySpan<float> pattern, bool startOff)
|
||||
=> GenerateOutline(path, width, pattern, startOff, JointStyle.Square, EndCapStyle.Butt);
|
||||
|
||||
/// <summary>
|
||||
/// Generates a outline of the path with alternating on and off segments based on the pattern.
|
||||
/// </summary>
|
||||
/// <param name="path">the path to outline</param>
|
||||
/// <param name="width">The final width outline</param>
|
||||
/// <param name="pattern">The pattern made of multiples of the width.</param>
|
||||
/// <param name="startOff">Weather the first item in the pattern is on or off.</param>
|
||||
/// <param name="jointStyle">The style to render the joints.</param>
|
||||
/// <param name="patternSectionCapStyle">The style to render between sections of the specified pattern.</param>
|
||||
/// <returns>A new path representing the outline.</returns>
|
||||
public static IPath GenerateOutline(this IPath path, float width, ReadOnlySpan<float> pattern, bool startOff, JointStyle jointStyle = JointStyle.Square, EndCapStyle patternSectionCapStyle = EndCapStyle.Butt)
|
||||
{
|
||||
if (pattern.Length < 2)
|
||||
{
|
||||
return path.GenerateOutline(width);
|
||||
}
|
||||
|
||||
var style = Convert(jointStyle);
|
||||
var patternSectionCap = Convert(patternSectionCapStyle);
|
||||
|
||||
IEnumerable<ISimplePath> paths = path.Flatten();
|
||||
|
||||
var offset = new ClipperOffset();
|
||||
var offset = new ClipperOffset()
|
||||
{
|
||||
MiterLimit = MiterOffsetDelta
|
||||
};
|
||||
|
||||
var buffer = new List<IntPoint>(3);
|
||||
foreach (ISimplePath p in paths)
|
||||
|
@ -103,7 +123,7 @@ namespace SixLabors.Shapes
|
|||
// we now inset a line joining
|
||||
if (online)
|
||||
{
|
||||
offset.AddPath(buffer, JoinType.jtSquare, EndType.etOpenButt);
|
||||
offset.AddPath(buffer, style, patternSectionCap);
|
||||
}
|
||||
|
||||
online = !online;
|
||||
|
@ -138,7 +158,7 @@ namespace SixLabors.Shapes
|
|||
|
||||
if (online)
|
||||
{
|
||||
offset.AddPath(buffer, JoinType.jtSquare, EndType.etOpenButt);
|
||||
offset.AddPath(buffer, style, patternSectionCap);
|
||||
}
|
||||
|
||||
online = !online;
|
||||
|
@ -158,9 +178,25 @@ namespace SixLabors.Shapes
|
|||
/// <param name="path">the path to outline</param>
|
||||
/// <param name="width">The final width outline</param>
|
||||
/// <returns>A new path representing the outline.</returns>
|
||||
public static IPath GenerateOutline(this IPath path, float width)
|
||||
public static IPath GenerateOutline(this IPath path, float width) => GenerateOutline(path, width, JointStyle.Square, EndCapStyle.Butt);
|
||||
|
||||
/// <summary>
|
||||
/// Generates a solid outline of the path.
|
||||
/// </summary>
|
||||
/// <param name="path">the path to outline</param>
|
||||
/// <param name="width">The final width outline</param>
|
||||
/// <param name="jointStyle">The style to render the joints.</param>
|
||||
/// <param name="endCapStyle">The style to render the end caps of open paths (ignored on closed paths).</param>
|
||||
/// <returns>A new path representing the outline.</returns>
|
||||
public static IPath GenerateOutline(this IPath path, float width, JointStyle jointStyle = JointStyle.Square, EndCapStyle endCapStyle = EndCapStyle.Butt)
|
||||
{
|
||||
var offset = new ClipperOffset();
|
||||
var offset = new ClipperOffset()
|
||||
{
|
||||
MiterLimit = MiterOffsetDelta
|
||||
};
|
||||
|
||||
var style = Convert(jointStyle);
|
||||
var openEndCapStyle = Convert(endCapStyle);
|
||||
|
||||
// Pattern can be applied to the path by cutting it into segments
|
||||
IEnumerable<ISimplePath> paths = path.Flatten();
|
||||
|
@ -173,9 +209,9 @@ namespace SixLabors.Shapes
|
|||
points.Add(new IntPoint(v.X * ScalingFactor, v.Y * ScalingFactor));
|
||||
}
|
||||
|
||||
EndType type = p.IsClosed ? EndType.etClosedLine : EndType.etOpenButt;
|
||||
EndType type = p.IsClosed ? EndType.etClosedLine : openEndCapStyle;
|
||||
|
||||
offset.AddPath(points, JoinType.jtSquare, type);
|
||||
offset.AddPath(points, style, type);
|
||||
}
|
||||
|
||||
return ExecuteOutliner(width, offset);
|
||||
|
@ -204,5 +240,33 @@ namespace SixLabors.Shapes
|
|||
{
|
||||
return new IntPoint(vector.X * ScalingFactor, vector.Y * ScalingFactor);
|
||||
}
|
||||
|
||||
private static JoinType Convert(JointStyle style)
|
||||
{
|
||||
switch (style)
|
||||
{
|
||||
case JointStyle.Round:
|
||||
return JoinType.jtRound;
|
||||
case JointStyle.Miter:
|
||||
return JoinType.jtMiter;
|
||||
case JointStyle.Square:
|
||||
default:
|
||||
return JoinType.jtSquare;
|
||||
}
|
||||
}
|
||||
|
||||
private static EndType Convert(EndCapStyle style)
|
||||
{
|
||||
switch (style)
|
||||
{
|
||||
case EndCapStyle.Round:
|
||||
return EndType.etOpenRound;
|
||||
case EndCapStyle.Square:
|
||||
return EndType.etOpenSquare;
|
||||
case EndCapStyle.Butt:
|
||||
default:
|
||||
return EndType.etOpenButt;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,10 +37,11 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<CodeAnalysisRuleSet>..\..\standards\SixLabors.ruleset</CodeAnalysisRuleSet>
|
||||
<Version>1.0.0</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="StyleCop.Analyzers" Version="1.1.1-beta.61" PrivateAssets="All"/>
|
||||
<PackageReference Include="StyleCop.Analyzers" Version="1.1.1-beta.61" PrivateAssets="All" />
|
||||
<PackageReference Include="SixLabors.Core" Version="1.0.0-beta0007" />
|
||||
</ItemGroup>
|
||||
</Project>
|
Загрузка…
Ссылка в новой задаче