Esempio n. 1
0
        private void AddSeperator(CGContext g, RectangleF frame, MoodDataSet mood)
        {
            var color      = new CGColor(255, 255, 255);
            var dataPoints = GetPointsForSpline(mood.DataPoints, frame);

            var     first = dataPoints.First();
            CGLayer layer = CGLayer.Create(g, new SizeF(frame.Width, frame.Height));

            layer.Context.SetStrokeColor(color);
            layer.Context.SetLineWidth(5f);
            layer.Context.MoveTo(first.X, first.Y);

            if (endsPrematurely)
            {
                dataPoints.RemoveAt(dataPoints.Count() - 1);
            }


            if (this.SmoothLines && dataPoints.Count() >= minDataPointsRequiredForSpline)
            {
                layer.Context.AddSpline(dataPoints.ToArray(), this.Tension);
                var last = dataPoints.Last();
                layer.Context.AddLineToPoint(last.X, last.Y);
            }
            else
            {
                layer.Context.AddLines(dataPoints.ToArray());
            }

            layer.Context.DrawPath(CGPathDrawingMode.Stroke);
            g.DrawLayer(layer, new PointF(0, 0));
        }
Esempio n. 2
0
        //========================================================================

        #endregion
        //========================================================================

        /// <summary>
        /// rect changes depending on if the whole view is being redrawn, or just a section
        /// </summary>
        /// <param name="rect">
        /// A <see cref="RectangleF"/>
        /// </param>
        public override void Draw(RectangleF rect)
        {
            Console.WriteLine("Draw() Called");
            base.Draw(rect);

            using (CGContext context = UIGraphics.GetCurrentContext())
            {
                CGAffineTransform affineTransform = context.GetCTM();
                //affineTransform.Scale (1, -1);
                affineTransform.Translate(1, -1);
                context.ConcatCTM(affineTransform);

                //---- fill the background with white
                // set fill color
                UIColor.White.SetFill();
                //context.SetRGBFillColor (1, 1, 1, 1f);
                // paint
                context.FillRect(rect);

                PointF[] myStarPoints = { new PointF(5f,                 5f)
                                          ,                 new PointF(10f,   15f), new PointF(10f, 15f)
                                          ,                 new PointF(15f,    5f), new PointF(15f, 5f)
                                          ,                 new PointF(12f,    5f), new PointF(15f, 5f)
                                          ,                 new PointF(2.5f,  11f), new PointF(2.5f, 11f)
                                          ,                 new PointF(16.5f, 11f),
                                          new PointF(16.5f,                 11f)
                                          ,                 new PointF(5f, 5f) };

                //---- create the layer
                using (CGLayer starLayer = CGLayer.Create(context, rect.Size))
                {
                    //---- set fill to blue
                    starLayer.Context.SetRGBFillColor(0f, 0f, 1f, 1f);
                    starLayer.Context.AddLines(myStarPoints);
                    starLayer.Context.FillPath();

                    //---- draw the layer onto our screen
                    float starYPos = 5;
                    float starXPos = 5;

                    for (int row = 0; row < 50; row++)
                    {
                        //---- reset the x position for each row
                        starXPos = 5;
                        //----
                        for (int col = 0; col < 30; col++)
                        {
                            context.DrawLayer(starLayer, new PointF(starXPos, starYPos));
                            starXPos += 20;
                        }
                        starYPos += 20;
                    }
                }
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Draws an image on the target.
        /// </summary>
        /// <param name="target"></param>
        /// <param name="left"></param>
        /// <param name="top"></param>
        /// <param name="right"></param>
        /// <param name="bottom"></param>
        /// <param name="imageData"></param>
        /// <returns>The image.</returns>
        /// <param name="tag">Tag.</param>
        protected override object DrawImage(Target2DWrapper <CGContextWrapper> target, double left, double top, double right,
                                            double bottom, byte[] imageData, object tag)
        {
            CGImage image = null;
            CGLayer layer = null;

            if (tag != null && tag is CGImage)
            {
                image = (tag as CGImage);
            }
            else if (tag != null && tag is CGLayer)
            {
                layer = (tag as CGLayer);
            }
            else
            {
                // TODO: figurate out how to use this horroble IOS api to instantiate an image from a bytearray.
                //CGImage image = CGImage.FromPNG(
            }

            if (image != null)
            { // there is an image. draw it!
                double[] topleft      = this.Tranform(left, top);
                double[] bottomright  = this.Tranform(right, bottom);
                float    leftPixels   = (float)topleft[0];
                float    topPixels    = (float)topleft[1];
                float    rightPixels  = (float)bottomright[0];
                float    bottomPixels = (float)bottomright[1];

                target.Target.CGContext.DrawImage(new RectangleF(leftPixels, topPixels, (rightPixels - leftPixels),
                                                                 (bottomPixels - topPixels)), image);
            }
            else if (layer != null)
            {
                double[] topleft      = this.Tranform(left, top);
                double[] bottomright  = this.Tranform(right, bottom);
                float    leftPixels   = (float)topleft[0];
                float    topPixels    = (float)topleft[1];
                float    rightPixels  = (float)bottomright[0];
                float    bottomPixels = (float)bottomright[1];

                target.Target.CGContext.DrawLayer(layer, new RectangleF(leftPixels, topPixels, (rightPixels - leftPixels),
                                                                        (bottomPixels - topPixels)));
            }
            return(image);
        }
Esempio n. 4
0
        private void AddMoodLayer(CGContext g, RectangleF frame, MoodDataSet mood, bool showDataPoints)
        {
            PointF  bottomRight = new PointF(frame.Width, frame.Height + 100);
            PointF  bottomLeft  = new PointF(0, frame.Height + 100);
            var     color       = mood.Mood.DisplayColor;
            var     dataPoints  = GetPointsForSpline(mood.DataPoints, frame);
            var     last        = dataPoints [dataPoints.Count - 1];
            var     first       = dataPoints.First();
            CGLayer layer       = CGLayer.Create(g, new SizeF(frame.Width, frame.Height));

            layer.Context.SetFillColor(color);
            layer.Context.SetStrokeColor(new CGColor(0, 0, 0));

            layer.Context.MoveTo(bottomLeft.X, bottomLeft.Y);
            layer.Context.AddLineToPoint(first.X, first.Y);


            if (this.SmoothLines && dataPoints.Count() >= minDataPointsRequiredForSpline)
            {
                layer.Context.AddSpline(dataPoints.ToArray(), this.Tension);
            }
            else
            {
                layer.Context.AddLines(dataPoints.ToArray());
            }

            layer.Context.AddLineToPoint(last.X, bottomRight.Y);
            layer.Context.AddLineToPoint(bottomLeft.X, bottomLeft.Y);


            layer.Context.DrawPath(CGPathDrawingMode.EOFill);
            g.DrawLayer(layer, new PointF(0, 0));

            if (ShowDataPoints)
            {
                var dpW = _dataPointWidth / 2;
                g.SetFillColor(new CGColor(0, 0, 0));
                foreach (var dp in dataPoints)
                {
                    g.FillEllipseInRect(new RectangleF(dp.X - dpW, dp.Y - dpW, _dataPointWidth, _dataPointWidth));
                }
            }
        }
Esempio n. 5
0
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            // set the background color of the view to white
            View.BackgroundColor = UIColor.White;

            // instantiate a new image view that takes up the whole screen and add it to
            // the view hierarchy
            CGRect imageViewFrame = new CGRect(0, -NavigationController.NavigationBar.Frame.Height, View.Frame.Width, View.Frame.Height);

            imageView = new UIImageView(imageViewFrame);
            View.AddSubview(imageView);

            // create our offscreen bitmap context
            // size
            CGSize bitmapSize = new CGSize(View.Frame.Size);

            using (CGBitmapContext context = new CGBitmapContext(
                       IntPtr.Zero,
                       (int)bitmapSize.Width, (int)bitmapSize.Height, 8,
                       (int)(4 * bitmapSize.Width), CGColorSpace.CreateDeviceRGB(),
                       CGImageAlphaInfo.PremultipliedFirst))
            {
                // declare vars
                int remainder;
                int textHeight = 20;

                #region -= vertical ticks =-

                // create our vertical tick lines
                using (CGLayer verticalTickLayer = CGLayer.Create(context, new CGSize(20, 3))) {
                    // draw a single tick
                    verticalTickLayer.Context.FillRect(new CGRect(0, 1, 20, 2));

                    // draw a vertical tick every 20 pixels
                    float yPos = 20;
                    nint  numberOfVerticalTicks = ((context.Height / 20) - 1);
                    for (int i = 0; i < numberOfVerticalTicks; i++)
                    {
                        // draw the layer
                        context.DrawLayer(verticalTickLayer, new CGPoint(0, yPos));

                        // starting at 40, draw the coordinate text nearly to the top
                        if (yPos > 40 && i < (numberOfVerticalTicks - 2))
                        {
                            // draw it every 80 points
                            Math.DivRem((int)yPos, (int)80, out remainder);
                            if (remainder == 0)
                            {
                                ShowTextAtPoint(context, 30, (yPos - (textHeight / 2)), yPos.ToString(), textHeight);
                            }
                        }

                        // increment the position of the next tick
                        yPos += 20;
                    }
                }

                #endregion

                #region -= horizontal ticks =-

                // create our horizontal tick lines
                using (CGLayer horizontalTickLayer = CGLayer.Create(context, new CGSize(3, 20))) {
                    horizontalTickLayer.Context.FillRect(new CGRect(1, 0, 2, 20));

                    // draw a horizontal tick every 20 pixels
                    float xPos = 20;
                    nint  numberOfHorizontalTicks = ((context.Width / 20) - 1);
                    for (int i = 0; i < numberOfHorizontalTicks; i++)
                    {
                        context.DrawLayer(horizontalTickLayer, new CGPoint(xPos, 0));

                        // starting at 100, draw the coordinate text nearly to the top
                        if (xPos > 100 && i < (numberOfHorizontalTicks - 1))
                        {
                            // draw it every 80 points
                            Math.DivRem((int)xPos, (int)80, out remainder);
                            if (remainder == 0)
                            {
                                ShowCenteredTextAtPoint(context, xPos, 30, xPos.ToString(), textHeight);
                            }
                        }

                        // increment the position of the next tick
                        xPos += 20;
                    }
                }

                #endregion

                // draw our "origin" text
                ShowTextAtPoint(context, 20, (20 + (textHeight / 2)), "Origin (0,0)", textHeight);

                #region -= points =-

                // (250,700)
                context.FillEllipseInRect(new CGRect(250, 700, 6, 6));
                ShowCenteredTextAtPoint(context, 250, 715, "(250,700)", textHeight);

                // (500,300)
                context.FillEllipseInRect(new CGRect(500, 300, 6, 6));
                ShowCenteredTextAtPoint(context, 500, 315, "(500,300)", textHeight);

                #endregion

                // output the drawing to the view
                imageView.Image = UIImage.FromImage(context.ToImage());
            }
        }
Esempio n. 6
0
        /// <summary>
        /// Draws our coordinate grid
        /// </summary>
        protected void DrawCoordinateSpace(CGBitmapContext context)
        {
            // declare vars
            int remainder;
            int textHeight = 20;

            #region -= vertical ticks =-

            // create our vertical tick lines
            using (CGLayer verticalTickLayer = CGLayer.Create(context, new CGSize(20, 3))) {
                // draw a single tick
                verticalTickLayer.Context.FillRect(new CGRect(0, 1, 20, 2));

                // draw a vertical tick every 20 pixels
                float yPos = 20;
                nint  numberOfVerticalTicks = ((context.Height / 20) - 1);
                for (int i = 0; i < numberOfVerticalTicks; i++)
                {
                    // draw the layer
                    context.DrawLayer(verticalTickLayer, new CGPoint(0, yPos));

                    // starting at 40, draw the coordinate text nearly to the top
                    if (yPos > 40 && i < (numberOfVerticalTicks - 2))
                    {
                        // draw it every 80 points
                        Math.DivRem((int)yPos, (int)80, out remainder);
                        if (remainder == 0)
                        {
                            DrawTextAtPoint(context, 30, (yPos - (textHeight / 2)), yPos.ToString(), textHeight);
                        }
                    }

                    // increment the position of the next tick
                    yPos += 20;
                }
            }

            #endregion

            #region -= horizontal ticks =-

            // create our horizontal tick lines
            using (CGLayer horizontalTickLayer = CGLayer.Create(context, new CGSize(3, 20))) {
                horizontalTickLayer.Context.FillRect(new CGRect(1, 0, 2, 20));

                // draw a horizontal tick every 20 pixels
                float xPos = 20;
                nint  numberOfHorizontalTicks = ((context.Width / 20) - 1);
                for (int i = 0; i < numberOfHorizontalTicks; i++)
                {
                    context.DrawLayer(horizontalTickLayer, new CGPoint(xPos, 0));

                    // starting at 100, draw the coordinate text nearly to the top
                    if (xPos > 100 && i < (numberOfHorizontalTicks - 1))
                    {
                        // draw it every 80 points
                        Math.DivRem((int)xPos, (int)80, out remainder);
                        if (remainder == 0)
                        {
                            DrawCenteredTextAtPoint(context, xPos, 30, xPos.ToString(), textHeight);
                        }
                    }

                    // increment the position of the next tick
                    xPos += 20;
                }
            }

            #endregion

            // draw our "origin" text
            DrawTextAtPoint(context, 20, (20 + (textHeight / 2)), "Origin (0,0)", textHeight);
        }
Esempio n. 7
0
        // rect changes depending on if the whole view is being redrawn, or just a section
        public override void Draw(CGRect rect)
        {
            Console.WriteLine("Draw() Called");
            base.Draw(rect);

            // get a reference to the context
            using (CGContext context = UIGraphics.GetCurrentContext()) {
                // declare vars
                int remainder;
                int textHeight = 20;

                // invert the 'y' coordinates on the text
                context.TextMatrix = CGAffineTransform.MakeScale(1, -1);

                #region -= vertical ticks =-

                // create our vertical tick lines
                using (CGLayer verticalTickLayer = CGLayer.Create(context, new CGSize(20, 3))) {
                    // draw a single tick
                    verticalTickLayer.Context.FillRect(new CGRect(0, 1, 20, 2));

                    // draw a vertical tick every 20 pixels
                    float yPos = 20;
                    int   numberOfVerticalTicks = (((int)Frame.Height / 20) - 1);
                    for (int i = 0; i < numberOfVerticalTicks; i++)
                    {
                        // draw the layer
                        context.DrawLayer(verticalTickLayer, new CGPoint(0, yPos));

                        // starting at 40, draw the coordinate text nearly to the top
                        if (yPos > 40 && i < (numberOfVerticalTicks - 2))
                        {
                            // draw it every 80 points
                            Math.DivRem((int)yPos, (int)80, out remainder);
                            if (remainder == 0)
                            {
                                ShowTextAtPoint(context, 30, (yPos - (textHeight / 2)), yPos.ToString(), textHeight);
                            }
                        }

                        // increment the position of the next tick
                        yPos += 20;
                    }
                }

                #endregion

                #region -= horizontal ticks =-

                // create our horizontal tick lines
                using (CGLayer horizontalTickLayer = CGLayer.Create(context, new CGSize(3, 20))) {
                    horizontalTickLayer.Context.FillRect(new CGRect(1, 0, 2, 20));

                    // draw a horizontal tick every 20 pixels
                    float xPos = 20;
                    int   numberOfHorizontalTicks = (((int)Frame.Width / 20) - 1);
                    for (int i = 0; i < numberOfHorizontalTicks; i++)
                    {
                        context.DrawLayer(horizontalTickLayer, new CGPoint(xPos, 0));

                        // starting at 100, draw the coordinate text nearly to the top
                        if (xPos > 100 && i < (numberOfHorizontalTicks - 1))
                        {
                            // draw it every 80 points
                            Math.DivRem((int)xPos, (int)80, out remainder);
                            if (remainder == 0)
                            {
                                ShowCenteredTextAtPoint(context, xPos, 40, xPos.ToString(), textHeight);
                            }
                        }

                        // increment the position of the next tick
                        xPos += 20;
                    }
                }

                #endregion

                // draw our "origin" text
                ShowTextAtPoint(context, 20, (30 + (textHeight / 2)), "Origin (0,0)", textHeight);

                #region -= points =-

                // (250,700)
                context.FillEllipseInRect(new CGRect(250, 700, 6, 6));
                ShowCenteredTextAtPoint(context, 250, 695, "(250,700)", textHeight);

                // (500,300)
                context.FillEllipseInRect(new CGRect(500, 300, 6, 6));
                ShowCenteredTextAtPoint(context, 500, 295, "(500,300)", textHeight);

                #endregion
            }
        }
Esempio n. 8
0
        protected void DrawFlag(CGContext context)
        {
            // declare vars
            int i, j;

            // general sizes
            float  flagWidth  = imageView.Frame.Width * .8f;
            float  flagHeight = (float)(flagWidth / 1.9);
            PointF flagOrigin = new PointF(imageView.Frame.Width * .1f, imageView.Frame.Height / 3);

            // stripe
            float      stripeHeight  = flagHeight / 13;
            float      stripeSpacing = stripeHeight * 2;
            RectangleF stripeRect    = new RectangleF(0, 0, flagWidth, stripeHeight);

            // star field
            float      starFieldHeight = 7 * stripeHeight;
            float      starFieldWidth  = flagWidth * (2f / 5f);
            RectangleF starField       = new RectangleF(flagOrigin.X, flagOrigin.Y + (6 * stripeHeight), starFieldWidth, starFieldHeight);

            // stars
            float  starDiameter = flagHeight * 0.0616f;
            float  starHorizontalCenterSpacing = (starFieldWidth / 6);
            float  starHorizontalPadding       = (starHorizontalCenterSpacing / 4);
            float  starVerticalCenterSpacing   = (starFieldHeight / 5);
            float  starVerticalPadding         = (starVerticalCenterSpacing / 4);
            PointF firstStarOrigin             = new PointF(flagOrigin.X + starHorizontalPadding, flagOrigin.Y + flagHeight - starVerticalPadding - (starVerticalCenterSpacing / 2));
            PointF secondRowFirstStarOrigin    = new PointF(firstStarOrigin.X + (starHorizontalCenterSpacing / 2), firstStarOrigin.Y - (starVerticalCenterSpacing / 2));

            // white background + shadow
            context.SaveState();
            context.SetShadow(new SizeF(15, -15), 7);
            context.SetFillColor(1, 1, 1, 1);
            context.FillRect(new RectangleF(flagOrigin.X, flagOrigin.Y, flagWidth, flagHeight));
            context.RestoreState();

            // create a stripe layer
            using (CGLayer stripeLayer = CGLayer.Create(context, stripeRect.Size)) {
                // set red as the fill color
                // this works
                stripeLayer.Context.SetFillColor(1f, 0f, 0f, 1f);
                // but this doesn't ????
                //stripeLayer.Context.SetFillColor (new float[] { 1f, 0f, 0f, 1f });
                // fill the stripe
                stripeLayer.Context.FillRect(stripeRect);

                // loop through the stripes and draw the layer
                context.SaveState();
                for (i = 0; i < 7; i++)
                {
                    Console.WriteLine("drawing stripe layer");
                    // draw the layer
                    context.DrawLayer(stripeLayer, flagOrigin);
                    // move the origin
                    context.TranslateCTM(0, stripeSpacing);
                }
                context.RestoreState();
            }

            // draw the star field
            //BUGBUG: apple bug - this only works on on-screen CGContext and CGLayer
            //context.SetFillColor (new float[] { 0f, 0f, 0.329f, 1.0f });
            context.SetFillColor(0f, 0f, 0.329f, 1.0f);
            context.FillRect(starField);

            // create the star layer
            using (CGLayer starLayer = CGLayer.Create(context, starField.Size)) {
                // draw the stars
                DrawStar(starLayer.Context, starDiameter);

                // 6-star rows
                // save state so that as we translate (move the origin around,
                // it goes back to normal when we restore)
                context.SaveState();
                context.TranslateCTM(firstStarOrigin.X, firstStarOrigin.Y);
                // loop through each row
                for (j = 0; j < 5; j++)
                {
                    // each star in the row
                    for (i = 0; i < 6; i++)
                    {
                        // draw the star, then move the origin to the right
                        context.DrawLayer(starLayer, new PointF(0f, 0f));
                        context.TranslateCTM(starHorizontalCenterSpacing, 0f);
                    }
                    // move the row down, and then back left
                    context.TranslateCTM((-i * starHorizontalCenterSpacing), -starVerticalCenterSpacing);
                }
                context.RestoreState();

                // 5-star rows
                context.SaveState();
                context.TranslateCTM(secondRowFirstStarOrigin.X, secondRowFirstStarOrigin.Y);
                // loop through each row
                for (j = 0; j < 4; j++)
                {
                    // each star in the row
                    for (i = 0; i < 5; i++)
                    {
                        context.DrawLayer(starLayer, new PointF(0f, 0f));
                        context.TranslateCTM(starHorizontalCenterSpacing, 0);
                    }
                    context.TranslateCTM((-i * starHorizontalCenterSpacing), -starVerticalCenterSpacing);
                }
                context.RestoreState();
            }
        }
Esempio n. 9
0
 public CIImage(CGLayer layer, CIImageInitializationOptions options)
 {
     throw new NotSupportedException();
 }
Esempio n. 10
0
 public CIImage(CGLayer layer, NSDictionary d)
 {
     throw new NotSupportedException();
 }
Esempio n. 11
0
 public CIImage(CGLayer layer)
 {
     throw new NotSupportedException();
 }
        public override void Draw(CGRect area)
        {
            if (image == null)
            {
                return;
            }

            CGContext context = UIGraphics.GetCurrentContext();

            //
            //-----------------------------------------------------------
            // Draw bottom layer containing image preview
            //-----------------------------------------------------------
            //

            if (layerBottom == null)
            {
                CGLayer   layer        = CGLayer.Create(context, this.Bounds.Size);
                CGContext layerContext = layer.Context;

                layerContext.SetFillColor(this.BackgroundColor.CGColor);
                layerContext.FillRect(this.Bounds);

                CGAffineTransform transform = new CGAffineTransform(1, 0, 0, -1, 0, this.Bounds.Size.Height);
                layerContext.ConcatCTM(transform);

                layerContext.DrawImage(WholeImageRectInView(), image.CGImage);

                layerBottom = layer;
            }

            context.DrawLayer(layerBottom, new CGPoint(0, 0));

            //-----------------------------------------------------------
            // Draw transparency layer containing edges around page area
            //-----------------------------------------------------------
            {
                CGPoint[] point = new CGPoint[4];
                GetCornersCoordinates(point, false);

                // Preserve the current drawing state
                context.SaveState();

                context.BeginTransparencyLayer(null);

                context.SetLineWidth(1.0f);
                context.SetStrokeColor(0.0f, 0.0f, 1.0f, 1.0f);

                //-----------------------------------------------------------------
                // Create complex path as intersection of subpath 1 with subpath 2
                //-----------------------------------------------------------------

                // Create subpath 1 with the whole image size
                context.SetFillColor(0, 0, 0, 0.4f);
                context.AddRect(this.Bounds);

                // Create subpath 2 which cuts a page area from the subpath 1
                context.MoveTo(point[0].X, point[0].Y);
                context.AddLineToPoint(point[1].X, point[1].Y);
                context.AddLineToPoint(point[3].X, point[3].Y);
                context.AddLineToPoint(point[2].X, point[2].Y);
                context.AddLineToPoint(point[0].X, point[0].Y);
                context.EOFillPath();

                //-----------------------------------------------------------------
                // Create a new path which draws edges around page area
                //-----------------------------------------------------------------

                // Draw edge around page
                context.SetFillColor(0, 0, 1, 1);
                context.BeginPath();
                context.MoveTo(point[0].X, point[0].Y);
                context.AddLineToPoint(point[1].X, point[1].Y);
                context.AddLineToPoint(point[3].X, point[3].Y);
                context.AddLineToPoint(point[2].X, point[2].Y);
                context.AddLineToPoint(point[0].X, point[0].Y);
                context.StrokePath();

                context.EndTransparencyLayer();

                // Restore the previous drawing state.
                context.RestoreState();
            }
        }
Esempio n. 13
0
        //draw our coloring screen
        public override void Draw(RectangleF rect)
        {
            using (var ctx = UIGraphics.GetCurrentContext()) {
                var frame     = Frame;
                var imageSize = background.Size;

                ctx.SaveState();
                ctx.TranslateCTM(0, frame.Height);
                ctx.ScaleCTM(1, -1);

                //TODO: Scale image if image W & H are too big
                ctx.DrawImage(new RectangleF(
                                  frame.Width / 2 - imageSize.Width / 2,
                                  frame.Height / 2 - imageSize.Height / 2,
                                  imageSize.Width,
                                  imageSize.Height),
                              background.CGImage);

                ctx.RestoreState();

                if (Drawing != null)
                {
                    ctx.DrawLayer(Drawing, PointF.Empty);
                }
                if (Points.Any())
                {
                    if (Drawing == null)
                    {
                        Drawing = CGLayer.Create(ctx, frame.Size);
                    }
                    DrawPoints(ctx);
                }

                var pos = CRAYON_START;
                foreach (var crayon in Crayons)
                {
                    ctx.SaveState();

                    //translate depending on orientation
                    switch (Orientation)
                    {
                    case UIInterfaceOrientation.Portrait:
                    case UIInterfaceOrientation.PortraitUpsideDown:
                        ctx.TranslateCTM(frame.Width - crayon.Length, pos);
                        ctx.RotateCTM(-(float)Math.PI / 2f);
                        break;

                    case UIInterfaceOrientation.LandscapeLeft:
                    case UIInterfaceOrientation.LandscapeRight:
                        ctx.TranslateCTM(frame.Width - pos - crayon.Width, frame.Height - crayon.Length);
                        break;

                    default:
                        Application.Log("WARN: Cannot detect device orientation");
                        break;
                    }

                    DrawCrayon(ctx, crayon);

                    ctx.RestoreState();
                    pos += crayon.Width + CRAYON_SPACING;
                }
            }
        }