Prechádzať zdrojové kódy

Added TARGET_JVM implementation of these classes

svn path=/trunk/mcs/; revision=47955
Andrew Skiba 20 rokov pred
rodič
commit
f353689e88

+ 406 - 0
mcs/class/System.Drawing/System.Drawing/Bitmap.jvm.cs

@@ -0,0 +1,406 @@
+using System;
+using System.IO;
+using System.Drawing.Imaging;
+using System.Runtime.Serialization;
+using java.io;
+using javax.imageio;
+using javax.imageio.stream;
+using javax.imageio.spi;
+
+using BufferedImage = java.awt.image.BufferedImage;
+using JavaImage = java.awt.Image;
+using awt = java.awt;
+using image = java.awt.image;
+
+namespace System.Drawing 
+{
+	public sealed class Bitmap : Image {
+
+		#region constructors
+
+		Bitmap (Bitmap orig):base (orig) {}
+
+		private Bitmap (SerializationInfo info, StreamingContext context) {
+			throw new NotImplementedException ();
+		}
+
+		public Bitmap (int width, int height, Graphics g) {
+			throw new NotImplementedException();			
+		}
+
+		public Bitmap (Image orig, Size newSize)
+			:this (orig, newSize.Width, newSize.Height) {}
+
+		public Bitmap (Image orig, int width, int height)
+			:base (CreateScaledImage (orig, width, height), ImageFormat.Bmp) {}
+
+		public Bitmap (int width, int height) 
+			:this (width, height, PixelFormat.Format32bppArgb) {}
+
+		public Bitmap (Image original) 
+			:this (original, original.Size) {}
+
+		public Bitmap (Stream stream)
+			:this (stream, false) {}
+
+		public Bitmap (string filename) 
+			:this (filename, false) {}
+
+		internal Bitmap (java.awt.Image nativeObject, ImageFormat format)
+			:base (nativeObject, format) {}
+
+		private Bitmap (java.awt.Image nativeObject, ImageFormat format, PixelFormat pixFormat)
+			:this (nativeObject, format) {
+			if (pixFormat != this.PixelFormat)
+				throw new NotImplementedException ("Converting PixelFormat is not implemented yet.");
+		}
+
+		public Bitmap (int width, int height, PixelFormat format)
+			:base (
+				new java.awt.image.BufferedImage (width, height,
+					ToBufferedImageFormat (format)),
+				ImageFormat.Bmp)
+		{
+			//TBD: why the following 3 lines are necessary?
+//			java.awt.Graphics2D graphics2d = NativeObject.createGraphics();
+//			graphics2d.drawImage(NativeObject, 0, 0, null);
+//			graphics2d.dispose();
+		}
+
+		public Bitmap (Stream stream, bool useIcm)
+			:this (stream, null) {}
+
+		public Bitmap (string filename, bool useIcm)
+			//FIXME: useIcm param
+			:this (filename, null) {}
+
+		internal Bitmap (Stream stream, ImageFormat format) {
+			//FIXME: useIcm param
+			//FIXME: use direct ImageInputStream wrapper for NET Stream
+			InputStream jis = vmw.common.IOUtils.ToInputStream (stream);
+            Initialize (new MemoryCacheImageInputStream (jis), format);
+		}
+
+		internal Bitmap (string filename, ImageFormat format) {
+			java.io.File file = vmw.common.IOUtils.getJavaFile (filename);
+			if (!file.exists ())
+				//TBD: check what exception throws NET
+				throw new System.IO.IOException ("File not found: "+filename);
+			Initialize (new FileImageInputStream (file), format);
+		}
+
+		public Bitmap (Type type, string resource) {
+			using (Stream s = type.Assembly.GetManifestResourceStream (resource)) {
+				if (s == null)
+					//TBD: check what type is thrown in MS
+					throw new Exception("Resource name was not found: `" + resource + "'");
+				InputStream jis = vmw.common.IOUtils.ToInputStream (s);
+				Initialize (new MemoryCacheImageInputStream (jis), null);
+			}
+		}
+
+		private void Initialize (ImageInputStream input, ImageFormat format) {
+			if (format != null) {
+				ImageReader r = format.ImageReaderSpi.createReaderInstance ();
+				r.setInput (input);
+				Initialize (r, format);
+			}
+			else {
+				java.util.Iterator iter = ImageIO.getImageReaders (input);
+				if (!iter.hasNext ())
+					throw new ArgumentException ("Format not found"); //TBD: make same text as MS
+
+				//following vars are initialized in the try block
+				string mimeType;
+				javax.imageio.spi.ImageReaderSpi readerSpi;
+				ImageReader r;
+				try {
+					r = (ImageReader) iter.next ();
+					r.setInput (input);
+					readerSpi = r.getOriginatingProvider();
+					mimeType = readerSpi.getMIMETypes() [0];
+				}
+				catch (Exception e) {
+					//TBD: make same text as MS
+					throw new ArgumentException ("Error reading", e);
+				}
+				format = new ImageFormat (mimeType, readerSpi, null);
+				Initialize (r, format);
+			}
+		}
+
+		private void Initialize (ImageReader r, ImageFormat format) {
+			java.awt.Image [] nativeObjects;
+			java.awt.Image [] thumbnails = null;
+			try {
+				nativeObjects = new BufferedImage [r.getNumImages (false)];
+				for (int i = 0; i < nativeObjects.Length; i++) {
+					if (r.hasThumbnails(i)) {
+						if (thumbnails == null)
+							thumbnails = new BufferedImage[nativeObjects.Length];
+
+						thumbnails[i] = r.readThumbnail(i, 0);
+					}
+					nativeObjects [i] = r.read (i);
+				}
+
+			}
+			catch (Exception e) {
+				//TDB: make exception same as in MS
+				throw new ArgumentException ("Error reading", e);
+			}
+			base.Initialize (nativeObjects, thumbnails, format, FrameDimension.Page.Guid);
+		}
+
+#if INTPTR_SUPPORT
+		public Bitmap (int width, int height, int stride, PixelFormat format, IntPtr scan0)
+		{						
+			throw new NotImplementedException();			
+		}
+#endif
+		#endregion
+
+		#region InternalSave
+		protected override void InternalSave (ImageOutputStream output, ImageFormat format) {
+			ImageWriterSpi spi = format.ImageWriterSpi;
+			if (spi == null)
+				spi = ImageFormat.Png.ImageWriterSpi;
+
+			ImageWriter writer = spi.createWriterInstance ();
+			writer.setOutput (output);
+			if (NativeObjectsCount == 1)
+				writer.write (NativeObject);
+			else if (writer.canWriteSequence ())
+				SaveSequence ();
+			else
+				throw new NotImplementedException ();
+		}
+
+		void SaveSequence () {
+			//FIXME: does not supports metadata and thumbnails for now
+			ImageWriter writer = RawFormat.ImageWriterSpi.createWriterInstance ();
+
+			writer.prepareWriteSequence (null);
+
+			for (int i = 0; i < NativeObjectsCount; i++) {
+				IIOImage iio = new IIOImage ((BufferedImage)this[i], null, null);
+				writer.writeToSequence (iio, null);
+			}
+
+			writer.endWriteSequence ();
+		}
+
+		#endregion
+
+		#region private statics: ToBufferedImageFormat, CreateScaledImage
+
+		private static int ToBufferedImageFormat (PixelFormat format) {
+			switch(format) {
+				case PixelFormat.Format16bppGrayScale:
+					return BufferedImage.TYPE_USHORT_GRAY;
+				case PixelFormat.Format1bppIndexed:
+					return BufferedImage.TYPE_BYTE_GRAY;
+				case PixelFormat.Format32bppArgb:
+					return BufferedImage.TYPE_INT_ARGB;
+				case PixelFormat.Format32bppRgb:
+					return BufferedImage.TYPE_INT_RGB;
+				case PixelFormat.Format32bppPArgb:
+					return BufferedImage.TYPE_INT_ARGB_PRE;
+				case PixelFormat.Format16bppRgb555:
+					return BufferedImage.TYPE_USHORT_555_RGB;
+				case PixelFormat.Format16bppRgb565:
+					return BufferedImage.TYPE_USHORT_565_RGB;
+				case PixelFormat.Indexed:
+					return BufferedImage.TYPE_BYTE_INDEXED;
+				default:
+					return 0;
+			}			
+		}
+
+		private static java.awt.Image CreateScaledImage(Image original, int width, int height) {
+			JavaImage oldscaled = original.NativeObject.getScaledInstance(width, height,
+				JavaImage.SCALE_DEFAULT);
+			BufferedImage newimage = new BufferedImage(oldscaled.getWidth(null), 
+				oldscaled.getHeight(null),
+				BufferedImage.TYPE_INT_ARGB);
+			java.awt.Graphics2D graphics2d = newimage.createGraphics();
+			graphics2d.drawImage(oldscaled, 0, 0, null);
+			graphics2d.dispose();
+			return newimage;				
+		}
+		#endregion
+
+		#region Get-SetPixel
+		public Color GetPixel (int x, int y) 
+		{
+
+			int argb = NativeObject.getRGB(x,y);				
+			return Color.FromArgb(argb); 
+		}
+
+		public void SetPixel (int x, int y, Color color)
+		{				
+			int rgb = color.ToArgb();
+			NativeObject.setRGB(x,y,rgb);
+		}
+		#endregion
+
+		#region Clone
+		public override object Clone () {
+			return new Bitmap (this);
+		}
+
+		public Bitmap Clone (Rectangle rect, PixelFormat format)
+		{
+			BufferedImage sub = NativeObject.getSubimage(rect.X,rect.Y,rect.Width,rect.Height);
+			return new Bitmap(sub, RawFormat, format);
+       	}
+		
+		public Bitmap Clone (RectangleF rect, PixelFormat format)
+		{
+			//TODO: check if there is more precise API
+			BufferedImage sub = NativeObject.getSubimage((int)rect.X,(int)rect.Y,(int)rect.Width,(int)rect.Height);
+			return new Bitmap(sub, RawFormat, format);
+		}
+		#endregion
+
+		#region LockBits [TODO]
+		public BitmapData LockBits (Rectangle rect, ImageLockMode flags, PixelFormat format) {
+			throw new NotImplementedException();
+		}
+		#endregion
+
+		#region MakeTransparent
+		public void MakeTransparent ()
+		{
+			Color clr = GetPixel(0,0);			
+			MakeTransparent (clr);
+		}
+
+		public void MakeTransparent (Color transparentColor)
+		{
+			byte A = transparentColor.A;
+			image.WritableRaster raster = NativeObject.getRaster();
+			int numBands  = raster.getNumBands();
+			int maxWidth  = raster.getWidth() + raster.getMinX();
+			int maxHeight = raster.getHeight() + raster.getMinY();
+			int[] srcPix  = new int[numBands];
+
+			for (int y = raster.getMinY(); y < maxHeight; y++) {
+				for (int x = raster.getMinX(); x < maxWidth; x++) {
+					/*srcPix =*/ raster.getPixel(x, y, srcPix);
+					for (int z = 0; z < numBands; z++) {
+						int argb = srcPix[z];
+						if ((uint)argb >> 24 == A) {
+							argb &= 0x00FFFFFF;
+							srcPix[z] = argb;
+						}
+					}
+				}
+			}
+		}
+		#endregion
+
+		#region SetResolution [TODO]
+		public void SetResolution (float xDpi, float yDpi)
+		{
+			throw new NotImplementedException();
+		}
+		#endregion 
+
+		#region UnlockBits [TODO]
+		public void UnlockBits (BitmapData bitmap_data)
+		{
+			throw new NotImplementedException();
+		}
+		#endregion 
+
+		#region NativeObject
+		internal new BufferedImage NativeObject {
+			get {
+				return (BufferedImage)base.NativeObject;
+			}
+		}
+
+		protected override java.awt.Image[] CloneNativeObjects(java.awt.Image[] src) {
+			if (src == null)
+				return null;
+
+			awt.Image[] dst = new awt.Image[src.Length];
+			for (int i = 0; i < dst.Length; i++) {
+				BufferedImage image = src[i] as BufferedImage;
+				if (image == null)
+					throw new ArgumentException(String.Format("Unsupported image type '{0}'", src[i].ToString()), "src");
+
+				dst[i] = new BufferedImage(image.getColorModel(), image.copyData(null), image.isAlphaPremultiplied(), null);
+			}
+
+			return dst;
+		}
+
+		#endregion
+
+		#region InternalPixelFormat
+		protected override PixelFormat InternalPixelFormat {
+			get {
+				int t = NativeObject.getType();
+				switch(t) {
+					case 11://JavaImage.TYPE_USHORT_GRAY:
+						return PixelFormat.Format16bppGrayScale;
+					case 10://JavaImage.TYPE_BYTE_GRAY:
+						return PixelFormat.Format1bppIndexed;				
+					case 1:	//JavaImage.TYPE_INT_RGB
+						return PixelFormat.Format32bppRgb;
+					case 2: //JavaImage.TYPE_INT_ARGB:			
+						return PixelFormat.Format32bppArgb;
+					case 3://JavaImage.TYPE_INT_ARGB_PRE:
+						return PixelFormat.Format32bppPArgb;
+					case 9://JavaImage.TYPE_USHORT_555_RGB:
+						return PixelFormat.Format16bppRgb555;
+					case 8://JavaImage.TYPE_USHORT_565_RGB:
+						return PixelFormat.Format16bppRgb565;
+					case 13://JavaImage.TYPE_BYTE_INDEXED:
+						return PixelFormat.Indexed;
+						//TODO: support this
+					case 12://JavaImage.TYPE_BYTE_BINARY:
+					case 0://JavaImage.TYPE_CUSTOM:
+					case 4://JavaImage.TYPE_INT_BGR:
+					case 5://JavaImage.TYPE_3BYTE_BGR:					
+					case 6://JavaImage.TYPE_4BYTE_ABGR:
+					case 7://JavaImage.TYPE_4BYTE_ABGR_PRE:
+					default:
+						return PixelFormat.Undefined;
+				}			
+			}		
+		}
+		#endregion
+
+#if INTPTR_SUPPORT
+		public static Bitmap FromHicon (IntPtr hicon)
+		{	
+			throw new NotImplementedException();
+		}
+
+		public static Bitmap FromResource (IntPtr hinstance, string bitmapName)	//TODO: Untested
+		{
+			throw new NotImplementedException();
+		}
+
+		public IntPtr GetHbitmap ()
+		{
+			throw new NotImplementedException();
+		}
+
+		public IntPtr GetHbitmap (Color background)
+		{
+			throw new NotImplementedException();
+		}
+
+		public IntPtr GetHicon ()
+		{
+			throw new NotImplementedException();
+		}
+#endif
+
+	}
+}

+ 46 - 0
mcs/class/System.Drawing/System.Drawing/Brush.jvm.cs

@@ -0,0 +1,46 @@
+using System;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Collections;
+
+using awt = java.awt;
+using image = java.awt.image;
+using geom = java.awt.geom;
+
+
+namespace System.Drawing
+{
+	public abstract class Brush : MarshalByRefObject, ICloneable, IDisposable, awt.Paint
+	{
+		protected abstract java.awt.Paint NativeObject {
+			get;
+		}
+
+		awt.PaintContext awt.Paint.createContext (image.ColorModel cm,
+			awt.Rectangle deviceBounds, geom.Rectangle2D userBounds, geom.AffineTransform xform,
+			awt.RenderingHints hints) {
+			return NativeObject.createContext (cm, deviceBounds, userBounds, xform, hints);
+		}
+
+		int awt.Transparency.getTransparency () {
+			return NativeObject.getTransparency ();
+		}
+
+		abstract public object Clone ();
+
+		public void Dispose ()
+		{
+			Dispose (true);
+		}
+
+		protected virtual void Dispose (bool disposing)
+		{
+		}
+
+//		~Brush ()
+//		{
+//			Dispose (false);
+//		}
+	}
+}
+

+ 6 - 0
mcs/class/System.Drawing/System.Drawing/ChangeLog

@@ -1,3 +1,9 @@
+2005-08-03 Andrew Skiba <[email protected]>
+
+	* Image.jvm.cs, StringFormat.jvm.cs, FontFamily.jvm.cs, Bitmap.jvm.cs,
+	Pen.jvm.cs, Region.jvm.cs, Brush.jvm.cs, Graphics.jvm.cs, TextureBrush.jvm.cs,
+	Font.jvm.cs: Added TARGET_JVM implementation
+
 2005-08-03 Andrew Skiba <[email protected]>
 
 	* Rectangle.cs, RectangleF.cs: TARGET_JVM - Add NativeObect property

+ 409 - 0
mcs/class/System.Drawing/System.Drawing/Font.jvm.cs

@@ -0,0 +1,409 @@
+
+using System.Runtime.Serialization;
+using System.Runtime.InteropServices;
+using System.ComponentModel;
+using awt = java.awt;
+using TextAttribute = java.awt.font.TextAttribute;
+
+namespace System.Drawing {
+
+	public sealed class Font: IDisposable	
+	{
+		const int DPI = 72; 
+		private GraphicsUnit gUnit = GraphicsUnit.Point;
+		awt.Font _jFont;
+
+		internal awt.Font NativeObject {
+			get {
+				return _jFont;
+			}
+		}
+
+		public void Dispose()
+		{
+
+		}
+
+       	private Font (SerializationInfo info, StreamingContext context)
+		{
+			
+		}
+		
+
+		// FIXME: add this method when/if there will be resources needed to be disposed
+//		~Font()
+//		{	
+//			
+//		}
+
+		internal float unitConversion(GraphicsUnit fromUnit, GraphicsUnit toUnit, float nSrc)
+		{
+			double inchs = 0;
+			double nTrg = 0;		
+			
+			switch (fromUnit) {
+			case GraphicsUnit.Display:
+				inchs = nSrc / 75f;
+				break;
+			case GraphicsUnit.Document:
+				inchs = nSrc / 300f;
+				break;
+			case GraphicsUnit.Inch:
+				inchs = nSrc;
+				break;
+			case GraphicsUnit.Millimeter:
+				inchs = nSrc / 25.4f;
+				break;
+			case GraphicsUnit.Pixel:				
+			case GraphicsUnit.World:
+				inchs = nSrc / Graphics.DefaultScreenResolution;
+				break;
+			case GraphicsUnit.Point:
+				inchs = nSrc / 72f;
+				break;				
+			default:		
+				throw new ArgumentException("Invalid GraphicsUnit");				
+			}			
+			
+			switch (toUnit) {
+			case GraphicsUnit.Display:
+				nTrg = inchs * 75;
+				break;
+			case GraphicsUnit.Document:
+				nTrg = inchs * 300;
+				break;
+			case GraphicsUnit.Inch:
+				nTrg = inchs;
+				break;
+			case GraphicsUnit.Millimeter:
+				nTrg = inchs * 25.4f;
+				break;
+			case GraphicsUnit.Pixel:				
+			case GraphicsUnit.World:
+				nTrg = inchs * Graphics.DefaultScreenResolution;
+				break;
+			case GraphicsUnit.Point:
+				nTrg = inchs * 72;
+				break;
+			default:	
+				throw new ArgumentException("Invalid GraphicsUnit");				
+			}
+			return (float)nTrg;	
+		}
+
+#if INTPTR_SUPPORT
+		public IntPtr ToHfont ()
+		{
+			throw new NotImplementedException();
+		}
+#endif
+
+		public Font(Font original, FontStyle style)
+		{
+			_jFont = original.NativeObject.deriveFont((int)style);
+		}
+
+		public Font(FontFamily family, float emSize)
+			: this(family, emSize, FontStyle.Regular, GraphicsUnit.Point, (byte)0, false)
+		{
+		}
+
+		public Font(FontFamily family, float emSize, FontStyle style)
+			: this(family, emSize, style, GraphicsUnit.Point, (byte)0, false)
+		{
+		}
+		public Font(FontFamily family, float emSize, GraphicsUnit unit)
+			: this(family, emSize, FontStyle.Regular, unit, (byte)0, false)
+		{
+		}
+
+		public Font(FontFamily family, float emSize, FontStyle style, GraphicsUnit unit)
+			: this(family, emSize, style, unit, (byte)0, false)
+		{
+		}
+
+		public Font(FontFamily family, float emSize, FontStyle style, GraphicsUnit unit, byte charSet)
+			: this(family, emSize, style, unit, charSet, false)
+		{
+		}
+		
+		public Font(FontFamily family, float emSize, FontStyle style, GraphicsUnit unit, byte charSet, bool isVertical)
+			:this(family.Name,emSize,style,unit,charSet,isVertical)
+		{
+		}
+
+		public Font(string familyName, float emSize)
+			: this(familyName, emSize, FontStyle.Regular, GraphicsUnit.Point, (byte)0, false)
+		{
+		}
+
+		public Font(string familyName, float emSize, FontStyle style)
+			: this(familyName, emSize, style, GraphicsUnit.Point, (byte)0, false)
+		{
+		}
+
+		public Font(string familyName, float emSize, GraphicsUnit unit)
+			: this(familyName, emSize, FontStyle.Regular, unit, (byte)0, false)
+		{
+		}
+		
+		public Font(string familyName, float emSize, FontStyle style, GraphicsUnit unit)
+			: this(familyName, emSize, style, unit, (byte)0, false)
+		{
+		}
+		
+		public Font(string familyName, float emSize, FontStyle style, GraphicsUnit unit, byte charSet)
+			: this(familyName, emSize, style, unit, charSet, false)
+		{
+		}
+		
+		public Font(string familyName, float emSize, FontStyle style, GraphicsUnit unit, byte charSet, bool isVertical)			 
+		{
+			//TODO: charset management
+			gUnit = unit;
+			java.util.Hashtable attribs = new java.util.Hashtable();
+			attribs.put(TextAttribute.FAMILY, familyName/*TODO: family doungrade possibility*/);
+			//init defaults
+			attribs.put(TextAttribute.POSTURE, TextAttribute.POSTURE_REGULAR);
+
+			if((style & FontStyle.Bold) != FontStyle.Regular)
+				attribs.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD);
+			if((style & FontStyle.Italic) != FontStyle.Regular)
+				attribs.put(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
+			if((style & FontStyle.Underline) != FontStyle.Regular)
+				attribs.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
+			if((style & FontStyle.Strikeout) != FontStyle.Regular)
+				attribs.put(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON);
+
+			float newSize = unitConversion(gUnit,GraphicsUnit.World,emSize);
+			attribs.put(TextAttribute.SIZE,new java.lang.Float(newSize));
+
+			#region OldStyleSwitch
+			//			switch(style)
+			//			{
+			//				case 0: // '\0'
+			//					attribs.put(TextAttribute.POSTURE, TextAttribute.POSTURE_REGULAR);
+			//					break;
+			//
+			//				case 1: // '\001'
+			//					attribs.put(TextAttribute.WEIGattribs, TextAttribute.WEIGattribs_BOLD);
+			//					break;
+			//
+			//				case 2: // '\002'
+			//					attribs.put(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
+			//					break;
+			//
+			//				case 3: // '\003'
+			//					attribs.put(TextAttribute.WEIGattribs, TextAttribute.WEIGattribs_BOLD);
+			//					attribs.put(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
+			//					break;
+			//
+			//				case 4: // '\004'
+			//					attribs.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
+			//					break;
+			//
+			//				case 5: // '\005'
+			//					attribs.put(TextAttribute.WEIGattribs, TextAttribute.WEIGattribs_BOLD);
+			//					attribs.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
+			//					break;
+			//
+			//				case 6: // '\006'
+			//					attribs.put(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
+			//					attribs.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
+			//					break;
+			//
+			//				case 7: // '\007'
+			//					attribs.put(TextAttribute.WEIGattribs, TextAttribute.WEIGattribs_BOLD);
+			//					attribs.put(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
+			//					attribs.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
+			//					break;
+			//
+			//				case 8: // '\b'
+			//					attribs.put(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON);
+			//					break;
+			//
+			//				case 9: // '\t'
+			//					attribs.put(TextAttribute.WEIGattribs, TextAttribute.WEIGattribs_BOLD);
+			//					attribs.put(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON);
+			//					break;
+			//
+			//				case 10: // '\n'
+			//					attribs.put(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
+			//					attribs.put(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON);
+			//					break;
+			//
+			//				case 11: // '\013'
+			//					attribs.put(TextAttribute.WEIGattribs, TextAttribute.WEIGattribs_BOLD);
+			//					attribs.put(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
+			//					attribs.put(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON);
+			//					break;
+			//
+			//				case 12: // '\f'
+			//					attribs.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
+			//					attribs.put(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON);
+			//					break;
+			//
+			//				case 13: // '\r'
+			//					attribs.put(TextAttribute.WEIGattribs, TextAttribute.WEIGattribs_BOLD);
+			//					attribs.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
+			//					attribs.put(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON);
+			//					break;
+			//
+			//				case 14: // '\016'
+			//					attribs.put(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
+			//					attribs.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
+			//					attribs.put(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON);
+			//					break;
+			//
+			//				case 15: // '\017'
+			//					attribs.put(TextAttribute.WEIGattribs, TextAttribute.WEIGattribs_BOLD);
+			//					attribs.put(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
+			//					attribs.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
+			//					attribs.put(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON);
+			//					break;
+			//
+			//				default:
+			//					attribs.put(TextAttribute.POSTURE, TextAttribute.POSTURE_REGULAR);
+			//					break;
+			//			}
+			#endregion
+			//TODO: units conversion
+			try
+			{
+				_jFont = new awt.Font(attribs);
+			}
+			catch (Exception e)
+			{
+#if DEBUG
+				string mess = e.ToString();
+				Console.WriteLine(mess);
+#endif
+				throw e;
+			}
+		}		
+		
+		public object Clone()
+		{
+			return new Font(this, Style);
+		}
+		
+		
+		
+		public bool Bold {
+			get {
+				return _jFont.isBold();
+			}
+		}
+		
+		
+		public FontFamily FontFamily {
+			get {				
+				return new FontFamily(_jFont.getFamily());
+			}
+		}
+		
+		public byte GdiCharSet {
+			get {
+				throw new NotSupportedException();
+			}
+		}
+		
+		public bool GdiVerticalFont {
+			get {
+				throw new NotSupportedException();
+			}
+		}
+		
+		public int Height {
+			get {
+				awt.Container c = new awt.Container();
+				return c.getFontMetrics(NativeObject).getHeight();
+			}
+		}
+
+		public bool Italic {
+			get {
+				return _jFont.isItalic();
+			}
+		}
+
+		public string Name {
+			get {
+				return _jFont.getName();
+			}
+		}
+
+		public float Size {
+			get {
+				return unitConversion(GraphicsUnit.World,gUnit,_jFont.getSize2D());
+			}
+		}
+
+		
+		public float SizeInPoints {
+			get {
+				return unitConversion(GraphicsUnit.World,GraphicsUnit.Point,_jFont.getSize2D());
+			}
+		}
+
+		
+		public bool Strikeout {
+			get {
+				try
+				{
+					if((java.lang.Boolean)_jFont.getAttributes().get(TextAttribute.STRIKETHROUGH) 
+						== TextAttribute.STRIKETHROUGH_ON )
+						return true;
+				}
+				catch
+				{
+				}
+				return false;
+			}
+		}
+		
+		public FontStyle Style {
+			get {
+				FontStyle style = FontStyle.Regular;
+				if (Bold)
+					style |= FontStyle.Bold;
+				if (Italic)
+					style |= FontStyle.Italic;
+				if (Underline)
+					style |= FontStyle.Underline;
+				if (Strikeout)
+					style |= FontStyle.Strikeout;
+
+				return style;
+			}
+		}
+
+		
+		public bool Underline {
+			get {
+				try
+				{
+					if((java.lang.Integer)_jFont.getAttributes().get(TextAttribute.UNDERLINE) 
+						== TextAttribute.UNDERLINE_ON )
+						return true;
+				}
+				catch
+				{
+				}
+				return false;
+			}
+		}
+
+		[TypeConverter(typeof(FontConverter.FontUnitConverter))]
+		public GraphicsUnit Unit {
+			get {
+				return gUnit;
+			}
+		}
+		
+		public override System.String ToString()
+		{
+			return ("[Font: Name="+ Name +", Size="+ Size+", Style="+ Style  +", Units="+ Unit + "]");			
+		}
+	}
+}

+ 194 - 0
mcs/class/System.Drawing/System.Drawing/FontFamily.jvm.cs

@@ -0,0 +1,194 @@
+//
+// System.Drawing.FontFamily.cs
+//
+// (C) 2005 Mainsoft Corporation (http://www.mainsoft.com)
+// Author: Konstantin Triger ([email protected])
+//
+
+//
+// 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;
+using System.Drawing.Text;
+using System.Text;
+using System.Runtime.InteropServices;
+using System.Globalization;
+using awt = java.awt;
+using geom = java.awt.geom;
+using font = java.awt.font;
+
+namespace System.Drawing {
+
+	public sealed class FontFamily : MarshalByRefObject, IDisposable {
+		
+		static readonly FontFamily _genericMonospace;
+		static readonly FontFamily _genericSansSerif;
+		static readonly FontFamily _genericSerif;
+		static readonly FontCollection _installedFonts;
+
+		static FontFamily() {
+			_installedFonts = new InstalledFontCollection();
+			_genericMonospace = new FontFamily("Monospaced");
+			_genericSansSerif = new FontFamily("SansSerif");
+			_genericSerif = new FontFamily("Serif");
+		}
+		
+		private readonly string _name;
+
+		// this is unavailable through Java API, usually 2048 for TT fonts
+		const int UnitsPerEm = 2048;
+		
+		
+//		~FontFamily()
+//		{	
+//		}
+
+		// dummy ctors to work around convertor problems
+		internal FontFamily() {}
+		internal FontFamily(IntPtr family) {}
+		
+		public FontFamily(string familyName) : this(familyName, null)
+		{}
+
+		public FontFamily(string name, FontCollection fontCollection) {
+			if (fontCollection == null)
+				fontCollection = _installedFonts;
+
+			string familyName = fontCollection.GetFamilyName(name);
+			if (familyName == null)
+				throw new ArgumentException(String.Format("Font family '{0}' not found", name));
+
+			_name = familyName;
+		}
+
+		public FontFamily(GenericFontFamilies genericFamily) {
+			switch(genericFamily) {
+				case GenericFontFamilies.SansSerif:
+					_name = _genericSansSerif._name;
+					break;
+				case GenericFontFamilies.Serif:
+					_name = _genericSerif._name;
+					break;
+				default:
+					_name = _genericMonospace._name;
+					break;
+			}
+		}
+		
+		
+		public string Name {
+			get {
+				return _name;
+			}
+		}
+
+		public static FontFamily[] Families {
+			get {
+				return _installedFonts.Families;
+			}
+		}
+		
+		public static FontFamily GenericMonospace {
+			get {
+				return _genericMonospace;
+			}
+		}
+		
+		public static FontFamily GenericSansSerif {
+			get {
+				return _genericSansSerif;
+			}
+		}
+		
+		public static FontFamily GenericSerif {
+			get {
+				return _genericSerif;
+			}
+		}		
+
+		public override bool Equals(object obj) {
+			if (this == obj)
+				return true;
+
+			if (!(obj is FontFamily))
+				return false;
+
+			return string.Compare(Name, ((FontFamily)obj).Name, true) == 0;
+		}
+
+		awt.FontMetrics GetMetrics(FontStyle style) {
+			awt.Container c = new awt.Container();
+			return c.getFontMetrics(new Font(this, (float)(UnitsPerEm<<1), style, GraphicsUnit.World).NativeObject);
+		}
+
+		public int GetCellAscent(FontStyle style) {
+			return GetMetrics(style).getMaxAscent()>>1;
+		}
+
+		public int GetCellDescent(FontStyle style) {
+			return GetMetrics(style).getMaxDecent()>>1;
+		}
+
+		public int GetEmHeight(FontStyle style) {
+			return UnitsPerEm;
+		}
+
+		public static FontFamily[] GetFamilies(Graphics graphics) {
+			if (graphics == null) {
+				throw new ArgumentNullException("graphics");
+			}
+			return _installedFonts.Families;
+		}
+
+		public override int GetHashCode() {
+			return Name.ToLower().GetHashCode();
+		}
+
+		public int GetLineSpacing(FontStyle style) {
+			return GetMetrics(style).getHeight()>>1;
+		}
+
+		public string GetName(int language) {
+			CultureInfo culture = new CultureInfo(language, false);
+			//TBD: get java locale
+			return new awt.Font(_name, awt.Font.PLAIN, 1).getFamily(null);
+		}
+
+		public bool IsStyleAvailable(FontStyle style) {
+			return (new Font(this, (float)(UnitsPerEm<<1), style, GraphicsUnit.World).Style & style) == style;
+		}
+
+		public override string ToString() {
+			return string.Format("[{0}: Name={1}]", GetType().Name, Name);
+		}
+
+
+
+		#region IDisposable Members
+
+		public void Dispose() {
+			// TODO:  Add FontFamily.Dispose implementation
+		}
+
+		#endregion
+	}
+}
+

+ 1989 - 0
mcs/class/System.Drawing/System.Drawing/Graphics.jvm.cs

