committed by
GitHub
26 changed files with 452 additions and 50 deletions
@ -0,0 +1,53 @@ |
|||
#nullable enable |
|||
|
|||
namespace Avalonia.Media |
|||
{ |
|||
/// <summary>
|
|||
/// Draws an image within a region defined by a <see cref="Rect"/>.
|
|||
/// </summary>
|
|||
public class ImageDrawing : Drawing |
|||
{ |
|||
/// <summary>
|
|||
/// Defines the <see cref="ImageSource"/> property.
|
|||
/// </summary>
|
|||
public static readonly StyledProperty<IImage?> ImageSourceProperty = |
|||
AvaloniaProperty.Register<ImageDrawing, IImage?>(nameof(ImageSource)); |
|||
|
|||
/// <summary>
|
|||
/// Defines the <see cref="Rect"/> property.
|
|||
/// </summary>
|
|||
public static readonly StyledProperty<Rect> RectProperty = |
|||
AvaloniaProperty.Register<ImageDrawing, Rect>(nameof(Rect)); |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the source of the image.
|
|||
/// </summary>
|
|||
public IImage? ImageSource |
|||
{ |
|||
get => GetValue(ImageSourceProperty); |
|||
set => SetValue(ImageSourceProperty, value); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets region in which the image is drawn.
|
|||
/// </summary>
|
|||
public Rect Rect |
|||
{ |
|||
get => GetValue(RectProperty); |
|||
set => SetValue(RectProperty, value); |
|||
} |
|||
|
|||
public override void Draw(DrawingContext context) |
|||
{ |
|||
var imageSource = ImageSource; |
|||
var rect = Rect; |
|||
|
|||
if (imageSource is object && !rect.IsEmpty) |
|||
{ |
|||
context.DrawImage(imageSource, rect); |
|||
} |
|||
} |
|||
|
|||
public override Rect GetBounds() => Rect; |
|||
} |
|||
} |
|||
@ -0,0 +1,103 @@ |
|||
using Avalonia.Media; |
|||
using Avalonia.Platform; |
|||
using Avalonia.Rendering.SceneGraph; |
|||
using Avalonia.Utilities; |
|||
using Avalonia.Visuals.Media.Imaging; |
|||
|
|||
namespace Avalonia.Benchmarks |
|||
{ |
|||
internal class NullDrawingContextImpl : IDrawingContextImpl |
|||
{ |
|||
public void Dispose() |
|||
{ |
|||
} |
|||
|
|||
public Matrix Transform { get; set; } |
|||
|
|||
public void Clear(Color color) |
|||
{ |
|||
} |
|||
|
|||
public void DrawBitmap(IRef<IBitmapImpl> source, double opacity, Rect sourceRect, Rect destRect, |
|||
BitmapInterpolationMode bitmapInterpolationMode = BitmapInterpolationMode.Default) |
|||
{ |
|||
} |
|||
|
|||
public void DrawBitmap(IRef<IBitmapImpl> source, IBrush opacityMask, Rect opacityMaskRect, Rect destRect) |
|||
{ |
|||
} |
|||
|
|||
public void DrawLine(IPen pen, Point p1, Point p2) |
|||
{ |
|||
} |
|||
|
|||
public void DrawGeometry(IBrush brush, IPen pen, IGeometryImpl geometry) |
|||
{ |
|||
} |
|||
|
|||
public void DrawRectangle(IBrush brush, IPen pen, RoundedRect rect, BoxShadows boxShadows = default) |
|||
{ |
|||
} |
|||
|
|||
public void DrawText(IBrush foreground, Point origin, IFormattedTextImpl text) |
|||
{ |
|||
} |
|||
|
|||
public void DrawGlyphRun(IBrush foreground, GlyphRun glyphRun) |
|||
{ |
|||
} |
|||
|
|||
public IDrawingContextLayerImpl CreateLayer(Size size) |
|||
{ |
|||
return null; |
|||
} |
|||
|
|||
public void PushClip(Rect clip) |
|||
{ |
|||
} |
|||
|
|||
public void PushClip(RoundedRect clip) |
|||
{ |
|||
} |
|||
|
|||
public void PopClip() |
|||
{ |
|||
} |
|||
|
|||
public void PushOpacity(double opacity) |
|||
{ |
|||
} |
|||
|
|||
public void PopOpacity() |
|||
{ |
|||
} |
|||
|
|||
public void PushOpacityMask(IBrush mask, Rect bounds) |
|||
{ |
|||
} |
|||
|
|||
public void PopOpacityMask() |
|||
{ |
|||
} |
|||
|
|||
public void PushGeometryClip(IGeometryImpl clip) |
|||
{ |
|||
} |
|||
|
|||
public void PopGeometryClip() |
|||
{ |
|||
} |
|||
|
|||
public void PushBitmapBlendMode(BitmapBlendingMode blendingMode) |
|||
{ |
|||
} |
|||
|
|||
public void PopBitmapBlendMode() |
|||
{ |
|||
} |
|||
|
|||
public void Custom(ICustomDrawOperation custom) |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,53 @@ |
|||
using Avalonia.Controls.Shapes; |
|||
using Avalonia.Media; |
|||
using Avalonia.Platform; |
|||
using BenchmarkDotNet.Attributes; |
|||
|
|||
namespace Avalonia.Benchmarks.Rendering |
|||
{ |
|||
[MemoryDiagnoser] |
|||
public class ShapeRendering |
|||
{ |
|||
private readonly DrawingContext _drawingContext; |
|||
private readonly Line _lineFill; |
|||
private readonly Line _lineFillAndStroke; |
|||
private readonly Line _lineNoBrushes; |
|||
private readonly Line _lineStroke; |
|||
|
|||
public ShapeRendering() |
|||
{ |
|||
_lineNoBrushes = new Line(); |
|||
_lineStroke = new Line { Stroke = new SolidColorBrush() }; |
|||
_lineFill = new Line { Fill = new SolidColorBrush() }; |
|||
_lineFillAndStroke = new Line { Stroke = new SolidColorBrush(), Fill = new SolidColorBrush() }; |
|||
|
|||
_drawingContext = new DrawingContext(new NullDrawingContextImpl(), true); |
|||
|
|||
AvaloniaLocator.CurrentMutable.Bind<IPlatformRenderInterface>().ToConstant(new NullRenderingPlatform()); |
|||
} |
|||
|
|||
[Benchmark] |
|||
public void Render_Line_NoBrushes() |
|||
{ |
|||
_lineNoBrushes.Render(_drawingContext); |
|||
} |
|||
|
|||
[Benchmark] |
|||
public void Render_Line_WithStroke() |
|||
{ |
|||
_lineStroke.Render(_drawingContext); |
|||
} |
|||
|
|||
[Benchmark] |
|||
public void Render_Line_WithFill() |
|||
{ |
|||
_lineFill.Render(_drawingContext); |
|||
} |
|||
|
|||
[Benchmark] |
|||
public void Render_Line_WithFillAndStroke() |
|||
{ |
|||
_lineFillAndStroke.Render(_drawingContext); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,84 @@ |
|||
using System.Threading.Tasks; |
|||
using Avalonia.Controls; |
|||
using Avalonia.Media; |
|||
using Avalonia.Media.Imaging; |
|||
using Xunit; |
|||
|
|||
#if AVALONIA_SKIA
|
|||
namespace Avalonia.Skia.RenderTests |
|||
#else
|
|||
namespace Avalonia.Direct2D1.RenderTests.Media |
|||
#endif
|
|||
{ |
|||
public class ImageDrawingTests : TestBase |
|||
{ |
|||
public ImageDrawingTests() |
|||
: base(@"Media\ImageDrawing") |
|||
{ |
|||
} |
|||
|
|||
private string BitmapPath |
|||
{ |
|||
get { return System.IO.Path.Combine(OutputPath, "github_icon.png"); } |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task ImageDrawing_Fill() |
|||
{ |
|||
Decorator target = new Decorator |
|||
{ |
|||
Width = 200, |
|||
Height = 200, |
|||
Child = new Image |
|||
{ |
|||
Source = new DrawingImage |
|||
{ |
|||
Drawing = new ImageDrawing |
|||
{ |
|||
ImageSource = new Bitmap(BitmapPath), |
|||
Rect = new Rect(0, 0, 200, 200), |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
|
|||
await RenderToFile(target); |
|||
CompareImages(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task ImageDrawing_BottomRight() |
|||
{ |
|||
Decorator target = new Decorator |
|||
{ |
|||
Width = 200, |
|||
Height = 200, |
|||
Child = new Image |
|||
{ |
|||
Source = new DrawingImage |
|||
{ |
|||
Drawing = new DrawingGroup |
|||
{ |
|||
Children = |
|||
{ |
|||
new GeometryDrawing |
|||
{ |
|||
Geometry = StreamGeometry.Parse("m0,0 l200,200"), |
|||
Brush = Brushes.Black, |
|||
}, |
|||
new ImageDrawing |
|||
{ |
|||
ImageSource = new Bitmap(BitmapPath), |
|||
Rect = new Rect(100, 100, 100, 100), |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
|
|||
await RenderToFile(target); |
|||
CompareImages(); |
|||
} |
|||
} |
|||
} |
|||
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 6.7 KiB |
|
After Width: | Height: | Size: 17 KiB |
Loading…
Reference in new issue