예제 #1
0
        public static NSBezierPath CreatePolygonPath(this CGRect rect, int sides, double cornerRadius = 0.0, double rotationOffset = 0.0)
        {
            var offsetRadians = rotationOffset * Math.PI / 180;
            var path          = new NSBezierPath();
            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);
        }
예제 #2
0
        CGPath?GetRoundedPath(CGRect rect, nfloat left, nfloat top, nfloat right, nfloat bottom)
        {
#if __IOS__
            var path = new UIBezierPath();
#else
            var path = new NSBezierPath();
#endif
            path.MoveTo(new CGPoint(rect.Width - right, rect.Y));

            path.AddArc(new CGPoint((float)rect.X + rect.Width - right, (float)rect.Y + right), (nfloat)right, (float)(Math.PI * 1.5), (float)Math.PI * 2, true);
            path.AddLineTo(new CGPoint(rect.Width, rect.Height - bottom));

            path.AddArc(new CGPoint((float)rect.X + rect.Width - bottom, (float)rect.Y + rect.Height - bottom), (nfloat)bottom, 0, (float)(Math.PI * .5), true);
            path.AddLineTo(new CGPoint(left, rect.Height));

            path.AddArc(new CGPoint((float)rect.X + left, (float)rect.Y + rect.Height - left), (nfloat)left, (float)(Math.PI * .5), (float)Math.PI, true);
            path.AddLineTo(new CGPoint(rect.X, top));

            path.AddArc(new CGPoint((float)rect.X + top, (float)rect.Y + top), (nfloat)top, (float)Math.PI, (float)(Math.PI * 1.5), true);

            path.ClosePath();

#if __IOS__
            return(path.CGPath);
#else
            return(path.ToCGPath());
#endif
        }
예제 #3
0
        public override void DrawRow(nint row, CGRect clipRect)
        {
            if (row >= RowCount)
            {
                return;
            }

            base.DrawRow(row, clipRect);

            NSGraphicsContext.GlobalSaveGraphicsState();
            NSGraphicsContext.CurrentContext.ShouldAntialias = false;

            CGRect rectRow    = RectForRow(row);
            CGRect rectColumn = RectForColumn(0);
            CGRect rect       = Frame;

            CGPoint start = new CGPoint(rectColumn.Left, rectRow.Top);
            CGPoint end   = new CGPoint(rectRow.Right, rectRow.Top);

            var linePath = new NSBezierPath();

            GridColor.Set();
            linePath.MoveTo(start);
            linePath.LineTo(end);
            linePath.ClosePath();
            linePath.Stroke();

            NSGraphicsContext.GlobalRestoreGraphicsState();
        }
예제 #4
0
        public override void DrawRect(RectangleF rect)
        {
            var xamarinBlue = NSColor.FromDeviceRgba(0.071f, 0.463f, 0.725f, 1.000f);

            NSBezierPath xamarinLogoPath = new NSBezierPath();

            xamarinLogoPath.MoveTo(new PointF(230.49f, 92.68f));
            xamarinLogoPath.LineTo(new PointF(200.74f, 92.68f));
            xamarinLogoPath.LineTo(new PointF(159.7f, 167.71f));
            xamarinLogoPath.LineTo(new PointF(200.74f, 242.73f));
            xamarinLogoPath.LineTo(new PointF(230.49f, 242.73f));
            xamarinLogoPath.LineTo(new PointF(191.23f, 167.71f));
            xamarinLogoPath.LineTo(new PointF(230.49f, 92.68f));
            xamarinLogoPath.ClosePath();
            xamarinLogoPath.MoveTo(new PointF(118.66f, 92.68f));
            xamarinLogoPath.LineTo(new PointF(88.92f, 92.68f));
            xamarinLogoPath.LineTo(new PointF(128.18f, 167.71f));
            xamarinLogoPath.LineTo(new PointF(88.92f, 242.73f));
            xamarinLogoPath.LineTo(new PointF(118.66f, 242.73f));
            xamarinLogoPath.LineTo(new PointF(159.7f, 167.71f));
            xamarinLogoPath.LineTo(new PointF(118.66f, 92.68f));
            xamarinLogoPath.ClosePath();
            xamarinLogoPath.MoveTo(new PointF(220.7f, 37.0f));
            xamarinLogoPath.CurveTo(new PointF(232.55f, 41.1f), new PointF(220.7f, 37.0f), new PointF(227.07f, 38.03f));
            xamarinLogoPath.CurveTo(new PointF(242.62f, 49.31f), new PointF(238.03f, 44.18f), new PointF(242.62f, 49.31f));
            xamarinLogoPath.LineTo(new PointF(304.22f, 152.47f));
            xamarinLogoPath.CurveTo(new PointF(308.95f, 170.05f), new PointF(304.22f, 152.47f), new PointF(309.55f, 163.02f));
            xamarinLogoPath.CurveTo(new PointF(304.22f, 183.53f), new PointF(308.36f, 177.09f), new PointF(304.22f, 183.53f));
            xamarinLogoPath.LineTo(new PointF(243.57f, 286.11f));
            xamarinLogoPath.CurveTo(new PointF(234.05f, 294.31f), new PointF(243.57f, 286.11f), new PointF(239.7f, 291.09f));
            xamarinLogoPath.CurveTo(new PointF(220.97f, 299.0f), new PointF(228.4f, 297.53f), new PointF(220.97f, 299.0f));
            xamarinLogoPath.LineTo(new PointF(97.25f, 299.0f));
            xamarinLogoPath.CurveTo(new PointF(84.16f, 294.31f), new PointF(97.25f, 299.0f), new PointF(89.51f, 297.53f));
            xamarinLogoPath.CurveTo(new PointF(75.83f, 286.11f), new PointF(78.81f, 291.09f), new PointF(75.83f, 286.11f));
            xamarinLogoPath.LineTo(new PointF(13.99f, 181.77f));
            xamarinLogoPath.CurveTo(new PointF(11.03f, 170.05f), new PointF(13.99f, 181.77f), new PointF(11.33f, 176.21f));
            xamarinLogoPath.CurveTo(new PointF(12.81f, 157.16f), new PointF(10.73f, 163.9f), new PointF(12.81f, 157.16f));
            xamarinLogoPath.LineTo(new PointF(75.59f, 49.31f));
            xamarinLogoPath.CurveTo(new PointF(85.07f, 41.1f), new PointF(75.59f, 49.31f), new PointF(79.59f, 44.18f));
            xamarinLogoPath.CurveTo(new PointF(97.5f, 37.0f), new PointF(90.54f, 38.03f), new PointF(97.5f, 37.0f));
            xamarinLogoPath.LineTo(new PointF(220.7f, 37.0f));
            xamarinLogoPath.LineTo(new PointF(220.7f, 37.0f));
            xamarinLogoPath.ClosePath();
            xamarinBlue.SetFill();
            xamarinLogoPath.Fill();
        }
예제 #5
0
        //

        void DrawBottomLine()
        {
            var linePath = new NSBezierPath();

            Utility.ColorWithHexColorValue(BookInfo.FontColor, 1.0f).SetStroke();

            linePath.LineWidth = 2;
            linePath.MoveTo(bottomLineTS);
            linePath.LineTo(bottomLineTE);
            linePath.ClosePath();

            linePath.Stroke();

            //var lineTPath = new NSBezierPath ();
            linePath.MoveTo(bottomLineBS);
            linePath.LineTo(bottomLineBE);
            linePath.ClosePath();
            linePath.Stroke();
        }
