[librsvg] stop.rs: Start porting the gradient stop element to Rust
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg] stop.rs: Start porting the gradient stop element to Rust
- Date: Wed, 31 May 2017 23:38:41 +0000 (UTC)
commit 6253c01b7693f311fd1283d4a1cd724ba7635c6a
Author: Federico Mena Quintero <federico gnome org>
Date: Wed May 31 18:28:55 2017 -0500
stop.rs: Start porting the gradient stop element to Rust
Makefile.am | 1 +
rust/src/lib.rs | 5 ++
rust/src/stop.rs | 169 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 175 insertions(+), 0 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 8ac975f..02620b4 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -93,6 +93,7 @@ RUST_SOURCES = \
rust/src/pt.rs \
rust/src/shapes.rs \
rust/src/state.rs \
+ rust/src/stop.rs \
rust/src/structure.rs \
rust/src/transform.rs \
rust/src/util.rs \
diff --git a/rust/src/lib.rs b/rust/src/lib.rs
index a4093a5..e789e13 100644
--- a/rust/src/lib.rs
+++ b/rust/src/lib.rs
@@ -99,6 +99,10 @@ pub use shapes::{
rsvg_node_rect_new,
};
+pub use stop::{
+ rsvg_node_stop_new
+};
+
pub use structure::{
rsvg_node_group_new,
rsvg_node_defs_new,
@@ -141,6 +145,7 @@ mod path_parser;
mod pattern;
mod property_bag;
mod state;
+mod stop;
mod shapes;
mod structure;
mod transform;
diff --git a/rust/src/stop.rs b/rust/src/stop.rs
new file mode 100644
index 0000000..d002c52
--- /dev/null
+++ b/rust/src/stop.rs
@@ -0,0 +1,169 @@
+use ::libc;
+use ::cssparser;
+use ::glib::translate::*;
+
+use std::cell::Cell;
+
+use color::*;
+use drawing_ctx;
+use drawing_ctx::*;
+use error::*;
+use handle::RsvgHandle;
+use length::*;
+use node::*;
+use opacity::*;
+use property_bag;
+use property_bag::*;
+use state::RsvgState;
+
+struct NodeStop {
+ offset: Cell<f64>,
+ rgba: Cell<u32>
+}
+
+impl NodeStop {
+ fn new () -> NodeStop {
+ NodeStop {
+ offset: Cell::new (0.0),
+ rgba: Cell::new (0)
+ }
+ }
+}
+
+impl NodeTrait for NodeStop {
+ fn set_atts (&self, node: &RsvgNode, handle: *const RsvgHandle, pbag: *const RsvgPropertyBag) ->
NodeResult {
+ let offset_length = property_bag::length_or_default (pbag, "offset", LengthDir::Both)?;
+ match offset_length.unit {
+ LengthUnit::Default |
+ LengthUnit::Percent => {
+ let mut offset = offset_length.length;
+
+ if offset < 0.0 {
+ offset = 0.0;
+ } else if offset > 1.0 {
+ offset = 1.0;
+ }
+
+ self.offset.set (offset);
+ },
+
+ _ => {
+ return Err (NodeError::value_error ("offset", "stop offset must be in default or percent
units"));
+ }
+ }
+
+ let state = node.get_state ();
+
+ // FIXME: this is the only place where rsvg_parse_style() and
+ // rsvg_parse_style_pairs() are called outside of the
+ // rsvg-base.c machinery. That one indirectly calls them via
+ // rsvg_parse_style_attrs().
+ //
+ // Should we resolve the stop-color / stop-opacity at
+ // rendering time?
+
+ if let Some (v) = property_bag::lookup (pbag, "style") {
+ unsafe {
+ rsvg_parse_style (handle, state, v.to_glib_none ().0);
+ }
+ }
+
+ unsafe {
+ rsvg_parse_style_pairs (state, pbag);
+ }
+
+ let inherited_state = drawing_ctx::state_new ();
+ drawing_ctx::state_reconstruct (inherited_state, box_node (node.clone ()));
+
+ let mut color_rgba: cssparser::RGBA;
+
+ let stop_color = drawing_ctx::state_get_stop_color (state)
+ .map_err (|e| NodeError::attribute_error ("stop-color", e))?;
+
+ match stop_color {
+ None => color_rgba = cssparser::RGBA::transparent (),
+
+ Some (Color::Inherit) => {
+ let inherited_stop_color = drawing_ctx::state_get_stop_color (inherited_state)
+ .map_err (|e| NodeError::attribute_error ("stop-color", e))?;
+
+ match inherited_stop_color {
+ None => unreachable! (),
+
+ Some (Color::Inherit) => color_rgba = cssparser::RGBA::transparent (),
+ Some (Color::CurrentColor) => {
+ let color = drawing_ctx::state_get_current_color (inherited_state);
+ match color {
+ Color::RGBA (rgba) => color_rgba = rgba,
+ _ => unreachable! ()
+ }
+ },
+
+ Some (Color::RGBA (rgba)) => color_rgba = rgba
+ }
+ },
+
+ Some (Color::CurrentColor) => {
+ let color = drawing_ctx::state_get_current_color (inherited_state);
+ match color {
+ Color::RGBA (rgba) => color_rgba = rgba,
+ _ => unreachable! ()
+ }
+ }
+
+ Some (Color::RGBA (rgba)) => color_rgba = rgba
+ }
+
+ let stop_opacity = drawing_ctx::state_get_stop_opacity (state)
+ .map_err (|e| NodeError::attribute_error ("stop-opacity", e))?;
+
+ match stop_opacity {
+ None => color_rgba.alpha = 0xff,
+
+ Some (Opacity::Inherit) => {
+ let inherited_opacity = drawing_ctx::state_get_stop_opacity (inherited_state)
+ .map_err (|e| NodeError::attribute_error ("stop-opacity", e))?;
+
+ match inherited_opacity {
+ Some (Opacity::Specified (opacity)) => color_rgba.alpha = opacity_to_u8 (opacity),
+ _ => color_rgba.alpha = 0xff
+ }
+ },
+
+ Some (Opacity::Specified (opacity)) => color_rgba.alpha = opacity_to_u8 (opacity)
+ }
+
+ self.rgba.set (u32_from_rgba (color_rgba));
+
+ drawing_ctx::state_free (inherited_state);
+
+ Ok (())
+ }
+
+ fn draw (&self, node: &RsvgNode, draw_ctx: *const RsvgDrawingCtx, dominate: i32) {
+ // nothing; paint servers are handled specially
+ }
+
+ fn get_c_impl (&self) -> *const RsvgCNodeImpl {
+ unreachable! ();
+ }
+}
+
+fn u32_from_rgba (rgba: cssparser::RGBA) -> u32 {
+ ((rgba.red as u32) << 24) |
+ ((rgba.green as u32) << 16) |
+ ((rgba.blue as u32) << 8) |
+ (rgba.alpha as u32)
+}
+
+extern "C" {
+ fn rsvg_parse_style_pairs (state: *mut RsvgState, pbag: *const RsvgPropertyBag);
+ fn rsvg_parse_style (handle: *const RsvgHandle, state: *mut RsvgState, string: *const libc::c_char);
+}
+
+#[no_mangle]
+pub extern fn rsvg_node_stop_new (_: *const libc::c_char, raw_parent: *const RsvgNode) -> *const RsvgNode {
+ boxed_node_new (NodeType::Stop,
+ raw_parent,
+ Box::new (NodeStop::new ()))
+}
[
Date Prev][Date Next] [
Thread Prev][Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]