@@ -0,0 +1,1989 @@
+using System;
+using System.Drawing.Drawing2D;
+using System.Drawing.Imaging;
+using System.Drawing.Text;
+using System.ComponentModel;
+using System.Runtime.InteropServices;
+using System.Text;
+using awt = java.awt;
+using geom = java.awt.geom;
+
+namespace System.Drawing {
+	[ComVisible(false)]
+	public sealed class Graphics : MarshalByRefObject, IDisposable {
+		#region Variables
+
+		readonly awt.Graphics2D _nativeObject;
+		readonly Image _image;
+
+		static internal readonly bool IsHeadless;
+	
+		#endregion
+
+#if INTPTR_SUPPORT
+		[ComVisible(false)]
+		public delegate bool EnumerateMetafileProc (EmfPlusRecordType recordType,
+							    int flags,
+							    int dataSize,
+							    IntPtr data,
+							    PlayRecordCallback callbackData);
+		[ComVisible (false)]
+			public delegate bool DrawImageAbort (IntPtr callbackData);		
+#endif			
+
+		#region Constr. and Destr.
+		private Graphics (Image image) {
+			_nativeObject = (awt.Graphics2D)image.NativeObject.getGraphics();
+			_image = image;
+
+//			NativeObject.setRenderingHint(awt.RenderingHints.KEY_TEXT_ANTIALIASING,awt.RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
+//
+//							((java.awt.Graphics2D)NativeObject).setRenderingHint(java.awt.RenderingHints.KEY_ANTIALIASING,java.awt.RenderingHints.VALUE_ANTIALIAS_ON);
+//							((java.awt.Graphics2D)NativeObject).setRenderingHint(java.awt.RenderingHints.KEY_STROKE_CONTROL,java.awt.RenderingHints.VALUE_STROKE_NORMALIZE);
+//							((java.awt.Graphics2D)NativeObject).setRenderingHint(java.awt.RenderingHints.KEY_FRACTIONALMETRICS,java.awt.RenderingHints.VALUE_FRACTIONALMETRICS_ON);
+//							((java.awt.Graphics2D)NativeObject).setRenderingHint(java.awt.RenderingHints.KEY_RENDERING,java.awt.RenderingHints.VALUE_RENDER_QUALITY);
+//							((java.awt.Graphics2D)NativeObject).setRenderingHint(java.awt.RenderingHints.KEY_TEXT_ANTIALIASING,java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
+//							//((java.awt.Graphics2D)NativeObject).setRenderingHint(java.awt.RenderingHints.KEY_TEXT_ANTIALIASING,java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
+//							((java.awt.Graphics2D)NativeObject).setComposite(java.awt.AlphaComposite.SrcOver);
+//							((java.awt.Graphics2D)NativeObject).setRenderingHint(java.awt.RenderingHints.KEY_INTERPOLATION,java.awt.RenderingHints.VALUE_INTERPOLATION_BILINEAR);
+//							((java.awt.Graphics2D)NativeObject).setRenderingHint(java.awt.RenderingHints.KEY_ALPHA_INTERPOLATION,java.awt.RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
+//							((java.awt.Graphics2D)NativeObject).setRenderingHint(java.awt.RenderingHints.KEY_DITHERING,java.awt.RenderingHints.VALUE_DITHER_DISABLE);
+//							((java.awt.Graphics2D)NativeObject).setBackground(java.awt.Color.WHITE);
+
+		}
+
+		//		~Graphics ()
+		//		{
+		//			nativeObject.finalize();
+		//		}
+		#endregion
+		
+		#region Internal Accessors
+
+		static Graphics() {
+			bool isHeadless = awt.GraphicsEnvironment.isHeadless();
+			if (!isHeadless) {
+				try {
+					awt.Toolkit.getDefaultToolkit();
+				}
+				catch{
+					isHeadless = true;
+				}
+			}
+
+			IsHeadless = isHeadless;
+		}
+
+		static internal int DefaultScreenResolution {
+			get {
+				return IsHeadless ? 96 :
+					awt.Toolkit.getDefaultToolkit().getScreenResolution();
+			}
+		}
+		
+		internal java.awt.Graphics2D NativeObject {
+			get {
+				return _nativeObject;
+			}
+		}
+		#endregion
+
+		#region FromImage (static accessor)
+		public static Graphics FromImage (Image image) {		
+			return new Graphics(image);
+		}
+		#endregion
+
+		#region Workers [INTERNAL]
+		void InternalSetBrush(Brush b) {
+			java.awt.Graphics2D g = NativeObject;
+			g.setPaint (b);
+			SolidBrush sb = b as SolidBrush;
+			if(sb != null) {
+				g.setColor(sb.Color.NativeObject);
+			}
+			else if(b is LinearGradientBrush) {
+#if DEBUG_GRADIENT_BRUSH
+				if(((LinearGradientBrush)b).dPoints != null)
+				{
+					PointF []pts = ((LinearGradientBrush)b).dPoints;
+					java.awt.Shape s = g.getClip();
+					g.setClip(0,0,99999,99999);
+					g.setPaint(new java.awt.Color(255,0,0));
+					g.drawLine((int)pts[0].X,(int)pts[0].Y,(int)pts[1].X,(int)pts[1].Y);
+					g.setPaint(new java.awt.Color(0,255,0));
+					g.drawLine((int)pts[1].X,(int)pts[1].Y,(int)pts[2].X,(int)pts[2].Y);
+					g.setPaint(new java.awt.Color(255,0,0));
+					g.drawLine((int)pts[2].X,(int)pts[2].Y,(int)pts[3].X,(int)pts[3].Y);
+					g.setPaint(new java.awt.Color(0,255,0));
+					g.drawLine((int)pts[3].X,(int)pts[3].Y,(int)pts[0].X,(int)pts[0].Y);
+					
+					g.setClip(s);
+				}
+#endif
+			}
+		}
+
+		//Ooh. This is exactly where java GeneralPath does not do its job
+		//well. Geometry of strait lines could be completelly missed
+		//Remember: setting stroke to DC works far more better than precreating
+		//stroked shape.
+		//		internal java.awt.Shape ShapeToDraw(Pen pen,java.awt.Shape sh)
+		//		{			
+		//			if(pen != null)
+		//			{
+		//				return pen.NativeObject.createStrokedShape(sh);
+		//			}
+		//			return sh;
+		//		}
+
+		internal void DrawShape(Graphics g,Pen pen,java.awt.Shape sh) {
+			DrawShape(g,pen,sh,true);
+		}
+
+		internal void DrawShape(Graphics g,Pen pen,java.awt.Shape sh,bool fSetStroke) {
+			java.awt.Graphics2D ng = NativeObject;
+			java.awt.Stroke bs = ng.getStroke();
+			if(pen != null) {
+				Color c = pen.Color;
+				//ng.setColor(new java.awt.Color(c.R,c.G,c.B,c.A));
+				ng.setPaint((awt.Paint)pen.Brush);
+				if(fSetStroke)
+					//ng.draw(ShapeToDraw(pen,sh));
+					ng.setStroke(pen.NativeObject);
+			}
+			ng.draw(/*ShapeToDraw(pen,*/sh/*)*/);
+			ng.setStroke(bs);
+		}
+
+		void FillShape(Brush brush,java.awt.Shape sh) {
+			InternalSetBrush(brush);
+			NativeObject.fill(sh);
+		}
+
+		internal SizeF MeasureDraw (string s, Font font, Brush brush, RectangleF layoutRectangle, StringFormat format, bool fDraw) {			
+			SizeF retVal = new SizeF(0,0);
+			awt.Graphics2D g = NativeObject;
+				
+			java.awt.Font fnt = font.NativeObject;
+			if(s != null && s.Length != 0 && fnt != null) {
+				float size = fnt.getSize();
+				float wid = layoutRectangle.Width;
+				float hei = layoutRectangle.Height;
+				float x = layoutRectangle.X;
+				float y = layoutRectangle.Y;
+				java.text.AttributedString astr = new java.text.AttributedString(s);
+				astr.addAttribute(java.awt.font.TextAttribute.FONT, fnt);
+				java.text.AttributedCharacterIterator prg = astr.getIterator();
+				java.awt.font.TextLayout textlayout = new java.awt.font.TextLayout(prg, g.getFontRenderContext());
+				int prgStart = prg.getBeginIndex();
+				int prgEnd = prg.getEndIndex();
+				java.awt.font.LineBreakMeasurer lineMeasurer = new java.awt.font.LineBreakMeasurer(
+					prg, new java.awt.font.FontRenderContext(null, false, false));
+				lineMeasurer.setPosition(prgStart);
+				float formatWidth = wid;
+				
+				//some vertical layout magic - should be reviewed
+				//				if(format != null)
+				//				{
+				//					StringFormatFlags formatflag = format.FormatFlags;
+				//					if(formatflag != StringFormatFlags.DirectionVertical)
+				//					{
+				//						if(size > (float)8 && wid > (float)13)
+				//							formatWidth = wid - (float)12;
+				//						if(formatflag ==  StringFormatFlags.DirectionRightToLeft && size == (float)6)
+				//							formatWidth = wid - (float)10;
+				//					}
+				//				}
+
+				//now calculate number of lines and full layout height
+				//this is required for LineAlignment calculations....
+				int lines=0;
+				float layHeight=0;
+				float layPrevHeight=0;
+				float layWidth=0;
+				float drawPosY = y;
+				//bool fSkipLastLine = false;
+				java.awt.font.TextLayout layout;
+				java.awt.geom.Rectangle2D bnds = new java.awt.geom.Rectangle2D.Float();
+				while(lineMeasurer.getPosition() < prgEnd) {
+					layout = lineMeasurer.nextLayout(formatWidth);
+					lines++;
+					bnds = bnds.createUnion(layout.getBounds());
+					layPrevHeight = layHeight;
+					layHeight += layout.getDescent() + layout.getLeading() + layout.getAscent();
+					float advance;
+					if((format != null) && 
+						((format.FormatFlags & StringFormatFlags.MeasureTrailingSpaces) != 0))
+						advance = layout.getAdvance();
+					else
+						advance = layout.getVisibleAdvance();
+					if(layWidth < advance)
+						layWidth = advance;
+					if((format != null) && ((format.FormatFlags & StringFormatFlags.NoWrap) != 0))
+						break;
+				}
+				//Overhanging parts of glyphs, and unwrapped text reaching outside 
+				//the formatting rectangle are allowed to show. By default all text 
+				//and glyph parts reaching outside the formatting rectangle are clipped.
+				if((lines == 1) && 
+					(format != null) && 
+					((format.FormatFlags & StringFormatFlags.NoClip) != 0)) {
+					formatWidth = layWidth;					
+				}
+
+				//Only entire lines are laid out in the formatting rectangle. By default layout 
+				//continues until the end of the text, or until no more lines are visible as a 
+				//result of clipping, whichever comes first. Note that the default settings allow 
+				//the last line to be partially obscured by a formatting rectangle that is not a 
+				//whole multiple of the line height. To ensure that only whole lines are seen, specify
+				//this value and be careful to provide a formatting rectangle at least as tall as the 
+				//height of one line.
+				if(format != null && ((format.FormatFlags & StringFormatFlags.LineLimit) != 0) && 
+					layHeight > hei && layPrevHeight < hei) {
+					layHeight = layPrevHeight;
+					lines--;
+				}
+
+				retVal.Height = layHeight;
+				retVal.Width = layWidth+size/2.5f;
+				if(!fDraw)
+					return retVal;
+
+				InternalSetBrush(brush);
+
+				//end measurment
+
+				//for draw we should probably update origins
+
+				//Vertical...
+				if(format != null) {
+					StringAlignment align = format.LineAlignment;
+					if(align == StringAlignment.Center) {
+						drawPosY = y + (float)hei/2 - layHeight/2;
+					}
+					else if(align == StringAlignment.Far) {
+						drawPosY = (float)y + (float)hei - layHeight;
+					}
+					//in both cases if string is not fit - switch to near
+					if(drawPosY < y)
+						drawPosY = y;
+				}
+
+				//Horisontal... on the fly
+				lineMeasurer.setPosition(prgStart);
+				float drawPosX = x;				
+				for(int line = 0;line < lines /*lineMeasurer.getPosition() < prgEnd*/;line++, drawPosY += layout.getDescent() + layout.getLeading()) {
+					layout = lineMeasurer.nextLayout(formatWidth);
+					drawPosX = x + size / (float)5;//???
+					drawPosY += layout.getAscent();
+					if(format != null) {
+						float advance;
+						if((format.FormatFlags & StringFormatFlags.MeasureTrailingSpaces) != 0)
+							advance = layout.getAdvance();
+						else
+							advance = layout.getVisibleAdvance();
+						
+						if(format.Alignment == StringAlignment.Center) {
+							drawPosX = (float)((double)x + ((double)formatWidth)/2 - advance/2);
+						}
+						else if(format.Alignment == StringAlignment.Far) {
+							drawPosX = (float)(drawPosX + formatWidth) - advance;
+						}
+						if((format.FormatFlags & StringFormatFlags.DirectionVertical ) != 0) {
+							java.awt.geom.AffineTransform at1 = java.awt.geom.AffineTransform.getTranslateInstance(
+								drawPosX +  size / (float)5, (drawPosY - layout.getAscent()) + size / (float)5);
+
+							at1.rotate(Math.PI/2);
+							awt.Shape sha = textlayout.getOutline(at1);
+							//g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+							g.fill(sha);
+							continue;
+						}
+						if((format.FormatFlags & StringFormatFlags.DirectionRightToLeft)  != 0) {
+							drawPosX = ((drawPosX + formatWidth) - advance) + (float)9;
+							layout.draw(g, drawPosX, drawPosY);
+						} 
+					}					
+					//Draw current line
+					layout.draw(g, drawPosX, drawPosY);					
+				}
+			} //not nulls
+
+			return retVal;
+		}
+		#endregion
+
+		#region Dispose
+		public void Dispose() {			
+			NativeObject.dispose();
+		}
+		#endregion
+		
+		#region Clear
+		public void Clear (Color color) {
+			java.awt.Graphics2D g = NativeObject;
+			g.setColor(new java.awt.Color(color.R,color.G,color.B,color.A));			
+			g.fillRect(0,0,_image.Width,_image.Height);			
+		}
+		#endregion
+
+		#region DrawArc
+		public void DrawArc (Pen pen, Rectangle rect, float startAngle, float sweepAngle) {
+			DrawArc (pen, 
+				rect.X, 
+				rect.Y, 
+				rect.Width, 
+				rect.Height, 
+				startAngle, 
+				sweepAngle);
+		}
+
+		
+		public void DrawArc (Pen pen, RectangleF rect, float startAngle, float sweepAngle) {
+			DrawArc (pen, 
+				rect.X, 
+				rect.Y, 
+				rect.Width, 
+				rect.Height, 
+				startAngle, 
+				sweepAngle);
+		}
+
+		public void DrawArc (Pen pen, int x, int y, int width, int height, int startAngle, int sweepAngle) {
+			DrawArc(pen,
+				(float)x,
+				(float)y,
+				(float)width,
+				(float)height,
+				(float)startAngle,
+				(float)sweepAngle);
+		}
+
+		public void DrawArc (Pen pen, float x, float y, float width, float height, float startAngle, float sweepAngle) {
+			if (sweepAngle >= 360) {
+				DrawEllipse(pen, x, y, width, height);
+				return;
+			}
+
+			double d1Tod2 = width/height;
+			double sqrd1Tod2 = d1Tod2*d1Tod2;
+			float start = (float)ConvertArcAngle(sqrd1Tod2, startAngle);
+			float extent = (float)ConvertArcAngle(sqrd1Tod2, startAngle+sweepAngle) - start;
+			DrawShape(this,pen,
+				new java.awt.geom.Arc2D.Float(x,y,width,height,-start,-extent,java.awt.geom.Arc2D.OPEN));
+		}
+
+		/// <summary>
+		/// .Net computes an angle by intersection of ellipse with a ray
+		/// java does the following: x1 = d1*cos(a), y1 = d2*sin(a)
+		/// where: d1 = width/2, d2 = height/2
+		/// we need to find angle x, which satisfies:
+		/// x1 = m*cos(a) = d1*cos(x)
+		/// y1 = m*sin(a) = d2*sin(x)
+		/// (x1*x1)/(d1*d1) + (x2*x2)/(d2*d2) = 1
+		/// </summary>
+		/// <param name="sqrd1Tod2">(d1/d2)*(d1/d2)</param>
+		/// <param name="angle">angle in degrees</param>
+		/// <returns>converted angle in degrees</returns>
+		static double ConvertArcAngle(double sqrd1Tod2, double angle) {
+			double angleRad = java.lang.Math.toRadians(angle);
+			double tan = Math.Tan(angleRad);
+			double cosx = 1/Math.Sqrt( sqrd1Tod2 * (tan*tan) + 1);
+			double xRad = Math.Acos(cosx);
+			double x = java.lang.Math.toDegrees(xRad);
+			int q = ((int)angle)/90;
+
+			switch (q&3) {
+				default:
+					return x;
+				case 1:
+					return 180-x;
+				case 2:
+					return 180+x;
+				case 3:
+					return 360-x;
+			}
+		}
+		#endregion
+
+		#region DrawBezier(s)
+		public void DrawBezier (Pen pen, PointF pt1, PointF pt2, PointF pt3, PointF pt4) {
+			DrawBezier(pen, pt1.X, pt1.Y, pt2.X, pt2.Y, pt3.X, pt3.Y, pt4.X, pt4.Y);
+		}
+
+		public void DrawBezier (Pen pen, Point pt1, Point pt2, Point pt3, Point pt4) {
+			DrawBezier(pen, pt1.X, pt1.Y, pt2.X, pt2.Y, pt3.X, pt3.Y, pt4.X, pt4.Y);
+		}
+
+		public void DrawBezier (Pen pen, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4) {
+			geom.GeneralPath path = new geom.GeneralPath();
+			path.moveTo(x1,y1);
+			path.curveTo(x2,y2,x3,y3,x4,y4);
+			DrawShape(this,pen,path);
+		}
+
+		public void DrawBeziers (Pen pen, Point [] points) {
+			int length = points.Length-1;
+			if (length < 3)
+				return;
+
+			for (int i = 0; i < length; i += 3) {
+				DrawBezier(pen,	
+					points [i].X,points [i].Y,
+					points [i+1].X,points [i+1].Y,
+					points [i+2].X,points [i+2].Y,
+					points [i+3].X,points [i+3].Y);
+			}
+		}
+
+		public void DrawBeziers (Pen pen, PointF [] points) {
+			int length = points.Length-1;
+			if (length < 3)
+				return;
+
+			for (int i = 0; i < length; i += 3) {
+				DrawBezier(pen,	
+					points [i].X,points [i].Y,
+					points [i+1].X,points [i+1].Y,
+					points [i+2].X,points [i+2].Y,
+					points [i+3].X,points [i+3].Y);
+			}
+		}
+		#endregion 
+
+		#region DrawClosedCurve [TODO]
+		public void DrawClosedCurve (Pen pen, PointF [] points) {
+			DrawClosedCurve(pen, points, 0.5f, FillMode.Alternate);
+		}
+		
+		public void DrawClosedCurve (Pen pen, Point [] points) {
+			DrawClosedCurve(pen, points, 0.5f, FillMode.Alternate);
+		}
+ 			
+		public void DrawClosedCurve (Pen pen, Point [] points, float tension, FillMode fillmode) {
+			//TBD: provide a correct implementation
+			DrawPolygon(pen, points);
+		}
+		
+		public void DrawClosedCurve (Pen pen, PointF [] points, float tension, FillMode fillmode) {
+			//TBD: provide a correct implementation
+			DrawPolygon(pen, points);
+		}
+		#endregion
+
+		#region DrawCurve [TODO]
+		public void DrawCurve (Pen pen, Point [] points) {
+			DrawCurve(pen, points, 0.5f);
+		}
+		
+		public void DrawCurve (Pen pen, PointF [] points) {
+			DrawCurve(pen, points, 0.5f);
+		}
+		
+		public void DrawCurve (Pen pen, PointF [] points, float tension) {
+			DrawCurve(pen, points, 0, points.Length-1, tension);
+		}
+		
+		public void DrawCurve (Pen pen, Point [] points, float tension) {
+			DrawCurve(pen, points, 0, points.Length-1, tension);
+		}
+		
+		
+		public void DrawCurve (Pen pen, PointF [] points, int offset, int numberOfSegments) {
+			DrawCurve(pen, points, offset, numberOfSegments, 0.5f);
+		}
+
+		public void DrawCurve (Pen pen, Point [] points, int offset, int numberOfSegments, float tension) {
+			//TBD: provide a correct implementation
+			Point[] pts = new Point[numberOfSegments+1];
+			Array.Copy(points, offset, pts, 0, pts.Length);
+			DrawLines(pen, pts);
+		}
+
+		
+		public void DrawCurve (Pen pen, PointF [] points, int offset, int numberOfSegments, float tension) {
+			//TBD: provide a correct implementation
+			PointF[] pts = new PointF[numberOfSegments+1];
+			Array.Copy(points, offset, pts, 0, pts.Length);
+			DrawLines(pen, pts);
+		}
+		#endregion
+
+		#region DrawEllipse
+		public void DrawEllipse (Pen pen, Rectangle rect) {
+			DrawEllipse (pen, rect.X, rect.Y, rect.Width, rect.Height);
+		}
+
+		public void DrawEllipse (Pen pen, RectangleF rect) {
+			DrawEllipse (pen, rect.X, rect.Y, rect.Width, rect.Height);
+		}
+
+		public void DrawEllipse (Pen pen, int x, int y, int width, int height) {
+			DrawEllipse(pen,(float)x,(float)y,(float)width,(float)height);
+		}
+
+		public void DrawEllipse (Pen pen, float x, float y, float width, float height) {
+			DrawShape(this,pen,new java.awt.geom.Ellipse2D.Float(x,y,width,height));
+		}
+		#endregion
+
+		#region DrawIcon
+		public void DrawIcon (Icon icon, Rectangle targetRect) {
+			Bitmap b = icon.ToBitmap ();
+			this.DrawImage (b, targetRect);
+		}
+
+		public void DrawIcon (Icon icon, int x, int y) {
+			Bitmap b = icon.ToBitmap ();
+			this.DrawImage (b, x, y);
+		}
+
+		public void DrawIconUnstretched (Icon icon, Rectangle targetRect) {
+			Bitmap b = icon.ToBitmap ();
+			this.DrawImageUnscaled (b, targetRect);
+		}
+		#endregion
+
+		#region DrawImage
+		public void DrawImage (Image image, RectangleF rect) {
+			geom.AffineTransform at = geom.AffineTransform.getTranslateInstance(rect.X, rect.Y);
+			at.scale(rect.Width/image.Width, rect.Height/image.Height);
+			NativeObject.drawImage(image.NativeObject,at,null);
+		}
+
+		
+		public void DrawImage (Image image, PointF point) {
+			geom.AffineTransform at = geom.AffineTransform.getTranslateInstance(point.X, point.Y);
+			NativeObject.drawImage(image.NativeObject,at,null);
+		}
+
+		
+		public void DrawImage (Image image, Point [] destPoints) {
+			Matrix m = new Matrix(new Rectangle(0, 0, image.Width, image.Height), destPoints);
+			NativeObject.drawImage(image.NativeObject,m.NativeObject,null);
+		}
+
+		
+		public void DrawImage (Image image, Point point) {
+			java.awt.Graphics2D g = NativeObject;
+			g.drawImage(image.NativeObject,point.X,point.Y,null);
+		}
+
+		
+		public void DrawImage (Image image, Rectangle rect) {
+			java.awt.Graphics2D g = NativeObject;
+			g.drawImage(image.NativeObject,rect.X,rect.Y,rect.Width,rect.Height,null);
+		}
+
+		
+		public void DrawImage (Image image, PointF [] destPoints) {
+			Matrix m = new Matrix(new RectangleF(0, 0, image.Width, image.Height), destPoints);
+			NativeObject.drawImage(image.NativeObject,m.NativeObject,null);
+		}
+
+		
+		public void DrawImage (Image image, int x, int y) {
+			java.awt.Graphics2D g =  NativeObject;
+			g.drawImage(image.NativeObject,x,y,null);
+		}
+
+		
+		public void DrawImage (Image image, float x, float y) {
+			java.awt.Graphics2D g = NativeObject;
+			g.drawImage(image.NativeObject,(int)x,(int)y,null);
+		}
+
+		
+		public void DrawImage (Image image, Rectangle destRect, Rectangle srcRect, GraphicsUnit srcUnit) {
+			//TODO:GraficsUnit
+			java.awt.Graphics2D g = NativeObject;
+			g.drawImage(image.NativeObject,destRect.X,destRect.Y,destRect.Width,destRect.Height,srcRect.X,srcRect.Y,srcRect.Width,srcRect.Height,null);
+		}
+		
+		public void DrawImage (Image image, RectangleF destRect, RectangleF srcRect, GraphicsUnit srcUnit) {			
+			//TODO:GraficsUnit
+			java.awt.Graphics2D g = NativeObject;
+			g.drawImage(image.NativeObject,
+				(int)destRect.X,
+				(int)destRect.Y,
+				(int)destRect.X + (int)destRect.Width,
+				(int)destRect.Y + (int)destRect.Height,
+				(int)srcRect.X,
+				(int)srcRect.Y,
+				(int)srcRect.X + (int)srcRect.Width,
+				(int)srcRect.Y + (int)srcRect.Height,
+				null);
+		}
+
+		
+		public void DrawImage (Image image, Point [] destPoints, Rectangle srcRect, GraphicsUnit srcUnit) {
+			DrawImage(image, destPoints, srcRect, srcUnit, null);
+		}
+
+		
+		public void DrawImage (Image image, PointF [] destPoints, RectangleF srcRect, GraphicsUnit srcUnit) {
+			
+			DrawImage(image, destPoints, srcRect, srcUnit, null);
+		}
+
+		
+		public void DrawImage (Image image, Point [] destPoints, Rectangle srcRect, GraphicsUnit srcUnit, 
+			ImageAttributes imageAttr) {
+			//TBD: GraphicsUnit, ImageAttributes
+			Matrix m = new Matrix(srcRect, destPoints);
+			NativeObject.drawImage(image.NativeObject,m.NativeObject,null);
+		}
+		
+		public void DrawImage (Image image, float x, float y, float width, float height) {
+			java.awt.Graphics2D g = NativeObject;
+			g.drawImage(image.NativeObject,(int)x,(int)y,(int)width,(int)height,null);
+		}
+
+		
+		public void DrawImage (Image image, PointF [] destPoints, RectangleF srcRect, GraphicsUnit srcUnit, 
+			ImageAttributes imageAttr) {
+			//TBD: GraphicsUnit, ImageAttributes
+			Matrix m = new Matrix(srcRect, destPoints);
+			NativeObject.drawImage(image.NativeObject,m.NativeObject,null);
+		}
+
+		
+		public void DrawImage (Image image, int x, int y, Rectangle srcRect, GraphicsUnit srcUnit) {			
+			//TODO:units
+			java.awt.Graphics2D g = NativeObject;
+			g.drawImage(image.NativeObject,x,y,srcRect.Width,srcRect.Height,srcRect.X,srcRect.Y,srcRect.Width,srcRect.Height,null);
+		}
+		
+		public void DrawImage (Image image, int x, int y, int width, int height) {
+			java.awt.Graphics2D g = NativeObject;
+			g.drawImage(image.NativeObject,x,y,width,height,null);
+		}
+
+		public void DrawImage (Image image, float x, float y, RectangleF srcRect, GraphicsUnit srcUnit) {	
+			//TODO:units,casts
+			java.awt.Graphics2D g = NativeObject;
+			g.drawImage(image.NativeObject,
+				(int)x,
+				(int)y,
+				(int)srcRect.Width,
+				(int)srcRect.Height,
+				(int)srcRect.X,
+				(int)srcRect.Y,
+				(int)srcRect.Width,
+				(int)srcRect.Height,null);
+		}
+
+#if INTPTR_SUPPORT
+		public void DrawImage (Image image, PointF [] destPoints, RectangleF srcRect, GraphicsUnit srcUnit, ImageAttributes imageAttr, DrawImageAbort callback)
+		{
+			throw new NotImplementedException();
+		}
+
+		
+		public void DrawImage (Image image, Point [] destPoints, Rectangle srcRect, GraphicsUnit srcUnit, ImageAttributes imageAttr, DrawImageAbort callback)
+		{
+			
+			throw new NotImplementedException();
+		}
+
+		
+		public void DrawImage (Image image, Point [] destPoints, Rectangle srcRect, GraphicsUnit srcUnit, ImageAttributes imageAttr, DrawImageAbort callback, int callbackData)
+		{
+			throw new NotImplementedException();
+		}
+#endif
+		
+		public void DrawImage (Image image, Rectangle destRect, float srcX, float srcY, float srcWidth, float srcHeight, GraphicsUnit srcUnit) {
+			//TODO:units
+			java.awt.Graphics2D g = NativeObject;
+			g.drawImage(image.NativeObject,
+				(int)destRect.X,
+				(int)destRect.Y,
+				(int)destRect.Width,
+				(int)destRect.Height,
+				(int)srcX,
+				(int)srcY,
+				(int)srcWidth,
+				(int)srcHeight,null);
+		}
+		
+#if INTPTR_SUPPORT		
+		public void DrawImage (Image image, PointF [] destPoints, RectangleF srcRect, GraphicsUnit srcUnit, ImageAttributes imageAttr, DrawImageAbort callback, int callbackData)
+		{
+			throw new NotImplementedException();
+		}
+#endif
+		
+		public void DrawImage (Image image, Rectangle destRect, int srcX, int srcY, int srcWidth, int srcHeight, GraphicsUnit srcUnit) {
+			//TODO:units
+			java.awt.Graphics2D g = NativeObject;
+			g.drawImage(image.NativeObject,destRect.X,destRect.Y,destRect.Width,destRect.Height,srcX,srcY,srcWidth,srcHeight,null);
+		}
+
+		
+		public void DrawImage (Image image, Rectangle destRect, float srcX, float srcY, float srcWidth, float srcHeight, GraphicsUnit srcUnit, ImageAttributes imageAttrs) {
+			//TODO:units
+			java.awt.Graphics2D g = NativeObject;
+			g.drawImage(image.NativeObject,
+				(int)destRect.X,
+				(int)destRect.Y,
+				(int)destRect.Width,
+				(int)destRect.Height,
+				(int)srcX,
+				(int)srcY,
+				(int)srcWidth,
+				(int)srcHeight,null);
+		}
+		
+		public void DrawImage (Image image, Rectangle destRect, int srcX, int srcY, int srcWidth, int srcHeight, GraphicsUnit srcUnit, ImageAttributes imageAttr) {			
+			//TODO:units,attributes
+			java.awt.Graphics2D g = NativeObject;
+			g.drawImage(image.NativeObject,
+				destRect.X,
+				destRect.Y,
+				destRect.X + destRect.Width,
+				destRect.Y+destRect.Height,
+				srcX,
+				srcY,
+				srcX+srcWidth,
+				srcX+srcHeight,null);
+		}
+		
+#if INTPTR_SUPPORT		
+		public void DrawImage (Image image, Rectangle destRect, int srcX, int srcY, int srcWidth, int srcHeight, GraphicsUnit srcUnit, ImageAttributes imageAttr, DrawImageAbort callback)
+		{
+			//TODO:units,attributes, callback
+			java.awt.Graphics2D g = (java.awt.Graphics2D)nativeObject;
+			g.drawImage(image.NativeObject,destRect.X,destRect.Y,destRect.Width,destRect.Height,srcX,srcY,srcWidth,srcHeight,null);
+		}
+		
+		public void DrawImage (Image image, Rectangle destRect, float srcX, float srcY, float srcWidth, float srcHeight, GraphicsUnit srcUnit, ImageAttributes imageAttr, DrawImageAbort callback)
+		{
+			//TODO:units,attributes, callback
+			java.awt.Graphics2D g = (java.awt.Graphics2D)nativeObject;
+			g.drawImage(image.NativeObject,
+				(int)destRect.X,
+				(int)destRect.Y,
+				(int)destRect.Width,
+				(int)destRect.Height,
+				(int)srcX,
+				(int)srcY,
+				(int)srcWidth,
+				(int)srcHeight,null);
+		}
+
+		public void DrawImage (Image image, Rectangle destRect, float srcX, float srcY, float srcWidth, float srcHeight, GraphicsUnit srcUnit, ImageAttributes imageAttr, DrawImageAbort callback, IntPtr callbackData)
+		{
+			//TODO:units,attributes, callback
+			java.awt.Graphics2D g = (java.awt.Graphics2D)nativeObject;
+			g.drawImage(image.NativeObject,
+				(int)destRect.X,
+				(int)destRect.Y,
+				(int)destRect.Width,
+				(int)destRect.Height,
+				(int)srcX,
+				(int)srcY,
+				(int)srcWidth,
+				(int)srcHeight,null);
+		}
+		
+		public void DrawImage (Image image, Rectangle destRect, int srcX, int srcY, int srcWidth, int srcHeight, GraphicsUnit srcUnit, ImageAttributes imageAttr, DrawImageAbort callback, IntPtr callbackData)
+		{
+			//TODO:units,attributes, callback
+			java.awt.Graphics2D g = (java.awt.Graphics2D)nativeObject;
+			g.drawImage(image.NativeObject,
+				destRect.X,
+				destRect.Y,
+				destRect.Width,
+				destRect.Height,
+				srcX,
+				srcY,
+				srcWidth,
+				srcHeight,null);
+		}		
+#endif
+		
+		public void DrawImageUnscaled (Image image, Point point) {
+			DrawImageUnscaled (image, point.X, point.Y);
+		}
+		
+		public void DrawImageUnscaled (Image image, Rectangle rect) {
+			DrawImageUnscaled (image, rect.X, rect.Y, rect.Width, rect.Height);
+		}
+		
+		public void DrawImageUnscaled (Image image, int x, int y) {
+			DrawImage (image, x, y, image.Width, image.Height);
+		}
+
+		public void DrawImageUnscaled (Image image, int x, int y, int width, int height) {
+			Image tmpImg = new Bitmap (width, height);
+			Graphics g = FromImage (tmpImg);
+			g.DrawImage (image, 0, 0, image.Width, image.Height);
+			this.DrawImage (tmpImg, x, y, width, height);
+			tmpImg.Dispose ();
+			g.Dispose ();		
+		}
+		#endregion
+
+		#region DrawLine
+		public void DrawLine (Pen pen, PointF pt1, PointF pt2) {
+			DrawLine(pen,pt1.X,pt1.Y,pt2.X,pt2.Y);
+		}
+
+		public void DrawLine (Pen pen, Point pt1, Point pt2) {
+			DrawLine(pen,(float)pt1.X,(float)pt1.Y,(float)pt2.X,(float)pt2.Y);
+		}
+
+		public void DrawLine (Pen pen, int x1, int y1, int x2, int y2) {
+			DrawLine(pen,(float)x1,(float)y1,(float)x2,(float)y2);
+		}
+
+		public void DrawLine (Pen pen, float x1, float y1, float x2, float y2) {
+			DrawShape(this,pen,new java.awt.geom.Line2D.Float(x1,y1,x2,y2));
+		}
+
+		public void DrawLines (Pen pen, PointF [] points) {
+			if(points.Length < 2)
+				return;
+			for(int i = 0;i<points.Length-1;i++)
+				DrawLine(pen,points[i].X,points[i].Y,points[i+1].X,points[i+1].Y);
+		}
+
+		public void DrawLines (Pen pen, Point [] points) {
+			for(int i = 0;i<points.Length-1;i++)
+				DrawLine(pen,points[i].X,points[i].Y,points[i+1].X,points[i+1].Y);
+		}
+		#endregion
+
+		#region DrawPath
+		public void DrawPath (Pen pen, GraphicsPath path) {
+			DrawShape(this,pen,path.NativeObject,true);
+		}
+		#endregion
+		
+		#region DrawPie
+		public void DrawPie (Pen pen, Rectangle rect, float startAngle, float sweepAngle) {
+			DrawPie (pen, rect.X, rect.Y, rect.Width, rect.Height, startAngle, sweepAngle);
+		}
+		
+		public void DrawPie (Pen pen, RectangleF rect, float startAngle, float sweepAngle) {
+			DrawPie (pen, rect.X, rect.Y, rect.Width, rect.Height, startAngle, sweepAngle);
+		}
+		
+		public void DrawPie (Pen pen, float x, float y, float width, float height, float startAngle, float sweepAngle) {
+			if (sweepAngle >= 360) {
+				DrawEllipse(pen, x, y, width, height);
+				return;
+			}
+
+			double d1Tod2 = width/height;
+			double sqrd1Tod2 = d1Tod2*d1Tod2;
+			float start = (float)ConvertArcAngle(sqrd1Tod2, startAngle);
+			float extent = (float)ConvertArcAngle(sqrd1Tod2, startAngle+sweepAngle) - start;
+
+			DrawShape(this,pen,new java.awt.geom.Arc2D.Float(x,y,width,height,-start,-extent,java.awt.geom.Arc2D.PIE));
+		}
+		
+		public void DrawPie (Pen pen, int x, int y, int width, int height, int startAngle, int sweepAngle) {
+			DrawPie(pen,(float)x,(float)y,(float)width,(float)height,(float)startAngle,(float)sweepAngle);
+		}
+		#endregion
+
+		#region DrawPolygon
+		public void DrawPolygon (Pen pen, Point [] points) {
+			if(points.Length < 1)
+				return;
+			java.awt.geom.GeneralPath path = new java.awt.geom.GeneralPath();
+			path.moveTo((float)points[0].X,(float)points[0].Y);
+			for(int i = points.Length - 1; i >= 0; i--)
+				path.lineTo(points[i].X,points[i].Y);
+			DrawShape(this,pen,path);
+		}
+
+		public void DrawPolygon (Pen pen, PointF [] points) {
+			if(points.Length < 1)
+				return;
+			java.awt.geom.GeneralPath path = new java.awt.geom.GeneralPath();
+			path.moveTo(points[0].X,points[0].Y);
+			for(int i = points.Length - 1; i >= 0; i--)
+				path.lineTo(points[i].X,points[i].Y);
+			DrawShape(this,pen,path);
+		}
+		#endregion
+
+		#region DrawRectangle(s)
+		internal void DrawRectangle (Pen pen, RectangleF rect) {
+			DrawRectangle (pen, rect.Left, rect.Top, rect.Width, rect.Height);
+		}
+
+		public void DrawRectangle (Pen pen, Rectangle rect) {
+			DrawRectangle (pen, rect.Left, rect.Top, rect.Width, rect.Height);
+		}
+
+		public void DrawRectangle (Pen pen, float x, float y, float width, float height) {
+			DrawShape(this,pen,new java.awt.geom.Rectangle2D.Float(x,y,width,height));
+		}
+
+		public void DrawRectangle (Pen pen, int x, int y, int width, int height) {
+			DrawRectangle (pen,(float) x,(float) y,(float) width,(float) height);
+		}
+
+		public void DrawRectangles (Pen pen, RectangleF [] rects) {
+			foreach(RectangleF r in rects)
+				DrawRectangle (pen, r.Left, r.Top, r.Width, r.Height);
+		}
+
+		public void DrawRectangles (Pen pen, Rectangle [] rects) {
+			foreach(Rectangle r in rects)
+				DrawRectangle (pen, r.Left, r.Top, r.Width, r.Height);
+		}
+		#endregion
+
+		#region DrawString
+		public void DrawString (string s, Font font, Brush brush, RectangleF layoutRectangle) {			
+			MeasureDraw(s,font,brush,layoutRectangle,null,true);
+		}
+		
+		public void DrawString (string s, Font font, Brush brush, PointF point) {
+			MeasureDraw(s,font,brush,new RectangleF(point.X,point.Y,99999f,99999f),null,true);
+		}
+		
+		public void DrawString (string s, Font font, Brush brush, PointF point, StringFormat format) {
+			MeasureDraw(s,font,brush,new RectangleF(point.X,point.Y,99999f,99999f),format,true);
+		}
+
+		public void DrawString (string s, Font font, Brush brush, RectangleF layoutRectangle, StringFormat format) {
+			MeasureDraw(s,font,brush,layoutRectangle,format,true);
+		}
+	
+#if false		
+		public void DrawString (string s, Font font, Brush brush, RectangleF layoutRectangle, StringFormat format)
+		{
+			java.awt.Graphics2D g = (java.awt.Graphics2D)nativeObject;			
+			//set
+			java.awt.Paint oldpaint = g.getPaint();
+			g.setPaint(brush.NativeObject);
+			java.awt.Font oldfont = g.getFont();
+			g.setFont(font.NativeObject);
+			java.awt.Shape oldb = g.getClip();
+			g.setClip(new java.awt.geom.Rectangle2D.Float(layoutRectangle.X,layoutRectangle.Y,layoutRectangle.Width,layoutRectangle.Height));
+			//draw
+			g.drawString(s,layoutRectangle.X,layoutRectangle.Y+layoutRectangle.Height);
+			//restore
+			g.setPaint(oldpaint);
+			g.setClip(oldb);
+			g.setFont(oldfont);
+		}
+#endif
+		public void DrawString (string s, Font font, Brush brush, float x, float y) {
+			MeasureDraw(s,font,brush,new RectangleF(x,y,99999f,99999f),null,true);
+		}
+
+		public void DrawString (string s, Font font, Brush brush, float x, float y, StringFormat format) {
+			MeasureDraw(s,font,brush,new RectangleF(x,y,99999f,99999f),format,true);
+		}
+		#endregion
+
+		#region Container [TODO]
+		public void EndContainer (GraphicsContainer container) {
+			throw new NotImplementedException ();
+		}
+
+		public GraphicsContainer BeginContainer () {
+			throw new NotImplementedException ();
+		}
+		
+		public GraphicsContainer BeginContainer (Rectangle dstrect, Rectangle srcrect, GraphicsUnit unit) {
+			throw new NotImplementedException ();
+		}
+
+		
+		public GraphicsContainer BeginContainer (RectangleF dstrect, RectangleF srcrect, GraphicsUnit unit) {
+			throw new NotImplementedException ();
+		}
+
+		#endregion
+
+		#region Metafiles Staff [TODO NotSupp]
+		public void AddMetafileComment (byte [] data) {
+			throw new NotImplementedException ();
+		}
+
+#if INTPTR_SUPPORT
+		public void EnumerateMetafile (Metafile metafile, Point [] destPoints, EnumerateMetafileProc callback)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void EnumerateMetafile (Metafile metafile, RectangleF destRect, EnumerateMetafileProc callback)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void EnumerateMetafile (Metafile metafile, PointF [] destPoints, EnumerateMetafileProc callback)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void EnumerateMetafile (Metafile metafile, Rectangle destRect, EnumerateMetafileProc callback)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void EnumerateMetafile (Metafile metafile, Point destPoint, EnumerateMetafileProc callback)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void EnumerateMetafile (Metafile metafile, PointF destPoint, EnumerateMetafileProc callback)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void EnumerateMetafile (Metafile metafile, PointF destPoint, EnumerateMetafileProc callback, IntPtr callbackData)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void EnumerateMetafile (Metafile metafile, Rectangle destRect, EnumerateMetafileProc callback, IntPtr callbackData)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void EnumerateMetafile (Metafile metafile, PointF [] destPoints, EnumerateMetafileProc callback, IntPtr callbackData)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void EnumerateMetafile (Metafile metafile, Point destPoint, EnumerateMetafileProc callback, IntPtr callbackData)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void EnumerateMetafile (Metafile metafile, Point [] destPoints, EnumerateMetafileProc callback, IntPtr callbackData)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void EnumerateMetafile (Metafile metafile, RectangleF destRect, EnumerateMetafileProc callback, IntPtr callbackData)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void EnumerateMetafile (Metafile metafile, PointF destPoint, RectangleF srcRect, GraphicsUnit srcUnit, EnumerateMetafileProc callback)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void EnumerateMetafile (Metafile metafile, Point destPoint, Rectangle srcRect, GraphicsUnit srcUnit, EnumerateMetafileProc callback)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void EnumerateMetafile (Metafile metafile, PointF [] destPoints, RectangleF srcRect, GraphicsUnit srcUnit, EnumerateMetafileProc callback)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void EnumerateMetafile (Metafile metafile, Point [] destPoints, Rectangle srcRect, GraphicsUnit srcUnit, EnumerateMetafileProc callback)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void EnumerateMetafile (Metafile metafile, RectangleF destRect, RectangleF srcRect, GraphicsUnit srcUnit, EnumerateMetafileProc callback)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void EnumerateMetafile (Metafile metafile, Rectangle destRect, Rectangle srcRect, GraphicsUnit srcUnit, EnumerateMetafileProc callback)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void EnumerateMetafile (Metafile metafile, RectangleF destRect, EnumerateMetafileProc callback, IntPtr callbackData, ImageAttributes imageAttr)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void EnumerateMetafile (Metafile metafile, Point destPoint, EnumerateMetafileProc callback, IntPtr callbackData, ImageAttributes imageAttr)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void EnumerateMetafile (Metafile metafile, PointF destPoint, EnumerateMetafileProc callback, IntPtr callbackData, ImageAttributes imageAttr)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void EnumerateMetafile (Metafile metafile, Point [] destPoints, EnumerateMetafileProc callback, IntPtr callbackData, ImageAttributes imageAttr)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void EnumerateMetafile (Metafile metafile, PointF [] destPoints, EnumerateMetafileProc callback, IntPtr callbackData, ImageAttributes imageAttr)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void EnumerateMetafile (Metafile metafile, Rectangle destRect, EnumerateMetafileProc callback, IntPtr callbackData, ImageAttributes imageAttr)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void EnumerateMetafile (Metafile metafile, Rectangle destRect, Rectangle srcRect, GraphicsUnit srcUnit, EnumerateMetafileProc callback, IntPtr callbackData)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void EnumerateMetafile (Metafile metafile, PointF [] destPoints, RectangleF srcRect, GraphicsUnit srcUnit, EnumerateMetafileProc callback, IntPtr callbackData)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void EnumerateMetafile (Metafile metafile, RectangleF destRect, RectangleF srcRect, GraphicsUnit srcUnit, EnumerateMetafileProc callback, IntPtr callbackData)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void EnumerateMetafile (Metafile metafile, PointF destPoint, RectangleF srcRect, GraphicsUnit srcUnit, EnumerateMetafileProc callback, IntPtr callbackData)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void EnumerateMetafile (Metafile metafile, Point destPoint, Rectangle srcRect, GraphicsUnit srcUnit, EnumerateMetafileProc callback, IntPtr callbackData)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void EnumerateMetafile (Metafile metafile, Point [] destPoints, Rectangle srcRect, GraphicsUnit srcUnit, EnumerateMetafileProc callback, IntPtr callbackData)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void EnumerateMetafile (Metafile metafile, Point [] destPoints, Rectangle srcRect, GraphicsUnit unit, EnumerateMetafileProc callback, IntPtr callbackData, ImageAttributes imageAttr)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void EnumerateMetafile (Metafile metafile, Rectangle destRect, Rectangle srcRect, GraphicsUnit unit, EnumerateMetafileProc callback, IntPtr callbackData, ImageAttributes imageAttr)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void EnumerateMetafile (Metafile metafile, Point destPoint, Rectangle srcRect, GraphicsUnit unit, EnumerateMetafileProc callback, IntPtr callbackData, ImageAttributes imageAttr)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void EnumerateMetafile (Metafile metafile, RectangleF destRect, RectangleF srcRect, GraphicsUnit unit, EnumerateMetafileProc callback, IntPtr callbackData, ImageAttributes imageAttr)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void EnumerateMetafile (Metafile metafile, PointF [] destPoints, RectangleF srcRect, GraphicsUnit unit, EnumerateMetafileProc callback, IntPtr callbackData, ImageAttributes imageAttr)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void EnumerateMetafile (Metafile metafile, PointF destPoint, RectangleF srcRect, GraphicsUnit unit, EnumerateMetafileProc callback, IntPtr callbackData, ImageAttributes imageAttr)
+		{
+			throw new NotImplementedException ();
+		}
+#endif 	
+		#endregion	
+
+		#region ExcludeClip
+		public void ExcludeClip (Rectangle rect) {
+			geom.Area clip = GetNativeClip();
+			clip.subtract(new geom.Area(rect.NativeObject));
+			SetNativeClip(clip);
+		}
+
+		public void ExcludeClip (Region region) {
+			geom.Area clip = GetNativeClip();
+			clip.subtract(region.NativeObject);
+			SetNativeClip(clip);
+		}
+		#endregion 
+
+		#region FillClosedCurve
+		public void FillClosedCurve (Brush brush, PointF [] points) {
+			FillClosedCurve (brush, points, FillMode.Alternate);
+		}
+
+		
+		public void FillClosedCurve (Brush brush, Point [] points) {
+			FillClosedCurve (brush, points, FillMode.Alternate);
+		}
+
+		
+		public void FillClosedCurve (Brush brush, PointF [] points, FillMode fillmode) {
+			FillClosedCurve (brush, points, fillmode, 0.5f);
+		}
+		
+		public void FillClosedCurve (Brush brush, Point [] points, FillMode fillmode) {
+			FillClosedCurve (brush, points, fillmode, 0.5f);
+		}
+
+		public void FillClosedCurve (Brush brush, PointF [] points, FillMode fillmode, float tension) {
+			//TBD: provide corrrect impl (tension) correct
+			FillPolygon(brush, points, fillmode);
+		}
+
+		public void FillClosedCurve (Brush brush, Point [] points, FillMode fillmode, float tension) {
+			//TBD: provide corrrect impl (tension) correct
+			FillPolygon(brush, points, fillmode);
+		}
+		#endregion
+
+		#region FillEllipse
+		public void FillEllipse (Brush brush, Rectangle rect) {
+			FillEllipse (brush, rect.X, rect.Y, rect.Width, rect.Height);
+		}
+
+		public void FillEllipse (Brush brush, RectangleF rect) {
+			FillEllipse (brush, rect.X, rect.Y, rect.Width, rect.Height);
+		}
+
+		public void FillEllipse (Brush brush, float x, float y, float width, float height) {
+			FillShape(brush,new java.awt.geom.Ellipse2D.Float(x,y,width,height));
+		}
+
+		public void FillEllipse (Brush brush, int x, int y, int width, int height) {
+			FillEllipse (brush,(float)x,(float)y,(float)width,(float)height);
+		}
+		#endregion
+
+		#region FillPath
+		public void FillPath (Brush brush, GraphicsPath path) {
+			FillShape(brush,path.NativeObject);
+		}
+		#endregion
+
+		#region FillPie
+		public void FillPie (Brush brush, Rectangle rect, float startAngle, float sweepAngle) {
+			FillPie(brush,(float)rect.X,(float)rect.Y,(float)rect.Width,(float)rect.Height,(float)startAngle,(float)sweepAngle);
+		}
+
+		public void FillPie (Brush brush, int x, int y, int width, int height, int startAngle, int sweepAngle) {
+			FillPie(brush,(float)x,(float)y,(float)width,(float)height,(float)startAngle,(float)sweepAngle);
+		}
+
+		public void FillPie (Brush brush, float x, float y, float width, float height, float startAngle, float sweepAngle) {
+			if (sweepAngle >= 360) {
+				FillEllipse(brush, x, y, width, height);
+				return;
+			}
+
+			double d1Tod2 = width/height;
+			double sqrd1Tod2 = d1Tod2*d1Tod2;
+			float start = (float)ConvertArcAngle(sqrd1Tod2, startAngle);
+			float extent = (float)ConvertArcAngle(sqrd1Tod2, startAngle+sweepAngle) - start;
+
+			FillShape(brush,new java.awt.geom.Arc2D.Float(
+				x,
+				y,
+				width,
+				height,
+				-start,
+				-extent,
+				java.awt.geom.Arc2D.PIE));
+		}
+		#endregion
+
+		#region FillPolygon
+		public void FillPolygon (Brush brush, PointF [] points) {
+			FillPolygon(brush, points, FillMode.Alternate);
+		}
+
+		public void FillPolygon (Brush brush, Point [] points) {
+			FillPolygon(brush, points, FillMode.Alternate);
+		}
+
+		public void FillPolygon (Brush brush, Point [] points, FillMode fillMode) {
+			if (points.Length < 3)
+				//nothing to fill
+				return;
+
+			geom.GeneralPath path = new geom.GeneralPath(
+				fillMode == FillMode.Alternate ? 
+				geom.GeneralPath.WIND_NON_ZERO : geom.GeneralPath.WIND_EVEN_ODD);
+			
+			path.moveTo(points[0].X,points[0].Y);
+			for(int i = points.Length - 1; i >= 0; i--)
+				path.lineTo(points[i].X,points[i].Y);
+
+			FillShape(brush,path);
+		}
+
+		public void FillPolygon (Brush brush, PointF [] points, FillMode fillMode) {
+			if (points.Length < 3)
+				//nothing to fill
+				return;
+
+			geom.GeneralPath path = new geom.GeneralPath(
+				fillMode == FillMode.Alternate ? 
+				geom.GeneralPath.WIND_NON_ZERO : geom.GeneralPath.WIND_EVEN_ODD);
+			
+			path.moveTo(points[0].X,points[0].Y);
+			for(int i = points.Length - 1; i >= 0; i--)
+				path.lineTo(points[i].X,points[i].Y);
+
+			FillShape(brush,path);
+		}
+		#endregion
+
+		#region FillRectangle
+		public void FillRectangle (Brush brush, RectangleF rect) {
+			FillRectangle (brush, rect.Left, rect.Top, rect.Width, rect.Height);
+		}
+
+		public void FillRectangle (Brush brush, Rectangle rect) {
+			FillRectangle (brush, rect.Left, rect.Top, rect.Width, rect.Height);
+		}
+
+		public void FillRectangle (Brush brush, int x, int y, int width, int height) {
+			FillRectangle(brush,(float)x,(float)y,(float)width,(float)height);
+		}
+
+		public void FillRectangle (Brush brush, float x, float y, float width, float height) {
+			FillShape(brush,new java.awt.geom.Rectangle2D.Float(x,y,width,height));
+		}
+
+		public void FillRectangles (Brush brush, Rectangle [] rects) {
+			for(int len = rects.Length, i = 0; i < len; i++)
+				FillRectangle(brush,rects[i].X,rects[i].Y,rects[i].Width,rects[i].Height);
+		}
+
+		public void FillRectangles (Brush brush, RectangleF [] rects) {
+			for(int len = rects.Length, i = 0; i < len; i++)
+				FillRectangle(brush,rects[i].X,rects[i].Y,rects[i].Width,rects[i].Height);
+		}
+		#endregion
+
+		#region FillRegion
+		public void FillRegion (Brush brush, Region region) {
+			FillShape(brush,region);
+		}
+
+		#endregion
+
+		public void Flush () {
+			Flush (FlushIntention.Flush);
+		}
+
+		
+		public void Flush (FlushIntention intention) {
+			if (_image != null)
+				_image.NativeObject.flush();
+		}
+
+#if INTPTR_SUPPORTED
+		[EditorBrowsable (EditorBrowsableState.Advanced)]
+		public void ReleaseHdc (IntPtr hdc)
+		{
+			throw new NotImplementedException();
+		}
+
+		[EditorBrowsable (EditorBrowsableState.Advanced)]
+		public void ReleaseHdcInternal (IntPtr hdc)
+		{
+			throw new NotImplementedException ();
+		}
+
+		[EditorBrowsable (EditorBrowsableState.Advanced)]		
+		public static Graphics FromHdc (IntPtr hdc)
+		{
+			throw new NotImplementedException();
+		}
+
+		[EditorBrowsable (EditorBrowsableState.Advanced)]
+		public static Graphics FromHdc (IntPtr hdc, IntPtr hdevice)
+		{
+			throw new NotImplementedException ();
+		}
+
+		[EditorBrowsable (EditorBrowsableState.Advanced)]
+		public static Graphics FromHdcInternal (IntPtr hdc)
+		{
+			throw new NotImplementedException ();
+		}
+
+		[EditorBrowsable (EditorBrowsableState.Advanced)]		
+		public static Graphics FromHwnd (IntPtr hwnd)
+		{
+			throw new NotImplementedException();
+		}
+
+		[EditorBrowsable (EditorBrowsableState.Advanced)]
+		public static Graphics FromHwndInternal (IntPtr hwnd)
+		{
+			throw new NotImplementedException ();
+		}
+
+		internal static Graphics FromXDrawable (IntPtr drawable, IntPtr display)
+		{
+			throw new NotImplementedException();
+		}
+
+		public static IntPtr GetHalftonePalette ()
+		{
+			throw new NotImplementedException ();
+		}
+
+		[EditorBrowsable (EditorBrowsableState.Advanced)]
+		public IntPtr GetHdc ()
+		{
+			throw new NotImplementedException();
+		}
+#endif
+		
+		#region GetNearestColor [TODO]
+		public Color GetNearestColor (Color color) {
+			throw new NotImplementedException();
+		}
+		#endregion
+
+		#region IntersectClip
+		public void IntersectClip (Region region) {
+			geom.Area clip = GetNativeClip();
+			clip.intersect(region.NativeObject);
+			SetNativeClip(clip);
+		}
+		
+		public void IntersectClip (RectangleF rect) {
+			geom.Area clip = GetNativeClip();
+			clip.intersect(new geom.Area(rect.NativeObject));
+			SetNativeClip(clip);
+		}
+
+		public void IntersectClip (Rectangle rect) {			
+			geom.Area clip = GetNativeClip();
+			clip.intersect(new geom.Area(rect.NativeObject));
+			SetNativeClip(clip);
+		}
+		#endregion
+
+		#region IsVisible
+		public bool IsVisible (Point point) {
+			return IsVisible(point.X,point.Y);
+		}
+
+		
+		public bool IsVisible (RectangleF rect) {
+			return IsVisible ((float)rect.X,(float)rect.Y,(float)rect.Width,(float)rect.Height);
+		}
+
+		public bool IsVisible (PointF point) {
+			return IsVisible(point.X,point.Y);
+		}
+		
+		public bool IsVisible (Rectangle rect) {
+			return IsVisible ((float)rect.X,(float)rect.Y,(float)rect.Width,(float)rect.Height);
+		}
+		
+		public bool IsVisible (float x, float y) {
+			java.awt.Graphics2D g = NativeObject;
+			java.awt.Shape s = g.getClip();
+			if (s == null)
+				return true;
+			else				
+				return s.contains(x,y);
+		}
+		
+		public bool IsVisible (int x, int y) {
+			return IsVisible ((float)x,(float)y);
+		}
+		
+		public bool IsVisible (float x, float y, float width, float height) {
+			java.awt.Graphics2D g = NativeObject;
+			java.awt.Shape s = g.getClip();
+			if (s == null)
+				return true;
+			else				
+				return s.contains(x,y,width,height);
+		}
+
+		
+		public bool IsVisible (int x, int y, int width, int height) {
+			return IsVisible ((float)x,(float)y,(float)width,(float)height);
+		}
+		#endregion
+
+		#region MeasureCharacterRanges [TODO]
+		public Region [] MeasureCharacterRanges (string text, Font font, RectangleF layoutRect, StringFormat stringFormat) {
+			throw new NotImplementedException();
+		}
+		#endregion
+		
+		#region MeasureString [1 method still TODO]
+		public SizeF MeasureString (string text, Font font) {
+			return MeasureDraw(text,font,null,new RectangleF(0,0,99999f,99999f),null,false);
+		}
+
+		
+		public SizeF MeasureString (string text, Font font, SizeF layoutArea) {
+			return MeasureDraw(text,font,null,new RectangleF(0,0,layoutArea.Width,layoutArea.Height),null,false);
+		}
+
+		
+		public SizeF MeasureString (string text, Font font, int width) {
+			return MeasureDraw(text,font,null,new RectangleF(0,0,(float)width,99999f),null,false);
+		}
+
+
+		public SizeF MeasureString (string text, Font font, SizeF layoutArea, StringFormat format) {
+			return MeasureDraw(text,font,null,new RectangleF(0,0,layoutArea.Width,layoutArea.Height),format,false);
+		}
+
+		
+		public SizeF MeasureString (string text, Font font, int width, StringFormat format) {
+			return MeasureDraw(text,font,null,new RectangleF(0,0,(float)width,99999f),format,false);
+		}
+
+		
+		public SizeF MeasureString (string text, Font font, PointF origin, StringFormat format) {
+			//TODO: MeasureDraw still not dealing with clipping region of dc
+			return MeasureDraw(text,font,null,new RectangleF(origin.X,origin.Y,99999f,99999f),format,false);
+		}
+
+		
+		public SizeF MeasureString (string text, Font font, SizeF layoutArea, StringFormat stringFormat, out int charactersFitted, out int linesFilled) {	
+			//TODO: charcount
+			throw new NotImplementedException();
+		}
+		#endregion
+
+		#region MultiplyTransform
+		public void MultiplyTransform (Matrix matrix) {
+			MultiplyTransform (matrix, MatrixOrder.Prepend);
+		}
+
+		public void MultiplyTransform (Matrix matrix, MatrixOrder order) {
+			ConcatenateTransform(matrix.NativeObject, order);
+		}
+		#endregion
+
+		#region Reset (Clip and Transform)
+		public void ResetClip () {
+			java.awt.Graphics2D g = NativeObject;
+			g.setClip(null);
+
+		}
+
+		public void ResetTransform () {
+			NativeObject.setTransform(new java.awt.geom.AffineTransform(1,0,0,1,0,0));
+		}
+		#endregion
+
+		public GraphicsState Save () {
+			throw new NotImplementedException();
+		}
+
+		public void Restore (GraphicsState gstate) {
+			throw new NotImplementedException();
+		}
+
+		#region RotateTransform
+		public void RotateTransform (float angle) {
+			RotateTransform (angle, MatrixOrder.Prepend);
+		}
+
+		public void RotateTransform (float angle, MatrixOrder order) {
+			ConcatenateTransform(
+				geom.AffineTransform.getRotateInstance(java.lang.Math.toRadians(angle)),
+				order);
+		}
+		#endregion
+
+		#region ScaleTransform
+		public void ScaleTransform (float sx, float sy) {
+			ScaleTransform (sx, sy, MatrixOrder.Prepend);
+		}
+
+		public void ScaleTransform (float sx, float sy, MatrixOrder order) {
+			ConcatenateTransform(
+				geom.AffineTransform.getScaleInstance(sx, sy),
+				order);
+		}
+		#endregion
+
+		#region SetClip [Must be reviewed - more abstraction needed]
+		public void SetClip (RectangleF rect) {
+			SetClip (rect, CombineMode.Replace);
+		}
+
+		public void SetClip (GraphicsPath path) {
+			SetClip (path, CombineMode.Replace);
+		}
+
+		public void SetClip (Rectangle rect) {
+			SetClip (rect, CombineMode.Replace);
+		}
+
+		public void SetClip (Graphics g) {
+			SetClip (g, CombineMode.Replace);
+		}
+
+		public void SetClip (Graphics g, CombineMode combineMode) {
+			if(g == null)
+				throw new NullReferenceException();
+			
+			SetNativeClip(
+				CombineClipArea(g.GetNativeClip(),
+				combineMode));
+		}
+
+		public void SetClip (Rectangle rect, CombineMode combineMode) {
+			SetClip(rect.X,rect.Y,rect.Width,rect.Height,combineMode);			
+		}		
+		public void SetClip (RectangleF rect, CombineMode combineMode) {			
+			SetClip(rect.X,rect.Y,rect.Width,rect.Height,combineMode);			
+		}
+		
+		public void SetClip (Region region, CombineMode combineMode) {
+			if(region == null)
+				throw new ArgumentNullException("region");
+
+			if(region == Region.InfiniteRegion) {
+				SetNativeClip(null);
+				return;
+			}
+
+			SetNativeClip(CombineClipArea(region.NativeObject,combineMode));
+		}
+		
+		public void SetClip (GraphicsPath path, CombineMode combineMode) {
+			if(path == null)
+				throw new ArgumentNullException("path");
+
+			SetNativeClip(CombineClipArea(new java.awt.geom.Area(path.NativeObject),combineMode));
+		}
+		#endregion
+
+		#region Clipping Staff [INTERNAL]
+		internal void SetClip(float x,float y,float width,float height,CombineMode combineMode) {					
+			SetNativeClip(CombineClipArea(new geom.Area(
+				new geom.Rectangle2D.Float(x,y,width,height)),combineMode));
+		}
+
+		geom.Area CombineClipArea(java.awt.geom.Area area, CombineMode combineMode) {
+			if (combineMode == CombineMode.Replace)
+				return area;
+
+			geom.Area curClip = GetNativeClip();
+			switch(combineMode) {
+				case CombineMode.Complement:
+					curClip.add(area);
+					break;
+				case CombineMode.Exclude:
+					curClip.subtract(area);
+					break;
+				case CombineMode.Intersect:
+					curClip.intersect(area);
+					break;
+				case CombineMode.Union:
+					curClip.add(area);
+					break;
+				case CombineMode.Xor:
+					curClip.exclusiveOr(area);
+					break;
+				default:
+					throw new ArgumentOutOfRangeException();					
+			}
+			
+			return curClip;
+		}
+		
+		void SetNativeClip(awt.Shape s) {
+			NativeObject.setClip(s);
+		}
+
+		geom.Area GetNativeClip() {
+			awt.Shape clip = NativeObject.getClip();
+			return clip != null ? new geom.Area(clip) : Region.InfiniteRegion.NativeObject;
+		}
+		#endregion
+		
+		#region TransformPoints
+		public void TransformPoints (CoordinateSpace destSpace, CoordinateSpace srcSpace, PointF [] pts) {
+			//TODO:CoordinateSpace
+			java.awt.Graphics2D g = NativeObject;
+			java.awt.geom.AffineTransform tr = g.getTransform();
+			float[] fpts = new float[2];
+			for(int i = 0; i< pts.Length; i++) {
+				fpts[0] = pts[i].X;
+				fpts[1] = pts[i].Y;
+				tr.transform(fpts, 0, fpts, 0, 1);
+				pts[i].X = fpts[0];
+				pts[i].Y = fpts[1];
+			}
+		}
+
+		public void TransformPoints (CoordinateSpace destSpace, CoordinateSpace srcSpace, Point [] pts) {						
+			//TODO:CoordinateSpace
+			java.awt.Graphics2D g = NativeObject;
+			java.awt.geom.AffineTransform tr = g.getTransform();
+			float[] fpts = new float[2];
+			for(int i = 0; i< pts.Length; i++) {
+				fpts[0] = pts[i].X;
+				fpts[1] = pts[i].Y;
+				tr.transform(fpts, 0, fpts, 0, 1);
+				pts[i].X = (int)fpts[0];
+				pts[i].Y = (int)fpts[1];
+			}
+		}
+		#endregion
+
+		#region TranslateClip
+		public void TranslateClip (int dx, int dy) {
+			TranslateClip((float)dx, (float)dy);
+		}
+
+		
+		public void TranslateClip (float dx, float dy) {
+			geom.Area clip = GetNativeClip();
+			clip.transform(geom.AffineTransform.getTranslateInstance(dx, dy));
+			SetNativeClip(clip);
+		}
+		#endregion
+
+		#region TranslateTransform
+		public void TranslateTransform (float dx, float dy) {
+			TranslateTransform (dx, dy, MatrixOrder.Prepend);
+		}
+
+		
+		public void TranslateTransform (float dx, float dy, MatrixOrder order) {
+			ConcatenateTransform(
+				geom.AffineTransform.getTranslateInstance(dx, dy),
+				order);
+		}
+		#endregion
+
+		#region Properties [Partial TODO]
+		public Region Clip {
+			get {
+				java.awt.Graphics2D g = NativeObject;
+				java.awt.Shape s = g.getClip();				
+				if(s != null) {
+					return new Region(new java.awt.geom.Area(s));
+				}
+				else {
+					return Region.InfiniteRegion.Clone();
+				}
+			}
+			set {
+				SetClip (value, CombineMode.Replace);
+			}
+		}
+
+		public RectangleF ClipBounds {
+			get {
+				java.awt.Graphics2D g = NativeObject;
+				java.awt.Rectangle r = g.getClipBounds();
+				RectangleF rect = new RectangleF ((float)r.getX(),(float)r.getY(),(float)r.getWidth(),(float)r.getHeight());
+				return rect;
+			}
+		}
+
+		public CompositingMode CompositingMode {
+			//TODO:check this carefully
+			get {
+				return (NativeObject.getComposite() == awt.AlphaComposite.SrcOver) ?
+					CompositingMode.SourceOver : CompositingMode.SourceCopy;
+			}
+			set {
+				NativeObject.setComposite(
+					(value == CompositingMode.SourceOver) ?
+					awt.AlphaComposite.SrcOver : awt.AlphaComposite.Src);
+			}
+
+		}
+
+		public CompositingQuality CompositingQuality {
+			get {
+				throw new NotImplementedException();
+			}
+			set {
+				throw new NotImplementedException();
+			}
+		}
+
+		public float DpiX {
+			get {				
+				return DefaultScreenResolution;
+			}
+		}
+
+		public float DpiY {
+			get {
+				//TODO: assume 72 (screen) for now
+				return DpiX;
+			}
+		}
+
+		public InterpolationMode InterpolationMode {
+			get {				
+				throw new NotImplementedException();
+			}
+			set {
+				throw new NotImplementedException();
+			}
+		}
+
+		public bool IsClipEmpty {
+			get {
+				java.awt.Graphics2D g = NativeObject;
+				awt.Shape clip = g.getClip();
+				if (clip == null)
+					return false;
+				return new geom.Area(clip).isEmpty();
+			}
+		}
+
+		public bool IsVisibleClipEmpty {
+			get {
+				//TODO:correct this
+				return IsClipEmpty;
+			}
+		}
+
+		public float PageScale {
+			get {
+				throw new NotImplementedException();
+			}
+			set {
+				throw new NotImplementedException();
+			}
+		}
+
+		public GraphicsUnit PageUnit {
+			get {
+				throw new NotImplementedException();
+			}
+			set {
+				throw new NotImplementedException();
+			}
+		}
+
+		public PixelOffsetMode PixelOffsetMode {
+			get {
+				throw new NotImplementedException();
+			}
+			set {
+				throw new NotImplementedException();
+			}
+		}
+
+		public Point RenderingOrigin {
+			get {
+				throw new NotImplementedException();
+			}
+			set {
+				throw new NotImplementedException();
+			}
+		}
+
+		public SmoothingMode SmoothingMode {
+			get {
+				java.awt.Graphics2D g = NativeObject;
+
+				awt.RenderingHints hints = g.getRenderingHints();
+				if(hints.containsKey(java.awt.RenderingHints.KEY_ANTIALIASING) &&
+					hints.get(java.awt.RenderingHints.KEY_ANTIALIASING) == 
+					java.awt.RenderingHints.VALUE_ANTIALIAS_ON) {
+					
+
+					if(hints.containsKey(java.awt.RenderingHints.KEY_RENDERING)) {
+						if(hints.get(java.awt.RenderingHints.KEY_RENDERING) == 
+							java.awt.RenderingHints.VALUE_RENDER_QUALITY)
+							return SmoothingMode.HighQuality;
+						if(hints.get(java.awt.RenderingHints.KEY_RENDERING) == 
+							java.awt.RenderingHints.VALUE_RENDER_SPEED)
+							return SmoothingMode.HighSpeed;
+						if(hints.get(java.awt.RenderingHints.KEY_RENDERING) == 
+							java.awt.RenderingHints.VALUE_RENDER_DEFAULT)
+							return SmoothingMode.AntiAlias;
+					}
+					return SmoothingMode.AntiAlias;
+				}
+				return SmoothingMode.Default;
+
+			}
+
+			set {
+				java.awt.Graphics2D g = NativeObject;
+
+				awt.RenderingHints hints = g.getRenderingHints();
+				if(value ==  SmoothingMode.AntiAlias)
+					g.setRenderingHint(java.awt.RenderingHints.KEY_ANTIALIASING,java.awt.RenderingHints.VALUE_ANTIALIAS_ON);
+				else
+					g.setRenderingHint(java.awt.RenderingHints.KEY_ANTIALIASING,java.awt.RenderingHints.VALUE_ANTIALIAS_OFF);
+				//TODO:make it good
+			}
+		}
+
+		public int TextContrast {
+			get {
+				//TODO:implement this
+				throw new NotImplementedException();
+			}
+
+			set {
+				//TODO:implement this
+				throw new NotImplementedException();
+			}
+		}
+
+		public TextRenderingHint TextRenderingHint {
+			get {
+				java.awt.Graphics2D g = NativeObject;
+
+				awt.RenderingHints hints = g.getRenderingHints();
+				if(hints.containsKey(java.awt.RenderingHints.KEY_TEXT_ANTIALIASING)) {
+					if(hints.get(java.awt.RenderingHints.KEY_TEXT_ANTIALIASING) == 
+						java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_ON)
+						return TextRenderingHint.AntiAlias;
+					if(hints.get(java.awt.RenderingHints.KEY_TEXT_ANTIALIASING) == 
+						java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_OFF)
+						return TextRenderingHint.SingleBitPerPixel;
+				}
+				return TextRenderingHint.SystemDefault;
+			}
+
+			set {
+				//TODO: implement this
+				throw new NotImplementedException();
+			}
+		}
+
+		public Matrix Transform {
+			get {
+				java.awt.Graphics2D g = NativeObject;
+				Matrix matrix = new Matrix (g.getTransform());
+				return matrix;
+			}
+			set {
+				java.awt.Graphics2D g = NativeObject;
+				g.setTransform(value.NativeObject);
+			}
+		}
+
+		public RectangleF VisibleClipBounds {
+			get {
+				//TODO: implement this
+				throw new NotImplementedException();
+			}
+		}
+
+		void ConcatenateTransform(geom.AffineTransform transform, MatrixOrder order) {
+			geom.AffineTransform at = NativeObject.getTransform();
+			Matrix.Multiply(at, transform, order);
+			NativeObject.setTransform(at);
+		}
+		#endregion
+	}
+}
+

