Port <style> element handling to Rust

parent 5fc3ca24
...@@ -95,14 +95,6 @@ struct RsvgSaxHandler { ...@@ -95,14 +95,6 @@ struct RsvgSaxHandler {
void (*characters) (RsvgSaxHandler * self, const char *ch, gsize len); void (*characters) (RsvgSaxHandler * self, const char *ch, gsize len);
}; };
typedef struct _RsvgSaxHandlerStyle {
RsvgSaxHandler super;
RsvgSaxHandler *parent;
RsvgLoad *load;
GString *style;
gboolean is_text_css;
} RsvgSaxHandlerStyle;
static xmlSAXHandler get_xml2_sax_handler (void); static xmlSAXHandler get_xml2_sax_handler (void);
RsvgLoad * RsvgLoad *
...@@ -170,90 +162,6 @@ rsvg_load_steal_tree (RsvgLoad *load) ...@@ -170,90 +162,6 @@ rsvg_load_steal_tree (RsvgLoad *load)
return rsvg_xml_state_steal_tree (load->xml.rust_state); return rsvg_xml_state_steal_tree (load->xml.rust_state);
} }
static void
style_handler_free (RsvgSaxHandler * self)
{
RsvgSaxHandlerStyle *z = (RsvgSaxHandlerStyle *) self;
if (z->is_text_css)
rsvg_css_parse_into_handle (z->load->handle, z->style->str, z->style->len);
g_string_free (z->style, TRUE);
g_free (z);
}
static void
style_handler_characters (RsvgSaxHandler * self, const char *ch, gsize len)
{
RsvgSaxHandlerStyle *z = (RsvgSaxHandlerStyle *) self;
g_string_append_len (z->style, ch, len);
}
static void
style_handler_start (RsvgSaxHandler * self, const char *name, RsvgPropertyBag atts)
{
}
static void
style_handler_end (RsvgSaxHandler * self, const char *name)
{
RsvgSaxHandlerStyle *z = (RsvgSaxHandlerStyle *) self;
RsvgSaxHandler *previous = z->parent;
RsvgLoad *load = z->load;
if (!strcmp (name, "style")) {
if (load->xml.handler != NULL) {
load->xml.handler->free (load->xml.handler);
load->xml.handler = previous;
}
}
}
static void
start_style (RsvgLoad *load, RsvgPropertyBag *atts)
{
RsvgSaxHandlerStyle *handler = g_new0 (RsvgSaxHandlerStyle, 1);
RsvgPropertyBagIter *iter;
const char *key;
RsvgAttribute attr;
const char *value;
handler->super.free = style_handler_free;
handler->super.characters = style_handler_characters;
handler->super.start_element = style_handler_start;
handler->super.end_element = style_handler_end;
handler->load = load;
handler->style = g_string_new (NULL);
handler->parent = load->xml.handler;
load->xml.handler = &handler->super;
/* FIXME: See these:
*
* https://www.w3.org/TR/SVG/styling.html#StyleElementTypeAttribute
* https://www.w3.org/TR/SVG/styling.html#ContentStyleTypeAttribute
*
* If the "type" attribute is not present, we should fallback to the
* "contentStyleType" attribute of the svg element, which in turn
* defaults to "text/css".
*
* See where is_text_css is used to see where we parse the contents
* of the style element.
*/
handler->is_text_css = TRUE;
iter = rsvg_property_bag_iter_begin (atts);
while (rsvg_property_bag_iter_next (iter, &key, &attr, &value)) {
if (attr == RSVG_ATTRIBUTE_TYPE) {
handler->is_text_css = (g_ascii_strcasecmp (value, "text/css") == 0);
}
}
rsvg_property_bag_iter_end (iter);
}
/* start xinclude */ /* start xinclude */
typedef struct _RsvgSaxHandlerXinclude { typedef struct _RsvgSaxHandlerXinclude {
......
...@@ -86,7 +86,7 @@ struct DocHandlerData { ...@@ -86,7 +86,7 @@ struct DocHandlerData {
selector: *mut CRSelector, selector: *mut CRSelector,
} }
fn parse_into_handle(handle: *mut RsvgHandle, buf: &str) { pub fn parse_into_handle(handle: *mut RsvgHandle, buf: &str) {
unsafe { unsafe {
let handler_data = DocHandlerData { let handler_data = DocHandlerData {
handle, handle,
......
use libc; use libc;
use std; use std;
use std::cell::RefCell;
use std::ptr; use std::ptr;
use std::rc::Rc; use std::rc::Rc;
use std::str; use std::str;
use attributes::Attribute;
use css;
use handle::{self, RsvgHandle}; use handle::{self, RsvgHandle};
use load::rsvg_load_new_node; use load::rsvg_load_new_node;
use node::{node_new, Node, NodeType}; use node::{node_new, Node, NodeType};
...@@ -55,7 +58,8 @@ impl XmlHandler for NodeCreationContext { ...@@ -55,7 +58,8 @@ impl XmlHandler for NodeCreationContext {
pbag: &PropertyBag, pbag: &PropertyBag,
) -> Box<XmlHandler> { ) -> Box<XmlHandler> {
if name == "style" { if name == "style" {
unimplemented!(); let ctx = StyleContext::empty();
StyleContext::start_element(&ctx, parent, handle, name, pbag)
} else { } else {
let node = self.create_node(parent, handle, name, pbag); let node = self.create_node(parent, handle, name, pbag);
...@@ -145,25 +149,65 @@ impl NodeCreationContext { ...@@ -145,25 +149,65 @@ impl NodeCreationContext {
} }
/// Handles the `<style>` element by parsing its character contents as CSS /// Handles the `<style>` element by parsing its character contents as CSS
struct StyleContext {} struct StyleContext {
is_text_css: bool,
text: RefCell<String>,
}
impl XmlHandler for StyleContext { impl XmlHandler for StyleContext {
fn start_element( fn start_element(
&self, &self,
parent: Option<&Rc<Node>>, _parent: Option<&Rc<Node>>,
handle: *mut RsvgHandle, _handle: *mut RsvgHandle,
name: &str, _name: &str,
pbag: &PropertyBag, pbag: &PropertyBag,
) -> Box<XmlHandler> { ) -> Box<XmlHandler> {
Box::new(StyleContext {}) // FIXME: See these:
//
// https://www.w3.org/TR/SVG/styling.html#StyleElementTypeAttribute
// https://www.w3.org/TR/SVG/styling.html#ContentStyleTypeAttribute
//
// If the "type" attribute is not present, we should fallback to the
// "contentStyleType" attribute of the svg element, which in turn
// defaults to "text/css".
//
// See where is_text_css is used to see where we parse the contents
// of the style element.
let mut is_text_css = true;
for (_key, attr, value) in pbag.iter() {
if attr == Attribute::Type {
is_text_css = value == "text/css";
}
}
Box::new(StyleContext {
is_text_css,
text: RefCell::new(String::new()),
})
} }
fn end_element(&self, handle: *mut RsvgHandle, _name: &str) -> Option<Rc<Node>> { fn end_element(&self, handle: *mut RsvgHandle, _name: &str) -> Option<Rc<Node>> {
unimplemented!(); if self.is_text_css {
let text = self.text.borrow();
css::parse_into_handle(handle, &text);
}
None
} }
fn characters(&self, text: &str) { fn characters(&self, text: &str) {
unimplemented!(); self.text.borrow_mut().push_str(text);
}
}
impl StyleContext {
fn empty() -> StyleContext {
StyleContext {
is_text_css: false,
text: RefCell::new(String::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