Skip to main content

gpui/text_system/
font_metrics.rs

1use crate::{Bounds, Pixels};
2
3/// The measurements of a typeface, in font units.
4///
5/// Get the values for a font with [`TextSystem::resolve_font`](crate::TextSystem::resolve_font) and the
6/// `TextSystem` metric methods. The methods on this type convert the values to
7/// pixels at a given font size. Use the font-unit fields directly only when
8/// you need exact values.
9#[derive(Clone, Copy, Debug)]
10pub struct FontMetrics {
11    /// The number of font units that make up the em square, the grid that font sizes are measured on.
12    pub units_per_em: u32,
13
14    /// The distance from the baseline up to the top of the tallest glyphs, in font units.
15    pub ascent: f32,
16
17    /// The distance from the baseline down to the bottom of the lowest glyphs, in font units.
18    pub descent: f32,
19
20    /// The extra space the font recommends between lines, in font units.
21    pub line_gap: f32,
22
23    /// The suggested vertical position of the underline, in font units.
24    pub underline_position: f32,
25
26    /// The suggested thickness of the underline, in font units.
27    pub underline_thickness: f32,
28
29    /// The height of a capital letter above the baseline, in font units.
30    pub cap_height: f32,
31
32    /// The height of a lowercase `x` above the baseline, in font units.
33    pub x_height: f32,
34
35    /// The outer limits of the area that the font covers, in font units.
36    /// Corresponds to the xMin / xMax / yMin / yMax values in the OpenType `head` table.
37    pub bounding_box: Bounds<f32>,
38}
39
40impl FontMetrics {
41    /// Returns the distance from the baseline up to the tallest glyphs, in pixels at `font_size`.
42    pub fn ascent(&self, font_size: Pixels) -> Pixels {
43        Pixels((self.ascent / self.units_per_em as f32) * font_size.0)
44    }
45
46    /// Returns the distance from the baseline down to the lowest glyphs, in pixels at `font_size`.
47    pub fn descent(&self, font_size: Pixels) -> Pixels {
48        Pixels((self.descent / self.units_per_em as f32) * font_size.0)
49    }
50
51    /// Returns the recommended extra space between lines, in pixels at `font_size`.
52    pub fn line_gap(&self, font_size: Pixels) -> Pixels {
53        Pixels((self.line_gap / self.units_per_em as f32) * font_size.0)
54    }
55
56    /// Returns the suggested position of the underline, in pixels at `font_size`.
57    pub fn underline_position(&self, font_size: Pixels) -> Pixels {
58        Pixels((self.underline_position / self.units_per_em as f32) * font_size.0)
59    }
60
61    /// Returns the suggested thickness of the underline, in pixels at `font_size`.
62    pub fn underline_thickness(&self, font_size: Pixels) -> Pixels {
63        Pixels((self.underline_thickness / self.units_per_em as f32) * font_size.0)
64    }
65
66    /// Returns the height of a capital letter above the baseline, in pixels at `font_size`.
67    pub fn cap_height(&self, font_size: Pixels) -> Pixels {
68        Pixels((self.cap_height / self.units_per_em as f32) * font_size.0)
69    }
70
71    /// Returns the height of a lowercase `x` above the baseline, in pixels at `font_size`.
72    pub fn x_height(&self, font_size: Pixels) -> Pixels {
73        Pixels((self.x_height / self.units_per_em as f32) * font_size.0)
74    }
75
76    /// Returns the outer limits of the area that the font covers, in pixels at `font_size`.
77    pub fn bounding_box(&self, font_size: Pixels) -> Bounds<Pixels> {
78        (self.bounding_box / self.units_per_em as f32 * font_size.0).map(crate::px)
79    }
80}