[librsvg: 1/4] (#484) implement basic auto-start-reverse functionality




commit 6f984e84b8749ece8043544d079214953241416d
Author: madds-h <madds hollandart io>
Date:   Tue Jun 15 20:09:57 2021 -0500

    (#484) implement basic auto-start-reverse functionality
    
    Part-of: <https://gitlab.gnome.org/GNOME/librsvg/-/merge_requests/550>

 src/angle.rs  |  5 +++++
 src/marker.rs | 34 +++++++++++++++++++++++++++++++---
 2 files changed, 36 insertions(+), 3 deletions(-)
---
diff --git a/src/angle.rs b/src/angle.rs
index 98835d46..8cd71d96 100644
--- a/src/angle.rs
+++ b/src/angle.rs
@@ -44,6 +44,11 @@ impl Angle {
         }
     }
 
+    //Flips an angle to be 180deg or PI radians rotated
+    pub fn flip(self) -> Angle {
+        Angle::new(self.radians() + PI)
+    }
+
     // Normalizes an angle to [0.0, 2*PI)
     fn normalize(rad: f64) -> f64 {
         let res = rad % (PI * 2.0);
diff --git a/src/marker.rs b/src/marker.rs
index b3d8e953..e06ff413 100644
--- a/src/marker.rs
+++ b/src/marker.rs
@@ -47,6 +47,7 @@ impl Parse for MarkerUnits {
 #[derive(Debug, Copy, Clone, PartialEq)]
 enum MarkerOrient {
     Auto,
+    AutoStartReverse,
     Angle(Angle),
 }
 
@@ -54,9 +55,21 @@ enum_default!(MarkerOrient, MarkerOrient::Angle(Angle::new(0.0)));
 
 impl Parse for MarkerOrient {
     fn parse<'i>(parser: &mut Parser<'i, '_>) -> Result<MarkerOrient, ParseError<'i>> {
-        parser
-            .try_parse(|p| p.expect_ident_matching("auto").map(|_| MarkerOrient::Auto))
-            .or_else(|_| Angle::parse(parser).map(MarkerOrient::Angle))
+        if parser
+            .try_parse(|p| p.expect_ident_matching("auto"))
+            .is_ok()
+        {
+            return Ok(MarkerOrient::Auto);
+        }
+
+        if parser
+            .try_parse(|p| p.expect_ident_matching("auto-start-reverse"))
+            .is_ok()
+        {
+            Ok(MarkerOrient::AutoStartReverse)
+        } else {
+            Angle::parse(parser).map(MarkerOrient::Angle)
+        }
     }
 }
 
@@ -98,6 +111,7 @@ impl Marker {
         computed_angle: Angle,
         line_width: f64,
         clipping: bool,
+        marker_type: MarkerType,
     ) -> Result<BoundingBox, RenderingError> {
         let cascaded = CascadedValues::new_from_node(&node);
         let values = cascaded.get();
@@ -116,6 +130,13 @@ impl Marker {
 
         let rotation = match self.orient {
             MarkerOrient::Auto => computed_angle,
+            MarkerOrient::AutoStartReverse => {
+                if marker_type == MarkerType::Start {
+                    computed_angle.flip()
+                } else {
+                    computed_angle
+                }
+            }
             MarkerOrient::Angle(a) => a,
         };
 
@@ -554,6 +575,7 @@ fn emit_marker_by_node(
     computed_angle: Angle,
     line_width: f64,
     clipping: bool,
+    marker_type: MarkerType,
 ) -> Result<BoundingBox, RenderingError> {
     match acquired_nodes.acquire_ref(marker_node) {
         Ok(acquired) => {
@@ -570,6 +592,7 @@ fn emit_marker_by_node(
                 computed_angle,
                 line_width,
                 clipping,
+                marker_type,
             )
         }
 
@@ -642,6 +665,7 @@ pub fn render_markers_for_shape(
                     computed_angle,
                     shape.stroke.width,
                     clipping,
+                    marker_type,
                 )
             } else {
                 Ok(draw_ctx.empty_bbox())
@@ -814,6 +838,10 @@ mod parser_tests {
     #[test]
     fn parses_marker_orient() {
         assert_eq!(MarkerOrient::parse_str("auto").unwrap(), MarkerOrient::Auto);
+        assert_eq!(
+            MarkerOrient::parse_str("auto-start-reverse").unwrap(),
+            MarkerOrient::AutoStartReverse
+        );
 
         assert_eq!(
             MarkerOrient::parse_str("0").unwrap(),


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