Update props/targets; fix all warnings

This commit is contained in:
James Jackson-South 2020-12-03 14:43:29 +00:00
Родитель 3d737b5d95
Коммит 233bbfe7d4
130 изменённых файлов: 2387 добавлений и 2708 удалений

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

@ -1,372 +1,436 @@
###############################################################################
# EditorConfig is awesome: http://EditorConfig.org
###############################################################################
# Version: 1.6.2 (Using https://semver.org/)
# Updated: 2020-11-02
# See https://github.com/RehanSaeed/EditorConfig/releases for release notes.
# See https://github.com/RehanSaeed/EditorConfig for updates to this file.
# See http://EditorConfig.org for more information about .editorconfig files.
###############################################################################
# Top-most EditorConfig file
###############################################################################
##########################################
# Common Settings
##########################################
# This file is the 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
###############################################################################
# All Files
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
###############################################################################
# Set file behavior to:
# 2 space indentation
###############################################################################
[*.{cmd,config,csproj,json,props,ps1,resx,sh,targets}]
indent_size = 2
##########################################
# File Extension Settings
##########################################
###############################################################################
# Set file behavior to:
# Windows-style line endings, and
# tabular indentation
###############################################################################
# Visual Studio Solution Files
[*.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
# Visual Studio XML Project Files
[*.{csproj,vbproj,vcxproj.filters,proj,projitems,shproj}]
indent_size = 2
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
# T4 Templates Files
[*.{tt,ttinclude}]
end_of_line = crlf
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
# XML Configuration Files
[*.{xml,config,props,targets,nuspec,resx,ruleset,vsixmanifest,vsct}]
indent_size = 2
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
# JSON Files
[*.{json,json5,webmanifest}]
indent_size = 2
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
# YAML Files
[*.{yml,yaml}]
indent_size = 2
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
# Markdown Files
[*.md]
trim_trailing_whitespace = false
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
# Web Files
[*.{htm,html,js,jsm,ts,tsx,css,sass,scss,less,svg,vue}]
indent_size = 2
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
# Batch Files
[*.{cmd,bat}]
end_of_line = crlf
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
# Makefiles
[Makefile]
indent_style = tab
###############################################################################
# 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
##########################################
# File Header (Uncomment to support file headers)
# https://docs.microsoft.com/visualstudio/ide/reference/add-file-header
##########################################
dotnet_naming_style.pascal_case.capitalization = pascal_case
# [*.{cs,csx,cake,vb,vbx,tt,ttinclude}]
file_header_template = Copyright (c) Six Labors.\nLicensed under the Apache License, Version 2.0.
dotnet_naming_style.pascal_case_suffixed_with_async.capitalization = pascal_case
dotnet_naming_style.pascal_case_suffixed_with_async.required_suffix = Async
# SA1636: File header copyright text should match
# Justification: .editorconfig supports file headers. If this is changed to a value other than "none", a stylecop.json file will need to added to the project.
# dotnet_diagnostic.SA1636.severity = none
dotnet_naming_style.pascal_case_prefixed_with_i.capitalization = pascal_case
dotnet_naming_style.pascal_case_prefixed_with_i.required_prefix = I
##########################################
# .NET Language Conventions
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions
##########################################
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
# .NET Code Style Settings
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#net-code-style-settings
[*.{cs,csx,cake,vb,vbx}]
# "this." and "Me." qualifiers
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#this-and-me
dotnet_style_qualification_for_field = true:warning
dotnet_style_qualification_for_method = true:warning
dotnet_style_qualification_for_property = true:warning
dotnet_style_qualification_for_method = true:warning
dotnet_style_qualification_for_event = true:warning
# Language keywords instead of framework type names for type references
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#language-keywords
dotnet_style_predefined_type_for_locals_parameters_members = true:warning
dotnet_style_predefined_type_for_member_access = true:warning
# Modifier preferences
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#normalize-modifiers
dotnet_style_require_accessibility_modifiers = always:warning
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:warning
visual_basic_preferred_modifier_order = Partial,Default,Private,Protected,Public,Friend,NotOverridable,Overridable,MustOverride,Overloads,Overrides,MustInherit,NotInheritable,Static,Shared,Shadows,ReadOnly,WriteOnly,Dim,Const,WithEvents,Widening,Narrowing,Custom,Async:warning
dotnet_style_readonly_field = true:warning
# Parentheses preferences
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#parentheses-preferences
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:warning
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:warning
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:warning
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:suggestion
# Expression-level preferences
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#expression-level-preferences
dotnet_style_object_initializer = true:warning
dotnet_style_collection_initializer = true:warning
dotnet_style_explicit_tuple_names = true:warning
dotnet_style_prefer_inferred_tuple_names = true:warning
dotnet_style_prefer_inferred_anonymous_type_member_names = true:warning
dotnet_style_prefer_auto_properties = true:warning
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:warning
dotnet_style_prefer_conditional_expression_over_assignment = false:suggestion
dotnet_style_prefer_conditional_expression_over_return = false:suggestion
dotnet_style_prefer_compound_assignment = true:warning
# Null-checking preferences
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#null-checking-preferences
dotnet_style_coalesce_expression = true:warning
dotnet_style_null_propagation = true:warning
# Parameter preferences
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#parameter-preferences
dotnet_code_quality_unused_parameters = all:warning
# More style options (Undocumented)
# https://github.com/MicrosoftDocs/visualstudio-docs/issues/3641
dotnet_style_operator_placement_when_wrapping = end_of_line
# https://github.com/dotnet/roslyn/pull/40070
dotnet_style_prefer_simplified_interpolation = true:warning
dotnet_style_readonly_field = true:suggestion
dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent
# C# Code Style Settings
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#c-code-style-settings
[*.{cs,csx,cake}]
# Implicit and explicit types
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#implicit-and-explicit-types
csharp_style_var_for_built_in_types = never
csharp_style_var_when_type_is_apparent = true:warning
csharp_style_var_elsewhere = false:warning
# Expression-bodied members
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#expression-bodied-members
csharp_style_expression_bodied_methods = true:warning
csharp_style_expression_bodied_constructors = true:warning
csharp_style_expression_bodied_operators = true:warning
csharp_style_expression_bodied_properties = true:warning
csharp_style_expression_bodied_indexers = true:warning
csharp_style_expression_bodied_accessors = true:warning
csharp_style_expression_bodied_lambdas = true:warning
csharp_style_expression_bodied_local_functions = true:warning
# Pattern matching
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#pattern-matching
csharp_style_pattern_matching_over_is_with_cast_check = true:warning
csharp_style_pattern_matching_over_as_with_null_check = true:warning
# Inlined variable declarations
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#inlined-variable-declarations
csharp_style_inlined_variable_declaration = true:warning
# Expression-level preferences
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#expression-level-preferences
csharp_prefer_simple_default_expression = true:warning
# "Null" checking preferences
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#c-null-checking-preferences
csharp_style_throw_expression = true:warning
csharp_style_conditional_delegate_call = true:warning
# Code block preferences
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#code-block-preferences
csharp_prefer_braces = true:warning
# Unused value preferences
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#unused-value-preferences
csharp_style_unused_value_expression_statement_preference = discard_variable:suggestion
csharp_style_unused_value_assignment_preference = discard_variable:suggestion
# Index and range preferences
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#index-and-range-preferences
csharp_style_prefer_index_operator = true:warning
csharp_style_prefer_range_operator = true:warning
# Miscellaneous preferences
# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#miscellaneous-preferences
csharp_style_deconstructed_variable_declaration = true:warning
csharp_style_pattern_local_over_anonymous_function = true:warning
csharp_using_directive_placement = outside_namespace:warning
csharp_prefer_static_local_function = true:warning
csharp_prefer_simple_using_statement = true:suggestion
###############################################################################
# Set dotnet style options to:
# suggest removing all unused parameters
###############################################################################
[*.cs]
dotnet_code_quality_unused_parameters = all:suggestion
##########################################
# .NET Formatting Conventions
# https://docs.microsoft.com/visualstudio/ide/editorconfig-code-style-settings-reference#formatting-conventions
##########################################
###############################################################################
# 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]
# Organize usings
# https://docs.microsoft.com/visualstudio/ide/editorconfig-formatting-conventions#organize-using-directives
dotnet_sort_system_directives_first = true
# Newline options
# https://docs.microsoft.com/visualstudio/ide/editorconfig-formatting-conventions#new-line-options
csharp_new_line_before_open_brace = all
csharp_new_line_before_else = true
csharp_new_line_before_catch = true
csharp_new_line_before_finally = true
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_between_query_expression_clauses = true
# Indentation options
# https://docs.microsoft.com/visualstudio/ide/editorconfig-formatting-conventions#indentation-options
csharp_indent_case_contents = true
csharp_indent_switch_labels = true
csharp_indent_labels = no_change
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]
# Spacing options
# https://docs.microsoft.com/visualstudio/ide/editorconfig-formatting-conventions#spacing-options
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_between_parentheses = false
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_after_colon_in_inheritance_clause = true
csharp_space_around_binary_operators = before_and_after
csharp_space_between_method_declaration_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_method_call_parameter_list_parentheses = false
csharp_space_between_method_call_empty_parameter_list_parentheses = false
csharp_space_between_method_call_name_and_opening_parenthesis = false
csharp_space_after_comma = true
csharp_space_before_comma = false
csharp_space_after_dot = false
csharp_space_before_dot = false
csharp_space_after_semicolon_in_for_statement = true
csharp_space_before_semicolon_in_for_statement = false
csharp_space_around_declaration_statements = false
csharp_space_before_open_square_brackets = false
csharp_space_between_empty_square_brackets = false
csharp_space_between_square_brackets = false
# Wrapping options
# https://docs.microsoft.com/visualstudio/ide/editorconfig-formatting-conventions#wrap-options
csharp_preserve_single_line_statements = false
csharp_preserve_single_line_blocks = true
###############################################################################
# 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
##########################################
# .NET Naming Conventions
# https://docs.microsoft.com/visualstudio/ide/editorconfig-naming-conventions
##########################################
csharp_style_conditional_delegate_call = true:suggestion
csharp_style_deconstructed_variable_declaration = true:suggestion
[*.{cs,csx,cake,vb,vbx}]
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
##########################################
# Styles
##########################################
csharp_style_inlined_variable_declaration = true:suggestion
# camel_case_style - Define the camelCase style
dotnet_naming_style.camel_case_style.capitalization = camel_case
# pascal_case_style - Define the PascalCase style
dotnet_naming_style.pascal_case_style.capitalization = pascal_case
# first_upper_style - The first character must start with an upper-case character
dotnet_naming_style.first_upper_style.capitalization = first_word_upper
# prefix_interface_with_i_style - Interfaces must be PascalCase and the first character of an interface must be an 'I'
dotnet_naming_style.prefix_interface_with_i_style.capitalization = pascal_case
dotnet_naming_style.prefix_interface_with_i_style.required_prefix = I
# prefix_type_parameters_with_t_style - Generic Type Parameters must be PascalCase and the first character must be a 'T'
dotnet_naming_style.prefix_type_parameters_with_t_style.capitalization = pascal_case
dotnet_naming_style.prefix_type_parameters_with_t_style.required_prefix = T
# disallowed_style - Anything that has this style applied is marked as disallowed
dotnet_naming_style.disallowed_style.capitalization = pascal_case
dotnet_naming_style.disallowed_style.required_prefix = ____RULE_VIOLATION____
dotnet_naming_style.disallowed_style.required_suffix = ____RULE_VIOLATION____
# internal_error_style - This style should never occur... if it does, it indicates a bug in file or in the parser using the file
dotnet_naming_style.internal_error_style.capitalization = pascal_case
dotnet_naming_style.internal_error_style.required_prefix = ____INTERNAL_ERROR____
dotnet_naming_style.internal_error_style.required_suffix = ____INTERNAL_ERROR____
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
##########################################
# .NET Design Guideline Field Naming Rules
# Naming rules for fields follow the .NET Framework design guidelines
# https://docs.microsoft.com/dotnet/standard/design-guidelines/index
##########################################
csharp_style_throw_expression = true:suggestion
# All public/protected/protected_internal constant fields must be PascalCase
# https://docs.microsoft.com/dotnet/standard/design-guidelines/field
dotnet_naming_symbols.public_protected_constant_fields_group.applicable_accessibilities = public, protected, protected_internal
dotnet_naming_symbols.public_protected_constant_fields_group.required_modifiers = const
dotnet_naming_symbols.public_protected_constant_fields_group.applicable_kinds = field
dotnet_naming_rule.public_protected_constant_fields_must_be_pascal_case_rule.symbols = public_protected_constant_fields_group
dotnet_naming_rule.public_protected_constant_fields_must_be_pascal_case_rule.style = pascal_case_style
dotnet_naming_rule.public_protected_constant_fields_must_be_pascal_case_rule.severity = warning
csharp_style_unused_value_expression_statement_preference = discard_variable:silent
csharp_style_unused_value_assignment_preference = discard_variable:suggestion
# All public/protected/protected_internal static readonly fields must be PascalCase
# https://docs.microsoft.com/dotnet/standard/design-guidelines/field
dotnet_naming_symbols.public_protected_static_readonly_fields_group.applicable_accessibilities = public, protected, protected_internal
dotnet_naming_symbols.public_protected_static_readonly_fields_group.required_modifiers = static, readonly
dotnet_naming_symbols.public_protected_static_readonly_fields_group.applicable_kinds = field
dotnet_naming_rule.public_protected_static_readonly_fields_must_be_pascal_case_rule.symbols = public_protected_static_readonly_fields_group
dotnet_naming_rule.public_protected_static_readonly_fields_must_be_pascal_case_rule.style = pascal_case_style
dotnet_naming_rule.public_protected_static_readonly_fields_must_be_pascal_case_rule.severity = warning
csharp_style_var_for_built_in_types = false:warning
csharp_style_var_elsewhere = false:warning
csharp_style_var_when_type_is_apparent = true:warning
# No other public/protected/protected_internal fields are allowed
# https://docs.microsoft.com/dotnet/standard/design-guidelines/field
dotnet_naming_symbols.other_public_protected_fields_group.applicable_accessibilities = public, protected, protected_internal
dotnet_naming_symbols.other_public_protected_fields_group.applicable_kinds = field
dotnet_naming_rule.other_public_protected_fields_disallowed_rule.symbols = other_public_protected_fields_group
dotnet_naming_rule.other_public_protected_fields_disallowed_rule.style = disallowed_style
dotnet_naming_rule.other_public_protected_fields_disallowed_rule.severity = error
##########################################
# StyleCop Field Naming Rules
# Naming rules for fields follow the StyleCop analyzers
# This does not override any rules using disallowed_style above
# https://github.com/DotNetAnalyzers/StyleCopAnalyzers
##########################################
# All constant fields must be PascalCase
# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1303.md
dotnet_naming_symbols.stylecop_constant_fields_group.applicable_accessibilities = public, internal, protected_internal, protected, private_protected, private
dotnet_naming_symbols.stylecop_constant_fields_group.required_modifiers = const
dotnet_naming_symbols.stylecop_constant_fields_group.applicable_kinds = field
dotnet_naming_rule.stylecop_constant_fields_must_be_pascal_case_rule.symbols = stylecop_constant_fields_group
dotnet_naming_rule.stylecop_constant_fields_must_be_pascal_case_rule.style = pascal_case_style
dotnet_naming_rule.stylecop_constant_fields_must_be_pascal_case_rule.severity = warning
# All static readonly fields must be PascalCase
# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1311.md
dotnet_naming_symbols.stylecop_static_readonly_fields_group.applicable_accessibilities = public, internal, protected_internal, protected, private_protected, private
dotnet_naming_symbols.stylecop_static_readonly_fields_group.required_modifiers = static, readonly
dotnet_naming_symbols.stylecop_static_readonly_fields_group.applicable_kinds = field
dotnet_naming_rule.stylecop_static_readonly_fields_must_be_pascal_case_rule.symbols = stylecop_static_readonly_fields_group
dotnet_naming_rule.stylecop_static_readonly_fields_must_be_pascal_case_rule.style = pascal_case_style
dotnet_naming_rule.stylecop_static_readonly_fields_must_be_pascal_case_rule.severity = warning
# No non-private instance fields are allowed
# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1401.md
dotnet_naming_symbols.stylecop_fields_must_be_private_group.applicable_accessibilities = public, internal, protected_internal, protected, private_protected
dotnet_naming_symbols.stylecop_fields_must_be_private_group.applicable_kinds = field
dotnet_naming_rule.stylecop_instance_fields_must_be_private_rule.symbols = stylecop_fields_must_be_private_group
dotnet_naming_rule.stylecop_instance_fields_must_be_private_rule.style = disallowed_style
dotnet_naming_rule.stylecop_instance_fields_must_be_private_rule.severity = error
# Private fields must be camelCase
# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1306.md
dotnet_naming_symbols.stylecop_private_fields_group.applicable_accessibilities = private
dotnet_naming_symbols.stylecop_private_fields_group.applicable_kinds = field
dotnet_naming_rule.stylecop_private_fields_must_be_camel_case_rule.symbols = stylecop_private_fields_group
dotnet_naming_rule.stylecop_private_fields_must_be_camel_case_rule.style = camel_case_style
dotnet_naming_rule.stylecop_private_fields_must_be_camel_case_rule.severity = warning
# Local variables must be camelCase
# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1312.md
dotnet_naming_symbols.stylecop_local_fields_group.applicable_accessibilities = local
dotnet_naming_symbols.stylecop_local_fields_group.applicable_kinds = local
dotnet_naming_rule.stylecop_local_fields_must_be_camel_case_rule.symbols = stylecop_local_fields_group
dotnet_naming_rule.stylecop_local_fields_must_be_camel_case_rule.style = camel_case_style
dotnet_naming_rule.stylecop_local_fields_must_be_camel_case_rule.severity = silent
# This rule should never fire. However, it's included for at least two purposes:
# First, it helps to understand, reason about, and root-case certain types of issues, such as bugs in .editorconfig parsers.
# Second, it helps to raise immediate awareness if a new field type is added (as occurred recently in C#).
dotnet_naming_symbols.sanity_check_uncovered_field_case_group.applicable_accessibilities = *
dotnet_naming_symbols.sanity_check_uncovered_field_case_group.applicable_kinds = field
dotnet_naming_rule.sanity_check_uncovered_field_case_rule.symbols = sanity_check_uncovered_field_case_group
dotnet_naming_rule.sanity_check_uncovered_field_case_rule.style = internal_error_style
dotnet_naming_rule.sanity_check_uncovered_field_case_rule.severity = error
##########################################
# Other Naming Rules
##########################################
# All of the following must be PascalCase:
# - Namespaces
# https://docs.microsoft.com/dotnet/standard/design-guidelines/names-of-namespaces
# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1300.md
# - Classes and Enumerations
# https://docs.microsoft.com/dotnet/standard/design-guidelines/names-of-classes-structs-and-interfaces
# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1300.md
# - Delegates
# https://docs.microsoft.com/dotnet/standard/design-guidelines/names-of-classes-structs-and-interfaces#names-of-common-types
# - Constructors, Properties, Events, Methods
# https://docs.microsoft.com/dotnet/standard/design-guidelines/names-of-type-members
dotnet_naming_symbols.element_group.applicable_kinds = namespace, class, enum, struct, delegate, event, method, property
dotnet_naming_rule.element_rule.symbols = element_group
dotnet_naming_rule.element_rule.style = pascal_case_style
dotnet_naming_rule.element_rule.severity = warning
# Interfaces use PascalCase and are prefixed with uppercase 'I'
# https://docs.microsoft.com/dotnet/standard/design-guidelines/names-of-classes-structs-and-interfaces
dotnet_naming_symbols.interface_group.applicable_kinds = interface
dotnet_naming_rule.interface_rule.symbols = interface_group
dotnet_naming_rule.interface_rule.style = prefix_interface_with_i_style
dotnet_naming_rule.interface_rule.severity = warning
# Generics Type Parameters use PascalCase and are prefixed with uppercase 'T'
# https://docs.microsoft.com/dotnet/standard/design-guidelines/names-of-classes-structs-and-interfaces
dotnet_naming_symbols.type_parameter_group.applicable_kinds = type_parameter
dotnet_naming_rule.type_parameter_rule.symbols = type_parameter_group
dotnet_naming_rule.type_parameter_rule.style = prefix_type_parameters_with_t_style
dotnet_naming_rule.type_parameter_rule.severity = warning
# Function parameters use camelCase
# https://docs.microsoft.com/dotnet/standard/design-guidelines/naming-parameters
dotnet_naming_symbols.parameters_group.applicable_kinds = parameter
dotnet_naming_rule.parameters_rule.symbols = parameters_group
dotnet_naming_rule.parameters_rule.style = camel_case_style
dotnet_naming_rule.parameters_rule.severity = warning
##########################################
# License
##########################################
# The following applies as to the .editorconfig file ONLY, and is
# included below for reference, per the requirements of the license
# corresponding to this .editorconfig file.
# See: https://github.com/RehanSaeed/EditorConfig
#
# MIT License
#
# Copyright (c) 2017-2019 Muhammad Rehan Saeed
# Copyright (c) 2019 Henry Gabryjelski
#
# Permission is hereby granted, free of charge, to any
# person obtaining a copy of this software and associated
# documentation files (the "Software"), to deal in the
# Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute,
# sublicense, and/or sell copies of the Software, and to permit
# persons to whom the Software is furnished to do so, subject
# to the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
##########################################

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

@ -96,22 +96,26 @@
*.gif binary
*.jpg binary
*.ktx binary
*.otf binary
*.pbm binary
*.pdf binary
*.png binary
*.ppt binary
*.pptx binary
*.pvr binary
*.ttf binary
*.snk binary
*.tga binary
*.tif binary
*.tiff binary
*.ttc binary
*.ttf binary
*.wbmp binary
*.webp binary
*.woff binary
*.woff2 binary
*.xls binary
*.xlsx binary
###############################################################################
# Set explicit file behavior to:
# diff as plain text

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

@ -10,106 +10,12 @@
that is done by the file that imports us.
-->
<!-- Default settings that are used by other settings -->
<PropertyGroup>
<BaseArtifactsPath>$(MSBuildThisFileDirectory)artifacts/</BaseArtifactsPath>
<BaseArtifactsPathSuffix>$(ImageSharpProjectCategory)/$(MSBuildProjectName)</BaseArtifactsPathSuffix>
<RepositoryUrl Condition="'$(RepositoryUrl)' == ''">https://github.com/SixLabors/ImageSharp.Drawing/</RepositoryUrl>
<!-- This MUST be defined before importing props. -->
<SixLaborsSolutionDirectory>$(MSBuildThisFileDirectory)</SixLaborsSolutionDirectory>
</PropertyGroup>
<!-- Default settings that explicitly differ from the Sdk.props defaults -->
<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DebugType>portable</DebugType>
<DebugType Condition="'$(codecov)' != ''">full</DebugType>
<NullableContextOptions>disable</NullableContextOptions>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
<SuppressNETCoreSdkPreviewMessage>true</SuppressNETCoreSdkPreviewMessage>
</PropertyGroup>
<!--
https://apisof.net/
+===================+=======+==========+=====================+=============+=================+====================+==============+
| SUPPORTS | MATHF | HASHCODE | EXTENDED_INTRINSICS | SPAN_STREAM | ENCODING_STRING | RUNTIME_INTRINSICS | CODECOVERAGE |
+===================+=======+==========+=====================+=============+=================+====================+==============+
| netcoreapp3.1 | Y | Y | Y | Y | Y | Y | Y |
| netcoreapp2.1 | Y | Y | Y | Y | Y | N | Y |
| netcoreapp2.0 | Y | N | N | N | N | N | Y |
| netstandard2.1 | Y | Y | N | Y | Y | N | Y |
| netstandard2.0 | N | N | N | N | N | N | Y |
| netstandard1.3 | N | N | N | N | N | N | N |
| net472 | N | N | Y | N | N | N | Y |
+===================+=======+==========+=====================+=============+=================+====================+==============+
-->
<PropertyGroup Condition="'$(TargetFramework)' == 'netcoreapp3.1'">
<DefineConstants>$(DefineConstants);SUPPORTS_MATHF;SUPPORTS_HASHCODE;SUPPORTS_EXTENDED_INTRINSICS;SUPPORTS_SPAN_STREAM;SUPPORTS_ENCODING_STRING;SUPPORTS_RUNTIME_INTRINSICS;SUPPORTS_CODECOVERAGE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'netcoreapp2.1'">
<DefineConstants>$(DefineConstants);SUPPORTS_MATHF;SUPPORTS_HASHCODE;SUPPORTS_EXTENDED_INTRINSICS;SUPPORTS_SPAN_STREAM;SUPPORTS_ENCODING_STRING;SUPPORTS_CODECOVERAGE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'netcoreapp2.0'">
<DefineConstants>$(DefineConstants);SUPPORTS_MATHF;SUPPORTS_CODECOVERAGE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'netstandard2.1'">
<DefineConstants>$(DefineConstants);SUPPORTS_MATHF;SUPPORTS_HASHCODE;SUPPORTS_SPAN_STREAM;SUPPORTS_ENCODING_STRING;SUPPORTS_CODECOVERAGE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<DefineConstants>$(DefineConstants);SUPPORTS_CODECOVERAGE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'net472'">
<DefineConstants>$(DefineConstants);SUPPORTS_EXTENDED_INTRINSICS;SUPPORTS_CODECOVERAGE</DefineConstants>
</PropertyGroup>
<!-- Default settings that explicitly differ from the Sdk.targets defaults-->
<PropertyGroup>
<Authors>Six Labors and contributors</Authors>
<Company>Six Labors</Company>
<PackageOutputPath>$(BaseArtifactsPath)pkg/$(BaseArtifactsPathSuffix)/$(Configuration)/</PackageOutputPath>
<Product>SixLabors.ImageSharp.Drawing</Product>
<VersionPrefix>0.0.1</VersionPrefix>
<VersionPrefix Condition="'$(packageversion)' != ''">$(PackageVersion)</VersionPrefix>
<VersionSuffix></VersionSuffix>
</PropertyGroup>
<!--MinVer Properties for versioning-->
<PropertyGroup>
<MinVerTagPrefix>v</MinVerTagPrefix>
<MinVerVerbosity>normal</MinVerVerbosity>
</PropertyGroup>
<!-- Default settings that are otherwise undefined -->
<PropertyGroup>
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)shared-infrastructure/SixLabors.snk</AssemblyOriginatorKeyFile>
<Copyright>Copyright © Six Labors and Contributors</Copyright>
<Features>strict;IOperation</Features>
<HighEntropyVA>true</HighEntropyVA>
<LangVersion>8.0</LangVersion>
<NeutralLanguage>en</NeutralLanguage>
<OverwriteReadOnlyFiles>true</OverwriteReadOnlyFiles>
<PackageIcon>sixlabors.imagesharp.drawing.128.png</PackageIcon>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
<PackageProjectUrl>$(RepositoryUrl)</PackageProjectUrl>
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
<RepositoryType>git</RepositoryType>
<RestoreSources>
https://www.myget.org/F/sixlabors/api/v3/index.json;
https://api.nuget.org/v3/index.json;
</RestoreSources>
<SixLaborsPublicKey>00240000048000009400000006020000002400005253413100040000010001000147e6fe6766715eec6cfed61f1e7dcdbf69748a3e355c67e9d8dfd953acab1d5e012ba34b23308166fdc61ee1d0390d5f36d814a6091dd4b5ed9eda5a26afced924c683b4bfb4b3d64b0586a57eff9f02b1f84e3cb0ddd518bd1697f2c84dcbb97eb8bb5c7801be12112ed0ec86db934b0e9a5171e6bb1384b6d2f7d54dfa97</SixLaborsPublicKey>
<UseSharedCompilation>true</UseSharedCompilation>
<SignAssembly>true</SignAssembly>
</PropertyGroup>
<!-- Package references and additional files which are consumed by all projects -->
<ItemGroup>
<PackageReference Include="Microsoft.Net.Compilers.Toolset" IsImplicitlyDefined="true" />
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" IsImplicitlyDefined="true" />
<!--TODO: Enable this once tests Stylecop issues are fixed-->
<!--<PackageReference Include="StyleCop.Analyzers" IsImplicitlyDefined="true" />-->
<AdditionalFiles Include="$(MSBuildThisFileDirectory)shared-infrastructure\stylecop.json" />
<!--NuGet package icon source-->
<None Include="$(MSBuildThisFileDirectory)shared-infrastructure\branding\icons\imagesharp.drawing\sixlabors.imagesharp.drawing.128.png" Pack="true" PackagePath="" />
</ItemGroup>
<!-- Import the shared global .props file -->
<Import Project="$(MSBuildThisFileDirectory)shared-infrastructure\msbuild\props\SixLabors.Global.props" />
</Project>

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

@ -5,29 +5,12 @@
Directory.Build.targets is automatically picked up and imported by
Microsoft.Common.targets. This file needs to exist, even if empty so that
files in the parent directory tree, with the same name, are not imported
instead. The import fairly late and most other props/targets will have been
instead. They import fairly late and most other props/targets will have been
imported beforehand. We also don't need to add ourselves to
MSBuildAllProjects, as that is done by the file that imports us.
-->
<!-- Settings that append the existing setting value -->
<PropertyGroup>
<DefineConstants>$(DefineConstants);$(OS)</DefineConstants>
</PropertyGroup>
<!-- Package versions for package references across all projects -->
<ItemGroup>
<!--Global Dependencies-->
<PackageReference Update="Microsoft.Net.Compilers.Toolset" Version="3.3.1" PrivateAssets="All" />
<PackageReference Update="Microsoft.NETFramework.ReferenceAssemblies" PrivateAssets="All" Version="1.0.0" />
<PackageReference Update="StyleCop.Analyzers" PrivateAssets="All" Version="1.1.118" />
<PackageReference Update="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All"/>
<PackageReference Update="MinVer" PrivateAssets="All" Version="2.3.0" />
<!--Src Dependencies-->
<PackageReference Update="SixLabors.Fonts" Version="1.0.0-beta0013" />
<PackageReference Update="SixLabors.ImageSharp" Version="1.0.2" />
</ItemGroup>
<!-- Import the shared global .props file -->
<Import Project="$(MSBuildThisFileDirectory)shared-infrastructure\msbuild\targets\SixLabors.Global.targets"/>
</Project>

@ -1 +1 @@
Subproject commit 93bd7d17ebb029d995d7fa69d4b4e850ec861c1e
Subproject commit 3ae9179b3ed0ebaffe7404ac57fe0d04eeabcf7e

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

@ -5,44 +5,23 @@
Directory.Build.props is automatically picked up and imported by
Microsoft.Common.props. This file needs to exist, even if empty so that
files in the parent directory tree, with the same name, are not imported
instead. The import fairly early and only Sdk.props will have been
instead. They import fairly early and only Sdk.props will have been
imported beforehand. We also don't need to add ourselves to
MSBuildAllProjects, as that is done by the file that imports us.
-->
<PropertyGroup>
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileDirectory)..\Directory.Build.props</MSBuildAllProjects>
<ImageSharpProjectCategory>src</ImageSharpProjectCategory>
</PropertyGroup>
<!-- Import the shared src .props file -->
<Import Project="$(MSBuildThisFileDirectory)..\shared-infrastructure\msbuild\props\SixLabors.Src.props" />
<!-- Import the solution .props file. -->
<Import Project="$(MSBuildThisFileDirectory)..\Directory.Build.props" />
<PropertyGroup>
<CodeAnalysisRuleSet>$(MSBuildThisFileDirectory)..\shared-infrastructure\SixLabors.ruleset</CodeAnalysisRuleSet>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
<!-- Compilation properties. -->
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<!--Add deterministic builds in CI-->
<PropertyGroup Condition="'$(GITHUB_ACTIONS)' == 'true'">
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
</PropertyGroup>
<PropertyGroup>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<!-- Build symbol package (.snupkg) to distribute the PDB containing Source Link -->
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>
<ItemGroup>
<!--TODO: Delete this once tests Stylecop issues are fixed-->
<PackageReference Include="StyleCop.Analyzers" IsImplicitlyDefined="true" />
<!-- DynamicProxyGenAssembly2 is needed so Moq can use our internals -->
<InternalsVisibleTo Include="DynamicProxyGenAssembly2" Key="0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7" />
<InternalsVisibleTo Include="SixLabors.ImageSharp.Tests" Key="$(SixLaborsPublicKey)" />

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

@ -5,62 +5,15 @@
Directory.Build.targets is automatically picked up and imported by
Microsoft.Common.targets. This file needs to exist, even if empty so that
files in the parent directory tree, with the same name, are not imported
instead. The import fairly late and most other props/targets will have
instead. They import fairly late and most other props/targets will have
been imported beforehand. We also don't need to add ourselves to
MSBuildAllProjects, as that is done by the file that imports us.
-->
<PropertyGroup>
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileDirectory)..\Directory.Build.targets</MSBuildAllProjects>
</PropertyGroup>
<!-- Import the shared src .targets file -->
<Import Project="$(MSBuildThisFileDirectory)..\shared-infrastructure\msbuild\targets\SixLabors.Src.targets" />
<!-- Import the solution .targets file. -->
<Import Project="$(MSBuildThisFileDirectory)..\Directory.Build.targets" />
<PropertyGroup>
<GeneratedInternalsVisibleToFile Condition="'$(GeneratedInternalsVisibleToFile)' == ''">$(IntermediateOutputPath)$(MSBuildProjectName).InternalsVisibleTo$(DefaultLanguageSourceExtension)</GeneratedInternalsVisibleToFile>
</PropertyGroup>
<!-- Workaround for running Coverlet with Determenistic builds -->
<!-- https://github.com/coverlet-coverage/coverlet/blob/master/Documentation/DeterministicBuild.md -->
<Target Name="CoverletGetPathMap"
DependsOnTargets="InitializeSourceRootMappedPaths"
Returns="@(_LocalTopLevelSourceRoot)"
Condition="'$(DeterministicSourcePaths)' == 'true'">
<ItemGroup>
<_LocalTopLevelSourceRoot Include="@(SourceRoot)" Condition="'%(SourceRoot.NestedRoot)' == ''"/>
</ItemGroup>
</Target>
<ItemDefinitionGroup>
<InternalsVisibleTo>
<Visible>false</Visible>
</InternalsVisibleTo>
</ItemDefinitionGroup>
<Target Name="GenerateInternalsVisibleTo"
BeforeTargets="CoreCompile"
DependsOnTargets="PrepareForBuild;CoreGenerateInternalsVisibleTo"
Condition="'@(InternalsVisibleTo)' != ''" />
<Target Name="CoreGenerateInternalsVisibleTo"
Condition="'$(Language)' == 'VB' or '$(Language)' == 'C#'"
Inputs="$(MSBuildAllProjects)"
Outputs="$(GeneratedInternalsVisibleToFile)">
<CreateItem Include="System.Runtime.CompilerServices.InternalsVisibleToAttribute" AdditionalMetadata="_Parameter1=%(InternalsVisibleTo.Identity)" Condition="'%(InternalsVisibleTo.Key)' == ''">
<Output TaskParameter="Include" ItemName="InternalsVisibleToAttribute" />
</CreateItem>
<CreateItem Include="System.Runtime.CompilerServices.InternalsVisibleToAttribute" AdditionalMetadata="_Parameter1=%(InternalsVisibleTo.Identity), PublicKey=%(InternalsVisibleTo.Key)" Condition="'%(InternalsVisibleTo.Key)' != ''">
<Output TaskParameter="Include" ItemName="InternalsVisibleToAttribute" />
</CreateItem>
<WriteCodeFragment AssemblyAttributes="@(InternalsVisibleToAttribute)" Language="$(Language)" OutputFile="$(GeneratedInternalsVisibleToFile)">
<Output TaskParameter="OutputFile" ItemName="Compile" />
<Output TaskParameter="OutputFile" ItemName="FileWrites" />
</WriteCodeFragment>
</Target>
<!-- Empty target so that `dotnet test` will work on the solution -->
<!-- https://github.com/Microsoft/vstest/issues/411 -->
<Target Name="VSTest" Condition="'$(IsTestProject)' == 'true'"/>
</Project>

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

@ -4,19 +4,24 @@
<PropertyGroup>
<AssemblyName>SixLabors.ImageSharp.Drawing</AssemblyName>
<AssemblyTitle>SixLabors.ImageSharp.Drawing</AssemblyTitle>
<Description>An extension to ImageSharp that allows the drawing of images, paths, and text.</Description>
<PackageId>SixLabors.ImageSharp.Drawing</PackageId>
<PackageTags>Image Draw Shape Path Font</PackageTags>
<RootNamespace>SixLabors.ImageSharp.Drawing</RootNamespace>
<PackageId>SixLabors.ImageSharp.Drawing</PackageId>
<PackageIcon>sixlabors.imagesharp.drawing.128.png</PackageIcon>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
<RepositoryUrl Condition="'$(RepositoryUrl)' == ''">https://github.com/SixLabors/ImageSharp.Drawing/</RepositoryUrl>
<PackageProjectUrl>$(RepositoryUrl)</PackageProjectUrl>
<PackageTags>Image Draw Shape Path Font</PackageTags>
<Description>An extension to ImageSharp that allows the drawing of images, paths, and text.</Description>
<TargetFrameworks>netcoreapp3.1;netcoreapp2.1;netstandard2.1;netstandard2.0;netstandard1.3;net472</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="SixLabors.Fonts" />
<PackageReference Include="SixLabors.ImageSharp" />
<PackageReference Include="Microsoft.SourceLink.GitHub" />
<PackageReference Include="MinVer" PrivateAssets="All" />
<None Include="..\..\shared-infrastructure\branding\icons\imagesharp.drawing\sixlabors.imagesharp.drawing.128.png" Pack="true" PackagePath="" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="SixLabors.Fonts" Version="1.0.0-beta0013"/>
<PackageReference Include="SixLabors.ImageSharp" Version="1.0.2" />
</ItemGroup>
<Import Project="..\..\shared-infrastructure\src\SharedInfrastructure\SharedInfrastructure.projitems" Label="Shared" />

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

