mirror of https://github.com/SixLabors/ImageSharp
Browse Source
# Conflicts: # global.json # src/ImageSharp.Drawing/project.json # src/ImageSharp.Formats.Bmp/project.json # src/ImageSharp.Formats.Gif/project.json # src/ImageSharp.Formats.Jpeg/project.json # src/ImageSharp.Formats.Png/project.json # src/ImageSharp.Processing/project.json # src/ImageSharp/project.json # tests/ImageSharp.Benchmarks/Program.cs # tests/ImageSharp.Benchmarks/project.json # tests/ImageSharp.Tests/project.jsonaf/merge-core
465 changed files with 16934 additions and 11786 deletions
@ -0,0 +1,31 @@ |
|||
{ |
|||
// See https://go.microsoft.com/fwlink/?LinkId=733558 |
|||
// for the documentation about the tasks.json format |
|||
"version": "0.1.0", |
|||
"command": "dotnet", |
|||
"isShellCommand": true, |
|||
"args": [], |
|||
"tasks": [ |
|||
{ |
|||
"taskName": "build", |
|||
"args": [ "src/*/project.json", "-f", "netstandard1.1" ], |
|||
"isBuildCommand": true, |
|||
"showOutput": "always", |
|||
"problemMatcher": "$msCompile" |
|||
}, |
|||
{ |
|||
"taskName": "build benchmark", |
|||
"suppressTaskName": true, |
|||
"args": [ "build", "tests/ImageSharp.Benchmarks/project.json", "-f", "netcoreapp1.1", "-c", "Release" ], |
|||
"showOutput": "always", |
|||
"problemMatcher": "$msCompile" |
|||
}, |
|||
{ |
|||
"taskName": "test", |
|||
"args": ["tests/ImageSharp.Tests/project.json", "-f", "netcoreapp1.1"], |
|||
"isTestCommand": true, |
|||
"showOutput": "always", |
|||
"problemMatcher": "$msCompile" |
|||
} |
|||
] |
|||
} |
|||
@ -1,6 +1,7 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<RuleSet Name="ImageSharp" ToolsVersion="14.0"> |
|||
<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.Analyzers"> |
|||
<Rule Id="SA1405" Action="None" /> |
|||
<Rule Id="SA1413" Action="None" /> |
|||
</Rules> |
|||
</RuleSet> |
|||
|
|||
@ -1,3 +1,3 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:01f79400a4a77c764273a97fbc76982546e88510fa4cc64a7b2e83e265b0e141 |
|||
size 2490 |
|||
oid sha256:47f14bb7d24f7228cd8833d8d1881a72750b2c7813f391bd2a0dd0eeea936841 |
|||
size 6569 |
|||
|
|||
@ -1,3 +1,3 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:5598d4cb5bad33aefc1084c4f389b071143a59505f00f7b7831c81254f1140f8 |
|||
size 4225 |
|||
oid sha256:757ec2f45cc5f9c2083fc65a236100f1a7776eee16bd1095a550e05783106a9f |
|||
size 13949 |
|||
|
|||
@ -1,3 +1,3 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:536e75abeaa2c35f34a95d34bee4f8bd13cf5514a979960566945da4ec8827d1 |
|||
size 979 |
|||
oid sha256:0f3a5375ce20321c2cfdc888a21dcb629d3e6a85641df5cca7c66e5b2a5f70f6 |
|||
size 1439 |
|||
|
|||
@ -1,3 +1,3 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:c8288a69f4182b25e04ba6419b452c6cdbca0013856352c0aeb08abc67f67e4d |
|||
size 7951 |
|||
oid sha256:0e4cd18406375999c2bee1c39ad439b37f9524485d6e247ab0f14d2eb90a65f3 |
|||
size 31256 |
|||
|
|||
@ -1,3 +1,3 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:6ab6d98a7a55caf570016a62a2f4d72842e22cbe03460ad60a4dc196b7b1d303 |
|||
size 1698 |
|||
oid sha256:fa25e5dbe84f942107a1c29f4f68ff2a73f497412ae91b6e60fc5464bc9b5f05 |
|||
size 3132 |
|||
|
|||
@ -0,0 +1,3 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:bf2335642c6fd291befa0b203dbfb3387d99434369399b35aeea037c0f9eba45 |
|||
size 10474 |
|||
@ -1,3 +1,3 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:2f20a3b2613811efa3455ee65b532284d88636d8796ee2279c08a584aa01744e |
|||
size 19129 |
|||
oid sha256:e4217fe820af06a593903441f0719cab1ca650fd4de795f0e6808c4240a89819 |
|||
size 59646 |
|||
|
|||
|
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 22 KiB |
@ -0,0 +1,112 @@ |
|||
// <copyright file="DrawBeziers.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System; |
|||
using System.Numerics; |
|||
using Drawing; |
|||
using Drawing.Brushes; |
|||
using Drawing.Pens; |
|||
|
|||
using SixLabors.Shapes; |
|||
|
|||
/// <summary>
|
|||
/// Extension methods for the <see cref="Image{TColor}"/> type.
|
|||
/// </summary>
|
|||
public static partial class ImageExtensions |
|||
{ |
|||
/// <summary>
|
|||
/// Draws the provided Points as an open Bezier path at the provided thickness with the supplied brush
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="brush">The brush.</param>
|
|||
/// <param name="thickness">The thickness.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> DrawBeziers<TColor>(this Image<TColor> source, IBrush<TColor> brush, float thickness, Vector2[] points, GraphicsOptions options) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.Draw(new Pen<TColor>(brush, thickness), new Path(new BezierLineSegment(points)), options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the provided Points as an open Bezier path at the provided thickness with the supplied brush
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="brush">The brush.</param>
|
|||
/// <param name="thickness">The thickness.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> DrawBeziers<TColor>(this Image<TColor> source, IBrush<TColor> brush, float thickness, Vector2[] points) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.Draw(new Pen<TColor>(brush, thickness), new Path(new BezierLineSegment(points))); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the provided Points as an open Bezier path at the provided thickness with the supplied brush
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="color">The color.</param>
|
|||
/// <param name="thickness">The thickness.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> DrawBeziers<TColor>(this Image<TColor> source, TColor color, float thickness, Vector2[] points) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.DrawBeziers(new SolidBrush<TColor>(color), thickness, points); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the provided Points as an open Bezier path at the provided thickness with the supplied brush
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="color">The color.</param>
|
|||
/// <param name="thickness">The thickness.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> DrawBeziers<TColor>(this Image<TColor> source, TColor color, float thickness, Vector2[] points, GraphicsOptions options) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.DrawBeziers(new SolidBrush<TColor>(color), thickness, points, options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the provided Points as an open Bezier path with the supplied pen
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="pen">The pen.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> DrawBeziers<TColor>(this Image<TColor> source, IPen<TColor> pen, Vector2[] points, GraphicsOptions options) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.Draw(pen, new Path(new BezierLineSegment(points)), options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the provided Points as an open Bezier path with the supplied pen
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="pen">The pen.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> DrawBeziers<TColor>(this Image<TColor> source, IPen<TColor> pen, Vector2[] points) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.Draw(pen, new Path(new BezierLineSegment(points))); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,112 @@ |
|||
// <copyright file="DrawLines.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System; |
|||
using System.Numerics; |
|||
using Drawing; |
|||
using Drawing.Brushes; |
|||
using Drawing.Pens; |
|||
|
|||
using SixLabors.Shapes; |
|||
|
|||
/// <summary>
|
|||
/// Extension methods for the <see cref="Image{TColor}"/> type.
|
|||
/// </summary>
|
|||
public static partial class ImageExtensions |
|||
{ |
|||
/// <summary>
|
|||
/// Draws the provided Points as an open Linear path at the provided thickness with the supplied brush
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="brush">The brush.</param>
|
|||
/// <param name="thickness">The thickness.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> DrawLines<TColor>(this Image<TColor> source, IBrush<TColor> brush, float thickness, Vector2[] points, GraphicsOptions options) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.Draw(new Pen<TColor>(brush, thickness), new Path(new LinearLineSegment(points)), options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the provided Points as an open Linear path at the provided thickness with the supplied brush
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="brush">The brush.</param>
|
|||
/// <param name="thickness">The thickness.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> DrawLines<TColor>(this Image<TColor> source, IBrush<TColor> brush, float thickness, Vector2[] points) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.Draw(new Pen<TColor>(brush, thickness), new Path(new LinearLineSegment(points))); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the provided Points as an open Linear path at the provided thickness with the supplied brush
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="color">The color.</param>
|
|||
/// <param name="thickness">The thickness.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> DrawLines<TColor>(this Image<TColor> source, TColor color, float thickness, Vector2[] points) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.DrawLines(new SolidBrush<TColor>(color), thickness, points); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the provided Points as an open Linear path at the provided thickness with the supplied brush
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="color">The color.</param>
|
|||
/// <param name="thickness">The thickness.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>>
|
|||
public static Image<TColor> DrawLines<TColor>(this Image<TColor> source, TColor color, float thickness, Vector2[] points, GraphicsOptions options) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.DrawLines(new SolidBrush<TColor>(color), thickness, points, options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the provided Points as an open Linear path with the supplied pen
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="pen">The pen.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> DrawLines<TColor>(this Image<TColor> source, IPen<TColor> pen, Vector2[] points, GraphicsOptions options) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.Draw(pen, new Path(new LinearLineSegment(points)), options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the provided Points as an open Linear path with the supplied pen
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="pen">The pen.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> DrawLines<TColor>(this Image<TColor> source, IPen<TColor> pen, Vector2[] points) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.Draw(pen, new Path(new LinearLineSegment(points))); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,112 @@ |
|||
// <copyright file="DrawPath.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System; |
|||
|
|||
using Drawing; |
|||
using Drawing.Brushes; |
|||
using Drawing.Pens; |
|||
|
|||
using SixLabors.Shapes; |
|||
|
|||
/// <summary>
|
|||
/// Extension methods for the <see cref="Image{TColor}"/> type.
|
|||
/// </summary>
|
|||
public static partial class ImageExtensions |
|||
{ |
|||
/// <summary>
|
|||
/// Draws the outline of the polygon with the provided pen.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="pen">The pen.</param>
|
|||
/// <param name="path">The path.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> Draw<TColor>(this Image<TColor> source, IPen<TColor> pen, IPath path, GraphicsOptions options) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.Draw(pen, new ShapePath(path), options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the outline of the polygon with the provided pen.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="pen">The pen.</param>
|
|||
/// <param name="path">The path.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> Draw<TColor>(this Image<TColor> source, IPen<TColor> pen, IPath path) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.Draw(pen, path, GraphicsOptions.Default); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the outline of the polygon with the provided brush at the provided thickness.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="brush">The brush.</param>
|
|||
/// <param name="thickness">The thickness.</param>
|
|||
/// <param name="path">The shape.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> Draw<TColor>(this Image<TColor> source, IBrush<TColor> brush, float thickness, IPath path, GraphicsOptions options) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.Draw(new Pen<TColor>(brush, thickness), path, options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the outline of the polygon with the provided brush at the provided thickness.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="brush">The brush.</param>
|
|||
/// <param name="thickness">The thickness.</param>
|
|||
/// <param name="path">The path.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> Draw<TColor>(this Image<TColor> source, IBrush<TColor> brush, float thickness, IPath path) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.Draw(new Pen<TColor>(brush, thickness), path); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the outline of the polygon with the provided brush at the provided thickness.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="color">The color.</param>
|
|||
/// <param name="thickness">The thickness.</param>
|
|||
/// <param name="path">The path.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> Draw<TColor>(this Image<TColor> source, TColor color, float thickness, IPath path, GraphicsOptions options) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.Draw(new SolidBrush<TColor>(color), thickness, path, options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the outline of the polygon with the provided brush at the provided thickness.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="color">The color.</param>
|
|||
/// <param name="thickness">The thickness.</param>
|
|||
/// <param name="path">The path.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> Draw<TColor>(this Image<TColor> source, TColor color, float thickness, IPath path) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.Draw(new SolidBrush<TColor>(color), thickness, path); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,112 @@ |
|||
// <copyright file="DrawPolygon.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System; |
|||
using System.Numerics; |
|||
using Drawing; |
|||
using Drawing.Brushes; |
|||
using Drawing.Pens; |
|||
|
|||
using SixLabors.Shapes; |
|||
|
|||
/// <summary>
|
|||
/// Extension methods for the <see cref="Image{TColor}"/> type.
|
|||
/// </summary>
|
|||
public static partial class ImageExtensions |
|||
{ |
|||
/// <summary>
|
|||
/// Draws the provided Points as a closed Linear Polygon with the provided brush at the provided thickness.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="brush">The brush.</param>
|
|||
/// <param name="thickness">The thickness.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> DrawPolygon<TColor>(this Image<TColor> source, IBrush<TColor> brush, float thickness, Vector2[] points, GraphicsOptions options) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.Draw(new Pen<TColor>(brush, thickness), new Polygon(new LinearLineSegment(points)), options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the provided Points as a closed Linear Polygon with the provided brush at the provided thickness.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="brush">The brush.</param>
|
|||
/// <param name="thickness">The thickness.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> DrawPolygon<TColor>(this Image<TColor> source, IBrush<TColor> brush, float thickness, Vector2[] points) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.Draw(new Pen<TColor>(brush, thickness), new Polygon(new LinearLineSegment(points))); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the provided Points as a closed Linear Polygon with the provided brush at the provided thickness.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="color">The color.</param>
|
|||
/// <param name="thickness">The thickness.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> DrawPolygon<TColor>(this Image<TColor> source, TColor color, float thickness, Vector2[] points) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.DrawPolygon(new SolidBrush<TColor>(color), thickness, points); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the provided Points as a closed Linear Polygon with the provided brush at the provided thickness.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="color">The color.</param>
|
|||
/// <param name="thickness">The thickness.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> DrawPolygon<TColor>(this Image<TColor> source, TColor color, float thickness, Vector2[] points, GraphicsOptions options) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.DrawPolygon(new SolidBrush<TColor>(color), thickness, points, options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the provided Points as a closed Linear Polygon with the provided Pen.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="pen">The pen.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> DrawPolygon<TColor>(this Image<TColor> source, IPen<TColor> pen, Vector2[] points) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.Draw(pen, new Polygon(new LinearLineSegment(points)), GraphicsOptions.Default); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the provided Points as a closed Linear Polygon with the provided Pen.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="pen">The pen.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> DrawPolygon<TColor>(this Image<TColor> source, IPen<TColor> pen, Vector2[] points, GraphicsOptions options) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.Draw(pen, new Polygon(new LinearLineSegment(points)), options); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,78 @@ |
|||
// <copyright file="FillPaths.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System; |
|||
|
|||
using Drawing; |
|||
using Drawing.Brushes; |
|||
|
|||
using SixLabors.Shapes; |
|||
|
|||
/// <summary>
|
|||
/// Extension methods for the <see cref="Image{TColor}"/> type.
|
|||
/// </summary>
|
|||
public static partial class ImageExtensions |
|||
{ |
|||
/// <summary>
|
|||
/// Flood fills the image in the shape of the provided polygon with the specified brush..
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="brush">The brush.</param>
|
|||
/// <param name="path">The shape.</param>
|
|||
/// <param name="options">The graphics options.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> Fill<TColor>(this Image<TColor> source, IBrush<TColor> brush, IPath path, GraphicsOptions options) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.Fill(brush, new ShapeRegion(path), options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Flood fills the image in the shape of the provided polygon with the specified brush.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="brush">The brush.</param>
|
|||
/// <param name="path">The path.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> Fill<TColor>(this Image<TColor> source, IBrush<TColor> brush, IPath path) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.Fill(brush, new ShapeRegion(path), GraphicsOptions.Default); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Flood fills the image in the shape of the provided polygon with the specified brush..
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="color">The color.</param>
|
|||
/// <param name="path">The path.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> Fill<TColor>(this Image<TColor> source, TColor color, IPath path, GraphicsOptions options) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.Fill(new SolidBrush<TColor>(color), path, options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Flood fills the image in the shape of the provided polygon with the specified brush..
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="color">The color.</param>
|
|||
/// <param name="path">The path.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> Fill<TColor>(this Image<TColor> source, TColor color, IPath path) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.Fill(new SolidBrush<TColor>(color), path); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,78 @@ |
|||
// <copyright file="FillPolygon.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System; |
|||
using System.Numerics; |
|||
using Drawing; |
|||
using Drawing.Brushes; |
|||
|
|||
using SixLabors.Shapes; |
|||
|
|||
/// <summary>
|
|||
/// Extension methods for the <see cref="Image{TColor}"/> type.
|
|||
/// </summary>
|
|||
public static partial class ImageExtensions |
|||
{ |
|||
/// <summary>
|
|||
/// Flood fills the image in the shape of a Linear polygon described by the points
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="brush">The brush.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> FillPolygon<TColor>(this Image<TColor> source, IBrush<TColor> brush, Vector2[] points, GraphicsOptions options) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.Fill(brush, new Polygon(new LinearLineSegment(points)), options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Flood fills the image in the shape of a Linear polygon described by the points
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="brush">The brush.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> FillPolygon<TColor>(this Image<TColor> source, IBrush<TColor> brush, Vector2[] points) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.Fill(brush, new Polygon(new LinearLineSegment(points))); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Flood fills the image in the shape of a Linear polygon described by the points
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="color">The color.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> FillPolygon<TColor>(this Image<TColor> source, TColor color, Vector2[] points, GraphicsOptions options) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.Fill(new SolidBrush<TColor>(color), new Polygon(new LinearLineSegment(points)), options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Flood fills the image in the shape of a Linear polygon described by the points
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="color">The color.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> FillPolygon<TColor>(this Image<TColor> source, TColor color, Vector2[] points) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.Fill(new SolidBrush<TColor>(color), new Polygon(new LinearLineSegment(points))); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,84 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<Description>A cross-platform library for the processing of image files; written in C#</Description> |
|||
<AssemblyTitle>ImageSharp.Drawing.Paths</AssemblyTitle> |
|||
<VersionPrefix>1.0.0-alpha2</VersionPrefix> |
|||
<Authors>James Jackson-South and contributors</Authors> |
|||
<TargetFrameworks>netstandard1.1;net45;net461</TargetFrameworks> |
|||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> |
|||
<GenerateDocumentationFile>true</GenerateDocumentationFile> |
|||
<AssemblyName>ImageSharp.Drawing.Paths</AssemblyName> |
|||
<PackageId>ImageSharp.Drawing.Paths</PackageId> |
|||
<PackageTags>Image Resize Crop Gif Jpg Jpeg Bitmap Png Core</PackageTags> |
|||
<PackageIconUrl>https://raw.githubusercontent.com/JimBobSquarePants/ImageSharp/master/build/icons/imagesharp-logo-128.png</PackageIconUrl> |
|||
<PackageProjectUrl>https://github.com/JimBobSquarePants/ImageSharp</PackageProjectUrl> |
|||
<PackageLicenseUrl>http://www.apache.org/licenses/LICENSE-2.0</PackageLicenseUrl> |
|||
<RepositoryType>git</RepositoryType> |
|||
<RepositoryUrl>https://github.com/JimBobSquarePants/ImageSharp</RepositoryUrl> |
|||
<GenerateAssemblyDescriptionAttribute>false</GenerateAssemblyDescriptionAttribute> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<GenerateAssemblyCopyrightAttribute>false</GenerateAssemblyCopyrightAttribute> |
|||
<GenerateNeutralResourcesLanguageAttribute>false</GenerateNeutralResourcesLanguageAttribute> |
|||
<GenerateAssemblyVersionAttribute>false</GenerateAssemblyVersionAttribute> |
|||
<GenerateAssemblyFileVersionAttribute>false</GenerateAssemblyFileVersionAttribute> |
|||
<GenerateAssemblyInformationalVersionAttribute>false</GenerateAssemblyInformationalVersionAttribute> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<Compile Include="..\Shared\*.cs" Exclude="bin\**;obj\**;**\*.xproj;packages\**" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\ImageSharp\ImageSharp.csproj" /> |
|||
<ProjectReference Include="..\ImageSharp.Drawing\ImageSharp.Drawing.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="SixLabors.Shapes" Version="0.1.0-alpha0007" /> |
|||
<PackageReference Include="System.Buffers" Version="4.0.0" /> |
|||
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="4.3.0" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard1.1' "> |
|||
<PackageReference Include="System.Collections" Version="4.0.11" /> |
|||
<PackageReference Include="System.Diagnostics.Debug" Version="4.0.11" /> |
|||
<PackageReference Include="System.Diagnostics.Tools" Version="4.0.1" /> |
|||
<PackageReference Include="System.IO" Version="4.1.0" /> |
|||
<PackageReference Include="System.IO.Compression" Version="4.1.0" /> |
|||
<PackageReference Include="System.Linq" Version="4.1.0" /> |
|||
<PackageReference Include="System.Numerics.Vectors" Version="4.1.1" /> |
|||
<PackageReference Include="System.ObjectModel" Version="4.0.12" /> |
|||
<PackageReference Include="System.Resources.ResourceManager" Version="4.0.1" /> |
|||
<PackageReference Include="System.Runtime.Extensions" Version="4.1.0" /> |
|||
<PackageReference Include="System.Runtime.InteropServices" Version="4.1.0" /> |
|||
<PackageReference Include="System.Runtime.Numerics" Version="4.0.1" /> |
|||
<PackageReference Include="System.Text.Encoding.Extensions" Version="4.0.11" /> |
|||
<PackageReference Include="System.Threading" Version="4.0.11" /> |
|||
<PackageReference Include="System.Threading.Tasks" Version="4.0.11" /> |
|||
<PackageReference Include="System.Threading.Tasks.Parallel" Version="4.0.1" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup Condition=" '$(TargetFramework)' == 'net45' "> |
|||
<PackageReference Include="System.Numerics.Vectors" Version="4.1.1" /> |
|||
<PackageReference Include="System.Threading.Tasks.Parallel" Version="4.0.1" /> |
|||
<Reference Include="System.Runtime" /> |
|||
<Reference Include="System" /> |
|||
<Reference Include="Microsoft.CSharp" /> |
|||
</ItemGroup> |
|||
|
|||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' "> |
|||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup Condition=" '$(TargetFramework)' == 'net461' "> |
|||
<PackageReference Include="System.Threading.Tasks.Parallel" Version="4.0.1" /> |
|||
<Reference Include="System.Runtime" /> |
|||
<Reference Include="System.Numerics" /> |
|||
<Reference Include="System" /> |
|||
<Reference Include="Microsoft.CSharp" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,6 @@ |
|||
// <copyright file="AssemblyInfo.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
// Common values read from `AssemblyInfo.Common.cs`
|
|||
@ -0,0 +1,29 @@ |
|||
// <copyright file="RectangleExtensions.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Drawing |
|||
{ |
|||
using System; |
|||
|
|||
/// <summary>
|
|||
/// Extension methods for helping to bridge Shaper2D and ImageSharp primitives.
|
|||
/// </summary>
|
|||
internal static class RectangleExtensions |
|||
{ |
|||
/// <summary>
|
|||
/// Converts a Shaper2D <see cref="SixLabors.Shapes.Rectangle"/> to an ImageSharp <see cref="Rectangle"/> by creating a <see cref="Rectangle"/> the entirely surrounds the source.
|
|||
/// </summary>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <returns>A <see cref="Rectangle"/> representation of this <see cref="SixLabors.Shapes.Rectangle"/></returns>
|
|||
public static Rectangle Convert(this SixLabors.Shapes.Rectangle source) |
|||
{ |
|||
int left = (int)Math.Floor(source.Left); |
|||
int right = (int)Math.Ceiling(source.Right); |
|||
int top = (int)Math.Floor(source.Top); |
|||
int bottom = (int)Math.Ceiling(source.Bottom); |
|||
return new Rectangle(left, top, right - left, bottom - top); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,104 @@ |
|||
// <copyright file="ShapePath.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Drawing |
|||
{ |
|||
using System.Buffers; |
|||
using System.Collections.Immutable; |
|||
using System.Numerics; |
|||
|
|||
using SixLabors.Shapes; |
|||
|
|||
using Rectangle = ImageSharp.Rectangle; |
|||
|
|||
/// <summary>
|
|||
/// A drawable mapping between a <see cref="IPath"/> and a drawable region.
|
|||
/// </summary>
|
|||
internal class ShapePath : Drawable |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="ShapePath"/> class.
|
|||
/// </summary>
|
|||
/// <param name="path">The path.</param>
|
|||
public ShapePath(IPath path) |
|||
{ |
|||
this.Path = path; |
|||
this.Bounds = path.Bounds.Convert(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the fillable shape
|
|||
/// </summary>
|
|||
public IPath Path { get; } |
|||
|
|||
/// <inheritdoc/>
|
|||
public override int MaxIntersections => this.Path.MaxIntersections; |
|||
|
|||
/// <inheritdoc/>
|
|||
public override Rectangle Bounds { get; } |
|||
|
|||
/// <inheritdoc/>
|
|||
public override int ScanX(int x, float[] buffer, int length, int offset) |
|||
{ |
|||
Vector2 start = new Vector2(x, this.Bounds.Top - 1); |
|||
Vector2 end = new Vector2(x, this.Bounds.Bottom + 1); |
|||
Vector2[] innerbuffer = ArrayPool<Vector2>.Shared.Rent(length); |
|||
try |
|||
{ |
|||
int count = this.Path.FindIntersections(start, end, innerbuffer, length, 0); |
|||
|
|||
for (int i = 0; i < count; i++) |
|||
{ |
|||
buffer[i + offset] = innerbuffer[i].Y; |
|||
} |
|||
|
|||
return count; |
|||
} |
|||
finally |
|||
{ |
|||
ArrayPool<Vector2>.Shared.Return(innerbuffer); |
|||
} |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override int ScanY(int y, float[] buffer, int length, int offset) |
|||
{ |
|||
Vector2 start = new Vector2(this.Bounds.Left - 1, y); |
|||
Vector2 end = new Vector2(this.Bounds.Right + 1, y); |
|||
Vector2[] innerbuffer = ArrayPool<Vector2>.Shared.Rent(length); |
|||
try |
|||
{ |
|||
int count = this.Path.FindIntersections(start, end, innerbuffer, length, 0); |
|||
|
|||
for (int i = 0; i < count; i++) |
|||
{ |
|||
buffer[i + offset] = innerbuffer[i].X; |
|||
} |
|||
|
|||
return count; |
|||
} |
|||
finally |
|||
{ |
|||
ArrayPool<Vector2>.Shared.Return(innerbuffer); |
|||
} |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override PointInfo GetPointInfo(int x, int y) |
|||
{ |
|||
Vector2 point = new Vector2(x, y); |
|||
SixLabors.Shapes.PointInfo dist = this.Path.Distance(point); |
|||
|
|||
return new PointInfo |
|||
{ |
|||
DistanceAlongPath = dist.DistanceAlongPath, |
|||
DistanceFromPath = |
|||
dist.DistanceFromPath < 0 |
|||
? -dist.DistanceFromPath |
|||
: dist.DistanceFromPath |
|||
}; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,87 @@ |
|||
// <copyright file="ShapeRegion.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Drawing |
|||
{ |
|||
using System.Buffers; |
|||
using System.Numerics; |
|||
|
|||
using SixLabors.Shapes; |
|||
|
|||
using Rectangle = ImageSharp.Rectangle; |
|||
|
|||
/// <summary>
|
|||
/// A mapping between a <see cref="IPath"/> and a region.
|
|||
/// </summary>
|
|||
internal class ShapeRegion : Region |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="ShapeRegion"/> class.
|
|||
/// </summary>
|
|||
/// <param name="shape">The shape.</param>
|
|||
public ShapeRegion(IPath shape) |
|||
{ |
|||
this.Shape = shape.AsClosedPath(); |
|||
this.Bounds = shape.Bounds.Convert(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the fillable shape
|
|||
/// </summary>
|
|||
public IPath Shape { get; } |
|||
|
|||
/// <inheritdoc/>
|
|||
public override int MaxIntersections => this.Shape.MaxIntersections; |
|||
|
|||
/// <inheritdoc/>
|
|||
public override Rectangle Bounds { get; } |
|||
|
|||
/// <inheritdoc/>
|
|||
public override int ScanX(int x, float[] buffer, int length, int offset) |
|||
{ |
|||
Vector2 start = new Vector2(x, this.Bounds.Top - 1); |
|||
Vector2 end = new Vector2(x, this.Bounds.Bottom + 1); |
|||
Vector2[] innerbuffer = ArrayPool<Vector2>.Shared.Rent(length); |
|||
try |
|||
{ |
|||
int count = this.Shape.FindIntersections(start, end, innerbuffer, length, 0); |
|||
|
|||
for (int i = 0; i < count; i++) |
|||
{ |
|||
buffer[i + offset] = innerbuffer[i].Y; |
|||
} |
|||
|
|||
return count; |
|||
} |
|||
finally |
|||
{ |
|||
ArrayPool<Vector2>.Shared.Return(innerbuffer); |
|||
} |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override int ScanY(int y, float[] buffer, int length, int offset) |
|||
{ |
|||
Vector2 start = new Vector2(this.Bounds.Left - 1, y); |
|||
Vector2 end = new Vector2(this.Bounds.Right + 1, y); |
|||
Vector2[] innerbuffer = ArrayPool<Vector2>.Shared.Rent(length); |
|||
try |
|||
{ |
|||
int count = this.Shape.FindIntersections(start, end, innerbuffer, length, 0); |
|||
|
|||
for (int i = 0; i < count; i++) |
|||
{ |
|||
buffer[i + offset] = innerbuffer[i].X; |
|||
} |
|||
|
|||
return count; |
|||
} |
|||
finally |
|||
{ |
|||
ArrayPool<Vector2>.Shared.Return(innerbuffer); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,203 @@ |
|||
// <copyright file="DrawText.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System.Numerics; |
|||
|
|||
using Drawing; |
|||
using Drawing.Brushes; |
|||
using Drawing.Pens; |
|||
|
|||
using SixLabors.Fonts; |
|||
|
|||
/// <summary>
|
|||
/// Extension methods for the <see cref="Image{TColor}"/> type.
|
|||
/// </summary>
|
|||
public static partial class ImageExtensions |
|||
{ |
|||
/// <summary>
|
|||
/// Draws the text onto the the image filled via the brush.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="text">The text.</param>
|
|||
/// <param name="font">The font.</param>
|
|||
/// <param name="color">The color.</param>
|
|||
/// <param name="location">The location.</param>
|
|||
/// <returns>
|
|||
/// The <see cref="Image{TColor}" />.
|
|||
/// </returns>
|
|||
public static Image<TColor> DrawText<TColor>(this Image<TColor> source, string text, Font font, TColor color, Vector2 location) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.DrawText(text, font, color, location, TextGraphicsOptions.Default); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the text onto the the image filled via the brush.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="text">The text.</param>
|
|||
/// <param name="font">The font.</param>
|
|||
/// <param name="color">The color.</param>
|
|||
/// <param name="location">The location.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>
|
|||
/// The <see cref="Image{TColor}" />.
|
|||
/// </returns>
|
|||
public static Image<TColor> DrawText<TColor>(this Image<TColor> source, string text, Font font, TColor color, Vector2 location, TextGraphicsOptions options) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.DrawText(text, font, Brushes<TColor>.Solid(color), null, location, options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the text onto the the image filled via the brush.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="text">The text.</param>
|
|||
/// <param name="font">The font.</param>
|
|||
/// <param name="brush">The brush.</param>
|
|||
/// <param name="location">The location.</param>
|
|||
/// <returns>
|
|||
/// The <see cref="Image{TColor}" />.
|
|||
/// </returns>
|
|||
public static Image<TColor> DrawText<TColor>(this Image<TColor> source, string text, Font font, IBrush<TColor> brush, Vector2 location) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.DrawText(text, font, brush, location, TextGraphicsOptions.Default); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the text onto the the image filled via the brush.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="text">The text.</param>
|
|||
/// <param name="font">The font.</param>
|
|||
/// <param name="brush">The brush.</param>
|
|||
/// <param name="location">The location.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>
|
|||
/// The <see cref="Image{TColor}" />.
|
|||
/// </returns>
|
|||
public static Image<TColor> DrawText<TColor>(this Image<TColor> source, string text, Font font, IBrush<TColor> brush, Vector2 location, TextGraphicsOptions options) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.DrawText(text, font, brush, null, location, options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the text onto the the image outlined via the pen.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="text">The text.</param>
|
|||
/// <param name="font">The font.</param>
|
|||
/// <param name="pen">The pen.</param>
|
|||
/// <param name="location">The location.</param>
|
|||
/// <returns>
|
|||
/// The <see cref="Image{TColor}" />.
|
|||
/// </returns>
|
|||
public static Image<TColor> DrawText<TColor>(this Image<TColor> source, string text, Font font, IPen<TColor> pen, Vector2 location) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.DrawText(text, font, pen, location, TextGraphicsOptions.Default); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the text onto the the image outlined via the pen.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="text">The text.</param>
|
|||
/// <param name="font">The font.</param>
|
|||
/// <param name="pen">The pen.</param>
|
|||
/// <param name="location">The location.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>
|
|||
/// The <see cref="Image{TColor}" />.
|
|||
/// </returns>
|
|||
public static Image<TColor> DrawText<TColor>(this Image<TColor> source, string text, Font font, IPen<TColor> pen, Vector2 location, TextGraphicsOptions options) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.DrawText(text, font, null, pen, location, options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the text onto the the image filled via the brush then outlined via the pen.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="text">The text.</param>
|
|||
/// <param name="font">The font.</param>
|
|||
/// <param name="brush">The brush.</param>
|
|||
/// <param name="pen">The pen.</param>
|
|||
/// <param name="location">The location.</param>
|
|||
/// <returns>
|
|||
/// The <see cref="Image{TColor}" />.
|
|||
/// </returns>
|
|||
public static Image<TColor> DrawText<TColor>(this Image<TColor> source, string text, Font font, IBrush<TColor> brush, IPen<TColor> pen, Vector2 location) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.DrawText(text, font, brush, pen, location, TextGraphicsOptions.Default); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the text onto the the image filled via the brush then outlined via the pen.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="text">The text.</param>
|
|||
/// <param name="font">The font.</param>
|
|||
/// <param name="brush">The brush.</param>
|
|||
/// <param name="pen">The pen.</param>
|
|||
/// <param name="location">The location.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>
|
|||
/// The <see cref="Image{TColor}" />.
|
|||
/// </returns>
|
|||
public static Image<TColor> DrawText<TColor>(this Image<TColor> source, string text, Font font, IBrush<TColor> brush, IPen<TColor> pen, Vector2 location, TextGraphicsOptions options) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
GlyphBuilder glyphBuilder = new GlyphBuilder(location); |
|||
|
|||
TextRenderer renderer = new TextRenderer(glyphBuilder); |
|||
|
|||
Vector2 dpi = new Vector2((float)source.MetaData.HorizontalResolution, (float)source.MetaData.VerticalResolution); |
|||
FontSpan style = new FontSpan(font) |
|||
{ |
|||
ApplyKerning = options.ApplyKerning, |
|||
TabWidth = options.TabWidth |
|||
}; |
|||
|
|||
renderer.RenderText(text, style, dpi); |
|||
|
|||
System.Collections.Generic.IEnumerable<SixLabors.Shapes.IPath> shapesToDraw = glyphBuilder.Paths; |
|||
|
|||
GraphicsOptions pathOptions = (GraphicsOptions)options; |
|||
if (brush != null) |
|||
{ |
|||
foreach (SixLabors.Shapes.IPath s in shapesToDraw) |
|||
{ |
|||
source.Fill(brush, s, pathOptions); |
|||
} |
|||
} |
|||
|
|||
if (pen != null) |
|||
{ |
|||
foreach (SixLabors.Shapes.IPath s in shapesToDraw) |
|||
{ |
|||
source.Draw(pen, s, pathOptions); |
|||
} |
|||
} |
|||
|
|||
return source; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,126 @@ |
|||
// <copyright file="GlyphBuilder.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Drawing |
|||
{ |
|||
using System.Collections.Generic; |
|||
using System.Numerics; |
|||
|
|||
using SixLabors.Fonts; |
|||
using SixLabors.Shapes; |
|||
|
|||
/// <summary>
|
|||
/// rendering surface that Fonts can use to generate Shapes.
|
|||
/// </summary>
|
|||
internal class GlyphBuilder : IGlyphRenderer |
|||
{ |
|||
private readonly PathBuilder builder = new PathBuilder(); |
|||
private readonly List<IPath> paths = new List<IPath>(); |
|||
private Vector2 currentPoint = default(Vector2); |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="GlyphBuilder"/> class.
|
|||
/// </summary>
|
|||
public GlyphBuilder() |
|||
: this(Vector2.Zero) |
|||
{ |
|||
// glyphs are renderd realative to bottom left so invert the Y axis to allow it to render on top left origin surface
|
|||
this.builder = new PathBuilder(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="GlyphBuilder"/> class.
|
|||
/// </summary>
|
|||
/// <param name="origin">The origin.</param>
|
|||
public GlyphBuilder(Vector2 origin) |
|||
{ |
|||
this.builder = new PathBuilder(); |
|||
this.builder.SetOrigin(origin); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the paths that have been rendered by this.
|
|||
/// </summary>
|
|||
public IEnumerable<IPath> Paths => this.paths; |
|||
|
|||
/// <summary>
|
|||
/// Begins the glyph.
|
|||
/// </summary>
|
|||
void IGlyphRenderer.BeginGlyph() |
|||
{ |
|||
this.builder.Clear(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Begins the figure.
|
|||
/// </summary>
|
|||
void IGlyphRenderer.BeginFigure() |
|||
{ |
|||
this.builder.StartFigure(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws a cubic bezier from the current point to the <paramref name="point"/>
|
|||
/// </summary>
|
|||
/// <param name="secondControlPoint">The second control point.</param>
|
|||
/// <param name="thirdControlPoint">The third control point.</param>
|
|||
/// <param name="point">The point.</param>
|
|||
void IGlyphRenderer.CubicBezierTo(Vector2 secondControlPoint, Vector2 thirdControlPoint, Vector2 point) |
|||
{ |
|||
this.builder.AddBezier(this.currentPoint, secondControlPoint, thirdControlPoint, point); |
|||
this.currentPoint = point; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Ends the glyph.
|
|||
/// </summary>
|
|||
void IGlyphRenderer.EndGlyph() |
|||
{ |
|||
this.paths.Add(this.builder.Build()); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Ends the figure.
|
|||
/// </summary>
|
|||
void IGlyphRenderer.EndFigure() |
|||
{ |
|||
this.builder.CloseFigure(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws a line from the current point to the <paramref name="point"/>.
|
|||
/// </summary>
|
|||
/// <param name="point">The point.</param>
|
|||
void IGlyphRenderer.LineTo(Vector2 point) |
|||
{ |
|||
this.builder.AddLine(this.currentPoint, point); |
|||
this.currentPoint = point; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Moves to current point to the supplied vector.
|
|||
/// </summary>
|
|||
/// <param name="point">The point.</param>
|
|||
void IGlyphRenderer.MoveTo(Vector2 point) |
|||
{ |
|||
this.builder.StartFigure(); |
|||
this.currentPoint = point; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws a quadratics bezier from the current point to the <paramref name="point"/>
|
|||
/// </summary>
|
|||
/// <param name="secondControlPoint">The second control point.</param>
|
|||
/// <param name="point">The point.</param>
|
|||
void IGlyphRenderer.QuadraticBezierTo(Vector2 secondControlPoint, Vector2 point) |
|||
{ |
|||
Vector2 c1 = (((secondControlPoint - this.currentPoint) * 2) / 3) + this.currentPoint; |
|||
Vector2 c2 = (((secondControlPoint - point) * 2) / 3) + point; |
|||
|
|||
this.builder.AddBezier(this.currentPoint, c1, c2, point); |
|||
this.currentPoint = point; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,84 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<Description>A cross-platform library for the processing of image files; written in C#</Description> |
|||
<AssemblyTitle>ImageSharp.Drawing.Text</AssemblyTitle> |
|||
<VersionPrefix>1.0.0-alpha2</VersionPrefix> |
|||
<Authors>James Jackson-South and contributors</Authors> |
|||
<TargetFrameworks>netstandard1.1;net45;net461</TargetFrameworks> |
|||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> |
|||
<GenerateDocumentationFile>true</GenerateDocumentationFile> |
|||
<AssemblyName>ImageSharp.Drawing.Text</AssemblyName> |
|||
<PackageId>ImageSharp.Drawing.Text</PackageId> |
|||
<PackageTags>Image Resize Crop Gif Jpg Jpeg Bitmap Png Core</PackageTags> |
|||
<PackageIconUrl>https://raw.githubusercontent.com/JimBobSquarePants/ImageSharp/master/build/icons/imagesharp-logo-128.png</PackageIconUrl> |
|||
<PackageProjectUrl>https://github.com/JimBobSquarePants/ImageSharp</PackageProjectUrl> |
|||
<PackageLicenseUrl>http://www.apache.org/licenses/LICENSE-2.0</PackageLicenseUrl> |
|||
<RepositoryType>git</RepositoryType> |
|||
<RepositoryUrl>https://github.com/JimBobSquarePants/ImageSharp</RepositoryUrl> |
|||
<GenerateAssemblyDescriptionAttribute>false</GenerateAssemblyDescriptionAttribute> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<GenerateAssemblyCopyrightAttribute>false</GenerateAssemblyCopyrightAttribute> |
|||
<GenerateNeutralResourcesLanguageAttribute>false</GenerateNeutralResourcesLanguageAttribute> |
|||
<GenerateAssemblyVersionAttribute>false</GenerateAssemblyVersionAttribute> |
|||
<GenerateAssemblyFileVersionAttribute>false</GenerateAssemblyFileVersionAttribute> |
|||
<GenerateAssemblyInformationalVersionAttribute>false</GenerateAssemblyInformationalVersionAttribute> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<Compile Include="..\Shared\*.cs" Exclude="bin\**;obj\**;**\*.xproj;packages\**" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\ImageSharp\ImageSharp.csproj" /> |
|||
<ProjectReference Include="..\ImageSharp.Drawing.Paths\ImageSharp.Drawing.Paths.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="SixLabors.Fonts" Version="0.1.0-alpha0001" /> |
|||
<PackageReference Include="System.Buffers" Version="4.0.0" /> |
|||
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="4.3.0" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard1.1' "> |
|||
<PackageReference Include="System.Collections" Version="4.0.11" /> |
|||
<PackageReference Include="System.Diagnostics.Debug" Version="4.0.11" /> |
|||
<PackageReference Include="System.Diagnostics.Tools" Version="4.0.1" /> |
|||
<PackageReference Include="System.IO" Version="4.1.0" /> |
|||
<PackageReference Include="System.IO.Compression" Version="4.1.0" /> |
|||
<PackageReference Include="System.Linq" Version="4.1.0" /> |
|||
<PackageReference Include="System.Numerics.Vectors" Version="4.1.1" /> |
|||
<PackageReference Include="System.ObjectModel" Version="4.0.12" /> |
|||
<PackageReference Include="System.Resources.ResourceManager" Version="4.0.1" /> |
|||
<PackageReference Include="System.Runtime.Extensions" Version="4.1.0" /> |
|||
<PackageReference Include="System.Runtime.InteropServices" Version="4.1.0" /> |
|||
<PackageReference Include="System.Runtime.Numerics" Version="4.0.1" /> |
|||
<PackageReference Include="System.Text.Encoding.Extensions" Version="4.0.11" /> |
|||
<PackageReference Include="System.Threading" Version="4.0.11" /> |
|||
<PackageReference Include="System.Threading.Tasks" Version="4.0.11" /> |
|||
<PackageReference Include="System.Threading.Tasks.Parallel" Version="4.0.1" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup Condition=" '$(TargetFramework)' == 'net45' "> |
|||
<PackageReference Include="System.Numerics.Vectors" Version="4.1.1" /> |
|||
<PackageReference Include="System.Threading.Tasks.Parallel" Version="4.0.1" /> |
|||
<Reference Include="System.Runtime" /> |
|||
<Reference Include="System" /> |
|||
<Reference Include="Microsoft.CSharp" /> |
|||
</ItemGroup> |
|||
|
|||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' "> |
|||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup Condition=" '$(TargetFramework)' == 'net461' "> |
|||
<PackageReference Include="System.Threading.Tasks.Parallel" Version="4.0.1" /> |
|||
<Reference Include="System.Runtime" /> |
|||
<Reference Include="System.Numerics" /> |
|||
<Reference Include="System" /> |
|||
<Reference Include="Microsoft.CSharp" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,6 @@ |
|||
// <copyright file="AssemblyInfo.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
// Common values read from `AssemblyInfo.Common.cs`
|
|||
@ -0,0 +1,68 @@ |
|||
// <copyright file="TextGraphicsOptions.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Drawing |
|||
{ |
|||
/// <summary>
|
|||
/// Options for influencing the drawing functions.
|
|||
/// </summary>
|
|||
public struct TextGraphicsOptions |
|||
{ |
|||
/// <summary>
|
|||
/// Represents the default <see cref="TextGraphicsOptions"/>.
|
|||
/// </summary>
|
|||
public static readonly TextGraphicsOptions Default = new TextGraphicsOptions(true); |
|||
|
|||
/// <summary>
|
|||
/// Whether antialiasing should be applied.
|
|||
/// </summary>
|
|||
public bool Antialias; |
|||
|
|||
/// <summary>
|
|||
/// Whether the text should be drawing with kerning enabled.
|
|||
/// </summary>
|
|||
public bool ApplyKerning; |
|||
|
|||
/// <summary>
|
|||
/// The number of space widths a tab should lock to.
|
|||
/// </summary>
|
|||
public float TabWidth; |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="TextGraphicsOptions" /> struct.
|
|||
/// </summary>
|
|||
/// <param name="enableAntialiasing">If set to <c>true</c> [enable antialiasing].</param>
|
|||
public TextGraphicsOptions(bool enableAntialiasing) |
|||
{ |
|||
this.Antialias = enableAntialiasing; |
|||
this.ApplyKerning = true; |
|||
this.TabWidth = 4; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Performs an implicit conversion from <see cref="GraphicsOptions"/> to <see cref="TextGraphicsOptions"/>.
|
|||
/// </summary>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>
|
|||
/// The result of the conversion.
|
|||
/// </returns>
|
|||
public static implicit operator TextGraphicsOptions(GraphicsOptions options) |
|||
{ |
|||
return new TextGraphicsOptions(options.Antialias); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Performs an explicit conversion from <see cref="TextGraphicsOptions"/> to <see cref="GraphicsOptions"/>.
|
|||
/// </summary>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>
|
|||
/// The result of the conversion.
|
|||
/// </returns>
|
|||
public static explicit operator GraphicsOptions(TextGraphicsOptions options) |
|||
{ |
|||
return new GraphicsOptions(options.Antialias); |
|||
} |
|||
} |
|||
} |
|||
@ -1,507 +0,0 @@ |
|||
// <copyright file="Draw.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System; |
|||
using System.Numerics; |
|||
using Drawing; |
|||
using Drawing.Brushes; |
|||
using Drawing.Paths; |
|||
using Drawing.Pens; |
|||
using Drawing.Processors; |
|||
using Drawing.Shapes; |
|||
|
|||
/// <summary>
|
|||
/// Extension methods for the <see cref="Image{TColor}"/> type.
|
|||
/// </summary>
|
|||
public static partial class ImageExtensions |
|||
{ |
|||
/// <summary>
|
|||
/// Draws the outline of the polygon with the provided pen.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The source.</param>
|
|||
/// <param name="pen">The pen.</param>
|
|||
/// <param name="shape">The shape.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>
|
|||
/// The Image
|
|||
/// </returns>
|
|||
public static Image<TColor> DrawPolygon<TColor>(this Image<TColor> source, IPen<TColor> pen, IShape shape, GraphicsOptions options) |
|||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|||
{ |
|||
return source.Apply(new DrawPathProcessor<TColor>(pen, shape, options)); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the outline of the polygon with the provided pen.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The source.</param>
|
|||
/// <param name="pen">The pen.</param>
|
|||
/// <param name="shape">The shape.</param>
|
|||
/// <returns>The Image</returns>
|
|||
public static Image<TColor> DrawPolygon<TColor>(this Image<TColor> source, IPen<TColor> pen, IShape shape) |
|||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|||
{ |
|||
return source.DrawPolygon(pen, shape, GraphicsOptions.Default); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the outline of the polygon with the provided brush at the provided thickness.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The source.</param>
|
|||
/// <param name="brush">The brush.</param>
|
|||
/// <param name="thickness">The thickness.</param>
|
|||
/// <param name="shape">The shape.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>
|
|||
/// The Image
|
|||
/// </returns>
|
|||
public static Image<TColor> DrawPolygon<TColor>(this Image<TColor> source, IBrush<TColor> brush, float thickness, IShape shape, GraphicsOptions options) |
|||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|||
{ |
|||
return source.DrawPolygon(new Pen<TColor>(brush, thickness), shape, options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the outline of the polygon with the provided brush at the provided thickness.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The source.</param>
|
|||
/// <param name="brush">The brush.</param>
|
|||
/// <param name="thickness">The thickness.</param>
|
|||
/// <param name="shape">The shape.</param>
|
|||
/// <returns>The Image</returns>
|
|||
public static Image<TColor> DrawPolygon<TColor>(this Image<TColor> source, IBrush<TColor> brush, float thickness, IShape shape) |
|||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|||
{ |
|||
return source.DrawPolygon(new Pen<TColor>(brush, thickness), shape); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the outline of the polygon with the provided brush at the provided thickness.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The source.</param>
|
|||
/// <param name="color">The color.</param>
|
|||
/// <param name="thickness">The thickness.</param>
|
|||
/// <param name="shape">The shape.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>
|
|||
/// The Image
|
|||
/// </returns>
|
|||
public static Image<TColor> DrawPolygon<TColor>(this Image<TColor> source, TColor color, float thickness, IShape shape, GraphicsOptions options) |
|||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|||
{ |
|||
return source.DrawPolygon(new SolidBrush<TColor>(color), thickness, shape, options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the outline of the polygon with the provided brush at the provided thickness.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The source.</param>
|
|||
/// <param name="color">The color.</param>
|
|||
/// <param name="thickness">The thickness.</param>
|
|||
/// <param name="shape">The shape.</param>
|
|||
/// <returns>The Image</returns>
|
|||
public static Image<TColor> DrawPolygon<TColor>(this Image<TColor> source, TColor color, float thickness, IShape shape) |
|||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|||
{ |
|||
return source.DrawPolygon(new SolidBrush<TColor>(color), thickness, shape); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the provided Points as a closed Linear Polygon with the provided brush at the provided thickness.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The source.</param>
|
|||
/// <param name="brush">The brush.</param>
|
|||
/// <param name="thickness">The thickness.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>
|
|||
/// The Image
|
|||
/// </returns>
|
|||
public static Image<TColor> DrawPolygon<TColor>(this Image<TColor> source, IBrush<TColor> brush, float thickness, Vector2[] points, GraphicsOptions options) |
|||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|||
{ |
|||
return source.DrawPolygon(new Pen<TColor>(brush, thickness), new Polygon(new LinearLineSegment(points)), options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the provided Points as a closed Linear Polygon with the provided brush at the provided thickness.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The source.</param>
|
|||
/// <param name="brush">The brush.</param>
|
|||
/// <param name="thickness">The thickness.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <returns>The Image</returns>
|
|||
public static Image<TColor> DrawPolygon<TColor>(this Image<TColor> source, IBrush<TColor> brush, float thickness, Vector2[] points) |
|||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|||
{ |
|||
return source.DrawPolygon(new Pen<TColor>(brush, thickness), new Polygon(new LinearLineSegment(points))); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the provided Points as a closed Linear Polygon with the provided brush at the provided thickness.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The source.</param>
|
|||
/// <param name="color">The color.</param>
|
|||
/// <param name="thickness">The thickness.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <returns>The Image</returns>
|
|||
public static Image<TColor> DrawPolygon<TColor>(this Image<TColor> source, TColor color, float thickness, Vector2[] points) |
|||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|||
{ |
|||
return source.DrawPolygon(new SolidBrush<TColor>(color), thickness, points); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the provided Points as a closed Linear Polygon with the provided brush at the provided thickness.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The source.</param>
|
|||
/// <param name="color">The color.</param>
|
|||
/// <param name="thickness">The thickness.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>
|
|||
/// The Image
|
|||
/// </returns>
|
|||
public static Image<TColor> DrawPolygon<TColor>(this Image<TColor> source, TColor color, float thickness, Vector2[] points, GraphicsOptions options) |
|||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|||
{ |
|||
return source.DrawPolygon(new SolidBrush<TColor>(color), thickness, points, options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the provided Points as a closed Linear Polygon with the provided Pen.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The source.</param>
|
|||
/// <param name="pen">The pen.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>
|
|||
/// The Image
|
|||
/// </returns>
|
|||
public static Image<TColor> DrawPolygon<TColor>(this Image<TColor> source, IPen<TColor> pen, Vector2[] points, GraphicsOptions options) |
|||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|||
{ |
|||
return source.DrawPolygon(pen, new Polygon(new LinearLineSegment(points)), options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the provided Points as a closed Linear Polygon with the provided Pen.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The source.</param>
|
|||
/// <param name="pen">The pen.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <returns>The Image</returns>
|
|||
public static Image<TColor> DrawPolygon<TColor>(this Image<TColor> source, IPen<TColor> pen, Vector2[] points) |
|||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|||
{ |
|||
return source.DrawPolygon(pen, new Polygon(new LinearLineSegment(points))); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the path with the provided pen.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The source.</param>
|
|||
/// <param name="pen">The pen.</param>
|
|||
/// <param name="path">The path.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>
|
|||
/// The Image
|
|||
/// </returns>
|
|||
public static Image<TColor> DrawPath<TColor>(this Image<TColor> source, IPen<TColor> pen, IPath path, GraphicsOptions options) |
|||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|||
{ |
|||
return source.Apply(new DrawPathProcessor<TColor>(pen, path, options)); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the path with the provided pen.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The source.</param>
|
|||
/// <param name="pen">The pen.</param>
|
|||
/// <param name="path">The path.</param>
|
|||
/// <returns>The Image</returns>
|
|||
public static Image<TColor> DrawPath<TColor>(this Image<TColor> source, IPen<TColor> pen, IPath path) |
|||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|||
{ |
|||
return source.Apply(new DrawPathProcessor<TColor>(pen, path, GraphicsOptions.Default)); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the path with the bursh at the privdied thickness.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The source.</param>
|
|||
/// <param name="brush">The brush.</param>
|
|||
/// <param name="thickness">The thickness.</param>
|
|||
/// <param name="path">The path.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>
|
|||
/// The Image
|
|||
/// </returns>
|
|||
public static Image<TColor> DrawPath<TColor>(this Image<TColor> source, IBrush<TColor> brush, float thickness, IPath path, GraphicsOptions options) |
|||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|||
{ |
|||
return source.DrawPath(new Pen<TColor>(brush, thickness), path, options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the path with the bursh at the privdied thickness.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The source.</param>
|
|||
/// <param name="brush">The brush.</param>
|
|||
/// <param name="thickness">The thickness.</param>
|
|||
/// <param name="path">The path.</param>
|
|||
/// <returns>The Image</returns>
|
|||
public static Image<TColor> DrawPath<TColor>(this Image<TColor> source, IBrush<TColor> brush, float thickness, IPath path) |
|||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|||
{ |
|||
return source.DrawPath(new Pen<TColor>(brush, thickness), path); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the path with the bursh at the privdied thickness.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The source.</param>
|
|||
/// <param name="color">The color.</param>
|
|||
/// <param name="thickness">The thickness.</param>
|
|||
/// <param name="path">The path.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>
|
|||
/// The Image
|
|||
/// </returns>
|
|||
public static Image<TColor> DrawPath<TColor>(this Image<TColor> source, TColor color, float thickness, IPath path, GraphicsOptions options) |
|||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|||
{ |
|||
return source.DrawPath(new SolidBrush<TColor>(color), thickness, path, options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the path with the bursh at the privdied thickness.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The source.</param>
|
|||
/// <param name="color">The color.</param>
|
|||
/// <param name="thickness">The thickness.</param>
|
|||
/// <param name="path">The path.</param>
|
|||
/// <returns>The Image</returns>
|
|||
public static Image<TColor> DrawPath<TColor>(this Image<TColor> source, TColor color, float thickness, IPath path) |
|||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|||
{ |
|||
return source.DrawPath(new SolidBrush<TColor>(color), thickness, path); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the provided Points as an open Linear path at the provided thickness with the supplied brush
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The source.</param>
|
|||
/// <param name="brush">The brush.</param>
|
|||
/// <param name="thickness">The thickness.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>
|
|||
/// The Image
|
|||
/// </returns>
|
|||
public static Image<TColor> DrawLines<TColor>(this Image<TColor> source, IBrush<TColor> brush, float thickness, Vector2[] points, GraphicsOptions options) |
|||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|||
{ |
|||
return source.DrawPath(new Pen<TColor>(brush, thickness), new Path(new LinearLineSegment(points)), options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the provided Points as an open Linear path at the provided thickness with the supplied brush
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The source.</param>
|
|||
/// <param name="brush">The brush.</param>
|
|||
/// <param name="thickness">The thickness.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <returns>The Image</returns>
|
|||
public static Image<TColor> DrawLines<TColor>(this Image<TColor> source, IBrush<TColor> brush, float thickness, Vector2[] points) |
|||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|||
{ |
|||
return source.DrawPath(new Pen<TColor>(brush, thickness), new Path(new LinearLineSegment(points))); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the provided Points as an open Linear path at the provided thickness with the supplied brush
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The source.</param>
|
|||
/// <param name="color">The color.</param>
|
|||
/// <param name="thickness">The thickness.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <returns>The Image</returns>
|
|||
public static Image<TColor> DrawLines<TColor>(this Image<TColor> source, TColor color, float thickness, Vector2[] points) |
|||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|||
{ |
|||
return source.DrawLines(new SolidBrush<TColor>(color), thickness, points); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the provided Points as an open Linear path at the provided thickness with the supplied brush
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The source.</param>
|
|||
/// <param name="color">The color.</param>
|
|||
/// <param name="thickness">The thickness.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>
|
|||
/// The Image
|
|||
/// </returns>
|
|||
public static Image<TColor> DrawLines<TColor>(this Image<TColor> source, TColor color, float thickness, Vector2[] points, GraphicsOptions options) |
|||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|||
{ |
|||
return source.DrawLines(new SolidBrush<TColor>(color), thickness, points, options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the provided Points as an open Linear path with the supplied pen
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The source.</param>
|
|||
/// <param name="pen">The pen.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>
|
|||
/// The Image
|
|||
/// </returns>
|
|||
public static Image<TColor> DrawLines<TColor>(this Image<TColor> source, IPen<TColor> pen, Vector2[] points, GraphicsOptions options) |
|||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|||
{ |
|||
return source.DrawPath(pen, new Path(new LinearLineSegment(points)), options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the provided Points as an open Linear path with the supplied pen
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The source.</param>
|
|||
/// <param name="pen">The pen.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <returns>The Image</returns>
|
|||
public static Image<TColor> DrawLines<TColor>(this Image<TColor> source, IPen<TColor> pen, Vector2[] points) |
|||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|||
{ |
|||
return source.DrawPath(pen, new Path(new LinearLineSegment(points))); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the provided Points as an open Bezier path at the provided thickness with the supplied brush
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The source.</param>
|
|||
/// <param name="brush">The brush.</param>
|
|||
/// <param name="thickness">The thickness.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>
|
|||
/// The Image
|
|||
/// </returns>
|
|||
public static Image<TColor> DrawBeziers<TColor>(this Image<TColor> source, IBrush<TColor> brush, float thickness, Vector2[] points, GraphicsOptions options) |
|||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|||
{ |
|||
return source.DrawPath(new Pen<TColor>(brush, thickness), new Path(new BezierLineSegment(points)), options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the provided Points as an open Bezier path at the provided thickness with the supplied brush
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The source.</param>
|
|||
/// <param name="brush">The brush.</param>
|
|||
/// <param name="thickness">The thickness.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <returns>The Image</returns>
|
|||
public static Image<TColor> DrawBeziers<TColor>(this Image<TColor> source, IBrush<TColor> brush, float thickness, Vector2[] points) |
|||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|||
{ |
|||
return source.DrawPath(new Pen<TColor>(brush, thickness), new Path(new BezierLineSegment(points))); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the provided Points as an open Bezier path at the provided thickness with the supplied brush
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The source.</param>
|
|||
/// <param name="color">The color.</param>
|
|||
/// <param name="thickness">The thickness.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <returns>The Image</returns>
|
|||
public static Image<TColor> DrawBeziers<TColor>(this Image<TColor> source, TColor color, float thickness, Vector2[] points) |
|||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|||
{ |
|||
return source.DrawBeziers(new SolidBrush<TColor>(color), thickness, points); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the provided Points as an open Bezier path at the provided thickness with the supplied brush
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The source.</param>
|
|||
/// <param name="color">The color.</param>
|
|||
/// <param name="thickness">The thickness.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>
|
|||
/// The Image
|
|||
/// </returns>
|
|||
public static Image<TColor> DrawBeziers<TColor>(this Image<TColor> source, TColor color, float thickness, Vector2[] points, GraphicsOptions options) |
|||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|||
{ |
|||
return source.DrawBeziers(new SolidBrush<TColor>(color), thickness, points, options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the provided Points as an open Bezier path with the supplied pen
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The source.</param>
|
|||
/// <param name="pen">The pen.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>
|
|||
/// The Image
|
|||
/// </returns>
|
|||
public static Image<TColor> DrawBeziers<TColor>(this Image<TColor> source, IPen<TColor> pen, Vector2[] points, GraphicsOptions options) |
|||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|||
{ |
|||
return source.DrawPath(pen, new Path(new BezierLineSegment(points)), options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the provided Points as an open Bezier path with the supplied pen
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The source.</param>
|
|||
/// <param name="pen">The pen.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <returns>The Image</returns>
|
|||
public static Image<TColor> DrawBeziers<TColor>(this Image<TColor> source, IPen<TColor> pen, Vector2[] points) |
|||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|||
{ |
|||
return source.DrawPath(pen, new Path(new BezierLineSegment(points))); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,111 @@ |
|||
// <copyright file="DrawPath.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System; |
|||
|
|||
using Drawing; |
|||
using Drawing.Brushes; |
|||
using Drawing.Pens; |
|||
using Drawing.Processors; |
|||
|
|||
/// <summary>
|
|||
/// Extension methods for the <see cref="Image{TColor}"/> type.
|
|||
/// </summary>
|
|||
public static partial class ImageExtensions |
|||
{ |
|||
/// <summary>
|
|||
/// Draws the outline of the region with the provided pen.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="pen">The pen.</param>
|
|||
/// <param name="path">The path.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> Draw<TColor>(this Image<TColor> source, IPen<TColor> pen, Drawable path, GraphicsOptions options) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.Apply(new DrawPathProcessor<TColor>(pen, path, options)); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the outline of the polygon with the provided pen.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="pen">The pen.</param>
|
|||
/// <param name="path">The path.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> Draw<TColor>(this Image<TColor> source, IPen<TColor> pen, Drawable path) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.Draw(pen, path, GraphicsOptions.Default); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the outline of the polygon with the provided brush at the provided thickness.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="brush">The brush.</param>
|
|||
/// <param name="thickness">The thickness.</param>
|
|||
/// <param name="path">The path.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> Draw<TColor>(this Image<TColor> source, IBrush<TColor> brush, float thickness, Drawable path, GraphicsOptions options) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.Draw(new Pen<TColor>(brush, thickness), path, options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the outline of the polygon with the provided brush at the provided thickness.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="brush">The brush.</param>
|
|||
/// <param name="thickness">The thickness.</param>
|
|||
/// <param name="path">The path.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> Draw<TColor>(this Image<TColor> source, IBrush<TColor> brush, float thickness, Drawable path) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.Draw(new Pen<TColor>(brush, thickness), path); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the outline of the polygon with the provided brush at the provided thickness.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="color">The color.</param>
|
|||
/// <param name="thickness">The thickness.</param>
|
|||
/// <param name="path">The path.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> Draw<TColor>(this Image<TColor> source, TColor color, float thickness, Drawable path, GraphicsOptions options) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.Draw(new SolidBrush<TColor>(color), thickness, path, options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws the outline of the polygon with the provided brush at the provided thickness.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="color">The color.</param>
|
|||
/// <param name="thickness">The thickness.</param>
|
|||
/// <param name="path">The path.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> Draw<TColor>(this Image<TColor> source, TColor color, float thickness, Drawable path) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.Draw(new SolidBrush<TColor>(color), thickness, path); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,51 @@ |
|||
// <copyright file="Drawable.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Drawing |
|||
{ |
|||
/// <summary>
|
|||
/// Represents a path or set of paths that can be drawn as an outline.
|
|||
/// </summary>
|
|||
public abstract class Drawable |
|||
{ |
|||
/// <summary>
|
|||
/// Gets the maximum number of intersections to could be returned.
|
|||
/// </summary>
|
|||
public abstract int MaxIntersections { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the bounds.
|
|||
/// </summary>
|
|||
public abstract Rectangle Bounds { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the point information for the specified x and y location.
|
|||
/// </summary>
|
|||
/// <param name="x">The x.</param>
|
|||
/// <param name="y">The y.</param>
|
|||
/// <returns>Information about the point in relation to a drawable edge</returns>
|
|||
public abstract PointInfo GetPointInfo(int x, int y); |
|||
|
|||
/// <summary>
|
|||
/// Scans the X axis for intersections.
|
|||
/// </summary>
|
|||
/// <param name="x">The x.</param>
|
|||
/// <param name="buffer">The buffer.</param>
|
|||
/// <param name="length">The length.</param>
|
|||
/// <param name="offset">The offset.</param>
|
|||
/// <returns>The number of intersections found.</returns>
|
|||
public abstract int ScanX(int x, float[] buffer, int length, int offset); |
|||
|
|||
/// <summary>
|
|||
/// Scans the Y axis for intersections.
|
|||
/// </summary>
|
|||
/// <param name="y">The position along the y axis to find intersections.</param>
|
|||
/// <param name="buffer">The buffer.</param>
|
|||
/// <param name="length">The length.</param>
|
|||
/// <param name="offset">The offset.</param>
|
|||
/// <returns>The number of intersections found.</returns>
|
|||
public abstract int ScanY(int y, float[] buffer, int length, int offset); |
|||
} |
|||
} |
|||
@ -1,173 +0,0 @@ |
|||
// <copyright file="Fill.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System; |
|||
using System.Numerics; |
|||
using Drawing; |
|||
using Drawing.Brushes; |
|||
using Drawing.Paths; |
|||
using Drawing.Processors; |
|||
using Drawing.Shapes; |
|||
|
|||
/// <summary>
|
|||
/// Extension methods for the <see cref="Image{TColor}"/> type.
|
|||
/// </summary>
|
|||
public static partial class ImageExtensions |
|||
{ |
|||
/// <summary>
|
|||
/// Flood fills the image with the specified brush.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The source.</param>
|
|||
/// <param name="brush">The brush.</param>
|
|||
/// <returns>The Image</returns>
|
|||
public static Image<TColor> Fill<TColor>(this Image<TColor> source, IBrush<TColor> brush) |
|||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|||
{ |
|||
return source.Apply(new FillProcessor<TColor>(brush)); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Flood fills the image with the specified color.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The source.</param>
|
|||
/// <param name="color">The color.</param>
|
|||
/// <returns>The Image</returns>
|
|||
public static Image<TColor> Fill<TColor>(this Image<TColor> source, TColor color) |
|||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|||
{ |
|||
return source.Fill(new SolidBrush<TColor>(color)); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Flood fills the image in the shape o fhte provided polygon with the specified brush..
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The source.</param>
|
|||
/// <param name="brush">The brush.</param>
|
|||
/// <param name="shape">The shape.</param>
|
|||
/// <param name="options">The graphics options.</param>
|
|||
/// <returns>The Image</returns>
|
|||
public static Image<TColor> Fill<TColor>(this Image<TColor> source, IBrush<TColor> brush, IShape shape, GraphicsOptions options) |
|||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|||
{ |
|||
return source.Apply(new FillShapeProcessor<TColor>(brush, shape, options)); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Flood fills the image in the shape of the provided polygon with the specified brush.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The source.</param>
|
|||
/// <param name="brush">The brush.</param>
|
|||
/// <param name="shape">The shape.</param>
|
|||
/// <returns>The Image</returns>
|
|||
public static Image<TColor> Fill<TColor>(this Image<TColor> source, IBrush<TColor> brush, IShape shape) |
|||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|||
{ |
|||
return source.Apply(new FillShapeProcessor<TColor>(brush, shape, GraphicsOptions.Default)); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Flood fills the image in the shape o fhte provided polygon with the specified brush..
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The source.</param>
|
|||
/// <param name="color">The color.</param>
|
|||
/// <param name="shape">The shape.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>
|
|||
/// The Image
|
|||
/// </returns>
|
|||
public static Image<TColor> Fill<TColor>(this Image<TColor> source, TColor color, IShape shape, GraphicsOptions options) |
|||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|||
{ |
|||
return source.Fill(new SolidBrush<TColor>(color), shape, options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Flood fills the image in the shape o fhte provided polygon with the specified brush..
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The source.</param>
|
|||
/// <param name="color">The color.</param>
|
|||
/// <param name="shape">The shape.</param>
|
|||
/// <returns>The Image</returns>
|
|||
public static Image<TColor> Fill<TColor>(this Image<TColor> source, TColor color, IShape shape) |
|||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|||
{ |
|||
return source.Fill(new SolidBrush<TColor>(color), shape); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Flood fills the image in the shape of a Linear polygon described by the points
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The source.</param>
|
|||
/// <param name="brush">The brush.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>
|
|||
/// The Image
|
|||
/// </returns>
|
|||
public static Image<TColor> FillPolygon<TColor>(this Image<TColor> source, IBrush<TColor> brush, Vector2[] points, GraphicsOptions options) |
|||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|||
{ |
|||
// using Polygon directly instead of LinearPolygon as its will have less indirection
|
|||
return source.Fill(brush, new Polygon(new LinearLineSegment(points)), options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Flood fills the image in the shape of a Linear polygon described by the points
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The source.</param>
|
|||
/// <param name="brush">The brush.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <returns>The Image</returns>
|
|||
public static Image<TColor> FillPolygon<TColor>(this Image<TColor> source, IBrush<TColor> brush, Vector2[] points) |
|||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|||
{ |
|||
// using Polygon directly instead of LinearPolygon as its will have less indirection
|
|||
return source.Fill(brush, new Polygon(new LinearLineSegment(points))); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Flood fills the image in the shape of a Linear polygon described by the points
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The source.</param>
|
|||
/// <param name="color">The color.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>
|
|||
/// The Image
|
|||
/// </returns>
|
|||
public static Image<TColor> FillPolygon<TColor>(this Image<TColor> source, TColor color, Vector2[] points, GraphicsOptions options) |
|||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|||
{ |
|||
// using Polygon directly instead of LinearPolygon as its will have less indirection
|
|||
return source.Fill(new SolidBrush<TColor>(color), new Polygon(new LinearLineSegment(points)), options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Flood fills the image in the shape of a Linear polygon described by the points
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The source.</param>
|
|||
/// <param name="color">The color.</param>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <returns>The Image</returns>
|
|||
public static Image<TColor> FillPolygon<TColor>(this Image<TColor> source, TColor color, Vector2[] points) |
|||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|||
{ |
|||
// using Polygon directly instead of LinearPolygon as its will have less indirection
|
|||
return source.Fill(new SolidBrush<TColor>(color), new Polygon(new LinearLineSegment(points))); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,103 @@ |
|||
// <copyright file="FillRegion.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp |
|||
{ |
|||
using System; |
|||
|
|||
using Drawing; |
|||
using Drawing.Brushes; |
|||
using Drawing.Processors; |
|||
|
|||
/// <summary>
|
|||
/// Extension methods for the <see cref="Image{TColor}"/> type.
|
|||
/// </summary>
|
|||
public static partial class ImageExtensions |
|||
{ |
|||
/// <summary>
|
|||
/// Flood fills the image with the specified brush.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="brush">The details how to fill the region of interest.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> Fill<TColor>(this Image<TColor> source, IBrush<TColor> brush) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.Apply(new FillProcessor<TColor>(brush)); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Flood fills the image with the specified color.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="color">The color.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> Fill<TColor>(this Image<TColor> source, TColor color) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.Fill(new SolidBrush<TColor>(color)); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Flood fills the image with in the region with the specified brush.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="brush">The brush.</param>
|
|||
/// <param name="region">The region.</param>
|
|||
/// <param name="options">The graphics options.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> Fill<TColor>(this Image<TColor> source, IBrush<TColor> brush, Region region, GraphicsOptions options) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.Apply(new FillRegionProcessor<TColor>(brush, region, options)); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Flood fills the image with in the region with the specified brush.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="brush">The brush.</param>
|
|||
/// <param name="region">The region.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> Fill<TColor>(this Image<TColor> source, IBrush<TColor> brush, Region region) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.Fill(brush, region, GraphicsOptions.Default); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Flood fills the image with in the region with the specified color.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="color">The color.</param>
|
|||
/// <param name="region">The region.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> Fill<TColor>(this Image<TColor> source, TColor color, Region region, GraphicsOptions options) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.Fill(new SolidBrush<TColor>(color), region, options); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Flood fills the image with in the region with the specified color.
|
|||
/// </summary>
|
|||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="color">The color.</param>
|
|||
/// <param name="region">The region.</param>
|
|||
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
|||
public static Image<TColor> Fill<TColor>(this Image<TColor> source, TColor color, Region region) |
|||
where TColor : struct, IPixel<TColor> |
|||
{ |
|||
return source.Fill(new SolidBrush<TColor>(color), region); |
|||
} |
|||
} |
|||
} |
|||
@ -1,119 +0,0 @@ |
|||
// <copyright file="BezierLineSegment.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Drawing.Paths |
|||
{ |
|||
using System.Numerics; |
|||
|
|||
/// <summary>
|
|||
/// Represents a line segment that conistst of control points that will be rendered as a cubic bezier curve
|
|||
/// </summary>
|
|||
/// <seealso cref="ImageSharp.Drawing.Paths.ILineSegment" />
|
|||
public class BezierLineSegment : ILineSegment |
|||
{ |
|||
/// <summary>
|
|||
/// The segments per curve.
|
|||
/// code for this taken from <see href="http://devmag.org.za/2011/04/05/bzier-curves-a-tutorial/"/>
|
|||
/// </summary>
|
|||
private const int SegmentsPerCurve = 50; |
|||
|
|||
/// <summary>
|
|||
/// The line points.
|
|||
/// </summary>
|
|||
private readonly Vector2[] linePoints; |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="BezierLineSegment"/> class.
|
|||
/// </summary>
|
|||
/// <param name="points">The points.</param>
|
|||
public BezierLineSegment(params Vector2[] points) |
|||
{ |
|||
Guard.NotNull(points, nameof(points)); |
|||
Guard.MustBeGreaterThanOrEqualTo(points.Length, 4, nameof(points)); |
|||
|
|||
this.linePoints = this.GetDrawingPoints(points); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Returns the current <see cref="ILineSegment" /> a simple linear path.
|
|||
/// </summary>
|
|||
/// <returns>
|
|||
/// Returns the current <see cref="ILineSegment" /> as simple linear path.
|
|||
/// </returns>
|
|||
public Vector2[] AsSimpleLinearPath() |
|||
{ |
|||
return this.linePoints; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Returns the drawing points along the line.
|
|||
/// </summary>
|
|||
/// <param name="controlPoints">The control points.</param>
|
|||
/// <returns>
|
|||
/// The <see cref="T:Vector2[]"/>.
|
|||
/// </returns>
|
|||
private Vector2[] GetDrawingPoints(Vector2[] controlPoints) |
|||
{ |
|||
// TODO we need to calculate an optimal SegmentsPerCurve value
|
|||
// depending on the calcualted length of this curve
|
|||
int curveCount = (controlPoints.Length - 1) / 3; |
|||
int finalPointCount = (SegmentsPerCurve * curveCount) + 1; // we have SegmentsPerCurve for each curve plus the origon point;
|
|||
|
|||
Vector2[] drawingPoints = new Vector2[finalPointCount]; |
|||
|
|||
int position = 0; |
|||
int targetPoint = controlPoints.Length - 3; |
|||
for (int i = 0; i < targetPoint; i += 3) |
|||
{ |
|||
Vector2 p0 = controlPoints[i]; |
|||
Vector2 p1 = controlPoints[i + 1]; |
|||
Vector2 p2 = controlPoints[i + 2]; |
|||
Vector2 p3 = controlPoints[i + 3]; |
|||
|
|||
// only do this for the first end point. When i != 0, this coincides with the end point of the previous segment,
|
|||
if (i == 0) |
|||
{ |
|||
drawingPoints[position++] = this.CalculateBezierPoint(0, p0, p1, p2, p3); |
|||
} |
|||
|
|||
for (int j = 1; j <= SegmentsPerCurve; j++) |
|||
{ |
|||
float t = j / (float)SegmentsPerCurve; |
|||
drawingPoints[position++] = this.CalculateBezierPoint(t, p0, p1, p2, p3); |
|||
} |
|||
} |
|||
|
|||
return drawingPoints; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Calculates the bezier point along the line.
|
|||
/// </summary>
|
|||
/// <param name="t">The position within the line.</param>
|
|||
/// <param name="p0">The p 0.</param>
|
|||
/// <param name="p1">The p 1.</param>
|
|||
/// <param name="p2">The p 2.</param>
|
|||
/// <param name="p3">The p 3.</param>
|
|||
/// <returns>
|
|||
/// The <see cref="Vector2"/>.
|
|||
/// </returns>
|
|||
private Vector2 CalculateBezierPoint(float t, Vector2 p0, Vector2 p1, Vector2 p2, Vector2 p3) |
|||
{ |
|||
float u = 1 - t; |
|||
float tt = t * t; |
|||
float uu = u * u; |
|||
float uuu = uu * u; |
|||
float ttt = tt * t; |
|||
|
|||
Vector2 p = uuu * p0; // first term
|
|||
|
|||
p += 3 * uu * t * p1; // second term
|
|||
p += 3 * u * tt * p2; // third term
|
|||
p += ttt * p3; // fourth term
|
|||
|
|||
return p; |
|||
} |
|||
} |
|||
} |
|||
@ -1,21 +0,0 @@ |
|||
// <copyright file="ILineSegment.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Drawing.Paths |
|||
{ |
|||
using System.Numerics; |
|||
|
|||
/// <summary>
|
|||
/// Represents a simple path segment
|
|||
/// </summary>
|
|||
public interface ILineSegment |
|||
{ |
|||
/// <summary>
|
|||
/// Converts the <see cref="ILineSegment" /> into a simple linear path..
|
|||
/// </summary>
|
|||
/// <returns>Returns the current <see cref="ILineSegment" /> as simple linear path.</returns>
|
|||
Vector2[] AsSimpleLinearPath(); // TODO move this over to ReadonlySpan<Vector2> once available
|
|||
} |
|||
} |
|||
@ -1,48 +0,0 @@ |
|||
// <copyright file="IPath.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Drawing.Paths |
|||
{ |
|||
using System.Numerics; |
|||
|
|||
/// <summary>
|
|||
/// Represents a logic path that can be drawn
|
|||
/// </summary>
|
|||
public interface IPath : ILineSegment |
|||
{ |
|||
/// <summary>
|
|||
/// Gets the bounds enclosing the path
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// The bounds.
|
|||
/// </value>
|
|||
RectangleF Bounds { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets a value indicating whether this instance is closed.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// <c>true</c> if this instance is closed; otherwise, <c>false</c>.
|
|||
/// </value>
|
|||
bool IsClosed { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the length of the path
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// The length.
|
|||
/// </value>
|
|||
float Length { get; } |
|||
|
|||
/// <summary>
|
|||
/// Calculates the distance along and away from the path for a specified point.
|
|||
/// </summary>
|
|||
/// <param name="point">The point along the path.</param>
|
|||
/// <returns>
|
|||
/// Returns details about the point and its distance away from the path.
|
|||
/// </returns>
|
|||
PointInfo Distance(Vector2 point); |
|||
} |
|||
} |
|||
@ -1,516 +0,0 @@ |
|||
// <copyright file="InternalPath.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
namespace ImageSharp.Drawing.Paths |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Numerics; |
|||
|
|||
/// <summary>
|
|||
/// Internal logic for integrating linear paths.
|
|||
/// </summary>
|
|||
internal class InternalPath |
|||
{ |
|||
/// <summary>
|
|||
/// The maximum vector
|
|||
/// </summary>
|
|||
private static readonly Vector2 MaxVector = new Vector2(float.MaxValue); |
|||
|
|||
/// <summary>
|
|||
/// The locker.
|
|||
/// </summary>
|
|||
private static readonly object Locker = new object(); |
|||
|
|||
/// <summary>
|
|||
/// The points.
|
|||
/// </summary>
|
|||
private readonly Vector2[] points; |
|||
|
|||
/// <summary>
|
|||
/// The closed path.
|
|||
/// </summary>
|
|||
private readonly bool closedPath; |
|||
|
|||
/// <summary>
|
|||
/// The total distance.
|
|||
/// </summary>
|
|||
private readonly Lazy<float> totalDistance; |
|||
|
|||
/// <summary>
|
|||
/// The constant.
|
|||
/// </summary>
|
|||
private float[] constant; |
|||
|
|||
/// <summary>
|
|||
/// The multiples.
|
|||
/// </summary>
|
|||
private float[] multiple; |
|||
|
|||
/// <summary>
|
|||
/// The distances.
|
|||
/// </summary>
|
|||
private float[] distance; |
|||
|
|||
/// <summary>
|
|||
/// The calculated.
|
|||
/// </summary>
|
|||
private bool calculated = false; |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="InternalPath"/> class.
|
|||
/// </summary>
|
|||
/// <param name="segments">The segments.</param>
|
|||
/// <param name="isClosedPath">if set to <c>true</c> [is closed path].</param>
|
|||
internal InternalPath(ILineSegment[] segments, bool isClosedPath) |
|||
: this(Simplify(segments), isClosedPath) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="InternalPath" /> class.
|
|||
/// </summary>
|
|||
/// <param name="segment">The segment.</param>
|
|||
/// <param name="isClosedPath">if set to <c>true</c> [is closed path].</param>
|
|||
internal InternalPath(ILineSegment segment, bool isClosedPath) |
|||
: this(segment.AsSimpleLinearPath(), isClosedPath) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="InternalPath" /> class.
|
|||
/// </summary>
|
|||
/// <param name="points">The points.</param>
|
|||
/// <param name="isClosedPath">if set to <c>true</c> [is closed path].</param>
|
|||
internal InternalPath(Vector2[] points, bool isClosedPath) |
|||
{ |
|||
this.points = points; |
|||
this.closedPath = isClosedPath; |
|||
|
|||
float minX = this.points.Min(x => x.X); |
|||
float maxX = this.points.Max(x => x.X); |
|||
float minY = this.points.Min(x => x.Y); |
|||
float maxY = this.points.Max(x => x.Y); |
|||
|
|||
this.Bounds = new RectangleF(minX, minY, maxX - minX, maxY - minY); |
|||
this.totalDistance = new Lazy<float>(this.CalculateLength); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the bounds.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// The bounds.
|
|||
/// </value>
|
|||
public RectangleF Bounds |
|||
{ |
|||
get; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the length.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// The length.
|
|||
/// </value>
|
|||
public float Length => this.totalDistance.Value; |
|||
|
|||
/// <summary>
|
|||
/// Gets the points.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// The points.
|
|||
/// </value>
|
|||
internal Vector2[] Points => this.points; |
|||
|
|||
/// <summary>
|
|||
/// Calculates the distance from the path.
|
|||
/// </summary>
|
|||
/// <param name="point">The point.</param>
|
|||
/// <returns>Returns the distance from the path</returns>
|
|||
public PointInfo DistanceFromPath(Vector2 point) |
|||
{ |
|||
this.CalculateConstants(); |
|||
|
|||
PointInfoInternal internalInfo = default(PointInfoInternal); |
|||
internalInfo.DistanceSquared = float.MaxValue; // Set it to max so that CalculateShorterDistance can reduce it back down
|
|||
|
|||
int polyCorners = this.points.Length; |
|||
|
|||
if (!this.closedPath) |
|||
{ |
|||
polyCorners -= 1; |
|||
} |
|||
|
|||
int closestPoint = 0; |
|||
for (int i = 0; i < polyCorners; i++) |
|||
{ |
|||
int next = i + 1; |
|||
if (this.closedPath && next == polyCorners) |
|||
{ |
|||
next = 0; |
|||
} |
|||
|
|||
if (this.CalculateShorterDistance(this.points[i], this.points[next], point, ref internalInfo)) |
|||
{ |
|||
closestPoint = i; |
|||
} |
|||
} |
|||
|
|||
return new PointInfo |
|||
{ |
|||
DistanceAlongPath = this.distance[closestPoint] + Vector2.Distance(this.points[closestPoint], point), |
|||
DistanceFromPath = (float)Math.Sqrt(internalInfo.DistanceSquared), |
|||
SearchPoint = point, |
|||
ClosestPointOnPath = internalInfo.PointOnLine |
|||
}; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Based on a line described by <paramref name="start" /> and <paramref name="end" />
|
|||
/// populate a buffer for all points on the path that the line intersects.
|
|||
/// </summary>
|
|||
/// <param name="start">The start.</param>
|
|||
/// <param name="end">The end.</param>
|
|||
/// <param name="buffer">The buffer.</param>
|
|||
/// <param name="count">The count.</param>
|
|||
/// <param name="offset">The offset.</param>
|
|||
/// <returns>number iof intersections hit</returns>
|
|||
public int FindIntersections(Vector2 start, Vector2 end, Vector2[] buffer, int count, int offset) |
|||
{ |
|||
int polyCorners = this.points.Length; |
|||
|
|||
if (!this.closedPath) |
|||
{ |
|||
polyCorners -= 1; |
|||
} |
|||
|
|||
int position = 0; |
|||
for (int i = 0; i < polyCorners && count > 0; i++) |
|||
{ |
|||
int next = i + 1; |
|||
if (this.closedPath && next == polyCorners) |
|||
{ |
|||
next = 0; |
|||
} |
|||
|
|||
Vector2 point = FindIntersection(this.points[i], this.points[next], start, end); |
|||
if (point != MaxVector) |
|||
{ |
|||
buffer[position + offset] = point; |
|||
position++; |
|||
count--; |
|||
} |
|||
} |
|||
|
|||
return position; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Determines if the specified point is inside or outside the path.
|
|||
/// </summary>
|
|||
/// <param name="point">The point.</param>
|
|||
/// <returns>Returns true if the point is inside the closed path.</returns>
|
|||
public bool PointInPolygon(Vector2 point) |
|||
{ |
|||
// You can only be inside a path if its "closed"
|
|||
if (!this.closedPath) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
if (!this.Bounds.Contains(point.X, point.Y)) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
this.CalculateConstants(); |
|||
|
|||
Vector2[] poly = this.points; |
|||
int polyCorners = poly.Length; |
|||
|
|||
int j = polyCorners - 1; |
|||
bool oddNodes = false; |
|||
|
|||
for (int i = 0; i < polyCorners; i++) |
|||
{ |
|||
if ((poly[i].Y < point.Y && poly[j].Y >= point.Y) |
|||
|| (poly[j].Y < point.Y && poly[i].Y >= point.Y)) |
|||
{ |
|||
oddNodes ^= (point.Y * this.multiple[i]) + this.constant[i] < point.X; |
|||
} |
|||
|
|||
j = i; |
|||
} |
|||
|
|||
return oddNodes; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Determins if the bounding box for 2 lines
|
|||
/// described by <paramref name="line1Start" /> and <paramref name="line1End" />
|
|||
/// and <paramref name="line2Start" /> and <paramref name="line2End" /> overlap.
|
|||
/// </summary>
|
|||
/// <param name="line1Start">The line1 start.</param>
|
|||
/// <param name="line1End">The line1 end.</param>
|
|||
/// <param name="line2Start">The line2 start.</param>
|
|||
/// <param name="line2End">The line2 end.</param>
|
|||
/// <returns>Returns true it the bounding box of the 2 lines intersect</returns>
|
|||
private static bool BoundingBoxesIntersect(Vector2 line1Start, Vector2 line1End, Vector2 line2Start, Vector2 line2End) |
|||
{ |
|||
Vector2 topLeft1 = Vector2.Min(line1Start, line1End); |
|||
Vector2 bottomRight1 = Vector2.Max(line1Start, line1End); |
|||
|
|||
Vector2 topLeft2 = Vector2.Min(line2Start, line2End); |
|||
Vector2 bottomRight2 = Vector2.Max(line2Start, line2End); |
|||
|
|||
float left1 = topLeft1.X; |
|||
float right1 = bottomRight1.X; |
|||
float top1 = topLeft1.Y; |
|||
float bottom1 = bottomRight1.Y; |
|||
|
|||
float left2 = topLeft2.X; |
|||
float right2 = bottomRight2.X; |
|||
float top2 = topLeft2.Y; |
|||
float bottom2 = bottomRight2.Y; |
|||
|
|||
return left1 <= right2 && right1 >= left2 |
|||
&& |
|||
top1 <= bottom2 && bottom1 >= top2; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Finds the point on line described by <paramref name="line1Start" /> and <paramref name="line1End" />
|
|||
/// that intersects with line described by <paramref name="line2Start" /> and <paramref name="line2End" />
|
|||
/// </summary>
|
|||
/// <param name="line1Start">The line1 start.</param>
|
|||
/// <param name="line1End">The line1 end.</param>
|
|||
/// <param name="line2Start">The line2 start.</param>
|
|||
/// <param name="line2End">The line2 end.</param>
|
|||
/// <returns>
|
|||
/// A <see cref="Vector2"/> describing the point that the 2 lines cross or <see cref="MaxVector"/> if they do not.
|
|||
/// </returns>
|
|||
private static Vector2 FindIntersection(Vector2 line1Start, Vector2 line1End, Vector2 line2Start, Vector2 line2End) |
|||
{ |
|||
// do bounding boxes overlap, if not then the lines can't and return fast.
|
|||
if (!BoundingBoxesIntersect(line1Start, line1End, line2Start, line2End)) |
|||
{ |
|||
return MaxVector; |
|||
} |
|||
|
|||
Vector2 line1Diff = line1End - line1Start; |
|||
Vector2 line2Diff = line2End - line2Start; |
|||
|
|||
Vector2 point; |
|||
if (line1Diff.X == 0) |
|||
{ |
|||
float slope = line2Diff.Y / line2Diff.X; |
|||
float yinter = line2Start.Y - (slope * line2Start.X); |
|||
float y = (line1Start.X * slope) + yinter; |
|||
point = new Vector2(line1Start.X, y); |
|||
|
|||
// horizontal and vertical lines
|
|||
} |
|||
else if (line2Diff.X == 0) |
|||
{ |
|||
float slope = line1Diff.Y / line1Diff.X; |
|||
float yinter = line1Start.Y - (slope * line1Start.X); |
|||
float y = (line2Start.X * slope) + yinter; |
|||
point = new Vector2(line2Start.X, y); |
|||
|
|||
// horizontal and vertical lines
|
|||
} |
|||
else |
|||
{ |
|||
float slope1 = line1Diff.Y / line1Diff.X; |
|||
float slope2 = line2Diff.Y / line2Diff.X; |
|||
|
|||
float yinter1 = line1Start.Y - (slope1 * line1Start.X); |
|||
float yinter2 = line2Start.Y - (slope2 * line2Start.X); |
|||
|
|||
if (slope1 == slope2 && yinter1 != yinter2) |
|||
{ |
|||
return MaxVector; |
|||
} |
|||
|
|||
float x = (yinter2 - yinter1) / (slope1 - slope2); |
|||
float y = (slope1 * x) + yinter1; |
|||
|
|||
point = new Vector2(x, y); |
|||
} |
|||
|
|||
if (BoundingBoxesIntersect(line1Start, line1End, point, point)) |
|||
{ |
|||
return point; |
|||
} |
|||
else if (BoundingBoxesIntersect(line2Start, line2End, point, point)) |
|||
{ |
|||
return point; |
|||
} |
|||
|
|||
return MaxVector; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Simplifies the collection of segments.
|
|||
/// </summary>
|
|||
/// <param name="segments">The segments.</param>
|
|||
/// <returns>
|
|||
/// The <see cref="T:Vector2[]"/>.
|
|||
/// </returns>
|
|||
private static Vector2[] Simplify(ILineSegment[] segments) |
|||
{ |
|||
List<Vector2> simplified = new List<Vector2>(); |
|||
foreach (ILineSegment seg in segments) |
|||
{ |
|||
simplified.AddRange(seg.AsSimpleLinearPath()); |
|||
} |
|||
|
|||
return simplified.ToArray(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Returns the length of the path.
|
|||
/// </summary>
|
|||
/// <returns>
|
|||
/// The <see cref="float"/>.
|
|||
/// </returns>
|
|||
private float CalculateLength() |
|||
{ |
|||
float length = 0; |
|||
int polyCorners = this.points.Length; |
|||
|
|||
if (!this.closedPath) |
|||
{ |
|||
polyCorners -= 1; |
|||
} |
|||
|
|||
for (int i = 0; i < polyCorners; i++) |
|||
{ |
|||
int next = i + 1; |
|||
if (this.closedPath && next == polyCorners) |
|||
{ |
|||
next = 0; |
|||
} |
|||
|
|||
length += Vector2.Distance(this.points[i], this.points[next]); |
|||
} |
|||
|
|||
return length; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Calculate the constants.
|
|||
/// </summary>
|
|||
private void CalculateConstants() |
|||
{ |
|||
// http://alienryderflex.com/polygon/ source for point in polygon logic
|
|||
if (this.calculated) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
lock (Locker) |
|||
{ |
|||
if (this.calculated) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
Vector2[] poly = this.points; |
|||
int polyCorners = poly.Length; |
|||
this.constant = new float[polyCorners]; |
|||
this.multiple = new float[polyCorners]; |
|||
this.distance = new float[polyCorners]; |
|||
int i, j = polyCorners - 1; |
|||
|
|||
this.distance[0] = 0; |
|||
|
|||
for (i = 0; i < polyCorners; i++) |
|||
{ |
|||
this.distance[j] = this.distance[i] + Vector2.Distance(poly[i], poly[j]); |
|||
if (poly[j].Y == poly[i].Y) |
|||
{ |
|||
this.constant[i] = poly[i].X; |
|||
this.multiple[i] = 0; |
|||
} |
|||
else |
|||
{ |
|||
Vector2 subtracted = poly[j] - poly[i]; |
|||
this.constant[i] = (poly[i].X - ((poly[i].Y * poly[j].X) / subtracted.Y)) + ((poly[i].Y * poly[i].X) / subtracted.Y); |
|||
this.multiple[i] = subtracted.X / subtracted.Y; |
|||
} |
|||
|
|||
j = i; |
|||
} |
|||
|
|||
this.calculated = true; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Calculate any shorter distances along the path.
|
|||
/// </summary>
|
|||
/// <param name="start">The start position.</param>
|
|||
/// <param name="end">The end position.</param>
|
|||
/// <param name="point">The current point.</param>
|
|||
/// <param name="info">The info.</param>
|
|||
/// <returns>
|
|||
/// The <see cref="bool"/>.
|
|||
/// </returns>
|
|||
private bool CalculateShorterDistance(Vector2 start, Vector2 end, Vector2 point, ref PointInfoInternal info) |
|||
{ |
|||
Vector2 diffEnds = end - start; |
|||
|
|||
float lengthSquared = diffEnds.LengthSquared(); |
|||
Vector2 diff = point - start; |
|||
|
|||
Vector2 multiplied = diff * diffEnds; |
|||
float u = (multiplied.X + multiplied.Y) / lengthSquared; |
|||
|
|||
if (u > 1) |
|||
{ |
|||
u = 1; |
|||
} |
|||
else if (u < 0) |
|||
{ |
|||
u = 0; |
|||
} |
|||
|
|||
Vector2 multipliedByU = diffEnds * u; |
|||
|
|||
Vector2 pointOnLine = start + multipliedByU; |
|||
|
|||
Vector2 d = pointOnLine - point; |
|||
|
|||
float dist = d.LengthSquared(); |
|||
|
|||
if (info.DistanceSquared > dist) |
|||
{ |
|||
info.DistanceSquared = dist; |
|||
info.PointOnLine = pointOnLine; |
|||
return true; |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Contains information about the current point.
|
|||
/// </summary>
|
|||
private struct PointInfoInternal |
|||
{ |
|||
/// <summary>
|
|||
/// The distance squared.
|
|||
/// </summary>
|
|||
public float DistanceSquared; |
|||
|
|||
/// <summary>
|
|||
/// The point on the current line.
|
|||
/// </summary>
|
|||
public Vector2 PointOnLine; |
|||
} |
|||
} |
|||
} |
|||
@ -1,55 +0,0 @@ |
|||
// <copyright file="LinearLineSegment.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Drawing.Paths |
|||
{ |
|||
using System.Linq; |
|||
using System.Numerics; |
|||
|
|||
/// <summary>
|
|||
/// Represents a series of control points that will be joined by straight lines
|
|||
/// </summary>
|
|||
/// <seealso cref="ILineSegment" />
|
|||
public class LinearLineSegment : ILineSegment |
|||
{ |
|||
/// <summary>
|
|||
/// The collection of points.
|
|||
/// </summary>
|
|||
private readonly Vector2[] points; |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="LinearLineSegment"/> class.
|
|||
/// </summary>
|
|||
/// <param name="start">The start.</param>
|
|||
/// <param name="end">The end.</param>
|
|||
public LinearLineSegment(Vector2 start, Vector2 end) |
|||
: this(new[] { start, end }) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="LinearLineSegment"/> class.
|
|||
/// </summary>
|
|||
/// <param name="points">The points.</param>
|
|||
public LinearLineSegment(params Vector2[] points) |
|||
{ |
|||
Guard.NotNull(points, nameof(points)); |
|||
Guard.MustBeGreaterThanOrEqualTo(points.Count(), 2, nameof(points)); |
|||
|
|||
this.points = points; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Converts the <see cref="ILineSegment" /> into a simple linear path..
|
|||
/// </summary>
|
|||
/// <returns>
|
|||
/// Returns the current <see cref="ILineSegment" /> as simple linear path.
|
|||
/// </returns>
|
|||
public Vector2[] AsSimpleLinearPath() |
|||
{ |
|||
return this.points; |
|||
} |
|||
} |
|||
} |
|||
@ -1,51 +0,0 @@ |
|||
// <copyright file="Path.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Drawing.Paths |
|||
{ |
|||
using System.Numerics; |
|||
|
|||
/// <summary>
|
|||
/// A aggregate of <see cref="ILineSegment"/>s making a single logical path
|
|||
/// </summary>
|
|||
/// <seealso cref="IPath" />
|
|||
public class Path : IPath |
|||
{ |
|||
/// <summary>
|
|||
/// The inner path.
|
|||
/// </summary>
|
|||
private readonly InternalPath innerPath; |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="Path"/> class.
|
|||
/// </summary>
|
|||
/// <param name="segment">The segment.</param>
|
|||
public Path(params ILineSegment[] segment) |
|||
{ |
|||
this.innerPath = new InternalPath(segment, false); |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
public RectangleF Bounds => this.innerPath.Bounds; |
|||
|
|||
/// <inheritdoc />
|
|||
public bool IsClosed => false; |
|||
|
|||
/// <inheritdoc />
|
|||
public float Length => this.innerPath.Length; |
|||
|
|||
/// <inheritdoc />
|
|||
public Vector2[] AsSimpleLinearPath() |
|||
{ |
|||
return this.innerPath.Points; |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
public PointInfo Distance(Vector2 point) |
|||
{ |
|||
return this.innerPath.DistanceFromPath(point); |
|||
} |
|||
} |
|||
} |
|||
@ -1,35 +0,0 @@ |
|||
// <copyright file="PointInfo.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Drawing.Paths |
|||
{ |
|||
using System.Numerics; |
|||
|
|||
/// <summary>
|
|||
/// Returns meta data about the nearest point on a path from a vector
|
|||
/// </summary>
|
|||
public struct PointInfo |
|||
{ |
|||
/// <summary>
|
|||
/// The search point
|
|||
/// </summary>
|
|||
public Vector2 SearchPoint; |
|||
|
|||
/// <summary>
|
|||
/// The distance along path <see cref="ClosestPointOnPath"/> is away from the start of the path
|
|||
/// </summary>
|
|||
public float DistanceAlongPath; |
|||
|
|||
/// <summary>
|
|||
/// The distance <see cref="SearchPoint"/> is away from <see cref="ClosestPointOnPath"/>.
|
|||
/// </summary>
|
|||
public float DistanceFromPath; |
|||
|
|||
/// <summary>
|
|||
/// The closest point to <see cref="SearchPoint"/> that lies on the path.
|
|||
/// </summary>
|
|||
public Vector2 ClosestPointOnPath; |
|||
} |
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
// <copyright file="PointInfo.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Drawing |
|||
{ |
|||
/// <summary>
|
|||
/// Returns details about how far away from the inside of a shape and the color the pixel could be.
|
|||
/// </summary>
|
|||
public struct PointInfo |
|||
{ |
|||
/// <summary>
|
|||
/// The distance along path
|
|||
/// </summary>
|
|||
public float DistanceAlongPath; |
|||
|
|||
/// <summary>
|
|||
/// The distance from path
|
|||
/// </summary>
|
|||
public float DistanceFromPath; |
|||
} |
|||
} |
|||
@ -0,0 +1,46 @@ |
|||
// <copyright file="Region.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Drawing |
|||
{ |
|||
/// <summary>
|
|||
/// Represents a region of an image.
|
|||
/// </summary>
|
|||
public abstract class Region |
|||
{ |
|||
/// <summary>
|
|||
/// Gets the maximum number of intersections to could be returned.
|
|||
/// </summary>
|
|||
public abstract int MaxIntersections { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the bounding box that entirely surrounds this region.
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// This should always contains all possible points returned from either <see cref="ScanX(int, float[], int, int)"/> or <see cref="ScanY(int, float[], int, int)"/>.
|
|||
/// </remarks>
|
|||
public abstract Rectangle Bounds { get; } |
|||
|
|||
/// <summary>
|
|||
/// Scans the X axis for intersections.
|
|||
/// </summary>
|
|||
/// <param name="x">The position along the X axis to find intersections.</param>
|
|||
/// <param name="buffer">The buffer.</param>
|
|||
/// <param name="length">The length.</param>
|
|||
/// <param name="offset">The offset.</param>
|
|||
/// <returns>The number of intersections found.</returns>
|
|||
public abstract int ScanX(int x, float[] buffer, int length, int offset); |
|||
|
|||
/// <summary>
|
|||
/// Scans the Y axis for intersections.
|
|||
/// </summary>
|
|||
/// <param name="y">The position along the y axis to find intersections.</param>
|
|||
/// <param name="buffer">The buffer.</param>
|
|||
/// <param name="length">The length.</param>
|
|||
/// <param name="offset">The offset.</param>
|
|||
/// <returns>The number of intersections found.</returns>
|
|||
public abstract int ScanY(int y, float[] buffer, int length, int offset); |
|||
} |
|||
} |
|||
@ -1,93 +0,0 @@ |
|||
// <copyright file="BezierPolygon.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Drawing.Shapes |
|||
{ |
|||
using System.Collections; |
|||
using System.Collections.Generic; |
|||
using System.Numerics; |
|||
using Paths; |
|||
|
|||
/// <summary>
|
|||
/// Represents a polygon made up exclusivly of a single close cubic Bezier curve.
|
|||
/// </summary>
|
|||
public sealed class BezierPolygon : IShape |
|||
{ |
|||
private Polygon innerPolygon; |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="BezierPolygon"/> class.
|
|||
/// </summary>
|
|||
/// <param name="points">The points.</param>
|
|||
public BezierPolygon(params Vector2[] points) |
|||
{ |
|||
this.innerPolygon = new Polygon(new BezierLineSegment(points)); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the bounding box of this shape.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// The bounds.
|
|||
/// </value>
|
|||
public RectangleF Bounds => this.innerPolygon.Bounds; |
|||
|
|||
/// <summary>
|
|||
/// Gets the maximum number intersections that a shape can have when testing a line.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// The maximum intersections.
|
|||
/// </value>
|
|||
public int MaxIntersections => this.innerPolygon.MaxIntersections; |
|||
|
|||
/// <summary>
|
|||
/// the distance of the point from the outline of the shape, if the value is negative it is inside the polygon bounds
|
|||
/// </summary>
|
|||
/// <param name="point">The point.</param>
|
|||
/// <returns>
|
|||
/// The distance from the shape.
|
|||
/// </returns>
|
|||
public float Distance(Vector2 point) => this.innerPolygon.Distance(point); |
|||
|
|||
/// <summary>
|
|||
/// Based on a line described by <paramref name="start"/> and <paramref name="end"/>
|
|||
/// populate a buffer for all points on the polygon that the line intersects.
|
|||
/// </summary>
|
|||
/// <param name="start">The start point of the line.</param>
|
|||
/// <param name="end">The end point of the line.</param>
|
|||
/// <param name="buffer">The buffer that will be populated with intersections.</param>
|
|||
/// <param name="count">The count.</param>
|
|||
/// <param name="offset">The offset.</param>
|
|||
/// <returns>
|
|||
/// The number of intersections populated into the buffer.
|
|||
/// </returns>
|
|||
public int FindIntersections(Vector2 start, Vector2 end, Vector2[] buffer, int count, int offset) |
|||
{ |
|||
return this.innerPolygon.FindIntersections(start, end, buffer, count, offset); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Returns an enumerator that iterates through the collection.
|
|||
/// </summary>
|
|||
/// <returns>
|
|||
/// An enumerator that can be used to iterate through the collection.
|
|||
/// </returns>
|
|||
public IEnumerator<IPath> GetEnumerator() |
|||
{ |
|||
return this.innerPolygon.GetEnumerator(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Returns an enumerator that iterates through a collection.
|
|||
/// </summary>
|
|||
/// <returns>
|
|||
/// An <see cref="T:System.Collections.IEnumerator" /> object that can be used to iterate through the collection.
|
|||
/// </returns>
|
|||
IEnumerator IEnumerable.GetEnumerator() |
|||
{ |
|||
return this.innerPolygon.GetEnumerator(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,246 +0,0 @@ |
|||
// <copyright file="ComplexPolygon.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Drawing.Shapes |
|||
{ |
|||
using System; |
|||
using System.Collections; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Numerics; |
|||
|
|||
using Paths; |
|||
using PolygonClipper; |
|||
|
|||
/// <summary>
|
|||
/// Represents a complex polygon made up of one or more outline
|
|||
/// polygons and one or more holes to punch out of them.
|
|||
/// </summary>
|
|||
/// <seealso cref="ImageSharp.Drawing.Shapes.IShape" />
|
|||
public sealed class ComplexPolygon : IShape |
|||
{ |
|||
private const float ClipperScaleFactor = 100f; |
|||
private IShape[] shapes; |
|||
private IEnumerable<IPath> paths; |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="ComplexPolygon"/> class.
|
|||
/// </summary>
|
|||
/// <param name="outline">The outline.</param>
|
|||
/// <param name="holes">The holes.</param>
|
|||
public ComplexPolygon(IShape outline, params IShape[] holes) |
|||
: this(new[] { outline }, holes) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="ComplexPolygon"/> class.
|
|||
/// </summary>
|
|||
/// <param name="outlines">The outlines.</param>
|
|||
/// <param name="holes">The holes.</param>
|
|||
public ComplexPolygon(IShape[] outlines, IShape[] holes) |
|||
{ |
|||
Guard.NotNull(outlines, nameof(outlines)); |
|||
Guard.MustBeGreaterThanOrEqualTo(outlines.Length, 1, nameof(outlines)); |
|||
|
|||
this.MaxIntersections = this.FixAndSetShapes(outlines, holes); |
|||
|
|||
float minX = this.shapes.Min(x => x.Bounds.Left); |
|||
float maxX = this.shapes.Max(x => x.Bounds.Right); |
|||
float minY = this.shapes.Min(x => x.Bounds.Top); |
|||
float maxY = this.shapes.Max(x => x.Bounds.Bottom); |
|||
|
|||
this.Bounds = new RectangleF(minX, minY, maxX - minX, maxY - minY); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the bounding box of this shape.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// The bounds.
|
|||
/// </value>
|
|||
public RectangleF Bounds { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the maximum number intersections that a shape can have when testing a line.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// The maximum intersections.
|
|||
/// </value>
|
|||
public int MaxIntersections { get; } |
|||
|
|||
/// <summary>
|
|||
/// the distance of the point from the outline of the shape, if the value is negative it is inside the polygon bounds
|
|||
/// </summary>
|
|||
/// <param name="point">The point.</param>
|
|||
/// <returns>
|
|||
/// Returns the distance from thr shape to the point
|
|||
/// </returns>
|
|||
/// <remarks>
|
|||
/// Due to the clipping we did during construction we know that out shapes do not overlap at there edges
|
|||
/// therefore for apoint to be in more that one we must be in a hole of another, theoretically this could
|
|||
/// then flip again to be in a outlin inside a hole inside an outline :)
|
|||
/// </remarks>
|
|||
float IShape.Distance(Vector2 point) |
|||
{ |
|||
float dist = float.MaxValue; |
|||
bool inside = false; |
|||
foreach (IShape shape in this.shapes) |
|||
{ |
|||
float d = shape.Distance(point); |
|||
|
|||
if (d <= 0) |
|||
{ |
|||
// we are inside a poly
|
|||
d = -d; // flip the sign
|
|||
inside ^= true; // flip the inside flag
|
|||
} |
|||
|
|||
if (d < dist) |
|||
{ |
|||
dist = d; |
|||
} |
|||
} |
|||
|
|||
if (inside) |
|||
{ |
|||
return -dist; |
|||
} |
|||
|
|||
return dist; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Based on a line described by <paramref name="start"/> and <paramref name="end"/>
|
|||
/// populate a buffer for all points on all the polygons, that make up this complex shape,
|
|||
/// that the line intersects.
|
|||
/// </summary>
|
|||
/// <param name="start">The start point of the line.</param>
|
|||
/// <param name="end">The end point of the line.</param>
|
|||
/// <param name="buffer">The buffer that will be populated with intersections.</param>
|
|||
/// <param name="count">The count.</param>
|
|||
/// <param name="offset">The offset.</param>
|
|||
/// <returns>
|
|||
/// The number of intersections populated into the buffer.
|
|||
/// </returns>
|
|||
public int FindIntersections(Vector2 start, Vector2 end, Vector2[] buffer, int count, int offset) |
|||
{ |
|||
int totalAdded = 0; |
|||
for (int i = 0; i < this.shapes.Length; i++) |
|||
{ |
|||
int added = this.shapes[i].FindIntersections(start, end, buffer, count, offset); |
|||
count -= added; |
|||
offset += added; |
|||
totalAdded += added; |
|||
} |
|||
|
|||
return totalAdded; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Returns an enumerator that iterates through the collection.
|
|||
/// </summary>
|
|||
/// <returns>
|
|||
/// An enumerator that can be used to iterate through the collection.
|
|||
/// </returns>
|
|||
public IEnumerator<IPath> GetEnumerator() |
|||
{ |
|||
return this.paths.GetEnumerator(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Returns an enumerator that iterates through a collection.
|
|||
/// </summary>
|
|||
/// <returns>
|
|||
/// An <see cref="T:System.Collections.IEnumerator" /> object that can be used to iterate through the collection.
|
|||
/// </returns>
|
|||
IEnumerator IEnumerable.GetEnumerator() |
|||
{ |
|||
return this.GetEnumerator(); |
|||
} |
|||
|
|||
private void AddPoints(Clipper clipper, IShape shape, PolyType polyType) |
|||
{ |
|||
// if the path is already the shape use it directly and skip the path loop.
|
|||
if (shape is IPath) |
|||
{ |
|||
clipper.AddPath( |
|||
(IPath)shape, |
|||
polyType); |
|||
} |
|||
else |
|||
{ |
|||
foreach (IPath path in shape) |
|||
{ |
|||
clipper.AddPath( |
|||
path, |
|||
polyType); |
|||
} |
|||
} |
|||
} |
|||
|
|||
private void AddPoints(Clipper clipper, IEnumerable<IShape> shapes, PolyType polyType) |
|||
{ |
|||
foreach (IShape shape in shapes) |
|||
{ |
|||
this.AddPoints(clipper, shape, polyType); |
|||
} |
|||
} |
|||
|
|||
private void ExtractOutlines(PolyNode tree, List<IShape> shapes, List<IPath> paths) |
|||
{ |
|||
if (tree.Contour.Any()) |
|||
{ |
|||
// if the source path is set then we clipper retained the full path intact thus we can freely
|
|||
// use it and get any shape optimisations that are availible.
|
|||
if (tree.SourcePath != null) |
|||
{ |
|||
shapes.Add((IShape)tree.SourcePath); |
|||
paths.Add(tree.SourcePath); |
|||
} |
|||
else |
|||
{ |
|||
// convert the Clipper Contour from scaled ints back down to the origional size (this is going to be lossy but not significantly)
|
|||
Polygon polygon = new Polygon(new Paths.LinearLineSegment(tree.Contour.ToArray())); |
|||
|
|||
shapes.Add(polygon); |
|||
paths.Add(polygon); |
|||
} |
|||
} |
|||
|
|||
foreach (PolyNode c in tree.Children) |
|||
{ |
|||
this.ExtractOutlines(c, shapes, paths); |
|||
} |
|||
} |
|||
|
|||
private int FixAndSetShapes(IEnumerable<IShape> outlines, IEnumerable<IShape> holes) |
|||
{ |
|||
Clipper clipper = new Clipper(); |
|||
|
|||
// add the outlines and the holes to clipper, scaling up from the float source to the int based system clipper uses
|
|||
this.AddPoints(clipper, outlines, PolyType.Subject); |
|||
this.AddPoints(clipper, holes, PolyType.Clip); |
|||
|
|||
PolyTree tree = clipper.Execute(); |
|||
|
|||
List<IShape> shapes = new List<IShape>(); |
|||
List<IPath> paths = new List<IPath>(); |
|||
|
|||
// convert the 'tree' back to paths
|
|||
this.ExtractOutlines(tree, shapes, paths); |
|||
this.shapes = shapes.ToArray(); |
|||
this.paths = paths.ToArray(); |
|||
|
|||
int intersections = 0; |
|||
foreach (IShape s in this.shapes) |
|||
{ |
|||
intersections += s.MaxIntersections; |
|||
} |
|||
|
|||
return intersections; |
|||
} |
|||
} |
|||
} |
|||
@ -1,56 +0,0 @@ |
|||
// <copyright file="IShape.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Drawing.Shapes |
|||
{ |
|||
using System.Collections.Generic; |
|||
using System.Numerics; |
|||
using Paths; |
|||
|
|||
/// <summary>
|
|||
/// Represents a closed set of paths making up a single shape.
|
|||
/// </summary>
|
|||
public interface IShape : IEnumerable<IPath> |
|||
{ |
|||
/// <summary>
|
|||
/// Gets the bounding box of this shape.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// The bounds.
|
|||
/// </value>
|
|||
RectangleF Bounds { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the maximum number intersections that a shape can have when testing a line.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// The maximum intersections.
|
|||
/// </value>
|
|||
int MaxIntersections { get; } |
|||
|
|||
/// <summary>
|
|||
/// the distance of the point from the outline of the shape, if the value is negative it is inside the polygon bounds
|
|||
/// </summary>
|
|||
/// <param name="point">The point.</param>
|
|||
/// <returns>
|
|||
/// Returns the distance from the shape to the point
|
|||
/// </returns>
|
|||
float Distance(Vector2 point); |
|||
|
|||
/// <summary>
|
|||
/// Based on a line described by <paramref name="start"/> and <paramref name="end"/>
|
|||
/// populate a buffer for all points on the polygon that the line intersects.
|
|||
/// </summary>
|
|||
/// <param name="start">The start point of the line.</param>
|
|||
/// <param name="end">The end point of the line.</param>
|
|||
/// <param name="buffer">The buffer that will be populated with intersections.</param>
|
|||
/// <param name="count">The count.</param>
|
|||
/// <param name="offset">The offset.</param>
|
|||
/// <returns>
|
|||
/// The number of intersections populated into the buffer.
|
|||
/// </returns>
|
|||
int FindIntersections(Vector2 start, Vector2 end, Vector2[] buffer, int count, int offset); |
|||
} |
|||
} |
|||
@ -1,93 +0,0 @@ |
|||
// <copyright file="LinearPolygon.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Drawing.Shapes |
|||
{ |
|||
using System.Collections; |
|||
using System.Collections.Generic; |
|||
using System.Numerics; |
|||
using Paths; |
|||
|
|||
/// <summary>
|
|||
/// Represents a polygon made up exclusivly of a single Linear path.
|
|||
/// </summary>
|
|||
public sealed class LinearPolygon : IShape |
|||
{ |
|||
private Polygon innerPolygon; |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="LinearPolygon"/> class.
|
|||
/// </summary>
|
|||
/// <param name="points">The points.</param>
|
|||
public LinearPolygon(params Vector2[] points) |
|||
{ |
|||
this.innerPolygon = new Polygon(new LinearLineSegment(points)); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the bounding box of this shape.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// The bounds.
|
|||
/// </value>
|
|||
public RectangleF Bounds => this.innerPolygon.Bounds; |
|||
|
|||
/// <summary>
|
|||
/// Gets the maximum number intersections that a shape can have when testing a line.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// The maximum intersections.
|
|||
/// </value>
|
|||
public int MaxIntersections |
|||
{ |
|||
get |
|||
{ |
|||
return this.innerPolygon.MaxIntersections; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// the distance of the point from the outline of the shape, if the value is negative it is inside the polygon bounds
|
|||
/// </summary>
|
|||
/// <param name="point">The point.</param>
|
|||
/// <returns>
|
|||
/// Returns the distance from the shape to the point
|
|||
/// </returns>
|
|||
public float Distance(Vector2 point) => this.innerPolygon.Distance(point); |
|||
|
|||
/// <summary>
|
|||
/// Based on a line described by <paramref name="start"/> and <paramref name="end"/>
|
|||
/// populate a buffer for all points on the polygon that the line intersects.
|
|||
/// </summary>
|
|||
/// <param name="start">The start point of the line.</param>
|
|||
/// <param name="end">The end point of the line.</param>
|
|||
/// <param name="buffer">The buffer that will be populated with intersections.</param>
|
|||
/// <param name="count">The count.</param>
|
|||
/// <param name="offset">The offset.</param>
|
|||
/// <returns>
|
|||
/// The number of intersections populated into the buffer.
|
|||
/// </returns>
|
|||
public int FindIntersections(Vector2 start, Vector2 end, Vector2[] buffer, int count, int offset) |
|||
{ |
|||
return this.innerPolygon.FindIntersections(start, end, buffer, count, offset); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Returns an enumerator that iterates through the collection.
|
|||
/// </summary>
|
|||
/// <returns>
|
|||
/// An enumerator that can be used to iterate through the collection.
|
|||
/// </returns>
|
|||
public IEnumerator<IPath> GetEnumerator() => this.innerPolygon.GetEnumerator(); |
|||
|
|||
/// <summary>
|
|||
/// Returns an enumerator that iterates through a collection.
|
|||
/// </summary>
|
|||
/// <returns>
|
|||
/// An <see cref="T:System.Collections.IEnumerator" /> object that can be used to iterate through the collection.
|
|||
/// </returns>
|
|||
IEnumerator IEnumerable.GetEnumerator() => this.innerPolygon.GetEnumerator(); |
|||
} |
|||
} |
|||
@ -1,156 +0,0 @@ |
|||
// <copyright file="Polygon.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Drawing.Shapes |
|||
{ |
|||
using System.Collections; |
|||
using System.Collections.Generic; |
|||
using System.Numerics; |
|||
|
|||
using Paths; |
|||
|
|||
/// <summary>
|
|||
/// A shape made up of a single path made up of one of more <see cref="ILineSegment"/>s
|
|||
/// </summary>
|
|||
public sealed class Polygon : IShape, IPath |
|||
{ |
|||
private readonly InternalPath innerPath; |
|||
private readonly IEnumerable<IPath> pathCollection; |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="Polygon"/> class.
|
|||
/// </summary>
|
|||
/// <param name="segments">The segments.</param>
|
|||
public Polygon(params ILineSegment[] segments) |
|||
{ |
|||
this.innerPath = new InternalPath(segments, true); |
|||
this.pathCollection = new[] { this }; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="Polygon" /> class.
|
|||
/// </summary>
|
|||
/// <param name="segment">The segment.</param>
|
|||
public Polygon(ILineSegment segment) |
|||
{ |
|||
this.innerPath = new InternalPath(segment, true); |
|||
this.pathCollection = new[] { this }; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the bounding box of this shape.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// The bounds.
|
|||
/// </value>
|
|||
public RectangleF Bounds => this.innerPath.Bounds; |
|||
|
|||
/// <summary>
|
|||
/// Gets the length of the path
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// The length.
|
|||
/// </value>
|
|||
public float Length => this.innerPath.Length; |
|||
|
|||
/// <summary>
|
|||
/// Gets a value indicating whether this instance is closed.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// <c>true</c> if this instance is closed; otherwise, <c>false</c>.
|
|||
/// </value>
|
|||
public bool IsClosed => true; |
|||
|
|||
/// <summary>
|
|||
/// Gets the maximum number intersections that a shape can have when testing a line.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// The maximum intersections.
|
|||
/// </value>
|
|||
public int MaxIntersections => this.innerPath.Points.Length; |
|||
|
|||
/// <summary>
|
|||
/// the distance of the point from the outline of the shape, if the value is negative it is inside the polygon bounds
|
|||
/// </summary>
|
|||
/// <param name="point">The point.</param>
|
|||
/// <returns>
|
|||
/// The distance of the point away from the shape
|
|||
/// </returns>
|
|||
public float Distance(Vector2 point) |
|||
{ |
|||
bool isInside = this.innerPath.PointInPolygon(point); |
|||
|
|||
float distance = this.innerPath.DistanceFromPath(point).DistanceFromPath; |
|||
if (isInside) |
|||
{ |
|||
return -distance; |
|||
} |
|||
|
|||
return distance; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Returns an enumerator that iterates through the collection.
|
|||
/// </summary>
|
|||
/// <returns>
|
|||
/// An enumerator that can be used to iterate through the collection.
|
|||
/// </returns>
|
|||
public IEnumerator<IPath> GetEnumerator() |
|||
{ |
|||
return this.pathCollection.GetEnumerator(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Returns an enumerator that iterates through a collection.
|
|||
/// </summary>
|
|||
/// <returns>
|
|||
/// An <see cref="T:System.Collections.IEnumerator" /> object that can be used to iterate through the collection.
|
|||
/// </returns>
|
|||
IEnumerator IEnumerable.GetEnumerator() |
|||
{ |
|||
return this.pathCollection.GetEnumerator(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Calcualtes the distance along and away from the path for a specified point.
|
|||
/// </summary>
|
|||
/// <param name="point">The point along the path.</param>
|
|||
/// <returns>
|
|||
/// distance metadata about the point.
|
|||
/// </returns>
|
|||
PointInfo IPath.Distance(Vector2 point) |
|||
{ |
|||
return this.innerPath.DistanceFromPath(point); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Returns the current shape as a simple linear path.
|
|||
/// </summary>
|
|||
/// <returns>
|
|||
/// Returns the current <see cref="ILineSegment" /> as simple linear path.
|
|||
/// </returns>
|
|||
public Vector2[] AsSimpleLinearPath() |
|||
{ |
|||
return this.innerPath.Points; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Based on a line described by <paramref name="start" /> and <paramref name="end" />
|
|||
/// populate a buffer for all points on the polygon that the line intersects.
|
|||
/// </summary>
|
|||
/// <param name="start">The start point of the line.</param>
|
|||
/// <param name="end">The end point of the line.</param>
|
|||
/// <param name="buffer">The buffer that will be populated with intersections.</param>
|
|||
/// <param name="count">The count.</param>
|
|||
/// <param name="offset">The offset.</param>
|
|||
/// <returns>
|
|||
/// The number of intersections populated into the buffer.
|
|||
/// </returns>
|
|||
public int FindIntersections(Vector2 start, Vector2 end, Vector2[] buffer, int count, int offset) |
|||
{ |
|||
return this.innerPath.FindIntersections(start, end, buffer, count, offset); |
|||
} |
|||
} |
|||
} |
|||
File diff suppressed because it is too large
@ -1,31 +0,0 @@ |
|||
// <copyright file="ClipperException.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Drawing.Shapes.PolygonClipper |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Numerics; |
|||
using System.Runtime.CompilerServices; |
|||
|
|||
using Paths; |
|||
|
|||
/// <summary>
|
|||
/// Clipper Exception
|
|||
/// </summary>
|
|||
/// <seealso cref="System.Exception" />
|
|||
internal class ClipperException : Exception |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="ClipperException"/> class.
|
|||
/// </summary>
|
|||
/// <param name="description">The description.</param>
|
|||
public ClipperException(string description) |
|||
: base(description) |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -1,31 +0,0 @@ |
|||
// <copyright file="Direction.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Drawing.Shapes.PolygonClipper |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Numerics; |
|||
using System.Runtime.CompilerServices; |
|||
|
|||
using Paths; |
|||
|
|||
/// <summary>
|
|||
/// ???
|
|||
/// </summary>
|
|||
internal enum Direction |
|||
{ |
|||
/// <summary>
|
|||
/// The right to left
|
|||
/// </summary>
|
|||
RightToLeft, |
|||
|
|||
/// <summary>
|
|||
/// The left to right
|
|||
/// </summary>
|
|||
LeftToRight |
|||
} |
|||
} |
|||
@ -1,31 +0,0 @@ |
|||
// <copyright file="EdgeSide.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Drawing.Shapes.PolygonClipper |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Numerics; |
|||
using System.Runtime.CompilerServices; |
|||
|
|||
using Paths; |
|||
|
|||
/// <summary>
|
|||
/// ??
|
|||
/// </summary>
|
|||
internal enum EdgeSide |
|||
{ |
|||
/// <summary>
|
|||
/// The left
|
|||
/// </summary>
|
|||
Left, |
|||
|
|||
/// <summary>
|
|||
/// The right
|
|||
/// </summary>
|
|||
Right |
|||
} |
|||
} |
|||
@ -1,38 +0,0 @@ |
|||
// <copyright file="IntersectNode.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Drawing.Shapes.PolygonClipper |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Numerics; |
|||
using System.Runtime.CompilerServices; |
|||
|
|||
using Paths; |
|||
|
|||
/// <summary>
|
|||
/// ??
|
|||
/// </summary>
|
|||
internal class IntersectNode |
|||
{ |
|||
#pragma warning disable SA1401 // Field must be private
|
|||
/// <summary>
|
|||
/// The edge1
|
|||
/// </summary>
|
|||
internal TEdge Edge1; |
|||
|
|||
/// <summary>
|
|||
/// The edge2
|
|||
/// </summary>
|
|||
internal TEdge Edge2; |
|||
|
|||
/// <summary>
|
|||
/// The pt
|
|||
/// </summary>
|
|||
internal System.Numerics.Vector2 Pt; |
|||
#pragma warning restore SA1401 // Field must be private
|
|||
} |
|||
} |
|||
@ -1,48 +0,0 @@ |
|||
// <copyright file="IntersectNodeSort.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Drawing.Shapes.PolygonClipper |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Numerics; |
|||
using System.Runtime.CompilerServices; |
|||
|
|||
using Paths; |
|||
|
|||
/// <summary>
|
|||
/// Compares <see cref="IntersectNode"/>s
|
|||
/// </summary>
|
|||
internal class IntersectNodeSort : IComparer<IntersectNode> |
|||
{ |
|||
/// <summary>
|
|||
/// Compares the specified node1.
|
|||
/// </summary>
|
|||
/// <param name="node1">The node1.</param>
|
|||
/// <param name="node2">The node2.</param>
|
|||
/// <returns>
|
|||
/// 1 if node2 %gt; node1
|
|||
/// -1 if node2 $lt; node1
|
|||
/// 0 if same
|
|||
/// </returns>
|
|||
public int Compare(IntersectNode node1, IntersectNode node2) |
|||
{ |
|||
float i = node2.Pt.Y - node1.Pt.Y; |
|||
if (i > 0) |
|||
{ |
|||
return 1; |
|||
} |
|||
else if (i < 0) |
|||
{ |
|||
return -1; |
|||
} |
|||
else |
|||
{ |
|||
return 0; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,38 +0,0 @@ |
|||
// <copyright file="Join.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Drawing.Shapes.PolygonClipper |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Numerics; |
|||
using System.Runtime.CompilerServices; |
|||
|
|||
using Paths; |
|||
|
|||
/// <summary>
|
|||
/// ??
|
|||
/// </summary>
|
|||
internal class Join |
|||
{ |
|||
#pragma warning disable SA1401 // Field must be private
|
|||
/// <summary>
|
|||
/// The out PT1
|
|||
/// </summary>
|
|||
internal OutPt OutPt1; |
|||
|
|||
/// <summary>
|
|||
/// The out PT2
|
|||
/// </summary>
|
|||
internal OutPt OutPt2; |
|||
|
|||
/// <summary>
|
|||
/// The off pt
|
|||
/// </summary>
|
|||
internal System.Numerics.Vector2 OffPt; |
|||
#pragma warning restore SA1401 // Field must be private
|
|||
} |
|||
} |
|||
@ -1,44 +0,0 @@ |
|||
// <copyright file="LocalMinima.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Drawing.Shapes.PolygonClipper |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Numerics; |
|||
using System.Runtime.CompilerServices; |
|||
|
|||
using Paths; |
|||
|
|||
/// <summary>
|
|||
/// ??
|
|||
/// </summary>
|
|||
internal class LocalMinima |
|||
{ |
|||
#pragma warning disable SA1401 // Field must be private
|
|||
/// <summary>
|
|||
/// The y
|
|||
/// </summary>
|
|||
internal float Y; |
|||
|
|||
/// <summary>
|
|||
/// The left bound
|
|||
/// </summary>
|
|||
internal TEdge LeftBound; |
|||
|
|||
/// <summary>
|
|||
/// The right bound
|
|||
/// </summary>
|
|||
internal TEdge RightBound; |
|||
|
|||
/// <summary>
|
|||
/// The next
|
|||
/// </summary>
|
|||
internal LocalMinima Next; |
|||
|
|||
#pragma warning restore SA1401 // Field must be private
|
|||
} |
|||
} |
|||
@ -1,38 +0,0 @@ |
|||
// <copyright file="Maxima.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Drawing.Shapes.PolygonClipper |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Numerics; |
|||
using System.Runtime.CompilerServices; |
|||
|
|||
using Paths; |
|||
|
|||
/// <summary>
|
|||
/// ??
|
|||
/// </summary>
|
|||
internal class Maxima |
|||
{ |
|||
#pragma warning disable SA1401 // Field must be private
|
|||
/// <summary>
|
|||
/// The x
|
|||
/// </summary>
|
|||
internal float X; |
|||
|
|||
/// <summary>
|
|||
/// The next
|
|||
/// </summary>
|
|||
internal Maxima Next; |
|||
|
|||
/// <summary>
|
|||
/// The previous
|
|||
/// </summary>
|
|||
internal Maxima Prev; |
|||
#pragma warning restore SA1401 // Field must be private
|
|||
} |
|||
} |
|||
@ -1,43 +0,0 @@ |
|||
// <copyright file="OutPt.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Drawing.Shapes.PolygonClipper |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Numerics; |
|||
using System.Runtime.CompilerServices; |
|||
|
|||
using Paths; |
|||
|
|||
/// <summary>
|
|||
/// ??
|
|||
/// </summary>
|
|||
internal class OutPt |
|||
{ |
|||
#pragma warning disable SA1401 // Field must be private
|
|||
/// <summary>
|
|||
/// The index
|
|||
/// </summary>
|
|||
internal int Idx; |
|||
|
|||
/// <summary>
|
|||
/// The pt
|
|||
/// </summary>
|
|||
internal System.Numerics.Vector2 Pt; |
|||
|
|||
/// <summary>
|
|||
/// The next
|
|||
/// </summary>
|
|||
internal OutPt Next; |
|||
|
|||
/// <summary>
|
|||
/// The previous
|
|||
/// </summary>
|
|||
internal OutPt Prev; |
|||
#pragma warning restore SA1401 // Field must be private
|
|||
} |
|||
} |
|||
@ -1,64 +0,0 @@ |
|||
// <copyright file="OutRec.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Drawing.Shapes.PolygonClipper |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Numerics; |
|||
using System.Runtime.CompilerServices; |
|||
|
|||
using Paths; |
|||
|
|||
/// <summary>
|
|||
/// OutRec: contains a path in the clipping solution. Edges in the AEL will
|
|||
/// carry a pointer to an OutRec when they are part of the clipping solution.
|
|||
/// </summary>
|
|||
internal class OutRec |
|||
{ |
|||
#pragma warning disable SA1401 // Field must be private
|
|||
/// <summary>
|
|||
/// The source path
|
|||
/// </summary>
|
|||
internal IPath SourcePath; |
|||
|
|||
/// <summary>
|
|||
/// The index
|
|||
/// </summary>
|
|||
internal int Idx; |
|||
|
|||
/// <summary>
|
|||
/// The is hole
|
|||
/// </summary>
|
|||
internal bool IsHole; |
|||
|
|||
/// <summary>
|
|||
/// The is open
|
|||
/// </summary>
|
|||
internal bool IsOpen; |
|||
|
|||
/// <summary>
|
|||
/// The first left
|
|||
/// </summary>
|
|||
internal OutRec FirstLeft; |
|||
|
|||
/// <summary>
|
|||
/// The PTS
|
|||
/// </summary>
|
|||
internal OutPt Pts; |
|||
|
|||
/// <summary>
|
|||
/// The bottom pt
|
|||
/// </summary>
|
|||
internal OutPt BottomPt; |
|||
|
|||
/// <summary>
|
|||
/// The poly node
|
|||
/// </summary>
|
|||
internal PolyNode PolyNode; |
|||
#pragma warning restore SA1401 // Field must be private
|
|||
} |
|||
} |
|||
@ -1,179 +0,0 @@ |
|||
// <copyright file="PolyNode.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Drawing.Shapes.PolygonClipper |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Numerics; |
|||
using System.Runtime.CompilerServices; |
|||
|
|||
using Paths; |
|||
|
|||
/// <summary>
|
|||
/// Poly Node
|
|||
/// </summary>
|
|||
internal class PolyNode |
|||
{ |
|||
#pragma warning disable SA1401 // Field must be private
|
|||
/// <summary>
|
|||
/// The polygon
|
|||
/// </summary>
|
|||
internal List<Vector2> Polygon = new List<Vector2>(); |
|||
|
|||
/// <summary>
|
|||
/// The index
|
|||
/// </summary>
|
|||
internal int Index; |
|||
|
|||
/// <summary>
|
|||
/// The childs
|
|||
/// </summary>
|
|||
protected List<PolyNode> children = new List<PolyNode>(); |
|||
|
|||
private PolyNode parent; |
|||
#pragma warning restore SA1401 // Field must be private
|
|||
|
|||
/// <summary>
|
|||
/// Gets the child count.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// The child count.
|
|||
/// </value>
|
|||
public int ChildCount |
|||
{ |
|||
get { return this.children.Count; } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the contour.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// The contour.
|
|||
/// </value>
|
|||
public List<Vector2> Contour |
|||
{ |
|||
get { return this.Polygon; } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the childs.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// The childs.
|
|||
/// </value>
|
|||
public List<PolyNode> Children |
|||
{ |
|||
get { return this.children; } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the parent.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// The parent.
|
|||
/// </value>
|
|||
public PolyNode Parent |
|||
{ |
|||
get { return this.parent; } |
|||
internal set { this.parent = value; } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets a value indicating whether this instance is hole.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// <c>true</c> if this instance is hole; otherwise, <c>false</c>.
|
|||
/// </value>
|
|||
public bool IsHole |
|||
{ |
|||
get { return this.IsHoleNode(); } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets a value indicating whether this instance is open.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// <c>true</c> if this instance is open; otherwise, <c>false</c>.
|
|||
/// </value>
|
|||
public bool IsOpen { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the source path.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// The source path.
|
|||
/// </value>
|
|||
public IPath SourcePath { get; internal set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the next.
|
|||
/// </summary>
|
|||
/// <returns>The next node</returns>
|
|||
public PolyNode GetNext() |
|||
{ |
|||
if (this.children.Count > 0) |
|||
{ |
|||
return this.children[0]; |
|||
} |
|||
else |
|||
{ |
|||
return this.GetNextSiblingUp(); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Adds the child.
|
|||
/// </summary>
|
|||
/// <param name="child">The child.</param>
|
|||
internal void AddChild(PolyNode child) |
|||
{ |
|||
int cnt = this.children.Count; |
|||
this.children.Add(child); |
|||
child.parent = this; |
|||
child.Index = cnt; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the next sibling up.
|
|||
/// </summary>
|
|||
/// <returns>The next sibling up</returns>
|
|||
internal PolyNode GetNextSiblingUp() |
|||
{ |
|||
if (this.parent == null) |
|||
{ |
|||
return null; |
|||
} |
|||
else if (this.Index == this.parent.children.Count - 1) |
|||
{ |
|||
return this.parent.GetNextSiblingUp(); |
|||
} |
|||
else |
|||
{ |
|||
return this.parent.Children[this.Index + 1]; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Determines whether [is hole node].
|
|||
/// </summary>
|
|||
/// <returns>
|
|||
/// <c>true</c> if [is hole node]; otherwise, <c>false</c>.
|
|||
/// </returns>
|
|||
private bool IsHoleNode() |
|||
{ |
|||
bool result = true; |
|||
PolyNode node = this.parent; |
|||
while (node != null) |
|||
{ |
|||
result = !result; |
|||
node = node.parent; |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
} |
|||
} |
|||
@ -1,81 +0,0 @@ |
|||
// <copyright file="PolyTree.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Drawing.Shapes.PolygonClipper |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Numerics; |
|||
using System.Runtime.CompilerServices; |
|||
|
|||
using Paths; |
|||
|
|||
/// <summary>
|
|||
/// Poly Tree
|
|||
/// </summary>
|
|||
/// <seealso cref="ImageSharp.Drawing.Shapes.PolygonClipper.PolyNode" />
|
|||
internal class PolyTree : PolyNode |
|||
{ |
|||
#pragma warning disable SA1401 // Field must be private
|
|||
/// <summary>
|
|||
/// All polys
|
|||
/// </summary>
|
|||
internal List<PolyNode> AllPolys = new List<PolyNode>(); |
|||
#pragma warning restore SA1401 // Field must be private
|
|||
|
|||
/// <summary>
|
|||
/// Gets the total.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// The total.
|
|||
/// </value>
|
|||
public int Total |
|||
{ |
|||
get |
|||
{ |
|||
int result = this.AllPolys.Count; |
|||
|
|||
// with negative offsets, ignore the hidden outer polygon ...
|
|||
if (result > 0 && this.Children[0] != this.AllPolys[0]) |
|||
{ |
|||
result--; |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Clears this instance.
|
|||
/// </summary>
|
|||
public void Clear() |
|||
{ |
|||
for (int i = 0; i < this.AllPolys.Count; i++) |
|||
{ |
|||
this.AllPolys[i] = null; |
|||
} |
|||
|
|||
this.AllPolys.Clear(); |
|||
this.Children.Clear(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the first.
|
|||
/// </summary>
|
|||
/// <returns>the first node</returns>
|
|||
public PolyNode GetFirst() |
|||
{ |
|||
if (this.Children.Count > 0) |
|||
{ |
|||
return this.Children[0]; |
|||
} |
|||
else |
|||
{ |
|||
return null; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,31 +0,0 @@ |
|||
// <copyright file="PolyType.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Drawing.Shapes.PolygonClipper |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Numerics; |
|||
using System.Runtime.CompilerServices; |
|||
|
|||
using Paths; |
|||
|
|||
/// <summary>
|
|||
/// Poly Type
|
|||
/// </summary>
|
|||
internal enum PolyType |
|||
{ |
|||
/// <summary>
|
|||
/// The subject
|
|||
/// </summary>
|
|||
Subject, |
|||
|
|||
/// <summary>
|
|||
/// The clip
|
|||
/// </summary>
|
|||
Clip |
|||
} |
|||
} |
|||
@ -1,40 +0,0 @@ |
|||
# Clipper |
|||
|
|||
License details for code in this folder, this is code original written by **Angus Johnson** |
|||
|
|||
The license header onthe original file which has now be split across multiple files in this folder. |
|||
|
|||
``` |
|||
/******************************************************************************* |
|||
* * |
|||
* Author : Angus Johnson * |
|||
* Version : 6.4.0 * |
|||
* Date : 2 July 2015 * |
|||
* Website : http://www.angusj.com * |
|||
* Copyright : Angus Johnson 2010-2015 * |
|||
* * |
|||
* License: * |
|||
* Use, modification & distribution is subject to Boost Software License Ver 1. * |
|||
* http://www.boost.org/LICENSE_1_0.txt * |
|||
* * |
|||
* Attributions: * |
|||
* The code in this library is an extension of Bala Vatti's clipping algorithm: * |
|||
* "A generic solution to polygon clipping" * |
|||
* Communications of the ACM, Vol 35, Issue 7 (July 1992) pp 56-63. * |
|||
* http://portal.acm.org/citation.cfm?id=129906 * |
|||
* * |
|||
* Computer graphics and geometric modeling: implementation and algorithms * |
|||
* By Max K. Agoston * |
|||
* Springer; 1 edition (January 4, 2005) * |
|||
* http://books.google.com/books?q=vatti+clipping+agoston * |
|||
* * |
|||
* See also: * |
|||
* "Polygon Offsetting by Computing Winding Numbers" * |
|||
* Paper no. DETC2005-85513 pp. 565-575 * |
|||
* ASME 2005 International Design Engineering Technical Conferences * |
|||
* and Computers and Information in Engineering Conference (IDETC/CIE2005) * |
|||
* September 24-28, 2005 , Long Beach, California, USA * |
|||
* http://www.me.berkeley.edu/~mcmains/pubs/DAC05OffsetPolygon.pdf * |
|||
* * |
|||
*******************************************************************************/ |
|||
``` |
|||
@ -1,33 +0,0 @@ |
|||
// <copyright file="Scanbeam.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Drawing.Shapes.PolygonClipper |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Numerics; |
|||
using System.Runtime.CompilerServices; |
|||
|
|||
using Paths; |
|||
|
|||
/// <summary>
|
|||
/// Scanbeam
|
|||
/// </summary>
|
|||
internal class Scanbeam // would this work as a struct?
|
|||
{ |
|||
#pragma warning disable SA1401 // Field must be private
|
|||
/// <summary>
|
|||
/// The y
|
|||
/// </summary>
|
|||
internal float Y; |
|||
|
|||
/// <summary>
|
|||
/// The next
|
|||
/// </summary>
|
|||
internal Scanbeam Next; |
|||
#pragma warning restore SA1401 // Field must be private
|
|||
} |
|||
} |
|||
@ -1,118 +0,0 @@ |
|||
// <copyright file="TEdge.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Drawing.Shapes.PolygonClipper |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Numerics; |
|||
using System.Runtime.CompilerServices; |
|||
|
|||
using Paths; |
|||
|
|||
/// <summary>
|
|||
/// TEdge
|
|||
/// </summary>
|
|||
internal class TEdge |
|||
{ |
|||
#pragma warning disable SA1401 // Field must be private
|
|||
/// <summary>
|
|||
/// The source path, see if we can link this back later
|
|||
/// </summary>
|
|||
internal IPath SourcePath; |
|||
|
|||
/// <summary>
|
|||
/// The bot
|
|||
/// </summary>
|
|||
internal System.Numerics.Vector2 Bot; |
|||
|
|||
/// <summary>
|
|||
/// The current (updated for every new scanbeam)
|
|||
/// </summary>
|
|||
internal System.Numerics.Vector2 Curr; |
|||
|
|||
/// <summary>
|
|||
/// The top
|
|||
/// </summary>
|
|||
internal System.Numerics.Vector2 Top; |
|||
|
|||
/// <summary>
|
|||
/// The delta
|
|||
/// </summary>
|
|||
internal System.Numerics.Vector2 Delta; |
|||
|
|||
/// <summary>
|
|||
/// The dx
|
|||
/// </summary>
|
|||
internal double Dx; |
|||
|
|||
/// <summary>
|
|||
/// The poly type
|
|||
/// </summary>
|
|||
internal PolyType PolyTyp; |
|||
|
|||
/// <summary>
|
|||
/// Side only refers to current side of solution poly
|
|||
/// </summary>
|
|||
internal EdgeSide Side; |
|||
|
|||
/// <summary>
|
|||
/// 1 or -1 depending on winding direction
|
|||
/// </summary>
|
|||
internal int WindDelta; |
|||
|
|||
/// <summary>
|
|||
/// The winding count
|
|||
/// </summary>
|
|||
internal int WindCnt; |
|||
|
|||
/// <summary>
|
|||
/// The winding count of the opposite polytype
|
|||
/// </summary>
|
|||
internal int WindCnt2; |
|||
|
|||
/// <summary>
|
|||
/// The out index
|
|||
/// </summary>
|
|||
internal int OutIdx; |
|||
|
|||
/// <summary>
|
|||
/// The next
|
|||
/// </summary>
|
|||
internal TEdge Next; |
|||
|
|||
/// <summary>
|
|||
/// The previous
|
|||
/// </summary>
|
|||
internal TEdge Prev; |
|||
|
|||
/// <summary>
|
|||
/// The next in LML
|
|||
/// </summary>
|
|||
internal TEdge NextInLML; |
|||
|
|||
/// <summary>
|
|||
/// The next in ael
|
|||
/// </summary>
|
|||
internal TEdge NextInAEL; |
|||
|
|||
/// <summary>
|
|||
/// The previous in ael
|
|||
/// </summary>
|
|||
internal TEdge PrevInAEL; |
|||
|
|||
/// <summary>
|
|||
/// The next in sel
|
|||
/// </summary>
|
|||
internal TEdge NextInSEL; |
|||
|
|||
/// <summary>
|
|||
/// The previous in sel
|
|||
/// </summary>
|
|||
internal TEdge PrevInSEL; |
|||
#pragma warning restore SA1401 // Field must be
|
|||
} |
|||
} |
|||
@ -1,281 +0,0 @@ |
|||
// <copyright file="RectangularPolygon.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Drawing.Shapes |
|||
{ |
|||
using System; |
|||
using System.Collections; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Numerics; |
|||
using System.Threading.Tasks; |
|||
using Paths; |
|||
|
|||
/// <summary>
|
|||
/// A way of optermising drawing rectangles.
|
|||
/// </summary>
|
|||
/// <seealso cref="ImageSharp.Drawing.Shapes.IShape" />
|
|||
public class RectangularPolygon : IShape, IPath |
|||
{ |
|||
private readonly RectangleF rectangle; |
|||
private readonly Vector2 topLeft; |
|||
private readonly Vector2 bottomRight; |
|||
private readonly Vector2[] points; |
|||
private readonly IEnumerable<IPath> pathCollection; |
|||
private readonly float halfLength; |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="RectangularPolygon"/> class.
|
|||
/// </summary>
|
|||
/// <param name="rect">The rect.</param>
|
|||
public RectangularPolygon(ImageSharp.Rectangle rect) |
|||
: this((RectangleF)rect) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="RectangularPolygon"/> class.
|
|||
/// </summary>
|
|||
/// <param name="rect">The rect.</param>
|
|||
public RectangularPolygon(ImageSharp.RectangleF rect) |
|||
{ |
|||
this.rectangle = rect; |
|||
this.points = new Vector2[4] |
|||
{ |
|||
this.topLeft = new Vector2(rect.Left, rect.Top), |
|||
new Vector2(rect.Right, rect.Top), |
|||
this.bottomRight = new Vector2(rect.Right, rect.Bottom), |
|||
new Vector2(rect.Left, rect.Bottom) |
|||
}; |
|||
|
|||
this.halfLength = this.rectangle.Width + this.rectangle.Height; |
|||
this.Length = this.halfLength * 2; |
|||
this.pathCollection = new[] { this }; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the bounding box of this shape.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// The bounds.
|
|||
/// </value>
|
|||
public RectangleF Bounds => this.rectangle; |
|||
|
|||
/// <summary>
|
|||
/// Gets a value indicating whether this instance is closed.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// <c>true</c> if this instance is closed; otherwise, <c>false</c>.
|
|||
/// </value>
|
|||
public bool IsClosed => true; |
|||
|
|||
/// <summary>
|
|||
/// Gets the length of the path
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// The length.
|
|||
/// </value>
|
|||
public float Length { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the maximum number intersections that a shape can have when testing a line.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// The maximum intersections.
|
|||
/// </value>
|
|||
public int MaxIntersections => 4; |
|||
|
|||
/// <summary>
|
|||
/// Calculates the distance along and away from the path for a specified point.
|
|||
/// </summary>
|
|||
/// <param name="point">The point along the path.</param>
|
|||
/// <returns>
|
|||
/// Returns details about the point and its distance away from the path.
|
|||
/// </returns>
|
|||
PointInfo IPath.Distance(Vector2 point) |
|||
{ |
|||
bool inside; // dont care about inside/outside for paths just distance
|
|||
return this.Distance(point, false, out inside); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// the distance of the point from the outline of the shape, if the value is negative it is inside the polygon bounds
|
|||
/// </summary>
|
|||
/// <param name="point">The point.</param>
|
|||
/// <returns>
|
|||
/// Returns the distance from the shape to the point
|
|||
/// </returns>
|
|||
public float Distance(Vector2 point) |
|||
{ |
|||
bool insidePoly; |
|||
PointInfo result = this.Distance(point, true, out insidePoly); |
|||
|
|||
// invert the distance from path when inside
|
|||
return insidePoly ? -result.DistanceFromPath : result.DistanceFromPath; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Returns an enumerator that iterates through the collection.
|
|||
/// </summary>
|
|||
/// <returns>
|
|||
/// An enumerator that can be used to iterate through the collection.
|
|||
/// </returns>
|
|||
public IEnumerator<IPath> GetEnumerator() |
|||
{ |
|||
return this.pathCollection.GetEnumerator(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Returns an enumerator that iterates through a collection.
|
|||
/// </summary>
|
|||
/// <returns>
|
|||
/// An <see cref="T:System.Collections.IEnumerator" /> object that can be used to iterate through the collection.
|
|||
/// </returns>
|
|||
IEnumerator IEnumerable.GetEnumerator() |
|||
{ |
|||
return this.pathCollection.GetEnumerator(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Converts the <see cref="ILineSegment" /> into a simple linear path..
|
|||
/// </summary>
|
|||
/// <returns>
|
|||
/// Returns the current <see cref="ILineSegment" /> as simple linear path.
|
|||
/// </returns>
|
|||
public Vector2[] AsSimpleLinearPath() |
|||
{ |
|||
return this.points; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Based on a line described by <paramref name="start"/> and <paramref name="end"/>
|
|||
/// populate a buffer for all points on the edges of the <see cref="RectangularPolygon"/>
|
|||
/// that the line intersects.
|
|||
/// </summary>
|
|||
/// <param name="start">The start point of the line.</param>
|
|||
/// <param name="end">The end point of the line.</param>
|
|||
/// <param name="buffer">The buffer that will be populated with intersections.</param>
|
|||
/// <param name="count">The count.</param>
|
|||
/// <param name="offset">The offset.</param>
|
|||
/// <returns>
|
|||
/// The number of intersections populated into the buffer.
|
|||
/// </returns>
|
|||
public int FindIntersections(Vector2 start, Vector2 end, Vector2[] buffer, int count, int offset) |
|||
{ |
|||
int discovered = 0; |
|||
Vector2 startPoint = Vector2.Clamp(start, this.topLeft, this.bottomRight); |
|||
Vector2 endPoint = Vector2.Clamp(end, this.topLeft, this.bottomRight); |
|||
|
|||
if (startPoint == Vector2.Clamp(startPoint, start, end)) |
|||
{ |
|||
// if start closest is within line then its a valid point
|
|||
discovered++; |
|||
buffer[offset++] = startPoint; |
|||
} |
|||
|
|||
if (endPoint == Vector2.Clamp(endPoint, start, end)) |
|||
{ |
|||
// if start closest is within line then its a valid point
|
|||
discovered++; |
|||
buffer[offset++] = endPoint; |
|||
} |
|||
|
|||
return discovered; |
|||
} |
|||
|
|||
private PointInfo Distance(Vector2 point, bool getDistanceAwayOnly, out bool isInside) |
|||
{ |
|||
// point in rectangle
|
|||
// if after its clamped by the extreams its still the same then it must be inside :)
|
|||
Vector2 clamped = Vector2.Clamp(point, this.topLeft, this.bottomRight); |
|||
isInside = clamped == point; |
|||
|
|||
float distanceFromEdge = float.MaxValue; |
|||
float distanceAlongEdge = 0f; |
|||
|
|||
if (isInside) |
|||
{ |
|||
// get the absolute distances from the extreams
|
|||
Vector2 topLeftDist = Vector2.Abs(point - this.topLeft); |
|||
Vector2 bottomRightDist = Vector2.Abs(point - this.bottomRight); |
|||
|
|||
// get the min components
|
|||
Vector2 minDists = Vector2.Min(topLeftDist, bottomRightDist); |
|||
|
|||
// and then the single smallest (dont have to worry about direction)
|
|||
distanceFromEdge = Math.Min(minDists.X, minDists.Y); |
|||
|
|||
if (!getDistanceAwayOnly) |
|||
{ |
|||
// we need to make clamped the closest point
|
|||
if (this.topLeft.X + distanceFromEdge == point.X) |
|||
{ |
|||
// closer to lhf
|
|||
clamped.X = this.topLeft.X; // y is already the same
|
|||
|
|||
// distance along edge is length minus the amout down we are from the top of the rect
|
|||
distanceAlongEdge = this.Length - (clamped.Y - this.topLeft.Y); |
|||
} |
|||
else if (this.topLeft.Y + distanceFromEdge == point.Y) |
|||
{ |
|||
// closer to top
|
|||
clamped.Y = this.topLeft.Y; // x is already the same
|
|||
|
|||
distanceAlongEdge = clamped.X - this.topLeft.X; |
|||
} |
|||
else if (this.bottomRight.Y - distanceFromEdge == point.Y) |
|||
{ |
|||
// closer to bottom
|
|||
clamped.Y = this.bottomRight.Y; // x is already the same
|
|||
|
|||
distanceAlongEdge = (this.bottomRight.X - clamped.X) + this.halfLength; |
|||
} |
|||
else if (this.bottomRight.X - distanceFromEdge == point.X) |
|||
{ |
|||
// closer to rhs
|
|||
clamped.X = this.bottomRight.X; // x is already the same
|
|||
|
|||
distanceAlongEdge = (this.bottomRight.Y - clamped.Y) + this.rectangle.Width; |
|||
} |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
// clamped is the point on the path thats closest no matter what
|
|||
distanceFromEdge = (clamped - point).Length(); |
|||
|
|||
if (!getDistanceAwayOnly) |
|||
{ |
|||
// we need to figure out whats the cloests edge now and thus what distance/poitn is closest
|
|||
if (this.topLeft.X == clamped.X) |
|||
{ |
|||
// distance along edge is length minus the amout down we are from the top of the rect
|
|||
distanceAlongEdge = this.Length - (clamped.Y - this.topLeft.Y); |
|||
} |
|||
else if (this.topLeft.Y == clamped.Y) |
|||
{ |
|||
distanceAlongEdge = clamped.X - this.topLeft.X; |
|||
} |
|||
else if (this.bottomRight.Y == clamped.Y) |
|||
{ |
|||
distanceAlongEdge = (this.bottomRight.X - clamped.X) + this.halfLength; |
|||
} |
|||
else if (this.bottomRight.X == clamped.X) |
|||
{ |
|||
distanceAlongEdge = (this.bottomRight.Y - clamped.Y) + this.rectangle.Width; |
|||
} |
|||
} |
|||
} |
|||
|
|||
return new PointInfo |
|||
{ |
|||
SearchPoint = point, |
|||
DistanceFromPath = distanceFromEdge, |
|||
ClosestPointOnPath = clamped, |
|||
DistanceAlongPath = distanceAlongEdge |
|||
}; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,45 @@ |
|||
// <copyright file="BmpEncoderOptions.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Formats |
|||
{ |
|||
/// <summary>
|
|||
/// Encapsulates the options for the <see cref="BmpEncoder"/>.
|
|||
/// </summary>
|
|||
public sealed class BmpEncoderOptions : EncoderOptions, IBmpEncoderOptions |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="BmpEncoderOptions"/> class.
|
|||
/// </summary>
|
|||
public BmpEncoderOptions() |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="BmpEncoderOptions"/> class.
|
|||
/// </summary>
|
|||
/// <param name="options">The options for the encoder.</param>
|
|||
private BmpEncoderOptions(IEncoderOptions options) |
|||
: base(options) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the number of bits per pixel.
|
|||
/// </summary>
|
|||
public BmpBitsPerPixel BitsPerPixel { get; set; } = BmpBitsPerPixel.Pixel24; |
|||
|
|||
/// <summary>
|
|||
/// Converts the options to a <see cref="IBmpEncoderOptions"/> instance with a cast
|
|||
/// or by creating a new instance with the specfied options.
|
|||
/// </summary>
|
|||
/// <param name="options">The options for the encoder.</param>
|
|||
/// <returns>The options for the <see cref="BmpEncoder"/>.</returns>
|
|||
internal static IBmpEncoderOptions Create(IEncoderOptions options) |
|||
{ |
|||
return options as IBmpEncoderOptions ?? new BmpEncoderOptions(options); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
// <copyright file="IBmpEncoderOptions.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Formats |
|||
{ |
|||
/// <summary>
|
|||
/// Encapsulates the options for the <see cref="BmpEncoder"/>.
|
|||
/// </summary>
|
|||
public interface IBmpEncoderOptions : IEncoderOptions |
|||
{ |
|||
/// <summary>
|
|||
/// Gets the number of bits per pixel.
|
|||
/// </summary>
|
|||
BmpBitsPerPixel BitsPerPixel { get; } |
|||
} |
|||
} |
|||
@ -0,0 +1,47 @@ |
|||
// <copyright file="GifDecoderOptions.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Formats |
|||
{ |
|||
using System.Text; |
|||
|
|||
/// <summary>
|
|||
/// Encapsulates the options for the <see cref="GifDecoder"/>.
|
|||
/// </summary>
|
|||
public sealed class GifDecoderOptions : DecoderOptions, IGifDecoderOptions |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="GifDecoderOptions"/> class.
|
|||
/// </summary>
|
|||
public GifDecoderOptions() |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="GifDecoderOptions"/> class.
|
|||
/// </summary>
|
|||
/// <param name="options">The options for the decoder.</param>
|
|||
private GifDecoderOptions(IDecoderOptions options) |
|||
: base(options) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the encoding that should be used when reading comments.
|
|||
/// </summary>
|
|||
public Encoding TextEncoding { get; set; } = GifConstants.DefaultEncoding; |
|||
|
|||
/// <summary>
|
|||
/// Converts the options to a <see cref="IGifDecoderOptions"/> instance with a cast
|
|||
/// or by creating a new instance with the specfied options.
|
|||
/// </summary>
|
|||
/// <param name="options">The options for the decoder.</param>
|
|||
/// <returns>The options for the <see cref="GifDecoder"/>.</returns>
|
|||
internal static IGifDecoderOptions Create(IDecoderOptions options) |
|||
{ |
|||
return options as IGifDecoderOptions ?? new GifDecoderOptions(options); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,65 @@ |
|||
// <copyright file="GifEncoderOptions.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Formats |
|||
{ |
|||
using System.Text; |
|||
|
|||
using Quantizers; |
|||
|
|||
/// <summary>
|
|||
/// Encapsulates the options for the <see cref="GifEncoder"/>.
|
|||
/// </summary>
|
|||
public sealed class GifEncoderOptions : EncoderOptions, IGifEncoderOptions |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="GifEncoderOptions"/> class.
|
|||
/// </summary>
|
|||
public GifEncoderOptions() |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="GifEncoderOptions"/> class.
|
|||
/// </summary>
|
|||
/// <param name="options">The options for the encoder.</param>
|
|||
private GifEncoderOptions(IEncoderOptions options) |
|||
: base(options) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the encoding that should be used when writing comments.
|
|||
/// </summary>
|
|||
public Encoding TextEncoding { get; set; } = GifConstants.DefaultEncoding; |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the quality of output for images.
|
|||
/// </summary>
|
|||
/// <remarks>For gifs the value ranges from 1 to 256.</remarks>
|
|||
public int Quality { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the transparency threshold.
|
|||
/// </summary>
|
|||
public byte Threshold { get; set; } = 128; |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the quantizer for reducing the color count.
|
|||
/// </summary>
|
|||
public IQuantizer Quantizer { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Converts the options to a <see cref="IGifEncoderOptions"/> instance with a
|
|||
/// cast or by creating a new instance with the specfied options.
|
|||
/// </summary>
|
|||
/// <param name="options">The options for the encoder.</param>
|
|||
/// <returns>The options for the <see cref="GifEncoder"/>.</returns>
|
|||
internal static IGifEncoderOptions Create(IEncoderOptions options) |
|||
{ |
|||
return options as IGifEncoderOptions ?? new GifEncoderOptions(options); |
|||
} |
|||
} |
|||
} |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue