* roottypes.cs: Rename from tree.cs.
[mono.git] / mcs / class / System.Drawing / System.Drawing / Graphics.jvm.cs
old mode 100755 (executable)
new mode 100644 (file)
index 7e348eb..9597432
@@ -29,8 +29,8 @@ namespace System.Drawing {
                        readonly geom.PathIterator _iter;\r
 \r
                        const float norm = 0.5f;\r
-                       const float rnd = (1.0f - norm);
-                       float ax = 0.0f;
+                       const float rnd = (1.0f - norm);\r
+                       float ax = 0.0f;\r
                        float ay = 0.0f;\r
 \r
                        #endregion\r
@@ -47,21 +47,21 @@ namespace System.Drawing {
 \r
                        static int GetIndex(int type) {\r
                                int index;\r
-                               switch ((GraphicsPath.JPI)type) {
-                                       case GraphicsPath.JPI.SEG_CUBICTO:
-                                               index = 4;
-                                               break;
-                                       case GraphicsPath.JPI.SEG_QUADTO:
-                                               index = 2;
-                                               break;
-                                       case GraphicsPath.JPI.SEG_MOVETO:
-                                       case GraphicsPath.JPI.SEG_LINETO:
-                                               index = 0;
-                                               break;
-                                       case GraphicsPath.JPI.SEG_CLOSE:
-                                       default:
-                                               index = -1;
-                                               break;
+                               switch ((GraphicsPath.JPI)type) {\r
+                                       case GraphicsPath.JPI.SEG_CUBICTO:\r
+                                               index = 4;\r
+                                               break;\r
+                                       case GraphicsPath.JPI.SEG_QUADTO:\r
+                                               index = 2;\r
+                                               break;\r
+                                       case GraphicsPath.JPI.SEG_MOVETO:\r
+                                       case GraphicsPath.JPI.SEG_LINETO:\r
+                                               index = 0;\r
+                                               break;\r
+                                       case GraphicsPath.JPI.SEG_CLOSE:\r
+                                       default:\r
+                                               index = -1;\r
+                                               break;\r
                                }\r
 \r
                                return index;\r
@@ -82,35 +82,35 @@ namespace System.Drawing {
                        int geom.PathIterator.currentSegment(float[] point) {\r
                                int type = _iter.currentSegment(point);\r
 \r
-                               int index = GetIndex(type);
-                               
-                               if (index >= 0) {
-                                       float ox = point[index];
-                                       float oy = point[index+1];
-                                       float newax = (float) java.lang.Math.floor(ox + rnd) + norm;
-                                       float neway = (float) java.lang.Math.floor(oy + rnd) + norm;
-                                       point[index] = newax;
-                                       point[index+1] = neway;
-                                       newax -= ox;
-                                       neway -= oy;
-                                       switch ((GraphicsPath.JPI)type) {
-                                               case GraphicsPath.JPI.SEG_CUBICTO:
-                                                       point[0] += ax;
-                                                       point[1] += ay;
-                                                       point[2] += newax;
-                                                       point[3] += neway;
-                                                       break;
-                                               case GraphicsPath.JPI.SEG_QUADTO:
-                                                       point[0] += (newax + ax) / 2;
-                                                       point[1] += (neway + ay) / 2;
-                                                       break;
-                                                       //                                                      case GraphicsPath.JPI.SEG_MOVETO:
-                                                       //                                                      case GraphicsPath.JPI.SEG_LINETO:
-                                                       //                                                      case GraphicsPath.JPI.SEG_CLOSE:
-                                                       //                                                              break;
-                                       }
-                                       ax = newax;
-                                       ay = neway;
+                               int index = GetIndex(type);\r
+                               \r
+                               if (index >= 0) {\r
+                                       float ox = point[index];\r
+                                       float oy = point[index+1];\r
+                                       float newax = (float) java.lang.Math.floor(ox + rnd) + norm;\r
+                                       float neway = (float) java.lang.Math.floor(oy + rnd) + norm;\r
+                                       point[index] = newax;\r
+                                       point[index+1] = neway;\r
+                                       newax -= ox;\r
+                                       neway -= oy;\r
+                                       switch ((GraphicsPath.JPI)type) {\r
+                                               case GraphicsPath.JPI.SEG_CUBICTO:\r
+                                                       point[0] += ax;\r
+                                                       point[1] += ay;\r
+                                                       point[2] += newax;\r
+                                                       point[3] += neway;\r
+                                                       break;\r
+                                               case GraphicsPath.JPI.SEG_QUADTO:\r
+                                                       point[0] += (newax + ax) / 2;\r
+                                                       point[1] += (neway + ay) / 2;\r
+                                                       break;\r
+                                                       //                                                      case GraphicsPath.JPI.SEG_MOVETO:\r
+                                                       //                                                      case GraphicsPath.JPI.SEG_LINETO:\r
+                                                       //                                                      case GraphicsPath.JPI.SEG_CLOSE:\r
+                                                       //                                                              break;\r
+                                       }\r
+                                       ax = newax;\r
+                                       ay = neway;\r
                                }\r
 \r
                                return type;\r
@@ -119,35 +119,35 @@ namespace System.Drawing {
                        int geom.PathIterator.currentSegment(double[] point) {\r
                                int type = _iter.currentSegment(point);\r
 \r
-                               int index = GetIndex(type);
-
-                               if (index >= 0) {
-                                       float ox = (float)point[index];
-                                       float oy = (float)point[index+1];
-                                       float newax = (float)java.lang.Math.floor(ox + rnd) + norm;
-                                       float neway = (float)java.lang.Math.floor(oy + rnd) + norm;
-                                       point[index] = newax;
-                                       point[index+1] = neway;
-                                       newax -= ox;
-                                       neway -= oy;
-                                       switch ((GraphicsPath.JPI)type) {
-                                               case GraphicsPath.JPI.SEG_CUBICTO:
-                                                       point[0] += ax;
-                                                       point[1] += ay;
-                                                       point[2] += newax;
-                                                       point[3] += neway;
-                                                       break;
-                                               case GraphicsPath.JPI.SEG_QUADTO:
-                                                       point[0] += (newax + ax) / 2;
-                                                       point[1] += (neway + ay) / 2;
-                                                       break;
-                                                       //                                                      case GraphicsPath.JPI.SEG_MOVETO:
-                                                       //                                                      case GraphicsPath.JPI.SEG_LINETO:
-                                                       //                                                      case GraphicsPath.JPI.SEG_CLOSE:
-                                                       //                                                              break;
-                                       }
-                                       ax = newax;
-                                       ay = neway;
+                               int index = GetIndex(type);\r
+\r
+                               if (index >= 0) {\r
+                                       float ox = (float)point[index];\r
+                                       float oy = (float)point[index+1];\r
+                                       float newax = (float)java.lang.Math.floor(ox + rnd) + norm;\r
+                                       float neway = (float)java.lang.Math.floor(oy + rnd) + norm;\r
+                                       point[index] = newax;\r
+                                       point[index+1] = neway;\r
+                                       newax -= ox;\r
+                                       neway -= oy;\r
+                                       switch ((GraphicsPath.JPI)type) {\r
+                                               case GraphicsPath.JPI.SEG_CUBICTO:\r
+                                                       point[0] += ax;\r
+                                                       point[1] += ay;\r
+                                                       point[2] += newax;\r
+                                                       point[3] += neway;\r
+                                                       break;\r
+                                               case GraphicsPath.JPI.SEG_QUADTO:\r
+                                                       point[0] += (newax + ax) / 2;\r
+                                                       point[1] += (neway + ay) / 2;\r
+                                                       break;\r
+                                                       //                                                      case GraphicsPath.JPI.SEG_MOVETO:\r
+                                                       //                                                      case GraphicsPath.JPI.SEG_LINETO:\r
+                                                       //                                                      case GraphicsPath.JPI.SEG_CLOSE:\r
+                                                       //                                                              break;\r
+                                       }\r
+                                       ax = newax;\r
+                                       ay = neway;\r
                                }\r
 \r
                                return type;\r
@@ -167,6 +167,7 @@ namespace System.Drawing {
                readonly awt.Graphics2D _nativeObject;\r
                PixelOffsetMode _pixelOffsetMode = PixelOffsetMode.Default;\r
                int _textContrast = 4;\r
+               TextRenderingHint _textRenderingHint;\r
                readonly Image _image;\r
                \r
                readonly Matrix _transform;\r
@@ -230,17 +231,24 @@ namespace System.Drawing {
 \r
                        NativeObject.setStroke(new DummyStroke());\r
                        NativeObject.setRenderingHint(awt.RenderingHints.KEY_COLOR_RENDERING, awt.RenderingHints.VALUE_COLOR_RENDER_QUALITY);\r
-
-                       InterpolationMode = InterpolationMode.Bilinear;
-
-                       _windowRect = new awt.Rectangle(_image.Width, _image.Height);
-                       _clip = new Region();
+\r
+                       InterpolationMode = InterpolationMode.Bilinear;\r
+                       TextRenderingHint = TextRenderingHint.SystemDefault;\r
+\r
+                       _windowRect = new awt.Rectangle(_image.Width, _image.Height);\r
+                       _clip = new Region();\r
                }\r
 \r
                #endregion\r
                \r
                #region Internal Accessors\r
 \r
+               static internal float [] UnitConversion {\r
+                       get {\r
+                               return _unitConversion;\r
+                       }\r
+               }\r
+               \r
                static internal int DefaultScreenResolution {\r
                        get {\r
                                return IsHeadless ? 96 :\r
@@ -261,51 +269,20 @@ namespace System.Drawing {
                }\r
                #endregion\r
 \r
-               #region Workers [INTERNAL]\r
-               void InternalSetBrush(Brush b) {\r
-                       java.awt.Graphics2D g = NativeObject;\r
-                       g.setPaint (b);\r
-                       SolidBrush sb = b as SolidBrush;\r
-                       if(sb != null) {\r
-                               g.setColor(sb.Color.NativeObject);\r
-                       }\r
-                       else if(b is LinearGradientBrush) {\r
-#if DEBUG_GRADIENT_BRUSH\r
-                               if(((LinearGradientBrush)b).dPoints != null)\r
-                               {\r
-                                       PointF []pts = ((LinearGradientBrush)b).dPoints;\r
-                                       java.awt.Shape s = g.getClip();\r
-                                       g.setClip(0,0,99999,99999);\r
-                                       g.setPaint(new java.awt.Color(255,0,0));\r
-                                       g.drawLine((int)pts[0].X,(int)pts[0].Y,(int)pts[1].X,(int)pts[1].Y);\r
-                                       g.setPaint(new java.awt.Color(0,255,0));\r
-                                       g.drawLine((int)pts[1].X,(int)pts[1].Y,(int)pts[2].X,(int)pts[2].Y);\r
-                                       g.setPaint(new java.awt.Color(255,0,0));\r
-                                       g.drawLine((int)pts[2].X,(int)pts[2].Y,(int)pts[3].X,(int)pts[3].Y);\r
-                                       g.setPaint(new java.awt.Color(0,255,0));\r
-                                       g.drawLine((int)pts[3].X,(int)pts[3].Y,(int)pts[0].X,(int)pts[0].Y);\r
-                                       \r
-                                       g.setClip(s);\r
-                               }\r
-#endif\r
-                       }\r
-               }\r
 \r
+               #region Workers [INTERNAL]\r
                void DrawShape(Pen pen, awt.Shape shape) {\r
                        if (pen == null)\r
                                throw new ArgumentNullException("pen");\r
 \r
-                       if (StrokeFactory.CanCreateAdvancedStroke) {\r
+                       if (StrokeFactory.CanCreateAdvancedStroke && \r
+                               (!pen.CanCreateBasicStroke || !NeedsNormalization)) {\r
                                geom.AffineTransform oldT = NativeObject.getTransform();\r
                                NativeObject.setTransform(Matrix.IdentityTransform.NativeObject);\r
 \r
                                try {\r
-                                       geom.Area clip = _clip.NativeObject;\r
                                        geom.AffineTransform t = GetFinalTransform();\r
                                        if (!oldT.isIdentity()) {\r
-                                               clip = (geom.Area)clip.clone();\r
-                                               clip.transform(oldT);\r
-\r
                                                t = (geom.AffineTransform)t.clone();\r
                                                t.preConcatenate(oldT);\r
                                        }\r
@@ -314,10 +291,12 @@ namespace System.Drawing {
 \r
                                        bool antiAlias = (SmoothingMode == SmoothingMode.AntiAlias);\r
 \r
-                                       bool thin = (widthsquared <= (antiAlias ? 
-                                               AdvancedStroke.MinPenSizeAASquared :
+                                       bool thin = (widthsquared <= (antiAlias ? \r
+                                               AdvancedStroke.MinPenSizeAASquared :\r
                                                AdvancedStroke.MinPenSizeSquared));\r
 \r
+                                       PenFit penFit = thin ? (antiAlias ? PenFit.ThinAntiAlias : PenFit.Thin) : PenFit.NotThin;\r
+\r
                                        if (NeedsNormalization) {\r
 \r
                                                bool normThin = \r
@@ -326,18 +305,18 @@ namespace System.Drawing {
                                                if (normThin) {\r
                                                        shape = GetNormalizedShape(shape, t);\r
                                                        shape = pen.GetNativeObject(\r
-                                                               t, null, thin).createStrokedShape(shape);\r
+                                                               t, null, penFit).createStrokedShape(shape);\r
                                                }\r
                                                else {\r
-                                                       shape = pen.GetNativeObject(t, thin).createStrokedShape(shape);\r
+                                                       shape = pen.GetNativeObject(t, penFit).createStrokedShape(shape);\r
                                                        shape = GetNormalizedShape(shape, null);\r
                                                }\r
                                        }\r
                                        else {\r
-                                               shape = pen.GetNativeObject(t, thin).createStrokedShape(shape);\r
+                                               shape = pen.GetNativeObject(t, penFit).createStrokedShape(shape);\r
                                        }\r
 \r
-                                       FillScaledShape(pen.Brush, shape, clip);\r
+                                       FillScaledShape(pen.Brush, shape);\r
                                }\r
                                finally {\r
                                        NativeObject.setTransform(oldT);\r
@@ -345,23 +324,18 @@ namespace System.Drawing {
                        }\r
                        else {\r
                                awt.Stroke oldStroke = NativeObject.getStroke();\r
-                               NativeObject.setStroke(pen.GetNativeObject(null, false));\r
+                               NativeObject.setStroke(pen.GetNativeObject(null, PenFit.NotThin));\r
                                try {\r
-                                       awt.Paint oldPaint = NativeObject.getPaint();\r
+\r
                                        NativeObject.setPaint(pen.Brush);\r
+\r
+                                       geom.AffineTransform oldT = NativeObject.getTransform();\r
+                                       NativeObject.transform(GetFinalTransform());\r
                                        try {\r
-                                               geom.AffineTransform oldT = NativeObject.getTransform();\r
-                                               NativeObject.transform(GetFinalTransform());\r
-                                               try {\r
-                                                       shape = IntersectUserClip(shape);\r
-                                                       NativeObject.draw(shape);\r
-                                               }\r
-                                               finally {\r
-                                                       NativeObject.setTransform(oldT);\r
-                                               }\r
+                                               NativeObject.draw(shape);\r
                                        }\r
                                        finally {\r
-                                               NativeObject.setPaint(oldPaint);\r
+                                               NativeObject.setTransform(oldT);\r
                                        }\r
                                }\r
                                finally {\r
@@ -369,20 +343,17 @@ namespace System.Drawing {
                                }\r
                        }\r
                }\r
-               void FillShape(awt.Paint paint, awt.Shape shape) {\r
+               void FillShape(Brush paint, awt.Shape shape) {\r
                        if (paint == null)\r
                                throw new ArgumentNullException("brush");\r
 \r
                        geom.AffineTransform oldT = null;\r
-                       geom.Area clip = _clip.NativeObject;\r
                        if (NeedsNormalization) {\r
                                oldT = NativeObject.getTransform();\r
                                geom.AffineTransform t = GetFinalTransform();\r
                                if (!oldT.isIdentity()) {\r
                                        t = (geom.AffineTransform)t.clone();\r
                                        t.preConcatenate(oldT);\r
-                                       clip = (geom.Area)clip.clone();\r
-                                       clip.transform(oldT);\r
                                }\r
                                shape = GetNormalizedShape(shape, t);\r
                        }\r
@@ -396,7 +367,7 @@ namespace System.Drawing {
                                NativeObject.setTransform(Matrix.IdentityTransform.NativeObject);\r
 \r
                        try {\r
-                               FillScaledShape(paint, shape, clip);\r
+                               FillScaledShape(paint, shape);\r
                        }\r
                        finally {\r
                                if (oldT != null)\r
@@ -419,197 +390,23 @@ namespace System.Drawing {
                        return path;\r
                }\r
 \r
-               void FillScaledShape(awt.Paint paint, awt.Shape shape, geom.Area clip) {\r
-                       geom.Rectangle2D r = shape.getBounds2D();\r
-                       awt.Paint oldP = NativeObject.getPaint();\r
-                       NativeObject.setPaint(paint);\r
+               void FillScaledShape(Brush paint, awt.Shape shape) {\r
+                       Matrix m = null;\r
+                       if (!(paint is SolidBrush || paint is HatchBrush) && !_transform.IsIdentity) {\r
+                               m = paint.BrushTransform;\r
+                               paint.BrushMultiplyTransform( _transform );\r
+                       }\r
+\r
                        try {\r
-                               shape = IntersectUserClip(shape, clip);\r
+                               NativeObject.setPaint(paint);\r
                                NativeObject.fill(shape);\r
                        }\r
                        finally {\r
-                               NativeObject.setPaint(oldP);\r
+                               if (m != null)\r
+                                       paint.BrushTransform = m;\r
                        }\r
                }\r
 \r
-               internal SizeF MeasureDraw (string s, Font font, Brush brush, RectangleF layoutRectangle, StringFormat format, bool fDraw) {                    \r
-                       SizeF retVal = new SizeF(0,0);\r
-                       awt.Graphics2D g = NativeObject;\r
-                               \r
-                       java.awt.Font fnt = font.NativeObject;\r
-                       if(s != null && s.Length != 0 && fnt != null) {\r
-                               float size = fnt.getSize();\r
-                               float wid = layoutRectangle.Width;\r
-                               float hei = layoutRectangle.Height;\r
-                               float x = layoutRectangle.X;\r
-                               float y = layoutRectangle.Y;\r
-                               java.text.AttributedString astr = new java.text.AttributedString(s);\r
-                               astr.addAttribute(java.awt.font.TextAttribute.FONT, fnt);\r
-                               java.text.AttributedCharacterIterator prg = astr.getIterator();\r
-                               java.awt.font.TextLayout textlayout = new java.awt.font.TextLayout(prg, g.getFontRenderContext());\r
-                               int prgStart = prg.getBeginIndex();\r
-                               int prgEnd = prg.getEndIndex();\r
-                               java.awt.font.LineBreakMeasurer lineMeasurer = new java.awt.font.LineBreakMeasurer(\r
-                                       prg, new java.awt.font.FontRenderContext(null, false, false));\r
-                               lineMeasurer.setPosition(prgStart);\r
-                               float formatWidth = wid;\r
-                               \r
-                               //some vertical layout magic - should be reviewed\r
-                               //                              if(format != null)\r
-                               //                              {\r
-                               //                                      StringFormatFlags formatflag = format.FormatFlags;\r
-                               //                                      if(formatflag != StringFormatFlags.DirectionVertical)\r
-                               //                                      {\r
-                               //                                              if(size > (float)8 && wid > (float)13)\r
-                               //                                                      formatWidth = wid - (float)12;\r
-                               //                                              if(formatflag ==  StringFormatFlags.DirectionRightToLeft && size == (float)6)\r
-                               //                                                      formatWidth = wid - (float)10;\r
-                               //                                      }\r
-                               //                              }\r
-\r
-                               //now calculate number of lines and full layout height\r
-                               //this is required for LineAlignment calculations....\r
-                               int lines=0;\r
-                               float layHeight=0;\r
-                               float layPrevHeight=0;\r
-                               float layWidth=0;\r
-                               float drawPosY = y;\r
-                               //bool fSkipLastLine = false;\r
-                               java.awt.font.TextLayout layout;\r
-                               java.awt.geom.Rectangle2D bnds = new java.awt.geom.Rectangle2D.Float();\r
-                               while(lineMeasurer.getPosition() < prgEnd) {\r
-                                       layout = lineMeasurer.nextLayout(formatWidth);\r
-                                       lines++;\r
-                                       bnds = bnds.createUnion(layout.getBounds());\r
-                                       layPrevHeight = layHeight;\r
-                                       layHeight += layout.getDescent() + layout.getLeading() + layout.getAscent();\r
-                                       float advance;\r
-                                       if((format != null) && \r
-                                               ((format.FormatFlags & StringFormatFlags.MeasureTrailingSpaces) != 0))\r
-                                               advance = layout.getAdvance();\r
-                                       else\r
-                                               advance = layout.getVisibleAdvance();\r
-                                       if(layWidth < advance)\r
-                                               layWidth = advance;\r
-                                       if((format != null) && ((format.FormatFlags & StringFormatFlags.NoWrap) != 0))\r
-                                               break;\r
-                               }\r
-                               //Overhanging parts of glyphs, and unwrapped text reaching outside \r
-                               //the formatting rectangle are allowed to show. By default all text \r
-                               //and glyph parts reaching outside the formatting rectangle are clipped.\r
-                               if((lines == 1) && \r
-                                       (format != null) && \r
-                                       ((format.FormatFlags & StringFormatFlags.NoClip) != 0)) {\r
-                                       formatWidth = layWidth;                                 \r
-                               }\r
-\r
-                               //Only entire lines are laid out in the formatting rectangle. By default layout \r
-                               //continues until the end of the text, or until no more lines are visible as a \r
-                               //result of clipping, whichever comes first. Note that the default settings allow \r
-                               //the last line to be partially obscured by a formatting rectangle that is not a \r
-                               //whole multiple of the line height. To ensure that only whole lines are seen, specify\r
-                               //this value and be careful to provide a formatting rectangle at least as tall as the \r
-                               //height of one line.\r
-                               if(format != null && ((format.FormatFlags & StringFormatFlags.LineLimit) != 0) && \r
-                                       layHeight > hei && layPrevHeight < hei) {\r
-                                       layHeight = layPrevHeight;\r
-                                       lines--;\r
-                               }\r
-\r
-                               retVal.Height = layHeight;\r
-                               retVal.Width = layWidth+size/2.5f;\r
-                               if(!fDraw)\r
-                                       return retVal;\r
-\r
-                               InternalSetBrush(brush);\r
-                               g.setRenderingHint(awt.RenderingHints.KEY_TEXT_ANTIALIASING, awt.RenderingHints.VALUE_TEXT_ANTIALIAS_ON);\r
-\r
-                               //end measurment\r
-\r
-                               //for draw we should probably update origins\r
-\r
-                               //Vertical...\r
-                               if(format != null) {\r
-                                       StringAlignment align = format.LineAlignment;\r
-                                       if(align == StringAlignment.Center) {\r
-                                               drawPosY = y + (float)hei/2 - layHeight/2;\r
-                                       }\r
-                                       else if(align == StringAlignment.Far) {\r
-                                               drawPosY = (float)y + (float)hei - layHeight;\r
-                                       }\r
-                                       //in both cases if string is not fit - switch to near\r
-                                       if(drawPosY < y)\r
-                                               drawPosY = y;\r
-                               }\r
-\r
-                               //Horisontal... on the fly\r
-                               lineMeasurer.setPosition(prgStart);\r
-                               float drawPosX = x;                             \r
-                               for(int line = 0;line < lines /*lineMeasurer.getPosition() < prgEnd*/;line++, drawPosY += layout.getDescent() + layout.getLeading()) {\r
-                                       layout = lineMeasurer.nextLayout(formatWidth);\r
-                                       drawPosX = x + size / (float)5;//???\r
-                                       drawPosY += layout.getAscent();\r
-                                       if(format != null) {\r
-                                               float advance;\r
-                                               if((format.FormatFlags & StringFormatFlags.MeasureTrailingSpaces) != 0)\r
-                                                       advance = layout.getAdvance();\r
-                                               else\r
-                                                       advance = layout.getVisibleAdvance();\r
-                                               \r
-                                               if(format.Alignment == StringAlignment.Center) {\r
-                                                       drawPosX = (float)((double)x + ((double)formatWidth)/2 - advance/2);\r
-                                               }\r
-                                               else if(format.Alignment == StringAlignment.Far) {\r
-                                                       drawPosX = (float)(drawPosX + formatWidth) - advance;\r
-                                               }\r
-                                               if((format.FormatFlags & StringFormatFlags.DirectionVertical ) != 0) {\r
-                                                       java.awt.geom.AffineTransform at1 = java.awt.geom.AffineTransform.getTranslateInstance(\r
-                                                               drawPosX +  size / (float)5, (drawPosY - layout.getAscent()) + size / (float)5);\r
-\r
-                                                       at1.rotate(Math.PI/2);\r
-                                                       awt.Shape sha = textlayout.getOutline(at1);\r
-                                                       geom.AffineTransform t = GetFinalTransform();\r
-                                                       if (!t.isIdentity())\r
-                                                               sha = t.createTransformedShape(sha);\r
-                                                       //g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);\r
-                                                       sha = IntersectUserClip(sha);\r
-                                                       g.fill(sha);\r
-                                                       continue;\r
-                                               }\r
-                                               if((format.FormatFlags & StringFormatFlags.DirectionRightToLeft)  != 0) {\r
-                                                       drawPosX = ((drawPosX + formatWidth) - advance) + (float)9;\r
-                                                       IntersectScaledClipWithBase(_clip);\r
-                                                       try {\r
-                                                               layout.draw(g, drawPosX, drawPosY);\r
-                                                       }\r
-                                                       finally {\r
-                                                               RestoreBaseClip();\r
-                                                       }\r
-                                               } \r
-                                       }                                       \r
-\r
-                                       geom.AffineTransform oldT = null;\r
-                                       geom.AffineTransform ft = GetFinalTransform();\r
-\r
-                                       //Draw current line\r
-                                       IntersectScaledClipWithBase(_clip);\r
-                                       try {\r
-                                               if (!ft.isIdentity()) {\r
-                                                       oldT = NativeObject.getTransform();\r
-                                                       NativeObject.transform(ft);\r
-                                               }\r
-                                               layout.draw(g, drawPosX, drawPosY);                                     \r
-                                       }\r
-                                       finally {\r
-                                               if (oldT != null)\r
-                                                       NativeObject.setTransform(oldT);\r
-                                               RestoreBaseClip();\r
-                                       }\r
-                               }\r
-                       } //not nulls\r
-\r
-                       return retVal;\r
-               }\r
                #endregion\r
 \r
                #region Dispose\r
@@ -620,7 +417,7 @@ namespace System.Drawing {
                \r
                #region Clear\r
                public void Clear (Color color) {\r
-                       FillScaledShape(color.NativeObject, _clip.NativeObject, null);\r
+                       FillScaledShape(new SolidBrush( color ), _clip.NativeObject);\r
                }\r
                #endregion\r
 \r
@@ -821,7 +618,14 @@ namespace System.Drawing {
                }\r
 \r
                public void DrawImage (Image image, float x, float y) {\r
-                       DrawImage( image, x, y, image.Width, image.Height );\r
+                       if ((image.HorizontalResolution != DpiX) || (image.VerticalResolution != DpiY))\r
+                               DrawImage( image, x, y, \r
+                                       (float)image.Width * (DpiX / image.HorizontalResolution) / _unitConversion[(int)PageUnit], \r
+                                       (float)image.Height * (DpiY / image.VerticalResolution) / _unitConversion[(int)PageUnit]) ;\r
+                       else\r
+                               DrawImage( image, x, y, \r
+                                       (float)image.Width / _unitConversion[(int)PageUnit], \r
+                                       (float)image.Height / _unitConversion[(int)PageUnit] );\r
                }\r
 \r
                \r
@@ -856,7 +660,7 @@ namespace System.Drawing {
                        DrawImage(image, destPoints, srcRect, srcUnit, null);\r
                }\r
 \r
-               \r
+               [MonoTODO]\r
                public void DrawImage (Image image, Point [] destPoints, Rectangle srcRect, GraphicsUnit srcUnit, ImageAttributes imageAttr) {\r
                        //TBD: ImageAttributes\r
                        if (srcUnit != GraphicsUnit.Pixel)\r
@@ -866,16 +670,10 @@ namespace System.Drawing {
                        Matrix mx = new Matrix(srcRect, destPoints);\r
 \r
                        Region region = new Region(srcRect);\r
-                       region.Transform (mx);\r
-                       \r
-                       geom.AffineTransform t = _transform.NativeObject;\r
-                       if (!t.isIdentity())\r
-                               region.NativeObject.transform(t);\r
-                       region.Intersect(_clip);\r
-\r
                        DrawImage(image, mx, region);\r
                }\r
                \r
+               [MonoTODO]\r
                public void DrawImage (Image image, PointF [] destPoints, RectangleF srcRect, GraphicsUnit srcUnit, ImageAttributes imageAttr) {\r
                        //TBD: ImageAttributes\r
                        if (srcUnit != GraphicsUnit.Pixel)\r
@@ -885,13 +683,6 @@ namespace System.Drawing {
                        Matrix mx = new Matrix(srcRect, destPoints);\r
 \r
                        Region region = new Region(srcRect);\r
-                       region.Transform (mx);\r
-                       \r
-                       geom.AffineTransform t = GetFinalTransform();\r
-                       if (!t.isIdentity())\r
-                               region.NativeObject.transform(t);\r
-                       region.Intersect(_clip);\r
-\r
                        DrawImage(image, mx, region);\r
                }\r
 \r
@@ -901,11 +692,8 @@ namespace System.Drawing {
                }\r
 \r
                public void DrawImage (Image image, float x, float y, float width, float height) {\r
-                       geom.Point2D.Float pt = new geom.Point2D.Float(x, y);\r
-                       GetFinalTransform().transform(pt, pt);\r
-\r
                        Matrix mx = new Matrix();\r
-                       mx.Translate((float)pt.getX(), (float)pt.getY());\r
+                       mx.Translate((float)x, (float)y);\r
                        mx.Scale(width / (float)image.Width, height / (float)image.Height);\r
 \r
                        DrawImage( image, mx );\r
@@ -930,6 +718,7 @@ namespace System.Drawing {
                }\r
                \r
 \r
+               [MonoTODO]\r
                public void DrawImage (Image image, Rectangle destRect, int srcX, int srcY, int srcWidth, int srcHeight, GraphicsUnit srcUnit, ImageAttributes imageAttr) {                     \r
                        //TBD: attributes\r
                        DrawImage(\r
@@ -939,6 +728,7 @@ namespace System.Drawing {
                                srcUnit);\r
                }\r
                \r
+               [MonoTODO]\r
                public void DrawImage (Image image, Rectangle destRect, float srcX, float srcY, float srcWidth, float srcHeight, GraphicsUnit srcUnit, ImageAttributes imageAttrs) {\r
                        //TBD: attributes\r
                        DrawImage(\r
@@ -956,28 +746,28 @@ namespace System.Drawing {
                internal void DrawImage (Image image, Matrix m, Region clip) {\r
                        if (clip == null) {\r
                                clip = new Region( new RectangleF( 0, 0, image.Width, image.Height ) );\r
-                               clip.Transform( m );\r
                        }\r
-                       clip.Intersect(_clip);\r
-                       \r
-                       geom.AffineTransform oldT = NativeObject.getTransform();\r
-                       // must set clip before the base transform is altered\r
+\r
+                       geom.AffineTransform t = GetFinalTransform(_transform.NativeObject, PageUnit, 1.0f);\r
+                       if (!t.isIdentity())\r
+                               m.NativeObject.preConcatenate(t);\r
+\r
+                               clip.Transform( m );\r
+\r
                        if (NeedsNormalization) {\r
                                Matrix normMatrix = ComputeClipNormalization(clip.GetBounds(this));\r
                                clip.Transform(normMatrix);\r
                        }\r
 \r
+                       awt.Shape oldClip = NativeObject.getClip();\r
                        IntersectScaledClipWithBase(clip);\r
                        \r
                        try {\r
-                               NativeObject.transform(_transform.NativeObject);\r
-                               \r
                                Matrix mm = ComputeImageNormalization(image, m);\r
                                NativeObject.drawImage(image.NativeObject.CurrentImage.NativeImage, mm.NativeObject, null);\r
                        }\r
                        finally {\r
-                               NativeObject.setTransform(oldT);\r
-                               RestoreBaseClip();\r
+                               NativeObject.setClip( oldClip );\r
                        }\r
                }\r
 \r
@@ -1019,19 +809,20 @@ namespace System.Drawing {
                \r
 \r
 #if INTPTR_SUPPORT\r
+               [MonoTODO]\r
                public void DrawImage (Image image, PointF [] destPoints, RectangleF srcRect, GraphicsUnit srcUnit, ImageAttributes imageAttr, DrawImageAbort callback)\r
                {\r
                        throw new NotImplementedException();\r
                }\r
 \r
-               \r
+               [MonoTODO]\r
                public void DrawImage (Image image, Point [] destPoints, Rectangle srcRect, GraphicsUnit srcUnit, ImageAttributes imageAttr, DrawImageAbort callback)\r
                {\r
                        \r
                        throw new NotImplementedException();\r
                }\r
 \r
-               \r
+               [MonoTODO]\r
                public void DrawImage (Image image, Point [] destPoints, Rectangle srcRect, GraphicsUnit srcUnit, ImageAttributes imageAttr, DrawImageAbort callback, int callbackData)\r
                {\r
                        throw new NotImplementedException();\r
@@ -1039,6 +830,7 @@ namespace System.Drawing {
 #endif\r
 \r
 #if INTPTR_SUPPORT             \r
+               [MonoTODO]\r
                public void DrawImage (Image image, PointF [] destPoints, RectangleF srcRect, GraphicsUnit srcUnit, ImageAttributes imageAttr, DrawImageAbort callback, int callbackData)\r
                {\r
                        throw new NotImplementedException();\r
@@ -1222,46 +1014,96 @@ namespace System.Drawing {
 \r
                #region DrawString\r
                public void DrawString (string s, Font font, Brush brush, RectangleF layoutRectangle) {                 \r
-                       MeasureDraw(s,font,brush,layoutRectangle,null,true);\r
+                       DrawString(s, font, brush, layoutRectangle.X, layoutRectangle.Y, layoutRectangle.Width, layoutRectangle.Height, null);\r
                }\r
                \r
                public void DrawString (string s, Font font, Brush brush, PointF point) {\r
-                       MeasureDraw(s,font,brush,new RectangleF(point.X,point.Y,99999f,99999f),null,true);\r
+                       DrawString(s, font, brush, point.X, point.Y, float.PositiveInfinity, float.PositiveInfinity, null);\r
                }\r
                \r
                public void DrawString (string s, Font font, Brush brush, PointF point, StringFormat format) {\r
-                       MeasureDraw(s,font,brush,new RectangleF(point.X,point.Y,99999f,99999f),format,true);\r
+                       DrawString(s, font, brush, point.X, point.Y, float.PositiveInfinity, float.PositiveInfinity, format);\r
                }\r
 \r
                public void DrawString (string s, Font font, Brush brush, RectangleF layoutRectangle, StringFormat format) {\r
-                       MeasureDraw(s,font,brush,layoutRectangle,format,true);\r
-               }\r
-       \r
-#if false              \r
-               public void DrawString (string s, Font font, Brush brush, RectangleF layoutRectangle, StringFormat format)\r
-               {\r
-                       java.awt.Graphics2D g = (java.awt.Graphics2D)nativeObject;                      \r
-                       //set\r
-                       java.awt.Paint oldpaint = g.getPaint();\r
-                       g.setPaint(brush.NativeObject);\r
-                       java.awt.Font oldfont = g.getFont();\r
-                       g.setFont(font.NativeObject);\r
-                       java.awt.Shape oldb = g.getClip();\r
-                       g.setClip(new java.awt.geom.Rectangle2D.Float(layoutRectangle.X,layoutRectangle.Y,layoutRectangle.Width,layoutRectangle.Height));\r
-                       //draw\r
-                       g.drawString(s,layoutRectangle.X,layoutRectangle.Y+layoutRectangle.Height);\r
-                       //restore\r
-                       g.setPaint(oldpaint);\r
-                       g.setClip(oldb);\r
-                       g.setFont(oldfont);\r
+                       DrawString(s, font, brush, layoutRectangle.X, layoutRectangle.Y, layoutRectangle.Width, layoutRectangle.Height, format);\r
                }\r
-#endif\r
+\r
                public void DrawString (string s, Font font, Brush brush, float x, float y) {\r
-                       MeasureDraw(s,font,brush,new RectangleF(x,y,99999f,99999f),null,true);\r
+                       DrawString(s, font, brush, x, y, float.PositiveInfinity, float.PositiveInfinity, null);\r
                }\r
 \r
                public void DrawString (string s, Font font, Brush brush, float x, float y, StringFormat format) {\r
-                       MeasureDraw(s,font,brush,new RectangleF(x,y,99999f,99999f),format,true);\r
+                       DrawString(s, font, brush, x, y, float.PositiveInfinity, float.PositiveInfinity, format);\r
+               }\r
+\r
+               void DrawString (string s, Font font, Brush brush, \r
+                       float x, float y, float width, float height, \r
+                       StringFormat format) {\r
+                       if (brush == null)\r
+                               throw new ArgumentNullException("brush");\r
+\r
+                       if (font == null)\r
+                               throw new ArgumentNullException("font");\r
+\r
+                       if (format != null && format.LineAlignment != StringAlignment.Near) {\r
+\r
+                               SizeF sizeF = MeasureString(s, font, format, width, height, null);\r
+\r
+                               float lineAWidth = width;\r
+                               float lineAHeight = height;\r
+\r
+                               if (float.IsPositiveInfinity(width))\r
+                                       lineAWidth = lineAHeight = 0;\r
+\r
+                               float wdelta = format.IsVertical ? lineAWidth - sizeF.Width : lineAHeight - sizeF.Height;\r
+                               float pdelta = format.LineAlignment == StringAlignment.Center ? wdelta/2 : wdelta;\r
+                               if (format.IsVertical) {\r
+                                       if (!(format.IsRightToLeft && format.LineAlignment == StringAlignment.Far))\r
+                                               x += pdelta;\r
+                                       if (!float.IsPositiveInfinity(width))\r
+                                               width -= wdelta;\r
+                               }\r
+                               else {\r
+                                       y += pdelta;\r
+                                       if (!float.IsPositiveInfinity(width))\r
+                                               height -= wdelta;\r
+                               }\r
+                       }\r
+\r
+                       awt.Paint oldP = NativeObject.getPaint();\r
+                       NativeObject.setPaint(brush);\r
+                       try {\r
+                               geom.AffineTransform oldT = NativeObject.getTransform();\r
+                               NativeObject.transform(GetFinalTransform());\r
+                               try {\r
+\r
+                                       bool noclip = float.IsPositiveInfinity(width) || (format != null && format.NoClip);\r
+\r
+                                       awt.Shape oldClip = null;\r
+                                       if (!noclip) {\r
+                                               oldClip = NativeObject.getClip();\r
+                                               NativeObject.clip(new geom.Rectangle2D.Float(x, y, width, height));\r
+                                       }\r
+                                       try {\r
+                                               TextLineIterator iter = new TextLineIterator(s, font, NativeObject.getFontRenderContext(), format, width, height);\r
+                                               NativeObject.transform(iter.Transform);\r
+                                               for (LineLayout layout = iter.NextLine(); layout != null; layout = iter.NextLine()) {\r
+                                                       layout.Draw(NativeObject, x, y);\r
+                                               }\r
+                                       }\r
+                                       finally {\r
+                                               if (!noclip)\r
+                                                       NativeObject.setClip(oldClip);\r
+                                       }\r
+                               }\r
+                               finally {\r
+                                       NativeObject.setTransform(oldT);\r
+                               }\r
+                       }\r
+                       finally {\r
+                               NativeObject.setPaint(oldP);\r
+                       }\r
                }\r
                #endregion\r
 \r
@@ -1306,7 +1148,7 @@ namespace System.Drawing {
                                                                 new Point (dstrect.X + dstrect.Width, dstrect.Y), \r
                                                                 new Point (dstrect.X, dstrect.Y + dstrect.Height) });\r
 \r
-                       float scale = 1/_unitConversion[ (int)unit ];\r
+                       float scale = _unitConversion[ (int)PageUnit ] / _unitConversion[ (int)unit ];\r
                        containerTransfrom.Scale(scale, scale);\r
 \r
                        return new GraphicsContainer(Save(containerTransfrom, true));\r
@@ -1320,7 +1162,7 @@ namespace System.Drawing {
                                                                 new PointF (dstrect.X + dstrect.Width, dstrect.Y), \r
                                                                 new PointF (dstrect.X, dstrect.Y + dstrect.Height) });\r
 \r
-                       float scale = 1/_unitConversion[ (int)unit ];\r
+                       float scale = _unitConversion[ (int)PageUnit ] / _unitConversion[ (int)unit ];\r
                        containerTransfrom.Scale(scale, scale);\r
 \r
                        return new GraphicsContainer(Save(containerTransfrom, true));\r
@@ -1349,187 +1191,224 @@ namespace System.Drawing {
 \r
                #endregion\r
 \r
-               #region Metafiles Staff [TODO NotSupp]\r
+               #region Metafiles Staff\r
+               [MonoTODO]\r
                public void AddMetafileComment (byte [] data) {\r
                        throw new NotImplementedException ();\r
                }\r
 \r
 #if INTPTR_SUPPORT\r
+               [MonoTODO]\r
                public void EnumerateMetafile (Metafile metafile, Point [] destPoints, EnumerateMetafileProc callback)\r
                {\r
                        throw new NotImplementedException ();\r
                }\r
 \r
+               [MonoTODO]\r
                public void EnumerateMetafile (Metafile metafile, RectangleF destRect, EnumerateMetafileProc callback)\r
                {\r
                        throw new NotImplementedException ();\r
                }\r
 \r
+               [MonoTODO]\r
                public void EnumerateMetafile (Metafile metafile, PointF [] destPoints, EnumerateMetafileProc callback)\r
                {\r
                        throw new NotImplementedException ();\r
                }\r
 \r
+               [MonoTODO]\r
                public void EnumerateMetafile (Metafile metafile, Rectangle destRect, EnumerateMetafileProc callback)\r
                {\r
                        throw new NotImplementedException ();\r
                }\r
 \r
+               [MonoTODO]\r
                public void EnumerateMetafile (Metafile metafile, Point destPoint, EnumerateMetafileProc callback)\r
                {\r
                        throw new NotImplementedException ();\r
                }\r
 \r
+               [MonoTODO]\r
                public void EnumerateMetafile (Metafile metafile, PointF destPoint, EnumerateMetafileProc callback)\r
                {\r
                        throw new NotImplementedException ();\r
                }\r
 \r
+               [MonoTODO]\r
                public void EnumerateMetafile (Metafile metafile, PointF destPoint, EnumerateMetafileProc callback, IntPtr callbackData)\r
                {\r
                        throw new NotImplementedException ();\r
                }\r
 \r
+               [MonoTODO]\r
                public void EnumerateMetafile (Metafile metafile, Rectangle destRect, EnumerateMetafileProc callback, IntPtr callbackData)\r
                {\r
                        throw new NotImplementedException ();\r
                }\r
 \r
+               [MonoTODO]\r
                public void EnumerateMetafile (Metafile metafile, PointF [] destPoints, EnumerateMetafileProc callback, IntPtr callbackData)\r
                {\r
                        throw new NotImplementedException ();\r
                }\r
 \r
+               [MonoTODO]\r
                public void EnumerateMetafile (Metafile metafile, Point destPoint, EnumerateMetafileProc callback, IntPtr callbackData)\r
                {\r
                        throw new NotImplementedException ();\r
                }\r
 \r
+               [MonoTODO]\r
                public void EnumerateMetafile (Metafile metafile, Point [] destPoints, EnumerateMetafileProc callback, IntPtr callbackData)\r
                {\r
                        throw new NotImplementedException ();\r
                }\r
 \r
+               [MonoTODO]\r
                public void EnumerateMetafile (Metafile metafile, RectangleF destRect, EnumerateMetafileProc callback, IntPtr callbackData)\r
                {\r
                        throw new NotImplementedException ();\r
                }\r
 \r
+               [MonoTODO]\r
                public void EnumerateMetafile (Metafile metafile, PointF destPoint, RectangleF srcRect, GraphicsUnit srcUnit, EnumerateMetafileProc callback)\r
                {\r
                        throw new NotImplementedException ();\r
                }\r
 \r
+               [MonoTODO]\r
                public void EnumerateMetafile (Metafile metafile, Point destPoint, Rectangle srcRect, GraphicsUnit srcUnit, EnumerateMetafileProc callback)\r
                {\r
                        throw new NotImplementedException ();\r
                }\r
 \r
+               [MonoTODO]\r
                public void EnumerateMetafile (Metafile metafile, PointF [] destPoints, RectangleF srcRect, GraphicsUnit srcUnit, EnumerateMetafileProc callback)\r
                {\r
                        throw new NotImplementedException ();\r
                }\r
 \r
+               [MonoTODO]\r
                public void EnumerateMetafile (Metafile metafile, Point [] destPoints, Rectangle srcRect, GraphicsUnit srcUnit, EnumerateMetafileProc callback)\r
                {\r
                        throw new NotImplementedException ();\r
                }\r
 \r
+               [MonoTODO]\r
                public void EnumerateMetafile (Metafile metafile, RectangleF destRect, RectangleF srcRect, GraphicsUnit srcUnit, EnumerateMetafileProc callback)\r
                {\r
                        throw new NotImplementedException ();\r
                }\r
 \r
+               [MonoTODO]\r
                public void EnumerateMetafile (Metafile metafile, Rectangle destRect, Rectangle srcRect, GraphicsUnit srcUnit, EnumerateMetafileProc callback)\r
                {\r
                        throw new NotImplementedException ();\r
                }\r
 \r
+               [MonoTODO]\r
                public void EnumerateMetafile (Metafile metafile, RectangleF destRect, EnumerateMetafileProc callback, IntPtr callbackData, ImageAttributes imageAttr)\r
                {\r
                        throw new NotImplementedException ();\r
                }\r
 \r
+               [MonoTODO]\r
                public void EnumerateMetafile (Metafile metafile, Point destPoint, EnumerateMetafileProc callback, IntPtr callbackData, ImageAttributes imageAttr)\r
                {\r
                        throw new NotImplementedException ();\r
                }\r
 \r
+               [MonoTODO]\r
                public void EnumerateMetafile (Metafile metafile, PointF destPoint, EnumerateMetafileProc callback, IntPtr callbackData, ImageAttributes imageAttr)\r
                {\r
                        throw new NotImplementedException ();\r
                }\r
 \r
+               [MonoTODO]\r
                public void EnumerateMetafile (Metafile metafile, Point [] destPoints, EnumerateMetafileProc callback, IntPtr callbackData, ImageAttributes imageAttr)\r
                {\r
                        throw new NotImplementedException ();\r
                }\r
 \r
+               [MonoTODO]\r
                public void EnumerateMetafile (Metafile metafile, PointF [] destPoints, EnumerateMetafileProc callback, IntPtr callbackData, ImageAttributes imageAttr)\r
                {\r
                        throw new NotImplementedException ();\r
                }\r
 \r
+               [MonoTODO]\r
                public void EnumerateMetafile (Metafile metafile, Rectangle destRect, EnumerateMetafileProc callback, IntPtr callbackData, ImageAttributes imageAttr)\r
                {\r
                        throw new NotImplementedException ();\r
                }\r
 \r
+               [MonoTODO]\r
                public void EnumerateMetafile (Metafile metafile, Rectangle destRect, Rectangle srcRect, GraphicsUnit srcUnit, EnumerateMetafileProc callback, IntPtr callbackData)\r
                {\r
                        throw new NotImplementedException ();\r
                }\r
 \r
+               [MonoTODO]\r
                public void EnumerateMetafile (Metafile metafile, PointF [] destPoints, RectangleF srcRect, GraphicsUnit srcUnit, EnumerateMetafileProc callback, IntPtr callbackData)\r
                {\r
                        throw new NotImplementedException ();\r
                }\r
 \r
+               [MonoTODO]\r
                public void EnumerateMetafile (Metafile metafile, RectangleF destRect, RectangleF srcRect, GraphicsUnit srcUnit, EnumerateMetafileProc callback, IntPtr callbackData)\r
                {\r
                        throw new NotImplementedException ();\r
                }\r
 \r
+               [MonoTODO]\r
                public void EnumerateMetafile (Metafile metafile, PointF destPoint, RectangleF srcRect, GraphicsUnit srcUnit, EnumerateMetafileProc callback, IntPtr callbackData)\r
                {\r
                        throw new NotImplementedException ();\r
                }\r
 \r
+               [MonoTODO]\r
                public void EnumerateMetafile (Metafile metafile, Point destPoint, Rectangle srcRect, GraphicsUnit srcUnit, EnumerateMetafileProc callback, IntPtr callbackData)\r
                {\r
                        throw new NotImplementedException ();\r
                }\r
 \r
+               [MonoTODO]\r
                public void EnumerateMetafile (Metafile metafile, Point [] destPoints, Rectangle srcRect, GraphicsUnit srcUnit, EnumerateMetafileProc callback, IntPtr callbackData)\r
                {\r
                        throw new NotImplementedException ();\r
                }\r
 \r
+               [MonoTODO]\r
                public void EnumerateMetafile (Metafile metafile, Point [] destPoints, Rectangle srcRect, GraphicsUnit unit, EnumerateMetafileProc callback, IntPtr callbackData, ImageAttributes imageAttr)\r
                {\r
                        throw new NotImplementedException ();\r
                }\r
 \r
+               [MonoTODO]\r
                public void EnumerateMetafile (Metafile metafile, Rectangle destRect, Rectangle srcRect, GraphicsUnit unit, EnumerateMetafileProc callback, IntPtr callbackData, ImageAttributes imageAttr)\r
                {\r
                        throw new NotImplementedException ();\r
                }\r
 \r
+               [MonoTODO]\r
                public void EnumerateMetafile (Metafile metafile, Point destPoint, Rectangle srcRect, GraphicsUnit unit, EnumerateMetafileProc callback, IntPtr callbackData, ImageAttributes imageAttr)\r
                {\r
                        throw new NotImplementedException ();\r
                }\r
 \r
+               [MonoTODO]\r
                public void EnumerateMetafile (Metafile metafile, RectangleF destRect, RectangleF srcRect, GraphicsUnit unit, EnumerateMetafileProc callback, IntPtr callbackData, ImageAttributes imageAttr)\r
                {\r
                        throw new NotImplementedException ();\r
                }\r
 \r
+               [MonoTODO]\r
                public void EnumerateMetafile (Metafile metafile, PointF [] destPoints, RectangleF srcRect, GraphicsUnit unit, EnumerateMetafileProc callback, IntPtr callbackData, ImageAttributes imageAttr)\r
                {\r
                        throw new NotImplementedException ();\r
                }\r
 \r
+               [MonoTODO]\r
                public void EnumerateMetafile (Metafile metafile, PointF destPoint, RectangleF srcRect, GraphicsUnit unit, EnumerateMetafileProc callback, IntPtr callbackData, ImageAttributes imageAttr)\r
                {\r
                        throw new NotImplementedException ();\r
@@ -1547,6 +1426,8 @@ namespace System.Drawing {
                        }\r
 \r
                        _clip.NativeObject.subtract(area);\r
+                       RestoreBaseClip();\r
+                       NativeObject.clip(_clip);\r
                }\r
 \r
                public void ExcludeClip (Rectangle rect) {\r
@@ -1706,65 +1587,76 @@ namespace System.Drawing {
 \r
 #if INTPTR_SUPPORTED\r
                [EditorBrowsable (EditorBrowsableState.Advanced)]\r
+               [MonoTODO]\r
                public void ReleaseHdc (IntPtr hdc)\r
                {\r
                        throw new NotImplementedException();\r
                }\r
 \r
                [EditorBrowsable (EditorBrowsableState.Advanced)]\r
+               [MonoTODO]\r
                public void ReleaseHdcInternal (IntPtr hdc)\r
                {\r
                        throw new NotImplementedException ();\r
                }\r
 \r
                [EditorBrowsable (EditorBrowsableState.Advanced)]               \r
+               [MonoTODO]\r
                public static Graphics FromHdc (IntPtr hdc)\r
                {\r
                        throw new NotImplementedException();\r
                }\r
 \r
                [EditorBrowsable (EditorBrowsableState.Advanced)]\r
+               [MonoTODO]\r
                public static Graphics FromHdc (IntPtr hdc, IntPtr hdevice)\r
                {\r
                        throw new NotImplementedException ();\r
                }\r
 \r
                [EditorBrowsable (EditorBrowsableState.Advanced)]\r
+               [MonoTODO]\r
                public static Graphics FromHdcInternal (IntPtr hdc)\r
                {\r
                        throw new NotImplementedException ();\r
                }\r
 \r
                [EditorBrowsable (EditorBrowsableState.Advanced)]               \r
+               [MonoTODO]\r
                public static Graphics FromHwnd (IntPtr hwnd)\r
                {\r
                        throw new NotImplementedException();\r
                }\r
 \r
                [EditorBrowsable (EditorBrowsableState.Advanced)]\r
+               [MonoTODO]\r
                public static Graphics FromHwndInternal (IntPtr hwnd)\r
                {\r
                        throw new NotImplementedException ();\r
                }\r
 \r
+               [MonoTODO]\r
                internal static Graphics FromXDrawable (IntPtr drawable, IntPtr display)\r
                {\r
                        throw new NotImplementedException();\r
                }\r
 \r
+               [MonoTODO]\r
                public static IntPtr GetHalftonePalette ()\r
                {\r
                        throw new NotImplementedException ();\r
                }\r
 \r
                [EditorBrowsable (EditorBrowsableState.Advanced)]\r
+               [MonoTODO]\r
                public IntPtr GetHdc ()\r
                {\r
                        throw new NotImplementedException();\r
                }\r
 #endif\r
                \r
-               #region GetNearestColor [TODO]\r
+               #region GetNearestColor\r
+               [MonoTODO]\r
                public Color GetNearestColor (Color color) {\r
                        throw new NotImplementedException();\r
                }\r
@@ -1780,6 +1672,8 @@ namespace System.Drawing {
                        }\r
 \r
                        _clip.NativeObject.intersect(area);\r
+                       RestoreBaseClip();\r
+                       NativeObject.clip(_clip);\r
                }\r
 \r
                public void IntersectClip (Region region) {\r
@@ -1861,47 +1755,178 @@ namespace System.Drawing {
                }\r
                #endregion\r
 \r
-               #region MeasureCharacterRanges [TODO]\r
+               #region MeasureCharacterRanges\r
                public Region [] MeasureCharacterRanges (string text, Font font, RectangleF layoutRect, StringFormat stringFormat) {\r
-                       throw new NotImplementedException();\r
+                       if (stringFormat == null)\r
+                               throw new ArgumentException("stringFormat");\r
+\r
+                       CharacterRange[] ranges = stringFormat.CharRanges;\r
+                       if (ranges == null || ranges.Length == 0)\r
+                               return new Region[0];\r
+\r
+                       GraphicsPath[] pathes = new GraphicsPath[ranges.Length];\r
+                       for (int i = 0; i < pathes.Length; i++)\r
+                               pathes[i] = new GraphicsPath();\r
+\r
+                       TextLineIterator iter = new TextLineIterator(text, font, NativeObject.getFontRenderContext(),\r
+                               stringFormat, layoutRect.Width, layoutRect.Height);\r
+                       \r
+                       for (LineLayout layout = iter.NextLine(); layout != null; layout = iter.NextLine()) {\r
+\r
+                               for (int i = 0; i < ranges.Length; i++) {\r
+                                       int start = ranges[i].First;\r
+                                       int length = ranges[i].Length;\r
+                                       start -= iter.CharsConsumed;\r
+                                       int limit = start + length;\r
+                                       int layoutStart = iter.CurrentPosition - layout.CharacterCount;\r
+                                       if (start < iter.CurrentPosition && limit > layoutStart) {\r
+\r
+                                               float layoutOffset;\r
+                                               if (start > layoutStart)\r
+                                                       layoutOffset = iter.GetAdvanceBetween(layoutStart, start);\r
+                                               else {\r
+                                                       layoutOffset = 0;\r
+                                                       start = layoutStart;\r
+                                               }\r
+\r
+                                               float width = (limit < iter.CurrentPosition) ?\r
+                                                       iter.GetAdvanceBetween(start, limit) :\r
+                                                       layout.Width - layoutOffset;\r
+\r
+                                               float height = layout.Ascent + layout.Descent;\r
+\r
+                                               float x = layout.NativeX;\r
+                                               float y = layout.NativeY;\r
+\r
+                                               if (stringFormat.IsVertical) {\r
+                                                       y += layoutOffset;\r
+                                                       x -= layout.Descent;\r
+                                               }\r
+                                               else {\r
+                                                       x += layoutOffset;\r
+                                                       y -= layout.Ascent;\r
+                                               }\r
+\r
+                                               if (layout.AccumulatedHeight + height > iter.WrapHeight) {\r
+                                                       float diff = iter.WrapHeight - layout.AccumulatedHeight;\r
+                                                       if (stringFormat.IsVertical && stringFormat.IsRightToLeft) {\r
+                                                               x += diff;\r
+                                                               height -= diff;\r
+                                                       }\r
+                                                       else\r
+                                                               height = diff;\r
+                                               }\r
+\r
+                                               if (stringFormat.IsVertical)\r
+                                                       pathes[i].AddRectangle(x + layoutRect.X, y + layoutRect.Y, height, width);\r
+                                               else\r
+                                                       pathes[i].AddRectangle(x + layoutRect.X, y + layoutRect.Y, width, height);\r
+                                       }\r
+                               }\r
+                       }\r
+\r
+                       geom.AffineTransform lineAlignT = iter.CalcLineAlignmentTransform();\r
+                       if (lineAlignT != null) {\r
+                               for (int i = 0; i < pathes.Length; i++)\r
+                                       pathes[i].NativeObject.transform(lineAlignT);\r
+                       }\r
+\r
+                       Region[] regions = new Region[ranges.Length];\r
+                       for (int i = 0; i < regions.Length; i++)\r
+                               regions[i] = new Region(pathes[i]);\r
+\r
+                       return regions;\r
                }\r
                #endregion\r
                \r
-               #region MeasureString [1 method still TODO]\r
+               #region MeasureString\r
                public SizeF MeasureString (string text, Font font) {\r
-                       return MeasureDraw(text,font,null,new RectangleF(0,0,99999f,99999f),null,false);\r
+                       return MeasureString(text, font, null, float.PositiveInfinity, float.PositiveInfinity, null); \r
                }\r
 \r
                \r
                public SizeF MeasureString (string text, Font font, SizeF layoutArea) {\r
-                       return MeasureDraw(text,font,null,new RectangleF(0,0,layoutArea.Width,layoutArea.Height),null,false);\r
+                       return MeasureString(text, font, layoutArea, null);\r
                }\r
 \r
                \r
                public SizeF MeasureString (string text, Font font, int width) {\r
-                       return MeasureDraw(text,font,null,new RectangleF(0,0,(float)width,99999f),null,false);\r
+                       return MeasureString(text, font, width, null);\r
                }\r
 \r
 \r
                public SizeF MeasureString (string text, Font font, SizeF layoutArea, StringFormat format) {\r
-                       return MeasureDraw(text,font,null,new RectangleF(0,0,layoutArea.Width,layoutArea.Height),format,false);\r
+                       return MeasureString(text, font, format, layoutArea.Width, layoutArea.Height, null);\r
                }\r
 \r
                \r
                public SizeF MeasureString (string text, Font font, int width, StringFormat format) {\r
-                       return MeasureDraw(text,font,null,new RectangleF(0,0,(float)width,99999f),format,false);\r
+                       return MeasureString(text, font, format, width, float.PositiveInfinity, null);\r
                }\r
 \r
                \r
                public SizeF MeasureString (string text, Font font, PointF origin, StringFormat format) {\r
-                       //TBD: MeasureDraw still not dealing with clipping region of dc\r
-                       return MeasureDraw(text,font,null,new RectangleF(origin.X,origin.Y,99999f,99999f),format,false);\r
+                       return MeasureString(text, font, format, float.PositiveInfinity, float.PositiveInfinity, null);\r
+               }\r
+\r
+               SizeF MeasureString (string text, Font font, StringFormat format, float width, float height, int[] statistics) {\r
+\r
+                       if (statistics != null) {\r
+                               statistics[0] = 0;\r
+                               statistics[1] = 0;\r
+                       }\r
+\r
+                       TextLineIterator iter = new TextLineIterator(text, font, NativeObject.getFontRenderContext(), format, width, height);\r
+\r
+                       float mwidth = 0;\r
+                       int linesFilled = 0;\r
+                       for (LineLayout layout = iter.NextLine(); layout != null; layout = iter.NextLine()) {\r
+\r
+                               linesFilled ++;\r
+                               float w = layout.MeasureWidth;\r
+\r
+                               if (w > mwidth)\r
+                                       mwidth = w;\r
+                       }\r
+\r
+                       if (linesFilled == 0)\r
+                               return SizeF.Empty;\r
+\r
+                       float mheight = iter.AccumulatedHeight;\r
+\r
+                       if (format != null) {\r
+                               if (format.IsVertical) {\r
+                                       float temp = mheight;\r
+                                       mheight = mwidth;\r
+                                       mwidth = temp;\r
+                               }\r
+                       }\r
+\r
+                       if (!(format != null && format.NoClip)) {\r
+                               if (mwidth > width)\r
+                                       mwidth = width;\r
+                               if (mheight > height)\r
+                                       mheight = height;\r
+                       }\r
+\r
+                       if (statistics != null) {\r
+                               statistics[0] = linesFilled;\r
+                               statistics[1] = iter.CharsConsumed;\r
+                       }\r
+\r
+                       return new SizeF(mwidth, mheight);\r
                }\r
 \r
                \r
                public SizeF MeasureString (string text, Font font, SizeF layoutArea, StringFormat stringFormat, out int charactersFitted, out int linesFilled) {       \r
-                       //TBD: charcount\r
-                       throw new NotImplementedException();\r
+                       linesFilled = 0;\r
+                       charactersFitted = 0;\r
+\r
+                       int[] statistics = new int[2];\r
+                       SizeF sz = MeasureString(text, font, stringFormat, layoutArea.Width, layoutArea.Height, statistics);\r
+                       linesFilled = statistics[0];\r
+                       charactersFitted = statistics[1];\r
+                       return sz;\r
                }\r
                #endregion\r
 \r
@@ -1918,6 +1943,8 @@ namespace System.Drawing {
                #region Reset (Clip and Transform)\r
                public void ResetClip () {\r
                        _clip.MakeInfinite();\r
+                       RestoreBaseClip();\r
+                       NativeObject.clip(_clip);\r
                }\r
 \r
                public void ResetTransform () {\r
@@ -2017,51 +2044,41 @@ namespace System.Drawing {
                        if (combineMode == CombineMode.Replace) {\r
                                _clip.NativeObject.reset();\r
                                _clip.NativeObject.add(area);\r
-                               return;\r
                        }\r
-\r
-                       geom.Area curClip = _clip.NativeObject;\r
-                       switch(combineMode) {\r
-                               case CombineMode.Complement:\r
-                                       curClip.add(area);\r
-                                       break;\r
-                               case CombineMode.Exclude:\r
-                                       curClip.subtract(area);\r
-                                       break;\r
-                               case CombineMode.Intersect:\r
-                                       curClip.intersect(area);\r
-                                       break;\r
-                               case CombineMode.Union:\r
-                                       curClip.add(area);\r
-                                       break;\r
-                               case CombineMode.Xor:\r
-                                       curClip.exclusiveOr(area);\r
-                                       break;\r
-                               default:\r
-                                       throw new ArgumentOutOfRangeException();                                        \r
+                       else {\r
+                               geom.Area curClip = _clip.NativeObject;\r
+                               switch(combineMode) {\r
+                                       case CombineMode.Complement:\r
+                                               curClip.add(area);\r
+                                               break;\r
+                                       case CombineMode.Exclude:\r
+                                               curClip.subtract(area);\r
+                                               break;\r
+                                       case CombineMode.Intersect:\r
+                                               curClip.intersect(area);\r
+                                               break;\r
+                                       case CombineMode.Union:\r
+                                               curClip.add(area);\r
+                                               break;\r
+                                       case CombineMode.Xor:\r
+                                               curClip.exclusiveOr(area);\r
+                                               break;\r
+                                       default:\r
+                                               throw new ArgumentOutOfRangeException();                                        \r
+                               }\r
                        }\r
+\r
+                       RestoreBaseClip();\r
+                       NativeObject.clip(_clip);\r
                }\r
 \r
                internal void IntersectScaledClipWithBase(awt.Shape clip) {\r
                        NativeObject.clip(clip);\r
                }\r
 \r
-               awt.Shape IntersectUserClip(awt.Shape shape, geom.Area clip) {\r
-                       if (clip == null)\r
-                               return shape;\r
-\r
-                       geom.Area area = new geom.Area(shape);\r
-                       area.intersect(clip);\r
-                       return area;\r
-               }\r
-\r
-               awt.Shape IntersectUserClip(awt.Shape shape) {\r
-                       return IntersectUserClip(shape, _clip.NativeObject);\r
-               }\r
-\r
                void RestoreBaseClip() {\r
                        if (_nextGraphicsState == null) {\r
-                               NativeObject.setClip(null);\r
+                               NativeObject.setClip(_windowRect);\r
                                return;\r
                        }\r
 \r
@@ -2071,6 +2088,7 @@ namespace System.Drawing {
                #endregion\r
                \r
                #region TransformPoints\r
+               [MonoTODO]\r
                public void TransformPoints (CoordinateSpace destSpace, CoordinateSpace srcSpace, PointF [] pts) {\r
                        //TBD:CoordinateSpace\r
                        java.awt.geom.AffineTransform tr = this.Transform.NativeObject;\r
@@ -2084,6 +2102,7 @@ namespace System.Drawing {
                        }\r
                }\r
 \r
+               [MonoTODO]\r
                public void TransformPoints (CoordinateSpace destSpace, CoordinateSpace srcSpace, Point [] pts) {                                               \r
                        //TBD:CoordinateSpace\r
                        java.awt.geom.AffineTransform tr = this.Transform.NativeObject;\r
@@ -2124,6 +2143,8 @@ namespace System.Drawing {
                        geom.AffineTransform t = geom.AffineTransform.getTranslateInstance(x, y);\r
 \r
                        _clip.NativeObject.transform(t);\r
+                       RestoreBaseClip();\r
+                       NativeObject.clip(_clip);\r
                }\r
                #endregion\r
 \r
@@ -2352,6 +2373,7 @@ namespace System.Drawing {
                        }\r
                }\r
 \r
+               [MonoTODO]\r
                public Point RenderingOrigin {\r
                        get {\r
                                throw new NotImplementedException();\r
@@ -2430,30 +2452,49 @@ namespace System.Drawing {
 \r
                public TextRenderingHint TextRenderingHint {\r
                        get {\r
-                               awt.RenderingHints hints = NativeObject.getRenderingHints();\r
-                               if(hints.containsKey(java.awt.RenderingHints.KEY_TEXT_ANTIALIASING)) {\r
-                                       if(hints.get(java.awt.RenderingHints.KEY_TEXT_ANTIALIASING) == \r
-                                               java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_ON)\r
-                                               return TextRenderingHint.AntiAlias;\r
-                                       if(hints.get(java.awt.RenderingHints.KEY_TEXT_ANTIALIASING) == \r
-                                               java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_OFF)\r
-                                               return TextRenderingHint.SingleBitPerPixel;\r
-                               }\r
-                               return TextRenderingHint.SystemDefault;\r
+                               return _textRenderingHint;\r
+//                             awt.RenderingHints hints = NativeObject.getRenderingHints();\r
+//                             if(hints.containsKey(java.awt.RenderingHints.KEY_TEXT_ANTIALIASING)) {\r
+//                                     if(hints.get(java.awt.RenderingHints.KEY_TEXT_ANTIALIASING) == \r
+//                                             java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_ON)\r
+//                                             return TextRenderingHint.AntiAlias;\r
+//                                     if(hints.get(java.awt.RenderingHints.KEY_TEXT_ANTIALIASING) == \r
+//                                             java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_OFF)\r
+//                                             return TextRenderingHint.SingleBitPerPixel;\r
+//                             }\r
+//                             //return TextRenderingHint.SystemDefault;\r
+//                             return TextRenderingHint.SingleBitPerPixelGridFit;\r
                        }\r
 \r
                        set {\r
-                               // TODO implement\r
+                               _textRenderingHint = value;\r
                                awt.RenderingHints hints = NativeObject.getRenderingHints();\r
                                switch (value) {\r
                                        case TextRenderingHint.AntiAlias:\r
                                        case TextRenderingHint.AntiAliasGridFit:\r
                                        case TextRenderingHint.ClearTypeGridFit:\r
-                                       case TextRenderingHint.SingleBitPerPixel:\r
+//                                     case TextRenderingHint.SystemDefault:\r
+                                               hints.put(awt.RenderingHints.KEY_TEXT_ANTIALIASING,\r
+                                                       awt.RenderingHints.VALUE_TEXT_ANTIALIAS_ON);\r
+                                               break;\r
+                                       \r
                                        case TextRenderingHint.SingleBitPerPixelGridFit:\r
+                                               hints.put(awt.RenderingHints.KEY_TEXT_ANTIALIASING,\r
+                                                       awt.RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT);\r
+                                               break;\r
+\r
+                                       case TextRenderingHint.SingleBitPerPixel:\r
+                                               hints.put(awt.RenderingHints.KEY_TEXT_ANTIALIASING,\r
+                                                       awt.RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);\r
+                                               break;\r
+\r
                                        case TextRenderingHint.SystemDefault:\r
+                                               hints.put(awt.RenderingHints.KEY_TEXT_ANTIALIASING,\r
+                                                       awt.RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT);\r
                                                break;\r
                                }\r
+                               \r
+                               NativeObject.setRenderingHints(hints);\r
                        }\r
                }\r
 \r
@@ -2500,6 +2541,9 @@ namespace System.Drawing {
                                awt.Shape clip = NativeObject.getClip();\r
                                geom.Rectangle2D clipBounds = (clip != null) ? clip.getBounds2D() : _windowRect;\r
                                geom.Rectangle2D.intersect(r, clipBounds, r);\r
+                               if ((r.getWidth() <= 0) || (r.getHeight() <= 0))\r
+                                       return RectangleF.Empty;\r
+\r
                                geom.AffineTransform t = GetFinalTransform();\r
                                if (!t.isIdentity()) {\r
                                        geom.AffineTransform it = t.createInverse();\r