[librsvg] mask.rs: Port NodeMask completely to Rust. Yay!



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]