using System.Drawing.Imaging;\r
using System.Drawing.Text;\r
using System.ComponentModel;\r
+using System.Collections;\r
using System.Runtime.InteropServices;\r
using System.Text;\r
using awt = java.awt;\r
namespace System.Drawing {\r
[ComVisible(false)]\r
public sealed class Graphics : MarshalByRefObject, IDisposable {\r
+ sealed class DummyStroke : awt.Stroke {\r
+ #region Stroke Members\r
+\r
+ awt.Shape awt.Stroke.createStrokedShape(awt.Shape arg_0) {\r
+ throw new NotImplementedException("DummyStroke");\r
+ }\r
+\r
+ #endregion\r
+ }\r
+\r
+ sealed class NormalizingPathIterator : geom.PathIterator {\r
+\r
+ #region fields\r
+\r
+ readonly geom.PathIterator _iter;\r
+\r
+ const float norm = 0.5f;\r
+ const float rnd = (1.0f - norm);\r
+ float ax = 0.0f;\r
+ float ay = 0.0f;\r
+\r
+ #endregion\r
+\r
+ #region ctor\r
+\r
+ public NormalizingPathIterator(geom.PathIterator iter) {\r
+ _iter = iter;\r
+ }\r
+\r
+ #endregion\r
+\r
+ #region methods\r
+\r
+ static int GetIndex(int type) {\r
+ int index;\r
+ 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
+ }\r
+\r
+ #endregion\r
+\r
+ #region PathIterator Members\r
+\r
+ void geom.PathIterator.next() {\r
+ _iter.next();\r
+ }\r
+\r
+ bool geom.PathIterator.isDone() {\r
+ return _iter.isDone();\r
+ }\r
+\r
+ int geom.PathIterator.currentSegment(float[] point) {\r
+ int type = _iter.currentSegment(point);\r
+\r
+ 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
+ }\r
+\r
+ int geom.PathIterator.currentSegment(double[] point) {\r
+ int type = _iter.currentSegment(point);\r
+\r
+ 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
+ }\r
+\r
+ int geom.PathIterator.getWindingRule() {\r
+ return _iter.getWindingRule();\r
+ }\r
+\r
+ #endregion\r
+\r
+ }\r
+\r
+\r
#region Variables\r
\r
readonly awt.Graphics2D _nativeObject;\r
PixelOffsetMode _pixelOffsetMode = PixelOffsetMode.Default;\r
int _textContrast = 4;\r
+ TextRenderingHint _textRenderingHint;\r
readonly Image _image;\r
\r
- Matrix _transform;\r
+ readonly Matrix _transform;\r
GraphicsUnit _pageUnit = GraphicsUnit.Display;\r
float _pageScale = 1.0f;\r
\r
+ readonly Region _clip;\r
+ readonly awt.Rectangle _windowRect;\r
+\r
+ GraphicsState _nextGraphicsState = null;\r
+\r
static readonly float [] _unitConversion = {\r
1, // World\r
1, // Display\r
DefaultScreenResolution / 25.4f // Millimeter\r
};\r
\r
- static internal readonly bool IsHeadless;\r
+ static int _isHeadless;\r
+ static internal bool IsHeadless {\r
+ get {\r
+ if (_isHeadless == 0) {\r
+ bool isHeadless = awt.GraphicsEnvironment.isHeadless();\r
+ if (!isHeadless) {\r
+ try {\r
+ awt.Toolkit.getDefaultToolkit();\r
+ }\r
+ catch{\r
+ isHeadless = true;\r
+ }\r
+ }\r
+\r
+ _isHeadless = isHeadless ? 2 : 1;\r
+ }\r
+\r
+ return _isHeadless > 1;\r
+ }\r
+ }\r
\r
#endregion\r
\r
\r
#region Constr. and Destr.\r
private Graphics (Image image) {\r
- _nativeObject = (awt.Graphics2D)image.NativeObject.getGraphics();\r
+ _nativeObject = (awt.Graphics2D)image.NativeObject.CurrentImage.NativeImage.getGraphics();\r
_image = image;\r
_transform = new Matrix ();\r
- _nativeObject.setTransform( _transform.NativeObject );\r
\r
+ NativeObject.setStroke(new DummyStroke());\r
NativeObject.setRenderingHint(awt.RenderingHints.KEY_COLOR_RENDERING, awt.RenderingHints.VALUE_COLOR_RENDER_QUALITY);\r
+\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 Graphics() {\r
- bool isHeadless = awt.GraphicsEnvironment.isHeadless();\r
- if (!isHeadless) {\r
- try {\r
- awt.Toolkit.getDefaultToolkit();\r
- }\r
- catch{\r
- isHeadless = true;\r
- }\r
+ static internal float [] UnitConversion {\r
+ get {\r
+ return _unitConversion;\r
}\r
-\r
- IsHeadless = isHeadless;\r
}\r
-\r
+ \r
static internal int DefaultScreenResolution {\r
get {\r
return IsHeadless ? 96 :\r
}\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
- shape = ((awt.Stroke)pen).createStrokedShape(shape);\r
- FillShape(pen.Brush, shape);\r
- }\r
+ if (StrokeFactory.CanCreateAdvancedStroke && \r
+ (!pen.CanCreateBasicStroke || !NeedsNormalization)) {\r
+ geom.AffineTransform oldT = NativeObject.getTransform();\r
+ NativeObject.setTransform(Matrix.IdentityTransform.NativeObject);\r
\r
- void FillShape(awt.Paint paint, awt.Shape shape) {\r
- if (paint == null)\r
- throw new ArgumentNullException("brush");\r
+ try {\r
+ geom.AffineTransform t = GetFinalTransform();\r
+ if (!oldT.isIdentity()) {\r
+ t = (geom.AffineTransform)t.clone();\r
+ t.preConcatenate(oldT);\r
+ }\r
+ \r
+ double widthsquared = pen.GetSquaredTransformedWidth(t);\r
\r
- awt.Paint old = NativeObject.getPaint();\r
- NativeObject.setPaint(paint);\r
- try {\r
- NativeObject.fill(shape);\r
- }\r
- finally {\r
- NativeObject.setPaint(old);\r
- }\r
- }\r
+ bool antiAlias = (SmoothingMode == SmoothingMode.AntiAlias);\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
+ bool thin = (widthsquared <= (antiAlias ? \r
+ AdvancedStroke.MinPenSizeAASquared :\r
+ AdvancedStroke.MinPenSizeSquared));\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
+ PenFit penFit = thin ? (antiAlias ? PenFit.ThinAntiAlias : PenFit.Thin) : PenFit.NotThin;\r
+\r
+ if (NeedsNormalization) {\r
\r
- retVal.Height = layHeight;\r
- retVal.Width = layWidth+size/2.5f;\r
- if(!fDraw)\r
- return retVal;\r
+ bool normThin = \r
+ widthsquared <= AdvancedStroke.MinPenSizeSquaredNorm;\r
\r
- InternalSetBrush(brush);\r
+ if (normThin) {\r
+ shape = GetNormalizedShape(shape, t);\r
+ shape = pen.GetNativeObject(\r
+ t, null, penFit).createStrokedShape(shape);\r
+ }\r
+ else {\r
+ shape = pen.GetNativeObject(t, penFit).createStrokedShape(shape);\r
+ shape = GetNormalizedShape(shape, null);\r
+ }\r
+ }\r
+ else {\r
+ shape = pen.GetNativeObject(t, penFit).createStrokedShape(shape);\r
+ }\r
\r
- //end measurment\r
+ FillScaledShape(pen.Brush, shape);\r
+ }\r
+ finally {\r
+ NativeObject.setTransform(oldT);\r
+ }\r
+ }\r
+ else {\r
+ awt.Stroke oldStroke = NativeObject.getStroke();\r
+ NativeObject.setStroke(pen.GetNativeObject(null, PenFit.NotThin));\r
+ try {\r
\r
- //for draw we should probably update origins\r
+ NativeObject.setPaint(pen.Brush);\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
+ geom.AffineTransform oldT = NativeObject.getTransform();\r
+ NativeObject.transform(GetFinalTransform());\r
+ try {\r
+ NativeObject.draw(shape);\r
}\r
- else if(align == StringAlignment.Far) {\r
- drawPosY = (float)y + (float)hei - layHeight;\r
+ finally {\r
+ NativeObject.setTransform(oldT);\r
}\r
- //in both cases if string is not fit - switch to near\r
- if(drawPosY < y)\r
- drawPosY = y;\r
}\r
+ finally {\r
+ NativeObject.setStroke(oldStroke);\r
+ }\r
+ }\r
+ }\r
+ void FillShape(Brush paint, awt.Shape shape) {\r
+ if (paint == null)\r
+ throw new ArgumentNullException("brush");\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
- //g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);\r
- g.fill(sha);\r
- continue;\r
- }\r
- if((format.FormatFlags & StringFormatFlags.DirectionRightToLeft) != 0) {\r
- drawPosX = ((drawPosX + formatWidth) - advance) + (float)9;\r
- layout.draw(g, drawPosX, drawPosY);\r
- } \r
- } \r
- //Draw current line\r
- layout.draw(g, drawPosX, drawPosY); \r
+ geom.AffineTransform oldT = null;\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
}\r
- } //not nulls\r
+ shape = GetNormalizedShape(shape, t);\r
+ }\r
+ else {\r
+ geom.AffineTransform t = GetFinalTransform();\r
+ if (!t.isIdentity())\r
+ shape = t.createTransformedShape(shape);\r
+ }\r
+\r
+ if (oldT != null)\r
+ NativeObject.setTransform(Matrix.IdentityTransform.NativeObject);\r
\r
- return retVal;\r
+ try {\r
+ FillScaledShape(paint, shape);\r
+ }\r
+ finally {\r
+ if (oldT != null)\r
+ NativeObject.setTransform(oldT);\r
+ }\r
}\r
+\r
+ bool NeedsNormalization {\r
+ get {\r
+ return PixelOffsetMode != PixelOffsetMode.Half &&\r
+ PixelOffsetMode != PixelOffsetMode.HighQuality;\r
+ }\r
+ }\r
+\r
+ static awt.Shape GetNormalizedShape(awt.Shape shape, geom.AffineTransform t) {\r
+ geom.PathIterator iter = new NormalizingPathIterator(shape.getPathIterator(t));\r
+ \r
+ geom.GeneralPath path = new geom.GeneralPath(iter.getWindingRule());\r
+ path.append(iter, false);\r
+ return path;\r
+ }\r
+\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
+ NativeObject.setPaint(paint);\r
+ NativeObject.fill(shape);\r
+ }\r
+ finally {\r
+ if (m != null)\r
+ paint.BrushTransform = m;\r
+ }\r
+ }\r
+\r
#endregion\r
\r
#region Dispose\r
\r
#region Clear\r
public void Clear (Color color) {\r
- geom.AffineTransform old = NativeObject.getTransform();\r
- NativeObject.setTransform(new geom.AffineTransform());\r
- try {\r
- FillShape(color.NativeObject, new awt.Rectangle(0,0,_image.Width,_image.Height));\r
- }\r
- finally {\r
- NativeObject.setTransform(old);\r
- }\r
+ FillScaledShape(new SolidBrush( color ), _clip.NativeObject);\r
}\r
#endregion\r
\r
\r
#region DrawImage\r
\r
- public void DrawImage (Image image, Point point) \r
- {\r
- DrawImage(image, (int)point.X, (int)point.Y);\r
+ public void DrawImage (Image image, Point point) {\r
+ DrawImage(image, point.X, point.Y);\r
}\r
\r
- public void DrawImage (Image image, PointF point) \r
- {\r
- DrawImage(image, (int)point.X, (int)point.Y);\r
+ public void DrawImage (Image image, PointF point) {\r
+ DrawImage(image, point.X, point.Y);\r
}\r
\r
\r
DrawImage(image, m);\r
}\r
\r
- public void DrawImage (Image image, PointF [] destPoints) \r
- {\r
+ public void DrawImage (Image image, PointF [] destPoints) {\r
Matrix m = new Matrix(new RectangleF(0, 0, image.Width, image.Height), destPoints);\r
DrawImage(image, m);\r
}\r
\r
\r
- public void DrawImage (Image image, Rectangle rect) \r
- {\r
+ public void DrawImage (Image image, Rectangle rect) {\r
DrawImage(image, rect.X, rect.Y, rect.Width, rect.Height);\r
}\r
\r
- public void DrawImage (Image image, RectangleF rect) \r
- {\r
- DrawImage(image, (int)rect.X, (int)rect.Y, (int)rect.Width, (int)rect.Height);\r
+ public void DrawImage (Image image, RectangleF rect) {\r
+ DrawImage(image, rect.X, rect.Y, rect.Width, rect.Height);\r
}\r
\r
\r
- public void DrawImage (Image image, int x, int y) \r
- {\r
- float current_scale = PageScale;\r
- if (current_scale != 1)\r
- PageScale = 1;\r
-\r
- try\r
- {\r
- NativeObject.drawImage(image.NativeObject, x, y, null);\r
- }\r
- finally\r
- {\r
- if (current_scale != 1)\r
- PageScale = current_scale;\r
- }\r
+ public void DrawImage (Image image, int x, int y) {\r
+ DrawImage(image, (float)x, (float)y);\r
}\r
\r
- public void DrawImage (Image image, float x, float y) \r
- {\r
- DrawImage(image, (int)x, (int)y);\r
+ public void DrawImage (Image image, float x, float y) {\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
public void DrawImage (Image image, Rectangle destRect, Rectangle srcRect, GraphicsUnit srcUnit) {\r
- if (srcUnit != GraphicsUnit.Pixel)\r
- throw new NotImplementedException();\r
- // Like in .NET http://dotnet247.com/247reference/msgs/45/227979.aspx\r
-\r
- float current_scale = PageScale;\r
- if (current_scale != 1)\r
- PageScale = 1;\r
-\r
- try\r
- {\r
- NativeObject.drawImage(image.NativeObject,\r
- destRect.X,\r
- destRect.Y,\r
- destRect.X + destRect.Width,\r
- destRect.Y + destRect.Height,\r
- srcRect.X,\r
- srcRect.Y,\r
- srcRect.X + srcRect.Width,\r
- srcRect.Y + srcRect.Height,\r
- null);\r
- }\r
- finally\r
- {\r
- if (current_scale != 1)\r
- PageScale = current_scale;\r
- }\r
+ DrawImage(\r
+ image,\r
+ new Point [] {\r
+ new Point( destRect.X, destRect.Y),\r
+ new Point( destRect.X + destRect.Width, destRect.Y),\r
+ new Point( destRect.X, destRect.Y + destRect.Height)},\r
+ srcRect, \r
+ srcUnit);\r
}\r
- \r
+ \r
public void DrawImage (Image image, RectangleF destRect, RectangleF srcRect, GraphicsUnit srcUnit) {\r
DrawImage(\r
- image, \r
- new Rectangle((int)destRect.X, (int)destRect.Y, (int)destRect.Width, (int)destRect.Height),\r
- new Rectangle((int)srcRect.X, (int)srcRect.Y, (int)srcRect.Width, (int)srcRect.Height),\r
+ image,\r
+ new PointF [] {\r
+ new PointF( destRect.X, destRect.Y),\r
+ new PointF( destRect.X + destRect.Width, destRect.Y),\r
+ new PointF( destRect.X, destRect.Y + destRect.Height)},\r
+ srcRect, \r
srcUnit);\r
}\r
\r
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
throw new NotImplementedException();\r
- // Like in .NET http://dotnet247.com/247reference/msgs/45/227979.aspx\r
+ // Like in .NET http://dotnet247.com/247reference/msgs/45/227979.aspx\r
\r
Matrix mx = new Matrix(srcRect, destPoints);\r
\r
Region region = new Region(srcRect);\r
- region.Transform (mx);\r
- \r
- geom.Area current_clip = (geom.Area)GetNativeClip().clone();\r
- IntersectClip(region);\r
- try\r
- {\r
- DrawImage(image, mx);\r
- }\r
- finally\r
- {\r
- SetNativeClip(current_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
throw new NotImplementedException();\r
- // Like in .NET http://dotnet247.com/247reference/msgs/45/227979.aspx\r
+ // Like in .NET http://dotnet247.com/247reference/msgs/45/227979.aspx\r
\r
Matrix mx = new Matrix(srcRect, destPoints);\r
\r
Region region = new Region(srcRect);\r
- region.Transform (mx);\r
- \r
- geom.Area current_clip = (geom.Area)GetNativeClip().clone();\r
- IntersectClip(region);\r
- try\r
- {\r
- DrawImage(image, mx);\r
- }\r
- finally\r
- {\r
- SetNativeClip(current_clip);\r
- }\r
+ DrawImage(image, mx, region);\r
}\r
\r
\r
public void DrawImage (Image image, int x, int y, int width, int height) {\r
- float current_scale = PageScale;\r
- if (current_scale != 1)\r
- PageScale = 1;\r
-\r
- try\r
- {\r
- NativeObject.drawImage(image.NativeObject, x, y, width, height, null);\r
- }\r
- finally\r
- {\r
- if (current_scale != 1)\r
- PageScale = current_scale;\r
- }\r
+ DrawImage(image, (float)x, (float)y, (float)width, (float)height);\r
}\r
\r
public void DrawImage (Image image, float x, float y, float width, float height) {\r
- DrawImage(image, (int)x, (int)y, (int)width, (int)height);\r
+ Matrix mx = new Matrix();\r
+ mx.Translate((float)x, (float)y);\r
+ mx.Scale(width / (float)image.Width, height / (float)image.Height);\r
+\r
+ DrawImage( image, mx );\r
}\r
\r
\r
}\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
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
image, \r
destRect,\r
- new Rectangle((int)srcX, (int)srcY, (int)srcWidth, (int)srcHeight),\r
+ new RectangleF(srcX, srcY, srcWidth, srcHeight),\r
srcUnit);\r
}\r
\r
\r
internal void DrawImage (Image image, Matrix m) {\r
- float current_scale = PageScale;\r
- if (current_scale != 1)\r
- PageScale = 1;\r
+ DrawImage(image, m, null);\r
+ }\r
+\r
+ 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
+ }\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
- try\r
- {\r
- NativeObject.drawImage(image.NativeObject, m.NativeObject, null);\r
+ if (NeedsNormalization) {\r
+ Matrix normMatrix = ComputeClipNormalization(clip.GetBounds(this));\r
+ clip.Transform(normMatrix);\r
}\r
- finally\r
- {\r
- if (current_scale != 1)\r
- PageScale = current_scale;\r
+\r
+ awt.Shape oldClip = NativeObject.getClip();\r
+ IntersectScaledClipWithBase(clip);\r
+ \r
+ try {\r
+ Matrix mm = ComputeImageNormalization(image, m);\r
+ NativeObject.drawImage(image.NativeObject.CurrentImage.NativeImage, mm.NativeObject, null);\r
+ }\r
+ finally {\r
+ NativeObject.setClip( oldClip );\r
}\r
}\r
+\r
+ private static Matrix ComputeImageNormalization(Image img, Matrix m) {\r
+ if ( m.IsIdentity )\r
+ return m;\r
+\r
+ //m.Translate( -(m.Elements[0] + m.Elements[2]) / 2.0f, -(m.Elements[3] + m.Elements[1]) / 2.0f, MatrixOrder.Append);\r
+ m.Translate( \r
+ -(float)(m.NativeObject.getScaleX() + m.NativeObject.getShearX()) / 2.0f, \r
+ -(float)(m.NativeObject.getScaleY() + m.NativeObject.getShearY()) / 2.0f, MatrixOrder.Append);\r
+ \r
+ PointF [] p = new PointF[] { \r
+ new PointF( 0, 0 ),\r
+ new PointF( img.Width, 0 ),\r
+ new PointF( 0, img.Height )};\r
+\r
+ m.TransformPoints(p);\r
+ for (int i=0; i < p.Length; i++) {\r
+ p[i].X = (float)( p[i].X + 0.5f );\r
+ p[i].Y = (float)( p[i].Y + 0.5f );\r
+ }\r
+\r
+ return new Matrix( new Rectangle(0, 0, img.Width, img.Height), p );\r
+ }\r
+ private static Matrix ComputeClipNormalization(RectangleF rect) {\r
+ PointF [] p = new PointF[] { \r
+ new PointF( rect.X, rect.Y ),\r
+ new PointF( rect.X + rect.Width, rect.Y ),\r
+ new PointF( rect.X, rect.Y + rect.Height )};\r
+\r
+ for (int i=0; i < p.Length; i++) {\r
+ p[i].X = (float)Math.Round( p[i].X + 0.5f ) + 0.5f;\r
+ p[i].Y = (float)Math.Round( p[i].Y + 0.5f ) + 0.5f;\r
+ }\r
+\r
+ return new Matrix( rect, p );\r
+ }\r
\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
#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
\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
- #region Container [TODO]\r
+ #region Container\r
+\r
+ void PushGraphicsState(GraphicsState state) {\r
+ state.Next = _nextGraphicsState;\r
+ _nextGraphicsState = state;\r
+ }\r
+\r
+ GraphicsState PopGraphicsState() {\r
+ GraphicsState state = _nextGraphicsState;\r
+ _nextGraphicsState = _nextGraphicsState.Next;\r
+ return state;\r
+ }\r
+\r
+ bool ContainsGraphicsState(GraphicsState state) {\r
+ GraphicsState gs = _nextGraphicsState;\r
+\r
+ while(gs != null) {\r
+ if (gs == state)\r
+ return true;\r
+\r
+ gs = gs.Next;\r
+ }\r
+\r
+ return false;\r
+ }\r
+\r
public void EndContainer (GraphicsContainer container) {\r
- throw new NotImplementedException ();\r
+ Restore(container.StateObject);\r
}\r
\r
public GraphicsContainer BeginContainer () {\r
- throw new NotImplementedException ();\r
+ return new GraphicsContainer(Save(Matrix.IdentityTransform, true));\r
}\r
\r
public GraphicsContainer BeginContainer (Rectangle dstrect, Rectangle srcrect, GraphicsUnit unit) {\r
- throw new NotImplementedException ();\r
+ Matrix containerTransfrom =\r
+ new Matrix( srcrect,\r
+ new Point [] { new Point (dstrect.X, dstrect.Y), \r
+ new Point (dstrect.X + dstrect.Width, dstrect.Y), \r
+ new Point (dstrect.X, dstrect.Y + dstrect.Height) });\r
+\r
+ float scale = _unitConversion[ (int)PageUnit ] / _unitConversion[ (int)unit ];\r
+ containerTransfrom.Scale(scale, scale);\r
+\r
+ return new GraphicsContainer(Save(containerTransfrom, true));\r
}\r
\r
\r
public GraphicsContainer BeginContainer (RectangleF dstrect, RectangleF srcrect, GraphicsUnit unit) {\r
- throw new NotImplementedException ();\r
+ Matrix containerTransfrom =\r
+ new Matrix( srcrect,\r
+ new PointF [] { new PointF (dstrect.X, dstrect.Y), \r
+ new PointF (dstrect.X + dstrect.Width, dstrect.Y), \r
+ new PointF (dstrect.X, dstrect.Y + dstrect.Height) });\r
+\r
+ float scale = _unitConversion[ (int)PageUnit ] / _unitConversion[ (int)unit ];\r
+ containerTransfrom.Scale(scale, scale);\r
+\r
+ return new GraphicsContainer(Save(containerTransfrom, true));\r
+ }\r
+\r
+ GraphicsState Save(Matrix matrix, bool resetState) {\r
+ GraphicsState graphicsState = new GraphicsState(this, matrix, resetState);\r
+\r
+ PushGraphicsState( graphicsState );\r
+ return graphicsState;\r
+ }\r
+\r
+ public GraphicsState Save () {\r
+ return Save(Matrix.IdentityTransform, false);\r
+ }\r
+\r
+ public void Restore (GraphicsState graphicsState) {\r
+ if (ContainsGraphicsState(graphicsState)) {\r
+ GraphicsState gs = PopGraphicsState();\r
+ while ( gs != graphicsState )\r
+ gs = PopGraphicsState();\r
+\r
+ graphicsState.RestoreState(this);\r
+ }\r
}\r
\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
#endregion \r
\r
#region ExcludeClip\r
+ void ExcludeClip(geom.Area area) {\r
+\r
+ geom.AffineTransform t = GetFinalTransform();\r
+ if (!t.isIdentity()) {\r
+ area = (geom.Area)area.clone();\r
+ area.transform(t);\r
+ }\r
+\r
+ _clip.NativeObject.subtract(area);\r
+ RestoreBaseClip();\r
+ NativeObject.clip(_clip);\r
+ }\r
+\r
public void ExcludeClip (Rectangle rect) {\r
- geom.Area clip = GetNativeClip();\r
- clip.subtract(new geom.Area(rect.NativeObject));\r
- SetNativeClip(clip);\r
+ ExcludeClip(new geom.Area(rect.NativeObject));\r
}\r
\r
public void ExcludeClip (Region region) {\r
- geom.Area clip = GetNativeClip();\r
- clip.subtract(region.NativeObject);\r
- SetNativeClip(clip);\r
+ if (region == null)\r
+ throw new ArgumentNullException("region");\r
+ ExcludeClip(region.NativeObject);\r
}\r
#endregion \r
\r
\r
#region FillPath\r
public void FillPath (Brush brush, GraphicsPath path) {\r
+ if (path == null)\r
+ throw new ArgumentNullException("path");\r
+\r
FillShape(brush,path);\r
}\r
#endregion\r
\r
public void Flush (FlushIntention intention) {\r
if (_image != null)\r
- _image.NativeObject.flush();\r
+ _image.NativeObject.CurrentImage.NativeImage.flush();\r
}\r
\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
\r
#region IntersectClip\r
void IntersectClip (geom.Area area) {\r
- geom.Area clip = GetNativeClip();\r
- clip.intersect(area);\r
- SetNativeClip(clip);\r
+ \r
+ geom.AffineTransform t = GetFinalTransform();\r
+ if (!t.isIdentity()) {\r
+ area = (geom.Area)area.clone();\r
+ area.transform(t);\r
+ }\r
+\r
+ _clip.NativeObject.intersect(area);\r
+ RestoreBaseClip();\r
+ NativeObject.clip(_clip);\r
}\r
\r
public void IntersectClip (Region region) {\r
}\r
\r
public bool IsVisible (float x, float y) {\r
- java.awt.Graphics2D g = NativeObject;\r
- java.awt.Shape s = g.getClip();\r
- if (s == null)\r
+ double dx = x;\r
+ double dy = y;\r
+ geom.AffineTransform t = GetFinalTransform();\r
+ if (!t.isIdentity()) {\r
+ double[] p = new double[] {dx, dy};\r
+ t.transform(p, 0, p, 0, 1);\r
+\r
+ dx = p[0];\r
+ dy = p[1];\r
+ }\r
+ if (!_clip.NativeObject.contains(dx, dy))\r
+ return false;\r
+\r
+ awt.Shape clip = NativeObject.getClip();\r
+ if (clip == null)\r
return true;\r
- else \r
- return s.contains(x,y);\r
+\r
+ return clip.contains(dx, dy);\r
}\r
\r
public bool IsVisible (int x, int y) {\r
}\r
\r
public bool IsVisible (float x, float y, float width, float height) {\r
- java.awt.Graphics2D g = NativeObject;\r
- java.awt.Shape s = g.getClip();\r
- if (s == null)\r
- return true;\r
- else \r
- return s.contains(x,y,width,height);\r
+\r
+ geom.AffineTransform t = GetFinalTransform();\r
+ geom.Rectangle2D r = new geom.Rectangle2D.Float(x, y, width, height);\r
+ \r
+ if (!t.isIdentity())\r
+ r = t.createTransformedShape(r).getBounds2D();\r
+ \r
+ return NativeObject.hitClip(\r
+ (int)(r.getX()+0.5), (int)(r.getY()+0.5),\r
+ (int)(r.getWidth()+0.5), (int)(r.getHeight()+0.5))\r
+ && _clip.NativeObject.intersects(r);\r
}\r
\r
\r
}\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
\r
#region Reset (Clip and Transform)\r
public void ResetClip () {\r
- java.awt.Graphics2D g = NativeObject;\r
- g.setClip(null);\r
-\r
+ _clip.MakeInfinite();\r
+ RestoreBaseClip();\r
+ NativeObject.clip(_clip);\r
}\r
\r
public void ResetTransform () {\r
- _transform = new Matrix(1,0,0,1,0,0);\r
- UpdateInternalTransform();\r
+ _transform.Reset();\r
}\r
#endregion\r
\r
- public GraphicsState Save () {\r
- throw new NotImplementedException();\r
- }\r
-\r
- public void Restore (GraphicsState gstate) {\r
- throw new NotImplementedException();\r
- }\r
-\r
#region RotateTransform\r
public void RotateTransform (float angle) {\r
RotateTransform (angle, MatrixOrder.Prepend);\r
if(g == null)\r
throw new NullReferenceException();\r
\r
- SetNativeClip(\r
- CombineClipArea(g.GetNativeClip(),\r
- combineMode));\r
+ CombineClipArea(g._clip.NativeObject, combineMode);\r
}\r
\r
public void SetClip (Rectangle rect, CombineMode combineMode) {\r
if(region == null)\r
throw new ArgumentNullException("region");\r
\r
- if(region == Region.InfiniteRegion) {\r
- SetNativeClip(null);\r
- return;\r
- }\r
-\r
- SetNativeClip(CombineClipArea(region.NativeObject,combineMode));\r
+ CombineClipArea((geom.Area)region.NativeObject.clone(),combineMode);\r
}\r
\r
public void SetClip (GraphicsPath path, CombineMode combineMode) {\r
if(path == null)\r
throw new ArgumentNullException("path");\r
\r
- SetNativeClip(CombineClipArea(new java.awt.geom.Area(path.NativeObject),combineMode));\r
+ CombineClipArea(new geom.Area(path.NativeObject), combineMode);\r
}\r
#endregion\r
\r
#region Clipping Staff [INTERNAL]\r
+ internal Region ScaledClip {\r
+ get {\r
+ return _clip.Clone();\r
+ }\r
+ set {\r
+ _clip.NativeObject.reset();\r
+ _clip.NativeObject.add(value.NativeObject);\r
+ }\r
+ }\r
internal void SetClip(float x,float y,float width,float height,CombineMode combineMode) { \r
- SetNativeClip(CombineClipArea(new geom.Area(\r
- new geom.Rectangle2D.Float(x,y,width,height)),combineMode));\r
- }\r
-\r
- geom.Area CombineClipArea(java.awt.geom.Area area, CombineMode combineMode) {\r
- if (combineMode == CombineMode.Replace)\r
- return area;\r
-\r
- geom.Area curClip = GetNativeClip();\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
+ CombineClipArea(new geom.Area(\r
+ new geom.Rectangle2D.Float(x,y,width,height)),combineMode);\r
+ }\r
+\r
+ void CombineClipArea(geom.Area area, CombineMode combineMode) {\r
+ geom.AffineTransform t = GetFinalTransform();\r
+ if (!t.isIdentity())\r
+ area.transform(t);\r
+ if (combineMode == CombineMode.Replace) {\r
+ _clip.NativeObject.reset();\r
+ _clip.NativeObject.add(area);\r
}\r
- \r
- return curClip;\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
- void SetNativeClip(awt.Shape s) {\r
- NativeObject.setClip(s);\r
+\r
+ internal void IntersectScaledClipWithBase(awt.Shape clip) {\r
+ NativeObject.clip(clip);\r
}\r
\r
- geom.Area GetNativeClip() {\r
- awt.Shape clip = NativeObject.getClip();\r
- return clip != null ? new geom.Area(clip) : (geom.Area)Region.InfiniteRegion.NativeObject.clone();\r
+ void RestoreBaseClip() {\r
+ if (_nextGraphicsState == null) {\r
+ NativeObject.setClip(_windowRect);\r
+ return;\r
+ }\r
+\r
+ _nextGraphicsState.RestoreBaseClip(this);\r
}\r
+ \r
#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
}\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
\r
\r
public void TranslateClip (float dx, float dy) {\r
- geom.Area clip = GetNativeClip();\r
- clip.transform(geom.AffineTransform.getTranslateInstance(dx, dy));\r
- SetNativeClip(clip);\r
+ double x = dx;\r
+ double y = dy;\r
+ geom.AffineTransform f = GetFinalTransform();\r
+\r
+ if (!f.isIdentity()) {\r
+ double[] p = new double[] {x, y};\r
+ f.deltaTransform(p, 0, p, 0, 1);\r
+\r
+ x = p[0];\r
+ y = p[1];\r
+ }\r
+\r
+ // It seems .Net does exactly this...\r
+ x = Math.Floor(x+0.96875);\r
+ y = Math.Floor(y+0.96875);\r
+\r
+ 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
#region Properties [Partial TODO]\r
public Region Clip {\r
get {\r
- java.awt.Graphics2D g = NativeObject;\r
- java.awt.Shape s = g.getClip(); \r
- if(s != null) {\r
- return new Region(new java.awt.geom.Area(s));\r
- }\r
- else {\r
- return Region.InfiniteRegion.Clone();\r
- }\r
+ Region r = _clip.Clone();\r
+ geom.AffineTransform t = GetFinalTransform();\r
+ if (!t.isIdentity())\r
+ r.NativeObject.transform(t.createInverse());\r
+\r
+ return r;\r
}\r
set {\r
SetClip (value, CombineMode.Replace);\r
\r
public RectangleF ClipBounds {\r
get {\r
- java.awt.Graphics2D g = NativeObject;\r
- java.awt.Rectangle r = g.getClipBounds();\r
- RectangleF rect = new RectangleF ((float)r.getX(),(float)r.getY(),(float)r.getWidth(),(float)r.getHeight());\r
- return rect;\r
+ awt.Shape shape = _clip.NativeObject;\r
+ if (shape == null)\r
+ shape = Region.InfiniteRegion.NativeObject;\r
+\r
+ geom.RectangularShape r = shape.getBounds2D();\r
+ geom.AffineTransform t = GetFinalTransform();\r
+ if (!t.isIdentity()) {\r
+ geom.AffineTransform it = t.createInverse();\r
+ r = it.createTransformedShape(r).getBounds2D();\r
+ }\r
+\r
+ return new RectangleF (r);\r
}\r
}\r
\r
\r
public bool IsClipEmpty {\r
get {\r
- java.awt.Graphics2D g = NativeObject;\r
- awt.Shape clip = g.getClip();\r
- if (clip == null)\r
- return false;\r
- return new geom.Area(clip).isEmpty();\r
+ return _clip.IsEmpty(this);\r
}\r
}\r
\r
public bool IsVisibleClipEmpty {\r
get {\r
- awt.Shape clip = NativeObject.getClip();\r
- if (clip == null)\r
- return false;\r
- return !clip.intersects(0, 0, _image.Width, _image.Height);\r
+ if (_clip.IsEmpty(this))\r
+ return true;\r
+\r
+ return VisibleClipBounds.IsEmpty;\r
}\r
}\r
\r
}\r
set {\r
_pageScale = value;\r
- UpdateInternalTransform();\r
}\r
}\r
\r
}\r
set {\r
_pageUnit = value;\r
- UpdateInternalTransform();\r
}\r
}\r
\r
- internal void UpdateInternalTransform()\r
- {\r
- float new_scale = _pageScale * _unitConversion[ (int)PageUnit ];\r
- Matrix mx = _transform.Clone();\r
+ static internal geom.AffineTransform GetFinalTransform(\r
+ geom.AffineTransform transform, GraphicsUnit pageUnit, float pageScale) {\r
+ geom.AffineTransform t = null;\r
+ if (pageUnit != GraphicsUnit.Display) {\r
+ float scale = pageScale * _unitConversion[ (int)pageUnit ];\r
+ if (Math.Abs(scale-1f) > float.Epsilon)\r
+ t = geom.AffineTransform.getScaleInstance(scale, scale);\r
+ }\r
\r
- mx.Scale( new_scale, new_scale, MatrixOrder.Prepend );\r
- mx.Translate(\r
- mx.OffsetX * new_scale - mx.OffsetX,\r
- mx.OffsetY * new_scale - mx.OffsetY, MatrixOrder.Append);\r
+ if (t != null)\r
+ t.concatenate(transform);\r
+ else\r
+ t = transform;\r
+ \r
+ return t;\r
+ }\r
\r
- java.awt.Graphics2D g = NativeObject;\r
- g.setTransform( mx.NativeObject );\r
+ geom.AffineTransform GetFinalTransform() {\r
+ return GetFinalTransform(_transform.NativeObject, PageUnit, PageScale);\r
}\r
\r
public PixelOffsetMode PixelOffsetMode {\r
}\r
}\r
\r
+ [MonoTODO]\r
public Point RenderingOrigin {\r
get {\r
throw new NotImplementedException();\r
\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
public Matrix Transform {\r
get {\r
- return _transform;\r
+ return _transform.Clone();\r
}\r
set {\r
- _transform = value.Clone();\r
- UpdateInternalTransform();\r
+ if (value == null)\r
+ throw new ArgumentNullException("matrix");\r
+\r
+ if (!value.IsInvertible)\r
+ throw new ArgumentException("Invalid parameter used.");\r
+\r
+ value.CopyTo(_transform);\r
+ }\r
+ }\r
+\r
+ internal Matrix BaseTransform {\r
+ get {\r
+ return new Matrix(NativeObject.getTransform());\r
+ }\r
+ set {\r
+ NativeObject.setTransform(value.NativeObject);\r
+ }\r
+ }\r
+\r
+ internal void PrependBaseTransform(geom.AffineTransform t) {\r
+ NativeObject.transform(t);\r
+ }\r
+\r
+ internal awt.Shape VisibleShape {\r
+ get {\r
+ return _windowRect;\r
}\r
}\r
\r
public RectangleF VisibleClipBounds {\r
get {\r
- RectangleF bounds = ClipBounds;\r
- bounds.Intersect(new RectangleF(0, 0, _image.Width, _image.Height));\r
- return bounds;\r
+ if (_clip.IsEmpty(this))\r
+ return RectangleF.Empty;\r
+\r
+ geom.Rectangle2D r = _clip.NativeObject.getBounds2D();\r
+ 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
+ r = it.createTransformedShape(r).getBounds2D();\r
+ }\r
+\r
+ return new RectangleF (r);\r
}\r
}\r
\r
void ConcatenateTransform(geom.AffineTransform transform, MatrixOrder order) {\r
geom.AffineTransform at = _transform.NativeObject;\r
Matrix.Multiply(at, transform, order);\r
-\r
- UpdateInternalTransform();\r
}\r
#endregion\r
}\r