From a9653353a2ee01802d1a51f03da9e01f535d250e Mon Sep 17 00:00:00 2001 From: Ratish Philip Date: Sat, 12 Dec 2020 08:12:45 -0800 Subject: [PATCH 01/21] RenderSurface classes - initial commit --- .../Surface/CompositionExtensions.cs | 385 +++++ .../Surface/CompositionGenerator.cs | 1431 +++++++++++++++++ .../Surface/CompositorExtensions.cs | 416 +++++ .../Surface/GaussianMaskSurface.cs | 246 +++ .../Surface/GeometrySurface.cs | 963 +++++++++++ .../Surface/ICompositionGenerator.cs | 333 ++++ .../Surface/ICompositionGeneratorInternal.cs | 126 ++ .../Surface/IGaussianMaskSurface.cs | 50 + .../Surface/IGeometrySurface.cs | 287 ++++ .../Surface/IImageMaskSurface.cs | 156 ++ .../Surface/IImageSurface.cs | 154 ++ .../Surface/IMaskSurface.cs | 60 + .../Surface/IRenderSurface.cs | 43 + .../Surface/ImageMaskSurface.cs | 708 ++++++++ .../Surface/ImageSurface.cs | 489 ++++++ .../Surface/ImageSurfaceOptions.cs | 162 ++ .../Surface/MaskSurface.cs | 200 +++ 17 files changed, 6209 insertions(+) create mode 100644 Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionExtensions.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositorExtensions.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Media/Surface/GaussianMaskSurface.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometrySurface.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Media/Surface/ICompositionGenerator.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Media/Surface/ICompositionGeneratorInternal.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Media/Surface/IGaussianMaskSurface.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Media/Surface/IGeometrySurface.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Media/Surface/IImageMaskSurface.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Media/Surface/IImageSurface.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Media/Surface/IMaskSurface.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Media/Surface/IRenderSurface.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageMaskSurface.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurface.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurfaceOptions.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Media/Surface/MaskSurface.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionExtensions.cs new file mode 100644 index 00000000000..78b098eeb55 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionExtensions.cs @@ -0,0 +1,385 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Linq; +using Microsoft.Graphics.Canvas; +using Microsoft.Graphics.Canvas.Effects; +using Windows.UI; +using Windows.UI.Composition; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Media; + +namespace Microsoft.Toolkit.Uwp.UI.Media.Surface +{ + /// + /// Extension Methods for Compositor + /// + public static class CompositionExtensions + { + /// + /// Creates a custom shaped Effect Brush using BackdropBrush and an IMaskSurface + /// + /// Compositor + /// IMaskSurface + /// Color to blend in the BackdropBrush + /// Blur Amount of the Backdrop Brush + /// Backdrop Brush (optional). If not provided, then compositor creates it. + /// CompositionEffectBrush + public static CompositionEffectBrush CreateMaskedBackdropBrush( + this Compositor compositor, IMaskSurface mask, Color blendColor, float blurAmount, CompositionBackdropBrush backdropBrush = null) + { + return CompositionExtensions.CreateBackdropBrush(compositor, mask, blendColor, blurAmount, backdropBrush); + } + + /// + /// Creates a custom shaped Effect Brush using BackdropBrush and an IGaussianMaskSurface + /// + /// Compositor + /// IMaskSurface + /// Color to blend in the BackdropBrush + /// Blur Amount of the Backdrop Brush + /// Backdrop Brush (optional). If not provided, then compositor creates it. + /// CompositionEffectBrush + public static CompositionEffectBrush CreateGaussianMaskedBackdropBrush( + this Compositor compositor, IGaussianMaskSurface mask, Color blendColor, float blurRadius, CompositionBackdropBrush backdropBrush = null) + { + return CompositionExtensions.CreateBackdropBrush(compositor, mask, blendColor, blurRadius, backdropBrush); + } + + /// + /// Creates a custom shaped Effect Brush using BackdropBrush and an IMaskSurface or an IGaussianMaskSurface + /// + /// Compositor + /// IMaskSurface or IGaussianMaskSurface + /// Color to blend in the BackdropBrush + /// Blur Amount of the Backdrop Brush + /// Backdrop Brush (optional). If not provided, then compositor creates it. + /// CompositionEffectBrush + internal static CompositionEffectBrush CreateBackdropBrush( + Compositor compositor, IRenderSurface mask, Color blendColor, float blurAmount, CompositionBackdropBrush backdropBrush = null) + { + // Blur Effect + var blurEffect = new GaussianBlurEffect() + { + Name = "Blur", + BlurAmount = blurAmount, + BorderMode = EffectBorderMode.Hard, + Optimization = EffectOptimization.Balanced, + Source = new CompositionEffectSourceParameter("backdrop"), + }; + + // Blend Effect + var blendEffect = new BlendEffect + { + Foreground = new ColorSourceEffect + { + Name = "Color", + Color = blendColor + }, + Background = blurEffect, + Mode = BlendEffectMode.Multiply + }; + + // Composite Effect + var effect = new CompositeEffect + { + Mode = CanvasComposite.DestinationIn, + Sources = + { + blendEffect, + new CompositionEffectSourceParameter("mask") + } + }; + + // Create Effect Factory + var factory = compositor.CreateEffectFactory(effect, new[] { "Blur.BlurAmount", "Color.Color" }); + + // Create Effect Brush + var brush = factory.CreateBrush(); + + // Set the BackDropBrush + // If no backdrop brush is provided, create one + brush.SetSourceParameter("backdrop", backdropBrush ?? compositor.CreateBackdropBrush()); + + // Set the Mask + // Create SurfaceBrush from IMaskSurface + var maskBrush = compositor.CreateSurfaceBrush(mask.Surface); + brush.SetSourceParameter("mask", maskBrush); + + return brush; + } + + /// + /// Creates a custom shaped Frosted Glass Effect Brush using BackdropBrush and a Mask + /// + /// Compositor + /// IMaskSurface + /// Color to blend in the BackdropBrush + /// Blur Amount of the Backdrop Brush + /// Backdrop Brush (optional). If not provided, then compositor creates it. + /// MultiplyAmount of the ArithmeticCompositeEffect + /// Source1Amount of the ArithmeticCompositeEffect + /// Source2Amount of the ArithmeticCompositeEffect + /// CompositionEffectBrush + public static CompositionEffectBrush CreateFrostedGlassBrush( + this Compositor compositor, + IMaskSurface mask, + Color blendColor, + float blurAmount, + CompositionBackdropBrush backdropBrush = null, + float multiplyAmount = 0, + float colorAmount = 0.5f, + float backdropAmount = 0.5f) + { + // Create a frosty glass effect + var frostEffect = new GaussianBlurEffect + { + Name = "Blur", + BlurAmount = blurAmount, + BorderMode = EffectBorderMode.Hard, + Source = new ArithmeticCompositeEffect + { + Name = "Source", + MultiplyAmount = multiplyAmount, + Source1Amount = backdropAmount, + Source2Amount = colorAmount, + Source1 = new CompositionEffectSourceParameter("backdrop"), + Source2 = new ColorSourceEffect + { + Name = "BlendColor", + Color = blendColor + } + } + }; + + // Composite Effect + var effect = new CompositeEffect + { + Mode = CanvasComposite.DestinationIn, + Sources = + { + frostEffect, + new CompositionEffectSourceParameter("mask") + } + }; + + // Create Effect Factory + var factory = compositor.CreateEffectFactory(effect, new[] { "Blur.BlurAmount", "BlendColor.Color" }); + + // Create Effect Brush + var brush = factory.CreateBrush(); + + // Set the BackDropBrush + // If no backdrop brush is provided, create one + brush.SetSourceParameter("backdrop", backdropBrush ?? compositor.CreateBackdropBrush()); + + // Set the Mask + // Create SurfaceBrush from CompositionMask + var maskBrush = compositor.CreateSurfaceBrush(mask.Surface); + brush.SetSourceParameter("mask", maskBrush); + + return brush; + } + + /// + /// Updates the CompositionSurfaceBrush's Stretch and Alignment options + /// + /// CompositionSurfaceBrush + /// Stretch mode + /// Horizontal Alignment + /// Vertical Alignment + /// The animation to use to update the horizontal alignment of the surface brush + /// The animation to use to update the vertical alignment of the surface brush + public static void UpdateSurfaceBrushOptions( + this CompositionSurfaceBrush surfaceBrush, + Stretch stretch, + AlignmentX alignX, + AlignmentY alignY, + ScalarKeyFrameAnimation alignXAnimation = null, + ScalarKeyFrameAnimation alignYAnimation = null) + { + // Stretch Mode + switch (stretch) + { + case Stretch.None: + surfaceBrush.Stretch = CompositionStretch.None; + break; + case Stretch.Fill: + surfaceBrush.Stretch = CompositionStretch.Fill; + break; + case Stretch.Uniform: + surfaceBrush.Stretch = CompositionStretch.Uniform; + break; + case Stretch.UniformToFill: + surfaceBrush.Stretch = CompositionStretch.UniformToFill; + break; + } + + // Horizontal Alignment + var finalAlignX = surfaceBrush.HorizontalAlignmentRatio; + switch (alignX) + { + case AlignmentX.Left: + finalAlignX = 0; + break; + case AlignmentX.Center: + finalAlignX = 0.5f; + break; + case AlignmentX.Right: + finalAlignX = 1; + break; + } + + // If animation is available, animate to the new value + // otherwise set it explicitly + if (alignXAnimation == null) + { + surfaceBrush.HorizontalAlignmentRatio = finalAlignX; + } + else + { + alignXAnimation.InsertKeyFrame(1f, finalAlignX); + surfaceBrush.StartAnimation("HorizontalAlignmentRatio", alignXAnimation); + } + + // Vertical Alignment + var finalAlignY = surfaceBrush.VerticalAlignmentRatio; + switch (alignY) + { + case AlignmentY.Top: + finalAlignY = 0; + break; + case AlignmentY.Center: + finalAlignY = 0.5f; + break; + case AlignmentY.Bottom: + finalAlignY = 1; + break; + } + + // If animation is available, animate to the new value + // otherwise set it explicitly + if (alignYAnimation == null) + { + surfaceBrush.VerticalAlignmentRatio = finalAlignY; + } + else + { + alignYAnimation.InsertKeyFrame(1f, finalAlignY); + surfaceBrush.StartAnimation("VerticalAlignmentRatio", alignYAnimation); + } + } + + /// + /// Gets the first descendant (of Type T) of this dependency object in the visual tree. + /// + /// Type deriving from DependencyObject + /// DependencyObject whose first descendant is to be obtained. + /// First descendant (of Type T), if any + public static T GetFirstDescendantOfType(this DependencyObject dependencyObject) + where T : DependencyObject + { + return dependencyObject.GetDescendantsOfType().FirstOrDefault(); + } + + /// + /// Gets the descendants (of Type T) of this dependency object in the visual tree. + /// + /// Type deriving from DependencyObject + /// DependencyObject whose descendants are to be obtained. + /// Enumerable collection of descendants (of Type T) + public static IEnumerable GetDescendantsOfType(this DependencyObject dependencyObject) + where T : DependencyObject + { + return dependencyObject.GetDescendants().OfType(); + } + + /// + /// Gets the descendants of this dependency object in the visual tree. + /// + /// DependencyObject whose descendants are to be obtained. + /// Enumerable collection of descendants + public static IEnumerable GetDescendants(this DependencyObject dependencyObject) + { + var queue = new Queue(); + + // Add to queue to obtain its descendants + queue.Enqueue(dependencyObject); + + while (queue.Count > 0) + { + var parent = queue.Dequeue(); + if (parent == null) + { + continue; + } + + var childrenCount = VisualTreeHelper.GetChildrenCount(parent); + for (var i = 0; i < childrenCount; i++) + { + var child = VisualTreeHelper.GetChild(parent, i); + + // Yield for enumeration + yield return child; + + // Add child to queue to obtain its descendants + queue.Enqueue(child); + } + } + } + + /// + /// Gets the first ancestor (of Type T) of this dependency object in the visual tree. + /// + /// Type deriving from DependencyObject + /// DependencyObject whose first ancestor is to be obtained. + /// First ancestor (of Type T), if any + public static T GetFirstAncestorOfType(this DependencyObject dependencyObject) + where T : DependencyObject + { + return dependencyObject.GetAncestorsOfType().FirstOrDefault(); + } + + /// + /// Gets the ancestors (of Type T) of this dependency object in the visual tree. + /// + /// Type deriving from DependencyObject + /// DependencyObject whose ancestors are to be obtained. + /// Enumerable collection of ancestors (of Type T) + public static IEnumerable GetAncestorsOfType(this DependencyObject dependencyObject) + where T : DependencyObject + { + return dependencyObject.GetAncestors().OfType(); + } + + /// + /// Gets the ancestors of this dependency object in the visual tree. + /// + /// DependencyObject whose ancestors are to be obtained. + /// Enumerable collection of ancestors + public static IEnumerable GetAncestors(this DependencyObject dependencyObject) + { + var parent = VisualTreeHelper.GetParent(dependencyObject); + + while (parent != null) + { + yield return parent; + parent = VisualTreeHelper.GetParent(parent); + } + } + + /// + /// Checks if this dependency object is present in the Visual Tree + /// of the current window. + /// + /// DependencyObject + /// True if present, otherwise False + public static bool IsInVisualTree(this DependencyObject dependencyObject) + { + return Window.Current.Content != null && + dependencyObject.GetAncestors().Contains(Window.Current.Content); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs new file mode 100644 index 00000000000..92d48f1f0fb --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs @@ -0,0 +1,1431 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Linq; +using System.Numerics; +using System.Threading.Tasks; +using Microsoft.Graphics.Canvas; +using Microsoft.Graphics.Canvas.Brushes; +using Microsoft.Graphics.Canvas.Effects; +using Microsoft.Graphics.Canvas.Geometry; +using Microsoft.Graphics.Canvas.UI.Composition; +using Microsoft.Toolkit.Uwp.UI.Media.Geometry; +using Windows.Foundation; +using Windows.Graphics.DirectX; +using Windows.UI; +using Windows.UI.Composition; +using Windows.UI.Xaml; + +namespace Microsoft.Toolkit.Uwp.UI.Media.Surface +{ + /// + /// Class to create mask which can be used to create custom shaped + /// Composition Visuals. + /// + internal sealed class CompositionGenerator : ICompositionGeneratorInternal + { + /// + /// Device Replaced event + /// + public event EventHandler DeviceReplaced; + + private readonly object _disposingLock; + private readonly bool _useSharedCanvasDevice; + private readonly bool _forceSoftwareRenderer; + private CompositionGraphicsDevice _compositionDevice; + + /// + /// Gets the Compositor + /// + public Compositor Compositor { get; private set; } + + /// + /// Gets the CanvasDevice + /// + public CanvasDevice Device { get; private set; } + + /// + /// Initializes a new instance of the class. + /// Constructor + /// + /// Compositor + /// Indicates whether to use a shared CanvasDevice or to create a new one. + /// Indicates whether to use Software Renderer when creating a new CanvasDevice. + public CompositionGenerator(Compositor compositor, bool useSharedCanvasDevice = true, bool forceSoftwareRenderer = false) + { + // Compositor + Compositor = compositor ?? throw new ArgumentNullException(nameof(compositor), "Compositor cannot be null!"); + + // Disposing Lock + _disposingLock = new object(); + + _useSharedCanvasDevice = useSharedCanvasDevice; + _forceSoftwareRenderer = forceSoftwareRenderer; + } + + /// + /// Renders the CanvasBitmap on the CompositionDrawingSurface based on the given options. + /// + /// The object to lock to prevent multiple threads + /// from accessing the surface at the same time. + /// CompositionDrawingSurface on which the CanvasBitmap has to be rendered. + /// CanvasBitmap created by loading the image from the Uri + /// Describes the image's resize and alignment options in the allocated space. + private static void RenderBitmap(object surfaceLock, CompositionDrawingSurface surface, CanvasBitmap canvasBitmap, ImageSurfaceOptions options) + { + var surfaceSize = surface.Size; + + // If the canvasBitmap is null, then just fill the surface with the SurfaceBackgroundColor + if (canvasBitmap == null) + { + // No need to render if the width and/or height of the surface is zero + if (surfaceSize.IsEmpty || surfaceSize.Width.IsZero() || surfaceSize.Height.IsZero()) + { + return; + } + + // Since multiple threads could be trying to get access to the device/surface + // at the same time, we need to do any device/surface work under a lock. + lock (surfaceLock) + { + using var session = CanvasComposition.CreateDrawingSession(surface); + + // Clear the surface with the SurfaceBackgroundColor + session.Clear(options.SurfaceBackgroundColor); + + // No need to proceed further + return; + } + } + + // Since multiple threads could be trying to get access to the device/surface + // at the same time, we need to do any device/surface work under a lock. + lock (surfaceLock) + { + // Is AutoResize Enabled? + if (options.AutoResize) + { + // If AutoResize is allowed and the canvasBitmap size and surface size are + // not matching then resize the surface to match the canvasBitmap size. + // + // NOTE: HorizontalAlignment, Vertical Alignment and Stretch will be + // handled by the CompositionSurfaceBrush created using this surface. + if (canvasBitmap.Size != surfaceSize) + { + // Resize the surface + CanvasComposition.Resize(surface, canvasBitmap.Size); + surfaceSize = canvasBitmap.Size; + } + + // No need to render if the width and/or height of the surface is zero + if (surfaceSize.IsEmpty || surface.Size.Width.IsZero() || surface.Size.Height.IsZero()) + { + return; + } + + // Draw the image to the surface + using var session = CanvasComposition.CreateDrawingSession(surface); + + // Clear the surface with the SurfaceBackgroundColor + session.Clear(options.SurfaceBackgroundColor); + + // Render the image + session.DrawImage( + canvasBitmap, // CanvasBitmap + new Rect(0, 0, surfaceSize.Width, surfaceSize.Height), // Target Rectangle + new Rect(0, 0, canvasBitmap.Size.Width, canvasBitmap.Size.Height), // Source Rectangle + options.Opacity, // Opacity + options.Interpolation); // Interpolation + } + else + { + // No need to render if the width and/or height of the surface is zero + if (surfaceSize.IsEmpty || surface.Size.Width.IsZero() || surface.Size.Height.IsZero()) + { + return; + } + + // Get the optimum size that can fit the surface + var targetRect = Utils.GetOptimumSize( + canvasBitmap.Size.Width, + canvasBitmap.Size.Height, + surfaceSize.Width, + surfaceSize.Height, + options.Stretch, + options.HorizontalAlignment, + options.VerticalAlignment); + + // Draw the image to the surface + using var session = CanvasComposition.CreateDrawingSession(surface); + + // Clear the surface with the SurfaceBackgroundColor + session.Clear(options.SurfaceBackgroundColor); + + // Render the image + session.DrawImage( + canvasBitmap, // CanvasBitmap + targetRect, // Target Rectangle + canvasBitmap.Bounds, // Source Rectangle + options.Opacity, // Opacity + options.Interpolation); // Interpolation + } + } + } + + /// + /// Renders the mask using the CanvasBitmap's alpha values on the CompositionDrawingSurface based on the given options. + /// + /// CanvasDevice + /// The object to lock to prevent multiple threads + /// from accessing the surface at the same time. + /// CompositionDrawingSurface on which the CanvasBitmap has to be rendered. + /// CanvasBitmap created by loading the image from the Uri + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where + /// the mask, created from the loaded image's alpha values, should be rendered. + /// Describes the image's resize and alignment options in the allocated space. + private static void RenderBitmapMask(CanvasDevice device, object surfaceLock, CompositionDrawingSurface surface, CanvasBitmap canvasBitmap, Thickness padding, ImageSurfaceOptions options) + { + var surfaceSize = surface.Size; + + // If the canvasBitmap is null, then just fill the surface with transparent color + if (canvasBitmap == null) + { + // No need to render if the width and/or height of the surface is zero + if (surfaceSize.IsEmpty || surfaceSize.Width.IsZero() || surfaceSize.Height.IsZero()) + { + return; + } + + // Since multiple threads could be trying to get access to the device/surface + // at the same time, we need to do any device/surface work under a lock. + lock (surfaceLock) + { + using var session = CanvasComposition.CreateDrawingSession(surface); + + // Clear the surface with the transparent color + session.Clear(options.SurfaceBackgroundColor); + + // No need to proceed further + return; + } + } + + // Since multiple threads could be trying to get access to the device/surface + // at the same time, we need to do any device/surface work under a lock. + lock (surfaceLock) + { + // No need to render if the width and/or height of the surface is zero + if (surfaceSize.IsEmpty || surface.Size.Width.IsZero() || surface.Size.Height.IsZero()) + { + return; + } + + // Get the available size on the surface + var paddingSize = padding.CollapseThickness(); + var availableWidth = Math.Max(0, surfaceSize.Width - paddingSize.Width); + var availableHeight = Math.Max(0, surfaceSize.Height - paddingSize.Height); + + if (availableWidth.IsZero() || availableHeight.IsZero()) + { + return; + } + + // Get the optimum size that can fit the available size on the surface + var targetRect = Utils.GetOptimumSize( + canvasBitmap.Size.Width, + canvasBitmap.Size.Height, + availableWidth, + availableHeight, + options.Stretch, + options.HorizontalAlignment, + options.VerticalAlignment); + + // Add the padding to the targetRect + targetRect.X += padding.Left; + targetRect.Y += padding.Top; + + // Resize the image to the target size + var imageCmdList = new CanvasCommandList(device); + using (var ds = imageCmdList.CreateDrawingSession()) + { + ds.DrawImage(canvasBitmap, targetRect, canvasBitmap.Bounds, 1f, options.Interpolation); + } + + // Fill the entire surface with White + var surfaceBounds = new Rect(0, 0, (float)surfaceSize.Width, (float)surfaceSize.Height); + + var rectCmdList = new CanvasCommandList(device); + using (var ds = rectCmdList.CreateDrawingSession()) + { + ds.FillRectangle(surfaceBounds, Colors.White); + } + + // Create the mask using the image's alpha values + var alphaEffect = new AlphaMaskEffect + { + Source = rectCmdList, + AlphaMask = imageCmdList + }; + + // Apply Gaussian blur on the mask to create the final mask + var blurEffect = new GaussianBlurEffect + { + Source = alphaEffect, + BlurAmount = options.BlurRadius + }; + + // Draw the final mask to the surface + using var session = CanvasComposition.CreateDrawingSession(surface); + + // Clear the surface with the SurfaceBackgroundColor + session.Clear(options.SurfaceBackgroundColor); + + // Render the mask + session.DrawImage( + blurEffect, // CanvasBitmap + surfaceBounds, // Target Rectangle + surfaceBounds, // Source Rectangle + options.Opacity, // Opacity + options.Interpolation); // Interpolation + } + } + + /// + /// Reloads the and fields. + /// + /// Indicates whether the DeviceReplacedEvent should be raised. + private void InitializeDevices(bool raiseEvent = false) + { + lock (this._disposingLock) + { + if (!(this.Device is null)) + { + this.Device.DeviceLost -= this.OnDeviceLost; + } + + if (!(this._compositionDevice is null)) + { + this._compositionDevice.RenderingDeviceReplaced -= this.OnRenderingDeviceReplaced; + } + + // Canvas Device + Device = _useSharedCanvasDevice + ? CanvasDevice.GetSharedDevice(_forceSoftwareRenderer) + : new CanvasDevice(_forceSoftwareRenderer); + + // Composition Graphics Device + _compositionDevice = CanvasComposition.CreateCompositionGraphicsDevice(Compositor, Device); + + _compositionDevice.RenderingDeviceReplaced += this.OnRenderingDeviceReplaced; + + this.Device.DeviceLost += this.OnDeviceLost; + this._compositionDevice.RenderingDeviceReplaced += this.OnRenderingDeviceReplaced; + + if (raiseEvent) + { + // Raise the device replaced event + RaiseDeviceReplacedEvent(); + } + } + } + + /// + /// Invokes when the current is lost and raises the DeviceReplacedEvent. + /// + private void OnDeviceLost(CanvasDevice sender, object args) + { + InitializeDevices(true); + } + + /// + /// Invokes when the current changes rendering device and raises the DeviceReplacedEvent. + /// + private void OnRenderingDeviceReplaced(CompositionGraphicsDevice sender, RenderingDeviceReplacedEventArgs args) + { + InitializeDevices(true); + } + + /// + /// Raises the DeviceReplacedEvent + /// + private void RaiseDeviceReplacedEvent() + { + var deviceEvent = DeviceReplaced; + deviceEvent?.Invoke(this, new EventArgs()); + } + + /// + /// Creates an Empty IMaskSurface having the no size and geometry. + /// NOTE: Use this API if you want to create an Empty IMaskSurface first + /// and change its geometry and/or size of the IMaskSurface later. + /// + /// IMaskSurface + public IMaskSurface CreateMaskSurface() + { + return CreateMaskSurface(default, null, Vector2.Zero); + } + + /// + /// Creates an IMaskSurface having the given size and geometry with MaskMode as True. + /// The geometry is filled with white color. The surface not covered by the geometry is + /// transparent. + /// + /// Size of the mask + /// Geometry of the mask + /// IMaskSurface + public IMaskSurface CreateMaskSurface(Size size, CanvasGeometry geometry) + { + return CreateMaskSurface(size, geometry, Vector2.Zero); + } + + /// + /// Creates an IMaskSurface having the given size and geometry with MaskMode as True. + /// The geometry is filled with white color. The surface not covered by the geometry is + /// transparent. + /// + /// Size of the mask + /// Geometry of the mask + /// The offset from the top left corner of the ICompositionSurface where + /// the Geometry is rendered. + /// IMaskSurface + public IMaskSurface CreateMaskSurface(Size size, CanvasGeometry geometry, Vector2 offset) + { + // Initialize the mask + IMaskSurface mask = new MaskSurface(this, size, geometry, offset); + + // Render the mask + mask.Redraw(); + + return mask; + } + + /// + /// Creates an Empty IGaussianMaskSurface having the no size and geometry. + /// NOTE: Use this API if you want to create an Empty IGaussianMaskSurface first + /// and change its geometry, size, offset and/or blurRadius of the IGaussianMaskSurface later. + /// + /// IGaussianMaskSurface + public IGaussianMaskSurface CreateGaussianMaskSurface() + { + return CreateGaussianMaskSurface(default, null, Vector2.Zero, 0); + } + + /// + /// Creates a IGaussianMaskSurface having the given size and geometry. The geometry is filled + /// with white color and a Gaussian blur is applied to it. The surface not covered by the geometry is transparent. + /// + /// Size of the mask + /// Geometry of the mask + /// The offset from the top left corner of the ICompositionSurface where + /// the Geometry is rendered. + /// Radius of Gaussian Blur to be applied on the IGaussianMaskSurface + /// IGaussianMaskSurface + public IGaussianMaskSurface CreateGaussianMaskSurface(Size size, CanvasGeometry geometry, Vector2 offset, float blurRadius) + { + // Initialize the mask + IGaussianMaskSurface mask = new GaussianMaskSurface(this, size, geometry, offset, blurRadius); + + // Render the mask + mask.Redraw(); + + return mask; + } + + /// + /// Creates an empty GeometrySurface having the no size and geometry. + /// NOTE: Use this API if you want to create an Empty IGeometrySurface + /// first and change its geometry and/or size, fillColor or stroke later. + /// + /// IGeometrySurface + public IGeometrySurface CreateGeometrySurface() + { + // Initialize the geometrySurface + IGeometrySurface geometrySurface = new GeometrySurface(this, default, null, null, Colors.Transparent, Colors.Transparent); + + // Render the geometrySurface + geometrySurface.Redraw(); + + return geometrySurface; + } + + /// + /// Creates a GeometrySurface having the given size, geometry, stroke + /// + /// Size of the GeometrySurface + /// Geometry to be rendered on the GeometrySurface + /// ICanvasStroke defining the outline for the geometry + /// IGeometrySurface + public IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasStroke stroke) + { + // Initialize the geometrySurface + IGeometrySurface geometrySurface = new GeometrySurface(this, size, geometry, stroke, Colors.Transparent, Colors.Transparent); + + // Render the geometrySurface + geometrySurface.Redraw(); + + return geometrySurface; + } + + /// + /// Creates a GeometrySurface having the given size, geometry, foreground color with + /// MaskMode as False. + /// + /// Size of the mask + /// Geometry of the mask + /// Fill color of the geometry. + /// IGeometrySurface + public IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, Color fillColor) + { + // Initialize the geometrySurface + IGeometrySurface geometrySurface = new GeometrySurface(this, size, geometry, null, fillColor, Colors.Transparent); + + // Render the geometrySurface + geometrySurface.Redraw(); + + return geometrySurface; + } + + /// + /// Creates a GeometrySurface having the given size, geometry, stroke and fill color + /// + /// Size of the GeometrySurface + /// Geometry to be rendered on the GeometrySurface + /// ICanvasStroke defining the outline for the geometry + /// Fill color of the geometry. + /// IGeometrySurface + public IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasStroke stroke, Color fillColor) + { + // Initialize the geometrySurface + IGeometrySurface geometrySurface = new GeometrySurface(this, size, geometry, stroke, fillColor, Colors.Transparent); + + // Render the geometrySurface + geometrySurface.Redraw(); + + return geometrySurface; + } + + /// + /// Creates a GeometrySurface having the given size, geometry, foreground color and + /// background color. + /// + /// Size of the mask + /// Geometry of the mask + /// Fill color of the geometry + /// Fill color of the Mask surface background which is + /// not covered by the geometry + /// IGeometrySurface + public IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, Color fillColor, Color backgroundColor) + { + // Initialize the geometrySurface + IGeometrySurface geometrySurface = new GeometrySurface(this, size, geometry, null, fillColor, backgroundColor); + + // Render the geometrySurface + geometrySurface.Redraw(); + + return geometrySurface; + } + + /// + /// Creates a GeometrySurface having the given size, geometry, stroke, fill color and + /// background color. + /// + /// Size of the GeometrySurface + /// Geometry to be rendered on the GeometrySurface + /// ICanvasStroke defining the outline for the geometry + /// Fill color of the geometry + /// Fill color of the GeometrySurface background which is + /// not covered by the geometry + /// IGeometrySurface + public IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasStroke stroke, Color fillColor, Color backgroundColor) + { + // Initialize the geometrySurface + IGeometrySurface geometrySurface = new GeometrySurface(this, size, geometry, stroke, fillColor, backgroundColor); + + // Render the geometrySurface + geometrySurface.Redraw(); + + return geometrySurface; + } + + /// + /// Creates a GeometrySurface having the given size, geometry and foreground brush with + /// MaskMode as False. + /// + /// Size of the mask + /// Geometry of the mask + /// The brush with which the geometry has to be filled + /// IGeometrySurface + public IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasBrush fillBrush) + { + // Create the background brush + var backgroundBrush = new CanvasSolidColorBrush(Device, Colors.Transparent); + + // Initialize the geometrySurface + IGeometrySurface geometrySurface = new GeometrySurface(this, size, geometry, null, fillBrush, backgroundBrush); + + // Render the geometrySurface + geometrySurface.Redraw(); + + return geometrySurface; + } + + /// + /// Creates a GeometrySurface having the given size, geometry, stroke and fill brush. + /// + /// Size of the GeometrySurface + /// Geometry to be rendered on the GeometrySurface + /// ICanvasStroke defining the outline for the geometry + /// The brush with which the geometry has to be filled + /// IGeometrySurface + public IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasStroke stroke, ICanvasBrush fillBrush) + { + // Create the background brush + var backgroundBrush = new CanvasSolidColorBrush(Device, Colors.Transparent); + + // Initialize the geometrySurface + IGeometrySurface geometrySurface = new GeometrySurface(this, size, geometry, stroke, fillBrush, backgroundBrush); + + // Render the geometrySurface + geometrySurface.Redraw(); + + return geometrySurface; + } + + /// + /// Creates a GeometrySurface having the given size, geometry, foreground brush and + /// background brush with MaskMode as False. + /// + /// Size of the mask + /// Geometry of the mask + /// The brush with which the geometry has to be filled + /// The brush to fill the Mask background surface which is + /// not covered by the geometry + /// IGeometrySurface + public IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasBrush fillBrush, ICanvasBrush backgroundBrush) + { + // Initialize the geometrySurface + IGeometrySurface geometrySurface = new GeometrySurface(this, size, geometry, null, fillBrush, backgroundBrush); + + // Render the geometrySurface + geometrySurface.Redraw(); + + return geometrySurface; + } + + /// + /// Creates a GeometrySurface having the given size, geometry, stroke, fill brush and + /// background brush. + /// + /// Size of the GeometrySurface + /// Geometry to be rendered on the GeometrySurface + /// ICanvasStroke defining the outline for the geometry + /// The brush with which the geometry has to be filled + /// The brush to fill the GeometrySurface background which is + /// not covered by the geometry + /// IGeometrySurface + public IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasStroke stroke, ICanvasBrush fillBrush, ICanvasBrush backgroundBrush) + { + // Initialize the geometrySurface + IGeometrySurface geometrySurface = new GeometrySurface(this, size, geometry, stroke, fillBrush, backgroundBrush); + + // Render the geometrySurface + geometrySurface.Redraw(); + + return geometrySurface; + } + + /// + /// Creates a GeometrySurface having the given size, geometry, foreground brush and + /// background color with MaskMode as False. + /// + /// Size of the mask + /// Geometry of the mask + /// The brush with which the geometry has to be filled + /// Fill color of the Mask background surface which is + /// not covered by the geometry + /// IGeometrySurface + public IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasBrush fillBrush, Color backgroundColor) + { + // Create the background brush + var backgroundBrush = new CanvasSolidColorBrush(Device, backgroundColor); + + // Initialize the geometrySurface + IGeometrySurface geometrySurface = new GeometrySurface(this, size, geometry, null, fillBrush, backgroundBrush); + + // Render the geometrySurface + geometrySurface.Redraw(); + + return geometrySurface; + } + + /// + /// Creates a GeometrySurface having the given size, geometry, stroke, fill brush and + /// background color. + /// + /// Size of the GeometrySurface + /// Geometry to be rendered on the GeometrySurface + /// ICanvasStroke defining the outline for the geometry + /// The brush with which the geometry has to be filled + /// Fill color of the GeometrySurface background which is + /// not covered by the geometry + /// IGeometrySurface + public IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasStroke stroke, ICanvasBrush fillBrush, Color backgroundColor) + { + // Create the background brush + var backgroundBrush = new CanvasSolidColorBrush(Device, backgroundColor); + + // Initialize the geometrySurface + IGeometrySurface geometrySurface = new GeometrySurface(this, size, geometry, stroke, fillBrush, backgroundBrush); + + // Render the geometrySurface + geometrySurface.Redraw(); + + return geometrySurface; + } + + /// + /// Creates a GeometrySurface having the given size, geometry, foreground color and + /// background brush. + /// + /// Size of the mask + /// Geometry of the mask + /// Fill color of the geometry + /// The brush to fill the Mask background surface which is + /// not covered by the geometry + /// IGeometrySurface + public IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, Color fillColor, ICanvasBrush backgroundBrush) + { + // Create the foreground brush + var foregroundBrush = new CanvasSolidColorBrush(Device, fillColor); + + // Initialize the geometrySurface + IGeometrySurface geometrySurface = new GeometrySurface(this, size, geometry, null, foregroundBrush, backgroundBrush); + + // Render the geometrySurface + geometrySurface.Redraw(); + + return geometrySurface; + } + + /// + /// Creates a GeometrySurface having the given size, geometry, stroke, fill color and + /// background brush. + /// + /// Size of the GeometrySurface + /// Geometry to be rendered on the GeometrySurface + /// ICanvasStroke defining the outline for the geometry + /// Fill color of the geometry + /// The brush to fill the GeometrySurface background which is + /// not covered by the geometry + /// IGeometrySurface + public IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasStroke stroke, Color fillColor, ICanvasBrush backgroundBrush) + { + // Create the foreground brush + var foregroundBrush = new CanvasSolidColorBrush(Device, fillColor); + + // Initialize the geometrySurface + IGeometrySurface geometrySurface = new GeometrySurface(this, size, geometry, stroke, foregroundBrush, backgroundBrush); + + // Render the geometrySurface + geometrySurface.Redraw(); + + return geometrySurface; + } + + /// + /// Creates an IImageSurface having the given size onto which an image (based on the Uri + /// and the options) is loaded. + /// + /// Uri of the image to be loaded onto the IImageSurface. + /// New size of the IImageSurface + /// Describes the image's resize and alignment options in the allocated space. + /// ICompositionSurfaceImage + public async Task CreateImageSurfaceAsync(Uri uri, Size size, ImageSurfaceOptions options) + { + // Initialize the IImageSurface + var imageSurface = new ImageSurface(this, uri, size, options); + + // Render the image onto the surface + await imageSurface.RedrawAsync(); + + return imageSurface; + } + + /// + /// Creates an IImageSurface having the given size onto which the given image is loaded. + /// + /// Image that will be loaded onto the IImageSurface. + /// Size of the IImageSurface + /// The image's resize and alignment options in the allocated space. + /// IImageSurface + public IImageSurface CreateImageSurface(CanvasBitmap bitmap, Size size, ImageSurfaceOptions options) + { + // Create a new IImageSurface using the given imageSurface + var imageSurface = new ImageSurface(this, bitmap, size, options); + + // Render the image onto the surface + imageSurface.Redraw(); + + return imageSurface; + } + + /// + /// Creates a copy of the given IImageSurface + /// + /// IImageSurface to copy + /// Copy of the given IImageSurface + public IImageSurface CreateImageSurface(IImageSurface imageSurface) + { + if (imageSurface != null) + { + // Create a new IImageSurface using the given imageSurface + var newImageSurface = new ImageSurface(this, imageSurface.SurfaceBitmap, imageSurface.Size, imageSurface.Options); + + // Render the image onto the surface + newImageSurface.Redraw(); + + return newImageSurface; + } + + // return an empty ImageSurface + return CreateImageSurface(null, new Size(0, 0), ImageSurfaceOptions.Default); + } + + /// + /// Creates a copy of the given IImageMaskSurface + /// + /// IImageMaskSurface to copy + /// IImageMaskSurface + public IImageMaskSurface CreateImageMaskSurface(IImageMaskSurface imageMaskSurface) + { + if (imageMaskSurface != null) + { + // Create a new IImageMaskSurface using the given imageMaskSurface + var newImageSurface = new ImageMaskSurface( + this, + imageMaskSurface.SurfaceBitmap, + imageMaskSurface.Size, + imageMaskSurface.MaskPadding, + imageMaskSurface.Options); + + // Render the image onto the surface + newImageSurface.Redraw(); + + return newImageSurface; + } + + // return an empty ImageSurface + return CreateImageMaskSurface(surfaceBitmap: null, new Size(0, 0), new Thickness(0), ImageSurfaceOptions.DefaultImageMaskOptions); + } + + /// + /// Creates an IImageMaskSurface using the alpha values of the given image at the specified offset using + /// the given blur radius. + /// + /// The CanvasBitmap whose alpha values will be used to create the Mask. + /// Size of the IImageMaskSurface + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where + /// the mask, created from the given image's alpha values, should be rendered. + /// Radius of the Gaussian blur applied to the the mask. + /// IImageMaskSurface + public IImageMaskSurface CreateImageMaskSurface(CanvasBitmap surfaceBitmap, Size size, Thickness padding, float blurRadius) + { + return CreateImageMaskSurface(surfaceBitmap, size, padding, ImageSurfaceOptions.GetDefaultImageMaskOptionsForBlur(blurRadius)); + } + + /// + /// Creates an IImageMaskSurface using the alpha values of the given image at the specified offset using + /// the given options. + /// + /// The CanvasBitmap whose alpha values will be used to create the Mask. + /// Size of the IImageMaskSurface + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where + /// the mask, created from the given image's alpha values, should be rendered. + /// The image's resize, alignment and blur radius options in the allocated space. + /// IImageMaskSurface + public IImageMaskSurface CreateImageMaskSurface(CanvasBitmap surfaceBitmap, Size size, Thickness padding, ImageSurfaceOptions options) + { + var imageMaskSurface = new ImageMaskSurface(this, surfaceBitmap, size, padding, options); + + // Render the image onto the surface + imageMaskSurface.Redraw(); + + return imageMaskSurface; + } + + /// + /// Creates an IImageMaskSurface using the alpha values of the given IImageSurface's image at the specified offset using + /// the given options. + /// + /// The IImageSurface whose image's alpha values will be used to create the Mask. + /// Size of the IImageMaskSurface + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where + /// the mask, created from the given image's alpha values, should be rendered. + /// The image's resize, alignment and blur radius options in the allocated space. + /// IImageMaskSurface + public IImageMaskSurface CreateImageMaskSurface(IImageSurface imageSurface, Size size, Thickness padding, ImageSurfaceOptions options) + { + if (imageSurface != null) + { + // Create a new IImageSurface using the given imageSurface + return CreateImageMaskSurface(imageSurface.SurfaceBitmap, size, padding, options); + } + + // Create an empty ImageMaskSurface + return CreateImageMaskSurface(surfaceBitmap: null, size, padding, options); + } + + /// + /// Creates an IImageMaskSurface using the alpha values of the image loaded from the Uri + /// and rendered at the specified offset using the given options. + /// + /// The URI of the image whose alpha values will be used to create the Mask. + /// Size of the IImageMaskSurface + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where + /// the mask, created from the given image's alpha values, should be rendered. + /// The image's resize, alignment and blur radius options in the allocated space. + /// IImageMaskSurface + public async Task CreateImageMaskSurfaceAsync(Uri uri, Size size, Thickness padding, ImageSurfaceOptions options) + { + var imageMaskSurface = new ImageMaskSurface(this, uri, size, padding, options); + + // Render the image onto the surface + await imageMaskSurface.RedrawAsync(); + + return imageMaskSurface; + } + + /// + /// Creates a reflection of the given Visual + /// + /// Visual whose reflection has to be created + /// Distance of the reflection from the visual + /// Normalized Length of the reflected visual that will be visible. + /// - Location of the reflection with respect + /// to the Visual - Bottom, Top, Left or Right + public void CreateReflection(ContainerVisual visual, float reflectionDistance = 0f, float reflectionLength = 0.7f, ReflectionLocation location = ReflectionLocation.Bottom) + { + // Create the visual layer that will contained the visual's reflection + var reflectionLayer = Compositor.CreateLayerVisual(); + reflectionLayer.Size = visual.Size; + reflectionLayer.CenterPoint = new Vector3(visual.Size * 0.5f, 0); + + // Create the effect to create the opacity mask + var effect = new CompositeEffect + { + // CanvasComposite.DestinationIn - Intersection of source and mask. + // Equation: O = MA * S + // where O - Output pixel, MA - Mask Alpha, S - Source pixel. + Mode = CanvasComposite.DestinationIn, + Sources = + { + new CompositionEffectSourceParameter("source"), + new CompositionEffectSourceParameter("mask") + } + }; + + var effectFactory = Compositor.CreateEffectFactory(effect); + var effectBrush = effectFactory.CreateBrush(); + + // Create the gradient brush for the effect + var gradientBrush = new CanvasLinearGradientBrush(Device, Colors.White, Colors.Transparent); + + // Based on the reflection location, + // Set the Offset, RotationAxis and RotationAngleInDegrees of the reflectionLayer and + // set the StartPoint and EndPoint of the gradientBrush + switch (location) + { + case ReflectionLocation.Bottom: + reflectionLayer.RotationAxis = new Vector3(1, 0, 0); + reflectionLayer.RotationAngleInDegrees = 180; + reflectionLayer.Offset = new Vector3(0, visual.Size.Y + reflectionDistance, 0); + gradientBrush.StartPoint = new Vector2(visual.Size.X * 0.5f, 0); + gradientBrush.EndPoint = new Vector2(visual.Size.X * 0.5f, visual.Size.Y * reflectionLength); + break; + case ReflectionLocation.Top: + reflectionLayer.RotationAxis = new Vector3(1, 0, 0); + reflectionLayer.RotationAngleInDegrees = -180; + reflectionLayer.Offset = new Vector3(0, -visual.Size.Y - reflectionDistance, 0); + gradientBrush.StartPoint = new Vector2(visual.Size.X * 0.5f, visual.Size.Y); + gradientBrush.EndPoint = new Vector2(visual.Size.X * 0.5f, visual.Size.Y * (1f - reflectionLength)); + break; + case ReflectionLocation.Left: + reflectionLayer.RotationAxis = new Vector3(0, 1, 0); + reflectionLayer.RotationAngleInDegrees = -180; + reflectionLayer.Offset = new Vector3(-visual.Size.X - reflectionDistance, 0, 0); + gradientBrush.StartPoint = new Vector2(visual.Size.X, visual.Size.Y * 0.5f); + gradientBrush.EndPoint = new Vector2(visual.Size.X * (1f - reflectionLength), visual.Size.Y * 0.5f); + break; + case ReflectionLocation.Right: + reflectionLayer.RotationAxis = new Vector3(0, 1, 0); + reflectionLayer.RotationAngleInDegrees = 180; + reflectionLayer.Offset = new Vector3(visual.Size.X + reflectionDistance, 0, 0); + gradientBrush.StartPoint = new Vector2(0, visual.Size.Y * 0.5f); + gradientBrush.EndPoint = new Vector2(visual.Size.X * reflectionLength, visual.Size.Y * 0.5f); + break; + } + + // Create a mask filled with gradientBrush + var mask = CreateGeometrySurface(visual.Size.ToSize(), null, Colors.Transparent, gradientBrush); + + // Set the 'mask' parameter of the effectBrush + effectBrush.SetSourceParameter("mask", Compositor.CreateSurfaceBrush(mask.Surface)); + + // Set the effect for the reflection layer + reflectionLayer.Effect = effectBrush; + + // Now we need to duplicate the visual tree of the visual + ArrangeVisualReflection(visual, reflectionLayer, true); + + visual.Children.InsertAtTop(reflectionLayer); + } + + /// + /// Creates a CompositionDrawingSurface of given size + /// + /// The object to lock to prevent multiple threads + /// from accessing the surface at the same time. + /// Size of the CompositionDrawingSurface + /// CompositionDrawingSurface + public CompositionDrawingSurface CreateDrawingSurface(object surfaceLock, Size size) + { + var surfaceSize = size; + if (surfaceSize.IsEmpty) + { + // We start out with a size of 0,0 for the surface, because we don't know + // the size of the image at this time. We resize the surface later. + surfaceSize = new Size(0, 0); + } + + // Since multiple threads could be trying to get access to the device/surface + // at the same time, we need to do any device/surface work under a lock. + lock (surfaceLock) + { + return this._compositionDevice.CreateDrawingSurface(surfaceSize, DirectXPixelFormat.B8G8R8A8UIntNormalized, DirectXAlphaMode.Premultiplied); + } + } + + /// + /// Resizes the Mask Surface to the given size + /// + /// The object to lock to prevent multiple threads + /// from accessing the surface at the same time. + /// CompositionDrawingSurface + /// New size of the Mask Surface + public void ResizeDrawingSurface(object surfaceLock, CompositionDrawingSurface surface, Size size) + { + // Cannot resize to Size.Empty. Will throw exception! + if (size.IsEmpty) + { + return; + } + + // Ensuring that the size contains positive values + size.Width = Math.Max(0, size.Width); + size.Height = Math.Max(0, size.Height); + + // Since multiple threads could be trying to get access to the device/surface + // at the same time, we need to do any device/surface work under a lock. + lock (surfaceLock) + { + CanvasComposition.Resize(surface, size); + } + } + + /// + /// Redraws the IMaskSurface with the given size and geometry + /// + /// The object to lock to prevent multiple threads + /// from accessing the surface at the same time. + /// CompositionDrawingSurface + /// Size of the IMaskSurface + /// Geometry of the IMaskSurface + /// The offset from the top left corner of the ICompositionSurface where + /// the Geometry is rendered. + public void RedrawMaskSurface(object surfaceLock, CompositionDrawingSurface surface, Size size, CanvasGeometry geometry, Vector2 offset) + { + // If the surface is not created, create it + surface ??= this.CreateDrawingSurface(surfaceLock, size); + + // No need to render if the width and/or height of the surface is zero + if (surface.Size.Width.IsZero() || surface.Size.Height.IsZero()) + { + return; + } + + // Since multiple threads could be trying to get access to the device/surface + // at the same time, we need to do any device/surface work under a lock. + lock (surfaceLock) + { + // Render the mask to the surface + using var session = CanvasComposition.CreateDrawingSession(surface); + session.Clear(Colors.Transparent); + if (geometry != null) + { + // If the geometry is not null then fill the geometry area at the given offset + // with White color. The rest of the area on the surface will be transparent. + // When this mask is applied to a visual, only the area that is white will be visible. + session.FillGeometry(geometry, offset, Colors.White); + } + else + { + // If the geometry is null, then the entire mask with a padding, provided by the offset, + // should be filled with White. If the color is White. + // When this mask is applied to a visual, only the area that is white will be visible. + var width = Math.Max(0, (float)size.Width - (2 * offset.X)); + var height = Math.Max(0, (float)size.Height - (2 * offset.Y)); + var maskRect = new Rect(offset.X, offset.Y, width, height); + session.FillRectangle(maskRect, Colors.White); + } + } + } + + /// + /// Redraws the GaussianMaskSurface with the given size and geometry + /// + /// The object to lock to prevent multiple threads + /// from accessing the surface at the same time. + /// CompositionDrawingSurface + /// Size of the GaussianMaskSurface + /// Geometry of the GaussianMaskSurface + /// The offset from the top left corner of the ICompositionSurface where + /// the Geometry is rendered. + /// Radius of Gaussian Blur to be applied. + public void RedrawGaussianMaskSurface(object surfaceLock, CompositionDrawingSurface surface, Size size, CanvasGeometry geometry, Vector2 offset, float blurRadius) + { + // If the surface is not created, create it + surface ??= this.CreateDrawingSurface(surfaceLock, size); + + // No need to render if the width and/or height of the surface is zero + if (surface.Size.Width.IsZero() || surface.Size.Height.IsZero()) + { + return; + } + + // Since multiple threads could be trying to get access to the device/surface + // at the same time, we need to do any device/surface work under a lock. + lock (surfaceLock) + { + // Render the mask to the surface + using var session = CanvasComposition.CreateDrawingSession(surface); + var cl = new CanvasCommandList(Device); + using (var ds = cl.CreateDrawingSession()) + { + ds.Clear(Colors.Transparent); + if (geometry != null) + { + // If the geometry is not null then fill the geometry area with the White color at the specified offset. + // The rest of the area on the surface will be transparent. + // When this mask is applied to a visual, only the area that is white will be visible. + ds.FillGeometry(geometry, offset, Colors.White); + } + else + { + // If the geometry is null, then the entire mask with a padding, provided by the offset, + // should be filled with white color. + // When this mask is applied to a visual, only the area that is white will be visible. + var width = Math.Max(0, (float)size.Width - (2 * offset.X)); + var height = Math.Max(0, (float)size.Height - (2 * offset.Y)); + var maskRect = new Rect(offset.X, offset.Y, width, height); + ds.FillRectangle(maskRect, Colors.White); + } + } + + // Apply the Gaussian blur + var blurGeometry = new GaussianBlurEffect() + { + BlurAmount = blurRadius, + Source = cl, + BorderMode = EffectBorderMode.Soft, + Optimization = EffectOptimization.Quality + }; + + // Clear previously rendered mask (if any) + session.Clear(Colors.Transparent); + + // Render the mask + session.DrawImage(blurGeometry); + } + } + + /// + /// Redraws the GeometrySurface with the given size, geometry, foreground brush and background brush + /// + /// The object to lock to prevent multiple threads + /// from accessing the surface at the same time. + /// CompositionDrawingSurface + /// Size of the GeometrySurface + /// Geometry of the GeometrySurface + /// ICanvasStroke defining the outline for the geometry + /// The brush with which the geometry has to be filled + /// The brush with which the GeometrySurface background has to be filled + public void RedrawGeometrySurface(object surfaceLock, CompositionDrawingSurface surface, Size size, CanvasGeometry geometry, ICanvasStroke stroke, ICanvasBrush fillBrush, ICanvasBrush backgroundBrush) + { + // If the surface is not created, create it + surface ??= this.CreateDrawingSurface(surfaceLock, size); + + // No need to render if the width and/or height of the surface is zero + if (surface.Size.Width.IsZero() || surface.Size.Height.IsZero()) + { + return; + } + + // Since multiple threads could be trying to get access to the device/surface + // at the same time, we need to do any device/surface work under a lock. + lock (surfaceLock) + { + // Render the geometry to the surface + using var session = CanvasComposition.CreateDrawingSession(surface); + + // Clear the surface + session.Clear(Colors.Transparent); + + // First fill the background + if (backgroundBrush is CanvasSolidColorBrush brush) + { + // If the backgroundBrush is a SolidColorBrush then use the Clear() + // method to fill the surface with background color. It is faster. + // Clear the surface with the background color + session.Clear(brush.Color); + } + else + { + // Fill the surface with the background brush. + session.FillRectangle(0, 0, (float)size.Width, (float)size.Height, backgroundBrush); + } + + // If the geometry is not null then render the geometry + if (geometry != null) + { + // If there is a stroke, then scale back the geometry to fit the stroke in the + // surface. + if (stroke != null) + { + var scaleX = (float)((surface.Size.Width - stroke.Width) / surface.Size.Width); + var scaleY = (float)((surface.Size.Height - stroke.Width) / surface.Size.Height); + + geometry = geometry.Transform( + Matrix3x2.CreateScale(new Vector2(scaleX, scaleY), surface.Size.ToVector2() * 0.5f)); + } + + // If fillBrush is defined then fill the geometry area + if (fillBrush != null) + { + session.FillGeometry(geometry, fillBrush); + } + + // If stroke is defined then outline the geometry area + if (stroke != null) + { + session.DrawGeometry(geometry, stroke.Brush, stroke.Width, stroke.Style); + } + } + } + } + + /// + /// Resizes the ImageSurface to the given size and redraws the ImageSurface + /// by rendering the canvasBitmap onto the surface. + /// + /// The object to lock to prevent multiple threads + /// from accessing the surface at the same time. + /// CompositionDrawingSurface + /// Describes the image's resize and alignment options in the allocated space. + /// The CanvasBitmap on which the image is loaded. + public void RedrawImageSurface(object surfaceLock, CompositionDrawingSurface surface, ImageSurfaceOptions options, CanvasBitmap canvasBitmap) + { + // Render the image to the surface + RenderBitmap(surfaceLock, surface, canvasBitmap, options); + } + + /// + /// Resizes the ImageSurface with the given size and redraws the ImageSurface by loading + /// image from the new Uri. + /// + /// The object to lock to prevent multiple threads + /// from accessing the surface at the same time. + /// CompositionDrawingSurface + /// Uri of the image to be loaded onto the IImageSurface. + /// Describes the image's resize and alignment options in the allocated space. + /// The CanvasBitmap on which the image is loaded. + /// CanvasBitmap + public async Task RedrawImageSurfaceAsync(object surfaceLock, CompositionDrawingSurface surface, Uri uri, ImageSurfaceOptions options, CanvasBitmap canvasBitmap) + { + if ((canvasBitmap == null) && (uri != null)) + { + try + { + canvasBitmap = await CanvasBitmap.LoadAsync(Device, uri); + } + catch (Exception) + { + // Do nothing here as RenderBitmap method will fill the surface + // with options.SurfaceBackgroundColor as the image failed to load + // from Uri + } + } + + // Render the image to the surface + RenderBitmap(surfaceLock, surface, canvasBitmap, options); + + return canvasBitmap; + } + + /// + /// Resizes the ImageMaskSurface to the given size and redraws the ImageMaskSurface + /// by rendering the mask using the image's alpha values onto the surface. + /// + /// The object to lock to prevent multiple threads from accessing the surface at the same time. + /// CompositionDrawingSurface + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where + /// the mask, created from the loaded image's alpha values, should be rendered. + /// Describes the image's resize and alignment options and blur radius in the allocated space. + /// The image whose alpha values is used to create the IImageMaskSurface. + public void RedrawImageMaskSurface(object surfaceLock, CompositionDrawingSurface surface, Thickness padding, ImageSurfaceOptions options, CanvasBitmap surfaceBitmap) + { + // Render the image mask to the surface + RenderBitmapMask(Device, surfaceLock, surface, surfaceBitmap, padding, options); + } + + /// + /// Resizes the ImageMaskSurface to the given size and redraws the ImageMaskSurface by loading the image from the new Uri and + /// rendering the mask using the image's alpha values onto the surface. + /// + /// The object to lock to prevent multiple threads + /// from accessing the surface at the same time. + /// CompositionDrawingSurface + /// Uri of the image to be loaded onto the IImageMaskSurface. + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where + /// the mask, created from the given image's alpha values, should be rendered. + /// Describes the image's resize and alignment options and blur radius in the allocated space. + /// The CanvasBitmap on which the image is loaded. + /// The CanvasBitmap whose alpha values is used to create the IImageMaskSurface. + public async Task RedrawImageMaskSurfaceAsync(object surfaceLock, CompositionDrawingSurface surface, Uri uri, Thickness padding, ImageSurfaceOptions options, CanvasBitmap surfaceBitmap) + { + if ((surfaceBitmap == null) && (uri != null)) + { + try + { + surfaceBitmap = await CanvasBitmap.LoadAsync(Device, uri); + } + catch (Exception) + { + // Do nothing here as RenderBitmap method will fill the surface + // with options.SurfaceBackgroundColor as the image failed to load + // from Uri + } + } + + // Render the image mask to the surface + RenderBitmapMask(Device, surfaceLock, surface, surfaceBitmap, padding, options); + + return surfaceBitmap; + } + + /// + /// Disposes the resources used by the CompositionMaskGenerator + /// + public void Dispose() + { + lock (_disposingLock) + { + Compositor = null; + + if (Device != null) + { + // Only dispose the canvas device if we own the device. + if (this._useSharedCanvasDevice) + { + Device.Dispose(); + } + + Device = null; + } + + if (this._compositionDevice == null) + { + return; + } + + this._compositionDevice.RenderingDeviceReplaced -= this.OnRenderingDeviceReplaced; + + // Only dispose the composition graphics device if we own the device. + if (!this._useSharedCanvasDevice) + { + this._compositionDevice.Dispose(); + } + + this._compositionDevice = null; + } + } + + /// + /// Creates a duplicate of the visual tree of the given visual and arranges them within the reflectedParent. + /// + /// Visual whose visual tree has to be duplicated + /// Visual in which will host the duplicated visual tree + /// Flag to indicate whether the given visual is the root of the visual tree to be duplicated. + private void ArrangeVisualReflection(ContainerVisual visual, ContainerVisual reflectedParent, bool isRoot = false) + { + if (visual == null) + { + return; + } + + ContainerVisual reflectedVisual; + + if (visual is LayerVisual layerVisual) + { + reflectedVisual = Compositor.CreateLayerVisual(); + ((LayerVisual)reflectedVisual).Effect = layerVisual.Effect; + } + else if (visual is SpriteVisual spriteVisual) + { + reflectedVisual = Compositor.CreateSpriteVisual(); + ((SpriteVisual)reflectedVisual).Brush = spriteVisual.Brush; + ((SpriteVisual)reflectedVisual).Shadow = spriteVisual.Shadow; + } + else + { + reflectedVisual = Compositor.CreateContainerVisual(); + } + + // Copy the Visual properties + reflectedVisual.AnchorPoint = visual.AnchorPoint; + reflectedVisual.BackfaceVisibility = visual.BackfaceVisibility; + reflectedVisual.BorderMode = visual.BorderMode; + reflectedVisual.CenterPoint = visual.CenterPoint; + reflectedVisual.Clip = visual.Clip; + reflectedVisual.CompositeMode = visual.CompositeMode; + reflectedVisual.ImplicitAnimations = visual.ImplicitAnimations; + reflectedVisual.IsVisible = visual.IsVisible; + reflectedVisual.Offset = isRoot ? Vector3.One : visual.Offset; + reflectedVisual.Opacity = visual.Opacity; + reflectedVisual.Orientation = visual.Orientation; + reflectedVisual.RotationAngle = visual.RotationAngle; + reflectedVisual.RotationAngleInDegrees = visual.RotationAngleInDegrees; + reflectedVisual.RotationAxis = visual.RotationAxis; + reflectedVisual.Scale = visual.Scale; + reflectedVisual.Size = visual.Size; + reflectedVisual.TransformMatrix = visual.TransformMatrix; + + // Add the reflectedVisual to the reflectedParent's Children (at the Top) + reflectedParent.Children.InsertAtTop(reflectedVisual); + + if (!visual.Children.Any()) + { + return; + } + + // Iterate each of the visual's Children and add them to + // the reflectedVisual's Children (at the Top so that the + // correct order is obtained) + foreach (var child in visual.Children) + { + ArrangeVisualReflection((ContainerVisual)child, reflectedVisual); + } + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositorExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositorExtensions.cs new file mode 100644 index 00000000000..9122695ba1c --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositorExtensions.cs @@ -0,0 +1,416 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Numerics; +using Microsoft.Graphics.Canvas.Geometry; +using Microsoft.Toolkit.Uwp.UI.Media.Geometry; +using Windows.UI.Composition; + +namespace Microsoft.Toolkit.Uwp.UI.Media.Surface +{ + /// + /// Extension methods for Windows.UI.Composition.Compositor + /// The easing function values have been obtained from http://easings.net/ + /// + public static class CompositorExtensions + { + /// + /// Creates a CompositionGenerator object + /// + /// Compositor + /// ICompositionGenerator + public static ICompositionGenerator CreateCompositionGenerator(this Compositor compositor) + { + return new CompositionGenerator(compositor); + } + + /// + /// Creates a CompositionGenerator object + /// + /// Compositor + /// Whether to use a shared CanvasDevice or to create a new one. + /// Whether to use Software Renderer when creating a new CanvasDevice. + /// ICompositionGenerator + public static ICompositionGenerator CreateCompositionGenerator(this Compositor compositor, bool useSharedCanvasDevice, bool useSoftwareRenderer) + { + return new CompositionGenerator(compositor, useSharedCanvasDevice, useSoftwareRenderer); + } + + /// + /// This extension method creates a scoped batch and handles the completed event + /// the subscribing and unsubscribing process internally. + /// + /// Example usage: + /// _compositor.CreateScopedBatch(CompositionBatchTypes.Animation, + /// () => // Action + /// { + /// transitionVisual.StartAnimation("Scale.XY", _scaleUpAnimation); + /// }, + /// () => // Post Action + /// { + /// BackBtn.IsEnabled = true; + /// }); + /// + /// + /// Compositor + /// Composition Batch Type + /// Action to perform within the scoped batch + /// Action to perform once the batch completes + public static void CreateScopedBatch(this Compositor compositor, CompositionBatchTypes batchType, Action action, Action postAction = null) + { + if (action == null) + { + throw new ArgumentException("Cannot create a scoped batch on an action with null value!", nameof(action)); + } + + // Create ScopedBatch + var batch = compositor.CreateScopedBatch(batchType); + + // Handler for the Completed Event + void BatchCompletedHandler(object s, CompositionBatchCompletedEventArgs ea) + { + var scopedBatch = s as CompositionScopedBatch; + + // Unsubscribe the handler from the Completed event + if (scopedBatch != null) + { + scopedBatch.Completed -= BatchCompletedHandler; + } + + try + { + // Invoke the post action + postAction?.Invoke(); + } + finally + { + scopedBatch?.Dispose(); + } + } + + // Subscribe to the Completed event + batch.Completed += BatchCompletedHandler; + + // Invoke the action + action(); + + // End Batch + batch.End(); + } + + /// + /// This extension method creates a scoped batch and handles the completed event + /// the subscribing and unsubscribing process internally. + /// + /// Example usage: + /// _compositor.CreateScopedBatch(CompositionBatchTypes.Animation, + /// (batch) => // Action + /// { + /// transitionVisual.StartAnimation("Scale.XY", _scaleUpAnimation); + /// }, + /// (batch) => // Post Action + /// { + /// BackBtn.IsEnabled = true; + /// }); + /// + /// + /// Compositor + /// Composition Batch Type + /// Action to perform within the scoped batch + /// Action to perform once the batch completes + public static void CreateScopedBatch(this Compositor compositor, CompositionBatchTypes batchType, Action action, Action postAction = null) + { + if (action == null) + { + throw new ArgumentException("Cannot create a scoped batch on an action with null value!", nameof(action)); + } + + // Create ScopedBatch + var batch = compositor.CreateScopedBatch(batchType); + + // Handler for the Completed Event + void BatchCompletedHandler(object s, CompositionBatchCompletedEventArgs ea) + { + var scopedBatch = s as CompositionScopedBatch; + + // Unsubscribe the handler from the Completed event + if (scopedBatch != null) + { + scopedBatch.Completed -= BatchCompletedHandler; + } + + try + { + // Invoke the post action + postAction?.Invoke(scopedBatch); + } + finally + { + scopedBatch?.Dispose(); + } + } + + // Subscribe to the Completed event + batch.Completed += BatchCompletedHandler; + + // Invoke the action + action(batch); + + // End Batch + batch.End(); + } + + /// + /// Back Easing Function - Ease In + /// + /// Compositor + /// CubicBezierEasingFunction + public static CubicBezierEasingFunction CreateEaseInBackEasingFunction(this Compositor compositor) + { + return compositor.CreateCubicBezierEasingFunction(new Vector2(0.600f, -0.280f), new Vector2(0.735f, 0.045f)); + } + + /// + /// Circle Easing Function - Ease In + /// + /// Compositor + /// CubicBezierEasingFunction + public static CubicBezierEasingFunction CreateEaseInCircleEasingFunction(this Compositor compositor) + { + return compositor.CreateCubicBezierEasingFunction(new Vector2(0.600f, 0.040f), new Vector2(0.980f, 0.335f)); + } + + /// + /// Cubic Easing Function - Ease In + /// + /// Compositor + /// CubicBezierEasingFunction + public static CubicBezierEasingFunction CreateEaseInCubicEasingFunction(this Compositor compositor) + { + return compositor.CreateCubicBezierEasingFunction(new Vector2(0.550f, 0.055f), new Vector2(0.675f, 0.190f)); + } + + /// + /// Exponential Easing Function - Ease In + /// + /// Compositor + /// CubicBezierEasingFunction + public static CubicBezierEasingFunction CreateEaseInExponentialEasingFunction(this Compositor compositor) + { + return compositor.CreateCubicBezierEasingFunction(new Vector2(0.950f, 0.050f), new Vector2(0.795f, 0.035f)); + } + + /// + /// Quadratic Easing Function - Ease In + /// + /// Compositor + /// CubicBezierEasingFunction + public static CubicBezierEasingFunction CreateEaseInQuadraticEasingFunction(this Compositor compositor) + { + return compositor.CreateCubicBezierEasingFunction(new Vector2(0.550f, 0.085f), new Vector2(0.680f, 0.530f)); + } + + /// + /// Quartic Easing Function - Ease In + /// + /// Compositor + /// CubicBezierEasingFunction + public static CubicBezierEasingFunction CreateEaseInQuarticEasingFunction(this Compositor compositor) + { + return compositor.CreateCubicBezierEasingFunction(new Vector2(0.895f, 0.030f), new Vector2(0.685f, 0.220f)); + } + + /// + /// Quintic Easing Function - Ease In + /// + /// Compositor + /// CubicBezierEasingFunction + public static CubicBezierEasingFunction CreateEaseInQuinticEasingFunction(this Compositor compositor) + { + return compositor.CreateCubicBezierEasingFunction(new Vector2(0.755f, 0.050f), new Vector2(0.855f, 0.060f)); + } + + /// + /// Sine Easing Function - Ease In + /// + /// Compositor + /// CubicBezierEasingFunction + public static CubicBezierEasingFunction CreateEaseInSineEasingFunction(this Compositor compositor) + { + return compositor.CreateCubicBezierEasingFunction(new Vector2(0.470f, 0.000f), new Vector2(0.745f, 0.715f)); + } + + /// + /// Back Easing Function - Ease Out + /// + /// Compositor + /// CubicBezierEasingFunction + public static CubicBezierEasingFunction CreateEaseOutBackEasingFunction(this Compositor compositor) + { + return compositor.CreateCubicBezierEasingFunction(new Vector2(0.175f, 0.885f), new Vector2(0.320f, 1.275f)); + } + + /// + /// Circle Easing Function - Ease Out + /// + /// Compositor + /// CubicBezierEasingFunction + public static CubicBezierEasingFunction CreateEaseOutCircleEasingFunction(this Compositor compositor) + { + return compositor.CreateCubicBezierEasingFunction(new Vector2(0.075f, 0.820f), new Vector2(0.165f, 1.000f)); + } + + /// + /// Cubic Easing Function - Ease Out + /// + /// Compositor + /// CubicBezierEasingFunction + public static CubicBezierEasingFunction CreateEaseOutCubicEasingFunction(this Compositor compositor) + { + return compositor.CreateCubicBezierEasingFunction(new Vector2(0.215f, 0.610f), new Vector2(0.355f, 1.000f)); + } + + /// + /// Exponential Easing Function - Ease Out + /// + /// Compositor + /// CubicBezierEasingFunction + public static CubicBezierEasingFunction CreateEaseOutExponentialEasingFunction(this Compositor compositor) + { + return compositor.CreateCubicBezierEasingFunction(new Vector2(0.190f, 1.000f), new Vector2(0.220f, 1.000f)); + } + + /// + /// Quadratic Easing Function - Ease Out + /// + /// Compositor + /// CubicBezierEasingFunction + public static CubicBezierEasingFunction CreateEaseOutQuadraticEasingFunction(this Compositor compositor) + { + return compositor.CreateCubicBezierEasingFunction(new Vector2(0.250f, 0.460f), new Vector2(0.450f, 0.940f)); + } + + /// + /// Quartic Easing Function - Ease Out + /// + /// Compositor + /// CubicBezierEasingFunction + public static CubicBezierEasingFunction CreateEaseOutQuarticEasingFunction(this Compositor compositor) + { + return compositor.CreateCubicBezierEasingFunction(new Vector2(0.165f, 0.840f), new Vector2(0.440f, 1.000f)); + } + + /// + /// Quintic Easing Function - Ease Out + /// + /// Compositor + /// CubicBezierEasingFunction + public static CubicBezierEasingFunction CreateEaseOutQuinticEasingFunction(this Compositor compositor) + { + return compositor.CreateCubicBezierEasingFunction(new Vector2(0.230f, 1.000f), new Vector2(0.320f, 1.000f)); + } + + /// + /// Sine Easing Function - Ease Out + /// + /// Compositor + /// CubicBezierEasingFunction + public static CubicBezierEasingFunction CreateEaseOutSineEasingFunction(this Compositor compositor) + { + return compositor.CreateCubicBezierEasingFunction(new Vector2(0.390f, 0.575f), new Vector2(0.565f, 1.000f)); + } + + /// + /// Back Easing Function - Ease In Out + /// + /// Compositor + /// CubicBezierEasingFunction + public static CubicBezierEasingFunction CreateEaseInOutBackEasingFunction(this Compositor compositor) + { + return compositor.CreateCubicBezierEasingFunction(new Vector2(0.680f, -0.550f), new Vector2(0.265f, 1.550f)); + } + + /// + /// Circle Easing Function - Ease In Out + /// + /// Compositor + /// CubicBezierEasingFunction + public static CubicBezierEasingFunction CreateEaseInOutCircleEasingFunction(this Compositor compositor) + { + return compositor.CreateCubicBezierEasingFunction(new Vector2(0.785f, 0.135f), new Vector2(0.150f, 0.860f)); + } + + /// + /// Cubic Easing Function - Ease In Out + /// + /// Compositor + /// CubicBezierEasingFunction + public static CubicBezierEasingFunction CreateEaseInOutCubicEasingFunction(this Compositor compositor) + { + return compositor.CreateCubicBezierEasingFunction(new Vector2(0.645f, 0.045f), new Vector2(0.355f, 1.000f)); + } + + /// + /// Exponential Easing Function - Ease In Out + /// + /// Compositor + /// CubicBezierEasingFunction + public static CubicBezierEasingFunction CreateEaseInOutExponentialEasingFunction(this Compositor compositor) + { + return compositor.CreateCubicBezierEasingFunction(new Vector2(1.000f, 0.000f), new Vector2(0.000f, 1.000f)); + } + + /// + /// Quadratic Easing Function - Ease In Out + /// + /// Compositor + /// CubicBezierEasingFunction + public static CubicBezierEasingFunction CreateEaseInOutQuadraticEasingFunction(this Compositor compositor) + { + return compositor.CreateCubicBezierEasingFunction(new Vector2(0.455f, 0.030f), new Vector2(0.515f, 0.955f)); + } + + /// + /// Quartic Easing Function - Ease In Out + /// + /// Compositor + /// CubicBezierEasingFunction + public static CubicBezierEasingFunction CreateEaseInOutQuarticEasingFunction(this Compositor compositor) + { + return compositor.CreateCubicBezierEasingFunction(new Vector2(0.770f, 0.000f), new Vector2(0.175f, 1.000f)); + } + + /// + /// Quintic Easing Function - Ease In Out + /// + /// Compositor + /// CubicBezierEasingFunction + public static CubicBezierEasingFunction CreateEaseInOutQuinticEasingFunction(this Compositor compositor) + { + return compositor.CreateCubicBezierEasingFunction(new Vector2(0.860f, 0.000f), new Vector2(0.070f, 1.000f)); + } + + /// + /// Sine Easing Function - Ease In Out + /// + /// Compositor + /// CubicBezierEasingFunction + public static CubicBezierEasingFunction CreateEaseInOutSineEasingFunction(this Compositor compositor) + { + return compositor.CreateCubicBezierEasingFunction(new Vector2(0.445f, 0.050f), new Vector2(0.550f, 0.950f)); + } + + /// + /// Creates the CompositionSurfaceBrush from the specified render surface. + /// + /// Compositor + /// An object deriving from IMaskSurface, IGaussianMaskSurface, IGeometrySurface or IImageSurface + /// CompositionSurfaceBrush + public static CompositionSurfaceBrush CreateSurfaceBrush(this Compositor compositor, IRenderSurface renderSurface) + { + return compositor.CreateSurfaceBrush(renderSurface.Surface); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/GaussianMaskSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/GaussianMaskSurface.cs new file mode 100644 index 00000000000..01262c2e91d --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/GaussianMaskSurface.cs @@ -0,0 +1,246 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Numerics; +using Microsoft.Graphics.Canvas.Geometry; +using Windows.Foundation; +using Windows.UI.Composition; + +namespace Microsoft.Toolkit.Uwp.UI.Media.Surface +{ + /// + /// Class for rendering custom shaped geometries onto ICompositionSurface + /// so that they can be used as masks on Composition Visuals. These geometries + /// have a Gaussian Blur applied to them. + /// + internal sealed class GaussianMaskSurface : IGaussianMaskSurface + { + private readonly object _surfaceLock; + private ICompositionGeneratorInternal _generator; + private CompositionDrawingSurface _surface; + + /// + /// Gets the Composition Generator + /// + public ICompositionGenerator Generator => _generator; + + /// + /// Gets the Surface of GaussianMaskSurface + /// + public ICompositionSurface Surface => _surface; + + /// + /// Gets the Geometry of the GaussianMaskSurface + /// + public CanvasGeometry Geometry { get; private set; } + + /// + /// Gets the Size of the GaussianMaskSurface + /// + public Size Size { get; private set; } + + /// + /// Gets the offset from the top left corner of the ICompositionSurface where + /// the Geometry is rendered. + /// + public Vector2 Offset { get; private set; } + + /// + /// Gets radius of Gaussian Blur to be applied on the GaussianMaskSurface + /// + public float BlurRadius { get; private set; } + + /// + /// Initializes a new instance of the class. + /// Constructor + /// + /// ICompositionMaskGeneratorInternal object + /// Size of the GaussianMaskSurface + /// Geometry of the GaussianMaskSurface + /// The offset from the top left corner of the ICompositionSurface where + /// the Geometry is rendered. + /// Radius of Gaussian Blur to be applied on the GaussianMaskSurface + public GaussianMaskSurface(ICompositionGeneratorInternal generator, Size size, CanvasGeometry geometry, Vector2 offset, float blurRadius) + { + _generator = generator ?? throw new ArgumentNullException(nameof(generator), "CompositionGenerator cannot be null!"); + _surfaceLock = new object(); + Geometry = geometry; + Offset = offset; + BlurRadius = Math.Abs(blurRadius); + + // Create Mask Surface + _surface = _generator.CreateDrawingSurface(_surfaceLock, size); + + // Set the size + Size = _surface?.Size ?? new Size(0, 0); + + // Subscribe to DeviceReplaced event + _generator.DeviceReplaced += OnDeviceReplaced; + } + + /// + /// Redraws the GaussianMaskSurface + /// + public void Redraw() + { + // Redraw the mask surface + RedrawSurface(); + } + + /// + /// Applies the given blur radius to the IGaussianMaskSurface. + /// + /// Radius of Gaussian Blur to be applied on the GaussianMaskSurface + public void Redraw(float blurRadius) + { + Redraw(Size, Geometry, Offset, blurRadius); + } + + /// + /// Redraws the GaussianMaskSurface with the new geometry + /// + /// New CanvasGeometry to be applied to the mask + public void Redraw(CanvasGeometry geometry) + { + Redraw(Size, geometry, Offset, BlurRadius); + } + + /// + /// Redraws the GaussianMaskSurface with the new geometry at the specified offset. + /// + /// New CanvasGeometry to be applied to the mask + /// The offset from the top left corner of the ICompositionSurface where + /// the Geometry is rendered. + public void Redraw(CanvasGeometry geometry, Vector2 offset) + { + Redraw(Size, geometry, offset, BlurRadius); + } + + /// + /// Redraws the IGaussianMaskSurface with the new geometry and fills it with White color after applying + /// the Gaussian blur with given blur radius. + /// + /// New CanvasGeometry to be applied to the GaussianMaskSurface + /// The offset from the top left corner of the ICompositionSurface where + /// the Geometry is rendered. + /// Radius of Gaussian Blur to be applied on the IGaussianMaskSurface + public void Redraw(CanvasGeometry geometry, Vector2 offset, float blurRadius) + { + Redraw(Size, geometry, offset, blurRadius); + } + + /// + /// Resizes the GaussianMaskSurface with the given size and redraws the GaussianMaskSurface + /// with the new geometry and fills it with White color. A Gaussian blur is applied to the + /// new geometry. + /// + /// New size of the mask + /// New CanvasGeometry to be applied to the mask + public void Redraw(Size size, CanvasGeometry geometry) + { + Redraw(size, geometry, Offset, BlurRadius); + } + + /// + /// Resizes the GaussianMaskSurface with the given size and redraws the GaussianMaskSurface + /// with the new geometry at the specified offset and fills it with White color. A Gaussian + /// blur is applied to the new geometry. + /// + /// New size of the mask + /// New CanvasGeometry to be applied to the mask + /// The offset from the top left corner of the ICompositionSurface where + /// the Geometry is rendered. + public void Redraw(Size size, CanvasGeometry geometry, Vector2 offset) + { + Redraw(size, geometry, offset, BlurRadius); + } + + /// + /// Resizes the GaussianMaskSurface with the given size and redraws the GaussianMaskSurface + /// with the new geometry and fills it with White color. A Gaussian blur is applied to the + /// new geometry. + /// + /// New size of the mask + /// New CanvasGeometry to be applied to the mask + /// The offset from the top left corner of the ICompositionSurface where + /// the Geometry is rendered. + /// Radius of Gaussian Blur to be applied on the GaussianMaskSurface + public void Redraw(Size size, CanvasGeometry geometry, Vector2 offset, float blurRadius) + { + // Resize the mask surface + _generator.ResizeDrawingSurface(_surfaceLock, _surface, size); + + // Set the size + Size = _surface?.Size ?? new Size(0, 0); + + // Set the offset + Offset = offset; + + // Set the new geometry + Geometry = geometry; + + // Set the new blur radius + BlurRadius = blurRadius; + + // Redraw the mask surface + RedrawSurface(); + } + + /// + /// Resizes the GaussianMaskSurface to the new size. + /// + /// New size of the mask + public void Resize(Size size) + { + // resize the mask surface + _generator.ResizeDrawingSurface(_surfaceLock, _surface, size); + + // Set the size + Size = _surface?.Size ?? new Size(0, 0); + + // Redraw the mask surface + RedrawSurface(); + } + + /// + /// Disposes the resources used by the GaussianMaskSurface + /// + public void Dispose() + { + _surface?.Dispose(); + Geometry?.Dispose(); + if (_generator != null) + { + _generator.DeviceReplaced -= OnDeviceReplaced; + } + + _surface = null; + _generator = null; + Geometry = null; + } + + /// + /// Handles the DeviceReplaced event + /// + /// Sender + /// object + private void OnDeviceReplaced(object sender, object e) + { + // Recreate the GaussianMaskSurface + _surface = _generator.CreateDrawingSurface(_surfaceLock, Size); + + // Redraw the mask surface + RedrawSurface(); + } + + /// + /// Helper class to redraw the GaussianMaskSurface + /// + private void RedrawSurface() + { + _generator.RedrawGaussianMaskSurface(_surfaceLock, _surface, Size, Geometry, Offset, BlurRadius); + } + } +} \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometrySurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometrySurface.cs new file mode 100644 index 00000000000..adda48a0cc7 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometrySurface.cs @@ -0,0 +1,963 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Microsoft.Graphics.Canvas.Brushes; +using Microsoft.Graphics.Canvas.Geometry; +using Microsoft.Toolkit.Uwp.UI.Media.Geometry; +using Windows.Foundation; +using Windows.UI; +using Windows.UI.Composition; + +namespace Microsoft.Toolkit.Uwp.UI.Media.Surface +{ + /// + /// Class for rendering custom shaped geometries onto ICompositionSurface + /// + internal sealed class GeometrySurface : IGeometrySurface + { + private readonly object _surfaceLock; + private ICompositionGeneratorInternal _generator; + private CompositionDrawingSurface _surface; + private CanvasGeometry _geometry; + private ICanvasStroke _stroke; + private ICanvasBrush _fill; + private ICanvasBrush _backgroundBrush; + + /// + /// Gets the Surface Generator + /// + public ICompositionGenerator Generator => _generator; + + /// + /// Gets the Surface of the GeometrySurface + /// + public ICompositionSurface Surface => _surface; + + /// + /// Gets the Geometry of the GeometrySurface + /// + public CanvasGeometry Geometry => _geometry; + + /// + /// Gets the ICanvasStroke with which the Geometry outline is rendered. + /// + public ICanvasStroke Stroke => _stroke; + + /// + /// Gets the Brush with which the Geometry is filled. + /// + public ICanvasBrush Fill => _fill; + + /// + /// Gets the Brush with which the GeometrySurface background is filled. + /// + public ICanvasBrush BackgroundBrush => _backgroundBrush; + + /// + /// Gets the Size of the GeometrySurface + /// + public Size Size { get; private set; } + + /// + /// Initializes a new instance of the class. + /// Constructor + /// + /// ICompositionMaskGeneratorInternal object + /// Size of the GeometrySurface + /// Geometry of the GeometrySurface + /// Stroke for the geometry + /// Fill color of the geometry + /// Brush to fill the GeometrySurface background surface which is + /// not covered by the geometry + public GeometrySurface(ICompositionGeneratorInternal generator, Size size, CanvasGeometry geometry, ICanvasStroke stroke, Color fillColor, Color backgroundColor) + { + _generator = generator ?? throw new ArgumentNullException(nameof(generator), "CompositionGenerator cannot be null!"); + _surfaceLock = new object(); + _geometry = geometry; + _stroke = stroke; + _fill = new CanvasSolidColorBrush(_generator.Device, fillColor); + _backgroundBrush = new CanvasSolidColorBrush(_generator.Device, backgroundColor); + + // Create GeometrySurface + _surface = _generator.CreateDrawingSurface(_surfaceLock, size); + + // Set the size + Size = _surface?.Size ?? new Size(0, 0); + + // Subscribe to DeviceReplaced event + _generator.DeviceReplaced += OnDeviceReplaced; + } + + /// + /// Initializes a new instance of the class. + /// Constructor + /// + /// ICompositionMaskGeneratorInternal object + /// Size of the GeometrySurface + /// Geometry of the GeometrySurface + /// Stroke for the geometry + /// Brush to fill the geometry + /// Brush to fill the GeometrySurface background surface which is + /// not covered by the geometry + public GeometrySurface(ICompositionGeneratorInternal generator, Size size, CanvasGeometry geometry, ICanvasStroke stroke, ICanvasBrush fill, ICanvasBrush backgroundBrush) + { + _generator = generator ?? throw new ArgumentNullException(nameof(generator), "CompositionGenerator cannot be null!"); + _surfaceLock = new object(); + _geometry = geometry; + _stroke = stroke; + _fill = fill; + _backgroundBrush = backgroundBrush; + + // Create GeometrySurface + _surface = _generator.CreateDrawingSurface(_surfaceLock, size); + + // Set the size + Size = _surface?.Size ?? new Size(0, 0); + + // Subscribe to DeviceReplaced event + _generator.DeviceReplaced += OnDeviceReplaced; + } + + /// + /// Redraws the GeometrySurface + /// + public void Redraw() + { + // Redraw the GeometrySurface + RedrawSurface(); + } + + /// + /// Redraws the GeometrySurface with the new geometry + /// + /// New CanvasGeometry to be applied to the GeometrySurface + public void Redraw(CanvasGeometry geometry) + { + // Set the new geometry + _geometry = geometry; + + // Redraw the GeometrySurface + RedrawSurface(); + } + + /// + /// Redraws the GeometrySurface by outlining the existing geometry with + /// the given ICanvasStroke + /// + /// ICanvasStroke defining the outline for the geometry + public void Redraw(ICanvasStroke stroke) + { + // Set the new stroke + _stroke = stroke; + + // Redraw the GeometrySurface + RedrawSurface(); + } + + /// + /// Redraws the GeometrySurface by filling the existing geometry with + /// the foreground color. + /// + /// Color with which the GeometrySurface geometry is to be filled + public void Redraw(Color fillColor) + { + // Set the fill + if (_fill is CanvasSolidColorBrush fillBrush) + { + fillBrush.Color = fillColor; + } + else + { + _fill = new CanvasSolidColorBrush(_generator.Device, fillColor); + } + + // Redraw the GeometrySurface + RedrawSurface(); + } + + /// + /// Redraws the GeometrySurface by filling the existing geometry with + /// the given fill color and outlining it with the given ICanvasStroke. + /// + /// ICanvasStroke defining the outline for the geometry + /// Color with which the geometry is to be filled + public void Redraw(ICanvasStroke stroke, Color fillColor) + { + // Set the new stroke + _stroke = stroke; + + // Set the fill + if (_fill is CanvasSolidColorBrush fillBrush) + { + fillBrush.Color = fillColor; + } + else + { + _fill = new CanvasSolidColorBrush(_generator.Device, fillColor); + } + + // Redraw the GeometrySurface + RedrawSurface(); + } + + /// + /// Redraws the GeometrySurface by filling the existing geometry with + /// the foreground color and the background with the background color. + /// + /// Color with which the GeometrySurface geometry is to be filled + /// Color with which the GeometrySurface background is to be filled + public void Redraw(Color fillColor, Color backgroundColor) + { + // Set the fill + if (_fill is CanvasSolidColorBrush fillBrush) + { + fillBrush.Color = fillColor; + } + else + { + _fill = new CanvasSolidColorBrush(_generator.Device, fillColor); + } + + // Set the backgroundBrush + if (_backgroundBrush is CanvasSolidColorBrush backBrush) + { + backBrush.Color = backgroundColor; + } + else + { + _backgroundBrush = new CanvasSolidColorBrush(_generator.Device, backgroundColor); + } + + // Redraw the GeometrySurface + RedrawSurface(); + } + + /// + /// Redraws the GeometrySurface by outlining the existing geometry with the + /// given ICanvasStroke, filling it with the fill color and the background with the background color. + /// + /// ICanvasStroke defining the outline for the geometry + /// Color with which the geometry is to be filled + /// Color with which the GeometrySurface background is to be filled + public void Redraw(ICanvasStroke stroke, Color fillColor, Color backgroundColor) + { + // Set the new stroke + _stroke = stroke; + + // Set the fill + if (_fill is CanvasSolidColorBrush fillBrush) + { + fillBrush.Color = fillColor; + } + else + { + _fill = new CanvasSolidColorBrush(_generator.Device, fillColor); + } + + // Set the backgroundBrush + if (_backgroundBrush is CanvasSolidColorBrush backBrush) + { + backBrush.Color = backgroundColor; + } + else + { + _backgroundBrush = new CanvasSolidColorBrush(_generator.Device, backgroundColor); + } + + // Redraw the GeometrySurface + RedrawSurface(); + } + + /// + /// Redraws the GeometrySurface by filling the existing geometry with + /// the foreground brush. + /// + /// Brush with which the GeometrySurface geometry is to be filled + public void Redraw(ICanvasBrush fillBrush) + { + // Set the fill + _fill = fillBrush ?? new CanvasSolidColorBrush(_generator.Device, Colors.Transparent); + + // Redraw the GeometrySurface + RedrawSurface(); + } + + /// + /// Redraws the GeometrySurface by outlining the existing geometry with the + /// given ICanvasStroke, filling it with the fill brush. + /// + /// ICanvasStroke defining the outline for the geometry + /// Brush with which the geometry is to be filled + public void Redraw(ICanvasStroke stroke, ICanvasBrush fillBrush) + { + // Set the new stroke + _stroke = stroke; + + // Set the fill + _fill = fillBrush ?? new CanvasSolidColorBrush(_generator.Device, Colors.Transparent); + + // Redraw the GeometrySurface + RedrawSurface(); + } + + /// + /// Redraws the GeometrySurface by filling the existing geometry with + /// the foreground brush and the background with the background brush. + /// + /// Brush with which the GeometrySurface geometry is to be filled + /// Brush with which the GeometrySurface background is to be filled + public void Redraw(ICanvasBrush fillBrush, ICanvasBrush backgroundBrush) + { + // Set the fill + _fill = fillBrush ?? new CanvasSolidColorBrush(_generator.Device, Colors.Transparent); + + // Set the backgroundBrush + _backgroundBrush = backgroundBrush ?? new CanvasSolidColorBrush(_generator.Device, Colors.Transparent); + + // Redraw the GeometrySurface + RedrawSurface(); + } + + /// + /// Redraws the GeometrySurface by outlining the existing geometry with the + /// given ICanvasStroke, filling it with the fill brush and the background with the background brush. + /// + /// ICanvasStroke defining the outline for the geometry + /// Brush with which the geometry is to be filled + /// Brush with which the GeometrySurface background is to be filled + public void Redraw(ICanvasStroke stroke, ICanvasBrush fillBrush, ICanvasBrush backgroundBrush) + { + // Set the new stroke + _stroke = stroke; + + // Set the fill + _fill = fillBrush ?? new CanvasSolidColorBrush(_generator.Device, Colors.Transparent); + + // Set the backgroundBrush + _backgroundBrush = backgroundBrush ?? new CanvasSolidColorBrush(_generator.Device, Colors.Transparent); + + // Redraw the GeometrySurface + RedrawSurface(); + } + + /// + /// Redraws the GeometrySurface by filling the existing geometry with + /// the foreground color and the background with the background brush. + /// + /// Color with which the GeometrySurface geometry is to be filled + /// Brush with which the GeometrySurface background is to be filled + public void Redraw(Color fillColor, ICanvasBrush backgroundBrush) + { + // Set the fill + if (_fill is CanvasSolidColorBrush fillBrush) + { + fillBrush.Color = fillColor; + } + else + { + _fill = new CanvasSolidColorBrush(_generator.Device, fillColor); + } + + // Set the backgroundBrush + _backgroundBrush = backgroundBrush ?? new CanvasSolidColorBrush(_generator.Device, Colors.Transparent); + + // Redraw the GeometrySurface + RedrawSurface(); + } + + /// + /// Redraws the GeometrySurface by outlining the existing geometry with the + /// given ICanvasStroke, filling it with the fill color and the background with the background brush. + /// + /// ICanvasStroke defining the outline for the geometry + /// Color with which the geometry is to be filled + /// Brush with which the GeometrySurface background is to be filled + public void Redraw(ICanvasStroke stroke, Color fillColor, ICanvasBrush backgroundBrush) + { + // Set the new stroke + _stroke = stroke; + + // Set the fill + if (_fill is CanvasSolidColorBrush fillBrush) + { + fillBrush.Color = fillColor; + } + else + { + _fill = new CanvasSolidColorBrush(_generator.Device, fillColor); + } + + // Set the backgroundBrush + _backgroundBrush = backgroundBrush ?? new CanvasSolidColorBrush(_generator.Device, Colors.Transparent); + + // Redraw the GeometrySurface + RedrawSurface(); + } + + /// + /// Redraws the GeometrySurface by filling the existing geometry with + /// the foreground brush and the background with the background brush. + /// + /// Brush with which the GeometrySurface geometry is to be filled + /// Color with which the GeometrySurface background is to be filled + public void Redraw(ICanvasBrush fillBrush, Color backgroundColor) + { + // Set the fill + _fill = fillBrush ?? new CanvasSolidColorBrush(_generator.Device, Colors.Transparent); + + // Set the backgroundBrush + if (_backgroundBrush is CanvasSolidColorBrush backBrush) + { + backBrush.Color = backgroundColor; + } + else + { + _backgroundBrush = new CanvasSolidColorBrush(_generator.Device, backgroundColor); + } + + // Redraw the GeometrySurface + RedrawSurface(); + } + + /// + /// Redraws the GeometrySurface by outlining the existing geometry with the + /// given ICanvasStroke, filling it with the fill brush and the background with the background color. + /// + /// ICanvasStroke defining the outline for the geometry + /// Brush with which the geometry is to be filled + /// Color with which the GeometrySurface background is to be filled + public void Redraw(ICanvasStroke stroke, ICanvasBrush fillBrush, Color backgroundColor) + { + // Set the new stroke + _stroke = stroke; + + // Set the fill + _fill = fillBrush ?? new CanvasSolidColorBrush(_generator.Device, Colors.Transparent); + + // Set the backgroundBrush + if (_backgroundBrush is CanvasSolidColorBrush backBrush) + { + backBrush.Color = backgroundColor; + } + else + { + _backgroundBrush = new CanvasSolidColorBrush(_generator.Device, backgroundColor); + } + + // Redraw the GeometrySurface + RedrawSurface(); + } + + /// + /// Resizes the GeometrySurface with the given size and redraws the GeometrySurface with the new geometry + /// + /// New size of the GeometrySurface + /// New CanvasGeometry to be applied to the GeometrySurface + public void Redraw(Size size, CanvasGeometry geometry) + { + // Resize the GeometrySurface + _generator.ResizeDrawingSurface(_surfaceLock, _surface, size); + + // Set the size + Size = _surface?.Size ?? new Size(0, 0); + + // Set the new geometry + _geometry = geometry; + + // Redraw the GeometrySurface + RedrawSurface(); + } + + /// + /// Resizes the GeometrySurface with the given size and redraws the GeometrySurface + /// with the new geometry and outlines it with the given ICanvasStroke. + /// + /// New size of the GeometrySurface + /// New CanvasGeometry to be applied to the GeometrySurface + /// ICanvasStroke defining the outline for the geometry + public void Redraw(Size size, CanvasGeometry geometry, ICanvasStroke stroke) + { + // Resize the GeometrySurface + _generator.ResizeDrawingSurface(_surfaceLock, _surface, size); + + // Set the size + Size = _surface?.Size ?? new Size(0, 0); + + // Set the new geometry + _geometry = geometry; + + // Set the new stroke + _stroke = stroke; + + // Redraw the GeometrySurface + RedrawSurface(); + } + + /// + /// Resizes the GeometrySurface with the given size and redraws the GeometrySurface + /// with the new geometry and fills it with the foreground color. + /// + /// New size of the GeometrySurface + /// New CanvasGeometry to be applied to the GeometrySurface + /// Fill color for the geometry + public void Redraw(Size size, CanvasGeometry geometry, Color fillColor) + { + // Resize the GeometrySurface + _generator.ResizeDrawingSurface(_surfaceLock, _surface, size); + + // Set the size + Size = _surface?.Size ?? new Size(0, 0); + + // Set the new geometry + _geometry = geometry; + + // Set the fill + if (_fill is CanvasSolidColorBrush fillBrush) + { + fillBrush.Color = fillColor; + } + else + { + _fill = new CanvasSolidColorBrush(_generator.Device, fillColor); + } + + // Redraw the GeometrySurface + RedrawSurface(); + } + + /// + /// Resizes the GeometrySurface with the given size and redraws the GeometrySurface + /// with the new geometry, outlines it with the given ICanvasStroke and fills + /// it with the fill color. + /// + /// New size of the GeometrySurface + /// New CanvasGeometry to be applied to the GeometrySurface + /// ICanvasStroke defining the outline for the geometry + /// Fill color for the geometry + public void Redraw(Size size, CanvasGeometry geometry, ICanvasStroke stroke, Color fillColor) + { + // Resize the GeometrySurface + _generator.ResizeDrawingSurface(_surfaceLock, _surface, size); + + // Set the size + Size = _surface?.Size ?? new Size(0, 0); + + // Set the new geometry + _geometry = geometry; + + // Set the new stroke + _stroke = stroke; + + // Set the fill + if (_fill is CanvasSolidColorBrush fillBrush) + { + fillBrush.Color = fillColor; + } + else + { + _fill = new CanvasSolidColorBrush(_generator.Device, fillColor); + } + + // Redraw the GeometrySurface + RedrawSurface(); + } + + /// + /// Resizes the GeometrySurface with the given size and redraws the GeometrySurface + /// with the new geometry and fills it with the foreground color and + /// fills the background with the background color. + /// + /// New size of the GeometrySurface + /// New CanvasGeometry to be applied to the GeometrySurface + /// Fill color for the geometry + /// Fill color for the GeometrySurface background + public void Redraw(Size size, CanvasGeometry geometry, Color fillColor, Color backgroundColor) + { + // Resize the GeometrySurface + _generator.ResizeDrawingSurface(_surfaceLock, _surface, size); + + // Set the size + Size = _surface?.Size ?? new Size(0, 0); + + // Set the new geometry + _geometry = geometry; + + // Set the fill + if (_fill is CanvasSolidColorBrush fillBrush) + { + fillBrush.Color = fillColor; + } + else + { + _fill = new CanvasSolidColorBrush(_generator.Device, fillColor); + } + + // Set the backgroundBrush + if (_backgroundBrush is CanvasSolidColorBrush backBrush) + { + backBrush.Color = backgroundColor; + } + else + { + _backgroundBrush = new CanvasSolidColorBrush(_generator.Device, backgroundColor); + } + + // Redraw the GeometrySurface + RedrawSurface(); + } + + /// + /// Resizes the GeometrySurface with the given size and redraws the GeometrySurface + /// with the new geometry, outlines it with the given ICanvasStroke and fills it with + /// the fill color and fills the background with the background color. + /// + /// New size of the GeometrySurface + /// New CanvasGeometry to be applied to the GeometrySurface + /// ICanvasStroke defining the outline for the geometry + /// Fill color for the geometry + /// Fill color for the GeometrySurface background + public void Redraw(Size size, CanvasGeometry geometry, ICanvasStroke stroke, Color fillColor, Color backgroundColor) + { + // Resize the GeometrySurface + _generator.ResizeDrawingSurface(_surfaceLock, _surface, size); + + // Set the size + Size = _surface?.Size ?? new Size(0, 0); + + // Set the new geometry + _geometry = geometry; + + // Set the new stroke + _stroke = stroke; + + // Set the fill + if (_fill is CanvasSolidColorBrush fillBrush) + { + fillBrush.Color = fillColor; + } + else + { + _fill = new CanvasSolidColorBrush(_generator.Device, fillColor); + } + + // Set the backgroundBrush + if (_backgroundBrush is CanvasSolidColorBrush backBrush) + { + backBrush.Color = backgroundColor; + } + else + { + _backgroundBrush = new CanvasSolidColorBrush(_generator.Device, backgroundColor); + } + + // Redraw the GeometrySurface + RedrawSurface(); + } + + /// + /// Resizes the GeometrySurface with the given size and redraws the GeometrySurface + /// with the new geometry and fills it with the foreground brush. + /// + /// New size of the GeometrySurface + /// New CanvasGeometry to be applied to the GeometrySurface + /// Brush to fill the geometry + public void Redraw(Size size, CanvasGeometry geometry, ICanvasBrush fillBrush) + { + // Resize the GeometrySurface + _generator.ResizeDrawingSurface(_surfaceLock, _surface, size); + + // Set the size + Size = _surface?.Size ?? new Size(0, 0); + + // Set the new geometry + _geometry = geometry; + + // Set the fill + _fill = fillBrush ?? new CanvasSolidColorBrush(_generator.Device, Colors.Transparent); + + // Redraw the GeometrySurface + RedrawSurface(); + } + + /// + /// Resizes the GeometrySurface with the given size and redraws the GeometrySurface + /// with the new geometry and fills it with the foreground brush and fills + /// the background with the background brush. + /// + /// New size of the GeometrySurface + /// New CanvasGeometry to be applied to the GeometrySurface + /// Brush to fill the geometry + /// Brush to fill the GeometrySurface background + public void Redraw(Size size, CanvasGeometry geometry, ICanvasBrush fillBrush, ICanvasBrush backgroundBrush) + { + _generator.ResizeDrawingSurface(_surfaceLock, _surface, size); + + // Set the size + Size = _surface?.Size ?? new Size(0, 0); + + // Set the new geometry + _geometry = geometry; + + // Set the fill + _fill = fillBrush ?? new CanvasSolidColorBrush(_generator.Device, Colors.Transparent); + + // Set the backgroundBrush + _backgroundBrush = backgroundBrush ?? new CanvasSolidColorBrush(_generator.Device, Colors.Transparent); + + // Redraw the GeometrySurface + RedrawSurface(); + } + + /// + /// Resizes the GeometrySurface with the given size and redraws the GeometrySurface + /// with the new geometry, outlines it with the given ICanvasStroke and fills it with the + /// fill brush and fills the background with the background brush. + /// + /// New size of the GeometrySurface + /// New CanvasGeometry to be applied to the GeometrySurface + /// ICanvasStroke defining the outline for the geometry + /// Brush to fill the geometry + /// Brush to fill the GeometrySurface background + public void Redraw(Size size, CanvasGeometry geometry, ICanvasStroke stroke, ICanvasBrush fillBrush, ICanvasBrush backgroundBrush) + { + // Resize the GeometrySurface + _generator.ResizeDrawingSurface(_surfaceLock, _surface, size); + + // Set the size + Size = _surface?.Size ?? new Size(0, 0); + + // Set the new geometry + _geometry = geometry; + + // Set the new stroke + _stroke = stroke; + + // Set the fill + _fill = fillBrush ?? new CanvasSolidColorBrush(_generator.Device, Colors.Transparent); + + // Set the backgroundBrush + _backgroundBrush = backgroundBrush ?? new CanvasSolidColorBrush(_generator.Device, Colors.Transparent); + + // Redraw the GeometrySurface + RedrawSurface(); + } + + /// + /// Resizes the GeometrySurface with the given size and redraws the GeometrySurface + /// with the new geometry and fills it with the foreground brush and the background + /// with the background color. + /// + /// New size of the GeometrySurface + /// New CanvasGeometry to be applied to the GeometrySurface + /// Brush to fill the geometry + /// Fill color for the GeometrySurface background + public void Redraw(Size size, CanvasGeometry geometry, ICanvasBrush fillBrush, Color backgroundColor) + { + _generator.ResizeDrawingSurface(_surfaceLock, _surface, size); + + // Set the size + Size = _surface?.Size ?? new Size(0, 0); + + // Set the new geometry + _geometry = geometry; + + // Set the fill + _fill = fillBrush ?? new CanvasSolidColorBrush(_generator.Device, Colors.Transparent); + + // Set the backgroundBrush + if (_backgroundBrush is CanvasSolidColorBrush backBrush) + { + backBrush.Color = backgroundColor; + } + else + { + _backgroundBrush = new CanvasSolidColorBrush(_generator.Device, backgroundColor); + } + + // Redraw the GeometrySurface + RedrawSurface(); + } + + /// + /// Resizes the GeometrySurface with the given size and redraws the GeometrySurface + /// with the new geometry, outlines it with the given ICanvasStroke and fills it with + /// the fill brush and the background with the background color. + /// + /// New size of the GeometrySurface + /// New CanvasGeometry to be applied to the GeometrySurface + /// ICanvasStroke defining the outline for the geometry + /// Brush to fill the geometry + /// Fill color for the GeometrySurface background + public void Redraw(Size size, CanvasGeometry geometry, ICanvasStroke stroke, ICanvasBrush fillBrush, Color backgroundColor) + { + // Resize the GeometrySurface + _generator.ResizeDrawingSurface(_surfaceLock, _surface, size); + + // Set the size + Size = _surface?.Size ?? new Size(0, 0); + + // Set the new geometry + _geometry = geometry; + + // Set the new stroke + _stroke = stroke; + + // Set the fill + _fill = fillBrush ?? new CanvasSolidColorBrush(_generator.Device, Colors.Transparent); + + // Set the backgroundBrush + if (_backgroundBrush is CanvasSolidColorBrush backBrush) + { + backBrush.Color = backgroundColor; + } + else + { + _backgroundBrush = new CanvasSolidColorBrush(_generator.Device, backgroundColor); + } + + // Redraw the GeometrySurface + RedrawSurface(); + } + + /// + /// Resizes the GeometrySurface with the given size and redraws the GeometrySurface + /// with the new geometry and fills it with the foreground color and the background + /// with the background brush. + /// + /// New size of the GeometrySurface + /// New CanvasGeometry to be applied to the GeometrySurface + /// Fill color for the geometry + /// Brush to fill the GeometrySurface background + public void Redraw(Size size, CanvasGeometry geometry, Color fillColor, ICanvasBrush backgroundBrush) + { + _generator.ResizeDrawingSurface(_surfaceLock, _surface, size); + + // Set the size + Size = _surface?.Size ?? new Size(0, 0); + + // Set the new geometry + _geometry = geometry; + + // Set the fill + if (_fill is CanvasSolidColorBrush fillBrush) + { + fillBrush.Color = fillColor; + } + else + { + _fill = new CanvasSolidColorBrush(_generator.Device, fillColor); + } + + // Set the backgroundBrush + _backgroundBrush = backgroundBrush ?? new CanvasSolidColorBrush(_generator.Device, Colors.Transparent); + + // Redraw the GeometrySurface + RedrawSurface(); + } + + /// + /// Resizes the GeometrySurface with the given size and redraws the GeometrySurface + /// with the new geometry, outlines it with the given ICanvasStroke and fills it with + /// the fill color and the background with the background brush. + /// + /// New size of the GeometrySurface + /// New CanvasGeometry to be applied to the GeometrySurface + /// ICanvasStroke defining the outline for the geometry + /// Fill color for the geometry + /// Brush to fill the GeometrySurface background + public void Redraw(Size size, CanvasGeometry geometry, ICanvasStroke stroke, Color fillColor, ICanvasBrush backgroundBrush) + { + // Resize the GeometrySurface + _generator.ResizeDrawingSurface(_surfaceLock, _surface, size); + + // Set the size + Size = _surface?.Size ?? new Size(0, 0); + + // Set the new geometry + _geometry = geometry; + + // Set the new stroke + _stroke = stroke; + + // Set the fill + if (_fill is CanvasSolidColorBrush fillBrush) + { + fillBrush.Color = fillColor; + } + else + { + _fill = new CanvasSolidColorBrush(_generator.Device, fillColor); + } + + // Set the backgroundBrush + _backgroundBrush = backgroundBrush ?? new CanvasSolidColorBrush(_generator.Device, Colors.Transparent); + + // Redraw the GeometrySurface + RedrawSurface(); + } + + /// + /// Resizes the GeometrySurface to the new size. + /// + /// New size of the GeometrySurface + public void Resize(Size size) + { + // resize the GeometrySurface + _generator.ResizeDrawingSurface(_surfaceLock, _surface, size); + + // Set the size + Size = _surface?.Size ?? new Size(0, 0); + + // Redraw the GeometrySurface + RedrawSurface(); + } + + /// + /// Disposes the resources used by the GeometrySurface + /// + public void Dispose() + { + _surface?.Dispose(); + _geometry?.Dispose(); + if (_generator != null) + { + _generator.DeviceReplaced -= OnDeviceReplaced; + } + + _stroke.Brush.Dispose(); + _fill.Dispose(); + _backgroundBrush.Dispose(); + + _stroke = null; + _fill = null; + _backgroundBrush = null; + _surface = null; + _generator = null; + _geometry = null; + } + + /// + /// Handles the DeviceReplaced event + /// + /// Sender + /// object + private void OnDeviceReplaced(object sender, object e) + { + // Recreate the GeometrySurface + _surface = _generator.CreateDrawingSurface(_surfaceLock, Size); + + // Redraw the GeometrySurface + RedrawSurface(); + } + + /// + /// Helper class to redraw the surface + /// + private void RedrawSurface() + { + _generator.RedrawGeometrySurface(_surfaceLock, _surface, Size, _geometry, _stroke, _fill, _backgroundBrush); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ICompositionGenerator.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ICompositionGenerator.cs new file mode 100644 index 00000000000..411bd8c2ed6 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ICompositionGenerator.cs @@ -0,0 +1,333 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Numerics; +using System.Threading.Tasks; +using Microsoft.Graphics.Canvas; +using Microsoft.Graphics.Canvas.Brushes; +using Microsoft.Graphics.Canvas.Geometry; +using Microsoft.Toolkit.Uwp.UI.Media.Geometry; +using Windows.Foundation; +using Windows.UI; +using Windows.UI.Composition; +using Windows.UI.Xaml; + +namespace Microsoft.Toolkit.Uwp.UI.Media.Surface +{ + /// + /// Interface for the CompositionMaskGenerator + /// + public interface ICompositionGenerator : IDisposable + { + /// + /// Device Replaced Event + /// + event EventHandler DeviceReplaced; + + /// + /// Gets the Compositor + /// + Compositor Compositor { get; } + + /// + /// Gets the CanvasDevice + /// + CanvasDevice Device { get; } + + /// + /// Creates an Empty MaskSurface having the no size and geometry. + /// NOTE: Use this API if you want to create an Empty IMaskSurface first + /// and change its geometry and/or size of the MaskSurface later. + /// + /// IMaskSurface + IMaskSurface CreateMaskSurface(); + + /// + /// Creates a MaskSurface having the given size and geometry. The geometry is filled + /// with white color. The surface not covered by the geometry is transparent. + /// + /// Size of the mask + /// Geometry of the mask + /// IMaskSurface + IMaskSurface CreateMaskSurface(Size size, CanvasGeometry geometry); + + /// + /// Creates a MaskSurface having the given size and geometry. The geometry is filled + /// with white color. The surface not covered by the geometry is transparent. + /// + /// Size of the mask + /// Geometry of the mask + /// The offset from the top left corner of the ICompositionSurface where + /// the Geometry is rendered. + /// IMaskSurface + IMaskSurface CreateMaskSurface(Size size, CanvasGeometry geometry, Vector2 offset); + + /// + /// Creates an Empty IGaussianMaskSurface having the no size and geometry. + /// NOTE: Use this API if you want to create an Empty IGaussianMaskSurface first + /// and change its geometry, size and/or blurRadius of the IGaussianMaskSurface later. + /// + /// IMaskSurface + IGaussianMaskSurface CreateGaussianMaskSurface(); + + /// + /// Creates an IGaussianMaskSurface having the given size and geometry. The geometry is filled + /// with white color and a Gaussian blur is applied to it. The surface not covered by the geometry is transparent. + /// + /// Size of the mask + /// Geometry of the mask + /// The offset from the top left corner of the ICompositionSurface where + /// the Geometry is rendered. + /// Radius of Gaussian Blur to be applied on the IGaussianMaskSurface + /// IGaussianMaskSurface + IGaussianMaskSurface CreateGaussianMaskSurface(Size size, CanvasGeometry geometry, Vector2 offset, float blurRadius); + + /// + /// Creates an Empty IGeometrySurface having the no size and geometry. + /// NOTE: Use this API if you want to create an Empty IGeometrySurface + /// first and change its geometry and/or size, fillColor or stroke later. + /// + /// IGeometrySurface + IGeometrySurface CreateGeometrySurface(); + + /// + /// Creates an IGeometrySurface having the given size, geometry, stroke + /// + /// Size of the IGeometrySurface + /// Geometry to be rendered on the IGeometrySurface + /// ICanvasStroke defining the outline for the geometry + /// IGeometrySurface + IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasStroke stroke); + + /// + /// Creates an IGeometrySurface having the given size, geometry, fill color + /// + /// Size of the IGeometrySurface + /// Geometry to be rendered on the IGeometrySurface + /// Fill color of the geometry. + /// IGeometrySurface + IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, Color fillColor); + + /// + /// Creates an IGeometrySurface having the given size, geometry, stroke and fill color + /// + /// Size of the IGeometrySurface + /// Geometry to be rendered on the IGeometrySurface + /// ICanvasStroke defining the outline for the geometry + /// Fill color of the geometry. + /// IGeometrySurface + IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasStroke stroke, Color fillColor); + + /// + /// Creates an IGeometrySurface having the given size, geometry, fill color and + /// background color. + /// + /// Size of the IGeometrySurface + /// Geometry to be rendered on the IGeometrySurface + /// Fill color of the geometry + /// Fill color of the IGeometrySurface background which is + /// not covered by the geometry + /// IGeometrySurface + IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, Color fillColor, Color backgroundColor); + + /// + /// Creates an IGeometrySurface having the given size, geometry, stroke, fill color and + /// background color. + /// + /// Size of the IGeometrySurface + /// Geometry to be rendered on the IGeometrySurface + /// ICanvasStroke defining the outline for the geometry + /// Fill color of the geometry + /// Fill color of the IGeometrySurface background which is + /// not covered by the geometry + /// IGeometrySurface + IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasStroke stroke, Color fillColor, Color backgroundColor); + + /// + /// Creates an IGeometrySurface having the given size, geometry and fill brush. + /// + /// Size of the IGeometrySurface + /// Geometry to be rendered on the IGeometrySurface + /// The brush with which the geometry has to be filled + /// IGeometrySurface + IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasBrush fillBrush); + + /// + /// Creates an IGeometrySurface having the given size, geometry, stroke and fill brush. + /// + /// Size of the IGeometrySurface + /// Geometry to be rendered on the IGeometrySurface + /// ICanvasStroke defining the outline for the geometry + /// The brush with which the geometry has to be filled + /// IGeometrySurface + IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasStroke stroke, ICanvasBrush fillBrush); + + /// + /// Creates an IGeometrySurface having the given size, geometry, fill brush and + /// background brush. + /// + /// Size of the IGeometrySurface + /// Geometry to be rendered on the IGeometrySurface + /// The brush with which the geometry has to be filled + /// The brush to fill the IGeometrySurface background which is + /// not covered by the geometry + /// IGeometrySurface + IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasBrush fillBrush, ICanvasBrush backgroundBrush); + + /// + /// Creates an IGeometrySurface having the given size, geometry, stroke, fill brush and + /// background brush. + /// + /// Size of the IGeometrySurface + /// Geometry to be rendered on the IGeometrySurface + /// ICanvasStroke defining the outline for the geometry + /// The brush with which the geometry has to be filled + /// The brush to fill the IGeometrySurface background which is + /// not covered by the geometry + /// IGeometrySurface + IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasStroke stroke, ICanvasBrush fillBrush, ICanvasBrush backgroundBrush); + + /// + /// Creates an IGeometrySurface having the given size, geometry, fill brush and + /// background color. + /// + /// Size of the IGeometrySurface + /// Geometry to be rendered on the IGeometrySurface + /// The brush with which the geometry has to be filled + /// Fill color of the IGeometrySurface background which is + /// not covered by the geometry + /// IGeometrySurface + IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasBrush fillBrush, Color backgroundColor); + + /// + /// Creates an IGeometrySurface having the given size, geometry, stroke, fill brush and + /// background color. + /// + /// Size of the IGeometrySurface + /// Geometry to be rendered on the IGeometrySurface + /// ICanvasStroke defining the outline for the geometry + /// The brush with which the geometry has to be filled + /// Fill color of the IGeometrySurface background which is + /// not covered by the geometry + /// IGeometrySurface + IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasStroke stroke, ICanvasBrush fillBrush, Color backgroundColor); + + /// + /// Creates an IGeometrySurface having the given size, geometry, fill color and + /// background brush. + /// + /// Size of the IGeometrySurface + /// Geometry to be rendered on the IGeometrySurface + /// Fill color of the geometry + /// The brush to fill the IGeometrySurface background which is + /// not covered by the geometry + /// IGeometrySurface + IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, Color fillColor, ICanvasBrush backgroundBrush); + + /// + /// Creates an IGeometrySurface having the given size, geometry, stroke, fill color and + /// background brush. + /// + /// Size of the IGeometrySurface + /// Geometry to be rendered on the IGeometrySurface + /// ICanvasStroke defining the outline for the geometry + /// Fill color of the geometry + /// The brush to fill the IGeometrySurface background which is + /// not covered by the geometry + /// IGeometrySurface + IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasStroke stroke, Color fillColor, ICanvasBrush backgroundBrush); + + /// + /// Creates an IImageSurface having the given size onto which an image (based on the Uri + /// and the options) is loaded. + /// + /// Uri of the image to be loaded onto the IImageSurface. + /// New size of the IImageSurface + /// The image's resize and alignment options in the allocated space. + /// Task<IImageSurface> + Task CreateImageSurfaceAsync(Uri uri, Size size, ImageSurfaceOptions options); + + /// + /// Creates an IImageSurface having the given size onto which the given image is loaded. + /// + /// Image that will be loaded onto the IImageSurface. + /// Size of the IImageSurface + /// The image's resize and alignment options in the allocated space. + /// IImageSurface + IImageSurface CreateImageSurface(CanvasBitmap bitmap, Size size, ImageSurfaceOptions options); + + /// + /// Creates a copy of the given IImageSurface + /// + /// IImageSurface to copy + /// IImageSurface + IImageSurface CreateImageSurface(IImageSurface imageSurface); + + /// + /// Creates a copy of the given IImageMaskSurface + /// + /// IImageMaskSurface to copy + /// IImageMaskSurface + IImageMaskSurface CreateImageMaskSurface(IImageMaskSurface imageMaskSurface); + + /// + /// Creates an IImageMaskSurface having the given size onto which an image (based on the Uri + /// and the options) is loaded. + /// + /// The CanvasBitmap whose alpha values will be used to create the Mask. + /// Size of the IImageSurface + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where + /// the mask, created from the given image's alpha values, should be rendered. + /// Radius of the Gaussian blur applied to the the mask. + /// IImageMaskSurface + IImageMaskSurface CreateImageMaskSurface(CanvasBitmap surfaceBitmap, Size size, Thickness padding, float blurRadius); + + /// + /// Creates an IImageMaskSurface having the given size onto which an image (based on the Uri + /// and the options) is loaded. + /// + /// The CanvasBitmap whose alpha values will be used to create the Mask. + /// Size of the IImageSurface + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where + /// the mask, created from the given image's alpha values, should be rendered. + /// The image's resize, alignment options and blur radius in the allocated space. + /// IImageMaskSurface + IImageMaskSurface CreateImageMaskSurface(CanvasBitmap surfaceBitmap, Size size, Thickness padding, ImageSurfaceOptions options); + + /// + /// Creates an IImageMaskSurface having the given size onto which an image (based on the Uri + /// and the options) is loaded. + /// + /// The IImageSurface whose image's alpha values will be used to create the Mask. + /// Size of the IImageMaskSurface + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where + /// the mask, created from the given image's alpha values, should be rendered. + /// The image's resize, alignment options and blur radius in the allocated space. + /// IImageMaskSurface + IImageMaskSurface CreateImageMaskSurface(IImageSurface imageSurface, Size size, Thickness padding, ImageSurfaceOptions options); + + /// + /// Creates a ImageSurface having the given size onto which an image (based on the Uri + /// and the options) is loaded. + /// + /// Uri of the image whose alpha values will be used to create the Mask. + /// Size of the IImageMaskSurface + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where + /// the mask, created from the given image's alpha values, should be rendered. + /// The image's resize, alignment options and blur radius in the allocated space. + /// Task<IImageMaskSurface> + Task CreateImageMaskSurfaceAsync(Uri uri, Size size, Thickness padding, ImageSurfaceOptions options); + + /// + /// Creates a reflection of the given Visual + /// + /// Visual whose reflection has to be created + /// Distance of the reflection from the visual + /// Normalized Length of the reflected visual that will be visible. + /// - Location of the reflection with respect + /// to the Visual - Bottom, Top, Left or Right + void CreateReflection(ContainerVisual visual, float reflectionDistance = 0f, float reflectionLength = 0.7f, ReflectionLocation location = ReflectionLocation.Bottom); + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ICompositionGeneratorInternal.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ICompositionGeneratorInternal.cs new file mode 100644 index 00000000000..da681328ccb --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ICompositionGeneratorInternal.cs @@ -0,0 +1,126 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Numerics; +using System.Threading.Tasks; +using Microsoft.Graphics.Canvas; +using Microsoft.Graphics.Canvas.Brushes; +using Microsoft.Graphics.Canvas.Geometry; +using Microsoft.Toolkit.Uwp.UI.Media.Geometry; +using Windows.Foundation; +using Windows.UI.Composition; +using Windows.UI.Xaml; + +namespace Microsoft.Toolkit.Uwp.UI.Media.Surface +{ + /// + /// Internal interface for the CompositionMaskGenerator + /// + internal interface ICompositionGeneratorInternal : ICompositionGenerator + { + /// + /// Creates a CompositionDrawingSurface for the given size. + /// + /// The object to lock to prevent multiple threads + /// from accessing the surface at the same time. + /// Size of the Mask Surface + /// CompositionDrawingSurface + CompositionDrawingSurface CreateDrawingSurface(object surfaceLock, Size size); + + /// + /// Resizes the MaskSurface to the given size. + /// + /// The object to lock to prevent multiple threads + /// from accessing the surface at the same time. + /// CompositionDrawingSurface + /// New size of the Mask Surface + void ResizeDrawingSurface(object surfaceLock, CompositionDrawingSurface surface, Size size); + + /// + /// Redraws the MaskSurface with the given size and geometry. + /// + /// The object to lock to prevent multiple threads + /// from accessing the surface at the same time. + /// CompositionDrawingSurface + /// Size of the MaskSurface + /// Geometry of the MaskSurface + /// The offset from the top left corner of the ICompositionSurface where + /// the Geometry is rendered. + void RedrawMaskSurface(object surfaceLock, CompositionDrawingSurface surface, Size size, CanvasGeometry geometry, Vector2 offset); + + /// + /// Redraws the GaussianMaskSurface with the given size and geometry. + /// + /// The object to lock to prevent multiple threads + /// from accessing the surface at the same time. + /// CompositionDrawingSurface + /// Size of the MaskSurface + /// Geometry of the MaskSurface + /// The offset from the top left corner of the ICompositionSurface where the Geometry is rendered. + /// Radius of Gaussian Blur to be applied on the GaussianMaskSurface + void RedrawGaussianMaskSurface(object surfaceLock, CompositionDrawingSurface surface, Size size, CanvasGeometry geometry, Vector2 offset, float blurRadius); + + /// + /// Redraws the GeometrySurface with the given size, geometry, foreground brush and background brush. + /// + /// The object to lock to prevent multiple threads + /// from accessing the surface at the same time. + /// CompositionDrawingSurface + /// Size of the GeometrySurface + /// Geometry of the GeometrySurface + /// ICanvasStroke defining the outline for the geometry + /// The brush with which the geometry has to be filled + /// The brush with which the GeometrySurface background has to be filled + void RedrawGeometrySurface(object surfaceLock, CompositionDrawingSurface surface, Size size, CanvasGeometry geometry, ICanvasStroke stroke, ICanvasBrush fillBrush, ICanvasBrush backgroundBrush); + + /// + /// Resizes the ImageSurface to the given size and redraws the ImageSurface by rendering the canvasBitmap onto the surface. + /// + /// The object to lock to prevent multiple threads from accessing the surface at the same time. + /// CompositionDrawingSurface + /// Describes the image's resize and alignment options in the allocated space. + /// The CanvasBitmap on which the image is loaded. + void RedrawImageSurface(object surfaceLock, CompositionDrawingSurface surface, ImageSurfaceOptions options, CanvasBitmap canvasBitmap); + + /// + /// Resizes the ImageSurface with the given size and redraws the ImageSurface by loading image from the new Uri. + /// + /// The object to lock to prevent multiple threads + /// from accessing the surface at the same time. + /// CompositionDrawingSurface + /// Uri of the image to be loaded onto the IImageSurface. + /// Describes the image's resize and alignment options in the allocated space. + /// The CanvasBitmap on which the image is loaded. + /// CanvasBitmap + Task RedrawImageSurfaceAsync(object surfaceLock, CompositionDrawingSurface surface, Uri uri, ImageSurfaceOptions options, CanvasBitmap canvasBitmap); + + /// + /// Resizes the ImageMaskSurface to the given size and redraws the ImageMaskSurface by rendering the mask + /// using the image's alpha values onto the surface. + /// + /// The object to lock to prevent multiple threads from accessing the surface at the same time. + /// CompositionDrawingSurface + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where + /// the mask, created from the loaded image's alpha values, should be rendered. + /// Describes the image's resize and alignment options and blur radius in the allocated space. + /// The image whose alpha values is used to create the IImageMaskSurface. + void RedrawImageMaskSurface(object surfaceLock, CompositionDrawingSurface surface, Thickness padding, ImageSurfaceOptions options, CanvasBitmap surfaceBitmap); + + /// + /// Resizes the ImageMaskSurface to the given size and redraws the ImageMaskSurface by loading the image from the new Uri and + /// rendering the mask using the image's alpha values onto the surface. + /// + /// The object to lock to prevent multiple threads + /// from accessing the surface at the same time. + /// CompositionDrawingSurface + /// Uri of the image to be loaded onto the IImageMaskSurface. + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where + /// the mask, created from the loaded image's alpha values, should be rendered. + /// Describes the image's resize and alignment options and blur radius in the allocated space. + /// The CanvasBitmap on which the image is loaded. + /// The CanvasBitmap whose alpha values is used to create the IImageMaskSurface. + Task RedrawImageMaskSurfaceAsync(object surfaceLock, CompositionDrawingSurface surface, Uri uri, Thickness padding, ImageSurfaceOptions options, CanvasBitmap surfaceBitmap); + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/IGaussianMaskSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/IGaussianMaskSurface.cs new file mode 100644 index 00000000000..1210bf3d2e2 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/IGaussianMaskSurface.cs @@ -0,0 +1,50 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Numerics; +using Microsoft.Graphics.Canvas.Geometry; +using Windows.Foundation; + +namespace Microsoft.Toolkit.Uwp.UI.Media.Surface +{ + /// + /// Interface for rendering custom shaped geometries onto ICompositionSurface + /// so that they can be used as masks on Composition Visuals. These geometries + /// have a Gaussian Blur applied to them. + /// + public interface IGaussianMaskSurface : IMaskSurface + { + /// + /// Gets radius of Gaussian Blur to be applied on the GaussianMaskSurface + /// + float BlurRadius { get; } + + /// + /// Applies the given blur radius to the IGaussianMaskSurface. + /// + /// Radius of Gaussian Blur to be applied on the GaussianMaskSurface + void Redraw(float blurRadius); + + /// + /// Redraws the IGaussianMaskSurface with the new geometry and fills it with White color after applying + /// the Gaussian blur with given blur radius. + /// + /// New CanvasGeometry to be applied to the GaussianMaskSurface + /// The offset from the top left corner of the ICompositionSurface where + /// the Geometry is rendered. + /// Radius of Gaussian Blur to be applied on the IGaussianMaskSurface + void Redraw(CanvasGeometry geometry, Vector2 offset, float blurRadius); + + /// + /// Resizes the IGaussianMaskSurface with the given size and redraws the IGaussianMaskSurface + /// with the new geometry and fills it with White color + /// + /// New size of the mask + /// New CanvasGeometry to be applied to the IGaussianMaskSurface + /// The offset from the top left corner of the ICompositionSurface where + /// the Geometry is rendered. + /// Radius of Gaussian Blur to be applied on the IGaussianMaskSurface + void Redraw(Size size, CanvasGeometry geometry, Vector2 offset, float blurRadius); + } +} \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/IGeometrySurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/IGeometrySurface.cs new file mode 100644 index 00000000000..8989fbb13d2 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/IGeometrySurface.cs @@ -0,0 +1,287 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.Graphics.Canvas.Brushes; +using Microsoft.Graphics.Canvas.Geometry; +using Microsoft.Toolkit.Uwp.UI.Media.Geometry; +using Windows.Foundation; +using Windows.UI; + +namespace Microsoft.Toolkit.Uwp.UI.Media.Surface +{ + /// + /// Interface for rendering custom shaped geometries onto ICompositionSurface + /// + public interface IGeometrySurface : IRenderSurface + { + /// + /// Gets the Surface Geometry + /// + CanvasGeometry Geometry { get; } + + /// + /// Gets the Stroke with which the Geometry is outlined. + /// + ICanvasStroke Stroke { get; } + + /// + /// Gets the Brush with which the Geometry is filled. + /// + ICanvasBrush Fill { get; } + + /// + /// Gets the Brush with which the IGeometrySurface background is filled. + /// + ICanvasBrush BackgroundBrush { get; } + + /// + /// Redraws the IGeometrySurface with the new geometry + /// + /// New CanvasGeometry to be applied to the IGeometrySurface + void Redraw(CanvasGeometry geometry); + + /// + /// Redraws the IGeometrySurface by outlining the existing geometry with + /// the given ICanvasStroke + /// + /// ICanvasStroke defining the outline for the geometry + void Redraw(ICanvasStroke stroke); + + /// + /// Redraws the IGeometrySurface by filling the existing geometry with + /// the fill color. + /// + /// Color with which the geometry is to be filled + void Redraw(Color fillColor); + + /// + /// Redraws the IGeometrySurface by filling the existing geometry with + /// the given fill color and outlining it with the given ICanvasStroke. + /// + /// ICanvasStroke defining the outline for the geometry + /// Color with which the geometry is to be filled + void Redraw(ICanvasStroke stroke, Color fillColor); + + /// + /// Redraws the IGeometrySurface by filling the existing geometry with + /// the fill color and the background with the background color. + /// + /// Color with which the geometry is to be filled + /// Color with which the IGeometrySurface background is to be filled + void Redraw(Color fillColor, Color backgroundColor); + + /// + /// Redraws the IGeometrySurface by outlining the existing geometry with the + /// given ICanvasStroke, filling it with the fill color and the background with the background color. + /// + /// ICanvasStroke defining the outline for the geometry + /// Color with which the geometry is to be filled + /// Color with which the IGeometrySurface background is to be filled + void Redraw(ICanvasStroke stroke, Color fillColor, Color backgroundColor); + + /// + /// Redraws the IGeometrySurface by filling the existing geometry with + /// the fill brush. + /// + /// Brush with which the geometry is to be filled + void Redraw(ICanvasBrush fillBrush); + + /// + /// Redraws the IGeometrySurface by outlining the existing geometry with the + /// given ICanvasStroke, filling it with the fill brush. + /// + /// ICanvasStroke defining the outline for the geometry + /// Brush with which the geometry is to be filled + void Redraw(ICanvasStroke stroke, ICanvasBrush fillBrush); + + /// + /// Redraws the IGeometrySurface by filling the existing geometry with + /// the fill brush and the background with the background brush. + /// + /// Brush with which the geometry is to be filled + /// Brush with which the IGeometrySurface background is to be filled + void Redraw(ICanvasBrush fillBrush, ICanvasBrush backgroundBrush); + + /// + /// Redraws the IGeometrySurface by outlining the existing geometry with the + /// given ICanvasStroke, filling it with the fill brush and the background with the background brush. + /// + /// ICanvasStroke defining the outline for the geometry + /// Brush with which the geometry is to be filled + /// Brush with which the IGeometrySurface background is to be filled + void Redraw(ICanvasStroke stroke, ICanvasBrush fillBrush, ICanvasBrush backgroundBrush); + + /// + /// Redraws the IGeometrySurface by filling the existing geometry with + /// the fill color and the background with the background brush. + /// + /// Color with which the geometry is to be filled + /// Brush with which the IGeometrySurface background is to be filled + void Redraw(Color fillColor, ICanvasBrush backgroundBrush); + + /// + /// Redraws the IGeometrySurface by outlining the existing geometry with the + /// given ICanvasStroke, filling it with the fill color and the background with the background brush. + /// + /// ICanvasStroke defining the outline for the geometry + /// Color with which the geometry is to be filled + /// Brush with which the IGeometrySurface background is to be filled + void Redraw(ICanvasStroke stroke, Color fillColor, ICanvasBrush backgroundBrush); + + /// + /// Redraws the IGeometrySurface by filling the existing geometry with + /// the fill brush and the background with the background color. + /// + /// Brush with which the geometry is to be filled + /// Color with which the IGeometrySurface background is to be filled + void Redraw(ICanvasBrush fillBrush, Color backgroundColor); + + /// + /// Redraws the IGeometrySurface by outlining the existing geometry with the + /// given ICanvasStroke, filling it with the fill brush and the background with the background color. + /// + /// ICanvasStroke defining the outline for the geometry + /// Brush with which the geometry is to be filled + /// Color with which the IGeometrySurface background is to be filled + void Redraw(ICanvasStroke stroke, ICanvasBrush fillBrush, Color backgroundColor); + + /// + /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface + /// with the new geometry. + /// + /// New size of the IGeometrySurface + /// New CanvasGeometry to be applied to the IGeometrySurface + void Redraw(Size size, CanvasGeometry geometry); + + /// + /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface + /// with the new geometry and outlines it with the given ICanvasStroke. + /// + /// New size of the IGeometrySurface + /// New CanvasGeometry to be applied to the IGeometrySurface + /// ICanvasStroke defining the outline for the geometry + void Redraw(Size size, CanvasGeometry geometry, ICanvasStroke stroke); + + /// + /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface + /// with the new geometry and fills it with the fill color. + /// + /// New size of the IGeometrySurface + /// New CanvasGeometry to be applied to the IGeometrySurface + /// Fill color for the geometry + void Redraw(Size size, CanvasGeometry geometry, Color fillColor); + + /// + /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface + /// with the new geometry, outlines it with the given ICanvasStroke and fills + /// it with the fill color. + /// + /// New size of the IGeometrySurface + /// New CanvasGeometry to be applied to the IGeometrySurface + /// ICanvasStroke defining the outline for the geometry + /// Fill color for the geometry + void Redraw(Size size, CanvasGeometry geometry, ICanvasStroke stroke, Color fillColor); + + /// + /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface + /// with the new geometry and fills it with the fill color and + /// fills the background with the background color. + /// + /// New size of the IGeometrySurface + /// New CanvasGeometry to be applied to the IGeometrySurface + /// Fill color for the geometry + /// Fill color for the IGeometrySurface background + void Redraw(Size size, CanvasGeometry geometry, Color fillColor, Color backgroundColor); + + /// + /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface + /// with the new geometry, outlines it with the given ICanvasStroke and fills it with + /// the fill color and fills the background with the background color. + /// + /// New size of the IGeometrySurface + /// New CanvasGeometry to be applied to the IGeometrySurface + /// ICanvasStroke defining the outline for the geometry + /// Fill color for the geometry + /// Fill color for the IGeometrySurface background + void Redraw(Size size, CanvasGeometry geometry, ICanvasStroke stroke, Color fillColor, Color backgroundColor); + + /// + /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface + /// with the new geometry and fills it with the fill brush. + /// + /// New size of the IGeometrySurface + /// New CanvasGeometry to be applied to the IGeometrySurface + /// Brush to fill the geometry + void Redraw(Size size, CanvasGeometry geometry, ICanvasBrush fillBrush); + + /// + /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface + /// with the new geometry and fills it with the fill brush and fills + /// the background with the background brush. + /// + /// New size of the IGeometrySurface + /// New CanvasGeometry to be applied to the IGeometrySurface + /// Brush to fill the geometry + /// Brush to fill the IGeometrySurface background + void Redraw(Size size, CanvasGeometry geometry, ICanvasBrush fillBrush, ICanvasBrush backgroundBrush); + + /// + /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface + /// with the new geometry, outlines it with the given ICanvasStroke and fills it with the + /// fill brush and fills the background with the background brush. + /// + /// New size of the IGeometrySurface + /// New CanvasGeometry to be applied to the IGeometrySurface + /// ICanvasStroke defining the outline for the geometry + /// Brush to fill the geometry + /// Brush to fill the IGeometrySurface background + void Redraw(Size size, CanvasGeometry geometry, ICanvasStroke stroke, ICanvasBrush fillBrush, ICanvasBrush backgroundBrush); + + /// + /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface + /// with the new geometry and fills it with the fill brush and the background + /// with the background color. + /// + /// New size of the IGeometrySurface + /// New CanvasGeometry to be applied to the IGeometrySurface + /// Brush to fill the geometry + /// Fill color for the IGeometrySurface background + void Redraw(Size size, CanvasGeometry geometry, ICanvasBrush fillBrush, Color backgroundColor); + + /// + /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface + /// with the new geometry, outlines it with the given ICanvasStroke and fills it with + /// the fill brush and the background with the background color. + /// + /// New size of the IGeometrySurface + /// New CanvasGeometry to be applied to the IGeometrySurface + /// ICanvasStroke defining the outline for the geometry + /// Brush to fill the geometry + /// Fill color for the IGeometrySurface background + void Redraw(Size size, CanvasGeometry geometry, ICanvasStroke stroke, ICanvasBrush fillBrush, Color backgroundColor); + + /// + /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface + /// with the new geometry and fills it with the fill color and the background + /// with the background brush. + /// + /// New size of the IGeometrySurface + /// New CanvasGeometry to be applied to the IGeometrySurface + /// Fill color for the geometry + /// Brush to fill the IGeometrySurface background + void Redraw(Size size, CanvasGeometry geometry, Color fillColor, ICanvasBrush backgroundBrush); + + /// + /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface + /// with the new geometry, outlines it with the given ICanvasStroke and fills it with + /// the fill color and the background with the background brush. + /// + /// New size of the IGeometrySurface + /// New CanvasGeometry to be applied to the IGeometrySurface + /// ICanvasStroke defining the outline for the geometry + /// Fill color for the geometry + /// Brush to fill the IGeometrySurface background + void Redraw(Size size, CanvasGeometry geometry, ICanvasStroke stroke, Color fillColor, ICanvasBrush backgroundBrush); + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/IImageMaskSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/IImageMaskSurface.cs new file mode 100644 index 00000000000..c30312d24d1 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/IImageMaskSurface.cs @@ -0,0 +1,156 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Threading.Tasks; +using Microsoft.Graphics.Canvas; +using Windows.Foundation; +using Windows.UI.Xaml; + +namespace Microsoft.Toolkit.Uwp.UI.Media.Surface +{ + /// + /// Interface for rendering a mask, using an Image's alpha values, onto an ICompositionSurface + /// + public interface IImageMaskSurface : IImageSurface + { + /// + /// Gets the padding between the IImageMaskSurface outer bounds and the bounds of the area where + /// the mask, created from the loaded image's alpha values, should be rendered. + /// + Thickness MaskPadding { get; } + + /// + /// Redraws the IImageMaskSurface using the given CanvasBitmap's alpha values with the given padding. + /// + /// ImageSurface whose image's alpha values are to be used to create the mask. + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where + /// the mask, created from the loaded image's alpha values, should be rendered. + void Redraw(IImageSurface imageSurface, Thickness padding); + + /// + /// Redraws the IImageMaskSurface using the given CanvasBitmap's alpha values with the given padding + /// using the given options. + /// + /// ImageSurface whose image's alpha values are to be used to create the mask. + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where + /// the mask, created from the loaded image's alpha values, should be rendered. + /// Describes the image's resize, alignment and blur radius options in the allocated space. + void Redraw(IImageSurface imageSurface, Thickness padding, ImageSurfaceOptions options); + + /// + /// Resizes and redraws the IImageMaskSurface using the given CanvasBitmap's alpha values with the given padding + /// using the given options. + /// + /// ImageSurface whose image's alpha values are to be used to create the mask. + /// New size of the IImageMaskSurface. + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where + /// the mask, created from the loaded image's alpha values, should be rendered. + /// Describes the image's resize, alignment and blur radius options in the allocated space. + void Redraw(IImageSurface imageSurface, Size size, Thickness padding, ImageSurfaceOptions options); + + /// + /// Redraws the IImageMaskSurface using the given CanvasBitmap's alpha values with the given padding. + /// + /// Image whose alpha values are to be used to create the mask. + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where + /// the mask, created from the loaded image's alpha values, should be rendered. + void Redraw(CanvasBitmap surfaceBitmap, Thickness padding); + + /// + /// Redraws the IImageMaskSurface using the given CanvasBitmap's alpha values with the given padding + /// using the given options. + /// + /// Image whose alpha values are to be used to create the mask. + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where + /// the mask, created from the loaded image's alpha values, should be rendered. + /// Describes the image's resize, alignment and blur radius options in the allocated space. + void Redraw(CanvasBitmap surfaceBitmap, Thickness padding, ImageSurfaceOptions options); + + /// + /// Redraws the IImageMaskSurface using the alpha values of the image in the given IImageMaskSurface. + /// + /// IImageMaskSurface whose image's alpha values are to be used to create the mask. + void Redraw(IImageMaskSurface imageMaskSurface); + + /// + /// Redraws the IImageMaskSurface using the alpha values of the image in the given IImageMaskSurface with the given padding + /// and options. + /// + /// IImageMaskSurface whose image's alpha values are to be used to create the mask. + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where + /// the mask, created from the loaded image's alpha values, should be rendered. + void Redraw(IImageMaskSurface imageMaskSurface, Thickness padding); + + /// + /// Redraws the IImageMaskSurface using the alpha values of the image in the given IImageMaskSurface with the given options. + /// + /// IImageMaskSurface whose image's alpha values are to be used to create the mask. + /// Describes the image's resize, alignment and blur radius options in the allocated space. + void Redraw(IImageMaskSurface imageMaskSurface, ImageSurfaceOptions options); + + /// + /// Redraws the IImageMaskSurface using the alpha values of the image in the given IImageMaskSurface using the given padding + /// and options. + /// + /// IImageMaskSurface whose image's alpha values are to be used to create the mask. + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where + /// the mask, created from the loaded image's alpha values, should be rendered. + /// Describes the image's resize, alignment and blur radius options in the allocated space. + void Redraw(IImageMaskSurface imageMaskSurface, Thickness padding, ImageSurfaceOptions options); + + /// + /// Resizes and redraws the IImageMaskSurface using the alpha values of the image in the given IImageMaskSurface + /// with the given padding and options. + /// + /// IImageMaskSurface whose image's alpha values are to be used to create the mask. + /// New size of the IImageMaskSurface. + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where + /// the mask, created from the loaded image's alpha values, should be rendered. + /// Describes the image's resize, alignment and blur radius options in the allocated space. + void Redraw(IImageMaskSurface imageMaskSurface, Size size, Thickness padding, ImageSurfaceOptions options); + + /// + /// Resizes and redraws the IImageMaskSurface using the given CanvasBitmap's alpha values with the given padding + /// using the given options. + /// + /// Image whose alpha values are to be used to create the mask. + /// New size of the IImageMaskSurface. + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where + /// the mask, created from the loaded image's alpha values, should be rendered. + /// Describes the image's resize, alignment and blur radius options in the allocated space. + void Redraw(CanvasBitmap surfaceBitmap, Size size, Thickness padding, ImageSurfaceOptions options); + + /// + /// Redraws the IImageMaskSurface by loading image from the new Uri and image options + /// + /// Uri of the image to be loaded on to the image surface. + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where + /// the mask, created from the loaded image's alpha values, should be rendered. + /// Describes the image's resize, alignment and blur radius options in the allocated space. + /// Task + Task RedrawAsync(Uri uri, Thickness padding, ImageSurfaceOptions options); + + /// + /// Resizes the IImageMaskSurface with the given size and loads the image from the new Uri and uses its + /// alpha values to redraw the IImageMaskSurface with the given padding using the given options. + /// + /// Uri of the image to be loaded onto the IImageMaskSurface. + /// New size of the IImageMaskSurface + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where + /// the mask, created from the loaded image's alpha values, should be rendered. + /// Describes the image's resize, alignment and blur radius options in the allocated space. + /// Task + Task RedrawAsync(Uri uri, Size size, Thickness padding, ImageSurfaceOptions options); + + /// + /// Resizes the IImageMaskSurface to the new size and redraws it with the given padding using the given options. + /// + /// New size of the IImageMaskSurface + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where + /// the mask, created from the loaded image's alpha values, should be rendered. + /// The image's resize, alignment and blur radius options in the allocated space. + void Resize(Size size, Thickness padding, ImageSurfaceOptions options); + } +} \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/IImageSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/IImageSurface.cs new file mode 100644 index 00000000000..9c7513edb5b --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/IImageSurface.cs @@ -0,0 +1,154 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Threading.Tasks; +using Microsoft.Graphics.Canvas; +using Windows.Foundation; + +namespace Microsoft.Toolkit.Uwp.UI.Media.Surface +{ + /// + /// Enumeration to describe the status of the loading of an image + /// on the IImageSurface + /// + public enum ImageSurfaceLoadStatus + { + /// + /// Indicates that no image has been loaded on the IImageSurface + /// + None, + + /// + /// Indicates that the image was successfully loaded on the IImageSurface. + /// + Success, + + /// + /// Indicates that the image could not be loaded on the IImageSurface. + /// + Error + } + + /// + /// Interface for rendering an image onto an ICompositionSurface + /// + public interface IImageSurface : IRenderSurface + { + /// + /// Event that is raised when the image has been downloaded, decoded and loaded + /// to the underlying IImageSurface. This event fires regardless of success or failure. + /// + event TypedEventHandler LoadCompleted; + + /// + /// Gets the Uri of the image to be loaded onto the IImageSurface + /// + Uri Uri { get; } + + /// + /// Gets the CanvasBitmap representing the loaded image + /// + CanvasBitmap SurfaceBitmap { get; } + + /// + /// Gets the image's resize and alignment options in the allocated space. + /// + ImageSurfaceOptions Options { get; } + + /// + /// Gets the size of the decoded image in physical pixels. + /// + Size DecodedPhysicalSize { get; } + + /// + /// Gets the size of the decoded image in device independent pixels. + /// + Size DecodedSize { get; } + + /// + /// Gets the status whether the image was loaded successfully or not. + /// + ImageSurfaceLoadStatus Status { get; } + + /// + /// Redraws the IImageSurface or IImageMaskSurface with the given image options. + /// + /// The image's resize and alignment options in the allocated space. + void Redraw(ImageSurfaceOptions options); + + /// + /// Redraws the IImageSurface (using the image in the given imageSurface) or the IImageMaskSurface + /// (using the alpha values of image in the given imageSurface). + /// + /// IImageSurface whose image is to be loaded on the surface. + void Redraw(IImageSurface imageSurface); + + /// + /// Redraws the IImageSurface (using the given CanvasBitmap) or the IImageMaskSurface + /// (using the given CanvasBitmap's alpha values) using the given options. + /// + /// IImageSurface whose image is to be loaded on the surface. + /// Describes the image's resize, alignment options in the allocated space. + void Redraw(IImageSurface imageSurface, ImageSurfaceOptions options); + + /// + /// Resizes and redraws the IImageSurface (using the given CanvasBitmap) or the IImageMaskSurface + /// (using the given CanvasBitmap's alpha values) using the given options. + /// + /// IImageSurface whose image is to be loaded on the surface. + /// New size of the IImageMaskSurface. + /// Describes the image's resize, alignment options in the allocated space. + void Redraw(IImageSurface imageSurface, Size size, ImageSurfaceOptions options); + + /// + /// Redraws the IImageSurface (using the given CanvasBitmap) or the IImageMaskSurface + /// (using the given CanvasBitmap's alpha values). + /// + /// Image to be loaded on the surface. + void Redraw(CanvasBitmap surfaceBitmap); + + /// + /// Redraws the IImageSurface (using the given CanvasBitmap) or the IImageMaskSurface + /// (using the given CanvasBitmap's alpha values) using the given options. + /// + /// Image to be loaded on the surface. + /// Describes the image's resize, alignment options in the allocated space. + void Redraw(CanvasBitmap surfaceBitmap, ImageSurfaceOptions options); + + /// + /// Resizes and redraws the IImageSurface (using the given CanvasBitmap) or the IImageMaskSurface + /// (using the given CanvasBitmap's alpha values) using the given options. + /// + /// Image to be loaded on the surface.. + /// New size of the IImageMaskSurface. + /// Describes the image's resize, alignment options in the allocated space. + void Redraw(CanvasBitmap surfaceBitmap, Size size, ImageSurfaceOptions options); + + /// + /// Redraws the IImageSurface or IImageMaskSurface by loading image from the new Uri and applying the image options. + /// + /// Uri of the image to be loaded on to the surface. + /// The image's resize and alignment options in the allocated space. + /// Task + Task RedrawAsync(Uri uri, ImageSurfaceOptions options); + + /// + /// Resizes the IImageSurface or IImageMaskSurface with the given size and redraws it by loading + /// image from the new Uri. + /// + /// Uri of the image to be loaded onto the IImageSurface. + /// New size of the IImageSurface + /// The image's resize and alignment options in the allocated space. + /// Task + Task RedrawAsync(Uri uri, Size size, ImageSurfaceOptions options); + + /// + /// Resizes the IImageSurface or IImageMaskSurface to the new size with the given image options. + /// + /// New size of the IImageSurface + /// The image's resize and alignment options in the allocated space. + void Resize(Size size, ImageSurfaceOptions options); + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/IMaskSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/IMaskSurface.cs new file mode 100644 index 00000000000..f00e96e87a4 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/IMaskSurface.cs @@ -0,0 +1,60 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Numerics; +using Microsoft.Graphics.Canvas.Geometry; +using Windows.Foundation; + +namespace Microsoft.Toolkit.Uwp.UI.Media.Surface +{ + /// + /// Interface for rendering custom shaped geometries onto ICompositionSurface + /// so that they can be used as masks on Composition Visuals. + /// + public interface IMaskSurface : IRenderSurface + { + /// + /// Gets the Geometry of the MaskSurface + /// + CanvasGeometry Geometry { get; } + + /// + /// Gets the offset from the top left corner of the ICompositionSurface where + /// the Geometry is rendered. + /// + Vector2 Offset { get; } + + /// + /// Redraws the MaskSurface with the new geometry + /// + /// New CanvasGeometry to be applied to the IMaskSurface + void Redraw(CanvasGeometry geometry); + + /// + /// Resizes the MaskSurface with the given size and redraws the IMaskSurface + /// with the new geometry and fills it with White color + /// + /// New size of the mask + /// New CanvasGeometry to be applied to the IMaskSurface + void Redraw(Size size, CanvasGeometry geometry); + + /// + /// Redraws the IMaskSurface with the new geometry + /// + /// New CanvasGeometry to be applied to the IMaskSurface + /// The offset from the top left corner of the ICompositionSurface where + /// the Geometry is rendered. + void Redraw(CanvasGeometry geometry, Vector2 offset); + + /// + /// Resizes the IMaskSurface with the given size and redraws the IMaskSurface + /// with the new geometry and fills it with White color + /// + /// New size of the mask + /// New CanvasGeometry to be applied to the IMaskSurface + /// The offset from the top left corner of the ICompositionSurface where + /// the Geometry is rendered. + void Redraw(Size size, CanvasGeometry geometry, Vector2 offset); + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/IRenderSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/IRenderSurface.cs new file mode 100644 index 00000000000..6afd9f4ad17 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/IRenderSurface.cs @@ -0,0 +1,43 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Windows.Foundation; +using Windows.UI.Composition; + +namespace Microsoft.Toolkit.Uwp.UI.Media.Surface +{ + /// + /// Represents the core interface for interfaces + /// which render onto ICompositionSurface. + /// + public interface IRenderSurface : IDisposable + { + /// + /// Gets the Generator + /// + ICompositionGenerator Generator { get; } + + /// + /// Gets the Surface + /// + ICompositionSurface Surface { get; } + + /// + /// Gets the Surface Size + /// + Size Size { get; } + + /// + /// Redraws the surface + /// + void Redraw(); + + /// + /// Resizes the surface to the specified size. + /// + /// New size of the surface + void Resize(Size size); + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageMaskSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageMaskSurface.cs new file mode 100644 index 00000000000..991301a5c7f --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageMaskSurface.cs @@ -0,0 +1,708 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Threading.Tasks; +using Microsoft.Graphics.Canvas; +using Microsoft.Toolkit.Uwp.UI.Media.Geometry; +using Windows.Foundation; +using Windows.UI.Composition; +using Windows.UI.Xaml; + +namespace Microsoft.Toolkit.Uwp.UI.Media.Surface +{ + internal sealed class ImageMaskSurface : IImageMaskSurface + { + private readonly object _surfaceLock; + private ICompositionGeneratorInternal _generator; + private CompositionDrawingSurface _surface; + private Uri _uri; + private CanvasBitmap _canvasBitmap; + private bool _raiseLoadCompletedEvent; + + /// + /// Event that is raised when the image has been downloaded, + /// decoded and loaded to the underlying IImageSurface. This + /// event fires regardless of success or failure. + /// + public event TypedEventHandler LoadCompleted; + + /// + /// Gets the CompositionGenerator + /// + public ICompositionGenerator Generator => _generator; + + /// + /// Gets the Surface of the IImageMaskSurface + /// + public ICompositionSurface Surface => _surface; + + /// + /// Gets the Uri of the image to be loaded onto the IImageSurface + /// + public Uri Uri => _uri; + + /// + /// Gets the CanvasBitmap representing the loaded image + /// + public CanvasBitmap SurfaceBitmap => _canvasBitmap; + + /// + /// Gets the IImageMaskSurface Size + /// + public Size Size { get; private set; } + + /// + /// Gets the image's resize and alignment options in the allocated space. + /// + public ImageSurfaceOptions Options { get; private set; } + + /// + /// Gets the size of the decoded image in physical pixels. + /// + public Size DecodedPhysicalSize { get; private set; } + + /// + /// Gets the size of the decoded image in device independent pixels. + /// + public Size DecodedSize { get; private set; } + + /// + /// Gets the status whether the image was loaded successfully or not. + /// + public ImageSurfaceLoadStatus Status { get; private set; } + + /// + /// Gets the padding between the IImageMaskSurface outer bounds and the bounds of the area where + /// the mask, created from the loaded image's alpha values, should be rendered. + /// + public Thickness MaskPadding { get; private set; } + + /// + /// Initializes a new instance of the class. + /// Constructor + /// + /// ICompositionMaskGeneratorInternal object + /// Uri of the image to be loaded onto the IImageMaskSurface. + /// Size of the IImageMaskSurface + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where + /// the mask, created from the loaded image's alpha values, should be rendered. + /// The image's resize, alignment options and blur radius in the allocated space. + public ImageMaskSurface(ICompositionGeneratorInternal generator, Uri uri, Size size, Thickness padding, ImageSurfaceOptions options) + { + _generator = generator ?? + throw new ArgumentNullException(nameof(generator), "CompositionGenerator cannot be null!"); + _surfaceLock = new object(); + + // Create the Surface of the IImageMaskSurface + _surface = _generator.CreateDrawingSurface(_surfaceLock, size); + Size = _surface?.Size ?? new Size(0, 0); + _uri = uri; + _raiseLoadCompletedEvent = _uri != null; + _canvasBitmap = null; + MaskPadding = padding; + + // Set the image options + Options = options; + + // Subscribe to DeviceReplaced event + _generator.DeviceReplaced += OnDeviceReplaced; + Status = ImageSurfaceLoadStatus.None; + } + + /// + /// Initializes a new instance of the class. + /// Constructor + /// + /// ICompositionMaskGeneratorInternal object + /// The CanvasBitmap whose alpha values will be used to create the Mask. + /// Size of the IImageMaskSurface + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where + /// the mask, created from the loaded image's alpha values, should be rendered. + /// The image's resize, alignment options and blur radius in the allocated space. + public ImageMaskSurface(ICompositionGeneratorInternal generator, CanvasBitmap surfaceBitmap, Size size, Thickness padding, ImageSurfaceOptions options) + { + _generator = generator ?? + throw new ArgumentNullException(nameof(generator), "CompositionGenerator cannot be null!"); + _surfaceLock = new object(); + + // Create the Surface of the IImageMaskSurface + _surface = _generator.CreateDrawingSurface(_surfaceLock, size); + Size = _surface?.Size ?? new Size(0, 0); + _uri = null; + _raiseLoadCompletedEvent = false; + if (surfaceBitmap != null) + { + _canvasBitmap = CanvasBitmap.CreateFromBytes( + _generator.Device, + surfaceBitmap.GetPixelBytes(), + (int)surfaceBitmap.Bounds.Width, + (int)surfaceBitmap.Bounds.Height, + surfaceBitmap.Format); + } + + // Set the mask padding + MaskPadding = padding; + + // Set the image options + Options = options; + + // Subscribe to DeviceReplaced event + _generator.DeviceReplaced += OnDeviceReplaced; + } + + /// + /// Redraws the IImageMaskSurface + /// + public void Redraw() + { + // Reload the IImageMaskSurface + RedrawSurface(); + } + + /// + /// Redraws the IImageMaskSurface with the given image options + /// + /// The image's resize, alignment options and blur radius in the allocated space. + public void Redraw(ImageSurfaceOptions options) + { + // Set the image options + Options = options; + + // Redraw the IImageMaskSurface + RedrawSurface(); + } + + /// + /// Redraws the IImageMaskSurface using the alpha values of image in the given imageSurface. + /// + /// IImageSurface whose image is to be loaded on the surface. + public void Redraw(IImageSurface imageSurface) + { + if (imageSurface != null) + { + Redraw(imageSurface.SurfaceBitmap, imageSurface.Size, MaskPadding, imageSurface.Options); + } + else + { + // Draw an empty surface + Redraw(surfaceBitmap: null, Size, MaskPadding, Options); + } + } + + /// + /// Redraws the IImageMaskSurface (using the alpha values of image in the given imageSurface). + /// + /// IImageSurface whose image is to be loaded on the surface. + /// Describes the image's resize, alignment and blur radius options in the allocated space. + public void Redraw(IImageSurface imageSurface, ImageSurfaceOptions options) + { + if (imageSurface != null) + { + Redraw(imageSurface.SurfaceBitmap, imageSurface.Size, MaskPadding, options); + } + else + { + // Draw an empty surface + Redraw(surfaceBitmap: null, Size, MaskPadding, options); + } + } + + /// + /// Resizes and redraws the IImageMaskSurface (using the alpha values of image in the given imageSurface). + /// + /// IImageSurface whose image is to be loaded on the surface. + /// New size of the IImageMaskSurface. + /// Describes the image's resize, alignment and blur radius options in the allocated space. + public void Redraw(IImageSurface imageSurface, Size size, ImageSurfaceOptions options) + { + Redraw(imageSurface?.SurfaceBitmap, size, MaskPadding, options); + } + + /// + /// Redraws the IImageMaskSurface using the alpha values of the image in the given IImageSurface with the given padding. + /// + /// ImageSurface whose image's alpha values are to be used to create the mask. + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where + /// the mask, created from the loaded image's alpha values, should be rendered. + public void Redraw(IImageSurface imageSurface, Thickness padding) + { + if (imageSurface != null) + { + Redraw(imageSurface.SurfaceBitmap, imageSurface.Size, padding, Options); + } + else + { + // Draw an empty surface + Redraw(surfaceBitmap: null, Size, padding, Options); + } + } + + /// + /// Redraws the IImageMaskSurface using the alpha values of the image in the given IImageSurface with the given padding + /// using the given options. + /// + /// ImageSurface whose image's alpha values are to be used to create the mask. + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where + /// the mask, created from the loaded image's alpha values, should be rendered. + /// Describes the image's resize, alignment and blur radius options in the allocated space. + public void Redraw(IImageSurface imageSurface, Thickness padding, ImageSurfaceOptions options) + { + if (imageSurface != null) + { + Redraw(imageSurface.SurfaceBitmap, imageSurface.Size, padding, options); + } + else + { + // Draw an empty surface + Redraw(surfaceBitmap: null, Size, padding, options); + } + } + + /// + /// Resizes and redraws the IImageMaskSurface using the alpha values of the image in the given IImageSurface + /// with the given padding and options. + /// + /// ImageSurface whose image's alpha values are to be used to create the mask. + /// New size of the IImageMaskSurface. + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where + /// the mask, created from the loaded image's alpha values, should be rendered. + /// Describes the image's resize, alignment and blur radius options in the allocated space. + public void Redraw(IImageSurface imageSurface, Size size, Thickness padding, ImageSurfaceOptions options) + { + Redraw(imageSurface?.SurfaceBitmap, size, padding, options); + } + + /// + /// Redraws the IImageMaskSurface using the alpha values of the image in the given IImageMaskSurface. + /// + /// IImageMaskSurface whose image's alpha values are to be used to create the mask. + public void Redraw(IImageMaskSurface imageMaskSurface) + { + if (imageMaskSurface != null) + { + Redraw(imageMaskSurface.SurfaceBitmap, imageMaskSurface.Size, imageMaskSurface.MaskPadding, imageMaskSurface.Options); + } + else + { + // Draw an empty surface + Redraw(surfaceBitmap: null, Size, MaskPadding, Options); + } + } + + /// + /// Redraws the IImageMaskSurface using the alpha values of the image in the given IImageMaskSurface with the given padding + /// and options. + /// + /// IImageMaskSurface whose image's alpha values are to be used to create the mask. + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where + /// the mask, created from the loaded image's alpha values, should be rendered. + public void Redraw(IImageMaskSurface imageMaskSurface, Thickness padding) + { + if (imageMaskSurface != null) + { + Redraw(imageMaskSurface.SurfaceBitmap, imageMaskSurface.Size, padding, imageMaskSurface.Options); + } + else + { + // Draw an empty surface + Redraw(surfaceBitmap: null, Size, padding, Options); + } + } + + /// + /// Redraws the IImageMaskSurface using the alpha values of the image in the given IImageMaskSurface with the given options. + /// + /// IImageMaskSurface whose image's alpha values are to be used to create the mask. + /// Describes the image's resize, alignment and blur radius options in the allocated space. + public void Redraw(IImageMaskSurface imageMaskSurface, ImageSurfaceOptions options) + { + if (imageMaskSurface != null) + { + Redraw(imageMaskSurface.SurfaceBitmap, imageMaskSurface.Size, imageMaskSurface.MaskPadding, options); + } + else + { + // Draw an empty surface + Redraw(surfaceBitmap: null, Size, MaskPadding, options); + } + } + + /// + /// Redraws the IImageMaskSurface using the alpha values of the image in the given IImageMaskSurface using the given padding + /// and options. + /// + /// IImageMaskSurface whose image's alpha values are to be used to create the mask. + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where + /// the mask, created from the loaded image's alpha values, should be rendered. + /// Describes the image's resize, alignment and blur radius options in the allocated space. + public void Redraw(IImageMaskSurface imageMaskSurface, Thickness padding, ImageSurfaceOptions options) + { + if (imageMaskSurface != null) + { + Redraw(imageMaskSurface.SurfaceBitmap, imageMaskSurface.Size, padding, options); + } + else + { + // Draw an empty surface + Redraw(surfaceBitmap: null, Size, padding, options); + } + } + + /// + /// Resizes and redraws the IImageMaskSurface using the alpha values of the image in the given IImageMaskSurface + /// with the given padding and options. + /// + /// IImageMaskSurface whose image's alpha values are to be used to create the mask. + /// New size of the IImageMaskSurface. + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where + /// the mask, created from the loaded image's alpha values, should be rendered. + /// Describes the image's resize, alignment and blur radius options in the allocated space. + public void Redraw(IImageMaskSurface imageMaskSurface, Size size, Thickness padding, ImageSurfaceOptions options) + { + Redraw(imageMaskSurface?.SurfaceBitmap, size, padding, options); + } + + /// + /// Redraws the IImageMaskSurface using the given CanvasBitmap's alpha values. + /// + /// Image whose alpha values are to be used to create the mask. + public void Redraw(CanvasBitmap surfaceBitmap) + { + Redraw(surfaceBitmap, Size, MaskPadding, Options); + } + + /// + /// Redraws the IImageMaskSurface using the given CanvasBitmap's alpha values with the given padding. + /// + /// Image whose alpha values are to be used to create the mask. + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where + /// the mask, created from the loaded image's alpha values, should be rendered. + public void Redraw(CanvasBitmap surfaceBitmap, Thickness padding) + { + Redraw(surfaceBitmap, Size, padding, Options); + } + + /// + /// Redraws the IImageMaskSurface using the given CanvasBitmap's alpha values and the given options. + /// + /// Image whose alpha values are to be used to create the mask. + /// The image's resize, alignment options and blur radius in the allocated space. + public void Redraw(CanvasBitmap surfaceBitmap, ImageSurfaceOptions options) + { + Redraw(surfaceBitmap, Size, MaskPadding, options); + } + + /// + /// Resizes and redraws the IImageMaskSurface using the given CanvasBitmap's alpha values and the given options. + /// + /// Image whose alpha values are to be used to create the mask. + /// New size of the IImageMaskSurface. + /// The image's resize, alignment options and blur radius in the allocated space. + public void Redraw(CanvasBitmap surfaceBitmap, Size size, ImageSurfaceOptions options) + { + Redraw(surfaceBitmap, size, MaskPadding, options); + } + + /// + /// Redraws the IImageMaskSurface using the given CanvasBitmap's alpha values with the given padding + /// using the given options. + /// + /// Image whose alpha values are to be used to create the mask. + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where + /// the mask, created from the loaded image's alpha values, should be rendered. + /// The image's resize, alignment options and blur radius in the allocated space. + public void Redraw(CanvasBitmap surfaceBitmap, Thickness padding, ImageSurfaceOptions options) + { + Redraw(surfaceBitmap, Size, padding, options); + } + + /// + /// Resizes and redraws the IImageMaskSurface using the given CanvasBitmap's alpha values with the given padding + /// using the given options. + /// + /// Image whose alpha values are to be used to create the mask. + /// New size of the IImageMaskSurface. + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where + /// the mask, created from the loaded image's alpha values, should be rendered. + /// The image's resize, alignment and blur radius options in the allocated space. + public void Redraw(CanvasBitmap surfaceBitmap, Size size, Thickness padding, ImageSurfaceOptions options) + { + if (_canvasBitmap != surfaceBitmap) + { + // Dispose the previous canvas bitmap resource (if any) + if (_canvasBitmap != null) + { + _canvasBitmap.Dispose(); + _canvasBitmap = null; + } + + if (surfaceBitmap != null) + { + // No need to copy again if _canvasBitmap and surfaceBitmap are same + if (_canvasBitmap != surfaceBitmap) + { + // Copy the surface bitmap onto _canvasBitmap + _canvasBitmap = CanvasBitmap.CreateFromBytes( + _generator.Device, + surfaceBitmap.GetPixelBytes(), + (int)surfaceBitmap.Bounds.Width, + (int)surfaceBitmap.Bounds.Height, + surfaceBitmap.Format); + } + } + else + { + _canvasBitmap = null; + } + } + + _uri = null; + _raiseLoadCompletedEvent = false; + + // Set the options + Options = options; + + // Resize if required + if (Size != size) + { + // resize the IImageMaskSurface + _generator.ResizeDrawingSurface(_surfaceLock, _surface, size); + + // Set the size + Size = _surface?.Size ?? new Size(0, 0); + } + + // Set the mask padding + MaskPadding = padding; + + // Redraw the IImageMaskSurface + RedrawSurface(); + } + + /// + /// Redraws the IImageMaskSurface by loading image from the new Uri + /// + /// Uri of the image to be loaded on to the image surface. + /// Task + public Task RedrawAsync(Uri uri) + { + return RedrawAsync(uri, Size, MaskPadding, Options); + } + + /// + /// Redraws the IImageMaskSurface by loading image from the new Uri and image options + /// + /// Uri of the image to be loaded on to the image surface. + /// The image's resize, alignment and blur radius options in the allocated space. + /// Task + public Task RedrawAsync(Uri uri, ImageSurfaceOptions options) + { + return RedrawAsync(uri, Size, MaskPadding, options); + } + + /// + /// Redraws the IImageMaskSurface by loading image from the new Uri and image options + /// + /// Uri of the image to be loaded on to the image surface. + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where + /// the mask, created from the loaded image's alpha values, should be rendered. + /// The image's resize, alignment and blur radius options in the allocated space. + /// Task + public Task RedrawAsync(Uri uri, Thickness padding, ImageSurfaceOptions options) + { + return RedrawAsync(uri, Size, padding, options); + } + + /// + /// Resizes the IImageMaskSurface with the given size and redraws the IImageMaskSurface by loading + /// image from the new Uri. + /// + /// Uri of the image to be loaded onto the IImageMaskSurface. + /// New size of the IImageMaskSurface + /// The image's resize and alignment options in the allocated space. + /// Task + public Task RedrawAsync(Uri uri, Size size, ImageSurfaceOptions options) + { + return RedrawAsync(uri, size, MaskPadding, options); + } + + /// + /// Resizes the IImageMaskSurface with the given size and loads the image from the new Uri and uses its + /// alpha values to redraw the IImageMaskSurface with the given padding using the given options. + /// + /// Uri of the image to be loaded onto the IImageMaskSurface. + /// New size of the IImageMaskSurface + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where + /// the mask, created from the loaded image's alpha values, should be rendered. + /// The image's resize, alignment and blur radius options in the allocated space. + /// Task + public async Task RedrawAsync(Uri uri, Size size, Thickness padding, ImageSurfaceOptions options) + { + // If the given Uri differs from the previously stored Uri or if the ImageSurface was + // directly created from a CanvasBitmap, dispose the existing canvasBitmap + if ((_uri != null && !_uri.IsEqualTo(uri)) + || (_uri == null && _canvasBitmap != null)) + { + _canvasBitmap?.Dispose(); + _canvasBitmap = null; + _raiseLoadCompletedEvent = uri != null; + } + + // Set the mask padding + MaskPadding = padding; + + // Set the image options + Options = options; + + // Resize the surface only if AutoResize option is disabled + if (Size != size) + { + // resize the IImageMaskSurface + _generator.ResizeDrawingSurface(_surfaceLock, _surface, size); + + // Set the size + Size = _surface?.Size ?? new Size(0, 0); + } + + // Set the new Uri of the image to be loaded + _uri = uri; + + // Reload the IImageMaskSurface + await RedrawSurfaceAsync(); + } + + /// + /// Resizes the IImageMaskSurface to the new size. + /// + /// New size of the IImageMaskSurface + public void Resize(Size size) + { + Resize(size, MaskPadding, Options); + } + + /// + /// Resizes the IImageMaskSurface to the new size using the given options. + /// + /// New size of the IImageMaskSurface + /// The image's resize, alignment and blur radius options in the allocated space. + public void Resize(Size size, ImageSurfaceOptions options) + { + Resize(size, MaskPadding, options); + } + + /// + /// Resizes the IImageMaskSurface to the new size and redraws it with the given padding using the given options. + /// + /// New size of the IImageMaskSurface + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where + /// the mask, created from the loaded image's alpha values, should be rendered. + /// The image's resize, alignment and blur radius options in the allocated space. + public void Resize(Size size, Thickness padding, ImageSurfaceOptions options) + { + // Set the mask padding + MaskPadding = padding; + + // Set the image options + Options = options; + + // Resize the surface only if AutoResize option is disabled + if (Size != size) + { + // resize the IImageMaskSurface + _generator.ResizeDrawingSurface(_surfaceLock, _surface, size); + + // Set the size + Size = _surface?.Size ?? new Size(0, 0); + } + + // Redraw the IImageMaskSurface + RedrawSurface(); + } + + /// + /// Disposes the resources used by the IImageMaskSurface + /// + public void Dispose() + { + _surface?.Dispose(); + if (_generator != null) + { + _generator.DeviceReplaced -= OnDeviceReplaced; + } + + _canvasBitmap?.Dispose(); + _canvasBitmap = null; + _surface = null; + _generator = null; + _uri = null; + Options = null; + } + + /// + /// Redraws the IImageMaskSurface asynchronously by loading the image from the Uri. + /// + /// Task + internal Task RedrawAsync() + { + // Reload the IImageMaskSurface + return RedrawSurfaceAsync(); + } + + /// + /// Handles the DeviceReplaced event + /// + /// Sender + /// object + private async void OnDeviceReplaced(object sender, object e) + { + // Recreate the ImageSurface + _surface = _generator.CreateDrawingSurface(_surfaceLock, Size); + + // Reload the IImageMaskSurface + await RedrawSurfaceAsync(); + } + + /// + /// Helper class to redraw the IImageMaskSurface synchronously + /// + private void RedrawSurface() + { + // Resize the surface image + _generator.RedrawImageMaskSurface(_surfaceLock, _surface, MaskPadding, Options, _canvasBitmap); + + Status = _canvasBitmap != null ? ImageSurfaceLoadStatus.Success : ImageSurfaceLoadStatus.Error; + + if (_canvasBitmap != null) + { + DecodedPhysicalSize = new Size(_canvasBitmap.SizeInPixels.Width, _canvasBitmap.SizeInPixels.Height); + DecodedSize = _canvasBitmap.Size; + } + } + + /// + /// Helper class to redraw the IImageMaskSurface asynchronously + /// + /// Task + private async Task RedrawSurfaceAsync() + { + // Cache the canvasBitmap to avoid reloading of the same image during Resize/Redraw operations + _canvasBitmap = await _generator.RedrawImageMaskSurfaceAsync(_surfaceLock, _surface, _uri, MaskPadding, Options, _canvasBitmap); + + Status = _canvasBitmap != null ? ImageSurfaceLoadStatus.Success : ImageSurfaceLoadStatus.Error; + + if (_canvasBitmap != null) + { + DecodedPhysicalSize = new Size(_canvasBitmap.SizeInPixels.Width, _canvasBitmap.SizeInPixels.Height); + DecodedSize = _canvasBitmap.Size; + } + + if (_raiseLoadCompletedEvent) + { + LoadCompleted?.Invoke(this, Status); + _raiseLoadCompletedEvent = false; + } + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurface.cs new file mode 100644 index 00000000000..f895bb7fb08 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurface.cs @@ -0,0 +1,489 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Threading.Tasks; +using Microsoft.Graphics.Canvas; +using Microsoft.Toolkit.Uwp.UI.Media.Geometry; +using Windows.Foundation; +using Windows.UI.Composition; + +namespace Microsoft.Toolkit.Uwp.UI.Media.Surface +{ + /// + /// Class for rendering an image onto a ICompositionSurface + /// + internal sealed class ImageSurface : IImageSurface + { + private readonly object _surfaceLock; + private ICompositionGeneratorInternal _generator; + private CompositionDrawingSurface _surface; + private Uri _uri; + private CanvasBitmap _canvasBitmap; + private bool _raiseLoadCompletedEvent; + + /// + /// Event that is raised when the image has been downloaded, decoded and loaded + /// to the underlying IImageSurface. This event fires regardless of success or failure. + /// + public event TypedEventHandler LoadCompleted; + + /// + /// Gets the CompositionGenerator + /// + public ICompositionGenerator Generator => _generator; + + /// + /// Gets the Surface of the IImageSurface + /// + public ICompositionSurface Surface => _surface; + + /// + /// Gets the Uri of the image to be loaded onto the IImageSurface + /// + public Uri Uri => _uri; + + /// + /// Gets the IImageSurface Size + /// + public Size Size { get; private set; } + + /// + /// Gets the image's resize and alignment options in the allocated space. + /// + public ImageSurfaceOptions Options { get; private set; } + + /// + /// Gets the size of the decoded image in physical pixels. + /// + public Size DecodedPhysicalSize { get; private set; } + + /// + /// Gets the size of the decoded image in device independent pixels. + /// + public Size DecodedSize { get; private set; } + + /// + /// Gets the status whether the image was loaded successfully or not. + /// + public ImageSurfaceLoadStatus Status { get; private set; } + + /// + /// Gets the CanvasBitmap representing the loaded image + /// + public CanvasBitmap SurfaceBitmap => _canvasBitmap; + + /// + /// Initializes a new instance of the class. + /// Constructor + /// + /// ICompositionMaskGeneratorInternal object + /// Uri of the image to be loaded onto the IImageSurface. + /// Size of the IImageSurface + /// The image's resize and alignment options in the allocated space. + public ImageSurface(ICompositionGeneratorInternal generator, Uri uri, Size size, ImageSurfaceOptions options) + { + _generator = generator ?? throw new ArgumentNullException(nameof(generator), "CompositionGenerator cannot be null!"); + _surfaceLock = new object(); + + // Create the Surface of the IImageSurface + _surface = _generator.CreateDrawingSurface(_surfaceLock, size); + Size = _surface?.Size ?? new Size(0, 0); + _uri = uri; + _raiseLoadCompletedEvent = _uri != null; + _canvasBitmap = null; + + // Set the image options + Options = options; + + // Subscribe to DeviceReplaced event + _generator.DeviceReplaced += OnDeviceReplaced; + Status = ImageSurfaceLoadStatus.None; + } + + /// + /// Initializes a new instance of the class. + /// Constructor + /// + /// ICompositionMaskGeneratorInternal object + /// CanvasBitmap which will be rendered on the IImageSurface. + /// Size of the IImageSurface + /// The image's resize and alignment options in the allocated space. + internal ImageSurface(ICompositionGeneratorInternal generator, CanvasBitmap surfaceBitmap, Size size, ImageSurfaceOptions options) + { + _generator = generator ?? throw new ArgumentNullException(nameof(generator), "CompositionGenerator cannot be null!"); + _surfaceLock = new object(); + + // Create the Surface of the IImageSurface + _surface = _generator.CreateDrawingSurface(_surfaceLock, size); + Size = _surface?.Size ?? new Size(0, 0); + _uri = null; + _raiseLoadCompletedEvent = false; + if (surfaceBitmap != null) + { + _canvasBitmap = CanvasBitmap.CreateFromBytes( + _generator.Device, + surfaceBitmap.GetPixelBytes(), + (int)surfaceBitmap.Bounds.Width, + (int)surfaceBitmap.Bounds.Height, + surfaceBitmap.Format); + } + + // Set the image options + Options = options; + + // Subscribe to DeviceReplaced event + _generator.DeviceReplaced += OnDeviceReplaced; + } + + /// + /// Redraws the IImageSurface + /// + public void Redraw() + { + // Reload the IImageSurface + RedrawSurface(); + } + + /// + /// Redraws the IImageSurface with the given image options + /// + /// The image's resize and alignment options in the allocated space. + public void Redraw(ImageSurfaceOptions options) + { + // Set the image options + Options = options; + + // Redraw the IImageSurface + RedrawSurface(); + } + + /// + /// Redraws the IImageSurface (using the image in the given imageSurface) or the IImageMaskSurface + /// (using the alpha values of image in the given imageSurface). + /// + /// IImageSurface whose image is to be loaded on the surface. + public void Redraw(IImageSurface imageSurface) + { + if (imageSurface != null) + { + Redraw(imageSurface.SurfaceBitmap, imageSurface.Size, imageSurface.Options); + } + else + { + // Draw an empty surface + Redraw(surfaceBitmap: null); + } + } + + /// + /// Redraws the IImageSurface (using the image in the given imageSurface) or the IImageMaskSurface + /// (using the alpha values of image in the given imageSurface). + /// + /// IImageSurface whose image is to be loaded on the surface. + /// Describes the image's resize, alignment options in the allocated space. + public void Redraw(IImageSurface imageSurface, ImageSurfaceOptions options) + { + if (imageSurface != null) + { + Redraw(imageSurface.SurfaceBitmap, imageSurface.Size, options); + } + else + { + // Draw an empty surface + Redraw(surfaceBitmap: null, options); + } + } + + /// + /// Resizes and redraws the IImageSurface (using the image in the given imageSurface) or the IImageMaskSurface + /// (using the alpha values of image in the given imageSurface). + /// + /// IImageSurface whose image is to be loaded on the surface. + /// New size of the IImageMaskSurface. + /// Describes the image's resize, alignment options in the allocated space. + public void Redraw(IImageSurface imageSurface, Size size, ImageSurfaceOptions options) + { + Redraw(imageSurface?.SurfaceBitmap, size, options); + } + + /// + /// Redraws the IImageSurface using the given CanvasBitmap. + /// + /// Image to be loaded on the surface. + public void Redraw(CanvasBitmap surfaceBitmap) + { + Redraw(surfaceBitmap, Size, Options); + } + + /// + /// Redraws the IImageSurface using the given CanvasBitmap using the given options. + /// + /// Image whose alpha values are to be used to create the mask. + /// The image's resize, alignment options in the allocated space. + public void Redraw(CanvasBitmap surfaceBitmap, ImageSurfaceOptions options) + { + // Set the image options + Options = options; + + // Redraw the IImageSurface + Redraw(surfaceBitmap, Size, Options); + } + + /// + /// Resizes and redraws the IImageSurface using the given CanvasBitmap using the given options. + /// + /// Image whose alpha values are to be used to create the mask. + /// New size of the IImageSurface. + /// The image's resize, alignment options in the allocated space. + public void Redraw(CanvasBitmap surfaceBitmap, Size size, ImageSurfaceOptions options) + { + if (_canvasBitmap != surfaceBitmap) + { + // Dispose the previous canvas bitmap resource (if any) + if (_canvasBitmap != null) + { + _canvasBitmap.Dispose(); + _canvasBitmap = null; + } + + if (surfaceBitmap != null) + { + if (_canvasBitmap != surfaceBitmap) + { + // Copy the surface bitmap onto _canvasBitmap + _canvasBitmap = CanvasBitmap.CreateFromBytes( + _generator.Device, + surfaceBitmap.GetPixelBytes(), + (int)surfaceBitmap.Bounds.Width, + (int)surfaceBitmap.Bounds.Height, + surfaceBitmap.Format); + } + } + else + { + _canvasBitmap = null; + } + } + + _uri = null; + _raiseLoadCompletedEvent = false; + + // Set the options + Options = options; + + // Resize the surface only if AutoResize option is disabled + if (!Options.AutoResize && Size != size) + { + // resize the IImageMaskSurface + _generator.ResizeDrawingSurface(_surfaceLock, _surface, size); + + // Set the size + Size = _surface?.Size ?? new Size(0, 0); + } + + // Redraw the IImageMaskSurface + RedrawSurface(); + } + + /// + /// Redraws the IImageSurface by loading image from the new Uri + /// + /// Uri of the image to be loaded on the surface. + /// Task + public Task RedrawAsync(Uri uri) + { + return RedrawAsync(uri, Size, Options); + } + + /// + /// Redraws the IImageSurface by loading image from the new Uri and image options + /// + /// Uri of the image to be loaded on to the image surface. + /// The image's resize and alignment options in the allocated space. + /// Task + public Task RedrawAsync(Uri uri, ImageSurfaceOptions options) + { + return RedrawAsync(uri, Size, options); + } + + /// + /// Resizes the IImageSurface with the given size and redraws the IImageSurface by loading + /// image from the new Uri. + /// + /// Uri of the image to be loaded onto the IImageSurface. + /// New size of the IImageSurface + /// The image's resize and alignment options in the allocated space. + /// Task + public Task RedrawAsync(Uri uri, Size size, ImageSurfaceOptions options) + { + // If the given Uri differs from the previously stored Uri or if the ImageSurface was + // directly created from a CanvasBitmap, dispose the existing canvasBitmap + if ((_uri != null && !_uri.IsEqualTo(uri)) + || (_uri == null && _canvasBitmap != null)) + { + _canvasBitmap?.Dispose(); + _canvasBitmap = null; + _raiseLoadCompletedEvent = uri != null; + } + + // Set the image options + Options = options; + + // Resize the surface only if AutoResize option is disabled + if (!Options.AutoResize) + { + // resize the IImageSurface + _generator.ResizeDrawingSurface(_surfaceLock, _surface, size); + + // Set the size + Size = _surface?.Size ?? new Size(0, 0); + } + + // Set the new Uri of the image to be loaded + _uri = uri; + + // Reload the IImageSurface + return RedrawSurfaceAsync(); + } + + /// + /// Resizes the IImageSurface to the new size. + /// + /// New size of the IImageSurface + public void Resize(Size size) + { + Resize(size, Options); + } + + /// + /// Resizes the IImageSurface to the new size. + /// + /// New size of the IImageSurface + /// The image's resize and alignment options in the allocated space. + public void Resize(Size size, ImageSurfaceOptions options) + { + // Set the image options + Options = options; + + // Resize the surface only if AutoResize option is disabled + if (!Options.AutoResize) + { + // resize the IImageSurface + _generator.ResizeDrawingSurface(_surfaceLock, _surface, size); + + // Set the size + Size = _surface?.Size ?? new Size(0, 0); + } + + // redraw the IImageSurface + RedrawSurface(); + } + + /// + /// Disposes the resources used by the IImageSurface + /// + public void Dispose() + { + _surface?.Dispose(); + if (_generator != null) + { + _generator.DeviceReplaced -= OnDeviceReplaced; + } + + _canvasBitmap?.Dispose(); + _canvasBitmap = null; + _surface = null; + _generator = null; + _uri = null; + Options = null; + } + + /// + /// Redraws the IImageSurface asynchronously + /// by loading the image from the Uri + /// + /// Task + internal Task RedrawAsync() + { + // Reload the IImageSurface + return RedrawSurfaceAsync(); + } + + /// + /// Handles the DeviceReplaced event + /// + /// Sender + /// object + private async void OnDeviceReplaced(object sender, object e) + { + // Recreate the ImageSurface + _surface = _generator.CreateDrawingSurface(_surfaceLock, Size); + + // Reload the IImageSurface + await RedrawSurfaceAsync(); + } + + /// + /// Helper class to redraw the IImageSurface synchronously + /// + private void RedrawSurface() + { + // Resize the surface image + _generator.RedrawImageSurface(_surfaceLock, _surface, Options, _canvasBitmap); + + // If AutoResize is allowed and the image is successfully loaded into the canvasBitmap, + // then update the Size property of the surface as the surface has been resized to match the canvasBitmap size + if (Options.AutoResize) + { + // If the image is successfully loaded into the canvasBitmap, then update the Size property + // of the surface as the surface has been resized to match the canvasBitmap size + Size = _canvasBitmap?.Size ?? new Size(0, 0); + } + + Status = _canvasBitmap != null ? ImageSurfaceLoadStatus.Success : ImageSurfaceLoadStatus.Error; + + if (_canvasBitmap != null) + { + DecodedPhysicalSize = new Size(_canvasBitmap.SizeInPixels.Width, _canvasBitmap.SizeInPixels.Height); + DecodedSize = _canvasBitmap.Size; + } + } + + /// + /// Helper class to redraw the IImageSurface asynchronously + /// + /// Task + private async Task RedrawSurfaceAsync() + { + // Cache the canvasBitmap to avoid reloading of the same image during Resize/Redraw operations + _canvasBitmap = await _generator.RedrawImageSurfaceAsync(_surfaceLock, _surface, _uri, Options, _canvasBitmap); + + // If AutoResize is allowed and the image is successfully loaded into the canvasBitmap, + // then update the Size property of the surface as the surface has been resized to match the canvasBitmap size + if (Options.AutoResize) + { + // If the image is successfully loaded into the canvasBitmap, then update the Size property + // of the surface as the surface has been resized to match the canvasBitmap size + Size = _canvasBitmap?.Size ?? new Size(0, 0); + } + + Status = _canvasBitmap != null ? ImageSurfaceLoadStatus.Success : ImageSurfaceLoadStatus.Error; + + // Get the canvasbitmap dimensions + if (_canvasBitmap != null) + { + DecodedPhysicalSize = new Size(_canvasBitmap.SizeInPixels.Width, _canvasBitmap.SizeInPixels.Height); + DecodedSize = _canvasBitmap.Size; + } + + // Raise the event + if (_raiseLoadCompletedEvent) + { + LoadCompleted?.Invoke(this, Status); + _raiseLoadCompletedEvent = false; + } + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurfaceOptions.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurfaceOptions.cs new file mode 100644 index 00000000000..a368c23541c --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurfaceOptions.cs @@ -0,0 +1,162 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.Graphics.Canvas; +using Windows.UI; +using Windows.UI.Xaml.Media; + +namespace Microsoft.Toolkit.Uwp.UI.Media.Surface +{ + /// + /// Enum to define the location of the + /// Reflection of a Visual. + /// + public enum ReflectionLocation + { + /// + /// Reflection at bottom of visual + /// + Bottom = 0, + + /// + /// Reflection at top of visual + /// + Top = 1, + + /// + /// Reflection at left of visual + /// + Left = 2, + + /// + /// Reflection at right of visual + /// + Right = 3 + } + + /// + /// Class to define the various options that would + /// influence the rendering of the image on the ImageSurface + /// + public class ImageSurfaceOptions + { + /// + /// Gets default ImageSurfaceOptions when AutoResize is True + /// Uniform Stretch and Center alignment + /// + public static ImageSurfaceOptions Default => + new ImageSurfaceOptions() + { + AutoResize = true, + Interpolation = CanvasImageInterpolation.HighQualityCubic, + Opacity = 1f, + Stretch = Stretch.Uniform, + HorizontalAlignment = AlignmentX.Center, + VerticalAlignment = AlignmentY.Center, + SurfaceBackgroundColor = Colors.Transparent, + BlurRadius = 0f + }; + + /// + /// Gets default ImageSurfaceOptions when AutoResize is False + /// Uniform Stretch and Center alignment + /// + public static ImageSurfaceOptions DefaultOptimized => + new ImageSurfaceOptions() + { + AutoResize = false, + Interpolation = CanvasImageInterpolation.HighQualityCubic, + Opacity = 1f, + Stretch = Stretch.Uniform, + HorizontalAlignment = AlignmentX.Center, + VerticalAlignment = AlignmentY.Center, + SurfaceBackgroundColor = Colors.Transparent, + BlurRadius = 0f + }; + + /// + /// Gets default ImageSurfaceOptions for IImageMaskSurface + /// Uniform Stretch and Center alignment + /// + public static ImageSurfaceOptions DefaultImageMaskOptions => + new ImageSurfaceOptions() + { + AutoResize = false, + Interpolation = CanvasImageInterpolation.HighQualityCubic, + Opacity = 1f, + Stretch = Stretch.Uniform, + HorizontalAlignment = AlignmentX.Center, + VerticalAlignment = AlignmentY.Center, + SurfaceBackgroundColor = Colors.Transparent, + BlurRadius = 0f + }; + + /// + /// Creates ImageSurfaceOptions for IImageMaskSurface for the given blurRadius - + /// Uniform Stretch and Center alignment + /// + /// Radius of the Gaussian Blur to be applied on the IImageMaskSurface. + /// instance. + public static ImageSurfaceOptions GetDefaultImageMaskOptionsForBlur(float blurRadius) + { + return new ImageSurfaceOptions() + { + AutoResize = false, + Interpolation = CanvasImageInterpolation.HighQualityCubic, + Opacity = 1f, + Stretch = Stretch.Uniform, + HorizontalAlignment = AlignmentX.Center, + VerticalAlignment = AlignmentY.Center, + SurfaceBackgroundColor = Colors.Transparent, + BlurRadius = blurRadius + }; + } + + /// + /// Gets or sets a value indicating whether specifies whether the IImageSurface should resize itself automatically to match the loaded image size. + /// NOTE: This property is not used by IImageMaskSurface. + /// + public bool AutoResize { get; set; } + + /// + /// Gets or sets describes how image is resized to fill its allocated space. + /// NOTE: This property is taken into consideration only if AutoResize is False. + /// + public Stretch Stretch { get; set; } = Stretch.None; + + /// + /// Gets or sets describes how image is positioned horizontally in the IImageSurface or IImageMaskSurface. + /// NOTE: This property is taken into consideration only if AutoResize is False. + /// + public AlignmentX HorizontalAlignment { get; set; } = AlignmentX.Center; + + /// + /// Gets or sets describes how image is positioned vertically in the IImageSurface or IImageMaskSurface. + /// NOTE: This property is taken into consideration only if AutoResize is False. + /// + public AlignmentY VerticalAlignment { get; set; } = AlignmentY.Center; + + /// + /// Gets or sets specifies the opacity of the rendered the image in an IImageSurface or the mask in an IImageMaskSurface. + /// + public float Opacity { get; set; } = 1f; + + /// + /// Gets or sets specifies the interpolation used to render the image in an IImageSurface or the mask in an IImageMaskSurface. + /// + public CanvasImageInterpolation Interpolation { get; set; } = CanvasImageInterpolation.HighQualityCubic; + + /// + /// Gets or sets color which will be used to fill the IImageSurface in an IImageSurface or the mask in an IImageMaskSurface + /// in case the image is not rendered. + /// + public Color SurfaceBackgroundColor { get; set; } = Colors.Transparent; + + /// + /// Gets or sets radius of the Gaussian blur to be applied to the IImageMaskSurface. + /// NOTE: This property is not used by IImageSurface. + /// + public float BlurRadius { get; set; } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/MaskSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/MaskSurface.cs new file mode 100644 index 00000000000..04601f43b2d --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/MaskSurface.cs @@ -0,0 +1,200 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Numerics; +using Microsoft.Graphics.Canvas.Geometry; +using Windows.Foundation; +using Windows.UI.Composition; + +namespace Microsoft.Toolkit.Uwp.UI.Media.Surface +{ + /// + /// Class for rendering custom shaped geometries onto ICompositionSurface + /// so that they can be used as masks on Composition Visuals. + /// + internal sealed class MaskSurface : IMaskSurface + { + private readonly object _surfaceLock; + private ICompositionGeneratorInternal _generator; + private CompositionDrawingSurface _surface; + + /// + /// Gets the Composition Generator + /// + public ICompositionGenerator Generator => _generator; + + /// + /// Gets the Surface of MaskSurface + /// + public ICompositionSurface Surface => _surface; + + /// + /// Gets the Geometry of the MaskSurface + /// + public CanvasGeometry Geometry { get; private set; } + + /// + /// Gets the Size of the MaskSurface + /// + public Size Size { get; private set; } + + /// + /// Gets the offset from the top left corner of the ICompositionSurface where + /// the Geometry is rendered. + /// + public Vector2 Offset { get; private set; } + + /// + /// Initializes a new instance of the class. + /// + /// ICompositionMaskGeneratorInternal object + /// Size of the MaskSurface + /// Geometry of the MaskSurface + /// The offset from the top left corner of the ICompositionSurface where + /// the Geometry is rendered. + public MaskSurface(ICompositionGeneratorInternal generator, Size size, CanvasGeometry geometry, Vector2 offset) + { + _generator = generator ?? throw new ArgumentNullException(nameof(generator), "CompositionGenerator cannot be null!"); + _surfaceLock = new object(); + Geometry = geometry; + Offset = offset; + + // Create Mask Surface + _surface = _generator.CreateDrawingSurface(_surfaceLock, size); + + // Set the size + Size = _surface?.Size ?? new Size(0, 0); + + // Subscribe to DeviceReplaced event + _generator.DeviceReplaced += OnDeviceReplaced; + } + + /// + /// Redraws the MaskSurface + /// + public void Redraw() + { + // Redraw the mask surface + RedrawSurface(); + } + + /// + /// Redraws the MaskSurface with the new geometry + /// + /// New CanvasGeometry to be applied to the mask + public void Redraw(CanvasGeometry geometry) + { + Redraw(Size, geometry, Offset); + } + + /// + /// Redraws the IMaskSurface with the new geometry + /// + /// New CanvasGeometry to be applied to the IMaskSurface + /// The offset from the top left corner of the ICompositionSurface where + /// the Geometry is rendered. + public void Redraw(CanvasGeometry geometry, Vector2 offset) + { + Redraw(Size, geometry, offset); + } + + /// + /// Resizes the MaskSurface with the given size and redraws the MaskSurface + /// with the new geometry and fills it either with White color + /// (if the MaskMode is True) or with the foreground brush + /// (if the MaskMode is False). + /// + /// New size of the mask + /// New CanvasGeometry to be applied to the mask + public void Redraw(Size size, CanvasGeometry geometry) + { + Redraw(size, geometry, Offset); + } + + /// + /// Resizes the IMaskSurface with the given size and redraws the IMaskSurface + /// with the new geometry and fills it with White color + /// + /// New size of the mask + /// New CanvasGeometry to be applied to the IMaskSurface + /// The offset from the top left corner of the ICompositionSurface where + /// the Geometry is rendered. + public void Redraw(Size size, CanvasGeometry geometry, Vector2 offset) + { + if (Size != size) + { + // Resize the mask surface + _generator.ResizeDrawingSurface(_surfaceLock, _surface, size); + + // Set the size + Size = _surface?.Size ?? new Size(0, 0); + } + + // Set the new geometry + Geometry = geometry; + + // Set the offset + Offset = offset; + + // Redraw the mask surface + RedrawSurface(); + } + + /// + /// Resizes the MaskSurface to the new size. + /// + /// New size of the mask + public void Resize(Size size) + { + // resize the mask surface + _generator.ResizeDrawingSurface(_surfaceLock, _surface, size); + + // Set the size + Size = _surface?.Size ?? new Size(0, 0); + + // Redraw the mask surface + RedrawSurface(); + } + + /// + /// Disposes the resources used by the MaskSurface + /// + public void Dispose() + { + _surface?.Dispose(); + Geometry?.Dispose(); + Geometry = null; + if (_generator != null) + { + _generator.DeviceReplaced -= OnDeviceReplaced; + } + + _surface = null; + _generator = null; + } + + /// + /// Handles the DeviceReplaced event + /// + /// Sender + /// object + private void OnDeviceReplaced(object sender, object e) + { + // Recreate the MaskSurface + _surface = _generator.CreateDrawingSurface(_surfaceLock, Size); + + // Redraw the mask surface + RedrawSurface(); + } + + /// + /// Helper class to redraw the MaskSurface + /// + private void RedrawSurface() + { + _generator.RedrawMaskSurface(_surfaceLock, _surface, Size, Geometry, Offset); + } + } +} From 824a5a51067f4e1f23458b0ceb4b0188201359fa Mon Sep 17 00:00:00 2001 From: Ratish Philip Date: Wed, 20 Jan 2021 15:52:56 -0800 Subject: [PATCH 02/21] Code comments updated. Usage of Guard included. --- .../Surface/CompositionExtensions.cs | 9 +- .../Surface/CompositionGenerator.cs | 4 +- .../Surface/CompositorExtensions.cs | 2 - .../Surface/GaussianMaskSurface.cs | 5 +- .../Surface/GeometrySurface.cs | 10 +- .../Surface/IGaussianMaskSurface.cs | 29 +++--- .../Surface/IGeometrySurface.cs | 95 +++++++------------ .../Surface/IImageMaskSurface.cs | 89 ++++++++--------- .../Surface/IImageSurface.cs | 33 +++---- .../Surface/IMaskSurface.cs | 22 ++--- .../Surface/IRenderSurface.cs | 11 +-- .../Surface/ImageMaskSurface.cs | 11 ++- .../Surface/ImageSurface.cs | 9 +- .../Surface/MaskSurface.cs | 55 ++++------- 14 files changed, 166 insertions(+), 218 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionExtensions.cs index 78b098eeb55..22fbed3e351 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionExtensions.cs @@ -27,8 +27,7 @@ public static class CompositionExtensions /// Blur Amount of the Backdrop Brush /// Backdrop Brush (optional). If not provided, then compositor creates it. /// CompositionEffectBrush - public static CompositionEffectBrush CreateMaskedBackdropBrush( - this Compositor compositor, IMaskSurface mask, Color blendColor, float blurAmount, CompositionBackdropBrush backdropBrush = null) + public static CompositionEffectBrush CreateMaskedBackdropBrush(this Compositor compositor, IMaskSurface mask, Color blendColor, float blurAmount, CompositionBackdropBrush backdropBrush = null) { return CompositionExtensions.CreateBackdropBrush(compositor, mask, blendColor, blurAmount, backdropBrush); } @@ -42,8 +41,7 @@ public static CompositionEffectBrush CreateMaskedBackdropBrush( /// Blur Amount of the Backdrop Brush /// Backdrop Brush (optional). If not provided, then compositor creates it. /// CompositionEffectBrush - public static CompositionEffectBrush CreateGaussianMaskedBackdropBrush( - this Compositor compositor, IGaussianMaskSurface mask, Color blendColor, float blurRadius, CompositionBackdropBrush backdropBrush = null) + public static CompositionEffectBrush CreateGaussianMaskedBackdropBrush(this Compositor compositor, IGaussianMaskSurface mask, Color blendColor, float blurRadius, CompositionBackdropBrush backdropBrush = null) { return CompositionExtensions.CreateBackdropBrush(compositor, mask, blendColor, blurRadius, backdropBrush); } @@ -57,8 +55,7 @@ public static CompositionEffectBrush CreateGaussianMaskedBackdropBrush( /// Blur Amount of the Backdrop Brush /// Backdrop Brush (optional). If not provided, then compositor creates it. /// CompositionEffectBrush - internal static CompositionEffectBrush CreateBackdropBrush( - Compositor compositor, IRenderSurface mask, Color blendColor, float blurAmount, CompositionBackdropBrush backdropBrush = null) + internal static CompositionEffectBrush CreateBackdropBrush(Compositor compositor, IRenderSurface mask, Color blendColor, float blurAmount, CompositionBackdropBrush backdropBrush = null) { // Blur Effect var blurEffect = new GaussianBlurEffect() diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs index 92d48f1f0fb..26a505c157e 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs @@ -11,6 +11,7 @@ using Microsoft.Graphics.Canvas.Effects; using Microsoft.Graphics.Canvas.Geometry; using Microsoft.Graphics.Canvas.UI.Composition; +using Microsoft.Toolkit.Diagnostics; using Microsoft.Toolkit.Uwp.UI.Media.Geometry; using Windows.Foundation; using Windows.Graphics.DirectX; @@ -56,7 +57,8 @@ internal sealed class CompositionGenerator : ICompositionGeneratorInternal public CompositionGenerator(Compositor compositor, bool useSharedCanvasDevice = true, bool forceSoftwareRenderer = false) { // Compositor - Compositor = compositor ?? throw new ArgumentNullException(nameof(compositor), "Compositor cannot be null!"); + Guard.IsNotNull(compositor, nameof(compositor)); + Compositor = compositor; // Disposing Lock _disposingLock = new object(); diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositorExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositorExtensions.cs index 9122695ba1c..be095957d96 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositorExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositorExtensions.cs @@ -4,8 +4,6 @@ using System; using System.Numerics; -using Microsoft.Graphics.Canvas.Geometry; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry; using Windows.UI.Composition; namespace Microsoft.Toolkit.Uwp.UI.Media.Surface diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/GaussianMaskSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/GaussianMaskSurface.cs index 01262c2e91d..01367f95fcf 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/GaussianMaskSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/GaussianMaskSurface.cs @@ -5,6 +5,7 @@ using System; using System.Numerics; using Microsoft.Graphics.Canvas.Geometry; +using Microsoft.Toolkit.Diagnostics; using Windows.Foundation; using Windows.UI.Composition; @@ -64,7 +65,9 @@ internal sealed class GaussianMaskSurface : IGaussianMaskSurface /// Radius of Gaussian Blur to be applied on the GaussianMaskSurface public GaussianMaskSurface(ICompositionGeneratorInternal generator, Size size, CanvasGeometry geometry, Vector2 offset, float blurRadius) { - _generator = generator ?? throw new ArgumentNullException(nameof(generator), "CompositionGenerator cannot be null!"); + Guard.IsNotNull(generator, nameof(generator)); + + _generator = generator; _surfaceLock = new object(); Geometry = geometry; Offset = offset; diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometrySurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometrySurface.cs index adda48a0cc7..07f66e716bd 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometrySurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometrySurface.cs @@ -2,9 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using Microsoft.Graphics.Canvas.Brushes; using Microsoft.Graphics.Canvas.Geometry; +using Microsoft.Toolkit.Diagnostics; using Microsoft.Toolkit.Uwp.UI.Media.Geometry; using Windows.Foundation; using Windows.UI; @@ -73,7 +73,9 @@ internal sealed class GeometrySurface : IGeometrySurface /// not covered by the geometry public GeometrySurface(ICompositionGeneratorInternal generator, Size size, CanvasGeometry geometry, ICanvasStroke stroke, Color fillColor, Color backgroundColor) { - _generator = generator ?? throw new ArgumentNullException(nameof(generator), "CompositionGenerator cannot be null!"); + Guard.IsNotNull(generator, nameof(generator)); + + _generator = generator; _surfaceLock = new object(); _geometry = geometry; _stroke = stroke; @@ -103,7 +105,9 @@ public GeometrySurface(ICompositionGeneratorInternal generator, Size size, Canva /// not covered by the geometry public GeometrySurface(ICompositionGeneratorInternal generator, Size size, CanvasGeometry geometry, ICanvasStroke stroke, ICanvasBrush fill, ICanvasBrush backgroundBrush) { - _generator = generator ?? throw new ArgumentNullException(nameof(generator), "CompositionGenerator cannot be null!"); + Guard.IsNotNull(generator, nameof(generator)); + + _generator = generator; _surfaceLock = new object(); _geometry = geometry; _stroke = stroke; diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/IGaussianMaskSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/IGaussianMaskSurface.cs index 1210bf3d2e2..cb493d92cd7 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/IGaussianMaskSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/IGaussianMaskSurface.cs @@ -9,42 +9,37 @@ namespace Microsoft.Toolkit.Uwp.UI.Media.Surface { /// - /// Interface for rendering custom shaped geometries onto ICompositionSurface - /// so that they can be used as masks on Composition Visuals. These geometries - /// have a Gaussian Blur applied to them. + /// Interface for rendering custom shaped geometries onto ICompositionSurface so that they can be used as masks on Composition Visuals. + /// These geometries have a Gaussian Blur applied to them. /// public interface IGaussianMaskSurface : IMaskSurface { /// - /// Gets radius of Gaussian Blur to be applied on the GaussianMaskSurface + /// Gets radius of Gaussian Blur to be applied on the GaussianMaskSurface. /// float BlurRadius { get; } /// /// Applies the given blur radius to the IGaussianMaskSurface. /// - /// Radius of Gaussian Blur to be applied on the GaussianMaskSurface + /// Radius of Gaussian Blur to be applied on the GaussianMaskSurface. void Redraw(float blurRadius); /// - /// Redraws the IGaussianMaskSurface with the new geometry and fills it with White color after applying - /// the Gaussian blur with given blur radius. + /// Redraws the IGaussianMaskSurface with the new geometry and fills it with White color after applying the Gaussian blur with given blur radius. /// - /// New CanvasGeometry to be applied to the GaussianMaskSurface - /// The offset from the top left corner of the ICompositionSurface where - /// the Geometry is rendered. - /// Radius of Gaussian Blur to be applied on the IGaussianMaskSurface + /// New CanvasGeometry to be applied to the GaussianMaskSurface. + /// The offset from the top left corner of the ICompositionSurface where the Geometry is rendered. + /// Radius of Gaussian Blur to be applied on the IGaussianMaskSurface. void Redraw(CanvasGeometry geometry, Vector2 offset, float blurRadius); /// - /// Resizes the IGaussianMaskSurface with the given size and redraws the IGaussianMaskSurface - /// with the new geometry and fills it with White color + /// Resizes the IGaussianMaskSurface with the given size and redraws the IGaussianMaskSurface with the new geometry and fills it with White color. /// /// New size of the mask - /// New CanvasGeometry to be applied to the IGaussianMaskSurface - /// The offset from the top left corner of the ICompositionSurface where - /// the Geometry is rendered. - /// Radius of Gaussian Blur to be applied on the IGaussianMaskSurface + /// New CanvasGeometry to be applied to the IGaussianMaskSurface. + /// The offset from the top left corner of the ICompositionSurface where the Geometry is rendered. + /// Radius of Gaussian Blur to be applied on the IGaussianMaskSurface. void Redraw(Size size, CanvasGeometry geometry, Vector2 offset, float blurRadius); } } \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/IGeometrySurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/IGeometrySurface.cs index 8989fbb13d2..0eef7993208 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/IGeometrySurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/IGeometrySurface.cs @@ -11,12 +11,12 @@ namespace Microsoft.Toolkit.Uwp.UI.Media.Surface { /// - /// Interface for rendering custom shaped geometries onto ICompositionSurface + /// Interface for rendering custom shaped geometries onto ICompositionSurface. /// public interface IGeometrySurface : IRenderSurface { /// - /// Gets the Surface Geometry + /// Gets the Surface Geometry. /// CanvasGeometry Geometry { get; } @@ -42,38 +42,33 @@ public interface IGeometrySurface : IRenderSurface void Redraw(CanvasGeometry geometry); /// - /// Redraws the IGeometrySurface by outlining the existing geometry with - /// the given ICanvasStroke + /// Redraws the IGeometrySurface by outlining the existing geometry with the given ICanvasStroke. /// /// ICanvasStroke defining the outline for the geometry void Redraw(ICanvasStroke stroke); /// - /// Redraws the IGeometrySurface by filling the existing geometry with - /// the fill color. + /// Redraws the IGeometrySurface by filling the existing geometry with the fill color. /// /// Color with which the geometry is to be filled void Redraw(Color fillColor); /// - /// Redraws the IGeometrySurface by filling the existing geometry with - /// the given fill color and outlining it with the given ICanvasStroke. + /// Redraws the IGeometrySurface by filling the existing geometry with the given fill color and outlining it with the given ICanvasStroke. /// /// ICanvasStroke defining the outline for the geometry /// Color with which the geometry is to be filled void Redraw(ICanvasStroke stroke, Color fillColor); /// - /// Redraws the IGeometrySurface by filling the existing geometry with - /// the fill color and the background with the background color. + /// Redraws the IGeometrySurface by filling the existing geometry with the fill color and the background with the background color. /// /// Color with which the geometry is to be filled /// Color with which the IGeometrySurface background is to be filled void Redraw(Color fillColor, Color backgroundColor); /// - /// Redraws the IGeometrySurface by outlining the existing geometry with the - /// given ICanvasStroke, filling it with the fill color and the background with the background color. + /// Redraws the IGeometrySurface by outlining the existing geometry with the given ICanvasStroke, filling it with the fill color and the background with the background color. /// /// ICanvasStroke defining the outline for the geometry /// Color with which the geometry is to be filled @@ -81,31 +76,27 @@ public interface IGeometrySurface : IRenderSurface void Redraw(ICanvasStroke stroke, Color fillColor, Color backgroundColor); /// - /// Redraws the IGeometrySurface by filling the existing geometry with - /// the fill brush. + /// Redraws the IGeometrySurface by filling the existing geometry with the fill brush. /// /// Brush with which the geometry is to be filled void Redraw(ICanvasBrush fillBrush); /// - /// Redraws the IGeometrySurface by outlining the existing geometry with the - /// given ICanvasStroke, filling it with the fill brush. + /// Redraws the IGeometrySurface by outlining the existing geometry with the given ICanvasStroke, filling it with the fill brush. /// /// ICanvasStroke defining the outline for the geometry /// Brush with which the geometry is to be filled void Redraw(ICanvasStroke stroke, ICanvasBrush fillBrush); /// - /// Redraws the IGeometrySurface by filling the existing geometry with - /// the fill brush and the background with the background brush. + /// Redraws the IGeometrySurface by filling the existing geometry with the fill brush and the background with the background brush. /// /// Brush with which the geometry is to be filled /// Brush with which the IGeometrySurface background is to be filled void Redraw(ICanvasBrush fillBrush, ICanvasBrush backgroundBrush); /// - /// Redraws the IGeometrySurface by outlining the existing geometry with the - /// given ICanvasStroke, filling it with the fill brush and the background with the background brush. + /// Redraws the IGeometrySurface by outlining the existing geometry with the given ICanvasStroke, filling it with the fill brush and the background with the background brush. /// /// ICanvasStroke defining the outline for the geometry /// Brush with which the geometry is to be filled @@ -113,16 +104,14 @@ public interface IGeometrySurface : IRenderSurface void Redraw(ICanvasStroke stroke, ICanvasBrush fillBrush, ICanvasBrush backgroundBrush); /// - /// Redraws the IGeometrySurface by filling the existing geometry with - /// the fill color and the background with the background brush. + /// Redraws the IGeometrySurface by filling the existing geometry with the fill color and the background with the background brush. /// /// Color with which the geometry is to be filled /// Brush with which the IGeometrySurface background is to be filled void Redraw(Color fillColor, ICanvasBrush backgroundBrush); /// - /// Redraws the IGeometrySurface by outlining the existing geometry with the - /// given ICanvasStroke, filling it with the fill color and the background with the background brush. + /// Redraws the IGeometrySurface by outlining the existing geometry with the given ICanvasStroke, filling it with the fill color and the background with the background brush. /// /// ICanvasStroke defining the outline for the geometry /// Color with which the geometry is to be filled @@ -130,16 +119,14 @@ public interface IGeometrySurface : IRenderSurface void Redraw(ICanvasStroke stroke, Color fillColor, ICanvasBrush backgroundBrush); /// - /// Redraws the IGeometrySurface by filling the existing geometry with - /// the fill brush and the background with the background color. + /// Redraws the IGeometrySurface by filling the existing geometry with the fill brush and the background with the background color. /// /// Brush with which the geometry is to be filled /// Color with which the IGeometrySurface background is to be filled void Redraw(ICanvasBrush fillBrush, Color backgroundColor); /// - /// Redraws the IGeometrySurface by outlining the existing geometry with the - /// given ICanvasStroke, filling it with the fill brush and the background with the background color. + /// Redraws the IGeometrySurface by outlining the existing geometry with the given ICanvasStroke, filling it with the fill brush and the background with the background color. /// /// ICanvasStroke defining the outline for the geometry /// Brush with which the geometry is to be filled @@ -147,16 +134,14 @@ public interface IGeometrySurface : IRenderSurface void Redraw(ICanvasStroke stroke, ICanvasBrush fillBrush, Color backgroundColor); /// - /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface - /// with the new geometry. + /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface with the new geometry. /// /// New size of the IGeometrySurface /// New CanvasGeometry to be applied to the IGeometrySurface void Redraw(Size size, CanvasGeometry geometry); /// - /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface - /// with the new geometry and outlines it with the given ICanvasStroke. + /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface with the new geometry and outlines it with the given ICanvasStroke. /// /// New size of the IGeometrySurface /// New CanvasGeometry to be applied to the IGeometrySurface @@ -164,8 +149,7 @@ public interface IGeometrySurface : IRenderSurface void Redraw(Size size, CanvasGeometry geometry, ICanvasStroke stroke); /// - /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface - /// with the new geometry and fills it with the fill color. + /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface with the new geometry and fills it with the fill color. /// /// New size of the IGeometrySurface /// New CanvasGeometry to be applied to the IGeometrySurface @@ -173,9 +157,7 @@ public interface IGeometrySurface : IRenderSurface void Redraw(Size size, CanvasGeometry geometry, Color fillColor); /// - /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface - /// with the new geometry, outlines it with the given ICanvasStroke and fills - /// it with the fill color. + /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface with the new geometry, outlines it with the given ICanvasStroke and fills it with the fill color. /// /// New size of the IGeometrySurface /// New CanvasGeometry to be applied to the IGeometrySurface @@ -184,9 +166,7 @@ public interface IGeometrySurface : IRenderSurface void Redraw(Size size, CanvasGeometry geometry, ICanvasStroke stroke, Color fillColor); /// - /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface - /// with the new geometry and fills it with the fill color and - /// fills the background with the background color. + /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface with the new geometry and fills it with the fill color and fills the background with the background color. /// /// New size of the IGeometrySurface /// New CanvasGeometry to be applied to the IGeometrySurface @@ -195,9 +175,8 @@ public interface IGeometrySurface : IRenderSurface void Redraw(Size size, CanvasGeometry geometry, Color fillColor, Color backgroundColor); /// - /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface - /// with the new geometry, outlines it with the given ICanvasStroke and fills it with - /// the fill color and fills the background with the background color. + /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface with the new geometry, outlines it with the given ICanvasStroke and + /// fills it with the fill color and fills the background with the background color. /// /// New size of the IGeometrySurface /// New CanvasGeometry to be applied to the IGeometrySurface @@ -207,8 +186,7 @@ public interface IGeometrySurface : IRenderSurface void Redraw(Size size, CanvasGeometry geometry, ICanvasStroke stroke, Color fillColor, Color backgroundColor); /// - /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface - /// with the new geometry and fills it with the fill brush. + /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface with the new geometry and fills it with the fill brush. /// /// New size of the IGeometrySurface /// New CanvasGeometry to be applied to the IGeometrySurface @@ -216,9 +194,7 @@ public interface IGeometrySurface : IRenderSurface void Redraw(Size size, CanvasGeometry geometry, ICanvasBrush fillBrush); /// - /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface - /// with the new geometry and fills it with the fill brush and fills - /// the background with the background brush. + /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface with the new geometry and fills it with the fill brush and fills the background with the background brush. /// /// New size of the IGeometrySurface /// New CanvasGeometry to be applied to the IGeometrySurface @@ -227,9 +203,8 @@ public interface IGeometrySurface : IRenderSurface void Redraw(Size size, CanvasGeometry geometry, ICanvasBrush fillBrush, ICanvasBrush backgroundBrush); /// - /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface - /// with the new geometry, outlines it with the given ICanvasStroke and fills it with the - /// fill brush and fills the background with the background brush. + /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface with the new geometry, outlines it with the given ICanvasStroke and + /// fills it with the fill brush and fills the background with the background brush. /// /// New size of the IGeometrySurface /// New CanvasGeometry to be applied to the IGeometrySurface @@ -239,9 +214,7 @@ public interface IGeometrySurface : IRenderSurface void Redraw(Size size, CanvasGeometry geometry, ICanvasStroke stroke, ICanvasBrush fillBrush, ICanvasBrush backgroundBrush); /// - /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface - /// with the new geometry and fills it with the fill brush and the background - /// with the background color. + /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface with the new geometry and fills it with the fill brush and the background with the background color. /// /// New size of the IGeometrySurface /// New CanvasGeometry to be applied to the IGeometrySurface @@ -250,9 +223,8 @@ public interface IGeometrySurface : IRenderSurface void Redraw(Size size, CanvasGeometry geometry, ICanvasBrush fillBrush, Color backgroundColor); /// - /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface - /// with the new geometry, outlines it with the given ICanvasStroke and fills it with - /// the fill brush and the background with the background color. + /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface with the new geometry, outlines it with the given ICanvasStroke and + /// fills it with the fill brush and the background with the background color. /// /// New size of the IGeometrySurface /// New CanvasGeometry to be applied to the IGeometrySurface @@ -262,9 +234,7 @@ public interface IGeometrySurface : IRenderSurface void Redraw(Size size, CanvasGeometry geometry, ICanvasStroke stroke, ICanvasBrush fillBrush, Color backgroundColor); /// - /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface - /// with the new geometry and fills it with the fill color and the background - /// with the background brush. + /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface with the new geometry and fills it with the fill color and the background with the background brush. /// /// New size of the IGeometrySurface /// New CanvasGeometry to be applied to the IGeometrySurface @@ -273,9 +243,8 @@ public interface IGeometrySurface : IRenderSurface void Redraw(Size size, CanvasGeometry geometry, Color fillColor, ICanvasBrush backgroundBrush); /// - /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface - /// with the new geometry, outlines it with the given ICanvasStroke and fills it with - /// the fill color and the background with the background brush. + /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface with the new geometry, outlines it with the given ICanvasStroke and + /// fills it with the fill color and the background with the background brush. /// /// New size of the IGeometrySurface /// New CanvasGeometry to be applied to the IGeometrySurface diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/IImageMaskSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/IImageMaskSurface.cs index c30312d24d1..eb46492d421 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/IImageMaskSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/IImageMaskSurface.cs @@ -11,13 +11,12 @@ namespace Microsoft.Toolkit.Uwp.UI.Media.Surface { /// - /// Interface for rendering a mask, using an Image's alpha values, onto an ICompositionSurface + /// Interface for rendering a mask, using an Image's alpha values, onto an ICompositionSurface. /// public interface IImageMaskSurface : IImageSurface { /// - /// Gets the padding between the IImageMaskSurface outer bounds and the bounds of the area where - /// the mask, created from the loaded image's alpha values, should be rendered. + /// Gets the padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. /// Thickness MaskPadding { get; } @@ -25,28 +24,29 @@ public interface IImageMaskSurface : IImageSurface /// Redraws the IImageMaskSurface using the given CanvasBitmap's alpha values with the given padding. /// /// ImageSurface whose image's alpha values are to be used to create the mask. - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where - /// the mask, created from the loaded image's alpha values, should be rendered. + /// + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. + /// void Redraw(IImageSurface imageSurface, Thickness padding); /// - /// Redraws the IImageMaskSurface using the given CanvasBitmap's alpha values with the given padding - /// using the given options. + /// Redraws the IImageMaskSurface using the given CanvasBitmap's alpha values with the given padding using the given options. /// /// ImageSurface whose image's alpha values are to be used to create the mask. - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where - /// the mask, created from the loaded image's alpha values, should be rendered. + /// + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. + /// /// Describes the image's resize, alignment and blur radius options in the allocated space. void Redraw(IImageSurface imageSurface, Thickness padding, ImageSurfaceOptions options); /// - /// Resizes and redraws the IImageMaskSurface using the given CanvasBitmap's alpha values with the given padding - /// using the given options. + /// Resizes and redraws the IImageMaskSurface using the given CanvasBitmap's alpha values with the given padding using the given options. /// /// ImageSurface whose image's alpha values are to be used to create the mask. /// New size of the IImageMaskSurface. - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where - /// the mask, created from the loaded image's alpha values, should be rendered. + /// + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. + /// /// Describes the image's resize, alignment and blur radius options in the allocated space. void Redraw(IImageSurface imageSurface, Size size, Thickness padding, ImageSurfaceOptions options); @@ -54,17 +54,18 @@ public interface IImageMaskSurface : IImageSurface /// Redraws the IImageMaskSurface using the given CanvasBitmap's alpha values with the given padding. /// /// Image whose alpha values are to be used to create the mask. - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where - /// the mask, created from the loaded image's alpha values, should be rendered. + /// + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. + /// void Redraw(CanvasBitmap surfaceBitmap, Thickness padding); /// - /// Redraws the IImageMaskSurface using the given CanvasBitmap's alpha values with the given padding - /// using the given options. + /// Redraws the IImageMaskSurface using the given CanvasBitmap's alpha values with the given padding using the given options. /// /// Image whose alpha values are to be used to create the mask. - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where - /// the mask, created from the loaded image's alpha values, should be rendered. + /// + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. + /// /// Describes the image's resize, alignment and blur radius options in the allocated space. void Redraw(CanvasBitmap surfaceBitmap, Thickness padding, ImageSurfaceOptions options); @@ -75,12 +76,12 @@ public interface IImageMaskSurface : IImageSurface void Redraw(IImageMaskSurface imageMaskSurface); /// - /// Redraws the IImageMaskSurface using the alpha values of the image in the given IImageMaskSurface with the given padding - /// and options. + /// Redraws the IImageMaskSurface using the alpha values of the image in the given IImageMaskSurface with the given padding and options. /// /// IImageMaskSurface whose image's alpha values are to be used to create the mask. - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where - /// the mask, created from the loaded image's alpha values, should be rendered. + /// + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. + /// void Redraw(IImageMaskSurface imageMaskSurface, Thickness padding); /// @@ -91,34 +92,34 @@ public interface IImageMaskSurface : IImageSurface void Redraw(IImageMaskSurface imageMaskSurface, ImageSurfaceOptions options); /// - /// Redraws the IImageMaskSurface using the alpha values of the image in the given IImageMaskSurface using the given padding - /// and options. + /// Redraws the IImageMaskSurface using the alpha values of the image in the given IImageMaskSurface using the given padding and options. /// /// IImageMaskSurface whose image's alpha values are to be used to create the mask. - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where - /// the mask, created from the loaded image's alpha values, should be rendered. + /// + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. + /// /// Describes the image's resize, alignment and blur radius options in the allocated space. void Redraw(IImageMaskSurface imageMaskSurface, Thickness padding, ImageSurfaceOptions options); /// - /// Resizes and redraws the IImageMaskSurface using the alpha values of the image in the given IImageMaskSurface - /// with the given padding and options. + /// Resizes and redraws the IImageMaskSurface using the alpha values of the image in the given IImageMaskSurface with the given padding and options. /// /// IImageMaskSurface whose image's alpha values are to be used to create the mask. /// New size of the IImageMaskSurface. - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where - /// the mask, created from the loaded image's alpha values, should be rendered. + /// + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. + /// /// Describes the image's resize, alignment and blur radius options in the allocated space. void Redraw(IImageMaskSurface imageMaskSurface, Size size, Thickness padding, ImageSurfaceOptions options); /// - /// Resizes and redraws the IImageMaskSurface using the given CanvasBitmap's alpha values with the given padding - /// using the given options. + /// Resizes and redraws the IImageMaskSurface using the given CanvasBitmap's alpha values with the given padding using the given options. /// /// Image whose alpha values are to be used to create the mask. /// New size of the IImageMaskSurface. - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where - /// the mask, created from the loaded image's alpha values, should be rendered. + /// + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. + /// /// Describes the image's resize, alignment and blur radius options in the allocated space. void Redraw(CanvasBitmap surfaceBitmap, Size size, Thickness padding, ImageSurfaceOptions options); @@ -126,20 +127,21 @@ public interface IImageMaskSurface : IImageSurface /// Redraws the IImageMaskSurface by loading image from the new Uri and image options /// /// Uri of the image to be loaded on to the image surface. - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where - /// the mask, created from the loaded image's alpha values, should be rendered. + /// + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. + /// /// Describes the image's resize, alignment and blur radius options in the allocated space. /// Task Task RedrawAsync(Uri uri, Thickness padding, ImageSurfaceOptions options); /// - /// Resizes the IImageMaskSurface with the given size and loads the image from the new Uri and uses its - /// alpha values to redraw the IImageMaskSurface with the given padding using the given options. + /// Resizes the IImageMaskSurface with the given size and loads the image from the new Uri and uses its alpha values to redraw the IImageMaskSurface with the given padding using the given options. /// /// Uri of the image to be loaded onto the IImageMaskSurface. /// New size of the IImageMaskSurface - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where - /// the mask, created from the loaded image's alpha values, should be rendered. + /// + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. + /// /// Describes the image's resize, alignment and blur radius options in the allocated space. /// Task Task RedrawAsync(Uri uri, Size size, Thickness padding, ImageSurfaceOptions options); @@ -148,8 +150,9 @@ public interface IImageMaskSurface : IImageSurface /// Resizes the IImageMaskSurface to the new size and redraws it with the given padding using the given options. /// /// New size of the IImageMaskSurface - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where - /// the mask, created from the loaded image's alpha values, should be rendered. + /// + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. + /// /// The image's resize, alignment and blur radius options in the allocated space. void Resize(Size size, Thickness padding, ImageSurfaceOptions options); } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/IImageSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/IImageSurface.cs index 9c7513edb5b..08356ad428a 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/IImageSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/IImageSurface.cs @@ -10,13 +10,12 @@ namespace Microsoft.Toolkit.Uwp.UI.Media.Surface { /// - /// Enumeration to describe the status of the loading of an image - /// on the IImageSurface + /// Enumeration to describe the status of the loading of an image on the IImageSurface. /// public enum ImageSurfaceLoadStatus { /// - /// Indicates that no image has been loaded on the IImageSurface + /// Indicates that no image has been loaded on the IImageSurface. /// None, @@ -37,18 +36,17 @@ public enum ImageSurfaceLoadStatus public interface IImageSurface : IRenderSurface { /// - /// Event that is raised when the image has been downloaded, decoded and loaded - /// to the underlying IImageSurface. This event fires regardless of success or failure. + /// Event that is raised when the image has been downloaded, decoded and loaded to the underlying IImageSurface. This event fires regardless of success or failure. /// event TypedEventHandler LoadCompleted; /// - /// Gets the Uri of the image to be loaded onto the IImageSurface + /// Gets the Uri of the image to be loaded onto the IImageSurface. /// Uri Uri { get; } /// - /// Gets the CanvasBitmap representing the loaded image + /// Gets the CanvasBitmap representing the loaded image. /// CanvasBitmap SurfaceBitmap { get; } @@ -79,23 +77,20 @@ public interface IImageSurface : IRenderSurface void Redraw(ImageSurfaceOptions options); /// - /// Redraws the IImageSurface (using the image in the given imageSurface) or the IImageMaskSurface - /// (using the alpha values of image in the given imageSurface). + /// Redraws the IImageSurface (using the image in the given imageSurface) or the IImageMaskSurface (using the alpha values of image in the given imageSurface). /// /// IImageSurface whose image is to be loaded on the surface. void Redraw(IImageSurface imageSurface); /// - /// Redraws the IImageSurface (using the given CanvasBitmap) or the IImageMaskSurface - /// (using the given CanvasBitmap's alpha values) using the given options. + /// Redraws the IImageSurface (using the given CanvasBitmap) or the IImageMaskSurface (using the given CanvasBitmap's alpha values) using the given options. /// /// IImageSurface whose image is to be loaded on the surface. /// Describes the image's resize, alignment options in the allocated space. void Redraw(IImageSurface imageSurface, ImageSurfaceOptions options); /// - /// Resizes and redraws the IImageSurface (using the given CanvasBitmap) or the IImageMaskSurface - /// (using the given CanvasBitmap's alpha values) using the given options. + /// Resizes and redraws the IImageSurface (using the given CanvasBitmap) or the IImageMaskSurface (using the given CanvasBitmap's alpha values) using the given options. /// /// IImageSurface whose image is to be loaded on the surface. /// New size of the IImageMaskSurface. @@ -103,23 +98,20 @@ public interface IImageSurface : IRenderSurface void Redraw(IImageSurface imageSurface, Size size, ImageSurfaceOptions options); /// - /// Redraws the IImageSurface (using the given CanvasBitmap) or the IImageMaskSurface - /// (using the given CanvasBitmap's alpha values). + /// Redraws the IImageSurface (using the given CanvasBitmap) or the IImageMaskSurface (using the given CanvasBitmap's alpha values). /// /// Image to be loaded on the surface. void Redraw(CanvasBitmap surfaceBitmap); /// - /// Redraws the IImageSurface (using the given CanvasBitmap) or the IImageMaskSurface - /// (using the given CanvasBitmap's alpha values) using the given options. + /// Redraws the IImageSurface (using the given CanvasBitmap) or the IImageMaskSurface (using the given CanvasBitmap's alpha values) using the given options. /// /// Image to be loaded on the surface. /// Describes the image's resize, alignment options in the allocated space. void Redraw(CanvasBitmap surfaceBitmap, ImageSurfaceOptions options); /// - /// Resizes and redraws the IImageSurface (using the given CanvasBitmap) or the IImageMaskSurface - /// (using the given CanvasBitmap's alpha values) using the given options. + /// Resizes and redraws the IImageSurface (using the given CanvasBitmap) or the IImageMaskSurface (using the given CanvasBitmap's alpha values) using the given options. /// /// Image to be loaded on the surface.. /// New size of the IImageMaskSurface. @@ -135,8 +127,7 @@ public interface IImageSurface : IRenderSurface Task RedrawAsync(Uri uri, ImageSurfaceOptions options); /// - /// Resizes the IImageSurface or IImageMaskSurface with the given size and redraws it by loading - /// image from the new Uri. + /// Resizes the IImageSurface or IImageMaskSurface with the given size and redraws it by loading image from the new Uri. /// /// Uri of the image to be loaded onto the IImageSurface. /// New size of the IImageSurface diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/IMaskSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/IMaskSurface.cs index f00e96e87a4..b1bc9c43bab 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/IMaskSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/IMaskSurface.cs @@ -9,19 +9,17 @@ namespace Microsoft.Toolkit.Uwp.UI.Media.Surface { /// - /// Interface for rendering custom shaped geometries onto ICompositionSurface - /// so that they can be used as masks on Composition Visuals. + /// Interface for rendering custom shaped geometries onto ICompositionSurface so that they can be used as masks on Composition Visuals. /// public interface IMaskSurface : IRenderSurface { /// - /// Gets the Geometry of the MaskSurface + /// Gets the Geometry of the MaskSurface. /// CanvasGeometry Geometry { get; } /// - /// Gets the offset from the top left corner of the ICompositionSurface where - /// the Geometry is rendered. + /// Gets the offset from the top left corner of the ICompositionSurface where the Geometry is rendered. /// Vector2 Offset { get; } @@ -32,29 +30,25 @@ public interface IMaskSurface : IRenderSurface void Redraw(CanvasGeometry geometry); /// - /// Resizes the MaskSurface with the given size and redraws the IMaskSurface - /// with the new geometry and fills it with White color + /// Resizes the MaskSurface with the given size and redraws the IMaskSurface with the new geometry and fills it with White color. /// /// New size of the mask /// New CanvasGeometry to be applied to the IMaskSurface void Redraw(Size size, CanvasGeometry geometry); /// - /// Redraws the IMaskSurface with the new geometry + /// Redraws the IMaskSurface with the new geometry. /// /// New CanvasGeometry to be applied to the IMaskSurface - /// The offset from the top left corner of the ICompositionSurface where - /// the Geometry is rendered. + /// The offset from the top left corner of the ICompositionSurface where the Geometry is rendered. void Redraw(CanvasGeometry geometry, Vector2 offset); /// - /// Resizes the IMaskSurface with the given size and redraws the IMaskSurface - /// with the new geometry and fills it with White color + /// Resizes the IMaskSurface with the given size and redraws the IMaskSurface with the new geometry and fills it with White color. /// /// New size of the mask /// New CanvasGeometry to be applied to the IMaskSurface - /// The offset from the top left corner of the ICompositionSurface where - /// the Geometry is rendered. + /// The offset from the top left corner of the ICompositionSurface where the Geometry is rendered. void Redraw(Size size, CanvasGeometry geometry, Vector2 offset); } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/IRenderSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/IRenderSurface.cs index 6afd9f4ad17..d91af826f2d 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/IRenderSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/IRenderSurface.cs @@ -9,28 +9,27 @@ namespace Microsoft.Toolkit.Uwp.UI.Media.Surface { /// - /// Represents the core interface for interfaces - /// which render onto ICompositionSurface. + /// Represents the core interface for interfaces which render onto ICompositionSurface. /// public interface IRenderSurface : IDisposable { /// - /// Gets the Generator + /// Gets the CompositionGenerator. /// ICompositionGenerator Generator { get; } /// - /// Gets the Surface + /// Gets the Surface. /// ICompositionSurface Surface { get; } /// - /// Gets the Surface Size + /// Gets the Surface Size. /// Size Size { get; } /// - /// Redraws the surface + /// Redraws the surface. /// void Redraw(); diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageMaskSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageMaskSurface.cs index 991301a5c7f..f8cae205266 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageMaskSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageMaskSurface.cs @@ -5,6 +5,7 @@ using System; using System.Threading.Tasks; using Microsoft.Graphics.Canvas; +using Microsoft.Toolkit.Diagnostics; using Microsoft.Toolkit.Uwp.UI.Media.Geometry; using Windows.Foundation; using Windows.UI.Composition; @@ -91,8 +92,9 @@ internal sealed class ImageMaskSurface : IImageMaskSurface /// The image's resize, alignment options and blur radius in the allocated space. public ImageMaskSurface(ICompositionGeneratorInternal generator, Uri uri, Size size, Thickness padding, ImageSurfaceOptions options) { - _generator = generator ?? - throw new ArgumentNullException(nameof(generator), "CompositionGenerator cannot be null!"); + Guard.IsNotNull(generator, nameof(generator)); + + _generator = generator; _surfaceLock = new object(); // Create the Surface of the IImageMaskSurface @@ -123,8 +125,9 @@ public ImageMaskSurface(ICompositionGeneratorInternal generator, Uri uri, Size s /// The image's resize, alignment options and blur radius in the allocated space. public ImageMaskSurface(ICompositionGeneratorInternal generator, CanvasBitmap surfaceBitmap, Size size, Thickness padding, ImageSurfaceOptions options) { - _generator = generator ?? - throw new ArgumentNullException(nameof(generator), "CompositionGenerator cannot be null!"); + Guard.IsNotNull(generator, nameof(generator)); + + _generator = generator; _surfaceLock = new object(); // Create the Surface of the IImageMaskSurface diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurface.cs index f895bb7fb08..028430fbfdb 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurface.cs @@ -5,6 +5,7 @@ using System; using System.Threading.Tasks; using Microsoft.Graphics.Canvas; +using Microsoft.Toolkit.Diagnostics; using Microsoft.Toolkit.Uwp.UI.Media.Geometry; using Windows.Foundation; using Windows.UI.Composition; @@ -84,7 +85,9 @@ internal sealed class ImageSurface : IImageSurface /// The image's resize and alignment options in the allocated space. public ImageSurface(ICompositionGeneratorInternal generator, Uri uri, Size size, ImageSurfaceOptions options) { - _generator = generator ?? throw new ArgumentNullException(nameof(generator), "CompositionGenerator cannot be null!"); + Guard.IsNotNull(generator, nameof(generator)); + + _generator = generator; _surfaceLock = new object(); // Create the Surface of the IImageSurface @@ -112,7 +115,9 @@ public ImageSurface(ICompositionGeneratorInternal generator, Uri uri, Size size, /// The image's resize and alignment options in the allocated space. internal ImageSurface(ICompositionGeneratorInternal generator, CanvasBitmap surfaceBitmap, Size size, ImageSurfaceOptions options) { - _generator = generator ?? throw new ArgumentNullException(nameof(generator), "CompositionGenerator cannot be null!"); + Guard.IsNotNull(generator, nameof(generator)); + + _generator = generator; _surfaceLock = new object(); // Create the Surface of the IImageSurface diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/MaskSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/MaskSurface.cs index 04601f43b2d..11f5f2626c1 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/MaskSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/MaskSurface.cs @@ -2,17 +2,16 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using System.Numerics; using Microsoft.Graphics.Canvas.Geometry; +using Microsoft.Toolkit.Diagnostics; using Windows.Foundation; using Windows.UI.Composition; namespace Microsoft.Toolkit.Uwp.UI.Media.Surface { /// - /// Class for rendering custom shaped geometries onto ICompositionSurface - /// so that they can be used as masks on Composition Visuals. + /// Class for rendering custom shaped geometries onto ICompositionSurface so that they can be used as masks on Composition Visuals. /// internal sealed class MaskSurface : IMaskSurface { @@ -20,30 +19,19 @@ internal sealed class MaskSurface : IMaskSurface private ICompositionGeneratorInternal _generator; private CompositionDrawingSurface _surface; - /// - /// Gets the Composition Generator - /// + /// public ICompositionGenerator Generator => _generator; - /// - /// Gets the Surface of MaskSurface - /// + /// public ICompositionSurface Surface => _surface; - /// - /// Gets the Geometry of the MaskSurface - /// + /// public CanvasGeometry Geometry { get; private set; } - /// - /// Gets the Size of the MaskSurface - /// + /// public Size Size { get; private set; } - /// - /// Gets the offset from the top left corner of the ICompositionSurface where - /// the Geometry is rendered. - /// + /// public Vector2 Offset { get; private set; } /// @@ -52,11 +40,12 @@ internal sealed class MaskSurface : IMaskSurface /// ICompositionMaskGeneratorInternal object /// Size of the MaskSurface /// Geometry of the MaskSurface - /// The offset from the top left corner of the ICompositionSurface where - /// the Geometry is rendered. + /// The offset from the top left corner of the ICompositionSurface where the Geometry is rendered. public MaskSurface(ICompositionGeneratorInternal generator, Size size, CanvasGeometry geometry, Vector2 offset) { - _generator = generator ?? throw new ArgumentNullException(nameof(generator), "CompositionGenerator cannot be null!"); + Guard.IsNotNull(generator, nameof(generator)); + + _generator = generator; _surfaceLock = new object(); Geometry = geometry; Offset = offset; @@ -81,9 +70,9 @@ public void Redraw() } /// - /// Redraws the MaskSurface with the new geometry + /// Redraws the MaskSurface with the new geometry. /// - /// New CanvasGeometry to be applied to the mask + /// New CanvasGeometry to be applied to the mask. public void Redraw(CanvasGeometry geometry) { Redraw(Size, geometry, Offset); @@ -93,18 +82,15 @@ public void Redraw(CanvasGeometry geometry) /// Redraws the IMaskSurface with the new geometry /// /// New CanvasGeometry to be applied to the IMaskSurface - /// The offset from the top left corner of the ICompositionSurface where - /// the Geometry is rendered. + /// The offset from the top left corner of the ICompositionSurface where the Geometry is rendered. public void Redraw(CanvasGeometry geometry, Vector2 offset) { Redraw(Size, geometry, offset); } /// - /// Resizes the MaskSurface with the given size and redraws the MaskSurface - /// with the new geometry and fills it either with White color - /// (if the MaskMode is True) or with the foreground brush - /// (if the MaskMode is False). + /// Resizes the MaskSurface with the given size and redraws the MaskSurface with the new geometry and fills it either with White color + /// (if the MaskMode is True) or with the foreground brush (if the MaskMode is False). /// /// New size of the mask /// New CanvasGeometry to be applied to the mask @@ -114,8 +100,7 @@ public void Redraw(Size size, CanvasGeometry geometry) } /// - /// Resizes the IMaskSurface with the given size and redraws the IMaskSurface - /// with the new geometry and fills it with White color + /// Resizes the IMaskSurface with the given size and redraws the IMaskSurface with the new geometry and fills it with White color. /// /// New size of the mask /// New CanvasGeometry to be applied to the IMaskSurface @@ -159,7 +144,7 @@ public void Resize(Size size) } /// - /// Disposes the resources used by the MaskSurface + /// Disposes the resources used by the MaskSurface. /// public void Dispose() { @@ -176,7 +161,7 @@ public void Dispose() } /// - /// Handles the DeviceReplaced event + /// Handles the DeviceReplaced event. /// /// Sender /// object @@ -190,7 +175,7 @@ private void OnDeviceReplaced(object sender, object e) } /// - /// Helper class to redraw the MaskSurface + /// Helper class to redraw the MaskSurface. /// private void RedrawSurface() { From 31633bd4081ed6051dbbe5faca3db9e48c7a3ab1 Mon Sep 17 00:00:00 2001 From: Ratish Philip Date: Sun, 24 Jan 2021 17:05:39 -0800 Subject: [PATCH 03/21] Build error fix for Effects. --- .../Surface/CompositionExtensions.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionExtensions.cs index 22fbed3e351..de4b55a3d48 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionExtensions.cs @@ -58,7 +58,7 @@ public static CompositionEffectBrush CreateGaussianMaskedBackdropBrush(this Comp internal static CompositionEffectBrush CreateBackdropBrush(Compositor compositor, IRenderSurface mask, Color blendColor, float blurAmount, CompositionBackdropBrush backdropBrush = null) { // Blur Effect - var blurEffect = new GaussianBlurEffect() + var blurEffect = new Microsoft.Graphics.Canvas.Effects.GaussianBlurEffect() { Name = "Blur", BlurAmount = blurAmount, @@ -68,9 +68,9 @@ internal static CompositionEffectBrush CreateBackdropBrush(Compositor compositor }; // Blend Effect - var blendEffect = new BlendEffect + var blendEffect = new Microsoft.Graphics.Canvas.Effects.BlendEffect { - Foreground = new ColorSourceEffect + Foreground = new Microsoft.Graphics.Canvas.Effects.ColorSourceEffect { Name = "Color", Color = blendColor @@ -80,7 +80,7 @@ internal static CompositionEffectBrush CreateBackdropBrush(Compositor compositor }; // Composite Effect - var effect = new CompositeEffect + var effect = new Microsoft.Graphics.Canvas.Effects.CompositeEffect { Mode = CanvasComposite.DestinationIn, Sources = @@ -131,19 +131,19 @@ public static CompositionEffectBrush CreateFrostedGlassBrush( float backdropAmount = 0.5f) { // Create a frosty glass effect - var frostEffect = new GaussianBlurEffect + var frostEffect = new Microsoft.Graphics.Canvas.Effects.GaussianBlurEffect { Name = "Blur", BlurAmount = blurAmount, BorderMode = EffectBorderMode.Hard, - Source = new ArithmeticCompositeEffect + Source = new Microsoft.Graphics.Canvas.Effects.ArithmeticCompositeEffect { Name = "Source", MultiplyAmount = multiplyAmount, Source1Amount = backdropAmount, Source2Amount = colorAmount, Source1 = new CompositionEffectSourceParameter("backdrop"), - Source2 = new ColorSourceEffect + Source2 = new Microsoft.Graphics.Canvas.Effects.ColorSourceEffect { Name = "BlendColor", Color = blendColor @@ -152,7 +152,7 @@ public static CompositionEffectBrush CreateFrostedGlassBrush( }; // Composite Effect - var effect = new CompositeEffect + var effect = new Microsoft.Graphics.Canvas.Effects.CompositeEffect { Mode = CanvasComposite.DestinationIn, Sources = From fe1ff1189f5fd7ac1d975f56baf1f9abcd480929 Mon Sep 17 00:00:00 2001 From: Ratish Philip Date: Wed, 17 Feb 2021 07:38:16 -0800 Subject: [PATCH 04/21] RenderSurfaces and basic CanvasGeometry classes for XAML added. --- .../Brushes/Base/RenderSurfaceBrushBase.cs | 160 ++++++++++++++++++ .../Brushes/GeometrySurfaceBrush.cs | 15 ++ .../Geometry/CanvasCoreGeometry.cs | 85 ++++++++++ .../Geometry/CanvasEllipseGeometry.cs | 137 +++++++++++++++ .../Geometry/CanvasPathGeometry.cs | 74 +++++++- .../Geometry/CanvasRectangleGeometry.cs | 63 +++++++ .../CanvasRoundedRectangleGeometry.cs | 96 +++++++++++ .../Geometry/CanvasSquircleGeometry.cs | 95 +++++++++++ .../Geometry/CanvasStroke.cs | 10 ++ .../Geometry/ICanvasPathGeometry.cs | 17 ++ .../Geometry/Parsers/CanvasGeometryParser.cs | 1 + .../Surface/CompositionExtensions.cs | 18 +- .../Surface/CompositionGenerator.cs | 137 ++++++++------- .../Surface/CompositorExtensions.cs | 24 +-- .../Surface/GaussianMaskSurface.cs | 6 +- ...{MaskSurface.cs => GeometryMaskSurface.cs} | 38 ++--- .../Surface/GeometrySurface.cs | 11 +- .../Surface/ICompositionGenerator.cs | 26 +-- .../Surface/ICompositionGeneratorInternal.cs | 14 +- .../Surface/IGaussianMaskSurface.cs | 2 +- ...MaskSurface.cs => IGeometryMaskSurface.cs} | 20 +-- .../Surface/ImageMaskSurface.cs | 9 +- .../Surface/ImageSurface.cs | 9 +- .../Converters/Vector2Converter.cs | 77 +++++++++ .../Converters/Vector4Converter.cs | 77 +++++++++ 25 files changed, 1051 insertions(+), 170 deletions(-) create mode 100644 Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderSurfaceBrushBase.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometrySurfaceBrush.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCoreGeometry.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasEllipseGeometry.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasRectangleGeometry.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasRoundedRectangleGeometry.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasSquircleGeometry.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Media/Geometry/ICanvasPathGeometry.cs rename Microsoft.Toolkit.Uwp.UI.Media/Surface/{MaskSurface.cs => GeometryMaskSurface.cs} (78%) rename Microsoft.Toolkit.Uwp.UI.Media/Surface/{IMaskSurface.cs => IGeometryMaskSurface.cs} (72%) create mode 100644 Microsoft.Toolkit.Uwp.UI/Converters/Vector2Converter.cs create mode 100644 Microsoft.Toolkit.Uwp.UI/Converters/Vector4Converter.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderSurfaceBrushBase.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderSurfaceBrushBase.cs new file mode 100644 index 00000000000..6e7ffca7551 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderSurfaceBrushBase.cs @@ -0,0 +1,160 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Toolkit.Uwp.UI.Media.Extensions; +using Microsoft.Toolkit.Uwp.UI.Media.Surface; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Media; + +namespace Microsoft.Toolkit.Uwp.UI.Media +{ + /// + /// Base class for RenderSurface brushes + /// + public abstract class RenderSurfaceBrushBase : XamlCompositionBrushBase + { + /// + /// The initialization instance. + /// + private readonly AsyncMutex connectedMutex = new AsyncMutex(); + + /// + /// SurfaceWidth Dependency Property + /// + public static readonly DependencyProperty SurfaceWidthProperty = DependencyProperty.Register( + "SurfaceWidth", + typeof(float), + typeof(RenderSurfaceBrushBase), + new PropertyMetadata(0f, OnSurfaceWidthChanged)); + + /// + /// SurfaceHeight Dependency Property + /// + public static readonly DependencyProperty SurfaceHeightProperty = DependencyProperty.Register( + "SurfaceHeight", + typeof(float), + typeof(RenderSurfaceBrushBase), + new PropertyMetadata(0f, OnSurfaceHeightChanged)); + + /// + /// Gets or sets the width of the Brush Surface. + /// + public float SurfaceWidth + { + get => (float)GetValue(SurfaceWidthProperty); + set => SetValue(SurfaceWidthProperty, value); + } + + /// + /// Gets or sets the height of the Brush Surface. + /// + public float SurfaceHeight + { + get => (float)GetValue(SurfaceHeightProperty); + set => SetValue(SurfaceHeightProperty, value); + } + + /// + /// Gets or sets the instance. + /// + protected ICompositionGenerator Generator { get; set; } + + /// + /// Handles changes to the SurfaceWidth property. + /// + /// RenderSurfaceBrushBase + /// DependencyProperty changed event arguments + private static void OnSurfaceWidthChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var target = (RenderSurfaceBrushBase)d; + target.OnSurfaceWidthChanged(); + } + + /// + /// Handles changes to the SurfaceHeight property. + /// + /// RenderSurfaceBrushBase + /// DependencyProperty changed event arguments + private static void OnSurfaceHeightChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var brush = (RenderSurfaceBrushBase)d; + brush.OnSurfaceHeightChanged(); + } + + /// + /// Instance handler for the changes to the SurfaceWidth property. + /// + private void OnSurfaceWidthChanged() + { + OnSurfaceBrushUpdated(); + } + + /// + /// Instance handler for the changes to the SurfaceHeight property. + /// + private void OnSurfaceHeightChanged() + { + OnSurfaceBrushUpdated(); + } + + /// + protected override async void OnConnected() + { + using (await connectedMutex.LockAsync()) + { + if (CompositionBrush == null) + { + Generator = CompositionGenerator.Instance; + + Generator.DeviceReplaced += OnDeviceReplaced; + + OnSurfaceBrushUpdated(); + } + } + + base.OnConnected(); + } + + /// + protected override async void OnDisconnected() + { + using (await connectedMutex.LockAsync()) + { + if (Generator != null) + { + Generator.DeviceReplaced -= OnDeviceReplaced; + Generator.Dispose(); + } + + // Dispose of composition resources when no longer in use. + if (CompositionBrush != null) + { + CompositionBrush.Dispose(); + CompositionBrush = null; + } + } + + base.OnDisconnected(); + } + + /// + /// Handler for the DeviceReplaced event. + /// + /// Sender + /// EventArgs + private void OnDeviceReplaced(object sender, object e) + { + OnDisconnected(); + OnConnected(); + } + + /// + /// Invoked whenever any brush property is updated. + /// + protected virtual void OnSurfaceBrushUpdated() + { + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometrySurfaceBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometrySurfaceBrush.cs new file mode 100644 index 00000000000..1861bdac574 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometrySurfaceBrush.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Microsoft.Toolkit.Uwp.UI.Media +{ + /// + /// Brush + /// + public sealed class GeometrySurfaceBrush : RenderSurfaceBrushBase + { + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCoreGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCoreGeometry.cs new file mode 100644 index 00000000000..2a1b515a170 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCoreGeometry.cs @@ -0,0 +1,85 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Runtime.CompilerServices; +using Microsoft.Graphics.Canvas.Geometry; +using Windows.UI.Xaml; + +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry +{ + /// + /// Provides a base class for objects that define geometric shapes using CanvasGeometry. + /// + public abstract class CanvasCoreGeometry : DependencyObject, ICanvasPathGeometry, IDisposable + { + private bool _disposedValue; + + /// + /// Geometry Dependency Property + /// + public static readonly DependencyProperty GeometryProperty = DependencyProperty.Register( + "Geometry", + typeof(CanvasGeometry), + typeof(CanvasCoreGeometry), + new PropertyMetadata(null, OnGeometryChanged)); + + /// + /// Gets or sets the associated Win2d CanvasGeometry. + /// + public CanvasGeometry Geometry + { + get => (CanvasGeometry)GetValue(GeometryProperty); + protected set => SetValue(GeometryProperty, value); + } + + /// + /// Handles changes to the Geometry property. + /// + /// CanvasCoreGeometry + /// DependencyProperty changed event arguments + private static void OnGeometryChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var coreGeometry = (CanvasCoreGeometry)d; + coreGeometry.OnGeometryChanged(); + } + + /// + /// Instance handler for the changes to the Geometry dependency property. + /// + protected virtual void OnGeometryChanged() + { + } + + /// + /// Method to be called when any of the parameters affecting the Geometry is updated. + /// + protected abstract void UpdateGeometry(); + + /// + /// Disposes the resources used by the CanvasCoreGeometry and its derivatives + /// + /// Flag to indicate if we are disposing the managed objects. + protected virtual void Dispose(bool disposing) + { + if (!_disposedValue) + { + if (disposing) + { + Geometry.Dispose(); + } + + _disposedValue = true; + } + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Dispose() + { + Dispose(disposing: true); + GC.SuppressFinalize(this); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasEllipseGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasEllipseGeometry.cs new file mode 100644 index 00000000000..144babced25 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasEllipseGeometry.cs @@ -0,0 +1,137 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.ComponentModel; +using System.Numerics; +using Microsoft.Graphics.Canvas.Geometry; +using Microsoft.Toolkit.Uwp.UI.Converters; +using Microsoft.Toolkit.Uwp.UI.Media.Surface; +using Windows.UI.Xaml; + +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry +{ + /// + /// Represents a rounded rectangle geometry object with the specified extents. + /// + public class CanvasEllipseGeometry : CanvasCoreGeometry + { + /// + /// Center Dependency Property + /// + public static readonly DependencyProperty CenterProperty = DependencyProperty.Register( + "Center", + typeof(Vector2), + typeof(CanvasEllipseGeometry), + new PropertyMetadata(Vector2.Zero, OnCenterChanged)); + + /// + /// Gets or sets the structure that describes the position and size of the . The default is . + /// + [TypeConverter(typeof(Vector2Converter))] + public Vector2 Center + { + get => (Vector2)GetValue(CenterProperty); + set => SetValue(CenterProperty, value); + } + + /// + /// Handles changes to the Center property. + /// + /// CanvasEllipseGeometry + /// DependencyProperty changed event arguments + private static void OnCenterChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var ellipseGeometry = (CanvasEllipseGeometry)d; + ellipseGeometry.OnCenterChanged(); + } + + /// + /// Instance handler for the changes to the Center dependency property. + /// + private void OnCenterChanged() + { + UpdateGeometry(); + } + + /// + /// RadiusX Dependency Property + /// + public static readonly DependencyProperty RadiusXProperty = DependencyProperty.Register( + "RadiusX", + typeof(float), + typeof(CanvasEllipseGeometry), + new PropertyMetadata(0f, OnRadiusXChanged)); + + /// + /// Gets or sets the x-radius value of the . + /// + public float RadiusX + { + get => (float)GetValue(RadiusXProperty); + set => SetValue(RadiusXProperty, value); + } + + /// + /// Handles changes to the RadiusX property. + /// + /// CanvasEllipseGeometry + /// DependencyProperty changed event arguments + private static void OnRadiusXChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var roundedRectangleGeometry = (CanvasEllipseGeometry)d; + roundedRectangleGeometry.OnRadiusXChanged(); + } + + /// + /// Instance handler for the changes to the RadiusX dependency property. + /// + private void OnRadiusXChanged() + { + UpdateGeometry(); + } + + /// + /// RadiusY Dependency Property + /// + public static readonly DependencyProperty RadiusYProperty = DependencyProperty.Register( + "RadiusY", + typeof(float), + typeof(CanvasEllipseGeometry), + new PropertyMetadata(0f, OnRadiusYChanged)); + + /// + /// Gets or sets the y-radius value of the . + /// + public float RadiusY + { + get => (float)GetValue(RadiusYProperty); + set => SetValue(RadiusYProperty, value); + } + + /// + /// Handles changes to the RadiusY property. + /// + /// CanvasEllipseGeometry + /// DependencyProperty changed event arguments + private static void OnRadiusYChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var roundedRectangleGeometry = (CanvasEllipseGeometry)d; + roundedRectangleGeometry.OnRadiusYChanged(); + } + + /// + /// Instance handler for the changes to the RadiusY dependency property. + /// + private void OnRadiusYChanged() + { + UpdateGeometry(); + } + + /// + protected override void UpdateGeometry() + { + Geometry = CanvasGeometry.CreateEllipse(CompositionGenerator.Instance.Device, Center, RadiusX, RadiusY); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasPathGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasPathGeometry.cs index 5a6bad1c378..8810c6ef72f 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasPathGeometry.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasPathGeometry.cs @@ -2,22 +2,86 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System; using System.Numerics; -using System.Runtime.CompilerServices; -using System.Text; using Microsoft.Graphics.Canvas; using Microsoft.Graphics.Canvas.Brushes; using Microsoft.Graphics.Canvas.Geometry; using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Parsers; +using Microsoft.Toolkit.Uwp.UI.Media.Surface; using Windows.UI; +using Windows.UI.Xaml; namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// - /// Helper Class for creating Win2d objects. + /// Represents a complex vector-based shape that may be composed of arcs, curves, ellipses, lines, rectangles, rounded rectangles, squircles. + /// Also provides several helper methods to create Win2d objects. /// - public static class CanvasPathGeometry + public class CanvasPathGeometry : CanvasCoreGeometry { + /// + /// Data Dependency Property + /// + public static readonly DependencyProperty DataProperty = DependencyProperty.Register( + "Data", + typeof(string), + typeof(CanvasPathGeometry), + new PropertyMetadata(string.Empty, OnDataChanged)); + + /// + /// Gets or sets the path data for the associated Win2d CanvasGeometry defined in the Win2d Path Mini Language. + /// + public string Data + { + get => (string)GetValue(DataProperty); + set => SetValue(DataProperty, value); + } + + /// + /// Handles changes to the Data property. + /// + /// CanvasPathGeometry + /// DependencyProperty changed event arguments + private static void OnDataChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var pathGeometry = (CanvasPathGeometry)d; + pathGeometry.OnDataChanged(); + } + + /// + /// Instance handler for the changes to the Data dependency property. + /// + protected virtual void OnDataChanged() + { + UpdateGeometry(); + } + + /// + /// Initializes a new instance of the class. + /// + public CanvasPathGeometry() + { + this.Geometry = null; + } + + /// + protected override void UpdateGeometry() + { + // Dispose previous CanvasGeometry (if any) + Geometry?.Dispose(); + Geometry = null; + + try + { + Geometry = CreateGeometry(CompositionGenerator.Instance.Device, Data); + } + catch (Exception) + { + Geometry = null; + } + } + /// /// Parses the Path data string and converts it to CanvasGeometry. /// @@ -25,7 +89,7 @@ public static class CanvasPathGeometry /// public static CanvasGeometry CreateGeometry(string pathData) { - return CreateGeometry(null, pathData); + return CreateGeometry(CompositionGenerator.Instance.Device, pathData); } /// diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasRectangleGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasRectangleGeometry.cs new file mode 100644 index 00000000000..88c6c9a9f88 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasRectangleGeometry.cs @@ -0,0 +1,63 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.ComponentModel; +using System.Numerics; +using Microsoft.Graphics.Canvas.Geometry; +using Microsoft.Toolkit.Uwp.UI.Converters; +using Microsoft.Toolkit.Uwp.UI.Media.Surface; +using Windows.UI.Xaml; + +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry +{ + /// + /// Represents a rectangular shape + /// + public class CanvasRectangleGeometry : CanvasCoreGeometry + { + /// + /// Rect Dependency Property + /// + public static readonly DependencyProperty RectProperty = DependencyProperty.Register( + "Rect", + typeof(Vector4), + typeof(CanvasRectangleGeometry), + new PropertyMetadata(Vector4.Zero, OnRectChanged)); + + /// + /// Gets or sets the structure that describes the position and size of the geometry. The default is . + /// + [TypeConverter(typeof(Vector4Converter))] + public Vector4 Rect + { + get => (Vector4)GetValue(RectProperty); + set => SetValue(RectProperty, value); + } + + /// + /// Handles changes to the Rect property. + /// + /// CanvasRectangleGeometry + /// DependencyProperty changed event arguments + private static void OnRectChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var rectangleGeometry = (CanvasRectangleGeometry)d; + rectangleGeometry.OnRectChanged(); + } + + /// + /// Instance handler for the changes to the Rect dependency property. + /// + private void OnRectChanged() + { + UpdateGeometry(); + } + + /// + protected override void UpdateGeometry() + { + Geometry = CanvasGeometry.CreateRectangle(CompositionGenerator.Instance.Device, Rect.X, Rect.Y, Rect.Z, Rect.W); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasRoundedRectangleGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasRoundedRectangleGeometry.cs new file mode 100644 index 00000000000..47ec841bec7 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasRoundedRectangleGeometry.cs @@ -0,0 +1,96 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.Graphics.Canvas.Geometry; +using Microsoft.Toolkit.Uwp.UI.Media.Surface; +using Windows.UI.Xaml; + +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry +{ + /// + /// Represents a rounded rectangle geometry object with the specified extents. + /// + public class CanvasRoundedRectangleGeometry : CanvasRectangleGeometry + { + /// + /// RadiusX Dependency Property + /// + public static readonly DependencyProperty RadiusXProperty = DependencyProperty.Register( + "RadiusX", + typeof(float), + typeof(CanvasRoundedRectangleGeometry), + new PropertyMetadata(0f, OnRadiusXChanged)); + + /// + /// Gets or sets the radius of the corners in the x-axis. + /// + public float RadiusX + { + get => (float)GetValue(RadiusXProperty); + set => SetValue(RadiusXProperty, value); + } + + /// + /// Handles changes to the RadiusX property. + /// + /// CanvasRoundedRectangleGeometry + /// DependencyProperty changed event arguments + private static void OnRadiusXChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var roundedRectangleGeometry = (CanvasRoundedRectangleGeometry)d; + roundedRectangleGeometry.OnRadiusXChanged(); + } + + /// + /// Instance handler for the changes to the RadiusX dependency property. + /// + private void OnRadiusXChanged() + { + UpdateGeometry(); + } + + /// + /// RadiusY Dependency Property + /// + public static readonly DependencyProperty RadiusYProperty = DependencyProperty.Register( + "RadiusY", + typeof(float), + typeof(CanvasRoundedRectangleGeometry), + new PropertyMetadata(0f, OnRadiusYChanged)); + + /// + /// Gets or sets the radius of the corners in the x-axis. + /// + public float RadiusY + { + get => (float)GetValue(RadiusYProperty); + set => SetValue(RadiusYProperty, value); + } + + /// + /// Handles changes to the RadiusY property. + /// + /// CanvasRoundedRectangleGeometry + /// DependencyProperty changed event arguments + private static void OnRadiusYChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var roundedRectangleGeometry = (CanvasRoundedRectangleGeometry)d; + roundedRectangleGeometry.OnRadiusYChanged(); + } + + /// + /// Instance handler for the changes to the RadiusY dependency property. + /// + private void OnRadiusYChanged() + { + UpdateGeometry(); + } + + /// + protected override void UpdateGeometry() + { + Geometry = CanvasGeometry.CreateRoundedRectangle(CompositionGenerator.Instance.Device, Rect.X, Rect.Y, Rect.Z, Rect.W, RadiusX, RadiusY); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasSquircleGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasSquircleGeometry.cs new file mode 100644 index 00000000000..9cdddd1963b --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasSquircleGeometry.cs @@ -0,0 +1,95 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.Toolkit.Uwp.UI.Media.Surface; +using Windows.UI.Xaml; + +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry +{ + /// + /// Represents a rounded rectangle geometry object with the specified extents. + /// + public class CanvasSquircleGeometry : CanvasRectangleGeometry + { + /// + /// RadiusX Dependency Property + /// + public static readonly DependencyProperty RadiusXProperty = DependencyProperty.Register( + "RadiusX", + typeof(float), + typeof(CanvasSquircleGeometry), + new PropertyMetadata(0f, OnRadiusXChanged)); + + /// + /// Gets or sets the radius of the corners in the x-axis. + /// + public float RadiusX + { + get => (float)GetValue(RadiusXProperty); + set => SetValue(RadiusXProperty, value); + } + + /// + /// Handles changes to the RadiusX property. + /// + /// CanvasSquircleGeometry + /// DependencyProperty changed event arguments + private static void OnRadiusXChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var roundedRectangleGeometry = (CanvasSquircleGeometry)d; + roundedRectangleGeometry.OnRadiusXChanged(); + } + + /// + /// Instance handler for the changes to the RadiusX dependency property. + /// + private void OnRadiusXChanged() + { + UpdateGeometry(); + } + + /// + /// RadiusY Dependency Property + /// + public static readonly DependencyProperty RadiusYProperty = DependencyProperty.Register( + "RadiusY", + typeof(float), + typeof(CanvasSquircleGeometry), + new PropertyMetadata(0f, OnRadiusYChanged)); + + /// + /// Gets or sets the radius of the corners in the x-axis. + /// + public float RadiusY + { + get => (float)GetValue(RadiusYProperty); + set => SetValue(RadiusYProperty, value); + } + + /// + /// Handles changes to the RadiusY property. + /// + /// CanvasSquircleGeometry + /// DependencyProperty changed event arguments + private static void OnRadiusYChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var roundedRectangleGeometry = (CanvasSquircleGeometry)d; + roundedRectangleGeometry.OnRadiusYChanged(); + } + + /// + /// Instance handler for the changes to the RadiusY dependency property. + /// + private void OnRadiusYChanged() + { + UpdateGeometry(); + } + + /// + protected override void UpdateGeometry() + { + Geometry = CanvasPathGeometry.CreateSquircle(CompositionGenerator.Instance.Device, Rect.X, Rect.Y, Rect.Z, Rect.W, RadiusX, RadiusY); + } + } +} \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasStroke.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasStroke.cs index 5daf59081c1..210f1dcfb7a 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasStroke.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasStroke.cs @@ -40,6 +40,16 @@ public Matrix3x2 Transform set => SetTransform(value); } + /// + /// Initializes a new instance of the class. + /// + public CanvasStroke() + { + Brush = null; + Width = 0; + Style = new CanvasStrokeStyle(); + } + /// /// Initializes a new instance of the class. /// diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/ICanvasPathGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/ICanvasPathGeometry.cs new file mode 100644 index 00000000000..b82f17a979d --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/ICanvasPathGeometry.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Graphics.Canvas.Geometry; + +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry +{ + internal interface ICanvasPathGeometry + { + /// + /// Gets the associate CanvasGeometry + /// + CanvasGeometry Geometry { get; } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasGeometryParser.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasGeometryParser.cs index df11070fedd..f47b47a72c6 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasGeometryParser.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasGeometryParser.cs @@ -128,6 +128,7 @@ static void ThrowForInvalidCharacters(List pathFigures, stri return CanvasGeometry.CreatePath(pathBuilder); static void ThrowForZeroCount() => throw new ArgumentException("PATH_ERR000:Invalid Path data! No matching path data found!"); + static void ThrowForNotOneCount() => throw new ArgumentException("PATH_ERR001:Multiple FillRule elements present in Path Data!\n" + "There should be only one FillRule within the Path Data. " + "You can either remove additional FillRule elements or split the Path Data " + diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionExtensions.cs index de4b55a3d48..2c92f4f3f8e 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionExtensions.cs @@ -19,15 +19,15 @@ namespace Microsoft.Toolkit.Uwp.UI.Media.Surface public static class CompositionExtensions { /// - /// Creates a custom shaped Effect Brush using BackdropBrush and an IMaskSurface + /// Creates a custom shaped Effect Brush using BackdropBrush and an IGeometryMaskSurface /// /// Compositor - /// IMaskSurface + /// IGeometryMaskSurface /// Color to blend in the BackdropBrush /// Blur Amount of the Backdrop Brush /// Backdrop Brush (optional). If not provided, then compositor creates it. /// CompositionEffectBrush - public static CompositionEffectBrush CreateMaskedBackdropBrush(this Compositor compositor, IMaskSurface mask, Color blendColor, float blurAmount, CompositionBackdropBrush backdropBrush = null) + public static CompositionEffectBrush CreateMaskedBackdropBrush(this Compositor compositor, IGeometryMaskSurface mask, Color blendColor, float blurAmount, CompositionBackdropBrush backdropBrush = null) { return CompositionExtensions.CreateBackdropBrush(compositor, mask, blendColor, blurAmount, backdropBrush); } @@ -36,7 +36,7 @@ public static CompositionEffectBrush CreateMaskedBackdropBrush(this Compositor c /// Creates a custom shaped Effect Brush using BackdropBrush and an IGaussianMaskSurface /// /// Compositor - /// IMaskSurface + /// IGeometryMaskSurface /// Color to blend in the BackdropBrush /// Blur Amount of the Backdrop Brush /// Backdrop Brush (optional). If not provided, then compositor creates it. @@ -47,10 +47,10 @@ public static CompositionEffectBrush CreateGaussianMaskedBackdropBrush(this Comp } /// - /// Creates a custom shaped Effect Brush using BackdropBrush and an IMaskSurface or an IGaussianMaskSurface + /// Creates a custom shaped Effect Brush using BackdropBrush and an IGeometryMaskSurface or an IGaussianMaskSurface /// /// Compositor - /// IMaskSurface or IGaussianMaskSurface + /// IGeometryMaskSurface or IGaussianMaskSurface /// Color to blend in the BackdropBrush /// Blur Amount of the Backdrop Brush /// Backdrop Brush (optional). If not provided, then compositor creates it. @@ -101,7 +101,7 @@ internal static CompositionEffectBrush CreateBackdropBrush(Compositor compositor brush.SetSourceParameter("backdrop", backdropBrush ?? compositor.CreateBackdropBrush()); // Set the Mask - // Create SurfaceBrush from IMaskSurface + // Create SurfaceBrush from IGeometryMaskSurface var maskBrush = compositor.CreateSurfaceBrush(mask.Surface); brush.SetSourceParameter("mask", maskBrush); @@ -112,7 +112,7 @@ internal static CompositionEffectBrush CreateBackdropBrush(Compositor compositor /// Creates a custom shaped Frosted Glass Effect Brush using BackdropBrush and a Mask /// /// Compositor - /// IMaskSurface + /// IGeometryMaskSurface /// Color to blend in the BackdropBrush /// Blur Amount of the Backdrop Brush /// Backdrop Brush (optional). If not provided, then compositor creates it. @@ -122,7 +122,7 @@ internal static CompositionEffectBrush CreateBackdropBrush(Compositor compositor /// CompositionEffectBrush public static CompositionEffectBrush CreateFrostedGlassBrush( this Compositor compositor, - IMaskSurface mask, + IGeometryMaskSurface mask, Color blendColor, float blurAmount, CompositionBackdropBrush backdropBrush = null, diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs index 26a505c157e..0f6900406ac 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs @@ -11,7 +11,6 @@ using Microsoft.Graphics.Canvas.Effects; using Microsoft.Graphics.Canvas.Geometry; using Microsoft.Graphics.Canvas.UI.Composition; -using Microsoft.Toolkit.Diagnostics; using Microsoft.Toolkit.Uwp.UI.Media.Geometry; using Windows.Foundation; using Windows.Graphics.DirectX; @@ -22,28 +21,34 @@ namespace Microsoft.Toolkit.Uwp.UI.Media.Surface { /// - /// Class to create mask which can be used to create custom shaped - /// Composition Visuals. + /// Core class which is used to create various RenderSurfaces like GeometrySurface, GeometryMaskSurface, GaussianMaskSurface, ImageSurface, ImageMaskSurface /// - internal sealed class CompositionGenerator : ICompositionGeneratorInternal + public sealed class CompositionGenerator : ICompositionGeneratorInternal { /// /// Device Replaced event /// public event EventHandler DeviceReplaced; + private static Lazy _instance = + new Lazy(() => new CompositionGenerator(), System.Threading.LazyThreadSafetyMode.PublicationOnly); + private readonly object _disposingLock; - private readonly bool _useSharedCanvasDevice; - private readonly bool _forceSoftwareRenderer; + private bool _useSharedCanvasDevice; private CompositionGraphicsDevice _compositionDevice; /// - /// Gets the Compositor + /// Gets the CompositionGenerator instance. + /// + public static ICompositionGenerator Instance => _instance.Value; + + /// + /// Gets the Compositor. /// public Compositor Compositor { get; private set; } /// - /// Gets the CanvasDevice + /// Gets the CanvasDevice. /// public CanvasDevice Device { get; private set; } @@ -51,20 +56,21 @@ internal sealed class CompositionGenerator : ICompositionGeneratorInternal /// Initializes a new instance of the class. /// Constructor /// - /// Compositor - /// Indicates whether to use a shared CanvasDevice or to create a new one. - /// Indicates whether to use Software Renderer when creating a new CanvasDevice. - public CompositionGenerator(Compositor compositor, bool useSharedCanvasDevice = true, bool forceSoftwareRenderer = false) + private CompositionGenerator() { - // Compositor - Guard.IsNotNull(compositor, nameof(compositor)); - Compositor = compositor; + Compositor = Window.Current.Compositor; + if (Compositor == null) + { + // Since the compositor is null, we cannot proceed with the initialization of the CompositionGenerator. Therefore, throw an exception so that the value of + // the GeneratorInstance.IsValueCreated property remains false, and subsequent calls to the GeneratorInstance.Value property, either by the thread where the exception was + // thrown or by other threads, cause the initialization method to run again. + throw new ArgumentException("Cannot instantiate CompositionGenerator. Window.Current.Compositor is null."); + } // Disposing Lock _disposingLock = new object(); - _useSharedCanvasDevice = useSharedCanvasDevice; - _forceSoftwareRenderer = forceSoftwareRenderer; + InitializeDevices(); } /// @@ -300,30 +306,34 @@ private static void RenderBitmapMask(CanvasDevice device, object surfaceLock, Co /// Indicates whether the DeviceReplacedEvent should be raised. private void InitializeDevices(bool raiseEvent = false) { - lock (this._disposingLock) + lock (_disposingLock) { - if (!(this.Device is null)) + if (!(Device is null)) { - this.Device.DeviceLost -= this.OnDeviceLost; + Device.DeviceLost -= OnDeviceLost; } - if (!(this._compositionDevice is null)) + if (!(_compositionDevice is null)) { - this._compositionDevice.RenderingDeviceReplaced -= this.OnRenderingDeviceReplaced; + _compositionDevice.RenderingDeviceReplaced -= OnRenderingDeviceReplaced; } // Canvas Device - Device = _useSharedCanvasDevice - ? CanvasDevice.GetSharedDevice(_forceSoftwareRenderer) - : new CanvasDevice(_forceSoftwareRenderer); + _useSharedCanvasDevice = true; + Device = CanvasDevice.GetSharedDevice(); + if (Device is null) + { + Device = new CanvasDevice(); + _useSharedCanvasDevice = false; + } // Composition Graphics Device _compositionDevice = CanvasComposition.CreateCompositionGraphicsDevice(Compositor, Device); - _compositionDevice.RenderingDeviceReplaced += this.OnRenderingDeviceReplaced; + _compositionDevice.RenderingDeviceReplaced += OnRenderingDeviceReplaced; - this.Device.DeviceLost += this.OnDeviceLost; - this._compositionDevice.RenderingDeviceReplaced += this.OnRenderingDeviceReplaced; + Device.DeviceLost += OnDeviceLost; + _compositionDevice.RenderingDeviceReplaced += OnRenderingDeviceReplaced; if (raiseEvent) { @@ -359,31 +369,31 @@ private void RaiseDeviceReplacedEvent() } /// - /// Creates an Empty IMaskSurface having the no size and geometry. - /// NOTE: Use this API if you want to create an Empty IMaskSurface first - /// and change its geometry and/or size of the IMaskSurface later. + /// Creates an Empty IGeometryMaskSurface having the no size and geometry. + /// NOTE: Use this API if you want to create an Empty IGeometryMaskSurface first + /// and change its geometry and/or size of the IGeometryMaskSurface later. /// - /// IMaskSurface - public IMaskSurface CreateMaskSurface() + /// IGeometryMaskSurface + public IGeometryMaskSurface CreateGeometryMaskSurface() { - return CreateMaskSurface(default, null, Vector2.Zero); + return CreateGeometryMaskSurface(default, null, Vector2.Zero); } /// - /// Creates an IMaskSurface having the given size and geometry with MaskMode as True. + /// Creates an IGeometryMaskSurface having the given size and geometry with MaskMode as True. /// The geometry is filled with white color. The surface not covered by the geometry is /// transparent. /// /// Size of the mask /// Geometry of the mask - /// IMaskSurface - public IMaskSurface CreateMaskSurface(Size size, CanvasGeometry geometry) + /// IGeometryMaskSurface + public IGeometryMaskSurface CreateGeometryMaskSurface(Size size, CanvasGeometry geometry) { - return CreateMaskSurface(size, geometry, Vector2.Zero); + return CreateGeometryMaskSurface(size, geometry, Vector2.Zero); } /// - /// Creates an IMaskSurface having the given size and geometry with MaskMode as True. + /// Creates an IGeometryMaskSurface having the given size and geometry with MaskMode as True. /// The geometry is filled with white color. The surface not covered by the geometry is /// transparent. /// @@ -391,11 +401,11 @@ public IMaskSurface CreateMaskSurface(Size size, CanvasGeometry geometry) /// Geometry of the mask /// The offset from the top left corner of the ICompositionSurface where /// the Geometry is rendered. - /// IMaskSurface - public IMaskSurface CreateMaskSurface(Size size, CanvasGeometry geometry, Vector2 offset) + /// IGeometryMaskSurface + public IGeometryMaskSurface CreateGeometryMaskSurface(Size size, CanvasGeometry geometry, Vector2 offset) { // Initialize the mask - IMaskSurface mask = new MaskSurface(this, size, geometry, offset); + IGeometryMaskSurface mask = new GeometryMaskSurface(this, size, geometry, offset); // Render the mask mask.Redraw(); @@ -427,12 +437,12 @@ public IGaussianMaskSurface CreateGaussianMaskSurface() public IGaussianMaskSurface CreateGaussianMaskSurface(Size size, CanvasGeometry geometry, Vector2 offset, float blurRadius) { // Initialize the mask - IGaussianMaskSurface mask = new GaussianMaskSurface(this, size, geometry, offset, blurRadius); + IGaussianMaskSurface gaussianMaskSurface = new GaussianMaskSurface(this, size, geometry, offset, blurRadius); // Render the mask - mask.Redraw(); + gaussianMaskSurface.Redraw(); - return mask; + return gaussianMaskSurface; } /// @@ -1005,7 +1015,7 @@ public CompositionDrawingSurface CreateDrawingSurface(object surfaceLock, Size s // at the same time, we need to do any device/surface work under a lock. lock (surfaceLock) { - return this._compositionDevice.CreateDrawingSurface(surfaceSize, DirectXPixelFormat.B8G8R8A8UIntNormalized, DirectXAlphaMode.Premultiplied); + return _compositionDevice.CreateDrawingSurface(surfaceSize, DirectXPixelFormat.B8G8R8A8UIntNormalized, DirectXAlphaMode.Premultiplied); } } @@ -1037,19 +1047,19 @@ public void ResizeDrawingSurface(object surfaceLock, CompositionDrawingSurface s } /// - /// Redraws the IMaskSurface with the given size and geometry + /// Redraws the IGeometryMaskSurface with the given size and geometry /// /// The object to lock to prevent multiple threads /// from accessing the surface at the same time. /// CompositionDrawingSurface - /// Size of the IMaskSurface - /// Geometry of the IMaskSurface + /// Size of the IGeometryMaskSurface + /// Geometry of the IGeometryMaskSurface /// The offset from the top left corner of the ICompositionSurface where /// the Geometry is rendered. public void RedrawMaskSurface(object surfaceLock, CompositionDrawingSurface surface, Size size, CanvasGeometry geometry, Vector2 offset) { // If the surface is not created, create it - surface ??= this.CreateDrawingSurface(surfaceLock, size); + surface ??= CreateDrawingSurface(surfaceLock, size); // No need to render if the width and/or height of the surface is zero if (surface.Size.Width.IsZero() || surface.Size.Height.IsZero()) @@ -1098,7 +1108,7 @@ public void RedrawMaskSurface(object surfaceLock, CompositionDrawingSurface surf public void RedrawGaussianMaskSurface(object surfaceLock, CompositionDrawingSurface surface, Size size, CanvasGeometry geometry, Vector2 offset, float blurRadius) { // If the surface is not created, create it - surface ??= this.CreateDrawingSurface(surfaceLock, size); + surface ??= CreateDrawingSurface(surfaceLock, size); // No need to render if the width and/or height of the surface is zero if (surface.Size.Width.IsZero() || surface.Size.Height.IsZero()) @@ -1166,7 +1176,7 @@ public void RedrawGaussianMaskSurface(object surfaceLock, CompositionDrawingSurf public void RedrawGeometrySurface(object surfaceLock, CompositionDrawingSurface surface, Size size, CanvasGeometry geometry, ICanvasStroke stroke, ICanvasBrush fillBrush, ICanvasBrush backgroundBrush) { // If the surface is not created, create it - surface ??= this.CreateDrawingSurface(surfaceLock, size); + surface ??= CreateDrawingSurface(surfaceLock, size); // No need to render if the width and/or height of the surface is zero if (surface.Size.Width.IsZero() || surface.Size.Height.IsZero()) @@ -1327,7 +1337,8 @@ public async Task RedrawImageMaskSurfaceAsync(object surfaceLock, } /// - /// Disposes the resources used by the CompositionMaskGenerator + /// Disposes the resources used by the CompositionGenerator. + /// NOTE: This should be called only when the application ends because CompositionGenerator is a singleton and its instance might be used across the application. /// public void Dispose() { @@ -1338,7 +1349,7 @@ public void Dispose() if (Device != null) { // Only dispose the canvas device if we own the device. - if (this._useSharedCanvasDevice) + if (!_useSharedCanvasDevice) { Device.Dispose(); } @@ -1346,20 +1357,20 @@ public void Dispose() Device = null; } - if (this._compositionDevice == null) + if (_compositionDevice != null) { - return; - } + _compositionDevice.RenderingDeviceReplaced -= OnRenderingDeviceReplaced; - this._compositionDevice.RenderingDeviceReplaced -= this.OnRenderingDeviceReplaced; + // Only dispose the composition graphics device if we own the device. + if (!_useSharedCanvasDevice) + { + _compositionDevice.Dispose(); + } - // Only dispose the composition graphics device if we own the device. - if (!this._useSharedCanvasDevice) - { - this._compositionDevice.Dispose(); + _compositionDevice = null; } - this._compositionDevice = null; + System.Threading.Interlocked.Exchange(ref _instance, null); } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositorExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositorExtensions.cs index be095957d96..a45f72e130e 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositorExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositorExtensions.cs @@ -14,28 +14,6 @@ namespace Microsoft.Toolkit.Uwp.UI.Media.Surface /// public static class CompositorExtensions { - /// - /// Creates a CompositionGenerator object - /// - /// Compositor - /// ICompositionGenerator - public static ICompositionGenerator CreateCompositionGenerator(this Compositor compositor) - { - return new CompositionGenerator(compositor); - } - - /// - /// Creates a CompositionGenerator object - /// - /// Compositor - /// Whether to use a shared CanvasDevice or to create a new one. - /// Whether to use Software Renderer when creating a new CanvasDevice. - /// ICompositionGenerator - public static ICompositionGenerator CreateCompositionGenerator(this Compositor compositor, bool useSharedCanvasDevice, bool useSoftwareRenderer) - { - return new CompositionGenerator(compositor, useSharedCanvasDevice, useSoftwareRenderer); - } - /// /// This extension method creates a scoped batch and handles the completed event /// the subscribing and unsubscribing process internally. @@ -404,7 +382,7 @@ public static CubicBezierEasingFunction CreateEaseInOutSineEasingFunction(this C /// Creates the CompositionSurfaceBrush from the specified render surface. /// /// Compositor - /// An object deriving from IMaskSurface, IGaussianMaskSurface, IGeometrySurface or IImageSurface + /// An object deriving from IGeometryMaskSurface, IGaussianMaskSurface, IGeometrySurface or IImageSurface /// CompositionSurfaceBrush public static CompositionSurfaceBrush CreateSurfaceBrush(this Compositor compositor, IRenderSurface renderSurface) { diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/GaussianMaskSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/GaussianMaskSurface.cs index 01367f95fcf..c9c3dfd193a 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/GaussianMaskSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/GaussianMaskSurface.cs @@ -5,7 +5,6 @@ using System; using System.Numerics; using Microsoft.Graphics.Canvas.Geometry; -using Microsoft.Toolkit.Diagnostics; using Windows.Foundation; using Windows.UI.Composition; @@ -57,7 +56,7 @@ internal sealed class GaussianMaskSurface : IGaussianMaskSurface /// Initializes a new instance of the class. /// Constructor /// - /// ICompositionMaskGeneratorInternal object + /// IComposiitonGeneratorInternal object /// Size of the GaussianMaskSurface /// Geometry of the GaussianMaskSurface /// The offset from the top left corner of the ICompositionSurface where @@ -65,9 +64,8 @@ internal sealed class GaussianMaskSurface : IGaussianMaskSurface /// Radius of Gaussian Blur to be applied on the GaussianMaskSurface public GaussianMaskSurface(ICompositionGeneratorInternal generator, Size size, CanvasGeometry geometry, Vector2 offset, float blurRadius) { - Guard.IsNotNull(generator, nameof(generator)); + _generator = generator ?? throw new ArgumentException("Generator cannot be null!", nameof(generator)); - _generator = generator; _surfaceLock = new object(); Geometry = geometry; Offset = offset; diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/MaskSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometryMaskSurface.cs similarity index 78% rename from Microsoft.Toolkit.Uwp.UI.Media/Surface/MaskSurface.cs rename to Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometryMaskSurface.cs index 11f5f2626c1..e2416edb904 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/MaskSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometryMaskSurface.cs @@ -2,9 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System; using System.Numerics; using Microsoft.Graphics.Canvas.Geometry; -using Microsoft.Toolkit.Diagnostics; using Windows.Foundation; using Windows.UI.Composition; @@ -13,7 +13,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Media.Surface /// /// Class for rendering custom shaped geometries onto ICompositionSurface so that they can be used as masks on Composition Visuals. /// - internal sealed class MaskSurface : IMaskSurface + internal sealed class GeometryMaskSurface : IGeometryMaskSurface { private readonly object _surfaceLock; private ICompositionGeneratorInternal _generator; @@ -35,15 +35,15 @@ internal sealed class MaskSurface : IMaskSurface public Vector2 Offset { get; private set; } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - /// ICompositionMaskGeneratorInternal object - /// Size of the MaskSurface - /// Geometry of the MaskSurface + /// IComposiitonGeneratorInternal object + /// Size of the GeometryMaskSurface + /// Geometry of the GeometryMaskSurface /// The offset from the top left corner of the ICompositionSurface where the Geometry is rendered. - public MaskSurface(ICompositionGeneratorInternal generator, Size size, CanvasGeometry geometry, Vector2 offset) + public GeometryMaskSurface(ICompositionGeneratorInternal generator, Size size, CanvasGeometry geometry, Vector2 offset) { - Guard.IsNotNull(generator, nameof(generator)); + _generator = generator ?? throw new ArgumentException("Generator cannot be null!", nameof(generator)); _generator = generator; _surfaceLock = new object(); @@ -61,7 +61,7 @@ public MaskSurface(ICompositionGeneratorInternal generator, Size size, CanvasGeo } /// - /// Redraws the MaskSurface + /// Redraws the GeometryMaskSurface /// public void Redraw() { @@ -70,7 +70,7 @@ public void Redraw() } /// - /// Redraws the MaskSurface with the new geometry. + /// Redraws the GeometryMaskSurface with the new geometry. /// /// New CanvasGeometry to be applied to the mask. public void Redraw(CanvasGeometry geometry) @@ -79,9 +79,9 @@ public void Redraw(CanvasGeometry geometry) } /// - /// Redraws the IMaskSurface with the new geometry + /// Redraws the IGeometryMaskSurface with the new geometry /// - /// New CanvasGeometry to be applied to the IMaskSurface + /// New CanvasGeometry to be applied to the IGeometryMaskSurface /// The offset from the top left corner of the ICompositionSurface where the Geometry is rendered. public void Redraw(CanvasGeometry geometry, Vector2 offset) { @@ -89,7 +89,7 @@ public void Redraw(CanvasGeometry geometry, Vector2 offset) } /// - /// Resizes the MaskSurface with the given size and redraws the MaskSurface with the new geometry and fills it either with White color + /// Resizes the GeometryMaskSurface with the given size and redraws the GeometryMaskSurface with the new geometry and fills it either with White color /// (if the MaskMode is True) or with the foreground brush (if the MaskMode is False). /// /// New size of the mask @@ -100,10 +100,10 @@ public void Redraw(Size size, CanvasGeometry geometry) } /// - /// Resizes the IMaskSurface with the given size and redraws the IMaskSurface with the new geometry and fills it with White color. + /// Resizes the IGeometryMaskSurface with the given size and redraws the IGeometryMaskSurface with the new geometry and fills it with White color. /// /// New size of the mask - /// New CanvasGeometry to be applied to the IMaskSurface + /// New CanvasGeometry to be applied to the IGeometryMaskSurface /// The offset from the top left corner of the ICompositionSurface where /// the Geometry is rendered. public void Redraw(Size size, CanvasGeometry geometry, Vector2 offset) @@ -128,7 +128,7 @@ public void Redraw(Size size, CanvasGeometry geometry, Vector2 offset) } /// - /// Resizes the MaskSurface to the new size. + /// Resizes the GeometryMaskSurface to the new size. /// /// New size of the mask public void Resize(Size size) @@ -144,7 +144,7 @@ public void Resize(Size size) } /// - /// Disposes the resources used by the MaskSurface. + /// Disposes the resources used by the GeometryMaskSurface. /// public void Dispose() { @@ -167,7 +167,7 @@ public void Dispose() /// object private void OnDeviceReplaced(object sender, object e) { - // Recreate the MaskSurface + // Recreate the GeometryMaskSurface _surface = _generator.CreateDrawingSurface(_surfaceLock, Size); // Redraw the mask surface @@ -175,7 +175,7 @@ private void OnDeviceReplaced(object sender, object e) } /// - /// Helper class to redraw the MaskSurface. + /// Helper class to redraw the GeometryMaskSurface. /// private void RedrawSurface() { diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometrySurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometrySurface.cs index 07f66e716bd..9cbfe29283e 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometrySurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometrySurface.cs @@ -2,9 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System; using Microsoft.Graphics.Canvas.Brushes; using Microsoft.Graphics.Canvas.Geometry; -using Microsoft.Toolkit.Diagnostics; using Microsoft.Toolkit.Uwp.UI.Media.Geometry; using Windows.Foundation; using Windows.UI; @@ -64,7 +64,7 @@ internal sealed class GeometrySurface : IGeometrySurface /// Initializes a new instance of the class. /// Constructor /// - /// ICompositionMaskGeneratorInternal object + /// IComposiitonGeneratorInternal object /// Size of the GeometrySurface /// Geometry of the GeometrySurface /// Stroke for the geometry @@ -73,9 +73,8 @@ internal sealed class GeometrySurface : IGeometrySurface /// not covered by the geometry public GeometrySurface(ICompositionGeneratorInternal generator, Size size, CanvasGeometry geometry, ICanvasStroke stroke, Color fillColor, Color backgroundColor) { - Guard.IsNotNull(generator, nameof(generator)); + _generator = generator ?? throw new ArgumentException("Generator cannot be null!", nameof(generator)); - _generator = generator; _surfaceLock = new object(); _geometry = geometry; _stroke = stroke; @@ -96,7 +95,7 @@ public GeometrySurface(ICompositionGeneratorInternal generator, Size size, Canva /// Initializes a new instance of the class. /// Constructor /// - /// ICompositionMaskGeneratorInternal object + /// IComposiitonGeneratorInternal object /// Size of the GeometrySurface /// Geometry of the GeometrySurface /// Stroke for the geometry @@ -105,7 +104,7 @@ public GeometrySurface(ICompositionGeneratorInternal generator, Size size, Canva /// not covered by the geometry public GeometrySurface(ICompositionGeneratorInternal generator, Size size, CanvasGeometry geometry, ICanvasStroke stroke, ICanvasBrush fill, ICanvasBrush backgroundBrush) { - Guard.IsNotNull(generator, nameof(generator)); + _generator = generator ?? throw new ArgumentException("Generator cannot be null!", nameof(generator)); _generator = generator; _surfaceLock = new object(); diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ICompositionGenerator.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ICompositionGenerator.cs index 411bd8c2ed6..0c252bcd090 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ICompositionGenerator.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ICompositionGenerator.cs @@ -17,7 +17,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Media.Surface { /// - /// Interface for the CompositionMaskGenerator + /// Interface for the ComposiitonGenerator /// public interface ICompositionGenerator : IDisposable { @@ -37,39 +37,39 @@ public interface ICompositionGenerator : IDisposable CanvasDevice Device { get; } /// - /// Creates an Empty MaskSurface having the no size and geometry. - /// NOTE: Use this API if you want to create an Empty IMaskSurface first - /// and change its geometry and/or size of the MaskSurface later. + /// Creates an Empty GeometryMaskSurface having the no size and geometry. + /// NOTE: Use this API if you want to create an Empty IGeometryMaskSurface first + /// and change its geometry and/or size of the GeometryMaskSurface later. /// - /// IMaskSurface - IMaskSurface CreateMaskSurface(); + /// IGeometryMaskSurface + IGeometryMaskSurface CreateGeometryMaskSurface(); /// - /// Creates a MaskSurface having the given size and geometry. The geometry is filled + /// Creates a GeometryMaskSurface having the given size and geometry. The geometry is filled /// with white color. The surface not covered by the geometry is transparent. /// /// Size of the mask /// Geometry of the mask - /// IMaskSurface - IMaskSurface CreateMaskSurface(Size size, CanvasGeometry geometry); + /// IGeometryMaskSurface + IGeometryMaskSurface CreateGeometryMaskSurface(Size size, CanvasGeometry geometry); /// - /// Creates a MaskSurface having the given size and geometry. The geometry is filled + /// Creates a GeometryMaskSurface having the given size and geometry. The geometry is filled /// with white color. The surface not covered by the geometry is transparent. /// /// Size of the mask /// Geometry of the mask /// The offset from the top left corner of the ICompositionSurface where /// the Geometry is rendered. - /// IMaskSurface - IMaskSurface CreateMaskSurface(Size size, CanvasGeometry geometry, Vector2 offset); + /// IGeometryMaskSurface + IGeometryMaskSurface CreateGeometryMaskSurface(Size size, CanvasGeometry geometry, Vector2 offset); /// /// Creates an Empty IGaussianMaskSurface having the no size and geometry. /// NOTE: Use this API if you want to create an Empty IGaussianMaskSurface first /// and change its geometry, size and/or blurRadius of the IGaussianMaskSurface later. /// - /// IMaskSurface + /// IGeometryMaskSurface IGaussianMaskSurface CreateGaussianMaskSurface(); /// diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ICompositionGeneratorInternal.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ICompositionGeneratorInternal.cs index da681328ccb..453fcd0ed1f 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ICompositionGeneratorInternal.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ICompositionGeneratorInternal.cs @@ -16,7 +16,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Media.Surface { /// - /// Internal interface for the CompositionMaskGenerator + /// Internal interface for the ComposiitonGenerator /// internal interface ICompositionGeneratorInternal : ICompositionGenerator { @@ -30,7 +30,7 @@ internal interface ICompositionGeneratorInternal : ICompositionGenerator CompositionDrawingSurface CreateDrawingSurface(object surfaceLock, Size size); /// - /// Resizes the MaskSurface to the given size. + /// Resizes the GeometryMaskSurface to the given size. /// /// The object to lock to prevent multiple threads /// from accessing the surface at the same time. @@ -39,13 +39,13 @@ internal interface ICompositionGeneratorInternal : ICompositionGenerator void ResizeDrawingSurface(object surfaceLock, CompositionDrawingSurface surface, Size size); /// - /// Redraws the MaskSurface with the given size and geometry. + /// Redraws the GeometryMaskSurface with the given size and geometry. /// /// The object to lock to prevent multiple threads /// from accessing the surface at the same time. /// CompositionDrawingSurface - /// Size of the MaskSurface - /// Geometry of the MaskSurface + /// Size of the GeometryMaskSurface + /// Geometry of the GeometryMaskSurface /// The offset from the top left corner of the ICompositionSurface where /// the Geometry is rendered. void RedrawMaskSurface(object surfaceLock, CompositionDrawingSurface surface, Size size, CanvasGeometry geometry, Vector2 offset); @@ -56,8 +56,8 @@ internal interface ICompositionGeneratorInternal : ICompositionGenerator /// The object to lock to prevent multiple threads /// from accessing the surface at the same time. /// CompositionDrawingSurface - /// Size of the MaskSurface - /// Geometry of the MaskSurface + /// Size of the GeometryMaskSurface + /// Geometry of the GeometryMaskSurface /// The offset from the top left corner of the ICompositionSurface where the Geometry is rendered. /// Radius of Gaussian Blur to be applied on the GaussianMaskSurface void RedrawGaussianMaskSurface(object surfaceLock, CompositionDrawingSurface surface, Size size, CanvasGeometry geometry, Vector2 offset, float blurRadius); diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/IGaussianMaskSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/IGaussianMaskSurface.cs index cb493d92cd7..25ad3ddfa54 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/IGaussianMaskSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/IGaussianMaskSurface.cs @@ -12,7 +12,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Media.Surface /// Interface for rendering custom shaped geometries onto ICompositionSurface so that they can be used as masks on Composition Visuals. /// These geometries have a Gaussian Blur applied to them. /// - public interface IGaussianMaskSurface : IMaskSurface + public interface IGaussianMaskSurface : IGeometryMaskSurface { /// /// Gets radius of Gaussian Blur to be applied on the GaussianMaskSurface. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/IMaskSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/IGeometryMaskSurface.cs similarity index 72% rename from Microsoft.Toolkit.Uwp.UI.Media/Surface/IMaskSurface.cs rename to Microsoft.Toolkit.Uwp.UI.Media/Surface/IGeometryMaskSurface.cs index b1bc9c43bab..d2b6c5d4540 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/IMaskSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/IGeometryMaskSurface.cs @@ -11,10 +11,10 @@ namespace Microsoft.Toolkit.Uwp.UI.Media.Surface /// /// Interface for rendering custom shaped geometries onto ICompositionSurface so that they can be used as masks on Composition Visuals. /// - public interface IMaskSurface : IRenderSurface + public interface IGeometryMaskSurface : IRenderSurface { /// - /// Gets the Geometry of the MaskSurface. + /// Gets the Geometry of the GeometryMaskSurface. /// CanvasGeometry Geometry { get; } @@ -24,30 +24,30 @@ public interface IMaskSurface : IRenderSurface Vector2 Offset { get; } /// - /// Redraws the MaskSurface with the new geometry + /// Redraws the GeometryMaskSurface with the new geometry /// - /// New CanvasGeometry to be applied to the IMaskSurface + /// New CanvasGeometry to be applied to the IGeometryMaskSurface void Redraw(CanvasGeometry geometry); /// - /// Resizes the MaskSurface with the given size and redraws the IMaskSurface with the new geometry and fills it with White color. + /// Resizes the GeometryMaskSurface with the given size and redraws the IGeometryMaskSurface with the new geometry and fills it with White color. /// /// New size of the mask - /// New CanvasGeometry to be applied to the IMaskSurface + /// New CanvasGeometry to be applied to the IGeometryMaskSurface void Redraw(Size size, CanvasGeometry geometry); /// - /// Redraws the IMaskSurface with the new geometry. + /// Redraws the IGeometryMaskSurface with the new geometry. /// - /// New CanvasGeometry to be applied to the IMaskSurface + /// New CanvasGeometry to be applied to the IGeometryMaskSurface /// The offset from the top left corner of the ICompositionSurface where the Geometry is rendered. void Redraw(CanvasGeometry geometry, Vector2 offset); /// - /// Resizes the IMaskSurface with the given size and redraws the IMaskSurface with the new geometry and fills it with White color. + /// Resizes the IGeometryMaskSurface with the given size and redraws the IGeometryMaskSurface with the new geometry and fills it with White color. /// /// New size of the mask - /// New CanvasGeometry to be applied to the IMaskSurface + /// New CanvasGeometry to be applied to the IGeometryMaskSurface /// The offset from the top left corner of the ICompositionSurface where the Geometry is rendered. void Redraw(Size size, CanvasGeometry geometry, Vector2 offset); } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageMaskSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageMaskSurface.cs index f8cae205266..d71adfc3420 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageMaskSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageMaskSurface.cs @@ -5,7 +5,6 @@ using System; using System.Threading.Tasks; using Microsoft.Graphics.Canvas; -using Microsoft.Toolkit.Diagnostics; using Microsoft.Toolkit.Uwp.UI.Media.Geometry; using Windows.Foundation; using Windows.UI.Composition; @@ -84,7 +83,7 @@ internal sealed class ImageMaskSurface : IImageMaskSurface /// Initializes a new instance of the class. /// Constructor /// - /// ICompositionMaskGeneratorInternal object + /// IComposiitonGeneratorInternal object /// Uri of the image to be loaded onto the IImageMaskSurface. /// Size of the IImageMaskSurface /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where @@ -92,7 +91,7 @@ internal sealed class ImageMaskSurface : IImageMaskSurface /// The image's resize, alignment options and blur radius in the allocated space. public ImageMaskSurface(ICompositionGeneratorInternal generator, Uri uri, Size size, Thickness padding, ImageSurfaceOptions options) { - Guard.IsNotNull(generator, nameof(generator)); + _generator = generator ?? throw new ArgumentException("Generator cannot be null!", nameof(generator)); _generator = generator; _surfaceLock = new object(); @@ -117,7 +116,7 @@ public ImageMaskSurface(ICompositionGeneratorInternal generator, Uri uri, Size s /// Initializes a new instance of the class. /// Constructor /// - /// ICompositionMaskGeneratorInternal object + /// IComposiitonGeneratorInternal object /// The CanvasBitmap whose alpha values will be used to create the Mask. /// Size of the IImageMaskSurface /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where @@ -125,7 +124,7 @@ public ImageMaskSurface(ICompositionGeneratorInternal generator, Uri uri, Size s /// The image's resize, alignment options and blur radius in the allocated space. public ImageMaskSurface(ICompositionGeneratorInternal generator, CanvasBitmap surfaceBitmap, Size size, Thickness padding, ImageSurfaceOptions options) { - Guard.IsNotNull(generator, nameof(generator)); + _generator = generator ?? throw new ArgumentException("Generator cannot be null!", nameof(generator)); _generator = generator; _surfaceLock = new object(); diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurface.cs index 028430fbfdb..f701a71d145 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurface.cs @@ -5,7 +5,6 @@ using System; using System.Threading.Tasks; using Microsoft.Graphics.Canvas; -using Microsoft.Toolkit.Diagnostics; using Microsoft.Toolkit.Uwp.UI.Media.Geometry; using Windows.Foundation; using Windows.UI.Composition; @@ -79,13 +78,13 @@ internal sealed class ImageSurface : IImageSurface /// Initializes a new instance of the class. /// Constructor /// - /// ICompositionMaskGeneratorInternal object + /// IComposiitonGeneratorInternal object /// Uri of the image to be loaded onto the IImageSurface. /// Size of the IImageSurface /// The image's resize and alignment options in the allocated space. public ImageSurface(ICompositionGeneratorInternal generator, Uri uri, Size size, ImageSurfaceOptions options) { - Guard.IsNotNull(generator, nameof(generator)); + _generator = generator ?? throw new ArgumentException("Generator cannot be null!", nameof(generator)); _generator = generator; _surfaceLock = new object(); @@ -109,13 +108,13 @@ public ImageSurface(ICompositionGeneratorInternal generator, Uri uri, Size size, /// Initializes a new instance of the class. /// Constructor /// - /// ICompositionMaskGeneratorInternal object + /// IComposiitonGeneratorInternal object /// CanvasBitmap which will be rendered on the IImageSurface. /// Size of the IImageSurface /// The image's resize and alignment options in the allocated space. internal ImageSurface(ICompositionGeneratorInternal generator, CanvasBitmap surfaceBitmap, Size size, ImageSurfaceOptions options) { - Guard.IsNotNull(generator, nameof(generator)); + _generator = generator ?? throw new ArgumentException("Generator cannot be null!", nameof(generator)); _generator = generator; _surfaceLock = new object(); diff --git a/Microsoft.Toolkit.Uwp.UI/Converters/Vector2Converter.cs b/Microsoft.Toolkit.Uwp.UI/Converters/Vector2Converter.cs new file mode 100644 index 00000000000..9b79f49f196 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI/Converters/Vector2Converter.cs @@ -0,0 +1,77 @@ +using System; +using System.ComponentModel; +using System.Globalization; +using System.Linq; +using System.Numerics; + +namespace Microsoft.Toolkit.Uwp.UI.Converters +{ + /// + /// Converter for converting string to + /// + public class Vector2Converter : TypeConverter + { + private const int MaxCount = 2; + + /// + public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) + { + return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType); + } + + /// + public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) + { + return destinationType == typeof(string) || base.CanConvertTo(context, destinationType); + } + + /// + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + if (value == null) + { + throw GetConvertFromException(value); + } + + if (value is string valStr) + { + var tokens = valStr.Split(',', StringSplitOptions.RemoveEmptyEntries); + if (tokens?.Count() == MaxCount) + { + var result = new float[MaxCount]; + bool isValid = true; + for (int i = 0; i < MaxCount; i++) + { + if (!float.TryParse(tokens[i], out result[i])) + { + isValid = false; + break; + } + } + + if (isValid) + { + return new Vector2(result[0], result[1]); + } + } + } + + return base.ConvertFrom(context, culture, value); + } + + /// + public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (destinationType != null && value is Vector2 instance) + { + if (destinationType == typeof(string)) + { + return $"{instance.X}, {instance.Y}"; + } + } + + // Pass unhandled cases to base class (which will throw exceptions for null value or destinationType.) + return base.ConvertTo(context, culture, value, destinationType); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI/Converters/Vector4Converter.cs b/Microsoft.Toolkit.Uwp.UI/Converters/Vector4Converter.cs new file mode 100644 index 00000000000..48843a693b6 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI/Converters/Vector4Converter.cs @@ -0,0 +1,77 @@ +using System; +using System.ComponentModel; +using System.Globalization; +using System.Linq; +using System.Numerics; + +namespace Microsoft.Toolkit.Uwp.UI.Converters +{ + /// + /// Converter for converting string to + /// + public class Vector4Converter : TypeConverter + { + private const int MaxCount = 4; + + /// + public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) + { + return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType); + } + + /// + public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) + { + return destinationType == typeof(string) || base.CanConvertTo(context, destinationType); + } + + /// + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + if (value == null) + { + throw GetConvertFromException(value); + } + + if (value is string valStr) + { + var tokens = valStr.Split(',', StringSplitOptions.RemoveEmptyEntries); + if (tokens?.Count() == MaxCount) + { + var result = new float[MaxCount]; + bool isValid = true; + for (int i = 0; i < MaxCount; i++) + { + if (!float.TryParse(tokens[i], out result[i])) + { + isValid = false; + break; + } + } + + if (isValid) + { + return new Vector4(result[0], result[1], result[2], result[3]); + } + } + } + + return base.ConvertFrom(context, culture, value); + } + + /// + public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (destinationType != null && value is Vector4 instance) + { + if (destinationType == typeof(string)) + { + return $"{instance.X}, {instance.Y}, {instance.Z}, {instance.W}"; + } + } + + // Pass unhandled cases to base class (which will throw exceptions for null value or destinationType.) + return base.ConvertTo(context, culture, value, destinationType); + } + } +} From eb82549c96dc8544ab6f4a4c27266165b995f556 Mon Sep 17 00:00:00 2001 From: Ratish Philip Date: Fri, 26 Feb 2021 06:00:32 -0800 Subject: [PATCH 05/21] updated geometries, compositionGenerator --- .../Brushes/Base/RenderSurfaceBrushBase.cs | 9 +- .../Brushes/GeometryMaskSurfaceBrush.cs | 15 ++ .../Geometry/CanvasCircleGeometry.cs | 100 ++++++++++ .../Geometry/CanvasCombinedGeometry.cs | 180 ++++++++++++++++++ .../Geometry/CanvasCoreGeometry.cs | 9 + .../Geometry/CanvasEllipseGeometry.cs | 8 +- .../Geometry/CanvasSquircleGeometry.cs | 4 +- .../Geometry/Utils.cs | 35 ++++ .../Surface/CompositionGenerator.cs | 2 +- .../Surface/GeometryMaskSurface.cs | 2 +- .../Surface/ICompositionGeneratorInternal.cs | 2 +- 11 files changed, 350 insertions(+), 16 deletions(-) create mode 100644 Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCircleGeometry.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCombinedGeometry.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderSurfaceBrushBase.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderSurfaceBrushBase.cs index 6e7ffca7551..941c1dc457b 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderSurfaceBrushBase.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderSurfaceBrushBase.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Microsoft.Toolkit.Uwp.UI.Media.Extensions; +using Microsoft.Toolkit.Uwp.UI.Media.Extensions; using Microsoft.Toolkit.Uwp.UI.Media.Surface; using Windows.UI.Xaml; using Windows.UI.Xaml.Media; @@ -125,7 +120,7 @@ protected override async void OnDisconnected() if (Generator != null) { Generator.DeviceReplaced -= OnDeviceReplaced; - Generator.Dispose(); + Generator = null; } // Dispose of composition resources when no longer in use. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs new file mode 100644 index 00000000000..a759719b52c --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Microsoft.Toolkit.Uwp.UI.Media.Brushes +{ + /// + /// Represents a brush + /// + public sealed class GeometryMaskSurfaceBrush : RenderSurfaceBrushBase + { + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCircleGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCircleGeometry.cs new file mode 100644 index 00000000000..10e75017aff --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCircleGeometry.cs @@ -0,0 +1,100 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.ComponentModel; +using System.Numerics; +using Microsoft.Graphics.Canvas.Geometry; +using Microsoft.Toolkit.Uwp.UI.Converters; +using Microsoft.Toolkit.Uwp.UI.Media.Surface; +using Windows.UI.Xaml; + +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry +{ + /// + /// Represents a circle geometry object with the specified extents. + /// + public class CanvasCircleGeometry : CanvasCoreGeometry + { + /// + /// Center Dependency Property + /// + public static readonly DependencyProperty CenterProperty = DependencyProperty.Register( + "Center", + typeof(Vector2), + typeof(CanvasCircleGeometry), + new PropertyMetadata(Vector2.Zero, OnCenterChanged)); + + /// + /// Gets or sets the structure that describes the position and size of the . The default is . + /// + [TypeConverter(typeof(Vector2Converter))] + public Vector2 Center + { + get => (Vector2)GetValue(CenterProperty); + set => SetValue(CenterProperty, value); + } + + /// + /// Handles changes to the Center property. + /// + /// CanvasCircleGeometry + /// DependencyProperty changed event arguments + private static void OnCenterChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var ellipseGeometry = (CanvasCircleGeometry)d; + ellipseGeometry.OnCenterChanged(); + } + + /// + /// Instance handler for the changes to the Center dependency property. + /// + private void OnCenterChanged() + { + UpdateGeometry(); + } + + /// + /// Radius Dependency Property + /// + public static readonly DependencyProperty RadiusProperty = DependencyProperty.Register( + "Radius", + typeof(float), + typeof(CanvasCircleGeometry), + new PropertyMetadata(0f, OnRadiusChanged)); + + /// + /// Gets or sets the radius value of the . + /// + public float Radius + { + get => (float)GetValue(RadiusProperty); + set => SetValue(RadiusProperty, value); + } + + /// + /// Handles changes to the Radius property. + /// + /// + /// DependencyProperty changed event arguments + private static void OnRadiusChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var roundedRectangleGeometry = (CanvasCircleGeometry)d; + roundedRectangleGeometry.OnRadiusChanged(); + } + + /// + /// Instance handler for the changes to the Radius dependency property. + /// + private void OnRadiusChanged() + { + UpdateGeometry(); + } + + /// + protected override void UpdateGeometry() + { + Geometry = CanvasGeometry.CreateCircle(CompositionGenerator.Instance.Device, Center, Radius); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCombinedGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCombinedGeometry.cs new file mode 100644 index 00000000000..173d8bfc2de --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCombinedGeometry.cs @@ -0,0 +1,180 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.ComponentModel; +using System.Numerics; +using Microsoft.Graphics.Canvas.Geometry; +using Microsoft.Toolkit.Uwp.UI.Converters; +using Microsoft.Toolkit.Uwp.UI.Media.Surface; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Media; + +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry +{ + /// + /// Represents a Geometry defined by the combination of two objects. + /// + public class CanvasCombinedGeometry : CanvasCoreGeometry + { + /// + /// Geometry1 Dependency Property + /// + public static readonly DependencyProperty Geometry1Property = DependencyProperty.Register( + "Geometry1", + typeof(CanvasCoreGeometry), + typeof(CanvasCombinedGeometry), + new PropertyMetadata(null, OnGeometry1Changed)); + + /// + /// Gets or sets the first object to combine. + /// + public CanvasCoreGeometry Geometry1 + { + get => (CanvasCoreGeometry)GetValue(Geometry1Property); + set => SetValue(Geometry1Property, value); + } + + /// + /// Handles changes to the Geometry1 property. + /// + /// + /// DependencyProperty changed event arguments + private static void OnGeometry1Changed(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var combinedGeometry = (CanvasCombinedGeometry)d; + combinedGeometry.OnGeometry1Changed(); + } + + /// + /// Instance handler for the changes to the Geometry1 dependency property. + /// + private void OnGeometry1Changed() + { + UpdateGeometry(); + } + + /// + /// Geometry2 Dependency Property + /// + public static readonly DependencyProperty Geometry2Property = DependencyProperty.Register( + "Geometry2", + typeof(CanvasCoreGeometry), + typeof(CanvasCombinedGeometry), + new PropertyMetadata(null, OnGeometry2Changed)); + + /// + /// Gets or sets the second to combine. + /// + public CanvasCoreGeometry Geometry2 + { + get => (CanvasCoreGeometry)GetValue(Geometry2Property); + set => SetValue(Geometry2Property, value); + } + + /// + /// Handles changes to the Geometry2 property. + /// + /// + /// DependencyProperty changed event arguments + private static void OnGeometry2Changed(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var combinedGeometry = (CanvasCombinedGeometry)d; + combinedGeometry.OnGeometry2Changed(); + } + + /// + /// Instance handler for the changes to the Geometry2 dependency property. + /// + private void OnGeometry2Changed() + { + UpdateGeometry(); + } + + /// + /// Transform Dependency Property + /// + public static readonly DependencyProperty TransformProperty = DependencyProperty.Register( + "Transform", + typeof(MatrixTransform), + typeof(CanvasCombinedGeometry), + new PropertyMetadata(Matrix3x2.Identity.ToMatrixTransform(), OnTransformChanged)); + + /// + /// Gets or sets the MatrixTransform to be applied to Geometry2 before combining with Geometry1. + /// + public MatrixTransform Transform + { + get => (MatrixTransform)GetValue(TransformProperty); + set => SetValue(TransformProperty, value); + } + + /// + /// Handles changes to the Transform property. + /// + /// + /// DependencyProperty changed event arguments + private static void OnTransformChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var combinedGeometry = (CanvasCombinedGeometry)d; + combinedGeometry.OnTransformChanged(); + } + + /// + /// Instance handler for the changes to the Transform dependency property. + /// + private void OnTransformChanged() + { + UpdateGeometry(); + } + + /// + /// GeometryCombineMode Dependency Property + /// + public static readonly DependencyProperty GeometryCombineModeProperty = DependencyProperty.Register( + "GeometryCombineMode", + typeof(CanvasGeometryCombine), + typeof(CanvasCombinedGeometry), + new PropertyMetadata(CanvasGeometryCombine.Union, OnGeometryCombineModeChanged)); + + /// + /// Gets or sets the method by which the geometries specified by and are meant to be combined. + /// + public CanvasGeometryCombine GeometryCombineMode + { + get => (CanvasGeometryCombine)GetValue(GeometryCombineModeProperty); + set => SetValue(GeometryCombineModeProperty, value); + } + + /// + /// Handles changes to the GeometryCombineMode property. + /// + /// + /// DependencyProperty changed event arguments + private static void OnGeometryCombineModeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var combinedGeometry = (CanvasCombinedGeometry)d; + combinedGeometry.OnGeometryCombineModeChanged(); + } + + /// + /// Instance handler for the changes to the GeometryCombineMode dependency property. + /// + private void OnGeometryCombineModeChanged() + { + UpdateGeometry(); + } + + /// + protected override void UpdateGeometry() + { + if (Geometry1?.Geometry == null || Geometry2?.Geometry == null) + { + Geometry = null; + return; + } + + Geometry = Geometry1.Geometry.CombineWith(Geometry2.Geometry, Transform.ToMatrix3x2(), GeometryCombineMode); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCoreGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCoreGeometry.cs index 2a1b515a170..d91da652216 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCoreGeometry.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCoreGeometry.cs @@ -5,6 +5,7 @@ using System; using System.Runtime.CompilerServices; using Microsoft.Graphics.Canvas.Geometry; +using Microsoft.Toolkit.Uwp.UI.Media.Surface; using Windows.UI.Xaml; namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry @@ -57,6 +58,14 @@ protected virtual void OnGeometryChanged() /// protected abstract void UpdateGeometry(); + /// + /// Call this method to redraw its Geometry (usually when event is raised). + /// + public void Refresh() + { + UpdateGeometry(); + } + /// /// Disposes the resources used by the CanvasCoreGeometry and its derivatives /// diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasEllipseGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasEllipseGeometry.cs index 144babced25..db5725135ba 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasEllipseGeometry.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasEllipseGeometry.cs @@ -12,7 +12,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// - /// Represents a rounded rectangle geometry object with the specified extents. + /// Represents an Ellipse geometry object with the specified extents. /// public class CanvasEllipseGeometry : CanvasCoreGeometry { @@ -38,7 +38,7 @@ public Vector2 Center /// /// Handles changes to the Center property. /// - /// CanvasEllipseGeometry + /// /// DependencyProperty changed event arguments private static void OnCenterChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { @@ -75,7 +75,7 @@ public float RadiusX /// /// Handles changes to the RadiusX property. /// - /// CanvasEllipseGeometry + /// /// DependencyProperty changed event arguments private static void OnRadiusXChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { @@ -112,7 +112,7 @@ public float RadiusY /// /// Handles changes to the RadiusY property. /// - /// CanvasEllipseGeometry + /// /// DependencyProperty changed event arguments private static void OnRadiusYChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasSquircleGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasSquircleGeometry.cs index 9cdddd1963b..9a18ccb048d 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasSquircleGeometry.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasSquircleGeometry.cs @@ -8,7 +8,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// - /// Represents a rounded rectangle geometry object with the specified extents. + /// Represents a Squircle geometry object with the specified extents. /// public class CanvasSquircleGeometry : CanvasRectangleGeometry { @@ -33,7 +33,7 @@ public float RadiusX /// /// Handles changes to the RadiusX property. /// - /// CanvasSquircleGeometry + /// /// DependencyProperty changed event arguments private static void OnRadiusXChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Utils.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Utils.cs index 9a893a799a6..df1d9dc2a50 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Utils.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Utils.cs @@ -813,5 +813,40 @@ public static Rect GetOptimumSize(double srcWidth, double srcHeight, double dest return new Rect(left, top, targetWidth, targetHeight); } + + /// + /// Converts to + /// + /// + /// + public static Matrix3x2 ToMatrix3x2(this MatrixTransform transform) + { + return new Matrix3x2( + (float)transform.Matrix.M11, + (float)transform.Matrix.M12, + (float)transform.Matrix.M21, + (float)transform.Matrix.M22, + (float)transform.Matrix.OffsetX, + (float)transform.Matrix.OffsetY); + } + + /// + /// Converts to + /// + /// + /// + public static MatrixTransform ToMatrixTransform(this Matrix3x2 matrix) + { + return new MatrixTransform() + { + Matrix = new Matrix( + matrix.M11, + matrix.M12, + matrix.M21, + matrix.M22, + matrix.M31, + matrix.M32) + }; + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs index 0f6900406ac..3d667e9e925 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs @@ -1056,7 +1056,7 @@ public void ResizeDrawingSurface(object surfaceLock, CompositionDrawingSurface s /// Geometry of the IGeometryMaskSurface /// The offset from the top left corner of the ICompositionSurface where /// the Geometry is rendered. - public void RedrawMaskSurface(object surfaceLock, CompositionDrawingSurface surface, Size size, CanvasGeometry geometry, Vector2 offset) + public void RedrawGeometryMaskSurface(object surfaceLock, CompositionDrawingSurface surface, Size size, CanvasGeometry geometry, Vector2 offset) { // If the surface is not created, create it surface ??= CreateDrawingSurface(surfaceLock, size); diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometryMaskSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometryMaskSurface.cs index e2416edb904..07893cb7469 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometryMaskSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometryMaskSurface.cs @@ -179,7 +179,7 @@ private void OnDeviceReplaced(object sender, object e) /// private void RedrawSurface() { - _generator.RedrawMaskSurface(_surfaceLock, _surface, Size, Geometry, Offset); + _generator.RedrawGeometryMaskSurface(_surfaceLock, _surface, Size, Geometry, Offset); } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ICompositionGeneratorInternal.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ICompositionGeneratorInternal.cs index 453fcd0ed1f..c41552ad8f8 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ICompositionGeneratorInternal.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ICompositionGeneratorInternal.cs @@ -48,7 +48,7 @@ internal interface ICompositionGeneratorInternal : ICompositionGenerator /// Geometry of the GeometryMaskSurface /// The offset from the top left corner of the ICompositionSurface where /// the Geometry is rendered. - void RedrawMaskSurface(object surfaceLock, CompositionDrawingSurface surface, Size size, CanvasGeometry geometry, Vector2 offset); + void RedrawGeometryMaskSurface(object surfaceLock, CompositionDrawingSurface surface, Size size, CanvasGeometry geometry, Vector2 offset); /// /// Redraws the GaussianMaskSurface with the given size and geometry. From ac5f9924fd735484756ceeeef48161f0a10aefb6 Mon Sep 17 00:00:00 2001 From: Ratish Philip Date: Tue, 2 Mar 2021 07:21:27 -0800 Subject: [PATCH 06/21] GeometryMaskSurfaceBrush initial commit. --- .../Brushes/Base/RenderSurfaceBrushBase.cs | 33 ++++++- .../Brushes/GeometryMaskSurfaceBrush.cs | 85 +++++++++++++++++++ 2 files changed, 116 insertions(+), 2 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderSurfaceBrushBase.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderSurfaceBrushBase.cs index 941c1dc457b..0de331e5a1a 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderSurfaceBrushBase.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderSurfaceBrushBase.cs @@ -1,5 +1,5 @@ -using Microsoft.Toolkit.Uwp.UI.Media.Extensions; -using Microsoft.Toolkit.Uwp.UI.Media.Surface; +using Microsoft.Toolkit.Uwp.UI.Media.Surface; +using Windows.UI.Composition; using Windows.UI.Xaml; using Windows.UI.Xaml.Media; @@ -15,6 +15,17 @@ public abstract class RenderSurfaceBrushBase : XamlCompositionBrushBase /// private readonly AsyncMutex connectedMutex = new AsyncMutex(); + /// + /// Gets the associated CompositionBrush + /// + internal CompositionBrush Brush + { + get + { + return CompositionBrush; + } + } + /// /// SurfaceWidth Dependency Property /// @@ -123,6 +134,9 @@ protected override async void OnDisconnected() Generator = null; } + // Dispose Brush resources + OnSurfaceBrushDisposed(); + // Dispose of composition resources when no longer in use. if (CompositionBrush != null) { @@ -151,5 +165,20 @@ private void OnDeviceReplaced(object sender, object e) protected virtual void OnSurfaceBrushUpdated() { } + + /// + /// Invoked whenever any brush property is updated. + /// + protected virtual void OnSurfaceBrushDisposed() + { + } + + /// + /// Redraws the brush content + /// + public void Refresh() + { + OnSurfaceBrushUpdated(); + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs index a759719b52c..4c2b21f091c 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs @@ -3,6 +3,8 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using Microsoft.Toolkit.Uwp.UI.Media.Geometry; +using Windows.UI.Xaml; namespace Microsoft.Toolkit.Uwp.UI.Media.Brushes { @@ -11,5 +13,88 @@ namespace Microsoft.Toolkit.Uwp.UI.Media.Brushes /// public sealed class GeometryMaskSurfaceBrush : RenderSurfaceBrushBase { + /// + /// Geometry Dependency Property + /// + public static readonly DependencyProperty GeometryProperty = DependencyProperty.Register( + "Geometry", + typeof(CanvasCoreGeometry), + typeof(GeometryMaskSurfaceBrush), + new PropertyMetadata(null, OnGeometryChanged)); + + /// + /// Gets or sets the that is used to create the mask. + /// + public CanvasCoreGeometry Geometry + { + get => (CanvasCoreGeometry)GetValue(GeometryProperty); + set => SetValue(GeometryProperty, value); + } + + /// + /// Handles changes to the Geometry property. + /// + /// + /// DependencyProperty changed event arguments + private static void OnGeometryChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var maskSurfaceBrush = (GeometryMaskSurfaceBrush)d; + maskSurfaceBrush.OnGeometryChanged(); + } + + /// + /// Instance handler for the changes to the Geometry dependency property. + /// + private void OnGeometryChanged() + { + } + + /// + /// Source Dependency Property + /// + public static readonly DependencyProperty SourceProperty = DependencyProperty.Register( + "Source", + typeof(RenderSurfaceBrushBase), + typeof(GeometryMaskSurfaceBrush), + new PropertyMetadata(null, OnSourceChanged)); + + /// + /// Gets or sets the on which the mask needs to be applied. + /// + public RenderSurfaceBrushBase Source + { + get => (RenderSurfaceBrushBase)GetValue(SourceProperty); + set => SetValue(SourceProperty, value); + } + + /// + /// Handles changes to the Source property. + /// + /// + /// DependencyProperty changed event arguments + private static void OnSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var maskSurfaceBrush = (GeometryMaskSurfaceBrush)d; + maskSurfaceBrush.OnSourceChanged(); + } + + /// + /// Instance handler for the changes to the Source dependency property. + /// + private void OnSourceChanged() + { + } + + /// + protected override void OnSurfaceBrushUpdated() + { + base.OnSurfaceBrushUpdated(); + + if (Source != null && Geometry != null) + { + var maskBrush = Window.Current.Compositor.CreateMaskBrush(); + maskBrush.Source = Source.Brush; + } + } } } From 8cf0cf5d75cdc7e415cd852c6ccbdf43df57191a Mon Sep 17 00:00:00 2001 From: Ratish Philip Date: Sat, 24 Apr 2021 10:48:42 -0700 Subject: [PATCH 07/21] Updated Brushes --- .../GeometryMaskSurface.png | Bin 0 -> 4651 bytes .../GeometryMaskSurfacePage.xaml | 24 +++ .../GeometryMaskSurfacePage.xaml.cs | 33 ++++ .../Brushes/Base/RenderSurfaceBrushBase.cs | 34 ++-- .../Brushes/GeometryMaskSurfaceBrush.cs | 8 + .../Brushes/ImageSurfaceBrush.cs | 150 ++++++++++++++++++ .../Geometry/CanvasCircleGeometry.cs | 20 +-- .../Surface/CompositionGenerator.cs | 2 +- 8 files changed, 252 insertions(+), 19 deletions(-) create mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurface.png create mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurfacePage.xaml create mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurfacePage.xaml.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageSurfaceBrush.cs diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurface.png b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurface.png new file mode 100644 index 0000000000000000000000000000000000000000..5c909a581e1e9abc021a85b6bb5d643b4e198d42 GIT binary patch literal 4651 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 literal 0 HcmV?d00001 diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurfacePage.xaml b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurfacePage.xaml new file mode 100644 index 00000000000..bb2236f19ba --- /dev/null +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurfacePage.xaml @@ -0,0 +1,24 @@ + + + + + + + + + + + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurfacePage.xaml.cs b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurfacePage.xaml.cs new file mode 100644 index 00000000000..04c5a3c8d39 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurfacePage.xaml.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices.WindowsRuntime; +using Windows.Foundation; +using Windows.Foundation.Collections; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Controls.Primitives; +using Windows.UI.Xaml.Data; +using Windows.UI.Xaml.Input; +using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Navigation; + +// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238 + +namespace Microsoft.Toolkit.Uwp.SampleApp.SamplePages.GeometryMaskSurfaceBrush +{ + /// + /// An empty page that can be used on its own or navigated to within a Frame. + /// + public sealed partial class GeometryMaskSurfacePage : Page + { + /// + /// Initializes a new instance of the class. + /// + public GeometryMaskSurfacePage() + { + this.InitializeComponent(); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderSurfaceBrushBase.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderSurfaceBrushBase.cs index 0de331e5a1a..e4741622290 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderSurfaceBrushBase.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderSurfaceBrushBase.cs @@ -10,6 +10,11 @@ namespace Microsoft.Toolkit.Uwp.UI.Media /// public abstract class RenderSurfaceBrushBase : XamlCompositionBrushBase { + /// + /// Gets or sets the CompositionSurface associated with the brush. + /// + protected IRenderSurface RenderSurface { get; set; } + /// /// The initialization instance. /// @@ -31,7 +36,7 @@ internal CompositionBrush Brush /// public static readonly DependencyProperty SurfaceWidthProperty = DependencyProperty.Register( "SurfaceWidth", - typeof(float), + typeof(double), typeof(RenderSurfaceBrushBase), new PropertyMetadata(0f, OnSurfaceWidthChanged)); @@ -40,25 +45,25 @@ internal CompositionBrush Brush /// public static readonly DependencyProperty SurfaceHeightProperty = DependencyProperty.Register( "SurfaceHeight", - typeof(float), + typeof(double), typeof(RenderSurfaceBrushBase), new PropertyMetadata(0f, OnSurfaceHeightChanged)); /// /// Gets or sets the width of the Brush Surface. /// - public float SurfaceWidth + public double SurfaceWidth { - get => (float)GetValue(SurfaceWidthProperty); + get => (double)GetValue(SurfaceWidthProperty); set => SetValue(SurfaceWidthProperty, value); } /// /// Gets or sets the height of the Brush Surface. /// - public float SurfaceHeight + public double SurfaceHeight { - get => (float)GetValue(SurfaceHeightProperty); + get => (double)GetValue(SurfaceHeightProperty); set => SetValue(SurfaceHeightProperty, value); } @@ -112,9 +117,7 @@ protected override async void OnConnected() { if (CompositionBrush == null) { - Generator = CompositionGenerator.Instance; - - Generator.DeviceReplaced += OnDeviceReplaced; + GetGeneratorInstance(); OnSurfaceBrushUpdated(); } @@ -123,6 +126,19 @@ protected override async void OnConnected() base.OnConnected(); } + /// + /// Gets the CompositionGenerator Instance + /// + protected void GetGeneratorInstance() + { + if (Window.Current != null) + { + Generator = CompositionGenerator.Instance; + + Generator.DeviceReplaced += OnDeviceReplaced; + } + } + /// protected override async void OnDisconnected() { diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs index 4c2b21f091c..a57d2fd23e0 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs @@ -4,6 +4,7 @@ using System.Text; using System.Threading.Tasks; using Microsoft.Toolkit.Uwp.UI.Media.Geometry; +using Windows.Foundation; using Windows.UI.Xaml; namespace Microsoft.Toolkit.Uwp.UI.Media.Brushes @@ -47,6 +48,7 @@ private static void OnGeometryChanged(DependencyObject d, DependencyPropertyChan /// private void OnGeometryChanged() { + OnSurfaceBrushUpdated(); } /// @@ -83,6 +85,7 @@ private static void OnSourceChanged(DependencyObject d, DependencyPropertyChange /// private void OnSourceChanged() { + OnSurfaceBrushUpdated(); } /// @@ -90,10 +93,15 @@ protected override void OnSurfaceBrushUpdated() { base.OnSurfaceBrushUpdated(); + CompositionBrush?.Dispose(); + if (Source != null && Geometry != null) { var maskBrush = Window.Current.Compositor.CreateMaskBrush(); maskBrush.Source = Source.Brush; + RenderSurface = Generator.CreateGeometryMaskSurface(new Size(SurfaceWidth, SurfaceHeight), Geometry.Geometry); + maskBrush.Mask = Window.Current.Compositor.CreateSurfaceBrush(RenderSurface.Surface); + CompositionBrush = maskBrush; } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageSurfaceBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageSurfaceBrush.cs new file mode 100644 index 00000000000..e80fcb8ea45 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageSurfaceBrush.cs @@ -0,0 +1,150 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Toolkit.Uwp.UI.Media.Surface; +using Windows.Foundation; +using Windows.UI; +using Windows.UI.Xaml; + +namespace Microsoft.Toolkit.Uwp.UI.Media.Brushes +{ + /// + /// Creates a Render Surface brush using an image + /// + public class ImageSurfaceBrush : RenderSurfaceBrushBase + { + private Uri _uri; + + private static bool IsHttpUri(Uri uri) + { + return uri != null && uri.IsAbsoluteUri && (uri.Scheme == "http" || uri.Scheme == "https"); + } + + /// + /// Background Dependency Property + /// + public static readonly DependencyProperty BackgroundProperty = DependencyProperty.Register( + "Background", + typeof(Color), + typeof(ImageSurfaceBrush), + new PropertyMetadata(Colors.Transparent, OnBackgroundChanged)); + + /// + /// Gets or sets the color that is rendered in the transparent areas of the Image. The default value is Colors.Transparent. + /// + public Color Background + { + get => (Color)GetValue(BackgroundProperty); + set => SetValue(BackgroundProperty, value); + } + + /// + /// Handles changes to the Background property. + /// + /// + /// DependencyProperty changed event arguments + private static void OnBackgroundChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var imageSurfaceBrush = (ImageSurfaceBrush)d; + imageSurfaceBrush.OnBackgroundChanged(); + } + + /// + /// Instance handler for the changes to the Background dependency property. + /// + private void OnBackgroundChanged() + { + OnSurfaceBrushUpdated(); + } + + /// + /// Source Dependency Property + /// + public static readonly DependencyProperty SourceProperty = DependencyProperty.Register( + "Source", + typeof(object), + typeof(ImageSurfaceBrush), + new PropertyMetadata(null, OnSourceChanged)); + + /// + /// Gets or sets the the . + /// + public object Source + { + get => (object)GetValue(SourceProperty); + set => SetValue(SourceProperty, value); + } + + /// + /// Handles changes to the Source property. + /// + /// + /// DependencyProperty changed event arguments + private static void OnSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var target = (ImageSurfaceBrush)d; + target.OnSourceChanged(); + } + + /// + /// Instance handler for the changes to the Source dependency property. + /// + private void OnSourceChanged() + { + if (Source == null) + { + return; + } + + var uri = Source as Uri; + if (uri == null) + { + var url = Source as string ?? Source.ToString(); + if (!Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out uri)) + { + _uri = null; + return; + } + } + + if (!IsHttpUri(uri) && !uri.IsAbsoluteUri) + { + _uri = new Uri("ms-appx:///" + uri.OriginalString.TrimStart('/')); + return; + } + + _uri = uri; + + OnSurfaceBrushUpdated(); + } + + /// + protected async override void OnSurfaceBrushUpdated() + { + base.OnSurfaceBrushUpdated(); + + CompositionBrush?.Dispose(); + + if (Generator == null) + { + GetGeneratorInstance(); + } + + if (_uri != null && Generator != null) + { + RenderSurface = await Generator.CreateImageSurfaceAsync(_uri, new Size(SurfaceWidth, SurfaceHeight), ImageSurfaceOptions.Default); + CompositionBrush = Window.Current.Compositor.CreateSurfaceBrush(RenderSurface.Surface); + } + } + + /// + /// Initializes a new instance of the class. + /// + public ImageSurfaceBrush() + { + + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCircleGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCircleGeometry.cs index 10e75017aff..0581c52724c 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCircleGeometry.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCircleGeometry.cs @@ -42,8 +42,8 @@ public Vector2 Center /// DependencyProperty changed event arguments private static void OnCenterChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { - var ellipseGeometry = (CanvasCircleGeometry)d; - ellipseGeometry.OnCenterChanged(); + var circleGeometry = (CanvasCircleGeometry)d; + circleGeometry.OnCenterChanged(); } /// @@ -59,16 +59,16 @@ private void OnCenterChanged() /// public static readonly DependencyProperty RadiusProperty = DependencyProperty.Register( "Radius", - typeof(float), + typeof(double), typeof(CanvasCircleGeometry), - new PropertyMetadata(0f, OnRadiusChanged)); + new PropertyMetadata(0, OnRadiusChanged)); /// /// Gets or sets the radius value of the . /// - public float Radius + public double Radius { - get => (float)GetValue(RadiusProperty); + get => (double)GetValue(RadiusProperty); set => SetValue(RadiusProperty, value); } @@ -79,8 +79,8 @@ public float Radius /// DependencyProperty changed event arguments private static void OnRadiusChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { - var roundedRectangleGeometry = (CanvasCircleGeometry)d; - roundedRectangleGeometry.OnRadiusChanged(); + var circleGeometry = (CanvasCircleGeometry)d; + circleGeometry.OnRadiusChanged(); } /// @@ -94,7 +94,9 @@ private void OnRadiusChanged() /// protected override void UpdateGeometry() { - Geometry = CanvasGeometry.CreateCircle(CompositionGenerator.Instance.Device, Center, Radius); + Geometry?.Dispose(); + + Geometry = CanvasGeometry.CreateCircle(CompositionGenerator.Instance.Device, Center, (float)Radius); } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs index 3d667e9e925..74d7fd8e229 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs @@ -58,7 +58,7 @@ public sealed class CompositionGenerator : ICompositionGeneratorInternal /// private CompositionGenerator() { - Compositor = Window.Current.Compositor; + Compositor = Window.Current?.Compositor; if (Compositor == null) { // Since the compositor is null, we cannot proceed with the initialization of the CompositionGenerator. Therefore, throw an exception so that the value of From 5b03b888235080857eb002e9384c1df0bd9d4e98 Mon Sep 17 00:00:00 2001 From: Ratish Philip Date: Sat, 5 Jun 2021 15:54:32 -0700 Subject: [PATCH 08/21] Render Surface Brushes added. --- .../Brushes/Base/RenderCanvasBrushBase.cs | 111 ++++++ .../Brushes/Base/RenderSurfaceBrushBase.cs | 85 ++-- .../Brushes/GeometryMaskSurfaceBrush.cs | 219 ++++++++--- .../Brushes/GeometrySurfaceBrush.cs | 371 +++++++++++++++++- .../Brushes/ImageMaskSurfaceBrush.cs | 254 ++++++++++++ .../Brushes/ImageSurfaceBrush.cs | 78 +++- .../Brushes/LinearGradientCanvasBrush.cs | 210 ++++++++++ .../Brushes/RadialGradientCanvasBrush.cs | 257 ++++++++++++ .../Brushes/SolidColorCanvasBrush.cs | 51 +++ .../Geometry/CanvasCircleGeometry.cs | 71 ++-- .../Geometry/CanvasCombinedGeometry.cs | 97 +++-- .../Geometry/CanvasCoreGeometry.cs | 14 +- .../CanvasDrawingSessionExtensions.cs | 4 +- .../Geometry/CanvasEllipseGeometry.cs | 91 ++--- .../Geometry/CanvasPathBuilderExtensions.cs | 4 +- .../Geometry/CanvasPathGeometry.cs | 8 +- .../Geometry/CanvasRectangleGeometry.cs | 94 +++-- .../CanvasRoundedRectangleGeometry.cs | 61 +-- .../Geometry/CanvasSquircleGeometry.cs | 61 +-- .../Geometry/CanvasStroke.cs | 4 +- .../Geometry/CompositorGeometryExtensions.cs | 4 +- .../Geometry/Core/CanvasRoundRect.cs | 4 +- .../Geometry/Core/GeometryTypeDefinitions.cs | 4 +- .../Geometry/Core/PathElementFactory.cs | 4 +- .../Geometry/Core/RegexFactory.cs | 4 +- .../Geometry/CultureShield.cs | 3 +- .../Brush/AbstractCanvasBrushElement.cs | 4 +- .../Elements/Brush/ICanvasBrushElement.cs | 4 +- .../Brush/LinearGradientBrushElement.cs | 4 +- .../Brush/LinearGradientHdrBrushElement.cs | 4 +- .../Brush/RadialGradientBrushElement.cs | 4 +- .../Brush/RadialGradientHdrBrushElement.cs | 4 +- .../Elements/Brush/SolidColorBrushElement.cs | 4 +- .../Elements/Path/AbstractPathElement.cs | 4 +- .../Geometry/Elements/Path/ArcElement.cs | 4 +- .../Elements/Path/CanvasEllipseFigure.cs | 4 +- .../Elements/Path/CanvasPathFigure.cs | 4 +- .../Elements/Path/CanvasPolygonFigure.cs | 4 +- .../Elements/Path/CanvasRectangleFigure.cs | 4 +- .../Path/CanvasRoundRectangleFigure.cs | 4 +- .../Elements/Path/ClosePathElement.cs | 4 +- .../Elements/Path/CubicBezierElement.cs | 4 +- .../Geometry/Elements/Path/FillRuleElement.cs | 4 +- .../Elements/Path/HorizontalLineElement.cs | 4 +- .../Elements/Path/ICanvasPathElement.cs | 5 +- .../Geometry/Elements/Path/LineElement.cs | 4 +- .../Geometry/Elements/Path/MoveToElement.cs | 4 +- .../Elements/Path/QuadraticBezierElement.cs | 4 +- .../Elements/Path/SmoothCubicBezierElement.cs | 4 +- .../Path/SmoothQuadraticBezierElement.cs | 4 +- .../Elements/Path/VerticalLineElement.cs | 4 +- .../Stroke/AbstractCanvasStrokeElement.cs | 4 +- .../Elements/Stroke/CanvasStrokeElement.cs | 4 +- .../Stroke/CanvasStrokeStyleElement.cs | 4 +- .../Elements/Stroke/ICanvasStrokeElement.cs | 4 +- .../Stroke/ICanvasStrokeStyleElement.cs | 4 +- .../Geometry/ICanvasPathGeometry.cs | 7 +- .../Geometry/ICanvasStroke.cs | 4 +- .../Geometry/Parsers/CanvasBrushParser.cs | 4 +- .../Geometry/Parsers/CanvasGeometryParser.cs | 6 +- .../Geometry/Parsers/CanvasStrokeParser.cs | 4 +- .../Parsers/CanvasStrokeStyleParser.cs | 4 +- .../Geometry/Parsers/ColorParser.cs | 4 +- .../Geometry/Scalar.cs | 4 +- .../Geometry/StrokeStyle.cs | 297 ++++++++++++++ .../Geometry/Utils.cs | 25 +- .../Surface/CompositionGenerator.cs | 11 +- .../Surface/ImageSurfaceOptions.cs | 180 ++++++++- .../{ => Interfaces}/ICompositionGenerator.cs | 0 .../ICompositionGeneratorInternal.cs | 0 .../{ => Interfaces}/IGaussianMaskSurface.cs | 0 .../{ => Interfaces}/IGeometryMaskSurface.cs | 0 .../{ => Interfaces}/IGeometrySurface.cs | 0 .../{ => Interfaces}/IImageMaskSurface.cs | 0 .../Surface/{ => Interfaces}/IImageSurface.cs | 0 .../{ => Interfaces}/IRenderSurface.cs | 0 76 files changed, 2343 insertions(+), 496 deletions(-) create mode 100644 Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderCanvasBrushBase.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageMaskSurfaceBrush.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Media/Brushes/LinearGradientCanvasBrush.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Media/Brushes/RadialGradientCanvasBrush.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Media/Brushes/SolidColorCanvasBrush.cs create mode 100644 Microsoft.Toolkit.Uwp.UI.Media/Geometry/StrokeStyle.cs rename Microsoft.Toolkit.Uwp.UI.Media/Surface/{ => Interfaces}/ICompositionGenerator.cs (100%) rename Microsoft.Toolkit.Uwp.UI.Media/Surface/{ => Interfaces}/ICompositionGeneratorInternal.cs (100%) rename Microsoft.Toolkit.Uwp.UI.Media/Surface/{ => Interfaces}/IGaussianMaskSurface.cs (100%) rename Microsoft.Toolkit.Uwp.UI.Media/Surface/{ => Interfaces}/IGeometryMaskSurface.cs (100%) rename Microsoft.Toolkit.Uwp.UI.Media/Surface/{ => Interfaces}/IGeometrySurface.cs (100%) rename Microsoft.Toolkit.Uwp.UI.Media/Surface/{ => Interfaces}/IImageMaskSurface.cs (100%) rename Microsoft.Toolkit.Uwp.UI.Media/Surface/{ => Interfaces}/IImageSurface.cs (100%) rename Microsoft.Toolkit.Uwp.UI.Media/Surface/{ => Interfaces}/IRenderSurface.cs (100%) diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderCanvasBrushBase.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderCanvasBrushBase.cs new file mode 100644 index 00000000000..e0133ef75ff --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderCanvasBrushBase.cs @@ -0,0 +1,111 @@ +using System; +using System.Runtime.CompilerServices; +using Microsoft.Graphics.Canvas.Brushes; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Media; + +namespace Microsoft.Toolkit.Uwp.UI.Media.Brushes +{ + public abstract class RenderCanvasBrushBase : DependencyObject, IDisposable + { + public event EventHandler Updated; + + private bool _disposedValue; + + public ICanvasBrush CanvasBrush { get; protected set; } + + /// + /// Opacity Dependency Property + /// + public static readonly DependencyProperty OpacityProperty = DependencyProperty.Register( + "Opacity", + typeof(double), + typeof(RenderCanvasBrushBase), + new PropertyMetadata(1d, OnPropertyChanged)); + + /// + /// Gets or sets the opacity of the brush. + /// + public double Opacity + { + get => (double)GetValue(OpacityProperty); + set => SetValue(OpacityProperty, value); + } + + /// + /// Transform Dependency Property + /// + public static readonly DependencyProperty TransformProperty = DependencyProperty.Register( + "Transform", + typeof(MatrixTransform), + typeof(RenderCanvasBrushBase), + new PropertyMetadata(new MatrixTransform { Matrix = Matrix.Identity }, OnPropertyChanged)); + + /// + /// Gets or sets the transform matrix applied to the brush. + /// + public MatrixTransform Transform + { + get => (MatrixTransform)GetValue(TransformProperty); + set => SetValue(TransformProperty, value); + } + + /// + /// Refreshes the CanvasBrush when any of the properties are updated + /// + protected virtual void OnUpdated() + { + RaiseUpdatedEvent(); + } + + protected void RaiseUpdatedEvent() + { + Updated?.Invoke(this, null); + } + + /// + /// Call this method to redraw its Geometry (usually when event is raised). + /// + public void Refresh() + { + OnUpdated(); + } + + /// + /// Disposes the resources used by the CanvasCoreGeometry and its derivatives + /// + /// Flag to indicate if we are disposing the managed objects. + protected virtual void Dispose(bool disposing) + { + if (!_disposedValue) + { + if (disposing) + { + } + + _disposedValue = true; + } + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Dispose() + { + Dispose(disposing: true); + GC.SuppressFinalize(this); + } + + /// + /// Method that is called whenever the dependency properties of the Brush changes + /// + /// The object whose property has changed + /// Event arguments + private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var brush = (RenderCanvasBrushBase)d; + + // Recreate the canvas brush on any property change. + brush.Refresh(); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderSurfaceBrushBase.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderSurfaceBrushBase.cs index e4741622290..a41914675ba 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderSurfaceBrushBase.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderSurfaceBrushBase.cs @@ -1,15 +1,18 @@ -using Microsoft.Toolkit.Uwp.UI.Media.Surface; +using System; +using Microsoft.Toolkit.Uwp.UI.Media.Surface; using Windows.UI.Composition; using Windows.UI.Xaml; using Windows.UI.Xaml.Media; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Brushes { /// /// Base class for RenderSurface brushes /// public abstract class RenderSurfaceBrushBase : XamlCompositionBrushBase { + public event EventHandler Updated; + /// /// Gets or sets the CompositionSurface associated with the brush. /// @@ -18,7 +21,7 @@ public abstract class RenderSurfaceBrushBase : XamlCompositionBrushBase /// /// The initialization instance. /// - private readonly AsyncMutex connectedMutex = new AsyncMutex(); + private readonly AsyncMutex connectedMutex = new(); /// /// Gets the associated CompositionBrush @@ -38,16 +41,7 @@ internal CompositionBrush Brush "SurfaceWidth", typeof(double), typeof(RenderSurfaceBrushBase), - new PropertyMetadata(0f, OnSurfaceWidthChanged)); - - /// - /// SurfaceHeight Dependency Property - /// - public static readonly DependencyProperty SurfaceHeightProperty = DependencyProperty.Register( - "SurfaceHeight", - typeof(double), - typeof(RenderSurfaceBrushBase), - new PropertyMetadata(0f, OnSurfaceHeightChanged)); + new PropertyMetadata(0d, OnPropertyChanged)); /// /// Gets or sets the width of the Brush Surface. @@ -58,6 +52,15 @@ public double SurfaceWidth set => SetValue(SurfaceWidthProperty, value); } + /// + /// SurfaceHeight Dependency Property + /// + public static readonly DependencyProperty SurfaceHeightProperty = DependencyProperty.Register( + "SurfaceHeight", + typeof(double), + typeof(RenderSurfaceBrushBase), + new PropertyMetadata(0d, OnPropertyChanged)); + /// /// Gets or sets the height of the Brush Surface. /// @@ -73,41 +76,26 @@ public double SurfaceHeight protected ICompositionGenerator Generator { get; set; } /// - /// Handles changes to the SurfaceWidth property. - /// - /// RenderSurfaceBrushBase - /// DependencyProperty changed event arguments - private static void OnSurfaceWidthChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - var target = (RenderSurfaceBrushBase)d; - target.OnSurfaceWidthChanged(); - } - - /// - /// Handles changes to the SurfaceHeight property. + /// Method that is called whenever the dependency properties of the Brush changes /// - /// RenderSurfaceBrushBase - /// DependencyProperty changed event arguments - private static void OnSurfaceHeightChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + /// The object whose property has changed + /// Event arguments + private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var brush = (RenderSurfaceBrushBase)d; - brush.OnSurfaceHeightChanged(); - } - /// - /// Instance handler for the changes to the SurfaceWidth property. - /// - private void OnSurfaceWidthChanged() - { - OnSurfaceBrushUpdated(); - } + if (brush.SurfaceWidth < 0d) + { + throw new ArgumentException("SurfaceWidth must be a positive number!"); + } - /// - /// Instance handler for the changes to the SurfaceHeight property. - /// - private void OnSurfaceHeightChanged() - { - OnSurfaceBrushUpdated(); + if (brush.SurfaceHeight < 0d) + { + throw new ArgumentException("SurfaceHeight must be a positive number!"); + } + + // Recreate the Render Surface Brush on any property change. + brush.Refresh(); } /// @@ -180,6 +168,7 @@ private void OnDeviceReplaced(object sender, object e) /// protected virtual void OnSurfaceBrushUpdated() { + Updated?.Invoke(this, null); } /// @@ -196,5 +185,15 @@ public void Refresh() { OnSurfaceBrushUpdated(); } + + /// + /// Checks if the URI starts with http: or https: + /// + /// URI. + /// True if it does, otherwise false. + protected static bool IsHttpUri(Uri uri) + { + return uri != null && uri.IsAbsoluteUri && (uri.Scheme == "http" || uri.Scheme == "https"); + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs index a57d2fd23e0..b10e816a160 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs @@ -1,10 +1,11 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System; +using System.Numerics; +using Microsoft.Toolkit.Uwp.Helpers; using Microsoft.Toolkit.Uwp.UI.Media.Geometry; +using Microsoft.Toolkit.Uwp.UI.Media.Surface; using Windows.Foundation; +using Windows.UI.Composition; +using Windows.UI.Core; using Windows.UI.Xaml; namespace Microsoft.Toolkit.Uwp.UI.Media.Brushes @@ -14,95 +15,223 @@ namespace Microsoft.Toolkit.Uwp.UI.Media.Brushes /// public sealed class GeometryMaskSurfaceBrush : RenderSurfaceBrushBase { + private CompositionMaskBrush _maskBrush; + + private WeakEventListener _maskUpdateListener; + private WeakEventListener _targetUpdateListener; + /// - /// Geometry Dependency Property + /// Target Dependency Property /// - public static readonly DependencyProperty GeometryProperty = DependencyProperty.Register( - "Geometry", - typeof(CanvasCoreGeometry), + public static readonly DependencyProperty TargetProperty = DependencyProperty.Register( + "Target", + typeof(RenderSurfaceBrushBase), typeof(GeometryMaskSurfaceBrush), - new PropertyMetadata(null, OnGeometryChanged)); + new PropertyMetadata(null, OnTargetChanged)); /// - /// Gets or sets the that is used to create the mask. + /// Gets or sets the Target Geometry on which the Mask is applied. /// - public CanvasCoreGeometry Geometry + public RenderSurfaceBrushBase Target { - get => (CanvasCoreGeometry)GetValue(GeometryProperty); - set => SetValue(GeometryProperty, value); + get => (RenderSurfaceBrushBase)GetValue(TargetProperty); + set => SetValue(TargetProperty, value); } /// - /// Handles changes to the Geometry property. + /// Handles changes to the Target property. /// /// /// DependencyProperty changed event arguments - private static void OnGeometryChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + private static void OnTargetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { - var maskSurfaceBrush = (GeometryMaskSurfaceBrush)d; - maskSurfaceBrush.OnGeometryChanged(); + var geometryMaskSurfaceBrush = (GeometryMaskSurfaceBrush)d; + geometryMaskSurfaceBrush.OnTargetChanged(); } /// - /// Instance handler for the changes to the Geometry dependency property. + /// Instance handler for the changes to the Target dependency property. /// - private void OnGeometryChanged() + private void OnTargetChanged() { - OnSurfaceBrushUpdated(); + _targetUpdateListener?.Detach(); + _targetUpdateListener = null; + + if (Target != null) + { + _targetUpdateListener = new WeakEventListener(Target) + { + OnEventAction = async (instance, source, args) => + { + await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => + { + OnSurfaceBrushUpdated(); + }); + } + }; + + Target.Updated += _targetUpdateListener.OnEvent; + + OnSurfaceBrushUpdated(); + } } /// - /// Source Dependency Property + /// Mask Dependency Property /// - public static readonly DependencyProperty SourceProperty = DependencyProperty.Register( - "Source", - typeof(RenderSurfaceBrushBase), + public static readonly DependencyProperty MaskProperty = DependencyProperty.Register( + "Mask", + typeof(CanvasCoreGeometry), typeof(GeometryMaskSurfaceBrush), - new PropertyMetadata(null, OnSourceChanged)); + new PropertyMetadata(null, OnMaskChanged)); /// - /// Gets or sets the on which the mask needs to be applied. + /// Gets or sets the Mask Geometry that is applied on the Target Geometry. /// - public RenderSurfaceBrushBase Source + public CanvasCoreGeometry Mask { - get => (RenderSurfaceBrushBase)GetValue(SourceProperty); - set => SetValue(SourceProperty, value); + get => (CanvasCoreGeometry)GetValue(MaskProperty); + set => SetValue(MaskProperty, value); } /// - /// Handles changes to the Source property. + /// Handles changes to the Mask property. /// /// /// DependencyProperty changed event arguments - private static void OnSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + private static void OnMaskChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var geometryMaskSurfaceBrush = (GeometryMaskSurfaceBrush)d; + geometryMaskSurfaceBrush.OnMaskChanged(); + } + + /// + /// Instance handler for the changes to the Mask dependency property. + /// + private void OnMaskChanged() + { + _maskUpdateListener?.Detach(); + _maskUpdateListener = null; + + if (Mask != null) + { + _maskUpdateListener = new WeakEventListener(Mask) + { + OnEventAction = async (instance, source, args) => + { + await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => + { + OnSurfaceBrushUpdated(); + }); + } + }; + + Mask.Updated += _maskUpdateListener.OnEvent; + + OnSurfaceBrushUpdated(); + } + } + + /// + /// OffsetX Dependency Property + /// + public static readonly DependencyProperty OffsetXProperty = DependencyProperty.Register( + "OffsetX", + typeof(double), + typeof(GeometryMaskSurfaceBrush), + new PropertyMetadata(0d, OnPropertyChanged)); + + /// + /// Gets or sets the offset on the x-axis from the top left corner of the Brush Surface where the Geometry is rendered. + /// + public double OffsetX + { + get => (double)GetValue(OffsetXProperty); + set => SetValue(OffsetXProperty, value); + } + + /// + /// OffsetY Dependency Property + /// + public static readonly DependencyProperty OffsetYProperty = DependencyProperty.Register( + "OffsetY", + typeof(double), + typeof(GeometryMaskSurfaceBrush), + new PropertyMetadata(0d, OnPropertyChanged)); + + /// + /// Gets or sets the offset on the y-axis from the top left corner of the Brush Surface where the Geometry is rendered. + /// + public double OffsetY + { + get => (double)GetValue(OffsetYProperty); + set => SetValue(OffsetYProperty, value); + } + + /// + /// BlurRadius Dependency Property + /// + public static readonly DependencyProperty BlurRadiusProperty = DependencyProperty.Register( + "BlurRadius", + typeof(double), + typeof(GeometryMaskSurfaceBrush), + new PropertyMetadata(0d, OnPropertyChanged)); + + /// + /// Gets or sets the radius of Gaussian Blur to be applied on the brush. + /// + public double BlurRadius { - var maskSurfaceBrush = (GeometryMaskSurfaceBrush)d; - maskSurfaceBrush.OnSourceChanged(); + get => (double)GetValue(BlurRadiusProperty); + set => SetValue(BlurRadiusProperty, value); } /// - /// Instance handler for the changes to the Source dependency property. + /// Method that is called whenever the dependency properties of the Brush changes /// - private void OnSourceChanged() + /// The object whose property has changed + /// Event arguments + private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { - OnSurfaceBrushUpdated(); + var brush = (GeometryMaskSurfaceBrush)d; + + // Recreate the canvas brush on any property change. + brush.OnSurfaceBrushUpdated(); } /// protected override void OnSurfaceBrushUpdated() { - base.OnSurfaceBrushUpdated(); - CompositionBrush?.Dispose(); - if (Source != null && Geometry != null) + if (Generator == null) + { + GetGeneratorInstance(); + } + + if (Target == null || Target.Brush == null || Mask == null || Generator == null) + { + return; + } + + var offset = new Vector2((float)OffsetX, (float)OffsetY); + + _maskBrush = Window.Current.Compositor.CreateMaskBrush(); + _maskBrush.Source = Target.Brush; + + if (RenderSurface == null) + { + RenderSurface = Generator.CreateGaussianMaskSurface(new Size(SurfaceWidth, SurfaceHeight), Mask.Geometry, offset, (float)BlurRadius); + } + else { - var maskBrush = Window.Current.Compositor.CreateMaskBrush(); - maskBrush.Source = Source.Brush; - RenderSurface = Generator.CreateGeometryMaskSurface(new Size(SurfaceWidth, SurfaceHeight), Geometry.Geometry); - maskBrush.Mask = Window.Current.Compositor.CreateSurfaceBrush(RenderSurface.Surface); - CompositionBrush = maskBrush; + ((IGaussianMaskSurface)RenderSurface).Redraw(new Size(SurfaceWidth, SurfaceHeight), Mask.Geometry, offset, (float)BlurRadius); } + + _maskBrush.Mask = Window.Current.Compositor.CreateSurfaceBrush(RenderSurface.Surface); + CompositionBrush = _maskBrush; + + base.OnSurfaceBrushUpdated(); } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometrySurfaceBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometrySurfaceBrush.cs index 1861bdac574..f3273c4bffa 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometrySurfaceBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometrySurfaceBrush.cs @@ -1,15 +1,374 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System; +using Microsoft.Graphics.Canvas.Brushes; +using Microsoft.Graphics.Canvas.Geometry; +using Microsoft.Toolkit.Uwp.Helpers; +using Microsoft.Toolkit.Uwp.UI.Media.Geometry; +using Windows.Foundation; +using Windows.UI; +using Windows.UI.Core; +using Windows.UI.Xaml; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Brushes { /// /// Brush /// public sealed class GeometrySurfaceBrush : RenderSurfaceBrushBase { + private WeakEventListener _geometryUpdateListener; + private WeakEventListener _strokeUpdateListener; + private WeakEventListener _fillBrushUpdateListener; + private WeakEventListener _bgBrushUpdateListener; + private WeakEventListener _strokeStyleUpdateListener; + + /// + /// Geometry Dependency Property + /// + public static readonly DependencyProperty GeometryProperty = DependencyProperty.Register( + "Geometry", + typeof(CanvasCoreGeometry), + typeof(GeometrySurfaceBrush), + new PropertyMetadata(null, OnGeometryChanged)); + + /// + /// Gets or sets the that is used to create the mask. + /// + public CanvasCoreGeometry Geometry + { + get => (CanvasCoreGeometry)GetValue(GeometryProperty); + set => SetValue(GeometryProperty, value); + } + + /// + /// Handles changes to the Geometry property. + /// + /// + /// DependencyProperty changed event arguments + private static void OnGeometryChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var maskSurfaceBrush = (GeometrySurfaceBrush)d; + maskSurfaceBrush.OnGeometryChanged(); + } + + /// + /// Instance handler for the changes to the Geometry dependency property. + /// + private void OnGeometryChanged() + { + _geometryUpdateListener?.Detach(); + _geometryUpdateListener = null; + + if (Geometry != null) + { + _geometryUpdateListener = new WeakEventListener(Geometry) + { + OnEventAction = async (instance, source, args) => + { + await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => + { + OnSurfaceBrushUpdated(); + }); + } + }; + + Geometry.Updated += _geometryUpdateListener.OnEvent; + + OnSurfaceBrushUpdated(); + } + } + + /// + /// Stroke Dependency Property + /// + public static readonly DependencyProperty StrokeProperty = DependencyProperty.Register( + "Stroke", + typeof(RenderCanvasBrushBase), + typeof(GeometrySurfaceBrush), + new PropertyMetadata(null, OnStrokeChanged)); + + /// + /// Gets or sets the brush for rendering the outline stroke of the geometry. + /// + public RenderCanvasBrushBase Stroke + { + get => (RenderCanvasBrushBase)GetValue(StrokeProperty); + set => SetValue(StrokeProperty, value); + } + + /// + /// Handles changes to the Stroke property. + /// + /// + /// DependencyProperty changed event arguments + private static void OnStrokeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var geometrySurfaceBrush = (GeometrySurfaceBrush)d; + geometrySurfaceBrush.OnStrokeChanged(); + } + + /// + /// Instance handler for the changes to the Stroke dependency property. + /// + private void OnStrokeChanged() + { + _strokeUpdateListener?.Detach(); + _strokeUpdateListener = null; + + if (Stroke != null) + { + _strokeUpdateListener = new WeakEventListener(Stroke) + { + OnEventAction = async (instance, source, args) => + { + await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => + { + OnSurfaceBrushUpdated(); + }); + } + }; + + Stroke.Updated += _strokeUpdateListener.OnEvent; + + OnSurfaceBrushUpdated(); + } + } + + /// + /// StrokeThickness Dependency Property + /// + public static readonly DependencyProperty StrokeThicknessProperty = DependencyProperty.Register( + "StrokeThickness", + typeof(double), + typeof(GeometrySurfaceBrush), + new PropertyMetadata(0d, OnStrokeThicknessChanged)); + + /// + /// Gets or sets the thickness of the outline of the geometry. + /// + public double StrokeThickness + { + get => (double)GetValue(StrokeThicknessProperty); + set => SetValue(StrokeThicknessProperty, value); + } + + /// + /// Handles changes to the StrokeThickness property. + /// + /// + /// DependencyProperty changed event arguments + private static void OnStrokeThicknessChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var geometrySurfaceBrush = (GeometrySurfaceBrush)d; + geometrySurfaceBrush.OnStrokeThicknessChanged(); + } + + /// + /// Instance handler for the changes to the StrokeThickness dependency property. + /// + private void OnStrokeThicknessChanged() + { + if (StrokeThickness < 0d) + { + throw new ArgumentException("StrokeThickness must be a non-negative number."); + } + + OnSurfaceBrushUpdated(); + } + + /// + /// RenderStrokeStyle Dependency Property + /// + public static readonly DependencyProperty RenderStrokeStyleProperty = DependencyProperty.Register( + "RenderStrokeStyle", + typeof(StrokeStyle), + typeof(GeometrySurfaceBrush), + new PropertyMetadata(null, OnRenderStrokeStyleChanged)); + + /// + /// Gets or sets the style of the outline for the Geometry. + /// + public StrokeStyle RenderStrokeStyle + { + get => (StrokeStyle)GetValue(RenderStrokeStyleProperty); + set => SetValue(RenderStrokeStyleProperty, value); + } + + /// + /// Handles changes to the RenderStrokeStyle property. + /// + /// + /// DependencyProperty changed event arguments + private static void OnRenderStrokeStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var geometrySurfaceBrush = (GeometrySurfaceBrush)d; + geometrySurfaceBrush.OnRenderStrokeStyleChanged(); + } + + /// + /// Instance handler for the changes to the RenderStrokeStyle dependency property. + /// + private void OnRenderStrokeStyleChanged() + { + _strokeStyleUpdateListener?.Detach(); + _strokeStyleUpdateListener = null; + + if (RenderStrokeStyle != null) + { + _strokeStyleUpdateListener = new WeakEventListener(RenderStrokeStyle) + { + OnEventAction = async (instance, source, args) => + { + await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => + { + OnSurfaceBrushUpdated(); + }); + } + }; + + RenderStrokeStyle.Updated += _strokeStyleUpdateListener.OnEvent; + + OnSurfaceBrushUpdated(); + } + } + + /// + /// FillBrush Dependency Property + /// + public static readonly DependencyProperty FillBrushProperty = DependencyProperty.Register( + "FillBrush", + typeof(RenderCanvasBrushBase), + typeof(GeometrySurfaceBrush), + new PropertyMetadata(null, OnFillBrushChanged)); + + /// + /// Gets or sets the brush which will be used to fill the geometry. + /// + public RenderCanvasBrushBase FillBrush + { + get => (RenderCanvasBrushBase)GetValue(FillBrushProperty); + set => SetValue(FillBrushProperty, value); + } + + /// + /// Handles changes to the FillBrush property. + /// + /// + /// DependencyProperty changed event arguments + private static void OnFillBrushChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var geometrySurfaceBrush = (GeometrySurfaceBrush)d; + geometrySurfaceBrush.OnFillBrushChanged(); + } + + /// + /// Instance handler for the changes to the FillBrush dependency property. + /// + private void OnFillBrushChanged() + { + _fillBrushUpdateListener?.Detach(); + _fillBrushUpdateListener = null; + + if (FillBrush != null) + { + _fillBrushUpdateListener = new WeakEventListener(FillBrush) + { + OnEventAction = async (instance, source, args) => + { + await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => + { + OnSurfaceBrushUpdated(); + }); + } + }; + + FillBrush.Updated += _fillBrushUpdateListener.OnEvent; + + OnSurfaceBrushUpdated(); + } + } + + /// + /// BackgroundBrush Dependency Property + /// + public static readonly DependencyProperty BackgroundBrushProperty = DependencyProperty.Register( + "BackgroundBrush", + typeof(RenderCanvasBrushBase), + typeof(GeometrySurfaceBrush), + new PropertyMetadata(null, OnBackgroundBrushChanged)); + + /// + /// Gets or sets the brush with which the background of the Geometry surface will be rendered. + /// + public RenderCanvasBrushBase BackgroundBrush + { + get => (RenderCanvasBrushBase)GetValue(BackgroundBrushProperty); + set => SetValue(BackgroundBrushProperty, value); + } + + /// + /// Handles changes to the BackgroundBrush property. + /// + /// + /// DependencyProperty changed event arguments + private static void OnBackgroundBrushChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var geometrySurfaceBrush = (GeometrySurfaceBrush)d; + geometrySurfaceBrush.OnBackgroundBrushChanged(); + } + + /// + /// Instance handler for the changes to the BackgroundBrush dependency property. + /// + private void OnBackgroundBrushChanged() + { + _bgBrushUpdateListener?.Detach(); + _bgBrushUpdateListener = null; + + if (BackgroundBrush != null) + { + _bgBrushUpdateListener = new WeakEventListener(BackgroundBrush) + { + OnEventAction = async (instance, source, args) => + { + await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => + { + OnSurfaceBrushUpdated(); + }); + } + }; + + BackgroundBrush.Updated += _bgBrushUpdateListener.OnEvent; + + OnSurfaceBrushUpdated(); + } + } + + /// + protected override void OnSurfaceBrushUpdated() + { + CompositionBrush?.Dispose(); + + if (Generator == null) + { + GetGeneratorInstance(); + } + + if (Geometry == null || Generator == null) + { + return; + } + + var transparentBrush = new CanvasSolidColorBrush(Generator.Device, Colors.Transparent); + var strokeBrush = (Stroke == null) ? transparentBrush : Stroke.CanvasBrush; + var fillBrush = (FillBrush == null) ? transparentBrush : FillBrush.CanvasBrush; + var bgBrush = (BackgroundBrush == null) ? transparentBrush : BackgroundBrush.CanvasBrush; + var strokeStyle = (RenderStrokeStyle == null) ? new CanvasStrokeStyle() : RenderStrokeStyle.GetCanvasStrokeStyle(); + var canvasstroke = new CanvasStroke(strokeBrush, (float)StrokeThickness, strokeStyle); + + RenderSurface = Generator.CreateGeometrySurface(new Size(SurfaceWidth, SurfaceHeight), Geometry.Geometry, canvasstroke, fillBrush, bgBrush); + CompositionBrush = Window.Current.Compositor.CreateSurfaceBrush(RenderSurface.Surface); + + base.OnSurfaceBrushUpdated(); + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageMaskSurfaceBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageMaskSurfaceBrush.cs new file mode 100644 index 00000000000..54fa28c913f --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageMaskSurfaceBrush.cs @@ -0,0 +1,254 @@ +using System; +using Microsoft.Toolkit.Uwp.Helpers; +using Microsoft.Toolkit.Uwp.UI.Media.Surface; +using Windows.Foundation; +using Windows.UI.Composition; +using Windows.UI.Core; +using Windows.UI.Xaml; + +namespace Microsoft.Toolkit.Uwp.UI.Media.Brushes +{ + public sealed class ImageMaskSurfaceBrush : RenderSurfaceBrushBase + { + private CompositionMaskBrush _maskBrush; + private Uri _uri; + + private WeakEventListener _targetUpdateListener; + private WeakEventListener _imageSurfaceOptionsUpdateListener; + + /// + /// Target Dependency Property + /// + public static readonly DependencyProperty TargetProperty = DependencyProperty.Register( + "Target", + typeof(RenderSurfaceBrushBase), + typeof(ImageMaskSurfaceBrush), + new PropertyMetadata(null, OnTargetChanged)); + + /// + /// Gets or sets the RenderSurfaceBrush upon which the mask is applied. + /// + public RenderSurfaceBrushBase Target + { + get => (RenderSurfaceBrushBase)GetValue(TargetProperty); + set => SetValue(TargetProperty, value); + } + + /// + /// Handles changes to the Target property. + /// + /// + /// DependencyProperty changed event arguments + private static void OnTargetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var imageMaskSurfaceBrush = (ImageMaskSurfaceBrush)d; + imageMaskSurfaceBrush.OnTargetChanged(); + } + + /// + /// Instance handler for the changes to the Target dependency property. + /// + private void OnTargetChanged() + { + _targetUpdateListener?.Detach(); + _targetUpdateListener = null; + + if (Target != null) + { + _targetUpdateListener = new WeakEventListener(Target) + { + OnEventAction = async (instance, source, args) => + { + await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => + { + OnSurfaceBrushUpdated(); + }); + } + }; + + Target.Updated += _targetUpdateListener.OnEvent; + + OnSurfaceBrushUpdated(); + } + } + + /// + /// Mask Dependency Property + /// + public static readonly DependencyProperty MaskProperty = DependencyProperty.Register( + "Mask", + typeof(object), + typeof(ImageMaskSurfaceBrush), + new PropertyMetadata(null, OnMaskChanged)); + + /// + /// Gets or sets the URI of the image that is used to create the mask. + /// + public object Mask + { + get => (object)GetValue(MaskProperty); + set => SetValue(MaskProperty, value); + } + + /// + /// Handles changes to the Mask property. + /// + /// + /// DependencyProperty changed event arguments + private static void OnMaskChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var imageMaskSurfaceBrush = (ImageMaskSurfaceBrush)d; + imageMaskSurfaceBrush.OnMaskChanged(); + } + + /// + /// Instance handler for the changes to the Mask dependency property. + /// + private void OnMaskChanged() + { + if (Mask == null) + { + return; + } + + var uri = Mask as Uri; + if (uri == null) + { + var url = Mask as string ?? Mask.ToString(); + if (!Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out uri)) + { + _uri = null; + return; + } + } + + if (!IsHttpUri(uri) && !uri.IsAbsoluteUri) + { + _uri = new Uri("ms-appx:///" + uri.OriginalString.TrimStart('/')); + return; + } + + _uri = uri; + + OnSurfaceBrushUpdated(); + } + + /// + /// ImageOptions Dependency Property + /// + public static readonly DependencyProperty ImageOptionsProperty = DependencyProperty.Register( + "ImageOptions", + typeof(ImageSurfaceOptions), + typeof(ImageMaskSurfaceBrush), + new PropertyMetadata(null, OnImageOptionsChanged)); + + /// + /// Gets or sets the additional options that can be used to configure the image used to create the brush. + /// + public ImageSurfaceOptions ImageOptions + { + get => (ImageSurfaceOptions)GetValue(ImageOptionsProperty); + set => SetValue(ImageOptionsProperty, value); + } + + /// + /// Handles changes to the ImageOptions property. + /// + /// + /// DependencyProperty changed event arguments + private static void OnImageOptionsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var imageMaskSurfaceBrush = (ImageMaskSurfaceBrush)d; + imageMaskSurfaceBrush.OnImageOptionsChanged(); + } + + /// + /// Instance handler for the changes to the ImageOptions dependency property. + /// + private void OnImageOptionsChanged() + { + _imageSurfaceOptionsUpdateListener?.Detach(); + _imageSurfaceOptionsUpdateListener = null; + + if (ImageOptions != null) + { + _imageSurfaceOptionsUpdateListener = new WeakEventListener(ImageOptions) + { + OnEventAction = async (instance, source, args) => + { + await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => + { + OnSurfaceBrushUpdated(); + }); + } + }; + + ImageOptions.Updated += _imageSurfaceOptionsUpdateListener.OnEvent; + + OnSurfaceBrushUpdated(); + } + } + + /// + /// Padding Dependency Property + /// + public static readonly DependencyProperty PaddingProperty = DependencyProperty.Register( + "Padding", + typeof(Thickness), + typeof(ImageMaskSurfaceBrush), + new PropertyMetadata(new Thickness(0d), OnPaddingChanged)); + + /// + /// Gets or sets the padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. + /// + public Thickness Padding + { + get => (Thickness)GetValue(PaddingProperty); + set => SetValue(PaddingProperty, value); + } + + /// + /// Handles changes to the Padding property. + /// + /// + /// DependencyProperty changed event arguments + private static void OnPaddingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var imageMaskSurfaceBrush = (ImageMaskSurfaceBrush)d; + imageMaskSurfaceBrush.OnPaddingChanged(); + } + + /// + /// Instance handler for the changes to the Padding dependency property. + /// + private void OnPaddingChanged() + { + OnSurfaceBrushUpdated(); + } + + /// + protected async override void OnSurfaceBrushUpdated() + { + CompositionBrush?.Dispose(); + + if (Generator == null) + { + GetGeneratorInstance(); + } + + if (Target == null || Target.Brush == null || _uri == null || Generator == null) + { + return; + } + + _maskBrush = Window.Current.Compositor.CreateMaskBrush(); + _maskBrush.Source = Target.Brush; + + RenderSurface = await Generator.CreateImageMaskSurfaceAsync(_uri, new Size(SurfaceWidth, SurfaceHeight), Padding, ImageOptions ?? ImageSurfaceOptions.Default); + _maskBrush.Mask = Window.Current.Compositor.CreateSurfaceBrush(RenderSurface.Surface); + CompositionBrush = _maskBrush; + + base.OnSurfaceBrushUpdated(); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageSurfaceBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageSurfaceBrush.cs index e80fcb8ea45..667ce29f7ab 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageSurfaceBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageSurfaceBrush.cs @@ -1,11 +1,9 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System; +using Microsoft.Toolkit.Uwp.Helpers; using Microsoft.Toolkit.Uwp.UI.Media.Surface; using Windows.Foundation; using Windows.UI; +using Windows.UI.Core; using Windows.UI.Xaml; namespace Microsoft.Toolkit.Uwp.UI.Media.Brushes @@ -15,12 +13,9 @@ namespace Microsoft.Toolkit.Uwp.UI.Media.Brushes /// public class ImageSurfaceBrush : RenderSurfaceBrushBase { - private Uri _uri; + private WeakEventListener _imageSurfaceOptionsUpdateListener; - private static bool IsHttpUri(Uri uri) - { - return uri != null && uri.IsAbsoluteUri && (uri.Scheme == "http" || uri.Scheme == "https"); - } + private Uri _uri; /// /// Background Dependency Property @@ -120,11 +115,65 @@ private void OnSourceChanged() OnSurfaceBrushUpdated(); } + /// + /// ImageOptions Dependency Property + /// + public static readonly DependencyProperty ImageOptionsProperty = DependencyProperty.Register( + "ImageOptions", + typeof(ImageSurfaceOptions), + typeof(ImageSurfaceBrush), + new PropertyMetadata(null, OnImageOptionsChanged)); + + /// + /// Gets or sets the additional options that can be used to configure the image used to create the brush. + /// + public ImageSurfaceOptions ImageOptions + { + get => (ImageSurfaceOptions)GetValue(ImageOptionsProperty); + set => SetValue(ImageOptionsProperty, value); + } + + /// + /// Handles changes to the ImageOptions property. + /// + /// + /// DependencyProperty changed event arguments + private static void OnImageOptionsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var imageSurfaceBrush = (ImageSurfaceBrush)d; + imageSurfaceBrush.OnImageOptionsChanged(); + } + + /// + /// Instance handler for the changes to the ImageOptions dependency property. + /// + private void OnImageOptionsChanged() + { + _imageSurfaceOptionsUpdateListener?.Detach(); + _imageSurfaceOptionsUpdateListener = null; + + if (ImageOptions != null) + { + _imageSurfaceOptionsUpdateListener = new WeakEventListener(ImageOptions) + { + OnEventAction = async (instance, source, args) => + { + await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => + { + OnSurfaceBrushUpdated(); + }); + } + }; + + ImageOptions.Updated += _imageSurfaceOptionsUpdateListener.OnEvent; + + OnSurfaceBrushUpdated(); + } + } + /// protected async override void OnSurfaceBrushUpdated() { - base.OnSurfaceBrushUpdated(); - CompositionBrush?.Dispose(); if (Generator == null) @@ -134,9 +183,11 @@ protected async override void OnSurfaceBrushUpdated() if (_uri != null && Generator != null) { - RenderSurface = await Generator.CreateImageSurfaceAsync(_uri, new Size(SurfaceWidth, SurfaceHeight), ImageSurfaceOptions.Default); + RenderSurface = await Generator.CreateImageSurfaceAsync(_uri, new Size(SurfaceWidth, SurfaceHeight), ImageOptions ?? ImageSurfaceOptions.Default); CompositionBrush = Window.Current.Compositor.CreateSurfaceBrush(RenderSurface.Surface); } + + base.OnSurfaceBrushUpdated(); } /// @@ -144,7 +195,6 @@ protected async override void OnSurfaceBrushUpdated() /// public ImageSurfaceBrush() { - } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/LinearGradientCanvasBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/LinearGradientCanvasBrush.cs new file mode 100644 index 00000000000..9568833f6dc --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/LinearGradientCanvasBrush.cs @@ -0,0 +1,210 @@ +using System.Collections.Generic; +using System.Numerics; +using Microsoft.Graphics.Canvas; +using Microsoft.Graphics.Canvas.Brushes; +using Microsoft.Toolkit.Uwp.UI.Media.Geometry; +using Microsoft.Toolkit.Uwp.UI.Media.Surface; +using Windows.Foundation; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Markup; +using Windows.UI.Xaml.Media; + +namespace Microsoft.Toolkit.Uwp.UI.Media.Brushes +{ + [ContentProperty(Name = nameof(Stops))] + public class LinearGradientCanvasBrush : RenderCanvasBrushBase + { + /// + /// AlphaMode Dependency Property + /// + public static readonly DependencyProperty AlphaModeProperty = DependencyProperty.Register( + "AlphaMode", + typeof(CanvasAlphaMode), + typeof(LinearGradientCanvasBrush), + new PropertyMetadata(CanvasAlphaMode.Premultiplied, OnPropertyChanged)); + + /// + /// Gets or sets the way in which the Alpha channel affects color channels. + /// + public CanvasAlphaMode AlphaMode + { + get => (CanvasAlphaMode)GetValue(AlphaModeProperty); + set => SetValue(AlphaModeProperty, value); + } + + /// + /// BufferPrecision Dependency Property + /// + public static readonly DependencyProperty BufferPrecisionProperty = DependencyProperty.Register( + "BufferPrecision", + typeof(CanvasBufferPrecision), + typeof(LinearGradientCanvasBrush), + new PropertyMetadata(CanvasBufferPrecision.Precision8UIntNormalized, OnPropertyChanged)); + + /// + /// Gets or sets the precision used for computation. + /// + public CanvasBufferPrecision BufferPrecision + { + get => (CanvasBufferPrecision)GetValue(BufferPrecisionProperty); + set => SetValue(BufferPrecisionProperty, value); + } + + /// + /// EdgeBehavior Dependency Property + /// + public static readonly DependencyProperty EdgeBehaviorProperty = DependencyProperty.Register( + "EdgeBehavior", + typeof(CanvasEdgeBehavior), + typeof(LinearGradientCanvasBrush), + new PropertyMetadata(CanvasEdgeBehavior.Clamp, OnPropertyChanged)); + + /// + /// Gets or sets the behavior of the pixels which fall outside of the gradient's typical rendering area. + /// + public CanvasEdgeBehavior EdgeBehavior + { + get => (CanvasEdgeBehavior)GetValue(EdgeBehaviorProperty); + set => SetValue(EdgeBehaviorProperty, value); + } + + /// + /// EndPoint Dependency Property + /// + public static readonly DependencyProperty EndPointProperty = DependencyProperty.Register( + "EndPoint", + typeof(Point), + typeof(LinearGradientCanvasBrush), + new PropertyMetadata(default(Point), OnPropertyChanged)); + + /// + /// Gets or sets the point on the Canvas where the gradient stops. + /// + public Point EndPoint + { + get => (Point)GetValue(EndPointProperty); + set => SetValue(EndPointProperty, value); + } + + /// + /// PostInterpolationSpace Dependency Property + /// + public static readonly DependencyProperty PostInterpolationSpaceProperty = DependencyProperty.Register( + "PostInterpolationSpace", + typeof(CanvasColorSpace), + typeof(LinearGradientCanvasBrush), + new PropertyMetadata(CanvasColorSpace.Srgb, OnPropertyChanged)); + + /// + /// Gets or sets the the color space to be used after interpolation. + /// + public CanvasColorSpace PostInterpolationSpace + { + get => (CanvasColorSpace)GetValue(PostInterpolationSpaceProperty); + set => SetValue(PostInterpolationSpaceProperty, value); + } + + /// + /// PreInterpolationSpace Dependency Property + /// + public static readonly DependencyProperty PreInterpolationSpaceProperty = DependencyProperty.Register( + "PreInterpolationSpace", + typeof(CanvasColorSpace), + typeof(LinearGradientCanvasBrush), + new PropertyMetadata(CanvasColorSpace.Srgb, OnPropertyChanged)); + + /// + /// Gets or sets the the color space to be used before interpolation. + /// + public CanvasColorSpace PreInterpolationSpace + { + get => (CanvasColorSpace)GetValue(PreInterpolationSpaceProperty); + set => SetValue(PreInterpolationSpaceProperty, value); + } + + /// + /// StartPoint Dependency Property + /// + public static readonly DependencyProperty StartPointProperty = DependencyProperty.Register( + "StartPoint", + typeof(Point), + typeof(LinearGradientCanvasBrush), + new PropertyMetadata(default(Point), OnPropertyChanged)); + + /// + /// Gets or sets the point on the Canvas where the gradient starts. + /// + public Point StartPoint + { + get => (Point)GetValue(StartPointProperty); + set => SetValue(StartPointProperty, value); + } + + /// + /// Stops Dependency Property + /// + public static readonly DependencyProperty StopsProperty = DependencyProperty.Register( + "Stops", + typeof(GradientStopCollection), + typeof(LinearGradientCanvasBrush), + new PropertyMetadata(null, OnPropertyChanged)); + + /// + /// Gets or sets the gradient stops that comprise the brush. + /// + public GradientStopCollection Stops + { + get => (GradientStopCollection)GetValue(StopsProperty); + set => SetValue(StopsProperty, value); + } + + /// + /// Method that is called whenever the dependency properties of the Brush changes + /// + /// The object whose property has changed + /// Event arguments + private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var brush = (LinearGradientCanvasBrush)d; + + // Recreate the canvas brush on any property change. + brush.OnUpdated(); + } + + /// + protected override void OnUpdated() + { + if (Stops == null) + { + return; + } + + var canvasGradientStops = new List(); + foreach (var stop in Stops) + { + canvasGradientStops.Add(new CanvasGradientStop() + { + Color = stop.Color, + Position = (float)stop.Offset + }); + } + + CanvasBrush = new CanvasLinearGradientBrush( + CompositionGenerator.Instance.Device, + canvasGradientStops.ToArray(), + EdgeBehavior, + AlphaMode, + PreInterpolationSpace, + PostInterpolationSpace, + BufferPrecision) + { + StartPoint = StartPoint.ToVector2(), + EndPoint = EndPoint.ToVector2(), + Opacity = (float)Opacity, + Transform = Transform.ToMatrix3x2() + }; + + base.OnUpdated(); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/RadialGradientCanvasBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/RadialGradientCanvasBrush.cs new file mode 100644 index 00000000000..c55b6ae36cd --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/RadialGradientCanvasBrush.cs @@ -0,0 +1,257 @@ +using System.Collections.Generic; +using System.Numerics; +using Microsoft.Graphics.Canvas; +using Microsoft.Graphics.Canvas.Brushes; +using Microsoft.Toolkit.Uwp.UI.Media.Geometry; +using Microsoft.Toolkit.Uwp.UI.Media.Surface; +using Windows.Foundation; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Markup; +using Windows.UI.Xaml.Media; + +namespace Microsoft.Toolkit.Uwp.UI.Media.Brushes +{ + [ContentProperty(Name = nameof(Stops))] + public class RadialGradientCanvasBrush : RenderCanvasBrushBase + { + /// + /// AlphaMode Dependency Property + /// + public static readonly DependencyProperty AlphaModeProperty = DependencyProperty.Register( + "AlphaMode", + typeof(CanvasAlphaMode), + typeof(RadialGradientCanvasBrush), + new PropertyMetadata(CanvasAlphaMode.Premultiplied, OnPropertyChanged)); + + /// + /// Gets or sets the way in which the Alpha channel affects color channels. + /// + public CanvasAlphaMode AlphaMode + { + get => (CanvasAlphaMode)GetValue(AlphaModeProperty); + set => SetValue(AlphaModeProperty, value); + } + + /// + /// BufferPrecision Dependency Property + /// + public static readonly DependencyProperty BufferPrecisionProperty = DependencyProperty.Register( + "BufferPrecision", + typeof(CanvasBufferPrecision), + typeof(RadialGradientCanvasBrush), + new PropertyMetadata(CanvasBufferPrecision.Precision8UIntNormalized, OnPropertyChanged)); + + /// + /// Gets or sets the precision used for computation. + /// + public CanvasBufferPrecision BufferPrecision + { + get => (CanvasBufferPrecision)GetValue(BufferPrecisionProperty); + set => SetValue(BufferPrecisionProperty, value); + } + + /// + /// Center Dependency Property + /// + public static readonly DependencyProperty CenterProperty = DependencyProperty.Register( + "Center", + typeof(Point), + typeof(RadialGradientCanvasBrush), + new PropertyMetadata(default(Point), OnPropertyChanged)); + + /// + /// Gets or sets the center of the brush's radial gradient. + /// + public Point Center + { + get => (Point)GetValue(CenterProperty); + set => SetValue(CenterProperty, value); + } + + /// + /// EdgeBehavior Dependency Property + /// + public static readonly DependencyProperty EdgeBehaviorProperty = DependencyProperty.Register( + "EdgeBehavior", + typeof(CanvasEdgeBehavior), + typeof(RadialGradientCanvasBrush), + new PropertyMetadata(CanvasEdgeBehavior.Clamp, OnPropertyChanged)); + + /// + /// Gets or sets the behavior of the pixels which fall outside of the gradient's typical rendering area. + /// + public CanvasEdgeBehavior EdgeBehavior + { + get => (CanvasEdgeBehavior)GetValue(EdgeBehaviorProperty); + set => SetValue(EdgeBehaviorProperty, value); + } + + /// + /// EndPoint Dependency Property + /// + public static readonly DependencyProperty EndPointProperty = DependencyProperty.Register( + "EndPoint", + typeof(Point), + typeof(RadialGradientCanvasBrush), + new PropertyMetadata(default(Point), OnPropertyChanged)); + + /// + /// OriginOffset Dependency Property + /// + public static readonly DependencyProperty OriginOffsetProperty = DependencyProperty.Register( + "OriginOffset", + typeof(Point), + typeof(RadialGradientCanvasBrush), + new PropertyMetadata(default(Point), OnPropertyChanged)); + + /// + /// Gets or sets the displacement from Center, used to form the brush's radial gradient. + /// + public Point OriginOffset + { + get => (Point)GetValue(OriginOffsetProperty); + set => SetValue(OriginOffsetProperty, value); + } + + /// + /// PostInterpolationSpace Dependency Property + /// + public static readonly DependencyProperty PostInterpolationSpaceProperty = DependencyProperty.Register( + "PostInterpolationSpace", + typeof(CanvasColorSpace), + typeof(RadialGradientCanvasBrush), + new PropertyMetadata(CanvasColorSpace.Srgb, OnPropertyChanged)); + + /// + /// Gets or sets the the color space to be used after interpolation. + /// + public CanvasColorSpace PostInterpolationSpace + { + get => (CanvasColorSpace)GetValue(PostInterpolationSpaceProperty); + set => SetValue(PostInterpolationSpaceProperty, value); + } + + /// + /// PreInterpolationSpace Dependency Property + /// + public static readonly DependencyProperty PreInterpolationSpaceProperty = DependencyProperty.Register( + "PreInterpolationSpace", + typeof(CanvasColorSpace), + typeof(RadialGradientCanvasBrush), + new PropertyMetadata(CanvasColorSpace.Srgb, OnPropertyChanged)); + + /// + /// Gets or sets the the color space to be used before interpolation. + /// + public CanvasColorSpace PreInterpolationSpace + { + get => (CanvasColorSpace)GetValue(PreInterpolationSpaceProperty); + set => SetValue(PreInterpolationSpaceProperty, value); + } + + /// + /// RadiusX Dependency Property + /// + public static readonly DependencyProperty RadiusXProperty = DependencyProperty.Register( + "RadiusX", + typeof(double), + typeof(RadialGradientCanvasBrush), + new PropertyMetadata(0d, OnPropertyChanged)); + + /// + /// Gets or sets the horizontal radius of the brush's radial gradient. + /// + public double RadiusX + { + get => (double)GetValue(RadiusXProperty); + set => SetValue(RadiusXProperty, value); + } + + /// + /// RadiusY Dependency Property + /// + public static readonly DependencyProperty RadiusYProperty = DependencyProperty.Register( + "RadiusY", + typeof(double), + typeof(RadialGradientCanvasBrush), + new PropertyMetadata(0d, OnPropertyChanged)); + + /// + /// Gets or sets the vertical radius of the brush's radial gradient. + /// + public double RadiusY + { + get => (double)GetValue(RadiusYProperty); + set => SetValue(RadiusYProperty, value); + } + + /// + /// Stops Dependency Property + /// + public static readonly DependencyProperty StopsProperty = DependencyProperty.Register( + "Stops", + typeof(GradientStopCollection), + typeof(RadialGradientCanvasBrush), + new PropertyMetadata(null, OnPropertyChanged)); + + /// + /// Gets or sets the gradient stops that comprise the brush. + /// + public GradientStopCollection Stops + { + get => (GradientStopCollection)GetValue(StopsProperty); + set => SetValue(StopsProperty, value); + } + + /// + /// Method that is called whenever the dependency properties of the Brush changes + /// + /// The object whose property has changed + /// Event arguments + private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var brush = (RadialGradientCanvasBrush)d; + + // Recreate the canvas brush on any property change. + brush.OnUpdated(); + } + + /// + protected override void OnUpdated() + { + if (Stops == null) + { + return; + } + + var canvasGradientStops = new List(); + foreach (var stop in Stops) + { + canvasGradientStops.Add(new CanvasGradientStop() + { + Color = stop.Color, + Position = (float)stop.Offset + }); + } + + CanvasBrush = new CanvasRadialGradientBrush( + CompositionGenerator.Instance.Device, + canvasGradientStops.ToArray(), + EdgeBehavior, + AlphaMode, + PreInterpolationSpace, + PostInterpolationSpace, + BufferPrecision) + { + Center = Center.ToVector2(), + RadiusX = (float)RadiusX, + RadiusY = (float)RadiusY, + OriginOffset = OriginOffset.ToVector2(), + Opacity = (float)Opacity, + Transform = Transform.ToMatrix3x2() + }; + + base.OnUpdated(); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/SolidColorCanvasBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/SolidColorCanvasBrush.cs new file mode 100644 index 00000000000..2486b7f719e --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/SolidColorCanvasBrush.cs @@ -0,0 +1,51 @@ +using Microsoft.Graphics.Canvas.Brushes; +using Microsoft.Toolkit.Uwp.UI.Media.Surface; +using Windows.UI; +using Windows.UI.Xaml; + +namespace Microsoft.Toolkit.Uwp.UI.Media.Brushes +{ + public class SolidColorCanvasBrush : RenderCanvasBrushBase + { + /// + /// Color Dependency Property + /// + public static readonly DependencyProperty ColorProperty = DependencyProperty.Register( + "Color", + typeof(Color), + typeof(SolidColorCanvasBrush), + new PropertyMetadata(Colors.Transparent, OnPropertyChanged)); + + /// + /// Gets or sets the color of the brush. + /// + public Color Color + { + get => (Color)GetValue(ColorProperty); + set => SetValue(ColorProperty, value); + } + + /// + /// Method that is called whenever the dependency properties of the Brush changes + /// + /// The object whose property has changed + /// Event arguments + private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var brush = (SolidColorCanvasBrush)d; + + // Recreate the canvas brush on any property change. + brush.OnUpdated(); + } + + protected override void OnUpdated() + { + CanvasBrush = new CanvasSolidColorBrush(CompositionGenerator.Instance.Device, Color); + base.OnUpdated(); + } + + public SolidColorCanvasBrush() + { + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCircleGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCircleGeometry.cs index 0581c52724c..a9ac97c7b92 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCircleGeometry.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCircleGeometry.cs @@ -2,10 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.ComponentModel; using System.Numerics; using Microsoft.Graphics.Canvas.Geometry; -using Microsoft.Toolkit.Uwp.UI.Converters; using Microsoft.Toolkit.Uwp.UI.Media.Surface; using Windows.UI.Xaml; @@ -17,41 +15,39 @@ namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry public class CanvasCircleGeometry : CanvasCoreGeometry { /// - /// Center Dependency Property + /// CenterX Dependency Property /// - public static readonly DependencyProperty CenterProperty = DependencyProperty.Register( - "Center", - typeof(Vector2), + public static readonly DependencyProperty CenterXProperty = DependencyProperty.Register( + "CenterX", + typeof(double), typeof(CanvasCircleGeometry), - new PropertyMetadata(Vector2.Zero, OnCenterChanged)); + new PropertyMetadata(0d, OnPropertyChanged)); /// - /// Gets or sets the structure that describes the position and size of the . The default is . + /// Gets or sets the the x coordinate of the center. /// - [TypeConverter(typeof(Vector2Converter))] - public Vector2 Center + public double CenterX { - get => (Vector2)GetValue(CenterProperty); - set => SetValue(CenterProperty, value); + get => (double)GetValue(CenterXProperty); + set => SetValue(CenterXProperty, value); } /// - /// Handles changes to the Center property. + /// CenterY Dependency Property /// - /// CanvasCircleGeometry - /// DependencyProperty changed event arguments - private static void OnCenterChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - var circleGeometry = (CanvasCircleGeometry)d; - circleGeometry.OnCenterChanged(); - } + public static readonly DependencyProperty CenterYProperty = DependencyProperty.Register( + "CenterY", + typeof(double), + typeof(CanvasCircleGeometry), + new PropertyMetadata(0d, OnPropertyChanged)); /// - /// Instance handler for the changes to the Center dependency property. + /// Gets or sets the y coordinate of the Center. /// - private void OnCenterChanged() + public double CenterY { - UpdateGeometry(); + get => (double)GetValue(CenterYProperty); + set => SetValue(CenterYProperty, value); } /// @@ -61,7 +57,7 @@ private void OnCenterChanged() "Radius", typeof(double), typeof(CanvasCircleGeometry), - new PropertyMetadata(0, OnRadiusChanged)); + new PropertyMetadata(0d, OnPropertyChanged)); /// /// Gets or sets the radius value of the . @@ -73,30 +69,27 @@ public double Radius } /// - /// Handles changes to the Radius property. + /// Method that is called whenever the dependency properties of the Brush changes /// - /// - /// DependencyProperty changed event arguments - private static void OnRadiusChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + /// The object whose property has changed + /// Event arguments + private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { - var circleGeometry = (CanvasCircleGeometry)d; - circleGeometry.OnRadiusChanged(); - } + var geometry = (CanvasCircleGeometry)d; - /// - /// Instance handler for the changes to the Radius dependency property. - /// - private void OnRadiusChanged() - { - UpdateGeometry(); + // Recreate the geometry on any property change. + geometry.OnUpdateGeometry(); } /// - protected override void UpdateGeometry() + protected override void OnUpdateGeometry() { Geometry?.Dispose(); - Geometry = CanvasGeometry.CreateCircle(CompositionGenerator.Instance.Device, Center, (float)Radius); + var center = new Vector2((float)CenterX, (float)CenterY); + Geometry = CanvasGeometry.CreateCircle(CompositionGenerator.Instance.Device, center, (float)Radius); + + base.OnUpdateGeometry(); } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCombinedGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCombinedGeometry.cs index 173d8bfc2de..0dc4de004ab 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCombinedGeometry.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCombinedGeometry.cs @@ -2,11 +2,10 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.ComponentModel; +using System; using System.Numerics; using Microsoft.Graphics.Canvas.Geometry; -using Microsoft.Toolkit.Uwp.UI.Converters; -using Microsoft.Toolkit.Uwp.UI.Media.Surface; +using Microsoft.Toolkit.Uwp.Helpers; using Windows.UI.Xaml; using Windows.UI.Xaml.Media; @@ -17,6 +16,9 @@ namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry /// public class CanvasCombinedGeometry : CanvasCoreGeometry { + private WeakEventListener _geometry1UpdateListener; + private WeakEventListener _geometry2UpdateListener; + /// /// Geometry1 Dependency Property /// @@ -51,7 +53,26 @@ private static void OnGeometry1Changed(DependencyObject d, DependencyPropertyCha /// private void OnGeometry1Changed() { - UpdateGeometry(); + _geometry1UpdateListener?.Detach(); + _geometry1UpdateListener = null; + + if (Geometry1 != null) + { + _geometry1UpdateListener = new WeakEventListener(Geometry1) + { + OnEventAction = async (instance, source, args) => + { + await Window.Current.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => + { + OnUpdateGeometry(); + }); + } + }; + + Geometry1.Updated += _geometry1UpdateListener.OnEvent; + + OnUpdateGeometry(); + } } /// @@ -88,7 +109,26 @@ private static void OnGeometry2Changed(DependencyObject d, DependencyPropertyCha /// private void OnGeometry2Changed() { - UpdateGeometry(); + _geometry2UpdateListener?.Detach(); + _geometry2UpdateListener = null; + + if (Geometry2 != null) + { + _geometry2UpdateListener = new WeakEventListener(Geometry2) + { + OnEventAction = async (instance, source, args) => + { + await Window.Current.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => + { + OnUpdateGeometry(); + }); + } + }; + + Geometry2.Updated += _geometry2UpdateListener.OnEvent; + + OnUpdateGeometry(); + } } /// @@ -98,7 +138,7 @@ private void OnGeometry2Changed() "Transform", typeof(MatrixTransform), typeof(CanvasCombinedGeometry), - new PropertyMetadata(Matrix3x2.Identity.ToMatrixTransform(), OnTransformChanged)); + new PropertyMetadata(Matrix3x2.Identity.ToMatrixTransform(), OnPropertyChanged)); /// /// Gets or sets the MatrixTransform to be applied to Geometry2 before combining with Geometry1. @@ -109,25 +149,6 @@ public MatrixTransform Transform set => SetValue(TransformProperty, value); } - /// - /// Handles changes to the Transform property. - /// - /// - /// DependencyProperty changed event arguments - private static void OnTransformChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - var combinedGeometry = (CanvasCombinedGeometry)d; - combinedGeometry.OnTransformChanged(); - } - - /// - /// Instance handler for the changes to the Transform dependency property. - /// - private void OnTransformChanged() - { - UpdateGeometry(); - } - /// /// GeometryCombineMode Dependency Property /// @@ -135,7 +156,7 @@ private void OnTransformChanged() "GeometryCombineMode", typeof(CanvasGeometryCombine), typeof(CanvasCombinedGeometry), - new PropertyMetadata(CanvasGeometryCombine.Union, OnGeometryCombineModeChanged)); + new PropertyMetadata(CanvasGeometryCombine.Union, OnPropertyChanged)); /// /// Gets or sets the method by which the geometries specified by and are meant to be combined. @@ -147,26 +168,20 @@ public CanvasGeometryCombine GeometryCombineMode } /// - /// Handles changes to the GeometryCombineMode property. + /// Method that is called whenever the dependency properties of the Brush changes /// - /// - /// DependencyProperty changed event arguments - private static void OnGeometryCombineModeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + /// The object whose property has changed + /// Event arguments + private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { - var combinedGeometry = (CanvasCombinedGeometry)d; - combinedGeometry.OnGeometryCombineModeChanged(); - } + var geometry = (CanvasCombinedGeometry)d; - /// - /// Instance handler for the changes to the GeometryCombineMode dependency property. - /// - private void OnGeometryCombineModeChanged() - { - UpdateGeometry(); + // Recreate the geometry on any property change. + geometry.OnUpdateGeometry(); } /// - protected override void UpdateGeometry() + protected override void OnUpdateGeometry() { if (Geometry1?.Geometry == null || Geometry2?.Geometry == null) { @@ -175,6 +190,8 @@ protected override void UpdateGeometry() } Geometry = Geometry1.Geometry.CombineWith(Geometry2.Geometry, Transform.ToMatrix3x2(), GeometryCombineMode); + + RaiseUpdatedEvent(); } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCoreGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCoreGeometry.cs index d91da652216..8eb79e9a963 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCoreGeometry.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCoreGeometry.cs @@ -15,6 +15,8 @@ namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry /// public abstract class CanvasCoreGeometry : DependencyObject, ICanvasPathGeometry, IDisposable { + public event EventHandler Updated; + private bool _disposedValue; /// @@ -56,14 +58,22 @@ protected virtual void OnGeometryChanged() /// /// Method to be called when any of the parameters affecting the Geometry is updated. /// - protected abstract void UpdateGeometry(); + protected virtual void OnUpdateGeometry() + { + Updated?.Invoke(this, null); + } + + protected void RaiseUpdatedEvent() + { + Updated?.Invoke(this, null); + } /// /// Call this method to redraw its Geometry (usually when event is raised). /// public void Refresh() { - UpdateGeometry(); + OnUpdateGeometry(); } /// diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasDrawingSessionExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasDrawingSessionExtensions.cs index bd297f71f89..c1d870f08f9 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasDrawingSessionExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasDrawingSessionExtensions.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -304,4 +304,4 @@ public static void FillSquircle(this CanvasDrawingSession session, float x, floa session.FillGeometry(geometry, offset, brush); } } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasEllipseGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasEllipseGeometry.cs index db5725135ba..726b74e8ab2 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasEllipseGeometry.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasEllipseGeometry.cs @@ -2,10 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.ComponentModel; using System.Numerics; using Microsoft.Graphics.Canvas.Geometry; -using Microsoft.Toolkit.Uwp.UI.Converters; using Microsoft.Toolkit.Uwp.UI.Media.Surface; using Windows.UI.Xaml; @@ -17,41 +15,39 @@ namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry public class CanvasEllipseGeometry : CanvasCoreGeometry { /// - /// Center Dependency Property + /// CenterX Dependency Property /// - public static readonly DependencyProperty CenterProperty = DependencyProperty.Register( - "Center", - typeof(Vector2), + public static readonly DependencyProperty CenterXProperty = DependencyProperty.Register( + "CenterX", + typeof(double), typeof(CanvasEllipseGeometry), - new PropertyMetadata(Vector2.Zero, OnCenterChanged)); + new PropertyMetadata(0d, OnPropertyChanged)); /// - /// Gets or sets the structure that describes the position and size of the . The default is . + /// Gets or sets the coordinate of the center of the on the x-axis. /// - [TypeConverter(typeof(Vector2Converter))] - public Vector2 Center + public double CenterX { - get => (Vector2)GetValue(CenterProperty); - set => SetValue(CenterProperty, value); + get => (double)GetValue(CenterXProperty); + set => SetValue(CenterXProperty, value); } /// - /// Handles changes to the Center property. + /// CenterY Dependency Property /// - /// - /// DependencyProperty changed event arguments - private static void OnCenterChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - var ellipseGeometry = (CanvasEllipseGeometry)d; - ellipseGeometry.OnCenterChanged(); - } + public static readonly DependencyProperty CenterYProperty = DependencyProperty.Register( + "CenterY", + typeof(double), + typeof(CanvasEllipseGeometry), + new PropertyMetadata(0d, OnPropertyChanged)); /// - /// Instance handler for the changes to the Center dependency property. + /// Gets or sets the coordinate of the center of the on the y-axis. /// - private void OnCenterChanged() + public double CenterY { - UpdateGeometry(); + get => (double)GetValue(CenterYProperty); + set => SetValue(CenterYProperty, value); } /// @@ -61,7 +57,7 @@ private void OnCenterChanged() "RadiusX", typeof(float), typeof(CanvasEllipseGeometry), - new PropertyMetadata(0f, OnRadiusXChanged)); + new PropertyMetadata(0d, OnPropertyChanged)); /// /// Gets or sets the x-radius value of the . @@ -72,25 +68,6 @@ public float RadiusX set => SetValue(RadiusXProperty, value); } - /// - /// Handles changes to the RadiusX property. - /// - /// - /// DependencyProperty changed event arguments - private static void OnRadiusXChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - var roundedRectangleGeometry = (CanvasEllipseGeometry)d; - roundedRectangleGeometry.OnRadiusXChanged(); - } - - /// - /// Instance handler for the changes to the RadiusX dependency property. - /// - private void OnRadiusXChanged() - { - UpdateGeometry(); - } - /// /// RadiusY Dependency Property /// @@ -98,7 +75,7 @@ private void OnRadiusXChanged() "RadiusY", typeof(float), typeof(CanvasEllipseGeometry), - new PropertyMetadata(0f, OnRadiusYChanged)); + new PropertyMetadata(0d, OnPropertyChanged)); /// /// Gets or sets the y-radius value of the . @@ -110,28 +87,24 @@ public float RadiusY } /// - /// Handles changes to the RadiusY property. + /// Method that is called whenever the dependency properties of the Brush changes /// - /// - /// DependencyProperty changed event arguments - private static void OnRadiusYChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + /// The object whose property has changed + /// Event arguments + private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { - var roundedRectangleGeometry = (CanvasEllipseGeometry)d; - roundedRectangleGeometry.OnRadiusYChanged(); - } + var geometry = (CanvasEllipseGeometry)d; - /// - /// Instance handler for the changes to the RadiusY dependency property. - /// - private void OnRadiusYChanged() - { - UpdateGeometry(); + // Recreate the geometry on any property change. + geometry.OnUpdateGeometry(); } /// - protected override void UpdateGeometry() + protected override void OnUpdateGeometry() { - Geometry = CanvasGeometry.CreateEllipse(CompositionGenerator.Instance.Device, Center, RadiusX, RadiusY); + Geometry = CanvasGeometry.CreateEllipse(CompositionGenerator.Instance.Device, new Vector2((float)CenterX, (float)CenterY), RadiusX, RadiusY); + + RaiseUpdatedEvent(); } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasPathBuilderExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasPathBuilderExtensions.cs index d9878de510d..b704ce13f18 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasPathBuilderExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasPathBuilderExtensions.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -459,4 +459,4 @@ public static CanvasPathBuilder BuildPathWithLines(this CanvasPathBuilder builde return BuildPathWithLines(builder, canvasFigureLoop, vectors); } } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasPathGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasPathGeometry.cs index 82585d3be98..e20b4e0e1fb 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasPathGeometry.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasPathGeometry.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -54,7 +54,7 @@ private static void OnDataChanged(DependencyObject d, DependencyPropertyChangedE /// protected virtual void OnDataChanged() { - UpdateGeometry(); + OnUpdateGeometry(); } /// @@ -66,7 +66,7 @@ public CanvasPathGeometry() } /// - protected override void UpdateGeometry() + protected override void OnUpdateGeometry() { // Dispose previous CanvasGeometry (if any) Geometry?.Dispose(); @@ -80,6 +80,8 @@ protected override void UpdateGeometry() { Geometry = null; } + + RaiseUpdatedEvent(); } /// diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasRectangleGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasRectangleGeometry.cs index 88c6c9a9f88..90f35aa12e2 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasRectangleGeometry.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasRectangleGeometry.cs @@ -2,10 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.ComponentModel; -using System.Numerics; using Microsoft.Graphics.Canvas.Geometry; -using Microsoft.Toolkit.Uwp.UI.Converters; using Microsoft.Toolkit.Uwp.UI.Media.Surface; using Windows.UI.Xaml; @@ -17,47 +14,96 @@ namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry public class CanvasRectangleGeometry : CanvasCoreGeometry { /// - /// Rect Dependency Property + /// X Dependency Property /// - public static readonly DependencyProperty RectProperty = DependencyProperty.Register( - "Rect", - typeof(Vector4), + public static readonly DependencyProperty XProperty = DependencyProperty.Register( + "X", + typeof(double), typeof(CanvasRectangleGeometry), - new PropertyMetadata(Vector4.Zero, OnRectChanged)); + new PropertyMetadata(0d, OnPropertyChanged)); /// - /// Gets or sets the structure that describes the position and size of the geometry. The default is . + /// Gets or sets the x-coordinate of the upper-left corner of the rectangle geometry. /// - [TypeConverter(typeof(Vector4Converter))] - public Vector4 Rect + public double X { - get => (Vector4)GetValue(RectProperty); - set => SetValue(RectProperty, value); + get => (double)GetValue(XProperty); + set => SetValue(XProperty, value); } /// - /// Handles changes to the Rect property. + /// Y Dependency Property /// - /// CanvasRectangleGeometry - /// DependencyProperty changed event arguments - private static void OnRectChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + public static readonly DependencyProperty YProperty = DependencyProperty.Register( + "Y", + typeof(double), + typeof(CanvasRectangleGeometry), + new PropertyMetadata(0d, OnPropertyChanged)); + + /// + /// Gets or sets the y-coordinate of the upper-left corner of the rectangle geometry. + /// + public double Y + { + get => (double)GetValue(YProperty); + set => SetValue(YProperty, value); + } + + /// + /// Width Dependency Property + /// + public static readonly DependencyProperty WidthProperty = DependencyProperty.Register( + "Width", + typeof(double), + typeof(CanvasRectangleGeometry), + new PropertyMetadata(0d, OnPropertyChanged)); + + /// + /// Gets or sets the width of the rectangle geometry. + /// + public double Width + { + get => (double)GetValue(WidthProperty); + set => SetValue(WidthProperty, value); + } + + /// + /// Height Dependency Property + /// + public static readonly DependencyProperty HeightProperty = DependencyProperty.Register( + "Height", + typeof(double), + typeof(CanvasRectangleGeometry), + new PropertyMetadata(0d, OnPropertyChanged)); + + /// + /// Gets or sets the height of the rectangle geometry. + /// + public double Height { - var rectangleGeometry = (CanvasRectangleGeometry)d; - rectangleGeometry.OnRectChanged(); + get => (double)GetValue(HeightProperty); + set => SetValue(HeightProperty, value); } /// - /// Instance handler for the changes to the Rect dependency property. + /// Method that is called whenever the dependency properties of the Brush changes /// - private void OnRectChanged() + /// The object whose property has changed + /// Event arguments + private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { - UpdateGeometry(); + var geometry = (CanvasRectangleGeometry)d; + + // Recreate the geometry on any property change. + geometry.OnUpdateGeometry(); } /// - protected override void UpdateGeometry() + protected override void OnUpdateGeometry() { - Geometry = CanvasGeometry.CreateRectangle(CompositionGenerator.Instance.Device, Rect.X, Rect.Y, Rect.Z, Rect.W); + Geometry = CanvasGeometry.CreateRectangle(CompositionGenerator.Instance.Device, (float)X, (float)Y, (float)Width, (float)Height); + + RaiseUpdatedEvent(); } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasRoundedRectangleGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasRoundedRectangleGeometry.cs index 47ec841bec7..de8ec139c02 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasRoundedRectangleGeometry.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasRoundedRectangleGeometry.cs @@ -18,79 +18,56 @@ public class CanvasRoundedRectangleGeometry : CanvasRectangleGeometry /// public static readonly DependencyProperty RadiusXProperty = DependencyProperty.Register( "RadiusX", - typeof(float), + typeof(double), typeof(CanvasRoundedRectangleGeometry), - new PropertyMetadata(0f, OnRadiusXChanged)); + new PropertyMetadata(0d, OnPropertyChanged)); /// /// Gets or sets the radius of the corners in the x-axis. /// - public float RadiusX + public double RadiusX { - get => (float)GetValue(RadiusXProperty); + get => (double)GetValue(RadiusXProperty); set => SetValue(RadiusXProperty, value); } - /// - /// Handles changes to the RadiusX property. - /// - /// CanvasRoundedRectangleGeometry - /// DependencyProperty changed event arguments - private static void OnRadiusXChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - var roundedRectangleGeometry = (CanvasRoundedRectangleGeometry)d; - roundedRectangleGeometry.OnRadiusXChanged(); - } - - /// - /// Instance handler for the changes to the RadiusX dependency property. - /// - private void OnRadiusXChanged() - { - UpdateGeometry(); - } - /// /// RadiusY Dependency Property /// public static readonly DependencyProperty RadiusYProperty = DependencyProperty.Register( "RadiusY", - typeof(float), + typeof(double), typeof(CanvasRoundedRectangleGeometry), - new PropertyMetadata(0f, OnRadiusYChanged)); + new PropertyMetadata(0d, OnPropertyChanged)); /// /// Gets or sets the radius of the corners in the x-axis. /// - public float RadiusY + public double RadiusY { - get => (float)GetValue(RadiusYProperty); + get => (double)GetValue(RadiusYProperty); set => SetValue(RadiusYProperty, value); } /// - /// Handles changes to the RadiusY property. + /// Method that is called whenever the dependency properties of the Brush changes /// - /// CanvasRoundedRectangleGeometry - /// DependencyProperty changed event arguments - private static void OnRadiusYChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + /// The object whose property has changed + /// Event arguments + private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { - var roundedRectangleGeometry = (CanvasRoundedRectangleGeometry)d; - roundedRectangleGeometry.OnRadiusYChanged(); - } + var geometry = (CanvasRoundedRectangleGeometry)d; - /// - /// Instance handler for the changes to the RadiusY dependency property. - /// - private void OnRadiusYChanged() - { - UpdateGeometry(); + // Recreate the geometry on any property change. + geometry.OnUpdateGeometry(); } /// - protected override void UpdateGeometry() + protected override void OnUpdateGeometry() { - Geometry = CanvasGeometry.CreateRoundedRectangle(CompositionGenerator.Instance.Device, Rect.X, Rect.Y, Rect.Z, Rect.W, RadiusX, RadiusY); + Geometry = CanvasGeometry.CreateRoundedRectangle(CompositionGenerator.Instance.Device, (float)X, (float)Y, (float)Width, (float)Height, (float)RadiusX, (float)RadiusY); + + RaiseUpdatedEvent(); } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasSquircleGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasSquircleGeometry.cs index 9a18ccb048d..90b65cb6edf 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasSquircleGeometry.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasSquircleGeometry.cs @@ -17,79 +17,56 @@ public class CanvasSquircleGeometry : CanvasRectangleGeometry /// public static readonly DependencyProperty RadiusXProperty = DependencyProperty.Register( "RadiusX", - typeof(float), + typeof(double), typeof(CanvasSquircleGeometry), - new PropertyMetadata(0f, OnRadiusXChanged)); + new PropertyMetadata(0d, OnPropertyChanged)); /// /// Gets or sets the radius of the corners in the x-axis. /// - public float RadiusX + public double RadiusX { - get => (float)GetValue(RadiusXProperty); + get => (double)GetValue(RadiusXProperty); set => SetValue(RadiusXProperty, value); } - /// - /// Handles changes to the RadiusX property. - /// - /// - /// DependencyProperty changed event arguments - private static void OnRadiusXChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - var roundedRectangleGeometry = (CanvasSquircleGeometry)d; - roundedRectangleGeometry.OnRadiusXChanged(); - } - - /// - /// Instance handler for the changes to the RadiusX dependency property. - /// - private void OnRadiusXChanged() - { - UpdateGeometry(); - } - /// /// RadiusY Dependency Property /// public static readonly DependencyProperty RadiusYProperty = DependencyProperty.Register( "RadiusY", - typeof(float), + typeof(double), typeof(CanvasSquircleGeometry), - new PropertyMetadata(0f, OnRadiusYChanged)); + new PropertyMetadata(0d, OnPropertyChanged)); /// /// Gets or sets the radius of the corners in the x-axis. /// - public float RadiusY + public double RadiusY { - get => (float)GetValue(RadiusYProperty); + get => (double)GetValue(RadiusYProperty); set => SetValue(RadiusYProperty, value); } /// - /// Handles changes to the RadiusY property. + /// Method that is called whenever the dependency properties of the Brush changes /// - /// CanvasSquircleGeometry - /// DependencyProperty changed event arguments - private static void OnRadiusYChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + /// The object whose property has changed + /// Event arguments + private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { - var roundedRectangleGeometry = (CanvasSquircleGeometry)d; - roundedRectangleGeometry.OnRadiusYChanged(); - } + var geometry = (CanvasSquircleGeometry)d; - /// - /// Instance handler for the changes to the RadiusY dependency property. - /// - private void OnRadiusYChanged() - { - UpdateGeometry(); + // Recreate the geometry on any property change. + geometry.OnUpdateGeometry(); } /// - protected override void UpdateGeometry() + protected override void OnUpdateGeometry() { - Geometry = CanvasPathGeometry.CreateSquircle(CompositionGenerator.Instance.Device, Rect.X, Rect.Y, Rect.Z, Rect.W, RadiusX, RadiusY); + Geometry = CanvasPathGeometry.CreateSquircle(CompositionGenerator.Instance.Device, (float)X, (float)Y, (float)Width, (float)Height, (float)RadiusX, (float)RadiusY); + + RaiseUpdatedEvent(); } } } \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasStroke.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasStroke.cs index d571434d916..210f1dcfb7a 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasStroke.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasStroke.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -119,4 +119,4 @@ private Matrix3x2 GetTransform() return Brush?.Transform ?? Matrix3x2.Identity; } } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CompositorGeometryExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CompositorGeometryExtensions.cs index 1f6f0f8f518..1d7c863dab6 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CompositorGeometryExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CompositorGeometryExtensions.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -93,4 +93,4 @@ public static CompositionGeometricClip CreateGeometricClip(this Compositor compo return compositor.CreateGeometricClip(geometry); } } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/CanvasRoundRect.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/CanvasRoundRect.cs index 5dae1483a6f..103ec3628bb 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/CanvasRoundRect.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/CanvasRoundRect.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -277,4 +277,4 @@ private void ComputeCoordinates(float originX, float originY) TopLeftY = topLeftY + originY; } } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/GeometryTypeDefinitions.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/GeometryTypeDefinitions.cs index c50c8625f98..027000a6547 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/GeometryTypeDefinitions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/GeometryTypeDefinitions.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -56,4 +56,4 @@ internal enum GradientStopAttributeType MainHdr, AdditionalHdr } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/PathElementFactory.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/PathElementFactory.cs index 16c911f1f3a..ee77de7b668 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/PathElementFactory.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/PathElementFactory.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -154,4 +154,4 @@ private static ICanvasPathElement CreatePathElement(PathElementType elementType) }; } } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/RegexFactory.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/RegexFactory.cs index 8ee81f4bad4..79112c46df4 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/RegexFactory.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/RegexFactory.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -599,4 +599,4 @@ internal static Regex GetAttributesRegex(GradientStopAttributeType gsAttrType) return GradientStopAttributeRegexes[gsAttrType]; } } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CultureShield.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CultureShield.cs index 763e34019bf..702cd9d2c51 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CultureShield.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CultureShield.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using System.Globalization; namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry @@ -56,4 +55,4 @@ public void Dispose() CultureInfo.CurrentCulture = _prevCulture; } } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/AbstractCanvasBrushElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/AbstractCanvasBrushElement.cs index 46d1fd086d3..dd0e9c1f27f 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/AbstractCanvasBrushElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/AbstractCanvasBrushElement.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -69,4 +69,4 @@ public virtual void Initialize(Capture capture) /// Match object protected abstract void GetAttributes(Match match); } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/ICanvasBrushElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/ICanvasBrushElement.cs index 75c34abcb8f..0e6bcea4202 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/ICanvasBrushElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/ICanvasBrushElement.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -37,4 +37,4 @@ internal interface ICanvasBrushElement /// ICanvasBrush ICanvasBrush CreateBrush(ICanvasResourceCreator resourceCreator); } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/LinearGradientBrushElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/LinearGradientBrushElement.cs index b27fe460aff..412343ef16b 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/LinearGradientBrushElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/LinearGradientBrushElement.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -203,4 +203,4 @@ protected override void GetAttributes(Match match) } } } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/LinearGradientHdrBrushElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/LinearGradientHdrBrushElement.cs index 49a1eef4553..1a348439fb2 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/LinearGradientHdrBrushElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/LinearGradientHdrBrushElement.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -209,4 +209,4 @@ protected override void GetAttributes(Match match) } } } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/RadialGradientBrushElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/RadialGradientBrushElement.cs index 728d0782177..9e47a089886 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/RadialGradientBrushElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/RadialGradientBrushElement.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -227,4 +227,4 @@ protected override void GetAttributes(Match match) } } } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/RadialGradientHdrBrushElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/RadialGradientHdrBrushElement.cs index 8ee430428e6..e1143d38eaf 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/RadialGradientHdrBrushElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/RadialGradientHdrBrushElement.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -234,4 +234,4 @@ protected override void GetAttributes(Match match) } } } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/SolidColorBrushElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/SolidColorBrushElement.cs index 078b4523836..7314835f7b9 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/SolidColorBrushElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/SolidColorBrushElement.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -70,4 +70,4 @@ protected override void GetAttributes(Match match) } } } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/AbstractPathElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/AbstractPathElement.cs index 0a1f9bb6de6..f6fb00c4f00 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/AbstractPathElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/AbstractPathElement.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -104,4 +104,4 @@ public virtual void InitializeAdditional(Capture capture, int index, bool isRela /// Match object protected abstract void GetAttributes(Match match); } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/ArcElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/ArcElement.cs index 984aa224591..9026d44f924 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/ArcElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/ArcElement.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -98,4 +98,4 @@ protected override void GetAttributes(Match match) float.TryParse(match.Groups["Y"].Value, out _y); } } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasEllipseFigure.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasEllipseFigure.cs index 9868ae2eddc..7f07c806e40 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasEllipseFigure.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasEllipseFigure.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -80,4 +80,4 @@ protected override void GetAttributes(Match match) float.TryParse(match.Groups["Y"].Value, out _y); } } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasPathFigure.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasPathFigure.cs index 8c38c6a5a54..63df1371edc 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasPathFigure.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasPathFigure.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -133,4 +133,4 @@ protected override void GetAttributes(Match match) // Do nothing } } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasPolygonFigure.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasPolygonFigure.cs index 4bf4cc8184f..806d1060385 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasPolygonFigure.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasPolygonFigure.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -82,4 +82,4 @@ protected override void GetAttributes(Match match) float.TryParse(match.Groups["Y"].Value, out _y); } } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasRectangleFigure.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasRectangleFigure.cs index 883ec7f847e..c691fee2602 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasRectangleFigure.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasRectangleFigure.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -87,4 +87,4 @@ protected override void GetAttributes(Match match) _height = Math.Abs(_height); } } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasRoundRectangleFigure.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasRoundRectangleFigure.cs index 3a0d7a1193c..f9fa6027f8a 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasRoundRectangleFigure.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasRoundRectangleFigure.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -101,4 +101,4 @@ protected override void GetAttributes(Match match) _radiusY = Math.Abs(_radiusY); } } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/ClosePathElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/ClosePathElement.cs index e66c387e4cb..61ffb6255bb 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/ClosePathElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/ClosePathElement.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -98,4 +98,4 @@ protected override void GetAttributes(Match match) // Do Nothing } } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CubicBezierElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CubicBezierElement.cs index d4113e8f76b..282d7740b22 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CubicBezierElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CubicBezierElement.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -102,4 +102,4 @@ protected override void GetAttributes(Match match) float.TryParse(match.Groups["Y"].Value, out _y); } } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/FillRuleElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/FillRuleElement.cs index 6d7948bf4a1..897219f3401 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/FillRuleElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/FillRuleElement.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -75,4 +75,4 @@ protected override void GetAttributes(Match match) Enum.TryParse(match.Groups["FillValue"].Value, out _fillValue); } } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/HorizontalLineElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/HorizontalLineElement.cs index bbd3201ff9f..4b98fcc0d59 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/HorizontalLineElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/HorizontalLineElement.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -66,4 +66,4 @@ protected override void GetAttributes(Match match) float.TryParse(match.Groups["X"].Value, out _x); } } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/ICanvasPathElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/ICanvasPathElement.cs index 2bee7f24960..c42c4e09973 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/ICanvasPathElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/ICanvasPathElement.cs @@ -1,9 +1,8 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Numerics; -using System.Text; using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; @@ -62,4 +61,4 @@ internal interface ICanvasPathElement /// The current point on the path after the path element is added Vector2 CreatePath(CanvasPathBuilder pathBuilder, Vector2 currentPoint, ref ICanvasPathElement lastElement); } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/LineElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/LineElement.cs index 2f52bbce991..186b63f18cd 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/LineElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/LineElement.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -71,4 +71,4 @@ protected override void GetAttributes(Match match) float.TryParse(match.Groups["Y"].Value, out _y); } } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/MoveToElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/MoveToElement.cs index 73aa61b4571..29d85724ecd 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/MoveToElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/MoveToElement.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -84,4 +84,4 @@ protected override void GetAttributes(Match match) float.TryParse(match.Groups["Y"].Value, out _y); } } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/QuadraticBezierElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/QuadraticBezierElement.cs index 3dd5ce32bc8..d697610ae75 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/QuadraticBezierElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/QuadraticBezierElement.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -94,4 +94,4 @@ protected override void GetAttributes(Match match) float.TryParse(match.Groups["Y"].Value, out _y); } } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/SmoothCubicBezierElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/SmoothCubicBezierElement.cs index d04112accae..6c6c820966d 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/SmoothCubicBezierElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/SmoothCubicBezierElement.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -114,4 +114,4 @@ protected override void GetAttributes(Match match) float.TryParse(match.Groups["Y"].Value, out _y); } } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/SmoothQuadraticBezierElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/SmoothQuadraticBezierElement.cs index 538b2997b6f..444a3262e14 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/SmoothQuadraticBezierElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/SmoothQuadraticBezierElement.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -103,4 +103,4 @@ protected override void GetAttributes(Match match) float.TryParse(match.Groups["Y"].Value, out _y); } } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/VerticalLineElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/VerticalLineElement.cs index 538bc570556..2b06607c4c7 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/VerticalLineElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/VerticalLineElement.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -66,4 +66,4 @@ protected override void GetAttributes(Match match) float.TryParse(match.Groups["Y"].Value, out _y); } } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/AbstractCanvasStrokeElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/AbstractCanvasStrokeElement.cs index fa086874b9d..ce2e8f4f2c6 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/AbstractCanvasStrokeElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/AbstractCanvasStrokeElement.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -62,4 +62,4 @@ protected virtual void Validate() /// Match object protected abstract void GetAttributes(Match match); } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/CanvasStrokeElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/CanvasStrokeElement.cs index e526074af53..419dc1f4269 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/CanvasStrokeElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/CanvasStrokeElement.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -102,4 +102,4 @@ protected override void Validate() } } } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/CanvasStrokeStyleElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/CanvasStrokeStyleElement.cs index 2780bc78732..79e2d396d15 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/CanvasStrokeStyleElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/CanvasStrokeStyleElement.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -179,4 +179,4 @@ public void Initialize(Match match) } } } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/ICanvasStrokeElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/ICanvasStrokeElement.cs index 92029aaa7aa..4cec2b20473 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/ICanvasStrokeElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/ICanvasStrokeElement.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -34,4 +34,4 @@ internal interface ICanvasStrokeElement /// ICanvasStroke ICanvasStroke CreateStroke(ICanvasResourceCreator resourceCreator); } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/ICanvasStrokeStyleElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/ICanvasStrokeStyleElement.cs index ec1fca39225..5a7fee6e268 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/ICanvasStrokeStyleElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/ICanvasStrokeStyleElement.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -33,4 +33,4 @@ internal interface ICanvasStrokeStyleElement /// Match object void Initialize(Match match); } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/ICanvasPathGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/ICanvasPathGeometry.cs index b82f17a979d..0c79a1cee5c 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/ICanvasPathGeometry.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/ICanvasPathGeometry.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Microsoft.Graphics.Canvas.Geometry; +using Microsoft.Graphics.Canvas.Geometry; namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/ICanvasStroke.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/ICanvasStroke.cs index 9c9a0b7f41f..e4209e85dcf 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/ICanvasStroke.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/ICanvasStroke.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -33,4 +33,4 @@ public interface ICanvasStroke /// Matrix3x2 Transform { get; set; } } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasBrushParser.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasBrushParser.cs index 2a66728c9bc..6f63b4cb518 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasBrushParser.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasBrushParser.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -119,4 +119,4 @@ internal static ICanvasBrush Parse(ICanvasResourceCreator resourceCreator, strin return brushElement.CreateBrush(resourceCreator); } } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasGeometryParser.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasGeometryParser.cs index 0ac3a86a1bb..f47b47a72c6 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasGeometryParser.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasGeometryParser.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -66,7 +66,7 @@ internal static CanvasGeometry Parse(ICanvasResourceCreator resourceCreator, str // Process the 'Additional' Group which contains just the attributes figures.AddRange(from Capture capture in figureMatch.Groups["Additional"].Captures - select PathElementFactory.CreateAdditionalPathFigure(type, capture, figureRootIndex + capture.Index, figure.IsRelative)); + select PathElementFactory.CreateAdditionalPathFigure(type, capture, figureRootIndex + capture.Index, figure.IsRelative)); } } @@ -135,4 +135,4 @@ static void ThrowForInvalidCharacters(List pathFigures, stri "into multiple Path Data and call the CanvasPathGeometry.CreateGeometry() method on each of them."); } } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasStrokeParser.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasStrokeParser.cs index e7c2fea9026..9f91969fb27 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasStrokeParser.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasStrokeParser.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -95,4 +95,4 @@ internal static ICanvasStroke Parse(ICanvasResourceCreator resourceCreator, stri return strokeElement.CreateStroke(resourceCreator); } } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasStrokeStyleParser.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasStrokeStyleParser.cs index 25bce614f4e..c0418ee5619 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasStrokeStyleParser.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasStrokeStyleParser.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -90,4 +90,4 @@ internal static ICanvasStrokeStyleElement Parse(Match match) return new CanvasStrokeStyleElement(match); } } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/ColorParser.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/ColorParser.cs index e6bf1cb7192..3bc1955d473 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/ColorParser.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/ColorParser.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -143,4 +143,4 @@ internal static Color Parse(Match match) return Colors.Transparent; } } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Scalar.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Scalar.cs index 773b4f46744..e93b1b62af7 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Scalar.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Scalar.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -61,4 +61,4 @@ internal static class Scalar /// internal const float RadiansToDegrees = 180f / Pi; } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/StrokeStyle.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/StrokeStyle.cs new file mode 100644 index 00000000000..94c585f4648 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/StrokeStyle.cs @@ -0,0 +1,297 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.Graphics.Canvas.Geometry; +using Windows.UI.Xaml; + +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry +{ + public class StrokeStyle : DependencyObject, IDisposable + { + private bool _disposedValue; + private CanvasStrokeStyle _canvasStrokeStyle; + + public event EventHandler Updated; + + /// + /// CustomDashStyle Dependency Property + /// + public static readonly DependencyProperty CustomDashStyleProperty = DependencyProperty.Register( + "CustomDashStyle", + typeof(string), + typeof(StrokeStyle), + new PropertyMetadata(string.Empty, OnCustomDashStyleChanged)); + + /// + /// Gets or sets the an array describing a custom dash pattern. This overrides the DashStyle property, which is only used when CustomDashStyle is set to null. + /// A custom dash style is an array whose elements specify the length of each dash and space in the pattern. + /// The first element sets the length of a dash, the second element sets the length of a space, the third element sets the length of a dash, and so on. + /// The length of each dash and space in the dash pattern is the product of the element value in the array and the stroke width. + /// This array must contain an even number of elements. + /// If the dash style is configured to contain a dash which is zero-length, that dash will only be visible with a cap style other than Flat. + /// + public string CustomDashStyle + { + get => (string)GetValue(CustomDashStyleProperty); + set => SetValue(CustomDashStyleProperty, value); + } + + /// + /// Handles changes to the CustomDashStyle property. + /// + /// + /// DependencyProperty changed event arguments + private static void OnCustomDashStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var strokeStyle = (StrokeStyle)d; + strokeStyle.OnCustomDashStyleChanged(); + } + + /// + /// Instance handler for the changes to the CustomDashStyle dependency property. + /// + private void OnCustomDashStyleChanged() + { + var result = new List(); + + if (!string.IsNullOrWhiteSpace(CustomDashStyle)) + { + var arr = CustomDashStyle.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); + + if (arr.Any()) + { + if (arr.Length % 2 != 0) + { + throw new ArgumentException("CustomDashStyle must contain an even number of elements!"); + } + + foreach (var token in arr) + { + if (float.TryParse(token, out float num)) + { + result.Add(num); + } + else + { + throw new ArgumentException($"Invalid value! Cannot convert '{token}' to 'System.Single'!"); + } + } + } + } + + ParsedCustomDashStyle = result.Any() ? result.ToArray() : null; + + OnUpdated(); + } + + public float[] ParsedCustomDashStyle { get; private set; } = null; + + /// + /// DashCap Dependency Property + /// + public static readonly DependencyProperty DashCapProperty = DependencyProperty.Register( + "DashCap", + typeof(CanvasCapStyle), + typeof(StrokeStyle), + new PropertyMetadata(CanvasCapStyle.Square, OnPropertyChanged)); + + /// + /// Gets or sets how the ends of each dash are drawn. Defaults to Square. + /// If this is set to Flat, dots will have zero size so only dashes are visible. + /// + public CanvasCapStyle DashCap + { + get => (CanvasCapStyle)GetValue(DashCapProperty); + set => SetValue(DashCapProperty, value); + } + + /// + /// DashOffset Dependency Property + /// + public static readonly DependencyProperty DashOffsetProperty = DependencyProperty.Register( + "DashOffset", + typeof(double), + typeof(StrokeStyle), + new PropertyMetadata(0d, OnPropertyChanged)); + + /// + /// Gets or sets how far into the dash sequence the stroke will start. + /// + public double DashOffset + { + get => (double)GetValue(DashOffsetProperty); + set => SetValue(DashOffsetProperty, value); + } + + /// + /// DashStyle Dependency Property + /// + public static readonly DependencyProperty DashStyleProperty = DependencyProperty.Register( + "DashStyle", + typeof(CanvasDashStyle), + typeof(StrokeStyle), + new PropertyMetadata(CanvasDashStyle.Solid, OnPropertyChanged)); + + /// + /// Gets or sets the stroke's dash pattern. This is ignored if CustomDashStyle has been set. + /// + public CanvasDashStyle DashStyle + { + get => (CanvasDashStyle)GetValue(DashStyleProperty); + set => SetValue(DashStyleProperty, value); + } + + /// + /// EndCap Dependency Property + /// + public static readonly DependencyProperty EndCapProperty = DependencyProperty.Register( + "EndCap", + typeof(CanvasCapStyle), + typeof(StrokeStyle), + new PropertyMetadata(CanvasCapStyle.Flat, OnPropertyChanged)); + + /// + /// Gets or sets the type of shape used at the end of a stroke. Defaults to Flat. + /// + public CanvasCapStyle EndCap + { + get => (CanvasCapStyle)GetValue(EndCapProperty); + set => SetValue(EndCapProperty, value); + } + + /// + /// LineJoin Dependency Property + /// + public static readonly DependencyProperty LineJoinProperty = DependencyProperty.Register( + "LineJoin", + typeof(CanvasLineJoin), + typeof(StrokeStyle), + new PropertyMetadata(CanvasLineJoin.Miter, OnPropertyChanged)); + + /// + /// Gets or sets the type of joint used at the vertices of a shape's outline. + /// + public CanvasLineJoin LineJoin + { + get => (CanvasLineJoin)GetValue(LineJoinProperty); + set => SetValue(LineJoinProperty, value); + } + + /// + /// MiterLimit Dependency Property + /// + public static readonly DependencyProperty MiterLimitProperty = DependencyProperty.Register( + "MiterLimit", + typeof(double), + typeof(StrokeStyle), + new PropertyMetadata(10d, OnPropertyChanged)); + + /// + /// Gets or sets the limit on the ratio of the miter length to half the stroke's thickness. + /// + public double MiterLimit + { + get => (double)GetValue(MiterLimitProperty); + set => SetValue(MiterLimitProperty, value); + } + + /// + /// StartCap Dependency Property + /// + public static readonly DependencyProperty StartCapProperty = DependencyProperty.Register( + "StartCap", + typeof(CanvasCapStyle), + typeof(StrokeStyle), + new PropertyMetadata(CanvasCapStyle.Flat, OnPropertyChanged)); + + /// + /// Gets or sets the type of shape used at the beginning of a stroke. Defaults to Flat. + /// + public CanvasCapStyle StartCap + { + get => (CanvasCapStyle)GetValue(StartCapProperty); + set => SetValue(StartCapProperty, value); + } + + /// + /// TransformBehavior Dependency Property + /// + public static readonly DependencyProperty TransformBehaviorProperty = DependencyProperty.Register( + "TransformBehavior", + typeof(CanvasStrokeTransformBehavior), + typeof(StrokeStyle), + new PropertyMetadata(CanvasStrokeTransformBehavior.Normal, OnPropertyChanged)); + + /// + /// Gets or sets how the world transform, dots per inch (DPI), and stroke width affect the shape of the pen. + /// + public CanvasStrokeTransformBehavior TransformBehavior + { + get => (CanvasStrokeTransformBehavior)GetValue(TransformBehaviorProperty); + set => SetValue(TransformBehaviorProperty, value); + } + + /// + /// Method that is called whenever the dependency properties of the StrokeStyle changes + /// + /// The object whose property has changed + /// Event arguments + private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var strokeStyle = (StrokeStyle)d; + + // Recreate the canvas brush on any property change. + strokeStyle.OnUpdated(); + } + + private void OnUpdated() + { + _canvasStrokeStyle = new CanvasStrokeStyle() + { + CustomDashStyle = ParsedCustomDashStyle, + DashCap = DashCap, + DashOffset = (float)DashOffset, + DashStyle = DashStyle, + EndCap = EndCap, + LineJoin = LineJoin, + MiterLimit = (float)MiterLimit, + StartCap = StartCap, + TransformBehavior = TransformBehavior + }; + + Updated?.Invoke(this, null); + } + + public StrokeStyle() + { + ParsedCustomDashStyle = new float[0]; + } + + private void Dispose(bool disposing) + { + if (!_disposedValue) + { + if (disposing) + { + // Dispose managed state (managed objects) + ParsedCustomDashStyle = null; + } + + // Free unmanaged resources (unmanaged objects), if any, and override finalizer + _disposedValue = true; + } + } + + public void Dispose() + { + // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + Dispose(disposing: true); + GC.SuppressFinalize(this); + } + + public CanvasStrokeStyle GetCanvasStrokeStyle() + { + return _canvasStrokeStyle; + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Utils.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Utils.cs index 51f23bb519b..fe42ae27fad 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Utils.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Utils.cs @@ -1,10 +1,9 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Numerics; -using System.Runtime.InteropServices; using Windows.Foundation; using Windows.UI; using Windows.UI.Xaml; @@ -31,7 +30,7 @@ public static class Utils /// The first double to compare. /// The second double to compare. /// - /// bool - the result of the AreClose comparison. + /// bool - the result of the AreClose comparision. /// public static bool IsCloseTo(this double value1, double value2) { @@ -55,7 +54,7 @@ public static bool IsCloseTo(this double value1, double value2) /// The first double to compare. /// The second double to compare. /// - /// bool - the result of the LessThan comparison. + /// bool - the result of the LessThan comparision. /// public static bool IsLessThan(this double value1, double value2) { @@ -68,7 +67,7 @@ public static bool IsLessThan(this double value1, double value2) /// The first double to compare. /// The second double to compare. /// - /// bool - the result of the GreaterThan comparison. + /// bool - the result of the GreaterThan comparision. /// public static bool IsGreaterThan(this double value1, double value2) { @@ -81,7 +80,7 @@ public static bool IsGreaterThan(this double value1, double value2) /// /// The double to compare to 1. /// - /// bool - the result of the AreClose comparison. + /// bool - the result of the AreClose comparision. /// public static bool IsOne(this double value) { @@ -94,7 +93,7 @@ public static bool IsOne(this double value) /// /// The double to compare to 0. /// - /// bool - the result of the AreClose comparison. + /// bool - the result of the AreClose comparision. /// public static bool IsZero(this double value) { @@ -107,7 +106,7 @@ public static bool IsZero(this double value) /// The first float to compare. /// The second float to compare. /// - /// bool - the result of the AreClose comparison. + /// bool - the result of the AreClose comparision. /// public static bool IsCloseTo(this float value1, float value2) { @@ -131,7 +130,7 @@ public static bool IsCloseTo(this float value1, float value2) /// The first float to compare. /// The second float to compare. /// - /// bool - the result of the LessThan comparison. + /// bool - the result of the LessThan comparision. /// public static bool IsLessThan(this float value1, float value2) { @@ -144,7 +143,7 @@ public static bool IsLessThan(this float value1, float value2) /// The first float to compare. /// The second float to compare. /// - /// bool - the result of the GreaterThan comparison. + /// bool - the result of the GreaterThan comparision. /// public static bool IsGreaterThan(this float value1, float value2) { @@ -157,7 +156,7 @@ public static bool IsGreaterThan(this float value1, float value2) /// /// The float to compare to 1. /// - /// bool - the result of the AreClose comparison. + /// bool - the result of the AreClose comparision. /// public static bool IsOne(this float value) { @@ -170,7 +169,7 @@ public static bool IsOne(this float value) /// /// The float to compare to 0. /// - /// bool - the result of the AreClose comparison. + /// bool - the result of the AreClose comparision. /// public static bool IsZero(this float value) { @@ -849,4 +848,4 @@ public static MatrixTransform ToMatrixTransform(this Matrix3x2 matrix) }; } } -} \ No newline at end of file +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs index 74d7fd8e229..e1448f28b7f 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs @@ -30,8 +30,7 @@ public sealed class CompositionGenerator : ICompositionGeneratorInternal /// public event EventHandler DeviceReplaced; - private static Lazy _instance = - new Lazy(() => new CompositionGenerator(), System.Threading.LazyThreadSafetyMode.PublicationOnly); + private static Lazy _instance = new(() => new CompositionGenerator(), System.Threading.LazyThreadSafetyMode.PublicationOnly); private readonly object _disposingLock; private bool _useSharedCanvasDevice; @@ -144,7 +143,7 @@ private static void RenderBitmap(object surfaceLock, CompositionDrawingSurface s canvasBitmap, // CanvasBitmap new Rect(0, 0, surfaceSize.Width, surfaceSize.Height), // Target Rectangle new Rect(0, 0, canvasBitmap.Size.Width, canvasBitmap.Size.Height), // Source Rectangle - options.Opacity, // Opacity + (float)options.Opacity, // Opacity options.Interpolation); // Interpolation } else @@ -176,7 +175,7 @@ private static void RenderBitmap(object surfaceLock, CompositionDrawingSurface s canvasBitmap, // CanvasBitmap targetRect, // Target Rectangle canvasBitmap.Bounds, // Source Rectangle - options.Opacity, // Opacity + (float)options.Opacity, // Opacity options.Interpolation); // Interpolation } } @@ -281,7 +280,7 @@ private static void RenderBitmapMask(CanvasDevice device, object surfaceLock, Co var blurEffect = new GaussianBlurEffect { Source = alphaEffect, - BlurAmount = options.BlurRadius + BlurAmount = (float)options.BlurRadius }; // Draw the final mask to the surface @@ -295,7 +294,7 @@ private static void RenderBitmapMask(CanvasDevice device, object surfaceLock, Co blurEffect, // CanvasBitmap surfaceBounds, // Target Rectangle surfaceBounds, // Source Rectangle - options.Opacity, // Opacity + (float)options.Opacity, // Opacity options.Interpolation); // Interpolation } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurfaceOptions.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurfaceOptions.cs index a368c23541c..b31df504527 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurfaceOptions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurfaceOptions.cs @@ -2,8 +2,10 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System; using Microsoft.Graphics.Canvas; using Windows.UI; +using Windows.UI.Xaml; using Windows.UI.Xaml.Media; namespace Microsoft.Toolkit.Uwp.UI.Media.Surface @@ -39,8 +41,10 @@ public enum ReflectionLocation /// Class to define the various options that would /// influence the rendering of the image on the ImageSurface /// - public class ImageSurfaceOptions + public class ImageSurfaceOptions : DependencyObject { + public event EventHandler Updated; + /// /// Gets default ImageSurfaceOptions when AutoResize is True /// Uniform Stretch and Center alignment @@ -113,50 +117,190 @@ public static ImageSurfaceOptions GetDefaultImageMaskOptionsForBlur(float blurRa }; } + /// + /// AutoResize Dependency Property + /// + public static readonly DependencyProperty AutoResizeProperty = DependencyProperty.Register( + "AutoResize", + typeof(bool), + typeof(ImageSurfaceOptions), + new PropertyMetadata(true, OnPropertyChanged)); + /// /// Gets or sets a value indicating whether specifies whether the IImageSurface should resize itself automatically to match the loaded image size. - /// NOTE: This property is not used by IImageMaskSurface. + /// NOTE: This property is not used by ImageMaskSurfaceBrush or IImageMaskSurface. /// - public bool AutoResize { get; set; } + public bool AutoResize + { + get => (bool)GetValue(AutoResizeProperty); + set => SetValue(AutoResizeProperty, value); + } /// - /// Gets or sets describes how image is resized to fill its allocated space. - /// NOTE: This property is taken into consideration only if AutoResize is False. + /// Stretch Dependency Property + /// + public static readonly DependencyProperty StretchProperty = DependencyProperty.Register( + "Stretch", + typeof(Stretch), + typeof(ImageSurfaceOptions), + new PropertyMetadata(Stretch.Uniform, OnPropertyChanged)); + + /// + /// Gets or sets a value describing how image is resized to fill its allocated space. + /// NOTE: This property is taken into consideration only if AutoResize is false. + /// + public Stretch Stretch + { + get => (Stretch)GetValue(StretchProperty); + set => SetValue(StretchProperty, value); + } + + /// + /// HorizontalAlignment Dependency Property /// - public Stretch Stretch { get; set; } = Stretch.None; + public static readonly DependencyProperty HorizontalAlignmentProperty = DependencyProperty.Register( + "HorizontalAlignment", + typeof(AlignmentX), + typeof(ImageSurfaceOptions), + new PropertyMetadata(AlignmentX.Center, OnPropertyChanged)); /// - /// Gets or sets describes how image is positioned horizontally in the IImageSurface or IImageMaskSurface. + /// Gets or sets a value describing how image is positioned horizontally in the IImageSurface or IImageMaskSurface. /// NOTE: This property is taken into consideration only if AutoResize is False. /// - public AlignmentX HorizontalAlignment { get; set; } = AlignmentX.Center; + public AlignmentX HorizontalAlignment + { + get => (AlignmentX)GetValue(HorizontalAlignmentProperty); + set => SetValue(HorizontalAlignmentProperty, value); + } + + /// + /// VerticalAlignment Dependency Property + /// + public static readonly DependencyProperty VerticalAlignmentProperty = DependencyProperty.Register( + "VerticalAlignment", + typeof(AlignmentY), + typeof(ImageSurfaceOptions), + new PropertyMetadata(AlignmentY.Center, OnPropertyChanged)); /// - /// Gets or sets describes how image is positioned vertically in the IImageSurface or IImageMaskSurface. + /// Gets or sets a value describing how image is positioned vertically in the IImageSurface or IImageMaskSurface. /// NOTE: This property is taken into consideration only if AutoResize is False. /// - public AlignmentY VerticalAlignment { get; set; } = AlignmentY.Center; + /// + public AlignmentY VerticalAlignment + { + get => (AlignmentY)GetValue(VerticalAlignmentProperty); + set => SetValue(VerticalAlignmentProperty, value); + } /// - /// Gets or sets specifies the opacity of the rendered the image in an IImageSurface or the mask in an IImageMaskSurface. + /// Opacity Dependency Property /// - public float Opacity { get; set; } = 1f; + public static readonly DependencyProperty OpacityProperty = DependencyProperty.Register( + "Opacity", + typeof(double), + typeof(ImageSurfaceOptions), + new PropertyMetadata(1d, OnPropertyChanged)); /// - /// Gets or sets specifies the interpolation used to render the image in an IImageSurface or the mask in an IImageMaskSurface. + /// Gets or sets the the opacity of the rendered the image in an IImageSurface or the mask in an IImageMaskSurface. /// - public CanvasImageInterpolation Interpolation { get; set; } = CanvasImageInterpolation.HighQualityCubic; + public double Opacity + { + get => (double)GetValue(OpacityProperty); + set => SetValue(OpacityProperty, value); + } /// - /// Gets or sets color which will be used to fill the IImageSurface in an IImageSurface or the mask in an IImageMaskSurface + /// Interpolation Dependency Property + /// + public static readonly DependencyProperty InterpolationProperty = DependencyProperty.Register( + "Interpolation", + typeof(CanvasImageInterpolation), + typeof(ImageSurfaceOptions), + new PropertyMetadata(CanvasImageInterpolation.HighQualityCubic, OnPropertyChanged)); + + /// + /// Gets or sets the the interpolation used to render the image in an IImageSurface or the mask in an IImageMaskSurface. + /// + public CanvasImageInterpolation Interpolation + { + get => (CanvasImageInterpolation)GetValue(InterpolationProperty); + set => SetValue(InterpolationProperty, value); + } + + /// + /// SurfaceBackgroundColor Dependency Property + /// + public static readonly DependencyProperty SurfaceBackgroundColorProperty = DependencyProperty.Register( + "SurfaceBackgroundColor", + typeof(Color), + typeof(ImageSurfaceOptions), + new PropertyMetadata(Colors.Transparent, OnPropertyChanged)); + + /// + /// Gets or sets the color which will be used to fill the IImageSurface in an IImageSurface or the mask in an IImageMaskSurface /// in case the image is not rendered. /// - public Color SurfaceBackgroundColor { get; set; } = Colors.Transparent; + public Color SurfaceBackgroundColor + { + get => (Color)GetValue(SurfaceBackgroundColorProperty); + set => SetValue(SurfaceBackgroundColorProperty, value); + } /// - /// Gets or sets radius of the Gaussian blur to be applied to the IImageMaskSurface. + /// BlurRadius Dependency Property + /// + public static readonly DependencyProperty BlurRadiusProperty = DependencyProperty.Register( + "BlurRadius", + typeof(double), + typeof(ImageSurfaceOptions), + new PropertyMetadata(0d, OnPropertyChanged)); + + /// + /// Gets or sets the radius of the Gaussian blur to be applied to the IImageMaskSurface. /// NOTE: This property is not used by IImageSurface. /// - public float BlurRadius { get; set; } + public double BlurRadius + { + get => (double)GetValue(BlurRadiusProperty); + set => SetValue(BlurRadiusProperty, value); + } + + /// + /// Method that is called whenever the dependency properties of the ImageSurfaceOptions changes. + /// + /// The object whose property has changed + /// Event arguments + private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var options = (ImageSurfaceOptions)d; + + options.OnUpdated(); + } + + /// + /// Raises the Updated event. + /// + private void OnUpdated() + { + Updated?.Invoke(this, null); + } + + /// + /// Initializes a new instance of the class. + /// + public ImageSurfaceOptions() + { + AutoResize = false; + Interpolation = CanvasImageInterpolation.HighQualityCubic; + Opacity = 1f; + Stretch = Stretch.Uniform; + HorizontalAlignment = AlignmentX.Center; + VerticalAlignment = AlignmentY.Center; + SurfaceBackgroundColor = Colors.Transparent; + BlurRadius = 0f; + } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ICompositionGenerator.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/ICompositionGenerator.cs similarity index 100% rename from Microsoft.Toolkit.Uwp.UI.Media/Surface/ICompositionGenerator.cs rename to Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/ICompositionGenerator.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ICompositionGeneratorInternal.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/ICompositionGeneratorInternal.cs similarity index 100% rename from Microsoft.Toolkit.Uwp.UI.Media/Surface/ICompositionGeneratorInternal.cs rename to Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/ICompositionGeneratorInternal.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/IGaussianMaskSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IGaussianMaskSurface.cs similarity index 100% rename from Microsoft.Toolkit.Uwp.UI.Media/Surface/IGaussianMaskSurface.cs rename to Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IGaussianMaskSurface.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/IGeometryMaskSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IGeometryMaskSurface.cs similarity index 100% rename from Microsoft.Toolkit.Uwp.UI.Media/Surface/IGeometryMaskSurface.cs rename to Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IGeometryMaskSurface.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/IGeometrySurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IGeometrySurface.cs similarity index 100% rename from Microsoft.Toolkit.Uwp.UI.Media/Surface/IGeometrySurface.cs rename to Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IGeometrySurface.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/IImageMaskSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IImageMaskSurface.cs similarity index 100% rename from Microsoft.Toolkit.Uwp.UI.Media/Surface/IImageMaskSurface.cs rename to Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IImageMaskSurface.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/IImageSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IImageSurface.cs similarity index 100% rename from Microsoft.Toolkit.Uwp.UI.Media/Surface/IImageSurface.cs rename to Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IImageSurface.cs diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/IRenderSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IRenderSurface.cs similarity index 100% rename from Microsoft.Toolkit.Uwp.UI.Media/Surface/IRenderSurface.cs rename to Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IRenderSurface.cs From 2ec87361c9699c4cd7e7f72667221529c01b03a8 Mon Sep 17 00:00:00 2001 From: Ratish Philip Date: Wed, 9 Jun 2021 07:01:35 -0700 Subject: [PATCH 09/21] updated namespace to common Microsoft.Toolkit.Uwp.UI.Media. Added missing headers to files. --- .../CanvasPathGeometryPage.xaml.cs | 2 +- .../Brushes/Base/RenderCanvasBrushBase.cs | 20 ++++++++++++++++-- .../Brushes/Base/RenderSurfaceBrushBase.cs | 10 +++++++-- .../Brushes/GeometryMaskSurfaceBrush.cs | 12 ++++++----- .../Brushes/GeometrySurfaceBrush.cs | 11 ++++++---- .../Brushes/ImageMaskSurfaceBrush.cs | 12 ++++++++--- .../Brushes/ImageSurfaceBrush.cs | 7 +++++-- .../Brushes/LinearGradientCanvasBrush.cs | 11 +++++++--- .../Brushes/RadialGradientCanvasBrush.cs | 13 ++++++++---- .../Brushes/SolidColorCanvasBrush.cs | 17 ++++++++------- .../Geometry/CanvasCircleGeometry.cs | 5 ++--- .../Geometry/CanvasCombinedGeometry.cs | 4 ++-- .../Geometry/CanvasCoreGeometry.cs | 11 +++++++--- .../CanvasDrawingSessionExtensions.cs | 4 ++-- .../Geometry/CanvasEllipseGeometry.cs | 5 ++--- .../Geometry/CanvasPathBuilderExtensions.cs | 5 ++--- .../Geometry/CanvasPathGeometry.cs | 6 ++---- .../Geometry/CanvasRectangleGeometry.cs | 5 ++--- .../CanvasRoundedRectangleGeometry.cs | 5 ++--- .../Geometry/CanvasSquircleGeometry.cs | 5 ++--- .../Geometry/CanvasStroke.cs | 4 ++-- .../Geometry/CompositorGeometryExtensions.cs | 4 ++-- .../Geometry/Core/CanvasRoundRect.cs | 4 ++-- .../Geometry/Core/GeometryTypeDefinitions.cs | 4 ++-- .../Geometry/Core/PathElementFactory.cs | 5 ++--- .../Geometry/Core/RegexFactory.cs | 4 ++-- .../Geometry/CultureShield.cs | 2 +- .../Brush/AbstractCanvasBrushElement.cs | 5 ++--- .../Elements/Brush/ICanvasBrushElement.cs | 4 ++-- .../Brush/LinearGradientBrushElement.cs | 6 ++---- .../Brush/LinearGradientHdrBrushElement.cs | 5 ++--- .../Brush/RadialGradientBrushElement.cs | 6 ++---- .../Brush/RadialGradientHdrBrushElement.cs | 5 ++--- .../Elements/Brush/SolidColorBrushElement.cs | 6 ++---- .../Elements/Path/AbstractPathElement.cs | 5 ++--- .../Geometry/Elements/Path/ArcElement.cs | 5 ++--- .../Elements/Path/CanvasEllipseFigure.cs | 5 ++--- .../Elements/Path/CanvasPathFigure.cs | 5 ++--- .../Elements/Path/CanvasPolygonFigure.cs | 5 ++--- .../Elements/Path/CanvasRectangleFigure.cs | 5 ++--- .../Path/CanvasRoundRectangleFigure.cs | 5 ++--- .../Elements/Path/ClosePathElement.cs | 5 ++--- .../Elements/Path/CubicBezierElement.cs | 5 ++--- .../Geometry/Elements/Path/FillRuleElement.cs | 4 ++-- .../Elements/Path/HorizontalLineElement.cs | 5 ++--- .../Elements/Path/ICanvasPathElement.cs | 4 ++-- .../Geometry/Elements/Path/LineElement.cs | 5 ++--- .../Geometry/Elements/Path/MoveToElement.cs | 5 ++--- .../Elements/Path/QuadraticBezierElement.cs | 5 ++--- .../Elements/Path/SmoothCubicBezierElement.cs | 5 ++--- .../Path/SmoothQuadraticBezierElement.cs | 5 ++--- .../Elements/Path/VerticalLineElement.cs | 5 ++--- .../Stroke/AbstractCanvasStrokeElement.cs | 5 ++--- .../Elements/Stroke/CanvasStrokeElement.cs | 7 ++----- .../Stroke/CanvasStrokeStyleElement.cs | 5 ++--- .../Elements/Stroke/ICanvasStrokeElement.cs | 4 ++-- .../Stroke/ICanvasStrokeStyleElement.cs | 4 ++-- .../Geometry/ICanvasPathGeometry.cs | 4 ++-- .../Geometry/ICanvasStroke.cs | 4 ++-- .../Geometry/Parsers/CanvasBrushParser.cs | 6 ++---- .../Geometry/Parsers/CanvasGeometryParser.cs | 6 ++---- .../Geometry/Parsers/CanvasStrokeParser.cs | 6 ++---- .../Parsers/CanvasStrokeStyleParser.cs | 6 ++---- .../Geometry/Parsers/ColorParser.cs | 5 ++--- .../Geometry/Scalar.cs | 4 ++-- .../Geometry/StrokeStyle.cs | 21 +++++++++++++++++-- .../Geometry/Utils.cs | 4 ++-- .../Surface/CompositionExtensions.cs | 4 ++-- .../Surface/CompositionGenerator.cs | 6 +++--- .../Surface/CompositorExtensions.cs | 4 ++-- .../Surface/GaussianMaskSurface.cs | 4 ++-- .../Surface/GeometryMaskSurface.cs | 4 ++-- .../Surface/GeometrySurface.cs | 5 ++--- .../Surface/ImageMaskSurface.cs | 5 ++--- .../Surface/ImageSurface.cs | 5 ++--- .../Surface/ImageSurfaceOptions.cs | 8 ++++--- .../Interfaces/ICompositionGenerator.cs | 5 ++--- .../ICompositionGeneratorInternal.cs | 5 ++--- .../Interfaces/IGaussianMaskSurface.cs | 4 ++-- .../Interfaces/IGeometryMaskSurface.cs | 4 ++-- .../Surface/Interfaces/IGeometrySurface.cs | 5 ++--- .../Surface/Interfaces/IImageMaskSurface.cs | 4 ++-- .../Surface/Interfaces/IImageSurface.cs | 4 ++-- .../Surface/Interfaces/IRenderSurface.cs | 4 ++-- .../Geometry/Test_CanvasPathGeometry.cs | 2 +- .../Geometry/Test_RegexFactory.cs | 2 +- .../UnitTests.UWP/Geometry/Test_Utils.cs | 2 +- 87 files changed, 259 insertions(+), 240 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/CanvasPathGeometry/CanvasPathGeometryPage.xaml.cs b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/CanvasPathGeometry/CanvasPathGeometryPage.xaml.cs index 3cbdacb187c..0b1f869cb54 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/CanvasPathGeometry/CanvasPathGeometryPage.xaml.cs +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/CanvasPathGeometry/CanvasPathGeometryPage.xaml.cs @@ -9,7 +9,7 @@ using Microsoft.Graphics.Canvas.Geometry; using Microsoft.Graphics.Canvas.UI.Xaml; using Microsoft.Toolkit.Uwp.UI; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry; +using Microsoft.Toolkit.Uwp.UI.Media; using Windows.System; using Windows.UI; using Windows.UI.Xaml; diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderCanvasBrushBase.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderCanvasBrushBase.cs index e0133ef75ff..5d3619edf1f 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderCanvasBrushBase.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderCanvasBrushBase.cs @@ -1,17 +1,30 @@ -using System; +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; using System.Runtime.CompilerServices; using Microsoft.Graphics.Canvas.Brushes; using Windows.UI.Xaml; using Windows.UI.Xaml.Media; -namespace Microsoft.Toolkit.Uwp.UI.Media.Brushes +namespace Microsoft.Toolkit.Uwp.UI.Media { + /// + /// Abstract base class for SolidColorCanvasBrush, LinearGradientCanvasBrush and RadialGradientCanvasBrush + /// public abstract class RenderCanvasBrushBase : DependencyObject, IDisposable { + /// + /// Event which indicates that the components of the brush have changed. + /// public event EventHandler Updated; private bool _disposedValue; + /// + /// Gets or sets the associated CanvasBrush. + /// public ICanvasBrush CanvasBrush { get; protected set; } /// @@ -58,6 +71,9 @@ protected virtual void OnUpdated() RaiseUpdatedEvent(); } + /// + /// Raises the Updated event. + /// protected void RaiseUpdatedEvent() { Updated?.Invoke(this, null); diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderSurfaceBrushBase.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderSurfaceBrushBase.cs index a41914675ba..542d4197319 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderSurfaceBrushBase.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderSurfaceBrushBase.cs @@ -1,16 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + using System; -using Microsoft.Toolkit.Uwp.UI.Media.Surface; using Windows.UI.Composition; using Windows.UI.Xaml; using Windows.UI.Xaml.Media; -namespace Microsoft.Toolkit.Uwp.UI.Media.Brushes +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Base class for RenderSurface brushes /// public abstract class RenderSurfaceBrushBase : XamlCompositionBrushBase { + /// + /// Event which indicates that the components of the brush have changed. + /// public event EventHandler Updated; /// diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs index b10e816a160..310e3dea124 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs @@ -1,17 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + using System; using System.Numerics; using Microsoft.Toolkit.Uwp.Helpers; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry; -using Microsoft.Toolkit.Uwp.UI.Media.Surface; using Windows.Foundation; using Windows.UI.Composition; using Windows.UI.Core; using Windows.UI.Xaml; -namespace Microsoft.Toolkit.Uwp.UI.Media.Brushes +namespace Microsoft.Toolkit.Uwp.UI.Media { /// - /// Represents a brush + /// Represents a brush which defines a as a mask to be applied on a derivative. /// public sealed class GeometryMaskSurfaceBrush : RenderSurfaceBrushBase { @@ -30,7 +32,7 @@ public sealed class GeometryMaskSurfaceBrush : RenderSurfaceBrushBase new PropertyMetadata(null, OnTargetChanged)); /// - /// Gets or sets the Target Geometry on which the Mask is applied. + /// Gets or sets the target on which the Mask is applied. /// public RenderSurfaceBrushBase Target { diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometrySurfaceBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometrySurfaceBrush.cs index f3273c4bffa..77b976a8fd1 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometrySurfaceBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometrySurfaceBrush.cs @@ -1,17 +1,20 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + using System; using Microsoft.Graphics.Canvas.Brushes; using Microsoft.Graphics.Canvas.Geometry; using Microsoft.Toolkit.Uwp.Helpers; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry; using Windows.Foundation; using Windows.UI; using Windows.UI.Core; using Windows.UI.Xaml; -namespace Microsoft.Toolkit.Uwp.UI.Media.Brushes +namespace Microsoft.Toolkit.Uwp.UI.Media { /// - /// Brush + /// Brush which renders the provided . /// public sealed class GeometrySurfaceBrush : RenderSurfaceBrushBase { @@ -42,7 +45,7 @@ public CanvasCoreGeometry Geometry /// /// Handles changes to the Geometry property. /// - /// + /// /// DependencyProperty changed event arguments private static void OnGeometryChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageMaskSurfaceBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageMaskSurfaceBrush.cs index 54fa28c913f..a9b9b393832 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageMaskSurfaceBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageMaskSurfaceBrush.cs @@ -1,13 +1,19 @@ -using System; +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; using Microsoft.Toolkit.Uwp.Helpers; -using Microsoft.Toolkit.Uwp.UI.Media.Surface; using Windows.Foundation; using Windows.UI.Composition; using Windows.UI.Core; using Windows.UI.Xaml; -namespace Microsoft.Toolkit.Uwp.UI.Media.Brushes +namespace Microsoft.Toolkit.Uwp.UI.Media { + /// + /// Represents a brush which uses an Image to create a mask to be applied on a derivative. + /// public sealed class ImageMaskSurfaceBrush : RenderSurfaceBrushBase { private CompositionMaskBrush _maskBrush; diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageSurfaceBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageSurfaceBrush.cs index 667ce29f7ab..e1e09c7f015 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageSurfaceBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageSurfaceBrush.cs @@ -1,12 +1,15 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + using System; using Microsoft.Toolkit.Uwp.Helpers; -using Microsoft.Toolkit.Uwp.UI.Media.Surface; using Windows.Foundation; using Windows.UI; using Windows.UI.Core; using Windows.UI.Xaml; -namespace Microsoft.Toolkit.Uwp.UI.Media.Brushes +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Creates a Render Surface brush using an image diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/LinearGradientCanvasBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/LinearGradientCanvasBrush.cs index 9568833f6dc..0cf0a5af527 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/LinearGradientCanvasBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/LinearGradientCanvasBrush.cs @@ -1,9 +1,11 @@ -using System.Collections.Generic; +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; using System.Numerics; using Microsoft.Graphics.Canvas; using Microsoft.Graphics.Canvas.Brushes; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry; -using Microsoft.Toolkit.Uwp.UI.Media.Surface; using Windows.Foundation; using Windows.UI.Xaml; using Windows.UI.Xaml.Markup; @@ -11,6 +13,9 @@ namespace Microsoft.Toolkit.Uwp.UI.Media.Brushes { + /// + /// XAML equivalent of Win2d's CanvasLinearGradientBrush class which paints in linear gradient. + /// [ContentProperty(Name = nameof(Stops))] public class LinearGradientCanvasBrush : RenderCanvasBrushBase { diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/RadialGradientCanvasBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/RadialGradientCanvasBrush.cs index c55b6ae36cd..6168152b1ef 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/RadialGradientCanvasBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/RadialGradientCanvasBrush.cs @@ -1,16 +1,21 @@ -using System.Collections.Generic; +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; using System.Numerics; using Microsoft.Graphics.Canvas; using Microsoft.Graphics.Canvas.Brushes; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry; -using Microsoft.Toolkit.Uwp.UI.Media.Surface; using Windows.Foundation; using Windows.UI.Xaml; using Windows.UI.Xaml.Markup; using Windows.UI.Xaml.Media; -namespace Microsoft.Toolkit.Uwp.UI.Media.Brushes +namespace Microsoft.Toolkit.Uwp.UI.Media { + /// + /// XAML equivalent of Win2d's CanvasRadialGradientBrush class which paints in radial gradient. + /// [ContentProperty(Name = nameof(Stops))] public class RadialGradientCanvasBrush : RenderCanvasBrushBase { diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/SolidColorCanvasBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/SolidColorCanvasBrush.cs index 2486b7f719e..54a39a97a65 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/SolidColorCanvasBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/SolidColorCanvasBrush.cs @@ -1,10 +1,16 @@ -using Microsoft.Graphics.Canvas.Brushes; -using Microsoft.Toolkit.Uwp.UI.Media.Surface; +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.Graphics.Canvas.Brushes; using Windows.UI; using Windows.UI.Xaml; -namespace Microsoft.Toolkit.Uwp.UI.Media.Brushes +namespace Microsoft.Toolkit.Uwp.UI.Media { + /// + /// XAML equivalent of Win2d's CanvasSolidColorBrush class which paints in solid color. + /// public class SolidColorCanvasBrush : RenderCanvasBrushBase { /// @@ -38,14 +44,11 @@ private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChan brush.OnUpdated(); } + /// protected override void OnUpdated() { CanvasBrush = new CanvasSolidColorBrush(CompositionGenerator.Instance.Device, Color); base.OnUpdated(); } - - public SolidColorCanvasBrush() - { - } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCircleGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCircleGeometry.cs index a9ac97c7b92..bc4ad0ea261 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCircleGeometry.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCircleGeometry.cs @@ -1,13 +1,12 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Numerics; using Microsoft.Graphics.Canvas.Geometry; -using Microsoft.Toolkit.Uwp.UI.Media.Surface; using Windows.UI.Xaml; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Represents a circle geometry object with the specified extents. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCombinedGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCombinedGeometry.cs index 0dc4de004ab..9255f7fe3da 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCombinedGeometry.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCombinedGeometry.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -9,7 +9,7 @@ using Windows.UI.Xaml; using Windows.UI.Xaml.Media; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Represents a Geometry defined by the combination of two objects. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCoreGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCoreGeometry.cs index 8eb79e9a963..8e91ea716eb 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCoreGeometry.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCoreGeometry.cs @@ -1,20 +1,22 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Runtime.CompilerServices; using Microsoft.Graphics.Canvas.Geometry; -using Microsoft.Toolkit.Uwp.UI.Media.Surface; using Windows.UI.Xaml; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Provides a base class for objects that define geometric shapes using CanvasGeometry. /// public abstract class CanvasCoreGeometry : DependencyObject, ICanvasPathGeometry, IDisposable { + /// + /// Event to notify that the properties of this class have been updated. + /// public event EventHandler Updated; private bool _disposedValue; @@ -63,6 +65,9 @@ protected virtual void OnUpdateGeometry() Updated?.Invoke(this, null); } + /// + /// Raises the Updated event. + /// protected void RaiseUpdatedEvent() { Updated?.Invoke(this, null); diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasDrawingSessionExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasDrawingSessionExtensions.cs index c1d870f08f9..b9f7480e993 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasDrawingSessionExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasDrawingSessionExtensions.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -9,7 +9,7 @@ using Windows.Foundation; using Windows.UI; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Extension methods for CanvasDrawingSession. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasEllipseGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasEllipseGeometry.cs index 726b74e8ab2..e3783c17b27 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasEllipseGeometry.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasEllipseGeometry.cs @@ -1,13 +1,12 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Numerics; using Microsoft.Graphics.Canvas.Geometry; -using Microsoft.Toolkit.Uwp.UI.Media.Surface; using Windows.UI.Xaml; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Represents an Ellipse geometry object with the specified extents. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasPathBuilderExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasPathBuilderExtensions.cs index b704ce13f18..9ad3e630e0f 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasPathBuilderExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasPathBuilderExtensions.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -7,9 +7,8 @@ using System.Linq; using System.Numerics; using Microsoft.Graphics.Canvas.Geometry; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Core; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Defines extension methods for CanvasPathBuilder. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasPathGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasPathGeometry.cs index e20b4e0e1fb..4e0bcf7c0fb 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasPathGeometry.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasPathGeometry.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -7,12 +7,10 @@ using Microsoft.Graphics.Canvas; using Microsoft.Graphics.Canvas.Brushes; using Microsoft.Graphics.Canvas.Geometry; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Parsers; -using Microsoft.Toolkit.Uwp.UI.Media.Surface; using Windows.UI; using Windows.UI.Xaml; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Represents a complex vector-based shape that may be composed of arcs, curves, ellipses, lines, rectangles, rounded rectangles, squircles. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasRectangleGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasRectangleGeometry.cs index 90f35aa12e2..cec4b71a978 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasRectangleGeometry.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasRectangleGeometry.cs @@ -1,12 +1,11 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using Microsoft.Graphics.Canvas.Geometry; -using Microsoft.Toolkit.Uwp.UI.Media.Surface; using Windows.UI.Xaml; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Represents a rectangular shape diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasRoundedRectangleGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasRoundedRectangleGeometry.cs index de8ec139c02..785e7f691ba 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasRoundedRectangleGeometry.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasRoundedRectangleGeometry.cs @@ -1,12 +1,11 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using Microsoft.Graphics.Canvas.Geometry; -using Microsoft.Toolkit.Uwp.UI.Media.Surface; using Windows.UI.Xaml; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Represents a rounded rectangle geometry object with the specified extents. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasSquircleGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasSquircleGeometry.cs index 90b65cb6edf..8143199e060 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasSquircleGeometry.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasSquircleGeometry.cs @@ -1,11 +1,10 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using Microsoft.Toolkit.Uwp.UI.Media.Surface; using Windows.UI.Xaml; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Represents a Squircle geometry object with the specified extents. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasStroke.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasStroke.cs index 210f1dcfb7a..26bf4f315ac 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasStroke.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasStroke.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -8,7 +8,7 @@ using Microsoft.Graphics.Canvas.Geometry; using Windows.UI; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Class to represent the Stroke which can be used to render an outline on a diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CompositorGeometryExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CompositorGeometryExtensions.cs index 1d7c863dab6..092572c3180 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CompositorGeometryExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CompositorGeometryExtensions.cs @@ -1,11 +1,11 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using Microsoft.Graphics.Canvas.Geometry; using Windows.UI.Composition; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Extension methods for compositor to support Win2d Path Mini Language. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/CanvasRoundRect.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/CanvasRoundRect.cs index 103ec3628bb..cb88e297f27 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/CanvasRoundRect.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/CanvasRoundRect.cs @@ -1,11 +1,11 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Numerics; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry.Core +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Structure which encapsulates the details of each of the core points of the path of the rounded rectangle which is calculated based on diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/GeometryTypeDefinitions.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/GeometryTypeDefinitions.cs index 027000a6547..bf092bc090c 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/GeometryTypeDefinitions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/GeometryTypeDefinitions.cs @@ -1,8 +1,8 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry.Core +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Enum for the various PathFigures. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/PathElementFactory.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/PathElementFactory.cs index ee77de7b668..b6fb880642a 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/PathElementFactory.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/PathElementFactory.cs @@ -1,12 +1,11 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Text.RegularExpressions; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Elements.Path; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry.Core +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Factory class to instantiate various PathElements. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/RegexFactory.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/RegexFactory.cs index 79112c46df4..7a8f1ffcf62 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/RegexFactory.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/RegexFactory.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -8,7 +8,7 @@ [assembly: InternalsVisibleTo("UnitTests.UWP")] -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry.Core +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Contains all the Regular Expressions which are used for parsing the Win2d Path Mini Language. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CultureShield.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CultureShield.cs index 702cd9d2c51..bdcc6053c74 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CultureShield.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CultureShield.cs @@ -4,7 +4,7 @@ using System.Globalization; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Class which can be used to encapsulate code statement(s) so that they are executed in a specific culture. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/AbstractCanvasBrushElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/AbstractCanvasBrushElement.cs index dd0e9c1f27f..6178802931c 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/AbstractCanvasBrushElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/AbstractCanvasBrushElement.cs @@ -1,13 +1,12 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas; using Microsoft.Graphics.Canvas.Brushes; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Core; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry.Elements.Brush +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Abstract base class for all Brush Elements diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/ICanvasBrushElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/ICanvasBrushElement.cs index 0e6bcea4202..c248ead83f0 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/ICanvasBrushElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/ICanvasBrushElement.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -6,7 +6,7 @@ using Microsoft.Graphics.Canvas; using Microsoft.Graphics.Canvas.Brushes; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry.Elements.Brush +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Interface for a Brush Element diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/LinearGradientBrushElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/LinearGradientBrushElement.cs index 412343ef16b..56a2ddc6454 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/LinearGradientBrushElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/LinearGradientBrushElement.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -9,11 +9,9 @@ using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas; using Microsoft.Graphics.Canvas.Brushes; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Core; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Parsers; using Windows.UI; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry.Elements.Brush +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Represents a CanvasLinearGradientBrush with GradientStops diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/LinearGradientHdrBrushElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/LinearGradientHdrBrushElement.cs index 1a348439fb2..3d1bbee13c6 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/LinearGradientHdrBrushElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/LinearGradientHdrBrushElement.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -9,9 +9,8 @@ using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas; using Microsoft.Graphics.Canvas.Brushes; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Core; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry.Elements.Brush +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Represents a CanvasLinearGradientBrush with GradientStopHdrs diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/RadialGradientBrushElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/RadialGradientBrushElement.cs index 9e47a089886..95dfbf6eb59 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/RadialGradientBrushElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/RadialGradientBrushElement.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -9,11 +9,9 @@ using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas; using Microsoft.Graphics.Canvas.Brushes; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Core; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Parsers; using Windows.UI; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry.Elements.Brush +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Represents a CanvasRadialGradientBrush with GradientStops diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/RadialGradientHdrBrushElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/RadialGradientHdrBrushElement.cs index e1143d38eaf..463852211b2 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/RadialGradientHdrBrushElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/RadialGradientHdrBrushElement.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -9,9 +9,8 @@ using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas; using Microsoft.Graphics.Canvas.Brushes; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Core; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry.Elements.Brush +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Represents a CanvasRadialGradientBrush with GradientStopHdrs diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/SolidColorBrushElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/SolidColorBrushElement.cs index 7314835f7b9..c8bff2e287a 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/SolidColorBrushElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/SolidColorBrushElement.cs @@ -1,15 +1,13 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas; using Microsoft.Graphics.Canvas.Brushes; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Core; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Parsers; using Windows.UI; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry.Elements.Brush +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Represents a CanvasSolidColorBrush diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/AbstractPathElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/AbstractPathElement.cs index f6fb00c4f00..d37b2b30f9f 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/AbstractPathElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/AbstractPathElement.cs @@ -1,13 +1,12 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Numerics; using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Core; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry.Elements.Path +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Abstract base class for all Path Elements diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/ArcElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/ArcElement.cs index 9026d44f924..f490949316d 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/ArcElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/ArcElement.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -6,9 +6,8 @@ using System.Numerics; using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Core; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry.Elements.Path +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Class representing the Arc Element in a Path Geometry diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasEllipseFigure.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasEllipseFigure.cs index 7f07c806e40..5e1eb541326 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasEllipseFigure.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasEllipseFigure.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -6,9 +6,8 @@ using System.Numerics; using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Core; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry.Elements.Path +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Class representing the Ellipse Figure in a Path Geometry diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasPathFigure.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasPathFigure.cs index 63df1371edc..b471bb7e0a9 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasPathFigure.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasPathFigure.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -8,9 +8,8 @@ using System.Numerics; using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Core; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry.Elements.Path +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Class which contains a collection of ICanvasPathElements diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasPolygonFigure.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasPolygonFigure.cs index 806d1060385..ae640cffd6d 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasPolygonFigure.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasPolygonFigure.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -6,9 +6,8 @@ using System.Numerics; using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Core; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry.Elements.Path +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Class representing the Polygon Figure in a Path Geometry diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasRectangleFigure.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasRectangleFigure.cs index c691fee2602..d197a557a70 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasRectangleFigure.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasRectangleFigure.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -6,9 +6,8 @@ using System.Numerics; using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Core; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry.Elements.Path +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Class representing the Rectangle Figure in a Path Geometry diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasRoundRectangleFigure.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasRoundRectangleFigure.cs index f9fa6027f8a..aa676571dd3 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasRoundRectangleFigure.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasRoundRectangleFigure.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -6,9 +6,8 @@ using System.Numerics; using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Core; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry.Elements.Path +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Class representing the RoundRectangle Figure in a Path Geometry diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/ClosePathElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/ClosePathElement.cs index 61ffb6255bb..8d40f6ef2aa 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/ClosePathElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/ClosePathElement.cs @@ -1,13 +1,12 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Numerics; using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Core; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry.Elements.Path +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Class representing the ClosePath command in a Path Geometry diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CubicBezierElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CubicBezierElement.cs index 282d7740b22..b4e4b9243b6 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CubicBezierElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CubicBezierElement.cs @@ -1,13 +1,12 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Numerics; using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Core; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry.Elements.Path +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Class representing the Cubic Bezier Element in a Path Geometry diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/FillRuleElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/FillRuleElement.cs index 897219f3401..dcb9dcba1cd 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/FillRuleElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/FillRuleElement.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -7,7 +7,7 @@ using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry.Elements.Path +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Class representing the Fill Rule Element in a Path Geometry diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/HorizontalLineElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/HorizontalLineElement.cs index 4b98fcc0d59..d96ffa5d6c1 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/HorizontalLineElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/HorizontalLineElement.cs @@ -1,13 +1,12 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Numerics; using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Core; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry.Elements.Path +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Class representing the Horizontal Line Element in a Path Geometry diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/ICanvasPathElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/ICanvasPathElement.cs index c42c4e09973..63e32e93700 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/ICanvasPathElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/ICanvasPathElement.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -6,7 +6,7 @@ using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry.Elements.Path +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Interface for a Path Element which serves diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/LineElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/LineElement.cs index 186b63f18cd..bbc7a0a03c0 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/LineElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/LineElement.cs @@ -1,13 +1,12 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Numerics; using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Core; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry.Elements.Path +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Class representing the Line Element in a Path Geometry diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/MoveToElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/MoveToElement.cs index 29d85724ecd..541604c6582 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/MoveToElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/MoveToElement.cs @@ -1,13 +1,12 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Numerics; using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Core; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry.Elements.Path +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Class representing the MoveTo Command in a Path Geometry diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/QuadraticBezierElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/QuadraticBezierElement.cs index d697610ae75..feba2f290b7 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/QuadraticBezierElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/QuadraticBezierElement.cs @@ -1,13 +1,12 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Numerics; using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Core; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry.Elements.Path +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Class representing the Quadratic Bezier Element in a Path Geometry diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/SmoothCubicBezierElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/SmoothCubicBezierElement.cs index 6c6c820966d..87a66bcdf01 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/SmoothCubicBezierElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/SmoothCubicBezierElement.cs @@ -1,13 +1,12 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Numerics; using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Core; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry.Elements.Path +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Class representing the Smooth Cubic Bezier Element in a Path Geometry diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/SmoothQuadraticBezierElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/SmoothQuadraticBezierElement.cs index 444a3262e14..97a0fd7bc7d 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/SmoothQuadraticBezierElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/SmoothQuadraticBezierElement.cs @@ -1,13 +1,12 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Numerics; using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Core; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry.Elements.Path +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Class representing the Smooth Quadratic Bezier Element in a Path Geometry diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/VerticalLineElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/VerticalLineElement.cs index 2b06607c4c7..1a1c72cb53d 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/VerticalLineElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/VerticalLineElement.cs @@ -1,13 +1,12 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Numerics; using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Core; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry.Elements.Path +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Class representing the Vertical Line Element in a Path Geometry diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/AbstractCanvasStrokeElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/AbstractCanvasStrokeElement.cs index ce2e8f4f2c6..ee01409b48e 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/AbstractCanvasStrokeElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/AbstractCanvasStrokeElement.cs @@ -1,12 +1,11 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Core; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry.Elements.Stroke +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Abstract base class for Stroke Element. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/CanvasStrokeElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/CanvasStrokeElement.cs index 419dc1f4269..8d56f992234 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/CanvasStrokeElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/CanvasStrokeElement.cs @@ -1,15 +1,12 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Core; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Elements.Brush; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Parsers; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry.Elements.Stroke +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Represents a Stroke Element. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/CanvasStrokeStyleElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/CanvasStrokeStyleElement.cs index 79e2d396d15..f3994deeb23 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/CanvasStrokeStyleElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/CanvasStrokeStyleElement.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -7,9 +7,8 @@ using System.Linq; using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Core; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry.Elements.Stroke +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Represents a CanvasStrokeStyle Element. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/ICanvasStrokeElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/ICanvasStrokeElement.cs index 4cec2b20473..fb55dc3c192 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/ICanvasStrokeElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/ICanvasStrokeElement.cs @@ -1,11 +1,11 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry.Elements.Stroke +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Interface for Stroke Element diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/ICanvasStrokeStyleElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/ICanvasStrokeStyleElement.cs index 5a7fee6e268..61d5562d71a 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/ICanvasStrokeStyleElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/ICanvasStrokeStyleElement.cs @@ -1,11 +1,11 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry.Elements.Stroke +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Interface for the CanvasStrokeStyle Element diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/ICanvasPathGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/ICanvasPathGeometry.cs index 0c79a1cee5c..83fc9e94846 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/ICanvasPathGeometry.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/ICanvasPathGeometry.cs @@ -1,6 +1,6 @@ -using Microsoft.Graphics.Canvas.Geometry; +using Microsoft.Graphics.Canvas.Geometry; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry +namespace Microsoft.Toolkit.Uwp.UI.Media { internal interface ICanvasPathGeometry { diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/ICanvasStroke.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/ICanvasStroke.cs index e4209e85dcf..3620d127840 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/ICanvasStroke.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/ICanvasStroke.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -6,7 +6,7 @@ using Microsoft.Graphics.Canvas.Brushes; using Microsoft.Graphics.Canvas.Geometry; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Interface to represent the Stroke which can be used to render an outline on a . diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasBrushParser.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasBrushParser.cs index 6f63b4cb518..b89f2442a93 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasBrushParser.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasBrushParser.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -6,10 +6,8 @@ using System.Runtime.CompilerServices; using Microsoft.Graphics.Canvas; using Microsoft.Graphics.Canvas.Brushes; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Core; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Elements.Brush; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry.Parsers +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Parser for ICanvasBrush. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasGeometryParser.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasGeometryParser.cs index f47b47a72c6..690ff25a61e 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasGeometryParser.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasGeometryParser.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -10,10 +10,8 @@ using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas; using Microsoft.Graphics.Canvas.Geometry; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Core; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Elements.Path; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry.Parsers +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Parser for CanvasGeometry. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasStrokeParser.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasStrokeParser.cs index 9f91969fb27..8764016f074 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasStrokeParser.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasStrokeParser.cs @@ -1,14 +1,12 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Runtime.CompilerServices; using Microsoft.Graphics.Canvas; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Core; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Elements.Stroke; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry.Parsers +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Parser for CanvasStroke diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasStrokeStyleParser.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasStrokeStyleParser.cs index c0418ee5619..46975902086 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasStrokeStyleParser.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasStrokeStyleParser.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -6,10 +6,8 @@ using System.Runtime.CompilerServices; using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Core; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Elements.Stroke; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry.Parsers +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Parser for the CanvasStrokeStyle diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/ColorParser.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/ColorParser.cs index 3bc1955d473..3abb0b9cb77 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/ColorParser.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/ColorParser.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -6,10 +6,9 @@ using System.Numerics; using System.Runtime.CompilerServices; using System.Text.RegularExpressions; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Core; using Windows.UI; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry.Parsers +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Parser for Color diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Scalar.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Scalar.cs index e93b1b62af7..d1b561c0ddf 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Scalar.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Scalar.cs @@ -1,10 +1,10 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Class containing some constants diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/StrokeStyle.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/StrokeStyle.cs index 94c585f4648..6115d073d3a 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/StrokeStyle.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/StrokeStyle.cs @@ -1,16 +1,22 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using Microsoft.Graphics.Canvas.Geometry; using Windows.UI.Xaml; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry +namespace Microsoft.Toolkit.Uwp.UI.Media { + /// + /// Class which defines various properties which govern how the stroke is rendered. + /// public class StrokeStyle : DependencyObject, IDisposable { private bool _disposedValue; private CanvasStrokeStyle _canvasStrokeStyle; + /// + /// Event to notify that the properties of this class have been updated. + /// public event EventHandler Updated; /// @@ -84,6 +90,9 @@ private void OnCustomDashStyleChanged() OnUpdated(); } + /// + /// Gets the custom dash style parsed from the input string. + /// public float[] ParsedCustomDashStyle { get; private set; } = null; /// @@ -262,6 +271,9 @@ private void OnUpdated() Updated?.Invoke(this, null); } + /// + /// Initializes a new instance of the class. + /// public StrokeStyle() { ParsedCustomDashStyle = new float[0]; @@ -282,6 +294,7 @@ private void Dispose(bool disposing) } } + /// public void Dispose() { // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method @@ -289,6 +302,10 @@ public void Dispose() GC.SuppressFinalize(this); } + /// + /// Gets the CanvasStrokeStyle. + /// + /// public CanvasStrokeStyle GetCanvasStrokeStyle() { return _canvasStrokeStyle; diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Utils.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Utils.cs index fe42ae27fad..b70af44d163 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Utils.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Utils.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -9,7 +9,7 @@ using Windows.UI.Xaml; using Windows.UI.Xaml.Media; -namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Class containing collection of useful methods for various types diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionExtensions.cs index 2c92f4f3f8e..c3c3600a91e 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionExtensions.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -11,7 +11,7 @@ using Windows.UI.Xaml; using Windows.UI.Xaml.Media; -namespace Microsoft.Toolkit.Uwp.UI.Media.Surface +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Extension Methods for Compositor diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs index e1448f28b7f..adfca4fcf53 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -11,14 +11,14 @@ using Microsoft.Graphics.Canvas.Effects; using Microsoft.Graphics.Canvas.Geometry; using Microsoft.Graphics.Canvas.UI.Composition; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry; +using Microsoft.Toolkit.Uwp.UI.Media; using Windows.Foundation; using Windows.Graphics.DirectX; using Windows.UI; using Windows.UI.Composition; using Windows.UI.Xaml; -namespace Microsoft.Toolkit.Uwp.UI.Media.Surface +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Core class which is used to create various RenderSurfaces like GeometrySurface, GeometryMaskSurface, GaussianMaskSurface, ImageSurface, ImageMaskSurface diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositorExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositorExtensions.cs index a45f72e130e..360c9a4e38d 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositorExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositorExtensions.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -6,7 +6,7 @@ using System.Numerics; using Windows.UI.Composition; -namespace Microsoft.Toolkit.Uwp.UI.Media.Surface +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Extension methods for Windows.UI.Composition.Compositor diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/GaussianMaskSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/GaussianMaskSurface.cs index c9c3dfd193a..6b33e622fb4 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/GaussianMaskSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/GaussianMaskSurface.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -8,7 +8,7 @@ using Windows.Foundation; using Windows.UI.Composition; -namespace Microsoft.Toolkit.Uwp.UI.Media.Surface +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Class for rendering custom shaped geometries onto ICompositionSurface diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometryMaskSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometryMaskSurface.cs index 07893cb7469..840b9cff35b 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometryMaskSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometryMaskSurface.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -8,7 +8,7 @@ using Windows.Foundation; using Windows.UI.Composition; -namespace Microsoft.Toolkit.Uwp.UI.Media.Surface +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Class for rendering custom shaped geometries onto ICompositionSurface so that they can be used as masks on Composition Visuals. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometrySurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometrySurface.cs index 9cbfe29283e..d945c05276f 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometrySurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometrySurface.cs @@ -1,16 +1,15 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using Microsoft.Graphics.Canvas.Brushes; using Microsoft.Graphics.Canvas.Geometry; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry; using Windows.Foundation; using Windows.UI; using Windows.UI.Composition; -namespace Microsoft.Toolkit.Uwp.UI.Media.Surface +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Class for rendering custom shaped geometries onto ICompositionSurface diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageMaskSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageMaskSurface.cs index d71adfc3420..b0e30081582 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageMaskSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageMaskSurface.cs @@ -1,16 +1,15 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Threading.Tasks; using Microsoft.Graphics.Canvas; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry; using Windows.Foundation; using Windows.UI.Composition; using Windows.UI.Xaml; -namespace Microsoft.Toolkit.Uwp.UI.Media.Surface +namespace Microsoft.Toolkit.Uwp.UI.Media { internal sealed class ImageMaskSurface : IImageMaskSurface { diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurface.cs index f701a71d145..7fa11785817 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurface.cs @@ -1,15 +1,14 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Threading.Tasks; using Microsoft.Graphics.Canvas; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry; using Windows.Foundation; using Windows.UI.Composition; -namespace Microsoft.Toolkit.Uwp.UI.Media.Surface +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Class for rendering an image onto a ICompositionSurface diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurfaceOptions.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurfaceOptions.cs index b31df504527..64ab57f981b 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurfaceOptions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurfaceOptions.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -8,7 +8,7 @@ using Windows.UI.Xaml; using Windows.UI.Xaml.Media; -namespace Microsoft.Toolkit.Uwp.UI.Media.Surface +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Enum to define the location of the @@ -43,6 +43,9 @@ public enum ReflectionLocation /// public class ImageSurfaceOptions : DependencyObject { + /// + /// Event which indicates that the components of the have changed. + /// public event EventHandler Updated; /// @@ -187,7 +190,6 @@ public AlignmentX HorizontalAlignment /// Gets or sets a value describing how image is positioned vertically in the IImageSurface or IImageMaskSurface. /// NOTE: This property is taken into consideration only if AutoResize is False. /// - /// public AlignmentY VerticalAlignment { get => (AlignmentY)GetValue(VerticalAlignmentProperty); diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/ICompositionGenerator.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/ICompositionGenerator.cs index 0c252bcd090..1cf75f77ca2 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/ICompositionGenerator.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/ICompositionGenerator.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -8,13 +8,12 @@ using Microsoft.Graphics.Canvas; using Microsoft.Graphics.Canvas.Brushes; using Microsoft.Graphics.Canvas.Geometry; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry; using Windows.Foundation; using Windows.UI; using Windows.UI.Composition; using Windows.UI.Xaml; -namespace Microsoft.Toolkit.Uwp.UI.Media.Surface +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Interface for the ComposiitonGenerator diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/ICompositionGeneratorInternal.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/ICompositionGeneratorInternal.cs index c41552ad8f8..cdb5c6e9777 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/ICompositionGeneratorInternal.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/ICompositionGeneratorInternal.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -8,12 +8,11 @@ using Microsoft.Graphics.Canvas; using Microsoft.Graphics.Canvas.Brushes; using Microsoft.Graphics.Canvas.Geometry; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry; using Windows.Foundation; using Windows.UI.Composition; using Windows.UI.Xaml; -namespace Microsoft.Toolkit.Uwp.UI.Media.Surface +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Internal interface for the ComposiitonGenerator diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IGaussianMaskSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IGaussianMaskSurface.cs index 25ad3ddfa54..f8a4bf93b97 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IGaussianMaskSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IGaussianMaskSurface.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -6,7 +6,7 @@ using Microsoft.Graphics.Canvas.Geometry; using Windows.Foundation; -namespace Microsoft.Toolkit.Uwp.UI.Media.Surface +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Interface for rendering custom shaped geometries onto ICompositionSurface so that they can be used as masks on Composition Visuals. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IGeometryMaskSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IGeometryMaskSurface.cs index d2b6c5d4540..5a59892e4a6 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IGeometryMaskSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IGeometryMaskSurface.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -6,7 +6,7 @@ using Microsoft.Graphics.Canvas.Geometry; using Windows.Foundation; -namespace Microsoft.Toolkit.Uwp.UI.Media.Surface +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Interface for rendering custom shaped geometries onto ICompositionSurface so that they can be used as masks on Composition Visuals. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IGeometrySurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IGeometrySurface.cs index 0eef7993208..491fc332830 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IGeometrySurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IGeometrySurface.cs @@ -1,14 +1,13 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using Microsoft.Graphics.Canvas.Brushes; using Microsoft.Graphics.Canvas.Geometry; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry; using Windows.Foundation; using Windows.UI; -namespace Microsoft.Toolkit.Uwp.UI.Media.Surface +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Interface for rendering custom shaped geometries onto ICompositionSurface. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IImageMaskSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IImageMaskSurface.cs index eb46492d421..8c32c466a7b 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IImageMaskSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IImageMaskSurface.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -8,7 +8,7 @@ using Windows.Foundation; using Windows.UI.Xaml; -namespace Microsoft.Toolkit.Uwp.UI.Media.Surface +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Interface for rendering a mask, using an Image's alpha values, onto an ICompositionSurface. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IImageSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IImageSurface.cs index 08356ad428a..6c7b78745d5 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IImageSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IImageSurface.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -7,7 +7,7 @@ using Microsoft.Graphics.Canvas; using Windows.Foundation; -namespace Microsoft.Toolkit.Uwp.UI.Media.Surface +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Enumeration to describe the status of the loading of an image on the IImageSurface. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IRenderSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IRenderSurface.cs index d91af826f2d..99e48a90fee 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IRenderSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IRenderSurface.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -6,7 +6,7 @@ using Windows.Foundation; using Windows.UI.Composition; -namespace Microsoft.Toolkit.Uwp.UI.Media.Surface +namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Represents the core interface for interfaces which render onto ICompositionSurface. diff --git a/UnitTests/UnitTests.UWP/Geometry/Test_CanvasPathGeometry.cs b/UnitTests/UnitTests.UWP/Geometry/Test_CanvasPathGeometry.cs index b82dc9d0865..986b67f4fe0 100644 --- a/UnitTests/UnitTests.UWP/Geometry/Test_CanvasPathGeometry.cs +++ b/UnitTests/UnitTests.UWP/Geometry/Test_CanvasPathGeometry.cs @@ -6,7 +6,7 @@ using System.Numerics; using Microsoft.Graphics.Canvas; using Microsoft.Graphics.Canvas.Geometry; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry; +using Microsoft.Toolkit.Uwp.UI.Media; using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting.AppContainer; diff --git a/UnitTests/UnitTests.UWP/Geometry/Test_RegexFactory.cs b/UnitTests/UnitTests.UWP/Geometry/Test_RegexFactory.cs index 69b7cb0f0b8..a93ef0f1a2c 100644 --- a/UnitTests/UnitTests.UWP/Geometry/Test_RegexFactory.cs +++ b/UnitTests/UnitTests.UWP/Geometry/Test_RegexFactory.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using Microsoft.Toolkit.Uwp.UI.Media.Geometry.Core; +using Microsoft.Toolkit.Uwp.UI.Media; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace UnitTests.UWP.Geometry diff --git a/UnitTests/UnitTests.UWP/Geometry/Test_Utils.cs b/UnitTests/UnitTests.UWP/Geometry/Test_Utils.cs index 80dde13c7aa..c2122064578 100644 --- a/UnitTests/UnitTests.UWP/Geometry/Test_Utils.cs +++ b/UnitTests/UnitTests.UWP/Geometry/Test_Utils.cs @@ -8,7 +8,7 @@ using Windows.UI; using Windows.UI.Xaml; using Windows.UI.Xaml.Media; -using Microsoft.Toolkit.Uwp.UI.Media.Geometry; +using Microsoft.Toolkit.Uwp.UI.Media; using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting.AppContainer; From fc4434d10a05ef19e19338ddd1a4118ec67138d5 Mon Sep 17 00:00:00 2001 From: Ratish Philip Date: Sun, 20 Jun 2021 20:39:19 -0700 Subject: [PATCH 10/21] Initial commit for GeometrySurfaceBrush sample application. --- .../Microsoft.Toolkit.Uwp.SampleApp.csproj | 11 ++++- .../GeometryMaskSurface.png | Bin 4651 -> 0 bytes .../GeometryMaskSurfacePage.xaml | 24 ---------- .../GeometrySurfaceBrush.png | Bin 0 -> 4390 bytes .../GeometrySurfaceBrushPage.xaml | 44 ++++++++++++++++++ .../GeometrySurfaceBrushPage.xaml.cs} | 9 ++-- .../GeometrySurfaceBrushXaml.bind | 1 + 7 files changed, 58 insertions(+), 31 deletions(-) delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurface.png delete mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurfacePage.xaml create mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrush.png create mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushPage.xaml rename Microsoft.Toolkit.Uwp.SampleApp/SamplePages/{GeometryMaskSurfaceBrush/GeometryMaskSurfacePage.xaml.cs => GeometrySurfaceBrush/GeometrySurfaceBrushPage.xaml.cs} (69%) create mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushXaml.bind diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj b/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj index d61626fda16..0c36de28426 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj +++ b/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj @@ -1,4 +1,4 @@ - + Debug @@ -274,6 +274,7 @@ PreserveNewest + @@ -506,6 +507,9 @@ FocusBehaviorPage.xaml + + GeometrySurfaceBrushPage.xaml + TilesBrushPage.xaml @@ -621,6 +625,7 @@ + @@ -973,6 +978,10 @@ Designer + + Designer + MSBuild:Compile + MSBuild:Compile Designer diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurface.png b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurface.png deleted file mode 100644 index 5c909a581e1e9abc021a85b6bb5d643b4e198d42..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4651 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 diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurfacePage.xaml b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurfacePage.xaml deleted file mode 100644 index bb2236f19ba..00000000000 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurfacePage.xaml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrush.png b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrush.png new file mode 100644 index 0000000000000000000000000000000000000000..7ba968db96973c9ef2279d6d7419ca91e029d293 GIT binary patch literal 4390 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 literal 0 HcmV?d00001 diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushPage.xaml b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushPage.xaml new file mode 100644 index 00000000000..74156b35040 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushPage.xaml @@ -0,0 +1,44 @@ + + + + + + + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurfacePage.xaml.cs b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushPage.xaml.cs similarity index 69% rename from Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurfacePage.xaml.cs rename to Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushPage.xaml.cs index 04c5a3c8d39..06d3e2371e4 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurfacePage.xaml.cs +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushPage.xaml.cs @@ -15,17 +15,14 @@ // The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238 -namespace Microsoft.Toolkit.Uwp.SampleApp.SamplePages.GeometryMaskSurfaceBrush +namespace Microsoft.Toolkit.Uwp.SampleApp.SamplePages.GeometrySurfaceBrush { /// /// An empty page that can be used on its own or navigated to within a Frame. /// - public sealed partial class GeometryMaskSurfacePage : Page + public sealed partial class GeometrySurfaceBrushPage : Page { - /// - /// Initializes a new instance of the class. - /// - public GeometryMaskSurfacePage() + public GeometrySurfaceBrushPage() { this.InitializeComponent(); } diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushXaml.bind new file mode 100644 index 00000000000..5f282702bb0 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushXaml.bind @@ -0,0 +1 @@ + \ No newline at end of file From 098759d0c1999031aa72aa990cf65aaade5a8e5e Mon Sep 17 00:00:00 2001 From: Ratish Philip Date: Sat, 10 Jul 2021 06:22:26 -0700 Subject: [PATCH 11/21] Working GeometrySurfaceBrush sample. --- .../Microsoft.Toolkit.Uwp.SampleApp.csproj | 5 +- .../Models/Sample.cs | 297 +++++++++--------- .../GeometrySurfaceBrushPage.xaml | 24 +- .../GeometrySurfaceBrushPage.xaml.cs | 5 +- .../GeometrySurfaceBrushXaml.bind | 44 ++- .../SamplePages/samples.json | 10 + 6 files changed, 224 insertions(+), 161 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj b/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj index ccd10556da1..a678cf58a7e 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj +++ b/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj @@ -630,7 +630,7 @@ - + @@ -994,6 +994,9 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile Designer diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Models/Sample.cs b/Microsoft.Toolkit.Uwp.SampleApp/Models/Sample.cs index f57a430d307..d8c8872674d 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/Models/Sample.cs +++ b/Microsoft.Toolkit.Uwp.SampleApp/Models/Sample.cs @@ -474,188 +474,195 @@ public async Task PreparePropertyDescriptorAsync() if (_propertyDescriptor == null) { - // Get Xaml code - using (var codeStream = await StreamHelper.GetPackagedFileStreamAsync(XamlCodeFile.StartsWith('/') ? XamlCodeFile : $"SamplePages/{Name}/{XamlCodeFile}")) + try { - XamlCode = await codeStream.ReadTextAsync(Encoding.UTF8); + // Get Xaml code + using (var codeStream = await StreamHelper.GetPackagedFileStreamAsync(XamlCodeFile.StartsWith('/') ? XamlCodeFile : $"SamplePages/{Name}/{XamlCodeFile}")) + { + XamlCode = await codeStream.ReadTextAsync(Encoding.UTF8); - // Look for @[] values and generate associated properties - var regularExpression = new Regex("(?<=\\\")@\\[(?.+?)(:(?.+?):(?.+?)(:(?.+?))?(:(?.*))*)?\\]@?(?=\\\")"); + // Look for @[] values and generate associated properties + var regularExpression = new Regex("(?<=\\\")@\\[(?.+?)(:(?.+?):(?.+?)(:(?.+?))?(:(?.*))*)?\\]@?(?=\\\")"); - _propertyDescriptor = new PropertyDescriptor { Expando = new ExpandoObject() }; - var proxy = (IDictionary)_propertyDescriptor.Expando; + _propertyDescriptor = new PropertyDescriptor { Expando = new ExpandoObject() }; + var proxy = (IDictionary)_propertyDescriptor.Expando; - foreach (Match match in regularExpression.Matches(XamlCode)) - { - var label = match.Groups["name"].Value; - var name = label.Replace(" ", string.Empty); // Allow us to have nicer display names, but create valid properties. - var type = match.Groups["type"].Value; - var value = match.Groups["value"].Value; + foreach (Match match in regularExpression.Matches(XamlCode)) + { + var label = match.Groups["name"].Value; + var name = label.Replace(" ", string.Empty); // Allow us to have nicer display names, but create valid properties. + var type = match.Groups["type"].Value; + var value = match.Groups["value"].Value; - var existingOption = _propertyDescriptor.Options.Where(o => o.Name == name).FirstOrDefault(); + var existingOption = _propertyDescriptor.Options.Where(o => o.Name == name).FirstOrDefault(); - if (existingOption == null && string.IsNullOrWhiteSpace(type)) - { - throw new NotSupportedException($"Unrecognized short identifier '{name}'; Define type and parameters of property in first occurrence in {XamlCodeFile}."); - } + if (existingOption == null && string.IsNullOrWhiteSpace(type)) + { + throw new NotSupportedException($"Unrecognized short identifier '{name}'; Define type and parameters of property in first occurrence in {XamlCodeFile}."); + } - if (Enum.TryParse(type, out PropertyKind kind)) - { - if (existingOption != null) + if (Enum.TryParse(type, out PropertyKind kind)) { - if (existingOption.Kind != kind) + if (existingOption != null) { - throw new NotSupportedException($"Multiple options with same name but different type not supported: {XamlCodeFile}:{name}"); - } + if (existingOption.Kind != kind) + { + throw new NotSupportedException($"Multiple options with same name but different type not supported: {XamlCodeFile}:{name}"); + } - continue; - } + continue; + } - PropertyOptions options; + PropertyOptions options; - switch (kind) - { - case PropertyKind.Slider: - case PropertyKind.DoubleSlider: - try - { - var sliderOptions = new SliderPropertyOptions { DefaultValue = double.Parse(value, CultureInfo.InvariantCulture) }; - var parameters = match.Groups["parameters"].Value; - var split = parameters.Split('-'); - int minIndex = 0; - int minMultiplier = 1; - if (string.IsNullOrEmpty(split[0])) + switch (kind) + { + case PropertyKind.Slider: + case PropertyKind.DoubleSlider: + try { - minIndex = 1; - minMultiplier = -1; + var sliderOptions = new SliderPropertyOptions { DefaultValue = double.Parse(value, CultureInfo.InvariantCulture) }; + var parameters = match.Groups["parameters"].Value; + var split = parameters.Split('-'); + int minIndex = 0; + int minMultiplier = 1; + if (string.IsNullOrEmpty(split[0])) + { + minIndex = 1; + minMultiplier = -1; + } + + sliderOptions.MinValue = minMultiplier * double.Parse(split[minIndex], CultureInfo.InvariantCulture); + sliderOptions.MaxValue = double.Parse(split[minIndex + 1], CultureInfo.InvariantCulture); + if (split.Length > 2 + minIndex) + { + sliderOptions.Step = double.Parse(split[split.Length - 1], CultureInfo.InvariantCulture); + } + + options = sliderOptions; } - - sliderOptions.MinValue = minMultiplier * double.Parse(split[minIndex], CultureInfo.InvariantCulture); - sliderOptions.MaxValue = double.Parse(split[minIndex + 1], CultureInfo.InvariantCulture); - if (split.Length > 2 + minIndex) + catch (Exception ex) { - sliderOptions.Step = double.Parse(split[split.Length - 1], CultureInfo.InvariantCulture); + Debug.WriteLine($"Unable to extract slider info from {value}({ex.Message})"); + TrackingManager.TrackException(ex); + continue; } - options = sliderOptions; - } - catch (Exception ex) - { - Debug.WriteLine($"Unable to extract slider info from {value}({ex.Message})"); - TrackingManager.TrackException(ex); - continue; - } - - break; + break; - case PropertyKind.TimeSpan: - try - { - var sliderOptions = new SliderPropertyOptions { DefaultValue = TimeSpan.FromMilliseconds(double.Parse(value, CultureInfo.InvariantCulture)) }; - var parameters = match.Groups["parameters"].Value; - var split = parameters.Split('-'); - int minIndex = 0; - int minMultiplier = 1; - if (string.IsNullOrEmpty(split[0])) + case PropertyKind.TimeSpan: + try { - minIndex = 1; - minMultiplier = -1; + var sliderOptions = new SliderPropertyOptions { DefaultValue = TimeSpan.FromMilliseconds(double.Parse(value, CultureInfo.InvariantCulture)) }; + var parameters = match.Groups["parameters"].Value; + var split = parameters.Split('-'); + int minIndex = 0; + int minMultiplier = 1; + if (string.IsNullOrEmpty(split[0])) + { + minIndex = 1; + minMultiplier = -1; + } + + sliderOptions.MinValue = minMultiplier * double.Parse(split[minIndex], CultureInfo.InvariantCulture); + sliderOptions.MaxValue = double.Parse(split[minIndex + 1], CultureInfo.InvariantCulture); + if (split.Length > 2 + minIndex) + { + sliderOptions.Step = double.Parse(split[split.Length - 1], CultureInfo.InvariantCulture); + } + + options = sliderOptions; } - - sliderOptions.MinValue = minMultiplier * double.Parse(split[minIndex], CultureInfo.InvariantCulture); - sliderOptions.MaxValue = double.Parse(split[minIndex + 1], CultureInfo.InvariantCulture); - if (split.Length > 2 + minIndex) + catch (Exception ex) { - sliderOptions.Step = double.Parse(split[split.Length - 1], CultureInfo.InvariantCulture); + Debug.WriteLine($"Unable to extract slider info from {value}({ex.Message})"); + TrackingManager.TrackException(ex); + continue; } - options = sliderOptions; - } - catch (Exception ex) - { - Debug.WriteLine($"Unable to extract slider info from {value}({ex.Message})"); - TrackingManager.TrackException(ex); - continue; - } - - break; + break; - case PropertyKind.Enum: - try - { - options = new PropertyOptions(); - var split = value.Split('.'); - var typeName = string.Join(".", split.Take(split.Length - 1)); - var enumType = LookForTypeByName(typeName); - options.DefaultValue = Enum.Parse(enumType, split.Last()); - } - catch (Exception ex) - { - Debug.WriteLine($"Unable to parse enum from {value}({ex.Message})"); - TrackingManager.TrackException(ex); - continue; - } + case PropertyKind.Enum: + try + { + options = new PropertyOptions(); + var split = value.Split('.'); + var typeName = string.Join(".", split.Take(split.Length - 1)); + var enumType = LookForTypeByName(typeName); + options.DefaultValue = Enum.Parse(enumType, split.Last()); + } + catch (Exception ex) + { + Debug.WriteLine($"Unable to parse enum from {value}({ex.Message})"); + TrackingManager.TrackException(ex); + continue; + } - break; + break; - case PropertyKind.Bool: - try - { - options = new PropertyOptions { DefaultValue = bool.Parse(value) }; - } - catch (Exception ex) - { - Debug.WriteLine($"Unable to parse bool from {value}({ex.Message})"); - continue; - } + case PropertyKind.Bool: + try + { + options = new PropertyOptions { DefaultValue = bool.Parse(value) }; + } + catch (Exception ex) + { + Debug.WriteLine($"Unable to parse bool from {value}({ex.Message})"); + continue; + } - break; + break; - case PropertyKind.Brush: - try - { - options = new PropertyOptions { DefaultValue = value }; - } - catch (Exception ex) - { - Debug.WriteLine($"Unable to parse bool from {value}({ex.Message})"); - TrackingManager.TrackException(ex); - continue; - } + case PropertyKind.Brush: + try + { + options = new PropertyOptions { DefaultValue = value }; + } + catch (Exception ex) + { + Debug.WriteLine($"Unable to parse bool from {value}({ex.Message})"); + TrackingManager.TrackException(ex); + continue; + } - break; + break; - case PropertyKind.Thickness: - try - { - var thicknessOptions = new ThicknessPropertyOptions { DefaultValue = value }; - options = thicknessOptions; - } - catch (Exception ex) - { - Debug.WriteLine($"Unable to extract slider info from {value}({ex.Message})"); - TrackingManager.TrackException(ex); - continue; - } + case PropertyKind.Thickness: + try + { + var thicknessOptions = new ThicknessPropertyOptions { DefaultValue = value }; + options = thicknessOptions; + } + catch (Exception ex) + { + Debug.WriteLine($"Unable to extract slider info from {value}({ex.Message})"); + TrackingManager.TrackException(ex); + continue; + } - break; + break; - default: - options = new PropertyOptions { DefaultValue = value }; - break; - } + default: + options = new PropertyOptions { DefaultValue = value }; + break; + } - options.Label = label; - options.Name = name; - options.OriginalString = match.Value; - options.Kind = kind; - options.IsTwoWayBinding = options.OriginalString.EndsWith("@"); - proxy[name] = new ValueHolder(options.DefaultValue); + options.Label = label; + options.Name = name; + options.OriginalString = match.Value; + options.Kind = kind; + options.IsTwoWayBinding = options.OriginalString.EndsWith("@"); + proxy[name] = new ValueHolder(options.DefaultValue); - _propertyDescriptor.Options.Add(options); + _propertyDescriptor.Options.Add(options); + } } } } + catch (Exception e) + { + var msg = e.Message; + } } } diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushPage.xaml b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushPage.xaml index 74156b35040..37f614dbda2 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushPage.xaml +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushPage.xaml @@ -1,4 +1,4 @@ - - + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushPage.xaml.cs b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushPage.xaml.cs index 06d3e2371e4..f9c1efdaf7c 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushPage.xaml.cs +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushPage.xaml.cs @@ -1,8 +1,9 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices.WindowsRuntime; +using Microsoft.Toolkit.Uwp.UI.Media; using Windows.Foundation; using Windows.Foundation.Collections; using Windows.UI.Xaml; @@ -15,7 +16,7 @@ // The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238 -namespace Microsoft.Toolkit.Uwp.SampleApp.SamplePages.GeometrySurfaceBrush +namespace Microsoft.Toolkit.Uwp.SampleApp.SamplePages { /// /// An empty page that can be used on its own or navigated to within a Frame. diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushXaml.bind index 5f282702bb0..27b3be3bcd9 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushXaml.bind +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushXaml.bind @@ -1 +1,43 @@ - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json index 437e8a44333..088e8816971 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json @@ -1093,6 +1093,16 @@ "Icon": "/SamplePages/TilesBrush/TilesBrush.png", "ApiCheck": "Windows.UI.Xaml.Media.XamlCompositionBrushBase", "DocumentationUrl": "https://raw.githubusercontent.com/MicrosoftDocs/WindowsCommunityToolkitDocs/master/docs/brushes/TilesBrush.md" + }, + { + "Name": "GeometrySurfaceBrush", + "Type": "GeometrySurfaceBrushPage", + "About": "Brush which fills the contents with a CanvasCoreGeometry.", + "CodeUrl": "https://github.com/ratishphilip/WindowsCommunityToolkit/tree/feature/rendersurfaces/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometrySurfaceBrush.cs", + "XamlCodeFile": "GeometrySurfaceBrushXaml.bind", + "Icon": "/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrush.png", + "ApiCheck": "Windows.UI.Xaml.Media.XamlCompositionBrushBase", + "DocumentationUrl": "https://raw.githubusercontent.com/MicrosoftDocs/WindowsCommunityToolkitDocs/master/docs/brushes/BackdropBlurBrush.md" } ] }, From 979ce760b15aed6e85430d673b6afb2ac1bda775 Mon Sep 17 00:00:00 2001 From: Ratish Philip Date: Wed, 14 Jul 2021 16:18:54 -0700 Subject: [PATCH 12/21] Created samples for Surface Brushes. --- .../Microsoft.Toolkit.Uwp.SampleApp.csproj | 33 ++++- .../GeometryMaskSurfaceBrush.png | Bin 0 -> 2280 bytes .../GeometryMaskSurfaceBrushPage.xaml | 30 ++++ .../GeometryMaskSurfaceBrushPage.xaml.cs | 16 +++ .../GeometryMaskSurfaceBrushXaml.bind | 29 ++++ .../GeometrySurfaceBrushPage.xaml.cs | 15 -- .../GeometrySurfaceBrushXaml.bind | 23 ++- .../ImageMaskSurfaceBrush.png | Bin 0 -> 9277 bytes .../ImageMaskSurfaceBrushPage.xaml | 131 ++++++++++++++++++ .../ImageMaskSurfaceBrushPage.xaml.cs | 112 +++++++++++++++ .../ImageMaskSurfaceBrushXaml.bind | 22 +++ .../ImageMaskSurfaceBrush/MaskImage1.png | Bin 0 -> 431997 bytes .../ImageMaskSurfaceBrush/MaskImage2.png | Bin 0 -> 258391 bytes .../ImageMaskSurfaceBrush/MaskImage3.png | Bin 0 -> 330878 bytes .../ImageSurfaceBrush/ImageSurfaceBrush.png | Bin 0 -> 3688 bytes .../ImageSurfaceBrushPage.xaml | 68 +++++++++ .../ImageSurfaceBrushPage.xaml.cs | 88 ++++++++++++ .../ImageSurfaceBrushXaml.bind | 22 +++ .../SamplePages/samples.json | 30 ++++ .../Brushes/ImageMaskSurfaceBrush.cs | 39 ++++-- .../Brushes/ImageSurfaceBrush.cs | 57 ++++++-- .../Surface/CompositionGenerator.cs | 4 +- 22 files changed, 665 insertions(+), 54 deletions(-) create mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurfaceBrush.png create mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurfaceBrushPage.xaml create mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurfaceBrushPage.xaml.cs create mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurfaceBrushXaml.bind create mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageMaskSurfaceBrush/ImageMaskSurfaceBrush.png create mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageMaskSurfaceBrush/ImageMaskSurfaceBrushPage.xaml create mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageMaskSurfaceBrush/ImageMaskSurfaceBrushPage.xaml.cs create mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageMaskSurfaceBrush/ImageMaskSurfaceBrushXaml.bind create mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageMaskSurfaceBrush/MaskImage1.png create mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageMaskSurfaceBrush/MaskImage2.png create mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageMaskSurfaceBrush/MaskImage3.png create mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageSurfaceBrush/ImageSurfaceBrush.png create mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageSurfaceBrush/ImageSurfaceBrushPage.xaml create mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageSurfaceBrush/ImageSurfaceBrushPage.xaml.cs create mode 100644 Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageSurfaceBrush/ImageSurfaceBrushXaml.bind diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj b/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj index a678cf58a7e..e9e16db9598 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj +++ b/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj @@ -274,10 +274,16 @@ PreserveNewest + + + + + + @@ -508,6 +514,15 @@ FocusBehaviorPage.xaml + + GeometryMaskSurfaceBrushPage.xaml + + + ImageMaskSurfaceBrushPage.xaml + + + ImageSurfaceBrushPage.xaml + MetadataControlPage.xaml @@ -631,6 +646,9 @@ + + + @@ -979,6 +997,18 @@ Designer + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + Designer MSBuild:Compile @@ -994,9 +1024,6 @@ Designer MSBuild:Compile - - Designer - MSBuild:Compile Designer diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurfaceBrush.png b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurfaceBrush.png new file mode 100644 index 0000000000000000000000000000000000000000..44a3b5ff8369810fe44ef66ff5bd1001383dd505 GIT binary patch literal 2280 zcmai#XHXN`5`e=MkxoD%ARxs-q=gbeBoLz@h#*0V(nAd)G{a3O5{hW(qEC?$q=^)T z&Tn0=%br0RVu2>2)J3 z0Dwc5ZNKB@V#`;REfltrz+JP$SqGwUA#OolfGeJX?q0H{{%+o0R$gwNVb~5YeE@(v z(bVXQP3Y$z<5$p5?HpWR6BdX36_T+$LvofU_@oCPY>C7#zMmMeY-~Oimysr>dh0rR zp!T}*NQ-?yI9d{uIfOMsJk2kp1qam~BYVcnJxL*V|T@4rj zU6jtq&E=~Hf#^eI$7aLI8(3WvsmP$f1Wc>{+6hj!iCC!@O0NBn;Ui?;Cu>btXCX1P~q#_~V!01i~Q_$-5aD znK^<3kO8;IfZpB`M&GDJLt~>M63M>E_r_Me^1DC~sd4w)+A7;KPWkXq6J1j4IyI ztq)U{5+#y56A#VQh=|&yPm{d4w()x_8wi*!p=r}ceqI=!@D{h`KEF1*Z}ve9 zSgKpeH`UB!Fb)pF=U-;aN0)s1!=ZnzI}++CfP-y3>Yv^*P)7Oy;hyJ@Ub?Xo=nD>4 zX4E=Dubk%KyeS~Z34Eue6d{alDlYa8_Q9ZB{WsGEOeJJwpu)=&sV)Fp@jbfC(W#JR zK#VqShXy#^cl_8tCC?;DI5{?!aVE+BGNssa(Ow^&77L zLCH+*Z(migR>gvHt zME&O8vt#Y_w7`RR!k_aHs0w0~6bm)Keb(eL@nBD=_8?MI8)A#c;|=b{?3b=iLUWAt zn?44pKV(5JcYUenmVFb-Y_A~p_V)Ih;tt-2w0+xK8POD|C3MoElt>_aP?)YLcv(p( zUkDjx45s#e72PXs{IydIj7@qNC+LR|M-WIWj z1hTvQXp%55kNNSmr`vo?>G>YoBxJrp;xUM0Q~WSJ?)H?m1{}cg2RB=g)eDmth9`tt zGNK~4mv05~m1U(K4a5I?d)3(xXkOTQb#NK$^AlI?mjNb zkP}A({K9AGMHnsb!-r8kC{P`IKx*CoQ;X;i5f^oMK`Q|?xQ6uf^blDrYIkc$FivdF zv!eDXb+o3X5yxDxF`Q8*eeCiZ8xn13XdvBgFAGw6?J*>^ylBfd7g;bJ2exKXv`bTF zDnPksZB0XH3;6bLG!6X=8LWp`y{DLq+E6G=tXQ!Fwi86XyZ-%kTx7Gu_+Js>8v@U} z(6GzZdZ_1)rqb+%_2!;?#U1IIPV(H|2%4?6? + + + + + + + + + + + + + + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurfaceBrushPage.xaml.cs b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurfaceBrushPage.xaml.cs new file mode 100644 index 00000000000..62e1a528fd9 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurfaceBrushPage.xaml.cs @@ -0,0 +1,16 @@ +using Windows.UI.Xaml.Controls; + +// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238 +namespace Microsoft.Toolkit.Uwp.SampleApp.SamplePages +{ + /// + /// An empty page that can be used on its own or navigated to within a Frame. + /// + public sealed partial class GeometryMaskSurfaceBrushPage : Page + { + public GeometryMaskSurfaceBrushPage() + { + this.InitializeComponent(); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurfaceBrushXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurfaceBrushXaml.bind new file mode 100644 index 00000000000..d1efea8fbd2 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurfaceBrushXaml.bind @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushPage.xaml.cs b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushPage.xaml.cs index f9c1efdaf7c..aa5950d57a7 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushPage.xaml.cs +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushPage.xaml.cs @@ -1,21 +1,6 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Runtime.InteropServices.WindowsRuntime; -using Microsoft.Toolkit.Uwp.UI.Media; -using Windows.Foundation; -using Windows.Foundation.Collections; -using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; -using Windows.UI.Xaml.Controls.Primitives; -using Windows.UI.Xaml.Data; -using Windows.UI.Xaml.Input; -using Windows.UI.Xaml.Media; -using Windows.UI.Xaml.Navigation; // The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238 - namespace Microsoft.Toolkit.Uwp.SampleApp.SamplePages { /// diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushXaml.bind index 27b3be3bcd9..4af3816416d 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushXaml.bind +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushXaml.bind @@ -1,17 +1,16 @@ - + + StrokeThickness="@[StrokeThickness:DoubleSlider:15:0-100]"> @@ -30,10 +29,10 @@ + RadiusX="@[RadiusX:DoubleSlider:30:10-60]" + RadiusY="@[RadiusY:DoubleSlider:30:10-60]" + X="@[X:DoubleSlider:300:100-500]" + Y="@[Y:DoubleSlider:350:150-550]" /> diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageMaskSurfaceBrush/ImageMaskSurfaceBrush.png b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageMaskSurfaceBrush/ImageMaskSurfaceBrush.png new file mode 100644 index 0000000000000000000000000000000000000000..9123372ad5132da86877a78900dcd47a4479976c GIT binary patch literal 9277 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 Jm55>Be*xCOp-%t+ literal 0 HcmV?d00001 diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageMaskSurfaceBrush/ImageMaskSurfaceBrushPage.xaml b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageMaskSurfaceBrush/ImageMaskSurfaceBrushPage.xaml new file mode 100644 index 00000000000..75d5b09ef4b --- /dev/null +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageMaskSurfaceBrush/ImageMaskSurfaceBrushPage.xaml @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageMaskSurfaceBrush/ImageMaskSurfaceBrushPage.xaml.cs b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageMaskSurfaceBrush/ImageMaskSurfaceBrushPage.xaml.cs new file mode 100644 index 00000000000..404ff7d0b49 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageMaskSurfaceBrush/ImageMaskSurfaceBrushPage.xaml.cs @@ -0,0 +1,112 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices.WindowsRuntime; +using Windows.Foundation; +using Windows.Foundation.Collections; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Controls.Primitives; +using Windows.UI.Xaml.Data; +using Windows.UI.Xaml.Input; +using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Navigation; + +// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238 +namespace Microsoft.Toolkit.Uwp.SampleApp.SamplePages +{ + /// + /// An empty page that can be used on its own or navigated to within a Frame. + /// + public sealed partial class ImageMaskSurfaceBrushPage : Page + { + private Dictionary _maskImages; + private Dictionary _targetImages; + + public ImageMaskSurfaceBrushPage() + { + this.InitializeComponent(); + this.SizeChanged += this.OnPageSizeChanged; + + _maskImages = new Dictionary + { + ["Image 1"] = "ms-appx:///SamplePages/ImageMaskSurfaceBrush/MaskImage1.png", + ["Image 2"] = "ms-appx:///SamplePages/ImageMaskSurfaceBrush/MaskImage2.png", + ["Image 3"] = "ms-appx:///SamplePages/ImageMaskSurfaceBrush/MaskImage3.png", + }; + + MaskImages.ItemsSource = _maskImages.Keys; + MaskImages.SelectedIndex = 0; + + _targetImages = new Dictionary + { + ["Image 1"] = "ms-appx:///Assets/Photos/PaintedHillsPathway.jpg", + ["Image 2"] = "ms-appx:///Assets/Photos/ShootingOnAutoOnTheDrone.jpg", + ["Image 3"] = "ms-appx:///Assets/Photos/NorthernCascadesReflection.jpg", + ["Image 4"] = "ms-appx:///Assets/Photos/Van.jpg", + }; + + TargetImages.ItemsSource = _targetImages.Keys; + TargetImages.SelectedIndex = 0; + } + + private void OnPageSizeChanged(object sender, SizeChangedEventArgs e) + { + //MaskImageBrush.SurfaceHeight = MaskGrid.ActualHeight; + //MaskImageBrush.SurfaceWidth = MaskGrid.ActualWidth; + //TargetImageBrush.SurfaceHeight = TargetGrid.ActualHeight; + //TargetImageBrush.SurfaceWidth = TargetGrid.ActualWidth; + } + + private void OnMaskImageChanged(object sender, SelectionChangedEventArgs e) + { + var image = MaskImages.SelectedValue as string; + if (string.IsNullOrWhiteSpace(image)) + { + return; + } + + try + { + MaskImageBrush.Source = _maskImages[image]; + //ImageMaskBrush.Mask = _maskImages[image]; + } + catch (Exception ex) + { + var msg = ex.Message; + } + } + + private void OnTargetImageChanged(object sender, SelectionChangedEventArgs e) + { + var image = TargetImages.SelectedValue as string; + if (string.IsNullOrWhiteSpace(image)) + { + return; + } + + try + { + TargetImageBrush.Source = _targetImages[image]; + //MaskTargetImageBrush.Source = _targetImages[image]; + } + catch (Exception ex) + { + var msg = ex.Message; + } + } + + private void OnBlurRadiusChanged(object sender, RangeBaseValueChangedEventArgs e) + { + try + { + MaskImageOptions.BlurRadius = e.NewValue; + } + catch (Exception ex) + { + var msg = ex.Message; + } + } + } +} diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageMaskSurfaceBrush/ImageMaskSurfaceBrushXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageMaskSurfaceBrush/ImageMaskSurfaceBrushXaml.bind new file mode 100644 index 00000000000..60560bf1e83 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageMaskSurfaceBrush/ImageMaskSurfaceBrushXaml.bind @@ -0,0 +1,22 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageMaskSurfaceBrush/MaskImage1.png b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageMaskSurfaceBrush/MaskImage1.png new file mode 100644 index 0000000000000000000000000000000000000000..a92ab65d842c76b093ab8c44a1698ca23834f5d9 GIT binary patch literal 431997 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
^$FoH@@lrH16(%xi4!&QxT+h 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

Lc%CL1H=4UI)Y?>k51%@(jwvO?k0e+s~>{ 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�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

rLm-kox_eRa{BR9xX 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%0D2wX*{Q-!uJl>1DM>-$5U|$1{Y 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%0D_5L$yKQg2`DQDGFfTF8|9@K|SZf8p_j}?$y!XAh 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
  • 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

    @0>BYYnv% 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 literal 0 HcmV?d00001 diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageSurfaceBrush/ImageSurfaceBrushPage.xaml b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageSurfaceBrush/ImageSurfaceBrushPage.xaml new file mode 100644 index 00000000000..cd822b80f42 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageSurfaceBrush/ImageSurfaceBrushPage.xaml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageSurfaceBrush/ImageSurfaceBrushPage.xaml.cs b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageSurfaceBrush/ImageSurfaceBrushPage.xaml.cs new file mode 100644 index 00000000000..6e8933fd1f1 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageSurfaceBrush/ImageSurfaceBrushPage.xaml.cs @@ -0,0 +1,88 @@ +using System; +using System.Collections.Generic; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Media; + +// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238 + +namespace Microsoft.Toolkit.Uwp.SampleApp.SamplePages +{ + /// + /// An empty page that can be used on its own or navigated to within a Frame. + /// + public sealed partial class ImageSurfaceBrushPage : Page + { + public ImageSurfaceBrushPage() + { + this.InitializeComponent(); + + StretchOptions.ItemsSource = new List + { + "None", + "Fill", + "Uniform", + "UniformToFill" + }; + + HAOptions.ItemsSource = new List + { + "Left", + "Center", + "Right" + }; + + VAOptions.ItemsSource = new List + { + "Top", + "Center", + "Bottom" + }; + + StretchOptions.SelectionChanged += OnStretchOptionsChanged; + StretchOptions.SelectedIndex = 2; + + HAOptions.SelectionChanged += OnHorizontalAlignmentChanged; + HAOptions.SelectedIndex = 1; + + VAOptions.SelectionChanged += OnVerticalAlignmentChanged; + VAOptions.SelectedIndex = 1; + } + + private void OnStretchOptionsChanged(object sender, SelectionChangedEventArgs e) + { + var stretch = StretchOptions.SelectedValue as string; + if (!string.IsNullOrWhiteSpace(stretch)) + { + if (Enum.TryParse(typeof(Stretch), stretch, out object stretchEnum)) + { + ImageOptions.Stretch = (Stretch)stretchEnum; + } + } + } + + private void OnHorizontalAlignmentChanged(object sender, SelectionChangedEventArgs e) + { + var align = HAOptions.SelectedValue as string; + if (!string.IsNullOrWhiteSpace(align)) + { + if (Enum.TryParse(typeof(AlignmentX), align, out object alignEnum)) + { + ImageOptions.HorizontalAlignment = (AlignmentX)alignEnum; + } + } + } + + private void OnVerticalAlignmentChanged(object sender, SelectionChangedEventArgs e) + { + var align = VAOptions.SelectedValue as string; + if (!string.IsNullOrWhiteSpace(align)) + { + if (Enum.TryParse(typeof(AlignmentY), align, out object alignEnum)) + { + ImageOptions.VerticalAlignment = (AlignmentY)alignEnum; + } + } + } + } +} diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageSurfaceBrush/ImageSurfaceBrushXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageSurfaceBrush/ImageSurfaceBrushXaml.bind new file mode 100644 index 00000000000..60560bf1e83 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageSurfaceBrush/ImageSurfaceBrushXaml.bind @@ -0,0 +1,22 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json index 088e8816971..d392178869d 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json @@ -1103,6 +1103,36 @@ "Icon": "/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrush.png", "ApiCheck": "Windows.UI.Xaml.Media.XamlCompositionBrushBase", "DocumentationUrl": "https://raw.githubusercontent.com/MicrosoftDocs/WindowsCommunityToolkitDocs/master/docs/brushes/BackdropBlurBrush.md" + }, + { + "Name": "GeometryMaskSurfaceBrush", + "Type": "GeometryMaskSurfaceBrushPage", + "About": "Brush which fills the contents with a CanvasCoreGeometry.", + "CodeUrl": "https://github.com/ratishphilip/WindowsCommunityToolkit/tree/feature/rendersurfaces/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs", + "XamlCodeFile": "GeometryMaskSurfaceBrushXaml.bind", + "Icon": "/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurfaceBrush.png", + "ApiCheck": "Windows.UI.Xaml.Media.XamlCompositionBrushBase", + "DocumentationUrl": "https://raw.githubusercontent.com/MicrosoftDocs/WindowsCommunityToolkitDocs/master/docs/brushes/BackdropBlurBrush.md" + }, + { + "Name": "ImageSurfaceBrush", + "Type": "ImageSurfaceBrushPage", + "About": "Brush which fills the contents with a Image.", + "CodeUrl": "https://github.com/ratishphilip/WindowsCommunityToolkit/tree/feature/rendersurfaces/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageSurfaceBrush.cs", + "XamlCodeFile": "ImageSurfaceBrushXaml.bind", + "Icon": "/SamplePages/ImageSurfaceBrush/ImageSurfaceBrush.png", + "ApiCheck": "Windows.UI.Xaml.Media.XamlCompositionBrushBase", + "DocumentationUrl": "https://raw.githubusercontent.com/MicrosoftDocs/WindowsCommunityToolkitDocs/master/docs/brushes/BackdropBlurBrush.md" + }, + { + "Name": "ImageMaskSurfaceBrush", + "Type": "ImageMaskSurfaceBrushPage", + "About": "Brush which fills the contents with a Image.", + "CodeUrl": "https://github.com/ratishphilip/WindowsCommunityToolkit/tree/feature/rendersurfaces/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageMaskSurfaceBrush.cs", + "XamlCodeFile": "ImageMaskSurfaceBrushXaml.bind", + "Icon": "/SamplePages/ImageMaskSurfaceBrush/ImageMaskSurfaceBrush.png", + "ApiCheck": "Windows.UI.Xaml.Media.XamlCompositionBrushBase", + "DocumentationUrl": "https://raw.githubusercontent.com/MicrosoftDocs/WindowsCommunityToolkitDocs/master/docs/brushes/BackdropBlurBrush.md" } ] }, diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageMaskSurfaceBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageMaskSurfaceBrush.cs index a9b9b393832..25717b5889a 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageMaskSurfaceBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageMaskSurfaceBrush.cs @@ -16,6 +16,8 @@ namespace Microsoft.Toolkit.Uwp.UI.Media ///
  • 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�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 XwS55X>$b&Tr^ib*E!C1|7Qz1qHqI1z literal 0 HcmV?d00001 diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageMaskSurfaceBrush/MaskImage3.png b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageMaskSurfaceBrush/MaskImage3.png new file mode 100644 index 0000000000000000000000000000000000000000..ad4cd9ebef769961766480d76d0ba328974f76ed GIT binary patch literal 330878 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%0D8qOIXs3f^p?qZD@=$DNtuLMuEjR6HRR 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%0DwQf4V( zZ-+#p?GjEis|3s##}ZaDrN9B<8XbHg7?hH_@00f=JC$Tq2m&D}=6uG>0i#8KO{qQm zth)SV%dF|-4;$9%(0VsOX_j@1q^mzUx6~Bdr_;=3lFi#7t}7x>0Q``I}*NcojNO|G%R>Vta` zp7T3gZ|tT~gPwr>+ES2i?gn- zjS_Kx>ZPBqZw;SwnzC`5WiXv!ZYjabBMJfd0dj1N)+3Klota1F{Y`xNBPH=N8fN(k9uZXNAq2g1PEfJ`tWzSc@t6P`K=JOv=s(1yUiDhn$~d z^&daRp?~}YzLJD{ALsbjzRJ|+zR2OJX&Q+RCXW-b3t$OYG;SemCg)TD#`>i6Rq0$; zlPrz{ea^og#|)PWjO^S=lvq(jON(fgu%%*s5SX$A_7otmcOmQt5c`<{3v2O8KC5#z z3MY7#xebO*)Ve_kd%Q zEMzUaR-E77Qdvuk;A&4$mZA-a`#mR8teqVDnt60J;yYY@5XMd^YXg&CXkHrnGwxo1bwbL&uKr{iE~Pz@vyw>`*M$ z#wg$8V6Dj$KX{NmPrI7nhMOpOhRS`9LIwo(yZ0Ixm4d_C%_9Rs;3s08FtMR((XB>L_k`_|2uL7LlyL_JVE=yXH@@mvgfwgPbfw^@a`a;hd(EM>aiG&!M9wh|wIfFm z!CG64Hp`&E7!B1HgJ@!F(Deqzvd6?Le;PeA(_tPwFEP1xQ;r-Sr2e_j5tquy(NXue zJwHii0CELNLxXr)w>_jtz)K@x)8-6JTR36ixOHGF?wNQ5r%ovSG^>w6(6G!1M7-B|KyBJb@=gn!wb)^{S^FW>0fH z>?wc-tj*_be=auoLpcuJ`2dYOzJNbIjt#^9(Q3wN=|rrGZ4 zeGI0j@pA#WViB)cZ0ov=?MOwuAYkR*`>0o2c)r&*AMavjlDb-7=C)56Sgj)rR6Moj z8v%Id?*SnZo=>zePyUwYa_+6qK&(XQo&+G0XL=$5AZa;u*(9JUnTtYTL<&ktM{`;} zH3`UyY^Nc>&x|9RVd?aGfKEz0A!tZJRd-6a*{)dl`EiKbpT_zNQ?Ps6O7F=iald)x4 zTUy#66DNjih6_B|j5zr2cS5U0@r5sC+t0lUTho}t1F_%pnuH{=)e{`jma4T>aZOuM z53m(I^Fc2d*4go8I~%Q3m+K|XXX`P4*)fxzTe!}g+>XhNVn(Ip;%%Fm*tU&GC}QJM zc9J}05o>Ev^0K#_zxC2n6fe#kX8_>8^Kt2=Zgc1dFQ8IQN;#R_#kB0zY{FURAZ~sx zY~SYeeo^EA4mee`HW~G^hH}|8jy&;*b6U^kx~J6BvVW&ojp*Uw`#8j>dPU(0;zu8) zxll(2e*Zrw1y+Mz)ogs-&k)@DLK>AA*@Dfl`B_ZhV;i+hw=qf6i9wExpnv!f%ZE>r zJ8ze}R;htlS~mAR3f2cam<#@n=r+qi;uDv>v`mZ0HrkwSB`O|ndD6gSM^U=#h_>5 z6YBt*)1^$dny0@_kWu$ zz(PGjcy4SBNWny6wUc%*N14Sb>L~-u9?;u125);eiZy^`&7>&$*vc4_VbM*;uQM~Y zvYqJD296k*o|)x|yC39{uYa2-KYs@^ciu&F-#%2cN#OhBN+o1Ik1Cg`Kk_IG(~Eee zT$kTpUulErUykP~tcvCoo1?C7V68!cJa4zl&GkHl@`#s~$iMa%D4(;5c&XXl^pp7; zTSVvYR1!cXGX9Mg%XZm$-cS((SPrCKJUu8@9mrMcV=*t&65W(DxBL&vteviwkb?7#@LAp~JkT-?wEGVsOwkNX*YU z7I0{|zhU%`0sz;Pe?_O;SL=>=J&v$Zh%$!CSMH$ItfO*4BCPH(4kAe@u`3Z9e(Z(h z|L~6pj~!$AyLYnXIZvnb+~*M=JcI~>E*8=@8j#N+!ibrVe2l<@foI?Bnr7m-trZhO zAbg*k@|fRu2pu@DsjQZy*XJxd@z~7nHOx$2tqf2|8&PO(u;Gr_(@jn)3O&Akl*K6!n%SeCPp2 zuf7_S&$;K#PnhsrE-@TeT_xmrc@^*Ci@5Ici#YN9?=xKs8P56m*mj4Y#+9~g0-WQ_ zi_k#Rb~FmAhk=MP?9|hINeQvWEV=zWS<~)(PoH}sB_i+60uSJVAP+s|jl*t>T=mcq$% z{LC2iMTbdLnd^LKZ23;4xpnI#kr!Z%alca~S2m^9-T1aj3W+tv+vY1D=5EZHZs0Qv z;D1Q@SCq>yKzaklm>3}iwQ9%oxmWP6wJQPdI0x~pTb#e%H@*R1{30AU;C6xo1Bfk~ z96+m7+wQFPp$FixM>>rgrv-mcwPb8MjV3zzT&$tla1+z)EcNMmR3Yb#j+0DUnV98T zt+6XH6R&$E#b5eW;u9wcj9~&8`pH)kA3p39C$=~I+~N-nv+&7J(u`pA?5!|3 zc1d*D9M|3GN{;nJ>y(zPG;8fj`jtD=$JWo~5cwRkR6>@Mw}CREP;g9sF6T9}y0$N;X(Q_bE$d}4BLub%>byOOQqgS|ebs3qtJg7Gwle-pzl0ZpiPy&HMZgd+ zlH7w;>%c<JAgM_2wOd7*kzB6Dx5nHCTZF`1p0&<0beKG8P&wKF(1_)EZpQ-uJskASW|DtoM=YO#hQvSG*h-xc5j}0y;jqE z5!-HSm=r{s#3wMzC}!Ds-NPsfoI65Zz-nw5#Zpp|kF_)pM25<06<-S1M3!2k3E{?^ zZR;yktc{JWx{C9+UMg7QWOL>?!vOyK9=E;w-Q0fr?cDaV7rg<&xh9GYo|4Y|HG*Ps zeJm{neCAV#`2~2|^==qkemP8TL>xWh+$07D5hJ6JFS_@KhLe#glPpKsN5}UgGJtI+ z5I318Wki?XRKPoD7maUyliHI<@yfaGzaa%CjIouN@n3!&g`ape@%$_pi}XB-m+Z!R zf%EzE{ciRz4DrV&soe1;PCUGy%_S)8xd46ES0SfdFF1=R2`a$o>&^Ja>>b}@SSWlU_} zOv#rt=1vl7i*h8O(kD3mj`j6oQUnbh^L|icVQ6?K~Y!>~>1Rd6%X4BuungX|uugzNDOZ()lED zeiA$^K_Ta~yh^$5YMXiGne(@`B)3;7Or=SFY?$Mo&uq0xLCLQB*u}0TX2cTkd>=3H z5Wa`+sdia!?Q`tF-kQl;h;@;8+6mkX+S5%)ul-AJ6OiycY%Qd4!}X}A-+*0ON&r0V zYJzPx@Xp_Z7gnkM@CjtzUvn}x0qeDtkvFhl-F*-lCO$h(RR)ZtU?LE(Nr9Is;iteY z59E{}iXx63pW?v7k1#zu$E@dZ)VS{4wDUE6?LlTUmNKF#c*$kt1EQzA+nc!4mK#XP zay4XkDaQ@J@H({bJ3A!L>tgJ&7K$b8>`6E<#Yj0|!CJJjtQw0a1f$Y5Z#)zkyu9M% z)I8_-g5p(I)0#d(?xIT=*fdVwec+vE`9i&kR+uv)DMY6Ep*n^_u^WaM$0}iB>?i)wbw2+1Pa-b60#Pct z^3lf4h#fl|_{-(o@5tvIpe&W0)~MNX`atCA!Cy92pw~ArWn4sJ1(VM^?cuza_}=> zW_Yx~gs{YyT>-FDl+r~iwOR~ZZ~^&+8D@{pp$a|{yS6#{6bo4vs8}JK z`Dq3ur2_LI;Yv#bfyaQ+Jhb-+Cmwj1<@@fYxpzN$VIIHLbn$fMGHTm4O4nS&SgFX# z`ya#P)VfSdZ<)G9N6Th#Rrx{!0JEiJXFFlpvS}j}3T;hTm#3sL2;aw6D#UTz7W}Wr zl&06GZo3mRPIsKDRGb?B>TFreT5KR$cxWGE6GP-Ky&S!=+E**q4+O@mtEkOe*uJ{R z@yGYGlK32E^;R|OK!M0?0MZ32F9b#5?rTXnAG4AW+pgYBN>v}&i?8yQ|A84 zKJ1|A0)O3Q;4BdIS=$xc@1C1RO#W3rf!wqeTT8p+lZ~kWq7Wkl`5SJ6d%jJ5ei7w+ zT|iFvY;<%VAl2JN8q={|85FQV2_~g#gSKJ<_=SK~<5iC~VwFp^#_m$RN8nOz`yaA)Y%j$fY@t3zQ&_!PlCqwk$`MhJ{9w zM&u{2GXRDX&&alxT6E@61B8h^(^loiSzZVV$^W_JecxJgLa=Fcn8}erP?B#hu5wSP z8TTZ|u-v~=Mwd2#GeO%NABYxaaOO*}(tS!#i^co?7|0m@7O7 zDF@?LD@F*FEn5;cT?gs#NCF788zIFa_OqXA>uET4!~r|4oes)3?&k`5r;kcgL2Ned z&^o3pmv=kxHJ!cdEL7?5Ng1{*GnYO0C_)xXL|^zUda;EXFS=518~n9URm<4#{Wo&A z-by?@?WO_GcMUEp%h>6uge}QrOlgf69zv|FaPZ^*1UbQ`LJl1Y#D;PAt$w~6#-)17 zWTFi#6((Qya^l*@ICOA|@^Bv8PC@DHRz;ukg=xPDA{|qRH2G2v9chG=U0|YWomg6G z=caFm3kYji4K*u=kD(79b3*39fRQa*7~H;t{5fY6T>CV(J^C0=KJYlX;eum?p5lOO zd-7SgYhKfcVGIMsJpS+yF&R*uwev}zgP|d8wTe#lc71?adR_9OljQX${XfSx|3%UGXzrYi5i)rao zv$oCNSX>EzOmyPzvWvFLyzYDgvMo@Sl6=Nnuu~3CHZoFlY26YUqD^Pmg?XrGL`fk^ zC03R~#$WxjocR3b37dv|!AT|7i&g6t+^4U{WImTo`N)DmlhHx6wTXQU;ms+uJy~OL zLH~F~0oXXkm!Ni>gK0IBCM`M}H4Th!0BZ=}|6WQbPf*SKE*dP^=+tfE4{E#hM!g-l zkcmi4Sfn8#7*GiaiDD!cJfCG_nXz!fSWar!pwUWBt7_n)Kypq#;DM&*h_>WKr+GnV zHeP9bqcIR+2&6(|+l?XFEMU`9GVjX77J^zMVuL4n-fLe4qa(y~b8ZtYjH{m}(g(Ny z77(@&o3|i+XvHz(QnJm$Q6upL{7_q-BLzDY{4lZ%<#HSkTipMi_j1LX-hlRf%*-6} zy6f2X+k)e7eFq^e{6Y?scx0)-qqe-lP^Cib`|WvCDG#sYv$I@gCx&ZVEr=qTwHhay zA$x00jz=+1XiFt!;d)B$5g?Ote#)wzEd|4}(_qqD88BKioX=4n96^HL z;d>HoEt696ur}Owc#7M0?I7?1!g}55u~V|eJ?}CG>v{5$mtB3%rQCbq{zpJv#2Fy? zqaJ5!=chYd_b*ucl6BcP={cXfYNgY$G&%-f`67Jt8&E7j9AYb#jxCB(P%61bkVhYd zg?YCCr5(lT|DNZ*HwrtU@m5$Yzz&afUW=4T z^Ni|FkB|~!3}Fbh_815R~JHoss7H=RS+GCMO|| z36h41>>}jh*q{}yky;~-#rGt^K%V??0W+9mIgB{?#3Am#zEH?p2DmoG1VGu-@&G5 z-N1MYo*pQ!Qi2K5(KJSho-+$#{633yx@e^(f72J?N;i(P8QUruJ7E)+mf*xJqBsB- zpGR>0_0)%knf1Z$-^cs|4-%9TjaSde>}OP*f{Fs`M~j(tnC|x1)6CZ1Vc+HSWY?5@ zdb>5()`b+*BRFd_V)JHbv>fA~F2YK|ww*9_4E@``LG(|b#abBmBsH8p)2vPWEp2Cf z_P)+^tj4$okLS81_xe^{V zju~$P`vn{X4g*Jl`2+x_df)|X8Sy30D&{Ff5eDa3n3jwC#Uttr!1jco7HI}zxb;83 z6frVNIJbaM9t3{J-YOlpafpqYZXGC>5hKHhC?b-QbCh5xt*p2vBkTMI(V8%hX+{yvNYnHJ zqI{A3*f?ix-pKQ}Z|3K>ZRF2346ws$O4iv|`5A^iWdd8toViCyMr5a4-{nncEP=I* z4-Zlp8ls8Q$LAz0SL)0m+Du~%Z1yBy4lRHBShwpw9`{ggd=qM=P=@=@jZu0c~ z&O*L<8(egeV*>Z>h2>=z5I#K(Cr-f3jC-4%g`-Dc=7bwrf#1DY^_$Aqi|t6iUmF-2 z#ys*c;p2yqW!HgamBQ5Ocr_S(!~a4)^EsHQ=}xIuN@s)9YC7Ft7SsaP8vKb3EPU~c z>^m^cj`1P|&nK=oVZ#RSR1cG7yGz)q=1~Ylqe&dcob}VMW^A-Xz1nIUkhV2p#?Xw7 z)64-|B<%4d=j)I?(y;4=&qeM&pSkH14rnIV&GuQ8o3nAIFQF5E)X|0 zOrL;Uku8^A47HfXa)U;#Ntj$iAtmxDls&y34PASYQHs@2bLhzfRHvp0tZ6R@?R&2^ zYH-LktXSOz{LDIUc~0H%VKWK>W7m4?iBkZREI2n>lON49e|(ntxBeO4_*hcLJRR(` z4r|n^Yi`fjmVN^M;dW8PfmI*Oi!8%}LxotiK^(5Jw2n<6SzH!h1M zxb}L)Ykm&#`~QpJH-CqfMvJL^N0E7-<6rm!F&d@RDHBzCL12MX_$tzU-LvuI?%UW!g)$?o)Sz-K|W!0eF>h{6pCf?S6@SvFR{=v6s2Sc*DYVnFzOoj z3>?)iA!t-VXgcG|&#-=-Qn_F;jM#PA#k_Q4gj;mPje+89B^XG~aoIr4m^I+W1L|5+ z2n{cI(am_9Hxn)`ck-gM8~H4F(H6o)*0XUFgwEzk;jV*CBov2Zi$UO}ago{}@`@jP z_RH|V{dnUOAQfh21}?vnEr0a8~zvYpU=imoJCXO}M zic>C~I)XdDhyACI!O%#@9!5yl`CG3$AXqB7g}hmZLJ2Oo2qrgT@3|9JmXQ+^sPS>U zu`#@nQM}@NFHB-1A6b{%zx#(oHgjPv0Ng?B8-MDTig_4 zY$uH*J-4)c-hLUbbP`w!U1 z60fYl?%nLX@*-L_O(X=dg`?WA0934{W-W`xGG#lZzV*(f9jVv*x;!tjXG+H7>Z)6y zFTND<6R$@6{4XMIc|KzI`FK%_#Xo;DN56HC+b~(nT(ySsbA4@i`Zdd>=D~8EdoEae z{X1zUowwB4NvyX{wi~W(!WORejgzN%Q&(Q?<}-|A0Jm<1g*o(Z{Tljxe}^qA7%4i( zfP`7wEMbT2WHP6ljuuHNSilBPaao|a%ol9;1jC|Zmac^Z_Xi`(ow4DGNJA7dQ?EHs z%N~|HtA+^@&~`AkOwuuQ?rj!Jk3dRJv@Ej=OXRP;hVh9}HiRv%@)a-2D_)kD+?ZFK z<9p;{&1xL8qD`lnp=o&Wv#uq7;e|9;Ry(#k>0Fq0O!qc?aR0mCjfg^QVz*^Zo`4H3V)GyW4~9wsgOw)3fyYFk$VU;n zUhOcE>oD%p_fblr0v|7zqa{3cPK@%5g2#N^*)aRSsDP*CBsb(GqYBCrMx^V|PU9IB zFr)-UYl%&aR*IbOQCVH(&yLTruN5)mNfvFl9(5`?^iBHZZ zCDmT`Z=I5GI*5uz#K{?2ciriDejzZ+bvywBZ~jy4BJ6Jp)HcYza50hBHSkdt(Of^O}u}ny9Yw~%t)`)X< zasI1*lKmh5CkFBXgQXJ1VgZ@Uf!5eYgGgB7#VTT`MBzEl#gxjZ>M9FUQ^d;Y!PfX{ z_gQ#PU7?h;4A|ub!bXjKb5(WtQ)?>^>_9jCrnqXAe6s^FoN z!b`eTMdEp7dzhLoU@E}#0~VSQ^`lcvPK;6<86#E+Q<~4?4UM3er=1_0F$j_Xc=|+M zC4VfmJ%-h%xGve|1WSKQnDxF#2#`g^{&#(l3wND|I_qrA!ooUwz|KiXYcS1_?LYG~ zEZqOQXrqw=ZuLFB92rg|nys7^NF<(gDJpe3=_(yC=Ay%5a1n(mBNNBYf3se9QjHxu zVfP-y&a<2sr;eeriYUaWmgMC7-p9=08G_+FI*!>`$gvbfRAP;vqqhrlHFQ-Z*8N{noW>)&!pUS9;VTR@&IyV6#dD6Lcjg5 zFm;gQMR#VYUN|{IV22W{TBpy;0|?28a^0;XMiaCev;@?Zk4`egE5>>8RkU^bSOIk_ zIk?o|@&iw@vbsuBxJWr|GS6FY_Opb?jpfBkk;Al`No=3po=jH2Lnmg~uwy&9OE1Ol z+sE>;DGJ3rg93)~K6}b#tP#vM8XT)NI1E_nPo%<8EU~*&o28ra_?NsjnCu65`+$dnbO?0Bh5)B3%IJwN0fB1VQf8pnejvhxS z4>NlbxobBY{`ilnzv+$W5~atld^`jUYizToV%``kjy8VZdDNX0{o%Y1yP&We)!Ox|NUxz}me z^$BBmcA)sLo5wI#V07GRoT0DMLE|frIDR2;{}}*y1_1uM9dCK}yQL7q*uQ?$R-)(` zSmQ>=`VVB%5E8=!@;G9#M@ ziG{?*+S%m{4#LQ&(=+(o7=`EDg7thvqX9Z#b$S}mqt?=?NiH$)T&FJRM3;~brJ3yR7WYKfopremUb$|W5@A`SM z^+pHwyZAN(>eo9=QdX6$?}O+Xe5EsPA1)xyKOZqRhB$nP=y!e-^R0UjW$-sRV6mPC z6ySU%cw9SxaIR_L)m$wzR?yl$i57y$&yyTlt#EC<4!Inq-FxtX=F}ART!0@NtWbEx z9FwIYlcSoes#T(T1HZCN>z;d2Tectu2S9lkZQNWJ$8MfWlPr`b95Ix~ zMv?30PdxQ@d4eTtc|vy<=yVg%j1Bpc;_feejc4!KL+Oeuh?bVxAdrol$^X&oslV}d z;)N=5q(D@w6NF8IQkf_W(OP#le!Y3r>HMPW1CISqHX+&k z@IKG9+eMrBrTcHV>CNK1-;Ox7pZ%HR3;=v;$M1stU9e1Sc^<-!#+9l@DTxrLqla9H zcjwt~%k$ulFF-KlKuxs@tE-4}c441*414e0h`Bkq;YKJAK%)WGDn==C|LG^#{*0Sh zedpU*`rduugEvx2V&t4Y&KkqX&wZ7V<5LX(&VR>DY``opCxfL2wul~0g;cP*O6#k4 zKmiB-hVl%&`K{O;XFJ_t%FtLGaDDO#?7erohL0`VTq#4lu3B<=-cJC#GD3Otaz2&IUrMoL!DF zh+G~iliw9Zuwy%1az#QR)RDy^dU1i(l{%`F!x;M`%?|x$6Kf29!RO$iBb>CBF<|rg z=Q~@ULkFSRBuq7umtKK)*4dQv1B^njpiN8|g^Y}jacpUs`IV*vLa+HL#HE*`u+D<%oO9g9Y3?M1aa+G- z0e|NX?0t80;IH0BW2H_ooOe=yIA)|=LU6YQTpiOJ^>2~#h6CfcmU2&VvH zriV%G?pDq`ml@jCJ_YW>7yX+}x&WvUh$iHB??8-A(E9riv+}mLV;V7PH19SkQS2@e z-LZS=`%&_@#<3izMC=~+Fc)2jxabnR^LFE3bq%#Y|5KuS@8bMTldLq3Gi3~g41;Qo z;k%Sf-E-1xxGa_7CBp4ncTv{R+ z8$-k~@!T9(i)^(pzE7;&W=)pL2q6jYybog_%qi@q3H*&)@Xk65H8zeI8NnEX@q9Nw z8jIC&r%)!-(k_SI$iUpt5j*g8L&U*VruJgtg?8*SU$a^7 zEZ6wEW=uf}CPl~4d)B~ZQt)d<#U4)(X}7WTaHZiR+Vatw=A^NVdXgrtW7xx$`h|2c zd!t74=NpHikfRxCcV4I0ugTb2s}Pr-8!cQ0+?(~!ICGo03opLO7Dbs77>eXi-_@~b*&C)Pr~ z02321H_OsLeuAI~q2SH+} zDw7OR5OL(h&7MxOSp{s~1Ut`he=`i7&4%w&Juywgx@fMxU6Y);v$g+XDwv5iVX~-~ zF1`@6JfE1P3S=0=Cd|VRp^qHKEG#&!&F=FV&lebvW2n`r@7u@xckd$%fPzAL zK_`EhA5DsjP~128|22_tyLe61iLsFDdI~ zZCBK3HW&TM#o1>wEoXN9F1rpR*axV4eR7NGkv&*z&;s&TU4^~-``Ax^64{8c8_Gmc z)c$^HyDgW}jfF98lj14KNYvu$=RFheSAGp+9b&ZAD%7hi?zxboU;GA7-{NuYrU|}% z;v@^kkWWCMQi}OXjkBs%)X)%5+c?3aPfnrz#1LKdk2+6*@o{b0Bn1y@%V5S)t9P&A z3Bi(uqYF!%t2|5;A!36X89@q*o?pPL)gYfoD!;wCw!V)TEhEARqYd%#85)OY(0Ba+ zHB=(MX%oTLtpvlv$YKGbHMUuIzOKf&O>nX3m_N~d@13Et;6e`$7|Uc5eYcP_J2kDP zl2>dVD#PJJ*z@)vsuj1X_k37c!VV3SzwI`7{p)F+SfV&u;5*YN`QGtaes<$1=T2_G zFBXZTsLMk%ZNAgik`H`nwfL7K$M{G+r06Mf$$8EtTFh7H1V5cqAfaO1d6tq5+E-eJ zJ3@meU_!dC@JT7yA_cK=A4e91(fs9xK?cf2T2bVlZDZUTky5wmMzQAx8ql7^qf&i7 zaPOHi@Q-$!F@o;5P^IS2@A->Oz6$=7Ff1C^JRwfY{$+jqS}oXhp0kjcnsO7+xx1iL zLKI4_t2fox?Rx^E5V3uy`<&Je#8m63i!Pyj>vQmz=4n2Dh&YN-sq4PA$Z|kyu}0%d zU!b^Y691ZOF|}lIOW8N2T#2}{49zBTV1U*?e}d-mlLXtx8F>ve*aMeqZvt*Da-BIpYs(}CZPOX~yfx~_p>T?6iHxl*q4z1>4ZU==Lg z^FuaVashJZPHe4_c4_#sMX z?;?yfrdq?q5k_l_=Mm4(qw5Xq$gnfjK4-UkPO23L{Gi>W=-Alr65Jt?s5$PjFaE7HSl;mG8E`&CVN4$u$Cr<0c|*YWRN(Hkk*xGMK14h z&8w>pbb6|@nT=z&S&t1yN=z=m=6y_{2Wx=7A**2anHl!RkEz#TTLTB}AOKi%JQNCX|N= zZg@K8fqRj&s|*g8_{V0%x0mbepPy$mj+iVK@bbB~t&l*t4M3p)l~vyS_yPW*7BS*0 z^2wZW(!d2u@TQXD#+=)1R+A0EkaW#iA8HxC7g`2nC*i1N;c32NL^?Ubmm8^|9DsEZ}q(V+`WLOW^o1IDQOq{vM}=3j##F?n<4dlA9Ec z9f9d7#O5t9lw{=!i>+3%L7u`b&!xEQEc7Ekq%~gyUm$!37G=@Ln3&qv@5GN9?;f$_VwOfh@b3V0Z z*e5Tg|G%#b--V5{9eE2fh_prG@wLSkiJhC#WcVF9mbx2D>h$n_bxFI_qJ}O z`M$qp_Kt6&M)C-4+8QX`3(AE+6?~Sb7Ln6O7}|XvR;eVV#+8zV)=u9i1jGh$!9{Lk zkqwzQ#%)$Sg+DaH>f7GRp?7}}TM+oUT)Q-Hgg{0yTXt?k3=O*|$5PRGGR853!$Y(d zmuPC^m`&Etu0EAmDf=_)b*+o1NO$N&PnQ#-A7R*eUkFSb6O4|c4j&@?+V?S1x2pl^ z7zl*RA;iQlv#xGkp&O(9@>*MHPjZC z$t^FCLt{MORZPy=1!tWF58mhIIHkxXI#P}0iP*9)jJRZ|#E_Ikt%$`0pcSNG)sq}O zKF{vTBL4MHM~6|ujwab_%?7qq#=r3<%nyIS;E5&n6$2VVuwdbvD|H^3n`c85FCGK_SQd@hN`m$>Tf#YzsV8hV}d9yyVx5iXkOv8roHmyo84$%ljHJCk>3t&b4m= zlS**C@4A|mfDbfc{#(iCxnqNbHtG0nucMi#JiD&0on(Xsq_&e=l>XxF$7ZH(`wi5Y zXt*-~@ZSyqFT7CP{)I2t+g|?S+wuJKjn<|O0IfYW`0G7NB{+H*kq_J=XF!~NuCr1Z z9Dt*TI+h-V0<12>zP*TI$$13YWcrUHOr?T4cQ@r1z5u^jr}@Jth#N7g9JtOs-$Mt2 z)q5VsKe!k9&_i(UxvryeVcwOag~FSdVCh}&MAvJKz5jz4KY-<>Zt!Qd1Aiw^VE_4J zj-9#e3bzV}5tIiI8#lRVqOab;%qKpBSN19A16EGV5yzHRD|8j)ty_@i?!wk<&d0FT z1m8zL`UuhNJd}&BOVheHflZ85lPD!ztej043~e0~CL0m*qKo0&UG8^gyi6<*43w!q zv6o}Vrtt%RO%lVJon)WIH~VqwnN>?nRfUwqEzS8iUPu1?^U(|Qh%ij7eTuNM3@a;; z3$T@yE;Bcg%Q@|ibl2RrnwT)cdLC-qHj3lpsQD#oGbb@ZknCae;SM*t3ZlMnEXYlziK(|_mC_--D zO#Iz%GyRVDAqRZd&73*Ev_#egrmRJk0v2bMQ95Gq@=J&-s|Y`EOieE5WCTF~%5yBd z7eE|lUQA*>K0Jzj>>&>Q>0d%w;RSxzn2%!3VBj&ndv{{bk(8{1z?CJnrZiZhvABdr zWEhP;%<3t$mYhP4Al6}Z`)S|c`Q+Sjv@PJ@c?DS~<(bMho|Fpu;+7wyMdvmOQb zSf?#i3Y*#s3E9yT6ml@X3dav3p7UG?Ti7T@jgF%4x{C)+&Vz~BJ~TkJQRhIdfhQ#r z!K&31b;P!9TWQ8IBZGrXA3M%TYbna4i+-I85Sqj!+;%F7Sw&1|1L4@@)mU?JKA>1E z5QUKgBi1IVO^LB{y`H!&C|A8`HoN>9Qw^oTc6lo)CBXNnM=?bm;YShX$^G!){c!NG z(~Ktu^oPQbyIPv>#+Ln7P&ZHwHM@t4Z1O!s7;z+FqVoc3zU0_}DfY++@2YFi)oQ2H zS0>hDg#zNHXW~8j1CE_s;R#PLAp}KFF>T?oN}ZL(1yr-ahC+@n{P0nJd#*~H^VuQ= zRqM2V*LZ?AmK0Y65@Vg^j==dbO5k5xhR?MeLpz8wqgFx?2tgYv(hqr0|jEL2<0%|6jvh~k2=cKwRWdf?Amm$f@}9Q&ou!N?fmg)fKwk0Z8icQyb+Be1yObahFo z6F+c|?*1pBzKYm+j{95`IbnLWg0X`9v!6rx;tSAEK0!FOfKkrO*0X|gIlw-C7;)kV z!LR)$Hf*`lZmohSmEhP>!h7yz=&gT=$QNADdoS~s%R{WOAN#P=NL_ddj1D{fUa{m# z)l$Iy_cHyS4^sznl00sv!k3K@Q{}8I2M_Ge3 z2ATE)1irf-%IlO|blhfOjImG;@vpcTv1gCdezjwQG{W=o^LbY9xrco}cm$jCPusgA z)>%x2=mtefK%ANo13_pw|0OTL4v#pnSF6D21nfHBX(_|dl`$3;I^Zv#CpvThayjJa zsCyRD$uA7CjRvN&>dd%3fvi=CDiJ!4L0W|85=T5No`66Kr=3bBTqVRQBcrpRA{H?UsDeH+okM?>U!tyCx+cl?SEUM_Sd|;XZ6H&b3My!;m*P43A((>eFa zVW$i0+0+I#JN_URe8|DoQ`bDr+gea_x1)T(;x{l4G#4XK8b=IWaJzb$~*>tXV` zi3(e2ITn&E0@2(lvi{W9USI@GV@ce4J-eaAl*x!9Y=pB4;~Q z%u&yq)#AjxQIcQ_o6X^|s-q%rYfi7ryZ3*7=5Q6nIPED8WR#jOX`E)SZ+ZiBPitc`T0htt`!Y*W4K>l?pO{rsQ)srl*e`sVi`<#%Us;>y2&WAHZ$ zr%qtM@LBH*We{(8D`ML=2cmHLHBqj>sT2LK@lrYfbpE_!54UfJiD~DbCtOFFSzANy z*-QPs?m6`Za&~ zd5w-@Kk+em;d$7-8*|-t*o_Uu_yp?6t;ohY^2O&^{piQY(9B-Ho3Wd2rgHcYl>-M5 z)6$r#6o)hn)C9lC}OmzNy+))m6v)}ks^f-K|o7a!)uEZDkZqe^ zgFpzzttPp6o@{ZEY<-Pvqk(QUFzZfxsMC~4y12wnCq_xJiDk7z^moHpxuSm14q>bZ zwU~LSw=5mg68aBV^ZKs5Y+HP9jnh`=~ z7$LAmyBcHW=P(txG3CMER`;*C^C?FEAqA~wi`wWYa%u`YF@czzhUsbK)D*Lm6CBt! z!;#5x4%8})ODLI)qw5Jf0vM^+n5{(Y67XCnCb5=!sAyz{3txGRLl54En3!K*w4- z-bSk8LHCoXMZ@i%7{vyP)O(gvuDWZSgTKDD zRrmkf=5^PlAL?w|e)Y_siE|5=EZ11T*Ymp81w8PYZnoSy6KC&7DYpeKHg@Dd=4yU` zqoeThOV~%hWBXg)Lh{QWCVuK=vRdNwYj@v;>3B_AJ|T2Euxl@-QgMux z8h|~;E*}dHz zcVhvBL>#%r0S;rJ(}az+9HF>jQy(Gz)F;UBDGCJvW zf1;3bkvF#F_vgH}r2d$zKurpwK%q&{Pd-8L9S1RY-Hko=l9NAFs&1t-`9b^VSt+;h zEHAm(zD|ec%P%8JkQf&$CUIp#1=N*fVR6|B=Kb5q0!wVPzb=8mr~s+tCSSiIU>juf zO#hPC1-V__X5s(4rC7hvMxJ#kZfF8}(QBEtH2pm;c@UHXKjE8=OqxO*cT2)GB`GOI zDF~2KqNQ-E6q^-3$@EyiKq7@>dUTr7PBRj1Fo}Q)G=K3I7&~wPGqVkO@DSy)BuWjp z%+8Rd855%;+@GX;X}y66LOQ_w!XouuJF#gBlasu0|6X2r{v>J587}8?&yv?BT7RAL zYmnKVt?JGOCCnsMjqDl4Z>lVC}MfZY>y zeyCRFH?FL(p)C{jh>Pn9PyUZz;I9AjpV49HESB z%2$yZ!XNop9<_9w#~DB=a{g1kq`Zl_tkz(48T*mngfv6kbQm=?P5UcfW$~%!IQ!8* z;KfItB51BMciXL)Fv2V>IGck!6Ih78xVb!ag!AXHk3WGd2S_0hQRuGM*q8&I6BCXl zvtDGavmSf6u?|6ieB+xCb90Un^g2Ns1Vp2wB*$LinJ+!css$x1+jj0ig(X%u)}4g| zc4%b=HpiX?Vsn#20&mP5IIPcy)O<-aI z{rs~u9zP1wU`i!o3-RSe+AqCIdh$53*(4YnM~qKkOJ#)7*fhb$38vF=4I{I2goh7P zIeeJXj%_Yld2NOD)s*!(qk*NV0-6X~xCW9u4>ez$8aRzqY+PhhS^yOi2bf2Npe_VK zffdvRAgKx+p|6MaV^|5q`to(zXG0qy zF|8C?4G8YJAKU6Uxka2f6L#ghz^^~(o&zBr_*+|rEJKcsVUE4T$%np(s+F83HP@8+ zbDscL?o|OY3*=vUJyI(2pgrI5u=46}SLK2F>TX2{b~u3WN|{@TsIEvxanWk!rn;EtR_SvG5tp zoarRt^UuFXEpio_02lA3C9HNdx0Apx{Q~i`C(yNs%vglA1VT^|a4NI>L2S4POo?8j zT$MK1NdN%=07*naR6u{uaOCHV-9oTO3NmAu9jz18%9uFmjs4KCcS5*|PhT9U=t_Gw ztyKd|ph8G8Gy0wnz3ta`ed3tD1_G}!fPb^s(WBCWA*{TOP)%hz(?pSUmMp1{Fe?!L zwov|1%7L7xpTZt}(lt;h;dYHd-~d3Y?Q(xR9T*>Ti%+ZRSitES=Mfd<4}c%^#zItr zO4X%rtSlqm@Mf6Z=6=^&_x@|^m}V3CzHg**{Q>mRqu7yAxA>*8o4BJ8$~E_}4HJn4 zf&17`e9U!E-f$y9xyH-?zhC0=TI_aoB`8O5!y6w&SF7$^>UEf(cTFs_vzy)Jt5vu% zkNL`15Mkh&AHv9irApOZtI;v9!%E!ZnMcBD1FZ(sYjEF#4xqMMUfX36QA8L9tQ~!p z7mvP3R*9%a5gW@5Ca&AZ(#f+Z(~B#X)w1Sa4b?@2Fd|ZF>(#I&bPf9 zJ7}#X3?rH)$(2kq>la+Z=4iegs8>AT>6_)PMb;pDc6wOuaPiu;vE9$N9^9id+8Y{aAgn<3*27fpyo2D@+mQ8oml;c~?$4Xcn;Wb} z1%dO&TUkUu^9-FYe4co10~-WgcDS!$MQh}AmGr~~!e9Ai!VmpVwjVsqh2!V=>dFRp zHrve2PNR|RpPJ;k=0z?U$x@>YafhHx?cmI_r^|}J{(t|R zZ$5O0%B{DPEiWOoi=b10Uf*EXo8Q0rF@TTH8rlz6DT(* zb*1aiN9sEW!?NG@1n}hJ*yo>f`oEm{lhS+f8EmtG*tXr-sH6s_X232uUDBSt*jHWx zSt`_qWI?PW9Y}1qv7i4e9Jv*7=qA@dkY&A6?!}AP?K_bGt3Xu0d-uboOE5Xuapn(xpG&Qn>Qvp^OC{_bsiTA>Ie!6BtvCj+ zTy~npjSZ*c%SHF4vg40$3fwTkb8!$Qvcirdn zlvf>!Gp_a~nhnl;?n|6%cmvTip@G|7R`*@U`DdOdPQa9Vpxrb($PCu}sh0=Xzv5(; zmp1l{1lVTEdE>G#+ac_ktRnaBcU_I8vKs@9hP!!}&SRICpj<&J3GFs3fBhMB0HKr! zpkl~S0!u#%H z^uaf>yV-<`=gCf;V(sKv8p{igJ@N=))b!3T#hp)0y1%Q!B3d-~RfVggy%BQ<=okkI z6R(eCi*n}RznekbrSG`B0tf?Rm@eZr3{V#R(o8;%jX_2w%yQFZSRX#(O7LL_x7~@D zn8cnw1>+NN`n20rjE?qp2cx5`KlucyXD{-NfH4N4Q>sAhqXebw*X8AGQlKOv2p#zG z4HVk;YwogvaTXMSh$#RkB?O_@^>uZCmTtpN&bkyqU;Z8=IIlJQJ*rFhv(7)!5Y1@>+- zv(5~1Jf!pK&r$j>|A}*7{t_y10Q*=cp}nxo-suSl6{BIm8mkVt}j>(=Lp$L1XHeUMyL0To-{~w+mWAISPn;%0*2|PHXtkN`r5SB!>b;?C*9l zTCNEA1~WBs<~JJv_tsiu5RjxPD<@7cap({__kZnEj5{6j%$%G5+ikK&6E!o<+wZ-NUwiB*F@jiYzM&NG zuCfD@X;_6oV3k0WDwJx_TwUWYR#MIx%b4sLl5gd2sc?xs*DJwop=86t$xO1)YBL^5 zf-u5lLs-4MQ>R>UYk=u7eXjpVBZcR<^XERzz+}Q^Mhl%qEH>W*JbjG;eC^k@3*=wF z@N2&&|Hb!zziIyJuWhexpL!aT&1H%93RTf3sCBcpazOC8qcAszJ$b@4OpK29)7RFQ zjh7bT>)!3sK~`6Lq2ZS=I`Mz0?7)}KdWN*vex^=qCtf$1OBC6?8*#_ou5|1Jx4W+C zxj3m*cIDG6mtbxVW_Nl)voB{PiF?p;jo|V!=Edg;qlj~V@kw4fw@4+&h&b`@J=;g1 zRK~=yE2WK1!0uh{v-0;b+5w_ChNI6oZO7C!vJ_&ia6q(H#cG!=?2=O2?%1?;#}_9K zDBky=E2|})!fsKZ$|W|Qdx0~jPE#HqB@hy%Kxc+>DPs3`e;4tqudw=Oe@@tLk{C;~ z6*IbTH|5C*Vgs?&)GAeMRDw#`8()VA6}VU|uQ42-o1@cgkt#*@(hDqn{wvg`DpbbD z(CxNg{TO@bikx&F`}?-tODGgH92aln#-PEGnN zmPY^wDP(kOjn=+#$KQ{6KPDt#$|2HPjDvo?_1tfw%z(t;iq`y;1Q7@>OGVWufTYGy z^V-fPf<#K%>oK<-+ROA^cao+lBF(rozepIm1{19{HjUjT+gfbu6JT_TNz*O>*VZ7a zHLO%f<2D$n1#K*{T4Dae1vWMsh%lgGd*G(&<$rGq1v{kZHkK&6d8#kk6-g(FbkBj= z-1K7ww2h^crqo787`@>JCkN^q*K|RUu@>FwAgWaYYx$igp5d6*-D?Me9%QvrK197{D5fn?ukog}w^sn&)!R0`o_ zFUBC1B2un2p5_-i%iLO#Yvz?Sp)raqeeB!++5h#%kN$^$e=QsM8UTEq`oCwMQR4R7 zwf*EDe>W=loou7g>;4sTGxb~>fyW=gKK~4ijJZK5r2|y?E-pzN`%o%50C@i!5D&h| z0Um2z&h6To(?Cqmz}Yj{^JiSi*A%9U!E$Xrn>3qHsUq&Y3ubpX0M!*2iQcRfgbrAp zIPSrfaeyq>HRjvjFvP|&tga$DZB~vxhp5$DXO}NwluSk`Q0QB4bMM<~xe{%;>h&8L zVtm4tbdBl7am~zNUwMW2H+~b!p);^vX(9{+-}XM_JHNiiILMs+6y0bplBCxVlA{5s zTs(6r>S+)2>oYz{@;^UB{KQd2H9$1h$ufh8Q$~O4r<|#EyWL|>wV#%Y%J44m&d`a^ zKaENt1sgyAv#g%Jgs2XnlKdEb15A=-?5~#jR4e7l%rGH(Wz)8GU%>!F(EZal$rvQs zYP9iS$ZONI1!;QVB99Pj7Fae3$Vd_hK~(rTF~C}6e$|eFNyneoYSjP&InWBiy1daQbG50s|Zm6dKs zrttUQwo`287*=MhFgEVTed>NF^43Z|B2k}R1OsYBqC(dpY^4MAYUfUP@C}%Dt0$ir zSg?$>1ob*AFTTXtuRKLKQtnD2Y=H?9z=-Ive8R$W+K|}(>z(BH$FpeClWy7ryjzuI zXW-b_qyV045>989Uuu)CoUq)EbbrObi9_jM#vIaBX2B*=Bt z#b>p6u!CSi3b&!$w-@GixXMXR-5Cp`byh$0KRJKwI6=LPFs2I}^G!;#a9zYz%J-u1 zjg^~!HZxGhaCm%#G)|nMeU>4EfFN+D%O^9-Wn(ExP}(pNgLU;TC4ZC=zN--nO|S%(+`{%UaU6!z6)Fg@#O=+rIx<+A&JdD%@iCr-Eswm5NM zDF~g0?b1aD%5w0svF>zzE6e?=ioBGXKW4@+>lU}Dr7`xgN8!es5H}w3i(=9{W~JO` zhZ5$mV4r!?v6PwLy9?nOO-Adk2}4Mih_HJPGdCXW+2(t2qqRXVFF}3GB_OmK?mRlN z1DCPi(T(^<6VJ*al@mBmPovMx6A&Y>-%0rWAH-gFJ!~}TazfVlCJ^nlApQZ*25XE4 zEhT2nI#x7a2(k>BYV7n3orM*|c;s|m?Ud@?U6^W(?A+PjHNBdTiQjEX-~F5EHDrC1 z+IRm$njiXaXh2p=0~y0Uu1#x3!w@k&&Gh^da;=35WOp$v6(-NH`*DtO5;*YZ=3~=i zpG9Gb6`N!1I`o=7jBvtzVQkk2P8SyFVred4H$z|+SoA-eyZqlN1^YdC?G#GI#j>No zbzu&&0SyBqsvi)v3t%UsKj%0U5>qZ=*4G`2tdtk~Wd$UoyS{!_ZH#U%0GmDI|7f1rr1=!@2;#GNlkng6PCO;F&+0Ia6T_%4lS(g%bT` zvB9q2Vz=bFPrRxW?q!rq4~Ccr3h!cQY>S;9m!3thnkKT&o>%4jV7>93C4wha)p~GMtE*z zoh%3l3*$F2hEQAfJ$OI5R7SL2T8zyy;v{(;yLt!IyO%M`;KWG;$^k&nRt8g3gvU?t z_zTCW*F!4CklOyuSbo10oBw^7ollNU1{rIBhJcb4wALF`yaksC0<1A)af|}aW`>2# zQpN%H7aK7fUwVXFXQxSDgjSY4$dgwtqNr5jUOiamb`ed3ba zz?ET9TBfxol(M_2D+jQc8a{J*g=H+09+Va{sO7*t)dipr&iAh_;3J8l?l+&GNDMbA z!P`Q~YMf9jg?_yWd<>y+eUEulh}JY3O`dABd32-2R})PD{Kib3S}CGq4aydL0xei; zH7W?JS@v$=$!jFnH30ZJ<_Rl=5XL_A(HT1SEwoxa0%Q>Ul}gZPV4rx*Ghl7^lVcN( z?W&EyS08avZ$J4naN<=sc>?>?6E5Xr{)+P_^BKF{g}u{pDFrjru(;IihPB-tt}P@< z6gD)0a!T71$FS=wh$DBnri&!@;4g-T>!9WS2b?A<)1ED~y-wpOa#3YbLFjDukop$eSwEJ9R9573@yH;<0E0yp1M`R!V5Nxa?zxRXKR>w7v z$RRB2;AB4d@~e{+wtuA(E_*n*>u!QS{1`e(ko6iOf#}FBuA3OT{%?K1H*66p=p?05 zuK8x$cBa4e+qm+Ze}ImR6KwZkQ%gw*#-^u0NVZ1-3gb*q3!q64XozeV^!2BCSkHF! zKF0K|D#C-RcA?~!GdelAOb2v$MO{>J;R_VcbLTV5f;QX~2yQ3|UXBgF(lJEBf%c5eUE2AvWX2L={r%b80F?t( zX?piJXNQVfw<6Qb04p@81*~k`)oD@W=GnLdl`3J)#{*uu!t$p-&5~!OE4Ig`7oU}3<+H77 zi^X)6qTaRxYzJ-`DI+YjJ25(+hh>kwG&(~C?s%r8;0;yDq&38sFC(I;d*2efd7N2m z5kcTKt=3|-rVVt2M2=J_jR;~38)?SIdW$tB*c-Tw1OkpGmM2q#l7dM@-?I$E;|SHj zJXR6#*QsU2Ld{>paRDzI%Svo`X8_wf9fFZMu~d|VMFh?ay4`AVbiKvr8XcZZGFAxyYSTXRQS6lp-8E0Od6%D(KHf@>y2K&SR{Ac*Z51VUc;A;Tz>aU|m9ho7j?;tdD zS=x5xUpe5Cqntsp{o-ew0D5K`re+cQuLG&D&prjuKJ8LGZoSi$ddH{W!R?59A9QID zFCFcb2#cUWDc1y1sYAKdReTFu0Dj$au;>Se*1~uR*4N?jN1X}o?5txRb5FiZI}gHI z%>hhrRNFnrJm5TxoL)+2$WpW!cnRU&BMKeJYsU`2l}ir%$^xU7B(5`fZraiO3-jn_ zk0P(T&VA0w<1jkzSkqz$ToH_Q8PI_TyjTt|{(L@}w%drA87gmoEAb;=Cf#Tv6sTKo z!?fF5GX{e|uqf`y%f+F>EG{DNdw}s%Ct3c&V=z^9z&Bs$tYKnu%9Rnbj43GyEt@>y z^2I_A(R0}XE0`aP=(C>aopat85Dd}dNQV2)ZSGR^x6M!JI|bY$orT95{q`cmX49xp zh92yMY~dOcN(09+2#%CebmBJY>MGIx{g^O>D_0!L97etSZHyCt3%_utsk_$3xW=Nf zF(*kdw!bTV*vlBV`P#V?Ha4(pYrXQjpqt;^&k7fSV3t8+!}&3KVf$8olerF3`bL_z zzh|s*pTSo%OHK5c-og7_v^vV~Plf&_o&0CZ^g6wB zo#$XKbgpMit^$q*OZx&yt>NZ!38D~_W+Vuvr>EGru*lg~O0^WyX|&n5cbfW52T7W( zt~JWl1x;e}Tu^v^jTA^Ep#ny0#E(6}tB*d$(wPgiER?GOskL0OmKmSm^0%oS4m-*g z5L&o7fL&5xk`xn$lq+S7)}(1x=xDdZ))FDOHI(dD0%;);(&ZBSaWRZ#w%w|>?YkHG z{npx`fi=(K21>F3#M-i53BJ-XTr`$ZF}$03Sm}3=Wv&3PYPe!8b^3aF83&fJ{9y{M zM#9@`hO#gutv0W0w0NY^;mIUp2}p&Y9w>GS_qhS!t@W{ii3$$8u9h+I^n6}2cW5D+8f%9ivDo4)#6@gA(GZ-238olC_ZTm~X)*`wr zi2uJ)_j~rm=MeVhf}M&5ojRS~?tO6SGSn&sQ0r_V(4M_h(wT1#n{cglps`$aK(U-U zkh#%-W~-OsJ2nAxk<(mVzKC5|aI9n$IibF8z|sPYjw813^sHqvpyeAd-yZxv*Jt+G z@`&!WGI2t5@4bXsf?iv52FsI^?q_rFEo+DSAr3Amg9fBZVAj{Ee$xj?&zxf8;sR>4 ziqM+C7$(NY5S20}&Cp6xsZ+{px{oEJGG!n*%>vC=2@yfD(dKIIq9Kn6#X6 zDVBc4kWyVyqgE^@rxuVCJRf*UAtXm;`&<8hf|w@<<*uwV0ejjE!QKmNBgs z%7Um=+_Rj&N1^mfyX`EZw1zN1W~pn`83G21wnLEn@%1L*;?F97&$r48&fjBPz*z$? z7)x378}f>)uv10mrsPY$gU4Kw02vb!2ztqBh(Yp`AYu9#9P0~r{ zIooWrqommJ;De-@abtfgnZ~C78z{_Li?J3Jl_*t8u)501=RVJgQ|CB$X^8{~s){fO z2(|XMIk0Fg)BSN{L(StEQvNN1qtt)RNw`ru1MV~jXq}GR)G0+tNsP4^W6>54hl*Jx zsM=nfUCu(wfs{03x886VHfNmUnZvx3w+u85yksm14*UfS&#UhHv(N>dZ~8)DUBHU5 zUCnV(UXYiEI|BYFHMEu+Bnun79H$8B5|(Z&1th>rnf2O6x5SGji7(w*M3dj{{uf@%t!uURwS*Tr`f8REQKHv zU2r5kv(Rojz;y7i16xV#Jl|Rk?C<}U%iFEjU0HbdZp7X97wlJjGf0-g!e!5941fxW z10^$auC&@%bL^OqUJDg^gJ}Py2L5hNVGSoM#jlf#lT50aVYBF#8zyA2Yw>gGkIW;>#!O_ zbV&KcA6jvJT`WMw~uxu<`Co$SE zx^32Vi5uhZm2ex4Bz3DyZ1QO+j=%J zXYbqXo@Gjwx_4MzWwF`mGvFNrL&o2iwSf}-pqC$o)S1EYVR7Bmrwkl3mg)fTwp;v; z9CGhv0o)glBOe3VzyS>2_w;I0#K0nxvrr$H8e_avA~UXuL0H#zJ{^U~R*UQ3{x%pH z#l&qkRbqx!3c4R43f{oX~}=C61@n$yqkG2p{uPf+gGUQK<$bClM~I z`eJ6dVk{`hn37b5+iWgdxMF)1gOY$7q~NS^y4gSqo=P&lAySl;=o)%sErH3bu*goD zRe!ppe;u$tc@67bV*rP}{`ox*ihlu!l6?!5X0ldWlO~e&6{wB6Q5APwxk)*{wXVKx zauU|ou)p@pPTMy&-V^GVE4>zVDIMT5#+g2MS7_Dm`=oP!t!0!wQo8*P!W}y?QexKEAa3>i#EjQ4Ub^6{3dScr16pW)7+S^?{WD^>JJajM(#+kj z>1mfjq5{WsuB>2ByaL;I!gU7_lT$tGmNeaz;;`lQkkYYIyZ12hZGWHU?|qa%tx8^q zHSbC@WJ%F22nLGDa)fEc*sjUP)yqc3Qg3lVH=ZFf)^@ExhA|XHZ@IzJtr=1t9%T1& zcA#zHSz|dOoiANpYA$|WAo_jQ2Em8RWwn$Mbgr^^VqE5IBX2BtW!d2E6LQU*$Cb*s$c0qAic~3v$fn%;CIQsWSvj z=1nrWt&rTJJXn0M1jpj+4pny}(^nghN_^Q$c0>`8)fi*lB_6B<^fC3l`O{c~2m+#7 z6@kEBy2zQAkMZjH%dDm#N`kN+c5{L^8YyqRVK*ua`O*s~Ny~yt5D-{P)7v$T`VMyc zI?KMXKb4(QuunR@XM5mh!vc72*u25SnXHS#y^veY4|X^U$&kHGadQ{|^Tsl7oP?lO zXpv3xXWj$Trg3qM+CSgL4Fi3kR4@rVZ!9lp*sa|0hegoOX6Jzj81p&VZO=lE`2NPG zv3+w_)4=!F6;*5bcxrhfH9Vo=-z>NI@azbIb+$gClw_%uS5jl!aQnDtMI^@V0Mr&uSVYD+h-q^rC`2=FuZa8qgD>29Ip3l?k zVI&93$3nUYzS%i!RCa)EW!Zhb@)ErKB6fBbal?(UYmYnjICfvf>o+KX%0D9v(W@(j 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

    public sealed class ImageMaskSurfaceBrush : RenderSurfaceBrushBase { + private AsyncMutex _renderMutex = new(); + private CompositionMaskBrush _maskBrush; private Uri _uri; @@ -184,14 +186,14 @@ private void OnImageOptionsChanged() { await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { - OnSurfaceBrushUpdated(); + OnImageOptionsUpdated(); }); } }; ImageOptions.Updated += _imageSurfaceOptionsUpdateListener.OnEvent; - OnSurfaceBrushUpdated(); + OnImageOptionsUpdated(); } } @@ -247,14 +249,35 @@ protected async override void OnSurfaceBrushUpdated() return; } - _maskBrush = Window.Current.Compositor.CreateMaskBrush(); - _maskBrush.Source = Target.Brush; + using (await _renderMutex.LockAsync()) + { + _maskBrush = Window.Current.Compositor.CreateMaskBrush(); + _maskBrush.Source = Target.Brush; + + RenderSurface = await Generator.CreateImageMaskSurfaceAsync(_uri, new Size(SurfaceWidth, SurfaceHeight), Padding, ImageOptions ?? ImageSurfaceOptions.Default); + _maskBrush.Mask = Window.Current.Compositor.CreateSurfaceBrush(RenderSurface.Surface); + CompositionBrush = _maskBrush; - RenderSurface = await Generator.CreateImageMaskSurfaceAsync(_uri, new Size(SurfaceWidth, SurfaceHeight), Padding, ImageOptions ?? ImageSurfaceOptions.Default); - _maskBrush.Mask = Window.Current.Compositor.CreateSurfaceBrush(RenderSurface.Surface); - CompositionBrush = _maskBrush; + base.OnSurfaceBrushUpdated(); + } + } - base.OnSurfaceBrushUpdated(); + private async void OnImageOptionsUpdated() + { + if (Generator == null) + { + GetGeneratorInstance(); + } + + if (Target == null || Target.Brush == null || _uri == null || Generator == null || RenderSurface == null) + { + return; + } + + using (await _renderMutex.LockAsync()) + { + await ((IImageMaskSurface)RenderSurface).RedrawAsync(_uri, ImageOptions ?? ImageSurfaceOptions.Default); + } } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageSurfaceBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageSurfaceBrush.cs index e1e09c7f015..be4d871c14c 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageSurfaceBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageSurfaceBrush.cs @@ -19,6 +19,7 @@ public class ImageSurfaceBrush : RenderSurfaceBrushBase private WeakEventListener _imageSurfaceOptionsUpdateListener; private Uri _uri; + private AsyncMutex _renderMutex = new(); /// /// Background Dependency Property @@ -97,20 +98,26 @@ private void OnSourceChanged() } var uri = Source as Uri; - if (uri == null) + try { - var url = Source as string ?? Source.ToString(); - if (!Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out uri)) + if (uri == null) { - _uri = null; - return; + var url = Source as string ?? Source.ToString(); + if (!Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out uri)) + { + _uri = null; + return; + } } - } - if (!IsHttpUri(uri) && !uri.IsAbsoluteUri) + if (!IsHttpUri(uri) && !uri.IsAbsoluteUri) + { + _uri = new Uri("ms-appx:///" + uri.OriginalString.TrimStart('/')); + } + } + catch (Exception ex) { - _uri = new Uri("ms-appx:///" + uri.OriginalString.TrimStart('/')); - return; + var msg = ex.Message; } _uri = uri; @@ -163,14 +170,14 @@ private void OnImageOptionsChanged() { await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { - OnSurfaceBrushUpdated(); + OnImageOptionsUpdated(); }); } }; ImageOptions.Updated += _imageSurfaceOptionsUpdateListener.OnEvent; - OnSurfaceBrushUpdated(); + OnImageOptionsUpdated(); } } @@ -186,13 +193,37 @@ protected async override void OnSurfaceBrushUpdated() if (_uri != null && Generator != null) { - RenderSurface = await Generator.CreateImageSurfaceAsync(_uri, new Size(SurfaceWidth, SurfaceHeight), ImageOptions ?? ImageSurfaceOptions.Default); - CompositionBrush = Window.Current.Compositor.CreateSurfaceBrush(RenderSurface.Surface); + using (await _renderMutex.LockAsync()) + { + RenderSurface = await Generator?.CreateImageSurfaceAsync(_uri, new Size(SurfaceWidth, SurfaceHeight), ImageOptions ?? ImageSurfaceOptions.Default); + if (RenderSurface != null) + { + CompositionBrush = Window.Current.Compositor.CreateSurfaceBrush(RenderSurface.Surface); + } + } } base.OnSurfaceBrushUpdated(); } + private async void OnImageOptionsUpdated() + { + if (Generator == null) + { + GetGeneratorInstance(); + } + + if (_uri == null || Generator == null || RenderSurface == null) + { + return; + } + + using (await _renderMutex.LockAsync()) + { + ((IImageSurface)RenderSurface)?.Redraw(ImageOptions ?? ImageSurfaceOptions.Default); + } + } + /// /// Initializes a new instance of the class. /// diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs index adfca4fcf53..f283f3c77c8 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs @@ -1323,9 +1323,7 @@ public async Task RedrawImageMaskSurfaceAsync(object surfaceLock, } catch (Exception) { - // Do nothing here as RenderBitmap method will fill the surface - // with options.SurfaceBackgroundColor as the image failed to load - // from Uri + // Do nothing here as RenderBitmap method will fill the surface with options.SurfaceBackgroundColor as the image failed to load from the provided Uri. } } From 3ff3f80610e5c624a9eb86b4516f4e2e1c12070b Mon Sep 17 00:00:00 2001 From: Ratish Philip Date: Thu, 15 Jul 2021 07:09:31 -0700 Subject: [PATCH 13/21] Optimized the SurfaceBrushes' rendering. --- .../ImageSurfaceBrushPage.xaml | 5 +- .../ImageSurfaceBrushPage.xaml.cs | 2 - .../Brushes/Base/RenderSurfaceBrushBase.cs | 31 ++++---- .../Brushes/GeometryMaskSurfaceBrush.cs | 14 ++-- .../Brushes/GeometrySurfaceBrush.cs | 18 +++-- .../Brushes/ImageMaskSurfaceBrush.cs | 45 ++++------- .../Brushes/ImageSurfaceBrush.cs | 74 ++++++------------- .../Surface/ImageMaskSurface.cs | 72 +++++++++++++++++- .../Surface/ImageSurface.cs | 24 ++++++ .../Surface/Interfaces/IImageMaskSurface.cs | 17 +++++ .../Surface/Interfaces/IImageSurface.cs | 7 ++ 11 files changed, 192 insertions(+), 117 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageSurfaceBrush/ImageSurfaceBrushPage.xaml b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageSurfaceBrush/ImageSurfaceBrushPage.xaml index cd822b80f42..b31d88889cd 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageSurfaceBrush/ImageSurfaceBrushPage.xaml +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageSurfaceBrush/ImageSurfaceBrushPage.xaml @@ -8,7 +8,7 @@ - + @@ -45,7 +45,8 @@ + Margin="0" + VerticalAlignment="Center" /> diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderSurfaceBrushBase.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderSurfaceBrushBase.cs index 542d4197319..2a7ae843f8c 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderSurfaceBrushBase.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderSurfaceBrushBase.cs @@ -104,6 +104,19 @@ private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChan brush.Refresh(); } + /// + /// Gets the CompositionGenerator Instance + /// + protected void GetGeneratorInstance() + { + if (Window.Current != null) + { + Generator = CompositionGenerator.Instance; + + Generator.DeviceReplaced += OnDeviceReplaced; + } + } + /// protected override async void OnConnected() { @@ -113,26 +126,13 @@ protected override async void OnConnected() { GetGeneratorInstance(); - OnSurfaceBrushUpdated(); + OnSurfaceBrushUpdated(true); } } base.OnConnected(); } - /// - /// Gets the CompositionGenerator Instance - /// - protected void GetGeneratorInstance() - { - if (Window.Current != null) - { - Generator = CompositionGenerator.Instance; - - Generator.DeviceReplaced += OnDeviceReplaced; - } - } - /// protected override async void OnDisconnected() { @@ -172,7 +172,8 @@ private void OnDeviceReplaced(object sender, object e) /// /// Invoked whenever any brush property is updated. /// - protected virtual void OnSurfaceBrushUpdated() + /// Indicates whether the surface needs to be created. + protected virtual void OnSurfaceBrushUpdated(bool createSurface = false) { Updated?.Invoke(this, null); } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs index 310e3dea124..ece6addc519 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs @@ -202,10 +202,8 @@ private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChan } /// - protected override void OnSurfaceBrushUpdated() + protected override void OnSurfaceBrushUpdated(bool createSurface = false) { - CompositionBrush?.Dispose(); - if (Generator == null) { GetGeneratorInstance(); @@ -221,19 +219,19 @@ protected override void OnSurfaceBrushUpdated() _maskBrush = Window.Current.Compositor.CreateMaskBrush(); _maskBrush.Source = Target.Brush; - if (RenderSurface == null) + if (createSurface || (RenderSurface == null)) { + CompositionBrush?.Dispose(); RenderSurface = Generator.CreateGaussianMaskSurface(new Size(SurfaceWidth, SurfaceHeight), Mask.Geometry, offset, (float)BlurRadius); + _maskBrush.Mask = Window.Current.Compositor.CreateSurfaceBrush(RenderSurface.Surface); + CompositionBrush = _maskBrush; } else { ((IGaussianMaskSurface)RenderSurface).Redraw(new Size(SurfaceWidth, SurfaceHeight), Mask.Geometry, offset, (float)BlurRadius); } - _maskBrush.Mask = Window.Current.Compositor.CreateSurfaceBrush(RenderSurface.Surface); - CompositionBrush = _maskBrush; - - base.OnSurfaceBrushUpdated(); + base.OnSurfaceBrushUpdated(createSurface); } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometrySurfaceBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometrySurfaceBrush.cs index 77b976a8fd1..dc1550ec1e6 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometrySurfaceBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometrySurfaceBrush.cs @@ -347,10 +347,8 @@ await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => } /// - protected override void OnSurfaceBrushUpdated() + protected override void OnSurfaceBrushUpdated(bool createSurface = false) { - CompositionBrush?.Dispose(); - if (Generator == null) { GetGeneratorInstance(); @@ -368,10 +366,18 @@ protected override void OnSurfaceBrushUpdated() var strokeStyle = (RenderStrokeStyle == null) ? new CanvasStrokeStyle() : RenderStrokeStyle.GetCanvasStrokeStyle(); var canvasstroke = new CanvasStroke(strokeBrush, (float)StrokeThickness, strokeStyle); - RenderSurface = Generator.CreateGeometrySurface(new Size(SurfaceWidth, SurfaceHeight), Geometry.Geometry, canvasstroke, fillBrush, bgBrush); - CompositionBrush = Window.Current.Compositor.CreateSurfaceBrush(RenderSurface.Surface); + if (createSurface || (RenderSurface == null)) + { + CompositionBrush?.Dispose(); + RenderSurface = Generator.CreateGeometrySurface(new Size(SurfaceWidth, SurfaceHeight), Geometry.Geometry, canvasstroke, fillBrush, bgBrush); + CompositionBrush = Window.Current.Compositor.CreateSurfaceBrush(RenderSurface.Surface); + } + else + { + ((IGeometrySurface)RenderSurface).Redraw(new Size(SurfaceWidth, SurfaceHeight), Geometry.Geometry, canvasstroke, fillBrush, bgBrush); + } - base.OnSurfaceBrushUpdated(); + base.OnSurfaceBrushUpdated(createSurface); } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageMaskSurfaceBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageMaskSurfaceBrush.cs index 25717b5889a..60897aa5ac6 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageMaskSurfaceBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageMaskSurfaceBrush.cs @@ -16,14 +16,12 @@ namespace Microsoft.Toolkit.Uwp.UI.Media /// public sealed class ImageMaskSurfaceBrush : RenderSurfaceBrushBase { - private AsyncMutex _renderMutex = new(); + private WeakEventListener _targetUpdateListener; + private WeakEventListener _imageSurfaceOptionsUpdateListener; private CompositionMaskBrush _maskBrush; private Uri _uri; - private WeakEventListener _targetUpdateListener; - private WeakEventListener _imageSurfaceOptionsUpdateListener; - /// /// Target Dependency Property /// @@ -69,14 +67,14 @@ private void OnTargetChanged() { await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { - OnSurfaceBrushUpdated(); + OnSurfaceBrushUpdated(true); }); } }; Target.Updated += _targetUpdateListener.OnEvent; - OnSurfaceBrushUpdated(); + OnSurfaceBrushUpdated(true); } } @@ -133,12 +131,11 @@ private void OnMaskChanged() if (!IsHttpUri(uri) && !uri.IsAbsoluteUri) { _uri = new Uri("ms-appx:///" + uri.OriginalString.TrimStart('/')); - return; } _uri = uri; - OnSurfaceBrushUpdated(); + OnSurfaceBrushUpdated(true); } /// @@ -186,14 +183,14 @@ private void OnImageOptionsChanged() { await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { - OnImageOptionsUpdated(); + OnSurfaceBrushUpdated(); }); } }; ImageOptions.Updated += _imageSurfaceOptionsUpdateListener.OnEvent; - OnImageOptionsUpdated(); + OnSurfaceBrushUpdated(); } } @@ -235,10 +232,8 @@ private void OnPaddingChanged() } /// - protected async override void OnSurfaceBrushUpdated() + protected async override void OnSurfaceBrushUpdated(bool createSurface = false) { - CompositionBrush?.Dispose(); - if (Generator == null) { GetGeneratorInstance(); @@ -249,35 +244,23 @@ protected async override void OnSurfaceBrushUpdated() return; } - using (await _renderMutex.LockAsync()) + if (createSurface || (RenderSurface == null)) { + CompositionBrush?.Dispose(); + _maskBrush = Window.Current.Compositor.CreateMaskBrush(); _maskBrush.Source = Target.Brush; RenderSurface = await Generator.CreateImageMaskSurfaceAsync(_uri, new Size(SurfaceWidth, SurfaceHeight), Padding, ImageOptions ?? ImageSurfaceOptions.Default); _maskBrush.Mask = Window.Current.Compositor.CreateSurfaceBrush(RenderSurface.Surface); CompositionBrush = _maskBrush; - - base.OnSurfaceBrushUpdated(); - } - } - - private async void OnImageOptionsUpdated() - { - if (Generator == null) - { - GetGeneratorInstance(); } - - if (Target == null || Target.Brush == null || _uri == null || Generator == null || RenderSurface == null) + else { - return; + ((IImageMaskSurface)RenderSurface)?.Redraw(new Size(SurfaceWidth, SurfaceHeight), Padding, ImageOptions ?? ImageSurfaceOptions.Default); } - using (await _renderMutex.LockAsync()) - { - await ((IImageMaskSurface)RenderSurface).RedrawAsync(_uri, ImageOptions ?? ImageSurfaceOptions.Default); - } + base.OnSurfaceBrushUpdated(createSurface); } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageSurfaceBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageSurfaceBrush.cs index be4d871c14c..f7b399fdab3 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageSurfaceBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageSurfaceBrush.cs @@ -19,7 +19,6 @@ public class ImageSurfaceBrush : RenderSurfaceBrushBase private WeakEventListener _imageSurfaceOptionsUpdateListener; private Uri _uri; - private AsyncMutex _renderMutex = new(); /// /// Background Dependency Property @@ -98,31 +97,25 @@ private void OnSourceChanged() } var uri = Source as Uri; - try - { - if (uri == null) - { - var url = Source as string ?? Source.ToString(); - if (!Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out uri)) - { - _uri = null; - return; - } - } - if (!IsHttpUri(uri) && !uri.IsAbsoluteUri) + if (uri == null) + { + var url = Source as string ?? Source.ToString(); + if (!Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out uri)) { - _uri = new Uri("ms-appx:///" + uri.OriginalString.TrimStart('/')); + _uri = null; + return; } } - catch (Exception ex) + + if (!IsHttpUri(uri) && !uri.IsAbsoluteUri) { - var msg = ex.Message; + _uri = new Uri("ms-appx:///" + uri.OriginalString.TrimStart('/')); } _uri = uri; - OnSurfaceBrushUpdated(); + OnSurfaceBrushUpdated(true); } /// @@ -170,65 +163,42 @@ private void OnImageOptionsChanged() { await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { - OnImageOptionsUpdated(); + OnSurfaceBrushUpdated(); }); } }; ImageOptions.Updated += _imageSurfaceOptionsUpdateListener.OnEvent; - OnImageOptionsUpdated(); + OnSurfaceBrushUpdated(); } } /// - protected async override void OnSurfaceBrushUpdated() + protected async override void OnSurfaceBrushUpdated(bool createSurface = false) { - CompositionBrush?.Dispose(); - if (Generator == null) { GetGeneratorInstance(); } - if (_uri != null && Generator != null) - { - using (await _renderMutex.LockAsync()) - { - RenderSurface = await Generator?.CreateImageSurfaceAsync(_uri, new Size(SurfaceWidth, SurfaceHeight), ImageOptions ?? ImageSurfaceOptions.Default); - if (RenderSurface != null) - { - CompositionBrush = Window.Current.Compositor.CreateSurfaceBrush(RenderSurface.Surface); - } - } - } - - base.OnSurfaceBrushUpdated(); - } - - private async void OnImageOptionsUpdated() - { - if (Generator == null) + if (_uri == null || Generator == null) { - GetGeneratorInstance(); + return; } - if (_uri == null || Generator == null || RenderSurface == null) + if (createSurface || (RenderSurface == null)) { - return; + CompositionBrush?.Dispose(); + RenderSurface = await Generator?.CreateImageSurfaceAsync(_uri, new Size(SurfaceWidth, SurfaceHeight), ImageOptions ?? ImageSurfaceOptions.Default); + CompositionBrush = Window.Current.Compositor.CreateSurfaceBrush(RenderSurface.Surface); } - - using (await _renderMutex.LockAsync()) + else { - ((IImageSurface)RenderSurface)?.Redraw(ImageOptions ?? ImageSurfaceOptions.Default); + ((IImageSurface)RenderSurface)?.Redraw(new Size(SurfaceWidth, SurfaceHeight), ImageOptions ?? ImageSurfaceOptions.Default); } - } - /// - /// Initializes a new instance of the class. - /// - public ImageSurfaceBrush() - { + base.OnSurfaceBrushUpdated(createSurface); } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageMaskSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageMaskSurface.cs index b0e30081582..5789e25ee0d 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageMaskSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageMaskSurface.cs @@ -163,7 +163,7 @@ public void Redraw() } /// - /// Redraws the IImageMaskSurface with the given image options + /// Redraws the IImageMaskSurface with the given image options. /// /// The image's resize, alignment options and blur radius in the allocated space. public void Redraw(ImageSurfaceOptions options) @@ -175,6 +175,76 @@ public void Redraw(ImageSurfaceOptions options) RedrawSurface(); } + /// + /// Redraws the IImageMaskSurface using the given padding and image options. + /// + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. + /// The image's resize, alignment and blur radius options in the allocated space. + public void Redraw(Thickness padding, ImageSurfaceOptions options) + { + // Set the mask padding + MaskPadding = padding; + + // Set the image options + Options = options; + + // Redraw the IImageMaskSurface + RedrawSurface(); + } + + /// + /// Resizes and redraws the IImageMaskSurface using the given image options. + /// + /// New size of the IImageMaskSurface. + /// The image's resize, alignment and blur radius options in the allocated space. + public void Redraw(Size size, ImageSurfaceOptions options) + { + // Resize if required + if (Size != size) + { + // resize the IImageMaskSurface + _generator.ResizeDrawingSurface(_surfaceLock, _surface, size); + + // Set the size + Size = _surface?.Size ?? new Size(0, 0); + } + + // Set the image options + Options = options; + + // Redraw the IImageMaskSurface + RedrawSurface(); + } + + /// + /// Resizes and redraws the IImageMaskSurface using the given padding and image options. + /// + /// New size of the IImageMaskSurface. + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where + /// the mask, created from the loaded image's alpha values, should be rendered. + /// The image's resize, alignment and blur radius options in the allocated space. + public void Redraw(Size size, Thickness padding, ImageSurfaceOptions options) + { + // Resize if required + if (Size != size) + { + // resize the IImageMaskSurface + _generator.ResizeDrawingSurface(_surfaceLock, _surface, size); + + // Set the size + Size = _surface?.Size ?? new Size(0, 0); + } + + // Set the mask padding + MaskPadding = padding; + + // Set the image options + Options = options; + + // Redraw the IImageMaskSurface + RedrawSurface(); + } + /// /// Redraws the IImageMaskSurface using the alpha values of image in the given imageSurface. /// diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurface.cs index 7fa11785817..29ad6acc938 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurface.cs @@ -162,6 +162,30 @@ public void Redraw(ImageSurfaceOptions options) RedrawSurface(); } + /// + /// Resizes and redraws the IImageSurface using the given options. + /// + /// New size of the IImageMaskSurface. + /// Describes the image's resize, alignment options in the allocated space. + public void Redraw(Size size, ImageSurfaceOptions options) + { + // Resize the surface only if AutoResize option is disabled + if (!Options.AutoResize && Size != size) + { + // resize the IImageMaskSurface + _generator.ResizeDrawingSurface(_surfaceLock, _surface, size); + + // Set the size + Size = _surface?.Size ?? new Size(0, 0); + } + + // Set the image options + Options = options; + + // Redraw the IImageSurface + RedrawSurface(); + } + /// /// Redraws the IImageSurface (using the image in the given imageSurface) or the IImageMaskSurface /// (using the alpha values of image in the given imageSurface). diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IImageMaskSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IImageMaskSurface.cs index 8c32c466a7b..4085e242c5c 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IImageMaskSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IImageMaskSurface.cs @@ -112,6 +112,23 @@ public interface IImageMaskSurface : IImageSurface /// Describes the image's resize, alignment and blur radius options in the allocated space. void Redraw(IImageMaskSurface imageMaskSurface, Size size, Thickness padding, ImageSurfaceOptions options); + /// + /// Resizes and redraws the IImageMaskSurface using the given CanvasBitmap's alpha values with the given padding using the given options. + /// + /// + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. + /// + /// Describes the image's resize, alignment and blur radius options in the allocated space. + void Redraw(Thickness padding, ImageSurfaceOptions options); + + /// + /// Resizes and redraws the IImageMaskSurface using the given padding and image options. + /// + /// New size of the IImageMaskSurface. + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. + /// Describes the image's resize, alignment and blur radius options in the allocated space. + void Redraw(Size size, Thickness padding, ImageSurfaceOptions options); + /// /// Resizes and redraws the IImageMaskSurface using the given CanvasBitmap's alpha values with the given padding using the given options. /// diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IImageSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IImageSurface.cs index 6c7b78745d5..a3e94040785 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IImageSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IImageSurface.cs @@ -76,6 +76,13 @@ public interface IImageSurface : IRenderSurface /// The image's resize and alignment options in the allocated space. void Redraw(ImageSurfaceOptions options); + /// + /// Resizes and redraws the IImageSurface using the given options. + /// + /// New size of the IImageMaskSurface. + /// Describes the image's resize, alignment options in the allocated space. + void Redraw(Size size, ImageSurfaceOptions options); + /// /// Redraws the IImageSurface (using the image in the given imageSurface) or the IImageMaskSurface (using the alpha values of image in the given imageSurface). /// From ede22467f2d02e7dfb4a1ba54c0bc190a578c0d5 Mon Sep 17 00:00:00 2001 From: Ratish Philip Date: Sat, 17 Jul 2021 08:54:01 -0700 Subject: [PATCH 14/21] Code and comments cleanup. --- .../GeometryMaskSurfaceBrushPage.xaml.cs | 4 + .../GeometrySurfaceBrushPage.xaml.cs | 4 + .../ImageMaskSurfaceBrushPage.xaml.cs | 15 +- .../ImageSurfaceBrushPage.xaml.cs | 4 + .../SamplePages/samples.json | 8 +- .../Brushes/Base/RenderCanvasBrushBase.cs | 2 +- .../Brushes/Base/RenderSurfaceBrushBase.cs | 16 +- .../Brushes/GeometryMaskSurfaceBrush.cs | 14 +- .../Brushes/GeometrySurfaceBrush.cs | 24 +- .../Brushes/ImageMaskSurfaceBrush.cs | 4 +- .../Brushes/LinearGradientCanvasBrush.cs | 4 +- .../Brushes/RadialGradientCanvasBrush.cs | 6 +- .../Geometry/CanvasCircleGeometry.cs | 2 +- .../Geometry/CanvasCombinedGeometry.cs | 8 +- .../Geometry/CanvasCoreGeometry.cs | 4 +- .../Geometry/CanvasPathGeometry.cs | 2 +- .../Geometry/CanvasRectangleGeometry.cs | 2 +- .../Geometry/ICanvasPathGeometry.cs | 6 +- .../Geometry/StrokeStyle.cs | 4 + .../Surface/CompositionExtensions.cs | 382 ------------- .../Surface/CompositionGenerator.cs | 395 ++------------ .../Surface/CompositorExtensions.cs | 502 +++++++++--------- .../Surface/GaussianMaskSurface.cs | 93 +--- .../Surface/GeometryMaskSurface.cs | 39 +- .../Surface/GeometrySurface.cs | 298 ++--------- .../Surface/ImageMaskSurface.cs | 292 ++-------- .../Surface/ImageSurface.cs | 147 ++--- .../Surface/ImageSurfaceOptions.cs | 20 +- .../Interfaces/ICompositionGenerator.cs | 168 +++--- .../ICompositionGeneratorInternal.cs | 70 ++- .../Interfaces/IGeometryMaskSurface.cs | 12 +- .../Surface/Interfaces/IGeometrySurface.cs | 158 +++--- .../Surface/Interfaces/IImageMaskSurface.cs | 52 +- .../Surface/Interfaces/IImageSurface.cs | 7 + .../Converters/Vector2Converter.cs | 77 --- .../Converters/Vector4Converter.cs | 77 --- 36 files changed, 762 insertions(+), 2160 deletions(-) delete mode 100644 Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionExtensions.cs delete mode 100644 Microsoft.Toolkit.Uwp.UI/Converters/Vector2Converter.cs delete mode 100644 Microsoft.Toolkit.Uwp.UI/Converters/Vector4Converter.cs diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurfaceBrushPage.xaml.cs b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurfaceBrushPage.xaml.cs index 62e1a528fd9..bac5cdfe5a1 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurfaceBrushPage.xaml.cs +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurfaceBrushPage.xaml.cs @@ -1,3 +1,7 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + using Windows.UI.Xaml.Controls; // The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238 diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushPage.xaml.cs b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushPage.xaml.cs index aa5950d57a7..e2f9531467e 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushPage.xaml.cs +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushPage.xaml.cs @@ -1,3 +1,7 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + using Windows.UI.Xaml.Controls; // The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238 diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageMaskSurfaceBrush/ImageMaskSurfaceBrushPage.xaml.cs b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageMaskSurfaceBrush/ImageMaskSurfaceBrushPage.xaml.cs index 404ff7d0b49..6c22fa25b12 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageMaskSurfaceBrush/ImageMaskSurfaceBrushPage.xaml.cs +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageMaskSurfaceBrush/ImageMaskSurfaceBrushPage.xaml.cs @@ -1,3 +1,7 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + using System; using System.Collections.Generic; using System.IO; @@ -27,7 +31,6 @@ public sealed partial class ImageMaskSurfaceBrushPage : Page public ImageMaskSurfaceBrushPage() { this.InitializeComponent(); - this.SizeChanged += this.OnPageSizeChanged; _maskImages = new Dictionary { @@ -51,14 +54,6 @@ public ImageMaskSurfaceBrushPage() TargetImages.SelectedIndex = 0; } - private void OnPageSizeChanged(object sender, SizeChangedEventArgs e) - { - //MaskImageBrush.SurfaceHeight = MaskGrid.ActualHeight; - //MaskImageBrush.SurfaceWidth = MaskGrid.ActualWidth; - //TargetImageBrush.SurfaceHeight = TargetGrid.ActualHeight; - //TargetImageBrush.SurfaceWidth = TargetGrid.ActualWidth; - } - private void OnMaskImageChanged(object sender, SelectionChangedEventArgs e) { var image = MaskImages.SelectedValue as string; @@ -70,7 +65,6 @@ private void OnMaskImageChanged(object sender, SelectionChangedEventArgs e) try { MaskImageBrush.Source = _maskImages[image]; - //ImageMaskBrush.Mask = _maskImages[image]; } catch (Exception ex) { @@ -89,7 +83,6 @@ private void OnTargetImageChanged(object sender, SelectionChangedEventArgs e) try { TargetImageBrush.Source = _targetImages[image]; - //MaskTargetImageBrush.Source = _targetImages[image]; } catch (Exception ex) { diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageSurfaceBrush/ImageSurfaceBrushPage.xaml.cs b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageSurfaceBrush/ImageSurfaceBrushPage.xaml.cs index 83b0a32423b..1761b4b184a 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageSurfaceBrush/ImageSurfaceBrushPage.xaml.cs +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageSurfaceBrush/ImageSurfaceBrushPage.xaml.cs @@ -1,3 +1,7 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + using System; using System.Collections.Generic; using Windows.UI.Xaml.Controls; diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json index d392178869d..5f2bf4fe8c0 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json @@ -1102,7 +1102,7 @@ "XamlCodeFile": "GeometrySurfaceBrushXaml.bind", "Icon": "/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrush.png", "ApiCheck": "Windows.UI.Xaml.Media.XamlCompositionBrushBase", - "DocumentationUrl": "https://raw.githubusercontent.com/MicrosoftDocs/WindowsCommunityToolkitDocs/master/docs/brushes/BackdropBlurBrush.md" + "DocumentationUrl": "" }, { "Name": "GeometryMaskSurfaceBrush", @@ -1112,7 +1112,7 @@ "XamlCodeFile": "GeometryMaskSurfaceBrushXaml.bind", "Icon": "/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurfaceBrush.png", "ApiCheck": "Windows.UI.Xaml.Media.XamlCompositionBrushBase", - "DocumentationUrl": "https://raw.githubusercontent.com/MicrosoftDocs/WindowsCommunityToolkitDocs/master/docs/brushes/BackdropBlurBrush.md" + "DocumentationUrl": "" }, { "Name": "ImageSurfaceBrush", @@ -1122,7 +1122,7 @@ "XamlCodeFile": "ImageSurfaceBrushXaml.bind", "Icon": "/SamplePages/ImageSurfaceBrush/ImageSurfaceBrush.png", "ApiCheck": "Windows.UI.Xaml.Media.XamlCompositionBrushBase", - "DocumentationUrl": "https://raw.githubusercontent.com/MicrosoftDocs/WindowsCommunityToolkitDocs/master/docs/brushes/BackdropBlurBrush.md" + "DocumentationUrl": "" }, { "Name": "ImageMaskSurfaceBrush", @@ -1132,7 +1132,7 @@ "XamlCodeFile": "ImageMaskSurfaceBrushXaml.bind", "Icon": "/SamplePages/ImageMaskSurfaceBrush/ImageMaskSurfaceBrush.png", "ApiCheck": "Windows.UI.Xaml.Media.XamlCompositionBrushBase", - "DocumentationUrl": "https://raw.githubusercontent.com/MicrosoftDocs/WindowsCommunityToolkitDocs/master/docs/brushes/BackdropBlurBrush.md" + "DocumentationUrl": "" } ] }, diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderCanvasBrushBase.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderCanvasBrushBase.cs index 5d3619edf1f..aada20fffbe 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderCanvasBrushBase.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderCanvasBrushBase.cs @@ -11,7 +11,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Media { /// - /// Abstract base class for SolidColorCanvasBrush, LinearGradientCanvasBrush and RadialGradientCanvasBrush + /// Abstract base class for SolidColorCanvasBrush, LinearGradientCanvasBrush and RadialGradientCanvasBrush which are XAML equivalents of Win2d brushes. /// public abstract class RenderCanvasBrushBase : DependencyObject, IDisposable { diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderSurfaceBrushBase.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderSurfaceBrushBase.cs index 2a7ae843f8c..d3794ded81e 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderSurfaceBrushBase.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/Base/RenderSurfaceBrushBase.cs @@ -10,7 +10,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Media { /// - /// Base class for RenderSurface brushes + /// Base class for RenderSurface brushes. /// public abstract class RenderSurfaceBrushBase : XamlCompositionBrushBase { @@ -82,10 +82,10 @@ public double SurfaceHeight protected ICompositionGenerator Generator { get; set; } /// - /// Method that is called whenever the dependency properties of the Brush changes + /// Method that is called whenever the dependency properties of the Brush changes. /// - /// The object whose property has changed - /// Event arguments + /// The object whose property has changed. + /// Event arguments. private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var brush = (RenderSurfaceBrushBase)d; @@ -105,7 +105,7 @@ private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChan } /// - /// Gets the CompositionGenerator Instance + /// Gets the CompositionGenerator Instance. /// protected void GetGeneratorInstance() { @@ -161,8 +161,8 @@ protected override async void OnDisconnected() /// /// Handler for the DeviceReplaced event. /// - /// Sender - /// EventArgs + /// Sender. + /// EventArgs. private void OnDeviceReplaced(object sender, object e) { OnDisconnected(); @@ -194,7 +194,7 @@ public void Refresh() } /// - /// Checks if the URI starts with http: or https: + /// Checks if the URI starts with http: or https:. /// /// URI. /// True if it does, otherwise false. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs index ece6addc519..5f231c3d717 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs @@ -43,8 +43,8 @@ public RenderSurfaceBrushBase Target /// /// Handles changes to the Target property. /// - /// - /// DependencyProperty changed event arguments + /// . + /// DependencyProperty changed event arguments. private static void OnTargetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var geometryMaskSurfaceBrush = (GeometryMaskSurfaceBrush)d; @@ -99,8 +99,8 @@ public CanvasCoreGeometry Mask /// /// Handles changes to the Mask property. /// - /// - /// DependencyProperty changed event arguments + /// . + /// DependencyProperty changed event arguments. private static void OnMaskChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var geometryMaskSurfaceBrush = (GeometryMaskSurfaceBrush)d; @@ -189,10 +189,10 @@ public double BlurRadius } /// - /// Method that is called whenever the dependency properties of the Brush changes + /// Method that is called whenever the dependency properties of the Brush changes. /// - /// The object whose property has changed - /// Event arguments + /// The object whose property has changed. + /// Event arguments. private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var brush = (GeometryMaskSurfaceBrush)d; diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometrySurfaceBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometrySurfaceBrush.cs index dc1550ec1e6..a570fab0870 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometrySurfaceBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometrySurfaceBrush.cs @@ -45,8 +45,8 @@ public CanvasCoreGeometry Geometry /// /// Handles changes to the Geometry property. /// - /// - /// DependencyProperty changed event arguments + /// . + /// DependencyProperty changed event arguments. private static void OnGeometryChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var maskSurfaceBrush = (GeometrySurfaceBrush)d; @@ -101,8 +101,8 @@ public RenderCanvasBrushBase Stroke /// /// Handles changes to the Stroke property. /// - /// - /// DependencyProperty changed event arguments + /// . + /// DependencyProperty changed event arguments. private static void OnStrokeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var geometrySurfaceBrush = (GeometrySurfaceBrush)d; @@ -157,8 +157,8 @@ public double StrokeThickness /// /// Handles changes to the StrokeThickness property. /// - /// - /// DependencyProperty changed event arguments + /// . + /// DependencyProperty changed event arguments. private static void OnStrokeThicknessChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var geometrySurfaceBrush = (GeometrySurfaceBrush)d; @@ -199,8 +199,8 @@ public StrokeStyle RenderStrokeStyle /// /// Handles changes to the RenderStrokeStyle property. /// - /// - /// DependencyProperty changed event arguments + /// . + /// DependencyProperty changed event arguments. private static void OnRenderStrokeStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var geometrySurfaceBrush = (GeometrySurfaceBrush)d; @@ -255,8 +255,8 @@ public RenderCanvasBrushBase FillBrush /// /// Handles changes to the FillBrush property. /// - /// - /// DependencyProperty changed event arguments + /// . + /// DependencyProperty changed event arguments. private static void OnFillBrushChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var geometrySurfaceBrush = (GeometrySurfaceBrush)d; @@ -311,8 +311,8 @@ public RenderCanvasBrushBase BackgroundBrush /// /// Handles changes to the BackgroundBrush property. /// - /// - /// DependencyProperty changed event arguments + /// . + /// DependencyProperty changed event arguments. private static void OnBackgroundBrushChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var geometrySurfaceBrush = (GeometrySurfaceBrush)d; diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageMaskSurfaceBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageMaskSurfaceBrush.cs index 60897aa5ac6..42c672996e8 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageMaskSurfaceBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageMaskSurfaceBrush.cs @@ -251,13 +251,13 @@ protected async override void OnSurfaceBrushUpdated(bool createSurface = false) _maskBrush = Window.Current.Compositor.CreateMaskBrush(); _maskBrush.Source = Target.Brush; - RenderSurface = await Generator.CreateImageMaskSurfaceAsync(_uri, new Size(SurfaceWidth, SurfaceHeight), Padding, ImageOptions ?? ImageSurfaceOptions.Default); + RenderSurface = await Generator.CreateImageMaskSurfaceAsync(_uri, new Size(SurfaceWidth, SurfaceHeight), Padding, ImageOptions ?? ImageSurfaceOptions.DefaultImageMaskOptions); _maskBrush.Mask = Window.Current.Compositor.CreateSurfaceBrush(RenderSurface.Surface); CompositionBrush = _maskBrush; } else { - ((IImageMaskSurface)RenderSurface)?.Redraw(new Size(SurfaceWidth, SurfaceHeight), Padding, ImageOptions ?? ImageSurfaceOptions.Default); + ((IImageMaskSurface)RenderSurface)?.Redraw(new Size(SurfaceWidth, SurfaceHeight), Padding, ImageOptions ?? ImageSurfaceOptions.DefaultImageMaskOptions); } base.OnSurfaceBrushUpdated(createSurface); diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/LinearGradientCanvasBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/LinearGradientCanvasBrush.cs index 0cf0a5af527..c29f1a11ac3 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/LinearGradientCanvasBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/LinearGradientCanvasBrush.cs @@ -166,8 +166,8 @@ public GradientStopCollection Stops /// /// Method that is called whenever the dependency properties of the Brush changes /// - /// The object whose property has changed - /// Event arguments + /// The object whose property has changed. + /// Event arguments. private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var brush = (LinearGradientCanvasBrush)d; diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/RadialGradientCanvasBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/RadialGradientCanvasBrush.cs index 6168152b1ef..a95fb493955 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/RadialGradientCanvasBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/RadialGradientCanvasBrush.cs @@ -209,10 +209,10 @@ public GradientStopCollection Stops } /// - /// Method that is called whenever the dependency properties of the Brush changes + /// Method that is called whenever the dependency properties of the Brush changes. /// - /// The object whose property has changed - /// Event arguments + /// The object whose property has changed. + /// Event arguments. private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var brush = (RadialGradientCanvasBrush)d; diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCircleGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCircleGeometry.cs index bc4ad0ea261..c084de6bbba 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCircleGeometry.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCircleGeometry.cs @@ -68,7 +68,7 @@ public double Radius } /// - /// Method that is called whenever the dependency properties of the Brush changes + /// Method that is called whenever the dependency properties of the Brush . /// /// The object whose property has changed /// Event arguments diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCombinedGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCombinedGeometry.cs index 9255f7fe3da..30cc1a8eaf3 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCombinedGeometry.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCombinedGeometry.cs @@ -40,8 +40,8 @@ public CanvasCoreGeometry Geometry1 /// /// Handles changes to the Geometry1 property. /// - /// - /// DependencyProperty changed event arguments + /// . + /// DependencyProperty changed event arguments. private static void OnGeometry1Changed(DependencyObject d, DependencyPropertyChangedEventArgs e) { var combinedGeometry = (CanvasCombinedGeometry)d; @@ -96,8 +96,8 @@ public CanvasCoreGeometry Geometry2 /// /// Handles changes to the Geometry2 property. /// - /// - /// DependencyProperty changed event arguments + /// . + /// DependencyProperty changed event arguments. private static void OnGeometry2Changed(DependencyObject d, DependencyPropertyChangedEventArgs e) { var combinedGeometry = (CanvasCombinedGeometry)d; diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCoreGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCoreGeometry.cs index 8e91ea716eb..a005080b60a 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCoreGeometry.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCoreGeometry.cs @@ -42,8 +42,8 @@ public CanvasGeometry Geometry /// /// Handles changes to the Geometry property. /// - /// CanvasCoreGeometry - /// DependencyProperty changed event arguments + /// CanvasCoreGeometry. + /// DependencyProperty changed event arguments. private static void OnGeometryChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var coreGeometry = (CanvasCoreGeometry)d; diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasPathGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasPathGeometry.cs index 4e0bcf7c0fb..318f93884dc 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasPathGeometry.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasPathGeometry.cs @@ -13,7 +13,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Media { /// - /// Represents a complex vector-based shape that may be composed of arcs, curves, ellipses, lines, rectangles, rounded rectangles, squircles. + /// Represents a complex vector-based shape geometry that may be composed of arcs, curves, ellipses, lines, rectangles, rounded rectangles, squircles. /// Also provides several helper methods to create Win2d objects. /// public class CanvasPathGeometry : CanvasCoreGeometry diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasRectangleGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasRectangleGeometry.cs index cec4b71a978..b970952864a 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasRectangleGeometry.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasRectangleGeometry.cs @@ -8,7 +8,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Media { /// - /// Represents a rectangular shape + /// Represents a rectangular geometry object with the specified extents. /// public class CanvasRectangleGeometry : CanvasCoreGeometry { diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/ICanvasPathGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/ICanvasPathGeometry.cs index 83fc9e94846..00674cf87b1 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/ICanvasPathGeometry.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/ICanvasPathGeometry.cs @@ -1,3 +1,7 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + using Microsoft.Graphics.Canvas.Geometry; namespace Microsoft.Toolkit.Uwp.UI.Media @@ -5,7 +9,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Media internal interface ICanvasPathGeometry { /// - /// Gets the associate CanvasGeometry + /// Gets the associated CanvasGeometry. /// CanvasGeometry Geometry { get; } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/StrokeStyle.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/StrokeStyle.cs index 6115d073d3a..0415af082b1 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/StrokeStyle.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/StrokeStyle.cs @@ -1,3 +1,7 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + using System; using System.Collections.Generic; using System.Linq; diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionExtensions.cs deleted file mode 100644 index c3c3600a91e..00000000000 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionExtensions.cs +++ /dev/null @@ -1,382 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Collections.Generic; -using System.Linq; -using Microsoft.Graphics.Canvas; -using Microsoft.Graphics.Canvas.Effects; -using Windows.UI; -using Windows.UI.Composition; -using Windows.UI.Xaml; -using Windows.UI.Xaml.Media; - -namespace Microsoft.Toolkit.Uwp.UI.Media -{ - /// - /// Extension Methods for Compositor - /// - public static class CompositionExtensions - { - /// - /// Creates a custom shaped Effect Brush using BackdropBrush and an IGeometryMaskSurface - /// - /// Compositor - /// IGeometryMaskSurface - /// Color to blend in the BackdropBrush - /// Blur Amount of the Backdrop Brush - /// Backdrop Brush (optional). If not provided, then compositor creates it. - /// CompositionEffectBrush - public static CompositionEffectBrush CreateMaskedBackdropBrush(this Compositor compositor, IGeometryMaskSurface mask, Color blendColor, float blurAmount, CompositionBackdropBrush backdropBrush = null) - { - return CompositionExtensions.CreateBackdropBrush(compositor, mask, blendColor, blurAmount, backdropBrush); - } - - /// - /// Creates a custom shaped Effect Brush using BackdropBrush and an IGaussianMaskSurface - /// - /// Compositor - /// IGeometryMaskSurface - /// Color to blend in the BackdropBrush - /// Blur Amount of the Backdrop Brush - /// Backdrop Brush (optional). If not provided, then compositor creates it. - /// CompositionEffectBrush - public static CompositionEffectBrush CreateGaussianMaskedBackdropBrush(this Compositor compositor, IGaussianMaskSurface mask, Color blendColor, float blurRadius, CompositionBackdropBrush backdropBrush = null) - { - return CompositionExtensions.CreateBackdropBrush(compositor, mask, blendColor, blurRadius, backdropBrush); - } - - /// - /// Creates a custom shaped Effect Brush using BackdropBrush and an IGeometryMaskSurface or an IGaussianMaskSurface - /// - /// Compositor - /// IGeometryMaskSurface or IGaussianMaskSurface - /// Color to blend in the BackdropBrush - /// Blur Amount of the Backdrop Brush - /// Backdrop Brush (optional). If not provided, then compositor creates it. - /// CompositionEffectBrush - internal static CompositionEffectBrush CreateBackdropBrush(Compositor compositor, IRenderSurface mask, Color blendColor, float blurAmount, CompositionBackdropBrush backdropBrush = null) - { - // Blur Effect - var blurEffect = new Microsoft.Graphics.Canvas.Effects.GaussianBlurEffect() - { - Name = "Blur", - BlurAmount = blurAmount, - BorderMode = EffectBorderMode.Hard, - Optimization = EffectOptimization.Balanced, - Source = new CompositionEffectSourceParameter("backdrop"), - }; - - // Blend Effect - var blendEffect = new Microsoft.Graphics.Canvas.Effects.BlendEffect - { - Foreground = new Microsoft.Graphics.Canvas.Effects.ColorSourceEffect - { - Name = "Color", - Color = blendColor - }, - Background = blurEffect, - Mode = BlendEffectMode.Multiply - }; - - // Composite Effect - var effect = new Microsoft.Graphics.Canvas.Effects.CompositeEffect - { - Mode = CanvasComposite.DestinationIn, - Sources = - { - blendEffect, - new CompositionEffectSourceParameter("mask") - } - }; - - // Create Effect Factory - var factory = compositor.CreateEffectFactory(effect, new[] { "Blur.BlurAmount", "Color.Color" }); - - // Create Effect Brush - var brush = factory.CreateBrush(); - - // Set the BackDropBrush - // If no backdrop brush is provided, create one - brush.SetSourceParameter("backdrop", backdropBrush ?? compositor.CreateBackdropBrush()); - - // Set the Mask - // Create SurfaceBrush from IGeometryMaskSurface - var maskBrush = compositor.CreateSurfaceBrush(mask.Surface); - brush.SetSourceParameter("mask", maskBrush); - - return brush; - } - - /// - /// Creates a custom shaped Frosted Glass Effect Brush using BackdropBrush and a Mask - /// - /// Compositor - /// IGeometryMaskSurface - /// Color to blend in the BackdropBrush - /// Blur Amount of the Backdrop Brush - /// Backdrop Brush (optional). If not provided, then compositor creates it. - /// MultiplyAmount of the ArithmeticCompositeEffect - /// Source1Amount of the ArithmeticCompositeEffect - /// Source2Amount of the ArithmeticCompositeEffect - /// CompositionEffectBrush - public static CompositionEffectBrush CreateFrostedGlassBrush( - this Compositor compositor, - IGeometryMaskSurface mask, - Color blendColor, - float blurAmount, - CompositionBackdropBrush backdropBrush = null, - float multiplyAmount = 0, - float colorAmount = 0.5f, - float backdropAmount = 0.5f) - { - // Create a frosty glass effect - var frostEffect = new Microsoft.Graphics.Canvas.Effects.GaussianBlurEffect - { - Name = "Blur", - BlurAmount = blurAmount, - BorderMode = EffectBorderMode.Hard, - Source = new Microsoft.Graphics.Canvas.Effects.ArithmeticCompositeEffect - { - Name = "Source", - MultiplyAmount = multiplyAmount, - Source1Amount = backdropAmount, - Source2Amount = colorAmount, - Source1 = new CompositionEffectSourceParameter("backdrop"), - Source2 = new Microsoft.Graphics.Canvas.Effects.ColorSourceEffect - { - Name = "BlendColor", - Color = blendColor - } - } - }; - - // Composite Effect - var effect = new Microsoft.Graphics.Canvas.Effects.CompositeEffect - { - Mode = CanvasComposite.DestinationIn, - Sources = - { - frostEffect, - new CompositionEffectSourceParameter("mask") - } - }; - - // Create Effect Factory - var factory = compositor.CreateEffectFactory(effect, new[] { "Blur.BlurAmount", "BlendColor.Color" }); - - // Create Effect Brush - var brush = factory.CreateBrush(); - - // Set the BackDropBrush - // If no backdrop brush is provided, create one - brush.SetSourceParameter("backdrop", backdropBrush ?? compositor.CreateBackdropBrush()); - - // Set the Mask - // Create SurfaceBrush from CompositionMask - var maskBrush = compositor.CreateSurfaceBrush(mask.Surface); - brush.SetSourceParameter("mask", maskBrush); - - return brush; - } - - /// - /// Updates the CompositionSurfaceBrush's Stretch and Alignment options - /// - /// CompositionSurfaceBrush - /// Stretch mode - /// Horizontal Alignment - /// Vertical Alignment - /// The animation to use to update the horizontal alignment of the surface brush - /// The animation to use to update the vertical alignment of the surface brush - public static void UpdateSurfaceBrushOptions( - this CompositionSurfaceBrush surfaceBrush, - Stretch stretch, - AlignmentX alignX, - AlignmentY alignY, - ScalarKeyFrameAnimation alignXAnimation = null, - ScalarKeyFrameAnimation alignYAnimation = null) - { - // Stretch Mode - switch (stretch) - { - case Stretch.None: - surfaceBrush.Stretch = CompositionStretch.None; - break; - case Stretch.Fill: - surfaceBrush.Stretch = CompositionStretch.Fill; - break; - case Stretch.Uniform: - surfaceBrush.Stretch = CompositionStretch.Uniform; - break; - case Stretch.UniformToFill: - surfaceBrush.Stretch = CompositionStretch.UniformToFill; - break; - } - - // Horizontal Alignment - var finalAlignX = surfaceBrush.HorizontalAlignmentRatio; - switch (alignX) - { - case AlignmentX.Left: - finalAlignX = 0; - break; - case AlignmentX.Center: - finalAlignX = 0.5f; - break; - case AlignmentX.Right: - finalAlignX = 1; - break; - } - - // If animation is available, animate to the new value - // otherwise set it explicitly - if (alignXAnimation == null) - { - surfaceBrush.HorizontalAlignmentRatio = finalAlignX; - } - else - { - alignXAnimation.InsertKeyFrame(1f, finalAlignX); - surfaceBrush.StartAnimation("HorizontalAlignmentRatio", alignXAnimation); - } - - // Vertical Alignment - var finalAlignY = surfaceBrush.VerticalAlignmentRatio; - switch (alignY) - { - case AlignmentY.Top: - finalAlignY = 0; - break; - case AlignmentY.Center: - finalAlignY = 0.5f; - break; - case AlignmentY.Bottom: - finalAlignY = 1; - break; - } - - // If animation is available, animate to the new value - // otherwise set it explicitly - if (alignYAnimation == null) - { - surfaceBrush.VerticalAlignmentRatio = finalAlignY; - } - else - { - alignYAnimation.InsertKeyFrame(1f, finalAlignY); - surfaceBrush.StartAnimation("VerticalAlignmentRatio", alignYAnimation); - } - } - - /// - /// Gets the first descendant (of Type T) of this dependency object in the visual tree. - /// - /// Type deriving from DependencyObject - /// DependencyObject whose first descendant is to be obtained. - /// First descendant (of Type T), if any - public static T GetFirstDescendantOfType(this DependencyObject dependencyObject) - where T : DependencyObject - { - return dependencyObject.GetDescendantsOfType().FirstOrDefault(); - } - - /// - /// Gets the descendants (of Type T) of this dependency object in the visual tree. - /// - /// Type deriving from DependencyObject - /// DependencyObject whose descendants are to be obtained. - /// Enumerable collection of descendants (of Type T) - public static IEnumerable GetDescendantsOfType(this DependencyObject dependencyObject) - where T : DependencyObject - { - return dependencyObject.GetDescendants().OfType(); - } - - /// - /// Gets the descendants of this dependency object in the visual tree. - /// - /// DependencyObject whose descendants are to be obtained. - /// Enumerable collection of descendants - public static IEnumerable GetDescendants(this DependencyObject dependencyObject) - { - var queue = new Queue(); - - // Add to queue to obtain its descendants - queue.Enqueue(dependencyObject); - - while (queue.Count > 0) - { - var parent = queue.Dequeue(); - if (parent == null) - { - continue; - } - - var childrenCount = VisualTreeHelper.GetChildrenCount(parent); - for (var i = 0; i < childrenCount; i++) - { - var child = VisualTreeHelper.GetChild(parent, i); - - // Yield for enumeration - yield return child; - - // Add child to queue to obtain its descendants - queue.Enqueue(child); - } - } - } - - /// - /// Gets the first ancestor (of Type T) of this dependency object in the visual tree. - /// - /// Type deriving from DependencyObject - /// DependencyObject whose first ancestor is to be obtained. - /// First ancestor (of Type T), if any - public static T GetFirstAncestorOfType(this DependencyObject dependencyObject) - where T : DependencyObject - { - return dependencyObject.GetAncestorsOfType().FirstOrDefault(); - } - - /// - /// Gets the ancestors (of Type T) of this dependency object in the visual tree. - /// - /// Type deriving from DependencyObject - /// DependencyObject whose ancestors are to be obtained. - /// Enumerable collection of ancestors (of Type T) - public static IEnumerable GetAncestorsOfType(this DependencyObject dependencyObject) - where T : DependencyObject - { - return dependencyObject.GetAncestors().OfType(); - } - - /// - /// Gets the ancestors of this dependency object in the visual tree. - /// - /// DependencyObject whose ancestors are to be obtained. - /// Enumerable collection of ancestors - public static IEnumerable GetAncestors(this DependencyObject dependencyObject) - { - var parent = VisualTreeHelper.GetParent(dependencyObject); - - while (parent != null) - { - yield return parent; - parent = VisualTreeHelper.GetParent(parent); - } - } - - /// - /// Checks if this dependency object is present in the Visual Tree - /// of the current window. - /// - /// DependencyObject - /// True if present, otherwise False - public static bool IsInVisualTree(this DependencyObject dependencyObject) - { - return Window.Current.Content != null && - dependencyObject.GetAncestors().Contains(Window.Current.Content); - } - } -} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs index f283f3c77c8..0ba53c64c3b 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs @@ -41,14 +41,10 @@ public sealed class CompositionGenerator : ICompositionGeneratorInternal /// public static ICompositionGenerator Instance => _instance.Value; - /// - /// Gets the Compositor. - /// + /// public Compositor Compositor { get; private set; } - /// - /// Gets the CanvasDevice. - /// + /// public CanvasDevice Device { get; private set; } /// @@ -80,7 +76,11 @@ private CompositionGenerator() /// CompositionDrawingSurface on which the CanvasBitmap has to be rendered. /// CanvasBitmap created by loading the image from the Uri /// Describes the image's resize and alignment options in the allocated space. - private static void RenderBitmap(object surfaceLock, CompositionDrawingSurface surface, CanvasBitmap canvasBitmap, ImageSurfaceOptions options) + private static void RenderBitmap( + object surfaceLock, + CompositionDrawingSurface surface, + CanvasBitmap canvasBitmap, + ImageSurfaceOptions options) { var surfaceSize = surface.Size; @@ -192,7 +192,13 @@ private static void RenderBitmap(object surfaceLock, CompositionDrawingSurface s /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where /// the mask, created from the loaded image's alpha values, should be rendered. /// Describes the image's resize and alignment options in the allocated space. - private static void RenderBitmapMask(CanvasDevice device, object surfaceLock, CompositionDrawingSurface surface, CanvasBitmap canvasBitmap, Thickness padding, ImageSurfaceOptions options) + private static void RenderBitmapMask( + CanvasDevice device, + object surfaceLock, + CompositionDrawingSurface surface, + CanvasBitmap canvasBitmap, + Thickness padding, + ImageSurfaceOptions options) { var surfaceSize = surface.Size; @@ -367,40 +373,19 @@ private void RaiseDeviceReplacedEvent() deviceEvent?.Invoke(this, new EventArgs()); } - /// - /// Creates an Empty IGeometryMaskSurface having the no size and geometry. - /// NOTE: Use this API if you want to create an Empty IGeometryMaskSurface first - /// and change its geometry and/or size of the IGeometryMaskSurface later. - /// - /// IGeometryMaskSurface + /// public IGeometryMaskSurface CreateGeometryMaskSurface() { return CreateGeometryMaskSurface(default, null, Vector2.Zero); } - /// - /// Creates an IGeometryMaskSurface having the given size and geometry with MaskMode as True. - /// The geometry is filled with white color. The surface not covered by the geometry is - /// transparent. - /// - /// Size of the mask - /// Geometry of the mask - /// IGeometryMaskSurface + /// public IGeometryMaskSurface CreateGeometryMaskSurface(Size size, CanvasGeometry geometry) { return CreateGeometryMaskSurface(size, geometry, Vector2.Zero); } - /// - /// Creates an IGeometryMaskSurface having the given size and geometry with MaskMode as True. - /// The geometry is filled with white color. The surface not covered by the geometry is - /// transparent. - /// - /// Size of the mask - /// Geometry of the mask - /// The offset from the top left corner of the ICompositionSurface where - /// the Geometry is rendered. - /// IGeometryMaskSurface + /// public IGeometryMaskSurface CreateGeometryMaskSurface(Size size, CanvasGeometry geometry, Vector2 offset) { // Initialize the mask @@ -412,27 +397,13 @@ public IGeometryMaskSurface CreateGeometryMaskSurface(Size size, CanvasGeometry return mask; } - /// - /// Creates an Empty IGaussianMaskSurface having the no size and geometry. - /// NOTE: Use this API if you want to create an Empty IGaussianMaskSurface first - /// and change its geometry, size, offset and/or blurRadius of the IGaussianMaskSurface later. - /// - /// IGaussianMaskSurface + /// public IGaussianMaskSurface CreateGaussianMaskSurface() { return CreateGaussianMaskSurface(default, null, Vector2.Zero, 0); } - /// - /// Creates a IGaussianMaskSurface having the given size and geometry. The geometry is filled - /// with white color and a Gaussian blur is applied to it. The surface not covered by the geometry is transparent. - /// - /// Size of the mask - /// Geometry of the mask - /// The offset from the top left corner of the ICompositionSurface where - /// the Geometry is rendered. - /// Radius of Gaussian Blur to be applied on the IGaussianMaskSurface - /// IGaussianMaskSurface + /// public IGaussianMaskSurface CreateGaussianMaskSurface(Size size, CanvasGeometry geometry, Vector2 offset, float blurRadius) { // Initialize the mask @@ -444,12 +415,7 @@ public IGaussianMaskSurface CreateGaussianMaskSurface(Size size, CanvasGeometry return gaussianMaskSurface; } - /// - /// Creates an empty GeometrySurface having the no size and geometry. - /// NOTE: Use this API if you want to create an Empty IGeometrySurface - /// first and change its geometry and/or size, fillColor or stroke later. - /// - /// IGeometrySurface + /// public IGeometrySurface CreateGeometrySurface() { // Initialize the geometrySurface @@ -461,13 +427,7 @@ public IGeometrySurface CreateGeometrySurface() return geometrySurface; } - /// - /// Creates a GeometrySurface having the given size, geometry, stroke - /// - /// Size of the GeometrySurface - /// Geometry to be rendered on the GeometrySurface - /// ICanvasStroke defining the outline for the geometry - /// IGeometrySurface + /// public IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasStroke stroke) { // Initialize the geometrySurface @@ -479,14 +439,7 @@ public IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry return geometrySurface; } - /// - /// Creates a GeometrySurface having the given size, geometry, foreground color with - /// MaskMode as False. - /// - /// Size of the mask - /// Geometry of the mask - /// Fill color of the geometry. - /// IGeometrySurface + /// public IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, Color fillColor) { // Initialize the geometrySurface @@ -498,14 +451,7 @@ public IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry return geometrySurface; } - /// - /// Creates a GeometrySurface having the given size, geometry, stroke and fill color - /// - /// Size of the GeometrySurface - /// Geometry to be rendered on the GeometrySurface - /// ICanvasStroke defining the outline for the geometry - /// Fill color of the geometry. - /// IGeometrySurface + /// public IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasStroke stroke, Color fillColor) { // Initialize the geometrySurface @@ -517,16 +463,7 @@ public IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry return geometrySurface; } - /// - /// Creates a GeometrySurface having the given size, geometry, foreground color and - /// background color. - /// - /// Size of the mask - /// Geometry of the mask - /// Fill color of the geometry - /// Fill color of the Mask surface background which is - /// not covered by the geometry - /// IGeometrySurface + /// public IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, Color fillColor, Color backgroundColor) { // Initialize the geometrySurface @@ -538,17 +475,7 @@ public IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry return geometrySurface; } - /// - /// Creates a GeometrySurface having the given size, geometry, stroke, fill color and - /// background color. - /// - /// Size of the GeometrySurface - /// Geometry to be rendered on the GeometrySurface - /// ICanvasStroke defining the outline for the geometry - /// Fill color of the geometry - /// Fill color of the GeometrySurface background which is - /// not covered by the geometry - /// IGeometrySurface + /// public IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasStroke stroke, Color fillColor, Color backgroundColor) { // Initialize the geometrySurface @@ -560,14 +487,7 @@ public IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry return geometrySurface; } - /// - /// Creates a GeometrySurface having the given size, geometry and foreground brush with - /// MaskMode as False. - /// - /// Size of the mask - /// Geometry of the mask - /// The brush with which the geometry has to be filled - /// IGeometrySurface + /// public IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasBrush fillBrush) { // Create the background brush @@ -582,14 +502,7 @@ public IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry return geometrySurface; } - /// - /// Creates a GeometrySurface having the given size, geometry, stroke and fill brush. - /// - /// Size of the GeometrySurface - /// Geometry to be rendered on the GeometrySurface - /// ICanvasStroke defining the outline for the geometry - /// The brush with which the geometry has to be filled - /// IGeometrySurface + /// public IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasStroke stroke, ICanvasBrush fillBrush) { // Create the background brush @@ -604,16 +517,7 @@ public IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry return geometrySurface; } - /// - /// Creates a GeometrySurface having the given size, geometry, foreground brush and - /// background brush with MaskMode as False. - /// - /// Size of the mask - /// Geometry of the mask - /// The brush with which the geometry has to be filled - /// The brush to fill the Mask background surface which is - /// not covered by the geometry - /// IGeometrySurface + /// public IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasBrush fillBrush, ICanvasBrush backgroundBrush) { // Initialize the geometrySurface @@ -625,17 +529,7 @@ public IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry return geometrySurface; } - /// - /// Creates a GeometrySurface having the given size, geometry, stroke, fill brush and - /// background brush. - /// - /// Size of the GeometrySurface - /// Geometry to be rendered on the GeometrySurface - /// ICanvasStroke defining the outline for the geometry - /// The brush with which the geometry has to be filled - /// The brush to fill the GeometrySurface background which is - /// not covered by the geometry - /// IGeometrySurface + /// public IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasStroke stroke, ICanvasBrush fillBrush, ICanvasBrush backgroundBrush) { // Initialize the geometrySurface @@ -647,16 +541,7 @@ public IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry return geometrySurface; } - /// - /// Creates a GeometrySurface having the given size, geometry, foreground brush and - /// background color with MaskMode as False. - /// - /// Size of the mask - /// Geometry of the mask - /// The brush with which the geometry has to be filled - /// Fill color of the Mask background surface which is - /// not covered by the geometry - /// IGeometrySurface + /// public IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasBrush fillBrush, Color backgroundColor) { // Create the background brush @@ -671,17 +556,7 @@ public IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry return geometrySurface; } - /// - /// Creates a GeometrySurface having the given size, geometry, stroke, fill brush and - /// background color. - /// - /// Size of the GeometrySurface - /// Geometry to be rendered on the GeometrySurface - /// ICanvasStroke defining the outline for the geometry - /// The brush with which the geometry has to be filled - /// Fill color of the GeometrySurface background which is - /// not covered by the geometry - /// IGeometrySurface + /// public IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasStroke stroke, ICanvasBrush fillBrush, Color backgroundColor) { // Create the background brush @@ -696,16 +571,7 @@ public IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry return geometrySurface; } - /// - /// Creates a GeometrySurface having the given size, geometry, foreground color and - /// background brush. - /// - /// Size of the mask - /// Geometry of the mask - /// Fill color of the geometry - /// The brush to fill the Mask background surface which is - /// not covered by the geometry - /// IGeometrySurface + /// public IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, Color fillColor, ICanvasBrush backgroundBrush) { // Create the foreground brush @@ -720,17 +586,7 @@ public IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry return geometrySurface; } - /// - /// Creates a GeometrySurface having the given size, geometry, stroke, fill color and - /// background brush. - /// - /// Size of the GeometrySurface - /// Geometry to be rendered on the GeometrySurface - /// ICanvasStroke defining the outline for the geometry - /// Fill color of the geometry - /// The brush to fill the GeometrySurface background which is - /// not covered by the geometry - /// IGeometrySurface + /// public IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasStroke stroke, Color fillColor, ICanvasBrush backgroundBrush) { // Create the foreground brush @@ -745,14 +601,7 @@ public IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry return geometrySurface; } - /// - /// Creates an IImageSurface having the given size onto which an image (based on the Uri - /// and the options) is loaded. - /// - /// Uri of the image to be loaded onto the IImageSurface. - /// New size of the IImageSurface - /// Describes the image's resize and alignment options in the allocated space. - /// ICompositionSurfaceImage + /// public async Task CreateImageSurfaceAsync(Uri uri, Size size, ImageSurfaceOptions options) { // Initialize the IImageSurface @@ -764,13 +613,7 @@ public async Task CreateImageSurfaceAsync(Uri uri, Size size, Ima return imageSurface; } - /// - /// Creates an IImageSurface having the given size onto which the given image is loaded. - /// - /// Image that will be loaded onto the IImageSurface. - /// Size of the IImageSurface - /// The image's resize and alignment options in the allocated space. - /// IImageSurface + /// public IImageSurface CreateImageSurface(CanvasBitmap bitmap, Size size, ImageSurfaceOptions options) { // Create a new IImageSurface using the given imageSurface @@ -782,11 +625,7 @@ public IImageSurface CreateImageSurface(CanvasBitmap bitmap, Size size, ImageSur return imageSurface; } - /// - /// Creates a copy of the given IImageSurface - /// - /// IImageSurface to copy - /// Copy of the given IImageSurface + /// public IImageSurface CreateImageSurface(IImageSurface imageSurface) { if (imageSurface != null) @@ -804,11 +643,7 @@ public IImageSurface CreateImageSurface(IImageSurface imageSurface) return CreateImageSurface(null, new Size(0, 0), ImageSurfaceOptions.Default); } - /// - /// Creates a copy of the given IImageMaskSurface - /// - /// IImageMaskSurface to copy - /// IImageMaskSurface + /// public IImageMaskSurface CreateImageMaskSurface(IImageMaskSurface imageMaskSurface) { if (imageMaskSurface != null) @@ -831,31 +666,13 @@ public IImageMaskSurface CreateImageMaskSurface(IImageMaskSurface imageMaskSurfa return CreateImageMaskSurface(surfaceBitmap: null, new Size(0, 0), new Thickness(0), ImageSurfaceOptions.DefaultImageMaskOptions); } - /// - /// Creates an IImageMaskSurface using the alpha values of the given image at the specified offset using - /// the given blur radius. - /// - /// The CanvasBitmap whose alpha values will be used to create the Mask. - /// Size of the IImageMaskSurface - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where - /// the mask, created from the given image's alpha values, should be rendered. - /// Radius of the Gaussian blur applied to the the mask. - /// IImageMaskSurface + /// public IImageMaskSurface CreateImageMaskSurface(CanvasBitmap surfaceBitmap, Size size, Thickness padding, float blurRadius) { return CreateImageMaskSurface(surfaceBitmap, size, padding, ImageSurfaceOptions.GetDefaultImageMaskOptionsForBlur(blurRadius)); } - /// - /// Creates an IImageMaskSurface using the alpha values of the given image at the specified offset using - /// the given options. - /// - /// The CanvasBitmap whose alpha values will be used to create the Mask. - /// Size of the IImageMaskSurface - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where - /// the mask, created from the given image's alpha values, should be rendered. - /// The image's resize, alignment and blur radius options in the allocated space. - /// IImageMaskSurface + /// public IImageMaskSurface CreateImageMaskSurface(CanvasBitmap surfaceBitmap, Size size, Thickness padding, ImageSurfaceOptions options) { var imageMaskSurface = new ImageMaskSurface(this, surfaceBitmap, size, padding, options); @@ -866,16 +683,7 @@ public IImageMaskSurface CreateImageMaskSurface(CanvasBitmap surfaceBitmap, Size return imageMaskSurface; } - /// - /// Creates an IImageMaskSurface using the alpha values of the given IImageSurface's image at the specified offset using - /// the given options. - /// - /// The IImageSurface whose image's alpha values will be used to create the Mask. - /// Size of the IImageMaskSurface - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where - /// the mask, created from the given image's alpha values, should be rendered. - /// The image's resize, alignment and blur radius options in the allocated space. - /// IImageMaskSurface + /// public IImageMaskSurface CreateImageMaskSurface(IImageSurface imageSurface, Size size, Thickness padding, ImageSurfaceOptions options) { if (imageSurface != null) @@ -888,16 +696,7 @@ public IImageMaskSurface CreateImageMaskSurface(IImageSurface imageSurface, Size return CreateImageMaskSurface(surfaceBitmap: null, size, padding, options); } - /// - /// Creates an IImageMaskSurface using the alpha values of the image loaded from the Uri - /// and rendered at the specified offset using the given options. - /// - /// The URI of the image whose alpha values will be used to create the Mask. - /// Size of the IImageMaskSurface - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where - /// the mask, created from the given image's alpha values, should be rendered. - /// The image's resize, alignment and blur radius options in the allocated space. - /// IImageMaskSurface + /// public async Task CreateImageMaskSurfaceAsync(Uri uri, Size size, Thickness padding, ImageSurfaceOptions options) { var imageMaskSurface = new ImageMaskSurface(this, uri, size, padding, options); @@ -908,14 +707,7 @@ public async Task CreateImageMaskSurfaceAsync(Uri uri, Size s return imageMaskSurface; } - /// - /// Creates a reflection of the given Visual - /// - /// Visual whose reflection has to be created - /// Distance of the reflection from the visual - /// Normalized Length of the reflected visual that will be visible. - /// - Location of the reflection with respect - /// to the Visual - Bottom, Top, Left or Right + /// public void CreateReflection(ContainerVisual visual, float reflectionDistance = 0f, float reflectionLength = 0.7f, ReflectionLocation location = ReflectionLocation.Bottom) { // Create the visual layer that will contained the visual's reflection @@ -993,13 +785,7 @@ public void CreateReflection(ContainerVisual visual, float reflectionDistance = visual.Children.InsertAtTop(reflectionLayer); } - /// - /// Creates a CompositionDrawingSurface of given size - /// - /// The object to lock to prevent multiple threads - /// from accessing the surface at the same time. - /// Size of the CompositionDrawingSurface - /// CompositionDrawingSurface + /// public CompositionDrawingSurface CreateDrawingSurface(object surfaceLock, Size size) { var surfaceSize = size; @@ -1018,13 +804,7 @@ public CompositionDrawingSurface CreateDrawingSurface(object surfaceLock, Size s } } - /// - /// Resizes the Mask Surface to the given size - /// - /// The object to lock to prevent multiple threads - /// from accessing the surface at the same time. - /// CompositionDrawingSurface - /// New size of the Mask Surface + /// public void ResizeDrawingSurface(object surfaceLock, CompositionDrawingSurface surface, Size size) { // Cannot resize to Size.Empty. Will throw exception! @@ -1045,16 +825,7 @@ public void ResizeDrawingSurface(object surfaceLock, CompositionDrawingSurface s } } - /// - /// Redraws the IGeometryMaskSurface with the given size and geometry - /// - /// The object to lock to prevent multiple threads - /// from accessing the surface at the same time. - /// CompositionDrawingSurface - /// Size of the IGeometryMaskSurface - /// Geometry of the IGeometryMaskSurface - /// The offset from the top left corner of the ICompositionSurface where - /// the Geometry is rendered. + /// public void RedrawGeometryMaskSurface(object surfaceLock, CompositionDrawingSurface surface, Size size, CanvasGeometry geometry, Vector2 offset) { // If the surface is not created, create it @@ -1093,17 +864,7 @@ public void RedrawGeometryMaskSurface(object surfaceLock, CompositionDrawingSurf } } - /// - /// Redraws the GaussianMaskSurface with the given size and geometry - /// - /// The object to lock to prevent multiple threads - /// from accessing the surface at the same time. - /// CompositionDrawingSurface - /// Size of the GaussianMaskSurface - /// Geometry of the GaussianMaskSurface - /// The offset from the top left corner of the ICompositionSurface where - /// the Geometry is rendered. - /// Radius of Gaussian Blur to be applied. + /// public void RedrawGaussianMaskSurface(object surfaceLock, CompositionDrawingSurface surface, Size size, CanvasGeometry geometry, Vector2 offset, float blurRadius) { // If the surface is not created, create it @@ -1161,17 +922,7 @@ public void RedrawGaussianMaskSurface(object surfaceLock, CompositionDrawingSurf } } - /// - /// Redraws the GeometrySurface with the given size, geometry, foreground brush and background brush - /// - /// The object to lock to prevent multiple threads - /// from accessing the surface at the same time. - /// CompositionDrawingSurface - /// Size of the GeometrySurface - /// Geometry of the GeometrySurface - /// ICanvasStroke defining the outline for the geometry - /// The brush with which the geometry has to be filled - /// The brush with which the GeometrySurface background has to be filled + /// public void RedrawGeometrySurface(object surfaceLock, CompositionDrawingSurface surface, Size size, CanvasGeometry geometry, ICanvasStroke stroke, ICanvasBrush fillBrush, ICanvasBrush backgroundBrush) { // If the surface is not created, create it @@ -1236,32 +987,14 @@ public void RedrawGeometrySurface(object surfaceLock, CompositionDrawingSurface } } - /// - /// Resizes the ImageSurface to the given size and redraws the ImageSurface - /// by rendering the canvasBitmap onto the surface. - /// - /// The object to lock to prevent multiple threads - /// from accessing the surface at the same time. - /// CompositionDrawingSurface - /// Describes the image's resize and alignment options in the allocated space. - /// The CanvasBitmap on which the image is loaded. + /// public void RedrawImageSurface(object surfaceLock, CompositionDrawingSurface surface, ImageSurfaceOptions options, CanvasBitmap canvasBitmap) { // Render the image to the surface RenderBitmap(surfaceLock, surface, canvasBitmap, options); } - /// - /// Resizes the ImageSurface with the given size and redraws the ImageSurface by loading - /// image from the new Uri. - /// - /// The object to lock to prevent multiple threads - /// from accessing the surface at the same time. - /// CompositionDrawingSurface - /// Uri of the image to be loaded onto the IImageSurface. - /// Describes the image's resize and alignment options in the allocated space. - /// The CanvasBitmap on which the image is loaded. - /// CanvasBitmap + /// public async Task RedrawImageSurfaceAsync(object surfaceLock, CompositionDrawingSurface surface, Uri uri, ImageSurfaceOptions options, CanvasBitmap canvasBitmap) { if ((canvasBitmap == null) && (uri != null)) @@ -1284,35 +1017,14 @@ public async Task RedrawImageSurfaceAsync(object surfaceLock, Comp return canvasBitmap; } - /// - /// Resizes the ImageMaskSurface to the given size and redraws the ImageMaskSurface - /// by rendering the mask using the image's alpha values onto the surface. - /// - /// The object to lock to prevent multiple threads from accessing the surface at the same time. - /// CompositionDrawingSurface - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where - /// the mask, created from the loaded image's alpha values, should be rendered. - /// Describes the image's resize and alignment options and blur radius in the allocated space. - /// The image whose alpha values is used to create the IImageMaskSurface. + /// public void RedrawImageMaskSurface(object surfaceLock, CompositionDrawingSurface surface, Thickness padding, ImageSurfaceOptions options, CanvasBitmap surfaceBitmap) { // Render the image mask to the surface RenderBitmapMask(Device, surfaceLock, surface, surfaceBitmap, padding, options); } - /// - /// Resizes the ImageMaskSurface to the given size and redraws the ImageMaskSurface by loading the image from the new Uri and - /// rendering the mask using the image's alpha values onto the surface. - /// - /// The object to lock to prevent multiple threads - /// from accessing the surface at the same time. - /// CompositionDrawingSurface - /// Uri of the image to be loaded onto the IImageMaskSurface. - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where - /// the mask, created from the given image's alpha values, should be rendered. - /// Describes the image's resize and alignment options and blur radius in the allocated space. - /// The CanvasBitmap on which the image is loaded. - /// The CanvasBitmap whose alpha values is used to create the IImageMaskSurface. + /// public async Task RedrawImageMaskSurfaceAsync(object surfaceLock, CompositionDrawingSurface surface, Uri uri, Thickness padding, ImageSurfaceOptions options, CanvasBitmap surfaceBitmap) { if ((surfaceBitmap == null) && (uri != null)) @@ -1333,10 +1045,7 @@ public async Task RedrawImageMaskSurfaceAsync(object surfaceLock, return surfaceBitmap; } - /// - /// Disposes the resources used by the CompositionGenerator. - /// NOTE: This should be called only when the application ends because CompositionGenerator is a singleton and its instance might be used across the application. - /// + /// public void Dispose() { lock (_disposingLock) diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositorExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositorExtensions.cs index 360c9a4e38d..633ac1f1b4b 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositorExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositorExtensions.cs @@ -3,17 +3,264 @@ // See the LICENSE file in the project root for more information. using System; -using System.Numerics; +using Microsoft.Graphics.Canvas; +using Microsoft.Graphics.Canvas.Effects; +using Microsoft.Toolkit.Uwp.UI.Media.Pipelines; +using Windows.UI; using Windows.UI.Composition; +using Windows.UI.Xaml.Media; namespace Microsoft.Toolkit.Uwp.UI.Media { /// /// Extension methods for Windows.UI.Composition.Compositor - /// The easing function values have been obtained from http://easings.net/ /// public static class CompositorExtensions { + /// + /// Creates the CompositionSurfaceBrush from the specified render surface. + /// + /// Compositor + /// An object deriving from IGeometryMaskSurface, IGaussianMaskSurface, IGeometrySurface or IImageSurface + /// CompositionSurfaceBrush + public static CompositionSurfaceBrush CreateSurfaceBrush(this Compositor compositor, IRenderSurface renderSurface) + { + return compositor.CreateSurfaceBrush(renderSurface.Surface); + } + + /// + /// Creates a custom shaped Effect Brush using BackdropBrush and an IGeometryMaskSurface. + /// + /// Compositor + /// IGeometryMaskSurface + /// Color to blend in the BackdropBrush + /// Blur Amount of the Backdrop Brush + /// Backdrop Brush (optional). If not provided, then compositor creates it. + /// CompositionEffectBrush + public static CompositionEffectBrush CreateMaskedBackdropBrush(this Compositor compositor, IGeometryMaskSurface mask, Color blendColor, float blurAmount, CompositionBackdropBrush backdropBrush = null) + { + return CreateBackdropBrush(compositor, mask, blendColor, blurAmount, backdropBrush); + } + + /// + /// Creates a custom shaped Effect Brush using BackdropBrush and an IGaussianMaskSurface. + /// + /// Compositor + /// IGeometryMaskSurface + /// Color to blend in the BackdropBrush + /// Blur Amount of the Backdrop Brush + /// Backdrop Brush (optional). If not provided, then compositor creates it. + /// CompositionEffectBrush + public static CompositionEffectBrush CreateGaussianMaskedBackdropBrush(this Compositor compositor, IGaussianMaskSurface mask, Color blendColor, float blurRadius, CompositionBackdropBrush backdropBrush = null) + { + return CreateBackdropBrush(compositor, mask, blendColor, blurRadius, backdropBrush); + } + + /// + /// Creates a custom shaped Effect Brush using BackdropBrush and an IGeometryMaskSurface or an IGaussianMaskSurface. + /// + /// Compositor + /// IGeometryMaskSurface or IGaussianMaskSurface + /// Color to blend in the BackdropBrush + /// Blur Amount of the Backdrop Brush + /// Backdrop Brush (optional). If not provided, then compositor creates it. + /// CompositionEffectBrush + internal static CompositionEffectBrush CreateBackdropBrush(Compositor compositor, IRenderSurface mask, Color blendColor, float blurAmount, CompositionBackdropBrush backdropBrush = null) + { + // Blur Effect + var blurEffect = new GaussianBlurEffect() + { + Name = "Blur", + BlurAmount = blurAmount, + BorderMode = EffectBorderMode.Hard, + Optimization = EffectOptimization.Balanced, + Source = new CompositionEffectSourceParameter("backdrop"), + }; + + // Blend Effect + var blendEffect = new Graphics.Canvas.Effects.BlendEffect + { + Foreground = new ColorSourceEffect + { + Name = "Color", + Color = blendColor + }, + Background = blurEffect, + Mode = BlendEffectMode.Multiply + }; + + // Composite Effect + var effect = new CompositeEffect + { + Mode = CanvasComposite.DestinationIn, + Sources = + { + blendEffect, + new CompositionEffectSourceParameter("mask") + } + }; + + // Create Effect Factory + var factory = compositor.CreateEffectFactory(effect, new[] { "Blur.BlurAmount", "Color.Color" }); + + // Create Effect Brush + var brush = factory.CreateBrush(); + + // Set the BackDropBrush + // If no backdrop brush is provided, create one + brush.SetSourceParameter("backdrop", backdropBrush ?? compositor.CreateBackdropBrush()); + + // Set the Mask + // Create SurfaceBrush from IGeometryMaskSurface + var maskBrush = compositor.CreateSurfaceBrush(mask.Surface); + brush.SetSourceParameter("mask", maskBrush); + + return brush; + } + + /// + /// Creates a custom shaped Frosted Glass Effect Brush using BackdropBrush and a Mask + /// + /// Compositor + /// IGeometryMaskSurface + /// Color to blend in the BackdropBrush + /// Blur Amount of the Backdrop Brush + /// Backdrop Brush (optional). If not provided, then compositor creates it. + /// MultiplyAmount of the ArithmeticCompositeEffect + /// Source1Amount of the ArithmeticCompositeEffect + /// Source2Amount of the ArithmeticCompositeEffect + /// CompositionEffectBrush + public static CompositionEffectBrush CreateFrostedGlassBrush( + this Compositor compositor, + IGeometryMaskSurface mask, + Color blendColor, + float blurAmount, + CompositionBackdropBrush backdropBrush = null, + float multiplyAmount = 0, + float colorAmount = 0.5f, + float backdropAmount = 0.5f) + { + // Create a frosty glass effect + var frostEffect = new GaussianBlurEffect + { + Name = "Blur", + BlurAmount = blurAmount, + BorderMode = EffectBorderMode.Hard, + Source = new ArithmeticCompositeEffect + { + Name = "Source", + MultiplyAmount = multiplyAmount, + Source1Amount = backdropAmount, + Source2Amount = colorAmount, + Source1 = new CompositionEffectSourceParameter("backdrop"), + Source2 = new ColorSourceEffect + { + Name = "BlendColor", + Color = blendColor + } + } + }; + + // Composite Effect + var effect = new CompositeEffect + { + Mode = CanvasComposite.DestinationIn, + Sources = + { + frostEffect, + new CompositionEffectSourceParameter("mask") + } + }; + + // Create Effect Factory + var factory = compositor.CreateEffectFactory(effect, new[] { "Blur.BlurAmount", "BlendColor.Color" }); + + // Create Effect Brush + var brush = factory.CreateBrush(); + + // Set the BackDropBrush + // If no backdrop brush is provided, create one + brush.SetSourceParameter("backdrop", backdropBrush ?? compositor.CreateBackdropBrush()); + + // Set the Mask + // Create SurfaceBrush from CompositionMask + var maskBrush = compositor.CreateSurfaceBrush(mask.Surface); + brush.SetSourceParameter("mask", maskBrush); + + return brush; + } + + /// + /// Updates the CompositionSurfaceBrush's Stretch and Alignment options + /// + /// CompositionSurfaceBrush + /// Stretch mode + /// Horizontal Alignment + /// Vertical Alignment + /// The animation to use to update the horizontal alignment of the surface brush + /// The animation to use to update the vertical alignment of the surface brush + public static void UpdateSurfaceBrushOptions( + this CompositionSurfaceBrush surfaceBrush, + Stretch stretch, + AlignmentX alignX, + AlignmentY alignY, + ScalarKeyFrameAnimation alignXAnimation = null, + ScalarKeyFrameAnimation alignYAnimation = null) + { + // Stretch Mode + surfaceBrush.Stretch = stretch switch + { + Stretch.None => CompositionStretch.None, + Stretch.Fill => CompositionStretch.Fill, + Stretch.Uniform => CompositionStretch.Uniform, + Stretch.UniformToFill => CompositionStretch.UniformToFill, + _ => throw new ArgumentException("Invalid stretch value") + + }; + + // Horizontal Alignment + var finalAlignX = alignX switch + { + AlignmentX.Left => 0, + AlignmentX.Center => 0.5f, + AlignmentX.Right => 1f, + _ => surfaceBrush.HorizontalAlignmentRatio + }; + + // If animation is available, animate to the new value + // otherwise set it explicitly + if (alignXAnimation == null) + { + surfaceBrush.HorizontalAlignmentRatio = finalAlignX; + } + else + { + alignXAnimation.InsertKeyFrame(1f, finalAlignX); + surfaceBrush.StartAnimation("HorizontalAlignmentRatio", alignXAnimation); + } + + // Vertical Alignment + var finalAlignY = alignY switch + { + AlignmentY.Top => 0, + AlignmentY.Center => 0.5f, + AlignmentY.Bottom => 1f, + _ => surfaceBrush.VerticalAlignmentRatio + }; + + // If animation is available, animate to the new value + // otherwise set it explicitly + if (alignYAnimation == null) + { + surfaceBrush.VerticalAlignmentRatio = finalAlignY; + } + else + { + alignYAnimation.InsertKeyFrame(1f, finalAlignY); + surfaceBrush.StartAnimation("VerticalAlignmentRatio", alignYAnimation); + } + } + /// /// This extension method creates a scoped batch and handles the completed event /// the subscribing and unsubscribing process internally. @@ -137,256 +384,5 @@ void BatchCompletedHandler(object s, CompositionBatchCompletedEventArgs ea) // End Batch batch.End(); } - - /// - /// Back Easing Function - Ease In - /// - /// Compositor - /// CubicBezierEasingFunction - public static CubicBezierEasingFunction CreateEaseInBackEasingFunction(this Compositor compositor) - { - return compositor.CreateCubicBezierEasingFunction(new Vector2(0.600f, -0.280f), new Vector2(0.735f, 0.045f)); - } - - /// - /// Circle Easing Function - Ease In - /// - /// Compositor - /// CubicBezierEasingFunction - public static CubicBezierEasingFunction CreateEaseInCircleEasingFunction(this Compositor compositor) - { - return compositor.CreateCubicBezierEasingFunction(new Vector2(0.600f, 0.040f), new Vector2(0.980f, 0.335f)); - } - - /// - /// Cubic Easing Function - Ease In - /// - /// Compositor - /// CubicBezierEasingFunction - public static CubicBezierEasingFunction CreateEaseInCubicEasingFunction(this Compositor compositor) - { - return compositor.CreateCubicBezierEasingFunction(new Vector2(0.550f, 0.055f), new Vector2(0.675f, 0.190f)); - } - - /// - /// Exponential Easing Function - Ease In - /// - /// Compositor - /// CubicBezierEasingFunction - public static CubicBezierEasingFunction CreateEaseInExponentialEasingFunction(this Compositor compositor) - { - return compositor.CreateCubicBezierEasingFunction(new Vector2(0.950f, 0.050f), new Vector2(0.795f, 0.035f)); - } - - /// - /// Quadratic Easing Function - Ease In - /// - /// Compositor - /// CubicBezierEasingFunction - public static CubicBezierEasingFunction CreateEaseInQuadraticEasingFunction(this Compositor compositor) - { - return compositor.CreateCubicBezierEasingFunction(new Vector2(0.550f, 0.085f), new Vector2(0.680f, 0.530f)); - } - - /// - /// Quartic Easing Function - Ease In - /// - /// Compositor - /// CubicBezierEasingFunction - public static CubicBezierEasingFunction CreateEaseInQuarticEasingFunction(this Compositor compositor) - { - return compositor.CreateCubicBezierEasingFunction(new Vector2(0.895f, 0.030f), new Vector2(0.685f, 0.220f)); - } - - /// - /// Quintic Easing Function - Ease In - /// - /// Compositor - /// CubicBezierEasingFunction - public static CubicBezierEasingFunction CreateEaseInQuinticEasingFunction(this Compositor compositor) - { - return compositor.CreateCubicBezierEasingFunction(new Vector2(0.755f, 0.050f), new Vector2(0.855f, 0.060f)); - } - - /// - /// Sine Easing Function - Ease In - /// - /// Compositor - /// CubicBezierEasingFunction - public static CubicBezierEasingFunction CreateEaseInSineEasingFunction(this Compositor compositor) - { - return compositor.CreateCubicBezierEasingFunction(new Vector2(0.470f, 0.000f), new Vector2(0.745f, 0.715f)); - } - - /// - /// Back Easing Function - Ease Out - /// - /// Compositor - /// CubicBezierEasingFunction - public static CubicBezierEasingFunction CreateEaseOutBackEasingFunction(this Compositor compositor) - { - return compositor.CreateCubicBezierEasingFunction(new Vector2(0.175f, 0.885f), new Vector2(0.320f, 1.275f)); - } - - /// - /// Circle Easing Function - Ease Out - /// - /// Compositor - /// CubicBezierEasingFunction - public static CubicBezierEasingFunction CreateEaseOutCircleEasingFunction(this Compositor compositor) - { - return compositor.CreateCubicBezierEasingFunction(new Vector2(0.075f, 0.820f), new Vector2(0.165f, 1.000f)); - } - - /// - /// Cubic Easing Function - Ease Out - /// - /// Compositor - /// CubicBezierEasingFunction - public static CubicBezierEasingFunction CreateEaseOutCubicEasingFunction(this Compositor compositor) - { - return compositor.CreateCubicBezierEasingFunction(new Vector2(0.215f, 0.610f), new Vector2(0.355f, 1.000f)); - } - - /// - /// Exponential Easing Function - Ease Out - /// - /// Compositor - /// CubicBezierEasingFunction - public static CubicBezierEasingFunction CreateEaseOutExponentialEasingFunction(this Compositor compositor) - { - return compositor.CreateCubicBezierEasingFunction(new Vector2(0.190f, 1.000f), new Vector2(0.220f, 1.000f)); - } - - /// - /// Quadratic Easing Function - Ease Out - /// - /// Compositor - /// CubicBezierEasingFunction - public static CubicBezierEasingFunction CreateEaseOutQuadraticEasingFunction(this Compositor compositor) - { - return compositor.CreateCubicBezierEasingFunction(new Vector2(0.250f, 0.460f), new Vector2(0.450f, 0.940f)); - } - - /// - /// Quartic Easing Function - Ease Out - /// - /// Compositor - /// CubicBezierEasingFunction - public static CubicBezierEasingFunction CreateEaseOutQuarticEasingFunction(this Compositor compositor) - { - return compositor.CreateCubicBezierEasingFunction(new Vector2(0.165f, 0.840f), new Vector2(0.440f, 1.000f)); - } - - /// - /// Quintic Easing Function - Ease Out - /// - /// Compositor - /// CubicBezierEasingFunction - public static CubicBezierEasingFunction CreateEaseOutQuinticEasingFunction(this Compositor compositor) - { - return compositor.CreateCubicBezierEasingFunction(new Vector2(0.230f, 1.000f), new Vector2(0.320f, 1.000f)); - } - - /// - /// Sine Easing Function - Ease Out - /// - /// Compositor - /// CubicBezierEasingFunction - public static CubicBezierEasingFunction CreateEaseOutSineEasingFunction(this Compositor compositor) - { - return compositor.CreateCubicBezierEasingFunction(new Vector2(0.390f, 0.575f), new Vector2(0.565f, 1.000f)); - } - - /// - /// Back Easing Function - Ease In Out - /// - /// Compositor - /// CubicBezierEasingFunction - public static CubicBezierEasingFunction CreateEaseInOutBackEasingFunction(this Compositor compositor) - { - return compositor.CreateCubicBezierEasingFunction(new Vector2(0.680f, -0.550f), new Vector2(0.265f, 1.550f)); - } - - /// - /// Circle Easing Function - Ease In Out - /// - /// Compositor - /// CubicBezierEasingFunction - public static CubicBezierEasingFunction CreateEaseInOutCircleEasingFunction(this Compositor compositor) - { - return compositor.CreateCubicBezierEasingFunction(new Vector2(0.785f, 0.135f), new Vector2(0.150f, 0.860f)); - } - - /// - /// Cubic Easing Function - Ease In Out - /// - /// Compositor - /// CubicBezierEasingFunction - public static CubicBezierEasingFunction CreateEaseInOutCubicEasingFunction(this Compositor compositor) - { - return compositor.CreateCubicBezierEasingFunction(new Vector2(0.645f, 0.045f), new Vector2(0.355f, 1.000f)); - } - - /// - /// Exponential Easing Function - Ease In Out - /// - /// Compositor - /// CubicBezierEasingFunction - public static CubicBezierEasingFunction CreateEaseInOutExponentialEasingFunction(this Compositor compositor) - { - return compositor.CreateCubicBezierEasingFunction(new Vector2(1.000f, 0.000f), new Vector2(0.000f, 1.000f)); - } - - /// - /// Quadratic Easing Function - Ease In Out - /// - /// Compositor - /// CubicBezierEasingFunction - public static CubicBezierEasingFunction CreateEaseInOutQuadraticEasingFunction(this Compositor compositor) - { - return compositor.CreateCubicBezierEasingFunction(new Vector2(0.455f, 0.030f), new Vector2(0.515f, 0.955f)); - } - - /// - /// Quartic Easing Function - Ease In Out - /// - /// Compositor - /// CubicBezierEasingFunction - public static CubicBezierEasingFunction CreateEaseInOutQuarticEasingFunction(this Compositor compositor) - { - return compositor.CreateCubicBezierEasingFunction(new Vector2(0.770f, 0.000f), new Vector2(0.175f, 1.000f)); - } - - /// - /// Quintic Easing Function - Ease In Out - /// - /// Compositor - /// CubicBezierEasingFunction - public static CubicBezierEasingFunction CreateEaseInOutQuinticEasingFunction(this Compositor compositor) - { - return compositor.CreateCubicBezierEasingFunction(new Vector2(0.860f, 0.000f), new Vector2(0.070f, 1.000f)); - } - - /// - /// Sine Easing Function - Ease In Out - /// - /// Compositor - /// CubicBezierEasingFunction - public static CubicBezierEasingFunction CreateEaseInOutSineEasingFunction(this Compositor compositor) - { - return compositor.CreateCubicBezierEasingFunction(new Vector2(0.445f, 0.050f), new Vector2(0.550f, 0.950f)); - } - - /// - /// Creates the CompositionSurfaceBrush from the specified render surface. - /// - /// Compositor - /// An object deriving from IGeometryMaskSurface, IGaussianMaskSurface, IGeometrySurface or IImageSurface - /// CompositionSurfaceBrush - public static CompositionSurfaceBrush CreateSurfaceBrush(this Compositor compositor, IRenderSurface renderSurface) - { - return compositor.CreateSurfaceBrush(renderSurface.Surface); - } } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/GaussianMaskSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/GaussianMaskSurface.cs index 6b33e622fb4..cf30207a6f1 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/GaussianMaskSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/GaussianMaskSurface.cs @@ -21,35 +21,22 @@ internal sealed class GaussianMaskSurface : IGaussianMaskSurface private ICompositionGeneratorInternal _generator; private CompositionDrawingSurface _surface; - /// - /// Gets the Composition Generator - /// + /// public ICompositionGenerator Generator => _generator; - /// - /// Gets the Surface of GaussianMaskSurface - /// + /// public ICompositionSurface Surface => _surface; - /// - /// Gets the Geometry of the GaussianMaskSurface - /// + /// public CanvasGeometry Geometry { get; private set; } - /// - /// Gets the Size of the GaussianMaskSurface - /// + /// public Size Size { get; private set; } - /// - /// Gets the offset from the top left corner of the ICompositionSurface where - /// the Geometry is rendered. - /// + /// public Vector2 Offset { get; private set; } - /// - /// Gets radius of Gaussian Blur to be applied on the GaussianMaskSurface - /// + /// public float BlurRadius { get; private set; } /// @@ -81,93 +68,50 @@ public GaussianMaskSurface(ICompositionGeneratorInternal generator, Size size, C _generator.DeviceReplaced += OnDeviceReplaced; } - /// - /// Redraws the GaussianMaskSurface - /// + /// public void Redraw() { // Redraw the mask surface RedrawSurface(); } - /// - /// Applies the given blur radius to the IGaussianMaskSurface. - /// - /// Radius of Gaussian Blur to be applied on the GaussianMaskSurface + /// public void Redraw(float blurRadius) { Redraw(Size, Geometry, Offset, blurRadius); } - /// - /// Redraws the GaussianMaskSurface with the new geometry - /// - /// New CanvasGeometry to be applied to the mask + /// public void Redraw(CanvasGeometry geometry) { Redraw(Size, geometry, Offset, BlurRadius); } - /// - /// Redraws the GaussianMaskSurface with the new geometry at the specified offset. - /// - /// New CanvasGeometry to be applied to the mask - /// The offset from the top left corner of the ICompositionSurface where - /// the Geometry is rendered. + /// public void Redraw(CanvasGeometry geometry, Vector2 offset) { Redraw(Size, geometry, offset, BlurRadius); } - /// - /// Redraws the IGaussianMaskSurface with the new geometry and fills it with White color after applying - /// the Gaussian blur with given blur radius. - /// - /// New CanvasGeometry to be applied to the GaussianMaskSurface - /// The offset from the top left corner of the ICompositionSurface where - /// the Geometry is rendered. - /// Radius of Gaussian Blur to be applied on the IGaussianMaskSurface + /// public void Redraw(CanvasGeometry geometry, Vector2 offset, float blurRadius) { Redraw(Size, geometry, offset, blurRadius); } - /// - /// Resizes the GaussianMaskSurface with the given size and redraws the GaussianMaskSurface - /// with the new geometry and fills it with White color. A Gaussian blur is applied to the - /// new geometry. - /// - /// New size of the mask - /// New CanvasGeometry to be applied to the mask + /// public void Redraw(Size size, CanvasGeometry geometry) { Redraw(size, geometry, Offset, BlurRadius); } - /// - /// Resizes the GaussianMaskSurface with the given size and redraws the GaussianMaskSurface - /// with the new geometry at the specified offset and fills it with White color. A Gaussian - /// blur is applied to the new geometry. - /// - /// New size of the mask - /// New CanvasGeometry to be applied to the mask - /// The offset from the top left corner of the ICompositionSurface where - /// the Geometry is rendered. + /// public void Redraw(Size size, CanvasGeometry geometry, Vector2 offset) { Redraw(size, geometry, offset, BlurRadius); } - /// - /// Resizes the GaussianMaskSurface with the given size and redraws the GaussianMaskSurface - /// with the new geometry and fills it with White color. A Gaussian blur is applied to the - /// new geometry. - /// - /// New size of the mask - /// New CanvasGeometry to be applied to the mask - /// The offset from the top left corner of the ICompositionSurface where - /// the Geometry is rendered. - /// Radius of Gaussian Blur to be applied on the GaussianMaskSurface + /// public void Redraw(Size size, CanvasGeometry geometry, Vector2 offset, float blurRadius) { // Resize the mask surface @@ -189,10 +133,7 @@ public void Redraw(Size size, CanvasGeometry geometry, Vector2 offset, float blu RedrawSurface(); } - /// - /// Resizes the GaussianMaskSurface to the new size. - /// - /// New size of the mask + /// public void Resize(Size size) { // resize the mask surface @@ -205,9 +146,7 @@ public void Resize(Size size) RedrawSurface(); } - /// - /// Disposes the resources used by the GaussianMaskSurface - /// + /// public void Dispose() { _surface?.Dispose(); diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometryMaskSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometryMaskSurface.cs index 840b9cff35b..acc2e4e3a23 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometryMaskSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometryMaskSurface.cs @@ -60,52 +60,32 @@ public GeometryMaskSurface(ICompositionGeneratorInternal generator, Size size, C _generator.DeviceReplaced += OnDeviceReplaced; } - /// - /// Redraws the GeometryMaskSurface - /// + /// public void Redraw() { // Redraw the mask surface RedrawSurface(); } - /// - /// Redraws the GeometryMaskSurface with the new geometry. - /// - /// New CanvasGeometry to be applied to the mask. + /// public void Redraw(CanvasGeometry geometry) { Redraw(Size, geometry, Offset); } - /// - /// Redraws the IGeometryMaskSurface with the new geometry - /// - /// New CanvasGeometry to be applied to the IGeometryMaskSurface - /// The offset from the top left corner of the ICompositionSurface where the Geometry is rendered. + /// public void Redraw(CanvasGeometry geometry, Vector2 offset) { Redraw(Size, geometry, offset); } - /// - /// Resizes the GeometryMaskSurface with the given size and redraws the GeometryMaskSurface with the new geometry and fills it either with White color - /// (if the MaskMode is True) or with the foreground brush (if the MaskMode is False). - /// - /// New size of the mask - /// New CanvasGeometry to be applied to the mask + /// public void Redraw(Size size, CanvasGeometry geometry) { Redraw(size, geometry, Offset); } - /// - /// Resizes the IGeometryMaskSurface with the given size and redraws the IGeometryMaskSurface with the new geometry and fills it with White color. - /// - /// New size of the mask - /// New CanvasGeometry to be applied to the IGeometryMaskSurface - /// The offset from the top left corner of the ICompositionSurface where - /// the Geometry is rendered. + /// public void Redraw(Size size, CanvasGeometry geometry, Vector2 offset) { if (Size != size) @@ -127,10 +107,7 @@ public void Redraw(Size size, CanvasGeometry geometry, Vector2 offset) RedrawSurface(); } - /// - /// Resizes the GeometryMaskSurface to the new size. - /// - /// New size of the mask + /// public void Resize(Size size) { // resize the mask surface @@ -143,9 +120,7 @@ public void Resize(Size size) RedrawSurface(); } - /// - /// Disposes the resources used by the GeometryMaskSurface. - /// + /// public void Dispose() { _surface?.Dispose(); diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometrySurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometrySurface.cs index d945c05276f..d2b94624628 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometrySurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometrySurface.cs @@ -12,7 +12,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Media { /// - /// Class for rendering custom shaped geometries onto ICompositionSurface + /// Class for rendering custom shaped geometries onto ICompositionSurface. /// internal sealed class GeometrySurface : IGeometrySurface { @@ -24,52 +24,37 @@ internal sealed class GeometrySurface : IGeometrySurface private ICanvasBrush _fill; private ICanvasBrush _backgroundBrush; - /// - /// Gets the Surface Generator - /// + /// public ICompositionGenerator Generator => _generator; - /// - /// Gets the Surface of the GeometrySurface - /// + /// public ICompositionSurface Surface => _surface; - /// - /// Gets the Geometry of the GeometrySurface - /// + /// public CanvasGeometry Geometry => _geometry; - /// - /// Gets the ICanvasStroke with which the Geometry outline is rendered. - /// + /// public ICanvasStroke Stroke => _stroke; - /// - /// Gets the Brush with which the Geometry is filled. - /// + /// public ICanvasBrush Fill => _fill; - /// - /// Gets the Brush with which the GeometrySurface background is filled. - /// + /// public ICanvasBrush BackgroundBrush => _backgroundBrush; - /// - /// Gets the Size of the GeometrySurface - /// + /// public Size Size { get; private set; } /// /// Initializes a new instance of the class. /// Constructor /// - /// IComposiitonGeneratorInternal object - /// Size of the GeometrySurface - /// Geometry of the GeometrySurface - /// Stroke for the geometry - /// Fill color of the geometry - /// Brush to fill the GeometrySurface background surface which is - /// not covered by the geometry + /// IComposiitonGeneratorInternal object. + /// Size of the GeometrySurface. + /// Geometry of the GeometrySurface. + /// Stroke for the geometry. + /// Fill color of the geometry. + /// Brush to fill the GeometrySurface background surface which is not covered by the geometry. public GeometrySurface(ICompositionGeneratorInternal generator, Size size, CanvasGeometry geometry, ICanvasStroke stroke, Color fillColor, Color backgroundColor) { _generator = generator ?? throw new ArgumentException("Generator cannot be null!", nameof(generator)); @@ -94,13 +79,12 @@ public GeometrySurface(ICompositionGeneratorInternal generator, Size size, Canva /// Initializes a new instance of the class. /// Constructor /// - /// IComposiitonGeneratorInternal object - /// Size of the GeometrySurface - /// Geometry of the GeometrySurface - /// Stroke for the geometry - /// Brush to fill the geometry - /// Brush to fill the GeometrySurface background surface which is - /// not covered by the geometry + /// IComposiitonGeneratorInternal object. + /// Size of the GeometrySurface. + /// Geometry of the GeometrySurface. + /// Stroke for the geometry. + /// Brush to fill the geometry. + /// Brush to fill the GeometrySurface background surface which is not covered by the geometry. public GeometrySurface(ICompositionGeneratorInternal generator, Size size, CanvasGeometry geometry, ICanvasStroke stroke, ICanvasBrush fill, ICanvasBrush backgroundBrush) { _generator = generator ?? throw new ArgumentException("Generator cannot be null!", nameof(generator)); @@ -122,19 +106,14 @@ public GeometrySurface(ICompositionGeneratorInternal generator, Size size, Canva _generator.DeviceReplaced += OnDeviceReplaced; } - /// - /// Redraws the GeometrySurface - /// + /// public void Redraw() { // Redraw the GeometrySurface RedrawSurface(); } - /// - /// Redraws the GeometrySurface with the new geometry - /// - /// New CanvasGeometry to be applied to the GeometrySurface + /// public void Redraw(CanvasGeometry geometry) { // Set the new geometry @@ -144,11 +123,7 @@ public void Redraw(CanvasGeometry geometry) RedrawSurface(); } - /// - /// Redraws the GeometrySurface by outlining the existing geometry with - /// the given ICanvasStroke - /// - /// ICanvasStroke defining the outline for the geometry + /// public void Redraw(ICanvasStroke stroke) { // Set the new stroke @@ -158,11 +133,7 @@ public void Redraw(ICanvasStroke stroke) RedrawSurface(); } - /// - /// Redraws the GeometrySurface by filling the existing geometry with - /// the foreground color. - /// - /// Color with which the GeometrySurface geometry is to be filled + /// public void Redraw(Color fillColor) { // Set the fill @@ -179,12 +150,7 @@ public void Redraw(Color fillColor) RedrawSurface(); } - /// - /// Redraws the GeometrySurface by filling the existing geometry with - /// the given fill color and outlining it with the given ICanvasStroke. - /// - /// ICanvasStroke defining the outline for the geometry - /// Color with which the geometry is to be filled + /// public void Redraw(ICanvasStroke stroke, Color fillColor) { // Set the new stroke @@ -204,12 +170,7 @@ public void Redraw(ICanvasStroke stroke, Color fillColor) RedrawSurface(); } - /// - /// Redraws the GeometrySurface by filling the existing geometry with - /// the foreground color and the background with the background color. - /// - /// Color with which the GeometrySurface geometry is to be filled - /// Color with which the GeometrySurface background is to be filled + /// public void Redraw(Color fillColor, Color backgroundColor) { // Set the fill @@ -236,13 +197,7 @@ public void Redraw(Color fillColor, Color backgroundColor) RedrawSurface(); } - /// - /// Redraws the GeometrySurface by outlining the existing geometry with the - /// given ICanvasStroke, filling it with the fill color and the background with the background color. - /// - /// ICanvasStroke defining the outline for the geometry - /// Color with which the geometry is to be filled - /// Color with which the GeometrySurface background is to be filled + /// public void Redraw(ICanvasStroke stroke, Color fillColor, Color backgroundColor) { // Set the new stroke @@ -272,11 +227,7 @@ public void Redraw(ICanvasStroke stroke, Color fillColor, Color backgroundColor) RedrawSurface(); } - /// - /// Redraws the GeometrySurface by filling the existing geometry with - /// the foreground brush. - /// - /// Brush with which the GeometrySurface geometry is to be filled + /// public void Redraw(ICanvasBrush fillBrush) { // Set the fill @@ -286,12 +237,7 @@ public void Redraw(ICanvasBrush fillBrush) RedrawSurface(); } - /// - /// Redraws the GeometrySurface by outlining the existing geometry with the - /// given ICanvasStroke, filling it with the fill brush. - /// - /// ICanvasStroke defining the outline for the geometry - /// Brush with which the geometry is to be filled + /// public void Redraw(ICanvasStroke stroke, ICanvasBrush fillBrush) { // Set the new stroke @@ -304,12 +250,7 @@ public void Redraw(ICanvasStroke stroke, ICanvasBrush fillBrush) RedrawSurface(); } - /// - /// Redraws the GeometrySurface by filling the existing geometry with - /// the foreground brush and the background with the background brush. - /// - /// Brush with which the GeometrySurface geometry is to be filled - /// Brush with which the GeometrySurface background is to be filled + /// public void Redraw(ICanvasBrush fillBrush, ICanvasBrush backgroundBrush) { // Set the fill @@ -322,13 +263,7 @@ public void Redraw(ICanvasBrush fillBrush, ICanvasBrush backgroundBrush) RedrawSurface(); } - /// - /// Redraws the GeometrySurface by outlining the existing geometry with the - /// given ICanvasStroke, filling it with the fill brush and the background with the background brush. - /// - /// ICanvasStroke defining the outline for the geometry - /// Brush with which the geometry is to be filled - /// Brush with which the GeometrySurface background is to be filled + /// public void Redraw(ICanvasStroke stroke, ICanvasBrush fillBrush, ICanvasBrush backgroundBrush) { // Set the new stroke @@ -344,12 +279,7 @@ public void Redraw(ICanvasStroke stroke, ICanvasBrush fillBrush, ICanvasBrush ba RedrawSurface(); } - /// - /// Redraws the GeometrySurface by filling the existing geometry with - /// the foreground color and the background with the background brush. - /// - /// Color with which the GeometrySurface geometry is to be filled - /// Brush with which the GeometrySurface background is to be filled + /// public void Redraw(Color fillColor, ICanvasBrush backgroundBrush) { // Set the fill @@ -369,13 +299,7 @@ public void Redraw(Color fillColor, ICanvasBrush backgroundBrush) RedrawSurface(); } - /// - /// Redraws the GeometrySurface by outlining the existing geometry with the - /// given ICanvasStroke, filling it with the fill color and the background with the background brush. - /// - /// ICanvasStroke defining the outline for the geometry - /// Color with which the geometry is to be filled - /// Brush with which the GeometrySurface background is to be filled + /// public void Redraw(ICanvasStroke stroke, Color fillColor, ICanvasBrush backgroundBrush) { // Set the new stroke @@ -398,12 +322,7 @@ public void Redraw(ICanvasStroke stroke, Color fillColor, ICanvasBrush backgroun RedrawSurface(); } - /// - /// Redraws the GeometrySurface by filling the existing geometry with - /// the foreground brush and the background with the background brush. - /// - /// Brush with which the GeometrySurface geometry is to be filled - /// Color with which the GeometrySurface background is to be filled + /// public void Redraw(ICanvasBrush fillBrush, Color backgroundColor) { // Set the fill @@ -423,13 +342,7 @@ public void Redraw(ICanvasBrush fillBrush, Color backgroundColor) RedrawSurface(); } - /// - /// Redraws the GeometrySurface by outlining the existing geometry with the - /// given ICanvasStroke, filling it with the fill brush and the background with the background color. - /// - /// ICanvasStroke defining the outline for the geometry - /// Brush with which the geometry is to be filled - /// Color with which the GeometrySurface background is to be filled + /// public void Redraw(ICanvasStroke stroke, ICanvasBrush fillBrush, Color backgroundColor) { // Set the new stroke @@ -452,11 +365,7 @@ public void Redraw(ICanvasStroke stroke, ICanvasBrush fillBrush, Color backgroun RedrawSurface(); } - /// - /// Resizes the GeometrySurface with the given size and redraws the GeometrySurface with the new geometry - /// - /// New size of the GeometrySurface - /// New CanvasGeometry to be applied to the GeometrySurface + /// public void Redraw(Size size, CanvasGeometry geometry) { // Resize the GeometrySurface @@ -472,13 +381,7 @@ public void Redraw(Size size, CanvasGeometry geometry) RedrawSurface(); } - /// - /// Resizes the GeometrySurface with the given size and redraws the GeometrySurface - /// with the new geometry and outlines it with the given ICanvasStroke. - /// - /// New size of the GeometrySurface - /// New CanvasGeometry to be applied to the GeometrySurface - /// ICanvasStroke defining the outline for the geometry + /// public void Redraw(Size size, CanvasGeometry geometry, ICanvasStroke stroke) { // Resize the GeometrySurface @@ -497,13 +400,7 @@ public void Redraw(Size size, CanvasGeometry geometry, ICanvasStroke stroke) RedrawSurface(); } - /// - /// Resizes the GeometrySurface with the given size and redraws the GeometrySurface - /// with the new geometry and fills it with the foreground color. - /// - /// New size of the GeometrySurface - /// New CanvasGeometry to be applied to the GeometrySurface - /// Fill color for the geometry + /// public void Redraw(Size size, CanvasGeometry geometry, Color fillColor) { // Resize the GeometrySurface @@ -529,15 +426,7 @@ public void Redraw(Size size, CanvasGeometry geometry, Color fillColor) RedrawSurface(); } - /// - /// Resizes the GeometrySurface with the given size and redraws the GeometrySurface - /// with the new geometry, outlines it with the given ICanvasStroke and fills - /// it with the fill color. - /// - /// New size of the GeometrySurface - /// New CanvasGeometry to be applied to the GeometrySurface - /// ICanvasStroke defining the outline for the geometry - /// Fill color for the geometry + /// public void Redraw(Size size, CanvasGeometry geometry, ICanvasStroke stroke, Color fillColor) { // Resize the GeometrySurface @@ -566,15 +455,7 @@ public void Redraw(Size size, CanvasGeometry geometry, ICanvasStroke stroke, Col RedrawSurface(); } - /// - /// Resizes the GeometrySurface with the given size and redraws the GeometrySurface - /// with the new geometry and fills it with the foreground color and - /// fills the background with the background color. - /// - /// New size of the GeometrySurface - /// New CanvasGeometry to be applied to the GeometrySurface - /// Fill color for the geometry - /// Fill color for the GeometrySurface background + /// public void Redraw(Size size, CanvasGeometry geometry, Color fillColor, Color backgroundColor) { // Resize the GeometrySurface @@ -610,16 +491,7 @@ public void Redraw(Size size, CanvasGeometry geometry, Color fillColor, Color ba RedrawSurface(); } - /// - /// Resizes the GeometrySurface with the given size and redraws the GeometrySurface - /// with the new geometry, outlines it with the given ICanvasStroke and fills it with - /// the fill color and fills the background with the background color. - /// - /// New size of the GeometrySurface - /// New CanvasGeometry to be applied to the GeometrySurface - /// ICanvasStroke defining the outline for the geometry - /// Fill color for the geometry - /// Fill color for the GeometrySurface background + /// public void Redraw(Size size, CanvasGeometry geometry, ICanvasStroke stroke, Color fillColor, Color backgroundColor) { // Resize the GeometrySurface @@ -658,13 +530,7 @@ public void Redraw(Size size, CanvasGeometry geometry, ICanvasStroke stroke, Col RedrawSurface(); } - /// - /// Resizes the GeometrySurface with the given size and redraws the GeometrySurface - /// with the new geometry and fills it with the foreground brush. - /// - /// New size of the GeometrySurface - /// New CanvasGeometry to be applied to the GeometrySurface - /// Brush to fill the geometry + /// public void Redraw(Size size, CanvasGeometry geometry, ICanvasBrush fillBrush) { // Resize the GeometrySurface @@ -683,15 +549,7 @@ public void Redraw(Size size, CanvasGeometry geometry, ICanvasBrush fillBrush) RedrawSurface(); } - /// - /// Resizes the GeometrySurface with the given size and redraws the GeometrySurface - /// with the new geometry and fills it with the foreground brush and fills - /// the background with the background brush. - /// - /// New size of the GeometrySurface - /// New CanvasGeometry to be applied to the GeometrySurface - /// Brush to fill the geometry - /// Brush to fill the GeometrySurface background + /// public void Redraw(Size size, CanvasGeometry geometry, ICanvasBrush fillBrush, ICanvasBrush backgroundBrush) { _generator.ResizeDrawingSurface(_surfaceLock, _surface, size); @@ -712,16 +570,7 @@ public void Redraw(Size size, CanvasGeometry geometry, ICanvasBrush fillBrush, I RedrawSurface(); } - /// - /// Resizes the GeometrySurface with the given size and redraws the GeometrySurface - /// with the new geometry, outlines it with the given ICanvasStroke and fills it with the - /// fill brush and fills the background with the background brush. - /// - /// New size of the GeometrySurface - /// New CanvasGeometry to be applied to the GeometrySurface - /// ICanvasStroke defining the outline for the geometry - /// Brush to fill the geometry - /// Brush to fill the GeometrySurface background + /// public void Redraw(Size size, CanvasGeometry geometry, ICanvasStroke stroke, ICanvasBrush fillBrush, ICanvasBrush backgroundBrush) { // Resize the GeometrySurface @@ -746,15 +595,7 @@ public void Redraw(Size size, CanvasGeometry geometry, ICanvasStroke stroke, ICa RedrawSurface(); } - /// - /// Resizes the GeometrySurface with the given size and redraws the GeometrySurface - /// with the new geometry and fills it with the foreground brush and the background - /// with the background color. - /// - /// New size of the GeometrySurface - /// New CanvasGeometry to be applied to the GeometrySurface - /// Brush to fill the geometry - /// Fill color for the GeometrySurface background + /// public void Redraw(Size size, CanvasGeometry geometry, ICanvasBrush fillBrush, Color backgroundColor) { _generator.ResizeDrawingSurface(_surfaceLock, _surface, size); @@ -782,16 +623,7 @@ public void Redraw(Size size, CanvasGeometry geometry, ICanvasBrush fillBrush, C RedrawSurface(); } - /// - /// Resizes the GeometrySurface with the given size and redraws the GeometrySurface - /// with the new geometry, outlines it with the given ICanvasStroke and fills it with - /// the fill brush and the background with the background color. - /// - /// New size of the GeometrySurface - /// New CanvasGeometry to be applied to the GeometrySurface - /// ICanvasStroke defining the outline for the geometry - /// Brush to fill the geometry - /// Fill color for the GeometrySurface background + /// public void Redraw(Size size, CanvasGeometry geometry, ICanvasStroke stroke, ICanvasBrush fillBrush, Color backgroundColor) { // Resize the GeometrySurface @@ -823,15 +655,7 @@ public void Redraw(Size size, CanvasGeometry geometry, ICanvasStroke stroke, ICa RedrawSurface(); } - /// - /// Resizes the GeometrySurface with the given size and redraws the GeometrySurface - /// with the new geometry and fills it with the foreground color and the background - /// with the background brush. - /// - /// New size of the GeometrySurface - /// New CanvasGeometry to be applied to the GeometrySurface - /// Fill color for the geometry - /// Brush to fill the GeometrySurface background + /// public void Redraw(Size size, CanvasGeometry geometry, Color fillColor, ICanvasBrush backgroundBrush) { _generator.ResizeDrawingSurface(_surfaceLock, _surface, size); @@ -859,16 +683,7 @@ public void Redraw(Size size, CanvasGeometry geometry, Color fillColor, ICanvasB RedrawSurface(); } - /// - /// Resizes the GeometrySurface with the given size and redraws the GeometrySurface - /// with the new geometry, outlines it with the given ICanvasStroke and fills it with - /// the fill color and the background with the background brush. - /// - /// New size of the GeometrySurface - /// New CanvasGeometry to be applied to the GeometrySurface - /// ICanvasStroke defining the outline for the geometry - /// Fill color for the geometry - /// Brush to fill the GeometrySurface background + /// public void Redraw(Size size, CanvasGeometry geometry, ICanvasStroke stroke, Color fillColor, ICanvasBrush backgroundBrush) { // Resize the GeometrySurface @@ -900,10 +715,7 @@ public void Redraw(Size size, CanvasGeometry geometry, ICanvasStroke stroke, Col RedrawSurface(); } - /// - /// Resizes the GeometrySurface to the new size. - /// - /// New size of the GeometrySurface + /// public void Resize(Size size) { // resize the GeometrySurface @@ -916,9 +728,7 @@ public void Resize(Size size) RedrawSurface(); } - /// - /// Disposes the resources used by the GeometrySurface - /// + /// public void Dispose() { _surface?.Dispose(); @@ -941,10 +751,10 @@ public void Dispose() } /// - /// Handles the DeviceReplaced event + /// Handles the DeviceReplaced event. /// - /// Sender - /// object + /// Sender. + /// object. private void OnDeviceReplaced(object sender, object e) { // Recreate the GeometrySurface @@ -955,7 +765,7 @@ private void OnDeviceReplaced(object sender, object e) } /// - /// Helper class to redraw the surface + /// Helper class to redraw the surface. /// private void RedrawSurface() { diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageMaskSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageMaskSurface.cs index 5789e25ee0d..e03984156b1 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageMaskSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageMaskSurface.cs @@ -11,6 +11,9 @@ namespace Microsoft.Toolkit.Uwp.UI.Media { + /// + /// Class for rendering a mask, using an Image's alpha values, onto an ICompositionSurface. + /// internal sealed class ImageMaskSurface : IImageMaskSurface { private readonly object _surfaceLock; @@ -21,72 +24,48 @@ internal sealed class ImageMaskSurface : IImageMaskSurface private bool _raiseLoadCompletedEvent; /// - /// Event that is raised when the image has been downloaded, - /// decoded and loaded to the underlying IImageSurface. This - /// event fires regardless of success or failure. + /// Event that is raised when the image has been downloaded, decoded and loaded to the underlying IImageSurface. + /// This event fires regardless of success or failure. /// public event TypedEventHandler LoadCompleted; - /// - /// Gets the CompositionGenerator - /// + /// public ICompositionGenerator Generator => _generator; - /// - /// Gets the Surface of the IImageMaskSurface - /// + /// public ICompositionSurface Surface => _surface; - /// - /// Gets the Uri of the image to be loaded onto the IImageSurface - /// + /// public Uri Uri => _uri; - /// - /// Gets the CanvasBitmap representing the loaded image - /// + /// public CanvasBitmap SurfaceBitmap => _canvasBitmap; - /// - /// Gets the IImageMaskSurface Size - /// + /// public Size Size { get; private set; } - /// - /// Gets the image's resize and alignment options in the allocated space. - /// + /// public ImageSurfaceOptions Options { get; private set; } - /// - /// Gets the size of the decoded image in physical pixels. - /// + /// public Size DecodedPhysicalSize { get; private set; } - /// - /// Gets the size of the decoded image in device independent pixels. - /// + /// public Size DecodedSize { get; private set; } - /// - /// Gets the status whether the image was loaded successfully or not. - /// + /// public ImageSurfaceLoadStatus Status { get; private set; } - /// - /// Gets the padding between the IImageMaskSurface outer bounds and the bounds of the area where - /// the mask, created from the loaded image's alpha values, should be rendered. - /// + /// public Thickness MaskPadding { get; private set; } /// /// Initializes a new instance of the class. - /// Constructor /// - /// IComposiitonGeneratorInternal object + /// IComposiitonGeneratorInternal object. /// Uri of the image to be loaded onto the IImageMaskSurface. - /// Size of the IImageMaskSurface - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where - /// the mask, created from the loaded image's alpha values, should be rendered. + /// Size of the IImageMaskSurface. + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. /// The image's resize, alignment options and blur radius in the allocated space. public ImageMaskSurface(ICompositionGeneratorInternal generator, Uri uri, Size size, Thickness padding, ImageSurfaceOptions options) { @@ -115,11 +94,10 @@ public ImageMaskSurface(ICompositionGeneratorInternal generator, Uri uri, Size s /// Initializes a new instance of the class. /// Constructor /// - /// IComposiitonGeneratorInternal object + /// IComposiitonGeneratorInternal object. /// The CanvasBitmap whose alpha values will be used to create the Mask. - /// Size of the IImageMaskSurface - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where - /// the mask, created from the loaded image's alpha values, should be rendered. + /// Size of the IImageMaskSurface. + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. /// The image's resize, alignment options and blur radius in the allocated space. public ImageMaskSurface(ICompositionGeneratorInternal generator, CanvasBitmap surfaceBitmap, Size size, Thickness padding, ImageSurfaceOptions options) { @@ -153,19 +131,14 @@ public ImageMaskSurface(ICompositionGeneratorInternal generator, CanvasBitmap su _generator.DeviceReplaced += OnDeviceReplaced; } - /// - /// Redraws the IImageMaskSurface - /// + /// public void Redraw() { // Reload the IImageMaskSurface RedrawSurface(); } - /// - /// Redraws the IImageMaskSurface with the given image options. - /// - /// The image's resize, alignment options and blur radius in the allocated space. + /// public void Redraw(ImageSurfaceOptions options) { // Set the image options @@ -175,11 +148,7 @@ public void Redraw(ImageSurfaceOptions options) RedrawSurface(); } - /// - /// Redraws the IImageMaskSurface using the given padding and image options. - /// - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. - /// The image's resize, alignment and blur radius options in the allocated space. + /// public void Redraw(Thickness padding, ImageSurfaceOptions options) { // Set the mask padding @@ -192,11 +161,7 @@ public void Redraw(Thickness padding, ImageSurfaceOptions options) RedrawSurface(); } - /// - /// Resizes and redraws the IImageMaskSurface using the given image options. - /// - /// New size of the IImageMaskSurface. - /// The image's resize, alignment and blur radius options in the allocated space. + /// public void Redraw(Size size, ImageSurfaceOptions options) { // Resize if required @@ -216,13 +181,7 @@ public void Redraw(Size size, ImageSurfaceOptions options) RedrawSurface(); } - /// - /// Resizes and redraws the IImageMaskSurface using the given padding and image options. - /// - /// New size of the IImageMaskSurface. - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where - /// the mask, created from the loaded image's alpha values, should be rendered. - /// The image's resize, alignment and blur radius options in the allocated space. + /// public void Redraw(Size size, Thickness padding, ImageSurfaceOptions options) { // Resize if required @@ -245,10 +204,7 @@ public void Redraw(Size size, Thickness padding, ImageSurfaceOptions options) RedrawSurface(); } - /// - /// Redraws the IImageMaskSurface using the alpha values of image in the given imageSurface. - /// - /// IImageSurface whose image is to be loaded on the surface. + /// public void Redraw(IImageSurface imageSurface) { if (imageSurface != null) @@ -262,11 +218,7 @@ public void Redraw(IImageSurface imageSurface) } } - /// - /// Redraws the IImageMaskSurface (using the alpha values of image in the given imageSurface). - /// - /// IImageSurface whose image is to be loaded on the surface. - /// Describes the image's resize, alignment and blur radius options in the allocated space. + /// public void Redraw(IImageSurface imageSurface, ImageSurfaceOptions options) { if (imageSurface != null) @@ -280,23 +232,13 @@ public void Redraw(IImageSurface imageSurface, ImageSurfaceOptions options) } } - /// - /// Resizes and redraws the IImageMaskSurface (using the alpha values of image in the given imageSurface). - /// - /// IImageSurface whose image is to be loaded on the surface. - /// New size of the IImageMaskSurface. - /// Describes the image's resize, alignment and blur radius options in the allocated space. + /// public void Redraw(IImageSurface imageSurface, Size size, ImageSurfaceOptions options) { Redraw(imageSurface?.SurfaceBitmap, size, MaskPadding, options); } - /// - /// Redraws the IImageMaskSurface using the alpha values of the image in the given IImageSurface with the given padding. - /// - /// ImageSurface whose image's alpha values are to be used to create the mask. - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where - /// the mask, created from the loaded image's alpha values, should be rendered. + /// public void Redraw(IImageSurface imageSurface, Thickness padding) { if (imageSurface != null) @@ -310,14 +252,7 @@ public void Redraw(IImageSurface imageSurface, Thickness padding) } } - /// - /// Redraws the IImageMaskSurface using the alpha values of the image in the given IImageSurface with the given padding - /// using the given options. - /// - /// ImageSurface whose image's alpha values are to be used to create the mask. - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where - /// the mask, created from the loaded image's alpha values, should be rendered. - /// Describes the image's resize, alignment and blur radius options in the allocated space. + /// public void Redraw(IImageSurface imageSurface, Thickness padding, ImageSurfaceOptions options) { if (imageSurface != null) @@ -331,24 +266,13 @@ public void Redraw(IImageSurface imageSurface, Thickness padding, ImageSurfaceOp } } - /// - /// Resizes and redraws the IImageMaskSurface using the alpha values of the image in the given IImageSurface - /// with the given padding and options. - /// - /// ImageSurface whose image's alpha values are to be used to create the mask. - /// New size of the IImageMaskSurface. - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where - /// the mask, created from the loaded image's alpha values, should be rendered. - /// Describes the image's resize, alignment and blur radius options in the allocated space. + /// public void Redraw(IImageSurface imageSurface, Size size, Thickness padding, ImageSurfaceOptions options) { Redraw(imageSurface?.SurfaceBitmap, size, padding, options); } - /// - /// Redraws the IImageMaskSurface using the alpha values of the image in the given IImageMaskSurface. - /// - /// IImageMaskSurface whose image's alpha values are to be used to create the mask. + /// public void Redraw(IImageMaskSurface imageMaskSurface) { if (imageMaskSurface != null) @@ -362,13 +286,7 @@ public void Redraw(IImageMaskSurface imageMaskSurface) } } - /// - /// Redraws the IImageMaskSurface using the alpha values of the image in the given IImageMaskSurface with the given padding - /// and options. - /// - /// IImageMaskSurface whose image's alpha values are to be used to create the mask. - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where - /// the mask, created from the loaded image's alpha values, should be rendered. + /// public void Redraw(IImageMaskSurface imageMaskSurface, Thickness padding) { if (imageMaskSurface != null) @@ -382,11 +300,7 @@ public void Redraw(IImageMaskSurface imageMaskSurface, Thickness padding) } } - /// - /// Redraws the IImageMaskSurface using the alpha values of the image in the given IImageMaskSurface with the given options. - /// - /// IImageMaskSurface whose image's alpha values are to be used to create the mask. - /// Describes the image's resize, alignment and blur radius options in the allocated space. + /// public void Redraw(IImageMaskSurface imageMaskSurface, ImageSurfaceOptions options) { if (imageMaskSurface != null) @@ -400,14 +314,7 @@ public void Redraw(IImageMaskSurface imageMaskSurface, ImageSurfaceOptions optio } } - /// - /// Redraws the IImageMaskSurface using the alpha values of the image in the given IImageMaskSurface using the given padding - /// and options. - /// - /// IImageMaskSurface whose image's alpha values are to be used to create the mask. - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where - /// the mask, created from the loaded image's alpha values, should be rendered. - /// Describes the image's resize, alignment and blur radius options in the allocated space. + /// public void Redraw(IImageMaskSurface imageMaskSurface, Thickness padding, ImageSurfaceOptions options) { if (imageMaskSurface != null) @@ -421,83 +328,43 @@ public void Redraw(IImageMaskSurface imageMaskSurface, Thickness padding, ImageS } } - /// - /// Resizes and redraws the IImageMaskSurface using the alpha values of the image in the given IImageMaskSurface - /// with the given padding and options. - /// - /// IImageMaskSurface whose image's alpha values are to be used to create the mask. - /// New size of the IImageMaskSurface. - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where - /// the mask, created from the loaded image's alpha values, should be rendered. - /// Describes the image's resize, alignment and blur radius options in the allocated space. + /// public void Redraw(IImageMaskSurface imageMaskSurface, Size size, Thickness padding, ImageSurfaceOptions options) { Redraw(imageMaskSurface?.SurfaceBitmap, size, padding, options); } - /// - /// Redraws the IImageMaskSurface using the given CanvasBitmap's alpha values. - /// - /// Image whose alpha values are to be used to create the mask. + /// public void Redraw(CanvasBitmap surfaceBitmap) { Redraw(surfaceBitmap, Size, MaskPadding, Options); } - /// - /// Redraws the IImageMaskSurface using the given CanvasBitmap's alpha values with the given padding. - /// - /// Image whose alpha values are to be used to create the mask. - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where - /// the mask, created from the loaded image's alpha values, should be rendered. + /// public void Redraw(CanvasBitmap surfaceBitmap, Thickness padding) { Redraw(surfaceBitmap, Size, padding, Options); } - /// - /// Redraws the IImageMaskSurface using the given CanvasBitmap's alpha values and the given options. - /// - /// Image whose alpha values are to be used to create the mask. - /// The image's resize, alignment options and blur radius in the allocated space. + /// public void Redraw(CanvasBitmap surfaceBitmap, ImageSurfaceOptions options) { Redraw(surfaceBitmap, Size, MaskPadding, options); } - /// - /// Resizes and redraws the IImageMaskSurface using the given CanvasBitmap's alpha values and the given options. - /// - /// Image whose alpha values are to be used to create the mask. - /// New size of the IImageMaskSurface. - /// The image's resize, alignment options and blur radius in the allocated space. + /// public void Redraw(CanvasBitmap surfaceBitmap, Size size, ImageSurfaceOptions options) { Redraw(surfaceBitmap, size, MaskPadding, options); } - /// - /// Redraws the IImageMaskSurface using the given CanvasBitmap's alpha values with the given padding - /// using the given options. - /// - /// Image whose alpha values are to be used to create the mask. - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where - /// the mask, created from the loaded image's alpha values, should be rendered. - /// The image's resize, alignment options and blur radius in the allocated space. + /// public void Redraw(CanvasBitmap surfaceBitmap, Thickness padding, ImageSurfaceOptions options) { Redraw(surfaceBitmap, Size, padding, options); } - /// - /// Resizes and redraws the IImageMaskSurface using the given CanvasBitmap's alpha values with the given padding - /// using the given options. - /// - /// Image whose alpha values are to be used to create the mask. - /// New size of the IImageMaskSurface. - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where - /// the mask, created from the loaded image's alpha values, should be rendered. - /// The image's resize, alignment and blur radius options in the allocated space. + /// public void Redraw(CanvasBitmap surfaceBitmap, Size size, Thickness padding, ImageSurfaceOptions options) { if (_canvasBitmap != surfaceBitmap) @@ -552,63 +419,31 @@ public void Redraw(CanvasBitmap surfaceBitmap, Size size, Thickness padding, Ima RedrawSurface(); } - /// - /// Redraws the IImageMaskSurface by loading image from the new Uri - /// - /// Uri of the image to be loaded on to the image surface. - /// Task + /// public Task RedrawAsync(Uri uri) { return RedrawAsync(uri, Size, MaskPadding, Options); } - /// - /// Redraws the IImageMaskSurface by loading image from the new Uri and image options - /// - /// Uri of the image to be loaded on to the image surface. - /// The image's resize, alignment and blur radius options in the allocated space. - /// Task + /// public Task RedrawAsync(Uri uri, ImageSurfaceOptions options) { return RedrawAsync(uri, Size, MaskPadding, options); } - /// - /// Redraws the IImageMaskSurface by loading image from the new Uri and image options - /// - /// Uri of the image to be loaded on to the image surface. - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where - /// the mask, created from the loaded image's alpha values, should be rendered. - /// The image's resize, alignment and blur radius options in the allocated space. - /// Task + /// public Task RedrawAsync(Uri uri, Thickness padding, ImageSurfaceOptions options) { return RedrawAsync(uri, Size, padding, options); } - /// - /// Resizes the IImageMaskSurface with the given size and redraws the IImageMaskSurface by loading - /// image from the new Uri. - /// - /// Uri of the image to be loaded onto the IImageMaskSurface. - /// New size of the IImageMaskSurface - /// The image's resize and alignment options in the allocated space. - /// Task + /// public Task RedrawAsync(Uri uri, Size size, ImageSurfaceOptions options) { return RedrawAsync(uri, size, MaskPadding, options); } - /// - /// Resizes the IImageMaskSurface with the given size and loads the image from the new Uri and uses its - /// alpha values to redraw the IImageMaskSurface with the given padding using the given options. - /// - /// Uri of the image to be loaded onto the IImageMaskSurface. - /// New size of the IImageMaskSurface - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where - /// the mask, created from the loaded image's alpha values, should be rendered. - /// The image's resize, alignment and blur radius options in the allocated space. - /// Task + /// public async Task RedrawAsync(Uri uri, Size size, Thickness padding, ImageSurfaceOptions options) { // If the given Uri differs from the previously stored Uri or if the ImageSurface was @@ -644,32 +479,19 @@ public async Task RedrawAsync(Uri uri, Size size, Thickness padding, ImageSurfac await RedrawSurfaceAsync(); } - /// - /// Resizes the IImageMaskSurface to the new size. - /// - /// New size of the IImageMaskSurface + /// public void Resize(Size size) { Resize(size, MaskPadding, Options); } - /// - /// Resizes the IImageMaskSurface to the new size using the given options. - /// - /// New size of the IImageMaskSurface - /// The image's resize, alignment and blur radius options in the allocated space. + /// public void Resize(Size size, ImageSurfaceOptions options) { Resize(size, MaskPadding, options); } - /// - /// Resizes the IImageMaskSurface to the new size and redraws it with the given padding using the given options. - /// - /// New size of the IImageMaskSurface - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where - /// the mask, created from the loaded image's alpha values, should be rendered. - /// The image's resize, alignment and blur radius options in the allocated space. + /// public void Resize(Size size, Thickness padding, ImageSurfaceOptions options) { // Set the mask padding @@ -692,9 +514,7 @@ public void Resize(Size size, Thickness padding, ImageSurfaceOptions options) RedrawSurface(); } - /// - /// Disposes the resources used by the IImageMaskSurface - /// + /// public void Dispose() { _surface?.Dispose(); @@ -724,8 +544,8 @@ internal Task RedrawAsync() /// /// Handles the DeviceReplaced event /// - /// Sender - /// object + /// Sender. + /// object. private async void OnDeviceReplaced(object sender, object e) { // Recreate the ImageSurface @@ -736,7 +556,7 @@ private async void OnDeviceReplaced(object sender, object e) } /// - /// Helper class to redraw the IImageMaskSurface synchronously + /// Helper class to redraw the IImageMaskSurface synchronously. /// private void RedrawSurface() { @@ -753,7 +573,7 @@ private void RedrawSurface() } /// - /// Helper class to redraw the IImageMaskSurface asynchronously + /// Helper class to redraw the IImageMaskSurface asynchronously. /// /// Task private async Task RedrawSurfaceAsync() diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurface.cs index 29ad6acc938..babfe512617 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurface.cs @@ -11,7 +11,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Media { /// - /// Class for rendering an image onto a ICompositionSurface + /// Class for rendering an image onto a ICompositionSurface. /// internal sealed class ImageSurface : IImageSurface { @@ -28,58 +28,40 @@ internal sealed class ImageSurface : IImageSurface /// public event TypedEventHandler LoadCompleted; - /// - /// Gets the CompositionGenerator - /// + /// public ICompositionGenerator Generator => _generator; - /// - /// Gets the Surface of the IImageSurface - /// + /// public ICompositionSurface Surface => _surface; - /// - /// Gets the Uri of the image to be loaded onto the IImageSurface - /// + /// public Uri Uri => _uri; - /// - /// Gets the IImageSurface Size - /// + /// public Size Size { get; private set; } - /// - /// Gets the image's resize and alignment options in the allocated space. - /// + /// public ImageSurfaceOptions Options { get; private set; } - /// - /// Gets the size of the decoded image in physical pixels. - /// + /// public Size DecodedPhysicalSize { get; private set; } - /// - /// Gets the size of the decoded image in device independent pixels. - /// + /// public Size DecodedSize { get; private set; } - /// - /// Gets the status whether the image was loaded successfully or not. - /// + /// public ImageSurfaceLoadStatus Status { get; private set; } - /// - /// Gets the CanvasBitmap representing the loaded image - /// + /// public CanvasBitmap SurfaceBitmap => _canvasBitmap; /// /// Initializes a new instance of the class. /// Constructor /// - /// IComposiitonGeneratorInternal object + /// IComposiitonGeneratorInternal object. /// Uri of the image to be loaded onto the IImageSurface. - /// Size of the IImageSurface + /// Size of the IImageSurface. /// The image's resize and alignment options in the allocated space. public ImageSurface(ICompositionGeneratorInternal generator, Uri uri, Size size, ImageSurfaceOptions options) { @@ -107,9 +89,9 @@ public ImageSurface(ICompositionGeneratorInternal generator, Uri uri, Size size, /// Initializes a new instance of the class. /// Constructor /// - /// IComposiitonGeneratorInternal object + /// IComposiitonGeneratorInternal object. /// CanvasBitmap which will be rendered on the IImageSurface. - /// Size of the IImageSurface + /// Size of the IImageSurface. /// The image's resize and alignment options in the allocated space. internal ImageSurface(ICompositionGeneratorInternal generator, CanvasBitmap surfaceBitmap, Size size, ImageSurfaceOptions options) { @@ -140,19 +122,14 @@ internal ImageSurface(ICompositionGeneratorInternal generator, CanvasBitmap surf _generator.DeviceReplaced += OnDeviceReplaced; } - /// - /// Redraws the IImageSurface - /// + /// public void Redraw() { // Reload the IImageSurface RedrawSurface(); } - /// - /// Redraws the IImageSurface with the given image options - /// - /// The image's resize and alignment options in the allocated space. + /// public void Redraw(ImageSurfaceOptions options) { // Set the image options @@ -162,11 +139,7 @@ public void Redraw(ImageSurfaceOptions options) RedrawSurface(); } - /// - /// Resizes and redraws the IImageSurface using the given options. - /// - /// New size of the IImageMaskSurface. - /// Describes the image's resize, alignment options in the allocated space. + /// public void Redraw(Size size, ImageSurfaceOptions options) { // Resize the surface only if AutoResize option is disabled @@ -186,11 +159,7 @@ public void Redraw(Size size, ImageSurfaceOptions options) RedrawSurface(); } - /// - /// Redraws the IImageSurface (using the image in the given imageSurface) or the IImageMaskSurface - /// (using the alpha values of image in the given imageSurface). - /// - /// IImageSurface whose image is to be loaded on the surface. + /// public void Redraw(IImageSurface imageSurface) { if (imageSurface != null) @@ -204,12 +173,7 @@ public void Redraw(IImageSurface imageSurface) } } - /// - /// Redraws the IImageSurface (using the image in the given imageSurface) or the IImageMaskSurface - /// (using the alpha values of image in the given imageSurface). - /// - /// IImageSurface whose image is to be loaded on the surface. - /// Describes the image's resize, alignment options in the allocated space. + /// public void Redraw(IImageSurface imageSurface, ImageSurfaceOptions options) { if (imageSurface != null) @@ -223,32 +187,19 @@ public void Redraw(IImageSurface imageSurface, ImageSurfaceOptions options) } } - /// - /// Resizes and redraws the IImageSurface (using the image in the given imageSurface) or the IImageMaskSurface - /// (using the alpha values of image in the given imageSurface). - /// - /// IImageSurface whose image is to be loaded on the surface. - /// New size of the IImageMaskSurface. - /// Describes the image's resize, alignment options in the allocated space. + /// public void Redraw(IImageSurface imageSurface, Size size, ImageSurfaceOptions options) { Redraw(imageSurface?.SurfaceBitmap, size, options); } - /// - /// Redraws the IImageSurface using the given CanvasBitmap. - /// - /// Image to be loaded on the surface. + /// public void Redraw(CanvasBitmap surfaceBitmap) { Redraw(surfaceBitmap, Size, Options); } - /// - /// Redraws the IImageSurface using the given CanvasBitmap using the given options. - /// - /// Image whose alpha values are to be used to create the mask. - /// The image's resize, alignment options in the allocated space. + /// public void Redraw(CanvasBitmap surfaceBitmap, ImageSurfaceOptions options) { // Set the image options @@ -258,12 +209,7 @@ public void Redraw(CanvasBitmap surfaceBitmap, ImageSurfaceOptions options) Redraw(surfaceBitmap, Size, Options); } - /// - /// Resizes and redraws the IImageSurface using the given CanvasBitmap using the given options. - /// - /// Image whose alpha values are to be used to create the mask. - /// New size of the IImageSurface. - /// The image's resize, alignment options in the allocated space. + /// public void Redraw(CanvasBitmap surfaceBitmap, Size size, ImageSurfaceOptions options) { if (_canvasBitmap != surfaceBitmap) @@ -314,35 +260,19 @@ public void Redraw(CanvasBitmap surfaceBitmap, Size size, ImageSurfaceOptions op RedrawSurface(); } - /// - /// Redraws the IImageSurface by loading image from the new Uri - /// - /// Uri of the image to be loaded on the surface. - /// Task + /// public Task RedrawAsync(Uri uri) { return RedrawAsync(uri, Size, Options); } - /// - /// Redraws the IImageSurface by loading image from the new Uri and image options - /// - /// Uri of the image to be loaded on to the image surface. - /// The image's resize and alignment options in the allocated space. - /// Task + /// public Task RedrawAsync(Uri uri, ImageSurfaceOptions options) { return RedrawAsync(uri, Size, options); } - /// - /// Resizes the IImageSurface with the given size and redraws the IImageSurface by loading - /// image from the new Uri. - /// - /// Uri of the image to be loaded onto the IImageSurface. - /// New size of the IImageSurface - /// The image's resize and alignment options in the allocated space. - /// Task + /// public Task RedrawAsync(Uri uri, Size size, ImageSurfaceOptions options) { // If the given Uri differs from the previously stored Uri or if the ImageSurface was @@ -375,20 +305,13 @@ public Task RedrawAsync(Uri uri, Size size, ImageSurfaceOptions options) return RedrawSurfaceAsync(); } - /// - /// Resizes the IImageSurface to the new size. - /// - /// New size of the IImageSurface + /// public void Resize(Size size) { Resize(size, Options); } - /// - /// Resizes the IImageSurface to the new size. - /// - /// New size of the IImageSurface - /// The image's resize and alignment options in the allocated space. + /// public void Resize(Size size, ImageSurfaceOptions options) { // Set the image options @@ -408,9 +331,7 @@ public void Resize(Size size, ImageSurfaceOptions options) RedrawSurface(); } - /// - /// Disposes the resources used by the IImageSurface - /// + /// public void Dispose() { _surface?.Dispose(); @@ -439,10 +360,10 @@ internal Task RedrawAsync() } /// - /// Handles the DeviceReplaced event + /// Handles the DeviceReplaced event. /// - /// Sender - /// object + /// Sender. + /// object. private async void OnDeviceReplaced(object sender, object e) { // Recreate the ImageSurface @@ -453,7 +374,7 @@ private async void OnDeviceReplaced(object sender, object e) } /// - /// Helper class to redraw the IImageSurface synchronously + /// Helper class to redraw the IImageSurface synchronously. /// private void RedrawSurface() { @@ -479,7 +400,7 @@ private void RedrawSurface() } /// - /// Helper class to redraw the IImageSurface asynchronously + /// Helper class to redraw the IImageSurface asynchronously. /// /// Task private async Task RedrawSurfaceAsync() diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurfaceOptions.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurfaceOptions.cs index 64ab57f981b..9e28e6b165c 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurfaceOptions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurfaceOptions.cs @@ -11,8 +11,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Media { /// - /// Enum to define the location of the - /// Reflection of a Visual. + /// Enum to define the location of the Reflection of a Visual. /// public enum ReflectionLocation { @@ -38,8 +37,7 @@ public enum ReflectionLocation } /// - /// Class to define the various options that would - /// influence the rendering of the image on the ImageSurface + /// Class to define the various options that would influence the rendering of the image on the ImageSurface /// public class ImageSurfaceOptions : DependencyObject { @@ -49,8 +47,8 @@ public class ImageSurfaceOptions : DependencyObject public event EventHandler Updated; /// - /// Gets default ImageSurfaceOptions when AutoResize is True - /// Uniform Stretch and Center alignment + /// Gets default ImageSurfaceOptions when AutoResize is True. + /// Uniform Stretch and Center alignment. /// public static ImageSurfaceOptions Default => new ImageSurfaceOptions() @@ -66,8 +64,8 @@ public class ImageSurfaceOptions : DependencyObject }; /// - /// Gets default ImageSurfaceOptions when AutoResize is False - /// Uniform Stretch and Center alignment + /// Gets default ImageSurfaceOptions when AutoResize is False. + /// Uniform Stretch and Center alignment. /// public static ImageSurfaceOptions DefaultOptimized => new ImageSurfaceOptions() @@ -83,7 +81,7 @@ public class ImageSurfaceOptions : DependencyObject }; /// - /// Gets default ImageSurfaceOptions for IImageMaskSurface + /// Gets default ImageSurfaceOptions for IImageMaskSurface. /// Uniform Stretch and Center alignment /// public static ImageSurfaceOptions DefaultImageMaskOptions => @@ -273,8 +271,8 @@ public double BlurRadius /// /// Method that is called whenever the dependency properties of the ImageSurfaceOptions changes. /// - /// The object whose property has changed - /// Event arguments + /// The object whose property has changed. + /// Event arguments. private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var options = (ImageSurfaceOptions)d; diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/ICompositionGenerator.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/ICompositionGenerator.cs index 1cf75f77ca2..feb18ceb2f5 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/ICompositionGenerator.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/ICompositionGenerator.cs @@ -26,12 +26,12 @@ public interface ICompositionGenerator : IDisposable event EventHandler DeviceReplaced; /// - /// Gets the Compositor + /// Gets the Compositor. /// Compositor Compositor { get; } /// - /// Gets the CanvasDevice + /// Gets the CanvasDevice. /// CanvasDevice Device { get; } @@ -47,8 +47,8 @@ public interface ICompositionGenerator : IDisposable /// Creates a GeometryMaskSurface having the given size and geometry. The geometry is filled /// with white color. The surface not covered by the geometry is transparent. /// - /// Size of the mask - /// Geometry of the mask + /// Size of the mask. + /// Geometry of the mask. /// IGeometryMaskSurface IGeometryMaskSurface CreateGeometryMaskSurface(Size size, CanvasGeometry geometry); @@ -56,10 +56,9 @@ public interface ICompositionGenerator : IDisposable /// Creates a GeometryMaskSurface having the given size and geometry. The geometry is filled /// with white color. The surface not covered by the geometry is transparent. /// - /// Size of the mask - /// Geometry of the mask - /// The offset from the top left corner of the ICompositionSurface where - /// the Geometry is rendered. + /// Size of the mask. + /// Geometry of the mask. + /// The offset from the top left corner of the ICompositionSurface where the Geometry is rendered. /// IGeometryMaskSurface IGeometryMaskSurface CreateGeometryMaskSurface(Size size, CanvasGeometry geometry, Vector2 offset); @@ -75,11 +74,10 @@ public interface ICompositionGenerator : IDisposable /// Creates an IGaussianMaskSurface having the given size and geometry. The geometry is filled /// with white color and a Gaussian blur is applied to it. The surface not covered by the geometry is transparent. /// - /// Size of the mask - /// Geometry of the mask - /// The offset from the top left corner of the ICompositionSurface where - /// the Geometry is rendered. - /// Radius of Gaussian Blur to be applied on the IGaussianMaskSurface + /// Size of the mask. + /// Geometry of the mask. + /// The offset from the top left corner of the ICompositionSurface where the Geometry is rendered. + /// Radius of Gaussian Blur to be applied on the IGaussianMaskSurface. /// IGaussianMaskSurface IGaussianMaskSurface CreateGaussianMaskSurface(Size size, CanvasGeometry geometry, Vector2 offset, float blurRadius); @@ -94,17 +92,17 @@ public interface ICompositionGenerator : IDisposable /// /// Creates an IGeometrySurface having the given size, geometry, stroke /// - /// Size of the IGeometrySurface - /// Geometry to be rendered on the IGeometrySurface - /// ICanvasStroke defining the outline for the geometry + /// Size of the IGeometrySurface. + /// Geometry to be rendered on the IGeometrySurface. + /// ICanvasStroke defining the outline for the geometry. /// IGeometrySurface IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasStroke stroke); /// /// Creates an IGeometrySurface having the given size, geometry, fill color /// - /// Size of the IGeometrySurface - /// Geometry to be rendered on the IGeometrySurface + /// Size of the IGeometrySurface. + /// Geometry to be rendered on the IGeometrySurface. /// Fill color of the geometry. /// IGeometrySurface IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, Color fillColor); @@ -112,9 +110,9 @@ public interface ICompositionGenerator : IDisposable /// /// Creates an IGeometrySurface having the given size, geometry, stroke and fill color /// - /// Size of the IGeometrySurface - /// Geometry to be rendered on the IGeometrySurface - /// ICanvasStroke defining the outline for the geometry + /// Size of the IGeometrySurface. + /// Geometry to be rendered on the IGeometrySurface. + /// ICanvasStroke defining the outline for the geometry. /// Fill color of the geometry. /// IGeometrySurface IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasStroke stroke, Color fillColor); @@ -123,11 +121,11 @@ public interface ICompositionGenerator : IDisposable /// Creates an IGeometrySurface having the given size, geometry, fill color and /// background color. /// - /// Size of the IGeometrySurface - /// Geometry to be rendered on the IGeometrySurface - /// Fill color of the geometry + /// Size of the IGeometrySurface. + /// Geometry to be rendered on the IGeometrySurface. + /// Fill color of the geometry. /// Fill color of the IGeometrySurface background which is - /// not covered by the geometry + /// not covered by the geometry. /// IGeometrySurface IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, Color fillColor, Color backgroundColor); @@ -135,31 +133,30 @@ public interface ICompositionGenerator : IDisposable /// Creates an IGeometrySurface having the given size, geometry, stroke, fill color and /// background color. /// - /// Size of the IGeometrySurface - /// Geometry to be rendered on the IGeometrySurface - /// ICanvasStroke defining the outline for the geometry - /// Fill color of the geometry - /// Fill color of the IGeometrySurface background which is - /// not covered by the geometry + /// Size of the IGeometrySurface. + /// Geometry to be rendered on the IGeometrySurface. + /// ICanvasStroke defining the outline for the geometry. + /// Fill color of the geometry. + /// Fill color of the IGeometrySurface background which is not covered by the geometry. /// IGeometrySurface IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasStroke stroke, Color fillColor, Color backgroundColor); /// /// Creates an IGeometrySurface having the given size, geometry and fill brush. /// - /// Size of the IGeometrySurface - /// Geometry to be rendered on the IGeometrySurface - /// The brush with which the geometry has to be filled + /// Size of the IGeometrySurface. + /// Geometry to be rendered on the IGeometrySurface. + /// The brush with which the geometry has to be filled. /// IGeometrySurface IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasBrush fillBrush); /// /// Creates an IGeometrySurface having the given size, geometry, stroke and fill brush. /// - /// Size of the IGeometrySurface - /// Geometry to be rendered on the IGeometrySurface - /// ICanvasStroke defining the outline for the geometry - /// The brush with which the geometry has to be filled + /// Size of the IGeometrySurface. + /// Geometry to be rendered on the IGeometrySurface. + /// ICanvasStroke defining the outline for the geometry. + /// The brush with which the geometry has to be filled. /// IGeometrySurface IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasStroke stroke, ICanvasBrush fillBrush); @@ -167,11 +164,10 @@ public interface ICompositionGenerator : IDisposable /// Creates an IGeometrySurface having the given size, geometry, fill brush and /// background brush. /// - /// Size of the IGeometrySurface - /// Geometry to be rendered on the IGeometrySurface - /// The brush with which the geometry has to be filled - /// The brush to fill the IGeometrySurface background which is - /// not covered by the geometry + /// Size of the IGeometrySurface. + /// Geometry to be rendered on the IGeometrySurface. + /// The brush with which the geometry has to be filled. + /// The brush to fill the IGeometrySurface background which is not covered by the geometry. /// IGeometrySurface IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasBrush fillBrush, ICanvasBrush backgroundBrush); @@ -179,12 +175,11 @@ public interface ICompositionGenerator : IDisposable /// Creates an IGeometrySurface having the given size, geometry, stroke, fill brush and /// background brush. /// - /// Size of the IGeometrySurface - /// Geometry to be rendered on the IGeometrySurface - /// ICanvasStroke defining the outline for the geometry - /// The brush with which the geometry has to be filled - /// The brush to fill the IGeometrySurface background which is - /// not covered by the geometry + /// Size of the IGeometrySurface. + /// Geometry to be rendered on the IGeometrySurface. + /// ICanvasStroke defining the outline for the geometry. + /// The brush with which the geometry has to be filled. + /// The brush to fill the IGeometrySurface background which is not covered by the geometry. /// IGeometrySurface IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasStroke stroke, ICanvasBrush fillBrush, ICanvasBrush backgroundBrush); @@ -192,11 +187,10 @@ public interface ICompositionGenerator : IDisposable /// Creates an IGeometrySurface having the given size, geometry, fill brush and /// background color. /// - /// Size of the IGeometrySurface - /// Geometry to be rendered on the IGeometrySurface - /// The brush with which the geometry has to be filled - /// Fill color of the IGeometrySurface background which is - /// not covered by the geometry + /// Size of the IGeometrySurface. + /// Geometry to be rendered on the IGeometrySurface. + /// The brush with which the geometry has to be filled. + /// Fill color of the IGeometrySurface background which is not covered by the geometry. /// IGeometrySurface IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasBrush fillBrush, Color backgroundColor); @@ -204,12 +198,11 @@ public interface ICompositionGenerator : IDisposable /// Creates an IGeometrySurface having the given size, geometry, stroke, fill brush and /// background color. /// - /// Size of the IGeometrySurface - /// Geometry to be rendered on the IGeometrySurface - /// ICanvasStroke defining the outline for the geometry - /// The brush with which the geometry has to be filled - /// Fill color of the IGeometrySurface background which is - /// not covered by the geometry + /// Size of the IGeometrySurface. + /// Geometry to be rendered on the IGeometrySurface. + /// ICanvasStroke defining the outline for the geometry. + /// The brush with which the geometry has to be filled. + /// Fill color of the IGeometrySurface background which is not covered by the geometry. /// IGeometrySurface IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasStroke stroke, ICanvasBrush fillBrush, Color backgroundColor); @@ -217,11 +210,10 @@ public interface ICompositionGenerator : IDisposable /// Creates an IGeometrySurface having the given size, geometry, fill color and /// background brush. /// - /// Size of the IGeometrySurface - /// Geometry to be rendered on the IGeometrySurface - /// Fill color of the geometry - /// The brush to fill the IGeometrySurface background which is - /// not covered by the geometry + /// Size of the IGeometrySurface. + /// Geometry to be rendered on the IGeometrySurface. + /// Fill color of the geometry. + /// The brush to fill the IGeometrySurface background which is not covered by the geometry. /// IGeometrySurface IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, Color fillColor, ICanvasBrush backgroundBrush); @@ -229,12 +221,11 @@ public interface ICompositionGenerator : IDisposable /// Creates an IGeometrySurface having the given size, geometry, stroke, fill color and /// background brush. /// - /// Size of the IGeometrySurface - /// Geometry to be rendered on the IGeometrySurface - /// ICanvasStroke defining the outline for the geometry - /// Fill color of the geometry - /// The brush to fill the IGeometrySurface background which is - /// not covered by the geometry + /// Size of the IGeometrySurface. + /// Geometry to be rendered on the IGeometrySurface. + /// ICanvasStroke defining the outline for the geometry. + /// Fill color of the geometry. + /// The brush to fill the IGeometrySurface background which is not covered by the geometry. /// IGeometrySurface IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasStroke stroke, Color fillColor, ICanvasBrush backgroundBrush); @@ -243,7 +234,7 @@ public interface ICompositionGenerator : IDisposable /// and the options) is loaded. /// /// Uri of the image to be loaded onto the IImageSurface. - /// New size of the IImageSurface + /// New size of the IImageSurface. /// The image's resize and alignment options in the allocated space. /// Task<IImageSurface> Task CreateImageSurfaceAsync(Uri uri, Size size, ImageSurfaceOptions options); @@ -252,7 +243,7 @@ public interface ICompositionGenerator : IDisposable /// Creates an IImageSurface having the given size onto which the given image is loaded. /// /// Image that will be loaded onto the IImageSurface. - /// Size of the IImageSurface + /// Size of the IImageSurface. /// The image's resize and alignment options in the allocated space. /// IImageSurface IImageSurface CreateImageSurface(CanvasBitmap bitmap, Size size, ImageSurfaceOptions options); @@ -260,14 +251,14 @@ public interface ICompositionGenerator : IDisposable /// /// Creates a copy of the given IImageSurface /// - /// IImageSurface to copy + /// IImageSurface to copy. /// IImageSurface IImageSurface CreateImageSurface(IImageSurface imageSurface); /// /// Creates a copy of the given IImageMaskSurface /// - /// IImageMaskSurface to copy + /// IImageMaskSurface to copy. /// IImageMaskSurface IImageMaskSurface CreateImageMaskSurface(IImageMaskSurface imageMaskSurface); @@ -276,9 +267,8 @@ public interface ICompositionGenerator : IDisposable /// and the options) is loaded. /// /// The CanvasBitmap whose alpha values will be used to create the Mask. - /// Size of the IImageSurface - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where - /// the mask, created from the given image's alpha values, should be rendered. + /// Size of the IImageSurface. + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the given image's alpha values, should be rendered. /// Radius of the Gaussian blur applied to the the mask. /// IImageMaskSurface IImageMaskSurface CreateImageMaskSurface(CanvasBitmap surfaceBitmap, Size size, Thickness padding, float blurRadius); @@ -288,9 +278,8 @@ public interface ICompositionGenerator : IDisposable /// and the options) is loaded. /// /// The CanvasBitmap whose alpha values will be used to create the Mask. - /// Size of the IImageSurface - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where - /// the mask, created from the given image's alpha values, should be rendered. + /// Size of the IImageSurface. + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the given image's alpha values, should be rendered. /// The image's resize, alignment options and blur radius in the allocated space. /// IImageMaskSurface IImageMaskSurface CreateImageMaskSurface(CanvasBitmap surfaceBitmap, Size size, Thickness padding, ImageSurfaceOptions options); @@ -300,9 +289,8 @@ public interface ICompositionGenerator : IDisposable /// and the options) is loaded. /// /// The IImageSurface whose image's alpha values will be used to create the Mask. - /// Size of the IImageMaskSurface - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where - /// the mask, created from the given image's alpha values, should be rendered. + /// Size of the IImageMaskSurface. + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the given image's alpha values, should be rendered. /// The image's resize, alignment options and blur radius in the allocated space. /// IImageMaskSurface IImageMaskSurface CreateImageMaskSurface(IImageSurface imageSurface, Size size, Thickness padding, ImageSurfaceOptions options); @@ -312,9 +300,8 @@ public interface ICompositionGenerator : IDisposable /// and the options) is loaded. /// /// Uri of the image whose alpha values will be used to create the Mask. - /// Size of the IImageMaskSurface - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where - /// the mask, created from the given image's alpha values, should be rendered. + /// Size of the IImageMaskSurface. + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the given image's alpha values, should be rendered. /// The image's resize, alignment options and blur radius in the allocated space. /// Task<IImageMaskSurface> Task CreateImageMaskSurfaceAsync(Uri uri, Size size, Thickness padding, ImageSurfaceOptions options); @@ -322,11 +309,10 @@ public interface ICompositionGenerator : IDisposable /// /// Creates a reflection of the given Visual /// - /// Visual whose reflection has to be created - /// Distance of the reflection from the visual + /// Visual whose reflection has to be created. + /// Distance of the reflection from the visual. /// Normalized Length of the reflected visual that will be visible. - /// - Location of the reflection with respect - /// to the Visual - Bottom, Top, Left or Right + /// - Location of the reflection with respect to the Visual - Bottom, Top, Left or Right. void CreateReflection(ContainerVisual visual, float reflectionDistance = 0f, float reflectionLength = 0.7f, ReflectionLocation location = ReflectionLocation.Bottom); } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/ICompositionGeneratorInternal.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/ICompositionGeneratorInternal.cs index cdb5c6e9777..6f03aa3adc6 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/ICompositionGeneratorInternal.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/ICompositionGeneratorInternal.cs @@ -22,63 +22,57 @@ internal interface ICompositionGeneratorInternal : ICompositionGenerator /// /// Creates a CompositionDrawingSurface for the given size. /// - /// The object to lock to prevent multiple threads - /// from accessing the surface at the same time. - /// Size of the Mask Surface + /// The object to lock to prevent multiple threads from accessing the surface at the same time. + /// Size of the Mask Surface. /// CompositionDrawingSurface CompositionDrawingSurface CreateDrawingSurface(object surfaceLock, Size size); /// /// Resizes the GeometryMaskSurface to the given size. /// - /// The object to lock to prevent multiple threads - /// from accessing the surface at the same time. - /// CompositionDrawingSurface - /// New size of the Mask Surface + /// The object to lock to prevent multiple threads from accessing the surface at the same time. + /// CompositionDrawingSurface. + /// New size of the Mask Surface. void ResizeDrawingSurface(object surfaceLock, CompositionDrawingSurface surface, Size size); /// /// Redraws the GeometryMaskSurface with the given size and geometry. /// - /// The object to lock to prevent multiple threads - /// from accessing the surface at the same time. - /// CompositionDrawingSurface - /// Size of the GeometryMaskSurface - /// Geometry of the GeometryMaskSurface - /// The offset from the top left corner of the ICompositionSurface where - /// the Geometry is rendered. + /// The object to lock to prevent multiple threads from accessing the surface at the same time. + /// CompositionDrawingSurface. + /// Size of the GeometryMaskSurface. + /// Geometry of the GeometryMaskSurface. + /// The offset from the top left corner of the ICompositionSurface where the Geometry is rendered. void RedrawGeometryMaskSurface(object surfaceLock, CompositionDrawingSurface surface, Size size, CanvasGeometry geometry, Vector2 offset); /// /// Redraws the GaussianMaskSurface with the given size and geometry. /// - /// The object to lock to prevent multiple threads - /// from accessing the surface at the same time. - /// CompositionDrawingSurface - /// Size of the GeometryMaskSurface - /// Geometry of the GeometryMaskSurface + /// The object to lock to prevent multiple threads from accessing the surface at the same time. + /// CompositionDrawingSurface. + /// Size of the GeometryMaskSurface. + /// Geometry of the GeometryMaskSurface. /// The offset from the top left corner of the ICompositionSurface where the Geometry is rendered. - /// Radius of Gaussian Blur to be applied on the GaussianMaskSurface + /// Radius of Gaussian Blur to be applied on the GaussianMaskSurface. void RedrawGaussianMaskSurface(object surfaceLock, CompositionDrawingSurface surface, Size size, CanvasGeometry geometry, Vector2 offset, float blurRadius); /// /// Redraws the GeometrySurface with the given size, geometry, foreground brush and background brush. /// - /// The object to lock to prevent multiple threads - /// from accessing the surface at the same time. - /// CompositionDrawingSurface - /// Size of the GeometrySurface - /// Geometry of the GeometrySurface - /// ICanvasStroke defining the outline for the geometry - /// The brush with which the geometry has to be filled - /// The brush with which the GeometrySurface background has to be filled + /// The object to lock to prevent multiple threads from accessing the surface at the same time. + /// CompositionDrawingSurface. + /// Size of the GeometrySurface. + /// Geometry of the GeometrySurface. + /// ICanvasStroke defining the outline for the geometry. + /// The brush with which the geometry has to be filled. + /// The brush with which the GeometrySurface background has to be filled. void RedrawGeometrySurface(object surfaceLock, CompositionDrawingSurface surface, Size size, CanvasGeometry geometry, ICanvasStroke stroke, ICanvasBrush fillBrush, ICanvasBrush backgroundBrush); /// /// Resizes the ImageSurface to the given size and redraws the ImageSurface by rendering the canvasBitmap onto the surface. /// /// The object to lock to prevent multiple threads from accessing the surface at the same time. - /// CompositionDrawingSurface + /// CompositionDrawingSurface. /// Describes the image's resize and alignment options in the allocated space. /// The CanvasBitmap on which the image is loaded. void RedrawImageSurface(object surfaceLock, CompositionDrawingSurface surface, ImageSurfaceOptions options, CanvasBitmap canvasBitmap); @@ -86,9 +80,8 @@ internal interface ICompositionGeneratorInternal : ICompositionGenerator /// /// Resizes the ImageSurface with the given size and redraws the ImageSurface by loading image from the new Uri. /// - /// The object to lock to prevent multiple threads - /// from accessing the surface at the same time. - /// CompositionDrawingSurface + /// The object to lock to prevent multiple threads from accessing the surface at the same time. + /// CompositionDrawingSurface. /// Uri of the image to be loaded onto the IImageSurface. /// Describes the image's resize and alignment options in the allocated space. /// The CanvasBitmap on which the image is loaded. @@ -100,9 +93,8 @@ internal interface ICompositionGeneratorInternal : ICompositionGenerator /// using the image's alpha values onto the surface. /// /// The object to lock to prevent multiple threads from accessing the surface at the same time. - /// CompositionDrawingSurface - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where - /// the mask, created from the loaded image's alpha values, should be rendered. + /// CompositionDrawingSurface. + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. /// Describes the image's resize and alignment options and blur radius in the allocated space. /// The image whose alpha values is used to create the IImageMaskSurface. void RedrawImageMaskSurface(object surfaceLock, CompositionDrawingSurface surface, Thickness padding, ImageSurfaceOptions options, CanvasBitmap surfaceBitmap); @@ -111,12 +103,10 @@ internal interface ICompositionGeneratorInternal : ICompositionGenerator /// Resizes the ImageMaskSurface to the given size and redraws the ImageMaskSurface by loading the image from the new Uri and /// rendering the mask using the image's alpha values onto the surface. /// - /// The object to lock to prevent multiple threads - /// from accessing the surface at the same time. - /// CompositionDrawingSurface + /// The object to lock to prevent multiple threads from accessing the surface at the same time. + /// CompositionDrawingSurface. /// Uri of the image to be loaded onto the IImageMaskSurface. - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where - /// the mask, created from the loaded image's alpha values, should be rendered. + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. /// Describes the image's resize and alignment options and blur radius in the allocated space. /// The CanvasBitmap on which the image is loaded. /// The CanvasBitmap whose alpha values is used to create the IImageMaskSurface. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IGeometryMaskSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IGeometryMaskSurface.cs index 5a59892e4a6..623b4891b3e 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IGeometryMaskSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IGeometryMaskSurface.cs @@ -26,28 +26,28 @@ public interface IGeometryMaskSurface : IRenderSurface /// /// Redraws the GeometryMaskSurface with the new geometry /// - /// New CanvasGeometry to be applied to the IGeometryMaskSurface + /// New CanvasGeometry to be applied to the IGeometryMaskSurface. void Redraw(CanvasGeometry geometry); /// /// Resizes the GeometryMaskSurface with the given size and redraws the IGeometryMaskSurface with the new geometry and fills it with White color. /// - /// New size of the mask - /// New CanvasGeometry to be applied to the IGeometryMaskSurface + /// New size of the mask. + /// New CanvasGeometry to be applied to the IGeometryMaskSurface. void Redraw(Size size, CanvasGeometry geometry); /// /// Redraws the IGeometryMaskSurface with the new geometry. /// - /// New CanvasGeometry to be applied to the IGeometryMaskSurface + /// New CanvasGeometry to be applied to the IGeometryMaskSurface. /// The offset from the top left corner of the ICompositionSurface where the Geometry is rendered. void Redraw(CanvasGeometry geometry, Vector2 offset); /// /// Resizes the IGeometryMaskSurface with the given size and redraws the IGeometryMaskSurface with the new geometry and fills it with White color. /// - /// New size of the mask - /// New CanvasGeometry to be applied to the IGeometryMaskSurface + /// New size of the mask. + /// New CanvasGeometry to be applied to the IGeometryMaskSurface. /// The offset from the top left corner of the ICompositionSurface where the Geometry is rendered. void Redraw(Size size, CanvasGeometry geometry, Vector2 offset); } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IGeometrySurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IGeometrySurface.cs index 491fc332830..7ee16218817 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IGeometrySurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IGeometrySurface.cs @@ -37,219 +37,219 @@ public interface IGeometrySurface : IRenderSurface /// /// Redraws the IGeometrySurface with the new geometry /// - /// New CanvasGeometry to be applied to the IGeometrySurface + /// New CanvasGeometry to be applied to the IGeometrySurface. void Redraw(CanvasGeometry geometry); /// /// Redraws the IGeometrySurface by outlining the existing geometry with the given ICanvasStroke. /// - /// ICanvasStroke defining the outline for the geometry + /// ICanvasStroke defining the outline for the geometry. void Redraw(ICanvasStroke stroke); /// /// Redraws the IGeometrySurface by filling the existing geometry with the fill color. /// - /// Color with which the geometry is to be filled + /// Color with which the geometry is to be filled. void Redraw(Color fillColor); /// /// Redraws the IGeometrySurface by filling the existing geometry with the given fill color and outlining it with the given ICanvasStroke. /// - /// ICanvasStroke defining the outline for the geometry - /// Color with which the geometry is to be filled + /// ICanvasStroke defining the outline for the geometry. + /// Color with which the geometry is to be filled. void Redraw(ICanvasStroke stroke, Color fillColor); /// /// Redraws the IGeometrySurface by filling the existing geometry with the fill color and the background with the background color. /// - /// Color with which the geometry is to be filled - /// Color with which the IGeometrySurface background is to be filled + /// Color with which the geometry is to be filled. + /// Color with which the IGeometrySurface background is to be filled. void Redraw(Color fillColor, Color backgroundColor); /// /// Redraws the IGeometrySurface by outlining the existing geometry with the given ICanvasStroke, filling it with the fill color and the background with the background color. /// - /// ICanvasStroke defining the outline for the geometry - /// Color with which the geometry is to be filled - /// Color with which the IGeometrySurface background is to be filled + /// ICanvasStroke defining the outline for the geometry. + /// Color with which the geometry is to be filled. + /// Color with which the IGeometrySurface background is to be filled. void Redraw(ICanvasStroke stroke, Color fillColor, Color backgroundColor); /// /// Redraws the IGeometrySurface by filling the existing geometry with the fill brush. /// - /// Brush with which the geometry is to be filled + /// Brush with which the geometry is to be filled. void Redraw(ICanvasBrush fillBrush); /// /// Redraws the IGeometrySurface by outlining the existing geometry with the given ICanvasStroke, filling it with the fill brush. /// - /// ICanvasStroke defining the outline for the geometry - /// Brush with which the geometry is to be filled + /// ICanvasStroke defining the outline for the geometry. + /// Brush with which the geometry is to be filled. void Redraw(ICanvasStroke stroke, ICanvasBrush fillBrush); /// /// Redraws the IGeometrySurface by filling the existing geometry with the fill brush and the background with the background brush. /// - /// Brush with which the geometry is to be filled - /// Brush with which the IGeometrySurface background is to be filled + /// Brush with which the geometry is to be filled. + /// Brush with which the IGeometrySurface background is to be filled. void Redraw(ICanvasBrush fillBrush, ICanvasBrush backgroundBrush); /// /// Redraws the IGeometrySurface by outlining the existing geometry with the given ICanvasStroke, filling it with the fill brush and the background with the background brush. /// - /// ICanvasStroke defining the outline for the geometry - /// Brush with which the geometry is to be filled - /// Brush with which the IGeometrySurface background is to be filled + /// ICanvasStroke defining the outline for the geometry. + /// Brush with which the geometry is to be filled. + /// Brush with which the IGeometrySurface background is to be filled. void Redraw(ICanvasStroke stroke, ICanvasBrush fillBrush, ICanvasBrush backgroundBrush); /// /// Redraws the IGeometrySurface by filling the existing geometry with the fill color and the background with the background brush. /// - /// Color with which the geometry is to be filled - /// Brush with which the IGeometrySurface background is to be filled + /// Color with which the geometry is to be filled. + /// Brush with which the IGeometrySurface background is to be filled. void Redraw(Color fillColor, ICanvasBrush backgroundBrush); /// /// Redraws the IGeometrySurface by outlining the existing geometry with the given ICanvasStroke, filling it with the fill color and the background with the background brush. /// - /// ICanvasStroke defining the outline for the geometry - /// Color with which the geometry is to be filled - /// Brush with which the IGeometrySurface background is to be filled + /// ICanvasStroke defining the outline for the geometry. + /// Color with which the geometry is to be filled. + /// Brush with which the IGeometrySurface background is to be filled. void Redraw(ICanvasStroke stroke, Color fillColor, ICanvasBrush backgroundBrush); /// /// Redraws the IGeometrySurface by filling the existing geometry with the fill brush and the background with the background color. /// - /// Brush with which the geometry is to be filled - /// Color with which the IGeometrySurface background is to be filled + /// Brush with which the geometry is to be filled. + /// Color with which the IGeometrySurface background is to be filled. void Redraw(ICanvasBrush fillBrush, Color backgroundColor); /// /// Redraws the IGeometrySurface by outlining the existing geometry with the given ICanvasStroke, filling it with the fill brush and the background with the background color. /// - /// ICanvasStroke defining the outline for the geometry - /// Brush with which the geometry is to be filled - /// Color with which the IGeometrySurface background is to be filled + /// ICanvasStroke defining the outline for the geometry. + /// Brush with which the geometry is to be filled. + /// Color with which the IGeometrySurface background is to be filled. void Redraw(ICanvasStroke stroke, ICanvasBrush fillBrush, Color backgroundColor); /// /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface with the new geometry. /// - /// New size of the IGeometrySurface - /// New CanvasGeometry to be applied to the IGeometrySurface + /// New size of the IGeometrySurface. + /// New CanvasGeometry to be applied to the IGeometrySurface. void Redraw(Size size, CanvasGeometry geometry); /// /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface with the new geometry and outlines it with the given ICanvasStroke. /// - /// New size of the IGeometrySurface - /// New CanvasGeometry to be applied to the IGeometrySurface - /// ICanvasStroke defining the outline for the geometry + /// New size of the IGeometrySurface. + /// New CanvasGeometry to be applied to the IGeometrySurface. + /// ICanvasStroke defining the outline for the geometry. void Redraw(Size size, CanvasGeometry geometry, ICanvasStroke stroke); /// /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface with the new geometry and fills it with the fill color. /// - /// New size of the IGeometrySurface - /// New CanvasGeometry to be applied to the IGeometrySurface - /// Fill color for the geometry + /// New size of the IGeometrySurface. + /// New CanvasGeometry to be applied to the IGeometrySurface. + /// Fill color for the geometry. void Redraw(Size size, CanvasGeometry geometry, Color fillColor); /// /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface with the new geometry, outlines it with the given ICanvasStroke and fills it with the fill color. /// - /// New size of the IGeometrySurface - /// New CanvasGeometry to be applied to the IGeometrySurface - /// ICanvasStroke defining the outline for the geometry - /// Fill color for the geometry + /// New size of the IGeometrySurface. + /// New CanvasGeometry to be applied to the IGeometrySurface. + /// ICanvasStroke defining the outline for the geometry. + /// Fill color for the geometry. void Redraw(Size size, CanvasGeometry geometry, ICanvasStroke stroke, Color fillColor); /// /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface with the new geometry and fills it with the fill color and fills the background with the background color. /// - /// New size of the IGeometrySurface - /// New CanvasGeometry to be applied to the IGeometrySurface - /// Fill color for the geometry - /// Fill color for the IGeometrySurface background + /// New size of the IGeometrySurface. + /// New CanvasGeometry to be applied to the IGeometrySurface. + /// Fill color for the geometry. + /// Fill color for the IGeometrySurface background. void Redraw(Size size, CanvasGeometry geometry, Color fillColor, Color backgroundColor); /// /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface with the new geometry, outlines it with the given ICanvasStroke and /// fills it with the fill color and fills the background with the background color. /// - /// New size of the IGeometrySurface - /// New CanvasGeometry to be applied to the IGeometrySurface - /// ICanvasStroke defining the outline for the geometry - /// Fill color for the geometry - /// Fill color for the IGeometrySurface background + /// New size of the IGeometrySurface. + /// New CanvasGeometry to be applied to the IGeometrySurface. + /// ICanvasStroke defining the outline for the geometry. + /// Fill color for the geometry. + /// Fill color for the IGeometrySurface background. void Redraw(Size size, CanvasGeometry geometry, ICanvasStroke stroke, Color fillColor, Color backgroundColor); /// /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface with the new geometry and fills it with the fill brush. /// - /// New size of the IGeometrySurface - /// New CanvasGeometry to be applied to the IGeometrySurface - /// Brush to fill the geometry + /// New size of the IGeometrySurface. + /// New CanvasGeometry to be applied to the IGeometrySurface. + /// Brush to fill the geometry. void Redraw(Size size, CanvasGeometry geometry, ICanvasBrush fillBrush); /// /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface with the new geometry and fills it with the fill brush and fills the background with the background brush. /// - /// New size of the IGeometrySurface - /// New CanvasGeometry to be applied to the IGeometrySurface - /// Brush to fill the geometry - /// Brush to fill the IGeometrySurface background + /// New size of the IGeometrySurface. + /// New CanvasGeometry to be applied to the IGeometrySurface. + /// Brush to fill the geometry. + /// Brush to fill the IGeometrySurface background. void Redraw(Size size, CanvasGeometry geometry, ICanvasBrush fillBrush, ICanvasBrush backgroundBrush); /// /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface with the new geometry, outlines it with the given ICanvasStroke and /// fills it with the fill brush and fills the background with the background brush. /// - /// New size of the IGeometrySurface - /// New CanvasGeometry to be applied to the IGeometrySurface - /// ICanvasStroke defining the outline for the geometry - /// Brush to fill the geometry - /// Brush to fill the IGeometrySurface background + /// New size of the IGeometrySurface. + /// New CanvasGeometry to be applied to the IGeometrySurface. + /// ICanvasStroke defining the outline for the geometry. + /// Brush to fill the geometry. + /// Brush to fill the IGeometrySurface background. void Redraw(Size size, CanvasGeometry geometry, ICanvasStroke stroke, ICanvasBrush fillBrush, ICanvasBrush backgroundBrush); /// /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface with the new geometry and fills it with the fill brush and the background with the background color. /// - /// New size of the IGeometrySurface - /// New CanvasGeometry to be applied to the IGeometrySurface - /// Brush to fill the geometry - /// Fill color for the IGeometrySurface background + /// New size of the IGeometrySurface. + /// New CanvasGeometry to be applied to the IGeometrySurface. + /// Brush to fill the geometry. + /// Fill color for the IGeometrySurface background. void Redraw(Size size, CanvasGeometry geometry, ICanvasBrush fillBrush, Color backgroundColor); /// /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface with the new geometry, outlines it with the given ICanvasStroke and /// fills it with the fill brush and the background with the background color. /// - /// New size of the IGeometrySurface - /// New CanvasGeometry to be applied to the IGeometrySurface - /// ICanvasStroke defining the outline for the geometry - /// Brush to fill the geometry - /// Fill color for the IGeometrySurface background + /// New size of the IGeometrySurface. + /// New CanvasGeometry to be applied to the IGeometrySurface. + /// ICanvasStroke defining the outline for the geometry. + /// Brush to fill the geometry. + /// Fill color for the IGeometrySurface background. void Redraw(Size size, CanvasGeometry geometry, ICanvasStroke stroke, ICanvasBrush fillBrush, Color backgroundColor); /// /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface with the new geometry and fills it with the fill color and the background with the background brush. /// - /// New size of the IGeometrySurface - /// New CanvasGeometry to be applied to the IGeometrySurface - /// Fill color for the geometry - /// Brush to fill the IGeometrySurface background + /// New size of the IGeometrySurface. + /// New CanvasGeometry to be applied to the IGeometrySurface. + /// Fill color for the geometry. + /// Brush to fill the IGeometrySurface background. void Redraw(Size size, CanvasGeometry geometry, Color fillColor, ICanvasBrush backgroundBrush); /// /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface with the new geometry, outlines it with the given ICanvasStroke and /// fills it with the fill color and the background with the background brush. /// - /// New size of the IGeometrySurface - /// New CanvasGeometry to be applied to the IGeometrySurface - /// ICanvasStroke defining the outline for the geometry - /// Fill color for the geometry - /// Brush to fill the IGeometrySurface background + /// New size of the IGeometrySurface. + /// New CanvasGeometry to be applied to the IGeometrySurface. + /// ICanvasStroke defining the outline for the geometry. + /// Fill color for the geometry. + /// Brush to fill the IGeometrySurface background. void Redraw(Size size, CanvasGeometry geometry, ICanvasStroke stroke, Color fillColor, ICanvasBrush backgroundBrush); } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IImageMaskSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IImageMaskSurface.cs index 4085e242c5c..c460ec324c0 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IImageMaskSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IImageMaskSurface.cs @@ -24,18 +24,14 @@ public interface IImageMaskSurface : IImageSurface /// Redraws the IImageMaskSurface using the given CanvasBitmap's alpha values with the given padding. /// /// ImageSurface whose image's alpha values are to be used to create the mask. - /// - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. - /// + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. void Redraw(IImageSurface imageSurface, Thickness padding); /// /// Redraws the IImageMaskSurface using the given CanvasBitmap's alpha values with the given padding using the given options. /// /// ImageSurface whose image's alpha values are to be used to create the mask. - /// - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. - /// + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. /// Describes the image's resize, alignment and blur radius options in the allocated space. void Redraw(IImageSurface imageSurface, Thickness padding, ImageSurfaceOptions options); @@ -44,9 +40,7 @@ public interface IImageMaskSurface : IImageSurface /// /// ImageSurface whose image's alpha values are to be used to create the mask. /// New size of the IImageMaskSurface. - /// - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. - /// + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. /// Describes the image's resize, alignment and blur radius options in the allocated space. void Redraw(IImageSurface imageSurface, Size size, Thickness padding, ImageSurfaceOptions options); @@ -54,18 +48,14 @@ public interface IImageMaskSurface : IImageSurface /// Redraws the IImageMaskSurface using the given CanvasBitmap's alpha values with the given padding. /// /// Image whose alpha values are to be used to create the mask. - /// - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. - /// + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. void Redraw(CanvasBitmap surfaceBitmap, Thickness padding); /// /// Redraws the IImageMaskSurface using the given CanvasBitmap's alpha values with the given padding using the given options. /// /// Image whose alpha values are to be used to create the mask. - /// - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. - /// + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. /// Describes the image's resize, alignment and blur radius options in the allocated space. void Redraw(CanvasBitmap surfaceBitmap, Thickness padding, ImageSurfaceOptions options); @@ -79,9 +69,7 @@ public interface IImageMaskSurface : IImageSurface /// Redraws the IImageMaskSurface using the alpha values of the image in the given IImageMaskSurface with the given padding and options. /// /// IImageMaskSurface whose image's alpha values are to be used to create the mask. - /// - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. - /// + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. void Redraw(IImageMaskSurface imageMaskSurface, Thickness padding); /// @@ -95,9 +83,7 @@ public interface IImageMaskSurface : IImageSurface /// Redraws the IImageMaskSurface using the alpha values of the image in the given IImageMaskSurface using the given padding and options. /// /// IImageMaskSurface whose image's alpha values are to be used to create the mask. - /// - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. - /// + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. /// Describes the image's resize, alignment and blur radius options in the allocated space. void Redraw(IImageMaskSurface imageMaskSurface, Thickness padding, ImageSurfaceOptions options); @@ -106,18 +92,14 @@ public interface IImageMaskSurface : IImageSurface /// /// IImageMaskSurface whose image's alpha values are to be used to create the mask. /// New size of the IImageMaskSurface. - /// - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. - /// + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. /// Describes the image's resize, alignment and blur radius options in the allocated space. void Redraw(IImageMaskSurface imageMaskSurface, Size size, Thickness padding, ImageSurfaceOptions options); /// /// Resizes and redraws the IImageMaskSurface using the given CanvasBitmap's alpha values with the given padding using the given options. /// - /// - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. - /// + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. /// Describes the image's resize, alignment and blur radius options in the allocated space. void Redraw(Thickness padding, ImageSurfaceOptions options); @@ -134,9 +116,7 @@ public interface IImageMaskSurface : IImageSurface /// /// Image whose alpha values are to be used to create the mask. /// New size of the IImageMaskSurface. - /// - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. - /// + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. /// Describes the image's resize, alignment and blur radius options in the allocated space. void Redraw(CanvasBitmap surfaceBitmap, Size size, Thickness padding, ImageSurfaceOptions options); @@ -144,9 +124,7 @@ public interface IImageMaskSurface : IImageSurface /// Redraws the IImageMaskSurface by loading image from the new Uri and image options /// /// Uri of the image to be loaded on to the image surface. - /// - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. - /// + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. /// Describes the image's resize, alignment and blur radius options in the allocated space. /// Task Task RedrawAsync(Uri uri, Thickness padding, ImageSurfaceOptions options); @@ -156,9 +134,7 @@ public interface IImageMaskSurface : IImageSurface /// /// Uri of the image to be loaded onto the IImageMaskSurface. /// New size of the IImageMaskSurface - /// - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. - /// + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. /// Describes the image's resize, alignment and blur radius options in the allocated space. /// Task Task RedrawAsync(Uri uri, Size size, Thickness padding, ImageSurfaceOptions options); @@ -167,9 +143,7 @@ public interface IImageMaskSurface : IImageSurface /// Resizes the IImageMaskSurface to the new size and redraws it with the given padding using the given options. /// /// New size of the IImageMaskSurface - /// - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. - /// + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. /// The image's resize, alignment and blur radius options in the allocated space. void Resize(Size size, Thickness padding, ImageSurfaceOptions options); } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IImageSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IImageSurface.cs index a3e94040785..92387c15677 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IImageSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IImageSurface.cs @@ -125,6 +125,13 @@ public interface IImageSurface : IRenderSurface /// Describes the image's resize, alignment options in the allocated space. void Redraw(CanvasBitmap surfaceBitmap, Size size, ImageSurfaceOptions options); + /// + /// Redraws the IImageSurface or IImageMaskSurface by loading image from the new Uri. + /// + /// Uri of the image to be loaded on to the surface. + /// Task + Task RedrawAsync(Uri uri); + /// /// Redraws the IImageSurface or IImageMaskSurface by loading image from the new Uri and applying the image options. /// diff --git a/Microsoft.Toolkit.Uwp.UI/Converters/Vector2Converter.cs b/Microsoft.Toolkit.Uwp.UI/Converters/Vector2Converter.cs deleted file mode 100644 index 9b79f49f196..00000000000 --- a/Microsoft.Toolkit.Uwp.UI/Converters/Vector2Converter.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System; -using System.ComponentModel; -using System.Globalization; -using System.Linq; -using System.Numerics; - -namespace Microsoft.Toolkit.Uwp.UI.Converters -{ - /// - /// Converter for converting string to - /// - public class Vector2Converter : TypeConverter - { - private const int MaxCount = 2; - - /// - public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) - { - return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType); - } - - /// - public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) - { - return destinationType == typeof(string) || base.CanConvertTo(context, destinationType); - } - - /// - public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) - { - if (value == null) - { - throw GetConvertFromException(value); - } - - if (value is string valStr) - { - var tokens = valStr.Split(',', StringSplitOptions.RemoveEmptyEntries); - if (tokens?.Count() == MaxCount) - { - var result = new float[MaxCount]; - bool isValid = true; - for (int i = 0; i < MaxCount; i++) - { - if (!float.TryParse(tokens[i], out result[i])) - { - isValid = false; - break; - } - } - - if (isValid) - { - return new Vector2(result[0], result[1]); - } - } - } - - return base.ConvertFrom(context, culture, value); - } - - /// - public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) - { - if (destinationType != null && value is Vector2 instance) - { - if (destinationType == typeof(string)) - { - return $"{instance.X}, {instance.Y}"; - } - } - - // Pass unhandled cases to base class (which will throw exceptions for null value or destinationType.) - return base.ConvertTo(context, culture, value, destinationType); - } - } -} diff --git a/Microsoft.Toolkit.Uwp.UI/Converters/Vector4Converter.cs b/Microsoft.Toolkit.Uwp.UI/Converters/Vector4Converter.cs deleted file mode 100644 index 48843a693b6..00000000000 --- a/Microsoft.Toolkit.Uwp.UI/Converters/Vector4Converter.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System; -using System.ComponentModel; -using System.Globalization; -using System.Linq; -using System.Numerics; - -namespace Microsoft.Toolkit.Uwp.UI.Converters -{ - /// - /// Converter for converting string to - /// - public class Vector4Converter : TypeConverter - { - private const int MaxCount = 4; - - /// - public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) - { - return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType); - } - - /// - public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) - { - return destinationType == typeof(string) || base.CanConvertTo(context, destinationType); - } - - /// - public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) - { - if (value == null) - { - throw GetConvertFromException(value); - } - - if (value is string valStr) - { - var tokens = valStr.Split(',', StringSplitOptions.RemoveEmptyEntries); - if (tokens?.Count() == MaxCount) - { - var result = new float[MaxCount]; - bool isValid = true; - for (int i = 0; i < MaxCount; i++) - { - if (!float.TryParse(tokens[i], out result[i])) - { - isValid = false; - break; - } - } - - if (isValid) - { - return new Vector4(result[0], result[1], result[2], result[3]); - } - } - } - - return base.ConvertFrom(context, culture, value); - } - - /// - public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) - { - if (destinationType != null && value is Vector4 instance) - { - if (destinationType == typeof(string)) - { - return $"{instance.X}, {instance.Y}, {instance.Z}, {instance.W}"; - } - } - - // Pass unhandled cases to base class (which will throw exceptions for null value or destinationType.) - return base.ConvertTo(context, culture, value, destinationType); - } - } -} From 2c46da62790d9566da84ff3b40ea55131a73276c Mon Sep 17 00:00:00 2001 From: Ratish Philip Date: Sat, 17 Jul 2021 09:31:36 -0700 Subject: [PATCH 15/21] cleanup of ImageMaskSurfaceBrush sample. --- .../ImageMaskSurfaceBrushPage.xaml.cs | 31 +++++-------------- 1 file changed, 7 insertions(+), 24 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageMaskSurfaceBrush/ImageMaskSurfaceBrushPage.xaml.cs b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageMaskSurfaceBrush/ImageMaskSurfaceBrushPage.xaml.cs index 6c22fa25b12..eea44086d73 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageMaskSurfaceBrush/ImageMaskSurfaceBrushPage.xaml.cs +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageMaskSurfaceBrush/ImageMaskSurfaceBrushPage.xaml.cs @@ -40,6 +40,8 @@ public ImageMaskSurfaceBrushPage() }; MaskImages.ItemsSource = _maskImages.Keys; + + // Select the first Image as mask MaskImages.SelectedIndex = 0; _targetImages = new Dictionary @@ -51,6 +53,8 @@ public ImageMaskSurfaceBrushPage() }; TargetImages.ItemsSource = _targetImages.Keys; + + // Select the first Image as target image. TargetImages.SelectedIndex = 0; } @@ -62,14 +66,7 @@ private void OnMaskImageChanged(object sender, SelectionChangedEventArgs e) return; } - try - { - MaskImageBrush.Source = _maskImages[image]; - } - catch (Exception ex) - { - var msg = ex.Message; - } + MaskImageBrush.Source = _maskImages[image]; } private void OnTargetImageChanged(object sender, SelectionChangedEventArgs e) @@ -80,26 +77,12 @@ private void OnTargetImageChanged(object sender, SelectionChangedEventArgs e) return; } - try - { - TargetImageBrush.Source = _targetImages[image]; - } - catch (Exception ex) - { - var msg = ex.Message; - } + TargetImageBrush.Source = _targetImages[image]; } private void OnBlurRadiusChanged(object sender, RangeBaseValueChangedEventArgs e) { - try - { - MaskImageOptions.BlurRadius = e.NewValue; - } - catch (Exception ex) - { - var msg = ex.Message; - } + MaskImageOptions.BlurRadius = e.NewValue; } } } From 03a127097d32641890f5a06522d95f461f3ffa1d Mon Sep 17 00:00:00 2001 From: Ratish Philip Date: Sun, 18 Jul 2021 09:18:42 -0700 Subject: [PATCH 16/21] Updated method headers with proper references. --- .../ImageMaskSurfaceBrushPage.xaml.cs | 11 - .../Geometry/CanvasCoreGeometry.cs | 2 +- .../Geometry/CanvasPathGeometry.cs | 66 ++--- .../Geometry/ICanvasPathGeometry.cs | 2 +- .../Surface/CompositionGenerator.cs | 27 +- .../Surface/CompositorExtensions.cs | 70 ++--- .../Surface/GaussianMaskSurface.cs | 18 +- .../Surface/GeometryMaskSurface.cs | 12 +- .../Surface/GeometrySurface.cs | 20 +- .../Surface/ImageMaskSurface.cs | 28 +- .../Surface/ImageSurface.cs | 23 +- .../Interfaces/ICompositionGenerator.cs | 252 +++++++++--------- .../ICompositionGeneratorInternal.cs | 84 +++--- .../Interfaces/IGaussianMaskSurface.cs | 25 +- .../Interfaces/IGeometryMaskSurface.cs | 27 +- .../Surface/Interfaces/IGeometrySurface.cs | 186 ++++++------- .../Surface/Interfaces/IImageMaskSurface.cs | 95 +++---- .../Surface/Interfaces/IImageSurface.cs | 54 ++-- .../Surface/Interfaces/IRenderSurface.cs | 4 +- 19 files changed, 495 insertions(+), 511 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageMaskSurfaceBrush/ImageMaskSurfaceBrushPage.xaml.cs b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageMaskSurfaceBrush/ImageMaskSurfaceBrushPage.xaml.cs index eea44086d73..64bd9606512 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageMaskSurfaceBrush/ImageMaskSurfaceBrushPage.xaml.cs +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ImageMaskSurfaceBrush/ImageMaskSurfaceBrushPage.xaml.cs @@ -2,20 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Runtime.InteropServices.WindowsRuntime; -using Windows.Foundation; -using Windows.Foundation.Collections; -using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls.Primitives; -using Windows.UI.Xaml.Data; -using Windows.UI.Xaml.Input; -using Windows.UI.Xaml.Media; -using Windows.UI.Xaml.Navigation; // The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238 namespace Microsoft.Toolkit.Uwp.SampleApp.SamplePages diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCoreGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCoreGeometry.cs index a005080b60a..02c47b37f1c 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCoreGeometry.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCoreGeometry.cs @@ -10,7 +10,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Media { /// - /// Provides a base class for objects that define geometric shapes using CanvasGeometry. + /// Provides a base class for objects that define geometric shapes using . /// public abstract class CanvasCoreGeometry : DependencyObject, ICanvasPathGeometry, IDisposable { diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasPathGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasPathGeometry.cs index 318f93884dc..d011712bfa8 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasPathGeometry.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasPathGeometry.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#pragma warning disable CS0419 // Ambiguous reference in cref attribute + using System; using System.Numerics; using Microsoft.Graphics.Canvas; @@ -28,7 +30,7 @@ public class CanvasPathGeometry : CanvasCoreGeometry new PropertyMetadata(string.Empty, OnDataChanged)); /// - /// Gets or sets the path data for the associated Win2d CanvasGeometry defined in the Win2d Path Mini Language. + /// Gets or sets the path data for the associated Win2d defined in the Win2d Path Mini Language. /// public string Data { @@ -39,8 +41,8 @@ public string Data /// /// Handles changes to the Data property. /// - /// CanvasPathGeometry - /// DependencyProperty changed event arguments + /// CanvasPathGeometry. + /// DependencyProperty changed event arguments. private static void OnDataChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var pathGeometry = (CanvasPathGeometry)d; @@ -83,9 +85,9 @@ protected override void OnUpdateGeometry() } /// - /// Parses the Path data string and converts it to CanvasGeometry. + /// Parses the Path data string and converts it to . /// - /// Path data + /// Path data. /// public static CanvasGeometry CreateGeometry(string pathData) { @@ -93,10 +95,10 @@ public static CanvasGeometry CreateGeometry(string pathData) } /// - /// Parses the Path data string and converts it to CanvasGeometry. + /// Parses the Path data string and converts it to . /// - /// - /// Path data + /// . + /// Path data. /// public static CanvasGeometry CreateGeometry(ICanvasResourceCreator resourceCreator, string pathData) { @@ -110,13 +112,13 @@ public static CanvasGeometry CreateGeometry(ICanvasResourceCreator resourceCreat /// /// Creates a Squircle geometry with the specified extents. /// - /// Resource creator - /// X offset of the TopLeft corner of the Squircle - /// Y offset of the TopLeft corner of the Squircle - /// Width of the Squircle - /// Height of the Squircle - /// Corner Radius on the x-axis - /// Corner Radius on the y-axis + /// Resource creator. + /// X offset of the TopLeft corner of the Squircle. + /// Y offset of the TopLeft corner of the Squircle. + /// Width of the Squircle. + /// Height of the Squircle. + /// Corner Radius on the x-axis. + /// Corner Radius on the y-axis. /// public static CanvasGeometry CreateSquircle(ICanvasResourceCreator resourceCreator, float x, float y, float width, float height, float radiusX, float radiusY) { @@ -126,10 +128,10 @@ public static CanvasGeometry CreateSquircle(ICanvasResourceCreator resourceCreat } /// - /// Parses the given Brush data string and converts it to ICanvasBrush. + /// Parses the given Brush data string and converts it to . /// - /// ICanvasResourceCreator - /// Brush data in string format + /// ICanvasResourceCreator. + /// Brush data in string format. /// public static ICanvasBrush CreateBrush(ICanvasResourceCreator resourceCreator, string brushData) { @@ -140,10 +142,10 @@ public static ICanvasBrush CreateBrush(ICanvasResourceCreator resourceCreator, s } /// - /// Parses the given Stroke data string and converts it to ICanvasStroke. + /// Parses the given Stroke data string and converts it to . /// - /// ICanvasResourceCreator - /// Stroke data in string format + /// . + /// Stroke data in string format. /// public static ICanvasStroke CreateStroke(ICanvasResourceCreator resourceCreator, string strokeData) { @@ -154,10 +156,10 @@ public static ICanvasStroke CreateStroke(ICanvasResourceCreator resourceCreator, } /// - /// Parses the give CanvasStrokeStyle data string and converts it to CanvasStrokeStyle. + /// Parses the give CanvasStrokeStyle data string and converts it to . /// - /// CanvasStrokeStyle data in string format - /// object + /// data in string format. + /// public static CanvasStrokeStyle CreateStrokeStyle(string styleData) { using (new CultureShield("en-US")) @@ -167,14 +169,14 @@ public static CanvasStrokeStyle CreateStrokeStyle(string styleData) } /// - /// Converts the color string in Hexadecimal or HDR color format to the corresponding Color object. + /// Converts the color string in Hexadecimal or HDR color format to the corresponding object. /// The hexadecimal color string should be in #RRGGBB or #AARRGGBB format. /// The '#' character is optional. /// The HDR color string should be in R G B A format. /// (R, G, B & A should have value in the range between 0 and 1, inclusive) /// - /// Color string in Hexadecimal or HDR format - /// Color + /// Color string in Hexadecimal or HDR format. + /// public static Color CreateColor(string colorString) { using (new CultureShield("en-US")) @@ -184,15 +186,15 @@ public static Color CreateColor(string colorString) } /// - /// Converts a Vector4 High Dynamic Range Color to Color object. + /// Converts a Vector4 High Dynamic Range Color to object. /// Negative components of the Vector4 will be sanitized by taking the absolute /// value of the component. The HDR Color components should have value in /// the range between 0 and 1, inclusive. If they are more than 1, they /// will be clamped at 1. /// Vector4's X, Y, Z, W components match to Color's R, G, B, A components respectively. /// - /// High Dynamic Range Color - /// Color + /// High Dynamic Range Color. + /// public static Color CreateColor(Vector4 hdrColor) { using (new CultureShield("en-US")) @@ -201,4 +203,6 @@ public static Color CreateColor(Vector4 hdrColor) } } } -} \ No newline at end of file +} + +#pragma warning restore CS0419 // Ambiguous reference in cref attribute diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/ICanvasPathGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/ICanvasPathGeometry.cs index 00674cf87b1..71cca7fe2ce 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/ICanvasPathGeometry.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/ICanvasPathGeometry.cs @@ -9,7 +9,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Media internal interface ICanvasPathGeometry { /// - /// Gets the associated CanvasGeometry. + /// Gets the associated . /// CanvasGeometry Geometry { get; } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs index 0ba53c64c3b..d3dd28442ca 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs @@ -37,7 +37,7 @@ public sealed class CompositionGenerator : ICompositionGeneratorInternal private CompositionGraphicsDevice _compositionDevice; /// - /// Gets the CompositionGenerator instance. + /// Gets the instance. /// public static ICompositionGenerator Instance => _instance.Value; @@ -69,12 +69,11 @@ private CompositionGenerator() } /// - /// Renders the CanvasBitmap on the CompositionDrawingSurface based on the given options. + /// Renders the on the based on the given options. /// - /// The object to lock to prevent multiple threads - /// from accessing the surface at the same time. - /// CompositionDrawingSurface on which the CanvasBitmap has to be rendered. - /// CanvasBitmap created by loading the image from the Uri + /// The object to lock to prevent multiple threads from accessing the surface at the same time. + /// on which the CanvasBitmap has to be rendered. + /// created by loading the image from the . /// Describes the image's resize and alignment options in the allocated space. private static void RenderBitmap( object surfaceLock, @@ -182,15 +181,13 @@ private static void RenderBitmap( } /// - /// Renders the mask using the CanvasBitmap's alpha values on the CompositionDrawingSurface based on the given options. + /// Renders the mask using the 's alpha values on the based on the given options. /// - /// CanvasDevice - /// The object to lock to prevent multiple threads - /// from accessing the surface at the same time. - /// CompositionDrawingSurface on which the CanvasBitmap has to be rendered. - /// CanvasBitmap created by loading the image from the Uri - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where - /// the mask, created from the loaded image's alpha values, should be rendered. + /// + /// The object to lock to prevent multiple threads from accessing the surface at the same time. + /// on which the CanvasBitmap has to be rendered. + /// created by loading the image from the . + /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. /// Describes the image's resize and alignment options in the allocated space. private static void RenderBitmapMask( CanvasDevice device, @@ -365,7 +362,7 @@ private void OnRenderingDeviceReplaced(CompositionGraphicsDevice sender, Renderi } /// - /// Raises the DeviceReplacedEvent + /// Raises the DeviceReplacedEvent. /// private void RaiseDeviceReplacedEvent() { diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositorExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositorExtensions.cs index 633ac1f1b4b..4a900e7d37a 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositorExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositorExtensions.cs @@ -13,51 +13,51 @@ namespace Microsoft.Toolkit.Uwp.UI.Media { /// - /// Extension methods for Windows.UI.Composition.Compositor + /// Extension methods for /// public static class CompositorExtensions { /// - /// Creates the CompositionSurfaceBrush from the specified render surface. + /// Creates the from the specified render surface. /// - /// Compositor - /// An object deriving from IGeometryMaskSurface, IGaussianMaskSurface, IGeometrySurface or IImageSurface - /// CompositionSurfaceBrush + /// + /// An object deriving from , , , or + /// public static CompositionSurfaceBrush CreateSurfaceBrush(this Compositor compositor, IRenderSurface renderSurface) { return compositor.CreateSurfaceBrush(renderSurface.Surface); } /// - /// Creates a custom shaped Effect Brush using BackdropBrush and an IGeometryMaskSurface. + /// Creates a custom shaped Effect Brush using BackdropBrush and an . /// /// Compositor - /// IGeometryMaskSurface - /// Color to blend in the BackdropBrush - /// Blur Amount of the Backdrop Brush + /// . + /// Color to blend in the BackdropBrush. + /// Blur Amount of the BackdropBrush. /// Backdrop Brush (optional). If not provided, then compositor creates it. - /// CompositionEffectBrush + /// public static CompositionEffectBrush CreateMaskedBackdropBrush(this Compositor compositor, IGeometryMaskSurface mask, Color blendColor, float blurAmount, CompositionBackdropBrush backdropBrush = null) { return CreateBackdropBrush(compositor, mask, blendColor, blurAmount, backdropBrush); } /// - /// Creates a custom shaped Effect Brush using BackdropBrush and an IGaussianMaskSurface. + /// Creates a custom shaped Effect Brush using BackdropBrush and an . /// /// Compositor - /// IGeometryMaskSurface + /// /// Color to blend in the BackdropBrush /// Blur Amount of the Backdrop Brush /// Backdrop Brush (optional). If not provided, then compositor creates it. - /// CompositionEffectBrush + /// public static CompositionEffectBrush CreateGaussianMaskedBackdropBrush(this Compositor compositor, IGaussianMaskSurface mask, Color blendColor, float blurRadius, CompositionBackdropBrush backdropBrush = null) { return CreateBackdropBrush(compositor, mask, blendColor, blurRadius, backdropBrush); } /// - /// Creates a custom shaped Effect Brush using BackdropBrush and an IGeometryMaskSurface or an IGaussianMaskSurface. + /// Creates a custom shaped Effect Brush using BackdropBrush and an or an . /// /// Compositor /// IGeometryMaskSurface or IGaussianMaskSurface @@ -119,17 +119,17 @@ internal static CompositionEffectBrush CreateBackdropBrush(Compositor compositor } /// - /// Creates a custom shaped Frosted Glass Effect Brush using BackdropBrush and a Mask + /// Creates a custom shaped Frosted Glass Effect Brush using BackdropBrush and a . /// /// Compositor - /// IGeometryMaskSurface + /// /// Color to blend in the BackdropBrush /// Blur Amount of the Backdrop Brush /// Backdrop Brush (optional). If not provided, then compositor creates it. - /// MultiplyAmount of the ArithmeticCompositeEffect - /// Source1Amount of the ArithmeticCompositeEffect - /// Source2Amount of the ArithmeticCompositeEffect - /// CompositionEffectBrush + /// MultiplyAmount of the + /// Source1Amount of the + /// Source2Amount of the + /// public static CompositionEffectBrush CreateFrostedGlassBrush( this Compositor compositor, IGeometryMaskSurface mask, @@ -191,14 +191,14 @@ public static CompositionEffectBrush CreateFrostedGlassBrush( } /// - /// Updates the CompositionSurfaceBrush's Stretch and Alignment options + /// Updates the 's Stretch and Alignment options. /// - /// CompositionSurfaceBrush - /// Stretch mode - /// Horizontal Alignment - /// Vertical Alignment - /// The animation to use to update the horizontal alignment of the surface brush - /// The animation to use to update the vertical alignment of the surface brush + /// CompositionSurfaceBrush. + /// Stretch mode. + /// Horizontal Alignment. + /// Vertical Alignment. + /// The animation to use to update the horizontal alignment of the surface brush. + /// The animation to use to update the vertical alignment of the surface brush. public static void UpdateSurfaceBrushOptions( this CompositionSurfaceBrush surfaceBrush, Stretch stretch, @@ -277,10 +277,10 @@ public static void UpdateSurfaceBrushOptions( /// }); /// /// - /// Compositor - /// Composition Batch Type - /// Action to perform within the scoped batch - /// Action to perform once the batch completes + /// Compositor. + /// Composition Batch Type. + /// Action to perform within the scoped batch. + /// Action to perform once the batch completes. public static void CreateScopedBatch(this Compositor compositor, CompositionBatchTypes batchType, Action action, Action postAction = null) { if (action == null) @@ -339,10 +339,10 @@ void BatchCompletedHandler(object s, CompositionBatchCompletedEventArgs ea) /// }); /// /// - /// Compositor - /// Composition Batch Type - /// Action to perform within the scoped batch - /// Action to perform once the batch completes + /// Compositor. + /// Composition Batch Type. + /// Action to perform within the scoped batch. + /// Action to perform once the batch completes. public static void CreateScopedBatch(this Compositor compositor, CompositionBatchTypes batchType, Action action, Action postAction = null) { if (action == null) diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/GaussianMaskSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/GaussianMaskSurface.cs index cf30207a6f1..e9ef45098aa 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/GaussianMaskSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/GaussianMaskSurface.cs @@ -11,9 +11,8 @@ namespace Microsoft.Toolkit.Uwp.UI.Media { /// - /// Class for rendering custom shaped geometries onto ICompositionSurface - /// so that they can be used as masks on Composition Visuals. These geometries - /// have a Gaussian Blur applied to them. + /// Class for rendering custom shaped geometries onto so that they can be used as masks on Composition Visuals. + /// These geometries have a Gaussian Blur applied to them. /// internal sealed class GaussianMaskSurface : IGaussianMaskSurface { @@ -43,12 +42,11 @@ internal sealed class GaussianMaskSurface : IGaussianMaskSurface /// Initializes a new instance of the class. /// Constructor /// - /// IComposiitonGeneratorInternal object - /// Size of the GaussianMaskSurface - /// Geometry of the GaussianMaskSurface - /// The offset from the top left corner of the ICompositionSurface where - /// the Geometry is rendered. - /// Radius of Gaussian Blur to be applied on the GaussianMaskSurface + /// object + /// Size of the + /// Geometry of the + /// The offset from the top left corner of the where the is rendered. + /// Radius of Gaussian Blur to be applied on the public GaussianMaskSurface(ICompositionGeneratorInternal generator, Size size, CanvasGeometry geometry, Vector2 offset, float blurRadius) { _generator = generator ?? throw new ArgumentException("Generator cannot be null!", nameof(generator)); @@ -176,7 +174,7 @@ private void OnDeviceReplaced(object sender, object e) } /// - /// Helper class to redraw the GaussianMaskSurface + /// Helper class to redraw the /// private void RedrawSurface() { diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometryMaskSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometryMaskSurface.cs index acc2e4e3a23..e44df6a3196 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometryMaskSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometryMaskSurface.cs @@ -11,7 +11,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Media { /// - /// Class for rendering custom shaped geometries onto ICompositionSurface so that they can be used as masks on Composition Visuals. + /// Class for rendering custom shaped geometries onto so that they can be used as masks on Composition Visuals. /// internal sealed class GeometryMaskSurface : IGeometryMaskSurface { @@ -37,10 +37,10 @@ internal sealed class GeometryMaskSurface : IGeometryMaskSurface /// /// Initializes a new instance of the class. /// - /// IComposiitonGeneratorInternal object - /// Size of the GeometryMaskSurface - /// Geometry of the GeometryMaskSurface - /// The offset from the top left corner of the ICompositionSurface where the Geometry is rendered. + /// object + /// Size of the + /// Geometry of the + /// The offset from the top left corner of the where the Geometry is rendered. public GeometryMaskSurface(ICompositionGeneratorInternal generator, Size size, CanvasGeometry geometry, Vector2 offset) { _generator = generator ?? throw new ArgumentException("Generator cannot be null!", nameof(generator)); @@ -150,7 +150,7 @@ private void OnDeviceReplaced(object sender, object e) } /// - /// Helper class to redraw the GeometryMaskSurface. + /// Helper class to redraw the . /// private void RedrawSurface() { diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometrySurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometrySurface.cs index d2b94624628..a4418f96641 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometrySurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometrySurface.cs @@ -12,7 +12,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Media { /// - /// Class for rendering custom shaped geometries onto ICompositionSurface. + /// Class for rendering custom shaped geometries onto . /// internal sealed class GeometrySurface : IGeometrySurface { @@ -49,12 +49,12 @@ internal sealed class GeometrySurface : IGeometrySurface /// Initializes a new instance of the class. /// Constructor /// - /// IComposiitonGeneratorInternal object. - /// Size of the GeometrySurface. - /// Geometry of the GeometrySurface. + /// object. + /// Size of the . + /// Geometry of the . /// Stroke for the geometry. /// Fill color of the geometry. - /// Brush to fill the GeometrySurface background surface which is not covered by the geometry. + /// Brush to fill the background surface which is not covered by the geometry. public GeometrySurface(ICompositionGeneratorInternal generator, Size size, CanvasGeometry geometry, ICanvasStroke stroke, Color fillColor, Color backgroundColor) { _generator = generator ?? throw new ArgumentException("Generator cannot be null!", nameof(generator)); @@ -79,9 +79,9 @@ public GeometrySurface(ICompositionGeneratorInternal generator, Size size, Canva /// Initializes a new instance of the class. /// Constructor /// - /// IComposiitonGeneratorInternal object. - /// Size of the GeometrySurface. - /// Geometry of the GeometrySurface. + /// object. + /// Size of the . + /// Geometry of the . /// Stroke for the geometry. /// Brush to fill the geometry. /// Brush to fill the GeometrySurface background surface which is not covered by the geometry. @@ -754,7 +754,7 @@ public void Dispose() /// Handles the DeviceReplaced event. /// /// Sender. - /// object. + /// Event Arguments. private void OnDeviceReplaced(object sender, object e) { // Recreate the GeometrySurface @@ -765,7 +765,7 @@ private void OnDeviceReplaced(object sender, object e) } /// - /// Helper class to redraw the surface. + /// Helper class to redraw the . /// private void RedrawSurface() { diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageMaskSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageMaskSurface.cs index e03984156b1..4fa8bd31263 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageMaskSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageMaskSurface.cs @@ -12,7 +12,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Media { /// - /// Class for rendering a mask, using an Image's alpha values, onto an ICompositionSurface. + /// Class for rendering a mask, using an Image's alpha values, onto an . /// internal sealed class ImageMaskSurface : IImageMaskSurface { @@ -24,7 +24,7 @@ internal sealed class ImageMaskSurface : IImageMaskSurface private bool _raiseLoadCompletedEvent; /// - /// Event that is raised when the image has been downloaded, decoded and loaded to the underlying IImageSurface. + /// Event that is raised when the image has been downloaded, decoded and loaded to the underlying . /// This event fires regardless of success or failure. /// public event TypedEventHandler LoadCompleted; @@ -62,10 +62,10 @@ internal sealed class ImageMaskSurface : IImageMaskSurface /// /// Initializes a new instance of the class. /// - /// IComposiitonGeneratorInternal object. - /// Uri of the image to be loaded onto the IImageMaskSurface. - /// Size of the IImageMaskSurface. - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. + /// object. + /// Uri of the image to be loaded onto the . + /// Size of the . + /// The padding between the outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. /// The image's resize, alignment options and blur radius in the allocated space. public ImageMaskSurface(ICompositionGeneratorInternal generator, Uri uri, Size size, Thickness padding, ImageSurfaceOptions options) { @@ -94,10 +94,10 @@ public ImageMaskSurface(ICompositionGeneratorInternal generator, Uri uri, Size s /// Initializes a new instance of the class. /// Constructor /// - /// IComposiitonGeneratorInternal object. - /// The CanvasBitmap whose alpha values will be used to create the Mask. - /// Size of the IImageMaskSurface. - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. + /// object. + /// The whose alpha values will be used to create the Mask. + /// Size of the . + /// The padding between the outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. /// The image's resize, alignment options and blur radius in the allocated space. public ImageMaskSurface(ICompositionGeneratorInternal generator, CanvasBitmap surfaceBitmap, Size size, Thickness padding, ImageSurfaceOptions options) { @@ -532,9 +532,9 @@ public void Dispose() } /// - /// Redraws the IImageMaskSurface asynchronously by loading the image from the Uri. + /// Redraws the asynchronously by loading the image from the Uri. /// - /// Task + /// internal Task RedrawAsync() { // Reload the IImageMaskSurface @@ -556,7 +556,7 @@ private async void OnDeviceReplaced(object sender, object e) } /// - /// Helper class to redraw the IImageMaskSurface synchronously. + /// Helper class to redraw the synchronously. /// private void RedrawSurface() { @@ -573,7 +573,7 @@ private void RedrawSurface() } /// - /// Helper class to redraw the IImageMaskSurface asynchronously. + /// Helper class to redraw the asynchronously. /// /// Task private async Task RedrawSurfaceAsync() diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurface.cs index babfe512617..edc7d587a3f 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurface.cs @@ -11,7 +11,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Media { /// - /// Class for rendering an image onto a ICompositionSurface. + /// Class for rendering an image onto a . /// internal sealed class ImageSurface : IImageSurface { @@ -59,9 +59,9 @@ internal sealed class ImageSurface : IImageSurface /// Initializes a new instance of the class. /// Constructor /// - /// IComposiitonGeneratorInternal object. - /// Uri of the image to be loaded onto the IImageSurface. - /// Size of the IImageSurface. + /// object. + /// of the image to be loaded onto the . + /// Size of the . /// The image's resize and alignment options in the allocated space. public ImageSurface(ICompositionGeneratorInternal generator, Uri uri, Size size, ImageSurfaceOptions options) { @@ -89,9 +89,9 @@ public ImageSurface(ICompositionGeneratorInternal generator, Uri uri, Size size, /// Initializes a new instance of the class. /// Constructor /// - /// IComposiitonGeneratorInternal object. - /// CanvasBitmap which will be rendered on the IImageSurface. - /// Size of the IImageSurface. + /// object. + /// which will be rendered on the . + /// Size of the . /// The image's resize and alignment options in the allocated space. internal ImageSurface(ICompositionGeneratorInternal generator, CanvasBitmap surfaceBitmap, Size size, ImageSurfaceOptions options) { @@ -349,8 +349,7 @@ public void Dispose() } /// - /// Redraws the IImageSurface asynchronously - /// by loading the image from the Uri + /// Redraws the asynchronously by loading the image from the Uri. /// /// Task internal Task RedrawAsync() @@ -374,7 +373,7 @@ private async void OnDeviceReplaced(object sender, object e) } /// - /// Helper class to redraw the IImageSurface synchronously. + /// Helper class to redraw the synchronously. /// private void RedrawSurface() { @@ -400,9 +399,9 @@ private void RedrawSurface() } /// - /// Helper class to redraw the IImageSurface asynchronously. + /// Helper class to redraw the asynchronously. /// - /// Task + /// private async Task RedrawSurfaceAsync() { // Cache the canvasBitmap to avoid reloading of the same image during Resize/Redraw operations diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/ICompositionGenerator.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/ICompositionGenerator.cs index feb18ceb2f5..77180410434 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/ICompositionGenerator.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/ICompositionGenerator.cs @@ -16,7 +16,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Media { /// - /// Interface for the ComposiitonGenerator + /// Interface for the /// public interface ICompositionGenerator : IDisposable { @@ -26,273 +26,263 @@ public interface ICompositionGenerator : IDisposable event EventHandler DeviceReplaced; /// - /// Gets the Compositor. + /// Gets the . /// Compositor Compositor { get; } /// - /// Gets the CanvasDevice. + /// Gets the . /// CanvasDevice Device { get; } /// - /// Creates an Empty GeometryMaskSurface having the no size and geometry. - /// NOTE: Use this API if you want to create an Empty IGeometryMaskSurface first - /// and change its geometry and/or size of the GeometryMaskSurface later. + /// Creates an Empty having the no size and geometry. + /// NOTE: Use this API if you want to create an Empty first + /// and change its geometry and/or size of the later. /// - /// IGeometryMaskSurface + /// IGeometryMaskSurface CreateGeometryMaskSurface(); /// - /// Creates a GeometryMaskSurface having the given size and geometry. The geometry is filled + /// Creates a having the given size and geometry. The geometry is filled /// with white color. The surface not covered by the geometry is transparent. /// /// Size of the mask. /// Geometry of the mask. - /// IGeometryMaskSurface + /// IGeometryMaskSurface CreateGeometryMaskSurface(Size size, CanvasGeometry geometry); /// - /// Creates a GeometryMaskSurface having the given size and geometry. The geometry is filled + /// Creates a having the given size and geometry. The geometry is filled /// with white color. The surface not covered by the geometry is transparent. /// /// Size of the mask. /// Geometry of the mask. - /// The offset from the top left corner of the ICompositionSurface where the Geometry is rendered. - /// IGeometryMaskSurface + /// The offset from the top left corner of the where the is rendered. + /// IGeometryMaskSurface CreateGeometryMaskSurface(Size size, CanvasGeometry geometry, Vector2 offset); /// - /// Creates an Empty IGaussianMaskSurface having the no size and geometry. - /// NOTE: Use this API if you want to create an Empty IGaussianMaskSurface first - /// and change its geometry, size and/or blurRadius of the IGaussianMaskSurface later. + /// Creates an Empty having the no size and geometry. + /// NOTE: Use this API if you want to create an Empty first and change its geometry, size and/or blurRadius of the later. /// - /// IGeometryMaskSurface + /// IGaussianMaskSurface CreateGaussianMaskSurface(); /// - /// Creates an IGaussianMaskSurface having the given size and geometry. The geometry is filled + /// Creates an having the given size and geometry. The geometry is filled /// with white color and a Gaussian blur is applied to it. The surface not covered by the geometry is transparent. /// /// Size of the mask. /// Geometry of the mask. - /// The offset from the top left corner of the ICompositionSurface where the Geometry is rendered. - /// Radius of Gaussian Blur to be applied on the IGaussianMaskSurface. - /// IGaussianMaskSurface + /// The offset from the top left corner of the where the is rendered. + /// Radius of Gaussian Blur to be applied on the . + /// IGaussianMaskSurface CreateGaussianMaskSurface(Size size, CanvasGeometry geometry, Vector2 offset, float blurRadius); /// - /// Creates an Empty IGeometrySurface having the no size and geometry. - /// NOTE: Use this API if you want to create an Empty IGeometrySurface - /// first and change its geometry and/or size, fillColor or stroke later. + /// Creates an Empty having the no size and geometry. + /// NOTE: Use this API if you want to create an Empty first and change its geometry and/or size, fillColor or stroke later. /// - /// IGeometrySurface + /// IGeometrySurface CreateGeometrySurface(); /// - /// Creates an IGeometrySurface having the given size, geometry, stroke + /// Creates an having the given size, geometry, stroke. /// - /// Size of the IGeometrySurface. - /// Geometry to be rendered on the IGeometrySurface. - /// ICanvasStroke defining the outline for the geometry. - /// IGeometrySurface + /// Size of the . + /// Geometry to be rendered on the . + /// defining the outline for the geometry. + /// IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasStroke stroke); /// - /// Creates an IGeometrySurface having the given size, geometry, fill color + /// Creates an having the given size, geometry, fill color. /// - /// Size of the IGeometrySurface. - /// Geometry to be rendered on the IGeometrySurface. + /// Size of the . + /// Geometry to be rendered on the . /// Fill color of the geometry. - /// IGeometrySurface + /// IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, Color fillColor); /// - /// Creates an IGeometrySurface having the given size, geometry, stroke and fill color + /// Creates an having the given size, geometry, stroke and fill color. /// - /// Size of the IGeometrySurface. - /// Geometry to be rendered on the IGeometrySurface. - /// ICanvasStroke defining the outline for the geometry. + /// Size of the . + /// Geometry to be rendered on the . + /// defining the outline for the geometry. /// Fill color of the geometry. - /// IGeometrySurface + /// IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasStroke stroke, Color fillColor); /// - /// Creates an IGeometrySurface having the given size, geometry, fill color and - /// background color. + /// Creates an having the given size, geometry, fill color and background color. /// - /// Size of the IGeometrySurface. - /// Geometry to be rendered on the IGeometrySurface. + /// Size of the . + /// Geometry to be rendered on the . /// Fill color of the geometry. - /// Fill color of the IGeometrySurface background which is + /// Fill color of the background which is /// not covered by the geometry. - /// IGeometrySurface + /// IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, Color fillColor, Color backgroundColor); /// - /// Creates an IGeometrySurface having the given size, geometry, stroke, fill color and - /// background color. + /// Creates an having the given size, geometry, stroke, fill color and background color. /// - /// Size of the IGeometrySurface. - /// Geometry to be rendered on the IGeometrySurface. - /// ICanvasStroke defining the outline for the geometry. + /// Size of the . + /// Geometry to be rendered on the . + /// defining the outline for the geometry. /// Fill color of the geometry. - /// Fill color of the IGeometrySurface background which is not covered by the geometry. - /// IGeometrySurface + /// Fill color of the background which is not covered by the geometry. + /// IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasStroke stroke, Color fillColor, Color backgroundColor); /// - /// Creates an IGeometrySurface having the given size, geometry and fill brush. + /// Creates an having the given size, geometry and fill brush. /// - /// Size of the IGeometrySurface. - /// Geometry to be rendered on the IGeometrySurface. + /// Size of the . + /// Geometry to be rendered on the . /// The brush with which the geometry has to be filled. - /// IGeometrySurface + /// IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasBrush fillBrush); /// - /// Creates an IGeometrySurface having the given size, geometry, stroke and fill brush. + /// Creates an having the given size, geometry, stroke and fill brush. /// - /// Size of the IGeometrySurface. - /// Geometry to be rendered on the IGeometrySurface. - /// ICanvasStroke defining the outline for the geometry. + /// Size of the . + /// Geometry to be rendered on the . + /// defining the outline for the geometry. /// The brush with which the geometry has to be filled. - /// IGeometrySurface + /// IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasStroke stroke, ICanvasBrush fillBrush); /// - /// Creates an IGeometrySurface having the given size, geometry, fill brush and - /// background brush. + /// Creates an having the given size, geometry, fill brush and background brush. /// - /// Size of the IGeometrySurface. - /// Geometry to be rendered on the IGeometrySurface. + /// Size of the . + /// Geometry to be rendered on the . /// The brush with which the geometry has to be filled. - /// The brush to fill the IGeometrySurface background which is not covered by the geometry. - /// IGeometrySurface + /// The brush to fill the background which is not covered by the geometry. + /// IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasBrush fillBrush, ICanvasBrush backgroundBrush); /// - /// Creates an IGeometrySurface having the given size, geometry, stroke, fill brush and - /// background brush. + /// Creates an having the given size, geometry, stroke, fill brush and background brush. /// - /// Size of the IGeometrySurface. - /// Geometry to be rendered on the IGeometrySurface. - /// ICanvasStroke defining the outline for the geometry. + /// Size of the . + /// Geometry to be rendered on the . + /// defining the outline for the geometry. /// The brush with which the geometry has to be filled. - /// The brush to fill the IGeometrySurface background which is not covered by the geometry. - /// IGeometrySurface + /// The brush to fill the background which is not covered by the geometry. + /// IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasStroke stroke, ICanvasBrush fillBrush, ICanvasBrush backgroundBrush); /// - /// Creates an IGeometrySurface having the given size, geometry, fill brush and - /// background color. + /// Creates an having the given size, geometry, fill brush and background color. /// - /// Size of the IGeometrySurface. - /// Geometry to be rendered on the IGeometrySurface. + /// Size of the . + /// Geometry to be rendered on the . /// The brush with which the geometry has to be filled. - /// Fill color of the IGeometrySurface background which is not covered by the geometry. - /// IGeometrySurface + /// Fill color of the background which is not covered by the geometry. + /// IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasBrush fillBrush, Color backgroundColor); /// - /// Creates an IGeometrySurface having the given size, geometry, stroke, fill brush and + /// Creates an having the given size, geometry, stroke, fill brush and /// background color. /// - /// Size of the IGeometrySurface. - /// Geometry to be rendered on the IGeometrySurface. - /// ICanvasStroke defining the outline for the geometry. + /// Size of the . + /// Geometry to be rendered on the . + /// defining the outline for the geometry. /// The brush with which the geometry has to be filled. - /// Fill color of the IGeometrySurface background which is not covered by the geometry. - /// IGeometrySurface + /// Fill color of the background which is not covered by the geometry. + /// IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasStroke stroke, ICanvasBrush fillBrush, Color backgroundColor); /// - /// Creates an IGeometrySurface having the given size, geometry, fill color and - /// background brush. + /// Creates an having the given size, geometry, fill color and background brush. /// - /// Size of the IGeometrySurface. - /// Geometry to be rendered on the IGeometrySurface. + /// Size of the . + /// Geometry to be rendered on the . /// Fill color of the geometry. - /// The brush to fill the IGeometrySurface background which is not covered by the geometry. - /// IGeometrySurface + /// The brush to fill the background which is not covered by the geometry. + /// IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, Color fillColor, ICanvasBrush backgroundBrush); /// - /// Creates an IGeometrySurface having the given size, geometry, stroke, fill color and - /// background brush. + /// Creates an having the given size, geometry, stroke, fill color and background brush. /// - /// Size of the IGeometrySurface. - /// Geometry to be rendered on the IGeometrySurface. - /// ICanvasStroke defining the outline for the geometry. + /// Size of the . + /// Geometry to be rendered on the . + /// defining the outline for the geometry. /// Fill color of the geometry. - /// The brush to fill the IGeometrySurface background which is not covered by the geometry. - /// IGeometrySurface + /// The brush to fill the background which is not covered by the geometry. + /// IGeometrySurface CreateGeometrySurface(Size size, CanvasGeometry geometry, ICanvasStroke stroke, Color fillColor, ICanvasBrush backgroundBrush); /// - /// Creates an IImageSurface having the given size onto which an image (based on the Uri - /// and the options) is loaded. + /// Creates an having the given size onto which an image (based on the and the options) is loaded. /// - /// Uri of the image to be loaded onto the IImageSurface. - /// New size of the IImageSurface. + /// Uri of the image to be loaded onto the . + /// New size of the . /// The image's resize and alignment options in the allocated space. - /// Task<IImageSurface> + /// <> Task CreateImageSurfaceAsync(Uri uri, Size size, ImageSurfaceOptions options); /// - /// Creates an IImageSurface having the given size onto which the given image is loaded. + /// Creates an having the given size onto which the given image is loaded. /// - /// Image that will be loaded onto the IImageSurface. - /// Size of the IImageSurface. + /// Image that will be loaded onto the . + /// Size of the . /// The image's resize and alignment options in the allocated space. - /// IImageSurface + /// IImageSurface CreateImageSurface(CanvasBitmap bitmap, Size size, ImageSurfaceOptions options); /// - /// Creates a copy of the given IImageSurface + /// Creates a copy of the given /// - /// IImageSurface to copy. - /// IImageSurface + /// to copy. + /// IImageSurface CreateImageSurface(IImageSurface imageSurface); /// - /// Creates a copy of the given IImageMaskSurface + /// Creates a copy of the given /// - /// IImageMaskSurface to copy. - /// IImageMaskSurface + /// to copy. + /// IImageMaskSurface CreateImageMaskSurface(IImageMaskSurface imageMaskSurface); /// - /// Creates an IImageMaskSurface having the given size onto which an image (based on the Uri + /// Creates an having the given size onto which an image (based on the Uri /// and the options) is loaded. /// /// The CanvasBitmap whose alpha values will be used to create the Mask. - /// Size of the IImageSurface. - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the given image's alpha values, should be rendered. + /// Size of the . + /// The padding between the outer bounds and the bounds of the area where the mask, created from the given image's alpha values, should be rendered. /// Radius of the Gaussian blur applied to the the mask. - /// IImageMaskSurface + /// IImageMaskSurface CreateImageMaskSurface(CanvasBitmap surfaceBitmap, Size size, Thickness padding, float blurRadius); /// - /// Creates an IImageMaskSurface having the given size onto which an image (based on the Uri + /// Creates an having the given size onto which an image (based on the Uri /// and the options) is loaded. /// /// The CanvasBitmap whose alpha values will be used to create the Mask. - /// Size of the IImageSurface. - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the given image's alpha values, should be rendered. + /// Size of the . + /// The padding between the outer bounds and the bounds of the area where the mask, created from the given image's alpha values, should be rendered. /// The image's resize, alignment options and blur radius in the allocated space. - /// IImageMaskSurface + /// IImageMaskSurface CreateImageMaskSurface(CanvasBitmap surfaceBitmap, Size size, Thickness padding, ImageSurfaceOptions options); /// - /// Creates an IImageMaskSurface having the given size onto which an image (based on the Uri + /// Creates an having the given size onto which an image (based on the Uri /// and the options) is loaded. /// - /// The IImageSurface whose image's alpha values will be used to create the Mask. - /// Size of the IImageMaskSurface. - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the given image's alpha values, should be rendered. + /// The whose image's alpha values will be used to create the Mask. + /// Size of the . + /// The padding between the outer bounds and the bounds of the area where the mask, created from the given image's alpha values, should be rendered. /// The image's resize, alignment options and blur radius in the allocated space. - /// IImageMaskSurface + /// IImageMaskSurface CreateImageMaskSurface(IImageSurface imageSurface, Size size, Thickness padding, ImageSurfaceOptions options); /// @@ -300,16 +290,16 @@ public interface ICompositionGenerator : IDisposable /// and the options) is loaded. /// /// Uri of the image whose alpha values will be used to create the Mask. - /// Size of the IImageMaskSurface. - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the given image's alpha values, should be rendered. + /// Size of the . + /// The padding between the outer bounds and the bounds of the area where the mask, created from the given image's alpha values, should be rendered. /// The image's resize, alignment options and blur radius in the allocated space. - /// Task<IImageMaskSurface> + /// <> Task CreateImageMaskSurfaceAsync(Uri uri, Size size, Thickness padding, ImageSurfaceOptions options); /// - /// Creates a reflection of the given Visual + /// Creates a reflection of the given . /// - /// Visual whose reflection has to be created. + /// whose reflection has to be created. /// Distance of the reflection from the visual. /// Normalized Length of the reflected visual that will be visible. /// - Location of the reflection with respect to the Visual - Bottom, Top, Left or Right. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/ICompositionGeneratorInternal.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/ICompositionGeneratorInternal.cs index 6f03aa3adc6..cbc47cac6a3 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/ICompositionGeneratorInternal.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/ICompositionGeneratorInternal.cs @@ -20,96 +20,94 @@ namespace Microsoft.Toolkit.Uwp.UI.Media internal interface ICompositionGeneratorInternal : ICompositionGenerator { /// - /// Creates a CompositionDrawingSurface for the given size. + /// Creates a for the given size. /// /// The object to lock to prevent multiple threads from accessing the surface at the same time. - /// Size of the Mask Surface. - /// CompositionDrawingSurface + /// Size of the . + /// CompositionDrawingSurface CreateDrawingSurface(object surfaceLock, Size size); /// - /// Resizes the GeometryMaskSurface to the given size. + /// Resizes the to the given size. /// /// The object to lock to prevent multiple threads from accessing the surface at the same time. - /// CompositionDrawingSurface. - /// New size of the Mask Surface. + /// . + /// New size of the . void ResizeDrawingSurface(object surfaceLock, CompositionDrawingSurface surface, Size size); /// - /// Redraws the GeometryMaskSurface with the given size and geometry. + /// Redraws the with the given size and geometry. /// /// The object to lock to prevent multiple threads from accessing the surface at the same time. - /// CompositionDrawingSurface. - /// Size of the GeometryMaskSurface. - /// Geometry of the GeometryMaskSurface. - /// The offset from the top left corner of the ICompositionSurface where the Geometry is rendered. + /// . + /// Size of the . + /// Geometry of the . + /// The offset from the top left corner of the where the is rendered. void RedrawGeometryMaskSurface(object surfaceLock, CompositionDrawingSurface surface, Size size, CanvasGeometry geometry, Vector2 offset); /// - /// Redraws the GaussianMaskSurface with the given size and geometry. + /// Redraws the with the given size and geometry. /// /// The object to lock to prevent multiple threads from accessing the surface at the same time. - /// CompositionDrawingSurface. - /// Size of the GeometryMaskSurface. - /// Geometry of the GeometryMaskSurface. - /// The offset from the top left corner of the ICompositionSurface where the Geometry is rendered. - /// Radius of Gaussian Blur to be applied on the GaussianMaskSurface. + /// . + /// Size of the . + /// Geometry of the . + /// The offset from the top left corner of the ICompositionSurface where the is rendered. + /// Radius of Gaussian Blur to be applied on the . void RedrawGaussianMaskSurface(object surfaceLock, CompositionDrawingSurface surface, Size size, CanvasGeometry geometry, Vector2 offset, float blurRadius); /// - /// Redraws the GeometrySurface with the given size, geometry, foreground brush and background brush. + /// Redraws the with the given size, geometry, foreground brush and background brush. /// /// The object to lock to prevent multiple threads from accessing the surface at the same time. - /// CompositionDrawingSurface. - /// Size of the GeometrySurface. - /// Geometry of the GeometrySurface. - /// ICanvasStroke defining the outline for the geometry. + /// . + /// Size of the . + /// Geometry of the . + /// defining the outline for the geometry. /// The brush with which the geometry has to be filled. - /// The brush with which the GeometrySurface background has to be filled. + /// The brush with which the background has to be filled. void RedrawGeometrySurface(object surfaceLock, CompositionDrawingSurface surface, Size size, CanvasGeometry geometry, ICanvasStroke stroke, ICanvasBrush fillBrush, ICanvasBrush backgroundBrush); /// - /// Resizes the ImageSurface to the given size and redraws the ImageSurface by rendering the canvasBitmap onto the surface. + /// Resizes the ImageSurface to the given size and redraws the by rendering the canvasBitmap onto the surface. /// /// The object to lock to prevent multiple threads from accessing the surface at the same time. - /// CompositionDrawingSurface. + /// . /// Describes the image's resize and alignment options in the allocated space. - /// The CanvasBitmap on which the image is loaded. + /// The on which the image is loaded. void RedrawImageSurface(object surfaceLock, CompositionDrawingSurface surface, ImageSurfaceOptions options, CanvasBitmap canvasBitmap); /// - /// Resizes the ImageSurface with the given size and redraws the ImageSurface by loading image from the new Uri. + /// Resizes the with the given size and redraws the by loading image from the new Uri. /// /// The object to lock to prevent multiple threads from accessing the surface at the same time. - /// CompositionDrawingSurface. - /// Uri of the image to be loaded onto the IImageSurface. + /// . + /// Uri of the image to be loaded onto the . /// Describes the image's resize and alignment options in the allocated space. - /// The CanvasBitmap on which the image is loaded. - /// CanvasBitmap + /// The on which the image is loaded. + /// Task RedrawImageSurfaceAsync(object surfaceLock, CompositionDrawingSurface surface, Uri uri, ImageSurfaceOptions options, CanvasBitmap canvasBitmap); /// - /// Resizes the ImageMaskSurface to the given size and redraws the ImageMaskSurface by rendering the mask - /// using the image's alpha values onto the surface. + /// Resizes the to the given size and redraws the IImageMaskSurface by rendering the mask using the image's alpha values onto the surface. /// /// The object to lock to prevent multiple threads from accessing the surface at the same time. - /// CompositionDrawingSurface. - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. + /// . + /// The padding between the outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. /// Describes the image's resize and alignment options and blur radius in the allocated space. - /// The image whose alpha values is used to create the IImageMaskSurface. + /// The image whose alpha values is used to create the . void RedrawImageMaskSurface(object surfaceLock, CompositionDrawingSurface surface, Thickness padding, ImageSurfaceOptions options, CanvasBitmap surfaceBitmap); /// - /// Resizes the ImageMaskSurface to the given size and redraws the ImageMaskSurface by loading the image from the new Uri and - /// rendering the mask using the image's alpha values onto the surface. + /// Resizes the to the given size and redraws the by loading the image from the new and rendering the mask using the image's alpha values onto the surface. /// /// The object to lock to prevent multiple threads from accessing the surface at the same time. - /// CompositionDrawingSurface. - /// Uri of the image to be loaded onto the IImageMaskSurface. - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. + /// . + /// Uri of the image to be loaded onto the . + /// The padding between the outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. /// Describes the image's resize and alignment options and blur radius in the allocated space. - /// The CanvasBitmap on which the image is loaded. - /// The CanvasBitmap whose alpha values is used to create the IImageMaskSurface. + /// The on which the image is loaded. + /// The whose alpha values is used to create the . Task RedrawImageMaskSurfaceAsync(object surfaceLock, CompositionDrawingSurface surface, Uri uri, Thickness padding, ImageSurfaceOptions options, CanvasBitmap surfaceBitmap); } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IGaussianMaskSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IGaussianMaskSurface.cs index f8a4bf93b97..4bd955e35f4 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IGaussianMaskSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IGaussianMaskSurface.cs @@ -5,41 +5,42 @@ using System.Numerics; using Microsoft.Graphics.Canvas.Geometry; using Windows.Foundation; +using Windows.UI.Composition; namespace Microsoft.Toolkit.Uwp.UI.Media { /// - /// Interface for rendering custom shaped geometries onto ICompositionSurface so that they can be used as masks on Composition Visuals. + /// Interface for rendering custom shaped geometries onto so that they can be used as masks on Composition Visuals. /// These geometries have a Gaussian Blur applied to them. /// public interface IGaussianMaskSurface : IGeometryMaskSurface { /// - /// Gets radius of Gaussian Blur to be applied on the GaussianMaskSurface. + /// Gets radius of Gaussian Blur to be applied on the . /// float BlurRadius { get; } /// - /// Applies the given blur radius to the IGaussianMaskSurface. + /// Applies the given blur radius to the . /// - /// Radius of Gaussian Blur to be applied on the GaussianMaskSurface. + /// Radius of Gaussian Blur to be applied on the . void Redraw(float blurRadius); /// - /// Redraws the IGaussianMaskSurface with the new geometry and fills it with White color after applying the Gaussian blur with given blur radius. + /// Redraws the with the new geometry and fills it with White color after applying the Gaussian blur with given blur radius. /// - /// New CanvasGeometry to be applied to the GaussianMaskSurface. - /// The offset from the top left corner of the ICompositionSurface where the Geometry is rendered. - /// Radius of Gaussian Blur to be applied on the IGaussianMaskSurface. + /// New to be applied to the . + /// The offset from the top left corner of the where the is rendered. + /// Radius of Gaussian Blur to be applied on the . void Redraw(CanvasGeometry geometry, Vector2 offset, float blurRadius); /// - /// Resizes the IGaussianMaskSurface with the given size and redraws the IGaussianMaskSurface with the new geometry and fills it with White color. + /// Resizes the with the given size and redraws the with the new geometry and fills it with White color. /// /// New size of the mask - /// New CanvasGeometry to be applied to the IGaussianMaskSurface. - /// The offset from the top left corner of the ICompositionSurface where the Geometry is rendered. - /// Radius of Gaussian Blur to be applied on the IGaussianMaskSurface. + /// New to be applied to the . + /// The offset from the top left corner of the where the is rendered. + /// Radius of Gaussian Blur to be applied on the . void Redraw(Size size, CanvasGeometry geometry, Vector2 offset, float blurRadius); } } \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IGeometryMaskSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IGeometryMaskSurface.cs index 623b4891b3e..173d8cbb042 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IGeometryMaskSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IGeometryMaskSurface.cs @@ -5,50 +5,51 @@ using System.Numerics; using Microsoft.Graphics.Canvas.Geometry; using Windows.Foundation; +using Windows.UI.Composition; namespace Microsoft.Toolkit.Uwp.UI.Media { /// - /// Interface for rendering custom shaped geometries onto ICompositionSurface so that they can be used as masks on Composition Visuals. + /// Interface for rendering custom shaped geometries onto so that they can be used as masks on Composition Visuals. /// public interface IGeometryMaskSurface : IRenderSurface { /// - /// Gets the Geometry of the GeometryMaskSurface. + /// Gets the of the . /// CanvasGeometry Geometry { get; } /// - /// Gets the offset from the top left corner of the ICompositionSurface where the Geometry is rendered. + /// Gets the offset from the top left corner of the where the is rendered. /// Vector2 Offset { get; } /// - /// Redraws the GeometryMaskSurface with the new geometry + /// Redraws the with the new geometry /// - /// New CanvasGeometry to be applied to the IGeometryMaskSurface. + /// New to be applied to the . void Redraw(CanvasGeometry geometry); /// - /// Resizes the GeometryMaskSurface with the given size and redraws the IGeometryMaskSurface with the new geometry and fills it with White color. + /// Resizes the with the given size and redraws the with the new geometry and fills it with White color. /// /// New size of the mask. - /// New CanvasGeometry to be applied to the IGeometryMaskSurface. + /// New to be applied to the . void Redraw(Size size, CanvasGeometry geometry); /// - /// Redraws the IGeometryMaskSurface with the new geometry. + /// Redraws the with the new geometry. /// - /// New CanvasGeometry to be applied to the IGeometryMaskSurface. - /// The offset from the top left corner of the ICompositionSurface where the Geometry is rendered. + /// New to be applied to the . + /// The offset from the top left corner of the where the is rendered. void Redraw(CanvasGeometry geometry, Vector2 offset); /// - /// Resizes the IGeometryMaskSurface with the given size and redraws the IGeometryMaskSurface with the new geometry and fills it with White color. + /// Resizes the with the given size and redraws the with the new geometry and fills it with White color. /// /// New size of the mask. - /// New CanvasGeometry to be applied to the IGeometryMaskSurface. - /// The offset from the top left corner of the ICompositionSurface where the Geometry is rendered. + /// New to be applied to the . + /// The offset from the top left corner of the where the is rendered. void Redraw(Size size, CanvasGeometry geometry, Vector2 offset); } } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IGeometrySurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IGeometrySurface.cs index 7ee16218817..0facb7a41a2 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IGeometrySurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IGeometrySurface.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#pragma warning disable CS0419 // Ambiguous reference in cref attribute + using Microsoft.Graphics.Canvas.Brushes; using Microsoft.Graphics.Canvas.Geometry; using Windows.Foundation; @@ -15,7 +17,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Media public interface IGeometrySurface : IRenderSurface { /// - /// Gets the Surface Geometry. + /// Gets the Surface . /// CanvasGeometry Geometry { get; } @@ -30,226 +32,228 @@ public interface IGeometrySurface : IRenderSurface ICanvasBrush Fill { get; } /// - /// Gets the Brush with which the IGeometrySurface background is filled. + /// Gets the Brush with which the background is filled. /// ICanvasBrush BackgroundBrush { get; } /// - /// Redraws the IGeometrySurface with the new geometry + /// Redraws the with the new geometry /// - /// New CanvasGeometry to be applied to the IGeometrySurface. + /// New to be applied to the . void Redraw(CanvasGeometry geometry); /// - /// Redraws the IGeometrySurface by outlining the existing geometry with the given ICanvasStroke. + /// Redraws the by outlining the existing geometry with the given . /// - /// ICanvasStroke defining the outline for the geometry. + /// defining the outline for the geometry. void Redraw(ICanvasStroke stroke); /// - /// Redraws the IGeometrySurface by filling the existing geometry with the fill color. + /// Redraws the by filling the existing geometry with the fill color. /// - /// Color with which the geometry is to be filled. + /// with which the geometry is to be filled. void Redraw(Color fillColor); /// - /// Redraws the IGeometrySurface by filling the existing geometry with the given fill color and outlining it with the given ICanvasStroke. + /// Redraws the by filling the existing geometry with the given fill color and outlining it with the given . /// - /// ICanvasStroke defining the outline for the geometry. - /// Color with which the geometry is to be filled. + /// The defining the outline for the geometry. + /// with which the geometry is to be filled. void Redraw(ICanvasStroke stroke, Color fillColor); /// - /// Redraws the IGeometrySurface by filling the existing geometry with the fill color and the background with the background color. + /// Redraws the by filling the existing geometry with the fill color and the background with the background color. /// - /// Color with which the geometry is to be filled. - /// Color with which the IGeometrySurface background is to be filled. + /// with which the geometry is to be filled. + /// with which the background is to be filled. void Redraw(Color fillColor, Color backgroundColor); /// - /// Redraws the IGeometrySurface by outlining the existing geometry with the given ICanvasStroke, filling it with the fill color and the background with the background color. + /// Redraws the by outlining the existing geometry with the given , filling it with the fill color and the background with the background color. /// - /// ICanvasStroke defining the outline for the geometry. - /// Color with which the geometry is to be filled. - /// Color with which the IGeometrySurface background is to be filled. + /// The defining the outline for the geometry. + /// with which the geometry is to be filled. + /// with which the background is to be filled. void Redraw(ICanvasStroke stroke, Color fillColor, Color backgroundColor); /// - /// Redraws the IGeometrySurface by filling the existing geometry with the fill brush. + /// Redraws the by filling the existing geometry with the fill brush. /// /// Brush with which the geometry is to be filled. void Redraw(ICanvasBrush fillBrush); /// - /// Redraws the IGeometrySurface by outlining the existing geometry with the given ICanvasStroke, filling it with the fill brush. + /// Redraws the by outlining the existing geometry with the given , filling it with the fill brush. /// - /// ICanvasStroke defining the outline for the geometry. + /// The defining the outline for the geometry. /// Brush with which the geometry is to be filled. void Redraw(ICanvasStroke stroke, ICanvasBrush fillBrush); /// - /// Redraws the IGeometrySurface by filling the existing geometry with the fill brush and the background with the background brush. + /// Redraws the by filling the existing geometry with the fill brush and the background with the background brush. /// /// Brush with which the geometry is to be filled. - /// Brush with which the IGeometrySurface background is to be filled. + /// Brush with which the background is to be filled. void Redraw(ICanvasBrush fillBrush, ICanvasBrush backgroundBrush); /// - /// Redraws the IGeometrySurface by outlining the existing geometry with the given ICanvasStroke, filling it with the fill brush and the background with the background brush. + /// Redraws the by outlining the existing geometry with the given , filling it with the fill brush and the background with the background brush. /// - /// ICanvasStroke defining the outline for the geometry. + /// The defining the outline for the geometry. /// Brush with which the geometry is to be filled. - /// Brush with which the IGeometrySurface background is to be filled. + /// Brush with which the background is to be filled. void Redraw(ICanvasStroke stroke, ICanvasBrush fillBrush, ICanvasBrush backgroundBrush); /// - /// Redraws the IGeometrySurface by filling the existing geometry with the fill color and the background with the background brush. + /// Redraws the by filling the existing geometry with the fill color and the background with the background brush. /// - /// Color with which the geometry is to be filled. - /// Brush with which the IGeometrySurface background is to be filled. + /// with which the geometry is to be filled. + /// Brush with which the background is to be filled. void Redraw(Color fillColor, ICanvasBrush backgroundBrush); /// - /// Redraws the IGeometrySurface by outlining the existing geometry with the given ICanvasStroke, filling it with the fill color and the background with the background brush. + /// Redraws the by outlining the existing geometry with the given , filling it with the fill color and the background with the background brush. /// - /// ICanvasStroke defining the outline for the geometry. - /// Color with which the geometry is to be filled. - /// Brush with which the IGeometrySurface background is to be filled. + /// The defining the outline for the geometry. + /// with which the geometry is to be filled. + /// Brush with which the background is to be filled. void Redraw(ICanvasStroke stroke, Color fillColor, ICanvasBrush backgroundBrush); /// - /// Redraws the IGeometrySurface by filling the existing geometry with the fill brush and the background with the background color. + /// Redraws the by filling the existing geometry with the fill brush and the background with the background color. /// /// Brush with which the geometry is to be filled. - /// Color with which the IGeometrySurface background is to be filled. + /// with which the background is to be filled. void Redraw(ICanvasBrush fillBrush, Color backgroundColor); /// - /// Redraws the IGeometrySurface by outlining the existing geometry with the given ICanvasStroke, filling it with the fill brush and the background with the background color. + /// Redraws the by outlining the existing geometry with the given , filling it with the fill brush and the background with the background color. /// - /// ICanvasStroke defining the outline for the geometry. + /// The defining the outline for the geometry. /// Brush with which the geometry is to be filled. - /// Color with which the IGeometrySurface background is to be filled. + /// with which the background is to be filled. void Redraw(ICanvasStroke stroke, ICanvasBrush fillBrush, Color backgroundColor); /// - /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface with the new geometry. + /// Resizes the with the given size and redraws the with the new geometry. /// - /// New size of the IGeometrySurface. - /// New CanvasGeometry to be applied to the IGeometrySurface. + /// New size of the . + /// New to be applied to the . void Redraw(Size size, CanvasGeometry geometry); /// - /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface with the new geometry and outlines it with the given ICanvasStroke. + /// Resizes the with the given size and redraws the with the new geometry and outlines it with the given . /// - /// New size of the IGeometrySurface. - /// New CanvasGeometry to be applied to the IGeometrySurface. - /// ICanvasStroke defining the outline for the geometry. + /// New size of the . + /// New to be applied to the . + /// The defining the outline for the geometry. void Redraw(Size size, CanvasGeometry geometry, ICanvasStroke stroke); /// - /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface with the new geometry and fills it with the fill color. + /// Resizes the with the given size and redraws the with the new geometry and fills it with the fill color. /// - /// New size of the IGeometrySurface. - /// New CanvasGeometry to be applied to the IGeometrySurface. + /// New size of the . + /// New to be applied to the . /// Fill color for the geometry. void Redraw(Size size, CanvasGeometry geometry, Color fillColor); /// - /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface with the new geometry, outlines it with the given ICanvasStroke and fills it with the fill color. + /// Resizes the with the given size and redraws the with the new geometry, outlines it with the given and fills it with the fill color. /// - /// New size of the IGeometrySurface. - /// New CanvasGeometry to be applied to the IGeometrySurface. - /// ICanvasStroke defining the outline for the geometry. + /// New size of the . + /// New to be applied to the . + /// The defining the outline for the geometry. /// Fill color for the geometry. void Redraw(Size size, CanvasGeometry geometry, ICanvasStroke stroke, Color fillColor); /// - /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface with the new geometry and fills it with the fill color and fills the background with the background color. + /// Resizes the with the given size and redraws the with the new geometry and fills it with the fill color and fills the background with the background color. /// - /// New size of the IGeometrySurface. - /// New CanvasGeometry to be applied to the IGeometrySurface. + /// New size of the . + /// New to be applied to the . /// Fill color for the geometry. - /// Fill color for the IGeometrySurface background. + /// Fill color for the background. void Redraw(Size size, CanvasGeometry geometry, Color fillColor, Color backgroundColor); /// - /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface with the new geometry, outlines it with the given ICanvasStroke and + /// Resizes the with the given size and redraws the with the new geometry, outlines it with the given and /// fills it with the fill color and fills the background with the background color. /// - /// New size of the IGeometrySurface. - /// New CanvasGeometry to be applied to the IGeometrySurface. - /// ICanvasStroke defining the outline for the geometry. + /// New size of the . + /// New to be applied to the . + /// The defining the outline for the geometry. /// Fill color for the geometry. - /// Fill color for the IGeometrySurface background. + /// Fill color for the background. void Redraw(Size size, CanvasGeometry geometry, ICanvasStroke stroke, Color fillColor, Color backgroundColor); /// - /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface with the new geometry and fills it with the fill brush. + /// Resizes the with the given size and redraws the with the new geometry and fills it with the fill brush. /// - /// New size of the IGeometrySurface. - /// New CanvasGeometry to be applied to the IGeometrySurface. + /// New size of the . + /// New to be applied to the . /// Brush to fill the geometry. void Redraw(Size size, CanvasGeometry geometry, ICanvasBrush fillBrush); /// - /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface with the new geometry and fills it with the fill brush and fills the background with the background brush. + /// Resizes the with the given size and redraws the with the new geometry and fills it with the fill brush and fills the background with the background brush. /// - /// New size of the IGeometrySurface. - /// New CanvasGeometry to be applied to the IGeometrySurface. + /// New size of the . + /// New to be applied to the . /// Brush to fill the geometry. - /// Brush to fill the IGeometrySurface background. + /// Brush to fill the background. void Redraw(Size size, CanvasGeometry geometry, ICanvasBrush fillBrush, ICanvasBrush backgroundBrush); /// - /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface with the new geometry, outlines it with the given ICanvasStroke and + /// Resizes the with the given size and redraws the with the new geometry, outlines it with the given and /// fills it with the fill brush and fills the background with the background brush. /// - /// New size of the IGeometrySurface. - /// New CanvasGeometry to be applied to the IGeometrySurface. - /// ICanvasStroke defining the outline for the geometry. + /// New size of the . + /// New to be applied to the . + /// The defining the outline for the geometry. /// Brush to fill the geometry. - /// Brush to fill the IGeometrySurface background. + /// Brush to fill the background. void Redraw(Size size, CanvasGeometry geometry, ICanvasStroke stroke, ICanvasBrush fillBrush, ICanvasBrush backgroundBrush); /// - /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface with the new geometry and fills it with the fill brush and the background with the background color. + /// Resizes the with the given size and redraws the with the new geometry and fills it with the fill brush and the background with the background color. /// - /// New size of the IGeometrySurface. - /// New CanvasGeometry to be applied to the IGeometrySurface. + /// New size of the . + /// New to be applied to the . /// Brush to fill the geometry. - /// Fill color for the IGeometrySurface background. + /// Fill color for the background. void Redraw(Size size, CanvasGeometry geometry, ICanvasBrush fillBrush, Color backgroundColor); /// - /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface with the new geometry, outlines it with the given ICanvasStroke and + /// Resizes the with the given size and redraws the with the new geometry, outlines it with the given and /// fills it with the fill brush and the background with the background color. /// - /// New size of the IGeometrySurface. - /// New CanvasGeometry to be applied to the IGeometrySurface. - /// ICanvasStroke defining the outline for the geometry. + /// New size of the . + /// New to be applied to the . + /// The defining the outline for the geometry. /// Brush to fill the geometry. - /// Fill color for the IGeometrySurface background. + /// Fill color for the background. void Redraw(Size size, CanvasGeometry geometry, ICanvasStroke stroke, ICanvasBrush fillBrush, Color backgroundColor); /// - /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface with the new geometry and fills it with the fill color and the background with the background brush. + /// Resizes the with the given size and redraws the with the new geometry and fills it with the fill color and the background with the background brush. /// - /// New size of the IGeometrySurface. - /// New CanvasGeometry to be applied to the IGeometrySurface. + /// New size of the . + /// New to be applied to the . /// Fill color for the geometry. - /// Brush to fill the IGeometrySurface background. + /// Brush to fill the background. void Redraw(Size size, CanvasGeometry geometry, Color fillColor, ICanvasBrush backgroundBrush); /// - /// Resizes the IGeometrySurface with the given size and redraws the IGeometrySurface with the new geometry, outlines it with the given ICanvasStroke and + /// Resizes the with the given size and redraws the with the new geometry, outlines it with the given and /// fills it with the fill color and the background with the background brush. /// - /// New size of the IGeometrySurface. - /// New CanvasGeometry to be applied to the IGeometrySurface. - /// ICanvasStroke defining the outline for the geometry. + /// New size of the . + /// New to be applied to the . + /// The defining the outline for the geometry. /// Fill color for the geometry. - /// Brush to fill the IGeometrySurface background. + /// Brush to fill the background. void Redraw(Size size, CanvasGeometry geometry, ICanvasStroke stroke, Color fillColor, ICanvasBrush backgroundBrush); } } + +#pragma warning restore CS0419 // Ambiguous reference in cref attribute diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IImageMaskSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IImageMaskSurface.cs index c460ec324c0..8e8d184d92e 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IImageMaskSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IImageMaskSurface.cs @@ -6,144 +6,145 @@ using System.Threading.Tasks; using Microsoft.Graphics.Canvas; using Windows.Foundation; +using Windows.UI.Composition; using Windows.UI.Xaml; namespace Microsoft.Toolkit.Uwp.UI.Media { /// - /// Interface for rendering a mask, using an Image's alpha values, onto an ICompositionSurface. + /// Interface for rendering a mask, using an Image's alpha values, onto an . /// public interface IImageMaskSurface : IImageSurface { /// - /// Gets the padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. + /// Gets the padding between the outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. /// Thickness MaskPadding { get; } /// - /// Redraws the IImageMaskSurface using the given CanvasBitmap's alpha values with the given padding. + /// Redraws the using the given 's alpha values with the given padding. /// - /// ImageSurface whose image's alpha values are to be used to create the mask. - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. + /// whose image's alpha values are to be used to create the mask. + /// The padding between the outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. void Redraw(IImageSurface imageSurface, Thickness padding); /// - /// Redraws the IImageMaskSurface using the given CanvasBitmap's alpha values with the given padding using the given options. + /// Redraws the using the given 's alpha values with the given padding using the given options. /// - /// ImageSurface whose image's alpha values are to be used to create the mask. - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. + /// whose image's alpha values are to be used to create the mask. + /// The padding between the outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. /// Describes the image's resize, alignment and blur radius options in the allocated space. void Redraw(IImageSurface imageSurface, Thickness padding, ImageSurfaceOptions options); /// - /// Resizes and redraws the IImageMaskSurface using the given CanvasBitmap's alpha values with the given padding using the given options. + /// Resizes and redraws the using the given 's alpha values with the given padding using the given options. /// - /// ImageSurface whose image's alpha values are to be used to create the mask. - /// New size of the IImageMaskSurface. - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. + /// whose image's alpha values are to be used to create the mask. + /// New size of the . + /// The padding between the outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. /// Describes the image's resize, alignment and blur radius options in the allocated space. void Redraw(IImageSurface imageSurface, Size size, Thickness padding, ImageSurfaceOptions options); /// - /// Redraws the IImageMaskSurface using the given CanvasBitmap's alpha values with the given padding. + /// Redraws the using the given 's alpha values with the given padding. /// /// Image whose alpha values are to be used to create the mask. - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. + /// The padding between the outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. void Redraw(CanvasBitmap surfaceBitmap, Thickness padding); /// - /// Redraws the IImageMaskSurface using the given CanvasBitmap's alpha values with the given padding using the given options. + /// Redraws the using the given 's alpha values with the given padding using the given options. /// /// Image whose alpha values are to be used to create the mask. - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. + /// The padding between the outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. /// Describes the image's resize, alignment and blur radius options in the allocated space. void Redraw(CanvasBitmap surfaceBitmap, Thickness padding, ImageSurfaceOptions options); /// - /// Redraws the IImageMaskSurface using the alpha values of the image in the given IImageMaskSurface. + /// Redraws the using the alpha values of the image in the given . /// - /// IImageMaskSurface whose image's alpha values are to be used to create the mask. + /// whose image's alpha values are to be used to create the mask. void Redraw(IImageMaskSurface imageMaskSurface); /// - /// Redraws the IImageMaskSurface using the alpha values of the image in the given IImageMaskSurface with the given padding and options. + /// Redraws the using the alpha values of the image in the given with the given padding and options. /// - /// IImageMaskSurface whose image's alpha values are to be used to create the mask. - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. + /// whose image's alpha values are to be used to create the mask. + /// The padding between the outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. void Redraw(IImageMaskSurface imageMaskSurface, Thickness padding); /// - /// Redraws the IImageMaskSurface using the alpha values of the image in the given IImageMaskSurface with the given options. + /// Redraws the using the alpha values of the image in the given with the given options. /// - /// IImageMaskSurface whose image's alpha values are to be used to create the mask. + /// whose image's alpha values are to be used to create the mask. /// Describes the image's resize, alignment and blur radius options in the allocated space. void Redraw(IImageMaskSurface imageMaskSurface, ImageSurfaceOptions options); /// - /// Redraws the IImageMaskSurface using the alpha values of the image in the given IImageMaskSurface using the given padding and options. + /// Redraws the using the alpha values of the image in the given using the given padding and options. /// - /// IImageMaskSurface whose image's alpha values are to be used to create the mask. - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. + /// whose image's alpha values are to be used to create the mask. + /// The padding between the outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. /// Describes the image's resize, alignment and blur radius options in the allocated space. void Redraw(IImageMaskSurface imageMaskSurface, Thickness padding, ImageSurfaceOptions options); /// - /// Resizes and redraws the IImageMaskSurface using the alpha values of the image in the given IImageMaskSurface with the given padding and options. + /// Resizes and redraws the using the alpha values of the image in the given with the given padding and options. /// - /// IImageMaskSurface whose image's alpha values are to be used to create the mask. - /// New size of the IImageMaskSurface. - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. + /// whose image's alpha values are to be used to create the mask. + /// New size of the . + /// The padding between the outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. /// Describes the image's resize, alignment and blur radius options in the allocated space. void Redraw(IImageMaskSurface imageMaskSurface, Size size, Thickness padding, ImageSurfaceOptions options); /// - /// Resizes and redraws the IImageMaskSurface using the given CanvasBitmap's alpha values with the given padding using the given options. + /// Resizes and redraws the using the given 's alpha values with the given padding using the given options. /// - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. + /// The padding between the outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. /// Describes the image's resize, alignment and blur radius options in the allocated space. void Redraw(Thickness padding, ImageSurfaceOptions options); /// - /// Resizes and redraws the IImageMaskSurface using the given padding and image options. + /// Resizes and redraws the using the given padding and image options. /// - /// New size of the IImageMaskSurface. - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. + /// New size of the . + /// The padding between the outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. /// Describes the image's resize, alignment and blur radius options in the allocated space. void Redraw(Size size, Thickness padding, ImageSurfaceOptions options); /// - /// Resizes and redraws the IImageMaskSurface using the given CanvasBitmap's alpha values with the given padding using the given options. + /// Resizes and redraws the using the given 's alpha values with the given padding using the given options. /// /// Image whose alpha values are to be used to create the mask. - /// New size of the IImageMaskSurface. - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. + /// New size of the . + /// The padding between the outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. /// Describes the image's resize, alignment and blur radius options in the allocated space. void Redraw(CanvasBitmap surfaceBitmap, Size size, Thickness padding, ImageSurfaceOptions options); /// - /// Redraws the IImageMaskSurface by loading image from the new Uri and image options + /// Redraws the by loading image from the new and image options. /// /// Uri of the image to be loaded on to the image surface. - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. + /// The padding between the outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. /// Describes the image's resize, alignment and blur radius options in the allocated space. /// Task Task RedrawAsync(Uri uri, Thickness padding, ImageSurfaceOptions options); /// - /// Resizes the IImageMaskSurface with the given size and loads the image from the new Uri and uses its alpha values to redraw the IImageMaskSurface with the given padding using the given options. + /// Resizes the with the given size and loads the image from the new Uri and uses its alpha values to redraw the IImageMaskSurface with the given padding using the given options. /// - /// Uri of the image to be loaded onto the IImageMaskSurface. - /// New size of the IImageMaskSurface - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. + /// Uri of the image to be loaded onto the . + /// New size of the + /// The padding between the outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. /// Describes the image's resize, alignment and blur radius options in the allocated space. /// Task Task RedrawAsync(Uri uri, Size size, Thickness padding, ImageSurfaceOptions options); /// - /// Resizes the IImageMaskSurface to the new size and redraws it with the given padding using the given options. + /// Resizes the to the new size and redraws it with the given padding using the given options. /// - /// New size of the IImageMaskSurface - /// The padding between the IImageMaskSurface outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. + /// New size of the + /// The padding between the outer bounds and the bounds of the area where the mask, created from the loaded image's alpha values, should be rendered. /// The image's resize, alignment and blur radius options in the allocated space. void Resize(Size size, Thickness padding, ImageSurfaceOptions options); } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IImageSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IImageSurface.cs index 92387c15677..0552fafc2f1 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IImageSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IImageSurface.cs @@ -6,6 +6,7 @@ using System.Threading.Tasks; using Microsoft.Graphics.Canvas; using Windows.Foundation; +using Windows.UI.Composition; namespace Microsoft.Toolkit.Uwp.UI.Media { @@ -15,38 +16,39 @@ namespace Microsoft.Toolkit.Uwp.UI.Media public enum ImageSurfaceLoadStatus { /// - /// Indicates that no image has been loaded on the IImageSurface. + /// Indicates that no image has been loaded on the . /// None, /// - /// Indicates that the image was successfully loaded on the IImageSurface. + /// Indicates that the image was successfully loaded on the . /// Success, /// - /// Indicates that the image could not be loaded on the IImageSurface. + /// Indicates that the image could not be loaded on the . /// Error } /// - /// Interface for rendering an image onto an ICompositionSurface + /// Interface for rendering an image onto an /// public interface IImageSurface : IRenderSurface { /// - /// Event that is raised when the image has been downloaded, decoded and loaded to the underlying IImageSurface. This event fires regardless of success or failure. + /// Event that is raised when the image has been downloaded, decoded and loaded to the underlying . + /// This event fires regardless of success or failure. /// event TypedEventHandler LoadCompleted; /// - /// Gets the Uri of the image to be loaded onto the IImageSurface. + /// Gets the Uri of the image to be loaded onto the . /// Uri Uri { get; } /// - /// Gets the CanvasBitmap representing the loaded image. + /// Gets the representing the loaded image. /// CanvasBitmap SurfaceBitmap { get; } @@ -71,54 +73,54 @@ public interface IImageSurface : IRenderSurface ImageSurfaceLoadStatus Status { get; } /// - /// Redraws the IImageSurface or IImageMaskSurface with the given image options. + /// Redraws the with the given image options. /// /// The image's resize and alignment options in the allocated space. void Redraw(ImageSurfaceOptions options); /// - /// Resizes and redraws the IImageSurface using the given options. + /// Resizes and redraws the using the given options. /// - /// New size of the IImageMaskSurface. + /// New size of the . /// Describes the image's resize, alignment options in the allocated space. void Redraw(Size size, ImageSurfaceOptions options); /// - /// Redraws the IImageSurface (using the image in the given imageSurface) or the IImageMaskSurface (using the alpha values of image in the given imageSurface). + /// Redraws the (using the image in the given imageSurface) or the (using the alpha values of image in the given imageSurface). /// /// IImageSurface whose image is to be loaded on the surface. void Redraw(IImageSurface imageSurface); /// - /// Redraws the IImageSurface (using the given CanvasBitmap) or the IImageMaskSurface (using the given CanvasBitmap's alpha values) using the given options. + /// Redraws the (using the given ) or the (using the given 's alpha values) using the given options. /// - /// IImageSurface whose image is to be loaded on the surface. + /// whose image is to be loaded on the surface. /// Describes the image's resize, alignment options in the allocated space. void Redraw(IImageSurface imageSurface, ImageSurfaceOptions options); /// - /// Resizes and redraws the IImageSurface (using the given CanvasBitmap) or the IImageMaskSurface (using the given CanvasBitmap's alpha values) using the given options. + /// Resizes and redraws the (using the given ) or the (using the given 's alpha values) using the given options. /// - /// IImageSurface whose image is to be loaded on the surface. - /// New size of the IImageMaskSurface. + /// whose image is to be loaded on the surface. + /// New size of the . /// Describes the image's resize, alignment options in the allocated space. void Redraw(IImageSurface imageSurface, Size size, ImageSurfaceOptions options); /// - /// Redraws the IImageSurface (using the given CanvasBitmap) or the IImageMaskSurface (using the given CanvasBitmap's alpha values). + /// Redraws the (using the given ) or the (using the given 's alpha values). /// /// Image to be loaded on the surface. void Redraw(CanvasBitmap surfaceBitmap); /// - /// Redraws the IImageSurface (using the given CanvasBitmap) or the IImageMaskSurface (using the given CanvasBitmap's alpha values) using the given options. + /// Redraws the (using the given ) or the (using the given 's alpha values) using the given options. /// /// Image to be loaded on the surface. /// Describes the image's resize, alignment options in the allocated space. void Redraw(CanvasBitmap surfaceBitmap, ImageSurfaceOptions options); /// - /// Resizes and redraws the IImageSurface (using the given CanvasBitmap) or the IImageMaskSurface (using the given CanvasBitmap's alpha values) using the given options. + /// Resizes and redraws the (using the given ) or the (using the given 's alpha values) using the given options. /// /// Image to be loaded on the surface.. /// New size of the IImageMaskSurface. @@ -126,14 +128,14 @@ public interface IImageSurface : IRenderSurface void Redraw(CanvasBitmap surfaceBitmap, Size size, ImageSurfaceOptions options); /// - /// Redraws the IImageSurface or IImageMaskSurface by loading image from the new Uri. + /// Redraws the or by loading image from the new . /// /// Uri of the image to be loaded on to the surface. /// Task Task RedrawAsync(Uri uri); /// - /// Redraws the IImageSurface or IImageMaskSurface by loading image from the new Uri and applying the image options. + /// Redraws the or by loading image from the new and applying the image options. /// /// Uri of the image to be loaded on to the surface. /// The image's resize and alignment options in the allocated space. @@ -141,18 +143,18 @@ public interface IImageSurface : IRenderSurface Task RedrawAsync(Uri uri, ImageSurfaceOptions options); /// - /// Resizes the IImageSurface or IImageMaskSurface with the given size and redraws it by loading image from the new Uri. + /// Resizes the or with the given size and redraws it by loading image from the new Uri. /// - /// Uri of the image to be loaded onto the IImageSurface. - /// New size of the IImageSurface + /// Uri of the image to be loaded onto the . + /// New size of the /// The image's resize and alignment options in the allocated space. /// Task Task RedrawAsync(Uri uri, Size size, ImageSurfaceOptions options); /// - /// Resizes the IImageSurface or IImageMaskSurface to the new size with the given image options. + /// Resizes the or to the new size with the given image options. /// - /// New size of the IImageSurface + /// New size of the . /// The image's resize and alignment options in the allocated space. void Resize(Size size, ImageSurfaceOptions options); } diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IRenderSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IRenderSurface.cs index 99e48a90fee..b2d2d1d277b 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IRenderSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IRenderSurface.cs @@ -14,12 +14,12 @@ namespace Microsoft.Toolkit.Uwp.UI.Media public interface IRenderSurface : IDisposable { /// - /// Gets the CompositionGenerator. + /// Gets the . /// ICompositionGenerator Generator { get; } /// - /// Gets the Surface. + /// Gets the . /// ICompositionSurface Surface { get; } From 5bc41341094a0085d04fb910bf4c44564096c628 Mon Sep 17 00:00:00 2001 From: Ratish Philip Date: Sat, 24 Jul 2021 19:54:31 -0700 Subject: [PATCH 17/21] updated namespaces. Fixed CanvasPathGeometry file overwrite. --- .../CanvasPathGeometryPage.xaml.cs | 1 + .../GeometryMaskSurfaceBrushPage.xaml | 11 +-- .../GeometryMaskSurfaceBrushXaml.bind | 5 +- .../GeometrySurfaceBrushPage.xaml | 41 ++++++------ .../GeometrySurfaceBrushXaml.bind | 67 ++++++++++--------- .../Brushes/GeometryMaskSurfaceBrush.cs | 1 + .../Brushes/GeometrySurfaceBrush.cs | 7 +- .../Brushes/LinearGradientCanvasBrush.cs | 1 + .../Brushes/RadialGradientCanvasBrush.cs | 1 + .../Geometry/CanvasCircleGeometry.cs | 2 +- .../Geometry/CanvasCombinedGeometry.cs | 2 +- .../Geometry/CanvasCoreGeometry.cs | 2 +- .../CanvasDrawingSessionExtensions.cs | 2 +- .../Geometry/CanvasEllipseGeometry.cs | 2 +- .../Geometry/CanvasPathBuilderExtensions.cs | 2 +- .../Geometry/CanvasPathGeometry.cs | 2 +- .../Geometry/CanvasRectangleGeometry.cs | 2 +- .../CanvasRoundedRectangleGeometry.cs | 2 +- .../Geometry/CanvasSquircleGeometry.cs | 3 +- .../Geometry/CanvasStroke.cs | 2 +- .../Geometry/CompositorGeometryExtensions.cs | 2 +- .../Geometry/Core/CanvasRoundRect.cs | 2 +- .../Geometry/Core/GeometryTypeDefinitions.cs | 2 +- .../Geometry/Core/PathElementFactory.cs | 2 +- .../Geometry/Core/RegexFactory.cs | 2 +- .../Geometry/CultureShield.cs | 2 +- .../Brush/AbstractCanvasBrushElement.cs | 2 +- .../Elements/Brush/ICanvasBrushElement.cs | 2 +- .../Brush/LinearGradientBrushElement.cs | 2 +- .../Brush/LinearGradientHdrBrushElement.cs | 2 +- .../Brush/RadialGradientBrushElement.cs | 2 +- .../Brush/RadialGradientHdrBrushElement.cs | 2 +- .../Elements/Brush/SolidColorBrushElement.cs | 2 +- .../Elements/Path/AbstractPathElement.cs | 2 +- .../Geometry/Elements/Path/ArcElement.cs | 2 +- .../Elements/Path/CanvasEllipseFigure.cs | 2 +- .../Elements/Path/CanvasPathFigure.cs | 2 +- .../Elements/Path/CanvasPolygonFigure.cs | 3 +- .../Elements/Path/CanvasRectangleFigure.cs | 3 +- .../Path/CanvasRoundRectangleFigure.cs | 3 +- .../Elements/Path/ClosePathElement.cs | 2 +- .../Elements/Path/CubicBezierElement.cs | 2 +- .../Geometry/Elements/Path/FillRuleElement.cs | 2 +- .../Elements/Path/HorizontalLineElement.cs | 2 +- .../Elements/Path/ICanvasPathElement.cs | 2 +- .../Geometry/Elements/Path/LineElement.cs | 2 +- .../Geometry/Elements/Path/MoveToElement.cs | 2 +- .../Elements/Path/QuadraticBezierElement.cs | 2 +- .../Elements/Path/SmoothCubicBezierElement.cs | 3 +- .../Path/SmoothQuadraticBezierElement.cs | 3 +- .../Elements/Path/VerticalLineElement.cs | 2 +- .../Stroke/AbstractCanvasStrokeElement.cs | 2 +- .../Elements/Stroke/CanvasStrokeElement.cs | 2 +- .../Stroke/CanvasStrokeStyleElement.cs | 2 +- .../Elements/Stroke/ICanvasStrokeElement.cs | 2 +- .../Stroke/ICanvasStrokeStyleElement.cs | 2 +- .../Geometry/ICanvasPathGeometry.cs | 2 +- .../Geometry/ICanvasStroke.cs | 1 + .../Geometry/Parsers/CanvasBrushParser.cs | 2 +- .../Geometry/Parsers/CanvasGeometryParser.cs | 2 +- .../Geometry/Parsers/CanvasStrokeParser.cs | 2 +- .../Parsers/CanvasStrokeStyleParser.cs | 2 +- .../Geometry/Parsers/ColorParser.cs | 2 +- .../Geometry/Scalar.cs | 2 +- .../Geometry/StrokeStyle.cs | 2 +- .../Geometry/Utils.cs | 2 +- .../Surface/CompositionGenerator.cs | 2 +- .../Surface/CompositorExtensions.cs | 1 - .../Surface/GeometrySurface.cs | 1 + .../Surface/ImageMaskSurface.cs | 1 + .../Surface/ImageSurface.cs | 1 + .../Interfaces/ICompositionGenerator.cs | 1 + .../ICompositionGeneratorInternal.cs | 1 + .../Surface/Interfaces/IGeometrySurface.cs | 1 + .../Geometry/Test_CanvasPathGeometry.cs | 2 +- .../Geometry/Test_RegexFactory.cs | 2 +- .../UnitTests.UWP/Geometry/Test_Utils.cs | 2 +- 77 files changed, 145 insertions(+), 124 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/CanvasPathGeometry/CanvasPathGeometryPage.xaml.cs b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/CanvasPathGeometry/CanvasPathGeometryPage.xaml.cs index 0b1f869cb54..8015c596a70 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/CanvasPathGeometry/CanvasPathGeometryPage.xaml.cs +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/CanvasPathGeometry/CanvasPathGeometryPage.xaml.cs @@ -10,6 +10,7 @@ using Microsoft.Graphics.Canvas.UI.Xaml; using Microsoft.Toolkit.Uwp.UI; using Microsoft.Toolkit.Uwp.UI.Media; +using Microsoft.Toolkit.Uwp.UI.Media.Geometry; using Windows.System; using Windows.UI; using Windows.UI.Xaml; diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurfaceBrushPage.xaml b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurfaceBrushPage.xaml index 26e3149f315..7f0e3a59ca2 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurfaceBrushPage.xaml +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurfaceBrushPage.xaml @@ -1,7 +1,8 @@ - @@ -19,10 +20,10 @@ SurfaceWidth="899.25" /> - + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurfaceBrushXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurfaceBrushXaml.bind index d1efea8fbd2..f9261043039 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurfaceBrushXaml.bind +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometryMaskSurfaceBrush/GeometryMaskSurfaceBrushXaml.bind @@ -1,8 +1,9 @@ - @@ -18,7 +19,7 @@ SurfaceWidth="899.25" /> - diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushPage.xaml b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushPage.xaml index 37f614dbda2..9b1f4326ff7 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushPage.xaml +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushPage.xaml @@ -1,7 +1,8 @@ - @@ -10,33 +11,33 @@ + SurfaceWidth="800"> - + - + - + - - - - - - - - + + + + + + + + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushXaml.bind index 4af3816416d..3c6500ca1bf 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushXaml.bind +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushXaml.bind @@ -1,42 +1,43 @@ - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs index 5f231c3d717..df6f3c6703e 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs @@ -5,6 +5,7 @@ using System; using System.Numerics; using Microsoft.Toolkit.Uwp.Helpers; +using Microsoft.Toolkit.Uwp.UI.Media.Geometry; using Windows.Foundation; using Windows.UI.Composition; using Windows.UI.Core; diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometrySurfaceBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometrySurfaceBrush.cs index a570fab0870..2461c26c433 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometrySurfaceBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometrySurfaceBrush.cs @@ -6,6 +6,7 @@ using Microsoft.Graphics.Canvas.Brushes; using Microsoft.Graphics.Canvas.Geometry; using Microsoft.Toolkit.Uwp.Helpers; +using Microsoft.Toolkit.Uwp.UI.Media.Geometry; using Windows.Foundation; using Windows.UI; using Windows.UI.Core; @@ -364,17 +365,17 @@ protected override void OnSurfaceBrushUpdated(bool createSurface = false) var fillBrush = (FillBrush == null) ? transparentBrush : FillBrush.CanvasBrush; var bgBrush = (BackgroundBrush == null) ? transparentBrush : BackgroundBrush.CanvasBrush; var strokeStyle = (RenderStrokeStyle == null) ? new CanvasStrokeStyle() : RenderStrokeStyle.GetCanvasStrokeStyle(); - var canvasstroke = new CanvasStroke(strokeBrush, (float)StrokeThickness, strokeStyle); + var canvasStroke = new CanvasStroke(strokeBrush, (float)StrokeThickness, strokeStyle); if (createSurface || (RenderSurface == null)) { CompositionBrush?.Dispose(); - RenderSurface = Generator.CreateGeometrySurface(new Size(SurfaceWidth, SurfaceHeight), Geometry.Geometry, canvasstroke, fillBrush, bgBrush); + RenderSurface = Generator.CreateGeometrySurface(new Size(SurfaceWidth, SurfaceHeight), Geometry.Geometry, canvasStroke, fillBrush, bgBrush); CompositionBrush = Window.Current.Compositor.CreateSurfaceBrush(RenderSurface.Surface); } else { - ((IGeometrySurface)RenderSurface).Redraw(new Size(SurfaceWidth, SurfaceHeight), Geometry.Geometry, canvasstroke, fillBrush, bgBrush); + ((IGeometrySurface)RenderSurface).Redraw(new Size(SurfaceWidth, SurfaceHeight), Geometry.Geometry, canvasStroke, fillBrush, bgBrush); } base.OnSurfaceBrushUpdated(createSurface); diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/LinearGradientCanvasBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/LinearGradientCanvasBrush.cs index c29f1a11ac3..8d0e2261aa7 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/LinearGradientCanvasBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/LinearGradientCanvasBrush.cs @@ -6,6 +6,7 @@ using System.Numerics; using Microsoft.Graphics.Canvas; using Microsoft.Graphics.Canvas.Brushes; +using Microsoft.Toolkit.Uwp.UI.Media.Geometry; using Windows.Foundation; using Windows.UI.Xaml; using Windows.UI.Xaml.Markup; diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/RadialGradientCanvasBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/RadialGradientCanvasBrush.cs index a95fb493955..0adfab9934b 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/RadialGradientCanvasBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/RadialGradientCanvasBrush.cs @@ -6,6 +6,7 @@ using System.Numerics; using Microsoft.Graphics.Canvas; using Microsoft.Graphics.Canvas.Brushes; +using Microsoft.Toolkit.Uwp.UI.Media.Geometry; using Windows.Foundation; using Windows.UI.Xaml; using Windows.UI.Xaml.Markup; diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCircleGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCircleGeometry.cs index c084de6bbba..cf6d773dcf9 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCircleGeometry.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCircleGeometry.cs @@ -6,7 +6,7 @@ using Microsoft.Graphics.Canvas.Geometry; using Windows.UI.Xaml; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Represents a circle geometry object with the specified extents. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCombinedGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCombinedGeometry.cs index 30cc1a8eaf3..bdf9308ccc0 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCombinedGeometry.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCombinedGeometry.cs @@ -9,7 +9,7 @@ using Windows.UI.Xaml; using Windows.UI.Xaml.Media; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Represents a Geometry defined by the combination of two objects. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCoreGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCoreGeometry.cs index 02c47b37f1c..788e30b7ab7 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCoreGeometry.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasCoreGeometry.cs @@ -7,7 +7,7 @@ using Microsoft.Graphics.Canvas.Geometry; using Windows.UI.Xaml; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Provides a base class for objects that define geometric shapes using . diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasDrawingSessionExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasDrawingSessionExtensions.cs index b9f7480e993..c4f3a607916 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasDrawingSessionExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasDrawingSessionExtensions.cs @@ -9,7 +9,7 @@ using Windows.Foundation; using Windows.UI; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Extension methods for CanvasDrawingSession. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasEllipseGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasEllipseGeometry.cs index e3783c17b27..15d6cda6ca0 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasEllipseGeometry.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasEllipseGeometry.cs @@ -6,7 +6,7 @@ using Microsoft.Graphics.Canvas.Geometry; using Windows.UI.Xaml; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Represents an Ellipse geometry object with the specified extents. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasPathBuilderExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasPathBuilderExtensions.cs index 9ad3e630e0f..4bce7681c9b 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasPathBuilderExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasPathBuilderExtensions.cs @@ -8,7 +8,7 @@ using System.Numerics; using Microsoft.Graphics.Canvas.Geometry; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Defines extension methods for CanvasPathBuilder. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasPathGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasPathGeometry.cs index d011712bfa8..48a8318212f 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasPathGeometry.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasPathGeometry.cs @@ -12,7 +12,7 @@ using Windows.UI; using Windows.UI.Xaml; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Represents a complex vector-based shape geometry that may be composed of arcs, curves, ellipses, lines, rectangles, rounded rectangles, squircles. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasRectangleGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasRectangleGeometry.cs index b970952864a..c249ea4c654 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasRectangleGeometry.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasRectangleGeometry.cs @@ -5,7 +5,7 @@ using Microsoft.Graphics.Canvas.Geometry; using Windows.UI.Xaml; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Represents a rectangular geometry object with the specified extents. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasRoundedRectangleGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasRoundedRectangleGeometry.cs index 785e7f691ba..417dc487d23 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasRoundedRectangleGeometry.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasRoundedRectangleGeometry.cs @@ -5,7 +5,7 @@ using Microsoft.Graphics.Canvas.Geometry; using Windows.UI.Xaml; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Represents a rounded rectangle geometry object with the specified extents. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasSquircleGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasSquircleGeometry.cs index 8143199e060..f2dc25a9c36 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasSquircleGeometry.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasSquircleGeometry.cs @@ -2,9 +2,10 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using Microsoft.Toolkit.Uwp.UI.Media.Geometry; using Windows.UI.Xaml; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Represents a Squircle geometry object with the specified extents. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasStroke.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasStroke.cs index 26bf4f315ac..2b2655cd39b 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasStroke.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CanvasStroke.cs @@ -8,7 +8,7 @@ using Microsoft.Graphics.Canvas.Geometry; using Windows.UI; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Class to represent the Stroke which can be used to render an outline on a diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CompositorGeometryExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CompositorGeometryExtensions.cs index 092572c3180..c06592cbbb9 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CompositorGeometryExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CompositorGeometryExtensions.cs @@ -5,7 +5,7 @@ using Microsoft.Graphics.Canvas.Geometry; using Windows.UI.Composition; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Extension methods for compositor to support Win2d Path Mini Language. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/CanvasRoundRect.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/CanvasRoundRect.cs index cb88e297f27..44a1bc2b3a5 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/CanvasRoundRect.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/CanvasRoundRect.cs @@ -5,7 +5,7 @@ using System; using System.Numerics; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Structure which encapsulates the details of each of the core points of the path of the rounded rectangle which is calculated based on diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/GeometryTypeDefinitions.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/GeometryTypeDefinitions.cs index bf092bc090c..c7d4e63b36c 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/GeometryTypeDefinitions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/GeometryTypeDefinitions.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Enum for the various PathFigures. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/PathElementFactory.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/PathElementFactory.cs index b6fb880642a..aadd11a4311 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/PathElementFactory.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/PathElementFactory.cs @@ -5,7 +5,7 @@ using System; using System.Text.RegularExpressions; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Factory class to instantiate various PathElements. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/RegexFactory.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/RegexFactory.cs index 7a8f1ffcf62..92406b0611d 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/RegexFactory.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Core/RegexFactory.cs @@ -8,7 +8,7 @@ [assembly: InternalsVisibleTo("UnitTests.UWP")] -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Contains all the Regular Expressions which are used for parsing the Win2d Path Mini Language. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CultureShield.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CultureShield.cs index bdcc6053c74..702cd9d2c51 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CultureShield.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/CultureShield.cs @@ -4,7 +4,7 @@ using System.Globalization; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Class which can be used to encapsulate code statement(s) so that they are executed in a specific culture. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/AbstractCanvasBrushElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/AbstractCanvasBrushElement.cs index 6178802931c..f38c958faff 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/AbstractCanvasBrushElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/AbstractCanvasBrushElement.cs @@ -6,7 +6,7 @@ using Microsoft.Graphics.Canvas; using Microsoft.Graphics.Canvas.Brushes; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Abstract base class for all Brush Elements diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/ICanvasBrushElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/ICanvasBrushElement.cs index c248ead83f0..f51a2633df5 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/ICanvasBrushElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/ICanvasBrushElement.cs @@ -6,7 +6,7 @@ using Microsoft.Graphics.Canvas; using Microsoft.Graphics.Canvas.Brushes; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Interface for a Brush Element diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/LinearGradientBrushElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/LinearGradientBrushElement.cs index 56a2ddc6454..00249484980 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/LinearGradientBrushElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/LinearGradientBrushElement.cs @@ -11,7 +11,7 @@ using Microsoft.Graphics.Canvas.Brushes; using Windows.UI; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Represents a CanvasLinearGradientBrush with GradientStops diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/LinearGradientHdrBrushElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/LinearGradientHdrBrushElement.cs index 3d1bbee13c6..19c3d98a1f2 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/LinearGradientHdrBrushElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/LinearGradientHdrBrushElement.cs @@ -10,7 +10,7 @@ using Microsoft.Graphics.Canvas; using Microsoft.Graphics.Canvas.Brushes; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Represents a CanvasLinearGradientBrush with GradientStopHdrs diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/RadialGradientBrushElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/RadialGradientBrushElement.cs index 95dfbf6eb59..190e305645d 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/RadialGradientBrushElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/RadialGradientBrushElement.cs @@ -11,7 +11,7 @@ using Microsoft.Graphics.Canvas.Brushes; using Windows.UI; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Represents a CanvasRadialGradientBrush with GradientStops diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/RadialGradientHdrBrushElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/RadialGradientHdrBrushElement.cs index 463852211b2..0b947f155ec 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/RadialGradientHdrBrushElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/RadialGradientHdrBrushElement.cs @@ -10,7 +10,7 @@ using Microsoft.Graphics.Canvas; using Microsoft.Graphics.Canvas.Brushes; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Represents a CanvasRadialGradientBrush with GradientStopHdrs diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/SolidColorBrushElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/SolidColorBrushElement.cs index c8bff2e287a..feeedc9fa6f 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/SolidColorBrushElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Brush/SolidColorBrushElement.cs @@ -7,7 +7,7 @@ using Microsoft.Graphics.Canvas.Brushes; using Windows.UI; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Represents a CanvasSolidColorBrush diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/AbstractPathElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/AbstractPathElement.cs index d37b2b30f9f..02951aa6836 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/AbstractPathElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/AbstractPathElement.cs @@ -6,7 +6,7 @@ using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Abstract base class for all Path Elements diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/ArcElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/ArcElement.cs index f490949316d..ef9f4cc8951 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/ArcElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/ArcElement.cs @@ -7,7 +7,7 @@ using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Class representing the Arc Element in a Path Geometry diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasEllipseFigure.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasEllipseFigure.cs index 5e1eb541326..a4f769f3414 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasEllipseFigure.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasEllipseFigure.cs @@ -7,7 +7,7 @@ using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Class representing the Ellipse Figure in a Path Geometry diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasPathFigure.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasPathFigure.cs index b471bb7e0a9..40b63b19b0d 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasPathFigure.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasPathFigure.cs @@ -9,7 +9,7 @@ using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Class which contains a collection of ICanvasPathElements diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasPolygonFigure.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasPolygonFigure.cs index ae640cffd6d..c448d49688c 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasPolygonFigure.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasPolygonFigure.cs @@ -6,8 +6,9 @@ using System.Numerics; using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; +using Microsoft.Toolkit.Uwp.UI.Media.Geometry; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Class representing the Polygon Figure in a Path Geometry diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasRectangleFigure.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasRectangleFigure.cs index d197a557a70..c45569e3f32 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasRectangleFigure.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasRectangleFigure.cs @@ -6,8 +6,9 @@ using System.Numerics; using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; +using Microsoft.Toolkit.Uwp.UI.Media.Geometry; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Class representing the Rectangle Figure in a Path Geometry diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasRoundRectangleFigure.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasRoundRectangleFigure.cs index aa676571dd3..7e8e1e5b4ec 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasRoundRectangleFigure.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CanvasRoundRectangleFigure.cs @@ -6,8 +6,9 @@ using System.Numerics; using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; +using Microsoft.Toolkit.Uwp.UI.Media.Geometry; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Class representing the RoundRectangle Figure in a Path Geometry diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/ClosePathElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/ClosePathElement.cs index 8d40f6ef2aa..bcbf2fb938e 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/ClosePathElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/ClosePathElement.cs @@ -6,7 +6,7 @@ using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Class representing the ClosePath command in a Path Geometry diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CubicBezierElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CubicBezierElement.cs index b4e4b9243b6..708520b95eb 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CubicBezierElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/CubicBezierElement.cs @@ -6,7 +6,7 @@ using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Class representing the Cubic Bezier Element in a Path Geometry diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/FillRuleElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/FillRuleElement.cs index dcb9dcba1cd..40d7c332501 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/FillRuleElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/FillRuleElement.cs @@ -7,7 +7,7 @@ using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Class representing the Fill Rule Element in a Path Geometry diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/HorizontalLineElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/HorizontalLineElement.cs index d96ffa5d6c1..4dec26cacb4 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/HorizontalLineElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/HorizontalLineElement.cs @@ -6,7 +6,7 @@ using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Class representing the Horizontal Line Element in a Path Geometry diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/ICanvasPathElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/ICanvasPathElement.cs index 63e32e93700..f9cfcd283fd 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/ICanvasPathElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/ICanvasPathElement.cs @@ -6,7 +6,7 @@ using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Interface for a Path Element which serves diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/LineElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/LineElement.cs index bbc7a0a03c0..00e97dd3c09 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/LineElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/LineElement.cs @@ -6,7 +6,7 @@ using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Class representing the Line Element in a Path Geometry diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/MoveToElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/MoveToElement.cs index 541604c6582..64feb9d1721 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/MoveToElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/MoveToElement.cs @@ -6,7 +6,7 @@ using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Class representing the MoveTo Command in a Path Geometry diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/QuadraticBezierElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/QuadraticBezierElement.cs index feba2f290b7..46ea0a89915 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/QuadraticBezierElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/QuadraticBezierElement.cs @@ -6,7 +6,7 @@ using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Class representing the Quadratic Bezier Element in a Path Geometry diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/SmoothCubicBezierElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/SmoothCubicBezierElement.cs index 87a66bcdf01..1c16ec40fc5 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/SmoothCubicBezierElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/SmoothCubicBezierElement.cs @@ -5,8 +5,9 @@ using System.Numerics; using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; +using Microsoft.Toolkit.Uwp.UI.Media.Geometry; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Class representing the Smooth Cubic Bezier Element in a Path Geometry diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/SmoothQuadraticBezierElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/SmoothQuadraticBezierElement.cs index 97a0fd7bc7d..3d61b4fba57 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/SmoothQuadraticBezierElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/SmoothQuadraticBezierElement.cs @@ -5,8 +5,9 @@ using System.Numerics; using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; +using Microsoft.Toolkit.Uwp.UI.Media.Geometry; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Class representing the Smooth Quadratic Bezier Element in a Path Geometry diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/VerticalLineElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/VerticalLineElement.cs index 1a1c72cb53d..ea3efa3b923 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/VerticalLineElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Path/VerticalLineElement.cs @@ -6,7 +6,7 @@ using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Class representing the Vertical Line Element in a Path Geometry diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/AbstractCanvasStrokeElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/AbstractCanvasStrokeElement.cs index ee01409b48e..ff933b4b956 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/AbstractCanvasStrokeElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/AbstractCanvasStrokeElement.cs @@ -5,7 +5,7 @@ using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Abstract base class for Stroke Element. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/CanvasStrokeElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/CanvasStrokeElement.cs index 8d56f992234..cc20c7ab27a 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/CanvasStrokeElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/CanvasStrokeElement.cs @@ -6,7 +6,7 @@ using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Represents a Stroke Element. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/CanvasStrokeStyleElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/CanvasStrokeStyleElement.cs index f3994deeb23..aca39407bc2 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/CanvasStrokeStyleElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/CanvasStrokeStyleElement.cs @@ -8,7 +8,7 @@ using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Represents a CanvasStrokeStyle Element. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/ICanvasStrokeElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/ICanvasStrokeElement.cs index fb55dc3c192..c6d99fbd8d2 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/ICanvasStrokeElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/ICanvasStrokeElement.cs @@ -5,7 +5,7 @@ using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Interface for Stroke Element diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/ICanvasStrokeStyleElement.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/ICanvasStrokeStyleElement.cs index 61d5562d71a..71e25056cc0 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/ICanvasStrokeStyleElement.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Elements/Stroke/ICanvasStrokeStyleElement.cs @@ -5,7 +5,7 @@ using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Interface for the CanvasStrokeStyle Element diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/ICanvasPathGeometry.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/ICanvasPathGeometry.cs index 71cca7fe2ce..899096159f5 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/ICanvasPathGeometry.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/ICanvasPathGeometry.cs @@ -4,7 +4,7 @@ using Microsoft.Graphics.Canvas.Geometry; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { internal interface ICanvasPathGeometry { diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/ICanvasStroke.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/ICanvasStroke.cs index 3620d127840..74be76ca1ab 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/ICanvasStroke.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/ICanvasStroke.cs @@ -5,6 +5,7 @@ using System.Numerics; using Microsoft.Graphics.Canvas.Brushes; using Microsoft.Graphics.Canvas.Geometry; +using Microsoft.Toolkit.Uwp.UI.Media.Geometry; namespace Microsoft.Toolkit.Uwp.UI.Media { diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasBrushParser.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasBrushParser.cs index b89f2442a93..b4d478c75ba 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasBrushParser.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasBrushParser.cs @@ -7,7 +7,7 @@ using Microsoft.Graphics.Canvas; using Microsoft.Graphics.Canvas.Brushes; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Parser for ICanvasBrush. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasGeometryParser.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasGeometryParser.cs index 690ff25a61e..50c912e8757 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasGeometryParser.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasGeometryParser.cs @@ -11,7 +11,7 @@ using Microsoft.Graphics.Canvas; using Microsoft.Graphics.Canvas.Geometry; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Parser for CanvasGeometry. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasStrokeParser.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasStrokeParser.cs index 8764016f074..f9102b086a4 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasStrokeParser.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasStrokeParser.cs @@ -6,7 +6,7 @@ using System.Runtime.CompilerServices; using Microsoft.Graphics.Canvas; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Parser for CanvasStroke diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasStrokeStyleParser.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasStrokeStyleParser.cs index 46975902086..54b4be50608 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasStrokeStyleParser.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/CanvasStrokeStyleParser.cs @@ -7,7 +7,7 @@ using System.Text.RegularExpressions; using Microsoft.Graphics.Canvas.Geometry; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Parser for the CanvasStrokeStyle diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/ColorParser.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/ColorParser.cs index 3abb0b9cb77..a356fc9abed 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/ColorParser.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Parsers/ColorParser.cs @@ -8,7 +8,7 @@ using System.Text.RegularExpressions; using Windows.UI; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Parser for Color diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Scalar.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Scalar.cs index d1b561c0ddf..6067794e1a8 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Scalar.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Scalar.cs @@ -4,7 +4,7 @@ using System; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Class containing some constants diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/StrokeStyle.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/StrokeStyle.cs index 0415af082b1..c555501bbbe 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/StrokeStyle.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/StrokeStyle.cs @@ -8,7 +8,7 @@ using Microsoft.Graphics.Canvas.Geometry; using Windows.UI.Xaml; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Class which defines various properties which govern how the stroke is rendered. diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Utils.cs b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Utils.cs index b70af44d163..afbb05f730a 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Utils.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Geometry/Utils.cs @@ -9,7 +9,7 @@ using Windows.UI.Xaml; using Windows.UI.Xaml.Media; -namespace Microsoft.Toolkit.Uwp.UI.Media +namespace Microsoft.Toolkit.Uwp.UI.Media.Geometry { /// /// Class containing collection of useful methods for various types diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs index d3dd28442ca..25fc0e5d8ce 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositionGenerator.cs @@ -11,7 +11,7 @@ using Microsoft.Graphics.Canvas.Effects; using Microsoft.Graphics.Canvas.Geometry; using Microsoft.Graphics.Canvas.UI.Composition; -using Microsoft.Toolkit.Uwp.UI.Media; +using Microsoft.Toolkit.Uwp.UI.Media.Geometry; using Windows.Foundation; using Windows.Graphics.DirectX; using Windows.UI; diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositorExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositorExtensions.cs index 4a900e7d37a..e12294c1b23 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositorExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositorExtensions.cs @@ -5,7 +5,6 @@ using System; using Microsoft.Graphics.Canvas; using Microsoft.Graphics.Canvas.Effects; -using Microsoft.Toolkit.Uwp.UI.Media.Pipelines; using Windows.UI; using Windows.UI.Composition; using Windows.UI.Xaml.Media; diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometrySurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometrySurface.cs index a4418f96641..bdadaffeb0e 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometrySurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/GeometrySurface.cs @@ -5,6 +5,7 @@ using System; using Microsoft.Graphics.Canvas.Brushes; using Microsoft.Graphics.Canvas.Geometry; +using Microsoft.Toolkit.Uwp.UI.Media.Geometry; using Windows.Foundation; using Windows.UI; using Windows.UI.Composition; diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageMaskSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageMaskSurface.cs index 4fa8bd31263..8784a2cc4b9 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageMaskSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageMaskSurface.cs @@ -5,6 +5,7 @@ using System; using System.Threading.Tasks; using Microsoft.Graphics.Canvas; +using Microsoft.Toolkit.Uwp.UI.Media.Geometry; using Windows.Foundation; using Windows.UI.Composition; using Windows.UI.Xaml; diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurface.cs index edc7d587a3f..665dbafd703 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/ImageSurface.cs @@ -5,6 +5,7 @@ using System; using System.Threading.Tasks; using Microsoft.Graphics.Canvas; +using Microsoft.Toolkit.Uwp.UI.Media.Geometry; using Windows.Foundation; using Windows.UI.Composition; diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/ICompositionGenerator.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/ICompositionGenerator.cs index 77180410434..413f9ff9378 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/ICompositionGenerator.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/ICompositionGenerator.cs @@ -8,6 +8,7 @@ using Microsoft.Graphics.Canvas; using Microsoft.Graphics.Canvas.Brushes; using Microsoft.Graphics.Canvas.Geometry; +using Microsoft.Toolkit.Uwp.UI.Media.Geometry; using Windows.Foundation; using Windows.UI; using Windows.UI.Composition; diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/ICompositionGeneratorInternal.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/ICompositionGeneratorInternal.cs index cbc47cac6a3..82ce6e0c99e 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/ICompositionGeneratorInternal.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/ICompositionGeneratorInternal.cs @@ -8,6 +8,7 @@ using Microsoft.Graphics.Canvas; using Microsoft.Graphics.Canvas.Brushes; using Microsoft.Graphics.Canvas.Geometry; +using Microsoft.Toolkit.Uwp.UI.Media.Geometry; using Windows.Foundation; using Windows.UI.Composition; using Windows.UI.Xaml; diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IGeometrySurface.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IGeometrySurface.cs index 0facb7a41a2..2e5dd7c773d 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IGeometrySurface.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/Interfaces/IGeometrySurface.cs @@ -6,6 +6,7 @@ using Microsoft.Graphics.Canvas.Brushes; using Microsoft.Graphics.Canvas.Geometry; +using Microsoft.Toolkit.Uwp.UI.Media.Geometry; using Windows.Foundation; using Windows.UI; diff --git a/UnitTests/UnitTests.UWP/Geometry/Test_CanvasPathGeometry.cs b/UnitTests/UnitTests.UWP/Geometry/Test_CanvasPathGeometry.cs index 986b67f4fe0..b82dc9d0865 100644 --- a/UnitTests/UnitTests.UWP/Geometry/Test_CanvasPathGeometry.cs +++ b/UnitTests/UnitTests.UWP/Geometry/Test_CanvasPathGeometry.cs @@ -6,7 +6,7 @@ using System.Numerics; using Microsoft.Graphics.Canvas; using Microsoft.Graphics.Canvas.Geometry; -using Microsoft.Toolkit.Uwp.UI.Media; +using Microsoft.Toolkit.Uwp.UI.Media.Geometry; using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting.AppContainer; diff --git a/UnitTests/UnitTests.UWP/Geometry/Test_RegexFactory.cs b/UnitTests/UnitTests.UWP/Geometry/Test_RegexFactory.cs index a93ef0f1a2c..bba3dd22567 100644 --- a/UnitTests/UnitTests.UWP/Geometry/Test_RegexFactory.cs +++ b/UnitTests/UnitTests.UWP/Geometry/Test_RegexFactory.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using Microsoft.Toolkit.Uwp.UI.Media; +using Microsoft.Toolkit.Uwp.UI.Media.Geometry; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace UnitTests.UWP.Geometry diff --git a/UnitTests/UnitTests.UWP/Geometry/Test_Utils.cs b/UnitTests/UnitTests.UWP/Geometry/Test_Utils.cs index c2122064578..80dde13c7aa 100644 --- a/UnitTests/UnitTests.UWP/Geometry/Test_Utils.cs +++ b/UnitTests/UnitTests.UWP/Geometry/Test_Utils.cs @@ -8,7 +8,7 @@ using Windows.UI; using Windows.UI.Xaml; using Windows.UI.Xaml.Media; -using Microsoft.Toolkit.Uwp.UI.Media; +using Microsoft.Toolkit.Uwp.UI.Media.Geometry; using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting.AppContainer; From 027b8ce1a24ce410b294ee6c0ffc42876b4a62c9 Mon Sep 17 00:00:00 2001 From: Ratish Philip Date: Sat, 24 Jul 2021 20:04:20 -0700 Subject: [PATCH 18/21] Changed Dispatcher.RunAsync to DispatcherQueue.GetForCurrentThread().EnqueueAsync --- .../Brushes/GeometryMaskSurfaceBrush.cs | 5 +++-- .../Brushes/GeometrySurfaceBrush.cs | 11 ++++++----- .../Brushes/ImageMaskSurfaceBrush.cs | 5 +++-- .../Brushes/ImageSurfaceBrush.cs | 3 ++- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs index df6f3c6703e..27b013dfbbb 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs @@ -7,6 +7,7 @@ using Microsoft.Toolkit.Uwp.Helpers; using Microsoft.Toolkit.Uwp.UI.Media.Geometry; using Windows.Foundation; +using Windows.System; using Windows.UI.Composition; using Windows.UI.Core; using Windows.UI.Xaml; @@ -66,7 +67,7 @@ private void OnTargetChanged() { OnEventAction = async (instance, source, args) => { - await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => + await DispatcherQueue.GetForCurrentThread().EnqueueAsync(() => { OnSurfaceBrushUpdated(); }); @@ -122,7 +123,7 @@ private void OnMaskChanged() { OnEventAction = async (instance, source, args) => { - await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => + await DispatcherQueue.GetForCurrentThread().EnqueueAsync(() => { OnSurfaceBrushUpdated(); }); diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometrySurfaceBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometrySurfaceBrush.cs index 2461c26c433..6760a63b2b4 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometrySurfaceBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometrySurfaceBrush.cs @@ -8,6 +8,7 @@ using Microsoft.Toolkit.Uwp.Helpers; using Microsoft.Toolkit.Uwp.UI.Media.Geometry; using Windows.Foundation; +using Windows.System; using Windows.UI; using Windows.UI.Core; using Windows.UI.Xaml; @@ -68,7 +69,7 @@ private void OnGeometryChanged() { OnEventAction = async (instance, source, args) => { - await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => + await DispatcherQueue.GetForCurrentThread().EnqueueAsync(() => { OnSurfaceBrushUpdated(); }); @@ -124,7 +125,7 @@ private void OnStrokeChanged() { OnEventAction = async (instance, source, args) => { - await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => + await DispatcherQueue.GetForCurrentThread().EnqueueAsync(() => { OnSurfaceBrushUpdated(); }); @@ -222,7 +223,7 @@ private void OnRenderStrokeStyleChanged() { OnEventAction = async (instance, source, args) => { - await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => + await DispatcherQueue.GetForCurrentThread().EnqueueAsync(() => { OnSurfaceBrushUpdated(); }); @@ -278,7 +279,7 @@ private void OnFillBrushChanged() { OnEventAction = async (instance, source, args) => { - await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => + await DispatcherQueue.GetForCurrentThread().EnqueueAsync(() => { OnSurfaceBrushUpdated(); }); @@ -334,7 +335,7 @@ private void OnBackgroundBrushChanged() { OnEventAction = async (instance, source, args) => { - await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => + await DispatcherQueue.GetForCurrentThread().EnqueueAsync(() => { OnSurfaceBrushUpdated(); }); diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageMaskSurfaceBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageMaskSurfaceBrush.cs index 42c672996e8..b61f76d9b7a 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageMaskSurfaceBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageMaskSurfaceBrush.cs @@ -5,6 +5,7 @@ using System; using Microsoft.Toolkit.Uwp.Helpers; using Windows.Foundation; +using Windows.System; using Windows.UI.Composition; using Windows.UI.Core; using Windows.UI.Xaml; @@ -65,7 +66,7 @@ private void OnTargetChanged() { OnEventAction = async (instance, source, args) => { - await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => + await DispatcherQueue.GetForCurrentThread().EnqueueAsync(() => { OnSurfaceBrushUpdated(true); }); @@ -181,7 +182,7 @@ private void OnImageOptionsChanged() { OnEventAction = async (instance, source, args) => { - await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => + await DispatcherQueue.GetForCurrentThread().EnqueueAsync(() => { OnSurfaceBrushUpdated(); }); diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageSurfaceBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageSurfaceBrush.cs index f7b399fdab3..e0dc01a78f8 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageSurfaceBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageSurfaceBrush.cs @@ -5,6 +5,7 @@ using System; using Microsoft.Toolkit.Uwp.Helpers; using Windows.Foundation; +using Windows.System; using Windows.UI; using Windows.UI.Core; using Windows.UI.Xaml; @@ -161,7 +162,7 @@ private void OnImageOptionsChanged() { OnEventAction = async (instance, source, args) => { - await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => + await DispatcherQueue.GetForCurrentThread().EnqueueAsync(() => { OnSurfaceBrushUpdated(); }); From 4ac882dce5c6ba425d3b4adec1cbe90cb27ab124 Mon Sep 17 00:00:00 2001 From: Ratish Philip Date: Mon, 6 Sep 2021 06:48:03 -0700 Subject: [PATCH 19/21] updated comments, removed unwanted using. --- .../Brushes/GeometryMaskSurfaceBrush.cs | 1 - Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometrySurfaceBrush.cs | 3 +-- .../Brushes/ImageMaskSurfaceBrush.cs | 1 - Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageSurfaceBrush.cs | 3 +-- 4 files changed, 2 insertions(+), 6 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs index 27b013dfbbb..929c2af656e 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs @@ -9,7 +9,6 @@ using Windows.Foundation; using Windows.System; using Windows.UI.Composition; -using Windows.UI.Core; using Windows.UI.Xaml; namespace Microsoft.Toolkit.Uwp.UI.Media diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometrySurfaceBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometrySurfaceBrush.cs index 6760a63b2b4..be803da5dc8 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometrySurfaceBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometrySurfaceBrush.cs @@ -10,7 +10,6 @@ using Windows.Foundation; using Windows.System; using Windows.UI; -using Windows.UI.Core; using Windows.UI.Xaml; namespace Microsoft.Toolkit.Uwp.UI.Media @@ -36,7 +35,7 @@ public sealed class GeometrySurfaceBrush : RenderSurfaceBrushBase new PropertyMetadata(null, OnGeometryChanged)); /// - /// Gets or sets the that is used to create the mask. + /// Gets or sets the that is used to paint the surface of the brush. /// public CanvasCoreGeometry Geometry { diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageMaskSurfaceBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageMaskSurfaceBrush.cs index b61f76d9b7a..61f1237aed2 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageMaskSurfaceBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageMaskSurfaceBrush.cs @@ -7,7 +7,6 @@ using Windows.Foundation; using Windows.System; using Windows.UI.Composition; -using Windows.UI.Core; using Windows.UI.Xaml; namespace Microsoft.Toolkit.Uwp.UI.Media diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageSurfaceBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageSurfaceBrush.cs index e0dc01a78f8..6f6a4c46841 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageSurfaceBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/ImageSurfaceBrush.cs @@ -7,7 +7,6 @@ using Windows.Foundation; using Windows.System; using Windows.UI; -using Windows.UI.Core; using Windows.UI.Xaml; namespace Microsoft.Toolkit.Uwp.UI.Media @@ -68,7 +67,7 @@ private void OnBackgroundChanged() new PropertyMetadata(null, OnSourceChanged)); /// - /// Gets or sets the the . + /// Gets or sets the object representing the image source. /// public object Source { From ca7db913ec3e7fe981cdcad6cb43e4d00e7c18dc Mon Sep 17 00:00:00 2001 From: Ratish Philip Date: Thu, 9 Sep 2021 10:50:22 -0700 Subject: [PATCH 20/21] minor update (comments and bind file) --- .../GeometrySurfaceBrush/GeometrySurfaceBrushXaml.bind | 2 +- .../Brushes/GeometryMaskSurfaceBrush.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushXaml.bind index 3c6500ca1bf..b2e26d667b3 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushXaml.bind +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/GeometrySurfaceBrush/GeometrySurfaceBrushXaml.bind @@ -13,7 +13,7 @@ SurfaceHeight="800" SurfaceWidth="800"> - + diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs index 929c2af656e..80b77351e51 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Brushes/GeometryMaskSurfaceBrush.cs @@ -181,7 +181,7 @@ public double OffsetY new PropertyMetadata(0d, OnPropertyChanged)); /// - /// Gets or sets the radius of Gaussian Blur to be applied on the brush. + /// Gets or sets the radius of Gaussian Blur to be applied on the mask. /// public double BlurRadius { From 8a4610c0d7f1cd3eb04f2e70aaaf852e82874a7a Mon Sep 17 00:00:00 2001 From: Ratish Philip Date: Sun, 12 Sep 2021 16:57:47 -0700 Subject: [PATCH 21/21] Updated the effect name. --- .../Surface/CompositorExtensions.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositorExtensions.cs b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositorExtensions.cs index e12294c1b23..578344d6195 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositorExtensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Surface/CompositorExtensions.cs @@ -58,10 +58,10 @@ public static CompositionEffectBrush CreateGaussianMaskedBackdropBrush(this Comp /// /// Creates a custom shaped Effect Brush using BackdropBrush and an or an . /// - /// Compositor - /// IGeometryMaskSurface or IGaussianMaskSurface - /// Color to blend in the BackdropBrush - /// Blur Amount of the Backdrop Brush + /// Compositor. + /// or . + /// Color to blend in the BackdropBrush. + /// Blur Amount of the Backdrop Brush. /// Backdrop Brush (optional). If not provided, then compositor creates it. /// CompositionEffectBrush internal static CompositionEffectBrush CreateBackdropBrush(Compositor compositor, IRenderSurface mask, Color blendColor, float blurAmount, CompositionBackdropBrush backdropBrush = null) @@ -100,7 +100,7 @@ internal static CompositionEffectBrush CreateBackdropBrush(Compositor compositor }; // Create Effect Factory - var factory = compositor.CreateEffectFactory(effect, new[] { "Blur.BlurAmount", "Color.Color" }); + var factory = compositor.CreateEffectFactory(effect, new[] { $"Blur.{nameof(GaussianBlurEffect.BlurAmount)}", $"Color.{nameof(ColorSourceEffect.Color)}" }); // Create Effect Brush var brush = factory.CreateBrush(); @@ -172,7 +172,7 @@ public static CompositionEffectBrush CreateFrostedGlassBrush( }; // Create Effect Factory - var factory = compositor.CreateEffectFactory(effect, new[] { "Blur.BlurAmount", "BlendColor.Color" }); + var factory = compositor.CreateEffectFactory(effect, new[] { $"Blur.{nameof(GaussianBlurEffect.BlurAmount)}", $"BlendColor.{nameof(ColorSourceEffect.Color)}" }); // Create Effect Brush var brush = factory.CreateBrush();