Skip to content

Commit 5dfc575

Browse files
Merge pull request #4189 from arcadiogarcia/user/arcadiog/ToCompositionString
Prevent floats from being represented in scientific notation in expression animation strings
2 parents b6ec0bc + 81b350e commit 5dfc575

File tree

8 files changed

+58
-11
lines changed

8 files changed

+58
-11
lines changed

Microsoft.Toolkit.Uwp.UI.Animations/Expressions/ExpressionNodes/Matrix3x2Node.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ public Matrix4x4Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3,
332332
/// <returns>System.String.</returns>
333333
protected internal override string GetValue()
334334
{
335-
return $"Matrix3x2({_value.M11},{_value.M12},{_value.M21},{_value.M22},{_value.M31},{_value.M32})";
335+
return $"Matrix3x2({_value.M11.ToCompositionString()},{_value.M12.ToCompositionString()},{_value.M21.ToCompositionString()},{_value.M22.ToCompositionString()},{_value.M31.ToCompositionString()},{_value.M32.ToCompositionString()})";
336336
}
337337

338338
private Matrix3x2 _value;

Microsoft.Toolkit.Uwp.UI.Animations/Expressions/ExpressionNodes/Matrix4x4Node.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -403,10 +403,10 @@ public Matrix4x4Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3,
403403
/// <returns>System.String.</returns>
404404
protected internal override string GetValue()
405405
{
406-
return $"Matrix4x4({_value.M11},{_value.M12},{_value.M13},{_value.M14}," +
407-
$"{_value.M21},{_value.M22},{_value.M23},{_value.M24}," +
408-
$"{_value.M31},{_value.M32},{_value.M33},{_value.M34}," +
409-
$"{_value.M41},{_value.M42},{_value.M43},{_value.M44})";
406+
return $"Matrix4x4({_value.M11.ToCompositionString()},{_value.M12.ToCompositionString()},{_value.M13.ToCompositionString()},{_value.M14.ToCompositionString()}," +
407+
$"{_value.M21.ToCompositionString()},{_value.M22.ToCompositionString()},{_value.M23.ToCompositionString()},{_value.M24.ToCompositionString()}," +
408+
$"{_value.M31.ToCompositionString()},{_value.M32.ToCompositionString()},{_value.M33.ToCompositionString()},{_value.M34.ToCompositionString()}," +
409+
$"{_value.M41.ToCompositionString()},{_value.M42.ToCompositionString()},{_value.M43.ToCompositionString()},{_value.M44.ToCompositionString()})";
410410
}
411411

412412
private Matrix4x4 _value;

Microsoft.Toolkit.Uwp.UI.Animations/Expressions/ExpressionNodes/QuaternionNode.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ public static implicit operator QuaternionNode(Quaternion value)
126126
/// <returns>System.String.</returns>
127127
protected internal override string GetValue()
128128
{
129-
return $"Quaternion({_value.X},{_value.Y},{_value.Z},{_value.W})";
129+
return $"Quaternion({_value.X.ToCompositionString()},{_value.Y.ToCompositionString()},{_value.Z.ToCompositionString()},{_value.W.ToCompositionString()})";
130130
}
131131

132132
private Quaternion _value;

Microsoft.Toolkit.Uwp.UI.Animations/Expressions/ExpressionNodes/ScalarNode.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -254,8 +254,7 @@ public static implicit operator ScalarNode(int value)
254254
/// <returns>System.String.</returns>
255255
protected internal override string GetValue()
256256
{
257-
// Important to use invariant culture to make sure that floats are written using a .
258-
return _value.ToString(System.Globalization.CultureInfo.InvariantCulture);
257+
return _value.ToCompositionString();
259258
}
260259

261260
private float _value;

Microsoft.Toolkit.Uwp.UI.Animations/Expressions/ExpressionNodes/Vector2Node.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ public Matrix4x4Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3,
297297
/// <returns>System.String.</returns>
298298
protected internal override string GetValue()
299299
{
300-
return $"Vector2({_value.X},{_value.Y})";
300+
return $"Vector2({_value.X.ToCompositionString()},{_value.Y.ToCompositionString()})";
301301
}
302302

303303
private Vector2 _value;

Microsoft.Toolkit.Uwp.UI.Animations/Expressions/ExpressionNodes/Vector3Node.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ public Matrix4x4Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3,
320320
/// <returns>System.String.</returns>
321321
protected internal override string GetValue()
322322
{
323-
return $"Vector3({_value.X},{_value.Y},{_value.Z})";
323+
return $"Vector3({_value.X.ToCompositionString()},{_value.Y.ToCompositionString()},{_value.Z.ToCompositionString()})";
324324
}
325325

326326
private Vector3 _value;

Microsoft.Toolkit.Uwp.UI.Animations/Expressions/ExpressionNodes/Vector4Node.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ public Matrix4x4Node GetSubchannels(Subchannel s1, Subchannel s2, Subchannel s3,
343343
/// <returns>System.String.</returns>
344344
protected internal override string GetValue()
345345
{
346-
return $"Vector4({_value.X},{_value.Y},{_value.Z},{_value.W})";
346+
return $"Vector4({_value.X.ToCompositionString()},{_value.Y.ToCompositionString()},{_value.Z.ToCompositionString()},{_value.W.ToCompositionString()})";
347347
}
348348

349349
private Vector4 _value;
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System.Diagnostics.Contracts;
6+
7+
namespace Microsoft.Toolkit.Uwp.UI.Animations
8+
{
9+
/// <summary>
10+
/// An extension <see langword="class"/> for the <see cref="float"/> type
11+
/// </summary>
12+
internal static class FloatExtensions
13+
{
14+
/// <summary>
15+
/// Returns a <see cref="string"/> representation of a <see cref="float"/> that avoids scientific notation, which is not compatible with the composition expression animations API
16+
/// </summary>
17+
/// <param name="number">The input <see cref="float"/> to process</param>
18+
/// <returns>A <see cref="string"/> representation of <paramref name="number"/> that can be used in a expression animation</returns>
19+
[Pure]
20+
public static string ToCompositionString(this float number)
21+
{
22+
var defaultString = number.ToString(System.Globalization.CultureInfo.InvariantCulture);
23+
var eIndex = defaultString.IndexOf('E');
24+
25+
// If the default string representation is not in scientific notation, we can use it
26+
if (eIndex == -1)
27+
{
28+
return defaultString;
29+
}
30+
31+
// If the number uses scientific notation because it is too large, we can print it without the decimal places
32+
var exponent = int.Parse(defaultString.Substring(eIndex + 1));
33+
if (exponent >= 0)
34+
{
35+
return number.ToString($"F0", System.Globalization.CultureInfo.InvariantCulture);
36+
}
37+
38+
// Otherwise, we need to print it with the right number of decimals
39+
var decimalPlaces = -exponent // The number of decimal places is the exponent of 10
40+
+ eIndex // Plus each character in the mantissa
41+
+ (number < 0 ?
42+
-3 : // Minus the sign, dot and first number of the mantissa if negative
43+
-2); // Minus the dot and first number of the mantissa otherwise
44+
45+
return number.ToString($"F{decimalPlaces}", System.Globalization.CultureInfo.InvariantCulture);
46+
}
47+
}
48+
}

0 commit comments

Comments
 (0)