public void DrawPath(IEnumerable<PathOp> ops, Pen pen = null, Brush brush = null) { if (pen == null && brush == null) return; using (var path = new global::Android.Graphics.Path ()) { var bb = new BoundingBoxBuilder (); foreach (var op in ops) { var mt = op as MoveTo; if (mt != null) { var p = mt.Point; path.MoveTo ((float)p.X, (float)p.Y); bb.Add (p); continue; } var lt = op as LineTo; if (lt != null) { var p = lt.Point; path.LineTo ((float)p.X, (float)p.Y); bb.Add (p); continue; } var at = op as ArcTo; if (at != null) { var p = at.Point; path.LineTo ((float)p.X, (float)p.Y); bb.Add (p); continue; } var ct = op as CurveTo; if (ct != null) { var p = ct.Point; var c1 = ct.Control1; var c2 = ct.Control2; path.CubicTo ((float)c1.X, (float)c1.Y, (float)c2.X, (float)c2.Y, (float)p.X, (float)p.Y); bb.Add (p); bb.Add (c1); bb.Add (c2); continue; } var cp = op as ClosePath; if (cp != null) { path.Close (); continue; } throw new NotSupportedException ("Path Op " + op); } var frame = bb.BoundingBox; if (brush != null) { var paint = GetBrushPaint (brush, frame); graphics.DrawPath (path, paint); } if (pen != null) { var paint = GetPenPaint (pen); graphics.DrawPath (path, paint); } } }
public void DrawPath(IEnumerable <PathOp> ops, Pen pen = null, Brush brush = null) { if (pen == null && brush == null) { return; } using (var path = new global::Android.Graphics.Path()) { var bb = new BoundingBoxBuilder(); Point?prevPoint = null; foreach (var op in ops) { var mt = op as MoveTo; if (mt != null) { var p = mt.Point; path.MoveTo((float)p.X, (float)p.Y); bb.Add(p); prevPoint = p; continue; } var lt = op as LineTo; if (lt != null) { var p = lt.Point; path.LineTo((float)p.X, (float)p.Y); bb.Add(p); prevPoint = p; continue; } var at = op as ArcTo; if (at != null) { var p = at.Point; if (!prevPoint.HasValue) { throw new NotSupportedException("Cannot begin path with Arc."); } var pp = prevPoint.Value; Point c1, c2; at.GetCircles(pp, out c1, out c2); var circleCenter = at.LargeArc ^ !at.SweepClockwise ? c2 : c1; var rect = new Rect(circleCenter - at.Radius, at.Radius * 2); var startAngle = Conversions.RadToDeg((float)Math.Atan2(pp.Y - circleCenter.Y, pp.X - circleCenter.X)); var endAngle = Conversions.RadToDeg((float)Math.Atan2(p.Y - circleCenter.Y, p.X - circleCenter.X)); var sweepAngle = endAngle - startAngle; if (at.SweepClockwise && sweepAngle < 0) { // If we want to go CW, sweepAngle needs to be positive sweepAngle += 360.0f; } else if (!at.SweepClockwise && sweepAngle > 0) { // If we want to go CCW, sweepAngle needs to be negative sweepAngle -= 360.0f; } path.AddArc(Conversions.GetRectF(rect), startAngle, sweepAngle); bb.Add(p); prevPoint = p; continue; } var ct = op as CurveTo; if (ct != null) { var p = ct.Point; var c1 = ct.Control1; var c2 = ct.Control2; path.CubicTo((float)c1.X, (float)c1.Y, (float)c2.X, (float)c2.Y, (float)p.X, (float)p.Y); bb.Add(p); bb.Add(c1); bb.Add(c2); prevPoint = p; continue; } var cp = op as ClosePath; if (cp != null) { path.Close(); continue; } throw new NotSupportedException("Path Op " + op); } var frame = bb.BoundingBox; if (brush != null) { var paint = GetBrushPaint(brush, frame); graphics.DrawPath(path, paint); } if (pen != null) { var paint = GetPenPaint(pen); graphics.DrawPath(path, paint); } } }
public void DrawPath(IEnumerable<PathOp> ops, Pen pen = null, Brush brush = null) { if (pen == null && brush == null) return; using (var path = new global::Android.Graphics.Path ()) { var bb = new BoundingBoxBuilder (); Point? prevPoint = null; foreach (var op in ops) { var mt = op as MoveTo; if (mt != null) { var p = mt.Point; path.MoveTo ((float)p.X, (float)p.Y); bb.Add (p); prevPoint = p; continue; } var lt = op as LineTo; if (lt != null) { var p = lt.Point; path.LineTo ((float)p.X, (float)p.Y); bb.Add (p); prevPoint = p; continue; } var at = op as ArcTo; if (at != null) { var p = at.Point; if (!prevPoint.HasValue) { throw new NotSupportedException("Cannot begin path with Arc."); } var pp = prevPoint.Value; Point c1, c2; at.GetCircles(pp, out c1, out c2); var circleCenter = at.LargeArc ^ !at.SweepClockwise ? c2 : c1; var rect = new Rect(circleCenter - at.Radius, at.Radius * 2); var startAngle = Conversions.RadToDeg((float)Math.Atan2(pp.Y - circleCenter.Y, pp.X - circleCenter.X)); var endAngle = Conversions.RadToDeg((float)Math.Atan2(p.Y - circleCenter.Y, p.X - circleCenter.X)); var sweepAngle = endAngle - startAngle; if (at.SweepClockwise && sweepAngle < 0) { // If we want to go CW, sweepAngle needs to be positive sweepAngle += 360.0f; } else if (!at.SweepClockwise && sweepAngle > 0) { // If we want to go CCW, sweepAngle needs to be negative sweepAngle -= 360.0f; } path.AddArc(Conversions.GetRectF(rect), startAngle, sweepAngle); bb.Add (p); prevPoint = p; continue; } var ct = op as CurveTo; if (ct != null) { var p = ct.Point; var c1 = ct.Control1; var c2 = ct.Control2; path.CubicTo ((float)c1.X, (float)c1.Y, (float)c2.X, (float)c2.Y, (float)p.X, (float)p.Y); bb.Add (p); bb.Add (c1); bb.Add (c2); prevPoint = p; continue; } var cp = op as ClosePath; if (cp != null) { path.Close (); continue; } throw new NotSupportedException ("Path Op " + op); } var frame = bb.BoundingBox; if (brush != null) { var paint = GetBrushPaint (brush, frame); graphics.DrawPath (path, paint); } if (pen != null) { var paint = GetPenPaint (pen); graphics.DrawPath (path, paint); } } }
protected override void OnDraw(Canvas canvas) { var trans = Element.RenderTransform ?? new IdentityTransform(); var path = new global::Android.Graphics.Path(); foreach (var command in PathDataParser.ToAbsolute(PathDataParser.Parse(Element.Data))) { switch (command.Type) { case PathDataParser.CommandType.MoveTo: { var pt = trans.TransformPoint( new System.Drawing.PointF(command.Arguments[0], command.Arguments[1])); path.MoveTo(pt.X, pt.Y); } break; case PathDataParser.CommandType.LineTo: { var pt = trans.TransformPoint( new System.Drawing.PointF(command.Arguments[0], command.Arguments[1])); path.LineTo(pt.X, pt.Y); } break; case PathDataParser.CommandType.QBezier: { var pt = trans.TransformPoint( new System.Drawing.PointF(command.Arguments[0], command.Arguments[1])); var pt2 = trans.TransformPoint( new System.Drawing.PointF(command.Arguments[2], command.Arguments[3])); path.QuadTo(pt.X, pt.Y, pt2.X, pt2.Y); } break; case PathDataParser.CommandType.Bezier: { var pt = trans.TransformPoint( new System.Drawing.PointF(command.Arguments[0], command.Arguments[1])); var pt2 = trans.TransformPoint( new System.Drawing.PointF(command.Arguments[2], command.Arguments[3])); var pt3 = trans.TransformPoint( new System.Drawing.PointF(command.Arguments[4], command.Arguments[5])); path.CubicTo(pt.X, pt.Y, pt2.X, pt2.Y, pt3.X, pt3.Y); } break; case PathDataParser.CommandType.Close: path.Close(); DrawPath(canvas, path); path = new global::Android.Graphics.Path(); break; } } if (!path.IsEmpty) { DrawPath(canvas, path); } }