// Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. using System; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing; using SixLabors.ImageSharp.Processing.Drawing; using SixLabors.ImageSharp.Processing.Drawing.Brushes.GradientBrushes; using Xunit; namespace SixLabors.ImageSharp.Tests.Drawing { [GroupOutput("Drawing/GradientBrushes")] public class FillEllipticGradientBrushTests : FileTestBase { [Theory] [WithBlankImages(10, 10, PixelTypes.Rgba32)] public void EllipticGradientBrushWithEqualColorsAndReturnsUnicolorImage( TestImageProvider provider) where TPixel : struct, IPixel { TPixel red = NamedColors.Red; using (Image image = provider.GetImage()) { EllipticGradientBrush unicolorLinearGradientBrush = new EllipticGradientBrush( new SixLabors.Primitives.Point(0, 0), new SixLabors.Primitives.Point(10, 0), 1.0f, GradientRepetitionMode.None, new ColorStop(0, red), new ColorStop(1, red)); image.Mutate(x => x.Fill(unicolorLinearGradientBrush)); image.DebugSave(provider); using (PixelAccessor sourcePixels = image.Lock()) { Assert.Equal(red, sourcePixels[0, 0]); Assert.Equal(red, sourcePixels[9, 9]); Assert.Equal(red, sourcePixels[5, 5]); Assert.Equal(red, sourcePixels[3, 8]); } image.CompareToReferenceOutput(provider); } } [Theory] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.1)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.4)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.8)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 1.0)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 1.2)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 1.6)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 2.0)] public void EllipticGradientBrushProducesAxisParallelEllipsesWithDifferentRatio( TestImageProvider provider, float ratio) where TPixel : struct, IPixel { TPixel yellow = NamedColors.Yellow; TPixel red = NamedColors.Red; TPixel black = NamedColors.Black; using (var image = provider.GetImage()) { EllipticGradientBrush unicolorLinearGradientBrush = new EllipticGradientBrush( new SixLabors.Primitives.Point(image.Width / 2, image.Height / 2), new SixLabors.Primitives.Point(image.Width / 2, (image.Width * 3) / 2), ratio, GradientRepetitionMode.None, new ColorStop(0, yellow), new ColorStop(1, red), new ColorStop(1, black)); image.Mutate(x => x.Fill(unicolorLinearGradientBrush)); image.DebugSave(provider, ratio); image.CompareToReferenceOutput(provider, ratio); } } [Theory] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.1, 0)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.4, 0)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.8, 0)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 1.0, 0)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.1, 45)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.4, 45)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.8, 45)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 1.0, 45)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.1, 90)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.4, 90)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.8, 90)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 1.0, 90)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.1, 30)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.4, 30)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.8, 30)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 1.0, 30)] public void EllipticGradientBrushProducesRotatedEllipsesWithDifferentRatio( TestImageProvider provider, float ratio, float rotationInDegree) where TPixel: struct, IPixel { string variant = $"{ratio}at{rotationInDegree}°"; using (var image = provider.GetImage()) { TPixel yellow = NamedColors.Yellow; TPixel red = NamedColors.Red; TPixel black = NamedColors.Black; var center = new SixLabors.Primitives.Point(image.Width / 2, image.Height / 2); var rotation = (Math.PI * rotationInDegree) / 180.0; var cos = Math.Cos(rotation); var sin = Math.Sin(rotation); int axisX = (int)((center.X * cos) - (center.Y * sin)); int axisY = (int)((center.X * sin) + (center.Y * cos)); EllipticGradientBrush unicolorLinearGradientBrush = new EllipticGradientBrush( center, new SixLabors.Primitives.Point(axisX, axisY), ratio, GradientRepetitionMode.None, new ColorStop(0, yellow), new ColorStop(1, red), new ColorStop(1, black)); image.Mutate(x => x.Fill(unicolorLinearGradientBrush)); image.DebugSave(provider, variant); image.CompareToReferenceOutput(provider, variant); } } } }