Browse Source

Refactoring

Add interpolation to TileBrush
pull/1762/head
Benedikt Schroeder 8 years ago
parent
commit
c0dd75bcce
  1. 6
      src/Avalonia.Controls/Image.cs
  2. 38
      src/Avalonia.Controls/RenderOptions.cs
  3. 6
      src/Avalonia.Visuals/Media/DrawingContext.cs
  4. 12
      src/Avalonia.Visuals/Media/ITileBrush.cs
  5. 19
      src/Avalonia.Visuals/Media/Imaging/BitmapInterpolationMode.cs
  6. 11
      src/Avalonia.Visuals/Media/Immutable/ImmutableImageBrush.cs
  7. 16
      src/Avalonia.Visuals/Media/Immutable/ImmutableTileBrush.cs
  8. 12
      src/Avalonia.Visuals/Media/Immutable/ImmutableVisualBrush.cs
  9. 38
      src/Avalonia.Visuals/Media/RenderOptions.cs
  10. 15
      src/Avalonia.Visuals/Media/TileBrush.cs
  11. 4
      src/Avalonia.Visuals/Platform/IDrawingContextImpl.cs
  12. 6
      src/Avalonia.Visuals/Rendering/SceneGraph/DeferredDrawingContextImpl.cs
  13. 16
      src/Avalonia.Visuals/Rendering/SceneGraph/ImageNode.cs
  14. 33
      src/Skia/Avalonia.Skia/DrawingContextImpl.cs
  15. 49
      src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs
  16. 9
      src/Windows/Avalonia.Direct2D1/Media/ImageBrushImpl.cs
  17. 2
      tests/Avalonia.Visuals.UnitTests/Rendering/DeferredRendererTests.cs
  18. 5
      tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/DrawOperationTests.cs

6
src/Avalonia.Controls/Image.cs

@ -1,14 +1,12 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using Avalonia.Media;
using Avalonia.Media.Imaging;
using Avalonia.Visuals.Media;
namespace Avalonia.Controls
{
using Avalonia.Visuals.Media.Imaging;
{
/// <summary>
/// Displays a <see cref="Bitmap"/> image.
/// </summary>

38
src/Avalonia.Controls/RenderOptions.cs

@ -1,38 +0,0 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using Avalonia.Visuals.Media.Imaging;
namespace Avalonia.Controls
{
public class RenderOptions
{
/// <summary>
/// Defines the <see cref="BitmapScalingMode"/> property.
/// </summary>
public static readonly StyledProperty<BitmapScalingMode> BitmapScalingModeProperty =
AvaloniaProperty.RegisterAttached<RenderOptions, Control, BitmapScalingMode>(
"BitmapScalingMode",
inherits: true);
/// <summary>
/// Gets the value of the BitmapScalingMode attached property for a control.
/// </summary>
/// <param name="element">The control.</param>
/// <returns>The control's left coordinate.</returns>
public static BitmapScalingMode GetBitmapScalingMode(AvaloniaObject element)
{
return element.GetValue(BitmapScalingModeProperty);
}
/// <summary>
/// Sets the value of the BitmapScalingMode attached property for a control.
/// </summary>
/// <param name="element">The control.</param>
/// <param name="value">The left value.</param>
public static void SetBitmapScalingMode(AvaloniaObject element, double value)
{
element.SetValue(BitmapScalingModeProperty, value);
}
}
}

6
src/Avalonia.Visuals/Media/DrawingContext.cs

@ -69,12 +69,12 @@ namespace Avalonia.Media
/// <param name="opacity">The opacity to draw with.</param>
/// <param name="sourceRect">The rect in the image to draw.</param>
/// <param name="destRect">The rect in the output to draw to.</param>
/// <param name="bitmapScalingMode"></param>
public void DrawImage(IBitmap source, double opacity, Rect sourceRect, Rect destRect, BitmapScalingMode bitmapScalingMode = default)
/// <param name="bitmapInterpolationMode"></param>
public void DrawImage(IBitmap source, double opacity, Rect sourceRect, Rect destRect, BitmapInterpolationMode bitmapInterpolationMode = default)
{
Contract.Requires<ArgumentNullException>(source != null);
PlatformImpl.DrawImage(source.PlatformImpl, opacity, sourceRect, destRect, bitmapScalingMode);
PlatformImpl.DrawImage(source.PlatformImpl, opacity, sourceRect, destRect, bitmapInterpolationMode);
}
/// <summary>

12
src/Avalonia.Visuals/Media/ITileBrush.cs

@ -1,5 +1,7 @@
namespace Avalonia.Media
{
using Avalonia.Visuals.Media.Imaging;
/// <summary>
/// A brush which displays a repeating image.
/// </summary>
@ -35,5 +37,13 @@
/// Gets the brush's tile mode.
/// </summary>
TileMode TileMode { get; }
/// <summary>
/// Gets the bitmap interpolation mode.
/// </summary>
/// <value>
/// The bitmap interpolation mode.
/// </value>
BitmapInterpolationMode BitmapInterpolationMode { get; }
}
}
}

