summaryrefslogtreecommitdiffstats
path: root/servo/components/style/values/specified/resolution.rs
diff options
context:
space:
mode:
Diffstat (limited to 'servo/components/style/values/specified/resolution.rs')
-rw-r--r--servo/components/style/values/specified/resolution.rs77
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())
+ )),
+ }
+ }
+}