Skip to main content

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}