[librsvg: 3/10] Put most of the define_length_type macro in a trait
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 3/10] Put most of the define_length_type macro in a trait
- Date: Wed, 13 Nov 2019 03:38:31 +0000 (UTC)
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]