Normalize docs and visibility modifiers

This commit is contained in:
James Jackson-South 2021-04-24 23:24:33 +01:00
Родитель 47e5e12f0e
Коммит 54bd57c8d1
16 изменённых файлов: 283 добавлений и 422 удалений

Просмотреть файл

@ -1,5 +1,5 @@
# Version: 1.6.2 (Using https://semver.org/)
# Updated: 2020-11-02
# Version: 2.1.0 (Using https://semver.org/)
# Updated: 2021-03-03
# See https://github.com/RehanSaeed/EditorConfig/releases for release notes.
# See https://github.com/RehanSaeed/EditorConfig for updates to this file.
# See http://EditorConfig.org for more information about .editorconfig files.
@ -60,87 +60,84 @@ indent_size = 2
[*.{cmd,bat}]
end_of_line = crlf
# Bash Files
[*.sh]
end_of_line = lf
# Makefiles
[Makefile]
indent_style = tab
##########################################
# File Header (Uncomment to support file headers)
# https://docs.microsoft.com/visualstudio/ide/reference/add-file-header
# Default .NET Code Style Severities
# https://docs.microsoft.com/dotnet/fundamentals/code-analysis/configuration-options#scope
##########################################
# [*.{cs,csx,cake,vb,vbx,tt,ttinclude}]
file_header_template = Copyright (c) Six Labors.\nLicensed under the Apache License, Version 2.0.
# SA1636: File header copyright text should match
# Justification: .editorconfig supports file headers. If this is changed to a value other than "none", a stylecop.json file will need to added to the project.
# dotnet_diagnostic.SA1636.severity = none
[*.{cs,csx,cake,vb,vbx}]
# Default Severity for all .NET Code Style rules below
dotnet_analyzer_diagnostic.severity = warning
##########################################
# .NET Language Conventions
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions
# Language Rules
# https://docs.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/language-rules
##########################################
# .NET Code Style Settings
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#net-code-style-settings
# .NET Style Rules
# https://docs.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/language-rules#net-style-rules
[*.{cs,csx,cake,vb,vbx}]
# "this." and "Me." qualifiers
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#this-and-me
dotnet_style_qualification_for_field = true:warning
dotnet_style_qualification_for_property = true:warning
dotnet_style_qualification_for_method = true:warning
dotnet_style_qualification_for_event = true:warning
# Language keywords instead of framework type names for type references
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#language-keywords
dotnet_style_predefined_type_for_locals_parameters_members = true:warning
dotnet_style_predefined_type_for_member_access = true:warning
# Modifier preferences
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#normalize-modifiers
dotnet_style_require_accessibility_modifiers = always:warning
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:warning
visual_basic_preferred_modifier_order = Partial,Default,Private,Protected,Public,Friend,NotOverridable,Overridable,MustOverride,Overloads,Overrides,MustInherit,NotInheritable,Static,Shared,Shadows,ReadOnly,WriteOnly,Dim,Const,WithEvents,Widening,Narrowing,Custom,Async:warning
dotnet_style_readonly_field = true:warning
# Parentheses preferences
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#parentheses-preferences
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:warning
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:warning
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:warning
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:suggestion
dotnet_style_parentheses_in_other_operators = always_for_clarity:suggestion
# Expression-level preferences
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#expression-level-preferences
dotnet_style_object_initializer = true:warning
dotnet_style_collection_initializer = true:warning
dotnet_style_explicit_tuple_names = true:warning
dotnet_style_prefer_inferred_tuple_names = true:warning
dotnet_style_prefer_inferred_anonymous_type_member_names = true:warning
dotnet_style_prefer_auto_properties = true:warning
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:warning
dotnet_style_prefer_conditional_expression_over_assignment = false:suggestion
dotnet_diagnostic.IDE0045.severity = suggestion
dotnet_style_prefer_conditional_expression_over_return = false:suggestion
dotnet_diagnostic.IDE0046.severity = suggestion
dotnet_style_prefer_compound_assignment = true:warning
dotnet_style_prefer_simplified_interpolation = true:warning
dotnet_style_prefer_simplified_boolean_expressions = true:warning
# Null-checking preferences
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#null-checking-preferences
dotnet_style_coalesce_expression = true:warning
dotnet_style_null_propagation = true:warning
# Parameter preferences
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#parameter-preferences
dotnet_code_quality_unused_parameters = all:warning
# More style options (Undocumented)
# https://github.com/MicrosoftDocs/visualstudio-docs/issues/3641
dotnet_style_operator_placement_when_wrapping = end_of_line
# https://github.com/dotnet/roslyn/pull/40070
dotnet_style_prefer_simplified_interpolation = true:warning
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:warning
# File header preferences
file_header_template = Copyright (c) Six Labors.\nLicensed under the Apache License, Version 2.0.
# SA1636: File header copyright text should match
# Justification: .editorconfig supports file headers. If this is changed to a value other than "none", a stylecop.json file will need to added to the project.
# dotnet_diagnostic.SA1636.severity = none
# C# Code Style Settings
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#c-code-style-settings
# Undocumented
dotnet_style_operator_placement_when_wrapping = end_of_line
# C# Style Rules
# https://docs.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/language-rules#c-style-rules
[*.{cs,csx,cake}]
# Implicit and explicit types
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#implicit-and-explicit-types
# 'var' preferences
csharp_style_var_for_built_in_types = never
csharp_style_var_when_type_is_apparent = true:warning
csharp_style_var_elsewhere = false:warning
# Expression-bodied members
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#expression-bodied-members
csharp_style_expression_bodied_methods = true:warning
csharp_style_expression_bodied_constructors = true:warning
csharp_style_expression_bodied_operators = true:warning
@ -149,47 +146,64 @@ csharp_style_expression_bodied_indexers = true:warning
csharp_style_expression_bodied_accessors = true:warning
csharp_style_expression_bodied_lambdas = true:warning
csharp_style_expression_bodied_local_functions = true:warning
# Pattern matching
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#pattern-matching
# Pattern matching preferences
csharp_style_pattern_matching_over_is_with_cast_check = true:warning
csharp_style_pattern_matching_over_as_with_null_check = true:warning
# Inlined variable declarations
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#inlined-variable-declarations
csharp_style_inlined_variable_declaration = true:warning
csharp_style_prefer_switch_expression = true:warning
csharp_style_prefer_pattern_matching = true:warning
csharp_style_prefer_not_pattern = true:warning
# Expression-level preferences
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#expression-level-preferences
csharp_style_inlined_variable_declaration = true:warning
csharp_prefer_simple_default_expression = true:warning
csharp_style_pattern_local_over_anonymous_function = true:warning
csharp_style_deconstructed_variable_declaration = true:warning
csharp_style_prefer_index_operator = true:warning
csharp_style_prefer_range_operator = true:warning
csharp_style_implicit_object_creation_when_type_is_apparent = true:warning
# "Null" checking preferences
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#c-null-checking-preferences
csharp_style_throw_expression = true:warning
csharp_style_conditional_delegate_call = true:warning
# Code block preferences
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#code-block-preferences
csharp_prefer_braces = true:warning
# Unused value preferences
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#unused-value-preferences
csharp_style_unused_value_expression_statement_preference = discard_variable:suggestion
csharp_style_unused_value_assignment_preference = discard_variable:suggestion
# Index and range preferences
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#index-and-range-preferences
csharp_style_prefer_index_operator = true:warning
csharp_style_prefer_range_operator = true:warning
# Miscellaneous preferences
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#miscellaneous-preferences
csharp_style_deconstructed_variable_declaration = true:warning
csharp_style_pattern_local_over_anonymous_function = true:warning
csharp_using_directive_placement = outside_namespace:warning
csharp_prefer_static_local_function = true:warning
csharp_prefer_simple_using_statement = true:suggestion
dotnet_diagnostic.IDE0063.severity = suggestion
# 'using' directive preferences
csharp_using_directive_placement = outside_namespace:warning
# Modifier preferences
csharp_prefer_static_local_function = true:warning
##########################################
# .NET Formatting Conventions
# https://docs.microsoft.com/visualstudio/ide/editorconfig-code-style-settings-reference#formatting-conventions
# Unnecessary Code Rules
# https://docs.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/unnecessary-code-rules
##########################################
# Organize usings
# https://docs.microsoft.com/visualstudio/ide/editorconfig-formatting-conventions#organize-using-directives
# .NET Unnecessary code rules
[*.{cs,csx,cake,vb,vbx}]
dotnet_code_quality_unused_parameters = all:warning
dotnet_remove_unnecessary_suppression_exclusions = none:warning
# C# Unnecessary code rules
[*.{cs,csx,cake}]
csharp_style_unused_value_expression_statement_preference = discard_variable:suggestion
dotnet_diagnostic.IDE0058.severity = suggestion
csharp_style_unused_value_assignment_preference = discard_variable:suggestion
dotnet_diagnostic.IDE0059.severity = suggestion
##########################################
# Formatting Rules
# https://docs.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/formatting-rules
##########################################
# .NET formatting rules
# https://docs.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/formatting-rules#net-formatting-rules
[*.{cs,csx,cake,vb,vbx}]
# Organize using directives
dotnet_sort_system_directives_first = true
dotnet_separate_import_directive_groups = false
# C# formatting rules
# https://docs.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/formatting-rules#c-formatting-rules
[*.{cs,csx,cake}]
# Newline options
# https://docs.microsoft.com/visualstudio/ide/editorconfig-formatting-conventions#new-line-options
csharp_new_line_before_open_brace = all
@ -231,14 +245,14 @@ csharp_space_around_declaration_statements = false
csharp_space_before_open_square_brackets = false
csharp_space_between_empty_square_brackets = false
csharp_space_between_square_brackets = false
# Wrapping options
# Wrap options
# https://docs.microsoft.com/visualstudio/ide/editorconfig-formatting-conventions#wrap-options
csharp_preserve_single_line_statements = false
csharp_preserve_single_line_blocks = true
##########################################
# .NET Naming Conventions
# https://docs.microsoft.com/visualstudio/ide/editorconfig-naming-conventions
# .NET Naming Rules
# https://docs.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/naming-rules
##########################################
[*.{cs,csx,cake,vb,vbx}]
@ -261,8 +275,9 @@ dotnet_naming_style.prefix_type_parameters_with_t_style.capitalization = pascal_
dotnet_naming_style.prefix_type_parameters_with_t_style.required_prefix = T
# disallowed_style - Anything that has this style applied is marked as disallowed
dotnet_naming_style.disallowed_style.capitalization = pascal_case
dotnet_naming_style.disallowed_style.required_prefix = ____RULE_VIOLATION____
dotnet_naming_style.disallowed_style.required_suffix = ____RULE_VIOLATION____
# Disabled while we investigate compatibility with VS 16.10
#dotnet_naming_style.disallowed_style.required_prefix = ____RULE_VIOLATION____
#dotnet_naming_style.disallowed_style.required_suffix = ____RULE_VIOLATION____
# internal_error_style - This style should never occur... if it does, it indicates a bug in file or in the parser using the file
dotnet_naming_style.internal_error_style.capitalization = pascal_case
dotnet_naming_style.internal_error_style.required_prefix = ____INTERNAL_ERROR____

31
.gitattributes поставляемый
Просмотреть файл

@ -4,7 +4,6 @@
# normalize to Unix-style line endings
###############################################################################
* text eol=lf
###############################################################################
# Set explicit file behavior to:
# treat as text and
@ -54,7 +53,6 @@
*.txt text eol=lf
*.vb text eol=lf
*.yml text eol=lf
###############################################################################
# Set explicit file behavior to:
# treat as text
@ -62,7 +60,6 @@
# diff as csharp
###############################################################################
*.cs text eol=lf diff=csharp
###############################################################################
# Set explicit file behavior to:
# treat as text
@ -74,7 +71,6 @@
*.fsproj text eol=lf merge=union
*.ncrunchproject text eol=lf merge=union
*.vbproj text eol=lf merge=union
###############################################################################
# Set explicit file behavior to:
# treat as text
@ -82,40 +78,28 @@
# use a union merge when resoling conflicts
###############################################################################
*.sln text eol=crlf merge=union
###############################################################################
# Set explicit file behavior to:
# treat as binary
###############################################################################
*.basis binary
*.bmp binary
*.dds binary
*.dll binary
*.eot binary
*.exe binary
*.gif binary
*.jpg binary
*.ktx binary
*.otf binary
*.pbm binary
*.pdf binary
*.png binary
*.ppt binary
*.pptx binary
*.pvr binary
*.snk binary
*.tga binary
*.tif binary
*.tiff binary
*.ttc binary
*.ttf binary
*.wbmp binary
*.webp binary
*.woff binary
*.woff2 binary
*.xls binary
*.xlsx binary
###############################################################################
# Set explicit file behavior to:
# diff as plain text
@ -127,3 +111,18 @@
*.pptx diff=astextplain
*.rtf diff=astextplain
*.svg diff=astextplain
###############################################################################
# Handle image files by git lfs
###############################################################################
*.jpg filter=lfs diff=lfs merge=lfs -text
*.jpeg filter=lfs diff=lfs merge=lfs -text
*.bmp filter=lfs diff=lfs merge=lfs -text
*.gif filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text
*.tif filter=lfs diff=lfs merge=lfs -text
*.tiff filter=lfs diff=lfs merge=lfs -text
*.tga filter=lfs diff=lfs merge=lfs -text
*.webp filter=lfs diff=lfs merge=lfs -text
*.dds filter=lfs diff=lfs merge=lfs -text
*.ktx filter=lfs diff=lfs merge=lfs -text
*.ktx2 filter=lfs diff=lfs merge=lfs -text

@ -1 +1 @@
Subproject commit b7b9a2755e456a96acbf103494228226d92eddf3
Subproject commit 0ea21d9e2a76d307dae9cfb74e33234b259352b7

Просмотреть файл

@ -83,8 +83,8 @@ namespace SixLabors.ImageSharp.Drawing.Processing
/// As this is a circular gradient, the position on the gradient is based on
/// the distance of the point to the center.
/// </summary>
/// <param name="x">The X coordinate of the target pixel.</param>
/// <param name="y">The Y coordinate of the target pixel.</param>
/// <param name="x">The x-coordinate of the target pixel.</param>
/// <param name="y">The y-coordinate of the target pixel.</param>
/// <returns>the position on the color gradient.</returns>
protected override float PositionOnGradient(float x, float y)
{

Просмотреть файл

@ -96,92 +96,21 @@ namespace SixLabors.ImageSharp.Drawing
this.PathType = PathTypes.Mixed;
}
/// <summary>
/// Gets a value indicating whether this instance is closed, open or a composite path with a mixture of open and closed figures.
/// </summary>
/// <inheritdoc/>
public PathTypes PathType { get; }
/// <summary>
/// Gets the paths that make up this shape
/// Gets the collection of paths that make up this shape.
/// </summary>
/// <value>
/// The paths.
/// </value>
public IEnumerable<IPath> Paths => this.paths;
/// <summary>
/// Gets the bounding box of this shape.
/// </summary>
/// <value>
/// The bounds.
/// </value>
/// <inheritdoc/>
public RectangleF Bounds { get; }
/// <inheritdoc/>
int IPathInternals.MaxIntersections => this.maxIntersections;
/// <inheritdoc />
int IPathInternals.FindIntersections(PointF start, PointF end, Span<PointF> intersections, Span<PointOrientation> orientations)
=> ((IPathInternals)this).FindIntersections(start, end, intersections, orientations, IntersectionRule.OddEven);
/// <inheritdoc />
int IPathInternals.FindIntersections(
PointF start,
PointF end,
Span<PointF> intersections,
Span<PointOrientation> orientations,
IntersectionRule intersectionRule)
{
int totalAdded = 0;
foreach (InternalPath ip in this.internalPaths)
{
Span<PointF> subBuffer = intersections.Slice(totalAdded);
Span<PointOrientation> subOrientationsSpan = orientations.Slice(totalAdded);
int position = ip.FindIntersectionsWithOrientation(start, end, subBuffer, subOrientationsSpan);
totalAdded += position;
}
// Avoid pool overhead for short runs.
// This method can be called in high volume.
const int MaxStackSize = 1024 / sizeof(float);
float[] rentedFromPool = null;
Span<float> buffer =
totalAdded > MaxStackSize
? (rentedFromPool = ArrayPool<float>.Shared.Rent(totalAdded))
: stackalloc float[MaxStackSize];
Span<float> distances = buffer.Slice(0, totalAdded);
for (int i = 0; i < totalAdded; i++)
{
distances[i] = Vector2.DistanceSquared(start, intersections[i]);
}
Span<PointF> activeIntersections = intersections.Slice(0, totalAdded);
Span<PointOrientation> activeOrientations = orientations.Slice(0, totalAdded);
SortUtility.Sort(distances, activeIntersections, activeOrientations);
if (intersectionRule == IntersectionRule.Nonzero)
{
totalAdded = InternalPath.ApplyNonZeroIntersectionRules(activeIntersections, activeOrientations);
}
if (rentedFromPool != null)
{
ArrayPool<float>.Shared.Return(rentedFromPool);
}
return totalAdded;
}
/// <summary>
/// Determines whether the <see cref="IPath" /> contains the specified point
/// </summary>
/// <param name="point">The point.</param>
/// <returns>
/// <c>true</c> if the <see cref="IPath" /> contains the specified point; otherwise, <c>false</c>.
/// </returns>
/// <inheritdoc/>
public bool Contains(PointF point)
{
bool inside = false;
@ -196,18 +125,12 @@ namespace SixLabors.ImageSharp.Drawing
return inside;
}
/// <summary>
/// Transforms the shape using the specified matrix.
/// </summary>
/// <param name="matrix">The matrix.</param>
/// <returns>
/// A new shape with the matrix applied to it.
/// </returns>
/// <inheritdoc/>
public IPath Transform(Matrix3x2 matrix)
{
if (matrix.IsIdentity)
{
// no transform to apply skip it
// No transform to apply skip it
return this;
}
@ -233,37 +156,79 @@ namespace SixLabors.ImageSharp.Drawing
return paths.ToArray();
}
/// <summary>
/// Converts a path to a closed path.
/// </summary>
/// <returns>
/// Returns the path as a closed path.
/// </returns>
/// <inheritdoc/>
public IPath AsClosedPath()
{
if (this.PathType == PathTypes.Closed)
{
return this;
}
else
{
var paths = new IPath[this.paths.Length];
for (int i = 0; i < this.paths.Length; i++)
{
paths[i] = this.paths[i].AsClosedPath();
}
return new ComplexPolygon(paths);
var paths = new IPath[this.paths.Length];
for (int i = 0; i < this.paths.Length; i++)
{
paths[i] = this.paths[i].AsClosedPath();
}
return new ComplexPolygon(paths);
}
/// <summary>
/// Calculates the point a certain distance a path.
/// </summary>
/// <param name="distance">The distance along the path to find details of.</param>
/// <returns>
/// Returns details about a point along a path.
/// </returns>
/// <inheritdoc />
int IPathInternals.FindIntersections(PointF start, PointF end, Span<PointF> intersections, Span<PointOrientation> orientations)
=> ((IPathInternals)this).FindIntersections(start, end, intersections, orientations, IntersectionRule.OddEven);
/// <inheritdoc />
int IPathInternals.FindIntersections(
PointF start,
PointF end,
Span<PointF> intersections,
Span<PointOrientation> orientations,
IntersectionRule intersectionRule)
{
int totalAdded = 0;
foreach (InternalPath ip in this.internalPaths)
{
Span<PointF> subBuffer = intersections.Slice(totalAdded);
Span<PointOrientation> subOrientationsSpan = orientations.Slice(totalAdded);
int position = ip.FindIntersectionsWithOrientation(start, end, subBuffer, subOrientationsSpan);
totalAdded += position;
}
// Avoid pool overhead for short runs.
// This method can be called in high volume.
const int maxStackSize = 1024 / sizeof(float);
float[] rentedFromPool = null;
Span<float> buffer =
totalAdded > maxStackSize
? (rentedFromPool = ArrayPool<float>.Shared.Rent(totalAdded))
: stackalloc float[maxStackSize];
Span<float> distances = buffer.Slice(0, totalAdded);
for (int i = 0; i < totalAdded; i++)
{
distances[i] = Vector2.DistanceSquared(start, intersections[i]);
}
Span<PointF> activeIntersections = intersections.Slice(0, totalAdded);
Span<PointOrientation> activeOrientations = orientations.Slice(0, totalAdded);
SortUtility.Sort(distances, activeIntersections, activeOrientations);
if (intersectionRule == IntersectionRule.Nonzero)
{
totalAdded = InternalPath.ApplyNonZeroIntersectionRules(activeIntersections, activeOrientations);
}
if (rentedFromPool != null)
{
ArrayPool<float>.Shared.Return(rentedFromPool);
}
return totalAdded;
}
/// <inheritdoc/>
SegmentInfo IPathInternals.PointAlongPath(float distance)
{
distance %= this.length;

Просмотреть файл

@ -10,7 +10,7 @@ namespace SixLabors.ImageSharp.Drawing
/// <summary>
/// An elliptical shape made up of a single path made up of one of more <see cref="ILineSegment"/>s.
/// </summary>
public class EllipsePolygon : IPath, ISimplePath, IPathInternals, IInternalPathOwner
public sealed class EllipsePolygon : IPath, ISimplePath, IPathInternals, IInternalPathOwner
{
private readonly InternalPath innerPath;
private readonly CubicBezierLineSegment segment;
@ -19,7 +19,7 @@ namespace SixLabors.ImageSharp.Drawing
/// Initializes a new instance of the <see cref="EllipsePolygon" /> class.
/// </summary>
/// <param name="location">The location the center of the ellipse will be placed.</param>
/// <param name="size">The width/hight of the final ellipse.</param>
/// <param name="size">The width/height of the final ellipse.</param>
public EllipsePolygon(PointF location, SizeF size)
: this(CreateSegment(location, size))
{
@ -38,8 +38,8 @@ namespace SixLabors.ImageSharp.Drawing
/// <summary>
/// Initializes a new instance of the <see cref="EllipsePolygon" /> class.
/// </summary>
/// <param name="x">The X coordinate of the center of the ellipse.</param>
/// <param name="y">The Y coordinate of the center of the ellipse.</param>
/// <param name="x">The x-coordinate of the center of the ellipse.</param>
/// <param name="y">The y-coordinate of the center of the ellipse.</param>
/// <param name="width">The width the ellipse should have.</param>
/// <param name="height">The height the ellipse should have.</param>
public EllipsePolygon(float x, float y, float width, float height)
@ -50,8 +50,8 @@ namespace SixLabors.ImageSharp.Drawing
/// <summary>
/// Initializes a new instance of the <see cref="EllipsePolygon" /> class.
/// </summary>
/// <param name="x">The X coordinate of the center of the circle.</param>
/// <param name="y">The Y coordinate of the center of the circle.</param>
/// <param name="x">The x-coordinate of the center of the circle.</param>
/// <param name="y">The y-coordinate of the center of the circle.</param>
/// <param name="radius">The radius final circle.</param>
public EllipsePolygon(float x, float y, float radius)
: this(new PointF(x, y), new SizeF(radius * 2, radius * 2))
@ -64,52 +64,28 @@ namespace SixLabors.ImageSharp.Drawing
this.innerPath = new InternalPath(segment, true);
}
/// <summary>
/// Gets a value indicating whether this instance is a closed path.
/// </summary>
bool ISimplePath.IsClosed => true;
/// <inheritdoc/>
public bool IsClosed => true;
/// <summary>
/// Gets the points that make up this simple linear path.
/// </summary>
ReadOnlyMemory<PointF> ISimplePath.Points => this.innerPath.Points();
/// <inheritdoc/>
public ReadOnlyMemory<PointF> Points => this.innerPath.Points();
/// <inheritdoc />
public RectangleF Bounds => this.innerPath.Bounds;
/// <summary>
/// Gets a value indicating whether this instance is closed, open or a composite path with a mixture of open and closed figures.
/// </summary>
PathTypes IPath.PathType => PathTypes.Closed;
/// <inheritdoc/>
public PathTypes PathType => PathTypes.Closed;
/// <inheritdoc />
int IPathInternals.MaxIntersections => this.innerPath.PointCount;
/// <summary>
/// Transforms the rectangle using specified matrix.
/// </summary>
/// <param name="matrix">The matrix.</param>
/// <returns>
/// A new path with the matrix applied to it.
/// </returns>
public EllipsePolygon Transform(Matrix3x2 matrix) => matrix.IsIdentity
? this
: new EllipsePolygon(this.segment.Transform(matrix));
/// <inheritdoc/>
public IPath Transform(Matrix3x2 matrix) => matrix.IsIdentity
? this
: new EllipsePolygon(this.segment.Transform(matrix));
/// <summary>
/// Transforms the path using the specified matrix.
/// </summary>
/// <param name="matrix">The matrix.</param>
/// <returns>
/// A new path with the matrix applied to it.
/// </returns>
IPath IPath.Transform(Matrix3x2 matrix) => this.Transform(matrix);
/// <summary>
/// Returns this polygon as a path
/// </summary>
/// <returns>This polygon as a path</returns>
IPath IPath.AsClosedPath() => this;
/// <inheritdoc/>
public IPath AsClosedPath() => this;
/// <inheritdoc />
public IEnumerable<ISimplePath> Flatten()
@ -130,13 +106,7 @@ namespace SixLabors.ImageSharp.Drawing
IntersectionRule intersectionRule)
=> this.innerPath.FindIntersections(start, end, intersections, orientations, intersectionRule);
/// <summary>
/// Determines whether the <see cref="IPath" /> contains the specified point
/// </summary>
/// <param name="point">The point.</param>
/// <returns>
/// <c>true</c> if the <see cref="IPath" /> contains the specified point; otherwise, <c>false</c>.
/// </returns>
/// <inheritdoc/>
public bool Contains(PointF point) => this.innerPath.PointInPolygon(point);
/// <inheritdoc />
@ -144,6 +114,10 @@ namespace SixLabors.ImageSharp.Drawing
SegmentInfo IPathInternals.PointAlongPath(float distance)
=> this.innerPath.PointAlongPath(distance);
/// <inheritdoc/>
IReadOnlyList<InternalPath> IInternalPathOwner.GetRingsAsInternalPath()
=> new[] { this.innerPath };
private static CubicBezierLineSegment CreateSegment(Vector2 location, SizeF size)
{
Guard.MustBeGreaterThan(size.Width, 0, "width");
@ -185,9 +159,5 @@ namespace SixLabors.ImageSharp.Drawing
return new CubicBezierLineSegment(points);
}
/// <inheritdoc/>
IReadOnlyList<InternalPath> IInternalPathOwner.GetRingsAsInternalPath()
=> new[] { this.innerPath };
}
}

Просмотреть файл

@ -7,7 +7,7 @@ using System.Numerics;
namespace SixLabors.ImageSharp.Drawing
{
/// <summary>
/// Represents a logic path that can be drawn
/// Represents a logic path that can be drawn.
/// </summary>
public interface IPath
{

Просмотреть файл

@ -6,7 +6,7 @@ using System;
namespace SixLabors.ImageSharp.Drawing
{
/// <summary>
/// Represents a logic path that can be drawn
/// Represents a simplified logic path that can be drawn.
/// </summary>
public interface ISimplePath
{

Просмотреть файл

@ -368,7 +368,6 @@ namespace SixLabors.ImageSharp.Drawing
diff = -1;
break;
case PointOrientation.Collinear:
default:
diff *= -1;
break;
}

Просмотреть файл

@ -9,7 +9,7 @@ using System.Numerics;
namespace SixLabors.ImageSharp.Drawing
{
/// <summary>
/// A aggregate of <see cref="ILineSegment"/>s making a single logical path
/// A aggregate of <see cref="ILineSegment"/>s making a single logical path.
/// </summary>
/// <seealso cref="IPath" />
public class Path : IPath, ISimplePath, IPathInternals, IInternalPathOwner
@ -42,39 +42,29 @@ namespace SixLabors.ImageSharp.Drawing
public Path(params ILineSegment[] segments)
=> this.lineSegments = segments ?? throw new ArgumentNullException(nameof(segments));
/// <summary>
/// Gets a value indicating whether this instance is a closed path.
/// </summary>
/// <inheritdoc/>
bool ISimplePath.IsClosed => this.IsClosed;
/// <summary>
/// Gets the points that make up this simple linear path.
/// </summary>
ReadOnlyMemory<PointF> ISimplePath.Points => this.InnerPath.Points();
/// <inheritdoc cref="ISimplePath.IsClosed"/>
public virtual bool IsClosed => false;
/// <inheritdoc/>
public ReadOnlyMemory<PointF> Points => this.InnerPath.Points();
/// <inheritdoc />
public RectangleF Bounds => this.InnerPath.Bounds;
/// <summary>
/// Gets a value indicating whether this instance is closed, open or a composite path with a mixture of open and closed figures.
/// </summary>
/// <inheritdoc />
public PathTypes PathType => this.IsClosed ? PathTypes.Open : PathTypes.Closed;
/// <summary>
/// Gets the maximum number intersections that a shape can have when testing a line.
/// </summary>
/// <inheritdoc />
public int MaxIntersections => this.InnerPath.PointCount;
/// <summary>
/// Gets the line segments
/// Gets readonly collection of line segments.
/// </summary>
public IReadOnlyList<ILineSegment> LineSegments => this.lineSegments;
/// <summary>
/// Gets a value indicating whether this instance is a closed path.
/// </summary>
protected virtual bool IsClosed => false;
/// <summary>
/// Gets or sets a value indicating whether close or collinear vertices should be removed. TEST ONLY!
/// </summary>
@ -83,13 +73,7 @@ namespace SixLabors.ImageSharp.Drawing
private InternalPath InnerPath =>
this.innerPath ??= new InternalPath(this.lineSegments, this.IsClosed, this.RemoveCloseAndCollinearPoints);
/// <summary>
/// Transforms the rectangle using specified matrix.
/// </summary>
/// <param name="matrix">The matrix.</param>
/// <returns>
/// A new path with the matrix applied to it.
/// </returns>
/// <inheritdoc />
public virtual IPath Transform(Matrix3x2 matrix)
{
if (matrix.IsIdentity)
@ -107,20 +91,15 @@ namespace SixLabors.ImageSharp.Drawing
return new Path(segments);
}
/// <summary>
/// Returns this polygon as a path
/// </summary>
/// <returns>This polygon as a path</returns>
/// <inheritdoc />
public IPath AsClosedPath()
{
if (this.IsClosed)
{
return this;
}
else
{
return new Polygon(this.LineSegments);
}
return new Polygon(this.LineSegments);
}
/// <inheritdoc />
@ -129,6 +108,9 @@ namespace SixLabors.ImageSharp.Drawing
yield return this;
}
/// <inheritdoc />
public bool Contains(PointF point) => this.InnerPath.PointInPolygon(point);
/// <inheritdoc />
int IPathInternals.FindIntersections(PointF start, PointF end, Span<PointF> intersections, Span<PointOrientation> orientations)
=> this.InnerPath.FindIntersections(start, end, intersections, orientations);
@ -142,18 +124,9 @@ namespace SixLabors.ImageSharp.Drawing
IntersectionRule intersectionRule)
=> this.InnerPath.FindIntersections(start, end, intersections, orientations, intersectionRule);
/// <summary>
/// Determines whether the <see cref="IPath" /> contains the specified point
/// </summary>
/// <param name="point">The point.</param>
/// <returns>
/// <c>true</c> if the <see cref="IPath" /> contains the specified point; otherwise, <c>false</c>.
/// </returns>
public bool Contains(PointF point) => this.InnerPath.PointInPolygon(point);
/// <inheritdoc/>
SegmentInfo IPathInternals.PointAlongPath(float distanceAlongPath)
=> this.InnerPath.PointAlongPath(distanceAlongPath);
SegmentInfo IPathInternals.PointAlongPath(float distance)
=> this.InnerPath.PointAlongPath(distance);
/// <inheritdoc/>
IReadOnlyList<InternalPath> IInternalPathOwner.GetRingsAsInternalPath() => new[] { this.InnerPath };

Просмотреть файл

@ -7,7 +7,7 @@ using System.Numerics;
namespace SixLabors.ImageSharp.Drawing
{
/// <summary>
/// A shape made up of a single path made up of one of more <see cref="ILineSegment"/>s
/// A shape made up of a single closed path made up of one of more <see cref="ILineSegment"/>s
/// </summary>
public class Polygon : Path
{
@ -47,18 +47,10 @@ namespace SixLabors.ImageSharp.Drawing
{
}
/// <summary>
/// Gets a value indicating whether this instance is a closed path.
/// </summary>
protected override bool IsClosed => true;
/// <inheritdoc />
public override bool IsClosed => true;
/// <summary>
/// Transforms the rectangle using specified matrix.
/// </summary>
/// <param name="matrix">The matrix.</param>
/// <returns>
/// A new shape with the matrix applied to it.
/// </returns>
/// <inheritdoc />
public override IPath Transform(Matrix3x2 matrix)
{
if (matrix.IsIdentity)

Просмотреть файл

@ -2,7 +2,7 @@
Scanning is done with a variant of the ["Active Edge Table" algorithm](https://en.wikipedia.org/wiki/Scanline_rendering#Algorithm), that doesn't build a table beforehand, just maintains the list of currently active edges.
After rasterizing polygons a collection of non-horizontal edges (ScanEdge) is extracted into ScanEdgeCollection. These are then sorted by minimum and maximum Y coordinate, which enables the maintanance of the Active Edge List as we traverse the collection from `minY` to `maxY`.
After rasterizing polygons a collection of non-horizontal edges (ScanEdge) is extracted into ScanEdgeCollection. These are then sorted by minimum and maximum y-coordinate, which enables the maintanance of the Active Edge List as we traverse the collection from `minY` to `maxY`.
When intersecting a ScanEdge start (Y0) and end (Y1) intersections have special handling. Since these belong to vertices (connection points) sometimes we need to emit the intersection point 2 times. In other cases we do not want to emit it at all.
@ -73,4 +73,4 @@ Edge In | Edge Out | Emit on "Edge In" | Emit on "Edge out"
⟶ | ↑ | 0 | 2
⟶ | ↓ | 0 | 1
⟶ | ⟵ | 0 | 0
⟶ | ⟶ | 0 | 0
⟶ | ⟶ | 0 | 0

Просмотреть файл

@ -11,14 +11,13 @@ namespace SixLabors.ImageSharp.Drawing
/// A polygon tha allows the optimized drawing of rectangles.
/// </summary>
/// <seealso cref="IPath" />
public class RectangularPolygon : IPath, ISimplePath, IPathInternals
public sealed class RectangularPolygon : IPath, ISimplePath, IPathInternals
{
private readonly Vector2 topLeft;
private readonly Vector2 bottomRight;
private readonly PointF[] points;
private readonly float halfLength;
private readonly float length;
private readonly RectangleF bounds;
/// <summary>
/// Initializes a new instance of the <see cref="RectangularPolygon" /> class.
@ -58,7 +57,7 @@ namespace SixLabors.ImageSharp.Drawing
this.halfLength = this.Size.Width + this.Size.Height;
this.length = this.halfLength * 2;
this.bounds = new RectangleF(this.Location, this.Size);
this.Bounds = new RectangleF(this.Location, this.Size);
}
/// <summary>
@ -119,60 +118,39 @@ namespace SixLabors.ImageSharp.Drawing
/// </summary>
public float Bottom => this.bottomRight.Y;
/// <summary>
/// Gets the bounding box of this shape.
/// </summary>
RectangleF IPath.Bounds => this.bounds;
/// <inheritdoc/>
public RectangleF Bounds { get; private set; }
/// <inheritdoc/>
int IPathInternals.MaxIntersections => 4;
/// <summary>
/// Gets a value indicating whether this instance is a closed path.
/// </summary>
bool ISimplePath.IsClosed => true;
/// <inheritdoc/>
public bool IsClosed => true;
/// <summary>
/// Gets the points that make this up as a simple linear path.
/// </summary>
ReadOnlyMemory<PointF> ISimplePath.Points => this.points;
/// <inheritdoc/>
public ReadOnlyMemory<PointF> Points => this.points;
/// <summary>
/// Gets the size.
/// </summary>
/// <value>
/// The size.
/// </value>
public SizeF Size { get; }
/// <summary>
/// Gets the size.
/// Gets the width.
/// </summary>
/// <value>
/// The size.
/// </value>
public float Width => this.Size.Width;
/// <summary>
/// Gets the height.
/// </summary>
/// <value>
/// The height.
/// </value>
public float Height => this.Size.Height;
/// <summary>
/// Gets a value indicating whether this instance is closed, open or a composite path with a mixture
/// of open and closed figures.
/// </summary>
PathTypes IPath.PathType => PathTypes.Closed;
/// <inheritdoc/>
public PathTypes PathType => PathTypes.Closed;
/// <summary>
/// Gets the center.
/// Gets the center point.
/// </summary>
/// <value>
/// The center.
/// </value>
public PointF Center => (this.topLeft + this.bottomRight) / 2;
/// <summary>
@ -182,14 +160,7 @@ namespace SixLabors.ImageSharp.Drawing
public static explicit operator RectangularPolygon(Polygon polygon)
=> new RectangularPolygon(polygon.Bounds.X, polygon.Bounds.Y, polygon.Bounds.Width, polygon.Bounds.Height);
/// <summary>
/// Determines if the specified point is contained within the rectangular region defined by
/// this <see cref="RectangularPolygon" />.
/// </summary>
/// <param name="point">The point.</param>
/// <returns>
/// The <see cref="bool" />
/// </returns>
/// <inheritdoc/>
public bool Contains(PointF point)
=> Vector2.Clamp(point, this.topLeft, this.bottomRight) == (Vector2)point;
@ -211,37 +182,25 @@ namespace SixLabors.ImageSharp.Drawing
var endPoint = Vector2.Clamp(end, this.topLeft, this.bottomRight);
// Start doesn't change when its inside the shape thus not crossing
if (startPoint != (Vector2)start)
if (startPoint != (Vector2)start && startPoint == Vector2.Clamp(startPoint, start, end))
{
if (startPoint == Vector2.Clamp(startPoint, start, end))
{
// If start closest is within line then its a valid point
discovered++;
intersections[offset++] = startPoint;
}
// If start closest is within line then its a valid point
discovered++;
intersections[offset++] = startPoint;
}
// End didn't change it must not intercept with an edge
if (endPoint != (Vector2)end)
if (endPoint != (Vector2)end && endPoint == Vector2.Clamp(endPoint, start, end))
{
if (endPoint == Vector2.Clamp(endPoint, start, end))
{
// If start closest is within line then its a valid point
discovered++;
intersections[offset] = endPoint;
}
// If start closest is within line then its a valid point
discovered++;
intersections[offset] = endPoint;
}
return discovered;
}
/// <summary>
/// Transforms the rectangle using specified matrix.
/// </summary>
/// <param name="matrix">The matrix.</param>
/// <returns>
/// A new shape with the matrix applied to it.
/// </returns>
/// <inheritdoc/>
public IPath Transform(Matrix3x2 matrix)
{
if (matrix.IsIdentity)
@ -249,7 +208,7 @@ namespace SixLabors.ImageSharp.Drawing
return this;
}
// rectangles may be rotated and skewed which means they will then nedd representing by a polygon
// Rectangles may be rotated and skewed which means they will then nedd representing by a polygon
return new Polygon(new LinearLineSegment(this.points).Transform(matrix));
}
@ -267,41 +226,35 @@ namespace SixLabors.ImageSharp.Drawing
Angle = MathF.PI
};
}
else
distance -= this.Width;
if (distance < this.Height)
{
distance -= this.Width;
if (distance < this.Height)
// down on right
return new SegmentInfo
{
// down on right
return new SegmentInfo
{
Point = new Vector2(this.Right, this.Top + distance),
Angle = -MathF.PI / 2
};
}
else
{
distance -= this.Height;
if (distance < this.Width)
{
// botom right to left
return new SegmentInfo
{
Point = new Vector2(this.Right - distance, this.Bottom),
Angle = 0
};
}
else
{
distance -= this.Width;
return new SegmentInfo
{
Point = new Vector2(this.Left, this.Bottom - distance),
Angle = (float)(Math.PI / 2)
};
}
}
Point = new Vector2(this.Right, this.Top + distance),
Angle = -MathF.PI / 2
};
}
distance -= this.Height;
if (distance < this.Width)
{
// botom right to left
return new SegmentInfo
{
Point = new Vector2(this.Right - distance, this.Bottom),
Angle = 0
};
}
distance -= this.Width;
return new SegmentInfo
{
Point = new Vector2(this.Left, this.Bottom - distance),
Angle = (float)(Math.PI / 2)
};
}
/// <inheritdoc/>
@ -310,12 +263,7 @@ namespace SixLabors.ImageSharp.Drawing
yield return this;
}
/// <summary>
/// Converts a path to a closed path.
/// </summary>
/// <returns>
/// Returns the path as a closed path.
/// </returns>
IPath IPath.AsClosedPath() => this;
/// <inheritdoc/>
public IPath AsClosedPath() => this;
}
}

Просмотреть файл

@ -27,8 +27,8 @@ namespace SixLabors.ImageSharp.Drawing
/// Initializes a new instance of the <see cref="RegularPolygon" /> class.
/// </summary>
/// <param name="location">The location the center of the polygon will be placed.</param>
/// <param name="radius">The radius of the circle that would touch all verticies.</param>
/// <param name="verticies">The number of verticies the <see cref="RegularPolygon"/> should have.</param>
/// <param name="radius">The radius of the circle that would touch all verticies.</param>
public RegularPolygon(PointF location, int verticies, float radius)
: this(location, verticies, radius, 0)
{
@ -37,8 +37,8 @@ namespace SixLabors.ImageSharp.Drawing
/// <summary>
/// Initializes a new instance of the <see cref="RegularPolygon" /> class.
/// </summary>
/// <param name="x">The X coordinate of the center of the polygon.</param>
/// <param name="y">The Y coordinate of the center of the polygon.</param>
/// <param name="x">The x-coordinate of the center of the polygon.</param>
/// <param name="y">The y-coordinate of the center of the polygon.</param>
/// <param name="verticies">The number of verticies the <see cref="RegularPolygon" /> should have.</param>
/// <param name="radius">The radius of the circle that would touch all verticies.</param>
/// <param name="angle">The angle of rotation in Radians</param>
@ -50,10 +50,10 @@ namespace SixLabors.ImageSharp.Drawing
/// <summary>
/// Initializes a new instance of the <see cref="RegularPolygon" /> class.
/// </summary>
/// <param name="x">The X coordinate of the center of the polygon.</param>
/// <param name="y">The Y coordinate of the center of the polygon.</param>
/// <param name="radius">The radius of the circle that would touch all verticies.</param>
/// <param name="x">The x-coordinate of the center of the polygon.</param>
/// <param name="y">The y-coordinate of the center of the polygon.</param>
/// <param name="verticies">The number of verticies the <see cref="RegularPolygon"/> should have.</param>
/// <param name="radius">The radius of the circle that would touch all verticies.</param>
public RegularPolygon(float x, float y, int verticies, float radius)
: this(new PointF(x, y), verticies, radius)
{
@ -66,7 +66,7 @@ namespace SixLabors.ImageSharp.Drawing
var distanceVector = new PointF(0, radius);
float anglePerSegments = (float)((2 * Math.PI) / verticies);
float anglePerSegments = (float)(2 * Math.PI / verticies);
float current = angle;
var points = new PointF[verticies];
for (int i = 0; i < verticies; i++)

Просмотреть файл

@ -7,7 +7,7 @@ using System.Numerics;
namespace SixLabors.ImageSharp.Drawing
{
/// <summary>
/// A shape made up of a single path made up of one of more <see cref="ILineSegment"/>s
/// A shape made up of a single closed path made up of one of more <see cref="ILineSegment"/>s
/// </summary>
public sealed class Star : Polygon
{
@ -39,8 +39,8 @@ namespace SixLabors.ImageSharp.Drawing
/// <summary>
/// Initializes a new instance of the <see cref="Star" /> class.
/// </summary>
/// <param name="x">The X coordinate of the center of the polygon.</param>
/// <param name="y">The Y coordinate of the center of the polygon.</param>
/// <param name="x">The x-coordinate of the center of the polygon.</param>
/// <param name="y">The y-coordinate of the center of the polygon.</param>
/// <param name="prongs">The number of verticies the <see cref="RegularPolygon" /> should have.</param>
/// <param name="innerRadii">The inner radii.</param>
/// <param name="outerRadii">The outer radii.</param>
@ -53,8 +53,8 @@ namespace SixLabors.ImageSharp.Drawing
/// <summary>
/// Initializes a new instance of the <see cref="Star" /> class.
/// </summary>
/// <param name="x">The X coordinate of the center of the polygon.</param>
/// <param name="y">The Y coordinate of the center of the polygon.</param>
/// <param name="x">The x-coordinate of the center of the polygon.</param>
/// <param name="y">The y-coordinate of the center of the polygon.</param>
/// <param name="prongs">The number of verticies the <see cref="RegularPolygon" /> should have.</param>
/// <param name="innerRadii">The inner radii.</param>
/// <param name="outerRadii">The outer radii.</param>
@ -73,7 +73,7 @@ namespace SixLabors.ImageSharp.Drawing
var distanceVectorOuter = new Vector2(0, outerRadii);
int verticies = prongs * 2;
float anglePerSegemnts = (float)((2 * Math.PI) / verticies);
float anglePerSegemnts = (float)(2 * Math.PI / verticies);
float current = angle;
var points = new PointF[verticies];
Vector2 distance = distanceVectorInner;

Просмотреть файл

@ -18,7 +18,7 @@ namespace SixLabors.ImageSharp.Drawing.Shapes
/// - Holes are oriented "Negative" (CW in world, CCW on screen)
/// - First vertex is always repeated at the end of the span in each ring
/// </summary>
internal class TessellatedMultipolygon : IDisposable, IReadOnlyList<TessellatedMultipolygon.Ring>
internal sealed class TessellatedMultipolygon : IDisposable, IReadOnlyList<TessellatedMultipolygon.Ring>
{
private Ring[] rings;