2 // System.Drawing.Pen.cs
5 // Miguel de Icaza (miguel@ximian.com)
6 // Alexandre Pigolkine (pigolkine@gmx.de)
7 // Duncan Mak (duncan@ximian.com)
8 // Ravindra (rkumar@novell.com)
10 // (C) Ximian, Inc. http://www.ximian.com
11 // (C) Novell, Inc. http://www.novell.com
15 using System.Drawing.Drawing2D;
16 using System.Runtime.InteropServices;
20 namespace System.Drawing
\r
23 public sealed class Pen : MarshalByRefObject, ICloneable, IDisposable, awt.Stroke
\r
27 static readonly float [] DASH_ARRAY = {4.0f,1.0f};
28 static readonly float [] DASHDOT_ARRAY = {4.0f,1.0f,1.0f,1.0f};
29 static readonly float [] DASHDOTDOT_ARRAY = {4.0f,1.0f,1.0f,1.0f,1.0f,1.0f};
30 static readonly float [] DOT_ARRAY = {1.0f,1.0f};
32 internal bool isModifiable = true;
42 PenAlignment _alignment;
47 //float[] _compoundArray;
53 #region Ctors. and Dtor
55 public Pen (Brush brush) : this (brush, 1.0F)
58 public Pen (Color color) : this (color, 1.0F)
61 public Pen (Color color, float width) : this(new SolidBrush(color), width)
64 public Pen (Brush brush, float width)
66 _brush = (Brush)brush.Clone();;
68 _dashStyle = DashStyle.Solid;
69 _startCap = LineCap.Flat;
70 _dashCap = DashCap.Flat;
71 _endCap = LineCap.Flat;
72 _alignment = PenAlignment.Center;
73 _lineJoin = LineJoin.Miter;
80 #region Alignment [TODO]
81 public PenAlignment Alignment
\r
108 throw new ArgumentNullException("brush");
115 public Color Color
\r
119 if(Brush is SolidBrush)
120 return ((SolidBrush)Brush).Color;
121 else if(Brush is HatchBrush)
122 return ((HatchBrush)Brush).ForegroundColor;
130 _brush = new SolidBrush (value);
135 #region CompoundArray [TODO]
136 public float[] CompoundArray {
138 throw new NotImplementedException ();
141 throw new NotImplementedException ();
146 #region CustomEndCap [TODO]
147 public CustomLineCap CustomEndCap
\r
151 throw new NotImplementedException ();
153 // do a check for isModifiable when implementing this property
156 throw new NotImplementedException ();
161 #region CustomStartCap [TODO]
162 public CustomLineCap CustomStartCap
\r
167 throw new NotImplementedException ();
170 // do a check for isModifiable when implementing this property
173 throw new NotImplementedException ();
179 public DashCap DashCap {
192 public float DashOffset
\r
210 public float [] DashPattern
\r
221 _dashPattern = value;
222 DashStyle = (_dashPattern == null) ? DashStyle.Solid : DashStyle.Custom;
228 public DashStyle DashStyle
\r
243 #region StartCap [TODO - now allways endcap]
245 public LineCap StartCap {
258 public LineCap EndCap
\r
274 #region LineJoin [partial TODO - missed styles]
275 public LineJoin LineJoin {
289 public float MiterLimit
\r
308 public PenType PenType
\r
312 if (Brush is TextureBrush)
313 return PenType.TextureFill;
314 else if (Brush is HatchBrush)
315 return PenType.HatchFill;
316 else if (Brush is LinearGradientBrush)
317 return PenType.LinearGradient;
318 else if (Brush is PathGradientBrush)
319 return PenType.PathGradient;
321 return PenType.SolidColor;
327 public Matrix Transform
\r
331 if (_transform == null)
332 _transform = new Matrix ();
346 public float Width
\r
362 public object Clone ()
364 Pen clone = (Pen)MemberwiseClone();
365 if (clone._transform != null)
366 clone._transform = clone._transform.Clone();
367 if (clone._dashPattern != null)
368 clone._dashPattern = (float[])clone._dashPattern.Clone();
374 public void Dispose ()
378 void Dispose (bool disposing)
380 if (!isModifiable && disposing)
381 throw new ArgumentException ("You may not change this Pen because it does not belong to you.");
382 // Restore the dtor if adding anything below
386 #region Transform Funcs
387 public void MultiplyTransform (Matrix matrix)
389 Transform.Multiply (matrix);
392 public void MultiplyTransform (Matrix matrix, MatrixOrder order)
394 Transform.Multiply (matrix, order);
397 public void ResetTransform ()
402 public void RotateTransform (float angle)
404 Transform.Rotate (angle);
407 public void RotateTransform (float angle, MatrixOrder order)
409 Transform.Rotate (angle, order);
412 public void ScaleTransform (float sx, float sy)
414 Transform.Scale (sx, sy);
417 public void ScaleTransform (float sx, float sy, MatrixOrder order)
419 Transform.Scale (sx, sy, order);
422 public void TranslateTransform (float dx, float dy) {
423 Transform.Translate (dx, dy);
426 public void TranslateTransform (float dx, float dy, MatrixOrder order) {
427 Transform.Translate (dx, dy, order);
431 public void SetLineCap (LineCap startCap, LineCap endCap, DashCap dashCap)
438 void EnsureModifiable() {
440 throw new ArgumentException ("You may not change this Pen because it does not belong to you.");
443 #region Stroke Members
\r
445 awt.Shape awt.Stroke.createStrokedShape(awt.Shape arg_0) {
\r
446 float[] dashPattern = null;
\r
448 //You will see many magic numbers above this place
449 //behaviours of dash patterns in .NET and JAVA are not similar
450 //also it looks like JAVA have some design flaw there.
451 //The issue is that in java only switched on (ODD) entries are
452 //looks to be dependent on current line with. Switched off (EVEN)
453 //entries allways remains exact width as you specify. So we should
454 //do some calculations to determine actual java pattern
455 //Also note that ODD entries does not grow proportionally with line width
456 //so they should be sligntly ajusted also.
457 //Well, i know that potential perfomance of this staf could be bad, but
458 //that is solution for now. Note, that .NET have also numerous bugs in this
459 //region, for example they mandatory could not tolerate patternalising
460 //lines of 1 pixel width - look will be BAD.
\r
461 switch (DashStyle) {
\r
462 case DashStyle.Custom:
\r
463 if (DashPattern != null) {
\r
464 dashPattern = new float[DashPattern.Length];
\r
465 for(int i = 0; i < DashPattern.Length; i++) {
467 if (DashPattern[i] > 1.0f)
468 dashPattern[i] = DashPattern[i] + (DashPattern[i]-1.0f) * Width / 2f;
471 dashPattern[i] = DashPattern[i] * Width * 2f;
\r
475 case DashStyle.Dash:
\r
476 dashPattern = DASH_ARRAY;
\r
478 case DashStyle.DashDot:
\r
479 dashPattern = DASHDOT_ARRAY;
\r
481 case DashStyle.DashDotDot:
\r
482 dashPattern = DASHDOTDOT_ARRAY;
\r
486 // case DashStyle.Solid:
\r
493 join = java.awt.BasicStroke.JOIN_BEVEL;
497 case LineJoin.MiterClipped:
498 join = java.awt.BasicStroke.JOIN_MITER;
501 join = java.awt.BasicStroke.JOIN_ROUND;
\r
505 // We go by End cap for now.
\r
510 case LineCap.SquareAnchor:
511 cap = awt.BasicStroke.CAP_SQUARE;
514 case LineCap.RoundAnchor:
515 cap = awt.BasicStroke.CAP_ROUND;
518 cap = awt.BasicStroke.CAP_BUTT;
522 awt.Stroke stroke = StrokeFactory.CreateStroke(Width, cap,
\r
523 join, MiterLimit, dashPattern, DashOffset,
\r
524 _transform != null ? _transform.NativeObject : null);
\r
526 return stroke.createStrokedShape(arg_0);
\r