瀏覽代碼

Refactoring
Add interpolation to TileBrush

Benedikt Schroeder 7 年之前
父節點
當前提交
c0dd75bcce

+ 2 - 4
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>

+ 0 - 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);
-        }
-    }
-}

+ 3 - 3
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>

+ 11 - 1
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; }
     }
-}
+}

+ 12 - 7
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
     }
 }

+ 7 - 4
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;
         }

+ 13 - 3
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; }
     }
 }

+ 9 - 3
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 - 0
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 - 0
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); }
+        }
     }
 }

+ 2 - 2
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.

+ 3 - 3
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
             {

+ 8 - 8
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/>

+ 19 - 14
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
             {

+ 21 - 28
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);
             }
         }
 

+ 6 - 3
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();
             }
 

+ 1 - 1
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(

+ 2 - 3
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);