Update submodule and fix violations

This commit is contained in:
James Jackson-South 2019-09-01 12:15:53 +10:00
Родитель 36c020d233
Коммит dc0e39ca82
33 изменённых файлов: 1047 добавлений и 589 удалений

372
.editorconfig Normal file
Просмотреть файл

@ -0,0 +1,372 @@
###############################################################################
# EditorConfig is awesome: http://EditorConfig.org
###############################################################################
###############################################################################
# Top-most EditorConfig file
###############################################################################
root = true
###############################################################################
# Set default behavior to:
# a UTF-8 encoding,
# Unix-style line endings,
# a newline ending the file,
# 4 space indentation, and
# trimming of trailing whitespace
###############################################################################
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
trim_trailing_whitespace = true
###############################################################################
# Set file behavior to:
# 2 space indentation
###############################################################################
[*.{cmd,config,csproj,json,props,ps1,resx,sh,targets}]
indent_size = 2
###############################################################################
# Set file behavior to:
# Windows-style line endings, and
# tabular indentation
###############################################################################
[*.sln]
end_of_line = crlf
indent_style = tab
###############################################################################
# Set dotnet naming rules to:
# suggest async members be pascal case suffixed with Async
# suggest const declarations be pascal case
# suggest interfaces be pascal case prefixed with I
# suggest parameters be camel case
# suggest private and internal static fields be camel case
# suggest private and internal fields be camel case
# suggest public and protected declarations be pascal case
# suggest static readonly declarations be pascal case
# suggest type parameters be prefixed with T
###############################################################################
[*.cs]
dotnet_naming_rule.async_members_should_be_pascal_case_suffixed_with_async.severity = suggestion
dotnet_naming_rule.async_members_should_be_pascal_case_suffixed_with_async.style = pascal_case_suffixed_with_async
dotnet_naming_rule.async_members_should_be_pascal_case_suffixed_with_async.symbols = async_members
dotnet_naming_rule.const_declarations_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.const_declarations_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.const_declarations_should_be_pascal_case.symbols = const_declarations
dotnet_naming_rule.interfaces_should_be_pascal_case_prefixed_with_i.severity = suggestion
dotnet_naming_rule.interfaces_should_be_pascal_case_prefixed_with_i.style = pascal_case_prefixed_with_i
dotnet_naming_rule.interfaces_should_be_pascal_case_prefixed_with_i.symbols = interfaces
dotnet_naming_rule.parameters_should_be_camel_case.severity = suggestion
dotnet_naming_rule.parameters_should_be_camel_case.style = camel_case
dotnet_naming_rule.parameters_should_be_camel_case.symbols = parameters
dotnet_naming_rule.private_and_internal_static_fields_should_be_camel_case.severity = suggestion
dotnet_naming_rule.private_and_internal_static_fields_should_be_camel_case.style = camel_case
dotnet_naming_rule.private_and_internal_static_fields_should_be_camel_case.symbols = private_and_internal_static_fields
dotnet_naming_rule.private_and_internal_fields_should_be_camel_case.severity = suggestion
dotnet_naming_rule.private_and_internal_fields_should_be_camel_case.style = camel_case
dotnet_naming_rule.private_and_internal_fields_should_be_camel_case.symbols = private_and_internal_fields
dotnet_naming_rule.public_and_protected_declarations_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.public_and_protected_declarations_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.public_and_protected_declarations_should_be_pascal_case.symbols = public_and_protected_declarations
dotnet_naming_symbols.public_and_protected_declarations.applicable_kinds = method, field, event, property
dotnet_naming_rule.static_readonly_declarations_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.static_readonly_declarations_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.static_readonly_declarations_should_be_pascal_case.symbols = static_readonly_declarations
dotnet_naming_rule.type_parameters_should_be_pascal_case_prefixed_with_t.severity = suggestion
dotnet_naming_rule.type_parameters_should_be_pascal_case_prefixed_with_t.style = pascal_case_prefixed_with_t
dotnet_naming_rule.type_parameters_should_be_pascal_case_prefixed_with_t.symbols = type_parameters
###############################################################################
# Set dotnet naming styles to define:
# camel case
# pascal case
# pascal case suffixed with Async
# pascal case prefixed with I
# pascal case prefixed with T
###############################################################################
[*.cs]
dotnet_naming_style.camel_case.capitalization = camel_case
dotnet_naming_style.pascal_case.capitalization = pascal_case
dotnet_naming_style.pascal_case_suffixed_with_async.capitalization = pascal_case
dotnet_naming_style.pascal_case_suffixed_with_async.required_suffix = Async
dotnet_naming_style.pascal_case_prefixed_with_i.capitalization = pascal_case
dotnet_naming_style.pascal_case_prefixed_with_i.required_prefix = I
dotnet_naming_style.pascal_case_prefixed_with_t.capitalization = pascal_case
dotnet_naming_style.pascal_case_prefixed_with_t.required_prefix = T
###############################################################################
# Set dotnet naming symbols to:
# async members
# const declarations
# interfaces
# private and internal fields
# private and internal static fields
# public and protected declarations
# static readonly declarations
# type parameters
###############################################################################
[*.cs]
dotnet_naming_symbols.async_members.required_modifiers = async
dotnet_naming_symbols.const_declarations.required_modifiers = const
dotnet_naming_symbols.interfaces.applicable_kinds = interface
dotnet_naming_symbols.parameters.applicable_kinds = parameter
dotnet_naming_symbols.private_and_internal_fields.applicable_accessibilities = private, internal
dotnet_naming_symbols.private_and_internal_fields.applicable_kinds = field
dotnet_naming_symbols.private_and_internal_static_fields.applicable_accessibilities = private, internal
dotnet_naming_symbols.private_and_internal_static_fields.applicable_kinds = field
dotnet_naming_symbols.private_and_internal_static_fields.required_modifiers = static
dotnet_naming_symbols.public_and_protected_declarations.applicable_accessibilities = public, protected
dotnet_naming_symbols.static_readonly_declarations.required_modifiers = static, readonly
dotnet_naming_symbols.type_parameters.applicable_kinds = type_parameter
###############################################################################
# Set dotnet sort options to:
# do not separate import directives into groups, and
# sort system directives first
###############################################################################
[*.cs]
dotnet_separate_import_directive_groups = false
dotnet_sort_system_directives_first = true
###############################################################################
# Set dotnet style options to:
# suggest null-coalescing expressions,
# suggest collection-initializers,
# suggest explicit tuple names,
# suggest null-propogation
# suggest object-initializers,
# generate parentheses in arithmetic binary operators for clarity,
# generate parentheses in other binary operators for clarity,
# don't generate parentheses in other operators if unnecessary,
# generate parentheses in relational binary operators for clarity,
# warn when not using predefined-types for locals, parameters, and members,
# generate predefined-types of type names for member access,
# generate auto properties,
# suggest compound assignment,
# generate conditional expression over assignment,
# generate conditional expression over return,
# suggest inferred anonymous types,
# suggest inferred tuple names,
# suggest 'is null' checks over '== null',
# don't generate 'this.' and 'Me.' for events,
# warn when not using 'this.' and 'Me.' for fields,
# warn when not using 'this.' and 'Me.' for methods,
# warn when not using 'this.' and 'Me.' for properties,
# suggest readonly fields, and
# generate accessibility modifiers for non interface members
###############################################################################
[*.cs]
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_collection_initializer = true:suggestion
dotnet_style_explicit_tuple_names = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_object_initializer = true:suggestion
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent
dotnet_style_predefined_type_for_locals_parameters_members = true:warning
dotnet_style_predefined_type_for_member_access = true:silent
dotnet_style_prefer_auto_properties = true:silent
dotnet_style_prefer_compound_assignment = true:suggestion
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
dotnet_style_prefer_conditional_expression_over_return = true:silent
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
dotnet_style_prefer_inferred_tuple_names = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
dotnet_style_qualification_for_event = false:silent
dotnet_style_qualification_for_field = true:warning
dotnet_style_qualification_for_method = true:warning
dotnet_style_qualification_for_property = true:warning
dotnet_style_readonly_field = true:suggestion
dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent
###############################################################################
# Set dotnet style options to:
# suggest removing all unused parameters
###############################################################################
[*.cs]
dotnet_code_quality_unused_parameters = all:suggestion
###############################################################################
# Set csharp indent options to:
# indent block contents,
# not indent braces,
# indent case contents,
# not indent case contents when block,
# indent labels one less than the current, and
# indent switch labels
###############################################################################
[*.cs]
csharp_indent_block_contents = true
csharp_indent_braces = false
csharp_indent_case_contents = true
csharp_indent_case_contents_when_block = false
csharp_indent_labels = one_less_than_current
csharp_indent_switch_labels = true
###############################################################################
# Set csharp new-line options to:
# insert a new-line before "catch",
# insert a new-line before "else",
# insert a new-line before "finally",
# insert a new-line before members in anonymous-types,
# insert a new-line before members in object-initializers, and
# insert a new-line before all open braces
###############################################################################
[*.cs]
csharp_new_line_before_catch = true
csharp_new_line_before_else = true
csharp_new_line_before_finally = true
csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_open_brace = all
###############################################################################
# Set csharp preserve options to:
# preserve single-line blocks, and
# preserve single-line statements
###############################################################################
[*.cs]
csharp_preserve_single_line_blocks = true
csharp_preserve_single_line_statements = true
###############################################################################
# Set csharp space options to:
# remove any space after a cast,
# add a space after the colon in an inheritance clause,
# add a space after a comma,
# remove any space after a dot,
# add a space after keywords in control flow statements,
# add a space after a semicolon in a "for" statement,
# add a space before and after binary operators,
# remove space around declaration statements,
# add a space before the colon in an inheritance clause,
# remove any space before a comma,
# remove any space before a dot,
# remove any space before an open square-bracket,
# remove any space before a semicolon in a "for" statement,
# remove any space between empty square-brackets,
# remove any space between a method call's empty parameter list parenthesis,
# remove any space between a method call's name and its opening parenthesis,
# remove any space between a method call's parameter list parenthesis,
# remove any space between a method declaration's empty parameter list parenthesis,
# remove any space between a method declaration's name and its openening parenthesis,
# remove any space between a method declaration's parameter list parenthesis,
# remove any space between parentheses, and
# remove any space between square brackets
###############################################################################
[*.cs]
csharp_space_after_cast = false
csharp_space_after_colon_in_inheritance_clause = true
csharp_space_after_comma = true
csharp_space_after_dot = false
csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_after_semicolon_in_for_statement = true
csharp_space_around_binary_operators = before_and_after
csharp_space_around_declaration_statements = do_not_ignore
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_before_comma = false
csharp_space_before_dot = false
csharp_space_before_open_square_brackets = false
csharp_space_before_semicolon_in_for_statement = false
csharp_space_between_empty_square_brackets = false
csharp_space_between_method_call_empty_parameter_list_parentheses = false
csharp_space_between_method_call_name_and_opening_parenthesis = false
csharp_space_between_method_call_parameter_list_parentheses = false
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
csharp_space_between_method_declaration_name_and_open_parenthesis = false
csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_parentheses = false
csharp_space_between_square_brackets = false
###############################################################################
# Set csharp style options to:
# generate braces,
# suggest simple default expressions,
# generate a preferred modifier order,
# suggest conditional delegate calls,
# suggest deconstructed variable declarations,
# generate expression-bodied accessors,
# generate expression-bodied constructors,
# generate expression-bodied indexers,
# generate expression-bodied lambdas,
# generate expression-bodied methods,
# generate expression-bodied operators,
# generate expression-bodied properties,
# suggest inlined variable declarations,
# suggest local over anonymous functions,
# suggest pattern-matching over "as" with "null" check,
# suggest pattern-matching over "is" with "cast" check,
# suggest throw expressions,
# generate a discard variable for unused value expression statements,
# suggest a discard variable for unused assignments,
# warn when using var for built-in types,
# warn when using var when the type is not apparent, and
# warn when not using var when the type is apparent
###############################################################################
[*.cs]
csharp_prefer_braces = true:silent
csharp_prefer_simple_default_expression = true:suggestion
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:silent
csharp_style_conditional_delegate_call = true:suggestion
csharp_style_deconstructed_variable_declaration = true:suggestion
csharp_style_expression_bodied_accessors = true:silent
csharp_style_expression_bodied_constructors = true:silent
csharp_style_expression_bodied_indexers = true:silent
csharp_style_expression_bodied_lambdas = true:silent
csharp_style_expression_bodied_methods = true:silent
csharp_style_expression_bodied_operators = true:silent
csharp_style_expression_bodied_properties = true:silent
csharp_style_inlined_variable_declaration = true:suggestion
csharp_style_pattern_local_over_anonymous_function = true:suggestion
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
csharp_style_throw_expression = true:suggestion
csharp_style_unused_value_expression_statement_preference = discard_variable:silent
csharp_style_unused_value_assignment_preference = discard_variable:suggestion
csharp_style_var_for_built_in_types = false:warning
csharp_style_var_elsewhere = false:warning
csharp_style_var_when_type_is_apparent = true:warning

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

@ -0,0 +1,108 @@
###############################################################################
# Set default behavior to:
# treat as text and
# normalize to Unix-style line endings
###############################################################################
* text eol=lf
###############################################################################
# Set explicit file behavior to:
# treat as text and
# normalize to Unix-style line endings
###############################################################################
*.asm text eol=lf
*.c text eol=lf
*.clj text eol=lf
*.cmd text eol=lf
*.cpp text eol=lf
*.css text eol=lf
*.cxx text eol=lf
*.config text eol=lf
*.DotSettings text eol=lf
*.erl text eol=lf
*.fs text eol=lf
*.fsx text eol=lf
*.h text eol=lf
*.htm text eol=lf
*.html text eol=lf
*.hs text eol=lf
*.hxx text eol=lf
*.java text eol=lf
*.js text eol=lf
*.json text eol=lf
*.less text eol=lf
*.lisp text eol=lf
*.lua text eol=lf
*.m text eol=lf
*.md text eol=lf
*.php text eol=lf
*.props text eol=lf
*.ps1 text eol=lf
*.py text eol=lf
*.rb text eol=lf
*.resx text eol=lf
*.runsettings text eol=lf
*.ruleset text eol=lf
*.sass text eol=lf
*.scss text eol=lf
*.sh text eol=lf
*.sql text eol=lf
*.svg text eol=lf
*.targets text eol=lf
*.tt text eol=crlf
*.ttinclude text eol=crlf
*.txt text eol=lf
*.vb text eol=lf
*.yml text eol=lf
###############################################################################
# Set explicit file behavior to:
# treat as text
# normalize to Unix-style line endings and
# diff as csharp
###############################################################################
*.cs text eol=lf diff=csharp
###############################################################################
# Set explicit file behavior to:
# treat as text
# normalize to Unix-style line endings and
# use a union merge when resoling conflicts
###############################################################################
*.csproj text eol=lf merge=union
*.dbproj text eol=lf merge=union
*.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
# normalize to Windows-style line endings and
# use a union merge when resoling conflicts
###############################################################################
*.sln text eol=crlf merge=union
###############################################################################
# Set explicit file behavior to:
# treat as binary
###############################################################################
*.bmp binary
*.dll binary
*.exe binary
*.gif binary
*.jpg binary
*.png binary
*.ttf binary
*.snk binary
###############################################################################
# Set explicit file behavior to:
# diff as plain text
###############################################################################
*.doc diff=astextplain
*.docx diff=astextplain
*.dot diff=astextplain
*.pdf diff=astextplain
*.pptx diff=astextplain
*.rtf diff=astextplain

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

