node.rs: Start implementing the basic Node struct in Rust

parent 190cd386
...@@ -279,6 +279,7 @@ typedef enum { ...@@ -279,6 +279,7 @@ typedef enum {
objectBoundingBox, userSpaceOnUse objectBoundingBox, userSpaceOnUse
} RsvgCoordUnits; } RsvgCoordUnits;
/* Keep this in sync with rust/src/node.rs:NodeType */
typedef enum { typedef enum {
RSVG_NODE_TYPE_INVALID = 0, RSVG_NODE_TYPE_INVALID = 0,
......
...@@ -5,13 +5,12 @@ extern crate libc; ...@@ -5,13 +5,12 @@ extern crate libc;
use self::glib::translate::*; use self::glib::translate::*;
use state::RsvgState; use node::RsvgNode;
use path_builder::RsvgPathBuilder; use path_builder::RsvgPathBuilder;
use state::RsvgState;
pub enum RsvgDrawingCtx {} pub enum RsvgDrawingCtx {}
pub enum RsvgNode {}
extern "C" { extern "C" {
fn rsvg_drawing_ctx_get_dpi (draw_ctx: *const RsvgDrawingCtx, fn rsvg_drawing_ctx_get_dpi (draw_ctx: *const RsvgDrawingCtx,
out_dpi_x: *mut f64, out_dpi_x: *mut f64,
......
...@@ -9,7 +9,7 @@ use length::*; ...@@ -9,7 +9,7 @@ use length::*;
use drawing_ctx; use drawing_ctx;
use drawing_ctx::RsvgDrawingCtx; use drawing_ctx::RsvgDrawingCtx;
use drawing_ctx::RsvgNode; use node::RsvgNode;
use bbox::*; use bbox::*;
......
...@@ -54,6 +54,10 @@ pub use length::{ ...@@ -54,6 +54,10 @@ pub use length::{
rsvg_length_hand_normalize, rsvg_length_hand_normalize,
}; };
pub use node::{
rsvg_node_get_type,
};
pub use viewbox::{ pub use viewbox::{
RsvgViewBox RsvgViewBox
}; };
......
extern crate libc; extern crate libc;
use std::rc::Rc;
use std::rc::Weak;
use std::cell::Cell;
use std::cell::RefCell;
use std::ptr;
use drawing_ctx; use drawing_ctx;
use drawing_ctx::RsvgDrawingCtx; use drawing_ctx::RsvgDrawingCtx;
...@@ -13,3 +19,144 @@ pub trait NodeTrait { ...@@ -13,3 +19,144 @@ pub trait NodeTrait {
fn set_atts (&self, handle: *const RsvgHandle, pbag: *const RsvgPropertyBag); fn set_atts (&self, handle: *const RsvgHandle, pbag: *const RsvgPropertyBag);
fn draw (&self, draw_ctx: *const RsvgDrawingCtx, dominate: i32); fn draw (&self, draw_ctx: *const RsvgDrawingCtx, dominate: i32);
} }
// strong Rc<Node> references in the toplevel RsvgHandle.all_nodes array
// weak references elsewhere inside of Node
pub struct Node<'a> {
node_type: NodeType,
parent: Option<Weak<RefCell<Node<'a>>>>, // optional; weak ref to parent-made-mutable
children: Vec<Rc<RefCell<Node<'a>>>>, // strong references to children-made-mutable through RefCell
state: *mut RsvgState,
node_impl: &'a NodeTrait
}
/* Keep this in sync with rsvg-private.h:RsvgNodeType */
#[repr(C)]
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum NodeType {
Invalid = 0,
Chars,
Circle,
ClipPath,
ComponentTransferFunction,
Defs,
Ellipse,
Filter,
Group,
Image,
LightSource,
Line,
LinearGradient,
Marker,
Mask,
Path,
Pattern,
Polygon,
Polyline,
RadialGradient,
Rect,
Stop,
Svg,
Switch,
Symbol,
Text,
TRef,
TSpan,
Use,
/* Filter primitives */
FilterPrimitiveFirst, /* just a marker; not a valid type */
FilterPrimitiveBlend,
FilterPrimitiveColorMatrix,
FilterPrimitiveComponentTransfer,
FilterPrimitiveComposite,
FilterPrimitiveConvolveMatrix,
FilterPrimitiveDiffuseLighting,
FilterPrimitiveDisplacementMap,
FilterPrimitiveErode,
FilterPrimitiveFlood,
FilterPrimitiveGaussianBlur,
FilterPrimitiveImage,
FilterPrimitiveMerge,
FilterPrimitiveMergeNode,
FilterPrimitiveOffset,
FilterPrimitiveSpecularLighting,
FilterPrimitiveTile,
FilterPrimitiveTurbulence,
FilterPrimitiveLast /* just a marker; not a valid type */
}
impl<'a> Node<'a> {
pub fn new (node_type: NodeType,
parent: Option<Weak<RefCell<Node<'a>>>>,
state: *mut RsvgState,
node_impl: &'a NodeTrait) -> Node<'a> {
Node {
node_type: node_type,
parent: parent,
children: Vec::new (),
state: state,
node_impl: node_impl
}
}
pub fn get_type (&self) -> NodeType {
self.node_type
}
pub fn get_state (&self) -> *mut RsvgState {
self.state
}
pub fn add_child (&mut self, child: &Rc<RefCell<Node<'a>>>) {
self.children.push (child.clone ());
}
}
pub enum RsvgNode {}
/* This is just to take a pointer to an Rc<RefCell<Node<'a>>> */
type RsvgRcNode<'a> = Rc<RefCell<Node<'a>>>;
#[no_mangle]
pub extern fn rsvg_node_get_type<'a> (raw_node: *const RsvgRcNode<'a>) -> NodeType {
assert! (!raw_node.is_null ());
let node: &RsvgRcNode<'a> = unsafe { & *raw_node };
node.borrow ().get_type ()
}
#[no_mangle]
pub extern fn rsvg_node_get_parent<'a> (raw_node: *const RsvgRcNode<'a>) -> *const RsvgRcNode<'a> {
assert! (!raw_node.is_null ());
let rc_node: &RsvgRcNode<'a> = unsafe { & *raw_node };
match rc_node.borrow ().parent {
None => { ptr::null () }
Some (ref weak_node) => {
let strong_node = weak_node.upgrade ().unwrap ();
&strong_node as *const RsvgRcNode<'a>
}
}
}
#[no_mangle]
pub extern fn rsvg_node_get_state<'a> (raw_node: *const RsvgRcNode<'a>) -> *mut RsvgState {
assert! (!raw_node.is_null ());
let rc_node: &RsvgRcNode<'a> = unsafe { & *raw_node };
rc_node.borrow ().get_state ()
}
#[no_mangle]
pub extern fn rsvg_node_add_child<'a> (raw_node: *mut RsvgRcNode<'a>, raw_child: *const RsvgRcNode<'a>) {
assert! (!raw_node.is_null ());
assert! (!raw_child.is_null ());
let rc_node: &mut RsvgRcNode<'a> = unsafe { &mut *raw_node };
let rc_child: &RsvgRcNode<'a> = unsafe { & *raw_child };
rc_node.borrow_mut ().add_child (rc_child);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment