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}