A cross-platform UI framework for .NET
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

96 lines
3.0 KiB

using System;
using Avalonia.Media.Imaging;
namespace Avalonia.Media.Imaging
{
/// <summary>
/// Crops a Bitmap.
/// </summary>
public class CroppedBitmap : AvaloniaObject, IImage, IAffectsRender, IDisposable
{
/// <summary>
/// Defines the <see cref="Source"/> property.
/// </summary>
public static readonly StyledProperty<IImage?> SourceProperty =
AvaloniaProperty.Register<CroppedBitmap, IImage?>(nameof(Source));
/// <summary>
/// Defines the <see cref="SourceRect"/> property.
/// </summary>
public static readonly StyledProperty<PixelRect> SourceRectProperty =
AvaloniaProperty.Register<CroppedBitmap, PixelRect>(nameof(SourceRect));
public event EventHandler? Invalidated;
static CroppedBitmap()
{
SourceRectProperty.Changed.AddClassHandler<CroppedBitmap>((x, e) => x.SourceRectChanged(e));
SourceProperty.Changed.AddClassHandler<CroppedBitmap>((x, e) => x.SourceChanged(e));
}
/// <summary>
/// Gets or sets the source for the bitmap.
/// </summary>
public IImage? Source
{
get => GetValue(SourceProperty);
set => SetValue(SourceProperty, value);
}
/// <summary>
/// Gets or sets the rectangular area that the bitmap is cropped to.
/// </summary>
public PixelRect SourceRect
{
get => GetValue(SourceRectProperty);
set => SetValue(SourceRectProperty, value);
}
public CroppedBitmap()
{
Source = null;
SourceRect = default;
}
public CroppedBitmap(IImage source, PixelRect sourceRect)
{
Source = source;
SourceRect = sourceRect;
}
private void SourceChanged(AvaloniaPropertyChangedEventArgs e)
{
if (e.NewValue == null)
return;
if (!(e.NewValue is IBitmap))
throw new ArgumentException("Only IBitmap supported as source");
Invalidated?.Invoke(this, e);
}
private void SourceRectChanged(AvaloniaPropertyChangedEventArgs e) => Invalidated?.Invoke(this, e);
public virtual void Dispose()
{
(Source as IBitmap)?.Dispose();
}
public Size Size {
get
{
if (Source is not IBitmap bmp)
return default;
if (SourceRect.IsDefault)
return Source.Size;
return SourceRect.Size.ToSizeWithDpi(bmp.Dpi);
}
}
public void Draw(DrawingContext context, Rect sourceRect, Rect destRect, BitmapInterpolationMode bitmapInterpolationMode)
{
if (Source is not IBitmap bmp)
return;
var topLeft = SourceRect.TopLeft.ToPointWithDpi(bmp.Dpi);
Source.Draw(context, sourceRect.Translate(new Vector(topLeft.X, topLeft.Y)), destRect, bitmapInterpolationMode);
}
}
}