[librsvg] gradient: store offset as a UnitInterval



commit 555d50bcd1293aa70dbb01842f57bf7058342333
Author: Paolo Borelli <pborelli gnome org>
Date:   Sun Dec 30 15:02:54 2018 +0100

    gradient: store offset as a UnitInterval
    
    We were manually clamping during parse. Using UnitInterval makes
    encodes the invariant in the type.

 rsvg_internals/src/gradient.rs | 22 +++++++++++++---------
 rsvg_internals/src/stop.rs     | 32 ++++++++++----------------------
 2 files changed, 23 insertions(+), 31 deletions(-)
---
diff --git a/rsvg_internals/src/gradient.rs b/rsvg_internals/src/gradient.rs
index fd6af744..75e079f4 100644
--- a/rsvg_internals/src/gradient.rs
+++ b/rsvg_internals/src/gradient.rs
@@ -22,7 +22,7 @@ use unit_interval::UnitInterval;
 
 #[derive(Copy, Clone)]
 pub struct ColorStop {
-    pub offset: f64,
+    pub offset: UnitInterval,
     pub rgba: cssparser::RGBA,
     pub opacity: UnitInterval,
 }
@@ -187,21 +187,23 @@ impl GradientCommon {
         self.fallback = fallback.fallback.clone();
     }
 
-    fn add_color_stop(&mut self, mut offset: f64, rgba: cssparser::RGBA, opacity: UnitInterval) {
+    fn add_color_stop(&mut self, offset: UnitInterval, rgba: cssparser::RGBA, opacity: UnitInterval) {
         if self.stops.is_none() {
             self.stops = Some(Vec::<ColorStop>::new());
         }
 
         if let Some(ref mut stops) = self.stops {
-            let last_offset: f64 = if !stops.is_empty() {
+            let last_offset = if !stops.is_empty() {
                 stops[stops.len() - 1].offset
             } else {
-                0.0
+                UnitInterval(0.0)
             };
 
-            if last_offset > offset {
-                offset = last_offset;
-            }
+            let offset = if offset > last_offset {
+                offset
+            } else {
+                last_offset
+            };
 
             stops.push(ColorStop {
                 offset,
@@ -391,12 +393,13 @@ impl Gradient {
                         StopColor(cssparser::Color::CurrentColor) => values.color.0,
                         StopColor(cssparser::Color::RGBA(ref rgba)) => *rgba,
                     };
+
                     self.add_color_stop(stop.get_offset(), rgba, values.stop_opacity.0);
                 })
             });
     }
 
-    fn add_color_stop(&mut self, offset: f64, rgba: cssparser::RGBA, opacity: UnitInterval) {
+    fn add_color_stop(&mut self, offset: UnitInterval, rgba: cssparser::RGBA, opacity: UnitInterval) {
         self.common.add_color_stop(offset, rgba, opacity);
     }
 
@@ -407,11 +410,12 @@ impl Gradient {
     ) {
         if let Some(stops) = self.common.stops.as_ref() {
             for stop in stops {
+                let UnitInterval(stop_offset) = stop.offset;
                 let &UnitInterval(o) = opacity;
                 let UnitInterval(stop_opacity) = stop.opacity;
 
                 pattern.add_color_stop_rgba(
-                    stop.offset,
+                    stop_offset,
                     f64::from(stop.rgba.red_f32()),
                     f64::from(stop.rgba.green_f32()),
                     f64::from(stop.rgba.blue_f32()),
diff --git a/rsvg_internals/src/stop.rs b/rsvg_internals/src/stop.rs
index 87c9eafd..cf7ca4fd 100644
--- a/rsvg_internals/src/stop.rs
+++ b/rsvg_internals/src/stop.rs
@@ -7,37 +7,27 @@ use length::*;
 use node::*;
 use parsers::ParseValue;
 use property_bag::PropertyBag;
+use unit_interval::UnitInterval;
 
 pub struct NodeStop {
-    offset: Cell<f64>,
+    offset: Cell<UnitInterval>,
 }
 
 impl NodeStop {
     pub fn new() -> NodeStop {
         NodeStop {
-            offset: Cell::new(0.0),
+            offset: Cell::new(UnitInterval(0.0)),
         }
     }
 
-    pub fn get_offset(&self) -> f64 {
+    pub fn get_offset(&self) -> UnitInterval {
         self.offset.get()
     }
 }
 
 fn validate_offset(length: Length) -> Result<Length, ValueErrorKind> {
     match length.unit {
-        LengthUnit::Default | LengthUnit::Percent => {
-            let mut offset = length.length;
-
-            if offset < 0.0 {
-                offset = 0.0;
-            } else if offset > 1.0 {
-                offset = 1.0;
-            }
-
-            Ok(Length::new(offset, LengthUnit::Default, LengthDir::Both))
-        }
-
+        LengthUnit::Default | LengthUnit::Percent => Ok(length),
         _ => Err(ValueErrorKind::Value(
             "stop offset must be in default or percent units".to_string(),
         )),
@@ -49,14 +39,12 @@ impl NodeTrait for NodeStop {
         for (attr, value) in pbag.iter() {
             match attr {
                 Attribute::Offset => {
-                    let length =
-                        attr.parse_and_validate(value, LengthDir::Both, validate_offset)?;
-                    assert!(
-                        length.unit == LengthUnit::Default || length.unit == LengthUnit::Percent
-                    );
-                    self.offset.set(length.length);
+                    self.offset.set(attr.parse_and_validate(
+                        value,
+                        LengthDir::Both,
+                        validate_offset,
+                    ).map(|l| UnitInterval::clamp(l.length))?);
                 }
-
                 _ => (),
             }
         }


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