diff options
Diffstat (limited to 'servo/components/style/values/specified/resolution.rs')
-rw-r--r-- | servo/components/style/values/specified/resolution.rs | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/servo/components/style/values/specified/resolution.rs b/servo/components/style/values/specified/resolution.rs new file mode 100644 index 0000000000..5ed642f981 --- /dev/null +++ b/servo/components/style/values/specified/resolution.rs @@ -0,0 +1,77 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +//! Resolution values: +//! +//! https://drafts.csswg.org/css-values/#resolution + +use crate::parser::{Parse, ParserContext}; +use crate::values::CSSFloat; +use cssparser::{Parser, Token}; +use style_traits::{ParseError, StyleParseErrorKind}; + +/// A specified resolution. +#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss, ToShmem)] +pub enum Resolution { + /// Dots per inch. + #[css(dimension)] + Dpi(CSSFloat), + /// An alias unit for dots per pixel. + #[css(dimension)] + X(CSSFloat), + /// Dots per pixel. + #[css(dimension)] + Dppx(CSSFloat), + /// Dots per centimeter. + #[css(dimension)] + Dpcm(CSSFloat), +} + +impl Resolution { + /// Convert this resolution value to dppx units. + pub fn to_dppx(&self) -> CSSFloat { + match *self { + Resolution::X(f) | Resolution::Dppx(f) => f, + _ => self.to_dpi() / 96.0, + } + } + + /// Convert this resolution value to dpi units. + pub fn to_dpi(&self) -> CSSFloat { + match *self { + Resolution::Dpi(f) => f, + Resolution::X(f) | Resolution::Dppx(f) => f * 96.0, + Resolution::Dpcm(f) => f * 2.54, + } + } +} + +impl Parse for Resolution { + fn parse<'i, 't>( + _: &ParserContext, + input: &mut Parser<'i, 't>, + ) -> Result<Self, ParseError<'i>> { + let location = input.current_source_location(); + let (value, unit) = match *input.next()? { + Token::Dimension { + value, ref unit, .. + } => (value, unit), + ref t => return Err(location.new_unexpected_token_error(t.clone())), + }; + + if value <= 0. { + return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError)); + } + + match_ignore_ascii_case! { &unit, + "dpi" => Ok(Resolution::Dpi(value)), + "dppx" => Ok(Resolution::Dppx(value)), + "dpcm" => Ok(Resolution::Dpcm(value)), + "x" => Ok(Resolution::X(value)), + _ => Err(location.new_custom_error( + StyleParseErrorKind::UnexpectedDimension(unit.clone()) + )), + } + } +} |