/// <summary>
        /// Constructor for LinearGradientPaintContext.
        /// </summary>
        /// <param name="paint"> the {@code LinearGradientPaint} from which this context
        ///              is created </param>
        /// <param name="cm"> {@code ColorModel} that receives
        ///           the <code>Paint</code> data. This is used only as a hint. </param>
        /// <param name="deviceBounds"> the device space bounding box of the
        ///                     graphics primitive being rendered </param>
        /// <param name="userBounds"> the user space bounding box of the
        ///                   graphics primitive being rendered </param>
        /// <param name="t"> the {@code AffineTransform} from user
        ///          space into device space (gradientTransform should be
        ///          concatenated with this) </param>
        /// <param name="hints"> the hints that the context object uses to choose
        ///              between rendering alternatives </param>
        /// <param name="start"> gradient start point, in user space </param>
        /// <param name="end"> gradient end point, in user space </param>
        /// <param name="fractions"> the fractions specifying the gradient distribution </param>
        /// <param name="colors"> the gradient colors </param>
        /// <param name="cycleMethod"> either NO_CYCLE, REFLECT, or REPEAT </param>
        /// <param name="colorSpace"> which colorspace to use for interpolation,
        ///                   either SRGB or LINEAR_RGB </param>
        internal LinearGradientPaintContext(LinearGradientPaint paint, ColorModel cm, Rectangle deviceBounds, Rectangle2D userBounds, AffineTransform t, RenderingHints hints, Point2D start, Point2D end, float[] fractions, Color[] colors, CycleMethod cycleMethod, ColorSpaceType colorSpace) : base(paint, cm, deviceBounds, userBounds, t, hints, fractions, colors, cycleMethod, colorSpace)
        {
            // A given point in the raster should take on the same color as its
            // projection onto the gradient vector.
            // Thus, we want the projection of the current position vector
            // onto the gradient vector, then normalized with respect to the
            // length of the gradient vector, giving a value which can be mapped
            // into the range 0-1.
            //    projection =
            //        currentVector dot gradientVector / length(gradientVector)
            //    normalized = projection / length(gradientVector)

            float startx = (float)start.X;
            float starty = (float)start.Y;
            float endx   = (float)end.X;
            float endy   = (float)end.Y;

            float dx  = endx - startx;            // change in x from start to end
            float dy  = endy - starty;            // change in y from start to end
            float dSq = dx * dx + dy * dy;        // total distance squared

            // avoid repeated calculations by doing these divides once
            float constX = dx / dSq;
            float constY = dy / dSq;

            // incremental change along gradient for +x
            DgdX = A00 * constX + A10 * constY;
            // incremental change along gradient for +y
            DgdY = A01 * constX + A11 * constY;

            // constant, incorporates the translation components from the matrix
            Gc = (A02 - startx) * constX + (A12 - starty) * constY;
        }
예제 #2
0
        void SetLinearGradientPaint(APaint platformPaint, LinearGradientPaint linearGradientPaint)
        {
            var p1 = linearGradientPaint.StartPoint;
            var x1 = (float)p1.X;
            var y1 = (float)p1.Y;
            var p2 = linearGradientPaint.EndPoint;
            var x2 = (float)p2.X;
            var y2 = (float)p2.Y;

            var data   = GetGradientPaintData(linearGradientPaint);
            var shader = new LinearGradientData(data.Colors, data.Offsets, x1, y1, x2, y2);

            if (_width == 0 && _height == 0)
            {
                return;
            }

            if (shader.Colors == null || shader.Colors.Length < 2)
            {
                return;
            }

            var linearGradientShader = new LinearGradient(
                _width * shader.X1,
                _height * shader.Y1,
                _width * shader.X2,
                _height * shader.Y2,
                shader.Colors,
                shader.Offsets,
                Shader.TileMode.Clamp !);

            platformPaint.SetShader(linearGradientShader);
        }
예제 #3
0
        public void SetBorderBrush(LinearGradientPaint linearGradientPaint)
        {
            _strokeColor = null;
            _stroke      = linearGradientPaint;

            SetNeedsDisplay();
        }
예제 #4
0
        public void SetBackground(LinearGradientPaint linearGradientPaint)
        {
            _backgroundColor = null;
            _background      = linearGradientPaint;

            SetNeedsDisplay();
        }
예제 #5
0
        public void SetBorderBrush(LinearGradientPaint linearGradientPaint)
        {
            _invalidatePath = true;

            _borderColor = null;
            _stroke      = linearGradientPaint;

            InitializeBorderIfNeeded();
            InvalidateSelf();
        }
예제 #6
0
		public static Drawable? CreateDrawable(this LinearGradientPaint linearGradientPaint, Context? context)
		{
			if (!linearGradientPaint.IsValid())
				return null;

			var drawable = new MauiDrawable(context);
			drawable.SetBackground(linearGradientPaint);

			return drawable;
		}
예제 #7
0
        public void SetBackground(LinearGradientPaint linearGradientPaint)
        {
            _invalidatePath = true;

            _backgroundColor = null;
            _background      = linearGradientPaint;

            InitializeBorderIfNeeded();
            InvalidateSelf();
        }
예제 #8
0
        public static MauiDrawable?CreateDrawable(this LinearGradientPaint linearGradientPaint)
        {
            if (!linearGradientPaint.IsValid())
            {
                return(null);
            }

            return(new MauiDrawable
            {
                Background = linearGradientPaint
            });
        }
예제 #9
0
        public static WBrush?CreateBrush(this LinearGradientPaint linearGradientPaint)
        {
            var brush = new WLinearGradientBrush
            {
                StartPoint = linearGradientPaint.StartPoint.ToNative(),
                EndPoint   = linearGradientPaint.EndPoint.ToNative()
            };

            brush.GradientStops.AddRange(linearGradientPaint.GradientStops);

            return(brush);
        }
        public static Drawable?CreateDrawable(this LinearGradientPaint linearGradientPaint)
        {
            if (!linearGradientPaint.IsValid())
            {
                return(null);
            }

            var drawable = new MauiDrawable();

            drawable.SetPaint(linearGradientPaint);

            return(drawable);
        }
예제 #11
0
        internal static LinearGradientShaderFactory GetLinearGradientShaderFactory(LinearGradientPaint linearGradientPaint)
        {
            var p1 = linearGradientPaint.StartPoint;
            var x1 = (float)p1.X;
            var y1 = (float)p1.Y;

            var p2   = linearGradientPaint.EndPoint;
            var x2   = (float)p2.X;
            var y2   = (float)p2.Y;
            var data = GetGradientPaintData(linearGradientPaint);
            var linearGradientShaderFactory = new LinearGradientShaderFactory(new LinearGradientData(data.Colors, data.Offsets, x1, y1, x2, y2));

            return(linearGradientShaderFactory);
        }
예제 #12
0
        public override void Draw(ICanvas canvas, RectF dirtyRect)
        {
            float height = Math.Max(MinimumHeight, dirtyRect.Height);

            UpdateHeight(height);

            base.Draw(canvas, dirtyRect);

            // Draw gradient rainbow Color spectrum
            canvas.SaveState();

            LinearGradientPaint linearGradientPaint = new LinearGradientPaint
            {
                GradientStops = new PaintGradientStop[]
                {
                    new PaintGradientStop(0.0f, new Color(255, 0, 0)),
                    new PaintGradientStop(0.2f, new Color(255, 255, 0)),
                    new PaintGradientStop(0.4f, new Color(0, 255, 0)),
                    new PaintGradientStop(0.6f, new Color(0, 255, 255)),
                    new PaintGradientStop(0.8f, new Color(255, 0, 255)),
                    new PaintGradientStop(1.0f, new Color(255, 0, 0))
                }
            };

            canvas.SetFillPaint(linearGradientPaint, dirtyRect);

            canvas.FillRectangle(dirtyRect);

            canvas.RestoreState();

            // Painting the Touch point
            canvas.SaveState();

            float size            = Math.Min(dirtyRect.Width, height);
            float pointerDiameter = (float)(size * 0.25f);

            canvas.StrokeColor = Colors.White;
            canvas.StrokeSize  = 5.0f;

            // Set initial Touch point position
            if (_lastTouchPoint == Point.Zero)
            {
                _lastTouchPoint = new Point(dirtyRect.Width / 2 - pointerDiameter / 2, height / 2 - pointerDiameter / 2);
            }

            canvas.DrawEllipse((float)_lastTouchPoint.X, (float)_lastTouchPoint.Y, pointerDiameter, pointerDiameter);

            canvas.RestoreState();
        }
        public void SetPaint(LinearGradientPaint linearGradientPaint)
        {
            var p1 = linearGradientPaint.StartPoint;
            var x1 = (float)p1.X;
            var y1 = (float)p1.Y;

            var p2 = linearGradientPaint.EndPoint;
            var x2 = (float)p2.X;
            var y2 = (float)p2.Y;

            var data   = GetGradientPaintData(linearGradientPaint);
            var shader = new LinearGradientData(data.Colors, data.Offsets, x1, y1, x2, y2);

            _backgroundColor = null;
            SetShaderFactory(new LinearGradientShaderFactory(shader));
        }
