1use std::fmt;
2
3use skia_bindings::{self as sb, SkPixelGeometry, SkSurfaceProps};
4
5use crate::prelude::*;
6
7// TODO: use the enum rewriter and strip underscores?
8#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
9#[repr(i32)]
10pub 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
19native_transmutable!(SkPixelGeometry, PixelGeometry, pixel_geometry_layout);
20
21impl 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
39bitflags! {
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
54impl Default for SurfacePropsFlags {
55 fn default() -> Self {
56 SurfacePropsFlags::empty()
57 }
58}
59
60#[derive(Copy, Clone)]
61#[repr(transparent)]
62pub struct SurfaceProps(SkSurfaceProps);
63
64native_transmutable!(SkSurfaceProps, SurfaceProps, surface_props_layout);
65
66impl PartialEq for SurfaceProps {
67 fn eq(&self, other: &Self) -> bool {
68 unsafe { sb::C_SkSurfaceProps_Equals(self.native(), rhs:other.native()) }
69 }
70}
71
72impl Eq for SurfaceProps {}
73
74impl Default for SurfaceProps {
75 fn default() -> Self {
76 SurfaceProps::new(flags:Default::default(), pixel_geometry:Default::default())
77 }
78}
79
80impl 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
89impl 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]
122fn 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