예제 #6
0
        private void DrawArrow(NSScrollerPart aScrollPart)
        {
            NSRect rect = RectForPart(aScrollPart);

            // draw background
            NSColor.BlackColor.Set();
            AppKitFramework.NSRectFill(rect);

            // draw button background
            if (aScrollPart == HitPart)
            {
                NSColor.WhiteColor.Set();
            }
            else
            {
                NSColor.ColorWithCalibratedWhiteAlpha(0.1f, 1.0f).Set();
            }

            NSBezierPath path = new NSBezierPath();

            path.AppendBezierPathWithRoundedRectXRadiusYRadius(rect.InsetRect(1.0f, 1.0f), 2.0f, 2.0f);
            path.LineWidth = 2.0f;
            path.Stroke();
            path.Release();

            // draw arrow
            NSColor.WhiteColor.Set();

            float arrowSize = 6.0f;

            NSRect arrowRect = new NSRect(rect.MidX - (arrowSize * 0.5f),
                                          rect.MidY - (arrowSize * 0.5f),
                                          arrowSize,
                                          arrowSize);

            path = new NSBezierPath();
            if (aScrollPart == NSScrollerPart.NSScrollerDecrementLine)
            {
                path.MoveToPoint(new NSPoint(arrowRect.MinX, arrowRect.MaxY));
                path.LineToPoint(new NSPoint(arrowRect.MaxX, arrowRect.MaxY));
                path.LineToPoint(new NSPoint(arrowRect.MidX, arrowRect.MinY));
                path.LineToPoint(new NSPoint(arrowRect.MinX, arrowRect.MaxY));
            }
            else
            {
                path.MoveToPoint(new NSPoint(arrowRect.MinX, arrowRect.MinY));
                path.LineToPoint(new NSPoint(arrowRect.MaxX, arrowRect.MinY));
                path.LineToPoint(new NSPoint(arrowRect.MidX, arrowRect.MaxY));
                path.LineToPoint(new NSPoint(arrowRect.MinX, arrowRect.MinY));
            }
            path.ClosePath();
            path.Fill();
            path.Release();
        }
예제 #7
0
        public void CreateRandomPath()
        {
            CGPoint p = RandomPoint();

            mPath.MoveTo(p);

            for (nint i = 0; i < 25; i++)
            {
                p = RandomPoint();
                mPath.LineTo(p);
            }
            mPath.ClosePath();
        }
예제 #8
0
        public override void DrawRect(NSRect aRect)
        {
            float left   = Bounds.MinX + iPadding;
            float right  = Bounds.MaxX - iPadding;
            float top    = Bounds.MaxY - iPadding - iAnchorHeight;
            float bottom = Bounds.MinY + iPadding + iAnchorHeight;

            NSBezierPath path = new NSBezierPath();

            // start the path in the bottom left corner, just past the arc of the corner and go clockwise
            path.MoveToPoint(new NSPoint(left, bottom + iCornerRadius));
            path.LineToPoint(new NSPoint(left, top - iCornerRadius));
            path.AppendBezierPathWithArcFromPointToPointRadius(new NSPoint(left, top),
                                                               new NSPoint(left + iCornerRadius, top),
                                                               iCornerRadius);
            if (iAnchorOnTop)
            {
                path.LineToPoint(new NSPoint(iAnchorApex - iAnchorWidth * 0.5f, top));
                path.LineToPoint(new NSPoint(iAnchorApex, top + iAnchorHeight));
                path.LineToPoint(new NSPoint(iAnchorApex + iAnchorWidth * 0.5f, top));
            }
            path.LineToPoint(new NSPoint(right - iCornerRadius, top));
            path.AppendBezierPathWithArcFromPointToPointRadius(new NSPoint(right, top),
                                                               new NSPoint(right, top - iCornerRadius),
                                                               iCornerRadius);
            path.LineToPoint(new NSPoint(right, bottom + iCornerRadius));
            path.AppendBezierPathWithArcFromPointToPointRadius(new NSPoint(right, bottom),
                                                               new NSPoint(right - iCornerRadius, bottom),
                                                               iCornerRadius);
            if (!iAnchorOnTop)
            {
                path.LineToPoint(new NSPoint(iAnchorApex + iAnchorWidth * 0.5f, bottom));
                path.LineToPoint(new NSPoint(iAnchorApex, bottom - iAnchorHeight));
                path.LineToPoint(new NSPoint(iAnchorApex - iAnchorWidth * 0.5f, bottom));
            }
            path.LineToPoint(new NSPoint(left + iCornerRadius, bottom));
            path.AppendBezierPathWithArcFromPointToPointRadius(new NSPoint(left, bottom),
                                                               new NSPoint(left, bottom + iCornerRadius),
                                                               iCornerRadius);
            path.ClosePath();

            NSColor.WhiteColor.SetStroke();
            path.LineWidth = 4.0f;
            path.Stroke();

            NSColor.ColorWithCalibratedWhiteAlpha(0.0f, 0.9f).SetFill();
            path.Fill();

            path.Release();
        }