예제 #14
0
        public static CALayer?CreateCALayer(this LinearGradientPaint linearGradientPaint, CGRect frame = default)
        {
            var p1 = linearGradientPaint.StartPoint;
            var p2 = linearGradientPaint.EndPoint;

            var linearGradientLayer = new CAGradientLayer
            {
                ContentsGravity = CALayer.GravityResizeAspectFill,
                Frame           = frame,
                LayerType       = CAGradientLayerType.Axial,
                StartPoint      = new CGPoint(p1.X, p1.Y),
                EndPoint        = new CGPoint(p2.X, p2.Y)
            };

            if (linearGradientPaint.GradientStops != null && linearGradientPaint.GradientStops.Length > 0)
            {
                var orderedStops = linearGradientPaint.GradientStops.OrderBy(x => x.Offset).ToList();
                linearGradientLayer.Colors    = orderedStops.Select(x => x.Color.ToCGColor()).ToArray();
                linearGradientLayer.Locations = GetCAGradientLayerLocations(orderedStops);
            }

            return(linearGradientLayer);
        }
예제 #15
0
        public static void DrawShape(
            this ICanvas canvas,
            Shape shape,
            RectangleF rect,
            DrawingStyle drawingStyle = DrawingStyle.Fill,
            float strokeWidth         = 1,
            Color strokeColor         = null,
            object fill = null)
        {
            if (shape == null)
            {
                return;
            }
            Paint strokePaint = null;
            Paint fillPaint   = null;
            //Graphics.sh shader = null;
            float lineWidth = 0;

            switch (drawingStyle)
            {
            case DrawingStyle.StrokeFill:
                strokePaint = new SolidPaint
                {
                    BackgroundColor = strokeColor,
                };

                fillPaint = new SolidPaint
                {
                    //BackgroundColor = strokeColor,
                };
                break;

            case DrawingStyle.Stroke:
                strokePaint = new SolidPaint
                {
                    BackgroundColor = strokeColor,
                };
                fillPaint = new SolidPaint();
                break;

            case DrawingStyle.Fill:
                fillPaint = new SolidPaint();
                break;
            }

            var shapeBounds = new RectangleF(
                rect.X + (lineWidth / 2),
                rect.Y + (lineWidth / 2),
                rect.Width - lineWidth,
                rect.Height - lineWidth);

            var path = shape.PathForBounds(shapeBounds);

            if (fill != null && fillPaint != null)
            {
                if (fill is Color color)
                {
                    canvas.FillColor = color;
                    canvas.FillPath(path);
                }
                else if (fill is Gradient gradient)
                {
                    canvas.SaveState();

                    var colors = new GradientStop[gradient.Stops.Length];

                    var sortedStops = gradient.GetSortedStops();

                    for (var i = 0; i < sortedStops.Length; i++)
                    {
                        colors[i] = new GradientStop(sortedStops[i].Offset, sortedStops[i].Color);
                    }

                    if (gradient is LinearGradient linearGradient)
                    {
                        var x1 = (float)(rect.X + rect.Width * linearGradient.StartPoint.X);
                        var y1 = (float)(rect.Y + rect.Height * linearGradient.StartPoint.Y);

                        var x2 = (float)(rect.X + rect.Width * linearGradient.EndPoint.X);
                        var y2 = (float)(rect.Y + rect.Height * linearGradient.EndPoint.Y);
                        fillPaint = new LinearGradientPaint
                        {
                            GradientStops = colors,
                        };
                        canvas.SetFillPaint(fillPaint, new RectangleF(x1, y1, x2, y2));
                        canvas.FillPath(path);
                    }
                    else if (gradient is RadialGradient radialGradient)
                    {
                        var x1 = (float)(rect.X + rect.Width * radialGradient.Center.X);
                        var y1 = (float)(rect.Y + rect.Height * radialGradient.Center.Y);
                        var x2 = x1;
                        var y2 = (float)(y1 + radialGradient.EndRadius);
                        fillPaint = new RadialGradientPaint
                        {
                            GradientStops = colors,
                        };

                        canvas.SetFillPaint(fillPaint, new RectangleF(x1, y1, x2, y2));
                        canvas.FillPath(path);
                    }

                    //if (shader != null)
                    //{
                    //	fillPaint.Shader = shader;
                    //	canvas.DrawPath(path, fillPaint);
                    //}

                    //shader.Dispose();
                    canvas.RestoreState();
                }
            }

            if (strokePaint != null)
            {
                canvas.StrokeSize  = strokeWidth;
                canvas.StrokeColor = strokeColor;
                canvas.DrawPath(path);
            }
        }
        public void DrawBackground(ICanvas canvas, RectF dirtyRect, IButton button)
        {
            canvas.SaveState();

            var x = dirtyRect.X;
            var y = dirtyRect.Y;

            var width  = dirtyRect.Width;
            var height = dirtyRect.Height;

            var defaultBackgroundColor = (Application.Current?.RequestedTheme == AppTheme.Light) ? Fluent.Color.Light.Control.Background.Default.ToColor() : Fluent.Color.Dark.Control.Background.Default.ToColor();

            if (button.Background != null && button.Background is SolidPaint solidPaint)
            {
                defaultBackgroundColor = solidPaint.Color;
            }

            var disabledColor = (Application.Current?.RequestedTheme == AppTheme.Light) ? Fluent.Color.Light.Control.Background.Disabled.ToColor() : Fluent.Color.Dark.Control.Background.Disabled.ToColor();

            var backgroundColor = button.IsEnabled ? defaultBackgroundColor : disabledColor;

            var fill = new LinearGradientPaint
            {
                GradientStops = new PaintGradientStop[]
                {
                    new PaintGradientStop(0.0f, backgroundColor.Lighter()),
                    new PaintGradientStop(0.9f, backgroundColor.Darker())
                },
                StartPoint = new Point(0, 0),
                EndPoint   = new Point(0, 1)
            };

            canvas.SetFillPaint(fill, dirtyRect);

            canvas.FillRoundedRectangle(x, y, width, height, 4);

            canvas.StrokeColor = Fluent.Color.Light.Control.Border.Default.ToColor();

            canvas.DrawRoundedRectangle(x, y, width, height, 4);

            canvas.RestoreState();

            canvas.SaveState();

            if (button.IsEnabled)
            {
                canvas.StrokeColor = Colors.Black;

                if (button.Background != null)
                {
                    canvas.SetFillPaint(button.Background, dirtyRect);
                }
                else
                {
                    canvas.FillColor = defaultBackgroundColor;
                }
            }
            else
            {
                canvas.StrokeColor = canvas.FillColor = disabledColor;
            }

            var   strokeWidth = 1;
            float margin      = strokeWidth * 2;

            canvas.FillRoundedRectangle(x + strokeWidth, y + strokeWidth, width - margin, height - margin, 4);

            canvas.RestoreState();
        }
