Browse Source
Conflicts: src/Avalonia.Visuals/Media/GradientBrush.cs src/Avalonia.Visuals/Media/IGradientBrush.cs src/Avalonia.Visuals/Media/IRadialGradientBrush.cs src/Avalonia.Visuals/Media/ImageBrush.cs src/Avalonia.Visuals/Media/LinearGradientBrush.cs src/Avalonia.Visuals/Media/RadialGradientBrush.cs src/Avalonia.Visuals/Media/VisualBrush.cs src/Gtk/Avalonia.Cairo/Media/DrawingContext.cs src/Gtk/Avalonia.Cairo/Media/ImageBrushImpl.cs src/Gtk/Avalonia.Cairo/Media/LinearGradientBrushImpl.cs src/Gtk/Avalonia.Cairo/Media/RadialGradientBrushImpl.cs src/Gtk/Avalonia.Cairo/Media/TileBrushes.cs src/Gtk/Avalonia.Cairo/Media/VisualBrushImpl.cs src/Skia/Avalonia.Skia/DrawingContextImpl.cs src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs src/Windows/Avalonia.Direct2D1/Media/LinearGradientBrushImpl.cs src/Windows/Avalonia.Direct2D1/Media/RadialGradientBrushImpl.cs src/Windows/Avalonia.Direct2D1/Media/TileBrushImpl.csscenegraph-after-breakage
20 changed files with 212 additions and 23 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,55 @@ |
|||
// 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 Cairo; |
|||
using Avalonia.Cairo.Media.Imaging; |
|||
using Avalonia.Layout; |
|||
using Avalonia.Media; |
|||
using Avalonia.Platform; |
|||
using Avalonia.Rendering; |
|||
using Avalonia.RenderHelpers; |
|||
|
|||
namespace Avalonia.Cairo.Media |
|||
{ |
|||
internal static class TileBrushes |
|||
{ |
|||
public static SurfacePattern CreateTileBrush(ITileBrush brush, Size targetSize) |
|||
{ |
|||
var helper = new TileBrushImplHelper(brush, targetSize); |
|||
if (!helper.IsValid) |
|||
return null; |
|||
|
|||
using (var intermediate = new ImageSurface(Format.ARGB32, (int)helper.IntermediateSize.Width, (int)helper.IntermediateSize.Height)) |
|||
using (var ctx = new RenderTarget(intermediate).CreateDrawingContext()) |
|||
{ |
|||
helper.DrawIntermediate(ctx); |
|||
|
|||
var result = new SurfacePattern(intermediate); |
|||
|
|||
if ((brush.TileMode & TileMode.FlipXY) != 0) |
|||
{ |
|||
// TODO: Currently always FlipXY as that's all cairo supports natively.
|
|||
// Support separate FlipX and FlipY by drawing flipped images to intermediate
|
|||
// surface.
|
|||
result.Extend = Extend.Reflect; |
|||
} |
|||
else |
|||
{ |
|||
result.Extend = Extend.Repeat; |
|||
} |
|||
|
|||
if (brush.TileMode != TileMode.None) |
|||
{ |
|||
var matrix = result.Matrix; |
|||
matrix.InitTranslate(-helper.DestinationRect.X, -helper.DestinationRect.Y); |
|||
result.Matrix = matrix; |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
} |
|||
|
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
using System; |
|||
using Avalonia.Media; |
|||
using global::Cairo; |
|||
|
|||
namespace Avalonia.Cairo.Media |
|||
{ |
|||
public class VisualBrushImpl : BrushImpl |
|||
{ |
|||
public VisualBrushImpl(IVisualBrush brush, Size destinationSize) |
|||
{ |
|||
this.PlatformBrush = TileBrushes.CreateTileBrush(brush, destinationSize); |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,78 @@ |
|||
// 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.Media; |
|||
using Avalonia.RenderHelpers; |
|||
using SharpDX.Direct2D1; |
|||
|
|||
namespace Avalonia.Direct2D1.Media |
|||
{ |
|||
public sealed class TileBrushImpl : BrushImpl |
|||
{ |
|||
public TileBrushImpl( |
|||
ITileBrush brush, |
|||
SharpDX.Direct2D1.RenderTarget target, |
|||
Size targetSize) |
|||
{ |
|||
var helper = new TileBrushImplHelper(brush, targetSize); |
|||
if (!helper.IsValid) |
|||
return; |
|||
|
|||
using (var intermediate = new BitmapRenderTarget(target, CompatibleRenderTargetOptions.None, helper.IntermediateSize.ToSharpDX())) |
|||
{ |
|||
using (var ctx = new RenderTarget(intermediate).CreateDrawingContext()) |
|||
{ |
|||
intermediate.Clear(null); |
|||
helper.DrawIntermediate(ctx); |
|||
} |
|||
|
|||
PlatformBrush = new BitmapBrush( |
|||
target, |
|||
intermediate.Bitmap, |
|||
GetBitmapBrushProperties(brush), |
|||
GetBrushProperties(brush, helper.DestinationRect)); |
|||
} |
|||
} |
|||
|
|||
private static BrushProperties GetBrushProperties(ITileBrush brush, Rect destinationRect) |
|||
{ |
|||
var tileTransform = |
|||
brush.TileMode != TileMode.None ? |
|||
Matrix.CreateTranslation(destinationRect.X, destinationRect.Y) : |
|||
Matrix.Identity; |
|||
|
|||
return new BrushProperties |
|||
{ |
|||
Opacity = (float)brush.Opacity, |
|||
Transform = tileTransform.ToDirect2D(), |
|||
}; |
|||
} |
|||
|
|||
private static BitmapBrushProperties GetBitmapBrushProperties(ITileBrush brush) |
|||
{ |
|||
var tileMode = brush.TileMode; |
|||
|
|||
return new BitmapBrushProperties |
|||
{ |
|||
ExtendModeX = GetExtendModeX(tileMode), |
|||
ExtendModeY = GetExtendModeY(tileMode), |
|||
}; |
|||
} |
|||
|
|||
private static ExtendMode GetExtendModeX(TileMode tileMode) |
|||
{ |
|||
return (tileMode & TileMode.FlipX) != 0 ? ExtendMode.Mirror : ExtendMode.Wrap; |
|||
} |
|||
|
|||
private static ExtendMode GetExtendModeY(TileMode tileMode) |
|||
{ |
|||
return (tileMode & TileMode.FlipY) != 0 ? ExtendMode.Mirror : ExtendMode.Wrap; |
|||
} |
|||
|
|||
public override void Dispose() |
|||
{ |
|||
((BitmapBrush)PlatformBrush)?.Bitmap.Dispose(); |
|||
base.Dispose(); |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue