[librsvg: 1/2] Allow percentages to be used as opacity




commit e9d1e4855eb968e2d3d68a7b2d807456ddfc9225
Author: Michael Howell <michael notriddle com>
Date:   Mon Jun 6 10:58:32 2022 -0700

    Allow percentages to be used as opacity
    
    This commit modifies the way UnitInterval works. After skimming through
    the code looking for places that UnitInterval was used, I found it being
    used for alpha-value, and for stop-offset. StopOffset actually had to
    implement percentage parsing already, so that just cleaned things up.
    
    Fixes #817
    
    Part-of: <https://gitlab.gnome.org/GNOME/librsvg/-/merge_requests/705>

 src/gradient.rs      | 19 +------------------
 src/unit_interval.rs | 26 ++++++++++++++++++++++++--
 2 files changed, 25 insertions(+), 20 deletions(-)
---
diff --git a/src/gradient.rs b/src/gradient.rs
index abe374e19..ac914e763 100644
--- a/src/gradient.rs
+++ b/src/gradient.rs
@@ -55,22 +55,6 @@ impl Parse for SpreadMethod {
     }
 }
 
-#[derive(Debug, Copy, Clone, PartialEq)]
-struct StopOffset(UnitInterval);
-
-impl Parse for StopOffset {
-    fn parse<'i>(parser: &mut Parser<'i, '_>) -> Result<Self, ParseError<'i>> {
-        let loc = parser.current_source_location();
-        let l: Length<Both> = Parse::parse(parser)?;
-        match l.unit {
-            LengthUnit::Px | LengthUnit::Percent => Ok(StopOffset(UnitInterval::clamp(l.length))),
-            _ => Err(loc.new_custom_error(ValueErrorKind::value_error(
-                "stop offset must be in default or percent units",
-            ))),
-        }
-    }
-}
-
 /// Node for the <stop> element
 #[derive(Default)]
 pub struct Stop {
@@ -84,8 +68,7 @@ impl SetAttributes for Stop {
     fn set_attributes(&mut self, attrs: &Attributes) -> ElementResult {
         for (attr, value) in attrs.iter() {
             if let expanded_name!("", "offset") = attr.expanded() {
-                let StopOffset(o) = attr.parse(value)?;
-                self.offset = o;
+                self.offset = attr.parse(value)?;
             }
         }
 
diff --git a/src/unit_interval.rs b/src/unit_interval.rs
index 2794f8e55..65cc3d94e 100644
--- a/src/unit_interval.rs
+++ b/src/unit_interval.rs
@@ -3,6 +3,7 @@
 use cssparser::Parser;
 
 use crate::error::*;
+use crate::length::*;
 use crate::parsers::Parse;
 use crate::util;
 
@@ -17,8 +18,14 @@ impl UnitInterval {
 
 impl Parse for UnitInterval {
     fn parse<'i>(parser: &mut Parser<'i, '_>) -> Result<UnitInterval, ParseError<'i>> {
-        let x = f64::parse(parser)?;
-        Ok(UnitInterval::clamp(x))
+        let loc = parser.current_source_location();
+        let l: Length<Both> = Parse::parse(parser)?;
+        match l.unit {
+            LengthUnit::Px | LengthUnit::Percent => Ok(UnitInterval::clamp(l.length)),
+            _ => Err(loc.new_custom_error(ValueErrorKind::value_error(
+                "<unit-interval> must be in default or percent units",
+            ))),
+        }
     }
 }
 
@@ -42,6 +49,19 @@ mod tests {
         assert_eq!(UnitInterval::clamp(2.0), UnitInterval(1.0));
     }
 
+    #[test]
+    fn parses_percentages() {
+        assert_eq!(UnitInterval::parse_str("-100%").unwrap(), UnitInterval(0.0));
+        assert_eq!(UnitInterval::parse_str("0%").unwrap(), UnitInterval(0.0));
+        assert_eq!(UnitInterval::parse_str("50%").unwrap(), UnitInterval(0.5));
+        assert_eq!(UnitInterval::parse_str("100%").unwrap(), UnitInterval(1.0));
+        assert_eq!(
+            UnitInterval::parse_str("100.1%").unwrap(),
+            UnitInterval(1.0)
+        );
+        assert_eq!(UnitInterval::parse_str("200%").unwrap(), UnitInterval(1.0));
+    }
+
     #[test]
     fn parses_number() {
         assert_eq!(UnitInterval::parse_str("0").unwrap(), UnitInterval(0.0));
@@ -61,6 +81,8 @@ mod tests {
         assert!(UnitInterval::parse_str("foo").is_err());
         assert!(UnitInterval::parse_str("-x").is_err());
         assert!(UnitInterval::parse_str("0.0foo").is_err());
+        assert!(UnitInterval::parse_str("0.0%%").is_err());
+        assert!(UnitInterval::parse_str("%").is_err());
     }
 
     #[test]


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