[librsvg] PaintServerSpread: Use this instead of plain cairo::enums::Extend for gradients



commit 22d1459fd908cea9bf781acd8548355c740a4274
Author: Federico Mena Quintero <federico gnome org>
Date:   Mon Jun 5 10:38:32 2017 -0500

    PaintServerSpread: Use this instead of plain cairo::enums::Extend for gradients
    
    We define PaintServerSpread as a newtype on cairo::enums::Extend, so we
    can implement FromStr and Default for it.  This will let us parse the
    "spreadMethod" property in gradients with our usual machinery.

 rust/src/gradient.rs     |   12 ++++++------
 rust/src/paint_server.rs |   39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 45 insertions(+), 6 deletions(-)
---
diff --git a/rust/src/gradient.rs b/rust/src/gradient.rs
index 26789da..269bd67 100644
--- a/rust/src/gradient.rs
+++ b/rust/src/gradient.rs
@@ -27,7 +27,7 @@ pub struct ColorStop {
 pub struct GradientCommon {
     pub units:    Option<PaintServerUnits>,
     pub affine:   Option<cairo::Matrix>,
-    pub spread:   Option<cairo::enums::Extend>,
+    pub spread:   Option<PaintServerSpread>,
     pub fallback: Option<String>,
     pub stops:    Option<Vec<ColorStop>>
 }
@@ -81,7 +81,7 @@ macro_rules! fallback_to (
 impl GradientCommon {
     fn new (units:    Option<PaintServerUnits>,
             affine:   Option<cairo::Matrix>,
-            spread:   Option<cairo::enums::Extend>,
+            spread:   Option<PaintServerSpread>,
             fallback: Option<String>,
             stops:    Option<Vec<ColorStop>>) -> GradientCommon {
         GradientCommon {
@@ -113,7 +113,7 @@ impl GradientCommon {
 
         fallback_to! (self.units,  Some (PaintServerUnits::default ()));
         fallback_to! (self.affine, Some (cairo::Matrix::identity ()));
-        fallback_to! (self.spread, Some (cairo::enums::Extend::Pad));
+        fallback_to! (self.spread, Some (PaintServerSpread::default ()));
         fallback_to! (self.stops,  Some (Vec::<ColorStop>::new ())); // empty array of color stops
 
         self.fallback = None;
@@ -376,7 +376,7 @@ fn set_common_on_pattern<P: cairo::Pattern + cairo::Gradient> (gradient: &Gradie
 
     affine.invert ();
     pattern.set_matrix (affine);
-    pattern.set_extend (gradient.common.spread.unwrap ());
+    pattern.set_extend (gradient.common.spread.unwrap ().0);
 
     gradient.add_color_stops_to_pattern (pattern, opacity);
 
@@ -535,7 +535,7 @@ pub unsafe extern fn gradient_linear_new (x1: *const RsvgLength,
                                           fallback_name: *const libc::c_char) -> *mut Gradient {
     let my_units         = { if obj_bbox.is_null ()      { None } else { Some 
(paint_server_units_from_gboolean (*obj_bbox)) } };
     let my_affine        = { if affine.is_null ()        { None } else { Some (*affine) } };
-    let my_spread        = { if spread.is_null ()        { None } else { Some (*spread) } };
+    let my_spread        = { if spread.is_null ()        { None } else { Some (PaintServerSpread (*spread)) 
} };
     let my_fallback_name = { if fallback_name.is_null () { None } else { Some (String::from_glib_none 
(fallback_name)) } };
 
     let my_x1 = { if x1.is_null () { None } else { Some (*x1) } };
@@ -566,7 +566,7 @@ pub unsafe extern fn gradient_radial_new (cx: *const RsvgLength,
                                           fallback_name: *const libc::c_char) -> *mut Gradient {
     let my_units         = { if obj_bbox.is_null ()      { None } else { Some 
(paint_server_units_from_gboolean (*obj_bbox)) } };
     let my_affine        = { if affine.is_null ()        { None } else { Some (*affine) } };
-    let my_spread        = { if spread.is_null ()        { None } else { Some (*spread) } };
+    let my_spread        = { if spread.is_null ()        { None } else { Some (PaintServerSpread (*spread)) 
} };
     let my_fallback_name = { if fallback_name.is_null () { None } else { Some (String::from_glib_none 
(fallback_name)) } };
 
     let my_cx = { if cx.is_null () { None } else { Some (*cx) } };
diff --git a/rust/src/paint_server.rs b/rust/src/paint_server.rs
index dfd88d1..e5f0342 100644
--- a/rust/src/paint_server.rs
+++ b/rust/src/paint_server.rs
@@ -1,3 +1,5 @@
+use ::cairo;
+
 use std::str::FromStr;
 
 use error::*;
@@ -30,6 +32,29 @@ impl Default for PaintServerUnits {
     }
 }
 
+// We define this as a newtype so we can impl FromStr on it
+#[derive(Debug, Copy, Clone, PartialEq)]
+pub struct PaintServerSpread (pub cairo::enums::Extend);
+
+impl FromStr for PaintServerSpread {
+    type Err = AttributeError;
+
+    fn from_str (s: &str) -> Result <PaintServerSpread, AttributeError> {
+        match s {
+            "pad"     => Ok (PaintServerSpread (cairo::enums::Extend::Pad)),
+            "reflect" => Ok (PaintServerSpread (cairo::enums::Extend::Reflect)),
+            "repeat"  => Ok (PaintServerSpread (cairo::enums::Extend::Repeat)),
+            _         => Err (AttributeError::Parse (ParseError::new ("expected 'pad' | 'reflect' | 
'repeat'")))
+        }
+    }
+}
+
+impl Default for PaintServerSpread {
+    fn default () -> PaintServerSpread {
+        PaintServerSpread (cairo::enums::Extend::Pad)
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;
@@ -46,4 +71,18 @@ mod tests {
         assert_eq! (PaintServerUnits::from_str ("userSpaceOnUse"), Ok (PaintServerUnits::UserSpaceOnUse));
         assert_eq! (PaintServerUnits::from_str ("objectBoundingBox"), Ok 
(PaintServerUnits::ObjectBoundingBox));
     }
+
+    #[test]
+    fn parses_spread_method () {
+        assert_eq! (PaintServerSpread::from_str ("pad"),
+                    Ok (PaintServerSpread (cairo::enums::Extend::Pad)));
+
+        assert_eq! (PaintServerSpread::from_str ("reflect"),
+                    Ok (PaintServerSpread (cairo::enums::Extend::Reflect)));
+
+        assert_eq! (PaintServerSpread::from_str ("repeat"),
+                    Ok (PaintServerSpread (cairo::enums::Extend::Repeat)));
+
+        assert! (PaintServerSpread::from_str ("foobar").is_err ());
+    }
 }


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