Commit cb059425 authored by Federico Mena Quintero's avatar Federico Mena Quintero

Merge branch 'pborelli/librsvg-node'

parents a19490cb efeaba56
Pipeline #43922 failed with stages
in 2 minutes and 58 seconds
...@@ -37,20 +37,8 @@ use text::{NodeTRef, NodeTSpan, NodeText}; ...@@ -37,20 +37,8 @@ use text::{NodeTRef, NodeTSpan, NodeText};
macro_rules! node_create_fn { macro_rules! node_create_fn {
($name:ident, $node_type:ident, $new_fn:expr) => { ($name:ident, $node_type:ident, $new_fn:expr) => {
fn $name( fn $name(id: Option<&str>, class: Option<&str>, parent: Option<&RsvgNode>) -> RsvgNode {
element_name: &str, node_new(NodeType::$node_type, parent, id, class, Box::new($new_fn()))
id: Option<&str>,
class: Option<&str>,
parent: Option<&RsvgNode>,
) -> RsvgNode {
node_new(
NodeType::$node_type,
parent,
element_name,
id,
class,
Box::new($new_fn()),
)
} }
}; };
} }
...@@ -69,24 +57,24 @@ node_create_fn!( ...@@ -69,24 +57,24 @@ node_create_fn!(
ComponentTransfer::new ComponentTransfer::new
); );
node_create_fn!( node_create_fn!(
create_component_transfer_func_r, create_component_transfer_func_a,
ComponentTransferFunction, ComponentTransferFunctionA,
FuncX::new_r FuncX::new_a
);
node_create_fn!(
create_component_transfer_func_g,
ComponentTransferFunction,
FuncX::new_g
); );
node_create_fn!( node_create_fn!(
create_component_transfer_func_b, create_component_transfer_func_b,
ComponentTransferFunction, ComponentTransferFunctionB,
FuncX::new_b FuncX::new_b
); );
node_create_fn!( node_create_fn!(
create_component_transfer_func_a, create_component_transfer_func_g,
ComponentTransferFunction, ComponentTransferFunctionG,
FuncX::new_a FuncX::new_g
);
node_create_fn!(
create_component_transfer_func_r,
ComponentTransferFunctionR,
FuncX::new_r
); );
node_create_fn!(create_composite, FilterPrimitiveComposite, Composite::new); node_create_fn!(create_composite, FilterPrimitiveComposite, Composite::new);
node_create_fn!( node_create_fn!(
...@@ -102,7 +90,7 @@ node_create_fn!( ...@@ -102,7 +90,7 @@ node_create_fn!(
); );
node_create_fn!( node_create_fn!(
create_distant_light, create_distant_light,
LightSource, DistantLight,
LightSource::new_distant_light LightSource::new_distant_light
); );
node_create_fn!( node_create_fn!(
...@@ -140,11 +128,7 @@ node_create_fn!( ...@@ -140,11 +128,7 @@ node_create_fn!(
node_create_fn!(create_offset, FilterPrimitiveOffset, Offset::new); node_create_fn!(create_offset, FilterPrimitiveOffset, Offset::new);
node_create_fn!(create_path, Path, NodePath::new); node_create_fn!(create_path, Path, NodePath::new);
node_create_fn!(create_pattern, Pattern, NodePattern::new); node_create_fn!(create_pattern, Pattern, NodePattern::new);
node_create_fn!( node_create_fn!(create_point_light, PointLight, LightSource::new_point_light);
create_point_light,
LightSource,
LightSource::new_point_light
);
node_create_fn!(create_polygon, Polygon, NodePoly::new_closed); node_create_fn!(create_polygon, Polygon, NodePoly::new_closed);
node_create_fn!(create_polyline, Polyline, NodePoly::new_open); node_create_fn!(create_polyline, Polyline, NodePoly::new_open);
node_create_fn!( node_create_fn!(
...@@ -158,7 +142,7 @@ node_create_fn!( ...@@ -158,7 +142,7 @@ node_create_fn!(
FilterPrimitiveSpecularLighting, FilterPrimitiveSpecularLighting,
Lighting::new_specular Lighting::new_specular
); );
node_create_fn!(create_spot_light, LightSource, LightSource::new_spot_light); node_create_fn!(create_spot_light, SpotLight, LightSource::new_spot_light);
node_create_fn!(create_stop, Stop, NodeStop::new); node_create_fn!(create_stop, Stop, NodeStop::new);
node_create_fn!(create_style, Style, NodeStyle::new); node_create_fn!(create_style, Style, NodeStyle::new);
node_create_fn!(create_svg, Svg, NodeSvg::new); node_create_fn!(create_svg, Svg, NodeSvg::new);
...@@ -175,8 +159,20 @@ node_create_fn!( ...@@ -175,8 +159,20 @@ node_create_fn!(
); );
node_create_fn!(create_use, Use, NodeUse::new); node_create_fn!(create_use, Use, NodeUse::new);
// hack to partially support conical gradient
node_create_fn!(
create_conical_gradient,
RadialGradient,
NodeGradient::new_radial
);
// hack to make multiImage sort-of work
node_create_fn!(create_multi_image, Switch, NodeSwitch::new);
node_create_fn!(create_sub_image, Group, NodeGroup::new);
node_create_fn!(create_sub_image_ref, Image, NodeImage::new);
type NodeCreateFn = type NodeCreateFn =
fn(name: &str, id: Option<&str>, class: Option<&str>, parent: Option<&RsvgNode>) -> RsvgNode; fn(id: Option<&str>, class: Option<&str>, parent: Option<&RsvgNode>) -> RsvgNode;
lazy_static! { lazy_static! {
// Lines in comments are elements that we don't support. // Lines in comments are elements that we don't support.
...@@ -194,7 +190,7 @@ lazy_static! { ...@@ -194,7 +190,7 @@ lazy_static! {
h.insert("circle", (true, create_circle as NodeCreateFn)); h.insert("circle", (true, create_circle as NodeCreateFn));
h.insert("clipPath", (true, create_clip_path as NodeCreateFn)); h.insert("clipPath", (true, create_clip_path as NodeCreateFn));
/* h.insert("color-profile", (false, as NodeCreateFn)); */ /* h.insert("color-profile", (false, as NodeCreateFn)); */
h.insert("conicalGradient", (true, create_radial_gradient as NodeCreateFn)); h.insert("conicalGradient", (true, create_conical_gradient as NodeCreateFn));
/* h.insert("cursor", (false, as NodeCreateFn)); */ /* h.insert("cursor", (false, as NodeCreateFn)); */
h.insert("defs", (true, create_defs as NodeCreateFn)); h.insert("defs", (true, create_defs as NodeCreateFn));
/* h.insert("desc", (true, as NodeCreateFn)); */ /* h.insert("desc", (true, as NodeCreateFn)); */
...@@ -207,10 +203,10 @@ lazy_static! { ...@@ -207,10 +203,10 @@ lazy_static! {
h.insert("feDiffuseLighting", (true, create_diffuse_lighting as NodeCreateFn)); h.insert("feDiffuseLighting", (true, create_diffuse_lighting as NodeCreateFn));
h.insert("feDisplacementMap", (true, create_displacement_map as NodeCreateFn)); h.insert("feDisplacementMap", (true, create_displacement_map as NodeCreateFn));
h.insert("feDistantLight", (false, create_distant_light as NodeCreateFn)); h.insert("feDistantLight", (false, create_distant_light as NodeCreateFn));
h.insert("feFuncR", (false, create_component_transfer_func_r as NodeCreateFn));
h.insert("feFuncG", (false, create_component_transfer_func_g as NodeCreateFn));
h.insert("feFuncB", (false, create_component_transfer_func_b as NodeCreateFn));
h.insert("feFuncA", (false, create_component_transfer_func_a as NodeCreateFn)); h.insert("feFuncA", (false, create_component_transfer_func_a as NodeCreateFn));
h.insert("feFuncB", (false, create_component_transfer_func_b as NodeCreateFn));
h.insert("feFuncG", (false, create_component_transfer_func_g as NodeCreateFn));
h.insert("feFuncR", (false, create_component_transfer_func_r as NodeCreateFn));
h.insert("feFlood", (true, create_flood as NodeCreateFn)); h.insert("feFlood", (true, create_flood as NodeCreateFn));
h.insert("feGaussianBlur", (true, create_gaussian_blur as NodeCreateFn)); h.insert("feGaussianBlur", (true, create_gaussian_blur as NodeCreateFn));
h.insert("feImage", (true, create_fe_image as NodeCreateFn)); h.insert("feImage", (true, create_fe_image as NodeCreateFn));
...@@ -243,7 +239,7 @@ lazy_static! { ...@@ -243,7 +239,7 @@ lazy_static! {
/* h.insert("metadata", (false, as NodeCreateFn)); */ /* h.insert("metadata", (false, as NodeCreateFn)); */
/* h.insert("missing-glyph", (true, as NodeCreateFn)); */ /* h.insert("missing-glyph", (true, as NodeCreateFn)); */
/* h.insert("mpath", (false, as NodeCreateFn)); */ /* h.insert("mpath", (false, as NodeCreateFn)); */
h.insert("multiImage", (false, create_switch as NodeCreateFn)); // hack to make multiImage sort-of work h.insert("multiImage", (false, create_multi_image as NodeCreateFn));
h.insert("path", (true, create_path as NodeCreateFn)); h.insert("path", (true, create_path as NodeCreateFn));
h.insert("pattern", (true, create_pattern as NodeCreateFn)); h.insert("pattern", (true, create_pattern as NodeCreateFn));
h.insert("polygon", (true, create_polygon as NodeCreateFn)); h.insert("polygon", (true, create_polygon as NodeCreateFn));
...@@ -254,8 +250,8 @@ lazy_static! { ...@@ -254,8 +250,8 @@ lazy_static! {
/* h.insert("set", (false, as NodeCreateFn)); */ /* h.insert("set", (false, as NodeCreateFn)); */
h.insert("stop", (true, create_stop as NodeCreateFn)); h.insert("stop", (true, create_stop as NodeCreateFn));
h.insert("style", (false, create_style as NodeCreateFn)); h.insert("style", (false, create_style as NodeCreateFn));
h.insert("subImage", (false, create_group as NodeCreateFn)); h.insert("subImage", (false, create_sub_image as NodeCreateFn));
h.insert("subImageRef", (false, create_image as NodeCreateFn)); h.insert("subImageRef", (false, create_sub_image_ref as NodeCreateFn));
h.insert("svg", (true, create_svg as NodeCreateFn)); h.insert("svg", (true, create_svg as NodeCreateFn));
h.insert("switch", (true, create_switch as NodeCreateFn)); h.insert("switch", (true, create_switch as NodeCreateFn));
h.insert("symbol", (true, create_symbol as NodeCreateFn)); h.insert("symbol", (true, create_symbol as NodeCreateFn));
...@@ -300,7 +296,7 @@ pub fn create_node_and_register_id( ...@@ -300,7 +296,7 @@ pub fn create_node_and_register_id(
class = None; class = None;
}; };
let node = create_fn(name, id, class, parent); let node = create_fn(id, class, parent);
if id.is_some() { if id.is_some() {
defs.insert(id.unwrap(), &node); defs.insert(id.unwrap(), &node);
......
...@@ -293,10 +293,13 @@ impl Filter for ComponentTransfer { ...@@ -293,10 +293,13 @@ impl Filter for ComponentTransfer {
)?; )?;
// Enumerate all child <feFuncX> nodes. // Enumerate all child <feFuncX> nodes.
let functions = node let functions = node.children().rev().filter(|c| match c.get_type() {
.children() NodeType::ComponentTransferFunctionA
.rev() | NodeType::ComponentTransferFunctionB
.filter(|c| c.get_type() == NodeType::ComponentTransferFunction); | NodeType::ComponentTransferFunctionG
| NodeType::ComponentTransferFunctionR => true,
_ => false,
});
// Get a node for every pixel component. // Get a node for every pixel component.
let get_node = |channel| { let get_node = |channel| {
......
...@@ -226,10 +226,10 @@ impl Filter for Lighting { ...@@ -226,10 +226,10 @@ impl Filter for Lighting {
cssparser::Color::RGBA(rgba) => rgba, cssparser::Color::RGBA(rgba) => rgba,
}; };
let mut light_sources = node let mut light_sources = node.children().rev().filter(|c| match c.get_type() {
.children() NodeType::DistantLight | NodeType::PointLight | NodeType::SpotLight => true,
.rev() _ => false,
.filter(|c| c.get_type() == NodeType::LightSource); });
let light_source = light_sources.next(); let light_source = light_sources.next();
if light_source.is_none() || light_sources.next().is_some() { if light_source.is_none() || light_sources.next().is_some() {
return Err(FilterError::InvalidLightSourceCount); return Err(FilterError::InvalidLightSourceCount);
......
...@@ -151,7 +151,6 @@ pub type NodeResult = Result<(), NodeError>; ...@@ -151,7 +151,6 @@ pub type NodeResult = Result<(), NodeError>;
pub struct Node { pub struct Node {
node_type: NodeType, node_type: NodeType,
parent: Option<Weak<Node>>, // optional; weak ref to parent parent: Option<Weak<Node>>, // optional; weak ref to parent
element_name: String, // we may want to intern these someday
id: Option<String>, // id attribute from XML element id: Option<String>, // id attribute from XML element
class: Option<String>, // class attribute from XML element class: Option<String>, // class attribute from XML element
first_child: RefCell<Option<Rc<Node>>>, first_child: RefCell<Option<Rc<Node>>>,
...@@ -175,18 +174,19 @@ pub struct Children { ...@@ -175,18 +174,19 @@ pub struct Children {
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)] #[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
pub enum NodeType { pub enum NodeType {
Invalid = 0,
Chars, Chars,
Circle, Circle,
ClipPath, ClipPath,
ComponentTransferFunction, ComponentTransferFunctionA,
ComponentTransferFunctionB,
ComponentTransferFunctionG,
ComponentTransferFunctionR,
Defs, Defs,
DistantLight,
Ellipse, Ellipse,
Filter, Filter,
Group, Group,
Image, Image,
LightSource,
Line, Line,
LinearGradient, LinearGradient,
Link, Link,
...@@ -194,10 +194,12 @@ pub enum NodeType { ...@@ -194,10 +194,12 @@ pub enum NodeType {
Mask, Mask,
Path, Path,
Pattern, Pattern,
PointLight,
Polygon, Polygon,
Polyline, Polyline,
RadialGradient, RadialGradient,
Rect, Rect,
SpotLight,
Stop, Stop,
Style, Style,
Svg, Svg,
...@@ -209,7 +211,6 @@ pub enum NodeType { ...@@ -209,7 +211,6 @@ pub enum NodeType {
Use, Use,
// Filter primitives // Filter primitives
FilterPrimitiveFirst, // just a marker; not a valid type
FilterPrimitiveBlend, FilterPrimitiveBlend,
FilterPrimitiveColorMatrix, FilterPrimitiveColorMatrix,
FilterPrimitiveComponentTransfer, FilterPrimitiveComponentTransfer,
...@@ -227,14 +228,71 @@ pub enum NodeType { ...@@ -227,14 +228,71 @@ pub enum NodeType {
FilterPrimitiveSpecularLighting, FilterPrimitiveSpecularLighting,
FilterPrimitiveTile, FilterPrimitiveTile,
FilterPrimitiveTurbulence, FilterPrimitiveTurbulence,
FilterPrimitiveLast, // just a marker; not a valid type }
impl NodeType {
fn element_name(&self) -> &'static str {
match self {
NodeType::Chars => "rsvg-chars", // Dummy element name for chars
NodeType::Circle => "circle",
NodeType::ClipPath => "clipPath",
NodeType::ComponentTransferFunctionA => "feFuncA",
NodeType::ComponentTransferFunctionB => "feFuncB",
NodeType::ComponentTransferFunctionG => "feFuncG",
NodeType::ComponentTransferFunctionR => "feFuncR",
NodeType::Defs => "defs",
NodeType::DistantLight => "feDistantLight",
NodeType::Ellipse => "ellipse",
NodeType::Filter => "filter",
NodeType::Group => "g",
NodeType::Image => "image",
NodeType::Line => "line",
NodeType::LinearGradient => "linearGradient",
NodeType::Link => "a",
NodeType::Marker => "marker",
NodeType::Mask => "mask",
NodeType::Path => "path",
NodeType::Pattern => "pattern",
NodeType::PointLight => "fePointight",
NodeType::Polygon => "polygon",
NodeType::Polyline => "polyline",
NodeType::RadialGradient => "radialGradient",
NodeType::Rect => "rect",
NodeType::SpotLight => "feSpotLight",
NodeType::Stop => "stop",
NodeType::Style => "style",
NodeType::Svg => "svg",
NodeType::Switch => "switch",
NodeType::Symbol => "symbol",
NodeType::Text => "text",
NodeType::TRef => "tref",
NodeType::TSpan => "tspan",
NodeType::Use => "use",
NodeType::FilterPrimitiveBlend => "feBlend",
NodeType::FilterPrimitiveColorMatrix => "feColorMatrix",
NodeType::FilterPrimitiveComponentTransfer => "feComponentTransfer",
NodeType::FilterPrimitiveComposite => "feComposite",
NodeType::FilterPrimitiveConvolveMatrix => "feConvolveMatrix",
NodeType::FilterPrimitiveDiffuseLighting => "feDiffuseLighting",
NodeType::FilterPrimitiveDisplacementMap => "feDisplacementMap",
NodeType::FilterPrimitiveFlood => "feFlood",
NodeType::FilterPrimitiveGaussianBlur => "feGaussianBlur",
NodeType::FilterPrimitiveImage => "feImage",
NodeType::FilterPrimitiveMerge => "feMerge",
NodeType::FilterPrimitiveMergeNode => "feMergeNode",
NodeType::FilterPrimitiveMorphology => "feMorphology",
NodeType::FilterPrimitiveOffset => "feOffset",
NodeType::FilterPrimitiveSpecularLighting => "feSpecularLighting",
NodeType::FilterPrimitiveTile => "feTile",
NodeType::FilterPrimitiveTurbulence => "feTurbulence",
}
}
} }
impl Node { impl Node {
pub fn new( pub fn new(
node_type: NodeType, node_type: NodeType,
parent: Option<Weak<Node>>, parent: Option<Weak<Node>>,
element_name: &str,
id: Option<&str>, id: Option<&str>,
class: Option<&str>, class: Option<&str>,
node_impl: Box<NodeTrait>, node_impl: Box<NodeTrait>,
...@@ -242,7 +300,6 @@ impl Node { ...@@ -242,7 +300,6 @@ impl Node {
Node { Node {
node_type, node_type,
parent, parent,
element_name: element_name.to_string(),
id: id.map(str::to_string), id: id.map(str::to_string),
class: class.map(str::to_string), class: class.map(str::to_string),
first_child: RefCell::new(None), first_child: RefCell::new(None),
...@@ -452,13 +509,14 @@ impl Node { ...@@ -452,13 +509,14 @@ impl Node {
// //
// This is basically a semi-compliant CSS2 selection engine // This is basically a semi-compliant CSS2 selection engine
let element_name = self.node_type.element_name();
let mut state = self.state.borrow_mut(); let mut state = self.state.borrow_mut();
// * // *
css_styles.lookup_apply("*", &mut state); css_styles.lookup_apply("*", &mut state);
// tag // tag
css_styles.lookup_apply(&self.element_name, &mut state); css_styles.lookup_apply(element_name, &mut state);
if let Some(klazz) = self.get_class() { if let Some(klazz) = self.get_class() {
for cls in klazz.split_whitespace() { for cls in klazz.split_whitespace() {
...@@ -467,7 +525,7 @@ impl Node { ...@@ -467,7 +525,7 @@ impl Node {
if !cls.is_empty() { if !cls.is_empty() {
// tag.class#id // tag.class#id
if let Some(id) = self.get_id() { if let Some(id) = self.get_id() {
let target = format!("{}.{}#{}", self.element_name, cls, id); let target = format!("{}.{}#{}", element_name, cls, id);
found = found || css_styles.lookup_apply(&target, &mut state); found = found || css_styles.lookup_apply(&target, &mut state);
} }
...@@ -478,7 +536,7 @@ impl Node { ...@@ -478,7 +536,7 @@ impl Node {
} }
// tag.class // tag.class
let target = format!("{}.{}", self.element_name, cls); let target = format!("{}.{}", element_name, cls);
found = found || css_styles.lookup_apply(&target, &mut state); found = found || css_styles.lookup_apply(&target, &mut state);
if !found { if !found {
...@@ -496,7 +554,7 @@ impl Node { ...@@ -496,7 +554,7 @@ impl Node {
css_styles.lookup_apply(&target, &mut state); css_styles.lookup_apply(&target, &mut state);
// tag#id // tag#id
let target = format!("{}#{}", self.element_name, id); let target = format!("{}#{}", element_name, id);
css_styles.lookup_apply(&target, &mut state); css_styles.lookup_apply(&target, &mut state);
} }
} }
...@@ -657,7 +715,6 @@ impl Node { ...@@ -657,7 +715,6 @@ impl Node {
pub fn node_new( pub fn node_new(
node_type: NodeType, node_type: NodeType,
parent: Option<&RsvgNode>, parent: Option<&RsvgNode>,
element_name: &str,
id: Option<&str>, id: Option<&str>,
class: Option<&str>, class: Option<&str>,
node_impl: Box<NodeTrait>, node_impl: Box<NodeTrait>,
...@@ -669,7 +726,6 @@ pub fn node_new( ...@@ -669,7 +726,6 @@ pub fn node_new(
} else { } else {
None None
}, },
element_name,
id, id,
class, class,
node_impl, node_impl,
...@@ -767,7 +823,6 @@ mod tests { ...@@ -767,7 +823,6 @@ mod tests {
let node = Rc::new(Node::new( let node = Rc::new(Node::new(
NodeType::Path, NodeType::Path,
None, None,
"path",
None, None,
None, None,
Box::new(TestNodeImpl {}), Box::new(TestNodeImpl {}),
...@@ -793,7 +848,6 @@ mod tests { ...@@ -793,7 +848,6 @@ mod tests {
let node = Rc::new(Node::new( let node = Rc::new(Node::new(
NodeType::Path, NodeType::Path,
None, None,
"path",
None, None,
None, None,
Box::new(TestNodeImpl {}), Box::new(TestNodeImpl {}),
...@@ -816,7 +870,6 @@ mod tests { ...@@ -816,7 +870,6 @@ mod tests {
let node = Rc::new(Node::new( let node = Rc::new(Node::new(
NodeType::Path, NodeType::Path,
None, None,
"path",
None, None,
None, None,
Box::new(TestNodeImpl {}), Box::new(TestNodeImpl {}),
...@@ -830,7 +883,6 @@ mod tests { ...@@ -830,7 +883,6 @@ mod tests {
let node = Rc::new(Node::new( let node = Rc::new(Node::new(
NodeType::Path, NodeType::Path,
None, None,
"path",
None, None,
None, None,
Box::new(TestNodeImpl {}), Box::new(TestNodeImpl {}),
...@@ -839,7 +891,6 @@ mod tests { ...@@ -839,7 +891,6 @@ mod tests {
let child = Rc::new(Node::new( let child = Rc::new(Node::new(
NodeType::Path, NodeType::Path,
Some(Rc::downgrade(&node)), Some(Rc::downgrade(&node)),
"path",
None, None,
None, None,
Box::new(TestNodeImpl {}), Box::new(TestNodeImpl {}),
...@@ -856,7 +907,6 @@ mod tests { ...@@ -856,7 +907,6 @@ mod tests {
let node = Rc::new(Node::new( let node = Rc::new(Node::new(
NodeType::Path, NodeType::Path,
None, None,
"path",
None, None,
None, None,
Box::new(TestNodeImpl {}), Box::new(TestNodeImpl {}),
...@@ -865,7 +915,6 @@ mod tests { ...@@ -865,7 +915,6 @@ mod tests {
let child = Rc::new(Node::new( let child = Rc::new(Node::new(
NodeType::Path, NodeType::Path,
Some(Rc::downgrade(&node)), Some(Rc::downgrade(&node)),
"path",
None, None,
None, None,
Box::new(TestNodeImpl {}), Box::new(TestNodeImpl {}),
...@@ -874,7 +923,6 @@ mod tests { ...@@ -874,7 +923,6 @@ mod tests {
let second_child = Rc::new(Node::new( let second_child = Rc::new(Node::new(
NodeType::Path, NodeType::Path,
Some(Rc::downgrade(&node)), Some(Rc::downgrade(&node)),
"path",
None, None,
None, None,
Box::new(TestNodeImpl {}), Box::new(TestNodeImpl {}),
......
...@@ -290,7 +290,6 @@ impl XmlState { ...@@ -290,7 +290,6 @@ impl XmlState {
let child = node_new( let child = node_new(
NodeType::Chars, NodeType::Chars,
Some(node), Some(node),
"rsvg-chars",
None, None,
None, None,
Box::new(NodeChars::new()), Box::new(NodeChars::new()),
......
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