Ejemplo n.º 1
0
        private UIBezierPath NormalPath(LiquittableCircle circle, LiquittableCircle other)
        {
            var tuple1   = CircleConnectedPoint(circle, other);
            var tuple2   = CircleConnectedPoint(other, circle);
            var cgPoint1 = tuple1.Item1;
            var cgPoint2 = tuple1.Item2;
            var cgPoint3 = tuple2.Item1;
            var cgPoint4 = tuple2.Item2;
            var nullable = CoreGraphicsExtensions.Intersection(cgPoint1, cgPoint3, cgPoint2, cgPoint4);

            if (!nullable.HasValue)
            {
                return(null);
            }
            var uiBezierPath = new UIBezierPath();
            var nfloat       = CircleRatio(circle, other);

            // ISSUE: reference to a compiler-generated method
            uiBezierPath.MoveTo(cgPoint1);
            var cgPoint5      = cgPoint2.Mid(cgPoint3);
            var cgPoint6      = cgPoint1.Mid(cgPoint4);
            var ratio         = (1 - nfloat) / (1 - AngleThreshold) * Viscosity;
            var controlPoint1 = cgPoint5.Mid(nullable.Value).Split(cgPoint6, ratio);
            var controlPoint2 = cgPoint6.Mid(nullable.Value).Split(cgPoint5, ratio);

            // ISSUE: reference to a compiler-generated method
            uiBezierPath.AddQuadCurveToPoint(cgPoint4, controlPoint1);
            // ISSUE: reference to a compiler-generated method
            uiBezierPath.AddLineTo(cgPoint3);
            // ISSUE: reference to a compiler-generated method
            uiBezierPath.AddQuadCurveToPoint(cgPoint2, controlPoint2);
            // ISSUE: reference to a compiler-generated method
            uiBezierPath.ClosePath();
            return(uiBezierPath);
        }
        private UIBezierPath NormalPath(LiquittableCircle circle, LiquittableCircle other)
        {
            var p1p2    = CircleConnectedPoint(circle, other);
            var p3p4    = CircleConnectedPoint(other, circle);
            var p1      = p1p2.Item1;
            var p2      = p1p2.Item2;
            var p3      = p3p4.Item1;
            var p4      = p3p4.Item2;
            var crossed = CoreGraphicsExtensions.Intersection(p1, p3, p2, p4);

            if (crossed != null)
            {
                var path = new UIBezierPath();
                var r    = CircleRatio(circle, other);
                path.MoveTo(p1);
                var r1   = p2.Mid(p3);
                var r2   = p1.Mid(p4);
                var rate = (1 - r) / (1 - AngleThreshold) * Viscosity;
                var mul  = r1.Mid(crossed.Value).Split(r2, rate);
                var mul2 = r2.Mid(crossed.Value).Split(r1, rate);
                path.AddQuadCurveToPoint(p4, mul);
                path.AddLineTo(p3);
                path.AddQuadCurveToPoint(p2, mul2);
                path.ClosePath();
                return(path);
            }
            return(null);
        }
Ejemplo n.º 3
0
        private UIBezierPath ShapePath(CGSize size)
        {
            var intensity    = 0.44f;
            var controlRatio = 0.25f;


            var     padding     = 0;
            CGPoint leftTop     = new CGPoint(x: padding, y: padding);
            CGPoint rightTop    = new CGPoint(x: size.Width - padding, y: padding);
            CGPoint leftBottom  = new CGPoint(x: padding, y: size.Height - padding);
            CGPoint rightBottom = new CGPoint(x: size.Width - padding, y: size.Height - padding);


            var path = new UIBezierPath();

            path.MoveTo(leftTop);
            path.AddQuadCurveToPoint(new CGPoint(x: size.Width / 2, y: size.Height / 2 * intensity),
                                     controlPoint: new CGPoint(x: size.Width / 2 * controlRatio, y: size.Height / 2 * intensity));
            path.AddQuadCurveToPoint(rightTop,
                                     controlPoint: new CGPoint(x: size.Width - (size.Width / 2 * controlRatio), y: size.Height / 2 * intensity));
            path.AddLineTo(rightBottom);
            path.AddQuadCurveToPoint(new CGPoint(x: size.Width / 2, y: size.Height - (size.Height / 2 * intensity)),
                                     controlPoint: new CGPoint(x: size.Width - (size.Width / 2 * controlRatio), y: size.Height - (size.Height / 2 * intensity)));
            path.AddQuadCurveToPoint(leftBottom,
                                     controlPoint: new CGPoint(x: size.Width / 2 * controlRatio, y: size.Height - (size.Height / 2 * intensity)));
            path.AddLineTo(leftTop);
            path.ClosePath();
            return(path);
        }
Ejemplo n.º 4
0
        public static UIBezierPath CreatePolygonPath(CGRect rect, int sides, double cornerRadius = 0.0, double rotationOffset = 0.0)
        {
            var offsetRadians = rotationOffset * Math.PI / 180;
            var path          = new UIBezierPath();
            var theta         = 2 * Math.PI / sides;

            var width  = (-cornerRadius + Math.Min(rect.Size.Width, rect.Size.Height)) / 2;
            var center = new CGPoint(rect.Width / 2, rect.Height / 2);

            var radius = width + cornerRadius - (Math.Cos(theta) * cornerRadius) / 2;

            var angle  = offsetRadians;
            var corner = new CGPoint(center.X + (radius - cornerRadius) * Math.Cos(angle), center.Y + (radius - cornerRadius) * Math.Sin(angle));

            path.MoveTo(new CGPoint(corner.X + cornerRadius * Math.Cos(angle + theta), corner.Y + cornerRadius * Math.Sin(angle + theta)));

            for (var i = 0; i < sides; i++)
            {
                angle += theta;
                corner = new CGPoint(center.X + (radius - cornerRadius) * Math.Cos(angle), center.Y + (radius - cornerRadius) * Math.Sin(angle));
                var tip   = new CGPoint(center.X + radius * Math.Cos(angle), center.Y + radius * Math.Sin(angle));
                var start = new CGPoint(corner.X + cornerRadius * Math.Cos(angle - theta), corner.Y + cornerRadius * Math.Sin(angle - theta));
                var end   = new CGPoint(corner.X + cornerRadius * Math.Cos(angle + theta), corner.Y + cornerRadius * Math.Sin(angle + theta));

                path.AddLineTo(start);
                path.AddQuadCurveToPoint(end, tip);
            }

            path.ClosePath();

            return(path);
        }
        private UIBezierPath[] SplitPath(LiquittableCircle circle, LiquittableCircle other, nfloat ratio)
        {
            var p1p2    = CircleConnectedPoint(circle, other, CoreGraphicsExtensions.DegToRad(60));
            var p3p4    = CircleConnectedPoint(other, circle, CoreGraphicsExtensions.DegToRad(60));
            var p1      = p1p2.Item1;
            var p2      = p1p2.Item2;
            var p3      = p3p4.Item1;
            var p4      = p3p4.Item2;
            var crossed = CoreGraphicsExtensions.Intersection(p1, p3, p2, p4);

            if (crossed != null)
            {
                var d1 = CircleConnectedPoint(circle, other, 0).Item1;
                var d2 = CircleConnectedPoint(other, circle, 0).Item1;
                var r  = (ratio - connectThresh) / (AngleThreshold - connectThresh);

                var a1   = d2.Split(crossed.Value, r * r);
                var part = new UIBezierPath();
                part.MoveTo(p1);
                part.AddQuadCurveToPoint(p2, a1);
                part.ClosePath();

                var a2    = d1.Split(crossed.Value, r * r);
                var part2 = new UIBezierPath();
                part2.MoveTo(p3);
                part2.AddQuadCurveToPoint(p4, a2);
                part2.ClosePath();

                return(new[] { part, part2 });
            }
            return(new UIBezierPath[0]);
        }
Ejemplo n.º 6
0
        async Task animateView(UIView view)
        {
            var size   = view.Frame.Size;
            var grow   = new SizeF(size.Width * 1.7f, size.Height * 1.7f);
            var shrink = new SizeF(size.Width * .4f, size.Height * .4f);
            TaskCompletionSource <bool> tcs = new TaskCompletionSource <bool> ();
            //Set the animation path
            var pathAnimation = CAKeyFrameAnimation.GetFromKeyPath("position");

            pathAnimation.CalculationMode     = CAAnimation.AnimationPaced;
            pathAnimation.FillMode            = CAFillMode.Forwards;
            pathAnimation.RemovedOnCompletion = false;
            pathAnimation.Duration            = .5;

            UIBezierPath path = new UIBezierPath();

            path.MoveTo(view.Center);
            path.AddQuadCurveToPoint(new PointF(290, 34), new PointF(view.Center.X, View.Center.Y));
            pathAnimation.Path = path.CGPath;

            //Set size change
            var growAnimation = CABasicAnimation.FromKeyPath("bounds.size");

            growAnimation.To                  = NSValue.FromSizeF(grow);
            growAnimation.FillMode            = CAFillMode.Forwards;
            growAnimation.Duration            = .1;
            growAnimation.RemovedOnCompletion = false;



            var shrinkAnimation = CABasicAnimation.FromKeyPath("bounds.size");

            shrinkAnimation.To                  = NSValue.FromSizeF(shrink);
            shrinkAnimation.FillMode            = CAFillMode.Forwards;
            shrinkAnimation.Duration            = .4;
            shrinkAnimation.RemovedOnCompletion = false;
            shrinkAnimation.BeginTime           = .1;


            CAAnimationGroup animations = new CAAnimationGroup();

            animations.FillMode            = CAFillMode.Forwards;
            animations.RemovedOnCompletion = false;
            animations.Animations          = new CAAnimation[] {
                pathAnimation,
                growAnimation,
                shrinkAnimation,
            };
            animations.Duration          = .5;
            animations.AnimationStopped += (sender, e) => {
                tcs.TrySetResult(true);
            };
            view.Layer.AddAnimation(animations, "movetocart");
            NSTimer.CreateScheduledTimer(.5, () => view.RemoveFromSuperview());
            await tcs.Task;
        }
		async Task animateView(UIView view)
		{
			var size = view.Frame.Size;
			var grow = new SizeF(size.Width * 1.7f, size.Height * 1.7f);
			var shrink = new SizeF(size.Width * .4f, size.Height * .4f);
			TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool> ();
			//Set the animation path
			var pathAnimation = CAKeyFrameAnimation.GetFromKeyPath("position");	
			pathAnimation.CalculationMode = CAAnimation.AnimationPaced;
			pathAnimation.FillMode = CAFillMode.Forwards;
			pathAnimation.RemovedOnCompletion = false;
			pathAnimation.Duration = .5;

			UIBezierPath path = new UIBezierPath ();
			path.MoveTo (view.Center);
			path.AddQuadCurveToPoint (new PointF (290, 34), new PointF(view.Center.X,View.Center.Y));
			pathAnimation.Path = path.CGPath;

			//Set size change
			var growAnimation = CABasicAnimation.FromKeyPath("bounds.size");
			growAnimation.To = NSValue.FromSizeF (grow);
			growAnimation.FillMode = CAFillMode.Forwards;
			growAnimation.Duration = .1;
			growAnimation.RemovedOnCompletion = false;



			var shrinkAnimation = CABasicAnimation.FromKeyPath("bounds.size");
			shrinkAnimation.To = NSValue.FromSizeF (shrink);
			shrinkAnimation.FillMode = CAFillMode.Forwards;
			shrinkAnimation.Duration = .4;
			shrinkAnimation.RemovedOnCompletion = false;
			shrinkAnimation.BeginTime = .1;


			CAAnimationGroup animations = new CAAnimationGroup ();
			animations.FillMode = CAFillMode.Forwards;
			animations.RemovedOnCompletion = false;
			animations.Animations = new CAAnimation[] {
				pathAnimation,
				growAnimation,
				shrinkAnimation,
			};
			animations.Duration = .5;
			animations.AnimationStopped += (sender, e) => {
				tcs.TrySetResult(true);
			};
			view.Layer.AddAnimation (animations,"movetocart");
			NSTimer.CreateScheduledTimer (.5, () => view.RemoveFromSuperview ());
			await tcs.Task;

		}
Ejemplo n.º 8
0
        public override void TouchesMoved(NSSet touches, UIEvent evt)
        {
            base.TouchesMoved(touches, evt);
            UITouch touch        = touches.AnyObject as UITouch;
            var     currentPoint = touch.LocationInView(this);

            currentPoint = touch.LocationInView(this);
            if (Math.Abs(currentPoint.X - previousPoint.X) >= 4 ||
                Math.Abs(currentPoint.Y - previousPoint.Y) >= 4)
            {
                var newPoint = new CGPoint((currentPoint.X + previousPoint.X) / 2, (currentPoint.Y + previousPoint.Y) / 2);

                currentPath.AddQuadCurveToPoint(newPoint, previousPoint);
                previousPoint = currentPoint;
            }

            InvokeOnMainThread(SetNeedsDisplay);
        }
Ejemplo n.º 9
0
        public override void TouchesMoved(MonoTouch.Foundation.NSSet touches, UIEvent evt)
        {
            base.TouchesMoved(touches, evt);
            UITouch touch    = (UITouch)touches.AnyObject;
            var     location = touch.LocationInView(this);

            float dx = Math.Abs(location.X - mX);
            float dy = Math.Abs(location.Y - mY);

            if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE)
            {
                mPath.AddQuadCurveToPoint(new PointF((location.X + mX) / 2f, (location.Y + mY) / 2f), new PointF(mX, mY));
                mMoved = true;
                mX     = location.X;
                mY     = location.Y;
                AddPixelsXY(mX, mY, false);
            }
            this.SetNeedsDisplay();
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Sent when one or more fingers move on the screen.
        /// </summary>
        /// <param name="touches">Set containing the touches as objects of type <see cref="T:UIKit.UITouch" />.</param>
        /// <param name="evt"><para>The UIEvent that encapsulates all of the touches and the event information.</para>
        /// <para tool="nullallowed">This parameter can be <see langword="null" />.</para></param>
        /// <remarks><para>Since iOS 9.0, <see cref="M:UIKit.UIResponder.TouchesMoved(Foundation.NSSet,UIKit.UIEvent)" /> events are raised on supported hardware and configurations for changes in user-applied pressure. The <see cref="P:UIKit.UITouch.Force" /> property of the <see cref="T:UIKit.UITouch" /> object in the <paramref name="touches" /> set argument contains the magnitude of the touch that raised the event. The following example shows a basic use:</para>
        /// <para>
        ///   <code lang="c#"><![CDATA[
        /// if (TraitCollection.ForceTouchCapability == UIForceTouchCapability.Available) {
        /// UITouch t = touches.AnyObject as UITouch;
        /// ForceLabel.Text = "Force: " + t.Force.ToString ();
        /// }
        /// else {
        /// ForceLabel.Text = "Force Not Active";
        /// }]]></code>
        /// </para></remarks>
        public override void TouchesMoved(NSSet touches, UIEvent evt)
        {
            var touch        = (UITouch)touches.AnyObject;
            var currentPoint = touch.LocationInView(this);

            if (Math.Abs(currentPoint.X - _previousPoint.X) >= 4 ||
                Math.Abs(currentPoint.Y - _previousPoint.Y) >= 4)
            {
                var newPoint = new CGPoint((currentPoint.X + _previousPoint.X) / 2, (currentPoint.Y + _previousPoint.Y) / 2);

                _currentPath.AddQuadCurveToPoint(newPoint, _previousPoint);
                _previousPoint = currentPoint;
            }
            else
            {
                _currentPath.AddLineTo(currentPoint);
            }

            InvokeOnMainThread(SetNeedsDisplay);
        }
