public override void RelCurveTo(object backend, double dx1, double dy1, double dx2, double dy2, double dx3, double dy3) { CGContext ctx = ((CGContextBackend)backend).Context; PointF p = ctx.GetPathCurrentPoint(); ctx.AddCurveToPoint((float)(p.X + dx1), (float)(p.Y + dy1), (float)(p.X + dx2), (float)(p.Y + dy2), (float)(p.X + dx3), (float)(p.Y + dy3)); }
private static void DrawSplineFromPoints(CGContext ctx, List <float> pts, float t) { var cp = new List <float>(); // array of control points, as x0,y0,x1,y1,... var n = pts.Count(); // Draw an open curve, not connected at the ends for (var i = 0; i < n - 4; i += 2) { cp = cp.Concat(GetControlPointsForSpline(pts[i], pts[i + 1], pts[i + 2], pts[i + 3], pts[i + 4], pts[i + 5], t)).ToList(); } ctx.MoveTo(pts[0], pts[1]); ctx.AddQuadCurveToPoint(cp[0], cp[1], pts[2], pts[3]); for (var i = 2; i < n - 5; i += 2) { ctx.AddCurveToPoint(cp[2 * i - 2], cp[2 * i - 1], cp[2 * i], cp[2 * i + 1], pts[i + 2], pts[i + 3]); } ctx.AddQuadCurveToPoint(cp[2 * n - 10], cp[2 * n - 9], pts[n - 2], pts[n - 1]); }
public override void DrawInContext(CGContext context) { // Drawing with a white stroke color context.SetRGBStrokeColor(1, 1, 1, 1); // Draw them with a 2 stroke width so they are a bit more visible. context.SetLineWidth(2); // Draw a bezier curve with end points s,e and control points cp1,cp2 var s = new PointF(30, 120); var e = new PointF(300, 120); var cp1 = new PointF(120, 30); var cp2 = new PointF(210, 210); context.MoveTo(s.X, s.Y); context.AddCurveToPoint(cp1.X, cp1.Y, cp2.X, cp2.Y, e.X, e.Y); context.StrokePath(); // Show the control points. context.SetRGBStrokeColor(1, 0, 0, 1); context.MoveTo(s.X, s.Y); context.AddLineToPoint(cp1.X, cp1.Y); context.MoveTo(e.X, e.Y); context.AddLineToPoint(cp2.X, cp2.Y); context.StrokePath(); // Draw a quad curve with end points s,e and control point cp1 context.SetRGBStrokeColor(1, 1, 1, 1); s = new PointF(30, 300); e = new PointF(270, 300); cp1 = new PointF(150, 180); context.MoveTo(s.X, s.Y); context.AddQuadCurveToPoint(cp1.X, cp1.Y, e.X, e.Y); context.StrokePath(); // Show the control point. context.SetRGBStrokeColor(1, 0, 0, 1); context.MoveTo(s.X, s.Y); context.AddLineToPoint(cp1.X, cp1.Y); context.StrokePath(); }
public void DrawPath(IEnumerable <PathOp> ops, Pen pen = null, Brush brush = null) { if (pen == null && brush == null) { return; } DrawElement(() => { var bb = new BoundingBoxBuilder(); foreach (var op in ops) { var mt = op as MoveTo; if (mt != null) { var p = mt.Point; if (!IsValid(p.X) || !IsValid(p.Y)) { continue; } context.MoveTo((nfloat)p.X, (nfloat)p.Y); bb.Add(p); continue; } var lt = op as LineTo; if (lt != null) { var p = lt.Point; if (!IsValid(p.X) || !IsValid(p.Y)) { continue; } context.AddLineToPoint((nfloat)p.X, (nfloat)p.Y); bb.Add(p); continue; } var at = op as ArcTo; if (at != null) { var p = at.Point; if (!IsValid(p.X) || !IsValid(p.Y)) { continue; } var pp = Conversions.GetPoint(context.GetPathCurrentPoint()); if (pp == p) { continue; } Point c1, c2; at.GetCircles(pp, out c1, out c2); var circleCenter = (at.LargeArc ^ at.SweepClockwise) ? c1 : c2; var startAngle = (float)Math.Atan2(pp.Y - circleCenter.Y, pp.X - circleCenter.X); var endAngle = (float)Math.Atan2(p.Y - circleCenter.Y, p.X - circleCenter.X); if (!IsValid(circleCenter.X) || !IsValid(circleCenter.Y) || !IsValid(startAngle) || !IsValid(endAngle)) { context.MoveTo((nfloat)p.X, (nfloat)p.Y); continue; } var clockwise = !at.SweepClockwise; context.AddArc((nfloat)circleCenter.X, (nfloat)circleCenter.Y, (nfloat)at.Radius.Min, startAngle, endAngle, clockwise); bb.Add(p); continue; } var ct = op as CurveTo; if (ct != null) { var p = ct.Point; if (!IsValid(p.X) || !IsValid(p.Y)) { continue; } var c1 = ct.Control1; var c2 = ct.Control2; if (!IsValid(c1.X) || !IsValid(c1.Y) || !IsValid(c2.X) || !IsValid(c2.Y)) { context.MoveTo((nfloat)p.X, (nfloat)p.Y); continue; } context.AddCurveToPoint((nfloat)c1.X, (nfloat)c1.Y, (nfloat)c2.X, (nfloat)c2.Y, (nfloat)p.X, (nfloat)p.Y); bb.Add(p); bb.Add(c1); bb.Add(c2); continue; } var cp = op as ClosePath; if (cp != null) { context.ClosePath(); continue; } throw new NotSupportedException("Path Op " + op); } return(bb.BoundingBox); }, pen, brush); }
/// <summary> /// Draw the view into the specified rect. /// </summary> /// <param name="rect">The Rect.</param> public override void Draw(RectangleF rect) { RectangleF viewBounds = this.Bounds; CGContext curContext = UIGraphics.GetCurrentContext(); var numberString = this.Value.ToString(this.TextFormat); SizeF numberSize = new NSString(numberString).StringSize(this.Font); using (CGPath badgePath = this.NewBadgePathForTextSize(numberSize)) { RectangleF badgeRect = badgePath.PathBoundingBox; badgeRect.X = 0; badgeRect.Y = 0; badgeRect.Size = new SizeF((float)Math.Ceiling(badgeRect.Size.Width), (float)Math.Ceiling(badgeRect.Size.Height)); curContext.SaveState(); curContext.SetLineWidth(this.StrokeWidth); curContext.SetStrokeColorWithColor(this.StrokeColor.CGColor); curContext.SetFillColorWithColor(this.FillColor.CGColor); // Line stroke straddles the path, so we need to account for the outer portion badgeRect.Size = new SizeF(badgeRect.Size.Width + (float)Math.Ceiling(this.StrokeWidth / 2), badgeRect.Size.Height + (float)Math.Ceiling(this.StrokeWidth / 2)); PointF ctm = new PointF(0f, 0f); switch (this.Alignment) { case UITextAlignment.Justified: case UITextAlignment.Natural: case UITextAlignment.Center: ctm = new PointF((float)Math.Round((viewBounds.Size.Width - badgeRect.Size.Width) / 2), (float)Math.Round((viewBounds.Size.Height - badgeRect.Size.Height) / 2)); break; case UITextAlignment.Left: ctm = new PointF(0.0f, (float)Math.Round((viewBounds.Size.Height - badgeRect.Size.Height) / 2)); break; case UITextAlignment.Right: ctm = new PointF(viewBounds.Size.Width - badgeRect.Size.Width, (float)Math.Round(viewBounds.Size.Height - badgeRect.Size.Height) / 2); break; } curContext.TranslateCTM(ctm.X, ctm.Y); if (this.Shadow) { curContext.SaveState(); SizeF blurSize = this.ShadowOffset; curContext.SetShadowWithColor(blurSize, 4, this.ShadowColor.CGColor); curContext.BeginPath(); curContext.AddPath(badgePath); curContext.ClosePath(); curContext.DrawPath(CGPathDrawingMode.FillStroke); curContext.RestoreState(); } curContext.BeginPath(); curContext.AddPath(badgePath); curContext.ClosePath(); curContext.DrawPath(CGPathDrawingMode.FillStroke); if (this.Shine) { curContext.BeginPath(); curContext.AddPath(badgePath); curContext.ClosePath(); curContext.Clip(); using (CGColorSpace colorSpace = CGColorSpace.CreateDeviceRGB()) { float[] shinyColorGradient = new float[8] { 1f, 1f, 1f, 0.8f, 1f, 1f, 1f, 0f }; float[] shinyLocationGradient = new float[2] { 0f, 1f }; using (CGGradient gradient = new CGGradient(colorSpace, shinyColorGradient, shinyLocationGradient)) { curContext.SaveState(); curContext.BeginPath(); curContext.MoveTo(0.0f, 0.0f); float shineStartY = badgeRect.Size.Height * 0.25f; float shineStopY = shineStartY + (badgeRect.Size.Height * 0.4f); curContext.AddLineToPoint(0, shineStartY); curContext.AddCurveToPoint( 0, shineStopY, badgeRect.Size.Width, shineStopY, badgeRect.Size.Width, shineStartY); curContext.AddLineToPoint(badgeRect.Size.Width, 0); curContext.ClosePath(); curContext.Clip(); curContext.DrawLinearGradient( gradient, new PointF(badgeRect.Size.Width / 2.0f, 0.0f), new PointF(badgeRect.Size.Width / 2.0f, shineStopY), CGGradientDrawingOptions.DrawsBeforeStartLocation); curContext.RestoreState(); } } } curContext.RestoreState(); curContext.SaveState(); curContext.SetFillColorWithColor(this.TextColor.CGColor); PointF textPt = new PointF( ctm.X + ((badgeRect.Size.Width - numberSize.Width) / 2) + this.AdjustOffset.X, ctm.Y + ((badgeRect.Size.Height - numberSize.Height) / 2) + this.AdjustOffset.Y); new NSString(numberString).DrawString(textPt, this.Font); curContext.RestoreState(); } }
make_arc(CGContext graphics, bool start, float x, float y, float width, float height, float startAngle, float endAngle, bool antialiasing, bool isPieSlice) { float delta, bcp; double sin_alpha, sin_beta, cos_alpha, cos_beta; float PI = (float)Math.PI; float rx = width / 2; float ry = height / 2; /* center */ float cx = x + rx; float cy = y + ry; /* angles in radians */ float alpha = startAngle * PI / 180; float beta = endAngle * PI / 180; /* adjust angles for ellipses */ alpha = (float)Math.Atan2(rx * Math.Sin(alpha), ry * Math.Cos(alpha)); beta = (float)Math.Atan2(rx * Math.Sin(beta), ry * Math.Cos(beta)); if (Math.Abs(beta - alpha) > PI) { if (beta > alpha) { beta -= 2 * PI; } else { alpha -= 2 * PI; } } delta = beta - alpha; bcp = (float)(4.0 / 3.0 * (1 - Math.Cos(delta / 2)) / Math.Sin(delta / 2)); sin_alpha = Math.Sin(alpha); sin_beta = Math.Sin(beta); cos_alpha = Math.Cos(alpha); cos_beta = Math.Cos(beta); /* don't move to starting point if we're continuing an existing curve */ if (start) { /* starting point */ double sx = cx + rx * cos_alpha; double sy = cy + ry * sin_alpha; if (isPieSlice) { graphics.AddLineToPoint((float)sx, (float)sy); } else { graphics.MoveTo((float)sx, (float)sy); } } graphics.AddCurveToPoint(cx + rx * (float)(cos_alpha - bcp * sin_alpha), cy + ry * (float)(sin_alpha + bcp * cos_alpha), cx + rx * (float)(cos_beta + bcp * sin_beta), cy + ry * (float)(sin_beta - bcp * cos_beta), cx + rx * (float)cos_beta, cy + ry * (float)sin_beta); }
public void DrawPath(IEnumerable <PathOp> ops, Pen pen = null, Brush brush = null) { if (pen == null && brush == null) { return; } DrawElement(() => { var bb = new BoundingBoxBuilder(); foreach (var op in ops) { var mt = op as MoveTo; if (mt != null) { var p = mt.Point; context.MoveTo((nfloat)p.X, (nfloat)p.Y); bb.Add(p); continue; } var lt = op as LineTo; if (lt != null) { var p = lt.Point; context.AddLineToPoint((nfloat)p.X, (nfloat)p.Y); bb.Add(p); continue; } var at = op as ArcTo; if (at != null) { var p = at.Point; var pp = Conversions.GetPoint(context.GetPathCurrentPoint()); Point c1, c2; at.GetCircles(pp, out c1, out c2); context.AddLineToPoint((nfloat)p.X, (nfloat)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; context.AddCurveToPoint((nfloat)c1.X, (nfloat)c1.Y, (nfloat)c2.X, (nfloat)c2.Y, (nfloat)p.X, (nfloat)p.Y); bb.Add(p); bb.Add(c1); bb.Add(c2); continue; } var cp = op as ClosePath; if (cp != null) { context.ClosePath(); continue; } throw new NotSupportedException("Path Op " + op); } return(bb.BoundingBox); }, pen, brush); }
public override void DrawInContext (CGContext context) { // Drawing with a white stroke color context.SetStrokeColor (1, 1, 1, 1); // Draw them with a 2 stroke width so they are a bit more visible. context.SetLineWidth (2); // Draw a bezier curve with end points s,e and control points cp1,cp2 var s = new CGPoint (30, 120); var e = new CGPoint (300, 120); var cp1 = new CGPoint (120, 30); var cp2 = new CGPoint (210, 210); context.MoveTo (s.X, s.Y); context.AddCurveToPoint (cp1.X, cp1.Y, cp2.X, cp2.Y, e.X, e.Y); context.StrokePath (); // Show the control points. context.SetStrokeColor (1, 0, 0, 1); context.MoveTo (s.X, s.Y); context.AddLineToPoint (cp1.X, cp1.Y); context.MoveTo (e.X, e.Y); context.AddLineToPoint (cp2.X, cp2.Y); context.StrokePath (); // Draw a quad curve with end points s,e and control point cp1 context.SetStrokeColor (1, 1, 1, 1); s = new CGPoint (30, 300); e = new CGPoint (270, 300); cp1 = new CGPoint (150, 180); context.MoveTo (s.X, s.Y); context.AddQuadCurveToPoint (cp1.X, cp1.Y, e.X, e.Y); context.StrokePath (); // Show the control point. context.SetStrokeColor (1, 0, 0, 1); context.MoveTo (s.X, s.Y); context.AddLineToPoint (cp1.X, cp1.Y); context.StrokePath (); }
public void DrawPath(IEnumerable <PathOperation> ops, Pen pen = null, BaseBrush baseBrush = null) { if (pen == null && baseBrush == null) { return; } DrawElement(() => { var bb = new BoundingBoxBuilder(); var lines = new List <CGPoint>(); foreach (var op in ops) { var moveTo = op as MoveTo; if (moveTo != null) { var start = moveTo.Start; var end = moveTo.End; context.MoveTo((nfloat)start.X, (nfloat)start.Y); context.MoveTo((nfloat)end.X, (nfloat)end.Y); bb.Add(start); bb.Add(end); continue; } var lt = op as LineTo; if (lt != null) { var start = lt.Start; var end = lt.End; context.AddLineToPoint((float)start.X, (float)start.Y); context.AddLineToPoint((float)end.X, (float)end.Y); bb.Add(start); bb.Add(end); continue; } var at = op as ArcTo; if (at != null) { var p = at.Point; var pp = Conversions.GetPoint(context.GetPathCurrentPoint()); Point c1, c2; at.GetCircles(pp, out c1, out c2); context.AddLineToPoint((nfloat)p.X, (nfloat)p.Y); bb.Add(p); continue; } var curveTo = op as CurveTo; if (curveTo != null) { var end = curveTo.End; var control1 = curveTo.FirstControlPoint; var control2 = curveTo.SecondControlPoint; context.AddCurveToPoint((nfloat)control1.X, (nfloat)control1.Y, (nfloat)control2.X, (nfloat)control2.Y, (nfloat)end.X, (nfloat)end.Y); bb.Add(control1); bb.Add(control2); bb.Add(end); continue; } var cp = op as ClosePath; if (cp != null) { context.ClosePath(); continue; } throw new NotSupportedException("Path Op " + op); } return(bb.BoundingBox); }, pen, baseBrush); }
void CurveTo(float x1, float y1, float x2, float y2, float x3, float y3) { context.AddCurveToPoint(x1, y1, x2, y2, x3, y3); }
/* * Based on the algorithm described in * http://www.stillhq.com/ctpfaq/2002/03/c1088.html#AEN1212 */ static void make_arc(CGContext graphics, bool start, float x, float y, float width, float height, float startAngle, float endAngle, bool antialiasing, bool isPieSlice) { float delta, bcp; double sin_alpha, sin_beta, cos_alpha, cos_beta; float PI = (float)Math.PI; float rx = width / 2; float ry = height / 2; /* center */ float cx = x + rx; float cy = y + ry; /* angles in radians */ float alpha = startAngle * PI / 180; float beta = endAngle * PI / 180; /* adjust angles for ellipses */ alpha = (float)Math.Atan2(rx * Math.Sin(alpha), ry * Math.Cos(alpha)); beta = (float)Math.Atan2(rx * Math.Sin(beta), ry * Math.Cos(beta)); if (Math.Abs(beta - alpha) > PI) { if (beta > alpha) beta -= 2 * PI; else alpha -= 2 * PI; } delta = beta - alpha; bcp = (float)(4.0 / 3.0 * (1 - Math.Cos(delta / 2)) / Math.Sin(delta / 2)); sin_alpha = Math.Sin(alpha); sin_beta = Math.Sin(beta); cos_alpha = Math.Cos(alpha); cos_beta = Math.Cos(beta); /* don't move to starting point if we're continuing an existing curve */ if (start) { /* starting point */ double sx = cx + rx * cos_alpha; double sy = cy + ry * sin_alpha; if (isPieSlice) graphics.AddLineToPoint((float)sx,(float)sy); else graphics.MoveTo((float)sx,(float)sy); } graphics.AddCurveToPoint(cx + rx * (float)(cos_alpha - bcp * sin_alpha), cy + ry * (float)(sin_alpha + bcp * cos_alpha), cx + rx * (float)(cos_beta + bcp * sin_beta), cy + ry * (float)(sin_beta - bcp * cos_beta), cx + rx * (float)cos_beta, cy + ry * (float)sin_beta); }