1use crate::derives::*;
8use crate::values::generics::rect::Rect;
9use crate::values::generics::size::Size2D;
10use crate::Zero;
11use std::fmt::{self, Write};
12use style_traits::{CssWriter, ToCss};
13
14#[derive(
16 Animate,
17 Clone,
18 ComputeSquaredDistance,
19 Copy,
20 Debug,
21 MallocSizeOf,
22 Parse,
23 PartialEq,
24 SpecifiedValueInfo,
25 ToAnimatedValue,
26 ToAnimatedZero,
27 ToComputedValue,
28 ToCss,
29 ToResolvedValue,
30 ToShmem,
31)]
32#[repr(C, u8)]
33pub enum GenericBorderImageSideWidth<LP, N> {
34 Number(N),
39 LengthPercentage(LP),
41 Auto,
43}
44
45pub use self::GenericBorderImageSideWidth as BorderImageSideWidth;
46
47#[derive(
49 Animate,
50 Clone,
51 ComputeSquaredDistance,
52 Copy,
53 Debug,
54 MallocSizeOf,
55 PartialEq,
56 SpecifiedValueInfo,
57 ToAnimatedValue,
58 ToAnimatedZero,
59 ToComputedValue,
60 ToCss,
61 ToResolvedValue,
62 ToShmem,
63 ToTyped,
64)]
65#[repr(C)]
66#[typed(todo_derive_fields)]
67pub struct GenericBorderImageSlice<NumberOrPercentage> {
68 #[css(field_bound)]
70 pub offsets: Rect<NumberOrPercentage>,
71 #[animation(constant)]
73 #[css(represents_keyword)]
74 pub fill: bool,
75}
76
77pub use self::GenericBorderImageSlice as BorderImageSlice;
78
79#[derive(
81 Animate,
82 Clone,
83 ComputeSquaredDistance,
84 Copy,
85 Debug,
86 Deserialize,
87 MallocSizeOf,
88 PartialEq,
89 SpecifiedValueInfo,
90 Serialize,
91 ToAnimatedValue,
92 ToAnimatedZero,
93 ToComputedValue,
94 ToCss,
95 ToResolvedValue,
96 ToShmem,
97 ToTyped,
98)]
99#[repr(C)]
100#[typed(todo_derive_fields)]
101pub struct GenericBorderCornerRadius<L>(
102 #[css(field_bound)]
103 #[shmem(field_bound)]
104 pub Size2D<L>,
105);
106
107pub use self::GenericBorderCornerRadius as BorderCornerRadius;
108
109impl<L> BorderCornerRadius<L> {
110 pub fn new(w: L, h: L) -> Self {
112 BorderCornerRadius(Size2D::new(w, h))
113 }
114}
115
116impl<L: Zero> Zero for BorderCornerRadius<L> {
117 fn zero() -> Self {
118 BorderCornerRadius(Size2D::zero())
119 }
120
121 fn is_zero(&self) -> bool {
122 self.0.is_zero()
123 }
124}
125
126#[derive(
128 Animate,
129 Clone,
130 ComputeSquaredDistance,
131 Copy,
132 Debug,
133 MallocSizeOf,
134 PartialEq,
135 SpecifiedValueInfo,
136 ToAnimatedValue,
137 ToAnimatedZero,
138 ToComputedValue,
139 ToCss,
140 ToResolvedValue,
141 ToShmem,
142 ToTyped,
143)]
144#[repr(transparent)]
145#[typed(todo_derive_fields)]
146pub struct GenericBorderSpacing<L>(
147 #[css(field_bound)]
148 #[shmem(field_bound)]
149 pub Size2D<L>,
150);
151
152pub use self::GenericBorderSpacing as BorderSpacing;
153impl<L> BorderSpacing<L> {
154 pub fn new(w: L, h: L) -> Self {
156 BorderSpacing(Size2D::new(w, h))
157 }
158}
159
160#[derive(
164 Animate,
165 Clone,
166 ComputeSquaredDistance,
167 Copy,
168 Debug,
169 Deserialize,
170 MallocSizeOf,
171 PartialEq,
172 SpecifiedValueInfo,
173 Serialize,
174 ToAnimatedValue,
175 ToComputedValue,
176 ToResolvedValue,
177 ToShmem,
178)]
179#[repr(C)]
180pub struct GenericBorderRadius<LengthPercentage> {
181 #[shmem(field_bound)]
183 pub top_left: GenericBorderCornerRadius<LengthPercentage>,
184 pub top_right: GenericBorderCornerRadius<LengthPercentage>,
186 pub bottom_right: GenericBorderCornerRadius<LengthPercentage>,
188 pub bottom_left: GenericBorderCornerRadius<LengthPercentage>,
190}
191
192pub use self::GenericBorderRadius as BorderRadius;
193
194impl<L> BorderRadius<L> {
195 #[inline]
197 pub fn new(
198 tl: BorderCornerRadius<L>,
199 tr: BorderCornerRadius<L>,
200 br: BorderCornerRadius<L>,
201 bl: BorderCornerRadius<L>,
202 ) -> Self {
203 BorderRadius {
204 top_left: tl,
205 top_right: tr,
206 bottom_right: br,
207 bottom_left: bl,
208 }
209 }
210
211 pub fn serialize_rects<W>(
214 widths: Rect<&L>,
215 heights: Rect<&L>,
216 dest: &mut CssWriter<W>,
217 ) -> fmt::Result
218 where
219 L: PartialEq + ToCss,
220 W: Write,
221 {
222 widths.to_css(dest)?;
223 if widths != heights {
224 dest.write_str(" / ")?;
225 heights.to_css(dest)?;
226 }
227 Ok(())
228 }
229}
230
231impl<L: Zero> Zero for BorderRadius<L> {
232 fn zero() -> Self {
233 Self::new(
234 BorderCornerRadius::<L>::zero(),
235 BorderCornerRadius::<L>::zero(),
236 BorderCornerRadius::<L>::zero(),
237 BorderCornerRadius::<L>::zero(),
238 )
239 }
240
241 fn is_zero(&self) -> bool {
242 self.top_left.is_zero()
243 && self.top_right.is_zero()
244 && self.bottom_right.is_zero()
245 && self.bottom_left.is_zero()
246 }
247}
248
249impl<L> ToCss for BorderRadius<L>
250where
251 L: PartialEq + ToCss,
252{
253 fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
254 where
255 W: Write,
256 {
257 let BorderRadius {
258 top_left: BorderCornerRadius(ref tl),
259 top_right: BorderCornerRadius(ref tr),
260 bottom_right: BorderCornerRadius(ref br),
261 bottom_left: BorderCornerRadius(ref bl),
262 } = *self;
263
264 let widths = Rect::new(&tl.width, &tr.width, &br.width, &bl.width);
265 let heights = Rect::new(&tl.height, &tr.height, &br.height, &bl.height);
266
267 Self::serialize_rects(widths, heights, dest)
268 }
269}