Ejemplo n.º 11
0
        private UIBezierPath[] SplitPath(LiquittableCircle circle, LiquittableCircle other, nfloat ratio)
        {
            var tuple1   = CircleConnectedPoint(circle, other, CoreGraphicsExtensions.DegToRad(60));
            var tuple2   = CircleConnectedPoint(other, circle, CoreGraphicsExtensions.DegToRad(60));
            var cgPoint1 = tuple1.Item1;
            var cgPoint2 = tuple1.Item2;
            var cgPoint3 = tuple2.Item1;
            var cgPoint4 = tuple2.Item2;
            var nullable = CoreGraphicsExtensions.Intersection(cgPoint1, cgPoint3, cgPoint2, cgPoint4);

            if (!nullable.HasValue)
            {
                return(new UIBezierPath[0]);
            }
            var self1         = CircleConnectedPoint(circle, other, 0).Item1;
            var self2         = CircleConnectedPoint(other, circle, 0).Item1;
            var nfloat        = (ratio - _connectThresh) / (AngleThreshold - _connectThresh);
            var controlPoint1 = self2.Split(nullable.Value, nfloat * nfloat);
            var uiBezierPath1 = new UIBezierPath();

            // ISSUE: reference to a compiler-generated method
            uiBezierPath1.MoveTo(cgPoint1);
            // ISSUE: reference to a compiler-generated method
            uiBezierPath1.AddQuadCurveToPoint(cgPoint2, controlPoint1);
            // ISSUE: reference to a compiler-generated method
            uiBezierPath1.ClosePath();
            var controlPoint2 = self1.Split(nullable.Value, nfloat * nfloat);
            var uiBezierPath2 = new UIBezierPath();

            // ISSUE: reference to a compiler-generated method
            uiBezierPath2.MoveTo(cgPoint3);
            // ISSUE: reference to a compiler-generated method
            uiBezierPath2.AddQuadCurveToPoint(cgPoint4, controlPoint2);
            // ISSUE: reference to a compiler-generated method
            uiBezierPath2.ClosePath();
            return(new[]
            {
                uiBezierPath1,
                uiBezierPath2
            });
        }
 public override void TouchesMoved(NSSet touches, UIEvent evt)
 {
     var touch = (UITouch)touches.AnyObject;
     var currentPoint = touch.LocationInView(this);
     if (Math.Abs(currentPoint.X - PreviousPoint.X) >= 4 ||
         Math.Abs(currentPoint.Y - PreviousPoint.Y) >= 4)
     {
         var newPoint = new PointF((currentPoint.X + PreviousPoint.X) / 2,
             (currentPoint.Y + PreviousPoint.Y) / 2);
         CurrentPath.AddQuadCurveToPoint(newPoint, PreviousPoint);
         PreviousPoint = currentPoint;
         InvokeOnMainThread(SetNeedsDisplay);
         PointerEvent?.Invoke(this, new PointerEventArgs(PointerEventArgs.
              PointerEventType.Move, PreviousPoint.ToPoint(), newPoint.ToPoint(), PointerDown));
     }
     else
     {
         CurrentPath.AddLineTo(currentPoint);
         InvokeOnMainThread(SetNeedsDisplay);
     }
 }
Ejemplo n.º 13
0
        public CGPath WavePath(nfloat amountX, nfloat amountY)
        {
            var w       = Frame.Width;
            var h       = Frame.Height;
            var centerY = (nfloat)0f;
            var bottomY = h;

            var topLeftPoint     = new CGPoint(0, centerY);
            var topMidPoint      = new CGPoint(w / 2 + amountX, centerY + amountY);
            var topRightPoint    = new CGPoint(w, centerY);
            var bottomLeftPoint  = new CGPoint(0, bottomY);
            var bottomRightPoint = new CGPoint(w, bottomY);

            var bezierPath = new UIBezierPath();

            bezierPath.MoveTo(bottomLeftPoint);
            bezierPath.AddLineTo(topLeftPoint);
            bezierPath.AddQuadCurveToPoint(topRightPoint, topMidPoint);
            bezierPath.AddLineTo(bottomRightPoint);
            return(bezierPath.CGPath);
        }
