mirror of https://github.com/SixLabors/ImageSharp
67 changed files with 1150 additions and 742 deletions
@ -0,0 +1,53 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System.Numerics; |
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
|
|||
namespace SixLabors.ImageSharp |
|||
{ |
|||
/// <summary>
|
|||
/// Extensions methods fpor the <see cref="GraphicsOptions"/> class.
|
|||
/// </summary>
|
|||
internal static class GraphicsOptionsExtensions |
|||
{ |
|||
/// <summary>
|
|||
/// Evaluates if a given SOURCE color can completely replace a BACKDROP color given the current blending and composition settings.
|
|||
/// </summary>
|
|||
/// <param name="options">The graphics options.</param>
|
|||
/// <param name="color">The source color.</param>
|
|||
/// <returns>true if the color can be considered opaque</returns>
|
|||
/// <remarks>
|
|||
/// Blending and composition is an expensive operation, in some cases, like
|
|||
/// filling with a solid color, the blending can be avoided by a plain color replacement.
|
|||
/// This method can be useful for such processors to select the fast path.
|
|||
/// </remarks>
|
|||
public static bool IsOpaqueColorWithoutBlending(this GraphicsOptions options, Color color) |
|||
{ |
|||
if (options.ColorBlendingMode != PixelColorBlendingMode.Normal) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
if (options.AlphaCompositionMode != PixelAlphaCompositionMode.SrcOver |
|||
&& options.AlphaCompositionMode != PixelAlphaCompositionMode.Src) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
const float Opaque = 1F; |
|||
|
|||
if (options.BlendPercentage != Opaque) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
if (((Vector4)color).W != Opaque) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
return true; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System.Runtime.CompilerServices; |
|||
|
|||
namespace SixLabors.ImageSharp |
|||
{ |
|||
/// <summary>
|
|||
/// Utility methods for numeric primitives.
|
|||
/// </summary>
|
|||
internal static class NumberUtils |
|||
{ |
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public static float ClampFloat(float value, float min, float max) |
|||
{ |
|||
if (value >= max) |
|||
{ |
|||
return max; |
|||
} |
|||
|
|||
if (value <= min) |
|||
{ |
|||
return min; |
|||
} |
|||
|
|||
return value; |
|||
} |
|||
} |
|||
} |
|||
@ -1,21 +1,100 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
using SixLabors.ImageSharp.Tests.TestUtilities; |
|||
using Xunit; |
|||
|
|||
namespace SixLabors.ImageSharp.Tests |
|||
{ |
|||
public class GraphicsOptionsTests |
|||
{ |
|||
private static readonly GraphicsOptionsComparer graphicsOptionsComparer = new GraphicsOptionsComparer(); |
|||
private readonly GraphicsOptions newGraphicsOptions = new GraphicsOptions(); |
|||
private readonly GraphicsOptions cloneGraphicsOptions = new GraphicsOptions().DeepClone(); |
|||
|
|||
[Fact] |
|||
public void CloneGraphicsOptionsIsNotNull() => Assert.True(this.cloneGraphicsOptions != null); |
|||
|
|||
[Fact] |
|||
public void DefaultGraphicsOptionsAntialias() |
|||
{ |
|||
Assert.True(this.newGraphicsOptions.Antialias); |
|||
Assert.True(this.cloneGraphicsOptions.Antialias); |
|||
} |
|||
|
|||
[Fact] |
|||
public void DefaultGraphicsOptionsAntialiasSuppixelDepth() |
|||
{ |
|||
const int Expected = 16; |
|||
Assert.Equal(Expected, this.newGraphicsOptions.AntialiasSubpixelDepth); |
|||
Assert.Equal(Expected, this.cloneGraphicsOptions.AntialiasSubpixelDepth); |
|||
} |
|||
|
|||
[Fact] |
|||
public void DefaultGraphicsOptionsBlendPercentage() |
|||
{ |
|||
const float Expected = 1F; |
|||
Assert.Equal(Expected, this.newGraphicsOptions.BlendPercentage); |
|||
Assert.Equal(Expected, this.cloneGraphicsOptions.BlendPercentage); |
|||
} |
|||
|
|||
[Fact] |
|||
public void DefaultGraphicsOptionsColorBlendingMode() |
|||
{ |
|||
const PixelColorBlendingMode Expected = PixelColorBlendingMode.Normal; |
|||
Assert.Equal(Expected, this.newGraphicsOptions.ColorBlendingMode); |
|||
Assert.Equal(Expected, this.cloneGraphicsOptions.ColorBlendingMode); |
|||
} |
|||
|
|||
[Fact] |
|||
public void DefaultGraphicsOptionsAlphaCompositionMode() |
|||
{ |
|||
const PixelAlphaCompositionMode Expected = PixelAlphaCompositionMode.SrcOver; |
|||
Assert.Equal(Expected, this.newGraphicsOptions.AlphaCompositionMode); |
|||
Assert.Equal(Expected, this.cloneGraphicsOptions.AlphaCompositionMode); |
|||
} |
|||
|
|||
[Fact] |
|||
public void NonDefaultClone() |
|||
{ |
|||
var expected = new GraphicsOptions |
|||
{ |
|||
AlphaCompositionMode = PixelAlphaCompositionMode.DestAtop, |
|||
Antialias = false, |
|||
AntialiasSubpixelDepth = 23, |
|||
BlendPercentage = .25F, |
|||
ColorBlendingMode = PixelColorBlendingMode.HardLight, |
|||
}; |
|||
|
|||
GraphicsOptions actual = expected.DeepClone(); |
|||
|
|||
Assert.Equal(expected, actual, graphicsOptionsComparer); |
|||
} |
|||
|
|||
[Fact] |
|||
public void CloneIsDeep() |
|||
{ |
|||
var expected = new GraphicsOptions(); |
|||
GraphicsOptions actual = expected.DeepClone(); |
|||
|
|||
actual.AlphaCompositionMode = PixelAlphaCompositionMode.DestAtop; |
|||
actual.Antialias = false; |
|||
actual.AntialiasSubpixelDepth = 23; |
|||
actual.BlendPercentage = .25F; |
|||
actual.ColorBlendingMode = PixelColorBlendingMode.HardLight; |
|||
|
|||
Assert.NotEqual(expected, actual, graphicsOptionsComparer); |
|||
} |
|||
|
|||
[Fact] |
|||
public void IsOpaqueColor() |
|||
{ |
|||
Assert.True(new GraphicsOptions(true).IsOpaqueColorWithoutBlending(Rgba32.Red)); |
|||
Assert.False(new GraphicsOptions(true, 0.5f).IsOpaqueColorWithoutBlending(Rgba32.Red)); |
|||
Assert.False(new GraphicsOptions(true).IsOpaqueColorWithoutBlending(Rgba32.Transparent)); |
|||
Assert.False(new GraphicsOptions(true, PixelColorBlendingMode.Lighten, 1).IsOpaqueColorWithoutBlending(Rgba32.Red)); |
|||
Assert.False(new GraphicsOptions(true, PixelColorBlendingMode.Normal, PixelAlphaCompositionMode.DestOver, 1).IsOpaqueColorWithoutBlending(Rgba32.Red)); |
|||
Assert.True(new GraphicsOptions().IsOpaqueColorWithoutBlending(Rgba32.Red)); |
|||
Assert.False(new GraphicsOptions { BlendPercentage = .5F }.IsOpaqueColorWithoutBlending(Rgba32.Red)); |
|||
Assert.False(new GraphicsOptions().IsOpaqueColorWithoutBlending(Rgba32.Transparent)); |
|||
Assert.False(new GraphicsOptions { ColorBlendingMode = PixelColorBlendingMode.Lighten, BlendPercentage = 1F }.IsOpaqueColorWithoutBlending(Rgba32.Red)); |
|||
Assert.False(new GraphicsOptions { ColorBlendingMode = PixelColorBlendingMode.Normal, AlphaCompositionMode = PixelAlphaCompositionMode.DestOver, BlendPercentage = 1f }.IsOpaqueColorWithoutBlending(Rgba32.Red)); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,21 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System.Collections.Generic; |
|||
|
|||
namespace SixLabors.ImageSharp.Tests.TestUtilities |
|||
{ |
|||
public class GraphicsOptionsComparer : IEqualityComparer<GraphicsOptions> |
|||
{ |
|||
public bool Equals(GraphicsOptions x, GraphicsOptions y) |
|||
{ |
|||
return x.AlphaCompositionMode == y.AlphaCompositionMode |
|||
&& x.Antialias == y.Antialias |
|||
&& x.AntialiasSubpixelDepth == y.AntialiasSubpixelDepth |
|||
&& x.BlendPercentage == y.BlendPercentage |
|||
&& x.ColorBlendingMode == y.ColorBlendingMode; |
|||
} |
|||
|
|||
public int GetHashCode(GraphicsOptions obj) => obj.GetHashCode(); |
|||
} |
|||
} |
|||
Loading…
Reference in new issue