@ -5,36 +5,15 @@
Directory.Build.props is automatically picked up and imported by
Microsoft.Common.props. This file needs to exist, even if empty so that
files in the parent directory tree, with the same name, are not imported
instead. The import fairly early and only Sdk.props will have been
instead. They import fairly early and only Sdk.props will have been
imported beforehand. We also don't need to add ourselves to
MSBuildAllProjects, as that is done by the file that imports us.
-->
<PropertyGroup>
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileDirectory)..\Directory.Build.props</MSBuildAllProjects>
<ImageSharpProjectCategory>tests</ImageSharpProjectCategory>
</PropertyGroup>
<PropertyGroup>
<CodeAnalysisRuleSet>$(MSBuildThisFileDirectory)..\shared-infrastructure\SixLabors.Tests.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup>
<CodeAnalysisRuleSet>$(MSBuildThisFileDirectory)..\shared-infrastructure\SixLabors.Tests.ruleset</CodeAnalysisRuleSet>
<!--TODO: We should remove all obsolete code from the solution-->
<NoWarn>$(NoWarn);CS0618</NoWarn>
</PropertyGroup>
<!-- Import the shared tests .props file -->
<Import Project="$(MSBuildThisFileDirectory)..\shared-infrastructure\msbuild\props\SixLabors.Tests.props" />
<!-- Import the solution .props file. -->
<Import Project="$(MSBuildThisFileDirectory)..\Directory.Build.props" />
<ItemGroup Condition="'$(IsTestProject)' == 'true'">
<PackageReference Include="Microsoft.NET.Test.Sdk" IsImplicitlyDefined="true" />
<PackageReference Include="xunit" IsImplicitlyDefined="true" />
<PackageReference Include="xunit.runner.visualstudio" IsImplicitlyDefined="true" />
</ItemGroup>
<ItemGroup Condition="'$(codecov)' == 'true' AND '$(IsTestProject)' == 'true'">
<PackageReference Include="coverlet.collector" IsImplicitlyDefined="true" />
</ItemGroup>
</Project>

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

@ -5,34 +5,23 @@
Directory.Build.targets is automatically picked up and imported by
Microsoft.Common.targets. This file needs to exist, even if empty so that
files in the parent directory tree, with the same name, are not imported
instead. The import fairly late and most other props/targets will have
instead. They import fairly late and most other props/targets will have
been imported beforehand. We also don't need to add ourselves to
MSBuildAllProjects, as that is done by the file that imports us.
-->
<PropertyGroup>
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileDirectory)..\Directory.Build.targets</MSBuildAllProjects>
</PropertyGroup>
<!-- Import the shared tests .targets file -->
<Import Project="$(MSBuildThisFileDirectory)..\shared-infrastructure\msbuild\targets\SixLabors.Tests.targets" />
<!-- Import the solution .targets file. -->
<Import Project="$(MSBuildThisFileDirectory)..\Directory.Build.targets" />
<!-- Tool versions for tool references across all projects -->
<ItemGroup Condition="'$(IsTestProject)' == 'true'">
<!--dotnet tools does not have an x86 runner. You have to use separate SDKs-->
<!--https://github.com/actions/setup-dotnet/issues/72-->
<DotNetCliToolReference Update="dotnet-xunit" Version="2.3.1" />
</ItemGroup>
<ItemGroup>
<!--Test Dependencies-->
<!-- Test Dependencies -->
<PackageReference Update="BenchmarkDotNet" Version="0.12.1" />
<PackageReference Update="coverlet.collector" Version="1.3.0" PrivateAssets="All"/>
<PackageReference Update="Magick.NET-Q16-AnyCPU" Version="7.14.4" />
<PackageReference Update="Microsoft.NET.Test.Sdk" Version="16.5.0-preview-20200116-01" />
<PackageReference Update="Moq" Version="4.10.0" />
<PackageReference Update="Magick.NET-Q16-AnyCPU" Version="7.22.0" />
<PackageReference Update="Moq" Version="4.14.6" />
<PackageReference Update="System.Drawing.Common" Version="4.7.0" />
<PackageReference Update="xunit" Version="2.4.1" />
<PackageReference Update="xunit.runner.visualstudio" Version="2.4.1" />
<PackageReference Update="GeoJSON.Net" Version="1.2.19" />
<PackageReference Update="SkiaSharp" Version="2.80.2" />
</ItemGroup>

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

@ -33,11 +33,13 @@ namespace SixLabors.ImageSharp.Drawing.Benchmarks
private SKSurface skSurface;
protected abstract int Width { get; }
protected abstract int Height { get; }
protected abstract float Thickness { get; }
protected virtual PointF[][] GetPoints(FeatureCollection features) =>
features.Features.SelectMany(f => PolygonFactory.GetGeoJsonPoints(f, Matrix3x2.CreateScale(60, 60))).ToArray();
features.Features.SelectMany(f => PolygonFactory.GetGeoJsonPoints(f, Matrix3x2.CreateScale(60, 60))).ToArray();
[GlobalSetup]
public void Setup()
@ -46,28 +48,27 @@ namespace SixLabors.ImageSharp.Drawing.Benchmarks
FeatureCollection featureCollection = JsonConvert.DeserializeObject<FeatureCollection>(jsonContent);
this.points = this.GetPoints(featureCollection);
this.sdPoints = this.points.Select(pts => pts.Select(p => new SDPointF(p.X, p.Y)).ToArray()).ToArray();
this.skPath = new SKPath();
foreach (PointF[] ptArr in this.points.Where(pts => pts.Length > 2))
{
skPath.MoveTo(ptArr[0].X, ptArr[1].Y);
this.skPath.MoveTo(ptArr[0].X, ptArr[1].Y);
for (int i = 1; i < ptArr.Length; i++)
{
skPath.LineTo(ptArr[i].X, ptArr[i].Y);
this.skPath.LineTo(ptArr[i].X, ptArr[i].Y);
}
skPath.LineTo(ptArr[0].X, ptArr[1].Y);
this.skPath.LineTo(ptArr[0].X, ptArr[1].Y);
}
this.image = new Image<Rgba32>(Width, Height);
this.sdBitmap = new Bitmap(Width, Height);
this.image = new Image<Rgba32>(this.Width, this.Height);
this.sdBitmap = new Bitmap(this.Width, this.Height);
this.sdGraphics = Graphics.FromImage(this.sdBitmap);
this.sdGraphics.InterpolationMode = InterpolationMode.Default;
this.sdGraphics.SmoothingMode = SmoothingMode.AntiAlias;
this.skSurface = SKSurface.Create(new SKImageInfo(Width, Height));
this.skSurface = SKSurface.Create(new SKImageInfo(this.Width, this.Height));
}
[GlobalCleanup]
@ -93,20 +94,19 @@ namespace SixLabors.ImageSharp.Drawing.Benchmarks
[Benchmark]
public void ImageSharp()
{
this.image.Mutate(c =>
{
foreach (PointF[] loop in this.points)
=> this.image.Mutate(
c =>
{
c.DrawPolygon(Color.White, this.Thickness, loop);
}
});
}
foreach (PointF[] loop in this.points)
{
c.DrawPolygon(Color.White, this.Thickness, loop);
}
});
[Benchmark(Baseline = true)]
public void SkiaSharp()
{
using SKPaint paint = new SKPaint
using var paint = new SKPaint
{
Style = SKPaintStyle.Stroke,
Color = SKColors.White,
@ -121,19 +121,23 @@ namespace SixLabors.ImageSharp.Drawing.Benchmarks
public class DrawPolygonAll : DrawPolygon
{
protected override int Width => 7200;
protected override int Height => 4800;
protected override float Thickness => 2f;
}
public class DrawPolygonMediumThin : DrawPolygon
{
protected override int Width => 1000;
protected override int Height => 1000;
protected override float Thickness => 1f;
protected override PointF[][] GetPoints(FeatureCollection features)
{
Feature state = features.Features.Single(f => (string) f.Properties["NAME"] == "Mississippi");
Feature state = features.Features.Single(f => (string)f.Properties["NAME"] == "Mississippi");
Matrix3x2 transform = Matrix3x2.CreateTranslation(-87, -54)
* Matrix3x2.CreateScale(60, 60);

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

@ -1,25 +1,17 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Linq;
using System.Numerics;
using BenchmarkDotNet.Attributes;
using GeoJSON.Net.Feature;
using Newtonsoft.Json;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.Drawing.Tests;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using SkiaSharp;
using SDPoint = System.Drawing.Point;
using SDPointF = System.Drawing.PointF;
using SDBitmap = System.Drawing.Bitmap;
using SDRectangleF = System.Drawing.RectangleF;
using SDFont = System.Drawing.Font;
using SDRectangleF = System.Drawing.RectangleF;
namespace SixLabors.ImageSharp.Drawing.Benchmarks
{
@ -32,7 +24,7 @@ namespace SixLabors.ImageSharp.Drawing.Benchmarks
[Params(1, 20)]
public int TextIterations { get; set; }
protected const string TextPhrase= "asdfghjkl123456789{}[]+$%?";
protected const string TextPhrase = "asdfghjkl123456789{}[]+$%?";
public string TextToRender => string.Join(" ", Enumerable.Repeat(TextPhrase, this.TextIterations));
@ -45,7 +37,7 @@ namespace SixLabors.ImageSharp.Drawing.Benchmarks
private SDFont sdFont;
private Fonts.Font font;
private SKTypeface skTypeface;
[GlobalSetup]
public void Setup()
{
@ -58,7 +50,7 @@ namespace SixLabors.ImageSharp.Drawing.Benchmarks
this.sdGraphics.SmoothingMode = SmoothingMode.AntiAlias;
this.skBitmap = new SKBitmap(Width, Height);
this.skCanvas = new SKCanvas(this.skBitmap);
this.sdFont = new SDFont("Arial", 12, GraphicsUnit.Point);
this.font = Fonts.SystemFonts.CreateFont("Arial", 12);
this.skTypeface = SKTypeface.FromFamilyName("Arial");
@ -75,42 +67,39 @@ namespace SixLabors.ImageSharp.Drawing.Benchmarks
this.sdFont.Dispose();
this.skTypeface.Dispose();
}
[Benchmark]
public void SystemDrawing()
{
this.sdGraphics.DrawString(
=> this.sdGraphics.DrawString(
this.TextToRender,
this.sdFont,
System.Drawing.Brushes.HotPink,
new SDRectangleF(10, 10, 780, 780));
}
[Benchmark]
public void ImageSharp()
{
this.image.Mutate(x => x
=> this.image.Mutate(
x => x
.SetGraphicsOptions(o => o.Antialias = true)
.SetTextOptions(o => o.WrapTextWidth = 780)
.DrawText(
this.TextToRender,
font,
this.font,
Processing.Brushes.Solid(Color.HotPink),
new PointF(10, 10)));
}
[Benchmark(Baseline = true)]
public void SkiaSharp()
{
using SKPaint paint = new SKPaint
using var paint = new SKPaint
{
Color = SKColors.HotPink,
IsAntialias = true,
TextSize = 16, // 12*1.3333
Typeface = skTypeface
Typeface = this.skTypeface
};
this.skCanvas.DrawText(TextToRender, 10, 10, paint);
this.skCanvas.DrawText(this.TextToRender, 10, 10, paint);
}
}
}

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

@ -81,16 +81,16 @@ namespace SixLabors.ImageSharp.Drawing.Benchmarks
new PointF(10, 10)));
}
IImageProcessingContext DrawTextOldVersion(
static IImageProcessingContext DrawTextOldVersion(
IImageProcessingContext source,
TextGraphicsOptions options,
string text,
SixLabors.Fonts.Font font,
Fonts.Font font,
IBrush brush,
IPen pen,
PointF location)
{
var style = new SixLabors.Fonts.RendererOptions(font, options.TextOptions.DpiX, options.TextOptions.DpiY, location)
var style = new Fonts.RendererOptions(font, options.TextOptions.DpiX, options.TextOptions.DpiY, location)
{
ApplyKerning = options.TextOptions.ApplyKerning,
TabWidth = options.TextOptions.TabWidth,
@ -115,7 +115,7 @@ namespace SixLabors.ImageSharp.Drawing.Benchmarks
return source;
}
}
// 11/12/2020
// BenchmarkDotNet=v0.12.1, OS=Windows 10.0.18363.1198 (1909/November2018Update/19H2)
// Intel Core i7-7700HQ CPU 2.80GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores

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

@ -15,9 +15,8 @@ using SixLabors.ImageSharp.Drawing.Tests;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using SkiaSharp;
using SDPoint = System.Drawing.Point;
using SDPointF = System.Drawing.PointF;
using SDBitmap = System.Drawing.Bitmap;
using SDPointF = System.Drawing.PointF;
namespace SixLabors.ImageSharp.Drawing.Benchmarks
{
@ -35,10 +34,13 @@ namespace SixLabors.ImageSharp.Drawing.Benchmarks
private SKCanvas skCanvas;
protected abstract int Width { get; }
protected abstract int Height { get; }
protected virtual PointF[][] GetPoints(FeatureCollection features) =>
features.Features.SelectMany(f => PolygonFactory.GetGeoJsonPoints(f, Matrix3x2.CreateScale(60, 60))).ToArray();
protected virtual PointF[][] GetPoints(FeatureCollection features)
=> features.Features
.SelectMany(f => PolygonFactory.GetGeoJsonPoints(f, Matrix3x2.CreateScale(60, 60)))
.ToArray();
[GlobalSetup]
public void Setup()
@ -55,23 +57,24 @@ namespace SixLabors.ImageSharp.Drawing.Benchmarks
this.skPaths = new List<SKPath>();
foreach (PointF[] ptArr in this.points.Where(pts => pts.Length > 2))
{
SKPath skPath = new SKPath();
var skPath = new SKPath();
skPath.MoveTo(ptArr[0].X, ptArr[1].Y);
for (int i = 1; i < ptArr.Length; i++)
{
skPath.LineTo(ptArr[i].X, ptArr[i].Y);
}
skPath.LineTo(ptArr[0].X, ptArr[1].Y);
this.skPaths.Add(skPath);
}
this.image = new Image<Rgba32>(Width, Height);
this.sdBitmap = new Bitmap(Width, Height);
this.image = new Image<Rgba32>(this.Width, this.Height);
this.sdBitmap = new SDBitmap(this.Width, this.Height);
this.sdGraphics = Graphics.FromImage(this.sdBitmap);
this.sdGraphics.InterpolationMode = InterpolationMode.Default;
this.sdGraphics.SmoothingMode = SmoothingMode.AntiAlias;
this.skBitmap = new SKBitmap(Width, Height);
this.skCanvas = new SKCanvas(skBitmap);
this.skBitmap = new SKBitmap(this.Width, this.Height);
this.skCanvas = new SKCanvas(this.skBitmap);
}
[GlobalCleanup]
@ -101,15 +104,13 @@ namespace SixLabors.ImageSharp.Drawing.Benchmarks
[Benchmark]
public void ImageSharp()
{
this.image.Mutate(c =>
=> this.image.Mutate(c =>
{
foreach (Polygon polygon in this.polygons)
{
c.Fill(Color.White, polygon);
}
});
}
[Benchmark(Baseline = true)]
public void SkiaSharp()
@ -117,7 +118,7 @@ namespace SixLabors.ImageSharp.Drawing.Benchmarks
foreach (SKPath path in this.skPaths)
{
// Emulate using different color for each polygon:
using SKPaint paint = new SKPaint
using var paint = new SKPaint
{
Style = SKPaintStyle.Fill,
Color = SKColors.White,
@ -131,23 +132,25 @@ namespace SixLabors.ImageSharp.Drawing.Benchmarks
public class FillPolygonAll : FillPolygon
{
protected override int Width => 7200;
protected override int Height => 4800;
}
public class FillPolygonMedium : FillPolygon
{
protected override int Width => 1000;
protected override int Height => 1000;
protected override PointF[][] GetPoints(FeatureCollection features)
{
Feature state = features.Features.Single(f => (string) f.Properties["NAME"] == "Mississippi");
Feature state = features.Features.Single(f => (string)f.Properties["NAME"] == "Mississippi");
Matrix3x2 transform = Matrix3x2.CreateTranslation(-87, -54)
* Matrix3x2.CreateScale(60, 60);
return PolygonFactory.GetGeoJsonPoints(state, transform).ToArray();
}
// ** 11/13/2020 @ Anton's PC ***
// BenchmarkDotNet=v0.12.1, OS=Windows 10.0.18363.1198 (1909/November2018Update/19H2)
// Intel Core i7-7700HQ CPU 2.80GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores
@ -166,11 +169,12 @@ namespace SixLabors.ImageSharp.Drawing.Benchmarks
public class FillPolygonSmall : FillPolygon
{
protected override int Width => 1000;
protected override int Height => 1000;
protected override PointF[][] GetPoints(FeatureCollection features)
{
Feature state = features.Features.Single(f => (string) f.Properties["NAME"] == "Utah");
Feature state = features.Features.Single(f => (string)f.Properties["NAME"] == "Utah");
Matrix3x2 transform = Matrix3x2.CreateTranslation(-60, -40)
* Matrix3x2.CreateScale(60, 60);

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

@ -6,7 +6,6 @@
<TargetFrameworks>netcoreapp3.1;netcoreapp2.1;net472</TargetFrameworks>
<IsPackable>false</IsPackable>
<GenerateProgramFile>false</GenerateProgramFile>
<!--Used to hide test project from dotnet test-->
<IsTestProject>false</IsTestProject>
</PropertyGroup>

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

@ -7,8 +7,8 @@ using Moq;
using SixLabors.ImageSharp.Formats.Bmp;
using SixLabors.ImageSharp.IO;
using Xunit;
// ReSharper disable InconsistentNaming
// ReSharper disable InconsistentNaming
namespace SixLabors.ImageSharp.Drawing.Tests
{
/// <summary>
@ -17,6 +17,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests
public class ConfigurationTests
{
public Configuration ConfigurationEmpty { get; }
public Configuration DefaultConfiguration { get; }
private readonly int expectedDefaultConfigurationCount = 5;
@ -74,10 +75,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests
if (throws)
{
Assert.Throws<ArgumentOutOfRangeException>(
() =>
{
cfg.MaxDegreeOfParallelism = maxDegreeOfParallelism;
});
() => cfg.MaxDegreeOfParallelism = maxDegreeOfParallelism);
}
else
{
@ -86,7 +84,6 @@ namespace SixLabors.ImageSharp.Drawing.Tests
}
}
[Fact]
public void ConstructorCallConfigureOnFormatProvider()
{
@ -111,26 +108,26 @@ namespace SixLabors.ImageSharp.Drawing.Tests
{
Configuration config = this.DefaultConfiguration;
Assert.Equal(expectedDefaultConfigurationCount, config.ImageFormats.Count());
Assert.Equal(this.expectedDefaultConfigurationCount, config.ImageFormats.Count());
config.ImageFormatsManager.AddImageFormat(BmpFormat.Instance);
Assert.Equal(expectedDefaultConfigurationCount, config.ImageFormats.Count());
Assert.Equal(this.expectedDefaultConfigurationCount, config.ImageFormats.Count());
}
[Fact]
public void DefaultConfigurationHasCorrectFormatCount()
{
Configuration config = Configuration.CreateDefaultInstance();
var config = Configuration.CreateDefaultInstance();
Assert.Equal(expectedDefaultConfigurationCount, config.ImageFormats.Count());
Assert.Equal(this.expectedDefaultConfigurationCount, config.ImageFormats.Count());
}
[Fact]
public void WorkingBufferSizeHint_DefaultIsCorrect()
{
Configuration config = this.DefaultConfiguration;
Assert.True(config.WorkingBufferSizeHintInBytes > 1024);
Assert.True(config.WorkingBufferSizeHintInBytes > 1024);
}
}
}

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

@ -9,24 +9,23 @@ using SixLabors.ImageSharp.Processing;
using Xunit;
// ReSharper disable InconsistentNaming
namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
{
[GroupOutput("Drawing")]
public class ClearSolidBrushTests
{
[Theory]
[WithBlankImages(1, 1, PixelTypes.Rgba32)]
[WithBlankImages(7, 4, PixelTypes.Rgba32)]
[WithBlankImages(16, 7, PixelTypes.Rgba32)]
[WithBlankImages(33, 32, PixelTypes.Rgba32)]
[WithBlankImages(400, 500, PixelTypes.Rgba32)]
[WithBlankImage(1, 1, PixelTypes.Rgba32)]
[WithBlankImage(7, 4, PixelTypes.Rgba32)]
[WithBlankImage(16, 7, PixelTypes.Rgba32)]
[WithBlankImage(33, 32, PixelTypes.Rgba32)]
[WithBlankImage(400, 500, PixelTypes.Rgba32)]
public void DoesNotDependOnSize<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
using (Image<TPixel> image = provider.GetImage())
{
var color = Color.HotPink;
Color color = Color.HotPink;
image.Mutate(c => c.Clear(color));
image.DebugSave(provider, appendPixelTypeToFileName: false);
@ -35,13 +34,13 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
}
[Theory]
[WithBlankImages(16, 16, PixelTypes.Rgba32 | PixelTypes.Argb32 | PixelTypes.RgbaVector)]
[WithBlankImage(16, 16, PixelTypes.Rgba32 | PixelTypes.Argb32 | PixelTypes.RgbaVector)]
public void DoesNotDependOnSinglePixelType<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
using (Image<TPixel> image = provider.GetImage())
{
var color = Color.HotPink;
Color color = Color.HotPink;
image.Mutate(c => c.Clear(color));
image.DebugSave(provider, appendSourceFileOrDescription: false);

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

@ -41,7 +41,8 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
FormattableString testDetails = $"{colorName}_A{alpha}_T{thickness}";
provider.RunValidatingProcessorTest(x => x.DrawBeziers(color, 5f, points),
provider.RunValidatingProcessorTest(
x => x.DrawBeziers(color, 5f, points),
testDetails,
appendSourceFileOrDescription: false,
appendPixelTypeToFileName: false);

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

@ -39,7 +39,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
Color color = colorRgba;
string testDetails = "";
string testDetails = string.Empty;
if (overlap)
{
testDetails += "_Overlap";

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

@ -70,7 +70,6 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
DrawLinesImpl(provider, colorName, alpha, thickness, antialias, pen);
}
private static void DrawLinesImpl<TPixel>(
TestImageProvider<TPixel> provider,
string colorName,
@ -84,7 +83,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
var options = new GraphicsOptions { Antialias = antialias };
string aa = antialias ? "" : "_NoAntialias";
string aa = antialias ? string.Empty : "_NoAntialias";
FormattableString outputDetails = $"{colorName}_A({alpha})_T({thickness}){aa}";
provider.RunValidatingProcessorTest(
@ -92,6 +91,5 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
outputDetails,
appendSourceFileOrDescription: false);
}
}
}

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

@ -57,7 +57,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
public void PathExtendingOffEdgeOfImageShouldNotBeCropped<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
var color = Color.White;
Color color = Color.White;
Pen pen = Pens.Solid(color, 5f);
provider.RunValidatingProcessorTest(

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

@ -28,7 +28,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
var options = new GraphicsOptions { Antialias = antialias };
string aa = antialias ? "" : "_NoAntialias";
string aa = antialias ? string.Empty : "_NoAntialias";
FormattableString outputDetails = $"{colorName}_A({alpha})_T({thickness}){aa}";
provider.RunValidatingProcessorTest(

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

@ -17,8 +17,8 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
{
public class DrawingProfilingBenchmarks : IDisposable
{
private Image<Rgba32> image;
private Polygon[] polygons;
private readonly Image<Rgba32> image;
private readonly Polygon[] polygons;
public DrawingProfilingBenchmarks()
{
@ -28,12 +28,12 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
PointF[][] points = GetPoints(featureCollection);
this.polygons = points.Select(pts => new Polygon(new LinearLineSegment(pts))).ToArray();
this.image = new Image<Rgba32>(1000, 1000);
static PointF[][] GetPoints(FeatureCollection features)
{
Feature state = features.Features.Single(f => (string) f.Properties["NAME"] == "Mississippi");
Feature state = features.Features.Single(f => (string)f.Properties["NAME"] == "Mississippi");
Matrix3x2 transform = Matrix3x2.CreateTranslation(-87, -54)
* Matrix3x2.CreateScale(60, 60);
@ -70,9 +70,9 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
public void DrawText(int textIterations)
{
const int Times = 20;
const string TextPhrase= "asdfghjkl123456789{}[]+$%?";
const string TextPhrase = "asdfghjkl123456789{}[]+$%?";
string textToRender = string.Join("/n", Enumerable.Repeat(TextPhrase, textIterations));
Font font = SystemFonts.CreateFont("Arial", 12);
for (int i = 0; i < Times; i++)
@ -88,9 +88,6 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
}
}
public void Dispose()
{
this.image.Dispose();
}
public void Dispose() => this.image.Dispose();
}
}
}

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

@ -25,17 +25,17 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
[WithSolidFilledImages(32, 32, "Black", PixelTypes.Rgba32)]
public void CompareToSkiaResults_SmallCircle(TestImageProvider<Rgba32> provider)
{
EllipsePolygon circle = new EllipsePolygon(16, 16, 10);
var circle = new EllipsePolygon(16, 16, 10);
CompareToSkiaResultsImpl(provider, circle);
}
[Theory(Skip = "For local testing")]
[WithSolidFilledImages(64, 64, "Black", PixelTypes.Rgba32)]
public void CompareToSkiaResults_StarCircle(TestImageProvider<Rgba32> provider)
{
EllipsePolygon circle = new EllipsePolygon(32, 32, 30);
Star star = new Star(32, 32, 7, 10, 27);
var circle = new EllipsePolygon(32, 32, 30);
var star = new Star(32, 32, 7, 10, 27);
IPath shape = circle.Clip(star);
CompareToSkiaResultsImpl(provider, shape);
@ -47,33 +47,36 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
image.Mutate(c => c.Fill(Color.White, shape));
image.DebugSave(provider, "ImageSharp", appendPixelTypeToFileName: false, appendSourceFileOrDescription: false);
using SKBitmap bitmap = new SKBitmap(new SKImageInfo(image.Width, image.Height));
using SKPath skPath = new SKPath();
using var bitmap = new SKBitmap(new SKImageInfo(image.Width, image.Height));
foreach (var loop in shape.Flatten())
using var skPath = new SKPath();
foreach (ISimplePath loop in shape.Flatten())
{
ReadOnlySpan<SKPoint> points = MemoryMarshal.Cast<PointF, SKPoint>(loop.Points.Span);
skPath.AddPoly(points.ToArray());
}
using SKPaint paint = new SKPaint
using var paint = new SKPaint
{
Style = SKPaintStyle.Fill,
Color = SKColors.White,
IsAntialias = true,
};
using SKCanvas canvas = new SKCanvas(bitmap);
using var canvas = new SKCanvas(bitmap);
canvas.Clear(new SKColor(0, 0, 0));
canvas.DrawPath(skPath, paint);
using Image<Rgba32> skResultImage =
using var skResultImage =
Image.LoadPixelData<Rgba32>(bitmap.GetPixelSpan(), image.Width, image.Height);
skResultImage.DebugSave(provider, "SkiaSharp", appendPixelTypeToFileName: false,
skResultImage.DebugSave(
provider,
"SkiaSharp",
appendPixelTypeToFileName: false,
appendSourceFileOrDescription: false);
var result = ImageComparer.Exact.CompareImagesOrFrames(image, skResultImage);
ImageSimilarityReport<Rgba32, Rgba32> result = ImageComparer.Exact.CompareImagesOrFrames(image, skResultImage);
throw new Exception(result.DifferencePercentageString);
}
@ -88,7 +91,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
using Image<Rgba32> image = provider.GetImage();
var options = new ShapeGraphicsOptions()
{
GraphicsOptions = new GraphicsOptions() {Antialias = aa > 0, AntialiasSubpixelDepth = aa},
GraphicsOptions = new GraphicsOptions() { Antialias = aa > 0, AntialiasSubpixelDepth = aa },
};
foreach (PointF[] loop in points)
{
@ -97,7 +100,8 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
string details = $"_{System.IO.Path.GetFileName(geoJsonFile)}_{sx}x{sy}_aa{aa}";
image.DebugSave(provider,
image.DebugSave(
provider,
details,
appendPixelTypeToFileName: false,
appendSourceFileOrDescription: false);
@ -107,8 +111,8 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
[WithSolidFilledImages(7200, 3300, "Black", PixelTypes.Rgba32)]
public void LargeGeoJson_States_Fill(TestImageProvider<Rgba32> provider)
{
using Image<Rgba32> image = FillGeoJsonPolygons(provider, TestImages.GeoJson.States, 16, new Vector2(60), new Vector2(0, -1000));
ImageComparer comparer = ImageComparer.TolerantPercentage(0.001f);
using Image<Rgba32> image = this.FillGeoJsonPolygons(provider, TestImages.GeoJson.States, 16, new Vector2(60), new Vector2(0, -1000));
var comparer = ImageComparer.TolerantPercentage(0.001f);
image.DebugSave(provider, appendPixelTypeToFileName: false, appendSourceFileOrDescription: false);
image.CompareToReferenceOutput(comparer, provider, appendPixelTypeToFileName: false, appendSourceFileOrDescription: false);
@ -123,15 +127,15 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
Image<Rgba32> image = provider.GetImage();
var options = new ShapeGraphicsOptions()
{
GraphicsOptions = new GraphicsOptions() {Antialias = aa > 0, AntialiasSubpixelDepth = aa},
GraphicsOptions = new GraphicsOptions() { Antialias = aa > 0, AntialiasSubpixelDepth = aa },
};
var rnd = new Random(42);
byte[] rgb = new byte[3];
foreach (PointF[] loop in points)
{
rnd.NextBytes(rgb);
Color color = Color.FromRgb(rgb[0], rgb[1], rgb[2]);
var color = Color.FromRgb(rgb[0], rgb[1], rgb[2]);
image.Mutate(c => c.FillPolygon(options, color, loop));
}
@ -147,12 +151,12 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
FeatureCollection features = JsonConvert.DeserializeObject<FeatureCollection>(jsonContent);
var missisipiGeom = features.Features.Single(f => (string) f.Properties["NAME"] == "Mississippi");
Feature missisipiGeom = features.Features.Single(f => (string)f.Properties["NAME"] == "Mississippi");
var transform = Matrix3x2.CreateTranslation(-87, -54)
Matrix3x2 transform = Matrix3x2.CreateTranslation(-87, -54)
* Matrix3x2.CreateScale(60, 60)
* Matrix3x2.CreateTranslation(pixelOffset, pixelOffset);
var points = PolygonFactory.GetGeoJsonPoints(missisipiGeom, transform);
IReadOnlyList<PointF[]> points = PolygonFactory.GetGeoJsonPoints(missisipiGeom, transform);
using Image<Rgba32> image = provider.GetImage();
@ -170,8 +174,6 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
image.DebugSave(provider, details, appendPixelTypeToFileName: false, appendSourceFileOrDescription: false);
image.CompareToReferenceOutput(comparer, provider, testOutputDetails: details, appendPixelTypeToFileName: false, appendSourceFileOrDescription: false);
}
[Theory(Skip = "For local experiments only")]
[InlineData(0)]
@ -183,15 +185,14 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
FeatureCollection features = JsonConvert.DeserializeObject<FeatureCollection>(jsonContent);
var missisipiGeom = features.Features.Single(f => (string) f.Properties["NAME"] == "Mississippi");
Feature missisipiGeom = features.Features.Single(f => (string)f.Properties["NAME"] == "Mississippi");
var transform = Matrix3x2.CreateTranslation(-87, -54)
Matrix3x2 transform = Matrix3x2.CreateTranslation(-87, -54)
* Matrix3x2.CreateScale(60, 60)
* Matrix3x2.CreateTranslation(offset, offset);
IReadOnlyList<PointF[]> points =PolygonFactory.GetGeoJsonPoints(missisipiGeom, transform);
IReadOnlyList<PointF[]> points = PolygonFactory.GetGeoJsonPoints(missisipiGeom, transform);
SKPath path = new SKPath();
var path = new SKPath();
foreach (PointF[] pts in points.Where(p => p.Length > 2))
{
@ -201,12 +202,13 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
{
path.LineTo(pts[i].X, pts[i].Y);
}
path.LineTo(pts[0].X, pts[0].Y);
}
SKImageInfo imageInfo = new SKImageInfo(10000, 10000);
var imageInfo = new SKImageInfo(10000, 10000);
using SKPaint paint = new SKPaint
using var paint = new SKPaint
{
Style = SKPaintStyle.Stroke,
Color = SKColors.White,
@ -214,9 +216,9 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
IsAntialias = true,
};
using SKSurface surface = SKSurface.Create(imageInfo);
using var surface = SKSurface.Create(imageInfo);
SKCanvas canvas = surface.Canvas;
canvas.Clear(new SKColor(0,0, 0));
canvas.Clear(new SKColor(0, 0, 0));
canvas.DrawPath(path, paint);
string outDir = TestEnvironment.CreateOutputDirectory("Skia");

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

@ -38,7 +38,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
Color color = colorRgba;
string testDetails = "";
string testDetails = string.Empty;
if (overlap)
{
testDetails += "_Overlap";

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

@ -2,24 +2,21 @@
// Licensed under the Apache License, Version 2.0.
using System;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.Drawing.Tests.TestUtilities.ImageComparison;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using Xunit;
namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
{
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.Drawing.Tests.TestUtilities.ImageComparison;
[GroupOutput("Drawing/GradientBrushes")]
public class FillEllipticGradientBrushTests
{
public static ImageComparer TolerantComparer = ImageComparer.TolerantPercentage(0.01f);
private static readonly ImageComparer TolerantComparer = ImageComparer.TolerantPercentage(0.01f);
[Theory]
[WithBlankImages(10, 10, PixelTypes.Rgba32)]
[WithBlankImage(10, 10, PixelTypes.Rgba32)]
public void WithEqualColorsReturnsUnicolorImage<TPixel>(
TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
@ -47,13 +44,13 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
}
[Theory]
[WithBlankImages(200, 200, PixelTypes.Rgba32, 0.1)]
[WithBlankImages(200, 200, PixelTypes.Rgba32, 0.4)]
[WithBlankImages(200, 200, PixelTypes.Rgba32, 0.8)]
[WithBlankImages(200, 200, PixelTypes.Rgba32, 1.0)]
[WithBlankImages(200, 200, PixelTypes.Rgba32, 1.2)]
[WithBlankImages(200, 200, PixelTypes.Rgba32, 1.6)]
[WithBlankImages(200, 200, PixelTypes.Rgba32, 2.0)]
[WithBlankImage(200, 200, PixelTypes.Rgba32, 0.1)]
[WithBlankImage(200, 200, PixelTypes.Rgba32, 0.4)]
[WithBlankImage(200, 200, PixelTypes.Rgba32, 0.8)]
[WithBlankImage(200, 200, PixelTypes.Rgba32, 1.0)]
[WithBlankImage(200, 200, PixelTypes.Rgba32, 1.2)]
[WithBlankImage(200, 200, PixelTypes.Rgba32, 1.6)]
[WithBlankImage(200, 200, PixelTypes.Rgba32, 2.0)]
public void AxisParallelEllipsesWithDifferentRatio<TPixel>(
TestImageProvider<TPixel> provider,
float ratio)
@ -69,7 +66,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
{
var unicolorLinearGradientBrush = new EllipticGradientBrush(
new Point(image.Width / 2, image.Height / 2),
new Point(image.Width / 2, (image.Width * 2) / 3),
new Point(image.Width / 2, image.Width * 2 / 3),
ratio,
GradientRepetitionMode.None,
new ColorStop(0, yellow),
@ -84,25 +81,25 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
}
[Theory]
[WithBlankImages(200, 200, PixelTypes.Rgba32, 0.1, 0)]
[WithBlankImages(200, 200, PixelTypes.Rgba32, 0.4, 0)]
[WithBlankImages(200, 200, PixelTypes.Rgba32, 0.8, 0)]
[WithBlankImages(200, 200, PixelTypes.Rgba32, 1.0, 0)]
[WithBlankImage(200, 200, PixelTypes.Rgba32, 0.1, 0)]
[WithBlankImage(200, 200, PixelTypes.Rgba32, 0.4, 0)]
[WithBlankImage(200, 200, PixelTypes.Rgba32, 0.8, 0)]
[WithBlankImage(200, 200, PixelTypes.Rgba32, 1.0, 0)]
[WithBlankImages(200, 200, PixelTypes.Rgba32, 0.1, 45)]
[WithBlankImages(200, 200, PixelTypes.Rgba32, 0.4, 45)]
[WithBlankImages(200, 200, PixelTypes.Rgba32, 0.8, 45)]
[WithBlankImages(200, 200, PixelTypes.Rgba32, 1.0, 45)]
[WithBlankImage(200, 200, PixelTypes.Rgba32, 0.1, 45)]
[WithBlankImage(200, 200, PixelTypes.Rgba32, 0.4, 45)]
[WithBlankImage(200, 200, PixelTypes.Rgba32, 0.8, 45)]
[WithBlankImage(200, 200, PixelTypes.Rgba32, 1.0, 45)]
[WithBlankImages(200, 200, PixelTypes.Rgba32, 0.1, 90)]
[WithBlankImages(200, 200, PixelTypes.Rgba32, 0.4, 90)]
[WithBlankImages(200, 200, PixelTypes.Rgba32, 0.8, 90)]
[WithBlankImages(200, 200, PixelTypes.Rgba32, 1.0, 90)]
[WithBlankImage(200, 200, PixelTypes.Rgba32, 0.1, 90)]
[WithBlankImage(200, 200, PixelTypes.Rgba32, 0.4, 90)]
[WithBlankImage(200, 200, PixelTypes.Rgba32, 0.8, 90)]
[WithBlankImage(200, 200, PixelTypes.Rgba32, 1.0, 90)]
[WithBlankImages(200, 200, PixelTypes.Rgba32, 0.1, 30)]
[WithBlankImages(200, 200, PixelTypes.Rgba32, 0.4, 30)]
[WithBlankImages(200, 200, PixelTypes.Rgba32, 0.8, 30)]
[WithBlankImages(200, 200, PixelTypes.Rgba32, 1.0, 30)]
[WithBlankImage(200, 200, PixelTypes.Rgba32, 0.1, 30)]
[WithBlankImage(200, 200, PixelTypes.Rgba32, 0.4, 30)]
[WithBlankImage(200, 200, PixelTypes.Rgba32, 0.8, 30)]
[WithBlankImage(200, 200, PixelTypes.Rgba32, 1.0, 30)]
public void RotatedEllipsesWithDifferentRatio<TPixel>(
TestImageProvider<TPixel> provider,
float ratio,
@ -121,7 +118,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
var center = new Point(image.Width / 2, image.Height / 2);
double rotation = (Math.PI * rotationInDegree) / 180.0;
double rotation = Math.PI * rotationInDegree / 180.0;
double cos = Math.Cos(rotation);
double sin = Math.Sin(rotation);

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

@ -8,7 +8,6 @@ using SixLabors.ImageSharp.Processing;
using Xunit;
// ReSharper disable InconsistentNaming
namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
{
[GroupOutput("Drawing")]
@ -29,7 +28,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
}
[Theory]
[WithTestPatternImages(200, 200, PixelTypes.Rgba32 | PixelTypes.Bgra32)]
[WithTestPatternImage(200, 200, PixelTypes.Rgba32 | PixelTypes.Bgra32)]
public void UseBrushOfDifferentPixelType<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{

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

@ -5,26 +5,22 @@ using System;
using System.Globalization;
using System.Linq;
using System.Text;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.Drawing.Tests.TestUtilities.ImageComparison;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using Xunit;
// ReSharper disable InconsistentNaming
// ReSharper disable InconsistentNaming
namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
{
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.Drawing.Tests.TestUtilities.ImageComparison;
[GroupOutput("Drawing/GradientBrushes")]
public class FillLinearGradientBrushTests
{
public static ImageComparer TolerantComparer = ImageComparer.TolerantPercentage(0.01f);
public static ImageComparer TolerantComparer { get; } = ImageComparer.TolerantPercentage(0.01f);
[Theory]
[WithBlankImages(10, 10, PixelTypes.Rgba32)]
[WithBlankImage(10, 10, PixelTypes.Rgba32)]
public void WithEqualColorsReturnsUnicolorImage<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
@ -49,13 +45,12 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
}
[Theory]
[WithBlankImages(20, 10, PixelTypes.Rgba32)]
[WithBlankImages(20, 10, PixelTypes.Argb32)]
[WithBlankImages(20, 10, PixelTypes.Rgb24)]
[WithBlankImage(20, 10, PixelTypes.Rgba32)]
[WithBlankImage(20, 10, PixelTypes.Argb32)]
[WithBlankImage(20, 10, PixelTypes.Rgb24)]
public void DoesNotDependOnSinglePixelType<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
provider.VerifyOperation(
=> provider.VerifyOperation(
TolerantComparer,
image =>
{
@ -69,14 +64,12 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
image.Mutate(x => x.Fill(unicolorLinearGradientBrush));
},
appendSourceFileOrDescription: false);
}
[Theory]
[WithBlankImages(500, 10, PixelTypes.Rgba32)]
[WithBlankImage(500, 10, PixelTypes.Rgba32)]
public void HorizontalReturnsUnicolorColumns<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
provider.VerifyOperation(
=> provider.VerifyOperation(
TolerantComparer,
image =>
{
@ -94,19 +87,17 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
},
false,
false);
}
[Theory]
[WithBlankImages(500, 10, PixelTypes.Rgba32, GradientRepetitionMode.DontFill)]
[WithBlankImages(500, 10, PixelTypes.Rgba32, GradientRepetitionMode.None)]
[WithBlankImages(500, 10, PixelTypes.Rgba32, GradientRepetitionMode.Repeat)]
[WithBlankImages(500, 10, PixelTypes.Rgba32, GradientRepetitionMode.Reflect)]
[WithBlankImage(500, 10, PixelTypes.Rgba32, GradientRepetitionMode.DontFill)]
[WithBlankImage(500, 10, PixelTypes.Rgba32, GradientRepetitionMode.None)]
[WithBlankImage(500, 10, PixelTypes.Rgba32, GradientRepetitionMode.Repeat)]
[WithBlankImage(500, 10, PixelTypes.Rgba32, GradientRepetitionMode.Reflect)]
public void HorizontalGradientWithRepMode<TPixel>(
TestImageProvider<TPixel> provider,
GradientRepetitionMode repetitionMode)
where TPixel : unmanaged, IPixel<TPixel>
{
provider.VerifyOperation(
=> provider.VerifyOperation(
TolerantComparer,
image =>
{
@ -125,12 +116,11 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
$"{repetitionMode}",
false,
false);
}
[Theory]
[WithBlankImages(200, 100, PixelTypes.Rgba32, new[] { 0.5f })]
[WithBlankImages(200, 100, PixelTypes.Rgba32, new[] { 0.2f, 0.4f, 0.6f, 0.8f })]
[WithBlankImages(200, 100, PixelTypes.Rgba32, new[] { 0.1f, 0.3f, 0.6f })]
[WithBlankImage(200, 100, PixelTypes.Rgba32, new[] { 0.5f })]
[WithBlankImage(200, 100, PixelTypes.Rgba32, new[] { 0.2f, 0.4f, 0.6f, 0.8f })]
[WithBlankImage(200, 100, PixelTypes.Rgba32, new[] { 0.1f, 0.3f, 0.6f })]
public void WithDoubledStopsProduceDashedPatterns<TPixel>(
TestImageProvider<TPixel> provider,
float[] pattern)
@ -148,12 +138,13 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
ColorStop[] colorStops =
Enumerable.Repeat(new ColorStop(0, black), 1)
.Concat(
pattern
.SelectMany((f, index) => new[]
{
new ColorStop(f, index % 2 == 0 ? black : white),
new ColorStop(f, index % 2 == 0 ? white : black)
}))
pattern.SelectMany(
(f, index) =>
new[]
{
new ColorStop(f, index % 2 == 0 ? black : white),
new ColorStop(f, index % 2 == 0 ? white : black)
}))
.Concat(Enumerable.Repeat(new ColorStop(1, pattern.Length % 2 == 0 ? black : white), 1))
.ToArray();
@ -190,7 +181,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
}
[Theory]
[WithBlankImages(10, 500, PixelTypes.Rgba32)]
[WithBlankImage(10, 500, PixelTypes.Rgba32)]
public void VerticalBrushReturnsUnicolorRows<TPixel>(
TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
@ -215,7 +206,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
false,
false);
void VerifyAllRowsAreUnicolor(Image<TPixel> image)
static void VerifyAllRowsAreUnicolor(Image<TPixel> image)
{
for (int y = 0; y < image.Height; y++)
{
@ -238,10 +229,10 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
}
[Theory]
[WithBlankImages(200, 200, PixelTypes.Rgba32, ImageCorner.TopLeft)]
[WithBlankImages(200, 200, PixelTypes.Rgba32, ImageCorner.TopRight)]
[WithBlankImages(200, 200, PixelTypes.Rgba32, ImageCorner.BottomLeft)]
[WithBlankImages(200, 200, PixelTypes.Rgba32, ImageCorner.BottomRight)]
[WithBlankImage(200, 200, PixelTypes.Rgba32, ImageCorner.TopLeft)]
[WithBlankImage(200, 200, PixelTypes.Rgba32, ImageCorner.TopRight)]
[WithBlankImage(200, 200, PixelTypes.Rgba32, ImageCorner.BottomLeft)]
[WithBlankImage(200, 200, PixelTypes.Rgba32, ImageCorner.BottomRight)]
public void DiagonalReturnsCorrectImages<TPixel>(
TestImageProvider<TPixel> provider,
ImageCorner startCorner)
@ -300,14 +291,16 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
}
[Theory]
[WithBlankImages(500, 500, PixelTypes.Rgba32, 0, 0, 499, 499, new[] { 0f, .2f, .5f, .9f }, new[] { 0, 0, 1, 1 })]
[WithBlankImages(500, 500, PixelTypes.Rgba32, 0, 499, 499, 0, new[] { 0f, 0.2f, 0.5f, 0.9f }, new[] { 0, 1, 2, 3 })]
[WithBlankImages(500, 500, PixelTypes.Rgba32, 499, 499, 0, 0, new[] { 0f, 0.7f, 0.8f, 0.9f }, new[] { 0, 1, 2, 0 })]
[WithBlankImages(500, 500, PixelTypes.Rgba32, 0, 0, 499, 499, new[] { 0f, .5f, 1f }, new[] { 0, 1, 3 })]
[WithBlankImage(500, 500, PixelTypes.Rgba32, 0, 0, 499, 499, new[] { 0f, .2f, .5f, .9f }, new[] { 0, 0, 1, 1 })]
[WithBlankImage(500, 500, PixelTypes.Rgba32, 0, 499, 499, 0, new[] { 0f, 0.2f, 0.5f, 0.9f }, new[] { 0, 1, 2, 3 })]
[WithBlankImage(500, 500, PixelTypes.Rgba32, 499, 499, 0, 0, new[] { 0f, 0.7f, 0.8f, 0.9f }, new[] { 0, 1, 2, 0 })]
[WithBlankImage(500, 500, PixelTypes.Rgba32, 0, 0, 499, 499, new[] { 0f, .5f, 1f }, new[] { 0, 1, 3 })]
public void ArbitraryGradients<TPixel>(
TestImageProvider<TPixel> provider,
int startX, int startY,
int endX, int endY,
int startX,
int startY,
int endX,
int endY,
float[] stopPositions,
int[] stopColorCodes)
where TPixel : unmanaged, IPixel<TPixel>
@ -349,11 +342,13 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
}
[Theory]
[WithBlankImages(200, 200, PixelTypes.Rgba32, 0, 0, 199, 199, new[] { 0f, .25f, .5f, .75f, 1f }, new[] { 0, 1, 2, 3, 4 })]
[WithBlankImage(200, 200, PixelTypes.Rgba32, 0, 0, 199, 199, new[] { 0f, .25f, .5f, .75f, 1f }, new[] { 0, 1, 2, 3, 4 })]
public void MultiplePointGradients<TPixel>(
TestImageProvider<TPixel> provider,
int startX, int startY,
int endX, int endY,
int startX,
int startY,
int endX,
int endY,
float[] stopPositions,
int[] stopColorCodes)
where TPixel : unmanaged, IPixel<TPixel>
@ -395,7 +390,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
}
[Theory]
[WithBlankImages(200, 200, PixelTypes.Rgba32)]
[WithBlankImage(200, 200, PixelTypes.Rgba32)]
public void GradientsWithTransparencyOnExistingBackground<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
@ -404,7 +399,6 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
{
image.Mutate(i => i.Fill(Color.Red));
image.Mutate(ApplyGloss);
});
void ApplyGloss(IImageProcessingContext ctx)
@ -433,11 +427,10 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
}
[Theory]
[WithBlankImages(200, 200, PixelTypes.Rgb24)]
[WithBlankImage(200, 200, PixelTypes.Rgb24)]
public void BrushApplicatorIsThreadSafeIssue1044<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
provider.VerifyOperation(
=> provider.VerifyOperation(
TolerantComparer,
img =>
{
@ -446,7 +439,8 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
new[] { Color.Red, Color.Yellow, Color.Green, Color.DarkCyan, Color.Red });
img.Mutate(m => m.Fill(brush));
}, false, false);
}
},
false,
false);
}
}

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

@ -1,3 +1,6 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
@ -9,10 +12,10 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
public class FillOutsideBoundsTests
{
[Theory]
[InlineData(-100)] //Crash
[InlineData(-99)] //Fine
[InlineData(99)] //Fine
[InlineData(100)] //Crash
[InlineData(-100)] // Crash
[InlineData(-99)] // Fine
[InlineData(99)] // Fine
[InlineData(100)] // Crash
public void DrawRectactangleOutsideBoundsDrawingArea(int xpos)
{
int width = 100;
@ -26,14 +29,14 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
}
}
public static TheoryData<int, int> CircleCoordinates = new TheoryData<int, int>()
public static TheoryData<int, int> CircleCoordinates { get; } = new TheoryData<int, int>()
{
{-110, -60}, { 0, -60 }, {110, -60},
{-110, -50}, { 0, -50 }, {110, -50},
{-110, -49}, { 0, -49 }, {110, -49},
{-110, -20}, { 0, -20 }, {110, -20},
{-110, -50}, { 0, -60 }, {110, -60},
{-110, 0}, { -99, 0}, { 0, 0 }, {99, 0}, { 110, 0},
{ -110, -60 }, { 0, -60 }, { 110, -60 },
{ -110, -50 }, { 0, -50 }, { 110, -50 },
{ -110, -49 }, { 0, -49 }, { 110, -49 },
{ -110, -20 }, { 0, -20 }, { 110, -20 },
{ -110, -50 }, { 0, -60 }, { 110, -60 },
{ -110, 0 }, { -99, 0 }, { 0, 0 }, { 99, 0 }, { 110, 0 },
};
[Theory]
@ -43,10 +46,11 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
int width = 100;
int height = 100;
using var image = provider.GetImage();
using Image<Rgba32> image = provider.GetImage();
var circle = new EllipsePolygon(xpos, ypos, width, height);
provider.RunValidatingProcessorTest(x => x.Fill(Color.Black, circle),
provider.RunValidatingProcessorTest(
x => x.Fill(Color.Black, circle),
$"({xpos}_{ypos})",
appendPixelTypeToFileName: false,
appendSourceFileOrDescription: false);

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

@ -13,14 +13,13 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
[GroupOutput("Drawing/GradientBrushes")]
public class FillPathGradientBrushTests
{
public static ImageComparer TolerantComparer = ImageComparer.TolerantPercentage(0.01f);
private static readonly ImageComparer TolerantComparer = ImageComparer.TolerantPercentage(0.01f);
[Theory]
[WithBlankImages(10, 10, PixelTypes.Rgba32)]
[WithBlankImage(10, 10, PixelTypes.Rgba32)]
public void FillRectangleWithDifferentColors<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
provider.VerifyOperation(
=> provider.VerifyOperation(
TolerantComparer,
image =>
{
@ -32,14 +31,12 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
image.Mutate(x => x.Fill(brush));
image.DebugSave(provider, appendPixelTypeToFileName: false, appendSourceFileOrDescription: false);
});
}
[Theory]
[WithBlankImages(20, 20, PixelTypes.Rgba32)]
[WithBlankImage(20, 20, PixelTypes.Rgba32)]
public void FillTriangleWithDifferentColors<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
provider.VerifyOperation(
=> provider.VerifyOperation(
TolerantComparer,
image =>
{
@ -51,42 +48,37 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
image.Mutate(x => x.Fill(brush));
image.DebugSave(provider, appendPixelTypeToFileName: false, appendSourceFileOrDescription: false);
});
}
[Theory]
[WithBlankImages(20, 20, PixelTypes.HalfSingle)]
[WithBlankImage(20, 20, PixelTypes.HalfSingle)]
public void FillTriangleWithGreyscale<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
provider.VerifyOperation(
=> provider.VerifyOperation(
ImageComparer.TolerantPercentage(0.02f),
image =>
{
PointF[] points = { new PointF(10, 0), new PointF(20, 20), new PointF(0, 20) };
var c1 = new Rgba32();
var c2 = new Rgba32();
var c3 = new Rgba32();
var c1 = default(Rgba32);
var c2 = default(Rgba32);
var c3 = default(Rgba32);
new HalfSingle(-1).ToRgba32(ref c1);
new HalfSingle(0).ToRgba32(ref c2);
new HalfSingle(1).ToRgba32(ref c3);
Color[] colors = { new Color(c1), new Color(c2), new Color(c3) };
Color[] colors = { new Color(c1), new Color(c2), new Color(c3) };
var brush = new PathGradientBrush(points, colors);
image.Mutate(x => x.Fill(brush));
image.DebugSave(provider, appendPixelTypeToFileName: false, appendSourceFileOrDescription: false);
});
}
[Theory]
[WithBlankImages(20, 20, PixelTypes.Rgba32)]
[WithBlankImage(20, 20, PixelTypes.Rgba32)]
public void FillTriangleWithDifferentColorsCenter<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
provider.VerifyOperation(
=> provider.VerifyOperation(
TolerantComparer,
image =>
{
@ -98,11 +90,9 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
image.Mutate(x => x.Fill(brush));
image.DebugSave(provider, appendPixelTypeToFileName: false, appendSourceFileOrDescription: false);
});
}
[Theory]
[WithBlankImages(10, 10, PixelTypes.Rgba32)]
[WithBlankImage(10, 10, PixelTypes.Rgba32)]
public void FillRectangleWithSingleColor<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
@ -120,11 +110,10 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
}
[Theory]
[WithBlankImages(10, 10, PixelTypes.Rgba32)]
[WithBlankImage(10, 10, PixelTypes.Rgba32)]
public void ShouldRotateTheColorsWhenThereAreMorePoints<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
provider.VerifyOperation(
=> provider.VerifyOperation(
TolerantComparer,
image =>
{
@ -136,14 +125,12 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
image.Mutate(x => x.Fill(brush));
image.DebugSave(provider, appendPixelTypeToFileName: false, appendSourceFileOrDescription: false);
});
}
[Theory]
[WithBlankImages(10, 10, PixelTypes.Rgba32)]
[WithBlankImage(10, 10, PixelTypes.Rgba32)]
public void FillWithCustomCenterColor<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
provider.VerifyOperation(
=> provider.VerifyOperation(
TolerantComparer,
image =>
{
@ -155,7 +142,6 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
image.Mutate(x => x.Fill(brush));
image.DebugSave(provider, appendPixelTypeToFileName: false, appendSourceFileOrDescription: false);
});
}
[Fact]
public void ShouldThrowArgumentNullExceptionWhenLinesAreNull()

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

@ -23,6 +23,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
image.Save($"{path}/{name}.png");
Buffer2D<Rgba32> sourcePixels = image.GetRootFramePixelBuffer();
// lets pick random spots to start checking
var r = new Random();
var expectedPatternFast = new DenseMatrix<Rgba32>(expectedPattern);
@ -53,225 +54,253 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
[Fact]
public void ImageShouldBeFloodFilledWithPercent10()
{
var expectedPattern = new Rgba32[,]
{
{ Color.HotPink, Color.LimeGreen, Color.LimeGreen, Color.LimeGreen },
{ Color.LimeGreen, Color.LimeGreen, Color.LimeGreen, Color.LimeGreen },
{ Color.LimeGreen, Color.LimeGreen, Color.HotPink, Color.LimeGreen },
{ Color.LimeGreen, Color.LimeGreen, Color.LimeGreen, Color.LimeGreen }
};
this.Test(
"Percent10",
Color.Blue,
Brushes.Percent10(Color.HotPink, Color.LimeGreen),
new Rgba32[,]
{
{ Color.HotPink, Color.LimeGreen, Color.LimeGreen, Color.LimeGreen },
{ Color.LimeGreen, Color.LimeGreen, Color.LimeGreen, Color.LimeGreen },
{ Color.LimeGreen, Color.LimeGreen, Color.HotPink, Color.LimeGreen },
{ Color.LimeGreen, Color.LimeGreen, Color.LimeGreen, Color.LimeGreen }
});
expectedPattern);
}
[Fact]
public void ImageShouldBeFloodFilledWithPercent10Transparent()
{
var expectedPattern = new Rgba32[,]
{
{ Color.HotPink, Color.Blue, Color.Blue, Color.Blue },
{ Color.Blue, Color.Blue, Color.Blue, Color.Blue },
{ Color.Blue, Color.Blue, Color.HotPink, Color.Blue },
{ Color.Blue, Color.Blue, Color.Blue, Color.Blue }
};
this.Test(
"Percent10_Transparent",
Color.Blue,
Brushes.Percent10(Color.HotPink),
new Rgba32[,]
{
{ Color.HotPink, Color.Blue, Color.Blue, Color.Blue },
{ Color.Blue, Color.Blue, Color.Blue, Color.Blue },
{ Color.Blue, Color.Blue, Color.HotPink, Color.Blue },
{ Color.Blue, Color.Blue, Color.Blue, Color.Blue }
});
expectedPattern);
}
[Fact]
public void ImageShouldBeFloodFilledWithPercent20()
{
var expectedPattern = new Rgba32[,]
{
{ Color.HotPink, Color.LimeGreen, Color.LimeGreen, Color.LimeGreen },
{ Color.LimeGreen, Color.LimeGreen, Color.HotPink, Color.LimeGreen },
{ Color.HotPink, Color.LimeGreen, Color.LimeGreen, Color.LimeGreen },
{ Color.LimeGreen, Color.LimeGreen, Color.HotPink, Color.LimeGreen }
};
this.Test(
"Percent20",
Color.Blue,
Brushes.Percent20(Color.HotPink, Color.LimeGreen),
new Rgba32[,]
{
{ Color.HotPink, Color.LimeGreen, Color.LimeGreen, Color.LimeGreen },
{ Color.LimeGreen, Color.LimeGreen, Color.HotPink, Color.LimeGreen },
{ Color.HotPink, Color.LimeGreen, Color.LimeGreen, Color.LimeGreen },
{ Color.LimeGreen, Color.LimeGreen, Color.HotPink, Color.LimeGreen }
});
expectedPattern);
}
[Fact]
public void ImageShouldBeFloodFilledWithPercent20_transparent()
{
var expectedPattern = new Rgba32[,]
{
{ Color.HotPink, Color.Blue, Color.Blue, Color.Blue },
{ Color.Blue, Color.Blue, Color.HotPink, Color.Blue },
{ Color.HotPink, Color.Blue, Color.Blue, Color.Blue },
{ Color.Blue, Color.Blue, Color.HotPink, Color.Blue }
};
this.Test(
"Percent20_Transparent",
Color.Blue,
Brushes.Percent20(Color.HotPink),
new Rgba32[,]
{
{ Color.HotPink, Color.Blue, Color.Blue, Color.Blue },
{ Color.Blue, Color.Blue, Color.HotPink, Color.Blue },
{ Color.HotPink, Color.Blue, Color.Blue, Color.Blue },
{ Color.Blue, Color.Blue, Color.HotPink, Color.Blue }
});
expectedPattern);
}
[Fact]
public void ImageShouldBeFloodFilledWithHorizontal()
{
var expectedPattern = new Rgba32[,]
{
{ Color.LimeGreen, Color.LimeGreen, Color.LimeGreen, Color.LimeGreen },
{ Color.HotPink, Color.HotPink, Color.HotPink, Color.HotPink },
{ Color.LimeGreen, Color.LimeGreen, Color.LimeGreen, Color.LimeGreen },
{ Color.LimeGreen, Color.LimeGreen, Color.LimeGreen, Color.LimeGreen }
};
this.Test(
"Horizontal",
Color.Blue,
Brushes.Horizontal(Color.HotPink, Color.LimeGreen),
new Rgba32[,]
{
{ Color.LimeGreen, Color.LimeGreen, Color.LimeGreen, Color.LimeGreen },
{ Color.HotPink, Color.HotPink, Color.HotPink, Color.HotPink },
{ Color.LimeGreen, Color.LimeGreen, Color.LimeGreen, Color.LimeGreen },
{ Color.LimeGreen, Color.LimeGreen, Color.LimeGreen, Color.LimeGreen }
});
expectedPattern);
}
[Fact]
public void ImageShouldBeFloodFilledWithHorizontal_transparent()
{
var expectedPattern = new Rgba32[,]
{
{ Color.Blue, Color.Blue, Color.Blue, Color.Blue },
{ Color.HotPink, Color.HotPink, Color.HotPink, Color.HotPink },
{ Color.Blue, Color.Blue, Color.Blue, Color.Blue },
{ Color.Blue, Color.Blue, Color.Blue, Color.Blue }
};
this.Test(
"Horizontal_Transparent",
Color.Blue,
Brushes.Horizontal(Color.HotPink),
new Rgba32[,]
{
{ Color.Blue, Color.Blue, Color.Blue, Color.Blue },
{ Color.HotPink, Color.HotPink, Color.HotPink, Color.HotPink },
{ Color.Blue, Color.Blue, Color.Blue, Color.Blue },
{ Color.Blue, Color.Blue, Color.Blue, Color.Blue }
});
expectedPattern);
}
[Fact]
public void ImageShouldBeFloodFilledWithMin()
{
var expectedPattern = new Rgba32[,]
{
{ Color.LimeGreen, Color.LimeGreen, Color.LimeGreen, Color.LimeGreen },
{ Color.LimeGreen, Color.LimeGreen, Color.LimeGreen, Color.LimeGreen },
{ Color.LimeGreen, Color.LimeGreen, Color.LimeGreen, Color.LimeGreen },
{ Color.HotPink, Color.HotPink, Color.HotPink, Color.HotPink }
};
this.Test(
"Min",
Color.Blue,
Brushes.Min(Color.HotPink, Color.LimeGreen),
new Rgba32[,]
{
{ Color.LimeGreen, Color.LimeGreen, Color.LimeGreen, Color.LimeGreen },
{ Color.LimeGreen, Color.LimeGreen, Color.LimeGreen, Color.LimeGreen },
{ Color.LimeGreen, Color.LimeGreen, Color.LimeGreen, Color.LimeGreen },
{ Color.HotPink, Color.HotPink, Color.HotPink, Color.HotPink }
});
expectedPattern);
}
[Fact]
public void ImageShouldBeFloodFilledWithMin_transparent()
{
var expectedPattern = new Rgba32[,]
{
{ Color.Blue, Color.Blue, Color.Blue, Color.Blue },
{ Color.Blue, Color.Blue, Color.Blue, Color.Blue },
{ Color.Blue, Color.Blue, Color.Blue, Color.Blue },
{ Color.HotPink, Color.HotPink, Color.HotPink, Color.HotPink },
};
this.Test(
"Min_Transparent",
Color.Blue,
Brushes.Min(Color.HotPink),
new Rgba32[,]
{
{ Color.Blue, Color.Blue, Color.Blue, Color.Blue },
{ Color.Blue, Color.Blue, Color.Blue, Color.Blue },
{ Color.Blue, Color.Blue, Color.Blue, Color.Blue },
{ Color.HotPink, Color.HotPink, Color.HotPink, Color.HotPink },
});
expectedPattern);
}
[Fact]
public void ImageShouldBeFloodFilledWithVertical()
{
var expectedPattern = new Rgba32[,]
{
{ Color.LimeGreen, Color.HotPink, Color.LimeGreen, Color.LimeGreen },
{ Color.LimeGreen, Color.HotPink, Color.LimeGreen, Color.LimeGreen },
{ Color.LimeGreen, Color.HotPink, Color.LimeGreen, Color.LimeGreen },
{ Color.LimeGreen, Color.HotPink, Color.LimeGreen, Color.LimeGreen }
};
this.Test(
"Vertical",
Color.Blue,
Brushes.Vertical(Color.HotPink, Color.LimeGreen),
new Rgba32[,]
{
{ Color.LimeGreen, Color.HotPink, Color.LimeGreen, Color.LimeGreen },
{ Color.LimeGreen, Color.HotPink, Color.LimeGreen, Color.LimeGreen },
{ Color.LimeGreen, Color.HotPink, Color.LimeGreen, Color.LimeGreen },
{ Color.LimeGreen, Color.HotPink, Color.LimeGreen, Color.LimeGreen }
});
expectedPattern);
}
[Fact]
public void ImageShouldBeFloodFilledWithVertical_transparent()
{
var expectedPattern = new Rgba32[,]
{
{ Color.Blue, Color.HotPink, Color.Blue, Color.Blue },
{ Color.Blue, Color.HotPink, Color.Blue, Color.Blue },
{ Color.Blue, Color.HotPink, Color.Blue, Color.Blue },
{ Color.Blue, Color.HotPink, Color.Blue, Color.Blue }
};
this.Test(
"Vertical_Transparent",
Color.Blue,
Brushes.Vertical(Color.HotPink),
new Rgba32[,]
{
{ Color.Blue, Color.HotPink, Color.Blue, Color.Blue },
{ Color.Blue, Color.HotPink, Color.Blue, Color.Blue },
{ Color.Blue, Color.HotPink, Color.Blue, Color.Blue },
{ Color.Blue, Color.HotPink, Color.Blue, Color.Blue }
});
expectedPattern);
}
[Fact]
public void ImageShouldBeFloodFilledWithForwardDiagonal()
{
var expectedPattern = new Rgba32[,]
{
{ Color.LimeGreen, Color.LimeGreen, Color.LimeGreen, Color.HotPink },
{ Color.LimeGreen, Color.LimeGreen, Color.HotPink, Color.LimeGreen },
{ Color.LimeGreen, Color.HotPink, Color.LimeGreen, Color.LimeGreen },
{ Color.HotPink, Color.LimeGreen, Color.LimeGreen, Color.LimeGreen }
};
this.Test(
"ForwardDiagonal",
Color.Blue,
Brushes.ForwardDiagonal(Color.HotPink, Color.LimeGreen),
new Rgba32[,]
{
{ Color.LimeGreen, Color.LimeGreen, Color.LimeGreen, Color.HotPink },
{ Color.LimeGreen, Color.LimeGreen, Color.HotPink, Color.LimeGreen },
{ Color.LimeGreen, Color.HotPink, Color.LimeGreen, Color.LimeGreen },
{ Color.HotPink, Color.LimeGreen, Color.LimeGreen, Color.LimeGreen }
});
expectedPattern);
}
[Fact]
public void ImageShouldBeFloodFilledWithForwardDiagonal_transparent()
{
var expectedPattern = new Rgba32[,]
{
{ Color.Blue, Color.Blue, Color.Blue, Color.HotPink },
{ Color.Blue, Color.Blue, Color.HotPink, Color.Blue },
{ Color.Blue, Color.HotPink, Color.Blue, Color.Blue },
{ Color.HotPink, Color.Blue, Color.Blue, Color.Blue }
};
this.Test(
"ForwardDiagonal_Transparent",
Color.Blue,
Brushes.ForwardDiagonal(Color.HotPink),
new Rgba32[,]
{
{ Color.Blue, Color.Blue, Color.Blue, Color.HotPink },
{ Color.Blue, Color.Blue, Color.HotPink, Color.Blue },
{ Color.Blue, Color.HotPink, Color.Blue, Color.Blue },
{ Color.HotPink, Color.Blue, Color.Blue, Color.Blue }
});
expectedPattern);
}
[Fact]
public void ImageShouldBeFloodFilledWithBackwardDiagonal()
{
var expectedPattern = new Rgba32[,]
{
{ Color.HotPink, Color.LimeGreen, Color.LimeGreen, Color.LimeGreen },
{ Color.LimeGreen, Color.HotPink, Color.LimeGreen, Color.LimeGreen },
{ Color.LimeGreen, Color.LimeGreen, Color.HotPink, Color.LimeGreen },
{ Color.LimeGreen, Color.LimeGreen, Color.LimeGreen, Color.HotPink }
};
this.Test(
"BackwardDiagonal",
Color.Blue,
Brushes.BackwardDiagonal(Color.HotPink, Color.LimeGreen),
new Rgba32[,]
{
{ Color.HotPink, Color.LimeGreen, Color.LimeGreen, Color.LimeGreen },
{ Color.LimeGreen, Color.HotPink, Color.LimeGreen, Color.LimeGreen },
{ Color.LimeGreen, Color.LimeGreen, Color.HotPink, Color.LimeGreen },
{ Color.LimeGreen, Color.LimeGreen, Color.LimeGreen, Color.HotPink }
});
"BackwardDiagonal",
Color.Blue,
Brushes.BackwardDiagonal(Color.HotPink, Color.LimeGreen),
expectedPattern);
}
[Fact]
public void ImageShouldBeFloodFilledWithBackwardDiagonal_transparent()
{
var expectedPattern = new Rgba32[,]
{
{ Color.HotPink, Color.Blue, Color.Blue, Color.Blue },
{ Color.Blue, Color.HotPink, Color.Blue, Color.Blue },
{ Color.Blue, Color.Blue, Color.HotPink, Color.Blue },
{ Color.Blue, Color.Blue, Color.Blue, Color.HotPink }
};
this.Test(
"BackwardDiagonal_Transparent",
Color.Blue,
Brushes.BackwardDiagonal(Color.HotPink),
new Rgba32[,]
{
{ Color.HotPink, Color.Blue, Color.Blue, Color.Blue },
{ Color.Blue, Color.HotPink, Color.Blue, Color.Blue },
{ Color.Blue, Color.Blue, Color.HotPink, Color.Blue },
{ Color.Blue, Color.Blue, Color.Blue, Color.HotPink }
});
expectedPattern);
}
}
}

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

@ -58,7 +58,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
var options = new GraphicsOptions { Antialias = antialias };
string aa = antialias ? "" : "_NoAntialias";
string aa = antialias ? string.Empty : "_NoAntialias";
FormattableString outputDetails = $"{colorName}_A{alpha}{aa}";
provider.RunValidatingProcessorTest(
@ -67,13 +67,13 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
appendSourceFileOrDescription: false);
}
public static TheoryData<bool, IntersectionRule> FillPolygon_Complex_Data =
public static TheoryData<bool, IntersectionRule> FillPolygon_Complex_Data { get; } =
new TheoryData<bool, IntersectionRule>()
{
{false, IntersectionRule.OddEven},
{false, IntersectionRule.Nonzero},
{true, IntersectionRule.OddEven},
{true, IntersectionRule.Nonzero},
{ false, IntersectionRule.OddEven },
{ false, IntersectionRule.Nonzero },
{ true, IntersectionRule.OddEven },
{ true, IntersectionRule.Nonzero },
};
[Theory]
@ -90,7 +90,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
Array.Reverse(hole);
}
ComplexPolygon polygon = new ComplexPolygon(
var polygon = new ComplexPolygon(
new Path(new LinearLineSegment(contour)),
new Path(new LinearLineSegment(hole)));
@ -129,7 +129,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
Array.Reverse(points);
}
var color = Color.LightGreen;
Color color = Color.LightGreen;
provider.RunValidatingProcessorTest(
c => c.FillPolygon(color, points),
@ -143,8 +143,8 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
[WithSolidFilledImages(64, 64, "Black", PixelTypes.Rgba32)]
public void FillPolygon_StarCircle(TestImageProvider<Rgba32> provider)
{
EllipsePolygon circle = new EllipsePolygon(32, 32, 30);
Star star = new Star(32, 32, 7, 10, 27);
var circle = new EllipsePolygon(32, 32, 30);
var star = new Star(32, 32, 7, 10, 27);
IPath shape = circle.Clip(star);
provider.RunValidatingProcessorTest(
@ -163,9 +163,9 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
{
new Vector2(10, 10), new Vector2(200, 150), new Vector2(50, 300)
};
var color = Color.Yellow;
Color color = Color.Yellow;
var brush = Brushes.Horizontal(color);
PatternBrush brush = Brushes.Horizontal(color);
provider.RunValidatingProcessorTest(
c => c.FillPolygon(brush, simplePath),
@ -200,7 +200,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
where TPixel : unmanaged, IPixel<TPixel>
{
var polygon = new RectangularPolygon(10, 10, 190, 140);
var color = Color.White;
Color color = Color.White;
provider.RunValidatingProcessorTest(
c => c.Fill(color, polygon),
@ -218,7 +218,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
{
float angle = GeometryUtilities.DegreeToRadian(angleDeg);
var polygon = new RegularPolygon(100, 100, vertices, radius, angle);
var color = Color.Yellow;
Color color = Color.Yellow;
FormattableString testOutput = $"V({vertices})_R({radius})_Ang({angleDeg})";
provider.RunValidatingProcessorTest(
@ -231,10 +231,10 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
public static readonly TheoryData<bool, IntersectionRule> Fill_EllipsePolygon_Data =
new TheoryData<bool, IntersectionRule>()
{
{ false, IntersectionRule.OddEven},
{ false, IntersectionRule.Nonzero},
{ true, IntersectionRule.OddEven},
{ true, IntersectionRule.Nonzero},
{ false, IntersectionRule.OddEven },
{ false, IntersectionRule.Nonzero },
{ true, IntersectionRule.OddEven },
{ true, IntersectionRule.Nonzero },
};
[Theory]
@ -248,7 +248,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
polygon = polygon.Reverse();
}
var color = Color.Azure;
Color color = Color.Azure;
provider.RunValidatingProcessorTest(
c =>
@ -269,9 +269,8 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
public void Fill_IntersectionRules_OddEven<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
using (var img = provider.GetImage())
using (Image<TPixel> img = provider.GetImage())
{
var poly = new Polygon(new LinearLineSegment(
new PointF(10, 30),
new PointF(10, 20),
@ -305,7 +304,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
where TPixel : unmanaged, IPixel<TPixel>
{
Configuration.Default.MaxDegreeOfParallelism = 1;
using (var img = provider.GetImage())
using (Image<TPixel> img = provider.GetImage())
{
var poly = new Polygon(new LinearLineSegment(
new PointF(10, 30),

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

@ -1,3 +1,6 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
@ -14,7 +17,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
public static ImageComparer TolerantComparer = ImageComparer.TolerantPercentage(0.01f);
[Theory]
[WithBlankImages(200, 200, PixelTypes.Rgba32)]
[WithBlankImage(200, 200, PixelTypes.Rgba32)]
public void WithEqualColorsReturnsUnicolorImage<TPixel>(
TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
@ -41,11 +44,11 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
}
[Theory]
[WithBlankImages(200, 200, PixelTypes.Rgba32, 100, 100)]
[WithBlankImages(200, 200, PixelTypes.Rgba32, 0, 0)]
[WithBlankImages(200, 200, PixelTypes.Rgba32, 100, 0)]
[WithBlankImages(200, 200, PixelTypes.Rgba32, 0, 100)]
[WithBlankImages(200, 200, PixelTypes.Rgba32, -40, 100)]
[WithBlankImage(200, 200, PixelTypes.Rgba32, 100, 100)]
[WithBlankImage(200, 200, PixelTypes.Rgba32, 0, 0)]
[WithBlankImage(200, 200, PixelTypes.Rgba32, 100, 0)]
[WithBlankImage(200, 200, PixelTypes.Rgba32, 0, 100)]
[WithBlankImage(200, 200, PixelTypes.Rgba32, -40, 100)]
public void WithDifferentCentersReturnsImage<TPixel>(
TestImageProvider<TPixel> provider,
int centerX,

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

@ -30,10 +30,10 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
[Fact]
public void DrawOffCanvas()
{
using (var img = new Image<Rgba32>(10, 10))
{
img.Mutate(x => x.DrawLines(new Pen(Color.Black, 10),
img.Mutate(x => x.DrawLines(
new Pen(Color.Black, 10),
new Vector2(-10, 5),
new Vector2(20, 5)));
}
@ -47,9 +47,8 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
{
img.Mutate(x => x.Fill(Color.Transparent));
img.Mutate(ctx =>
{
ctx.DrawLines(
img.Mutate(
ctx => ctx.DrawLines(
Color.Red,
0.984252f,
new PointF(104.762581f, 1074.99365f),
@ -59,10 +58,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
new PointF(104.764488f, 1075.08838f),
new PointF(104.772186f, 1075.111f),
new PointF(104.782608f, 1075.13245f),
new PointF(104.782608f, 1075.13245f)
);
}
);
new PointF(104.782608f, 1075.13245f)));
}
}
@ -74,13 +70,9 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
var path = new Polygon(
new LinearLineSegment(new PointF(17.11f, 13.99659f), new PointF(14.01433f, 27.06201f)),
new LinearLineSegment(new PointF(14.01433f, 27.06201f), new PointF(13.79267f, 14.00023f)),
new LinearLineSegment(new PointF(13.79267f, 14.00023f), new PointF(17.11f, 13.99659f))
);
new LinearLineSegment(new PointF(13.79267f, 14.00023f), new PointF(17.11f, 13.99659f)));
image.Mutate(ctx =>
{
ctx.Fill(Color.White, path);
});
image.Mutate(ctx => ctx.Fill(Color.White, path));
}
}
@ -88,17 +80,17 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
private class MockRegion1 : Region
{
public override Rectangle Bounds => new Rectangle(-100, -10, 10, 10);
internal override IPath Shape => throw new NotImplementedException();
}
private class MockRegion2 : Region
{
public MockRegion2(Rectangle bounds)
{
this.Bounds = bounds;
}
=> this.Bounds = bounds;
public override Rectangle Bounds { get; }
internal override IPath Shape => throw new NotImplementedException();
}
}

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

@ -8,25 +8,23 @@ using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using Xunit;
// ReSharper disable InconsistentNaming
namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
{
[GroupOutput("Drawing")]
public class FillSolidBrushTests
{
[Theory]
[WithBlankImages(1, 1, PixelTypes.Rgba32)]
[WithBlankImages(7, 4, PixelTypes.Rgba32)]
[WithBlankImages(16, 7, PixelTypes.Rgba32)]
[WithBlankImages(33, 32, PixelTypes.Rgba32)]
[WithBlankImages(400, 500, PixelTypes.Rgba32)]
[WithBlankImage(1, 1, PixelTypes.Rgba32)]
[WithBlankImage(7, 4, PixelTypes.Rgba32)]
[WithBlankImage(16, 7, PixelTypes.Rgba32)]
[WithBlankImage(33, 32, PixelTypes.Rgba32)]
[WithBlankImage(400, 500, PixelTypes.Rgba32)]
public void DoesNotDependOnSize<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
using (Image<TPixel> image = provider.GetImage())
{
var color = Color.HotPink;
Color color = Color.HotPink;
image.Mutate(c => c.Fill(color));
image.DebugSave(provider, appendPixelTypeToFileName: false);
@ -35,13 +33,13 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
}
[Theory]
[WithBlankImages(16, 16, PixelTypes.Rgba32 | PixelTypes.Argb32 | PixelTypes.RgbaVector)]
[WithBlankImage(16, 16, PixelTypes.Rgba32 | PixelTypes.Argb32 | PixelTypes.RgbaVector)]
public void DoesNotDependOnSinglePixelType<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
using (Image<TPixel> image = provider.GetImage())
{
var color = Color.HotPink;
Color color = Color.HotPink;
image.Mutate(c => c.Fill(color));
image.DebugSave(provider, appendSourceFileOrDescription: false);
@ -172,11 +170,11 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
var testOutputDetails = new
{
triggerFillRegion = triggerFillRegion,
newColorName = newColorName,
alpha = alpha,
blenderMode = blenderMode,
blendPercentage = blendPercentage
triggerFillRegion,
newColorName,
alpha,
blenderMode,
blendPercentage
};
image.DebugSave(

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

@ -13,15 +13,16 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
{
public class Clear : BaseImageOperationsExtensionTest
{
GraphicsOptionsComparer clearComparer = new GraphicsOptionsComparer() { SkipClearOptions = true };
GraphicsOptions nonDefaultOptions = new GraphicsOptions()
private readonly GraphicsOptionsComparer clearComparer = new GraphicsOptionsComparer() { SkipClearOptions = true };
private readonly GraphicsOptions nonDefaultOptions = new GraphicsOptions()
{
AlphaCompositionMode = PixelFormats.PixelAlphaCompositionMode.Clear,
BlendPercentage = 0.5f,
ColorBlendingMode = PixelFormats.PixelColorBlendingMode.Darken,
AntialiasSubpixelDepth = 99
};
IBrush brush = new SolidBrush(Color.HotPink);
private readonly IBrush brush = new SolidBrush(Color.HotPink);
[Fact]
public void Brush()
@ -57,7 +58,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
Assert.Equal(this.nonDefaultOptions, processor.Options, this.clearComparer);
var solidBrush = Assert.IsType<SolidBrush>(processor.Brush);
SolidBrush solidBrush = Assert.IsType<SolidBrush>(processor.Brush);
Assert.Equal(Color.Red, solidBrush.Color);
}
@ -70,7 +71,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
Assert.Equal(this.options, processor.Options, this.clearComparer);
var solidBrush = Assert.IsType<SolidBrush>(processor.Brush);
SolidBrush solidBrush = Assert.IsType<SolidBrush>(processor.Brush);
Assert.Equal(Color.Red, solidBrush.Color);
}
}

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

@ -1,7 +1,6 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System.Numerics;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.Drawing.Processing.Processors.Drawing;
using SixLabors.ImageSharp.Drawing.Tests.Processing;
@ -12,17 +11,19 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
{
public class ClearPath : BaseImageOperationsExtensionTest
{
GraphicsOptionsComparer clearComparer = new GraphicsOptionsComparer() { SkipClearOptions = true };
ShapeGraphicsOptions nonDefaultOptions = new ShapeGraphicsOptions()
private readonly GraphicsOptionsComparer clearComparer = new GraphicsOptionsComparer() { SkipClearOptions = true };
private readonly ShapeGraphicsOptions nonDefaultOptions = new ShapeGraphicsOptions()
{
GraphicsOptions = {
GraphicsOptions =
{
AlphaCompositionMode = PixelFormats.PixelAlphaCompositionMode.Clear,
BlendPercentage = 0.5f,
ColorBlendingMode = PixelFormats.PixelColorBlendingMode.Darken
}
};
IBrush brush = Brushes.Solid(Color.HotPink);
IPath path = new Star(1, 10, 5, 23, 56);
private readonly IBrush brush = Brushes.Solid(Color.HotPink);
private readonly IPath path = new Star(1, 10, 5, 23, 56);
[Fact]
public void Brush()
@ -31,7 +32,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
FillPathProcessor processor = this.Verify<FillPathProcessor>();
var expectedOptions = this.nonDefaultOptions;
ShapeGraphicsOptions expectedOptions = this.nonDefaultOptions;
Assert.Equal(expectedOptions.ShapeOptions, processor.Options.ShapeOptions);
Assert.Equal(1, processor.Options.GraphicsOptions.BlendPercentage);
Assert.Equal(PixelFormats.PixelAlphaCompositionMode.Src, processor.Options.GraphicsOptions.AlphaCompositionMode);
@ -48,7 +49,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
FillPathProcessor processor = this.Verify<FillPathProcessor>();
var expectedOptions = this.shapeOptions;
ShapeOptions expectedOptions = this.shapeOptions;
Assert.Equal(expectedOptions, processor.Options.ShapeOptions);
Assert.Equal(1, processor.Options.GraphicsOptions.BlendPercentage);
Assert.Equal(PixelFormats.PixelAlphaCompositionMode.Src, processor.Options.GraphicsOptions.AlphaCompositionMode);
@ -65,7 +66,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
FillPathProcessor processor = this.Verify<FillPathProcessor>();
var expectedOptions = this.nonDefaultOptions;
ShapeGraphicsOptions expectedOptions = this.nonDefaultOptions;
Assert.Equal(expectedOptions.ShapeOptions, processor.Options.ShapeOptions);
Assert.Equal(1, processor.Options.GraphicsOptions.BlendPercentage);
@ -73,7 +74,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
Assert.Equal(PixelFormats.PixelColorBlendingMode.Normal, processor.Options.GraphicsOptions.ColorBlendingMode);
Assert.Equal(this.path, processor.Shape);
Assert.NotEqual(this.brush, processor.Brush);
var brush = Assert.IsType<SolidBrush>(processor.Brush);
SolidBrush brush = Assert.IsType<SolidBrush>(processor.Brush);
Assert.Equal(Color.Red, brush.Color);
}
@ -84,16 +85,15 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
FillPathProcessor processor = this.Verify<FillPathProcessor>();
var expectedOptions = this.shapeOptions;
ShapeOptions expectedOptions = this.shapeOptions;
Assert.Equal(expectedOptions, processor.Options.ShapeOptions);
Assert.Equal(1, processor.Options.GraphicsOptions.BlendPercentage);
Assert.Equal(PixelFormats.PixelAlphaCompositionMode.Src, processor.Options.GraphicsOptions.AlphaCompositionMode);
Assert.Equal(PixelFormats.PixelColorBlendingMode.Normal, processor.Options.GraphicsOptions.ColorBlendingMode);
Assert.Equal(this.path, processor.Shape);
Assert.NotEqual(this.brush, processor.Brush);
var brush = Assert.IsType<SolidBrush>(processor.Brush);
SolidBrush brush = Assert.IsType<SolidBrush>(processor.Brush);
Assert.Equal(Color.Red, brush.Color);
}
}

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

@ -1,20 +1,19 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System.Numerics;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.Drawing.Processing.Processors.Drawing;
using SixLabors.ImageSharp.Drawing.Tests.Processing;
using SixLabors.ImageSharp.Drawing.Tests.TestUtilities;
using Xunit;
namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
{
public class ClearRectangle : BaseImageOperationsExtensionTest
{
IBrush brush = Brushes.Solid(Color.HotPink);
RectangleF rectangle = new RectangleF(10, 10, 20, 20);
RectangularPolygon rectanglePolygon => new RectangularPolygon(rectangle);
private readonly IBrush brush = Brushes.Solid(Color.HotPink);
private RectangleF rectangle = new RectangleF(10, 10, 20, 20);
private RectangularPolygon RectanglePolygon => new RectangularPolygon(this.rectangle);
[Fact]
public void Brush()
@ -24,7 +23,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
FillPathProcessor processor = this.Verify<FillPathProcessor>();
Assert.NotEqual(this.shapeOptions, processor.Options.ShapeOptions);
Assert.Equal(this.rectanglePolygon, processor.Shape);
Assert.Equal(this.RectanglePolygon, processor.Shape);
Assert.Equal(this.brush, processor.Brush);
}
@ -36,7 +35,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
FillPathProcessor processor = this.Verify<FillPathProcessor>();
Assert.Equal(this.shapeOptions, processor.Options.ShapeOptions);
Assert.Equal(this.rectanglePolygon, processor.Shape);
Assert.Equal(this.RectanglePolygon, processor.Shape);
Assert.Equal(this.brush, processor.Brush);
}
@ -48,9 +47,9 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
FillPathProcessor processor = this.Verify<FillPathProcessor>();
Assert.NotEqual(this.shapeOptions, processor.Options.ShapeOptions);
Assert.Equal(this.rectanglePolygon, processor.Shape);
Assert.Equal(this.RectanglePolygon, processor.Shape);
Assert.NotEqual(this.brush, processor.Brush);
var brush = Assert.IsType<SolidBrush>(processor.Brush);
SolidBrush brush = Assert.IsType<SolidBrush>(processor.Brush);
Assert.Equal(Color.Red, brush.Color);
}
@ -62,9 +61,9 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
FillPathProcessor processor = this.Verify<FillPathProcessor>();
Assert.Equal(this.shapeOptions, processor.Options.ShapeOptions);
Assert.Equal(this.rectanglePolygon, processor.Shape);
Assert.Equal(this.RectanglePolygon, processor.Shape);
Assert.NotEqual(this.brush, processor.Brush);
var brush = Assert.IsType<SolidBrush>(processor.Brush);
SolidBrush brush = Assert.IsType<SolidBrush>(processor.Brush);
Assert.Equal(Color.Red, brush.Color);
}
}

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

@ -1,27 +1,27 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System.Numerics;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.Drawing.Processing.Processors.Drawing;
using SixLabors.ImageSharp.Drawing.Tests.Processing;
using SixLabors.ImageSharp.Drawing.Tests.TestUtilities;
using Xunit;
namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
{
public class ClearRegion : BaseImageOperationsExtensionTest
{
ShapeGraphicsOptions nonDefaultOptions = new ShapeGraphicsOptions()
private readonly ShapeGraphicsOptions nonDefaultOptions = new ShapeGraphicsOptions()
{
GraphicsOptions = {
GraphicsOptions =
{
AlphaCompositionMode = PixelFormats.PixelAlphaCompositionMode.Clear,
BlendPercentage = 0.5f,
ColorBlendingMode = PixelFormats.PixelColorBlendingMode.Darken
}
};
IBrush brush = Brushes.Solid(Color.HotPink);
Region path = new ShapeRegion(new EllipsePolygon(10, 10, 100));
private readonly IBrush brush = Brushes.Solid(Color.HotPink);
private readonly Region path = new ShapeRegion(new EllipsePolygon(10, 10, 100));
[Fact]
public void Brush()
@ -30,13 +30,12 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
FillRegionProcessor processor = this.Verify<FillRegionProcessor>();
var expectedOptions = this.nonDefaultOptions;
ShapeGraphicsOptions expectedOptions = this.nonDefaultOptions;
Assert.Equal(expectedOptions.ShapeOptions, processor.Options.ShapeOptions);
Assert.Equal(1, processor.Options.GraphicsOptions.BlendPercentage);
Assert.Equal(PixelFormats.PixelAlphaCompositionMode.Src, processor.Options.GraphicsOptions.AlphaCompositionMode);
Assert.Equal(PixelFormats.PixelColorBlendingMode.Normal, processor.Options.GraphicsOptions.ColorBlendingMode);
Assert.Equal(this.path, processor.Region);
Assert.Equal(this.brush, processor.Brush);
}
@ -48,7 +47,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
FillRegionProcessor processor = this.Verify<FillRegionProcessor>();
var expectedOptions = this.shapeOptions;
ShapeOptions expectedOptions = this.shapeOptions;
Assert.Equal(expectedOptions, processor.Options.ShapeOptions);
Assert.Equal(1, processor.Options.GraphicsOptions.BlendPercentage);
Assert.Equal(PixelFormats.PixelAlphaCompositionMode.Src, processor.Options.GraphicsOptions.AlphaCompositionMode);
@ -65,7 +64,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
FillRegionProcessor processor = this.Verify<FillRegionProcessor>();
var expectedOptions = this.nonDefaultOptions;
ShapeGraphicsOptions expectedOptions = this.nonDefaultOptions;
Assert.Equal(expectedOptions.ShapeOptions, processor.Options.ShapeOptions);
Assert.Equal(1, processor.Options.GraphicsOptions.BlendPercentage);
@ -73,7 +72,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
Assert.Equal(PixelFormats.PixelColorBlendingMode.Normal, processor.Options.GraphicsOptions.ColorBlendingMode);
Assert.Equal(this.path, processor.Region);
Assert.NotEqual(this.brush, processor.Brush);
var brush = Assert.IsType<SolidBrush>(processor.Brush);
SolidBrush brush = Assert.IsType<SolidBrush>(processor.Brush);
Assert.Equal(Color.Red, brush.Color);
}
@ -84,16 +83,15 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
FillRegionProcessor processor = this.Verify<FillRegionProcessor>();
var expectedOptions = this.shapeOptions;
ShapeOptions expectedOptions = this.shapeOptions;
Assert.Equal(expectedOptions, processor.Options.ShapeOptions);
Assert.Equal(1, processor.Options.GraphicsOptions.BlendPercentage);
Assert.Equal(PixelFormats.PixelAlphaCompositionMode.Src, processor.Options.GraphicsOptions.AlphaCompositionMode);
Assert.Equal(PixelFormats.PixelColorBlendingMode.Normal, processor.Options.GraphicsOptions.ColorBlendingMode);
Assert.Equal(this.path, processor.Region);
Assert.NotEqual(this.brush, processor.Brush);
var brush = Assert.IsType<SolidBrush>(processor.Brush);
SolidBrush brush = Assert.IsType<SolidBrush>(processor.Brush);
Assert.Equal(Color.Red, brush.Color);
}
}

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

@ -2,34 +2,32 @@
// Licensed under the Apache License, Version 2.0.
using System.Linq;
using System.Numerics;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.Drawing.Processing.Processors.Drawing;
using SixLabors.ImageSharp.Drawing.Tests.Processing;
using SixLabors.ImageSharp.Drawing.Tests.TestUtilities;
using Xunit;
namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
{
public class DrawBezier : BaseImageOperationsExtensionTest
{
IPen pen = Pens.Solid(Color.HotPink, 2);
PointF[] points = new PointF[]{
private readonly IPen pen = Pens.Solid(Color.HotPink, 2);
private readonly PointF[] points = new PointF[]
{
new PointF(10, 10),
new PointF(20, 20),
new PointF(20, 50),
new PointF(50, 10)
};
};
private void VerifyPoints(PointF[] expectedPoints, IPath path)
{
var innerPath = Assert.IsType<Path>(path);
var segment = Assert.Single(innerPath.LineSegments);
var bezierSegment = Assert.IsType<CubicBezierLineSegment>(segment);
Path innerPath = Assert.IsType<Path>(path);
ILineSegment segment = Assert.Single(innerPath.LineSegments);
CubicBezierLineSegment bezierSegment = Assert.IsType<CubicBezierLineSegment>(segment);
Assert.Equal(expectedPoints, bezierSegment.ControlPoints.ToArray());
var simplePath = Assert.Single(path.Flatten());
ISimplePath simplePath = Assert.Single(path.Flatten());
Assert.False(simplePath.IsClosed);
}
@ -92,7 +90,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
Assert.NotEqual(this.shapeOptions, processor.Options.ShapeOptions);
this.VerifyPoints(this.points, processor.Shape);
var brush = Assert.IsType<SolidBrush>(processor.Pen.StrokeFill);
SolidBrush brush = Assert.IsType<SolidBrush>(processor.Pen.StrokeFill);
Assert.Equal(Color.Red, brush.Color);
Assert.Equal(10, processor.Pen.StrokeWidth);
}
@ -106,7 +104,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
Assert.Equal(this.shapeOptions, processor.Options.ShapeOptions);
this.VerifyPoints(this.points, processor.Shape);
var brush = Assert.IsType<SolidBrush>(processor.Pen.StrokeFill);
SolidBrush brush = Assert.IsType<SolidBrush>(processor.Pen.StrokeFill);
Assert.Equal(Color.Red, brush.Color);
Assert.Equal(10, processor.Pen.StrokeWidth);
}

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

@ -1,30 +1,27 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System.Linq;
using System.Numerics;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.Drawing.Processing.Processors.Drawing;
using SixLabors.ImageSharp.Drawing.Tests.Processing;
using SixLabors.ImageSharp.Drawing.Tests.TestUtilities;
using Xunit;
namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
{
public class DrawLine : BaseImageOperationsExtensionTest
{
IPen pen = Pens.Solid(Color.HotPink, 2);
PointF[] points = new PointF[]{
private readonly IPen pen = Pens.Solid(Color.HotPink, 2);
private readonly PointF[] points = new PointF[]
{
new PointF(10, 10),
new PointF(20, 20),
new PointF(20, 50),
new PointF(50, 10)
};
};
private void VerifyPoints(PointF[] expectedPoints, IPath path)
{
var simplePath = Assert.Single(path.Flatten());
ISimplePath simplePath = Assert.Single(path.Flatten());
Assert.False(simplePath.IsClosed);
Assert.Equal(expectedPoints, simplePath.Points.ToArray());
}
@ -88,7 +85,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
Assert.NotEqual(this.shapeOptions, processor.Options.ShapeOptions);
this.VerifyPoints(this.points, processor.Shape);
var brush = Assert.IsType<SolidBrush>(processor.Pen.StrokeFill);
SolidBrush brush = Assert.IsType<SolidBrush>(processor.Pen.StrokeFill);
Assert.Equal(Color.Red, brush.Color);
Assert.Equal(10, processor.Pen.StrokeWidth);
}
@ -102,7 +99,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
Assert.Equal(this.shapeOptions, processor.Options.ShapeOptions);
this.VerifyPoints(this.points, processor.Shape);
var brush = Assert.IsType<SolidBrush>(processor.Pen.StrokeFill);
SolidBrush brush = Assert.IsType<SolidBrush>(processor.Pen.StrokeFill);
Assert.Equal(Color.Red, brush.Color);
Assert.Equal(10, processor.Pen.StrokeWidth);
}

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

@ -1,21 +1,17 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System.Linq;
using System.Numerics;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.Drawing.Processing.Processors.Drawing;
using SixLabors.ImageSharp.Drawing.Tests.Processing;
using SixLabors.ImageSharp.Drawing.Tests.TestUtilities;
using Xunit;
namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
{
public class DrawPath : BaseImageOperationsExtensionTest
{
IPen pen = Pens.Solid(Color.HotPink, 2);
IPath path = new EllipsePolygon(10, 10, 100);
private readonly IPen pen = Pens.Solid(Color.HotPink, 2);
private readonly IPath path = new EllipsePolygon(10, 10, 100);
[Fact]
public void Pen()
@ -76,7 +72,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
Assert.NotEqual(this.shapeOptions, processor.Options.ShapeOptions);
Assert.Equal(this.path, processor.Shape);
var brush = Assert.IsType<SolidBrush>(processor.Pen.StrokeFill);
SolidBrush brush = Assert.IsType<SolidBrush>(processor.Pen.StrokeFill);
Assert.Equal(Color.Red, brush.Color);
Assert.Equal(10, processor.Pen.StrokeWidth);
}
@ -90,7 +86,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
Assert.Equal(this.shapeOptions, processor.Options.ShapeOptions);
Assert.Equal(this.path, processor.Shape);
var brush = Assert.IsType<SolidBrush>(processor.Pen.StrokeFill);
SolidBrush brush = Assert.IsType<SolidBrush>(processor.Pen.StrokeFill);
Assert.Equal(Color.Red, brush.Color);
Assert.Equal(10, processor.Pen.StrokeWidth);
}

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

@ -1,6 +1,7 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System.Collections.Generic;
using System.Numerics;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.Drawing.Processing.Processors.Drawing;
@ -12,35 +13,37 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
{
public class DrawPathCollection : BaseImageOperationsExtensionTest
{
GraphicsOptions nonDefault = new GraphicsOptions { Antialias = false };
Color color = Color.HotPink;
Pen pen = Pens.Solid(Color.HotPink, 1);
IPath path1 = new Path(new LinearLineSegment(new PointF[] {
new Vector2(10,10),
new Vector2(20,10),
new Vector2(20,10),
new Vector2(30,10),
}));
private readonly GraphicsOptions nonDefault = new GraphicsOptions { Antialias = false };
private readonly Color color = Color.HotPink;
private readonly Pen pen = Pens.Solid(Color.HotPink, 1);
private readonly IPath path1 = new Path(new LinearLineSegment(
new PointF[]
{
new Vector2(10, 10),
new Vector2(20, 10),
new Vector2(20, 10),
new Vector2(30, 10),
}));
IPath path2 = new Path(new LinearLineSegment(new PointF[] {
new Vector2(10,10),
new Vector2(20,10),
new Vector2(20,10),
new Vector2(30,10),
}));
private readonly IPath path2 = new Path(new LinearLineSegment(
new PointF[]
{
new Vector2(10, 10),
new Vector2(20, 10),
new Vector2(20, 10),
new Vector2(30, 10),
}));
IPathCollection pathCollection;
private readonly IPathCollection pathCollection;
public DrawPathCollection()
{
this.pathCollection = new PathCollection(this.path1, this.path2);
}
=> this.pathCollection = new PathCollection(this.path1, this.path2);
[Fact]
public void Pen()
{
this.operations.Draw(new ShapeGraphicsOptions(), this.pen, this.pathCollection);
var processors = this.VerifyAll<DrawPathProcessor>();
IEnumerable<DrawPathProcessor> processors = this.VerifyAll<DrawPathProcessor>();
Assert.All(processors, p =>
{
@ -48,16 +51,17 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
Assert.Equal(this.pen, p.Pen);
});
Assert.Collection(processors,
p => Assert.Equal(this.path1, p.Shape),
p => Assert.Equal(this.path2, p.Shape));
Assert.Collection(
processors,
p => Assert.Equal(this.path1, p.Shape),
p => Assert.Equal(this.path2, p.Shape));
}
[Fact]
public void PenDefaultOptions()
{
this.operations.Draw(this.pen, this.pathCollection);
var processors = this.VerifyAll<DrawPathProcessor>();
IEnumerable<DrawPathProcessor> processors = this.VerifyAll<DrawPathProcessor>();
Assert.All(processors, p =>
{
@ -65,16 +69,17 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
Assert.Equal(this.pen, p.Pen);
});
Assert.Collection(processors,
p => Assert.Equal(this.path1, p.Shape),
p => Assert.Equal(this.path2, p.Shape));
Assert.Collection(
processors,
p => Assert.Equal(this.path1, p.Shape),
p => Assert.Equal(this.path2, p.Shape));
}
[Fact]
public void BrushAndThickness()
{
this.operations.Draw(new ShapeGraphicsOptions(), this.pen.StrokeFill, 10, this.pathCollection);
var processors = this.VerifyAll<DrawPathProcessor>();
IEnumerable<DrawPathProcessor> processors = this.VerifyAll<DrawPathProcessor>();
Assert.All(processors, p =>
{
@ -83,16 +88,17 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
Assert.Equal(10, p.Pen.StrokeWidth);
});
Assert.Collection(processors,
p => Assert.Equal(this.path1, p.Shape),
p => Assert.Equal(this.path2, p.Shape));
Assert.Collection(
processors,
p => Assert.Equal(this.path1, p.Shape),
p => Assert.Equal(this.path2, p.Shape));
}
[Fact]
public void BrushAndThicknessDefaultOptions()
{
this.operations.Draw(this.pen.StrokeFill, 10, this.pathCollection);
var processors = this.VerifyAll<DrawPathProcessor>();
IEnumerable<DrawPathProcessor> processors = this.VerifyAll<DrawPathProcessor>();
Assert.All(processors, p =>
{
@ -101,48 +107,50 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
Assert.Equal(10, p.Pen.StrokeWidth);
});
Assert.Collection(processors,
p => Assert.Equal(this.path1, p.Shape),
p => Assert.Equal(this.path2, p.Shape));
Assert.Collection(
processors,
p => Assert.Equal(this.path1, p.Shape),
p => Assert.Equal(this.path2, p.Shape));
}
[Fact]
public void ColorAndThickness()
{
this.operations.Draw(new ShapeGraphicsOptions(), Color.Pink, 10, this.pathCollection);
var processors = this.VerifyAll<DrawPathProcessor>();
IEnumerable<DrawPathProcessor> processors = this.VerifyAll<DrawPathProcessor>();
Assert.All(processors, p =>
{
Assert.NotEqual(this.shapeOptions, p.Options.ShapeOptions);
var brush = Assert.IsType<SolidBrush>(p.Pen.StrokeFill);
SolidBrush brush = Assert.IsType<SolidBrush>(p.Pen.StrokeFill);
Assert.Equal(Color.Pink, brush.Color);
Assert.Equal(10, p.Pen.StrokeWidth);
});
Assert.Collection(processors,
p => Assert.Equal(this.path1, p.Shape),
p => Assert.Equal(this.path2, p.Shape));
Assert.Collection(
processors,
p => Assert.Equal(this.path1, p.Shape),
p => Assert.Equal(this.path2, p.Shape));
}
[Fact]
public void ColorAndThicknessDefaultOptions()
{
this.operations.Draw(Color.Pink, 10, this.pathCollection);
var processors = this.VerifyAll<DrawPathProcessor>();
IEnumerable<DrawPathProcessor> processors = this.VerifyAll<DrawPathProcessor>();
Assert.All(processors, p =>
{
Assert.Equal(this.shapeOptions, p.Options.ShapeOptions);
var brush = Assert.IsType<SolidBrush>(p.Pen.StrokeFill);
SolidBrush brush = Assert.IsType<SolidBrush>(p.Pen.StrokeFill);
Assert.Equal(Color.Pink, brush.Color);
Assert.Equal(10, p.Pen.StrokeWidth);
});
Assert.Collection(processors,
p => Assert.Equal(this.path1, p.Shape),
p => Assert.Equal(this.path2, p.Shape));
Assert.Collection(
processors,
p => Assert.Equal(this.path1, p.Shape),
p => Assert.Equal(this.path2, p.Shape));
}
}
}

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

@ -1,21 +1,18 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System.Linq;
using System.Numerics;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.Drawing.Processing.Processors.Drawing;
using SixLabors.ImageSharp.Drawing.Tests.Processing;
using SixLabors.ImageSharp.Drawing.Tests.TestUtilities;
using Xunit;
namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
{
public class DrawPolygon : BaseImageOperationsExtensionTest
{
IPen pen = Pens.Solid(Color.HotPink, 2);
PointF[] points = new[] {
private readonly IPen pen = Pens.Solid(Color.HotPink, 2);
private readonly PointF[] points = new[]
{
new PointF(10, 10),
new PointF(10, 20),
new PointF(20, 20),
@ -25,7 +22,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
private void VerifyPoints(PointF[] expectedPoints, IPath path)
{
var simplePath = Assert.Single(path.Flatten());
ISimplePath simplePath = Assert.Single(path.Flatten());
Assert.True(simplePath.IsClosed);
Assert.Equal(expectedPoints, simplePath.Points.ToArray());
}
@ -89,7 +86,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
Assert.NotEqual(this.shapeOptions, processor.Options.ShapeOptions);
this.VerifyPoints(this.points, processor.Shape);
var brush = Assert.IsType<SolidBrush>(processor.Pen.StrokeFill);
SolidBrush brush = Assert.IsType<SolidBrush>(processor.Pen.StrokeFill);
Assert.Equal(Color.Red, brush.Color);
Assert.Equal(10, processor.Pen.StrokeWidth);
}
@ -103,7 +100,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
Assert.Equal(this.shapeOptions, processor.Options.ShapeOptions);
this.VerifyPoints(this.points, processor.Shape);
var brush = Assert.IsType<SolidBrush>(processor.Pen.StrokeFill);
SolidBrush brush = Assert.IsType<SolidBrush>(processor.Pen.StrokeFill);
Assert.Equal(Color.Red, brush.Color);
Assert.Equal(10, processor.Pen.StrokeWidth);
}

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

@ -1,20 +1,19 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System.Numerics;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.Drawing.Processing.Processors.Drawing;
using SixLabors.ImageSharp.Drawing.Tests.Processing;
using SixLabors.ImageSharp.Drawing.Tests.TestUtilities;
using Xunit;
namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
{
public class DrawRectangle : BaseImageOperationsExtensionTest
{
IPen pen = Pens.Solid(Color.HotPink, 2);
RectangleF rectangle = new RectangleF(10, 10, 20, 20);
RectangularPolygon rectanglePolygon => new RectangularPolygon(rectangle);
private readonly IPen pen = Pens.Solid(Color.HotPink, 2);
private RectangleF rectangle = new RectangleF(10, 10, 20, 20);
private RectangularPolygon RectanglePolygon => new RectangularPolygon(this.rectangle);
[Fact]
public void CorrectlySetsPenAndPath()
@ -24,7 +23,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
DrawPathProcessor processor = this.Verify<DrawPathProcessor>();
Assert.NotEqual(this.shapeOptions, processor.Options.ShapeOptions);
Assert.Equal(this.rectanglePolygon, processor.Shape);
Assert.Equal(this.RectanglePolygon, processor.Shape);
Assert.Equal(this.pen, processor.Pen);
}
@ -36,7 +35,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
DrawPathProcessor processor = this.Verify<DrawPathProcessor>();
Assert.Equal(this.shapeOptions, processor.Options.ShapeOptions);
Assert.Equal(this.rectanglePolygon, processor.Shape);
Assert.Equal(this.RectanglePolygon, processor.Shape);
Assert.Equal(this.pen, processor.Pen);
}
@ -48,7 +47,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
DrawPathProcessor processor = this.Verify<DrawPathProcessor>();
Assert.NotEqual(this.shapeOptions, processor.Options.ShapeOptions);
Assert.Equal(this.rectanglePolygon, processor.Shape);
Assert.Equal(this.RectanglePolygon, processor.Shape);
Assert.NotEqual(this.pen, processor.Pen);
Assert.Equal(this.pen.StrokeFill, processor.Pen.StrokeFill);
Assert.Equal(10, processor.Pen.StrokeWidth);
@ -62,7 +61,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
DrawPathProcessor processor = this.Verify<DrawPathProcessor>();
Assert.Equal(this.shapeOptions, processor.Options.ShapeOptions);
Assert.Equal(this.rectanglePolygon, processor.Shape);
Assert.Equal(this.RectanglePolygon, processor.Shape);
Assert.NotEqual(this.pen, processor.Pen);
Assert.Equal(this.pen.StrokeFill, processor.Pen.StrokeFill);
Assert.Equal(10, processor.Pen.StrokeWidth);
@ -76,9 +75,9 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
DrawPathProcessor processor = this.Verify<DrawPathProcessor>();
Assert.NotEqual(this.shapeOptions, processor.Options.ShapeOptions);
Assert.Equal(this.rectanglePolygon, processor.Shape);
Assert.Equal(this.RectanglePolygon, processor.Shape);
Assert.NotEqual(this.pen, processor.Pen);
var brush = Assert.IsType<SolidBrush>(processor.Pen.StrokeFill);
SolidBrush brush = Assert.IsType<SolidBrush>(processor.Pen.StrokeFill);
Assert.Equal(Color.Red, brush.Color);
Assert.Equal(10, processor.Pen.StrokeWidth);
}
@ -91,9 +90,9 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
DrawPathProcessor processor = this.Verify<DrawPathProcessor>();
Assert.Equal(this.shapeOptions, processor.Options.ShapeOptions);
Assert.Equal(this.rectanglePolygon, processor.Shape);
Assert.Equal(this.RectanglePolygon, processor.Shape);
Assert.NotEqual(this.pen, processor.Pen);
var brush = Assert.IsType<SolidBrush>(processor.Pen.StrokeFill);
SolidBrush brush = Assert.IsType<SolidBrush>(processor.Pen.StrokeFill);
Assert.Equal(Color.Red, brush.Color);
Assert.Equal(10, processor.Pen.StrokeWidth);
}

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

@ -1,20 +1,17 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System.Numerics;
using System.Runtime.CompilerServices;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.Drawing.Processing.Processors.Drawing;
using SixLabors.ImageSharp.Drawing.Tests.Processing;
using SixLabors.ImageSharp.Drawing.Tests.TestUtilities;
using Xunit;
namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
{
public class Fill : BaseImageOperationsExtensionTest
{
GraphicsOptions nonDefaultOptions = new GraphicsOptions();
IBrush brush = new SolidBrush(Color.HotPink);
private readonly GraphicsOptions nonDefaultOptions = new GraphicsOptions();
private readonly IBrush brush = new SolidBrush(Color.HotPink);
[Fact]
public void Brush()
@ -23,7 +20,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
FillProcessor processor = this.Verify<FillProcessor>();
var expectedOptions = this.nonDefaultOptions;
GraphicsOptions expectedOptions = this.nonDefaultOptions;
Assert.Equal(expectedOptions, processor.Options);
Assert.Equal(expectedOptions.BlendPercentage, processor.Options.BlendPercentage);
Assert.Equal(expectedOptions.AlphaCompositionMode, processor.Options.AlphaCompositionMode);
@ -39,7 +36,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
FillProcessor processor = this.Verify<FillProcessor>();
var expectedOptions = this.options;
GraphicsOptions expectedOptions = this.options;
Assert.Equal(expectedOptions, processor.Options);
Assert.Equal(expectedOptions.BlendPercentage, processor.Options.BlendPercentage);
Assert.Equal(expectedOptions.AlphaCompositionMode, processor.Options.AlphaCompositionMode);
@ -55,14 +52,13 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
FillProcessor processor = this.Verify<FillProcessor>();
var expectedOptions = this.nonDefaultOptions;
GraphicsOptions expectedOptions = this.nonDefaultOptions;
Assert.Equal(expectedOptions, processor.Options);
Assert.Equal(expectedOptions.BlendPercentage, processor.Options.BlendPercentage);
Assert.Equal(expectedOptions.AlphaCompositionMode, processor.Options.AlphaCompositionMode);
Assert.Equal(expectedOptions.ColorBlendingMode, processor.Options.ColorBlendingMode);
var solidBrush = Assert.IsType<SolidBrush>(processor.Brush);
SolidBrush solidBrush = Assert.IsType<SolidBrush>(processor.Brush);
Assert.Equal(Color.Red, solidBrush.Color);
}
@ -73,13 +69,13 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
FillProcessor processor = this.Verify<FillProcessor>();
var expectedOptions = this.options;
GraphicsOptions expectedOptions = this.options;
Assert.Equal(expectedOptions, processor.Options);
Assert.Equal(expectedOptions.BlendPercentage, processor.Options.BlendPercentage);
Assert.Equal(expectedOptions.AlphaCompositionMode, processor.Options.AlphaCompositionMode);
Assert.Equal(expectedOptions.ColorBlendingMode, processor.Options.ColorBlendingMode);
var solidBrush = Assert.IsType<SolidBrush>(processor.Brush);
SolidBrush solidBrush = Assert.IsType<SolidBrush>(processor.Brush);
Assert.Equal(Color.Red, solidBrush.Color);
}
}

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

@ -1,19 +1,17 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System.Numerics;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.Drawing.Processing.Processors.Drawing;
using SixLabors.ImageSharp.Drawing.Tests.Processing;
using SixLabors.ImageSharp.Drawing.Tests.TestUtilities;
using Xunit;
namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
{
public class FillPath : BaseImageOperationsExtensionTest
{
IBrush brush = Brushes.Solid(Color.HotPink);
IPath path = new Star(1, 10, 5, 23, 56);
private readonly IBrush brush = Brushes.Solid(Color.HotPink);
private readonly IPath path = new Star(1, 10, 5, 23, 56);
[Fact]
public void Brush()
@ -49,7 +47,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
Assert.NotEqual(this.shapeOptions, processor.Options.ShapeOptions);
Assert.Equal(this.path, processor.Shape);
Assert.NotEqual(this.brush, processor.Brush);
var brush = Assert.IsType<SolidBrush>(processor.Brush);
SolidBrush brush = Assert.IsType<SolidBrush>(processor.Brush);
Assert.Equal(Color.Red, brush.Color);
}
@ -63,7 +61,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
Assert.Equal(this.shapeOptions, processor.Options.ShapeOptions);
Assert.Equal(this.path, processor.Shape);
Assert.NotEqual(this.brush, processor.Brush);
var brush = Assert.IsType<SolidBrush>(processor.Brush);
SolidBrush brush = Assert.IsType<SolidBrush>(processor.Brush);
Assert.Equal(Color.Red, brush.Color);
}
}

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

@ -2,22 +2,18 @@
// Licensed under the Apache License, Version 2.0.
using System;
using System.Linq;
using System.Numerics;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.Drawing.Processing.Processors.Drawing;
using SixLabors.ImageSharp.Drawing.Tests.Processing;
using SixLabors.ImageSharp.Drawing.Tests.TestUtilities;
using Xunit;
namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
{
public class FillPathBuilder : BaseImageOperationsExtensionTest
{
IBrush brush = Brushes.Solid(Color.HotPink);
IPath path = null;
Action<PathBuilder> builder = pb =>
private readonly IBrush brush = Brushes.Solid(Color.HotPink);
private readonly IPath path = null;
private readonly Action<PathBuilder> builder = pb =>
{
pb.StartFigure();
pb.AddLine(10, 10, 20, 20);
@ -29,16 +25,16 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
public FillPathBuilder()
{
var pb = new PathBuilder();
builder(pb);
path = pb.Build();
this.builder(pb);
this.path = pb.Build();
}
private void VerifyPoints(IPath expectedPath, IPath path)
{
var simplePathExpected = Assert.Single(expectedPath.Flatten());
var expectedPoints = simplePathExpected.Points.ToArray();
ISimplePath simplePathExpected = Assert.Single(expectedPath.Flatten());
PointF[] expectedPoints = simplePathExpected.Points.ToArray();
var simplePath = Assert.Single(path.Flatten());
ISimplePath simplePath = Assert.Single(path.Flatten());
Assert.True(simplePath.IsClosed);
Assert.Equal(expectedPoints, simplePath.Points.ToArray());
}
@ -77,7 +73,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
Assert.NotEqual(this.shapeOptions, processor.Options.ShapeOptions);
this.VerifyPoints(this.path, processor.Shape);
Assert.NotEqual(this.brush, processor.Brush);
var brush = Assert.IsType<SolidBrush>(processor.Brush);
SolidBrush brush = Assert.IsType<SolidBrush>(processor.Brush);
Assert.Equal(Color.Red, brush.Color);
}
@ -91,7 +87,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
Assert.Equal(this.shapeOptions, processor.Options.ShapeOptions);
this.VerifyPoints(this.path, processor.Shape);
Assert.NotEqual(this.brush, processor.Brush);
var brush = Assert.IsType<SolidBrush>(processor.Brush);
SolidBrush brush = Assert.IsType<SolidBrush>(processor.Brush);
Assert.Equal(Color.Red, brush.Color);
}
}

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

@ -1,45 +1,47 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System.Linq;
using System.Collections.Generic;
using System.Numerics;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.Drawing.Processing.Processors.Drawing;
using SixLabors.ImageSharp.Drawing.Tests.Processing;
using SixLabors.ImageSharp.Drawing.Tests.TestUtilities;
using Xunit;
namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
{
public class FillPathCollection : BaseImageOperationsExtensionTest
{
Color color = Color.HotPink;
SolidBrush brush = Brushes.Solid(Color.HotPink);
IPath path1 = new Path(new LinearLineSegment(new PointF[] {
new Vector2(10,10),
new Vector2(20,10),
new Vector2(20,10),
new Vector2(30,10),
}));
IPath path2 = new Path(new LinearLineSegment(new PointF[] {
new Vector2(10,10),
new Vector2(20,10),
new Vector2(20,10),
new Vector2(30,10),
}));
private readonly Color color = Color.HotPink;
private readonly SolidBrush brush = Brushes.Solid(Color.HotPink);
private readonly IPath path1 = new Path(new LinearLineSegment(
new PointF[]
{
new Vector2(10, 10),
new Vector2(20, 10),
new Vector2(20, 10),
new Vector2(30, 10),
}));
IPathCollection pathCollection;
private readonly IPath path2 = new Path(new LinearLineSegment(
new PointF[]
{
new Vector2(10, 10),
new Vector2(20, 10),
new Vector2(20, 10),
new Vector2(30, 10),
}));
private readonly IPathCollection pathCollection;
public FillPathCollection()
{
this.pathCollection = new PathCollection(this.path1, this.path2);
}
=> this.pathCollection = new PathCollection(this.path1, this.path2);
[Fact]
public void Brush()
{
this.operations.Fill(new ShapeGraphicsOptions(), this.brush, this.pathCollection);
var processors = this.VerifyAll<FillPathProcessor>();
IEnumerable<FillPathProcessor> processors = this.VerifyAll<FillPathProcessor>();
Assert.All(processors, p =>
{
@ -47,16 +49,17 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
Assert.Equal(this.brush, p.Brush);
});
Assert.Collection(processors,
p => Assert.Equal(this.path1, p.Shape),
p => Assert.Equal(this.path2, p.Shape));
Assert.Collection(
processors,
p => Assert.Equal(this.path1, p.Shape),
p => Assert.Equal(this.path2, p.Shape));
}
[Fact]
public void BrushWithDefault()
{
this.operations.Fill(this.brush, this.pathCollection);
var processors = this.VerifyAll<FillPathProcessor>();
IEnumerable<FillPathProcessor> processors = this.VerifyAll<FillPathProcessor>();
Assert.All(processors, p =>
{
@ -64,45 +67,48 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
Assert.Equal(this.brush, p.Brush);
});
Assert.Collection(processors,
p => Assert.Equal(this.path1, p.Shape),
p => Assert.Equal(this.path2, p.Shape));
Assert.Collection(
processors,
p => Assert.Equal(this.path1, p.Shape),
p => Assert.Equal(this.path2, p.Shape));
}
[Fact]
public void ColorSet()
{
this.operations.Fill(new ShapeGraphicsOptions(), Color.Pink, this.pathCollection);
var processors = this.VerifyAll<FillPathProcessor>();
IEnumerable<FillPathProcessor> processors = this.VerifyAll<FillPathProcessor>();
Assert.All(processors, p =>
{
Assert.NotEqual(this.shapeOptions, p.Options.ShapeOptions);
var brush = Assert.IsType<SolidBrush>(p.Brush);
SolidBrush brush = Assert.IsType<SolidBrush>(p.Brush);
Assert.Equal(Color.Pink, brush.Color);
});
Assert.Collection(processors,
p => Assert.Equal(this.path1, p.Shape),
p => Assert.Equal(this.path2, p.Shape));
Assert.Collection(
processors,
p => Assert.Equal(this.path1, p.Shape),
p => Assert.Equal(this.path2, p.Shape));
}
[Fact]
public void ColorWithDefault()
{
this.operations.Fill(Color.Pink, this.pathCollection);
var processors = this.VerifyAll<FillPathProcessor>();
IEnumerable<FillPathProcessor> processors = this.VerifyAll<FillPathProcessor>();
Assert.All(processors, p =>
{
Assert.Equal(this.shapeOptions, p.Options.ShapeOptions);
var brush = Assert.IsType<SolidBrush>(p.Brush);
SolidBrush brush = Assert.IsType<SolidBrush>(p.Brush);
Assert.Equal(Color.Pink, brush.Color);
});
Assert.Collection(processors,
p => Assert.Equal(this.path1, p.Shape),
p => Assert.Equal(this.path2, p.Shape));
Assert.Collection(
processors,
p => Assert.Equal(this.path1, p.Shape),
p => Assert.Equal(this.path2, p.Shape));
}
}
}

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

@ -1,20 +1,18 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System.Linq;
using System.Numerics;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.Drawing.Processing.Processors.Drawing;
using SixLabors.ImageSharp.Drawing.Tests.Processing;
using SixLabors.ImageSharp.Drawing.Tests.TestUtilities;
using Xunit;
namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
{
public class FillPolygon : BaseImageOperationsExtensionTest
{
IBrush brush = Brushes.Solid(Color.HotPink);
PointF[] path = new[] {
private readonly IBrush brush = Brushes.Solid(Color.HotPink);
private readonly PointF[] path = new[]
{
new PointF(10, 10),
new PointF(10, 20),
new PointF(20, 20),
@ -24,7 +22,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
private void VerifyPoints(PointF[] expectedPoints, IPath path)
{
var simplePath = Assert.Single(path.Flatten());
ISimplePath simplePath = Assert.Single(path.Flatten());
Assert.True(simplePath.IsClosed);
Assert.Equal(expectedPoints, simplePath.Points.ToArray());
}
@ -63,7 +61,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
Assert.NotEqual(this.shapeOptions, processor.Options.ShapeOptions);
this.VerifyPoints(this.path, processor.Shape);
Assert.NotEqual(this.brush, processor.Brush);
var brush = Assert.IsType<SolidBrush>(processor.Brush);
SolidBrush brush = Assert.IsType<SolidBrush>(processor.Brush);
Assert.Equal(Color.Red, brush.Color);
}
@ -77,7 +75,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
Assert.Equal(this.shapeOptions, processor.Options.ShapeOptions);
this.VerifyPoints(this.path, processor.Shape);
Assert.NotEqual(this.brush, processor.Brush);
var brush = Assert.IsType<SolidBrush>(processor.Brush);
SolidBrush brush = Assert.IsType<SolidBrush>(processor.Brush);
Assert.Equal(Color.Red, brush.Color);
}
}

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

@ -12,9 +12,10 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
{
public class FillRectangle : BaseImageOperationsExtensionTest
{
IBrush brush = Brushes.Solid(Color.HotPink);
RectangleF rectangle = new RectangleF(10, 10, 20, 20);
RectangularPolygon rectanglePolygon => new RectangularPolygon(rectangle);
private readonly IBrush brush = Brushes.Solid(Color.HotPink);
private RectangleF rectangle = new RectangleF(10, 10, 20, 20);
private RectangularPolygon RectanglePolygon => new RectangularPolygon(this.rectangle);
[Fact]
public void Brush()
@ -24,7 +25,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
FillPathProcessor processor = this.Verify<FillPathProcessor>();
Assert.NotEqual(this.shapeOptions, processor.Options.ShapeOptions);
Assert.Equal(this.rectanglePolygon, processor.Shape);
Assert.Equal(this.RectanglePolygon, processor.Shape);
Assert.Equal(this.brush, processor.Brush);
}
@ -36,7 +37,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
FillPathProcessor processor = this.Verify<FillPathProcessor>();
Assert.Equal(this.shapeOptions, processor.Options.ShapeOptions);
Assert.Equal(this.rectanglePolygon, processor.Shape);
Assert.Equal(this.RectanglePolygon, processor.Shape);
Assert.Equal(this.brush, processor.Brush);
}
@ -48,9 +49,9 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
FillPathProcessor processor = this.Verify<FillPathProcessor>();
Assert.NotEqual(this.shapeOptions, processor.Options.ShapeOptions);
Assert.Equal(this.rectanglePolygon, processor.Shape);
Assert.Equal(this.RectanglePolygon, processor.Shape);
Assert.NotEqual(this.brush, processor.Brush);
var brush = Assert.IsType<SolidBrush>(processor.Brush);
SolidBrush brush = Assert.IsType<SolidBrush>(processor.Brush);
Assert.Equal(Color.Red, brush.Color);
}
@ -62,9 +63,9 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
FillPathProcessor processor = this.Verify<FillPathProcessor>();
Assert.Equal(this.shapeOptions, processor.Options.ShapeOptions);
Assert.Equal(this.rectanglePolygon, processor.Shape);
Assert.Equal(this.RectanglePolygon, processor.Shape);
Assert.NotEqual(this.brush, processor.Brush);
var brush = Assert.IsType<SolidBrush>(processor.Brush);
SolidBrush brush = Assert.IsType<SolidBrush>(processor.Brush);
Assert.Equal(Color.Red, brush.Color);
}
}

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

@ -1,19 +1,17 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System.Numerics;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.Drawing.Processing.Processors.Drawing;
using SixLabors.ImageSharp.Drawing.Tests.Processing;
using SixLabors.ImageSharp.Drawing.Tests.TestUtilities;
using Xunit;
namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
{
public class FillRegion : BaseImageOperationsExtensionTest
{
IBrush brush = new SolidBrush(Color.HotPink);
Region region = new ShapeRegion(new RectangularPolygon(10, 10, 10, 10));
private readonly IBrush brush = new SolidBrush(Color.HotPink);
private readonly Region region = new ShapeRegion(new RectangularPolygon(10, 10, 10, 10));
[Fact]
public void Brush()
@ -38,6 +36,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
Assert.Equal(this.region, processor.Region);
Assert.Equal(this.brush, processor.Brush);
}
[Fact]
public void ColorSet()
{
@ -47,7 +46,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
Assert.NotEqual(this.shapeOptions, processor.Options.ShapeOptions);
Assert.Equal(this.region, processor.Region);
var solidBrush = Assert.IsType<SolidBrush>(processor.Brush);
SolidBrush solidBrush = Assert.IsType<SolidBrush>(processor.Brush);
Assert.Equal(Color.Red, solidBrush.Color);
}
@ -60,7 +59,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
Assert.Equal(this.shapeOptions, processor.Options.ShapeOptions);
Assert.Equal(this.region, processor.Region);
var solidBrush = Assert.IsType<SolidBrush>(processor.Brush);
SolidBrush solidBrush = Assert.IsType<SolidBrush>(processor.Brush);
Assert.Equal(Color.Red, solidBrush.Color);
}
}

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

@ -14,17 +14,24 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
public abstract class MockPath : IPath
{
public abstract RectangleF Bounds { get; }
public IPath AsClosedPath() => this;
public abstract SegmentInfo PointAlongPath(float distanceAlongPath);
public abstract PointInfo Distance(PointF point);
public abstract IEnumerable<ISimplePath> Flatten();
public abstract bool Contains(PointF point);
public abstract IPath Transform(Matrix3x2 matrix);
public abstract PathTypes PathType { get; }
public abstract int MaxIntersections { get; }
public abstract float Length { get; }
public abstract PointInfo Distance(PointF point);
public abstract IEnumerable<ISimplePath> Flatten();
public abstract bool Contains(PointF point);
public abstract IPath Transform(Matrix3x2 matrix);
public abstract PathTypes PathType { get; }
public abstract int MaxIntersections { get; }
public abstract float Length { get; }
public int FindIntersections(PointF start, PointF end, PointF[] buffer, int offset, IntersectionRule intersectionRule)
{
@ -44,13 +51,15 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Paths
}
public int FindIntersections(PointF start, PointF end, PointF[] buffer, int offset)
=> FindIntersections(start, end, buffer, offset, IntersectionRule.OddEven);
=> this.FindIntersections(start, end, buffer, offset, IntersectionRule.OddEven);
public int FindIntersections(PointF s, PointF e, Span<PointF> buffer)
=> FindIntersections(s, e, buffer, IntersectionRule.OddEven);
=> this.FindIntersections(s, e, buffer, IntersectionRule.OddEven);
public int TestFindIntersectionsInvocationCounter { get; private set; }
public virtual int TestYToScan => 10;
public virtual int TestFindIntersectionsResult => 3;
}

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

@ -15,8 +15,8 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
[Theory]
[WithFile(TestImages.Png.CalliphoraPartial, PixelTypes.Rgba32, "Yellow", "Pink", 0.2f)]
[WithFile(TestImages.Png.CalliphoraPartial, PixelTypes.Bgra32, "Yellow", "Pink", 0.5f)]
[WithTestPatternImages(100, 100, PixelTypes.Rgba32, "Red", "Blue", 0.2f)]
[WithTestPatternImages(100, 100, PixelTypes.Rgba32, "Red", "Blue", 0.6f)]
[WithTestPatternImage(100, 100, PixelTypes.Rgba32, "Red", "Blue", 0.2f)]
[WithTestPatternImage(100, 100, PixelTypes.Rgba32, "Red", "Blue", 0.6f)]
public void Recolor<TPixel>(TestImageProvider<TPixel> provider, string sourceColorName, string targetColorName, float threshold)
where TPixel : unmanaged, IPixel<TPixel>
{
@ -30,7 +30,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
[Theory]
[WithFile(TestImages.Png.CalliphoraPartial, PixelTypes.Bgra32, "Yellow", "Pink", 0.5f)]
[WithTestPatternImages(100, 100, PixelTypes.Rgba32, "Red", "Blue", 0.2f)]
[WithTestPatternImage(100, 100, PixelTypes.Rgba32, "Red", "Blue", 0.2f)]
public void Recolor_InBox<TPixel>(TestImageProvider<TPixel> provider, string sourceColorName, string targetColorName, float threshold)
where TPixel : unmanaged, IPixel<TPixel>
{
@ -39,10 +39,11 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
var brush = new RecolorBrush(sourceColor, targetColor, threshold);
FormattableString testInfo = $"{sourceColorName}-{targetColorName}-{threshold}";
provider.RunValidatingProcessorTest(x =>
provider.RunValidatingProcessorTest(
x =>
{
Size size = x.GetCurrentSize();
var rectangle = new Rectangle(0, size.Height / 2 - size.Height / 4, size.Width, size.Height / 2);
var rectangle = new Rectangle(0, (size.Height / 2) - (size.Height / 4), size.Width, size.Height / 2);
x.Fill(brush, rectangle);
}, testInfo);
}

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

@ -13,15 +13,16 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
public class SolidBezierTests
{
[Theory]
[WithBlankImages(500, 500, PixelTypes.Rgba32)]
[WithBlankImage(500, 500, PixelTypes.Rgba32)]
public void FilledBezier<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
PointF[] simplePath = {
new Vector2(10, 400),
new Vector2(30, 10),
new Vector2(240, 30),
new Vector2(300, 400)
PointF[] simplePath =
{
new Vector2(10, 400),
new Vector2(30, 10),
new Vector2(240, 30),
new Vector2(300, 400)
};
Color blue = Color.Blue;
@ -36,17 +37,17 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
}
}
[Theory]
[WithBlankImages(500, 500, PixelTypes.Rgba32)]
[WithBlankImage(500, 500, PixelTypes.Rgba32)]
public void OverlayByFilledPolygonOpacity<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
PointF[] simplePath = {
new Vector2(10, 400),
new Vector2(30, 10),
new Vector2(240, 30),
new Vector2(300, 400)
PointF[] simplePath =
{
new Vector2(10, 400),
new Vector2(30, 10),
new Vector2(240, 30),
new Vector2(300, 400)
};
Rgba32 color = Color.HotPink;

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

@ -1,5 +1,6 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Collections.Generic;
using SixLabors.ImageSharp.Drawing.Processing;
@ -14,7 +15,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
[GroupOutput("Drawing")]
public class SolidFillBlendedShapesTests
{
public static IEnumerable<object[]> modes = GetAllModeCombinations();
public static IEnumerable<object[]> Modes { get; } = GetAllModeCombinations();
private static IEnumerable<object[]> GetAllModeCombinations()
{
@ -28,12 +29,16 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
}
[Theory]
[WithBlankImages(nameof(modes), 250, 250, PixelTypes.Rgba32)]
[WithBlankImage(nameof(Modes), 250, 250, PixelTypes.Rgba32)]
#pragma warning disable IDE1006 // Naming Styles
#pragma warning disable SA1300 // Element should begin with upper-case letter
public void _1DarkBlueRect_2BlendHotPinkRect<TPixel>(
TestImageProvider<TPixel> provider,
PixelColorBlendingMode blending,
PixelAlphaCompositionMode composition)
where TPixel : unmanaged, IPixel<TPixel>
#pragma warning restore SA1300 // Element should begin with upper-case letter
#pragma warning restore IDE1006 // Naming Styles
{
using (Image<TPixel> img = provider.GetImage())
{
@ -42,31 +47,34 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
img.Mutate(
x => x.Fill(
Color.DarkBlue,
new Rectangle(0 * scaleX, 40 * scaleY, 100 * scaleX, 20 * scaleY)
)
new Rectangle(0 * scaleX, 40 * scaleY, 100 * scaleX, 20 * scaleY))
.Fill(
new ShapeGraphicsOptions
{
GraphicsOptions = {
GraphicsOptions =
{
Antialias = true, ColorBlendingMode = blending, AlphaCompositionMode = composition
}
},
Color.HotPink,
new Rectangle(20 * scaleX, 0 * scaleY, 30 * scaleX, 100 * scaleY))
);
new Rectangle(20 * scaleX, 0 * scaleY, 30 * scaleX, 100 * scaleY)));
VerifyImage(provider, blending, composition, img);
}
}
[Theory]
[WithBlankImages(nameof(modes), 250, 250, PixelTypes.Rgba32)]
[WithBlankImage(nameof(Modes), 250, 250, PixelTypes.Rgba32)]
#pragma warning disable IDE1006 // Naming Styles
#pragma warning disable SA1300 // Element should begin with upper-case letter
public void _1DarkBlueRect_2BlendHotPinkRect_3BlendTransparentEllipse<TPixel>(
TestImageProvider<TPixel> provider,
PixelColorBlendingMode blending,
PixelAlphaCompositionMode composition)
where TPixel : unmanaged, IPixel<TPixel>
#pragma warning restore SA1300 // Element should begin with upper-case letter
#pragma warning restore IDE1006 // Naming Styles
{
using (Image<TPixel> img = provider.GetImage())
{
@ -91,25 +99,28 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
GraphicsOptions = new GraphicsOptions { Antialias = true, ColorBlendingMode = blending, AlphaCompositionMode = composition }
},
Color.Transparent,
new EllipsePolygon(40 * scaleX, 50 * scaleY, 50 * scaleX, 50 * scaleY))
);
new EllipsePolygon(40 * scaleX, 50 * scaleY, 50 * scaleX, 50 * scaleY)));
VerifyImage(provider, blending, composition, img);
}
}
[Theory]
[WithBlankImages(nameof(modes), 250, 250, PixelTypes.Rgba32)]
[WithBlankImage(nameof(Modes), 250, 250, PixelTypes.Rgba32)]
#pragma warning disable IDE1006 // Naming Styles
#pragma warning disable SA1300 // Element should begin with upper-case letter
public void _1DarkBlueRect_2BlendHotPinkRect_3BlendSemiTransparentRedEllipse<TPixel>(
TestImageProvider<TPixel> provider,
PixelColorBlendingMode blending,
PixelAlphaCompositionMode composition)
where TPixel : unmanaged, IPixel<TPixel>
#pragma warning restore SA1300 // Element should begin with upper-case letter
#pragma warning restore IDE1006 // Naming Styles
{
using (Image<TPixel> img = provider.GetImage())
{
int scaleX = (img.Width / 100);
int scaleY = (img.Height / 100);
int scaleX = img.Width / 100;
int scaleY = img.Height / 100;
img.Mutate(
x => x.Fill(
Color.DarkBlue,
@ -132,20 +143,23 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
GraphicsOptions = new GraphicsOptions { Antialias = true, ColorBlendingMode = blending, AlphaCompositionMode = composition }
},
transparentRed,
new EllipsePolygon(40 * scaleX, 50 * scaleY, 50 * scaleX, 50 * scaleY))
);
new EllipsePolygon(40 * scaleX, 50 * scaleY, 50 * scaleX, 50 * scaleY)));
VerifyImage(provider, blending, composition, img); ;
VerifyImage(provider, blending, composition, img);
}
}
[Theory]
[WithBlankImages(nameof(modes), 250, 250, PixelTypes.Rgba32)]
[WithBlankImage(nameof(Modes), 250, 250, PixelTypes.Rgba32)]
#pragma warning disable IDE1006 // Naming Styles
#pragma warning disable SA1300 // Element should begin with upper-case letter
public void _1DarkBlueRect_2BlendBlackEllipse<TPixel>(
TestImageProvider<TPixel> provider,
PixelColorBlendingMode blending,
PixelAlphaCompositionMode composition)
where TPixel : unmanaged, IPixel<TPixel>
#pragma warning restore SA1300 // Element should begin with upper-case letter
#pragma warning restore IDE1006 // Naming Styles
{
using (Image<TPixel> dstImg = provider.GetImage(), srcImg = provider.GetImage())
{
@ -183,7 +197,8 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing
appendSourceFileOrDescription: false);
var comparer = ImageComparer.TolerantPercentage(0.01f, 3);
img.CompareFirstFrameToReferenceOutput(comparer,
img.CompareFirstFrameToReferenceOutput(
comparer,
provider,
new { composition, blending },
appendPixelTypeToFileName: false,

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

@ -12,18 +12,19 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Text
{
public class DrawText : BaseImageOperationsExtensionTest
{
private readonly FontCollection FontCollection;
private readonly FontCollection fontCollection;
private readonly TextGraphicsOptions otherTextOptions = new TextGraphicsOptions()
{
TextOptions = new TextOptions(),
GraphicsOptions = new GraphicsOptions()
};
private readonly Font Font;
private readonly Font font;
public DrawText()
{
this.FontCollection = new FontCollection();
this.Font = this.FontCollection.Install(TestFontUtilities.GetPath("SixLaborsSampleAB.woff")).CreateFont(12);
this.fontCollection = new FontCollection();
this.font = this.fontCollection.Install(TestFontUtilities.GetPath("SixLaborsSampleAB.woff")).CreateFont(12);
}
[Fact]
@ -32,12 +33,12 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Text
this.operations.DrawText(
this.otherTextOptions,
"123",
this.Font,
this.font,
Brushes.Solid(Color.Red),
null,
Vector2.Zero);
var processor = this.Verify<DrawTextProcessor>(0);
DrawTextProcessor processor = this.Verify<DrawTextProcessor>(0);
Assert.NotEqual(this.textOptions, processor.Options.TextOptions);
Assert.NotEqual(this.options, processor.Options.GraphicsOptions);
}
@ -45,9 +46,9 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Text
[Fact]
public void FillsForEachACharacterWhenBrushSetAndNotPenDefaultOptions()
{
this.operations.DrawText("123", this.Font, Brushes.Solid(Color.Red), null, Vector2.Zero);
this.operations.DrawText("123", this.font, Brushes.Solid(Color.Red), null, Vector2.Zero);
var processor = this.Verify<DrawTextProcessor>(0);
DrawTextProcessor processor = this.Verify<DrawTextProcessor>(0);
Assert.Equal(this.textOptions, processor.Options.TextOptions);
Assert.Equal(this.options, processor.Options.GraphicsOptions);
}
@ -55,9 +56,9 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Text
[Fact]
public void FillsForEachACharacterWhenBrushSet()
{
this.operations.DrawText(this.otherTextOptions, "123", this.Font, Brushes.Solid(Color.Red), Vector2.Zero);
this.operations.DrawText(this.otherTextOptions, "123", this.font, Brushes.Solid(Color.Red), Vector2.Zero);
var processor = this.Verify<DrawTextProcessor>(0);
DrawTextProcessor processor = this.Verify<DrawTextProcessor>(0);
Assert.NotEqual(this.textOptions, processor.Options.TextOptions);
Assert.NotEqual(this.options, processor.Options.GraphicsOptions);
}
@ -65,9 +66,9 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Text
[Fact]
public void FillsForEachACharacterWhenBrushSetDefaultOptions()
{
this.operations.DrawText("123", this.Font, Brushes.Solid(Color.Red), Vector2.Zero);
this.operations.DrawText("123", this.font, Brushes.Solid(Color.Red), Vector2.Zero);
var processor = this.Verify<DrawTextProcessor>(0);
DrawTextProcessor processor = this.Verify<DrawTextProcessor>(0);
Assert.Equal(this.textOptions, processor.Options.TextOptions);
Assert.Equal(this.options, processor.Options.GraphicsOptions);
}
@ -75,9 +76,9 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Text
[Fact]
public void FillsForEachACharacterWhenColorSet()
{
this.operations.DrawText(this.otherTextOptions, "123", this.Font, Color.Red, Vector2.Zero);
this.operations.DrawText(this.otherTextOptions, "123", this.font, Color.Red, Vector2.Zero);
var processor = this.Verify<DrawTextProcessor>(0);
DrawTextProcessor processor = this.Verify<DrawTextProcessor>(0);
SolidBrush brush = Assert.IsType<SolidBrush>(processor.Brush);
Assert.Equal(Color.Red, brush.Color);
@ -88,9 +89,9 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Text
[Fact]
public void FillsForEachACharacterWhenColorSetDefaultOptions()
{
this.operations.DrawText("123", this.Font, Color.Red, Vector2.Zero);
this.operations.DrawText("123", this.font, Color.Red, Vector2.Zero);
var processor = this.Verify<DrawTextProcessor>(0);
DrawTextProcessor processor = this.Verify<DrawTextProcessor>(0);
SolidBrush brush = Assert.IsType<SolidBrush>(processor.Brush);
Assert.Equal(Color.Red, brush.Color);
@ -104,12 +105,12 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Text
this.operations.DrawText(
this.otherTextOptions,
"123",
this.Font,
this.font,
null,
Pens.Dash(Color.Red, 1),
Vector2.Zero);
var processor = this.Verify<DrawTextProcessor>(0);
DrawTextProcessor processor = this.Verify<DrawTextProcessor>(0);
Assert.NotEqual(this.textOptions, processor.Options.TextOptions);
Assert.NotEqual(this.options, processor.Options.GraphicsOptions);
}
@ -117,9 +118,9 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Text
[Fact]
public void DrawForEachACharacterWhenPenSetAndNotBrushDefaultOptions()
{
this.operations.DrawText("123", this.Font, null, Pens.Dash(Color.Red, 1), Vector2.Zero);
this.operations.DrawText("123", this.font, null, Pens.Dash(Color.Red, 1), Vector2.Zero);
var processor = this.Verify<DrawTextProcessor>(0);
DrawTextProcessor processor = this.Verify<DrawTextProcessor>(0);
Assert.Equal(this.textOptions, processor.Options.TextOptions);
Assert.Equal(this.options, processor.Options.GraphicsOptions);
}
@ -127,9 +128,9 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Text
[Fact]
public void DrawForEachACharacterWhenPenSet()
{
this.operations.DrawText(this.otherTextOptions, "123", this.Font, Pens.Dash(Color.Red, 1), Vector2.Zero);
this.operations.DrawText(this.otherTextOptions, "123", this.font, Pens.Dash(Color.Red, 1), Vector2.Zero);
var processor = this.Verify<DrawTextProcessor>(0);
DrawTextProcessor processor = this.Verify<DrawTextProcessor>(0);
Assert.NotEqual(this.textOptions, processor.Options.TextOptions);
Assert.NotEqual(this.options, processor.Options.GraphicsOptions);
}
@ -137,13 +138,13 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Text
[Fact]
public void DrawForEachACharacterWhenPenSetDefaultOptions()
{
this.operations.DrawText("123", this.Font, Pens.Dash(Color.Red, 1), Vector2.Zero);
this.operations.DrawText("123", this.font, Pens.Dash(Color.Red, 1), Vector2.Zero);
var processor = this.Verify<DrawTextProcessor>(0);
DrawTextProcessor processor = this.Verify<DrawTextProcessor>(0);
Assert.Equal("123", processor.Text);
Assert.Equal(this.Font, processor.Font);
var penBrush = Assert.IsType<SolidBrush>(processor.Pen.StrokeFill);
Assert.Equal(this.font, processor.Font);
SolidBrush penBrush = Assert.IsType<SolidBrush>(processor.Pen.StrokeFill);
Assert.Equal(Color.Red, penBrush.Color);
Assert.Equal(1, processor.Pen.StrokeWidth);
Assert.Equal(PointF.Empty, processor.Location);
@ -157,19 +158,19 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Text
this.operations.DrawText(
this.otherTextOptions,
"123",
this.Font,
this.font,
Brushes.Solid(Color.Red),
Pens.Dash(Color.Red, 1),
Vector2.Zero);
var processor = this.Verify<DrawTextProcessor>(0);
DrawTextProcessor processor = this.Verify<DrawTextProcessor>(0);
Assert.Equal("123", processor.Text);
Assert.Equal(this.Font, processor.Font);
var brush = Assert.IsType<SolidBrush>(processor.Brush);
Assert.Equal(this.font, processor.Font);
SolidBrush brush = Assert.IsType<SolidBrush>(processor.Brush);
Assert.Equal(Color.Red, brush.Color);
Assert.Equal(PointF.Empty, processor.Location);
var penBrush = Assert.IsType<SolidBrush>(processor.Pen.StrokeFill);
SolidBrush penBrush = Assert.IsType<SolidBrush>(processor.Pen.StrokeFill);
Assert.Equal(Color.Red, penBrush.Color);
Assert.Equal(1, processor.Pen.StrokeWidth);
Assert.NotEqual(this.textOptions, processor.Options.TextOptions);

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

@ -6,16 +6,13 @@ using System.Linq;
using System.Text;
using SixLabors.Fonts;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.Drawing.Shapes;
using SixLabors.ImageSharp.Drawing.Tests.TestUtilities.ImageComparison;
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using Xunit;
using Xunit.Abstractions;
// ReSharper disable InconsistentNaming
namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Text
{
[GroupOutput("Drawing/Text")]
@ -25,16 +22,14 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Text
private const string TestText = "Sphinx of black quartz, judge my vow\n0123456789";
public static ImageComparer TextDrawingComparer = TestEnvironment.IsFramework
private static readonly ImageComparer TextDrawingComparer = TestEnvironment.IsFramework
? ImageComparer.TolerantPercentage(1e-3f) // Relax comparison on .NET Framework
: ImageComparer.TolerantPercentage(1e-5f);
public static ImageComparer OutlinedTextDrawingComparer = ImageComparer.TolerantPercentage(5e-4f);
private static readonly ImageComparer OutlinedTextDrawingComparer = ImageComparer.TolerantPercentage(5e-4f);
public DrawTextOnImageTests(ITestOutputHelper output)
{
this.Output = output;
}
=> this.Output = output;
private ITestOutputHelper Output { get; }
@ -47,17 +42,16 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Text
Font font = CreateFont("OpenSans-Regular.ttf", 70);
FontFamily emjoiFontFamily = CreateFont("TwemojiMozilla.ttf", 36).Family;
var color = Color.Black;
var text = "A short piece of text 😀 with an emoji";
Color color = Color.Black;
string text = "A short piece of text 😀 with an emoji";
var textGraphicOptions = new TextGraphicsOptions
{
TextOptions = {
TextOptions =
{
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
FallbackFonts = {
emjoiFontFamily
},
FallbackFonts = { emjoiFontFamily },
RenderColorFonts = enableColorFonts
}
};
@ -78,24 +72,25 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Text
where TPixel : unmanaged, IPixel<TPixel>
{
Font font = CreateFont("OpenSans-Regular.ttf", 36);
var color = Color.Black;
var text = "A short piece of text";
Color color = Color.Black;
string text = "A short piece of text";
using (var img = provider.GetImage())
using (Image<TPixel> img = provider.GetImage())
{
// measure the text size
var size = TextMeasurer.Measure(text, new RendererOptions(font));
FontRectangle size = TextMeasurer.Measure(text, new RendererOptions(font));
//find out how much we need to scale the text to fill the space (up or down)
// find out how much we need to scale the text to fill the space (up or down)
float scalingFactor = Math.Min(img.Width / size.Width, img.Height / size.Height);
//create a new font
// create a new font
var scaledFont = new Font(font, scalingFactor * font.Size);
var center = new PointF(img.Width / 2, img.Height / 2);
var textGraphicOptions = new TextGraphicsOptions
{
TextOptions = {
TextOptions =
{
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center
}
@ -113,8 +108,8 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Text
using (Image<TPixel> img = provider.GetImage())
{
Font font = CreateFont("OpenSans-Regular.ttf", 39);
string text = new string('a', 10000); // exception
// string text = "Hello"; // no exception
string text = new string('a', 10000);
Rgba32 color = Color.Black;
var point = new PointF(100, 100);
@ -122,7 +117,6 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Text
}
}
[Theory]
[WithSolidFilledImages(200, 200, "White", PixelTypes.Rgba32)]
public void OpenSansJWithNoneZeroShouldntExtendPastGlyphe<TPixel>(TestImageProvider<TPixel> provider)
@ -190,24 +184,22 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Text
var textOptions = new TextGraphicsOptions
{
TextOptions = {
TextOptions =
{
ApplyKerning = true,
VerticalAlignment = VerticalAlignment.Top,
HorizontalAlignment = HorizontalAlignment.Left,
}
};
var color = Color.Black;
Color color = Color.Black;
// Strict comparer, because the image is sparse:
var comparer = ImageComparer.TolerantPercentage(1e-6f);
provider.VerifyOperation(
comparer,
img =>
{
img.Mutate(c => c.DrawText(textOptions, sb.ToString(), font, color, new PointF(10, 1)));
},
img => img.Mutate(c => c.DrawText(textOptions, sb.ToString(), font, color, new PointF(10, 1))),
false,
false);
}
@ -226,14 +218,11 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Text
where TPixel : unmanaged, IPixel<TPixel>
{
Font font = CreateFont(fontName, fontSize);
var color = Color.Black;
Color color = Color.Black;
provider.VerifyOperation(
OutlinedTextDrawingComparer,
img =>
{
img.Mutate(c => c.DrawText(text, new Font(font, fontSize), null, Pens.Solid(color, 1), new PointF(x, y)));
},
img => img.Mutate(c => c.DrawText(text, new Font(font, fontSize), null, Pens.Solid(color, 1), new PointF(x, y))),
$"pen_{fontName}-{fontSize}-{ToTestOutputDisplayText(text)}-({x},{y})",
appendPixelTypeToFileName: false,
appendSourceFileOrDescription: true);
@ -253,14 +242,11 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Text
where TPixel : unmanaged, IPixel<TPixel>
{
Font font = CreateFont(fontName, fontSize);
var color = Color.Black;
Color color = Color.Black;
provider.VerifyOperation(
OutlinedTextDrawingComparer,
img =>
{
img.Mutate(c => c.DrawText(text, new Font(font, fontSize), null, Pens.DashDot(color, 3), new PointF(x, y)));
},
img => img.Mutate(c => c.DrawText(text, new Font(font, fontSize), null, Pens.DashDot(color, 3), new PointF(x, y))),
$"pen_{fontName}-{fontSize}-{ToTestOutputDisplayText(text)}-({x},{y})",
appendPixelTypeToFileName: false,
appendSourceFileOrDescription: true);
@ -273,16 +259,18 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Text
{
Font font = CreateFont(fontName, 30);
string text = Repeat("Beware the Jabberwock, my son! The jaws that bite, the claws that catch! Beware the Jubjub bird, and shun The frumious Bandersnatch!\n",
string text = Repeat(
"Beware the Jabberwock, my son! The jaws that bite, the claws that catch! Beware the Jubjub bird, and shun The frumious Bandersnatch!\n",
20);
var textOptions = new TextGraphicsOptions
{
TextOptions = {
TextOptions =
{
WrapTextWidth = 1000
}
};
string details = fontName.Replace(" ", "");
string details = fontName.Replace(" ", string.Empty);
// Based on the reported 0.1755% difference with AccuracyMultiple = 8
// We should avoid quality regressions leading to higher difference!
@ -300,7 +288,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Text
private static string ToTestOutputDisplayText(string text)
{
string fnDisplayText = text.Replace("\n", "");
string fnDisplayText = text.Replace("\n", string.Empty);
fnDisplayText = fnDisplayText.Substring(0, Math.Min(fnDisplayText.Length, 4));
return fnDisplayText;
}

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

@ -8,7 +8,7 @@ using Xunit;
namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Text
{
public class TextGraphicOptionsDefaultsExtensionsTests
public class TextOptionsDefaultsExtensionsTests
{
[Fact]
public void SetDefaultOptionsOnProcessingContext()
@ -41,7 +41,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Text
o.TabWidth = 9;
});
var returnedOption = context.GetTextOptions();
TextOptions returnedOption = context.GetTextOptions();
Assert.Equal(9, returnedOption.TabWidth);
Assert.Equal(99, option.TabWidth); // hasn't been mutated
}
@ -73,7 +73,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Text
o.TabWidth = 9;
});
var returnedOption = config.GetTextOptions();
TextOptions returnedOption = config.GetTextOptions();
Assert.Equal(9, returnedOption.TabWidth);
Assert.Equal(99, option.TabWidth); // hasn't been mutated
}
@ -83,11 +83,11 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Text
{
var config = new Configuration();
var options = config.GetTextOptions();
TextOptions options = config.GetTextOptions();
Assert.NotNull(options);
config.SetTextOptions((TextOptions)null);
var options2 = config.GetTextOptions();
TextOptions options2 = config.GetTextOptions();
Assert.NotNull(options2);
// we set it to null should now be a new instance
@ -100,7 +100,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Text
var config = new Configuration();
config.Properties[typeof(TextOptions)] = "wronge type";
var options = config.GetTextOptions();
TextOptions options = config.GetTextOptions();
Assert.NotNull(options);
Assert.IsType<TextOptions>(options);
}
@ -111,7 +111,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Text
var config = new Configuration();
Assert.DoesNotContain(typeof(TextOptions), config.Properties.Keys);
var options = config.GetTextOptions();
TextOptions options = config.GetTextOptions();
Assert.NotNull(options);
}
@ -120,8 +120,8 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Text
{
var config = new Configuration();
var options = config.GetTextOptions();
var options2 = config.GetTextOptions();
TextOptions options = config.GetTextOptions();
TextOptions options2 = config.GetTextOptions();
Assert.Equal(options, options2);
}
@ -131,7 +131,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Text
var config = new Configuration();
var context = new FakeImageOperationsProvider.FakeImageOperations<Rgba32>(config, null, true);
var ctxOptions = context.GetTextOptions();
TextOptions ctxOptions = context.GetTextOptions();
Assert.NotNull(ctxOptions);
}
@ -142,7 +142,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Text
var context = new FakeImageOperationsProvider.FakeImageOperations<Rgba32>(config, null, true);
context.SetTextOptions((TextOptions)null);
var ctxOptions = context.GetTextOptions();
TextOptions ctxOptions = context.GetTextOptions();
Assert.NotNull(ctxOptions);
}
@ -154,7 +154,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Text
config.SetTextOptions(option);
var context = new FakeImageOperationsProvider.FakeImageOperations<Rgba32>(config, null, true);
var ctxOptions = context.GetTextOptions();
TextOptions ctxOptions = context.GetTextOptions();
Assert.Equal(option, ctxOptions);
}
@ -164,7 +164,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Text
var config = new Configuration();
var context = new FakeImageOperationsProvider.FakeImageOperations<Rgba32>(config, null, true);
context.Properties[typeof(TextOptions)] = "wronge type";
var options = context.GetTextOptions();
TextOptions options = context.GetTextOptions();
Assert.NotNull(options);
Assert.IsType<TextOptions>(options);
}

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

@ -3,8 +3,6 @@
using SixLabors.Fonts;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.PixelFormats;
using Xunit;
namespace SixLabors.ImageSharp.Drawing.Tests.Drawing.Text

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

@ -1,113 +0,0 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Collections.Generic;
namespace SixLabors.ImageSharp.Drawing.Tests
{
/// <summary>
/// The test base class for reading and writing to files.
/// </summary>
[Obsolete("See: https://github.com/SixLabors/ImageSharp/issues/868")]
public abstract class FileTestBase
{
/// <summary>
/// TODO: We really should not depend on this! Let's use well defined, test-case specific inputs everywhere!
/// A collection made up of one file for each image format
/// </summary>
public static IEnumerable<string> DefaultFiles =
new[]
{
TestImages.Bmp.Car,
TestImages.Jpeg.Baseline.Calliphora,
TestImages.Png.Splash,
TestImages.Gif.Trans
};
/// <summary>
/// A collection of all the bmp test images
/// </summary>
public static IEnumerable<string> AllBmpFiles = TestImages.Bmp.Benchmark;
/// <summary>
/// A collection of all the jpeg test images
/// </summary>
public static IEnumerable<string> AllJpegFiles = TestImages.Jpeg.All;
/// <summary>
/// A collection of all the png test images
/// </summary>
public static IEnumerable<string> AllPngFiles = TestImages.Png.All;
/// <summary>
/// A collection of all the gif test images
/// </summary>
public static IEnumerable<string> AllGifFiles = TestImages.Gif.All;
/// <summary>
/// The standard pixel format enumeration
/// </summary>
public const PixelTypes DefaultPixelType = PixelTypes.Rgba32;
/// <summary>
/// A few other pixel types to prove that a processor is not bound to a single one.
/// </summary>
public const PixelTypes CommonNonDefaultPixelTypes = PixelTypes.Rgba32 | PixelTypes.Bgra32 | PixelTypes.RgbaVector;
public static class Extensions
{
public const string Bmp = "bmp";
public const string Jpeg = "jpg";
public const string Png = "png";
public const string Gif = "gif";
}
/// <summary>
/// The collection of image files to test against.
/// </summary>
protected static readonly List<TestFile> Files = new List<TestFile>
{
TestFile.Create(TestImages.Jpeg.Baseline.Calliphora),
//TestFile.Create(TestImages.Jpeg.Baseline.Turtle), // Perf: Enable for local testing only
//TestFile.Create(TestImages.Jpeg.Baseline.Ycck), // Perf: Enable for local testing only
//TestFile.Create(TestImages.Jpeg.Baseline.Cmyk), // Perf: Enable for local testing only
//TestFile.Create(TestImages.Jpeg.Baseline.Floorplan), // Perf: Enable for local testing only
//TestFile.Create(TestImages.Jpeg.Progressive.Festzug), // Perf: Enable for local testing only
//TestFile.Create(TestImages.Jpeg.Baseline.Bad.BadEOF), // Perf: Enable for local testing only
//TestFile.Create(TestImages.Jpeg.Baseline.Bad.ExifUndefType), // Perf: Enable for local testing only
//TestFile.Create(TestImages.Jpeg.Progressive.Fb), // Perf: Enable for local testing only
//TestFile.Create(TestImages.Jpeg.Progressive.Progress), // Perf: Enable for local testing only
//TestFile.Create(TestImages.Jpeg.Baseline.GammaDalaiLamaGray), // Perf: Enable for local testing only
//TestFile.Create(TestImages.Jpeg.Progressive.Bad.BadEOF), // Perf: Enable for local testing only
TestFile.Create(TestImages.Bmp.Car),
// TestFile.Create(TestImages.Bmp.NegHeight), // Perf: Enable for local testing only
// TestFile.Create(TestImages.Bmp.CoreHeader), // Perf: Enable for local testing only
TestFile.Create(TestImages.Png.Splash),
// TestFile.Create(TestImages.Png.SnakeGame),
// TestFile.Create(TestImages.Png.Cross), // Perf: Enable for local testing only
// TestFile.Create(TestImages.Png.Bad.ChunkLength1), // Perf: Enable for local testing only
// TestFile.Create(TestImages.Png.Bad.ChunkLength2), // Perf: Enable for local testing only
// TestFile.Create(TestImages.Png.Powerpoint), // Perf: Enable for local testing only
// TestFile.Create(TestImages.Png.Blur), // Perf: Enable for local testing only
// TestFile.Create(TestImages.Png.Indexed), // Perf: Enable for local testing only
// TestFile.Create(TestImages.Png.SplashInterlaced), // Perf: Enable for local testing only
// TestFile.Create(TestImages.Png.Interlaced), // Perf: Enable for local testing only
// TestFile.Create(TestImages.Png.Filter0), // Perf: Enable for local testing only
// TestFile.Create(TestImages.Png.Filter1), // Perf: Enable for local testing only
// TestFile.Create(TestImages.Png.Filter2), // Perf: Enable for local testing only
// TestFile.Create(TestImages.Png.Filter3), // Perf: Enable for local testing only
// TestFile.Create(TestImages.Png.Filter4), // Perf: Enable for local testing only
// TestFile.Create(TestImages.Png.FilterVar), // Perf: Enable for local testing only
// TestFile.Create(TestImages.Png.P1), // Perf: Enable for local testing only
// TestFile.Create(TestImages.Png.Pd), // Perf: Enable for local testing only
TestFile.Create(TestImages.Gif.Rings),
// TestFile.Create(TestImages.Gif.Trans), // Perf: Enable for local testing only
// TestFile.Create(TestImages.Gif.Cheers), // Perf: Enable for local testing only
// TestFile.Create(TestImages.Gif.Giphy) // Perf: Enable for local testing only
};
}
}

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

@ -1,10 +0,0 @@
// This file is used by Code Analysis to maintain SuppressMessage
// attributes that are applied to this project.
// Project-level suppressions either have no target or are given
// a specific target and scoped to a namespace, type, member, etc.
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "xUnit1026:Theory methods should use all of their parameters")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "xUnit1013:Public method should be marked as test")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Assertions", "xUnit2013:Do not use equality check to check for collection size.")]

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

@ -1,15 +1,15 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Drawing.Tests.TestUtilities;
using SixLabors.ImageSharp.PixelFormats;
using Xunit;
namespace SixLabors.ImageSharp.Drawing.Tests
{
public class GraphicsOptionsTests
{
private static readonly GraphicsOptionsComparer graphicsOptionsComparer = new GraphicsOptionsComparer();
private static readonly GraphicsOptionsComparer GraphicsOptionsComparer = new GraphicsOptionsComparer();
private readonly GraphicsOptions newGraphicsOptions = new GraphicsOptions();
private readonly GraphicsOptions cloneGraphicsOptions = new GraphicsOptions().DeepClone();
@ -69,7 +69,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests
GraphicsOptions actual = expected.DeepClone();
Assert.Equal(expected, actual, graphicsOptionsComparer);
Assert.Equal(expected, actual, GraphicsOptionsComparer);
}
[Fact]
@ -84,7 +84,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests
actual.BlendPercentage = .25F;
actual.ColorBlendingMode = PixelColorBlendingMode.HardLight;
Assert.NotEqual(expected, actual, graphicsOptionsComparer);
Assert.NotEqual(expected, actual, GraphicsOptionsComparer);
}
[Fact]

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

@ -9,14 +9,8 @@
<AssemblyName>SixLabors.ImageSharp.Tests</AssemblyName>
<Platforms>AnyCPU;x64;x86</Platforms>
<RootNamespace>SixLabors.ImageSharp.Drawing.Tests</RootNamespace>
<!--Used to show test project to dotnet test-->
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<ItemGroup>
<DotNetCliToolReference Include="dotnet-xunit" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Magick.NET-Q16-AnyCPU" />
<PackageReference Include="Moq" />

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

@ -1,8 +1,8 @@
using System;
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SixLabors.ImageSharp.ColorSpaces;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
@ -24,14 +24,10 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Issues
this.red,
1f,
new PointF(0, 0),
new PointF(100, 0)
));
new PointF(100, 0)));
var locations = Enumerable.Range(0, 100).Select(i => (x: i, y: 0));
Assert.All(locations, l =>
{
Assert.Equal(this.red, image[l.x, l.y]);
});
IEnumerable<(int x, int y)> locations = Enumerable.Range(0, 100).Select(i => (x: i, y: 0));
Assert.All(locations, l => Assert.Equal(this.red, image[l.x, l.y]));
}
[Fact]
@ -44,14 +40,10 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Issues
this.red,
1f,
new PointF(0, 99),
new PointF(100, 99)
));
new PointF(100, 99)));
var locations = Enumerable.Range(0, 100).Select(i => (x: i, y: 99));
Assert.All(locations, l =>
{
Assert.Equal(this.red, image[l.x, l.y]);
});
IEnumerable<(int x, int y)> locations = Enumerable.Range(0, 100).Select(i => (x: i, y: 99));
Assert.All(locations, l => Assert.Equal(this.red, image[l.x, l.y]));
}
[Fact]
@ -64,14 +56,10 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Issues
this.red,
1f,
new PointF(0, 0),
new PointF(0, 99)
));
new PointF(0, 99)));
var locations = Enumerable.Range(0, 100).Select(i => (x: 0, y: i));
Assert.All(locations, l =>
{
Assert.Equal(this.red, image[l.x, l.y]);
});
IEnumerable<(int x, int y)> locations = Enumerable.Range(0, 100).Select(i => (x: 0, y: i));
Assert.All(locations, l => Assert.Equal(this.red, image[l.x, l.y]));
}
[Fact]
@ -84,14 +72,11 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Issues
this.red,
1f,
new PointF(99, 0),
new PointF(99, 99)
));
new PointF(99, 99)));
var locations = Enumerable.Range(0, 100).Select(i => (x: 99, y: i));
Assert.All(locations, l =>
{
Assert.Equal(this.red, image[l.x, l.y]);
});
IEnumerable<(int x, int y)> locations = Enumerable.Range(0, 100).Select(i => (x: 99, y: i));
Assert.All(locations, l => Assert.Equal(this.red, image[l.x, l.y]));
}
}
}

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

@ -24,9 +24,8 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Issues
Fonts.Font font = Fonts.SystemFonts.CreateFont("Arial", 40, Fonts.FontStyle.Regular);
var graphicsOptions = new GraphicsOptions { Antialias = false };
image.Mutate(x =>
{
x.BackgroundColor(Color.White)
image.Mutate(
x => x.BackgroundColor(Color.White)
.DrawLines(
new ShapeGraphicsOptions { GraphicsOptions = graphicsOptions },
Color.Black,
@ -38,8 +37,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Issues
text,
font,
Color.Black,
new PointF(50, 50));
});
new PointF(50, 50)));
}
}
}

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

@ -1,3 +1,6 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Runtime.InteropServices;
using SixLabors.Fonts;
@ -17,14 +20,14 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Issues
int width = 768;
int height = 438;
// Creates a new image with empty pixel data.
// Creates a new image with empty pixel data.
using (var image = new Image<Rgba32>(width, height))
{
FontFamily family = SystemFonts.Find("verdana");
Font font = family.CreateFont(48, FontStyle.Bold);
// The options are optional
TextGraphicsOptions options = new TextGraphicsOptions()
var options = new TextGraphicsOptions()
{
TextOptions = new TextOptions()
{
@ -55,7 +58,6 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Issues
Assert.StartsWith("Parameter \"width\" (System.Single) must be greater than 0, was 0", ex.Message);
}
[Fact]
public void ComplexPolygoWithZeroPathsCausesBoundsToBeNonSensicalValue()
{

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

@ -1,3 +1,6 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Collections.Generic;
using System.Drawing;

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

@ -35,8 +35,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Issues
new LinearLineSegment(new PointF(592.0153f, 1156.238f), new PointF(592.4992f, 1157.138f)),
new LinearLineSegment(new PointF(592.4992f, 1157.138f), new PointF(593.3998f, 1156.654f)),
new LinearLineSegment(new PointF(593.3998f, 1156.654f), new PointF(592.916f, 1155.754f)),
new LinearLineSegment(new PointF(592.916f, 1155.754f), new PointF(592.0153f, 1156.238f))
);
new LinearLineSegment(new PointF(592.916f, 1155.754f), new PointF(592.0153f, 1156.238f)));
using var image = new Image<Rgba32>(2000, 2000);
image.Mutate(imageContext => imageContext.Draw(new Rgba32(255, 0, 0), 1, path));

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

@ -11,31 +11,26 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Processing
{
internal class FakeImageOperationsProvider : IImageProcessingContextFactory
{
private List<object> ImageOperators = new List<object>();
private readonly List<object> imageOperators = new List<object>();
public bool HasCreated<TPixel>(Image<TPixel> source)
where TPixel : unmanaged, IPixel<TPixel>
{
return this.Created(source).Any();
}
public IEnumerable<FakeImageOperations<TPixel>> Created<TPixel>(Image<TPixel> source) where TPixel : unmanaged, IPixel<TPixel>
{
return this.ImageOperators.OfType<FakeImageOperations<TPixel>>()
.Where(x => x.Source == source);
}
=> this.Created(source).Any();
public IEnumerable<FakeImageOperations<TPixel>> Created<TPixel>(Image<TPixel> source)
where TPixel : unmanaged, IPixel<TPixel>
=> this.imageOperators.OfType<FakeImageOperations<TPixel>>()
.Where(x => x.Source == source);
public IEnumerable<FakeImageOperations<TPixel>.AppliedOperation> AppliedOperations<TPixel>(Image<TPixel> source)
where TPixel : unmanaged, IPixel<TPixel>
{
return this.Created(source)
.SelectMany(x => x.Applied);
}
=> this.Created(source).SelectMany(x => x.Applied);
public IInternalImageProcessingContext<TPixel> CreateImageProcessingContext<TPixel>(Configuration configuration, Image<TPixel> source, bool mutate)
where TPixel : unmanaged, IPixel<TPixel>
{
var op = new FakeImageOperations<TPixel>(configuration, source, mutate);
this.ImageOperators.Add(op);
this.imageOperators.Add(op);
return op;
}
@ -56,15 +51,9 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Processing
public IDictionary<object, object> Properties { get; } = new Dictionary<object, object>();
public Image<TPixel> GetResultImage()
{
return this.Source;
}
public Image<TPixel> GetResultImage() => this.Source;
public Size GetCurrentSize()
{
return this.Source.Size();
}
public Size GetCurrentSize() => this.Source.Size();
public IImageProcessingContext ApplyProcessor(IImageProcessor processor, Rectangle rectangle)
{
@ -88,6 +77,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Processing
public struct AppliedOperation
{
public Rectangle? Rectangle { get; set; }
public IImageProcessor<TPixel> GenericProcessor { get; set; }
public IImageProcessor NonGenericProcessor { get; set; }

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

@ -1,10 +1,15 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.Drawing.Processing.Processors.Drawing;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing.Processors;
using Xunit;
namespace SixLabors.ImageSharp.Drawing.Tests.Processing
@ -16,13 +21,15 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Processing
{
var imageSize = new Rectangle(0, 0, 500, 500);
var path = new EllipsePolygon(1, 1, 23);
var processor = new FillPathProcessor(new ImageSharp.Drawing.Processing.ShapeGraphicsOptions()
{
GraphicsOptions = {
Antialias = true
}
}, Brushes.Solid(Color.Red), path);
var pixelProcessor = processor.CreatePixelSpecificProcessor<Rgba32>(null, null, imageSize);
var processor = new FillPathProcessor(
new ShapeGraphicsOptions()
{
GraphicsOptions = { Antialias = true }
},
Brushes.Solid(Color.Red),
path);
IImageProcessor<Rgba32> pixelProcessor = processor.CreatePixelSpecificProcessor<Rgba32>(null, null, imageSize);
Assert.IsType<FillRegionProcessor<Rgba32>>(pixelProcessor);
}
@ -34,13 +41,15 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Processing
var floatRect = new RectangleF(10.5f, 10.5f, 400.6f, 400.9f);
var expectedRect = new Rectangle(10, 10, 400, 400);
var path = new RectangularPolygon(floatRect);
var processor = new FillPathProcessor(new ImageSharp.Drawing.Processing.ShapeGraphicsOptions()
{
GraphicsOptions = {
Antialias = true
}
}, Brushes.Solid(Color.Red), path);
var pixelProcessor = processor.CreatePixelSpecificProcessor<Rgba32>(null, null, imageSize);
var processor = new FillPathProcessor(
new ShapeGraphicsOptions()
{
GraphicsOptions = { Antialias = true }
},
Brushes.Solid(Color.Red),
path);
IImageProcessor<Rgba32> pixelProcessor = processor.CreatePixelSpecificProcessor<Rgba32>(null, null, imageSize);
Assert.IsType<FillRegionProcessor<Rgba32>>(pixelProcessor);
}
@ -51,15 +60,17 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Processing
var imageSize = new Rectangle(0, 0, 500, 500);
var expectedRect = new Rectangle(10, 10, 400, 400);
var path = new RectangularPolygon(expectedRect);
var processor = new FillPathProcessor(new ImageSharp.Drawing.Processing.ShapeGraphicsOptions()
{
GraphicsOptions = {
Antialias = true
}
}, Brushes.Solid(Color.Red), path);
var pixelProcessor = processor.CreatePixelSpecificProcessor<Rgba32>(null, null, imageSize);
var processor = new FillPathProcessor(
new ShapeGraphicsOptions()
{
GraphicsOptions = { Antialias = true }
},
Brushes.Solid(Color.Red),
path);
var fill = Assert.IsType<FillProcessor<Rgba32>>(pixelProcessor);
IImageProcessor<Rgba32> pixelProcessor = processor.CreatePixelSpecificProcessor<Rgba32>(null, null, imageSize);
FillProcessor<Rgba32> fill = Assert.IsType<FillProcessor<Rgba32>>(pixelProcessor);
Assert.Equal(expectedRect, fill.GetProtectedValue<Rectangle>("SourceRectangle"));
}
@ -70,15 +81,17 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Processing
var floatRect = new RectangleF(10.5f, 10.5f, 400.6f, 400.9f);
var expectedRect = new Rectangle(10, 10, 400, 400);
var path = new RectangularPolygon(floatRect);
var processor = new FillPathProcessor(new ImageSharp.Drawing.Processing.ShapeGraphicsOptions()
{
GraphicsOptions = {
Antialias = false
}
}, Brushes.Solid(Color.Red), path);
var pixelProcessor = processor.CreatePixelSpecificProcessor<Rgba32>(null, null, imageSize);
var processor = new FillPathProcessor(
new ShapeGraphicsOptions()
{
GraphicsOptions = { Antialias = false }
},
Brushes.Solid(Color.Red),
path);
IImageProcessor<Rgba32> pixelProcessor = processor.CreatePixelSpecificProcessor<Rgba32>(null, null, imageSize);
FillProcessor<Rgba32> fill = Assert.IsType<FillProcessor<Rgba32>>(pixelProcessor);
var fill = Assert.IsType<FillProcessor<Rgba32>>(pixelProcessor);
Assert.Equal(expectedRect, fill.GetProtectedValue<Rectangle>("SourceRectangle"));
}
}
@ -86,11 +99,9 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Processing
internal static class ReflectionHelpers
{
internal static T GetProtectedValue<T>(this object obj, string name)
{
return (T)obj.GetType()
.GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.FlattenHierarchy)
.Single(x => x.Name == name)
.GetValue(obj);
}
=> (T)obj.GetType()
.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy)
.Single(x => x.Name == name)
.GetValue(obj);
}
}

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

