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};
macro_rules! node_create_fn {
($name:ident, $node_type:ident, $new_fn:expr) => {
fn $name(
element_name: &str,
id: Option<&str>,
class: Option<&str>,
parent: Option<&RsvgNode>,
) -> RsvgNode {
node_new(
NodeType::$node_type,
parent,
element_name,
id,
class,
Box::new($new_fn()),
)
fn $name(id: Option<&str>, class: Option<&str>, parent: Option<&RsvgNode>) -> RsvgNode {
node_new(NodeType::$node_type, parent, id, class, Box::new($new_fn()))
}
};
}
......@@ -69,24 +57,24 @@ node_create_fn!(
ComponentTransfer::new
);
node_create_fn!(
create_component_transfer_func_r,
ComponentTransferFunction,
FuncX::new_r
);
node_create_fn!(
create_component_transfer_func_g,
ComponentTransferFunction,
FuncX::new_g
create_component_transfer_func_a,
ComponentTransferFunctionA,
FuncX::new_a
);
node_create_fn!(
create_component_transfer_func_b,
ComponentTransferFunction,
ComponentTransferFunctionB,
FuncX::new_b
);
node_create_fn!(
create_component_transfer_func_a,
ComponentTransferFunction,
FuncX::new_a
create_component_transfer_func_g,
ComponentTransferFunctionG,
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!(
......@@ -102,7 +90,7 @@ node_create_fn!(
);
node_create_fn!(
create_distant_light,
LightSource,
DistantLight,
LightSource::new_distant_light
);
node_create_fn!(
......@@ -140,11 +128,7 @@ node_create_fn!(
node_create_fn!(create_offset, FilterPrimitiveOffset, Offset::new);
node_create_fn!(create_path, Path, NodePath::new);
node_create_fn!(create_pattern, Pattern, NodePattern::new);
node_create_fn!(
create_point_light,
LightSource,
LightSource::new_point_light
);
node_create_fn!(create_point_light, PointLight, LightSource::new_point_light);
node_create_fn!(create_polygon, Polygon, NodePoly::new_closed);
node_create_fn!(create_polyline, Polyline, NodePoly::new_open);
node_create_fn!(
......@@ -158,7 +142,7 @@ node_create_fn!(
FilterPrimitiveSpecularLighting,
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_style, Style, NodeStyle::new);
node_create_fn!(create_svg, Svg, NodeSvg::new);
......@@ -175,8 +159,20 @@ node_create_fn!(
);
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 =
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! {
// Lines in comments are elements that we don't support.
......@@ -194,7 +190,7 @@ lazy_static! {
h.insert("circle", (true, create_circle as NodeCreateFn));
h.insert("clipPath", (true, create_clip_path 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("defs", (true, create_defs as NodeCreateFn));
/* h.insert("desc", (true, as NodeCreateFn)); */
......@@ -207,10 +203,10 @@ lazy_static! {
h.insert("feDiffuseLighting", (true, create_diffuse_lighting as NodeCreateFn));
h.insert("feDisplacementMap", (true, create_displacement_map 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("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("feGaussianBlur", (true, create_gaussian_blur as NodeCreateFn));
h.insert("feImage", (true, create_fe_image as NodeCreateFn));
......@@ -243,7 +239,7 @@ lazy_static! {
/* h.insert("metadata", (false, as NodeCreateFn)); */
/* h.insert("missing-glyph", (true, 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("pattern", (true, create_pattern as NodeCreateFn));
h.insert("polygon", (true, create_polygon as NodeCreateFn));
......@@ -254,8 +250,8 @@ lazy_static! {
/* h.insert("set", (false, as NodeCreateFn)); */
h.insert("stop", (true, create_stop as NodeCreateFn));
h.insert("style", (false, create_style as NodeCreateFn));
h.insert("subImage", (false, create_group as NodeCreateFn));
h.insert("subImageRef", (false, create_image as NodeCreateFn));
h.insert("subImage", (false, create_sub_image as NodeCreateFn));
h.insert("subImageRef", (false, create_sub_image_ref as NodeCreateFn));
h.insert("svg", (true, create_svg as NodeCreateFn));
h.insert("switch", (true, create_switch as NodeCreateFn));
h.insert("symbol", (true, create_symbol as NodeCreateFn));
......@@ -300,7 +296,7 @@ pub fn create_node_and_register_id(
class = None;
};
let node = create_fn(name, id, class, parent);
let node = create_fn(id, class, parent);
if id.is_some() {
defs.insert(id.unwrap(), &node);
......
......@@ -293,10 +293,13 @@ impl Filter for ComponentTransfer {
)?;
// Enumerate all child <feFuncX> nodes.
let functions = node
.children()
.rev()
.filter(|c| c.get_type() == NodeType::ComponentTransferFunction);
let functions = node.children().rev().filter(|c| match c.get_type() {
NodeType::ComponentTransferFunctionA
| NodeType::ComponentTransferFunctionB
| NodeType::ComponentTransferFunctionG
| NodeType::ComponentTransferFunctionR => true,
_ => false,
});
// Get a node for every pixel component.
let get_node = |channel| {
......
......@@ -226,10 +226,10 @@ impl Filter for Lighting {
cssparser::Color::RGBA(rgba) => rgba,
};
let mut light_sources = node
.children()
.rev()
.filter(|c| c.get_type() == NodeType::LightSource);
let mut light_sources = node.children().rev().filter(|c| match c.get_type() {
NodeType::DistantLight | NodeType::PointLight | NodeType::SpotLight => true,
_ => false,
});
let light_source = light_sources.next();
if light_source.is_none() || light_sources.next().is_some() {
return Err(FilterError::InvalidLightSourceCount);
......
......@@ -151,7 +151,6 @@ pub type NodeResult = Result<(), NodeError>;
pub struct Node {
node_type: NodeType,
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
class: Option<String>, // class attribute from XML element
first_child: RefCell<Option<Rc<Node>>>,
......@@ -175,18 +174,19 @@ pub struct Children {
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
pub enum NodeType {
Invalid = 0,
Chars,
Circle,
ClipPath,
ComponentTransferFunction,
ComponentTransferFunctionA,
ComponentTransferFunctionB,
ComponentTransferFunctionG,
ComponentTransferFunctionR,
Defs,
DistantLight,
Ellipse,
Filter,
Group,
Image,
LightSource,
Line,
LinearGradient,
Link,
......@@ -194,10 +194,12 @@ pub enum NodeType {
Mask,
Path,
Pattern,
PointLight,
Polygon,
Polyline,
RadialGradient,
Rect,
SpotLight,
Stop,
Style,
Svg,
......@@ -209,7 +211,6 @@ pub enum NodeType {
Use,
// Filter primitives
FilterPrimitiveFirst, // just a marker; not a valid type
FilterPrimitiveBlend,
FilterPrimitiveColorMatrix,
FilterPrimitiveComponentTransfer,
......@@ -227,14 +228,71 @@ pub enum NodeType {
FilterPrimitiveSpecularLighting,
FilterPrimitiveTile,
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 {
pub fn new(
node_type: NodeType,
parent: Option<Weak<Node>>,
element_name: &str,
id: Option<&str>,
class: Option<&str>,
node_impl: Box<NodeTrait>,
......@@ -242,7 +300,6 @@ impl Node {
Node {
node_type,
parent,
element_name: element_name.to_string(),
id: id.map(str::to_string),
class: class.map(str::to_string),
first_child: RefCell::new(None),
......@@ -452,13 +509,14 @@ impl Node {
//
// This is basically a semi-compliant CSS2 selection engine
let element_name = self.node_type.element_name();
let mut state = self.state.borrow_mut();
// *
css_styles.lookup_apply("*", &mut state);
// 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() {
for cls in klazz.split_whitespace() {
......@@ -467,7 +525,7 @@ impl Node {
if !cls.is_empty() {
// tag.class#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);
}
......@@ -478,7 +536,7 @@ impl Node {
}
// tag.class
let target = format!("{}.{}", self.element_name, cls);
let target = format!("{}.{}", element_name, cls);
found = found || css_styles.lookup_apply(&target, &mut state);
if !found {
......@@ -496,7 +554,7 @@ impl Node {
css_styles.lookup_apply(&target, &mut state);
// tag#id
let target = format!("{}#{}", self.element_name, id);
let target = format!("{}#{}", element_name, id);
css_styles.lookup_apply(&target, &mut state);
}
}
......@@ -657,7 +715,6 @@ impl Node {
pub fn node_new(
node_type: NodeType,
parent: Option<&RsvgNode>,
element_name: &str,
id: Option<&str>,
class: Option<&str>,
node_impl: Box<NodeTrait>,
......@@ -669,7 +726,6 @@ pub fn node_new(
} else {
None
},
element_name,
id,
class,
node_impl,
......@@ -767,7 +823,6 @@ mod tests {
let node = Rc::new(Node::new(
NodeType::Path,
None,
"path",
None,
None,
Box::new(TestNodeImpl {}),
......@@ -793,7 +848,6 @@ mod tests {
let node = Rc::new(Node::new(
NodeType::Path,
None,
"path",
None,
None,
Box::new(TestNodeImpl {}),
......@@ -816,7 +870,6 @@ mod tests {
let node = Rc::new(Node::new(
NodeType::Path,
None,
"path",
None,
None,
Box::new(TestNodeImpl {}),
......@@ -830,7 +883,6 @@ mod tests {
let node = Rc::new(Node::new(
NodeType::Path,
None,
"path",
None,
None,
Box::new(TestNodeImpl {}),
......@@ -839,7 +891,6 @@ mod tests {
let child = Rc::new(Node::new(
NodeType::Path,
Some(Rc::downgrade(&node)),
"path",
None,
None,
Box::new(TestNodeImpl {}),
......@@ -856,7 +907,6 @@ mod tests {
let node = Rc::new(Node::new(
NodeType::Path,
None,
"path",
None,
None,
Box::new(TestNodeImpl {}),
......@@ -865,7 +915,6 @@ mod tests {
let child = Rc::new(Node::new(
NodeType::Path,
Some(Rc::downgrade(&node)),
"path",
None,
None,
Box::new(TestNodeImpl {}),
......@@ -874,7 +923,6 @@ mod tests {
let second_child = Rc::new(Node::new(
NodeType::Path,
Some(Rc::downgrade(&node)),
"path",
None,
None,
Box::new(TestNodeImpl {}),
......
......@@ -290,7 +290,6 @@ impl XmlState {
let child = node_new(
NodeType::Chars,
Some(node),
"rsvg-chars",
None,
None,
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