[librsvg: 1/22] Parser for the line-height property



commit c4fd517cb75837161f87041e143cc6da191e7927
Author: Federico Mena Quintero <federico gnome org>
Date:   Tue Jun 23 19:37:35 2020 -0500

    Parser for the line-height property
    
    We need to parse line-height in order to implement the "font"
    shorthand property... which gnome-shell needs.

 rsvg_internals/src/font_props.rs | 75 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 73 insertions(+), 2 deletions(-)
---
diff --git a/rsvg_internals/src/font_props.rs b/rsvg_internals/src/font_props.rs
index 3b00a6d8..65095fa6 100644
--- a/rsvg_internals/src/font_props.rs
+++ b/rsvg_internals/src/font_props.rs
@@ -1,12 +1,12 @@
 //! CSS font properties.
 
 use cast::u16;
-use cssparser::Parser;
+use cssparser::{Parser, Token};
 
 use crate::drawing_ctx::ViewParams;
 use crate::error::*;
 use crate::length::*;
-use crate::parsers::Parse;
+use crate::parsers::{finite_f32, Parse};
 use crate::properties::ComputedValues;
 
 // https://www.w3.org/TR/2008/REC-CSS2-20080411/fonts.html#propdef-font-size
@@ -236,6 +236,47 @@ impl Parse for LetterSpacingSpec {
     }
 }
 
+// https://www.w3.org/TR/CSS2/visudet.html#propdef-line-height
+#[derive(Debug, Copy, Clone, PartialEq)]
+pub enum LineHeightSpec {
+    Normal,
+    Number(f32),
+    Length(Length<Both>),
+    Percentage(f32),
+}
+
+impl Parse for LineHeightSpec {
+    fn parse<'i>(parser: &mut Parser<'i, '_>) -> Result<LineHeightSpec, ParseError<'i>> {
+        let state = parser.state();
+        let loc = parser.current_source_location();
+
+        let token = parser.next()?.clone();
+
+        match token {
+            Token::Ident(ref cow) => {
+                if cow.eq_ignore_ascii_case("normal") {
+                    Ok(LineHeightSpec::Normal)
+                } else {
+                    Err(parser.new_basic_unexpected_token_error(token.clone()))?
+                }
+            }
+
+            Token::Number { value, .. } => Ok(LineHeightSpec::Number(finite_f32(value).map_err(|e| 
loc.new_custom_error(e))?)),
+
+            Token::Percentage { unit_value, .. } => Ok(LineHeightSpec::Percentage(unit_value)),
+
+            Token::Dimension { .. } => {
+                parser.reset(&state);
+                Ok(LineHeightSpec::Length(Length::<Both>::parse(parser)?))
+            }
+
+            _ => {
+                Err(parser.new_basic_unexpected_token_error(token))?
+            }
+        }
+    }
+}
+
 /// https://www.w3.org/TR/2008/REC-CSS2-20080411/fonts.html#propdef-font-family
 #[derive(Debug, Clone, PartialEq)]
 pub struct MultiFontFamily(pub String);
@@ -432,4 +473,34 @@ mod tests {
         assert!(<MultiFontFamily as Parse>::parse_str("''").is_err());
         assert!(<MultiFontFamily as Parse>::parse_str("42").is_err());
     }
+
+    #[test]
+    fn parses_line_height() {
+        assert_eq!(
+            <LineHeightSpec as Parse>::parse_str("normal"),
+            Ok(LineHeightSpec::Normal),
+        );
+
+        assert_eq!(
+            <LineHeightSpec as Parse>::parse_str("2"),
+            Ok(LineHeightSpec::Number(2.0)),
+        );
+
+        assert_eq!(
+            <LineHeightSpec as Parse>::parse_str("2cm"),
+            Ok(LineHeightSpec::Length(Length::new(2.0, LengthUnit::Cm))),
+        );
+
+        assert_eq!(
+            <LineHeightSpec as Parse>::parse_str("150%"),
+            Ok(LineHeightSpec::Percentage(1.5)),
+        );
+    }
+
+    #[test]
+    fn detects_invalid_line_height() {
+        assert!(<LineHeightSpec as Parse>::parse_str("").is_err());
+        assert!(<LineHeightSpec as Parse>::parse_str("florp").is_err());
+        assert!(<LineHeightSpec as Parse>::parse_str("3florp").is_err());
+    }
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]