+ 477 - 0
mcs/class/System.Drawing/System.Drawing/Image.jvm.cs

@@ -0,0 +1,477 @@
+//
+// System.Drawing.Image.cs
+//
+// (C) 2002 Ximian, Inc.  http://www.ximian.com
+// Author: 	Christian Meyer ([email protected])
+// 		Alexandre Pigolkine ([email protected])
+//		Jordi Mas i Hernandez ([email protected])
+//
+namespace System.Drawing {
+
+using System;
+using System.Runtime.Remoting;
+using System.Runtime.Serialization;
+using System.Runtime.InteropServices;
+using System.ComponentModel;
+using System.Drawing.Imaging;
+using System.IO;
+using BufferedImage = java.awt.image.BufferedImage;
+using java.io;
+using javax.imageio;
+using javax.imageio.stream;
+using vmw.common;
+using awt = java.awt;
+using image = java.awt.image;
+
+public abstract class Image : MarshalByRefObject, IDisposable , ICloneable
+{	
+	#region Vars	
+	java.awt.Image [] _nativeObjects;
+
+	//consider using Image[] to support many thumbnails per Image
+	java.awt.Image [] _thumbnails;
+	int _currentObject;
+	Guid _dimension;
+	ImageFormat _format;
+	#endregion
+
+	#region Constructor
+	public void Dispose ()
+	{
+	}
+
+	protected virtual void DisposeResources ()
+	{
+	}
+	
+	protected virtual void Dispose (bool disposing)
+	{
+	}
+
+	// Derived classes must call Initialize () when they use this constructor
+	protected Image () {
+	}
+ 
+	protected Image (Image orig) {
+		_nativeObjects = CloneNativeObjects(orig._nativeObjects);
+		_thumbnails = CloneNativeObjects(orig._thumbnails);
+		_format = orig._format;
+		_currentObject = orig._currentObject;
+		_dimension = orig._dimension;
+	}
+
+	protected Image (java.awt.Image nativeObject, ImageFormat format)
+		:this (new java.awt.Image [] {nativeObject}, format) {}
+
+	protected Image (java.awt.Image [] nativeObjects, ImageFormat format)
+        :this (nativeObjects, format, FrameDimension.Page.Guid)	{}
+
+	protected Image (java.awt.Image [] nativeObjects, ImageFormat format, Guid dimension) {
+		Initialize (nativeObjects, null, format, dimension);
+	}
+
+	protected void Initialize (java.awt.Image [] nativeObjects, java.awt.Image [] thumbnails, ImageFormat format, Guid dimension) {
+		_format = format;
+		_nativeObjects = nativeObjects;
+		_thumbnails = thumbnails;
+		_currentObject = 0;
+		_dimension = dimension;
+	}
+
+	#endregion
+	
+	#region Internals
+
+	internal java.awt.Image NativeObject {
+		get {
+		  return _nativeObjects [_currentObject];
+		}
+	}
+
+	protected java.awt.Image this [int i] {
+		get {
+			return _nativeObjects [i];
+		}
+	}
+
+	protected int NativeObjectsCount {
+		get {
+			return _nativeObjects.Length;
+		}
+	}
+
+	#endregion
+    
+	#region FromFile
+	public static Image FromFile(string filename)
+	{
+		//FIXME: check if it's not a metafile
+		return new Bitmap (filename);
+	}
+	
+	public static Image FromFile(string filename, bool useIcm)
+	{
+		//FIXME: check if it's not a metafile
+		return new Bitmap (filename, useIcm);
+	}
+	#endregion
+
+	#region GetThumbnailImageAbort
+	[Serializable]
+	public delegate bool GetThumbnailImageAbort();
+	#endregion
+
+	#region Clone
+	public virtual object Clone() {
+		throw new NotImplementedException ("Must be implemented in child class");
+	}
+	#endregion
+
+	// static
+	#region FromStream
+	public static Image FromStream (Stream stream)
+	{
+		//FIXME: check if it's not a metafile
+		return new Bitmap (stream);
+	}
+	
+	public static Image FromStream (Stream stream, bool useIcm)
+	{
+		//FIXME: check if it's not a metafile
+		return new Bitmap (stream, useIcm);
+	}
+	#endregion
+
+	#region GetPixelFormatSize
+	public static int GetPixelFormatSize(PixelFormat pixfmt)
+	{
+
+		int result = 0;
+		switch (pixfmt) {
+			case PixelFormat.Format16bppArgb1555:
+			case PixelFormat.Format16bppGrayScale:
+			case PixelFormat.Format16bppRgb555:
+			case PixelFormat.Format16bppRgb565:
+				result = 16;
+				break;
+			case PixelFormat.Format1bppIndexed:
+				result = 1;
+				break;
+			case PixelFormat.Format24bppRgb:
+				result = 24;
+				break;
+			case PixelFormat.Format32bppArgb:
+			case PixelFormat.Format32bppPArgb:
+			case PixelFormat.Format32bppRgb:
+				result = 32;
+				break;
+			case PixelFormat.Format48bppRgb:
+				result = 48;
+				break;
+			case PixelFormat.Format4bppIndexed:
+				result = 4;
+				break;
+			case PixelFormat.Format64bppArgb:
+			case PixelFormat.Format64bppPArgb:
+				result = 64;
+				break;
+			case PixelFormat.Format8bppIndexed:
+				result = 8;
+				break;
+		}
+		return result;
+	}
+	#endregion
+
+	#region IsAlphaPixelFormat
+	public static bool IsAlphaPixelFormat(PixelFormat pixfmt)
+	{
+		return (pixfmt & PixelFormat.Alpha) != PixelFormat.Undefined;
+	}
+	#endregion
+	
+	#region GetCanonicalPixelFormat [TODO]
+	public static bool IsCanonicalPixelFormat (PixelFormat pixfmt)
+	{
+		return (pixfmt & PixelFormat.Canonical) != PixelFormat.Undefined;
+	}
+	#endregion
+	
+	#region IsextendedPixelFormat [TODO]
+	public static bool IsExtendedPixelFormat (PixelFormat pixfmt)
+	{
+		return (pixfmt & PixelFormat.Extended) != PixelFormat.Undefined;
+	}
+	#endregion
+
+	// non-static
+	#region GetBounds
+	public RectangleF GetBounds (ref GraphicsUnit pageUnit)
+	{	
+		int w = NativeObject.getWidth(null);
+		int h = NativeObject.getHeight(null);
+
+		pageUnit = GraphicsUnit.Pixel; //java.awt.Image always returns pixels
+
+		return new RectangleF((float)0,(float)0,(float)w,(float)h);
+	}
+	#endregion
+	
+	#region GetEncoderParameterList [TODO]
+	public EncoderParameters GetEncoderParameterList(Guid encoder)
+	{
+		throw new NotImplementedException ();
+	}
+	#endregion
+	
+	#region GetFrameCount
+	public int GetFrameCount(FrameDimension dimension)
+	{
+		return _nativeObjects.Length;
+	}
+	#endregion
+	
+	#region GetPropertyItem [TODO]
+	public PropertyItem GetPropertyItem(int propid)
+	{
+		throw new NotImplementedException ();
+	}
+	#endregion
+
+	#region RemovePropertyItem [TODO]
+	public void RemovePropertyItem (int propid)
+	{		
+		throw new NotImplementedException ();
+	}
+	#endregion
+	
+	#region RotateFlip [TODO]
+	public void RotateFlip (RotateFlipType rotateFlipType)
+	{		
+		throw new NotImplementedException ();
+	}
+	#endregion
+
+	#region Save
+	protected abstract void InternalSave (ImageOutputStream output, ImageFormat format);
+
+	public void Save(Stream stream, ImageCodecInfo encoder, EncoderParameters encoderParams)
+	{
+		//FIXME: ignoring encoderParams
+		Save (stream, new ImageFormat (encoder.FormatID));
+	}
+	
+	public void Save(string filename, ImageCodecInfo encoder, EncoderParameters encoderParams)
+	{
+		//FIXME: ignoring encoderParams
+		Save (filename, new ImageFormat (encoder.FormatID));
+	}
+
+	public void Save (string filename)
+	{
+		Save (filename, RawFormat);
+	}
+
+	public void Save (Stream stream, ImageFormat format)
+	{
+		java.io.OutputStream jos = vmw.common.IOUtils.ToOutputStream (stream);
+		MemoryCacheImageOutputStream output = new MemoryCacheImageOutputStream(jos);
+		InternalSave (output, format);
+	}
+
+	public void Save(string filename, ImageFormat format) 
+	{
+		java.io.File jf = vmw.common.IOUtils.getJavaFile (filename);
+		FileImageOutputStream output = new FileImageOutputStream (jf);
+		InternalSave (output, format);
+	}
+	#endregion
+
+	#region SaveAdd [TODO]
+	public void SaveAdd(EncoderParameters encoderParams)
+	{
+		throw new NotImplementedException ();
+	}
+	
+	public void SaveAdd(Image image, EncoderParameters encoderParams)
+	{
+		throw new NotImplementedException ();
+	}
+	#endregion
+	
+	#region SelectActiveFrame
+	public int SelectActiveFrame(FrameDimension dimension, int frameIndex)
+	{
+		if (dimension.Guid != _dimension) //TBD check if this is the correct exception and message
+            throw new ArgumentException (dimension + " dimension is not supported");
+		_currentObject = frameIndex;
+		//TBD check what net makes when index out of bounds
+		return frameIndex;
+	}
+	#endregion
+	
+	#region SetPropertyItem [TODO]
+	public void SetPropertyItem(PropertyItem propitem)
+	{
+		throw new NotImplementedException ();
+	}
+	#endregion
+
+	// properties
+	#region Flags[TODO]
+	public int Flags 
+	{
+		get {
+			throw new NotImplementedException ();	
+		}
+	}
+	#endregion
+
+	#region FrameDimensionsList
+	public Guid[] FrameDimensionsList {
+		get {
+			return new Guid [] {_dimension};
+		}
+	}
+	#endregion
+
+	#region Height
+	public int Height 
+	{
+		get {
+			return NativeObject.getHeight(null);
+		}
+	}
+	#endregion
+	
+	#region HorisontalDimention [TODO]
+	public float HorizontalResolution 
+	{
+		get {
+			throw new NotImplementedException ();
+		}
+	}
+	#endregion
+	
+	#region ColorPalette [TODO]
+	public ColorPalette Palette 
+	{
+		get {							
+			
+			throw new NotImplementedException ();
+		}
+		set {
+			throw new NotImplementedException ();
+		}
+	}
+	#endregion
+		
+	#region PhysicalDimension [TODO]
+	public SizeF PhysicalDimension 
+	{
+		get {
+			throw new NotImplementedException ();
+		}
+	}
+	#endregion
+	
+	#region PixelFormat
+	abstract protected PixelFormat InternalPixelFormat {get;}
+
+	public PixelFormat PixelFormat {
+		get {
+			return InternalPixelFormat;
+		}
+	}
+	#endregion
+		
+	#region PropertiIdList [TODO]
+	public int[] PropertyIdList 
+	{
+		get {
+			throw new NotImplementedException ();
+		}
+	}
+	#endregion
+		
+	#region PropertItems [TODO]
+	public PropertyItem[] PropertyItems 
+	{
+		get {
+			throw new NotImplementedException ();
+		}
+	}
+	#endregion
+
+	#region RawFormat
+	public ImageFormat RawFormat 
+	{
+		get {
+			return _format;
+		}
+	}
+	#endregion
+
+	#region Size
+	public Size Size 
+	{
+		get {
+			return new Size(Width, Height);
+		}
+	}
+	#endregion
+	
+	#region VerticalResolution [TODO]
+	public float VerticalResolution 
+	{
+		get {
+			throw new NotImplementedException();
+		}
+	}
+	#endregion
+	
+	#region Width
+	public int Width 
+	{
+		get {
+			return NativeObject.getWidth(null);
+		}
+	}
+	#endregion	
+
+	public Image GetThumbnailImage(int thumbWidth, int thumbHeight, Image.GetThumbnailImageAbort callback, IntPtr callbackData)
+	{
+		awt.Image img = NativeObject;			
+		if (_thumbnails != null && _currentObject < _thumbnails.Length) {
+			if (_thumbnails[_currentObject] != null)
+				img = _thumbnails[_currentObject];
+		}
+
+		if (img.getHeight(null) != thumbHeight || img.getWidth(null) != thumbWidth)
+			img = img.getScaledInstance(thumbWidth, thumbHeight, awt.Image.SCALE_DEFAULT);
+
+		return ImageFromNativeImage(img, RawFormat);
+	}
+#if INTPTR_SUPPORT
+	public static Bitmap FromHbitmap(IntPtr hbitmap)
+	{		
+		throw new NotImplementedException ();
+	}	
+
+	public static Bitmap FromHbitmap(IntPtr hbitmap, IntPtr hpalette)
+	{		
+		throw new NotImplementedException ();
+	}
+#endif
+
+	internal static Image ImageFromNativeImage(awt.Image nativeImage, ImageFormat format) {
+		if (nativeImage is BufferedImage)
+			return new Bitmap(nativeImage, format);
+
+		throw new ArgumentException("Invalid image type");
+	}
+
+	protected abstract awt.Image [] CloneNativeObjects(awt.Image [] src);
+}
+
+}

+ 588 - 0
mcs/class/System.Drawing/System.Drawing/Pen.jvm.cs

@@ -0,0 +1,588 @@
+//
+// System.Drawing.Pen.cs
+//
+// Authors:
+//   Miguel de Icaza ([email protected])
+//   Alexandre Pigolkine ([email protected])
+//   Duncan Mak ([email protected])
+//   Ravindra ([email protected])
+//
+// (C) Ximian, Inc.  http://www.ximian.com
+// (C) Novell, Inc.  http://www.novell.com
+//
+
+using System;
+using System.Drawing.Drawing2D;
+using System.Runtime.InteropServices;
+using java.awt;
+
+namespace System.Drawing 
+{
+
+	public sealed class Pen : MarshalByRefObject, ICloneable, IDisposable 
+	{
+		#region Member Vars
+		java.awt.BasicStroke nativeObject;
+		internal bool isModifiable = true;
+		Brush brush;
+		DashStyle _ds = DashStyle.Solid; 
+		PenAlignment _alignment;
+		Matrix _transform;
+		#endregion
+
+		#region Internals
+		internal Pen (java.awt.BasicStroke p)
+		{
+			nativeObject = p;
+		}
+
+		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 (Brush brush, float width)
+		{
+			brush = (Brush)brush.Clone();
+			nativeObject = new java.awt.BasicStroke(width);
+		}
+		#endregion
+		//
+		// Properties
+		//
+		#region Alignment [TODO]
+		public PenAlignment Alignment 
+		{
+			get 
+			{
+				return _alignment;
+			}
+
+			set 
+			{
+				if (!isModifiable)
+					throw new ArgumentException ("Pen is not modifiable");
+				_alignment = value;
+			}
+		}
+		#endregion
+
+		#region Brush
+		public Brush Brush 
+		{
+			get 
+			{
+				return brush;
+			}
+
+			set 
+			{
+				if (isModifiable) 
+				{
+					brush = value;
+				}
+				else
+					throw new ArgumentException ("You may not change this Pen because it does not belong to you.");
+			}
+		}
+		#endregion
+
+		#region Color
+		public Color Color 
+		{
+			get 
+			{
+				if(brush is SolidBrush)
+					return ((SolidBrush)brush).Color;
+				else if(brush is HatchBrush)
+					return ((HatchBrush)brush).ForegroundColor;
+				else
+					return Color.Empty;
+			}
+
+			set 
+			{
+				if (isModifiable) 
+				{
+					brush = new SolidBrush (value);
+				}
+				else
+					throw new ArgumentException ("You may not change this Pen because it does not belong to you.");
+			}
+		}
+		#endregion 
+            
+		#region CustomEndCap [TODO]
+		public CustomLineCap CustomEndCap 
+		{
+			get 
+			{
+				throw new NotImplementedException ();
+			}
+			// do a check for isModifiable when implementing this property
+			set 
+			{
+				throw new NotImplementedException ();                                
+			}
+		}
+		#endregion 
+
+		#region CustoStartCap [TODO]
+		public CustomLineCap CustomStartCap 
+		{
+
+			get 
+			{
+				throw new NotImplementedException ();                                
+			}
+
+			// do a check for isModifiable when implementing this property
+			set 
+			{
+				throw new NotImplementedException ();                                
+			}
+		}
+		#endregion
+
+		#region DashCap [TODO, now - allways flat]
+		public DashCap DashCap 
+		{
+			get 
+			{
+				//TODO
+				return DashCap.Flat;
+			}
+
+			set 
+			{
+				
+			}
+		}
+		#endregion
+
+		#region DashOffset
+		public float DashOffset 
+		{
+
+			get 
+			{
+				return nativeObject.getDashPhase();
+			}
+
+			set 
+			{
+				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.");
+			}
+		}
+		#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)
+		{
+			if(patt == null)
+			{
+				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;
+			}
+
+		}
+
+		public float [] DashPattern 
+		{
+			get 
+			{
+				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;
+
+				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.");
+			}
+		}
+		#endregion
+
+		#region DashStyle
+		public DashStyle DashStyle 
+		{
+			get 
+			{
+				return _ds;
+			}
+
+			set 
+			{
+				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.");
+			}
+		}
+		#endregion 
+
+		#region StartCap [TODO - now allways endcap]
+
+		public LineCap StartCap 
+		{
+			get 
+			{
+				//TODO
+                return EndCap;           
+			}
+
+			set 
+			{
+				EndCap = value;
+			}
+		}
+		#endregion
+
+		#region EndCap 
+		public LineCap EndCap 
+		{
+			get 
+			{
+				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 
+			{
+				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;						 
+			}
+		}
+		#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();
+			}
+
+			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.");
+			}
+		}
+		#endregion
+
+		#region MiterLimit 
+		public float MiterLimit 
+		{
+
+			get 
+			{
+				return nativeObject.getMiterLimit();
+			}
+
+			set 
+			{
+				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.");
+			}
+	                    
+		}
+		#endregion
+
+		#region PenType
+		public PenType PenType 
+		{
+
+			get 
+			{
+				if (brush is TextureBrush)
+					return PenType.TextureFill;
+				else if (brush is HatchBrush)
+					return PenType.HatchFill;
+				else if (brush is LinearGradientBrush)
+					return PenType.LinearGradient;
+				else if (brush is PathGradientBrush)
+					return PenType.PathGradient;
+				else
+					return PenType.SolidColor;
+			}
+		}
+		#endregion
+
+		#region Transform [TODO]
+		public Matrix Transform 
+		{
+			get 
+			{
+				if (_transform == null)
+					_transform = new Matrix ();
+				return _transform;
+			}
+					
+			set 
+			{
+				if (!isModifiable)
+                    throw new ArgumentException ("Pen is not modifiable");
+				_transform = value;
+			}
+		}
+		#endregion
+
+		#region Width
+		public float Width 
+		{
+			get 
+			{
+				return nativeObject.getLineWidth();
+			}
+			set 
+			{
+				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.");
+			}
+		}
+		#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;
+		}
+		#endregion
+
+		#region Dispose 
+		public void Dispose ()
+		{
+			Dispose (true);
+		}
+		void Dispose (bool disposing)
+		{
+			if (!isModifiable && disposing)
+				throw new ArgumentException ("You may not change this Pen because it does not belong to you.");
+			// Restore the dtor if adding anything below
+		}
+		#endregion
+
+		#region Transform Funcs [TODO]
+		public void MultiplyTransform (Matrix matrix)
+		{
+			Transform.Multiply (matrix);
+		}
+
+		public void MultiplyTransform (Matrix matrix, MatrixOrder order)
+		{
+			Transform.Multiply (matrix, order);
+		}
+
+		public void ResetTransform ()
+		{
+			Transform.Reset ();
+		}
+
+		public void RotateTransform (float angle)
+		{
+			Transform.Rotate (angle);
+		}
+
+		public void RotateTransform (float angle, MatrixOrder order)
+		{
+			Transform.Rotate (angle, order);
+		}
+
+		public void ScaleTransform (float sx, float sy)
+		{
+			Transform.Scale (sx, sy);
+		}
+
+		public void ScaleTransform (float sx, float sy, MatrixOrder order)
+		{
+			Transform.Scale (sx, sy, order);
+		}
+
+		public void TranslateTransform (float dx, float dy) {
+			Transform.Translate (dx, dy);
+		}
+
+		public void TranslateTransform (float dx, float dy, MatrixOrder order) {
+			Transform.Translate (dx, dy, order);
+		}
+		#endregion
+		public void SetLineCap (LineCap startCap, LineCap endCap, DashCap dashCap)
+		{
+			throw new NotImplementedException();
+		}
+	}
+}

