mirror of
https://github.com/nsnail/spectre.console.git
synced 2025-09-18 02:15:34 +08:00
Use file scoped namespace declarations
This commit is contained in:

committed by
Phil Scott

parent
1dbaf50935
commit
ec1188b837
@@ -2,80 +2,79 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Spectre.Console
|
||||
namespace Spectre.Console;
|
||||
|
||||
internal static partial class ColorPalette
|
||||
{
|
||||
internal static partial class ColorPalette
|
||||
public static IReadOnlyList<Color> Legacy { get; }
|
||||
public static IReadOnlyList<Color> Standard { get; }
|
||||
public static IReadOnlyList<Color> EightBit { get; }
|
||||
|
||||
static ColorPalette()
|
||||
{
|
||||
public static IReadOnlyList<Color> Legacy { get; }
|
||||
public static IReadOnlyList<Color> Standard { get; }
|
||||
public static IReadOnlyList<Color> EightBit { get; }
|
||||
|
||||
static ColorPalette()
|
||||
{
|
||||
Legacy = GenerateLegacyPalette();
|
||||
Standard = GenerateStandardPalette(Legacy);
|
||||
EightBit = GenerateEightBitPalette(Standard);
|
||||
}
|
||||
|
||||
internal static Color ExactOrClosest(ColorSystem system, Color color)
|
||||
{
|
||||
var exact = Exact(system, color);
|
||||
return exact ?? Closest(system, color);
|
||||
}
|
||||
|
||||
private static Color? Exact(ColorSystem system, Color color)
|
||||
{
|
||||
if (system == ColorSystem.TrueColor)
|
||||
{
|
||||
return color;
|
||||
}
|
||||
|
||||
var palette = system switch
|
||||
{
|
||||
ColorSystem.Legacy => Legacy,
|
||||
ColorSystem.Standard => Standard,
|
||||
ColorSystem.EightBit => EightBit,
|
||||
_ => throw new NotSupportedException(),
|
||||
};
|
||||
|
||||
return palette
|
||||
.Where(c => c.Equals(color))
|
||||
.Cast<Color?>()
|
||||
.FirstOrDefault();
|
||||
}
|
||||
|
||||
private static Color Closest(ColorSystem system, Color color)
|
||||
{
|
||||
if (system == ColorSystem.TrueColor)
|
||||
{
|
||||
return color;
|
||||
}
|
||||
|
||||
var palette = system switch
|
||||
{
|
||||
ColorSystem.Legacy => Legacy,
|
||||
ColorSystem.Standard => Standard,
|
||||
ColorSystem.EightBit => EightBit,
|
||||
_ => throw new NotSupportedException(),
|
||||
};
|
||||
|
||||
// https://stackoverflow.com/a/9085524
|
||||
static double Distance(Color first, Color second)
|
||||
{
|
||||
var rmean = ((float)first.R + second.R) / 2;
|
||||
var r = first.R - second.R;
|
||||
var g = first.G - second.G;
|
||||
var b = first.B - second.B;
|
||||
return Math.Sqrt(
|
||||
((int)((512 + rmean) * r * r) >> 8)
|
||||
+ (4 * g * g)
|
||||
+ ((int)((767 - rmean) * b * b) >> 8));
|
||||
}
|
||||
|
||||
return Enumerable.Range(0, int.MaxValue)
|
||||
.Zip(palette, (id, other) => (Distance: Distance(other, color), Id: id, Color: other))
|
||||
.OrderBy(x => x.Distance)
|
||||
.FirstOrDefault().Color;
|
||||
}
|
||||
Legacy = GenerateLegacyPalette();
|
||||
Standard = GenerateStandardPalette(Legacy);
|
||||
EightBit = GenerateEightBitPalette(Standard);
|
||||
}
|
||||
}
|
||||
|
||||
internal static Color ExactOrClosest(ColorSystem system, Color color)
|
||||
{
|
||||
var exact = Exact(system, color);
|
||||
return exact ?? Closest(system, color);
|
||||
}
|
||||
|
||||
private static Color? Exact(ColorSystem system, Color color)
|
||||
{
|
||||
if (system == ColorSystem.TrueColor)
|
||||
{
|
||||
return color;
|
||||
}
|
||||
|
||||
var palette = system switch
|
||||
{
|
||||
ColorSystem.Legacy => Legacy,
|
||||
ColorSystem.Standard => Standard,
|
||||
ColorSystem.EightBit => EightBit,
|
||||
_ => throw new NotSupportedException(),
|
||||
};
|
||||
|
||||
return palette
|
||||
.Where(c => c.Equals(color))
|
||||
.Cast<Color?>()
|
||||
.FirstOrDefault();
|
||||
}
|
||||
|
||||
private static Color Closest(ColorSystem system, Color color)
|
||||
{
|
||||
if (system == ColorSystem.TrueColor)
|
||||
{
|
||||
return color;
|
||||
}
|
||||
|
||||
var palette = system switch
|
||||
{
|
||||
ColorSystem.Legacy => Legacy,
|
||||
ColorSystem.Standard => Standard,
|
||||
ColorSystem.EightBit => EightBit,
|
||||
_ => throw new NotSupportedException(),
|
||||
};
|
||||
|
||||
// https://stackoverflow.com/a/9085524
|
||||
static double Distance(Color first, Color second)
|
||||
{
|
||||
var rmean = ((float)first.R + second.R) / 2;
|
||||
var r = first.R - second.R;
|
||||
var g = first.G - second.G;
|
||||
var b = first.B - second.B;
|
||||
return Math.Sqrt(
|
||||
((int)((512 + rmean) * r * r) >> 8)
|
||||
+ (4 * g * g)
|
||||
+ ((int)((767 - rmean) * b * b) >> 8));
|
||||
}
|
||||
|
||||
return Enumerable.Range(0, int.MaxValue)
|
||||
.Zip(palette, (id, other) => (Distance: Distance(other, color), Id: id, Color: other))
|
||||
.OrderBy(x => x.Distance)
|
||||
.FirstOrDefault().Color;
|
||||
}
|
||||
}
|
@@ -1,92 +1,91 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Spectre.Console
|
||||
namespace Spectre.Console;
|
||||
|
||||
internal static class ColorSystemDetector
|
||||
{
|
||||
internal static class ColorSystemDetector
|
||||
// Adapted from https://github.com/willmcgugan/rich/blob/f0c29052c22d1e49579956a9207324d9072beed7/rich/console.py#L391
|
||||
public static ColorSystem Detect(bool supportsAnsi)
|
||||
{
|
||||
// Adapted from https://github.com/willmcgugan/rich/blob/f0c29052c22d1e49579956a9207324d9072beed7/rich/console.py#L391
|
||||
public static ColorSystem Detect(bool supportsAnsi)
|
||||
// No colors?
|
||||
if (Environment.GetEnvironmentVariables().Contains("NO_COLOR"))
|
||||
{
|
||||
// No colors?
|
||||
if (Environment.GetEnvironmentVariables().Contains("NO_COLOR"))
|
||||
{
|
||||
return ColorSystem.NoColors;
|
||||
}
|
||||
|
||||
// Windows?
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
if (!supportsAnsi)
|
||||
{
|
||||
// Figure out what we should do here.
|
||||
// Does really all Windows terminals support
|
||||
// eight-bit colors? Probably not...
|
||||
return ColorSystem.EightBit;
|
||||
}
|
||||
|
||||
// Windows 10.0.15063 and above support true color,
|
||||
// and we can probably assume that the next major
|
||||
// version of Windows will support true color as well.
|
||||
if (GetWindowsVersionInformation(out var major, out var build))
|
||||
{
|
||||
if (major == 10 && build >= 15063)
|
||||
{
|
||||
return ColorSystem.TrueColor;
|
||||
}
|
||||
else if (major > 10)
|
||||
{
|
||||
return ColorSystem.TrueColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var colorTerm = Environment.GetEnvironmentVariable("COLORTERM");
|
||||
if (!string.IsNullOrWhiteSpace(colorTerm))
|
||||
{
|
||||
if (colorTerm.Equals("truecolor", StringComparison.OrdinalIgnoreCase) ||
|
||||
colorTerm.Equals("24bit", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return ColorSystem.TrueColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Should we default to eight-bit colors?
|
||||
return ColorSystem.EightBit;
|
||||
return ColorSystem.NoColors;
|
||||
}
|
||||
|
||||
private static bool GetWindowsVersionInformation(out int major, out int build)
|
||||
// Windows?
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
major = 0;
|
||||
build = 0;
|
||||
|
||||
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
if (!supportsAnsi)
|
||||
{
|
||||
return false;
|
||||
// Figure out what we should do here.
|
||||
// Does really all Windows terminals support
|
||||
// eight-bit colors? Probably not...
|
||||
return ColorSystem.EightBit;
|
||||
}
|
||||
|
||||
// Windows 10.0.15063 and above support true color,
|
||||
// and we can probably assume that the next major
|
||||
// version of Windows will support true color as well.
|
||||
if (GetWindowsVersionInformation(out var major, out var build))
|
||||
{
|
||||
if (major == 10 && build >= 15063)
|
||||
{
|
||||
return ColorSystem.TrueColor;
|
||||
}
|
||||
else if (major > 10)
|
||||
{
|
||||
return ColorSystem.TrueColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var colorTerm = Environment.GetEnvironmentVariable("COLORTERM");
|
||||
if (!string.IsNullOrWhiteSpace(colorTerm))
|
||||
{
|
||||
if (colorTerm.Equals("truecolor", StringComparison.OrdinalIgnoreCase) ||
|
||||
colorTerm.Equals("24bit", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return ColorSystem.TrueColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Should we default to eight-bit colors?
|
||||
return ColorSystem.EightBit;
|
||||
}
|
||||
|
||||
private static bool GetWindowsVersionInformation(out int major, out int build)
|
||||
{
|
||||
major = 0;
|
||||
build = 0;
|
||||
|
||||
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#if NET5_0_OR_GREATER
|
||||
// The reason we're not always using this, is because it will return wrong values on other runtimes than .NET 5+
|
||||
// See https://docs.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/5.0/environment-osversion-returns-correct-version
|
||||
var version = Environment.OSVersion.Version;
|
||||
major = version.Major;
|
||||
build = version.Build;
|
||||
return true;
|
||||
// The reason we're not always using this, is because it will return wrong values on other runtimes than .NET 5+
|
||||
// See https://docs.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/5.0/environment-osversion-returns-correct-version
|
||||
var version = Environment.OSVersion.Version;
|
||||
major = version.Major;
|
||||
build = version.Build;
|
||||
return true;
|
||||
#else
|
||||
var regex = new System.Text.RegularExpressions.Regex("Microsoft Windows (?'major'[0-9]*).(?'minor'[0-9]*).(?'build'[0-9]*)\\s*$");
|
||||
var match = regex.Match(RuntimeInformation.OSDescription);
|
||||
if (match.Success && int.TryParse(match.Groups["major"].Value, out major))
|
||||
var regex = new System.Text.RegularExpressions.Regex("Microsoft Windows (?'major'[0-9]*).(?'minor'[0-9]*).(?'build'[0-9]*)\\s*$");
|
||||
var match = regex.Match(RuntimeInformation.OSDescription);
|
||||
if (match.Success && int.TryParse(match.Groups["major"].Value, out major))
|
||||
{
|
||||
if (int.TryParse(match.Groups["build"].Value, out build))
|
||||
{
|
||||
if (int.TryParse(match.Groups["build"].Value, out build))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,57 +1,56 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Spectre.Console
|
||||
namespace Spectre.Console;
|
||||
|
||||
internal static partial class ColorTable
|
||||
{
|
||||
internal static partial class ColorTable
|
||||
private static readonly Dictionary<int, string> _nameLookup;
|
||||
private static readonly Dictionary<string, int> _numberLookup;
|
||||
|
||||
static ColorTable()
|
||||
{
|
||||
private static readonly Dictionary<int, string> _nameLookup;
|
||||
private static readonly Dictionary<string, int> _numberLookup;
|
||||
|
||||
static ColorTable()
|
||||
_numberLookup = GenerateTable();
|
||||
_nameLookup = new Dictionary<int, string>();
|
||||
foreach (var pair in _numberLookup)
|
||||
{
|
||||
_numberLookup = GenerateTable();
|
||||
_nameLookup = new Dictionary<int, string>();
|
||||
foreach (var pair in _numberLookup)
|
||||
if (_nameLookup.ContainsKey(pair.Value))
|
||||
{
|
||||
if (_nameLookup.ContainsKey(pair.Value))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
_nameLookup.Add(pair.Value, pair.Key);
|
||||
}
|
||||
}
|
||||
|
||||
public static Color GetColor(int number)
|
||||
{
|
||||
if (number < 0 || number > 255)
|
||||
{
|
||||
throw new InvalidOperationException("Color number must be between 0 and 255");
|
||||
continue;
|
||||
}
|
||||
|
||||
return ColorPalette.EightBit[number];
|
||||
}
|
||||
|
||||
public static Color? GetColor(string name)
|
||||
{
|
||||
if (!_numberLookup.TryGetValue(name, out var number))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (number > ColorPalette.EightBit.Count - 1)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return ColorPalette.EightBit[number];
|
||||
}
|
||||
|
||||
public static string? GetName(int number)
|
||||
{
|
||||
_nameLookup.TryGetValue(number, out var name);
|
||||
return name;
|
||||
_nameLookup.Add(pair.Value, pair.Key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Color GetColor(int number)
|
||||
{
|
||||
if (number < 0 || number > 255)
|
||||
{
|
||||
throw new InvalidOperationException("Color number must be between 0 and 255");
|
||||
}
|
||||
|
||||
return ColorPalette.EightBit[number];
|
||||
}
|
||||
|
||||
public static Color? GetColor(string name)
|
||||
{
|
||||
if (!_numberLookup.TryGetValue(name, out var number))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (number > ColorPalette.EightBit.Count - 1)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return ColorPalette.EightBit[number];
|
||||
}
|
||||
|
||||
public static string? GetName(int number)
|
||||
{
|
||||
_nameLookup.TryGetValue(number, out var name);
|
||||
return name;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user