1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
//! This file contains implementations for types that are
//! re-exported in skia-safe.
//!
//! We could provide trait implementations in skia-safe, but then users of the library would have to
//! import the implementation type _and_ the trait.
//!
//! See also: <https://github.com/rust-lang/rfcs/issues/1880>

use crate::{SkAlphaType, SkBlendMode, SkBlendModeCoeff, SkPathFillType, SkPathVerb, SkPath_Verb};
use std::ffi::CStr;

impl SkBlendMode {
    pub fn as_coeff(self) -> Option<(SkBlendModeCoeff, SkBlendModeCoeff)> {
        let mut src = SkBlendModeCoeff::Zero;
        let mut dst = SkBlendModeCoeff::Zero;
        if unsafe { crate::SkBlendMode_AsCoeff(self, &mut src, &mut dst) } {
            Some((src, dst))
        } else {
            None
        }
    }

    pub fn name(self) -> &'static str {
        unsafe {
            let name_ptr = crate::SkBlendMode_Name(self);
            CStr::from_ptr(name_ptr).to_str().unwrap()
        }
    }
}

//
// m84 introduced two different variants of the Path verb types.
// One with Done and one without.
//

impl SkPathVerb {
    /// The maximum number of points an iterator will return for the verb.
    pub const MAX_POINTS: usize = SkPath_Verb::MAX_POINTS;
    /// The number of points an iterator will return for the verb.
    pub fn points(self) -> usize {
        SkPath_Verb::from(self).points()
    }
}

impl SkPath_Verb {
    /// The maximum number of points an iterator will return for the verb.
    pub const MAX_POINTS: usize = 4;
    /// The number of points an iterator will return for the verb.
    pub fn points(self) -> usize {
        match self {
            SkPath_Verb::Move => 1,
            SkPath_Verb::Line => 2,
            SkPath_Verb::Quad => 3,
            SkPath_Verb::Conic => 3,
            SkPath_Verb::Cubic => 4,
            SkPath_Verb::Close => 0,
            SkPath_Verb::Done => 0,
        }
    }
}

impl From<SkPathVerb> for SkPath_Verb {
    fn from(v: SkPathVerb) -> Self {
        match v {
            SkPathVerb::Move => SkPath_Verb::Move,
            SkPathVerb::Line => SkPath_Verb::Line,
            SkPathVerb::Quad => SkPath_Verb::Quad,
            SkPathVerb::Conic => SkPath_Verb::Conic,
            SkPathVerb::Cubic => SkPath_Verb::Cubic,
            SkPathVerb::Close => SkPath_Verb::Close,
        }
    }
}

impl SkPathFillType {
    pub fn is_even_odd(self) -> bool {
        (self as i32 & 1) != 0
    }

    pub fn is_inverse(self) -> bool {
        (self as i32 & 2) != 0
    }

    #[must_use]
    pub fn to_non_inverse(self) -> Self {
        use SkPathFillType::*;
        match self {
            Winding => self,
            EvenOdd => self,
            InverseWinding => Winding,
            InverseEvenOdd => EvenOdd,
        }
    }
}

impl SkAlphaType {
    pub fn is_opaque(self) -> bool {
        self == SkAlphaType::Opaque
    }
}

#[cfg(feature = "gl")]
impl From<crate::GrGLenum> for crate::GrGLFormat {
    fn from(e: crate::GrGLenum) -> Self {
        unsafe { crate::C_GrGLFormatFromGLEnum(e) }
    }
}

#[cfg(feature = "gl")]
impl From<crate::GrGLFormat> for crate::GrGLenum {
    fn from(format: crate::GrGLFormat) -> Self {
        unsafe { crate::C_GrGLFormatToEnum(format) }
    }
}

#[cfg(feature = "d3d")]
mod d3d {
    use std::marker::PhantomData;

    impl<T> Default for crate::gr_cp<T> {
        fn default() -> Self {
            Self {
                fObject: std::ptr::null_mut(),
                _phantom_0: PhantomData,
            }
        }
    }

    impl Default for crate::GrD3DTextureResourceInfo {
        fn default() -> Self {
            let mut instance = std::mem::MaybeUninit::uninit();
            unsafe {
                crate::C_GrD3DTextureResourceInfo_Construct(instance.as_mut_ptr());
                instance.assume_init()
            }
        }
    }
}