diff --git a/source/Lottie/Loader.cs b/source/Lottie/Loader.cs index 648207fb..20c2ca74 100644 --- a/source/Lottie/Loader.cs +++ b/source/Lottie/Loader.cs @@ -12,6 +12,7 @@ using System.Threading.Tasks; using Microsoft.Toolkit.Uwp.UI.Lottie.CompMetadata; using Microsoft.Toolkit.Uwp.UI.Lottie.LottieData; +using Microsoft.Toolkit.Uwp.UI.Lottie.LottieData.Optimization; using Microsoft.Toolkit.Uwp.UI.Lottie.LottieData.Serialization; using Microsoft.Toolkit.Uwp.UI.Lottie.LottieToWinComp; using Windows.Foundation.Metadata; @@ -84,6 +85,11 @@ await Task.Run(() => LottieCompositionReader.Options.IgnoreMatchNames, out var readerIssues); + if (lottieComposition is not null) + { + lottieComposition = LottieMergeOptimizer.Optimize(lottieComposition); + } + if (diagnostics is not null) { diagnostics.JsonParsingIssues = ToIssues(readerIssues); diff --git a/source/LottieData/Optimization/Experimental/MergeHelper.cs b/source/LottieData/Optimization/Experimental/MergeHelper.cs index f3b1a3ab..3f5c8bde 100644 --- a/source/LottieData/Optimization/Experimental/MergeHelper.cs +++ b/source/LottieData/Optimization/Experimental/MergeHelper.cs @@ -374,6 +374,82 @@ MergeResult MergePaths(Path a, TimeRange aRange, Path b, TimeRange bRange) return new MergeResult(new Path(args, a.DrawingDirection, geometryData.Value!)); } + MergeResult MergeRectangles(Rectangle a, TimeRange aRange, Rectangle b, TimeRange bRange) + { + if (a.BlendMode != b.BlendMode || a.DrawingDirection != b.DrawingDirection) + { + return MergeResult.Failed; + } + + var args = new ShapeLayerContentArgs + { + Name = $"{a.Name} {b.Name}", + MatchName = $"{a.MatchName}{b.MatchName}", + BlendMode = a.BlendMode, + }; + + var position = MergeIAnimatableVector3(a.Position, aRange, b.Position, bRange); + var size = MergeIAnimatableVector3(a.Size, aRange, b.Size, bRange); + var roundness = MergeAnimatable(a.Roundness, aRange, b.Roundness, bRange); + + if (!position.Success || !size.Success || !roundness.Success) + { + return MergeResult.Failed; + } + + return new MergeResult(new Rectangle(args, a.DrawingDirection, position.Value!, size.Value!, roundness.Value!)); + } + + MergeResult MergeTrimPaths(TrimPath a, TimeRange aRange, TrimPath b, TimeRange bRange) + { + if (a.BlendMode != b.BlendMode || a.TrimPathType != b.TrimPathType) + { + return MergeResult.Failed; + } + + var args = new ShapeLayerContentArgs + { + Name = $"{a.Name} {b.Name}", + MatchName = $"{a.MatchName}{b.MatchName}", + BlendMode = a.BlendMode, + }; + + var start = MergeAnimatable(a.Start, aRange, b.Start, bRange); + var end = MergeAnimatable(a.End, aRange, b.End, bRange); + var offset = MergeAnimatable(a.Offset, aRange, b.Offset, bRange); + + if (!start.Success || !end.Success || !offset.Success) + { + return MergeResult.Failed; + } + + return new MergeResult(new TrimPath(args, a.TrimPathType, start.Value!, end.Value!, offset.Value!)); + } + + MergeResult MergeRoundCorners(RoundCorners a, TimeRange aRange, RoundCorners b, TimeRange bRange) + { + if (a.BlendMode != b.BlendMode) + { + return MergeResult.Failed; + } + + var args = new ShapeLayerContentArgs + { + Name = $"{a.Name} {b.Name}", + MatchName = $"{a.MatchName}{b.MatchName}", + BlendMode = a.BlendMode, + }; + + var radius = MergeAnimatable(a.Radius, aRange, b.Radius, bRange); + + if (!radius.Success) + { + return MergeResult.Failed; + } + + return new MergeResult(new RoundCorners(args, radius.Value!)); + } + MergeResult MergeEllipses(Ellipse a, TimeRange aRange, Ellipse b, TimeRange bRange) { if (a.BlendMode != b.BlendMode || a.DrawingDirection != b.DrawingDirection) @@ -508,20 +584,26 @@ MergeResult MergeShapeLayerContents(ShapeLayerContent a, Time switch (a.ContentType) { - case ShapeContentType.Group: - return MergeResult.From(MergeShapeGroup((ShapeGroup)a, aRange, (ShapeGroup)b, bRange)); - case ShapeContentType.Path: - return MergeResult.From(MergePaths((Path)a, aRange, (Path)b, bRange)); case ShapeContentType.Ellipse: return MergeResult.From(MergeEllipses((Ellipse)a, aRange, (Ellipse)b, bRange)); + case ShapeContentType.Group: + return MergeResult.From(MergeShapeGroup((ShapeGroup)a, aRange, (ShapeGroup)b, bRange)); case ShapeContentType.LinearGradientFill: return MergeResult.From(MergeLinearGradientFills((LinearGradientFill)a, aRange, (LinearGradientFill)b, bRange)); - case ShapeContentType.Transform: - return MergeResult.From(MergeTransform((Transform)a, aRange, (Transform)b, bRange)); + case ShapeContentType.Path: + return MergeResult.From(MergePaths((Path)a, aRange, (Path)b, bRange)); + case ShapeContentType.Rectangle: + return MergeResult.From(MergeRectangles((Rectangle)a, aRange, (Rectangle)b, bRange)); + case ShapeContentType.RoundCorners: + return MergeResult.From(MergeRoundCorners((RoundCorners)a, aRange, (RoundCorners)b, bRange)); case ShapeContentType.SolidColorFill: return MergeResult.From(MergeSolidColorFills((SolidColorFill)a, aRange, (SolidColorFill)b, bRange)); case ShapeContentType.SolidColorStroke: return MergeResult.From(MergeSolidColorStrokes((SolidColorStroke)a, aRange, (SolidColorStroke)b, bRange)); + case ShapeContentType.Transform: + return MergeResult.From(MergeTransform((Transform)a, aRange, (Transform)b, bRange)); + case ShapeContentType.TrimPath: + return MergeResult.From(MergeTrimPaths((TrimPath)a, aRange, (TrimPath)b, bRange)); } return MergeResult.Failed; @@ -678,16 +760,6 @@ MergeResult MergeAssets(Asset a, TimeRange aParentRange, Asset b, TimeRan public MergeResult MergeLayerGroups(LayerGroup a, LayerGroup b) { - if (a.MainLayer is PreCompLayer || b.MainLayer is PreCompLayer) - { - return MergeResult.Failed; - } - - if (a.MatteLayer is PreCompLayer || b.MatteLayer is PreCompLayer) - { - return MergeResult.Failed; - } - if (!a.CanBeMerged || !b.CanBeMerged) { return MergeResult.Failed; @@ -836,7 +908,7 @@ MergeResult MergePreCompLayers(PreCompLayer a, PreCompLayer b) var bAsset = GetAssetById(b.RefId); - if (aAsset is not LayerCollectionAsset || bAsset is not LayerCollectionAsset || aAsset == bAsset) + if (aAsset is not LayerCollectionAsset || bAsset is not LayerCollectionAsset) { return MergeResult.Failed; } diff --git a/source/LottieReader/Serialization/LottieCompositionReader.cs b/source/LottieReader/Serialization/LottieCompositionReader.cs index d732f723..4d09eb59 100644 --- a/source/LottieReader/Serialization/LottieCompositionReader.cs +++ b/source/LottieReader/Serialization/LottieCompositionReader.cs @@ -288,8 +288,6 @@ LottieComposition ParseLottieComposition(ref Reader reader) layers: new LayerCollection(layers), markers: markers); - result = LottieMergeOptimizer.Optimize(result); - return result; }