1use crate::{prelude::*, YUVColorSpace};
2use skia_bindings::{self as sb, SkColorMatrix};
3use std::fmt;
4
5pub type ColorMatrix = Handle<SkColorMatrix>;
6unsafe_send_sync!(ColorMatrix);
7
8impl NativeDrop for SkColorMatrix {
9 fn drop(&mut self) {}
10}
11
12impl PartialEq for ColorMatrix {
13 fn eq(&self, other: &Self) -> bool {
14 let mut array_self: [f32; 20] = [0.0f32; 20];
15 let mut array_other: [f32; 20] = [0.0f32; 20];
16 self.get_row_major(&mut array_self);
17 other.get_row_major(&mut array_other);
18 array_self == array_other
19 }
20}
21
22impl Default for ColorMatrix {
23 fn default() -> Self {
24 ColorMatrix::construct(|cm: *mut SkColorMatrix| unsafe { sb::C_SkColorMatrix_Construct(uninitialized:cm) })
25 }
26}
27
28impl fmt::Debug for ColorMatrix {
29 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
30 f&mut DebugStruct<'_, '_>.debug_struct("ColorMatrix")
31 .field(name:"mat", &self.native().fMat)
32 .finish()
33 }
34}
35
36impl ColorMatrix {
37 #[allow(clippy::too_many_arguments)]
38 pub fn new(
39 m00: f32,
40 m01: f32,
41 m02: f32,
42 m03: f32,
43 m04: f32,
44 m10: f32,
45 m11: f32,
46 m12: f32,
47 m13: f32,
48 m14: f32,
49 m20: f32,
50 m21: f32,
51 m22: f32,
52 m23: f32,
53 m24: f32,
54 m30: f32,
55 m31: f32,
56 m32: f32,
57 m33: f32,
58 m34: f32,
59 ) -> Self {
60 ColorMatrix::construct(|cm| unsafe {
61 sb::C_SkColorMatrix_Construct2(
62 cm, m00, m01, m02, m03, m04, m10, m11, m12, m13, m14, m20, m21, m22, m23, m24, m30,
63 m31, m32, m33, m34,
64 )
65 })
66 }
67
68 pub fn rgb_to_yuv(rgb: YUVColorSpace) -> Self {
69 Self::from_native_c(unsafe { sb::SkColorMatrix_RGBtoYUV(rgb) })
70 }
71
72 pub fn yuv_to_rgb(yuv: YUVColorSpace) -> Self {
73 Self::from_native_c(unsafe { sb::SkColorMatrix_YUVtoRGB(yuv) })
74 }
75
76 pub fn set_identity(&mut self) {
77 unsafe { self.native_mut().setIdentity() }
78 }
79
80 pub fn set_scale(
81 &mut self,
82 r_scale: f32,
83 g_scale: f32,
84 b_scale: f32,
85 a_scale: impl Into<Option<f32>>,
86 ) {
87 unsafe {
88 self.native_mut()
89 .setScale(r_scale, g_scale, b_scale, a_scale.into().unwrap_or(1.0))
90 }
91 }
92
93 pub fn post_translate(&mut self, dr: f32, dg: f32, db: f32, da: f32) {
94 unsafe { self.native_mut().postTranslate(dr, dg, db, da) }
95 }
96
97 pub fn set_concat(&mut self, a: &ColorMatrix, b: &ColorMatrix) {
98 unsafe { self.native_mut().setConcat(a.native(), b.native()) }
99 }
100
101 pub fn pre_concat(&mut self, mat: &ColorMatrix) {
102 let self_ptr = self.native() as *const _;
103 unsafe { self.native_mut().setConcat(self_ptr, mat.native()) }
104 }
105
106 pub fn post_concat(&mut self, mat: &ColorMatrix) {
107 let self_ptr = self.native() as *const _;
108 unsafe { self.native_mut().setConcat(mat.native(), self_ptr) }
109 }
110
111 pub fn set_saturation(&mut self, sat: f32) {
112 unsafe { self.native_mut().setSaturation(sat) }
113 }
114
115 pub fn set_row_major(&mut self, src: &[f32; 20]) {
116 unsafe {
117 sb::C_SkColorMatrix_setRowMajor(self.native_mut(), src.as_ptr());
118 }
119 }
120
121 pub fn get_row_major(&self, dst: &mut [f32; 20]) {
122 unsafe {
123 sb::C_SkColorMatrix_getRowMajor(self.native(), dst.as_mut_ptr());
124 }
125 }
126}
127