|
|
|
@ -1,25 +1,77 @@ |
|
|
|
using System; |
|
|
|
using System.Collections.Generic; |
|
|
|
using System.Text; |
|
|
|
using Avalonia.Visuals.Media.Imaging; |
|
|
|
|
|
|
|
namespace Avalonia.Media.Imaging |
|
|
|
{ |
|
|
|
public class CroppedBitmap : IImage, IDisposable |
|
|
|
/// <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(IBitmap source, PixelRect sourceRect) |
|
|
|
|
|
|
|
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?.Dispose(); |
|
|
|
(Source as IBitmap)?.Dispose(); |
|
|
|
} |
|
|
|
|
|
|
|
public Size Size { |
|
|
|
@ -29,7 +81,7 @@ namespace Avalonia.Media.Imaging |
|
|
|
return Size.Empty; |
|
|
|
if (SourceRect.IsEmpty) |
|
|
|
return Source.Size; |
|
|
|
return SourceRect.Size.ToSizeWithDpi(Source.Dpi); |
|
|
|
return SourceRect.Size.ToSizeWithDpi((Source as IBitmap).Dpi); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -37,11 +89,8 @@ namespace Avalonia.Media.Imaging |
|
|
|
{ |
|
|
|
if (Source == null) |
|
|
|
return; |
|
|
|
var topLeft = SourceRect.TopLeft.ToPointWithDpi(Source.Dpi); |
|
|
|
var topLeft = SourceRect.TopLeft.ToPointWithDpi((Source as IBitmap).Dpi); |
|
|
|
Source.Draw(context, sourceRect.Translate(new Vector(topLeft.X, topLeft.Y)), destRect, bitmapInterpolationMode); |
|
|
|
} |
|
|
|
|
|
|
|
public IBitmap Source { get; } |
|
|
|
public PixelRect SourceRect { get; } |
|
|
|
} |
|
|
|
} |
|
|
|
|