/* This Source Code Form is subject to the terms of the Mozilla Public *License,v.2.0.IfacopyoftheMPLwasnotdistributedwiththis
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
//! Specified angles.
usecrate::parser::{Parse, ParserContext}; usecrate::values::computed::angle::Angle as ComputedAngle; usecrate::values::computed::{Context, ToComputedValue}; usecrate::values::specified::calc::CalcNode; usecrate::values::CSSFloat; usecrate::Zero; use cssparser::{Parser, Token}; use std::f32::consts::PI; use std::fmt::{self, Write}; use style_traits::{CssWriter, ParseError, SpecifiedValueInfo, ToCss};
/// A specified angle dimension. #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] #[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, PartialOrd, ToCss, ToShmem)] pubenum AngleDimension { /// An angle with degree unit. #[css(dimension)]
Deg(CSSFloat), /// An angle with gradian unit. #[css(dimension)]
Grad(CSSFloat), /// An angle with radian unit. #[css(dimension)]
Rad(CSSFloat), /// An angle with turn unit. #[css(dimension)]
Turn(CSSFloat),
}
impl Zero for AngleDimension { fn zero() -> Self {
AngleDimension::Deg(0.)
}
/// A specified Angle value, which is just the angle dimension, plus whether it /// was specified as `calc()` or not. #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] #[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToShmem)] pubstruct Angle {
value: AngleDimension,
was_calc: bool,
}
impl Zero for Angle { fn zero() -> Self { Self {
value: Zero::zero(),
was_calc: false,
}
}
impl Angle { /// Creates an angle with the given value in degrees. #[inline] pubfn from_degrees(value: CSSFloat, was_calc: bool) -> Self {
Angle {
value: AngleDimension::Deg(value),
was_calc,
}
}
/// Creates an angle with the given value in radians. #[inline] pubfn from_radians(value: CSSFloat) -> Self {
Angle {
value: AngleDimension::Rad(value),
was_calc: false,
}
}
/// Returns the value of the angle in degrees, mostly for `calc()`. #[inline] pubfn degrees(&self) -> CSSFloat { self.value.degrees()
}
/// Returns the value of the angle in radians. #[inline] pubfn radians(&self) -> CSSFloat { const RAD_PER_DEG: f32 = PI / 180.0; self.value.degrees() * RAD_PER_DEG
}
/// Whether this specified angle came from a `calc()` expression. #[inline] pubfn was_calc(&self) -> bool { self.was_calc
}
/// Returns an `Angle` parsed from a `calc()` expression. pubfn from_calc(degrees: CSSFloat) -> Self {
Angle {
value: AngleDimension::Deg(degrees),
was_calc: true,
}
}
/// Returns the unit of the angle. #[inline] pubfn unit(&self) -> &'static str { self.value.unit()
}
}
impl Parse for Angle { /// Parses an angle according to CSS-VALUES § 6.1. fn parse<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> { Self::parse_internal(context, input, AllowUnitlessZeroAngle::No)
}
}
impl Angle { /// Parse an `<angle>` value given a value and an unit. pubfn parse_dimension(value: CSSFloat, unit: &str, was_calc: bool) -> Result<Angle, ()> { let value = match_ignore_ascii_case! { unit, "deg" => AngleDimension::Deg(value), "grad" => AngleDimension::Grad(value), "turn" => AngleDimension::Turn(value), "rad" => AngleDimension::Rad(value),
_ => return Err(())
};
Ok(Self { value, was_calc })
}
/// Parse an `<angle>` allowing unitless zero to represent a zero angle. /// /// See the comment in `AllowUnitlessZeroAngle` for why. #[inline] pubfn parse_with_unitless<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> { Self::parse_internal(context, input, AllowUnitlessZeroAngle::Yes)
}
pub(super) fn parse_internal<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
allow_unitless_zero: AllowUnitlessZeroAngle,
) -> Result<Self, ParseError<'i>> { let location = input.current_source_location(); let t = input.next()?; let allow_unitless_zero = matches!(allow_unitless_zero, AllowUnitlessZeroAngle::Yes); match *t {
Token::Dimension {
value, ref unit, ..
} => { match Angle::parse_dimension(value, unit, /* from_calc = */ false) {
Ok(angle) => Ok(angle),
Err(()) => { let t = t.clone();
Err(input.new_unexpected_token_error(t))
},
}
},
Token::Function(ref name) => { let function = CalcNode::math_function(context, name, location)?;
CalcNode::parse_angle(context, input, function)
},
Token::Number { value, .. } if value == 0. && allow_unitless_zero => Ok(Angle::zero()), ref t => { let t = t.clone();
Err(input.new_unexpected_token_error(t))
},
}
}
}
impl SpecifiedValueInfo for Angle {}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.9 Sekunden
(vorverarbeitet am 2026-06-19)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.