[librsvg: 3/10] Put most of the define_length_type macro in a trait



commit 21a40f4ef801eecfe58c7602835c37f436f0e926
Author: Federico Mena Quintero <federico gnome org>
Date:   Tue Nov 12 18:05:05 2019 -0600

    Put most of the define_length_type macro in a trait
    
    This is the first step to removing the LengthHorizontal/etc. newtypes.

 librsvg/c_api.rs                     |  31 ++---
 librsvg_crate/src/lib.rs             |   2 +-
 rsvg_internals/src/drawing_ctx.rs    |   2 +-
 rsvg_internals/src/filter.rs         |   2 +-
 rsvg_internals/src/filters/bounds.rs |   2 +-
 rsvg_internals/src/filters/mod.rs    |   2 +-
 rsvg_internals/src/font_props.rs     |   2 +-
 rsvg_internals/src/image.rs          |   2 +-
 rsvg_internals/src/length.rs         | 219 +++++++++++++++++++----------------
 rsvg_internals/src/lib.rs            |   2 +-
 rsvg_internals/src/marker.rs         |   2 +-
 rsvg_internals/src/mask.rs           |   2 +-
 rsvg_internals/src/property_defs.rs  |   2 +-
 13 files changed, 145 insertions(+), 127 deletions(-)
---
diff --git a/librsvg/c_api.rs b/librsvg/c_api.rs
index 9bfe61ae..8392fdfc 100644
--- a/librsvg/c_api.rs
+++ b/librsvg/c_api.rs
@@ -34,14 +34,13 @@ use glib_sys;
 use gobject_sys::{self, GEnumValue, GFlagsValue};
 
 use rsvg_internals::{
-    rsvg_log, set_gerror, DefsLookupErrorKind, Dpi, Handle, IntrinsicDimensions, LoadOptions,
-    LoadingError, RenderingError, RsvgDimensionData, RsvgLength, RsvgPositionData, RsvgRectangle,
-    RsvgSizeFunc, SizeCallback, RSVG_ERROR_FAILED, SharedImageSurface, SurfaceType,
+    rsvg_log, set_gerror, DefsLookupErrorKind, Dpi, Handle, IntrinsicDimensions, LengthTrait,
+    LoadOptions, LoadingError, RenderingError, RsvgDimensionData, RsvgLength, RsvgPositionData,
+    RsvgRectangle, RsvgSizeFunc, SharedImageSurface, SizeCallback, SurfaceType, RSVG_ERROR_FAILED,
 };
 
 use crate::pixbuf_utils::{empty_pixbuf, pixbuf_from_surface};
 
-
 mod handle_flags {
     // The following is entirely stolen from the auto-generated code
     // for GBindingFlags, from gtk-rs/glib/src/gobject/auto/flags.rs
@@ -180,10 +179,7 @@ impl BaseUrl {
     fn set(&mut self, url: Url) {
         let cstring = CString::new(url.as_str()).unwrap();
 
-        self.inner = Some(BaseUrlInner {
-            url,
-            cstring,
-        });
+        self.inner = Some(BaseUrlInner { url, cstring });
     }
 
     fn get(&self) -> Option<&Url> {
@@ -191,7 +187,10 @@ impl BaseUrl {
     }
 
     fn get_ptr(&self) -> *const libc::c_char {
-        self.inner.as_ref().map(|b| b.cstring.as_ptr()).unwrap_or_else(|| ptr::null())
+        self.inner
+            .as_ref()
+            .map(|b| b.cstring.as_ptr())
+            .unwrap_or_else(|| ptr::null())
     }
 }
 
@@ -520,16 +519,16 @@ impl CHandle {
                 *state = LoadState::Loading {
                     buffer: Vec::from(buf),
                 }
-            },
+            }
 
             LoadState::Loading { ref mut buffer } => {
                 buffer.extend_from_slice(buf);
-            },
+            }
 
             _ => {
                 rsvg_g_critical("Handle must not be closed in order to write to it");
                 return;
-            },
+            }
         }
     }
 
@@ -664,13 +663,7 @@ impl CHandle {
         let handle = self.get_handle_ref()?;
         let inner = self.inner.borrow();
         handle
-            .render_cairo_sub(
-                cr,
-                id,
-                inner.dpi,
-                &inner.size_callback,
-                inner.is_testing,
-            )
+            .render_cairo_sub(cr, id, inner.dpi, &inner.size_callback, inner.is_testing)
             .map_err(warn_on_invalid_id)
     }
 
diff --git a/librsvg_crate/src/lib.rs b/librsvg_crate/src/lib.rs
index 09141569..f84aa604 100644
--- a/librsvg_crate/src/lib.rs
+++ b/librsvg_crate/src/lib.rs
@@ -97,7 +97,7 @@ use std::path::Path;
 
 use gio::{Cancellable, FileExt};
 
-use rsvg_internals::{Dpi, Handle, LoadOptions};
+use rsvg_internals::{Dpi, Handle, LengthTrait, LoadOptions};
 
 pub use rsvg_internals::{
     DefsLookupErrorKind,
diff --git a/rsvg_internals/src/drawing_ctx.rs b/rsvg_internals/src/drawing_ctx.rs
index 95661d52..834c3424 100644
--- a/rsvg_internals/src/drawing_ctx.rs
+++ b/rsvg_internals/src/drawing_ctx.rs
@@ -13,7 +13,7 @@ use crate::dpi::Dpi;
 use crate::error::{AcquireError, RenderingError};
 use crate::filters;
 use crate::gradient::{LinearGradient, RadialGradient};
-use crate::length::Dasharray;
+use crate::length::{Dasharray, LengthTrait};
 use crate::limits;
 use crate::mask::Mask;
 use crate::node::{CascadedValues, NodeDraw, NodeType, RsvgNode};
diff --git a/rsvg_internals/src/filter.rs b/rsvg_internals/src/filter.rs
index f68cdff3..e5791159 100644
--- a/rsvg_internals/src/filter.rs
+++ b/rsvg_internals/src/filter.rs
@@ -5,7 +5,7 @@ use crate::bbox::BoundingBox;
 use crate::coord_units::CoordUnits;
 use crate::drawing_ctx::DrawingCtx;
 use crate::error::ValueErrorKind;
-use crate::length::{LengthHorizontal, LengthUnit, LengthVertical};
+use crate::length::{LengthHorizontal, LengthUnit, LengthTrait, LengthVertical};
 use crate::node::{NodeResult, NodeTrait, RsvgNode};
 use crate::parsers::{Parse, ParseError, ParseValue};
 use crate::properties::ComputedValues;
diff --git a/rsvg_internals/src/filters/bounds.rs b/rsvg_internals/src/filters/bounds.rs
index 10548726..ef137ee2 100644
--- a/rsvg_internals/src/filters/bounds.rs
+++ b/rsvg_internals/src/filters/bounds.rs
@@ -3,7 +3,7 @@ use cairo;
 
 use crate::bbox::BoundingBox;
 use crate::drawing_ctx::DrawingCtx;
-use crate::length::{LengthHorizontal, LengthVertical};
+use crate::length::{LengthHorizontal, LengthTrait, LengthVertical};
 use crate::rect::IRect;
 
 use super::context::{FilterContext, FilterInput, FilterOutput};
diff --git a/rsvg_internals/src/filters/mod.rs b/rsvg_internals/src/filters/mod.rs
index 8dc3bfb6..41a60897 100644
--- a/rsvg_internals/src/filters/mod.rs
+++ b/rsvg_internals/src/filters/mod.rs
@@ -9,7 +9,7 @@ use crate::coord_units::CoordUnits;
 use crate::drawing_ctx::DrawingCtx;
 use crate::error::{RenderingError, ValueErrorKind};
 use crate::filter::Filter;
-use crate::length::{LengthHorizontal, LengthUnit, LengthVertical};
+use crate::length::{LengthHorizontal, LengthUnit, LengthTrait, LengthVertical};
 use crate::node::{CascadedValues, NodeResult, NodeTrait, NodeType, RsvgNode};
 use crate::parsers::{ParseError, ParseValue};
 use crate::properties::ComputedValues;
diff --git a/rsvg_internals/src/font_props.rs b/rsvg_internals/src/font_props.rs
index 20d3a30c..a8bc4e08 100644
--- a/rsvg_internals/src/font_props.rs
+++ b/rsvg_internals/src/font_props.rs
@@ -2,7 +2,7 @@ use cssparser::{BasicParseError, Parser, Token};
 
 use crate::drawing_ctx::ViewParams;
 use crate::error::*;
-use crate::length::{LengthBoth, LengthHorizontal, LengthUnit, POINTS_PER_INCH};
+use crate::length::{LengthBoth, LengthHorizontal, LengthTrait, LengthUnit, POINTS_PER_INCH};
 use crate::parsers::{Parse, ParseError};
 use crate::properties::ComputedValues;
 
diff --git a/rsvg_internals/src/image.rs b/rsvg_internals/src/image.rs
index cf2509b4..cee2a1ae 100644
--- a/rsvg_internals/src/image.rs
+++ b/rsvg_internals/src/image.rs
@@ -8,7 +8,7 @@ use crate::bbox::BoundingBox;
 use crate::drawing_ctx::{ClipMode, DrawingCtx};
 use crate::error::{NodeError, RenderingError};
 use crate::float_eq_cairo::ApproxEqCairo;
-use crate::length::{LengthHorizontal, LengthVertical};
+use crate::length::{LengthHorizontal, LengthTrait, LengthVertical};
 use crate::node::*;
 use crate::parsers::{ParseError, ParseValue};
 use crate::property_bag::PropertyBag;
diff --git a/rsvg_internals/src/length.rs b/rsvg_internals/src/length.rs
index ca86deb9..64b3f59e 100644
--- a/rsvg_internals/src/length.rs
+++ b/rsvg_internals/src/length.rs
@@ -78,119 +78,144 @@ pub enum LengthUnit {
     Pc,
 }
 
-/// Internal type used to implement the newtypes [`LengthHorizontal`], [`LengthVertical`],
-/// [`LengthBoth`].
-///
-/// [`LengthHorizontal`]: struct.LengthHorizontal.html
-/// [`LengthVertical`]: struct.LengthVertical.html
-/// [`LengthBoth`]: struct.LengthBoth.html
-#[derive(Debug, PartialEq, Copy, Clone)]
-enum LengthDir {
-    Horizontal,
-    Vertical,
-    Both,
-}
-
-impl LengthDir {
+pub trait Orientation {
     /// Computes a direction-based scaling factor.
     ///
     /// This is so that `LengthDir::Both` will use the "normalized
     /// diagonal length" of the current viewport, per
     /// https://www.w3.org/TR/SVG/coords.html#Units
-    fn scaling_factor(self, x: f64, y: f64) -> f64 {
-        match self {
-            LengthDir::Horizontal => x,
-            LengthDir::Vertical => y,
-            LengthDir::Both => viewport_percentage(x, y),
-        }
+    fn scaling_factor(x: f64, y: f64) -> f64;
+}
+
+pub struct Horizontal;
+pub struct Vertical;
+pub struct Both;
+
+impl Orientation for Horizontal {
+    #[inline]
+    fn scaling_factor(x: f64, _y: f64) -> f64 {
+        x
     }
 }
 
-macro_rules! define_length_type {
-    {$(#[$docs:meta])* $name:ident, $dir:expr} => {
-        $(#[$docs])*
-        #[derive(Debug, PartialEq, Copy, Clone)]
-        pub struct $name(Length);
+impl Orientation for Vertical {
+    #[inline]
+    fn scaling_factor(_x: f64, y: f64) -> f64 {
+        y
+    }
+}
 
-        impl $name {
-            pub fn new(length: f64, unit: LengthUnit) -> Self {
-                $name(Length::new(length, unit))
-            }
+impl Orientation for Both {
+    #[inline]
+    fn scaling_factor(x: f64, y: f64) -> f64 {
+        viewport_percentage(x, y)
+    }
+}
 
-            pub fn length(&self) -> f64 {
-                self.0.length
+pub trait LengthTrait: Sized {
+    type Orientation: Orientation;
+
+    /// Getter for the `length` field
+    fn length(&self) -> f64;
+
+    /// Getter for the `unit` field
+    fn unit(&self) -> LengthUnit;
+
+    /// Extracts the interior [`Length`].
+    ///
+    /// [`Length`]: struct.Length.html
+    fn to_length(&self) -> Length;
+
+    /// Returns `self` if the length is >= 0, or an error.
+    ///
+    /// See the documentation for [`from_cssparser`] for an example.
+    ///
+    /// [`from_cssparser`]: #method.from_cssparser
+    fn check_nonnegative(self) -> Result<Self, ValueErrorKind> {
+        if self.length() >= 0.0 {
+            Ok(self)
+        } else {
+            Err(ValueErrorKind::Value(
+                "value must be non-negative".to_string(),
+            ))
+        }
+    }
+
+    /// Normalizes a specified length into a used value.
+    ///
+    /// Lengths may come with non-pixel units, and when rendering, they need to be
+    /// normalized to pixels based on the current viewport (e.g. for lengths with
+    /// percent units), and on the current element's set of `ComputedValues` (e.g. for
+    /// lengths with `Em` units that need to be resolved against the current font
+    /// size).
+    fn normalize(&self, values: &ComputedValues, params: &ViewParams) -> f64 {
+        match self.unit() {
+            LengthUnit::Px => self.length(),
+
+            LengthUnit::Percent => {
+                self.length()
+                    * <Self::Orientation>::scaling_factor(
+                        params.view_box_width,
+                        params.view_box_height,
+                    )
             }
 
-            pub fn unit(&self) -> LengthUnit {
-                self.0.unit
+            LengthUnit::Em => self.length() * font_size_from_values(values, params),
+
+            LengthUnit::Ex => self.length() * font_size_from_values(values, params) / 2.0,
+
+            LengthUnit::In => {
+                self.length() * <Self::Orientation>::scaling_factor(params.dpi_x, params.dpi_y)
             }
 
-            /// Extracts the interior [`Length`].
-            ///
-            /// [`Length`]: struct.Length.html
-            pub fn to_length(&self) -> Length {
-                self.0
+            LengthUnit::Cm => {
+                self.length() * <Self::Orientation>::scaling_factor(params.dpi_x, params.dpi_y)
+                    / CM_PER_INCH
             }
 
-            /// Returns `self` if the length is >= 0, or an error.
-            ///
-            /// See the documentation for [`from_cssparser`] for an example.
-            ///
-            /// [`from_cssparser`]: #method.from_cssparser
-            pub fn check_nonnegative(self) -> Result<Self, ValueErrorKind> {
-                if self.length() >= 0.0 {
-                    Ok(self)
-                } else {
-                    Err(ValueErrorKind::Value(
-                        "value must be non-negative".to_string(),
-                    ))
-                }
+            LengthUnit::Mm => {
+                self.length() * <Self::Orientation>::scaling_factor(params.dpi_x, params.dpi_y)
+                    / MM_PER_INCH
             }
 
-            /// Normalizes a specified length into a used value.
-            ///
-            /// Lengths may come with non-pixel units, and when rendering, they need to be
-            /// normalized to pixels based on the current viewport (e.g. for lengths with
-            /// percent units), and on the current element's set of `ComputedValues` (e.g. for
-            /// lengths with `Em` units that need to be resolved against the current font
-            /// size).
-            pub fn normalize(&self, values: &ComputedValues, params: &ViewParams) -> f64 {
-                match self.unit() {
-                    LengthUnit::Px => self.length(),
-
-                    LengthUnit::Percent => {
-                        self.length()
-                            * $dir.scaling_factor(params.view_box_width, params.view_box_height)
-                    }
+            LengthUnit::Pt => {
+                self.length() * <Self::Orientation>::scaling_factor(params.dpi_x, params.dpi_y)
+                    / POINTS_PER_INCH
+            }
 
-                    LengthUnit::Em => self.length() * font_size_from_values(values, params),
+            LengthUnit::Pc => {
+                self.length() * <Self::Orientation>::scaling_factor(params.dpi_x, params.dpi_y)
+                    / PICA_PER_INCH
+            }
+        }
+    }
+}
 
-                    LengthUnit::Ex => self.length() * font_size_from_values(values, params) / 2.0,
+macro_rules! define_length_type {
+    {$(#[$docs:meta])* $name:ident, $orient:ty} => {
+        $(#[$docs])*
+        #[derive(Debug, PartialEq, Copy, Clone)]
+        pub struct $name(Length);
 
-                    LengthUnit::In => {
-                        self.length() * $dir.scaling_factor(params.dpi_x, params.dpi_y)
-                    }
+        impl LengthTrait for $name {
+            type Orientation = $orient;
 
-                    LengthUnit::Cm => {
-                        self.length() * $dir.scaling_factor(params.dpi_x, params.dpi_y)
-                            / CM_PER_INCH
-                    }
+            fn length(&self) -> f64 {
+                self.0.length
+            }
 
-                    LengthUnit::Mm => {
-                        self.length() * $dir.scaling_factor(params.dpi_x, params.dpi_y)
-                            / MM_PER_INCH
-                    }
+            fn unit(&self) -> LengthUnit {
+                self.0.unit
+            }
 
-                    LengthUnit::Pt => {
-                        self.length() * $dir.scaling_factor(params.dpi_x, params.dpi_y)
-                            / POINTS_PER_INCH
-                    }
+            fn to_length(&self) -> Length {
+                self.0
+            }
+        }
 
-                    LengthUnit::Pc => {
-                        self.length() * $dir.scaling_factor(params.dpi_x, params.dpi_y)
-                            / PICA_PER_INCH
-                    }
-                }
+        impl $name {
+            pub fn new(length: f64, unit: LengthUnit) -> Self {
+                $name(Length::new(length, unit))
             }
 
             /// Parses a LENGTH from a `Parser`.
@@ -232,7 +257,7 @@ define_length_type! {
     /// When this is specified as a percent value, it will get normalized
     /// against the current viewport's width.
 
-    LengthHorizontal, LengthDir::Horizontal
+    LengthHorizontal, Horizontal
 }
 
 define_length_type! {
@@ -240,7 +265,7 @@ define_length_type! {
     ///
     /// When this is specified as a percent value, it will get normalized
     /// against the current viewport's height.
-    LengthVertical, LengthDir::Vertical
+    LengthVertical, Vertical
 }
 
 define_length_type! {
@@ -249,7 +274,7 @@ define_length_type! {
     /// When this is specified as a percent value, it will get normalized
     /// against the current viewport's width and height.
 
-    LengthBoth, LengthDir::Both
+    LengthBoth, Both
 }
 
 /// A CSS length value.
@@ -404,19 +429,19 @@ fn font_size_from_values(values: &ComputedValues, params: &ViewParams) -> f64 {
         // This is the same default as used in Svg::get_size()
         LengthUnit::Ex => v.length * 12.0 / 2.0,
 
-        // FontSize always is a LengthDir::Both, per properties.rs
-        LengthUnit::In => v.length * LengthDir::Both.scaling_factor(params.dpi_x, params.dpi_y),
+        // FontSize always is a Both, per properties.rs
+        LengthUnit::In => v.length * Both::scaling_factor(params.dpi_x, params.dpi_y),
         LengthUnit::Cm => {
-            v.length * LengthDir::Both.scaling_factor(params.dpi_x, params.dpi_y) / CM_PER_INCH
+            v.length * Both::scaling_factor(params.dpi_x, params.dpi_y) / CM_PER_INCH
         }
         LengthUnit::Mm => {
-            v.length * LengthDir::Both.scaling_factor(params.dpi_x, params.dpi_y) / MM_PER_INCH
+            v.length * Both::scaling_factor(params.dpi_x, params.dpi_y) / MM_PER_INCH
         }
         LengthUnit::Pt => {
-            v.length * LengthDir::Both.scaling_factor(params.dpi_x, params.dpi_y) / POINTS_PER_INCH
+            v.length * Both::scaling_factor(params.dpi_x, params.dpi_y) / POINTS_PER_INCH
         }
         LengthUnit::Pc => {
-            v.length * LengthDir::Both.scaling_factor(params.dpi_x, params.dpi_y) / PICA_PER_INCH
+            v.length * Both::scaling_factor(params.dpi_x, params.dpi_y) / PICA_PER_INCH
         }
     }
 }
diff --git a/rsvg_internals/src/lib.rs b/rsvg_internals/src/lib.rs
index 4e77b4df..1d48eec1 100644
--- a/rsvg_internals/src/lib.rs
+++ b/rsvg_internals/src/lib.rs
@@ -55,7 +55,7 @@ pub use crate::handle::{
     Handle, LoadOptions, RsvgDimensionData, RsvgPositionData, RsvgSizeFunc, SizeCallback,
 };
 
-pub use crate::length::{Length, LengthUnit, RsvgLength};
+pub use crate::length::{Length, LengthUnit, LengthTrait, RsvgLength};
 
 pub use crate::rect::IRect;
 
diff --git a/rsvg_internals/src/marker.rs b/rsvg_internals/src/marker.rs
index dbb5e451..265bbc5f 100644
--- a/rsvg_internals/src/marker.rs
+++ b/rsvg_internals/src/marker.rs
@@ -13,7 +13,7 @@ use crate::drawing_ctx::DrawingCtx;
 use crate::error::*;
 use crate::float_eq_cairo::ApproxEqCairo;
 use crate::iri::IRI;
-use crate::length::{LengthHorizontal, LengthVertical};
+use crate::length::{LengthHorizontal, LengthTrait, LengthVertical};
 use crate::node::*;
 use crate::parsers::{Parse, ParseError, ParseValue};
 use crate::path_builder::*;
diff --git a/rsvg_internals/src/mask.rs b/rsvg_internals/src/mask.rs
index 239d129e..9f70114e 100644
--- a/rsvg_internals/src/mask.rs
+++ b/rsvg_internals/src/mask.rs
@@ -5,7 +5,7 @@ use crate::bbox::BoundingBox;
 use crate::coord_units::CoordUnits;
 use crate::drawing_ctx::{CompositingAffines, DrawingCtx};
 use crate::error::RenderingError;
-use crate::length::{LengthHorizontal, LengthVertical};
+use crate::length::{LengthHorizontal, LengthTrait, LengthVertical};
 use crate::node::{CascadedValues, NodeDraw, NodeResult, NodeTrait, RsvgNode};
 use crate::parsers::{Parse, ParseValue};
 use crate::property_bag::PropertyBag;
diff --git a/rsvg_internals/src/property_defs.rs b/rsvg_internals/src/property_defs.rs
index 07a4ce2f..fca4bf7a 100644
--- a/rsvg_internals/src/property_defs.rs
+++ b/rsvg_internals/src/property_defs.rs
@@ -3,7 +3,7 @@ use cssparser::{self, Parser, Token};
 use crate::error::*;
 use crate::font_props::{FontSizeSpec, FontWeightSpec, LetterSpacingSpec, SingleFontFamily};
 use crate::iri::IRI;
-use crate::length::{Dasharray, LengthBoth, LengthUnit};
+use crate::length::{Dasharray, LengthBoth, LengthTrait, LengthUnit};
 use crate::paint_server::PaintServer;
 use crate::parsers::{Parse, ParseError};
 use crate::properties::ComputedValues;


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