-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathUtilities.cs
115 lines (94 loc) · 3.6 KB
/
Utilities.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
using System;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Text.RegularExpressions;
namespace SpriteEditor
{
public static class Utilities
{
private static readonly Regex hexRegex = new(
@"^#((?'R'[0-9a-f]{2})(?'G'[0-9a-f]{2})(?'B'[0-9a-f]{2}))"
+ @"|((?'R'[0-9a-f])(?'G'[0-9a-f])(?'B'[0-9a-f]))$",
RegexOptions.Compiled | RegexOptions.IgnoreCase);
// http://stackoverflow.com/questions/982028/convert-net-color-objects-to-hex-codes-and-back
public static string ToHex(this Color color)
{
return $"#{color.R:X2}{color.G:X2}{color.B:X2}";
}
public static Color FromHex(string colorString)
{
ArgumentNullException.ThrowIfNull(colorString);
var match = hexRegex.Match(colorString);
if (!match.Success)
{
throw new ArgumentException(
$"\"{colorString}\" doesn't represent a valid hex color", nameof(colorString));
}
return Color.FromArgb(
ColorComponentToValue(match.Groups["R"].Value),
ColorComponentToValue(match.Groups["G"].Value),
ColorComponentToValue(match.Groups["B"].Value));
}
public static int ColorComponentToValue(string component)
{
Debug.Assert(component != null, "Color component is not null");
Debug.Assert(component.Length > 0, "Color component length greater than 0");
Debug.Assert(component.Length <= 2, "Color component length less than 0");
if (component.Length == 1)
{
component += component;
}
return int.Parse(
component,
System.Globalization.NumberStyles.HexNumber);
}
public static bool CheckClose(float a, float b)
{
return CheckClose(a, b, 0.01f);
}
public static bool CheckClose(float a, float b, float epsilon)
{
float absA = Math.Abs(a);
float absB = Math.Abs(b);
float diff = Math.Abs(a - b);
if (a * b == 0)
{
// a or b or both are zero
// relative error is not meaningful here
return diff < (epsilon * epsilon);
}
// use relative error
return diff / (absA + absB) < epsilon;
}
public static string ResolveRelativePath(string referencePath, string relativePath)
{
var uri = new Uri(Path.Combine(referencePath, relativePath));
return Uri.UnescapeDataString(Path.GetFullPath(uri.AbsolutePath));
}
public static string MakeRelativePath(string fromPath, string toPath)
{
if (string.IsNullOrEmpty(fromPath))
{
throw new ArgumentNullException(nameof(fromPath));
}
if (string.IsNullOrEmpty(toPath))
{
throw new ArgumentNullException(nameof(toPath));
}
if (Directory.Exists(fromPath) && !fromPath.EndsWith('\\'))
{
fromPath += "\\";
}
if (Directory.Exists(toPath) && !toPath.EndsWith('\\'))
{
toPath += "\\";
}
var fromUri = new Uri(fromPath);
var toUri = new Uri(toPath);
var relativeUri = fromUri.MakeRelativeUri(toUri);
var relativePath = Uri.UnescapeDataString(relativeUri.ToString());
return relativePath;
}
}
}