Ejemplo n.º 14
0
        public override void Draw(CGRect rect)
        {
            var boxView = (RoundedStackLayout)Element;

            double sourceWidth  = rect.Size.Width;
            double sourceHeight = rect.Size.Height;

            double desiredWidth  = sourceWidth;
            double desiredHeight = sourceHeight;

            var topLeftCornerSize     = boxView.CornerRadius;
            var topRightCornerSize    = boxView.CornerRadius;
            var bottomLeftCornerSize  = boxView.CornerRadius;
            var bottomRightCornerSize = boxView.CornerRadius;

            using (CGContext context = UIGraphics.GetCurrentContext())
            {
                context.BeginPath();

                using (var path = new UIBezierPath())
                {
                    // TopLeft
                    if (boxView.CornersAttributes.HasFlag(CornerAttributes.TopLeftRounded))
                    {
                        path.MoveTo(new CGPoint(0, topLeftCornerSize));
                        path.AddQuadCurveToPoint(new CGPoint(topLeftCornerSize, 0), new CGPoint(0, 0));
                    }
                    else
                    {
                        path.MoveTo(new CGPoint(0, 0));
                    }

                    // TopRight
                    if (boxView.CornersAttributes.HasFlag(CornerAttributes.TopRightRounded))
                    {
                        path.AddLineTo(new CGPoint(desiredWidth - topRightCornerSize, 0));
                        path.AddQuadCurveToPoint(new CGPoint(desiredWidth, topRightCornerSize), new CGPoint(desiredWidth, 0));
                    }
                    else
                    {
                        path.AddLineTo(new CGPoint(desiredWidth, 0));
                    }

                    // BottomRight
                    if (boxView.CornersAttributes.HasFlag(CornerAttributes.BottomRightRounded))
                    {
                        path.AddLineTo(new CGPoint(desiredWidth, desiredHeight - bottomRightCornerSize));
                        path.AddQuadCurveToPoint(new CGPoint(desiredWidth - bottomRightCornerSize, desiredHeight), new CGPoint(desiredWidth, desiredHeight));
                    }
                    else
                    {
                        path.AddLineTo(new CGPoint(desiredWidth, desiredHeight));
                    }

                    // BottomLeft
                    if (boxView.CornersAttributes.HasFlag(CornerAttributes.BottomLeftRounded))
                    {
                        path.AddLineTo(new CGPoint(bottomLeftCornerSize, desiredHeight));
                        path.AddQuadCurveToPoint(new CGPoint(0, desiredHeight - bottomLeftCornerSize), new CGPoint(0, desiredHeight));
                    }
                    else
                    {
                        path.AddLineTo(new CGPoint(0, desiredHeight));
                    }

                    boxView.BackgroundColor.ToUIColor().SetFill();
                    path.Fill();

                    path.ClosePath();
                    context.AddPath(path.CGPath);
                    context.Clip();
                }
            }
        }
