* roottypes.cs: Rename from tree.cs.
[mono.git] / mcs / class / System.Drawing / System.Drawing.Drawing2D / PathGradientBrush.cs
1 //
2 // System.Drawing.Drawing2D.PathGradientBrush.cs
3 //
4 // Authors:
5 //   Dennis Hayes (dennish@Raytek.com)
6 //   Andreas Nahr (ClassDevelopment@A-SoftTech.com)
7 //   Ravindra (rkumar@novell.com)
8 //
9 // Copyright (C) 2002/3 Ximian, Inc. http://www.ximian.com
10 // Copyright (C) 2004,2006 Novell, Inc (http://www.novell.com)
11 //
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
19 // 
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 // 
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 //
31
32 using System.ComponentModel;
33
34 namespace System.Drawing.Drawing2D {
35
36         [MonoTODO ("libgdiplus/cairo doesn't support path gradients - unless it can be mapped to a radial gradient")]
37         public sealed class PathGradientBrush : Brush {
38
39                 internal PathGradientBrush (IntPtr native) : base (native)
40                 {
41                 }
42
43                 public PathGradientBrush (GraphicsPath path)
44                 {
45                         if (path == null)
46                                 throw new ArgumentNullException ("path");
47
48                         Status status = GDIPlus.GdipCreatePathGradientFromPath (path.NativeObject, out nativeObject);
49                         GDIPlus.CheckStatus (status);
50                 }
51
52                 public PathGradientBrush (Point [] points) : this (points, WrapMode.Clamp)
53                 {
54                 }
55
56                 public PathGradientBrush (PointF [] points) : this (points, WrapMode.Clamp)
57                 {
58                 }
59
60                 public PathGradientBrush (Point [] points, WrapMode wrapMode)
61                 {
62                         if (points == null)
63                                 throw new ArgumentNullException ("points");
64                         if ((wrapMode < WrapMode.Tile) || (wrapMode > WrapMode.Clamp))
65                                 throw new InvalidEnumArgumentException ("WrapMode");
66
67                         Status status = GDIPlus.GdipCreatePathGradientI (points, points.Length, wrapMode, out nativeObject);
68                         GDIPlus.CheckStatus (status);
69                 }
70
71                 public PathGradientBrush (PointF [] points, WrapMode wrapMode)
72                 {
73                         if (points == null)
74                                 throw new ArgumentNullException ("points");
75                         if ((wrapMode < WrapMode.Tile) || (wrapMode > WrapMode.Clamp))
76                                 throw new InvalidEnumArgumentException ("WrapMode");
77
78                         Status status = GDIPlus.GdipCreatePathGradient (points, points.Length, wrapMode, out nativeObject);
79                         GDIPlus.CheckStatus (status);
80                 }
81
82                 // Properties
83
84                 public Blend Blend {
85                         get {
86                                 int count;
87                                 Status status = GDIPlus.GdipGetPathGradientBlendCount (nativeObject, out count);
88                                 GDIPlus.CheckStatus (status);
89                                 float [] factors = new float [count];
90                                 float [] positions = new float [count];
91                                 status = GDIPlus.GdipGetPathGradientBlend (nativeObject, factors, positions, count);
92                                 GDIPlus.CheckStatus (status);
93
94                                 Blend blend = new Blend ();
95                                 blend.Factors = factors;
96                                 blend.Positions = positions;
97
98                                 return blend;
99                         }
100                         set {
101                                 int count;
102                                 float [] factors = value.Factors;
103                                 float [] positions = value.Positions;
104                                 count = factors.Length;
105
106                                 if (count == 0 || positions.Length == 0)
107                                         throw new ArgumentException ("Invalid Blend object. It should have at least 2 elements in each of the factors and positions arrays.");
108
109                                 if (count != positions.Length)
110                                         throw new ArgumentException ("Invalid Blend object. It should contain the same number of factors and positions values.");
111
112                                 if (positions [0] != 0.0F)
113                                         throw new ArgumentException ("Invalid Blend object. The positions array must have 0.0 as its first element.");
114
115                                 if (positions [count - 1] != 1.0F)
116                                         throw new ArgumentException ("Invalid Blend object. The positions array must have 1.0 as its last element.");
117
118                                 Status status = GDIPlus.GdipSetPathGradientBlend (nativeObject, factors, positions, count);
119                                 GDIPlus.CheckStatus (status);
120                         }
121                 }
122
123                 public Color CenterColor {
124                         get {
125                                 int centerColor;
126                                 Status status = GDIPlus.GdipGetPathGradientCenterColor (nativeObject, out centerColor);
127                                 GDIPlus.CheckStatus (status);
128                                 return Color.FromArgb (centerColor);
129                         }
130                         set {
131                                 Status status = GDIPlus.GdipSetPathGradientCenterColor (nativeObject, value.ToArgb ());
132                                 GDIPlus.CheckStatus (status);
133                         }
134                 }
135
136                 public PointF CenterPoint {
137                         get {
138                                 PointF center;
139                                 Status status = GDIPlus.GdipGetPathGradientCenterPoint (nativeObject, out center);
140                                 GDIPlus.CheckStatus (status);
141
142                                 return center;
143                         }
144                         set {
145                                 PointF center = value;
146                                 Status status = GDIPlus.GdipSetPathGradientCenterPoint (nativeObject, ref center);
147                                 GDIPlus.CheckStatus (status);
148                         }
149                 }
150
151                 public PointF FocusScales {
152                         get {
153                                 float xScale;
154                                 float yScale;
155                                 Status status = GDIPlus.GdipGetPathGradientFocusScales (nativeObject, out xScale, out yScale);
156                                 GDIPlus.CheckStatus (status);
157
158                                 return new PointF (xScale, yScale);
159                         }
160                         set {
161                                 Status status = GDIPlus.GdipSetPathGradientFocusScales (nativeObject, value.X, value.Y);
162                                 GDIPlus.CheckStatus (status);
163                         }
164                 }
165
166                 public ColorBlend InterpolationColors {
167                         get {
168                                 int count;
169                                 Status status = GDIPlus.GdipGetPathGradientPresetBlendCount (nativeObject, out count);
170                                 GDIPlus.CheckStatus (status);
171                                 int [] intcolors = new int [count];
172                                 float [] positions = new float [count];
173                                 status = GDIPlus.GdipGetPathGradientPresetBlend (nativeObject, intcolors, positions, count);
174                                 GDIPlus.CheckStatus (status);
175
176                                 ColorBlend interpolationColors = new ColorBlend ();
177                                 Color [] colors = new Color [count];
178                                 for (int i = 0; i < count; i++)
179                                         colors [i] = Color.FromArgb (intcolors [i]);
180                                 interpolationColors.Colors = colors;
181                                 interpolationColors.Positions = positions;
182
183                                 return interpolationColors;
184                         }
185                         set {
186                                 int count;
187                                 Color [] colors = value.Colors;
188                                 float [] positions = value.Positions;
189                                 count = colors.Length;
190
191                                 if (count == 0 || positions.Length == 0)
192                                         throw new ArgumentException ("Invalid ColorBlend object. It should have at least 2 elements in each of the colors and positions arrays.");
193
194                                 if (count != positions.Length)
195                                         throw new ArgumentException ("Invalid ColorBlend object. It should contain the same number of positions and color values.");
196
197                                 if (positions [0] != 0.0F)
198                                         throw new ArgumentException ("Invalid ColorBlend object. The positions array must have 0.0 as its first element.");
199
200                                 if (positions [count - 1] != 1.0F)
201                                         throw new ArgumentException ("Invalid ColorBlend object. The positions array must have 1.0 as its last element.");
202
203                                 int [] blend = new int [colors.Length];
204                                 for (int i = 0; i < colors.Length; i++)
205                                         blend [i] = colors [i].ToArgb ();
206
207                                 Status status = GDIPlus.GdipSetPathGradientPresetBlend (nativeObject, blend, positions, count);
208                                 GDIPlus.CheckStatus (status);
209                         }
210                 }
211
212                 public RectangleF Rectangle {
213                         get {
214                                 RectangleF rect;
215                                 Status status = GDIPlus.GdipGetPathGradientRect (nativeObject, out rect);
216                                 GDIPlus.CheckStatus (status);
217
218                                 return rect;
219                         }
220                 }
221
222                 public Color [] SurroundColors {
223                         get {
224                                 int count;
225                                 Status status = GDIPlus.GdipGetPathGradientSurroundColorCount (nativeObject, out count);
226                                 GDIPlus.CheckStatus (status);
227
228                                 int [] intcolors = new int [count];
229                                 status = GDIPlus.GdipGetPathGradientSurroundColorsWithCount (nativeObject, intcolors, ref count);
230                                 GDIPlus.CheckStatus (status);
231
232                                 Color [] colors = new Color [count];
233                                 for (int i = 0; i < count; i++)
234                                         colors [i] = Color.FromArgb (intcolors [i]);
235
236                                 return colors;
237                         }
238                         set {
239                                 int count = value.Length;
240                                 int [] colors = new int [count];
241                                 for (int i = 0; i < count; i++)
242                                         colors [i] = value [i].ToArgb ();
243
244                                 Status status = GDIPlus.GdipSetPathGradientSurroundColorsWithCount (nativeObject, colors, ref count);
245                                 GDIPlus.CheckStatus (status);
246                         }
247                 }
248
249                 public Matrix Transform {
250                         get {
251                                 Matrix matrix = new Matrix ();
252                                 Status status = GDIPlus.GdipGetPathGradientTransform (nativeObject, matrix.nativeMatrix);
253                                 GDIPlus.CheckStatus (status);
254
255                                 return matrix;
256                         }
257                         set {
258                                 if (value == null)
259                                         throw new ArgumentNullException ("Transform");
260
261                                 Status status = GDIPlus.GdipSetPathGradientTransform (nativeObject, value.nativeMatrix);
262                                 GDIPlus.CheckStatus (status);
263                         }
264                 }
265
266                 public WrapMode WrapMode {
267                         get {
268                                 WrapMode wrapMode;
269                                 Status status = GDIPlus.GdipGetPathGradientWrapMode (nativeObject, out wrapMode);
270                                 GDIPlus.CheckStatus (status);
271
272                                 return wrapMode;
273                         }
274                         set {
275                                 if ((value < WrapMode.Tile) || (value > WrapMode.Clamp))
276                                         throw new InvalidEnumArgumentException ("WrapMode");
277
278                                 Status status = GDIPlus.GdipSetPathGradientWrapMode (nativeObject, value);
279                                 GDIPlus.CheckStatus (status);
280                         }
281                 }
282
283                 // Methods
284
285                 public void MultiplyTransform (Matrix matrix)
286                 {
287                         MultiplyTransform (matrix, MatrixOrder.Prepend);
288                 }
289
290                 public void MultiplyTransform (Matrix matrix, MatrixOrder order)
291                 {
292                         if (matrix == null)
293                                 throw new ArgumentNullException ("matrix");
294
295                         Status status = GDIPlus.GdipMultiplyPathGradientTransform (nativeObject, matrix.nativeMatrix, order);
296                         GDIPlus.CheckStatus (status);
297                 }
298
299                 public void ResetTransform ()
300                 {
301                         Status status = GDIPlus.GdipResetPathGradientTransform (nativeObject);
302                         GDIPlus.CheckStatus (status);
303                 }
304
305                 public void RotateTransform (float angle)
306                 {
307                         RotateTransform (angle, MatrixOrder.Prepend);
308                 }
309
310                 public void RotateTransform (float angle, MatrixOrder order)
311                 {
312                         Status status = GDIPlus.GdipRotatePathGradientTransform (nativeObject, angle, order);
313                         GDIPlus.CheckStatus (status);
314                 }
315
316                 public void ScaleTransform (float sx, float sy)
317                 {
318                         ScaleTransform (sx, sy, MatrixOrder.Prepend);
319                 }
320
321                 public void ScaleTransform (float sx, float sy, MatrixOrder order)
322                 {
323                         Status status = GDIPlus.GdipScalePathGradientTransform (nativeObject, sx, sy, order);
324                         GDIPlus.CheckStatus (status);
325                 }
326
327                 public void SetBlendTriangularShape (float focus)
328                 {
329                         SetBlendTriangularShape (focus, 1.0F);
330                 }
331
332                 public void SetBlendTriangularShape (float focus, float scale)
333                 {
334                         if (focus < 0 || focus > 1 || scale < 0 || scale > 1)
335                                 throw new ArgumentException ("Invalid parameter passed.");
336
337                         Status status = GDIPlus.GdipSetPathGradientLinearBlend (nativeObject, focus, scale);
338                         GDIPlus.CheckStatus (status);
339                 }
340
341                 public void SetSigmaBellShape (float focus)
342                 {
343                         SetSigmaBellShape (focus, 1.0F);
344                 }
345
346                 public void SetSigmaBellShape (float focus, float scale)
347                 {
348                         if (focus < 0 || focus > 1 || scale < 0 || scale > 1)
349                                 throw new ArgumentException ("Invalid parameter passed.");
350
351                         Status status = GDIPlus.GdipSetPathGradientSigmaBlend (nativeObject, focus, scale);
352                         GDIPlus.CheckStatus (status);
353                 }
354
355                 public void TranslateTransform (float dx, float dy)
356                 {
357                         TranslateTransform (dx, dy, MatrixOrder.Prepend);
358                 }
359
360                 public void TranslateTransform (float dx, float dy, MatrixOrder order)
361                 {
362                         Status status = GDIPlus.GdipTranslatePathGradientTransform (nativeObject, dx, dy, order);
363                         GDIPlus.CheckStatus (status);
364                 }
365
366                 public override object Clone ()
367                 {
368                         IntPtr clonePtr;
369                         Status status = GDIPlus.GdipCloneBrush (nativeObject, out clonePtr);
370                         GDIPlus.CheckStatus (status);
371
372                         PathGradientBrush clone = new PathGradientBrush (clonePtr);
373                         return clone;
374                 }
375         }
376 }