[librsvg: 24/48] Port <style> element handling to Rust
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 24/48] Port <style> element handling to Rust
- Date: Sat, 17 Nov 2018 10:22:02 +0000 (UTC)
commit 02610405a0fe09558d058bd17357ae4084c7e7d3
Author: Federico Mena Quintero <federico gnome org>
Date: Fri Sep 7 16:16:48 2018 -0500
Port <style> element handling to Rust
librsvg/rsvg-load.c | 92 -----------------------------------------------
rsvg_internals/src/css.rs | 2 +-
rsvg_internals/src/xml.rs | 60 ++++++++++++++++++++++++++-----
3 files changed, 53 insertions(+), 101 deletions(-)
---
diff --git a/librsvg/rsvg-load.c b/librsvg/rsvg-load.c
index 52e75ebb..48754571 100644
--- a/librsvg/rsvg-load.c
+++ b/librsvg/rsvg-load.c
@@ -95,14 +95,6 @@ struct RsvgSaxHandler {
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);
RsvgLoad *
@@ -170,90 +162,6 @@ rsvg_load_steal_tree (RsvgLoad *load)
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 */
typedef struct _RsvgSaxHandlerXinclude {
diff --git a/rsvg_internals/src/css.rs b/rsvg_internals/src/css.rs
index d4ef1df1..ba4c4657 100644
--- a/rsvg_internals/src/css.rs
+++ b/rsvg_internals/src/css.rs
@@ -86,7 +86,7 @@ struct DocHandlerData {
selector: *mut CRSelector,
}
-fn parse_into_handle(handle: *mut RsvgHandle, buf: &str) {
+pub fn parse_into_handle(handle: *mut RsvgHandle, buf: &str) {
unsafe {
let handler_data = DocHandlerData {
handle,
diff --git a/rsvg_internals/src/xml.rs b/rsvg_internals/src/xml.rs
index 1d88e378..ffbd7af7 100644
--- a/rsvg_internals/src/xml.rs
+++ b/rsvg_internals/src/xml.rs
@@ -1,9 +1,12 @@
use libc;
use std;
+use std::cell::RefCell;
use std::ptr;
use std::rc::Rc;
use std::str;
+use attributes::Attribute;
+use css;
use handle::{self, RsvgHandle};
use load::rsvg_load_new_node;
use node::{node_new, Node, NodeType};
@@ -55,7 +58,8 @@ impl XmlHandler for NodeCreationContext {
pbag: &PropertyBag,
) -> Box<XmlHandler> {
if name == "style" {
- unimplemented!();
+ let ctx = StyleContext::empty();
+ StyleContext::start_element(&ctx, parent, handle, name, pbag)
} else {
let node = self.create_node(parent, handle, name, pbag);
@@ -145,25 +149,65 @@ impl NodeCreationContext {
}
/// 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 {
fn start_element(
&self,
- parent: Option<&Rc<Node>>,
- handle: *mut RsvgHandle,
- name: &str,
+ _parent: Option<&Rc<Node>>,
+ _handle: *mut RsvgHandle,
+ _name: &str,
pbag: &PropertyBag,
) -> 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>> {
- unimplemented!();
+ if self.is_text_css {
+ let text = self.text.borrow();
+ css::parse_into_handle(handle, &text);
+ }
+
+ None
}
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()),
+ }
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]