Browse Source
And make an immutable `SceneImageBrush` and `SceneVisualBrush` which clone the mutable `ImageBrush` and `VisualBrush` for use in the scene graph, as we shouldn't be accessing mutable state from the render thread.scenegraph-after-breakage
20 changed files with 230 additions and 71 deletions
@ -0,0 +1,15 @@ |
|||
using Avalonia.Media.Imaging; |
|||
|
|||
namespace Avalonia.Media |
|||
{ |
|||
/// <summary>
|
|||
/// Paints an area with an <see cref="IBitmap"/>.
|
|||
/// </summary>
|
|||
public interface IImageBrush : ITileBrush |
|||
{ |
|||
/// <summary>
|
|||
/// Gets the image to draw.
|
|||
/// </summary>
|
|||
IBitmap Source { get; } |
|||
} |
|||
} |
|||
@ -0,0 +1,39 @@ |
|||
namespace Avalonia.Media |
|||
{ |
|||
/// <summary>
|
|||
/// A brush which displays a repeating image.
|
|||
/// </summary>
|
|||
public interface ITileBrush : IBrush |
|||
{ |
|||
/// <summary>
|
|||
/// Gets the horizontal alignment of a tile in the destination.
|
|||
/// </summary>
|
|||
AlignmentX AlignmentX { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the horizontal alignment of a tile in the destination.
|
|||
/// </summary>
|
|||
AlignmentY AlignmentY { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the rectangle on the destination in which to paint a tile.
|
|||
/// </summary>
|
|||
RelativeRect DestinationRect { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the rectangle of the source image that will be displayed.
|
|||
/// </summary>
|
|||
RelativeRect SourceRect { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets a value indicating how the source rectangle will be stretched to fill the
|
|||
/// destination rect.
|
|||
/// </summary>
|
|||
Stretch Stretch { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the brush's tile mode.
|
|||
/// </summary>
|
|||
TileMode TileMode { get; } |
|||
} |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
using Avalonia.VisualTree; |
|||
|
|||
namespace Avalonia.Media |
|||
{ |
|||
/// <summary>
|
|||
/// Paints an area with an <see cref="IVisual"/>.
|
|||
/// </summary>
|
|||
public interface IVisualBrush : ITileBrush |
|||
{ |
|||
/// <summary>
|
|||
/// Gets the visual to draw.
|
|||
/// </summary>
|
|||
IVisual Visual { get; } |
|||
} |
|||
} |
|||
@ -0,0 +1,48 @@ |
|||
using System; |
|||
using Avalonia.Media; |
|||
using Avalonia.Rendering.SceneGraph.Media; |
|||
|
|||
namespace Avalonia.Rendering.SceneGraph |
|||
{ |
|||
public abstract class BrushDrawOperation : IDrawOperation |
|||
{ |
|||
public abstract Rect Bounds { get; } |
|||
public abstract bool HitTest(Point p); |
|||
public abstract void Render(IDrawingContextImpl context); |
|||
|
|||
protected IBrush Convert(IBrush brush) |
|||
{ |
|||
var imageBrush = brush as ImageBrush; |
|||
var visualBrush = brush as VisualBrush; |
|||
|
|||
if (imageBrush != null) |
|||
{ |
|||
return new SceneImageBrush(imageBrush); |
|||
} |
|||
else if (visualBrush != null) |
|||
{ |
|||
return new SceneVisualBrush(visualBrush); |
|||
} |
|||
else |
|||
{ |
|||
return brush; |
|||
} |
|||
} |
|||
|
|||
protected Pen Convert(Pen pen) |
|||
{ |
|||
var brush = pen?.Brush != null ? Convert(pen.Brush) : null; |
|||
return ReferenceEquals(pen?.Brush, brush) ? |
|||
pen : |
|||
new Pen( |
|||
pen.Brush, |
|||
thickness: pen.Thickness, |
|||
dashStyle: pen.DashStyle, |
|||
dashCap: pen.DashCap, |
|||
startLineCap: pen.StartLineCap, |
|||
endLineCap: pen.EndLineCap, |
|||
lineJoin: pen.LineJoin, |
|||
miterLimit: pen.MiterLimit); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,37 @@ |
|||
using System; |
|||
using Avalonia.Media; |
|||
using Avalonia.Media.Imaging; |
|||
|
|||
namespace Avalonia.Rendering.SceneGraph.Media |
|||
{ |
|||
internal class SceneImageBrush : IImageBrush |
|||
{ |
|||
public SceneImageBrush(IImageBrush source) |
|||
{ |
|||
AlignmentX = source.AlignmentX; |
|||
AlignmentY = source.AlignmentY; |
|||
DestinationRect = source.DestinationRect; |
|||
Opacity = source.Opacity; |
|||
Source = source.Source; |
|||
SourceRect = source.SourceRect; |
|||
Stretch = source.Stretch; |
|||
TileMode = source.TileMode; |
|||
} |
|||
|
|||
public AlignmentX AlignmentX { get; } |
|||
|
|||
public AlignmentY AlignmentY { get; } |
|||
|
|||
public RelativeRect DestinationRect { get; } |
|||
|
|||
public double Opacity { get; } |
|||
|
|||
public IBitmap Source { get; } |
|||
|
|||
public RelativeRect SourceRect { get; } |
|||
|
|||
public Stretch Stretch { get; } |
|||
|
|||
public TileMode TileMode { get; } |
|||
} |
|||
} |
|||
@ -0,0 +1,37 @@ |
|||
using System; |
|||
using Avalonia.Media; |
|||
using Avalonia.VisualTree; |
|||
|
|||
namespace Avalonia.Rendering.SceneGraph.Media |
|||
{ |
|||
internal class SceneVisualBrush : IVisualBrush |
|||
{ |
|||
public SceneVisualBrush(IVisualBrush source) |
|||
{ |
|||
AlignmentX = source.AlignmentX; |
|||
AlignmentY = source.AlignmentY; |
|||
DestinationRect = source.DestinationRect; |
|||
Opacity = source.Opacity; |
|||
SourceRect = source.SourceRect; |
|||
Stretch = source.Stretch; |
|||
TileMode = source.TileMode; |
|||
Visual = source.Visual; |
|||
} |
|||
|
|||
public AlignmentX AlignmentX { get; } |
|||
|
|||
public AlignmentY AlignmentY { get; } |
|||
|
|||
public RelativeRect DestinationRect { get; } |
|||
|
|||
public double Opacity { get; } |
|||
|
|||
public RelativeRect SourceRect { get; } |
|||
|
|||
public Stretch Stretch { get; } |
|||
|
|||
public TileMode TileMode { get; } |
|||
|
|||
public IVisual Visual { get; } |
|||
} |
|||
} |
|||
Loading…
Reference in new issue