예제 #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();
            }
            public sd2.PathGradientBrush GetBrush(RectangleF rect)
            {
                var scale  = 1f;
                var bounds = rect;

                if (Matrix != null)
                {
                    bounds = Matrix.Inverse().TransformRectangle(bounds);
                }

                scale = GradientHelper.GetRadialScale(Center, Radius, GradientOrigin, bounds);

                if (brush == null || lastScale != scale)
                {
                    lastScale = scale;

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

                    var path = new sd2.GraphicsPath();
                    path.AddEllipse(scaledRect.ToSD());

                    brush                = new sd2.PathGradientBrush(path);
                    brush.CenterColor    = StartColor.ToSD();
                    brush.CenterPoint    = GradientOrigin.ToSD();
                    brush.WrapMode       = wrapMode.ToSD();
                    brush.SurroundColors = new[] { EndColor.ToSD() };

                    if (Matrix != null)
                    {
                        brush.MultiplyTransform(Matrix.ToSD());
                    }

                    if (scale > 1f)
                    {
                        var paths = GradientHelper.GetGradientStops(StartColor.ToSD(), EndColor.ToSD(), scale, wrapMode);

                        brush.InterpolationColors = new sd2.ColorBlend
                        {
                            Positions = paths.Reverse().Select(r => 1f - r.Item1).ToArray(),
                            Colors    = paths.Reverse().Select(r => r.Item2).ToArray()
                        };
                    }
                }

                return(brush);
            }