[librsvg: 10/48] Port standard_element_start() to Rust
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 10/48] Port standard_element_start() to Rust
- Date: Sat, 17 Nov 2018 10:20:52 +0000 (UTC)
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]