[librsvg] state: pull important_styles set out of State



commit 50899fbf1a7c66ffa2aafea57319d42610daaaeb
Author: Paolo Borelli <pborelli gnome org>
Date:   Fri Jan 18 16:27:31 2019 +0100

    state: pull important_styles set out of State

 rsvg_internals/src/css.rs   | 10 ++++++++--
 rsvg_internals/src/node.rs  | 27 ++++++++++++++++++---------
 rsvg_internals/src/state.rs | 16 +++++++++-------
 3 files changed, 35 insertions(+), 18 deletions(-)
---
diff --git a/rsvg_internals/src/css.rs b/rsvg_internals/src/css.rs
index d0cbb4e4..e4a0e03c 100644
--- a/rsvg_internals/src/css.rs
+++ b/rsvg_internals/src/css.rs
@@ -1,5 +1,5 @@
 use std::collections::hash_map::Entry;
-use std::collections::HashMap;
+use std::collections::{HashMap, HashSet};
 use std::ptr;
 use std::str::{self, FromStr};
 
@@ -127,7 +127,12 @@ impl CssStyles {
         }
     }
 
-    pub fn lookup_apply(&self, selector: &str, state: &mut State) -> bool {
+    pub fn lookup_apply(
+        &self,
+        selector: &str,
+        state: &mut State,
+        important_styles: &mut HashSet<Attribute>,
+    ) -> bool {
         if let Some(decl_list) = self.selectors_to_declarations.get(selector) {
             for (prop_name, declaration) in decl_list.iter() {
                 if let Ok(attr) = Attribute::from_str(prop_name) {
@@ -136,6 +141,7 @@ impl CssStyles {
                         attr,
                         &declaration.prop_value,
                         declaration.important,
+                        important_styles,
                     );
                 }
             }
diff --git a/rsvg_internals/src/node.rs b/rsvg_internals/src/node.rs
index 6c0092b6..aa85350d 100644
--- a/rsvg_internals/src/node.rs
+++ b/rsvg_internals/src/node.rs
@@ -1,6 +1,7 @@
 use cairo::{Matrix, MatrixTrait};
 use downcast_rs::*;
 use std::cell::{Cell, Ref, RefCell};
+use std::collections::HashSet;
 use std::rc::{Rc, Weak};
 
 use attributes::Attribute;
@@ -143,6 +144,7 @@ pub struct NodeData {
     id: Option<String>,    // id attribute from XML element
     class: Option<String>, // class attribute from XML element
     state: RefCell<State>,
+    important_styles: RefCell<HashSet<Attribute>>,
     result: RefCell<NodeResult>,
     transform: Cell<Matrix>,
     values: RefCell<ComputedValues>,
@@ -282,6 +284,7 @@ impl Node {
             id: id.map(str::to_string),
             class: class.map(str::to_string),
             state: RefCell::new(State::new()),
+            important_styles: Default::default(),
             transform: Cell::new(Matrix::identity()),
             result: RefCell::new(Ok(())),
             values: RefCell::new(ComputedValues::default()),
@@ -452,12 +455,13 @@ impl Node {
 
         let element_name = self.get_type().element_name();
         let mut state = self.data.state.borrow_mut();
+        let mut important_styles = self.data.important_styles.borrow_mut();
 
         // *
-        css_styles.lookup_apply("*", &mut state);
+        css_styles.lookup_apply("*", &mut state, &mut important_styles);
 
         // tag
-        css_styles.lookup_apply(element_name, &mut state);
+        css_styles.lookup_apply(element_name, &mut state, &mut important_styles);
 
         if let Some(klazz) = self.get_class() {
             for cls in klazz.split_whitespace() {
@@ -467,23 +471,26 @@ impl Node {
                     // tag.class#id
                     if let Some(id) = self.get_id() {
                         let target = format!("{}.{}#{}", element_name, cls, id);
-                        found = found || css_styles.lookup_apply(&target, &mut state);
+                        found = found
+                            || css_styles.lookup_apply(&target, &mut state, &mut important_styles);
                     }
 
                     // .class#id
                     if let Some(id) = self.get_id() {
                         let target = format!(".{}#{}", cls, id);
-                        found = found || css_styles.lookup_apply(&target, &mut state);
+                        found = found
+                            || css_styles.lookup_apply(&target, &mut state, &mut important_styles);
                     }
 
                     // tag.class
                     let target = format!("{}.{}", element_name, cls);
-                    found = found || css_styles.lookup_apply(&target, &mut state);
+                    found = found
+                        || css_styles.lookup_apply(&target, &mut state, &mut important_styles);
 
                     if !found {
                         // didn't find anything more specific, just apply the class style
                         let target = format!(".{}", cls);
-                        css_styles.lookup_apply(&target, &mut state);
+                        css_styles.lookup_apply(&target, &mut state, &mut important_styles);
                     }
                 }
             }
@@ -492,21 +499,23 @@ impl Node {
         if let Some(id) = self.get_id() {
             // id
             let target = format!("#{}", id);
-            css_styles.lookup_apply(&target, &mut state);
+            css_styles.lookup_apply(&target, &mut state, &mut important_styles);
 
             // tag#id
             let target = format!("{}#{}", element_name, id);
-            css_styles.lookup_apply(&target, &mut state);
+            css_styles.lookup_apply(&target, &mut state, &mut important_styles);
         }
     }
 
     /// Looks for the "style" attribute in the pbag, and applies CSS styles from it
     fn set_style_attribute(&self, pbag: &PropertyBag<'_>) {
+        let mut important_styles = self.data.important_styles.borrow_mut();
+
         for (attr, value) in pbag.iter() {
             match attr {
                 Attribute::Style => {
                     let mut state = self.data.state.borrow_mut();
-                    if let Err(e) = state.parse_style_declarations(value) {
+                    if let Err(e) = state.parse_style_declarations(value, &mut important_styles) {
                         self.set_error(e);
                         break;
                     }
diff --git a/rsvg_internals/src/state.rs b/rsvg_internals/src/state.rs
index c38ee07e..c9ee9abd 100644
--- a/rsvg_internals/src/state.rs
+++ b/rsvg_internals/src/state.rs
@@ -1,5 +1,4 @@
 use cssparser::{self, Parser, Token};
-use std::cell::RefCell;
 use std::collections::HashSet;
 use std::str::FromStr;
 
@@ -82,7 +81,6 @@ where
 
 pub struct State {
     pub values: SpecifiedValues,
-    important_styles: RefCell<HashSet<Attribute>>,
 }
 
 #[derive(Default, Clone)]
@@ -274,7 +272,6 @@ impl State {
     pub fn new() -> State {
         State {
             values: Default::default(),
-            important_styles: Default::default(),
         }
     }
 
@@ -534,19 +531,24 @@ impl State {
         attr: Attribute,
         value: &str,
         important: bool,
+        important_styles: &mut HashSet<Attribute>,
     ) -> Result<(), NodeError> {
-        if !important && self.important_styles.borrow().contains(&attr) {
+        if !important && important_styles.contains(&attr) {
             return Ok(());
         }
 
         if important {
-            self.important_styles.borrow_mut().insert(attr);
+            important_styles.insert(attr);
         }
 
         self.parse_attribute_pair(attr, value, true)
     }
 
-    pub fn parse_style_declarations(&mut self, declarations: &str) -> Result<(), NodeError> {
+    pub fn parse_style_declarations(
+        &mut self,
+        declarations: &str,
+        important_styles: &mut HashSet<Attribute>,
+    ) -> Result<(), NodeError> {
         // Split an attribute value like style="foo: bar; baz: beep;" into
         // individual CSS declarations ("foo: bar" and "baz: beep") and
         // set them onto the state struct.
@@ -577,7 +579,7 @@ impl State {
                     };
 
                     if let Ok(attr) = Attribute::from_str(prop_name) {
-                        self.parse_style_pair(attr, value, important)?;
+                        self.parse_style_pair(attr, value, important, important_styles)?;
                     }
                     // else unknown property name; ignore
                 }


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