[librsvg] transform.rs: New public function parse_transform()
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg] transform.rs: New public function parse_transform()
- Date: Wed, 22 Mar 2017 18:00:20 +0000 (UTC)
commit c06fbc77e32212d8563599cddce76d53c8391c59
Author: Federico Mena Quintero <federico gnome org>
Date: Wed Mar 22 10:44:55 2017 -0600
transform.rs: New public function parse_transform()
This wraps parse_TransformList as generated by lalrpop. It converts
lalrpop errors into our own AttributeError, and validates the resulting
transformation matrix.
rust/src/transform.rs | 95 +++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 81 insertions(+), 14 deletions(-)
---
diff --git a/rust/src/transform.rs b/rust/src/transform.rs
index 0b61536..8dd5426 100644
--- a/rust/src/transform.rs
+++ b/rust/src/transform.rs
@@ -1,3 +1,5 @@
+extern crate lalrpop_util;
+
extern crate cairo;
use self::cairo::MatrixTrait;
@@ -5,8 +7,86 @@ use std::f64::consts::*;
use parse_transform::*;
+use error::*;
+use parsers::ParseError;
+
+pub fn parse_transform (s: &str) -> Result <cairo::Matrix, AttributeError> {
+ let r = parse_TransformList (s);
+
+ match r {
+ Ok (m) => {
+ m.try_invert ().map (|_| m)
+ .map_err (|_| AttributeError::Value ("invalid transformation matrix".to_string ()))
+ },
+
+ Err (e) => {
+ Err (AttributeError::Parse (ParseError::new (format! ("{:?}", e))))
+ }
+ }
+}
+
+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
+}
+
#[cfg(test)]
-mod parse_transform_tests {
+mod test {
+ use super::*;
+
+ #[test]
+ fn parses_valid_transform () {
+ let t = cairo::Matrix::new (1.0, 0.0, 0.0, 1.0, 20.0, 30.0);
+ let s = cairo::Matrix::new (10.0, 0.0, 0.0, 10.0, 0.0, 0.0);
+ let r = make_rotation_matrix (30.0, 10.0, 10.0);
+
+ let a = cairo::Matrix::multiply (&s, &t);
+ assert_eq! (parse_transform ("translate(20, 30), scale (10) rotate (30 10 10)").unwrap (),
+ cairo::Matrix::multiply (&r, &a));
+ }
+
+ #[test]
+ fn syntax_error_yields_parse_error () {
+ match parse_transform ("foo") {
+ Err (AttributeError::Parse (_)) => {},
+ _ => { panic! (); }
+ }
+
+ match parse_transform ("matrix (1 2 3 4 5)") {
+ Err (AttributeError::Parse (_)) => {},
+ _ => { panic! (); }
+ }
+ }
+
+ #[test]
+ fn invalid_transform_yields_value_error () {
+ match parse_transform ("matrix (0 0 0 0 0 0)") {
+ Err (AttributeError::Value (_)) => {},
+ _ => { panic! (); }
+ }
+
+ match parse_transform ("scale (0), translate (10, 10)") {
+ Err (AttributeError::Value (_)) => {},
+ _ => { panic! (); }
+ }
+
+ match parse_transform ("scale (0), skewX (90)") {
+ Err (AttributeError::Value (_)) => {},
+ _ => { panic! (); }
+ }
+ }
+}
+
+#[cfg(test)]
+mod parser_tests {
use super::*;
#[test]
@@ -64,19 +144,6 @@ mod parse_transform_tests {
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));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]