1use alloc::{boxed::Box, collections::btree_map::BTreeMap, string::String, vec::Vec};
4use core::{
5 cmp::Ordering,
6 ffi::c_void,
7 fmt,
8 hash::{Hash, Hasher},
9 sync::atomic::{AtomicUsize, Ordering as AtomicOrdering},
10};
11
12use crate::{css::CssPropertyValue, AzString, OptionI16, OptionU16, OptionU32, U8Vec};
13
14pub const EM_HEIGHT: f32 = 16.0;
16pub const PT_TO_PX: f32 = 96.0 / 72.0;
17
18const COMBINED_CSS_PROPERTIES_KEY_MAP: [(CombinedCssPropertyType, &'static str); 12] = [
19 (CombinedCssPropertyType::BorderRadius, "border-radius"),
20 (CombinedCssPropertyType::Overflow, "overflow"),
21 (CombinedCssPropertyType::Padding, "padding"),
22 (CombinedCssPropertyType::Margin, "margin"),
23 (CombinedCssPropertyType::Border, "border"),
24 (CombinedCssPropertyType::BorderLeft, "border-left"),
25 (CombinedCssPropertyType::BorderRight, "border-right"),
26 (CombinedCssPropertyType::BorderTop, "border-top"),
27 (CombinedCssPropertyType::BorderBottom, "border-bottom"),
28 (CombinedCssPropertyType::BoxShadow, "box-shadow"),
29 (CombinedCssPropertyType::BackgroundColor, "background-color"),
30 (CombinedCssPropertyType::BackgroundImage, "background-image"),
31];
32
33const CSS_PROPERTY_KEY_MAP: [(CssPropertyType, &'static str); 74] = [
35 (CssPropertyType::Display, "display"),
36 (CssPropertyType::Float, "float"),
37 (CssPropertyType::BoxSizing, "box-sizing"),
38 (CssPropertyType::TextColor, "color"),
39 (CssPropertyType::FontSize, "font-size"),
40 (CssPropertyType::FontFamily, "font-family"),
41 (CssPropertyType::TextAlign, "text-align"),
42 (CssPropertyType::LetterSpacing, "letter-spacing"),
43 (CssPropertyType::LineHeight, "line-height"),
44 (CssPropertyType::WordSpacing, "word-spacing"),
45 (CssPropertyType::TabWidth, "tab-width"),
46 (CssPropertyType::Cursor, "cursor"),
47 (CssPropertyType::Width, "width"),
48 (CssPropertyType::Height, "height"),
49 (CssPropertyType::MinWidth, "min-width"),
50 (CssPropertyType::MinHeight, "min-height"),
51 (CssPropertyType::MaxWidth, "max-width"),
52 (CssPropertyType::MaxHeight, "max-height"),
53 (CssPropertyType::Position, "position"),
54 (CssPropertyType::Top, "top"),
55 (CssPropertyType::Right, "right"),
56 (CssPropertyType::Left, "left"),
57 (CssPropertyType::Bottom, "bottom"),
58 (CssPropertyType::FlexWrap, "flex-wrap"),
59 (CssPropertyType::FlexDirection, "flex-direction"),
60 (CssPropertyType::FlexGrow, "flex-grow"),
61 (CssPropertyType::FlexShrink, "flex-shrink"),
62 (CssPropertyType::JustifyContent, "justify-content"),
63 (CssPropertyType::AlignItems, "align-items"),
64 (CssPropertyType::AlignContent, "align-content"),
65 (CssPropertyType::OverflowX, "overflow-x"),
66 (CssPropertyType::OverflowY, "overflow-y"),
67 (CssPropertyType::PaddingTop, "padding-top"),
68 (CssPropertyType::PaddingLeft, "padding-left"),
69 (CssPropertyType::PaddingRight, "padding-right"),
70 (CssPropertyType::PaddingBottom, "padding-bottom"),
71 (CssPropertyType::MarginTop, "margin-top"),
72 (CssPropertyType::MarginLeft, "margin-left"),
73 (CssPropertyType::MarginRight, "margin-right"),
74 (CssPropertyType::MarginBottom, "margin-bottom"),
75 (CssPropertyType::BackgroundContent, "background"),
76 (CssPropertyType::BackgroundPosition, "background-position"),
77 (CssPropertyType::BackgroundSize, "background-size"),
78 (CssPropertyType::BackgroundRepeat, "background-repeat"),
79 (
80 CssPropertyType::BorderTopLeftRadius,
81 "border-top-left-radius",
82 ),
83 (
84 CssPropertyType::BorderTopRightRadius,
85 "border-top-right-radius",
86 ),
87 (
88 CssPropertyType::BorderBottomLeftRadius,
89 "border-bottom-left-radius",
90 ),
91 (
92 CssPropertyType::BorderBottomRightRadius,
93 "border-bottom-right-radius",
94 ),
95 (CssPropertyType::BorderTopColor, "border-top-color"),
96 (CssPropertyType::BorderRightColor, "border-right-color"),
97 (CssPropertyType::BorderLeftColor, "border-left-color"),
98 (CssPropertyType::BorderBottomColor, "border-bottom-color"),
99 (CssPropertyType::BorderTopStyle, "border-top-style"),
100 (CssPropertyType::BorderRightStyle, "border-right-style"),
101 (CssPropertyType::BorderLeftStyle, "border-left-style"),
102 (CssPropertyType::BorderBottomStyle, "border-bottom-style"),
103 (CssPropertyType::BorderTopWidth, "border-top-width"),
104 (CssPropertyType::BorderRightWidth, "border-right-width"),
105 (CssPropertyType::BorderLeftWidth, "border-left-width"),
106 (CssPropertyType::BorderBottomWidth, "border-bottom-width"),
107 (CssPropertyType::BoxShadowTop, "-azul-box-shadow-top"),
108 (CssPropertyType::BoxShadowRight, "-azul-box-shadow-right"),
109 (CssPropertyType::BoxShadowLeft, "-azul-box-shadow-left"),
110 (CssPropertyType::BoxShadowBottom, "-azul-box-shadow-bottom"),
111 (CssPropertyType::ScrollbarStyle, "-azul-scrollbar-style"),
112 (CssPropertyType::Opacity, "opacity"),
113 (CssPropertyType::Transform, "transform"),
114 (CssPropertyType::PerspectiveOrigin, "perspective-origin"),
115 (CssPropertyType::TransformOrigin, "transform-origin"),
116 (CssPropertyType::BackfaceVisibility, "backface-visibility"),
117 (CssPropertyType::MixBlendMode, "mix-blend-mode"),
118 (CssPropertyType::Filter, "filter"),
119 (CssPropertyType::BackdropFilter, "backdrop-filter"),
120 (CssPropertyType::TextShadow, "text-shadow"),
121];
122
123#[derive(Copy, Clone, PartialEq, PartialOrd)]
128#[repr(C)]
129pub struct LayoutRect {
130 pub origin: LayoutPoint,
131 pub size: LayoutSize,
132}
133
134impl_option!(
135 LayoutRect,
136 OptionLayoutRect,
137 [Debug, Copy, Clone, PartialEq, PartialOrd]
138);
139
140impl_vec!(LayoutRect, LayoutRectVec, LayoutRectVecDestructor);
141impl_vec_clone!(LayoutRect, LayoutRectVec, LayoutRectVecDestructor);
142impl_vec_debug!(LayoutRect, LayoutRectVec);
143impl_vec_mut!(LayoutRect, LayoutRectVec);
144impl_vec_partialeq!(LayoutRect, LayoutRectVec);
145impl_vec_partialord!(LayoutRect, LayoutRectVec);
146
147impl fmt::Debug for LayoutRect {
148 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
149 write!(f, "{}", self)
150 }
151}
152
153impl fmt::Display for LayoutRect {
154 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
155 write!(f, "{} @ {}", self.size, self.origin)
156 }
157}
158
159impl LayoutRect {
160 #[inline(always)]
161 pub const fn new(origin: LayoutPoint, size: LayoutSize) -> Self {
162 Self { origin, size }
163 }
164 #[inline(always)]
165 pub const fn zero() -> Self {
166 Self::new(LayoutPoint::zero(), LayoutSize::zero())
167 }
168 #[inline(always)]
169 pub const fn max_x(&self) -> isize {
170 self.origin.x + self.size.width
171 }
172 #[inline(always)]
173 pub const fn min_x(&self) -> isize {
174 self.origin.x
175 }
176 #[inline(always)]
177 pub const fn max_y(&self) -> isize {
178 self.origin.y + self.size.height
179 }
180 #[inline(always)]
181 pub const fn min_y(&self) -> isize {
182 self.origin.y
183 }
184 #[inline(always)]
185 pub const fn width(&self) -> isize {
186 self.max_x() - self.min_x()
187 }
188 #[inline(always)]
189 pub const fn height(&self) -> isize {
190 self.max_y() - self.min_y()
191 }
192
193 pub const fn contains(&self, other: &LayoutPoint) -> bool {
194 self.min_x() <= other.x
195 && other.x < self.max_x()
196 && self.min_y() <= other.y
197 && other.y < self.max_y()
198 }
199
200 pub fn contains_f32(&self, other_x: f32, other_y: f32) -> bool {
201 self.min_x() as f32 <= other_x
202 && other_x < self.max_x() as f32
203 && self.min_y() as f32 <= other_y
204 && other_y < self.max_y() as f32
205 }
206
207 #[inline]
211 pub const fn hit_test(&self, other: &LayoutPoint) -> Option<LayoutPoint> {
212 let dx_left_edge = other.x - self.min_x();
213 let dx_right_edge = self.max_x() - other.x;
214 let dy_top_edge = other.y - self.min_y();
215 let dy_bottom_edge = self.max_y() - other.y;
216 if dx_left_edge > 0 && dx_right_edge > 0 && dy_top_edge > 0 && dy_bottom_edge > 0 {
217 Some(LayoutPoint::new(dx_left_edge, dy_top_edge))
218 } else {
219 None
220 }
221 }
222
223 #[inline]
225 pub fn union<I: Iterator<Item = Self>>(mut rects: I) -> Option<Self> {
226 let first = rects.next()?;
227
228 let mut max_width = first.size.width;
229 let mut max_height = first.size.height;
230 let mut min_x = first.origin.x;
231 let mut min_y = first.origin.y;
232
233 while let Some(Self {
234 origin: LayoutPoint { x, y },
235 size: LayoutSize { width, height },
236 }) = rects.next()
237 {
238 let cur_lower_right_x = x + width;
239 let cur_lower_right_y = y + height;
240 max_width = max_width.max(cur_lower_right_x - min_x);
241 max_height = max_height.max(cur_lower_right_y - min_y);
242 min_x = min_x.min(x);
243 min_y = min_y.min(y);
244 }
245
246 Some(Self {
247 origin: LayoutPoint { x: min_x, y: min_y },
248 size: LayoutSize {
249 width: max_width,
250 height: max_height,
251 },
252 })
253 }
254
255 #[inline]
257 pub fn get_scroll_rect<I: Iterator<Item = Self>>(&self, children: I) -> Option<Self> {
258 let children_union = Self::union(children)?;
259 Self::union([*self, children_union].iter().map(|r| *r))
260 }
261
262 #[inline(always)]
264 pub const fn contains_rect(&self, b: &LayoutRect) -> bool {
265 let a = self;
266
267 let a_x = a.origin.x;
268 let a_y = a.origin.y;
269 let a_width = a.size.width;
270 let a_height = a.size.height;
271
272 let b_x = b.origin.x;
273 let b_y = b.origin.y;
274 let b_width = b.size.width;
275 let b_height = b.size.height;
276
277 b_x >= a_x
278 && b_y >= a_y
279 && b_x + b_width <= a_x + a_width
280 && b_y + b_height <= a_y + a_height
281 }
282}
283
284#[derive(Copy, Default, Clone, PartialEq, PartialOrd, Ord, Eq, Hash)]
286#[repr(C)]
287pub struct LayoutSize {
288 pub width: isize,
289 pub height: isize,
290}
291
292impl_option!(
293 LayoutSize,
294 OptionLayoutSize,
295 [Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash]
296);
297
298impl fmt::Debug for LayoutSize {
299 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
300 write!(f, "{}", self)
301 }
302}
303
304impl fmt::Display for LayoutSize {
305 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
306 write!(f, "{}x{}", self.width, self.height)
307 }
308}
309
310impl LayoutSize {
311 #[inline(always)]
312 pub const fn new(width: isize, height: isize) -> Self {
313 Self { width, height }
314 }
315 #[inline(always)]
316 pub const fn zero() -> Self {
317 Self::new(0, 0)
318 }
319 #[inline]
320 pub fn round(width: f32, height: f32) -> Self {
321 Self {
322 width: libm::roundf(width) as isize,
323 height: libm::roundf(height) as isize,
324 }
325 }
326}
327
328#[derive(Copy, Default, Clone, PartialEq, PartialOrd, Ord, Eq, Hash)]
330#[repr(C)]
331pub struct LayoutPoint {
332 pub x: isize,
333 pub y: isize,
334}
335
336impl fmt::Debug for LayoutPoint {
337 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
338 write!(f, "{}", self)
339 }
340}
341
342impl fmt::Display for LayoutPoint {
343 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
344 write!(f, "({}, {})", self.x, self.y)
345 }
346}
347
348impl LayoutPoint {
349 #[inline(always)]
350 pub const fn new(x: isize, y: isize) -> Self {
351 Self { x, y }
352 }
353 #[inline(always)]
354 pub const fn zero() -> Self {
355 Self::new(0, 0)
356 }
357}
358
359impl_option!(
360 LayoutPoint,
361 OptionLayoutPoint,
362 [Debug, Copy, Clone, PartialEq, PartialOrd]
363);
364
365#[derive(Default, Debug, Copy, Clone, PartialEq, Ord, PartialOrd, Eq, Hash)]
367pub struct PixelSize {
368 pub width: PixelValue,
369 pub height: PixelValue,
370}
371
372impl PixelSize {
373 pub const fn new(width: PixelValue, height: PixelValue) -> Self {
374 Self { width, height }
375 }
376
377 pub const fn zero() -> Self {
378 Self::new(PixelValue::const_px(0), PixelValue::const_px(0))
379 }
380}
381
382#[derive(Debug, Copy, Clone, PartialEq, Ord, PartialOrd, Eq, Hash)]
384#[repr(C)]
385pub struct LayoutSideOffsets {
386 pub top: FloatValue,
387 pub right: FloatValue,
388 pub bottom: FloatValue,
389 pub left: FloatValue,
390}
391
392#[derive(Debug, Copy, Clone, PartialEq, Ord, PartialOrd, Eq, Hash)]
394#[repr(C)]
395pub struct ColorU {
396 pub r: u8,
397 pub g: u8,
398 pub b: u8,
399 pub a: u8,
400}
401
402impl Default for ColorU {
403 fn default() -> Self {
404 ColorU::BLACK
405 }
406}
407
408impl fmt::Display for ColorU {
409 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
410 write!(
411 f,
412 "rgba({}, {}, {}, {})",
413 self.r,
414 self.g,
415 self.b,
416 self.a as f32 / 255.0
417 )
418 }
419}
420
421impl ColorU {
422 pub const ALPHA_TRANSPARENT: u8 = 0;
423 pub const ALPHA_OPAQUE: u8 = 255;
424
425 pub const RED: ColorU = ColorU {
426 r: 255,
427 g: 0,
428 b: 0,
429 a: Self::ALPHA_OPAQUE,
430 };
431 pub const GREEN: ColorU = ColorU {
432 r: 0,
433 g: 255,
434 b: 0,
435 a: Self::ALPHA_OPAQUE,
436 };
437 pub const BLUE: ColorU = ColorU {
438 r: 0,
439 g: 0,
440 b: 255,
441 a: Self::ALPHA_OPAQUE,
442 };
443 pub const WHITE: ColorU = ColorU {
444 r: 255,
445 g: 255,
446 b: 255,
447 a: Self::ALPHA_OPAQUE,
448 };
449 pub const BLACK: ColorU = ColorU {
450 r: 0,
451 g: 0,
452 b: 0,
453 a: Self::ALPHA_OPAQUE,
454 };
455 pub const TRANSPARENT: ColorU = ColorU {
456 r: 0,
457 g: 0,
458 b: 0,
459 a: Self::ALPHA_TRANSPARENT,
460 };
461
462 pub const fn new_rgb(r: u8, g: u8, b: u8) -> Self {
463 Self { r, g, b, a: 255 }
464 }
465
466 pub fn interpolate(&self, other: &Self, t: f32) -> Self {
467 Self {
468 r: libm::roundf(self.r as f32 + (other.r as f32 - self.r as f32) * t) as u8,
469 g: libm::roundf(self.g as f32 + (other.g as f32 - self.g as f32) * t) as u8,
470 b: libm::roundf(self.b as f32 + (other.b as f32 - self.b as f32) * t) as u8,
471 a: libm::roundf(self.a as f32 + (other.a as f32 - self.a as f32) * t) as u8,
472 }
473 }
474
475 pub const fn has_alpha(&self) -> bool {
476 self.a != Self::ALPHA_OPAQUE
477 }
478
479 pub fn to_hash(&self) -> String {
480 format!("#{:02x}{:02x}{:02x}{:02x}", self.r, self.g, self.b, self.a)
481 }
482
483 pub fn write_hash(&self, f: &mut fmt::Formatter) -> fmt::Result {
484 write!(
485 f,
486 "#{:02x}{:02x}{:02x}{:02x}",
487 self.r, self.g, self.b, self.a
488 )
489 }
490}
491
492#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
494pub struct ColorF {
495 pub r: f32,
496 pub g: f32,
497 pub b: f32,
498 pub a: f32,
499}
500
501impl Default for ColorF {
502 fn default() -> Self {
503 ColorF::BLACK
504 }
505}
506
507impl fmt::Display for ColorF {
508 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
509 write!(
510 f,
511 "rgba({}, {}, {}, {})",
512 self.r * 255.0,
513 self.g * 255.0,
514 self.b * 255.0,
515 self.a
516 )
517 }
518}
519
520impl ColorF {
521 pub const ALPHA_TRANSPARENT: f32 = 0.0;
522 pub const ALPHA_OPAQUE: f32 = 1.0;
523
524 pub const WHITE: ColorF = ColorF {
525 r: 1.0,
526 g: 1.0,
527 b: 1.0,
528 a: Self::ALPHA_OPAQUE,
529 };
530 pub const BLACK: ColorF = ColorF {
531 r: 0.0,
532 g: 0.0,
533 b: 0.0,
534 a: Self::ALPHA_OPAQUE,
535 };
536 pub const TRANSPARENT: ColorF = ColorF {
537 r: 0.0,
538 g: 0.0,
539 b: 0.0,
540 a: Self::ALPHA_TRANSPARENT,
541 };
542}
543
544impl From<ColorU> for ColorF {
545 fn from(input: ColorU) -> ColorF {
546 ColorF {
547 r: (input.r as f32) / 255.0,
548 g: (input.g as f32) / 255.0,
549 b: (input.b as f32) / 255.0,
550 a: (input.a as f32) / 255.0,
551 }
552 }
553}
554
555impl From<ColorF> for ColorU {
556 fn from(input: ColorF) -> ColorU {
557 ColorU {
558 r: (input.r.min(1.0) * 255.0) as u8,
559 g: (input.g.min(1.0) * 255.0) as u8,
560 b: (input.b.min(1.0) * 255.0) as u8,
561 a: (input.a.min(1.0) * 255.0) as u8,
562 }
563 }
564}
565
566#[derive(Debug, Copy, Clone, PartialEq, Ord, PartialOrd, Eq, Hash)]
567pub enum BorderDetails {
568 Normal(NormalBorder),
569 NinePatch(NinePatchBorder),
570}
571
572#[derive(Debug, Copy, Clone, PartialEq, Ord, PartialOrd, Eq, Hash)]
574pub struct NormalBorder {
575 pub left: BorderSide,
576 pub right: BorderSide,
577 pub top: BorderSide,
578 pub bottom: BorderSide,
579 pub radius: Option<(
580 StyleBorderTopLeftRadius,
581 StyleBorderTopRightRadius,
582 StyleBorderBottomLeftRadius,
583 StyleBorderBottomRightRadius,
584 )>,
585}
586
587#[derive(Debug, Copy, Clone, PartialEq, Ord, PartialOrd, Eq, Hash)]
588#[repr(C)]
589pub struct BorderSide {
590 pub color: ColorU,
591 pub style: BorderStyle,
592}
593
594#[derive(Debug, Copy, Clone, PartialEq, Ord, PartialOrd, Eq, Hash)]
596#[repr(C)]
597pub enum BoxShadowClipMode {
598 Outset,
599 Inset,
600}
601
602impl fmt::Display for BoxShadowClipMode {
603 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
604 use self::BoxShadowClipMode::*;
605 match self {
606 Outset => write!(f, "outset"),
607 Inset => write!(f, "inset"),
608 }
609 }
610}
611
612#[derive(Debug, Copy, Clone, PartialEq, Ord, PartialOrd, Eq, Hash)]
614#[repr(C)]
615pub enum ExtendMode {
616 Clamp,
617 Repeat,
618}
619
620impl Default for ExtendMode {
621 fn default() -> Self {
622 ExtendMode::Clamp
623 }
624}
625
626#[derive(Debug, Copy, Clone, PartialEq, Ord, PartialOrd, Eq, Hash)]
628#[repr(C)]
629pub enum BorderStyle {
630 None,
631 Solid,
632 Double,
633 Dotted,
634 Dashed,
635 Hidden,
636 Groove,
637 Ridge,
638 Inset,
639 Outset,
640}
641
642impl fmt::Display for BorderStyle {
643 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
644 use self::BorderStyle::*;
645 match self {
646 None => write!(f, "none"),
647 Solid => write!(f, "solid"),
648 Double => write!(f, "double"),
649 Dotted => write!(f, "dotted"),
650 Dashed => write!(f, "dashed"),
651 Hidden => write!(f, "hidden"),
652 Groove => write!(f, "groove"),
653 Ridge => write!(f, "ridge"),
654 Inset => write!(f, "inset"),
655 Outset => write!(f, "outset"),
656 }
657 }
658}
659
660impl BorderStyle {
661 pub fn normalize_border(self) -> Option<BorderStyleNoNone> {
662 match self {
663 BorderStyle::None => None,
664 BorderStyle::Solid => Some(BorderStyleNoNone::Solid),
665 BorderStyle::Double => Some(BorderStyleNoNone::Double),
666 BorderStyle::Dotted => Some(BorderStyleNoNone::Dotted),
667 BorderStyle::Dashed => Some(BorderStyleNoNone::Dashed),
668 BorderStyle::Hidden => Some(BorderStyleNoNone::Hidden),
669 BorderStyle::Groove => Some(BorderStyleNoNone::Groove),
670 BorderStyle::Ridge => Some(BorderStyleNoNone::Ridge),
671 BorderStyle::Inset => Some(BorderStyleNoNone::Inset),
672 BorderStyle::Outset => Some(BorderStyleNoNone::Outset),
673 }
674 }
675}
676
677#[derive(Debug, Copy, Clone, PartialEq, Ord, PartialOrd, Eq, Hash)]
678pub enum BorderStyleNoNone {
679 Solid,
680 Double,
681 Dotted,
682 Dashed,
683 Hidden,
684 Groove,
685 Ridge,
686 Inset,
687 Outset,
688}
689
690impl Default for BorderStyle {
691 fn default() -> Self {
692 BorderStyle::Solid
693 }
694}
695
696#[derive(Debug, Copy, Clone, PartialEq, Ord, PartialOrd, Eq, Hash)]
697pub struct NinePatchBorder {
698 }
700
701macro_rules! derive_debug_zero {
702 ($struct:ident) => {
703 impl fmt::Debug for $struct {
704 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
705 write!(f, "{:?}", self.inner)
706 }
707 }
708 };
709}
710
711macro_rules! derive_display_zero {
712 ($struct:ident) => {
713 impl fmt::Display for $struct {
714 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
715 write!(f, "{}", self.inner)
716 }
717 }
718 };
719}
720
721macro_rules! impl_pixel_value {
724 ($struct:ident) => {
725 derive_debug_zero!($struct);
726 derive_display_zero!($struct);
727
728 impl $struct {
729 #[inline]
730 pub const fn zero() -> Self {
731 Self {
732 inner: PixelValue::zero(),
733 }
734 }
735
736 #[inline]
739 pub const fn const_px(value: isize) -> Self {
740 Self {
741 inner: PixelValue::const_px(value),
742 }
743 }
744
745 #[inline]
748 pub const fn const_em(value: isize) -> Self {
749 Self {
750 inner: PixelValue::const_em(value),
751 }
752 }
753
754 #[inline]
757 pub const fn const_pt(value: isize) -> Self {
758 Self {
759 inner: PixelValue::const_pt(value),
760 }
761 }
762
763 #[inline]
766 pub const fn const_percent(value: isize) -> Self {
767 Self {
768 inner: PixelValue::const_percent(value),
769 }
770 }
771
772 #[inline]
773 pub const fn const_from_metric(metric: SizeMetric, value: isize) -> Self {
774 Self {
775 inner: PixelValue::const_from_metric(metric, value),
776 }
777 }
778
779 #[inline]
780 pub fn px(value: f32) -> Self {
781 Self {
782 inner: PixelValue::px(value),
783 }
784 }
785
786 #[inline]
787 pub fn em(value: f32) -> Self {
788 Self {
789 inner: PixelValue::em(value),
790 }
791 }
792
793 #[inline]
794 pub fn pt(value: f32) -> Self {
795 Self {
796 inner: PixelValue::pt(value),
797 }
798 }
799
800 #[inline]
801 pub fn percent(value: f32) -> Self {
802 Self {
803 inner: PixelValue::percent(value),
804 }
805 }
806
807 #[inline]
808 pub fn from_metric(metric: SizeMetric, value: f32) -> Self {
809 Self {
810 inner: PixelValue::from_metric(metric, value),
811 }
812 }
813
814 #[inline]
815 pub fn interpolate(&self, other: &Self, t: f32) -> Self {
816 $struct {
817 inner: self.inner.interpolate(&other.inner, t),
818 }
819 }
820 }
821 };
822}
823
824macro_rules! impl_percentage_value {
825 ($struct:ident) => {
826 impl ::core::fmt::Display for $struct {
827 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
828 write!(f, "{}%", self.inner.get())
829 }
830 }
831
832 impl ::core::fmt::Debug for $struct {
833 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
834 write!(f, "{}%", self.inner.get())
835 }
836 }
837
838 impl $struct {
839 #[inline]
842 pub const fn const_new(value: isize) -> Self {
843 Self {
844 inner: PercentageValue::const_new(value),
845 }
846 }
847
848 #[inline]
849 pub fn new(value: f32) -> Self {
850 Self {
851 inner: PercentageValue::new(value),
852 }
853 }
854
855 #[inline]
856 pub fn interpolate(&self, other: &Self, t: f32) -> Self {
857 $struct {
858 inner: self.inner.interpolate(&other.inner, t),
859 }
860 }
861 }
862 };
863}
864
865macro_rules! impl_float_value {
866 ($struct:ident) => {
867 impl $struct {
868 pub const fn const_new(value: isize) -> Self {
871 Self {
872 inner: FloatValue::const_new(value),
873 }
874 }
875
876 pub fn new(value: f32) -> Self {
877 Self {
878 inner: FloatValue::new(value),
879 }
880 }
881
882 pub fn get(&self) -> f32 {
883 self.inner.get()
884 }
885
886 #[inline]
887 pub fn interpolate(&self, other: &Self, t: f32) -> Self {
888 Self {
889 inner: self.inner.interpolate(&other.inner, t),
890 }
891 }
892 }
893
894 impl From<f32> for $struct {
895 fn from(val: f32) -> Self {
896 Self {
897 inner: FloatValue::from(val),
898 }
899 }
900 }
901
902 impl ::core::fmt::Display for $struct {
903 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
904 write!(f, "{}", self.inner.get())
905 }
906 }
907
908 impl ::core::fmt::Debug for $struct {
909 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
910 write!(f, "{}", self.inner.get())
911 }
912 }
913 };
914}
915
916#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
917pub enum CombinedCssPropertyType {
918 BorderRadius,
919 Overflow,
920 Margin,
921 Border,
922 BorderLeft,
923 BorderRight,
924 BorderTop,
925 BorderBottom,
926 Padding,
927 BoxShadow,
928 BackgroundColor, BackgroundImage, }
931
932impl fmt::Display for CombinedCssPropertyType {
933 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
934 let key = COMBINED_CSS_PROPERTIES_KEY_MAP
935 .iter()
936 .find(|(v, _)| *v == *self)
937 .and_then(|(k, _)| Some(k))
938 .unwrap();
939 write!(f, "{}", key)
940 }
941}
942
943impl CombinedCssPropertyType {
944 pub fn from_str(input: &str, map: &CssKeyMap) -> Option<Self> {
957 let input = input.trim();
958 map.shorthands.get(input).map(|x| *x)
959 }
960
961 pub fn to_str(&self, map: &CssKeyMap) -> &'static str {
963 map.shorthands
964 .iter()
965 .find(|(_, v)| *v == self)
966 .map(|(k, _)| k)
967 .unwrap()
968 }
969}
970
971#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
972pub struct CssKeyMap {
973 pub non_shorthands: BTreeMap<&'static str, CssPropertyType>,
975 pub shorthands: BTreeMap<&'static str, CombinedCssPropertyType>,
977}
978
979impl CssKeyMap {
980 pub fn get() -> Self {
981 get_css_key_map()
982 }
983}
984
985pub fn get_css_key_map() -> CssKeyMap {
987 CssKeyMap {
988 non_shorthands: CSS_PROPERTY_KEY_MAP.iter().map(|(v, k)| (*k, *v)).collect(),
989 shorthands: COMBINED_CSS_PROPERTIES_KEY_MAP
990 .iter()
991 .map(|(v, k)| (*k, *v))
992 .collect(),
993 }
994}
995
996#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
999#[repr(C)]
1000pub enum CssPropertyType {
1001 TextColor,
1002 FontSize,
1003 FontFamily,
1004 TextAlign,
1005 LetterSpacing,
1006 LineHeight,
1007 WordSpacing,
1008 TabWidth,
1009 Cursor,
1010 Display,
1011 Float,
1012 BoxSizing,
1013 Width,
1014 Height,
1015 MinWidth,
1016 MinHeight,
1017 MaxWidth,
1018 MaxHeight,
1019 Position,
1020 Top,
1021 Right,
1022 Left,
1023 Bottom,
1024 FlexWrap,
1025 FlexDirection,
1026 FlexGrow,
1027 FlexShrink,
1028 JustifyContent,
1029 AlignItems,
1030 AlignContent,
1031 BackgroundContent,
1032 BackgroundPosition,
1033 BackgroundSize,
1034 BackgroundRepeat,
1035 OverflowX,
1036 OverflowY,
1037 PaddingTop,
1038 PaddingLeft,
1039 PaddingRight,
1040 PaddingBottom,
1041 MarginTop,
1042 MarginLeft,
1043 MarginRight,
1044 MarginBottom,
1045 BorderTopLeftRadius,
1046 BorderTopRightRadius,
1047 BorderBottomLeftRadius,
1048 BorderBottomRightRadius,
1049 BorderTopColor,
1050 BorderRightColor,
1051 BorderLeftColor,
1052 BorderBottomColor,
1053 BorderTopStyle,
1054 BorderRightStyle,
1055 BorderLeftStyle,
1056 BorderBottomStyle,
1057 BorderTopWidth,
1058 BorderRightWidth,
1059 BorderLeftWidth,
1060 BorderBottomWidth,
1061 BoxShadowLeft,
1062 BoxShadowRight,
1063 BoxShadowTop,
1064 BoxShadowBottom,
1065 ScrollbarStyle,
1066 Opacity,
1067 Transform,
1068 TransformOrigin,
1069 PerspectiveOrigin,
1070 BackfaceVisibility,
1071 MixBlendMode,
1072 Filter,
1073 BackdropFilter,
1074 TextShadow,
1075}
1076
1077impl CssPropertyType {
1078 pub fn from_str(input: &str, map: &CssKeyMap) -> Option<Self> {
1096 let input = input.trim();
1097 map.non_shorthands.get(input).and_then(|x| Some(*x))
1098 }
1099
1100 pub fn to_str(&self) -> &'static str {
1102 match self {
1103 CssPropertyType::TextColor => "color",
1104 CssPropertyType::FontSize => "font-size",
1105 CssPropertyType::FontFamily => "font-family",
1106 CssPropertyType::TextAlign => "text-align",
1107 CssPropertyType::LetterSpacing => "letter-spacing",
1108 CssPropertyType::LineHeight => "line-height",
1109 CssPropertyType::WordSpacing => "word-spacing",
1110 CssPropertyType::TabWidth => "tab-width",
1111 CssPropertyType::Cursor => "cursor",
1112 CssPropertyType::Display => "display",
1113 CssPropertyType::Float => "float",
1114 CssPropertyType::BoxSizing => "box-sizing",
1115 CssPropertyType::Width => "width",
1116 CssPropertyType::Height => "height",
1117 CssPropertyType::MinWidth => "min-width",
1118 CssPropertyType::MinHeight => "min-height",
1119 CssPropertyType::MaxWidth => "max-width",
1120 CssPropertyType::MaxHeight => "max-height",
1121 CssPropertyType::Position => "position",
1122 CssPropertyType::Top => "top",
1123 CssPropertyType::Right => "right",
1124 CssPropertyType::Left => "left",
1125 CssPropertyType::Bottom => "bottom",
1126 CssPropertyType::FlexWrap => "flex-wrap",
1127 CssPropertyType::FlexDirection => "flex-direction",
1128 CssPropertyType::FlexGrow => "flex-grow",
1129 CssPropertyType::FlexShrink => "flex-shrink",
1130 CssPropertyType::JustifyContent => "justify-content",
1131 CssPropertyType::AlignItems => "align-items",
1132 CssPropertyType::AlignContent => "align-content",
1133 CssPropertyType::BackgroundContent => "background",
1134 CssPropertyType::BackgroundPosition => "background-position",
1135 CssPropertyType::BackgroundSize => "background-size",
1136 CssPropertyType::BackgroundRepeat => "background-repeat",
1137 CssPropertyType::OverflowX => "overflow-x",
1138 CssPropertyType::OverflowY => "overflow-y",
1139 CssPropertyType::PaddingTop => "padding-top",
1140 CssPropertyType::PaddingLeft => "padding-left",
1141 CssPropertyType::PaddingRight => "padding-right",
1142 CssPropertyType::PaddingBottom => "padding-bottom",
1143 CssPropertyType::MarginTop => "margin-top",
1144 CssPropertyType::MarginLeft => "margin-left",
1145 CssPropertyType::MarginRight => "margin-right",
1146 CssPropertyType::MarginBottom => "margin-bottom",
1147 CssPropertyType::BorderTopLeftRadius => "border-top-left-radius",
1148 CssPropertyType::BorderTopRightRadius => "border-top-right-radius",
1149 CssPropertyType::BorderBottomLeftRadius => "border-bottom-left-radius",
1150 CssPropertyType::BorderBottomRightRadius => "border-bottom-right-radius",
1151 CssPropertyType::BorderTopColor => "border-top-color",
1152 CssPropertyType::BorderRightColor => "border-right-color",
1153 CssPropertyType::BorderLeftColor => "border-left-color",
1154 CssPropertyType::BorderBottomColor => "border-bottom-color",
1155 CssPropertyType::BorderTopStyle => "border-top-style",
1156 CssPropertyType::BorderRightStyle => "border-right-style",
1157 CssPropertyType::BorderLeftStyle => "border-left-style",
1158 CssPropertyType::BorderBottomStyle => "border-bottom-style",
1159 CssPropertyType::BorderTopWidth => "border-top-width",
1160 CssPropertyType::BorderRightWidth => "border-right-width",
1161 CssPropertyType::BorderLeftWidth => "border-left-width",
1162 CssPropertyType::BorderBottomWidth => "border-bottom-width",
1163 CssPropertyType::BoxShadowLeft => "-azul-box-shadow-left",
1164 CssPropertyType::BoxShadowRight => "-azul-box-shadow-right",
1165 CssPropertyType::BoxShadowTop => "-azul-box-shadow-top",
1166 CssPropertyType::BoxShadowBottom => "-azul-box-shadow-bottom",
1167 CssPropertyType::ScrollbarStyle => "-azul-scrollbar-style",
1168 CssPropertyType::Opacity => "opacity",
1169 CssPropertyType::Transform => "transform",
1170 CssPropertyType::TransformOrigin => "transform-origin",
1171 CssPropertyType::PerspectiveOrigin => "perspective-origin",
1172 CssPropertyType::BackfaceVisibility => "backface-visibility",
1173 CssPropertyType::MixBlendMode => "mix-blend-mode",
1174 CssPropertyType::Filter => "filter",
1175 CssPropertyType::BackdropFilter => "backdrop-filter",
1176 CssPropertyType::TextShadow => "text-shadow",
1177 }
1178 }
1179
1180 pub fn is_inheritable(&self) -> bool {
1182 use self::CssPropertyType::*;
1183 match self {
1184 TextColor | FontFamily | FontSize | LineHeight | TextAlign => true,
1185 _ => false,
1186 }
1187 }
1188
1189 pub fn can_trigger_relayout(&self) -> bool {
1192 use self::CssPropertyType::*;
1193
1194 match self {
1201 TextColor
1202 | Cursor
1203 | BackgroundContent
1204 | BackgroundPosition
1205 | BackgroundSize
1206 | BackgroundRepeat
1207 | BorderTopLeftRadius
1208 | BorderTopRightRadius
1209 | BorderBottomLeftRadius
1210 | BorderBottomRightRadius
1211 | BorderTopColor
1212 | BorderRightColor
1213 | BorderLeftColor
1214 | BorderBottomColor
1215 | BorderTopStyle
1216 | BorderRightStyle
1217 | BorderLeftStyle
1218 | BorderBottomStyle
1219 | BoxShadowLeft
1220 | BoxShadowRight
1221 | BoxShadowTop
1222 | BoxShadowBottom
1223 | ScrollbarStyle
1224 | Opacity
1225 | Transform
1226 | TransformOrigin
1227 | PerspectiveOrigin
1228 | BackfaceVisibility
1229 | MixBlendMode
1230 | Filter
1231 | BackdropFilter
1232 | TextShadow => false,
1233 _ => true,
1234 }
1235 }
1236
1237 pub fn is_gpu_only_property(&self) -> bool {
1239 match self {
1240 CssPropertyType::Opacity |
1241 CssPropertyType::Transform => true,
1242 _ => false
1243 }
1244 }
1245}
1246
1247impl fmt::Debug for CssPropertyType {
1248 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1249 write!(f, "{}", self.to_str())
1250 }
1251}
1252
1253impl fmt::Display for CssPropertyType {
1254 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1255 write!(f, "{}", self.to_str())
1256 }
1257}
1258
1259#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
1262#[repr(C, u8)]
1263pub enum CssProperty {
1264 TextColor(StyleTextColorValue),
1265 FontSize(StyleFontSizeValue),
1266 FontFamily(StyleFontFamilyVecValue),
1267 TextAlign(StyleTextAlignValue),
1268 LetterSpacing(StyleLetterSpacingValue),
1269 LineHeight(StyleLineHeightValue),
1270 WordSpacing(StyleWordSpacingValue),
1271 TabWidth(StyleTabWidthValue),
1272 Cursor(StyleCursorValue),
1273 Display(LayoutDisplayValue),
1274 Float(LayoutFloatValue),
1275 BoxSizing(LayoutBoxSizingValue),
1276 Width(LayoutWidthValue),
1277 Height(LayoutHeightValue),
1278 MinWidth(LayoutMinWidthValue),
1279 MinHeight(LayoutMinHeightValue),
1280 MaxWidth(LayoutMaxWidthValue),
1281 MaxHeight(LayoutMaxHeightValue),
1282 Position(LayoutPositionValue),
1283 Top(LayoutTopValue),
1284 Right(LayoutRightValue),
1285 Left(LayoutLeftValue),
1286 Bottom(LayoutBottomValue),
1287 FlexWrap(LayoutFlexWrapValue),
1288 FlexDirection(LayoutFlexDirectionValue),
1289 FlexGrow(LayoutFlexGrowValue),
1290 FlexShrink(LayoutFlexShrinkValue),
1291 JustifyContent(LayoutJustifyContentValue),
1292 AlignItems(LayoutAlignItemsValue),
1293 AlignContent(LayoutAlignContentValue),
1294 BackgroundContent(StyleBackgroundContentVecValue),
1295 BackgroundPosition(StyleBackgroundPositionVecValue),
1296 BackgroundSize(StyleBackgroundSizeVecValue),
1297 BackgroundRepeat(StyleBackgroundRepeatVecValue),
1298 OverflowX(LayoutOverflowValue),
1299 OverflowY(LayoutOverflowValue),
1300 PaddingTop(LayoutPaddingTopValue),
1301 PaddingLeft(LayoutPaddingLeftValue),
1302 PaddingRight(LayoutPaddingRightValue),
1303 PaddingBottom(LayoutPaddingBottomValue),
1304 MarginTop(LayoutMarginTopValue),
1305 MarginLeft(LayoutMarginLeftValue),
1306 MarginRight(LayoutMarginRightValue),
1307 MarginBottom(LayoutMarginBottomValue),
1308 BorderTopLeftRadius(StyleBorderTopLeftRadiusValue),
1309 BorderTopRightRadius(StyleBorderTopRightRadiusValue),
1310 BorderBottomLeftRadius(StyleBorderBottomLeftRadiusValue),
1311 BorderBottomRightRadius(StyleBorderBottomRightRadiusValue),
1312 BorderTopColor(StyleBorderTopColorValue),
1313 BorderRightColor(StyleBorderRightColorValue),
1314 BorderLeftColor(StyleBorderLeftColorValue),
1315 BorderBottomColor(StyleBorderBottomColorValue),
1316 BorderTopStyle(StyleBorderTopStyleValue),
1317 BorderRightStyle(StyleBorderRightStyleValue),
1318 BorderLeftStyle(StyleBorderLeftStyleValue),
1319 BorderBottomStyle(StyleBorderBottomStyleValue),
1320 BorderTopWidth(LayoutBorderTopWidthValue),
1321 BorderRightWidth(LayoutBorderRightWidthValue),
1322 BorderLeftWidth(LayoutBorderLeftWidthValue),
1323 BorderBottomWidth(LayoutBorderBottomWidthValue),
1324 BoxShadowLeft(StyleBoxShadowValue),
1325 BoxShadowRight(StyleBoxShadowValue),
1326 BoxShadowTop(StyleBoxShadowValue),
1327 BoxShadowBottom(StyleBoxShadowValue),
1328 ScrollbarStyle(ScrollbarStyleValue),
1329 Opacity(StyleOpacityValue),
1330 Transform(StyleTransformVecValue),
1331 TransformOrigin(StyleTransformOriginValue),
1332 PerspectiveOrigin(StylePerspectiveOriginValue),
1333 BackfaceVisibility(StyleBackfaceVisibilityValue),
1334 MixBlendMode(StyleMixBlendModeValue),
1335 Filter(StyleFilterVecValue),
1336 BackdropFilter(StyleFilterVecValue),
1337 TextShadow(StyleBoxShadowValue),
1338}
1339
1340impl_option!(
1341 CssProperty,
1342 OptionCssProperty,
1343 copy = false,
1344 [Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord]
1345);
1346
1347macro_rules! css_property_from_type {
1348 ($prop_type:expr, $content_type:ident) => {{
1349 match $prop_type {
1350 CssPropertyType::TextColor => {
1351 CssProperty::TextColor(StyleTextColorValue::$content_type)
1352 }
1353 CssPropertyType::FontSize => CssProperty::FontSize(StyleFontSizeValue::$content_type),
1354 CssPropertyType::FontFamily => {
1355 CssProperty::FontFamily(StyleFontFamilyVecValue::$content_type)
1356 }
1357 CssPropertyType::TextAlign => {
1358 CssProperty::TextAlign(StyleTextAlignValue::$content_type)
1359 }
1360 CssPropertyType::LetterSpacing => {
1361 CssProperty::LetterSpacing(StyleLetterSpacingValue::$content_type)
1362 }
1363 CssPropertyType::LineHeight => {
1364 CssProperty::LineHeight(StyleLineHeightValue::$content_type)
1365 }
1366 CssPropertyType::WordSpacing => {
1367 CssProperty::WordSpacing(StyleWordSpacingValue::$content_type)
1368 }
1369 CssPropertyType::TabWidth => CssProperty::TabWidth(StyleTabWidthValue::$content_type),
1370 CssPropertyType::Cursor => CssProperty::Cursor(StyleCursorValue::$content_type),
1371 CssPropertyType::Display => CssProperty::Display(LayoutDisplayValue::$content_type),
1372 CssPropertyType::Float => CssProperty::Float(LayoutFloatValue::$content_type),
1373 CssPropertyType::BoxSizing => {
1374 CssProperty::BoxSizing(LayoutBoxSizingValue::$content_type)
1375 }
1376 CssPropertyType::Width => CssProperty::Width(LayoutWidthValue::$content_type),
1377 CssPropertyType::Height => CssProperty::Height(LayoutHeightValue::$content_type),
1378 CssPropertyType::MinWidth => CssProperty::MinWidth(LayoutMinWidthValue::$content_type),
1379 CssPropertyType::MinHeight => {
1380 CssProperty::MinHeight(LayoutMinHeightValue::$content_type)
1381 }
1382 CssPropertyType::MaxWidth => CssProperty::MaxWidth(LayoutMaxWidthValue::$content_type),
1383 CssPropertyType::MaxHeight => {
1384 CssProperty::MaxHeight(LayoutMaxHeightValue::$content_type)
1385 }
1386 CssPropertyType::Position => CssProperty::Position(LayoutPositionValue::$content_type),
1387 CssPropertyType::Top => CssProperty::Top(LayoutTopValue::$content_type),
1388 CssPropertyType::Right => CssProperty::Right(LayoutRightValue::$content_type),
1389 CssPropertyType::Left => CssProperty::Left(LayoutLeftValue::$content_type),
1390 CssPropertyType::Bottom => CssProperty::Bottom(LayoutBottomValue::$content_type),
1391 CssPropertyType::FlexWrap => CssProperty::FlexWrap(LayoutFlexWrapValue::$content_type),
1392 CssPropertyType::FlexDirection => {
1393 CssProperty::FlexDirection(LayoutFlexDirectionValue::$content_type)
1394 }
1395 CssPropertyType::FlexGrow => CssProperty::FlexGrow(LayoutFlexGrowValue::$content_type),
1396 CssPropertyType::FlexShrink => {
1397 CssProperty::FlexShrink(LayoutFlexShrinkValue::$content_type)
1398 }
1399 CssPropertyType::JustifyContent => {
1400 CssProperty::JustifyContent(LayoutJustifyContentValue::$content_type)
1401 }
1402 CssPropertyType::AlignItems => {
1403 CssProperty::AlignItems(LayoutAlignItemsValue::$content_type)
1404 }
1405 CssPropertyType::AlignContent => {
1406 CssProperty::AlignContent(LayoutAlignContentValue::$content_type)
1407 }
1408 CssPropertyType::BackgroundContent => {
1409 CssProperty::BackgroundContent(StyleBackgroundContentVecValue::$content_type)
1410 }
1411 CssPropertyType::BackgroundPosition => {
1412 CssProperty::BackgroundPosition(StyleBackgroundPositionVecValue::$content_type)
1413 }
1414 CssPropertyType::BackgroundSize => {
1415 CssProperty::BackgroundSize(StyleBackgroundSizeVecValue::$content_type)
1416 }
1417 CssPropertyType::BackgroundRepeat => {
1418 CssProperty::BackgroundRepeat(StyleBackgroundRepeatVecValue::$content_type)
1419 }
1420 CssPropertyType::OverflowX => {
1421 CssProperty::OverflowX(LayoutOverflowValue::$content_type)
1422 }
1423 CssPropertyType::OverflowY => {
1424 CssProperty::OverflowY(LayoutOverflowValue::$content_type)
1425 }
1426 CssPropertyType::PaddingTop => {
1427 CssProperty::PaddingTop(LayoutPaddingTopValue::$content_type)
1428 }
1429 CssPropertyType::PaddingLeft => {
1430 CssProperty::PaddingLeft(LayoutPaddingLeftValue::$content_type)
1431 }
1432 CssPropertyType::PaddingRight => {
1433 CssProperty::PaddingRight(LayoutPaddingRightValue::$content_type)
1434 }
1435 CssPropertyType::PaddingBottom => {
1436 CssProperty::PaddingBottom(LayoutPaddingBottomValue::$content_type)
1437 }
1438 CssPropertyType::MarginTop => {
1439 CssProperty::MarginTop(LayoutMarginTopValue::$content_type)
1440 }
1441 CssPropertyType::MarginLeft => {
1442 CssProperty::MarginLeft(LayoutMarginLeftValue::$content_type)
1443 }
1444 CssPropertyType::MarginRight => {
1445 CssProperty::MarginRight(LayoutMarginRightValue::$content_type)
1446 }
1447 CssPropertyType::MarginBottom => {
1448 CssProperty::MarginBottom(LayoutMarginBottomValue::$content_type)
1449 }
1450 CssPropertyType::BorderTopLeftRadius => {
1451 CssProperty::BorderTopLeftRadius(StyleBorderTopLeftRadiusValue::$content_type)
1452 }
1453 CssPropertyType::BorderTopRightRadius => {
1454 CssProperty::BorderTopRightRadius(StyleBorderTopRightRadiusValue::$content_type)
1455 }
1456 CssPropertyType::BorderBottomLeftRadius => {
1457 CssProperty::BorderBottomLeftRadius(StyleBorderBottomLeftRadiusValue::$content_type)
1458 }
1459 CssPropertyType::BorderBottomRightRadius => CssProperty::BorderBottomRightRadius(
1460 StyleBorderBottomRightRadiusValue::$content_type,
1461 ),
1462 CssPropertyType::BorderTopColor => {
1463 CssProperty::BorderTopColor(StyleBorderTopColorValue::$content_type)
1464 }
1465 CssPropertyType::BorderRightColor => {
1466 CssProperty::BorderRightColor(StyleBorderRightColorValue::$content_type)
1467 }
1468 CssPropertyType::BorderLeftColor => {
1469 CssProperty::BorderLeftColor(StyleBorderLeftColorValue::$content_type)
1470 }
1471 CssPropertyType::BorderBottomColor => {
1472 CssProperty::BorderBottomColor(StyleBorderBottomColorValue::$content_type)
1473 }
1474 CssPropertyType::BorderTopStyle => {
1475 CssProperty::BorderTopStyle(StyleBorderTopStyleValue::$content_type)
1476 }
1477 CssPropertyType::BorderRightStyle => {
1478 CssProperty::BorderRightStyle(StyleBorderRightStyleValue::$content_type)
1479 }
1480 CssPropertyType::BorderLeftStyle => {
1481 CssProperty::BorderLeftStyle(StyleBorderLeftStyleValue::$content_type)
1482 }
1483 CssPropertyType::BorderBottomStyle => {
1484 CssProperty::BorderBottomStyle(StyleBorderBottomStyleValue::$content_type)
1485 }
1486 CssPropertyType::BorderTopWidth => {
1487 CssProperty::BorderTopWidth(LayoutBorderTopWidthValue::$content_type)
1488 }
1489 CssPropertyType::BorderRightWidth => {
1490 CssProperty::BorderRightWidth(LayoutBorderRightWidthValue::$content_type)
1491 }
1492 CssPropertyType::BorderLeftWidth => {
1493 CssProperty::BorderLeftWidth(LayoutBorderLeftWidthValue::$content_type)
1494 }
1495 CssPropertyType::BorderBottomWidth => {
1496 CssProperty::BorderBottomWidth(LayoutBorderBottomWidthValue::$content_type)
1497 }
1498 CssPropertyType::BoxShadowLeft => {
1499 CssProperty::BoxShadowLeft(StyleBoxShadowValue::$content_type)
1500 }
1501 CssPropertyType::BoxShadowRight => {
1502 CssProperty::BoxShadowRight(StyleBoxShadowValue::$content_type)
1503 }
1504 CssPropertyType::BoxShadowTop => {
1505 CssProperty::BoxShadowTop(StyleBoxShadowValue::$content_type)
1506 }
1507 CssPropertyType::BoxShadowBottom => {
1508 CssProperty::BoxShadowBottom(StyleBoxShadowValue::$content_type)
1509 }
1510 CssPropertyType::ScrollbarStyle => {
1511 CssProperty::ScrollbarStyle(ScrollbarStyleValue::$content_type)
1512 }
1513 CssPropertyType::Opacity => CssProperty::Opacity(StyleOpacityValue::$content_type),
1514 CssPropertyType::Transform => {
1515 CssProperty::Transform(StyleTransformVecValue::$content_type)
1516 }
1517 CssPropertyType::PerspectiveOrigin => {
1518 CssProperty::PerspectiveOrigin(StylePerspectiveOriginValue::$content_type)
1519 }
1520 CssPropertyType::TransformOrigin => {
1521 CssProperty::TransformOrigin(StyleTransformOriginValue::$content_type)
1522 }
1523 CssPropertyType::BackfaceVisibility => {
1524 CssProperty::BackfaceVisibility(StyleBackfaceVisibilityValue::$content_type)
1525 }
1526 CssPropertyType::MixBlendMode => {
1527 CssProperty::MixBlendMode(StyleMixBlendModeValue::$content_type)
1528 }
1529 CssPropertyType::Filter => CssProperty::Filter(StyleFilterVecValue::$content_type),
1530 CssPropertyType::BackdropFilter => {
1531 CssProperty::BackdropFilter(StyleFilterVecValue::$content_type)
1532 }
1533 CssPropertyType::TextShadow => {
1534 CssProperty::TextShadow(StyleBoxShadowValue::$content_type)
1535 }
1536 }
1537 }};
1538}
1539
1540impl CssProperty {
1541 pub fn is_initial(&self) -> bool {
1542 use self::CssProperty::*;
1543 match self {
1544 TextColor(c) => c.is_initial(),
1545 FontSize(c) => c.is_initial(),
1546 FontFamily(c) => c.is_initial(),
1547 TextAlign(c) => c.is_initial(),
1548 LetterSpacing(c) => c.is_initial(),
1549 LineHeight(c) => c.is_initial(),
1550 WordSpacing(c) => c.is_initial(),
1551 TabWidth(c) => c.is_initial(),
1552 Cursor(c) => c.is_initial(),
1553 Display(c) => c.is_initial(),
1554 Float(c) => c.is_initial(),
1555 BoxSizing(c) => c.is_initial(),
1556 Width(c) => c.is_initial(),
1557 Height(c) => c.is_initial(),
1558 MinWidth(c) => c.is_initial(),
1559 MinHeight(c) => c.is_initial(),
1560 MaxWidth(c) => c.is_initial(),
1561 MaxHeight(c) => c.is_initial(),
1562 Position(c) => c.is_initial(),
1563 Top(c) => c.is_initial(),
1564 Right(c) => c.is_initial(),
1565 Left(c) => c.is_initial(),
1566 Bottom(c) => c.is_initial(),
1567 FlexWrap(c) => c.is_initial(),
1568 FlexDirection(c) => c.is_initial(),
1569 FlexGrow(c) => c.is_initial(),
1570 FlexShrink(c) => c.is_initial(),
1571 JustifyContent(c) => c.is_initial(),
1572 AlignItems(c) => c.is_initial(),
1573 AlignContent(c) => c.is_initial(),
1574 BackgroundContent(c) => c.is_initial(),
1575 BackgroundPosition(c) => c.is_initial(),
1576 BackgroundSize(c) => c.is_initial(),
1577 BackgroundRepeat(c) => c.is_initial(),
1578 OverflowX(c) => c.is_initial(),
1579 OverflowY(c) => c.is_initial(),
1580 PaddingTop(c) => c.is_initial(),
1581 PaddingLeft(c) => c.is_initial(),
1582 PaddingRight(c) => c.is_initial(),
1583 PaddingBottom(c) => c.is_initial(),
1584 MarginTop(c) => c.is_initial(),
1585 MarginLeft(c) => c.is_initial(),
1586 MarginRight(c) => c.is_initial(),
1587 MarginBottom(c) => c.is_initial(),
1588 BorderTopLeftRadius(c) => c.is_initial(),
1589 BorderTopRightRadius(c) => c.is_initial(),
1590 BorderBottomLeftRadius(c) => c.is_initial(),
1591 BorderBottomRightRadius(c) => c.is_initial(),
1592 BorderTopColor(c) => c.is_initial(),
1593 BorderRightColor(c) => c.is_initial(),
1594 BorderLeftColor(c) => c.is_initial(),
1595 BorderBottomColor(c) => c.is_initial(),
1596 BorderTopStyle(c) => c.is_initial(),
1597 BorderRightStyle(c) => c.is_initial(),
1598 BorderLeftStyle(c) => c.is_initial(),
1599 BorderBottomStyle(c) => c.is_initial(),
1600 BorderTopWidth(c) => c.is_initial(),
1601 BorderRightWidth(c) => c.is_initial(),
1602 BorderLeftWidth(c) => c.is_initial(),
1603 BorderBottomWidth(c) => c.is_initial(),
1604 BoxShadowLeft(c) => c.is_initial(),
1605 BoxShadowRight(c) => c.is_initial(),
1606 BoxShadowTop(c) => c.is_initial(),
1607 BoxShadowBottom(c) => c.is_initial(),
1608 ScrollbarStyle(c) => c.is_initial(),
1609 Opacity(c) => c.is_initial(),
1610 Transform(c) => c.is_initial(),
1611 TransformOrigin(c) => c.is_initial(),
1612 PerspectiveOrigin(c) => c.is_initial(),
1613 BackfaceVisibility(c) => c.is_initial(),
1614 MixBlendMode(c) => c.is_initial(),
1615 Filter(c) => c.is_initial(),
1616 BackdropFilter(c) => c.is_initial(),
1617 TextShadow(c) => c.is_initial(),
1618 }
1619 }
1620
1621 pub const fn const_none(prop_type: CssPropertyType) -> Self {
1622 css_property_from_type!(prop_type, None)
1623 }
1624 pub const fn const_auto(prop_type: CssPropertyType) -> Self {
1625 css_property_from_type!(prop_type, Auto)
1626 }
1627 pub const fn const_initial(prop_type: CssPropertyType) -> Self {
1628 css_property_from_type!(prop_type, Initial)
1629 }
1630 pub const fn const_inherit(prop_type: CssPropertyType) -> Self {
1631 css_property_from_type!(prop_type, Inherit)
1632 }
1633
1634 pub const fn const_text_color(input: StyleTextColor) -> Self {
1635 CssProperty::TextColor(StyleTextColorValue::Exact(input))
1636 }
1637 pub const fn const_font_size(input: StyleFontSize) -> Self {
1638 CssProperty::FontSize(StyleFontSizeValue::Exact(input))
1639 }
1640 pub const fn const_font_family(input: StyleFontFamilyVec) -> Self {
1641 CssProperty::FontFamily(StyleFontFamilyVecValue::Exact(input))
1642 }
1643 pub const fn const_text_align(input: StyleTextAlign) -> Self {
1644 CssProperty::TextAlign(StyleTextAlignValue::Exact(input))
1645 }
1646 pub const fn const_letter_spacing(input: StyleLetterSpacing) -> Self {
1647 CssProperty::LetterSpacing(StyleLetterSpacingValue::Exact(input))
1648 }
1649 pub const fn const_line_height(input: StyleLineHeight) -> Self {
1650 CssProperty::LineHeight(StyleLineHeightValue::Exact(input))
1651 }
1652 pub const fn const_word_spacing(input: StyleWordSpacing) -> Self {
1653 CssProperty::WordSpacing(StyleWordSpacingValue::Exact(input))
1654 }
1655 pub const fn const_tab_width(input: StyleTabWidth) -> Self {
1656 CssProperty::TabWidth(StyleTabWidthValue::Exact(input))
1657 }
1658 pub const fn const_cursor(input: StyleCursor) -> Self {
1659 CssProperty::Cursor(StyleCursorValue::Exact(input))
1660 }
1661 pub const fn const_display(input: LayoutDisplay) -> Self {
1662 CssProperty::Display(LayoutDisplayValue::Exact(input))
1663 }
1664 pub const fn const_float(input: LayoutFloat) -> Self {
1665 CssProperty::Float(LayoutFloatValue::Exact(input))
1666 }
1667 pub const fn const_box_sizing(input: LayoutBoxSizing) -> Self {
1668 CssProperty::BoxSizing(LayoutBoxSizingValue::Exact(input))
1669 }
1670 pub const fn const_width(input: LayoutWidth) -> Self {
1671 CssProperty::Width(LayoutWidthValue::Exact(input))
1672 }
1673 pub const fn const_height(input: LayoutHeight) -> Self {
1674 CssProperty::Height(LayoutHeightValue::Exact(input))
1675 }
1676 pub const fn const_min_width(input: LayoutMinWidth) -> Self {
1677 CssProperty::MinWidth(LayoutMinWidthValue::Exact(input))
1678 }
1679 pub const fn const_min_height(input: LayoutMinHeight) -> Self {
1680 CssProperty::MinHeight(LayoutMinHeightValue::Exact(input))
1681 }
1682 pub const fn const_max_width(input: LayoutMaxWidth) -> Self {
1683 CssProperty::MaxWidth(LayoutMaxWidthValue::Exact(input))
1684 }
1685 pub const fn const_max_height(input: LayoutMaxHeight) -> Self {
1686 CssProperty::MaxHeight(LayoutMaxHeightValue::Exact(input))
1687 }
1688 pub const fn const_position(input: LayoutPosition) -> Self {
1689 CssProperty::Position(LayoutPositionValue::Exact(input))
1690 }
1691 pub const fn const_top(input: LayoutTop) -> Self {
1692 CssProperty::Top(LayoutTopValue::Exact(input))
1693 }
1694 pub const fn const_right(input: LayoutRight) -> Self {
1695 CssProperty::Right(LayoutRightValue::Exact(input))
1696 }
1697 pub const fn const_left(input: LayoutLeft) -> Self {
1698 CssProperty::Left(LayoutLeftValue::Exact(input))
1699 }
1700 pub const fn const_bottom(input: LayoutBottom) -> Self {
1701 CssProperty::Bottom(LayoutBottomValue::Exact(input))
1702 }
1703 pub const fn const_flex_wrap(input: LayoutFlexWrap) -> Self {
1704 CssProperty::FlexWrap(LayoutFlexWrapValue::Exact(input))
1705 }
1706 pub const fn const_flex_direction(input: LayoutFlexDirection) -> Self {
1707 CssProperty::FlexDirection(LayoutFlexDirectionValue::Exact(input))
1708 }
1709 pub const fn const_flex_grow(input: LayoutFlexGrow) -> Self {
1710 CssProperty::FlexGrow(LayoutFlexGrowValue::Exact(input))
1711 }
1712 pub const fn const_flex_shrink(input: LayoutFlexShrink) -> Self {
1713 CssProperty::FlexShrink(LayoutFlexShrinkValue::Exact(input))
1714 }
1715 pub const fn const_justify_content(input: LayoutJustifyContent) -> Self {
1716 CssProperty::JustifyContent(LayoutJustifyContentValue::Exact(input))
1717 }
1718 pub const fn const_align_items(input: LayoutAlignItems) -> Self {
1719 CssProperty::AlignItems(LayoutAlignItemsValue::Exact(input))
1720 }
1721 pub const fn const_align_content(input: LayoutAlignContent) -> Self {
1722 CssProperty::AlignContent(LayoutAlignContentValue::Exact(input))
1723 }
1724 pub const fn const_background_content(input: StyleBackgroundContentVec) -> Self {
1725 CssProperty::BackgroundContent(StyleBackgroundContentVecValue::Exact(input))
1726 }
1727 pub const fn const_background_position(input: StyleBackgroundPositionVec) -> Self {
1728 CssProperty::BackgroundPosition(StyleBackgroundPositionVecValue::Exact(input))
1729 }
1730 pub const fn const_background_size(input: StyleBackgroundSizeVec) -> Self {
1731 CssProperty::BackgroundSize(StyleBackgroundSizeVecValue::Exact(input))
1732 }
1733 pub const fn const_background_repeat(input: StyleBackgroundRepeatVec) -> Self {
1734 CssProperty::BackgroundRepeat(StyleBackgroundRepeatVecValue::Exact(input))
1735 }
1736 pub const fn const_overflow_x(input: LayoutOverflow) -> Self {
1737 CssProperty::OverflowX(LayoutOverflowValue::Exact(input))
1738 }
1739 pub const fn const_overflow_y(input: LayoutOverflow) -> Self {
1740 CssProperty::OverflowY(LayoutOverflowValue::Exact(input))
1741 }
1742 pub const fn const_padding_top(input: LayoutPaddingTop) -> Self {
1743 CssProperty::PaddingTop(LayoutPaddingTopValue::Exact(input))
1744 }
1745 pub const fn const_padding_left(input: LayoutPaddingLeft) -> Self {
1746 CssProperty::PaddingLeft(LayoutPaddingLeftValue::Exact(input))
1747 }
1748 pub const fn const_padding_right(input: LayoutPaddingRight) -> Self {
1749 CssProperty::PaddingRight(LayoutPaddingRightValue::Exact(input))
1750 }
1751 pub const fn const_padding_bottom(input: LayoutPaddingBottom) -> Self {
1752 CssProperty::PaddingBottom(LayoutPaddingBottomValue::Exact(input))
1753 }
1754 pub const fn const_margin_top(input: LayoutMarginTop) -> Self {
1755 CssProperty::MarginTop(LayoutMarginTopValue::Exact(input))
1756 }
1757 pub const fn const_margin_left(input: LayoutMarginLeft) -> Self {
1758 CssProperty::MarginLeft(LayoutMarginLeftValue::Exact(input))
1759 }
1760 pub const fn const_margin_right(input: LayoutMarginRight) -> Self {
1761 CssProperty::MarginRight(LayoutMarginRightValue::Exact(input))
1762 }
1763 pub const fn const_margin_bottom(input: LayoutMarginBottom) -> Self {
1764 CssProperty::MarginBottom(LayoutMarginBottomValue::Exact(input))
1765 }
1766 pub const fn const_border_top_left_radius(input: StyleBorderTopLeftRadius) -> Self {
1767 CssProperty::BorderTopLeftRadius(StyleBorderTopLeftRadiusValue::Exact(input))
1768 }
1769 pub const fn const_border_top_right_radius(input: StyleBorderTopRightRadius) -> Self {
1770 CssProperty::BorderTopRightRadius(StyleBorderTopRightRadiusValue::Exact(input))
1771 }
1772 pub const fn const_border_bottom_left_radius(input: StyleBorderBottomLeftRadius) -> Self {
1773 CssProperty::BorderBottomLeftRadius(StyleBorderBottomLeftRadiusValue::Exact(input))
1774 }
1775 pub const fn const_border_bottom_right_radius(input: StyleBorderBottomRightRadius) -> Self {
1776 CssProperty::BorderBottomRightRadius(StyleBorderBottomRightRadiusValue::Exact(input))
1777 }
1778 pub const fn const_border_top_color(input: StyleBorderTopColor) -> Self {
1779 CssProperty::BorderTopColor(StyleBorderTopColorValue::Exact(input))
1780 }
1781 pub const fn const_border_right_color(input: StyleBorderRightColor) -> Self {
1782 CssProperty::BorderRightColor(StyleBorderRightColorValue::Exact(input))
1783 }
1784 pub const fn const_border_left_color(input: StyleBorderLeftColor) -> Self {
1785 CssProperty::BorderLeftColor(StyleBorderLeftColorValue::Exact(input))
1786 }
1787 pub const fn const_border_bottom_color(input: StyleBorderBottomColor) -> Self {
1788 CssProperty::BorderBottomColor(StyleBorderBottomColorValue::Exact(input))
1789 }
1790 pub const fn const_border_top_style(input: StyleBorderTopStyle) -> Self {
1791 CssProperty::BorderTopStyle(StyleBorderTopStyleValue::Exact(input))
1792 }
1793 pub const fn const_border_right_style(input: StyleBorderRightStyle) -> Self {
1794 CssProperty::BorderRightStyle(StyleBorderRightStyleValue::Exact(input))
1795 }
1796 pub const fn const_border_left_style(input: StyleBorderLeftStyle) -> Self {
1797 CssProperty::BorderLeftStyle(StyleBorderLeftStyleValue::Exact(input))
1798 }
1799 pub const fn const_border_bottom_style(input: StyleBorderBottomStyle) -> Self {
1800 CssProperty::BorderBottomStyle(StyleBorderBottomStyleValue::Exact(input))
1801 }
1802 pub const fn const_border_top_width(input: LayoutBorderTopWidth) -> Self {
1803 CssProperty::BorderTopWidth(LayoutBorderTopWidthValue::Exact(input))
1804 }
1805 pub const fn const_border_right_width(input: LayoutBorderRightWidth) -> Self {
1806 CssProperty::BorderRightWidth(LayoutBorderRightWidthValue::Exact(input))
1807 }
1808 pub const fn const_border_left_width(input: LayoutBorderLeftWidth) -> Self {
1809 CssProperty::BorderLeftWidth(LayoutBorderLeftWidthValue::Exact(input))
1810 }
1811 pub const fn const_border_bottom_width(input: LayoutBorderBottomWidth) -> Self {
1812 CssProperty::BorderBottomWidth(LayoutBorderBottomWidthValue::Exact(input))
1813 }
1814 pub const fn const_box_shadow_left(input: StyleBoxShadow) -> Self {
1815 CssProperty::BoxShadowLeft(StyleBoxShadowValue::Exact(input))
1816 }
1817 pub const fn const_box_shadow_right(input: StyleBoxShadow) -> Self {
1818 CssProperty::BoxShadowRight(StyleBoxShadowValue::Exact(input))
1819 }
1820 pub const fn const_box_shadow_top(input: StyleBoxShadow) -> Self {
1821 CssProperty::BoxShadowTop(StyleBoxShadowValue::Exact(input))
1822 }
1823 pub const fn const_box_shadow_bottom(input: StyleBoxShadow) -> Self {
1824 CssProperty::BoxShadowBottom(StyleBoxShadowValue::Exact(input))
1825 }
1826 pub const fn const_opacity(input: StyleOpacity) -> Self {
1827 CssProperty::Opacity(StyleOpacityValue::Exact(input))
1828 }
1829 pub const fn const_transform(input: StyleTransformVec) -> Self {
1830 CssProperty::Transform(StyleTransformVecValue::Exact(input))
1831 }
1832 pub const fn const_transform_origin(input: StyleTransformOrigin) -> Self {
1833 CssProperty::TransformOrigin(StyleTransformOriginValue::Exact(input))
1834 }
1835 pub const fn const_perspective_origin(input: StylePerspectiveOrigin) -> Self {
1836 CssProperty::PerspectiveOrigin(StylePerspectiveOriginValue::Exact(input))
1837 }
1838 pub const fn const_backface_visiblity(input: StyleBackfaceVisibility) -> Self {
1839 CssProperty::BackfaceVisibility(StyleBackfaceVisibilityValue::Exact(input))
1840 }
1841}
1842#[derive(Debug, Copy, Clone, PartialEq)]
1843#[repr(C, u8)]
1844pub enum AnimationInterpolationFunction {
1845 Ease,
1846 Linear,
1847 EaseIn,
1848 EaseOut,
1849 EaseInOut,
1850 CubicBezier(SvgCubicCurve),
1851}
1852
1853#[derive(Debug, Default, Copy, Clone, PartialEq, PartialOrd)]
1854#[repr(C)]
1855pub struct SvgPoint {
1856 pub x: f32,
1857 pub y: f32,
1858}
1859
1860impl_option!(
1861 SvgPoint,
1862 OptionSvgPoint,
1863 [Debug, Clone, PartialEq, PartialOrd]
1864);
1865
1866impl SvgPoint {
1867 #[inline]
1868 pub fn distance(&self, other: Self) -> f64 {
1869 let dx = other.x - self.x;
1870 let dy = other.y - self.y;
1871 libm::hypotf(dx, dy) as f64
1872 }
1873}
1874
1875#[derive(Debug, Default, Copy, Clone, PartialEq, PartialOrd)]
1876#[repr(C)]
1877pub struct SvgRect {
1878 pub width: f32,
1879 pub height: f32,
1880 pub x: f32,
1881 pub y: f32,
1882 pub radius_top_left: f32,
1883 pub radius_top_right: f32,
1884 pub radius_bottom_left: f32,
1885 pub radius_bottom_right: f32,
1886}
1887
1888impl SvgRect {
1889 pub fn union_with(&mut self, other: &Self) {
1890 let self_max_x = self.x + self.width;
1891 let self_max_y = self.y + self.height;
1892 let self_min_x = self.x;
1893 let self_min_y = self.y;
1894
1895 let other_max_x = other.x + other.width;
1896 let other_max_y = other.y + other.height;
1897 let other_min_x = other.x;
1898 let other_min_y = other.y;
1899
1900 let max_x = self_max_x.max(other_max_x);
1901 let max_y = self_max_y.max(other_max_y);
1902 let min_x = self_min_x.min(other_min_x);
1903 let min_y = self_min_y.min(other_min_y);
1904
1905 self.x = min_x;
1906 self.y = min_y;
1907 self.width = max_x - min_x;
1908 self.height = max_y - min_y;
1909 }
1910
1911 pub fn contains_point(&self, x: f32, y: f32) -> bool {
1914 x > self.x && x < self.x + self.width && y > self.y && y < self.y + self.height
1915 }
1916
1917 pub fn expand(
1919 &self,
1920 padding_top: f32,
1921 padding_bottom: f32,
1922 padding_left: f32,
1923 padding_right: f32,
1924 ) -> SvgRect {
1925 SvgRect {
1926 width: self.width + padding_left + padding_right,
1927 height: self.height + padding_top + padding_bottom,
1928 x: self.x - padding_left,
1929 y: self.y - padding_top,
1930 ..*self
1931 }
1932 }
1933
1934 pub fn get_center(&self) -> SvgPoint {
1935 SvgPoint {
1936 x: self.x + (self.width / 2.0),
1937 y: self.y + (self.height / 2.0),
1938 }
1939 }
1940}
1941
1942#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
1943#[repr(C)]
1944pub struct SvgCubicCurve {
1945 pub start: SvgPoint,
1946 pub ctrl_1: SvgPoint,
1947 pub ctrl_2: SvgPoint,
1948 pub end: SvgPoint,
1949}
1950
1951#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
1952#[repr(C)]
1953pub struct SvgVector {
1954 pub x: f64,
1955 pub y: f64,
1956}
1957
1958impl SvgVector {
1959 #[inline]
1961 pub fn angle_degrees(&self) -> f64 {
1962 (-self.x).atan2(self.y).to_degrees()
1969 }
1970
1971 #[inline]
1972 #[must_use = "returns a new vector"]
1973 pub fn normalize(&self) -> Self {
1974 let tangent_length = libm::hypotf(self.x as f32, self.y as f32) as f64;
1975
1976 Self {
1977 x: self.x / tangent_length,
1978 y: self.y / tangent_length,
1979 }
1980 }
1981
1982 #[must_use = "returns a new vector"]
1984 #[inline]
1985 pub fn rotate_90deg_ccw(&self) -> Self {
1986 Self {
1987 x: -self.y,
1988 y: self.x,
1989 }
1990 }
1991}
1992
1993const STEP_SIZE: usize = 20;
1994const STEP_SIZE_F64: f64 = 0.05;
1995
1996impl SvgCubicCurve {
1997 pub fn reverse(&mut self) {
1998 let mut temp = self.start;
1999 self.start = self.end;
2000 self.end = temp;
2001 temp = self.ctrl_1;
2002 self.ctrl_1 = self.ctrl_2;
2003 self.ctrl_2 = temp;
2004 }
2005
2006 pub fn get_start(&self) -> SvgPoint {
2007 self.start
2008 }
2009 pub fn get_end(&self) -> SvgPoint {
2010 self.end
2011 }
2012
2013 pub fn get_x_at_t(&self, t: f64) -> f64 {
2015 let c_x = 3.0 * (self.ctrl_1.x as f64 - self.start.x as f64);
2016 let b_x = 3.0 * (self.ctrl_2.x as f64 - self.ctrl_1.x as f64) - c_x;
2017 let a_x = self.end.x as f64 - self.start.x as f64 - c_x - b_x;
2018
2019 (a_x * t * t * t) + (b_x * t * t) + (c_x * t) + self.start.x as f64
2020 }
2021
2022 pub fn get_y_at_t(&self, t: f64) -> f64 {
2023 let c_x = 3.0 * (self.ctrl_1.y as f64 - self.start.y as f64);
2024 let b_x = 3.0 * (self.ctrl_2.y as f64 - self.ctrl_1.y as f64) - c_x;
2025 let a_x = self.end.y as f64 - self.start.y as f64 - c_x - b_x;
2026
2027 (a_x * t * t * t) + (b_x * t * t) + (c_x * t) + self.start.y as f64
2028 }
2029
2030 pub fn get_length(&self) -> f64 {
2031 let mut arc_length = 0.0;
2033 let mut prev_point = self.get_start();
2034
2035 for i in 0..STEP_SIZE {
2036 let t_next = (i + 1) as f64 * STEP_SIZE_F64;
2037 let next_point = SvgPoint {
2038 x: self.get_x_at_t(t_next) as f32,
2039 y: self.get_y_at_t(t_next) as f32,
2040 };
2041 arc_length += prev_point.distance(next_point);
2042 prev_point = next_point;
2043 }
2044
2045 arc_length
2046 }
2047
2048 pub fn get_t_at_offset(&self, offset: f64) -> f64 {
2049 let mut arc_length = 0.0;
2053 let mut t_current = 0.0;
2054 let mut prev_point = self.get_start();
2055
2056 for i in 0..STEP_SIZE {
2057 let t_next = (i + 1) as f64 * STEP_SIZE_F64;
2058 let next_point = SvgPoint {
2059 x: self.get_x_at_t(t_next) as f32,
2060 y: self.get_y_at_t(t_next) as f32,
2061 };
2062
2063 let distance = prev_point.distance(next_point);
2064
2065 arc_length += distance;
2066
2067 if arc_length > offset {
2069 let remaining = arc_length - offset;
2070 return t_current + (remaining / distance) * STEP_SIZE_F64;
2071 }
2072
2073 prev_point = next_point;
2074 t_current = t_next;
2075 }
2076
2077 t_current
2078 }
2079
2080 pub fn get_tangent_vector_at_t(&self, t: f64) -> SvgVector {
2081 let w0 = SvgPoint {
2091 x: self.ctrl_1.x - self.start.x,
2092 y: self.ctrl_1.y - self.start.y,
2093 };
2094
2095 let w1 = SvgPoint {
2096 x: self.ctrl_2.x - self.ctrl_1.x,
2097 y: self.ctrl_2.y - self.ctrl_1.y,
2098 };
2099
2100 let w2 = SvgPoint {
2101 x: self.end.x - self.ctrl_2.x,
2102 y: self.end.y - self.ctrl_2.y,
2103 };
2104
2105 let quadratic_curve = SvgQuadraticCurve {
2106 start: w0,
2107 ctrl: w1,
2108 end: w2,
2109 };
2110
2111 let tangent_vector = SvgVector {
2116 x: quadratic_curve.get_x_at_t(t),
2117 y: quadratic_curve.get_y_at_t(t),
2118 };
2119
2120 tangent_vector.normalize()
2121 }
2122
2123 pub fn get_bounds(&self) -> SvgRect {
2124 let min_x = self
2125 .start
2126 .x
2127 .min(self.end.x)
2128 .min(self.ctrl_1.x)
2129 .min(self.ctrl_2.x);
2130 let max_x = self
2131 .start
2132 .x
2133 .max(self.end.x)
2134 .max(self.ctrl_1.x)
2135 .max(self.ctrl_2.x);
2136
2137 let min_y = self
2138 .start
2139 .y
2140 .min(self.end.y)
2141 .min(self.ctrl_1.y)
2142 .min(self.ctrl_2.y);
2143 let max_y = self
2144 .start
2145 .y
2146 .max(self.end.y)
2147 .max(self.ctrl_1.y)
2148 .max(self.ctrl_2.y);
2149
2150 let width = (max_x - min_x).abs();
2151 let height = (max_y - min_y).abs();
2152
2153 SvgRect {
2154 width,
2155 height,
2156 x: min_x,
2157 y: min_y,
2158 ..SvgRect::default()
2159 }
2160 }
2161}
2162
2163#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
2164#[repr(C)]
2165pub struct SvgQuadraticCurve {
2166 pub start: SvgPoint,
2167 pub ctrl: SvgPoint,
2168 pub end: SvgPoint,
2169}
2170
2171impl SvgQuadraticCurve {
2172 pub fn reverse(&mut self) {
2173 let mut temp = self.start;
2174 self.start = self.end;
2175 self.end = temp;
2176 }
2177 pub fn get_start(&self) -> SvgPoint {
2178 self.start
2179 }
2180 pub fn get_end(&self) -> SvgPoint {
2181 self.end
2182 }
2183 pub fn get_bounds(&self) -> SvgRect {
2184 let min_x = self.start.x.min(self.end.x).min(self.ctrl.x);
2185 let max_x = self.start.x.max(self.end.x).max(self.ctrl.x);
2186
2187 let min_y = self.start.y.min(self.end.y).min(self.ctrl.y);
2188 let max_y = self.start.y.max(self.end.y).max(self.ctrl.y);
2189
2190 let width = (max_x - min_x).abs();
2191 let height = (max_y - min_y).abs();
2192
2193 SvgRect {
2194 width,
2195 height,
2196 x: min_x,
2197 y: min_y,
2198 ..SvgRect::default()
2199 }
2200 }
2201
2202 pub fn get_x_at_t(&self, t: f64) -> f64 {
2203 let one_minus = 1.0 - t;
2204 let one_minus_squared = one_minus * one_minus;
2205 let t_squared = t * t;
2206
2207 1.0 * one_minus_squared * 1.0 * self.start.x as f64
2208 + 2.0 * one_minus * t * self.ctrl.x as f64
2209 + 3.0 * 1.0 * t_squared * self.end.x as f64
2210 }
2211
2212 pub fn get_y_at_t(&self, t: f64) -> f64 {
2213 let one_minus = 1.0 - t;
2214 let one_minus_squared = one_minus * one_minus;
2215 let t_squared = t * t;
2216
2217 1.0 * one_minus_squared * 1.0 * self.start.y as f64
2218 + 2.0 * one_minus * t * self.ctrl.y as f64
2219 + 3.0 * 1.0 * t_squared * self.end.y as f64
2220 }
2221
2222 pub fn get_length(&self) -> f64 {
2223 self.to_cubic().get_length()
2224 }
2225
2226 pub fn get_t_at_offset(&self, offset: f64) -> f64 {
2227 self.to_cubic().get_t_at_offset(offset)
2228 }
2229
2230 pub fn get_tangent_vector_at_t(&self, t: f64) -> SvgVector {
2231 self.to_cubic().get_tangent_vector_at_t(t)
2232 }
2233
2234 fn to_cubic(&self) -> SvgCubicCurve {
2235 SvgCubicCurve {
2236 start: self.start,
2237 ctrl_1: SvgPoint {
2238 x: self.start.x + (0.75 * self.ctrl.x - self.start.x),
2239 y: self.start.y + (0.75 * self.ctrl.y - self.start.y),
2240 },
2241 ctrl_2: SvgPoint {
2242 x: self.start.x + (0.75 * self.end.x - self.ctrl.x),
2243 y: self.start.y + (0.75 * self.end.y - self.ctrl.y),
2244 },
2245 end: self.end,
2246 }
2247 }
2248}
2249
2250impl AnimationInterpolationFunction {
2251 pub const fn get_curve(self) -> SvgCubicCurve {
2252 match self {
2253 AnimationInterpolationFunction::Ease => SvgCubicCurve {
2254 start: SvgPoint { x: 0.0, y: 0.0 },
2255 ctrl_1: SvgPoint { x: 0.25, y: 0.1 },
2256 ctrl_2: SvgPoint { x: 0.25, y: 1.0 },
2257 end: SvgPoint { x: 1.0, y: 1.0 },
2258 },
2259 AnimationInterpolationFunction::Linear => SvgCubicCurve {
2260 start: SvgPoint { x: 0.0, y: 0.0 },
2261 ctrl_1: SvgPoint { x: 0.0, y: 0.0 },
2262 ctrl_2: SvgPoint { x: 1.0, y: 1.0 },
2263 end: SvgPoint { x: 1.0, y: 1.0 },
2264 },
2265 AnimationInterpolationFunction::EaseIn => SvgCubicCurve {
2266 start: SvgPoint { x: 0.0, y: 0.0 },
2267 ctrl_1: SvgPoint { x: 0.42, y: 0.0 },
2268 ctrl_2: SvgPoint { x: 1.0, y: 1.0 },
2269 end: SvgPoint { x: 1.0, y: 1.0 },
2270 },
2271 AnimationInterpolationFunction::EaseOut => SvgCubicCurve {
2272 start: SvgPoint { x: 0.0, y: 0.0 },
2273 ctrl_1: SvgPoint { x: 0.0, y: 0.0 },
2274 ctrl_2: SvgPoint { x: 0.58, y: 1.0 },
2275 end: SvgPoint { x: 1.0, y: 1.0 },
2276 },
2277 AnimationInterpolationFunction::EaseInOut => SvgCubicCurve {
2278 start: SvgPoint { x: 0.0, y: 0.0 },
2279 ctrl_1: SvgPoint { x: 0.42, y: 0.0 },
2280 ctrl_2: SvgPoint { x: 0.58, y: 1.0 },
2281 end: SvgPoint { x: 1.0, y: 1.0 },
2282 },
2283 AnimationInterpolationFunction::CubicBezier(c) => c,
2284 }
2285 }
2286
2287 pub fn evaluate(self, t: f64) -> f32 {
2288 self.get_curve().get_y_at_t(t) as f32
2289 }
2290}
2291
2292#[derive(Debug, Clone, PartialEq)]
2293#[repr(C)]
2294pub struct InterpolateResolver {
2295 pub interpolate_func: AnimationInterpolationFunction,
2296 pub parent_rect_width: f32,
2297 pub parent_rect_height: f32,
2298 pub current_rect_width: f32,
2299 pub current_rect_height: f32,
2300}
2301
2302impl CssProperty {
2303 pub fn key(&self) -> &'static str {
2304 self.get_type().to_str()
2305 }
2306
2307 pub fn value(&self) -> String {
2308 match self {
2309 CssProperty::TextColor(v) => v.get_css_value_fmt(),
2310 CssProperty::FontSize(v) => v.get_css_value_fmt(),
2311 CssProperty::FontFamily(v) => v.get_css_value_fmt(),
2312 CssProperty::TextAlign(v) => v.get_css_value_fmt(),
2313 CssProperty::LetterSpacing(v) => v.get_css_value_fmt(),
2314 CssProperty::LineHeight(v) => v.get_css_value_fmt(),
2315 CssProperty::WordSpacing(v) => v.get_css_value_fmt(),
2316 CssProperty::TabWidth(v) => v.get_css_value_fmt(),
2317 CssProperty::Cursor(v) => v.get_css_value_fmt(),
2318 CssProperty::Display(v) => v.get_css_value_fmt(),
2319 CssProperty::Float(v) => v.get_css_value_fmt(),
2320 CssProperty::BoxSizing(v) => v.get_css_value_fmt(),
2321 CssProperty::Width(v) => v.get_css_value_fmt(),
2322 CssProperty::Height(v) => v.get_css_value_fmt(),
2323 CssProperty::MinWidth(v) => v.get_css_value_fmt(),
2324 CssProperty::MinHeight(v) => v.get_css_value_fmt(),
2325 CssProperty::MaxWidth(v) => v.get_css_value_fmt(),
2326 CssProperty::MaxHeight(v) => v.get_css_value_fmt(),
2327 CssProperty::Position(v) => v.get_css_value_fmt(),
2328 CssProperty::Top(v) => v.get_css_value_fmt(),
2329 CssProperty::Right(v) => v.get_css_value_fmt(),
2330 CssProperty::Left(v) => v.get_css_value_fmt(),
2331 CssProperty::Bottom(v) => v.get_css_value_fmt(),
2332 CssProperty::FlexWrap(v) => v.get_css_value_fmt(),
2333 CssProperty::FlexDirection(v) => v.get_css_value_fmt(),
2334 CssProperty::FlexGrow(v) => v.get_css_value_fmt(),
2335 CssProperty::FlexShrink(v) => v.get_css_value_fmt(),
2336 CssProperty::JustifyContent(v) => v.get_css_value_fmt(),
2337 CssProperty::AlignItems(v) => v.get_css_value_fmt(),
2338 CssProperty::AlignContent(v) => v.get_css_value_fmt(),
2339 CssProperty::BackgroundContent(v) => v.get_css_value_fmt(),
2340 CssProperty::BackgroundPosition(v) => v.get_css_value_fmt(),
2341 CssProperty::BackgroundSize(v) => v.get_css_value_fmt(),
2342 CssProperty::BackgroundRepeat(v) => v.get_css_value_fmt(),
2343 CssProperty::OverflowX(v) => v.get_css_value_fmt(),
2344 CssProperty::OverflowY(v) => v.get_css_value_fmt(),
2345 CssProperty::PaddingTop(v) => v.get_css_value_fmt(),
2346 CssProperty::PaddingLeft(v) => v.get_css_value_fmt(),
2347 CssProperty::PaddingRight(v) => v.get_css_value_fmt(),
2348 CssProperty::PaddingBottom(v) => v.get_css_value_fmt(),
2349 CssProperty::MarginTop(v) => v.get_css_value_fmt(),
2350 CssProperty::MarginLeft(v) => v.get_css_value_fmt(),
2351 CssProperty::MarginRight(v) => v.get_css_value_fmt(),
2352 CssProperty::MarginBottom(v) => v.get_css_value_fmt(),
2353 CssProperty::BorderTopLeftRadius(v) => v.get_css_value_fmt(),
2354 CssProperty::BorderTopRightRadius(v) => v.get_css_value_fmt(),
2355 CssProperty::BorderBottomLeftRadius(v) => v.get_css_value_fmt(),
2356 CssProperty::BorderBottomRightRadius(v) => v.get_css_value_fmt(),
2357 CssProperty::BorderTopColor(v) => v.get_css_value_fmt(),
2358 CssProperty::BorderRightColor(v) => v.get_css_value_fmt(),
2359 CssProperty::BorderLeftColor(v) => v.get_css_value_fmt(),
2360 CssProperty::BorderBottomColor(v) => v.get_css_value_fmt(),
2361 CssProperty::BorderTopStyle(v) => v.get_css_value_fmt(),
2362 CssProperty::BorderRightStyle(v) => v.get_css_value_fmt(),
2363 CssProperty::BorderLeftStyle(v) => v.get_css_value_fmt(),
2364 CssProperty::BorderBottomStyle(v) => v.get_css_value_fmt(),
2365 CssProperty::BorderTopWidth(v) => v.get_css_value_fmt(),
2366 CssProperty::BorderRightWidth(v) => v.get_css_value_fmt(),
2367 CssProperty::BorderLeftWidth(v) => v.get_css_value_fmt(),
2368 CssProperty::BorderBottomWidth(v) => v.get_css_value_fmt(),
2369 CssProperty::BoxShadowLeft(v) => v.get_css_value_fmt(),
2370 CssProperty::BoxShadowRight(v) => v.get_css_value_fmt(),
2371 CssProperty::BoxShadowTop(v) => v.get_css_value_fmt(),
2372 CssProperty::BoxShadowBottom(v) => v.get_css_value_fmt(),
2373 CssProperty::ScrollbarStyle(v) => v.get_css_value_fmt(),
2374 CssProperty::Opacity(v) => v.get_css_value_fmt(),
2375 CssProperty::Transform(v) => v.get_css_value_fmt(),
2376 CssProperty::TransformOrigin(v) => v.get_css_value_fmt(),
2377 CssProperty::PerspectiveOrigin(v) => v.get_css_value_fmt(),
2378 CssProperty::BackfaceVisibility(v) => v.get_css_value_fmt(),
2379 CssProperty::MixBlendMode(v) => v.get_css_value_fmt(),
2380 CssProperty::Filter(v) => v.get_css_value_fmt(),
2381 CssProperty::BackdropFilter(v) => v.get_css_value_fmt(),
2382 CssProperty::TextShadow(v) => v.get_css_value_fmt(),
2383 }
2384 }
2385
2386 pub fn format_css(&self) -> String {
2387 format!("{}: {};", self.key(), self.value())
2388 }
2389
2390 pub fn interpolate(
2391 &self,
2392 other: &Self,
2393 t: f32,
2394 interpolate_resolver: &InterpolateResolver,
2395 ) -> Self {
2396 if t <= 0.0 {
2397 return self.clone();
2398 } else if t >= 1.0 {
2399 return other.clone();
2400 }
2401
2402 let t: f32 = interpolate_resolver.interpolate_func.evaluate(t as f64);
2404
2405 let t = t.max(0.0).min(1.0);
2406
2407 match (self, other) {
2408 (CssProperty::TextColor(col_start), CssProperty::TextColor(col_end)) => {
2409 let col_start = col_start.get_property().copied().unwrap_or_default();
2410 let col_end = col_end.get_property().copied().unwrap_or_default();
2411 CssProperty::text_color(col_start.interpolate(&col_end, t))
2412 }
2413 (CssProperty::FontSize(fs_start), CssProperty::FontSize(fs_end)) => {
2414 let fs_start = fs_start.get_property().copied().unwrap_or_default();
2415 let fs_end = fs_end.get_property().copied().unwrap_or_default();
2416 CssProperty::font_size(fs_start.interpolate(&fs_end, t))
2417 }
2418 (CssProperty::LetterSpacing(ls_start), CssProperty::LetterSpacing(ls_end)) => {
2419 let ls_start = ls_start.get_property().copied().unwrap_or_default();
2420 let ls_end = ls_end.get_property().copied().unwrap_or_default();
2421 CssProperty::letter_spacing(ls_start.interpolate(&ls_end, t))
2422 }
2423 (CssProperty::LineHeight(lh_start), CssProperty::LineHeight(lh_end)) => {
2424 let lh_start = lh_start.get_property().copied().unwrap_or_default();
2425 let lh_end = lh_end.get_property().copied().unwrap_or_default();
2426 CssProperty::line_height(lh_start.interpolate(&lh_end, t))
2427 }
2428 (CssProperty::WordSpacing(ws_start), CssProperty::WordSpacing(ws_end)) => {
2429 let ws_start = ws_start.get_property().copied().unwrap_or_default();
2430 let ws_end = ws_end.get_property().copied().unwrap_or_default();
2431 CssProperty::word_spacing(ws_start.interpolate(&ws_end, t))
2432 }
2433 (CssProperty::TabWidth(tw_start), CssProperty::TabWidth(tw_end)) => {
2434 let tw_start = tw_start.get_property().copied().unwrap_or_default();
2435 let tw_end = tw_end.get_property().copied().unwrap_or_default();
2436 CssProperty::tab_width(tw_start.interpolate(&tw_end, t))
2437 }
2438 (CssProperty::Width(start), CssProperty::Width(end)) => {
2439 let start = start
2440 .get_property()
2441 .copied()
2442 .unwrap_or(LayoutWidth::px(interpolate_resolver.current_rect_width));
2443 let end = end.get_property().copied().unwrap_or_default();
2444 CssProperty::Width(CssPropertyValue::Exact(start.interpolate(&end, t)))
2445 }
2446 (CssProperty::Height(start), CssProperty::Height(end)) => {
2447 let start = start
2448 .get_property()
2449 .copied()
2450 .unwrap_or(LayoutHeight::px(interpolate_resolver.current_rect_height));
2451 let end = end.get_property().copied().unwrap_or_default();
2452 CssProperty::Height(CssPropertyValue::Exact(start.interpolate(&end, t)))
2453 }
2454 (CssProperty::MinWidth(start), CssProperty::MinWidth(end)) => {
2455 let start = start.get_property().copied().unwrap_or_default();
2456 let end = end.get_property().copied().unwrap_or_default();
2457 CssProperty::MinWidth(CssPropertyValue::Exact(start.interpolate(&end, t)))
2458 }
2459 (CssProperty::MinHeight(start), CssProperty::MinHeight(end)) => {
2460 let start = start.get_property().copied().unwrap_or_default();
2461 let end = end.get_property().copied().unwrap_or_default();
2462 CssProperty::MinHeight(CssPropertyValue::Exact(start.interpolate(&end, t)))
2463 }
2464 (CssProperty::MaxWidth(start), CssProperty::MaxWidth(end)) => {
2465 let start = start.get_property().copied().unwrap_or_default();
2466 let end = end.get_property().copied().unwrap_or_default();
2467 CssProperty::MaxWidth(CssPropertyValue::Exact(start.interpolate(&end, t)))
2468 }
2469 (CssProperty::MaxHeight(start), CssProperty::MaxHeight(end)) => {
2470 let start = start.get_property().copied().unwrap_or_default();
2471 let end = end.get_property().copied().unwrap_or_default();
2472 CssProperty::MaxHeight(CssPropertyValue::Exact(start.interpolate(&end, t)))
2473 }
2474 (CssProperty::Top(start), CssProperty::Top(end)) => {
2475 let start = start.get_property().copied().unwrap_or_default();
2476 let end = end.get_property().copied().unwrap_or_default();
2477 CssProperty::Top(CssPropertyValue::Exact(start.interpolate(&end, t)))
2478 }
2479 (CssProperty::Right(start), CssProperty::Right(end)) => {
2480 let start = start.get_property().copied().unwrap_or_default();
2481 let end = end.get_property().copied().unwrap_or_default();
2482 CssProperty::Right(CssPropertyValue::Exact(start.interpolate(&end, t)))
2483 }
2484 (CssProperty::Left(start), CssProperty::Left(end)) => {
2485 let start = start.get_property().copied().unwrap_or_default();
2486 let end = end.get_property().copied().unwrap_or_default();
2487 CssProperty::Left(CssPropertyValue::Exact(start.interpolate(&end, t)))
2488 }
2489 (CssProperty::Bottom(start), CssProperty::Bottom(end)) => {
2490 let start = start.get_property().copied().unwrap_or_default();
2491 let end = end.get_property().copied().unwrap_or_default();
2492 CssProperty::Bottom(CssPropertyValue::Exact(start.interpolate(&end, t)))
2493 }
2494 (CssProperty::FlexGrow(start), CssProperty::FlexGrow(end)) => {
2495 let start = start.get_property().copied().unwrap_or_default();
2496 let end = end.get_property().copied().unwrap_or_default();
2497 CssProperty::FlexGrow(CssPropertyValue::Exact(start.interpolate(&end, t)))
2498 }
2499 (CssProperty::FlexShrink(start), CssProperty::FlexShrink(end)) => {
2500 let start = start.get_property().copied().unwrap_or_default();
2501 let end = end.get_property().copied().unwrap_or_default();
2502 CssProperty::FlexShrink(CssPropertyValue::Exact(start.interpolate(&end, t)))
2503 }
2504 (CssProperty::PaddingTop(start), CssProperty::PaddingTop(end)) => {
2505 let start = start.get_property().copied().unwrap_or_default();
2506 let end = end.get_property().copied().unwrap_or_default();
2507 CssProperty::PaddingTop(CssPropertyValue::Exact(start.interpolate(&end, t)))
2508 }
2509 (CssProperty::PaddingLeft(start), CssProperty::PaddingLeft(end)) => {
2510 let start = start.get_property().copied().unwrap_or_default();
2511 let end = end.get_property().copied().unwrap_or_default();
2512 CssProperty::PaddingLeft(CssPropertyValue::Exact(start.interpolate(&end, t)))
2513 }
2514 (CssProperty::PaddingRight(start), CssProperty::PaddingRight(end)) => {
2515 let start = start.get_property().copied().unwrap_or_default();
2516 let end = end.get_property().copied().unwrap_or_default();
2517 CssProperty::PaddingRight(CssPropertyValue::Exact(start.interpolate(&end, t)))
2518 }
2519 (CssProperty::PaddingBottom(start), CssProperty::PaddingBottom(end)) => {
2520 let start = start.get_property().copied().unwrap_or_default();
2521 let end = end.get_property().copied().unwrap_or_default();
2522 CssProperty::PaddingBottom(CssPropertyValue::Exact(start.interpolate(&end, t)))
2523 }
2524 (CssProperty::MarginTop(start), CssProperty::MarginTop(end)) => {
2525 let start = start.get_property().copied().unwrap_or_default();
2526 let end = end.get_property().copied().unwrap_or_default();
2527 CssProperty::MarginTop(CssPropertyValue::Exact(start.interpolate(&end, t)))
2528 }
2529 (CssProperty::MarginLeft(start), CssProperty::MarginLeft(end)) => {
2530 let start = start.get_property().copied().unwrap_or_default();
2531 let end = end.get_property().copied().unwrap_or_default();
2532 CssProperty::MarginLeft(CssPropertyValue::Exact(start.interpolate(&end, t)))
2533 }
2534 (CssProperty::MarginRight(start), CssProperty::MarginRight(end)) => {
2535 let start = start.get_property().copied().unwrap_or_default();
2536 let end = end.get_property().copied().unwrap_or_default();
2537 CssProperty::MarginRight(CssPropertyValue::Exact(start.interpolate(&end, t)))
2538 }
2539 (CssProperty::MarginBottom(start), CssProperty::MarginBottom(end)) => {
2540 let start = start.get_property().copied().unwrap_or_default();
2541 let end = end.get_property().copied().unwrap_or_default();
2542 CssProperty::MarginBottom(CssPropertyValue::Exact(start.interpolate(&end, t)))
2543 }
2544 (CssProperty::BorderTopLeftRadius(start), CssProperty::BorderTopLeftRadius(end)) => {
2545 let start = start.get_property().copied().unwrap_or_default();
2546 let end = end.get_property().copied().unwrap_or_default();
2547 CssProperty::BorderTopLeftRadius(CssPropertyValue::Exact(
2548 start.interpolate(&end, t),
2549 ))
2550 }
2551 (CssProperty::BorderTopRightRadius(start), CssProperty::BorderTopRightRadius(end)) => {
2552 let start = start.get_property().copied().unwrap_or_default();
2553 let end = end.get_property().copied().unwrap_or_default();
2554 CssProperty::BorderTopRightRadius(CssPropertyValue::Exact(
2555 start.interpolate(&end, t),
2556 ))
2557 }
2558 (
2559 CssProperty::BorderBottomLeftRadius(start),
2560 CssProperty::BorderBottomLeftRadius(end),
2561 ) => {
2562 let start = start.get_property().copied().unwrap_or_default();
2563 let end = end.get_property().copied().unwrap_or_default();
2564 CssProperty::BorderBottomLeftRadius(CssPropertyValue::Exact(
2565 start.interpolate(&end, t),
2566 ))
2567 }
2568 (
2569 CssProperty::BorderBottomRightRadius(start),
2570 CssProperty::BorderBottomRightRadius(end),
2571 ) => {
2572 let start = start.get_property().copied().unwrap_or_default();
2573 let end = end.get_property().copied().unwrap_or_default();
2574 CssProperty::BorderBottomRightRadius(CssPropertyValue::Exact(
2575 start.interpolate(&end, t),
2576 ))
2577 }
2578 (CssProperty::BorderTopColor(start), CssProperty::BorderTopColor(end)) => {
2579 let start = start.get_property().copied().unwrap_or_default();
2580 let end = end.get_property().copied().unwrap_or_default();
2581 CssProperty::BorderTopColor(CssPropertyValue::Exact(start.interpolate(&end, t)))
2582 }
2583 (CssProperty::BorderRightColor(start), CssProperty::BorderRightColor(end)) => {
2584 let start = start.get_property().copied().unwrap_or_default();
2585 let end = end.get_property().copied().unwrap_or_default();
2586 CssProperty::BorderRightColor(CssPropertyValue::Exact(start.interpolate(&end, t)))
2587 }
2588 (CssProperty::BorderLeftColor(start), CssProperty::BorderLeftColor(end)) => {
2589 let start = start.get_property().copied().unwrap_or_default();
2590 let end = end.get_property().copied().unwrap_or_default();
2591 CssProperty::BorderLeftColor(CssPropertyValue::Exact(start.interpolate(&end, t)))
2592 }
2593 (CssProperty::BorderBottomColor(start), CssProperty::BorderBottomColor(end)) => {
2594 let start = start.get_property().copied().unwrap_or_default();
2595 let end = end.get_property().copied().unwrap_or_default();
2596 CssProperty::BorderBottomColor(CssPropertyValue::Exact(start.interpolate(&end, t)))
2597 }
2598 (CssProperty::BorderTopWidth(start), CssProperty::BorderTopWidth(end)) => {
2599 let start = start.get_property().copied().unwrap_or_default();
2600 let end = end.get_property().copied().unwrap_or_default();
2601 CssProperty::BorderTopWidth(CssPropertyValue::Exact(start.interpolate(&end, t)))
2602 }
2603 (CssProperty::BorderRightWidth(start), CssProperty::BorderRightWidth(end)) => {
2604 let start = start.get_property().copied().unwrap_or_default();
2605 let end = end.get_property().copied().unwrap_or_default();
2606 CssProperty::BorderRightWidth(CssPropertyValue::Exact(start.interpolate(&end, t)))
2607 }
2608 (CssProperty::BorderLeftWidth(start), CssProperty::BorderLeftWidth(end)) => {
2609 let start = start.get_property().copied().unwrap_or_default();
2610 let end = end.get_property().copied().unwrap_or_default();
2611 CssProperty::BorderLeftWidth(CssPropertyValue::Exact(start.interpolate(&end, t)))
2612 }
2613 (CssProperty::BorderBottomWidth(start), CssProperty::BorderBottomWidth(end)) => {
2614 let start = start.get_property().copied().unwrap_or_default();
2615 let end = end.get_property().copied().unwrap_or_default();
2616 CssProperty::BorderBottomWidth(CssPropertyValue::Exact(start.interpolate(&end, t)))
2617 }
2618 (CssProperty::Opacity(start), CssProperty::Opacity(end)) => {
2619 let start = start.get_property().copied().unwrap_or_default();
2620 let end = end.get_property().copied().unwrap_or_default();
2621 CssProperty::Opacity(CssPropertyValue::Exact(start.interpolate(&end, t)))
2622 }
2623 (CssProperty::TransformOrigin(start), CssProperty::TransformOrigin(end)) => {
2624 let start = start.get_property().copied().unwrap_or_default();
2625 let end = end.get_property().copied().unwrap_or_default();
2626 CssProperty::TransformOrigin(CssPropertyValue::Exact(start.interpolate(&end, t)))
2627 }
2628 (CssProperty::PerspectiveOrigin(start), CssProperty::PerspectiveOrigin(end)) => {
2629 let start = start.get_property().copied().unwrap_or_default();
2630 let end = end.get_property().copied().unwrap_or_default();
2631 CssProperty::PerspectiveOrigin(CssPropertyValue::Exact(start.interpolate(&end, t)))
2632 }
2633 (_, _) => {
2649 if t > 0.5 {
2651 other.clone()
2652 } else {
2653 self.clone()
2654 }
2655 }
2656 }
2657 }
2658}
2659
2660impl_vec!(CssProperty, CssPropertyVec, CssPropertyVecDestructor);
2661impl_vec_debug!(CssProperty, CssPropertyVec);
2662impl_vec_partialord!(CssProperty, CssPropertyVec);
2663impl_vec_ord!(CssProperty, CssPropertyVec);
2664impl_vec_clone!(CssProperty, CssPropertyVec, CssPropertyVecDestructor);
2665impl_vec_partialeq!(CssProperty, CssPropertyVec);
2666impl_vec_eq!(CssProperty, CssPropertyVec);
2667impl_vec_hash!(CssProperty, CssPropertyVec);
2668
2669macro_rules! css_property_from_type {
2670 ($prop_type:expr, $content_type:ident) => {{
2671 match $prop_type {
2672 CssPropertyType::TextColor => CssProperty::TextColor(CssPropertyValue::$content_type),
2673 CssPropertyType::FontSize => CssProperty::FontSize(CssPropertyValue::$content_type),
2674 CssPropertyType::FontFamily => CssProperty::FontFamily(CssPropertyValue::$content_type),
2675 CssPropertyType::TextAlign => CssProperty::TextAlign(CssPropertyValue::$content_type),
2676 CssPropertyType::LetterSpacing => {
2677 CssProperty::LetterSpacing(CssPropertyValue::$content_type)
2678 }
2679 CssPropertyType::LineHeight => CssProperty::LineHeight(CssPropertyValue::$content_type),
2680 CssPropertyType::WordSpacing => {
2681 CssProperty::WordSpacing(CssPropertyValue::$content_type)
2682 }
2683 CssPropertyType::TabWidth => CssProperty::TabWidth(CssPropertyValue::$content_type),
2684 CssPropertyType::Cursor => CssProperty::Cursor(CssPropertyValue::$content_type),
2685 CssPropertyType::Display => CssProperty::Display(CssPropertyValue::$content_type),
2686 CssPropertyType::Float => CssProperty::Float(CssPropertyValue::$content_type),
2687 CssPropertyType::BoxSizing => CssProperty::BoxSizing(CssPropertyValue::$content_type),
2688 CssPropertyType::Width => CssProperty::Width(CssPropertyValue::$content_type),
2689 CssPropertyType::Height => CssProperty::Height(CssPropertyValue::$content_type),
2690 CssPropertyType::MinWidth => CssProperty::MinWidth(CssPropertyValue::$content_type),
2691 CssPropertyType::MinHeight => CssProperty::MinHeight(CssPropertyValue::$content_type),
2692 CssPropertyType::MaxWidth => CssProperty::MaxWidth(CssPropertyValue::$content_type),
2693 CssPropertyType::MaxHeight => CssProperty::MaxHeight(CssPropertyValue::$content_type),
2694 CssPropertyType::Position => CssProperty::Position(CssPropertyValue::$content_type),
2695 CssPropertyType::Top => CssProperty::Top(CssPropertyValue::$content_type),
2696 CssPropertyType::Right => CssProperty::Right(CssPropertyValue::$content_type),
2697 CssPropertyType::Left => CssProperty::Left(CssPropertyValue::$content_type),
2698 CssPropertyType::Bottom => CssProperty::Bottom(CssPropertyValue::$content_type),
2699 CssPropertyType::FlexWrap => CssProperty::FlexWrap(CssPropertyValue::$content_type),
2700 CssPropertyType::FlexDirection => {
2701 CssProperty::FlexDirection(CssPropertyValue::$content_type)
2702 }
2703 CssPropertyType::FlexGrow => CssProperty::FlexGrow(CssPropertyValue::$content_type),
2704 CssPropertyType::FlexShrink => CssProperty::FlexShrink(CssPropertyValue::$content_type),
2705 CssPropertyType::JustifyContent => {
2706 CssProperty::JustifyContent(CssPropertyValue::$content_type)
2707 }
2708 CssPropertyType::AlignItems => CssProperty::AlignItems(CssPropertyValue::$content_type),
2709 CssPropertyType::AlignContent => {
2710 CssProperty::AlignContent(CssPropertyValue::$content_type)
2711 }
2712 CssPropertyType::OverflowX => CssProperty::OverflowX(CssPropertyValue::$content_type),
2713 CssPropertyType::OverflowY => CssProperty::OverflowY(CssPropertyValue::$content_type),
2714 CssPropertyType::PaddingTop => CssProperty::PaddingTop(CssPropertyValue::$content_type),
2715 CssPropertyType::PaddingLeft => {
2716 CssProperty::PaddingLeft(CssPropertyValue::$content_type)
2717 }
2718 CssPropertyType::PaddingRight => {
2719 CssProperty::PaddingRight(CssPropertyValue::$content_type)
2720 }
2721 CssPropertyType::PaddingBottom => {
2722 CssProperty::PaddingBottom(CssPropertyValue::$content_type)
2723 }
2724 CssPropertyType::MarginTop => CssProperty::MarginTop(CssPropertyValue::$content_type),
2725 CssPropertyType::MarginLeft => CssProperty::MarginLeft(CssPropertyValue::$content_type),
2726 CssPropertyType::MarginRight => {
2727 CssProperty::MarginRight(CssPropertyValue::$content_type)
2728 }
2729 CssPropertyType::MarginBottom => {
2730 CssProperty::MarginBottom(CssPropertyValue::$content_type)
2731 }
2732 CssPropertyType::BackgroundContent => {
2733 CssProperty::BackgroundContent(CssPropertyValue::$content_type)
2734 }
2735 CssPropertyType::BackgroundPosition => {
2736 CssProperty::BackgroundPosition(CssPropertyValue::$content_type)
2737 }
2738 CssPropertyType::BackgroundSize => {
2739 CssProperty::BackgroundSize(CssPropertyValue::$content_type)
2740 }
2741 CssPropertyType::BackgroundRepeat => {
2742 CssProperty::BackgroundRepeat(CssPropertyValue::$content_type)
2743 }
2744 CssPropertyType::BorderTopLeftRadius => {
2745 CssProperty::BorderTopLeftRadius(CssPropertyValue::$content_type)
2746 }
2747 CssPropertyType::BorderTopRightRadius => {
2748 CssProperty::BorderTopRightRadius(CssPropertyValue::$content_type)
2749 }
2750 CssPropertyType::BorderBottomLeftRadius => {
2751 CssProperty::BorderBottomLeftRadius(CssPropertyValue::$content_type)
2752 }
2753 CssPropertyType::BorderBottomRightRadius => {
2754 CssProperty::BorderBottomRightRadius(CssPropertyValue::$content_type)
2755 }
2756 CssPropertyType::BorderTopColor => {
2757 CssProperty::BorderTopColor(CssPropertyValue::$content_type)
2758 }
2759 CssPropertyType::BorderRightColor => {
2760 CssProperty::BorderRightColor(CssPropertyValue::$content_type)
2761 }
2762 CssPropertyType::BorderLeftColor => {
2763 CssProperty::BorderLeftColor(CssPropertyValue::$content_type)
2764 }
2765 CssPropertyType::BorderBottomColor => {
2766 CssProperty::BorderBottomColor(CssPropertyValue::$content_type)
2767 }
2768 CssPropertyType::BorderTopStyle => {
2769 CssProperty::BorderTopStyle(CssPropertyValue::$content_type)
2770 }
2771 CssPropertyType::BorderRightStyle => {
2772 CssProperty::BorderRightStyle(CssPropertyValue::$content_type)
2773 }
2774 CssPropertyType::BorderLeftStyle => {
2775 CssProperty::BorderLeftStyle(CssPropertyValue::$content_type)
2776 }
2777 CssPropertyType::BorderBottomStyle => {
2778 CssProperty::BorderBottomStyle(CssPropertyValue::$content_type)
2779 }
2780 CssPropertyType::BorderTopWidth => {
2781 CssProperty::BorderTopWidth(CssPropertyValue::$content_type)
2782 }
2783 CssPropertyType::BorderRightWidth => {
2784 CssProperty::BorderRightWidth(CssPropertyValue::$content_type)
2785 }
2786 CssPropertyType::BorderLeftWidth => {
2787 CssProperty::BorderLeftWidth(CssPropertyValue::$content_type)
2788 }
2789 CssPropertyType::BorderBottomWidth => {
2790 CssProperty::BorderBottomWidth(CssPropertyValue::$content_type)
2791 }
2792 CssPropertyType::BoxShadowLeft => {
2793 CssProperty::BoxShadowLeft(CssPropertyValue::$content_type)
2794 }
2795 CssPropertyType::BoxShadowRight => {
2796 CssProperty::BoxShadowRight(CssPropertyValue::$content_type)
2797 }
2798 CssPropertyType::BoxShadowTop => {
2799 CssProperty::BoxShadowTop(CssPropertyValue::$content_type)
2800 }
2801 CssPropertyType::BoxShadowBottom => {
2802 CssProperty::BoxShadowBottom(CssPropertyValue::$content_type)
2803 }
2804 CssPropertyType::ScrollbarStyle => {
2805 CssProperty::ScrollbarStyle(CssPropertyValue::$content_type)
2806 }
2807 CssPropertyType::Opacity => CssProperty::Opacity(CssPropertyValue::$content_type),
2808 CssPropertyType::Transform => CssProperty::Transform(CssPropertyValue::$content_type),
2809 CssPropertyType::PerspectiveOrigin => {
2810 CssProperty::PerspectiveOrigin(CssPropertyValue::$content_type)
2811 }
2812 CssPropertyType::TransformOrigin => {
2813 CssProperty::TransformOrigin(CssPropertyValue::$content_type)
2814 }
2815 CssPropertyType::BackfaceVisibility => {
2816 CssProperty::BackfaceVisibility(CssPropertyValue::$content_type)
2817 }
2818 CssPropertyType::MixBlendMode => {
2819 CssProperty::MixBlendMode(CssPropertyValue::$content_type)
2820 }
2821 CssPropertyType::Filter => CssProperty::Filter(CssPropertyValue::$content_type),
2822 CssPropertyType::BackdropFilter => {
2823 CssProperty::BackdropFilter(CssPropertyValue::$content_type)
2824 }
2825 CssPropertyType::TextShadow => CssProperty::TextShadow(CssPropertyValue::$content_type),
2826 }
2827 }};
2828}
2829
2830impl CssProperty {
2831 pub const fn get_type(&self) -> CssPropertyType {
2833 match &self {
2834 CssProperty::TextColor(_) => CssPropertyType::TextColor,
2835 CssProperty::FontSize(_) => CssPropertyType::FontSize,
2836 CssProperty::FontFamily(_) => CssPropertyType::FontFamily,
2837 CssProperty::TextAlign(_) => CssPropertyType::TextAlign,
2838 CssProperty::LetterSpacing(_) => CssPropertyType::LetterSpacing,
2839 CssProperty::LineHeight(_) => CssPropertyType::LineHeight,
2840 CssProperty::WordSpacing(_) => CssPropertyType::WordSpacing,
2841 CssProperty::TabWidth(_) => CssPropertyType::TabWidth,
2842 CssProperty::Cursor(_) => CssPropertyType::Cursor,
2843 CssProperty::Display(_) => CssPropertyType::Display,
2844 CssProperty::Float(_) => CssPropertyType::Float,
2845 CssProperty::BoxSizing(_) => CssPropertyType::BoxSizing,
2846 CssProperty::Width(_) => CssPropertyType::Width,
2847 CssProperty::Height(_) => CssPropertyType::Height,
2848 CssProperty::MinWidth(_) => CssPropertyType::MinWidth,
2849 CssProperty::MinHeight(_) => CssPropertyType::MinHeight,
2850 CssProperty::MaxWidth(_) => CssPropertyType::MaxWidth,
2851 CssProperty::MaxHeight(_) => CssPropertyType::MaxHeight,
2852 CssProperty::Position(_) => CssPropertyType::Position,
2853 CssProperty::Top(_) => CssPropertyType::Top,
2854 CssProperty::Right(_) => CssPropertyType::Right,
2855 CssProperty::Left(_) => CssPropertyType::Left,
2856 CssProperty::Bottom(_) => CssPropertyType::Bottom,
2857 CssProperty::FlexWrap(_) => CssPropertyType::FlexWrap,
2858 CssProperty::FlexDirection(_) => CssPropertyType::FlexDirection,
2859 CssProperty::FlexGrow(_) => CssPropertyType::FlexGrow,
2860 CssProperty::FlexShrink(_) => CssPropertyType::FlexShrink,
2861 CssProperty::JustifyContent(_) => CssPropertyType::JustifyContent,
2862 CssProperty::AlignItems(_) => CssPropertyType::AlignItems,
2863 CssProperty::AlignContent(_) => CssPropertyType::AlignContent,
2864 CssProperty::BackgroundContent(_) => CssPropertyType::BackgroundContent,
2865 CssProperty::BackgroundPosition(_) => CssPropertyType::BackgroundPosition,
2866 CssProperty::BackgroundSize(_) => CssPropertyType::BackgroundSize,
2867 CssProperty::BackgroundRepeat(_) => CssPropertyType::BackgroundRepeat,
2868 CssProperty::OverflowX(_) => CssPropertyType::OverflowX,
2869 CssProperty::OverflowY(_) => CssPropertyType::OverflowY,
2870 CssProperty::PaddingTop(_) => CssPropertyType::PaddingTop,
2871 CssProperty::PaddingLeft(_) => CssPropertyType::PaddingLeft,
2872 CssProperty::PaddingRight(_) => CssPropertyType::PaddingRight,
2873 CssProperty::PaddingBottom(_) => CssPropertyType::PaddingBottom,
2874 CssProperty::MarginTop(_) => CssPropertyType::MarginTop,
2875 CssProperty::MarginLeft(_) => CssPropertyType::MarginLeft,
2876 CssProperty::MarginRight(_) => CssPropertyType::MarginRight,
2877 CssProperty::MarginBottom(_) => CssPropertyType::MarginBottom,
2878 CssProperty::BorderTopLeftRadius(_) => CssPropertyType::BorderTopLeftRadius,
2879 CssProperty::BorderTopRightRadius(_) => CssPropertyType::BorderTopRightRadius,
2880 CssProperty::BorderBottomLeftRadius(_) => CssPropertyType::BorderBottomLeftRadius,
2881 CssProperty::BorderBottomRightRadius(_) => CssPropertyType::BorderBottomRightRadius,
2882 CssProperty::BorderTopColor(_) => CssPropertyType::BorderTopColor,
2883 CssProperty::BorderRightColor(_) => CssPropertyType::BorderRightColor,
2884 CssProperty::BorderLeftColor(_) => CssPropertyType::BorderLeftColor,
2885 CssProperty::BorderBottomColor(_) => CssPropertyType::BorderBottomColor,
2886 CssProperty::BorderTopStyle(_) => CssPropertyType::BorderTopStyle,
2887 CssProperty::BorderRightStyle(_) => CssPropertyType::BorderRightStyle,
2888 CssProperty::BorderLeftStyle(_) => CssPropertyType::BorderLeftStyle,
2889 CssProperty::BorderBottomStyle(_) => CssPropertyType::BorderBottomStyle,
2890 CssProperty::BorderTopWidth(_) => CssPropertyType::BorderTopWidth,
2891 CssProperty::BorderRightWidth(_) => CssPropertyType::BorderRightWidth,
2892 CssProperty::BorderLeftWidth(_) => CssPropertyType::BorderLeftWidth,
2893 CssProperty::BorderBottomWidth(_) => CssPropertyType::BorderBottomWidth,
2894 CssProperty::BoxShadowLeft(_) => CssPropertyType::BoxShadowLeft,
2895 CssProperty::BoxShadowRight(_) => CssPropertyType::BoxShadowRight,
2896 CssProperty::BoxShadowTop(_) => CssPropertyType::BoxShadowTop,
2897 CssProperty::BoxShadowBottom(_) => CssPropertyType::BoxShadowBottom,
2898 CssProperty::ScrollbarStyle(_) => CssPropertyType::ScrollbarStyle,
2899 CssProperty::Opacity(_) => CssPropertyType::Opacity,
2900 CssProperty::Transform(_) => CssPropertyType::Transform,
2901 CssProperty::PerspectiveOrigin(_) => CssPropertyType::PerspectiveOrigin,
2902 CssProperty::TransformOrigin(_) => CssPropertyType::TransformOrigin,
2903 CssProperty::BackfaceVisibility(_) => CssPropertyType::BackfaceVisibility,
2904 CssProperty::MixBlendMode(_) => CssPropertyType::MixBlendMode,
2905 CssProperty::Filter(_) => CssPropertyType::Filter,
2906 CssProperty::BackdropFilter(_) => CssPropertyType::BackdropFilter,
2907 CssProperty::TextShadow(_) => CssPropertyType::TextShadow,
2908 }
2909 }
2910
2911 pub const fn none(prop_type: CssPropertyType) -> Self {
2914 css_property_from_type!(prop_type, None)
2915 }
2916 pub const fn auto(prop_type: CssPropertyType) -> Self {
2917 css_property_from_type!(prop_type, Auto)
2918 }
2919 pub const fn initial(prop_type: CssPropertyType) -> Self {
2920 css_property_from_type!(prop_type, Initial)
2921 }
2922 pub const fn inherit(prop_type: CssPropertyType) -> Self {
2923 css_property_from_type!(prop_type, Inherit)
2924 }
2925
2926 pub const fn text_color(input: StyleTextColor) -> Self {
2927 CssProperty::TextColor(CssPropertyValue::Exact(input))
2928 }
2929 pub const fn font_size(input: StyleFontSize) -> Self {
2930 CssProperty::FontSize(CssPropertyValue::Exact(input))
2931 }
2932 pub const fn font_family(input: StyleFontFamilyVec) -> Self {
2933 CssProperty::FontFamily(CssPropertyValue::Exact(input))
2934 }
2935 pub const fn text_align(input: StyleTextAlign) -> Self {
2936 CssProperty::TextAlign(CssPropertyValue::Exact(input))
2937 }
2938 pub const fn letter_spacing(input: StyleLetterSpacing) -> Self {
2939 CssProperty::LetterSpacing(CssPropertyValue::Exact(input))
2940 }
2941 pub const fn line_height(input: StyleLineHeight) -> Self {
2942 CssProperty::LineHeight(CssPropertyValue::Exact(input))
2943 }
2944 pub const fn word_spacing(input: StyleWordSpacing) -> Self {
2945 CssProperty::WordSpacing(CssPropertyValue::Exact(input))
2946 }
2947 pub const fn tab_width(input: StyleTabWidth) -> Self {
2948 CssProperty::TabWidth(CssPropertyValue::Exact(input))
2949 }
2950 pub const fn cursor(input: StyleCursor) -> Self {
2951 CssProperty::Cursor(CssPropertyValue::Exact(input))
2952 }
2953 pub const fn display(input: LayoutDisplay) -> Self {
2954 CssProperty::Display(CssPropertyValue::Exact(input))
2955 }
2956 pub const fn float(input: LayoutFloat) -> Self {
2957 CssProperty::Float(CssPropertyValue::Exact(input))
2958 }
2959 pub const fn box_sizing(input: LayoutBoxSizing) -> Self {
2960 CssProperty::BoxSizing(CssPropertyValue::Exact(input))
2961 }
2962 pub const fn width(input: LayoutWidth) -> Self {
2963 CssProperty::Width(CssPropertyValue::Exact(input))
2964 }
2965 pub const fn height(input: LayoutHeight) -> Self {
2966 CssProperty::Height(CssPropertyValue::Exact(input))
2967 }
2968 pub const fn min_width(input: LayoutMinWidth) -> Self {
2969 CssProperty::MinWidth(CssPropertyValue::Exact(input))
2970 }
2971 pub const fn min_height(input: LayoutMinHeight) -> Self {
2972 CssProperty::MinHeight(CssPropertyValue::Exact(input))
2973 }
2974 pub const fn max_width(input: LayoutMaxWidth) -> Self {
2975 CssProperty::MaxWidth(CssPropertyValue::Exact(input))
2976 }
2977 pub const fn max_height(input: LayoutMaxHeight) -> Self {
2978 CssProperty::MaxHeight(CssPropertyValue::Exact(input))
2979 }
2980 pub const fn position(input: LayoutPosition) -> Self {
2981 CssProperty::Position(CssPropertyValue::Exact(input))
2982 }
2983 pub const fn top(input: LayoutTop) -> Self {
2984 CssProperty::Top(CssPropertyValue::Exact(input))
2985 }
2986 pub const fn right(input: LayoutRight) -> Self {
2987 CssProperty::Right(CssPropertyValue::Exact(input))
2988 }
2989 pub const fn left(input: LayoutLeft) -> Self {
2990 CssProperty::Left(CssPropertyValue::Exact(input))
2991 }
2992 pub const fn bottom(input: LayoutBottom) -> Self {
2993 CssProperty::Bottom(CssPropertyValue::Exact(input))
2994 }
2995 pub const fn flex_wrap(input: LayoutFlexWrap) -> Self {
2996 CssProperty::FlexWrap(CssPropertyValue::Exact(input))
2997 }
2998 pub const fn flex_direction(input: LayoutFlexDirection) -> Self {
2999 CssProperty::FlexDirection(CssPropertyValue::Exact(input))
3000 }
3001 pub const fn flex_grow(input: LayoutFlexGrow) -> Self {
3002 CssProperty::FlexGrow(CssPropertyValue::Exact(input))
3003 }
3004 pub const fn flex_shrink(input: LayoutFlexShrink) -> Self {
3005 CssProperty::FlexShrink(CssPropertyValue::Exact(input))
3006 }
3007 pub const fn justify_content(input: LayoutJustifyContent) -> Self {
3008 CssProperty::JustifyContent(CssPropertyValue::Exact(input))
3009 }
3010 pub const fn align_items(input: LayoutAlignItems) -> Self {
3011 CssProperty::AlignItems(CssPropertyValue::Exact(input))
3012 }
3013 pub const fn align_content(input: LayoutAlignContent) -> Self {
3014 CssProperty::AlignContent(CssPropertyValue::Exact(input))
3015 }
3016 pub const fn background_content(input: StyleBackgroundContentVec) -> Self {
3017 CssProperty::BackgroundContent(CssPropertyValue::Exact(input))
3018 }
3019 pub const fn background_position(input: StyleBackgroundPositionVec) -> Self {
3020 CssProperty::BackgroundPosition(CssPropertyValue::Exact(input))
3021 }
3022 pub const fn background_size(input: StyleBackgroundSizeVec) -> Self {
3023 CssProperty::BackgroundSize(CssPropertyValue::Exact(input))
3024 }
3025 pub const fn background_repeat(input: StyleBackgroundRepeatVec) -> Self {
3026 CssProperty::BackgroundRepeat(CssPropertyValue::Exact(input))
3027 }
3028 pub const fn overflow_x(input: LayoutOverflow) -> Self {
3029 CssProperty::OverflowX(CssPropertyValue::Exact(input))
3030 }
3031 pub const fn overflow_y(input: LayoutOverflow) -> Self {
3032 CssProperty::OverflowY(CssPropertyValue::Exact(input))
3033 }
3034 pub const fn padding_top(input: LayoutPaddingTop) -> Self {
3035 CssProperty::PaddingTop(CssPropertyValue::Exact(input))
3036 }
3037 pub const fn padding_left(input: LayoutPaddingLeft) -> Self {
3038 CssProperty::PaddingLeft(CssPropertyValue::Exact(input))
3039 }
3040 pub const fn padding_right(input: LayoutPaddingRight) -> Self {
3041 CssProperty::PaddingRight(CssPropertyValue::Exact(input))
3042 }
3043 pub const fn padding_bottom(input: LayoutPaddingBottom) -> Self {
3044 CssProperty::PaddingBottom(CssPropertyValue::Exact(input))
3045 }
3046 pub const fn margin_top(input: LayoutMarginTop) -> Self {
3047 CssProperty::MarginTop(CssPropertyValue::Exact(input))
3048 }
3049 pub const fn margin_left(input: LayoutMarginLeft) -> Self {
3050 CssProperty::MarginLeft(CssPropertyValue::Exact(input))
3051 }
3052 pub const fn margin_right(input: LayoutMarginRight) -> Self {
3053 CssProperty::MarginRight(CssPropertyValue::Exact(input))
3054 }
3055 pub const fn margin_bottom(input: LayoutMarginBottom) -> Self {
3056 CssProperty::MarginBottom(CssPropertyValue::Exact(input))
3057 }
3058 pub const fn border_top_left_radius(input: StyleBorderTopLeftRadius) -> Self {
3059 CssProperty::BorderTopLeftRadius(CssPropertyValue::Exact(input))
3060 }
3061 pub const fn border_top_right_radius(input: StyleBorderTopRightRadius) -> Self {
3062 CssProperty::BorderTopRightRadius(CssPropertyValue::Exact(input))
3063 }
3064 pub const fn border_bottom_left_radius(input: StyleBorderBottomLeftRadius) -> Self {
3065 CssProperty::BorderBottomLeftRadius(CssPropertyValue::Exact(input))
3066 }
3067 pub const fn border_bottom_right_radius(input: StyleBorderBottomRightRadius) -> Self {
3068 CssProperty::BorderBottomRightRadius(CssPropertyValue::Exact(input))
3069 }
3070 pub const fn border_top_color(input: StyleBorderTopColor) -> Self {
3071 CssProperty::BorderTopColor(CssPropertyValue::Exact(input))
3072 }
3073 pub const fn border_right_color(input: StyleBorderRightColor) -> Self {
3074 CssProperty::BorderRightColor(CssPropertyValue::Exact(input))
3075 }
3076 pub const fn border_left_color(input: StyleBorderLeftColor) -> Self {
3077 CssProperty::BorderLeftColor(CssPropertyValue::Exact(input))
3078 }
3079 pub const fn border_bottom_color(input: StyleBorderBottomColor) -> Self {
3080 CssProperty::BorderBottomColor(CssPropertyValue::Exact(input))
3081 }
3082 pub const fn border_top_style(input: StyleBorderTopStyle) -> Self {
3083 CssProperty::BorderTopStyle(CssPropertyValue::Exact(input))
3084 }
3085 pub const fn border_right_style(input: StyleBorderRightStyle) -> Self {
3086 CssProperty::BorderRightStyle(CssPropertyValue::Exact(input))
3087 }
3088 pub const fn border_left_style(input: StyleBorderLeftStyle) -> Self {
3089 CssProperty::BorderLeftStyle(CssPropertyValue::Exact(input))
3090 }
3091 pub const fn border_bottom_style(input: StyleBorderBottomStyle) -> Self {
3092 CssProperty::BorderBottomStyle(CssPropertyValue::Exact(input))
3093 }
3094 pub const fn border_top_width(input: LayoutBorderTopWidth) -> Self {
3095 CssProperty::BorderTopWidth(CssPropertyValue::Exact(input))
3096 }
3097 pub const fn border_right_width(input: LayoutBorderRightWidth) -> Self {
3098 CssProperty::BorderRightWidth(CssPropertyValue::Exact(input))
3099 }
3100 pub const fn border_left_width(input: LayoutBorderLeftWidth) -> Self {
3101 CssProperty::BorderLeftWidth(CssPropertyValue::Exact(input))
3102 }
3103 pub const fn border_bottom_width(input: LayoutBorderBottomWidth) -> Self {
3104 CssProperty::BorderBottomWidth(CssPropertyValue::Exact(input))
3105 }
3106 pub const fn box_shadow_left(input: StyleBoxShadow) -> Self {
3107 CssProperty::BoxShadowLeft(CssPropertyValue::Exact(input))
3108 }
3109 pub const fn box_shadow_right(input: StyleBoxShadow) -> Self {
3110 CssProperty::BoxShadowRight(CssPropertyValue::Exact(input))
3111 }
3112 pub const fn box_shadow_top(input: StyleBoxShadow) -> Self {
3113 CssProperty::BoxShadowTop(CssPropertyValue::Exact(input))
3114 }
3115 pub const fn box_shadow_bottom(input: StyleBoxShadow) -> Self {
3116 CssProperty::BoxShadowBottom(CssPropertyValue::Exact(input))
3117 }
3118 pub const fn opacity(input: StyleOpacity) -> Self {
3119 CssProperty::Opacity(CssPropertyValue::Exact(input))
3120 }
3121 pub const fn transform(input: StyleTransformVec) -> Self {
3122 CssProperty::Transform(CssPropertyValue::Exact(input))
3123 }
3124 pub const fn transform_origin(input: StyleTransformOrigin) -> Self {
3125 CssProperty::TransformOrigin(CssPropertyValue::Exact(input))
3126 }
3127 pub const fn perspective_origin(input: StylePerspectiveOrigin) -> Self {
3128 CssProperty::PerspectiveOrigin(CssPropertyValue::Exact(input))
3129 }
3130 pub const fn backface_visiblity(input: StyleBackfaceVisibility) -> Self {
3131 CssProperty::BackfaceVisibility(CssPropertyValue::Exact(input))
3132 }
3133
3134 pub const fn as_background_content(&self) -> Option<&StyleBackgroundContentVecValue> {
3137 match self {
3138 CssProperty::BackgroundContent(f) => Some(f),
3139 _ => None,
3140 }
3141 }
3142 pub const fn as_background_position(&self) -> Option<&StyleBackgroundPositionVecValue> {
3143 match self {
3144 CssProperty::BackgroundPosition(f) => Some(f),
3145 _ => None,
3146 }
3147 }
3148 pub const fn as_background_size(&self) -> Option<&StyleBackgroundSizeVecValue> {
3149 match self {
3150 CssProperty::BackgroundSize(f) => Some(f),
3151 _ => None,
3152 }
3153 }
3154 pub const fn as_background_repeat(&self) -> Option<&StyleBackgroundRepeatVecValue> {
3155 match self {
3156 CssProperty::BackgroundRepeat(f) => Some(f),
3157 _ => None,
3158 }
3159 }
3160 pub const fn as_font_size(&self) -> Option<&StyleFontSizeValue> {
3161 match self {
3162 CssProperty::FontSize(f) => Some(f),
3163 _ => None,
3164 }
3165 }
3166 pub const fn as_font_family(&self) -> Option<&StyleFontFamilyVecValue> {
3167 match self {
3168 CssProperty::FontFamily(f) => Some(f),
3169 _ => None,
3170 }
3171 }
3172 pub const fn as_text_color(&self) -> Option<&StyleTextColorValue> {
3173 match self {
3174 CssProperty::TextColor(f) => Some(f),
3175 _ => None,
3176 }
3177 }
3178 pub const fn as_text_align(&self) -> Option<&StyleTextAlignValue> {
3179 match self {
3180 CssProperty::TextAlign(f) => Some(f),
3181 _ => None,
3182 }
3183 }
3184 pub const fn as_line_height(&self) -> Option<&StyleLineHeightValue> {
3185 match self {
3186 CssProperty::LineHeight(f) => Some(f),
3187 _ => None,
3188 }
3189 }
3190 pub const fn as_letter_spacing(&self) -> Option<&StyleLetterSpacingValue> {
3191 match self {
3192 CssProperty::LetterSpacing(f) => Some(f),
3193 _ => None,
3194 }
3195 }
3196 pub const fn as_word_spacing(&self) -> Option<&StyleWordSpacingValue> {
3197 match self {
3198 CssProperty::WordSpacing(f) => Some(f),
3199 _ => None,
3200 }
3201 }
3202 pub const fn as_tab_width(&self) -> Option<&StyleTabWidthValue> {
3203 match self {
3204 CssProperty::TabWidth(f) => Some(f),
3205 _ => None,
3206 }
3207 }
3208 pub const fn as_cursor(&self) -> Option<&StyleCursorValue> {
3209 match self {
3210 CssProperty::Cursor(f) => Some(f),
3211 _ => None,
3212 }
3213 }
3214 pub const fn as_box_shadow_left(&self) -> Option<&StyleBoxShadowValue> {
3215 match self {
3216 CssProperty::BoxShadowLeft(f) => Some(f),
3217 _ => None,
3218 }
3219 }
3220 pub const fn as_box_shadow_right(&self) -> Option<&StyleBoxShadowValue> {
3221 match self {
3222 CssProperty::BoxShadowRight(f) => Some(f),
3223 _ => None,
3224 }
3225 }
3226 pub const fn as_box_shadow_top(&self) -> Option<&StyleBoxShadowValue> {
3227 match self {
3228 CssProperty::BoxShadowTop(f) => Some(f),
3229 _ => None,
3230 }
3231 }
3232 pub const fn as_box_shadow_bottom(&self) -> Option<&StyleBoxShadowValue> {
3233 match self {
3234 CssProperty::BoxShadowBottom(f) => Some(f),
3235 _ => None,
3236 }
3237 }
3238 pub const fn as_border_top_color(&self) -> Option<&StyleBorderTopColorValue> {
3239 match self {
3240 CssProperty::BorderTopColor(f) => Some(f),
3241 _ => None,
3242 }
3243 }
3244 pub const fn as_border_left_color(&self) -> Option<&StyleBorderLeftColorValue> {
3245 match self {
3246 CssProperty::BorderLeftColor(f) => Some(f),
3247 _ => None,
3248 }
3249 }
3250 pub const fn as_border_right_color(&self) -> Option<&StyleBorderRightColorValue> {
3251 match self {
3252 CssProperty::BorderRightColor(f) => Some(f),
3253 _ => None,
3254 }
3255 }
3256 pub const fn as_border_bottom_color(&self) -> Option<&StyleBorderBottomColorValue> {
3257 match self {
3258 CssProperty::BorderBottomColor(f) => Some(f),
3259 _ => None,
3260 }
3261 }
3262 pub const fn as_border_top_style(&self) -> Option<&StyleBorderTopStyleValue> {
3263 match self {
3264 CssProperty::BorderTopStyle(f) => Some(f),
3265 _ => None,
3266 }
3267 }
3268 pub const fn as_border_left_style(&self) -> Option<&StyleBorderLeftStyleValue> {
3269 match self {
3270 CssProperty::BorderLeftStyle(f) => Some(f),
3271 _ => None,
3272 }
3273 }
3274 pub const fn as_border_right_style(&self) -> Option<&StyleBorderRightStyleValue> {
3275 match self {
3276 CssProperty::BorderRightStyle(f) => Some(f),
3277 _ => None,
3278 }
3279 }
3280 pub const fn as_border_bottom_style(&self) -> Option<&StyleBorderBottomStyleValue> {
3281 match self {
3282 CssProperty::BorderBottomStyle(f) => Some(f),
3283 _ => None,
3284 }
3285 }
3286 pub const fn as_border_top_left_radius(&self) -> Option<&StyleBorderTopLeftRadiusValue> {
3287 match self {
3288 CssProperty::BorderTopLeftRadius(f) => Some(f),
3289 _ => None,
3290 }
3291 }
3292 pub const fn as_border_top_right_radius(&self) -> Option<&StyleBorderTopRightRadiusValue> {
3293 match self {
3294 CssProperty::BorderTopRightRadius(f) => Some(f),
3295 _ => None,
3296 }
3297 }
3298 pub const fn as_border_bottom_left_radius(&self) -> Option<&StyleBorderBottomLeftRadiusValue> {
3299 match self {
3300 CssProperty::BorderBottomLeftRadius(f) => Some(f),
3301 _ => None,
3302 }
3303 }
3304 pub const fn as_border_bottom_right_radius(
3305 &self,
3306 ) -> Option<&StyleBorderBottomRightRadiusValue> {
3307 match self {
3308 CssProperty::BorderBottomRightRadius(f) => Some(f),
3309 _ => None,
3310 }
3311 }
3312 pub const fn as_opacity(&self) -> Option<&StyleOpacityValue> {
3313 match self {
3314 CssProperty::Opacity(f) => Some(f),
3315 _ => None,
3316 }
3317 }
3318 pub const fn as_transform(&self) -> Option<&StyleTransformVecValue> {
3319 match self {
3320 CssProperty::Transform(f) => Some(f),
3321 _ => None,
3322 }
3323 }
3324 pub const fn as_transform_origin(&self) -> Option<&StyleTransformOriginValue> {
3325 match self {
3326 CssProperty::TransformOrigin(f) => Some(f),
3327 _ => None,
3328 }
3329 }
3330 pub const fn as_perspective_origin(&self) -> Option<&StylePerspectiveOriginValue> {
3331 match self {
3332 CssProperty::PerspectiveOrigin(f) => Some(f),
3333 _ => None,
3334 }
3335 }
3336 pub const fn as_backface_visibility(&self) -> Option<&StyleBackfaceVisibilityValue> {
3337 match self {
3338 CssProperty::BackfaceVisibility(f) => Some(f),
3339 _ => None,
3340 }
3341 }
3342 pub const fn as_mix_blend_mode(&self) -> Option<&StyleMixBlendModeValue> {
3343 match self {
3344 CssProperty::MixBlendMode(f) => Some(f),
3345 _ => None,
3346 }
3347 }
3348 pub const fn as_filter(&self) -> Option<&StyleFilterVecValue> {
3349 match self {
3350 CssProperty::Filter(f) => Some(f),
3351 _ => None,
3352 }
3353 }
3354 pub const fn as_backdrop_filter(&self) -> Option<&StyleFilterVecValue> {
3355 match self {
3356 CssProperty::BackdropFilter(f) => Some(f),
3357 _ => None,
3358 }
3359 }
3360 pub const fn as_text_shadow(&self) -> Option<&StyleBoxShadowValue> {
3361 match self {
3362 CssProperty::TextShadow(f) => Some(f),
3363 _ => None,
3364 }
3365 }
3366
3367 pub const fn as_display(&self) -> Option<&LayoutDisplayValue> {
3370 match self {
3371 CssProperty::Display(f) => Some(f),
3372 _ => None,
3373 }
3374 }
3375 pub const fn as_float(&self) -> Option<&LayoutFloatValue> {
3376 match self {
3377 CssProperty::Float(f) => Some(f),
3378 _ => None,
3379 }
3380 }
3381 pub const fn as_box_sizing(&self) -> Option<&LayoutBoxSizingValue> {
3382 match self {
3383 CssProperty::BoxSizing(f) => Some(f),
3384 _ => None,
3385 }
3386 }
3387 pub const fn as_width(&self) -> Option<&LayoutWidthValue> {
3388 match self {
3389 CssProperty::Width(f) => Some(f),
3390 _ => None,
3391 }
3392 }
3393 pub const fn as_height(&self) -> Option<&LayoutHeightValue> {
3394 match self {
3395 CssProperty::Height(f) => Some(f),
3396 _ => None,
3397 }
3398 }
3399 pub const fn as_min_width(&self) -> Option<&LayoutMinWidthValue> {
3400 match self {
3401 CssProperty::MinWidth(f) => Some(f),
3402 _ => None,
3403 }
3404 }
3405 pub const fn as_min_height(&self) -> Option<&LayoutMinHeightValue> {
3406 match self {
3407 CssProperty::MinHeight(f) => Some(f),
3408 _ => None,
3409 }
3410 }
3411 pub const fn as_max_width(&self) -> Option<&LayoutMaxWidthValue> {
3412 match self {
3413 CssProperty::MaxWidth(f) => Some(f),
3414 _ => None,
3415 }
3416 }
3417 pub const fn as_max_height(&self) -> Option<&LayoutMaxHeightValue> {
3418 match self {
3419 CssProperty::MaxHeight(f) => Some(f),
3420 _ => None,
3421 }
3422 }
3423 pub const fn as_position(&self) -> Option<&LayoutPositionValue> {
3424 match self {
3425 CssProperty::Position(f) => Some(f),
3426 _ => None,
3427 }
3428 }
3429 pub const fn as_top(&self) -> Option<&LayoutTopValue> {
3430 match self {
3431 CssProperty::Top(f) => Some(f),
3432 _ => None,
3433 }
3434 }
3435 pub const fn as_bottom(&self) -> Option<&LayoutBottomValue> {
3436 match self {
3437 CssProperty::Bottom(f) => Some(f),
3438 _ => None,
3439 }
3440 }
3441 pub const fn as_right(&self) -> Option<&LayoutRightValue> {
3442 match self {
3443 CssProperty::Right(f) => Some(f),
3444 _ => None,
3445 }
3446 }
3447 pub const fn as_left(&self) -> Option<&LayoutLeftValue> {
3448 match self {
3449 CssProperty::Left(f) => Some(f),
3450 _ => None,
3451 }
3452 }
3453 pub const fn as_padding_top(&self) -> Option<&LayoutPaddingTopValue> {
3454 match self {
3455 CssProperty::PaddingTop(f) => Some(f),
3456 _ => None,
3457 }
3458 }
3459 pub const fn as_padding_bottom(&self) -> Option<&LayoutPaddingBottomValue> {
3460 match self {
3461 CssProperty::PaddingBottom(f) => Some(f),
3462 _ => None,
3463 }
3464 }
3465 pub const fn as_padding_left(&self) -> Option<&LayoutPaddingLeftValue> {
3466 match self {
3467 CssProperty::PaddingLeft(f) => Some(f),
3468 _ => None,
3469 }
3470 }
3471 pub const fn as_padding_right(&self) -> Option<&LayoutPaddingRightValue> {
3472 match self {
3473 CssProperty::PaddingRight(f) => Some(f),
3474 _ => None,
3475 }
3476 }
3477 pub const fn as_margin_top(&self) -> Option<&LayoutMarginTopValue> {
3478 match self {
3479 CssProperty::MarginTop(f) => Some(f),
3480 _ => None,
3481 }
3482 }
3483 pub const fn as_margin_bottom(&self) -> Option<&LayoutMarginBottomValue> {
3484 match self {
3485 CssProperty::MarginBottom(f) => Some(f),
3486 _ => None,
3487 }
3488 }
3489 pub const fn as_margin_left(&self) -> Option<&LayoutMarginLeftValue> {
3490 match self {
3491 CssProperty::MarginLeft(f) => Some(f),
3492 _ => None,
3493 }
3494 }
3495 pub const fn as_margin_right(&self) -> Option<&LayoutMarginRightValue> {
3496 match self {
3497 CssProperty::MarginRight(f) => Some(f),
3498 _ => None,
3499 }
3500 }
3501 pub const fn as_border_top_width(&self) -> Option<&LayoutBorderTopWidthValue> {
3502 match self {
3503 CssProperty::BorderTopWidth(f) => Some(f),
3504 _ => None,
3505 }
3506 }
3507 pub const fn as_border_left_width(&self) -> Option<&LayoutBorderLeftWidthValue> {
3508 match self {
3509 CssProperty::BorderLeftWidth(f) => Some(f),
3510 _ => None,
3511 }
3512 }
3513 pub const fn as_border_right_width(&self) -> Option<&LayoutBorderRightWidthValue> {
3514 match self {
3515 CssProperty::BorderRightWidth(f) => Some(f),
3516 _ => None,
3517 }
3518 }
3519 pub const fn as_border_bottom_width(&self) -> Option<&LayoutBorderBottomWidthValue> {
3520 match self {
3521 CssProperty::BorderBottomWidth(f) => Some(f),
3522 _ => None,
3523 }
3524 }
3525 pub const fn as_overflow_x(&self) -> Option<&LayoutOverflowValue> {
3526 match self {
3527 CssProperty::OverflowX(f) => Some(f),
3528 _ => None,
3529 }
3530 }
3531 pub const fn as_overflow_y(&self) -> Option<&LayoutOverflowValue> {
3532 match self {
3533 CssProperty::OverflowY(f) => Some(f),
3534 _ => None,
3535 }
3536 }
3537 pub const fn as_direction(&self) -> Option<&LayoutFlexDirectionValue> {
3538 match self {
3539 CssProperty::FlexDirection(f) => Some(f),
3540 _ => None,
3541 }
3542 }
3543 pub const fn as_flex_wrap(&self) -> Option<&LayoutFlexWrapValue> {
3544 match self {
3545 CssProperty::FlexWrap(f) => Some(f),
3546 _ => None,
3547 }
3548 }
3549 pub const fn as_flex_grow(&self) -> Option<&LayoutFlexGrowValue> {
3550 match self {
3551 CssProperty::FlexGrow(f) => Some(f),
3552 _ => None,
3553 }
3554 }
3555 pub const fn as_flex_shrink(&self) -> Option<&LayoutFlexShrinkValue> {
3556 match self {
3557 CssProperty::FlexShrink(f) => Some(f),
3558 _ => None,
3559 }
3560 }
3561 pub const fn as_justify_content(&self) -> Option<&LayoutJustifyContentValue> {
3562 match self {
3563 CssProperty::JustifyContent(f) => Some(f),
3564 _ => None,
3565 }
3566 }
3567 pub const fn as_align_items(&self) -> Option<&LayoutAlignItemsValue> {
3568 match self {
3569 CssProperty::AlignItems(f) => Some(f),
3570 _ => None,
3571 }
3572 }
3573 pub const fn as_align_content(&self) -> Option<&LayoutAlignContentValue> {
3574 match self {
3575 CssProperty::AlignContent(f) => Some(f),
3576 _ => None,
3577 }
3578 }
3579}
3580
3581macro_rules! impl_from_css_prop {
3582 ($a:ident, $b:ident:: $enum_type:ident) => {
3583 impl From<$a> for $b {
3584 fn from(e: $a) -> Self {
3585 $b::$enum_type(CssPropertyValue::from(e))
3586 }
3587 }
3588 };
3589}
3590
3591impl_from_css_prop!(StyleTextColor, CssProperty::TextColor);
3592impl_from_css_prop!(StyleFontSize, CssProperty::FontSize);
3593impl_from_css_prop!(StyleFontFamilyVec, CssProperty::FontFamily);
3594impl_from_css_prop!(StyleTextAlign, CssProperty::TextAlign);
3595impl_from_css_prop!(StyleLetterSpacing, CssProperty::LetterSpacing);
3596impl_from_css_prop!(StyleLineHeight, CssProperty::LineHeight);
3597impl_from_css_prop!(StyleWordSpacing, CssProperty::WordSpacing);
3598impl_from_css_prop!(StyleTabWidth, CssProperty::TabWidth);
3599impl_from_css_prop!(StyleCursor, CssProperty::Cursor);
3600impl_from_css_prop!(LayoutDisplay, CssProperty::Display);
3601impl_from_css_prop!(LayoutFloat, CssProperty::Float);
3602impl_from_css_prop!(LayoutBoxSizing, CssProperty::BoxSizing);
3603impl_from_css_prop!(LayoutWidth, CssProperty::Width);
3604impl_from_css_prop!(LayoutHeight, CssProperty::Height);
3605impl_from_css_prop!(LayoutMinWidth, CssProperty::MinWidth);
3606impl_from_css_prop!(LayoutMinHeight, CssProperty::MinHeight);
3607impl_from_css_prop!(LayoutMaxWidth, CssProperty::MaxWidth);
3608impl_from_css_prop!(LayoutMaxHeight, CssProperty::MaxHeight);
3609impl_from_css_prop!(LayoutPosition, CssProperty::Position);
3610impl_from_css_prop!(LayoutTop, CssProperty::Top);
3611impl_from_css_prop!(LayoutRight, CssProperty::Right);
3612impl_from_css_prop!(LayoutLeft, CssProperty::Left);
3613impl_from_css_prop!(LayoutBottom, CssProperty::Bottom);
3614impl_from_css_prop!(LayoutFlexWrap, CssProperty::FlexWrap);
3615impl_from_css_prop!(LayoutFlexDirection, CssProperty::FlexDirection);
3616impl_from_css_prop!(LayoutFlexGrow, CssProperty::FlexGrow);
3617impl_from_css_prop!(LayoutFlexShrink, CssProperty::FlexShrink);
3618impl_from_css_prop!(LayoutJustifyContent, CssProperty::JustifyContent);
3619impl_from_css_prop!(LayoutAlignItems, CssProperty::AlignItems);
3620impl_from_css_prop!(LayoutAlignContent, CssProperty::AlignContent);
3621impl_from_css_prop!(StyleBackgroundContentVec, CssProperty::BackgroundContent);
3622impl_from_css_prop!(StyleBackgroundPositionVec, CssProperty::BackgroundPosition);
3623impl_from_css_prop!(StyleBackgroundSizeVec, CssProperty::BackgroundSize);
3624impl_from_css_prop!(StyleBackgroundRepeatVec, CssProperty::BackgroundRepeat);
3625impl_from_css_prop!(LayoutPaddingTop, CssProperty::PaddingTop);
3626impl_from_css_prop!(LayoutPaddingLeft, CssProperty::PaddingLeft);
3627impl_from_css_prop!(LayoutPaddingRight, CssProperty::PaddingRight);
3628impl_from_css_prop!(LayoutPaddingBottom, CssProperty::PaddingBottom);
3629impl_from_css_prop!(LayoutMarginTop, CssProperty::MarginTop);
3630impl_from_css_prop!(LayoutMarginLeft, CssProperty::MarginLeft);
3631impl_from_css_prop!(LayoutMarginRight, CssProperty::MarginRight);
3632impl_from_css_prop!(LayoutMarginBottom, CssProperty::MarginBottom);
3633impl_from_css_prop!(StyleBorderTopLeftRadius, CssProperty::BorderTopLeftRadius);
3634impl_from_css_prop!(StyleBorderTopRightRadius, CssProperty::BorderTopRightRadius);
3635impl_from_css_prop!(
3636 StyleBorderBottomLeftRadius,
3637 CssProperty::BorderBottomLeftRadius
3638);
3639impl_from_css_prop!(
3640 StyleBorderBottomRightRadius,
3641 CssProperty::BorderBottomRightRadius
3642);
3643impl_from_css_prop!(StyleBorderTopColor, CssProperty::BorderTopColor);
3644impl_from_css_prop!(StyleBorderRightColor, CssProperty::BorderRightColor);
3645impl_from_css_prop!(StyleBorderLeftColor, CssProperty::BorderLeftColor);
3646impl_from_css_prop!(StyleBorderBottomColor, CssProperty::BorderBottomColor);
3647impl_from_css_prop!(StyleBorderTopStyle, CssProperty::BorderTopStyle);
3648impl_from_css_prop!(StyleBorderRightStyle, CssProperty::BorderRightStyle);
3649impl_from_css_prop!(StyleBorderLeftStyle, CssProperty::BorderLeftStyle);
3650impl_from_css_prop!(StyleBorderBottomStyle, CssProperty::BorderBottomStyle);
3651impl_from_css_prop!(LayoutBorderTopWidth, CssProperty::BorderTopWidth);
3652impl_from_css_prop!(LayoutBorderRightWidth, CssProperty::BorderRightWidth);
3653impl_from_css_prop!(LayoutBorderLeftWidth, CssProperty::BorderLeftWidth);
3654impl_from_css_prop!(LayoutBorderBottomWidth, CssProperty::BorderBottomWidth);
3655impl_from_css_prop!(ScrollbarStyle, CssProperty::ScrollbarStyle);
3656impl_from_css_prop!(StyleOpacity, CssProperty::Opacity);
3657impl_from_css_prop!(StyleTransformVec, CssProperty::Transform);
3658impl_from_css_prop!(StyleTransformOrigin, CssProperty::TransformOrigin);
3659impl_from_css_prop!(StylePerspectiveOrigin, CssProperty::PerspectiveOrigin);
3660impl_from_css_prop!(StyleBackfaceVisibility, CssProperty::BackfaceVisibility);
3661impl_from_css_prop!(StyleMixBlendMode, CssProperty::MixBlendMode);
3662
3663const FP_PRECISION_MULTIPLIER: f32 = 1000.0;
3669const FP_PRECISION_MULTIPLIER_CONST: isize = FP_PRECISION_MULTIPLIER as isize;
3670
3671#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
3673#[repr(C)]
3674pub struct PixelValueNoPercent {
3675 pub inner: PixelValue,
3676}
3677
3678impl PixelValueNoPercent {
3679 pub fn scale_for_dpi(&mut self, scale_factor: f32) {
3680 self.inner.scale_for_dpi(scale_factor);
3681 }
3682}
3683
3684impl_option!(
3685 PixelValueNoPercent,
3686 OptionPixelValueNoPercent,
3687 [Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
3688);
3689
3690impl fmt::Display for PixelValueNoPercent {
3691 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3692 write!(f, "{}", self.inner)
3693 }
3694}
3695
3696impl ::core::fmt::Debug for PixelValueNoPercent {
3697 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
3698 write!(f, "{}", self)
3699 }
3700}
3701
3702impl PixelValueNoPercent {
3703 pub fn to_pixels(&self) -> f32 {
3704 self.inner.to_pixels(0.0)
3705 }
3706}
3707
3708#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
3710#[repr(C)]
3711pub struct AngleValue {
3712 pub metric: AngleMetric,
3713 pub number: FloatValue,
3714}
3715
3716impl_option!(
3717 AngleValue,
3718 OptionAngleValue,
3719 [Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
3720);
3721
3722impl fmt::Debug for AngleValue {
3723 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3724 write!(f, "{}", self)
3725 }
3726}
3727
3728impl fmt::Display for AngleValue {
3730 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3731 write!(f, "{}{}", self.number, self.metric)
3732 }
3733}
3734
3735#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
3736#[repr(C)]
3737pub enum AngleMetric {
3738 Degree,
3739 Radians,
3740 Grad,
3741 Turn,
3742 Percent,
3743}
3744
3745impl Default for AngleMetric {
3746 fn default() -> AngleMetric {
3747 AngleMetric::Degree
3748 }
3749}
3750
3751impl fmt::Display for AngleMetric {
3752 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3753 use self::AngleMetric::*;
3754 match self {
3755 Degree => write!(f, "deg"),
3756 Radians => write!(f, "rad"),
3757 Grad => write!(f, "grad"),
3758 Turn => write!(f, "turn"),
3759 Percent => write!(f, "%"),
3760 }
3761 }
3762}
3763
3764impl AngleValue {
3765 #[inline]
3766 pub const fn zero() -> Self {
3767 const ZERO_DEG: AngleValue = AngleValue::const_deg(0);
3768 ZERO_DEG
3769 }
3770
3771 #[inline]
3774 pub const fn const_deg(value: isize) -> Self {
3775 Self::const_from_metric(AngleMetric::Degree, value)
3776 }
3777
3778 #[inline]
3781 pub const fn const_rad(value: isize) -> Self {
3782 Self::const_from_metric(AngleMetric::Radians, value)
3783 }
3784
3785 #[inline]
3788 pub const fn const_grad(value: isize) -> Self {
3789 Self::const_from_metric(AngleMetric::Grad, value)
3790 }
3791
3792 #[inline]
3795 pub const fn const_turn(value: isize) -> Self {
3796 Self::const_from_metric(AngleMetric::Turn, value)
3797 }
3798
3799 #[inline]
3800 pub fn const_percent(value: isize) -> Self {
3801 Self::const_from_metric(AngleMetric::Percent, value)
3802 }
3803
3804 #[inline]
3805 pub const fn const_from_metric(metric: AngleMetric, value: isize) -> Self {
3806 Self {
3807 metric,
3808 number: FloatValue::const_new(value),
3809 }
3810 }
3811
3812 #[inline]
3813 pub fn deg(value: f32) -> Self {
3814 Self::from_metric(AngleMetric::Degree, value)
3815 }
3816
3817 #[inline]
3818 pub fn rad(value: f32) -> Self {
3819 Self::from_metric(AngleMetric::Radians, value)
3820 }
3821
3822 #[inline]
3823 pub fn grad(value: f32) -> Self {
3824 Self::from_metric(AngleMetric::Grad, value)
3825 }
3826
3827 #[inline]
3828 pub fn turn(value: f32) -> Self {
3829 Self::from_metric(AngleMetric::Turn, value)
3830 }
3831
3832 #[inline]
3833 pub fn percent(value: f32) -> Self {
3834 Self::from_metric(AngleMetric::Percent, value)
3835 }
3836
3837 #[inline]
3838 pub fn from_metric(metric: AngleMetric, value: f32) -> Self {
3839 Self {
3840 metric,
3841 number: FloatValue::new(value),
3842 }
3843 }
3844
3845 #[inline]
3847 pub fn to_degrees(&self) -> f32 {
3848 let val = match self.metric {
3849 AngleMetric::Degree => self.number.get(),
3850 AngleMetric::Radians => self.number.get() / 400.0 * 360.0,
3851 AngleMetric::Grad => self.number.get() / (2.0 * core::f32::consts::PI) * 360.0,
3852 AngleMetric::Turn => self.number.get() * 360.0,
3853 AngleMetric::Percent => self.number.get() / 100.0 * 360.0,
3854 };
3855
3856 let mut val = val % 360.0;
3858 if val < 0.0 {
3859 val = 360.0 + val;
3860 }
3861 val
3862 }
3863}
3864
3865#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
3866#[repr(C)]
3867pub struct PixelValue {
3868 pub metric: SizeMetric,
3869 pub number: FloatValue,
3870}
3871
3872impl PixelValue {
3873 pub fn scale_for_dpi(&mut self, scale_factor: f32) {
3874 self.number = FloatValue::new(self.number.get() * scale_factor);
3875 }
3876}
3877
3878impl fmt::Debug for PixelValue {
3879 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3880 write!(f, "{}{}", self.number, self.metric)
3881 }
3882}
3883
3884impl fmt::Display for PixelValue {
3886 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3887 write!(f, "{}{}", self.number, self.metric)
3888 }
3889}
3890
3891impl fmt::Display for SizeMetric {
3892 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3893 use self::SizeMetric::*;
3894 match self {
3895 Px => write!(f, "px"),
3896 Pt => write!(f, "pt"),
3897 Em => write!(f, "pt"),
3898 Percent => write!(f, "%"),
3899 }
3900 }
3901}
3902
3903impl PixelValue {
3904 #[inline]
3905 pub const fn zero() -> Self {
3906 const ZERO_PX: PixelValue = PixelValue::const_px(0);
3907 ZERO_PX
3908 }
3909
3910 #[inline]
3913 pub const fn const_px(value: isize) -> Self {
3914 Self::const_from_metric(SizeMetric::Px, value)
3915 }
3916
3917 #[inline]
3920 pub const fn const_em(value: isize) -> Self {
3921 Self::const_from_metric(SizeMetric::Em, value)
3922 }
3923
3924 #[inline]
3927 pub const fn const_pt(value: isize) -> Self {
3928 Self::const_from_metric(SizeMetric::Pt, value)
3929 }
3930
3931 #[inline]
3934 pub const fn const_percent(value: isize) -> Self {
3935 Self::const_from_metric(SizeMetric::Percent, value)
3936 }
3937
3938 #[inline]
3939 pub const fn const_from_metric(metric: SizeMetric, value: isize) -> Self {
3940 Self {
3941 metric,
3942 number: FloatValue::const_new(value),
3943 }
3944 }
3945
3946 #[inline]
3947 pub fn px(value: f32) -> Self {
3948 Self::from_metric(SizeMetric::Px, value)
3949 }
3950
3951 #[inline]
3952 pub fn em(value: f32) -> Self {
3953 Self::from_metric(SizeMetric::Em, value)
3954 }
3955
3956 #[inline]
3957 pub fn pt(value: f32) -> Self {
3958 Self::from_metric(SizeMetric::Pt, value)
3959 }
3960
3961 #[inline]
3962 pub fn percent(value: f32) -> Self {
3963 Self::from_metric(SizeMetric::Percent, value)
3964 }
3965
3966 #[inline]
3967 pub fn from_metric(metric: SizeMetric, value: f32) -> Self {
3968 Self {
3969 metric,
3970 number: FloatValue::new(value),
3971 }
3972 }
3973
3974 #[inline]
3975 pub fn interpolate(&self, other: &Self, t: f32) -> Self {
3976 if self.metric == other.metric {
3977 Self {
3978 metric: self.metric,
3979 number: self.number.interpolate(&other.number, t),
3980 }
3981 } else {
3982 let self_px_interp = self.to_pixels(0.0);
3985 let other_px_interp = other.to_pixels(0.0);
3986 Self::from_metric(
3987 SizeMetric::Px,
3988 self_px_interp + (other_px_interp - self_px_interp) * t,
3989 )
3990 }
3991 }
3992
3993 #[inline]
3995 pub fn to_pixels(&self, percent_resolve: f32) -> f32 {
3996 match self.metric {
3997 SizeMetric::Px => self.number.get(),
3998 SizeMetric::Pt => self.number.get() * PT_TO_PX,
3999 SizeMetric::Em => self.number.get() * EM_HEIGHT,
4000 SizeMetric::Percent => self.number.get() / 100.0 * percent_resolve,
4001 }
4002 }
4003}
4004
4005#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
4008#[repr(C)]
4009pub struct PercentageValue {
4010 number: FloatValue,
4011}
4012
4013impl_option!(
4014 PercentageValue,
4015 OptionPercentageValue,
4016 [Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
4017);
4018
4019impl fmt::Display for PercentageValue {
4020 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4021 write!(f, "{}%", self.get())
4022 }
4023}
4024
4025impl PercentageValue {
4026 #[inline]
4029 pub const fn const_new(value: isize) -> Self {
4030 Self {
4031 number: FloatValue::const_new(value),
4032 }
4033 }
4034
4035 #[inline]
4036 pub fn new(value: f32) -> Self {
4037 Self {
4038 number: value.into(),
4039 }
4040 }
4041
4042 #[inline]
4043 pub fn get(&self) -> f32 {
4044 self.number.get()
4045 }
4046
4047 #[inline]
4048 pub fn normalized(&self) -> f32 {
4049 self.get() / 100.0
4050 }
4051
4052 #[inline]
4053 pub fn interpolate(&self, other: &Self, t: f32) -> Self {
4054 Self {
4055 number: self.number.interpolate(&other.number, t),
4056 }
4057 }
4058}
4059
4060#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
4063#[repr(C)]
4064pub struct FloatValue {
4065 pub number: isize,
4066}
4067
4068impl fmt::Display for FloatValue {
4069 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4070 write!(f, "{}", self.get())
4071 }
4072}
4073
4074impl ::core::fmt::Debug for FloatValue {
4075 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
4076 write!(f, "{}", self)
4077 }
4078}
4079
4080impl Default for FloatValue {
4081 fn default() -> Self {
4082 const DEFAULT_FLV: FloatValue = FloatValue::const_new(0);
4083 DEFAULT_FLV
4084 }
4085}
4086
4087impl FloatValue {
4088 #[inline]
4091 pub const fn const_new(value: isize) -> Self {
4092 Self {
4093 number: value * FP_PRECISION_MULTIPLIER_CONST,
4094 }
4095 }
4096
4097 #[inline]
4098 pub fn new(value: f32) -> Self {
4099 Self {
4100 number: (value * FP_PRECISION_MULTIPLIER) as isize,
4101 }
4102 }
4103
4104 #[inline]
4105 pub fn get(&self) -> f32 {
4106 self.number as f32 / FP_PRECISION_MULTIPLIER
4107 }
4108
4109 #[inline]
4110 pub fn interpolate(&self, other: &Self, t: f32) -> Self {
4111 let self_val_f32 = self.get();
4112 let other_val_f32 = other.get();
4113 let interpolated = self_val_f32 + ((other_val_f32 - self_val_f32) * t);
4114 Self::new(interpolated)
4115 }
4116}
4117
4118impl From<f32> for FloatValue {
4119 #[inline]
4120 fn from(val: f32) -> Self {
4121 Self::new(val)
4122 }
4123}
4124
4125#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
4127#[repr(C)]
4128pub enum SizeMetric {
4129 Px,
4130 Pt,
4131 Em,
4132 Percent,
4133}
4134
4135impl Default for SizeMetric {
4136 fn default() -> Self {
4137 SizeMetric::Px
4138 }
4139}
4140
4141#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
4143#[repr(C, u8)]
4144pub enum StyleBackgroundSize {
4145 ExactSize([PixelValue; 2]),
4146 Contain,
4147 Cover,
4148}
4149
4150impl StyleBackgroundSize {
4151 pub fn scale_for_dpi(&mut self, scale_factor: f32) {
4152 match self {
4153 StyleBackgroundSize::ExactSize(a) => {
4154 for q in a.iter_mut() {
4155 q.scale_for_dpi(scale_factor);
4156 }
4157 }
4158 _ => {}
4159 }
4160 }
4161}
4162
4163impl Default for StyleBackgroundSize {
4164 fn default() -> Self {
4165 StyleBackgroundSize::Contain
4166 }
4167}
4168
4169impl_vec!(
4170 StyleBackgroundSize,
4171 StyleBackgroundSizeVec,
4172 StyleBackgroundSizeVecDestructor
4173);
4174impl_vec_debug!(StyleBackgroundSize, StyleBackgroundSizeVec);
4175impl_vec_partialord!(StyleBackgroundSize, StyleBackgroundSizeVec);
4176impl_vec_ord!(StyleBackgroundSize, StyleBackgroundSizeVec);
4177impl_vec_clone!(
4178 StyleBackgroundSize,
4179 StyleBackgroundSizeVec,
4180 StyleBackgroundSizeVecDestructor
4181);
4182impl_vec_partialeq!(StyleBackgroundSize, StyleBackgroundSizeVec);
4183impl_vec_eq!(StyleBackgroundSize, StyleBackgroundSizeVec);
4184impl_vec_hash!(StyleBackgroundSize, StyleBackgroundSizeVec);
4185
4186#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
4188#[repr(C)]
4189pub struct StyleBackgroundPosition {
4190 pub horizontal: BackgroundPositionHorizontal,
4191 pub vertical: BackgroundPositionVertical,
4192}
4193
4194impl StyleBackgroundPosition {
4195 pub fn scale_for_dpi(&mut self, scale_factor: f32) {
4196 self.horizontal.scale_for_dpi(scale_factor);
4197 self.vertical.scale_for_dpi(scale_factor);
4198 }
4199}
4200
4201impl_vec!(
4202 StyleBackgroundPosition,
4203 StyleBackgroundPositionVec,
4204 StyleBackgroundPositionVecDestructor
4205);
4206impl_vec_debug!(StyleBackgroundPosition, StyleBackgroundPositionVec);
4207impl_vec_partialord!(StyleBackgroundPosition, StyleBackgroundPositionVec);
4208impl_vec_ord!(StyleBackgroundPosition, StyleBackgroundPositionVec);
4209impl_vec_clone!(
4210 StyleBackgroundPosition,
4211 StyleBackgroundPositionVec,
4212 StyleBackgroundPositionVecDestructor
4213);
4214impl_vec_partialeq!(StyleBackgroundPosition, StyleBackgroundPositionVec);
4215impl_vec_eq!(StyleBackgroundPosition, StyleBackgroundPositionVec);
4216impl_vec_hash!(StyleBackgroundPosition, StyleBackgroundPositionVec);
4217
4218impl Default for StyleBackgroundPosition {
4219 fn default() -> Self {
4220 StyleBackgroundPosition {
4221 horizontal: BackgroundPositionHorizontal::Left,
4222 vertical: BackgroundPositionVertical::Top,
4223 }
4224 }
4225}
4226
4227#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
4228#[repr(C, u8)]
4229pub enum BackgroundPositionHorizontal {
4230 Left,
4231 Center,
4232 Right,
4233 Exact(PixelValue),
4234}
4235
4236impl BackgroundPositionHorizontal {
4237 pub fn scale_for_dpi(&mut self, scale_factor: f32) {
4238 match self {
4239 BackgroundPositionHorizontal::Exact(s) => {
4240 s.scale_for_dpi(scale_factor);
4241 }
4242 _ => {}
4243 }
4244 }
4245}
4246
4247#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
4248#[repr(C, u8)]
4249pub enum BackgroundPositionVertical {
4250 Top,
4251 Center,
4252 Bottom,
4253 Exact(PixelValue),
4254}
4255
4256impl BackgroundPositionVertical {
4257 pub fn scale_for_dpi(&mut self, scale_factor: f32) {
4258 match self {
4259 BackgroundPositionVertical::Exact(s) => {
4260 s.scale_for_dpi(scale_factor);
4261 }
4262 _ => {}
4263 }
4264 }
4265}
4266
4267#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
4269#[repr(C)]
4270pub enum StyleBackgroundRepeat {
4271 NoRepeat,
4272 Repeat,
4273 RepeatX,
4274 RepeatY,
4275}
4276
4277impl_vec!(
4278 StyleBackgroundRepeat,
4279 StyleBackgroundRepeatVec,
4280 StyleBackgroundRepeatVecDestructor
4281);
4282impl_vec_debug!(StyleBackgroundRepeat, StyleBackgroundRepeatVec);
4283impl_vec_partialord!(StyleBackgroundRepeat, StyleBackgroundRepeatVec);
4284impl_vec_ord!(StyleBackgroundRepeat, StyleBackgroundRepeatVec);
4285impl_vec_clone!(
4286 StyleBackgroundRepeat,
4287 StyleBackgroundRepeatVec,
4288 StyleBackgroundRepeatVecDestructor
4289);
4290impl_vec_partialeq!(StyleBackgroundRepeat, StyleBackgroundRepeatVec);
4291impl_vec_eq!(StyleBackgroundRepeat, StyleBackgroundRepeatVec);
4292impl_vec_hash!(StyleBackgroundRepeat, StyleBackgroundRepeatVec);
4293
4294impl Default for StyleBackgroundRepeat {
4295 fn default() -> Self {
4296 StyleBackgroundRepeat::Repeat
4297 }
4298}
4299
4300#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
4302#[repr(C)]
4303pub struct StyleTextColor {
4304 pub inner: ColorU,
4305}
4306
4307derive_debug_zero!(StyleTextColor);
4308derive_display_zero!(StyleTextColor);
4309
4310impl StyleTextColor {
4311 pub fn interpolate(&self, other: &Self, t: f32) -> Self {
4312 Self {
4313 inner: self.inner.interpolate(&other.inner, t),
4314 }
4315 }
4316}
4317
4318#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
4322#[repr(C)]
4323pub struct StyleBorderTopLeftRadius {
4324 pub inner: PixelValue,
4325}
4326#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
4328#[repr(C)]
4329pub struct StyleBorderBottomLeftRadius {
4330 pub inner: PixelValue,
4331}
4332#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
4334#[repr(C)]
4335pub struct StyleBorderTopRightRadius {
4336 pub inner: PixelValue,
4337}
4338#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
4340#[repr(C)]
4341pub struct StyleBorderBottomRightRadius {
4342 pub inner: PixelValue,
4343}
4344
4345impl_pixel_value!(StyleBorderTopLeftRadius);
4346impl_pixel_value!(StyleBorderBottomLeftRadius);
4347impl_pixel_value!(StyleBorderTopRightRadius);
4348impl_pixel_value!(StyleBorderBottomRightRadius);
4349
4350#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
4352#[repr(C)]
4353pub struct LayoutBorderTopWidth {
4354 pub inner: PixelValue,
4355}
4356#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
4358#[repr(C)]
4359pub struct LayoutBorderLeftWidth {
4360 pub inner: PixelValue,
4361}
4362#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
4364#[repr(C)]
4365pub struct LayoutBorderRightWidth {
4366 pub inner: PixelValue,
4367}
4368#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
4370#[repr(C)]
4371pub struct LayoutBorderBottomWidth {
4372 pub inner: PixelValue,
4373}
4374
4375impl_pixel_value!(LayoutBorderTopWidth);
4376impl_pixel_value!(LayoutBorderLeftWidth);
4377impl_pixel_value!(LayoutBorderRightWidth);
4378impl_pixel_value!(LayoutBorderBottomWidth);
4379
4380impl CssPropertyValue<StyleBorderTopLeftRadius> {
4381 pub fn scale_for_dpi(&mut self, scale_factor: f32) {
4382 match self {
4383 CssPropertyValue::Exact(s) => {
4384 s.scale_for_dpi(scale_factor);
4385 }
4386 _ => {}
4387 }
4388 }
4389}
4390
4391impl CssPropertyValue<StyleBorderTopRightRadius> {
4392 pub fn scale_for_dpi(&mut self, scale_factor: f32) {
4393 match self {
4394 CssPropertyValue::Exact(s) => {
4395 s.scale_for_dpi(scale_factor);
4396 }
4397 _ => {}
4398 }
4399 }
4400}
4401
4402impl CssPropertyValue<StyleBorderBottomLeftRadius> {
4403 pub fn scale_for_dpi(&mut self, scale_factor: f32) {
4404 match self {
4405 CssPropertyValue::Exact(s) => {
4406 s.scale_for_dpi(scale_factor);
4407 }
4408 _ => {}
4409 }
4410 }
4411}
4412
4413impl CssPropertyValue<StyleBorderBottomRightRadius> {
4414 pub fn scale_for_dpi(&mut self, scale_factor: f32) {
4415 match self {
4416 CssPropertyValue::Exact(s) => {
4417 s.scale_for_dpi(scale_factor);
4418 }
4419 _ => {}
4420 }
4421 }
4422}
4423
4424impl CssPropertyValue<LayoutBorderTopWidth> {
4425 pub fn scale_for_dpi(&mut self, scale_factor: f32) {
4426 match self {
4427 CssPropertyValue::Exact(s) => {
4428 s.scale_for_dpi(scale_factor);
4429 }
4430 _ => {}
4431 }
4432 }
4433}
4434
4435impl CssPropertyValue<LayoutBorderRightWidth> {
4436 pub fn scale_for_dpi(&mut self, scale_factor: f32) {
4437 match self {
4438 CssPropertyValue::Exact(s) => {
4439 s.scale_for_dpi(scale_factor);
4440 }
4441 _ => {}
4442 }
4443 }
4444}
4445
4446impl CssPropertyValue<LayoutBorderBottomWidth> {
4447 pub fn scale_for_dpi(&mut self, scale_factor: f32) {
4448 match self {
4449 CssPropertyValue::Exact(s) => {
4450 s.scale_for_dpi(scale_factor);
4451 }
4452 _ => {}
4453 }
4454 }
4455}
4456
4457impl CssPropertyValue<LayoutBorderLeftWidth> {
4458 pub fn scale_for_dpi(&mut self, scale_factor: f32) {
4459 match self {
4460 CssPropertyValue::Exact(s) => {
4461 s.scale_for_dpi(scale_factor);
4462 }
4463 _ => {}
4464 }
4465 }
4466}
4467
4468impl StyleBorderTopLeftRadius {
4469 pub fn scale_for_dpi(&mut self, scale_factor: f32) {
4470 self.inner.scale_for_dpi(scale_factor);
4471 }
4472}
4473
4474impl StyleBorderTopRightRadius {
4475 pub fn scale_for_dpi(&mut self, scale_factor: f32) {
4476 self.inner.scale_for_dpi(scale_factor);
4477 }
4478}
4479
4480impl StyleBorderBottomLeftRadius {
4481 pub fn scale_for_dpi(&mut self, scale_factor: f32) {
4482 self.inner.scale_for_dpi(scale_factor);
4483 }
4484}
4485
4486impl StyleBorderBottomRightRadius {
4487 pub fn scale_for_dpi(&mut self, scale_factor: f32) {
4488 self.inner.scale_for_dpi(scale_factor);
4489 }
4490}
4491
4492impl LayoutBorderTopWidth {
4493 pub fn scale_for_dpi(&mut self, scale_factor: f32) {
4494 self.inner.scale_for_dpi(scale_factor);
4495 }
4496}
4497
4498impl LayoutBorderRightWidth {
4499 pub fn scale_for_dpi(&mut self, scale_factor: f32) {
4500 self.inner.scale_for_dpi(scale_factor);
4501 }
4502}
4503
4504impl LayoutBorderBottomWidth {
4505 pub fn scale_for_dpi(&mut self, scale_factor: f32) {
4506 self.inner.scale_for_dpi(scale_factor);
4507 }
4508}
4509
4510impl LayoutBorderLeftWidth {
4511 pub fn scale_for_dpi(&mut self, scale_factor: f32) {
4512 self.inner.scale_for_dpi(scale_factor);
4513 }
4514}
4515
4516#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
4518#[repr(C)]
4519pub struct StyleBorderTopStyle {
4520 pub inner: BorderStyle,
4521}
4522#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
4524#[repr(C)]
4525pub struct StyleBorderLeftStyle {
4526 pub inner: BorderStyle,
4527}
4528#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
4530#[repr(C)]
4531pub struct StyleBorderRightStyle {
4532 pub inner: BorderStyle,
4533}
4534#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
4536#[repr(C)]
4537pub struct StyleBorderBottomStyle {
4538 pub inner: BorderStyle,
4539}
4540
4541derive_debug_zero!(StyleBorderTopStyle);
4542derive_debug_zero!(StyleBorderLeftStyle);
4543derive_debug_zero!(StyleBorderBottomStyle);
4544derive_debug_zero!(StyleBorderRightStyle);
4545
4546derive_display_zero!(StyleBorderTopStyle);
4547derive_display_zero!(StyleBorderLeftStyle);
4548derive_display_zero!(StyleBorderBottomStyle);
4549derive_display_zero!(StyleBorderRightStyle);
4550
4551#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
4553#[repr(C)]
4554pub struct StyleBorderTopColor {
4555 pub inner: ColorU,
4556}
4557#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
4559#[repr(C)]
4560pub struct StyleBorderLeftColor {
4561 pub inner: ColorU,
4562}
4563#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
4565#[repr(C)]
4566pub struct StyleBorderRightColor {
4567 pub inner: ColorU,
4568}
4569#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
4571#[repr(C)]
4572pub struct StyleBorderBottomColor {
4573 pub inner: ColorU,
4574}
4575
4576impl StyleBorderTopColor {
4577 pub fn interpolate(&self, other: &Self, t: f32) -> Self {
4578 Self {
4579 inner: self.inner.interpolate(&other.inner, t),
4580 }
4581 }
4582}
4583impl StyleBorderLeftColor {
4584 pub fn interpolate(&self, other: &Self, t: f32) -> Self {
4585 Self {
4586 inner: self.inner.interpolate(&other.inner, t),
4587 }
4588 }
4589}
4590impl StyleBorderRightColor {
4591 pub fn interpolate(&self, other: &Self, t: f32) -> Self {
4592 Self {
4593 inner: self.inner.interpolate(&other.inner, t),
4594 }
4595 }
4596}
4597impl StyleBorderBottomColor {
4598 pub fn interpolate(&self, other: &Self, t: f32) -> Self {
4599 Self {
4600 inner: self.inner.interpolate(&other.inner, t),
4601 }
4602 }
4603}
4604derive_debug_zero!(StyleBorderTopColor);
4605derive_debug_zero!(StyleBorderLeftColor);
4606derive_debug_zero!(StyleBorderRightColor);
4607derive_debug_zero!(StyleBorderBottomColor);
4608
4609derive_display_zero!(StyleBorderTopColor);
4610derive_display_zero!(StyleBorderLeftColor);
4611derive_display_zero!(StyleBorderRightColor);
4612derive_display_zero!(StyleBorderBottomColor);
4613
4614#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
4615pub struct StyleBorderSide {
4616 pub border_width: PixelValue,
4617 pub border_style: BorderStyle,
4618 pub border_color: ColorU,
4619}
4620
4621#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
4623#[repr(C)]
4624pub struct StyleBoxShadow {
4625 pub offset: [PixelValueNoPercent; 2],
4626 pub color: ColorU,
4627 pub blur_radius: PixelValueNoPercent,
4628 pub spread_radius: PixelValueNoPercent,
4629 pub clip_mode: BoxShadowClipMode,
4630}
4631
4632impl StyleBoxShadow {
4633 pub fn scale_for_dpi(&mut self, scale_factor: f32) {
4634 for s in self.offset.iter_mut() {
4635 s.scale_for_dpi(scale_factor);
4636 }
4637 self.blur_radius.scale_for_dpi(scale_factor);
4638 self.spread_radius.scale_for_dpi(scale_factor);
4639 }
4640}
4641
4642#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
4643#[repr(C, u8)]
4644pub enum StyleBackgroundContent {
4645 LinearGradient(LinearGradient),
4646 RadialGradient(RadialGradient),
4647 ConicGradient(ConicGradient),
4648 Image(AzString),
4649 Color(ColorU),
4650}
4651
4652impl_vec!(
4653 StyleBackgroundContent,
4654 StyleBackgroundContentVec,
4655 StyleBackgroundContentVecDestructor
4656);
4657impl_vec_debug!(StyleBackgroundContent, StyleBackgroundContentVec);
4658impl_vec_partialord!(StyleBackgroundContent, StyleBackgroundContentVec);
4659impl_vec_ord!(StyleBackgroundContent, StyleBackgroundContentVec);
4660impl_vec_clone!(
4661 StyleBackgroundContent,
4662 StyleBackgroundContentVec,
4663 StyleBackgroundContentVecDestructor
4664);
4665impl_vec_partialeq!(StyleBackgroundContent, StyleBackgroundContentVec);
4666impl_vec_eq!(StyleBackgroundContent, StyleBackgroundContentVec);
4667impl_vec_hash!(StyleBackgroundContent, StyleBackgroundContentVec);
4668
4669impl Default for StyleBackgroundContent {
4670 fn default() -> StyleBackgroundContent {
4671 StyleBackgroundContent::Color(ColorU::TRANSPARENT)
4672 }
4673}
4674
4675impl<'a> From<AzString> for StyleBackgroundContent {
4676 fn from(id: AzString) -> Self {
4677 StyleBackgroundContent::Image(id)
4678 }
4679}
4680
4681#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
4682#[repr(C)]
4683pub struct LinearGradient {
4684 pub direction: Direction,
4685 pub extend_mode: ExtendMode,
4686 pub stops: NormalizedLinearColorStopVec,
4687}
4688
4689impl Default for LinearGradient {
4690 fn default() -> Self {
4691 Self {
4692 direction: Direction::default(),
4693 extend_mode: ExtendMode::default(),
4694 stops: Vec::new().into(),
4695 }
4696 }
4697}
4698
4699#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
4700#[repr(C)]
4701pub struct ConicGradient {
4702 pub extend_mode: ExtendMode, pub center: StyleBackgroundPosition, pub angle: AngleValue, pub stops: NormalizedRadialColorStopVec, }
4707
4708impl Default for ConicGradient {
4709 fn default() -> Self {
4710 Self {
4711 extend_mode: ExtendMode::default(),
4712 center: StyleBackgroundPosition {
4713 horizontal: BackgroundPositionHorizontal::Center,
4714 vertical: BackgroundPositionVertical::Center,
4715 },
4716 angle: AngleValue::default(),
4717 stops: Vec::new().into(),
4718 }
4719 }
4720}
4721
4722#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
4724#[repr(C)]
4725pub struct NormalizedLinearColorStop {
4726 pub offset: PercentageValue, pub color: ColorU,
4728}
4729
4730#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
4731#[repr(C)]
4732pub struct NormalizedRadialColorStop {
4733 pub angle: AngleValue, pub color: ColorU,
4735}
4736
4737impl LinearColorStop {
4738 pub fn get_normalized_linear_stops(
4739 stops: &[LinearColorStop],
4740 ) -> Vec<NormalizedLinearColorStop> {
4741 const MIN_STOP_DEGREE: f32 = 0.0;
4742 const MAX_STOP_DEGREE: f32 = 100.0;
4743
4744 if stops.is_empty() {
4745 return Vec::new();
4746 }
4747
4748 let self_stops = stops;
4749
4750 let mut stops = self_stops
4751 .iter()
4752 .map(|s| NormalizedLinearColorStop {
4753 offset: s
4754 .offset
4755 .as_ref()
4756 .copied()
4757 .unwrap_or(PercentageValue::new(MIN_STOP_DEGREE)),
4758 color: s.color,
4759 })
4760 .collect::<Vec<_>>();
4761
4762 let mut stops_to_distribute = 0;
4763 let mut last_stop = None;
4764 let stops_len = stops.len();
4765
4766 for (stop_id, stop) in self_stops.iter().enumerate() {
4767 if let Some(s) = stop.offset.into_option() {
4768 let current_stop_val = s.get();
4769 if stops_to_distribute != 0 {
4770 let last_stop_val = stops[(stop_id - stops_to_distribute)].offset.get();
4771 let value_to_add_per_stop = (current_stop_val.max(last_stop_val)
4772 - last_stop_val)
4773 / (stops_to_distribute - 1) as f32;
4774 for (s_id, s) in stops[(stop_id - stops_to_distribute)..stop_id]
4775 .iter_mut()
4776 .enumerate()
4777 {
4778 s.offset = PercentageValue::new(
4779 last_stop_val + (s_id as f32 * value_to_add_per_stop),
4780 );
4781 }
4782 }
4783 stops_to_distribute = 0;
4784 last_stop = Some(s);
4785 } else {
4786 stops_to_distribute += 1;
4787 }
4788 }
4789
4790 if stops_to_distribute != 0 {
4791 let last_stop_val = last_stop
4792 .unwrap_or(PercentageValue::new(MIN_STOP_DEGREE))
4793 .get();
4794 let value_to_add_per_stop = (MAX_STOP_DEGREE.max(last_stop_val) - last_stop_val)
4795 / (stops_to_distribute - 1) as f32;
4796 for (s_id, s) in stops[(stops_len - stops_to_distribute)..]
4797 .iter_mut()
4798 .enumerate()
4799 {
4800 s.offset =
4801 PercentageValue::new(last_stop_val + (s_id as f32 * value_to_add_per_stop));
4802 }
4803 }
4804
4805 stops
4806 }
4807}
4808
4809impl RadialColorStop {
4810 pub fn get_normalized_radial_stops(
4811 stops: &[RadialColorStop],
4812 ) -> Vec<NormalizedRadialColorStop> {
4813 const MIN_STOP_DEGREE: f32 = 0.0;
4814 const MAX_STOP_DEGREE: f32 = 360.0;
4815
4816 if stops.is_empty() {
4817 return Vec::new();
4818 }
4819
4820 let self_stops = stops;
4821
4822 let mut stops = self_stops
4823 .iter()
4824 .map(|s| NormalizedRadialColorStop {
4825 angle: s
4826 .offset
4827 .as_ref()
4828 .copied()
4829 .unwrap_or(AngleValue::deg(MIN_STOP_DEGREE)),
4830 color: s.color,
4831 })
4832 .collect::<Vec<_>>();
4833
4834 let mut stops_to_distribute = 0;
4835 let mut last_stop = None;
4836 let stops_len = stops.len();
4837
4838 for (stop_id, stop) in self_stops.iter().enumerate() {
4839 if let Some(s) = stop.offset.into_option() {
4840 let current_stop_val = s.to_degrees();
4841 if stops_to_distribute != 0 {
4842 let last_stop_val = stops[(stop_id - stops_to_distribute)].angle.to_degrees();
4843 let value_to_add_per_stop = (current_stop_val.max(last_stop_val)
4844 - last_stop_val)
4845 / (stops_to_distribute - 1) as f32;
4846 for (s_id, s) in stops[(stop_id - stops_to_distribute)..stop_id]
4847 .iter_mut()
4848 .enumerate()
4849 {
4850 s.angle =
4851 AngleValue::deg(last_stop_val + (s_id as f32 * value_to_add_per_stop));
4852 }
4853 }
4854 stops_to_distribute = 0;
4855 last_stop = Some(s);
4856 } else {
4857 stops_to_distribute += 1;
4858 }
4859 }
4860
4861 if stops_to_distribute != 0 {
4862 let last_stop_val = last_stop
4863 .unwrap_or(AngleValue::deg(MIN_STOP_DEGREE))
4864 .to_degrees();
4865 let value_to_add_per_stop = (MAX_STOP_DEGREE.max(last_stop_val) - last_stop_val)
4866 / (stops_to_distribute - 1) as f32;
4867 for (s_id, s) in stops[(stops_len - stops_to_distribute)..]
4868 .iter_mut()
4869 .enumerate()
4870 {
4871 s.angle = AngleValue::deg(last_stop_val + (s_id as f32 * value_to_add_per_stop));
4872 }
4873 }
4874
4875 stops
4876 }
4877}
4878
4879#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
4880#[repr(C)]
4881pub struct RadialGradient {
4882 pub shape: Shape,
4883 pub size: RadialGradientSize,
4884 pub position: StyleBackgroundPosition,
4885 pub extend_mode: ExtendMode,
4886 pub stops: NormalizedLinearColorStopVec,
4887}
4888
4889impl Default for RadialGradient {
4890 fn default() -> Self {
4891 Self {
4892 shape: Shape::default(),
4893 size: RadialGradientSize::default(),
4894 position: StyleBackgroundPosition::default(),
4895 extend_mode: ExtendMode::default(),
4896 stops: Vec::new().into(),
4897 }
4898 }
4899}
4900
4901#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
4902#[repr(C)]
4903pub enum RadialGradientSize {
4904 ClosestSide,
4908 ClosestCorner,
4911 FarthestSide,
4914 FarthestCorner,
4917}
4918
4919impl Default for RadialGradientSize {
4920 fn default() -> Self {
4921 RadialGradientSize::FarthestCorner
4922 }
4923}
4924
4925impl RadialGradientSize {
4926 pub fn get_size(&self, parent_rect: LayoutRect, gradient_center: LayoutPosition) -> LayoutSize {
4927 parent_rect.size
4929 }
4930}
4931
4932#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
4933#[repr(C)]
4934pub struct DirectionCorners {
4935 pub from: DirectionCorner,
4936 pub to: DirectionCorner,
4937}
4938
4939#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
4942#[repr(C, u8)]
4943pub enum Direction {
4944 Angle(AngleValue),
4945 FromTo(DirectionCorners),
4946}
4947
4948impl Default for Direction {
4949 fn default() -> Self {
4950 Direction::FromTo(DirectionCorners {
4951 from: DirectionCorner::Top,
4952 to: DirectionCorner::Bottom,
4953 })
4954 }
4955}
4956
4957impl Direction {
4958 pub fn to_points(&self, rect: &LayoutRect) -> (LayoutPoint, LayoutPoint) {
4960 match self {
4961 Direction::Angle(angle_value) => {
4962 let deg = angle_value.to_degrees(); let deg = -deg; let width_half = rect.size.width as f32 / 2.0;
4971 let height_half = rect.size.height as f32 / 2.0;
4972
4973 let hypotenuse_len = libm::hypotf(width_half, height_half);
4975
4976 let angle_to_top_left = libm::atanf(height_half / width_half).to_degrees();
4981
4982 let ending_point_degrees = if deg < 90.0 {
4984 90.0 - angle_to_top_left
4986 } else if deg < 180.0 {
4987 90.0 + angle_to_top_left
4989 } else if deg < 270.0 {
4990 270.0 - angle_to_top_left
4992 } else
4993 {
4995 270.0 + angle_to_top_left
4997 };
4998
4999 let degree_diff_to_corner = ending_point_degrees as f32 - deg;
5001
5002 let searched_len = libm::fabsf(libm::cosf(
5005 hypotenuse_len * degree_diff_to_corner.to_radians() as f32,
5006 ));
5007
5008 let dx = libm::sinf(deg.to_radians() as f32) * searched_len;
5013 let dy = libm::cosf(deg.to_radians() as f32) * searched_len;
5014
5015 let start_point_location = LayoutPoint {
5016 x: libm::roundf(width_half + dx) as isize,
5017 y: libm::roundf(height_half + dy) as isize,
5018 };
5019 let end_point_location = LayoutPoint {
5020 x: libm::roundf(width_half - dx) as isize,
5021 y: libm::roundf(height_half - dy) as isize,
5022 };
5023
5024 (start_point_location, end_point_location)
5025 }
5026 Direction::FromTo(ft) => (ft.from.to_point(rect), ft.to.to_point(rect)),
5027 }
5028 }
5029}
5030
5031#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5032#[repr(C)]
5033pub enum Shape {
5034 Ellipse,
5035 Circle,
5036}
5037
5038impl Default for Shape {
5039 fn default() -> Self {
5040 Shape::Ellipse
5041 }
5042}
5043
5044#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5045#[repr(C)]
5046pub enum StyleCursor {
5047 Alias,
5049 AllScroll,
5051 Cell,
5053 ColResize,
5055 ContextMenu,
5057 Copy,
5059 Crosshair,
5061 Default,
5063 EResize,
5065 EwResize,
5067 Grab,
5069 Grabbing,
5071 Help,
5073 Move,
5075 NResize,
5077 NsResize,
5079 NeswResize,
5081 NwseResize,
5083 Pointer,
5085 Progress,
5087 RowResize,
5089 SResize,
5091 SeResize,
5093 Text,
5095 Unset,
5097 VerticalText,
5099 WResize,
5101 Wait,
5103 ZoomIn,
5105 ZoomOut,
5107}
5108
5109impl Default for StyleCursor {
5110 fn default() -> StyleCursor {
5111 StyleCursor::Default
5112 }
5113}
5114
5115#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5116#[repr(C)]
5117pub enum DirectionCorner {
5118 Right,
5119 Left,
5120 Top,
5121 Bottom,
5122 TopRight,
5123 TopLeft,
5124 BottomRight,
5125 BottomLeft,
5126}
5127
5128impl fmt::Display for DirectionCorner {
5129 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5130 write!(
5131 f,
5132 "{}",
5133 match self {
5134 DirectionCorner::Right => "right",
5135 DirectionCorner::Left => "left",
5136 DirectionCorner::Top => "top",
5137 DirectionCorner::Bottom => "bottom",
5138 DirectionCorner::TopRight => "top right",
5139 DirectionCorner::TopLeft => "top left",
5140 DirectionCorner::BottomRight => "bottom right",
5141 DirectionCorner::BottomLeft => "bottom left",
5142 }
5143 )
5144 }
5145}
5146
5147impl DirectionCorner {
5148 pub const fn opposite(&self) -> Self {
5149 use self::DirectionCorner::*;
5150 match *self {
5151 Right => Left,
5152 Left => Right,
5153 Top => Bottom,
5154 Bottom => Top,
5155 TopRight => BottomLeft,
5156 BottomLeft => TopRight,
5157 TopLeft => BottomRight,
5158 BottomRight => TopLeft,
5159 }
5160 }
5161
5162 pub const fn combine(&self, other: &Self) -> Option<Self> {
5163 use self::DirectionCorner::*;
5164 match (*self, *other) {
5165 (Right, Top) | (Top, Right) => Some(TopRight),
5166 (Left, Top) | (Top, Left) => Some(TopLeft),
5167 (Right, Bottom) | (Bottom, Right) => Some(BottomRight),
5168 (Left, Bottom) | (Bottom, Left) => Some(BottomLeft),
5169 _ => None,
5170 }
5171 }
5172
5173 pub const fn to_point(&self, rect: &LayoutRect) -> LayoutPoint {
5174 use self::DirectionCorner::*;
5175 match *self {
5176 Right => LayoutPoint {
5177 x: rect.size.width,
5178 y: rect.size.height / 2,
5179 },
5180 Left => LayoutPoint {
5181 x: 0,
5182 y: rect.size.height / 2,
5183 },
5184 Top => LayoutPoint {
5185 x: rect.size.width / 2,
5186 y: 0,
5187 },
5188 Bottom => LayoutPoint {
5189 x: rect.size.width / 2,
5190 y: rect.size.height,
5191 },
5192 TopRight => LayoutPoint {
5193 x: rect.size.width,
5194 y: 0,
5195 },
5196 TopLeft => LayoutPoint { x: 0, y: 0 },
5197 BottomRight => LayoutPoint {
5198 x: rect.size.width,
5199 y: rect.size.height,
5200 },
5201 BottomLeft => LayoutPoint {
5202 x: 0,
5203 y: rect.size.height,
5204 },
5205 }
5206 }
5207}
5208
5209#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5210pub struct RadialColorStop {
5211 pub offset: OptionAngleValue,
5213 pub color: ColorU,
5214}
5215
5216impl_vec!(
5217 NormalizedRadialColorStop,
5218 NormalizedRadialColorStopVec,
5219 NormalizedRadialColorStopVecDestructor
5220);
5221impl_vec_debug!(NormalizedRadialColorStop, NormalizedRadialColorStopVec);
5222impl_vec_partialord!(NormalizedRadialColorStop, NormalizedRadialColorStopVec);
5223impl_vec_ord!(NormalizedRadialColorStop, NormalizedRadialColorStopVec);
5224impl_vec_clone!(
5225 NormalizedRadialColorStop,
5226 NormalizedRadialColorStopVec,
5227 NormalizedRadialColorStopVecDestructor
5228);
5229impl_vec_partialeq!(NormalizedRadialColorStop, NormalizedRadialColorStopVec);
5230impl_vec_eq!(NormalizedRadialColorStop, NormalizedRadialColorStopVec);
5231impl_vec_hash!(NormalizedRadialColorStop, NormalizedRadialColorStopVec);
5232
5233#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5234pub struct LinearColorStop {
5235 pub offset: OptionPercentageValue,
5237 pub color: ColorU,
5238}
5239
5240impl_vec!(
5241 NormalizedLinearColorStop,
5242 NormalizedLinearColorStopVec,
5243 NormalizedLinearColorStopVecDestructor
5244);
5245impl_vec_debug!(NormalizedLinearColorStop, NormalizedLinearColorStopVec);
5246impl_vec_partialord!(NormalizedLinearColorStop, NormalizedLinearColorStopVec);
5247impl_vec_ord!(NormalizedLinearColorStop, NormalizedLinearColorStopVec);
5248impl_vec_clone!(
5249 NormalizedLinearColorStop,
5250 NormalizedLinearColorStopVec,
5251 NormalizedLinearColorStopVecDestructor
5252);
5253impl_vec_partialeq!(NormalizedLinearColorStop, NormalizedLinearColorStopVec);
5254impl_vec_eq!(NormalizedLinearColorStop, NormalizedLinearColorStopVec);
5255impl_vec_hash!(NormalizedLinearColorStop, NormalizedLinearColorStopVec);
5256
5257#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5259#[repr(C)]
5260pub struct LayoutWidth {
5261 pub inner: PixelValue,
5262}
5263#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5265#[repr(C)]
5266pub struct LayoutMinWidth {
5267 pub inner: PixelValue,
5268}
5269#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5271#[repr(C)]
5272pub struct LayoutMaxWidth {
5273 pub inner: PixelValue,
5274}
5275#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5277#[repr(C)]
5278pub struct LayoutHeight {
5279 pub inner: PixelValue,
5280}
5281#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5283#[repr(C)]
5284pub struct LayoutMinHeight {
5285 pub inner: PixelValue,
5286}
5287#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5289#[repr(C)]
5290pub struct LayoutMaxHeight {
5291 pub inner: PixelValue,
5292}
5293
5294impl Default for LayoutMaxHeight {
5295 fn default() -> Self {
5296 Self {
5297 inner: PixelValue::px(core::f32::MAX),
5298 }
5299 }
5300}
5301impl Default for LayoutMaxWidth {
5302 fn default() -> Self {
5303 Self {
5304 inner: PixelValue::px(core::f32::MAX),
5305 }
5306 }
5307}
5308
5309impl_pixel_value!(LayoutWidth);
5310impl_pixel_value!(LayoutHeight);
5311impl_pixel_value!(LayoutMinHeight);
5312impl_pixel_value!(LayoutMinWidth);
5313impl_pixel_value!(LayoutMaxWidth);
5314impl_pixel_value!(LayoutMaxHeight);
5315
5316#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5318#[repr(C)]
5319pub struct LayoutTop {
5320 pub inner: PixelValue,
5321}
5322#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5324#[repr(C)]
5325pub struct LayoutLeft {
5326 pub inner: PixelValue,
5327}
5328#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5330#[repr(C)]
5331pub struct LayoutRight {
5332 pub inner: PixelValue,
5333}
5334#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5336#[repr(C)]
5337pub struct LayoutBottom {
5338 pub inner: PixelValue,
5339}
5340
5341impl_pixel_value!(LayoutTop);
5342impl_pixel_value!(LayoutBottom);
5343impl_pixel_value!(LayoutRight);
5344impl_pixel_value!(LayoutLeft);
5345
5346#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5348#[repr(C)]
5349pub struct LayoutPaddingTop {
5350 pub inner: PixelValue,
5351}
5352#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5354#[repr(C)]
5355pub struct LayoutPaddingLeft {
5356 pub inner: PixelValue,
5357}
5358#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5360#[repr(C)]
5361pub struct LayoutPaddingRight {
5362 pub inner: PixelValue,
5363}
5364#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5366#[repr(C)]
5367pub struct LayoutPaddingBottom {
5368 pub inner: PixelValue,
5369}
5370
5371impl_pixel_value!(LayoutPaddingTop);
5372impl_pixel_value!(LayoutPaddingBottom);
5373impl_pixel_value!(LayoutPaddingRight);
5374impl_pixel_value!(LayoutPaddingLeft);
5375
5376#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5378#[repr(C)]
5379pub struct LayoutMarginTop {
5380 pub inner: PixelValue,
5381}
5382#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5384#[repr(C)]
5385pub struct LayoutMarginLeft {
5386 pub inner: PixelValue,
5387}
5388#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5390#[repr(C)]
5391pub struct LayoutMarginRight {
5392 pub inner: PixelValue,
5393}
5394#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5396#[repr(C)]
5397pub struct LayoutMarginBottom {
5398 pub inner: PixelValue,
5399}
5400
5401impl_pixel_value!(LayoutMarginTop);
5402impl_pixel_value!(LayoutMarginBottom);
5403impl_pixel_value!(LayoutMarginRight);
5404impl_pixel_value!(LayoutMarginLeft);
5405
5406#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5408#[repr(C)]
5409pub struct LayoutFlexGrow {
5410 pub inner: FloatValue,
5411}
5412
5413impl Default for LayoutFlexGrow {
5414 fn default() -> Self {
5415 LayoutFlexGrow {
5416 inner: FloatValue::const_new(0),
5417 }
5418 }
5419}
5420
5421#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5423#[repr(C)]
5424pub struct LayoutFlexShrink {
5425 pub inner: FloatValue,
5426}
5427
5428impl Default for LayoutFlexShrink {
5429 fn default() -> Self {
5430 LayoutFlexShrink {
5431 inner: FloatValue::const_new(0),
5432 }
5433 }
5434}
5435
5436impl_float_value!(LayoutFlexGrow);
5437impl_float_value!(LayoutFlexShrink);
5438
5439#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5441#[repr(C)]
5442pub enum LayoutFlexDirection {
5443 Row,
5444 RowReverse,
5445 Column,
5446 ColumnReverse,
5447}
5448
5449impl Default for LayoutFlexDirection {
5450 fn default() -> Self {
5451 LayoutFlexDirection::Column
5452 }
5453}
5454
5455impl LayoutFlexDirection {
5456 pub fn get_axis(&self) -> LayoutAxis {
5457 use self::{LayoutAxis::*, LayoutFlexDirection::*};
5458 match self {
5459 Row | RowReverse => Horizontal,
5460 Column | ColumnReverse => Vertical,
5461 }
5462 }
5463
5464 pub fn is_reverse(&self) -> bool {
5466 *self == LayoutFlexDirection::RowReverse || *self == LayoutFlexDirection::ColumnReverse
5467 }
5468}
5469
5470#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5472#[repr(C)]
5473pub enum LayoutBoxSizing {
5474 ContentBox,
5475 BorderBox,
5476}
5477
5478impl Default for LayoutBoxSizing {
5479 fn default() -> Self {
5480 LayoutBoxSizing::ContentBox
5481 }
5482}
5483
5484#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5486#[repr(C)]
5487pub struct StyleLineHeight {
5488 pub inner: PercentageValue,
5489}
5490
5491impl_percentage_value!(StyleLineHeight);
5492
5493impl Default for StyleLineHeight {
5494 fn default() -> Self {
5495 Self {
5496 inner: PercentageValue::const_new(100),
5497 }
5498 }
5499}
5500
5501#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5503#[repr(C)]
5504pub struct StyleTabWidth {
5505 pub inner: PercentageValue,
5506}
5507
5508impl_percentage_value!(StyleTabWidth);
5509
5510impl Default for StyleTabWidth {
5511 fn default() -> Self {
5512 Self {
5513 inner: PercentageValue::const_new(100),
5514 }
5515 }
5516}
5517
5518#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5520#[repr(C)]
5521pub struct StyleLetterSpacing {
5522 pub inner: PixelValue,
5523}
5524
5525impl Default for StyleLetterSpacing {
5526 fn default() -> Self {
5527 Self {
5528 inner: PixelValue::const_px(0),
5529 }
5530 }
5531}
5532
5533impl_pixel_value!(StyleLetterSpacing);
5534
5535#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5537#[repr(C)]
5538pub struct StyleWordSpacing {
5539 pub inner: PixelValue,
5540}
5541
5542impl_pixel_value!(StyleWordSpacing);
5543
5544impl Default for StyleWordSpacing {
5545 fn default() -> Self {
5546 Self {
5547 inner: PixelValue::const_px(0),
5548 }
5549 }
5550}
5551
5552#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5556#[repr(C)]
5557pub enum LayoutAxis {
5558 Horizontal,
5559 Vertical,
5560}
5561
5562#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5564#[repr(C)]
5565pub enum LayoutDisplay {
5566 None,
5567 Flex,
5568 Block,
5569 InlineBlock,
5570}
5571
5572impl Default for LayoutDisplay {
5573 fn default() -> Self {
5574 LayoutDisplay::Flex
5575 }
5576}
5577
5578#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5580#[repr(C)]
5581pub enum LayoutFloat {
5582 Left,
5583 Right,
5584}
5585
5586impl Default for LayoutFloat {
5587 fn default() -> Self {
5588 LayoutFloat::Left
5589 }
5590}
5591
5592#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5596#[repr(C)]
5597pub enum LayoutPosition {
5598 Static,
5599 Relative,
5600 Absolute,
5601 Fixed,
5602}
5603
5604impl LayoutPosition {
5605 pub fn is_positioned(&self) -> bool {
5606 *self != LayoutPosition::Static
5607 }
5608}
5609
5610impl Default for LayoutPosition {
5611 fn default() -> Self {
5612 LayoutPosition::Static
5613 }
5614}
5615
5616#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5618#[repr(C)]
5619pub enum LayoutFlexWrap {
5620 Wrap,
5621 NoWrap,
5622}
5623
5624impl Default for LayoutFlexWrap {
5625 fn default() -> Self {
5626 LayoutFlexWrap::Wrap
5627 }
5628}
5629
5630#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5632#[repr(C)]
5633pub enum LayoutJustifyContent {
5634 Start,
5636 End,
5638 Center,
5640 SpaceBetween,
5642 SpaceAround,
5644 SpaceEvenly,
5647}
5648
5649impl Default for LayoutJustifyContent {
5650 fn default() -> Self {
5651 LayoutJustifyContent::Start
5652 }
5653}
5654
5655#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5657#[repr(C)]
5658pub enum LayoutAlignItems {
5659 Stretch,
5661 Center,
5663 FlexStart,
5665 FlexEnd,
5667}
5668
5669impl Default for LayoutAlignItems {
5670 fn default() -> Self {
5671 LayoutAlignItems::FlexStart
5672 }
5673}
5674
5675#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5677#[repr(C)]
5678pub enum LayoutAlignContent {
5679 Stretch,
5681 Center,
5683 Start,
5685 End,
5687 SpaceBetween,
5689 SpaceAround,
5691}
5692
5693impl Default for LayoutAlignContent {
5694 fn default() -> Self {
5695 LayoutAlignContent::Stretch
5696 }
5697}
5698
5699#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5702#[repr(C)]
5703pub enum LayoutOverflow {
5704 Scroll,
5706 Auto,
5708 Hidden,
5710 Visible,
5712}
5713
5714impl Default for LayoutOverflow {
5715 fn default() -> Self {
5716 LayoutOverflow::Auto
5717 }
5718}
5719
5720impl LayoutOverflow {
5721 pub fn needs_scrollbar(&self, currently_overflowing: bool) -> bool {
5727 use self::LayoutOverflow::*;
5728 match self {
5729 Scroll => true,
5730 Auto => currently_overflowing,
5731 Hidden | Visible => false,
5732 }
5733 }
5734
5735 pub fn is_overflow_visible(&self) -> bool {
5738 *self == LayoutOverflow::Visible
5739 }
5740
5741 pub fn is_overflow_hidden(&self) -> bool {
5742 *self == LayoutOverflow::Hidden
5743 }
5744}
5745
5746#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5748#[repr(C)]
5749pub enum StyleTextAlign {
5750 Left,
5751 Center,
5752 Right,
5753}
5754
5755impl Default for StyleTextAlign {
5756 fn default() -> Self {
5757 StyleTextAlign::Left
5758 }
5759}
5760
5761#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5763#[repr(C)]
5764pub enum StyleVerticalAlign {
5765 Top,
5766 Center,
5767 Bottom,
5768}
5769
5770impl Default for StyleVerticalAlign {
5771 fn default() -> Self {
5772 StyleVerticalAlign::Top
5773 }
5774}
5775
5776#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5778#[repr(C)]
5779pub struct StyleOpacity {
5780 pub inner: PercentageValue,
5781}
5782
5783impl Default for StyleOpacity {
5784 fn default() -> Self {
5785 StyleOpacity {
5786 inner: PercentageValue::const_new(0),
5787 }
5788 }
5789}
5790
5791impl_percentage_value!(StyleOpacity);
5792
5793#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5795#[repr(C)]
5796pub struct StylePerspectiveOrigin {
5797 pub x: PixelValue,
5798 pub y: PixelValue,
5799}
5800
5801impl StylePerspectiveOrigin {
5802 pub fn interpolate(&self, other: &Self, t: f32) -> Self {
5803 Self {
5804 x: self.x.interpolate(&other.x, t),
5805 y: self.y.interpolate(&other.y, t),
5806 }
5807 }
5808}
5809
5810impl Default for StylePerspectiveOrigin {
5811 fn default() -> Self {
5812 StylePerspectiveOrigin {
5813 x: PixelValue::const_px(0),
5814 y: PixelValue::const_px(0),
5815 }
5816 }
5817}
5818
5819#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5821#[repr(C)]
5822pub struct StyleTransformOrigin {
5823 pub x: PixelValue,
5824 pub y: PixelValue,
5825}
5826
5827impl StyleTransformOrigin {
5828 pub fn interpolate(&self, other: &Self, t: f32) -> Self {
5829 Self {
5830 x: self.x.interpolate(&other.x, t),
5831 y: self.y.interpolate(&other.y, t),
5832 }
5833 }
5834}
5835
5836impl Default for StyleTransformOrigin {
5837 fn default() -> Self {
5838 StyleTransformOrigin {
5839 x: PixelValue::const_percent(50),
5840 y: PixelValue::const_percent(50),
5841 }
5842 }
5843}
5844
5845#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5847#[repr(C)]
5848pub enum StyleBackfaceVisibility {
5849 Hidden,
5850 Visible,
5851}
5852
5853impl Default for StyleBackfaceVisibility {
5854 fn default() -> Self {
5855 StyleBackfaceVisibility::Visible
5856 }
5857}
5858
5859#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5861#[repr(C, u8)]
5862pub enum StyleTransform {
5863 Matrix(StyleTransformMatrix2D),
5864 Matrix3D(StyleTransformMatrix3D),
5865 Translate(StyleTransformTranslate2D),
5866 Translate3D(StyleTransformTranslate3D),
5867 TranslateX(PixelValue),
5868 TranslateY(PixelValue),
5869 TranslateZ(PixelValue),
5870 Rotate(AngleValue),
5871 Rotate3D(StyleTransformRotate3D),
5872 RotateX(AngleValue),
5873 RotateY(AngleValue),
5874 RotateZ(AngleValue),
5875 Scale(StyleTransformScale2D),
5876 Scale3D(StyleTransformScale3D),
5877 ScaleX(PercentageValue),
5878 ScaleY(PercentageValue),
5879 ScaleZ(PercentageValue),
5880 Skew(StyleTransformSkew2D),
5881 SkewX(PercentageValue),
5882 SkewY(PercentageValue),
5883 Perspective(PixelValue),
5884}
5885
5886impl_vec!(
5887 StyleTransform,
5888 StyleTransformVec,
5889 StyleTransformVecDestructor
5890);
5891impl_vec_debug!(StyleTransform, StyleTransformVec);
5892impl_vec_partialord!(StyleTransform, StyleTransformVec);
5893impl_vec_ord!(StyleTransform, StyleTransformVec);
5894impl_vec_clone!(
5895 StyleTransform,
5896 StyleTransformVec,
5897 StyleTransformVecDestructor
5898);
5899impl_vec_partialeq!(StyleTransform, StyleTransformVec);
5900impl_vec_eq!(StyleTransform, StyleTransformVec);
5901impl_vec_hash!(StyleTransform, StyleTransformVec);
5902
5903#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5904#[repr(C)]
5905pub struct StyleTransformMatrix2D {
5906 pub a: PixelValue,
5907 pub b: PixelValue,
5908 pub c: PixelValue,
5909 pub d: PixelValue,
5910 pub tx: PixelValue,
5911 pub ty: PixelValue,
5912}
5913
5914#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5915#[repr(C)]
5916pub struct StyleTransformMatrix3D {
5917 pub m11: PixelValue,
5918 pub m12: PixelValue,
5919 pub m13: PixelValue,
5920 pub m14: PixelValue,
5921 pub m21: PixelValue,
5922 pub m22: PixelValue,
5923 pub m23: PixelValue,
5924 pub m24: PixelValue,
5925 pub m31: PixelValue,
5926 pub m32: PixelValue,
5927 pub m33: PixelValue,
5928 pub m34: PixelValue,
5929 pub m41: PixelValue,
5930 pub m42: PixelValue,
5931 pub m43: PixelValue,
5932 pub m44: PixelValue,
5933}
5934
5935#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5936#[repr(C)]
5937pub struct StyleTransformTranslate2D {
5938 pub x: PixelValue,
5939 pub y: PixelValue,
5940}
5941
5942#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5943#[repr(C)]
5944pub struct StyleTransformTranslate3D {
5945 pub x: PixelValue,
5946 pub y: PixelValue,
5947 pub z: PixelValue,
5948}
5949
5950#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5951#[repr(C)]
5952pub struct StyleTransformRotate3D {
5953 pub x: PercentageValue,
5954 pub y: PercentageValue,
5955 pub z: PercentageValue,
5956 pub angle: AngleValue,
5957}
5958
5959#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5960#[repr(C)]
5961pub struct StyleTransformScale2D {
5962 pub x: PercentageValue,
5963 pub y: PercentageValue,
5964}
5965
5966#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5967#[repr(C)]
5968pub struct StyleTransformScale3D {
5969 pub x: PercentageValue,
5970 pub y: PercentageValue,
5971 pub z: PercentageValue,
5972}
5973
5974#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5975#[repr(C)]
5976pub struct StyleTransformSkew2D {
5977 pub x: PercentageValue,
5978 pub y: PercentageValue,
5979}
5980
5981pub type StyleBackgroundContentVecValue = CssPropertyValue<StyleBackgroundContentVec>;
5982pub type StyleBackgroundPositionVecValue = CssPropertyValue<StyleBackgroundPositionVec>;
5983pub type StyleBackgroundSizeVecValue = CssPropertyValue<StyleBackgroundSizeVec>;
5984pub type StyleBackgroundRepeatVecValue = CssPropertyValue<StyleBackgroundRepeatVec>;
5985pub type StyleFontSizeValue = CssPropertyValue<StyleFontSize>;
5986pub type StyleFontFamilyVecValue = CssPropertyValue<StyleFontFamilyVec>;
5987pub type StyleTextColorValue = CssPropertyValue<StyleTextColor>;
5988pub type StyleTextAlignValue = CssPropertyValue<StyleTextAlign>;
5989pub type StyleLineHeightValue = CssPropertyValue<StyleLineHeight>;
5990pub type StyleLetterSpacingValue = CssPropertyValue<StyleLetterSpacing>;
5991pub type StyleWordSpacingValue = CssPropertyValue<StyleWordSpacing>;
5992pub type StyleTabWidthValue = CssPropertyValue<StyleTabWidth>;
5993pub type StyleCursorValue = CssPropertyValue<StyleCursor>;
5994pub type StyleBoxShadowValue = CssPropertyValue<StyleBoxShadow>;
5995pub type StyleBorderTopColorValue = CssPropertyValue<StyleBorderTopColor>;
5996pub type StyleBorderLeftColorValue = CssPropertyValue<StyleBorderLeftColor>;
5997pub type StyleBorderRightColorValue = CssPropertyValue<StyleBorderRightColor>;
5998pub type StyleBorderBottomColorValue = CssPropertyValue<StyleBorderBottomColor>;
5999pub type StyleBorderTopStyleValue = CssPropertyValue<StyleBorderTopStyle>;
6000pub type StyleBorderLeftStyleValue = CssPropertyValue<StyleBorderLeftStyle>;
6001pub type StyleBorderRightStyleValue = CssPropertyValue<StyleBorderRightStyle>;
6002pub type StyleBorderBottomStyleValue = CssPropertyValue<StyleBorderBottomStyle>;
6003pub type StyleBorderTopLeftRadiusValue = CssPropertyValue<StyleBorderTopLeftRadius>;
6004pub type StyleBorderTopRightRadiusValue = CssPropertyValue<StyleBorderTopRightRadius>;
6005pub type StyleBorderBottomLeftRadiusValue = CssPropertyValue<StyleBorderBottomLeftRadius>;
6006pub type StyleBorderBottomRightRadiusValue = CssPropertyValue<StyleBorderBottomRightRadius>;
6007pub type StyleOpacityValue = CssPropertyValue<StyleOpacity>;
6008pub type StyleTransformVecValue = CssPropertyValue<StyleTransformVec>;
6009pub type StyleTransformOriginValue = CssPropertyValue<StyleTransformOrigin>;
6010pub type StylePerspectiveOriginValue = CssPropertyValue<StylePerspectiveOrigin>;
6011pub type StyleBackfaceVisibilityValue = CssPropertyValue<StyleBackfaceVisibility>;
6012pub type StyleMixBlendModeValue = CssPropertyValue<StyleMixBlendMode>;
6013pub type StyleFilterVecValue = CssPropertyValue<StyleFilterVec>;
6014pub type ScrollbarStyleValue = CssPropertyValue<ScrollbarStyle>;
6015pub type LayoutDisplayValue = CssPropertyValue<LayoutDisplay>;
6016impl_option!(
6017 LayoutDisplayValue,
6018 OptionLayoutDisplayValue,
6019 copy = false,
6020 [Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
6021);
6022pub type LayoutFloatValue = CssPropertyValue<LayoutFloat>;
6023impl_option!(
6024 LayoutFloatValue,
6025 OptionLayoutFloatValue,
6026 copy = false,
6027 [Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
6028);
6029pub type LayoutBoxSizingValue = CssPropertyValue<LayoutBoxSizing>;
6030impl_option!(
6031 LayoutBoxSizingValue,
6032 OptionLayoutBoxSizingValue,
6033 copy = false,
6034 [Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
6035);
6036pub type LayoutWidthValue = CssPropertyValue<LayoutWidth>;
6037impl_option!(
6038 LayoutWidthValue,
6039 OptionLayoutWidthValue,
6040 copy = false,
6041 [Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
6042);
6043pub type LayoutHeightValue = CssPropertyValue<LayoutHeight>;
6044impl_option!(
6045 LayoutHeightValue,
6046 OptionLayoutHeightValue,
6047 copy = false,
6048 [Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
6049);
6050pub type LayoutMinWidthValue = CssPropertyValue<LayoutMinWidth>;
6051impl_option!(
6052 LayoutMinWidthValue,
6053 OptionLayoutMinWidthValue,
6054 copy = false,
6055 [Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
6056);
6057pub type LayoutMinHeightValue = CssPropertyValue<LayoutMinHeight>;
6058impl_option!(
6059 LayoutMinHeightValue,
6060 OptionLayoutMinHeightValue,
6061 copy = false,
6062 [Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
6063);
6064pub type LayoutMaxWidthValue = CssPropertyValue<LayoutMaxWidth>;
6065impl_option!(
6066 LayoutMaxWidthValue,
6067 OptionLayoutMaxWidthValue,
6068 copy = false,
6069 [Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
6070);
6071pub type LayoutMaxHeightValue = CssPropertyValue<LayoutMaxHeight>;
6072impl_option!(
6073 LayoutMaxHeightValue,
6074 OptionLayoutMaxHeightValue,
6075 copy = false,
6076 [Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
6077);
6078pub type LayoutPositionValue = CssPropertyValue<LayoutPosition>;
6079impl_option!(
6080 LayoutPositionValue,
6081 OptionLayoutPositionValue,
6082 copy = false,
6083 [Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
6084);
6085pub type LayoutTopValue = CssPropertyValue<LayoutTop>;
6086impl_option!(
6087 LayoutTopValue,
6088 OptionLayoutTopValue,
6089 copy = false,
6090 [Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
6091);
6092pub type LayoutBottomValue = CssPropertyValue<LayoutBottom>;
6093impl_option!(
6094 LayoutBottomValue,
6095 OptionLayoutBottomValue,
6096 copy = false,
6097 [Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
6098);
6099pub type LayoutRightValue = CssPropertyValue<LayoutRight>;
6100impl_option!(
6101 LayoutRightValue,
6102 OptionLayoutRightValue,
6103 copy = false,
6104 [Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
6105);
6106pub type LayoutLeftValue = CssPropertyValue<LayoutLeft>;
6107impl_option!(
6108 LayoutLeftValue,
6109 OptionLayoutLeftValue,
6110 copy = false,
6111 [Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
6112);
6113pub type LayoutPaddingTopValue = CssPropertyValue<LayoutPaddingTop>;
6114impl_option!(
6115 LayoutPaddingTopValue,
6116 OptionLayoutPaddingTopValue,
6117 copy = false,
6118 [Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
6119);
6120pub type LayoutPaddingBottomValue = CssPropertyValue<LayoutPaddingBottom>;
6121impl_option!(
6122 LayoutPaddingBottomValue,
6123 OptionLayoutPaddingBottomValue,
6124 copy = false,
6125 [Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
6126);
6127pub type LayoutPaddingLeftValue = CssPropertyValue<LayoutPaddingLeft>;
6128impl_option!(
6129 LayoutPaddingLeftValue,
6130 OptionLayoutPaddingLeftValue,
6131 copy = false,
6132 [Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
6133);
6134pub type LayoutPaddingRightValue = CssPropertyValue<LayoutPaddingRight>;
6135impl_option!(
6136 LayoutPaddingRightValue,
6137 OptionLayoutPaddingRightValue,
6138 copy = false,
6139 [Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
6140);
6141pub type LayoutMarginTopValue = CssPropertyValue<LayoutMarginTop>;
6142impl_option!(
6143 LayoutMarginTopValue,
6144 OptionLayoutMarginTopValue,
6145 copy = false,
6146 [Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
6147);
6148pub type LayoutMarginBottomValue = CssPropertyValue<LayoutMarginBottom>;
6149impl_option!(
6150 LayoutMarginBottomValue,
6151 OptionLayoutMarginBottomValue,
6152 copy = false,
6153 [Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
6154);
6155pub type LayoutMarginLeftValue = CssPropertyValue<LayoutMarginLeft>;
6156impl_option!(
6157 LayoutMarginLeftValue,
6158 OptionLayoutMarginLeftValue,
6159 copy = false,
6160 [Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
6161);
6162pub type LayoutMarginRightValue = CssPropertyValue<LayoutMarginRight>;
6163impl_option!(
6164 LayoutMarginRightValue,
6165 OptionLayoutMarginRightValue,
6166 copy = false,
6167 [Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
6168);
6169pub type LayoutBorderTopWidthValue = CssPropertyValue<LayoutBorderTopWidth>;
6170pub type LayoutBorderLeftWidthValue = CssPropertyValue<LayoutBorderLeftWidth>;
6171pub type LayoutBorderRightWidthValue = CssPropertyValue<LayoutBorderRightWidth>;
6172pub type LayoutBorderBottomWidthValue = CssPropertyValue<LayoutBorderBottomWidth>;
6173pub type LayoutOverflowValue = CssPropertyValue<LayoutOverflow>;
6174impl_option!(
6175 LayoutOverflowValue,
6176 OptionLayoutOverflowValue,
6177 copy = false,
6178 [Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
6179);
6180pub type LayoutFlexDirectionValue = CssPropertyValue<LayoutFlexDirection>;
6181impl_option!(
6182 LayoutFlexDirectionValue,
6183 OptionLayoutFlexDirectionValue,
6184 copy = false,
6185 [Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
6186);
6187pub type LayoutFlexWrapValue = CssPropertyValue<LayoutFlexWrap>;
6188impl_option!(
6189 LayoutFlexWrapValue,
6190 OptionLayoutFlexWrapValue,
6191 copy = false,
6192 [Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
6193);
6194pub type LayoutFlexGrowValue = CssPropertyValue<LayoutFlexGrow>;
6195impl_option!(
6196 LayoutFlexGrowValue,
6197 OptionLayoutFlexGrowValue,
6198 copy = false,
6199 [Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
6200);
6201pub type LayoutFlexShrinkValue = CssPropertyValue<LayoutFlexShrink>;
6202impl_option!(
6203 LayoutFlexShrinkValue,
6204 OptionLayoutFlexShrinkValue,
6205 copy = false,
6206 [Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
6207);
6208pub type LayoutJustifyContentValue = CssPropertyValue<LayoutJustifyContent>;
6209impl_option!(
6210 LayoutJustifyContentValue,
6211 OptionLayoutJustifyContentValue,
6212 copy = false,
6213 [Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
6214);
6215pub type LayoutAlignItemsValue = CssPropertyValue<LayoutAlignItems>;
6216impl_option!(
6217 LayoutAlignItemsValue,
6218 OptionLayoutAlignItemsValue,
6219 copy = false,
6220 [Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
6221);
6222pub type LayoutAlignContentValue = CssPropertyValue<LayoutAlignContent>;
6223impl_option!(
6224 LayoutAlignContentValue,
6225 OptionLayoutAlignContentValue,
6226 copy = false,
6227 [Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
6228);
6229
6230#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
6232#[repr(C)]
6233pub struct ScrollbarInfo {
6234 pub width: LayoutWidth,
6236 pub padding_left: LayoutPaddingLeft,
6239 pub padding_right: LayoutPaddingRight,
6241 pub track: StyleBackgroundContent,
6245 pub thumb: StyleBackgroundContent,
6247 pub button: StyleBackgroundContent,
6249 pub corner: StyleBackgroundContent,
6252 pub resizer: StyleBackgroundContent,
6255}
6256
6257impl Default for ScrollbarInfo {
6258 fn default() -> Self {
6259 ScrollbarInfo {
6260 width: LayoutWidth::px(17.0),
6261 padding_left: LayoutPaddingLeft::px(2.0),
6262 padding_right: LayoutPaddingRight::px(2.0),
6263 track: StyleBackgroundContent::Color(ColorU {
6264 r: 241,
6265 g: 241,
6266 b: 241,
6267 a: 255,
6268 }),
6269 thumb: StyleBackgroundContent::Color(ColorU {
6270 r: 193,
6271 g: 193,
6272 b: 193,
6273 a: 255,
6274 }),
6275 button: StyleBackgroundContent::Color(ColorU {
6276 r: 163,
6277 g: 163,
6278 b: 163,
6279 a: 255,
6280 }),
6281 corner: StyleBackgroundContent::default(),
6282 resizer: StyleBackgroundContent::default(),
6283 }
6284 }
6285}
6286
6287#[derive(Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
6289#[repr(C)]
6290pub struct ScrollbarStyle {
6291 pub horizontal: ScrollbarInfo,
6293 pub vertical: ScrollbarInfo,
6295}
6296
6297#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
6299#[repr(C)]
6300pub struct StyleFontSize {
6301 pub inner: PixelValue,
6302}
6303
6304impl Default for StyleFontSize {
6305 fn default() -> Self {
6306 Self {
6307 inner: PixelValue::const_em(1),
6308 }
6309 }
6310}
6311
6312impl_pixel_value!(StyleFontSize);
6313
6314#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
6315#[repr(C)]
6316pub struct FontMetrics {
6317 pub units_per_em: u16,
6319 pub font_flags: u16,
6320 pub x_min: i16,
6321 pub y_min: i16,
6322 pub x_max: i16,
6323 pub y_max: i16,
6324
6325 pub ascender: i16,
6327 pub descender: i16,
6328 pub line_gap: i16,
6329 pub advance_width_max: u16,
6330 pub min_left_side_bearing: i16,
6331 pub min_right_side_bearing: i16,
6332 pub x_max_extent: i16,
6333 pub caret_slope_rise: i16,
6334 pub caret_slope_run: i16,
6335 pub caret_offset: i16,
6336 pub num_h_metrics: u16,
6337
6338 pub x_avg_char_width: i16,
6340 pub us_weight_class: u16,
6341 pub us_width_class: u16,
6342 pub fs_type: u16,
6343 pub y_subscript_x_size: i16,
6344 pub y_subscript_y_size: i16,
6345 pub y_subscript_x_offset: i16,
6346 pub y_subscript_y_offset: i16,
6347 pub y_superscript_x_size: i16,
6348 pub y_superscript_y_size: i16,
6349 pub y_superscript_x_offset: i16,
6350 pub y_superscript_y_offset: i16,
6351 pub y_strikeout_size: i16,
6352 pub y_strikeout_position: i16,
6353 pub s_family_class: i16,
6354 pub panose: [u8; 10],
6355 pub ul_unicode_range1: u32,
6356 pub ul_unicode_range2: u32,
6357 pub ul_unicode_range3: u32,
6358 pub ul_unicode_range4: u32,
6359 pub ach_vend_id: u32,
6360 pub fs_selection: u16,
6361 pub us_first_char_index: u16,
6362 pub us_last_char_index: u16,
6363
6364 pub s_typo_ascender: OptionI16,
6366 pub s_typo_descender: OptionI16,
6367 pub s_typo_line_gap: OptionI16,
6368 pub us_win_ascent: OptionU16,
6369 pub us_win_descent: OptionU16,
6370
6371 pub ul_code_page_range1: OptionU32,
6373 pub ul_code_page_range2: OptionU32,
6374
6375 pub sx_height: OptionI16,
6377 pub s_cap_height: OptionI16,
6378 pub us_default_char: OptionU16,
6379 pub us_break_char: OptionU16,
6380 pub us_max_context: OptionU16,
6381
6382 pub us_lower_optical_point_size: OptionU16,
6384 pub us_upper_optical_point_size: OptionU16,
6385}
6386
6387impl Default for FontMetrics {
6388 fn default() -> Self {
6389 FontMetrics::zero()
6390 }
6391}
6392
6393impl FontMetrics {
6394 pub const fn zero() -> Self {
6397 FontMetrics {
6398 units_per_em: 1000,
6399 font_flags: 0,
6400 x_min: 0,
6401 y_min: 0,
6402 x_max: 0,
6403 y_max: 0,
6404 ascender: 0,
6405 descender: 0,
6406 line_gap: 0,
6407 advance_width_max: 0,
6408 min_left_side_bearing: 0,
6409 min_right_side_bearing: 0,
6410 x_max_extent: 0,
6411 caret_slope_rise: 0,
6412 caret_slope_run: 0,
6413 caret_offset: 0,
6414 num_h_metrics: 0,
6415 x_avg_char_width: 0,
6416 us_weight_class: 0,
6417 us_width_class: 0,
6418 fs_type: 0,
6419 y_subscript_x_size: 0,
6420 y_subscript_y_size: 0,
6421 y_subscript_x_offset: 0,
6422 y_subscript_y_offset: 0,
6423 y_superscript_x_size: 0,
6424 y_superscript_y_size: 0,
6425 y_superscript_x_offset: 0,
6426 y_superscript_y_offset: 0,
6427 y_strikeout_size: 0,
6428 y_strikeout_position: 0,
6429 s_family_class: 0,
6430 panose: [0; 10],
6431 ul_unicode_range1: 0,
6432 ul_unicode_range2: 0,
6433 ul_unicode_range3: 0,
6434 ul_unicode_range4: 0,
6435 ach_vend_id: 0,
6436 fs_selection: 0,
6437 us_first_char_index: 0,
6438 us_last_char_index: 0,
6439 s_typo_ascender: OptionI16::None,
6440 s_typo_descender: OptionI16::None,
6441 s_typo_line_gap: OptionI16::None,
6442 us_win_ascent: OptionU16::None,
6443 us_win_descent: OptionU16::None,
6444 ul_code_page_range1: OptionU32::None,
6445 ul_code_page_range2: OptionU32::None,
6446 sx_height: OptionI16::None,
6447 s_cap_height: OptionI16::None,
6448 us_default_char: OptionU16::None,
6449 us_break_char: OptionU16::None,
6450 us_max_context: OptionU16::None,
6451 us_lower_optical_point_size: OptionU16::None,
6452 us_upper_optical_point_size: OptionU16::None,
6453 }
6454 }
6455
6456 pub fn use_typo_metrics(&self) -> bool {
6461 self.fs_selection & (1 << 7) != 0
6462 }
6463
6464 pub fn get_ascender_unscaled(&self) -> i16 {
6465 let use_typo = if !self.use_typo_metrics() {
6466 None
6467 } else {
6468 self.s_typo_ascender.into()
6469 };
6470 match use_typo {
6471 Some(s) => s,
6472 None => self.ascender,
6473 }
6474 }
6475
6476 pub fn get_descender_unscaled(&self) -> i16 {
6478 let use_typo = if !self.use_typo_metrics() {
6479 None
6480 } else {
6481 self.s_typo_descender.into()
6482 };
6483 match use_typo {
6484 Some(s) => s,
6485 None => self.descender,
6486 }
6487 }
6488
6489 pub fn get_line_gap_unscaled(&self) -> i16 {
6490 let use_typo = if !self.use_typo_metrics() {
6491 None
6492 } else {
6493 self.s_typo_line_gap.into()
6494 };
6495 match use_typo {
6496 Some(s) => s,
6497 None => self.line_gap,
6498 }
6499 }
6500
6501 pub fn get_ascender(&self, target_font_size: f32) -> f32 {
6502 self.get_ascender_unscaled() as f32 / self.units_per_em as f32 * target_font_size
6503 }
6504 pub fn get_descender(&self, target_font_size: f32) -> f32 {
6505 self.get_descender_unscaled() as f32 / self.units_per_em as f32 * target_font_size
6506 }
6507 pub fn get_line_gap(&self, target_font_size: f32) -> f32 {
6508 self.get_line_gap_unscaled() as f32 / self.units_per_em as f32 * target_font_size
6509 }
6510
6511 pub fn get_x_min(&self, target_font_size: f32) -> f32 {
6512 self.x_min as f32 / self.units_per_em as f32 * target_font_size
6513 }
6514 pub fn get_y_min(&self, target_font_size: f32) -> f32 {
6515 self.y_min as f32 / self.units_per_em as f32 * target_font_size
6516 }
6517 pub fn get_x_max(&self, target_font_size: f32) -> f32 {
6518 self.x_max as f32 / self.units_per_em as f32 * target_font_size
6519 }
6520 pub fn get_y_max(&self, target_font_size: f32) -> f32 {
6521 self.y_max as f32 / self.units_per_em as f32 * target_font_size
6522 }
6523 pub fn get_advance_width_max(&self, target_font_size: f32) -> f32 {
6524 self.advance_width_max as f32 / self.units_per_em as f32 * target_font_size
6525 }
6526 pub fn get_min_left_side_bearing(&self, target_font_size: f32) -> f32 {
6527 self.min_left_side_bearing as f32 / self.units_per_em as f32 * target_font_size
6528 }
6529 pub fn get_min_right_side_bearing(&self, target_font_size: f32) -> f32 {
6530 self.min_right_side_bearing as f32 / self.units_per_em as f32 * target_font_size
6531 }
6532 pub fn get_x_max_extent(&self, target_font_size: f32) -> f32 {
6533 self.x_max_extent as f32 / self.units_per_em as f32 * target_font_size
6534 }
6535 pub fn get_x_avg_char_width(&self, target_font_size: f32) -> f32 {
6536 self.x_avg_char_width as f32 / self.units_per_em as f32 * target_font_size
6537 }
6538 pub fn get_y_subscript_x_size(&self, target_font_size: f32) -> f32 {
6539 self.y_subscript_x_size as f32 / self.units_per_em as f32 * target_font_size
6540 }
6541 pub fn get_y_subscript_y_size(&self, target_font_size: f32) -> f32 {
6542 self.y_subscript_y_size as f32 / self.units_per_em as f32 * target_font_size
6543 }
6544 pub fn get_y_subscript_x_offset(&self, target_font_size: f32) -> f32 {
6545 self.y_subscript_x_offset as f32 / self.units_per_em as f32 * target_font_size
6546 }
6547 pub fn get_y_subscript_y_offset(&self, target_font_size: f32) -> f32 {
6548 self.y_subscript_y_offset as f32 / self.units_per_em as f32 * target_font_size
6549 }
6550 pub fn get_y_superscript_x_size(&self, target_font_size: f32) -> f32 {
6551 self.y_superscript_x_size as f32 / self.units_per_em as f32 * target_font_size
6552 }
6553 pub fn get_y_superscript_y_size(&self, target_font_size: f32) -> f32 {
6554 self.y_superscript_y_size as f32 / self.units_per_em as f32 * target_font_size
6555 }
6556 pub fn get_y_superscript_x_offset(&self, target_font_size: f32) -> f32 {
6557 self.y_superscript_x_offset as f32 / self.units_per_em as f32 * target_font_size
6558 }
6559 pub fn get_y_superscript_y_offset(&self, target_font_size: f32) -> f32 {
6560 self.y_superscript_y_offset as f32 / self.units_per_em as f32 * target_font_size
6561 }
6562 pub fn get_y_strikeout_size(&self, target_font_size: f32) -> f32 {
6563 self.y_strikeout_size as f32 / self.units_per_em as f32 * target_font_size
6564 }
6565 pub fn get_y_strikeout_position(&self, target_font_size: f32) -> f32 {
6566 self.y_strikeout_position as f32 / self.units_per_em as f32 * target_font_size
6567 }
6568
6569 pub fn get_s_typo_ascender(&self, target_font_size: f32) -> Option<f32> {
6570 self.s_typo_ascender
6571 .map(|s| s as f32 / self.units_per_em as f32 * target_font_size)
6572 }
6573 pub fn get_s_typo_descender(&self, target_font_size: f32) -> Option<f32> {
6574 self.s_typo_descender
6575 .map(|s| s as f32 / self.units_per_em as f32 * target_font_size)
6576 }
6577 pub fn get_s_typo_line_gap(&self, target_font_size: f32) -> Option<f32> {
6578 self.s_typo_line_gap
6579 .map(|s| s as f32 / self.units_per_em as f32 * target_font_size)
6580 }
6581 pub fn get_us_win_ascent(&self, target_font_size: f32) -> Option<f32> {
6582 self.us_win_ascent
6583 .map(|s| s as f32 / self.units_per_em as f32 * target_font_size)
6584 }
6585 pub fn get_us_win_descent(&self, target_font_size: f32) -> Option<f32> {
6586 self.us_win_descent
6587 .map(|s| s as f32 / self.units_per_em as f32 * target_font_size)
6588 }
6589 pub fn get_sx_height(&self, target_font_size: f32) -> Option<f32> {
6590 self.sx_height
6591 .map(|s| s as f32 / self.units_per_em as f32 * target_font_size)
6592 }
6593 pub fn get_s_cap_height(&self, target_font_size: f32) -> Option<f32> {
6594 self.s_cap_height
6595 .map(|s| s as f32 / self.units_per_em as f32 * target_font_size)
6596 }
6597}
6598
6599#[repr(C)]
6600pub struct FontRef {
6601 pub data: *const FontData,
6603 pub copies: *const AtomicUsize,
6605 pub run_destructor: bool,
6606}
6607
6608impl fmt::Debug for FontRef {
6609 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6610 write!(f, "printing FontRef 0x{:0x}", self.data as usize)?;
6611 if let Some(d) = unsafe { self.data.as_ref() } {
6612 d.fmt(f)?;
6613 }
6614 if let Some(c) = unsafe { self.copies.as_ref() } {
6615 c.fmt(f)?;
6616 }
6617 Ok(())
6618 }
6619}
6620
6621impl FontRef {
6622 #[inline]
6623 pub fn get_data<'a>(&'a self) -> &'a FontData {
6624 unsafe { &*self.data }
6625 }
6626}
6627
6628impl_option!(
6629 FontRef,
6630 OptionFontRef,
6631 copy = false,
6632 [Debug, Clone, PartialEq, Eq, Hash]
6633);
6634
6635unsafe impl Send for FontRef {}
6636unsafe impl Sync for FontRef {}
6637
6638impl PartialEq for FontRef {
6639 fn eq(&self, rhs: &Self) -> bool {
6640 self.data as usize == rhs.data as usize
6641 }
6642}
6643
6644impl PartialOrd for FontRef {
6645 fn partial_cmp(&self, other: &Self) -> Option<::core::cmp::Ordering> {
6646 Some((self.data as usize).cmp(&(other.data as usize)))
6647 }
6648}
6649
6650impl Ord for FontRef {
6651 fn cmp(&self, other: &Self) -> Ordering {
6652 let self_data = self.data as usize;
6653 let other_data = other.data as usize;
6654 self_data.cmp(&other_data)
6655 }
6656}
6657
6658impl Eq for FontRef {}
6659
6660impl Hash for FontRef {
6661 fn hash<H>(&self, state: &mut H)
6662 where
6663 H: Hasher,
6664 {
6665 let self_data = self.data as usize;
6666 self_data.hash(state)
6667 }
6668}
6669
6670impl FontRef {
6671 pub fn new(data: FontData) -> Self {
6672 Self {
6673 data: Box::into_raw(Box::new(data)),
6674 copies: Box::into_raw(Box::new(AtomicUsize::new(1))),
6675 run_destructor: true,
6676 }
6677 }
6678 pub fn get_bytes(&self) -> U8Vec {
6679 self.get_data().bytes.clone()
6680 }
6681}
6682
6683impl Clone for FontRef {
6684 fn clone(&self) -> Self {
6685 unsafe {
6686 self.copies
6687 .as_ref()
6688 .map(|f| f.fetch_add(1, AtomicOrdering::SeqCst));
6689 }
6690 Self {
6691 data: self.data, copies: self.copies, run_destructor: true,
6694 }
6695 }
6696}
6697
6698impl Drop for FontRef {
6699 fn drop(&mut self) {
6700 self.run_destructor = false;
6701 unsafe {
6702 let copies = unsafe { (*self.copies).fetch_sub(1, AtomicOrdering::SeqCst) };
6703 if copies == 1 {
6704 let _ = Box::from_raw(self.data as *mut FontData);
6705 let _ = Box::from_raw(self.copies as *mut AtomicUsize);
6706 }
6707 }
6708 }
6709}
6710
6711pub struct FontData {
6712 pub bytes: U8Vec,
6715 pub font_index: u32,
6718 pub parsed: *const c_void, pub parsed_destructor: fn(*mut c_void),
6722}
6723
6724impl fmt::Debug for FontData {
6725 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6726 write!(f, "FontData: {{");
6727 " bytes: ".fmt(f)?;
6728 self.bytes.len().fmt(f)?;
6729 " font_index: ".fmt(f)?;
6730 write!(f, "}}")?;
6731 Ok(())
6732 }
6733}
6734
6735unsafe impl Send for FontData {}
6736unsafe impl Sync for FontData {}
6737
6738impl Drop for FontData {
6739 fn drop(&mut self) {
6740 (self.parsed_destructor)(self.parsed as *mut c_void)
6742 }
6743}
6744
6745#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
6747#[repr(C, u8)]
6748pub enum StyleFontFamily {
6749 System(AzString),
6751 File(AzString),
6753 Ref(FontRef),
6756}
6757
6758impl StyleFontFamily {
6759 pub(crate) fn as_string(&self) -> String {
6760 match &self {
6761 StyleFontFamily::System(s) => s.clone().into_library_owned_string(),
6762 StyleFontFamily::File(s) => s.clone().into_library_owned_string(),
6763 StyleFontFamily::Ref(s) => format!("{:0x}", s.data as usize),
6764 }
6765 }
6766}
6767
6768impl_vec!(
6769 StyleFontFamily,
6770 StyleFontFamilyVec,
6771 StyleFontFamilyVecDestructor
6772);
6773impl_vec_clone!(
6774 StyleFontFamily,
6775 StyleFontFamilyVec,
6776 StyleFontFamilyVecDestructor
6777);
6778impl_vec_debug!(StyleFontFamily, StyleFontFamilyVec);
6779impl_vec_eq!(StyleFontFamily, StyleFontFamilyVec);
6780impl_vec_ord!(StyleFontFamily, StyleFontFamilyVec);
6781impl_vec_hash!(StyleFontFamily, StyleFontFamilyVec);
6782impl_vec_partialeq!(StyleFontFamily, StyleFontFamilyVec);
6783impl_vec_partialord!(StyleFontFamily, StyleFontFamilyVec);
6784
6785#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
6786#[repr(C)]
6787pub enum StyleMixBlendMode {
6788 Normal,
6789 Multiply,
6790 Screen,
6791 Overlay,
6792 Darken,
6793 Lighten,
6794 ColorDodge,
6795 ColorBurn,
6796 HardLight,
6797 SoftLight,
6798 Difference,
6799 Exclusion,
6800 Hue,
6801 Saturation,
6802 Color,
6803 Luminosity,
6804}
6805
6806impl Default for StyleMixBlendMode {
6807 fn default() -> StyleMixBlendMode {
6808 StyleMixBlendMode::Normal
6809 }
6810}
6811
6812impl fmt::Display for StyleMixBlendMode {
6813 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6814 use self::StyleMixBlendMode::*;
6815 write!(
6816 f,
6817 "{}",
6818 match self {
6819 Normal => "normal",
6820 Multiply => "multiply",
6821 Screen => "screen",
6822 Overlay => "overlay",
6823 Darken => "darken",
6824 Lighten => "lighten",
6825 ColorDodge => "color-dodge",
6826 ColorBurn => "color-burn",
6827 HardLight => "hard-light",
6828 SoftLight => "soft-light",
6829 Difference => "difference",
6830 Exclusion => "exclusion",
6831 Hue => "hue",
6832 Saturation => "saturation",
6833 Color => "color",
6834 Luminosity => "luminosity",
6835 }
6836 )
6837 }
6838}
6839
6840#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
6841#[repr(C, u8)]
6842pub enum StyleFilter {
6843 Blend(StyleMixBlendMode),
6844 Flood(ColorU),
6845 Blur(StyleBlur),
6846 Opacity(PercentageValue),
6847 ColorMatrix(StyleColorMatrix),
6848 DropShadow(StyleBoxShadow),
6849 ComponentTransfer,
6850 Offset(StyleFilterOffset),
6851 Composite(StyleCompositeFilter),
6852}
6853
6854impl_vec!(StyleFilter, StyleFilterVec, StyleFilterVecDestructor);
6855impl_vec_clone!(StyleFilter, StyleFilterVec, StyleFilterVecDestructor);
6856impl_vec_debug!(StyleFilter, StyleFilterVec);
6857impl_vec_eq!(StyleFilter, StyleFilterVec);
6858impl_vec_ord!(StyleFilter, StyleFilterVec);
6859impl_vec_hash!(StyleFilter, StyleFilterVec);
6860impl_vec_partialeq!(StyleFilter, StyleFilterVec);
6861impl_vec_partialord!(StyleFilter, StyleFilterVec);
6862
6863#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
6864#[repr(C)]
6865pub struct StyleBlur {
6866 pub width: PixelValue,
6867 pub height: PixelValue,
6868}
6869
6870#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
6871#[repr(C)]
6872pub struct StyleColorMatrix {
6873 pub matrix: [FloatValue; 20],
6874}
6875#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
6876#[repr(C)]
6877pub struct StyleFilterOffset {
6878 pub x: PixelValue,
6879 pub y: PixelValue,
6880}
6881
6882#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
6883#[repr(C, u8)]
6884pub enum StyleCompositeFilter {
6885 Over,
6886 In,
6887 Atop,
6888 Out,
6889 Xor,
6890 Lighter,
6891 Arithmetic([FloatValue; 4]),
6892}