19
src/Avalonia.Visuals/Media/Imaging/BitmapScalingMode.cs → src/Avalonia.Visuals/Media/Imaging/BitmapInterpolationMode.cs

@ -6,21 +6,26 @@ namespace Avalonia.Visuals.Media.Imaging
/// <summary>
/// Controls the performance and quality of bitmap scaling.
/// </summary>
public enum BitmapScalingMode
public enum BitmapInterpolationMode
{
/// <summary>
/// Highest quality but worst performance.
/// Uses the default behavior of the underling render backend.
/// </summary>
Default,
/// <summary>
/// The best performance but worst image quality.
/// </summary>
HighQuality,
LowQuality,
/// <summary>
/// Good performance and decent image quality.
/// </summary>
MediumQuality,
MediumQuality,
/// <summary>
/// The best performance but worst image quality.
/// Highest quality but worst performance.
/// </summary>
LowQuality
HighQuality
}
}

11
src/Avalonia.Visuals/Media/Immutable/ImmutableImageBrush.cs

@ -1,5 +1,5 @@
using System;
using Avalonia.Media.Imaging;
using Avalonia.Media.Imaging;
using Avalonia.Visuals.Media.Imaging;
namespace Avalonia.Media.Immutable
{
@ -21,6 +21,7 @@ namespace Avalonia.Media.Immutable
/// How the source rectangle will be stretched to fill the destination rect.
/// </param>
/// <param name="tileMode">The tile mode.</param>
/// <param name="bitmapInterpolationMode">The bitmap interpolation mode.</param>
public ImmutableImageBrush(
IBitmap source,
AlignmentX alignmentX = AlignmentX.Center,
@ -29,7 +30,8 @@ namespace Avalonia.Media.Immutable
double opacity = 1,
RelativeRect? sourceRect = null,
Stretch stretch = Stretch.Uniform,
TileMode tileMode = TileMode.None)
TileMode tileMode = TileMode.None,
BitmapInterpolationMode bitmapInterpolationMode = BitmapInterpolationMode.Default)
: base(
alignmentX,
alignmentY,
@ -37,7 +39,8 @@ namespace Avalonia.Media.Immutable
opacity,
sourceRect ?? RelativeRect.Fill,
stretch,
tileMode)
tileMode,
bitmapInterpolationMode)
{
Source = source;
}

16
src/Avalonia.Visuals/Media/Immutable/ImmutableTileBrush.cs

@ -1,4 +1,7 @@
using System;
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using Avalonia.Visuals.Media.Imaging;
namespace Avalonia.Media.Immutable
{
@ -19,6 +22,7 @@ namespace Avalonia.Media.Immutable
/// How the source rectangle will be stretched to fill the destination rect.
/// </param>
/// <param name="tileMode">The tile mode.</param>
/// <param name="bitmapInterpolationMode">Controls the quality of interpolation.</param>
protected ImmutableTileBrush(
AlignmentX alignmentX,
AlignmentY alignmentY,
@ -26,7 +30,8 @@ namespace Avalonia.Media.Immutable
double opacity,
RelativeRect sourceRect,
Stretch stretch,
TileMode tileMode)
TileMode tileMode,
BitmapInterpolationMode bitmapInterpolationMode)
{
AlignmentX = alignmentX;
AlignmentY = alignmentY;
@ -35,6 +40,7 @@ namespace Avalonia.Media.Immutable
SourceRect = sourceRect;
Stretch = stretch;
TileMode = tileMode;
BitmapInterpolationMode = bitmapInterpolationMode;
}
/// <summary>
@ -49,7 +55,8 @@ namespace Avalonia.Media.Immutable
source.Opacity,
source.SourceRect,
source.Stretch,
source.TileMode)
source.TileMode,
source.BitmapInterpolationMode)
{
}
@ -73,5 +80,8 @@ namespace Avalonia.Media.Immutable
/// <inheritdoc/>
public TileMode TileMode { get; }
/// <inheritdoc/>
public BitmapInterpolationMode BitmapInterpolationMode { get; }
}
}

12
src/Avalonia.Visuals/Media/Immutable/ImmutableVisualBrush.cs

@ -1,4 +1,7 @@
using System;
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using Avalonia.Visuals.Media.Imaging;
using Avalonia.VisualTree;
namespace Avalonia.Media.Immutable
@ -21,6 +24,7 @@ namespace Avalonia.Media.Immutable
/// How the source rectangle will be stretched to fill the destination rect.
/// </param>
/// <param name="tileMode">The tile mode.</param>
/// <param name="bitmapInterpolationMode">Controls the quality of interpolation.</param>
public ImmutableVisualBrush(
IVisual visual,
AlignmentX alignmentX = AlignmentX.Center,
@ -29,7 +33,8 @@ namespace Avalonia.Media.Immutable
double opacity = 1,
RelativeRect? sourceRect = null,
Stretch stretch = Stretch.Uniform,
TileMode tileMode = TileMode.None)
TileMode tileMode = TileMode.None,
BitmapInterpolationMode bitmapInterpolationMode = BitmapInterpolationMode.Default)
: base(
alignmentX,
alignmentY,
@ -37,7 +42,8 @@ namespace Avalonia.Media.Immutable
opacity,
sourceRect ?? RelativeRect.Fill,
stretch,
tileMode)
tileMode,
bitmapInterpolationMode)
{
Visual = visual;
}

38
src/Avalonia.Visuals/Media/RenderOptions.cs

@ -0,0 +1,38 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using Avalonia.Visuals.Media.Imaging;
namespace Avalonia.Visuals.Media
{
public class RenderOptions
{
/// <summary>
/// Defines the <see cref="Imaging.BitmapInterpolationMode"/> property.
/// </summary>
public static readonly StyledProperty<BitmapInterpolationMode> BitmapInterpolationMode =
AvaloniaProperty.RegisterAttached<RenderOptions, AvaloniaObject, BitmapInterpolationMode>(
"BitmapInterpolationMode",
inherits: true);
/// <summary>
/// Gets the value of the BitmapInterpolationMode attached property for a control.
/// </summary>
/// <param name="element">The control.</param>
/// <returns>The control's left coordinate.</returns>
public static BitmapInterpolationMode GetBitmapScalingMode(AvaloniaObject element)
{
return element.GetValue(BitmapInterpolationMode);
}
/// <summary>
/// Sets the value of the BitmapInterpolationMode attached property for a control.
/// </summary>
/// <param name="element">The control.</param>
/// <param name="value">The left value.</param>
public static void SetBitmapScalingMode(AvaloniaObject element, BitmapInterpolationMode value)
{
element.SetValue(BitmapInterpolationMode, value);
}
}
}

15
src/Avalonia.Visuals/Media/TileBrush.cs

