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