+ 386 - 0
mcs/class/System.Drawing/System.Drawing/Region.jvm.cs

@@ -0,0 +1,386 @@
+
+using System;
+using System.Drawing.Drawing2D;
+using System.Runtime.InteropServices;
+
+using awt = java.awt;
+using geom = java.awt.geom;
+
+namespace System.Drawing
+{
+	[ComVisible (false)]
+	public sealed class Region : BasicShape
+	{
+		#region Member Vars
+		internal static readonly Region InfiniteRegion = new Region(new Rectangle(-0x400000, -0x400000, 0x800000, 0x800000));
+		#endregion
+        
+		#region Internals
+		internal geom.Area NativeObject
+		{
+			get
+			{
+				return (geom.Area)Shape;
+			}
+		}
+		#endregion
+		
+		#region Ctors. and Dtor
+
+
+		public Region() : this(new geom.Area())
+		{                  
+		}
+
+        internal Region(geom.Area native) : base(native)
+		{
+        }
+                
+		
+		public Region (GraphicsPath path) : this(new geom.Area(path.NativeObject))
+		{	
+		}
+
+		public Region (Rectangle rect) : this(new geom.Area(new awt.Rectangle(rect.X,rect.Y,rect.Width,rect.Height)))
+		{
+		}
+
+		public Region (RectangleF rect) : this(new geom.Area(new geom.Rectangle2D.Float(rect.X,rect.Y,rect.Width,rect.Height)))
+		{
+		}
+
+		public Region (RegionData region_data) : this((geom.Area)null)
+		{
+			throw new NotImplementedException ();
+		}
+		#endregion
+		
+		#region Union
+		public void Union (GraphicsPath path)
+		{
+			if (path == null)
+				throw new ArgumentNullException("path");
+			NativeObject.add(new geom.Area(path.NativeObject));
+		}
+
+
+		public void Union (Rectangle rect)
+		{                                    
+			NativeObject.add(new geom.Area(new awt.Rectangle(rect.X,rect.Y,rect.Width,rect.Height)));
+		}
+
+		public void Union (RectangleF rect)
+		{
+			NativeObject.add(new geom.Area(new geom.Rectangle2D.Float(rect.X,rect.Y,rect.Width,rect.Height)));
+		}
+
+		public void Union (Region region)
+		{
+			if (region == null)
+				throw new ArgumentNullException("region");
+			NativeObject.add(new geom.Area(region.NativeObject));
+		}
+		#endregion                                                                                 
+
+		#region Intersect
+		//
+		public void Intersect (GraphicsPath path)
+		{
+			if (path == null)
+				throw new ArgumentNullException("path");
+			NativeObject.intersect(new geom.Area(path.NativeObject));
+		}
+
+		public void Intersect (Rectangle rect)
+		{
+			NativeObject.intersect(new geom.Area(new awt.Rectangle(rect.X,rect.Y,rect.Width,rect.Height)));
+		}
+
+		public void Intersect (RectangleF rect)
+		{
+			NativeObject.intersect(new geom.Area(new geom.Rectangle2D.Float(rect.X,rect.Y,rect.Width,rect.Height)));
+		}
+
+		public void Intersect (Region region)
+		{
+			if (region == null)
+				throw new ArgumentNullException("region");
+			NativeObject.intersect(new geom.Area(region.NativeObject));
+		}
+		#endregion
+
+		#region  Complement
+		//
+		public void Complement (GraphicsPath path)
+		{
+			if (path == null)
+				throw new ArgumentNullException("path");
+			geom.Area a = new geom.Area(path.NativeObject);
+			a.subtract(NativeObject);
+			Shape = a;
+		}
+
+		public void Complement (Rectangle rect)
+		{
+			geom.Area a = new geom.Area(new geom.Area(new awt.Rectangle(rect.X,rect.Y,rect.Width,rect.Height)));
+			a.subtract(NativeObject);
+			Shape = a;
+		}
+
+		public void Complement (RectangleF rect)
+		{
+			geom.Area a = new geom.Area(new geom.Area(new geom.Rectangle2D.Float(rect.X,rect.Y,rect.Width,rect.Height)));
+			a.subtract(NativeObject);
+			Shape = a;
+		}
+
+		public void Complement (Region region)
+		{
+			if (region == null)
+				throw new ArgumentNullException("region");
+			geom.Area a = new geom.Area(region);
+			a.subtract(NativeObject);
+			Shape = a;
+		}
+		#endregion
+
+		#region Exclude
+		//
+		public void Exclude (GraphicsPath path)
+		{
+			if (path == null)
+				throw new ArgumentNullException("path");
+			NativeObject.subtract(new geom.Area(path.NativeObject));
+		}
+
+		public void Exclude (Rectangle rect)
+		{
+			NativeObject.subtract(new geom.Area(new awt.Rectangle(rect.X,rect.Y,rect.Width,rect.Height)));
+		}
+
+		public void Exclude (RectangleF rect)
+		{
+			NativeObject.subtract(new geom.Area(new geom.Rectangle2D.Float(rect.X,rect.Y,rect.Width,rect.Height)));
+		}
+
+		public void Exclude (Region region)
+		{
+			if (region == null)
+				throw new ArgumentNullException("region");
+			NativeObject.subtract(region.NativeObject);
+		}
+		#endregion
+
+		#region  Xor
+		//
+		public void Xor (GraphicsPath path)
+		{
+			if (path == null)
+				throw new ArgumentNullException("path");
+			NativeObject.exclusiveOr(new geom.Area(path.NativeObject));
+		}
+
+		public void Xor (Rectangle rect)
+		{
+			NativeObject.exclusiveOr(new geom.Area(new awt.Rectangle(rect.X,rect.Y,rect.Width,rect.Height)));
+		}
+
+		public void Xor (RectangleF rect)
+		{
+			NativeObject.exclusiveOr(new geom.Area(new geom.Rectangle2D.Float(rect.X,rect.Y,rect.Width,rect.Height)));
+		}
+
+		public void Xor (Region region)
+		{
+			if (region == null)
+				throw new ArgumentNullException("region");
+			NativeObject.exclusiveOr(region.NativeObject);
+		}
+		#endregion
+
+		#region GetBounds
+		//
+		public RectangleF GetBounds (Graphics graphics)
+		{
+			if (graphics == null)
+				throw new ArgumentNullException("graphics");
+			geom.Rectangle2D r = NativeObject.createTransformedArea(graphics.NativeObject.getTransform()).getBounds2D();
+			return new RectangleF((float)r.getX(),(float)r.getY(),(float)r.getWidth(),(float)r.getHeight());                        
+		}
+		#endregion
+
+		#region  Translate
+		//
+		public void Translate (int dx, int dy)
+		{
+			NativeObject.transform(geom.AffineTransform.getTranslateInstance(
+				(float)dx,
+				(float)dy));
+		}
+
+		public void Translate (float dx, float dy)
+		{
+			NativeObject.transform(geom.AffineTransform.getTranslateInstance(
+				dx,
+				dy));
+		}
+		#endregion
+
+		#region  IsVisible [TODO]
+		//
+		public bool IsVisible (int x, int y, Graphics g)
+		{
+			return IsVisible((float)x, (float)y, g);
+		}
+
+		public bool IsVisible (int x, int y, int width, int height)
+		{
+			return IsVisible((float)x, (float)y, (float)width, (float)height);
+		}
+
+		public bool IsVisible (int x, int y, int width, int height, Graphics g)
+		{
+			return IsVisible((float)x, (float)y, (float)width, (float)height, g);
+		}
+
+		public bool IsVisible (Point point)
+		{
+			return IsVisible(point.X, point.Y);
+		}
+
+		public bool IsVisible (PointF point)
+		{
+			return IsVisible(point.X, point.Y);
+		}
+
+		public bool IsVisible (Point point, Graphics g)
+		{
+			return IsVisible(point.X, point.Y, g);
+		}
+
+		public bool IsVisible (PointF point, Graphics g)
+		{
+			return IsVisible(point.X, point.Y, g);
+		}
+
+		public bool IsVisible (Rectangle rect)
+		{
+			return IsVisible(rect.X, rect.Y, rect.Width, rect.Height);
+		}
+
+		public bool IsVisible (RectangleF rect)
+		{
+			return IsVisible(rect.X, rect.Y, rect.Width, rect.Height);
+		}
+
+		public bool IsVisible (Rectangle rect, Graphics g)
+		{
+			return IsVisible(rect.X, rect.Y, rect.Width, rect.Height, g);
+		}
+
+		public bool IsVisible (RectangleF rect, Graphics g)
+		{
+			return IsVisible(rect.X, rect.Y, rect.Width, rect.Height, g);
+		}
+
+		public bool IsVisible (float x, float y)
+		{
+			return NativeObject.contains(x,y);
+		}
+
+		public bool IsVisible (float x, float y, Graphics g)
+		{
+			if (g == null)
+				throw new ArgumentNullException("graphics");
+			return NativeObject.createTransformedArea(g.NativeObject.getTransform()).contains(x,y);
+		}
+
+		public bool IsVisible (float x, float y, float width, float height)
+		{
+			return NativeObject.contains(x,y,width,height);
+		}
+
+		public bool IsVisible (float x, float y, float width, float height, Graphics g) 
+		{
+			if (g == null)
+				throw new ArgumentNullException("graphics");
+			return NativeObject.createTransformedArea(g.NativeObject.getTransform()).contains(x,y,width,height);
+		}
+		#endregion
+
+		#region IsEmpty
+		public bool IsEmpty(Graphics g)
+		{
+			if (g == null)
+				throw new ArgumentNullException("graphics");
+			return NativeObject.createTransformedArea(g.NativeObject.getTransform()).isEmpty();
+		}
+		#endregion
+
+		#region IsInfinite
+		public bool IsInfinite(Graphics g)
+		{
+			if (g == null)
+				throw new ArgumentNullException("graphics");
+			//probably too naive.
+			return NativeObject.createTransformedArea(g.NativeObject.getTransform()).equals(InfiniteRegion.NativeObject);
+		}
+		#endregion
+
+		#region MakeEmpty
+		public void MakeEmpty()
+		{
+			NativeObject.reset();
+		}
+		#endregion
+
+		#region MakeInfinite
+		public void MakeInfinite()
+		{
+			Shape = new geom.Area(InfiniteRegion.NativeObject);
+		}
+		#endregion 
+
+		#region Equals
+		public bool Equals(Region region, Graphics g)
+		{
+			if (g == null)
+				throw new ArgumentNullException("graphics");
+			return NativeObject.createTransformedArea(g.NativeObject.getTransform()).equals(region.NativeObject);
+		}
+		#endregion
+				
+		public RegionData GetRegionData()
+		{
+			throw new NotImplementedException();
+		}
+		
+		
+		#region GetRegionScans [TODO]
+		public RectangleF[] GetRegionScans(Matrix matrix)
+		{
+			geom.Area area = NativeObject;
+			if (matrix !=null)
+				area = area.createTransformedArea (matrix.NativeObject);
+			//FIXME: return more exact result
+			return new RectangleF [] {new RectangleF (area.getBounds2D ())};
+		}
+		#endregion
+		
+		#region Transform 
+		public void Transform(Matrix matrix)
+		{
+			if (matrix == null)
+				throw new ArgumentNullException("matrix");
+			NativeObject.transform(matrix.NativeObject);
+		}		
+		#endregion
+
+		#region Clone
+		public Region Clone()
+		{
+			return new Region((geom.Area)NativeObject.clone());
+		}
+		#endregion
+	}
+}

+ 234 - 0
mcs/class/System.Drawing/System.Drawing/StringFormat.jvm.cs

@@ -0,0 +1,234 @@
+//
+// System.Drawing.StringFormat.cs
+//
+// Authors:
+//   Dennis Hayes ([email protected])
+//   Miguel de Icaza ([email protected])
+//   Jordi Mas i Hernandez ([email protected])
+//
+// Copyright (C) 2002 Ximian, Inc (http://www.ximian.com)
+//
+// Copyright (C) 2004 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;
+using System.Drawing.Text;
+
+namespace System.Drawing
+{
+	/// <summary>
+	/// Summary description for StringFormat.
+	/// </summary>
+	public sealed class StringFormat : IDisposable, ICloneable
+	{
+		private static StringFormat genericDefault;
+		private int language = 0;
+		internal CharacterRange [] CharRanges;
+
+		//local storage
+		internal StringAlignment alignment;
+		internal StringAlignment linealignment;
+		internal HotkeyPrefix prefix;
+		internal StringFormatFlags flags;
+		internal StringDigitSubstitute subst;
+		internal StringTrimming trimming;
+		internal float firstTabOffset;
+		internal float [] tabStops;
+		
+		public StringFormat()
+		{					   
+			
+		}		
+		
+		public StringFormat(StringFormatFlags options, int lang)
+		{
+				flags = options;
+				LineAlignment =  StringAlignment.Near;
+				Alignment =  StringAlignment.Near;			
+				language = lang;
+		}
+		
+		public StringFormat(StringFormatFlags options):this(options,0)
+		{
+		}
+		
+//		~StringFormat()
+//		{	
+//			Dispose ();
+//		}
+		
+		public void Dispose()
+		{	
+		}
+
+
+		public StringFormat (StringFormat source)
+		{
+			Alignment = source.Alignment;
+			LineAlignment = source.LineAlignment;
+			HotkeyPrefix = source.HotkeyPrefix;
+			subst = source.subst;
+			flags = source.flags;
+		}
+
+		
+		public StringAlignment Alignment 
+		{
+			get 
+			{
+				return alignment;
+			}
+
+			set 
+			{
+				alignment = value;
+			}
+		}
+
+		public StringAlignment LineAlignment 
+		{
+			get 
+			{
+				return linealignment;
+			}
+			set 
+			{
+				linealignment = value;
+			}
+		}
+
+		public StringFormatFlags FormatFlags 
+		{
+			get 
+			{				
+				return flags;
+			}
+
+			set 
+			{
+				flags = value;
+			}
+		}
+
+		public HotkeyPrefix HotkeyPrefix 
+		{
+			get 
+			{				
+				return prefix;
+			}
+
+			set 
+			{
+				prefix = value;
+			}
+		}
+
+
+		public StringTrimming Trimming 
+		{
+			get 
+			{
+				return trimming;
+			}
+
+			set 
+			{
+				trimming = value;
+			}
+		}
+
+		public static StringFormat GenericDefault 
+		{
+			get 
+			{
+				return genericDefault;
+			}
+		}
+		
+		
+		public int DigitSubstitutionLanguage 
+		{
+			get
+			{
+				return language;
+			}
+		}
+
+		
+		public static StringFormat GenericTypographic 
+		{
+			get 
+			{
+				throw new NotImplementedException();
+			}
+		}
+
+		public StringDigitSubstitute  DigitSubstitutionMethod  
+		{
+			get 
+			{
+				return subst;     
+			}
+		}
+
+
+		public void SetMeasurableCharacterRanges (CharacterRange [] range)
+		{
+			CharRanges=(CharacterRange [])range.Clone();
+		}
+
+		internal CharacterRange [] GetCharRanges
+		{
+			get 
+			{
+				return(CharRanges);
+			}
+		}
+	
+		public object Clone()
+		{
+			throw new NotImplementedException();
+		}
+
+		public override string ToString()
+		{
+			return "[StringFormat, FormatFlags=" + this.FormatFlags.ToString() + "]";
+		}
+		
+		public void SetTabStops(float firstTabOffset, float[] tabStops)
+		{
+			this.firstTabOffset = firstTabOffset;
+			this.tabStops = tabStops;
+		}
+
+		public void SetDigitSubstitution(int language,  StringDigitSubstitute substitute)
+		{
+			subst = substitute;
+		}
+
+		public float[] GetTabStops(out float firstTabOffset)
+		{
+			firstTabOffset = this.firstTabOffset;
+			return this.tabStops;
+		}
+
+	}
+}

