style/values/computed/
border.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5//! Computed types for CSS values related to borders.
6
7use crate::derives::*;
8use crate::properties::{LogicalGroupId, LonghandId};
9use crate::values::animated::{Context as AnimatedContext, ToAnimatedValue};
10use crate::values::computed::length::{
11    CSSPixelLength, NonNegativeLength, NonNegativeLengthPercentage,
12};
13use crate::values::computed::{NonNegativeNumber, NonNegativeNumberOrPercentage};
14use crate::values::generics::border::{
15    GenericBorderCornerRadius, GenericBorderImageSideWidth, GenericBorderImageSlice,
16    GenericBorderRadius, GenericBorderSpacing,
17};
18use crate::values::generics::rect::Rect;
19use crate::values::generics::size::Size2D;
20use crate::values::generics::NonNegative;
21use crate::values::resolved::{Context as ResolvedContext, ToResolvedValue};
22use crate::Zero;
23use app_units::Au;
24
25pub use crate::values::specified::border::BorderImageRepeat;
26
27/// A computed value for -webkit-text-stroke-width.
28pub type LineWidth = Au;
29
30/// A computed value for border-width (and the like).
31#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss, ToTyped, From)]
32#[repr(transparent)]
33#[typed_value(derive_fields)]
34pub struct BorderSideWidth(pub Au);
35
36impl BorderSideWidth {
37    /// The `medium` value.
38    pub fn medium() -> Self {
39        Self(Au::from_px(3))
40    }
41}
42
43impl ToAnimatedValue for BorderSideWidth {
44    type AnimatedValue = CSSPixelLength;
45
46    #[inline]
47    fn to_animated_value(self, context: &AnimatedContext) -> Self::AnimatedValue {
48        self.0.to_animated_value(context)
49    }
50
51    #[inline]
52    fn from_animated_value(animated: Self::AnimatedValue) -> Self {
53        Self(Au::from_animated_value(animated))
54    }
55}
56
57impl ToResolvedValue for BorderSideWidth {
58    type ResolvedValue = CSSPixelLength;
59
60    fn to_resolved_value(self, context: &ResolvedContext) -> Self::ResolvedValue {
61        let resolved_length = CSSPixelLength::from(self.0).to_resolved_value(context);
62        if !context
63            .current_longhand
64            .is_some_and(|l| l.logical_group() == Some(LogicalGroupId::BorderWidth))
65        {
66            return resolved_length;
67        }
68        // Only for border widths, a style of none/hidden causes the resolved value to be zero.
69        let style = match context.current_longhand.unwrap() {
70            LonghandId::BorderTopWidth => context.style.clone_border_top_style(),
71            LonghandId::BorderRightWidth => context.style.clone_border_right_style(),
72            LonghandId::BorderBottomWidth => context.style.clone_border_bottom_style(),
73            LonghandId::BorderLeftWidth => context.style.clone_border_left_style(),
74            _ => {
75                debug_assert!(false, "Expected a physical longhand");
76                return resolved_length;
77            },
78        };
79        if style.none_or_hidden() {
80            return CSSPixelLength::new(0.0);
81        }
82        resolved_length
83    }
84
85    #[inline]
86    fn from_resolved_value(value: Self::ResolvedValue) -> Self {
87        Self(Au::from_f32_px(value.px()))
88    }
89}
90
91/// A computed value for outline-offset
92pub type BorderSideOffset = Au;
93
94/// A computed value for the `border-image-width` property.
95pub type BorderImageWidth = Rect<BorderImageSideWidth>;
96
97/// A computed value for a single side of a `border-image-width` property.
98pub type BorderImageSideWidth =
99    GenericBorderImageSideWidth<NonNegativeLengthPercentage, NonNegativeNumber>;
100
101/// A computed value for the `border-image-slice` property.
102pub type BorderImageSlice = GenericBorderImageSlice<NonNegativeNumberOrPercentage>;
103
104/// A computed value for the `border-radius` property.
105pub type BorderRadius = GenericBorderRadius<NonNegativeLengthPercentage>;
106
107/// A computed value for the `border-*-radius` longhand properties.
108pub type BorderCornerRadius = GenericBorderCornerRadius<NonNegativeLengthPercentage>;
109
110/// A computed value for the `border-spacing` longhand property.
111pub type BorderSpacing = GenericBorderSpacing<NonNegativeLength>;
112
113impl BorderImageSideWidth {
114    /// Returns `1`.
115    #[inline]
116    pub fn one() -> Self {
117        GenericBorderImageSideWidth::Number(NonNegative(1.))
118    }
119}
120
121impl BorderImageSlice {
122    /// Returns the `100%` value.
123    #[inline]
124    pub fn hundred_percent() -> Self {
125        GenericBorderImageSlice {
126            offsets: Rect::all(NonNegativeNumberOrPercentage::hundred_percent()),
127            fill: false,
128        }
129    }
130}
131
132impl BorderSpacing {
133    /// Returns `0 0`.
134    pub fn zero() -> Self {
135        GenericBorderSpacing(Size2D::new(
136            NonNegativeLength::zero(),
137            NonNegativeLength::zero(),
138        ))
139    }
140
141    /// Returns the horizontal spacing.
142    pub fn horizontal(&self) -> Au {
143        Au::from(*self.0.width())
144    }
145
146    /// Returns the vertical spacing.
147    pub fn vertical(&self) -> Au {
148        Au::from(*self.0.height())
149    }
150}