skia_safe/core/
surface_props.rs1use std::fmt;
2
3use skia_bindings::{self as sb, SkPixelGeometry, SkSurfaceProps};
4
5use crate::{prelude::*, scalar};
6
7#[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 DEFAULT = sb::SkSurfaceProps_Flags_kDefault_Flag as u32;
44 #[allow(clippy::unnecessary_cast)]
45 const USE_DEVICE_INDEPENDENT_FONTS =
46 sb::SkSurfaceProps_Flags_kUseDeviceIndependentFonts_Flag as u32;
47 #[allow(clippy::unnecessary_cast)]
48 const DYNAMIC_MSAA =
49 sb::SkSurfaceProps_Flags_kDynamicMSAA_Flag as u32;
50 #[allow(clippy::unnecessary_cast)]
51 const ALWAYS_DITHER =
52 sb::SkSurfaceProps_Flags_kAlwaysDither_Flag as u32;
53 }
54}
55
56impl Default for SurfacePropsFlags {
57 fn default() -> Self {
58 SurfacePropsFlags::empty()
59 }
60}
61
62#[derive(Copy, Clone)]
63#[repr(transparent)]
64pub struct SurfaceProps(SkSurfaceProps);
65
66native_transmutable!(SkSurfaceProps, SurfaceProps, surface_props_layout);
67
68impl PartialEq for SurfaceProps {
69 fn eq(&self, other: &Self) -> bool {
70 unsafe { sb::C_SkSurfaceProps_Equals(self.native(), other.native()) }
71 }
72}
73
74impl Eq for SurfaceProps {}
75
76impl Default for SurfaceProps {
77 fn default() -> Self {
78 SurfaceProps::new(Default::default(), Default::default())
79 }
80}
81
82impl fmt::Debug for SurfaceProps {
83 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
84 f.debug_struct("SurfaceProps")
85 .field("flags", &self.flags())
86 .field("pixel_geometry", &self.pixel_geometry())
87 .field("text_contrast", &self.text_contrast())
88 .field("text_gamma", &self.text_gamma())
89 .finish()
90 }
91}
92
93impl SurfaceProps {
94 pub fn new(flags: SurfacePropsFlags, pixel_geometry: PixelGeometry) -> SurfaceProps {
95 Self::from_native_c(unsafe {
96 SkSurfaceProps::new1(flags.bits(), pixel_geometry.into_native())
97 })
98 }
99
100 pub fn new_with_text_properties(
101 flags: SurfacePropsFlags,
102 pixel_geometry: PixelGeometry,
103 text_contrast: scalar,
104 text_gamma: scalar,
105 ) -> SurfaceProps {
106 Self::from_native_c(unsafe {
107 SkSurfaceProps::new2(
108 flags.bits(),
109 pixel_geometry.into_native(),
110 text_contrast,
111 text_gamma,
112 )
113 })
114 }
115
116 pub fn flags(self) -> SurfacePropsFlags {
117 SurfacePropsFlags::from_bits_truncate(self.native().fFlags)
118 }
119
120 #[must_use]
121 pub fn clone_with_pixel_geometry(&self, new_pixel_geometry: PixelGeometry) -> Self {
122 Self::new_with_text_properties(
123 self.flags(),
124 new_pixel_geometry,
125 self.text_contrast(),
126 self.text_gamma(),
127 )
128 }
129
130 pub const MAX_CONTRAST_INCLUSIVE: scalar = 1.;
131 pub const MIN_CONTRAST_INCLUSIVE: scalar = 0.;
132 pub const MAX_GAMMA_EXCLUSIVE: scalar = 4.;
133 pub const MIN_GAMMA_INCLUSIVE: scalar = 0.;
134
135 pub fn pixel_geometry(self) -> PixelGeometry {
136 PixelGeometry::from_native_c(self.native().fPixelGeometry)
137 }
138
139 pub fn text_contrast(self) -> scalar {
140 self.native().fTextContrast
141 }
142
143 pub fn text_gamma(self) -> scalar {
144 self.native().fTextGamma
145 }
146
147 pub fn is_use_device_independent_fonts(self) -> bool {
148 self.flags()
149 .contains(SurfacePropsFlags::USE_DEVICE_INDEPENDENT_FONTS)
150 }
151
152 pub fn is_always_dither(self) -> bool {
153 self.flags().contains(SurfacePropsFlags::ALWAYS_DITHER)
154 }
155}
156
157#[test]
158fn create() {
159 let props = SurfaceProps::new(
160 SurfacePropsFlags::USE_DEVICE_INDEPENDENT_FONTS,
161 PixelGeometry::RGBH,
162 );
163 assert_eq!(
164 SurfacePropsFlags::USE_DEVICE_INDEPENDENT_FONTS,
165 props.flags()
166 );
167 assert_eq!(PixelGeometry::RGBH, props.pixel_geometry());
168 assert!(props.is_use_device_independent_fonts());
169}