[librsvg] mask.rs: Port NodeMask completely to Rust. Yay!
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg] mask.rs: Port NodeMask completely to Rust. Yay!
- Date: Tue, 5 Dec 2017 03:01:10 +0000 (UTC)
commit d535a8f21f218f81c79a2749a54237d0bf526e8f
Author: Federico Mena Quintero <federico gnome org>
Date: Mon Dec 4 21:00:21 2017 -0600
mask.rs: Port NodeMask completely to Rust. Yay!
Removed rsvg-mask.c.
Makefile.am | 2 +-
rsvg-base.c | 2 +-
rsvg-cairo-draw.c | 12 ++--
rsvg-mask.c | 128 ---------------------------------------
rsvg-mask.h | 24 ++++---
rust/src/lib.rs | 11 ++++
rust/src/mask.rs | 172 +++++++++++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 204 insertions(+), 147 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index b4a4225..e5de7c7 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -36,7 +36,6 @@ librsvg_@RSVG_API_MAJOR_VERSION@_la_SOURCES = \
rsvg-filter.c \
rsvg-filter.h \
rsvg-marker.h \
- rsvg-mask.c \
rsvg-mask.h \
rsvg-shapes.h \
rsvg-structure.h \
@@ -83,6 +82,7 @@ RUST_SOURCES = \
rust/src/length.rs \
rust/src/lib.rs \
rust/src/marker.rs \
+ rust/src/mask.rs \
rust/src/node.rs \
rust/src/opacity.rs \
rust/src/paint_server.rs \
diff --git a/rsvg-base.c b/rsvg-base.c
index f4465d4..0bfedef 100644
--- a/rsvg-base.c
+++ b/rsvg-base.c
@@ -319,7 +319,7 @@ static const NodeCreator node_creators[] = {
{ "line", TRUE, rsvg_node_line_new },
{ "linearGradient", TRUE, rsvg_node_linear_gradient_new },
{ "marker", TRUE, rsvg_node_marker_new },
- { "mask", TRUE, rsvg_new_mask },
+ { "mask", TRUE, rsvg_node_mask_new },
/* "metadata", FALSE, */
/* "missing-glyph", TRUE, */
/* "mpath" FALSE, */
diff --git a/rsvg-cairo-draw.c b/rsvg-cairo-draw.c
index 624b50e..6d2c348 100644
--- a/rsvg-cairo-draw.c
+++ b/rsvg-cairo-draw.c
@@ -518,7 +518,7 @@ rsvg_cairo_set_cairo_context (RsvgDrawingCtx *ctx, cairo_t *cr)
}
static void
-rsvg_cairo_generate_mask (cairo_t * cr, RsvgNode *node_mask, RsvgDrawingCtx *ctx, RsvgBbox *bbox)
+rsvg_cairo_generate_mask (cairo_t * cr, RsvgNode *mask, RsvgDrawingCtx *ctx, RsvgBbox *bbox)
{
RsvgCairoRender *render = RSVG_CAIRO_RENDER (ctx->render);
cairo_surface_t *surface;
@@ -531,12 +531,10 @@ rsvg_cairo_generate_mask (cairo_t * cr, RsvgNode *node_mask, RsvgDrawingCtx *ctx
RsvgLength mask_x, mask_y, mask_w, mask_h;
double sx, sy, sw, sh;
gboolean nest = cr != render->initial_cr;
- RsvgMask *mask;
RsvgCoordUnits mask_units;
RsvgCoordUnits content_units;
- g_assert (rsvg_node_get_type (node_mask) == RSVG_NODE_TYPE_MASK);
- mask = rsvg_rust_cnode_get_impl (node_mask);
+ g_assert (rsvg_node_get_type (mask) == RSVG_NODE_TYPE_MASK);
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS) {
@@ -592,7 +590,7 @@ rsvg_cairo_generate_mask (cairo_t * cr, RsvgNode *node_mask, RsvgDrawingCtx *ctx
bbox->rect.x,
bbox->rect.y);
- mask_state = rsvg_node_get_state (node_mask);
+ mask_state = rsvg_node_get_state (mask);
affinesave = mask_state->affine;
cairo_matrix_multiply (&mask_state->affine, &bbtransform, &mask_state->affine);
@@ -600,7 +598,7 @@ rsvg_cairo_generate_mask (cairo_t * cr, RsvgNode *node_mask, RsvgDrawingCtx *ctx
}
rsvg_state_push (ctx);
- rsvg_node_draw_children (node_mask, ctx, 0);
+ rsvg_node_draw_children (mask, ctx, 0);
rsvg_state_pop (ctx);
if (content_units == objectBoundingBox) {
@@ -608,7 +606,7 @@ rsvg_cairo_generate_mask (cairo_t * cr, RsvgNode *node_mask, RsvgDrawingCtx *ctx
rsvg_drawing_ctx_pop_view_box (ctx);
- mask_state = rsvg_node_get_state (node_mask);
+ mask_state = rsvg_node_get_state (mask);
mask_state->affine = affinesave;
}
diff --git a/rsvg-mask.h b/rsvg-mask.h
index 29fab06..24368dd 100644
--- a/rsvg-mask.h
+++ b/rsvg-mask.h
@@ -35,29 +35,33 @@
G_BEGIN_DECLS
-
-typedef struct _RsvgMask RsvgMask;
-
+/* Implemented in rust/src/mask.rs */
G_GNUC_INTERNAL
-RsvgNode *rsvg_new_mask (const char *element_name, RsvgNode *node);
+RsvgNode *rsvg_node_mask_new (const char *element_name, RsvgNode *node);
+/* Implemented in rust/src/mask.rs */
G_GNUC_INTERNAL
-RsvgLength rsvg_node_mask_get_x (RsvgMask *mask);
+RsvgLength rsvg_node_mask_get_x (RsvgNode *node);
+/* Implemented in rust/src/mask.rs */
G_GNUC_INTERNAL
-RsvgLength rsvg_node_mask_get_y (RsvgMask *mask);
+RsvgLength rsvg_node_mask_get_y (RsvgNode *node);
+/* Implemented in rust/src/mask.rs */
G_GNUC_INTERNAL
-RsvgLength rsvg_node_mask_get_width (RsvgMask *mask);
+RsvgLength rsvg_node_mask_get_width (RsvgNode *node);
+/* Implemented in rust/src/mask.rs */
G_GNUC_INTERNAL
-RsvgLength rsvg_node_mask_get_height (RsvgMask *mask);
+RsvgLength rsvg_node_mask_get_height (RsvgNode *node);
+/* Implemented in rust/src/mask.rs */
G_GNUC_INTERNAL
-RsvgCoordUnits rsvg_node_mask_get_units (RsvgMask *mask);
+RsvgCoordUnits rsvg_node_mask_get_units (RsvgNode *node);
+/* Implemented in rust/src/mask.rs */
G_GNUC_INTERNAL
-RsvgCoordUnits rsvg_node_mask_get_content_units (RsvgMask *mask);
+RsvgCoordUnits rsvg_node_mask_get_content_units (RsvgNode *node);
/* Implemented in rust/src/clip_path.rs */
G_GNUC_INTERNAL
diff --git a/rust/src/lib.rs b/rust/src/lib.rs
index 70aba0d..8924951 100644
--- a/rust/src/lib.rs
+++ b/rust/src/lib.rs
@@ -56,6 +56,16 @@ pub use marker::{
rsvg_node_marker_new,
};
+pub use mask::{
+ rsvg_node_mask_new,
+ rsvg_node_mask_get_x,
+ rsvg_node_mask_get_y,
+ rsvg_node_mask_get_width,
+ rsvg_node_mask_get_height,
+ rsvg_node_mask_get_units,
+ rsvg_node_mask_get_content_units,
+};
+
pub use node::{
rsvg_node_get_type,
rsvg_node_get_parent,
@@ -141,6 +151,7 @@ mod handle;
mod image;
mod length;
mod marker;
+mod mask;
mod node;
mod opacity;
mod paint_server;
diff --git a/rust/src/mask.rs b/rust/src/mask.rs
new file mode 100644
index 0000000..492d0c8
--- /dev/null
+++ b/rust/src/mask.rs
@@ -0,0 +1,172 @@
+use libc;
+use std::cell::Cell;
+
+use coord_units::CoordUnits;
+use drawing_ctx::RsvgDrawingCtx;
+use handle::RsvgHandle;
+use length::{RsvgLength, LengthDir};
+use node::{NodeResult, NodeTrait, NodeType, RsvgCNodeImpl, RsvgNode, boxed_node_new};
+use parsers::Parse;
+use property_bag::{self, RsvgPropertyBag};
+
+coord_units!(MaskUnits, CoordUnits::ObjectBoundingBox);
+coord_units!(MaskContentUnits, CoordUnits::UserSpaceOnUse);
+
+struct NodeMask {
+ x: Cell<RsvgLength>,
+ y: Cell<RsvgLength>,
+ width: Cell<RsvgLength>,
+ height: Cell<RsvgLength>,
+
+ units: Cell<MaskUnits>,
+ content_units: Cell<MaskContentUnits>,
+}
+
+impl NodeMask {
+ fn new() -> NodeMask {
+ NodeMask {
+ x: Cell::new(NodeMask::get_default_pos(LengthDir::Horizontal)),
+ y: Cell::new(NodeMask::get_default_pos(LengthDir::Vertical)),
+
+ width: Cell::new(NodeMask::get_default_size(LengthDir::Horizontal)),
+ height: Cell::new(NodeMask::get_default_size(LengthDir::Vertical)),
+
+ units: Cell::new(MaskUnits::default()),
+ content_units: Cell::new(MaskContentUnits::default())
+ }
+ }
+
+ fn get_default_pos(dir: LengthDir) -> RsvgLength {
+ RsvgLength::parse("-10%", dir).unwrap()
+ }
+
+ fn get_default_size(dir: LengthDir) -> RsvgLength {
+ RsvgLength::parse("120%", dir).unwrap()
+ }
+}
+
+impl NodeTrait for NodeMask {
+ fn set_atts(&self, _: &RsvgNode, _: *const RsvgHandle, pbag: *const RsvgPropertyBag) -> NodeResult {
+ self.x.set(property_bag::parse_or_value(pbag, "x",
+ LengthDir::Horizontal,
+ NodeMask::get_default_pos(LengthDir::Horizontal),
+ None)?);
+ self.y.set(property_bag::parse_or_value(pbag, "y",
+ LengthDir::Vertical,
+ NodeMask::get_default_pos(LengthDir::Vertical),
+ None)?);
+
+ self.width.set (property_bag::parse_or_value (pbag, "width",
+ LengthDir::Horizontal,
+ NodeMask::get_default_size(LengthDir::Horizontal),
+ Some(RsvgLength::check_nonnegative))?);
+ self.height.set (property_bag::parse_or_value (pbag, "height",
+ LengthDir::Vertical,
+ NodeMask::get_default_size(LengthDir::Vertical),
+ Some(RsvgLength::check_nonnegative))?);
+
+ self.units.set(property_bag::parse_or_default(pbag, "maskUnits", (), None)?);
+ self.content_units.set(property_bag::parse_or_default(pbag, "maskContentUnits", (), None)?);
+
+ Ok(())
+ }
+
+ fn draw(&self, _: &RsvgNode, _: *const RsvgDrawingCtx, _: i32) {
+ // nothing; masks are handled specially
+ }
+
+ fn get_c_impl(&self) -> *const RsvgCNodeImpl {
+ unreachable!();
+ }
+}
+
+#[no_mangle]
+pub extern fn rsvg_node_mask_new(_: *const libc::c_char, raw_parent: *const RsvgNode) -> *const RsvgNode {
+ boxed_node_new(NodeType::Mask,
+ raw_parent,
+ Box::new(NodeMask::new()))
+}
+
+#[no_mangle]
+pub extern fn rsvg_node_mask_get_x(raw_node: *const RsvgNode) -> RsvgLength {
+ assert! (!raw_node.is_null ());
+ let node: &RsvgNode = unsafe { & *raw_node };
+
+ let mut v = RsvgLength::default();
+
+ node.with_impl(|mask: &NodeMask| {
+ v = mask.x.get();
+ });
+
+ v
+}
+
+#[no_mangle]
+pub extern fn rsvg_node_mask_get_y(raw_node: *const RsvgNode) -> RsvgLength {
+ assert! (!raw_node.is_null ());
+ let node: &RsvgNode = unsafe { & *raw_node };
+
+ let mut v = RsvgLength::default();
+
+ node.with_impl(|mask: &NodeMask| {
+ v = mask.y.get();
+ });
+
+ v
+}
+
+#[no_mangle]
+pub extern fn rsvg_node_mask_get_width(raw_node: *const RsvgNode) -> RsvgLength {
+ assert! (!raw_node.is_null ());
+ let node: &RsvgNode = unsafe { & *raw_node };
+
+ let mut v = RsvgLength::default();
+
+ node.with_impl(|mask: &NodeMask| {
+ v = mask.width.get();
+ });
+
+ v
+}
+
+#[no_mangle]
+pub extern fn rsvg_node_mask_get_height(raw_node: *const RsvgNode) -> RsvgLength {
+ assert! (!raw_node.is_null ());
+ let node: &RsvgNode = unsafe { & *raw_node };
+
+ let mut v = RsvgLength::default();
+
+ node.with_impl(|mask: &NodeMask| {
+ v = mask.height.get();
+ });
+
+ v
+}
+
+#[no_mangle]
+pub extern fn rsvg_node_mask_get_units(raw_node: *const RsvgNode) -> CoordUnits {
+ assert! (!raw_node.is_null ());
+ let node: &RsvgNode = unsafe { & *raw_node };
+
+ let mut units = MaskUnits::default();
+
+ node.with_impl(|mask: &NodeMask| {
+ units = mask.units.get();
+ });
+
+ CoordUnits::from(units)
+}
+
+#[no_mangle]
+pub extern fn rsvg_node_mask_get_content_units(raw_node: *const RsvgNode) -> CoordUnits {
+ assert! (!raw_node.is_null ());
+ let node: &RsvgNode = unsafe { & *raw_node };
+
+ let mut units = MaskContentUnits::default();
+
+ node.with_impl(|mask: &NodeMask| {
+ units = mask.content_units.get();
+ });
+
+ CoordUnits::from(units)
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]