Add new font search criterea.
This commit is contained in:
parent
bc3dcff3ea
commit
ccb0c6ffe7
240
Quik/Media/Font/FontFace.cs
Normal file
240
Quik/Media/Font/FontFace.cs
Normal file
@ -0,0 +1,240 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
9
Quik/Media/Font/FontSlant.cs
Normal file
9
Quik/Media/Font/FontSlant.cs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
namespace Quik.Media.Font
|
||||||
|
{
|
||||||
|
public enum FontSlant
|
||||||
|
{
|
||||||
|
Normal = 0,
|
||||||
|
Italic = 1,
|
||||||
|
Oblique = 2,
|
||||||
|
}
|
||||||
|
}
|
18
Quik/Media/Font/FontStretch.cs
Normal file
18
Quik/Media/Font/FontStretch.cs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
namespace Quik.Media.Font
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Enumeration of font stretch values.
|
||||||
|
/// </summary>
|
||||||
|
public enum FontStretch
|
||||||
|
{
|
||||||
|
UltraCondensed = 500,
|
||||||
|
ExtraCondensed = 625,
|
||||||
|
Condensed = 750,
|
||||||
|
SemiCondensed = 875,
|
||||||
|
Normal = 1000,
|
||||||
|
SemiExpanded = 1125,
|
||||||
|
Expanded = 1250,
|
||||||
|
ExtraExpanded = 1500,
|
||||||
|
UltraExpanded = 2000,
|
||||||
|
}
|
||||||
|
}
|
22
Quik/Media/Font/FontWeight.cs
Normal file
22
Quik/Media/Font/FontWeight.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Quik.Media.Font
|
||||||
|
{
|
||||||
|
public enum FontWeight
|
||||||
|
{
|
||||||
|
_100 = 100,
|
||||||
|
_200 = 200,
|
||||||
|
_300 = 300,
|
||||||
|
_400 = 400,
|
||||||
|
_500 = 500,
|
||||||
|
_600 = 600,
|
||||||
|
_700 = 700,
|
||||||
|
_800 = 800,
|
||||||
|
_900 = 900,
|
||||||
|
|
||||||
|
Thin = _100,
|
||||||
|
Normal = _400,
|
||||||
|
Bold = _700,
|
||||||
|
Heavy = _900,
|
||||||
|
}
|
||||||
|
}
|
@ -1,44 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace Quik.Media
|
|
||||||
{
|
|
||||||
public struct FontInfo : IEquatable<FontInfo>
|
|
||||||
{
|
|
||||||
public string Family { get; }
|
|
||||||
public FontStyle Style { get; }
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
return $"{Family} {Style}";
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int GetHashCode()
|
|
||||||
{
|
|
||||||
return Family.GetHashCode() ^
|
|
||||||
(Style.GetHashCode() * 3976061);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator==(FontInfo a, FontInfo b)
|
|
||||||
{
|
|
||||||
return (a.Style == b.Style) &&
|
|
||||||
(a.Family == a.Family);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator!=(FontInfo a, FontInfo b)
|
|
||||||
{
|
|
||||||
return (a.Style != b.Style) ||
|
|
||||||
(a.Family != b.Family);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Equals(FontInfo other)
|
|
||||||
{
|
|
||||||
return this == other;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Equals(object obj)
|
|
||||||
{
|
|
||||||
return (obj.GetType() == typeof(FontInfo)) &&
|
|
||||||
this == (FontInfo)obj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace Quik.Media
|
|
||||||
{
|
|
||||||
[Flags]
|
|
||||||
public enum FontStyle
|
|
||||||
{
|
|
||||||
Italic = 1 << 0,
|
|
||||||
Bold = 1 << 1,
|
|
||||||
|
|
||||||
Normal = 0,
|
|
||||||
BoldItalic = Italic | Bold,
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,4 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Quik.Media;
|
||||||
|
using Quik.Media.Font;
|
||||||
|
|
||||||
namespace Quik.Media
|
namespace Quik.Media
|
||||||
{
|
{
|
||||||
@ -7,9 +10,11 @@ namespace Quik.Media
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class QFont : IDisposable
|
public abstract class QFont : IDisposable
|
||||||
{
|
{
|
||||||
public abstract FontInfo Info { get; }
|
public abstract FontFace Face { get; }
|
||||||
public string Family => Info.Family;
|
public string Family => Face.Family;
|
||||||
public FontStyle Style => Info.Style;
|
public FontSlant Slant => Face.Slant;
|
||||||
|
public FontWeight Weight => Face.Weight;
|
||||||
|
public FontStretch Stretch => Face.Stretch;
|
||||||
|
|
||||||
public abstract bool HasRune(int rune);
|
public abstract bool HasRune(int rune);
|
||||||
public abstract QFontPage RasterizePage(int codepage, float size, in FontRasterizerOptions options);
|
public abstract QFontPage RasterizePage(int codepage, float size, in FontRasterizerOptions options);
|
||||||
|
@ -10,11 +10,6 @@ namespace Quik.Media
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public int Rune { get; }
|
public int Rune { get; }
|
||||||
|
|
||||||
// /// <summary>
|
|
||||||
// /// Location of the glyph on the atlas.
|
|
||||||
// /// </summary>
|
|
||||||
// public QRectangle Location { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Size of the glyph in units.
|
/// Size of the glyph in units.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -37,14 +32,12 @@ namespace Quik.Media
|
|||||||
|
|
||||||
public QGlyphMetrics(
|
public QGlyphMetrics(
|
||||||
int character,
|
int character,
|
||||||
// QRectangle location,
|
|
||||||
QVec2 size,
|
QVec2 size,
|
||||||
QVec2 horizontalBearing,
|
QVec2 horizontalBearing,
|
||||||
QVec2 verticalBearing,
|
QVec2 verticalBearing,
|
||||||
QVec2 advance)
|
QVec2 advance)
|
||||||
{
|
{
|
||||||
Rune = character;
|
Rune = character;
|
||||||
// Location = location;
|
|
||||||
Size = size;
|
Size = size;
|
||||||
HorizontalBearing = horizontalBearing;
|
HorizontalBearing = horizontalBearing;
|
||||||
VerticalBearing = verticalBearing;
|
VerticalBearing = verticalBearing;
|
||||||
|
54
Quik/PAL/IFontDatabase.cs
Normal file
54
Quik/PAL/IFontDatabase.cs
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using Quik.Media.Font;
|
||||||
|
|
||||||
|
namespace Quik.PAL
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Flags that effect font search criterea.
|
||||||
|
/// </summary>
|
||||||
|
[Flags]
|
||||||
|
public enum FontMatchCriteria
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Family = 1 << 0,
|
||||||
|
Slant = 1 << 1,
|
||||||
|
Weight = 1 << 2,
|
||||||
|
Stretch = 1 << 3,
|
||||||
|
All = Family | Slant | Weight | Stretch,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An abstraction over the system font database.
|
||||||
|
/// </summary>
|
||||||
|
public interface IFontDataBase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// All the fonts installed in the system.
|
||||||
|
/// </summary>
|
||||||
|
IEnumerable<FontFace> All { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Search for the given font face.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="prototype">The font face prototype.</param>
|
||||||
|
/// <param name="criteria">The match criteria</param>
|
||||||
|
/// <returns>A list of fonts sorted by the closest match first.</returns>
|
||||||
|
IEnumerable<FontFace> Search(FontFace prototype, FontMatchCriteria criteria = FontMatchCriteria.All);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the font face file info if it exists.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="face">The face to look for.</param>
|
||||||
|
/// <returns>The file info if it exists.</returns>
|
||||||
|
FileInfo FontFileInfo(FontFace face);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Open a font face.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="face">The font face to open.</param>
|
||||||
|
/// <returns>The stream to the font face.</returns>
|
||||||
|
Stream Open(FontFace face);
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Quik.Media;
|
using Quik.Media;
|
||||||
using Quik.Typography;
|
using Quik.Media.Font;
|
||||||
|
|
||||||
namespace Quik
|
namespace Quik
|
||||||
{
|
{
|
||||||
@ -109,9 +109,9 @@ namespace Quik
|
|||||||
set => this["list-marker-position"] = value;
|
set => this["list-marker-position"] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public QuikTexture ListMarkerImage
|
public QImage ListMarkerImage
|
||||||
{
|
{
|
||||||
get => (QuikTexture)this["list-marker-image"];
|
get => (QImage)this["list-marker-image"];
|
||||||
set => this["list-marker-image"] = value;
|
set => this["list-marker-image"] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,9 +127,9 @@ namespace Quik
|
|||||||
set => this["stroke-color"] = value;
|
set => this["stroke-color"] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FontInfo Font
|
public FontFace Font
|
||||||
{
|
{
|
||||||
get => (FontInfo)this["font"];
|
get => (FontFace)this["font"];
|
||||||
set => this["font"] = value;
|
set => this["font"] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user