1use std::collections::BTreeMap;
4use std::fmt;
5use crate::css::CssPropertyValue;
6
7pub trait FormatAsCssValue {
8 fn format_as_css_value(&self, f: &mut fmt::Formatter) -> fmt::Result;
9}
10
11pub const EM_HEIGHT: f32 = 16.0;
13pub const PT_TO_PX: f32 = 96.0 / 72.0;
14
15const COMBINED_CSS_PROPERTIES_KEY_MAP: [(CombinedCssPropertyType, &'static str);10] = [
16 (CombinedCssPropertyType::BorderRadius, "border-radius"),
17 (CombinedCssPropertyType::Overflow, "overflow"),
18 (CombinedCssPropertyType::Padding, "padding"),
19 (CombinedCssPropertyType::Margin, "margin"),
20 (CombinedCssPropertyType::Border, "border"),
21 (CombinedCssPropertyType::BorderLeft, "border-left"),
22 (CombinedCssPropertyType::BorderRight, "border-right"),
23 (CombinedCssPropertyType::BorderTop, "border-top"),
24 (CombinedCssPropertyType::BorderBottom, "border-bottom"),
25 (CombinedCssPropertyType::BoxShadow, "box-shadow"),
26];
27
28const CSS_PROPERTY_KEY_MAP: [(CssPropertyType, &'static str);66] = [
30
31 (CssPropertyType::Display, "display"),
32 (CssPropertyType::Float, "float"),
33 (CssPropertyType::BoxSizing, "box-sizing"),
34
35 (CssPropertyType::TextColor, "color"),
36 (CssPropertyType::FontSize, "font-size"),
37 (CssPropertyType::FontFamily, "font-family"),
38 (CssPropertyType::TextAlign, "text-align"),
39
40 (CssPropertyType::LetterSpacing, "letter-spacing"),
41 (CssPropertyType::LineHeight, "line-height"),
42 (CssPropertyType::WordSpacing, "word-spacing"),
43 (CssPropertyType::TabWidth, "tab-width"),
44 (CssPropertyType::Cursor, "cursor"),
45
46 (CssPropertyType::Width, "width"),
47 (CssPropertyType::Height, "height"),
48 (CssPropertyType::MinWidth, "min-width"),
49 (CssPropertyType::MinHeight, "min-height"),
50 (CssPropertyType::MaxWidth, "max-width"),
51 (CssPropertyType::MaxHeight, "max-height"),
52
53 (CssPropertyType::Position, "position"),
54 (CssPropertyType::Top, "top"),
55 (CssPropertyType::Right, "right"),
56 (CssPropertyType::Left, "left"),
57 (CssPropertyType::Bottom, "bottom"),
58
59 (CssPropertyType::FlexWrap, "flex-wrap"),
60 (CssPropertyType::FlexDirection, "flex-direction"),
61 (CssPropertyType::FlexGrow, "flex-grow"),
62 (CssPropertyType::FlexShrink, "flex-shrink"),
63 (CssPropertyType::JustifyContent, "justify-content"),
64 (CssPropertyType::AlignItems, "align-items"),
65 (CssPropertyType::AlignContent, "align-content"),
66
67 (CssPropertyType::OverflowX, "overflow-x"),
68 (CssPropertyType::OverflowY, "overflow-y"),
69
70 (CssPropertyType::PaddingTop, "padding-top"),
71 (CssPropertyType::PaddingLeft, "padding-left"),
72 (CssPropertyType::PaddingRight, "padding-right"),
73 (CssPropertyType::PaddingBottom, "padding-bottom"),
74
75 (CssPropertyType::MarginTop, "margin-top"),
76 (CssPropertyType::MarginLeft, "margin-left"),
77 (CssPropertyType::MarginRight, "margin-right"),
78 (CssPropertyType::MarginBottom, "margin-bottom"),
79
80 (CssPropertyType::Background, "background"),
81 (CssPropertyType::BackgroundImage, "background-image"),
82 (CssPropertyType::BackgroundColor, "background-color"),
83 (CssPropertyType::BackgroundPosition, "background-position"),
84 (CssPropertyType::BackgroundSize, "background-size"),
85 (CssPropertyType::BackgroundRepeat, "background-repeat"),
86
87 (CssPropertyType::BorderTopLeftRadius, "border-top-left-radius"),
88 (CssPropertyType::BorderTopRightRadius, "border-top-right-radius"),
89 (CssPropertyType::BorderBottomLeftRadius, "border-bottom-left-radius"),
90 (CssPropertyType::BorderBottomRightRadius, "border-bottom-right-radius"),
91
92 (CssPropertyType::BorderTopColor, "border-top-color"),
93 (CssPropertyType::BorderRightColor, "border-right-color"),
94 (CssPropertyType::BorderLeftColor, "border-left-color"),
95 (CssPropertyType::BorderBottomColor, "border-bottom-color"),
96
97 (CssPropertyType::BorderTopStyle, "border-top-style"),
98 (CssPropertyType::BorderRightStyle, "border-right-style"),
99 (CssPropertyType::BorderLeftStyle, "border-left-style"),
100 (CssPropertyType::BorderBottomStyle, "border-bottom-style"),
101
102 (CssPropertyType::BorderTopWidth, "border-top-width"),
103 (CssPropertyType::BorderRightWidth, "border-right-width"),
104 (CssPropertyType::BorderLeftWidth, "border-left-width"),
105 (CssPropertyType::BorderBottomWidth, "border-bottom-width"),
106
107 (CssPropertyType::BoxShadowTop, "box-shadow-top"),
108 (CssPropertyType::BoxShadowRight, "box-shadow-right"),
109 (CssPropertyType::BoxShadowLeft, "box-shadow-left"),
110 (CssPropertyType::BoxShadowBottom, "box-shadow-bottom"),
111];
112
113#[derive(Copy, Clone, PartialEq, PartialOrd)]
118pub struct LayoutRect { pub origin: LayoutPoint, pub size: LayoutSize }
119
120impl fmt::Debug for LayoutRect {
121 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
122 write!(f, "{}", self)
123 }
124}
125
126impl fmt::Display for LayoutRect {
127 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
128 write!(f, "{} @ {}", self.size, self.origin)
129 }
130}
131
132impl LayoutRect {
133 #[inline(always)]
134 pub fn new(origin: LayoutPoint, size: LayoutSize) -> Self { Self { origin, size } }
135 #[inline(always)]
136 pub fn zero() -> Self { Self::new(LayoutPoint::zero(), LayoutSize::zero()) }
137 #[inline(always)]
138 pub fn max_x(&self) -> f32 { self.origin.x + self.size.width }
139 #[inline(always)]
140 pub fn min_x(&self) -> f32 { self.origin.x }
141 #[inline(always)]
142 pub fn max_y(&self) -> f32 { self.origin.y + self.size.height }
143 #[inline(always)]
144 pub fn min_y(&self) -> f32 { self.origin.y }
145 #[inline(always)]
146 pub fn contains(&self, other: &LayoutPoint) -> bool {
147 self.min_x() <= other.x && other.x < self.max_x() &&
148 self.min_y() <= other.y && other.y < self.max_y()
149 }
150
151 #[inline]
153 pub fn union<I: Iterator<Item=Self>>(mut rects: I) -> Option<Self> {
154 let first = rects.next()?;
155
156 let mut max_width = first.size.width;
157 let mut max_height = first.size.height;
158 let mut min_x = first.origin.x;
159 let mut min_y = first.origin.y;
160
161 while let Some(Self { origin: LayoutPoint { x, y }, size: LayoutSize { width, height } }) = rects.next() {
162 let cur_lower_right_x = x + width;
163 let cur_lower_right_y = y + height;
164 max_width = max_width.max(cur_lower_right_x - min_x);
165 max_height = max_height.max(cur_lower_right_y - min_y);
166 min_x = min_x.min(x);
167 min_y = min_y.min(y);
168 }
169
170 Some(Self {
171 origin: LayoutPoint { x: min_x, y: min_y },
172 size: LayoutSize { width: max_width, height: max_height },
173 })
174 }
175
176 #[inline]
178 pub fn get_scroll_rect<I: Iterator<Item=Self>>(&self, children: I) -> Option<Self> {
179 let children_union = Self::union(children)?;
180 Self::union([*self, children_union].iter().map(|r| *r))
181 }
182
183 #[inline(always)]
185 pub fn contains_rect(&self, b: &LayoutRect) -> bool {
186
187 let a = self;
188
189 let a_x = a.origin.x;
190 let a_y = a.origin.y;
191 let a_width = a.size.width;
192 let a_height = a.size.height;
193
194 let b_x = b.origin.x;
195 let b_y = b.origin.y;
196 let b_width = b.size.width;
197 let b_height = b.size.height;
198
199 b_x >= a_x &&
200 b_y >= a_y &&
201 b_x + b_width <= a_x + a_width &&
202 b_y + b_height <= a_y + a_height
203 }
204}
205
206#[derive(Copy, Clone, PartialEq, PartialOrd)]
208pub struct LayoutSize { pub width: f32, pub height: f32 }
209
210impl fmt::Debug for LayoutSize {
211 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
212 write!(f, "{}", self)
213 }
214}
215
216impl fmt::Display for LayoutSize {
217 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
218 write!(f, "{}x{}", self.width, self.height)
219 }
220}
221
222impl LayoutSize {
223 #[inline(always)]
224 pub const fn new(width: f32, height: f32) -> Self { Self { width, height } }
225 #[inline(always)]
226 pub const fn zero() -> Self { Self::new(0.0, 0.0) }
227}
228
229#[derive(Copy, Clone, PartialEq, PartialOrd)]
231pub struct LayoutPoint { pub x: f32, pub y: f32 }
232
233impl fmt::Debug for LayoutPoint {
234 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
235 write!(f, "{}", self)
236 }
237}
238
239impl fmt::Display for LayoutPoint {
240 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
241 write!(f, "({}, {})", self.x, self.y)
242 }
243}
244
245impl LayoutPoint {
246 #[inline(always)]
247 pub const fn new(x: f32, y: f32) -> Self { Self { x, y } }
248 #[inline(always)]
249 pub const fn zero() -> Self { Self::new(0.0, 0.0) }
250}
251
252#[derive(Default, Debug, Copy, Clone, PartialEq, Ord, PartialOrd, Eq, Hash)]
254pub struct PixelSize { pub width: PixelValue, pub height: PixelValue }
255
256impl PixelSize {
257
258 pub const fn new(width: PixelValue, height: PixelValue) -> Self {
259 Self {
260 width,
261 height,
262 }
263 }
264
265 pub const fn zero() -> Self {
266 Self::new(PixelValue::const_px(0), PixelValue::const_px(0))
267 }
268}
269
270#[derive(Debug, Copy, Clone, PartialEq, Ord, PartialOrd, Eq, Hash)]
272pub struct LayoutSideOffsets {
273 pub top: FloatValue,
274 pub right: FloatValue,
275 pub bottom: FloatValue,
276 pub left: FloatValue,
277}
278
279#[derive(Copy, Clone, PartialEq, Ord, PartialOrd, Eq, Hash)]
281pub struct ColorU { pub r: u8, pub g: u8, pub b: u8, pub a: u8 }
282
283impl Default for ColorU { fn default() -> Self { ColorU::BLACK } }
284
285impl fmt::Debug for ColorU {
286 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
287 write!(f, "rgba({}, {}, {}, {})", self.r, self.g, self.b, self.a as f32 / 255.0)
288 }
289}
290
291impl fmt::Display for ColorU {
292 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
293 write!(f, "rgba({}, {}, {}, {})", self.r, self.g, self.b, self.a as f32 / 255.0)
294 }
295}
296
297impl ColorU {
298 pub const RED: ColorU = ColorU { r: 255, g: 0, b: 0, a: 255 };
299 pub const WHITE: ColorU = ColorU { r: 255, g: 255, b: 255, a: 255 };
300 pub const BLACK: ColorU = ColorU { r: 0, g: 0, b: 0, a: 255 };
301 pub const TRANSPARENT: ColorU = ColorU { r: 0, g: 0, b: 0, a: 0 };
302
303 pub fn write_hash(&self, f: &mut fmt::Formatter) -> fmt::Result {
304 write!(f, "#{:x}{:x}{:x}{:x}", self.r, self.g, self.b, self.a)
305 }
306}
307
308#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
310pub struct ColorF { pub r: f32, pub g: f32, pub b: f32, pub a: f32 }
311
312impl Default for ColorF { fn default() -> Self { ColorF::BLACK } }
313
314impl fmt::Display for ColorF {
315 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
316 write!(f, "rgba({}, {}, {}, {})", self.r * 255.0, self.g * 255.0, self.b * 255.0, self.a)
317 }
318}
319
320impl ColorF {
321 pub const WHITE: ColorF = ColorF { r: 1.0, g: 1.0, b: 1.0, a: 1.0 };
322 pub const BLACK: ColorF = ColorF { r: 0.0, g: 0.0, b: 0.0, a: 1.0 };
323 pub const TRANSPARENT: ColorF = ColorF { r: 0.0, g: 0.0, b: 0.0, a: 0.0 };
324}
325
326impl From<ColorU> for ColorF {
327 fn from(input: ColorU) -> ColorF {
328 ColorF {
329 r: (input.r as f32) / 255.0,
330 g: (input.g as f32) / 255.0,
331 b: (input.b as f32) / 255.0,
332 a: (input.a as f32) / 255.0,
333 }
334 }
335}
336
337impl From<ColorF> for ColorU {
338 fn from(input: ColorF) -> ColorU {
339 ColorU {
340 r: (input.r.min(1.0) * 255.0) as u8,
341 g: (input.g.min(1.0) * 255.0) as u8,
342 b: (input.b.min(1.0) * 255.0) as u8,
343 a: (input.a.min(1.0) * 255.0) as u8,
344 }
345 }
346}
347
348#[derive(Debug, Copy, Clone, PartialEq, Ord, PartialOrd, Eq, Hash)]
349pub enum BorderDetails {
350 Normal(NormalBorder),
351 NinePatch(NinePatchBorder),
352}
353
354#[derive(Debug, Copy, Clone, PartialEq, Ord, PartialOrd, Eq, Hash)]
356pub struct NormalBorder {
357 pub left: BorderSide,
358 pub right: BorderSide,
359 pub top: BorderSide,
360 pub bottom: BorderSide,
361 pub radius: Option<(
362 StyleBorderTopLeftRadius,
363 StyleBorderTopRightRadius,
364 StyleBorderBottomLeftRadius,
365 StyleBorderBottomRightRadius,
366 )>,
367}
368
369#[derive(Debug, Copy, Clone, PartialEq, Ord, PartialOrd, Eq, Hash)]
370pub struct BorderSide {
371 pub color: ColorU,
372 pub style: BorderStyle,
373}
374
375#[derive(Debug, Copy, Clone, PartialEq, Ord, PartialOrd, Eq, Hash)]
377pub enum BoxShadowClipMode {
378 Outset,
379 Inset,
380}
381
382impl fmt::Display for BoxShadowClipMode {
383 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
384 use self::BoxShadowClipMode::*;
385 match self {
386 Outset => write!(f, "outset"),
387 Inset => write!(f, "inset"),
388 }
389 }
390}
391
392#[derive(Debug, Copy, Clone, PartialEq, Ord, PartialOrd, Eq, Hash)]
394pub enum ExtendMode {
395 Clamp,
396 Repeat,
397}
398
399#[derive(Debug, Copy, Clone, PartialEq, Ord, PartialOrd, Eq, Hash)]
401pub enum BorderStyle {
402 None,
403 Solid,
404 Double,
405 Dotted,
406 Dashed,
407 Hidden,
408 Groove,
409 Ridge,
410 Inset,
411 Outset,
412}
413
414impl fmt::Display for BorderStyle {
415 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
416 use self::BorderStyle::*;
417 match self {
418 None => write!(f, "none"),
419 Solid => write!(f, "solid"),
420 Double => write!(f, "double"),
421 Dotted => write!(f, "dotted"),
422 Dashed => write!(f, "dashed"),
423 Hidden => write!(f, "hidden"),
424 Groove => write!(f, "groove"),
425 Ridge => write!(f, "ridge"),
426 Inset => write!(f, "inset"),
427 Outset => write!(f, "outset"),
428 }
429 }
430}
431
432impl BorderStyle {
433 pub fn normalize_border(self) -> Option<BorderStyleNoNone> {
434 match self {
435 BorderStyle::None => None,
436 BorderStyle::Solid => Some(BorderStyleNoNone::Solid),
437 BorderStyle::Double => Some(BorderStyleNoNone::Double),
438 BorderStyle::Dotted => Some(BorderStyleNoNone::Dotted),
439 BorderStyle::Dashed => Some(BorderStyleNoNone::Dashed),
440 BorderStyle::Hidden => Some(BorderStyleNoNone::Hidden),
441 BorderStyle::Groove => Some(BorderStyleNoNone::Groove),
442 BorderStyle::Ridge => Some(BorderStyleNoNone::Ridge),
443 BorderStyle::Inset => Some(BorderStyleNoNone::Inset),
444 BorderStyle::Outset => Some(BorderStyleNoNone::Outset),
445 }
446 }
447}
448
449#[derive(Debug, Copy, Clone, PartialEq, Ord, PartialOrd, Eq, Hash)]
450pub enum BorderStyleNoNone {
451 Solid,
452 Double,
453 Dotted,
454 Dashed,
455 Hidden,
456 Groove,
457 Ridge,
458 Inset,
459 Outset,
460}
461
462
463impl Default for BorderStyle {
464 fn default() -> Self {
465 BorderStyle::Solid
466 }
467}
468
469#[derive(Debug, Copy, Clone, PartialEq, Ord, PartialOrd, Eq, Hash)]
470pub struct NinePatchBorder {
471 }
473
474macro_rules! derive_debug_zero {($struct:ident) => (
475 impl fmt::Debug for $struct {
476 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
477 write!(f, "{:?}", self.0)
478 }
479 }
480)}
481
482macro_rules! derive_display_zero {($struct:ident) => (
483 impl fmt::Display for $struct {
484 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
485 write!(f, "{}", self.0)
486 }
487 }
488)}
489
490macro_rules! impl_pixel_value {($struct:ident) => (
493
494 derive_debug_zero!($struct);
495 derive_display_zero!($struct);
496
497 impl $struct {
498 #[inline]
499 pub fn px(value: f32) -> Self {
500 $struct(PixelValue::px(value))
501 }
502
503 #[inline]
504 pub fn em(value: f32) -> Self {
505 $struct(PixelValue::em(value))
506 }
507
508 #[inline]
509 pub fn pt(value: f32) -> Self {
510 $struct(PixelValue::pt(value))
511 }
512 }
513
514 impl FormatAsCssValue for $struct {
515 fn format_as_css_value(&self, f: &mut fmt::Formatter) -> fmt::Result {
516 self.0.format_as_css_value(f)
517 }
518 }
519)}
520
521macro_rules! impl_percentage_value{($struct:ident) => (
522 impl ::std::fmt::Display for $struct {
523 fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
524 write!(f, "{}%", self.0.get())
525 }
526 }
527
528 impl ::std::fmt::Debug for $struct {
529 fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
530 write!(f, "{}%", self.0.get())
531 }
532 }
533
534 impl FormatAsCssValue for $struct {
535 fn format_as_css_value(&self, f: &mut fmt::Formatter) -> fmt::Result {
536 write!(f, "{}%", self.0.get())
537 }
538 }
539)}
540
541macro_rules! impl_float_value{($struct:ident) => (
542 impl ::std::fmt::Display for $struct {
543 fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
544 write!(f, "{}", self.0.get())
545 }
546 }
547
548 impl ::std::fmt::Debug for $struct {
549 fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
550 write!(f, "{}", self.0.get())
551 }
552 }
553
554 impl FormatAsCssValue for $struct {
555 fn format_as_css_value(&self, f: &mut fmt::Formatter) -> fmt::Result {
556 write!(f, "{}", self.0.get())
557 }
558 }
559)}
560
561#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
562pub enum CombinedCssPropertyType {
563 BorderRadius,
564 Overflow,
565 Margin,
566 Border,
567 BorderLeft,
568 BorderRight,
569 BorderTop,
570 BorderBottom,
571 Padding,
572 BoxShadow,
573}
574
575impl fmt::Display for CombinedCssPropertyType {
576 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
577 let key = COMBINED_CSS_PROPERTIES_KEY_MAP.iter().find(|(v, _)| *v == *self).and_then(|(k, _)| Some(k)).unwrap();
578 write!(f, "{}", key)
579 }
580}
581
582impl CombinedCssPropertyType {
583
584 pub fn from_str(input: &str, map: &CssKeyMap) -> Option<Self> {
594 let input = input.trim();
595 map.shorthands.get(input).map(|x| *x)
596 }
597
598 pub fn to_str(&self, map: &CssKeyMap) -> &'static str {
600 map.shorthands.iter().find(|(_, v)| *v == self).map(|(k, _)| k).unwrap()
601 }
602}
603
604#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
605pub struct CssKeyMap {
606 pub non_shorthands: BTreeMap<&'static str, CssPropertyType>,
608 pub shorthands: BTreeMap<&'static str, CombinedCssPropertyType>,
610}
611
612pub fn get_css_key_map() -> CssKeyMap {
614 CssKeyMap {
615 non_shorthands: CSS_PROPERTY_KEY_MAP.iter().map(|(v, k)| (*k, *v)).collect(),
616 shorthands: COMBINED_CSS_PROPERTIES_KEY_MAP.iter().map(|(v, k)| (*k, *v)).collect(),
617 }
618}
619
620#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
623pub enum CssPropertyType {
624
625 TextColor,
626 FontSize,
627 FontFamily,
628 TextAlign,
629
630 LetterSpacing,
631 LineHeight,
632 WordSpacing,
633 TabWidth,
634 Cursor,
635
636 Display,
637 Float,
638 BoxSizing,
639 Width,
640 Height,
641 MinWidth,
642 MinHeight,
643 MaxWidth,
644 MaxHeight,
645
646 Position,
647 Top,
648 Right,
649 Left,
650 Bottom,
651
652 FlexWrap,
653 FlexDirection,
654 FlexGrow,
655 FlexShrink,
656 JustifyContent,
657 AlignItems,
658 AlignContent,
659
660 OverflowX,
661 OverflowY,
662
663 PaddingTop,
664 PaddingLeft,
665 PaddingRight,
666 PaddingBottom,
667
668 MarginTop,
669 MarginLeft,
670 MarginRight,
671 MarginBottom,
672
673 Background,
674 BackgroundImage, BackgroundColor, BackgroundPosition,
677 BackgroundSize,
678 BackgroundRepeat,
679
680 BorderTopLeftRadius,
681 BorderTopRightRadius,
682 BorderBottomLeftRadius,
683 BorderBottomRightRadius,
684
685 BorderTopColor,
686 BorderRightColor,
687 BorderLeftColor,
688 BorderBottomColor,
689
690 BorderTopStyle,
691 BorderRightStyle,
692 BorderLeftStyle,
693 BorderBottomStyle,
694
695 BorderTopWidth,
696 BorderRightWidth,
697 BorderLeftWidth,
698 BorderBottomWidth,
699
700 BoxShadowLeft,
701 BoxShadowRight,
702 BoxShadowTop,
703 BoxShadowBottom,
704}
705
706impl CssPropertyType {
707
708 pub fn from_str(input: &str, map: &CssKeyMap) -> Option<Self> {
720 let input = input.trim();
721 map.non_shorthands.get(input).and_then(|x| Some(*x))
722 }
723
724 pub fn to_str(&self, map: &CssKeyMap) -> &'static str {
726 map.non_shorthands.iter().find(|(_, v)| *v == self).and_then(|(k, _)| Some(k)).unwrap()
727 }
728
729 pub fn is_inheritable(&self) -> bool {
731 use self::CssPropertyType::*;
732 match self {
733 | TextColor
734 | FontFamily
735 | FontSize
736 | LineHeight
737 | TextAlign => true,
738 _ => false,
739 }
740 }
741
742 pub fn can_trigger_relayout(&self) -> bool {
744
745 use self::CssPropertyType::*;
746
747 match self {
754 | TextColor
755 | Cursor
756 | Background
757 | BackgroundPosition
758 | BackgroundSize
759 | BackgroundRepeat
760 | BackgroundImage
761 | BorderTopLeftRadius
762 | BorderTopRightRadius
763 | BorderBottomLeftRadius
764 | BorderBottomRightRadius
765 | BorderTopColor
766 | BorderRightColor
767 | BorderLeftColor
768 | BorderBottomColor
769 | BorderTopStyle
770 | BorderRightStyle
771 | BorderLeftStyle
772 | BorderBottomStyle
773 | BoxShadowLeft
774 | BoxShadowRight
775 | BoxShadowTop
776 | BoxShadowBottom
777 => false,
778 _ => true,
779 }
780 }
781}
782
783impl fmt::Display for CssPropertyType {
784 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
785 let key = CSS_PROPERTY_KEY_MAP.iter().find(|(v, _)| *v == *self).and_then(|(k, _)| Some(k)).unwrap();
786 write!(f, "{}", key)
787 }
788}
789
790#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
792pub enum CssProperty {
793
794 TextColor(CssPropertyValue<StyleTextColor>),
795 FontSize(CssPropertyValue<StyleFontSize>),
796 FontFamily(CssPropertyValue<StyleFontFamily>),
797 TextAlign(CssPropertyValue<StyleTextAlignmentHorz>),
798
799 LetterSpacing(CssPropertyValue<StyleLetterSpacing>),
800 LineHeight(CssPropertyValue<StyleLineHeight>),
801 WordSpacing(CssPropertyValue<StyleWordSpacing>),
802 TabWidth(CssPropertyValue<StyleTabWidth>),
803 Cursor(CssPropertyValue<StyleCursor>),
804
805 Display(CssPropertyValue<LayoutDisplay>),
806 Float(CssPropertyValue<LayoutFloat>),
807 BoxSizing(CssPropertyValue<LayoutBoxSizing>),
808
809 Width(CssPropertyValue<LayoutWidth>),
810 Height(CssPropertyValue<LayoutHeight>),
811 MinWidth(CssPropertyValue<LayoutMinWidth>),
812 MinHeight(CssPropertyValue<LayoutMinHeight>),
813 MaxWidth(CssPropertyValue<LayoutMaxWidth>),
814 MaxHeight(CssPropertyValue<LayoutMaxHeight>),
815
816 Position(CssPropertyValue<LayoutPosition>),
817 Top(CssPropertyValue<LayoutTop>),
818 Right(CssPropertyValue<LayoutRight>),
819 Left(CssPropertyValue<LayoutLeft>),
820 Bottom(CssPropertyValue<LayoutBottom>),
821
822 FlexWrap(CssPropertyValue<LayoutWrap>),
823 FlexDirection(CssPropertyValue<LayoutDirection>),
824 FlexGrow(CssPropertyValue<LayoutFlexGrow>),
825 FlexShrink(CssPropertyValue<LayoutFlexShrink>),
826 JustifyContent(CssPropertyValue<LayoutJustifyContent>),
827 AlignItems(CssPropertyValue<LayoutAlignItems>),
828 AlignContent(CssPropertyValue<LayoutAlignContent>),
829
830 BackgroundContent(CssPropertyValue<StyleBackgroundContent>),
831 BackgroundPosition(CssPropertyValue<StyleBackgroundPosition>),
832 BackgroundSize(CssPropertyValue<StyleBackgroundSize>),
833 BackgroundRepeat(CssPropertyValue<StyleBackgroundRepeat>),
834
835 OverflowX(CssPropertyValue<Overflow>),
836 OverflowY(CssPropertyValue<Overflow>),
837
838 PaddingTop(CssPropertyValue<LayoutPaddingTop>),
839 PaddingLeft(CssPropertyValue<LayoutPaddingLeft>),
840 PaddingRight(CssPropertyValue<LayoutPaddingRight>),
841 PaddingBottom(CssPropertyValue<LayoutPaddingBottom>),
842
843 MarginTop(CssPropertyValue<LayoutMarginTop>),
844 MarginLeft(CssPropertyValue<LayoutMarginLeft>),
845 MarginRight(CssPropertyValue<LayoutMarginRight>),
846 MarginBottom(CssPropertyValue<LayoutMarginBottom>),
847
848 BorderTopLeftRadius(CssPropertyValue<StyleBorderTopLeftRadius>),
849 BorderTopRightRadius(CssPropertyValue<StyleBorderTopRightRadius>),
850 BorderBottomLeftRadius(CssPropertyValue<StyleBorderBottomLeftRadius>),
851 BorderBottomRightRadius(CssPropertyValue<StyleBorderBottomRightRadius>),
852
853 BorderTopColor(CssPropertyValue<StyleBorderTopColor>),
854 BorderRightColor(CssPropertyValue<StyleBorderRightColor>),
855 BorderLeftColor(CssPropertyValue<StyleBorderLeftColor>),
856 BorderBottomColor(CssPropertyValue<StyleBorderBottomColor>),
857
858 BorderTopStyle(CssPropertyValue<StyleBorderTopStyle>),
859 BorderRightStyle(CssPropertyValue<StyleBorderRightStyle>),
860 BorderLeftStyle(CssPropertyValue<StyleBorderLeftStyle>),
861 BorderBottomStyle(CssPropertyValue<StyleBorderBottomStyle>),
862
863 BorderTopWidth(CssPropertyValue<StyleBorderTopWidth>),
864 BorderRightWidth(CssPropertyValue<StyleBorderRightWidth>),
865 BorderLeftWidth(CssPropertyValue<StyleBorderLeftWidth>),
866 BorderBottomWidth(CssPropertyValue<StyleBorderBottomWidth>),
867
868 BoxShadowLeft(CssPropertyValue<BoxShadowPreDisplayItem>),
869 BoxShadowRight(CssPropertyValue<BoxShadowPreDisplayItem>),
870 BoxShadowTop(CssPropertyValue<BoxShadowPreDisplayItem>),
871 BoxShadowBottom(CssPropertyValue<BoxShadowPreDisplayItem>),
872}
873
874macro_rules! css_property_from_type {($prop_type:expr, $content_type:ident) => ({
875 match $prop_type {
876 CssPropertyType::TextColor => CssProperty::TextColor(CssPropertyValue::$content_type),
877 CssPropertyType::FontSize => CssProperty::FontSize(CssPropertyValue::$content_type),
878 CssPropertyType::FontFamily => CssProperty::FontFamily(CssPropertyValue::$content_type),
879 CssPropertyType::TextAlign => CssProperty::TextAlign(CssPropertyValue::$content_type),
880 CssPropertyType::LetterSpacing => CssProperty::LetterSpacing(CssPropertyValue::$content_type),
881 CssPropertyType::LineHeight => CssProperty::LineHeight(CssPropertyValue::$content_type),
882 CssPropertyType::WordSpacing => CssProperty::WordSpacing(CssPropertyValue::$content_type),
883 CssPropertyType::TabWidth => CssProperty::TabWidth(CssPropertyValue::$content_type),
884 CssPropertyType::Cursor => CssProperty::Cursor(CssPropertyValue::$content_type),
885 CssPropertyType::Display => CssProperty::Display(CssPropertyValue::$content_type),
886 CssPropertyType::Float => CssProperty::Float(CssPropertyValue::$content_type),
887 CssPropertyType::BoxSizing => CssProperty::BoxSizing(CssPropertyValue::$content_type),
888 CssPropertyType::Width => CssProperty::Width(CssPropertyValue::$content_type),
889 CssPropertyType::Height => CssProperty::Height(CssPropertyValue::$content_type),
890 CssPropertyType::MinWidth => CssProperty::MinWidth(CssPropertyValue::$content_type),
891 CssPropertyType::MinHeight => CssProperty::MinHeight(CssPropertyValue::$content_type),
892 CssPropertyType::MaxWidth => CssProperty::MaxWidth(CssPropertyValue::$content_type),
893 CssPropertyType::MaxHeight => CssProperty::MaxHeight(CssPropertyValue::$content_type),
894 CssPropertyType::Position => CssProperty::Position(CssPropertyValue::$content_type),
895 CssPropertyType::Top => CssProperty::Top(CssPropertyValue::$content_type),
896 CssPropertyType::Right => CssProperty::Right(CssPropertyValue::$content_type),
897 CssPropertyType::Left => CssProperty::Left(CssPropertyValue::$content_type),
898 CssPropertyType::Bottom => CssProperty::Bottom(CssPropertyValue::$content_type),
899 CssPropertyType::FlexWrap => CssProperty::FlexWrap(CssPropertyValue::$content_type),
900 CssPropertyType::FlexDirection => CssProperty::FlexDirection(CssPropertyValue::$content_type),
901 CssPropertyType::FlexGrow => CssProperty::FlexGrow(CssPropertyValue::$content_type),
902 CssPropertyType::FlexShrink => CssProperty::FlexShrink(CssPropertyValue::$content_type),
903 CssPropertyType::JustifyContent => CssProperty::JustifyContent(CssPropertyValue::$content_type),
904 CssPropertyType::AlignItems => CssProperty::AlignItems(CssPropertyValue::$content_type),
905 CssPropertyType::AlignContent => CssProperty::AlignContent(CssPropertyValue::$content_type),
906 CssPropertyType::OverflowX => CssProperty::OverflowX(CssPropertyValue::$content_type),
907 CssPropertyType::OverflowY => CssProperty::OverflowY(CssPropertyValue::$content_type),
908 CssPropertyType::PaddingTop => CssProperty::PaddingTop(CssPropertyValue::$content_type),
909 CssPropertyType::PaddingLeft => CssProperty::PaddingLeft(CssPropertyValue::$content_type),
910 CssPropertyType::PaddingRight => CssProperty::PaddingRight(CssPropertyValue::$content_type),
911 CssPropertyType::PaddingBottom => CssProperty::PaddingBottom(CssPropertyValue::$content_type),
912 CssPropertyType::MarginTop => CssProperty::MarginTop(CssPropertyValue::$content_type),
913 CssPropertyType::MarginLeft => CssProperty::MarginLeft(CssPropertyValue::$content_type),
914 CssPropertyType::MarginRight => CssProperty::MarginRight(CssPropertyValue::$content_type),
915 CssPropertyType::MarginBottom => CssProperty::MarginBottom(CssPropertyValue::$content_type),
916 CssPropertyType::Background => CssProperty::BackgroundContent(CssPropertyValue::$content_type),
917 CssPropertyType::BackgroundImage => CssProperty::BackgroundContent(CssPropertyValue::$content_type), CssPropertyType::BackgroundColor => CssProperty::BackgroundContent(CssPropertyValue::$content_type), CssPropertyType::BackgroundPosition => CssProperty::BackgroundPosition(CssPropertyValue::$content_type),
920 CssPropertyType::BackgroundSize => CssProperty::BackgroundSize(CssPropertyValue::$content_type),
921 CssPropertyType::BackgroundRepeat => CssProperty::BackgroundRepeat(CssPropertyValue::$content_type),
922 CssPropertyType::BorderTopLeftRadius => CssProperty::BorderTopLeftRadius(CssPropertyValue::$content_type),
923 CssPropertyType::BorderTopRightRadius => CssProperty::BorderTopRightRadius(CssPropertyValue::$content_type),
924 CssPropertyType::BorderBottomLeftRadius => CssProperty::BorderBottomLeftRadius(CssPropertyValue::$content_type),
925 CssPropertyType::BorderBottomRightRadius => CssProperty::BorderBottomRightRadius(CssPropertyValue::$content_type),
926 CssPropertyType::BorderTopColor => CssProperty::BorderTopColor(CssPropertyValue::$content_type),
927 CssPropertyType::BorderRightColor => CssProperty::BorderRightColor(CssPropertyValue::$content_type),
928 CssPropertyType::BorderLeftColor => CssProperty::BorderLeftColor(CssPropertyValue::$content_type),
929 CssPropertyType::BorderBottomColor => CssProperty::BorderBottomColor(CssPropertyValue::$content_type),
930 CssPropertyType::BorderTopStyle => CssProperty::BorderTopStyle(CssPropertyValue::$content_type),
931 CssPropertyType::BorderRightStyle => CssProperty::BorderRightStyle(CssPropertyValue::$content_type),
932 CssPropertyType::BorderLeftStyle => CssProperty::BorderLeftStyle(CssPropertyValue::$content_type),
933 CssPropertyType::BorderBottomStyle => CssProperty::BorderBottomStyle(CssPropertyValue::$content_type),
934 CssPropertyType::BorderTopWidth => CssProperty::BorderTopWidth(CssPropertyValue::$content_type),
935 CssPropertyType::BorderRightWidth => CssProperty::BorderRightWidth(CssPropertyValue::$content_type),
936 CssPropertyType::BorderLeftWidth => CssProperty::BorderLeftWidth(CssPropertyValue::$content_type),
937 CssPropertyType::BorderBottomWidth => CssProperty::BorderBottomWidth(CssPropertyValue::$content_type),
938 CssPropertyType::BoxShadowLeft => CssProperty::BoxShadowLeft(CssPropertyValue::$content_type),
939 CssPropertyType::BoxShadowRight => CssProperty::BoxShadowRight(CssPropertyValue::$content_type),
940 CssPropertyType::BoxShadowTop => CssProperty::BoxShadowTop(CssPropertyValue::$content_type),
941 CssPropertyType::BoxShadowBottom => CssProperty::BoxShadowBottom(CssPropertyValue::$content_type),
942 }
943})}
944
945impl CssProperty {
946
947 pub fn get_type(&self) -> CssPropertyType {
949 match &self {
950 CssProperty::TextColor(_) => CssPropertyType::TextColor,
951 CssProperty::FontSize(_) => CssPropertyType::FontSize,
952 CssProperty::FontFamily(_) => CssPropertyType::FontFamily,
953 CssProperty::TextAlign(_) => CssPropertyType::TextAlign,
954 CssProperty::LetterSpacing(_) => CssPropertyType::LetterSpacing,
955 CssProperty::LineHeight(_) => CssPropertyType::LineHeight,
956 CssProperty::WordSpacing(_) => CssPropertyType::WordSpacing,
957 CssProperty::TabWidth(_) => CssPropertyType::TabWidth,
958 CssProperty::Cursor(_) => CssPropertyType::Cursor,
959 CssProperty::Display(_) => CssPropertyType::Display,
960 CssProperty::Float(_) => CssPropertyType::Float,
961 CssProperty::BoxSizing(_) => CssPropertyType::BoxSizing,
962 CssProperty::Width(_) => CssPropertyType::Width,
963 CssProperty::Height(_) => CssPropertyType::Height,
964 CssProperty::MinWidth(_) => CssPropertyType::MinWidth,
965 CssProperty::MinHeight(_) => CssPropertyType::MinHeight,
966 CssProperty::MaxWidth(_) => CssPropertyType::MaxWidth,
967 CssProperty::MaxHeight(_) => CssPropertyType::MaxHeight,
968 CssProperty::Position(_) => CssPropertyType::Position,
969 CssProperty::Top(_) => CssPropertyType::Top,
970 CssProperty::Right(_) => CssPropertyType::Right,
971 CssProperty::Left(_) => CssPropertyType::Left,
972 CssProperty::Bottom(_) => CssPropertyType::Bottom,
973 CssProperty::FlexWrap(_) => CssPropertyType::FlexWrap,
974 CssProperty::FlexDirection(_) => CssPropertyType::FlexDirection,
975 CssProperty::FlexGrow(_) => CssPropertyType::FlexGrow,
976 CssProperty::FlexShrink(_) => CssPropertyType::FlexShrink,
977 CssProperty::JustifyContent(_) => CssPropertyType::JustifyContent,
978 CssProperty::AlignItems(_) => CssPropertyType::AlignItems,
979 CssProperty::AlignContent(_) => CssPropertyType::AlignContent,
980
981 CssProperty::BackgroundContent(_) => CssPropertyType::BackgroundImage, CssProperty::BackgroundPosition(_) => CssPropertyType::BackgroundPosition,
983 CssProperty::BackgroundSize(_) => CssPropertyType::BackgroundSize,
984 CssProperty::BackgroundRepeat(_) => CssPropertyType::BackgroundRepeat,
985
986 CssProperty::OverflowX(_) => CssPropertyType::OverflowX,
987 CssProperty::OverflowY(_) => CssPropertyType::OverflowY,
988 CssProperty::PaddingTop(_) => CssPropertyType::PaddingTop,
989 CssProperty::PaddingLeft(_) => CssPropertyType::PaddingLeft,
990 CssProperty::PaddingRight(_) => CssPropertyType::PaddingRight,
991 CssProperty::PaddingBottom(_) => CssPropertyType::PaddingBottom,
992 CssProperty::MarginTop(_) => CssPropertyType::MarginTop,
993 CssProperty::MarginLeft(_) => CssPropertyType::MarginLeft,
994 CssProperty::MarginRight(_) => CssPropertyType::MarginRight,
995 CssProperty::MarginBottom(_) => CssPropertyType::MarginBottom,
996 CssProperty::BorderTopLeftRadius(_) => CssPropertyType::BorderTopLeftRadius,
997 CssProperty::BorderTopRightRadius(_) => CssPropertyType::BorderTopRightRadius,
998 CssProperty::BorderBottomLeftRadius(_) => CssPropertyType::BorderBottomLeftRadius,
999 CssProperty::BorderBottomRightRadius(_) => CssPropertyType::BorderBottomRightRadius,
1000 CssProperty::BorderTopColor(_) => CssPropertyType::BorderTopColor,
1001 CssProperty::BorderRightColor(_) => CssPropertyType::BorderRightColor,
1002 CssProperty::BorderLeftColor(_) => CssPropertyType::BorderLeftColor,
1003 CssProperty::BorderBottomColor(_) => CssPropertyType::BorderBottomColor,
1004 CssProperty::BorderTopStyle(_) => CssPropertyType::BorderTopStyle,
1005 CssProperty::BorderRightStyle(_) => CssPropertyType::BorderRightStyle,
1006 CssProperty::BorderLeftStyle(_) => CssPropertyType::BorderLeftStyle,
1007 CssProperty::BorderBottomStyle(_) => CssPropertyType::BorderBottomStyle,
1008 CssProperty::BorderTopWidth(_) => CssPropertyType::BorderTopWidth,
1009 CssProperty::BorderRightWidth(_) => CssPropertyType::BorderRightWidth,
1010 CssProperty::BorderLeftWidth(_) => CssPropertyType::BorderLeftWidth,
1011 CssProperty::BorderBottomWidth(_) => CssPropertyType::BorderBottomWidth,
1012 CssProperty::BoxShadowLeft(_) => CssPropertyType::BoxShadowLeft,
1013 CssProperty::BoxShadowRight(_) => CssPropertyType::BoxShadowRight,
1014 CssProperty::BoxShadowTop(_) => CssPropertyType::BoxShadowTop,
1015 CssProperty::BoxShadowBottom(_) => CssPropertyType::BoxShadowBottom,
1016 }
1017 }
1018
1019 pub fn none(prop_type: CssPropertyType) -> Self {
1020 css_property_from_type!(prop_type, None)
1021 }
1022
1023 pub fn auto(prop_type: CssPropertyType) -> Self {
1024 css_property_from_type!(prop_type, Auto)
1025 }
1026
1027 pub fn initial(prop_type: CssPropertyType) -> Self {
1028 css_property_from_type!(prop_type, Initial)
1029 }
1030
1031 pub fn inherit(prop_type: CssPropertyType) -> Self {
1032 css_property_from_type!(prop_type, Inherit)
1033 }
1034
1035
1036 pub const fn text_color(input: StyleTextColor) -> Self { CssProperty::TextColor(CssPropertyValue::Exact(input)) }
1038
1039 pub const fn font_size(input: StyleFontSize) -> Self { CssProperty::FontSize(CssPropertyValue::Exact(input)) }
1041
1042 pub const fn font_family(input: StyleFontFamily) -> Self { CssProperty::FontFamily(CssPropertyValue::Exact(input)) }
1044
1045 pub const fn text_align(input: StyleTextAlignmentHorz) -> Self { CssProperty::TextAlign(CssPropertyValue::Exact(input)) }
1047
1048 pub const fn letter_spacing(input: StyleLetterSpacing) -> Self { CssProperty::LetterSpacing(CssPropertyValue::Exact(input)) }
1050
1051 pub const fn line_height(input: StyleLineHeight) -> Self { CssProperty::LineHeight(CssPropertyValue::Exact(input)) }
1053
1054 pub const fn word_spacing(input: StyleWordSpacing) -> Self { CssProperty::WordSpacing(CssPropertyValue::Exact(input)) }
1056
1057 pub const fn tab_width(input: StyleTabWidth) -> Self { CssProperty::TabWidth(CssPropertyValue::Exact(input)) }
1059
1060 pub const fn cursor(input: StyleCursor) -> Self { CssProperty::Cursor(CssPropertyValue::Exact(input)) }
1062
1063 pub const fn display(input: LayoutDisplay) -> Self { CssProperty::Display(CssPropertyValue::Exact(input)) }
1065
1066 pub const fn float(input: LayoutFloat) -> Self { CssProperty::Float(CssPropertyValue::Exact(input)) }
1068
1069 pub const fn box_sizing(input: LayoutBoxSizing) -> Self { CssProperty::BoxSizing(CssPropertyValue::Exact(input)) }
1071
1072 pub const fn width(input: LayoutWidth) -> Self { CssProperty::Width(CssPropertyValue::Exact(input)) }
1074
1075 pub const fn height(input: LayoutHeight) -> Self { CssProperty::Height(CssPropertyValue::Exact(input)) }
1077
1078 pub const fn min_width(input: LayoutMinWidth) -> Self { CssProperty::MinWidth(CssPropertyValue::Exact(input)) }
1080
1081 pub const fn min_height(input: LayoutMinHeight) -> Self { CssProperty::MinHeight(CssPropertyValue::Exact(input)) }
1083
1084 pub const fn max_width(input: LayoutMaxWidth) -> Self { CssProperty::MaxWidth(CssPropertyValue::Exact(input)) }
1086
1087 pub const fn max_height(input: LayoutMaxHeight) -> Self { CssProperty::MaxHeight(CssPropertyValue::Exact(input)) }
1089
1090 pub const fn position(input: LayoutPosition) -> Self { CssProperty::Position(CssPropertyValue::Exact(input)) }
1092
1093 pub const fn top(input: LayoutTop) -> Self { CssProperty::Top(CssPropertyValue::Exact(input)) }
1095
1096 pub const fn right(input: LayoutRight) -> Self { CssProperty::Right(CssPropertyValue::Exact(input)) }
1098
1099 pub const fn left(input: LayoutLeft) -> Self { CssProperty::Left(CssPropertyValue::Exact(input)) }
1101
1102 pub const fn bottom(input: LayoutBottom) -> Self { CssProperty::Bottom(CssPropertyValue::Exact(input)) }
1104
1105 pub const fn flex_wrap(input: LayoutWrap) -> Self { CssProperty::FlexWrap(CssPropertyValue::Exact(input)) }
1107
1108 pub const fn flex_direction(input: LayoutDirection) -> Self { CssProperty::FlexDirection(CssPropertyValue::Exact(input)) }
1110
1111 pub const fn flex_grow(input: LayoutFlexGrow) -> Self { CssProperty::FlexGrow(CssPropertyValue::Exact(input)) }
1113
1114 pub const fn flex_shrink(input: LayoutFlexShrink) -> Self { CssProperty::FlexShrink(CssPropertyValue::Exact(input)) }
1116
1117 pub const fn justify_content(input: LayoutJustifyContent) -> Self { CssProperty::JustifyContent(CssPropertyValue::Exact(input)) }
1119
1120 pub const fn align_items(input: LayoutAlignItems) -> Self { CssProperty::AlignItems(CssPropertyValue::Exact(input)) }
1122
1123 pub const fn align_content(input: LayoutAlignContent) -> Self { CssProperty::AlignContent(CssPropertyValue::Exact(input)) }
1125
1126 pub const fn background_content(input: StyleBackgroundContent) -> Self { CssProperty::BackgroundContent(CssPropertyValue::Exact(input)) }
1128
1129 pub const fn background_position(input: StyleBackgroundPosition) -> Self { CssProperty::BackgroundPosition(CssPropertyValue::Exact(input)) }
1131
1132 pub const fn background_size(input: StyleBackgroundSize) -> Self { CssProperty::BackgroundSize(CssPropertyValue::Exact(input)) }
1134
1135 pub const fn background_repeat(input: StyleBackgroundRepeat) -> Self { CssProperty::BackgroundRepeat(CssPropertyValue::Exact(input)) }
1137
1138 pub const fn overflow_x(input: Overflow) -> Self { CssProperty::OverflowX(CssPropertyValue::Exact(input)) }
1140
1141 pub const fn overflow_y(input: Overflow) -> Self { CssProperty::OverflowY(CssPropertyValue::Exact(input)) }
1143
1144 pub const fn padding_top(input: LayoutPaddingTop) -> Self { CssProperty::PaddingTop(CssPropertyValue::Exact(input)) }
1146
1147 pub const fn padding_left(input: LayoutPaddingLeft) -> Self { CssProperty::PaddingLeft(CssPropertyValue::Exact(input)) }
1149
1150 pub const fn padding_right(input: LayoutPaddingRight) -> Self { CssProperty::PaddingRight(CssPropertyValue::Exact(input)) }
1152
1153 pub const fn padding_bottom(input: LayoutPaddingBottom) -> Self { CssProperty::PaddingBottom(CssPropertyValue::Exact(input)) }
1155
1156 pub const fn margin_top(input: LayoutMarginTop) -> Self { CssProperty::MarginTop(CssPropertyValue::Exact(input)) }
1158
1159 pub const fn margin_left(input: LayoutMarginLeft) -> Self { CssProperty::MarginLeft(CssPropertyValue::Exact(input)) }
1161
1162 pub const fn margin_right(input: LayoutMarginRight) -> Self { CssProperty::MarginRight(CssPropertyValue::Exact(input)) }
1164
1165 pub const fn margin_bottom(input: LayoutMarginBottom) -> Self { CssProperty::MarginBottom(CssPropertyValue::Exact(input)) }
1167
1168 pub const fn border_top_left_radius(input: StyleBorderTopLeftRadius) -> Self { CssProperty::BorderTopLeftRadius(CssPropertyValue::Exact(input)) }
1170
1171 pub const fn border_top_right_radius(input: StyleBorderTopRightRadius) -> Self { CssProperty::BorderTopRightRadius(CssPropertyValue::Exact(input)) }
1173
1174 pub const fn border_bottom_left_radius(input: StyleBorderBottomLeftRadius) -> Self { CssProperty::BorderBottomLeftRadius(CssPropertyValue::Exact(input)) }
1176
1177 pub const fn border_bottom_right_radius(input: StyleBorderBottomRightRadius) -> Self { CssProperty::BorderBottomRightRadius(CssPropertyValue::Exact(input)) }
1179
1180 pub const fn border_top_color(input: StyleBorderTopColor) -> Self { CssProperty::BorderTopColor(CssPropertyValue::Exact(input)) }
1182
1183 pub const fn border_right_color(input: StyleBorderRightColor) -> Self { CssProperty::BorderRightColor(CssPropertyValue::Exact(input)) }
1185
1186 pub const fn border_left_color(input: StyleBorderLeftColor) -> Self { CssProperty::BorderLeftColor(CssPropertyValue::Exact(input)) }
1188
1189 pub const fn border_bottom_color(input: StyleBorderBottomColor) -> Self { CssProperty::BorderBottomColor(CssPropertyValue::Exact(input)) }
1191
1192 pub const fn border_top_style(input: StyleBorderTopStyle) -> Self { CssProperty::BorderTopStyle(CssPropertyValue::Exact(input)) }
1194
1195 pub const fn border_right_style(input: StyleBorderRightStyle) -> Self { CssProperty::BorderRightStyle(CssPropertyValue::Exact(input)) }
1197
1198 pub const fn border_left_style(input: StyleBorderLeftStyle) -> Self { CssProperty::BorderLeftStyle(CssPropertyValue::Exact(input)) }
1200
1201 pub const fn border_bottom_style(input: StyleBorderBottomStyle) -> Self { CssProperty::BorderBottomStyle(CssPropertyValue::Exact(input)) }
1203
1204 pub const fn border_top_width(input: StyleBorderTopWidth) -> Self { CssProperty::BorderTopWidth(CssPropertyValue::Exact(input)) }
1206
1207 pub const fn border_right_width(input: StyleBorderRightWidth) -> Self { CssProperty::BorderRightWidth(CssPropertyValue::Exact(input)) }
1209
1210 pub const fn border_left_width(input: StyleBorderLeftWidth) -> Self { CssProperty::BorderLeftWidth(CssPropertyValue::Exact(input)) }
1212
1213 pub const fn border_bottom_width(input: StyleBorderBottomWidth) -> Self { CssProperty::BorderBottomWidth(CssPropertyValue::Exact(input)) }
1215
1216 pub const fn box_shadow_left(input: BoxShadowPreDisplayItem) -> Self { CssProperty::BoxShadowLeft(CssPropertyValue::Exact(input)) }
1218
1219 pub const fn box_shadow_right(input: BoxShadowPreDisplayItem) -> Self { CssProperty::BoxShadowRight(CssPropertyValue::Exact(input)) }
1221
1222 pub const fn box_shadow_top(input: BoxShadowPreDisplayItem) -> Self { CssProperty::BoxShadowTop(CssPropertyValue::Exact(input)) }
1224
1225 pub const fn box_shadow_bottom(input: BoxShadowPreDisplayItem) -> Self { CssProperty::BoxShadowBottom(CssPropertyValue::Exact(input)) }
1227
1228}
1229
1230macro_rules! impl_from_css_prop {
1231 ($a:ident, $b:ident::$enum_type:ident) => {
1232 impl From<$a> for $b {
1233 fn from(e: $a) -> Self {
1234 $b::$enum_type(CssPropertyValue::from(e))
1235 }
1236 }
1237 };
1238}
1239
1240impl_from_css_prop!(StyleTextColor, CssProperty::TextColor);
1241impl_from_css_prop!(StyleFontSize, CssProperty::FontSize);
1242impl_from_css_prop!(StyleFontFamily, CssProperty::FontFamily);
1243impl_from_css_prop!(StyleTextAlignmentHorz, CssProperty::TextAlign);
1244impl_from_css_prop!(StyleLetterSpacing, CssProperty::LetterSpacing);
1245impl_from_css_prop!(StyleLineHeight, CssProperty::LineHeight);
1246impl_from_css_prop!(StyleWordSpacing, CssProperty::WordSpacing);
1247impl_from_css_prop!(StyleTabWidth, CssProperty::TabWidth);
1248impl_from_css_prop!(StyleCursor, CssProperty::Cursor);
1249impl_from_css_prop!(LayoutDisplay, CssProperty::Display);
1250impl_from_css_prop!(LayoutFloat, CssProperty::Float);
1251impl_from_css_prop!(LayoutBoxSizing, CssProperty::BoxSizing);
1252impl_from_css_prop!(LayoutWidth, CssProperty::Width);
1253impl_from_css_prop!(LayoutHeight, CssProperty::Height);
1254impl_from_css_prop!(LayoutMinWidth, CssProperty::MinWidth);
1255impl_from_css_prop!(LayoutMinHeight, CssProperty::MinHeight);
1256impl_from_css_prop!(LayoutMaxWidth, CssProperty::MaxWidth);
1257impl_from_css_prop!(LayoutMaxHeight, CssProperty::MaxHeight);
1258impl_from_css_prop!(LayoutPosition, CssProperty::Position);
1259impl_from_css_prop!(LayoutTop, CssProperty::Top);
1260impl_from_css_prop!(LayoutRight, CssProperty::Right);
1261impl_from_css_prop!(LayoutLeft, CssProperty::Left);
1262impl_from_css_prop!(LayoutBottom, CssProperty::Bottom);
1263impl_from_css_prop!(LayoutWrap, CssProperty::FlexWrap);
1264impl_from_css_prop!(LayoutDirection, CssProperty::FlexDirection);
1265impl_from_css_prop!(LayoutFlexGrow, CssProperty::FlexGrow);
1266impl_from_css_prop!(LayoutFlexShrink, CssProperty::FlexShrink);
1267impl_from_css_prop!(LayoutJustifyContent, CssProperty::JustifyContent);
1268impl_from_css_prop!(LayoutAlignItems, CssProperty::AlignItems);
1269impl_from_css_prop!(LayoutAlignContent, CssProperty::AlignContent);
1270impl_from_css_prop!(StyleBackgroundContent, CssProperty::BackgroundContent);
1271impl_from_css_prop!(StyleBackgroundPosition, CssProperty::BackgroundPosition);
1272impl_from_css_prop!(StyleBackgroundSize, CssProperty::BackgroundSize);
1273impl_from_css_prop!(StyleBackgroundRepeat, CssProperty::BackgroundRepeat);
1274impl_from_css_prop!(LayoutPaddingTop, CssProperty::PaddingTop);
1275impl_from_css_prop!(LayoutPaddingLeft, CssProperty::PaddingLeft);
1276impl_from_css_prop!(LayoutPaddingRight, CssProperty::PaddingRight);
1277impl_from_css_prop!(LayoutPaddingBottom, CssProperty::PaddingBottom);
1278impl_from_css_prop!(LayoutMarginTop, CssProperty::MarginTop);
1279impl_from_css_prop!(LayoutMarginLeft, CssProperty::MarginLeft);
1280impl_from_css_prop!(LayoutMarginRight, CssProperty::MarginRight);
1281impl_from_css_prop!(LayoutMarginBottom, CssProperty::MarginBottom);
1282impl_from_css_prop!(StyleBorderTopLeftRadius, CssProperty::BorderTopLeftRadius);
1283impl_from_css_prop!(StyleBorderTopRightRadius, CssProperty::BorderTopRightRadius);
1284impl_from_css_prop!(StyleBorderBottomLeftRadius, CssProperty::BorderBottomLeftRadius);
1285impl_from_css_prop!(StyleBorderBottomRightRadius, CssProperty::BorderBottomRightRadius);
1286impl_from_css_prop!(StyleBorderTopColor, CssProperty::BorderTopColor);
1287impl_from_css_prop!(StyleBorderRightColor, CssProperty::BorderRightColor);
1288impl_from_css_prop!(StyleBorderLeftColor, CssProperty::BorderLeftColor);
1289impl_from_css_prop!(StyleBorderBottomColor, CssProperty::BorderBottomColor);
1290impl_from_css_prop!(StyleBorderTopStyle, CssProperty::BorderTopStyle);
1291impl_from_css_prop!(StyleBorderRightStyle, CssProperty::BorderRightStyle);
1292impl_from_css_prop!(StyleBorderLeftStyle, CssProperty::BorderLeftStyle);
1293impl_from_css_prop!(StyleBorderBottomStyle, CssProperty::BorderBottomStyle);
1294impl_from_css_prop!(StyleBorderTopWidth, CssProperty::BorderTopWidth);
1295impl_from_css_prop!(StyleBorderRightWidth, CssProperty::BorderRightWidth);
1296impl_from_css_prop!(StyleBorderLeftWidth, CssProperty::BorderLeftWidth);
1297impl_from_css_prop!(StyleBorderBottomWidth, CssProperty::BorderBottomWidth);
1298
1299const FP_PRECISION_MULTIPLIER: f32 = 1000.0;
1305const FP_PRECISION_MULTIPLIER_CONST: isize = FP_PRECISION_MULTIPLIER as isize;
1306
1307#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1309pub struct PixelValueNoPercent(pub PixelValue);
1310
1311impl fmt::Display for PixelValueNoPercent {
1312 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1313 write!(f, "{}", self.0)
1314 }
1315}
1316
1317impl PixelValueNoPercent {
1318 pub fn to_pixels(&self) -> f32 {
1319 self.0.to_pixels(0.0)
1320 }
1321}
1322
1323#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1325pub struct PixelValue {
1326 pub metric: SizeMetric,
1327 pub number: FloatValue,
1328}
1329
1330impl fmt::Debug for PixelValue {
1331 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1332 write!(f, "{}{}", self.number, self.metric)
1333 }
1334}
1335
1336impl fmt::Display for PixelValue {
1338 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1339 write!(f, "{}{}", self.number, self.metric)
1340 }
1341}
1342
1343impl FormatAsCssValue for PixelValue {
1344 fn format_as_css_value(&self, f: &mut fmt::Formatter) -> fmt::Result {
1345 write!(f, "{}{}", self.number, self.metric)
1346 }
1347}
1348
1349impl fmt::Display for SizeMetric {
1350 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1351 use self::SizeMetric::*;
1352 match self {
1353 Px => write!(f, "px"),
1354 Pt => write!(f, "pt"),
1355 Em => write!(f, "pt"),
1356 Percent => write!(f, "%"),
1357 }
1358 }
1359}
1360
1361impl PixelValue {
1362
1363 #[inline]
1364 pub const fn zero() -> Self {
1365 const ZERO_PX: PixelValue = PixelValue::const_px(0);
1366 ZERO_PX
1367 }
1368
1369 #[inline]
1372 pub const fn const_px(value: isize) -> Self {
1373 Self::const_from_metric(SizeMetric::Px, value)
1374 }
1375
1376 #[inline]
1379 pub const fn const_em(value: isize) -> Self {
1380 Self::const_from_metric(SizeMetric::Em, value)
1381 }
1382
1383 #[inline]
1386 pub const fn const_pt(value: isize) -> Self {
1387 Self::const_from_metric(SizeMetric::Pt, value)
1388 }
1389
1390 #[inline]
1393 pub const fn const_percent(value: isize) -> Self {
1394 Self::const_from_metric(SizeMetric::Percent, value)
1395 }
1396
1397 #[inline]
1398 pub const fn const_from_metric(metric: SizeMetric, value: isize) -> Self {
1399 Self {
1400 metric: metric,
1401 number: FloatValue::const_new(value),
1402 }
1403 }
1404
1405 #[inline]
1406 pub fn px(value: f32) -> Self {
1407 Self::from_metric(SizeMetric::Px, value)
1408 }
1409
1410 #[inline]
1411 pub fn em(value: f32) -> Self {
1412 Self::from_metric(SizeMetric::Em, value)
1413 }
1414
1415 #[inline]
1416 pub fn pt(value: f32) -> Self {
1417 Self::from_metric(SizeMetric::Pt, value)
1418 }
1419
1420 #[inline]
1421 pub fn percent(value: f32) -> Self {
1422 Self::from_metric(SizeMetric::Percent, value)
1423 }
1424
1425 #[inline]
1426 pub fn from_metric(metric: SizeMetric, value: f32) -> Self {
1427 Self {
1428 metric: metric,
1429 number: FloatValue::new(value),
1430 }
1431 }
1432
1433 #[inline]
1435 pub fn to_pixels(&self, percent_resolve: f32) -> f32 {
1436 match self.metric {
1437 SizeMetric::Px => self.number.get(),
1438 SizeMetric::Pt => self.number.get() * PT_TO_PX,
1439 SizeMetric::Em => self.number.get() * EM_HEIGHT,
1440 SizeMetric::Percent => self.number.get() / 100.0 * percent_resolve,
1441 }
1442 }
1443}
1444
1445#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1448pub struct PercentageValue {
1449 number: FloatValue,
1450}
1451
1452impl fmt::Display for PercentageValue {
1453 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1454 write!(f, "{}%", self.get())
1455 }
1456}
1457
1458impl PercentageValue {
1459
1460 pub const fn const_new(value: isize) -> Self {
1463 Self { number: FloatValue::const_new(value) }
1464 }
1465
1466 pub fn new(value: f32) -> Self {
1467 Self { number: value.into() }
1468 }
1469
1470 pub fn get(&self) -> f32 {
1471 self.number.get()
1472 }
1473}
1474
1475#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1478pub struct FloatValue {
1479 pub number: isize,
1480}
1481
1482impl fmt::Display for FloatValue {
1483 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1484 write!(f, "{}", self.get())
1485 }
1486}
1487
1488impl Default for FloatValue {
1489 fn default() -> Self {
1490 const DEFAULT_FLV: FloatValue = FloatValue::const_new(0);
1491 DEFAULT_FLV
1492 }
1493}
1494
1495impl FloatValue {
1496
1497 pub const fn const_new(value: isize) -> Self {
1500 Self { number: value * FP_PRECISION_MULTIPLIER_CONST }
1501 }
1502
1503 pub fn new(value: f32) -> Self {
1504 Self { number: (value * FP_PRECISION_MULTIPLIER) as isize }
1505 }
1506
1507 pub fn get(&self) -> f32 {
1508 self.number as f32 / FP_PRECISION_MULTIPLIER
1509 }
1510}
1511
1512impl From<f32> for FloatValue {
1513 fn from(val: f32) -> Self {
1514 Self::new(val)
1515 }
1516}
1517
1518#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1520pub enum SizeMetric {
1521 Px,
1522 Pt,
1523 Em,
1524 Percent,
1525}
1526
1527impl Default for SizeMetric {
1528 fn default() -> Self { SizeMetric::Px }
1529}
1530
1531#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1533pub enum StyleBackgroundSize {
1534 ExactSize(PixelValue, PixelValue),
1535 Contain,
1536 Cover,
1537}
1538
1539#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1541pub struct StyleBackgroundPosition {
1542 pub horizontal: BackgroundPositionHorizontal,
1543 pub vertical: BackgroundPositionVertical,
1544}
1545
1546impl Default for StyleBackgroundPosition {
1547 fn default() -> Self {
1548 StyleBackgroundPosition {
1549 horizontal: BackgroundPositionHorizontal::Left,
1550 vertical: BackgroundPositionVertical::Top,
1551 }
1552 }
1553}
1554
1555#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1556pub enum BackgroundPositionHorizontal {
1557 Left,
1558 Center,
1559 Right,
1560 Exact(PixelValue),
1561}
1562
1563#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1564pub enum BackgroundPositionVertical {
1565 Top,
1566 Center,
1567 Bottom,
1568 Exact(PixelValue),
1569}
1570
1571#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1573pub enum StyleBackgroundRepeat {
1574 NoRepeat,
1575 Repeat,
1576 RepeatX,
1577 RepeatY,
1578}
1579
1580impl Default for StyleBackgroundRepeat {
1581 fn default() -> Self {
1582 StyleBackgroundRepeat::Repeat
1583 }
1584}
1585
1586#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1588pub struct StyleTextColor(pub ColorU);
1589
1590derive_debug_zero!(StyleTextColor);
1591derive_display_zero!(StyleTextColor);
1592
1593#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1597pub struct StyleBorderTopLeftRadius(pub PixelValue);
1598#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1600pub struct StyleBorderBottomLeftRadius(pub PixelValue);
1601#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1603pub struct StyleBorderTopRightRadius(pub PixelValue);
1604#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1606pub struct StyleBorderBottomRightRadius(pub PixelValue);
1607
1608impl_pixel_value!(StyleBorderTopLeftRadius);
1609impl_pixel_value!(StyleBorderBottomLeftRadius);
1610impl_pixel_value!(StyleBorderTopRightRadius);
1611impl_pixel_value!(StyleBorderBottomRightRadius);
1612
1613#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1615pub struct StyleBorderTopWidth(pub PixelValue);
1616#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1618pub struct StyleBorderLeftWidth(pub PixelValue);
1619#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1621pub struct StyleBorderRightWidth(pub PixelValue);
1622#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1624pub struct StyleBorderBottomWidth(pub PixelValue);
1625
1626impl_pixel_value!(StyleBorderTopWidth);
1627impl_pixel_value!(StyleBorderLeftWidth);
1628impl_pixel_value!(StyleBorderRightWidth);
1629impl_pixel_value!(StyleBorderBottomWidth);
1630
1631#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1633pub struct StyleBorderTopStyle(pub BorderStyle);
1634#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1636pub struct StyleBorderLeftStyle(pub BorderStyle);
1637#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1639pub struct StyleBorderRightStyle(pub BorderStyle);
1640#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1642pub struct StyleBorderBottomStyle(pub BorderStyle);
1643
1644derive_debug_zero!(StyleBorderTopStyle);
1645derive_debug_zero!(StyleBorderLeftStyle);
1646derive_debug_zero!(StyleBorderBottomStyle);
1647derive_debug_zero!(StyleBorderRightStyle);
1648
1649derive_display_zero!(StyleBorderTopStyle);
1650derive_display_zero!(StyleBorderLeftStyle);
1651derive_display_zero!(StyleBorderBottomStyle);
1652derive_display_zero!(StyleBorderRightStyle);
1653
1654#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1656pub struct StyleBorderTopColor(pub ColorU);
1657#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1659pub struct StyleBorderLeftColor(pub ColorU);
1660#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1662pub struct StyleBorderRightColor(pub ColorU);
1663#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1665pub struct StyleBorderBottomColor(pub ColorU);
1666
1667derive_debug_zero!(StyleBorderTopColor);
1668derive_debug_zero!(StyleBorderLeftColor);
1669derive_debug_zero!(StyleBorderRightColor);
1670derive_debug_zero!(StyleBorderBottomColor);
1671
1672derive_display_zero!(StyleBorderTopColor);
1673derive_display_zero!(StyleBorderLeftColor);
1674derive_display_zero!(StyleBorderRightColor);
1675derive_display_zero!(StyleBorderBottomColor);
1676
1677#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1678pub struct StyleBorderSide {
1679 pub border_width: PixelValue,
1680 pub border_style: BorderStyle,
1681 pub border_color: ColorU,
1682}
1683
1684#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1686pub struct BoxShadowPreDisplayItem {
1687 pub offset: [PixelValueNoPercent;2],
1688 pub color: ColorU,
1689 pub blur_radius: PixelValueNoPercent,
1690 pub spread_radius: PixelValueNoPercent,
1691 pub clip_mode: BoxShadowClipMode,
1692}
1693
1694impl fmt::Display for BoxShadowPreDisplayItem {
1695 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1696 if self.clip_mode == BoxShadowClipMode::Inset {
1697 write!(f, "{} ", self.clip_mode)?;
1698 }
1699 write!(f, "{} {} {} {} {}",
1700 self.offset[0], self.offset[1],
1701 self.blur_radius, self.spread_radius, self.color,
1702 )
1703 }
1704}
1705
1706#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1707pub enum StyleBackgroundContent {
1708 LinearGradient(LinearGradient),
1709 RadialGradient(RadialGradient),
1710 Image(CssImageId),
1711 Color(ColorU),
1712}
1713
1714impl fmt::Debug for StyleBackgroundContent {
1715 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1716 use self::StyleBackgroundContent::*;
1717 match self {
1718 LinearGradient(l) => write!(f, "{}", l),
1719 RadialGradient(r) => write!(f, "{}", r),
1720 Image(id) => write!(f, "image({})", id),
1721 Color(c) => write!(f, "{}", c),
1722 }
1723 }
1724}
1725
1726impl StyleBackgroundContent {
1727 pub fn get_css_image_id(&self) -> Option<&CssImageId> {
1728 match self {
1729 StyleBackgroundContent::Image(i) => Some(i),
1730 _ => None,
1731 }
1732 }
1733}
1734
1735impl<'a> From<CssImageId> for StyleBackgroundContent {
1736 fn from(id: CssImageId) -> Self {
1737 StyleBackgroundContent::Image(id)
1738 }
1739}
1740
1741#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1742pub struct LinearGradient {
1743 pub direction: Direction,
1744 pub extend_mode: ExtendMode,
1745 pub stops: Vec<GradientStopPre>,
1746}
1747
1748impl fmt::Display for LinearGradient {
1749 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1750 let prefix = match self.extend_mode {
1751 ExtendMode::Clamp => "linear-gradient",
1752 ExtendMode::Repeat => "repeating-linear-gradient",
1753 };
1754
1755 write!(f, "{}({}", prefix, self.direction)?;
1756 for s in &self.stops {
1757 write!(f, ", {}", s)?;
1758 }
1759 write!(f, ")")
1760 }
1761}
1762
1763#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1764pub struct RadialGradient {
1765 pub shape: Shape,
1766 pub extend_mode: ExtendMode,
1767 pub stops: Vec<GradientStopPre>,
1768}
1769
1770impl fmt::Display for RadialGradient {
1771 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1772 let prefix = match self.extend_mode {
1773 ExtendMode::Clamp => "radial-gradient",
1774 ExtendMode::Repeat => "repeating-radial-gradient",
1775 };
1776
1777 write!(f, "{}({}", prefix, self.shape)?;
1778 for s in &self.stops {
1779 write!(f, ", {}", s)?;
1780 }
1781 write!(f, ")")
1782 }
1783}
1784
1785#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1788pub enum Direction {
1789 Angle(FloatValue),
1790 FromTo(DirectionCorner, DirectionCorner),
1791}
1792
1793impl fmt::Display for Direction {
1794 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1795 use self::Direction::*;
1796 match self {
1797 Angle(d) => write!(f, "{}deg", d.get()),
1798 FromTo(_, t) => write!(f, "to {}", t),
1799 }
1800 }
1801}
1802
1803impl Direction {
1804
1805 pub fn to_points(&self, rect: &LayoutRect)
1807 -> (LayoutPoint, LayoutPoint)
1808 {
1809 match self {
1810 Direction::Angle(deg) => {
1811 let deg = deg.get(); let deg = -deg; let width_half = rect.size.width as usize / 2;
1820 let height_half = rect.size.height as usize / 2;
1821
1822 let hypotenuse_len = (((width_half * width_half) + (height_half * height_half)) as f64).sqrt();
1824
1825 let angle_to_top_left = (height_half as f64 / width_half as f64).atan().to_degrees();
1830
1831 let ending_point_degrees = if deg < 90.0 {
1833 90.0 - angle_to_top_left
1835 } else if deg < 180.0 {
1836 90.0 + angle_to_top_left
1838 } else if deg < 270.0 {
1839 270.0 - angle_to_top_left
1841 } else {
1842 270.0 + angle_to_top_left
1844 };
1845
1846 let degree_diff_to_corner = ending_point_degrees - deg as f64;
1848
1849 let searched_len = (hypotenuse_len * degree_diff_to_corner.to_radians().cos()).abs();
1852
1853 let dx = deg.to_radians().sin() * searched_len as f32;
1858 let dy = deg.to_radians().cos() * searched_len as f32;
1859
1860 let start_point_location = LayoutPoint { x: width_half as f32 + dx, y: height_half as f32 + dy };
1861 let end_point_location = LayoutPoint { x: width_half as f32 - dx, y: height_half as f32 - dy };
1862
1863 (start_point_location, end_point_location)
1864 },
1865 Direction::FromTo(from, to) => {
1866 (from.to_point(rect), to.to_point(rect))
1867 }
1868 }
1869 }
1870}
1871
1872#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1873pub enum Shape {
1874 Ellipse,
1875 Circle,
1876}
1877
1878impl fmt::Display for Shape {
1879 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1880 use self::Shape::*;
1881 match self {
1882 Ellipse => write!(f, "ellipse"),
1883 Circle => write!(f, "circle"),
1884 }
1885 }
1886}
1887
1888#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1889pub enum StyleCursor {
1890 Alias,
1892 AllScroll,
1894 Cell,
1896 ColResize,
1898 ContextMenu,
1900 Copy,
1902 Crosshair,
1904 Default,
1906 EResize,
1908 EwResize,
1910 Grab,
1912 Grabbing,
1914 Help,
1916 Move,
1918 NResize,
1920 NsResize,
1922 NeswResize,
1924 NwseResize,
1926 Pointer,
1928 Progress,
1930 RowResize,
1932 SResize,
1934 SeResize,
1936 Text,
1938 Unset,
1940 VerticalText,
1942 WResize,
1944 Wait,
1946 ZoomIn,
1948 ZoomOut,
1950}
1951
1952impl Default for StyleCursor {
1953 fn default() -> StyleCursor {
1954 StyleCursor::Default
1955 }
1956}
1957
1958#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1959pub enum DirectionCorner {
1960 Right,
1961 Left,
1962 Top,
1963 Bottom,
1964 TopRight,
1965 TopLeft,
1966 BottomRight,
1967 BottomLeft,
1968}
1969
1970impl fmt::Display for DirectionCorner {
1971 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1972 use self::DirectionCorner::*;
1973 match self {
1974 Right => write!(f, "right"),
1975 Left => write!(f, "left"),
1976 Top => write!(f, "top"),
1977 Bottom => write!(f, "bottom"),
1978 TopRight => write!(f, "top right"),
1979 TopLeft => write!(f, "top left"),
1980 BottomRight => write!(f, "bottom right"),
1981 BottomLeft => write!(f, "bottom left"),
1982 }
1983 }
1984}
1985
1986impl DirectionCorner {
1987
1988 pub fn opposite(&self) -> Self {
1989 use self::DirectionCorner::*;
1990 match *self {
1991 Right => Left,
1992 Left => Right,
1993 Top => Bottom,
1994 Bottom => Top,
1995 TopRight => BottomLeft,
1996 BottomLeft => TopRight,
1997 TopLeft => BottomRight,
1998 BottomRight => TopLeft,
1999 }
2000 }
2001
2002 pub fn combine(&self, other: &Self) -> Option<Self> {
2003 use self::DirectionCorner::*;
2004 match (*self, *other) {
2005 (Right, Top) | (Top, Right) => Some(TopRight),
2006 (Left, Top) | (Top, Left) => Some(TopLeft),
2007 (Right, Bottom) | (Bottom, Right) => Some(BottomRight),
2008 (Left, Bottom) | (Bottom, Left) => Some(BottomLeft),
2009 _ => { None }
2010 }
2011 }
2012
2013 pub fn to_point(&self, rect: &LayoutRect) -> LayoutPoint
2014 {
2015 use self::DirectionCorner::*;
2016 match *self {
2017 Right => LayoutPoint { x: rect.size.width, y: rect.size.height / 2.0 },
2018 Left => LayoutPoint { x: 0.0, y: rect.size.height / 2.0 },
2019 Top => LayoutPoint { x: rect.size.width / 2.0, y: 0.0 },
2020 Bottom => LayoutPoint { x: rect.size.width / 2.0, y: rect.size.height },
2021 TopRight => LayoutPoint { x: rect.size.width, y: 0.0 },
2022 TopLeft => LayoutPoint { x: 0.0, y: 0.0 },
2023 BottomRight => LayoutPoint { x: rect.size.width, y: rect.size.height },
2024 BottomLeft => LayoutPoint { x: 0.0, y: rect.size.height },
2025 }
2026 }
2027}
2028
2029#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2030pub enum GradientType {
2031 LinearGradient,
2032 RepeatingLinearGradient,
2033 RadialGradient,
2034 RepeatingRadialGradient,
2035}
2036
2037#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2044pub struct CssImageId(pub String);
2045
2046impl fmt::Display for CssImageId {
2047 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2048 write!(f, "{}", self.0)
2049 }
2050}
2051
2052
2053#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2054pub struct GradientStopPre {
2055 pub offset: Option<PercentageValue>,
2057 pub color: ColorU,
2058}
2059
2060impl fmt::Display for GradientStopPre {
2061 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2062 self.color.write_hash(f)?;
2063 if let Some(offset) = self.offset {
2064 write!(f, " {}", offset)?;
2065 }
2066 Ok(())
2067 }
2068}
2069
2070#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2072pub struct LayoutWidth(pub PixelValue);
2073#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2075pub struct LayoutMinWidth(pub PixelValue);
2076#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2078pub struct LayoutMaxWidth(pub PixelValue);
2079#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2081pub struct LayoutHeight(pub PixelValue);
2082#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2084pub struct LayoutMinHeight(pub PixelValue);
2085#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2087pub struct LayoutMaxHeight(pub PixelValue);
2088
2089impl_pixel_value!(LayoutWidth);
2090impl_pixel_value!(LayoutHeight);
2091impl_pixel_value!(LayoutMinHeight);
2092impl_pixel_value!(LayoutMinWidth);
2093impl_pixel_value!(LayoutMaxWidth);
2094impl_pixel_value!(LayoutMaxHeight);
2095
2096#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2098pub struct LayoutTop(pub PixelValue);
2099#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2101pub struct LayoutLeft(pub PixelValue);
2102#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2104pub struct LayoutRight(pub PixelValue);
2105#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2107pub struct LayoutBottom(pub PixelValue);
2108
2109impl_pixel_value!(LayoutTop);
2110impl_pixel_value!(LayoutBottom);
2111impl_pixel_value!(LayoutRight);
2112impl_pixel_value!(LayoutLeft);
2113
2114#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2116pub struct LayoutPaddingTop(pub PixelValue);
2117#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2119pub struct LayoutPaddingLeft(pub PixelValue);
2120#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2122pub struct LayoutPaddingRight(pub PixelValue);
2123#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2125pub struct LayoutPaddingBottom(pub PixelValue);
2126
2127impl_pixel_value!(LayoutPaddingTop);
2128impl_pixel_value!(LayoutPaddingBottom);
2129impl_pixel_value!(LayoutPaddingRight);
2130impl_pixel_value!(LayoutPaddingLeft);
2131
2132#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2134pub struct LayoutMarginTop(pub PixelValue);
2135#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2137pub struct LayoutMarginLeft(pub PixelValue);
2138#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2140pub struct LayoutMarginRight(pub PixelValue);
2141#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2143pub struct LayoutMarginBottom(pub PixelValue);
2144
2145impl_pixel_value!(LayoutMarginTop);
2146impl_pixel_value!(LayoutMarginBottom);
2147impl_pixel_value!(LayoutMarginRight);
2148impl_pixel_value!(LayoutMarginLeft);
2149
2150#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2152pub struct LayoutFlexGrow(pub FloatValue);
2153
2154impl Default for LayoutFlexGrow {
2155 fn default() -> Self {
2156 LayoutFlexGrow(FloatValue::const_new(0))
2157 }
2158}
2159
2160#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2162pub struct LayoutFlexShrink(pub FloatValue);
2163
2164impl Default for LayoutFlexShrink {
2165 fn default() -> Self {
2166 LayoutFlexShrink(FloatValue::const_new(0))
2167 }
2168}
2169
2170impl_float_value!(LayoutFlexGrow);
2171impl_float_value!(LayoutFlexShrink);
2172
2173#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2175pub enum LayoutDirection {
2176 Row,
2177 RowReverse,
2178 Column,
2179 ColumnReverse,
2180}
2181
2182impl Default for LayoutDirection {
2183 fn default() -> Self {
2184 LayoutDirection::Row
2185 }
2186}
2187
2188impl LayoutDirection {
2189 pub fn get_axis(&self) -> LayoutAxis {
2190 use self::{LayoutAxis::*, LayoutDirection::*};
2191 match self {
2192 Row | RowReverse => Horizontal,
2193 Column | ColumnReverse => Vertical,
2194 }
2195 }
2196
2197 pub fn is_reverse(&self) -> bool {
2199 *self == LayoutDirection::RowReverse || *self == LayoutDirection::ColumnReverse
2200 }
2201}
2202
2203#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2205pub enum LayoutBoxSizing {
2206 ContentBox,
2207 BorderBox,
2208}
2209
2210impl Default for LayoutBoxSizing {
2211 fn default() -> Self {
2212 LayoutBoxSizing::ContentBox
2213 }
2214}
2215
2216#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2218pub struct StyleLineHeight(pub PercentageValue);
2219#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2221pub struct StyleTabWidth(pub PercentageValue);
2222
2223impl_percentage_value!(StyleTabWidth);
2224impl_percentage_value!(StyleLineHeight);
2225
2226#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2228pub struct StyleLetterSpacing(pub PixelValue);
2229#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2231pub struct StyleWordSpacing(pub PixelValue);
2232
2233impl_pixel_value!(StyleLetterSpacing);
2234impl_pixel_value!(StyleWordSpacing);
2235
2236#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2240pub enum LayoutAxis {
2241 Horizontal,
2242 Vertical,
2243}
2244
2245#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2247pub enum LayoutDisplay {
2248 Flex,
2249 Block,
2250 InlineBlock,
2251}
2252
2253impl Default for LayoutDisplay {
2254 fn default() -> Self {
2255 LayoutDisplay::Block
2256 }
2257}
2258
2259#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2261pub enum LayoutFloat {
2262 Left,
2263 Right,
2264}
2265
2266impl Default for LayoutFloat {
2267 fn default() -> Self {
2268 LayoutFloat::Left
2269 }
2270}
2271
2272
2273#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2277pub enum LayoutPosition {
2278 Static,
2279 Relative,
2280 Absolute,
2281 Fixed,
2282}
2283
2284impl Default for LayoutPosition {
2285 fn default() -> Self {
2286 LayoutPosition::Static
2287 }
2288}
2289
2290#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2292pub enum LayoutWrap {
2293 Wrap,
2294 NoWrap,
2295}
2296
2297impl Default for LayoutWrap {
2298 fn default() -> Self {
2299 LayoutWrap::Wrap
2300 }
2301}
2302
2303#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2305pub enum LayoutJustifyContent {
2306 Start,
2308 End,
2310 Center,
2312 SpaceBetween,
2314 SpaceAround,
2316 SpaceEvenly,
2319}
2320
2321impl Default for LayoutJustifyContent {
2322 fn default() -> Self {
2323 LayoutJustifyContent::Start
2324 }
2325}
2326
2327#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2329pub enum LayoutAlignItems {
2330 Stretch,
2332 Center,
2334 Start,
2336 End,
2338}
2339
2340impl Default for LayoutAlignItems {
2341 fn default() -> Self {
2342 LayoutAlignItems::Start
2343 }
2344}
2345
2346#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2348pub enum LayoutAlignContent {
2349 Stretch,
2351 Center,
2353 Start,
2355 End,
2357 SpaceBetween,
2359 SpaceAround,
2361}
2362
2363impl Default for LayoutAlignContent {
2364 fn default() -> Self {
2365 LayoutAlignContent::Stretch
2366 }
2367}
2368
2369#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2372pub enum Overflow {
2373 Scroll,
2375 Auto,
2377 Hidden,
2379 Visible,
2381}
2382
2383impl Default for Overflow {
2384 fn default() -> Self {
2385 Overflow::Auto
2386 }
2387}
2388
2389impl Overflow {
2390
2391 pub fn needs_scrollbar(&self, currently_overflowing: bool) -> bool {
2397 use self::Overflow::*;
2398 match self {
2399 Scroll => true,
2400 Auto => currently_overflowing,
2401 Hidden | Visible => false,
2402 }
2403 }
2404
2405 pub fn is_overflow_visible(&self) -> bool {
2408 *self == Overflow::Visible
2409 }
2410}
2411
2412#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2414pub enum StyleTextAlignmentHorz {
2415 Left,
2416 Center,
2417 Right,
2418}
2419
2420impl Default for StyleTextAlignmentHorz {
2421 fn default() -> Self {
2422 StyleTextAlignmentHorz::Left
2423 }
2424}
2425
2426#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2428pub enum StyleTextAlignmentVert {
2429 Top,
2430 Center,
2431 Bottom,
2432}
2433
2434impl Default for StyleTextAlignmentVert {
2435 fn default() -> Self {
2436 StyleTextAlignmentVert::Top
2437 }
2438}
2439
2440#[derive(Default, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2442pub struct RectStyle {
2443
2444 pub background: Option<CssPropertyValue<StyleBackgroundContent>>,
2445 pub background_position: Option<CssPropertyValue<StyleBackgroundPosition>>,
2446 pub background_size: Option<CssPropertyValue<StyleBackgroundSize>>,
2447 pub background_repeat: Option<CssPropertyValue<StyleBackgroundRepeat>>,
2448 pub font_size: Option<CssPropertyValue<StyleFontSize>>,
2449 pub font_family: Option<CssPropertyValue<StyleFontFamily>>,
2450 pub text_color: Option<CssPropertyValue<StyleTextColor>>,
2451 pub text_align: Option<CssPropertyValue<StyleTextAlignmentHorz>>,
2452 pub line_height: Option<CssPropertyValue<StyleLineHeight>>,
2453 pub letter_spacing: Option<CssPropertyValue<StyleLetterSpacing>>,
2454 pub word_spacing: Option<CssPropertyValue<StyleWordSpacing>>,
2455 pub tab_width: Option<CssPropertyValue<StyleTabWidth>>,
2456 pub cursor: Option<CssPropertyValue<StyleCursor>>,
2457
2458 pub box_shadow_left: Option<CssPropertyValue<BoxShadowPreDisplayItem>>,
2459 pub box_shadow_right: Option<CssPropertyValue<BoxShadowPreDisplayItem>>,
2460 pub box_shadow_top: Option<CssPropertyValue<BoxShadowPreDisplayItem>>,
2461 pub box_shadow_bottom: Option<CssPropertyValue<BoxShadowPreDisplayItem>>,
2462
2463 pub border_top_color: Option<CssPropertyValue<StyleBorderTopColor>>,
2464 pub border_left_color: Option<CssPropertyValue<StyleBorderLeftColor>>,
2465 pub border_right_color: Option<CssPropertyValue<StyleBorderRightColor>>,
2466 pub border_bottom_color: Option<CssPropertyValue<StyleBorderBottomColor>>,
2467
2468 pub border_top_style: Option<CssPropertyValue<StyleBorderTopStyle>>,
2469 pub border_left_style: Option<CssPropertyValue<StyleBorderLeftStyle>>,
2470 pub border_right_style: Option<CssPropertyValue<StyleBorderRightStyle>>,
2471 pub border_bottom_style: Option<CssPropertyValue<StyleBorderBottomStyle>>,
2472
2473 pub border_top_left_radius: Option<CssPropertyValue<StyleBorderTopLeftRadius>>,
2474 pub border_top_right_radius: Option<CssPropertyValue<StyleBorderTopRightRadius>>,
2475 pub border_bottom_left_radius: Option<CssPropertyValue<StyleBorderBottomLeftRadius>>,
2476 pub border_bottom_right_radius: Option<CssPropertyValue<StyleBorderBottomRightRadius>>,
2477}
2478
2479#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2481pub struct RectLayout {
2482 pub display: Option<CssPropertyValue<LayoutDisplay>>,
2483 pub float: Option<CssPropertyValue<LayoutFloat>>,
2484 pub box_sizing: Option<CssPropertyValue<LayoutBoxSizing>>,
2485
2486 pub width: Option<CssPropertyValue<LayoutWidth>>,
2487 pub height: Option<CssPropertyValue<LayoutHeight>>,
2488 pub min_width: Option<CssPropertyValue<LayoutMinWidth>>,
2489 pub min_height: Option<CssPropertyValue<LayoutMinHeight>>,
2490 pub max_width: Option<CssPropertyValue<LayoutMaxWidth>>,
2491 pub max_height: Option<CssPropertyValue<LayoutMaxHeight>>,
2492
2493 pub position: Option<CssPropertyValue<LayoutPosition>>,
2494 pub top: Option<CssPropertyValue<LayoutTop>>,
2495 pub bottom: Option<CssPropertyValue<LayoutBottom>>,
2496 pub right: Option<CssPropertyValue<LayoutRight>>,
2497 pub left: Option<CssPropertyValue<LayoutLeft>>,
2498
2499 pub padding_top: Option<CssPropertyValue<LayoutPaddingTop>>,
2500 pub padding_bottom: Option<CssPropertyValue<LayoutPaddingBottom>>,
2501 pub padding_left: Option<CssPropertyValue<LayoutPaddingLeft>>,
2502 pub padding_right: Option<CssPropertyValue<LayoutPaddingRight>>,
2503
2504 pub margin_top: Option<CssPropertyValue<LayoutMarginTop>>,
2505 pub margin_bottom: Option<CssPropertyValue<LayoutMarginBottom>>,
2506 pub margin_left: Option<CssPropertyValue<LayoutMarginLeft>>,
2507 pub margin_right: Option<CssPropertyValue<LayoutMarginRight>>,
2508
2509 pub border_top_width: Option<CssPropertyValue<StyleBorderTopWidth>>,
2510 pub border_left_width: Option<CssPropertyValue<StyleBorderLeftWidth>>,
2511 pub border_right_width: Option<CssPropertyValue<StyleBorderRightWidth>>,
2512 pub border_bottom_width: Option<CssPropertyValue<StyleBorderBottomWidth>>,
2513
2514 pub overflow_x: Option<CssPropertyValue<Overflow>>,
2515 pub overflow_y: Option<CssPropertyValue<Overflow>>,
2516
2517 pub direction: Option<CssPropertyValue<LayoutDirection>>,
2518 pub wrap: Option<CssPropertyValue<LayoutWrap>>,
2519 pub flex_grow: Option<CssPropertyValue<LayoutFlexGrow>>,
2520 pub flex_shrink: Option<CssPropertyValue<LayoutFlexShrink>>,
2521 pub justify_content: Option<CssPropertyValue<LayoutJustifyContent>>,
2522 pub align_items: Option<CssPropertyValue<LayoutAlignItems>>,
2523 pub align_content: Option<CssPropertyValue<LayoutAlignContent>>,
2524}
2525
2526#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2528pub struct ScrollbarInfo {
2529 pub width: LayoutWidth,
2531 pub padding_left: LayoutPaddingLeft,
2533 pub padding_right: LayoutPaddingRight,
2534 pub track: RectStyle,
2537 pub thumb: RectStyle,
2539 pub button: RectStyle,
2541 pub corner: RectStyle,
2544 pub resizer: RectStyle,
2547}
2548
2549impl Default for ScrollbarInfo {
2550 fn default() -> Self {
2551 ScrollbarInfo {
2552 width: LayoutWidth(PixelValue::px(17.0)),
2553 padding_left: LayoutPaddingLeft(PixelValue::px(2.0)),
2554 padding_right: LayoutPaddingRight(PixelValue::px(2.0)),
2555 track: RectStyle {
2556 background: Some(CssPropertyValue::Exact(StyleBackgroundContent::Color(ColorU {
2557 r: 241, g: 241, b: 241, a: 255
2558 }))),
2559 .. Default::default()
2560 },
2561 thumb: RectStyle {
2562 background: Some(CssPropertyValue::Exact(StyleBackgroundContent::Color(ColorU {
2563 r: 193, g: 193, b: 193, a: 255
2564 }))),
2565 .. Default::default()
2566 },
2567 button: RectStyle {
2568 background: Some(CssPropertyValue::Exact(StyleBackgroundContent::Color(ColorU {
2569 r: 163, g: 163, b: 163, a: 255
2570 }))),
2571 .. Default::default()
2572 },
2573 corner: RectStyle::default(),
2574 resizer: RectStyle::default(),
2575 }
2576 }
2577}
2578
2579#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2586pub struct ScrollbarStyle {
2587 pub horizontal: Option<ScrollbarInfo>,
2589 pub vertical: Option<ScrollbarInfo>,
2591}
2592
2593impl RectStyle {
2594
2595 pub fn get_horizontal_scrollbar_style(&self) -> ScrollbarInfo {
2596 ScrollbarInfo::default()
2597 }
2598
2599 pub fn get_vertical_scrollbar_style(&self) -> ScrollbarInfo {
2600 ScrollbarInfo::default()
2601 }
2602
2603 pub fn has_box_shadow(&self) -> bool {
2604 self.box_shadow_left.and_then(|bs| bs.get_property().map(|_| ())).is_some() ||
2605 self.box_shadow_right.and_then(|bs| bs.get_property().map(|_| ())).is_some() ||
2606 self.box_shadow_top.and_then(|bs| bs.get_property().map(|_| ())).is_some() ||
2607 self.box_shadow_bottom.and_then(|bs| bs.get_property().map(|_| ())).is_some()
2608 }
2609
2610 pub fn has_border(&self) -> bool {
2611 self.border_left_style.and_then(|bs| bs.get_property_or_default()).is_some() ||
2612 self.border_right_style.and_then(|bs| bs.get_property_or_default()).is_some() ||
2613 self.border_top_style.and_then(|bs| bs.get_property_or_default()).is_some() ||
2614 self.border_bottom_style.and_then(|bs| bs.get_property_or_default()).is_some()
2615 }
2616}
2617
2618impl RectLayout {
2619
2620 pub fn is_horizontal_overflow_visible(&self) -> bool {
2621 self.overflow_x.map(|css_prop| css_prop.get_property().map(|overflow| overflow.is_overflow_visible()).unwrap_or_default()) == Some(true)
2622 }
2623
2624 pub fn is_vertical_overflow_visible(&self) -> bool {
2625 self.overflow_y.map(|css_prop| css_prop.get_property().map(|overflow| overflow.is_overflow_visible()).unwrap_or_default()) == Some(true)
2626 }
2627}
2628
2629#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2631pub struct StyleFontSize(pub PixelValue);
2632
2633impl_pixel_value!(StyleFontSize);
2634
2635#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2637pub struct StyleFontFamily {
2638 pub fonts: Vec<FontId>
2640}
2641
2642#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2643pub struct FontId(pub String);
2644
2645impl FontId {
2646 pub fn get_str(&self) -> &str {
2647 &self.0
2648 }
2649}