[librsvg] clip_path.rs: Move the clipPath implementation to Rust. Yay!



commit 388870e1fc285bd951c1a13f594672cb10750cc2
Author: Federico Mena Quintero <federico gnome org>
Date:   Thu Nov 30 11:31:20 2017 -0600

    clip_path.rs: Move the clipPath implementation to Rust.  Yay!

 Makefile.am              |    1 +
 rsvg-base.c              |    2 +-
 rsvg-mask.c              |   54 -----------------------------------------
 rsvg-mask.h              |    4 ++-
 rsvg-private.h           |    4 +-
 rust/src/clip_path.rs    |   60 ++++++++++++++++++++++++++++++++++++++++++++++
 rust/src/lib.rs          |    6 ++++
 rust/src/paint_server.rs |    1 +
 rust/src/pattern.rs      |    2 +-
 9 files changed, 75 insertions(+), 59 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 5286691..cf9d5d1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -71,6 +71,7 @@ RUST_SOURCES =                                        \
        rust/Cargo.toml                         \
        rust/src/aspect_ratio.rs                \
        rust/src/bbox.rs                        \
+       rust/src/clip_path.rs                   \
        rust/src/cnode.rs                       \
        rust/src/color.rs                       \
        rust/src/drawing_ctx.rs                 \
diff --git a/rsvg-base.c b/rsvg-base.c
index f0a5539..74a59ec 100644
--- a/rsvg-base.c
+++ b/rsvg-base.c
@@ -272,7 +272,7 @@ static const NodeCreator node_creators[] = {
     /* "animateMotion",      FALSE, */
     /* "animateTransform",   FALSE, */
     { "circle",              TRUE,  rsvg_node_circle_new },
-    { "clipPath",            TRUE,  rsvg_new_clip_path },
+    { "clipPath",            TRUE,  rsvg_node_clip_path_new },
     /* "color-profile",      FALSE, */
     { "conicalGradient",     TRUE,  rsvg_node_radial_gradient_new },
     /* "cursor",             FALSE, */
diff --git a/rsvg-mask.c b/rsvg-mask.c
index 356812d..dfb772e 100644
--- a/rsvg-mask.c
+++ b/rsvg-mask.c
@@ -84,57 +84,3 @@ rsvg_new_mask (const char *element_name, RsvgNode *parent)
                                 rsvg_mask_draw,
                                 g_free);
 }
-
-typedef struct _RsvgClipPath RsvgClipPath;
-
-struct _RsvgClipPath {
-    RsvgCoordUnits units;
-};
-
-static void
-rsvg_clip_path_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, RsvgPropertyBag *atts)
-{
-    RsvgClipPath *clip_path = impl;
-    const char *value;
-
-    if ((value = rsvg_property_bag_lookup (atts, "clipPathUnits"))) {
-        if (!strcmp (value, "objectBoundingBox"))
-            clip_path->units = objectBoundingBox;
-        else
-            clip_path->units = userSpaceOnUse;
-    }
-}
-
-static void
-rsvg_clip_path_draw (RsvgNode *node, gpointer impl, RsvgDrawingCtx *ctx, int dominate)
-{
-    /* nothing; this gets drawn specially in rsvg-cairo-draw.c */
-}
-
-RsvgNode *
-rsvg_new_clip_path (const char *element_name, RsvgNode *parent)
-{
-    RsvgClipPath *clip_path;
-
-    clip_path = g_new0 (RsvgClipPath, 1);
-    clip_path->units = userSpaceOnUse;
-
-    return rsvg_rust_cnode_new (RSVG_NODE_TYPE_CLIP_PATH,
-                                parent,
-                                rsvg_state_new (),
-                                clip_path,
-                                rsvg_clip_path_set_atts,
-                                rsvg_clip_path_draw,
-                                g_free); 
-}
-
-RsvgCoordUnits
-rsvg_node_clip_path_get_units (RsvgNode *node)
-{
-    RsvgClipPath *clip_path;
-
-    g_assert (rsvg_node_get_type (node) == RSVG_NODE_TYPE_CLIP_PATH);
-
-    clip_path = rsvg_rust_cnode_get_impl (node);
-    return clip_path->units;
-}
diff --git a/rsvg-mask.h b/rsvg-mask.h
index 938efe8..e9f5a45 100644
--- a/rsvg-mask.h
+++ b/rsvg-mask.h
@@ -48,9 +48,11 @@ struct _RsvgMask {
 G_GNUC_INTERNAL
 RsvgNode *rsvg_new_mask            (const char *element_name, RsvgNode *node);
 
+/* Implemented in rust/src/clip_path.rs */
 G_GNUC_INTERNAL
-RsvgNode *rsvg_new_clip_path   (const char *element_name, RsvgNode *node);
+RsvgNode *rsvg_node_clip_path_new (const char *element_name, RsvgNode *node);
 
+/* Implemented in rust/src/clip_path.rs */
 G_GNUC_INTERNAL
 RsvgCoordUnits rsvg_node_clip_path_get_units (RsvgNode *node);
 
diff --git a/rsvg-private.h b/rsvg-private.h
index 0f10197..546bf02 100644
--- a/rsvg-private.h
+++ b/rsvg-private.h
@@ -284,8 +284,8 @@ typedef struct {
 } RsvgBbox;
 
 typedef enum {
-    objectBoundingBox,
-    userSpaceOnUse
+    userSpaceOnUse,
+    objectBoundingBox
 } RsvgCoordUnits;
 
 /* Keep this in sync with rust/src/node.rs:NodeType */
diff --git a/rust/src/clip_path.rs b/rust/src/clip_path.rs
new file mode 100644
index 0000000..039f6c7
--- /dev/null
+++ b/rust/src/clip_path.rs
@@ -0,0 +1,60 @@
+use libc;
+use std::cell::Cell;
+
+use drawing_ctx::RsvgDrawingCtx;
+use handle::RsvgHandle;
+use node::{NodeResult, NodeTrait, NodeType, RsvgCNodeImpl, RsvgNode, boxed_node_new};
+use paint_server::PaintServerUnits;
+use pattern::PatternContentUnits;
+use property_bag::{self, RsvgPropertyBag};
+
+type ClipPathUnits = PatternContentUnits;
+
+struct NodeClipPath {
+    units: Cell<ClipPathUnits>
+}
+
+impl NodeClipPath {
+    fn new() -> NodeClipPath {
+        NodeClipPath {
+            units: Cell::new(PatternContentUnits::from(PaintServerUnits::UserSpaceOnUse))
+        }
+    }
+}
+
+impl NodeTrait for NodeClipPath {
+    fn set_atts(&self, _: &RsvgNode, _: *const RsvgHandle, pbag: *const RsvgPropertyBag) -> NodeResult {
+        self.units.set(property_bag::parse_or_default(pbag, "clipPathUnits", (), None)?);
+
+        Ok(())
+    }
+
+    fn draw(&self, _: &RsvgNode, _: *const RsvgDrawingCtx, _: i32) {
+        // nothing; clip paths are handled specially
+    }
+
+    fn get_c_impl(&self) -> *const RsvgCNodeImpl {
+        unreachable!();
+    }
+}
+
+#[no_mangle]
+pub extern fn rsvg_node_clip_path_new(_: *const libc::c_char, raw_parent: *const RsvgNode) -> *const 
RsvgNode {
+    boxed_node_new(NodeType::ClipPath,
+                   raw_parent,
+                   Box::new(NodeClipPath::new()))
+}
+
+#[no_mangle]
+pub extern fn rsvg_node_clip_path_get_units(raw_node: *const RsvgNode) -> PaintServerUnits {
+    assert! (!raw_node.is_null ());
+    let node: &RsvgNode = unsafe { & *raw_node };
+
+    let mut units = PatternContentUnits::default();
+
+    node.with_impl(|clip_path: &NodeClipPath| {
+        units = clip_path.units.get();
+    });
+
+    units.0
+}
diff --git a/rust/src/lib.rs b/rust/src/lib.rs
index 9dd7cec..52721d8 100644
--- a/rust/src/lib.rs
+++ b/rust/src/lib.rs
@@ -22,6 +22,11 @@ pub use bbox::{
     rsvg_bbox_clip
 };
 
+pub use clip_path::{
+    rsvg_node_clip_path_new,
+    rsvg_node_clip_path_get_units
+};
+
 pub use cnode::{
     rsvg_rust_cnode_new,
     rsvg_rust_cnode_get_impl
@@ -130,6 +135,7 @@ pub use viewbox::{
 
 mod aspect_ratio;
 mod bbox;
+mod clip_path;
 mod cnode;
 mod color;
 mod drawing_ctx;
diff --git a/rust/src/paint_server.rs b/rust/src/paint_server.rs
index 3e5af59..6d2808c 100644
--- a/rust/src/paint_server.rs
+++ b/rust/src/paint_server.rs
@@ -7,6 +7,7 @@ use parsers::ParseError;
 /// Defines the units to be used for scaling paint servers, per the [svg specification].
 ///
 /// [svg spec]: https://www.w3.org/TR/SVG/pservers.html
+#[repr(C)]
 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
 pub enum PaintServerUnits {
     UserSpaceOnUse,
diff --git a/rust/src/pattern.rs b/rust/src/pattern.rs
index c601edf..9978a7d 100644
--- a/rust/src/pattern.rs
+++ b/rust/src/pattern.rs
@@ -69,7 +69,7 @@ impl Default for Pattern {
 // objects which it references.  We define PatternContentUnits as a newtype, so that
 // it can have its own default value, different from the one in PaintServerUnits.
 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
-pub struct PatternContentUnits(PaintServerUnits);
+pub struct PatternContentUnits(pub PaintServerUnits);
 
 impl From<PaintServerUnits> for PatternContentUnits {
     fn from (units: PaintServerUnits) -> PatternContentUnits {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]