Ejemplo n.º 15
0
        public static UIImage ToTransformedCorners(UIImage source, double topLeftCornerSize, double topRightCornerSize, double bottomLeftCornerSize, double bottomRightCornerSize,
                                                   CornerTransformType cornersTransformType, double cropWidthRatio, double cropHeightRatio)
        {
            double sourceWidth  = source.Size.Width;
            double sourceHeight = source.Size.Height;

            double desiredWidth  = sourceWidth;
            double desiredHeight = sourceHeight;

            double desiredRatio = cropWidthRatio / cropHeightRatio;
            double currentRatio = sourceWidth / sourceHeight;

            if (currentRatio > desiredRatio)
            {
                desiredWidth = (cropWidthRatio * sourceHeight / cropHeightRatio);
            }
            else if (currentRatio < desiredRatio)
            {
                desiredHeight = (cropHeightRatio * sourceWidth / cropWidthRatio);
            }

            topLeftCornerSize     = topLeftCornerSize * (desiredWidth + desiredHeight) / 2 / 100;
            topRightCornerSize    = topRightCornerSize * (desiredWidth + desiredHeight) / 2 / 100;
            bottomLeftCornerSize  = bottomLeftCornerSize * (desiredWidth + desiredHeight) / 2 / 100;
            bottomRightCornerSize = bottomRightCornerSize * (desiredWidth + desiredHeight) / 2 / 100;

            float cropX = (float)((sourceWidth - desiredWidth) / 2);
            float cropY = (float)((sourceHeight - desiredHeight) / 2);

            UIGraphics.BeginImageContextWithOptions(new CGSize(desiredWidth, desiredHeight), false, (nfloat)0.0);

            try
            {
                using (var context = UIGraphics.GetCurrentContext())
                {
                    context.BeginPath();

                    using (var path = new UIBezierPath())
                    {
                        // TopLeft
                        if (cornersTransformType.HasFlag(CornerTransformType.TopLeftCut))
                        {
                            path.MoveTo(new CGPoint(0, topLeftCornerSize));
                            path.AddLineTo(new CGPoint(topLeftCornerSize, 0));
                        }
                        else if (cornersTransformType.HasFlag(CornerTransformType.TopLeftRounded))
                        {
                            path.MoveTo(new CGPoint(0, topLeftCornerSize));
                            path.AddQuadCurveToPoint(new CGPoint(topLeftCornerSize, 0), new CGPoint(0, 0));
                        }
                        else
                        {
                            path.MoveTo(new CGPoint(0, 0));
                        }

                        // TopRight
                        if (cornersTransformType.HasFlag(CornerTransformType.TopRightCut))
                        {
                            path.AddLineTo(new CGPoint(desiredWidth - topRightCornerSize, 0));
                            path.AddLineTo(new CGPoint(desiredWidth, topRightCornerSize));
                        }
                        else if (cornersTransformType.HasFlag(CornerTransformType.TopRightRounded))
                        {
                            path.AddLineTo(new CGPoint(desiredWidth - topRightCornerSize, 0));
                            path.AddQuadCurveToPoint(new CGPoint(desiredWidth, topRightCornerSize), new CGPoint(desiredWidth, 0));
                        }
                        else
                        {
                            path.AddLineTo(new CGPoint(desiredWidth, 0));
                        }

                        // BottomRight
                        if (cornersTransformType.HasFlag(CornerTransformType.BottomRightCut))
                        {
                            path.AddLineTo(new CGPoint(desiredWidth, desiredHeight - bottomRightCornerSize));
                            path.AddLineTo(new CGPoint(desiredWidth - bottomRightCornerSize, desiredHeight));
                        }
                        else if (cornersTransformType.HasFlag(CornerTransformType.BottomRightRounded))
                        {
                            path.AddLineTo(new CGPoint(desiredWidth, desiredHeight - bottomRightCornerSize));
                            path.AddQuadCurveToPoint(new CGPoint(desiredWidth - bottomRightCornerSize, desiredHeight), new CGPoint(desiredWidth, desiredHeight));
                        }
                        else
                        {
                            path.AddLineTo(new CGPoint(desiredWidth, desiredHeight));
                        }

                        // BottomLeft
                        if (cornersTransformType.HasFlag(CornerTransformType.BottomLeftCut))
                        {
                            path.AddLineTo(new CGPoint(bottomLeftCornerSize, desiredHeight));
                            path.AddLineTo(new CGPoint(0, desiredHeight - bottomLeftCornerSize));
                        }
                        else if (cornersTransformType.HasFlag(CornerTransformType.BottomLeftRounded))
                        {
                            path.AddLineTo(new CGPoint(bottomLeftCornerSize, desiredHeight));
                            path.AddQuadCurveToPoint(new CGPoint(0, desiredHeight - bottomLeftCornerSize), new CGPoint(0, desiredHeight));
                        }
                        else
                        {
                            path.AddLineTo(new CGPoint(0, desiredHeight));
                        }

                        path.ClosePath();
                        context.AddPath(path.CGPath);
                        context.Clip();
                    }

                    var drawRect = new CGRect(-cropX, -cropY, sourceWidth, sourceHeight);
                    source.Draw(drawRect);
                    var modifiedImage = UIGraphics.GetImageFromCurrentImageContext();

                    return(modifiedImage);
                }
            }
            finally
            {
                UIGraphics.EndImageContext();
            }
        }
        public override void CreatePath(Arc shape, CGRect bounds)
        {
            using (var path = new UIBezierPath())
            {
                var arcHeightAbs = Math.Abs(shape.ArcHeight);

                switch (shape.Position)
                {
                case ShapePosition.Left:
                    if (shape.IsCropInside)
                    {
                        path.MoveTo(new CGPoint(bounds.Width, 0));
                        path.AddLineTo(new CGPoint(0, 0));
                        path.AddQuadCurveToPoint(new CGPoint(0, bounds.Height), new CGPoint(arcHeightAbs * 2, bounds.Height / 2));
                        path.AddLineTo(new CGPoint(bounds.Width, bounds.Height));
                        path.ClosePath();
                    }
                    else
                    {
                        path.MoveTo(new CGPoint(bounds.Width, 0));
                        path.AddLineTo(new CGPoint(arcHeightAbs, 0));
                        path.AddQuadCurveToPoint(new CGPoint(arcHeightAbs, bounds.Height), new CGPoint(-arcHeightAbs, bounds.Height / 2));
                        path.AddLineTo(new CGPoint(bounds.Width, bounds.Height));
                        path.ClosePath();
                    }
                    break;

                case ShapePosition.Top:
                    if (shape.IsCropInside)
                    {
                        path.MoveTo(new CGPoint(0, bounds.Height));
                        path.AddLineTo(new CGPoint(0, 0));
                        path.AddQuadCurveToPoint(new CGPoint(bounds.Width, 0), new CGPoint(bounds.Width / 2, 2 * arcHeightAbs));
                        path.AddLineTo(new CGPoint(bounds.Width, bounds.Height));
                        path.ClosePath();
                    }
                    else
                    {
                        path.MoveTo(new CGPoint(0, arcHeightAbs));
                        path.AddQuadCurveToPoint(new CGPoint(bounds.Width, arcHeightAbs), new CGPoint(bounds.Width / 2, -arcHeightAbs));
                        path.AddLineTo(new CGPoint(bounds.Width, bounds.Height));
                        path.AddLineTo(new CGPoint(0, bounds.Height));
                        path.ClosePath();
                    }
                    break;

                case ShapePosition.Right:
                    if (shape.IsCropInside)
                    {
                        path.MoveTo(new CGPoint(0, 0));
                        path.AddLineTo(new CGPoint(bounds.Width, 0));
                        path.AddQuadCurveToPoint(new CGPoint(bounds.Width, bounds.Height), new CGPoint(bounds.Width - arcHeightAbs * 2, bounds.Height / 2));
                        path.AddLineTo(new CGPoint(0, bounds.Height));
                        path.ClosePath();
                    }
                    else
                    {
                        path.MoveTo(new CGPoint(0, 0));
                        path.AddLineTo(new CGPoint(bounds.Width - arcHeightAbs, 0));
                        path.AddQuadCurveToPoint(new CGPoint(bounds.Width - arcHeightAbs, bounds.Height), new CGPoint(bounds.Width + arcHeightAbs, bounds.Height / 2));
                        path.AddLineTo(new CGPoint(0, bounds.Height));
                        path.ClosePath();
                    }
                    break;

                case ShapePosition.Bottom:
                    if (shape.IsCropInside)
                    {
                        path.MoveTo(new CGPoint(0, 0));
                        path.AddLineTo(new CGPoint(0, bounds.Height));
                        path.AddQuadCurveToPoint(new CGPoint(bounds.Width, bounds.Height), new CGPoint(bounds.Width / 2, bounds.Height - 2 * arcHeightAbs));
                        path.AddLineTo(new CGPoint(bounds.Width, 0));
                        path.ClosePath();
                    }
                    else
                    {
                        path.MoveTo(new CGPoint(0, 0));
                        path.AddLineTo(new CGPoint(0, bounds.Height - arcHeightAbs));
                        path.AddQuadCurveToPoint(new CGPoint(bounds.Width, bounds.Height - arcHeightAbs), new CGPoint(bounds.Width / 2, bounds.Height + arcHeightAbs));
                        path.AddLineTo(new CGPoint(bounds.Width, 0));
                        path.ClosePath();
                    }
                    break;
                }

                Path = path.CGPath;
            }
        }