mirror of https://github.com/SixLabors/ImageSharp
committed by
GitHub
140 changed files with 7251 additions and 1756 deletions
File diff suppressed because it is too large
File diff suppressed because it is too large
@ -1,112 +1,188 @@ |
|||||
<# |
<# |
||||
// Copyright (c) Six Labors and contributors. |
// Copyright (c) Six Labors and contributors. |
||||
// Licensed under the Apache License, Version 2.0. |
// Licensed under the Apache License, Version 2.0. |
||||
#> |
#> |
||||
<#@ template debug="false" hostspecific="false" language="C#" #> |
<#@ template debug="false" hostspecific="false" language="C#" #> |
||||
<#@ assembly name="System.Core" #> |
<#@ assembly name="System.Core" #> |
||||
<#@ import namespace="System.Linq" #> |
<#@ import namespace="System.Linq" #> |
||||
<#@ import namespace="System.Text" #> |
<#@ import namespace="System.Text" #> |
||||
<#@ import namespace="System.Collections.Generic" #> |
<#@ import namespace="System.Collections.Generic" #> |
||||
<#@ output extension=".cs" #> |
<#@ output extension=".cs" #> |
||||
// Copyright (c) Six Labors and contributors. |
// Copyright (c) Six Labors and contributors. |
||||
// Licensed under the Apache License, Version 2.0. |
// Licensed under the Apache License, Version 2.0. |
||||
|
|
||||
// <auto-generated /> |
// <auto-generated /> |
||||
|
|
||||
using System; |
using System; |
||||
using System.Numerics; |
using System.Numerics; |
||||
using System.Runtime.CompilerServices; |
using System.Runtime.CompilerServices; |
||||
|
|
||||
namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders |
namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders |
||||
{ |
{ |
||||
internal static partial class PorterDuffFunctions |
internal static partial class PorterDuffFunctions |
||||
{ |
{ |
||||
<# |
|
||||
|
<# void GeneratePixelBlenders(string blender) { #> |
||||
void GeneratePixelBlender (string blender) |
|
||||
{ |
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
||||
#> |
public static Vector4 <#=blender#>Src(Vector4 backdrop, Vector4 source, float opacity) |
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
{ |
||||
public static TPixel <#=blender#><TPixel>(TPixel backdrop, TPixel source, float amount) |
opacity = opacity.Clamp(0, 1); |
||||
where TPixel : struct, IPixel<TPixel> |
source.W *= opacity; |
||||
{ |
|
||||
TPixel dest = default; |
return source; |
||||
dest.PackFromVector4(<#=blender#>(backdrop.ToVector4(), source.ToVector4(), amount)); |
} |
||||
return dest; |
|
||||
} |
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
||||
|
public static Vector4 <#=blender#>SrcAtop(Vector4 backdrop, Vector4 source, float opacity) |
||||
<# |
{ |
||||
} |
opacity = opacity.Clamp(0, 1); |
||||
|
source.W *= opacity; |
||||
void GenerateVectorCompositor(string name, string sourceVar, string destVar, string blendVar) |
|
||||
{ |
return Atop(backdrop, source, <#=blender#>(backdrop, source)); |
||||
int a_s = sourceVar == "Vector4.Zero" ? 0 : 1; |
} |
||||
int a_b = destVar == "Vector4.Zero" ? 0 : 1; |
|
||||
int a_x = blendVar == "Vector4.Zero" ? 0 : 1; |
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
||||
#> |
public static Vector4 <#=blender#>SrcOver(Vector4 backdrop, Vector4 source, float opacity) |
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
{ |
||||
public static Vector4 <#=name#>(Vector4 backdrop, Vector4 source, float opacity) |
opacity = opacity.Clamp(0, 1); |
||||
{ |
source.W *= opacity; |
||||
opacity = opacity.Clamp(0, 1); |
|
||||
<# if(sourceVar != "Vector4.Zero" ) { #> |
return Over(backdrop, source, <#=blender#>(backdrop, source)); |
||||
source.W *= opacity; |
} |
||||
<# } #> |
|
||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
||||
// calculate weights |
public static Vector4 <#=blender#>SrcIn(Vector4 backdrop, Vector4 source, float opacity) |
||||
float xw = backdrop.W * source.W; |
{ |
||||
float bw = backdrop.W - xw; |
opacity = opacity.Clamp(0, 1); |
||||
float sw = source.W - xw; |
source.W *= opacity; |
||||
|
|
||||
// calculate final alpha |
return In(backdrop, source, <#=blender#>(backdrop, source)); |
||||
float fw = (sw * <#=a_s#>) + (bw * <#=a_b#>) + (xw * <#=a_x#>); |
} |
||||
|
|
||||
// calculate final value |
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
||||
Vector4 xform = ((<#=blendVar#> * xw) + (<#=destVar#> * bw) + (<#=sourceVar#> * sw)) / MathF.Max(fw, Constants.Epsilon); |
public static Vector4 <#=blender#>SrcOut(Vector4 backdrop, Vector4 source, float opacity) |
||||
xform.W = fw; |
{ |
||||
|
opacity = opacity.Clamp(0, 1); |
||||
return Vector4.Lerp(backdrop, xform, opacity); |
source.W *= opacity; |
||||
} |
|
||||
|
return Out(backdrop, source); |
||||
<# |
} |
||||
} |
|
||||
GenerateVectorCompositor("Src", "source", "Vector4.Zero", "source"); |
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
||||
GenerateVectorCompositor("Atop", "Vector4.Zero", "backdrop", "source"); |
public static Vector4 <#=blender#>Dest(Vector4 backdrop, Vector4 source, float opacity) |
||||
GenerateVectorCompositor("Over", "source", "backdrop", "source"); |
{ |
||||
GenerateVectorCompositor("In", "Vector4.Zero", "Vector4.Zero", "source"); |
return backdrop; |
||||
GenerateVectorCompositor("Out", "source", "Vector4.Zero", "Vector4.Zero"); |
} |
||||
GenerateVectorCompositor("Dest", "Vector4.Zero", "backdrop", "backdrop"); |
|
||||
GenerateVectorCompositor("DestAtop", "source", "Vector4.Zero", "backdrop"); |
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
||||
GenerateVectorCompositor("DestOver", "source", "backdrop", "backdrop"); |
public static Vector4 <#=blender#>DestAtop(Vector4 backdrop, Vector4 source, float opacity) |
||||
GenerateVectorCompositor("DestIn", "Vector4.Zero", "Vector4.Zero", "backdrop"); |
{ |
||||
GenerateVectorCompositor("DestOut", "Vector4.Zero", "backdrop", "Vector4.Zero"); |
opacity = opacity.Clamp(0, 1); |
||||
GenerateVectorCompositor("Clear", "Vector4.Zero", "Vector4.Zero", "Vector4.Zero"); |
source.W *= opacity; |
||||
GenerateVectorCompositor("Xor", "source", "backdrop", "Vector4.Zero"); |
|
||||
|
return Atop(source, backdrop, <#=blender#>(source, backdrop)); |
||||
|
} |
||||
GeneratePixelBlender("Normal"); |
|
||||
GeneratePixelBlender("Multiply"); |
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
||||
GeneratePixelBlender("Add"); |
public static Vector4 <#=blender#>DestOver(Vector4 backdrop, Vector4 source, float opacity) |
||||
GeneratePixelBlender("Subtract"); |
{ |
||||
GeneratePixelBlender("Screen"); |
opacity = opacity.Clamp(0, 1); |
||||
GeneratePixelBlender("Darken"); |
source.W *= opacity; |
||||
GeneratePixelBlender("Lighten"); |
|
||||
GeneratePixelBlender("Overlay"); |
return Over(source, backdrop, <#=blender#>(source, backdrop)); |
||||
GeneratePixelBlender("HardLight"); |
} |
||||
|
|
||||
GeneratePixelBlender("Src"); |
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
||||
GeneratePixelBlender("Atop"); |
public static Vector4 <#=blender#>DestIn(Vector4 backdrop, Vector4 source, float opacity) |
||||
GeneratePixelBlender("Over"); |
{ |
||||
GeneratePixelBlender("In"); |
opacity = opacity.Clamp(0, 1); |
||||
GeneratePixelBlender("Out"); |
source.W *= opacity; |
||||
GeneratePixelBlender("Dest"); |
|
||||
GeneratePixelBlender("DestAtop"); |
return In(source, backdrop, <#=blender#>(source, backdrop)); |
||||
GeneratePixelBlender("DestOver"); |
} |
||||
GeneratePixelBlender("DestIn"); |
|
||||
GeneratePixelBlender("DestOut"); |
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
||||
GeneratePixelBlender("Clear"); |
public static Vector4 <#=blender#>DestOut(Vector4 backdrop, Vector4 source, float opacity) |
||||
GeneratePixelBlender("Xor"); |
{ |
||||
|
opacity = opacity.Clamp(0, 1); |
||||
|
source.W *= opacity; |
||||
#> |
|
||||
} |
return Out(source, backdrop); |
||||
|
} |
||||
|
|
||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
||||
|
public static Vector4 <#=blender#>Xor(Vector4 backdrop, Vector4 source, float opacity) |
||||
|
{ |
||||
|
opacity = opacity.Clamp(0, 1); |
||||
|
source.W *= opacity; |
||||
|
|
||||
|
return Xor(backdrop, source); |
||||
|
} |
||||
|
|
||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
||||
|
public static Vector4 <#=blender#>Clear(Vector4 backdrop, Vector4 source, float opacity) |
||||
|
{ |
||||
|
opacity = opacity.Clamp(0, 1); |
||||
|
source.W *= opacity; |
||||
|
|
||||
|
return Clear(backdrop, source); |
||||
|
} |
||||
|
<# } #> |
||||
|
|
||||
|
|
||||
|
<# void GenerateGenericPixelBlender(string blender, string composer) { #> |
||||
|
|
||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
||||
|
public static TPixel <#=blender#><#=composer#><TPixel>(TPixel backdrop, TPixel source, float opacity) |
||||
|
where TPixel : struct, IPixel<TPixel> |
||||
|
{ |
||||
|
TPixel dest = default; |
||||
|
dest.PackFromVector4(<#=blender#><#=composer#>(backdrop.ToVector4(),source.ToVector4(),opacity)); |
||||
|
return dest; |
||||
|
} |
||||
|
|
||||
|
<# } #> |
||||
|
|
||||
|
<# |
||||
|
|
||||
|
string[] composers = new []{ |
||||
|
"Src", |
||||
|
"SrcAtop", |
||||
|
"SrcOver", |
||||
|
"SrcIn", |
||||
|
"SrcOut", |
||||
|
"Dest", |
||||
|
"DestAtop", |
||||
|
"DestOver", |
||||
|
"DestIn", |
||||
|
"DestOut", |
||||
|
"Clear", |
||||
|
"Xor", |
||||
|
}; |
||||
|
|
||||
|
string[] blenders = new []{ |
||||
|
"Normal", |
||||
|
"Multiply", |
||||
|
"Add", |
||||
|
"Subtract", |
||||
|
"Screen", |
||||
|
"Darken", |
||||
|
"Lighten", |
||||
|
"Overlay", |
||||
|
"HardLight" |
||||
|
}; |
||||
|
|
||||
|
foreach(var blender in blenders) |
||||
|
{ |
||||
|
GeneratePixelBlenders(blender); |
||||
|
|
||||
|
foreach(var composer in composers) |
||||
|
{ |
||||
|
GenerateGenericPixelBlender(blender,composer); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#> |
||||
|
} |
||||
} |
} |
||||
@ -1,194 +1,257 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
// Copyright (c) Six Labors and contributors.
|
||||
// Licensed under the Apache License, Version 2.0.
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
using System; |
using System; |
||||
using System.Numerics; |
using System.Numerics; |
||||
using System.Runtime.CompilerServices; |
using System.Runtime.CompilerServices; |
||||
|
|
||||
namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders |
namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders |
||||
{ |
{ |
||||
/// <summary>
|
/// <summary>
|
||||
/// Collection of Porter Duff alpha blending functions applying an the 'Over' composition model.
|
/// Collection of Porter Duff alpha blending functions applying an the 'Over' composition model.
|
||||
/// </summary>
|
/// </summary>
|
||||
/// <remarks>
|
/// <remarks>
|
||||
/// These functions are designed to be a general solution for all color cases,
|
/// These functions are designed to be a general solution for all color cases,
|
||||
/// that is, they take in account the alpha value of both the backdrop
|
/// that is, they take in account the alpha value of both the backdrop
|
||||
/// and source, and there's no need to alpha-premultiply neither the backdrop
|
/// and source, and there's no need to alpha-premultiply neither the backdrop
|
||||
/// nor the source.
|
/// nor the source.
|
||||
/// Note there are faster functions for when the backdrop color is known
|
/// Note there are faster functions for when the backdrop color is known
|
||||
/// to be opaque
|
/// to be opaque
|
||||
/// </remarks>
|
/// </remarks>
|
||||
internal static partial class PorterDuffFunctions |
internal static partial class PorterDuffFunctions |
||||
{ |
{ |
||||
/// <summary>
|
/// <summary>
|
||||
/// Source over backdrop
|
/// Source over backdrop
|
||||
/// </summary>
|
/// </summary>
|
||||
/// <param name="backdrop">Backdrop color</param>
|
/// <param name="backdrop">Backdrop color</param>
|
||||
/// <param name="source">Source color</param>
|
/// <param name="source">Source color</param>
|
||||
/// <param name="opacity">Opacity applied to Source Alpha</param>
|
/// <returns>Output color</returns>
|
||||
/// <returns>Output color</returns>
|
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
public static Vector4 Normal(Vector4 backdrop, Vector4 source) |
||||
public static Vector4 Normal(Vector4 backdrop, Vector4 source, float opacity) |
{ |
||||
{ |
return source; |
||||
source.W *= opacity; |
} |
||||
return Compose(backdrop, source, source); |
|
||||
} |
/// <summary>
|
||||
|
/// Source multiplied by backdrop
|
||||
/// <summary>
|
/// </summary>
|
||||
/// Source multiplied by backdrop
|
/// <param name="backdrop">Backdrop color</param>
|
||||
/// </summary>
|
/// <param name="source">Source color</param>
|
||||
/// <param name="backdrop">Backdrop color</param>
|
/// <returns>Output color</returns>
|
||||
/// <param name="source">Source color</param>
|
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
||||
/// <param name="opacity">Opacity applied to Source Alpha</param>
|
public static Vector4 Multiply(Vector4 backdrop, Vector4 source) |
||||
/// <returns>Output color</returns>
|
{ |
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
return backdrop * source; |
||||
public static Vector4 Multiply(Vector4 backdrop, Vector4 source, float opacity) |
} |
||||
{ |
|
||||
source.W *= opacity; |
/// <summary>
|
||||
return Compose(backdrop, source, backdrop * source); |
/// Source added to backdrop
|
||||
} |
/// </summary>
|
||||
|
/// <param name="backdrop">Backdrop color</param>
|
||||
/// <summary>
|
/// <param name="source">Source color</param>
|
||||
/// Source added to backdrop
|
/// <returns>Output color</returns>
|
||||
/// </summary>
|
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
||||
/// <param name="backdrop">Backdrop color</param>
|
public static Vector4 Add(Vector4 backdrop, Vector4 source) |
||||
/// <param name="source">Source color</param>
|
{ |
||||
/// <param name="opacity">Opacity applied to Source Alpha</param>
|
return Vector4.Min(Vector4.One, backdrop + source); |
||||
/// <returns>Output color</returns>
|
} |
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|
||||
public static Vector4 Add(Vector4 backdrop, Vector4 source, float opacity) |
/// <summary>
|
||||
{ |
/// Source subtracted from backdrop
|
||||
source.W *= opacity; |
/// </summary>
|
||||
return Compose(backdrop, source, Vector4.Min(Vector4.One, backdrop + source)); |
/// <param name="backdrop">Backdrop color</param>
|
||||
} |
/// <param name="source">Source color</param>
|
||||
|
/// <returns>Output color</returns>
|
||||
/// <summary>
|
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
||||
/// Source subtracted from backdrop
|
public static Vector4 Subtract(Vector4 backdrop, Vector4 source) |
||||
/// </summary>
|
{ |
||||
/// <param name="backdrop">Backdrop color</param>
|
return Vector4.Max(Vector4.Zero, backdrop - source); |
||||
/// <param name="source">Source color</param>
|
} |
||||
/// <param name="opacity">Opacity applied to Source Alpha</param>
|
|
||||
/// <returns>Output color</returns>
|
/// <summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
/// Complement of source multiplied by the complement of backdrop
|
||||
public static Vector4 Subtract(Vector4 backdrop, Vector4 source, float opacity) |
/// </summary>
|
||||
{ |
/// <param name="backdrop">Backdrop color</param>
|
||||
source.W *= opacity; |
/// <param name="source">Source color</param>
|
||||
return Compose(backdrop, source, Vector4.Max(Vector4.Zero, backdrop - source)); |
/// <returns>Output color</returns>
|
||||
} |
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
||||
|
public static Vector4 Screen(Vector4 backdrop, Vector4 source) |
||||
/// <summary>
|
{ |
||||
/// Complement of source multiplied by the complement of backdrop
|
return Vector4.One - ((Vector4.One - backdrop) * (Vector4.One - source)); |
||||
/// </summary>
|
} |
||||
/// <param name="backdrop">Backdrop color</param>
|
|
||||
/// <param name="source">Source color</param>
|
/// <summary>
|
||||
/// <param name="opacity">Opacity applied to Source Alpha</param>
|
/// Per element, chooses the smallest value of source and backdrop
|
||||
/// <returns>Output color</returns>
|
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
/// <param name="backdrop">Backdrop color</param>
|
||||
public static Vector4 Screen(Vector4 backdrop, Vector4 source, float opacity) |
/// <param name="source">Source color</param>
|
||||
{ |
/// <returns>Output color</returns>
|
||||
source.W *= opacity; |
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
||||
return Compose(backdrop, source, Vector4.One - ((Vector4.One - backdrop) * (Vector4.One - source))); |
public static Vector4 Darken(Vector4 backdrop, Vector4 source) |
||||
} |
{ |
||||
|
return Vector4.Min(backdrop, source); |
||||
/// <summary>
|
} |
||||
/// Per element, chooses the smallest value of source and backdrop
|
|
||||
/// </summary>
|
/// <summary>
|
||||
/// <param name="backdrop">Backdrop color</param>
|
/// Per element, chooses the largest value of source and backdrop
|
||||
/// <param name="source">Source color</param>
|
/// </summary>
|
||||
/// <param name="opacity">Opacity applied to Source Alpha</param>
|
/// <param name="backdrop">Backdrop color</param>
|
||||
/// <returns>Output color</returns>
|
/// <param name="source">Source color</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
/// <returns>Output color</returns>
|
||||
public static Vector4 Darken(Vector4 backdrop, Vector4 source, float opacity) |
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
||||
{ |
public static Vector4 Lighten(Vector4 backdrop, Vector4 source) |
||||
source.W *= opacity; |
{ |
||||
return Compose(backdrop, source, Vector4.Min(backdrop, source)); |
return Vector4.Max(backdrop, source); |
||||
} |
} |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// Per element, chooses the largest value of source and backdrop
|
/// Overlays source over backdrop
|
||||
/// </summary>
|
/// </summary>
|
||||
/// <param name="backdrop">Backdrop color</param>
|
/// <param name="backdrop">Backdrop color</param>
|
||||
/// <param name="source">Source color</param>
|
/// <param name="source">Source color</param>
|
||||
/// <param name="opacity">Opacity applied to Source Alpha</param>
|
/// <returns>Output color</returns>
|
||||
/// <returns>Output color</returns>
|
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
public static Vector4 Overlay(Vector4 backdrop, Vector4 source) |
||||
public static Vector4 Lighten(Vector4 backdrop, Vector4 source, float opacity) |
{ |
||||
{ |
float cr = OverlayValueFunction(backdrop.X, source.X); |
||||
source.W *= opacity; |
float cg = OverlayValueFunction(backdrop.Y, source.Y); |
||||
return Compose(backdrop, source, Vector4.Max(backdrop, source)); |
float cb = OverlayValueFunction(backdrop.Z, source.Z); |
||||
} |
|
||||
|
return Vector4.Min(Vector4.One, new Vector4(cr, cg, cb, 0)); |
||||
/// <summary>
|
} |
||||
/// Overlays source over backdrop
|
|
||||
/// </summary>
|
/// <summary>
|
||||
/// <param name="backdrop">Backdrop color</param>
|
/// Hard light effect
|
||||
/// <param name="source">Source color</param>
|
/// </summary>
|
||||
/// <param name="opacity">Opacity applied to Source Alpha</param>
|
/// <param name="backdrop">Backdrop color</param>
|
||||
/// <returns>Output color</returns>
|
/// <param name="source">Source color</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
/// <returns>Output color</returns>
|
||||
public static Vector4 Overlay(Vector4 backdrop, Vector4 source, float opacity) |
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
||||
{ |
public static Vector4 HardLight(Vector4 backdrop, Vector4 source) |
||||
source.W *= opacity; |
{ |
||||
float cr = OverlayValueFunction(backdrop.X, source.X); |
float cr = OverlayValueFunction(source.X, backdrop.X); |
||||
float cg = OverlayValueFunction(backdrop.Y, source.Y); |
float cg = OverlayValueFunction(source.Y, backdrop.Y); |
||||
float cb = OverlayValueFunction(backdrop.Z, source.Z); |
float cb = OverlayValueFunction(source.Z, backdrop.Z); |
||||
|
|
||||
return Compose(backdrop, source, Vector4.Min(Vector4.One, new Vector4(cr, cg, cb, 0))); |
return Vector4.Min(Vector4.One, new Vector4(cr, cg, cb, 0)); |
||||
} |
} |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// Hard light effect
|
/// Helper function for Overlay andHardLight modes
|
||||
/// </summary>
|
/// </summary>
|
||||
/// <param name="backdrop">Backdrop color</param>
|
/// <param name="backdrop">Backdrop color element</param>
|
||||
/// <param name="source">Source color</param>
|
/// <param name="source">Source color element</param>
|
||||
/// <param name="opacity">Opacity applied to Source Alpha</param>
|
/// <returns>Overlay value</returns>
|
||||
/// <returns>Output color</returns>
|
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
private static float OverlayValueFunction(float backdrop, float source) |
||||
public static Vector4 HardLight(Vector4 backdrop, Vector4 source, float opacity) |
{ |
||||
{ |
return backdrop <= 0.5f ? (2 * backdrop * source) : 1 - ((2 * (1 - source)) * (1 - backdrop)); |
||||
source.W *= opacity; |
} |
||||
float cr = OverlayValueFunction(source.X, backdrop.X); |
|
||||
float cg = OverlayValueFunction(source.Y, backdrop.Y); |
/// <summary>
|
||||
float cb = OverlayValueFunction(source.Z, backdrop.Z); |
/// General composition function for all modes, with a general solution for alpha channel
|
||||
|
/// </summary>
|
||||
return Compose(backdrop, source, Vector4.Min(Vector4.One, new Vector4(cr, cg, cb, 0))); |
/// <param name="backdrop">Original Backdrop color</param>
|
||||
} |
/// <param name="source">Original source color</param>
|
||||
|
/// <param name="xform">Desired transformed color, without taking Alpha channel in account</param>
|
||||
/// <summary>
|
/// <returns>The final color</returns>
|
||||
/// Helper function for Overlay andHardLight modes
|
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
||||
/// </summary>
|
private static Vector4 SrcOverReference(Vector4 backdrop, Vector4 source, Vector4 xform) |
||||
/// <param name="backdrop">Backdrop color element</param>
|
{ |
||||
/// <param name="source">Source color element</param>
|
// calculate weights
|
||||
/// <returns>Overlay value</returns>
|
float xw = backdrop.W * source.W; |
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
float bw = backdrop.W - xw; |
||||
private static float OverlayValueFunction(float backdrop, float source) |
float sw = source.W - xw; |
||||
{ |
|
||||
return backdrop <= 0.5f ? (2 * backdrop * source) : 1 - ((2 * (1 - source)) * (1 - backdrop)); |
// calculate final alpha
|
||||
} |
float a = xw + bw + sw; |
||||
|
|
||||
/// <summary>
|
// calculate final value
|
||||
/// General composition function for all modes, with a general solution for alpha channel
|
xform = ((xform * xw) + (backdrop * bw) + (source * sw)) / MathF.Max(a, Constants.Epsilon); |
||||
/// </summary>
|
xform.W = a; |
||||
/// <param name="backdrop">Original Backdrop color</param>
|
|
||||
/// <param name="source">Original source color</param>
|
return xform; |
||||
/// <param name="xform">Desired transformed color, without taking Alpha channel in account</param>
|
} |
||||
/// <returns>The final color</returns>
|
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
public static Vector4 Over(Vector4 dst, Vector4 src, Vector4 blend) |
||||
private static Vector4 Compose(Vector4 backdrop, Vector4 source, Vector4 xform) |
{ |
||||
{ |
// calculate weights
|
||||
// calculate weights
|
float blendW = dst.W * src.W; |
||||
float xw = backdrop.W * source.W; |
float dstW = dst.W - blendW; |
||||
float bw = backdrop.W - xw; |
float srcW = src.W - blendW; |
||||
float sw = source.W - xw; |
|
||||
|
// calculate final alpha
|
||||
// calculate final alpha
|
float alpha = dstW + srcW + blendW; |
||||
float a = xw + bw + sw; |
|
||||
|
// calculate final color
|
||||
// calculate final value
|
Vector4 color = (dst * dstW) + (src * srcW) + (blend * blendW); |
||||
xform = ((xform * xw) + (backdrop * bw) + (source * sw)) / MathF.Max(a, Constants.Epsilon); |
|
||||
xform.W = a; |
// unpremultiply
|
||||
|
color /= MathF.Max(alpha, Constants.Epsilon); |
||||
return xform; |
color.W = alpha; |
||||
} |
|
||||
} |
return color; |
||||
|
} |
||||
|
|
||||
|
public static Vector4 Atop(Vector4 dst, Vector4 src, Vector4 blend) |
||||
|
{ |
||||
|
// calculate weights
|
||||
|
float blendW = dst.W * src.W; |
||||
|
float dstW = dst.W - blendW; |
||||
|
|
||||
|
// calculate final alpha
|
||||
|
float alpha = dstW + blendW; |
||||
|
|
||||
|
// calculate final color
|
||||
|
Vector4 color = (dst * dstW) + (blend * blendW); |
||||
|
|
||||
|
// unpremultiply
|
||||
|
color /= MathF.Max(alpha, Constants.Epsilon); |
||||
|
color.W = alpha; |
||||
|
|
||||
|
return color; |
||||
|
} |
||||
|
|
||||
|
public static Vector4 In(Vector4 dst, Vector4 src, Vector4 blend) |
||||
|
{ |
||||
|
float alpha = dst.W * src.W; |
||||
|
|
||||
|
Vector4 color = src * alpha; // premultiply
|
||||
|
color /= MathF.Max(alpha, Constants.Epsilon); // unpremultiply
|
||||
|
color.W = alpha; |
||||
|
|
||||
|
return color; |
||||
|
} |
||||
|
|
||||
|
public static Vector4 Out(Vector4 dst, Vector4 src) |
||||
|
{ |
||||
|
float alpha = (1 - dst.W) * src.W; |
||||
|
|
||||
|
Vector4 color = src * alpha; // premultiply
|
||||
|
color /= MathF.Max(alpha, Constants.Epsilon); // unpremultiply
|
||||
|
color.W = alpha; |
||||
|
|
||||
|
return color; |
||||
|
} |
||||
|
|
||||
|
public static Vector4 Xor(Vector4 dst, Vector4 src) |
||||
|
{ |
||||
|
float srcW = 1 - dst.W; |
||||
|
float dstW = 1 - src.W; |
||||
|
|
||||
|
float alpha = (src.W * srcW) + (dst.W * dstW); |
||||
|
Vector4 color = (src.W * src * srcW) + (dst.W * dst * dstW); |
||||
|
|
||||
|
// unpremultiply
|
||||
|
color /= MathF.Max(alpha, Constants.Epsilon); |
||||
|
color.W = alpha; |
||||
|
|
||||
|
return color; |
||||
|
} |
||||
|
|
||||
|
private static Vector4 Clear(Vector4 backdrop, Vector4 source) |
||||
|
{ |
||||
|
return Vector4.Zero; |
||||
|
} |
||||
|
} |
||||
} |
} |
||||
@ -0,0 +1,56 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
namespace SixLabors.ImageSharp.PixelFormats |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Enumerates the various color blending modes.
|
||||
|
/// </summary>
|
||||
|
public enum PixelColorBlendingMode |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Default blending mode, also known as "Normal" or "Alpha Blending"
|
||||
|
/// </summary>
|
||||
|
Normal = 0, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Blends the 2 values by multiplication.
|
||||
|
/// </summary>
|
||||
|
Multiply, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Blends the 2 values by addition.
|
||||
|
/// </summary>
|
||||
|
Add, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Blends the 2 values by subtraction.
|
||||
|
/// </summary>
|
||||
|
Subtract, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Multiplies the complements of the backdrop and source values, then complements the result.
|
||||
|
/// </summary>
|
||||
|
Screen, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Selects the minimum of the backdrop and source values.
|
||||
|
/// </summary>
|
||||
|
Darken, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Selects the max of the backdrop and source values.
|
||||
|
/// </summary>
|
||||
|
Lighten, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Multiplies or screens the values, depending on the backdrop vector values.
|
||||
|
/// </summary>
|
||||
|
Overlay, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Multiplies or screens the colors, depending on the source value.
|
||||
|
/// </summary>
|
||||
|
HardLight, |
||||
|
} |
||||
|
} |
||||
@ -1,50 +1,217 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
// Copyright (c) Six Labors and contributors.
|
||||
// Licensed under the Apache License, Version 2.0.
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
using SixLabors.ImageSharp.PixelFormats.PixelBlenders; |
using SixLabors.ImageSharp.PixelFormats.PixelBlenders; |
||||
|
|
||||
namespace SixLabors.ImageSharp.PixelFormats |
namespace SixLabors.ImageSharp.PixelFormats |
||||
{ |
{ |
||||
/// <content>
|
/// <content>
|
||||
/// Provides access to pixel blenders
|
/// Provides access to pixel blenders
|
||||
/// </content>
|
/// </content>
|
||||
public partial class PixelOperations<TPixel> |
public partial class PixelOperations<TPixel> |
||||
where TPixel : struct, IPixel<TPixel> |
where TPixel : struct, IPixel<TPixel> |
||||
{ |
{ |
||||
/// <summary>
|
/// <summary>
|
||||
/// Find an instance of the pixel blender.
|
/// Find an instance of the pixel blender.
|
||||
/// </summary>
|
/// </summary>
|
||||
/// <param name="mode">The blending mode to apply</param>
|
/// <param name="options">the blending and composition to apply</param>
|
||||
/// <returns>A <see cref="PixelBlender{TPixel}"/>.</returns>
|
/// <returns>A <see cref="PixelBlender{TPixel}"/>.</returns>
|
||||
internal virtual PixelBlender<TPixel> GetPixelBlender(PixelBlenderMode mode) |
internal PixelBlender<TPixel> GetPixelBlender(GraphicsOptions options) |
||||
{ |
{ |
||||
switch (mode) |
return this.GetPixelBlender(options.ColorBlendingMode, options.AlphaCompositionMode); |
||||
{ |
} |
||||
case PixelBlenderMode.Multiply: return DefaultPixelBlenders<TPixel>.Multiply.Instance; |
|
||||
case PixelBlenderMode.Add: return DefaultPixelBlenders<TPixel>.Add.Instance; |
/// <summary>
|
||||
case PixelBlenderMode.Subtract: return DefaultPixelBlenders<TPixel>.Subtract.Instance; |
/// Find an instance of the pixel blender.
|
||||
case PixelBlenderMode.Screen: return DefaultPixelBlenders<TPixel>.Screen.Instance; |
/// </summary>
|
||||
case PixelBlenderMode.Darken: return DefaultPixelBlenders<TPixel>.Darken.Instance; |
/// <param name="colorMode">The color blending mode to apply</param>
|
||||
case PixelBlenderMode.Lighten: return DefaultPixelBlenders<TPixel>.Lighten.Instance; |
/// <param name="alphaMode">The alpha composition mode to apply</param>
|
||||
case PixelBlenderMode.Overlay: return DefaultPixelBlenders<TPixel>.Overlay.Instance; |
/// <returns>A <see cref="PixelBlender{TPixel}"/>.</returns>
|
||||
case PixelBlenderMode.HardLight: return DefaultPixelBlenders<TPixel>.HardLight.Instance; |
internal virtual PixelBlender<TPixel> GetPixelBlender(PixelColorBlendingMode colorMode, PixelAlphaCompositionMode alphaMode) |
||||
case PixelBlenderMode.Src: return DefaultPixelBlenders<TPixel>.Src.Instance; |
{ |
||||
case PixelBlenderMode.Atop: return DefaultPixelBlenders<TPixel>.Atop.Instance; |
switch (alphaMode) |
||||
case PixelBlenderMode.Over: return DefaultPixelBlenders<TPixel>.Over.Instance; |
{ |
||||
case PixelBlenderMode.In: return DefaultPixelBlenders<TPixel>.In.Instance; |
case PixelAlphaCompositionMode.Clear: |
||||
case PixelBlenderMode.Out: return DefaultPixelBlenders<TPixel>.Out.Instance; |
switch (colorMode) |
||||
case PixelBlenderMode.Dest: return DefaultPixelBlenders<TPixel>.Dest.Instance; |
{ |
||||
case PixelBlenderMode.DestAtop: return DefaultPixelBlenders<TPixel>.DestAtop.Instance; |
case PixelColorBlendingMode.Multiply: return DefaultPixelBlenders<TPixel>.MultiplyClear.Instance; |
||||
case PixelBlenderMode.DestOver: return DefaultPixelBlenders<TPixel>.DestOver.Instance; |
case PixelColorBlendingMode.Add: return DefaultPixelBlenders<TPixel>.AddClear.Instance; |
||||
case PixelBlenderMode.DestIn: return DefaultPixelBlenders<TPixel>.DestIn.Instance; |
case PixelColorBlendingMode.Subtract: return DefaultPixelBlenders<TPixel>.SubtractClear.Instance; |
||||
case PixelBlenderMode.DestOut: return DefaultPixelBlenders<TPixel>.DestOut.Instance; |
case PixelColorBlendingMode.Screen: return DefaultPixelBlenders<TPixel>.ScreenClear.Instance; |
||||
case PixelBlenderMode.Clear: return DefaultPixelBlenders<TPixel>.Clear.Instance; |
case PixelColorBlendingMode.Darken: return DefaultPixelBlenders<TPixel>.DarkenClear.Instance; |
||||
case PixelBlenderMode.Xor: return DefaultPixelBlenders<TPixel>.Xor.Instance; |
case PixelColorBlendingMode.Lighten: return DefaultPixelBlenders<TPixel>.LightenClear.Instance; |
||||
|
case PixelColorBlendingMode.Overlay: return DefaultPixelBlenders<TPixel>.OverlayClear.Instance; |
||||
case PixelBlenderMode.Normal: |
case PixelColorBlendingMode.HardLight: return DefaultPixelBlenders<TPixel>.HardLightClear.Instance; |
||||
default: |
case PixelColorBlendingMode.Normal: |
||||
return DefaultPixelBlenders<TPixel>.Normal.Instance; |
default: return DefaultPixelBlenders<TPixel>.NormalClear.Instance; |
||||
} |
} |
||||
} |
|
||||
} |
case PixelAlphaCompositionMode.Xor: |
||||
|
switch (colorMode) |
||||
|
{ |
||||
|
case PixelColorBlendingMode.Multiply: return DefaultPixelBlenders<TPixel>.MultiplyXor.Instance; |
||||
|
case PixelColorBlendingMode.Add: return DefaultPixelBlenders<TPixel>.AddXor.Instance; |
||||
|
case PixelColorBlendingMode.Subtract: return DefaultPixelBlenders<TPixel>.SubtractXor.Instance; |
||||
|
case PixelColorBlendingMode.Screen: return DefaultPixelBlenders<TPixel>.ScreenXor.Instance; |
||||
|
case PixelColorBlendingMode.Darken: return DefaultPixelBlenders<TPixel>.DarkenXor.Instance; |
||||
|
case PixelColorBlendingMode.Lighten: return DefaultPixelBlenders<TPixel>.LightenXor.Instance; |
||||
|
case PixelColorBlendingMode.Overlay: return DefaultPixelBlenders<TPixel>.OverlayXor.Instance; |
||||
|
case PixelColorBlendingMode.HardLight: return DefaultPixelBlenders<TPixel>.HardLightXor.Instance; |
||||
|
case PixelColorBlendingMode.Normal: |
||||
|
default: return DefaultPixelBlenders<TPixel>.NormalXor.Instance; |
||||
|
} |
||||
|
|
||||
|
case PixelAlphaCompositionMode.Src: |
||||
|
switch (colorMode) |
||||
|
{ |
||||
|
case PixelColorBlendingMode.Multiply: return DefaultPixelBlenders<TPixel>.MultiplySrc.Instance; |
||||
|
case PixelColorBlendingMode.Add: return DefaultPixelBlenders<TPixel>.AddSrc.Instance; |
||||
|
case PixelColorBlendingMode.Subtract: return DefaultPixelBlenders<TPixel>.SubtractSrc.Instance; |
||||
|
case PixelColorBlendingMode.Screen: return DefaultPixelBlenders<TPixel>.ScreenSrc.Instance; |
||||
|
case PixelColorBlendingMode.Darken: return DefaultPixelBlenders<TPixel>.DarkenSrc.Instance; |
||||
|
case PixelColorBlendingMode.Lighten: return DefaultPixelBlenders<TPixel>.LightenSrc.Instance; |
||||
|
case PixelColorBlendingMode.Overlay: return DefaultPixelBlenders<TPixel>.OverlaySrc.Instance; |
||||
|
case PixelColorBlendingMode.HardLight: return DefaultPixelBlenders<TPixel>.HardLightSrc.Instance; |
||||
|
case PixelColorBlendingMode.Normal: |
||||
|
default: return DefaultPixelBlenders<TPixel>.NormalSrc.Instance; |
||||
|
} |
||||
|
|
||||
|
case PixelAlphaCompositionMode.SrcAtop: |
||||
|
switch (colorMode) |
||||
|
{ |
||||
|
case PixelColorBlendingMode.Multiply: return DefaultPixelBlenders<TPixel>.MultiplySrcAtop.Instance; |
||||
|
case PixelColorBlendingMode.Add: return DefaultPixelBlenders<TPixel>.AddSrcAtop.Instance; |
||||
|
case PixelColorBlendingMode.Subtract: return DefaultPixelBlenders<TPixel>.SubtractSrcAtop.Instance; |
||||
|
case PixelColorBlendingMode.Screen: return DefaultPixelBlenders<TPixel>.ScreenSrcAtop.Instance; |
||||
|
case PixelColorBlendingMode.Darken: return DefaultPixelBlenders<TPixel>.DarkenSrcAtop.Instance; |
||||
|
case PixelColorBlendingMode.Lighten: return DefaultPixelBlenders<TPixel>.LightenSrcAtop.Instance; |
||||
|
case PixelColorBlendingMode.Overlay: return DefaultPixelBlenders<TPixel>.OverlaySrcAtop.Instance; |
||||
|
case PixelColorBlendingMode.HardLight: return DefaultPixelBlenders<TPixel>.HardLightSrcAtop.Instance; |
||||
|
case PixelColorBlendingMode.Normal: |
||||
|
default: return DefaultPixelBlenders<TPixel>.NormalSrcAtop.Instance; |
||||
|
} |
||||
|
|
||||
|
case PixelAlphaCompositionMode.SrcIn: |
||||
|
switch (colorMode) |
||||
|
{ |
||||
|
case PixelColorBlendingMode.Multiply: return DefaultPixelBlenders<TPixel>.MultiplySrcIn.Instance; |
||||
|
case PixelColorBlendingMode.Add: return DefaultPixelBlenders<TPixel>.AddSrcIn.Instance; |
||||
|
case PixelColorBlendingMode.Subtract: return DefaultPixelBlenders<TPixel>.SubtractSrcIn.Instance; |
||||
|
case PixelColorBlendingMode.Screen: return DefaultPixelBlenders<TPixel>.ScreenSrcIn.Instance; |
||||
|
case PixelColorBlendingMode.Darken: return DefaultPixelBlenders<TPixel>.DarkenSrcIn.Instance; |
||||
|
case PixelColorBlendingMode.Lighten: return DefaultPixelBlenders<TPixel>.LightenSrcIn.Instance; |
||||
|
case PixelColorBlendingMode.Overlay: return DefaultPixelBlenders<TPixel>.OverlaySrcIn.Instance; |
||||
|
case PixelColorBlendingMode.HardLight: return DefaultPixelBlenders<TPixel>.HardLightSrcIn.Instance; |
||||
|
case PixelColorBlendingMode.Normal: |
||||
|
default: return DefaultPixelBlenders<TPixel>.NormalSrcIn.Instance; |
||||
|
} |
||||
|
|
||||
|
case PixelAlphaCompositionMode.SrcOut: |
||||
|
switch (colorMode) |
||||
|
{ |
||||
|
case PixelColorBlendingMode.Multiply: return DefaultPixelBlenders<TPixel>.MultiplySrcOut.Instance; |
||||
|
case PixelColorBlendingMode.Add: return DefaultPixelBlenders<TPixel>.AddSrcOut.Instance; |
||||
|
case PixelColorBlendingMode.Subtract: return DefaultPixelBlenders<TPixel>.SubtractSrcOut.Instance; |
||||
|
case PixelColorBlendingMode.Screen: return DefaultPixelBlenders<TPixel>.ScreenSrcOut.Instance; |
||||
|
case PixelColorBlendingMode.Darken: return DefaultPixelBlenders<TPixel>.DarkenSrcOut.Instance; |
||||
|
case PixelColorBlendingMode.Lighten: return DefaultPixelBlenders<TPixel>.LightenSrcOut.Instance; |
||||
|
case PixelColorBlendingMode.Overlay: return DefaultPixelBlenders<TPixel>.OverlaySrcOut.Instance; |
||||
|
case PixelColorBlendingMode.HardLight: return DefaultPixelBlenders<TPixel>.HardLightSrcOut.Instance; |
||||
|
case PixelColorBlendingMode.Normal: |
||||
|
default: return DefaultPixelBlenders<TPixel>.NormalSrcOut.Instance; |
||||
|
} |
||||
|
|
||||
|
case PixelAlphaCompositionMode.Dest: |
||||
|
switch (colorMode) |
||||
|
{ |
||||
|
case PixelColorBlendingMode.Multiply: return DefaultPixelBlenders<TPixel>.MultiplyDest.Instance; |
||||
|
case PixelColorBlendingMode.Add: return DefaultPixelBlenders<TPixel>.AddDest.Instance; |
||||
|
case PixelColorBlendingMode.Subtract: return DefaultPixelBlenders<TPixel>.SubtractDest.Instance; |
||||
|
case PixelColorBlendingMode.Screen: return DefaultPixelBlenders<TPixel>.ScreenDest.Instance; |
||||
|
case PixelColorBlendingMode.Darken: return DefaultPixelBlenders<TPixel>.DarkenDest.Instance; |
||||
|
case PixelColorBlendingMode.Lighten: return DefaultPixelBlenders<TPixel>.LightenDest.Instance; |
||||
|
case PixelColorBlendingMode.Overlay: return DefaultPixelBlenders<TPixel>.OverlayDest.Instance; |
||||
|
case PixelColorBlendingMode.HardLight: return DefaultPixelBlenders<TPixel>.HardLightDest.Instance; |
||||
|
case PixelColorBlendingMode.Normal: |
||||
|
default: return DefaultPixelBlenders<TPixel>.NormalDest.Instance; |
||||
|
} |
||||
|
|
||||
|
case PixelAlphaCompositionMode.DestAtop: |
||||
|
switch (colorMode) |
||||
|
{ |
||||
|
case PixelColorBlendingMode.Multiply: return DefaultPixelBlenders<TPixel>.MultiplyDestAtop.Instance; |
||||
|
case PixelColorBlendingMode.Add: return DefaultPixelBlenders<TPixel>.AddDestAtop.Instance; |
||||
|
case PixelColorBlendingMode.Subtract: return DefaultPixelBlenders<TPixel>.SubtractDestAtop.Instance; |
||||
|
case PixelColorBlendingMode.Screen: return DefaultPixelBlenders<TPixel>.ScreenDestAtop.Instance; |
||||
|
case PixelColorBlendingMode.Darken: return DefaultPixelBlenders<TPixel>.DarkenDestAtop.Instance; |
||||
|
case PixelColorBlendingMode.Lighten: return DefaultPixelBlenders<TPixel>.LightenDestAtop.Instance; |
||||
|
case PixelColorBlendingMode.Overlay: return DefaultPixelBlenders<TPixel>.OverlayDestAtop.Instance; |
||||
|
case PixelColorBlendingMode.HardLight: return DefaultPixelBlenders<TPixel>.HardLightDestAtop.Instance; |
||||
|
case PixelColorBlendingMode.Normal: |
||||
|
default: return DefaultPixelBlenders<TPixel>.NormalDestAtop.Instance; |
||||
|
} |
||||
|
|
||||
|
case PixelAlphaCompositionMode.DestIn: |
||||
|
switch (colorMode) |
||||
|
{ |
||||
|
case PixelColorBlendingMode.Multiply: return DefaultPixelBlenders<TPixel>.MultiplyDestIn.Instance; |
||||
|
case PixelColorBlendingMode.Add: return DefaultPixelBlenders<TPixel>.AddDestIn.Instance; |
||||
|
case PixelColorBlendingMode.Subtract: return DefaultPixelBlenders<TPixel>.SubtractDestIn.Instance; |
||||
|
case PixelColorBlendingMode.Screen: return DefaultPixelBlenders<TPixel>.ScreenDestIn.Instance; |
||||
|
case PixelColorBlendingMode.Darken: return DefaultPixelBlenders<TPixel>.DarkenDestIn.Instance; |
||||
|
case PixelColorBlendingMode.Lighten: return DefaultPixelBlenders<TPixel>.LightenDestIn.Instance; |
||||
|
case PixelColorBlendingMode.Overlay: return DefaultPixelBlenders<TPixel>.OverlayDestIn.Instance; |
||||
|
case PixelColorBlendingMode.HardLight: return DefaultPixelBlenders<TPixel>.HardLightDestIn.Instance; |
||||
|
case PixelColorBlendingMode.Normal: |
||||
|
default: return DefaultPixelBlenders<TPixel>.NormalDestIn.Instance; |
||||
|
} |
||||
|
|
||||
|
case PixelAlphaCompositionMode.DestOut: |
||||
|
switch (colorMode) |
||||
|
{ |
||||
|
case PixelColorBlendingMode.Multiply: return DefaultPixelBlenders<TPixel>.MultiplyDestOut.Instance; |
||||
|
case PixelColorBlendingMode.Add: return DefaultPixelBlenders<TPixel>.AddDestOut.Instance; |
||||
|
case PixelColorBlendingMode.Subtract: return DefaultPixelBlenders<TPixel>.SubtractDestOut.Instance; |
||||
|
case PixelColorBlendingMode.Screen: return DefaultPixelBlenders<TPixel>.ScreenDestOut.Instance; |
||||
|
case PixelColorBlendingMode.Darken: return DefaultPixelBlenders<TPixel>.DarkenDestOut.Instance; |
||||
|
case PixelColorBlendingMode.Lighten: return DefaultPixelBlenders<TPixel>.LightenDestOut.Instance; |
||||
|
case PixelColorBlendingMode.Overlay: return DefaultPixelBlenders<TPixel>.OverlayDestOut.Instance; |
||||
|
case PixelColorBlendingMode.HardLight: return DefaultPixelBlenders<TPixel>.HardLightDestOut.Instance; |
||||
|
case PixelColorBlendingMode.Normal: |
||||
|
default: return DefaultPixelBlenders<TPixel>.NormalDestOut.Instance; |
||||
|
} |
||||
|
|
||||
|
case PixelAlphaCompositionMode.DestOver: |
||||
|
switch (colorMode) |
||||
|
{ |
||||
|
case PixelColorBlendingMode.Multiply: return DefaultPixelBlenders<TPixel>.MultiplyDestOver.Instance; |
||||
|
case PixelColorBlendingMode.Add: return DefaultPixelBlenders<TPixel>.AddDestOver.Instance; |
||||
|
case PixelColorBlendingMode.Subtract: return DefaultPixelBlenders<TPixel>.SubtractDestOver.Instance; |
||||
|
case PixelColorBlendingMode.Screen: return DefaultPixelBlenders<TPixel>.ScreenDestOver.Instance; |
||||
|
case PixelColorBlendingMode.Darken: return DefaultPixelBlenders<TPixel>.DarkenDestOver.Instance; |
||||
|
case PixelColorBlendingMode.Lighten: return DefaultPixelBlenders<TPixel>.LightenDestOver.Instance; |
||||
|
case PixelColorBlendingMode.Overlay: return DefaultPixelBlenders<TPixel>.OverlayDestOver.Instance; |
||||
|
case PixelColorBlendingMode.HardLight: return DefaultPixelBlenders<TPixel>.HardLightDestOver.Instance; |
||||
|
case PixelColorBlendingMode.Normal: |
||||
|
default: return DefaultPixelBlenders<TPixel>.NormalDestOver.Instance; |
||||
|
} |
||||
|
|
||||
|
case PixelAlphaCompositionMode.SrcOver: |
||||
|
default: |
||||
|
switch (colorMode) |
||||
|
{ |
||||
|
case PixelColorBlendingMode.Multiply: return DefaultPixelBlenders<TPixel>.MultiplySrcOver.Instance; |
||||
|
case PixelColorBlendingMode.Add: return DefaultPixelBlenders<TPixel>.AddSrcOver.Instance; |
||||
|
case PixelColorBlendingMode.Subtract: return DefaultPixelBlenders<TPixel>.SubtractSrcOver.Instance; |
||||
|
case PixelColorBlendingMode.Screen: return DefaultPixelBlenders<TPixel>.ScreenSrcOver.Instance; |
||||
|
case PixelColorBlendingMode.Darken: return DefaultPixelBlenders<TPixel>.DarkenSrcOver.Instance; |
||||
|
case PixelColorBlendingMode.Lighten: return DefaultPixelBlenders<TPixel>.LightenSrcOver.Instance; |
||||
|
case PixelColorBlendingMode.Overlay: return DefaultPixelBlenders<TPixel>.OverlaySrcOver.Instance; |
||||
|
case PixelColorBlendingMode.HardLight: return DefaultPixelBlenders<TPixel>.HardLightSrcOver.Instance; |
||||
|
case PixelColorBlendingMode.Normal: |
||||
|
default: return DefaultPixelBlenders<TPixel>.NormalSrcOver.Instance; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
} |
} |
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue