/// <summary> /// Draws a geometry. /// </summary> /// <param name="brush">The fill brush.</param> /// <param name="pen">The stroke pen.</param> /// <param name="geometry">The geometry.</param> public void DrawGeometry(IBrush?brush, IPen?pen, Geometry geometry) { if (geometry.PlatformImpl is not null) { DrawGeometry(brush, pen, geometry.PlatformImpl); } }
/// <summary> /// Determines if this draw operation equals another. /// </summary> /// <param name="transform">The transform of the other draw operation.</param> /// <param name="brush">The fill of the other draw operation.</param> /// <param name="pen">The stroke of the other draw operation.</param> /// <param name="geometry">The geometry of the other draw operation.</param> /// <returns>True if the draw operations are the same, otherwise false.</returns> /// <remarks> /// The properties of the other draw operation are passed in as arguments to prevent /// allocation of a not-yet-constructed draw operation object. /// </remarks> public bool Equals(Matrix transform, IBrush?brush, IPen?pen, IGeometryImpl geometry) { return(transform == Transform && Equals(brush, Brush) && Equals(Pen, pen) && Equals(geometry, Geometry)); }
public bool Equals(Matrix transform, IBrush?brush, IPen?pen, Rect rect) { return(transform == Transform && Equals(brush, Brush) && Equals(Pen, pen) && rect.Equals(Rect)); }
/// <summary> /// Determines if this draw operation equals another. /// </summary> /// <param name="transform">The transform of the other draw operation.</param> /// <param name="brush">The fill of the other draw operation.</param> /// <param name="pen">The stroke of the other draw operation.</param> /// <param name="rect">The rectangle of the other draw operation.</param> /// <param name="boxShadows">The box shadow parameters of the other draw operation</param> /// <returns>True if the draw operations are the same, otherwise false.</returns> /// <remarks> /// The properties of the other draw operation are passed in as arguments to prevent /// allocation of a not-yet-constructed draw operation object. /// </remarks> public bool Equals(Matrix transform, IBrush?brush, IPen?pen, RoundedRect rect, BoxShadows boxShadows) { return(transform == Transform && Equals(brush, Brush) && Equals(Pen, pen) && BoxShadows.Equals(boxShadows) && rect.Equals(Rect)); }
/// <summary> /// Draws a geometry. /// </summary> /// <param name="brush">The fill brush.</param> /// <param name="pen">The stroke pen.</param> /// <param name="geometry">The geometry.</param> public void DrawGeometry(IBrush?brush, IPen?pen, IGeometryImpl geometry) { _ = geometry ?? throw new ArgumentNullException(nameof(geometry)); if (brush != null || PenIsVisible(pen)) { PlatformImpl.DrawGeometry(brush, pen, geometry); } }
/// <summary> /// Initializes a new instance of the <see cref="GeometryNode"/> class. /// </summary> /// <param name="transform">The transform.</param> /// <param name="brush">The fill brush.</param> /// <param name="pen">The stroke pen.</param> /// <param name="geometry">The geometry.</param> /// <param name="aux">Auxiliary data required to draw the brush.</param> public GeometryNode(Matrix transform, IBrush?brush, IPen?pen, IGeometryImpl geometry, IDisposable?aux) : base(geometry.GetRenderBounds(pen).CalculateBoundsWithLineCaps(pen), transform, aux) { Transform = transform; Brush = brush?.ToImmutable(); Pen = pen?.ToImmutable(); Geometry = geometry; }
void RenderCore(DrawingContext context, IBrush?background, IBrush?borderBrush, BoxShadows boxShadows, double borderDashOffset, PenLineCap borderLineCap, PenLineJoin borderLineJoin, AvaloniaList <double>?borderDashArray) { if (_useComplexRendering) { var backgroundGeometry = _backgroundGeometryCache; if (backgroundGeometry != null) { context.DrawGeometry(background, null, backgroundGeometry); } var borderGeometry = _borderGeometryCache; if (borderGeometry != null) { context.DrawGeometry(borderBrush, null, borderGeometry); } } else { var borderThickness = _borderThickness.Top; IPen?pen = null; ImmutableDashStyle?dashStyle = null; if (borderDashArray != null && borderDashArray.Count > 0) { dashStyle = new ImmutableDashStyle(borderDashArray, borderDashOffset); } if (borderBrush != null && borderThickness > 0) { pen = new ImmutablePen( borderBrush.ToImmutable(), borderThickness, dashStyle, borderLineCap, borderLineJoin); } var rect = new Rect(_size); if (!MathUtilities.IsZero(borderThickness)) { rect = rect.Deflate(borderThickness * 0.5); } var rrect = new RoundedRect(rect, _cornerRadius.TopLeft, _cornerRadius.TopRight, _cornerRadius.BottomRight, _cornerRadius.BottomLeft); context.PlatformImpl.DrawRectangle(background, pen, rrect, boxShadows); } }
public EllipseNode( Matrix transform, IBrush?brush, IPen?pen, Rect rect, IDisposable?aux = null) : base(rect.Inflate(pen?.Thickness ?? 0), transform, aux) { Transform = transform; Brush = brush?.ToImmutable(); Pen = pen?.ToImmutable(); Rect = rect; }
public void DrawEllipse(IBrush?brush, IPen?pen, Rect rect) { var next = NextDrawAs <EllipseNode>(); if (next == null || !next.Item.Equals(Transform, brush, pen, rect)) { Add(new EllipseNode(Transform, brush, pen, rect, CreateChildScene(brush))); } else { ++_drawOperationindex; } }
/// <inheritdoc/> public void DrawGeometry(IBrush?brush, IPen?pen, IGeometryImpl geometry) { var next = NextDrawAs <GeometryNode>(); if (next == null || !next.Item.Equals(Transform, brush, pen, geometry)) { Add(new GeometryNode(Transform, brush, pen, geometry, CreateChildScene(brush))); } else { ++_drawOperationindex; } }
/// <summary> /// Initializes a new instance of the <see cref="GeometryNode"/> class. /// </summary> /// <param name="transform">The transform.</param> /// <param name="brush">The fill brush.</param> /// <param name="pen">The stroke pen.</param> /// <param name="geometry">The geometry.</param> /// <param name="childScenes">Child scenes for drawing visual brushes.</param> public GeometryNode(Matrix transform, IBrush?brush, IPen?pen, IGeometryImpl geometry, IDictionary <IVisual, Scene>?childScenes = null) : base(geometry.GetRenderBounds(pen).CalculateBoundsWithLineCaps(pen), transform) { Transform = transform; Brush = brush?.ToImmutable(); Pen = pen?.ToImmutable(); Geometry = geometry; ChildScenes = childScenes; }
public EllipseNode( Matrix transform, IBrush?brush, IPen?pen, Rect rect, IDictionary <IVisual, Scene>?childScenes = null) : base(rect.Inflate(pen?.Thickness ?? 0), transform) { Transform = transform; Brush = brush?.ToImmutable(); Pen = pen?.ToImmutable(); Rect = rect; ChildScenes = childScenes; }
/// <inheritdoc/> public void DrawRectangle(IBrush?brush, IPen?pen, RoundedRect rect, BoxShadows boxShadows = default) { var next = NextDrawAs <RectangleNode>(); if (next == null || !next.Item.Equals(Transform, brush, pen, rect, boxShadows)) { Add(new RectangleNode(Transform, brush, pen, rect, boxShadows, CreateChildScene(brush))); } else { ++_drawOperationindex; } }
/// <summary> /// Draws an ellipse with the specified Brush and Pen. /// </summary> /// <param name="brush">The brush used to fill the ellipse, or <c>null</c> for no fill.</param> /// <param name="pen">The pen used to stroke the ellipse, or <c>null</c> for no stroke.</param> /// <param name="center">The location of the center of the ellipse.</param> /// <param name="radiusX">The horizontal radius of the ellipse.</param> /// <param name="radiusY">The vertical radius of the ellipse.</param> /// <remarks> /// The brush and the pen can both be null. If the brush is null, then no fill is performed. /// If the pen is null, then no stoke is performed. If both the pen and the brush are null, then the drawing is not visible. /// </remarks> public void DrawEllipse(IBrush?brush, IPen?pen, Point center, double radiusX, double radiusY) { if (brush == null && !PenIsVisible(pen)) { return; } var originX = center.X - radiusX; var originY = center.Y - radiusY; var width = radiusX * 2; var height = radiusY * 2; PlatformImpl.DrawEllipse(brush, pen, new Rect(originX, originY, width, height)); }
/// <summary> /// Initializes a new instance of the <see cref="RectangleNode"/> class. /// </summary> /// <param name="transform">The transform.</param> /// <param name="brush">The fill brush.</param> /// <param name="pen">The stroke pen.</param> /// <param name="rect">The rectangle to draw.</param> /// <param name="boxShadows">The box shadow parameters</param> /// <param name="aux">Auxiliary data required to draw the brush.</param> public RectangleNode( Matrix transform, IBrush?brush, IPen?pen, RoundedRect rect, BoxShadows boxShadows, IDisposable?aux = null) : base(boxShadows.TransformBounds(rect.Rect).Inflate((pen?.Thickness ?? 0) / 2), transform, aux) { Transform = transform; Brush = brush?.ToImmutable(); Pen = pen?.ToImmutable(); Rect = rect; BoxShadows = boxShadows; }
/// <summary> /// Initializes a new instance of the <see cref="RectangleNode"/> class. /// </summary> /// <param name="transform">The transform.</param> /// <param name="brush">The fill brush.</param> /// <param name="pen">The stroke pen.</param> /// <param name="rect">The rectangle to draw.</param> /// <param name="boxShadows">The box shadow parameters</param> /// <param name="childScenes">Child scenes for drawing visual brushes.</param> public RectangleNode( Matrix transform, IBrush?brush, IPen?pen, RoundedRect rect, BoxShadows boxShadows, IDictionary <IVisual, Scene>?childScenes = null) : base(boxShadows.TransformBounds(rect.Rect).Inflate((pen?.Thickness ?? 0) / 2), transform) { Transform = transform; Brush = brush?.ToImmutable(); Pen = pen?.ToImmutable(); Rect = rect; ChildScenes = childScenes; BoxShadows = boxShadows; }
public override void Dispose() { if (_isOpen) { _context.EndFigure(false); _isOpen = false; } _context.Dispose(); // Passing a null brush is a workaround for https://github.com/AvaloniaUI/Avalonia/issues/1419 IBrush?brush = Foreground?.ToSolidColorBrush() ?? _canvas.CurrentBrush; IPen? pen = null; if (_canvas.CurrentStyle == PaintStyle.Stroke) { pen = new Pen(brush); brush = null; } _canvas.DrawingContext.DrawGeometry(brush, pen, _path); }
/// <inheritdoc/> public bool Equals(IPen?other) { if (ReferenceEquals(this, other)) { return(true); } else if (other is null) { return(false); } return(EqualityComparer <IBrush> .Default.Equals(Brush, other.Brush) && Thickness == other.Thickness && EqualityComparer <IDashStyle> .Default.Equals(DashStyle, other.DashStyle) && LineCap == other.LineCap && LineJoin == other.LineJoin && MiterLimit == other.MiterLimit); }
/// <summary> /// Draws a rectangle with the specified Brush and Pen. /// </summary> /// <param name="brush">The brush used to fill the rectangle, or <c>null</c> for no fill.</param> /// <param name="pen">The pen used to stroke the rectangle, or <c>null</c> for no stroke.</param> /// <param name="rect">The rectangle bounds.</param> /// <param name="radiusX">The radius in the X dimension of the rounded corners. /// This value will be clamped to the range of 0 to Width/2 /// </param> /// <param name="radiusY">The radius in the Y dimension of the rounded corners. /// This value will be clamped to the range of 0 to Height/2 /// </param> /// <param name="boxShadows">Box shadow effect parameters</param> /// <remarks> /// The brush and the pen can both be null. If the brush is null, then no fill is performed. /// If the pen is null, then no stoke is performed. If both the pen and the brush are null, then the drawing is not visible. /// </remarks> public void DrawRectangle(IBrush?brush, IPen?pen, Rect rect, double radiusX = 0, double radiusY = 0, BoxShadows boxShadows = default) { if (brush == null && !PenIsVisible(pen)) { return; } if (!MathUtilities.IsZero(radiusX)) { radiusX = Math.Min(radiusX, rect.Width / 2); } if (!MathUtilities.IsZero(radiusY)) { radiusY = Math.Min(radiusY, rect.Height / 2); } PlatformImpl.DrawRectangle(brush, pen, new RoundedRect(rect, radiusX, radiusY), boxShadows); }
/// <summary> /// Calculates the bounds of a given geometry with respect to the pens <see cref="IPen.LineCap"/> /// </summary> /// <param name="originalBounds">The calculated bounds without <see cref="IPen.LineCap"/>s</param> /// <param name="pen">The pen with information about the <see cref="IPen.LineCap"/>s</param> /// <returns></returns> public static Rect CalculateBoundsWithLineCaps(this Rect originalBounds, IPen?pen) { if (pen is null || MathUtilities.IsZero(pen.Thickness)) { return(originalBounds); } switch (pen.LineCap) { case PenLineCap.Flat: return(originalBounds); case PenLineCap.Round: return(originalBounds.Inflate(pen.Thickness / 2)); case PenLineCap.Square: return(originalBounds.Inflate(pen.Thickness)); default: throw new ArgumentOutOfRangeException(); } }
private static bool PenIsVisible(IPen?pen) { return(pen?.Brush != null && pen.Thickness > 0); }