//
// System.Drawing.Pen.cs
//
// Authors:
// Miguel de Icaza (miguel@ximian.com)
// Alexandre Pigolkine (pigolkine@gmx.de)
// Duncan Mak (duncan@ximian.com)
// Ravindra (rkumar@novell.com)
//
// Copyright (C) Ximian, Inc. http://www.ximian.com
// Copyright (C) 2004,2006 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System.ComponentModel;
using System.Drawing.Drawing2D;
using System.Runtime.InteropServices;
namespace System.Drawing{
public sealed class Pen : MarshalByRefObject, ICloneable, IDisposable
{
internal IntPtr nativeObject;
internal bool isModifiable = true;
private Color color;
private CustomLineCap startCap;
private CustomLineCap endCap;
internal Pen (IntPtr p)
{
nativeObject = p;
}
public Pen (Brush brush) : this (brush, 1.0F)
{
}
public Pen (Color color) : this (color, 1.0F)
{
}
public Pen (Brush brush, float width)
{
if (brush == null)
throw new ArgumentNullException ("brush");
Status status = GDIPlus.GdipCreatePen2 (brush.nativeObject, width, GraphicsUnit.World, out nativeObject);
GDIPlus.CheckStatus (status);
color = Color.Empty;
}
public Pen (Color color, float width)
{
Status status = GDIPlus.GdipCreatePen1 (color.ToArgb (), width, GraphicsUnit.World, out nativeObject);
GDIPlus.CheckStatus (status);
this.color = color;
}
//
// Properties
//
[MonoLimitation ("Libgdiplus doesn't use this property for rendering")]
public PenAlignment Alignment {
get {
PenAlignment retval;
Status status = GDIPlus.GdipGetPenMode (nativeObject, out retval);
GDIPlus.CheckStatus (status);
return retval;
}
set {
if ((value < PenAlignment.Center) || (value > PenAlignment.Right))
throw new InvalidEnumArgumentException ("Alignment", (int)value, typeof (PenAlignment));
if (isModifiable) {
Status status = GDIPlus.GdipSetPenMode (nativeObject, value);
GDIPlus.CheckStatus (status);
} else
throw new ArgumentException (Locale.GetText ("This Pen object can't be modified."));
}
}
public Brush Brush {
get {
IntPtr brush;
Status status = GDIPlus.GdipGetPenBrushFill (nativeObject, out brush);
GDIPlus.CheckStatus (status);
return new SolidBrush (brush);
}
set {
#if NET_2_0
if (value == null)
throw new ArgumentNullException ("Brush");
#endif
if (!isModifiable)
throw new ArgumentException (Locale.GetText ("This Pen object can't be modified."));
Status status = GDIPlus.GdipSetPenBrushFill (nativeObject, value.nativeObject);
GDIPlus.CheckStatus (status);
color = Color.Empty;
}
}
public Color Color {
get {
if (color.Equals (Color.Empty)) {
int c;
Status status = GDIPlus.GdipGetPenColor (nativeObject, out c);
GDIPlus.CheckStatus (status);
color = Color.FromArgb (c);
}
return color;
}
set {
if (!isModifiable)
throw new ArgumentException (Locale.GetText ("This Pen object can't be modified."));
Status status = GDIPlus.GdipSetPenColor (nativeObject, value.ToArgb ());
GDIPlus.CheckStatus (status);
color = value;
}
}
public float [] CompoundArray {
get {
int count;
Status status = GDIPlus.GdipGetPenCompoundCount (nativeObject, out count);
GDIPlus.CheckStatus (status);
float [] compArray = new float [count];
status = GDIPlus.GdipGetPenCompoundArray (nativeObject, compArray, count);
GDIPlus.CheckStatus (status);
return compArray;
}
set {
if (isModifiable) {
int length = value.Length;
if (length < 2)
throw new ArgumentException ("Invalid parameter.");
foreach (float val in value)
if (val < 0 || val > 1)
throw new ArgumentException ("Invalid parameter.");
Status status = GDIPlus.GdipSetPenCompoundArray (nativeObject, value, value.Length);
GDIPlus.CheckStatus (status);
} else
throw new ArgumentException (Locale.GetText ("This Pen object can't be modified."));
}
}
public CustomLineCap CustomEndCap {
get {
return endCap;
}
set {
if (isModifiable) {
Status status = GDIPlus.GdipSetPenCustomEndCap (nativeObject, value.nativeObject);
GDIPlus.CheckStatus (status);
endCap = value;
} else
throw new ArgumentException (Locale.GetText ("This Pen object can't be modified."));
}
}
public CustomLineCap CustomStartCap {
get {
return startCap;
}
set {
if (isModifiable) {
Status status = GDIPlus.GdipSetPenCustomStartCap (nativeObject, value.nativeObject);
GDIPlus.CheckStatus (status);
startCap = value;
} else
throw new ArgumentException (Locale.GetText ("This Pen object can't be modified."));
}
}
public DashCap DashCap {
get {
DashCap retval;
Status status = GDIPlus.GdipGetPenDashCap197819 (nativeObject, out retval);
GDIPlus.CheckStatus (status);
return retval;
}
set {
if ((value < DashCap.Flat) || (value > DashCap.Triangle))
throw new InvalidEnumArgumentException ("DashCap", (int)value, typeof (DashCap));
if (isModifiable) {
Status status = GDIPlus.GdipSetPenDashCap197819 (nativeObject, value);
GDIPlus.CheckStatus (status);
} else
throw new ArgumentException (Locale.GetText ("This Pen object can't be modified."));
}
}
public float DashOffset {
get {
float retval;
Status status = GDIPlus.GdipGetPenDashOffset (nativeObject, out retval);
GDIPlus.CheckStatus (status);
return retval;
}
set {
if (isModifiable) {
Status status = GDIPlus.GdipSetPenDashOffset (nativeObject, value);
GDIPlus.CheckStatus (status);
} else
throw new ArgumentException (Locale.GetText ("This Pen object can't be modified."));
}
}
public float [] DashPattern {
get {
int count;
Status status = GDIPlus.GdipGetPenDashCount (nativeObject, out count);
GDIPlus.CheckStatus (status);
float[] pattern;
// don't call GdipGetPenDashArray with a 0 count
if (count > 0) {
pattern = new float [count];
status = GDIPlus.GdipGetPenDashArray (nativeObject, pattern, count);
GDIPlus.CheckStatus (status);
} else if (DashStyle == DashStyle.Custom) {
// special case (not handled inside GDI+)
pattern = new float [1];
pattern[0] = 1.0f;
} else {
pattern = new float [0];
}
return pattern;
}
set {
if (isModifiable) {
int length = value.Length;
if (length == 0)
throw new ArgumentException ("Invalid parameter.");
foreach (float val in value)
if (val <= 0)
throw new ArgumentException ("Invalid parameter.");
Status status = GDIPlus.GdipSetPenDashArray (nativeObject, value, value.Length);
GDIPlus.CheckStatus (status);
} else
throw new ArgumentException (Locale.GetText ("This Pen object can't be modified."));
}
}
public DashStyle DashStyle {
get {
DashStyle retval;
Status status = GDIPlus.GdipGetPenDashStyle (nativeObject, out retval);
GDIPlus.CheckStatus (status);
return retval;
}
set {
if ((value < DashStyle.Solid) || (value > DashStyle.Custom))
throw new InvalidEnumArgumentException ("DashStyle", (int)value, typeof (DashStyle));
if (isModifiable) {
Status status = GDIPlus.GdipSetPenDashStyle (nativeObject, value);
GDIPlus.CheckStatus (status);
} else
throw new ArgumentException (Locale.GetText ("This Pen object can't be modified."));
}
}
public LineCap StartCap {
get {
LineCap retval;
Status status = GDIPlus.GdipGetPenStartCap (nativeObject, out retval);
GDIPlus.CheckStatus (status);
return retval;
}
set {
if ((value < LineCap.Flat) || (value > LineCap.Custom))
throw new InvalidEnumArgumentException ("StartCap", (int)value, typeof (LineCap));
if (isModifiable) {
Status status = GDIPlus.GdipSetPenStartCap (nativeObject, value);
GDIPlus.CheckStatus (status);
} else
throw new ArgumentException (Locale.GetText ("This Pen object can't be modified."));
}
}
public LineCap EndCap {
get {
LineCap retval;
Status status = GDIPlus.GdipGetPenEndCap (nativeObject, out retval);
GDIPlus.CheckStatus (status);
return retval;
}
set {
if ((value < LineCap.Flat) || (value > LineCap.Custom))
throw new InvalidEnumArgumentException ("EndCap", (int)value, typeof (LineCap));
if (isModifiable) {
Status status = GDIPlus.GdipSetPenEndCap (nativeObject, value);
GDIPlus.CheckStatus (status);
} else
throw new ArgumentException (Locale.GetText ("This Pen object can't be modified."));
}
}
public LineJoin LineJoin {
get {
LineJoin result;
Status status = GDIPlus.GdipGetPenLineJoin (nativeObject, out result);
GDIPlus.CheckStatus (status);
return result;
}
set {
if ((value < LineJoin.Miter) || (value > LineJoin.MiterClipped))
throw new InvalidEnumArgumentException ("LineJoin", (int)value, typeof (LineJoin));
if (isModifiable) {
Status status = GDIPlus.GdipSetPenLineJoin (nativeObject, value);
GDIPlus.CheckStatus (status);
} else
throw new ArgumentException (Locale.GetText ("This Pen object can't be modified."));
}
}
public float MiterLimit {
get {
float result;
Status status = GDIPlus.GdipGetPenMiterLimit (nativeObject, out result);
GDIPlus.CheckStatus (status);
return result;
}
set {
if (isModifiable) {
Status status = GDIPlus.GdipSetPenMiterLimit (nativeObject, value);
GDIPlus.CheckStatus (status);
} else
throw new ArgumentException (Locale.GetText ("This Pen object can't be modified."));
}
}
public PenType PenType {
get {
PenType type;
Status status = GDIPlus.GdipGetPenFillType (nativeObject, out type);
GDIPlus.CheckStatus (status);
return type;
}
}
public Matrix Transform {
get {
Matrix matrix = new Matrix ();
Status status = GDIPlus.GdipGetPenTransform (nativeObject, matrix.nativeMatrix);
GDIPlus.CheckStatus (status);
return matrix;
}
set {
if (value == null)
throw new ArgumentNullException ("Transform");
if (isModifiable) {
Status status = GDIPlus.GdipSetPenTransform (nativeObject, value.nativeMatrix);
GDIPlus.CheckStatus (status);
} else
throw new ArgumentException (Locale.GetText ("This Pen object can't be modified."));
}
}
public float Width {
get {
float f;
Status status = GDIPlus.GdipGetPenWidth (nativeObject, out f);
GDIPlus.CheckStatus (status);
return f;
}
set {
if (isModifiable) {
Status status = GDIPlus.GdipSetPenWidth (nativeObject, value);
GDIPlus.CheckStatus (status);
} else
throw new ArgumentException (Locale.GetText ("This Pen object can't be modified."));
}
}
public object Clone ()
{
IntPtr ptr;
Status status = GDIPlus.GdipClonePen (nativeObject, out ptr);
GDIPlus.CheckStatus (status);
Pen p = new Pen (ptr);
p.startCap = startCap;
p.endCap = endCap;
return p;
}
public void Dispose ()
{
Dispose (true);
System.GC.SuppressFinalize (this);
}
private void Dispose (bool disposing)
{
if (disposing && !isModifiable)
throw new ArgumentException (Locale.GetText ("This Pen object can't be modified."));
if (nativeObject != IntPtr.Zero) {
Status status = GDIPlus.GdipDeletePen (nativeObject);
nativeObject = IntPtr.Zero;
GDIPlus.CheckStatus (status);
}
}
~Pen ()
{
Dispose (false);
}
public void MultiplyTransform (Matrix matrix)
{
MultiplyTransform (matrix, MatrixOrder.Prepend);
}
public void MultiplyTransform (Matrix matrix, MatrixOrder order)
{
Status status = GDIPlus.GdipMultiplyPenTransform (nativeObject, matrix.nativeMatrix, order);
GDIPlus.CheckStatus (status);
}
public void ResetTransform ()
{
Status status = GDIPlus.GdipResetPenTransform (nativeObject);
GDIPlus.CheckStatus (status);
}
public void RotateTransform (float angle)
{
RotateTransform (angle, MatrixOrder.Prepend);
}
public void RotateTransform (float angle, MatrixOrder order)
{
Status status = GDIPlus.GdipRotatePenTransform (nativeObject, angle, order);
GDIPlus.CheckStatus (status);
}
public void ScaleTransform (float sx, float sy)
{
ScaleTransform (sx, sy, MatrixOrder.Prepend);
}
public void ScaleTransform (float sx, float sy, MatrixOrder order)
{
Status status = GDIPlus.GdipScalePenTransform (nativeObject, sx, sy, order);
GDIPlus.CheckStatus (status);
}
public void SetLineCap (LineCap startCap, LineCap endCap, DashCap dashCap)
{
if (isModifiable) {
Status status = GDIPlus.GdipSetPenLineCap197819 (nativeObject, startCap, endCap, dashCap);
GDIPlus.CheckStatus (status);
} else
throw new ArgumentException (Locale.GetText ("This Pen object can't be modified."));
}
public void TranslateTransform (float dx, float dy)
{
TranslateTransform (dx, dy, MatrixOrder.Prepend);
}
public void TranslateTransform (float dx, float dy, MatrixOrder order)
{
Status status = GDIPlus.GdipTranslatePenTransform (nativeObject, dx, dy, order);
GDIPlus.CheckStatus (status);
}
}
}
|