A game framework written with osu! in mind.
1// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
2// See the LICENCE file in the repository root for full licence text.
3
4using System;
5using JetBrains.Annotations;
6
7namespace osu.Framework.Graphics.Sprites
8{
9 /// <summary>
10 /// Represents a specific usage of a font.
11 /// </summary>
12 public readonly struct FontUsage : IEquatable<FontUsage>
13 {
14 private const float default_text_size = 20;
15
16 /// <summary>
17 /// Gets the default <see cref="FontUsage"/>, using the fallback font family.
18 /// </summary>
19 public static FontUsage Default => new FontUsage(null);
20
21 /// <summary>
22 /// The font family name.
23 /// </summary>
24 [CanBeNull]
25 public string Family { get; }
26
27 /// <summary>
28 /// The font weight.
29 /// </summary>
30 [CanBeNull]
31 public string Weight { get; }
32
33 /// <summary>
34 /// Whether the font is italic.
35 /// </summary>
36 public bool Italics { get; }
37
38 /// <summary>
39 /// The size of the text in local space. For a value of 16, a single line will have a height of 16px.
40 /// </summary>
41 public float Size { get; }
42
43 /// <summary>
44 /// Whether all characters should be spaced the same distance apart.
45 /// </summary>
46 public bool FixedWidth { get; }
47
48 /// <summary>
49 /// The font's full name to be used for lookups. This is an aggregate of all other properties of <see cref="FontUsage"/>.
50 /// <remarks>
51 /// The format is of the form: <br />
52 /// {Family} <br />
53 /// {Family}-Italic <br />
54 /// {Family}-{Weight}Italic
55 /// </remarks>
56 /// </summary>
57 [NotNull]
58 public string FontName { get; }
59
60 /// <summary>
61 /// Creates an instance of <see cref="FontUsage"/> using the specified font <paramref name="family"/>, font <paramref name="weight"/> and a value indicating whether the used font is italic or not.
62 /// </summary>
63 /// <param name="family">The font family name.</param>
64 /// <param name="size">The size of the text in local space. For a value of 16, a single line will have a height of 16px.</param>
65 /// <param name="weight">The font weight.</param>
66 /// <param name="italics">Whether the font is italic.</param>
67 /// <param name="fixedWidth">Whether all characters should be spaced the same distance apart.</param>
68 public FontUsage([CanBeNull] string family = null, float size = default_text_size, [CanBeNull] string weight = null, bool italics = false, bool fixedWidth = false)
69 {
70 Family = family;
71 Size = size >= 0 ? size : throw new ArgumentOutOfRangeException(nameof(size), "Must be non-negative.");
72 Weight = weight;
73 Italics = italics;
74 FixedWidth = fixedWidth;
75
76 FontName = Family + "-";
77 if (!string.IsNullOrEmpty(weight))
78 FontName += weight;
79
80 if (italics)
81 FontName += "Italic";
82
83 FontName = FontName.TrimEnd('-');
84 }
85
86 /// <summary>
87 /// Creates a new <see cref="FontUsage"/> by applying adjustments to this <see cref="FontUsage"/>.
88 /// </summary>
89 /// <param name="family">The font family. If null, the value is copied from this <see cref="FontUsage"/>.</param>
90 /// <param name="size">The text size. If null, the value is copied from this <see cref="FontUsage"/>.</param>
91 /// <param name="weight">The font weight. If null, the value is copied from this <see cref="FontUsage"/>.</param>
92 /// <param name="italics">Whether the font is italic. If null, the value is copied from this <see cref="FontUsage"/>.</param>
93 /// <param name="fixedWidth">Whether all characters should be spaced apart the same distance. If null, the value is copied from this <see cref="FontUsage"/>.</param>
94 /// <returns>The resulting <see cref="FontUsage"/>.</returns>
95 public FontUsage With([CanBeNull] string family = null, [CanBeNull] float? size = null, [CanBeNull] string weight = null, [CanBeNull] bool? italics = null,
96 [CanBeNull] bool? fixedWidth = null)
97 => new FontUsage(family ?? Family, size ?? Size, weight ?? Weight, italics ?? Italics, fixedWidth ?? FixedWidth);
98
99 public override string ToString() => $"Font={FontName}, Size={Size}, Italics={Italics}, FixedWidth={FixedWidth}";
100
101 public bool Equals(FontUsage other) => Family == other.Family && Weight == other.Weight && Italics == other.Italics && Size.Equals(other.Size) && FixedWidth == other.FixedWidth;
102
103 public override bool Equals(object obj) => obj is FontUsage other && Equals(other);
104
105 public override int GetHashCode() => HashCode.Combine(Family, Weight, Italics, Size, FixedWidth);
106 }
107}