1 | use crate::prelude::*; |
2 | use skia_bindings::{self as sb, SkFontStyle, SkFontStyle_Weight, SkFontStyle_Width}; |
3 | use 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)] |
11 | pub struct Weight(i32); |
12 | |
13 | native_transmutable!(i32, Weight, weight_layout); |
14 | |
15 | impl From<i32> for Weight { |
16 | fn from(weight: i32) -> Self { |
17 | Weight(weight) |
18 | } |
19 | } |
20 | |
21 | impl 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)] |
29 | impl 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)] |
49 | pub struct Width(i32); |
50 | |
51 | native_transmutable!(i32, Width, width_layout); |
52 | |
53 | impl From<i32> for Width { |
54 | fn from(width: i32) -> Self { |
55 | Width(width) |
56 | } |
57 | } |
58 | |
59 | impl 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)] |
67 | impl 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 | |
79 | pub use skia_bindings::SkFontStyle_Slant as Slant; |
80 | variant_name!(Slant::Upright); |
81 | |
82 | // TODO: implement Display |
83 | #[derive (Copy, Clone)] |
84 | #[repr (transparent)] |
85 | pub struct FontStyle(SkFontStyle); |
86 | |
87 | native_transmutable!(SkFontStyle, FontStyle, font_style_layout); |
88 | |
89 | impl PartialEq for FontStyle { |
90 | fn eq(&self, rhs: &Self) -> bool { |
91 | unsafe { sb::C_SkFontStyle_Equals(self.native(), rhs:rhs.native()) } |
92 | } |
93 | } |
94 | |
95 | impl Default for FontStyle { |
96 | fn default() -> Self { |
97 | FontStyle::construct(|fs: *mut SkFontStyle| unsafe { sb::C_SkFontStyle_Construct(uninitialized:fs) }) |
98 | } |
99 | } |
100 | |
101 | impl fmt::Debug for FontStyle { |
102 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
103 | f&mut DebugStruct<'_, '_>.debug_struct("FontStyle" ) |
104 | .field("weight" , &self.weight()) |
105 | .field("width" , &self.width()) |
106 | .field(name:"slant" , &self.slant()) |
107 | .finish() |
108 | } |
109 | } |
110 | |
111 | impl 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 | |
147 | mod 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 ] |
163 | fn test_equality() { |
164 | let style: FontStyle = Default::default(); |
165 | let style2: FontStyle = Default::default(); |
166 | assert!(style == style2); |
167 | } |
168 | |