Skip to content

Commit

Permalink
Refactored DrawingContext and VisualBrush, added DrawingBrush (#10419)
Browse files Browse the repository at this point in the history
Refactored DrawingContext and VisualBrush, added DrawingBrush
  • Loading branch information
kekekeks authored Feb 23, 2023
1 parent bd5865f commit ae1fcfe
Show file tree
Hide file tree
Showing 70 changed files with 1,094 additions and 945 deletions.
20 changes: 10 additions & 10 deletions samples/RenderDemo/Pages/CustomSkiaPage.cs
Original file line number Diff line number Diff line change
@@ -1,29 +1,35 @@
using System;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Media;
using Avalonia.Platform;
using Avalonia.Rendering.SceneGraph;
using Avalonia.Skia;
using Avalonia.Threading;
using Avalonia.Utilities;
using SkiaSharp;

namespace RenderDemo.Pages
{
public class CustomSkiaPage : Control
{
private readonly GlyphRun _noSkia;
public CustomSkiaPage()
{
ClipToBounds = true;
var text = "Current rendering API is not Skia";
var glyphs = text.Select(ch => Typeface.Default.GlyphTypeface.GetGlyph(ch)).ToArray();
_noSkia = new GlyphRun(Typeface.Default.GlyphTypeface, 12, text.AsMemory(), glyphs);
}

class CustomDrawOp : ICustomDrawOperation
{
private readonly FormattedText _noSkia;
private readonly GlyphRun _noSkia;

public CustomDrawOp(Rect bounds, FormattedText noSkia)
public CustomDrawOp(Rect bounds, GlyphRun noSkia)
{
_noSkia = noSkia;
Bounds = bounds;
Expand All @@ -42,10 +48,7 @@ public void Render(IDrawingContextImpl context)
{
var leaseFeature = context.GetFeature<ISkiaSharpApiLeaseFeature>();
if (leaseFeature == null)
using (var c = new DrawingContext(context, false))
{
c.DrawText(_noSkia, new Point());
}
context.DrawGlyphRun(Brushes.Black, _noSkia.PlatformImpl);
else
{
using var lease = leaseFeature.Lease();
Expand Down Expand Up @@ -114,10 +117,7 @@ static int Animate(int d, int from, int to)

public override void Render(DrawingContext context)
{
var noSkia = new FormattedText("Current rendering API is not Skia", CultureInfo.CurrentCulture,
FlowDirection.LeftToRight, Typeface.Default, 12, Brushes.Black);

context.Custom(new CustomDrawOp(new Rect(0, 0, Bounds.Width, Bounds.Height), noSkia));
context.Custom(new CustomDrawOp(new Rect(0, 0, Bounds.Width, Bounds.Height), _noSkia));
Dispatcher.UIThread.InvokeAsync(InvalidateVisual, DispatcherPriority.Background);
}
}
Expand Down
5 changes: 1 addition & 4 deletions samples/RenderDemo/Pages/PathMeasurementPage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,8 @@ protected override void OnDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs

public override void Render(DrawingContext context)
{
using (var ctxi = _bitmap.CreateDrawingContext(null))
using (var bitmapCtx = new DrawingContext(ctxi, false))
using (var bitmapCtx = _bitmap.CreateDrawingContext())
{
ctxi.Clear(default);

var basePath = new PathGeometry();

using (var basePathCtx = basePath.Open())
Expand Down
4 changes: 1 addition & 3 deletions samples/RenderDemo/Pages/RenderTargetBitmapPage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,11 @@ protected override void OnDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs
readonly Stopwatch _st = Stopwatch.StartNew();
public override void Render(DrawingContext context)
{
using (var ctxi = _bitmap.CreateDrawingContext(null))
using(var ctx = new DrawingContext(ctxi, false))
using (var ctx = _bitmap.CreateDrawingContext())
using (ctx.PushPostTransform(Matrix.CreateTranslation(-100, -100)
* Matrix.CreateRotation(_st.Elapsed.TotalSeconds)
* Matrix.CreateTranslation(100, 100)))
{
ctxi.Clear(default);
ctx.FillRectangle(Brushes.Fuchsia, new Rect(50, 50, 100, 100));
}

Expand Down
66 changes: 66 additions & 0 deletions src/Avalonia.Base/Media/DrawingBrush.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
using Avalonia.Media.Immutable;
using Avalonia.Rendering;
using Avalonia.Rendering.Composition;
using Avalonia.Rendering.Composition.Drawing;

namespace Avalonia.Media
{
/// <summary>
/// Paints an area with an <see cref="Drawing"/>.
/// </summary>
public class DrawingBrush : TileBrush, ISceneBrush, IAffectsRender
{
/// <summary>
/// Defines the <see cref="Drawing"/> property.
/// </summary>
public static readonly StyledProperty<Drawing?> DrawingProperty =
AvaloniaProperty.Register<DrawingBrush, Drawing?>(nameof(Drawing));

static DrawingBrush()
{
AffectsRender<DrawingBrush>(DrawingProperty);
}

/// <summary>
/// Initializes a new instance of the <see cref="DrawingBrush"/> class.
/// </summary>
public DrawingBrush()
{
}

/// <summary>
/// Initializes a new instance of the <see cref="DrawingBrush"/> class.
/// </summary>
/// <param name="visual">The visual to draw.</param>
public DrawingBrush(Drawing visual)
{
Drawing = visual;
}

/// <summary>
/// Gets or sets the visual to draw.
/// </summary>
public Drawing? Drawing
{
get { return GetValue(DrawingProperty); }
set { SetValue(DrawingProperty, value); }
}

ISceneBrushContent? ISceneBrush.CreateContent()
{
if (Drawing == null)
return null;


var recorder = new CompositionDrawingContext();
recorder.BeginUpdate(null);
Drawing?.Draw(recorder);
var drawList = recorder.EndUpdate();
if (drawList == null)
return null;

return new CompositionDrawListSceneBrushContent(new ImmutableSceneBrush(this), drawList,
drawList.CalculateBounds(), true);
}
}
}
Loading

0 comments on commit ae1fcfe

Please sign in to comment.