protected void CreatePathShape() { if (Path != null && !drawable.Bounds.IsEmpty) { drawable.Shape = new PathShape(Path, drawable.Bounds.Width(), drawable.Bounds.Height()); } else { drawable.Shape = null; } // Find the path bounds. // Can't use ComputeFounds on the path because that includes Bezier control points. // Need to obtain the fill path first. if (Path != null) { using (droidGraphics.Path fillPath = new droidGraphics.Path()) { drawable.Paint.StrokeWidth = 0.01f; drawable.Paint.SetStyle(droidGraphics.Paint.Style.Stroke); drawable.Paint.GetFillPath(Path, fillPath); fillPath.ComputeBounds(pathFillBounds, false); drawable.Paint.StrokeWidth = strokeWidth; } } else { pathFillBounds.SetEmpty(); } fillShader = null; // really only necessary for LinearGradientBrush CalculatePathStrokeBounds(); }
public Shader createShader() { if(this.mShader != null) { return this.mShader; } if(!this.mSVGGradientStopsBuilt) { this.buildSVGGradientStopsArrays(); } Shader.TileMode tileMode = this.getTileMode(); if(this.mLinear) { float x1 =this.mSVGAttributes.getFloatAttribute(SVGConstants.ATTRIBUTE_X1, true, 0f); float x2 = this.mSVGAttributes.getFloatAttribute(SVGConstants.ATTRIBUTE_X2, true, 0f); float y1 = this.mSVGAttributes.getFloatAttribute(SVGConstants.ATTRIBUTE_Y1, true, 0f); float y2 = this.mSVGAttributes.getFloatAttribute(SVGConstants.ATTRIBUTE_Y2, true, 0f); this.mShader = new LinearGradient(x1, y1, x2, y2, this.mSVGGradientStopsColors, this.mSVGGradientStopsPositions, tileMode); } else { float centerX = this.mSVGAttributes.getFloatAttribute(SVGConstants.ATTRIBUTE_CENTER_X, true, 0f); float centerY = this.mSVGAttributes.getFloatAttribute(SVGConstants.ATTRIBUTE_CENTER_Y, true, 0f); float radius = this.mSVGAttributes.getFloatAttribute(SVGConstants.ATTRIBUTE_RADIUS, true, 0f); this.mShader = new RadialGradient(centerX, centerY, radius, this.mSVGGradientStopsColors, this.mSVGGradientStopsPositions, tileMode); } this.mMatrix = this.getTransform(); if (this.mMatrix != null) { this.mShader.SetLocalMatrix(this.mMatrix); } return this.mShader; }
public void SetStretch(Stretch stretch) { this.stretch = stretch; fillShader = null; strokeShader = null; Invalidate(); }
public SampleView (Context context) : base (context) { Focusable = true; Stream input = context.Resources.OpenRawResource (Resource.Drawable.app_sample_code); mBitmap = BitmapFactory.DecodeStream (input); mBitmap2 = mBitmap.ExtractAlpha (); mBitmap3 = Bitmap.CreateBitmap (200, 200, Bitmap.Config.Alpha8); DrawIntoBitmap (mBitmap3); mShader = new LinearGradient (0, 0, 100, 70, new int[] { Color.Red, Color.Green, Color.Blue }, null, Shader.TileMode.Mirror); }
// Set from above and when stroke width or style changes void CalculatePathStrokeBounds() { if (Path != null) { using (droidGraphics.Path strokePath = new droidGraphics.Path()) { drawable.Paint.SetStyle(droidGraphics.Paint.Style.Stroke); drawable.Paint.GetFillPath(Path, strokePath); strokePath.ComputeBounds(pathStrokeBounds, false); } } else { pathStrokeBounds.SetEmpty(); } strokeShader = null; // really only necessary of LinearGradientBrush Invalidate(); }
private void drawAlphaPanel(Canvas canvas) { /* * Will be drawn with hw acceleration, very fast. */ if(!mShowAlphaPanel || mAlphaRect == null || mAlphaPattern == null) return; RectF rect = mAlphaRect; if(BORDER_WIDTH_PX > 0){ //TODO: cross check the color byte[] byteArr = BitConverter.GetBytes (mBorderColor); mBorderPaint.Color = Color.Argb (byteArr [0], byteArr [1], byteArr [2], byteArr [3]); // mBorderPaint.Color = mBorderColor; canvas.DrawRect(rect.Left - BORDER_WIDTH_PX, rect.Top - BORDER_WIDTH_PX, rect.Right + BORDER_WIDTH_PX, rect.Bottom + BORDER_WIDTH_PX, mBorderPaint); } mAlphaPattern.Draw(canvas); float[] hsv = new float[]{mHue,mSat,mVal}; Color color = Color.HSVToColor(hsv); Color acolor = Color.HSVToColor(0, hsv); mAlphaShader = new LinearGradient(rect.Left, rect.Top, rect.Right, rect.Top, color, acolor, Android.Graphics.Shader.TileMode.Clamp); mAlphaPaint.SetShader(mAlphaShader); canvas.DrawRect(rect, mAlphaPaint); if(mAlphaSliderText != null && !mAlphaSliderText.Equals("")){ canvas.DrawText(mAlphaSliderText, rect.CenterX(), rect.CenterY() + 4 * mDensity, mAlphaTextPaint); } float rectWidth = 4 * mDensity / 2; Point p = alphaToPoint(mAlpha); RectF r = new RectF(); r.Left = p.X - rectWidth; r.Right = p.X + rectWidth; r.Top = rect.Top - RECTANGLE_TRACKER_OFFSET; r.Bottom = rect.Bottom + RECTANGLE_TRACKER_OFFSET; canvas.DrawRoundRect(r, 2, 2, mHueAlphaTrackerPaint); }
private void drawHuePanel(Canvas canvas){ /* * Drawn with hw acceleration, very fast. */ //long start = SystemClock.elapsedRealtime(); RectF rect = mHueRect; if(BORDER_WIDTH_PX > 0) { //TODO: Cross check the color setting byte[] byteArr = BitConverter.GetBytes (mBorderColor); mBorderPaint.Color = Color.Argb (byteArr [0], byteArr [1], byteArr [2], byteArr [3]); // mBorderPaint.Color = mBorderColor; canvas.DrawRect(rect.Left - BORDER_WIDTH_PX, rect.Top - BORDER_WIDTH_PX, rect.Right + BORDER_WIDTH_PX, rect.Bottom + BORDER_WIDTH_PX, mBorderPaint); } if (mHueShader == null) { //The hue shader has either not yet been created or the view has been resized. mHueShader = new LinearGradient(0, 0, 0, rect.Height(), buildHueColorArray(), null, Android.Graphics.Shader.TileMode.Clamp); mHuePaint.SetShader(mHueShader); } canvas.DrawRect(rect, mHuePaint); float rectHeight = 4 * mDensity / 2; Point p = hueToPoint(mHue); RectF r = new RectF(); r.Left = rect.Left - RECTANGLE_TRACKER_OFFSET; r.Right = rect.Right + RECTANGLE_TRACKER_OFFSET; r.Top = p.Y - rectHeight; r.Bottom = p.Y + rectHeight; canvas.DrawRoundRect(r, 2, 2, mHueAlphaTrackerPaint); //Log.d("mColorPicker", "Draw Time Hue: " + (SystemClock.elapsedRealtime() - start) + "ms"); }
protected override void Dispose(bool disposing) { if (disposing) { if (null != _satValPaint) { _satValPaint.Dispose(); _satValPaint = null; } if (null != _satValTrackerPaint) { _satValTrackerPaint.Dispose(); _satValTrackerPaint = null; } if (null != _huePaint) { _huePaint.Dispose(); _huePaint = null; } if (null != _hueTrackerPaint) { _hueTrackerPaint.Dispose(); _hueTrackerPaint = null; } if (null != _alphaPaint) { _alphaPaint.Dispose(); _alphaPaint = null; } if (null != _alphaTextPaint) { _alphaTextPaint.Dispose(); _alphaTextPaint = null; } if (null != _hueShader) { _hueShader.Dispose(); _hueShader = null; } if (null != _borderPaint) { _borderPaint.Dispose(); _borderPaint = null; } if (null != _valShader) { _valShader.Dispose(); _valShader = null; } if (null != _satShader) { _satShader.Dispose(); _satShader = null; } if (null != _alphaShader) { _alphaShader.Dispose(); _alphaShader = null; } if (null != _alphaPattern) { _alphaPattern.Dispose(); _alphaPattern = null; } } GC.Collect(); base.Dispose(disposing); }
// Methods called from ShapeRenderer public void SetFillColor(object color) { fill = color; fillShader = null; Invalidate(); }
private void drawHuePanel(Canvas canvas) { /* * Drawn with hw acceleration, very fast. */ //long start = SystemClock.elapsedRealtime(); RectF rect = mHueRect; if (BORDER_WIDTH_PX > 0) { mBorderPaint.Color = new Color((int)mBorderColor); canvas.DrawRect(rect.Left - BORDER_WIDTH_PX, rect.Top - BORDER_WIDTH_PX, rect.Right + BORDER_WIDTH_PX, rect.Bottom + BORDER_WIDTH_PX, mBorderPaint); } if (mHueShader == null) { //The hue shader has either not yet been created or the view has been resized. mHueShader = new LinearGradient(0, 0, 0, rect.Height(), buildHueColorArray(), null, Shader.TileMode.Clamp); mHuePaint.SetShader(mHueShader); } canvas.DrawRect(rect, mHuePaint); float rectHeight = 4 * mDensity / 2; Point p = hueToPoint(mHue); RectF r = new RectF { Left = rect.Left - RECTANGLE_TRACKER_OFFSET, Right = rect.Right + RECTANGLE_TRACKER_OFFSET, Top = p.Y - rectHeight, Bottom = p.Y + rectHeight }; canvas.DrawRoundRect(r, 2, 2, mHueAlphaTrackerPaint); //Log.d("mColorPicker", "Draw Time Hue: " + (SystemClock.elapsedRealtime() - start) + "ms"); }
private void DrawSatValPanel(Canvas canvas) { #if __ANDROID_11__ if (Android.OS.Build.VERSION.SdkInt > Android.OS.BuildVersionCodes.Honeycomb) { RootView.SetLayerType(LayerType.Software, null); } #endif var rect = _satValRect; if(BorderWidthPx > 0){ _borderPaint.Color = _borderColor; canvas.DrawRect(_drawingRect.Left, _drawingRect.Top, rect.Right + BorderWidthPx, rect.Bottom + BorderWidthPx, _borderPaint); } if (_valShader == null) { _valShader = new LinearGradient(rect.Left, rect.Top, rect.Left, rect.Bottom, Color.Argb(255,255,255,255), Color.Argb(255,0,0,0), Shader.TileMode.Clamp); } var rgb = ColorUtils.ColorFromHSV(_hue/360f,1f,1f); using (_satShader = new LinearGradient(rect.Left, rect.Top, rect.Right, rect.Top, Color.Argb(255,255,255,255), rgb, Shader.TileMode.Clamp)) { var mShader = new ComposeShader(_valShader, _satShader, PorterDuff.Mode.Multiply); _satValPaint.SetShader(mShader); canvas.DrawRect(rect, _satValPaint); } var p = SatValToPoint(_sat, _val); _satValTrackerPaint.Color = Color.Argb(255,0,0,0); canvas.DrawCircle(p.X, p.Y, _paletteCircleTrackerRadius - 1f * _density, _satValTrackerPaint); _satValTrackerPaint.Color = Color.Argb(255, 221, 221, 221); canvas.DrawCircle(p.X, p.Y, _paletteCircleTrackerRadius, _satValTrackerPaint); }
private void DrawSatValPanel(Canvas canvas) { var rect = _satValRect; if(BorderWidthPx > 0){ _borderPaint.Color = _borderColor; canvas.DrawRect(_drawingRect.Left, _drawingRect.Top, rect.Right + BorderWidthPx, rect.Bottom + BorderWidthPx, _borderPaint); } if (_valShader == null) { _valShader = new LinearGradient(rect.Left, rect.Top, rect.Left, rect.Bottom, Color.Argb(255,255,255,255), Color.Argb(255,0,0,0), Shader.TileMode.Clamp); } var rgb = ColorUtils.ColorFromHSV(_hue/360f,1f,1f); using (_satShader = new LinearGradient(rect.Left, rect.Top, rect.Right, rect.Top, Color.Argb(255,255,255,255), rgb, Shader.TileMode.Clamp)) { var mShader = new ComposeShader(_valShader, _satShader, PorterDuff.Mode.Multiply); _satValPaint.SetShader(mShader); canvas.DrawRect(rect, _satValPaint); } var p = SatValToPoint(_sat, _val); _satValTrackerPaint.Color = Color.Argb(255,0,0,0); canvas.DrawCircle(p.X, p.Y, _paletteCircleTrackerRadius - 1f * _density, _satValTrackerPaint); _satValTrackerPaint.Color = Color.Argb(255, 221, 221, 221); canvas.DrawCircle(p.X, p.Y, _paletteCircleTrackerRadius, _satValTrackerPaint); }
public void SetStrokeColor(object color) { stroke = color; strokeShader = null; Invalidate(); }
/** * Set if the user is allowed to adjust the alpha panel. Default is false. * If it is set to false no alpha will be set. * @param visible */ public void setAlphaSliderVisible(bool visible) { if (mShowAlphaPanel != visible) { mShowAlphaPanel = visible; /* * Reset all shader to force a recreation. * Otherwise they will not look right after * the size of the view has changed. */ mValShader = null; mSatShader = null; mHueShader = null; ; RequestLayout(); } }
private void DrawHuePanel(Canvas canvas) { var rect = _hueRect; if (BorderWidthPx > 0) { _borderPaint.Color = _borderColor; canvas.DrawRect(rect.Left - BorderWidthPx, rect.Top - BorderWidthPx, rect.Right + BorderWidthPx, rect.Bottom + BorderWidthPx, _borderPaint); } if (_hueShader == null) { using(_hueShader = new LinearGradient(rect.Left, rect.Top, rect.Left, rect.Bottom, BuildHueColorArray(), null, Shader.TileMode.Clamp)) _huePaint.SetShader(_hueShader); } canvas.DrawRect(rect, _huePaint); var rectHeight = 4 * _density / 2; var p = HueToPoint(_hue); var r = new RectF { Left = rect.Left - _rectangleTrackerOffset, Right = rect.Right + _rectangleTrackerOffset, Top = p.Y - rectHeight, Bottom = p.Y + rectHeight }; canvas.DrawRoundRect(r, 2, 2, _hueTrackerPaint); }
protected override void OnSizeChanged(int w, int h, int oldw, int oldh) { base.OnSizeChanged(w, h, oldw, oldh); mDrawingRect = new RectF(); mDrawingRect.Left = mDrawingOffset + PaddingLeft; mDrawingRect.Right = w - mDrawingOffset - PaddingRight; mDrawingRect.Top = mDrawingOffset + PaddingTop; mDrawingRect.Bottom = h - mDrawingOffset - PaddingBottom; //The need to be recreated because they depend on the size of the view. mValShader = null; mSatShader = null; mHueShader = null; ; setUpSatValRect(); setUpHueRect(); setUpAlphaRect(); }
private void DrawAlphaPanel(Canvas canvas){ if(!_showAlphaPanel || _alphaRect == null || _alphaPattern == null) return; var rect = _alphaRect; if (BorderWidthPx > 0) { _borderPaint.Color = _borderColor; canvas.DrawRect(rect.Left - BorderWidthPx, rect.Top - BorderWidthPx, rect.Right + BorderWidthPx, rect.Bottom + BorderWidthPx, _borderPaint); } _alphaPattern.Draw(canvas); var color = ColorUtils.ColorFromHSV(_hue/360f,_sat,_val); var acolor = ColorUtils.ColorFromHSV(_hue/360f, _sat, _val, 0); using (_alphaShader = new LinearGradient(rect.Left, rect.Top, rect.Right, rect.Top, color, acolor, Shader.TileMode.Clamp)) { _alphaPaint.SetShader(_alphaShader); canvas.DrawRect(rect, _alphaPaint); } if(!string.IsNullOrEmpty(_alphaSliderText)){ canvas.DrawText(_alphaSliderText, rect.CenterX(), rect.CenterY() + 4 * _density, _alphaTextPaint); } float rectWidth = 4 * _density / 2; var p = AlphaToPoint(_alpha); var r = new RectF { Left = p.X - rectWidth, Right = p.X + rectWidth, Top = rect.Top - _rectangleTrackerOffset, Bottom = rect.Bottom + _rectangleTrackerOffset }; canvas.DrawRoundRect(r, 2, 2, _hueTrackerPaint); }
private void drawSatValPanel(Canvas canvas) { /* * Draw time for this code without using bitmap cache and hardware acceleration was around 20ms. * Now with the bitmap cache and the ability to use hardware acceleration we are down at 1ms as long as the hue isn't changed. * If the hue is changed we the sat/val rectangle will be rendered in software and it takes around 10ms. * But since the rest of the view will be rendered in hardware the performance gain is big! */ RectF rect = mSatValRect; if (BORDER_WIDTH_PX > 0) { mBorderPaint.Color = new Color((int)mBorderColor); canvas.DrawRect(mDrawingRect.Left, mDrawingRect.Top, rect.Right + BORDER_WIDTH_PX, rect.Bottom + BORDER_WIDTH_PX, mBorderPaint); } if (mValShader == null) { //Black gradient has either not been created or the view has been resized. uint startColor = 0xFFFFFFFF; uint endColor = 0xFF000000; mValShader = new LinearGradient(rect.Left, rect.Top, rect.Left, rect.Bottom, new Color((int)startColor), new Color((int)endColor), Shader.TileMode.Clamp); } //If the hue has changed we need to recreate the cache. if (mSatValBackgroundCache == null || mSatValBackgroundCache.value != mHue) { if (mSatValBackgroundCache == null) { mSatValBackgroundCache = new BitmapCache(); } //We create our bitmap in the cache if it doesn't exist. if (mSatValBackgroundCache.bitmap == null) { mSatValBackgroundCache.bitmap = Bitmap.CreateBitmap((int)rect.Width(), (int)rect.Height(), Bitmap.Config.Argb8888); } //We create the canvas once so we can draw on our bitmap and the hold on to it. if (mSatValBackgroundCache.canvas == null) { mSatValBackgroundCache.canvas = new Canvas(mSatValBackgroundCache.bitmap); } int rgb = Color.HSVToColor(new float[] { mHue, 1f, 1f }); uint startColor = 0xFFFFFFFF; mSatShader = new LinearGradient(rect.Left, rect.Top, rect.Right, rect.Top, new Color((int)startColor), new Color(rgb), Shader.TileMode.Clamp); ComposeShader mShader = new ComposeShader(mValShader, mSatShader, PorterDuff.Mode.Multiply); mSatValPaint.SetShader(mShader); //ly we draw on our canvas, the result will be stored in our bitmap which is already in the cache. //Since this is drawn on a canvas not rendered on screen it will automatically not be using the hardware acceleration. //And this was the code that wasn't supported by hardware acceleration which mean there is no need to turn it of anymore. //The rest of the view will still be hardware accelerated!! mSatValBackgroundCache.canvas.DrawRect(0, 0, mSatValBackgroundCache.bitmap.Width, mSatValBackgroundCache.bitmap.Height, mSatValPaint); //We set the hue value in our cache to which hue it was drawn with, //then we know that if it hasn't changed we can reuse our cached bitmap. mSatValBackgroundCache.value = mHue; } //We draw our bitmap from the cached, if the hue has changed //then it was just recreated otherwise the old one will be used. canvas.DrawBitmap(mSatValBackgroundCache.bitmap, null, rect, null); Point p = satValToPoint(mSat, mVal); mSatValTrackerPaint.Color = Color.Black; canvas.DrawCircle(p.X, p.Y, PALETTE_CIRCLE_TRACKER_RADIUS - 1f * mDensity, mSatValTrackerPaint); mSatValTrackerPaint.Color = Color.LightGray; canvas.DrawCircle(p.X, p.Y, PALETTE_CIRCLE_TRACKER_RADIUS, mSatValTrackerPaint); }
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); }