[librsvg] XmlState: create the CssStyles here, not in the caller



commit baa84a44c219ba66ca17836ef2b67db78dd65bd7
Author: Federico Mena Quintero <federico gnome org>
Date:   Tue Nov 27 09:53:44 2018 -0600

    XmlState: create the CssStyles here, not in the caller
    
    Again, this is to decouple the handle from the result of parsing.  Now
    the CssStyles are returned in steal_result().

 librsvg/rsvg-handle.c        | 10 ++++++----
 librsvg/rsvg-load.c          | 19 +++++++++++++------
 librsvg/rsvg-load.h          |  3 ++-
 librsvg/rsvg-private.h       |  6 ------
 rsvg_internals/src/css.rs    |  2 +-
 rsvg_internals/src/handle.rs | 33 +++-----------------------------
 rsvg_internals/src/lib.rs    |  2 +-
 rsvg_internals/src/xml.rs    | 45 +++++++++++++++++++++++++++++++++-----------
 8 files changed, 60 insertions(+), 60 deletions(-)
---
diff --git a/librsvg/rsvg-handle.c b/librsvg/rsvg-handle.c
index bd37c9c9..b85ef14f 100644
--- a/librsvg/rsvg-handle.c
+++ b/librsvg/rsvg-handle.c
@@ -155,13 +155,12 @@ rsvg_handle_init (RsvgHandle * self)
 
     self->priv->flags = RSVG_HANDLE_FLAGS_NONE;
     self->priv->hstate = RSVG_HANDLE_STATE_START;
-    self->priv->defs = NULL;
     self->priv->dpi_x = rsvg_internal_dpi_x;
     self->priv->dpi_y = rsvg_internal_dpi_y;
 
-    self->priv->css_styles = rsvg_css_styles_new ();
-
     self->priv->tree = NULL;
+    self->priv->defs = NULL;
+    self->priv->css_styles = NULL;
 
     self->priv->cancellable = NULL;
 
@@ -681,6 +680,7 @@ finish_load (RsvgHandle *handle, gboolean was_successful, GError **error)
 {
     RsvgTree *tree = NULL;
     RsvgDefs *defs = NULL;
+    RsvgCssStyles *css_styles = NULL;
 
     g_assert (handle->priv->load != NULL);
     g_assert (handle->priv->tree == NULL);
@@ -688,11 +688,12 @@ finish_load (RsvgHandle *handle, gboolean was_successful, GError **error)
     if (was_successful) {
         g_assert (error == NULL || *error == NULL);
 
-        rsvg_load_steal_result (handle->priv->load, &tree, &defs);
+        rsvg_load_steal_result (handle->priv->load, &tree, &defs, &css_styles);
         was_successful = tree_is_valid (tree, error);
         if (!was_successful) {
             g_clear_pointer (&tree, rsvg_tree_free);
             g_clear_pointer (&defs, rsvg_defs_free);
+            g_clear_pointer (&css_styles, rsvg_css_styles_free);
         }
     }
 
@@ -706,6 +707,7 @@ finish_load (RsvgHandle *handle, gboolean was_successful, GError **error)
     g_clear_pointer (&handle->priv->load, rsvg_load_free);
     handle->priv->tree = tree;
     handle->priv->defs = defs;
+    handle->priv->css_styles = css_styles;
 
     return was_successful;
 }
diff --git a/librsvg/rsvg-load.c b/librsvg/rsvg-load.c
index 8d2b806f..a4944a16 100644
--- a/librsvg/rsvg-load.c
+++ b/librsvg/rsvg-load.c
@@ -54,7 +54,8 @@ extern RsvgXmlState *rsvg_xml_state_new ();
 extern void rsvg_xml_state_free (RsvgXmlState *xml);
 extern void rsvg_xml_state_steal_result(RsvgXmlState *xml,
                                         RsvgTree **out_tree,
-                                        RsvgDefs **out_defs);
+                                        RsvgDefs **out_defs,
+                                        RsvgCssStyles **out_css_styles);
 extern void rsvg_xml_state_start_element(RsvgXmlState *xml, RsvgHandle *handle, const char *name, 
RsvgPropertyBag atts);
 extern void rsvg_xml_state_end_element(RsvgXmlState *xml, RsvgHandle *handle, const char *name);
 extern void rsvg_xml_state_characters(RsvgXmlState *xml, const char *unterminated_text, gsize len);
