gpui/text_system/font.rs
1use crate::{FontFallbacks, FontFeatures, FontStyle, FontWeight, FontWidth};
2use gpui_shared_string::SharedString;
3
4/// An opaque identifier for a font face that the [`TextSystem`](crate::TextSystem) has resolved.
5///
6/// Get one with [`TextSystem::resolve_font`](crate::TextSystem::resolve_font). The id is valid for the lifetime of
7/// the [`TextSystem`](crate::TextSystem) that produced it and is used for metrics and glyph rasterization.
8#[derive(Hash, PartialEq, Eq, Clone, Copy, Debug)]
9#[repr(C)]
10pub struct FontId(pub usize);
11
12/// The face to use for text: a font family plus its weight, width, style, features, and fallbacks.
13///
14/// Build one with [`font`] and then adjust it with the builder methods, or set
15/// the public fields directly. The [`TextSystem`](crate::TextSystem) caches lookups by `Font`, so
16/// equal fonts share one lookup.
17///
18/// The default is the family `.SystemUIFont`, which the platform maps to its
19/// system interface font. Use a named family when the look must be the same
20/// on every platform.
21///
22/// # Examples
23///
24/// ```
25/// # use gpui::{Font, FontStyle, FontWeight, font};
26/// let heading = font("Lilex").bold();
27/// assert_eq!(heading.weight, FontWeight::BOLD);
28///
29/// let quote = Font {
30/// style: FontStyle::Italic,
31/// ..font("Source Serif 4")
32/// };
33/// assert_eq!(quote.style, FontStyle::Italic);
34/// ```
35///
36/// See [text](crate::_documentation::guides::text) for how fonts are chosen and
37/// how to add your own.
38#[derive(Clone, Debug, Eq, PartialEq, Hash)]
39pub struct Font {
40 /// The font family name, such as `"Lilex"`.
41 ///
42 /// The special name `.SystemUIFont` refers to the system interface font,
43 /// which differs by platform. Names come from [`TextSystem::all_font_names`](crate::TextSystem::all_font_names).
44 pub family: SharedString,
45
46 /// The OpenType features to apply, such as ligatures or tabular figures.
47 pub features: FontFeatures,
48
49 /// Families to try, in order, when [`Font::family`] has no glyph for a character.
50 pub fallbacks: Option<FontFallbacks>,
51
52 /// The weight of the face. See [`FontWeight`].
53 pub weight: FontWeight,
54
55 /// The width of the face. Exhaustive font literals must supply this field.
56 pub width: FontWidth,
57
58 /// Whether to select the italic or oblique face. See [`FontStyle`].
59 pub style: FontStyle,
60}
61
62impl Default for Font {
63 /// Returns the `.SystemUIFont` family with normal weight, width, and style.
64 fn default() -> Self {
65 font(".SystemUIFont")
66 }
67}
68
69/// Returns a [`Font`] for `family`, with normal weight, width, and style.
70///
71/// Pass a family name from [`TextSystem::all_font_names`](crate::TextSystem::all_font_names) or one you added with
72/// [`TextSystem::add_fonts`](crate::TextSystem::add_fonts). Chain [`Font::bold`] or [`Font::italic`] to change
73/// the style.
74///
75/// # Examples
76///
77/// ```
78/// # use gpui::{FontStyle, FontWeight, font};
79/// let body = font("Lilex");
80/// assert_eq!(body.family.as_ref(), "Lilex");
81/// assert_eq!(body.weight, FontWeight::NORMAL);
82/// assert_eq!(body.style, FontStyle::Normal);
83/// ```
84pub fn font(family: impl Into<SharedString>) -> Font {
85 Font {
86 family: family.into(),
87 features: FontFeatures::default(),
88 weight: FontWeight::default(),
89 width: FontWidth::default(),
90 style: FontStyle::default(),
91 fallbacks: None,
92 }
93}
94
95impl Font {
96 /// Returns this font with the weight set to [`FontWeight::BOLD`].
97 pub fn bold(mut self) -> Self {
98 self.weight = FontWeight::BOLD;
99 self
100 }
101
102 /// Returns this font with the style set to [`FontStyle::Italic`].
103 pub fn italic(mut self) -> Self {
104 self.style = FontStyle::Italic;
105 self
106 }
107}