예제 #17
0
        public void DrawThumb(ICanvas canvas, RectF dirtyRect, ISlider slider)
        {
            float size        = 38f;
            float strokeWidth = 0.5f;

            var value = slider.Value / slider.Maximum - slider.Minimum;
            var x     = (float)((dirtyRect.Width * value) - (size / 2));

            if (x <= strokeWidth)
            {
                x = strokeWidth;
            }

            if (x >= dirtyRect.Width - (size + strokeWidth))
            {
                x = dirtyRect.Width - (size + strokeWidth);
            }

            var y = (float)((dirtyRect.Height - size) / 2);

            canvas.SaveState();

            canvas.StrokeColor = Color.FromArgb("#4F01E0"); //slider.ThumbColor.WithDefault(Colors.Black.ToArgbHex());
            canvas.StrokeSize  = strokeWidth;

            var linearGradientPaint = new LinearGradientPaint
            {
                StartColor = Color.FromArgb("#B589D6"),
                EndColor   = Color.FromArgb("#552586")
            };

            linearGradientPaint.StartPoint = new Point(0, 0);
            linearGradientPaint.EndPoint   = new Point(0.8, 1.0);

            canvas.SetFillPaint(linearGradientPaint, new RectF(x, y, size, size)); //slider.ThumbColor.WithDefault(Colors.White.ToArgbHex());

            canvas.SetShadow(new SizeF(6, 6), 6, Color.FromArgb("#99330194"));

            touchTargetRect.Center(new PointF(x, y));

            canvas.FillRoundedRectangle(x, y, size, size, 6);

            canvas.RestoreState();

            canvas.SaveState();

            canvas.SetShadow(new SizeF(-6, -6), 6, Color.FromArgb("#999E27FF"));

            canvas.DrawRoundedRectangle(x, y, size, size, 6);

            canvas.RestoreState();

            canvas.RestoreState();

            float marginX = 3;
            float marginY = 13;

            canvas.Translate(x + marginX, y + marginY);

            var vBuilder = new PathBuilder();
            var path     = vBuilder.BuildPath("M6.0190067,0.16500799L7.4250088,1.5890061 3.9923439,4.979006 14.419033,4.979006 14.419033,6.9799988 3.699379,6.9799988 7.4300079,10.708995 6.015007,12.123994 0,6.1090004z M25.982016,0L32.001003,5.9430005 25.985983,11.958999 24.571004,10.543993 28.167773,6.9479963 18.027001,6.9479963 18.027001,4.9470035 28.144115,4.9470035 24.576009,1.4240091z");

            canvas.FillColor = Colors.White;
            canvas.FillPath(path);

            canvas.SaveState();
        }