+ 191 - 0
mcs/class/System.Drawing/System.Drawing/TextureBrush.jvm.cs

@@ -0,0 +1,191 @@
+//
+// System.Drawing.TextureBrush.cs
+//
+// Author:
+//   Dennis Hayes ([email protected])
+//   Ravindra ([email protected])
+//
+// (C) 2002 Ximian, Inc
+// (C) 2004 Novell, Inc.
+//
+
+//
+// Copyright (C) 2004 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;
+using System.Drawing.Drawing2D;
+using System.Drawing.Imaging;
+
+using awt = java.awt;
+using geom = java.awt.geom;
+using image = java.awt.image;
+
+namespace System.Drawing
+{
+	/// <summary>
+	/// Summary description for TextureBrush.
+	/// </summary>
+	public sealed class TextureBrush : Brush
+	{
+		awt.TexturePaint _nativeObject;
+
+		protected override java.awt.Paint NativeObject {
+			get {
+				return _nativeObject;
+			}
+		}
+
+
+		WrapMode _wrapMode;
+
+		TextureBrush (awt.TexturePaint ptr)
+		{
+			_nativeObject = ptr;
+		}
+
+		public TextureBrush (Image image) : this (image, WrapMode.Tile)
+		{
+		}
+
+		public TextureBrush (Image image, Rectangle dstRect)
+		{
+		}
+
+		public TextureBrush (Image image, RectangleF dstRect)
+		{
+			_nativeObject = new awt.TexturePaint((image.BufferedImage)image.NativeObject,
+				new geom.Rectangle2D.Float((float)dstRect.X,(float)dstRect.Y,(float)dstRect.Width,
+				(float)dstRect.Height));
+		}
+
+		public TextureBrush (Image image, WrapMode wrapMode)
+		{
+			//	TODO: WRAP MODE
+			_nativeObject = new awt.TexturePaint((image.BufferedImage)image.NativeObject,
+				new geom.Rectangle2D.Float(0,0,1,1));
+		}
+
+		public TextureBrush (Image image, Rectangle dstRect, ImageAttributes imageAttr)
+		{
+			throw new NotImplementedException();
+		}
+
+		public TextureBrush (Image image, RectangleF dstRect, ImageAttributes imageAttr)
+		{
+			throw new NotImplementedException();
+		}
+
+		public TextureBrush (Image image, WrapMode wrapMode, Rectangle dstRect)
+		{
+			//TODO:WRAP MODE
+			_nativeObject = new awt.TexturePaint((image.BufferedImage)image.NativeObject,
+				new geom.Rectangle2D.Float ((float)dstRect.X,(float)dstRect.Y,(float)dstRect.Width,(float)dstRect.Height));
+		}
+
+		public TextureBrush (Image image, WrapMode wrapMode, RectangleF dstRect)
+		{
+			//TODO:WRAP MODE
+			_nativeObject = new awt.TexturePaint((image.BufferedImage)image.NativeObject,
+				new geom.Rectangle2D.Float((float)dstRect.X,(float)dstRect.Y,(float)dstRect.Width,
+				(float)dstRect.Height));
+		}
+
+		// properties
+		public Image Image {
+			get {
+				return Image.ImageFromNativeImage(((awt.TexturePaint)NativeObject).getImage(),
+					ImageFormat.Bmp);
+			}
+		}
+
+		public Matrix Transform {
+			get {					
+				throw new NotImplementedException();
+			}
+			set {
+				throw new NotImplementedException();
+			}
+		}
+
+		public WrapMode WrapMode {
+			get {
+				return _wrapMode;
+			}
+			set {
+				_wrapMode = value;
+			}
+		}
+
+		// public methods
+
+		public override object Clone ()
+		{
+			throw new NotImplementedException();
+		}
+
+		public void MultiplyTransform (Matrix matrix)
+		{
+			MultiplyTransform (matrix, MatrixOrder.Prepend);
+		}
+
+		public void MultiplyTransform (Matrix matrix, MatrixOrder order)
+		{
+			throw new NotImplementedException();
+		}
+
+		public void ResetTransform ()
+		{
+			throw new NotImplementedException();
+		}
+
+		public void RotateTransform (float angle)
+		{
+			RotateTransform (angle, MatrixOrder.Prepend);
+		}
+
+		public void RotateTransform (float angle, MatrixOrder order)
+		{
+			throw new NotImplementedException();
+		}
+
+		public void ScaleTransform (float sx, float sy)
+		{
+			ScaleTransform (sx, sy, MatrixOrder.Prepend);
+		}
+
+		public void ScaleTransform (float sx, float sy, MatrixOrder order)
+		{
+			throw new NotImplementedException();
+		}
+
+		public void TranslateTransform (float dx, float dy)
+		{
+			TranslateTransform (dx, dy, MatrixOrder.Prepend);
+		}
+
+		public void TranslateTransform (float dx, float dy, MatrixOrder order)
+		{
+			throw new NotImplementedException();
+		}
+	}
+}