// 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.Media.Imaging; namespace Avalonia.Controls { /// /// Displays a image. /// public class Image : Control { /// /// Defines the property. /// public static readonly StyledProperty SourceProperty = AvaloniaProperty.Register(nameof(Source)); /// /// Defines the property. /// public static readonly StyledProperty StretchProperty = AvaloniaProperty.Register(nameof(Stretch), Stretch.Uniform); static Image() { AffectsRender(SourceProperty, StretchProperty); AffectsMeasure(SourceProperty, StretchProperty); } /// /// Gets or sets the bitmap image that will be displayed. /// public IBitmap Source { get { return GetValue(SourceProperty); } set { SetValue(SourceProperty, value); } } /// /// Gets or sets a value controlling how the image will be stretched. /// public Stretch Stretch { get { return (Stretch)GetValue(StretchProperty); } set { SetValue(StretchProperty, value); } } /// /// Renders the control. /// /// The drawing context. public override void Render(DrawingContext context) { var source = Source; if (source != null) { Rect viewPort = new Rect(Bounds.Size); Size sourceSize = new Size(source.PixelSize.Width, source.PixelSize.Height); Vector scale = Stretch.CalculateScaling(Bounds.Size, sourceSize); Size scaledSize = sourceSize * scale; Rect destRect = viewPort .CenterRect(new Rect(scaledSize)) .Intersect(viewPort); Rect sourceRect = new Rect(sourceSize) .CenterRect(new Rect(destRect.Size / scale)); var interpolationMode = RenderOptions.GetBitmapInterpolationMode(this); context.DrawImage(source, 1, sourceRect, destRect, interpolationMode); } } /// /// Measures the control. /// /// The available size. /// The desired size of the control. protected override Size MeasureOverride(Size availableSize) { var source = Source; var result = new Size(); if (source != null) { Size sourceSize = new Size(source.PixelSize.Width, source.PixelSize.Height); if (double.IsInfinity(availableSize.Width) || double.IsInfinity(availableSize.Height)) { result = sourceSize; } else { result = Stretch.CalculateSize(availableSize, sourceSize); } } return result.Constrain(availableSize); } /// protected override Size ArrangeOverride(Size finalSize) { var source = Source; if (source != null) { var sourceSize = new Size(source.PixelSize.Width, source.PixelSize.Height); var result = Stretch.CalculateSize(finalSize, sourceSize); return result; } else { return new Size(); } } } }