skia_safe/core/
font_style.rs

1use crate::prelude::*;
2use skia_bindings::{self as sb, SkFontStyle, SkFontStyle_Weight, SkFontStyle_Width};
3use std::{fmt, ops::Deref};
4
5/// Wrapper type of a font weight.
6///
7/// Use Weight::from() to create a weight from an i32.
8/// Use *weight to pull out the wrapped value of the Weight.
9#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
10#[repr(transparent)]
11pub struct Weight(i32);
12
13native_transmutable!(i32, Weight, weight_layout);
14
15impl From<i32> for Weight {
16    fn from(weight: i32) -> Self {
17        Weight(weight)
18    }
19}
20
21impl Deref for Weight {
22    type Target = i32;
23    fn deref(&self) -> &Self::Target {
24        &self.0
25    }
26}
27
28#[allow(non_upper_case_globals)]
29impl Weight {
30    pub const INVISIBLE: Self = Self(SkFontStyle_Weight::kInvisible_Weight as _);
31    pub const THIN: Self = Self(SkFontStyle_Weight::kThin_Weight as _);
32    pub const EXTRA_LIGHT: Self = Self(SkFontStyle_Weight::kExtraLight_Weight as _);
33    pub const LIGHT: Self = Self(SkFontStyle_Weight::kLight_Weight as _);
34    pub const NORMAL: Self = Self(SkFontStyle_Weight::kNormal_Weight as _);
35    pub const MEDIUM: Self = Self(SkFontStyle_Weight::kMedium_Weight as _);
36    pub const SEMI_BOLD: Self = Self(SkFontStyle_Weight::kSemiBold_Weight as _);
37    pub const BOLD: Self = Self(SkFontStyle_Weight::kBold_Weight as _);
38    pub const EXTRA_BOLD: Self = Self(SkFontStyle_Weight::kExtraBold_Weight as _);
39    pub const BLACK: Self = Self(SkFontStyle_Weight::kBlack_Weight as _);
40    pub const EXTRA_BLACK: Self = Self(SkFontStyle_Weight::kExtraBlack_Weight as _);
41}
42
43/// Wrapper type for the width of a font.
44///
45/// To create a width of a font from an i32, use Width::from().
46/// To access the underlying value of the font weight, dereference *weight.
47#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
48#[repr(transparent)]
49pub struct Width(i32);
50
51native_transmutable!(i32, Width, width_layout);
52
53impl From<i32> for Width {
54    fn from(width: i32) -> Self {
55        Width(width)
56    }
57}
58
59impl Deref for Width {
60    type Target = i32;
61    fn deref(&self) -> &Self::Target {
62        &self.0
63    }
64}
65
66#[allow(non_upper_case_globals)]
67impl Width {
68    pub const ULTRA_CONDENSED: Self = Self(SkFontStyle_Width::kUltraCondensed_Width as _);
69    pub const EXTRA_CONDENSED: Self = Self(SkFontStyle_Width::kExtraCondensed_Width as _);
70    pub const CONDENSED: Self = Self(SkFontStyle_Width::kCondensed_Width as _);
71    pub const SEMI_CONDENSED: Self = Self(SkFontStyle_Width::kSemiCondensed_Width as _);
72    pub const NORMAL: Self = Self(SkFontStyle_Width::kNormal_Width as _);
73    pub const SEMI_EXPANDED: Self = Self(SkFontStyle_Width::kSemiExpanded_Width as _);
74    pub const EXPANDED: Self = Self(SkFontStyle_Width::kExpanded_Width as _);
75    pub const EXTRA_EXPANDED: Self = Self(SkFontStyle_Width::kExtraExpanded_Width as _);
76    pub const ULTRA_EXPANDED: Self = Self(SkFontStyle_Width::kUltraExpanded_Width as _);
77}
78
79pub use skia_bindings::SkFontStyle_Slant as Slant;
80variant_name!(Slant::Upright);
81
82// TODO: implement Display
83#[derive(Copy, Clone)]
84#[repr(transparent)]
85pub struct FontStyle(SkFontStyle);
86
87native_transmutable!(SkFontStyle, FontStyle, font_style_layout);
88
89impl PartialEq for FontStyle {
90    fn eq(&self, rhs: &Self) -> bool {
91        unsafe { sb::C_SkFontStyle_Equals(self.native(), rhs.native()) }
92    }
93}
94
95impl Default for FontStyle {
96    fn default() -> Self {
97        FontStyle::construct(|fs| unsafe { sb::C_SkFontStyle_Construct(fs) })
98    }
99}
100
101impl fmt::Debug for FontStyle {
102    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
103        f.debug_struct("FontStyle")
104            .field("weight", &self.weight())
105            .field("width", &self.width())
106            .field("slant", &self.slant())
107            .finish()
108    }
109}
110
111impl FontStyle {
112    pub fn new(weight: Weight, width: Width, slant: Slant) -> Self {
113        Self::construct(|fs| unsafe {
114            sb::C_SkFontStyle_Construct2(fs, weight.into_native(), width.into_native(), slant)
115        })
116    }
117
118    pub fn weight(self) -> Weight {
119        Weight::from_native_c(unsafe { sb::C_SkFontStyle_weight(self.native()) })
120    }
121
122    pub fn width(self) -> Width {
123        Width::from_native_c(unsafe { sb::C_SkFontStyle_width(self.native()) })
124    }
125
126    pub fn slant(self) -> Slant {
127        unsafe { sb::C_SkFontStyle_slant(self.native()) }
128    }
129
130    pub fn normal() -> FontStyle {
131        *font_style_static::NORMAL
132    }
133
134    pub fn bold() -> FontStyle {
135        *font_style_static::BOLD
136    }
137
138    pub fn italic() -> FontStyle {
139        *font_style_static::ITALIC
140    }
141
142    pub fn bold_italic() -> FontStyle {
143        *font_style_static::BOLD_ITALIC
144    }
145}
146
147mod font_style_static {
148    use super::{FontStyle, Slant, Weight, Width};
149
150    lazy_static! {
151        pub static ref NORMAL: FontStyle =
152            FontStyle::new(Weight::NORMAL, Width::NORMAL, Slant::Upright);
153        pub static ref BOLD: FontStyle =
154            FontStyle::new(Weight::BOLD, Width::NORMAL, Slant::Upright);
155        pub static ref ITALIC: FontStyle =
156            FontStyle::new(Weight::NORMAL, Width::NORMAL, Slant::Italic);
157        pub static ref BOLD_ITALIC: FontStyle =
158            FontStyle::new(Weight::BOLD, Width::NORMAL, Slant::Italic);
159    }
160}
161
162#[test]
163fn test_equality() {
164    let style: FontStyle = Default::default();
165    let style2: FontStyle = Default::default();
166    assert!(style == style2);
167}