Anti-alias the edges of masks and mattes for a smoother result. (#176)

* Anti-alias the edges of masks and mattes for a smoother result.

The default BorderMode for Visuals is Inherit, and if not specified the value Hard (i.e. not anti-aliased) is passed into the root.
The default worked for us previously because the desktop tree sets the BorderMode to Soft and we inherit it so we got Soft behavior everywhere.
However the trees created for masks and mattes are not rooted in the desktop, so they were getting set to Hard and some edges looked aliased.

This change adds the ability to set the BorderMode and sets it to Soft for the trees created for masks and mattes.

* Improve comments.
This commit is contained in:
Simeon 2019-10-29 21:52:59 -07:00 коммит произвёл GitHub
Родитель d39062f746
Коммит f2a026ce8f
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
9 изменённых файлов: 81 добавлений и 3 удалений

Просмотреть файл

@ -15,7 +15,6 @@ using Mgc = Microsoft.Graphics.Canvas;
using Mgce = Microsoft.Graphics.Canvas.Effects;
using Wc = Windows.UI.Composition;
using Wd = Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData;
using Wge = Windows.Graphics.Effects;
using Wm = Windows.UI.Xaml.Media;
using Wmd = Microsoft.Toolkit.Uwp.UI.Lottie.WinUIXamlMediaData;
@ -173,9 +172,9 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie
{
CacheAndInitializeCompositionObject(source, target);
if (source.Clip != null)
if (source.BorderMode.HasValue)
{
target.Clip = GetCompositionClip(source.Clip);
target.BorderMode = BorderMode(source.BorderMode.Value);
}
if (source.CenterPoint.HasValue)
@ -183,6 +182,11 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie
target.CenterPoint = source.CenterPoint.Value;
}
if (source.Clip != null)
{
target.Clip = GetCompositionClip(source.Clip);
}
if (source.Offset.HasValue)
{
target.Offset = source.Offset.Value;
@ -1394,6 +1398,17 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie
return result;
}
static Wc.CompositionBorderMode BorderMode(Wd.CompositionBorderMode value)
{
switch (value)
{
case Wd.CompositionBorderMode.Hard: return Wc.CompositionBorderMode.Hard;
case Wd.CompositionBorderMode.Inherit: return Wc.CompositionBorderMode.Inherit;
case Wd.CompositionBorderMode.Soft: return Wc.CompositionBorderMode.Soft;
default: throw new InvalidOperationException();
}
}
static Wc.CompositionStrokeLineJoin StrokeLineJoin(Wd.CompositionStrokeLineJoin value)
{
switch (value)

Просмотреть файл

@ -670,9 +670,21 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.LottieToWinComp
// the visual we want captured by the visual surface has a parent to use as the
// origin of its offsets.
var sourceIntermediateParent = _c.CreateContainerVisual();
// Because this is the root of a tree, the inherited BorderMode is Hard.
// We want it to be Soft in order to enable anti-aliasing.
// Note that the border mode for trees that are attached to the desktop do not
// need to have their BorderMode set as they inherit Soft from the desktop.
sourceIntermediateParent.BorderMode = CompositionBorderMode.Soft;
sourceIntermediateParent.Children.Add(source);
var destinationIntermediateParent = _c.CreateContainerVisual();
// Because this is the root of a tree, the inherited BorderMode is Hard.
// We want it to be Soft in order to enable anti-aliasing.
// Note that the border mode for trees that are attached to the desktop do not
// need to have their BorderMode set as they inherit Soft from the desktop.
destinationIntermediateParent.BorderMode = CompositionBorderMode.Soft;
destinationIntermediateParent.Children.Add(destination);
var sourceVisualSurface = _c.CreateVisualSurface();

Просмотреть файл

@ -665,6 +665,8 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
string Vector3(Vector3 value) => _stringifier.Vector3(value);
string BorderMode(CompositionBorderMode value) => _stringifier.BorderMode(value);
string ColorSpace(CompositionColorSpace value) => _stringifier.ColorSpace(value);
string ExtendMode(CompositionGradientExtendMode value) => _stringifier.ExtendMode(value);
@ -1264,6 +1266,11 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
{
InitializeCompositionObject(builder, obj, node);
if (obj.BorderMode.HasValue)
{
builder.WriteLine($"result{Deref}BorderMode = {BorderMode(obj.BorderMode.Value)};");
}
if (obj.CenterPoint.HasValue)
{
builder.WriteLine($"result{Deref}CenterPoint = {Vector3(obj.CenterPoint.Value)};");

Просмотреть файл

@ -173,11 +173,13 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
where T : Visual
{
CacheAndInitializeCompositionObject(source, target);
if (source.Clip != null)
{
target.Clip = GetCompositionClip(source.Clip);
}
target.BorderMode = source.BorderMode;
target.CenterPoint = source.CenterPoint;
target.Offset = source.Offset;
target.Opacity = source.Opacity;

Просмотреть файл

@ -79,6 +79,18 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.UIData.CodeGen
public virtual string ByteArray => "byte[]";
public string BorderMode(CompositionBorderMode value)
{
var typeName = nameof(CompositionBorderMode);
switch (value)
{
case CompositionBorderMode.Hard: return $"{typeName}{ScopeResolve}{nameof(CompositionBorderMode.Hard)}";
case CompositionBorderMode.Soft: return $"{typeName}{ScopeResolve}{nameof(CompositionBorderMode.Soft)}";
case CompositionBorderMode.Inherit: return $"{typeName}{ScopeResolve}{nameof(CompositionBorderMode.Inherit)}";
default: throw new InvalidOperationException();
}
}
public virtual string CanvasFigureLoop(CanvasFigureLoop value)
{
var typeName = nameof(CanvasFigureLoop);

Просмотреть файл

@ -0,0 +1,17 @@
// 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.Lottie.WinCompData
{
[MetaData.UapVersion(2)]
#if PUBLIC_WinCompData
public
#endif
enum CompositionBorderMode
{
Inherit = 0,
Soft = 1,
Hard = 2,
}
}

Просмотреть файл

@ -572,6 +572,11 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData.Tools
yield return FromVector2DefaultZero(nameof(obj.Size), obj.Size);
if (obj.BorderMode.HasValue)
{
yield return new XAttribute(nameof(obj.BorderMode), obj.BorderMode.Value);
}
foreach (var item in FromAnimatableVector3("Offset", obj.Animators, obj.Offset))
{
yield return item;

Просмотреть файл

@ -16,6 +16,13 @@ namespace Microsoft.Toolkit.Uwp.UI.Lottie.WinCompData
{
}
// Defaults to Inherit.
// Note that trees rooted by the desktop have Soft passed into them so
// they inherit Soft unless overridden.
// Non-rooted trees have Hard passed into them so they inherit Hard unless
// overridden.
public CompositionBorderMode? BorderMode { get; set; }
public Vector3? CenterPoint { get; set; }
public CompositionClip Clip { get; set; }

Просмотреть файл

@ -9,6 +9,7 @@
<Compile Include="$(MSBuildThisFileDirectory)AnimationController.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ColorKeyFrameAnimation.cs" />
<Compile Include="$(MSBuildThisFileDirectory)CompositionAnimation.cs" />
<Compile Include="$(MSBuildThisFileDirectory)CompositionBorderMode.cs" />
<Compile Include="$(MSBuildThisFileDirectory)CompositionBrush.cs" />
<Compile Include="$(MSBuildThisFileDirectory)CompositionClip.cs" />
<Compile Include="$(MSBuildThisFileDirectory)CompositionColorBrush.cs" />