[librsvg] parse_transform.lalrpop: Parse the "rotate" transform



commit 1f74649e75e36065e1f4349d7a3ee595d7557e9e
Author: Federico Mena Quintero <federico gnome org>
Date:   Wed Mar 22 08:46:43 2017 -0600

    parse_transform.lalrpop: Parse the "rotate" transform

 rust/src/parse_transform.lalrpop |   19 +++++++++++++++++++
 rust/src/parsers.rs              |   20 ++++++++++++++++++++
 2 files changed, 39 insertions(+), 0 deletions(-)
---
diff --git a/rust/src/parse_transform.lalrpop b/rust/src/parse_transform.lalrpop
index 6f9e66a..735fc69 100644
--- a/rust/src/parse_transform.lalrpop
+++ b/rust/src/parse_transform.lalrpop
@@ -4,6 +4,7 @@
 // Its operataion and grammar are described here:
 // https://www.w3.org/TR/SVG/coords.html#TransformAttribute
 
+use std::f64::consts::*;
 use std::str::FromStr;
 
 use pt::cairo;
@@ -33,6 +34,24 @@ pub Scale: cairo::Matrix = {
     "scale" "(" <sx: Num> comma? <sy: Num> ")" => cairo::Matrix::new (sx, 0.0, 0.0, sy, 0.0, 0.0),
 };
 
+pub Rotate: cairo::Matrix = {
+    "rotate" "(" <angle: Num> ")" => {
+        let a = angle * PI / 180.0;
+        let (s, c) = a.sin_cos ();
+        cairo::Matrix::new (c, s, -s, c, 0.0, 0.0)
+    },
+
+    "rotate" "(" <angle: Num> comma? <tx: Num> comma? <ty: Num> ")" => {
+        let a = angle * PI / 180.0;
+        let (s, c) = a.sin_cos ();
+        let mut m = cairo::Matrix::new (1.0, 0.0, 0.0, 1.0, tx, ty);
+
+        m = cairo::Matrix::multiply (&cairo::Matrix::new (c, s, -s, c, 0.0, 0.0), &m);
+        m = cairo::Matrix::multiply (&cairo::Matrix::new (1.0, 0.0, 0.0, 1.0, -tx, -ty), &m);
+        m
+    }
+};
+
 pub Num: f64 = <s:r"[+-]?([0-9]*\.[0-9]+|[0-9]+(\.[0-9]*)?)([Ee][+-]?[0-9]+)?"> =>
     f64::from_str (s).unwrap ();
 
diff --git a/rust/src/parsers.rs b/rust/src/parsers.rs
index 2511227..2ae58b8 100644
--- a/rust/src/parsers.rs
+++ b/rust/src/parsers.rs
@@ -328,4 +328,24 @@ mod parse_transform_tests {
         assert_eq! (parse_Scale ("scale(-1)").unwrap (),
                     cairo::Matrix::new (-1.0, 0.0, 0.0, -1.0, 0.0, 0.0));
     }
+
+    fn make_rotation_matrix (angle_degrees: f64, tx: f64, ty: f64) -> cairo::Matrix {
+        let angle = angle_degrees * PI / 180.0;
+
+        let mut m = cairo::Matrix::new (1.0, 0.0, 0.0, 1.0, tx, ty);
+
+        let mut r = cairo::Matrix::identity ();
+        r.rotate (angle);
+        m = cairo::Matrix::multiply (&r, &m);
+
+        m = cairo::Matrix::multiply (&cairo::Matrix::new (1.0, 0.0, 0.0, 1.0, -tx, -ty), &m);
+        m
+    }
+
+    #[test]
+    fn parses_rotate () {
+        assert_eq! (parse_Rotate ("rotate (30)").unwrap (), make_rotation_matrix (30.0, 0.0, 0.0));
+        assert_eq! (parse_Rotate ("rotate (30,-1,-2)").unwrap (), make_rotation_matrix (30.0, -1.0, -2.0));
+        assert_eq! (parse_Rotate ("rotate (30, -1, -2)").unwrap (), make_rotation_matrix (30.0, -1.0, -2.0));
+    }
 }


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