@ -3,6 +3,9 @@
namespace Avalonia.Media
{
using Avalonia.Visuals.Media;
using Avalonia.Visuals.Media.Imaging;
/// <summary>
/// Describes how a <see cref="TileBrush"/> is tiled.
/// </summary>
@ -129,5 +132,17 @@ namespace Avalonia.Media
get { return (TileMode)GetValue(TileModeProperty); }
set { SetValue(TileModeProperty, value); }
}
/// <summary>
/// Gets or sets the bitmap interpolation mode.
/// </summary>
/// <value>
/// The bitmap interpolation mode.
/// </value>
public BitmapInterpolationMode BitmapInterpolationMode
{
get { return RenderOptions.GetBitmapScalingMode(this); }
set { RenderOptions.SetBitmapScalingMode(this, value); }
}
}
}

4
src/Avalonia.Visuals/Platform/IDrawingContextImpl.cs

@ -32,8 +32,8 @@ namespace Avalonia.Platform
/// <param name="opacity">The opacity to draw with.</param>
/// <param name="sourceRect">The rect in the image to draw.</param>
/// <param name="destRect">The rect in the output to draw to.</param>
/// <param name="bitmapScalingMode">Controls</param>
void DrawImage(IRef<IBitmapImpl> source, double opacity, Rect sourceRect, Rect destRect, BitmapScalingMode bitmapScalingMode = default);
/// <param name="bitmapInterpolationMode">Controls</param>
void DrawImage(IRef<IBitmapImpl> source, double opacity, Rect sourceRect, Rect destRect, BitmapInterpolationMode bitmapInterpolationMode = default);
/// <summary>
/// Draws a bitmap image.

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

