Browse Source

Store transform with clip nodes.

Clip and geometry clip nodes were not being correctly applied with the current canvas transform from the time of their rendering. Make the nodes store the current canvas transform like the other drawing nodes.

Fixes #6359.
pull/6764/head
Steven Kirk 5 years ago
parent
commit
572eb355e4
  1. 20
      src/Avalonia.Visuals/Rendering/SceneGraph/ClipNode.cs
  2. 12
      src/Avalonia.Visuals/Rendering/SceneGraph/DeferredDrawingContextImpl.cs
  3. 14
      src/Avalonia.Visuals/Rendering/SceneGraph/GeometryClipNode.cs

20
src/Avalonia.Visuals/Rendering/SceneGraph/ClipNode.cs

@ -11,19 +11,23 @@ namespace Avalonia.Rendering.SceneGraph
/// Initializes a new instance of the <see cref="ClipNode"/> class that represents a
/// clip push.
/// </summary>
/// <param name="transform">The current transform.</param>
/// <param name="clip">The clip to push.</param>
public ClipNode(Rect clip)
public ClipNode(Matrix transform, Rect clip)
{
Transform = transform;
Clip = clip;
}
/// <summary>
/// Initializes a new instance of the <see cref="ClipNode"/> class that represents a
/// clip push.
/// </summary>
/// <param name="transform">The current transform.</param>
/// <param name="clip">The clip to push.</param>
public ClipNode(RoundedRect clip)
public ClipNode(Matrix transform, RoundedRect clip)
{
Transform = transform;
Clip = clip;
}
@ -43,23 +47,31 @@ namespace Avalonia.Rendering.SceneGraph
/// </summary>
public RoundedRect? Clip { get; }
/// <summary>
/// Gets the transform with which the node will be drawn.
/// </summary>
public Matrix Transform { get; }
/// <inheritdoc/>
public bool HitTest(Point p) => false;
/// <summary>
/// Determines if this draw operation equals another.
/// </summary>
/// <param name="transform">The transform of the other draw operation.</param>
/// <param name="clip">The clip 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(RoundedRect? clip) => Clip == clip;
public bool Equals(Matrix transform, RoundedRect? clip) => Transform == transform && Clip == clip;
/// <inheritdoc/>
public void Render(IDrawingContextImpl context)
{
context.Transform = Transform;
if (Clip.HasValue)
{
context.PushClip(Clip.Value);

12
src/Avalonia.Visuals/Rendering/SceneGraph/DeferredDrawingContextImpl.cs

@ -303,9 +303,9 @@ namespace Avalonia.Rendering.SceneGraph
{
var next = NextDrawAs<ClipNode>();
if (next == null || !next.Item.Equals(clip))
if (next == null || !next.Item.Equals(Transform, clip))
{
Add(new ClipNode(clip));
Add(new ClipNode(Transform, clip));
}
else
{
@ -318,9 +318,9 @@ namespace Avalonia.Rendering.SceneGraph
{
var next = NextDrawAs<ClipNode>();
if (next == null || !next.Item.Equals(clip))
if (next == null || !next.Item.Equals(Transform, clip))
{
Add(new ClipNode(clip));
Add(new ClipNode(Transform, clip));
}
else
{
@ -333,9 +333,9 @@ namespace Avalonia.Rendering.SceneGraph
{
var next = NextDrawAs<GeometryClipNode>();
if (next == null || !next.Item.Equals(clip))
if (next == null || !next.Item.Equals(Transform, clip))
{
Add(new GeometryClipNode(clip));
Add(new GeometryClipNode(Transform, clip));
}
else
{

14
src/Avalonia.Visuals/Rendering/SceneGraph/GeometryClipNode.cs

@ -11,9 +11,11 @@ namespace Avalonia.Rendering.SceneGraph
/// Initializes a new instance of the <see cref="GeometryClipNode"/> class that represents a
/// geometry clip push.
/// </summary>
/// <param name="transform">The current transform.</param>
/// <param name="clip">The clip to push.</param>
public GeometryClipNode(IGeometryImpl clip)
public GeometryClipNode(Matrix transform, IGeometryImpl clip)
{
Transform = transform;
Clip = clip;
}
@ -33,23 +35,31 @@ namespace Avalonia.Rendering.SceneGraph
/// </summary>
public IGeometryImpl Clip { get; }
/// <summary>
/// Gets the transform with which the node will be drawn.
/// </summary>
public Matrix Transform { get; }
/// <inheritdoc/>
public bool HitTest(Point p) => false;
/// <summary>
/// Determines if this draw operation equals another.
/// </summary>
/// <param name="transform">The transform of the other draw operation.</param>
/// <param name="clip">The clip 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(IGeometryImpl clip) => Clip == clip;
public bool Equals(Matrix transform, IGeometryImpl clip) => Transform == transform && Clip == clip;
/// <inheritdoc/>
public void Render(IDrawingContextImpl context)
{
context.Transform = Transform;
if (Clip != null)
{
context.PushGeometryClip(Clip);

Loading…
Cancel
Save