protected override Paint GetPaintInner(Windows.Foundation.Rect destinationRect) { var paint = new Paint(); // Android LinearGradient requires two ore more stop points. if (GradientStops.Count >= 2) { var colors = GradientStops.Select(s => ((Android.Graphics.Color)s.Color).ToArgb()).ToArray(); var locations = GradientStops.Select(s => (float)s.Offset).ToArray(); var width = destinationRect.Width; var height = destinationRect.Height; var transform = RelativeTransform?.ToNative(size: new Windows.Foundation.Size(width, height), isBrush: true); //Matrix .MapPoints takes an array of floats var pts = new[] { StartPoint, EndPoint } .Select(p => new float[] { (float)(p.X * width), (float)(p.Y * height) }) .SelectMany(p => p) .ToArray(); transform?.MapPoints(pts); var shader = new LinearGradient(pts[0], pts[1], pts[2], pts[3], colors, locations, Shader.TileMode.Mirror); paint.SetShader(shader); } return(paint); }
/// <summary> /// Create matrix to transform image based on relative dimensions of bitmap and drawRect, Stretch mode, and RelativeTransform /// </summary> /// <param name="drawRect"></param> /// <param name="bitmap"></param> /// <returns></returns> private Android.Graphics.Matrix GenerateMatrix(Windows.Foundation.Rect drawRect, Bitmap bitmap) { var matrix = new Android.Graphics.Matrix(); // Note that bitmap.Width and bitmap.Height (in physical pixels) are automatically scaled up when loaded from local resources, but aren't when acquired externally. // This means that bitmaps acquired externally might not render the same way on devices with different densities when using Stretch.None. var sourceRect = new Windows.Foundation.Rect(0, 0, bitmap.Width, bitmap.Height); var destinationRect = GetArrangedImageRect(sourceRect.Size, drawRect); matrix.SetRectToRect(sourceRect.ToRectF(), destinationRect.ToRectF(), Android.Graphics.Matrix.ScaleToFit.Fill); RelativeTransform?.ToNative(matrix, new Size(drawRect.Width, drawRect.Height), isBrush: true); return(matrix); }
protected internal override Shader GetShader(Rect destinationRect) { var center = Center; var radiusX = RadiusX; var radiusY = RadiusY; float radius; if (MappingMode == BrushMappingMode.RelativeToBoundingBox) { var size = destinationRect.Size; center = new Point(center.X * size.Width, Center.Y * size.Height); radius = (float)(radiusX * size.Width + radiusY * size.Height) / 2.0f; // We take the avg } else { center = center.LogicalToPhysicalPixels(); radius = ViewHelper.LogicalToPhysicalPixels((radiusX + radiusY) / 2.0d); // We take the avg } // Android requires a radius and two or more stop points. if (radius <= 0 || GradientStops.Count < 2) { return(null); } var colors = GradientStops.SelectToArray(s => ((Android.Graphics.Color)s.Color).ToArgb()); var locations = GradientStops.SelectToArray(s => (float)s.Offset); var width = destinationRect.Width; var height = destinationRect.Height; var transform = RelativeTransform?.ToNative(size: new Windows.Foundation.Size(width, height), isBrush: true); var shader = new RadialGradient( (float)center.X, (float)center.Y, radius, colors, locations, Shader.TileMode.Clamp); return(shader); }
protected internal override Shader GetShader(Rect destinationRect) { // Android LinearGradient requires two ore more stop points. if (GradientStops.Count >= 2) { var colors = GradientStops.SelectToArray(s => ((Android.Graphics.Color)s.Color).ToArgb()); var locations = GradientStops.SelectToArray(s => (float)s.Offset); var width = destinationRect.Width; var height = destinationRect.Height; var transform = RelativeTransform?.ToNative(size: new Windows.Foundation.Size(width, height), isBrush: true); //Matrix .MapPoints takes an array of floats var pts = MappingMode == BrushMappingMode.RelativeToBoundingBox ? new[] { (float)(StartPoint.X * width), (float)(StartPoint.Y * height), (float)(EndPoint.X * width), (float)(EndPoint.Y * height) } : new[] { (float)StartPoint.X, (float)StartPoint.Y, (float)EndPoint.X, (float)EndPoint.Y }; transform?.MapPoints(pts); return(new LinearGradient(pts[0], pts[1], pts[2], pts[3], colors, locations, Shader.TileMode.Clamp)); } return(null); }