예제 #18
0
        public void Draw(ICanvas canvas, RectF dirtyRect)
        {
            canvas.SaveState();

            //
            // DrawXXXX Methods
            //

            canvas.StrokeColor = Colors.Grey;
            canvas.DrawLine(0, 0, 100, 100);
            canvas.DrawRectangle(100, 0, 100, 100);
            canvas.DrawEllipse(200, 0, 100, 100);
            canvas.DrawRoundedRectangle(300, 0, 100, 100, 25);

            var path = new PathF();

            path.MoveTo(400, 0);
            path.LineTo(400, 100);
            path.QuadTo(500, 100, 500, 0);
            path.CurveTo(450, 0, 500, 50, 450, 50);
            canvas.DrawPath(path);

            canvas.DrawRectangle(500, 0, 100, 50);
            canvas.DrawEllipse(600, 0, 100, 50);
            canvas.DrawRoundedRectangle(700, 0, 100, 50, 25);
            canvas.DrawRoundedRectangle(800, 0, 100, 25, 25);

            //
            // FillXXXX Methods
            //

            canvas.FillColor = Colors.Red;
            canvas.FillRectangle(210, 210, 80, 80);

            canvas.FillColor = Colors.Green;
            canvas.FillEllipse(310, 210, 80, 80);

            canvas.FillColor = Colors.Blue;
            canvas.FillRoundedRectangle(410, 210, 80, 80, 10);

            canvas.FillColor = Colors.CornflowerBlue;
            path             = new PathF();
            path.MoveTo(510, 210);
            path.LineTo(550, 290);
            path.LineTo(590, 210);
            path.Close();
            canvas.FillPath(path);

            canvas.FillColor = Colors.White;

            //
            //StrokeLocation.CENTER
            //
            canvas.StrokeSize = 10;
            canvas.DrawRectangle(50, 400, 100, 50);
            canvas.DrawEllipse(200, 400, 100, 50);
            canvas.DrawRoundedRectangle(350, 400, 100, 50, 25);

            path = new PathF();
            path.MoveTo(550, 400);
            path.LineTo(500, 450);
            path.LineTo(600, 450);
            path.Close();
            canvas.DrawPath(path);

            //
            // Stroke Color and Line Caps
            //

            canvas.StrokeColor = Colors.CornflowerBlue;
            canvas.DrawLine(100, 120, 300, 120);

            canvas.StrokeColor   = Colors.Red;
            canvas.StrokeLineCap = LineCap.Butt;
            canvas.DrawLine(100, 140, 300, 140);

            canvas.StrokeColor   = Colors.Green;
            canvas.StrokeLineCap = LineCap.Round;
            canvas.DrawLine(100, 160, 300, 160);

            canvas.StrokeColor   = Colors.Blue;
            canvas.StrokeLineCap = LineCap.Square;
            canvas.DrawLine(100, 180, 300, 180);

            canvas.StrokeLineCap = LineCap.Butt;

            //
            // Line Joins
            //

            canvas.StrokeColor = Colors.Black;

            path = new PathF();
            path.MoveTo(350, 120);
            path.LineTo(370, 180);
            path.LineTo(390, 120);
            canvas.DrawPath(path);

            canvas.StrokeLineJoin = LineJoin.Miter;
            path = new PathF();
            path.MoveTo(400, 120);
            path.LineTo(420, 180);
            path.LineTo(440, 120);
            canvas.DrawPath(path);

            canvas.StrokeLineJoin = LineJoin.Round;
            path = new PathF();
            path.MoveTo(450, 120);
            path.LineTo(470, 180);
            path.LineTo(490, 120);
            canvas.DrawPath(path);

            canvas.StrokeLineJoin = LineJoin.Bevel;
            path = new PathF();
            path.MoveTo(500, 120);
            path.LineTo(520, 180);
            path.LineTo(540, 120);
            canvas.DrawPath(path);

            canvas.StrokeLineJoin = LineJoin.Miter;
            canvas.MiterLimit     = 2;
            path = new PathF();
            path.MoveTo(550, 120);
            path.LineTo(570, 180);
            path.LineTo(590, 120);
            canvas.DrawPath(path);

            canvas.MiterLimit = CanvasDefaults.DefaultMiterLimit;

            //
            // Stroke Dash Pattern
            //
            canvas.StrokeSize        = 1;
            canvas.StrokeDashPattern = new float[] { 2, 2 };
            canvas.DrawLine(650, 120, 800, 120);

            canvas.StrokeSize        = 3;
            canvas.StrokeDashPattern = new float[] { 2, 2 };
            canvas.DrawLine(650, 140, 800, 140);

            canvas.StrokeDashPattern = new float[] { 4, 4, 1, 4 };
            canvas.DrawLine(650, 160, 800, 160);

            canvas.StrokeDashPattern = null;
            canvas.DrawLine(650, 180, 800, 180);

            canvas.StrokeLineCap = LineCap.Butt;

            //
            // Linear Gradient Fill
            //

            var linearGradientPaint = new LinearGradientPaint
            {
                StartColor = Colors.White,
                EndColor   = Colors.Black
            };

            linearGradientPaint.StartPoint = new Point(0.1, 0.1);
            linearGradientPaint.EndPoint   = new Point(0.9, 0.9);

            var linearRectangleRectangle = new RectF(50, 700, 100, 50);

            canvas.SetFillPaint(linearGradientPaint, linearRectangleRectangle);
            canvas.FillRectangle(linearRectangleRectangle);

            linearGradientPaint.StartPoint = new Point(0.1, 0.1);
            linearGradientPaint.EndPoint   = new Point(0.9, 0.9);

            var linearEllipseRectangle = new RectF(200, 700, 100, 50);

            canvas.SetFillPaint(linearGradientPaint, linearEllipseRectangle);
            canvas.FillEllipse(linearEllipseRectangle);

            linearGradientPaint.AddOffset(.5f, Colors.IndianRed);
            linearGradientPaint.StartPoint = new Point(0.1, 0.1);
            linearGradientPaint.EndPoint   = new Point(0.9, 0.9);

            var linearRoundedRectangleRectangle = new RectF(350, 700, 100, 50);

            canvas.SetFillPaint(linearGradientPaint, linearRoundedRectangleRectangle);
            canvas.FillRoundedRectangle(linearRoundedRectangleRectangle, 25);

            path = new PathF();
            path.MoveTo(550, 700);
            path.LineTo(500, 750);
            path.LineTo(600, 750);
            path.Close();

            linearGradientPaint.StartPoint = new Point(0.1, 0.1);
            linearGradientPaint.EndPoint   = new Point(0.9, 0.9);

            var linearPathRectangle = new RectF(500, 700, 200, 50);

            canvas.SetFillPaint(linearGradientPaint, linearPathRectangle);
            canvas.FillPath(path);

            //
            // Radial Gradient Fill
            //

            var radialGradientPaint = new RadialGradientPaint
            {
                StartColor = Colors.White,
                EndColor   = Colors.Black
            };

            radialGradientPaint.Center = new Point(0.5, 0.5);
            radialGradientPaint.Radius = 0.5;

            var radialRectangleRectangle = new RectF(50, 800, 100, 50);

            canvas.SetFillPaint(radialGradientPaint, radialRectangleRectangle);
            canvas.FillRectangle(radialRectangleRectangle);

            radialGradientPaint.Center = new Point(0.5, 0.5);
            radialGradientPaint.Radius = 0.5;

            var radialEllipseRectangle = new RectF(200, 800, 100, 50);

            canvas.SetFillPaint(radialGradientPaint, radialEllipseRectangle);
            canvas.FillEllipse(radialEllipseRectangle);

            radialGradientPaint.AddOffset(.5f, Colors.IndianRed);
            radialGradientPaint.Center = new Point(0.5, 0.5);
            radialGradientPaint.Radius = 0.5;

            var radialRoundedRectangleRectangle = new RectF(350, 800, 100, 50);

            canvas.SetFillPaint(radialGradientPaint, radialRoundedRectangleRectangle);
            canvas.FillRoundedRectangle(radialRoundedRectangleRectangle, 25);

            path = new PathF();
            path.MoveTo(550, 800);
            path.LineTo(500, 850);
            path.LineTo(600, 850);
            path.Close();

            radialGradientPaint.Center = new Point(0.5, 0.5);
            radialGradientPaint.Radius = 0.5;

            var radialPathRectangle = new RectF(550, 800, 200, 50);

            canvas.SetFillPaint(radialGradientPaint, radialPathRectangle);
            canvas.FillPath(path);

            //
            // Solid Fill With Shadow
            //

            canvas.SaveState();
            canvas.FillColor = Colors.CornflowerBlue;
            canvas.SetShadow(new SizeF(5, 5), 0, Colors.Grey);
            canvas.FillRectangle(50, 900, 100, 50);

            canvas.SetShadow(new SizeF(5, 5), 2, Colors.Red);
            canvas.FillEllipse(200, 900, 100, 50);

            canvas.SetShadow(new SizeF(5, 5), 5, Colors.Green);
            canvas.FillRoundedRectangle(350, 900, 100, 50, 25);

            canvas.SetShadow(new SizeF(10, 10), 5, Colors.Blue);

            path = new PathF();
            path.MoveTo(550, 900);
            path.LineTo(500, 950);
            path.LineTo(600, 950);
            path.Close();

            canvas.FillPath(path);

            //
            // Draw With Shadow
            //

            canvas.StrokeColor = Colors.Black;
            canvas.SetShadow(new SizeF(5, 5), 0, Colors.Grey);
            canvas.DrawRectangle(50, 1000, 100, 50);

            canvas.SetShadow(new SizeF(5, 5), 2, Colors.Red);
            canvas.DrawEllipse(200, 1000, 100, 50);

            canvas.SetShadow(new SizeF(5, 5), 5, Colors.Green);
            canvas.DrawRoundedRectangle(350, 1000, 100, 50, 25);

            canvas.SetShadow(new SizeF(10, 10), 5, Colors.Blue);
            path = new PathF();
            path.MoveTo(550, 1000);
            path.LineTo(500, 1050);
            path.LineTo(600, 1050);
            path.Close();

            canvas.DrawPath(path);

            canvas.RestoreState();

            //
            // Solid Fill Without Shadow
            //

            canvas.FillColor = Colors.DarkOliveGreen;
            canvas.FillRectangle(50, 1100, 100, 50);
            canvas.FillEllipse(200, 1100, 100, 50);
            canvas.FillRoundedRectangle(350, 1100, 100, 50, 25);

            path = new PathF();
            path.MoveTo(550, 1100);
            path.LineTo(500, 1150);
            path.LineTo(600, 1150);
            path.Close();

            canvas.FillPath(path);

            //
            // FILL WITH SHADOW USING ALPHA
            //

            canvas.SaveState();

            canvas.Alpha     = .25f;
            canvas.FillColor = Colors.CornflowerBlue;
            canvas.SetShadow(new SizeF(5, 5), 0, Colors.Grey);
            canvas.FillRectangle(50, 1200, 100, 50);

            canvas.Alpha = .5f;
            canvas.SetShadow(new SizeF(5, 5), 2, Colors.Red);
            canvas.FillEllipse(200, 1200, 100, 50);

            canvas.Alpha = .75f;
            canvas.SetShadow(new SizeF(5, 5), 5, Colors.Green);
            canvas.FillRoundedRectangle(350, 1200, 100, 50, 25);

            canvas.Alpha = 1;
            canvas.SetShadow(new SizeF(10, 10), 5, Colors.Blue);

            path = new PathF();
            path.MoveTo(550, 1200);
            path.LineTo(500, 1250);
            path.LineTo(600, 1250);
            path.Close();

            canvas.FillPath(path);
            canvas.RestoreState();

            //
            // Test Scaling
            //

            canvas.StrokeSize  = 1;
            canvas.StrokeColor = Colors.Black;
            canvas.DrawLine(10, 0, 0, 10);

            canvas.SaveState();

            canvas.Scale(2, 2);
            canvas.DrawLine(10, 0, 0, 10);

            canvas.Scale(2, 2);
            canvas.DrawLine(10, 0, 0, 10);

            canvas.RestoreState();

            //
            // Test simple rotation relative to 0,0
            //

            canvas.SaveState();
            canvas.SetShadow(new SizeF(2, 0), 2, Colors.Black);
            canvas.StrokeColor = Colors.CornflowerBlue;
            canvas.Rotate(15);
            canvas.DrawEllipse(60, 60, 10, 10);
            canvas.Rotate(15);
            canvas.DrawEllipse(60, 60, 10, 10);
            canvas.Rotate(15);
            canvas.DrawEllipse(60, 60, 10, 10);
            canvas.StrokeColor = Colors.DarkSeaGreen;
            canvas.Rotate(-60);
            canvas.DrawEllipse(60, 60, 10, 10);
            canvas.Rotate(-15);
            canvas.DrawEllipse(60, 60, 10, 10);
            canvas.RestoreState();

            canvas.DrawRectangle(60, 60, 10, 10);

            //
            // Test rotation relative to a point
            //

            canvas.DrawRectangle(25, 125, 50, 50);

            canvas.SaveState();
            canvas.Rotate(5, 50, 150);
            canvas.DrawRectangle(25, 125, 50, 50);
            canvas.RestoreState();

            canvas.SaveState();
            canvas.Rotate(-5, 50, 150);
            canvas.DrawRectangle(25, 125, 50, 50);
            canvas.RestoreState();

            //
            // Test text
            //

            canvas.StrokeSize  = 1;
            canvas.StrokeColor = Colors.Blue;

            const string vTextLong =
                "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
            const string vTextShort = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. ";

            for (int x = 0; x < 4; x++)
            {
                for (int y = 0; y < 3; y++)
                {
                    float dx = 1000 + x * 200;
                    float dy = 0 + y * 150;

                    canvas.DrawRectangle(dx, dy, 190, 140);

                    var vHorizontalAlignment = (HorizontalAlignment)x;
                    var vVerticalAlignment   = (VerticalAlignment)y;

                    canvas.Font     = new Font("Arial");
                    canvas.FontSize = 12f;
                    canvas.DrawString(vTextLong, dx, dy, 190, 140, vHorizontalAlignment, vVerticalAlignment);
                }
            }

            canvas.SaveState();
            canvas.SetShadow(new SizeF(2, 2), 2, Colors.DarkGrey);

            for (int x = 0; x < 4; x++)
            {
                for (int y = 0; y < 3; y++)
                {
                    float dx = 1000 + x * 200;
                    float dy = 450 + y * 150;

                    canvas.DrawRectangle(dx, dy, 190, 140);

                    var vHorizontalAlignment = (HorizontalAlignment)x;
                    var vVerticalAlignment   = (VerticalAlignment)y;

                    canvas.Font     = new Font("Arial");
                    canvas.FontSize = 12f;
                    canvas.DrawString(vTextShort, dx, dy, 190, 140, vHorizontalAlignment, vVerticalAlignment);
                }
            }

            canvas.RestoreState();

            for (int y = 0; y < 3; y++)
            {
                float       dx = 1000 + y * 200;
                const float dy = 1050;

                canvas.DrawRectangle(dx, dy, 190, 140);

                const HorizontalAlignment vHorizontalAlignment = HorizontalAlignment.Left;
                var vVerticalAlignment = (VerticalAlignment)y;

                canvas.Font     = new Font("Arial");
                canvas.FontSize = 12f;
                canvas.DrawString(
                    vTextLong,
                    dx,
                    dy,
                    190,
                    140,
                    vHorizontalAlignment,
                    vVerticalAlignment,
                    TextFlow.OverflowBounds);
            }

            //
            // Test simple drawing string
            //
            canvas.DrawLine(1000, 1300, 1200, 1300);
            canvas.DrawLine(1000, 1325, 1200, 1325);
            canvas.DrawLine(1000, 1350, 1200, 1350);
            canvas.DrawLine(1000, 1375, 1200, 1375);
            canvas.DrawLine(1100, 1300, 1100, 1400);
            canvas.DrawString("This is a test.", 1100, 1300, HorizontalAlignment.Left);
            canvas.DrawString("This is a test.", 1100, 1325, HorizontalAlignment.Center);
            canvas.DrawString("This is a test.", 1100, 1350, HorizontalAlignment.Right);
            canvas.DrawString("This is a test.", 1100, 1375, HorizontalAlignment.Justified);

            //
            // Test inverse clipping area
            //

            canvas.SaveState();
            canvas.DrawRectangle(200, 1300, 200, 50);
            canvas.SubtractFromClip(200, 1300, 200, 50);
            canvas.DrawLine(100, 1325, 500, 1325);
            canvas.DrawLine(300, 1275, 300, 1375);
            canvas.RestoreState();

            //
            // Test String Measuring
            //

            canvas.StrokeColor = Colors.Blue;
            for (int i = 0; i < 4; i++)
            {
                canvas.FontSize = 12 + i * 6;
                canvas.DrawString("Test String Length", 650, 400 + (100 * i), HorizontalAlignment.Left);

                var size = canvas.GetStringSize("Test String Length", new Font("Arial"), 12 + i * 6);
                canvas.DrawRectangle(650, 400 + (100 * i), size.Width, size.Height);
            }

            //
            // Test Path Measuring
            //

            var vBuilder = new PathBuilder();

            path = vBuilder.BuildPath("M0 52.5 C60 -17.5 60 -17.5 100 52.5 C140 122.5 140 122.5 100 152.5 Q60 182.5 0 152.5 Z");

            canvas.SaveState();
            canvas.Translate(650, 900);
            canvas.StrokeColor = Colors.Black;
            canvas.DrawPath(path);

            canvas.RestoreState();

            canvas.RestoreState();
        }