[librsvg: 3/12] state: move conditional processing to rust
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 3/12] state: move conditional processing to rust
- Date: Tue, 24 Apr 2018 23:15:19 +0000 (UTC)
commit a6f72224dcc282c4679d05433cde12fef9d2184f
Author: Paolo Borelli <pborelli gnome org>
Date: Sat Apr 21 15:33:08 2018 +0200
state: move conditional processing to rust
Note that the state cond now is a plain bool, not an Option<bool>
even if the C code had a has_cond field. As far as I can see there
is no reason to distinguish between cond being set to true and cond
being unset.
librsvg/rsvg-styles.c | 69 +++------------------------------------
librsvg/rsvg-styles.h | 9 ------
rsvg_internals/src/cond.rs | 49 ++--------------------------
rsvg_internals/src/lib.rs | 7 +---
rsvg_internals/src/state.rs | 72 ++++++++++++++++++++++++++++++++++-------
rsvg_internals/src/structure.rs | 4 +--
rsvg_internals/src/text.rs | 2 +-
7 files changed, 70 insertions(+), 142 deletions(-)
---
diff --git a/librsvg/rsvg-styles.c b/librsvg/rsvg-styles.c
index 4e4d5ada..d5c860b5 100644
--- a/librsvg/rsvg-styles.c
+++ b/librsvg/rsvg-styles.c
@@ -58,6 +58,9 @@ extern gboolean rsvg_state_rust_parse_style_pair(State *state, RsvgAttribute att
extern void rsvg_state_rust_inherit_run(State *dst, State *src, InheritanceFunction inherit_fn, gboolean
inherituninheritables);
+extern gboolean rsvg_state_parse_conditional_processing_attributes (RsvgState *state, RsvgPropertyBag *pbag)
+ G_GNUC_WARN_UNUSED_RESULT;
+
typedef struct _StyleValueData {
gchar *value;
gboolean important;
@@ -113,8 +116,6 @@ rsvg_state_init (RsvgState * state)
state->flood_color = 0;
state->flood_opacity = 255;
- state->cond_true = TRUE;
-
state->has_current_color = FALSE;
state->has_flood_color = FALSE;
state->has_flood_opacity = FALSE;
@@ -122,7 +123,6 @@ rsvg_state_init (RsvgState * state)
state->has_fill_opacity = FALSE;
state->has_stroke_server = FALSE;
state->has_stroke_opacity = FALSE;
- state->has_cond = FALSE;
state->has_stop_color = FALSE;
state->has_stop_opacity = FALSE;
@@ -246,8 +246,6 @@ rsvg_state_inherit_run (RsvgState * dst, const RsvgState * src,
dst->stop_opacity = src->stop_opacity;
}
}
- if (function (dst->has_cond, src->has_cond))
- dst->cond_true = src->cond_true;
rsvg_state_rust_inherit_run (dst->state_rust, src->state_rust, function, inherituninheritables);
@@ -533,53 +531,6 @@ rsvg_parse_style_pair (RsvgState *state,
return success;
}
-/* returns TRUE if this element should be processed according to <switch> semantics
- http://www.w3.org/TR/SVG/struct.html#SwitchElement */
-static void
-rsvg_parse_conditional_processing_attributes (RsvgState * state, RsvgPropertyBag * atts)
-{
- gboolean required_features_ok = TRUE;
- gboolean required_extensions_ok = TRUE;
- gboolean system_language_ok = TRUE;
- gboolean has_cond = FALSE;
-
- RsvgPropertyBagIter *iter;
- const char *key;
- RsvgAttribute attr;
- const char *value;
-
- iter = rsvg_property_bag_iter_begin (atts);
-
- while (rsvg_property_bag_iter_next (iter, &key, &attr, &value)) {
- switch (attr) {
- case RSVG_ATTRIBUTE_REQUIRED_FEATURES:
- required_features_ok = rsvg_cond_check_required_features (value);
- has_cond = TRUE;
- break;
-
- case RSVG_ATTRIBUTE_REQUIRED_EXTENSIONS:
- required_extensions_ok = rsvg_cond_check_required_extensions (value);
- has_cond = TRUE;
- break;
-
- case RSVG_ATTRIBUTE_SYSTEM_LANGUAGE:
- system_language_ok = rsvg_cond_check_system_language (value);
- has_cond = TRUE;
- break;
-
- default:
- break;
- }
- }
-
- rsvg_property_bag_iter_end (iter);
-
- if (has_cond) {
- state->cond_true = required_features_ok && required_extensions_ok && system_language_ok;
- state->has_cond = TRUE;
- }
-}
-
/* take a pair of the form (fill="#ff00ff") and parse it as a style */
void
rsvg_parse_presentation_attributes (RsvgState * state, RsvgPropertyBag * atts)
@@ -988,7 +939,7 @@ rsvg_parse_style_attrs (RsvgHandle *handle,
rsvg_parse_presentation_attributes (state, atts);
/* TODO: i'm not sure it should reside here */
- rsvg_parse_conditional_processing_attributes (state, atts);
+ success = success && rsvg_state_parse_conditional_processing_attributes (state, atts);
/* Try to properly support all of the following, including inheritance:
* *
@@ -1157,18 +1108,6 @@ rsvg_state_get_stroke_opacity (RsvgState *state)
return state->stroke_opacity;
}
-gboolean
-rsvg_state_get_cond_true (RsvgState *state)
-{
- return state->cond_true;
-}
-
-void
-rsvg_state_set_cond_true (RsvgState *state, gboolean cond_true)
-{
- state->cond_true = cond_true;
-}
-
RsvgCssColorSpec *
rsvg_state_get_stop_color (RsvgState *state)
{
diff --git a/librsvg/rsvg-styles.h b/librsvg/rsvg-styles.h
index 4f48d341..7e426203 100644
--- a/librsvg/rsvg-styles.h
+++ b/librsvg/rsvg-styles.h
@@ -66,9 +66,6 @@ struct _RsvgState {
RsvgOpacitySpec stop_opacity;
gboolean has_stop_opacity;
- gboolean has_cond;
- gboolean cond_true;
-
guint32 current_color;
gboolean has_current_color;
@@ -148,12 +145,6 @@ RsvgPaintServer *rsvg_state_get_stroke (RsvgState *state);
G_GNUC_INTERNAL
guint8 rsvg_state_get_stroke_opacity (RsvgState *state);
-G_GNUC_INTERNAL
-gboolean rsvg_state_get_cond_true (RsvgState *state);
-
-G_GNUC_INTERNAL
-void rsvg_state_set_cond_true (RsvgState *state, gboolean cond_true);
-
G_GNUC_INTERNAL
RsvgCssColorSpec *rsvg_state_get_stop_color (RsvgState *state);
diff --git a/rsvg_internals/src/cond.rs b/rsvg_internals/src/cond.rs
index 6b79c2d9..5c30a95a 100644
--- a/rsvg_internals/src/cond.rs
+++ b/rsvg_internals/src/cond.rs
@@ -1,22 +1,15 @@
-use glib;
-use glib_sys;
-use libc;
-
use error::*;
use parsers::Parse;
use std::marker::PhantomData;
-use util::utf8_cstr;
#[allow(unused_imports)]
use std::ascii::AsciiExt;
-use self::glib::translate::*;
-
// No extensions at the moment.
static IMPLEMENTED_EXTENSIONS: &[&str] = &[];
#[derive(Debug, PartialEq)]
-struct RequiredExtensions(bool);
+pub struct RequiredExtensions(pub bool);
impl Parse for RequiredExtensions {
type Data = ();
@@ -58,7 +51,7 @@ static IMPLEMENTED_FEATURES: &[&str] = &[
];
#[derive(Debug, PartialEq)]
-struct RequiredFeatures(bool);
+pub struct RequiredFeatures(pub bool);
impl Parse for RequiredFeatures {
type Data = ();
@@ -75,7 +68,7 @@ impl Parse for RequiredFeatures {
}
#[derive(Debug, PartialEq)]
-struct SystemLanguage<'a>(bool, PhantomData<&'a i8>);
+pub struct SystemLanguage<'a>(pub bool, pub PhantomData<&'a i8>);
impl<'a> Parse for SystemLanguage<'a> {
type Data = &'a [String];
@@ -106,42 +99,6 @@ impl<'a> Parse for SystemLanguage<'a> {
}
}
-#[no_mangle]
-pub extern "C" fn rsvg_cond_check_required_extensions(
- raw_value: *const libc::c_char,
-) -> glib_sys::gboolean {
- let value = unsafe { utf8_cstr(raw_value) };
-
- match RequiredExtensions::parse(value, ()) {
- Ok(RequiredExtensions(res)) => res.to_glib(),
- Err(_) => false.to_glib(),
- }
-}
-
-#[no_mangle]
-pub extern "C" fn rsvg_cond_check_required_features(
- raw_value: *const libc::c_char,
-) -> glib_sys::gboolean {
- let value = unsafe { utf8_cstr(raw_value) };
-
- match RequiredFeatures::parse(value, ()) {
- Ok(RequiredFeatures(res)) => res.to_glib(),
- Err(_) => false.to_glib(),
- }
-}
-
-#[no_mangle]
-pub extern "C" fn rsvg_cond_check_system_language(
- raw_value: *const libc::c_char,
-) -> glib_sys::gboolean {
- let value = unsafe { utf8_cstr(raw_value) };
-
- match SystemLanguage::parse(value, &glib::get_language_names()) {
- Ok(SystemLanguage(res, _)) => res.to_glib(),
- Err(_) => false.to_glib(),
- }
-}
-
#[cfg(test)]
mod tests {
use super::*;
diff --git a/rsvg_internals/src/lib.rs b/rsvg_internals/src/lib.rs
index 372b430d..0c3035ff 100644
--- a/rsvg_internals/src/lib.rs
+++ b/rsvg_internals/src/lib.rs
@@ -31,12 +31,6 @@ pub use cnode::{rsvg_rust_cnode_get_impl, rsvg_rust_cnode_new};
pub use color::{rsvg_css_parse_color, AllowCurrentColor, AllowInherit, ColorKind, ColorSpec};
-pub use cond::{
- rsvg_cond_check_required_extensions,
- rsvg_cond_check_required_features,
- rsvg_cond_check_system_language,
-};
-
pub use draw::rsvg_cairo_add_clipping_rect;
pub use drawing_ctx::{rsvg_drawing_ctx_state_pop, rsvg_drawing_ctx_state_push};
@@ -119,6 +113,7 @@ pub use shapes::{
pub use state::{
rsvg_state_is_visible,
+ rsvg_state_parse_conditional_processing_attributes,
rsvg_state_reconstruct,
rsvg_state_rust_clone,
rsvg_state_rust_contains_important_style,
diff --git a/rsvg_internals/src/state.rs b/rsvg_internals/src/state.rs
index e6c4ca0c..7b977420 100644
--- a/rsvg_internals/src/state.rs
+++ b/rsvg_internals/src/state.rs
@@ -1,4 +1,5 @@
use cairo::{self, MatrixTrait};
+use glib;
use glib::translate::*;
use glib_sys;
use libc;
@@ -8,6 +9,7 @@ use std::ptr;
use attributes::Attribute;
use color::{Color, ColorSpec};
+use cond::{RequiredExtensions, RequiredFeatures, SystemLanguage};
use error::*;
use iri::IRI;
use length::{Dasharray, LengthDir, RsvgLength};
@@ -15,6 +17,7 @@ use node::RsvgNode;
use opacity::{Opacity, OpacitySpec};
use paint_server::PaintServer;
use parsers::Parse;
+use property_bag::PropertyBag;
use property_macros::Property;
use util::utf8_cstr;
@@ -75,6 +78,7 @@ pub struct State {
pub xml_space: Option<XmlSpace>,
important_styles: RefCell<HashSet<String>>,
+ cond: bool,
}
impl State {
@@ -121,6 +125,7 @@ impl State {
xml_space: Default::default(),
important_styles: Default::default(),
+ cond: true,
}
}
@@ -304,6 +309,34 @@ impl State {
Ok(())
}
+
+ pub fn parse_conditional_processing_attributes(
+ &mut self,
+ pbag: &PropertyBag,
+ ) -> Result<(), AttributeError> {
+ for (_key, attr, value) in pbag.iter() {
+ match attr {
+ Attribute::RequiredExtensions if self.cond => {
+ self.cond =
+ RequiredExtensions::parse(value, ()).map(|RequiredExtensions(res)| res)?;
+ }
+
+ Attribute::RequiredFeatures if self.cond => {
+ self.cond =
+ RequiredFeatures::parse(value, ()).map(|RequiredFeatures(res)| res)?;
+ }
+
+ Attribute::SystemLanguage if self.cond => {
+ self.cond = SystemLanguage::parse(value, &glib::get_language_names())
+ .map(|SystemLanguage(res, _)| res)?;
+ }
+
+ _ => {}
+ }
+ }
+
+ Ok(())
+ }
}
// Parses the `value` for the type `T` of the property, including `inherit` values.
@@ -329,8 +362,6 @@ extern "C" {
fn rsvg_state_reinit(state: *mut RsvgState);
fn rsvg_state_clone(state: *mut RsvgState, src: *const RsvgState);
fn rsvg_state_parent(state: *const RsvgState) -> *mut RsvgState;
- fn rsvg_state_get_cond_true(state: *const RsvgState) -> glib_sys::gboolean;
- fn rsvg_state_set_cond_true(state: *const RsvgState, cond_true: glib_sys::gboolean);
fn rsvg_state_get_stop_color(state: *const RsvgState) -> *const ColorSpec;
fn rsvg_state_get_stop_opacity(state: *const RsvgState) -> *const OpacitySpec;
fn rsvg_state_get_current_color(state: *const RsvgState) -> u32;
@@ -420,16 +451,6 @@ pub fn text_gravity_is_vertical(state: *const RsvgState) -> bool {
}
}
-pub fn get_cond_true(state: *const RsvgState) -> bool {
- unsafe { from_glib(rsvg_state_get_cond_true(state)) }
-}
-
-pub fn set_cond_true(state: *const RsvgState, cond_true: bool) {
- unsafe {
- rsvg_state_set_cond_true(state, cond_true.to_glib());
- }
-}
-
pub fn get_stop_color(state: *const RsvgState) -> Result<Option<Color>, AttributeError> {
unsafe {
let spec_ptr = rsvg_state_get_stop_color(state);
@@ -510,6 +531,16 @@ pub fn reinherit(state: *mut RsvgState, src: *const RsvgState) {
}
}
+pub fn get_cond(state: *mut RsvgState) -> bool {
+ get_state_rust(state).cond
+}
+
+pub fn set_cond(state: *mut RsvgState, value: bool) {
+ let rstate = get_state_rust(state);
+
+ rstate.cond = value;
+}
+
pub fn get_state_rust<'a>(state: *const RsvgState) -> &'a mut State {
unsafe { &mut *rsvg_state_get_state_rust(state) }
}
@@ -960,6 +991,21 @@ pub extern "C" fn rsvg_state_is_visible(state: *const RsvgState) -> glib_sys::gb
is_visible(state).to_glib()
}
+#[no_mangle]
+pub extern "C" fn rsvg_state_parse_conditional_processing_attributes(
+ state: *mut RsvgState,
+ pbag: *const PropertyBag,
+) -> glib_sys::gboolean {
+ let state = unsafe { &mut *state };
+ let pbag = unsafe { &*pbag };
+
+ let rstate = get_state_rust(state);
+ match rstate.parse_conditional_processing_attributes(pbag) {
+ Ok(_) => true.to_glib(),
+ Err(_) => false.to_glib(),
+ }
+}
+
// Rust State API for consumption from C ----------------------------------------
#[no_mangle]
@@ -1100,6 +1146,8 @@ pub extern "C" fn rsvg_state_rust_inherit_run(
inherit(inherit_fn, &mut dst.xml_lang, &src.xml_lang);
inherit(inherit_fn, &mut dst.xml_space, &src.xml_space);
+ dst.cond = src.cond;
+
if from_glib(inheritunheritables) {
dst.clip_path.clone_from(&src.clip_path);
dst.comp_op.clone_from(&src.comp_op);
diff --git a/rsvg_internals/src/structure.rs b/rsvg_internals/src/structure.rs
index 0c64a29c..86efd373 100644
--- a/rsvg_internals/src/structure.rs
+++ b/rsvg_internals/src/structure.rs
@@ -85,9 +85,7 @@ impl NodeTrait for NodeSwitch {
drawing_ctx::push_discrete_layer(draw_ctx, clipping);
- if let Some(child) = node.children()
- .find(|c| state::get_cond_true(c.get_state()))
- {
+ if let Some(child) = node.children().find(|c| state::get_cond(c.get_state())) {
let boxed_child = box_node(child.clone());
drawing_ctx::draw_node_from_stack(draw_ctx, boxed_child, 0, clipping);
diff --git a/rsvg_internals/src/text.rs b/rsvg_internals/src/text.rs
index e0c30d0e..eb1392fe 100644
--- a/rsvg_internals/src/text.rs
+++ b/rsvg_internals/src/text.rs
@@ -693,7 +693,7 @@ pub extern "C" fn rsvg_node_chars_new(raw_parent: *const RsvgNode) -> *const Rsv
let node = boxed_node_new(NodeType::Chars, raw_parent, Box::new(NodeChars::new()));
let state = rsvg_node_get_state(node);
- state::set_cond_true(state, false);
+ state::set_cond(state, false);
node
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]