Exemplo n.º 1
0
            public void Draw(GraphicsHandler graphics, bool stroke, FillMode fillMode, bool clip)
            {
                var outerRadius = Radius.Width;
                var yscale      = Radius.Height / Radius.Width;
                var center      = Center;
                var origin      = GradientOrigin;
                var scale       = 1f;
                var rect        = graphics.Control.GetPathBoundingBox().ToEto();

                if (stroke)
                {
                    graphics.Control.ReplacePathWithStrokedPath();
                }
                if (clip)
                {
                    graphics.Clip(fillMode);
                }

                if (wrap != GradientWrapMode.Pad)
                {
                    // use eto's transformrectangle as it'll make the rect encompass the resulting transformed area
                    var boundRect = transform.Invert().ToEto().TransformRectangle(rect);

                    // find max number of iterations we need to fill the bounding rectangle
                    scale = GradientHelper.GetRadialScale(Center, Radius, GradientOrigin, boundRect);
                }

                if (Gradient == null || scale > lastScale)
                {
                    var stops = GradientHelper.GetGradientStops(StartColor.ToCG(), EndColor.ToCG(), scale, wrap).ToList();
                    lastScale = scale;
                    Gradient  = new CGGradient(CGColorSpace.CreateDeviceRGB(), stops.Select(r => r.Item2).ToArray(), stops.Select(r => (nfloat)r.Item1).ToArray());
                }
                else
                {
                    scale = lastScale;
                }

                var scaledRect = new RectangleF(GradientOrigin - (GradientOrigin - Center + Radius) * scale, GradientOrigin + (Center + Radius - GradientOrigin) * scale);

                center       = scaledRect.Center;
                outerRadius *= scale;

                // adjust center based on ellipse scale from gradient origin
                center.Y = origin.Y - (origin.Y - center.Y) / yscale;

                // scale to draw elliptical gradient
                var t = new CGAffineTransform(1, 0f, 0f, yscale, 0, origin.Y - origin.Y * yscale);

                t.Multiply(transform);

                graphics.Control.SaveState();
                graphics.Control.ConcatCTM(t);
                graphics.Control.DrawRadialGradient(Gradient, origin.ToNS(), 0, center.ToNS(), outerRadius, CGGradientDrawingOptions.DrawsAfterEndLocation | CGGradientDrawingOptions.DrawsBeforeStartLocation);
                graphics.Control.RestoreState();
            }