1+ // Copyright (c) Six Labors and contributors.
2+ // Licensed under the Apache License, Version 2.0.
3+ using System ;
4+ using System . Collections . Generic ;
5+ using System . Linq ;
6+ using SixLabors . ImageSharp . PixelFormats ;
7+ using SixLabors . ImageSharp . Processing ;
8+ using SixLabors . ImageSharp . Processing . Drawing ;
9+ using SixLabors . ImageSharp . Tests . TestUtilities . ImageComparison ;
10+ using SixLabors . Primitives ;
11+ using Xunit ;
12+
13+ // ReSharper disable InconsistentNaming
14+ namespace SixLabors . ImageSharp . Tests . Drawing
15+ {
16+ [ GroupOutput ( "Drawing" ) ]
17+ public class SolidFillBlendedShapesTests
18+ {
19+ public static IEnumerable < object [ ] > modes =
20+ ( ( PixelBlenderMode [ ] ) Enum . GetValues ( typeof ( PixelBlenderMode ) ) ) . Select ( x => new object [ ] { x } ) ;
21+
22+ [ Theory ]
23+ [ WithBlankImages ( nameof ( modes ) , 250 , 250 , PixelTypes . Rgba32 ) ]
24+ public void _1DarkBlueRect_2BlendHotPinkRect < TPixel > (
25+ TestImageProvider < TPixel > provider ,
26+ PixelBlenderMode mode )
27+ where TPixel : struct , IPixel < TPixel >
28+ {
29+ using ( Image < TPixel > img = provider . GetImage ( ) )
30+ {
31+ int scaleX = img . Width / 100 ;
32+ int scaleY = img . Height / 100 ;
33+ img . Mutate (
34+ x => x . Fill (
35+ NamedColors < TPixel > . DarkBlue ,
36+ new Rectangle ( 0 * scaleX , 40 * scaleY , 100 * scaleX , 20 * scaleY )
37+ )
38+ . Fill ( new GraphicsOptions ( true ) { BlenderMode = mode } ,
39+ NamedColors < TPixel > . HotPink ,
40+ new Rectangle ( 20 * scaleX , 0 * scaleY , 30 * scaleX , 100 * scaleY ) )
41+ ) ;
42+
43+ VerifyImage ( provider , mode , img ) ;
44+ }
45+ }
46+
47+ [ Theory ]
48+ [ WithBlankImages ( nameof ( modes ) , 250 , 250 , PixelTypes . Rgba32 ) ]
49+ public void _1DarkBlueRect_2BlendHotPinkRect_3BlendTransparentEllipse < TPixel > (
50+ TestImageProvider < TPixel > provider ,
51+ PixelBlenderMode mode )
52+ where TPixel : struct , IPixel < TPixel >
53+ {
54+ using ( Image < TPixel > img = provider . GetImage ( ) )
55+ {
56+ int scaleX = img . Width / 100 ;
57+ int scaleY = img . Height / 100 ;
58+ img . Mutate (
59+ x => x . Fill (
60+ NamedColors < TPixel > . DarkBlue ,
61+ new Rectangle ( 0 * scaleX , 40 * scaleY , 100 * scaleX , 20 * scaleY ) ) ) ;
62+ img . Mutate (
63+ x => x . Fill (
64+ new GraphicsOptions ( true ) { BlenderMode = mode } ,
65+ NamedColors < TPixel > . HotPink ,
66+ new Rectangle ( 20 * scaleX , 0 * scaleY , 30 * scaleX , 100 * scaleY ) ) ) ;
67+ img . Mutate (
68+ x => x . Fill (
69+ new GraphicsOptions ( true ) { BlenderMode = mode } ,
70+ NamedColors < TPixel > . Transparent ,
71+ new Shapes . EllipsePolygon ( 40 * scaleX , 50 * scaleY , 50 * scaleX , 50 * scaleY ) )
72+ ) ;
73+
74+ VerifyImage ( provider , mode , img ) ;
75+ }
76+ }
77+
78+ [ Theory ]
79+ [ WithBlankImages ( nameof ( modes ) , 250 , 250 , PixelTypes . Rgba32 ) ]
80+ public void _1DarkBlueRect_2BlendHotPinkRect_3BlendSemiTransparentRedEllipse < TPixel > (
81+ TestImageProvider < TPixel > provider ,
82+ PixelBlenderMode mode )
83+ where TPixel : struct , IPixel < TPixel >
84+ {
85+ using ( Image < TPixel > img = provider . GetImage ( ) )
86+ {
87+ int scaleX = ( img . Width / 100 ) ;
88+ int scaleY = ( img . Height / 100 ) ;
89+ img . Mutate (
90+ x => x . Fill (
91+ NamedColors < TPixel > . DarkBlue ,
92+ new Rectangle ( 0 * scaleX , 40 , 100 * scaleX , 20 * scaleY ) ) ) ;
93+ img . Mutate (
94+ x => x . Fill (
95+ new GraphicsOptions ( true ) { BlenderMode = mode } ,
96+ NamedColors < TPixel > . HotPink ,
97+ new Rectangle ( 20 * scaleX , 0 , 30 * scaleX , 100 * scaleY ) ) ) ;
98+ var c = NamedColors < TPixel > . Red . ToVector4 ( ) ;
99+ c . W *= 0.5f ;
100+ var pixel = default ( TPixel ) ;
101+ pixel . PackFromVector4 ( c ) ;
102+
103+ img . Mutate (
104+ x => x . Fill (
105+ new GraphicsOptions ( true ) { BlenderMode = mode } ,
106+ pixel ,
107+ new Shapes . EllipsePolygon ( 40 * scaleX , 50 * scaleY , 50 * scaleX , 50 * scaleY ) )
108+ ) ;
109+
110+ VerifyImage ( provider , mode , img ) ; ;
111+ }
112+ }
113+
114+ [ Theory ]
115+ [ WithBlankImages ( nameof ( modes ) , 250 , 250 , PixelTypes . Rgba32 ) ]
116+ public void _1DarkBlueRect_2BlendBlackEllipse < TPixel > ( TestImageProvider < TPixel > provider , PixelBlenderMode mode )
117+ where TPixel : struct , IPixel < TPixel >
118+ {
119+ using ( Image < TPixel > img = provider . GetImage ( ) )
120+ {
121+ int scaleX = ( img . Width / 100 ) ;
122+ int scaleY = ( img . Height / 100 ) ;
123+ img . Mutate (
124+ x => x . Fill (
125+ NamedColors < TPixel > . DarkBlue ,
126+ new Rectangle ( 0 * scaleX , 40 * scaleY , 100 * scaleX , 20 * scaleY ) ) ) ;
127+ img . Mutate (
128+ x => x . Fill (
129+ new GraphicsOptions ( true ) { BlenderMode = mode } ,
130+ NamedColors < TPixel > . Black ,
131+ new Shapes . EllipsePolygon ( 40 * scaleX , 50 * scaleY , 50 * scaleX , 50 * scaleY ) ) ) ;
132+
133+ VerifyImage ( provider , mode , img ) ;
134+ }
135+ }
136+
137+ private static void VerifyImage < TPixel > ( TestImageProvider < TPixel > provider , PixelBlenderMode mode , Image < TPixel > img )
138+ where TPixel : struct , IPixel < TPixel >
139+ {
140+ img . DebugSave (
141+ provider ,
142+ new { mode } ,
143+ appendPixelTypeToFileName : false ,
144+ appendSourceFileOrDescription : false ) ;
145+
146+ var comparer = ImageComparer . TolerantPercentage ( 0.01f , 3 ) ;
147+ img . CompareFirstFrameToReferenceOutput ( comparer ,
148+ provider ,
149+ new { mode } ,
150+ appendPixelTypeToFileName : false ,
151+ appendSourceFileOrDescription : false ) ;
152+ }
153+ }
154+ }
0 commit comments