[librsvg] gradient.rs, pattern.rs: Do the fallbacks with a macro for less verbosity



commit b591609e05849f43448b0b4e653c4edbccb9e11c
Author: Federico Mena Quintero <federico gnome org>
Date:   Thu Feb 9 10:34:53 2017 -0600

    gradient.rs, pattern.rs: Do the fallbacks with a macro for less verbosity
    
    Instead of a bunch of
    
      if self.foo.is_none () { self.foo = Some (default_value); }
    
    for defaults, or instead of
    
      if self.foo.is_none () { self.foo = fallback.foo; }
    
    for fallbacks, we now have a macro that can be invoked as
    
      fallback_to! (self.foo, some_value);
    
    which seems easier to read.
    
    The macro is duplicated for both gradient.rs and pattern.rs, but we will
    refactor those two files into a single thing anyway.

 rust/src/gradient.rs |   76 ++++++++++++++++++++++++++++++++-----------------
 rust/src/pattern.rs  |   67 +++++++++++++++++++++++++++-----------------
 2 files changed, 90 insertions(+), 53 deletions(-)
---
diff --git a/rust/src/gradient.rs b/rust/src/gradient.rs
index db73346..08aca85 100644
--- a/rust/src/gradient.rs
+++ b/rust/src/gradient.rs
@@ -58,6 +58,29 @@ pub struct Gradient {
     pub variant: GradientVariant
 }
 