@ -115,13 +115,13 @@ namespace Avalonia.Rendering.SceneGraph
}
/// <inheritdoc/>
public void DrawImage(IRef<IBitmapImpl> source, double opacity, Rect sourceRect, Rect destRect, BitmapScalingMode bitmapScalingMode)
public void DrawImage(IRef<IBitmapImpl> source, double opacity, Rect sourceRect, Rect destRect, BitmapInterpolationMode bitmapInterpolationMode)
{
var next = NextDrawAs<ImageNode>();
if (next == null || !next.Item.Equals(Transform, source, opacity, sourceRect, destRect, bitmapScalingMode))
if (next == null || !next.Item.Equals(Transform, source, opacity, sourceRect, destRect, bitmapInterpolationMode))
{
Add(new ImageNode(Transform, source, opacity, sourceRect, destRect, bitmapScalingMode));
Add(new ImageNode(Transform, source, opacity, sourceRect, destRect, bitmapInterpolationMode));
}
else
{

16
src/Avalonia.Visuals/Rendering/SceneGraph/ImageNode.cs

@ -21,8 +21,8 @@ namespace Avalonia.Rendering.SceneGraph
/// <param name="opacity">The draw opacity.</param>
/// <param name="sourceRect">The source rect.</param>
/// <param name="destRect">The destination rect.</param>
/// <param name="bitmapScalingMode">The bitmap scaling mode.</param>
public ImageNode(Matrix transform, IRef<IBitmapImpl> source, double opacity, Rect sourceRect, Rect destRect, BitmapScalingMode bitmapScalingMode)
/// <param name="bitmapInterpolationMode">The bitmap scaling mode.</param>
public ImageNode(Matrix transform, IRef<IBitmapImpl> source, double opacity, Rect sourceRect, Rect destRect, BitmapInterpolationMode bitmapInterpolationMode)
: base(destRect, transform, null)
{
Transform = transform;
@ -30,7 +30,7 @@ namespace Avalonia.Rendering.SceneGraph
Opacity = opacity;
SourceRect = sourceRect;
DestRect = destRect;
BitmapScalingMode = bitmapScalingMode;
BitmapInterpolationMode = bitmapInterpolationMode;
}
/// <summary>
@ -64,7 +64,7 @@ namespace Avalonia.Rendering.SceneGraph
/// <value>
/// The scaling mode.
/// </value>
public BitmapScalingMode BitmapScalingMode { get; }
public BitmapInterpolationMode BitmapInterpolationMode { get; }
/// <summary>
/// Determines if this draw operation equals another.
@ -74,20 +74,20 @@ namespace Avalonia.Rendering.SceneGraph
/// <param name="opacity">The opacity of the other draw operation.</param>
/// <param name="sourceRect">The source rect of the other draw operation.</param>
/// <param name="destRect">The dest rect of the other draw operation.</param>
/// <param name="bitmapScalingMode">The bitmap scaling mode.</param>
/// <param name="bitmapInterpolationMode">The bitmap scaling mode.</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, IRef<IBitmapImpl> source, double opacity, Rect sourceRect, Rect destRect, BitmapScalingMode bitmapScalingMode)
public bool Equals(Matrix transform, IRef<IBitmapImpl> source, double opacity, Rect sourceRect, Rect destRect, BitmapInterpolationMode bitmapInterpolationMode)
{
return transform == Transform &&
Equals(source.Item, Source.Item) &&
opacity == Opacity &&
sourceRect == SourceRect &&
destRect == DestRect &&
bitmapScalingMode == BitmapScalingMode;
bitmapInterpolationMode == BitmapInterpolationMode;
}
/// <inheritdoc/>
@ -96,7 +96,7 @@ namespace Avalonia.Rendering.SceneGraph
// TODO: Probably need to introduce some kind of locking mechanism in the case of
// WriteableBitmap.
context.Transform = Transform;
context.DrawImage(Source, Opacity, SourceRect, DestRect, BitmapScalingMode);
context.DrawImage(Source, Opacity, SourceRect, DestRect, BitmapInterpolationMode);
}
/// <inheritdoc/>

33
src/Skia/Avalonia.Skia/DrawingContextImpl.cs

@ -14,7 +14,9 @@ using Avalonia.Visuals.Media.Imaging;
using SkiaSharp;
namespace Avalonia.Skia
{
{
using Avalonia.Controls;
/// <summary>
/// Skia based drawing context.
/// </summary>
@ -96,7 +98,7 @@ namespace Avalonia.Skia
}
/// <inheritdoc />
public void DrawImage(IRef<IBitmapImpl> source, double opacity, Rect sourceRect, Rect destRect, BitmapScalingMode bitmapScalingMode)
public void DrawImage(IRef<IBitmapImpl> source, double opacity, Rect sourceRect, Rect destRect, BitmapInterpolationMode bitmapInterpolationMode)
{
var drawableImage = (IDrawableBitmapImpl)source.Item;
var s = sourceRect.ToSKRect();
@ -108,24 +110,26 @@ namespace Avalonia.Skia
Color = new SKColor(255, 255, 255, (byte)(255 * opacity * _currentOpacity))
})
{
paint.FilterQuality = GetInterpolationMode(bitmapScalingMode);
paint.FilterQuality = GetInterpolationMode(bitmapInterpolationMode);
drawableImage.Draw(this, s, d, paint);
}
}
private static SKFilterQuality GetInterpolationMode(BitmapScalingMode scalingMode)
private static SKFilterQuality GetInterpolationMode(BitmapInterpolationMode interpolationMode)
{
switch (scalingMode)
switch (interpolationMode)
{
case BitmapScalingMode.LowQuality:
case BitmapInterpolationMode.LowQuality:
return SKFilterQuality.Low;
case BitmapScalingMode.MediumQuality:
case BitmapInterpolationMode.MediumQuality:
return SKFilterQuality.Medium;
case BitmapScalingMode.HighQuality:
case BitmapInterpolationMode.HighQuality:
return SKFilterQuality.High;
case BitmapInterpolationMode.Default:
return SKFilterQuality.None;
default:
throw new ArgumentOutOfRangeException(nameof(scalingMode), scalingMode, null);
throw new ArgumentOutOfRangeException(nameof(interpolationMode), interpolationMode, null);
}
}
@ -133,7 +137,7 @@ namespace Avalonia.Skia
public void DrawImage(IRef<IBitmapImpl> source, IBrush opacityMask, Rect opacityMaskRect, Rect destRect)
{
PushOpacityMask(opacityMask, opacityMaskRect);
DrawImage(source, 1, new Rect(0, 0, source.Item.PixelWidth, source.Item.PixelHeight), destRect, default(BitmapScalingMode));
DrawImage(source, 1, new Rect(0, 0, source.Item.PixelWidth, source.Item.PixelHeight), destRect, BitmapInterpolationMode.Default);
PopOpacityMask();
}
@ -378,7 +382,8 @@ namespace Avalonia.Skia
/// <param name="targetSize">Target size.</param>
/// <param name="tileBrush">Tile brush to use.</param>
/// <param name="tileBrushImage">Tile brush image.</param>
private void ConfigureTileBrush(ref PaintWrapper paintWrapper, Size targetSize, ITileBrush tileBrush, IDrawableBitmapImpl tileBrushImage)
/// <param name="interpolationMode">The bitmap interpolation mode.</param>
private void ConfigureTileBrush(ref PaintWrapper paintWrapper, Size targetSize, ITileBrush tileBrush, IDrawableBitmapImpl tileBrushImage, BitmapInterpolationMode interpolationMode)
{
var calc = new TileBrushCalculator(tileBrush,
new Size(tileBrushImage.PixelWidth, tileBrushImage.PixelHeight), targetSize);
@ -396,7 +401,7 @@ namespace Avalonia.Skia
context.Clear(Colors.Transparent);
context.PushClip(calc.IntermediateClip);
context.Transform = calc.IntermediateTransform;
context.DrawImage(RefCountable.CreateUnownedNotClonable(tileBrushImage), 1, rect, rect);
context.DrawImage(RefCountable.CreateUnownedNotClonable(tileBrushImage), 1, rect, rect, interpolationMode);
context.PopClip();
}
@ -505,12 +510,12 @@ namespace Avalonia.Skia
}
else
{
tileBrushImage = (IDrawableBitmapImpl) (tileBrush as IImageBrush)?.Source?.PlatformImpl.Item;
tileBrushImage = (IDrawableBitmapImpl)(tileBrush as IImageBrush)?.Source?.PlatformImpl.Item;
}
if (tileBrush != null && tileBrushImage != null)
{
ConfigureTileBrush(ref paintWrapper, targetSize, tileBrush, tileBrushImage);
ConfigureTileBrush(ref paintWrapper, targetSize, tileBrush, tileBrushImage, tileBrush.BitmapInterpolationMode);
}
else
{

49
src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs

@ -14,6 +14,8 @@ using SharpDX.Mathematics.Interop;
namespace Avalonia.Direct2D1.Media
{
using BitmapInterpolationMode = Avalonia.Visuals.Media.Imaging.BitmapInterpolationMode;
/// <summary>
/// Draws using Direct2D1.
/// </summary>
@ -101,43 +103,34 @@ namespace Avalonia.Direct2D1.Media
/// <param name="opacity">The opacity to draw with.</param>
/// <param name="sourceRect">The rect in the image to draw.</param>
/// <param name="destRect">The rect in the output to draw to.</param>
/// <param name="bitmapScalingMode"></param>
public void DrawImage(IRef<IBitmapImpl> source, double opacity, Rect sourceRect, Rect destRect, BitmapScalingMode bitmapScalingMode)
/// <param name="bitmapInterpolationMode"></param>
public void DrawImage(IRef<IBitmapImpl> source, double opacity, Rect sourceRect, Rect destRect, BitmapInterpolationMode bitmapInterpolationMode)
{
using (var d2d = ((BitmapImpl)source.Item).GetDirect2DBitmap(_renderTarget))
{
if (_renderTarget is DeviceContext deviceContext)
{
deviceContext.DrawBitmap(d2d.Value, destRect.ToDirect2D(), (float)opacity, GetInterpolationMode(bitmapScalingMode), sourceRect.ToDirect2D(), null);
}
else
{
var interpolationMode = bitmapScalingMode == BitmapScalingMode.LowQuality
? BitmapInterpolationMode.NearestNeighbor
: BitmapInterpolationMode.Linear;
_renderTarget.DrawBitmap(
d2d.Value,
destRect.ToSharpDX(),
(float)opacity,
interpolationMode,
sourceRect.ToSharpDX());
}
var interpolationMode = GetInterpolationMode(bitmapInterpolationMode);
_renderTarget.DrawBitmap(
d2d.Value,
destRect.ToSharpDX(),
(float)opacity,
interpolationMode,
sourceRect.ToSharpDX());
}
}
private static InterpolationMode GetInterpolationMode(BitmapScalingMode scalingMode)
private static SharpDX.Direct2D1.BitmapInterpolationMode GetInterpolationMode(BitmapInterpolationMode interpolationMode)
{
switch (scalingMode)
switch (interpolationMode)
{
case BitmapScalingMode.LowQuality:
return InterpolationMode.NearestNeighbor;
case BitmapScalingMode.MediumQuality:
return InterpolationMode.Linear;
case BitmapScalingMode.HighQuality:
return InterpolationMode.HighQualityCubic;
case BitmapInterpolationMode.LowQuality:
return SharpDX.Direct2D1.BitmapInterpolationMode.NearestNeighbor;
case BitmapInterpolationMode.MediumQuality:
case BitmapInterpolationMode.HighQuality:
case BitmapInterpolationMode.Default:
return SharpDX.Direct2D1.BitmapInterpolationMode.Linear;
default:
throw new ArgumentOutOfRangeException(nameof(scalingMode), scalingMode, null);
throw new ArgumentOutOfRangeException(nameof(interpolationMode), interpolationMode, null);
}
}

9
src/Windows/Avalonia.Direct2D1/Media/ImageBrushImpl.cs

@ -1,7 +1,6 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using Avalonia.Media;
using Avalonia.Rendering.Utilities;
using Avalonia.Utilities;
@ -11,7 +10,9 @@ namespace Avalonia.Direct2D1.Media
{
public sealed class ImageBrushImpl : BrushImpl
{
OptionalDispose<Bitmap> _bitmap;
private readonly OptionalDispose<Bitmap> _bitmap;
private readonly Visuals.Media.Imaging.BitmapInterpolationMode _bitmapInterpolationMode;
public ImageBrushImpl(
ITileBrush brush,
@ -41,6 +42,8 @@ namespace Avalonia.Direct2D1.Media
GetBrushProperties(brush, calc.DestinationRect));
}
}
_bitmapInterpolationMode = brush.BitmapInterpolationMode;
}
public override void Dispose()
@ -102,7 +105,7 @@ namespace Avalonia.Direct2D1.Media
context.PushClip(calc.IntermediateClip);
context.Transform = calc.IntermediateTransform;
context.DrawImage(RefCountable.CreateUnownedNotClonable(bitmap), 1, rect, rect);
context.DrawImage(RefCountable.CreateUnownedNotClonable(bitmap), 1, rect, rect, _bitmapInterpolationMode);
context.PopClip();
}

2
tests/Avalonia.Visuals.UnitTests/Rendering/DeferredRendererTests.cs

@ -340,7 +340,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering
var context = Mock.Get(target.RenderTarget.CreateDrawingContext(null));
var borderLayer = target.Layers[border].Bitmap;
context.Verify(x => x.DrawImage(borderLayer, 0.5, It.IsAny<Rect>(), It.IsAny<Rect>(), default(BitmapScalingMode)));
context.Verify(x => x.DrawImage(borderLayer, 0.5, It.IsAny<Rect>(), It.IsAny<Rect>(), BitmapInterpolationMode.Default));
}
private DeferredRenderer CreateTargetAndRunFrame(

5
tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/DrawOperationTests.cs

@ -1,5 +1,4 @@
using System;
using Avalonia.Media;
using Avalonia.Media;
using Avalonia.Platform;
using Avalonia.Rendering.SceneGraph;
using Avalonia.Utilities;
@ -53,7 +52,7 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
1,
new Rect(1, 1, 1, 1),
new Rect(1, 1, 1, 1),
BitmapScalingMode.LowQuality);
BitmapInterpolationMode.Default);
Assert.Equal(2, bitmap.RefCount);

Loading…
Cancel
Save