Skip to main content

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