[librsvg: 2/15] state: move CompOp to rust



commit 570acfc9632d2474676c712a061ce2a00b95ea27
Author: Paolo Borelli <pborelli gnome org>
Date:   Thu Apr 5 19:55:13 2018 +0200

    state: move CompOp to rust
    
    Note this is the first property that is not "inherit automatically".
    This means that the C version did not have has_comp_op, however
    I still kept the Option<> in rust since I think that when having
    the property explicitely set to "inherit" we should set to None.

 librsvg/rsvg-cairo-draw.c   |  8 ++++--
 librsvg/rsvg-styles.c       | 67 ++++-----------------------------------------
 librsvg/rsvg-styles.h       |  1 -
 rsvg_internals/src/draw.rs  | 44 +++++++++++++++++++++++------
 rsvg_internals/src/lib.rs   |  1 +
 rsvg_internals/src/state.rs | 56 +++++++++++++++++++++++++++++++++----
 6 files changed, 98 insertions(+), 79 deletions(-)
---
diff --git a/librsvg/rsvg-cairo-draw.c b/librsvg/rsvg-cairo-draw.c
index d77a333f..f3cac6f1 100644
--- a/librsvg/rsvg-cairo-draw.c
+++ b/librsvg/rsvg-cairo-draw.c
@@ -332,6 +332,7 @@ rsvg_cairo_push_render_stack (RsvgDrawingCtx * ctx)
     cairo_t *child_cr;
     RsvgBbox *bbox;
     RsvgState *state = rsvg_drawing_ctx_get_current_state (ctx);
+    cairo_operator_t comp_op = rsvg_state_get_comp_op (state);
     gboolean lateclip = FALSE;
     cairo_matrix_t affine;
 
@@ -357,7 +358,7 @@ rsvg_cairo_push_render_stack (RsvgDrawingCtx * ctx)
     }
 
     if (state->opacity == 0xFF
-        && !state->filter && !state->mask && !lateclip && (state->comp_op == CAIRO_OPERATOR_OVER)
+        && !state->filter && !state->mask && !lateclip && (comp_op == CAIRO_OPERATOR_OVER)
         && (state->enable_background == RSVG_ENABLE_BACKGROUND_ACCUMULATE))
         return;
 
@@ -415,6 +416,7 @@ rsvg_cairo_pop_render_stack (RsvgDrawingCtx * ctx)
     RsvgNode *lateclip = NULL;
     cairo_surface_t *surface = NULL;
     RsvgState *state = rsvg_drawing_ctx_get_current_state (ctx);
+    cairo_operator_t comp_op = rsvg_state_get_comp_op (state);
     gboolean nest, needs_destroy = FALSE;
 
     if (state->clip_path) {
@@ -430,7 +432,7 @@ rsvg_cairo_pop_render_stack (RsvgDrawingCtx * ctx)
     }
 
     if (state->opacity == 0xFF
-        && !state->filter && !state->mask && !lateclip && (state->comp_op == CAIRO_OPERATOR_OVER)
+        && !state->filter && !state->mask && !lateclip && (comp_op == CAIRO_OPERATOR_OVER)
         && (state->enable_background == RSVG_ENABLE_BACKGROUND_ACCUMULATE))
         return;
 
@@ -467,7 +469,7 @@ rsvg_cairo_pop_render_stack (RsvgDrawingCtx * ctx)
         rsvg_drawing_ctx_release_node (ctx, lateclip);
     }
 
-    cairo_set_operator (render->cr, state->comp_op);
+    cairo_set_operator (render->cr, comp_op);
 
     if (state->mask) {
         RsvgNode *mask;
diff --git a/librsvg/rsvg-styles.c b/librsvg/rsvg-styles.c
index 359a8019..84c7d6b3 100644
--- a/librsvg/rsvg-styles.c
+++ b/librsvg/rsvg-styles.c
@@ -53,11 +53,12 @@ extern void rsvg_state_rust_free(State *state);
 extern State *rsvg_state_rust_clone(State *state);
 extern cairo_matrix_t rsvg_state_rust_get_affine(const State *state);
 extern void rsvg_state_rust_set_affine(State *state, cairo_matrix_t affine);
+extern cairo_operator_t rsvg_state_rust_get_comp_op(const State *state);
 
 extern gboolean rsvg_state_rust_parse_style_pair(State *state, RsvgAttribute attr, const char *value)
     G_GNUC_WARN_UNUSED_RESULT;
 
-extern void rsvg_state_rust_inherit_run(State *dst, State *src, InheritanceFunction inherit_fn);
+extern void rsvg_state_rust_inherit_run(State *dst, State *src, InheritanceFunction inherit_fn, gboolean 
inherituninheritables);
 
 enum {
   SHAPE_RENDERING_AUTO = CAIRO_ANTIALIAS_DEFAULT,
@@ -129,7 +130,6 @@ rsvg_state_init (RsvgState * state)
 
     state->clip_rule = CAIRO_FILL_RULE_WINDING;
     state->enable_background = RSVG_ENABLE_BACKGROUND_ACCUMULATE;
-    state->comp_op = CAIRO_OPERATOR_OVER;
     state->flood_color = 0;
     state->flood_opacity = 255;
 
@@ -299,7 +299,8 @@ rsvg_state_clone (RsvgState * dst, const RsvgState * src)
 
 static void
 rsvg_state_inherit_run (RsvgState * dst, const RsvgState * src,
-                        const InheritanceFunction function, const gboolean inherituninheritables)
+                        const InheritanceFunction function,
+                        gboolean inherituninheritables)
 {
     if (function (dst->has_current_color, src->has_current_color))
         dst->current_color = src->current_color;
@@ -384,7 +385,7 @@ rsvg_state_inherit_run (RsvgState * dst, const RsvgState * src,
         dst->dash_offset = src->dash_offset;
     }
 
-    rsvg_state_rust_inherit_run (dst->state_rust, src->state_rust, function);
+    rsvg_state_rust_inherit_run (dst->state_rust, src->state_rust, function, inherituninheritables);
 
     if (inherituninheritables) {
         g_free (dst->clip_path);
@@ -395,7 +396,6 @@ rsvg_state_inherit_run (RsvgState * dst, const RsvgState * src,
         dst->filter = g_strdup (src->filter);
         dst->enable_background = src->enable_background;
         dst->opacity = src->opacity;
-        dst->comp_op = src->comp_op;
     }
 }
 
@@ -631,61 +631,6 @@ rsvg_parse_style_pair (RsvgState *state,
     }
     break;
 
-    case RSVG_ATTRIBUTE_COMP_OP:
-    {
-        if (g_str_equal (value, "clear"))
-            state->comp_op = CAIRO_OPERATOR_CLEAR;
-        else if (g_str_equal (value, "src"))
-            state->comp_op = CAIRO_OPERATOR_SOURCE;
-        else if (g_str_equal (value, "dst"))
-            state->comp_op = CAIRO_OPERATOR_DEST;
-        else if (g_str_equal (value, "src-over"))
-            state->comp_op = CAIRO_OPERATOR_OVER;
-        else if (g_str_equal (value, "dst-over"))
-            state->comp_op = CAIRO_OPERATOR_DEST_OVER;
-        else if (g_str_equal (value, "src-in"))
-            state->comp_op = CAIRO_OPERATOR_IN;
-        else if (g_str_equal (value, "dst-in"))
-            state->comp_op = CAIRO_OPERATOR_DEST_IN;
-        else if (g_str_equal (value, "src-out"))
-            state->comp_op = CAIRO_OPERATOR_OUT;
-        else if (g_str_equal (value, "dst-out"))
-            state->comp_op = CAIRO_OPERATOR_DEST_OUT;
-        else if (g_str_equal (value, "src-atop"))
-            state->comp_op = CAIRO_OPERATOR_ATOP;
-        else if (g_str_equal (value, "dst-atop"))
-            state->comp_op = CAIRO_OPERATOR_DEST_ATOP;
-        else if (g_str_equal (value, "xor"))
-            state->comp_op = CAIRO_OPERATOR_XOR;
-        else if (g_str_equal (value, "plus"))
-            state->comp_op = CAIRO_OPERATOR_ADD;
-        else if (g_str_equal (value, "multiply"))
-            state->comp_op = CAIRO_OPERATOR_MULTIPLY;
-        else if (g_str_equal (value, "screen"))
-            state->comp_op = CAIRO_OPERATOR_SCREEN;
-        else if (g_str_equal (value, "overlay"))
-            state->comp_op = CAIRO_OPERATOR_OVERLAY;
-        else if (g_str_equal (value, "darken"))
-            state->comp_op = CAIRO_OPERATOR_DARKEN;
-        else if (g_str_equal (value, "lighten"))
-            state->comp_op = CAIRO_OPERATOR_LIGHTEN;
-        else if (g_str_equal (value, "color-dodge"))
-            state->comp_op = CAIRO_OPERATOR_COLOR_DODGE;
-        else if (g_str_equal (value, "color-burn"))
-            state->comp_op = CAIRO_OPERATOR_COLOR_BURN;
-        else if (g_str_equal (value, "hard-light"))
-            state->comp_op = CAIRO_OPERATOR_HARD_LIGHT;
-        else if (g_str_equal (value, "soft-light"))
-            state->comp_op = CAIRO_OPERATOR_SOFT_LIGHT;
-        else if (g_str_equal (value, "difference"))
-            state->comp_op = CAIRO_OPERATOR_DIFFERENCE;
-        else if (g_str_equal (value, "exclusion"))
-            state->comp_op = CAIRO_OPERATOR_EXCLUSION;
-        else
-            state->comp_op = CAIRO_OPERATOR_OVER;
-    }
-    break;
-
     case RSVG_ATTRIBUTE_DISPLAY:
     {
         state->has_visible = TRUE;
@@ -1681,7 +1626,7 @@ rsvg_state_get_text_rendering_type (RsvgState *state)
 cairo_operator_t
 rsvg_state_get_comp_op (RsvgState *state)
 {
-    return state->comp_op;
+    return rsvg_state_rust_get_comp_op (state->state_rust);
 }
 
 State *
diff --git a/librsvg/rsvg-styles.h b/librsvg/rsvg-styles.h
index b6869a4c..b66005e1 100644
--- a/librsvg/rsvg-styles.h
+++ b/librsvg/rsvg-styles.h
@@ -113,7 +113,6 @@ struct _RsvgState {
     gboolean has_middleMarker;
     gboolean has_endMarker;
 
-    cairo_operator_t comp_op;
     RsvgEnableBackgroundType enable_background;
 
     cairo_antialias_t shape_rendering_type;
diff --git a/rsvg_internals/src/draw.rs b/rsvg_internals/src/draw.rs
index 7c68a161..0bbc4e81 100644
--- a/rsvg_internals/src/draw.rs
+++ b/rsvg_internals/src/draw.rs
@@ -10,14 +10,7 @@ use float_eq_cairo::ApproxEqCairo;
 use length::StrokeDasharray;
 use paint_server;
 use path_builder::PathBuilder;
-use state::{
-    self,
-    FillRule,
-    RsvgState,
-    StrokeLinecap,
-    StrokeLinejoin,
-    StrokeMiterlimit,
-};
+use state::{self, CompOp, FillRule, RsvgState, StrokeLinecap, StrokeLinejoin, StrokeMiterlimit};
 use text;
 
 pub fn draw_path_builder(draw_ctx: *mut RsvgDrawingCtx, builder: &PathBuilder, clipping: bool) {
@@ -116,6 +109,37 @@ impl From<StrokeLinecap> for cairo::LineCap {
     }
 }
 
+impl From<CompOp> for cairo::Operator {
+    fn from(op: CompOp) -> cairo::Operator {
+        match op {
+            CompOp::Clear => cairo::Operator::Clear,
+            CompOp::Src => cairo::Operator::Source,
+            CompOp::Dst => cairo::Operator::Dest,
+            CompOp::SrcOver => cairo::Operator::Over,
+            CompOp::DstOver => cairo::Operator::DestOver,
+            CompOp::SrcIn => cairo::Operator::In,
+            CompOp::DstIn => cairo::Operator::DestIn,
+            CompOp::SrcOut => cairo::Operator::Out,
+            CompOp::DstOut => cairo::Operator::DestOut,
+            CompOp::SrcAtop => cairo::Operator::Atop,
+            CompOp::DstAtop => cairo::Operator::DestAtop,
+            CompOp::Xor => cairo::Operator::Xor,
+            CompOp::Plus => cairo::Operator::Add,
+            CompOp::Multiply => cairo::Operator::Multiply,
+            CompOp::Screen => cairo::Operator::Screen,
+            CompOp::Overlay => cairo::Operator::Overlay,
+            CompOp::Darken => cairo::Operator::Darken,
+            CompOp::Lighten => cairo::Operator::Lighten,
+            CompOp::ColorDodge => cairo::Operator::ColorDodge,
+            CompOp::ColorBurn => cairo::Operator::ColorBurn,
+            CompOp::HardLight => cairo::Operator::HardLight,
+            CompOp::SoftLight => cairo::Operator::SoftLight,
+            CompOp::Difference => cairo::Operator::Difference,
+            CompOp::Exclusion => cairo::Operator::Exclusion,
+        }
+    }
+}
+
 impl From<FillRule> for cairo::FillRule {
     fn from(f: FillRule) -> cairo::FillRule {
         match f {
@@ -355,6 +379,8 @@ pub fn draw_surface(
     }
 
     let state = drawing_ctx::get_current_state(draw_ctx);
+    let rstate = state::get_state_rust(state);
+
     let cr = drawing_ctx::get_cairo_context(draw_ctx);
     let affine = state::get_state_rust(state).affine;
 
@@ -381,7 +407,7 @@ pub fn draw_surface(
     let x = x * width / w;
     let y = y * height / h;
 
-    cr.set_operator(state::get_comp_op(state));
+    cr.set_operator(cairo::Operator::from(rstate.comp_op.unwrap_or_default()));
 
     cr.set_source_surface(&surface, x, y);
     cr.paint();
diff --git a/rsvg_internals/src/lib.rs b/rsvg_internals/src/lib.rs
index 4bb0ed73..32534a2b 100644
--- a/rsvg_internals/src/lib.rs
+++ b/rsvg_internals/src/lib.rs
@@ -129,6 +129,7 @@ pub use state::{
     rsvg_state_rust_clone,
     rsvg_state_rust_free,
     rsvg_state_rust_get_affine,
+    rsvg_state_rust_get_comp_op,
     rsvg_state_rust_inherit_run,
     rsvg_state_rust_new,
     rsvg_state_rust_parse_style_pair,
diff --git a/rsvg_internals/src/state.rs b/rsvg_internals/src/state.rs
index 4aea408a..f85d8320 100644
--- a/rsvg_internals/src/state.rs
+++ b/rsvg_internals/src/state.rs
@@ -36,6 +36,7 @@ pub struct State {
     pub affine: cairo::Matrix,
 
     pub baseline_shift: Option<BaselineShift>,
+    pub comp_op: Option<CompOp>,
     pub fill_rule: Option<FillRule>,
     pub font_family: Option<FontFamily>,
     pub font_size: Option<FontSize>,
@@ -60,6 +61,7 @@ impl State {
 
             // please keep these sorted
             baseline_shift: Default::default(),
+            comp_op: Default::default(),
             fill_rule: Default::default(),
             font_family: Default::default(),
             font_size: Default::default(),
@@ -85,6 +87,10 @@ impl State {
                 self.baseline_shift = parse_property(value, ())?;
             }
 
+            Attribute::CompOp => {
+                self.comp_op = parse_property(value, ())?;
+            }
+
             Attribute::FillRule => {
                 self.fill_rule = parse_property(value, ())?;
             }
@@ -203,7 +209,6 @@ extern "C" {
     fn rsvg_state_get_clip_rule(state: *const RsvgState) -> cairo::FillRule;
     fn rsvg_state_get_fill(state: *const RsvgState) -> *const PaintServer;
     fn rsvg_state_get_fill_opacity(state: *const RsvgState) -> u8;
-    fn rsvg_state_get_comp_op(state: *const RsvgState) -> cairo::Operator;
 
     fn rsvg_state_dominate(state: *mut RsvgState, src: *const RsvgState);
     fn rsvg_state_force(state: *mut RsvgState, src: *const RsvgState);
@@ -385,10 +390,6 @@ pub fn get_fill_opacity(state: *const RsvgState) -> u8 {
     unsafe { rsvg_state_get_fill_opacity(state) }
 }
 
-pub fn get_comp_op(state: *const RsvgState) -> cairo::Operator {
-    unsafe { rsvg_state_get_comp_op(state) }
-}
-
 pub fn dominate(state: *mut RsvgState, src: *const RsvgState) {
     unsafe {
         rsvg_state_dominate(state, src);
@@ -437,6 +438,38 @@ impl Parse for BaselineShift {
     }
 }
 
+make_property!(
+    CompOp,
+    default: SrcOver,
+    inherits_automatically: false,
+
+    identifiers:
+    "clear" => Clear,
+    "src" => Src,
+    "dst" => Dst,
+    "src-over" => SrcOver,
+    "dst-over" => DstOver,
+    "src-in" => SrcIn,
+    "dst-in" => DstIn,
+    "src-out" => SrcOut,
+    "dst-out" => DstOut,
+    "src-atop" => SrcAtop,
+    "dst-atop" => DstAtop,
+    "xor" => Xor,
+    "plus" => Plus,
+    "multiply" => Multiply,
+    "screen" => Screen,
+    "overlay" => Overlay,
+    "darken" => Darken,
+    "lighten" => Lighten,
+    "color-dodge" => ColorDodge,
+    "color-burn" => ColorBurn,
+    "hard-light" => HardLight,
+    "soft-light" => SoftLight,
+    "difference" => Difference,
+    "exclusion" => Exclusion,
+);
+
 make_property!(
     FillRule,
     default: NonZero,
@@ -686,6 +719,7 @@ pub extern "C" fn rsvg_state_rust_inherit_run(
     dst: *mut State,
     src: *const State,
     inherit_fn: extern "C" fn(glib_sys::gboolean, glib_sys::gboolean) -> glib_sys::gboolean,
+    inheritunheritables: glib_sys::gboolean,
 ) {
     assert!(!dst.is_null());
     assert!(!src.is_null());
@@ -714,6 +748,10 @@ pub extern "C" fn rsvg_state_rust_inherit_run(
     inherit(inherit_fn, &mut dst.unicode_bidi, &src.unicode_bidi);
     inherit(inherit_fn, &mut dst.xml_lang, &src.xml_lang);
     inherit(inherit_fn, &mut dst.xml_space, &src.xml_space);
+
+    if from_glib(inheritunheritables) {
+        dst.comp_op.clone_from(&src.comp_op);
+    }
 }
 
 #[no_mangle]
@@ -731,3 +769,11 @@ pub extern "C" fn rsvg_state_rust_set_affine(state: *mut State, affine: cairo::M
         state.affine = affine;
     }
 }
+
+#[no_mangle]
+pub extern "C" fn rsvg_state_rust_get_comp_op(state: *const State) -> cairo::Operator {
+    unsafe {
+        let state = &*state;
+        cairo::Operator::from(state.comp_op.unwrap_or_default())
+    }
+}


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