2 // System.Drawing.Drawing2D.GraphicsPath.cs
5 // Konstantin Triger <kostat@mainsoft.com>
6 // Bors Kirzner <boris@mainsoft.com>
8 // Copyright (C) 2005 Mainsoft Corporation, (http://www.mainsoft.com)
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 using System.Drawing;
\r
31 using System.Drawing.Text;
\r
32 using System.Collections;
\r
33 using java.awt.geom;
\r
36 namespace System.Drawing.Drawing2D
\r
38 public sealed class GraphicsPath : BasicShape, ICloneable
\r
41 SEG_MOVETO = ExtendedGeneralPath.SEG_MOVETO,
\r
42 SEG_LINETO = ExtendedGeneralPath.SEG_LINETO,
\r
43 SEG_QUADTO = ExtendedGeneralPath.SEG_QUADTO,
\r
44 SEG_CUBICTO = ExtendedGeneralPath.SEG_CUBICTO,
\r
45 SEG_CLOSE = ExtendedGeneralPath.SEG_CLOSE
\r
50 internal ExtendedGeneralPath NativeObject
\r
54 return (ExtendedGeneralPath)Shape;
\r
58 GraphicsPath (ExtendedGeneralPath ptr) : base(ptr)
\r
64 public GraphicsPath ():
\r
65 this(FillMode.Alternate)
\r
69 public GraphicsPath (FillMode fillMode) : this(new ExtendedGeneralPath ())
\r
71 FillMode = fillMode;
\r
74 public GraphicsPath (Point[] pts, byte[] types) : this(pts, types, FillMode.Alternate)
\r
78 public GraphicsPath (PointF [] pts, byte [] types) : this(pts, types, FillMode.Alternate)
\r
82 public GraphicsPath (Point [] pts, byte [] types, FillMode fillMode) : this(new ExtendedGeneralPath ())
\r
84 FillMode = fillMode;
\r
85 SetPath (pts, types);
\r
88 public GraphicsPath (PointF [] pts, byte [] types, FillMode fillMode) : this(new ExtendedGeneralPath ())
\r
90 FillMode = fillMode;
\r
91 SetPath (pts, types);
\r
97 public object Clone ()
\r
99 return new GraphicsPath ((ExtendedGeneralPath) NativeObject.Clone ());
\r
104 public FillMode FillMode
\r
107 { if(NativeObject.getWindingRule() == GeneralPath.WIND_EVEN_ODD)
\r
108 return FillMode.Alternate;
\r
110 return FillMode.Winding;
\r
115 if (value == FillMode.Alternate)
\r
116 NativeObject.setWindingRule (GeneralPath.WIND_EVEN_ODD);
\r
118 NativeObject.setWindingRule (GeneralPath.WIND_NON_ZERO);
\r
122 public PathData PathData
\r
124 get { return NativeObject.PathData; }
\r
127 public PointF [] PathPoints
\r
131 return PathData.Points;
\r
135 public byte [] PathTypes
\r
139 return PathData.Types;
\r
145 public int PointCount
\r
149 return NativeObject.PointCount;
\r
155 public void AddArc (Rectangle rect, float startAngle, float sweepAngle)
\r
157 AddArc(rect.X,rect.Y,rect.Width,rect.Height,startAngle,sweepAngle);
\r
160 public void AddArc (RectangleF rect, float startAngle, float sweepAngle)
\r
162 AddArc(rect.X,rect.Y,rect.Width,rect.Height,startAngle,sweepAngle);
\r
165 public void AddArc (int x, int y, int width, int height, float startAngle, float sweepAngle)
\r
167 AddArc((float)x,(float)y,(float)width,(float)height,startAngle,sweepAngle);
\r
170 public void AddArc (float x, float y, float width, float height, float startAngle, float sweepAngle)
\r
172 Shape shape = null;
\r
174 if (sweepAngle >= 360)
\r
175 shape = new Ellipse2D.Float(x, y, width, height);
\r
178 double d1Tod2 = width/height;
\r
179 double sqrd1Tod2 = d1Tod2*d1Tod2;
\r
180 double start = ConvertArcAngle(sqrd1Tod2, startAngle);
\r
181 double extent = ConvertArcAngle(sqrd1Tod2, startAngle+sweepAngle) - start;
\r
183 shape = new Arc2D.Double(x,y,width,height,-start,-extent,Arc2D.OPEN);
\r
186 NativeObject.append(shape);
\r
190 /// .Net computes an angle by intersection of ellipse with a ray
\r
191 /// java does the following: x1 = d1*cos(a), y1 = d2*sin(a)
\r
192 /// where: d1 = width/2, d2 = height/2
\r
193 /// we need to find angle x, which satisfies:
\r
194 /// x1 = m*cos(a) = d1*cos(x)
\r
195 /// y1 = m*sin(a) = d2*sin(x)
\r
196 /// (x1*x1)/(d1*d1) + (x2*x2)/(d2*d2) = 1
\r
198 /// <param name="sqrd1Tod2">(d1/d2)*(d1/d2)</param>
\r
199 /// <param name="angle">angle in degrees</param>
\r
200 /// <returns>converted angle in degrees</returns>
\r
201 static double ConvertArcAngle(double sqrd1Tod2, double angle) {
\r
202 double angleRad = java.lang.Math.toRadians(angle);
\r
203 double tan = Math.Tan(angleRad);
\r
204 double cosx = 1/Math.Sqrt( sqrd1Tod2 * (tan*tan) + 1);
\r
205 double xRad = Math.Acos(cosx);
\r
206 double x = java.lang.Math.toDegrees(xRad);
\r
207 int q = (Math.Abs((int)angle))/90;
\r
224 x += (((int)angle)/360)*360;
\r
231 #region AddBezier(s)
\r
232 public void AddBezier (Point pt1, Point pt2, Point pt3, Point pt4)
\r
234 AddBezier(pt1.X,pt1.Y,pt2.X,pt2.Y,pt3.X,pt3.Y,pt4.X,pt4.Y);
\r
237 public void AddBezier (PointF pt1, PointF pt2, PointF pt3, PointF pt4)
\r
239 AddBezier(pt1.X,pt1.Y,pt2.X,pt2.Y,pt3.X,pt3.Y,pt4.X,pt4.Y);
\r
242 public void AddBezier (int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4)
\r
244 AddBezier((float)x1,(float)y1,(float)x2,(float)y2,(float)x3,(float)y3,(float)x4,(float)y4);
\r
247 public void AddBezier (float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4)
\r
249 CubicCurve2D cc = new CubicCurve2D.Float(x1,y1,x2,y2,x3,y3,x4,y4);
\r
250 NativeObject.append(cc);
\r
253 public void AddBeziers (Point [] pts)
\r
256 throw new ArgumentNullException("points");
\r
258 AddBezier(pts [0].X,pts [0].Y,
\r
259 pts [1].X,pts [1].Y,
\r
260 pts [2].X,pts [2].Y,
\r
261 pts [3].X,pts [3].Y);
\r
263 for (int i = 4; i < pts.Length; i += 3) {
\r
264 NativeObject.curveTo(
\r
265 pts [i].X,pts [i].Y,
\r
266 pts [i+1].X,pts [i+1].Y,
\r
267 pts [i+2].X,pts [i+2].Y);
\r
271 public void AddBeziers (PointF [] pts)
\r
274 throw new ArgumentNullException("points");
\r
276 AddBezier(pts [0].X,pts [0].Y,
\r
277 pts [1].X,pts [1].Y,
\r
278 pts [2].X,pts [2].Y,
\r
279 pts [3].X,pts [3].Y);
\r
281 for (int i = 4; i < pts.Length; i += 3) {
\r
282 NativeObject.curveTo(
\r
283 pts [i].X,pts [i].Y,
\r
284 pts [i+1].X,pts [i+1].Y,
\r
285 pts [i+2].X,pts [i+2].Y);
\r
291 public void AddEllipse (float x, float y, float width, float height)
\r
293 Ellipse2D e = new Ellipse2D.Float(x,y,width,height);
\r
294 NativeObject.append(e,false);
\r
297 public void AddEllipse (RectangleF r)
\r
299 AddEllipse(r.X,r.Y,r.Width,r.Height);
\r
302 public void AddEllipse (Rectangle r)
\r
304 AddEllipse(r.X,r.Y,r.Width,r.Height);
\r
307 public void AddEllipse (int x, int y, int width, int height)
\r
309 AddEllipse((float)x, (float)y, (float)width, (float)height);
\r
314 public void AddLine (float x1, float y1, float x2, float y2)
\r
316 Line2D l = new Line2D.Float(x1,y1,x2,y2);
\r
317 NativeObject.append(l);
\r
320 public void AddLine (Point a, Point b)
\r
322 AddLine(a.X,a.Y,b.X,b.Y);
\r
325 public void AddLine (PointF a, PointF b)
\r
327 AddLine(a.X,a.Y,b.X,b.Y);
\r
330 public void AddLine (int x1, int y1, int x2, int y2)
\r
332 AddLine((float)x1,(float)y1,(float)x2,(float)y2);
\r
335 public void AddLines (Point [] points)
\r
337 if (points == null)
\r
338 throw new ArgumentNullException("points");
\r
340 if (points.Length == 0)
\r
343 if (NativeObject.LastFigureClosed)
\r
344 NativeObject.moveTo(points[0].X, points[0].Y);
\r
346 NativeObject.lineTo(points[0].X, points[0].Y);
\r
348 for (int i = 1; i < points.Length; i ++)
\r
349 NativeObject.lineTo(points[i].X, points[i].Y);
\r
352 public void AddLines (PointF [] points)
\r
354 if (points == null)
\r
355 throw new ArgumentNullException("points");
\r
357 if (points.Length == 0)
\r
360 if (NativeObject.LastFigureClosed)
\r
361 NativeObject.moveTo(points[0].X, points[0].Y);
\r
363 NativeObject.lineTo(points[0].X, points[0].Y);
\r
365 for (int i = 1; i < points.Length; i ++)
\r
366 NativeObject.lineTo(points[i].X, points[i].Y);
\r
371 public void AddPie (float x, float y, float width, float height, float startAngle, float sweepAngle)
\r
373 Shape shape = null;
\r
375 if (sweepAngle >= 360)
\r
376 shape = new Ellipse2D.Float(x, y, width, height);
\r
379 double d1Tod2 = width/height;
\r
380 double sqrd1Tod2 = d1Tod2*d1Tod2;
\r
381 double start = ConvertArcAngle(sqrd1Tod2, startAngle);
\r
382 double extent = ConvertArcAngle(sqrd1Tod2, startAngle+sweepAngle) - start;
\r
384 shape = new Arc2D.Double(x,y,width,height,-start,-extent,Arc2D.PIE);
\r
387 NativeObject.append(shape,false);
\r
390 public void AddPie (Rectangle rect, float startAngle, float sweepAngle)
\r
392 AddPie((float)rect.X, (float)rect.Y,(float)rect.Width,(float)rect.Height,startAngle,sweepAngle);
\r
395 public void AddPie (int x, int y, int width, int height, float startAngle, float sweepAngle)
\r
397 AddPie((float)x,(float)y,(float)width,(float)height,startAngle,sweepAngle);
\r
402 public void AddPolygon (Point [] points)
\r
404 if (points == null)
\r
405 throw new ArgumentNullException("points");
\r
407 if (points.Length < 3)
\r
408 throw new ArgumentException("Invalid parameter used.");
\r
410 NativeObject.moveTo((float)points[0].X,(float)points[0].Y);
\r
411 for (int i = 1; i< points.Length; i++)
\r
413 NativeObject.lineTo((float)points[i].X,(float)points[i].Y);
\r
415 NativeObject.closePath();
\r
418 public void AddPolygon (PointF [] points)
\r
420 if (points == null)
\r
421 throw new ArgumentNullException("points");
\r
423 if (points.Length < 3)
\r
424 throw new ArgumentException("Invalid parameter used.");
\r
426 NativeObject.moveTo(points[0].X,points[0].Y);
\r
427 for (int i = 1; i < points.Length; i++)
\r
429 NativeObject.lineTo(points[i].X,points[i].Y);
\r
431 NativeObject.closePath();
\r
435 #region AddRectangle(s)
\r
436 internal void AddRectangle(float x,float y, float w, float h)
\r
438 NativeObject.moveTo(x, y);
\r
439 NativeObject.lineTo (x + w, y);
\r
440 NativeObject.lineTo (x + w, y + h);
\r
441 NativeObject.lineTo (x, y + h);
\r
442 NativeObject.closePath ();
\r
444 public void AddRectangle (RectangleF rect)
\r
446 AddRectangle(rect.X,rect.Y,rect.Width,rect.Height);
\r
449 public void AddRectangle (Rectangle rect)
\r
451 AddRectangle(rect.X,rect.Y,rect.Width,rect.Height);
\r
454 public void AddRectangles (Rectangle [] rects)
\r
456 foreach(Rectangle rect in rects)
\r
457 AddRectangle(rect.X,rect.Y,rect.Width,rect.Height);
\r
460 public void AddRectangles (RectangleF [] rects)
\r
462 foreach(RectangleF rect in rects)
\r
463 AddRectangle(rect.X,rect.Y,rect.Width,rect.Height);
\r
468 public void AddPath (GraphicsPath addingPath, bool connect)
\r
470 if (NativeObject.LastFigureClosed || addingPath.NativeObject.LastFigureClosed)
\r
473 NativeObject.append(addingPath.NativeObject,connect);
\r
477 #region GetLastPoint
\r
478 public PointF GetLastPoint ()
\r
480 return NativeObject.GetLastPoint ();
\r
485 public void Reset ()
\r
487 NativeObject.reset();
\r
492 public RectangleF GetBounds ()
\r
494 return GetBounds (null, null);
\r
497 public RectangleF GetBounds (Matrix matrix)
\r
499 return GetBounds (matrix, null);
\r
502 public RectangleF GetBounds (Matrix matrix, Pen pen)
\r
504 // FIXME : we do not know exacly how the bounding rectangle
\r
505 // is calculated so this implementation obtains different bounds
\r
506 // that still contains the path widened by oen and transformed by matrix
\r
507 // the order of operations is similar to widening, as .Net does.
\r
509 // first get original shape bounds
\r
510 //Shape shape = NativeObject.getBounds2D();
\r
511 Shape shape = NativeObject;
\r
515 shape = ((Stroke)pen).createStrokedShape (shape);
\r
517 Rectangle2D rect = shape.getBounds2D ();
\r
519 // transform bounds
\r
520 if (matrix != null)
\r
521 rect = matrix.NativeObject.createTransformedShape(rect).getBounds2D();
\r
523 return new RectangleF (rect);
\r
528 public void Transform (Matrix matrix)
\r
533 NativeObject.transform(matrix.NativeObject);
\r
538 public bool IsVisible (Point point)
\r
540 return IsVisible (point.X, point.Y, null);
\r
543 public bool IsVisible (PointF point)
\r
545 return IsVisible (point.X, point.Y, null);
\r
548 public bool IsVisible (int x, int y)
\r
550 return IsVisible (x, y, null);
\r
553 public bool IsVisible (float x, float y)
\r
555 return IsVisible (x, y, null);
\r
558 public bool IsVisible (Point pt, Graphics graphics)
\r
560 return IsVisible (pt.X, pt.Y, graphics);
\r
563 public bool IsVisible (PointF pt, Graphics graphics)
\r
565 return IsVisible (pt.X, pt.Y, graphics);
\r
568 public bool IsVisible (int x, int y, Graphics graphics)
\r
570 return IsVisible((float)x,(float)y,null);
\r
573 public bool IsVisible (float x, float y, Graphics graphics)
\r
575 // LAMESPEC : .Net is currently ignorig Graphics object
\r
576 //if (graphics != null && !graphics.IsVisible(x,y))
\r
579 return NativeObject.contains(x,y);
\r
584 public void Reverse ()
\r
586 NativeObject.Reverse ();
\r
590 #region AddClosedCurve
\r
591 public void AddClosedCurve (Point [] points)
\r
593 AddClosedCurve(points, 0.5f);
\r
596 public void AddClosedCurve (PointF [] points)
\r
598 AddClosedCurve(points, 0.5f);
\r
601 public void AddClosedCurve (Point [] points, float tension)
\r
603 if (points == null)
\r
604 throw new ArgumentNullException("points");
\r
606 if (points.Length < 3)
\r
607 throw new ArgumentException("Invalid parameter used.");
\r
609 int length = (points.Length + 3)*2;
\r
611 float[] pts = new float[length];
\r
612 pts[--length] = points[1].Y;
\r
613 pts[--length] = points[1].X;
\r
614 pts[--length] = points[0].Y;
\r
615 pts[--length] = points[0].X;
\r
617 for (int i = points.Length-1; i >= 0; i--) {
\r
618 pts[--length] = points[i].Y;
\r
619 pts[--length] = points[i].X;
\r
622 pts[--length] = points[points.Length-1].Y;
\r
623 pts[--length] = points[points.Length-1].X;
\r
625 AddCurve(pts, !NativeObject.LastFigureClosed, tension);
\r
629 public void AddClosedCurve (PointF [] points, float tension)
\r
631 if (points == null)
\r
632 throw new ArgumentNullException("points");
\r
634 if (points.Length < 3)
\r
635 throw new ArgumentException("Invalid parameter used.");
\r
637 int length = (points.Length + 3)*2;
\r
639 float[] pts = new float[length];
\r
640 pts[--length] = points[1].Y;
\r
641 pts[--length] = points[1].X;
\r
642 pts[--length] = points[0].Y;
\r
643 pts[--length] = points[0].X;
\r
645 for (int i = points.Length-1; i >= 0; i--) {
\r
646 pts[--length] = points[i].Y;
\r
647 pts[--length] = points[i].X;
\r
650 pts[--length] = points[points.Length-1].Y;
\r
651 pts[--length] = points[points.Length-1].X;
\r
653 AddCurve(pts, !NativeObject.LastFigureClosed, tension);
\r
659 //we have now two approaches for drawing cardinal curves
\r
660 //the first one is to convert cardinals into approximate beziers
\r
661 //the second one - to draw curve ourself with all interpolation staff
\r
662 //here. I preffer the first one because we could utilize java antialiasing and
\r
663 //flattening features, otherwise curves will be more strict but less cool
\r
664 public void AddCurve (Point [] points)
\r
666 AddCurve(points,0.5F);
\r
669 public void AddCurve (PointF [] points)
\r
671 AddCurve(points,0.5f);
\r
674 public void AddCurve (Point [] points, float tension)
\r
676 AddCurve(points, 0, points.Length-1, tension);
\r
679 public void AddCurve (PointF [] points, float tension)
\r
681 AddCurve(points, 0, points.Length-1, tension);
\r
684 public void AddCurve (Point [] points, int offset, int numberOfSegments, float tension)
\r
686 int nPoints = numberOfSegments + 1;
\r
687 int length = nPoints*2 + 4;
\r
688 float[] pts = new float[length];
\r
690 int lastP = offset + nPoints;
\r
691 if (lastP == points.Length) {
\r
693 pts[--length] = points[lastP].Y;
\r
694 pts[--length] = points[lastP].X;
\r
697 for (; length > 0 && lastP >= 0; lastP--) {
\r
698 pts[--length] = points[lastP].Y;
\r
699 pts[--length] = points[lastP].X;
\r
703 pts[1] = points[0].Y;
\r
704 pts[0] = points[0].X;
\r
707 AddCurve(pts, !NativeObject.LastFigureClosed, tension);
\r
710 public void AddCurve (PointF [] points, int offset, int numberOfSegments, float tension)
\r
712 int nPoints = numberOfSegments + 1;
\r
713 int length = nPoints*2 + 4;
\r
714 float[] pts = new float[length];
\r
716 int lastP = offset + nPoints;
\r
717 if (lastP == points.Length) {
\r
719 pts[--length] = points[lastP].Y;
\r
720 pts[--length] = points[lastP].X;
\r
723 for (; length > 0 && lastP >= 0; lastP--) {
\r
724 pts[--length] = points[lastP].Y;
\r
725 pts[--length] = points[lastP].X;
\r
729 pts[1] = points[0].Y;
\r
730 pts[0] = points[0].X;
\r
733 AddCurve(pts, !NativeObject.LastFigureClosed, tension);
\r
737 /// Based on http://pubpages.unh.edu/~cs770/a5/cardinal.html
\r
739 /// <param name="pts">point array (x1,y1,x2,y2 ...).
\r
740 /// The first and last points considered only for calculations, but are not added.</param>
\r
741 void AddCurve(float[] pts, bool connect, float tension) {
\r
742 tension /= 3f; //looks like a good pick
\r
745 NativeObject.lineTo(pts[2],pts[3]);
\r
747 NativeObject.moveTo(pts[2],pts[3]);
\r
749 float dx = pts[4] - pts[0];
\r
750 float dy = pts[5] - pts[1];
\r
752 float sx = pts[2] + tension*dx;
\r
753 float sy = pts[3] + tension*dy;
\r
755 for (int offset = 2, total = pts.Length-4; offset < total; offset += 2) {
\r
756 int cur_offset = offset;
\r
757 int pX = cur_offset++;
\r
758 int pY = cur_offset++;
\r
759 int X = cur_offset++;
\r
760 int Y = cur_offset++;
\r
761 int nX = cur_offset++;
\r
762 int nY = cur_offset++;
\r
764 dx = pts[nX] - pts[pX];
\r
765 dy = pts[nY] - pts[pY];
\r
767 float rx = pts[X] - tension*dx;
\r
768 float ry = pts[Y] - tension*dy;
\r
770 NativeObject.curveTo(sx, sy, rx, ry, pts[X], pts[Y]);
\r
772 sx = pts[X] + tension*dx;
\r
773 sy = pts[Y] + tension*dy;
\r
779 public void AddString (string s, FontFamily family, int style, float emSize, Point origin, StringFormat format)
\r
781 AddString(s, new Font(family, emSize, (FontStyle)style, GraphicsUnit.World), origin.X, origin.Y, float.PositiveInfinity, float.PositiveInfinity,
\r
785 public void AddString (string s, FontFamily family, int style, float emSize, PointF origin, StringFormat format)
\r
787 AddString(s, new Font(family, emSize, (FontStyle)style, GraphicsUnit.World), origin.X, origin.Y, float.PositiveInfinity, float.PositiveInfinity,
\r
791 public void AddString (string s, FontFamily family, int style, float emSize, Rectangle layoutRect, StringFormat format)
\r
793 AddString(s, new Font(family, emSize, (FontStyle)style, GraphicsUnit.World),
\r
794 layoutRect.X, layoutRect.Y, layoutRect.Width, layoutRect.Height,
\r
798 public void AddString (string s, FontFamily family, int style, float emSize, RectangleF layoutRect, StringFormat format)
\r
800 AddString(s, new Font(family, emSize, (FontStyle)style, GraphicsUnit.World),
\r
801 layoutRect.X, layoutRect.Y, layoutRect.Width, layoutRect.Height,
\r
805 void AddString (string s, Font font,
\r
806 float x, float y, float width, float height,
\r
807 StringFormat format) {
\r
809 TextLineIterator iter = new TextLineIterator(s, font,
\r
810 new java.awt.font.FontRenderContext(null, false, false),
\r
811 format, width, height);
\r
813 int coordsCount = NativeObject.CoordsCount;
\r
815 for (LineLayout layout = iter.NextLine(); layout != null; layout = iter.NextLine()) {
\r
816 NativeObject.append(layout.GetOutline(x, y), false);
\r
819 AffineTransform lineAlignT = iter.CalcLineAlignmentTransform();
\r
820 if (lineAlignT != null)
\r
821 NativeObject.transform(lineAlignT, coordsCount, NativeObject.CoordsCount - coordsCount);
\r
825 #region ClearMarkers
\r
826 public void ClearMarkers()
\r
828 NativeObject.ClearMarkers ();
\r
833 public void CloseAllFigures()
\r
835 ExtendedGeneralPath p = new ExtendedGeneralPath();
\r
836 PathIterator pi = NativeObject.getPathIterator(null);
\r
837 JPI lastSeg = JPI.SEG_CLOSE;
\r
838 float [] points = new float[6];
\r
840 p.setWindingRule(pi.getWindingRule());
\r
841 while(!pi.isDone())
\r
843 JPI curSeg = (JPI)pi.currentSegment(points);
\r
846 case JPI.SEG_CLOSE:
\r
849 case JPI.SEG_MOVETO:
\r
850 if(lastSeg != JPI.SEG_CLOSE)
\r
852 p.moveTo(points[0],points[1]);
\r
854 case JPI.SEG_LINETO:
\r
855 p.lineTo(points[0],points[1]);
\r
857 case JPI.SEG_QUADTO:
\r
858 p.quadTo(points[0],points[1],points[2],points[3]);
\r
860 case JPI.SEG_CUBICTO:
\r
861 p.curveTo(points[0],points[1],points[2],points[3],points[4],points[5]);
\r
874 public void CloseFigure() {
\r
875 if (!NativeObject.LastFigureClosed)
\r
876 NativeObject.closePath();
\r
881 public void Flatten ()
\r
883 // 1/4 is the FlatnessDefault as defined in GdiPlusEnums.h
\r
884 Flatten (null, 1.0f / 4.0f);
\r
887 public void Flatten (Matrix matrix)
\r
889 Flatten (matrix, 1.0f / 4.0f);
\r
892 public void Flatten (Matrix matrix, float flatness)
\r
894 AffineTransform tr = null;
\r
895 if(matrix != null)
\r
896 tr = matrix.NativeObject;
\r
898 //FIXME : Review (perfomance reasons).
\r
899 PathIterator pi = NativeObject.getPathIterator(tr,flatness);
\r
900 ExtendedGeneralPath newPath = new ExtendedGeneralPath();
\r
901 newPath.append(pi,false);
\r
906 #region GetOutlineVisible
\r
907 public bool IsOutlineVisible (Point point, Pen pen)
\r
909 return IsOutlineVisible (point.X, point.Y, pen, null);
\r
912 public bool IsOutlineVisible (PointF point, Pen pen)
\r
914 return IsOutlineVisible (point.X, point.Y, pen, null);
\r
917 public bool IsOutlineVisible (int x, int y, Pen pen)
\r
919 return IsOutlineVisible (x, y, pen, null);
\r
922 public bool IsOutlineVisible (float x, float y, Pen pen)
\r
924 return IsOutlineVisible (x, y, pen, null);
\r
927 public bool IsOutlineVisible (Point pt, Pen pen, Graphics graphics)
\r
929 return IsOutlineVisible (pt.X, pt.Y, pen, graphics);
\r
932 public bool IsOutlineVisible (PointF pt, Pen pen, Graphics graphics)
\r
934 return IsOutlineVisible (pt.X, pt.Y, pen, graphics);
\r
937 public bool IsOutlineVisible (int x, int y, Pen pen, Graphics graphics)
\r
939 // LAMESPEC : .Net is currently ignorig Graphics object
\r
940 //if (graphics != null) {
\r
941 // if (!graphics.IsVisible (x, y))
\r
945 return ((Stroke)pen).createStrokedShape (NativeObject).contains (x, y);
\r
948 public bool IsOutlineVisible (float x, float y, Pen pen, Graphics graphics)
\r
950 return ((Stroke)pen).createStrokedShape (NativeObject).contains (x, y);
\r
954 #region SetMarkers
\r
955 public void SetMarkers ()
\r
957 NativeObject.SetMarkers ();
\r
961 #region StartFigure
\r
962 public void StartFigure()
\r
964 NativeObject.StartFigure ();
\r
970 public void Warp (PointF[] destPoints, RectangleF srcRect)
\r
972 Warp (destPoints, srcRect, null, WarpMode.Perspective, 1.0f / 4.0f);
\r
976 public void Warp (PointF[] destPoints, RectangleF srcRect, Matrix matrix)
\r
978 Warp (destPoints, srcRect, matrix, WarpMode.Perspective, 1.0f / 4.0f);
\r
982 public void Warp (PointF[] destPoints, RectangleF srcRect, Matrix matrix, WarpMode warpMode)
\r
984 Warp (destPoints, srcRect, matrix, warpMode, 1.0f / 4.0f);
\r
988 public void Warp (PointF[] destPoints, RectangleF srcRect, Matrix matrix, WarpMode warpMode, float flatness)
\r
990 throw new NotImplementedException();
\r
995 public void Widen (Pen pen)
\r
1000 public void Widen (Pen pen, Matrix matrix)
\r
1002 Widen (pen, matrix, 2f/3f);
\r
1005 public void Widen (Pen pen, Matrix matrix, float flatness)
\r
1008 throw new ArgumentNullException("pen");
\r
1010 Shape = new ExtendedGeneralPath(((Stroke)pen).createStrokedShape(this));
\r
1011 Flatten(matrix, flatness);
\r
1015 private void SetPath (Point [] pts, byte [] types)
\r
1017 NativeObject.Clear ();
\r
1018 if (((PathPointType)types [0] & PathPointType.PathTypeMask) != PathPointType.Start)
\r
1019 NativeObject.moveTo (pts [0].X, pts [0].Y);
\r
1021 for (int i=0; i < pts.Length; i++) {
\r
1022 switch (((PathPointType)types [i] & PathPointType.PathTypeMask)) {
\r
1023 case PathPointType.Start :
\r
1024 NativeObject.moveTo (pts [i].X, pts [i].Y);
\r
1026 case PathPointType.Line :
\r
1027 NativeObject.lineTo (pts [i].X, pts [i].Y);
\r
1029 case PathPointType.Bezier3 :
\r
1030 float x1 = pts [i].X;
\r
1031 float y1 = pts [i].Y;
\r
1033 float x2 = pts [i].X;
\r
1034 float y2 = pts [i].Y;
\r
1036 float x3 = pts [i].X;
\r
1037 float y3 = pts [i].Y;
\r
1038 NativeObject.curveTo (x1,y1, x2, y2, x3, y3);
\r
1041 if (((PathPointType)types [i] & PathPointType.CloseSubpath) != 0)
\r
1042 NativeObject.closePath();
\r
1044 if (((PathPointType)types [i] & PathPointType.PathMarker) != 0)
\r
1045 NativeObject.SetMarkers ();
\r
1049 internal void SetPath (PointF [] pts, byte [] types)
\r
1051 NativeObject.Clear ();
\r
1052 if (((PathPointType)types [0] & PathPointType.PathTypeMask) != PathPointType.Start)
\r
1053 NativeObject.moveTo (pts [0].X, pts [0].Y);
\r
1054 for (int i=0; i < pts.Length; i++) {
\r
1055 switch (((PathPointType)types [i] & PathPointType.PathTypeMask)) {
\r
1056 case PathPointType.Start :
\r
1057 NativeObject.moveTo (pts [i].X, pts [i].Y);
\r
1059 case PathPointType.Line :
\r
1060 NativeObject.lineTo (pts [i].X, pts [i].Y);
\r
1062 case PathPointType.Bezier3 :
\r
1063 float x1 = pts [i].X;
\r
1064 float y1 = pts [i].Y;
\r
1066 float x2 = pts [i].X;
\r
1067 float y2 = pts [i].Y;
\r
1069 float x3 = pts [i].X;
\r
1070 float y3 = pts [i].Y;
\r
1071 NativeObject.curveTo (x1,y1, x2, y2, x3, y3);
\r
1074 if (((PathPointType)types [i] & PathPointType.CloseSubpath) != 0)
\r
1075 NativeObject.closePath();
\r
1077 if (((PathPointType)types [i] & PathPointType.PathMarker) != 0)
\r
1078 NativeObject.SetMarkers ();
\r