예제 #9
0
        public static NSBezierPath CreateRoundedRectPath(this CGRect rect, CornerRadius cornerRadius)
        {
            var path = new NSBezierPath();

            path.MoveTo(new CGPoint(rect.Width - cornerRadius.TopRight, rect.Y));
            path.AddArc(new CGPoint((float)rect.X + rect.Width - cornerRadius.TopRight, (float)rect.Y + cornerRadius.TopRight), (nfloat)cornerRadius.TopRight, (float)(Math.PI * 1.5), (float)Math.PI * 2, true);
            path.AddLineTo(new CGPoint(rect.Width, rect.Height - cornerRadius.BottomRight));
            path.AddArc(new CGPoint((float)rect.X + rect.Width - cornerRadius.BottomRight, (float)rect.Y + rect.Height - cornerRadius.BottomRight), (nfloat)cornerRadius.BottomRight, 0, (float)(Math.PI * .5), true);
            path.AddLineTo(new CGPoint(cornerRadius.BottomLeft, rect.Height));
            path.AddArc(new CGPoint((float)rect.X + cornerRadius.BottomLeft, (float)rect.Y + rect.Height - cornerRadius.BottomLeft), (nfloat)cornerRadius.BottomLeft, (float)(Math.PI * .5), (float)Math.PI, true);
            path.AddLineTo(new CGPoint(rect.X, cornerRadius.TopLeft));
            path.AddArc(new CGPoint((float)rect.X + cornerRadius.TopLeft, (float)rect.Y + cornerRadius.TopLeft), (nfloat)cornerRadius.TopLeft, (float)Math.PI, (float)(Math.PI * 1.5), true);

            path.ClosePath();

            return(path);
        }
예제 #10
0
        public override void DrawRect(RectangleF dirtyRect)
        {
            int radius = 5, arrowHeight = 10, arrowWidth = 20;
            var roundedRectangleRect = new RectangleF(0, 0, this.Bounds.Width, this.Bounds.Height - arrowHeight);
            var path = new NSBezierPath();

            path.AppendPathWithRoundedRect(roundedRectangleRect, radius, radius);

            // Draw the triangle
            path.MoveTo(new PointF((this.Bounds.Width / 2) - (arrowWidth / 2), this.Bounds.Height - arrowHeight));
            path.LineTo(new PointF((this.Bounds.Width / 2), this.Bounds.Height));
            path.LineTo(new PointF((this.Bounds.Width / 2) + (arrowWidth / 2), this.Bounds.Height - arrowHeight));
            path.ClosePath();

            NSColor.Control.SetFill();
            path.Fill();
        }
