1use crate::{prelude::*, scalar};
2use skia_bindings::{self as sb, SkISize, SkSize};
3use std::ops::{Div, DivAssign, Mul, MulAssign};
4
5#[repr(C)]
6#[derive(Copy, Clone, PartialEq, Eq, Default, Debug)]
7pub struct ISize {
8 pub width: i32,
9 pub height: i32,
10}
11
12native_transmutable!(SkISize, ISize, isize_layout);
13
14impl ISize {
15 pub const fn new(w: i32, h: i32) -> ISize {
16 ISize {
17 width: w,
18 height: h,
19 }
20 }
21
22 pub const fn new_empty() -> ISize {
23 Self::new(0, 0)
24 }
25
26 pub fn set(&mut self, w: i32, h: i32) {
27 *self = Self::new(w, h);
28 }
29
30 pub fn is_zero(self) -> bool {
31 self.width == 0 && self.height == 0
32 }
33
34 pub fn is_empty(self) -> bool {
35 self.width <= 0 || self.height <= 0
36 }
37
38 pub fn set_empty(&mut self) {
39 *self = Self::new_empty();
40 }
41
42 pub const fn area(self) -> i64 {
43 self.width as i64 * self.height as i64
44 }
45
46 // TODO: should the functions with() and height() be supported?
47
48 pub fn equals(self, w: i32, h: i32) -> bool {
49 self == Self::new(w, h)
50 }
51}
52
53#[repr(C)]
54#[derive(Copy, Clone, PartialEq, Default, Debug)]
55pub struct Size {
56 pub width: scalar,
57 pub height: scalar,
58}
59
60native_transmutable!(SkSize, Size, size_layout);
61
62impl Size {
63 pub const fn new(w: scalar, h: scalar) -> Size {
64 Size {
65 width: w,
66 height: h,
67 }
68 }
69
70 pub const fn from_isize(src: ISize) -> Size {
71 Self::new(src.width as _, src.height as _)
72 }
73
74 pub const fn new_empty() -> Self {
75 Self::new(0.0, 0.0)
76 }
77
78 pub fn set(&mut self, w: scalar, h: scalar) {
79 *self = Self::new(w, h);
80 }
81
82 pub fn is_zero(self) -> bool {
83 self.width == 0.0 && self.height == 0.0
84 }
85
86 pub fn is_empty(self) -> bool {
87 self.width <= 0.0 || self.height <= 0.0
88 }
89
90 pub fn set_empty(&mut self) {
91 *self = Self::new_empty()
92 }
93
94 // TODO: should width() and height() be supported?
95
96 pub fn equals(self, w: scalar, h: scalar) -> bool {
97 self == Self::new(w, h)
98 }
99
100 pub fn to_round(self) -> ISize {
101 ISize::from_native_c(unsafe { sb::C_SkSize_toRound(self.native()) })
102 }
103
104 pub fn to_ceil(self) -> ISize {
105 ISize::from_native_c(unsafe { sb::C_SkSize_toCeil(self.native()) })
106 }
107
108 pub fn to_floor(self) -> ISize {
109 ISize::from_native_c(unsafe { sb::C_SkSize_toFloor(self.native()) })
110 }
111}
112
113//
114// From
115//
116
117impl From<(i32, i32)> for ISize {
118 fn from(source: (i32, i32)) -> Self {
119 Self::new(w:source.0, h:source.1)
120 }
121}
122
123impl From<(scalar, scalar)> for Size {
124 fn from(source: (scalar, scalar)) -> Self {
125 Self::new(w:source.0, h:source.1)
126 }
127}
128
129impl From<ISize> for Size {
130 fn from(size: ISize) -> Self {
131 Self::new(w:size.width as _, h:size.height as _)
132 }
133}
134
135// TODO: this is experimental.
136impl From<(i32, i32)> for Size {
137 fn from(source: (i32, i32)) -> Self {
138 (source.0 as scalar, source.1 as scalar).into()
139 }
140}
141
142impl Div<scalar> for Size {
143 type Output = Self;
144 fn div(self, rhs: scalar) -> Self {
145 Self::new(self.width / rhs, self.height / rhs)
146 }
147}
148
149impl DivAssign<scalar> for Size {
150 fn div_assign(&mut self, rhs: scalar) {
151 *self = *self / rhs
152 }
153}
154
155impl Mul<scalar> for Size {
156 type Output = Self;
157 fn mul(self, rhs: scalar) -> Self {
158 Self::new(self.width * rhs, self.height * rhs)
159 }
160}
161
162impl MulAssign<scalar> for Size {
163 fn mul_assign(&mut self, rhs: scalar) {
164 *self = *self * rhs
165 }
166}
167