mirror of https://github.com/SixLabors/ImageSharp
1732 changed files with 91282 additions and 63566 deletions
@ -1,20 +1,373 @@ |
|||
# top-most EditorConfig file |
|||
############################################################################### |
|||
# EditorConfig is awesome: http://EditorConfig.org |
|||
############################################################################### |
|||
|
|||
############################################################################### |
|||
# Top-most EditorConfig file |
|||
############################################################################### |
|||
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_size = 4 |
|||
csharp_style_var_for_built_in_types = false:warning |
|||
csharp_style_var_elsewhere = false:warning |
|||
csharp_style_var_when_type_is_apparent = true:warning |
|||
trim_trailing_whitespace = true |
|||
|
|||
############################################################################### |
|||
# Set file behavior to: |
|||
# 2 space indentation |
|||
############################################################################### |
|||
[*.{cmd,config,csproj,json,props,ps1,resx,sh,targets}] |
|||
indent_size = 2 |
|||
|
|||
############################################################################### |
|||
# Set file behavior to: |
|||
# Windows-style line endings, and |
|||
# tabular indentation |
|||
############################################################################### |
|||
[*.sln] |
|||
end_of_line = crlf |
|||
indent_style = tab |
|||
|
|||
############################################################################### |
|||
# Set dotnet naming rules to: |
|||
# suggest async members be pascal case suffixed with Async |
|||
# suggest const declarations be pascal case |
|||
# suggest interfaces be pascal case prefixed with I |
|||
# suggest parameters be camel case |
|||
# suggest private and internal static fields be camel case |
|||
# suggest private and internal fields be camel case |
|||
# suggest public and protected declarations be pascal case |
|||
# suggest static readonly declarations be pascal case |
|||
# suggest type parameters be prefixed with T |
|||
############################################################################### |
|||
[*.cs] |
|||
dotnet_naming_rule.async_members_should_be_pascal_case_suffixed_with_async.severity = suggestion |
|||
dotnet_naming_rule.async_members_should_be_pascal_case_suffixed_with_async.style = pascal_case_suffixed_with_async |
|||
dotnet_naming_rule.async_members_should_be_pascal_case_suffixed_with_async.symbols = async_members |
|||
|
|||
dotnet_naming_rule.const_declarations_should_be_pascal_case.severity = suggestion |
|||
dotnet_naming_rule.const_declarations_should_be_pascal_case.style = pascal_case |
|||
dotnet_naming_rule.const_declarations_should_be_pascal_case.symbols = const_declarations |
|||
|
|||
dotnet_naming_rule.interfaces_should_be_pascal_case_prefixed_with_i.severity = suggestion |
|||
dotnet_naming_rule.interfaces_should_be_pascal_case_prefixed_with_i.style = pascal_case_prefixed_with_i |
|||
dotnet_naming_rule.interfaces_should_be_pascal_case_prefixed_with_i.symbols = interfaces |
|||
|
|||
dotnet_naming_rule.parameters_should_be_camel_case.severity = suggestion |
|||
dotnet_naming_rule.parameters_should_be_camel_case.style = camel_case |
|||
dotnet_naming_rule.parameters_should_be_camel_case.symbols = parameters |
|||
|
|||
dotnet_naming_rule.private_and_internal_static_fields_should_be_camel_case.severity = suggestion |
|||
dotnet_naming_rule.private_and_internal_static_fields_should_be_camel_case.style = camel_case |
|||
dotnet_naming_rule.private_and_internal_static_fields_should_be_camel_case.symbols = private_and_internal_static_fields |
|||
|
|||
dotnet_naming_rule.private_and_internal_fields_should_be_camel_case.severity = suggestion |
|||
dotnet_naming_rule.private_and_internal_fields_should_be_camel_case.style = camel_case |
|||
dotnet_naming_rule.private_and_internal_fields_should_be_camel_case.symbols = private_and_internal_fields |
|||
|
|||
dotnet_naming_rule.public_and_protected_declarations_should_be_pascal_case.severity = suggestion |
|||
dotnet_naming_rule.public_and_protected_declarations_should_be_pascal_case.style = pascal_case |
|||
dotnet_naming_rule.public_and_protected_declarations_should_be_pascal_case.symbols = public_and_protected_declarations |
|||
dotnet_naming_symbols.public_and_protected_declarations.applicable_kinds = method, field, event, property |
|||
|
|||
dotnet_naming_rule.static_readonly_declarations_should_be_pascal_case.severity = suggestion |
|||
dotnet_naming_rule.static_readonly_declarations_should_be_pascal_case.style = pascal_case |
|||
dotnet_naming_rule.static_readonly_declarations_should_be_pascal_case.symbols = static_readonly_declarations |
|||
|
|||
dotnet_naming_rule.type_parameters_should_be_pascal_case_prefixed_with_t.severity = suggestion |
|||
dotnet_naming_rule.type_parameters_should_be_pascal_case_prefixed_with_t.style = pascal_case_prefixed_with_t |
|||
dotnet_naming_rule.type_parameters_should_be_pascal_case_prefixed_with_t.symbols = type_parameters |
|||
|
|||
############################################################################### |
|||
# Set dotnet naming styles to define: |
|||
# camel case |
|||
# pascal case |
|||
# pascal case suffixed with Async |
|||
# pascal case prefixed with I |
|||
# pascal case prefixed with T |
|||
############################################################################### |
|||
[*.cs] |
|||
dotnet_naming_style.camel_case.capitalization = camel_case |
|||
|
|||
dotnet_naming_style.pascal_case.capitalization = pascal_case |
|||
|
|||
dotnet_naming_style.pascal_case_suffixed_with_async.capitalization = pascal_case |
|||
dotnet_naming_style.pascal_case_suffixed_with_async.required_suffix = Async |
|||
|
|||
dotnet_naming_style.pascal_case_prefixed_with_i.capitalization = pascal_case |
|||
dotnet_naming_style.pascal_case_prefixed_with_i.required_prefix = I |
|||
|
|||
dotnet_naming_style.pascal_case_prefixed_with_t.capitalization = pascal_case |
|||
dotnet_naming_style.pascal_case_prefixed_with_t.required_prefix = T |
|||
|
|||
############################################################################### |
|||
# Set dotnet naming symbols to: |
|||
# async members |
|||
# const declarations |
|||
# interfaces |
|||
# private and internal fields |
|||
# private and internal static fields |
|||
# public and protected declarations |
|||
# static readonly declarations |
|||
# type parameters |
|||
############################################################################### |
|||
[*.cs] |
|||
dotnet_naming_symbols.async_members.required_modifiers = async |
|||
|
|||
dotnet_naming_symbols.const_declarations.required_modifiers = const |
|||
|
|||
dotnet_naming_symbols.interfaces.applicable_kinds = interface |
|||
|
|||
dotnet_naming_symbols.parameters.applicable_kinds = parameter |
|||
|
|||
dotnet_naming_symbols.private_and_internal_fields.applicable_accessibilities = private, internal |
|||
dotnet_naming_symbols.private_and_internal_fields.applicable_kinds = field |
|||
|
|||
dotnet_naming_symbols.private_and_internal_static_fields.applicable_accessibilities = private, internal |
|||
dotnet_naming_symbols.private_and_internal_static_fields.applicable_kinds = field |
|||
dotnet_naming_symbols.private_and_internal_static_fields.required_modifiers = static |
|||
|
|||
dotnet_naming_symbols.public_and_protected_declarations.applicable_accessibilities = public, protected |
|||
|
|||
dotnet_naming_symbols.static_readonly_declarations.required_modifiers = static, readonly |
|||
|
|||
dotnet_naming_symbols.type_parameters.applicable_kinds = type_parameter |
|||
|
|||
############################################################################### |
|||
# Set dotnet sort options to: |
|||
# do not separate import directives into groups, and |
|||
# sort system directives first |
|||
############################################################################### |
|||
[*.cs] |
|||
dotnet_separate_import_directive_groups = false |
|||
dotnet_sort_system_directives_first = true |
|||
|
|||
############################################################################### |
|||
# Set dotnet style options to: |
|||
# suggest null-coalescing expressions, |
|||
# suggest collection-initializers, |
|||
# suggest explicit tuple names, |
|||
# suggest null-propogation |
|||
# suggest object-initializers, |
|||
# generate parentheses in arithmetic binary operators for clarity, |
|||
# generate parentheses in other binary operators for clarity, |
|||
# don't generate parentheses in other operators if unnecessary, |
|||
# generate parentheses in relational binary operators for clarity, |
|||
# warn when not using predefined-types for locals, parameters, and members, |
|||
# generate predefined-types of type names for member access, |
|||
# generate auto properties, |
|||
# suggest compound assignment, |
|||
# generate conditional expression over assignment, |
|||
# generate conditional expression over return, |
|||
# suggest inferred anonymous types, |
|||
# suggest inferred tuple names, |
|||
# suggest 'is null' checks over '== null', |
|||
# don't generate 'this.' and 'Me.' for events, |
|||
# warn when not using 'this.' and 'Me.' for fields, |
|||
# warn when not using 'this.' and 'Me.' for methods, |
|||
# warn when not using 'this.' and 'Me.' for properties, |
|||
# suggest readonly fields, and |
|||
# generate accessibility modifiers for non interface members |
|||
############################################################################### |
|||
[*.cs] |
|||
dotnet_style_coalesce_expression = true:suggestion |
|||
dotnet_style_collection_initializer = true:suggestion |
|||
dotnet_style_explicit_tuple_names = true:suggestion |
|||
dotnet_style_null_propagation = true:suggestion |
|||
dotnet_style_object_initializer = true:suggestion |
|||
|
|||
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent |
|||
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent |
|||
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent |
|||
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent |
|||
|
|||
dotnet_style_predefined_type_for_locals_parameters_members = true:warning |
|||
dotnet_style_predefined_type_for_member_access = true:warning |
|||
dotnet_style_predefined_type_for_member_access = true:silent |
|||
|
|||
dotnet_style_prefer_auto_properties = true:silent |
|||
dotnet_style_prefer_compound_assignment = true:suggestion |
|||
dotnet_style_prefer_conditional_expression_over_assignment = true:silent |
|||
dotnet_style_prefer_conditional_expression_over_return = true:silent |
|||
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion |
|||
dotnet_style_prefer_inferred_tuple_names = true:suggestion |
|||
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion |
|||
|
|||
dotnet_style_qualification_for_event = false:silent |
|||
dotnet_style_qualification_for_field = true:warning |
|||
dotnet_style_qualification_for_method = true:warning |
|||
dotnet_style_qualification_for_property = true:warning |
|||
|
|||
[*.tt] |
|||
indent_style = space |
|||
indent_size = 4 |
|||
dotnet_style_readonly_field = true:suggestion |
|||
dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent |
|||
|
|||
############################################################################### |
|||
# Set dotnet style options to: |
|||
# suggest removing all unused parameters |
|||
############################################################################### |
|||
[*.cs] |
|||
dotnet_code_quality_unused_parameters = all:suggestion |
|||
|
|||
############################################################################### |
|||
# Set csharp indent options to: |
|||
# indent block contents, |
|||
# not indent braces, |
|||
# indent case contents, |
|||
# not indent case contents when block, |
|||
# indent labels one less than the current, and |
|||
# indent switch labels |
|||
############################################################################### |
|||
[*.cs] |
|||
csharp_indent_block_contents = true |
|||
csharp_indent_braces = false |
|||
csharp_indent_case_contents = true |
|||
csharp_indent_case_contents_when_block = false |
|||
csharp_indent_labels = one_less_than_current |
|||
csharp_indent_switch_labels = true |
|||
|
|||
############################################################################### |
|||
# Set csharp new-line options to: |
|||
# insert a new-line before "catch", |
|||
# insert a new-line before "else", |
|||
# insert a new-line before "finally", |
|||
# insert a new-line before members in anonymous-types, |
|||
# insert a new-line before members in object-initializers, and |
|||
# insert a new-line before all open braces |
|||
############################################################################### |
|||
[*.cs] |
|||
csharp_new_line_before_catch = true |
|||
csharp_new_line_before_else = true |
|||
csharp_new_line_before_finally = true |
|||
|
|||
csharp_new_line_before_members_in_anonymous_types = true |
|||
csharp_new_line_before_members_in_object_initializers = true |
|||
|
|||
csharp_new_line_before_open_brace = all |
|||
|
|||
############################################################################### |
|||
# Set csharp preserve options to: |
|||
# preserve single-line blocks, and |
|||
# preserve single-line statements |
|||
############################################################################### |
|||
[*.cs] |
|||
csharp_preserve_single_line_blocks = true |
|||
csharp_preserve_single_line_statements = true |
|||
|
|||
############################################################################### |
|||
# Set csharp space options to: |
|||
# remove any space after a cast, |
|||
# add a space after the colon in an inheritance clause, |
|||
# add a space after a comma, |
|||
# remove any space after a dot, |
|||
# add a space after keywords in control flow statements, |
|||
# add a space after a semicolon in a "for" statement, |
|||
# add a space before and after binary operators, |
|||
# remove space around declaration statements, |
|||
# add a space before the colon in an inheritance clause, |
|||
# remove any space before a comma, |
|||
# remove any space before a dot, |
|||
# remove any space before an open square-bracket, |
|||
# remove any space before a semicolon in a "for" statement, |
|||
# remove any space between empty square-brackets, |
|||
# remove any space between a method call's empty parameter list parenthesis, |
|||
# remove any space between a method call's name and its opening parenthesis, |
|||
# remove any space between a method call's parameter list parenthesis, |
|||
# remove any space between a method declaration's empty parameter list parenthesis, |
|||
# remove any space between a method declaration's name and its openening parenthesis, |
|||
# remove any space between a method declaration's parameter list parenthesis, |
|||
# remove any space between parentheses, and |
|||
# remove any space between square brackets |
|||
############################################################################### |
|||
[*.cs] |
|||
csharp_space_after_cast = false |
|||
csharp_space_after_colon_in_inheritance_clause = true |
|||
csharp_space_after_comma = true |
|||
csharp_space_after_dot = false |
|||
csharp_space_after_keywords_in_control_flow_statements = true |
|||
csharp_space_after_semicolon_in_for_statement = true |
|||
|
|||
csharp_space_around_binary_operators = before_and_after |
|||
csharp_space_around_declaration_statements = do_not_ignore |
|||
|
|||
csharp_space_before_colon_in_inheritance_clause = true |
|||
csharp_space_before_comma = false |
|||
csharp_space_before_dot = false |
|||
csharp_space_before_open_square_brackets = false |
|||
csharp_space_before_semicolon_in_for_statement = false |
|||
|
|||
csharp_space_between_empty_square_brackets = false |
|||
csharp_space_between_method_call_empty_parameter_list_parentheses = false |
|||
csharp_space_between_method_call_name_and_opening_parenthesis = false |
|||
csharp_space_between_method_call_parameter_list_parentheses = false |
|||
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false |
|||
csharp_space_between_method_declaration_name_and_open_parenthesis = false |
|||
csharp_space_between_method_declaration_parameter_list_parentheses = false |
|||
csharp_space_between_parentheses = false |
|||
csharp_space_between_square_brackets = false |
|||
|
|||
############################################################################### |
|||
# Set csharp style options to: |
|||
# generate braces, |
|||
# suggest simple default expressions, |
|||
# generate a preferred modifier order, |
|||
# suggest conditional delegate calls, |
|||
# suggest deconstructed variable declarations, |
|||
# generate expression-bodied accessors, |
|||
# generate expression-bodied constructors, |
|||
# generate expression-bodied indexers, |
|||
# generate expression-bodied lambdas, |
|||
# generate expression-bodied methods, |
|||
# generate expression-bodied operators, |
|||
# generate expression-bodied properties, |
|||
# suggest inlined variable declarations, |
|||
# suggest local over anonymous functions, |
|||
# suggest pattern-matching over "as" with "null" check, |
|||
# suggest pattern-matching over "is" with "cast" check, |
|||
# suggest throw expressions, |
|||
# generate a discard variable for unused value expression statements, |
|||
# suggest a discard variable for unused assignments, |
|||
# warn when using var for built-in types, |
|||
# warn when using var when the type is not apparent, and |
|||
# warn when not using var when the type is apparent |
|||
# 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 |
|||
|
|||
@ -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 } |
|||
@ -1,3 +0,0 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:148a268c589b628f5d0b5af0e86911a0b393c35b8b25233c71553657c88e0b96 |
|||
size 7568 |
|||
@ -1,3 +0,0 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:7e4b2ff72aef1979500cd130c28490a00be116bb833bc96ca30c85dc0596099c |
|||
size 15413 |
|||
@ -1,3 +0,0 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:021c12313afbdc65f58bfea8c7b436d5c2102513bb63d9e64ee2b61a1344c56a |
|||
size 1799 |
|||
@ -1,3 +0,0 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:3ae54ae0035df1f8f1459081e2f1d5cceda6f88cca6ec015d8c0209bf0d34edf |
|||
size 32534 |
|||
@ -1,3 +0,0 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:92896854265693f28f9a503b9093cb2c9a4a9b329f310732efdd9c6f6c3761bc |
|||
size 3736 |
|||
@ -1,3 +0,0 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:3ae54ae0035df1f8f1459081e2f1d5cceda6f88cca6ec015d8c0209bf0d34edf |
|||
size 32534 |
|||
|
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: |
|||
"src/ImageSharp/Common/Helpers/DebugGuard.cs" |
|||
# Documentation: https://docs.codecov.io/docs/codecov-yaml |
|||
|
|||
|
|||
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); |
|||
} |
|||
} |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue