// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using SixLabors.ImageSharp.Drawing.PolygonGeometry;
using SixLabors.ImageSharp.Drawing.Processing;
using System;
namespace SixLabors.ImageSharp.Drawing {
///
/// Extensions to that allow the generation of outlines.
///
public static class OutlinePathExtensions
{
private static readonly StrokeOptions DefaultOptions = new();
///
/// Generates an outline of the path.
///
/// The path to outline
/// The outline width.
/// A new representing the outline.
public static IPath GenerateOutline(this IPath path, float width)
=> GenerateOutline(path, width, DefaultOptions);
///
/// Generates an outline of the path.
///
/// The path to outline
/// The outline width.
/// The stroke geometry options.
/// A new representing the outline.
public static IPath GenerateOutline(this IPath path, float width, StrokeOptions strokeOptions)
{
if (width <= 0)
{
return Path.Empty;
}
return StrokedShapeGenerator.GenerateStrokedShapes(path, width, strokeOptions);
}
///
/// Generates an outline of the path with alternating on and off segments based on the pattern.
///
/// The path to outline
/// The outline width.
/// The pattern made of multiples of the width.
/// A new representing the outline.
public static IPath GenerateOutline(this IPath path, float width, ReadOnlySpan pattern)
=> path.GenerateOutline(width, pattern, false);
///
/// Generates an outline of the path with alternating on and off segments based on the pattern.
///
/// The path to outline
/// The outline width.
/// The pattern made of multiples of the width.
/// The stroke geometry options.
/// A new representing the outline.
public static IPath GenerateOutline(this IPath path, float width, ReadOnlySpan pattern, StrokeOptions strokeOptions)
=> GenerateOutline(path, width, pattern, false, strokeOptions);
///
/// Generates an outline of the path with alternating on and off segments based on the pattern.
///
/// The path to outline
/// The outline width.
/// The pattern made of multiples of the width.
/// Whether the first item in the pattern is on or off.
/// A new representing the outline.
public static IPath GenerateOutline(this IPath path, float width, ReadOnlySpan pattern, bool startOff)
=> GenerateOutline(path, width, pattern, startOff, DefaultOptions);
///
/// Generates an outline of the path with alternating on and off segments based on the pattern.
///
/// The path to outline
/// The outline width.
/// The pattern made of multiples of the width.
/// Whether the first item in the pattern is on or off.
/// The stroke geometry options.
/// A new representing the outline.
public static IPath GenerateOutline(
this IPath path,
float width,
ReadOnlySpan pattern,
bool startOff,
StrokeOptions strokeOptions)
{
if (width <= 0)
{
return Path.Empty;
}
if (pattern.Length < 2)
{
return path.GenerateOutline(width, strokeOptions);
}
IPath dashed = path.GenerateDashes(width, pattern, startOff);
// GenerateDashes returns the original path when the pattern is degenerate
// or when segmentation would exceed safety limits; stroke it as solid.
if (ReferenceEquals(dashed, path))
{
return path.GenerateOutline(width, strokeOptions);
}
if (dashed == Path.Empty)
{
return Path.Empty;
}
// Each dash segment is an open sub-path; stroke expansion and boolean merge
// are handled by the generator.
return StrokedShapeGenerator.GenerateStrokedShapes(dashed, width, strokeOptions);
}
}
}