style/values/computed/
position.rs1use crate::values::computed::{Integer, LengthPercentage, NonNegativeNumber, Percentage};
11use crate::values::generics::position::Position as GenericPosition;
12use crate::values::generics::position::PositionComponent as GenericPositionComponent;
13use crate::values::generics::position::PositionOrAuto as GenericPositionOrAuto;
14use crate::values::generics::position::ZIndex as GenericZIndex;
15use crate::values::generics::position::{
16 AnchorSideKeyword, GenericAnchorFunction, GenericAnchorSide,
17};
18use crate::values::generics::position::{AspectRatio as GenericAspectRatio, GenericInset};
19pub use crate::values::specified::position::{
20 AnchorName, AnchorScope, DashedIdentAndOrTryTactic, PositionAnchor, PositionArea,
21 PositionAreaKeyword, PositionTryFallbacks, PositionTryOrder, PositionVisibility,
22};
23pub use crate::values::specified::position::{GridAutoFlow, GridTemplateAreas, MasonryAutoFlow};
24use crate::Zero;
25use std::fmt::{self, Write};
26use style_traits::{CssWriter, ToCss};
27
28pub type Position = GenericPosition<HorizontalPosition, VerticalPosition>;
30
31pub type PositionOrAuto = GenericPositionOrAuto<Position>;
33
34pub type HorizontalPosition = LengthPercentage;
36
37pub type VerticalPosition = LengthPercentage;
39
40pub type AnchorSide = GenericAnchorSide<Percentage>;
42
43impl AnchorSide {
44 pub fn keyword_and_percentage(&self) -> (AnchorSideKeyword, Percentage) {
46 match self {
47 Self::Percentage(p) => (AnchorSideKeyword::Start, *p),
48 Self::Keyword(k) => {
49 if matches!(k, AnchorSideKeyword::Center) {
50 (AnchorSideKeyword::Start, Percentage(0.5))
51 } else {
52 (*k, Percentage::zero())
53 }
54 },
55 }
56 }
57}
58
59pub type AnchorFunction = GenericAnchorFunction<Percentage, Inset>;
61
62#[cfg(feature = "gecko")]
63use crate::{
64 gecko_bindings::structs::AnchorPosOffsetResolutionParams,
65 logical_geometry::PhysicalSide,
66 values::{computed::Length, DashedIdent},
67};
68
69impl AnchorFunction {
70 #[cfg(feature = "gecko")]
72 pub fn resolve(
73 anchor_name: &DashedIdent,
74 anchor_side: &AnchorSide,
75 prop_side: PhysicalSide,
76 params: &AnchorPosOffsetResolutionParams,
77 ) -> Result<Length, ()> {
78 use crate::gecko_bindings::structs::Gecko_GetAnchorPosOffset;
79
80 let (keyword, percentage) = anchor_side.keyword_and_percentage();
81 let mut offset = Length::zero();
82 let valid = unsafe {
83 Gecko_GetAnchorPosOffset(
84 params,
85 anchor_name.0.as_ptr(),
86 prop_side as u8,
87 keyword as u8,
88 percentage.0,
89 &mut offset,
90 )
91 };
92
93 if !valid {
94 return Err(());
95 }
96
97 Ok(offset)
98 }
99}
100
101pub type Inset = GenericInset<Percentage, LengthPercentage>;
103
104impl Position {
105 #[inline]
107 pub fn center() -> Self {
108 Self::new(
109 LengthPercentage::new_percent(Percentage(0.5)),
110 LengthPercentage::new_percent(Percentage(0.5)),
111 )
112 }
113
114 #[inline]
116 pub fn zero() -> Self {
117 Self::new(LengthPercentage::zero(), LengthPercentage::zero())
118 }
119}
120
121impl ToCss for Position {
122 fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
123 where
124 W: Write,
125 {
126 self.horizontal.to_css(dest)?;
127 dest.write_char(' ')?;
128 self.vertical.to_css(dest)
129 }
130}
131
132impl GenericPositionComponent for LengthPercentage {
133 fn is_center(&self) -> bool {
134 match self.to_percentage() {
135 Some(Percentage(per)) => per == 0.5,
136 _ => false,
137 }
138 }
139}
140
141pub type ZIndex = GenericZIndex<Integer>;
143
144pub type AspectRatio = GenericAspectRatio<NonNegativeNumber>;