[librsvg/rustification] path_parser.rs: Implement closepath commands 'Z' and 'z'



commit 0d8d4b39008a0185d037d6df56f6edc687525600
Author: Federico Mena Quintero <federico gnome org>
Date:   Tue Nov 8 14:24:45 2016 -0600

    path_parser.rs: Implement closepath commands 'Z' and 'z'

 rust/src/path_parser.rs |   47 +++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 45 insertions(+), 2 deletions(-)
---
diff --git a/rust/src/path_parser.rs b/rust/src/path_parser.rs
index 3799ec0..0d5bd41 100644
--- a/rust/src/path_parser.rs
+++ b/rust/src/path_parser.rs
@@ -31,6 +31,12 @@ pub struct PathParser<'external> {
      */
     quadratic_reflection_x: f64,
     quadratic_reflection_y: f64,
+
+    /* Start point of current subpath (i.e. position of last moveto);
+     * used for closepath.
+     */
+    subpath_start_x: f64,
+    subpath_start_y: f64
 }
 
 /* This is a recursive descent parser for path data in SVG files,
@@ -78,7 +84,10 @@ impl<'external> PathParser<'external> {
             cubic_reflection_y: 0.0,
 
             quadratic_reflection_x: 0.0,
-            quadratic_reflection_y: 0.0
+            quadratic_reflection_y: 0.0,
+
+            subpath_start_x: 0.0,
+            subpath_start_y: 0.0
         }
     }
 
@@ -306,6 +315,9 @@ impl<'external> PathParser<'external> {
     fn emit_move_to (&mut self, x: f64, y: f64) {
         self.set_current_point (x, y);
 
+        self.subpath_start_x = self.current_x;
+        self.subpath_start_y = self.current_y;
+
         self.builder.move_to (self.current_x, self.current_y);
         println! ("emitting moveto {} {}", self.current_x, self.current_y);
     }
@@ -340,6 +352,13 @@ impl<'external> PathParser<'external> {
         println! ("emitting curveto ({} {}) ({} {}) ({} {})", x2, y2, x3, y3, x4, y4);
     }
 
+    fn emit_close_path (&mut self) {
+        let (x, y) = (self.subpath_start_x, self.subpath_start_y);
+        self.set_current_point (x, y);
+
+        self.builder.close_path ();
+    }
+
     fn lineto_argument_sequence (&mut self, absolute: bool) -> bool {
         if let Some ((mut x, mut y)) = self.coordinate_pair () {
             if !absolute {
@@ -468,7 +487,12 @@ impl<'external> PathParser<'external> {
     }
 
     fn close_path (&mut self) -> bool {
-        false
+        if self.match_char ('Z') || self.match_char ('z') {
+            self.emit_close_path ();
+            true
+        } else {
+            false
+        }
     }
 
     fn line_to (&mut self) -> bool {
@@ -1384,4 +1408,23 @@ mod tests {
                          curveto (220.0 / 3.0, 280.0 / 3.0, 50.0, 120.0, -10.0, 160.0)
                      ]);
     }
+
+    #[test]
+    fn path_parser_handles_close_path () {
+        test_parser ("M10 20 Z",
+                     &vec! [
+                         moveto (10.0, 20.0),
+                         closepath ()
+                     ]);
+
+        test_parser ("m10 20 30 40 m 50 60 70 80 90 100z",
+                     &vec![
+                         moveto (10.0, 20.0),
+                         lineto (40.0, 60.0),
+                         moveto (90.0, 120.0),
+                         lineto (160.0, 200.0),
+                         lineto (250.0, 300.0),
+                         closepath ()
+                     ]);
+    }
 }


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