1 | use std::fmt; |
2 | |
3 | use skia_bindings::{self as sb, SkPixelGeometry, SkSurfaceProps}; |
4 | |
5 | use crate::prelude::*; |
6 | |
7 | // TODO: use the enum rewriter and strip underscores? |
8 | #[derive (Copy, Clone, PartialEq, Eq, Debug, Default)] |
9 | #[repr (i32)] |
10 | pub enum PixelGeometry { |
11 | #[default] |
12 | Unknown = SkPixelGeometry::kUnknown_SkPixelGeometry as _, |
13 | RGBH = SkPixelGeometry::kRGB_H_SkPixelGeometry as _, |
14 | BGRH = SkPixelGeometry::kBGR_H_SkPixelGeometry as _, |
15 | RGBV = SkPixelGeometry::kRGB_V_SkPixelGeometry as _, |
16 | BGRV = SkPixelGeometry::kBGR_V_SkPixelGeometry as _, |
17 | } |
18 | |
19 | native_transmutable!(SkPixelGeometry, PixelGeometry, pixel_geometry_layout); |
20 | |
21 | impl PixelGeometry { |
22 | pub fn is_rgb(self) -> bool { |
23 | self == PixelGeometry::RGBH || self == PixelGeometry::RGBV |
24 | } |
25 | |
26 | pub fn is_bgr(self) -> bool { |
27 | self == PixelGeometry::BGRH || self == PixelGeometry::BGRV |
28 | } |
29 | |
30 | pub fn is_h(self) -> bool { |
31 | self == PixelGeometry::RGBH || self == PixelGeometry::BGRH |
32 | } |
33 | |
34 | pub fn is_v(self) -> bool { |
35 | self == PixelGeometry::RGBV || self == PixelGeometry::BGRV |
36 | } |
37 | } |
38 | |
39 | bitflags! { |
40 | #[derive (Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] |
41 | pub struct SurfacePropsFlags: u32 { |
42 | #[allow(clippy::unnecessary_cast)] |
43 | const USE_DEVICE_INDEPENDENT_FONTS = |
44 | sb::SkSurfaceProps_Flags_kUseDeviceIndependentFonts_Flag as u32; |
45 | #[allow(clippy::unnecessary_cast)] |
46 | const DYNAMIC_MSAA = |
47 | sb::SkSurfaceProps_Flags_kDynamicMSAA_Flag as u32; |
48 | #[allow(clippy::unnecessary_cast)] |
49 | const ALWAYS_DITHER = |
50 | sb::SkSurfaceProps_Flags_kAlwaysDither_Flag as u32; |
51 | } |
52 | } |
53 | |
54 | impl Default for SurfacePropsFlags { |
55 | fn default() -> Self { |
56 | SurfacePropsFlags::empty() |
57 | } |
58 | } |
59 | |
60 | #[derive (Copy, Clone)] |
61 | #[repr (transparent)] |
62 | pub struct SurfaceProps(SkSurfaceProps); |
63 | |
64 | native_transmutable!(SkSurfaceProps, SurfaceProps, surface_props_layout); |
65 | |
66 | impl PartialEq for SurfaceProps { |
67 | fn eq(&self, other: &Self) -> bool { |
68 | unsafe { sb::C_SkSurfaceProps_Equals(self.native(), rhs:other.native()) } |
69 | } |
70 | } |
71 | |
72 | impl Eq for SurfaceProps {} |
73 | |
74 | impl Default for SurfaceProps { |
75 | fn default() -> Self { |
76 | SurfaceProps::new(flags:Default::default(), pixel_geometry:Default::default()) |
77 | } |
78 | } |
79 | |
80 | impl fmt::Debug for SurfaceProps { |
81 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
82 | f&mut DebugStruct<'_, '_>.debug_struct("SurfaceProps" ) |
83 | .field("flags" , &self.flags()) |
84 | .field(name:"pixel_geometry" , &self.pixel_geometry()) |
85 | .finish() |
86 | } |
87 | } |
88 | |
89 | impl SurfaceProps { |
90 | // TODO: do we need to wrap the constructor(s) with InitType? |
91 | |
92 | pub fn new(flags: SurfacePropsFlags, pixel_geometry: PixelGeometry) -> SurfaceProps { |
93 | Self::from_native_c(unsafe { |
94 | SkSurfaceProps::new1(flags.bits(), pixel_geometry.into_native()) |
95 | }) |
96 | } |
97 | |
98 | pub fn flags(self) -> SurfacePropsFlags { |
99 | SurfacePropsFlags::from_bits_truncate(self.native().fFlags) |
100 | } |
101 | |
102 | #[must_use ] |
103 | pub fn clone_with_pixel_geometry(&self, new_pixel_geometry: PixelGeometry) -> Self { |
104 | Self::new(self.flags(), new_pixel_geometry) |
105 | } |
106 | |
107 | pub fn pixel_geometry(self) -> PixelGeometry { |
108 | PixelGeometry::from_native_c(self.native().fPixelGeometry) |
109 | } |
110 | |
111 | pub fn is_use_device_independent_fonts(self) -> bool { |
112 | self.flags() |
113 | .contains(SurfacePropsFlags::USE_DEVICE_INDEPENDENT_FONTS) |
114 | } |
115 | |
116 | pub fn is_always_dither(self) -> bool { |
117 | self.flags().contains(SurfacePropsFlags::ALWAYS_DITHER) |
118 | } |
119 | } |
120 | |
121 | #[test ] |
122 | fn create() { |
123 | let props: SurfaceProps = SurfaceProps::new( |
124 | flags:SurfacePropsFlags::USE_DEVICE_INDEPENDENT_FONTS, |
125 | PixelGeometry::RGBH, |
126 | ); |
127 | assert_eq!( |
128 | SurfacePropsFlags::USE_DEVICE_INDEPENDENT_FONTS, |
129 | props.flags() |
130 | ); |
131 | assert_eq!(PixelGeometry::RGBH, props.pixel_geometry()); |
132 | assert!(props.is_use_device_independent_fonts()); |
133 | } |
134 | |