[librsvg: 3/5] Port rsvg_filter_primitive_get_bounds() to Rust



commit f2d0468edc4bc9490985f4351ca8bd5a150789d1
Author: Ivan Molodetskikh <yalterz gmail com>
Date:   Thu May 24 19:24:55 2018 +0300

    Port rsvg_filter_primitive_get_bounds() to Rust

 librsvg/filters/common.c             | 166 +++++++++++++++++------------------
 librsvg/filters/common.h             |   3 +-
 rsvg_internals/src/filter_context.rs |  33 +++++++
 rsvg_internals/src/filters/ffi.rs    |  45 ++--------
 rsvg_internals/src/filters/mod.rs    |   2 +-
 rsvg_internals/src/lib.rs            |   1 +
 6 files changed, 129 insertions(+), 121 deletions(-)
---
diff --git a/librsvg/filters/common.c b/librsvg/filters/common.c
index ddec2750..6c3310d7 100644
--- a/librsvg/filters/common.c
+++ b/librsvg/filters/common.c
@@ -93,89 +93,89 @@ rsvg_filter_primitive_render (RsvgNode *node, RsvgFilterPrimitive *primitive, Rs
     primitive->render (node, primitive, ctx);
 }
 
-RsvgIRect
-rsvg_filter_primitive_get_bounds (RsvgFilterPrimitive * self, RsvgFilterContext * ctx)
-{
-    RsvgBbox *box, *otherbox;
-    cairo_matrix_t affine, ctx_affine;
-    cairo_rectangle_t rect;
-    const RsvgFilter *ctx_filter = rsvg_filter_context_get_filter(ctx);
-    RsvgDrawingCtx *drawing_ctx = rsvg_filter_context_get_drawing_ctx(ctx);
-
-    cairo_matrix_init_identity (&affine);
-
-    box = rsvg_bbox_new (&affine, NULL, NULL);
-
-    ctx_affine = rsvg_filter_context_get_affine(ctx);
-
-    if (ctx_filter->filterunits == objectBoundingBox)
-        rsvg_drawing_ctx_push_view_box (drawing_ctx, 1., 1.);
-
-    rect.x = rsvg_length_normalize (&ctx_filter->x, drawing_ctx);
-    rect.y = rsvg_length_normalize (&ctx_filter->y, drawing_ctx);
-    rect.width = rsvg_length_normalize (&ctx_filter->width, drawing_ctx);
-    rect.height = rsvg_length_normalize (&ctx_filter->height, drawing_ctx);
-
-    if (ctx_filter->filterunits == objectBoundingBox)
-        rsvg_drawing_ctx_pop_view_box (drawing_ctx);
-
-    otherbox = rsvg_bbox_new (&ctx_affine, &rect, NULL);
-    rsvg_bbox_insert (box, otherbox);
-    rsvg_bbox_free (otherbox);
-
-    if (self != NULL) {
-        if (self->x_specified || self->y_specified || self->width_specified || self->height_specified) {
-            cairo_matrix_t ctx_paffine;
-
-            ctx_paffine = rsvg_filter_context_get_paffine(ctx);
-
-            if (ctx_filter->primitiveunits == objectBoundingBox)
-                rsvg_drawing_ctx_push_view_box (drawing_ctx, 1., 1.);
-
-            rect.x = self->x_specified ? rsvg_length_normalize (&self->x, drawing_ctx) : 0;
-            rect.y = self->y_specified ? rsvg_length_normalize (&self->y, drawing_ctx) : 0;
-
-            if (self->width_specified || self->height_specified) {
-                double curr_vbox_w, curr_vbox_h;
-
-                rsvg_drawing_ctx_get_view_box_size (drawing_ctx, &curr_vbox_w, &curr_vbox_h);
-
-                rect.width = self->width_specified ? rsvg_length_normalize (&self->width, drawing_ctx) : 
curr_vbox_w;
-                rect.height = self->height_specified ? rsvg_length_normalize (&self->height, drawing_ctx) : 
curr_vbox_h;
-            }
-
-            if (ctx_filter->primitiveunits == objectBoundingBox)
-                rsvg_drawing_ctx_pop_view_box (drawing_ctx);
-
-            otherbox = rsvg_bbox_new (&ctx_paffine, &rect, NULL);
-            rsvg_bbox_clip (box, otherbox);
-            rsvg_bbox_free (otherbox);
-        }
-    }
-
-    rect.x = 0;
-    rect.y = 0;
-    rect.width = rsvg_filter_context_get_width(ctx);
-    rect.height = rsvg_filter_context_get_height(ctx);
-
-    otherbox = rsvg_bbox_new (&affine, &rect, NULL);
-    rsvg_bbox_clip (box, otherbox);
-    rsvg_bbox_free (otherbox);
-
-    {
-        cairo_rectangle_t box_rect;
-
-        rsvg_bbox_get_rect (box, &box_rect, NULL);
-        RsvgIRect output = {
-            box_rect.x,
-            box_rect.y,
-            box_rect.x + box_rect.width,
-            box_rect.y + box_rect.height
-        };
-
-        return output;
-    }
-}
+// RsvgIRect
+// rsvg_filter_primitive_get_bounds (RsvgFilterPrimitive * self, RsvgFilterContext * ctx)
+// {
+//     RsvgBbox *box, *otherbox;
+//     cairo_matrix_t affine, ctx_affine;
+//     cairo_rectangle_t rect;
+//     const RsvgFilter *ctx_filter = rsvg_filter_context_get_filter(ctx);
+//     RsvgDrawingCtx *drawing_ctx = rsvg_filter_context_get_drawing_ctx(ctx);
+// 
+//     cairo_matrix_init_identity (&affine);
+// 
+//     box = rsvg_bbox_new (&affine, NULL, NULL);
+// 
+//     ctx_affine = rsvg_filter_context_get_affine(ctx);
+// 
+//     if (ctx_filter->filterunits == objectBoundingBox)
+//         rsvg_drawing_ctx_push_view_box (drawing_ctx, 1., 1.);
+// 
+//     rect.x = rsvg_length_normalize (&ctx_filter->x, drawing_ctx);
+//     rect.y = rsvg_length_normalize (&ctx_filter->y, drawing_ctx);
+//     rect.width = rsvg_length_normalize (&ctx_filter->width, drawing_ctx);
+//     rect.height = rsvg_length_normalize (&ctx_filter->height, drawing_ctx);
+// 
+//     if (ctx_filter->filterunits == objectBoundingBox)
+//         rsvg_drawing_ctx_pop_view_box (drawing_ctx);
+// 
+//     otherbox = rsvg_bbox_new (&ctx_affine, &rect, NULL);
+//     rsvg_bbox_insert (box, otherbox);
+//     rsvg_bbox_free (otherbox);
+// 
+//     if (self != NULL) {
+//         if (self->x_specified || self->y_specified || self->width_specified || self->height_specified) {
+//             cairo_matrix_t ctx_paffine;
+// 
+//             ctx_paffine = rsvg_filter_context_get_paffine(ctx);
+// 
+//             if (ctx_filter->primitiveunits == objectBoundingBox)
+//                 rsvg_drawing_ctx_push_view_box (drawing_ctx, 1., 1.);
+// 
+//             rect.x = self->x_specified ? rsvg_length_normalize (&self->x, drawing_ctx) : 0;
+//             rect.y = self->y_specified ? rsvg_length_normalize (&self->y, drawing_ctx) : 0;
+// 
+//             if (self->width_specified || self->height_specified) {
+//                 double curr_vbox_w, curr_vbox_h;
+// 
+//                 rsvg_drawing_ctx_get_view_box_size (drawing_ctx, &curr_vbox_w, &curr_vbox_h);
+// 
+//                 rect.width = self->width_specified ? rsvg_length_normalize (&self->width, drawing_ctx) : 
curr_vbox_w;
+//                 rect.height = self->height_specified ? rsvg_length_normalize (&self->height, drawing_ctx) 
: curr_vbox_h;
+//             }
+// 
+//             if (ctx_filter->primitiveunits == objectBoundingBox)
+//                 rsvg_drawing_ctx_pop_view_box (drawing_ctx);
+// 
+//             otherbox = rsvg_bbox_new (&ctx_paffine, &rect, NULL);
+//             rsvg_bbox_clip (box, otherbox);
+//             rsvg_bbox_free (otherbox);
+//         }
+//     }
+// 
+//     rect.x = 0;
+//     rect.y = 0;
+//     rect.width = rsvg_filter_context_get_width(ctx);
+//     rect.height = rsvg_filter_context_get_height(ctx);
+// 
+//     otherbox = rsvg_bbox_new (&affine, &rect, NULL);
+//     rsvg_bbox_clip (box, otherbox);
+//     rsvg_bbox_free (otherbox);
+// 
+//     {
+//         cairo_rectangle_t box_rect;
+// 
+//         rsvg_bbox_get_rect (box, &box_rect, NULL);
+//         RsvgIRect output = {
+//             box_rect.x,
+//             box_rect.y,
+//             box_rect.x + box_rect.width,
+//             box_rect.y + box_rect.height
+//         };
+// 
+//         return output;
+//     }
+// }
 
 cairo_surface_t *
 _rsvg_image_surface_new (int width, int height)
diff --git a/librsvg/filters/common.h b/librsvg/filters/common.h
index d4953289..0dcae48e 100644
--- a/librsvg/filters/common.h
+++ b/librsvg/filters/common.h
@@ -139,8 +139,9 @@ void rsvg_filter_set_atts (RsvgNode *node, gpointer impl, RsvgHandle *handle, Rs
 G_GNUC_INTERNAL
 void rsvg_filter_primitive_free (gpointer impl);
 
+/* Implemented in rust/src/filter_context.rs */
 G_GNUC_INTERNAL
-RsvgIRect rsvg_filter_primitive_get_bounds (RsvgFilterPrimitive * self, RsvgFilterContext * ctx);
+RsvgIRect rsvg_filter_primitive_get_bounds (const RsvgFilterPrimitive * self, const RsvgFilterContext * ctx);
 
 /* Implemented in rust/src/filter_context.rs */
 G_GNUC_INTERNAL
diff --git a/rsvg_internals/src/filter_context.rs b/rsvg_internals/src/filter_context.rs
index 7d3a06b5..2ab98ded 100644
--- a/rsvg_internals/src/filter_context.rs
+++ b/rsvg_internals/src/filter_context.rs
@@ -406,3 +406,36 @@ pub unsafe extern "C" fn rsvg_filter_store_output(
 
     (*ctx).store_result(Some(name), result);
 }
+
+#[no_mangle]
+pub unsafe extern "C" fn rsvg_filter_primitive_get_bounds(
+    primitive: *const RsvgFilterPrimitive,
+    ctx: *const RsvgFilterContext,
+) -> IRect {
+    assert!(!ctx.is_null());
+
+    let mut x = None;
+    let mut y = None;
+    let mut width = None;
+    let mut height = None;
+
+    if !primitive.is_null() {
+        if (*primitive).x_specified != 0 {
+            x = Some((*primitive).x)
+        };
+
+        if (*primitive).y_specified != 0 {
+            y = Some((*primitive).y)
+        };
+
+        if (*primitive).width_specified != 0 {
+            width = Some((*primitive).width)
+        };
+
+        if (*primitive).height_specified != 0 {
+            height = Some((*primitive).height)
+        };
+    }
+
+    (*ctx).compute_bounds(x, y, width, height)
+}
diff --git a/rsvg_internals/src/filters/ffi.rs b/rsvg_internals/src/filters/ffi.rs
index 3ee20f18..e4b52984 100644
--- a/rsvg_internals/src/filters/ffi.rs
+++ b/rsvg_internals/src/filters/ffi.rs
@@ -1,7 +1,6 @@
 //! Internal FFI and marshalling things.
 
-use std::default::Default;
-use std::{mem, ptr};
+use std::mem;
 
 use cairo;
 use cairo::prelude::SurfaceExt;
@@ -22,14 +21,14 @@ use super::Filter;
 // ../../librsvg/librsvg/filters/common.h:_RsvgFilterPrimitive
 #[repr(C)]
 pub struct RsvgFilterPrimitive {
-    x: RsvgLength,
-    y: RsvgLength,
-    width: RsvgLength,
-    height: RsvgLength,
-    x_specified: gboolean,
-    y_specified: gboolean,
-    width_specified: gboolean,
-    height_specified: gboolean,
+    pub x: RsvgLength,
+    pub y: RsvgLength,
+    pub width: RsvgLength,
+    pub height: RsvgLength,
+    pub x_specified: gboolean,
+    pub y_specified: gboolean,
+    pub width_specified: gboolean,
+    pub height_specified: gboolean,
     in_: *mut GString,
     result: *mut GString,
 
@@ -38,32 +37,6 @@ pub struct RsvgFilterPrimitive {
     >,
 }
 
-impl RsvgFilterPrimitive {
-    /// Creates a new `RsvgFilterPrimitive` with the given properties.
-    #[inline]
-    pub(super) fn with_props(
-        x: Option<RsvgLength>,
-        y: Option<RsvgLength>,
-        width: Option<RsvgLength>,
-        height: Option<RsvgLength>,
-    ) -> Self {
-        Self {
-            x: x.unwrap_or_else(Default::default),
-            y: y.unwrap_or_else(Default::default),
-            width: width.unwrap_or_else(Default::default),
-            height: height.unwrap_or_else(Default::default),
-            x_specified: if x.is_some() { 1 } else { 0 },
-            y_specified: if y.is_some() { 1 } else { 0 },
-            width_specified: if width.is_some() { 1 } else { 0 },
-            height_specified: if height.is_some() { 1 } else { 0 },
-
-            in_: ptr::null_mut(),
-            result: ptr::null_mut(),
-            render: None,
-        }
-    }
-}
-
 /// The type of the render function below.
 pub(super) type RenderFunctionType = fn(&RsvgNode, &mut FilterContext);
 
diff --git a/rsvg_internals/src/filters/mod.rs b/rsvg_internals/src/filters/mod.rs
index d782f2f5..24056e72 100644
--- a/rsvg_internals/src/filters/mod.rs
+++ b/rsvg_internals/src/filters/mod.rs
@@ -13,8 +13,8 @@ use property_bag::PropertyBag;
 use state::ComputedValues;
 
 mod ffi;
-pub use self::ffi::rsvg_filter_render;
 use self::ffi::*;
+pub use self::ffi::{rsvg_filter_render, RsvgFilterPrimitive};
 
 pub mod offset;
 
diff --git a/rsvg_internals/src/lib.rs b/rsvg_internals/src/lib.rs
index 7a976a97..51c5aa3f 100644
--- a/rsvg_internals/src/lib.rs
+++ b/rsvg_internals/src/lib.rs
@@ -60,6 +60,7 @@ pub use filter_context::{
     rsvg_filter_context_get_previous_result,
     rsvg_filter_context_get_source_surface,
     rsvg_filter_context_get_width,
+    rsvg_filter_primitive_get_bounds,
     rsvg_filter_store_output,
 };
 


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