Dashboard/Quik/Media/Font/FontFace.cs

240 lines
8.0 KiB
C#

using System;
using System.Net.WebSockets;
using System.Text;
using Quik.Media.Font;
namespace Quik.Media.Font
{
public readonly struct FontFace : IEquatable<FontFace>
{
public string Family { get; }
public FontSlant Slant { get; }
public FontWeight Weight { get; }
public FontStretch Stretch { get; }
public FontFace(string family, FontSlant slant, FontWeight weight, FontStretch stretch)
{
Family = family;
Slant = slant;
Weight = weight;
Stretch = stretch;
}
public override string ToString()
{
StringBuilder builder = new StringBuilder(Family);
if (Slant != FontSlant.Normal)
{
builder.Append(' ');
builder.Append(Slant);
}
if (Stretch != FontStretch.Normal)
{
builder.Append(' ');
builder.Append(Stretch);
}
if (Weight != FontWeight.Normal)
{
builder.Append(' ');
builder.Append(Weight);
}
if (Slant == FontSlant.Normal &&
Stretch == FontStretch.Normal &&
Weight == FontWeight.Normal)
{
builder.Append(" Regular");
}
return builder.ToString();
}
public override int GetHashCode()
{
return HashCode.Combine(Family, Slant, Weight, Stretch);
}
public static bool operator==(FontFace a, FontFace b)
{
return (a.Slant == b.Slant) &&
(a.Weight == b.Weight) &&
(a.Stretch == b.Stretch) &&
(a.Family == a.Family);
}
public static bool operator!=(FontFace a, FontFace b)
{
return (a.Slant != b.Slant) ||
(a.Weight != b.Weight) ||
(a.Stretch != b.Stretch) ||
(a.Family != b.Family);
}
public bool Equals(FontFace other)
{
return this == other;
}
public override bool Equals(object obj)
{
return (obj.GetType() == typeof(FontFace)) &&
this == (FontFace)obj;
}
public static FontFace Parse(string family, string style)
{
FontSlant slant = FontSlant.Normal;
FontWeight weight = FontWeight.Normal;
FontStretch stretch = FontStretch.Normal;
string[] tokens = style.Split(' ');
foreach (string token in tokens)
{
/**/ if (TryParseSlant(token, out FontSlant xslant)) slant = xslant;
else if (TryParseWeight(token, out FontWeight xweight)) weight = xweight;
else if (TryParseStretch(token, out FontStretch xstretch)) stretch = xstretch;
}
return new FontFace(family, slant, weight, stretch);
}
public static FontFace Parse(string face)
{
StringBuilder family = new StringBuilder();
FontSlant slant = FontSlant.Normal;
FontWeight weight = FontWeight.Normal;
FontStretch stretch = FontStretch.Normal;
string[] tokens = face.Split(' ');
foreach (string token in tokens)
{
string xtoken = token.ToLower();
if (xtoken == "regular" || xtoken == "normal")
{
continue;
}
else if (TryParseSlant(xtoken, out FontSlant xslant)) slant = xslant;
else if (TryParseWeight(xtoken, out FontWeight xweight)) weight = xweight;
else if (TryParseStretch(xtoken, out FontStretch xstretch)) stretch = xstretch;
else
{
family.Append(token);
}
}
return new FontFace(family.ToString(), slant, weight, stretch);
}
/// <summary>
/// Try to convert a token that represents a font slant into its enum.
/// </summary>
/// <param name="token">The token to interpret.</param>
/// <param name="slant">The resulting slant.</param>
/// <returns>True if it matched any.</returns>
public static bool TryParseSlant(string token, out FontSlant slant)
{
switch (token.ToLower())
{
case "italic":
slant = FontSlant.Italic;
return true;
case "oblique":
slant = FontSlant.Oblique;
return true;
default:
slant = FontSlant.Normal;
return false;
}
}
/// <summary>
/// Try to convert a token that represents a font weight into its enum.
/// </summary>
/// <param name="token">The token to interpret.</param>
/// <param name="weight">The resulting weight.</param>
/// <returns>True if it matched any.</returns>
public static bool TryParseWeight(string token, out FontWeight weight)
{
switch (token.ToLower())
{
case "thin":
weight = FontWeight.Thin;
return true;
case "extralight":
case "ultralight":
weight = FontWeight._200;
return true;
case "light":
case "demilight":
case "semilight":
weight = FontWeight._300;
return true;
case "demibold":
case "semibold":
weight = FontWeight._600;
return true;
case "bold":
weight = FontWeight._700;
return true;
case "extrabold":
case "ultrabold":
weight = FontWeight._800;
return true;
case "heavy":
case "extrablack":
case "black":
case "ultrablack":
weight = FontWeight._900;
return true;
default:
weight = FontWeight.Normal;
return false;
}
}
/// <summary>
/// Try to convert a token that represents a font stretch into its enum.
/// </summary>
/// <param name="token">The token to interpret.</param>
/// <param name="stretch">The resulting stretch.</param>
/// <returns>True if it matched any.</returns>
public static bool TryParseStretch(string token, out FontStretch stretch)
{
switch (token.ToLower())
{
case "ultracondensed":
stretch = FontStretch.UltraCondensed;
return true;
case "extracondensed":
stretch = FontStretch.ExtraCondensed;
return true;
case "condensed":
stretch = FontStretch.Condensed;
return true;
case "semicondensed":
case "demicondensed":
stretch = FontStretch.SemiCondensed;
return true;
case "semiexpanded":
case "demiexpanded":
stretch = FontStretch.SemiExpanded;
return true;
case "expanded":
stretch = FontStretch.Expanded;
return true;
case "extraexpanded":
stretch = FontStretch.ExtraExpanded;
return true;
case "ultraexpanded":
stretch = FontStretch.UltraExpanded;
return true;
default:
stretch = FontStretch.Normal;
return false;
}
}
}
}