Skip to main content

markdown/
typography.rs

1//! What a document is set in.
2//!
3//! Installed once at boot like the highlighter and the link preview, and read
4//! at paint: how a document is set is the app's decision, and this crate holds
5//! only what it defaults to.
6
7use gpui::{App, FontWeight, Global};
8use theme::{Metrics, TextStyle};
9
10/// What a document is set in, role by role.
11#[derive(Clone, Copy, Debug, PartialEq)]
12pub struct Typography {
13    pub body: Metrics,
14    pub h1: Metrics,
15    pub h2: Metrics,
16    pub h3: Metrics,
17    /// Every heading past the third.
18    pub h4: Metrics,
19    /// Code, in a fence and inline.
20    pub code: Metrics,
21    /// A bookmark card's blurb and footer.
22    pub card: Metrics,
23    /// An image's caption.
24    pub caption: Metrics,
25}
26
27impl Typography {
28    /// What documents are set in, or [`Typography::default`] before anything is
29    /// installed. Mirrors [`theme::Theme::of`].
30    pub fn of(cx: &App) -> Self {
31        cx.try_global::<Installed>()
32            .map_or_else(Self::default, |installed| installed.0)
33    }
34
35    pub fn heading(&self, level: u8) -> Metrics {
36        match level {
37            1 => self.h1,
38            2 => self.h2,
39            3 => self.h3,
40            _ => self.h4,
41        }
42    }
43}
44
45impl Default for Typography {
46    /// Each leading is written as the pixel pair it came from, so the ratio the
47    /// document was tuned at survives a change of size.
48    fn default() -> Self {
49        Self {
50            body: Metrics::new(TextStyle::Body, 22.0 / 14.0, FontWeight::NORMAL),
51            h1: Metrics::new(TextStyle::Title, 27.0 / 19.0, FontWeight::SEMIBOLD),
52            h2: Metrics::new(TextStyle::Title2, 24.0 / 16.0, FontWeight::SEMIBOLD),
53            h3: Metrics::new(TextStyle::Title3, 22.0 / 15.0, FontWeight::SEMIBOLD),
54            h4: Metrics::new(TextStyle::Headline, 22.0 / 14.0, FontWeight::SEMIBOLD),
55            code: Metrics::new(TextStyle::Callout, 18.0 / 12.5, FontWeight::NORMAL),
56            card: Metrics::new(TextStyle::Callout, 17.0 / 12.0, FontWeight::NORMAL),
57            caption: Metrics::new(TextStyle::Subheadline, 17.0 / 11.5, FontWeight::NORMAL),
58        }
59    }
60}
61
62struct Installed(Typography);
63
64impl Global for Installed {}
65
66/// `markdown::set_typography(cx, my_typography)` — call once at boot.
67pub fn set_typography(cx: &mut App, typography: Typography) {
68    cx.set_global(Installed(typography));
69}