using System;
using System.Drawing.Drawing2D;
using System.Runtime.InteropServices;
-using java.awt;
-namespace System.Drawing
+using awt = java.awt;
+
+namespace System.Drawing \r
{
- public sealed class Pen : MarshalByRefObject, ICloneable, IDisposable
+ public sealed class Pen : MarshalByRefObject, ICloneable, IDisposable, awt.Stroke\r
{
#region Member Vars
- java.awt.BasicStroke nativeObject;
+
+ static readonly float [] DASH_ARRAY = {4.0f,1.0f};
+ static readonly float [] DASHDOT_ARRAY = {4.0f,1.0f,1.0f,1.0f};
+ static readonly float [] DASHDOTDOT_ARRAY = {4.0f,1.0f,1.0f,1.0f,1.0f,1.0f};
+ static readonly float [] DOT_ARRAY = {1.0f,1.0f};
+
internal bool isModifiable = true;
- Brush brush;
- DashStyle _ds = DashStyle.Solid;
+
+ Brush _brush;
+ DashStyle _dashStyle;
+ DashCap _dashCap;
+ LineCap _startCap;
+ LineCap _endCap;
+
+ LineJoin _lineJoin;
+
PenAlignment _alignment;
Matrix _transform;
- #endregion
+ float _width;
+ float _dashOffset;
+ float[] _dashPattern;
+ //float[] _compoundArray;
- #region Internals
- internal Pen (java.awt.BasicStroke p)
- {
- nativeObject = p;
- }
+ float _miterLimit;
- internal java.awt.BasicStroke NativeObject
- {
- get
- {
- return nativeObject;
- }
- set
- {
- nativeObject=value;
- }
- }
#endregion
#region Ctors. and Dtor
-// ~Pen ()
-// {
-// Dispose (false);
-// }
public Pen (Brush brush) : this (brush, 1.0F)
- {
- }
+ {}
public Pen (Color color) : this (color, 1.0F)
- {
- }
+ {}
- public Pen (Color color, float width)
- {
- brush = new SolidBrush(color);
- nativeObject = new java.awt.BasicStroke(width);
- }
+ public Pen (Color color, float width) : this(new SolidBrush(color), width)
+ {}
public Pen (Brush brush, float width)
{
- brush = (Brush)brush.Clone();
- nativeObject = new java.awt.BasicStroke(width);
+ _brush = (Brush)brush.Clone();;
+ _width = width;
+ _dashStyle = DashStyle.Solid;
+ _startCap = LineCap.Flat;
+ _dashCap = DashCap.Flat;
+ _endCap = LineCap.Flat;
+ _alignment = PenAlignment.Center;
+ _lineJoin = LineJoin.Miter;
+ _miterLimit = 10f;
}
#endregion
//
// Properties
//
#region Alignment [TODO]
- public PenAlignment Alignment
+ public PenAlignment Alignment \r
{
- get
+ get \r
{
return _alignment;
}
- set
+ set \r
{
- if (!isModifiable)
- throw new ArgumentException ("Pen is not modifiable");
+ EnsureModifiable();
_alignment = value;
}
}
#endregion
#region Brush
- public Brush Brush
+ public Brush Brush \r
{
- get
+ get \r
{
- return brush;
+ return _brush;
}
- set
+ set \r
{
- if (isModifiable)
- {
- brush = value;
- }
- else
- throw new ArgumentException ("You may not change this Pen because it does not belong to you.");
+ EnsureModifiable();
+ if (value == null)
+ throw new ArgumentNullException("brush");
+ _brush = value;
}
}
#endregion
#region Color
- public Color Color
+ public Color Color \r
{
- get
+ get \r
{
- if(brush is SolidBrush)
- return ((SolidBrush)brush).Color;
- else if(brush is HatchBrush)
- return ((HatchBrush)brush).ForegroundColor;
+ if(Brush is SolidBrush)
+ return ((SolidBrush)Brush).Color;
+ else if(Brush is HatchBrush)
+ return ((HatchBrush)Brush).ForegroundColor;
else
return Color.Empty;
}
- set
+ set \r
{
- if (isModifiable)
- {
- brush = new SolidBrush (value);
- }
- else
- throw new ArgumentException ("You may not change this Pen because it does not belong to you.");
+ EnsureModifiable();
+ _brush = new SolidBrush (value);
}
}
#endregion
+
+ #region CompoundArray [TODO]
+ public float[] CompoundArray {
+ get {
+ throw new NotImplementedException ();
+ }
+ set {
+ throw new NotImplementedException ();
+ }
+ }
+ #endregion
#region CustomEndCap [TODO]
- public CustomLineCap CustomEndCap
+ public CustomLineCap CustomEndCap \r
{
- get
+ get \r
{
throw new NotImplementedException ();
}
// do a check for isModifiable when implementing this property
- set
+ set \r
{
throw new NotImplementedException ();
}
}
#endregion
- #region CustoStartCap [TODO]
- public CustomLineCap CustomStartCap
+ #region CustomStartCap [TODO]
+ public CustomLineCap CustomStartCap \r
{
- get
+ get \r
{
throw new NotImplementedException ();
}
// do a check for isModifiable when implementing this property
- set
+ set \r
{
throw new NotImplementedException ();
}
}
#endregion
- #region DashCap [TODO, now - allways flat]
- public DashCap DashCap
- {
- get
- {
- //TODO
- return DashCap.Flat;
+ #region DashCap
+ public DashCap DashCap {
+ get {
+ return _dashCap;
}
- set
- {
-
+ set {
+ EnsureModifiable();
+ _dashCap = value;
}
}
#endregion
#region DashOffset
- public float DashOffset
+ public float DashOffset \r
{
- get
+ get \r
{
- return nativeObject.getDashPhase();
+ return _dashOffset;
}
- set
+ set \r
{
- if (isModifiable)
- nativeObject = new java.awt.BasicStroke(
- nativeObject.getLineWidth(),
- nativeObject.getEndCap(),
- nativeObject.getLineJoin(),
- nativeObject.getMiterLimit(),
- nativeObject.getDashArray(),
- value);
- else
- throw new ArgumentException ("You may not change this Pen because it does not belong to you.");
+ EnsureModifiable();
+ _dashOffset = value;
}
}
#endregion
#region DashPattern
- //spivak.BUGBUG
- //You will see many magic numbers above this place
- //behaviours of dash patterns in .NET and JAVA are not similar
- //also it looks like JAVA have some design flaw there.
- //The issue is that in java only switched on (ODD) entries are
- //looks to be dependent on current line with. Switched off (EVEN)
- //entries allways remains exact width as you specify. So we should
- //do some calculations to determine actual java pattern
- //Also note that ODD entries does not grow proportionally with line width
- //so they should be sligntly ajusted also.
- //Well, i know that potential perfomance of this staf could be bad, but
- //that is solution for now. Note, that .NET have also numerous bugs in this
- //region, for example they mandatory could not tolerate patternalising
- //lines of 1 pixel width - look will be BAD.
-
- internal void SetDashPattern(float [] patt,DashStyle s)
+ public float [] DashPattern \r
{
- if(patt == null)
+ get \r
{
- nativeObject = new java.awt.BasicStroke(
- nativeObject.getLineWidth(),
- nativeObject.getEndCap(),
- nativeObject.getLineJoin(),
- nativeObject.getMiterLimit(),
- null,
- nativeObject.getDashPhase());
- _ds = DashStyle.Solid;
- }
- else
- {
- float [] temp = new float[patt.Length];
- patt.CopyTo(temp,0);
- float w = nativeObject.getLineWidth();
- int i;
- for(i = 0;i<temp.Length;i+=2)
- if(temp[i] > 1.0f)
- temp[i] = temp[i] + (temp[i]-1.0f) * w / (float)2;
-
- for(i = 1;i<temp.Length;i+=2)
- temp[i] *= nativeObject.getLineWidth() * (float)2;
-
- nativeObject = new java.awt.BasicStroke(
- nativeObject.getLineWidth(),
- nativeObject.getEndCap(),
- nativeObject.getLineJoin(),
- nativeObject.getMiterLimit(),
- temp,
- nativeObject.getDashPhase());
- _ds = DashStyle.Custom;
+ return _dashPattern;
}
- }
-
- public float [] DashPattern
- {
- get
+ set \r
{
- float w = nativeObject.getLineWidth();
- float [] temp = nativeObject.getDashArray();
- for(int i = 0;i<temp.Length;i+=2)
- if(temp[i] > 1.0f)
- temp[i] -= (temp[i] - 1.0f) / w * (float)2;
-
- for(int i = 1;i<temp.Length;i+=2)
- temp[i] /= w * 2;
+ EnsureModifiable();
- return temp;
- }
-
- set
- {
-
- if (isModifiable)
- SetDashPattern(value,DashStyle.Custom);
- else
- throw new ArgumentException ("You may not change this Pen because it does not belong to you.");
+ _dashPattern = value;
+ DashStyle = (_dashPattern == null) ? DashStyle.Solid : DashStyle.Custom;
}
}
#endregion
#region DashStyle
- public DashStyle DashStyle
+ public DashStyle DashStyle \r
{
- get
+ get \r
{
- return _ds;
+ return _dashStyle;
}
- set
+ set \r
{
- if (isModifiable)
- {
- if (value == DashStyle.Solid)
- SetDashPattern(null,value);
- else if (value == DashStyle.Dash)
- SetDashPattern(System.Drawing.Drawing2D.DashAttribs.DASH_ARRAY,value);
- else if (value == DashStyle.DashDot)
- SetDashPattern(System.Drawing.Drawing2D.DashAttribs.DASHDOT_ARRAY,value);
- else if (value == DashStyle.DashDotDot)
- SetDashPattern(System.Drawing.Drawing2D.DashAttribs.DASHDOTDOT_ARRAY,value);
- else if (value == DashStyle.Dot)
- SetDashPattern(System.Drawing.Drawing2D.DashAttribs.DOT_ARRAY,value);
- else
- throw new ArgumentOutOfRangeException();
- }
- else
- throw new ArgumentException ("You may not change this Pen because it does not belong to you.");
+ EnsureModifiable();
+ _dashStyle = value;
}
}
#endregion
#region StartCap [TODO - now allways endcap]
- public LineCap StartCap
- {
- get
- {
- //TODO
- return EndCap;
+ public LineCap StartCap {
+ get {
+ return _startCap;
}
- set
- {
- EndCap = value;
+ set {
+ EnsureModifiable();
+ _startCap = value;
}
}
#endregion
#region EndCap
- public LineCap EndCap
+ public LineCap EndCap \r
{
- get
+ get \r
{
- int cup = nativeObject.getEndCap();
- if(cup == BasicStroke.CAP_ROUND)
- return LineCap.Round;
- else if(cup == BasicStroke.CAP_BUTT)
- return LineCap.Flat;
- else if(cup == BasicStroke.CAP_SQUARE)
- return LineCap.Square;
- else
- return LineCap.Custom;
- }
-
- set
+ return _endCap;
+ }
+
+ set \r
{
- int cap;
- if((value == LineCap.Square) ||
- (value == LineCap.SquareAnchor))
- cap = BasicStroke.CAP_SQUARE;
- else if ((value == LineCap.Round) ||
- (value == LineCap.RoundAnchor))
- cap = BasicStroke.CAP_ROUND;
- else if ((value == LineCap.Flat))
- cap = BasicStroke.CAP_BUTT;
- else
- //TODO:default
- cap = BasicStroke.CAP_SQUARE;
+ EnsureModifiable();
+
+ _endCap = value;
}
}
#endregion
#region LineJoin [partial TODO - missed styles]
- public LineJoin LineJoin
- {
- //TODO:missed styles
-
- get
- {
-
- int join = nativeObject.getLineJoin();
- if(join == java.awt.BasicStroke.JOIN_BEVEL)
- return LineJoin.Bevel;
- else if(join == java.awt.BasicStroke.JOIN_MITER)
- return LineJoin.Miter;
- else if(join == java.awt.BasicStroke.JOIN_ROUND)
- return LineJoin.Round;
- else
- throw new ArgumentOutOfRangeException();
+ public LineJoin LineJoin {
+ get {
+ return _lineJoin;
}
- set
- {
- if (isModifiable)
- {
- int join = 0;
- if (value == LineJoin.Bevel)
- join = java.awt.BasicStroke.JOIN_BEVEL;
- if ((value == LineJoin.Miter) || (value==LineJoin.MiterClipped))
- join = java.awt.BasicStroke.JOIN_MITER;
- if (value == LineJoin.Round)
- join = java.awt.BasicStroke.JOIN_ROUND;
-
- nativeObject = new java.awt.BasicStroke(
- nativeObject.getLineWidth(),
- nativeObject.getEndCap(),
- join,
- nativeObject.getMiterLimit(),
- nativeObject.getDashArray(),
- nativeObject.getDashPhase());
- }
- else
- throw new ArgumentException ("You may not change this Pen because it does not belong to you.");
+ set {
+ EnsureModifiable();
+ _lineJoin = value;
}
}
+
#endregion
#region MiterLimit
- public float MiterLimit
+ public float MiterLimit \r
{
- get
+ get \r
{
- return nativeObject.getMiterLimit();
+ return _miterLimit;
}
- set
+ set \r
{
- if (isModifiable)
- nativeObject = new java.awt.BasicStroke(
- nativeObject.getLineWidth(),
- nativeObject.getEndCap(),
- nativeObject.getLineJoin(),
- value,
- nativeObject.getDashArray(),
- nativeObject.getDashPhase());
- else
- throw new ArgumentException ("You may not change this Pen because it does not belong to you.");
+ EnsureModifiable();
+
+ _miterLimit = value;
}
}
#endregion
#region PenType
- public PenType PenType
+ public PenType PenType \r
{
-
- get
+ get \r
{
- if (brush is TextureBrush)
+ if (Brush is TextureBrush)
return PenType.TextureFill;
- else if (brush is HatchBrush)
+ else if (Brush is HatchBrush)
return PenType.HatchFill;
- else if (brush is LinearGradientBrush)
+ else if (Brush is LinearGradientBrush)
return PenType.LinearGradient;
- else if (brush is PathGradientBrush)
+ else if (Brush is PathGradientBrush)
return PenType.PathGradient;
else
return PenType.SolidColor;
}
#endregion
- #region Transform [TODO]
- public Matrix Transform
+ #region Transform
+ public Matrix Transform \r
{
- get
+ get \r
{
if (_transform == null)
_transform = new Matrix ();
return _transform;
}
- set
+ set \r
{
- if (!isModifiable)
- throw new ArgumentException ("Pen is not modifiable");
+ EnsureModifiable();
+
_transform = value;
}
}
#endregion
#region Width
- public float Width
+ public float Width \r
{
- get
+ get \r
{
- return nativeObject.getLineWidth();
+ return _width;
}
- set
+ set \r
{
- if (isModifiable)
- nativeObject = new java.awt.BasicStroke(
- value,
- nativeObject.getEndCap(),
- nativeObject.getLineJoin(),
- nativeObject.getMiterLimit(),
- nativeObject.getDashArray(),
- nativeObject.getDashPhase());
- else
- throw new ArgumentException ("You may not change this Pen because it does not belong to you.");
+ EnsureModifiable();
+
+ _width = value;
}
}
#endregion
#region Clone
public object Clone ()
{
- Pen p = new Pen (nativeObject);
- p.isModifiable = isModifiable;
- p.brush = brush;
- p._ds = _ds;
- p._alignment = _alignment;
- p._transform = _transform;
- return p;
+ Pen clone = (Pen)MemberwiseClone();
+ if (clone._transform != null)
+ clone._transform = clone._transform.Clone();
+ if (clone._dashPattern != null)
+ clone._dashPattern = (float[])clone._dashPattern.Clone();
+ return clone;
}
#endregion
}
#endregion
- #region Transform Funcs [TODO]
+ #region Transform Funcs
public void MultiplyTransform (Matrix matrix)
{
Transform.Multiply (matrix);
Transform.Translate (dx, dy, order);
}
#endregion
+
public void SetLineCap (LineCap startCap, LineCap endCap, DashCap dashCap)
{
- throw new NotImplementedException();
+ StartCap = startCap;
+ DashCap = dashCap;
+ EndCap = endCap;
}
+
+ void EnsureModifiable() {
+ if (!isModifiable)
+ throw new ArgumentException ("You may not change this Pen because it does not belong to you.");
+ }
+
+ #region Stroke Members\r
+\r
+ awt.Shape awt.Stroke.createStrokedShape(awt.Shape arg_0) {\r
+ float[] dashPattern = null;\r
+ //spivak.BUGBUG
+ //You will see many magic numbers above this place
+ //behaviours of dash patterns in .NET and JAVA are not similar
+ //also it looks like JAVA have some design flaw there.
+ //The issue is that in java only switched on (ODD) entries are
+ //looks to be dependent on current line with. Switched off (EVEN)
+ //entries allways remains exact width as you specify. So we should
+ //do some calculations to determine actual java pattern
+ //Also note that ODD entries does not grow proportionally with line width
+ //so they should be sligntly ajusted also.
+ //Well, i know that potential perfomance of this staf could be bad, but
+ //that is solution for now. Note, that .NET have also numerous bugs in this
+ //region, for example they mandatory could not tolerate patternalising
+ //lines of 1 pixel width - look will be BAD.\r
+ switch (DashStyle) {\r
+ case DashStyle.Custom:\r
+ if (DashPattern != null) {\r
+ dashPattern = new float[DashPattern.Length];\r
+ for(int i = 0; i < DashPattern.Length; i++) {
+ if((i & 1) == 0) {
+ if (DashPattern[i] > 1.0f)
+ dashPattern[i] = DashPattern[i] + (DashPattern[i]-1.0f) * Width / 2f;
+ }
+ else
+ dashPattern[i] = DashPattern[i] * Width * 2f;\r
+ }\r
+ }\r
+ break;\r
+ case DashStyle.Dash:\r
+ dashPattern = DASH_ARRAY;\r
+ break;\r
+ case DashStyle.DashDot:\r
+ dashPattern = DASHDOT_ARRAY;\r
+ break;\r
+ case DashStyle.DashDotDot:\r
+ dashPattern = DASHDOTDOT_ARRAY;\r
+ break;\r
+ \r
+// default:\r
+// case DashStyle.Solid:\r
+// break;\r
+ }\r
+\r
+ int join;
+ switch (LineJoin) {
+ case LineJoin.Bevel:
+ join = java.awt.BasicStroke.JOIN_BEVEL;
+ break;
+ default:
+ case LineJoin.Miter:
+ case LineJoin.MiterClipped:
+ join = java.awt.BasicStroke.JOIN_MITER;
+ break;
+ case LineJoin.Round:
+ join = java.awt.BasicStroke.JOIN_ROUND;\r
+ break;\r
+ }\r
+\r
+ // We go by End cap for now.\r
+ int cap;\r
+ switch (EndCap) {\r
+ default:\r
+ case LineCap.Square:
+ case LineCap.SquareAnchor:
+ cap = awt.BasicStroke.CAP_SQUARE;
+ break;
+ case LineCap.Round:
+ case LineCap.RoundAnchor:
+ cap = awt.BasicStroke.CAP_ROUND;
+ break;
+ case LineCap.Flat:
+ cap = awt.BasicStroke.CAP_BUTT;
+ break;\r
+ }\r
+\r
+ awt.Stroke stroke = StrokeFactory.CreateStroke(Width, cap, \r
+ join, MiterLimit, dashPattern, DashOffset,\r
+ _transform != null ? _transform.NativeObject : null);\r
+ \r
+ return stroke.createStrokedShape(arg_0);\r
+ }\r
+\r
+ #endregion
}
}