[librsvg: 1/2] state: port fill and stroke to rust



commit 4ca9508399285a80277464423f22a3040a244bc3
Author: Paolo Borelli <pborelli gnome org>
Date:   Wed Apr 25 15:09:41 2018 +0200

    state: port fill and stroke to rust

 librsvg/rsvg-styles.c              |  56 --------------------
 librsvg/rsvg-styles.h              |  12 -----
 rsvg_internals/src/draw.rs         |  77 ++++++++++++++++-----------
 rsvg_internals/src/lib.rs          |   2 -
 rsvg_internals/src/paint_server.rs | 103 +------------------------------------
 rsvg_internals/src/state.rs        |  56 ++++++++++----------
 6 files changed, 78 insertions(+), 228 deletions(-)
---
diff --git a/librsvg/rsvg-styles.c b/librsvg/rsvg-styles.c
index 249f1670..6249e536 100644
--- a/librsvg/rsvg-styles.c
+++ b/librsvg/rsvg-styles.c
@@ -98,8 +98,6 @@ rsvg_state_init (RsvgState * state)
 
     state->parent = NULL;
 
-    state->fill = rsvg_paint_server_parse (NULL, "#000");
-
     /* The following two start as INHERIT, even though has_stop_color and
      * has_stop_opacity get initialized to FALSE below.  This is so that the
      * first pass of rsvg_state_inherit_run(), called from
@@ -110,8 +108,6 @@ rsvg_state_init (RsvgState * state)
     state->stop_color.kind = RSVG_CSS_COLOR_SPEC_INHERIT;
     state->stop_opacity.kind = RSVG_OPACITY_INHERIT;
 
-    state->has_fill_server = FALSE;
-    state->has_stroke_server = FALSE;
     state->has_stop_color = FALSE;
     state->has_stop_opacity = FALSE;
 
@@ -144,12 +140,6 @@ rsvg_state_new (void)
 static void
 rsvg_state_finalize (RsvgState * state)
 {
-    rsvg_paint_server_unref (state->fill);
-    state->fill = NULL;
-
-    rsvg_paint_server_unref (state->stroke);
-    state->stroke = NULL;
-
     if (state->state_rust) {
         rsvg_state_rust_free (state->state_rust);
         state->state_rust = NULL;
@@ -183,8 +173,6 @@ rsvg_state_clone (RsvgState * dst, const RsvgState * src)
 
     *dst = *src;
     dst->parent = parent;
-    rsvg_paint_server_ref (dst->fill);
-    rsvg_paint_server_ref (dst->stroke);
 
     dst->state_rust = rsvg_state_rust_clone(src->state_rust);
 }
@@ -201,18 +189,6 @@ rsvg_state_inherit_run (RsvgState * dst, const RsvgState * src,
                         const InheritanceFunction function,
                         gboolean inherituninheritables)
 {
-    if (function (dst->has_fill_server, src->has_fill_server)) {
-        rsvg_paint_server_ref (src->fill);
-        if (dst->fill)
-            rsvg_paint_server_unref (dst->fill);
-        dst->fill = src->fill;
-    }
-    if (function (dst->has_stroke_server, src->has_stroke_server)) {
-        rsvg_paint_server_ref (src->stroke);
-        if (dst->stroke)
-            rsvg_paint_server_unref (dst->stroke);
-        dst->stroke = src->stroke;
-    }
     if (function (dst->has_stop_color, src->has_stop_color)) {
         if (dst->stop_color.kind == RSVG_CSS_COLOR_SPEC_INHERIT) {
             dst->has_stop_color = TRUE;
@@ -338,26 +314,6 @@ rsvg_parse_style_pair (RsvgState *state,
     }
 
     switch (attr) {
-    case RSVG_ATTRIBUTE_FILL:
-    {
-        RsvgPaintServer *fill = state->fill;
-        state->fill =
-            rsvg_paint_server_parse (&state->has_fill_server, value);
-        rsvg_paint_server_unref (fill);
-    }
-    break;
-
-    case RSVG_ATTRIBUTE_STROKE:
-    {
-        RsvgPaintServer *stroke = state->stroke;
-
-        state->stroke =
-            rsvg_paint_server_parse (&state->has_stroke_server, value);
-
-        rsvg_paint_server_unref (stroke);
-    }
-    break;
-
     case RSVG_ATTRIBUTE_STOP_COLOR:
     {
         state->has_stop_color = TRUE;
@@ -950,12 +906,6 @@ rsvg_state_get_opacity (RsvgState *state)
     return rsvg_state_rust_get_opacity (state->state_rust);
 }
 
-RsvgPaintServer *
-rsvg_state_get_stroke (RsvgState *state)
-{
-    return state->stroke;
-}
-
 RsvgCssColorSpec *
 rsvg_state_get_stop_color (RsvgState *state)
 {
@@ -982,12 +932,6 @@ rsvg_state_get_current_color (RsvgState *state)
     return rsvg_state_rust_get_color (state->state_rust);
 }
 
-RsvgPaintServer *
-rsvg_state_get_fill (RsvgState *state)
-{
-    return state->fill;
-}
-
 guint32
 rsvg_state_get_flood_color (RsvgState *state)
 {
diff --git a/librsvg/rsvg-styles.h b/librsvg/rsvg-styles.h
index 5293051f..a418ecfb 100644
--- a/librsvg/rsvg-styles.h
+++ b/librsvg/rsvg-styles.h
@@ -48,12 +48,6 @@ typedef struct State State;
 struct _RsvgState {
     RsvgState *parent;
 
-    RsvgPaintServer *fill;
-    gboolean has_fill_server;
-
-    RsvgPaintServer *stroke;
-    gboolean has_stroke_server;
-
     RsvgCssColorSpec stop_color;
     gboolean has_stop_color;
 
@@ -124,9 +118,6 @@ char *rsvg_state_get_mask (RsvgState *state);
 G_GNUC_INTERNAL
 guint8 rsvg_state_get_opacity (RsvgState *state);
 
-G_GNUC_INTERNAL
-RsvgPaintServer *rsvg_state_get_stroke (RsvgState *state);
-
 G_GNUC_INTERNAL
 RsvgCssColorSpec *rsvg_state_get_stop_color (RsvgState *state);
 
@@ -136,9 +127,6 @@ RsvgOpacitySpec *rsvg_state_get_stop_opacity (RsvgState *state);
 G_GNUC_INTERNAL
 guint32 rsvg_state_get_current_color (RsvgState *state);
 
-G_GNUC_INTERNAL
-RsvgPaintServer *rsvg_state_get_fill (RsvgState *state);
-
 G_GNUC_INTERNAL
 guint32 rsvg_state_get_flood_color (RsvgState *state);
 
diff --git a/rsvg_internals/src/draw.rs b/rsvg_internals/src/draw.rs
index 77306351..cf29a450 100644
--- a/rsvg_internals/src/draw.rs
+++ b/rsvg_internals/src/draw.rs
@@ -17,9 +17,11 @@ use state::{
     Color,
     CompOp,
     FillOpacity,
+    Fill,
     FillRule,
     RsvgState,
     ShapeRendering,
+    Stroke,
     StrokeDasharray,
     StrokeDashoffset,
     StrokeLinecap,
@@ -72,9 +74,6 @@ fn stroke_and_fill(cr: &cairo::Context, draw_ctx: *mut RsvgDrawingCtx) {
     // coordinate system in patterns.
     extents.to_drawing_ctx(draw_ctx);
 
-    let fill = state::get_fill(state);
-    let stroke = state::get_stroke(state);
-
     let current_color = rstate
         .color
         .as_ref()
@@ -85,19 +84,29 @@ fn stroke_and_fill(cr: &cairo::Context, draw_ctx: *mut RsvgDrawingCtx) {
         .as_ref()
         .map_or_else(|| FillOpacity::default().0, |o| o.0);
 
-    if let Some(fill) = fill {
-        if paint_server::_set_source_rsvg_paint_server(
+    let success = match rstate.fill {
+        Some(Fill(ref fill)) => paint_server::_set_source_rsvg_paint_server(
             draw_ctx,
             fill,
             u8::from(fill_opacity),
             &extents.bbox,
             &current_color,
-        ) {
-            if stroke.is_some() {
-                cr.fill_preserve();
-            } else {
-                cr.fill();
-            }
+        ),
+
+        _ => paint_server::_set_source_rsvg_paint_server(
+            draw_ctx,
+            &Fill::default().0,
+            u8::from(fill_opacity),
+            &extents.bbox,
+            &current_color,
+        ),
+    };
+
+    if success {
+        if rstate.stroke.is_some() {
+            cr.fill_preserve();
+        } else {
+            cr.fill();
         }
     }
 
@@ -106,7 +115,7 @@ fn stroke_and_fill(cr: &cairo::Context, draw_ctx: *mut RsvgDrawingCtx) {
         .as_ref()
         .map_or_else(|| StrokeOpacity::default().0, |o| o.0);
 
-    if let Some(stroke) = stroke {
+    if let Some(Stroke(ref stroke)) = rstate.stroke {
         if paint_server::_set_source_rsvg_paint_server(
             draw_ctx,
             stroke,
@@ -326,7 +335,7 @@ fn compute_stroke_and_fill_extents(cr: &cairo::Context, state: *mut RsvgState) -
 
     // Bounding box for stroke
 
-    if state::get_stroke(state).is_some() {
+    if rstate.stroke.is_some() {
         let mut sb = RsvgBbox::new(&rstate.affine);
 
         let (x, y, w, h) = cr.stroke_extents();
@@ -384,9 +393,6 @@ pub fn draw_pango_layout(
 
     let bbox = compute_text_bbox(&ink, x, y, &rstate.affine, gravity);
 
-    let fill = state::get_fill(state);
-    let stroke = state::get_stroke(state);
-
     if !clipping {
         drawing_ctx::insert_bbox(draw_ctx, &bbox);
     }
@@ -418,17 +424,27 @@ pub fn draw_pango_layout(
         .map_or_else(|| FillOpacity::default().0, |o| o.0);
 
     if !clipping {
-        if let Some(fill) = fill {
-            if paint_server::_set_source_rsvg_paint_server(
+        let success = match rstate.fill {
+            Some(Fill(ref fill)) => paint_server::_set_source_rsvg_paint_server(
                 draw_ctx,
                 fill,
                 u8::from(fill_opacity),
                 &bbox,
                 &current_color,
-            ) {
-                pangocairo::functions::update_layout(&cr, layout);
-                pangocairo::functions::show_layout(&cr, layout);
-            }
+            ),
+
+            _ => paint_server::_set_source_rsvg_paint_server(
+                draw_ctx,
+                &Fill::default().0,
+                u8::from(fill_opacity),
+                &bbox,
+                &current_color,
+            ),
+        };
+
+        if success {
+            pangocairo::functions::update_layout(&cr, layout);
+            pangocairo::functions::show_layout(&cr, layout);
         }
     }
 
@@ -437,19 +453,20 @@ pub fn draw_pango_layout(
         .as_ref()
         .map_or_else(|| StrokeOpacity::default().0, |o| o.0);
 
-    let need_layout_path;
+    let mut need_layout_path = clipping;
 
-    if clipping {
-        need_layout_path = true;
-    } else {
-        need_layout_path = stroke.is_some()
-            && paint_server::_set_source_rsvg_paint_server(
+    if !clipping {
+        if let Some(Stroke(ref stroke)) = rstate.stroke {
+            if paint_server::_set_source_rsvg_paint_server(
                 draw_ctx,
-                stroke.unwrap(),
+                stroke,
                 u8::from(stroke_opacity),
                 &bbox,
                 &current_color,
-            );
+            ) {
+                need_layout_path = true;
+            }
+        }
     }
 
     if need_layout_path {
diff --git a/rsvg_internals/src/lib.rs b/rsvg_internals/src/lib.rs
index 075487ab..e437d3c1 100644
--- a/rsvg_internals/src/lib.rs
+++ b/rsvg_internals/src/lib.rs
@@ -82,8 +82,6 @@ pub use node::{
 
 pub use opacity::{rsvg_css_parse_opacity, OpacityKind, OpacitySpec};
 
-pub use paint_server::{rsvg_paint_server_parse, rsvg_paint_server_ref, rsvg_paint_server_unref};
-
 pub use parsers::{rsvg_css_parse_number_list, rsvg_css_parse_number_optional_number};
 
 pub use pattern::rsvg_node_pattern_new;
diff --git a/rsvg_internals/src/paint_server.rs b/rsvg_internals/src/paint_server.rs
index d4192e64..5617bff0 100644
--- a/rsvg_internals/src/paint_server.rs
+++ b/rsvg_internals/src/paint_server.rs
@@ -1,11 +1,5 @@
 use cairo;
 use cssparser;
-use glib::translate::*;
-use glib_sys;
-use libc;
-
-use std::ptr;
-use std::rc::Rc;
 
 use bbox::RsvgBbox;
 use drawing_ctx;
@@ -14,7 +8,6 @@ use gradient;
 use node::NodeType;
 use parsers::{Parse, ParseError};
 use pattern;
-use util::utf8_cstr;
 
 #[derive(Debug, Copy, Clone, PartialEq)]
 pub struct PaintServerSpread(pub cairo::enums::Extend);
@@ -43,7 +36,6 @@ impl Default for PaintServerSpread {
 
 #[derive(Debug, Clone, PartialEq)]
 pub enum PaintServer {
-    Inherit,
     None,
     Iri {
         iri: String,
@@ -60,9 +52,7 @@ impl Parse for PaintServer {
         let mut input = cssparser::ParserInput::new(s);
         let mut parser = cssparser::Parser::new(&mut input);
 
-        if parser.try(|i| i.expect_ident_matching("inherit")).is_ok() {
-            Ok(PaintServer::Inherit)
-        } else if parser.try(|i| i.expect_ident_matching("none")).is_ok() {
+        if parser.try(|i| i.expect_ident_matching("none")).is_ok() {
             Ok(PaintServer::None)
         } else if let Ok(url) = parser.try(|i| i.expect_url()) {
             let alternate = if !parser.is_exhausted() {
@@ -106,72 +96,6 @@ fn _set_source_rsvg_solid_color(
     );
 }
 
-/// Parses the paint specification, creating a new paint server object.
-/// Return value: (nullable): The newly created paint server, or NULL on error.
-///
-/// # Arguments
-///
-/// * `str` - The SVG paint specification string to parse.
-#[no_mangle]
-pub extern "C" fn rsvg_paint_server_parse(
-    inherit: *mut glib_sys::gboolean,
-    str: *const libc::c_char,
-) -> *const PaintServer {
-    if !inherit.is_null() {
-        unsafe {
-            *inherit = true.to_glib();
-        }
-    }
-
-    let paint_server = PaintServer::parse(unsafe { utf8_cstr(str) }, ());
-
-    if let Ok(PaintServer::Inherit) = paint_server {
-        if !inherit.is_null() {
-            unsafe {
-                *inherit = false.to_glib();
-            }
-        }
-    }
-
-    match paint_server {
-        Ok(m) => Rc::into_raw(Rc::new(m)),
-        Err(_) => ptr::null_mut(),
-    }
-}
-
-/// Increase references counter of `PaintServer`.
-///
-/// # Arguments
-///
-/// * `paint_server` - must be constructed with `rsvg_paint_server_parse`.
-#[no_mangle]
-pub extern "C" fn rsvg_paint_server_ref(paint_server: *const PaintServer) {
-    if paint_server.is_null() {
-        return;
-    }
-
-    let server: Rc<PaintServer> = unsafe { Rc::from_raw(paint_server) };
-
-    // forget about references
-    Rc::into_raw(server.clone());
-    Rc::into_raw(server);
-}
-
-/// Decrease references counter of `PaintServer`.
-///
-/// # Arguments
-///
-/// * `paint_server` - must be constructed with `rsvg_paint_server_parse`.
-#[no_mangle]
-pub extern "C" fn rsvg_paint_server_unref(paint_server: *const PaintServer) {
-    if paint_server.is_null() {
-        return;
-    }
-
-    // drop reference
-    unsafe { Rc::from_raw(paint_server) };
-}
-
 pub fn _set_source_rsvg_paint_server(
     c_ctx: *mut drawing_ctx::RsvgDrawingCtx,
     ps: &PaintServer,
@@ -222,10 +146,6 @@ pub fn _set_source_rsvg_paint_server(
         PaintServer::None => {
             had_paint_server = false;
         }
-
-        PaintServer::Inherit => {
-            unreachable!();
-        }
     };
 
     had_paint_server
@@ -262,11 +182,6 @@ mod tests {
         assert!(PaintServer::parse("invalid", ()).is_err());
     }
 
-    #[test]
-    fn parses_inherit() {
-        assert_eq!(PaintServer::parse("inherit", ()), Ok(PaintServer::Inherit));
-    }
-
     #[test]
     fn parses_none() {
         assert_eq!(PaintServer::parse("none", ()), Ok(PaintServer::None));
@@ -335,20 +250,4 @@ mod tests {
 
         assert!(PaintServer::parse("url(#link) invalid", ()).is_err());
     }
-
-    #[test]
-    fn paint_server_refs_and_unrefs() {
-        let rc = Rc::new(PaintServer::parse("#ffffff", ()).unwrap());
-        let weak = Rc::downgrade(&rc);
-        let ps = Rc::into_raw(rc);
-
-        rsvg_paint_server_ref(ps);
-        assert!(weak.upgrade().is_some());
-
-        rsvg_paint_server_unref(ps);
-        assert!(weak.upgrade().is_some());
-
-        rsvg_paint_server_unref(ps);
-        assert!(weak.upgrade().is_none());
-    }
 }
diff --git a/rsvg_internals/src/state.rs b/rsvg_internals/src/state.rs
index d28bd1ed..9a9ad955 100644
--- a/rsvg_internals/src/state.rs
+++ b/rsvg_internals/src/state.rs
@@ -50,6 +50,7 @@ pub struct State {
     pub direction: Option<Direction>,
     pub display: Option<Display>,
     pub enable_background: Option<EnableBackground>,
+    pub fill: Option<Fill>,
     pub fill_opacity: Option<FillOpacity>,
     pub fill_rule: Option<FillRule>,
     pub filter: Option<Filter>,
@@ -69,6 +70,7 @@ pub struct State {
     pub opacity: Option<Opacity>,
     pub overflow: Option<Overflow>,
     pub shape_rendering: Option<ShapeRendering>,
+    pub stroke: Option<Stroke>,
     pub stroke_dasharray: Option<StrokeDasharray>,
     pub stroke_dashoffset: Option<StrokeDashoffset>,
     pub stroke_line_cap: Option<StrokeLinecap>,
@@ -103,6 +105,7 @@ impl State {
             direction: Default::default(),
             display: Default::default(),
             enable_background: Default::default(),
+            fill: Default::default(),
             fill_opacity: Default::default(),
             fill_rule: Default::default(),
             filter: Default::default(),
@@ -122,6 +125,7 @@ impl State {
             opacity: Default::default(),
             overflow: Default::default(),
             shape_rendering: Default::default(),
+            stroke: Default::default(),
             stroke_dasharray: Default::default(),
             stroke_dashoffset: Default::default(),
             stroke_line_cap: Default::default(),
@@ -183,6 +187,10 @@ impl State {
                 self.enable_background = parse_property(value, ())?;
             }
 
+            Attribute::Fill => {
+                self.fill = parse_property(value, ())?;
+            }
+
             Attribute::FillOpacity => {
                 self.fill_opacity = parse_property(value, ())?;
             }
@@ -273,6 +281,10 @@ impl State {
                 self.shape_rendering = parse_property(value, ())?;
             }
 
+            Attribute::Stroke => {
+                self.stroke = parse_property(value, ())?;
+            }
+
             Attribute::StrokeDasharray => {
                 self.stroke_dasharray = parse_property(value, ())?;
             }
@@ -402,8 +414,6 @@ extern "C" {
     fn rsvg_state_parent(state: *const RsvgState) -> *mut RsvgState;
     fn rsvg_state_get_stop_color(state: *const RsvgState) -> *const color::ColorSpec;
     fn rsvg_state_get_stop_opacity(state: *const RsvgState) -> *const opacity::OpacitySpec;
-    fn rsvg_state_get_stroke(state: *const RsvgState) -> *const PaintServer;
-    fn rsvg_state_get_fill(state: *const RsvgState) -> *const PaintServer;
 
     fn rsvg_state_dominate(state: *mut RsvgState, src: *const RsvgState);
     fn rsvg_state_force(state: *mut RsvgState, src: *const RsvgState);
@@ -510,30 +520,6 @@ pub fn get_stop_opacity(state: *const RsvgState) -> Result<Option<opacity::Opaci
     }
 }
 
-pub fn get_stroke<'a>(state: *const RsvgState) -> Option<&'a PaintServer> {
-    unsafe {
-        let ps = rsvg_state_get_stroke(state);
-
-        if ps.is_null() {
-            None
-        } else {
-            Some(&*ps)
-        }
-    }
-}
-
-pub fn get_fill<'a>(state: *const RsvgState) -> Option<&'a PaintServer> {
-    unsafe {
-        let ps = rsvg_state_get_fill(state);
-
-        if ps.is_null() {
-            None
-        } else {
-            Some(&*ps)
-        }
-    }
-}
-
 pub fn dominate(state: *mut RsvgState, src: *const RsvgState) {
     unsafe {
         rsvg_state_dominate(state, src);
@@ -697,6 +683,14 @@ make_property!(
     "new" => New,
 );
 
+make_property!(
+    Fill,
+    default: PaintServer::parse("#000", ()).unwrap(),
+    inherits_automatically: true,
+    newtype_parse: PaintServer,
+    parse_data_type: ()
+);
+
 make_property!(
     FillOpacity,
     default: UnitInterval(1.0),
@@ -884,6 +878,14 @@ make_property!(
     "crispEdges" => CrispEdges,
 );
 
+make_property!(
+    Stroke,
+    default: PaintServer::parse("#000", ()).unwrap(),
+    inherits_automatically: true,
+    newtype_parse: PaintServer,
+    parse_data_type: ()
+);
+
 make_property!(
     StrokeDasharray,
     default: Dasharray::default(),
@@ -1171,6 +1173,7 @@ pub extern "C" fn rsvg_state_rust_inherit_run(
     inherit(inherit_fn, &mut dst.color, &src.color);
     inherit(inherit_fn, &mut dst.direction, &src.direction);
     inherit(inherit_fn, &mut dst.display, &src.display);
+    inherit(inherit_fn, &mut dst.fill, &src.fill);
     inherit(inherit_fn, &mut dst.fill_opacity, &src.fill_opacity);
     inherit(inherit_fn, &mut dst.fill_rule, &src.fill_rule);
     inherit(inherit_fn, &mut dst.flood_color, &src.flood_color);
@@ -1187,6 +1190,7 @@ pub extern "C" fn rsvg_state_rust_inherit_run(
     inherit(inherit_fn, &mut dst.marker_start, &src.marker_start);
     inherit(inherit_fn, &mut dst.overflow, &src.overflow);
     inherit(inherit_fn, &mut dst.shape_rendering, &src.shape_rendering);
+    inherit(inherit_fn, &mut dst.stroke, &src.stroke);
     inherit(inherit_fn, &mut dst.stroke_dasharray, &src.stroke_dasharray);
     inherit(
         inherit_fn,


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