Skip to content

Commit 04cd5fe

Browse files
committed
Made some changes + comments cleanup as discussed
1 parent e27c69f commit 04cd5fe

File tree

4 files changed

+79
-68
lines changed

4 files changed

+79
-68
lines changed

source/LottieToWinComp/Brushes.cs

Lines changed: 53 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ static void TranslateAndApplyLinearGradientStroke(
168168
ApplyCommonStrokeProperties(
169169
context,
170170
shapeStroke,
171-
TranslateLinearGradient(context, shapeStroke, contextOpacity, null),
171+
TranslateLinearGradient(context, shapeStroke, contextOpacity),
172172
sprite);
173173
}
174174

@@ -181,7 +181,7 @@ static void TranslateAndApplyRadialGradientStroke(
181181
ApplyCommonStrokeProperties(
182182
context,
183183
shapeStroke,
184-
TranslateRadialGradient(context, shapeStroke, contextOpacity, null),
184+
TranslateRadialGradient(context, shapeStroke, contextOpacity),
185185
sprite);
186186
}
187187

@@ -258,7 +258,7 @@ static void ApplyCommonStrokeProperties(
258258
LayerContext context,
259259
ShapeFill? shapeFill,
260260
CompositeOpacity opacity,
261-
Rectangles.InternalOffset? internalOffset)
261+
Rectangles.OriginOffset? originOffset)
262262
{
263263
if (shapeFill is null)
264264
{
@@ -267,9 +267,12 @@ static void ApplyCommonStrokeProperties(
267267

268268
return shapeFill.FillKind switch
269269
{
270-
ShapeFill.ShapeFillKind.SolidColor => TranslateSolidColorFill(context, (SolidColorFill)shapeFill, opacity),
271-
ShapeFill.ShapeFillKind.LinearGradient => TranslateLinearGradient(context, (LinearGradientFill)shapeFill, opacity, internalOffset),
272-
ShapeFill.ShapeFillKind.RadialGradient => TranslateRadialGradient(context, (RadialGradientFill)shapeFill, opacity, internalOffset),
270+
ShapeFill.ShapeFillKind.SolidColor =>
271+
TranslateSolidColorFill(context, (SolidColorFill)shapeFill, opacity),
272+
ShapeFill.ShapeFillKind.LinearGradient =>
273+
TranslateLinearGradient(context, (LinearGradientFill)shapeFill, opacity, originOffset),
274+
ShapeFill.ShapeFillKind.RadialGradient =>
275+
TranslateRadialGradient(context, (RadialGradientFill)shapeFill, opacity, originOffset),
273276
_ => throw new InvalidOperationException(),
274277
};
275278
}
@@ -410,40 +413,64 @@ static CompositionColorBrush TranslateBoundSolidColor(
410413
return result;
411414
}
412415

413-
static void TranslateVector2AnimatableWithInternalOffset(
416+
// Animate Vector2 property of object with TrimmedAnimatable while applying OriginOffset to it.
417+
// Returns non-null Sn.Vector2 value if no animation is needed (and no animation was applied).
418+
static Sn.Vector2? AnimateVector2WithOriginOffsetOrGetValue(
414419
LayerContext context,
415420
CompositionObject obj,
416421
string propertyName,
417422
TrimmedAnimatable<Vector2> value,
418-
Rectangles.InternalOffset offset)
423+
Rectangles.OriginOffset? offset)
419424
{
420-
// anomate source property first
425+
if (offset is null)
426+
{
427+
if (value.IsAnimated)
428+
{
429+
Animate.Vector2(context, value, obj, propertyName);
430+
return null;
431+
}
432+
else
433+
{
434+
return ConvertTo.Vector2(value.InitialValue);
435+
}
436+
}
437+
438+
if (!offset.IsAnimated && !value.IsAnimated)
439+
{
440+
return ConvertTo.Vector2(value.InitialValue) + offset.OffsetValue!;
441+
}
442+
443+
// Animate source property first.
444+
// We are using this auxiliary property to store original animation,
445+
// so that its value can be used in expression animation of property itself.
421446
string sourcePropertyName = propertyName + "Source";
422447
obj.Properties.InsertVector2(sourcePropertyName, ConvertTo.Vector2(value.InitialValue));
423448
Animate.Vector2(context, value, obj, sourcePropertyName);
424449

425-
// create expression that offsets source property by internal offset
450+
// Create expression that offsets source property by origin offset.
426451
WinCompData.Expressions.Vector2 expression = offset.IsAnimated ?
427-
ExpressionFactory.InternalOffsetExressionAdded(sourcePropertyName, offset.OffsetExpression!) :
428-
ExpressionFactory.InternalOffsetValueAdded(sourcePropertyName, (Sn.Vector2)offset.OffsetValue!);
452+
ExpressionFactory.OriginOffsetExressionAdded(sourcePropertyName, offset.OffsetExpression!) :
453+
ExpressionFactory.OriginOffsetValueAdded(sourcePropertyName, (Sn.Vector2)offset.OffsetValue!);
429454

430455
var expressionAnimation = context.ObjectFactory.CreateExpressionAnimation(expression);
431456
expressionAnimation.SetReferenceParameter("my", obj);
432457
if (offset.IsAnimated)
433458
{
434-
// expression can use geometry
459+
// Expression can use geometry.
435460
expressionAnimation.SetReferenceParameter("geometry", offset.Geometry);
436461
}
437462

438-
// animate original property with expression that applies internal offset to it
463+
// Animate original property with expression that applies origin offset to it.
439464
Animate.WithExpression(obj, expressionAnimation, propertyName);
465+
466+
return null;
440467
}
441468

442469
static CompositionLinearGradientBrush? TranslateLinearGradient(
443470
LayerContext context,
444471
IGradient linearGradient,
445472
CompositeOpacity opacity,
446-
Rectangles.InternalOffset? internalOffset)
473+
Rectangles.OriginOffset? originOffset = null)
447474
{
448475
var result = context.ObjectFactory.CreateLinearGradientBrush();
449476

@@ -453,30 +480,16 @@ static void TranslateVector2AnimatableWithInternalOffset(
453480
var startPoint = Optimizer.TrimAnimatable(context, linearGradient.StartPoint);
454481
var endPoint = Optimizer.TrimAnimatable(context, linearGradient.EndPoint);
455482

456-
if (internalOffset is not null)
457-
{
458-
TranslateVector2AnimatableWithInternalOffset(context, result, nameof(result.StartPoint), startPoint, internalOffset);
459-
}
460-
else if (startPoint.IsAnimated)
483+
var startPointValue = AnimateVector2WithOriginOffsetOrGetValue(context, result, nameof(result.StartPoint), startPoint, originOffset);
484+
if (startPointValue is not null)
461485
{
462-
Animate.Vector2(context, startPoint, result, nameof(result.StartPoint));
463-
}
464-
else
465-
{
466-
result.StartPoint = ConvertTo.Vector2(startPoint.InitialValue);
486+
result.StartPoint = startPointValue!;
467487
}
468488

469-
if (internalOffset is not null)
489+
var endPointValue = AnimateVector2WithOriginOffsetOrGetValue(context, result, nameof(result.EndPoint), endPoint, originOffset);
490+
if (endPointValue is not null)
470491
{
471-
TranslateVector2AnimatableWithInternalOffset(context, result, nameof(result.EndPoint), endPoint, internalOffset);
472-
}
473-
else if (endPoint.IsAnimated)
474-
{
475-
Animate.Vector2(context, endPoint, result, nameof(result.EndPoint));
476-
}
477-
else
478-
{
479-
result.EndPoint = ConvertTo.Vector2(endPoint.InitialValue);
492+
result.EndPoint = endPointValue!;
480493
}
481494

482495
var gradientStops = Optimizer.TrimAnimatable(context, linearGradient.GradientStops);
@@ -496,13 +509,13 @@ static void TranslateVector2AnimatableWithInternalOffset(
496509
LayerContext context,
497510
IRadialGradient gradient,
498511
CompositeOpacity opacity,
499-
Rectangles.InternalOffset? internalOffset)
512+
Rectangles.OriginOffset? originOffset = null)
500513
{
501514
if (!context.ObjectFactory.IsUapApiAvailable(nameof(CompositionRadialGradientBrush), versionDependentFeatureDescription: "Radial gradient fill"))
502515
{
503516
// CompositionRadialGradientBrush didn't exist until UAP v8. If the target OS doesn't support
504517
// UAP v8 then fall back to linear gradients as a compromise.
505-
return TranslateLinearGradient(context, gradient, opacity, internalOffset);
518+
return TranslateLinearGradient(context, gradient, opacity, originOffset);
506519
}
507520

508521
var result = context.ObjectFactory.CreateRadialGradientBrush();
@@ -513,17 +526,10 @@ static void TranslateVector2AnimatableWithInternalOffset(
513526
var startPoint = Optimizer.TrimAnimatable(context, gradient.StartPoint);
514527
var endPoint = Optimizer.TrimAnimatable(context, gradient.EndPoint);
515528

516-
if (internalOffset is not null)
517-
{
518-
TranslateVector2AnimatableWithInternalOffset(context, result, nameof(result.EllipseCenter), startPoint, internalOffset);
519-
}
520-
else if (startPoint.IsAnimated)
521-
{
522-
Animate.Vector2(context, startPoint, result, nameof(result.EllipseCenter));
523-
}
524-
else
529+
var startPointValue = AnimateVector2WithOriginOffsetOrGetValue(context, result, nameof(result.EllipseCenter), startPoint, originOffset);
530+
if (startPointValue is not null)
525531
{
526-
result.EllipseCenter = ConvertTo.Vector2(startPoint.InitialValue);
532+
result.EllipseCenter = startPointValue!;
527533
}
528534

529535
if (endPoint.IsAnimated)

source/LottieToWinComp/ExpressionFactory.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ static class ExpressionFactory
4747
MyPosition.Y - MyAnchor.Y,
4848
0);
4949

50-
internal static Vector2 InternalOffsetExressionAdded(string property, Vector2 offsetExpression) => MyVector2(property) + offsetExpression;
50+
internal static Vector2 OriginOffsetExressionAdded(string property, Vector2 offsetExpression) => MyVector2(property) + offsetExpression;
5151

52-
internal static Vector2 InternalOffsetValueAdded(string property, Sn.Vector2 offsetValue) => MyVector2(property) + Vector2(offsetValue);
52+
internal static Vector2 OriginOffsetValueAdded(string property, Sn.Vector2 offsetValue) => MyVector2(property) + Vector2(offsetValue);
5353

5454
internal static Color ThemedColorMultipliedByOpacity(string bindingName, Animatables.Opacity opacity)
5555
=> ColorAsVector4MultipliedByOpacity(ThemedColor4Property(bindingName), opacity.Value);

source/LottieToWinComp/Rectangles.cs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,31 +21,29 @@ static class Rectangles
2121
// Rectangles are implemented differently in WinComp API
2222
// and Lottie. In WinComp API coordinates inside rectangle start in
2323
// top left corner and in Lottie they start in the middle
24-
// To account for this we need to offset all the internal points
25-
// for (Rectangle.Size / 2)
24+
// To account for this we need to offset all the points inside
25+
// the rectangle for (Rectangle.Size / 2).
2626
// This class represents this offset (static or animated)
27-
public class InternalOffset
27+
public class OriginOffset
2828
{
2929
public RectangleOrRoundedRectangleGeometry Geometry { get; }
3030

3131
// Use expression if size is animated
32-
#nullable enable
3332
public Expressions.Vector2? OffsetExpression { get; }
34-
#nullable disable
3533

3634
// Use constant value if size if static
3735
public Sn.Vector2? OffsetValue { get; }
3836

39-
public bool IsAnimated => OffsetExpression is not null;
37+
public bool IsAnimated => OffsetValue is null;
4038

41-
public InternalOffset(RectangleOrRoundedRectangleGeometry geometry, Expressions.Vector2 expression)
39+
public OriginOffset(RectangleOrRoundedRectangleGeometry geometry, Expressions.Vector2 expression)
4240
{
4341
Geometry = geometry;
4442
OffsetExpression = expression;
4543
OffsetValue = null;
4644
}
4745

48-
public InternalOffset(RectangleOrRoundedRectangleGeometry geometry, Sn.Vector2 value)
46+
public OriginOffset(RectangleOrRoundedRectangleGeometry geometry, Sn.Vector2 value)
4947
{
5048
Geometry = geometry;
5149
OffsetExpression = null;
@@ -353,15 +351,16 @@ static void ApplyRectangleContentCommon(
353351
var height = size.InitialValue.Y;
354352
var trimOffsetDegrees = (width / (2 * (width + height))) * 360;
355353

356-
InternalOffset internalOffset = size.IsAnimated ?
357-
new InternalOffset(geometry, ExpressionFactory.GeometryHalfSize) :
358-
new InternalOffset(geometry, ConvertTo.Vector2(size.InitialValue / 2));
354+
// If offset is not animated then other computations for fill brush can be optimized.
355+
OriginOffset originOffset = size.IsAnimated ?
356+
new OriginOffset(geometry, ExpressionFactory.GeometryHalfSize) :
357+
new OriginOffset(geometry, ConvertTo.Vector2(size.InitialValue / 2));
359358

360359
Shapes.TranslateAndApplyShapeContextWithTrimOffset(
361360
context,
362361
compositionRectangle,
363362
rectangle.DrawingDirection == DrawingDirection.Reverse,
364-
internalOffset,
363+
originOffset,
365364
trimOffsetDegrees: trimOffsetDegrees);
366365

367366
compositionRectangle.SetDescription(context, () => rectangle.Name);
@@ -448,15 +447,16 @@ static void ApplyRectangleContentCommonXY(
448447
var initialHeight = height.InitialValue;
449448
var trimOffsetDegrees = (initialWidth / (2 * (initialWidth + initialHeight))) * 360;
450449

451-
InternalOffset internalOffset = width.IsAnimated || height.IsAnimated ?
452-
new InternalOffset(geometry, ExpressionFactory.GeometryHalfSize) :
453-
new InternalOffset(geometry, ConvertTo.Vector2(width.InitialValue / 2, height.InitialValue / 2));
450+
// If offset is not animated then other computations for fill brush can be optimized.
451+
OriginOffset originOffset = width.IsAnimated || height.IsAnimated ?
452+
new OriginOffset(geometry, ExpressionFactory.GeometryHalfSize) :
453+
new OriginOffset(geometry, ConvertTo.Vector2(width.InitialValue / 2, height.InitialValue / 2));
454454

455455
Shapes.TranslateAndApplyShapeContextWithTrimOffset(
456456
context,
457457
compositionRectangle,
458458
rectangle.DrawingDirection == DrawingDirection.Reverse,
459-
internalOffset,
459+
originOffset,
460460
trimOffsetDegrees: trimOffsetDegrees);
461461

462462
compositionRectangle.SetDescription(context, () => rectangle.Name);

source/LottieToWinComp/Shapes.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,18 +34,23 @@ public static void TranslateAndApplyShapeContext(
3434
ShapeContext context,
3535
CompositionSpriteShape shape,
3636
bool reverseDirection) =>
37-
TranslateAndApplyShapeContextWithTrimOffset(context, shape, reverseDirection, null, 0);
37+
TranslateAndApplyShapeContextWithTrimOffset(
38+
context,
39+
shape,
40+
reverseDirection,
41+
originOffset: null,
42+
trimOffsetDegrees: 0);
3843

3944
public static void TranslateAndApplyShapeContextWithTrimOffset(
4045
ShapeContext context,
4146
CompositionSpriteShape shape,
4247
bool reverseDirection,
43-
Rectangles.InternalOffset? internalOffset,
48+
Rectangles.OriginOffset? originOffset,
4449
double trimOffsetDegrees)
4550
{
4651
Debug.Assert(shape.Geometry is not null, "Precondition");
4752

48-
shape.FillBrush = Brushes.TranslateShapeFill(context, context.Fill, context.Opacity, internalOffset);
53+
shape.FillBrush = Brushes.TranslateShapeFill(context, context.Fill, context.Opacity, originOffset);
4954
Brushes.TranslateAndApplyStroke(context, context.Stroke, shape, context.Opacity);
5055

5156
TranslateAndApplyTrimPath(

0 commit comments

Comments
 (0)