protected override void OnDraw(Canvas canvas) { base.OnDraw(canvas); if (_path == null) { return; } AMatrix transformMatrix = CreateMatrix(); _path.Transform(transformMatrix); transformMatrix.MapRect(_pathFillBounds); transformMatrix.MapRect(_pathStrokeBounds); if (_fill != null) { _drawable.Paint.SetStyle(Paint.Style.Fill); _drawable.Paint.Color = _fill; _drawable.Draw(canvas); _drawable.Paint.SetShader(null); } if (_stroke != null) { _drawable.Paint.SetStyle(Paint.Style.Stroke); _drawable.Paint.Color = _stroke; _drawable.Draw(canvas); _drawable.Paint.SetShader(null); } AMatrix inverseTransformMatrix = new AMatrix(); transformMatrix.Invert(inverseTransformMatrix); _path.Transform(inverseTransformMatrix); inverseTransformMatrix.MapRect(_pathFillBounds); inverseTransformMatrix.MapRect(_pathStrokeBounds); }
protected override void OnDraw(Canvas canvas) { base.OnDraw(canvas); if (_path == null) { return; } AMatrix transformMatrix = CreateMatrix(); _path.Transform(transformMatrix); transformMatrix.MapRect(_pathFillBounds); transformMatrix.MapRect(_pathStrokeBounds); if (_fill != null) { _drawable.Paint.SetStyle(Paint.Style.Fill); if (_fill is GradientBrush fillGradientBrush) { if (fillGradientBrush is LinearGradientBrush linearGradientBrush) { _fillShader = CreateLinearGradient(linearGradientBrush, _pathFillBounds); } if (fillGradientBrush is RadialGradientBrush radialGradientBrush) { _fillShader = CreateRadialGradient(radialGradientBrush, _pathFillBounds); } _drawable.Paint.SetShader(_fillShader); } else { AColor fillColor = Colors.Transparent.ToAndroid(); if (_fill is SolidColorBrush solidColorBrush && solidColorBrush.Color != null) { fillColor = solidColorBrush.Color.ToAndroid(); } _drawable.Paint.Color = fillColor; } _drawable.Draw(canvas); _drawable.Paint.SetShader(null); } if (_stroke != null) { _drawable.Paint.SetStyle(Paint.Style.Stroke); if (_stroke is GradientBrush strokeGradientBrush) { UpdatePathStrokeBounds(); if (strokeGradientBrush is LinearGradientBrush linearGradientBrush) { _strokeShader = CreateLinearGradient(linearGradientBrush, _pathStrokeBounds); } if (strokeGradientBrush is RadialGradientBrush radialGradientBrush) { _strokeShader = CreateRadialGradient(radialGradientBrush, _pathStrokeBounds); } _drawable.Paint.SetShader(_strokeShader); } else { AColor strokeColor = Graphics.Colors.Transparent.ToAndroid(); if (_stroke is SolidColorBrush solidColorBrush && solidColorBrush.Color != null) { strokeColor = solidColorBrush.Color.ToAndroid(); } _drawable.Paint.Color = strokeColor; } _drawable.Draw(canvas); _drawable.Paint.SetShader(null); } AMatrix inverseTransformMatrix = new AMatrix(); transformMatrix.Invert(inverseTransformMatrix); _path.Transform(inverseTransformMatrix); inverseTransformMatrix.MapRect(_pathFillBounds); inverseTransformMatrix.MapRect(_pathStrokeBounds); }
private RectF GetDisplayRect(Matrix matrix) { ImageView imageView = GetImageView(); if (null != imageView) { Android.Graphics.Drawables.Drawable d = imageView.Drawable; if (null != d) { mDisplayRect.Set(0, 0, d.IntrinsicWidth, d.IntrinsicHeight); matrix.MapRect(mDisplayRect); return mDisplayRect; } } return null; }
public override void Draw(Canvas canvas) { if (_path == null) { return; } AMatrix transformMatrix = CreateMatrix(); _path.Transform(transformMatrix); transformMatrix.MapRect(_pathFillBounds); transformMatrix.MapRect(_pathStrokeBounds); if (_fill != null) { this.Paint.SetStyle(_strokeWidth > 0 ? Paint.Style.Fill : Paint.Style.FillAndStroke); if (_fill is GradientBrush fillGradientBrush) { if (fillGradientBrush is LinearGradientBrush linearGradientBrush) { _fillShader = CreateLinearGradient(linearGradientBrush, _pathFillBounds); } if (fillGradientBrush is RadialGradientBrush radialGradientBrush) { _fillShader = CreateRadialGradient(radialGradientBrush, _pathFillBounds); } this.Paint.SetShader(_fillShader); } else { AColor fillColor = Color.Default.ToAndroid(); if (_fill is SolidColorBrush solidColorBrush && solidColorBrush.Color != Color.Default) { fillColor = solidColorBrush.Color.ToAndroid(); } this.Paint.Color = fillColor; } base.Draw(canvas); this.Paint.SetShader(null); } if (_stroke != null && _strokeWidth > 0) { this.Paint.SetStyle(Paint.Style.Stroke); if (_stroke is GradientBrush strokeGradientBrush) { if (strokeGradientBrush is LinearGradientBrush linearGradientBrush) { _strokeShader = CreateLinearGradient(linearGradientBrush, _pathStrokeBounds); } if (strokeGradientBrush is RadialGradientBrush radialGradientBrush) { _strokeShader = CreateRadialGradient(radialGradientBrush, _pathStrokeBounds); } this.Paint.SetShader(_strokeShader); } else { AColor strokeColor = Color.Default.ToAndroid(); if (_stroke is SolidColorBrush solidColorBrush && solidColorBrush.Color != Color.Default) { strokeColor = solidColorBrush.Color.ToAndroid(); } this.Paint.Color = strokeColor; } base.Draw(canvas); this.Paint.SetShader(null); } AMatrix inverseTransformMatrix = new AMatrix(); transformMatrix.Invert(inverseTransformMatrix); _path.Transform(inverseTransformMatrix); inverseTransformMatrix.MapRect(_pathFillBounds); inverseTransformMatrix.MapRect(_pathStrokeBounds); }
droidGraphics.LinearGradient CreateLinearGradient(LinearGradientBrush xamBrush, droidGraphics.RectF pathBounds, droidGraphics.Matrix stretchMatrix) { if (Path == null) { return(null); } int[] colors = new int[xamBrush.GradientStops.Count]; float[] offsets = new float[xamBrush.GradientStops.Count]; for (int index = 0; index < xamBrush.GradientStops.Count; index++) { colors[index] = ConvertColor(xamBrush.GradientStops[index].Color); offsets[index] = (float)xamBrush.GradientStops[index].Offset; } droidGraphics.Shader.TileMode tilemode = droidGraphics.Shader.TileMode.Clamp; switch (xamBrush.SpreadMethod) { case GradientSpreadMethod.Pad: tilemode = droidGraphics.Shader.TileMode.Clamp; break; case GradientSpreadMethod.Refect: tilemode = droidGraphics.Shader.TileMode.Mirror; break; case GradientSpreadMethod.Repeat: tilemode = droidGraphics.Shader.TileMode.Repeat; break; } // pathBounds has already been stretched using (droidGraphics.RectF xformedBounds = new droidGraphics.RectF(pathBounds)) { if (xamBrush.Transform != null) { // But the brush transform offsets needs to be stretched droidGraphics.Matrix transform = xamBrush.Transform.GetNativeObject() as droidGraphics.Matrix; float[] stretchValues = new float[9]; stretchMatrix.GetValues(stretchValues); float[] transformValues = new float[9]; transform.GetValues(transformValues); // Scale x-offset by stretch transformValues[2] *= stretchValues[0]; // Scale y-offset by stretch transformValues[5] *= stretchValues[4]; using (droidGraphics.Matrix matx = new droidGraphics.Matrix()) { matx.SetValues(transformValues); float[] a2 = new float[9]; matx.GetValues(a2); matx.MapRect(xformedBounds); } } return(new droidGraphics.LinearGradient((float)xamBrush.StartPoint.X * xformedBounds.Width() + xformedBounds.Left, (float)xamBrush.StartPoint.Y * xformedBounds.Height() + xformedBounds.Top, (float)xamBrush.EndPoint.X * xformedBounds.Width() + xformedBounds.Left, (float)xamBrush.EndPoint.Y * xformedBounds.Height() + xformedBounds.Top, colors, offsets, tilemode)); } }
protected override void OnDraw(droidGraphics.Canvas canvas) { base.OnDraw(canvas); // Prevent clipping of negative coordinates Step 2 // TODO: Is there a better place / way to do this? if (Parent != null) { if (Parent.Parent as global::Android.Views.ViewGroup != null) { (Parent.Parent as global::Android.Views.ViewGroup).SetClipChildren(false); } } if (Path == null) { return; } droidGraphics.Matrix stretchMatrix = ComputeStretchMatrix(); Path.Transform(stretchMatrix); stretchMatrix.MapRect(pathFillBounds); stretchMatrix.MapRect(pathStrokeBounds); // Special processing for Rectangle because RadiusX, RadiusY can't be subject to Stretch transform if (this is RectangleDrawableView) { float radiusX = (this as RectangleDrawableView).RadiusX; float radiusY = (this as RectangleDrawableView).RadiusY; Path.Reset(); Path.AddRoundRect(pathFillBounds, radiusX, radiusY, droidGraphics.Path.Direction.Cw); // TODO: is the direction right? } if (fill != null) { drawable.Paint.SetStyle(droidGraphics.Paint.Style.Fill); if (fill is Color) { Color fillColor = (Color)fill; drawable.Paint.SetARGB((int)(255 * fillColor.A), (int)(255 * fillColor.R), (int)(255 * fillColor.G), (int)(255 * fillColor.B)); } else if (fillShader == null) { if (fill is LinearGradientBrush) { fillShader = CreateLinearGradient(fill as LinearGradientBrush, pathFillBounds, stretchMatrix); } else if (fill is ImageBrush) { fillShader = CreateBitmapShader(fill as ImageBrush); } drawable.Paint.SetShader(fillShader); } drawable.Draw(canvas); drawable.Paint.SetShader(null); } if (stroke != null) { drawable.Paint.SetStyle(droidGraphics.Paint.Style.Stroke); if (stroke is Color) { Color strokeColor = (Color)stroke; drawable.Paint.SetARGB((int)(255 * strokeColor.A), (int)(255 * strokeColor.R), (int)(255 * strokeColor.G), (int)(255 * strokeColor.B)); } else if (strokeShader == null) { if (stroke is LinearGradientBrush) { strokeShader = CreateLinearGradient(stroke as LinearGradientBrush, pathStrokeBounds, stretchMatrix); } else if (stroke is ImageBrush) { strokeShader = CreateBitmapShader(stroke as ImageBrush); } drawable.Paint.SetShader(strokeShader); } drawable.Draw(canvas); drawable.Paint.SetShader(null); } // Return everything back to its pre-stretched state droidGraphics.Matrix inverseStretchMatrix = new droidGraphics.Matrix(); stretchMatrix.Invert(inverseStretchMatrix); Path.Transform(inverseStretchMatrix); inverseStretchMatrix.MapRect(pathFillBounds); inverseStretchMatrix.MapRect(pathStrokeBounds); }