@ -1,20 +1,373 @@ |
|||||
# top-most EditorConfig file |
############################################################################### |
||||
|
# EditorConfig is awesome: http://EditorConfig.org |
||||
|
############################################################################### |
||||
|
|
||||
|
############################################################################### |
||||
|
# Top-most EditorConfig file |
||||
|
############################################################################### |
||||
root = true |
root = true |
||||
|
|
||||
[*.cs] |
############################################################################### |
||||
|
# Set default behavior to: |
||||
|
# a UTF-8 encoding, |
||||
|
# Unix-style line endings, |
||||
|
# a newline ending the file, |
||||
|
# 4 space indentation, and |
||||
|
# trimming of trailing whitespace |
||||
|
############################################################################### |
||||
|
[*] |
||||
|
charset = utf-8 |
||||
|
end_of_line = lf |
||||
|
insert_final_newline = true |
||||
indent_style = space |
indent_style = space |
||||
indent_size = 4 |
indent_size = 4 |
||||
csharp_style_var_for_built_in_types = false:warning |
trim_trailing_whitespace = true |
||||
csharp_style_var_elsewhere = false:warning |
|
||||
csharp_style_var_when_type_is_apparent = true:warning |
############################################################################### |
||||
|
# Set file behavior to: |
||||
|
# 2 space indentation |
||||
|
############################################################################### |
||||
|
[*.{cmd,config,csproj,json,props,ps1,resx,sh,targets}] |
||||
|
indent_size = 2 |
||||
|
|
||||
|
############################################################################### |
||||
|
# Set file behavior to: |
||||
|
# Windows-style line endings, and |
||||
|
# tabular indentation |
||||
|
############################################################################### |
||||
|
[*.sln] |
||||
end_of_line = crlf |
end_of_line = crlf |
||||
|
indent_style = tab |
||||
|
|
||||
|
############################################################################### |
||||
|
# Set dotnet naming rules to: |
||||
|
# suggest async members be pascal case suffixed with Async |
||||
|
# suggest const declarations be pascal case |
||||
|
# suggest interfaces be pascal case prefixed with I |
||||
|
# suggest parameters be camel case |
||||
|
# suggest private and internal static fields be camel case |
||||
|
# suggest private and internal fields be camel case |
||||
|
# suggest public and protected declarations be pascal case |
||||
|
# suggest static readonly declarations be pascal case |
||||
|
# suggest type parameters be prefixed with T |
||||
|
############################################################################### |
||||
|
[*.cs] |
||||
|
dotnet_naming_rule.async_members_should_be_pascal_case_suffixed_with_async.severity = suggestion |
||||
|
dotnet_naming_rule.async_members_should_be_pascal_case_suffixed_with_async.style = pascal_case_suffixed_with_async |
||||
|
dotnet_naming_rule.async_members_should_be_pascal_case_suffixed_with_async.symbols = async_members |
||||
|
|
||||
|
dotnet_naming_rule.const_declarations_should_be_pascal_case.severity = suggestion |
||||
|
dotnet_naming_rule.const_declarations_should_be_pascal_case.style = pascal_case |
||||
|
dotnet_naming_rule.const_declarations_should_be_pascal_case.symbols = const_declarations |
||||
|
|
||||
|
dotnet_naming_rule.interfaces_should_be_pascal_case_prefixed_with_i.severity = suggestion |
||||
|
dotnet_naming_rule.interfaces_should_be_pascal_case_prefixed_with_i.style = pascal_case_prefixed_with_i |
||||
|
dotnet_naming_rule.interfaces_should_be_pascal_case_prefixed_with_i.symbols = interfaces |
||||
|
|
||||
|
dotnet_naming_rule.parameters_should_be_camel_case.severity = suggestion |
||||
|
dotnet_naming_rule.parameters_should_be_camel_case.style = camel_case |
||||
|
dotnet_naming_rule.parameters_should_be_camel_case.symbols = parameters |
||||
|
|
||||
|
dotnet_naming_rule.private_and_internal_static_fields_should_be_camel_case.severity = suggestion |
||||
|
dotnet_naming_rule.private_and_internal_static_fields_should_be_camel_case.style = camel_case |
||||
|
dotnet_naming_rule.private_and_internal_static_fields_should_be_camel_case.symbols = private_and_internal_static_fields |
||||
|
|
||||
|
dotnet_naming_rule.private_and_internal_fields_should_be_camel_case.severity = suggestion |
||||
|
dotnet_naming_rule.private_and_internal_fields_should_be_camel_case.style = camel_case |
||||
|
dotnet_naming_rule.private_and_internal_fields_should_be_camel_case.symbols = private_and_internal_fields |
||||
|
|
||||
|
dotnet_naming_rule.public_and_protected_declarations_should_be_pascal_case.severity = suggestion |
||||
|
dotnet_naming_rule.public_and_protected_declarations_should_be_pascal_case.style = pascal_case |
||||
|
dotnet_naming_rule.public_and_protected_declarations_should_be_pascal_case.symbols = public_and_protected_declarations |
||||
|
dotnet_naming_symbols.public_and_protected_declarations.applicable_kinds = method, field, event, property |
||||
|
|
||||
|
dotnet_naming_rule.static_readonly_declarations_should_be_pascal_case.severity = suggestion |
||||
|
dotnet_naming_rule.static_readonly_declarations_should_be_pascal_case.style = pascal_case |
||||
|
dotnet_naming_rule.static_readonly_declarations_should_be_pascal_case.symbols = static_readonly_declarations |
||||
|
|
||||
|
dotnet_naming_rule.type_parameters_should_be_pascal_case_prefixed_with_t.severity = suggestion |
||||
|
dotnet_naming_rule.type_parameters_should_be_pascal_case_prefixed_with_t.style = pascal_case_prefixed_with_t |
||||
|
dotnet_naming_rule.type_parameters_should_be_pascal_case_prefixed_with_t.symbols = type_parameters |
||||
|
|
||||
|
############################################################################### |
||||
|
# Set dotnet naming styles to define: |
||||
|
# camel case |
||||
|
# pascal case |
||||
|
# pascal case suffixed with Async |
||||
|
# pascal case prefixed with I |
||||
|
# pascal case prefixed with T |
||||
|
############################################################################### |
||||
|
[*.cs] |
||||
|
dotnet_naming_style.camel_case.capitalization = camel_case |
||||
|
|
||||
|
dotnet_naming_style.pascal_case.capitalization = pascal_case |
||||
|
|
||||
|
dotnet_naming_style.pascal_case_suffixed_with_async.capitalization = pascal_case |
||||
|
dotnet_naming_style.pascal_case_suffixed_with_async.required_suffix = Async |
||||
|
|
||||
|
dotnet_naming_style.pascal_case_prefixed_with_i.capitalization = pascal_case |
||||
|
dotnet_naming_style.pascal_case_prefixed_with_i.required_prefix = I |
||||
|
|
||||
|
dotnet_naming_style.pascal_case_prefixed_with_t.capitalization = pascal_case |
||||
|
dotnet_naming_style.pascal_case_prefixed_with_t.required_prefix = T |
||||
|
|
||||
|
############################################################################### |
||||
|
# Set dotnet naming symbols to: |
||||
|
# async members |
||||
|
# const declarations |
||||
|
# interfaces |
||||
|
# private and internal fields |
||||
|
# private and internal static fields |
||||
|
# public and protected declarations |
||||
|
# static readonly declarations |
||||
|
# type parameters |
||||
|
############################################################################### |
||||
|
[*.cs] |
||||
|
dotnet_naming_symbols.async_members.required_modifiers = async |
||||
|
|
||||
|
dotnet_naming_symbols.const_declarations.required_modifiers = const |
||||
|
|
||||
|
dotnet_naming_symbols.interfaces.applicable_kinds = interface |
||||
|
|
||||
|
dotnet_naming_symbols.parameters.applicable_kinds = parameter |
||||
|
|
||||
|
dotnet_naming_symbols.private_and_internal_fields.applicable_accessibilities = private, internal |
||||
|
dotnet_naming_symbols.private_and_internal_fields.applicable_kinds = field |
||||
|
|
||||
|
dotnet_naming_symbols.private_and_internal_static_fields.applicable_accessibilities = private, internal |
||||
|
dotnet_naming_symbols.private_and_internal_static_fields.applicable_kinds = field |
||||
|
dotnet_naming_symbols.private_and_internal_static_fields.required_modifiers = static |
||||
|
|
||||
|
dotnet_naming_symbols.public_and_protected_declarations.applicable_accessibilities = public, protected |
||||
|
|
||||
|
dotnet_naming_symbols.static_readonly_declarations.required_modifiers = static, readonly |
||||
|
|
||||
|
dotnet_naming_symbols.type_parameters.applicable_kinds = type_parameter |
||||
|
|
||||
|
############################################################################### |
||||
|
# Set dotnet sort options to: |
||||
|
# do not separate import directives into groups, and |
||||
|
# sort system directives first |
||||
|
############################################################################### |
||||
|
[*.cs] |
||||
|
dotnet_separate_import_directive_groups = false |
||||
dotnet_sort_system_directives_first = true |
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_locals_parameters_members = true:warning |
||||
dotnet_style_predefined_type_for_member_access = true:warning |
dotnet_style_predefined_type_for_member_access = true:silent |
||||
|
|
||||
|
dotnet_style_prefer_auto_properties = true:silent |
||||
|
dotnet_style_prefer_compound_assignment = true:suggestion |
||||
|
dotnet_style_prefer_conditional_expression_over_assignment = true:silent |
||||
|
dotnet_style_prefer_conditional_expression_over_return = true:silent |
||||
|
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion |
||||
|
dotnet_style_prefer_inferred_tuple_names = true:suggestion |
||||
|
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion |
||||
|
|
||||
|
dotnet_style_qualification_for_event = false:silent |
||||
dotnet_style_qualification_for_field = true:warning |
dotnet_style_qualification_for_field = true:warning |
||||
dotnet_style_qualification_for_method = true:warning |
dotnet_style_qualification_for_method = true:warning |
||||
dotnet_style_qualification_for_property = true:warning |
dotnet_style_qualification_for_property = true:warning |
||||
|
|
||||
[*.tt] |
dotnet_style_readonly_field = true:suggestion |
||||
indent_style = space |
dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent |
||||
indent_size = 4 |
|
||||
|
############################################################################### |
||||
|
# Set dotnet style options to: |
||||
|
# suggest removing all unused parameters |
||||
|
############################################################################### |
||||
|
[*.cs] |
||||
|
dotnet_code_quality_unused_parameters = all:suggestion |
||||
|
|
||||
|
############################################################################### |
||||
|
# Set csharp indent options to: |
||||
|
# indent block contents, |
||||
|
# not indent braces, |
||||
|
# indent case contents, |
||||
|
# not indent case contents when block, |
||||
|
# indent labels one less than the current, and |
||||
|
# indent switch labels |
||||
|
############################################################################### |
||||
|
[*.cs] |
||||
|
csharp_indent_block_contents = true |
||||
|
csharp_indent_braces = false |
||||
|
csharp_indent_case_contents = true |
||||
|
csharp_indent_case_contents_when_block = false |
||||
|
csharp_indent_labels = one_less_than_current |
||||
|
csharp_indent_switch_labels = true |
||||
|
|
||||
|
############################################################################### |
||||
|
# Set csharp new-line options to: |
||||
|
# insert a new-line before "catch", |
||||
|
# insert a new-line before "else", |
||||
|
# insert a new-line before "finally", |
||||
|
# insert a new-line before members in anonymous-types, |
||||
|
# insert a new-line before members in object-initializers, and |
||||
|
# insert a new-line before all open braces |
||||
|
############################################################################### |
||||
|
[*.cs] |
||||
|
csharp_new_line_before_catch = true |
||||
|
csharp_new_line_before_else = true |
||||
|
csharp_new_line_before_finally = true |
||||
|
|
||||
|
csharp_new_line_before_members_in_anonymous_types = true |
||||
|
csharp_new_line_before_members_in_object_initializers = true |
||||
|
|
||||
|
csharp_new_line_before_open_brace = all |
||||
|
|
||||
|
############################################################################### |
||||
|
# Set csharp preserve options to: |
||||
|
# preserve single-line blocks, and |
||||
|
# preserve single-line statements |
||||
|
############################################################################### |
||||
|
[*.cs] |
||||
|
csharp_preserve_single_line_blocks = true |
||||
|
csharp_preserve_single_line_statements = true |
||||
|
|
||||
|
############################################################################### |
||||
|
# Set csharp space options to: |
||||
|
# remove any space after a cast, |
||||
|
# add a space after the colon in an inheritance clause, |
||||
|
# add a space after a comma, |
||||
|
# remove any space after a dot, |
||||
|
# add a space after keywords in control flow statements, |
||||
|
# add a space after a semicolon in a "for" statement, |
||||
|
# add a space before and after binary operators, |
||||
|
# remove space around declaration statements, |
||||
|
# add a space before the colon in an inheritance clause, |
||||
|
# remove any space before a comma, |
||||
|
# remove any space before a dot, |
||||
|
# remove any space before an open square-bracket, |
||||
|
# remove any space before a semicolon in a "for" statement, |
||||
|
# remove any space between empty square-brackets, |
||||
|
# remove any space between a method call's empty parameter list parenthesis, |
||||
|
# remove any space between a method call's name and its opening parenthesis, |
||||
|
# remove any space between a method call's parameter list parenthesis, |
||||
|
# remove any space between a method declaration's empty parameter list parenthesis, |
||||
|
# remove any space between a method declaration's name and its openening parenthesis, |
||||
|
# remove any space between a method declaration's parameter list parenthesis, |
||||
|
# remove any space between parentheses, and |
||||
|
# remove any space between square brackets |
||||
|
############################################################################### |
||||
|
[*.cs] |
||||
|
csharp_space_after_cast = false |
||||
|
csharp_space_after_colon_in_inheritance_clause = true |
||||
|
csharp_space_after_comma = true |
||||
|
csharp_space_after_dot = false |
||||
|
csharp_space_after_keywords_in_control_flow_statements = true |
||||
|
csharp_space_after_semicolon_in_for_statement = true |
||||
|
|
||||
|
csharp_space_around_binary_operators = before_and_after |
||||
|
csharp_space_around_declaration_statements = do_not_ignore |
||||
|
|
||||
|
csharp_space_before_colon_in_inheritance_clause = true |
||||
|
csharp_space_before_comma = false |
||||
|
csharp_space_before_dot = false |
||||
|
csharp_space_before_open_square_brackets = false |
||||
|
csharp_space_before_semicolon_in_for_statement = false |
||||
|
|
||||
|
csharp_space_between_empty_square_brackets = false |
||||
|
csharp_space_between_method_call_empty_parameter_list_parentheses = false |
||||
|
csharp_space_between_method_call_name_and_opening_parenthesis = false |
||||
|
csharp_space_between_method_call_parameter_list_parentheses = false |
||||
|
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false |
||||
|
csharp_space_between_method_declaration_name_and_open_parenthesis = false |
||||
|
csharp_space_between_method_declaration_parameter_list_parentheses = false |
||||
|
csharp_space_between_parentheses = false |
||||
|
csharp_space_between_square_brackets = false |
||||
|
|
||||
|
############################################################################### |
||||
|
# Set csharp style options to: |
||||
|
# generate braces, |
||||
|
# suggest simple default expressions, |
||||
|
# generate a preferred modifier order, |
||||
|
# suggest conditional delegate calls, |
||||
|
# suggest deconstructed variable declarations, |
||||
|
# generate expression-bodied accessors, |
||||
|
# generate expression-bodied constructors, |
||||
|
# generate expression-bodied indexers, |
||||
|
# generate expression-bodied lambdas, |
||||
|
# generate expression-bodied methods, |
||||
|
# generate expression-bodied operators, |
||||
|
# generate expression-bodied properties, |
||||
|
# suggest inlined variable declarations, |
||||
|
# suggest local over anonymous functions, |
||||
|
# suggest pattern-matching over "as" with "null" check, |
||||
|
# suggest pattern-matching over "is" with "cast" check, |
||||
|
# suggest throw expressions, |
||||
|
# generate a discard variable for unused value expression statements, |
||||
|
# suggest a discard variable for unused assignments, |
||||
|
# warn when using var for built-in types, |
||||
|
# warn when using var when the type is not apparent, and |
||||
|
# warn when not using var when the type is apparent |
||||
|
# warn when using simplified "using" declaration |
||||
|
############################################################################### |
||||
|
[*.cs] |
||||
|
csharp_prefer_braces = true:silent |
||||
|
csharp_prefer_simple_default_expression = true:suggestion |
||||
|
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:silent |
||||
|
|
||||
|
csharp_style_conditional_delegate_call = true:suggestion |
||||
|
csharp_style_deconstructed_variable_declaration = true:suggestion |
||||
|
|
||||
|
csharp_style_expression_bodied_accessors = true:silent |
||||
|
csharp_style_expression_bodied_constructors = true:silent |
||||
|
csharp_style_expression_bodied_indexers = true:silent |
||||
|
csharp_style_expression_bodied_lambdas = true:silent |
||||
|
csharp_style_expression_bodied_methods = true:silent |
||||
|
csharp_style_expression_bodied_operators = true:silent |
||||
|
csharp_style_expression_bodied_properties = true:silent |
||||
|
|
||||
|
csharp_style_inlined_variable_declaration = true:suggestion |
||||
|
|
||||
|
csharp_style_pattern_local_over_anonymous_function = true:suggestion |
||||
|
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion |
||||
|
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion |
||||
|
|
||||
|
csharp_style_throw_expression = true:suggestion |
||||
|
|
||||
|
csharp_style_unused_value_expression_statement_preference = discard_variable:silent |
||||
|
csharp_style_unused_value_assignment_preference = discard_variable:suggestion |
||||
|
|
||||
|
csharp_style_var_for_built_in_types = never |
||||
|
csharp_style_var_when_type_is_apparent = true:warning |
||||
|
csharp_style_var_elsewhere = false:warning |
||||
|
|||||
@ -1,49 +1,125 @@ |
|||||
*.doc diff=astextplain |
############################################################################### |
||||
*.DOC diff=astextplain |
# Set default behavior to: |
||||
*.docx diff=astextplain |
# treat as text and |
||||
*.DOCX diff=astextplain |
# normalize to Unix-style line endings |
||||
*.dot diff=astextplain |
############################################################################### |
||||
*.DOT diff=astextplain |
* text eol=lf |
||||
*.pdf diff=astextplain |
|
||||
*.PDF diff=astextplain |
|
||||
*.rtf diff=astextplain |
|
||||
*.RTF diff=astextplain |
|
||||
|
|
||||
*.jpg binary |
############################################################################### |
||||
*.png binary |
# Set explicit file behavior to: |
||||
*.gif binary |
# treat as text and |
||||
|
# normalize to Unix-style line endings |
||||
|
############################################################################### |
||||
|
*.asm text eol=lf |
||||
|
*.c text eol=lf |
||||
|
*.clj text eol=lf |
||||
|
*.cmd text eol=lf |
||||
|
*.cpp text eol=lf |
||||
|
*.css text eol=lf |
||||
|
*.cxx text eol=lf |
||||
|
*.config text eol=lf |
||||
|
*.DotSettings text eol=lf |
||||
|
*.erl text eol=lf |
||||
|
*.fs text eol=lf |
||||
|
*.fsx text eol=lf |
||||
|
*.h text eol=lf |
||||
|
*.htm text eol=lf |
||||
|
*.html text eol=lf |
||||
|
*.hs text eol=lf |
||||
|
*.hxx text eol=lf |
||||
|
*.java text eol=lf |
||||
|
*.js text eol=lf |
||||
|
*.json text eol=lf |
||||
|
*.less text eol=lf |
||||
|
*.lisp text eol=lf |
||||
|
*.lua text eol=lf |
||||
|
*.m text eol=lf |
||||
|
*.md text eol=lf |
||||
|
*.php text eol=lf |
||||
|
*.props text eol=lf |
||||
|
*.ps1 text eol=lf |
||||
|
*.py text eol=lf |
||||
|
*.rb text eol=lf |
||||
|
*.resx text eol=lf |
||||
|
*.runsettings text eol=lf |
||||
|
*.ruleset text eol=lf |
||||
|
*.sass text eol=lf |
||||
|
*.scss text eol=lf |
||||
|
*.sh text eol=lf |
||||
|
*.sql text eol=lf |
||||
|
*.svg text eol=lf |
||||
|
*.targets text eol=lf |
||||
|
*.tt text eol=crlf |
||||
|
*.ttinclude text eol=crlf |
||||
|
*.txt text eol=lf |
||||
|
*.vb text eol=lf |
||||
|
*.yml text eol=lf |
||||
|
|
||||
*.cs text=auto diff=csharp |
############################################################################### |
||||
*.vb text=auto |
# Set explicit file behavior to: |
||||
*.c text=auto |
# treat as text |
||||
*.cpp text=auto |
# normalize to Unix-style line endings and |
||||
*.cxx text=auto |
# diff as csharp |
||||
*.h text=auto |
############################################################################### |
||||
*.hxx text=auto |
*.cs text eol=lf diff=csharp |
||||
*.py text=auto |
|
||||
*.rb text=auto |
|
||||
*.java text=auto |
|
||||
*.html text=auto |
|
||||
*.htm text=auto |
|
||||
*.css text=auto |
|
||||
*.scss text=auto |
|
||||
*.sass text=auto |
|
||||
*.less text=auto |
|
||||
*.js text=auto |
|
||||
*.lisp text=auto |
|
||||
*.clj text=auto |
|
||||
*.sql text=auto |
|
||||
*.php text=auto |
|
||||
*.lua text=auto |
|
||||
*.m text=auto |
|
||||
*.asm text=auto |
|
||||
*.erl text=auto |
|
||||
*.fs text=auto |
|
||||
*.fsx text=auto |
|
||||
*.hs text=auto |
|
||||
|
|
||||
*.csproj text=auto merge=union |
############################################################################### |
||||
*.vbproj text=auto merge=union |
# Set explicit file behavior to: |
||||
*.fsproj text=auto merge=union |
# treat as text |
||||
*.dbproj text=auto merge=union |
# normalize to Unix-style line endings and |
||||
*.sln text=auto eol=crlf merge=union |
# use a union merge when resoling conflicts |
||||
|
############################################################################### |
||||
|
*.csproj text eol=lf merge=union |
||||
|
*.dbproj text eol=lf merge=union |
||||
|
*.fsproj text eol=lf merge=union |
||||
|
*.ncrunchproject text eol=lf merge=union |
||||
|
*.vbproj text eol=lf merge=union |
||||
|
|
||||
|
############################################################################### |
||||
|
# Set explicit file behavior to: |
||||
|
# treat as text |
||||
|
# normalize to Windows-style line endings and |
||||
|
# use a union merge when resoling conflicts |
||||
|
############################################################################### |
||||
|
*.sln text eol=crlf merge=union |
||||
|
|
||||
|
############################################################################### |
||||
|
# Set explicit file behavior to: |
||||
|
# treat as binary |
||||
|
############################################################################### |
||||
|
*.basis binary |
||||
|
*.bmp binary |
||||
|
*.dds binary |
||||
|
*.dll binary |
||||
|
*.eot binary |
||||
|
*.exe binary |
||||
|
*.gif binary |
||||
|
*.jpg binary |
||||
|
*.ktx binary |
||||
|
*.otf binary |
||||
|
*.pbm binary |
||||
|
*.pdf binary |
||||
|
*.png binary |
||||
|
*.ppt binary |
||||
|
*.pptx binary |
||||
|
*.pvr binary |
||||
|
*.snk binary |
||||
|
*.tga binary |
||||
|
*.ttc binary |
||||
|
*.ttf binary |
||||
|
*.woff binary |
||||
|
*.woff2 binary |
||||
|
*.xls binary |
||||
|
*.xlsx binary |
||||
|
|
||||
|
############################################################################### |
||||
|
# Set explicit file behavior to: |
||||
|
# diff as plain text |
||||
|
############################################################################### |
||||
|
*.doc diff=astextplain |
||||
|
*.docx diff=astextplain |
||||
|
*.dot diff=astextplain |
||||
|
*.pdf diff=astextplain |
||||
|
*.pptx diff=astextplain |
||||
|
*.rtf diff=astextplain |
||||
|
*.svg diff=astextplain |
||||
|
|||||
@ -0,0 +1 @@ |
|||||
|
open_collective: imagesharp |
||||
@ -0,0 +1,148 @@ |
|||||
|
name: Build |
||||
|
|
||||
|
on: |
||||
|
push: |
||||
|
branches: |
||||
|
- master |
||||
|
tags: |
||||
|
- "v*" |
||||
|
pull_request: |
||||
|
branches: |
||||
|
- master |
||||
|
|
||||
|
jobs: |
||||
|
Build: |
||||
|
strategy: |
||||
|
matrix: |
||||
|
options: |
||||
|
- os: ubuntu-latest |
||||
|
framework: netcoreapp3.1 |
||||
|
runtime: -x64 |
||||
|
codecov: false |
||||
|
- os: windows-latest |
||||
|
framework: netcoreapp3.1 |
||||
|
runtime: -x64 |
||||
|
codecov: true |
||||
|
- os: windows-latest |
||||
|
framework: netcoreapp2.1 |
||||
|
runtime: -x64 |
||||
|
codecov: false |
||||
|
- os: windows-latest |
||||
|
framework: net472 |
||||
|
runtime: -x64 |
||||
|
codecov: false |
||||
|
- os: windows-latest |
||||
|
framework: net472 |
||||
|
runtime: -x86 |
||||
|
codecov: false |
||||
|
|
||||
|
runs-on: ${{matrix.options.os}} |
||||
|
|
||||
|
steps: |
||||
|
- uses: actions/checkout@v2 |
||||
|
|
||||
|
- name: Install NuGet |
||||
|
uses: NuGet/setup-nuget@v1 |
||||
|
|
||||
|
- name: Setup Git |
||||
|
shell: bash |
||||
|
run: | |
||||
|
git config --global core.autocrlf false |
||||
|
git config --global core.longpaths true |
||||
|
git fetch --prune --unshallow |
||||
|
git submodule -q update --init --recursive |
||||
|
|
||||
|
- name: Fetch Tags for GitVersion |
||||
|
run: | |
||||
|
git fetch --tags |
||||
|
|
||||
|
- name: Fetch master for GitVersion |
||||
|
if: github.ref != 'refs/heads/master' |
||||
|
run: git branch --create-reflog master origin/master |
||||
|
|
||||
|
- name: Install GitVersion |
||||
|
uses: gittools/actions/setup-gitversion@v0.3 |
||||
|
with: |
||||
|
versionSpec: "5.1.x" |
||||
|
|
||||
|
- name: Use GitVersion |
||||
|
id: gitversion # step id used as reference for output values |
||||
|
uses: gittools/actions/execute-gitversion@v0.3 |
||||
|
|
||||
|
- name: Setup DotNet SDK |
||||
|
uses: actions/setup-dotnet@v1 |
||||
|
with: |
||||
|
dotnet-version: "3.1.101" |
||||
|
|
||||
|
- name: Build |
||||
|
shell: pwsh |
||||
|
run: ./ci-build.ps1 "${{steps.gitversion.outputs.nuGetVersion}}" "${{matrix.options.framework}}" |
||||
|
|
||||
|
- name: Test |
||||
|
shell: pwsh |
||||
|
run: ./ci-test.ps1 "${{matrix.options.os}}" "${{matrix.options.framework}}" "${{matrix.options.runtime}}" "${{matrix.options.codecov}}" |
||||
|
env: |
||||
|
CI: True |
||||
|
XUNIT_PATH: .\tests\ImageSharp.Tests # Required for xunit |
||||
|
|
||||
|
# Avoid "Please provide the repository token to upload reports via `-t :repository-token`" |
||||
|
# https://community.codecov.io/t/whitelist-github-action-servers-to-upload-without-a-token/491/10 |
||||
|
# https://github.community/t5/GitHub-Actions/Make-secrets-available-to-builds-of-forks/m-p/42814/highlight/true#M5129 |
||||
|
- name: Update Codecov |
||||
|
uses: iansu/codecov-action-node@v1.0.0 |
||||
|
if: matrix.options.codecov == true && startsWith(github.repository, 'SixLabors') |
||||
|
with: |
||||
|
token: 0ef021c7-2679-4012-b42f-4bed33d99450 |
||||
|
flags: unittests |
||||
|
|
||||
|
Publish: |
||||
|
needs: [Build] |
||||
|
|
||||
|
runs-on: windows-latest |
||||
|
|
||||
|
if: (github.event_name == 'push') |
||||
|
|
||||
|
steps: |
||||
|
- uses: actions/checkout@v2 |
||||
|
|
||||
|
- name: Install NuGet |
||||
|
uses: NuGet/setup-nuget@v1 |
||||
|
|
||||
|
- name: Setup Git |
||||
|
shell: bash |
||||
|
run: | |
||||
|
git config --global core.autocrlf false |
||||
|
git config --global core.longpaths true |
||||
|
git fetch --prune --unshallow |
||||
|
git submodule -q update --init --recursive |
||||
|
|
||||
|
- name: Fetch Tags for GitVersion |
||||
|
run: | |
||||
|
git fetch --tags |
||||
|
|
||||
|
- name: Fetch master for GitVersion |
||||
|
if: github.ref != 'refs/heads/master' |
||||
|
run: git branch --create-reflog master origin/master |
||||
|
|
||||
|
- name: Install GitVersion |
||||
|
uses: gittools/actions/setup-gitversion@v0.3 |
||||
|
with: |
||||
|
versionSpec: "5.1.x" |
||||
|
|
||||
|
- name: Use GitVersion |
||||
|
id: gitversion # step id used as reference for output values |
||||
|
uses: gittools/actions/execute-gitversion@v0.3 |
||||
|
|
||||
|
- name: Setup DotNet SDK |
||||
|
uses: actions/setup-dotnet@v1 |
||||
|
with: |
||||
|
dotnet-version: "3.1.101" |
||||
|
|
||||
|
- name: Pack |
||||
|
shell: pwsh |
||||
|
run: ./ci-pack.ps1 "${{steps.gitversion.outputs.nuGetVersion}}" |
||||
|
|
||||
|
- name: Publish to MyGet |
||||
|
shell: pwsh |
||||
|
run: nuget.exe push .\artifacts\*.nupkg ${{secrets.MYGET_TOKEN}} -Source https://www.myget.org/F/sixlabors/api/v2/package |
||||
|
# TODO: If github.ref starts with 'refs/tags' then it was tag push and we can optionally push out package to nuget.org |
||||
@ -1,43 +0,0 @@ |
|||||
language: csharp |
|
||||
solution: ImageSharp.sln |
|
||||
|
|
||||
matrix: |
|
||||
include: |
|
||||
- os: linux # Ubuntu 14.04 |
|
||||
dist: trusty |
|
||||
sudo: required |
|
||||
dotnet: 2.1.401 |
|
||||
mono: latest |
|
||||
# - os: osx # OSX 10.11 |
|
||||
# osx_image: xcode7.3.1 |
|
||||
# dotnet: 1.0.0-preview2-003121 |
|
||||
# mono: latest |
|
||||
|
|
||||
branches: |
|
||||
only: |
|
||||
- master |
|
||||
- coverity_scan |
|
||||
|
|
||||
script: |
|
||||
- git submodule -q update --init |
|
||||
- dotnet restore |
|
||||
- dotnet test tests/ImageSharp.Tests/ImageSharp.Tests.csproj -c Release -f "netcoreapp2.1" |
|
||||
|
|
||||
env: |
|
||||
global: |
|
||||
# The next declaration is the encrypted COVERITY_SCAN_TOKEN, created |
|
||||
# via the "travis encrypt" command using the project repo's public key |
|
||||
- secure: "rjMvEMN9rpvIXqXqCAAKzbHyABzr7E4wPU/dYJ/mHBqlCccFpQrEXVVM1MfRFXYuWZSaIioknhLATZjT5xvIYpTNM6D57z4OTmqeRHhYm80=" |
|
||||
|
|
||||
before_install: |
|
||||
- echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca- |
|
||||
|
|
||||
addons: |
|
||||
coverity_scan: |
|
||||
project: |
|
||||
name: "SixLabors/ImageSharp" |
|
||||
description: "Build submitted via Travis CI" |
|
||||
notification_email: james_south@hotmail.com |
|
||||
build_command_prepend: "dotnet restore" |
|
||||
build_command: "dotnet build -c Release" |
|
||||
branch_pattern: coverity_scan |
|
||||
@ -1,28 +0,0 @@ |
|||||
{ |
|
||||
// Use IntelliSense to find out which attributes exist for C# debugging |
|
||||
// Use hover for the description of the existing attributes |
|
||||
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md |
|
||||
"version": "0.2.0", |
|
||||
"configurations": [ |
|
||||
{ |
|
||||
"name": ".NET Core Launch (console)", |
|
||||
"type": "coreclr", |
|
||||
"request": "launch", |
|
||||
"preLaunchTask": "build", |
|
||||
// If you have changed target frameworks, make sure to update the program path. |
|
||||
"program": "${workspaceRoot}/tests/ImageSharp.Benchmarks/bin/Debug/netcoreapp2.0/ImageSharp.Benchmarks.dll", |
|
||||
"args": [], |
|
||||
"cwd": "${workspaceRoot}/samples/AvatarWithRoundedCorner", |
|
||||
// For more information about the 'console' field, see https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md#console-terminal-window |
|
||||
"console": "internalConsole", |
|
||||
"stopAtEntry": false, |
|
||||
"internalConsoleOptions": "openOnSessionStart" |
|
||||
}, |
|
||||
{ |
|
||||
"name": ".NET Core Attach", |
|
||||
"type": "coreclr", |
|
||||
"request": "attach", |
|
||||
"processId": "${command:pickProcess}" |
|
||||
} |
|
||||
] |
|
||||
} |
|
||||
@ -1,31 +0,0 @@ |
|||||
{ |
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558 |
|
||||
// for the documentation about the tasks.json format |
|
||||
"version": "0.1.0", |
|
||||
"command": "dotnet", |
|
||||
"isShellCommand": true, |
|
||||
"args": [], |
|
||||
"tasks": [ |
|
||||
{ |
|
||||
"taskName": "build", |
|
||||
"args": [ "ImageSharp.sln" ], |
|
||||
"isBuildCommand": true, |
|
||||
"showOutput": "always", |
|
||||
"problemMatcher": "$msCompile" |
|
||||
}, |
|
||||
{ |
|
||||
"taskName": "build benchmark", |
|
||||
"suppressTaskName": true, |
|
||||
"args": [ "build", "tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj", "-f", "netcoreapp2.0", "-c", "Release" ], |
|
||||
"showOutput": "always", |
|
||||
"problemMatcher": "$msCompile" |
|
||||
}, |
|
||||
{ |
|
||||
"taskName": "test", |
|
||||
"args": ["tests/ImageSharp.Tests/ImageSharp.Tests.csproj", "-c", "release", "-f", "netcoreapp2.0"], |
|
||||
"isTestCommand": true, |
|
||||
"showOutput": "always", |
|
||||
"problemMatcher": "$msCompile" |
|
||||
} |
|
||||
] |
|
||||
} |
|
||||
@ -0,0 +1,3 @@ |
|||||
|
# Code of Conduct |
||||
|
This project has adopted the code of conduct defined by the [Contributor Covenant](https://contributor-covenant.org/) to clarify expected behavior in our community. |
||||
|
For more information, see the [.NET Foundation Code of Conduct](https://dotnetfoundation.org/code-of-conduct). |
||||
@ -1,22 +0,0 @@ |
|||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||
<RunSettings> |
|
||||
<DataCollectionRunSettings> |
|
||||
<DataCollectors> |
|
||||
<DataCollector friendlyName="Code Coverage" uri="datacollector://Microsoft/CodeCoverage/2.0" assemblyQualifiedName="Microsoft.VisualStudio.Coverage.DynamicCoverageDataCollector, Microsoft.VisualStudio.TraceCollector, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> |
|
||||
<Configuration> |
|
||||
<CodeCoverage> |
|
||||
<ModulePaths> |
|
||||
<Include> |
|
||||
<ModulePath>.*ImageSharp.dll</ModulePath> |
|
||||
</Include> |
|
||||
<Exclude> |
|
||||
<ModulePath>.*tests*</ModulePath> |
|
||||
<ModulePath>.*Tests*</ModulePath> |
|
||||
</Exclude> |
|
||||
</ModulePaths> |
|
||||
</CodeCoverage> |
|
||||
</Configuration> |
|
||||
</DataCollector> |
|
||||
</DataCollectors> |
|
||||
</DataCollectionRunSettings> |
|
||||
</RunSettings> |
|
||||
@ -0,0 +1,113 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<Project> |
||||
|
|
||||
|
<!-- |
||||
|
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 imported |
||||
|
beforehand. We also don't need to add ourselves to MSBuildAllProjects, as |
||||
|
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/</RepositoryUrl> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<!-- Default settings that explicitly differ from the Sdk.props defaults --> |
||||
|
<PropertyGroup> |
||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> |
||||
|
<BaseIntermediateOutputPath>$(BaseArtifactsPath)obj/$(BaseArtifactsPathSuffix)/</BaseIntermediateOutputPath> |
||||
|
<DebugType>portable</DebugType> |
||||
|
<DebugType Condition="'$(codecov)' != ''">full</DebugType> |
||||
|
<NullableContextOptions>disable</NullableContextOptions> |
||||
|
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance> |
||||
|
<SignAssembly>false</SignAssembly> |
||||
|
<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> |
||||
|
<BaseOutputPath>$(BaseArtifactsPath)bin/$(BaseArtifactsPathSuffix)/</BaseOutputPath> |
||||
|
<Company>Six Labors</Company> |
||||
|
<PackageOutputPath>$(BaseArtifactsPath)pkg/$(BaseArtifactsPathSuffix)/$(Configuration)/</PackageOutputPath> |
||||
|
<Product>SixLabors.ImageSharp</Product> |
||||
|
<VersionPrefix>0.0.1</VersionPrefix> |
||||
|
<VersionPrefix Condition="'$(packageversion)' != ''">$(PackageVersion)</VersionPrefix> |
||||
|
<VersionSuffix></VersionSuffix> |
||||
|
</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>icon.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; |
||||
|
<!-- Contains RemoteExecutor. Taken from: https://github.com/dotnet/runtime/blob/master/NuGet.config --> |
||||
|
https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/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" /> |
||||
|
<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\sixlabors.imagesharp.128.png" Pack="true" PackagePath="\icon.png" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,37 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<Project> |
||||
|
|
||||
|
<!-- |
||||
|
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 |
||||
|
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" /> |
||||
|
<PackageReference Update="Microsoft.NETFramework.ReferenceAssemblies" PrivateAssets="All" Version="1.0.0" /> |
||||
|
<PackageReference Update="StyleCop.Analyzers" PrivateAssets="All" Version="1.1.118" /> |
||||
|
|
||||
|
<!--Src Dependencies--> |
||||
|
<PackageReference Update="System.Buffers" Version="4.5.0" /> |
||||
|
<PackageReference Update="System.IO.Compression" Version="4.3.0" /> |
||||
|
<PackageReference Update="System.IO.UnmanagedMemoryStream" Version="4.3.0" /> |
||||
|
<PackageReference Update="System.Numerics.Vectors" Version="4.5.0" /> |
||||
|
<PackageReference Update="System.Memory" Version="4.5.3" /> |
||||
|
<PackageReference Update="System.Runtime.CompilerServices.Unsafe" Version="4.7" /> |
||||
|
<PackageReference Update="System.Threading.Tasks.Parallel" Version="4.3.0" /> |
||||
|
<PackageReference Update="System.ValueTuple" Version="4.5.0" /> |
||||
|
|
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,7 @@ |
|||||
|
continuous-delivery-fallback-tag: ci |
||||
|
branches: |
||||
|
master: |
||||
|
tag: unstable |
||||
|
mode: ContinuousDeployment |
||||
|
pull-request: |
||||
|
tag: pr |
||||
@ -1,15 +0,0 @@ |
|||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||
<RuleSet Name="ImageSharp" ToolsVersion="15.0"> |
|
||||
<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.Analyzers"> |
|
||||
<Rule Id="AD0001" Action="None" /> |
|
||||
<Rule Id="SA1413" Action="None" /> |
|
||||
<!-- <Rule Id="SA1405" Action="None" /> |
|
||||
temp remove the header requirement as stylecop is currently failing to read the stylecop.json file from 'dotnet build' |
|
||||
<Rule Id="SA1636" Action="None" />--> |
|
||||
<Rule Id="SA1633" Action="None" /> |
|
||||
<!--1.1.0-beta6 incorrectly throws a wobbler here for multiline matrices--> |
|
||||
<Rule Id="SA1500" Action="None" /> |
|
||||
<!--Comments should end with a period. I like this but there's 3000+ errors to fix--> |
|
||||
<Rule Id="SA1629" Action="None" /> |
|
||||
</Rules> |
|
||||
</RuleSet> |
|
||||
@ -1,391 +0,0 @@ |
|||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> |
|
||||
<s:String x:Key="/Default/CodeStyle/CodeCleanup/Profiles/=StyleCop/@EntryIndexedValue"><?xml version="1.0" encoding="utf-16"?> |
|
||||
<Profile name="StyleCop"> |
|
||||
<CSUpdateFileHeader>False</CSUpdateFileHeader> |
|
||||
<CSArrangeQualifiers>True</CSArrangeQualifiers> |
|
||||
<CSOptimizeUsings> |
|
||||
<OptimizeUsings>True</OptimizeUsings> |
|
||||
<EmbraceInRegion>False</EmbraceInRegion> |
|
||||
<RegionName></RegionName> |
|
||||
</CSOptimizeUsings> |
|
||||
<CSReformatCode>True</CSReformatCode> |
|
||||
<CSReorderTypeMembers>True</CSReorderTypeMembers> |
|
||||
</Profile></s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/CodeCleanup/SilentCleanupProfile/@EntryValue">StyleCop</s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/MODIFIERS_ORDER/@EntryValue">public protected internal private static new abstract virtual override sealed readonly extern unsafe volatile async</s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/ThisQualifier/INSTANCE_MEMBERS_QUALIFY_MEMBERS/@EntryValue">Field, Property, Event, Method</s:String> |
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_LINQ_QUERY/@EntryValue">True</s:Boolean> |
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_ARRAY_AND_OBJECT_INITIALIZER/@EntryValue">True</s:Boolean> |
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_EXPRESSION/@EntryValue">True</s:Boolean> |
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_EXTENDS_LIST/@EntryValue">True</s:Boolean> |
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_FOR_STMT/@EntryValue">True</s:Boolean> |
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_PARAMETER/@EntryValue">True</s:Boolean> |
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTIPLE_DECLARATION/@EntryValue">True</s:Boolean> |
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTLINE_TYPE_PARAMETER_CONSTRAINS/@EntryValue">True</s:Boolean> |
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTLINE_TYPE_PARAMETER_LIST/@EntryValue">True</s:Boolean> |
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ANONYMOUS_METHOD_DECLARATION_BRACES/@EntryValue">NEXT_LINE_SHIFTED_2</s:String> |
|
||||
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/BLANK_LINES_AROUND_SINGLE_LINE_AUTO_PROPERTY/@EntryValue">1</s:Int64> |
|
||||
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/BLANK_LINES_AROUND_SINGLE_LINE_FIELD/@EntryValue">1</s:Int64> |
|
||||
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/BLANK_LINES_AROUND_SINGLE_LINE_INVOCABLE/@EntryValue">1</s:Int64> |
|
||||
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/BLANK_LINES_AROUND_SINGLE_LINE_PROPERTY/@EntryValue">1</s:Int64> |
|
||||
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/BLANK_LINES_BETWEEN_USING_GROUPS/@EntryValue">1</s:Int64> |
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/CASE_BLOCK_BRACES/@EntryValue">NEXT_LINE_SHIFTED_2</s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/FORCE_FIXED_BRACES_STYLE/@EntryValue">ALWAYS_ADD</s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/FORCE_FOR_BRACES_STYLE/@EntryValue">ALWAYS_ADD</s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/FORCE_FOREACH_BRACES_STYLE/@EntryValue">ALWAYS_ADD</s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/FORCE_IFELSE_BRACES_STYLE/@EntryValue">ALWAYS_ADD</s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/FORCE_WHILE_BRACES_STYLE/@EntryValue">ALWAYS_ADD</s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INITIALIZER_BRACES/@EntryValue">NEXT_LINE_SHIFTED_2</s:String> |
|
||||
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_BLANK_LINES_IN_CODE/@EntryValue">1</s:Int64> |
|
||||
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_BLANK_LINES_IN_DECLARATIONS/@EntryValue">1</s:Int64> |
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_EXISTING_EXPR_MEMBER_ARRANGEMENT/@EntryValue">False</s:Boolean> |
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_EXISTING_INITIALIZER_ARRANGEMENT/@EntryValue">False</s:Boolean> |
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_USER_LINEBREAKS/@EntryValue">False</s:Boolean> |
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_ACCESSORHOLDER_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String> |
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_CONSTRUCTOR_INITIALIZER_ON_SAME_LINE/@EntryValue">False</s:Boolean> |
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_FIELD_ATTRIBUTE_ON_SAME_LINE/@EntryValue">False</s:Boolean> |
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_FIELD_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String> |
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_ACCESSOR_ON_SINGLE_LINE/@EntryValue">False</s:Boolean> |
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_EMBEDDED_STATEMENT_ON_SAME_LINE/@EntryValue">ALWAYS</s:String> |
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_TYPE_CONSTRAINTS_ON_SAME_LINE/@EntryValue">False</s:Boolean> |
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_WHILE_ON_NEW_LINE/@EntryValue">True</s:Boolean> |
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SIMPLE_EMBEDDED_STATEMENT_STYLE/@EntryValue">ON_SINGLE_LINE</s:String> |
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_AFTER_TYPECAST_PARENTHESES/@EntryValue">False</s:Boolean> |
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_AROUND_MULTIPLICATIVE_OP/@EntryValue">True</s:Boolean> |
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_WITHIN_SINGLE_LINE_ARRAY_INITIALIZER_BRACES/@EntryValue">True</s:Boolean> |
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/STICK_COMMENT/@EntryValue">False</s:Boolean> |
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_AFTER_DECLARATION_LPAR/@EntryValue">True</s:Boolean> |
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_AFTER_INVOCATION_LPAR/@EntryValue">True</s:Boolean> |
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_ARGUMENTS_STYLE/@EntryValue">CHOP_IF_LONG</s:String> |
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_BEFORE_BINARY_OPSIGN/@EntryValue">True</s:Boolean> |
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_BEFORE_FIRST_TYPE_PARAMETER_CONSTRAINT/@EntryValue">True</s:Boolean> |
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_EXTENDS_LIST_STYLE/@EntryValue">CHOP_IF_LONG</s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_PARAMETERS_STYLE/@EntryValue">CHOP_IF_LONG</s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/CSharpFileLayoutPatterns/Pattern/@EntryValue"><?xml version="1.0" encoding="utf-16"?>
 |
|
||||
<Patterns xmlns="urn:schemas-jetbrains-com:member-reordering-patterns">
 |
|
||||
<TypePattern DisplayName="COM interfaces or structs">
 |
|
||||
<TypePattern.Match>
 |
|
||||
<Or>
 |
|
||||
<And>
 |
|
||||
<Kind Is="Interface" />
 |
|
||||
<Or>
 |
|
||||
<HasAttribute Name="System.Runtime.InteropServices.InterfaceTypeAttribute" />
 |
|
||||
<HasAttribute Name="System.Runtime.InteropServices.ComImport" />
 |
|
||||
</Or>
 |
|
||||
</And>
 |
|
||||
<Kind Is="Struct" />
 |
|
||||
</Or>
 |
|
||||
</TypePattern.Match>
 |
|
||||
</TypePattern>
 |
|
||||
<TypePattern DisplayName="P/Invoke classes called 'NativeMethods' (StyleCop)">
 |
|
||||
<TypePattern.Match>
 |
|
||||
<And>
 |
|
||||
<Kind Is="Class" />
 |
|
||||
<Name Is=".*NativeMethods" />
 |
|
||||
</And>
 |
|
||||
</TypePattern.Match>
 |
|
||||
</TypePattern>
 |
|
||||
<TypePattern DisplayName="DataMember serialisation classes (StyleCop)">
 |
|
||||
<TypePattern.Match>
 |
|
||||
<And>
 |
|
||||
<Or>
 |
|
||||
<Kind Is="Field" />
 |
|
||||
<Kind Is="Property" />
 |
|
||||
</Or>
 |
|
||||
<HasAttribute Name="System.Runtime.Serialization.DataMemberAttribute" />
 |
|
||||
</And>
 |
|
||||
</TypePattern.Match>
 |
|
||||
</TypePattern>
 |
|
||||
<TypePattern DisplayName="Default Pattern (StyleCop)" RemoveRegions="All">
 |
|
||||
<Entry DisplayName="Constants">
 |
|
||||
<Entry.Match>
 |
|
||||
<Kind Is="Constant" />
 |
|
||||
</Entry.Match>
 |
|
||||
<Entry.SortBy>
 |
|
||||
<Access Order="Public Internal ProtectedInternal Protected Private" />
 |
|
||||
<Name />
 |
|
||||
</Entry.SortBy>
 |
|
||||
</Entry>
 |
|
||||
<Entry DisplayName="Static fields">
 |
|
||||
<Entry.Match>
 |
|
||||
<And>
 |
|
||||
<Kind Is="Field" />
 |
|
||||
<Static />
 |
|
||||
</And>
 |
|
||||
</Entry.Match>
 |
|
||||
<Entry.SortBy>
 |
|
||||
<Access Order="Public Internal ProtectedInternal Protected Private" />
 |
|
||||
<Readonly />
 |
|
||||
<Name />
 |
|
||||
</Entry.SortBy>
 |
|
||||
</Entry>
 |
|
||||
<Entry DisplayName="Fields">
 |
|
||||
<Entry.Match>
 |
|
||||
<Kind Is="Field" />
 |
|
||||
</Entry.Match>
 |
|
||||
<Entry.SortBy>
 |
|
||||
<Access Order="Public Internal ProtectedInternal Protected Private" />
 |
|
||||
<Readonly />
 |
|
||||
<Name />
 |
|
||||
</Entry.SortBy>
 |
|
||||
</Entry>
 |
|
||||
<Entry Priority="200" DisplayName="Constructors and Destructors">
 |
|
||||
<Entry.Match>
 |
|
||||
<Or>
 |
|
||||
<Kind Is="Constructor" />
 |
|
||||
<Kind Is="Destructor" />
 |
|
||||
</Or>
 |
|
||||
</Entry.Match>
 |
|
||||
<Entry.SortBy>
 |
|
||||
<Static />
 |
|
||||
<Kind Order="Constructor Destructor" />
 |
|
||||
<Access Order="Public Internal ProtectedInternal Protected Private" />
 |
|
||||
</Entry.SortBy>
 |
|
||||
</Entry>
 |
|
||||
<Entry DisplayName="Delegates">
 |
|
||||
<Entry.Match>
 |
|
||||
<Kind Is="Delegate" />
 |
|
||||
</Entry.Match>
 |
|
||||
<Entry.SortBy>
 |
|
||||
<Access Order="Public Internal ProtectedInternal Protected Private" />
 |
|
||||
<Static />
 |
|
||||
<Name />
 |
|
||||
</Entry.SortBy>
 |
|
||||
</Entry>
 |
|
||||
<Entry DisplayName="Public events">
 |
|
||||
<Entry.Match>
 |
|
||||
<And>
 |
|
||||
<Kind Is="Event" />
 |
|
||||
<Access Is="Public" />
 |
|
||||
</And>
 |
|
||||
</Entry.Match>
 |
|
||||
<Entry.SortBy>
 |
|
||||
<Access Order="Public" />
 |
|
||||
<Static />
 |
|
||||
<Name />
 |
|
||||
</Entry.SortBy>
 |
|
||||
</Entry>
 |
|
||||
<Entry DisplayName="Interface events">
 |
|
||||
<Entry.Match>
 |
|
||||
<And>
 |
|
||||
<Kind Is="Event" />
 |
|
||||
<ImplementsInterface />
 |
|
||||
</And>
 |
|
||||
</Entry.Match>
 |
|
||||
<Entry.SortBy>
 |
|
||||
<ImplementsInterface Immediate="True" />
 |
|
||||
<Name />
 |
|
||||
</Entry.SortBy>
 |
|
||||
</Entry>
 |
|
||||
<Entry DisplayName="Other events">
 |
|
||||
<Entry.Match>
 |
|
||||
<Kind Is="Event" />
 |
|
||||
</Entry.Match>
 |
|
||||
<Entry.SortBy>
 |
|
||||
<Access Order="Public Internal ProtectedInternal Protected Private" />
 |
|
||||
<Static />
 |
|
||||
<Name />
 |
|
||||
</Entry.SortBy>
 |
|
||||
</Entry>
 |
|
||||
<Entry DisplayName="Enums">
 |
|
||||
<Entry.Match>
 |
|
||||
<Kind Is="Enum" />
 |
|
||||
</Entry.Match>
 |
|
||||
<Entry.SortBy>
 |
|
||||
<Access Order="Public Internal ProtectedInternal Protected Private" />
 |
|
||||
<Name />
 |
|
||||
</Entry.SortBy>
 |
|
||||
</Entry>
 |
|
||||
<Entry DisplayName="Interfaces">
 |
|
||||
<Entry.Match>
 |
|
||||
<Kind Is="Interface" />
 |
|
||||
</Entry.Match>
 |
|
||||
<Entry.SortBy>
 |
|
||||
<Access Order="Public Internal ProtectedInternal Protected Private" />
 |
|
||||
<Name />
 |
|
||||
</Entry.SortBy>
 |
|
||||
</Entry>
 |
|
||||
<Entry DisplayName="Public properties">
 |
|
||||
<Entry.Match>
 |
|
||||
<And>
 |
|
||||
<Kind Is="Property" />
 |
|
||||
<Access Is="Public" />
 |
|
||||
</And>
 |
|
||||
</Entry.Match>
 |
|
||||
<Entry.SortBy>
 |
|
||||
<Static />
 |
|
||||
<Name />
 |
|
||||
</Entry.SortBy>
 |
|
||||
</Entry>
 |
|
||||
<Entry DisplayName="Interface properties">
 |
|
||||
<Entry.Match>
 |
|
||||
<And>
 |
|
||||
<Kind Is="Property" />
 |
|
||||
<ImplementsInterface />
 |
|
||||
</And>
 |
|
||||
</Entry.Match>
 |
|
||||
<Entry.SortBy>
 |
|
||||
<ImplementsInterface Immediate="True" />
 |
|
||||
<Name />
 |
|
||||
</Entry.SortBy>
 |
|
||||
</Entry>
 |
|
||||
<Entry DisplayName="Other properties">
 |
|
||||
<Entry.Match>
 |
|
||||
<Kind Is="Property" />
 |
|
||||
</Entry.Match>
 |
|
||||
<Entry.SortBy>
 |
|
||||
<Access Order="Public Internal ProtectedInternal Protected Private" />
 |
|
||||
<Static />
 |
|
||||
<Name />
 |
|
||||
</Entry.SortBy>
 |
|
||||
</Entry>
 |
|
||||
<Entry Priority="1000" DisplayName="Public indexers">
 |
|
||||
<Entry.Match>
 |
|
||||
<And>
 |
|
||||
<Kind Is="Indexer" />
 |
|
||||
<Access Is="Public" />
 |
|
||||
</And>
 |
|
||||
</Entry.Match>
 |
|
||||
<Entry.SortBy>
 |
|
||||
<Static />
 |
|
||||
<Name />
 |
|
||||
</Entry.SortBy>
 |
|
||||
</Entry>
 |
|
||||
<Entry Priority="1000" DisplayName="Interface indexers">
 |
|
||||
<Entry.Match>
 |
|
||||
<And>
 |
|
||||
<Kind Is="Indexer" />
 |
|
||||
<ImplementsInterface />
 |
|
||||
</And>
 |
|
||||
</Entry.Match>
 |
|
||||
<Entry.SortBy>
 |
|
||||
<ImplementsInterface Immediate="True" />
 |
|
||||
<Name />
 |
|
||||
</Entry.SortBy>
 |
|
||||
</Entry>
 |
|
||||
<Entry Priority="1000" DisplayName="Other indexers">
 |
|
||||
<Entry.Match>
 |
|
||||
<Kind Is="Indexer" />
 |
|
||||
</Entry.Match>
 |
|
||||
<Entry.SortBy>
 |
|
||||
<Access Order="Public Internal ProtectedInternal Protected Private" />
 |
|
||||
<Static />
 |
|
||||
<Name />
 |
|
||||
</Entry.SortBy>
 |
|
||||
</Entry>
 |
|
||||
<Entry DisplayName="Public methods and operators">
 |
|
||||
<Entry.Match>
 |
|
||||
<And>
 |
|
||||
<Or>
 |
|
||||
<Kind Is="Method" />
 |
|
||||
<Kind Is="Operator" />
 |
|
||||
</Or>
 |
|
||||
<Access Is="Public" />
 |
|
||||
</And>
 |
|
||||
</Entry.Match>
 |
|
||||
<Entry.SortBy>
 |
|
||||
<Static />
 |
|
||||
<Name />
 |
|
||||
</Entry.SortBy>
 |
|
||||
</Entry>
 |
|
||||
<Entry DisplayName="Interface methods">
 |
|
||||
<Entry.Match>
 |
|
||||
<And>
 |
|
||||
<Kind Is="Method" />
 |
|
||||
<ImplementsInterface />
 |
|
||||
</And>
 |
|
||||
</Entry.Match>
 |
|
||||
<Entry.SortBy>
 |
|
||||
<ImplementsInterface Immediate="True" />
 |
|
||||
<Name />
 |
|
||||
</Entry.SortBy>
 |
|
||||
</Entry>
 |
|
||||
<Entry DisplayName="Other methods">
 |
|
||||
<Entry.Match>
 |
|
||||
<Kind Is="Method" />
 |
|
||||
</Entry.Match>
 |
|
||||
<Entry.SortBy>
 |
|
||||
<Access Order="Public Internal ProtectedInternal Protected Private" />
 |
|
||||
<Static />
 |
|
||||
<Name />
 |
|
||||
</Entry.SortBy>
 |
|
||||
</Entry>
 |
|
||||
<Entry DisplayName="Operators">
 |
|
||||
<Entry.Match>
 |
|
||||
<Kind Is="Operator" />
 |
|
||||
</Entry.Match>
 |
|
||||
<Entry.SortBy>
 |
|
||||
<Access Order="Public Internal ProtectedInternal Protected Private" />
 |
|
||||
<Static />
 |
|
||||
<Name />
 |
|
||||
</Entry.SortBy>
 |
|
||||
</Entry>
 |
|
||||
<Entry Priority="600" DisplayName="Nested structs">
 |
|
||||
<Entry.Match>
 |
|
||||
<Kind Is="Struct" />
 |
|
||||
</Entry.Match>
 |
|
||||
<Entry.SortBy>
 |
|
||||
<Static />
 |
|
||||
<Access Order="Public Internal ProtectedInternal Protected Private" />
 |
|
||||
<Name />
 |
|
||||
</Entry.SortBy>
 |
|
||||
</Entry>
 |
|
||||
<Entry Priority="700" DisplayName="Nested classes">
 |
|
||||
<Entry.Match>
 |
|
||||
<Kind Is="Class" />
 |
|
||||
</Entry.Match>
 |
|
||||
<Entry.SortBy>
 |
|
||||
<Static />
 |
|
||||
<Access Order="Public Internal ProtectedInternal Protected Private" />
 |
|
||||
<Name />
 |
|
||||
</Entry.SortBy>
 |
|
||||
</Entry>
 |
|
||||
<Entry DisplayName="All other members" />
 |
|
||||
</TypePattern>
 |
|
||||
</Patterns></s:String> |
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CSharpUsing/AddImportsToDeepestScope/@EntryValue">False</s:Boolean> |
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CSharpUsing/QualifiedUsingAtNestedScope/@EntryValue">True</s:Boolean> |
|
||||
<s:String x:Key="/Default/CodeStyle/FileHeader/FileHeaderText/@EntryValue">// Copyright (c) Six Labors and contributors.
 |
|
||||
// Licensed under the Apache License, Version 2.0.
 |
|
||||
</s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=AC/@EntryIndexedValue">AC</s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=DC/@EntryIndexedValue">DC</s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=DCT/@EntryIndexedValue">DCT</s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=EOF/@EntryIndexedValue">EOF</s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=FDCT/@EntryIndexedValue">FDCT</s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=IDCT/@EntryIndexedValue">IDCT</s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=JPEG/@EntryIndexedValue">JPEG</s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MCU/@EntryIndexedValue">MCU</s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=PNG/@EntryIndexedValue">PNG</s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=RGB/@EntryIndexedValue">RGB</s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=RLE/@EntryIndexedValue">RLE</s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=XY/@EntryIndexedValue">XY</s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=XYZ/@EntryIndexedValue">XYZ</s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/EventHandlerPatternLong/@EntryValue">$object$_On$event$</s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Constants/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=EnumMember/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Interfaces/@EntryIndexedValue"><Policy Inspect="True" Prefix="I" Suffix="" Style="AaBb" /></s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=LocalConstants/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Locals/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=MethodPropertyEvent/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Other/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Parameters/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateConstants/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateInstanceFields/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticFields/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticReadonly/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PublicFields/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=StaticReadonly/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=TypeParameters/@EntryIndexedValue"><Policy Inspect="True" Prefix="T" Suffix="" Style="AaBb" /></s:String> |
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=TypesAndNamespaces/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String> |
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpAttributeForSingleLineMethodUpgrade/@EntryIndexedValue">True</s:Boolean> |
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean> |
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean> |
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpRenamePlacementToArrangementMigration/@EntryIndexedValue">True</s:Boolean> |
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean> |
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAddAccessorOwnerDeclarationBracesMigration/@EntryIndexedValue">True</s:Boolean> |
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAlwaysTreatStructAsNotReorderableMigration/@EntryIndexedValue">True</s:Boolean> |
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002ECSharpPlaceAttributeOnSameLineMigration/@EntryIndexedValue">True</s:Boolean> |
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean> |
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean> |
|
||||
</wpf:ResourceDictionary> |
|
||||
@ -1,9 +0,0 @@ |
|||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||
<configuration> |
|
||||
<packageSources> |
|
||||
<add key="myget.org sixlabors" value="https://www.myget.org/F/sixlabors/api/v3/index.json" /> |
|
||||
<add key="myget.org dotnet-core" value="https://dotnet.myget.org/F/dotnet-core/api/v3/index.json" /> |
|
||||
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" /> |
|
||||
<add key="nuget.org" value="https://www.nuget.org/api/v2/" /> |
|
||||
</packageSources> |
|
||||
</configuration> |
|
||||
@ -1,69 +0,0 @@ |
|||||
version: 1.0.0.{build} |
|
||||
image: Visual Studio 2017 |
|
||||
|
|
||||
# prevent the double build when a branch has an active PR |
|
||||
skip_branch_with_pr: true |
|
||||
|
|
||||
environment: |
|
||||
matrix: |
|
||||
- target_framework: netcoreapp2.1 |
|
||||
is_32bit: False |
|
||||
|
|
||||
- target_framework: netcoreapp2.1 |
|
||||
is_32bit: True |
|
||||
|
|
||||
- target_framework: net472 |
|
||||
is_32bit: False |
|
||||
|
|
||||
- target_framework: net472 |
|
||||
is_32bit: True |
|
||||
|
|
||||
- target_framework: net462 |
|
||||
is_32bit: False |
|
||||
|
|
||||
- target_framework: net462 |
|
||||
is_32bit: True |
|
||||
|
|
||||
#- target_framework: mono |
|
||||
# is_32bit: False |
|
||||
#- target_framework: mono |
|
||||
# is_32bit: True |
|
||||
#- target_framework: net47 |
|
||||
# is_32bit: False |
|
||||
#- target_framework: net47 |
|
||||
# is_32bit: True |
|
||||
|
|
||||
install: |
|
||||
- ps: | |
|
||||
if ($env:target_framework -eq "mono") { |
|
||||
if ($env:is_32bit -eq "True") { |
|
||||
cinst mono --x86 |
|
||||
} else { |
|
||||
cinst mono |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
before_build: |
|
||||
- git submodule -q update --init |
|
||||
- cmd: dotnet --info |
|
||||
|
|
||||
build_script: |
|
||||
- cmd: build.cmd |
|
||||
|
|
||||
test_script: |
|
||||
- ps: .\run-tests.ps1 $env:target_framework $env:is_32bit |
|
||||
|
|
||||
after_test: |
|
||||
- cmd: appveyor PushArtifact "artifacts\SixLabors.ImageSharp.%APPVEYOR_BUILD_VERSION%.nupkg" |
|
||||
- cmd: appveyor PushArtifact "artifacts\SixLabors.ImageSharp.Drawing.%APPVEYOR_BUILD_VERSION%.nupkg" |
|
||||
|
|
||||
deploy: |
|
||||
# MyGet Deployment for builds & releases |
|
||||
- provider: NuGet |
|
||||
server: https://www.myget.org/F/sixlabors/api/v2/package |
|
||||
symbol_server: https://www.myget.org/F/sixlabors/symbols/api/v2/package |
|
||||
api_key: |
|
||||
secure: V/lEHP0UeMWIpWd0fiNlY2IgbCnJKQlGdRksECdJbOBdaE20Fl0RNL7WyqHe02o4 |
|
||||
artifact: /.*\.nupkg/ |
|
||||
on: |
|
||||
branch: master |
|
||||
@ -1,17 +0,0 @@ |
|||||
@echo Off |
|
||||
|
|
||||
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& '.\build.ps1'" |
|
||||
|
|
||||
if not "%errorlevel%"=="0" goto failure |
|
||||
|
|
||||
:success |
|
||||
ECHO successfully built project |
|
||||
REM exit 0 |
|
||||
goto end |
|
||||
|
|
||||
:failure |
|
||||
ECHO failed to build. |
|
||||
REM exit -1 |
|
||||
goto end |
|
||||
|
|
||||
:end |
|
||||
@ -1,122 +0,0 @@ |
|||||
|
|
||||
# lets calulat the correct version here |
|
||||
$fallbackVersion = "1.0.0"; |
|
||||
$version = '' |
|
||||
|
|
||||
$tagRegex = '^v?(\d+\.\d+\.\d+)(-([a-zA-Z]+)\.?(\d*))?$' |
|
||||
|
|
||||
# we are running on the build server |
|
||||
$isVersionTag = $env:APPVEYOR_REPO_TAG_NAME -match $tagRegex |
|
||||
|
|
||||
if($isVersionTag) { |
|
||||
|
|
||||
Write-Debug "Building commit tagged with a compatable version number" |
|
||||
|
|
||||
$version = $matches[1] |
|
||||
$postTag = $matches[3] |
|
||||
$count = $matches[4] |
|
||||
Write-Debug "version number: ${version} post tag: ${postTag} count: ${count}" |
|
||||
if("$postTag" -ne ""){ |
|
||||
$version = "${version}-${postTag}" |
|
||||
} |
|
||||
if("$count" -ne ""){ |
|
||||
# for consistancy with previous releases we pad the counter to only 4 places |
|
||||
$padded = $count.Trim().Trim('0').PadLeft(4,"0"); |
|
||||
Write-Debug "count '$count', padded '${padded}'" |
|
||||
|
|
||||
$version = "${version}${padded}" |
|
||||
} |
|
||||
} |
|
||||
else { |
|
||||
|
|
||||
Write-Debug "Untagged" |
|
||||
$lastTag = (git tag --list --sort=-taggerdate) | Out-String |
|
||||
$list = $lastTag.Split("`n") |
|
||||
foreach ($tag in $list) { |
|
||||
|
|
||||
Write-Debug "testing ${tag}" |
|
||||
$tag = $tag.Trim(); |
|
||||
if($tag -match $tagRegex){ |
|
||||
Write-Debug "matched ${tag}" |
|
||||
$version = $matches[1]; |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
if("$version" -eq ""){ |
|
||||
$version = $fallbackVersion |
|
||||
Write-Debug "Failed to discover base version Fallback to '${version}'" |
|
||||
}else{ |
|
||||
|
|
||||
Write-Debug "Discovered base version from tags '${version}'" |
|
||||
} |
|
||||
|
|
||||
$buildNumber = $env:APPVEYOR_BUILD_NUMBER |
|
||||
|
|
||||
# build number replacement is padded to 6 places |
|
||||
$buildNumber = "$buildNumber".Trim().Trim('0').PadLeft(6,"0"); |
|
||||
if("$env:APPVEYOR_PULL_REQUEST_NUMBER" -ne ""){ |
|
||||
Write-Debug "building a PR" |
|
||||
|
|
||||
$prNumber = "$env:APPVEYOR_PULL_REQUEST_NUMBER".Trim().Trim('0').PadLeft(5,"0"); |
|
||||
# this is a PR |
|
||||
$version = "${version}-PullRequest${prNumber}${buildNumber}"; |
|
||||
}else{ |
|
||||
Write-Debug "building a branch commit" |
|
||||
|
|
||||
# this is a general branch commit |
|
||||
$branch = $env:APPVEYOR_REPO_BRANCH |
|
||||
|
|
||||
if("$branch" -eq ""){ |
|
||||
$branch = ((git rev-parse --abbrev-ref HEAD) | Out-String).Trim() |
|
||||
|
|
||||
if("$branch" -eq ""){ |
|
||||
$branch = "unknown" |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
$branch = $branch.Replace("/","-").ToLower() |
|
||||
|
|
||||
if($branch.ToLower() -eq "master"){ |
|
||||
$branch = "dev" |
|
||||
} |
|
||||
|
|
||||
$version = "${version}-${branch}${buildNumber}"; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
if("$env:APPVEYOR_API_URL" -ne ""){ |
|
||||
# update appveyor build number for this build |
|
||||
Invoke-RestMethod -Method "PUT" ` |
|
||||
-Uri "${env:APPVEYOR_API_URL}api/build" ` |
|
||||
-Body "{version:'${version}'}" ` |
|
||||
-ContentType "application/json" |
|
||||
} |
|
||||
|
|
||||
Write-Host "Building version '${version}'" |
|
||||
dotnet restore /p:packageversion=$version /p:DisableImplicitNuGetFallbackFolder=true |
|
||||
|
|
||||
Write-Host "Building projects" |
|
||||
dotnet build -c Release /p:packageversion=$version |
|
||||
|
|
||||
if ($LASTEXITCODE ){ Exit $LASTEXITCODE } |
|
||||
|
|
||||
# |
|
||||
# TODO: DO WE NEED TO RUN TESTS IMPLICITLY? |
|
||||
# |
|
||||
# if ( $env:CI -ne "True") { |
|
||||
# cd ./tests/ImageSharp.Tests/ |
|
||||
# dotnet xunit -nobuild -c Release -f netcoreapp2.0 --fx-version 2.0.0 |
|
||||
# ./RunExtendedTests.cmd |
|
||||
# cd ../.. |
|
||||
# } |
|
||||
# |
|
||||
|
|
||||
if ($LASTEXITCODE ){ Exit $LASTEXITCODE } |
|
||||
|
|
||||
Write-Host "Packaging projects" |
|
||||
dotnet pack ./src/ImageSharp/ -c Release --output ../../artifacts --no-build /p:packageversion=$version |
|
||||
if ($LASTEXITCODE ){ Exit $LASTEXITCODE } |
|
||||
|
|
||||
dotnet pack ./src/ImageSharp.Drawing/ -c Release --output ../../artifacts --no-build /p:packageversion=$version |
|
||||
if ($LASTEXITCODE ){ Exit $LASTEXITCODE } |
|
||||
|
Before Width: | Height: | Size: 7.4 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 2.7 KiB |
@ -0,0 +1,13 @@ |
|||||
|
param( |
||||
|
[Parameter(Mandatory, Position = 0)] |
||||
|
[string]$version, |
||||
|
[Parameter(Mandatory = $true, Position = 1)] |
||||
|
[string]$targetFramework |
||||
|
) |
||||
|
|
||||
|
dotnet clean -c Release |
||||
|
|
||||
|
$repositoryUrl = "https://github.com/$env:GITHUB_REPOSITORY" |
||||
|
|
||||
|
# Building for a specific framework. |
||||
|
dotnet build -c Release -f $targetFramework /p:packageversion=$version /p:RepositoryUrl=$repositoryUrl |
||||
@ -0,0 +1,11 @@ |
|||||
|
param( |
||||
|
[Parameter(Mandatory, Position = 0)] |
||||
|
[string]$version |
||||
|
) |
||||
|
|
||||
|
dotnet clean -c Release |
||||
|
|
||||
|
$repositoryUrl = "https://github.com/$env:GITHUB_REPOSITORY" |
||||
|
|
||||
|
# Building for packing and publishing. |
||||
|
dotnet pack -c Release --output "$PSScriptRoot/artifacts" /p:packageversion=$version /p:RepositoryUrl=$repositoryUrl |
||||
@ -0,0 +1,37 @@ |
|||||
|
param( |
||||
|
[Parameter(Mandatory, Position = 0)] |
||||
|
[string]$os, |
||||
|
[Parameter(Mandatory, Position = 1)] |
||||
|
[string]$targetFramework, |
||||
|
[Parameter(Mandatory, Position = 2)] |
||||
|
[string]$platform, |
||||
|
[Parameter(Mandatory, Position = 3)] |
||||
|
[string]$codecov, |
||||
|
[Parameter(Position = 4)] |
||||
|
[string]$codecovProfile = 'Release' |
||||
|
) |
||||
|
|
||||
|
$netFxRegex = '^net\d+' |
||||
|
|
||||
|
if ($codecov -eq 'true') { |
||||
|
|
||||
|
# Allow toggling of profile to workaround any potential JIT errors caused by code injection. |
||||
|
dotnet clean -c $codecovProfile |
||||
|
dotnet test --collect "XPlat Code Coverage" --settings .\tests\coverlet.runsettings -c $codecovProfile -f $targetFramework /p:CodeCov=true |
||||
|
} |
||||
|
elseif ($platform -eq '-x86' -and $targetFramework -match $netFxRegex) { |
||||
|
|
||||
|
# xunit doesn't run on core with NET SDK 3.1+. |
||||
|
# xunit doesn't actually understand -x64 as an option. |
||||
|
# |
||||
|
# xunit requires explicit path. |
||||
|
Set-Location $env:XUNIT_PATH |
||||
|
|
||||
|
dotnet xunit --no-build -c Release -f $targetFramework ${fxVersion} $platform |
||||
|
|
||||
|
Set-Location $PSScriptRoot |
||||
|
} |
||||
|
else { |
||||
|
|
||||
|
dotnet test --no-build -c Release -f $targetFramework |
||||
|
} |
||||
@ -1,4 +1,11 @@ |
|||||
ignore: |
# Documentation: https://docs.codecov.io/docs/codecov-yaml |
||||
"src/ImageSharp/Common/Helpers/DebugGuard.cs" |
|
||||
|
|
||||
|
codecov: |
||||
|
# Avoid "Missing base report" |
||||
|
# https://github.com/codecov/support/issues/363 |
||||
|
# https://docs.codecov.io/docs/comparing-commits |
||||
|
allow_coverage_offsets: true |
||||
|
|
||||
|
# Avoid Report Expired |
||||
|
# https://docs.codecov.io/docs/codecov-yaml#section-expired-reports |
||||
|
max_report_age: off |
||||
|
|||||
@ -1,112 +0,0 @@ |
|||||
param( |
|
||||
[string]$targetFramework, |
|
||||
[string]$is32Bit = "False" |
|
||||
) |
|
||||
|
|
||||
if (!$targetFramework){ |
|
||||
Write-Host "run-tests.ps1 ERROR: targetFramework is undefined!" |
|
||||
exit 1 |
|
||||
} |
|
||||
|
|
||||
function VerifyPath($path, $errorMessage) { |
|
||||
if (!(Test-Path -Path $path)) { |
|
||||
Write-Host "run-tests.ps1 $errorMessage `n $xunitRunnerPath" |
|
||||
exit 1 |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
function CheckSubmoduleStatus() { |
|
||||
$submoduleStatus = (git submodule status) | Out-String |
|
||||
# if the result string is empty, the command failed to run (we didn't capture the error stream) |
|
||||
if ($submoduleStatus) { |
|
||||
# git has been called successfully, what about the status? |
|
||||
if (($submoduleStatus -match "\-") -or ($submoduleStatus -match "\(\(null\)\)")) |
|
||||
{ |
|
||||
# submodule has not been initialized! |
|
||||
return 2; |
|
||||
} |
|
||||
elseif ($submoduleStatus -match "\+") |
|
||||
{ |
|
||||
# submodule is not synced: |
|
||||
return 1; |
|
||||
} |
|
||||
else { |
|
||||
# everything fine: |
|
||||
return 0; |
|
||||
} |
|
||||
} else { |
|
||||
# git call failed, so we should warn |
|
||||
return 3; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
|
|
||||
if ( ($targetFramework -eq "netcoreapp2.1") -and ($env:CI -eq "True") -and ($is32Bit -ne "True")) { |
|
||||
# We execute CodeCoverage.cmd only for one specific job on CI (netcoreapp2.1 + 64bit ) |
|
||||
$testRunnerCmd = ".\tests\CodeCoverage\CodeCoverage.cmd" |
|
||||
} |
|
||||
elseif ($targetFramework -eq "mono") { |
|
||||
$testDllPath = "$PSScriptRoot\tests\ImageSharp.Tests\bin\Release\net462\SixLabors.ImageSharp.Tests.dll" |
|
||||
VerifyPath($testDllPath, "test dll missing:") |
|
||||
|
|
||||
$xunitRunnerPath = "${env:HOMEPATH}\.nuget\packages\xunit.runner.console\2.3.1\tools\net452\" |
|
||||
|
|
||||
VerifyPath($xunitRunnerPath, "xunit console runner is missing on path:") |
|
||||
|
|
||||
cd "$xunitRunnerPath" |
|
||||
|
|
||||
if ($is32Bit -ne "True") { |
|
||||
$monoPath = "${env:PROGRAMFILES}\Mono\bin\mono.exe" |
|
||||
} |
|
||||
else { |
|
||||
$monoPath = "${env:ProgramFiles(x86)}\Mono\bin\mono.exe" |
|
||||
} |
|
||||
|
|
||||
VerifyPath($monoPath, "mono runtime missing:") |
|
||||
|
|
||||
$testRunnerCmd = "& `"${monoPath}`" .\xunit.console.exe `"${testDllPath}`"" |
|
||||
} |
|
||||
else { |
|
||||
cd .\tests\ImageSharp.Tests |
|
||||
$xunitArgs = "-nobuild -c Release -framework $targetFramework" |
|
||||
|
|
||||
if ($targetFramework -eq "netcoreapp2.1") { |
|
||||
# There were issues matching the correct installed runtime if we do not specify it explicitly: |
|
||||
$xunitArgs += " --fx-version 2.1.0" |
|
||||
} |
|
||||
|
|
||||
if ($is32Bit -eq "True") { |
|
||||
$xunitArgs += " -x86" |
|
||||
} |
|
||||
|
|
||||
$testRunnerCmd = "dotnet xunit $xunitArgs" |
|
||||
} |
|
||||
|
|
||||
Write-Host "running:" |
|
||||
Write-Host $testRunnerCmd |
|
||||
Write-Host "..." |
|
||||
|
|
||||
Invoke-Expression $testRunnerCmd |
|
||||
|
|
||||
cd $PSScriptRoot |
|
||||
|
|
||||
$exitCodeOfTests = $LASTEXITCODE; |
|
||||
|
|
||||
if (0 -ne ([int]$exitCodeOfTests)) { |
|
||||
# check submodule status |
|
||||
$submoduleStatus = CheckSubmoduleStatus |
|
||||
if ([int]$submoduleStatus -eq 1) { |
|
||||
# not synced |
|
||||
Write-Host -ForegroundColor Yellow "Check if submodules are up to date. You can use 'git submodule update' to fix this"; |
|
||||
} elseif ($submoduleStatus -eq 2) { |
|
||||
# not initialized |
|
||||
Write-Host -ForegroundColor Yellow "Check if submodules are initialized. You can run 'git submodule init' to initialize them." |
|
||||
} elseif ($submoduleStatus -eq 3) { |
|
||||
# git not found, maybe submodules not synced? |
|
||||
Write-Host -ForegroundColor Yellow "Could not check if submodules are initialized correctly. Maybe git is not installed?" |
|
||||
} else { |
|
||||
#Write-Host "Submodules are up to date"; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
exit $exitCodeOfTests |
|
||||
@ -0,0 +1,39 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<Project> |
||||
|
|
||||
|
<!-- |
||||
|
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 |
||||
|
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 Project="$(MSBuildThisFileDirectory)..\Directory.Build.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<CodeAnalysisRuleSet>$(MSBuildThisFileDirectory)..\shared-infrastructure\SixLabors.ruleset</CodeAnalysisRuleSet> |
||||
|
<GenerateDocumentationFile>true</GenerateDocumentationFile> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<PropertyGroup Condition="'$(Configuration)' == 'Release'"> |
||||
|
<TreatWarningsAsErrors>true</TreatWarningsAsErrors> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<!-- DynamicProxyGenAssembly2 is needed so Moq can use our internals --> |
||||
|
<InternalsVisibleTo Include="DynamicProxyGenAssembly2" PublicKey="0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7" /> |
||||
|
<InternalsVisibleTo Include="ImageSharp.Benchmarks" PublicKey="$(SixLaborsPublicKey)" /> |
||||
|
<InternalsVisibleTo Include="ImageSharp.Tests.ProfilingSandbox" PublicKey="$(SixLaborsPublicKey)" /> |
||||
|
<InternalsVisibleTo Include="SixLabors.ImageSharp.Tests" PublicKey="$(SixLaborsPublicKey)" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
|
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,75 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<Project> |
||||
|
|
||||
|
<!-- |
||||
|
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 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 Project="$(MSBuildThisFileDirectory)..\Directory.Build.targets" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<GeneratedInternalsVisibleToFile Condition="'$(GeneratedInternalsVisibleToFile)' == ''">$(IntermediateOutputPath)$(MSBuildProjectName).InternalsVisibleTo$(DefaultLanguageSourceExtension)</GeneratedInternalsVisibleToFile> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<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.PublicKey)' == ''"> |
||||
|
<Output TaskParameter="Include" ItemName="InternalsVisibleToAttribute" /> |
||||
|
</CreateItem> |
||||
|
<CreateItem Include="System.Runtime.CompilerServices.InternalsVisibleToAttribute" AdditionalMetadata="_Parameter1=%(InternalsVisibleTo.Identity), PublicKey=%(InternalsVisibleTo.PublicKey)" Condition="'%(InternalsVisibleTo.PublicKey)' != ''"> |
||||
|
<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'"/> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<!--Shared config files that have to exist at root level.--> |
||||
|
<ConfigFilesToCopy Include="..\..\shared-infrastructure\.editorconfig;..\..\shared-infrastructure\.gitattributes" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<!--Ensures our config files are up to date.--> |
||||
|
<Target Name="CopyFiles" BeforeTargets="Build"> |
||||
|
<Copy SourceFiles="@(ConfigFilesToCopy)" |
||||
|
SkipUnchangedFiles = "true" |
||||
|
DestinationFolder="..\..\" /> |
||||
|
</Target> |
||||
|
|
||||
|
<!-- Allows regenerating T4-generated files at build time using MsBuild --> |
||||
|
<!-- Enable on Windows OS to build all T4 templates. TODO: XPlat |
||||
|
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TextTemplating\Microsoft.TextTemplating.targets" /> |
||||
|
<PropertyGroup> |
||||
|
<TransformOnBuild>true</TransformOnBuild> |
||||
|
</PropertyGroup> |
||||
|
--> |
||||
|
|
||||
|
</Project> |
||||
@ -1,53 +0,0 @@ |
|||||
<Project Sdk="Microsoft.NET.Sdk"> |
|
||||
<PropertyGroup> |
|
||||
<AssemblyTitle>SixLabors.ImageSharp.Drawing</AssemblyTitle> |
|
||||
<Authors>SixLabors and contributors</Authors> |
|
||||
<Company>Six Labors</Company> |
|
||||
<Copyright>Copyright (c) Six Labors and contributors.</Copyright> |
|
||||
<Product>SixLabors.ImageSharp</Product> |
|
||||
<Description>An extension to ImageSharp that allows the drawing of images, paths, and text.</Description> |
|
||||
<NeutralLanguage>en</NeutralLanguage> |
|
||||
|
|
||||
<VersionPrefix Condition="$(packageversion) != ''">$(packageversion)</VersionPrefix> |
|
||||
<VersionPrefix Condition="$(packageversion) == ''">0.0.1</VersionPrefix> |
|
||||
<TargetFrameworks>netcoreapp2.1;netstandard1.3;netstandard2.0</TargetFrameworks> |
|
||||
<LangVersion>7.3</LangVersion> |
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> |
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile> |
|
||||
<AssemblyName>SixLabors.ImageSharp.Drawing</AssemblyName> |
|
||||
<PackageId>SixLabors.ImageSharp.Drawing</PackageId> |
|
||||
<PackageTags>Image Draw Shape Path Font</PackageTags> |
|
||||
<PackageIconUrl>https://raw.githubusercontent.com/SixLabors/Branding/master/icons/imagesharp/sixlabors.imagesharp.128.png</PackageIconUrl> |
|
||||
<PackageProjectUrl>https://github.com/SixLabors/ImageSharp</PackageProjectUrl> |
|
||||
<PackageLicenseUrl>http://www.apache.org/licenses/LICENSE-2.0</PackageLicenseUrl> |
|
||||
<RepositoryType>git</RepositoryType> |
|
||||
<RepositoryUrl>https://github.com/SixLabors/ImageSharp</RepositoryUrl> |
|
||||
<DebugType Condition="$(codecov) != ''">full</DebugType> |
|
||||
<DebugType Condition="$(codecov) == ''">portable</DebugType> |
|
||||
<DebugSymbols>True</DebugSymbols> |
|
||||
</PropertyGroup> |
|
||||
|
|
||||
<ItemGroup> |
|
||||
<Compile Include="..\Shared\*.cs" Exclude="bin\**;obj\**;**\*.xproj;packages\**" /> |
|
||||
</ItemGroup> |
|
||||
|
|
||||
<ItemGroup> |
|
||||
<ProjectReference Include="..\ImageSharp\ImageSharp.csproj" /> |
|
||||
</ItemGroup> |
|
||||
|
|
||||
<ItemGroup> |
|
||||
<AdditionalFiles Include="..\..\standards\stylecop.json" /> |
|
||||
<PackageReference Include="SixLabors.Fonts" Version="1.0.0-beta0008" /> |
|
||||
<PackageReference Include="SixLabors.Shapes" Version="1.0.0-beta0008" /> |
|
||||
<PackageReference Include="StyleCop.Analyzers" Version="1.1.1-beta.61" PrivateAssets="All" /> |
|
||||
</ItemGroup> |
|
||||
|
|
||||
<PropertyGroup> |
|
||||
<CodeAnalysisRuleSet>..\..\standards\SixLabors.ruleset</CodeAnalysisRuleSet> |
|
||||
<RootNamespace>SixLabors.ImageSharp</RootNamespace> |
|
||||
</PropertyGroup> |
|
||||
|
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' "> |
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors> |
|
||||
</PropertyGroup> |
|
||||
</Project> |
|
||||
@ -1,36 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using System; |
|
||||
using SixLabors.Primitives; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Primitives |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Represents a region of an image.
|
|
||||
/// </summary>
|
|
||||
public abstract class Region |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Gets the maximum number of intersections to could be returned.
|
|
||||
/// </summary>
|
|
||||
public abstract int MaxIntersections { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the bounding box that entirely surrounds this region.
|
|
||||
/// </summary>
|
|
||||
/// <remarks>
|
|
||||
/// This should always contains all possible points returned from <see cref="Scan"/>.
|
|
||||
/// </remarks>
|
|
||||
public abstract Rectangle Bounds { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Scans the X axis for intersections at the Y axis position.
|
|
||||
/// </summary>
|
|
||||
/// <param name="y">The position along the y axis to find intersections.</param>
|
|
||||
/// <param name="buffer">The buffer.</param>
|
|
||||
/// <param name="configuration">A <see cref="Configuration"/> instance in the context of the caller.</param>
|
|
||||
/// <returns>The number of intersections found.</returns>
|
|
||||
public abstract int Scan(float y, Span<float> buffer, Configuration configuration); |
|
||||
} |
|
||||
} |
|
||||
@ -1,24 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using SixLabors.ImageSharp.Processing; |
|
||||
using SixLabors.Shapes; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Primitives |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// A mapping between a <see cref="IPath"/> and a region.
|
|
||||
/// </summary>
|
|
||||
internal class ShapePath : ShapeRegion |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="ShapePath"/> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="shape">The shape.</param>
|
|
||||
/// <param name="pen">The pen to apply to the shape.</param>
|
|
||||
public ShapePath(IPath shape, IPen pen) |
|
||||
: base(shape.GenerateOutline(pen.StrokeWidth, pen.StrokePattern)) |
|
||||
{ |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,65 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using System; |
|
||||
using System.Buffers; |
|
||||
|
|
||||
using SixLabors.ImageSharp.Memory; |
|
||||
using SixLabors.Memory; |
|
||||
using SixLabors.Primitives; |
|
||||
using SixLabors.Shapes; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Primitives |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// A mapping between a <see cref="IPath"/> and a region.
|
|
||||
/// </summary>
|
|
||||
internal class ShapeRegion : Region |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="ShapeRegion"/> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="shape">The shape.</param>
|
|
||||
public ShapeRegion(IPath shape) |
|
||||
{ |
|
||||
this.Shape = shape.AsClosedPath(); |
|
||||
int left = (int)MathF.Floor(shape.Bounds.Left); |
|
||||
int top = (int)MathF.Floor(shape.Bounds.Top); |
|
||||
|
|
||||
int right = (int)MathF.Ceiling(shape.Bounds.Right); |
|
||||
int bottom = (int)MathF.Ceiling(shape.Bounds.Bottom); |
|
||||
this.Bounds = Rectangle.FromLTRB(left, top, right, bottom); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the fillable shape
|
|
||||
/// </summary>
|
|
||||
public IPath Shape { get; } |
|
||||
|
|
||||
/// <inheritdoc/>
|
|
||||
public override int MaxIntersections => this.Shape.MaxIntersections; |
|
||||
|
|
||||
/// <inheritdoc/>
|
|
||||
public override Rectangle Bounds { get; } |
|
||||
|
|
||||
/// <inheritdoc/>
|
|
||||
public override int Scan(float y, Span<float> buffer, Configuration configuration) |
|
||||
{ |
|
||||
var start = new PointF(this.Bounds.Left - 1, y); |
|
||||
var end = new PointF(this.Bounds.Right + 1, y); |
|
||||
|
|
||||
using (IMemoryOwner<PointF> tempBuffer = configuration.MemoryAllocator.Allocate<PointF>(buffer.Length)) |
|
||||
{ |
|
||||
Span<PointF> innerBuffer = tempBuffer.GetSpan(); |
|
||||
int count = this.Shape.FindIntersections(start, end, innerBuffer); |
|
||||
|
|
||||
for (int i = 0; i < count; i++) |
|
||||
{ |
|
||||
buffer[i] = innerBuffer[i].X; |
|
||||
} |
|
||||
|
|
||||
return count; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,96 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using System; |
|
||||
using System.Buffers; |
|
||||
|
|
||||
using SixLabors.ImageSharp.Advanced; |
|
||||
using SixLabors.ImageSharp.Memory; |
|
||||
using SixLabors.ImageSharp.PixelFormats; |
|
||||
using SixLabors.Memory; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Processing |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// primitive that converts a point in to a color for discovering the fill color based on an implementation
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|
||||
/// <seealso cref="System.IDisposable" />
|
|
||||
public abstract class BrushApplicator<TPixel> : IDisposable // disposable will be required if/when there is an ImageBrush
|
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="BrushApplicator{TPixel}"/> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="target">The target.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
internal BrushApplicator(ImageFrame<TPixel> target, GraphicsOptions options) |
|
||||
{ |
|
||||
this.Target = target; |
|
||||
this.Options = options; |
|
||||
this.Blender = PixelOperations<TPixel>.Instance.GetPixelBlender(options); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the blender
|
|
||||
/// </summary>
|
|
||||
internal PixelBlender<TPixel> Blender { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the destination
|
|
||||
/// </summary>
|
|
||||
protected ImageFrame<TPixel> Target { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the blend percentage
|
|
||||
/// </summary>
|
|
||||
protected GraphicsOptions Options { get; private set; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the color for a single pixel.
|
|
||||
/// </summary>
|
|
||||
/// <param name="x">The x coordinate.</param>
|
|
||||
/// <param name="y">The y coordinate.</param>
|
|
||||
/// <returns>The a <typeparamref name="TPixel"/> that should be applied to the pixel.</returns>
|
|
||||
internal abstract TPixel this[int x, int y] { get; } |
|
||||
|
|
||||
/// <inheritdoc/>
|
|
||||
public abstract void Dispose(); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Applies the opacity weighting for each pixel in a scanline to the target based on the pattern contained in the brush.
|
|
||||
/// </summary>
|
|
||||
/// <param name="scanline">The a collection of opacity values between 0 and 1 to be merged with the brushed color value before being applied to the target.</param>
|
|
||||
/// <param name="x">The x position in the target pixel space that the start of the scanline data corresponds to.</param>
|
|
||||
/// <param name="y">The y position in the target pixel space that whole scanline corresponds to.</param>
|
|
||||
/// <remarks>scanlineBuffer will be > scanlineWidth but provide and offset in case we want to share a larger buffer across runs.</remarks>
|
|
||||
internal virtual void Apply(Span<float> scanline, int x, int y) |
|
||||
{ |
|
||||
MemoryAllocator memoryAllocator = this.Target.MemoryAllocator; |
|
||||
|
|
||||
using (IMemoryOwner<float> amountBuffer = memoryAllocator.Allocate<float>(scanline.Length)) |
|
||||
using (IMemoryOwner<TPixel> overlay = memoryAllocator.Allocate<TPixel>(scanline.Length)) |
|
||||
{ |
|
||||
Span<float> amountSpan = amountBuffer.GetSpan(); |
|
||||
Span<TPixel> overlaySpan = overlay.GetSpan(); |
|
||||
|
|
||||
for (int i = 0; i < scanline.Length; i++) |
|
||||
{ |
|
||||
if (this.Options.BlendPercentage < 1) |
|
||||
{ |
|
||||
amountSpan[i] = scanline[i] * this.Options.BlendPercentage; |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
amountSpan[i] = scanline[i]; |
|
||||
} |
|
||||
|
|
||||
overlaySpan[i] = this[x + i, y]; |
|
||||
} |
|
||||
|
|
||||
Span<TPixel> destinationRow = this.Target.GetPixelRowSpan(y).Slice(x, scanline.Length); |
|
||||
this.Blender.Blend(this.Target.Configuration, destinationRow, destinationRow, overlaySpan, amountSpan); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,256 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using SixLabors.ImageSharp.PixelFormats; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Processing |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// A collection of methods for creating generic brushes.
|
|
||||
/// </summary>
|
|
||||
/// <returns>A New <see cref="PatternBrush{TPixel}"/></returns>
|
|
||||
public static class Brushes |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Percent10 Hatch Pattern
|
|
||||
/// </summary>
|
|
||||
/// ---> x axis
|
|
||||
/// ^
|
|
||||
/// | y - axis
|
|
||||
/// |
|
|
||||
/// see PatternBrush for details about how to make new patterns work
|
|
||||
private static readonly bool[,] Percent10Pattern = |
|
||||
{ |
|
||||
{ true, false, false, false }, |
|
||||
{ false, false, false, false }, |
|
||||
{ false, false, true, false }, |
|
||||
{ false, false, false, false } |
|
||||
}; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Percent20 pattern.
|
|
||||
/// </summary>
|
|
||||
private static readonly bool[,] Percent20Pattern = |
|
||||
{ |
|
||||
{ true, false, false, false }, |
|
||||
{ false, false, true, false }, |
|
||||
{ true, false, false, false }, |
|
||||
{ false, false, true, false } |
|
||||
}; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Horizontal Hatch Pattern
|
|
||||
/// </summary>
|
|
||||
private static readonly bool[,] HorizontalPattern = |
|
||||
{ |
|
||||
{ false }, |
|
||||
{ true }, |
|
||||
{ false }, |
|
||||
{ false } |
|
||||
}; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Min Pattern
|
|
||||
/// </summary>
|
|
||||
private static readonly bool[,] MinPattern = |
|
||||
{ |
|
||||
{ false }, |
|
||||
{ false }, |
|
||||
{ false }, |
|
||||
{ true } |
|
||||
}; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Vertical Pattern
|
|
||||
/// </summary>
|
|
||||
private static readonly bool[,] VerticalPattern = |
|
||||
{ |
|
||||
{ false, true, false, false }, |
|
||||
}; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Forward Diagonal Pattern
|
|
||||
/// </summary>
|
|
||||
private static readonly bool[,] ForwardDiagonalPattern = |
|
||||
{ |
|
||||
{ false, false, false, true }, |
|
||||
{ false, false, true, false }, |
|
||||
{ false, true, false, false }, |
|
||||
{ true, false, false, false } |
|
||||
}; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Backward Diagonal Pattern
|
|
||||
/// </summary>
|
|
||||
private static readonly bool[,] BackwardDiagonalPattern = |
|
||||
{ |
|
||||
{ true, false, false, false }, |
|
||||
{ false, true, false, false }, |
|
||||
{ false, false, true, false }, |
|
||||
{ false, false, false, true } |
|
||||
}; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Create as brush that will paint a solid color
|
|
||||
/// </summary>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|
||||
/// <returns>A New <see cref="PatternBrush{TPixel}"/></returns>
|
|
||||
public static SolidBrush<TPixel> Solid<TPixel>(TPixel color) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> new SolidBrush<TPixel>(color); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Create as brush that will paint a Percent10 Hatch Pattern with the specified colors
|
|
||||
/// </summary>
|
|
||||
/// <param name="foreColor">Color of the foreground.</param>
|
|
||||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|
||||
/// <returns>A New <see cref="PatternBrush{TPixel}"/></returns>
|
|
||||
public static PatternBrush<TPixel> Percent10<TPixel>(TPixel foreColor) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> new PatternBrush<TPixel>(foreColor, NamedColors<TPixel>.Transparent, Percent10Pattern); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Create as brush that will paint a Percent10 Hatch Pattern with the specified colors
|
|
||||
/// </summary>
|
|
||||
/// <param name="foreColor">Color of the foreground.</param>
|
|
||||
/// <param name="backColor">Color of the background.</param>
|
|
||||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|
||||
/// <returns>A New <see cref="PatternBrush{TPixel}"/></returns>
|
|
||||
public static PatternBrush<TPixel> Percent10<TPixel>(TPixel foreColor, TPixel backColor) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> new PatternBrush<TPixel>(foreColor, backColor, Percent10Pattern); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Create as brush that will paint a Percent20 Hatch Pattern with the specified foreground color and a
|
|
||||
/// transparent background.
|
|
||||
/// </summary>
|
|
||||
/// <param name="foreColor">Color of the foreground.</param>
|
|
||||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|
||||
/// <returns>A New <see cref="PatternBrush{TPixel}"/></returns>
|
|
||||
public static PatternBrush<TPixel> Percent20<TPixel>(TPixel foreColor) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> new PatternBrush<TPixel>(foreColor, NamedColors<TPixel>.Transparent, Percent20Pattern); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Create as brush that will paint a Percent20 Hatch Pattern with the specified colors
|
|
||||
/// </summary>
|
|
||||
/// <param name="foreColor">Color of the foreground.</param>
|
|
||||
/// <param name="backColor">Color of the background.</param>
|
|
||||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|
||||
/// <returns>A New <see cref="PatternBrush{TPixel}"/></returns>
|
|
||||
public static PatternBrush<TPixel> Percent20<TPixel>(TPixel foreColor, TPixel backColor) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> new PatternBrush<TPixel>(foreColor, backColor, Percent20Pattern); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Create as brush that will paint a Horizontal Hatch Pattern with the specified foreground color and a
|
|
||||
/// transparent background.
|
|
||||
/// </summary>
|
|
||||
/// <param name="foreColor">Color of the foreground.</param>
|
|
||||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|
||||
/// <returns>A New <see cref="PatternBrush{TPixel}"/></returns>
|
|
||||
public static PatternBrush<TPixel> Horizontal<TPixel>(TPixel foreColor) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> new PatternBrush<TPixel>(foreColor, NamedColors<TPixel>.Transparent, HorizontalPattern); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Create as brush that will paint a Horizontal Hatch Pattern with the specified colors
|
|
||||
/// </summary>
|
|
||||
/// <param name="foreColor">Color of the foreground.</param>
|
|
||||
/// <param name="backColor">Color of the background.</param>
|
|
||||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|
||||
/// <returns>A New <see cref="PatternBrush{TPixel}"/></returns>
|
|
||||
public static PatternBrush<TPixel> Horizontal<TPixel>(TPixel foreColor, TPixel backColor) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> new PatternBrush<TPixel>(foreColor, backColor, HorizontalPattern); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Create as brush that will paint a Min Hatch Pattern with the specified foreground color and a
|
|
||||
/// transparent background.
|
|
||||
/// </summary>
|
|
||||
/// <param name="foreColor">Color of the foreground.</param>
|
|
||||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|
||||
/// <returns>A New <see cref="PatternBrush{TPixel}"/></returns>
|
|
||||
public static PatternBrush<TPixel> Min<TPixel>(TPixel foreColor) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> new PatternBrush<TPixel>(foreColor, NamedColors<TPixel>.Transparent, MinPattern); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Create as brush that will paint a Min Hatch Pattern with the specified colors
|
|
||||
/// </summary>
|
|
||||
/// <param name="foreColor">Color of the foreground.</param>
|
|
||||
/// <param name="backColor">Color of the background.</param>
|
|
||||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|
||||
/// <returns>A New <see cref="PatternBrush{TPixel}"/></returns>
|
|
||||
public static PatternBrush<TPixel> Min<TPixel>(TPixel foreColor, TPixel backColor) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> new PatternBrush<TPixel>(foreColor, backColor, MinPattern); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Create as brush that will paint a Vertical Hatch Pattern with the specified foreground color and a
|
|
||||
/// transparent background.
|
|
||||
/// </summary>
|
|
||||
/// <param name="foreColor">Color of the foreground.</param>
|
|
||||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|
||||
/// <returns>A New <see cref="PatternBrush{TPixel}"/></returns>
|
|
||||
public static PatternBrush<TPixel> Vertical<TPixel>(TPixel foreColor) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> new PatternBrush<TPixel>(foreColor, NamedColors<TPixel>.Transparent, VerticalPattern); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Create as brush that will paint a Vertical Hatch Pattern with the specified colors
|
|
||||
/// </summary>
|
|
||||
/// <param name="foreColor">Color of the foreground.</param>
|
|
||||
/// <param name="backColor">Color of the background.</param>
|
|
||||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|
||||
/// <returns>A New <see cref="PatternBrush{TPixel}"/></returns>
|
|
||||
public static PatternBrush<TPixel> Vertical<TPixel>(TPixel foreColor, TPixel backColor) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> new PatternBrush<TPixel>(foreColor, backColor, VerticalPattern); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Create as brush that will paint a Forward Diagonal Hatch Pattern with the specified foreground color and a
|
|
||||
/// transparent background.
|
|
||||
/// </summary>
|
|
||||
/// <param name="foreColor">Color of the foreground.</param>
|
|
||||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|
||||
/// <returns>A New <see cref="PatternBrush{TPixel}"/></returns>
|
|
||||
public static PatternBrush<TPixel> ForwardDiagonal<TPixel>(TPixel foreColor) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> new PatternBrush<TPixel>(foreColor, NamedColors<TPixel>.Transparent, ForwardDiagonalPattern); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Create as brush that will paint a Forward Diagonal Hatch Pattern with the specified colors
|
|
||||
/// </summary>
|
|
||||
/// <param name="foreColor">Color of the foreground.</param>
|
|
||||
/// <param name="backColor">Color of the background.</param>
|
|
||||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|
||||
/// <returns>A New <see cref="PatternBrush{TPixel}"/></returns>
|
|
||||
public static PatternBrush<TPixel> ForwardDiagonal<TPixel>(TPixel foreColor, TPixel backColor) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> new PatternBrush<TPixel>(foreColor, backColor, ForwardDiagonalPattern); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Create as brush that will paint a Backward Diagonal Hatch Pattern with the specified foreground color and a
|
|
||||
/// transparent background.
|
|
||||
/// </summary>
|
|
||||
/// <param name="foreColor">Color of the foreground.</param>
|
|
||||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|
||||
/// <returns>A New <see cref="PatternBrush{TPixel}"/></returns>
|
|
||||
public static PatternBrush<TPixel> BackwardDiagonal<TPixel>(TPixel foreColor) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> new PatternBrush<TPixel>(foreColor, NamedColors<TPixel>.Transparent, BackwardDiagonalPattern); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Create as brush that will paint a Backward Diagonal Hatch Pattern with the specified colors
|
|
||||
/// </summary>
|
|
||||
/// <param name="foreColor">Color of the foreground.</param>
|
|
||||
/// <param name="backColor">Color of the background.</param>
|
|
||||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|
||||
/// <returns>A New <see cref="PatternBrush{TPixel}"/></returns>
|
|
||||
public static PatternBrush<TPixel> BackwardDiagonal<TPixel>(TPixel foreColor, TPixel backColor) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> new PatternBrush<TPixel>(foreColor, backColor, BackwardDiagonalPattern); |
|
||||
} |
|
||||
} |
|
||||
@ -1,39 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using System.Diagnostics; |
|
||||
|
|
||||
using SixLabors.ImageSharp.PixelFormats; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Processing |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// A struct that defines a single color stop.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|
||||
[DebuggerDisplay("ColorStop({Ratio} -> {Color}")] |
|
||||
public struct ColorStop<TPixel> |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="ColorStop{TPixel}" /> struct.
|
|
||||
/// </summary>
|
|
||||
/// <param name="ratio">Where should it be? 0 is at the start, 1 at the end of the Gradient.</param>
|
|
||||
/// <param name="color">What color should be used at that point?</param>
|
|
||||
public ColorStop(float ratio, TPixel color) |
|
||||
{ |
|
||||
this.Ratio = ratio; |
|
||||
this.Color = color; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the point along the defined gradient axis.
|
|
||||
/// </summary>
|
|
||||
public float Ratio { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the color to be used.
|
|
||||
/// </summary>
|
|
||||
public TPixel Color { get; } |
|
||||
} |
|
||||
} |
|
||||
@ -1,94 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using SixLabors.ImageSharp.PixelFormats; |
|
||||
using SixLabors.Primitives; |
|
||||
using SixLabors.Shapes; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Processing |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Adds extensions that allow the drawing of Bezier paths to the <see cref="Image{TPixel}"/> type.
|
|
||||
/// </summary>
|
|
||||
public static class DrawBezierExtensions |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Draws the provided points as an open Bezier path at the provided thickness with the supplied brush
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> DrawBeziers<TPixel>(this IImageProcessingContext<TPixel> source, GraphicsOptions options, IBrush<TPixel> brush, float thickness, params PointF[] points) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Draw(options, new Pen<TPixel>(brush, thickness), new Path(new CubicBezierLineSegment(points))); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the provided points as an open Bezier path at the provided thickness with the supplied brush
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> DrawBeziers<TPixel>(this IImageProcessingContext<TPixel> source, IBrush<TPixel> brush, float thickness, params PointF[] points) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Draw(new Pen<TPixel>(brush, thickness), new Path(new CubicBezierLineSegment(points))); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the provided points as an open Bezier path at the provided thickness with the supplied brush
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> DrawBeziers<TPixel>(this IImageProcessingContext<TPixel> source, TPixel color, float thickness, params PointF[] points) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.DrawBeziers(new SolidBrush<TPixel>(color), thickness, points); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the provided points as an open Bezier path at the provided thickness with the supplied brush
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> DrawBeziers<TPixel>(this IImageProcessingContext<TPixel> source, GraphicsOptions options, TPixel color, float thickness, params PointF[] points) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.DrawBeziers(options, new SolidBrush<TPixel>(color), thickness, points); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the provided points as an open Bezier path with the supplied pen
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <param name="pen">The pen.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> DrawBeziers<TPixel>(this IImageProcessingContext<TPixel> source, GraphicsOptions options, IPen<TPixel> pen, params PointF[] points) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Draw(options, pen, new Path(new CubicBezierLineSegment(points))); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the provided points as an open Bezier path with the supplied pen
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="pen">The pen.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> DrawBeziers<TPixel>(this IImageProcessingContext<TPixel> source, IPen<TPixel> pen, params PointF[] points) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Draw(pen, new Path(new CubicBezierLineSegment(points))); |
|
||||
} |
|
||||
} |
|
||||
@ -1,137 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using SixLabors.ImageSharp.PixelFormats; |
|
||||
using SixLabors.ImageSharp.Processing.Processors.Drawing; |
|
||||
using SixLabors.Primitives; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Processing |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Adds extensions that allow the drawing of images to the <see cref="Image{TPixel}"/> type.
|
|
||||
/// </summary>
|
|
||||
public static class DrawImageExtensions |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Draws the given image together with the current one by blending their pixels.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixelDst">The pixel format of the destination image.</typeparam>
|
|
||||
/// <typeparam name="TPixelSrc">The pixel format of the source image.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="image">The image to blend with the currently processing image.</param>
|
|
||||
/// <param name="opacity">The opacity of the image to blend. Must be between 0 and 1.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixelDst}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixelDst> DrawImage<TPixelDst, TPixelSrc>(this IImageProcessingContext<TPixelDst> source, Image<TPixelSrc> image, float opacity) |
|
||||
where TPixelDst : struct, IPixel<TPixelDst> |
|
||||
where TPixelSrc : struct, IPixel<TPixelSrc> |
|
||||
=> source.ApplyProcessor(new DrawImageProcessor<TPixelDst, TPixelSrc>(image, Point.Empty, GraphicsOptions.Default.ColorBlendingMode, GraphicsOptions.Default.AlphaCompositionMode, opacity)); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the given image together with the current one by blending their pixels.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixelDst">The pixel format of the destination image.</typeparam>
|
|
||||
/// <typeparam name="TPixelSrc">The pixel format of the source image.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="image">The image to blend with the currently processing image.</param>
|
|
||||
/// <param name="colorBlending">The blending mode.</param>
|
|
||||
/// <param name="opacity">The opacity of the image to blend. Must be between 0 and 1.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixelDst}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixelDst> DrawImage<TPixelDst, TPixelSrc>(this IImageProcessingContext<TPixelDst> source, Image<TPixelSrc> image, PixelColorBlendingMode colorBlending, float opacity) |
|
||||
where TPixelDst : struct, IPixel<TPixelDst> |
|
||||
where TPixelSrc : struct, IPixel<TPixelSrc> |
|
||||
=> source.ApplyProcessor(new DrawImageProcessor<TPixelDst, TPixelSrc>(image, Point.Empty, colorBlending, GraphicsOptions.Default.AlphaCompositionMode, opacity)); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the given image together with the current one by blending their pixels.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixelDst">The pixel format of the destination image.</typeparam>
|
|
||||
/// <typeparam name="TPixelSrc">The pixel format of the source image.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="image">The image to blend with the currently processing image.</param>
|
|
||||
/// <param name="colorBlending">The color blending mode.</param>
|
|
||||
/// <param name="alphaComposition">The alpha composition mode.</param>
|
|
||||
/// <param name="opacity">The opacity of the image to blend. Must be between 0 and 1.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixelDst}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixelDst> DrawImage<TPixelDst, TPixelSrc>(this IImageProcessingContext<TPixelDst> source, Image<TPixelSrc> image, PixelColorBlendingMode colorBlending, PixelAlphaCompositionMode alphaComposition, float opacity) |
|
||||
where TPixelDst : struct, IPixel<TPixelDst> |
|
||||
where TPixelSrc : struct, IPixel<TPixelSrc> |
|
||||
=> source.ApplyProcessor(new DrawImageProcessor<TPixelDst, TPixelSrc>(image, Point.Empty, colorBlending, alphaComposition, opacity)); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the given image together with the current one by blending their pixels.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixelDst">The pixel format of the destination image.</typeparam>
|
|
||||
/// <typeparam name="TPixelSrc">The pixel format of the source image.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="image">The image to blend with the currently processing image.</param>
|
|
||||
/// <param name="options">The options, including the blending type and blending amount.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixelDst}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixelDst> DrawImage<TPixelDst, TPixelSrc>(this IImageProcessingContext<TPixelDst> source, Image<TPixelSrc> image, GraphicsOptions options) |
|
||||
where TPixelDst : struct, IPixel<TPixelDst> |
|
||||
where TPixelSrc : struct, IPixel<TPixelSrc> |
|
||||
=> source.ApplyProcessor(new DrawImageProcessor<TPixelDst, TPixelSrc>(image, Point.Empty, options.ColorBlendingMode, options.AlphaCompositionMode, options.BlendPercentage)); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the given image together with the current one by blending their pixels.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixelDst">The pixel format of the destination image.</typeparam>
|
|
||||
/// <typeparam name="TPixelSrc">The pixel format of the source image.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="image">The image to blend with the currently processing image.</param>
|
|
||||
/// <param name="location">The location to draw the blended image.</param>
|
|
||||
/// <param name="opacity">The opacity of the image to blend. Must be between 0 and 1.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixelDst}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixelDst> DrawImage<TPixelDst, TPixelSrc>(this IImageProcessingContext<TPixelDst> source, Image<TPixelSrc> image, Point location, float opacity) |
|
||||
where TPixelDst : struct, IPixel<TPixelDst> |
|
||||
where TPixelSrc : struct, IPixel<TPixelSrc> |
|
||||
=> source.ApplyProcessor(new DrawImageProcessor<TPixelDst, TPixelSrc>(image, location, GraphicsOptions.Default.ColorBlendingMode, GraphicsOptions.Default.AlphaCompositionMode, opacity)); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the given image together with the current one by blending their pixels.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixelDst">The pixel format of the destination image.</typeparam>
|
|
||||
/// <typeparam name="TPixelSrc">The pixel format of the source image.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="image">The image to blend with the currently processing image.</param>
|
|
||||
/// <param name="location">The location to draw the blended image.</param>
|
|
||||
/// <param name="colorBlending">The color blending to apply.</param>
|
|
||||
/// <param name="opacity">The opacity of the image to blend. Must be between 0 and 1.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixelDst}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixelDst> DrawImage<TPixelDst, TPixelSrc>(this IImageProcessingContext<TPixelDst> source, Image<TPixelSrc> image, Point location, PixelColorBlendingMode colorBlending, float opacity) |
|
||||
where TPixelDst : struct, IPixel<TPixelDst> |
|
||||
where TPixelSrc : struct, IPixel<TPixelSrc> |
|
||||
=> source.ApplyProcessor(new DrawImageProcessor<TPixelDst, TPixelSrc>(image, location, colorBlending, GraphicsOptions.Default.AlphaCompositionMode, opacity)); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the given image together with the current one by blending their pixels.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixelDst">The pixel format of the destination image.</typeparam>
|
|
||||
/// <typeparam name="TPixelSrc">The pixel format of the source image.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="image">The image to blend with the currently processing image.</param>
|
|
||||
/// <param name="location">The location to draw the blended image.</param>
|
|
||||
/// <param name="colorBlending">The color blending to apply.</param>
|
|
||||
/// <param name="alphaComposition">The alpha composition mode.</param>
|
|
||||
/// <param name="opacity">The opacity of the image to blend. Must be between 0 and 1.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixelDst}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixelDst> DrawImage<TPixelDst, TPixelSrc>(this IImageProcessingContext<TPixelDst> source, Image<TPixelSrc> image, Point location, PixelColorBlendingMode colorBlending, PixelAlphaCompositionMode alphaComposition, float opacity) |
|
||||
where TPixelDst : struct, IPixel<TPixelDst> |
|
||||
where TPixelSrc : struct, IPixel<TPixelSrc> |
|
||||
=> source.ApplyProcessor(new DrawImageProcessor<TPixelDst, TPixelSrc>(image, location, colorBlending, alphaComposition, opacity)); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the given image together with the current one by blending their pixels.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixelDst">The pixel format of the destination image.</typeparam>
|
|
||||
/// <typeparam name="TPixelSrc">The pixel format of the source image.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="image">The image to blend with the currently processing image.</param>
|
|
||||
/// <param name="location">The location to draw the blended image.</param>
|
|
||||
/// <param name="options">The options containing the blend mode and opacity.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixelDst}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixelDst> DrawImage<TPixelDst, TPixelSrc>(this IImageProcessingContext<TPixelDst> source, Image<TPixelSrc> image, Point location, GraphicsOptions options) |
|
||||
where TPixelDst : struct, IPixel<TPixelDst> |
|
||||
where TPixelSrc : struct, IPixel<TPixelSrc> |
|
||||
=> source.ApplyProcessor(new DrawImageProcessor<TPixelDst, TPixelSrc>(image, location, options.ColorBlendingMode, options.AlphaCompositionMode, options.BlendPercentage)); |
|
||||
} |
|
||||
} |
|
||||
@ -1,94 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using SixLabors.ImageSharp.PixelFormats; |
|
||||
using SixLabors.Primitives; |
|
||||
using SixLabors.Shapes; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Processing |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Adds extensions that allow the drawing of lines to the <see cref="Image{TPixel}"/> type.
|
|
||||
/// </summary>
|
|
||||
public static class DrawLineExtensions |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Draws the provided Points as an open Linear path at the provided thickness with the supplied brush
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> DrawLines<TPixel>(this IImageProcessingContext<TPixel> source, GraphicsOptions options, IBrush<TPixel> brush, float thickness, params PointF[] points) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Draw(options, new Pen<TPixel>(brush, thickness), new Path(new LinearLineSegment(points))); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the provided Points as an open Linear path at the provided thickness with the supplied brush
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> DrawLines<TPixel>(this IImageProcessingContext<TPixel> source, IBrush<TPixel> brush, float thickness, params PointF[] points) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Draw(new Pen<TPixel>(brush, thickness), new Path(new LinearLineSegment(points))); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the provided Points as an open Linear path at the provided thickness with the supplied brush
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> DrawLines<TPixel>(this IImageProcessingContext<TPixel> source, TPixel color, float thickness, params PointF[] points) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.DrawLines(new SolidBrush<TPixel>(color), thickness, points); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the provided Points as an open Linear path at the provided thickness with the supplied brush
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>>
|
|
||||
public static IImageProcessingContext<TPixel> DrawLines<TPixel>(this IImageProcessingContext<TPixel> source, GraphicsOptions options, TPixel color, float thickness, params PointF[] points) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.DrawLines(options, new SolidBrush<TPixel>(color), thickness, points); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the provided Points as an open Linear path with the supplied pen
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <param name="pen">The pen.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> DrawLines<TPixel>(this IImageProcessingContext<TPixel> source, GraphicsOptions options, IPen<TPixel> pen, params PointF[] points) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Draw(options, pen, new Path(new LinearLineSegment(points))); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the provided Points as an open Linear path with the supplied pen
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="pen">The pen.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> DrawLines<TPixel>(this IImageProcessingContext<TPixel> source, IPen<TPixel> pen, params PointF[] points) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Draw(pen, new Path(new LinearLineSegment(points))); |
|
||||
} |
|
||||
} |
|
||||
@ -1,100 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using SixLabors.ImageSharp.PixelFormats; |
|
||||
using SixLabors.Shapes; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Processing |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Adds extensions that allow the drawing of collections of polygon outlines to the <see cref="Image{TPixel}"/> type.
|
|
||||
/// </summary>
|
|
||||
public static class DrawPathCollectionExtensions |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Draws the outline of the polygon with the provided pen.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <param name="pen">The pen.</param>
|
|
||||
/// <param name="paths">The paths.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> Draw<TPixel>(this IImageProcessingContext<TPixel> source, GraphicsOptions options, IPen<TPixel> pen, IPathCollection paths) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
{ |
|
||||
foreach (IPath path in paths) |
|
||||
{ |
|
||||
source.Draw(options, pen, path); |
|
||||
} |
|
||||
|
|
||||
return source; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the outline of the polygon with the provided pen.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="pen">The pen.</param>
|
|
||||
/// <param name="paths">The paths.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> Draw<TPixel>(this IImageProcessingContext<TPixel> source, IPen<TPixel> pen, IPathCollection paths) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Draw(GraphicsOptions.Default, pen, paths); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the outline of the polygon with the provided brush at the provided thickness.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="paths">The shapes.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> Draw<TPixel>(this IImageProcessingContext<TPixel> source, GraphicsOptions options, IBrush<TPixel> brush, float thickness, IPathCollection paths) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Draw(options, new Pen<TPixel>(brush, thickness), paths); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the outline of the polygon with the provided brush at the provided thickness.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="paths">The paths.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> Draw<TPixel>(this IImageProcessingContext<TPixel> source, IBrush<TPixel> brush, float thickness, IPathCollection paths) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Draw(new Pen<TPixel>(brush, thickness), paths); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the outline of the polygon with the provided brush at the provided thickness.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="paths">The paths.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> Draw<TPixel>(this IImageProcessingContext<TPixel> source, GraphicsOptions options, TPixel color, float thickness, IPathCollection paths) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Draw(options, new SolidBrush<TPixel>(color), thickness, paths); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the outline of the polygon with the provided brush at the provided thickness.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="paths">The paths.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> Draw<TPixel>(this IImageProcessingContext<TPixel> source, TPixel color, float thickness, IPathCollection paths) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Draw(new SolidBrush<TPixel>(color), thickness, paths); |
|
||||
} |
|
||||
} |
|
||||
@ -1,94 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using SixLabors.ImageSharp.PixelFormats; |
|
||||
using SixLabors.ImageSharp.Primitives; |
|
||||
using SixLabors.Shapes; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Processing |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Adds extensions that allow the drawing of polygon outlines to the <see cref="Image{TPixel}"/> type.
|
|
||||
/// </summary>
|
|
||||
public static class DrawPathExtensions |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Draws the outline of the polygon with the provided pen.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <param name="pen">The pen.</param>
|
|
||||
/// <param name="path">The path.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> Draw<TPixel>(this IImageProcessingContext<TPixel> source, GraphicsOptions options, IPen<TPixel> pen, IPath path) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Fill(options, pen.StrokeFill, new ShapePath(path, pen)); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the outline of the polygon with the provided pen.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="pen">The pen.</param>
|
|
||||
/// <param name="path">The path.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> Draw<TPixel>(this IImageProcessingContext<TPixel> source, IPen<TPixel> pen, IPath path) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Draw(GraphicsOptions.Default, pen, path); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the outline of the polygon with the provided brush at the provided thickness.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="path">The shape.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> Draw<TPixel>(this IImageProcessingContext<TPixel> source, GraphicsOptions options, IBrush<TPixel> brush, float thickness, IPath path) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Draw(options, new Pen<TPixel>(brush, thickness), path); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the outline of the polygon with the provided brush at the provided thickness.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="path">The path.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> Draw<TPixel>(this IImageProcessingContext<TPixel> source, IBrush<TPixel> brush, float thickness, IPath path) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Draw(new Pen<TPixel>(brush, thickness), path); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the outline of the polygon with the provided brush at the provided thickness.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="path">The path.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> Draw<TPixel>(this IImageProcessingContext<TPixel> source, GraphicsOptions options, TPixel color, float thickness, IPath path) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Draw(options, new SolidBrush<TPixel>(color), thickness, path); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the outline of the polygon with the provided brush at the provided thickness.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="path">The path.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> Draw<TPixel>(this IImageProcessingContext<TPixel> source, TPixel color, float thickness, IPath path) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Draw(new SolidBrush<TPixel>(color), thickness, path); |
|
||||
} |
|
||||
} |
|
||||
@ -1,94 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using SixLabors.ImageSharp.PixelFormats; |
|
||||
using SixLabors.Primitives; |
|
||||
using SixLabors.Shapes; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Processing |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Adds extensions that allow the drawing of closed linear polygons to the <see cref="Image{TPixel}"/> type.
|
|
||||
/// </summary>
|
|
||||
public static class DrawPolygonExtensions |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Draws the provided Points as a closed Linear Polygon with the provided brush at the provided thickness.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> DrawPolygon<TPixel>(this IImageProcessingContext<TPixel> source, GraphicsOptions options, IBrush<TPixel> brush, float thickness, params PointF[] points) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Draw(options, new Pen<TPixel>(brush, thickness), new Polygon(new LinearLineSegment(points))); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the provided Points as a closed Linear Polygon with the provided brush at the provided thickness.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> DrawPolygon<TPixel>(this IImageProcessingContext<TPixel> source, IBrush<TPixel> brush, float thickness, params PointF[] points) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Draw(new Pen<TPixel>(brush, thickness), new Polygon(new LinearLineSegment(points))); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the provided Points as a closed Linear Polygon with the provided brush at the provided thickness.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> DrawPolygon<TPixel>(this IImageProcessingContext<TPixel> source, TPixel color, float thickness, params PointF[] points) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.DrawPolygon(new SolidBrush<TPixel>(color), thickness, points); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the provided Points as a closed Linear Polygon with the provided brush at the provided thickness.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> DrawPolygon<TPixel>(this IImageProcessingContext<TPixel> source, GraphicsOptions options, TPixel color, float thickness, params PointF[] points) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.DrawPolygon(options, new SolidBrush<TPixel>(color), thickness, points); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the provided Points as a closed Linear Polygon with the provided Pen.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="pen">The pen.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> DrawPolygon<TPixel>(this IImageProcessingContext<TPixel> source, IPen<TPixel> pen, params PointF[] points) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Draw(GraphicsOptions.Default, pen, new Polygon(new LinearLineSegment(points))); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the provided Points as a closed Linear Polygon with the provided Pen.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <param name="pen">The pen.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> DrawPolygon<TPixel>(this IImageProcessingContext<TPixel> source, GraphicsOptions options, IPen<TPixel> pen, params PointF[] points) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Draw(options, pen, new Polygon(new LinearLineSegment(points))); |
|
||||
} |
|
||||
} |
|
||||
@ -1,94 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using SixLabors.ImageSharp.PixelFormats; |
|
||||
using SixLabors.Primitives; |
|
||||
using SixLabors.Shapes; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Processing |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Adds extensions that allow the drawing of rectangles to the <see cref="Image{TPixel}"/> type.
|
|
||||
/// </summary>
|
|
||||
public static class DrawRectangleExtensions |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Draws the outline of the rectangle with the provided pen.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <param name="pen">The pen.</param>
|
|
||||
/// <param name="shape">The shape.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> Draw<TPixel>(this IImageProcessingContext<TPixel> source, GraphicsOptions options, IPen<TPixel> pen, RectangleF shape) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Draw(options, pen, new RectangularPolygon(shape.X, shape.Y, shape.Width, shape.Height)); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the outline of the rectangle with the provided pen.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="pen">The pen.</param>
|
|
||||
/// <param name="shape">The shape.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> Draw<TPixel>(this IImageProcessingContext<TPixel> source, IPen<TPixel> pen, RectangleF shape) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Draw(GraphicsOptions.Default, pen, shape); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the outline of the rectangle with the provided brush at the provided thickness.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="shape">The shape.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> Draw<TPixel>(this IImageProcessingContext<TPixel> source, GraphicsOptions options, IBrush<TPixel> brush, float thickness, RectangleF shape) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Draw(options, new Pen<TPixel>(brush, thickness), shape); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the outline of the rectangle with the provided brush at the provided thickness.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="shape">The shape.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> Draw<TPixel>(this IImageProcessingContext<TPixel> source, IBrush<TPixel> brush, float thickness, RectangleF shape) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Draw(new Pen<TPixel>(brush, thickness), shape); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the outline of the rectangle with the provided brush at the provided thickness.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="shape">The shape.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> Draw<TPixel>(this IImageProcessingContext<TPixel> source, GraphicsOptions options, TPixel color, float thickness, RectangleF shape) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Draw(options, new SolidBrush<TPixel>(color), thickness, shape); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the outline of the rectangle with the provided brush at the provided thickness.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="shape">The shape.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> Draw<TPixel>(this IImageProcessingContext<TPixel> source, TPixel color, float thickness, RectangleF shape) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Draw(new SolidBrush<TPixel>(color), thickness, shape); |
|
||||
} |
|
||||
} |
|
||||
@ -1,150 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using SixLabors.Fonts; |
|
||||
using SixLabors.ImageSharp.PixelFormats; |
|
||||
using SixLabors.ImageSharp.Processing.Processors.Text; |
|
||||
using SixLabors.Primitives; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Processing |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Adds extensions that allow the drawing of text to the <see cref="Image{TPixel}"/> type.
|
|
||||
/// </summary>
|
|
||||
public static class DrawTextExtensions |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Draws the text onto the the image filled via the brush.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="text">The text.</param>
|
|
||||
/// <param name="font">The font.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="location">The location.</param>
|
|
||||
/// <returns>
|
|
||||
/// The <see cref="Image{TPixel}" />.
|
|
||||
/// </returns>
|
|
||||
public static IImageProcessingContext<TPixel> DrawText<TPixel>(this IImageProcessingContext<TPixel> source, string text, Font font, TPixel color, PointF location) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.DrawText(TextGraphicsOptions.Default, text, font, color, location); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the text onto the the image filled via the brush.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <param name="text">The text.</param>
|
|
||||
/// <param name="font">The font.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="location">The location.</param>
|
|
||||
/// <returns>
|
|
||||
/// The <see cref="Image{TPixel}" />.
|
|
||||
/// </returns>
|
|
||||
public static IImageProcessingContext<TPixel> DrawText<TPixel>(this IImageProcessingContext<TPixel> source, TextGraphicsOptions options, string text, Font font, TPixel color, PointF location) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.DrawText(options, text, font, Brushes.Solid(color), null, location); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the text onto the the image filled via the brush.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="text">The text.</param>
|
|
||||
/// <param name="font">The font.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="location">The location.</param>
|
|
||||
/// <returns>
|
|
||||
/// The <see cref="Image{TPixel}" />.
|
|
||||
/// </returns>
|
|
||||
public static IImageProcessingContext<TPixel> DrawText<TPixel>(this IImageProcessingContext<TPixel> source, string text, Font font, IBrush<TPixel> brush, PointF location) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.DrawText(TextGraphicsOptions.Default, text, font, brush, location); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the text onto the the image filled via the brush.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <param name="text">The text.</param>
|
|
||||
/// <param name="font">The font.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="location">The location.</param>
|
|
||||
/// <returns>
|
|
||||
/// The <see cref="Image{TPixel}" />.
|
|
||||
/// </returns>
|
|
||||
public static IImageProcessingContext<TPixel> DrawText<TPixel>(this IImageProcessingContext<TPixel> source, TextGraphicsOptions options, string text, Font font, IBrush<TPixel> brush, PointF location) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.DrawText(options, text, font, brush, null, location); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the text onto the the image outlined via the pen.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="text">The text.</param>
|
|
||||
/// <param name="font">The font.</param>
|
|
||||
/// <param name="pen">The pen.</param>
|
|
||||
/// <param name="location">The location.</param>
|
|
||||
/// <returns>
|
|
||||
/// The <see cref="Image{TPixel}" />.
|
|
||||
/// </returns>
|
|
||||
public static IImageProcessingContext<TPixel> DrawText<TPixel>(this IImageProcessingContext<TPixel> source, string text, Font font, IPen<TPixel> pen, PointF location) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.DrawText(TextGraphicsOptions.Default, text, font, pen, location); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the text onto the the image outlined via the pen.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <param name="text">The text.</param>
|
|
||||
/// <param name="font">The font.</param>
|
|
||||
/// <param name="pen">The pen.</param>
|
|
||||
/// <param name="location">The location.</param>
|
|
||||
/// <returns>
|
|
||||
/// The <see cref="Image{TPixel}" />.
|
|
||||
/// </returns>
|
|
||||
public static IImageProcessingContext<TPixel> DrawText<TPixel>(this IImageProcessingContext<TPixel> source, TextGraphicsOptions options, string text, Font font, IPen<TPixel> pen, PointF location) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.DrawText(options, text, font, null, pen, location); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the text onto the the image filled via the brush then outlined via the pen.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="text">The text.</param>
|
|
||||
/// <param name="font">The font.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="pen">The pen.</param>
|
|
||||
/// <param name="location">The location.</param>
|
|
||||
/// <returns>
|
|
||||
/// The <see cref="Image{TPixel}" />.
|
|
||||
/// </returns>
|
|
||||
public static IImageProcessingContext<TPixel> DrawText<TPixel>(this IImageProcessingContext<TPixel> source, string text, Font font, IBrush<TPixel> brush, IPen<TPixel> pen, PointF location) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.DrawText(TextGraphicsOptions.Default, text, font, brush, pen, location); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the text using the default resolution of <value>72dpi</value> onto the the image filled via the brush then outlined via the pen.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <param name="text">The text.</param>
|
|
||||
/// <param name="font">The font.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="pen">The pen.</param>
|
|
||||
/// <param name="location">The location.</param>
|
|
||||
/// <returns>
|
|
||||
/// The <see cref="Image{TPixel}" />.
|
|
||||
/// </returns>
|
|
||||
public static IImageProcessingContext<TPixel> DrawText<TPixel>(this IImageProcessingContext<TPixel> source, TextGraphicsOptions options, string text, Font font, IBrush<TPixel> brush, IPen<TPixel> pen, PointF location) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.ApplyProcessor(new DrawTextProcessor<TPixel>(options, text, font, brush, pen, location)); |
|
||||
} |
|
||||
} |
|
||||
@ -1,170 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using System; |
|
||||
|
|
||||
using SixLabors.ImageSharp.PixelFormats; |
|
||||
using SixLabors.Primitives; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Processing |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Gradient Brush with elliptic shape.
|
|
||||
/// The ellipse is defined by a center point,
|
|
||||
/// a point on the longest extension of the ellipse and
|
|
||||
/// the ratio between longest and shortest extension.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The Pixel format that is used.</typeparam>
|
|
||||
public sealed class EllipticGradientBrush<TPixel> : GradientBrushBase<TPixel> |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
{ |
|
||||
private readonly PointF center; |
|
||||
|
|
||||
private readonly PointF referenceAxisEnd; |
|
||||
|
|
||||
private readonly float axisRatio; |
|
||||
|
|
||||
/// <inheritdoc cref="GradientBrushBase{TPixel}" />
|
|
||||
/// <param name="center">The center of the elliptical gradient and 0 for the color stops.</param>
|
|
||||
/// <param name="referenceAxisEnd">The end point of the reference axis of the ellipse.</param>
|
|
||||
/// <param name="axisRatio">
|
|
||||
/// The ratio of the axis widths.
|
|
||||
/// The second axis' is perpendicular to the reference axis and
|
|
||||
/// it's length is the reference axis' length multiplied by this factor.
|
|
||||
/// </param>
|
|
||||
/// <param name="repetitionMode">Defines how the colors of the gradients are repeated.</param>
|
|
||||
/// <param name="colorStops">the color stops as defined in base class.</param>
|
|
||||
public EllipticGradientBrush( |
|
||||
PointF center, |
|
||||
PointF referenceAxisEnd, |
|
||||
float axisRatio, |
|
||||
GradientRepetitionMode repetitionMode, |
|
||||
params ColorStop<TPixel>[] colorStops) |
|
||||
: base(repetitionMode, colorStops) |
|
||||
{ |
|
||||
this.center = center; |
|
||||
this.referenceAxisEnd = referenceAxisEnd; |
|
||||
this.axisRatio = axisRatio; |
|
||||
} |
|
||||
|
|
||||
/// <inheritdoc cref="CreateApplicator" />
|
|
||||
public override BrushApplicator<TPixel> CreateApplicator( |
|
||||
ImageFrame<TPixel> source, |
|
||||
RectangleF region, |
|
||||
GraphicsOptions options) => |
|
||||
new RadialGradientBrushApplicator( |
|
||||
source, |
|
||||
options, |
|
||||
this.center, |
|
||||
this.referenceAxisEnd, |
|
||||
this.axisRatio, |
|
||||
this.ColorStops, |
|
||||
this.RepetitionMode); |
|
||||
|
|
||||
/// <inheritdoc />
|
|
||||
private sealed class RadialGradientBrushApplicator : GradientBrushApplicatorBase |
|
||||
{ |
|
||||
private readonly PointF center; |
|
||||
|
|
||||
private readonly PointF referenceAxisEnd; |
|
||||
|
|
||||
private readonly float axisRatio; |
|
||||
|
|
||||
private readonly double rotation; |
|
||||
|
|
||||
private readonly float referenceRadius; |
|
||||
|
|
||||
private readonly float secondRadius; |
|
||||
|
|
||||
private readonly float cosRotation; |
|
||||
|
|
||||
private readonly float sinRotation; |
|
||||
|
|
||||
private readonly float secondRadiusSquared; |
|
||||
|
|
||||
private readonly float referenceRadiusSquared; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="RadialGradientBrushApplicator" /> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="target">The target image</param>
|
|
||||
/// <param name="options">The options</param>
|
|
||||
/// <param name="center">Center of the ellipse</param>
|
|
||||
/// <param name="referenceAxisEnd">Point on one angular points of the ellipse.</param>
|
|
||||
/// <param name="axisRatio">
|
|
||||
/// Ratio of the axis length's. Used to determine the length of the second axis,
|
|
||||
/// the first is defined by <see cref="center"/> and <see cref="referenceAxisEnd"/>.</param>
|
|
||||
/// <param name="colorStops">Definition of colors</param>
|
|
||||
/// <param name="repetitionMode">Defines how the gradient colors are repeated.</param>
|
|
||||
public RadialGradientBrushApplicator( |
|
||||
ImageFrame<TPixel> target, |
|
||||
GraphicsOptions options, |
|
||||
PointF center, |
|
||||
PointF referenceAxisEnd, |
|
||||
float axisRatio, |
|
||||
ColorStop<TPixel>[] colorStops, |
|
||||
GradientRepetitionMode repetitionMode) |
|
||||
: base(target, options, colorStops, repetitionMode) |
|
||||
{ |
|
||||
this.center = center; |
|
||||
this.referenceAxisEnd = referenceAxisEnd; |
|
||||
this.axisRatio = axisRatio; |
|
||||
this.rotation = this.AngleBetween( |
|
||||
this.center, |
|
||||
new PointF(this.center.X + 1, this.center.Y), |
|
||||
this.referenceAxisEnd); |
|
||||
this.referenceRadius = this.DistanceBetween(this.center, this.referenceAxisEnd); |
|
||||
this.secondRadius = this.referenceRadius * this.axisRatio; |
|
||||
|
|
||||
this.referenceRadiusSquared = this.referenceRadius * this.referenceRadius; |
|
||||
this.secondRadiusSquared = this.secondRadius * this.secondRadius; |
|
||||
|
|
||||
this.sinRotation = (float)Math.Sin(this.rotation); |
|
||||
this.cosRotation = (float)Math.Cos(this.rotation); |
|
||||
} |
|
||||
|
|
||||
/// <inheritdoc />
|
|
||||
public override void Dispose() |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
/// <inheritdoc />
|
|
||||
protected override float PositionOnGradient(float xt, float yt) |
|
||||
{ |
|
||||
float x0 = xt - this.center.X; |
|
||||
float y0 = yt - this.center.Y; |
|
||||
|
|
||||
float x = (x0 * this.cosRotation) - (y0 * this.sinRotation); |
|
||||
float y = (x0 * this.sinRotation) + (y0 * this.cosRotation); |
|
||||
|
|
||||
float xSquared = x * x; |
|
||||
float ySquared = y * y; |
|
||||
|
|
||||
var inBoundaryChecker = (xSquared / this.referenceRadiusSquared) |
|
||||
+ (ySquared / this.secondRadiusSquared); |
|
||||
|
|
||||
return inBoundaryChecker; |
|
||||
} |
|
||||
|
|
||||
private float AngleBetween(PointF junction, PointF a, PointF b) |
|
||||
{ |
|
||||
var vA = a - junction; |
|
||||
var vB = b - junction; |
|
||||
return (float)(Math.Atan2(vB.Y, vB.X) |
|
||||
- Math.Atan2(vA.Y, vA.X)); |
|
||||
} |
|
||||
|
|
||||
private float DistanceBetween( |
|
||||
PointF p1, |
|
||||
PointF p2) |
|
||||
{ |
|
||||
float dX = p1.X - p2.X; |
|
||||
float dXsquared = dX * dX; |
|
||||
|
|
||||
float dY = p1.Y - p2.Y; |
|
||||
float dYsquared = dY * dY; |
|
||||
return (float)Math.Sqrt(dXsquared + dYsquared); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,70 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using System; |
|
||||
using SixLabors.ImageSharp.PixelFormats; |
|
||||
using SixLabors.Shapes; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Processing |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Adds extensions that allow the filling of polygons with various brushes to the <see cref="Image{TPixel}"/> type.
|
|
||||
/// </summary>
|
|
||||
public static class FillPathBuilderExtensions |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Flood fills the image in the shape of the provided polygon with the specified brush.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="options">The graphics options.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="path">The shape.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> Fill<TPixel>(this IImageProcessingContext<TPixel> source, GraphicsOptions options, IBrush<TPixel> brush, Action<PathBuilder> path) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
{ |
|
||||
var pb = new PathBuilder(); |
|
||||
path(pb); |
|
||||
|
|
||||
return source.Fill(options, brush, pb.Build()); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Flood fills the image in the shape of the provided polygon with the specified brush.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="path">The path.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> Fill<TPixel>(this IImageProcessingContext<TPixel> source, IBrush<TPixel> brush, Action<PathBuilder> path) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Fill(GraphicsOptions.Default, brush, path); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Flood fills the image in the shape of the provided polygon with the specified brush.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="path">The path.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> Fill<TPixel>(this IImageProcessingContext<TPixel> source, GraphicsOptions options, TPixel color, Action<PathBuilder> path) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Fill(options, new SolidBrush<TPixel>(color), path); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Flood fills the image in the shape of the provided polygon with the specified brush.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="path">The path.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> Fill<TPixel>(this IImageProcessingContext<TPixel> source, TPixel color, Action<PathBuilder> path) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Fill(new SolidBrush<TPixel>(color), path); |
|
||||
} |
|
||||
} |
|
||||
@ -1,71 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using SixLabors.ImageSharp.PixelFormats; |
|
||||
using SixLabors.Shapes; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Processing |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Adds extensions that allow the filling of collections of polygon outlines to the <see cref="Image{TPixel}"/> type.
|
|
||||
/// </summary>
|
|
||||
public static class FillPathCollectionExtensions |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Flood fills the image in the shape of the provided polygon with the specified brush.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="options">The graphics options.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="paths">The shapes.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> Fill<TPixel>(this IImageProcessingContext<TPixel> source, GraphicsOptions options, IBrush<TPixel> brush, IPathCollection paths) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
{ |
|
||||
foreach (IPath s in paths) |
|
||||
{ |
|
||||
source.Fill(options, brush, s); |
|
||||
} |
|
||||
|
|
||||
return source; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Flood fills the image in the shape of the provided polygon with the specified brush.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="paths">The paths.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> Fill<TPixel>(this IImageProcessingContext<TPixel> source, IBrush<TPixel> brush, IPathCollection paths) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Fill(GraphicsOptions.Default, brush, paths); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Flood fills the image in the shape of the provided polygon with the specified brush.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="paths">The paths.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> Fill<TPixel>(this IImageProcessingContext<TPixel> source, GraphicsOptions options, TPixel color, IPathCollection paths) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Fill(options, new SolidBrush<TPixel>(color), paths); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Flood fills the image in the shape of the provided polygon with the specified brush.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="paths">The paths.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> Fill<TPixel>(this IImageProcessingContext<TPixel> source, TPixel color, IPathCollection paths) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Fill(new SolidBrush<TPixel>(color), paths); |
|
||||
} |
|
||||
} |
|
||||
@ -1,65 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using SixLabors.ImageSharp.PixelFormats; |
|
||||
using SixLabors.ImageSharp.Primitives; |
|
||||
using SixLabors.Shapes; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Processing |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Adds extensions that allow the filling of polygon outlines to the <see cref="Image{TPixel}"/> type.
|
|
||||
/// </summary>
|
|
||||
public static class FillPathExtensions |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Flood fills the image in the shape of the provided polygon with the specified brush.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="options">The graphics options.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="path">The shape.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> Fill<TPixel>(this IImageProcessingContext<TPixel> source, GraphicsOptions options, IBrush<TPixel> brush, IPath path) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Fill(options, brush, new ShapeRegion(path)); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Flood fills the image in the shape of the provided polygon with the specified brush.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="path">The path.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> Fill<TPixel>(this IImageProcessingContext<TPixel> source, IBrush<TPixel> brush, IPath path) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Fill(GraphicsOptions.Default, brush, new ShapeRegion(path)); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Flood fills the image in the shape of the provided polygon with the specified brush..
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="path">The path.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> Fill<TPixel>(this IImageProcessingContext<TPixel> source, GraphicsOptions options, TPixel color, IPath path) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Fill(options, new SolidBrush<TPixel>(color), path); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Flood fills the image in the shape of the provided polygon with the specified brush..
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="path">The path.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> Fill<TPixel>(this IImageProcessingContext<TPixel> source, TPixel color, IPath path) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Fill(new SolidBrush<TPixel>(color), path); |
|
||||
} |
|
||||
} |
|
||||
@ -1,65 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using SixLabors.ImageSharp.PixelFormats; |
|
||||
using SixLabors.Primitives; |
|
||||
using SixLabors.Shapes; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Processing |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Adds extensions that allow the filling of closed linear polygons to the <see cref="Image{TPixel}"/> type.
|
|
||||
/// </summary>
|
|
||||
public static class FillPolygonExtensions |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Flood fills the image in the shape of a Linear polygon described by the points
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> FillPolygon<TPixel>(this IImageProcessingContext<TPixel> source, GraphicsOptions options, IBrush<TPixel> brush, params PointF[] points) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Fill(options, brush, new Polygon(new LinearLineSegment(points))); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Flood fills the image in the shape of a Linear polygon described by the points
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> FillPolygon<TPixel>(this IImageProcessingContext<TPixel> source, IBrush<TPixel> brush, params PointF[] points) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Fill(brush, new Polygon(new LinearLineSegment(points))); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Flood fills the image in the shape of a Linear polygon described by the points
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> FillPolygon<TPixel>(this IImageProcessingContext<TPixel> source, GraphicsOptions options, TPixel color, params PointF[] points) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Fill(options, new SolidBrush<TPixel>(color), new Polygon(new LinearLineSegment(points))); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Flood fills the image in the shape of a Linear polygon described by the points
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> FillPolygon<TPixel>(this IImageProcessingContext<TPixel> source, TPixel color, params PointF[] points) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Fill(new SolidBrush<TPixel>(color), new Polygon(new LinearLineSegment(points))); |
|
||||
} |
|
||||
} |
|
||||
@ -1,65 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using SixLabors.ImageSharp.PixelFormats; |
|
||||
using SixLabors.Primitives; |
|
||||
using SixLabors.Shapes; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Processing |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Adds extensions that allow the filling of rectangles to the <see cref="Image{TPixel}"/> type.
|
|
||||
/// </summary>
|
|
||||
public static class FillRectangleExtensions |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Flood fills the image in the shape of the provided rectangle with the specified brush.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="shape">The shape.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> Fill<TPixel>(this IImageProcessingContext<TPixel> source, GraphicsOptions options, IBrush<TPixel> brush, RectangleF shape) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Fill(options, brush, new RectangularPolygon(shape.X, shape.Y, shape.Width, shape.Height)); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Flood fills the image in the shape of the provided rectangle with the specified brush.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="shape">The shape.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> Fill<TPixel>(this IImageProcessingContext<TPixel> source, IBrush<TPixel> brush, RectangleF shape) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Fill(brush, new RectangularPolygon(shape.X, shape.Y, shape.Width, shape.Height)); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Flood fills the image in the shape of the provided rectangle with the specified brush.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="shape">The shape.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> Fill<TPixel>(this IImageProcessingContext<TPixel> source, GraphicsOptions options, TPixel color, RectangleF shape) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Fill(options, new SolidBrush<TPixel>(color), shape); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Flood fills the image in the shape of the provided rectangle with the specified brush.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="shape">The shape.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> Fill<TPixel>(this IImageProcessingContext<TPixel> source, TPixel color, RectangleF shape) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Fill(new SolidBrush<TPixel>(color), shape); |
|
||||
} |
|
||||
} |
|
||||
@ -1,99 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using SixLabors.ImageSharp.PixelFormats; |
|
||||
using SixLabors.ImageSharp.Primitives; |
|
||||
using SixLabors.ImageSharp.Processing.Processors.Drawing; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Processing |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Adds extensions that allow the filling of regions with various brushes to the <see cref="Image{TPixel}"/> type.
|
|
||||
/// </summary>
|
|
||||
public static class FillRegionExtensions |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Flood fills the image with the specified brush.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="brush">The details how to fill the region of interest.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> Fill<TPixel>(this IImageProcessingContext<TPixel> source, IBrush<TPixel> brush) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Fill(GraphicsOptions.Default, brush); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Flood fills the image with the specified color.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> Fill<TPixel>(this IImageProcessingContext<TPixel> source, TPixel color) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Fill(new SolidBrush<TPixel>(color)); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Flood fills the image with in the region with the specified brush.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="region">The region.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> Fill<TPixel>(this IImageProcessingContext<TPixel> source, IBrush<TPixel> brush, Region region) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Fill(GraphicsOptions.Default, brush, region); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Flood fills the image with in the region with the specified color.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="region">The region.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> Fill<TPixel>(this IImageProcessingContext<TPixel> source, GraphicsOptions options, TPixel color, Region region) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Fill(options, new SolidBrush<TPixel>(color), region); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Flood fills the image with in the region with the specified color.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="region">The region.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> Fill<TPixel>(this IImageProcessingContext<TPixel> source, TPixel color, Region region) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.Fill(new SolidBrush<TPixel>(color), region); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Flood fills the image with in the region with the specified brush.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="options">The graphics options.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="region">The region.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> Fill<TPixel>(this IImageProcessingContext<TPixel> source, GraphicsOptions options, IBrush<TPixel> brush, Region region) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.ApplyProcessor(new FillRegionProcessor<TPixel>(brush, region, options)); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Flood fills the image with the specified brush.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="options">The graphics options.</param>
|
|
||||
/// <param name="brush">The details how to fill the region of interest.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageProcessingContext<TPixel> Fill<TPixel>(this IImageProcessingContext<TPixel> source, GraphicsOptions options, IBrush<TPixel> brush) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> source.ApplyProcessor(new FillProcessor<TPixel>(brush, options)); |
|
||||
} |
|
||||
} |
|
||||
@ -1,177 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using System; |
|
||||
using System.Numerics; |
|
||||
|
|
||||
using SixLabors.ImageSharp.PixelFormats; |
|
||||
using SixLabors.ImageSharp.PixelFormats.PixelBlenders; |
|
||||
using SixLabors.Primitives; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Processing |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Base class for Gradient brushes
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The pixel format</typeparam>
|
|
||||
public abstract class GradientBrushBase<TPixel> : IBrush<TPixel> |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
{ |
|
||||
/// <inheritdoc cref="IBrush{TPixel}"/>
|
|
||||
/// <param name="repetitionMode">Defines how the colors are repeated beyond the interval [0..1]</param>
|
|
||||
/// <param name="colorStops">The gradient colors.</param>
|
|
||||
protected GradientBrushBase( |
|
||||
GradientRepetitionMode repetitionMode, |
|
||||
params ColorStop<TPixel>[] colorStops) |
|
||||
{ |
|
||||
this.RepetitionMode = repetitionMode; |
|
||||
this.ColorStops = colorStops; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets how the colors are repeated beyond the interval [0..1].
|
|
||||
/// </summary>
|
|
||||
protected GradientRepetitionMode RepetitionMode { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the list of color stops for this gradient.
|
|
||||
/// </summary>
|
|
||||
protected ColorStop<TPixel>[] ColorStops { get; } |
|
||||
|
|
||||
/// <inheritdoc cref="IBrush{TPixel}" />
|
|
||||
public abstract BrushApplicator<TPixel> CreateApplicator( |
|
||||
ImageFrame<TPixel> source, |
|
||||
RectangleF region, |
|
||||
GraphicsOptions options); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Base class for gradient brush applicators
|
|
||||
/// </summary>
|
|
||||
protected abstract class GradientBrushApplicatorBase : BrushApplicator<TPixel> |
|
||||
{ |
|
||||
private readonly ColorStop<TPixel>[] colorStops; |
|
||||
|
|
||||
private readonly GradientRepetitionMode repetitionMode; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="GradientBrushApplicatorBase"/> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="target">The target.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <param name="colorStops">An array of color stops sorted by their position.</param>
|
|
||||
/// <param name="repetitionMode">Defines if and how the gradient should be repeated.</param>
|
|
||||
protected GradientBrushApplicatorBase( |
|
||||
ImageFrame<TPixel> target, |
|
||||
GraphicsOptions options, |
|
||||
ColorStop<TPixel>[] colorStops, |
|
||||
GradientRepetitionMode repetitionMode) |
|
||||
: base(target, options) |
|
||||
{ |
|
||||
this.colorStops = colorStops; // TODO: requires colorStops to be sorted by position - should that be checked?
|
|
||||
this.repetitionMode = repetitionMode; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Base implementation of the indexer for gradients
|
|
||||
/// (follows the facade pattern, using abstract methods)
|
|
||||
/// </summary>
|
|
||||
/// <param name="x">X coordinate of the Pixel.</param>
|
|
||||
/// <param name="y">Y coordinate of the Pixel.</param>
|
|
||||
internal override TPixel this[int x, int y] |
|
||||
{ |
|
||||
get |
|
||||
{ |
|
||||
float positionOnCompleteGradient = this.PositionOnGradient(x + 0.5f, y + 0.5f); |
|
||||
|
|
||||
switch (this.repetitionMode) |
|
||||
{ |
|
||||
case GradientRepetitionMode.None: |
|
||||
// do nothing. The following could be done, but is not necessary:
|
|
||||
// onLocalGradient = Math.Min(0, Math.Max(1, onLocalGradient));
|
|
||||
break; |
|
||||
case GradientRepetitionMode.Repeat: |
|
||||
positionOnCompleteGradient = positionOnCompleteGradient % 1; |
|
||||
break; |
|
||||
case GradientRepetitionMode.Reflect: |
|
||||
positionOnCompleteGradient = positionOnCompleteGradient % 2; |
|
||||
if (positionOnCompleteGradient > 1) |
|
||||
{ |
|
||||
positionOnCompleteGradient = 2 - positionOnCompleteGradient; |
|
||||
} |
|
||||
|
|
||||
break; |
|
||||
case GradientRepetitionMode.DontFill: |
|
||||
if (positionOnCompleteGradient > 1 || positionOnCompleteGradient < 0) |
|
||||
{ |
|
||||
return NamedColors<TPixel>.Transparent; |
|
||||
} |
|
||||
|
|
||||
break; |
|
||||
default: |
|
||||
throw new ArgumentOutOfRangeException(); |
|
||||
} |
|
||||
|
|
||||
(ColorStop<TPixel> from, ColorStop<TPixel> to) = this.GetGradientSegment(positionOnCompleteGradient); |
|
||||
|
|
||||
if (from.Color.Equals(to.Color)) |
|
||||
{ |
|
||||
return from.Color; |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
var fromAsVector = from.Color.ToVector4(); |
|
||||
var toAsVector = to.Color.ToVector4(); |
|
||||
float onLocalGradient = (positionOnCompleteGradient - from.Ratio) / (to.Ratio - from.Ratio); |
|
||||
|
|
||||
// TODO: this should be changeble for different gradienting functions
|
|
||||
Vector4 result = PorterDuffFunctions.NormalSrcOver( |
|
||||
fromAsVector, |
|
||||
toAsVector, |
|
||||
onLocalGradient); |
|
||||
|
|
||||
TPixel resultColor = default; |
|
||||
resultColor.FromVector4(result); |
|
||||
return resultColor; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// calculates the position on the gradient for a given point.
|
|
||||
/// This method is abstract as it's content depends on the shape of the gradient.
|
|
||||
/// </summary>
|
|
||||
/// <param name="x">The x coordinate of the point</param>
|
|
||||
/// <param name="y">The y coordinate of the point</param>
|
|
||||
/// <returns>
|
|
||||
/// The position the given point has on the gradient.
|
|
||||
/// The position is not bound to the [0..1] interval.
|
|
||||
/// Values outside of that interval may be treated differently,
|
|
||||
/// e.g. for the <see cref="GradientRepetitionMode" /> enum.
|
|
||||
/// </returns>
|
|
||||
protected abstract float PositionOnGradient(float x, float y); |
|
||||
|
|
||||
private (ColorStop<TPixel> from, ColorStop<TPixel> to) GetGradientSegment( |
|
||||
float positionOnCompleteGradient) |
|
||||
{ |
|
||||
ColorStop<TPixel> localGradientFrom = this.colorStops[0]; |
|
||||
ColorStop<TPixel> localGradientTo = default; |
|
||||
|
|
||||
// TODO: ensure colorStops has at least 2 items (technically 1 would be okay, but that's no gradient)
|
|
||||
foreach (ColorStop<TPixel> colorStop in this.colorStops) |
|
||||
{ |
|
||||
localGradientTo = colorStop; |
|
||||
|
|
||||
if (colorStop.Ratio > positionOnCompleteGradient) |
|
||||
{ |
|
||||
// we're done here, so break it!
|
|
||||
break; |
|
||||
} |
|
||||
|
|
||||
localGradientFrom = localGradientTo; |
|
||||
} |
|
||||
|
|
||||
return (localGradientFrom, localGradientTo); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,37 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Processing |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Modes to repeat a gradient.
|
|
||||
/// </summary>
|
|
||||
public enum GradientRepetitionMode |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// don't repeat, keep the color of start and end beyond those points stable.
|
|
||||
/// </summary>
|
|
||||
None, |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Repeat the gradient.
|
|
||||
/// If it's a black-white gradient, with Repeat it will be Black->{gray}->White|Black->{gray}->White|...
|
|
||||
/// </summary>
|
|
||||
Repeat, |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Reflect the gradient.
|
|
||||
/// Similar to <see cref="Repeat"/>, but each other repetition uses inverse order of <see cref="ColorStop{TPixel}"/>s.
|
|
||||
/// Used on a Black-White gradient, Reflect leads to Black->{gray}->White->{gray}->White...
|
|
||||
/// </summary>
|
|
||||
Reflect, |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// With DontFill a gradient does not touch any pixel beyond it's borders.
|
|
||||
/// For the <see cref="LinearGradientBrush{TPixel}" /> this is beyond the orthogonal through start and end,
|
|
||||
/// TODO For the cref="PolygonalGradientBrush" it's outside the polygon,
|
|
||||
/// For <see cref="RadialGradientBrush{TPixel}" /> and <see cref="EllipticGradientBrush{TPixel}" /> it's beyond 1.0.
|
|
||||
/// </summary>
|
|
||||
DontFill |
|
||||
} |
|
||||
} |
|
||||
@ -1,35 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using SixLabors.ImageSharp.PixelFormats; |
|
||||
using SixLabors.Primitives; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Processing |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Brush represents a logical configuration of a brush which can be used to source pixel colors
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|
||||
/// <remarks>
|
|
||||
/// A brush is a simple class that will return an <see cref="BrushApplicator{TPixel}" /> that will perform the
|
|
||||
/// logic for converting a pixel location to a <typeparamref name="TPixel"/>.
|
|
||||
/// </remarks>
|
|
||||
public interface IBrush<TPixel> |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Creates the applicator for this brush.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The source image.</param>
|
|
||||
/// <param name="region">The region the brush will be applied to.</param>
|
|
||||
/// <param name="options">The graphic options</param>
|
|
||||
/// <returns>
|
|
||||
/// The brush applicator for this brush
|
|
||||
/// </returns>
|
|
||||
/// <remarks>
|
|
||||
/// The <paramref name="region" /> when being applied to things like shapes would usually be the
|
|
||||
/// bounding box of the shape not necessarily the bounds of the whole image
|
|
||||
/// </remarks>
|
|
||||
BrushApplicator<TPixel> CreateApplicator(ImageFrame<TPixel> source, RectangleF region, GraphicsOptions options); |
|
||||
} |
|
||||
} |
|
||||
@ -1,37 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using System; |
|
||||
using SixLabors.ImageSharp.PixelFormats; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Processing |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Interface representing a Pen
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
public interface IPen<TPixel> : IPen |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Gets the stroke fill.
|
|
||||
/// </summary>
|
|
||||
IBrush<TPixel> StrokeFill { get; } |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Interface representing the pattern and size of the stroke to apply with a Pen.
|
|
||||
/// </summary>
|
|
||||
public interface IPen |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Gets the width to apply to the stroke
|
|
||||
/// </summary>
|
|
||||
float StrokeWidth { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the stoke pattern.
|
|
||||
/// </summary>
|
|
||||
ReadOnlySpan<float> StrokePattern { get; } |
|
||||
} |
|
||||
} |
|
||||
@ -1,153 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using System; |
|
||||
using System.Buffers; |
|
||||
using SixLabors.ImageSharp.Advanced; |
|
||||
using SixLabors.ImageSharp.Memory; |
|
||||
using SixLabors.ImageSharp.PixelFormats; |
|
||||
using SixLabors.Memory; |
|
||||
using SixLabors.Primitives; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Processing |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Provides an implementation of an image brush for painting images within areas.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|
||||
public class ImageBrush<TPixel> : IBrush<TPixel> |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// The image to paint.
|
|
||||
/// </summary>
|
|
||||
private readonly ImageFrame<TPixel> image; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="ImageBrush{TPixel}"/> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="image">The image.</param>
|
|
||||
public ImageBrush(ImageFrame<TPixel> image) |
|
||||
{ |
|
||||
this.image = image; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="ImageBrush{TPixel}"/> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="image">The image.</param>
|
|
||||
public ImageBrush(Image<TPixel> image) |
|
||||
: this(image.Frames.RootFrame) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
/// <inheritdoc />
|
|
||||
public BrushApplicator<TPixel> CreateApplicator(ImageFrame<TPixel> source, RectangleF region, GraphicsOptions options) |
|
||||
=> new ImageBrushApplicator(source, this.image, region, options); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// The image brush applicator.
|
|
||||
/// </summary>
|
|
||||
private class ImageBrushApplicator : BrushApplicator<TPixel> |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// The source image.
|
|
||||
/// </summary>
|
|
||||
private readonly ImageFrame<TPixel> source; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// The y-length.
|
|
||||
/// </summary>
|
|
||||
private readonly int yLength; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// The x-length.
|
|
||||
/// </summary>
|
|
||||
private readonly int xLength; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// The Y offset.
|
|
||||
/// </summary>
|
|
||||
private readonly int offsetY; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// The X offset.
|
|
||||
/// </summary>
|
|
||||
private readonly int offsetX; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="ImageBrushApplicator"/> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="target">The target image.</param>
|
|
||||
/// <param name="image">The image.</param>
|
|
||||
/// <param name="region">The region.</param>
|
|
||||
/// <param name="options">The options</param>
|
|
||||
public ImageBrushApplicator(ImageFrame<TPixel> target, ImageFrame<TPixel> image, RectangleF region, GraphicsOptions options) |
|
||||
: base(target, options) |
|
||||
{ |
|
||||
this.source = image; |
|
||||
this.xLength = image.Width; |
|
||||
this.yLength = image.Height; |
|
||||
this.offsetY = (int)MathF.Max(MathF.Floor(region.Top), 0); |
|
||||
this.offsetX = (int)MathF.Max(MathF.Floor(region.Left), 0); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the color for a single pixel.
|
|
||||
/// </summary>
|
|
||||
/// <param name="x">The x.</param>
|
|
||||
/// <param name="y">The y.</param>
|
|
||||
/// <returns>
|
|
||||
/// The color
|
|
||||
/// </returns>
|
|
||||
internal override TPixel this[int x, int y] |
|
||||
{ |
|
||||
get |
|
||||
{ |
|
||||
int srcX = (x - this.offsetX) % this.xLength; |
|
||||
int srcY = (y - this.offsetY) % this.yLength; |
|
||||
return this.source[srcX, srcY]; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/// <inheritdoc />
|
|
||||
public override void Dispose() |
|
||||
{ |
|
||||
this.source.Dispose(); |
|
||||
} |
|
||||
|
|
||||
/// <inheritdoc />
|
|
||||
internal override void Apply(Span<float> scanline, int x, int y) |
|
||||
{ |
|
||||
// Create a span for colors
|
|
||||
using (IMemoryOwner<float> amountBuffer = this.Target.MemoryAllocator.Allocate<float>(scanline.Length)) |
|
||||
using (IMemoryOwner<TPixel> overlay = this.Target.MemoryAllocator.Allocate<TPixel>(scanline.Length)) |
|
||||
{ |
|
||||
Span<float> amountSpan = amountBuffer.GetSpan(); |
|
||||
Span<TPixel> overlaySpan = overlay.GetSpan(); |
|
||||
|
|
||||
int sourceY = (y - this.offsetY) % this.yLength; |
|
||||
int offsetX = x - this.offsetX; |
|
||||
Span<TPixel> sourceRow = this.source.GetPixelRowSpan(sourceY); |
|
||||
|
|
||||
for (int i = 0; i < scanline.Length; i++) |
|
||||
{ |
|
||||
amountSpan[i] = scanline[i] * this.Options.BlendPercentage; |
|
||||
|
|
||||
int sourceX = (i + offsetX) % this.xLength; |
|
||||
TPixel pixel = sourceRow[sourceX]; |
|
||||
overlaySpan[i] = pixel; |
|
||||
} |
|
||||
|
|
||||
Span<TPixel> destinationRow = this.Target.GetPixelRowSpan(y).Slice(x, scanline.Length); |
|
||||
this.Blender.Blend( |
|
||||
this.source.Configuration, |
|
||||
destinationRow, |
|
||||
destinationRow, |
|
||||
overlaySpan, |
|
||||
amountSpan); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,155 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using System; |
|
||||
|
|
||||
using SixLabors.ImageSharp.PixelFormats; |
|
||||
using SixLabors.Primitives; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Processing |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Provides an implementation of a brush for painting linear gradients within areas.
|
|
||||
/// Supported right now:
|
|
||||
/// - a set of colors in relative distances to each other.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The pixel format</typeparam>
|
|
||||
public sealed class LinearGradientBrush<TPixel> : GradientBrushBase<TPixel> |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
{ |
|
||||
private readonly PointF p1; |
|
||||
|
|
||||
private readonly PointF p2; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="LinearGradientBrush{TPixel}"/> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="p1">Start point</param>
|
|
||||
/// <param name="p2">End point</param>
|
|
||||
/// <param name="repetitionMode">defines how colors are repeated.</param>
|
|
||||
/// <param name="colorStops"><inheritdoc /></param>
|
|
||||
public LinearGradientBrush( |
|
||||
PointF p1, |
|
||||
PointF p2, |
|
||||
GradientRepetitionMode repetitionMode, |
|
||||
params ColorStop<TPixel>[] colorStops) |
|
||||
: base(repetitionMode, colorStops) |
|
||||
{ |
|
||||
this.p1 = p1; |
|
||||
this.p2 = p2; |
|
||||
} |
|
||||
|
|
||||
/// <inheritdoc />
|
|
||||
public override BrushApplicator<TPixel> CreateApplicator(ImageFrame<TPixel> source, RectangleF region, GraphicsOptions options) |
|
||||
=> new LinearGradientBrushApplicator(source, this.p1, this.p2, this.ColorStops, this.RepetitionMode, options); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// The linear gradient brush applicator.
|
|
||||
/// </summary>
|
|
||||
private sealed class LinearGradientBrushApplicator : GradientBrushApplicatorBase |
|
||||
{ |
|
||||
private readonly PointF start; |
|
||||
|
|
||||
private readonly PointF end; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// the vector along the gradient, x component
|
|
||||
/// </summary>
|
|
||||
private readonly float alongX; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// the vector along the gradient, y component
|
|
||||
/// </summary>
|
|
||||
private readonly float alongY; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// the vector perpendicular to the gradient, y component
|
|
||||
/// </summary>
|
|
||||
private readonly float acrossY; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// the vector perpendicular to the gradient, x component
|
|
||||
/// </summary>
|
|
||||
private readonly float acrossX; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// the result of <see cref="alongX"/>^2 + <see cref="alongY"/>^2
|
|
||||
/// </summary>
|
|
||||
private readonly float alongsSquared; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// the length of the defined gradient (between source and end)
|
|
||||
/// </summary>
|
|
||||
private readonly float length; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="LinearGradientBrushApplicator" /> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The source</param>
|
|
||||
/// <param name="start">start point of the gradient</param>
|
|
||||
/// <param name="end">end point of the gradient</param>
|
|
||||
/// <param name="colorStops">tuple list of colors and their respective position between 0 and 1 on the line</param>
|
|
||||
/// <param name="repetitionMode">defines how the gradient colors are repeated.</param>
|
|
||||
/// <param name="options">the graphics options</param>
|
|
||||
public LinearGradientBrushApplicator( |
|
||||
ImageFrame<TPixel> source, |
|
||||
PointF start, |
|
||||
PointF end, |
|
||||
ColorStop<TPixel>[] colorStops, |
|
||||
GradientRepetitionMode repetitionMode, |
|
||||
GraphicsOptions options) |
|
||||
: base(source, options, colorStops, repetitionMode) |
|
||||
{ |
|
||||
this.start = start; |
|
||||
this.end = end; |
|
||||
|
|
||||
// the along vector:
|
|
||||
this.alongX = this.end.X - this.start.X; |
|
||||
this.alongY = this.end.Y - this.start.Y; |
|
||||
|
|
||||
// the cross vector:
|
|
||||
this.acrossX = this.alongY; |
|
||||
this.acrossY = -this.alongX; |
|
||||
|
|
||||
// some helpers:
|
|
||||
this.alongsSquared = (this.alongX * this.alongX) + (this.alongY * this.alongY); |
|
||||
this.length = (float)Math.Sqrt(this.alongsSquared); |
|
||||
} |
|
||||
|
|
||||
protected override float PositionOnGradient(float x, float y) |
|
||||
{ |
|
||||
if (this.acrossX == 0) |
|
||||
{ |
|
||||
return (x - this.start.X) / (this.end.X - this.start.X); |
|
||||
} |
|
||||
else if (this.acrossY == 0) |
|
||||
{ |
|
||||
return (y - this.start.Y) / (this.end.Y - this.start.Y); |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
float deltaX = x - this.start.X; |
|
||||
float deltaY = y - this.start.Y; |
|
||||
float k = ((this.alongY * deltaX) - (this.alongX * deltaY)) / this.alongsSquared; |
|
||||
|
|
||||
// point on the line:
|
|
||||
float x4 = x - (k * this.alongY); |
|
||||
float y4 = y + (k * this.alongX); |
|
||||
|
|
||||
// get distance from (x4,y4) to start
|
|
||||
float distance = (float)Math.Sqrt( |
|
||||
Math.Pow(x4 - this.start.X, 2) |
|
||||
+ Math.Pow(y4 - this.start.Y, 2)); |
|
||||
|
|
||||
// get and return ratio
|
|
||||
float ratio = distance / this.length; |
|
||||
return ratio; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public override void Dispose() |
|
||||
{ |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,183 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using System; |
|
||||
using System.Buffers; |
|
||||
using System.Numerics; |
|
||||
using SixLabors.ImageSharp.Advanced; |
|
||||
using SixLabors.ImageSharp.Memory; |
|
||||
using SixLabors.ImageSharp.PixelFormats; |
|
||||
using SixLabors.ImageSharp.Primitives; |
|
||||
using SixLabors.Memory; |
|
||||
using SixLabors.Primitives; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Processing |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Provides an implementation of a pattern brush for painting patterns.
|
|
||||
/// </summary>
|
|
||||
/// <remarks>
|
|
||||
/// The patterns that are used to create a custom pattern brush are made up of a repeating matrix of flags,
|
|
||||
/// where each flag denotes whether to draw the foreground color or the background color.
|
|
||||
/// so to create a new bool[,] with your flags
|
|
||||
/// <para>
|
|
||||
/// For example if you wanted to create a diagonal line that repeat every 4 pixels you would use a pattern like so
|
|
||||
/// 1000
|
|
||||
/// 0100
|
|
||||
/// 0010
|
|
||||
/// 0001
|
|
||||
/// </para>
|
|
||||
/// <para>
|
|
||||
/// or you want a horizontal stripe which is 3 pixels apart you would use a pattern like
|
|
||||
/// 1
|
|
||||
/// 0
|
|
||||
/// 0
|
|
||||
/// </para>
|
|
||||
/// </remarks>
|
|
||||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|
||||
public class PatternBrush<TPixel> : IBrush<TPixel> |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// The pattern.
|
|
||||
/// </summary>
|
|
||||
private readonly DenseMatrix<TPixel> pattern; |
|
||||
private readonly DenseMatrix<Vector4> patternVector; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="PatternBrush{TPixel}"/> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="foreColor">Color of the fore.</param>
|
|
||||
/// <param name="backColor">Color of the back.</param>
|
|
||||
/// <param name="pattern">The pattern.</param>
|
|
||||
public PatternBrush(TPixel foreColor, TPixel backColor, bool[,] pattern) |
|
||||
: this(foreColor, backColor, new DenseMatrix<bool>(pattern)) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="PatternBrush{TPixel}"/> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="foreColor">Color of the fore.</param>
|
|
||||
/// <param name="backColor">Color of the back.</param>
|
|
||||
/// <param name="pattern">The pattern.</param>
|
|
||||
internal PatternBrush(TPixel foreColor, TPixel backColor, DenseMatrix<bool> pattern) |
|
||||
{ |
|
||||
var foreColorVector = foreColor.ToVector4(); |
|
||||
var backColorVector = backColor.ToVector4(); |
|
||||
this.pattern = new DenseMatrix<TPixel>(pattern.Columns, pattern.Rows); |
|
||||
this.patternVector = new DenseMatrix<Vector4>(pattern.Columns, pattern.Rows); |
|
||||
for (int i = 0; i < pattern.Data.Length; i++) |
|
||||
{ |
|
||||
if (pattern.Data[i]) |
|
||||
{ |
|
||||
this.pattern.Data[i] = foreColor; |
|
||||
this.patternVector.Data[i] = foreColorVector; |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
this.pattern.Data[i] = backColor; |
|
||||
this.patternVector.Data[i] = backColorVector; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="PatternBrush{TPixel}"/> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
internal PatternBrush(PatternBrush<TPixel> brush) |
|
||||
{ |
|
||||
this.pattern = brush.pattern; |
|
||||
this.patternVector = brush.patternVector; |
|
||||
} |
|
||||
|
|
||||
/// <inheritdoc />
|
|
||||
public BrushApplicator<TPixel> CreateApplicator(ImageFrame<TPixel> source, RectangleF region, GraphicsOptions options) |
|
||||
{ |
|
||||
return new PatternBrushApplicator(source, this.pattern, this.patternVector, options); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// The pattern brush applicator.
|
|
||||
/// </summary>
|
|
||||
private class PatternBrushApplicator : BrushApplicator<TPixel> |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// The pattern.
|
|
||||
/// </summary>
|
|
||||
private readonly DenseMatrix<TPixel> pattern; |
|
||||
private readonly DenseMatrix<Vector4> patternVector; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="PatternBrushApplicator" /> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The source image.</param>
|
|
||||
/// <param name="pattern">The pattern.</param>
|
|
||||
/// <param name="patternVector">The patternVector.</param>
|
|
||||
/// <param name="options">The options</param>
|
|
||||
public PatternBrushApplicator(ImageFrame<TPixel> source, DenseMatrix<TPixel> pattern, DenseMatrix<Vector4> patternVector, GraphicsOptions options) |
|
||||
: base(source, options) |
|
||||
{ |
|
||||
this.pattern = pattern; |
|
||||
this.patternVector = patternVector; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the color for a single pixel.
|
|
||||
/// </summary>#
|
|
||||
/// <param name="x">The x.</param>
|
|
||||
/// <param name="y">The y.</param>
|
|
||||
/// <returns>
|
|
||||
/// The Color.
|
|
||||
/// </returns>
|
|
||||
internal override TPixel this[int x, int y] |
|
||||
{ |
|
||||
get |
|
||||
{ |
|
||||
x = x % this.pattern.Columns; |
|
||||
y = y % this.pattern.Rows; |
|
||||
|
|
||||
// 2d array index at row/column
|
|
||||
return this.pattern[y, x]; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/// <inheritdoc />
|
|
||||
public override void Dispose() |
|
||||
{ |
|
||||
// noop
|
|
||||
} |
|
||||
|
|
||||
/// <inheritdoc />
|
|
||||
internal override void Apply(Span<float> scanline, int x, int y) |
|
||||
{ |
|
||||
int patternY = y % this.pattern.Rows; |
|
||||
MemoryAllocator memoryAllocator = this.Target.MemoryAllocator; |
|
||||
|
|
||||
using (IMemoryOwner<float> amountBuffer = memoryAllocator.Allocate<float>(scanline.Length)) |
|
||||
using (IMemoryOwner<TPixel> overlay = memoryAllocator.Allocate<TPixel>(scanline.Length)) |
|
||||
{ |
|
||||
Span<float> amountSpan = amountBuffer.GetSpan(); |
|
||||
Span<TPixel> overlaySpan = overlay.GetSpan(); |
|
||||
|
|
||||
for (int i = 0; i < scanline.Length; i++) |
|
||||
{ |
|
||||
amountSpan[i] = (scanline[i] * this.Options.BlendPercentage).Clamp(0, 1); |
|
||||
|
|
||||
int patternX = (x + i) % this.pattern.Columns; |
|
||||
overlaySpan[i] = this.pattern[patternY, patternX]; |
|
||||
} |
|
||||
|
|
||||
Span<TPixel> destinationRow = this.Target.GetPixelRowSpan(y).Slice(x, scanline.Length); |
|
||||
this.Blender.Blend( |
|
||||
this.Target.Configuration, |
|
||||
destinationRow, |
|
||||
destinationRow, |
|
||||
overlaySpan, |
|
||||
amountSpan); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,129 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using SixLabors.ImageSharp.PixelFormats; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Processing |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Contains a collection of common Pen styles
|
|
||||
/// </summary>
|
|
||||
public static class Pens |
|
||||
{ |
|
||||
private static readonly float[] DashDotPattern = { 3f, 1f, 1f, 1f }; |
|
||||
private static readonly float[] DashDotDotPattern = { 3f, 1f, 1f, 1f, 1f, 1f }; |
|
||||
private static readonly float[] DottedPattern = { 1f, 1f }; |
|
||||
private static readonly float[] DashedPattern = { 3f, 1f }; |
|
||||
internal static readonly float[] EmptyPattern = new float[0]; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Create a solid pen with out any drawing patterns
|
|
||||
/// </summary>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="width">The width.</param>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <returns>The Pen</returns>
|
|
||||
public static Pen<TPixel> Solid<TPixel>(TPixel color, float width) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> new Pen<TPixel>(color, width); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Create a solid pen with out any drawing patterns
|
|
||||
/// </summary>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="width">The width.</param>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <returns>The Pen</returns>
|
|
||||
public static Pen<TPixel> Solid<TPixel>(IBrush<TPixel> brush, float width) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> new Pen<TPixel>(brush, width); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Create a pen with a 'Dash' drawing patterns
|
|
||||
/// </summary>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="width">The width.</param>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <returns>The Pen</returns>
|
|
||||
public static Pen<TPixel> Dash<TPixel>(TPixel color, float width) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> new Pen<TPixel>(color, width, DashedPattern); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Create a pen with a 'Dash' drawing patterns
|
|
||||
/// </summary>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="width">The width.</param>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <returns>The Pen</returns>
|
|
||||
public static Pen<TPixel> Dash<TPixel>(IBrush<TPixel> brush, float width) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> new Pen<TPixel>(brush, width, DashedPattern); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Create a pen with a 'Dot' drawing patterns
|
|
||||
/// </summary>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="width">The width.</param>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <returns>The Pen</returns>
|
|
||||
public static Pen<TPixel> Dot<TPixel>(TPixel color, float width) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> new Pen<TPixel>(color, width, DottedPattern); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Create a pen with a 'Dot' drawing patterns
|
|
||||
/// </summary>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="width">The width.</param>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <returns>The Pen</returns>
|
|
||||
public static Pen<TPixel> Dot<TPixel>(IBrush<TPixel> brush, float width) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> new Pen<TPixel>(brush, width, DottedPattern); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Create a pen with a 'Dash Dot' drawing patterns
|
|
||||
/// </summary>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="width">The width.</param>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <returns>The Pen</returns>
|
|
||||
public static Pen<TPixel> DashDot<TPixel>(TPixel color, float width) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> new Pen<TPixel>(color, width, DashDotPattern); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Create a pen with a 'Dash Dot' drawing patterns
|
|
||||
/// </summary>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="width">The width.</param>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <returns>The Pen</returns>
|
|
||||
public static Pen<TPixel> DashDot<TPixel>(IBrush<TPixel> brush, float width) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> new Pen<TPixel>(brush, width, DashDotPattern); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Create a pen with a 'Dash Dot Dot' drawing patterns
|
|
||||
/// </summary>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="width">The width.</param>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <returns>The Pen</returns>
|
|
||||
public static Pen<TPixel> DashDotDot<TPixel>(TPixel color, float width) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> new Pen<TPixel>(color, width, DashDotDotPattern); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Create a pen with a 'Dash Dot Dot' drawing patterns
|
|
||||
/// </summary>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="width">The width.</param>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <returns>The Pen</returns>
|
|
||||
public static Pen<TPixel> DashDotDot<TPixel>(IBrush<TPixel> brush, float width) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
=> new Pen<TPixel>(brush, width, DashDotDotPattern); |
|
||||
} |
|
||||
} |
|
||||
@ -1,79 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using System; |
|
||||
using SixLabors.ImageSharp.PixelFormats; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Processing |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Provides a pen that can apply a pattern to a line with a set brush and thickness
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <remarks>
|
|
||||
/// The pattern will be in to the form of new float[]{ 1f, 2f, 0.5f} this will be
|
|
||||
/// converted into a pattern that is 3.5 times longer that the width with 3 sections
|
|
||||
/// section 1 will be width long (making a square) and will be filled by the brush
|
|
||||
/// section 2 will be width * 2 long and will be empty
|
|
||||
/// section 3 will be width/2 long and will be filled
|
|
||||
/// the the pattern will immediately repeat without gap.
|
|
||||
/// </remarks>
|
|
||||
public class Pen<TPixel> : IPen<TPixel> |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
{ |
|
||||
private readonly float[] pattern; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="Pen{TPixel}"/> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="width">The width.</param>
|
|
||||
/// <param name="pattern">The pattern.</param>
|
|
||||
public Pen(TPixel color, float width, float[] pattern) |
|
||||
: this(new SolidBrush<TPixel>(color), width, pattern) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="Pen{TPixel}"/> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="width">The width.</param>
|
|
||||
/// <param name="pattern">The pattern.</param>
|
|
||||
public Pen(IBrush<TPixel> brush, float width, float[] pattern) |
|
||||
{ |
|
||||
this.StrokeFill = brush; |
|
||||
this.StrokeWidth = width; |
|
||||
this.pattern = pattern; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="Pen{TPixel}"/> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="width">The width.</param>
|
|
||||
public Pen(TPixel color, float width) |
|
||||
: this(new SolidBrush<TPixel>(color), width) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="Pen{TPixel}"/> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="width">The width.</param>
|
|
||||
public Pen(IBrush<TPixel> brush, float width) |
|
||||
: this(brush, width, Pens.EmptyPattern) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
/// <inheritdoc/>
|
|
||||
public IBrush<TPixel> StrokeFill { get; } |
|
||||
|
|
||||
/// <inheritdoc/>
|
|
||||
public float StrokeWidth { get; } |
|
||||
|
|
||||
/// <inheritdoc/>
|
|
||||
public ReadOnlySpan<float> StrokePattern => this.pattern; |
|
||||
} |
|
||||
} |
|
||||
@ -1,99 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using System; |
|
||||
using System.Buffers; |
|
||||
using System.Threading.Tasks; |
|
||||
using SixLabors.ImageSharp.Advanced; |
|
||||
using SixLabors.ImageSharp.Memory; |
|
||||
using SixLabors.ImageSharp.ParallelUtils; |
|
||||
using SixLabors.ImageSharp.PixelFormats; |
|
||||
using SixLabors.Memory; |
|
||||
using SixLabors.Primitives; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Processing.Processors.Drawing |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Combines two images together by blending the pixels.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixelDst">The pixel format of destination image.</typeparam>
|
|
||||
/// <typeparam name="TPixelSrc">The pixel format of source image.</typeparam>
|
|
||||
internal class DrawImageProcessor<TPixelDst, TPixelSrc> : ImageProcessor<TPixelDst> |
|
||||
where TPixelDst : struct, IPixel<TPixelDst> |
|
||||
where TPixelSrc : struct, IPixel<TPixelSrc> |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="DrawImageProcessor{TPixelDst, TPixelSrc}"/> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="image">The image to blend with the currently processing image.</param>
|
|
||||
/// <param name="location">The location to draw the blended image.</param>
|
|
||||
/// <param name="colorBlendingMode">The blending mode to use when drawing the image.</param>
|
|
||||
/// <param name="alphaCompositionMode">The Alpha blending mode to use when drawing the image.</param>
|
|
||||
/// <param name="opacity">The opacity of the image to blend. Must be between 0 and 1.</param>
|
|
||||
public DrawImageProcessor(Image<TPixelSrc> image, Point location, PixelColorBlendingMode colorBlendingMode, PixelAlphaCompositionMode alphaCompositionMode, float opacity) |
|
||||
{ |
|
||||
Guard.MustBeBetweenOrEqualTo(opacity, 0, 1, nameof(opacity)); |
|
||||
|
|
||||
this.Image = image; |
|
||||
this.Opacity = opacity; |
|
||||
this.Blender = PixelOperations<TPixelDst>.Instance.GetPixelBlender(colorBlendingMode, alphaCompositionMode); |
|
||||
this.Location = location; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the image to blend
|
|
||||
/// </summary>
|
|
||||
public Image<TPixelSrc> Image { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the opacity of the image to blend
|
|
||||
/// </summary>
|
|
||||
public float Opacity { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the pixel blender
|
|
||||
/// </summary>
|
|
||||
public PixelBlender<TPixelDst> Blender { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the location to draw the blended image
|
|
||||
/// </summary>
|
|
||||
public Point Location { get; } |
|
||||
|
|
||||
/// <inheritdoc/>
|
|
||||
protected override void OnFrameApply(ImageFrame<TPixelDst> source, Rectangle sourceRectangle, Configuration configuration) |
|
||||
{ |
|
||||
Image<TPixelSrc> targetImage = this.Image; |
|
||||
PixelBlender<TPixelDst> blender = this.Blender; |
|
||||
int locationY = this.Location.Y; |
|
||||
|
|
||||
// Align start/end positions.
|
|
||||
Rectangle bounds = targetImage.Bounds(); |
|
||||
|
|
||||
int minX = Math.Max(this.Location.X, sourceRectangle.X); |
|
||||
int maxX = Math.Min(this.Location.X + bounds.Width, sourceRectangle.Width); |
|
||||
int targetX = minX - this.Location.X; |
|
||||
|
|
||||
int minY = Math.Max(this.Location.Y, sourceRectangle.Y); |
|
||||
int maxY = Math.Min(this.Location.Y + bounds.Height, sourceRectangle.Bottom); |
|
||||
|
|
||||
int width = maxX - minX; |
|
||||
|
|
||||
var workingRect = Rectangle.FromLTRB(minX, minY, maxX, maxY); |
|
||||
|
|
||||
ParallelHelper.IterateRows( |
|
||||
workingRect, |
|
||||
configuration, |
|
||||
rows => |
|
||||
{ |
|
||||
for (int y = rows.Min; y < rows.Max; y++) |
|
||||
{ |
|
||||
Span<TPixelDst> background = source.GetPixelRowSpan(y).Slice(minX, width); |
|
||||
Span<TPixelSrc> foreground = |
|
||||
targetImage.GetPixelRowSpan(y - locationY).Slice(targetX, width); |
|
||||
blender.Blend<TPixelSrc>(configuration, background, background, foreground, this.Opacity); |
|
||||
} |
|
||||
}); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,124 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using System; |
|
||||
using System.Buffers; |
|
||||
using System.Threading.Tasks; |
|
||||
using SixLabors.ImageSharp.Advanced; |
|
||||
using SixLabors.ImageSharp.Memory; |
|
||||
using SixLabors.ImageSharp.ParallelUtils; |
|
||||
using SixLabors.ImageSharp.PixelFormats; |
|
||||
using SixLabors.Memory; |
|
||||
using SixLabors.Primitives; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Processing.Processors.Drawing |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Using the brush as a source of pixels colors blends the brush color with source.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|
||||
internal class FillProcessor<TPixel> : ImageProcessor<TPixel> |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// The brush.
|
|
||||
/// </summary>
|
|
||||
private readonly IBrush<TPixel> brush; |
|
||||
private readonly GraphicsOptions options; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="FillProcessor{TPixel}"/> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="brush">The brush to source pixel colors from.</param>
|
|
||||
/// <param name="options">The options</param>
|
|
||||
public FillProcessor(IBrush<TPixel> brush, GraphicsOptions options) |
|
||||
{ |
|
||||
this.brush = brush; |
|
||||
this.options = options; |
|
||||
} |
|
||||
|
|
||||
/// <inheritdoc/>
|
|
||||
protected override void OnFrameApply(ImageFrame<TPixel> source, Rectangle sourceRectangle, Configuration configuration) |
|
||||
{ |
|
||||
int startX = sourceRectangle.X; |
|
||||
int endX = sourceRectangle.Right; |
|
||||
int startY = sourceRectangle.Y; |
|
||||
int endY = sourceRectangle.Bottom; |
|
||||
|
|
||||
// Align start/end positions.
|
|
||||
int minX = Math.Max(0, startX); |
|
||||
int maxX = Math.Min(source.Width, endX); |
|
||||
int minY = Math.Max(0, startY); |
|
||||
int maxY = Math.Min(source.Height, endY); |
|
||||
|
|
||||
int width = maxX - minX; |
|
||||
|
|
||||
var workingRect = Rectangle.FromLTRB(minX, minY, maxX, maxY); |
|
||||
|
|
||||
// If there's no reason for blending, then avoid it.
|
|
||||
if (this.IsSolidBrushWithoutBlending(out SolidBrush<TPixel> solidBrush)) |
|
||||
{ |
|
||||
ParallelExecutionSettings parallelSettings = configuration.GetParallelSettings().MultiplyMinimumPixelsPerTask(4); |
|
||||
|
|
||||
ParallelHelper.IterateRows( |
|
||||
workingRect, |
|
||||
parallelSettings, |
|
||||
rows => |
|
||||
{ |
|
||||
for (int y = rows.Min; y < rows.Max; y++) |
|
||||
{ |
|
||||
source.GetPixelRowSpan(y).Slice(minX, width).Fill(solidBrush.Color); |
|
||||
} |
|
||||
}); |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
// Reset offset if necessary.
|
|
||||
if (minX > 0) |
|
||||
{ |
|
||||
startX = 0; |
|
||||
} |
|
||||
|
|
||||
if (minY > 0) |
|
||||
{ |
|
||||
startY = 0; |
|
||||
} |
|
||||
|
|
||||
using (IMemoryOwner<float> amount = source.MemoryAllocator.Allocate<float>(width)) |
|
||||
using (BrushApplicator<TPixel> applicator = this.brush.CreateApplicator( |
|
||||
source, |
|
||||
sourceRectangle, |
|
||||
this.options)) |
|
||||
{ |
|
||||
amount.GetSpan().Fill(1f); |
|
||||
|
|
||||
ParallelHelper.IterateRows( |
|
||||
workingRect, |
|
||||
configuration, |
|
||||
rows => |
|
||||
{ |
|
||||
for (int y = rows.Min; y < rows.Max; y++) |
|
||||
{ |
|
||||
int offsetY = y - startY; |
|
||||
int offsetX = minX - startX; |
|
||||
|
|
||||
applicator.Apply(amount.GetSpan(), offsetX, offsetY); |
|
||||
} |
|
||||
}); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private bool IsSolidBrushWithoutBlending(out SolidBrush<TPixel> solidBrush) |
|
||||
{ |
|
||||
solidBrush = this.brush as SolidBrush<TPixel>; |
|
||||
|
|
||||
if (solidBrush == null) |
|
||||
{ |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
return this.options.IsOpaqueColorWithoutBlending(solidBrush.Color); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,219 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using System; |
|
||||
using System.Buffers; |
|
||||
using SixLabors.ImageSharp.Advanced; |
|
||||
using SixLabors.ImageSharp.Memory; |
|
||||
using SixLabors.ImageSharp.PixelFormats; |
|
||||
using SixLabors.ImageSharp.Primitives; |
|
||||
using SixLabors.ImageSharp.Utils; |
|
||||
using SixLabors.Memory; |
|
||||
using SixLabors.Primitives; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Processing.Processors.Drawing |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Using a brush and a shape fills shape with contents of brush the
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The type of the color.</typeparam>
|
|
||||
/// <seealso cref="ImageProcessor{TPixel}" />
|
|
||||
internal class FillRegionProcessor<TPixel> : ImageProcessor<TPixel> |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
{ |
|
||||
private const float AntialiasFactor = 1f; |
|
||||
private const int DrawPadding = 1; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="FillRegionProcessor{TPixel}" /> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="brush">The details how to fill the region of interest.</param>
|
|
||||
/// <param name="region">The region of interest to be filled.</param>
|
|
||||
/// <param name="options">The configuration options.</param>
|
|
||||
public FillRegionProcessor(IBrush<TPixel> brush, Region region, GraphicsOptions options) |
|
||||
{ |
|
||||
this.Region = region; |
|
||||
this.Brush = brush; |
|
||||
this.Options = options; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the brush.
|
|
||||
/// </summary>
|
|
||||
public IBrush<TPixel> Brush { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the region that this processor applies to.
|
|
||||
/// </summary>
|
|
||||
public Region Region { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the options.
|
|
||||
/// </summary>
|
|
||||
/// <value>
|
|
||||
/// The options.
|
|
||||
/// </value>
|
|
||||
public GraphicsOptions Options { get; } |
|
||||
|
|
||||
/// <inheritdoc/>
|
|
||||
protected override void OnFrameApply(ImageFrame<TPixel> source, Rectangle sourceRectangle, Configuration configuration) |
|
||||
{ |
|
||||
Region region = this.Region; |
|
||||
Rectangle rect = region.Bounds; |
|
||||
|
|
||||
// Align start/end positions.
|
|
||||
int minX = Math.Max(0, rect.Left); |
|
||||
int maxX = Math.Min(source.Width, rect.Right); |
|
||||
int minY = Math.Max(0, rect.Top); |
|
||||
int maxY = Math.Min(source.Height, rect.Bottom); |
|
||||
if (minX >= maxX) |
|
||||
{ |
|
||||
return; // no effect inside image;
|
|
||||
} |
|
||||
|
|
||||
if (minY >= maxY) |
|
||||
{ |
|
||||
return; // no effect inside image;
|
|
||||
} |
|
||||
|
|
||||
int maxIntersections = region.MaxIntersections; |
|
||||
float subpixelCount = 4; |
|
||||
|
|
||||
// we need to offset the pixel grid to account for when we outline a path.
|
|
||||
// basically if the line is [1,2] => [3,2] then when outlining at 1 we end up with a region of [0.5,1.5],[1.5, 1.5],[3.5,2.5],[2.5,2.5]
|
|
||||
// and this can cause missed fills when not using antialiasing.so we offset the pixel grid by 0.5 in the x & y direction thus causing the#
|
|
||||
// region to align with the pixel grid.
|
|
||||
float offset = 0.5f; |
|
||||
if (this.Options.Antialias) |
|
||||
{ |
|
||||
offset = 0f; // we are antialiasing skip offsetting as real antialiasing should take care of offset.
|
|
||||
subpixelCount = this.Options.AntialiasSubpixelDepth; |
|
||||
if (subpixelCount < 4) |
|
||||
{ |
|
||||
subpixelCount = 4; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
using (BrushApplicator<TPixel> applicator = this.Brush.CreateApplicator(source, rect, this.Options)) |
|
||||
{ |
|
||||
int scanlineWidth = maxX - minX; |
|
||||
using (IMemoryOwner<float> bBuffer = source.MemoryAllocator.Allocate<float>(maxIntersections)) |
|
||||
using (IMemoryOwner<float> bScanline = source.MemoryAllocator.Allocate<float>(scanlineWidth)) |
|
||||
{ |
|
||||
bool scanlineDirty = true; |
|
||||
float subpixelFraction = 1f / subpixelCount; |
|
||||
float subpixelFractionPoint = subpixelFraction / subpixelCount; |
|
||||
|
|
||||
Span<float> buffer = bBuffer.GetSpan(); |
|
||||
Span<float> scanline = bScanline.GetSpan(); |
|
||||
|
|
||||
bool isSolidBrushWithoutBlending = this.IsSolidBrushWithoutBlending(out SolidBrush<TPixel> solidBrush); |
|
||||
|
|
||||
for (int y = minY; y < maxY; y++) |
|
||||
{ |
|
||||
if (scanlineDirty) |
|
||||
{ |
|
||||
scanline.Clear(); |
|
||||
scanlineDirty = false; |
|
||||
} |
|
||||
|
|
||||
float yPlusOne = y + 1; |
|
||||
for (float subPixel = (float)y; subPixel < yPlusOne; subPixel += subpixelFraction) |
|
||||
{ |
|
||||
int pointsFound = region.Scan(subPixel + offset, buffer, configuration); |
|
||||
if (pointsFound == 0) |
|
||||
{ |
|
||||
// nothing on this line, skip
|
|
||||
continue; |
|
||||
} |
|
||||
|
|
||||
QuickSort.Sort(buffer.Slice(0, pointsFound)); |
|
||||
|
|
||||
for (int point = 0; point < pointsFound; point += 2) |
|
||||
{ |
|
||||
// points will be paired up
|
|
||||
float scanStart = buffer[point] - minX; |
|
||||
float scanEnd = buffer[point + 1] - minX; |
|
||||
int startX = (int)MathF.Floor(scanStart + offset); |
|
||||
int endX = (int)MathF.Floor(scanEnd + offset); |
|
||||
|
|
||||
if (startX >= 0 && startX < scanline.Length) |
|
||||
{ |
|
||||
for (float x = scanStart; x < startX + 1; x += subpixelFraction) |
|
||||
{ |
|
||||
scanline[startX] += subpixelFractionPoint; |
|
||||
scanlineDirty = true; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
if (endX >= 0 && endX < scanline.Length) |
|
||||
{ |
|
||||
for (float x = endX; x < scanEnd; x += subpixelFraction) |
|
||||
{ |
|
||||
scanline[endX] += subpixelFractionPoint; |
|
||||
scanlineDirty = true; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
int nextX = startX + 1; |
|
||||
endX = Math.Min(endX, scanline.Length); // reduce to end to the right edge
|
|
||||
nextX = Math.Max(nextX, 0); |
|
||||
for (int x = nextX; x < endX; x++) |
|
||||
{ |
|
||||
scanline[x] += subpixelFraction; |
|
||||
scanlineDirty = true; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
if (scanlineDirty) |
|
||||
{ |
|
||||
if (!this.Options.Antialias) |
|
||||
{ |
|
||||
bool hasOnes = false; |
|
||||
bool hasZeros = false; |
|
||||
for (int x = 0; x < scanlineWidth; x++) |
|
||||
{ |
|
||||
if (scanline[x] >= 0.5) |
|
||||
{ |
|
||||
scanline[x] = 1; |
|
||||
hasOnes = true; |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
scanline[x] = 0; |
|
||||
hasZeros = true; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
if (isSolidBrushWithoutBlending && hasOnes != hasZeros) |
|
||||
{ |
|
||||
if (hasOnes) |
|
||||
{ |
|
||||
source.GetPixelRowSpan(y).Slice(minX, scanlineWidth).Fill(solidBrush.Color); |
|
||||
} |
|
||||
|
|
||||
continue; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
applicator.Apply(scanline, minX, y); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private bool IsSolidBrushWithoutBlending(out SolidBrush<TPixel> solidBrush) |
|
||||
{ |
|
||||
solidBrush = this.Brush as SolidBrush<TPixel>; |
|
||||
|
|
||||
if (solidBrush == null) |
|
||||
{ |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
return this.Options.IsOpaqueColorWithoutBlending(solidBrush.Color); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,483 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using System; |
|
||||
using System.Buffers; |
|
||||
using System.Collections.Generic; |
|
||||
using SixLabors.Fonts; |
|
||||
using SixLabors.ImageSharp.Advanced; |
|
||||
using SixLabors.ImageSharp.Memory; |
|
||||
using SixLabors.ImageSharp.PixelFormats; |
|
||||
using SixLabors.ImageSharp.Utils; |
|
||||
using SixLabors.Memory; |
|
||||
using SixLabors.Primitives; |
|
||||
using SixLabors.Shapes; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Processing.Processors.Text |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Using the brush as a source of pixels colors blends the brush color with source.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|
||||
internal class DrawTextProcessor<TPixel> : ImageProcessor<TPixel> |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
{ |
|
||||
private CachingGlyphRenderer textRenderer; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="DrawTextProcessor{TPixel}"/> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="options">The options</param>
|
|
||||
/// <param name="text">The text we want to render</param>
|
|
||||
/// <param name="font">The font we want to render with</param>
|
|
||||
/// <param name="brush">The brush to source pixel colors from.</param>
|
|
||||
/// <param name="pen">The pen to outline text with.</param>
|
|
||||
/// <param name="location">The location on the image to start drawing the text from.</param>
|
|
||||
public DrawTextProcessor(TextGraphicsOptions options, string text, Font font, IBrush<TPixel> brush, IPen<TPixel> pen, PointF location) |
|
||||
{ |
|
||||
Guard.NotNull(text, nameof(text)); |
|
||||
Guard.NotNull(font, nameof(font)); |
|
||||
|
|
||||
if (brush is null && pen is null) |
|
||||
{ |
|
||||
throw new ArgumentNullException($"Expected a {nameof(brush)} or {nameof(pen)}. Both were null"); |
|
||||
} |
|
||||
|
|
||||
this.Options = options; |
|
||||
this.Text = text; |
|
||||
this.Font = font; |
|
||||
this.Location = location; |
|
||||
this.Brush = brush; |
|
||||
this.Pen = pen; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the brush.
|
|
||||
/// </summary>
|
|
||||
public IBrush<TPixel> Brush { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the options
|
|
||||
/// </summary>
|
|
||||
public TextGraphicsOptions Options { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the text
|
|
||||
/// </summary>
|
|
||||
public string Text { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the pen used for outlining the text, if Null then we will not outline
|
|
||||
/// </summary>
|
|
||||
public IPen<TPixel> Pen { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the font used to render the text.
|
|
||||
/// </summary>
|
|
||||
public Font Font { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the location to draw the text at.
|
|
||||
/// </summary>
|
|
||||
public PointF Location { get; } |
|
||||
|
|
||||
protected override void BeforeImageApply(Image<TPixel> source, Rectangle sourceRectangle) |
|
||||
{ |
|
||||
base.BeforeImageApply(source, sourceRectangle); |
|
||||
|
|
||||
// do everything at the image level as we are delegating the processing down to other processors
|
|
||||
var style = new RendererOptions(this.Font, this.Options.DpiX, this.Options.DpiY, this.Location) |
|
||||
{ |
|
||||
ApplyKerning = this.Options.ApplyKerning, |
|
||||
TabWidth = this.Options.TabWidth, |
|
||||
WrappingWidth = this.Options.WrapTextWidth, |
|
||||
HorizontalAlignment = this.Options.HorizontalAlignment, |
|
||||
VerticalAlignment = this.Options.VerticalAlignment |
|
||||
}; |
|
||||
|
|
||||
this.textRenderer = new CachingGlyphRenderer(source.GetMemoryAllocator(), this.Text.Length, this.Pen, this.Brush != null); |
|
||||
this.textRenderer.Options = (GraphicsOptions)this.Options; |
|
||||
var renderer = new TextRenderer(this.textRenderer); |
|
||||
renderer.RenderText(this.Text, style); |
|
||||
} |
|
||||
|
|
||||
protected override void AfterImageApply(Image<TPixel> source, Rectangle sourceRectangle) |
|
||||
{ |
|
||||
base.AfterImageApply(source, sourceRectangle); |
|
||||
this.textRenderer?.Dispose(); |
|
||||
this.textRenderer = null; |
|
||||
} |
|
||||
|
|
||||
/// <inheritdoc/>
|
|
||||
protected override void OnFrameApply(ImageFrame<TPixel> source, Rectangle sourceRectangle, Configuration configuration) |
|
||||
{ |
|
||||
// this is a no-op as we have processes all as an image, we should be able to pass out of before email apply a skip frames outcome
|
|
||||
Draw(this.textRenderer.FillOperations, this.Brush); |
|
||||
Draw(this.textRenderer.OutlineOperations, this.Pen?.StrokeFill); |
|
||||
|
|
||||
void Draw(List<DrawingOperation> operations, IBrush<TPixel> brush) |
|
||||
{ |
|
||||
if (operations?.Count > 0) |
|
||||
{ |
|
||||
using (BrushApplicator<TPixel> app = brush.CreateApplicator(source, sourceRectangle, this.textRenderer.Options)) |
|
||||
{ |
|
||||
foreach (DrawingOperation operation in operations) |
|
||||
{ |
|
||||
Buffer2D<float> buffer = operation.Map; |
|
||||
int startY = operation.Location.Y; |
|
||||
int startX = operation.Location.X; |
|
||||
int offSetSpan = 0; |
|
||||
if (startX < 0) |
|
||||
{ |
|
||||
offSetSpan = -startX; |
|
||||
startX = 0; |
|
||||
} |
|
||||
|
|
||||
int fistRow = 0; |
|
||||
if (startY < 0) |
|
||||
{ |
|
||||
fistRow = -startY; |
|
||||
} |
|
||||
|
|
||||
int maxHeight = source.Height - startY; |
|
||||
int end = Math.Min(operation.Map.Height, maxHeight); |
|
||||
|
|
||||
for (int row = fistRow; row < end; row++) |
|
||||
{ |
|
||||
int y = startY + row; |
|
||||
Span<float> span = buffer.GetRowSpan(row).Slice(offSetSpan); |
|
||||
app.Apply(span, startX, y); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private struct DrawingOperation |
|
||||
{ |
|
||||
public Buffer2D<float> Map { get; set; } |
|
||||
|
|
||||
public Point Location { get; set; } |
|
||||
} |
|
||||
|
|
||||
private class CachingGlyphRenderer : IGlyphRenderer, IDisposable |
|
||||
{ |
|
||||
// just enough accuracy to allow for 1/8 pixel differences which
|
|
||||
// later are accumulated while rendering, but do not grow into full pixel offsets
|
|
||||
// The value 8 is benchmarked to:
|
|
||||
// - Provide a good accuracy (smaller than 0.2% image difference compared to the non-caching variant)
|
|
||||
// - Cache hit ratio above 60%
|
|
||||
private const float AccuracyMultiple = 8; |
|
||||
|
|
||||
private readonly PathBuilder builder; |
|
||||
|
|
||||
private Point currentRenderPosition = default; |
|
||||
private (GlyphRendererParameters glyph, PointF subPixelOffset) currentGlyphRenderParams = default; |
|
||||
private readonly int offset = 0; |
|
||||
private PointF currentPoint = default(PointF); |
|
||||
|
|
||||
private readonly Dictionary<(GlyphRendererParameters glyph, PointF subPixelOffset), GlyphRenderData> |
|
||||
glyphData = new Dictionary<(GlyphRendererParameters glyph, PointF subPixelOffset), GlyphRenderData>(); |
|
||||
|
|
||||
private readonly bool renderOutline = false; |
|
||||
private readonly bool renderFill = false; |
|
||||
private bool rasterizationRequired = false; |
|
||||
|
|
||||
public CachingGlyphRenderer(MemoryAllocator memoryAllocator, int size, IPen pen, bool renderFill) |
|
||||
{ |
|
||||
this.MemoryAllocator = memoryAllocator; |
|
||||
this.Pen = pen; |
|
||||
this.renderFill = renderFill; |
|
||||
this.renderOutline = pen != null; |
|
||||
this.offset = 2; |
|
||||
if (this.renderFill) |
|
||||
{ |
|
||||
this.FillOperations = new List<DrawingOperation>(size); |
|
||||
} |
|
||||
|
|
||||
if (this.renderOutline) |
|
||||
{ |
|
||||
this.offset = (int)MathF.Ceiling((pen.StrokeWidth * 2) + 2); |
|
||||
this.OutlineOperations = new List<DrawingOperation>(size); |
|
||||
} |
|
||||
|
|
||||
this.builder = new PathBuilder(); |
|
||||
} |
|
||||
|
|
||||
public List<DrawingOperation> FillOperations { get; } |
|
||||
|
|
||||
public List<DrawingOperation> OutlineOperations { get; } |
|
||||
|
|
||||
public MemoryAllocator MemoryAllocator { get; internal set; } |
|
||||
|
|
||||
public IPen Pen { get; internal set; } |
|
||||
|
|
||||
public GraphicsOptions Options { get; internal set; } |
|
||||
|
|
||||
public void BeginFigure() |
|
||||
{ |
|
||||
this.builder.StartFigure(); |
|
||||
} |
|
||||
|
|
||||
public bool BeginGlyph(RectangleF bounds, GlyphRendererParameters parameters) |
|
||||
{ |
|
||||
this.currentRenderPosition = Point.Truncate(bounds.Location); |
|
||||
PointF subPixelOffset = bounds.Location - this.currentRenderPosition; |
|
||||
|
|
||||
subPixelOffset.X = MathF.Round(subPixelOffset.X * AccuracyMultiple) / AccuracyMultiple; |
|
||||
subPixelOffset.Y = MathF.Round(subPixelOffset.Y * AccuracyMultiple) / AccuracyMultiple; |
|
||||
|
|
||||
// we have offset our rendering origion a little bit down to prevent edge cropping, move the draw origin up to compensate
|
|
||||
this.currentRenderPosition = new Point(this.currentRenderPosition.X - this.offset, this.currentRenderPosition.Y - this.offset); |
|
||||
this.currentGlyphRenderParams = (parameters, subPixelOffset); |
|
||||
|
|
||||
if (this.glyphData.ContainsKey(this.currentGlyphRenderParams)) |
|
||||
{ |
|
||||
// we have already drawn the glyph vectors skip trying again
|
|
||||
this.rasterizationRequired = false; |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
// we check to see if we have a render cache and if we do then we render else
|
|
||||
this.builder.Clear(); |
|
||||
|
|
||||
// ensure all glyphs render around [zero, zero] so offset negative root positions so when we draw the glyph we can offet it back
|
|
||||
this.builder.SetOrigin(new PointF(-(int)bounds.X + this.offset, -(int)bounds.Y + this.offset)); |
|
||||
|
|
||||
this.rasterizationRequired = true; |
|
||||
return true; |
|
||||
} |
|
||||
|
|
||||
public void BeginText(RectangleF bounds) |
|
||||
{ |
|
||||
// not concerned about this one
|
|
||||
this.OutlineOperations?.Clear(); |
|
||||
this.FillOperations?.Clear(); |
|
||||
} |
|
||||
|
|
||||
public void CubicBezierTo(PointF secondControlPoint, PointF thirdControlPoint, PointF point) |
|
||||
{ |
|
||||
this.builder.AddBezier(this.currentPoint, secondControlPoint, thirdControlPoint, point); |
|
||||
this.currentPoint = point; |
|
||||
} |
|
||||
|
|
||||
public void Dispose() |
|
||||
{ |
|
||||
foreach (KeyValuePair<(GlyphRendererParameters glyph, PointF subPixelOffset), GlyphRenderData> kv in this.glyphData) |
|
||||
{ |
|
||||
kv.Value.Dispose(); |
|
||||
} |
|
||||
|
|
||||
this.glyphData.Clear(); |
|
||||
} |
|
||||
|
|
||||
public void EndFigure() |
|
||||
{ |
|
||||
this.builder.CloseFigure(); |
|
||||
} |
|
||||
|
|
||||
public void EndGlyph() |
|
||||
{ |
|
||||
GlyphRenderData renderData = default; |
|
||||
|
|
||||
// has the glyoh been rendedered already????
|
|
||||
if (this.rasterizationRequired) |
|
||||
{ |
|
||||
IPath path = this.builder.Build(); |
|
||||
|
|
||||
if (this.renderFill) |
|
||||
{ |
|
||||
renderData.FillMap = this.Render(path); |
|
||||
} |
|
||||
|
|
||||
if (this.renderOutline) |
|
||||
{ |
|
||||
if (this.Pen.StrokePattern.Length == 0) |
|
||||
{ |
|
||||
path = path.GenerateOutline(this.Pen.StrokeWidth); |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
path = path.GenerateOutline(this.Pen.StrokeWidth, this.Pen.StrokePattern); |
|
||||
} |
|
||||
|
|
||||
renderData.OutlineMap = this.Render(path); |
|
||||
} |
|
||||
|
|
||||
this.glyphData[this.currentGlyphRenderParams] = renderData; |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
renderData = this.glyphData[this.currentGlyphRenderParams]; |
|
||||
} |
|
||||
|
|
||||
if (this.renderFill) |
|
||||
{ |
|
||||
this.FillOperations.Add(new DrawingOperation |
|
||||
{ |
|
||||
Location = this.currentRenderPosition, |
|
||||
Map = renderData.FillMap |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
if (this.renderOutline) |
|
||||
{ |
|
||||
this.OutlineOperations.Add(new DrawingOperation |
|
||||
{ |
|
||||
Location = this.currentRenderPosition, |
|
||||
Map = renderData.OutlineMap |
|
||||
}); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private Buffer2D<float> Render(IPath path) |
|
||||
{ |
|
||||
Size size = Rectangle.Ceiling(path.Bounds).Size; |
|
||||
size = new Size(size.Width + (this.offset * 2), size.Height + (this.offset * 2)); |
|
||||
|
|
||||
float subpixelCount = 4; |
|
||||
float offset = 0.5f; |
|
||||
if (this.Options.Antialias) |
|
||||
{ |
|
||||
offset = 0f; // we are antialising skip offsetting as real antalising should take care of offset.
|
|
||||
subpixelCount = this.Options.AntialiasSubpixelDepth; |
|
||||
if (subpixelCount < 4) |
|
||||
{ |
|
||||
subpixelCount = 4; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// take the path inside the path builder, scan thing and generate a Buffer2d representing the glyph and cache it.
|
|
||||
Buffer2D<float> fullBuffer = this.MemoryAllocator.Allocate2D<float>(size.Width + 1, size.Height + 1, AllocationOptions.Clean); |
|
||||
|
|
||||
using (IMemoryOwner<float> bufferBacking = this.MemoryAllocator.Allocate<float>(path.MaxIntersections)) |
|
||||
using (IMemoryOwner<PointF> rowIntersectionBuffer = this.MemoryAllocator.Allocate<PointF>(size.Width)) |
|
||||
{ |
|
||||
float subpixelFraction = 1f / subpixelCount; |
|
||||
float subpixelFractionPoint = subpixelFraction / subpixelCount; |
|
||||
|
|
||||
for (int y = 0; y <= size.Height; y++) |
|
||||
{ |
|
||||
Span<float> scanline = fullBuffer.GetRowSpan(y); |
|
||||
bool scanlineDirty = false; |
|
||||
float yPlusOne = y + 1; |
|
||||
|
|
||||
for (float subPixel = (float)y; subPixel < yPlusOne; subPixel += subpixelFraction) |
|
||||
{ |
|
||||
var start = new PointF(path.Bounds.Left - 1, subPixel); |
|
||||
var end = new PointF(path.Bounds.Right + 1, subPixel); |
|
||||
Span<PointF> intersectionSpan = rowIntersectionBuffer.GetSpan(); |
|
||||
Span<float> buffer = bufferBacking.GetSpan(); |
|
||||
int pointsFound = path.FindIntersections(start, end, intersectionSpan); |
|
||||
|
|
||||
if (pointsFound == 0) |
|
||||
{ |
|
||||
// nothing on this line skip
|
|
||||
continue; |
|
||||
} |
|
||||
|
|
||||
for (int i = 0; i < pointsFound && i < intersectionSpan.Length; i++) |
|
||||
{ |
|
||||
buffer[i] = intersectionSpan[i].X; |
|
||||
} |
|
||||
|
|
||||
QuickSort.Sort(buffer.Slice(0, pointsFound)); |
|
||||
|
|
||||
for (int point = 0; point < pointsFound; point += 2) |
|
||||
{ |
|
||||
// points will be paired up
|
|
||||
float scanStart = buffer[point]; |
|
||||
float scanEnd = buffer[point + 1]; |
|
||||
int startX = (int)MathF.Floor(scanStart + offset); |
|
||||
int endX = (int)MathF.Floor(scanEnd + offset); |
|
||||
|
|
||||
if (startX >= 0 && startX < scanline.Length) |
|
||||
{ |
|
||||
for (float x = scanStart; x < startX + 1; x += subpixelFraction) |
|
||||
{ |
|
||||
scanline[startX] += subpixelFractionPoint; |
|
||||
scanlineDirty = true; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
if (endX >= 0 && endX < scanline.Length) |
|
||||
{ |
|
||||
for (float x = endX; x < scanEnd; x += subpixelFraction) |
|
||||
{ |
|
||||
scanline[endX] += subpixelFractionPoint; |
|
||||
scanlineDirty = true; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
int nextX = startX + 1; |
|
||||
endX = Math.Min(endX, scanline.Length); // reduce to end to the right edge
|
|
||||
nextX = Math.Max(nextX, 0); |
|
||||
for (int x = nextX; x < endX; x++) |
|
||||
{ |
|
||||
scanline[x] += subpixelFraction; |
|
||||
scanlineDirty = true; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
if (scanlineDirty) |
|
||||
{ |
|
||||
if (!this.Options.Antialias) |
|
||||
{ |
|
||||
for (int x = 0; x < size.Width; x++) |
|
||||
{ |
|
||||
if (scanline[x] >= 0.5) |
|
||||
{ |
|
||||
scanline[x] = 1; |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
scanline[x] = 0; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
return fullBuffer; |
|
||||
} |
|
||||
|
|
||||
public void EndText() |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
public void LineTo(PointF point) |
|
||||
{ |
|
||||
this.builder.AddLine(this.currentPoint, point); |
|
||||
this.currentPoint = point; |
|
||||
} |
|
||||
|
|
||||
public void MoveTo(PointF point) |
|
||||
{ |
|
||||
this.builder.StartFigure(); |
|
||||
this.currentPoint = point; |
|
||||
} |
|
||||
|
|
||||
public void QuadraticBezierTo(PointF secondControlPoint, PointF point) |
|
||||
{ |
|
||||
this.builder.AddBezier(this.currentPoint, secondControlPoint, point); |
|
||||
this.currentPoint = point; |
|
||||
} |
|
||||
|
|
||||
private struct GlyphRenderData : IDisposable |
|
||||
{ |
|
||||
public Buffer2D<float> FillMap; |
|
||||
|
|
||||
public Buffer2D<float> OutlineMap; |
|
||||
|
|
||||
public void Dispose() |
|
||||
{ |
|
||||
this.FillMap?.Dispose(); |
|
||||
this.OutlineMap?.Dispose(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,105 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using System; |
|
||||
|
|
||||
using SixLabors.ImageSharp.PixelFormats; |
|
||||
using SixLabors.Primitives; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Processing |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// A Circular Gradient Brush, defined by center point and radius.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|
||||
public sealed class RadialGradientBrush<TPixel> : GradientBrushBase<TPixel> |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
{ |
|
||||
private readonly PointF center; |
|
||||
|
|
||||
private readonly float radius; |
|
||||
|
|
||||
/// <inheritdoc cref="GradientBrushBase{TPixel}" />
|
|
||||
/// <param name="center">The center of the circular gradient and 0 for the color stops.</param>
|
|
||||
/// <param name="radius">The radius of the circular gradient and 1 for the color stops.</param>
|
|
||||
/// <param name="repetitionMode">Defines how the colors in the gradient are repeated.</param>
|
|
||||
/// <param name="colorStops">the color stops as defined in base class.</param>
|
|
||||
public RadialGradientBrush( |
|
||||
PointF center, |
|
||||
float radius, |
|
||||
GradientRepetitionMode repetitionMode, |
|
||||
params ColorStop<TPixel>[] colorStops) |
|
||||
: base(repetitionMode, colorStops) |
|
||||
{ |
|
||||
this.center = center; |
|
||||
this.radius = radius; |
|
||||
} |
|
||||
|
|
||||
/// <inheritdoc cref="CreateApplicator" />
|
|
||||
public override BrushApplicator<TPixel> CreateApplicator( |
|
||||
ImageFrame<TPixel> source, |
|
||||
RectangleF region, |
|
||||
GraphicsOptions options) => |
|
||||
new RadialGradientBrushApplicator( |
|
||||
source, |
|
||||
options, |
|
||||
this.center, |
|
||||
this.radius, |
|
||||
this.ColorStops, |
|
||||
this.RepetitionMode); |
|
||||
|
|
||||
/// <inheritdoc />
|
|
||||
private sealed class RadialGradientBrushApplicator : GradientBrushApplicatorBase |
|
||||
{ |
|
||||
private readonly PointF center; |
|
||||
|
|
||||
private readonly float radius; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="RadialGradientBrushApplicator" /> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="target">The target image</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <param name="center">Center point of the gradient.</param>
|
|
||||
/// <param name="radius">Radius of the gradient.</param>
|
|
||||
/// <param name="colorStops">Definition of colors.</param>
|
|
||||
/// <param name="repetitionMode">How the colors are repeated beyond the first gradient.</param>
|
|
||||
public RadialGradientBrushApplicator( |
|
||||
ImageFrame<TPixel> target, |
|
||||
GraphicsOptions options, |
|
||||
PointF center, |
|
||||
float radius, |
|
||||
ColorStop<TPixel>[] colorStops, |
|
||||
GradientRepetitionMode repetitionMode) |
|
||||
: base(target, options, colorStops, repetitionMode) |
|
||||
{ |
|
||||
this.center = center; |
|
||||
this.radius = radius; |
|
||||
} |
|
||||
|
|
||||
/// <inheritdoc cref="Dispose" />
|
|
||||
public override void Dispose() |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// As this is a circular gradient, the position on the gradient is based on
|
|
||||
/// the distance of the point to the center.
|
|
||||
/// </summary>
|
|
||||
/// <param name="x">The X coordinate of the target pixel.</param>
|
|
||||
/// <param name="y">The Y coordinate of the target pixel.</param>
|
|
||||
/// <returns>the position on the color gradient.</returns>
|
|
||||
protected override float PositionOnGradient(float x, float y) |
|
||||
{ |
|
||||
float distance = (float)Math.Sqrt(Math.Pow(this.center.X - x, 2) + Math.Pow(this.center.Y - y, 2)); |
|
||||
return distance / this.radius; |
|
||||
} |
|
||||
|
|
||||
internal override void Apply(Span<float> scanline, int x, int y) |
|
||||
{ |
|
||||
// TODO: each row is symmetric across center, so we can calculate half of it and mirror it to improve performance.
|
|
||||
base.Apply(scanline, x, y); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,171 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using System; |
|
||||
using System.Buffers; |
|
||||
using System.Numerics; |
|
||||
using SixLabors.ImageSharp.Advanced; |
|
||||
using SixLabors.ImageSharp.Memory; |
|
||||
using SixLabors.ImageSharp.PixelFormats; |
|
||||
using SixLabors.Memory; |
|
||||
using SixLabors.Primitives; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Processing |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Provides an implementation of a brush that can recolor an image
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|
||||
public class RecolorBrush<TPixel> : IBrush<TPixel> |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="RecolorBrush{TPixel}" /> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="sourceColor">Color of the source.</param>
|
|
||||
/// <param name="targetColor">Color of the target.</param>
|
|
||||
/// <param name="threshold">The threshold as a value between 0 and 1.</param>
|
|
||||
public RecolorBrush(TPixel sourceColor, TPixel targetColor, float threshold) |
|
||||
{ |
|
||||
this.SourceColor = sourceColor; |
|
||||
this.Threshold = threshold; |
|
||||
this.TargetColor = targetColor; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the threshold.
|
|
||||
/// </summary>
|
|
||||
public float Threshold { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the source color.
|
|
||||
/// </summary>
|
|
||||
/// <value>
|
|
||||
/// The color of the source.
|
|
||||
/// </value>
|
|
||||
public TPixel SourceColor { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the target color.
|
|
||||
/// </summary>
|
|
||||
public TPixel TargetColor { get; } |
|
||||
|
|
||||
/// <inheritdoc />
|
|
||||
public BrushApplicator<TPixel> CreateApplicator(ImageFrame<TPixel> source, RectangleF region, GraphicsOptions options) |
|
||||
{ |
|
||||
return new RecolorBrushApplicator(source, this.SourceColor, this.TargetColor, this.Threshold, options); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// The recolor brush applicator.
|
|
||||
/// </summary>
|
|
||||
private class RecolorBrushApplicator : BrushApplicator<TPixel> |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// The source color.
|
|
||||
/// </summary>
|
|
||||
private readonly Vector4 sourceColor; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// The target color.
|
|
||||
/// </summary>
|
|
||||
private readonly Vector4 targetColor; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// The threshold.
|
|
||||
/// </summary>
|
|
||||
private readonly float threshold; |
|
||||
|
|
||||
private readonly TPixel targetColorPixel; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="RecolorBrushApplicator" /> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The source image.</param>
|
|
||||
/// <param name="sourceColor">Color of the source.</param>
|
|
||||
/// <param name="targetColor">Color of the target.</param>
|
|
||||
/// <param name="threshold">The threshold .</param>
|
|
||||
/// <param name="options">The options</param>
|
|
||||
public RecolorBrushApplicator(ImageFrame<TPixel> source, TPixel sourceColor, TPixel targetColor, float threshold, GraphicsOptions options) |
|
||||
: base(source, options) |
|
||||
{ |
|
||||
this.sourceColor = sourceColor.ToVector4(); |
|
||||
this.targetColor = targetColor.ToVector4(); |
|
||||
this.targetColorPixel = targetColor; |
|
||||
|
|
||||
// Lets hack a min max extremes for a color space by letting the IPackedPixel clamp our values to something in the correct spaces :)
|
|
||||
var maxColor = default(TPixel); |
|
||||
maxColor.FromVector4(new Vector4(float.MaxValue)); |
|
||||
var minColor = default(TPixel); |
|
||||
minColor.FromVector4(new Vector4(float.MinValue)); |
|
||||
this.threshold = Vector4.DistanceSquared(maxColor.ToVector4(), minColor.ToVector4()) * threshold; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the color for a single pixel.
|
|
||||
/// </summary>
|
|
||||
/// <param name="x">The x.</param>
|
|
||||
/// <param name="y">The y.</param>
|
|
||||
/// <returns>
|
|
||||
/// The color
|
|
||||
/// </returns>
|
|
||||
internal override TPixel this[int x, int y] |
|
||||
{ |
|
||||
get |
|
||||
{ |
|
||||
// Offset the requested pixel by the value in the rectangle (the shapes position)
|
|
||||
TPixel result = this.Target[x, y]; |
|
||||
var background = result.ToVector4(); |
|
||||
float distance = Vector4.DistanceSquared(background, this.sourceColor); |
|
||||
if (distance <= this.threshold) |
|
||||
{ |
|
||||
float lerpAmount = (this.threshold - distance) / this.threshold; |
|
||||
return this.Blender.Blend( |
|
||||
result, |
|
||||
this.targetColorPixel, |
|
||||
lerpAmount); |
|
||||
} |
|
||||
|
|
||||
return result; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/// <inheritdoc />
|
|
||||
public override void Dispose() |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
/// <inheritdoc />
|
|
||||
internal override void Apply(Span<float> scanline, int x, int y) |
|
||||
{ |
|
||||
MemoryAllocator memoryAllocator = this.Target.MemoryAllocator; |
|
||||
|
|
||||
using (IMemoryOwner<float> amountBuffer = memoryAllocator.Allocate<float>(scanline.Length)) |
|
||||
using (IMemoryOwner<TPixel> overlay = memoryAllocator.Allocate<TPixel>(scanline.Length)) |
|
||||
{ |
|
||||
Span<float> amountSpan = amountBuffer.GetSpan(); |
|
||||
Span<TPixel> overlaySpan = overlay.GetSpan(); |
|
||||
|
|
||||
for (int i = 0; i < scanline.Length; i++) |
|
||||
{ |
|
||||
amountSpan[i] = scanline[i] * this.Options.BlendPercentage; |
|
||||
|
|
||||
int offsetX = x + i; |
|
||||
|
|
||||
// No doubt this one can be optimized further but I can't imagine its
|
|
||||
// actually being used and can probably be removed/internalized for now
|
|
||||
overlaySpan[i] = this[offsetX, y]; |
|
||||
} |
|
||||
|
|
||||
Span<TPixel> destinationRow = this.Target.GetPixelRowSpan(y).Slice(x, scanline.Length); |
|
||||
this.Blender.Blend( |
|
||||
this.Target.Configuration, |
|
||||
destinationRow, |
|
||||
destinationRow, |
|
||||
overlaySpan, |
|
||||
amountSpan); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,133 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using System; |
|
||||
using System.Buffers; |
|
||||
|
|
||||
using SixLabors.ImageSharp.Advanced; |
|
||||
using SixLabors.ImageSharp.Memory; |
|
||||
using SixLabors.ImageSharp.PixelFormats; |
|
||||
using SixLabors.Memory; |
|
||||
using SixLabors.Primitives; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Processing |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Provides an implementation of a solid brush for painting solid color areas.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|
||||
public class SolidBrush<TPixel> : IBrush<TPixel> |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// The color to paint.
|
|
||||
/// </summary>
|
|
||||
private readonly TPixel color; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="SolidBrush{TPixel}"/> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
public SolidBrush(TPixel color) |
|
||||
{ |
|
||||
this.color = color; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the color.
|
|
||||
/// </summary>
|
|
||||
/// <value>
|
|
||||
/// The color.
|
|
||||
/// </value>
|
|
||||
public TPixel Color => this.color; |
|
||||
|
|
||||
/// <inheritdoc />
|
|
||||
public BrushApplicator<TPixel> CreateApplicator(ImageFrame<TPixel> source, RectangleF region, GraphicsOptions options) |
|
||||
{ |
|
||||
return new SolidBrushApplicator(source, this.color, options); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// The solid brush applicator.
|
|
||||
/// </summary>
|
|
||||
private class SolidBrushApplicator : BrushApplicator<TPixel> |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="SolidBrushApplicator"/> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="source">The source image.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="options">The options</param>
|
|
||||
public SolidBrushApplicator(ImageFrame<TPixel> source, TPixel color, GraphicsOptions options) |
|
||||
: base(source, options) |
|
||||
{ |
|
||||
this.Colors = source.MemoryAllocator.Allocate<TPixel>(source.Width); |
|
||||
this.Colors.GetSpan().Fill(color); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the colors.
|
|
||||
/// </summary>
|
|
||||
protected IMemoryOwner<TPixel> Colors { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the color for a single pixel.
|
|
||||
/// </summary>
|
|
||||
/// <param name="x">The x.</param>
|
|
||||
/// <param name="y">The y.</param>
|
|
||||
/// <returns>
|
|
||||
/// The color
|
|
||||
/// </returns>
|
|
||||
internal override TPixel this[int x, int y] => this.Colors.GetSpan()[x]; |
|
||||
|
|
||||
/// <inheritdoc />
|
|
||||
public override void Dispose() |
|
||||
{ |
|
||||
this.Colors.Dispose(); |
|
||||
} |
|
||||
|
|
||||
/// <inheritdoc />
|
|
||||
internal override void Apply(Span<float> scanline, int x, int y) |
|
||||
{ |
|
||||
Span<TPixel> destinationRow = this.Target.GetPixelRowSpan(y).Slice(x); |
|
||||
|
|
||||
// constrain the spans to each other
|
|
||||
if (destinationRow.Length > scanline.Length) |
|
||||
{ |
|
||||
destinationRow = destinationRow.Slice(0, scanline.Length); |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
scanline = scanline.Slice(0, destinationRow.Length); |
|
||||
} |
|
||||
|
|
||||
MemoryAllocator memoryAllocator = this.Target.MemoryAllocator; |
|
||||
Configuration configuration = this.Target.Configuration; |
|
||||
|
|
||||
if (this.Options.BlendPercentage == 1f) |
|
||||
{ |
|
||||
this.Blender.Blend(configuration, destinationRow, destinationRow, this.Colors.GetSpan(), scanline); |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
using (IMemoryOwner<float> amountBuffer = memoryAllocator.Allocate<float>(scanline.Length)) |
|
||||
{ |
|
||||
Span<float> amountSpan = amountBuffer.GetSpan(); |
|
||||
|
|
||||
for (int i = 0; i < scanline.Length; i++) |
|
||||
{ |
|
||||
amountSpan[i] = scanline[i] * this.Options.BlendPercentage; |
|
||||
} |
|
||||
|
|
||||
this.Blender.Blend( |
|
||||
configuration, |
|
||||
destinationRow, |
|
||||
destinationRow, |
|
||||
this.Colors.GetSpan(), |
|
||||
amountSpan); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,169 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using SixLabors.Fonts; |
|
||||
using SixLabors.ImageSharp.PixelFormats; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Processing |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Options for influencing the drawing functions.
|
|
||||
/// </summary>
|
|
||||
public struct TextGraphicsOptions |
|
||||
{ |
|
||||
private const int DefaultTextDpi = 72; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Represents the default <see cref="TextGraphicsOptions"/>.
|
|
||||
/// </summary>
|
|
||||
public static readonly TextGraphicsOptions Default = new TextGraphicsOptions(true); |
|
||||
|
|
||||
private float? blendPercentage; |
|
||||
|
|
||||
private int? antialiasSubpixelDepth; |
|
||||
|
|
||||
private bool? antialias; |
|
||||
|
|
||||
private bool? applyKerning; |
|
||||
|
|
||||
private float? tabWidth; |
|
||||
|
|
||||
private float? dpiX; |
|
||||
|
|
||||
private float? dpiY; |
|
||||
|
|
||||
private PixelColorBlendingMode colorBlendingMode; |
|
||||
|
|
||||
private PixelAlphaCompositionMode alphaCompositionMode; |
|
||||
|
|
||||
private float wrapTextWidth; |
|
||||
|
|
||||
private HorizontalAlignment? horizontalAlignment; |
|
||||
|
|
||||
private VerticalAlignment? verticalAlignment; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="TextGraphicsOptions" /> struct.
|
|
||||
/// </summary>
|
|
||||
/// <param name="enableAntialiasing">If set to <c>true</c> [enable antialiasing].</param>
|
|
||||
public TextGraphicsOptions(bool enableAntialiasing) |
|
||||
{ |
|
||||
this.applyKerning = true; |
|
||||
this.tabWidth = 4; |
|
||||
this.wrapTextWidth = 0; |
|
||||
this.horizontalAlignment = HorizontalAlignment.Left; |
|
||||
this.verticalAlignment = VerticalAlignment.Top; |
|
||||
|
|
||||
this.antialiasSubpixelDepth = 16; |
|
||||
this.colorBlendingMode = PixelColorBlendingMode.Normal; |
|
||||
this.alphaCompositionMode = PixelAlphaCompositionMode.SrcOver; |
|
||||
this.blendPercentage = 1; |
|
||||
this.antialias = enableAntialiasing; |
|
||||
this.dpiX = DefaultTextDpi; |
|
||||
this.dpiY = DefaultTextDpi; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets or sets a value indicating whether antialiasing should be applied.
|
|
||||
/// </summary>
|
|
||||
public bool Antialias { get => this.antialias ?? true; set => this.antialias = value; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets or sets a value indicating the number of subpixels to use while rendering with antialiasing enabled.
|
|
||||
/// </summary>
|
|
||||
public int AntialiasSubpixelDepth { get => this.antialiasSubpixelDepth ?? 16; set => this.antialiasSubpixelDepth = value; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets or sets a value indicating the blending percentage to apply to the drawing operation
|
|
||||
/// </summary>
|
|
||||
public float BlendPercentage { get => (this.blendPercentage ?? 1).Clamp(0, 1); set => this.blendPercentage = value; } |
|
||||
|
|
||||
// In the future we could expose a PixelBlender<TPixel> directly on here
|
|
||||
// or some forms of PixelBlender factory for each pixel type. Will need
|
|
||||
// some API thought post V1.
|
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets or sets a value indicating the color blending percentage to apply to the drawing operation
|
|
||||
/// </summary>
|
|
||||
public PixelColorBlendingMode ColorBlendingMode { get => this.colorBlendingMode; set => this.colorBlendingMode = value; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets or sets a value indicating the color blending percentage to apply to the drawing operation
|
|
||||
/// </summary>
|
|
||||
public PixelAlphaCompositionMode AlphaCompositionMode { get => this.alphaCompositionMode; set => this.alphaCompositionMode = value; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets or sets a value indicating whether the text should be drawing with kerning enabled.
|
|
||||
/// </summary>
|
|
||||
public bool ApplyKerning { get => this.applyKerning ?? true; set => this.applyKerning = value; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets or sets a value indicating the number of space widths a tab should lock to.
|
|
||||
/// </summary>
|
|
||||
public float TabWidth { get => this.tabWidth ?? 4; set => this.tabWidth = value; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets or sets a value indicating if greater than zero determine the width at which text should wrap.
|
|
||||
/// </summary>
|
|
||||
public float WrapTextWidth { get => this.wrapTextWidth; set => this.wrapTextWidth = value; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets or sets a value indicating the DPI to render text along the X axis.
|
|
||||
/// </summary>
|
|
||||
public float DpiX { get => this.dpiX ?? DefaultTextDpi; set => this.dpiX = value; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets or sets a value indicating the DPI to render text along the Y axis.
|
|
||||
/// </summary>
|
|
||||
public float DpiY { get => this.dpiY ?? DefaultTextDpi; set => this.dpiY = value; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets or sets a value indicating how to align the text relative to the rendering space.
|
|
||||
/// If <see cref="WrapTextWidth"/> is greater than zero it will align relative to the space
|
|
||||
/// defined by the location and width, if <see cref="WrapTextWidth"/> equals zero, and thus
|
|
||||
/// wrapping disabled, then the alignment is relative to the drawing location.
|
|
||||
/// </summary>
|
|
||||
public HorizontalAlignment HorizontalAlignment { get => this.horizontalAlignment ?? HorizontalAlignment.Left; set => this.horizontalAlignment = value; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets or sets a value indicating how to align the text relative to the rendering space.
|
|
||||
/// </summary>
|
|
||||
public VerticalAlignment VerticalAlignment { get => this.verticalAlignment ?? VerticalAlignment.Top; set => this.verticalAlignment = value; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Performs an implicit conversion from <see cref="GraphicsOptions"/> to <see cref="TextGraphicsOptions"/>.
|
|
||||
/// </summary>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <returns>
|
|
||||
/// The result of the conversion.
|
|
||||
/// </returns>
|
|
||||
public static implicit operator TextGraphicsOptions(GraphicsOptions options) |
|
||||
{ |
|
||||
return new TextGraphicsOptions(options.Antialias) |
|
||||
{ |
|
||||
AntialiasSubpixelDepth = options.AntialiasSubpixelDepth, |
|
||||
blendPercentage = options.BlendPercentage, |
|
||||
colorBlendingMode = options.ColorBlendingMode, |
|
||||
alphaCompositionMode = options.AlphaCompositionMode |
|
||||
}; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Performs an explicit conversion from <see cref="TextGraphicsOptions"/> to <see cref="GraphicsOptions"/>.
|
|
||||
/// </summary>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <returns>
|
|
||||
/// The result of the conversion.
|
|
||||
/// </returns>
|
|
||||
public static explicit operator GraphicsOptions(TextGraphicsOptions options) |
|
||||
{ |
|
||||
return new GraphicsOptions(options.Antialias) |
|
||||
{ |
|
||||
AntialiasSubpixelDepth = options.AntialiasSubpixelDepth, |
|
||||
ColorBlendingMode = options.ColorBlendingMode, |
|
||||
AlphaCompositionMode = options.AlphaCompositionMode, |
|
||||
BlendPercentage = options.BlendPercentage |
|
||||
}; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,4 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
// Common values read from `AssemblyInfo.Common.cs`
|
|
||||
@ -1,84 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using System; |
|
||||
using System.Runtime.CompilerServices; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Utils |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Optimized quick sort implementation for Span{float} input
|
|
||||
/// </summary>
|
|
||||
internal class QuickSort |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Sorts the elements of <paramref name="data"/> in ascending order
|
|
||||
/// </summary>
|
|
||||
/// <param name="data">The items to sort</param>
|
|
||||
public static void Sort(Span<float> data) |
|
||||
{ |
|
||||
if (data.Length < 2) |
|
||||
{ |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
if (data.Length == 2) |
|
||||
{ |
|
||||
if (data[0] > data[1]) |
|
||||
{ |
|
||||
Swap(ref data[0], ref data[1]); |
|
||||
} |
|
||||
|
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
Sort(ref data[0], 0, data.Length - 1); |
|
||||
} |
|
||||
|
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|
||||
private static void Swap(ref float left, ref float right) |
|
||||
{ |
|
||||
float tmp = left; |
|
||||
left = right; |
|
||||
right = tmp; |
|
||||
} |
|
||||
|
|
||||
private static void Sort(ref float data0, int lo, int hi) |
|
||||
{ |
|
||||
if (lo < hi) |
|
||||
{ |
|
||||
int p = Partition(ref data0, lo, hi); |
|
||||
Sort(ref data0, lo, p); |
|
||||
Sort(ref data0, p + 1, hi); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private static int Partition(ref float data0, int lo, int hi) |
|
||||
{ |
|
||||
float pivot = Unsafe.Add(ref data0, lo); |
|
||||
int i = lo - 1; |
|
||||
int j = hi + 1; |
|
||||
while (true) |
|
||||
{ |
|
||||
do |
|
||||
{ |
|
||||
i = i + 1; |
|
||||
} |
|
||||
while (Unsafe.Add(ref data0, i) < pivot && i < hi); |
|
||||
|
|
||||
do |
|
||||
{ |
|
||||
j = j - 1; |
|
||||
} |
|
||||
while (Unsafe.Add(ref data0, j) > pivot && j > lo); |
|
||||
|
|
||||
if (i >= j) |
|
||||
{ |
|
||||
return j; |
|
||||
} |
|
||||
|
|
||||
Swap(ref Unsafe.Add(ref data0, i), ref Unsafe.Add(ref data0, j)); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,16 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Advanced |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Encapsulates the properties for configuration.
|
|
||||
/// </summary>
|
|
||||
internal interface IConfigurable |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Gets the configuration.
|
|
||||
/// </summary>
|
|
||||
Configuration Configuration { get; } |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,16 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Advanced |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Defines the contract for objects that can provide access to configuration.
|
||||
|
/// </summary>
|
||||
|
internal interface IConfigurationProvider |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Gets the configuration which allows altering default behaviour or extending the library.
|
||||
|
/// </summary>
|
||||
|
Configuration Configuration { get; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,22 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using SixLabors.ImageSharp.PixelFormats; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Advanced |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// A visitor to implement a double-dispatch pattern in order to apply pixel-specific operations
|
||||
|
/// on non-generic <see cref="Image"/> instances.
|
||||
|
/// </summary>
|
||||
|
public interface IImageVisitor |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Provides a pixel-specific implementation for a given operation.
|
||||
|
/// </summary>
|
||||
|
/// <param name="image">The image.</param>
|
||||
|
/// <typeparam name="TPixel">The pixel type.</typeparam>
|
||||
|
void Visit<TPixel>(Image<TPixel> image) |
||||
|
where TPixel : unmanaged, IPixel<TPixel>; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,19 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using SixLabors.ImageSharp.Memory; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Advanced |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Defines the contract for an action that operates on a row interval.
|
||||
|
/// </summary>
|
||||
|
public interface IRowIntervalOperation |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Invokes the method passing the row interval.
|
||||
|
/// </summary>
|
||||
|
/// <param name="rows">The row interval.</param>
|
||||
|
void Invoke(in RowInterval rows); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using System; |
||||
|
using SixLabors.ImageSharp.Memory; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Advanced |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Defines the contract for an action that operates on a row interval with a temporary buffer.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TBuffer">The type of buffer elements.</typeparam>
|
||||
|
public interface IRowIntervalOperation<TBuffer> |
||||
|
where TBuffer : unmanaged |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Invokes the method passing the row interval and a buffer.
|
||||
|
/// </summary>
|
||||
|
/// <param name="rows">The row interval.</param>
|
||||
|
/// <param name="span">The contiguous region of memory.</param>
|
||||
|
void Invoke(in RowInterval rows, Span<TBuffer> span); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Advanced |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Defines the contract for an action that operates on a row.
|
||||
|
/// </summary>
|
||||
|
public interface IRowOperation |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Invokes the method passing the row y coordinate.
|
||||
|
/// </summary>
|
||||
|
/// <param name="y">The row y coordinate.</param>
|
||||
|
void Invoke(int y); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,22 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using System; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Advanced |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Defines the contract for an action that operates on a row with a temporary buffer.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TBuffer">The type of buffer elements.</typeparam>
|
||||
|
public interface IRowOperation<TBuffer> |
||||
|
where TBuffer : unmanaged |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Invokes the method passing the row and a buffer.
|
||||
|
/// </summary>
|
||||
|
/// <param name="y">The row y coordinate.</param>
|
||||
|
/// <param name="span">The contiguous region of memory.</param>
|
||||
|
void Invoke(int y, Span<TBuffer> span); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,101 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using System; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
using SixLabors.ImageSharp.Memory; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Advanced |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Defines execution settings for methods in <see cref="ParallelRowIterator"/>.
|
||||
|
/// </summary>
|
||||
|
public readonly struct ParallelExecutionSettings |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Default value for <see cref="MinimumPixelsProcessedPerTask"/>.
|
||||
|
/// </summary>
|
||||
|
public const int DefaultMinimumPixelsProcessedPerTask = 4096; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="ParallelExecutionSettings"/> struct.
|
||||
|
/// </summary>
|
||||
|
/// <param name="maxDegreeOfParallelism">The value used for initializing <see cref="ParallelOptions.MaxDegreeOfParallelism"/> when using TPL.</param>
|
||||
|
/// <param name="minimumPixelsProcessedPerTask">The value for <see cref="MinimumPixelsProcessedPerTask"/>.</param>
|
||||
|
/// <param name="memoryAllocator">The <see cref="MemoryAllocator"/>.</param>
|
||||
|
public ParallelExecutionSettings( |
||||
|
int maxDegreeOfParallelism, |
||||
|
int minimumPixelsProcessedPerTask, |
||||
|
MemoryAllocator memoryAllocator) |
||||
|
{ |
||||
|
// Shall be compatible with ParallelOptions.MaxDegreeOfParallelism:
|
||||
|
// https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.paralleloptions.maxdegreeofparallelism
|
||||
|
if (maxDegreeOfParallelism == 0 || maxDegreeOfParallelism < -1) |
||||
|
{ |
||||
|
throw new ArgumentOutOfRangeException(nameof(maxDegreeOfParallelism)); |
||||
|
} |
||||
|
|
||||
|
Guard.MustBeGreaterThan(minimumPixelsProcessedPerTask, 0, nameof(minimumPixelsProcessedPerTask)); |
||||
|
Guard.NotNull(memoryAllocator, nameof(memoryAllocator)); |
||||
|
|
||||
|
this.MaxDegreeOfParallelism = maxDegreeOfParallelism; |
||||
|
this.MinimumPixelsProcessedPerTask = minimumPixelsProcessedPerTask; |
||||
|
this.MemoryAllocator = memoryAllocator; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="ParallelExecutionSettings"/> struct.
|
||||
|
/// </summary>
|
||||
|
/// <param name="maxDegreeOfParallelism">The value used for initializing <see cref="ParallelOptions.MaxDegreeOfParallelism"/> when using TPL.</param>
|
||||
|
/// <param name="memoryAllocator">The <see cref="MemoryAllocator"/>.</param>
|
||||
|
public ParallelExecutionSettings(int maxDegreeOfParallelism, MemoryAllocator memoryAllocator) |
||||
|
: this(maxDegreeOfParallelism, DefaultMinimumPixelsProcessedPerTask, memoryAllocator) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the <see cref="MemoryAllocator"/>.
|
||||
|
/// </summary>
|
||||
|
public MemoryAllocator MemoryAllocator { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the value used for initializing <see cref="ParallelOptions.MaxDegreeOfParallelism"/> when using TPL.
|
||||
|
/// </summary>
|
||||
|
public int MaxDegreeOfParallelism { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the minimum number of pixels being processed by a single task when parallelizing operations with TPL.
|
||||
|
/// Launching tasks for pixel regions below this limit is not worth the overhead.
|
||||
|
/// Initialized with <see cref="DefaultMinimumPixelsProcessedPerTask"/> by default,
|
||||
|
/// the optimum value is operation specific. (The cheaper the operation, the larger the value is.)
|
||||
|
/// </summary>
|
||||
|
public int MinimumPixelsProcessedPerTask { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of <see cref="ParallelExecutionSettings"/>
|
||||
|
/// having <see cref="MinimumPixelsProcessedPerTask"/> multiplied by <paramref name="multiplier"/>
|
||||
|
/// </summary>
|
||||
|
/// <param name="multiplier">The value to multiply <see cref="MinimumPixelsProcessedPerTask"/> with.</param>
|
||||
|
/// <returns>The modified <see cref="ParallelExecutionSettings"/>.</returns>
|
||||
|
public ParallelExecutionSettings MultiplyMinimumPixelsPerTask(int multiplier) |
||||
|
{ |
||||
|
Guard.MustBeGreaterThan(multiplier, 0, nameof(multiplier)); |
||||
|
|
||||
|
return new ParallelExecutionSettings( |
||||
|
this.MaxDegreeOfParallelism, |
||||
|
this.MinimumPixelsProcessedPerTask * multiplier, |
||||
|
this.MemoryAllocator); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Get the default <see cref="SixLabors.ImageSharp.Advanced.ParallelExecutionSettings"/> for a <see cref="SixLabors.ImageSharp.Configuration"/>
|
||||
|
/// </summary>
|
||||
|
/// <param name="configuration">The <see cref="Configuration"/>.</param>
|
||||
|
/// <returns>The <see cref="ParallelExecutionSettings"/>.</returns>
|
||||
|
public static ParallelExecutionSettings FromConfiguration(Configuration configuration) |
||||
|
{ |
||||
|
return new ParallelExecutionSettings(configuration.MaxDegreeOfParallelism, configuration.MemoryAllocator); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,198 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using System; |
||||
|
using System.Buffers; |
||||
|
using System.Runtime.CompilerServices; |
||||
|
using System.Threading.Tasks; |
||||
|
using SixLabors.ImageSharp.Memory; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Advanced |
||||
|
{ |
||||
|
/// <content>
|
||||
|
/// Utility methods for batched processing of pixel row intervals.
|
||||
|
/// Parallel execution is optimized for image processing based on values defined
|
||||
|
/// <see cref="ParallelExecutionSettings"/> or <see cref="Configuration"/>.
|
||||
|
/// Using this class is preferred over direct usage of <see cref="Parallel"/> utility methods.
|
||||
|
/// </content>
|
||||
|
public static partial class ParallelRowIterator |
||||
|
{ |
||||
|
private readonly struct RowOperationWrapper<T> |
||||
|
where T : struct, IRowOperation |
||||
|
{ |
||||
|
private readonly int minY; |
||||
|
private readonly int maxY; |
||||
|
private readonly int stepY; |
||||
|
private readonly T action; |
||||
|
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public RowOperationWrapper( |
||||
|
int minY, |
||||
|
int maxY, |
||||
|
int stepY, |
||||
|
in T action) |
||||
|
{ |
||||
|
this.minY = minY; |
||||
|
this.maxY = maxY; |
||||
|
this.stepY = stepY; |
||||
|
this.action = action; |
||||
|
} |
||||
|
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public void Invoke(int i) |
||||
|
{ |
||||
|
int yMin = this.minY + (i * this.stepY); |
||||
|
|
||||
|
if (yMin >= this.maxY) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
int yMax = Math.Min(yMin + this.stepY, this.maxY); |
||||
|
|
||||
|
for (int y = yMin; y < yMax; y++) |
||||
|
{ |
||||
|
// Skip the safety copy when invoking a potentially impure method on a readonly field
|
||||
|
Unsafe.AsRef(this.action).Invoke(y); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private readonly struct RowOperationWrapper<T, TBuffer> |
||||
|
where T : struct, IRowOperation<TBuffer> |
||||
|
where TBuffer : unmanaged |
||||
|
{ |
||||
|
private readonly int minY; |
||||
|
private readonly int maxY; |
||||
|
private readonly int stepY; |
||||
|
private readonly int width; |
||||
|
private readonly MemoryAllocator allocator; |
||||
|
private readonly T action; |
||||
|
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public RowOperationWrapper( |
||||
|
int minY, |
||||
|
int maxY, |
||||
|
int stepY, |
||||
|
int width, |
||||
|
MemoryAllocator allocator, |
||||
|
in T action) |
||||
|
{ |
||||
|
this.minY = minY; |
||||
|
this.maxY = maxY; |
||||
|
this.stepY = stepY; |
||||
|
this.width = width; |
||||
|
this.allocator = allocator; |
||||
|
this.action = action; |
||||
|
} |
||||
|
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public void Invoke(int i) |
||||
|
{ |
||||
|
int yMin = this.minY + (i * this.stepY); |
||||
|
|
||||
|
if (yMin >= this.maxY) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
int yMax = Math.Min(yMin + this.stepY, this.maxY); |
||||
|
|
||||
|
using IMemoryOwner<TBuffer> buffer = this.allocator.Allocate<TBuffer>(this.width); |
||||
|
|
||||
|
Span<TBuffer> span = buffer.Memory.Span; |
||||
|
|
||||
|
for (int y = yMin; y < yMax; y++) |
||||
|
{ |
||||
|
Unsafe.AsRef(this.action).Invoke(y, span); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private readonly struct RowIntervalOperationWrapper<T> |
||||
|
where T : struct, IRowIntervalOperation |
||||
|
{ |
||||
|
private readonly int minY; |
||||
|
private readonly int maxY; |
||||
|
private readonly int stepY; |
||||
|
private readonly T operation; |
||||
|
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public RowIntervalOperationWrapper( |
||||
|
int minY, |
||||
|
int maxY, |
||||
|
int stepY, |
||||
|
in T operation) |
||||
|
{ |
||||
|
this.minY = minY; |
||||
|
this.maxY = maxY; |
||||
|
this.stepY = stepY; |
||||
|
this.operation = operation; |
||||
|
} |
||||
|
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public void Invoke(int i) |
||||
|
{ |
||||
|
int yMin = this.minY + (i * this.stepY); |
||||
|
|
||||
|
if (yMin >= this.maxY) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
int yMax = Math.Min(yMin + this.stepY, this.maxY); |
||||
|
var rows = new RowInterval(yMin, yMax); |
||||
|
|
||||
|
// Skip the safety copy when invoking a potentially impure method on a readonly field
|
||||
|
Unsafe.AsRef(in this.operation).Invoke(in rows); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private readonly struct RowIntervalOperationWrapper<T, TBuffer> |
||||
|
where T : struct, IRowIntervalOperation<TBuffer> |
||||
|
where TBuffer : unmanaged |
||||
|
{ |
||||
|
private readonly int minY; |
||||
|
private readonly int maxY; |
||||
|
private readonly int stepY; |
||||
|
private readonly int width; |
||||
|
private readonly MemoryAllocator allocator; |
||||
|
private readonly T operation; |
||||
|
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public RowIntervalOperationWrapper( |
||||
|
int minY, |
||||
|
int maxY, |
||||
|
int stepY, |
||||
|
int width, |
||||
|
MemoryAllocator allocator, |
||||
|
in T operation) |
||||
|
{ |
||||
|
this.minY = minY; |
||||
|
this.maxY = maxY; |
||||
|
this.stepY = stepY; |
||||
|
this.width = width; |
||||
|
this.allocator = allocator; |
||||
|
this.operation = operation; |
||||
|
} |
||||
|
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public void Invoke(int i) |
||||
|
{ |
||||
|
int yMin = this.minY + (i * this.stepY); |
||||
|
|
||||
|
if (yMin >= this.maxY) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
int yMax = Math.Min(yMin + this.stepY, this.maxY); |
||||
|
var rows = new RowInterval(yMin, yMax); |
||||
|
|
||||
|
using IMemoryOwner<TBuffer> buffer = this.allocator.Allocate<TBuffer>(this.width); |
||||
|
|
||||
|
Unsafe.AsRef(in this.operation).Invoke(in rows, buffer.Memory.Span); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,288 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using System; |
||||
|
using System.Buffers; |
||||
|
using System.Runtime.CompilerServices; |
||||
|
using System.Threading.Tasks; |
||||
|
using SixLabors.ImageSharp.Memory; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Advanced |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Utility methods for batched processing of pixel row intervals.
|
||||
|
/// Parallel execution is optimized for image processing based on values defined
|
||||
|
/// <see cref="ParallelExecutionSettings"/> or <see cref="Configuration"/>.
|
||||
|
/// Using this class is preferred over direct usage of <see cref="Parallel"/> utility methods.
|
||||
|
/// </summary>
|
||||
|
public static partial class ParallelRowIterator |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Iterate through the rows of a rectangle in optimized batches.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="T">The type of row operation to perform.</typeparam>
|
||||
|
/// <param name="configuration">The <see cref="Configuration"/> to get the parallel settings from.</param>
|
||||
|
/// <param name="rectangle">The <see cref="Rectangle"/>.</param>
|
||||
|
/// <param name="operation">The operation defining the iteration logic on a single row.</param>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public static void IterateRows<T>(Configuration configuration, Rectangle rectangle, in T operation) |
||||
|
where T : struct, IRowOperation |
||||
|
{ |
||||
|
var parallelSettings = ParallelExecutionSettings.FromConfiguration(configuration); |
||||
|
IterateRows(rectangle, in parallelSettings, in operation); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Iterate through the rows of a rectangle in optimized batches.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="T">The type of row operation to perform.</typeparam>
|
||||
|
/// <param name="rectangle">The <see cref="Rectangle"/>.</param>
|
||||
|
/// <param name="parallelSettings">The <see cref="ParallelExecutionSettings"/>.</param>
|
||||
|
/// <param name="operation">The operation defining the iteration logic on a single row.</param>
|
||||
|
public static void IterateRows<T>( |
||||
|
Rectangle rectangle, |
||||
|
in ParallelExecutionSettings parallelSettings, |
||||
|
in T operation) |
||||
|
where T : struct, IRowOperation |
||||
|
{ |
||||
|
ValidateRectangle(rectangle); |
||||
|
|
||||
|
int top = rectangle.Top; |
||||
|
int bottom = rectangle.Bottom; |
||||
|
int width = rectangle.Width; |
||||
|
int height = rectangle.Height; |
||||
|
|
||||
|
int maxSteps = DivideCeil(width * height, parallelSettings.MinimumPixelsProcessedPerTask); |
||||
|
int numOfSteps = Math.Min(parallelSettings.MaxDegreeOfParallelism, maxSteps); |
||||
|
|
||||
|
// Avoid TPL overhead in this trivial case:
|
||||
|
if (numOfSteps == 1) |
||||
|
{ |
||||
|
for (int y = top; y < bottom; y++) |
||||
|
{ |
||||
|
Unsafe.AsRef(operation).Invoke(y); |
||||
|
} |
||||
|
|
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
int verticalStep = DivideCeil(rectangle.Height, numOfSteps); |
||||
|
var parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = numOfSteps }; |
||||
|
var wrappingOperation = new RowOperationWrapper<T>(top, bottom, verticalStep, in operation); |
||||
|
|
||||
|
Parallel.For( |
||||
|
0, |
||||
|
numOfSteps, |
||||
|
parallelOptions, |
||||
|
wrappingOperation.Invoke); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Iterate through the rows of a rectangle in optimized batches.
|
||||
|
/// instantiating a temporary buffer for each <paramref name="operation"/> invocation.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="T">The type of row operation to perform.</typeparam>
|
||||
|
/// <typeparam name="TBuffer">The type of buffer elements.</typeparam>
|
||||
|
/// <param name="configuration">The <see cref="Configuration"/> to get the parallel settings from.</param>
|
||||
|
/// <param name="rectangle">The <see cref="Rectangle"/>.</param>
|
||||
|
/// <param name="operation">The operation defining the iteration logic on a single row.</param>
|
||||
|
public static void IterateRows<T, TBuffer>(Configuration configuration, Rectangle rectangle, in T operation) |
||||
|
where T : struct, IRowOperation<TBuffer> |
||||
|
where TBuffer : unmanaged |
||||
|
{ |
||||
|
var parallelSettings = ParallelExecutionSettings.FromConfiguration(configuration); |
||||
|
IterateRows<T, TBuffer>(rectangle, in parallelSettings, in operation); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Iterate through the rows of a rectangle in optimized batches.
|
||||
|
/// instantiating a temporary buffer for each <paramref name="operation"/> invocation.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="T">The type of row operation to perform.</typeparam>
|
||||
|
/// <typeparam name="TBuffer">The type of buffer elements.</typeparam>
|
||||
|
/// <param name="rectangle">The <see cref="Rectangle"/>.</param>
|
||||
|
/// <param name="parallelSettings">The <see cref="ParallelExecutionSettings"/>.</param>
|
||||
|
/// <param name="operation">The operation defining the iteration logic on a single row.</param>
|
||||
|
public static void IterateRows<T, TBuffer>( |
||||
|
Rectangle rectangle, |
||||
|
in ParallelExecutionSettings parallelSettings, |
||||
|
in T operation) |
||||
|
where T : struct, IRowOperation<TBuffer> |
||||
|
where TBuffer : unmanaged |
||||
|
{ |
||||
|
ValidateRectangle(rectangle); |
||||
|
|
||||
|
int top = rectangle.Top; |
||||
|
int bottom = rectangle.Bottom; |
||||
|
int width = rectangle.Width; |
||||
|
int height = rectangle.Height; |
||||
|
|
||||
|
int maxSteps = DivideCeil(width * height, parallelSettings.MinimumPixelsProcessedPerTask); |
||||
|
int numOfSteps = Math.Min(parallelSettings.MaxDegreeOfParallelism, maxSteps); |
||||
|
MemoryAllocator allocator = parallelSettings.MemoryAllocator; |
||||
|
|
||||
|
// Avoid TPL overhead in this trivial case:
|
||||
|
if (numOfSteps == 1) |
||||
|
{ |
||||
|
using IMemoryOwner<TBuffer> buffer = allocator.Allocate<TBuffer>(width); |
||||
|
Span<TBuffer> span = buffer.Memory.Span; |
||||
|
|
||||
|
for (int y = top; y < bottom; y++) |
||||
|
{ |
||||
|
Unsafe.AsRef(operation).Invoke(y, span); |
||||
|
} |
||||
|
|
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
int verticalStep = DivideCeil(height, numOfSteps); |
||||
|
var parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = numOfSteps }; |
||||
|
var wrappingOperation = new RowOperationWrapper<T, TBuffer>(top, bottom, verticalStep, width, allocator, in operation); |
||||
|
|
||||
|
Parallel.For( |
||||
|
0, |
||||
|
numOfSteps, |
||||
|
parallelOptions, |
||||
|
wrappingOperation.Invoke); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Iterate through the rows of a rectangle in optimized batches defined by <see cref="RowInterval"/>-s.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="T">The type of row operation to perform.</typeparam>
|
||||
|
/// <param name="configuration">The <see cref="Configuration"/> to get the parallel settings from.</param>
|
||||
|
/// <param name="rectangle">The <see cref="Rectangle"/>.</param>
|
||||
|
/// <param name="operation">The operation defining the iteration logic on a single <see cref="RowInterval"/>.</param>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public static void IterateRowIntervals<T>(Configuration configuration, Rectangle rectangle, in T operation) |
||||
|
where T : struct, IRowIntervalOperation |
||||
|
{ |
||||
|
var parallelSettings = ParallelExecutionSettings.FromConfiguration(configuration); |
||||
|
IterateRowIntervals(rectangle, in parallelSettings, in operation); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Iterate through the rows of a rectangle in optimized batches defined by <see cref="RowInterval"/>-s.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="T">The type of row operation to perform.</typeparam>
|
||||
|
/// <param name="rectangle">The <see cref="Rectangle"/>.</param>
|
||||
|
/// <param name="parallelSettings">The <see cref="ParallelExecutionSettings"/>.</param>
|
||||
|
/// <param name="operation">The operation defining the iteration logic on a single <see cref="RowInterval"/>.</param>
|
||||
|
public static void IterateRowIntervals<T>( |
||||
|
Rectangle rectangle, |
||||
|
in ParallelExecutionSettings parallelSettings, |
||||
|
in T operation) |
||||
|
where T : struct, IRowIntervalOperation |
||||
|
{ |
||||
|
ValidateRectangle(rectangle); |
||||
|
|
||||
|
int top = rectangle.Top; |
||||
|
int bottom = rectangle.Bottom; |
||||
|
int width = rectangle.Width; |
||||
|
int height = rectangle.Height; |
||||
|
|
||||
|
int maxSteps = DivideCeil(width * height, parallelSettings.MinimumPixelsProcessedPerTask); |
||||
|
int numOfSteps = Math.Min(parallelSettings.MaxDegreeOfParallelism, maxSteps); |
||||
|
|
||||
|
// Avoid TPL overhead in this trivial case:
|
||||
|
if (numOfSteps == 1) |
||||
|
{ |
||||
|
var rows = new RowInterval(top, bottom); |
||||
|
Unsafe.AsRef(in operation).Invoke(in rows); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
int verticalStep = DivideCeil(rectangle.Height, numOfSteps); |
||||
|
var parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = numOfSteps }; |
||||
|
var wrappingOperation = new RowIntervalOperationWrapper<T>(top, bottom, verticalStep, in operation); |
||||
|
|
||||
|
Parallel.For( |
||||
|
0, |
||||
|
numOfSteps, |
||||
|
parallelOptions, |
||||
|
wrappingOperation.Invoke); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Iterate through the rows of a rectangle in optimized batches defined by <see cref="RowInterval"/>-s
|
||||
|
/// instantiating a temporary buffer for each <paramref name="operation"/> invocation.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="T">The type of row operation to perform.</typeparam>
|
||||
|
/// <typeparam name="TBuffer">The type of buffer elements.</typeparam>
|
||||
|
/// <param name="configuration">The <see cref="Configuration"/> to get the parallel settings from.</param>
|
||||
|
/// <param name="rectangle">The <see cref="Rectangle"/>.</param>
|
||||
|
/// <param name="operation">The operation defining the iteration logic on a single <see cref="RowInterval"/>.</param>
|
||||
|
public static void IterateRowIntervals<T, TBuffer>(Configuration configuration, Rectangle rectangle, in T operation) |
||||
|
where T : struct, IRowIntervalOperation<TBuffer> |
||||
|
where TBuffer : unmanaged |
||||
|
{ |
||||
|
var parallelSettings = ParallelExecutionSettings.FromConfiguration(configuration); |
||||
|
IterateRowIntervals<T, TBuffer>(rectangle, in parallelSettings, in operation); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Iterate through the rows of a rectangle in optimized batches defined by <see cref="RowInterval"/>-s
|
||||
|
/// instantiating a temporary buffer for each <paramref name="operation"/> invocation.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="T">The type of row operation to perform.</typeparam>
|
||||
|
/// <typeparam name="TBuffer">The type of buffer elements.</typeparam>
|
||||
|
/// <param name="rectangle">The <see cref="Rectangle"/>.</param>
|
||||
|
/// <param name="parallelSettings">The <see cref="ParallelExecutionSettings"/>.</param>
|
||||
|
/// <param name="operation">The operation defining the iteration logic on a single <see cref="RowInterval"/>.</param>
|
||||
|
public static void IterateRowIntervals<T, TBuffer>( |
||||
|
Rectangle rectangle, |
||||
|
in ParallelExecutionSettings parallelSettings, |
||||
|
in T operation) |
||||
|
where T : struct, IRowIntervalOperation<TBuffer> |
||||
|
where TBuffer : unmanaged |
||||
|
{ |
||||
|
ValidateRectangle(rectangle); |
||||
|
|
||||
|
int top = rectangle.Top; |
||||
|
int bottom = rectangle.Bottom; |
||||
|
int width = rectangle.Width; |
||||
|
int height = rectangle.Height; |
||||
|
|
||||
|
int maxSteps = DivideCeil(width * height, parallelSettings.MinimumPixelsProcessedPerTask); |
||||
|
int numOfSteps = Math.Min(parallelSettings.MaxDegreeOfParallelism, maxSteps); |
||||
|
MemoryAllocator allocator = parallelSettings.MemoryAllocator; |
||||
|
|
||||
|
// Avoid TPL overhead in this trivial case:
|
||||
|
if (numOfSteps == 1) |
||||
|
{ |
||||
|
var rows = new RowInterval(top, bottom); |
||||
|
using IMemoryOwner<TBuffer> buffer = allocator.Allocate<TBuffer>(width); |
||||
|
|
||||
|
Unsafe.AsRef(operation).Invoke(in rows, buffer.Memory.Span); |
||||
|
|
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
int verticalStep = DivideCeil(height, numOfSteps); |
||||
|
var parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = numOfSteps }; |
||||
|
var wrappingOperation = new RowIntervalOperationWrapper<T, TBuffer>(top, bottom, verticalStep, width, allocator, in operation); |
||||
|
|
||||
|
Parallel.For( |
||||
|
0, |
||||
|
numOfSteps, |
||||
|
parallelOptions, |
||||
|
wrappingOperation.Invoke); |
||||
|
} |
||||
|
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
private static int DivideCeil(int dividend, int divisor) => 1 + ((dividend - 1) / divisor); |
||||
|
|
||||
|
private static void ValidateRectangle(Rectangle rectangle) |
||||
|
{ |
||||
|
Guard.MustBeGreaterThan( |
||||
|
rectangle.Width, |
||||
|
0, |
||||
|
$"{nameof(rectangle)}.{nameof(rectangle.Width)}"); |
||||
|
|
||||
|
Guard.MustBeGreaterThan( |
||||
|
rectangle.Height, |
||||
|
0, |
||||
|
$"{nameof(rectangle)}.{nameof(rectangle.Height)}"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,98 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using System.Numerics; |
||||
|
using System.Runtime.CompilerServices; |
||||
|
|
||||
|
using SixLabors.ImageSharp.PixelFormats; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp |
||||
|
{ |
||||
|
/// <content>
|
||||
|
/// Contains constructors and implicit conversion methods.
|
||||
|
/// </content>
|
||||
|
public readonly partial struct Color |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="Color"/> struct.
|
||||
|
/// </summary>
|
||||
|
/// <param name="pixel">The <see cref="Rgba64"/> containing the color information.</param>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public Color(Rgba64 pixel) => this.data = pixel; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="Color"/> struct.
|
||||
|
/// </summary>
|
||||
|
/// <param name="pixel">The <see cref="Rgba32"/> containing the color information.</param>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public Color(Rgba32 pixel) => this.data = new Rgba64(pixel); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="Color"/> struct.
|
||||
|
/// </summary>
|
||||
|
/// <param name="pixel">The <see cref="Argb32"/> containing the color information.</param>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public Color(Argb32 pixel) => this.data = new Rgba64(pixel); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="Color"/> struct.
|
||||
|
/// </summary>
|
||||
|
/// <param name="pixel">The <see cref="Bgra32"/> containing the color information.</param>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public Color(Bgra32 pixel) => this.data = new Rgba64(pixel); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="Color"/> struct.
|
||||
|
/// </summary>
|
||||
|
/// <param name="pixel">The <see cref="Rgb24"/> containing the color information.</param>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public Color(Rgb24 pixel) => this.data = new Rgba64(pixel); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="Color"/> struct.
|
||||
|
/// </summary>
|
||||
|
/// <param name="pixel">The <see cref="Bgr24"/> containing the color information.</param>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public Color(Bgr24 pixel) => this.data = new Rgba64(pixel); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="Color"/> struct.
|
||||
|
/// </summary>
|
||||
|
/// <param name="vector">The <see cref="Vector4"/> containing the color information.</param>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public Color(Vector4 vector) => this.data = new Rgba64(vector); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Converts a <see cref="Color"/> to <see cref="Vector4"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="color">The <see cref="Color"/>.</param>
|
||||
|
/// <returns>The <see cref="Vector4"/>.</returns>
|
||||
|
public static explicit operator Vector4(Color color) => color.data.ToVector4(); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Converts an <see cref="Vector4"/> to <see cref="Color"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">The <see cref="Vector4"/>.</param>
|
||||
|
/// <returns>The <see cref="Color"/>.</returns>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public static explicit operator Color(Vector4 source) => new Color(source); |
||||
|
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
internal Rgba32 ToRgba32() => this.data.ToRgba32(); |
||||
|
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
internal Bgra32 ToBgra32() => this.data.ToBgra32(); |
||||
|
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
internal Argb32 ToArgb32() => this.data.ToArgb32(); |
||||
|
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
internal Rgb24 ToRgb24() => this.data.ToRgb24(); |
||||
|
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
internal Bgr24 ToBgr24() => this.data.ToBgr24(); |
||||
|
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
internal Vector4 ToVector4() => this.data.ToVector4(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,918 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp |
||||
|
{ |
||||
|
/// <content>
|
||||
|
/// Contains static named color values.
|
||||
|
/// <see href="https://www.w3.org/TR/css-color-3/"/>
|
||||
|
/// </content>
|
||||
|
public readonly partial struct Color |
||||
|
{ |
||||
|
private static readonly Lazy<Dictionary<string, Color>> NamedColorsLookupLazy = new Lazy<Dictionary<string, Color>>(CreateNamedColorsLookup, true); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #F0F8FF.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color AliceBlue = FromRgba(240, 248, 255, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FAEBD7.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color AntiqueWhite = FromRgba(250, 235, 215, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #00FFFF.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Aqua = FromRgba(0, 255, 255, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #7FFFD4.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Aquamarine = FromRgba(127, 255, 212, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #F0FFFF.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Azure = FromRgba(240, 255, 255, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #F5F5DC.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Beige = FromRgba(245, 245, 220, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFE4C4.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Bisque = FromRgba(255, 228, 196, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #000000.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Black = FromRgba(0, 0, 0, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFEBCD.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color BlanchedAlmond = FromRgba(255, 235, 205, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #0000FF.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Blue = FromRgba(0, 0, 255, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #8A2BE2.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color BlueViolet = FromRgba(138, 43, 226, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #A52A2A.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Brown = FromRgba(165, 42, 42, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #DEB887.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color BurlyWood = FromRgba(222, 184, 135, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #5F9EA0.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color CadetBlue = FromRgba(95, 158, 160, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #7FFF00.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Chartreuse = FromRgba(127, 255, 0, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #D2691E.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Chocolate = FromRgba(210, 105, 30, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FF7F50.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Coral = FromRgba(255, 127, 80, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #6495ED.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color CornflowerBlue = FromRgba(100, 149, 237, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFF8DC.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Cornsilk = FromRgba(255, 248, 220, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #DC143C.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Crimson = FromRgba(220, 20, 60, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #00FFFF.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Cyan = Aqua; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #00008B.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color DarkBlue = FromRgba(0, 0, 139, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #008B8B.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color DarkCyan = FromRgba(0, 139, 139, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #B8860B.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color DarkGoldenrod = FromRgba(184, 134, 11, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #A9A9A9.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color DarkGray = FromRgba(169, 169, 169, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #006400.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color DarkGreen = FromRgba(0, 100, 0, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #A9A9A9.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color DarkGrey = DarkGray; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #BDB76B.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color DarkKhaki = FromRgba(189, 183, 107, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #8B008B.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color DarkMagenta = FromRgba(139, 0, 139, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #556B2F.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color DarkOliveGreen = FromRgba(85, 107, 47, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FF8C00.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color DarkOrange = FromRgba(255, 140, 0, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #9932CC.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color DarkOrchid = FromRgba(153, 50, 204, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #8B0000.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color DarkRed = FromRgba(139, 0, 0, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #E9967A.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color DarkSalmon = FromRgba(233, 150, 122, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #8FBC8F.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color DarkSeaGreen = FromRgba(143, 188, 143, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #483D8B.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color DarkSlateBlue = FromRgba(72, 61, 139, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #2F4F4F.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color DarkSlateGray = FromRgba(47, 79, 79, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #2F4F4F.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color DarkSlateGrey = DarkSlateGray; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #00CED1.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color DarkTurquoise = FromRgba(0, 206, 209, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #9400D3.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color DarkViolet = FromRgba(148, 0, 211, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FF1493.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color DeepPink = FromRgba(255, 20, 147, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #00BFFF.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color DeepSkyBlue = FromRgba(0, 191, 255, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #696969.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color DimGray = FromRgba(105, 105, 105, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #696969.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color DimGrey = DimGray; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #1E90FF.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color DodgerBlue = FromRgba(30, 144, 255, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #B22222.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Firebrick = FromRgba(178, 34, 34, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFFAF0.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color FloralWhite = FromRgba(255, 250, 240, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #228B22.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color ForestGreen = FromRgba(34, 139, 34, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FF00FF.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Fuchsia = FromRgba(255, 0, 255, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #DCDCDC.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Gainsboro = FromRgba(220, 220, 220, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #F8F8FF.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color GhostWhite = FromRgba(248, 248, 255, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFD700.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Gold = FromRgba(255, 215, 0, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #DAA520.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Goldenrod = FromRgba(218, 165, 32, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #808080.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Gray = FromRgba(128, 128, 128, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #008000.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Green = FromRgba(0, 128, 0, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #ADFF2F.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color GreenYellow = FromRgba(173, 255, 47, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #808080.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Grey = Gray; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #F0FFF0.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Honeydew = FromRgba(240, 255, 240, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FF69B4.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color HotPink = FromRgba(255, 105, 180, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #CD5C5C.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color IndianRed = FromRgba(205, 92, 92, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #4B0082.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Indigo = FromRgba(75, 0, 130, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFFFF0.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Ivory = FromRgba(255, 255, 240, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #F0E68C.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Khaki = FromRgba(240, 230, 140, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #E6E6FA.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Lavender = FromRgba(230, 230, 250, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFF0F5.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color LavenderBlush = FromRgba(255, 240, 245, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #7CFC00.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color LawnGreen = FromRgba(124, 252, 0, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFFACD.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color LemonChiffon = FromRgba(255, 250, 205, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #ADD8E6.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color LightBlue = FromRgba(173, 216, 230, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #F08080.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color LightCoral = FromRgba(240, 128, 128, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #E0FFFF.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color LightCyan = FromRgba(224, 255, 255, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FAFAD2.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color LightGoldenrodYellow = FromRgba(250, 250, 210, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #D3D3D3.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color LightGray = FromRgba(211, 211, 211, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #90EE90.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color LightGreen = FromRgba(144, 238, 144, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #D3D3D3.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color LightGrey = LightGray; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFB6C1.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color LightPink = FromRgba(255, 182, 193, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFA07A.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color LightSalmon = FromRgba(255, 160, 122, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #20B2AA.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color LightSeaGreen = FromRgba(32, 178, 170, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #87CEFA.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color LightSkyBlue = FromRgba(135, 206, 250, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #778899.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color LightSlateGray = FromRgba(119, 136, 153, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #778899.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color LightSlateGrey = LightSlateGray; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #B0C4DE.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color LightSteelBlue = FromRgba(176, 196, 222, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFFFE0.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color LightYellow = FromRgba(255, 255, 224, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #00FF00.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Lime = FromRgba(0, 255, 0, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #32CD32.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color LimeGreen = FromRgba(50, 205, 50, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FAF0E6.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Linen = FromRgba(250, 240, 230, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FF00FF.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Magenta = Fuchsia; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #800000.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Maroon = FromRgba(128, 0, 0, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #66CDAA.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color MediumAquamarine = FromRgba(102, 205, 170, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #0000CD.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color MediumBlue = FromRgba(0, 0, 205, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #BA55D3.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color MediumOrchid = FromRgba(186, 85, 211, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #9370DB.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color MediumPurple = FromRgba(147, 112, 219, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #3CB371.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color MediumSeaGreen = FromRgba(60, 179, 113, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #7B68EE.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color MediumSlateBlue = FromRgba(123, 104, 238, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #00FA9A.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color MediumSpringGreen = FromRgba(0, 250, 154, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #48D1CC.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color MediumTurquoise = FromRgba(72, 209, 204, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #C71585.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color MediumVioletRed = FromRgba(199, 21, 133, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #191970.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color MidnightBlue = FromRgba(25, 25, 112, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #F5FFFA.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color MintCream = FromRgba(245, 255, 250, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFE4E1.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color MistyRose = FromRgba(255, 228, 225, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFE4B5.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Moccasin = FromRgba(255, 228, 181, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFDEAD.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color NavajoWhite = FromRgba(255, 222, 173, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #000080.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Navy = FromRgba(0, 0, 128, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FDF5E6.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color OldLace = FromRgba(253, 245, 230, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #808000.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Olive = FromRgba(128, 128, 0, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #6B8E23.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color OliveDrab = FromRgba(107, 142, 35, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFA500.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Orange = FromRgba(255, 165, 0, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FF4500.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color OrangeRed = FromRgba(255, 69, 0, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #DA70D6.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Orchid = FromRgba(218, 112, 214, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #EEE8AA.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color PaleGoldenrod = FromRgba(238, 232, 170, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #98FB98.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color PaleGreen = FromRgba(152, 251, 152, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #AFEEEE.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color PaleTurquoise = FromRgba(175, 238, 238, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #DB7093.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color PaleVioletRed = FromRgba(219, 112, 147, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFEFD5.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color PapayaWhip = FromRgba(255, 239, 213, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFDAB9.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color PeachPuff = FromRgba(255, 218, 185, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #CD853F.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Peru = FromRgba(205, 133, 63, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFC0CB.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Pink = FromRgba(255, 192, 203, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #DDA0DD.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Plum = FromRgba(221, 160, 221, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #B0E0E6.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color PowderBlue = FromRgba(176, 224, 230, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #800080.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Purple = FromRgba(128, 0, 128, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #663399.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color RebeccaPurple = FromRgba(102, 51, 153, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FF0000.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Red = FromRgba(255, 0, 0, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #BC8F8F.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color RosyBrown = FromRgba(188, 143, 143, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #4169E1.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color RoyalBlue = FromRgba(65, 105, 225, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #8B4513.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color SaddleBrown = FromRgba(139, 69, 19, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FA8072.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Salmon = FromRgba(250, 128, 114, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #F4A460.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color SandyBrown = FromRgba(244, 164, 96, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #2E8B57.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color SeaGreen = FromRgba(46, 139, 87, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFF5EE.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color SeaShell = FromRgba(255, 245, 238, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #A0522D.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Sienna = FromRgba(160, 82, 45, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #C0C0C0.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Silver = FromRgba(192, 192, 192, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #87CEEB.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color SkyBlue = FromRgba(135, 206, 235, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #6A5ACD.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color SlateBlue = FromRgba(106, 90, 205, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #708090.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color SlateGray = FromRgba(112, 128, 144, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #708090.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color SlateGrey = SlateGray; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFFAFA.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Snow = FromRgba(255, 250, 250, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #00FF7F.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color SpringGreen = FromRgba(0, 255, 127, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #4682B4.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color SteelBlue = FromRgba(70, 130, 180, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #D2B48C.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Tan = FromRgba(210, 180, 140, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #008080.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Teal = FromRgba(0, 128, 128, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #D8BFD8.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Thistle = FromRgba(216, 191, 216, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FF6347.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Tomato = FromRgba(255, 99, 71, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #00000000.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Transparent = FromRgba(0, 0, 0, 0); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #40E0D0.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Turquoise = FromRgba(64, 224, 208, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #EE82EE.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Violet = FromRgba(238, 130, 238, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #F5DEB3.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Wheat = FromRgba(245, 222, 179, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFFFFF.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color White = FromRgba(255, 255, 255, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #F5F5F5.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color WhiteSmoke = FromRgba(245, 245, 245, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #FFFF00.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color Yellow = FromRgba(255, 255, 0, 255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a <see paramref="Color"/> matching the W3C definition that has an hex value of #9ACD32.
|
||||
|
/// </summary>
|
||||
|
public static readonly Color YellowGreen = FromRgba(154, 205, 50, 255); |
||||
|
|
||||
|
private static Dictionary<string, Color> CreateNamedColorsLookup() |
||||
|
{ |
||||
|
return new Dictionary<string, Color>(StringComparer.OrdinalIgnoreCase) |
||||
|
{ |
||||
|
{ nameof(AliceBlue), AliceBlue }, |
||||
|
{ nameof(AntiqueWhite), AntiqueWhite }, |
||||
|
{ nameof(Aqua), Aqua }, |
||||
|
{ nameof(Aquamarine), Aquamarine }, |
||||
|
{ nameof(Azure), Azure }, |
||||
|
{ nameof(Beige), Beige }, |
||||
|
{ nameof(Bisque), Bisque }, |
||||
|
{ nameof(Black), Black }, |
||||
|
{ nameof(BlanchedAlmond), BlanchedAlmond }, |
||||
|
{ nameof(Blue), Blue }, |
||||
|
{ nameof(BlueViolet), BlueViolet }, |
||||
|
{ nameof(Brown), Brown }, |
||||
|
{ nameof(BurlyWood), BurlyWood }, |
||||
|
{ nameof(CadetBlue), CadetBlue }, |
||||
|
{ nameof(Chartreuse), Chartreuse }, |
||||
|
{ nameof(Chocolate), Chocolate }, |
||||
|
{ nameof(Coral), Coral }, |
||||
|
{ nameof(CornflowerBlue), CornflowerBlue }, |
||||
|
{ nameof(Cornsilk), Cornsilk }, |
||||
|
{ nameof(Crimson), Crimson }, |
||||
|
{ nameof(Cyan), Cyan }, |
||||
|
{ nameof(DarkBlue), DarkBlue }, |
||||
|
{ nameof(DarkCyan), DarkCyan }, |
||||
|
{ nameof(DarkGoldenrod), DarkGoldenrod }, |
||||
|
{ nameof(DarkGray), DarkGray }, |
||||
|
{ nameof(DarkGreen), DarkGreen }, |
||||
|
{ nameof(DarkGrey), DarkGrey }, |
||||
|
{ nameof(DarkKhaki), DarkKhaki }, |
||||
|
{ nameof(DarkMagenta), DarkMagenta }, |
||||
|
{ nameof(DarkOliveGreen), DarkOliveGreen }, |
||||
|
{ nameof(DarkOrange), DarkOrange }, |
||||
|
{ nameof(DarkOrchid), DarkOrchid }, |
||||
|
{ nameof(DarkRed), DarkRed }, |
||||
|
{ nameof(DarkSalmon), DarkSalmon }, |
||||
|
{ nameof(DarkSeaGreen), DarkSeaGreen }, |
||||
|
{ nameof(DarkSlateBlue), DarkSlateBlue }, |
||||
|
{ nameof(DarkSlateGray), DarkSlateGray }, |
||||
|
{ nameof(DarkSlateGrey), DarkSlateGrey }, |
||||
|
{ nameof(DarkTurquoise), DarkTurquoise }, |
||||
|
{ nameof(DarkViolet), DarkViolet }, |
||||
|
{ nameof(DeepPink), DeepPink }, |
||||
|
{ nameof(DeepSkyBlue), DeepSkyBlue }, |
||||
|
{ nameof(DimGray), DimGray }, |
||||
|
{ nameof(DimGrey), DimGrey }, |
||||
|
{ nameof(DodgerBlue), DodgerBlue }, |
||||
|
{ nameof(Firebrick), Firebrick }, |
||||
|
{ nameof(FloralWhite), FloralWhite }, |
||||
|
{ nameof(ForestGreen), ForestGreen }, |
||||
|
{ nameof(Fuchsia), Fuchsia }, |
||||
|
{ nameof(Gainsboro), Gainsboro }, |
||||
|
{ nameof(GhostWhite), GhostWhite }, |
||||
|
{ nameof(Gold), Gold }, |
||||
|
{ nameof(Goldenrod), Goldenrod }, |
||||
|
{ nameof(Gray), Gray }, |
||||
|
{ nameof(Green), Green }, |
||||
|
{ nameof(GreenYellow), GreenYellow }, |
||||
|
{ nameof(Grey), Grey }, |
||||
|
{ nameof(Honeydew), Honeydew }, |
||||
|
{ nameof(HotPink), HotPink }, |
||||
|
{ nameof(IndianRed), IndianRed }, |
||||
|
{ nameof(Indigo), Indigo }, |
||||
|
{ nameof(Ivory), Ivory }, |
||||
|
{ nameof(Khaki), Khaki }, |
||||
|
{ nameof(Lavender), Lavender }, |
||||
|
{ nameof(LavenderBlush), LavenderBlush }, |
||||
|
{ nameof(LawnGreen), LawnGreen }, |
||||
|
{ nameof(LemonChiffon), LemonChiffon }, |
||||
|
{ nameof(LightBlue), LightBlue }, |
||||
|
{ nameof(LightCoral), LightCoral }, |
||||
|
{ nameof(LightCyan), LightCyan }, |
||||
|
{ nameof(LightGoldenrodYellow), LightGoldenrodYellow }, |
||||
|
{ nameof(LightGray), LightGray }, |
||||
|
{ nameof(LightGreen), LightGreen }, |
||||
|
{ nameof(LightGrey), LightGrey }, |
||||
|
{ nameof(LightPink), LightPink }, |
||||
|
{ nameof(LightSalmon), LightSalmon }, |
||||
|
{ nameof(LightSeaGreen), LightSeaGreen }, |
||||
|
{ nameof(LightSkyBlue), LightSkyBlue }, |
||||
|
{ nameof(LightSlateGray), LightSlateGray }, |
||||
|
{ nameof(LightSlateGrey), LightSlateGrey }, |
||||
|
{ nameof(LightSteelBlue), LightSteelBlue }, |
||||
|
{ nameof(LightYellow), LightYellow }, |
||||
|
{ nameof(Lime), Lime }, |
||||
|
{ nameof(LimeGreen), LimeGreen }, |
||||
|
{ nameof(Linen), Linen }, |
||||
|
{ nameof(Magenta), Magenta }, |
||||
|
{ nameof(Maroon), Maroon }, |
||||
|
{ nameof(MediumAquamarine), MediumAquamarine }, |
||||
|
{ nameof(MediumBlue), MediumBlue }, |
||||
|
{ nameof(MediumOrchid), MediumOrchid }, |
||||
|
{ nameof(MediumPurple), MediumPurple }, |
||||
|
{ nameof(MediumSeaGreen), MediumSeaGreen }, |
||||
|
{ nameof(MediumSlateBlue), MediumSlateBlue }, |
||||
|
{ nameof(MediumSpringGreen), MediumSpringGreen }, |
||||
|
{ nameof(MediumTurquoise), MediumTurquoise }, |
||||
|
{ nameof(MediumVioletRed), MediumVioletRed }, |
||||
|
{ nameof(MidnightBlue), MidnightBlue }, |
||||
|
{ nameof(MintCream), MintCream }, |
||||
|
{ nameof(MistyRose), MistyRose }, |
||||
|
{ nameof(Moccasin), Moccasin }, |
||||
|
{ nameof(NavajoWhite), NavajoWhite }, |
||||
|
{ nameof(Navy), Navy }, |
||||
|
{ nameof(OldLace), OldLace }, |
||||
|
{ nameof(Olive), Olive }, |
||||
|
{ nameof(OliveDrab), OliveDrab }, |
||||
|
{ nameof(Orange), Orange }, |
||||
|
{ nameof(OrangeRed), OrangeRed }, |
||||
|
{ nameof(Orchid), Orchid }, |
||||
|
{ nameof(PaleGoldenrod), PaleGoldenrod }, |
||||
|
{ nameof(PaleGreen), PaleGreen }, |
||||
|
{ nameof(PaleTurquoise), PaleTurquoise }, |
||||
|
{ nameof(PaleVioletRed), PaleVioletRed }, |
||||
|
{ nameof(PapayaWhip), PapayaWhip }, |
||||
|
{ nameof(PeachPuff), PeachPuff }, |
||||
|
{ nameof(Peru), Peru }, |
||||
|
{ nameof(Pink), Pink }, |
||||
|
{ nameof(Plum), Plum }, |
||||
|
{ nameof(PowderBlue), PowderBlue }, |
||||
|
{ nameof(Purple), Purple }, |
||||
|
{ nameof(RebeccaPurple), RebeccaPurple }, |
||||
|
{ nameof(Red), Red }, |
||||
|
{ nameof(RosyBrown), RosyBrown }, |
||||
|
{ nameof(RoyalBlue), RoyalBlue }, |
||||
|
{ nameof(SaddleBrown), SaddleBrown }, |
||||
|
{ nameof(Salmon), Salmon }, |
||||
|
{ nameof(SandyBrown), SandyBrown }, |
||||
|
{ nameof(SeaGreen), SeaGreen }, |
||||
|
{ nameof(SeaShell), SeaShell }, |
||||
|
{ nameof(Sienna), Sienna }, |
||||
|
{ nameof(Silver), Silver }, |
||||
|
{ nameof(SkyBlue), SkyBlue }, |
||||
|
{ nameof(SlateBlue), SlateBlue }, |
||||
|
{ nameof(SlateGray), SlateGray }, |
||||
|
{ nameof(SlateGrey), SlateGrey }, |
||||
|
{ nameof(Snow), Snow }, |
||||
|
{ nameof(SpringGreen), SpringGreen }, |
||||
|
{ nameof(SteelBlue), SteelBlue }, |
||||
|
{ nameof(Tan), Tan }, |
||||
|
{ nameof(Teal), Teal }, |
||||
|
{ nameof(Thistle), Thistle }, |
||||
|
{ nameof(Tomato), Tomato }, |
||||
|
{ nameof(Transparent), Transparent }, |
||||
|
{ nameof(Turquoise), Turquoise }, |
||||
|
{ nameof(Violet), Violet }, |
||||
|
{ nameof(Wheat), Wheat }, |
||||
|
{ nameof(White), White }, |
||||
|
{ nameof(WhiteSmoke), WhiteSmoke }, |
||||
|
{ nameof(Yellow), Yellow }, |
||||
|
{ nameof(YellowGreen), YellowGreen } |
||||
|
}; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,166 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using System; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp |
||||
|
{ |
||||
|
/// <content>
|
||||
|
/// Contains the definition of <see cref="WebSafePalette"/>.
|
||||
|
/// </content>
|
||||
|
public partial struct Color |
||||
|
{ |
||||
|
private static readonly Lazy<Color[]> WebSafePaletteLazy = new Lazy<Color[]>(CreateWebSafePalette, true); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets a collection of named, web safe colors as defined in the CSS Color Module Level 4.
|
||||
|
/// </summary>
|
||||
|
public static ReadOnlyMemory<Color> WebSafePalette => WebSafePaletteLazy.Value; |
||||
|
|
||||
|
private static Color[] CreateWebSafePalette() => new[] |
||||
|
{ |
||||
|
AliceBlue, |
||||
|
AntiqueWhite, |
||||
|
Aqua, |
||||
|
Aquamarine, |
||||
|
Azure, |
||||
|
Beige, |
||||
|
Bisque, |
||||
|
Black, |
||||
|
BlanchedAlmond, |
||||
|
Blue, |
||||
|
BlueViolet, |
||||
|
Brown, |
||||
|
BurlyWood, |
||||
|
CadetBlue, |
||||
|
Chartreuse, |
||||
|
Chocolate, |
||||
|
Coral, |
||||
|
CornflowerBlue, |
||||
|
Cornsilk, |
||||
|
Crimson, |
||||
|
Cyan, |
||||
|
DarkBlue, |
||||
|
DarkCyan, |
||||
|
DarkGoldenrod, |
||||
|
DarkGray, |
||||
|
DarkGreen, |
||||
|
DarkKhaki, |
||||
|
DarkMagenta, |
||||
|
DarkOliveGreen, |
||||
|
DarkOrange, |
||||
|
DarkOrchid, |
||||
|
DarkRed, |
||||
|
DarkSalmon, |
||||
|
DarkSeaGreen, |
||||
|
DarkSlateBlue, |
||||
|
DarkSlateGray, |
||||
|
DarkTurquoise, |
||||
|
DarkViolet, |
||||
|
DeepPink, |
||||
|
DeepSkyBlue, |
||||
|
DimGray, |
||||
|
DodgerBlue, |
||||
|
Firebrick, |
||||
|
FloralWhite, |
||||
|
ForestGreen, |
||||
|
Fuchsia, |
||||
|
Gainsboro, |
||||
|
GhostWhite, |
||||
|
Gold, |
||||
|
Goldenrod, |
||||
|
Gray, |
||||
|
Green, |
||||
|
GreenYellow, |
||||
|
Honeydew, |
||||
|
HotPink, |
||||
|
IndianRed, |
||||
|
Indigo, |
||||
|
Ivory, |
||||
|
Khaki, |
||||
|
Lavender, |
||||
|
LavenderBlush, |
||||
|
LawnGreen, |
||||
|
LemonChiffon, |
||||
|
LightBlue, |
||||
|
LightCoral, |
||||
|
LightCyan, |
||||
|
LightGoldenrodYellow, |
||||
|
LightGray, |
||||
|
LightGreen, |
||||
|
LightPink, |
||||
|
LightSalmon, |
||||
|
LightSeaGreen, |
||||
|
LightSkyBlue, |
||||
|
LightSlateGray, |
||||
|
LightSteelBlue, |
||||
|
LightYellow, |
||||
|
Lime, |
||||
|
LimeGreen, |
||||
|
Linen, |
||||
|
Magenta, |
||||
|
Maroon, |
||||
|
MediumAquamarine, |
||||
|
MediumBlue, |
||||
|
MediumOrchid, |
||||
|
MediumPurple, |
||||
|
MediumSeaGreen, |
||||
|
MediumSlateBlue, |
||||
|
MediumSpringGreen, |
||||
|
MediumTurquoise, |
||||
|
MediumVioletRed, |
||||
|
MidnightBlue, |
||||
|
MintCream, |
||||
|
MistyRose, |
||||
|
Moccasin, |
||||
|
NavajoWhite, |
||||
|
Navy, |
||||
|
OldLace, |
||||
|
Olive, |
||||
|
OliveDrab, |
||||
|
Orange, |
||||
|
OrangeRed, |
||||
|
Orchid, |
||||
|
PaleGoldenrod, |
||||
|
PaleGreen, |
||||
|
PaleTurquoise, |
||||
|
PaleVioletRed, |
||||
|
PapayaWhip, |
||||
|
PeachPuff, |
||||
|
Peru, |
||||
|
Pink, |
||||
|
Plum, |
||||
|
PowderBlue, |
||||
|
Purple, |
||||
|
RebeccaPurple, |
||||
|
Red, |
||||
|
RosyBrown, |
||||
|
RoyalBlue, |
||||
|
SaddleBrown, |
||||
|
Salmon, |
||||
|
SandyBrown, |
||||
|
SeaGreen, |
||||
|
SeaShell, |
||||
|
Sienna, |
||||
|
Silver, |
||||
|
SkyBlue, |
||||
|
SlateBlue, |
||||
|
SlateGray, |
||||
|
Snow, |
||||
|
SpringGreen, |
||||
|
SteelBlue, |
||||
|
Tan, |
||||
|
Teal, |
||||
|
Thistle, |
||||
|
Tomato, |
||||
|
Transparent, |
||||
|
Turquoise, |
||||
|
Violet, |
||||
|
Wheat, |
||||
|
White, |
||||
|
WhiteSmoke, |
||||
|
Yellow, |
||||
|
YellowGreen |
||||
|
}; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,135 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using System; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp |
||||
|
{ |
||||
|
/// <content>
|
||||
|
/// Contains the definition of <see cref="WernerPalette"/>.
|
||||
|
/// </content>
|
||||
|
public partial struct Color |
||||
|
{ |
||||
|
private static readonly Lazy<Color[]> WernerPaletteLazy = new Lazy<Color[]>(CreateWernerPalette, true); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets a collection of colors as defined in the original second edition of Werner’s Nomenclature of Colours 1821.
|
||||
|
/// The hex codes were collected and defined by Nicholas Rougeux <see href="https://www.c82.net/werner"/>.
|
||||
|
/// </summary>
|
||||
|
public static ReadOnlyMemory<Color> WernerPalette => WernerPaletteLazy.Value; |
||||
|
|
||||
|
private static Color[] CreateWernerPalette() => new[] |
||||
|
{ |
||||
|
ParseHex("#f1e9cd"), |
||||
|
ParseHex("#f2e7cf"), |
||||
|
ParseHex("#ece6d0"), |
||||
|
ParseHex("#f2eacc"), |
||||
|
ParseHex("#f3e9ca"), |
||||
|
ParseHex("#f2ebcd"), |
||||
|
ParseHex("#e6e1c9"), |
||||
|
ParseHex("#e2ddc6"), |
||||
|
ParseHex("#cbc8b7"), |
||||
|
ParseHex("#bfbbb0"), |
||||
|
ParseHex("#bebeb3"), |
||||
|
ParseHex("#b7b5ac"), |
||||
|
ParseHex("#bab191"), |
||||
|
ParseHex("#9c9d9a"), |
||||
|
ParseHex("#8a8d84"), |
||||
|
ParseHex("#5b5c61"), |
||||
|
ParseHex("#555152"), |
||||
|
ParseHex("#413f44"), |
||||
|
ParseHex("#454445"), |
||||
|
ParseHex("#423937"), |
||||
|
ParseHex("#433635"), |
||||
|
ParseHex("#252024"), |
||||
|
ParseHex("#241f20"), |
||||
|
ParseHex("#281f3f"), |
||||
|
ParseHex("#1c1949"), |
||||
|
ParseHex("#4f638d"), |
||||
|
ParseHex("#383867"), |
||||
|
ParseHex("#5c6b8f"), |
||||
|
ParseHex("#657abb"), |
||||
|
ParseHex("#6f88af"), |
||||
|
ParseHex("#7994b5"), |
||||
|
ParseHex("#6fb5a8"), |
||||
|
ParseHex("#719ba2"), |
||||
|
ParseHex("#8aa1a6"), |
||||
|
ParseHex("#d0d5d3"), |
||||
|
ParseHex("#8590ae"), |
||||
|
ParseHex("#3a2f52"), |
||||
|
ParseHex("#39334a"), |
||||
|
ParseHex("#6c6d94"), |
||||
|
ParseHex("#584c77"), |
||||
|
ParseHex("#533552"), |
||||
|
ParseHex("#463759"), |
||||
|
ParseHex("#bfbac0"), |
||||
|
ParseHex("#77747f"), |
||||
|
ParseHex("#4a475c"), |
||||
|
ParseHex("#b8bfaf"), |
||||
|
ParseHex("#b2b599"), |
||||
|
ParseHex("#979c84"), |
||||
|
ParseHex("#5d6161"), |
||||
|
ParseHex("#61ac86"), |
||||
|
ParseHex("#a4b6a7"), |
||||
|
ParseHex("#adba98"), |
||||
|
ParseHex("#93b778"), |
||||
|
ParseHex("#7d8c55"), |
||||
|
ParseHex("#33431e"), |
||||
|
ParseHex("#7c8635"), |
||||
|
ParseHex("#8e9849"), |
||||
|
ParseHex("#c2c190"), |
||||
|
ParseHex("#67765b"), |
||||
|
ParseHex("#ab924b"), |
||||
|
ParseHex("#c8c76f"), |
||||
|
ParseHex("#ccc050"), |
||||
|
ParseHex("#ebdd99"), |
||||
|
ParseHex("#ab9649"), |
||||
|
ParseHex("#dbc364"), |
||||
|
ParseHex("#e6d058"), |
||||
|
ParseHex("#ead665"), |
||||
|
ParseHex("#d09b2c"), |
||||
|
ParseHex("#a36629"), |
||||
|
ParseHex("#a77d35"), |
||||
|
ParseHex("#f0d696"), |
||||
|
ParseHex("#d7c485"), |
||||
|
ParseHex("#f1d28c"), |
||||
|
ParseHex("#efcc83"), |
||||
|
ParseHex("#f3daa7"), |
||||
|
ParseHex("#dfa837"), |
||||
|
ParseHex("#ebbc71"), |
||||
|
ParseHex("#d17c3f"), |
||||
|
ParseHex("#92462f"), |
||||
|
ParseHex("#be7249"), |
||||
|
ParseHex("#bb603c"), |
||||
|
ParseHex("#c76b4a"), |
||||
|
ParseHex("#a75536"), |
||||
|
ParseHex("#b63e36"), |
||||
|
ParseHex("#b5493a"), |
||||
|
ParseHex("#cd6d57"), |
||||
|
ParseHex("#711518"), |
||||
|
ParseHex("#e9c49d"), |
||||
|
ParseHex("#eedac3"), |
||||
|
ParseHex("#eecfbf"), |
||||
|
ParseHex("#ce536b"), |
||||
|
ParseHex("#b74a70"), |
||||
|
ParseHex("#b7757c"), |
||||
|
ParseHex("#612741"), |
||||
|
ParseHex("#7a4848"), |
||||
|
ParseHex("#3f3033"), |
||||
|
ParseHex("#8d746f"), |
||||
|
ParseHex("#4d3635"), |
||||
|
ParseHex("#6e3b31"), |
||||
|
ParseHex("#864735"), |
||||
|
ParseHex("#553d3a"), |
||||
|
ParseHex("#613936"), |
||||
|
ParseHex("#7a4b3a"), |
||||
|
ParseHex("#946943"), |
||||
|
ParseHex("#c39e6d"), |
||||
|
ParseHex("#513e32"), |
||||
|
ParseHex("#8b7859"), |
||||
|
ParseHex("#9b856b"), |
||||
|
ParseHex("#766051"), |
||||
|
ParseHex("#453b32") |
||||
|
}; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,268 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using System; |
||||
|
using System.Numerics; |
||||
|
using System.Runtime.CompilerServices; |
||||
|
using System.Runtime.InteropServices; |
||||
|
|
||||
|
using SixLabors.ImageSharp.PixelFormats; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Represents a color value that is convertible to any <see cref="IPixel{TSelf}"/> type.
|
||||
|
/// </summary>
|
||||
|
/// <remarks>
|
||||
|
/// The internal representation and layout of this structure is hidden by intention.
|
||||
|
/// It's not serializable, and it should not be considered as part of a contract.
|
||||
|
/// Unlike System.Drawing.Color, <see cref="Color"/> has to be converted to a specific pixel value
|
||||
|
/// to query the color components.
|
||||
|
/// </remarks>
|
||||
|
public readonly partial struct Color : IEquatable<Color> |
||||
|
{ |
||||
|
private readonly Rgba64 data; |
||||
|
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
private Color(byte r, byte g, byte b, byte a) |
||||
|
{ |
||||
|
this.data = new Rgba64( |
||||
|
ImageMaths.UpscaleFrom8BitTo16Bit(r), |
||||
|
ImageMaths.UpscaleFrom8BitTo16Bit(g), |
||||
|
ImageMaths.UpscaleFrom8BitTo16Bit(b), |
||||
|
ImageMaths.UpscaleFrom8BitTo16Bit(a)); |
||||
|
} |
||||
|
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
private Color(byte r, byte g, byte b) |
||||
|
{ |
||||
|
this.data = new Rgba64( |
||||
|
ImageMaths.UpscaleFrom8BitTo16Bit(r), |
||||
|
ImageMaths.UpscaleFrom8BitTo16Bit(g), |
||||
|
ImageMaths.UpscaleFrom8BitTo16Bit(b), |
||||
|
ushort.MaxValue); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Checks whether two <see cref="Color"/> structures are equal.
|
||||
|
/// </summary>
|
||||
|
/// <param name="left">The left hand <see cref="Color"/> operand.</param>
|
||||
|
/// <param name="right">The right hand <see cref="Color"/> operand.</param>
|
||||
|
/// <returns>
|
||||
|
/// True if the <paramref name="left"/> parameter is equal to the <paramref name="right"/> parameter;
|
||||
|
/// otherwise, false.
|
||||
|
/// </returns>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public static bool operator ==(Color left, Color right) |
||||
|
{ |
||||
|
return left.Equals(right); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Checks whether two <see cref="Color"/> structures are equal.
|
||||
|
/// </summary>
|
||||
|
/// <param name="left">The left hand <see cref="Color"/> operand.</param>
|
||||
|
/// <param name="right">The right hand <see cref="Color"/> operand.</param>
|
||||
|
/// <returns>
|
||||
|
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter;
|
||||
|
/// otherwise, false.
|
||||
|
/// </returns>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public static bool operator !=(Color left, Color right) |
||||
|
{ |
||||
|
return !left.Equals(right); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Creates a <see cref="Color"/> from RGBA bytes.
|
||||
|
/// </summary>
|
||||
|
/// <param name="r">The red component (0-255).</param>
|
||||
|
/// <param name="g">The green component (0-255).</param>
|
||||
|
/// <param name="b">The blue component (0-255).</param>
|
||||
|
/// <param name="a">The alpha component (0-255).</param>
|
||||
|
/// <returns>The <see cref="Color"/>.</returns>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public static Color FromRgba(byte r, byte g, byte b, byte a) => new Color(r, g, b, a); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Creates a <see cref="Color"/> from RGB bytes.
|
||||
|
/// </summary>
|
||||
|
/// <param name="r">The red component (0-255).</param>
|
||||
|
/// <param name="g">The green component (0-255).</param>
|
||||
|
/// <param name="b">The blue component (0-255).</param>
|
||||
|
/// <returns>The <see cref="Color"/>.</returns>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public static Color FromRgb(byte r, byte g, byte b) => new Color(r, g, b); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of the <see cref="Color"/> struct
|
||||
|
/// from the given hexadecimal string.
|
||||
|
/// </summary>
|
||||
|
/// <param name="hex">
|
||||
|
/// The hexadecimal representation of the combined color components arranged
|
||||
|
/// in rgb, rgba, rrggbb, or rrggbbaa format to match web syntax.
|
||||
|
/// </param>
|
||||
|
/// <returns>
|
||||
|
/// The <see cref="Color"/>.
|
||||
|
/// </returns>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public static Color ParseHex(string hex) |
||||
|
{ |
||||
|
var rgba = Rgba32.ParseHex(hex); |
||||
|
|
||||
|
return new Color(rgba); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Attempts to creates a new instance of the <see cref="Color"/> struct
|
||||
|
/// from the given hexadecimal string.
|
||||
|
/// </summary>
|
||||
|
/// <param name="hex">
|
||||
|
/// The hexadecimal representation of the combined color components arranged
|
||||
|
/// in rgb, rgba, rrggbb, or rrggbbaa format to match web syntax.
|
||||
|
/// </param>
|
||||
|
/// <param name="result">When this method returns, contains the <see cref="Color"/> equivalent of the hexadecimal input.</param>
|
||||
|
/// <returns>
|
||||
|
/// The <see cref="bool"/>.
|
||||
|
/// </returns>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public static bool TryParseHex(string hex, out Color result) |
||||
|
{ |
||||
|
result = default; |
||||
|
|
||||
|
if (Rgba32.TryParseHex(hex, out Rgba32 rgba)) |
||||
|
{ |
||||
|
result = new Color(rgba); |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Creates a new instance of the <see cref="Color"/> struct
|
||||
|
/// from the given input string.
|
||||
|
/// </summary>
|
||||
|
/// <param name="input">
|
||||
|
/// The name of the color or the hexadecimal representation of the combined color components arranged
|
||||
|
/// in rgb, rgba, rrggbb, or rrggbbaa format to match web syntax.
|
||||
|
/// </param>
|
||||
|
/// <returns>
|
||||
|
/// The <see cref="Color"/>.
|
||||
|
/// </returns>
|
||||
|
public static Color Parse(string input) |
||||
|
{ |
||||
|
Guard.NotNull(input, nameof(input)); |
||||
|
|
||||
|
if (!TryParse(input, out Color color)) |
||||
|
{ |
||||
|
throw new ArgumentException("Input string is not in the correct format.", nameof(input)); |
||||
|
} |
||||
|
|
||||
|
return color; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Attempts to creates a new instance of the <see cref="Color"/> struct
|
||||
|
/// from the given input string.
|
||||
|
/// </summary>
|
||||
|
/// <param name="input">
|
||||
|
/// The name of the color or the hexadecimal representation of the combined color components arranged
|
||||
|
/// in rgb, rgba, rrggbb, or rrggbbaa format to match web syntax.
|
||||
|
/// </param>
|
||||
|
/// <param name="result">When this method returns, contains the <see cref="Color"/> equivalent of the hexadecimal input.</param>
|
||||
|
/// <returns>
|
||||
|
/// The <see cref="bool"/>.
|
||||
|
/// </returns>
|
||||
|
public static bool TryParse(string input, out Color result) |
||||
|
{ |
||||
|
result = default; |
||||
|
|
||||
|
if (string.IsNullOrWhiteSpace(input)) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
if (NamedColorsLookupLazy.Value.TryGetValue(input, out result)) |
||||
|
{ |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
return TryParseHex(input, out result); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Alters the alpha channel of the color, returning a new instance.
|
||||
|
/// </summary>
|
||||
|
/// <param name="alpha">The new value of alpha [0..1].</param>
|
||||
|
/// <returns>The color having it's alpha channel altered.</returns>
|
||||
|
public Color WithAlpha(float alpha) |
||||
|
{ |
||||
|
var v = (Vector4)this; |
||||
|
v.W = alpha; |
||||
|
return new Color(v); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the hexadecimal representation of the color instance in rrggbbaa form.
|
||||
|
/// </summary>
|
||||
|
/// <returns>A hexadecimal string representation of the value.</returns>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public string ToHex() => this.data.ToRgba32().ToHex(); |
||||
|
|
||||
|
/// <inheritdoc />
|
||||
|
public override string ToString() => this.ToHex(); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Converts the color instance to a specified <see cref="IPixel{TSelf}"/> type.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TPixel">The pixel type to convert to.</typeparam>
|
||||
|
/// <returns>The pixel value.</returns>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public TPixel ToPixel<TPixel>() |
||||
|
where TPixel : unmanaged, IPixel<TPixel> |
||||
|
{ |
||||
|
TPixel pixel = default; |
||||
|
pixel.FromRgba64(this.data); |
||||
|
return pixel; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Bulk converts a span of <see cref="Color"/> to a span of a specified <see cref="IPixel{TSelf}"/> type.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TPixel">The pixel type to convert to.</typeparam>
|
||||
|
/// <param name="configuration">The configuration.</param>
|
||||
|
/// <param name="source">The source color span.</param>
|
||||
|
/// <param name="destination">The destination pixel span.</param>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public static void ToPixel<TPixel>( |
||||
|
Configuration configuration, |
||||
|
ReadOnlySpan<Color> source, |
||||
|
Span<TPixel> destination) |
||||
|
where TPixel : unmanaged, IPixel<TPixel> |
||||
|
{ |
||||
|
ReadOnlySpan<Rgba64> rgba64Span = MemoryMarshal.Cast<Color, Rgba64>(source); |
||||
|
PixelOperations<TPixel>.Instance.FromRgba64(configuration, rgba64Span, destination); |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc />
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public bool Equals(Color other) |
||||
|
{ |
||||
|
return this.data.PackedValue == other.data.PackedValue; |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc />
|
||||
|
public override bool Equals(object obj) |
||||
|
{ |
||||
|
return obj is Color other && this.Equals(other); |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc />
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public override int GetHashCode() |
||||
|
{ |
||||
|
return this.data.PackedValue.GetHashCode(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,79 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using System; |
|
||||
using System.Runtime.CompilerServices; |
|
||||
|
|
||||
// ReSharper disable CompareOfFloatsByEqualityOperator
|
|
||||
namespace SixLabors.ImageSharp.ColorSpaces |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Represents the coordinates of CIEXY chromaticity space.
|
|
||||
/// </summary>
|
|
||||
public readonly struct CieXyChromaticityCoordinates : IEquatable<CieXyChromaticityCoordinates> |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Gets the chromaticity X-coordinate.
|
|
||||
/// </summary>
|
|
||||
/// <remarks>
|
|
||||
/// Ranges usually from 0 to 1.
|
|
||||
/// </remarks>
|
|
||||
public readonly float X; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the chromaticity Y-coordinate
|
|
||||
/// </summary>
|
|
||||
/// <remarks>
|
|
||||
/// Ranges usually from 0 to 1.
|
|
||||
/// </remarks>
|
|
||||
public readonly float Y; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="CieXyChromaticityCoordinates"/> struct.
|
|
||||
/// </summary>
|
|
||||
/// <param name="x">Chromaticity coordinate x (usually from 0 to 1)</param>
|
|
||||
/// <param name="y">Chromaticity coordinate y (usually from 0 to 1)</param>
|
|
||||
[MethodImpl(InliningOptions.ShortMethod)] |
|
||||
public CieXyChromaticityCoordinates(float x, float y) |
|
||||
{ |
|
||||
this.X = x; |
|
||||
this.Y = y; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Compares two <see cref="CieXyChromaticityCoordinates"/> objects for equality.
|
|
||||
/// </summary>
|
|
||||
/// <param name="left">The <see cref="CieXyChromaticityCoordinates"/> on the left side of the operand.</param>
|
|
||||
/// <param name="right">The <see cref="CieXyChromaticityCoordinates"/> on the right side of the operand.</param>
|
|
||||
/// <returns>
|
|
||||
/// True if the current left is equal to the <paramref name="right"/> parameter; otherwise, false.
|
|
||||
/// </returns>
|
|
||||
[MethodImpl(InliningOptions.ShortMethod)] |
|
||||
public static bool operator ==(CieXyChromaticityCoordinates left, CieXyChromaticityCoordinates right) => left.Equals(right); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Compares two <see cref="CieXyChromaticityCoordinates"/> objects for inequality
|
|
||||
/// </summary>
|
|
||||
/// <param name="left">The <see cref="CieXyChromaticityCoordinates"/> on the left side of the operand.</param>
|
|
||||
/// <param name="right">The <see cref="CieXyChromaticityCoordinates"/> on the right side of the operand.</param>
|
|
||||
/// <returns>
|
|
||||
/// True if the current left is unequal to the <paramref name="right"/> parameter; otherwise, false.
|
|
||||
/// </returns>
|
|
||||
[MethodImpl(InliningOptions.ShortMethod)] |
|
||||
public static bool operator !=(CieXyChromaticityCoordinates left, CieXyChromaticityCoordinates right) => !left.Equals(right); |
|
||||
|
|
||||
/// <inheritdoc />
|
|
||||
[MethodImpl(InliningOptions.ShortMethod)] |
|
||||
public override int GetHashCode() => HashCode.Combine(this.X, this.Y); |
|
||||
|
|
||||
/// <inheritdoc/>
|
|
||||
public override string ToString() => FormattableString.Invariant($"CieXyChromaticityCoordinates({this.X:#0.##}, {this.Y:#0.##})"); |
|
||||
|
|
||||
/// <inheritdoc/>
|
|
||||
public override bool Equals(object obj) => obj is CieXyChromaticityCoordinates other && this.Equals(other); |
|
||||
|
|
||||
/// <inheritdoc/>
|
|
||||
[MethodImpl(InliningOptions.ShortMethod)] |
|
||||
public bool Equals(CieXyChromaticityCoordinates other) => this.X.Equals(other.X) && this.Y.Equals(other.Y); |
|
||||
} |
|
||||
} |
|
||||