Browse Source

switch to using helper in the color classes

pull/9215/head
Emmanuel Hansen 4 years ago
parent
commit
868e5a5488
  1. 44
      src/Avalonia.Base/Media/Color.cs
  2. 30
      src/Avalonia.Base/Media/HslColor.cs
  3. 30
      src/Avalonia.Base/Media/HsvColor.cs
  4. 24
      src/Avalonia.Base/Utilities/SpanHelpers.cs
  5. 18
      src/Avalonia.Build.Tasks/SpanCompat.cs

44
src/Avalonia.Base/Media/Color.cs

@ -381,9 +381,9 @@ namespace Avalonia.Media
if (components.Length == 3) // RGB
{
if (InternalTryParseByte(components[0], out byte red) &&
InternalTryParseByte(components[1], out byte green) &&
InternalTryParseByte(components[2], out byte blue))
if (InternalTryParseByte(components[0].AsSpan(), out byte red) &&
InternalTryParseByte(components[1].AsSpan(), out byte green) &&
InternalTryParseByte(components[2].AsSpan(), out byte blue))
{
color = new Color(0xFF, red, green, blue);
return true;
@ -391,10 +391,10 @@ namespace Avalonia.Media
}
else if (components.Length == 4) // RGBA
{
if (InternalTryParseByte(components[0], out byte red) &&
InternalTryParseByte(components[1], out byte green) &&
InternalTryParseByte(components[2], out byte blue) &&
InternalTryParseDouble(components[3], out double alpha))
if (InternalTryParseByte(components[0].AsSpan(), out byte red) &&
InternalTryParseByte(components[1].AsSpan(), out byte green) &&
InternalTryParseByte(components[2].AsSpan(), out byte blue) &&
InternalTryParseDouble(components[3].AsSpan(), out double alpha))
{
color = new Color((byte)Math.Round(alpha * 255.0), red, green, blue);
return true;
@ -402,17 +402,14 @@ namespace Avalonia.Media
}
// Local function to specially parse a byte value with an optional percentage sign
bool InternalTryParseByte(string inString, out byte outByte)
bool InternalTryParseByte(ReadOnlySpan<char> inString, out byte outByte)
{
// The percent sign, if it exists, must be at the end of the number
int percentIndex = inString.IndexOf("%", StringComparison.Ordinal);
int percentIndex = inString.IndexOf("%".AsSpan(), StringComparison.Ordinal);
if (percentIndex >= 0)
{
var result = double.TryParse(
inString.Substring(0, percentIndex),
NumberStyles.Number,
CultureInfo.InvariantCulture,
var result = inString.Slice(0, percentIndex).TryParseNumberToDouble(
out double percentage);
outByte = (byte)Math.Round((percentage / 100.0) * 255.0);
@ -420,37 +417,28 @@ namespace Avalonia.Media
}
else
{
return byte.TryParse(
inString,
NumberStyles.Number,
CultureInfo.InvariantCulture,
return inString.TryParseNumberToByte(
out outByte);
}
}
// Local function to specially parse a double value with an optional percentage sign
bool InternalTryParseDouble(string inString, out double outDouble)
bool InternalTryParseDouble(ReadOnlySpan<char> inString, out double outDouble)
{
// The percent sign, if it exists, must be at the end of the number
int percentIndex = inString.IndexOf("%", StringComparison.Ordinal);
int percentIndex = inString.IndexOf("%".AsSpan(), StringComparison.Ordinal);
if (percentIndex >= 0)
{
var result = double.TryParse(
inString.Substring(0, percentIndex),
NumberStyles.Number,
CultureInfo.InvariantCulture,
out double percentage);
var result = inString.Slice(0, percentIndex).TryParseNumberToDouble(
out double percentage);
outDouble = percentage / 100.0;
return result;
}
else
{
return double.TryParse(
inString,
NumberStyles.Number,
CultureInfo.InvariantCulture,
return inString.TryParseNumberToDouble(
out outDouble);
}
}

30
src/Avalonia.Base/Media/HslColor.cs

@ -302,9 +302,9 @@ namespace Avalonia.Media
if (components.Length == 3) // HSL
{
if (double.TryParse(components[0], NumberStyles.Number, CultureInfo.InvariantCulture, out double hue) &&
TryInternalParse(components[1], out double saturation) &&
TryInternalParse(components[2], out double lightness))
if (components[0].AsSpan().TryParseNumberToDouble(out double hue) &&
TryInternalParse(components[1].AsSpan(), out double saturation) &&
TryInternalParse(components[2].AsSpan(), out double lightness))
{
hslColor = new HslColor(1.0, hue, saturation, lightness);
return true;
@ -312,10 +312,10 @@ namespace Avalonia.Media
}
else if (components.Length == 4) // HSLA
{
if (double.TryParse(components[0], NumberStyles.Number, CultureInfo.InvariantCulture, out double hue) &&
TryInternalParse(components[1], out double saturation) &&
TryInternalParse(components[2], out double lightness) &&
TryInternalParse(components[3], out double alpha))
if (components[0].AsSpan().TryParseNumberToDouble(out double hue) &&
TryInternalParse(components[1].AsSpan(), out double saturation) &&
TryInternalParse(components[2].AsSpan(), out double lightness) &&
TryInternalParse(components[3].AsSpan(), out double alpha))
{
hslColor = new HslColor(alpha, hue, saturation, lightness);
return true;
@ -323,28 +323,22 @@ namespace Avalonia.Media
}
// Local function to specially parse a double value with an optional percentage sign
bool TryInternalParse(string inString, out double outDouble)
bool TryInternalParse(ReadOnlySpan<char> inString, out double outDouble)
{
// The percent sign, if it exists, must be at the end of the number
int percentIndex = inString.IndexOf("%", StringComparison.Ordinal);
int percentIndex = inString.IndexOf("%".AsSpan(), StringComparison.Ordinal);
if (percentIndex >= 0)
{
var result = double.TryParse(
inString.Substring(0, percentIndex),
NumberStyles.Number,
CultureInfo.InvariantCulture,
out double percentage);
var result = inString.Slice(0, percentIndex).TryParseNumberToDouble(
out double percentage);
outDouble = percentage / 100.0;
return result;
}
else
{
return double.TryParse(
inString,
NumberStyles.Number,
CultureInfo.InvariantCulture,
return inString.TryParseNumberToDouble(
out outDouble);
}
}

30
src/Avalonia.Base/Media/HsvColor.cs

@ -302,9 +302,9 @@ namespace Avalonia.Media
if (components.Length == 3) // HSV
{
if (double.TryParse(components[0], NumberStyles.Number, CultureInfo.InvariantCulture, out double hue) &&
TryInternalParse(components[1], out double saturation) &&
TryInternalParse(components[2], out double value))
if (components[0].AsSpan().TryParseNumberToDouble(out double hue) &&
TryInternalParse(components[1].AsSpan(), out double saturation) &&
TryInternalParse(components[2].AsSpan(), out double value))
{
hsvColor = new HsvColor(1.0, hue, saturation, value);
return true;
@ -312,10 +312,10 @@ namespace Avalonia.Media
}
else if (components.Length == 4) // HSVA
{
if (double.TryParse(components[0], NumberStyles.Number, CultureInfo.InvariantCulture, out double hue) &&
TryInternalParse(components[1], out double saturation) &&
TryInternalParse(components[2], out double value) &&
TryInternalParse(components[3], out double alpha))
if (components[0].AsSpan().TryParseNumberToDouble(out double hue) &&
TryInternalParse(components[1].AsSpan(), out double saturation) &&
TryInternalParse(components[2].AsSpan(), out double value) &&
TryInternalParse(components[3].AsSpan(), out double alpha))
{
hsvColor = new HsvColor(alpha, hue, saturation, value);
return true;
@ -323,28 +323,22 @@ namespace Avalonia.Media
}
// Local function to specially parse a double value with an optional percentage sign
bool TryInternalParse(string inString, out double outDouble)
bool TryInternalParse(ReadOnlySpan<char> inString, out double outDouble)
{
// The percent sign, if it exists, must be at the end of the number
int percentIndex = inString.IndexOf("%", StringComparison.Ordinal);
int percentIndex = inString.IndexOf("%".AsSpan(), StringComparison.Ordinal);
if (percentIndex >= 0)
{
var result = double.TryParse(
inString.Substring(0, percentIndex),
NumberStyles.Number,
CultureInfo.InvariantCulture,
out double percentage);
var result = inString.Slice(0, percentIndex).TryParseNumberToDouble(
out double percentage);
outDouble = percentage / 100.0;
return result;
}
else
{
return double.TryParse(
inString,
NumberStyles.Number,
CultureInfo.InvariantCulture,
return inString.TryParseNumberToDouble(
out outDouble);
}
}

24
src/Avalonia.Base/Utilities/SpanHelpers.cs

@ -25,6 +25,30 @@ namespace Avalonia.Utilities
return int.TryParse(span.ToString(), out value);
#else
return int.TryParse(span, out value);
#endif
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryParseNumberToDouble(this ReadOnlySpan<char> span, out double value)
{
#if NETSTANDARD2_0
return double.TryParse(span.ToString(), NumberStyles.Number, CultureInfo.InvariantCulture,
out value);
#else
return double.TryParse(span, NumberStyles.Number, CultureInfo.InvariantCulture,
out value);
#endif
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryParseNumberToByte(this ReadOnlySpan<char> span, out byte value)
{
#if NETSTANDARD2_0
return byte.TryParse(span.ToString(), NumberStyles.Number, CultureInfo.InvariantCulture,
out value);
#else
return byte.TryParse(span, NumberStyles.Number, CultureInfo.InvariantCulture,
out value);
#endif
}
}

18
src/Avalonia.Build.Tasks/SpanCompat.cs

@ -99,11 +99,25 @@ namespace System
return int.TryParse(ToString(), out value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool TryParseNumberToDouble(out double value)
{
return double.TryParse(ToString(), NumberStyles.Number, CultureInfo.InvariantCulture,
out value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool TryParseNumberToByte(out byte value)
{
return byte.TryParse(ToString(), NumberStyles.Number, CultureInfo.InvariantCulture,
out value);
}
public override string ToString() => _length == 0 ? string.Empty : _s.Substring(_start, _length);
internal int IndexOf(string v, StringComparison ordinal, int start = 0)
internal int IndexOf(ReadOnlySpan<char> v, StringComparison ordinal, int start = 0)
{
if(Length == 0 || string.IsNullOrEmpty(v))
if(Length == 0 || v.IsEmpty)
{
return -1;
}

Loading…
Cancel
Save