[librsvg] Move NodeStop over to Rust. Yay!
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg] Move NodeStop over to Rust. Yay!
- Date: Fri, 2 Jun 2017 15:29:40 +0000 (UTC)
commit 59bec0b08d30bb59976d7f2eb6e4277cdf23fb58
Author: Federico Mena Quintero <federico gnome org>
Date: Fri Jun 2 09:53:02 2017 -0500
Move NodeStop over to Rust. Yay!
This reimplements gradient_add_color_stops_from_node() in Rust based on
the old C code.
rsvg-base.c | 2 +-
rsvg-cairo-draw.c | 31 +----------
rsvg-paint-server.c | 140 --------------------------------------------------
rsvg-paint-server.h | 17 ++----
rust/src/gradient.rs | 31 ++++++++----
rust/src/lib.rs | 2 +-
rust/src/node.rs | 4 ++
rust/src/stop.rs | 4 +-
8 files changed, 36 insertions(+), 195 deletions(-)
---
diff --git a/rsvg-base.c b/rsvg-base.c
index 6cc74c7..5205424 100644
--- a/rsvg-base.c
+++ b/rsvg-base.c
@@ -321,7 +321,7 @@ static const NodeCreator node_creators[] = {
{ "rect", TRUE, rsvg_node_rect_new },
/* "script", FALSE, */
/* "set", FALSE, */
- { "stop", TRUE, rsvg_new_stop },
+ { "stop", TRUE, rsvg_node_stop_new },
/* "style", FALSE, */
{ "subImage", FALSE, rsvg_node_group_new },
{ "subImageRef", FALSE, rsvg_new_image },
diff --git a/rsvg-cairo-draw.c b/rsvg-cairo-draw.c
index 0e2de5e..d240987 100644
--- a/rsvg-cairo-draw.c
+++ b/rsvg-cairo-draw.c
@@ -42,33 +42,6 @@
#include <pango/pangocairo.h>
#include <pango/pangofc-fontmap.h>
-static gboolean
-add_color_stop_to_gradient (RsvgNode *node, gpointer data)
-{
- Gradient *gradient = data;
- RsvgGradientStop *stop;
-
- if (rsvg_node_get_type (node) != RSVG_NODE_TYPE_STOP)
- return TRUE; /* just ignore this node */
-
- stop = rsvg_rust_cnode_get_impl (node);
-
- if (!stop->is_valid) {
- /* Don't add any more stops. */
- return FALSE;
- }
-
- gradient_add_color_stop (gradient, stop->offset, stop->rgba);
-
- return TRUE;
-}
-
-static void
-add_color_stops_to_gradient (Gradient *gradient, RsvgNode *node)
-{
- rsvg_node_foreach_child (node, add_color_stop_to_gradient, gradient);
-}
-
static Gradient *
linear_gradient_to_rust (RsvgNode *node)
{
@@ -87,7 +60,7 @@ linear_gradient_to_rust (RsvgNode *node)
linear->hasspread ? &linear->spread : NULL,
linear->fallback);
- add_color_stops_to_gradient (gradient, node);
+ gradient_add_color_stops_from_node (gradient, node);
return gradient;
}
@@ -111,7 +84,7 @@ radial_gradient_to_rust (RsvgNode *node)
radial->hasspread ? &radial->spread : NULL,
radial->fallback);
- add_color_stops_to_gradient (gradient, node);
+ gradient_add_color_stops_from_node (gradient, node);
return gradient;
}
diff --git a/rsvg-paint-server.c b/rsvg-paint-server.c
index 05ad241..3e94ae2 100644
--- a/rsvg-paint-server.c
+++ b/rsvg-paint-server.c
@@ -210,151 +210,11 @@ rsvg_paint_server_unref (RsvgPaintServer * ps)
}
static void
-rsvg_stop_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag *atts)
-{
- RsvgGradientStop *stop = impl;
- const char *value;
- RsvgState *state;
- RsvgState *inherited_state;
- int opacity;
- guint32 color;
-
- state = rsvg_node_get_state (node);
-
- if ((value = rsvg_property_bag_lookup (atts, "offset"))) {
- /* either a number [0,1] or a percentage */
- RsvgLength length = rsvg_length_parse (value, LENGTH_DIR_BOTH);
-
- if (length.unit == LENGTH_UNIT_DEFAULT || length.unit == LENGTH_UNIT_PERCENT) {
- double offset;
-
- offset = length.length;
-
- if (offset < 0.0)
- offset = 0.0;
- else if (offset > 1.0)
- offset = 1.0;
-
- stop->offset = offset;
- stop->is_valid = TRUE;
- } else {
- /* Only default and percent values are allowed */
- stop->is_valid = FALSE;
- }
- }
- if ((value = rsvg_property_bag_lookup (atts, "style")))
- rsvg_parse_style (handle, state, value);
-
- rsvg_parse_style_pairs (state, atts);
-
- inherited_state = rsvg_state_new ();
- rsvg_state_reconstruct (inherited_state, node);
-
- if (state->has_stop_color) {
- switch (state->stop_color.kind) {
- case RSVG_CSS_COLOR_SPEC_INHERIT:
- switch (inherited_state->stop_color.kind) {
- case RSVG_CSS_COLOR_SPEC_INHERIT:
- color = 0;
- break;
-
- case RSVG_CSS_COLOR_SPEC_CURRENT_COLOR:
- color = inherited_state->current_color;
- break;
-
- case RSVG_CSS_COLOR_SPEC_ARGB:
- color = inherited_state->stop_color.argb;
- break;
-
- case RSVG_CSS_COLOR_PARSE_ERROR:
- color = 0;
- break;
-
- default:
- g_assert_not_reached ();
- return;
- }
- break;
-
- case RSVG_CSS_COLOR_SPEC_CURRENT_COLOR:
- color = inherited_state->current_color;
- break;
-
- case RSVG_CSS_COLOR_SPEC_ARGB:
- color = state->stop_color.argb & 0x00ffffff;
- break;
-
- case RSVG_CSS_COLOR_PARSE_ERROR:
- color = 0;
- break;
-
- default:
- g_assert_not_reached ();
- return;
- }
- } else {
- color = 0;
- }
-
- if (state->has_stop_opacity) {
- switch (state->stop_opacity.kind) {
- case RSVG_OPACITY_SPECIFIED:
- opacity = state->stop_opacity.opacity;
- break;
-
- case RSVG_OPACITY_INHERIT:
- switch (inherited_state->stop_opacity.kind) {
- case RSVG_OPACITY_SPECIFIED:
- opacity = inherited_state->stop_opacity.opacity;
- break;
-
- case RSVG_OPACITY_INHERIT:
- opacity = 0xff;
- break;
-
- default:
- g_assert_not_reached ();
- return;
- }
- break;
-
- default:
- g_assert_not_reached ();
- return;
- }
- } else {
- opacity = 0xff;
- }
-
- stop->rgba = (color << 8) | opacity;
-
- rsvg_state_free (inherited_state);
-}
-
-static void
rsvg_paint_server_draw (RsvgNode *node, gpointer impl, RsvgDrawingCtx *ctx, int dominate)
{
/* nothing; paint servers are handled specially */
}
-RsvgNode *
-rsvg_new_stop (const char *element_name, RsvgNode *parent)
-{
- RsvgGradientStop *stop = g_new0 (RsvgGradientStop, 1);
-
- stop->offset = 0;
- stop->rgba = 0xff000000;
- stop->is_valid = FALSE;
-
- return rsvg_rust_cnode_new (RSVG_NODE_TYPE_STOP,
- parent,
- rsvg_state_new (),
- stop,
- rsvg_stop_set_atts,
- rsvg_paint_server_draw,
- g_free);
-}
-
static void
rsvg_linear_gradient_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag *atts)
{
diff --git a/rsvg-paint-server.h b/rsvg-paint-server.h
index dc152e9..7022ed4 100644
--- a/rsvg-paint-server.h
+++ b/rsvg-paint-server.h
@@ -32,8 +32,6 @@
G_BEGIN_DECLS
-typedef struct _RsvgGradientStop RsvgGradientStop;
-typedef struct _RsvgGradientStops RsvgGradientStops;
typedef struct _RsvgLinearGradient RsvgLinearGradient;
typedef struct _RsvgRadialGradient RsvgRadialGradient;
typedef struct _RsvgSolidColor RsvgSolidColor;
@@ -42,12 +40,6 @@ typedef struct _RsvgPaintServer RsvgPaintServer;
typedef struct _RsvgPSCtx RsvgPSCtx;
-struct _RsvgGradientStop {
- double offset;
- guint32 rgba;
- gboolean is_valid;
-};
-
struct _RsvgLinearGradient {
gboolean obj_bbox;
cairo_matrix_t affine; /* user space to actual at time of gradient def */
@@ -111,9 +103,8 @@ void gradient_destroy (Gradient *gradient);
/* Implemented in rust/src/gradient.rs */
G_GNUC_INTERNAL
-void gradient_add_color_stop (Gradient *gradient,
- double offset,
- guint32 rgba);
+void gradient_add_color_stops_from_node (Gradient *gradient,
+ RsvgNode *node);
/* Implemented in rust/src/gradient.rs */
G_GNUC_INTERNAL
@@ -179,8 +170,10 @@ G_GNUC_INTERNAL
RsvgNode *rsvg_new_linear_gradient (const char *element_name, RsvgNode *parent);
G_GNUC_INTERNAL
RsvgNode *rsvg_new_radial_gradient (const char *element_name, RsvgNode *parent);
+
+/* Implemented in rust/src/stop.rs */
G_GNUC_INTERNAL
-RsvgNode *rsvg_new_stop (const char *element_name, RsvgNode *parent);
+RsvgNode *rsvg_node_stop_new (const char *element_name, RsvgNode *parent);
G_END_DECLS
diff --git a/rust/src/gradient.rs b/rust/src/gradient.rs
index 071ff67..102dc0f 100644
--- a/rust/src/gradient.rs
+++ b/rust/src/gradient.rs
@@ -6,15 +6,13 @@ extern crate glib;
use self::glib::translate::*;
-use length::*;
-
+use bbox::*;
use drawing_ctx;
use drawing_ctx::RsvgDrawingCtx;
-use node::RsvgNode;
+use length::*;
+use node::*;
use paint_server::*;
-
-use bbox::*;
-
+use stop::*;
use util::*;
use self::cairo::MatrixTrait;
@@ -600,14 +598,27 @@ pub unsafe extern fn gradient_destroy (raw_gradient: *mut Gradient) {
}
#[no_mangle]
-pub extern fn gradient_add_color_stop (raw_gradient: *mut Gradient,
- offset: f64,
- rgba: u32) {
+pub extern fn gradient_add_color_stops_from_node (raw_gradient: *mut Gradient,
+ raw_node: *const RsvgNode) {
assert! (!raw_gradient.is_null ());
+ assert! (!raw_node.is_null ());
let gradient: &mut Gradient = unsafe { &mut (*raw_gradient) };
+ let node: &RsvgNode = unsafe { & *raw_node };
+
+ for child in &*node.children.borrow () {
+ if child.get_type () != NodeType::Stop {
+ continue; // just ignore this child; we are only interested in gradient stops
+ }
- gradient.add_color_stop (offset, rgba);
+ if child.get_result ().is_err () {
+ break; // don't add any more stops
+ }
+
+ child.with_impl (|stop: &NodeStop| {
+ gradient.add_color_stop (stop.get_offset (), stop.get_rgba ());
+ });
+ }
}
#[no_mangle]
diff --git a/rust/src/lib.rs b/rust/src/lib.rs
index e789e13..a2adbb8 100644
--- a/rust/src/lib.rs
+++ b/rust/src/lib.rs
@@ -42,7 +42,7 @@ pub use gradient::{
gradient_linear_new,
gradient_radial_new,
gradient_destroy,
- gradient_add_color_stop,
+ gradient_add_color_stops_from_node,
gradient_resolve_fallbacks_and_set_pattern
};
diff --git a/rust/src/node.rs b/rust/src/node.rs
index 3f3c63d..8d7a5fc 100644
--- a/rust/src/node.rs
+++ b/rust/src/node.rs
@@ -192,6 +192,10 @@ impl Node {
*self.result.borrow_mut () = Err (error);
}
+ pub fn get_result (&self) -> NodeResult {
+ self.result.borrow ().clone ()
+ }
+
pub fn get_c_impl (&self) -> *const RsvgCNodeImpl {
self.node_impl.get_c_impl ()
}
diff --git a/rust/src/stop.rs b/rust/src/stop.rs
index 26763af..22420f0 100644
--- a/rust/src/stop.rs
+++ b/rust/src/stop.rs
@@ -16,7 +16,7 @@ use property_bag;
use property_bag::*;
use state::RsvgState;
-struct NodeStop {
+pub struct NodeStop {
offset: Cell<f64>,
rgba: Cell<u32>
}
@@ -148,7 +148,7 @@ impl NodeTrait for NodeStop {
Ok (())
}
- fn draw (&self, node: &RsvgNode, draw_ctx: *const RsvgDrawingCtx, dominate: i32) {
+ fn draw (&self, _: &RsvgNode, _: *const RsvgDrawingCtx, _: i32) {
// nothing; paint servers are handled specially
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]