[librsvg: 10/48] Port standard_element_start() to Rust



commit 05406503ebb21ae1d13135b73cbcdf4f2ec25f7d
Author: Federico Mena Quintero <federico gnome org>
Date:   Thu Sep 6 20:25:05 2018 -0500

    Port standard_element_start() to Rust
    
    Now the create_fn in load.rs can deal with RsvgNode directly, instead
    of boxed versions.

 librsvg/rsvg-load.c          | 54 +++++++++++---------------------------------
 rsvg_internals/src/handle.rs |  4 ++--
 rsvg_internals/src/lib.rs    |  3 ++-
 rsvg_internals/src/load.rs   | 52 ++++++++++++++----------------------------
 rsvg_internals/src/node.rs   | 23 +++++++++++++++++++
 rsvg_internals/src/xml.rs    | 52 ++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 109 insertions(+), 79 deletions(-)
---
diff --git a/librsvg/rsvg-load.c b/librsvg/rsvg-load.c
index 92851469..81baf2ad 100644
--- a/librsvg/rsvg-load.c
+++ b/librsvg/rsvg-load.c
@@ -37,14 +37,6 @@ typedef enum {
     LOAD_STATE_CLOSED
 } LoadState;
 
-/* Implemented in rsvg_internals/src/load.rs */
-G_GNUC_INTERNAL
-RsvgNode *rsvg_load_new_node (const char *element_name, RsvgNode *parent, RsvgPropertyBag *atts, RsvgDefs 
*defs);
-
-/* Implemented in rsvg_internals/src/load.rs */
-G_GNUC_INTERNAL
-void rsvg_load_set_node_atts (RsvgHandle *handle, RsvgNode *node, RsvgPropertyBag atts);
-
 /* Implemented in rsvg_internals/src/load.rs */
 G_GNUC_INTERNAL
 void rsvg_load_set_svg_node_atts (RsvgHandle *handle, RsvgNode *node);
@@ -67,6 +59,7 @@ extern void rsvg_xml_state_push_element_name(RsvgXmlState *xml, const char *name
 extern void rsvg_xml_state_pop_element_name(RsvgXmlState *xml);
 extern gboolean rsvg_xml_state_topmost_element_name_is(RsvgXmlState *xml, const char *name);
 extern void rsvg_xml_state_free_element_name_stack(RsvgXmlState *xml);
+extern void rsvg_xml_state_standard_element_start(RsvgXmlState *xml, RsvgHandle *handle, const char *name, 
RsvgPropertyBag atts);
 
 /* Holds the XML parsing state */
 typedef struct {
@@ -265,35 +258,6 @@ start_style (RsvgLoad *load, RsvgPropertyBag *atts)
     rsvg_property_bag_iter_end (iter);
 }
 
-static void
-standard_element_start (RsvgLoad *load, const char *name, RsvgPropertyBag * atts)
-{
-    RsvgDefs *defs;
-    RsvgNode *current_node;
-    RsvgNode *newnode;
-
-    defs = rsvg_handle_get_defs(load->handle);
-
-    current_node = rsvg_xml_state_get_current_node (load->xml.rust_state);
-
-    newnode = rsvg_load_new_node (name, current_node, atts, defs);
-
-    rsvg_xml_state_push_element_name (load->xml.rust_state, name);
-
-    if (current_node) {
-        rsvg_node_add_child (current_node, newnode);
-    } else if (is_svg) {
-        rsvg_xml_state_set_root (load->xml.rust_state, newnode);
-    }
-
-    rsvg_xml_state_set_current_node (load->xml.rust_state, newnode);
-    current_node = rsvg_node_unref (current_node);
-
-    rsvg_load_set_node_atts (load->handle, newnode, atts);
-
-    newnode = rsvg_node_unref (newnode);
-}
-
 /* start xinclude */
 
 typedef struct _RsvgSaxHandlerXinclude {
@@ -333,8 +297,12 @@ xinclude_handler_start (RsvgSaxHandler * self, const char *name, RsvgPropertyBag
         if (z->in_fallback) {
             if (!strcmp (name, "xi:include"))
                 start_xinclude (z->load, atts);
-            else
-                standard_element_start (z->load, (const char *) name, atts);
+            else {
+                rsvg_xml_state_standard_element_start (z->load->xml.rust_state,
+                                                       z->load->handle,
+                                                       (const char *) name,
+                                                       atts);
+            }
         } else if (!strcmp (name, "xi:fallback")) {
             z->in_fallback = TRUE;
         }
@@ -603,8 +571,12 @@ sax_start_element_cb (void *data, const xmlChar * name, const xmlChar ** atts)
             start_style (load, bag);
         else if (!strcmp ((const char *) name, "include"))      /* xi:include */
             start_xinclude (load, bag);
-        else
-            standard_element_start (load, (const char *) name, bag);
+        else {
+            rsvg_xml_state_standard_element_start (load->xml.rust_state,
+                                                   load->handle,
+                                                   (const char *) name,
+                                                   bag);
+        }
     }
 
     rsvg_property_bag_free (bag);
diff --git a/rsvg_internals/src/handle.rs b/rsvg_internals/src/handle.rs
index f75492e5..b202e7ee 100644
--- a/rsvg_internals/src/handle.rs
+++ b/rsvg_internals/src/handle.rs
@@ -35,10 +35,10 @@ extern "C" {
     ) -> *mut u8;
 }
 
-pub fn get_defs<'a>(handle: *const RsvgHandle) -> &'a Defs {
+pub fn get_defs<'a>(handle: *const RsvgHandle) -> &'a mut Defs {
     unsafe {
         let d = rsvg_handle_get_defs(handle);
-        &*(d as *const Defs)
+        &mut *(d as *mut Defs)
     }
 }
 
diff --git a/rsvg_internals/src/lib.rs b/rsvg_internals/src/lib.rs
index 4e7e6df2..22b75082 100644
--- a/rsvg_internals/src/lib.rs
+++ b/rsvg_internals/src/lib.rs
@@ -44,7 +44,7 @@ pub use drawing_ctx::{
     rsvg_drawing_ctx_new,
 };
 
-pub use load::{rsvg_load_new_node, rsvg_load_set_node_atts, rsvg_load_set_svg_node_atts};
+pub use load::rsvg_load_set_svg_node_atts;
 
 pub use node::{
     rsvg_node_add_child,
@@ -86,6 +86,7 @@ pub use xml::{
     rsvg_xml_state_push_element_name,
     rsvg_xml_state_set_current_node,
     rsvg_xml_state_set_root,
+    rsvg_xml_state_standard_element_start,
     rsvg_xml_state_steal_tree,
     rsvg_xml_state_topmost_element_name_is,
 };
diff --git a/rsvg_internals/src/load.rs b/rsvg_internals/src/load.rs
index 53142970..b7892f26 100644
--- a/rsvg_internals/src/load.rs
+++ b/rsvg_internals/src/load.rs
@@ -1,9 +1,8 @@
-use libc;
 use std::collections::HashMap;
 
 use attributes::Attribute;
 use clip_path::NodeClipPath;
-use defs::{Defs, RsvgDefs};
+use defs::Defs;
 use filters::{
     blend::Blend,
     color_matrix::ColorMatrix,
@@ -35,7 +34,6 @@ use shapes::{NodeCircle, NodeEllipse, NodeLine, NodePath, NodePoly, NodeRect};
 use stop::NodeStop;
 use structure::{NodeDefs, NodeGroup, NodeSvg, NodeSwitch, NodeSymbol, NodeUse};
 use text::{NodeTRef, NodeTSpan, NodeText};
-use util::utf8_cstr;
 
 macro_rules! node_create_fn {
     ($name:ident, $node_type:ident, $new_fn:expr) => {
@@ -43,9 +41,9 @@ macro_rules! node_create_fn {
             element_name: &str,
             id: Option<&str>,
             class: Option<&str>,
-            parent: *const RsvgNode,
-        ) -> *const RsvgNode {
-            boxed_node_new(
+            parent: Option<&RsvgNode>,
+        ) -> RsvgNode {
+            node_new(
                 NodeType::$node_type,
                 parent,
                 element_name,
@@ -176,7 +174,8 @@ node_create_fn!(
 );
 node_create_fn!(create_use, Use, NodeUse::new);
 
-type NodeCreateFn = fn(&str, Option<&str>, Option<&str>, *const RsvgNode) -> *const RsvgNode;
+type NodeCreateFn =
+    fn(name: &str, id: Option<&str>, class: Option<&str>, parent: Option<&RsvgNode>) -> RsvgNode;
 
 lazy_static! {
     // Lines in comments are elements that we don't support.
@@ -271,21 +270,12 @@ lazy_static! {
     };
 }
 
-#[no_mangle]
-pub extern "C" fn rsvg_load_new_node(
-    raw_name: *const libc::c_char,
-    parent: *const RsvgNode,
-    pbag: *const PropertyBag<'_>,
-    defs: *mut RsvgDefs,
-) -> *const RsvgNode {
-    assert!(!raw_name.is_null());
-    assert!(!pbag.is_null());
-    assert!(!defs.is_null());
-
-    let name = unsafe { utf8_cstr(raw_name) };
-    let pbag = unsafe { &*pbag };
-    let defs = unsafe { &mut *(defs as *mut Defs) };
-
+pub fn rsvg_load_new_node(
+    name: &str,
+    parent: Option<&RsvgNode>,
+    pbag: &PropertyBag,
+    defs: &mut Defs,
+) -> RsvgNode {
     let mut id = None;
     let mut class = None;
 
@@ -310,28 +300,20 @@ pub extern "C" fn rsvg_load_new_node(
     };
 
     let node = create_fn(name, id, class, parent);
-    assert!(!node.is_null());
 
     if id.is_some() {
-        let n = unsafe { &*node };
-        defs.insert(id.unwrap(), n);
+        defs.insert(id.unwrap(), &node);
     }
 
     node
 }
 
-#[no_mangle]
-pub extern "C" fn rsvg_load_set_node_atts(
+pub fn rsvg_load_set_node_atts(
     handle: *const RsvgHandle,
-    raw_node: *mut RsvgNode,
-    pbag: *const PropertyBag<'_>,
+    node: &RsvgNode,
+    tag: &str,
+    pbag: &PropertyBag,
 ) {
-    assert!(!raw_node.is_null());
-    assert!(!pbag.is_null());
-
-    let node: &RsvgNode = unsafe { &*raw_node };
-    let pbag = unsafe { &*pbag };
-
     node.set_atts(node, handle, pbag);
 
     // The "svg" node is special; it will load its id/class
diff --git a/rsvg_internals/src/node.rs b/rsvg_internals/src/node.rs
index 0e394cad..a2d35446 100644
--- a/rsvg_internals/src/node.rs
+++ b/rsvg_internals/src/node.rs
@@ -672,6 +672,29 @@ pub fn boxed_node_new(
     )))
 }
 
+pub fn node_new(
+    node_type: NodeType,
+    parent: Option<&RsvgNode>,
+    element_name: &str,
+    id: Option<&str>,
+    class: Option<&str>,
+    node_impl: Box<NodeTrait>,
+) -> RsvgNode {
+    Rc::new(Node::new(
+        node_type,
+        if let Some(parent) = parent {
+            Some(Rc::downgrade(parent))
+        } else {
+            None
+        },
+        element_name,
+        id,
+        class,
+        rsvg_state_new(),
+        node_impl,
+    ))
+}
+
 impl Children {
     fn new(next: Option<Rc<Node>>, next_back: Option<Rc<Node>>) -> Self {
         Self { next, next_back }
diff --git a/rsvg_internals/src/xml.rs b/rsvg_internals/src/xml.rs
index 41dcb202..50a14f1b 100644
--- a/rsvg_internals/src/xml.rs
+++ b/rsvg_internals/src/xml.rs
@@ -5,7 +5,10 @@ use std::rc::Rc;
 use glib::translate::*;
 use glib_sys;
 
+use handle::{self, RsvgHandle};
+use load::{rsvg_load_new_node, rsvg_load_set_node_atts};
 use node::{box_node, Node, RsvgNode};
+use property_bag::PropertyBag;
 use tree::{RsvgTree, Tree};
 use util::utf8_cstr;
 
@@ -71,6 +74,36 @@ impl XmlState {
     pub fn free_element_name_stack(&mut self) {
         self.element_name_stack.clear();
     }
+
+    pub fn standard_element_start(
+        &mut self,
+        handle: *const RsvgHandle,
+        name: &str,
+        pbag: &PropertyBag,
+    ) {
+        let mut defs = handle::get_defs(handle);
+        let mut is_svg = false;
+
+        let new_node = rsvg_load_new_node(
+            name,
+            self.current_node.as_ref(),
+            pbag,
+            &mut defs,
+            &mut is_svg,
+        );
+
+        self.push_element_name(name);
+
+        if let Some(ref current_node) = self.current_node {
+            current_node.add_child(&new_node);
+        } else if is_svg {
+            self.set_root(&new_node);
+        }
+
+        self.set_current_node(Some(new_node.clone()));
+
+        rsvg_load_set_node_atts(handle, &new_node, name, pbag);
+    }
 }
 
 #[no_mangle]
@@ -183,3 +216,22 @@ pub extern "C" fn rsvg_xml_state_free_element_name_stack(xml: *mut RsvgXmlState)
 
     xml.free_element_name_stack();
 }
+
+#[no_mangle]
+pub extern "C" fn rsvg_xml_state_standard_element_start(
+    xml: *mut RsvgXmlState,
+    handle: *const RsvgHandle,
+    name: *const libc::c_char,
+    pbag: *const PropertyBag,
+) {
+    assert!(!xml.is_null());
+    let xml = unsafe { &mut *(xml as *mut XmlState) };
+
+    assert!(!name.is_null());
+    let name = unsafe { utf8_cstr(name) };
+
+    assert!(!pbag.is_null());
+    let pbag = unsafe { &*pbag };
+
+    xml.standard_element_start(handle, name, pbag);
+}


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