1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
//! Font families, weights, etcetera
use std::sync::Arc;
/// A reference to a font family.
///
/// This may be either a CSS-style "generic family name", such as "serif"
/// or "monospace", or it can be an explicit family name.
///
/// To use a generic family name, use the provided associated constants:
/// `FontFamily::SERIF`, `FontFamily::SANS_SERIF`, `FontFamily::SYSTEM_UI`,
/// and `FontFamily::MONOSPACE`.
///
/// To use a specific font family you should not construct this type directly;
/// instead you should verify that the desired family exists, via the
/// [`Text::font_family`] API.
///
/// [`Text::font_family`]: crate::Text::font_family
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct FontFamily(FontFamilyInner);
/// The inner representation of a font family.
///
/// This is not public API for users of piet; it is exposed for backends only.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[doc(hidden)]
#[non_exhaustive]
pub enum FontFamilyInner {
Serif,
SansSerif,
Monospace,
SystemUi,
Named(Arc<str>),
}
/// A font weight, represented as a value in the range 1..=1000.
///
/// This is based on the [CSS `font-weight`] property. In general, you should
/// prefer the constants defined on this type, such as `FontWeight::REGULAR` or
/// `FontWeight::BOLD`.
///
/// [CSS `font-weight`]: https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct FontWeight(u16);
/// A font style, which may be italic or regular.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum FontStyle {
/// Prefer the regular style for the current font family, if available.
Regular,
/// Prefer the italic style for the current font family, if available.
///
/// If italic is not available and oblique is, we will use that; if neither
/// is available we will apply synthetic italics to the regular style.
Italic,
}
impl FontFamily {
/// A san-serif font, such as Arial or Helvetica.
pub const SANS_SERIF: FontFamily = FontFamily(FontFamilyInner::SansSerif);
/// A serif font, such as Times New Roman or Charter.
pub const SERIF: FontFamily = FontFamily(FontFamilyInner::Serif);
/// The platform's preferred UI font; San Francisco on macOS, and Segoe UI
/// on recent Windows.
pub const SYSTEM_UI: FontFamily = FontFamily(FontFamilyInner::SystemUi);
/// A monospace font.
pub const MONOSPACE: FontFamily = FontFamily(FontFamilyInner::Monospace);
/// Create a new font family with a given name, without verifying that it exists.
///
/// This should generally not be used; instead you should create a `FontFamily`
/// by calling the [`Text::font_family`] method, which verifies that the
/// family name exists.
///
/// [`Text::font_family`]: crate::Text::font_family
pub fn new_unchecked(s: impl Into<Arc<str>>) -> Self {
FontFamily(FontFamilyInner::Named(s.into()))
}
/// The name of the font family.
pub fn name(&self) -> &str {
match &self.0 {
FontFamilyInner::Serif => "serif",
FontFamilyInner::SansSerif => "sans-serif",
FontFamilyInner::SystemUi => "system-ui",
FontFamilyInner::Monospace => "monospace",
FontFamilyInner::Named(s) => s,
}
}
/// Returns `true` if this is a generic font family.
pub fn is_generic(&self) -> bool {
!matches!(self.0, FontFamilyInner::Named(_))
}
/// Backend-only API; access the inner `FontFamilyInner` enum.
#[doc(hidden)]
pub fn inner(&self) -> &FontFamilyInner {
&self.0
}
}
impl FontWeight {
/// 100
pub const THIN: FontWeight = FontWeight(100);
/// 100
pub const HAIRLINE: FontWeight = FontWeight::THIN;
/// 200
pub const EXTRA_LIGHT: FontWeight = FontWeight(200);
/// 300
pub const LIGHT: FontWeight = FontWeight(300);
/// 400
pub const REGULAR: FontWeight = FontWeight(400);
/// 400
pub const NORMAL: FontWeight = FontWeight::REGULAR;
/// 500
pub const MEDIUM: FontWeight = FontWeight(500);
/// 600
pub const SEMI_BOLD: FontWeight = FontWeight(600);
/// 700
pub const BOLD: FontWeight = FontWeight(700);
/// 800
pub const EXTRA_BOLD: FontWeight = FontWeight(800);
/// 900
pub const BLACK: FontWeight = FontWeight(900);
/// 900
pub const HEAVY: FontWeight = FontWeight::BLACK;
/// 950
pub const EXTRA_BLACK: FontWeight = FontWeight(950);
/// Create a new `FontWeight` with a custom value.
///
/// Values will be clamped to the range 1..=1000.
pub fn new(raw: u16) -> FontWeight {
let raw = raw.clamp(1, 1000);
FontWeight(raw)
}
/// Return the raw value as a u16.
pub const fn to_raw(self) -> u16 {
self.0
}
}
impl Default for FontFamily {
fn default() -> Self {
FontFamily::SYSTEM_UI
}
}
impl Default for FontWeight {
fn default() -> Self {
FontWeight::REGULAR
}
}
impl Default for FontStyle {
fn default() -> Self {
FontStyle::Regular
}
}