예제 #11
0
        public static NSBezierPath SCArrowBezierPath(CGSize baseSize, CGSize tipSize, float hollow, bool twoSides)
        {
            var arrow = new NSBezierPath();

            var h = new nfloat[5];
            var w = new nfloat[4];

            w [0] = 0;
            w [1] = baseSize.Width - tipSize.Width - hollow;
            w [2] = baseSize.Width - tipSize.Width;
            w [3] = baseSize.Width;

            h [0] = 0;
            h [1] = (tipSize.Height - baseSize.Height) * 0.5f;
            h [2] = (tipSize.Height) * 0.5f;
            h [3] = (tipSize.Height + baseSize.Height) * 0.5f;
            h [4] = tipSize.Height;

            if (twoSides)
            {
                arrow.MoveTo(new CGPoint(tipSize.Width, h [1]));
                arrow.LineTo(new CGPoint(tipSize.Width + hollow, h [0]));
                arrow.LineTo(new CGPoint(0, h [2]));
                arrow.LineTo(new CGPoint(tipSize.Width + hollow, h [4]));
                arrow.LineTo(new CGPoint(tipSize.Width, h [3]));
            }
            else
            {
                arrow.MoveTo(new CGPoint(0, h [1]));
                arrow.LineTo(new CGPoint(0, h [3]));
            }

            arrow.LineTo(new CGPoint(w [2], h [3]));
            arrow.LineTo(new CGPoint(w [1], h [4]));
            arrow.LineTo(new CGPoint(w [3], h [2]));
            arrow.LineTo(new CGPoint(w [1], h [0]));
            arrow.LineTo(new CGPoint(w [2], h [1]));

            arrow.ClosePath();

            return(arrow);
        }
예제 #12
0
            public void Set(Polygon poly, ref Style style)
            {
                if (this.poly != poly)
                {
                    //Console.WriteLine ($"({this.sx} == {sx} && {this.sy} == {sy} && {this.ex} == {ex} && {this.ey == ey})");
                    this.poly = poly;

                    //Console.WriteLine (style.Transform);
                    var ps = poly.Points;
                    var n  = ps.Count;
                    if (n > 1)
                    {
                        var path = new NSBezierPath();
                        path.MoveTo(new CGPoint(ps[0].X, ps[0].Y));
                        for (var i = 1; i < n; i++)
                        {
                            path.LineTo(new CGPoint(ps[i].X, ps[i].Y));
                        }
                        path.ClosePath();
                        var g = SCNShape.Create(path, 1);
                        g.FirstMaterial = GetNativeMaterial(style.Color);
                        Geometry        = g;
                    }
                    else
                    {
                        Geometry = null;
                    }

                    Transform =
                        style.Transform
                    ;
                }
                if (ColorChanged(ref style))
                {
                    this.style.Color = style.Color;
                    var g = Geometry;
                    if (g is object)
                    {
                        g.FirstMaterial = GetNativeMaterial(style.Color);
                    }
                }
            }
예제 #13
0
		public static NSBezierPath SCArrowBezierPath (CGSize baseSize, CGSize tipSize, nfloat hollow, bool twoSides)
		{
			var arrow = new NSBezierPath ();

			var h = new nfloat[5];
			var w = new nfloat[4];

			w [0] = 0;
			w [1] = baseSize.Width - tipSize.Width - hollow;
			w [2] = baseSize.Width - tipSize.Width;
			w [3] = baseSize.Width;

			h [0] = 0;
			h [1] = (tipSize.Height - baseSize.Height) * 0.5f;
			h [2] = (tipSize.Height) * 0.5f;
			h [3] = (tipSize.Height + baseSize.Height) * 0.5f;
			h [4] = tipSize.Height;

			if (twoSides) {
				arrow.MoveTo (new CGPoint (tipSize.Width, h [1]));
				arrow.LineTo (new CGPoint (tipSize.Width + hollow, h [0]));
				arrow.LineTo (new CGPoint (0, h [2]));
				arrow.LineTo (new CGPoint (tipSize.Width + hollow, h [4]));
				arrow.LineTo (new CGPoint (tipSize.Width, h [3]));
			} else {
				arrow.MoveTo (new CGPoint (0, h [1]));
				arrow.LineTo (new CGPoint (0, h [3]));
			}

			arrow.LineTo (new CGPoint (w [2], h [3]));
			arrow.LineTo (new CGPoint (w [1], h [4]));
			arrow.LineTo (new CGPoint (w [3], h [2]));
			arrow.LineTo (new CGPoint (w [1], h [0]));
			arrow.LineTo (new CGPoint (w [2], h [1]));

			arrow.ClosePath ();

			return arrow;
		}
        public override void DrawRect(RectangleF dirtyRect)
        {
            var contentRect = new RectangleF(Bounds.X + LineThickness, Bounds.Y + LineThickness, Bounds.Width - (LineThickness * 2), Bounds.Height - (LineThickness * 2));

            // Mac coords are reversed vs. .Net / MonoTouch coords, so we just reverse the top/bottom coords to compensate
            var top    = contentRect.Bottom;
            var bottom = contentRect.Top;

            var left  = contentRect.Left;
            var right = contentRect.Right;
            var path  = new NSBezierPath();

            // Draw the 'arrow' at the top
            path.MoveTo(new PointF(ArrowX, top));
            path.LineTo(new PointF(ArrowX + ArrowWidth / 2, top - ArrowHeight));
            path.LineTo(new PointF(right - CornerRadius, top - ArrowHeight));

            // Right right
            var topRightCorner = new PointF(right, top - ArrowHeight);

            path.CurveTo(new PointF(right, top - ArrowHeight - CornerRadius), topRightCorner, topRightCorner);

            // Right line
            path.LineTo(new PointF(right, bottom + CornerRadius));

            // Bottom right
            var bottomRightCorner = new PointF(right, bottom);

            path.CurveTo(new PointF(right - CornerRadius, bottom), bottomRightCorner, bottomRightCorner);

            // Bottom line
            path.LineTo(new PointF(left + CornerRadius, bottom));

            // Bottom left
            var bottomLeftCorner = new PointF(left, bottom);

            path.CurveTo(new PointF(left, bottom + CornerRadius), bottomLeftCorner, bottomLeftCorner);

            // Left line
            path.LineTo(new PointF(left, top - ArrowHeight - CornerRadius));

            // Top left
            var topLeftCorner = new PointF(left, top - ArrowHeight);

            path.CurveTo(new PointF(left + CornerRadius, top - ArrowHeight), topLeftCorner, topLeftCorner);

            // Line up to start of 'arrow' & finish
            path.LineTo(new PointF(ArrowX - ArrowWidth / 2, top - ArrowHeight));
            path.ClosePath();

            // Fill the path with a semi-transparent white
            NSColor.FromDeviceWhite(1.0f, FillOpacity).SetFill();
            path.Fill();

            NSGraphicsContext.GlobalSaveGraphicsState();

            // Clip all rendering of controls within view to within the path outline we specified earlier
            var clip = NSBezierPath.FromRect(Bounds);

            clip.AppendPath(path);
            clip.AddClip();

            // Draw the border
            path.LineWidth = LineThickness * 2;
            NSColor.White.SetStroke();
            path.Stroke();

            NSGraphicsContext.GlobalRestoreGraphicsState();
        }
예제 #15
0
 public virtual void ClosePath()
 {
     path.ClosePath();
 }
        public static NSImage ToTransformedCorners(NSImage source, double topLeftCornerSize, double topRightCornerSize, double bottomLeftCornerSize, double bottomRightCornerSize,
                                                   CornerTransformType cornersTransformType, double cropWidthRatio, double cropHeightRatio)
        {
            double sourceWidth  = source.CGImage.Width;
            double sourceHeight = source.CGImage.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);

            var       colorSpace       = CGColorSpace.CreateDeviceRGB();
            const int bytesPerPixel    = 4;
            int       width            = (int)desiredWidth;
            int       height           = (int)desiredHeight;
            var       bytes            = new byte[width * height * bytesPerPixel];
            int       bytesPerRow      = bytesPerPixel * width;
            const int bitsPerComponent = 8;

            using (var context = new CGBitmapContext(bytes, width, height, bitsPerComponent, bytesPerRow, colorSpace, CGBitmapFlags.PremultipliedLast | CGBitmapFlags.ByteOrder32Big))
            {
                context.BeginPath();

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

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

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

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

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

                var drawRect = new CGRect(-cropX, -cropY, sourceWidth, sourceHeight);
                context.DrawImage(drawRect, source.CGImage);


                using (var output = context.ToImage())
                {
                    return(new NSImage(output, CGSize.Empty));
                }
            }
        }