@ -32,13 +32,15 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Processing
var processorMock = new Mock<IImageProcessor>();
this.processorDefinition = processorMock.Object;
this.image = new Image<Rgba32>(new Configuration
{
ImageOperationsProvider = this.provider
}, 1, 1);
this.image = new Image<Rgba32>(
new Configuration
{
ImageOperationsProvider = this.provider
},
1,
1);
}
[Fact]
public void MutateCallsImageOperationsProvider_Func_OriginalImage()
{
@ -169,7 +171,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Processing
private static void CheckThrowsCorrectObjectDisposedException(Action action)
{
var ex = Assert.Throws<ObjectDisposedException>(action);
ObjectDisposedException ex = Assert.Throws<ObjectDisposedException>(action);
Assert.Equal(ExpectedExceptionMessage, ex.Message);
}
}

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

@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0.
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.Drawing.Tests.Processing;
using SixLabors.ImageSharp.PixelFormats;
using Xunit;
@ -41,7 +40,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Processing
o.IntersectionRule = IntersectionRule.OddEven;
});
var returnedOption = context.GetShapeOptions();
ShapeOptions returnedOption = context.GetShapeOptions();
Assert.Equal(IntersectionRule.OddEven, returnedOption.IntersectionRule);
Assert.Equal(IntersectionRule.Nonzero, option.IntersectionRule); // hasn't been mutated
}
@ -73,7 +72,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Processing
o.IntersectionRule = IntersectionRule.OddEven;
});
var returnedOption = config.GetShapeOptions();
ShapeOptions returnedOption = config.GetShapeOptions();
Assert.Equal(IntersectionRule.OddEven, returnedOption.IntersectionRule);
Assert.Equal(IntersectionRule.Nonzero, option.IntersectionRule); // hasn't been mutated
}
@ -83,11 +82,11 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Processing
{
var config = new Configuration();
var options = config.GetShapeOptions();
ShapeOptions options = config.GetShapeOptions();
Assert.NotNull(options);
config.SetShapeOptions((ShapeOptions)null);
var options2 = config.GetShapeOptions();
ShapeOptions options2 = config.GetShapeOptions();
Assert.NotNull(options2);
// we set it to null should now be a new instance
@ -100,7 +99,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Processing
var config = new Configuration();
config.Properties[typeof(ShapeOptions)] = "wronge type";
var options = config.GetShapeOptions();
ShapeOptions options = config.GetShapeOptions();
Assert.NotNull(options);
Assert.IsType<ShapeOptions>(options);
}
@ -111,7 +110,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Processing
var config = new Configuration();
Assert.DoesNotContain(typeof(ShapeOptions), config.Properties.Keys);
var options = config.GetShapeOptions();
ShapeOptions options = config.GetShapeOptions();
Assert.NotNull(options);
}
@ -120,8 +119,8 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Processing
{
var config = new Configuration();
var options = config.GetShapeOptions();
var options2 = config.GetShapeOptions();
ShapeOptions options = config.GetShapeOptions();
ShapeOptions options2 = config.GetShapeOptions();
Assert.Equal(options, options2);
}
@ -131,7 +130,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Processing
var config = new Configuration();
var context = new FakeImageOperationsProvider.FakeImageOperations<Rgba32>(config, null, true);
var ctxOptions = context.GetShapeOptions();
ShapeOptions ctxOptions = context.GetShapeOptions();
Assert.NotNull(ctxOptions);
}
@ -142,7 +141,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Processing
var context = new FakeImageOperationsProvider.FakeImageOperations<Rgba32>(config, null, true);
context.SetShapeOptions((ShapeOptions)null);
var ctxOptions = context.GetShapeOptions();
ShapeOptions ctxOptions = context.GetShapeOptions();
Assert.NotNull(ctxOptions);
}
@ -154,7 +153,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Processing
config.SetShapeOptions(option);
var context = new FakeImageOperationsProvider.FakeImageOperations<Rgba32>(config, null, true);
var ctxOptions = context.GetShapeOptions();
ShapeOptions ctxOptions = context.GetShapeOptions();
Assert.Equal(option, ctxOptions);
}
@ -164,7 +163,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Processing
var config = new Configuration();
var context = new FakeImageOperationsProvider.FakeImageOperations<Rgba32>(config, null, true);
context.Properties[typeof(ShapeOptions)] = "wronge type";
var options = context.GetShapeOptions();
ShapeOptions options = context.GetShapeOptions();
Assert.NotNull(options);
Assert.IsType<ShapeOptions>(options);
}

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

@ -60,7 +60,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests
var complex = new ComplexPolygon(simplePath1, simplePath2);
var buffer = new PointF[10];
var points = complex.FindIntersections(new PointF(0, 2.5f), new PointF(6, 2.5f), buffer, 0, IntersectionRule.Nonzero);
int points = complex.FindIntersections(new PointF(0, 2.5f), new PointF(6, 2.5f), buffer, 0, IntersectionRule.Nonzero);
Assert.Equal(2, points);
Assert.Equal(1, buffer[0].X);
@ -85,7 +85,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests
var complex = new ComplexPolygon(simplePath1, simplePath2);
var buffer = new PointF[10];
var points = complex.FindIntersections(new PointF(0, 2.5f), new PointF(6, 2.5f), buffer, 0, IntersectionRule.OddEven);
int points = complex.FindIntersections(new PointF(0, 2.5f), new PointF(6, 2.5f), buffer, 0, IntersectionRule.OddEven);
Assert.Equal(4, points);
Assert.Equal(1, buffer[0].X);

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

@ -68,53 +68,53 @@ namespace SixLabors.ImageSharp.Drawing.Tests
return new InternalPath(new ILineSegment[] { seg1, seg2 }, closed);
}
public static TheoryData<TestPoint, TestSize, TestPoint, bool> PointInPolygonTheoryData =
new TheoryData<TestPoint, TestSize, TestPoint, bool>
{
{
public static TheoryData<TestPoint, TestSize, TestPoint, bool> PointInPolygonTheoryData { get; }
= new TheoryData<TestPoint, TestSize, TestPoint, bool>
{
{
new PointF(10, 10), // loc
new SizeF(100, 100), // size
new PointF(10, 10), // test
true
}, // corner is inside
{
}, // 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 =
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(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(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(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 },
};
public static TheoryData<TestPoint, float, float> PathDistanceTheoryData { get; }
= 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(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(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(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 },
};
[Theory]
[MemberData(nameof(PointInPolygonTheoryData))]
@ -229,7 +229,6 @@ namespace SixLabors.ImageSharp.Drawing.Tests
Assert.Empty(buffer);
}
[Fact]
public void Intersections_Diagonal_and_straight_NoHit()
{
@ -240,21 +239,21 @@ namespace SixLabors.ImageSharp.Drawing.Tests
Assert.Empty(buffer);
}
[Fact]
public void Intersections_IntersectionRule_OddEven()
{
var shape = new InternalPath(new LinearLineSegment(
new PointF(1, 3),
new PointF(1, 2),
new PointF(5, 2),
new PointF(5, 5),
new PointF(2, 5),
new PointF(2, 1),
new PointF(3, 1),
new PointF(3, 4),
new PointF(4, 4),
new PointF(3, 4)), true);
var shape = new InternalPath(
new LinearLineSegment(
new PointF(1, 3),
new PointF(1, 2),
new PointF(5, 2),
new PointF(5, 5),
new PointF(2, 5),
new PointF(2, 1),
new PointF(3, 1),
new PointF(3, 4),
new PointF(4, 4),
new PointF(3, 4)), true);
PointF[] buffer = shape.FindIntersections(new PointF(0, 2.5f), new PointF(6, 2.5f), IntersectionRule.OddEven).ToArray();
@ -264,17 +263,19 @@ namespace SixLabors.ImageSharp.Drawing.Tests
[Fact]
public void Intersections_IntersectionRule_Nonezero()
{
var shape = new InternalPath(new LinearLineSegment(
new PointF(1, 3),
new PointF(1, 2),
new PointF(5, 2),
new PointF(5, 5),
new PointF(2, 5),
new PointF(2, 1),
new PointF(3, 1),
new PointF(3, 4),
new PointF(4, 4),
new PointF(3, 4)), true);
var shape = new InternalPath(
new LinearLineSegment(
new PointF(1, 3),
new PointF(1, 2),
new PointF(5, 2),
new PointF(5, 5),
new PointF(2, 5),
new PointF(2, 1),
new PointF(3, 1),
new PointF(3, 4),
new PointF(4, 4),
new PointF(3, 4)),
true);
PointF[] buffer = shape.FindIntersections(new PointF(0, 2.5f), new PointF(6, 2.5f), IntersectionRule.Nonzero).ToArray();

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

@ -11,8 +11,8 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Shapes.Scan
public static readonly Polygon A = PolygonFactory.CreatePolygon(
(2, 2.5f), (11, 2.5f), (11, 3.25f), (8, 3.1f), (5, 3), (2, 3));
public static readonly Polygon B = PolygonFactory.CreatePolygon(
(12, 2.5f), (21, 2.5f), (21, 3.2f), (18, 3.125f), (15,3), (12,3));
public static readonly Polygon B = PolygonFactory.CreatePolygon(
(12, 2.5f), (21, 2.5f), (21, 3.2f), (18, 3.125f), (15, 3), (12, 3));
public static readonly Polygon C = PolygonFactory.CreatePolygon(
(2, 3.4f), (8, 3.6f), (8, 4), (5, 3.875f), (2, 4));
@ -33,7 +33,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Shapes.Scan
public static Polygon GetByName(string name)
{
return (Polygon) typeof(NumericCornerCasePolygons).GetField(name).GetValue(null);
return (Polygon)typeof(NumericCornerCasePolygons).GetField(name).GetValue(null);
}
}
}

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

@ -5,12 +5,10 @@ using System;
using System.Linq;
using System.Numerics;
using System.Text;
using SixLabors.ImageSharp.Drawing.Shapes;
using SixLabors.ImageSharp.Drawing.Shapes.Rasterization;
using SixLabors.ImageSharp.Drawing.Tests.TestUtilities;
using Xunit;
using Xunit.Abstractions;
using IOPath = System.IO.Path;
namespace SixLabors.ImageSharp.Drawing.Tests.Shapes.Scan
{
@ -21,13 +19,11 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Shapes.Scan
private static readonly DebugDraw DebugDraw = new DebugDraw(nameof(PolygonScannerTests));
public PolygonScannerTests(ITestOutputHelper output)
{
this.output = output;
}
=> this.output = output;
private void PrintPoints(ReadOnlySpan<PointF> points)
{
StringBuilder sb = new StringBuilder();
var sb = new StringBuilder();
foreach (PointF p in points)
{
@ -37,14 +33,15 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Shapes.Scan
this.output.WriteLine(sb.ToString());
}
private void PrintPointsX(PointF[] isc)
{
string s = string.Join(",", isc.Select(p => $"{p.X}"));
this.output.WriteLine(s);
}
private static void VerifyScanline(ReadOnlySpan<FuzzyFloat> expected, ReadOnlySpan<float> actual,
private static void VerifyScanline(
ReadOnlySpan<FuzzyFloat> expected,
ReadOnlySpan<float> actual,
string scanlineId)
{
if (expected == null)
@ -52,7 +49,8 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Shapes.Scan
return;
}
Assert.True(expected.Length == actual.Length,
Assert.True(
expected.Length == actual.Length,
$"Scanline had {actual.Length} intersections instead of {expected.Length}: {scanlineId}");
for (int i = 0; i < expected.Length; i++)
@ -62,7 +60,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Shapes.Scan
}
private void TestScan(IPath path, int min, int max, int subsampling, FuzzyFloat[][] expected) =>
TestScan(path, min, max, subsampling, expected, IntersectionRule.OddEven);
this.TestScan(path, min, max, subsampling, expected, IntersectionRule.OddEven);
private void TestScan(
IPath path,
@ -72,7 +70,8 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Shapes.Scan
FuzzyFloat[][] expected,
IntersectionRule intersectionRule)
{
var scanner = PolygonScanner.Create(path,
var scanner = PolygonScanner.Create(
path,
min,
max,
subsampling,
@ -109,19 +108,19 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Shapes.Scan
FuzzyFloat[][] expected =
{
new FuzzyFloat[] {2, 2},
new FuzzyFloat[] {2, 5},
new FuzzyFloat[] {2, 5},
new FuzzyFloat[] {2, 5},
new FuzzyFloat[] {2, 5, 5, 8},
new FuzzyFloat[] {2, 8},
new FuzzyFloat[] {2.75f, 8},
new FuzzyFloat[] {3.5f, 8},
new FuzzyFloat[] {4.25f, 6.5f},
new FuzzyFloat[] {5, 5},
new FuzzyFloat[] { 2, 2 },
new FuzzyFloat[] { 2, 5 },
new FuzzyFloat[] { 2, 5 },
new FuzzyFloat[] { 2, 5 },
new FuzzyFloat[] { 2, 5, 5, 8 },
new FuzzyFloat[] { 2, 8 },
new FuzzyFloat[] { 2.75f, 8 },
new FuzzyFloat[] { 3.5f, 8 },
new FuzzyFloat[] { 4.25f, 6.5f },
new FuzzyFloat[] { 5, 5 },
};
TestScan(poly, 2, 11, 1, expected);
this.TestScan(poly, 2, 11, 1, expected);
}
[Fact]
@ -132,30 +131,30 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Shapes.Scan
FuzzyFloat[][] expected =
{
new FuzzyFloat[] {0f, 0f, 20.000000f, 20.000000f,},
new FuzzyFloat[] {0f, 1.0000000f, 19.000000f, 20.000000f},
new FuzzyFloat[] {0f, 2.0000000f, 18.000000f, 20.000000f},
new FuzzyFloat[] {0f, 3.0000000f, 17.000000f, 20.000000f},
new FuzzyFloat[] {0f, 4.0000000f, 16.000000f, 20.000000f},
new FuzzyFloat[] {0f, 5.0000000f, 15.000000f, 20.000000f},
new FuzzyFloat[] {0f, 6.0000000f, 14.000000f, 20.000000f},
new FuzzyFloat[] {0f, 7.0000000f, 13.000000f, 20.000000f},
new FuzzyFloat[] {0f, 8.0000000f, 12.000000f, 20.000000f},
new FuzzyFloat[] {0f, 9.0000000f, 11.000000f, 20.000000f},
new FuzzyFloat[] {0f, 10.000000f, 10.000000f, 20.000000f},
new FuzzyFloat[] {0f, 20.000000f},
new FuzzyFloat[] {0f, 20.000000f},
new FuzzyFloat[] {0f, 20.000000f},
new FuzzyFloat[] {0f, 20.000000f},
new FuzzyFloat[] {0f, 20.000000f},
new FuzzyFloat[] {0f, 20.000000f},
new FuzzyFloat[] {0f, 20.000000f},
new FuzzyFloat[] {0f, 20.000000f},
new FuzzyFloat[] {0f, 20.000000f},
new FuzzyFloat[] {0f, 20.000000f},
new FuzzyFloat[] { 0f, 0f, 20.000000f, 20.000000f, },
new FuzzyFloat[] { 0f, 1.0000000f, 19.000000f, 20.000000f },
new FuzzyFloat[] { 0f, 2.0000000f, 18.000000f, 20.000000f },
new FuzzyFloat[] { 0f, 3.0000000f, 17.000000f, 20.000000f },
new FuzzyFloat[] { 0f, 4.0000000f, 16.000000f, 20.000000f },
new FuzzyFloat[] { 0f, 5.0000000f, 15.000000f, 20.000000f },
new FuzzyFloat[] { 0f, 6.0000000f, 14.000000f, 20.000000f },
new FuzzyFloat[] { 0f, 7.0000000f, 13.000000f, 20.000000f },
new FuzzyFloat[] { 0f, 8.0000000f, 12.000000f, 20.000000f },
new FuzzyFloat[] { 0f, 9.0000000f, 11.000000f, 20.000000f },
new FuzzyFloat[] { 0f, 10.000000f, 10.000000f, 20.000000f },
new FuzzyFloat[] { 0f, 20.000000f },
new FuzzyFloat[] { 0f, 20.000000f },
new FuzzyFloat[] { 0f, 20.000000f },
new FuzzyFloat[] { 0f, 20.000000f },
new FuzzyFloat[] { 0f, 20.000000f },
new FuzzyFloat[] { 0f, 20.000000f },
new FuzzyFloat[] { 0f, 20.000000f },
new FuzzyFloat[] { 0f, 20.000000f },
new FuzzyFloat[] { 0f, 20.000000f },
new FuzzyFloat[] { 0f, 20.000000f },
};
TestScan(poly, 0, 20, 1, expected);
this.TestScan(poly, 0, 20, 1, expected);
}
[Fact]
@ -166,43 +165,57 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Shapes.Scan
FuzzyFloat[][] expected =
{
new FuzzyFloat[] {0f, 0f, 3.0000000f, 3.0000000f},
new FuzzyFloat[] {0f, 0.50000000f, 2.5000000f, 3.0000000f},
new FuzzyFloat[] {0f, 1.0000000f, 2.0000000f, 3.0000000f},
new FuzzyFloat[] {0f, 1.0000000f, 1.5000000f, 3.0000000f},
new FuzzyFloat[] {0f, 1.0000000f, 1.0000000f, 3.0000000f},
new FuzzyFloat[] {0f, 3.0000000f},
new FuzzyFloat[] {0f, 3.0000000f},
new FuzzyFloat[] { 0f, 0f, 3.0000000f, 3.0000000f },
new FuzzyFloat[] { 0f, 0.50000000f, 2.5000000f, 3.0000000f },
new FuzzyFloat[] { 0f, 1.0000000f, 2.0000000f, 3.0000000f },
new FuzzyFloat[] { 0f, 1.0000000f, 1.5000000f, 3.0000000f },
new FuzzyFloat[] { 0f, 1.0000000f, 1.0000000f, 3.0000000f },
new FuzzyFloat[] { 0f, 3.0000000f },
new FuzzyFloat[] { 0f, 3.0000000f },
};
TestScan(poly, 0, 3, 2, expected);
this.TestScan(poly, 0, 3, 2, expected);
}
[Fact]
public void BasicConcave03()
{
IPath poly = PolygonFactory.CreatePolygon((0, 0), (2, 0), (3, 1), (3, 0), (6, 0), (6, 2), (5, 2), (5, 1),
(4, 1), (4, 2), (2, 2), (1, 1), (0, 2));
IPath poly = PolygonFactory.CreatePolygon(
(0, 0),
(2, 0),
(3, 1),
(3, 0),
(6, 0),
(6, 2),
(5, 2),
(5, 1),
(4, 1),
(4, 2),
(2, 2),
(1, 1),
(0, 2));
DebugDraw.Polygon(poly, 1f, 100f);
FuzzyFloat[][] expected =
{
new FuzzyFloat[] {0f, 2.0000000f, 3.0000000f, 6.0000000f},
new FuzzyFloat[] {0f, 2.2000000f, 3.0000000f, 6.0000000f},
new FuzzyFloat[] {0f, 2.4000000f, 3.0000000f, 6.0000000f},
new FuzzyFloat[] {0f, 2.6000000f, 3.0000000f, 6.0000000f},
new FuzzyFloat[] {0f, 2.8000000f, 3.0000000f, 6.0000000f},
new FuzzyFloat[] { 0f, 2.0000000f, 3.0000000f, 6.0000000f },
new FuzzyFloat[] { 0f, 2.2000000f, 3.0000000f, 6.0000000f },
new FuzzyFloat[] { 0f, 2.4000000f, 3.0000000f, 6.0000000f },
new FuzzyFloat[] { 0f, 2.6000000f, 3.0000000f, 6.0000000f },
new FuzzyFloat[] { 0f, 2.8000000f, 3.0000000f, 6.0000000f },
new FuzzyFloat[]
{
0f, 1.0000000f, 1.0000000f, 3.0000000f, 3.0000000f, 4.0000000f, 4.0000000f, 5.0000000f, 5.0000000f,
6.0000000f
},
new FuzzyFloat[] {0f, 0.80000000f, 1.2000000f, 4.0000000f, 5.0000000f, 6.0000000f},
new FuzzyFloat[] {0f, 0.60000000f, 1.4000000f, 4.0000000f, 5.0000000f, 6.0000000f},
new FuzzyFloat[] {0f, 0.40000000f, 1.6000000f, 4.0000000f, 5.0000000f, 6.0000000f},
new FuzzyFloat[] {0f, 0.20000000f, 1.8000000f, 4.0000000f, 5.0000000f, 6.0000000f},
new FuzzyFloat[] {0f, 0f, 2.0000000f, 4.0000000f, 5.0000000f, 6.0000000f},
new FuzzyFloat[] { 0f, 0.80000000f, 1.2000000f, 4.0000000f, 5.0000000f, 6.0000000f },
new FuzzyFloat[] { 0f, 0.60000000f, 1.4000000f, 4.0000000f, 5.0000000f, 6.0000000f },
new FuzzyFloat[] { 0f, 0.40000000f, 1.6000000f, 4.0000000f, 5.0000000f, 6.0000000f },
new FuzzyFloat[] { 0f, 0.20000000f, 1.8000000f, 4.0000000f, 5.0000000f, 6.0000000f },
new FuzzyFloat[] { 0f, 0f, 2.0000000f, 4.0000000f, 5.0000000f, 6.0000000f },
};
TestScan(poly, 0, 2, 5, expected);
this.TestScan(poly, 0, 2, 5, expected);
}
[Fact]
@ -214,29 +227,29 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Shapes.Scan
FuzzyFloat[][] expected =
{
new FuzzyFloat[] {0f, 10.000000f},
new FuzzyFloat[] {0.50000000f, 9.5000000f},
new FuzzyFloat[] {1.0000000f, 9.0000000f},
new FuzzyFloat[] {1.5000000f, 8.5000000f},
new FuzzyFloat[] {2.0000000f, 8.0000000f},
new FuzzyFloat[] {2.5000000f, 7.5000000f},
new FuzzyFloat[] {3.0000000f, 7.0000000f},
new FuzzyFloat[] {3.5000000f, 6.5000000f},
new FuzzyFloat[] {4.0000000f, 6.0000000f},
new FuzzyFloat[] {4.5000000f, 5.5000000f},
new FuzzyFloat[] {5.0000000f, 5.0000000f},
new FuzzyFloat[] {4.5000000f, 5.5000000f},
new FuzzyFloat[] {4.0000000f, 6.0000000f},
new FuzzyFloat[] {3.5000000f, 6.5000000f},
new FuzzyFloat[] {3.0000000f, 7.0000000f},
new FuzzyFloat[] {2.5000000f, 7.5000000f},
new FuzzyFloat[] {2.0000000f, 8.0000000f},
new FuzzyFloat[] {1.5000000f, 8.5000000f},
new FuzzyFloat[] {1.0000000f, 9.0000000f},
new FuzzyFloat[] {0.50000000f, 9.5000000f},
new FuzzyFloat[] {0f, 10.000000f},
new FuzzyFloat[] { 0f, 10.000000f },
new FuzzyFloat[] { 0.50000000f, 9.5000000f },
new FuzzyFloat[] { 1.0000000f, 9.0000000f },
new FuzzyFloat[] { 1.5000000f, 8.5000000f },
new FuzzyFloat[] { 2.0000000f, 8.0000000f },
new FuzzyFloat[] { 2.5000000f, 7.5000000f },
new FuzzyFloat[] { 3.0000000f, 7.0000000f },
new FuzzyFloat[] { 3.5000000f, 6.5000000f },
new FuzzyFloat[] { 4.0000000f, 6.0000000f },
new FuzzyFloat[] { 4.5000000f, 5.5000000f },
new FuzzyFloat[] { 5.0000000f, 5.0000000f },
new FuzzyFloat[] { 4.5000000f, 5.5000000f },
new FuzzyFloat[] { 4.0000000f, 6.0000000f },
new FuzzyFloat[] { 3.5000000f, 6.5000000f },
new FuzzyFloat[] { 3.0000000f, 7.0000000f },
new FuzzyFloat[] { 2.5000000f, 7.5000000f },
new FuzzyFloat[] { 2.0000000f, 8.0000000f },
new FuzzyFloat[] { 1.5000000f, 8.5000000f },
new FuzzyFloat[] { 1.0000000f, 9.0000000f },
new FuzzyFloat[] { 0.50000000f, 9.5000000f },
new FuzzyFloat[] { 0f, 10.000000f },
};
TestScan(poly, 0, 10, 2, expected);
this.TestScan(poly, 0, 10, 2, expected);
}
[Fact]
@ -247,29 +260,29 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Shapes.Scan
FuzzyFloat[][] expected =
{
new FuzzyFloat[] {0f, 0f, 10.000000f, 10.000000f},
new FuzzyFloat[] {0f, 0.50000000f, 9.5000000f, 10.000000f},
new FuzzyFloat[] {0f, 1.0000000f, 9.0000000f, 10.000000f},
new FuzzyFloat[] {0f, 1.5000000f, 8.5000000f, 10.000000f},
new FuzzyFloat[] {0f, 2.0000000f, 8.0000000f, 10.000000f},
new FuzzyFloat[] {0f, 2.5000000f, 7.5000000f, 10.000000f},
new FuzzyFloat[] {0f, 3.0000000f, 7.0000000f, 10.000000f},
new FuzzyFloat[] {0f, 3.5000000f, 6.5000000f, 10.000000f},
new FuzzyFloat[] {0f, 4.0000000f, 6.0000000f, 10.000000f},
new FuzzyFloat[] {0f, 4.5000000f, 5.5000000f, 10.000000f},
new FuzzyFloat[] {0f, 5.0000000f, 5.0000000f, 10.000000f},
new FuzzyFloat[] {0f, 4.5000000f, 5.5000000f, 10.000000f},
new FuzzyFloat[] {0f, 4.0000000f, 6.0000000f, 10.000000f},
new FuzzyFloat[] {0f, 3.5000000f, 6.5000000f, 10.000000f},
new FuzzyFloat[] {0f, 3.0000000f, 7.0000000f, 10.000000f},
new FuzzyFloat[] {0f, 2.5000000f, 7.5000000f, 10.000000f},
new FuzzyFloat[] {0f, 2.0000000f, 8.0000000f, 10.000000f},
new FuzzyFloat[] {0f, 1.5000000f, 8.5000000f, 10.000000f},
new FuzzyFloat[] {0f, 1.0000000f, 9.0000000f, 10.000000f},
new FuzzyFloat[] {0f, 0.50000000f, 9.5000000f, 10.000000f},
new FuzzyFloat[] {0f, 0f, 10.000000f, 10.000000f},
new FuzzyFloat[] { 0f, 0f, 10.000000f, 10.000000f },
new FuzzyFloat[] { 0f, 0.50000000f, 9.5000000f, 10.000000f },
new FuzzyFloat[] { 0f, 1.0000000f, 9.0000000f, 10.000000f },
new FuzzyFloat[] { 0f, 1.5000000f, 8.5000000f, 10.000000f },
new FuzzyFloat[] { 0f, 2.0000000f, 8.0000000f, 10.000000f },
new FuzzyFloat[] { 0f, 2.5000000f, 7.5000000f, 10.000000f },
new FuzzyFloat[] { 0f, 3.0000000f, 7.0000000f, 10.000000f },
new FuzzyFloat[] { 0f, 3.5000000f, 6.5000000f, 10.000000f },
new FuzzyFloat[] { 0f, 4.0000000f, 6.0000000f, 10.000000f },
new FuzzyFloat[] { 0f, 4.5000000f, 5.5000000f, 10.000000f },
new FuzzyFloat[] { 0f, 5.0000000f, 5.0000000f, 10.000000f },
new FuzzyFloat[] { 0f, 4.5000000f, 5.5000000f, 10.000000f },
new FuzzyFloat[] { 0f, 4.0000000f, 6.0000000f, 10.000000f },
new FuzzyFloat[] { 0f, 3.5000000f, 6.5000000f, 10.000000f },
new FuzzyFloat[] { 0f, 3.0000000f, 7.0000000f, 10.000000f },
new FuzzyFloat[] { 0f, 2.5000000f, 7.5000000f, 10.000000f },
new FuzzyFloat[] { 0f, 2.0000000f, 8.0000000f, 10.000000f },
new FuzzyFloat[] { 0f, 1.5000000f, 8.5000000f, 10.000000f },
new FuzzyFloat[] { 0f, 1.0000000f, 9.0000000f, 10.000000f },
new FuzzyFloat[] { 0f, 0.50000000f, 9.5000000f, 10.000000f },
new FuzzyFloat[] { 0f, 0f, 10.000000f, 10.000000f },
};
TestScan(poly, 0, 10, 2, expected);
this.TestScan(poly, 0, 10, 2, expected);
}
[Theory]
@ -277,8 +290,19 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Shapes.Scan
[InlineData(IntersectionRule.Nonzero)]
public void SelfIntersecting03(IntersectionRule rule)
{
IPath poly = PolygonFactory.CreatePolygon((1, 3), (1, 2), (5, 2), (5, 5), (2, 5), (2, 1), (3, 1), (3, 4),
(4, 4), (4, 3), (1, 3));
IPath poly = PolygonFactory.CreatePolygon(
(1, 3),
(1, 2),
(5, 2),
(5, 5),
(2, 5),
(2, 1),
(3, 1),
(3, 4),
(4, 4),
(4, 3),
(1, 3));
DebugDraw.Polygon(poly, 1f, 100f);
FuzzyFloat[][] expected;
@ -286,34 +310,34 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Shapes.Scan
{
expected = new[]
{
new FuzzyFloat[] {2.0000000f, 3.0000000f},
new FuzzyFloat[] {2.0000000f, 3.0000000f},
new FuzzyFloat[] {1.0000000f, 2.0000000f, 3.0000000f, 5.0000000f},
new FuzzyFloat[] {1.0000000f, 2.0000000f, 3.0000000f, 5.0000000f},
new FuzzyFloat[] {1.0000000f, 2.0000000f, 3.0000000f, 4.0000000f, 4.0000000f, 5.0000000f},
new FuzzyFloat[] {2.0000000f, 3.0000000f, 4.0000000f, 5.0000000f},
new FuzzyFloat[] {2.0000000f, 3.0000000f, 3.0000000f, 4.0000000f, 4.0000000f, 5.0000000f},
new FuzzyFloat[] {2.0000000f, 5.0000000f},
new FuzzyFloat[] {2.0000000f, 5.0000000f},
new FuzzyFloat[] { 2.0000000f, 3.0000000f },
new FuzzyFloat[] { 2.0000000f, 3.0000000f },
new FuzzyFloat[] { 1.0000000f, 2.0000000f, 3.0000000f, 5.0000000f },
new FuzzyFloat[] { 1.0000000f, 2.0000000f, 3.0000000f, 5.0000000f },
new FuzzyFloat[] { 1.0000000f, 2.0000000f, 3.0000000f, 4.0000000f, 4.0000000f, 5.0000000f },
new FuzzyFloat[] { 2.0000000f, 3.0000000f, 4.0000000f, 5.0000000f },
new FuzzyFloat[] { 2.0000000f, 3.0000000f, 3.0000000f, 4.0000000f, 4.0000000f, 5.0000000f },
new FuzzyFloat[] { 2.0000000f, 5.0000000f },
new FuzzyFloat[] { 2.0000000f, 5.0000000f },
};
}
else
{
expected = new[]
{
new FuzzyFloat[] {2.0000000f, 3.0000000f},
new FuzzyFloat[] {2.0000000f, 3.0000000f},
new FuzzyFloat[] {1.0000000f, 5.0000000f},
new FuzzyFloat[] {1.0000000f, 5.0000000f},
new FuzzyFloat[] {1.0000000f, 4.0000000f, 4.0000000f, 5.0000000f},
new FuzzyFloat[] {2.0000000f, 3.0000000f, 4.0000000f, 5.0000000f},
new FuzzyFloat[] {2.0000000f, 3.0000000f, 3.0000000f, 4.0000000f, 4.0000000f, 5.0000000f},
new FuzzyFloat[] {2.0000000f, 5.0000000f},
new FuzzyFloat[] {2.0000000f, 5.0000000f},
new FuzzyFloat[] { 2.0000000f, 3.0000000f },
new FuzzyFloat[] { 2.0000000f, 3.0000000f },
new FuzzyFloat[] { 1.0000000f, 5.0000000f },
new FuzzyFloat[] { 1.0000000f, 5.0000000f },
new FuzzyFloat[] { 1.0000000f, 4.0000000f, 4.0000000f, 5.0000000f },
new FuzzyFloat[] { 2.0000000f, 3.0000000f, 4.0000000f, 5.0000000f },
new FuzzyFloat[] { 2.0000000f, 3.0000000f, 3.0000000f, 4.0000000f, 4.0000000f, 5.0000000f },
new FuzzyFloat[] { 2.0000000f, 5.0000000f },
new FuzzyFloat[] { 2.0000000f, 5.0000000f },
};
}
TestScan(poly, 1, 5, 2, expected, rule);
this.TestScan(poly, 1, 5, 2, expected, rule);
}
[Theory]
@ -321,8 +345,23 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Shapes.Scan
[InlineData(IntersectionRule.Nonzero)]
public void SelfIntersecting04(IntersectionRule rule)
{
IPath poly = PolygonFactory.CreatePolygon((1, 4), (1, 3), (3, 3), (3, 2), (2, 2), (2, 4), (1, 4), (1, 1),
(4, 1), (4, 4), (3, 4), (3, 5), (2, 5), (2, 4), (1, 4));
IPath poly = PolygonFactory.CreatePolygon(
(1, 4),
(1, 3),
(3, 3),
(3, 2),
(2, 2),
(2, 4),
(1, 4),
(1, 1),
(4, 1),
(4, 4),
(3, 4),
(3, 5),
(2, 5),
(2, 4),
(1, 4));
DebugDraw.Polygon(poly, 1f, 100f);
FuzzyFloat[][] expected;
@ -330,37 +369,36 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Shapes.Scan
{
expected = new[]
{
new FuzzyFloat[] {1, 4},
new FuzzyFloat[] {1, 4},
new FuzzyFloat[] {1, 2, 2, 3, 3, 4},
new FuzzyFloat[] {1, 2, 3, 4},
new FuzzyFloat[] {1, 1, 2, 3, 3, 4},
new FuzzyFloat[] {1, 1, 2, 4},
new FuzzyFloat[] {1, 1, 2, 2, 2, 3, 3, 4},
new FuzzyFloat[] {2, 3},
new FuzzyFloat[] {2, 3},
new FuzzyFloat[] { 1, 4 },
new FuzzyFloat[] { 1, 4 },
new FuzzyFloat[] { 1, 2, 2, 3, 3, 4 },
new FuzzyFloat[] { 1, 2, 3, 4 },
new FuzzyFloat[] { 1, 1, 2, 3, 3, 4 },
new FuzzyFloat[] { 1, 1, 2, 4 },
new FuzzyFloat[] { 1, 1, 2, 2, 2, 3, 3, 4 },
new FuzzyFloat[] { 2, 3 },
new FuzzyFloat[] { 2, 3 },
};
}
else
{
expected = new[]
{
new FuzzyFloat[] {1, 4},
new FuzzyFloat[] {1, 4},
new FuzzyFloat[] {1, 2, 2, 3, 3, 4},
new FuzzyFloat[] {1, 2, 3, 4},
new FuzzyFloat[] {1, 3, 3, 4},
new FuzzyFloat[] {1, 4},
new FuzzyFloat[] {1, 2, 2, 3, 3, 4 },
new FuzzyFloat[] {2, 3},
new FuzzyFloat[] {2, 3},
new FuzzyFloat[] { 1, 4 },
new FuzzyFloat[] { 1, 4 },
new FuzzyFloat[] { 1, 2, 2, 3, 3, 4 },
new FuzzyFloat[] { 1, 2, 3, 4 },
new FuzzyFloat[] { 1, 3, 3, 4 },
new FuzzyFloat[] { 1, 4 },
new FuzzyFloat[] { 1, 2, 2, 3, 3, 4 },
new FuzzyFloat[] { 2, 3 },
new FuzzyFloat[] { 2, 3 },
};
}
TestScan(poly, 1, 5, 2, expected, rule);
this.TestScan(poly, 1, 5, 2, expected, rule);
}
[Theory]
[InlineData(IntersectionRule.OddEven)]
[InlineData(IntersectionRule.Nonzero)]
@ -378,14 +416,14 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Shapes.Scan
FuzzyFloat[][] expected =
{
new FuzzyFloat[] { 0, 0, 2, 2},
new FuzzyFloat[] { 0, 0, 2, 2 },
new FuzzyFloat[] { 0, 2 },
new FuzzyFloat[] { 0, 2 },
new FuzzyFloat[] { 0, 2 },
new FuzzyFloat[] { 0, 0, 2, 2},
new FuzzyFloat[] { 0, 0, 2, 2 },
};
TestScan(poly, 0, 2, 2, expected, intersectionRule);
this.TestScan(poly, 0, 2, 2, expected, intersectionRule);
}
private static (float y, FuzzyFloat[] x) Empty(float y) => (y, new FuzzyFloat[0]);
@ -400,10 +438,10 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Shapes.Scan
{
Empty(2f), Empty(2.25f),
(2.5f, new FuzzyFloat[] {2, 11}),
(2.75f, new FuzzyFloat[] {2, 11}),
(3f, new FuzzyFloat[] {2, 8, 8, 11}),
(3.25f, new FuzzyFloat[] {11, 11}),
(2.5f, new FuzzyFloat[] { 2, 11 }),
(2.75f, new FuzzyFloat[] { 2, 11 }),
(3f, new FuzzyFloat[] { 2, 8, 8, 11 }),
(3.25f, new FuzzyFloat[] { 11, 11 }),
Empty(3.5f), Empty(3.75f), Empty(4f),
}
@ -413,10 +451,10 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Shapes.Scan
{
Empty(2f), Empty(2.25f),
(2.5f, new FuzzyFloat[] {12, 21}),
(2.75f, new FuzzyFloat[] {12, 21}),
(3f, new FuzzyFloat[] {12, 15, 15, 21}),
(3.25f, new FuzzyFloat[] {18, 21}),
(2.5f, new FuzzyFloat[] { 12, 21 }),
(2.75f, new FuzzyFloat[] { 12, 21 }),
(3f, new FuzzyFloat[] { 12, 15, 15, 21 }),
(3.25f, new FuzzyFloat[] { 18, 21 }),
Empty(3.5f), Empty(3.75f), Empty(4f),
}
@ -426,9 +464,9 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Shapes.Scan
{
Empty(3f), Empty(3.25f),
(3.5f, new FuzzyFloat[] {2, 8}),
(3.75f, new FuzzyFloat[] {2, 8}),
(4f, new FuzzyFloat[] {2, 8}),
(3.5f, new FuzzyFloat[] { 2, 8 }),
(3.75f, new FuzzyFloat[] { 2, 8 }),
(4f, new FuzzyFloat[] { 2, 8 }),
}
},
{
@ -436,10 +474,10 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Shapes.Scan
{
Empty(3f),
(3.25f, new FuzzyFloat[] {12, 12}),
(3.5f, new FuzzyFloat[] {12, 18}),
(3.75f, new FuzzyFloat[] {12, 15, 15, 18}),
(4f, new FuzzyFloat[] {12, 12, 18, 18}),
(3.25f, new FuzzyFloat[] { 12, 12 }),
(3.5f, new FuzzyFloat[] { 12, 18 }),
(3.75f, new FuzzyFloat[] { 12, 15, 15, 18 }),
(4f, new FuzzyFloat[] { 12, 12, 18, 18 }),
}
},
{
@ -447,9 +485,9 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Shapes.Scan
{
Empty(4f), Empty(4.25f),
(4.5f, new FuzzyFloat[] {3, 3, 6, 6}),
(4.75f, new FuzzyFloat[] {F(2.4166667f, 0.5f), 4, 4, 6}),
(5f, new FuzzyFloat[] {2, 6}),
(4.5f, new FuzzyFloat[] { 3, 3, 6, 6 }),
(4.75f, new FuzzyFloat[] { F(2.4166667f, 0.5f), 4, 4, 6 }),
(5f, new FuzzyFloat[] { 2, 6 }),
}
},
{
@ -458,10 +496,10 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Shapes.Scan
Empty(4f),
// Eps = 0.01 to address inaccuracies on .NET Framework
(4.25f, new FuzzyFloat[] { F(13, 0.01f), F(13, 0.01f)}),
(4.5f, new FuzzyFloat[] {F(12.714286f, 0.5f), F(13.444444f, 0.5f), 16, 16}),
(4.75f, new FuzzyFloat[] {F(12.357143f, 0.5f), 14, 14, 16}),
(5f, new FuzzyFloat[] {12, 16}),
(4.25f, new FuzzyFloat[] { F(13, 0.01f), F(13, 0.01f) }),
(4.5f, new FuzzyFloat[] { F(12.714286f, 0.5f), F(13.444444f, 0.5f), 16, 16 }),
(4.75f, new FuzzyFloat[] { F(12.357143f, 0.5f), 14, 14, 16 }),
(5f, new FuzzyFloat[] { 12, 16 }),
}
},
{
@ -469,9 +507,9 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Shapes.Scan
{
Empty(1f), Empty(1.25f), Empty(1.5f),
(1.75f, new FuzzyFloat[] {6, 6}),
(2f, new FuzzyFloat[] {F(4.6315789f, 1f), F(7.3684211f, 1f)}),
(2.25f, new FuzzyFloat[] {2, 10}),
(1.75f, new FuzzyFloat[] { 6, 6 }),
(2f, new FuzzyFloat[] { F(4.6315789f, 1f), F(7.3684211f, 1f) }),
(2.25f, new FuzzyFloat[] { 2, 10 }),
Empty(2.5f), Empty(1.75f), Empty(3f),
}
@ -481,9 +519,9 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Shapes.Scan
{
Empty(1f), Empty(1.25f), Empty(1.5f),
(1.75f, new FuzzyFloat[] {16, 16}),
(2f, new FuzzyFloat[] {14, 14, 14, 16}), // this emits 2 dummy points, but normally it should not corrupt quality too much
(2.25f, new FuzzyFloat[] {16, 16}),
(1.75f, new FuzzyFloat[] { 16, 16 }),
(2f, new FuzzyFloat[] { 14, 14, 14, 16 }), // this emits 2 dummy points, but normally it should not corrupt quality too much
(2.25f, new FuzzyFloat[] { 16, 16 }),
Empty(2.5f), Empty(1.75f), Empty(3f),
}
@ -495,25 +533,25 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Shapes.Scan
public void NumericCornerCases(string name, (float y, FuzzyFloat[] x)[] expectedIntersections)
{
Polygon poly = NumericCornerCasePolygons.GetByName(name);
DebugDraw.Polygon(poly, 0.25f, 100f, $"{nameof(NumericCornerCases)}_{name}");
DebugDraw.Polygon(poly, 0.25f, 100f, $"{nameof(this.NumericCornerCases)}_{name}");
int min = (int) expectedIntersections.First().y;
int max = (int) expectedIntersections.Last().y;
int min = (int)expectedIntersections.First().y;
int max = (int)expectedIntersections.Last().y;
TestScan(poly, min, max, 4, expectedIntersections.Select(i => i.x).ToArray());
this.TestScan(poly, min, max, 4, expectedIntersections.Select(i => i.x).ToArray());
}
public static TheoryData<float, string, (float y, FuzzyFloat[] x)[]> NumericCornerCases_Offset_Data()
{
var result = new TheoryData<float, string, (float y, FuzzyFloat[] x)[]>();
float[] offsets = {1e3f, 1e4f, 1e5f};
float[] offsets = { 1e3f, 1e4f, 1e5f };
foreach (float offset in offsets)
{
foreach (var data in NumericCornerCasesData)
foreach (object[] data in NumericCornerCasesData)
{
result.Add(offset, (string)data[0], ((float y, FuzzyFloat[] x)[]) data[1]);
result.Add(offset, (string)data[0], ((float y, FuzzyFloat[] x)[])data[1]);
}
}
@ -530,16 +568,14 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Shapes.Scan
IPath poly = NumericCornerCasePolygons.GetByName(name).Transform(Matrix3x2.CreateTranslation(dx, dy));
expectedIntersections = TranslateIntersections(expectedIntersections, dx, dy);
int min = (int) expectedIntersections.First().y;
int max = (int) expectedIntersections.Last().y;
int min = (int)expectedIntersections.First().y;
int max = (int)expectedIntersections.Last().y;
TestScan(poly, min, max, 4, expectedIntersections.Select(i => i.x).ToArray());
this.TestScan(poly, min, max, 4, expectedIntersections.Select(i => i.x).ToArray());
}
private static (float y, FuzzyFloat[] x)[] TranslateIntersections(
(float y, FuzzyFloat[] x)[] ex, float dx, float dy)
{
return ex.Select(e => (e.y + dy, e.x.Select(xx => xx + dx).ToArray())).ToArray();
}
=> ex.Select(e => (e.y + dy, e.x.Select(xx => xx + dx).ToArray())).ToArray();
}
}

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

@ -10,21 +10,21 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Shapes.Scan
{
public class ScanEdgeCollectionTests
{
private ScanEdgeCollection _edges;
private ScanEdgeCollection edges;
private static MemoryAllocator MemoryAllocator => Configuration.Default.MemoryAllocator;
private static readonly DebugDraw DebugDraw = new DebugDraw(nameof(ScanEdgeCollectionTests));
private void VerifyEdge(float y0,
private void VerifyEdge(
float y0,
float y1,
(FuzzyFloat X, FuzzyFloat Y) arbitraryPoint,
int emit0,
int emit1,
bool edgeUp)
{
foreach (ScanEdge e in _edges.Edges)
foreach (ScanEdge e in this.edges.Edges)
{
if (y0 == e.Y0 && y1 == e.Y1)
{
@ -49,36 +49,58 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Shapes.Scan
{
// see: SimplePolygon_AllEmitCases.png
Polygon polygon = PolygonFactory.CreatePolygon(
(1, 2), (2, 2), (3, 1), (4, 3), (6, 1), (7, 2), (8, 2), (9, 3),
(9, 4), (10, 5), (9, 6), (8, 6), (8, 7), (9,7), (9, 8),
(7, 8), (6, 7), (5, 8), (4, 7), (3, 8), (2, 8),
(2, 6), (3, 5), (2, 5), (2, 4), (1, 3)
);
(1, 2),
(2, 2),
(3, 1),
(4, 3),
(6, 1),
(7, 2),
(8, 2),
(9, 3),
(9, 4),
(10, 5),
(9, 6),
(8, 6),
(8, 7),
(9, 7),
(9, 8),
(7, 8),
(6, 7),
(5, 8),
(4, 7),
(3, 8),
(2, 8),
(2, 6),
(3, 5),
(2, 5),
(2, 4),
(1, 3));
DebugDraw.Polygon(polygon, 1, 100);
_edges = ScanEdgeCollection.Create(polygon, MemoryAllocator, 16);
this.edges = ScanEdgeCollection.Create(polygon, MemoryAllocator, 16);
Assert.Equal(19, _edges.Edges.Length);
Assert.Equal(19, this.edges.Edges.Length);
VerifyEdge(1f, 2f, (2.5f, 1.5f), 1, 2, true);
VerifyEdge(1f, 3f, (3.5f, 2f), 1, 1, false);
VerifyEdge(1f, 3f, (5f, 2f), 1, 1, true);
VerifyEdge(1f, 2f, (6.5f, 1.5f), 1, 2, false);
VerifyEdge(2f, 3f, (8.5f, 2.5f), 1, 0, false);
VerifyEdge(3f, 4f, (9f, 3.5f), 1, 0, false);
VerifyEdge(4f, 5f, (9.5f, 4.5f), 1, 0, false);
VerifyEdge(5f, 6f, (9.5f, 5.5f), 1, 1, false);
VerifyEdge(6f, 7f, (8f, 6.5f), 2, 2, false);
VerifyEdge(7f, 8f, (9f, 7.5f), 1, 1, false);
VerifyEdge(7f, 8f, (6.5f, 7.5f), 1, 1, true);
VerifyEdge(7f, 8f, (5.5f, 7.5f), 1, 1, false);
VerifyEdge(7f, 8f, (4.5f, 7.5f), 1, 1, true);
VerifyEdge(7f, 8f, (3.5f, 7.5f), 1, 1, false);
VerifyEdge(6f, 8f, (2f, 7f), 0, 1, true);
VerifyEdge(5f, 6f, (2.5f, 5.5f), 2, 1, true);
VerifyEdge(4f, 5f, (2f, 4.5f), 0, 1, true);
VerifyEdge(3f, 4f, (1.5f, 3.5f), 0, 1, true);
VerifyEdge(2f, 3f, (1f, 1.5f), 1, 1, true);
this.VerifyEdge(1f, 2f, (2.5f, 1.5f), 1, 2, true);
this.VerifyEdge(1f, 3f, (3.5f, 2f), 1, 1, false);
this.VerifyEdge(1f, 3f, (5f, 2f), 1, 1, true);
this.VerifyEdge(1f, 2f, (6.5f, 1.5f), 1, 2, false);
this.VerifyEdge(2f, 3f, (8.5f, 2.5f), 1, 0, false);
this.VerifyEdge(3f, 4f, (9f, 3.5f), 1, 0, false);
this.VerifyEdge(4f, 5f, (9.5f, 4.5f), 1, 0, false);
this.VerifyEdge(5f, 6f, (9.5f, 5.5f), 1, 1, false);
this.VerifyEdge(6f, 7f, (8f, 6.5f), 2, 2, false);
this.VerifyEdge(7f, 8f, (9f, 7.5f), 1, 1, false);
this.VerifyEdge(7f, 8f, (6.5f, 7.5f), 1, 1, true);
this.VerifyEdge(7f, 8f, (5.5f, 7.5f), 1, 1, false);
this.VerifyEdge(7f, 8f, (4.5f, 7.5f), 1, 1, true);
this.VerifyEdge(7f, 8f, (3.5f, 7.5f), 1, 1, false);
this.VerifyEdge(6f, 8f, (2f, 7f), 0, 1, true);
this.VerifyEdge(5f, 6f, (2.5f, 5.5f), 2, 1, true);
this.VerifyEdge(4f, 5f, (2f, 4.5f), 0, 1, true);
this.VerifyEdge(3f, 4f, (1.5f, 3.5f), 0, 1, true);
this.VerifyEdge(2f, 3f, (1f, 1.5f), 1, 1, true);
}
[Fact]
@ -92,39 +114,39 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Shapes.Scan
IPath polygon = contour.Clip(hole);
DebugDraw.Polygon(polygon, 1, 100);
_edges = ScanEdgeCollection.Create(polygon, MemoryAllocator, 16);
this.edges = ScanEdgeCollection.Create(polygon, MemoryAllocator, 16);
Assert.Equal(8, _edges.Count);
Assert.Equal(8, this.edges.Count);
VerifyEdge(1, 4, (1, 2), 1, 1, true);
VerifyEdge(1, 2, (4, 1.5f), 1, 2, false);
VerifyEdge(4, 5, (2, 4.5f), 2, 1, true);
VerifyEdge(2, 5, (5, 3f), 1, 1, false);
this.VerifyEdge(1, 4, (1, 2), 1, 1, true);
this.VerifyEdge(1, 2, (4, 1.5f), 1, 2, false);
this.VerifyEdge(4, 5, (2, 4.5f), 2, 1, true);
this.VerifyEdge(2, 5, (5, 3f), 1, 1, false);
VerifyEdge(2, 3, (2, 2.5f), 2, 2, false);
VerifyEdge(2, 3, (3.5f, 2.5f), 2, 1, true);
VerifyEdge(3, 4, (3, 3.5f), 1, 2, false);
VerifyEdge(3, 4, (4, 3.5f), 0, 2, true);
this.VerifyEdge(2, 3, (2, 2.5f), 2, 2, false);
this.VerifyEdge(2, 3, (3.5f, 2.5f), 2, 1, true);
this.VerifyEdge(3, 4, (3, 3.5f), 1, 2, false);
this.VerifyEdge(3, 4, (4, 3.5f), 0, 2, true);
}
[Fact]
public void NumericCornerCase_C()
{
_edges = ScanEdgeCollection.Create(NumericCornerCasePolygons.C, MemoryAllocator, 4);
Assert.Equal(2, _edges.Count);
VerifyEdge(3.5f, 4f, (2f, 3.75f), 1, 1, true);
VerifyEdge(3.5f, 4f, (8f, 3.75f), 1, 1, false);
this.edges = ScanEdgeCollection.Create(NumericCornerCasePolygons.C, MemoryAllocator, 4);
Assert.Equal(2, this.edges.Count);
this.VerifyEdge(3.5f, 4f, (2f, 3.75f), 1, 1, true);
this.VerifyEdge(3.5f, 4f, (8f, 3.75f), 1, 1, false);
}
[Fact]
public void NumericCornerCase_D()
{
_edges = ScanEdgeCollection.Create(NumericCornerCasePolygons.D, MemoryAllocator, 4);
Assert.Equal(5, _edges.Count);
this.edges = ScanEdgeCollection.Create(NumericCornerCasePolygons.D, MemoryAllocator, 4);
Assert.Equal(5, this.edges.Count);
VerifyEdge(3.25f, 4f, (12f, 3.75f), 1, 1, true);
VerifyEdge(3.25f, 3.5f, (15f, 3.375f), 1, 0, false);
VerifyEdge(3.5f, 4f, (18f, 3.75f), 1, 1, false);
this.VerifyEdge(3.25f, 4f, (12f, 3.75f), 1, 1, true);
this.VerifyEdge(3.25f, 3.5f, (15f, 3.375f), 1, 0, false);
this.VerifyEdge(3.5f, 4f, (18f, 3.75f), 1, 1, false);
// TODO: verify 2 more edges
}
@ -132,14 +154,14 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Shapes.Scan
[Fact]
public void NumericCornerCase_H_ShouldCollapseNearZeroEdge()
{
_edges = ScanEdgeCollection.Create(NumericCornerCasePolygons.H, MemoryAllocator, 4);
this.edges = ScanEdgeCollection.Create(NumericCornerCasePolygons.H, MemoryAllocator, 4);
Assert.Equal(3, _edges.Count);
VerifyEdge(1.75f, 2f, (15f, 1.875f), 1, 1, true);
VerifyEdge(1.75f, 2.25f, (16f, 2f), 1, 1, false);
Assert.Equal(3, this.edges.Count);
this.VerifyEdge(1.75f, 2f, (15f, 1.875f), 1, 1, true);
this.VerifyEdge(1.75f, 2.25f, (16f, 2f), 1, 1, false);
// this places two dummy points:
VerifyEdge( 2f, 2.25f, (15f, 2.125f), 2, 1, true);
this.VerifyEdge(2f, 2.25f, (15f, 2.125f), 2, 1, true);
}
private static FuzzyFloat F(float value, float eps) => new FuzzyFloat(value, eps);

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

@ -4,7 +4,6 @@
using System;
using System.Linq;
using SixLabors.ImageSharp.Drawing.Shapes;
using SixLabors.ImageSharp.Drawing.Shapes.Rasterization;
using SixLabors.ImageSharp.Memory;
using Xunit;
@ -24,8 +23,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Shapes.Scan
originalPoints = originalPoints.CloneArray();
if (originalPositive && isHole || !originalPositive && !isHole)
if ((originalPositive && isHole) || (!originalPositive && !isHole))
{
originalPoints.AsSpan().Reverse();
points = points.Slice(1);
@ -49,7 +47,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Shapes.Scan
points.AsSpan().Reverse();
}
Polygon polygon = new Polygon(new LinearLineSegment(points));
var polygon = new Polygon(new LinearLineSegment(points));
using var multipolygon = TessellatedMultipolygon.Create(polygon, MemoryAllocator);
VerifyRing(multipolygon[0], points, reverseOriginal, false);
@ -67,7 +65,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Shapes.Scan
points.AsSpan().Reverse();
}
Polygon polygon = new Polygon(new LinearLineSegment(points));
var polygon = new Polygon(new LinearLineSegment(points));
using var multipolygon = TessellatedMultipolygon.Create(polygon, MemoryAllocator);
@ -77,7 +75,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Shapes.Scan
[Fact]
public void Create_FromRecangle()
{
RectangularPolygon polygon = new RectangularPolygon( 10, 20, 100, 50);
var polygon = new RectangularPolygon(10, 20, 100, 50);
PointF[] points = polygon.Flatten().Single().Points.Span.ToArray();
@ -89,7 +87,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Shapes.Scan
[Fact]
public void Create_FromStar()
{
Star polygon = new Star(100, 100, 5, 30, 60);
var polygon = new Star(100, 100, 5, 30, 60);
PointF[] points = polygon.Flatten().Single().Points.Span.ToArray();
using var multipolygon = TessellatedMultipolygon.Create(polygon, MemoryAllocator);

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

@ -3,17 +3,23 @@
using System;
using SixLabors.ImageSharp.Drawing.Shapes.Helpers;
using SixLabors.ImageSharp.Drawing.Shapes.Rasterization;
using Xunit;
namespace SixLabors.ImageSharp.Drawing.Tests.Shapes.Scan
{
public class TopologyUtilitiesTests0
public class TopologyUtilitiesTests
{
private static PointF[] CreateTestPoints()
{
return PolygonFactory.CreatePointArray((10, 0), (20, 0), (20, 30), (10, 30), (10, 20), (0, 20), (0, 10), (10, 10), (10,0));
}
=> PolygonFactory.CreatePointArray(
(10, 0),
(20, 0),
(20, 30),
(10, 30),
(10, 20),
(0, 20),
(0, 10),
(10, 10),
(10, 0));
[Theory]
[InlineData(true)]
@ -27,13 +33,12 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Shapes.Scan
{
polygon.AsSpan().Reverse();
}
TopologyUtilities.EnsureOrientation(polygon, 1);
Assert.Equal(expected, polygon);
}
[Theory]
[InlineData(true)]
[InlineData(false)]
@ -41,17 +46,17 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Shapes.Scan
{
PointF[] expected = CreateTestPoints();
expected.AsSpan().Reverse();
PointF[] polygon = expected.CloneArray();
if (!isNegative)
{
polygon.AsSpan().Reverse();
}
TopologyUtilities.EnsureOrientation(polygon, -1);
Assert.Equal(expected, polygon);
}
}
}
}

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

@ -4,7 +4,6 @@
using System;
using System.Collections.Concurrent;
using System.IO;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.PixelFormats;
@ -26,7 +25,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests
/// The "Formats" directory, as lazy value
/// </summary>
// ReSharper disable once InconsistentNaming
private static readonly Lazy<string> inputImagesDirectory = new Lazy<string>(() => TestEnvironment.InputImagesDirectoryFullPath);
private static readonly Lazy<string> LazyInputImagesDirectory = new Lazy<string>(() => TestEnvironment.InputImagesDirectoryFullPath);
/// <summary>
/// The image (lazy initialized value)
@ -43,53 +42,47 @@ namespace SixLabors.ImageSharp.Drawing.Tests
/// </summary>
/// <param name="file">The file.</param>
private TestFile(string file)
{
this.FullPath = file;
}
=> this.FullPath = file;
/// <summary>
/// Gets the image bytes.
/// </summary>
public byte[] Bytes => this.bytes ?? (this.bytes = File.ReadAllBytes(this.FullPath));
public byte[] Bytes => this.bytes ??= File.ReadAllBytes(this.FullPath);
/// <summary>
/// The full path to file.
/// Gets the full path to file.
/// </summary>
public string FullPath { get; }
/// <summary>
/// The file name.
/// Gets the file name.
/// </summary>
public string FileName => IOPath.GetFileName(this.FullPath);
/// <summary>
/// The file name without extension.
/// Gets the file name without extension.
/// </summary>
public string FileNameWithoutExtension => IOPath.GetFileNameWithoutExtension(this.FullPath);
/// <summary>
/// Gets the image with lazy initialization.
/// </summary>
private Image<Rgba32> Image => this.image ?? (this.image = ImageSharp.Image.Load<Rgba32>(this.Bytes));
private Image<Rgba32> Image => this.image ??= ImageSharp.Image.Load<Rgba32>(this.Bytes);
/// <summary>
/// Gets the input image directory.
/// </summary>
private static string InputImagesDirectory => inputImagesDirectory.Value;
private static string InputImagesDirectory => LazyInputImagesDirectory.Value;
/// <summary>
/// Gets the full qualified path to the input test file.
/// </summary>
/// <param name="file">
/// The file path.
/// </param>
/// <param name="file">The file path.</param>
/// <returns>
/// The <see cref="string"/>.
/// </returns>
public static string GetInputFileFullPath(string file)
{
return IOPath.Combine(InputImagesDirectory, file).Replace('\\', IOPath.DirectorySeparatorChar);
}
=> IOPath.Combine(InputImagesDirectory, file).Replace('\\', IOPath.DirectorySeparatorChar);
/// <summary>
/// Creates a new test file or returns one from the cache.
@ -99,9 +92,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests
/// The <see cref="TestFile"/>.
/// </returns>
public static TestFile Create(string file)
{
return Cache.GetOrAdd(file, (string fileName) => new TestFile(GetInputFileFullPath(file)));
}
=> Cache.GetOrAdd(file, (string fileName) => new TestFile(GetInputFileFullPath(file)));
/// <summary>
/// Gets the file name.
@ -111,9 +102,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests
/// The <see cref="string"/>.
/// </returns>
public string GetFileName(object value)
{
return $"{this.FileNameWithoutExtension}-{value}{IOPath.GetExtension(this.FullPath)}";
}
=> $"{this.FileNameWithoutExtension}-{value}{IOPath.GetExtension(this.FullPath)}";
/// <summary>
/// Gets the file name without extension.
@ -123,9 +112,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests
/// The <see cref="string"/>.
/// </returns>
public string GetFileNameWithoutExtension(object value)
{
return this.FileNameWithoutExtension + "-" + value;
}
=> this.FileNameWithoutExtension + "-" + value;
/// <summary>
/// Creates a new image.
@ -133,10 +120,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests
/// <returns>
/// The <see cref="ImageSharp.Image"/>.
/// </returns>
public Image<Rgba32> CreateRgba32Image()
{
return this.Image.Clone();
}
public Image<Rgba32> CreateRgba32Image() => this.Image.Clone();
/// <summary>
/// Creates a new image.
@ -145,8 +129,6 @@ namespace SixLabors.ImageSharp.Drawing.Tests
/// The <see cref="ImageSharp.Image"/>.
/// </returns>
public Image<Rgba32> CreateRgba32Image(IImageDecoder decoder)
{
return ImageSharp.Image.Load<Rgba32>(this.Image.GetConfiguration(), this.Bytes, decoder);
}
=> ImageSharp.Image.Load<Rgba32>(this.Image.GetConfiguration(), this.Bytes, decoder);
}
}

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

@ -28,10 +28,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests
/// <returns>
/// The <see cref="string"/>.
/// </returns>
public static string GetPath(string file)
{
return IOPath.Combine(FormatsDirectory, file);
}
public static string GetPath(string file) => IOPath.Combine(FormatsDirectory, file);
/// <summary>
/// Gets the correct path to the formats directory.
@ -41,7 +38,8 @@ namespace SixLabors.ImageSharp.Drawing.Tests
/// </returns>
private static string GetFontsDirectory()
{
var directories = new List<string> {
var directories = new List<string>
{
"TestFonts/", // Here for code coverage tests.
"tests/ImageSharp.Drawing.Tests/TestFonts/", // from travis/build script
"../../../../../ImageSharp.Drawing.Tests/TestFonts/", // from Sandbox46

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

@ -38,7 +38,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests
public IImageDecoder Decoder { get; }
private byte[] header = Guid.NewGuid().ToByteArray();
private readonly byte[] header = Guid.NewGuid().ToByteArray();
public MemoryStream CreateStream(byte[] marker = null)
{
@ -49,6 +49,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests
{
ms.Write(marker, 0, marker.Length);
}
ms.Position = 0;
return ms;
}
@ -58,7 +59,6 @@ namespace SixLabors.ImageSharp.Drawing.Tests
{
DecodeOperation[] discovered = this.DecodeCalls.Where(x => x.IsMatch(marker, config, typeof(TPixel))).ToArray();
Assert.True(discovered.Any(), "No calls to decode on this format with the provided options happened");
foreach (DecodeOperation d in discovered)
@ -71,7 +71,6 @@ namespace SixLabors.ImageSharp.Drawing.Tests
{
DecodeOperation[] discovered = this.DecodeCalls.Where(x => x.IsMatch(marker, config, typeof(TestPixelForAgnosticDecode))).ToArray();
Assert.True(discovered.Any(), "No calls to decode on this format with the provided options happened");
foreach (DecodeOperation d in discovered)
@ -118,6 +117,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests
{
return false;
}
for (int i = 0; i < this.header.Length; i++)
{
if (header[i] != this.header[i])
@ -125,6 +125,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests
return false;
}
}
return true;
}
@ -137,156 +138,186 @@ namespace SixLabors.ImageSharp.Drawing.Tests
public struct DecodeOperation
{
public byte[] marker;
internal Configuration config;
public byte[] Marker { get; set; }
public Type pixelType;
internal Configuration Config { get; set; }
public Type PixelType { get; set; }
public bool IsMatch(byte[] testMarker, Configuration config, Type pixelType)
{
if (this.config != config || this.pixelType != pixelType)
if (this.Config != config || this.PixelType != pixelType)
{
return false;
}
if (testMarker.Length != this.marker.Length)
if (testMarker.Length != this.Marker.Length)
{
return false;
}
for (int i = 0; i < this.marker.Length; i++)
for (int i = 0; i < this.Marker.Length; i++)
{
if (testMarker[i] != this.marker[i])
if (testMarker[i] != this.Marker[i])
{
return false;
}
}
return true;
}
}
public class TestHeader : IImageFormatDetector
{
private readonly TestFormat testFormat;
private TestFormat testFormat;
public TestHeader(TestFormat testFormat) => this.testFormat = testFormat;
public int HeaderSize => this.testFormat.HeaderSize;
public IImageFormat DetectFormat(ReadOnlySpan<byte> header)
{
if (this.testFormat.IsSupportedFileFormat(header))
{
return this.testFormat;
}
return null;
}
public TestHeader(TestFormat testFormat)
{
this.testFormat = testFormat;
}
}
public class TestDecoder : IImageDecoder
{
private TestFormat testFormat;
private readonly TestFormat testFormat;
public TestDecoder(TestFormat testFormat)
{
this.testFormat = testFormat;
}
public TestDecoder(TestFormat testFormat) => this.testFormat = testFormat;
public IEnumerable<string> MimeTypes => new[] { testFormat.MimeType };
public IEnumerable<string> MimeTypes => new[] { this.testFormat.MimeType };
public IEnumerable<string> FileExtensions => testFormat.SupportedExtensions;
public IEnumerable<string> FileExtensions => this.testFormat.SupportedExtensions;
public int HeaderSize => testFormat.HeaderSize;
public Image<TPixel> Decode<TPixel>(Configuration config, Stream stream) where TPixel : unmanaged, IPixel<TPixel>
public int HeaderSize => this.testFormat.HeaderSize;
public Image<TPixel> Decode<TPixel>(Configuration config, Stream stream)
where TPixel : unmanaged, IPixel<TPixel>
{
var ms = new MemoryStream();
stream.CopyTo(ms);
var marker = ms.ToArray().Skip(this.testFormat.header.Length).ToArray();
byte[] marker = ms.ToArray().Skip(this.testFormat.header.Length).ToArray();
this.testFormat.DecodeCalls.Add(new DecodeOperation
{
marker = marker,
config = config,
pixelType = typeof(TPixel)
Marker = marker,
Config = config,
PixelType = typeof(TPixel)
});
// TODO record this happened so we can verify it.
return this.testFormat.Sample<TPixel>();
}
public bool IsSupportedFileFormat(Span<byte> header) => testFormat.IsSupportedFileFormat(header);
public bool IsSupportedFileFormat(Span<byte> header) => this.testFormat.IsSupportedFileFormat(header);
public Image Decode(Configuration configuration, Stream stream) => this.Decode<TestPixelForAgnosticDecode>(configuration, stream);
public Task<Image<TPixel>> DecodeAsync<TPixel>(Configuration configuration, Stream stream, CancellationToken cancellationToken) where TPixel : unmanaged, IPixel<TPixel>
{
throw new NotImplementedException();
}
public Task<Image<TPixel>> DecodeAsync<TPixel>(Configuration configuration, Stream stream, CancellationToken cancellationToken)
where TPixel : unmanaged, IPixel<TPixel>
=> throw new NotImplementedException();
public Task<Image> DecodeAsync(Configuration configuration, Stream stream, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public Task<Image<TPixel>> DecodeAsync<TPixel>(Configuration configuration, Stream stream)
where TPixel : unmanaged, IPixel<TPixel>
=> throw new NotImplementedException();
public Task<Image> DecodeAsync(Configuration configuration, Stream stream)
=> throw new NotImplementedException();
=> throw new NotImplementedException();
}
public class TestEncoder : IImageEncoder
{
private TestFormat testFormat;
private readonly TestFormat testFormat;
public TestEncoder(TestFormat testFormat)
{
this.testFormat = testFormat;
}
=> this.testFormat = testFormat;
public IEnumerable<string> MimeTypes => new[] { testFormat.MimeType };
public IEnumerable<string> MimeTypes => new[] { this.testFormat.MimeType };
public IEnumerable<string> FileExtensions => testFormat.SupportedExtensions;
public IEnumerable<string> FileExtensions => this.testFormat.SupportedExtensions;
public void Encode<TPixel>(Image<TPixel> image, Stream stream) where TPixel : unmanaged, IPixel<TPixel>
public void Encode<TPixel>(Image<TPixel> image, Stream stream)
where TPixel : unmanaged, IPixel<TPixel>
{
// TODO record this happened so we can verify it.
}
public Task EncodeAsync<TPixel>(Image<TPixel> image, Stream stream, CancellationToken cancellationToken) where TPixel : unmanaged, IPixel<TPixel>
{
throw new NotImplementedException();
}
public Task EncodeAsync<TPixel>(Image<TPixel> image, Stream stream) where TPixel : unmanaged, IPixel<TPixel>
=> throw new NotImplementedException();
public Task EncodeAsync<TPixel>(Image<TPixel> image, Stream stream, CancellationToken cancellationToken)
where TPixel : unmanaged, IPixel<TPixel>
=> throw new NotImplementedException();
}
struct TestPixelForAgnosticDecode : IPixel<TestPixelForAgnosticDecode>
private struct TestPixelForAgnosticDecode : IPixel<TestPixelForAgnosticDecode>
{
public PixelOperations<TestPixelForAgnosticDecode> CreatePixelOperations() => new PixelOperations<TestPixelForAgnosticDecode>();
public void FromScaledVector4(Vector4 vector) { }
public void FromScaledVector4(Vector4 vector)
{
}
public Vector4 ToScaledVector4() => default;
public void FromVector4(Vector4 vector) { }
public void FromVector4(Vector4 vector)
{
}
public Vector4 ToVector4() => default;
public void FromArgb32(Argb32 source) { }
public void FromBgra5551(Bgra5551 source) { }
public void FromBgr24(Bgr24 source) { }
public void FromBgra32(Bgra32 source) { }
public void FromL8(L8 source) { }
public void FromL16(L16 source) { }
public void FromLa16(La16 source) { }
public void FromLa32(La32 source) { }
public void FromRgb24(Rgb24 source) { }
public void FromRgba32(Rgba32 source) { }
public void ToRgba32(ref Rgba32 dest) { }
public void FromRgb48(Rgb48 source) { }
public void FromRgba64(Rgba64 source) { }
public void FromArgb32(Argb32 source)
{
}
public void FromBgra5551(Bgra5551 source)
{
}
public void FromBgr24(Bgr24 source)
{
}
public void FromBgra32(Bgra32 source)
{
}
public void FromL8(L8 source)
{
}
public void FromL16(L16 source)
{
}
public void FromLa16(La16 source)
{
}
public void FromLa32(La32 source)
{
}
public void FromRgb24(Rgb24 source)
{
}
public void FromRgba32(Rgba32 source)
{
}
public void ToRgba32(ref Rgba32 dest)
{
}
public void FromRgb48(Rgb48 source)
{
}
public void FromRgba64(Rgba64 source)
{
}
public bool Equals(TestPixelForAgnosticDecode other) => false;
}
}

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

@ -2,14 +2,14 @@
// Licensed under the Apache License, Version 2.0.
using System.Linq;
// ReSharper disable InconsistentNaming
// ReSharper disable InconsistentNaming
// ReSharper disable MemberHidesStaticFromOuterClass
namespace SixLabors.ImageSharp.Drawing.Tests
{
/// <summary>
/// Class that contains all the relative test image paths in the TestImages/Formats directory.
/// Use with <see cref="WithFileAttribute"/>, <see cref="WithFileCollectionAttribute"/> or <see cref="FileTestBase"/>.
/// Use with <see cref="WithFileAttribute"/>, <see cref="WithFileCollectionAttribute"/>.
/// </summary>
public static class TestImages
{
@ -310,42 +310,42 @@ namespace SixLabors.ImageSharp.Drawing.Tests
public const string Rgba321010102 = "Bmp/rgba32-1010102.bmp";
public const string RgbaAlphaBitfields = "Bmp/rgba32abf.bmp";
public static readonly string[] BitFields
= {
Rgb32bfdef,
Rgb32bf,
Rgb16565,
Rgb16bfdef,
Rgb16565pal,
Issue735,
public static readonly string[] BitFields =
{
Rgb32bfdef,
Rgb32bf,
Rgb16565,
Rgb16bfdef,
Rgb16565pal,
Issue735,
};
public static readonly string[] Miscellaneous
= {
public static readonly string[] Miscellaneous =
{
Car,
F,
NegHeight
};
public static readonly string[] Benchmark
= {
Car,
F,
NegHeight,
CoreHeader,
V5Header,
RLE4,
RLE8,
RLE8Inverted,
Bit1,
Bit1Pal1,
Bit4,
Bit8,
Bit8Inverted,
Bit16,
Bit16Inverted,
Bit32Rgb
};
public static readonly string[] Benchmark =
{
Car,
F,
NegHeight,
CoreHeader,
V5Header,
RLE4,
RLE8,
RLE8Inverted,
Bit1,
Bit1Pal1,
Bit4,
Bit8,
Bit8Inverted,
Bit16,
Bit16Inverted,
Bit32Rgb
};
}
public static class Gif

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

@ -15,20 +15,20 @@ namespace SixLabors.ImageSharp.Drawing.Tests
IEqualityComparer<Vector4>,
IEqualityComparer<ColorMatrix>
{
private readonly float Epsilon;
private readonly float epsilon;
/// <summary>
/// Initializes a new instance of the <see cref="ApproximateFloatComparer"/> class.
/// </summary>
/// <param name="epsilon">The comparison error difference epsilon to use.</param>
public ApproximateFloatComparer(float epsilon = 1F) => this.Epsilon = epsilon;
public ApproximateFloatComparer(float epsilon = 1F) => this.epsilon = epsilon;
/// <inheritdoc/>
public bool Equals(float x, float y)
{
float d = x - y;
return d >= -this.Epsilon && d <= this.Epsilon;
return d >= -this.epsilon && d <= this.epsilon;
}
/// <inheritdoc/>
@ -48,14 +48,11 @@ namespace SixLabors.ImageSharp.Drawing.Tests
/// <inheritdoc/>
public bool Equals(ColorMatrix x, ColorMatrix y)
{
return
this.Equals(x.M11, y.M11) && this.Equals(x.M12, y.M12) && this.Equals(x.M13, y.M13) && this.Equals(x.M14, y.M14)
=> this.Equals(x.M11, y.M11) && this.Equals(x.M12, y.M12) && this.Equals(x.M13, y.M13) && this.Equals(x.M14, y.M14)
&& this.Equals(x.M21, y.M21) && this.Equals(x.M22, y.M22) && this.Equals(x.M23, y.M23) && this.Equals(x.M24, y.M24)
&& this.Equals(x.M31, y.M31) && this.Equals(x.M32, y.M32) && this.Equals(x.M33, y.M33) && this.Equals(x.M34, y.M34)
&& this.Equals(x.M41, y.M41) && this.Equals(x.M42, y.M42) && this.Equals(x.M43, y.M43) && this.Equals(x.M44, y.M44)
&& this.Equals(x.M51, y.M51) && this.Equals(x.M52, y.M52) && this.Equals(x.M53, y.M53) && this.Equals(x.M54, y.M54);
}
/// <inheritdoc/>
public int GetHashCode(ColorMatrix obj) => obj.GetHashCode();

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

@ -1,4 +1,7 @@
namespace SixLabors.ImageSharp.Drawing.Tests
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
namespace SixLabors.ImageSharp.Drawing.Tests
{
using System;

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

@ -14,16 +14,9 @@ namespace SixLabors.ImageSharp.Drawing.Tests
/// </summary>
public abstract class ImageDataAttributeBase : DataAttribute
{
protected readonly object[] AdditionalParameters;
protected readonly PixelTypes PixelTypes;
/// <summary>
/// Initializes a new instance of the <see cref="ImageDataAttributeBase"/> class.
/// </summary>
/// <param name="memberName"></param>
/// <param name="pixelTypes"></param>
/// <param name="additionalParameters"></param>
protected ImageDataAttributeBase(string memberName, PixelTypes pixelTypes, object[] additionalParameters)
{
this.PixelTypes = pixelTypes;
@ -37,10 +30,14 @@ namespace SixLabors.ImageSharp.Drawing.Tests
public string MemberName { get; }
/// <summary>
/// Gets the member type
/// Gets or sets the member type
/// </summary>
public Type MemberType { get; set; }
protected object[] AdditionalParameters { get; }
protected PixelTypes PixelTypes { get; }
/// <summary>Returns the data to be used to test theory.</summary>
/// <param name="testMethod">The method that is being tested</param>
/// <returns>One or more sets of theory data. Each invocation of the test method
@ -84,8 +81,6 @@ namespace SixLabors.ImageSharp.Drawing.Tests
/// <summary>
/// Returns a value indicating whether the first parameter of the method is a test provider.
/// </summary>
/// <param name="testMethod"></param>
/// <returns></returns>
private bool FirstIsProvider(MethodInfo testMethod)
{
TypeInfo dataType = testMethod.GetParameters().First().ParameterType.GetTypeInfo();
@ -102,7 +97,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests
{
foreach (object[] row in memberData)
{
var actualFactoryMethodArgs = new object[originalFactoryMethodArgs.Length + 2];
object[] actualFactoryMethodArgs = new object[originalFactoryMethodArgs.Length + 2];
Array.Copy(originalFactoryMethodArgs, actualFactoryMethodArgs, originalFactoryMethodArgs.Length);
actualFactoryMethodArgs[actualFactoryMethodArgs.Length - 2] = testMethod;
actualFactoryMethodArgs[actualFactoryMethodArgs.Length - 1] = kv.Key;
@ -110,7 +105,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests
object factory = factoryType.GetMethod(this.GetFactoryMethodName(testMethod))
.Invoke(null, actualFactoryMethodArgs);
var result = new object[this.AdditionalParameters.Length + 1 + row.Length];
object[] result = new object[this.AdditionalParameters.Length + 1 + row.Length];
result[0] = factory;
Array.Copy(row, 0, result, 1, row.Length);
Array.Copy(this.AdditionalParameters, 0, result, 1 + row.Length, this.AdditionalParameters.Length);
@ -139,9 +134,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests
/// <param name="factoryType">The test image provider factory type</param>
/// <returns>The <see cref="T:object[]"/></returns>
protected virtual object[] GetFactoryMethodArgs(MethodInfo testMethod, Type factoryType)
{
throw new InvalidOperationException("Semi-abstract method");
}
=> throw new InvalidOperationException("Semi-abstract method");
/// <summary>
/// Generates the method name from the given test method.
@ -153,6 +146,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests
/// <summary>
/// Gets the field accessor for the given type.
/// </summary>
/// <returns>The <see cref="Func{out TResult}"/>.</returns>
protected Func<object> GetFieldAccessor(Type type, string memberName)
{
FieldInfo fieldInfo = null;
@ -160,11 +154,15 @@ namespace SixLabors.ImageSharp.Drawing.Tests
{
fieldInfo = reflectionType.GetRuntimeField(memberName);
if (fieldInfo != null)
{
break;
}
}
if (fieldInfo == null || !fieldInfo.IsStatic)
{
return null;
}
return () => fieldInfo.GetValue(null);
}
@ -172,6 +170,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests
/// <summary>
/// Gets the property accessor for the given type.
/// </summary>
/// <returns>The <see cref="Func{out TResult}"/>.</returns>
protected Func<object> GetPropertyAccessor(Type type, string memberName)
{
PropertyInfo propInfo = null;

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

@ -1,3 +1,6 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
@ -19,7 +22,8 @@ namespace SixLabors.ImageSharp.Drawing.Tests.TestUtilities.Attributes
public class WindowsFactAttribute : PlatformFactAttribute
{
public WindowsFactAttribute() : base(OSPlatform.Windows)
public WindowsFactAttribute()
: base(OSPlatform.Windows)
{
}
}

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

@ -1,4 +1,4 @@
// Copyright (c) Six Labors.
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System;
@ -10,7 +10,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests
/// Triggers passing <see cref="TestImageProvider{TPixel}"/> instances which produce a blank image of size width * height.
/// One <see cref="TestImageProvider{TPixel}"/> instance will be passed for each the pixel format defined by the pixelTypes parameter
/// </summary>
public class WithBlankImagesAttribute : ImageDataAttributeBase
public class WithBlankImageAttribute : ImageDataAttributeBase
{
/// <summary>
/// Triggers passing an <see cref="TestImageProvider{TPixel}"/> that produces a blank image of size width * height
@ -19,7 +19,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests
/// <param name="height">The required height</param>
/// <param name="pixelTypes">The requested parameter</param>
/// <param name="additionalParameters">Additional theory parameter values</param>
public WithBlankImagesAttribute(int width, int height, PixelTypes pixelTypes, params object[] additionalParameters)
public WithBlankImageAttribute(int width, int height, PixelTypes pixelTypes, params object[] additionalParameters)
: base(null, pixelTypes, additionalParameters)
{
this.Width = width;
@ -34,7 +34,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests
/// <param name="height">The required height</param>
/// <param name="pixelTypes">The requested parameter</param>
/// <param name="additionalParameters">Additional theory parameter values</param>
public WithBlankImagesAttribute(string memberData, int width, int height, PixelTypes pixelTypes, params object[] additionalParameters)
public WithBlankImageAttribute(string memberData, int width, int height, PixelTypes pixelTypes, params object[] additionalParameters)
: base(memberData, pixelTypes, additionalParameters)
{
this.Width = width;
@ -42,10 +42,11 @@ namespace SixLabors.ImageSharp.Drawing.Tests
}
public int Width { get; }
public int Height { get; }
protected override string GetFactoryMethodName(MethodInfo testMethod) => "Blank";
protected override object[] GetFactoryMethodArgs(MethodInfo testMethod, Type factoryType) => new object[] { this.Width, this.Height };
}
}
}

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

@ -12,7 +12,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests
/// Triggers passing <see cref="TestImageProvider{TPixel}"/> instances which produce an image of size width * height filled with the requested color.
/// One <see cref="TestImageProvider{TPixel}"/> instance will be passed for each the pixel format defined by the pixelTypes parameter
/// </summary>
public class WithSolidFilledImagesAttribute : WithBlankImagesAttribute
public class WithSolidFilledImagesAttribute : WithBlankImageAttribute
{
/// <summary>
/// Triggers passing <see cref="TestImageProvider{TPixel}"/> instances which produce an image of size width * height filled with the requested color.

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

@ -1,4 +1,4 @@
// Copyright (c) Six Labors.
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System;
@ -10,7 +10,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests
/// Triggers passing <see cref="TestImageProvider{TPixel}"/> instances which produce a blank image of size width * height.
/// One <see cref="TestImageProvider{TPixel}"/> instance will be passed for each the pixel format defined by the pixelTypes parameter
/// </summary>
public class WithTestPatternImagesAttribute : ImageDataAttributeBase
public class WithTestPatternImageAttribute : ImageDataAttributeBase
{
/// <summary>
/// Triggers passing an <see cref="TestImageProvider{TPixel}"/> that produces a test pattern image of size width * height
@ -19,7 +19,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests
/// <param name="height">The required height</param>
/// <param name="pixelTypes">The requested parameter</param>
/// <param name="additionalParameters">Additional theory parameter values</param>
public WithTestPatternImagesAttribute(int width, int height, PixelTypes pixelTypes, params object[] additionalParameters)
public WithTestPatternImageAttribute(int width, int height, PixelTypes pixelTypes, params object[] additionalParameters)
: this(null, width, height, pixelTypes, additionalParameters)
{
}
@ -32,7 +32,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests
/// <param name="height">The required height</param>
/// <param name="pixelTypes">The requested parameter</param>
/// <param name="additionalParameters">Additional theory parameter values</param>
public WithTestPatternImagesAttribute(string memberData, int width, int height, PixelTypes pixelTypes, params object[] additionalParameters)
public WithTestPatternImageAttribute(string memberData, int width, int height, PixelTypes pixelTypes, params object[] additionalParameters)
: base(memberData, pixelTypes, additionalParameters)
{
this.Width = width;
@ -53,4 +53,4 @@ namespace SixLabors.ImageSharp.Drawing.Tests
protected override object[] GetFactoryMethodArgs(MethodInfo testMethod, Type factoryType) => new object[] { this.Width, this.Height };
}
}
}

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

@ -18,11 +18,9 @@ namespace SixLabors.ImageSharp.Drawing.Tests
private readonly string outputDir;
public DebugDraw(string outputDir)
{
this.outputDir = outputDir;
}
=> this.outputDir = outputDir;
public void Polygon(IPath path, float gridSize = 10f, float scale = 10f, [CallerMemberName]string testMethod = "")
public void Polygon(IPath path, float gridSize = 10f, float scale = 10f, [CallerMemberName] string testMethod = "")
{
if (TestEnvironment.RunsOnCI)
{
@ -33,7 +31,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests
RectangleF bounds = path.Bounds;
gridSize *= scale;
using Image img = new Image<Rgba32>((int)(bounds.Right + 2 * gridSize), (int)(bounds.Bottom + 2 * gridSize));
using Image img = new Image<Rgba32>((int)(bounds.Right + (2 * gridSize)), (int)(bounds.Bottom + (2 * gridSize)));
img.Mutate(ctx => DrawGrid(ctx.Fill(TestBrush, path), bounds, gridSize));
string outDir = TestEnvironment.CreateOutputDirectory(this.outputDir);
@ -47,13 +45,13 @@ namespace SixLabors.ImageSharp.Drawing.Tests
{
for (float x = rect.Left; x <= rect.Right; x += gridSize)
{
PointF[] line = {P(x, rect.Top), P(x, rect.Bottom)};
PointF[] line = { P(x, rect.Top), P(x, rect.Bottom) };
ctx.DrawLines(GridPen, line);
}
for (float y = rect.Top; y <= rect.Bottom; y += gridSize)
{
PointF[] line = {P(rect.Left, y), P(rect.Right, y)};
PointF[] line = { P(rect.Left, y), P(rect.Right, y) };
ctx.DrawLines(GridPen, line);
}
}

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

@ -12,13 +12,13 @@ namespace SixLabors.ImageSharp.Drawing.Tests.TestUtilities
public struct FuzzyFloat : IEquatable<float>, IXunitSerializable
{
public static readonly float DefaultEpsilon = 1e-5f;
private float value;
private float min;
private float max;
private float eps;
public FuzzyFloat(float value)
public FuzzyFloat(float value)
: this(value, DefaultEpsilon)
{
}
@ -31,32 +31,34 @@ namespace SixLabors.ImageSharp.Drawing.Tests.TestUtilities
this.max = value + eps;
}
public static implicit operator float(FuzzyFloat x) => x.value;
public static implicit operator float(FuzzyFloat x) => x.value;
public static implicit operator FuzzyFloat(float x) => new FuzzyFloat(x);
public static implicit operator FuzzyFloat(int x) => new FuzzyFloat(x);
public static implicit operator FuzzyFloat(double x) => new FuzzyFloat((float)x);
public bool Equals(float x) => x >= this.min && x <= this.max;
public override string ToString() => $"{value}±{eps}";
public override string ToString() => $"{this.value}±{this.eps}";
public void Serialize(IXunitSerializationInfo info)
{
info.AddValue(nameof(value), this.value);
info.AddValue(nameof(eps), this.eps);
info.AddValue(nameof(this.value), this.value);
info.AddValue(nameof(this.eps), this.eps);
}
public void Deserialize(IXunitSerializationInfo info)
{
this.value = info.GetValue<float>(nameof(value));
this.eps = info.GetValue<float>(nameof(eps));
this.min = value - eps;
this.max = value + eps;
this.value = info.GetValue<float>(nameof(this.value));
this.eps = info.GetValue<float>(nameof(this.eps));
this.min = this.value - this.eps;
this.max = this.value + this.eps;
}
public static FuzzyFloat operator+(FuzzyFloat a, float b) => new FuzzyFloat(a.value + b, a.eps);
public static FuzzyFloat operator-(FuzzyFloat a, float b) => new FuzzyFloat(a.value - b, a.eps);
public static FuzzyFloat operator +(FuzzyFloat a, float b) => new FuzzyFloat(a.value + b, a.eps);
public static FuzzyFloat operator -(FuzzyFloat a, float b) => new FuzzyFloat(a.value - b, a.eps);
}
}
}

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

@ -9,6 +9,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.TestUtilities
public class GraphicsOptionsComparer : IEqualityComparer<GraphicsOptions>
{
public bool SkipClearOptions { get; set; } = false;
public bool Equals(GraphicsOptions x, GraphicsOptions y)
{
if (this.SkipClearOptions)
@ -26,5 +27,4 @@ namespace SixLabors.ImageSharp.Drawing.Tests.TestUtilities
public int GetHashCode(GraphicsOptions obj) => obj.GetHashCode();
}
}

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

@ -1,3 +1,6 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Collections.Generic;
using SixLabors.ImageSharp.Advanced;
@ -21,7 +24,6 @@ namespace SixLabors.ImageSharp.Drawing.Tests.TestUtilities.ImageComparison
int width = actual.Width;
// TODO: Comparing through Rgba64 may not be robust enough because of the existence of super high precision pixel types.
var aBuffer = new Rgba64[width];
var bBuffer = new Rgba64[width];

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

@ -1,3 +1,6 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Collections.Generic;
using System.Linq;
@ -11,9 +14,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.TestUtilities.ImageComparison
public ImageDifferenceIsOverThresholdException(IEnumerable<ImageSimilarityReport> reports)
: base("Image difference is over threshold!" + StringifyReports(reports))
{
this.Reports = reports.ToArray();
}
=> this.Reports = reports.ToArray();
private static string StringifyReports(IEnumerable<ImageSimilarityReport> reports)
{
@ -29,7 +30,8 @@ namespace SixLabors.ImageSharp.Drawing.Tests.TestUtilities.ImageComparison
sb.Append(Environment.NewLine);
i++;
}
return sb.ToString();
}
}
}
}

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

@ -13,6 +13,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.TestUtilities.ImageComparison
}
public Size ExpectedSize { get; }
public Size ActualSize { get; }
}
}

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

@ -1,7 +1,10 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System;
namespace SixLabors.ImageSharp.Drawing.Tests.TestUtilities.ImageComparison
{
using System;
public class ImagesSimilarityException : Exception
{
public ImagesSimilarityException(string message)
@ -9,4 +12,4 @@ namespace SixLabors.ImageSharp.Drawing.Tests.TestUtilities.ImageComparison
{
}
}
}
}

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

@ -16,23 +16,24 @@ namespace SixLabors.ImageSharp.Drawing.Tests.TestUtilities.ImageComparison
/// Returns an instance of <see cref="TolerantImageComparer"/>.
/// Individual manhattan pixel difference is only added to total image difference when the individual difference is over 'perPixelManhattanThreshold'.
/// </summary>
/// <returns>The <see cref="ImageComparer"/>.</returns>
public static ImageComparer Tolerant(
float imageThreshold = TolerantImageComparer.DefaultImageThreshold,
int perPixelManhattanThreshold = 0)
{
return new TolerantImageComparer(imageThreshold, perPixelManhattanThreshold);
}
=> new TolerantImageComparer(imageThreshold, perPixelManhattanThreshold);
/// <summary>
/// Returns Tolerant(imageThresholdInPercents/100)
/// </summary>
/// <returns>The <see cref="ImageComparer"/>.</returns>
public static ImageComparer TolerantPercentage(float imageThresholdInPercents, int perPixelManhattanThreshold = 0)
=> Tolerant(imageThresholdInPercents / 100F, perPixelManhattanThreshold);
public abstract ImageSimilarityReport<TPixelA, TPixelB> CompareImagesOrFrames<TPixelA, TPixelB>(
ImageFrame<TPixelA> expected,
ImageFrame<TPixelB> actual)
where TPixelA : unmanaged, IPixel<TPixelA> where TPixelB : unmanaged, IPixel<TPixelB>;
where TPixelA : unmanaged, IPixel<TPixelA>
where TPixelB : unmanaged, IPixel<TPixelB>;
}
public static class ImageComparerExtensions
@ -41,16 +42,16 @@ namespace SixLabors.ImageSharp.Drawing.Tests.TestUtilities.ImageComparison
this ImageComparer comparer,
Image<TPixelA> expected,
Image<TPixelB> actual)
where TPixelA : unmanaged, IPixel<TPixelA> where TPixelB : unmanaged, IPixel<TPixelB>
{
return comparer.CompareImagesOrFrames(expected.Frames.RootFrame, actual.Frames.RootFrame);
}
where TPixelA : unmanaged, IPixel<TPixelA>
where TPixelB : unmanaged, IPixel<TPixelB>
=> comparer.CompareImagesOrFrames(expected.Frames.RootFrame, actual.Frames.RootFrame);
public static IEnumerable<ImageSimilarityReport<TPixelA, TPixelB>> CompareImages<TPixelA, TPixelB>(
this ImageComparer comparer,
Image<TPixelA> expected,
Image<TPixelB> actual)
where TPixelA : unmanaged, IPixel<TPixelA> where TPixelB : unmanaged, IPixel<TPixelB>
where TPixelA : unmanaged, IPixel<TPixelA>
where TPixelB : unmanaged, IPixel<TPixelB>
{
var result = new List<ImageSimilarityReport<TPixelA, TPixelB>>();
@ -58,6 +59,7 @@ namespace SixLabors.ImageSharp.Drawing.Tests.TestUtilities.ImageComparison
{
throw new Exception("Frame count does not match!");
}
for (int i = 0; i < expected.Frames.Count; i++)
{
ImageSimilarityReport<TPixelA, TPixelB> report = comparer.CompareImagesOrFrames(expected.Frames[i], actual.Frames[i]);
@ -74,7 +76,8 @@ namespace SixLabors.ImageSharp.Drawing.Tests.TestUtilities.ImageComparison
this ImageComparer comparer,
Image<TPixelA> expected,
Image<TPixelB> actual)
where TPixelA : unmanaged, IPixel<TPixelA> where TPixelB : unmanaged, IPixel<TPixelB>
where TPixelA : unmanaged, IPixel<TPixelA>
where TPixelB : unmanaged, IPixel<TPixelB>
{
if (expected.Size() != actual.Size())
{

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше