238 lines
7.9 KiB
C#
238 lines
7.9 KiB
C#
using System;
|
|
using System.Text;
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
} |