| 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.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 | |