[librsvg: 24/48] Port <style> element handling to Rust



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]