[librsvg] shapes.rs: NodeLine completely implemented in Rust. Yay!



commit 4ba0fef19bff5542b7ca9ad2857dd4ae7ef896bf
Author: Federico Mena Quintero <federico gnome org>
Date:   Mon Feb 20 16:06:16 2017 -0600

    shapes.rs: NodeLine completely implemented in Rust.  Yay!

 rsvg-base.c        |    2 +-
 rsvg-shapes.c      |   73 --------------------------------------
 rsvg-shapes.h      |    6 ++-
 rust/src/lib.rs    |    1 +
 rust/src/shapes.rs |   98 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 104 insertions(+), 76 deletions(-)
---
diff --git a/rsvg-base.c b/rsvg-base.c
index 17df81c..983576c 100644
--- a/rsvg-base.c
+++ b/rsvg-base.c
@@ -305,7 +305,7 @@ static const NodeCreator node_creators[] = {
     /* "glyphRef",           TRUE,  */
     /* "hkern",              FALSE, */
     { "image",               TRUE,  rsvg_new_image },
-    { "line",                TRUE,  rsvg_new_line },
+    { "line",                TRUE,  rsvg_node_line_new },
     { "linearGradient",      TRUE,  rsvg_new_linear_gradient },
     { "marker",              TRUE,  rsvg_new_marker },
     { "mask",                TRUE,  rsvg_new_mask },
diff --git a/rsvg-shapes.c b/rsvg-shapes.c
index 9f9f98b..1ef1a9f 100644
--- a/rsvg-shapes.c
+++ b/rsvg-shapes.c
@@ -167,79 +167,6 @@ rsvg_new_polyline (const char *element_name, RsvgNode *parent)
     return rsvg_new_any_poly (RSVG_NODE_TYPE_POLYLINE, parent);
 }
 
-
-typedef struct _RsvgNodeLine RsvgNodeLine;
-
-struct _RsvgNodeLine {
-    RsvgLength x1, x2, y1, y2;
-};
-
-static void
-rsvg_node_line_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag *atts)
-{
-    RsvgNodeLine *line = impl;
-    const char *value;
-
-    if ((value = rsvg_property_bag_lookup (atts, "x1")))
-        line->x1 = rsvg_length_parse (value, LENGTH_DIR_HORIZONTAL);
-    if ((value = rsvg_property_bag_lookup (atts, "y1")))
-        line->y1 = rsvg_length_parse (value, LENGTH_DIR_VERTICAL);
-    if ((value = rsvg_property_bag_lookup (atts, "x2")))
-        line->x2 = rsvg_length_parse (value, LENGTH_DIR_HORIZONTAL);
-    if ((value = rsvg_property_bag_lookup (atts, "y2")))
-        line->y2 = rsvg_length_parse (value, LENGTH_DIR_VERTICAL);
-}
-
-static void
-rsvg_node_line_draw (RsvgNode *node, gpointer impl, RsvgDrawingCtx *ctx, int dominate)
-{
-    RsvgNodeLine *line = impl;
-    RsvgPathBuilder *builder;
-    double x1, y1, x2, y2;
-
-    builder = rsvg_path_builder_new ();
-
-    x1 = rsvg_length_normalize (&line->x1, ctx);
-    y1 = rsvg_length_normalize (&line->y1, ctx);
-    x2 = rsvg_length_normalize (&line->x2, ctx);
-    y2 = rsvg_length_normalize (&line->y2, ctx);
-
-    rsvg_path_builder_move_to (builder, x1, y1);
-    rsvg_path_builder_line_to (builder, x2, y2);
-
-    rsvg_state_reinherit_top (ctx, rsvg_node_get_state (node), dominate);
-
-    rsvg_render_path_builder (ctx, builder);
-    rsvg_render_markers (ctx, builder);
-
-    rsvg_path_builder_destroy (builder);
-}
-
-static void
-rsvg_node_line_free (gpointer impl)
-{
-    RsvgNodeLine *line = impl;
-
-    g_free (line);
-}
-
-RsvgNode *
-rsvg_new_line (const char *element_name, RsvgNode *parent)
-{
-    RsvgNodeLine *line;
-
-    line = g_new0 (RsvgNodeLine, 1);
-    line->x1 = line->x2 = line->y1 = line->y2 = rsvg_length_parse ("0", LENGTH_DIR_BOTH);
-
-    return rsvg_rust_cnode_new (RSVG_NODE_TYPE_LINE,
-                                parent,
-                                rsvg_state_new (),
-                                line,
-                                rsvg_node_line_set_atts,
-                                rsvg_node_line_draw,
-                                rsvg_node_line_free);
-}
-
 typedef struct _RsvgNodeRect RsvgNodeRect;
 
 struct _RsvgNodeRect {
diff --git a/rsvg-shapes.h b/rsvg-shapes.h
index c6b33b5..855f9e1 100644
--- a/rsvg-shapes.h
+++ b/rsvg-shapes.h
@@ -40,13 +40,15 @@ G_BEGIN_DECLS
 G_GNUC_INTERNAL
 RsvgNode *rsvg_node_path_new (const char *element_name, RsvgNode *parent);
 
+/* Implemented in rust/src/shapes.rs */
+G_GNUC_INTERNAL
+RsvgNode *rsvg_node_line_new (const char *element_name, RsvgNode *parent);
+
 G_GNUC_INTERNAL
 RsvgNode *rsvg_new_polygon (const char *element_name, RsvgNode *parent);
 G_GNUC_INTERNAL
 RsvgNode *rsvg_new_polyline (const char *element_name, RsvgNode *parent);
 G_GNUC_INTERNAL
-RsvgNode *rsvg_new_line (const char *element_name, RsvgNode *parent);
-G_GNUC_INTERNAL
 RsvgNode *rsvg_new_rect (const char *element_name, RsvgNode *parent);
 G_GNUC_INTERNAL
 RsvgNode *rsvg_new_circle (const char *element_name, RsvgNode *parent);
diff --git a/rust/src/lib.rs b/rust/src/lib.rs
index 512f368..ae61d88 100644
--- a/rust/src/lib.rs
+++ b/rust/src/lib.rs
@@ -79,6 +79,7 @@ pub use pattern::{
 };
 
 pub use shapes::{
+    rsvg_node_line_new,
     rsvg_node_path_new,
 };
 pub use viewbox::{
diff --git a/rust/src/shapes.rs b/rust/src/shapes.rs
index afe7ba4..adf6a7d 100644
--- a/rust/src/shapes.rs
+++ b/rust/src/shapes.rs
@@ -1,12 +1,14 @@
 use std::cell::RefCell;
 use std::ptr;
 use std::rc::Rc;
+use std::cell::Cell;
 extern crate libc;
 
 use cnode::*;
 use drawing_ctx;
 use drawing_ctx::*;
 use handle::RsvgHandle;
+use length::*;
 use marker;
 use node::*;
 use path_builder::*;
@@ -63,6 +65,94 @@ impl NodeTrait for NodePath {
     }
 }
 
+/***** NodePoly *****/
+/*
+struct NodePoly {
+    builder: RefCell<RsvgPathBuilder>
+}
+
+impl NodePoly {
+    fn new () -> NodePoly {
+        NodePoly {
+            builder: RefCell::new (RsvgPathBuilder::new ())
+        }
+    }
+}
+
+impl NodeTrait for NodePoly {
+    fn set_atts (&self, _: &RsvgNode, _: *const RsvgHandle, pbag: *const RsvgPropertyBag) {
+        // support for svg < 1.0 which used verts
+        if let Some (value) = property_bag::lookup (pbag, "verts").or (property_bag::lookup (pbag, 
"points")) {
+            let mut builder = self.builder.borrow_mut ();
+
+
+        }
+    }
+
+    fn draw (&self, node: &RsvgNode, draw_ctx: *const RsvgDrawingCtx, dominate: i32) {
+        render_path_builder (&*self.builder.borrow (), draw_ctx, node.get_state (), dominate, true);
+    }
+
+    fn get_c_impl (&self) -> *const RsvgCNodeImpl {
+        ptr::null ()
+    }
+}
+*/
+
+/***** NodeLine *****/
+
+struct NodeLine {
+    x1: Cell<RsvgLength>,
+    y1: Cell<RsvgLength>,
+    x2: Cell<RsvgLength>,
+    y2: Cell<RsvgLength>
+}
+
+impl NodeLine {
+    fn new () -> NodeLine {
+        NodeLine {
+            x1: Cell::new (RsvgLength::default ()),
+            y1: Cell::new (RsvgLength::default ()),
+            x2: Cell::new (RsvgLength::default ()),
+            y2: Cell::new (RsvgLength::default ())
+        }
+    }
+}
+
+impl NodeTrait for NodeLine {
+    fn set_atts (&self, _: &RsvgNode, _: *const RsvgHandle, pbag: *const RsvgPropertyBag) {
+        self.x1.set (property_bag::lookup (pbag, "x1").map_or (RsvgLength::default (),
+                                                               |v| RsvgLength::parse (&v, 
LengthDir::Horizontal)));
+
+        self.y1.set (property_bag::lookup (pbag, "y1").map_or (RsvgLength::default (),
+                                                               |v| RsvgLength::parse (&v, 
LengthDir::Vertical)));
+
+        self.x2.set (property_bag::lookup (pbag, "x2").map_or (RsvgLength::default (),
+                                                               |v| RsvgLength::parse (&v, 
LengthDir::Horizontal)));
+
+        self.y2.set (property_bag::lookup (pbag, "y2").map_or (RsvgLength::default (),
+                                                               |v| RsvgLength::parse (&v, 
LengthDir::Vertical)));
+    }
+
+    fn draw (&self, node: &RsvgNode, draw_ctx: *const RsvgDrawingCtx, dominate: i32) {
+        let mut builder = RsvgPathBuilder::new ();
+
+        let x1 = self.x1.get ().normalize (draw_ctx);
+        let y1 = self.y1.get ().normalize (draw_ctx);
+        let x2 = self.x2.get ().normalize (draw_ctx);
+        let y2 = self.y2.get ().normalize (draw_ctx);
+
+        builder.move_to (x1, y1);
+        builder.line_to (x2, y2);
+
+        render_path_builder (&builder, draw_ctx, node.get_state (), dominate, true);
+    }
+
+    fn get_c_impl (&self) -> *const RsvgCNodeImpl {
+        ptr::null ()
+    }
+}
+
 /***** C Prototypes *****/
 
 #[no_mangle]
@@ -72,3 +162,11 @@ pub extern fn rsvg_node_path_new (element_name: *const libc::c_char, raw_parent:
                                   drawing_ctx::state_new (),
                                   Box::new (NodePath::new ()))))
 }
+
+#[no_mangle]
+pub extern fn rsvg_node_line_new (element_name: *const libc::c_char, raw_parent: *const RsvgNode) -> *const 
RsvgNode {
+    box_node (Rc::new (Node::new (NodeType::Line,
+                                  parent_ptr_to_weak (raw_parent),
+                                  drawing_ctx::state_new (),
+                                  Box::new (NodeLine::new ()))))
+}


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