@ -0,0 +1,3 @@
[submodule "shared-infrastructure"]
path = shared-infrastructure
url = https://github.com/SixLabors/SharedInfrastructure

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

@ -1,17 +1,18 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26430.6
# Visual Studio Version 16
VisualStudioVersion = 16.0.29215.179
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SolutionItems", "SolutionItems", "{C317F1B1-D75E-4C6D-83EB-80367343E0D7}"
ProjectSection(SolutionItems) = preProject
standards\.editorconfig = standards\.editorconfig
shared-infrastructure\.editorconfig = shared-infrastructure\.editorconfig
appveyor.yml = appveyor.yml
build.cmd = build.cmd
NuGet.config = NuGet.config
README.md = README.md
standards\SixLabors.ruleset = standards\SixLabors.ruleset
standards\stylecop.json = standards\stylecop.json
shared-infrastructure\SixLabors.ruleset = shared-infrastructure\SixLabors.ruleset
shared-infrastructure\SixLabors.Tests.ruleset = shared-infrastructure\SixLabors.Tests.ruleset
shared-infrastructure\stylecop.json = shared-infrastructure\stylecop.json
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Source", "Source", "{815C0625-CD3D-440F-9F80-2D83856AB7AE}"
@ -21,7 +22,6 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{9E574A07-F879-4811-9C41-5CBDC6BAFDB7}"
ProjectSection(SolutionItems) = preProject
src\Shared\AssemblyInfo.Common.cs = src\Shared\AssemblyInfo.Common.cs
src\Shared\stylecop.json = src\Shared\stylecop.json
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{9F33164A-9EA9-4CB4-A384-A8A0A6DCA35D}"

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

@ -12,7 +12,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-dev002362" />
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-dev002919" />
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
<PackageReference Include="System.Runtime.Numerics" Version="4.3.0" />
</ItemGroup>

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

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Numerics;
using SixLabors.ImageSharp;
@ -12,22 +12,20 @@ namespace SixLabors.Shapes.DrawShapesWithImageSharp
public static void SaveLogo(float size, string path)
{
// the point are based on a 1206x1206 shape so size requires scaling from there
float scalingFactor = size / 1206;
Vector2 center = new Vector2(603);
var center = new Vector2(603);
// segment whoes cetner of rotation should be
Vector2 segmentOffset = new Vector2(301.16968f, 301.16974f);
// segment whose center of rotation should be
var segmentOffset = new Vector2(301.16968f, 301.16974f);
IPath segment = new Polygon(new LinearLineSegment(new Vector2(230.54f, 361.0261f), new System.Numerics.Vector2(5.8641942f, 361.46031f)),
new CubicBezierLineSegment(new Vector2(5.8641942f, 361.46031f),
new Vector2(-11.715693f, 259.54052f),
new Vector2(24.441609f, 158.17478f),
new Vector2(78.26f, 97.0461f))).Translate(center - segmentOffset);
//we need to create 6 of theses all rotated about the center point
List<IPath> segments = new List<IPath>();
// we need to create 6 of theses all rotated about the center point
var segments = new List<IPath>();
for (int i = 0; i < 6; i++)
{
float angle = i * ((float)Math.PI / 3);
@ -35,7 +33,7 @@ namespace SixLabors.Shapes.DrawShapesWithImageSharp
segments.Add(s);
}
List<Rgba32> colors = new List<Rgba32>() {
var colors = new List<Rgba32>() {
Rgba32.FromHex("35a849"),
Rgba32.FromHex("fcee21"),
Rgba32.FromHex("ed7124"),
@ -44,10 +42,10 @@ namespace SixLabors.Shapes.DrawShapesWithImageSharp
Rgba32.FromHex("085ba7"),
};
Matrix3x2 scaler = Matrix3x2.CreateScale(scalingFactor, Vector2.Zero);
var scaler = Matrix3x2.CreateScale(scalingFactor, Vector2.Zero);
int dimensions = (int)Math.Ceiling(size);
using (Image<Rgba32> img = new Image<Rgba32>(dimensions, dimensions))
using (var img = new Image<Rgba32>(dimensions, dimensions))
{
img.Mutate(i => i.Fill(Rgba32.Black));
img.Mutate(i => i.Fill(Rgba32.FromHex("e1e1e1ff"), new EllipsePolygon(center, 600f).Transform(scaler)));

1
shared-infrastructure Submodule

@ -0,0 +1 @@
Subproject commit 9b5a5b70b46bc23b9d8d8645cd691d5bc5a2d84f

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

@ -32,15 +32,15 @@
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\standards\**\*.cs" />
<Compile Include="..\..\shared-infrastructure\**\*.cs" />
</ItemGroup>
<PropertyGroup>
<CodeAnalysisRuleSet>..\..\standards\SixLabors.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRuleSet>..\..\shared-infrastructure\SixLabors.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<AdditionalFiles Include="..\..\standards\stylecop.json" />
<AdditionalFiles Include="..\..\shared-infrastructure\stylecop.json" />
</ItemGroup>
<ItemGroup>

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

@ -32,20 +32,19 @@
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\standards\**\*.cs" />
</ItemGroup>
<ItemGroup>
<AdditionalFiles Include="..\..\standards\stylecop.json" />
<Compile Include="..\..\shared-infrastructure\**\*.cs" />
</ItemGroup>
<PropertyGroup>
<CodeAnalysisRuleSet>..\..\standards\SixLabors.ruleset</CodeAnalysisRuleSet>
<Version>1.0.0</Version>
<CodeAnalysisRuleSet>..\..\shared-infrastructure\SixLabors.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="StyleCop.Analyzers" Version="1.1.1-beta.61" PrivateAssets="All" />
<PackageReference Include="SixLabors.Core" Version="1.0.0-beta0007" />
<AdditionalFiles Include="..\..\shared-infrastructure\stylecop.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="All" />
<PackageReference Include="SixLabors.Core" Version="1.0.0-dev000137" />
</ItemGroup>
</Project>

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

@ -1,9 +0,0 @@
{
"$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
"settings": {
"documentationRules": {
"companyName": "Scott Williams",
"copyrightText": "Copyright (c) Scott Williams and contributors.\nLicensed under the Apache License, Version 2.0."
}
}
}

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

@ -1,20 +1,20 @@
using System;
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Numerics;
using SixLabors.Primitives;
using Xunit;
namespace SixLabors.Shapes.Tests
{
using SixLabors.Primitives;
using System.Numerics;
public class BezierLineSegmentTests
{
[Fact]
public void SingleSegmentConstructor()
{
CubicBezierLineSegment segment = new CubicBezierLineSegment(new Vector2(0, 0), new Vector2(10, 0), new Vector2(10, 0), new Vector2(20, 0));
var segment = new CubicBezierLineSegment(new Vector2(0, 0), new Vector2(10, 0), new Vector2(10, 0), new Vector2(20, 0));
IReadOnlyList<PointF> points = segment.Flatten();
Assert.Contains(new Vector2(0, 0), points);
Assert.Contains(new Vector2(10, 0), points);

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

@ -1,37 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Xunit;
using SixLabors.Primitives;
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Buffers;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Numerics;
using SixLabors.Primitives;
using Xunit;
using Xunit.Abstractions;
// ReSharper disable InconsistentNaming
namespace SixLabors.Shapes.Tests
{
using System.Globalization;
using System.Numerics;
public class ComplexPolygonTests
{
public static readonly TheoryData<int, int, int> CommonOffsetData = new TheoryData<int, int, int>()
{
{0, 0, 0},
{1500, 1500, 0},
{3000, 3000, 0},
{8000, 8000, 0},
{20000, 20000, 0},
{0, 0, 42},
{1500, 1500, 42},
{3000, 3000, 42},
{8000, 8000, 42},
{20000, 20000, 42},
{0, 0, 123},
{1500, 1500, 123},
{3000, 3000, 123},
{8000, 8000, 123},
{20000, 20000, 123},
};
public static readonly TheoryData<int, int, int> CommonOffsetData
= new TheoryData<int, int, int>()
{
{ 0, 0, 0 },
{ 1500, 1500, 0 },
{ 3000, 3000, 0 },
{ 8000, 8000, 0 },
{ 20000, 20000, 0 },
{ 0, 0, 42 },
{ 1500, 1500, 42 },
{ 3000, 3000, 42 },
{ 8000, 8000, 42 },
{ 20000, 20000, 42 },
{ 0, 0, 123 },
{ 1500, 1500, 123 },
{ 3000, 3000, 123 },
{ 8000, 8000, 123 },
{ 20000, 20000, 123 },
};
public ComplexPolygonTests(ITestOutputHelper output)
{
@ -39,17 +41,17 @@ namespace SixLabors.Shapes.Tests
}
private ITestOutputHelper Output { get; }
[Fact]
public void MissingIntersection()
{
float[] data = new float[6];
Polygon simplePath = new Polygon(new LinearLineSegment(
var simplePath = new Polygon(new LinearLineSegment(
new PointF(10, 10),
new PointF(200, 150),
new PointF(50, 300)));
Polygon hole1 = new Polygon(new LinearLineSegment(
var hole1 = new Polygon(new LinearLineSegment(
new PointF(65, 137),
new PointF(37, 85),
new PointF(93, 85)));
@ -66,8 +68,8 @@ namespace SixLabors.Shapes.Tests
public int ScanY(IPath shape, float y, float[] buffer, int length, int offset)
{
PointF start = new PointF(shape.Bounds.Left - 1, y);
PointF end = new PointF(shape.Bounds.Right + 1, y);
var start = new PointF(shape.Bounds.Left - 1, y);
var end = new PointF(shape.Bounds.Right + 1, y);
PointF[] innerbuffer = ArrayPool<PointF>.Shared.Rent(length);
try
{
@ -90,58 +92,61 @@ namespace SixLabors.Shapes.Tests
[MemberData(nameof(CommonOffsetData))]
public void MissingIntersectionsOpenSans_a(int dx, int dy, int noiseSeed)
{
string path = @"36.57813x49.16406 35.41797x43.67969 35.41797x43.67969 35.13672x43.67969 35.13672x43.67969 34.41629x44.54843 33.69641x45.34412 32.97708x46.06674 32.2583x46.71631 31.54007x47.29282 30.82239x47.79626 30.10526x48.22665 29.38867x48.58398 29.38867x48.58398 28.65012x48.88474 27.86707x49.14539 27.03952x49.36594 26.16748x49.54639 25.25095x49.68674 24.28992x49.78699 23.28439x49.84714 22.23438x49.86719 22.23438x49.86719 21.52775x49.85564 20.84048x49.82104 20.17258x49.76337 19.52405x49.68262 18.28506x49.4519 17.12354x49.12891 16.03946x48.71362 15.03284x48.20605 14.10367x47.6062 13.25195x46.91406 13.25195x46.91406 12.48978x46.13678 11.82922x45.28149 11.27029x44.34821 10.81299x43.33691 10.45731x42.24762 10.20325x41.08032 10.05081x39.83502 10.0127x39.18312 10x38.51172 10x38.51172 10.01823x37.79307 10.07292x37.09613 10.16407x36.42088 10.29169x35.76733 10.6563x34.52533 11.16675x33.37012 11.82304x32.3017 12.62518x31.32007 13.57317x30.42523 14.10185x30.01036 14.66699x29.61719 15.2686x29.24571 15.90666x28.89594 16.58119x28.56786 17.29218x28.26147 18.03962x27.97679 18.82353x27.71381 19.6439x27.47252 20.50073x27.25293 22.32378x26.87885 24.29266x26.59155 26.40739x26.39105 28.66797x26.27734 28.66797x26.27734 35.20703x26.06641 35.20703x26.06641 35.20703x23.67578 35.20703x23.67578 35.17654x22.57907 35.08508x21.55652 34.93265x20.60812 34.71924x19.73389 34.44485x18.93381 34.1095x18.20789 33.71317x17.55612 33.25586x16.97852 33.25586x16.97852 32.73154x16.47177 32.13416x16.03259 31.46371x15.66098 30.72021x15.35693 29.90366x15.12045 29.01404x14.95154 28.05136x14.85019 27.01563x14.81641 27.01563x14.81641 25.79175x14.86255 24.52832x15.00098 23.88177x15.1048 23.22534x15.23169 21.88281x15.55469 20.50073x15.96997 19.0791x16.47754 17.61792x17.07739 16.11719x17.76953 16.11719x17.76953 14.32422x13.30469 14.32422x13.30469 15.04465x12.92841 15.7821x12.573 17.30811x11.9248 18.90222x11.36011 20.56445x10.87891 20.56445x10.87891 22.26184x10.49438 23.96143x10.21973 24.81204x10.1236 25.66321x10.05493 26.51492x10.01373 27.36719x10 27.36719x10 29.03409x10.04779 29.82572x10.10753 30.58948x10.19116 31.32536x10.29869 32.03336x10.43011 32.71348x10.58543 33.36572x10.76465 34.58658x11.19476 35.69592x11.72046 36.69376x12.34174 37.58008x13.05859 37.58008x13.05859 38.35873x13.88092 39.03357x14.8186 39.60458x15.87164 40.07178x17.04004 40.26644x17.6675 40.43515x18.32379 40.5779x19.00893 40.6947x19.7229 40.78555x20.46571 40.85043x21.23737 40.88937x22.03786 40.90234x22.86719 40.90234x22.86719 40.90234x49.16406
const string Path = @"36.57813x49.16406 35.41797x43.67969 35.41797x43.67969 35.13672x43.67969 35.13672x43.67969 34.41629x44.54843 33.69641x45.34412 32.97708x46.06674 32.2583x46.71631 31.54007x47.29282 30.82239x47.79626 30.10526x48.22665 29.38867x48.58398 29.38867x48.58398 28.65012x48.88474 27.86707x49.14539 27.03952x49.36594 26.16748x49.54639 25.25095x49.68674 24.28992x49.78699 23.28439x49.84714 22.23438x49.86719 22.23438x49.86719 21.52775x49.85564 20.84048x49.82104 20.17258x49.76337 19.52405x49.68262 18.28506x49.4519 17.12354x49.12891 16.03946x48.71362 15.03284x48.20605 14.10367x47.6062 13.25195x46.91406 13.25195x46.91406 12.48978x46.13678 11.82922x45.28149 11.27029x44.34821 10.81299x43.33691 10.45731x42.24762 10.20325x41.08032 10.05081x39.83502 10.0127x39.18312 10x38.51172 10x38.51172 10.01823x37.79307 10.07292x37.09613 10.16407x36.42088 10.29169x35.76733 10.6563x34.52533 11.16675x33.37012 11.82304x32.3017 12.62518x31.32007 13.57317x30.42523 14.10185x30.01036 14.66699x29.61719 15.2686x29.24571 15.90666x28.89594 16.58119x28.56786 17.29218x28.26147 18.03962x27.97679 18.82353x27.71381 19.6439x27.47252 20.50073x27.25293 22.32378x26.87885 24.29266x26.59155 26.40739x26.39105 28.66797x26.27734 28.66797x26.27734 35.20703x26.06641 35.20703x26.06641 35.20703x23.67578 35.20703x23.67578 35.17654x22.57907 35.08508x21.55652 34.93265x20.60812 34.71924x19.73389 34.44485x18.93381 34.1095x18.20789 33.71317x17.55612 33.25586x16.97852 33.25586x16.97852 32.73154x16.47177 32.13416x16.03259 31.46371x15.66098 30.72021x15.35693 29.90366x15.12045 29.01404x14.95154 28.05136x14.85019 27.01563x14.81641 27.01563x14.81641 25.79175x14.86255 24.52832x15.00098 23.88177x15.1048 23.22534x15.23169 21.88281x15.55469 20.50073x15.96997 19.0791x16.47754 17.61792x17.07739 16.11719x17.76953 16.11719x17.76953 14.32422x13.30469 14.32422x13.30469 15.04465x12.92841 15.7821x12.573 17.30811x11.9248 18.90222x11.36011 20.56445x10.87891 20.56445x10.87891 22.26184x10.49438 23.96143x10.21973 24.81204x10.1236 25.66321x10.05493 26.51492x10.01373 27.36719x10 27.36719x10 29.03409x10.04779 29.82572x10.10753 30.58948x10.19116 31.32536x10.29869 32.03336x10.43011 32.71348x10.58543 33.36572x10.76465 34.58658x11.19476 35.69592x11.72046 36.69376x12.34174 37.58008x13.05859 37.58008x13.05859 38.35873x13.88092 39.03357x14.8186 39.60458x15.87164 40.07178x17.04004 40.26644x17.6675 40.43515x18.32379 40.5779x19.00893 40.6947x19.7229 40.78555x20.46571 40.85043x21.23737 40.88937x22.03786 40.90234x22.86719 40.90234x22.86719 40.90234x49.16406
23.39453x45.05078 24.06655x45.03911 24.72031x45.00409 25.97302x44.86401 27.15268x44.63055 28.25928x44.30371 29.29282x43.88348 30.2533x43.36987 31.14072x42.76288 31.95508x42.0625 31.95508x42.0625 32.6843x41.27808 33.31628x40.41895 33.85104x39.48511 34.28857x38.47656 34.62888x37.39331 34.87195x36.23535 35.01779x35.00269 35.06641x33.69531 35.06641x33.69531 35.06641x30.21484 35.06641x30.21484 29.23047x30.46094 29.23047x30.46094 27.55093x30.54855 25.9928x30.68835 24.55606x30.88034 23.24072x31.12451 22.04678x31.42087 20.97424x31.76941 20.0231x32.17014 19.19336x32.62305 19.19336x32.62305 18.47238x33.13528 17.84753x33.71399 17.31882x34.35916 16.88623x35.0708 16.54977x35.84891 16.30945x36.69348 16.16525x37.60452 16.11719x38.58203 16.11719x38.58203 16.14713x39.34943 16.23694x40.06958 16.38663x40.74249 16.59619x41.36816 17.19495x42.47778 18.0332x43.39844 18.0332x43.39844 19.08679x44.12134 19.68527x44.40533 20.33154x44.6377 21.0256x44.81842 21.76746x44.94751 22.5571x45.02496 23.39453x45.05078";
Vector2 offset = MakeOffsetVector(dx, dy, noiseSeed);
this.TestMissingFontIntersectionCore(offset, path, 10,
(intersections, data) =>
{
Assert.True(intersections % 2 == 0, $"even number of intersections expected but found {intersections}");
});
this.TestMissingFontIntersectionCore(
offset,
Path,
10,
(intersections, _)
=> Assert.True(intersections % 2 == 0, $"even number of intersections expected but found {intersections}"));
}
[Theory]
[MemberData(nameof(CommonOffsetData))]
public void MissingIntersectionsOpenSans_o(int dx, int dy, int noiseSeed)
{
string path = @"45.40234x29.93359 45.3838x31.09519 45.32819x32.22452 45.23549x33.32157 45.10571x34.38635 44.93886x35.41886 44.73492x36.4191 44.49391x37.38706 44.21582x38.32275 43.90065x39.22617 43.5484x40.09732 43.15907x40.9362 42.73267x41.7428 42.26918x42.51713 41.76862x43.25919 41.23097x43.96897 40.65625x44.64648 40.65625x44.64648 40.04884x45.28719 39.41315x45.88657 38.74916x46.4446 38.05688x46.9613 37.33632x47.43667 36.58746x47.8707 35.81032x48.26339 35.00488x48.61475 34.17116x48.92477 33.30914x49.19345 32.41884x49.4208 31.50024x49.60681 30.55336x49.75149 29.57819x49.85483 28.57472x49.91683 27.54297x49.9375 27.54297x49.9375 26.2691x49.8996 25.03149x49.78589 23.83014x49.59637 22.66504x49.33105 21.53619x48.98993 20.4436x48.573 19.38727x48.08026 18.36719x47.51172 18.36719x47.51172 17.3938x46.87231 16.47754x46.16699 15.61841x45.39575 14.81641x44.55859 14.07153x43.65552 13.38379x42.68652 12.75317x41.65161 12.17969x40.55078 12.17969x40.55078 11.66882x39.39282 11.22607x38.18652 10.85144x36.93188 10.54492x35.62891 10.30652x34.27759 10.13623x32.87793 10.03406x31.42993 10x29.93359 10x29.93359 10.0184x28.77213 10.07361x27.64322 10.16562x26.54685 10.29443x25.48303 10.46005x24.45176 10.66248x23.45303 10.9017x22.48685 11.17773x21.55322 11.49057x20.65214 11.84021x19.7836 12.22665x18.94761 12.6499x18.14417 13.10995x17.37327 13.60681x16.63492 14.14047x15.92912 14.71094x15.25586 14.71094x15.25586 15.31409x14.61941 15.9458x14.02402 16.60608x13.46969 17.29492x12.95642 18.01233x12.48421 18.7583x12.05307 19.53284x11.66299 20.33594x11.31396 21.1676x11.006 22.02783x10.73911 22.91663x10.51327 23.83398x10.32849 24.77991x10.18478 25.75439x10.08212 26.75745x10.02053 27.78906x10 27.78906x10 28.78683x10.02101 29.75864x10.08405 30.70449x10.1891 31.62439x10.33618 32.51833x10.52528 33.38632x10.75641 34.22836x11.02956 35.04443x11.34473 35.83456x11.70192 36.59872x12.10114 37.33694x12.54237 38.04919x13.02563 38.7355x13.55092 39.39584x14.11823 40.03024x14.72755 40.63867x15.37891 40.63867x15.37891 41.21552x16.0661 41.75516x16.78296 42.25757x17.52948 42.72278x18.30566 43.15077x19.11151 43.54153x19.94702 43.89509x20.81219 44.21143x21.70703 44.49055x22.63153 44.73245x23.58569 44.93714x24.56952 45.10461x25.58301 45.23487x26.62616 45.32791x27.69897 45.38374x28.80145 45.40234x29.93359
const string Path = @"45.40234x29.93359 45.3838x31.09519 45.32819x32.22452 45.23549x33.32157 45.10571x34.38635 44.93886x35.41886 44.73492x36.4191 44.49391x37.38706 44.21582x38.32275 43.90065x39.22617 43.5484x40.09732 43.15907x40.9362 42.73267x41.7428 42.26918x42.51713 41.76862x43.25919 41.23097x43.96897 40.65625x44.64648 40.65625x44.64648 40.04884x45.28719 39.41315x45.88657 38.74916x46.4446 38.05688x46.9613 37.33632x47.43667 36.58746x47.8707 35.81032x48.26339 35.00488x48.61475 34.17116x48.92477 33.30914x49.19345 32.41884x49.4208 31.50024x49.60681 30.55336x49.75149 29.57819x49.85483 28.57472x49.91683 27.54297x49.9375 27.54297x49.9375 26.2691x49.8996 25.03149x49.78589 23.83014x49.59637 22.66504x49.33105 21.53619x48.98993 20.4436x48.573 19.38727x48.08026 18.36719x47.51172 18.36719x47.51172 17.3938x46.87231 16.47754x46.16699 15.61841x45.39575 14.81641x44.55859 14.07153x43.65552 13.38379x42.68652 12.75317x41.65161 12.17969x40.55078 12.17969x40.55078 11.66882x39.39282 11.22607x38.18652 10.85144x36.93188 10.54492x35.62891 10.30652x34.27759 10.13623x32.87793 10.03406x31.42993 10x29.93359 10x29.93359 10.0184x28.77213 10.07361x27.64322 10.16562x26.54685 10.29443x25.48303 10.46005x24.45176 10.66248x23.45303 10.9017x22.48685 11.17773x21.55322 11.49057x20.65214 11.84021x19.7836 12.22665x18.94761 12.6499x18.14417 13.10995x17.37327 13.60681x16.63492 14.14047x15.92912 14.71094x15.25586 14.71094x15.25586 15.31409x14.61941 15.9458x14.02402 16.60608x13.46969 17.29492x12.95642 18.01233x12.48421 18.7583x12.05307 19.53284x11.66299 20.33594x11.31396 21.1676x11.006 22.02783x10.73911 22.91663x10.51327 23.83398x10.32849 24.77991x10.18478 25.75439x10.08212 26.75745x10.02053 27.78906x10 27.78906x10 28.78683x10.02101 29.75864x10.08405 30.70449x10.1891 31.62439x10.33618 32.51833x10.52528 33.38632x10.75641 34.22836x11.02956 35.04443x11.34473 35.83456x11.70192 36.59872x12.10114 37.33694x12.54237 38.04919x13.02563 38.7355x13.55092 39.39584x14.11823 40.03024x14.72755 40.63867x15.37891 40.63867x15.37891 41.21552x16.0661 41.75516x16.78296 42.25757x17.52948 42.72278x18.30566 43.15077x19.11151 43.54153x19.94702 43.89509x20.81219 44.21143x21.70703 44.49055x22.63153 44.73245x23.58569 44.93714x24.56952 45.10461x25.58301 45.23487x26.62616 45.32791x27.69897 45.38374x28.80145 45.40234x29.93359
16.04688x29.93359 16.09302x31.72437 16.23145x33.40527 16.33527x34.20453 16.46216x34.97632 16.61212x35.72064 16.78516x36.4375 16.98126x37.12689 17.20044x37.78882 17.44269x38.42328 17.70801x39.03027 18.30786x40.16187 19x41.18359 19x41.18359 19.78168x42.08997 20.65015x42.87549 21.60541x43.54016 22.64746x44.08398 23.77631x44.50696 24.99194x44.80908 26.29437x44.99036 26.97813x45.03568 27.68359x45.05078 27.68359x45.05078 28.38912x45.03575 29.07309x44.99063 30.37634x44.81018 31.59335x44.50943 32.72412x44.08838 33.76865x43.54703 34.72693x42.88538 35.59897x42.10342 36.38477x41.20117 36.38477x41.20117 37.08102x40.18301 37.68445x39.05334 37.95135x38.44669 38.19504x37.81216 38.41552x37.14976 38.61279x36.45947 38.78686x35.74131 38.93771x34.99527 39.06536x34.22135 39.1698x33.41956 39.30905x31.73233 39.35547x29.93359 39.35547x29.93359 39.30905x28.15189 39.1698x26.48059 39.06536x25.68635 38.93771x24.91971 38.78686x24.18067 38.61279x23.46924 38.41552x22.78541 38.19504x22.12918 37.95135x21.50056 37.68445x20.89954 37.08102x19.7803 36.38477x18.77148 36.38477x18.77148 35.59787x17.87747 34.72253x17.10266 33.75876x16.44705 32.70654x15.91064 31.56589x15.49344 30.33679x15.19543 29.68908x15.09113 29.01926x15.01663 28.32732x14.97193 27.61328x14.95703 27.61328x14.95703 26.90796x14.97173 26.22461x15.01581 24.92383x15.19214 23.71094x15.48602 22.58594x15.89746 21.54883x16.42645 20.59961x17.073 19.73828x17.8371 18.96484x18.71875 18.96484x18.71875 18.28094x19.71686 17.68823x20.83032 17.42607x21.43031 17.18671x22.05914 16.97014x22.71681 16.77637x23.40332 16.60539x24.11867 16.45721x24.86285 16.33183x25.63588 16.22925x26.43774 16.09247x28.12799 16.04688x29.93359 ";
Vector2 offset = MakeOffsetVector(dx, dy, noiseSeed);
this.TestMissingFontIntersectionCore(offset, path, 30,
this.TestMissingFontIntersectionCore(
offset,
Path,
30,
(intersections, data) =>
{
float expectedMinX = 28f + offset.X;
Assert.True(data[1] < expectedMinX, $"second intersection should be > {expectedMinX} but was {data[1]}");
Assert.True(intersections % 2 == 0, $"even number of intersections expected but found {intersections}");
});
{
float expectedMinX = 28f + offset.X;
Assert.True(data[1] < expectedMinX, $"second intersection should be > {expectedMinX} but was {data[1]}");
Assert.True(intersections % 2 == 0, $"even number of intersections expected but found {intersections}");
});
}
private void TestMissingFontIntersectionCore(Vector2 offset, string path, int scanStartY, Action<int, float[]> validateIntersections)
{
string[] paths = path.Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
Polygon[] polys = paths.Select(line => {
string[] pl = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
Polygon[] polys = paths.Select(line =>
{
string[] pl = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
PointF[] points = pl.Select(p => p.Split('x'))
.Select(p =>
{
float x = float.Parse(p[0], CultureInfo.InvariantCulture);
float y = float.Parse(p[1], CultureInfo.InvariantCulture);
PointF pt = new Vector2(x, y) + offset;
return pt;
})
.ToArray();
return new Polygon(new LinearLineSegment(points));
}).ToArray();
PointF[] points = pl.Select(p => p.Split('x'))
.Select(p =>
{
float x = float.Parse(p[0], CultureInfo.InvariantCulture);
float y = float.Parse(p[1], CultureInfo.InvariantCulture);
return (PointF)(new Vector2(x, y) + offset);
})
.ToArray();
ComplexPolygon complex = new ComplexPolygon(polys);
return new Polygon(new LinearLineSegment(points));
}).ToArray();
var complex = new ComplexPolygon(polys);
float[] data = new float[complex.MaxIntersections];
int intersections = this.ScanY(complex, scanStartY + offset.Y, data, complex.MaxIntersections, 0);
@ -149,10 +154,8 @@ namespace SixLabors.Shapes.Tests
validateIntersections(intersections, data);
}
/// <summary>
/// Test is based on @woutware's the idea and drawing logic in opening comment:
/// https://github.com/SixLabors/Shapes/pull/43#issue-189141926
/// </summary>
// Test is based on @woutware's the idea and drawing logic in opening comment:
// https://github.com/SixLabors/Shapes/pull/43#issue-189141926
[Theory]
[InlineData(100, 100, 10, 3)]
[InlineData(800, 600, 8, 2)]
@ -160,23 +163,23 @@ namespace SixLabors.Shapes.Tests
[InlineData(4000, 4000, 8, 2)]
public void SmallRingAtLargeCoords_HorizontalScansShouldFind4IntersectionPoints(int w, int h, int r, int thickness)
{
int cx = w - 2 * r;
int cy = h - 2 * 3;
int cx = w - (2 * r);
int cy = h - (2 * 3);
EllipsePolygon ellipse = new EllipsePolygon(cx, cy, r);
var ellipse = new EllipsePolygon(cx, cy, r);
IPath path = ellipse.GenerateOutline(thickness);
int yMin = cy - r + thickness + 1;
int yMax = cy + r - thickness;
PointF[] buffer = new PointF[16];
var buffer = new PointF[16];
List<int> badPositions = new List<int>();
var badPositions = new List<int>();
for (int y = yMin; y < yMax; y++)
{
PointF start = new PointF(-1, y);
PointF end = new PointF(w + 1, y);
var start = new PointF(-1, y);
var end = new PointF(w + 1, y);
int intersectionCount = path.FindIntersections(start, end, buffer);
if (intersectionCount != 4)
@ -185,7 +188,7 @@ namespace SixLabors.Shapes.Tests
}
}
if (badPositions.Any())
if (badPositions.Count > 0)
{
string badPoz = string.Join(',', badPositions);
this.Output.WriteLine($"BAD: {badPositions.Count} of {yMax - yMin}: {badPoz}");
@ -194,23 +197,21 @@ namespace SixLabors.Shapes.Tests
}
}
/// <summary>
/// Test is based on @woutware's the idea in another issue comment:
/// https://github.com/SixLabors/Shapes/pull/43#issuecomment-390358702
/// </summary>
// Test is based on @woutware's the idea in another issue comment:
// https://github.com/SixLabors/Shapes/pull/43#issuecomment-390358702
[Theory]
[MemberData(nameof(CommonOffsetData))]
public void OffsetingIntersectingSegments_ShouldPreserveIntersection(int dx, int dy, int noiseSeed)
{
Vector2 offset = MakeOffsetVector(dx, dy, noiseSeed);
PointF a = new Vector2(21.904f, 78.48f) + offset;
PointF b = new Vector2(22.026f, 79.8f) + offset;
PointF c = new Vector2(48f, 78.5f) + offset;
PointF d = new Vector2(20f, 78.5f) + offset;
Path path = new Path(new LinearLineSegment(a, b));
var path = new Path(new LinearLineSegment(a, b));
int count = path.FindIntersections(c, d, new PointF[1]);
Assert.Equal(1, count);
@ -218,12 +219,12 @@ namespace SixLabors.Shapes.Tests
private static Vector2 MakeOffsetVector(int dx, int dy, int noiseSeed)
{
Vector2 offset = new Vector2(dx, dy);
var offset = new Vector2(dx, dy);
// Let's randomize the input data, while still keeping the test reproducible
if (noiseSeed > 0)
{
Random rnd = new Random(noiseSeed);
var rnd = new Random(noiseSeed);
offset.X += (float)rnd.NextDouble();
offset.Y += (float)rnd.NextDouble();
}

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

@ -1,14 +1,14 @@
using System;
using System.Collections.Generic;
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Linq;
using System.Threading.Tasks;
using System.Numerics;
using SixLabors.Primitives;
using Xunit;
namespace SixLabors.Shapes.Tests
{
using SixLabors.Primitives;
using System.Numerics;
public class EllipseTests
{
[Theory]
@ -20,13 +20,13 @@ namespace SixLabors.Shapes.Tests
{
if (throws)
{
ArgumentOutOfRangeException ex = Assert.Throws<ArgumentOutOfRangeException>(() => new EllipsePolygon(0,0, width, 99));
ArgumentOutOfRangeException ex = Assert.Throws<ArgumentOutOfRangeException>(() => new EllipsePolygon(0, 0, width, 99));
Assert.Equal("width", ex.ParamName);
}
else
{
EllipsePolygon p = new EllipsePolygon(0, 0, width, 99);
var p = new EllipsePolygon(0, 0, width, 99);
Assert.NotNull(p);
}
}
@ -40,13 +40,13 @@ namespace SixLabors.Shapes.Tests
{
if (throws)
{
ArgumentOutOfRangeException ex = Assert.Throws<ArgumentOutOfRangeException>(() => new EllipsePolygon(0,0,99, height));
ArgumentOutOfRangeException ex = Assert.Throws<ArgumentOutOfRangeException>(() => new EllipsePolygon(0, 0, 99, height));
Assert.Equal("height", ex.ParamName);
}
else
{
EllipsePolygon p = new EllipsePolygon(0, 0, 99, height);
var p = new EllipsePolygon(0, 0, 99, height);
Assert.NotNull(p);
}
}
@ -54,7 +54,7 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void ClippingCornerShouldReturn2Points()
{
EllipsePolygon poly = new EllipsePolygon(50, 50, 30, 50);
var poly = new EllipsePolygon(50, 50, 30, 50);
PointF[] points = poly.FindIntersections(new Vector2(0, 75), new Vector2(100, 75)).ToArray();
Assert.Equal(2, points.Length);
@ -63,7 +63,7 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void AcrossEllipsShouldReturn2()
{
EllipsePolygon poly = new EllipsePolygon(50, 50, 30, 50);
var poly = new EllipsePolygon(50, 50, 30, 50);
PointF[] points = poly.FindIntersections(new Vector2(0, 49), new Vector2(100, 49)).ToArray();
Assert.Equal(2, points.Length);
@ -80,7 +80,5 @@ namespace SixLabors.Shapes.Tests
Assert.Equal(2, points.Length);
}
}
}

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

@ -1,15 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace SixLabors.Shapes.Tests
{
public static class Extensions
{
public static IPath AsPath(this RectangularPolygon rect)
{
return ((IPath)rect);
}
}
}

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

@ -1,19 +1,21 @@
using SixLabors.Primitives;
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Threading.Tasks;
using SixLabors.Primitives;
using Xunit;
namespace SixLabors.Shapes.Tests
{
public class GeneralClosedPolygonIntersectionTests
{
static Dictionary<string, IPath> shapes = new Dictionary<string, IPath> {
{"ellispeWithHole", new ComplexPolygon(new SixLabors.Shapes.EllipsePolygon(new Vector2(603), 161f), new SixLabors.Shapes.EllipsePolygon(new Vector2(603), 61f)) },
{ "largeEllipse", new SixLabors.Shapes.EllipsePolygon(new Vector2(603), 603f-60) },
private static readonly Dictionary<string, IPath> ShapesData = new Dictionary<string, IPath>
{
{ "ellispeWithHole", new ComplexPolygon(new EllipsePolygon(new Vector2(603), 161f), new EllipsePolygon(new Vector2(603), 61f)) },
{ "largeEllipse", new EllipsePolygon(new Vector2(603), 603f - 60) },
{ "iris_0", Shapes.IrisSegment(0) },
{ "iris_1", Shapes.IrisSegment(1) },
{ "iris_2", Shapes.IrisSegment(2) },
@ -21,7 +23,6 @@ namespace SixLabors.Shapes.Tests
{ "iris_4", Shapes.IrisSegment(4) },
{ "iris_5", Shapes.IrisSegment(5) },
{ "iris_6", Shapes.IrisSegment(6) },
{ "scaled_300_iris_0", Shapes.IrisSegment(300, 0) },
{ "scaled_300_iris_1", Shapes.IrisSegment(300, 1) },
{ "scaled_300_iris_2", Shapes.IrisSegment(300, 2) },
@ -29,20 +30,22 @@ namespace SixLabors.Shapes.Tests
{ "scaled_300_iris_4", Shapes.IrisSegment(300, 4) },
{ "scaled_300_iris_5", Shapes.IrisSegment(300, 5) },
{ "scaled_300_iris_6", Shapes.IrisSegment(300, 6) },
{ "clippedRect", new RectangularPolygon(10, 10, 40, 40).Clip(new RectangularPolygon(20, 0, 20, 20)) },
{ "clippedRect", new RectangularPolygon(10, 10, 40, 40).Clip(new RectangularPolygon(20, 0, 20, 20)) },
{ "hourGlass", Shapes.HourGlass().AsClosedPath() },
{ "BigCurve", new Polygon(new CubicBezierLineSegment( new Vector2(10, 400), new Vector2(30, 10), new Vector2(240, 30), new Vector2(300, 400))) },
{ "ChopCorner", new Polygon(new LinearLineSegment(new Vector2( 8, 8 ),
new Vector2( 64, 8 ),
new Vector2( 64, 64 ),
new Vector2( 120, 64 ),
new Vector2( 120, 120 ),
new Vector2( 8, 120 ) )) }
{ "BigCurve", new Polygon(new CubicBezierLineSegment(new Vector2(10, 400), new Vector2(30, 10), new Vector2(240, 30), new Vector2(300, 400))) },
{
"ChopCorner", new Polygon(new LinearLineSegment(
new Vector2(8, 8),
new Vector2(64, 8),
new Vector2(64, 64),
new Vector2(120, 64),
new Vector2(120, 120),
new Vector2(8, 120)))
}
};
public static TheoryData<string> polygonsTheoryData = new TheoryData<string> {
public static TheoryData<string> PolygonsTheoryData = new TheoryData<string>
{
{ "ellispeWithHole" },
{ "largeEllipse" },
{ "iris_0" },
@ -52,7 +55,6 @@ namespace SixLabors.Shapes.Tests
{ "iris_4" },
{ "iris_5" },
{ "iris_6" },
{ "scaled_300_iris_0" },
{ "scaled_300_iris_1" },
{ "scaled_300_iris_2" },
@ -60,18 +62,16 @@ namespace SixLabors.Shapes.Tests
{ "scaled_300_iris_4" },
{ "scaled_300_iris_5" },
{ "scaled_300_iris_6" },
{ "clippedRect" },
{ "hourGlass" },
{ "ChopCorner"},
{ "ChopCorner" },
};
[Theory]
[MemberData(nameof(polygonsTheoryData))]
[MemberData(nameof(PolygonsTheoryData))]
public void ShapeMissingEdgeHits(string name)
{
IPath polygon = shapes[name];
IPath polygon = ShapesData[name];
int top = (int)Math.Ceiling(polygon.Bounds.Top);
int bottom = (int)Math.Floor(polygon.Bounds.Bottom);
@ -85,7 +85,7 @@ namespace SixLabors.Shapes.Tests
}
}
public static TheoryData<string, int> specificErrors = new TheoryData<string, int>
public static TheoryData<string, int> SpecificErrors = new TheoryData<string, int>
{
{ "ellispeWithHole", 603 },
{ "ellispeWithHole", 442 },
@ -93,20 +93,19 @@ namespace SixLabors.Shapes.Tests
{ "iris_2", 512 },
{ "scaled_300_iris_3", 135 },
{ "scaled_300_iris_0", 165 },
{ "clippedRect", 20},
{ "clippedRect", 10},
{ "clippedRect", 20 },
{ "clippedRect", 10 },
{ "hourGlass", 25 },
{ "hourGlass", 175 },
{ "BigCurve", 115},
{ "ChopCorner", 64},
{ "BigCurve", 115 },
{ "ChopCorner", 64 },
};
[Theory]
[MemberData(nameof(specificErrors))]
[MemberData(nameof(SpecificErrors))]
public void SpecificMisses(string name, int yScanLine)
{
IPath polygon = shapes[name];
IPath polygon = ShapesData[name];
int intersections = polygon.FindIntersections(new Vector2(polygon.Bounds.Left - 1, yScanLine), new Vector2(polygon.Bounds.Right + 1, yScanLine)).Count();

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

@ -1,16 +1,13 @@
// <copyright file="PathExtensions.cs" company="Scott Williams">
// Copyright (c) Scott Williams and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
using System.Buffers;
using System.Collections.Generic;
using System.Numerics;
using SixLabors.Primitives;
namespace SixLabors.Shapes
{
using SixLabors.Primitives;
using System.Buffers;
using System.Collections.Generic;
using System.Numerics;
internal static class InternalPathExtensions
{
/// <summary>
@ -21,7 +18,7 @@ namespace SixLabors.Shapes
/// <returns>The points along the line the intersect with the boundaries of the polygon.</returns>
internal static IEnumerable<PointF> FindIntersections(this InternalPath path, Vector2 start, Vector2 end)
{
List<PointF> results = new List<PointF>();
var results = new List<PointF>();
PointF[] buffer = ArrayPool<PointF>.Shared.Rent(path.PointCount);
try
{
@ -38,6 +35,5 @@ namespace SixLabors.Shapes
return results;
}
}
}

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

@ -1,12 +1,13 @@
using Xunit;
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Linq;
using SixLabors.Primitives;
using Xunit;
namespace SixLabors.Shapes.Tests
{
using SixLabors.Primitives;
using System;
using System.Linq;
using System.Numerics;
/// <summary>
/// The internal path tests.
/// </summary>
@ -15,10 +16,10 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void MultipleLineSegmentsSimplePathsAreMerged()
{
LinearLineSegment seg1 = new LinearLineSegment(new PointF(0, 0), new PointF(2, 2));
LinearLineSegment seg2 = new LinearLineSegment(new PointF(4, 4), new PointF(5, 5));
var seg1 = new LinearLineSegment(new PointF(0, 0), new PointF(2, 2));
var seg2 = new LinearLineSegment(new PointF(4, 4), new PointF(5, 5));
InternalPath path = new InternalPath(new ILineSegment[] { seg1, seg2 }, true);
var path = new InternalPath(new ILineSegment[] { seg1, seg2 }, true);
Assert.Contains(new PointF(0, 0), path.Points());
Assert.DoesNotContain(new PointF(2, 2), path.Points());
@ -29,9 +30,9 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void Length_Closed()
{
LinearLineSegment seg1 = new LinearLineSegment(new PointF(0, 0), new PointF(0, 2));
var seg1 = new LinearLineSegment(new PointF(0, 0), new PointF(0, 2));
InternalPath path = new InternalPath(seg1, true);
var path = new InternalPath(seg1, true);
Assert.Equal(4, path.Length);
}
@ -39,9 +40,9 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void Length_Open()
{
LinearLineSegment seg1 = new LinearLineSegment(new PointF(0, 0), new PointF(0, 2));
var seg1 = new LinearLineSegment(new PointF(0, 0), new PointF(0, 2));
InternalPath path = new InternalPath(seg1, false);
var path = new InternalPath(seg1, false);
Assert.Equal(2, path.Length);
}
@ -49,10 +50,10 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void Bounds()
{
LinearLineSegment seg1 = new LinearLineSegment(new PointF(0, 0), new PointF(2, 2));
LinearLineSegment seg2 = new LinearLineSegment(new PointF(4, 4), new PointF(5, 5));
var seg1 = new LinearLineSegment(new PointF(0, 0), new PointF(2, 2));
var seg2 = new LinearLineSegment(new PointF(4, 4), new PointF(5, 5));
InternalPath path = new InternalPath(new ILineSegment[] { seg1, seg2 }, true);
var path = new InternalPath(new ILineSegment[] { seg1, seg2 }, true);
Assert.Equal(0, path.Bounds.Left);
Assert.Equal(5, path.Bounds.Right);
@ -62,8 +63,8 @@ namespace SixLabors.Shapes.Tests
private static InternalPath Create(PointF location, SizeF size, bool closed = true)
{
LinearLineSegment seg1 = new LinearLineSegment(location, location + new PointF(size.Width, 0));
LinearLineSegment seg2 = new LinearLineSegment(location + new PointF(size.Width, size.Height), location + new PointF(0, size.Height));
var seg1 = new LinearLineSegment(location, location + new PointF(size.Width, 0));
var seg2 = new LinearLineSegment(location + new PointF(size.Width, size.Height), location + new PointF(0, size.Height));
return new InternalPath(new ILineSegment[] { seg1, seg2 }, closed);
}
@ -72,17 +73,17 @@ namespace SixLabors.Shapes.Tests
new TheoryData<TestPoint, TestSize, TestPoint, bool>
{
{
new PointF(10,10), // loc
new SizeF(100,100), // size
new PointF(10,10), // test
new PointF(10, 10), // loc
new SizeF(100, 100), // size
new PointF(10, 10), // test
true
}, //corner is inside
{
new PointF(10,10), // loc
new SizeF(100,100), // size
new PointF(9,9), // test
}, // corner is inside
{
new PointF(10, 10), // loc
new SizeF(100, 100), // size
new PointF(9, 9), // test
false
},
},
};
public static TheoryData<TestPoint, float, float> PathDistanceTheoryData =
@ -127,17 +128,17 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void PointInPolygon_OpenPath()
{
LinearLineSegment seg1 = new LinearLineSegment(new PointF(0, 0), new PointF(0, 10), new PointF(10, 10), new PointF(10, 0));
var seg1 = new LinearLineSegment(new PointF(0, 0), new PointF(0, 10), new PointF(10, 10), new PointF(10, 0));
InternalPath p = new InternalPath(seg1, false);
var p = new InternalPath(seg1, false);
Assert.False(p.PointInPolygon(new PointF(5, 5)));
InternalPath p2 = new InternalPath(seg1, true);
var p2 = new InternalPath(seg1, true);
Assert.True(p2.PointInPolygon(new PointF(5, 5f)));
}
const float HalfPi = (float)(Math.PI / 2);
const float Pi = (float)(Math.PI);
private const float HalfPi = (float)(Math.PI / 2);
private const float Pi = (float)Math.PI;
[Theory]
[InlineData(0, 50, 50, Pi)]
@ -178,7 +179,7 @@ namespace SixLabors.Shapes.Tests
public void Intersections_buffer()
{
InternalPath shape = Create(new PointF(0, 0), new Size(10, 10));
PointF[] buffer = new PointF[shape.PointCount];
var buffer = new PointF[shape.PointCount];
int hits = shape.FindIntersections(new PointF(5, -10), new PointF(5, 20), buffer);
Assert.Equal(2, hits);
@ -211,7 +212,7 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void Intersections_Diagonal()
{
InternalPath shape = new InternalPath(new LinearLineSegment(new PointF(0, 0), new PointF(10, 10)), false);
var shape = new InternalPath(new LinearLineSegment(new PointF(0, 0), new PointF(10, 10)), false);
PointF[] buffer = shape.FindIntersections(new PointF(0, 10), new PointF(10, 0)).ToArray();
@ -222,26 +223,28 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void Intersections_Diagonal_NoHit()
{
InternalPath shape = new InternalPath(new LinearLineSegment(new PointF(0, 0), new PointF(4, 4)), false);
var shape = new InternalPath(new LinearLineSegment(new PointF(0, 0), new PointF(4, 4)), false);
PointF[] buffer = shape.FindIntersections(new PointF(0, 10), new PointF(10, 0)).ToArray();
Assert.Empty(buffer);
}
[Fact]
public void Intersections_Diagonal_and_straight_Hit()
{
InternalPath shape = new InternalPath(new LinearLineSegment(new PointF(0, 0), new PointF(4, 4)), false);
var shape = new InternalPath(new LinearLineSegment(new PointF(0, 0), new PointF(4, 4)), false);
PointF[] buffer = shape.FindIntersections(new PointF(3, 10), new PointF(3, 0)).ToArray();
Assert.Single(buffer);
Assert.Equal(new PointF(3, 3), buffer[0]);
}
[Fact]
public void Intersections_Diagonal_and_straight_NoHit()
{
InternalPath shape = new InternalPath(new LinearLineSegment(new PointF(0, 0), new PointF(4, 4)), false);
var shape = new InternalPath(new LinearLineSegment(new PointF(0, 0), new PointF(4, 4)), false);
PointF[] buffer = shape.FindIntersections(new PointF(3, 10), new PointF(3, 3.5f)).ToArray();

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

@ -1,23 +1,23 @@
using SixLabors.Primitives;
using System;
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Text;
using SixLabors.Primitives;
using Xunit;
namespace SixLabors.Shapes.Tests
{
/// <summary>
/// see https://github.com/SixLabors/Shapes/issues/16
/// Also for furter details see https://github.com/SixLabors/Fonts/issues/22
/// Also for furter details see https://github.com/SixLabors/Fonts/issues/22
/// </summary>
public class Issue_16
{
[Fact]
public void IndexOutoufRangeException()
{
InternalPath p = new InternalPath(new PointF[] { new Vector2(0, 0), new Vector2(0.000000001f, 0), new Vector2(0, 0.000000001f) }, true);
var p = new InternalPath(new PointF[] { new Vector2(0, 0), new Vector2(0.000000001f, 0), new Vector2(0, 0.000000001f) }, true);
IEnumerable<PointF> inter = p.FindIntersections(Vector2.One, Vector2.Zero);

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

@ -1,26 +1,28 @@
using SixLabors.Primitives;
using System;
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Text;
using SixLabors.Primitives;
using Xunit;
namespace SixLabors.Shapes.Tests
{
/// <summary>
/// see https://github.com/SixLabors/Shapes/issues/19
/// Also for furter details see https://github.com/SixLabors/Fonts/issues/22
/// Also for furter details see https://github.com/SixLabors/Fonts/issues/22
/// </summary>
public class Issue_19
{
[Fact]
public void LoosingPartOfLineIfSelfIntersects()
{
PointF[] line1 = new PointF[] { new Vector2(117f, 199f), new Vector2(31f, 210f), new Vector2(35f, 191f), new Vector2(117f, 199f), new Vector2(2f, 9f) };
Path path = new Path(new LinearLineSegment(line1));
var line1 = new PointF[] { new Vector2(117f, 199f), new Vector2(31f, 210f), new Vector2(35f, 191f), new Vector2(117f, 199f), new Vector2(2f, 9f) };
var path = new Path(new LinearLineSegment(line1));
IPath outline = path.GenerateOutline(5f);
// all points must not be in the outline;
foreach (PointF v in line1)
{
@ -31,8 +33,8 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void PAthLoosingSelfIntersectingPoint()
{
PointF[] line1 = new PointF[] { new Vector2(117f, 199f), new Vector2(31f, 210f), new Vector2(35f, 191f), new Vector2(117f, 199f), new Vector2(2f, 9f) };
Path path = new Path(new LinearLineSegment(line1));
var line1 = new PointF[] { new Vector2(117f, 199f), new Vector2(31f, 210f), new Vector2(35f, 191f), new Vector2(117f, 199f), new Vector2(2f, 9f) };
var path = new Path(new LinearLineSegment(line1));
IReadOnlyList<PointF> pathPoints = path.Flatten().First().Points;
// all points must not be in the outline;
@ -45,8 +47,8 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void InternalPathLoosingSelfIntersectingPoint()
{
PointF[] line1 = new PointF[] { new Vector2(117f, 199f), new Vector2(31f, 210f), new Vector2(35f, 191f), new Vector2(117f, 199f), new Vector2(2f, 9f) };
InternalPath path = new InternalPath(new LinearLineSegment(line1), false);
var line1 = new PointF[] { new Vector2(117f, 199f), new Vector2(31f, 210f), new Vector2(35f, 191f), new Vector2(117f, 199f), new Vector2(2f, 9f) };
var path = new InternalPath(new LinearLineSegment(line1), false);
IReadOnlyList<PointF> pathPoints = path.Points();
// all points must not be in the outline;

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

@ -1,8 +1,8 @@
using SixLabors.Primitives;
using System;
using System.Collections.Generic;
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System.Linq;
using System.Text;
using SixLabors.Primitives;
using Xunit;
namespace SixLabors.Shapes.Tests.Issues
@ -12,12 +12,12 @@ namespace SixLabors.Shapes.Tests.Issues
[Fact]
public void ClippedTriangle()
{
Polygon simplePath = new Polygon(new LinearLineSegment(
var simplePath = new Polygon(new LinearLineSegment(
new PointF(10, 10),
new PointF(200, 150),
new PointF(50, 300)));
Polygon hole1 = new Polygon(new LinearLineSegment(
var hole1 = new Polygon(new LinearLineSegment(
new PointF(37, 85),
new PointF(93, 85),
new PointF(65, 137)));
@ -31,26 +31,26 @@ namespace SixLabors.Shapes.Tests.Issues
[Fact]
public void ClippedTriangleGapInIntersections()
{
Polygon simplePath = new Polygon(new LinearLineSegment(
var simplePath = new Polygon(new LinearLineSegment(
new PointF(10, 10),
new PointF(200, 150),
new PointF(50, 300)));
Polygon hole1 = new Polygon(new LinearLineSegment(
var hole1 = new Polygon(new LinearLineSegment(
new PointF(37, 85),
new PointF(93, 85),
new PointF(65, 137)));
IPath clippedPath = simplePath.Clip(hole1);
IPath outline = clippedPath.GenerateOutline(5, new[] { 1f });
PointF[] buffer = new PointF[20];
var buffer = new PointF[20];
PointF start = new PointF(outline.Bounds.Left - 1, 102);
PointF end = new PointF(outline.Bounds.Right + 1, 102);
var start = new PointF(outline.Bounds.Left - 1, 102);
var end = new PointF(outline.Bounds.Right + 1, 102);
int matches = outline.FindIntersections(start, end, buffer, 0);
int maxIndex = buffer.Select((x, i) => new { x, i }).Where(x => x.x.X > 0).Select(x=>x.i).Last();
Assert.Equal(matches-1, maxIndex);
int maxIndex = buffer.Select((x, i) => new { x, i }).Where(x => x.x.X > 0).Select(x => x.i).Last();
Assert.Equal(matches - 1, maxIndex);
}
}
}

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

@ -1,20 +1,20 @@
using System;
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Numerics;
using SixLabors.Primitives;
using Xunit;
namespace SixLabors.Shapes.Tests
{
using SixLabors.Primitives;
using System.Numerics;
public class LinearLineSegmentTests
{
[Fact]
public void SingleSegmentConstructor()
{
LinearLineSegment segment = new LinearLineSegment(new Vector2(0, 0), new Vector2(10, 10));
var segment = new LinearLineSegment(new Vector2(0, 0), new Vector2(10, 10));
IReadOnlyList<PointF> flatPath = segment.Flatten();
Assert.Equal(2, flatPath.Count);
Assert.Equal(new PointF(0, 0), flatPath[0]);
@ -30,9 +30,7 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void NullPointsArrayThrowsCountException()
{
Assert.ThrowsAny<ArgumentNullException>(() => {
new LinearLineSegment((PointF[])null);
});
Assert.ThrowsAny<ArgumentNullException>(() => new LinearLineSegment(null));
}
}
}

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

@ -1,54 +1,52 @@
using System;
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Numerics;
using SixLabors.Primitives;
using Xunit;
namespace SixLabors.Shapes.Tests
{
using SixLabors.Primitives;
using System.Numerics;
using Xunit;
public class PathBuilderTests
{
[Fact]
public void DrawLinesClosedFigure()
{
PathBuilder builder = new PathBuilder();
var builder = new PathBuilder();
builder.AddLine(10, 10, 10, 90);
builder.AddLine(10, 90, 50, 50);
builder.CloseFigure();
Polygon shape = Assert.IsType<Polygon>(builder.Build());
Assert.IsType<Polygon>(builder.Build());
}
[Fact]
public void AddBezier()
{
PathBuilder builder = new PathBuilder();
var builder = new PathBuilder();
builder.AddBezier(new Vector2(10, 10), new Vector2(20, 20), new Vector2(20, 30), new Vector2(10, 40));
Path shape = Assert.IsType<Path>(builder.Build());
Assert.IsType<Path>(builder.Build());
}
[Fact]
public void DrawLinesOpenFigure()
{
PathBuilder builder = new PathBuilder();
var builder = new PathBuilder();
builder.AddLine(10, 10, 10, 90);
builder.AddLine(10, 90, 50, 50);
Path shape = Assert.IsType<Path>(builder.Build());
Assert.IsType<Path>(builder.Build());
}
[Fact]
public void DrawLines2OpenFigures()
{
PathBuilder builder = new PathBuilder();
var builder = new PathBuilder();
builder.AddLine(10, 10, 10, 90);
builder.AddLine(10, 90, 50, 50);
@ -62,10 +60,11 @@ namespace SixLabors.Shapes.Tests
Assert.IsType<Path>(p[0]);
Assert.IsType<Path>(p[1]);
}
[Fact]
public void DrawLinesOpenThenClosedFigures()
{
PathBuilder builder = new PathBuilder();
var builder = new PathBuilder();
builder.AddLine(10, 10, 10, 90);
builder.AddLine(10, 90, 50, 50);
@ -84,7 +83,7 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void DrawLinesClosedThenOpenFigures()
{
PathBuilder builder = new PathBuilder();
var builder = new PathBuilder();
builder.AddLine(10, 10, 10, 90);
builder.AddLine(10, 90, 50, 50);
@ -102,7 +101,7 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void DrawLinesCloseAllFigures()
{
PathBuilder builder = new PathBuilder();
var builder = new PathBuilder();
builder.AddLine(10, 10, 10, 90);
builder.AddLine(10, 90, 50, 50);
@ -128,12 +127,12 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void EnumerableAddLines()
{
Vector2 point1 = new Vector2(10, 10);
Vector2 point2 = new Vector2(10, 90);
Vector2 point3 = new Vector2(50, 50);
PathBuilder builder = new PathBuilder();
var point1 = new Vector2(10, 10);
var point2 = new Vector2(10, 90);
var point3 = new Vector2(50, 50);
var builder = new PathBuilder();
builder.AddLines(new List<PointF> { point1, point2, point3});
builder.AddLines(new List<PointF> { point1, point2, point3 });
Path shape = Assert.IsType<Path>(builder.Build());
Assert.Equal(10, shape.Bounds.Left);
}
@ -141,26 +140,26 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void MultipleStartFiguresDoesntCreateEmptyPaths()
{
Vector2 point1 = new Vector2(10, 10);
Vector2 point2 = new Vector2(10, 90);
Vector2 point3 = new Vector2(50, 50);
PathBuilder builder = new PathBuilder();
var point1 = new Vector2(10, 10);
var point2 = new Vector2(10, 90);
var point3 = new Vector2(50, 50);
var builder = new PathBuilder();
builder.StartFigure();
builder.StartFigure();
builder.StartFigure();
builder.StartFigure();
builder.AddLines(new List<PointF> { point1, point2, point3 });
Path shape = Assert.IsType<Path>(builder.Build());
Assert.IsType<Path>(builder.Build());
}
[Fact]
public void DefaultTransform()
{
Vector2 point1 = new Vector2(10, 10);
Vector2 point2 = new Vector2(10, 90);
Vector2 point3 = new Vector2(50, 50);
Matrix3x2 matrix = Matrix3x2.CreateTranslation(new Vector2(5, 5));
PathBuilder builder = new PathBuilder(matrix);
var point1 = new Vector2(10, 10);
var point2 = new Vector2(10, 90);
var point3 = new Vector2(50, 50);
var matrix = Matrix3x2.CreateTranslation(new Vector2(5, 5));
var builder = new PathBuilder(matrix);
builder.AddLines(point1, point2, point3);
IPath shape = builder.Build();
@ -170,11 +169,11 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void SetTransform()
{
Vector2 point1 = new Vector2(10, 10);
Vector2 point2 = new Vector2(10, 90);
Vector2 point3 = new Vector2(50, 50);
Matrix3x2 matrix = Matrix3x2.CreateTranslation(new Vector2(100, 100));
PathBuilder builder = new PathBuilder();
var point1 = new Vector2(10, 10);
var point2 = new Vector2(10, 90);
var point3 = new Vector2(50, 50);
var matrix = Matrix3x2.CreateTranslation(new Vector2(100, 100));
var builder = new PathBuilder();
builder.AddLines(point1, point2, point3);
builder.SetTransform(matrix);
@ -193,15 +192,15 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void SetOriginLeaveMatrix()
{
Vector2 point1 = new Vector2(10, 10);
Vector2 point2 = new Vector2(10, 90);
Vector2 point3 = new Vector2(50, 50);
Vector2 origin = new Vector2(-50, -100);
PathBuilder builder = new PathBuilder(Matrix3x2.CreateScale(10));
var point1 = new Vector2(10, 10);
var point2 = new Vector2(10, 90);
var point3 = new Vector2(50, 50);
var origin = new Vector2(-50, -100);
var builder = new PathBuilder(Matrix3x2.CreateScale(10));
builder.AddLines(point1, point2, point3);
builder.SetOrigin(origin); //new origin is scaled by default transform
builder.SetOrigin(origin); // new origin is scaled by default transform
builder.StartFigure();
builder.AddLines(point1, point2, point3);
IPath[] shape = Assert.IsType<ComplexPolygon>(builder.Build()).Paths.ToArray();

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

@ -1,11 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Numerics;
using System.Threading.Tasks;
using Moq;
using Xunit;
using SixLabors.Primitives;
using Xunit;
namespace SixLabors.Shapes.Tests
{
@ -24,20 +24,18 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void RotateInRadians()
{
float angle = (float)Math.PI;
const float Angle = (float)Math.PI;
this.mockPath.Setup(x => x.Transform(It.IsAny<Matrix3x2>()))
.Callback<Matrix3x2>(m =>
{
//validate matrix in here
Matrix3x2 targetMatrix = Matrix3x2.CreateRotation(angle, RectangleF.Center(this.bounds));
// validate matrix in here
var targetMatrix = Matrix3x2.CreateRotation(Angle, RectangleF.Center(this.bounds));
Assert.Equal(targetMatrix, m);
}).Returns(this.mockPath.Object);
this.mockPath.Object.Rotate(angle);
this.mockPath.Object.Rotate(Angle);
this.mockPath.Verify(x => x.Transform(It.IsAny<Matrix3x2>()), Times.Once);
}
@ -45,21 +43,20 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void RotateInDegrees()
{
float angle = 90;
const float Angle = 90;
this.mockPath.Setup(x => x.Transform(It.IsAny<Matrix3x2>()))
.Callback<Matrix3x2>(m =>
{
//validate matrix in here
float radians = (float)(Math.PI * angle / 180.0);
// validate matrix in here
const float Radians = (float)(Math.PI * Angle / 180.0);
Matrix3x2 targetMatrix = Matrix3x2.CreateRotation(radians, RectangleF.Center(this.bounds));
var targetMatrix = Matrix3x2.CreateRotation(Radians, RectangleF.Center(this.bounds));
Assert.Equal(targetMatrix, m);
}).Returns(this.mockPath.Object);
this.mockPath.Object.RotateDegree(angle);
this.mockPath.Object.RotateDegree(Angle);
this.mockPath.Verify(x => x.Transform(It.IsAny<Matrix3x2>()), Times.Once);
}
@ -67,17 +64,15 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void TranslateVector()
{
Vector2 point = new Vector2(98, 120);
var point = new Vector2(98, 120);
this.mockPath.Setup(x => x.Transform(It.IsAny<Matrix3x2>()))
.Callback<Matrix3x2>(m =>
{
//validate matrix in here
Matrix3x2 targetMatrix = Matrix3x2.CreateTranslation(point);
// validate matrix in here
var targetMatrix = Matrix3x2.CreateTranslation(point);
Assert.Equal(targetMatrix, m);
}).Returns(this.mockPath.Object);
this.mockPath.Object.Translate(point);
@ -88,21 +83,19 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void TranslateXY()
{
float x = 76;
float y = 7;
const float X = 76;
const float Y = 7;
this.mockPath.Setup(p => p.Transform(It.IsAny<Matrix3x2>()))
.Callback<Matrix3x2>(m =>
{
//validate matrix in here
Matrix3x2 targetMatrix = Matrix3x2.CreateTranslation(new Vector2(x, y));
// validate matrix in here
var targetMatrix = Matrix3x2.CreateTranslation(new Vector2(X, Y));
Assert.Equal(targetMatrix, m);
}).Returns(this.mockPath.Object);
this.mockPath.Object.Translate(x, y);
this.mockPath.Object.Translate(X, Y);
this.mockPath.Verify(p => p.Transform(It.IsAny<Matrix3x2>()), Times.Once);
}

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

@ -1,11 +1,12 @@
using Xunit;
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System.Linq;
using SixLabors.Primitives;
using Xunit;
namespace SixLabors.Shapes.Tests
{
using SixLabors.Primitives;
using System.Linq;
using System.Numerics;
/// <summary>
/// The internal path tests.
/// </summary>
@ -14,10 +15,10 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void Bounds()
{
LinearLineSegment seg1 = new LinearLineSegment(new PointF(0, 0), new PointF(2, 2));
LinearLineSegment seg2 = new LinearLineSegment(new PointF(4, 4), new PointF(5, 5));
var seg1 = new LinearLineSegment(new PointF(0, 0), new PointF(2, 2));
var seg2 = new LinearLineSegment(new PointF(4, 4), new PointF(5, 5));
Path path = new Path(seg1, seg2);
var path = new Path(seg1, seg2);
Assert.Equal(0, path.Bounds.Left);
Assert.Equal(5, path.Bounds.Right);
@ -56,7 +57,7 @@ namespace SixLabors.Shapes.Tests
[MemberData(nameof(PathDistanceTheoryData))]
public void DistanceFromPath_Path(TestPoint point, float expectedDistance, float alongPath)
{
Path path = new Path(new LinearLineSegment(new PointF(0, 0), new PointF(10, 0), new PointF(10, 10), new PointF(0, 10)));
var path = new Path(new LinearLineSegment(new PointF(0, 0), new PointF(10, 0), new PointF(10, 10), new PointF(0, 10)));
PointInfo info = path.Distance(point);
Assert.Equal(expectedDistance, info.DistanceFromPath);
Assert.Equal(alongPath, info.DistanceAlongPath);
@ -65,7 +66,7 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void SimplePath()
{
Path path = new Path(new LinearLineSegment(new PointF(0, 0), new PointF(10, 0), new PointF(10, 10), new PointF(0, 10)));
var path = new Path(new LinearLineSegment(new PointF(0, 0), new PointF(10, 0), new PointF(10, 10), new PointF(0, 10)));
System.Collections.Generic.IReadOnlyList<PointF> points = path.Flatten().Single().Points;
Assert.Equal(4, points.Count);

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

@ -1,42 +1,37 @@
using System;
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Moq;
using System.Numerics;
using SixLabors.Primitives;
using SixLabors.Shapes.PolygonClipper;
using Xunit;
using Clipper = SixLabors.Shapes.PolygonClipper.Clipper;
namespace SixLabors.Shapes.Tests.PolygonClipper
{
using System.Collections.Immutable;
using System.Numerics;
using SixLabors.Shapes.PolygonClipper;
using Xunit;
using ClipperLib;
using Clipper = SixLabors.Shapes.PolygonClipper.Clipper;
using SixLabors.Primitives;
public class ClipperTests
{
private RectangularPolygon BigSquare = new RectangularPolygon(10, 10, 40, 40);
private RectangularPolygon Hole = new RectangularPolygon(20, 20, 10, 10);
private RectangularPolygon TopLeft = new RectangularPolygon(0, 0, 20, 20);
private RectangularPolygon TopRight = new RectangularPolygon(30, 0, 20, 20);
private RectangularPolygon TopMiddle = new RectangularPolygon(20, 0, 10, 20);
private readonly RectangularPolygon bigSquare = new RectangularPolygon(10, 10, 40, 40);
private readonly RectangularPolygon hole = new RectangularPolygon(20, 20, 10, 10);
private readonly RectangularPolygon topLeft = new RectangularPolygon(0, 0, 20, 20);
private readonly RectangularPolygon topRight = new RectangularPolygon(30, 0, 20, 20);
private readonly RectangularPolygon topMiddle = new RectangularPolygon(20, 0, 10, 20);
private Polygon BigTriangle = new Polygon(new LinearLineSegment(
private readonly Polygon bigTriangle = new Polygon(new LinearLineSegment(
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300)));
private Polygon LittleTriangle = new Polygon(new LinearLineSegment(
private readonly Polygon littleTriangle = new Polygon(new LinearLineSegment(
new Vector2(37, 85),
new Vector2(130, 40),
new Vector2(65, 137)));
private IEnumerable<IPath> Clip(IPath shape, params IPath[] hole)
{
Clipper clipper = new Clipper();
var clipper = new Clipper();
clipper.AddPath(shape, ClippingType.Subject);
if (hole != null)
@ -53,12 +48,12 @@ namespace SixLabors.Shapes.Tests.PolygonClipper
[Fact]
public void OverlappingTriangleCutRightSide()
{
Polygon triangle = new Polygon(new LinearLineSegment(
var triangle = new Polygon(new LinearLineSegment(
new Vector2(0, 50),
new Vector2(70, 0),
new Vector2(50, 100)));
Polygon cutout = new Polygon(new LinearLineSegment(
var cutout = new Polygon(new LinearLineSegment(
new Vector2(20, 0),
new Vector2(70, 0),
new Vector2(70, 100),
@ -72,11 +67,11 @@ namespace SixLabors.Shapes.Tests.PolygonClipper
[Fact]
public void OverlappingTriangles()
{
IEnumerable<IPath> shapes = this.Clip(this.BigTriangle, this.LittleTriangle);
IEnumerable<IPath> shapes = this.Clip(this.bigTriangle, this.littleTriangle);
Assert.Single(shapes);
IReadOnlyList<PointF> path = shapes.Single().Flatten().First().Points;
Assert.Equal(7, path.Count);
foreach (Vector2 p in this.BigTriangle.Flatten().First().Points)
foreach (Vector2 p in this.bigTriangle.Flatten().First().Points)
{
Assert.Contains(p, path);
}
@ -85,43 +80,43 @@ namespace SixLabors.Shapes.Tests.PolygonClipper
[Fact]
public void NonOverlapping()
{
IEnumerable<RectangularPolygon> shapes = this.Clip(this.TopLeft, this.TopRight)
IEnumerable<RectangularPolygon> shapes = this.Clip(this.topLeft, this.topRight)
.OfType<Polygon>().Select(x => (RectangularPolygon)x);
Assert.Single(shapes);
Assert.Contains(this.TopLeft, shapes);
Assert.Contains(this.topLeft, shapes);
Assert.DoesNotContain(this.TopRight, shapes);
Assert.DoesNotContain(this.topRight, shapes);
}
[Fact]
public void OverLappingReturns1NewShape()
{
IEnumerable<IPath> shapes = this.Clip(this.BigSquare, this.TopLeft);
IEnumerable<IPath> shapes = this.Clip(this.bigSquare, this.topLeft);
Assert.Single(shapes);
Assert.DoesNotContain(this.BigSquare, shapes);
Assert.DoesNotContain(this.TopLeft, shapes);
Assert.DoesNotContain(this.bigSquare, shapes);
Assert.DoesNotContain(this.topLeft, shapes);
}
[Fact]
public void OverlappingButNotCrossingRetuensOrigionalShapes()
{
IEnumerable<RectangularPolygon> shapes = this.Clip(this.BigSquare, this.Hole)
IEnumerable<RectangularPolygon> shapes = this.Clip(this.bigSquare, this.hole)
.OfType<Polygon>().Select(x => (RectangularPolygon)x);
Assert.Equal(2, shapes.Count());
Assert.Contains(this.BigSquare, shapes);
Assert.Contains(this.Hole, shapes);
Assert.Contains(this.bigSquare, shapes);
Assert.Contains(this.hole, shapes);
}
[Fact]
public void TouchingButNotOverlapping()
{
IEnumerable<IPath> shapes = this.Clip(this.TopMiddle, this.TopLeft);
IEnumerable<IPath> shapes = this.Clip(this.topMiddle, this.topLeft);
Assert.Single(shapes);
Assert.DoesNotContain(this.TopMiddle, shapes);
Assert.DoesNotContain(this.TopLeft, shapes);
Assert.DoesNotContain(this.topMiddle, shapes);
Assert.DoesNotContain(this.topLeft, shapes);
}
[Fact]

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

@ -1,44 +1,46 @@
using System;
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using SixLabors.Primitives;
using Xunit;
namespace SixLabors.Shapes.Tests
{
using SixLabors.Primitives;
using System.Numerics;
public class PolygonTests
{
public static TheoryData<TestPoint[], TestPoint, bool> PointInPolygonTheoryData =
new TheoryData<TestPoint[], TestPoint, bool>
{
{
new TestPoint[] {new PointF(10, 10), new PointF(10, 100), new PointF(100, 100), new PointF(100, 10)},
new TestPoint[] { new PointF(10, 10), new PointF(10, 100), new PointF(100, 100), new PointF(100, 10) },
// loc
new PointF(10, 10), // test
true
}, //corner is inside
}, // corner is inside
{
new TestPoint[] {new PointF(10, 10), new PointF(10, 100), new PointF(100, 100), new PointF(100, 10)},
new TestPoint[] { new PointF(10, 10), new PointF(10, 100), new PointF(100, 100), new PointF(100, 10) },
// loc
new PointF(10, 11), // test
true
}, //on line
}, // on line
{
new TestPoint[] {new PointF(10, 10), new PointF(10, 100), new PointF(100, 100), new PointF(100, 10)},
new TestPoint[] { new PointF(10, 10), new PointF(10, 100), new PointF(100, 100), new PointF(100, 10) },
// loc
new PointF(9, 9), // test
false
}, //corner is inside
}, // corner is inside
};
[Theory]
[MemberData(nameof(PointInPolygonTheoryData))]
public void PointInPolygon(TestPoint[] controlPoints, TestPoint point, bool isInside)
{
Polygon shape = new Polygon(new LinearLineSegment(controlPoints.Select(x => (PointF)x).ToArray()));
var shape = new Polygon(new LinearLineSegment(controlPoints.Select(x => (PointF)x).ToArray()));
Assert.Equal(isInside, shape.Contains(point));
}
@ -46,19 +48,19 @@ namespace SixLabors.Shapes.Tests
new TheoryData<TestPoint[], TestPoint, float>
{
{
new TestPoint[] {new PointF(10, 10), new PointF(10, 100), new PointF(100, 100), new PointF(100, 10)},
new TestPoint[] { new PointF(10, 10), new PointF(10, 100), new PointF(100, 100), new PointF(100, 10) },
new PointF(10, 10),
0
},
{
{
new TestPoint[] { new PointF(10, 10), new PointF(10, 100), new PointF(100, 100), new PointF(100, 10) },
new PointF(10, 11), 0
},
{
},
{
new TestPoint[] { new PointF(10, 10), new PointF(10, 100), new PointF(100, 100), new PointF(100, 10) },
new PointF(11, 11), -1
},
{
{
new TestPoint[] { new PointF(10, 10), new PointF(10, 100), new PointF(100, 100), new PointF(100, 10) },
new PointF(9, 10), 1
},
@ -68,7 +70,7 @@ namespace SixLabors.Shapes.Tests
[MemberData(nameof(DistanceTheoryData))]
public void Distance(TestPoint[] controlPoints, TestPoint point, float expected)
{
Polygon shape = new Polygon(new LinearLineSegment(controlPoints.Select(x => (PointF)x).ToArray()));
var shape = new Polygon(new LinearLineSegment(controlPoints.Select(x => (PointF)x).ToArray()));
Assert.Equal(expected, shape.Distance(point).DistanceFromPath);
}
@ -112,7 +114,7 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void AsSimpleLinearPath()
{
Polygon poly = new Polygon(new LinearLineSegment(new PointF(0, 0), new PointF(0, 10), new PointF(5, 5)));
var poly = new Polygon(new LinearLineSegment(new PointF(0, 0), new PointF(0, 10), new PointF(5, 5)));
IReadOnlyList<PointF> paths = poly.Flatten().First().Points;
Assert.Equal(3, paths.Count);
Assert.Equal(new PointF(0, 0), paths[0]);
@ -123,8 +125,8 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void FindIntersectionsBuffer()
{
Polygon poly = new Polygon(new LinearLineSegment(new PointF(0, 0), new PointF(0, 10), new PointF(10, 10), new PointF(10, 0)));
PointF[] buffer = new PointF[2];
var poly = new Polygon(new LinearLineSegment(new PointF(0, 0), new PointF(0, 10), new PointF(10, 10), new PointF(10, 0)));
var buffer = new PointF[2];
int hits = poly.FindIntersections(new PointF(5, -5), new PointF(5, 15), buffer, 0);
Assert.Equal(2, hits);
@ -135,7 +137,7 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void FindIntersectionsCollection()
{
Polygon poly = new Polygon(new LinearLineSegment(new PointF(0, 0), new PointF(0, 10), new PointF(10, 10), new PointF(10, 0)));
var poly = new Polygon(new LinearLineSegment(new PointF(0, 0), new PointF(0, 10), new PointF(10, 10), new PointF(10, 0)));
PointF[] buffer = poly.FindIntersections(new PointF(5, -5), new PointF(5, 15)).ToArray();
Assert.Equal(2, buffer.Length);
@ -146,7 +148,7 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void ReturnsWrapperOfSelfASOwnPath_SingleSegment()
{
Polygon poly = new Polygon(new LinearLineSegment(new PointF(0, 0), new PointF(0, 10), new PointF(5, 5)));
var poly = new Polygon(new LinearLineSegment(new PointF(0, 0), new PointF(0, 10), new PointF(5, 5)));
ISimplePath[] paths = poly.Flatten().ToArray();
Assert.Single(paths);
Assert.Equal(poly, paths[0]);
@ -155,7 +157,7 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void ReturnsWrapperOfSelfASOwnPath_MultiSegment()
{
Polygon poly = new Polygon(new LinearLineSegment(new PointF(0, 0), new PointF(0, 10)), new LinearLineSegment(new PointF(2, 5), new PointF(5, 5)));
var poly = new Polygon(new LinearLineSegment(new PointF(0, 0), new PointF(0, 10)), new LinearLineSegment(new PointF(2, 5), new PointF(5, 5)));
ISimplePath[] paths = poly.Flatten().ToArray();
Assert.Single(paths);
Assert.Equal(poly, paths[0]);
@ -164,7 +166,7 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void Bounds()
{
Polygon poly = new Polygon(new LinearLineSegment(new PointF(0, 0), new PointF(0, 10), new PointF(5, 5)));
var poly = new Polygon(new LinearLineSegment(new PointF(0, 0), new PointF(0, 10), new PointF(5, 5)));
RectangleF bounds = poly.Bounds;
Assert.Equal(0, bounds.Left);
Assert.Equal(0, bounds.Top);
@ -175,7 +177,7 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void MaxIntersections()
{
Polygon poly = new Polygon(new LinearLineSegment(new PointF(0, 0), new PointF(0, 10)));
var poly = new Polygon(new LinearLineSegment(new PointF(0, 0), new PointF(0, 10)));
// with linear polygons its the number of points the segments have
Assert.Equal(2, poly.MaxIntersections);
@ -184,7 +186,7 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void FindBothIntersections()
{
Polygon poly = new Polygon(new LinearLineSegment(
var poly = new Polygon(new LinearLineSegment(
new PointF(10, 10),
new PointF(200, 150),
new PointF(50, 300)));
@ -195,12 +197,12 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void HandleClippingInnerCorner()
{
Polygon simplePath = new Polygon(new LinearLineSegment(
var simplePath = new Polygon(new LinearLineSegment(
new PointF(10, 10),
new PointF(200, 150),
new PointF(50, 300)));
Polygon hole1 = new Polygon(new LinearLineSegment(
var hole1 = new Polygon(new LinearLineSegment(
new PointF(37, 85),
new PointF(130, 40),
new PointF(65, 137)));
@ -213,11 +215,10 @@ namespace SixLabors.Shapes.Tests
Assert.Equal(4, intersections.Count());
}
[Fact]
public void CrossingCorner()
{
Polygon simplePath = new Polygon(new LinearLineSegment(
var simplePath = new Polygon(new LinearLineSegment(
new PointF(10, 10),
new PointF(200, 150),
new PointF(50, 300)));
@ -228,7 +229,6 @@ namespace SixLabors.Shapes.Tests
Assert.Equal(2, intersections.Count());
}
[Fact]
public void ClippingEdgefromInside()
{
@ -243,7 +243,7 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void ClippingEdgeFromOutside()
{
Polygon simplePath = new Polygon(new LinearLineSegment(
var simplePath = new Polygon(new LinearLineSegment(
new PointF(10, 10),
new PointF(100, 10),
new PointF(50, 300)));
@ -257,12 +257,12 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void HandleClippingOutterCorner()
{
Polygon simplePath = new Polygon(new LinearLineSegment(
var simplePath = new Polygon(new LinearLineSegment(
new PointF(10, 10),
new PointF(200, 150),
new PointF(50, 300)));
Polygon hole1 = new Polygon(new LinearLineSegment(
var hole1 = new Polygon(new LinearLineSegment(
new PointF(37, 85),
new PointF(130, 40),
new PointF(65, 137)));
@ -278,12 +278,12 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void MissingIntersection()
{
Polygon simplePath = new Polygon(new LinearLineSegment(
var simplePath = new Polygon(new LinearLineSegment(
new PointF(10, 10),
new PointF(200, 150),
new PointF(50, 300)));
Polygon hole1 = new Polygon(new LinearLineSegment(
var hole1 = new Polygon(new LinearLineSegment(
new PointF(37, 85),
new PointF(130, 40),
new PointF(65, 137)));
@ -303,18 +303,19 @@ namespace SixLabors.Shapes.Tests
public void BezierPolygonReturning2Points(int y)
{
// missing bands in test from ImageSharp
PointF[] simplePath = new[] {
PointF[] simplePath = new[]
{
new PointF(10, 400),
new PointF(30, 10),
new PointF(240, 30),
new PointF(300, 400)
};
Polygon poly = new Polygon(new CubicBezierLineSegment(simplePath));
var poly = new Polygon(new CubicBezierLineSegment(simplePath));
List<PointF> points = poly.FindIntersections(new PointF(float.MinValue, y), new PointF(float.MaxValue, y)).ToList();
var points = poly.FindIntersections(new PointF(float.MinValue, y), new PointF(float.MaxValue, y)).ToList();
Assert.Equal(2, points.Count());
Assert.Equal(2, points.Count);
}
}
}

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

@ -1,9 +1,11 @@
using SixLabors.Primitives;
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Threading.Tasks;
using SixLabors.Primitives;
using Xunit;
namespace SixLabors.Shapes.Tests
@ -14,97 +16,96 @@ namespace SixLabors.Shapes.Tests
new TheoryData<TestPoint, TestSize, TestPoint, bool>
{
{
new PointF(10,10), // loc
new SizeF(100,100), // size
new PointF(10,10), // test
new PointF(10, 10), // loc
new SizeF(100, 100), // size
new PointF(10, 10), // test
true
}, //corner is inside
{
new PointF(10,10), // loc
new SizeF(100,100), // size
new PointF(9,9), // test
}, // corner is inside
{
new PointF(10, 10), // loc
new SizeF(100, 100), // size
new PointF(9, 9), // test
false
}, //corner is inside
}, // corner is inside
};
public static TheoryData<TestPoint, TestSize, TestPoint, float> DistanceTheoryData =
new TheoryData<TestPoint, TestSize, TestPoint, float>
{
{
new PointF(10,10), // loc
new SizeF(100,100), // size
new PointF(10,10), // test
new PointF(10, 10), // loc
new SizeF(100, 100), // size
new PointF(10, 10), // test
0f
}, //corner is inside
{
new PointF(10,10), // loc
new SizeF(100,100), // size
new PointF(9,10), // test
}, // corner is inside
{
new PointF(10, 10), // loc
new SizeF(100, 100), // size
new PointF(9, 10), // test
1f
},
{
new PointF(10,10), // loc
new SizeF(100,100), // size
new PointF(10,13), // test
},
{
new PointF(10, 10), // loc
new SizeF(100, 100), // size
new PointF(10, 13), // test
0f
},
{
new PointF(10,10), // loc
new SizeF(100,100), // size
new PointF(14,13), // test
},
{
new PointF(10, 10), // loc
new SizeF(100, 100), // size
new PointF(14, 13), // test
-3f
},
{
new PointF(10,10), // loc
new SizeF(100,100), // size
new PointF(13,14), // test
},
{
new PointF(10, 10), // loc
new SizeF(100, 100), // size
new PointF(13, 14), // test
-3f
},
{
new PointF(10,10), // loc
new SizeF(100,100), // size
new PointF(7,6), // test
},
{
new PointF(10, 10), // loc
new SizeF(100, 100), // size
new PointF(7, 6), // test
5f
},
},
};
public static TheoryData<TestPoint, float, float> PathDistanceTheoryData =
new TheoryData<TestPoint, float, float>
{
{ new PointF(0,0), 0f, 0f },
{ new PointF(1,0), 0f, 1f },
{ new PointF(9,0), 0f, 9f },
{ new PointF(10,0), 0f, 10f },
{ new PointF(0, 0), 0f, 0f },
{ new PointF(1, 0), 0f, 1f },
{ new PointF(9, 0), 0f, 9f },
{ new PointF(10, 0), 0f, 10f },
{ new PointF(10, 1), 0f, 11f },
{ new PointF(10,9), 0f, 19f },
{ new PointF(10,10), 0f, 20f },
{ new PointF(9,10), 0f, 21f },
{ new PointF(1,10), 0f, 29f },
{ new PointF(0,10), 0f, 30f },
{ new PointF(0,9), 0f, 31f },
{ new PointF(0,1), 0f, 39f },
{ new PointF(4,3), -3f, 4f },
{ new PointF(10, 9), 0f, 19f },
{ new PointF(10, 10), 0f, 20f },
{ new PointF(9, 10), 0f, 21f },
{ new PointF(1, 10), 0f, 29f },
{ new PointF(0, 10), 0f, 30f },
{ new PointF(0, 9), 0f, 31f },
{ new PointF(0, 1), 0f, 39f },
{ new PointF(4, 3), -3f, 4f },
{ new PointF(3, 4), -3f, 36f },
{ new PointF(-1,0), 1f, 0f },
{ new PointF(1,-1), 1f, 1f },
{ new PointF(9,-1), 1f, 9f },
{ new PointF(11,0), 1f, 10f },
{ new PointF(-1, 0), 1f, 0f },
{ new PointF(1, -1), 1f, 1f },
{ new PointF(9, -1), 1f, 9f },
{ new PointF(11, 0), 1f, 10f },
{ new PointF(11, 1), 1f, 11f },
{ new PointF(11,9), 1f, 19f },
{ new PointF(11,10), 1f, 20f },
{ new PointF(9,11), 1f, 21f },
{ new PointF(1,11), 1f, 29f },
{ new PointF(-1,10), 1f, 30f },
{ new PointF(-1,9), 1f, 31f },
{ new PointF(-1,1), 1f, 39f },
{ new PointF(11, 9), 1f, 19f },
{ new PointF(11, 10), 1f, 20f },
{ new PointF(9, 11), 1f, 21f },
{ new PointF(1, 11), 1f, 29f },
{ new PointF(-1, 10), 1f, 30f },
{ new PointF(-1, 9), 1f, 31f },
{ new PointF(-1, 1), 1f, 39f },
};
[Theory]
[MemberData(nameof(PointInPolygonTheoryData))]
public void PointInPolygon(TestPoint location, TestSize size, TestPoint point, bool isInside)
{
RectangularPolygon shape = new RectangularPolygon(location, size);
var shape = new RectangularPolygon(location, size);
Assert.Equal(isInside, shape.Contains(point));
}
@ -121,7 +122,7 @@ namespace SixLabors.Shapes.Tests
[MemberData(nameof(PathDistanceTheoryData))]
public void DistanceFromPath_Path(TestPoint point, float expectecDistance, float alongPath)
{
IPath shape = new RectangularPolygon(0, 0, 10, 10).AsPath();
IPath shape = new RectangularPolygon(0, 0, 10, 10);
PointInfo info = shape.Distance(point);
Assert.Equal(expectecDistance, info.DistanceFromPath);
Assert.Equal(alongPath, info.DistanceAlongPath);
@ -130,35 +131,35 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void Left()
{
RectangularPolygon shape = new RectangularPolygon(10, 11, 12, 13);
var shape = new RectangularPolygon(10, 11, 12, 13);
Assert.Equal(10, shape.Left);
}
[Fact]
public void Right()
{
RectangularPolygon shape = new RectangularPolygon(10, 11, 12, 13);
var shape = new RectangularPolygon(10, 11, 12, 13);
Assert.Equal(22, shape.Right);
}
[Fact]
public void Top()
{
RectangularPolygon shape = new RectangularPolygon(10, 11, 12, 13);
var shape = new RectangularPolygon(10, 11, 12, 13);
Assert.Equal(11, shape.Top);
}
[Fact]
public void Bottom()
{
RectangularPolygon shape = new RectangularPolygon(10, 11, 12, 13);
var shape = new RectangularPolygon(10, 11, 12, 13);
Assert.Equal(24, shape.Bottom);
}
[Fact]
public void SizeF()
{
RectangularPolygon shape = new RectangularPolygon(10, 11, 12, 13);
var shape = new RectangularPolygon(10, 11, 12, 13);
Assert.Equal(12, shape.Size.Width);
Assert.Equal(13, shape.Size.Height);
}
@ -176,7 +177,7 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void LienearSegements()
{
IPath shape = new RectangularPolygon(10, 11, 12, 13).AsPath();
IPath shape = new RectangularPolygon(10, 11, 12, 13);
IReadOnlyList<PointF> segemnts = shape.Flatten().ToArray()[0].Points;
Assert.Equal(new PointF(10, 11), segemnts[0]);
Assert.Equal(new PointF(22, 11), segemnts[1]);
@ -217,13 +218,13 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void Bounds_Path()
{
IPath shape = new RectangularPolygon(10, 11, 12, 13).AsPath();
IPath shape = new RectangularPolygon(10, 11, 12, 13);
Assert.Equal(10, shape.Bounds.Left);
Assert.Equal(22, shape.Bounds.Right);
Assert.Equal(11, shape.Bounds.Top);
Assert.Equal(24, shape.Bounds.Bottom);
}
[Fact]
public void MaxIntersections_Shape()
{
@ -242,9 +243,8 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void TransformIdnetityReturnsSahpeObject()
{
IPath shape = new RectangularPolygon(0, 0, 200, 60);
IPath transformdShape = shape.Transform(Matrix3x2.Identity);
IPath transformdShape = shape.Transform(Matrix3x2.Identity);
Assert.Same(shape, transformdShape);
}
@ -263,13 +263,13 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void Center()
{
RectangularPolygon shape = new RectangularPolygon(50, 50, 200, 60);
var shape = new RectangularPolygon(50, 50, 200, 60);
Assert.Equal(new PointF(150, 80), shape.Center);
}
const float HalfPi = (float)(Math.PI / 2);
const float Pi = (float)(Math.PI);
private const float HalfPi = (float)(Math.PI / 2);
private const float Pi = (float)Math.PI;
[Theory]
[InlineData(0, 50, 50, Pi)]
@ -286,7 +286,5 @@ namespace SixLabors.Shapes.Tests
Assert.Equal(expectedY, point.Point.Y);
Assert.Equal(expectedAngle, point.Angle);
}
}
}

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

@ -1,17 +1,17 @@
using System;
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Numerics;
using SixLabors.Primitives;
using Xunit;
namespace SixLabors.Shapes.Tests
{
using SixLabors.Primitives;
using System.Numerics;
public class RegularPolygonTests
{
[Theory]
[InlineData(0, true)]
[InlineData(1, true)]
@ -28,7 +28,7 @@ namespace SixLabors.Shapes.Tests
}
else
{
RegularPolygon p = new RegularPolygon(Vector2.Zero, points, 10f, 0);
var p = new RegularPolygon(Vector2.Zero, points, 10f, 0);
Assert.NotNull(p);
}
}
@ -48,7 +48,7 @@ namespace SixLabors.Shapes.Tests
}
else
{
RegularPolygon p = new RegularPolygon(Vector2.Zero, 3, radius, 0);
var p = new RegularPolygon(Vector2.Zero, 3, radius, 0);
Assert.NotNull(p);
}
}
@ -56,10 +56,10 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void GeneratesCorrectPath()
{
float radius = 10;
const float Radius = 10;
int pointsCount = new Random().Next(3, 20);
RegularPolygon poly = new RegularPolygon(Vector2.Zero, pointsCount, radius, 0);
var poly = new RegularPolygon(Vector2.Zero, pointsCount, Radius, 0);
IReadOnlyList<PointF> points = poly.Flatten().ToArray()[0].Points;
@ -77,7 +77,7 @@ namespace SixLabors.Shapes.Tests
float actual = Vector2.Distance(points[i], points[j]);
Assert.Equal(baseline, actual, 3);
Assert.Equal(radius, Vector2.Distance(Vector2.Zero, points[i]), 3);
Assert.Equal(Radius, Vector2.Distance(Vector2.Zero, points[i]), 3);
}
}
@ -85,23 +85,22 @@ namespace SixLabors.Shapes.Tests
public void AngleChangesOnePointToStartAtThatPosition()
{
const double TwoPI = 2 * Math.PI;
float radius = 10;
const float Radius = 10;
double anAngle = new Random().NextDouble() * TwoPI;
RegularPolygon poly = new RegularPolygon(Vector2.Zero, 3, radius, (float)anAngle);
var poly = new RegularPolygon(Vector2.Zero, 3, Radius, (float)anAngle);
IReadOnlyList<PointF> points = poly.Flatten().ToArray()[0].Points;
IEnumerable<double> allAngles = points.Select(b => Math.Atan2(b.Y, b.X))
.Select(x => x < 0 ? x + TwoPI : x); // normalise it from +/- PI to 0 to TwoPI
Assert.Contains(allAngles, a => Math.Abs(a - anAngle) > 0.000001);
}
[Fact]
public void TriangleMissingIntersectionsDownCenter()
{
RegularPolygon poly = new SixLabors.Shapes.RegularPolygon(50, 50, 3, 30);
var poly = new SixLabors.Shapes.RegularPolygon(50, 50, 3, 30);
PointF[] points = poly.FindIntersections(new PointF(0, 50), new PointF(100, 50)).ToArray();
Assert.Equal(2, points.Length);
@ -110,7 +109,7 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void ClippingCornerShouldReturn2Points()
{
RegularPolygon poly = new RegularPolygon(50, 50, 7, 30, -(float)Math.PI);
var poly = new RegularPolygon(50, 50, 7, 30, -(float)Math.PI);
PointF[] points = poly.FindIntersections(new PointF(0, 20), new PointF(100, 20)).ToArray();
Assert.Equal(2, points.Length);

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

@ -1,8 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Numerics;
using System.Threading.Tasks;
namespace SixLabors.Shapes.Tests
{
@ -10,13 +10,15 @@ namespace SixLabors.Shapes.Tests
{
public static IPath IrisSegment(int rotationPos)
{
Vector2 center = new Vector2(603);
Vector2 segmentRotationCenter = new Vector2(301.16968f, 301.16974f);
IPath segment = new Polygon(new LinearLineSegment(new Vector2(230.54f, 361.0261f), new System.Numerics.Vector2(5.8641942f, 361.46031f)),
new CubicBezierLineSegment(new Vector2(5.8641942f, 361.46031f),
new Vector2(-11.715693f, 259.54052f),
new Vector2(24.441609f, 158.17478f),
new Vector2(78.26f, 97.0461f))).Translate(center - segmentRotationCenter);
var center = new Vector2(603);
var segmentRotationCenter = new Vector2(301.16968f, 301.16974f);
IPath segment = new Polygon(
new LinearLineSegment(new Vector2(230.54f, 361.0261f), new System.Numerics.Vector2(5.8641942f, 361.46031f)),
new CubicBezierLineSegment(
new Vector2(5.8641942f, 361.46031f),
new Vector2(-11.715693f, 259.54052f),
new Vector2(24.441609f, 158.17478f),
new Vector2(78.26f, 97.0461f))).Translate(center - segmentRotationCenter);
float angle = rotationPos * ((float)Math.PI / 3);
return segment.Transform(Matrix3x2.CreateRotation(angle, center));
@ -24,32 +26,32 @@ namespace SixLabors.Shapes.Tests
public static IPath IrisSegment(float size, int rotationPos)
{
float scalingFactor = size / 1206;
Vector2 center = new Vector2(603);
Vector2 segmentRotationCenter = new Vector2(301.16968f, 301.16974f);
IPath segment = new Polygon(new LinearLineSegment(new Vector2(230.54f, 361.0261f), new System.Numerics.Vector2(5.8641942f, 361.46031f)),
new CubicBezierLineSegment(new Vector2(5.8641942f, 361.46031f),
new Vector2(-11.715693f, 259.54052f),
new Vector2(24.441609f, 158.17478f),
new Vector2(78.26f, 97.0461f))).Translate(center - segmentRotationCenter);
var center = new Vector2(603);
var segmentRotationCenter = new Vector2(301.16968f, 301.16974f);
IPath segment = new Polygon(
new LinearLineSegment(new Vector2(230.54f, 361.0261f), new System.Numerics.Vector2(5.8641942f, 361.46031f)),
new CubicBezierLineSegment(
new Vector2(5.8641942f, 361.46031f),
new Vector2(-11.715693f, 259.54052f),
new Vector2(24.441609f, 158.17478f),
new Vector2(78.26f, 97.0461f))).Translate(center - segmentRotationCenter);
float angle = rotationPos * ((float)Math.PI / 3);
IPath rotated = segment.Transform(Matrix3x2.CreateRotation(angle, center));
Matrix3x2 scaler = Matrix3x2.CreateScale(scalingFactor, Vector2.Zero);
var scaler = Matrix3x2.CreateScale(scalingFactor, Vector2.Zero);
IPath scaled = rotated.Transform(scaler);
return scaled;
}
public static IPath HourGlass()
{
// center the shape outerRadii + 10 px away from edges
PathBuilder sb = new PathBuilder();
var sb = new PathBuilder();
// overlay rectangle
sb.AddLine(new Vector2(15, 0), new Vector2(25, 0));

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

@ -17,6 +17,15 @@
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
<PackageReference Include="xunit" Version="2.3.1" />
<PackageReference Include="Moq" Version="4.8.2" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="All" />
</ItemGroup>
<ItemGroup>
<AdditionalFiles Include="..\..\shared-infrastructure\stylecop.json" />
</ItemGroup>
<PropertyGroup>
<CodeAnalysisRuleSet>..\..\shared-infrastructure\SixLabors.Tests.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
</Project>

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

@ -1,17 +1,17 @@
using System;
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Numerics;
using SixLabors.Primitives;
using Xunit;
namespace SixLabors.Shapes.Tests
{
using SixLabors.Primitives;
using System.Numerics;
public class StarTests
{
[Theory]
[InlineData(0, true)]
[InlineData(1, true)]
@ -28,7 +28,7 @@ namespace SixLabors.Shapes.Tests
}
else
{
Star p = new Star(Vector2.Zero, points, 10f, 20f, 0);
var p = new Star(Vector2.Zero, points, 10f, 20f, 0);
Assert.NotNull(p);
}
}
@ -50,7 +50,7 @@ namespace SixLabors.Shapes.Tests
}
else
{
Star p = new Star(Vector2.Zero, 3, radius, radius, 0);
var p = new Star(Vector2.Zero, 3, radius, radius, 0);
Assert.NotNull(p);
}
}
@ -58,11 +58,11 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void GeneratesCorrectPath()
{
float radius = 5;
float radius2 = 30;
const float Radius = 5;
const float Radius2 = 30;
int pointsCount = new Random().Next(3, 20);
Star poly = new Star(Vector2.Zero, pointsCount, radius, radius2, 0);
var poly = new Star(Vector2.Zero, pointsCount, Radius, Radius2, 0);
PointF[] points = poly.Flatten().ToArray()[0].Points.ToArray();
@ -83,11 +83,11 @@ namespace SixLabors.Shapes.Tests
Assert.Equal(baseline, actual, 3);
if (i % 2 == 1)
{
Assert.Equal(radius, Vector2.Distance(Vector2.Zero, points[i]), 3);
Assert.Equal(Radius, Vector2.Distance(Vector2.Zero, points[i]), 3);
}
else
{
Assert.Equal(radius2, Vector2.Distance(Vector2.Zero, points[i]), 3);
Assert.Equal(Radius2, Vector2.Distance(Vector2.Zero, points[i]), 3);
}
}
}
@ -96,11 +96,11 @@ namespace SixLabors.Shapes.Tests
public void AngleChangesOnePointToStartAtThatPosition()
{
const double TwoPI = 2 * Math.PI;
float radius = 10;
float radius2 = 20;
const float Radius = 10;
const float Radius2 = 20;
double anAngle = new Random().NextDouble() * TwoPI;
Star poly = new Star(Vector2.Zero, 3, radius, radius2, (float)anAngle);
var poly = new Star(Vector2.Zero, 3, Radius, Radius2, (float)anAngle);
ISimplePath[] points = poly.Flatten().ToArray();
IEnumerable<double> allAngles = points[0].Points.Select(b => Math.Atan2(b.Y, b.X))
@ -112,8 +112,7 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void TriangleMissingIntersectionsDownCenter()
{
Star poly = new SixLabors.Shapes.Star(50, 50, 3, 50, 30);
var poly = new SixLabors.Shapes.Star(50, 50, 3, 50, 30);
PointF[] points = poly.FindIntersections(new Vector2(0, 50), new Vector2(100, 50)).ToArray();
Assert.Equal(2, points.Length);
@ -122,7 +121,7 @@ namespace SixLabors.Shapes.Tests
[Fact]
public void ClippingCornerShouldReturn2Points()
{
Star star = new Star(40, 40, 3, 10, 20);
var star = new Star(40, 40, 3, 10, 20);
PointF[] points = star.FindIntersections(new Vector2(0, 30), new Vector2(100, 30)).ToArray();
Assert.True(points.Length % 2 == 0, "Should have even number of intersection points");

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

@ -1,18 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Numerics;
using SixLabors.Primitives;
using Xunit.Abstractions;
namespace SixLabors.Shapes.Tests
{
using SixLabors.Primitives;
using System.Numerics;
[Serializable]
public class TestPoint : IXunitSerializable
{
public TestPoint() { }
public TestPoint()
{
}
public TestPoint(float x, float y)
{
@ -21,6 +22,7 @@ namespace SixLabors.Shapes.Tests
}
public float X { get; private set; }
public float Y { get; private set; }
public void Deserialize(IXunitSerializationInfo info)
@ -44,6 +46,7 @@ namespace SixLabors.Shapes.Tests
{
return new Vector2(p.X, p.Y);
}
public static implicit operator TestPoint(PointF p)
{
return new TestPoint(p.X, p.Y);

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

@ -1,8 +1,8 @@
using SixLabors.Primitives;
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using SixLabors.Primitives;
using Xunit.Abstractions;
namespace SixLabors.Shapes.Tests
@ -10,7 +10,9 @@ namespace SixLabors.Shapes.Tests
[Serializable]
public class TestSize : IXunitSerializable
{
public TestSize() { }
public TestSize()
{
}
public TestSize(float width, float height)
{
@ -19,6 +21,7 @@ namespace SixLabors.Shapes.Tests
}
public float Width { get; private set; }
public float Height { get; private set; }
public void Deserialize(IXunitSerializationInfo info)
@ -37,10 +40,12 @@ namespace SixLabors.Shapes.Tests
{
return new SizeF(p.Width, p.Height);
}
public static implicit operator TestSize(SizeF p)
{
return new TestSize(p.Width, p.Height);
}
public override string ToString()
{
return $"{this.Width}x{this.Height}";