@@ -67,6 +68,11 @@ extern void rsvg_xml_state_entity_insert(RsvgXmlState *xml,
                                          const char *entity_name,
                                          xmlEntityPtr entity);
 
+extern void rsvg_xml_state_load_css_from_href(RsvgXmlState *xml,
+                                              RsvgHandle *handle,
+                                              const char *href);
+
+
 /* Holds the XML parsing state */
 typedef struct {
     xmlParserCtxtPtr ctxt;
@@ -146,9 +152,10 @@ rsvg_load_free (RsvgLoad *load)
 void
 rsvg_load_steal_result (RsvgLoad *load,
                         RsvgTree **out_tree,
-                        RsvgDefs **out_defs)
+                        RsvgDefs **out_defs,
+                        RsvgCssStyles **out_css_styles)
 {
-    rsvg_xml_state_steal_result (load->xml.rust_state, out_tree, out_defs);
+    rsvg_xml_state_steal_result (load->xml.rust_state, out_tree, out_defs, out_css_styles);
 }
 
 static void
@@ -548,9 +555,9 @@ sax_processing_instruction_cb (void *user_data, const xmlChar * target, const xm
                 && type && strcmp (type, "text/css") == 0
                 && href)
             {
-                rsvg_handle_load_css (load->handle,
-                                      rsvg_handle_get_css_styles(load->handle),
-                                      href);
+                rsvg_xml_state_load_css_from_href (load->xml.rust_state,
+                                                   load->handle,
+                                                   href);
             }
 
             rsvg_property_bag_free (atts);
diff --git a/librsvg/rsvg-load.h b/librsvg/rsvg-load.h
index 6c62cdbd..4b803cfb 100644
--- a/librsvg/rsvg-load.h
+++ b/librsvg/rsvg-load.h
@@ -37,7 +37,8 @@ gboolean rsvg_load_handle_xml_xinclude (RsvgHandle *handle, const char *url);
 G_GNUC_INTERNAL
 void rsvg_load_steal_result (RsvgLoad *load,
                              RsvgTree **out_tree,
-                             RsvgDefs **out_defs);
+                             RsvgDefs **out_defs,
+                             RsvgCssStyles **out_css_styles);
 
 G_GNUC_INTERNAL
 gboolean rsvg_load_write (RsvgLoad *load, const guchar *buf, gsize count, GError **error) 
G_GNUC_WARN_UNUSED_RESULT;
diff --git a/librsvg/rsvg-private.h b/librsvg/rsvg-private.h
index 55c43826..c439dca8 100644
--- a/librsvg/rsvg-private.h
+++ b/librsvg/rsvg-private.h
@@ -100,9 +100,7 @@ struct RsvgHandlePrivate {
     GDestroyNotify user_data_destroy;
 
     RsvgTree *tree;
-
     RsvgDefs *defs; /* lookup table for nodes that have an id="foo" attribute */
-
     RsvgCssStyles *css_styles;
 
     GCancellable *cancellable;
@@ -255,10 +253,6 @@ RsvgHandleRust *rsvg_handle_get_rust (RsvgHandle *handle);
 G_GNUC_INTERNAL
 RsvgCssStyles *rsvg_handle_get_css_styles (RsvgHandle *handle);
 
-/* Implemented in rsvg_internals/src/handle.rs */
-G_GNUC_INTERNAL
-void rsvg_handle_load_css(RsvgHandle *handle, RsvgCssStyles *css_styles, const char *href);
-
 /* Implemented in rsvg_internals/src/handle.rs */
 G_GNUC_INTERNAL
 RsvgHandleRust *rsvg_handle_rust_new (void);
diff --git a/rsvg_internals/src/css.rs b/rsvg_internals/src/css.rs
index b180580c..efedb35e 100644
--- a/rsvg_internals/src/css.rs
+++ b/rsvg_internals/src/css.rs
@@ -29,7 +29,7 @@ pub struct CssStyles {
 }
 
 impl CssStyles {
-    fn new() -> CssStyles {
+    pub fn new() -> CssStyles {
         CssStyles {
             selectors_to_declarations: HashMap::new(),
         }
diff --git a/rsvg_internals/src/handle.rs b/rsvg_internals/src/handle.rs
index ee4de245..8246013b 100644
--- a/rsvg_internals/src/handle.rs
+++ b/rsvg_internals/src/handle.rs
@@ -13,12 +13,11 @@ use libc;
 use url::Url;
 
 use allowed_url::AllowedUrl;
-use css::{self, CssStyles, RsvgCssStyles};
+use css::{self, CssStyles};
 use defs::{Defs, RsvgDefs};
 use error::{set_gerror, LoadingError, RsvgError};
 use io;
 use surface_utils::shared_surface::SharedImageSurface;
-use util::utf8_cstr;
 
 pub enum RsvgHandle {}
 
@@ -45,8 +44,6 @@ extern "C" {
         href: *const libc::c_char,
     ) -> *const RsvgHandle;
 
-    fn rsvg_handle_get_css_styles(handle: *const RsvgHandle) -> *mut RsvgCssStyles;
-
     fn _rsvg_handle_acquire_stream(
         handle: *mut RsvgHandle,
         href: *const libc::c_char,
@@ -90,14 +87,6 @@ pub fn get_base_url<'a>(handle: *const RsvgHandle) -> Ref<'a, Option<Url>> {
     rhandle.base_url.borrow()
 }
 
-pub fn get_css_styles<'a>(handle: *const RsvgHandle) -> &'a CssStyles {
-    unsafe { &*(rsvg_handle_get_css_styles(handle) as *const CssStyles) }
-}
-
-pub fn get_css_styles_mut<'a>(handle: *const RsvgHandle) -> &'a mut CssStyles {
-    unsafe { &mut *(rsvg_handle_get_css_styles(handle) as *mut CssStyles) }
-}
-
 fn get_cancellable<'a>(handle: *const RsvgHandle) -> Option<Cancellable> {
     unsafe { from_glib_borrow(rsvg_handle_get_cancellable(handle)) }
 }
@@ -194,6 +183,8 @@ pub fn load_xml_xinclude(handle: *mut RsvgHandle, href: &str) -> bool {
     unsafe { from_glib(rsvg_load_handle_xml_xinclude(handle, href.to_glib_none().0)) }
 }
 
+// This function just slurps CSS data from a possibly-relative href
+// and parses it.  We'll move it to a better place in the end.
 pub fn load_css(css_styles: &mut CssStyles, handle: *mut RsvgHandle, href: &str) {
     if let Ok(data) = acquire_data(handle, href) {
         let BinaryData {
@@ -223,24 +214,6 @@ pub fn load_css(css_styles: &mut CssStyles, handle: *mut RsvgHandle, href: &str)
     }
 }
 
-// This function just slurps CSS data from a possibly-relative href
-// and parses it.  We'll move it to a better place in the end.
-#[no_mangle]
-pub unsafe extern "C" fn rsvg_handle_load_css(
-    handle: *mut RsvgHandle,
-    css_styles: *mut RsvgCssStyles,
-    href: *const libc::c_char,
-) {
-    assert!(!handle.is_null());
-    assert!(!css_styles.is_null());
-    assert!(!href.is_null());
-
-    let css_styles = &mut *(css_styles as *mut CssStyles);
-
-    let href = utf8_cstr(href);
-    load_css(css_styles, handle, href);
-}
-
 #[no_mangle]
 pub unsafe extern "C" fn rsvg_handle_rust_new() -> *mut RsvgHandleRust {
     Box::into_raw(Box::new(Handle::new())) as *mut RsvgHandleRust
diff --git a/rsvg_internals/src/lib.rs b/rsvg_internals/src/lib.rs
index fe5850c0..9149bdeb 100644
--- a/rsvg_internals/src/lib.rs
+++ b/rsvg_internals/src/lib.rs
@@ -49,7 +49,6 @@ pub use drawing_ctx::{
 pub use handle::{
     rsvg_handle_acquire_data,
     rsvg_handle_acquire_stream,
-    rsvg_handle_load_css,
     rsvg_handle_rust_free,
     rsvg_handle_rust_get_base_gfile,
     rsvg_handle_rust_new,
@@ -85,6 +84,7 @@ pub use xml::{
     rsvg_xml_state_entity_lookup,
     rsvg_xml_state_error,
     rsvg_xml_state_free,
+    rsvg_xml_state_load_css_from_href,
     rsvg_xml_state_new,
     rsvg_xml_state_start_element,
     rsvg_xml_state_steal_result,
diff --git a/rsvg_internals/src/xml.rs b/rsvg_internals/src/xml.rs
index 5fe53900..7f0452f9 100644
--- a/rsvg_internals/src/xml.rs
+++ b/rsvg_internals/src/xml.rs
@@ -11,7 +11,7 @@ use std::str;
 
 use attributes::Attribute;
 use create_node::create_node_and_register_id;
-use css;
+use css::{self, CssStyles, RsvgCssStyles};
 use defs::{Defs, RsvgDefs};
 use handle::{self, RsvgHandle};
 use node::{node_new, Node, NodeType};
@@ -96,6 +96,7 @@ extern "C" {
 struct XmlState {
     tree: Option<Box<Tree>>,
     defs: Option<Defs>,
+    css_styles: Option<CssStyles>,
     context: Context,
     context_stack: Vec<Context>,
     current_node: Option<Rc<Node>>,
@@ -120,6 +121,7 @@ impl XmlState {
         XmlState {
             tree: None,
             defs: Some(Defs::new()),
+            css_styles: Some(CssStyles::new()),
             context: Context::empty(),
             context_stack: Vec::new(),
             current_node: None,
@@ -135,8 +137,12 @@ impl XmlState {
         self.tree = Some(Box::new(Tree::new(root)));
     }
 
-    pub fn steal_result(&mut self) -> (Option<Box<Tree>>, Box<Defs>) {
-        (self.tree.take(), Box::new(self.defs.take().unwrap()))
+    pub fn steal_result(&mut self) -> (Option<Box<Tree>>, Box<Defs>, Box<CssStyles>) {
+        (
+            self.tree.take(),
+            Box::new(self.defs.take().unwrap()),
+            Box::new(self.css_styles.take().unwrap()),
+        )
     }
 
     fn push_context(&mut self, ctx: Context) {
@@ -258,17 +264,14 @@ impl XmlState {
         // here, not during element creation.
         if node.get_type() == NodeType::Svg {
             node.with_impl(|svg: &NodeSvg| {
-                let css_styles = handle::get_css_styles(handle);
-                svg.set_delayed_style(&node, css_styles);
+                svg.set_delayed_style(&node, self.css_styles.as_ref().unwrap());
             });
         }
 
         if node.get_type() == NodeType::Style {
             let css_data = node.with_impl(|style: &NodeStyle| style.get_css(&node));
 
-            let css_styles = handle::get_css_styles_mut(handle);
-
-            css::parse_into_css_styles(css_styles, handle, &css_data);
+            css::parse_into_css_styles(self.css_styles.as_mut().unwrap(), handle, &css_data);
         }
 
         self.current_node = node.get_parent();
@@ -319,8 +322,7 @@ impl XmlState {
         // The "svg" node is special; it will parse its style attributes
         // until the end, in standard_element_end().
         if new_node.get_type() != NodeType::Svg {
-            let css_styles = handle::get_css_styles(handle);
-            new_node.set_style(css_styles, pbag);
+            new_node.set_style(self.css_styles.as_ref().unwrap(), pbag);
         }
 
         new_node.set_overridden_properties();
@@ -517,20 +519,24 @@ pub unsafe extern "C" fn rsvg_xml_state_steal_result(
     xml: *mut RsvgXmlState,
     out_tree: *mut *mut RsvgTree,
     out_defs: *mut *mut RsvgDefs,
+    out_css_styles: *mut *mut RsvgCssStyles,
 ) {
     assert!(!xml.is_null());
     assert!(!out_tree.is_null());
     assert!(!out_defs.is_null());
+    assert!(!out_css_styles.is_null());
 
     let xml = &mut *(xml as *mut XmlState);
 
-    let (tree, defs) = xml.steal_result();
+    let (tree, defs, css_styles) = xml.steal_result();
 
     *out_tree = tree
         .map(|tree| Box::into_raw(tree) as *mut RsvgTree)
         .unwrap_or(ptr::null_mut());
 
     *out_defs = Box::into_raw(defs) as *mut RsvgDefs;
+
+    *out_css_styles = Box::into_raw(css_styles) as *mut RsvgCssStyles;
 }
 
 #[no_mangle]
@@ -629,3 +635,20 @@ pub unsafe extern "C" fn rsvg_xml_state_entity_insert(
 
     xml.entity_insert(entity_name, entity);
 }
+
+#[no_mangle]
+pub unsafe extern "C" fn rsvg_xml_state_load_css_from_href(
+    xml: *mut RsvgXmlState,
+    handle: *mut RsvgHandle,
+    href: *const libc::c_char,
+) {
+    assert!(!xml.is_null());
+    let xml = &mut *(xml as *mut XmlState);
+
+    assert!(!handle.is_null());
+    assert!(!href.is_null());
+
+    let href: String = from_glib_none(href);
+
+    handle::load_css(xml.css_styles.as_mut().unwrap(), handle, &href);
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]