+// All of the Gradient's fields are Option<foo> values, because
+// those fields can be omitted in the SVG file.  We need to resolve
+// them to default values, or to fallback values that come from
+// another Gradient.
+//
+// For the fallback case, this would need something like
+//
+//    if self.foo.is_none () { self.foo = fallback.foo; }
+//
+// And for the default case, it would be like
+//    if self.foo.is_none () { self.foo = Some (default_value); }
+//
+// Both can be replaced by
+//
+//    self.foo = self.foo.take ().or (bar);
+//
+// So we define a macro for that.
+macro_rules! fallback_to (
+    ($dest:expr, $default:expr) => (
+        $dest = $dest.take ().or ($default)
+    );
+);
+
 impl GradientCommon {
     fn new (obj_bbox: Option<bool>,
             affine:   Option<cairo::Matrix>,
@@ -91,20 +114,19 @@ impl GradientCommon {
     fn resolve_from_defaults (&mut self) {
         /* These are per the spec */
 
-        if self.obj_bbox.is_none () { self.obj_bbox = Some (true); }
-        if self.affine.is_none ()   { self.affine   = Some (cairo::Matrix::identity ()); }
-        if self.spread.is_none ()   { self.spread   = Some (cairo::enums::Extend::Pad); }
+        fallback_to! (self.obj_bbox, Some (true));
+        fallback_to! (self.affine,   Some (cairo::Matrix::identity ()));
+        fallback_to! (self.spread,   Some (cairo::enums::Extend::Pad));
+        fallback_to! (self.stops,    Some (Vec::<ColorStop>::new ())); // empty array of color stops
 
         self.fallback = None;
-
-        if self.stops.is_none ()    { self.stops    = Some (Vec::<ColorStop>::new ()); } // empty array of 
color stops
     }
 
     fn resolve_from_fallback (&mut self, fallback: &GradientCommon) {
-        if self.obj_bbox.is_none () { self.obj_bbox = fallback.obj_bbox; }
-        if self.affine.is_none ()   { self.affine   = fallback.affine; }
-        if self.spread.is_none ()   { self.spread   = fallback.spread; }
-        if self.stops.is_none ()    { self.stops    = fallback.clone_stops (); }
+        fallback_to! (self.obj_bbox, fallback.obj_bbox);
+        fallback_to! (self.affine,   fallback.affine);
+        fallback_to! (self.spread,   fallback.spread);
+        fallback_to! (self.stops,    fallback.clone_stops ());
 
         self.fallback = clone_fallback_name (&fallback.fallback);
     }
@@ -170,20 +192,20 @@ impl GradientVariant {
 
         match *self {
             GradientVariant::Linear { ref mut x1, ref mut y1, ref mut x2, ref mut y2 } => {
-                if x1.is_none () { *x1 = Some (RsvgLength::parse ("0%", LengthDir::Horizontal)); }
-                if y1.is_none () { *y1 = Some (RsvgLength::parse ("0%", LengthDir::Vertical)); }
-                if x2.is_none () { *x2 = Some (RsvgLength::parse ("100%", LengthDir::Horizontal)); }
-                if y2.is_none () { *y2 = Some (RsvgLength::parse ("0%", LengthDir::Vertical)); }
+                fallback_to! (*x1, Some (RsvgLength::parse ("0%", LengthDir::Horizontal)));
+                fallback_to! (*y1, Some (RsvgLength::parse ("0%", LengthDir::Vertical)));
+                fallback_to! (*x2, Some (RsvgLength::parse ("100%", LengthDir::Horizontal)));
+                fallback_to! (*y2, Some (RsvgLength::parse ("0%", LengthDir::Vertical)));
             },
 
             GradientVariant::Radial { ref mut cx, ref mut cy, ref mut r, ref mut fx, ref mut fy } => {
-                if cx.is_none () { *cx = Some (RsvgLength::parse ("50%", LengthDir::Horizontal)); }
-                if cy.is_none () { *cy = Some (RsvgLength::parse ("50%", LengthDir::Vertical)); }
-                if r.is_none ()  { *r  = Some (RsvgLength::parse ("50%", LengthDir::Both)); }
+                fallback_to! (*cx, Some (RsvgLength::parse ("50%", LengthDir::Horizontal)));
+                fallback_to! (*cy, Some (RsvgLength::parse ("50%", LengthDir::Vertical)));
+                fallback_to! (*r,  Some (RsvgLength::parse ("50%", LengthDir::Both)));
 
                 /* fx and fy fall back to the presentational value of cx and cy */
-                if fx.is_none () { *fx = *cx }
-                if fy.is_none () { *fy = *cy }
+                fallback_to! (*fx, *cx);
+                fallback_to! (*fy, *cy);
             }
         }
     }
@@ -192,20 +214,20 @@ impl GradientVariant {
         match *self {
             GradientVariant::Linear { ref mut x1, ref mut y1, ref mut x2, ref mut y2 } => {
                 if let &GradientVariant::Linear { x1: x1f, y1: y1f, x2: x2f, y2: y2f } = fallback {
-                    if x1.is_none () { *x1 = x1f; }
-                    if y1.is_none () { *y1 = y1f; }
-                    if x2.is_none () { *x2 = x2f; }
-                    if y2.is_none () { *y2 = y2f; }
+                    fallback_to! (*x1, x1f);
+                    fallback_to! (*y1, y1f);
+                    fallback_to! (*x2, x2f);
+                    fallback_to! (*y2, y2f);
                 }
             },
 
             GradientVariant::Radial { ref mut cx, ref mut cy, ref mut r, ref mut fx, ref mut fy } => {
                 if let &GradientVariant::Radial { cx: cxf, cy: cyf, r: rf, fx: fxf, fy: fyf } = fallback {
-                    if cx.is_none () { *cx = cxf; }
-                    if cy.is_none () { *cy = cyf; }
-                    if r.is_none ()  { *r  = rf;  }
-                    if fx.is_none () { *fx = fxf; }
-                    if fy.is_none () { *fy = fyf; }
+                    fallback_to! (*cx, cxf);
+                    fallback_to! (*cy, cyf);
+                    fallback_to! (*r,  rf);
+                    fallback_to! (*fx, fxf);
+                    fallback_to! (*fy, fyf);
                 }
             }
         }
diff --git a/rust/src/pattern.rs b/rust/src/pattern.rs
index 4759e88..3e1b6ed 100644
--- a/rust/src/pattern.rs
+++ b/rust/src/pattern.rs
@@ -50,6 +50,29 @@ fn pattern_node_has_children (c_node: *const RsvgNode) -> bool {
     unsafe { rsvg_pattern_node_has_children (c_node) }
 }
 
+// All of the Pattern's fields are Option<foo> values, because
+// those fields can be omitted in the SVG file.  We need to resolve
+// them to default values, or to fallback values that come from
+// another Pattern.
+//
+// For the fallback case, this would need something like
+//
+//    if self.foo.is_none () { self.foo = fallback.foo; }
+//
+// And for the default case, it would be like
+//    if self.foo.is_none () { self.foo = Some (default_value); }
+//
+// Both can be replaced by
+//
+//    self.foo = self.foo.take ().or (bar);
+//
+// So we define a macro for that.
+macro_rules! fallback_to (
+    ($dest:expr, $default:expr) => (
+        $dest = $dest.take ().or ($default)
+    );
+);
+
 impl Pattern {
     fn is_resolved (&self) -> bool {
         self.obj_bbox.is_some () &&
@@ -67,41 +90,33 @@ impl Pattern {
     fn resolve_from_defaults (&mut self) {
         /* These are per the spec */
 
-        if self.obj_bbox.is_none ()  { self.obj_bbox  = Some (true); }
-        if self.obj_cbbox.is_none () { self.obj_cbbox = Some (false); }
-        if self.vbox.is_none ()      { self.vbox      = Some (RsvgViewBox::new_inactive ()); }
-
-        if self.preserve_aspect_ratio.is_none () {
-            let aspect: AspectRatio = Default::default ();
-            self.preserve_aspect_ratio = Some (aspect);
-        }
+        fallback_to! (self.obj_bbox,              Some (true));
+        fallback_to! (self.obj_cbbox,             Some (false));
+        fallback_to! (self.vbox,                  Some (RsvgViewBox::new_inactive ()));
+        fallback_to! (self.preserve_aspect_ratio, Some (AspectRatio::default ()));
+        fallback_to! (self.affine,                Some (cairo::Matrix::identity ()));
 
-        if self.affine.is_none ()    { self.affine    = Some (cairo::Matrix::identity ()); }
+        fallback_to! (self.x,                     Some (RsvgLength::parse ("0", LengthDir::Horizontal)));
+        fallback_to! (self.y,                     Some (RsvgLength::parse ("0", LengthDir::Horizontal)));
+        fallback_to! (self.width,                 Some (RsvgLength::parse ("0", LengthDir::Horizontal)));
+        fallback_to! (self.height,                Some (RsvgLength::parse ("0", LengthDir::Horizontal)));
 
         self.fallback = None;
 
-        if self.x.is_none ()         { self.x         = Some (RsvgLength::parse ("0", 
LengthDir::Horizontal)); }
-        if self.y.is_none ()         { self.y         = Some (RsvgLength::parse ("0", 
LengthDir::Horizontal)); }
-        if self.width.is_none ()     { self.width     = Some (RsvgLength::parse ("0", 
LengthDir::Horizontal)); }
-        if self.height.is_none ()    { self.height    = Some (RsvgLength::parse ("0", 
LengthDir::Horizontal)); }
-
         // We don't resolve the children here - instead, we'll just
         // NOP if there are no children at drawing time.
     }
 
     fn resolve_from_fallback (&mut self, fallback: &Pattern) {
-        if self.obj_bbox.is_none ()  { self.obj_bbox  = fallback.obj_bbox; }
-        if self.obj_cbbox.is_none () { self.obj_cbbox = fallback.obj_cbbox; }
-        if self.vbox.is_none ()      { self.vbox      = fallback.vbox; }
-
-        if self.preserve_aspect_ratio.is_none () { self.preserve_aspect_ratio = 
fallback.preserve_aspect_ratio; }
-
-        if self.affine.is_none ()    { self.affine    = fallback.affine; }
-
-        if self.x.is_none ()         { self.x         = fallback.x; }
-        if self.y.is_none ()         { self.y         = fallback.y; }
-        if self.width.is_none ()     { self.width     = fallback.width; }
-        if self.height.is_none ()    { self.height    = fallback.height; }
+        fallback_to! (self.obj_bbox,              fallback.obj_bbox);
+        fallback_to! (self.obj_cbbox,             fallback.obj_cbbox);
+        fallback_to! (self.vbox,                  fallback.vbox);
+        fallback_to! (self.preserve_aspect_ratio, fallback.preserve_aspect_ratio);
+        fallback_to! (self.affine,                fallback.affine);
+        fallback_to! (self.x,                     fallback.x);
+        fallback_to! (self.y,                     fallback.y);
+        fallback_to! (self.width,                 fallback.width);
+        fallback_to! (self.height,                fallback.height);
 
         self.fallback = clone_fallback_name (&fallback.fallback);
 


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