public unsafe override void Draw (RectangleF rect) { var start = new PointF (rect.Left, rect.Bottom); var end = new PointF (rect.Left, rect.Top); var domain = new nfloat[] {0f, 1f}; var range = new nfloat[] {0f, 1f, 0f, 1f}; using (var context = UIGraphics.GetCurrentContext ()) using (var rgb = CGColorSpace.CreateDeviceGray()) using (var shadingFunction = new CGFunction(domain, range, Shading)) using (var shading = CGShading.CreateAxial (rgb, start, end, shadingFunction, true, false)) { context.DrawShading (shading); } base.Draw (rect); }
// http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_shadings/dq_shadings.html#//apple_ref/doc/uid/TP30001066-CH207-BBCECJBF internal override void Setup(Graphics graphics, bool fill) { CGContext context = graphics.context; // if fill is false then we are being called from a Pen stroke so // we need to setup a transparency layer // http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_shadings/dq_shadings.html#//apple_ref/doc/uid/TP30001066-CH207-BBCECJBF if (!fill) { context.BeginTransparencyLayer(); hasTransparencyLayer = true; // Make sure we set a color here so that the gradient shows up graphics.lastBrushColor = Color.Black; return; } // if this is the same as the last that was set and no changes have been made // then return. if (graphics.LastBrush != this || changed) { setupShadingColors(); } CGSize gradientRegionCg = context.GetClipBoundingBox().Size; SizeF gradientRegion = new SizeF((float)gradientRegionCg.Width, (float)gradientRegionCg.Height); // SizeF gradientRegionPath = context.GetPathBoundingBox().Size; PointF sp = startPoint; PointF ep = endPoint; PointF[] points = { sp, ep }; // Transform the start and end points using the brush's transformation matrix gradientTransform.TransformPoints(points); sp = points[0]; ep = points[1]; var cgf = CyclicGradientFunction(gradientRegion, ref sp, ref ep); var colorSpace = CGColorSpace.CreateDeviceRGB(); CGPoint cgsp = new CGPoint(sp.X, sp.Y), cgep = new CGPoint(ep.X, ep.Y); var shading = CGShading.CreateAxial(colorSpace, cgsp, cgep, cgf, false, false); colorSpace.Dispose(); context.SaveState(); // if path is empty here then we are being called from a Pen stroke so // we set the blend mode for strokes and clip the path for fills if (!context.IsPathEmpty()) { context.Clip(); } else { context.SetBlendMode(CGBlendMode.SourceIn); } context.DrawShading(shading); context.RestoreState(); // If we are in a Transparency layer then we need to end the transparency if (hasTransparencyLayer) { context.EndTransparencyLayer(); } cgf.Dispose(); shading.Dispose(); shading = null; changed = false; graphics.LastBrush = this; // We will reset the last pen so that it can be setup again // so that we do not loose the settings after stroking the gradient // not sure where the setting are being reset so this may be a hack // and things are just not being restored correctly. graphics.LastPen = null; // I am setting this to be used for Text coloring in DrawString graphics.lastBrushColor = colors[0]; }