You've already forked linux-packaging-mono
523 lines
17 KiB
C#
523 lines
17 KiB
C#
//
|
|
// 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 (value == null)
|
|
throw new ArgumentNullException ("Brush");
|
|
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);
|
|
}
|
|
}
|
|
}
|