[librsvg/rustification] gradient.rs: Export functions to create Gradient objects and set their color stops
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg/rustification] gradient.rs: Export functions to create Gradient objects and set their color stops
- Date: Fri, 25 Nov 2016 22:39:24 +0000 (UTC)
commit 370634f1491df627009128191ba2625fc9bbd473
Author: Federico Mena Quintero <federico gnome org>
Date: Fri Nov 25 15:09:42 2016 -0600
gradient.rs: Export functions to create Gradient objects and set their color stops
We will use these from the *_fix_fallback() functions to do fallback
resolution for gradients in the Rust code.
rsvg-paint-server.h | 22 +++++++++++++
rust/src/gradient.rs | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++
rust/src/lib.rs | 6 +++
3 files changed, 112 insertions(+), 0 deletions(-)
---
diff --git a/rsvg-paint-server.h b/rsvg-paint-server.h
index bfc31ae..c1dcc64 100644
--- a/rsvg-paint-server.h
+++ b/rsvg-paint-server.h
@@ -84,6 +84,28 @@ struct _RsvgRadialGradient {
char *fallback;
};
+typedef struct _Gradient Gradient;
+
+/* Implemented in rust/src/gradient.rs */
+G_GNUC_INTERNAL
+Gradient *gradient_linear_new (RsvgLength *x1,
+ RsvgLength *y1,
+ RsvgLength *x2,
+ RsvgLength *y2,
+ gboolean *obj_bbox,
+ cairo_matrix_t *affine,
+ cairo_extend_t *extend,
+ const char *fallback_name);
+
+/* Implemented in rust/src/gradient.rs */
+G_GNUC_INTERNAL
+void gradient_destroy (Gradient *gradient);
+
+G_GNUC_INTERNAL
+void gradient_add_color_stop (Gradient *gradient,
+ double offset,
+ guint32 rgba);
+
struct _RsvgPattern {
RsvgNode super;
gboolean obj_cbbox;
diff --git a/rust/src/gradient.rs b/rust/src/gradient.rs
index a68f21d..cab051a 100644
--- a/rust/src/gradient.rs
+++ b/rust/src/gradient.rs
@@ -1,5 +1,9 @@
+extern crate libc;
extern crate cairo;
extern crate cairo_sys;
+extern crate glib;
+
+use self::glib::translate::*;
use length::*;
@@ -98,6 +102,29 @@ impl GradientCommon {
self.fallback = clone_fallback_name (&fallback.fallback);
}
}
+
+ fn add_color_stop (&mut self, mut offset: f64, rgba: u32) {
+ if self.stops.is_none () {
+ self.stops = Some (Vec::<ColorStop>::new ());
+ }
+
+ if let Some (ref mut stops) = self.stops {
+ let mut last_offset: f64 = 0.0;
+
+ if stops.len () > 0 {
+ last_offset = stops[stops.len () - 1].offset;
+ }
+
+ if last_offset > offset {
+ offset = last_offset;
+ }
+
+ stops.push (ColorStop { offset: offset,
+ rgba: rgba });
+ } else {
+ unreachable! ();
+ }
+ }
}
fn clone_fallback_name (fallback: &Option<String>) -> Option<String> {
@@ -196,6 +223,11 @@ impl Gradient {
self.common.resolve_from_fallback (&fallback.common);
self.variant.resolve_from_fallback (&fallback.variant);
}
+
+ fn add_color_stop (&mut self, offset: f64, rgba: u32) {
+ self.common.add_color_stop (offset, rgba);
+ }
+
}
trait FallbackSource {
@@ -227,3 +259,55 @@ fn resolve_gradient (gradient: &Gradient, fallback_source: &FallbackSource) -> G
result
}
+
+/* All the arguments are pointers because they are in fact optional in
+ * SVG. We turn the arguments into Option<foo>: NULL into None, and
+ * anything else into a Some().
+ */
+#[no_mangle]
+pub unsafe extern fn gradient_linear_new (x1: *const RsvgLength,
+ y1: *const RsvgLength,
+ x2: *const RsvgLength,
+ y2: *const RsvgLength,
+ obj_bbox: *const bool,
+ affine: *const cairo::Matrix,
+ spread: *const cairo::enums::Extend,
+ fallback_name: *const libc::c_char) -> *mut Gradient {
+ let my_obj_bbox = { if obj_bbox.is_null () { None } else { Some (*obj_bbox) } };
+ let my_affine = { if affine.is_null () { None } else { Some (*affine) } };
+ let my_spread = { if spread.is_null () { None } else { Some (*spread) } };
+ let my_fallback_name = from_glib_none (fallback_name);
+
+ let my_x1 = { if x1.is_null () { None } else { Some (*x1) } };
+ let my_y1 = { if y1.is_null () { None } else { Some (*y1) } };
+ let my_x2 = { if x2.is_null () { None } else { Some (*x2) } };
+ let my_y2 = { if y2.is_null () { None } else { Some (*y2) } };
+
+ let gradient = Gradient::new (GradientCommon::new (my_obj_bbox, my_affine, my_spread, my_fallback_name,
None),
+ GradientVariant::Linear { x1: my_x1,
+ y1: my_y1,
+ x2: my_x2,
+ y2: my_y2 });
+
+ let boxed_gradient = Box::new (gradient);
+
+ Box::into_raw (boxed_gradient)
+}
+
+#[no_mangle]
+pub unsafe extern fn gradient_destroy (raw_gradient: *mut Gradient) {
+ assert! (!raw_gradient.is_null ());
+
+ let _ = Box::from_raw (raw_gradient);
+}
+
+#[no_mangle]
+pub extern fn gradient_add_color_stop (raw_gradient: *mut Gradient,
+ offset: f64,
+ rgba: u32) {
+ assert! (!raw_gradient.is_null ());
+
+ let gradient: &mut Gradient = unsafe { &mut (*raw_gradient) };
+
+ gradient.add_color_stop (offset, rgba);
+}
diff --git a/rust/src/lib.rs b/rust/src/lib.rs
index 2068691..f6ccfa7 100644
--- a/rust/src/lib.rs
+++ b/rust/src/lib.rs
@@ -1,3 +1,9 @@
+pub use gradient::{
+ gradient_linear_new,
+ gradient_destroy,
+ gradient_add_color_stop
+};
+
pub use path_builder::{
rsvg_path_builder_new,
rsvg_path_builder_destroy,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]