[librsvg: 4/6] drawing-ctx: move stroke_and_fill method to drawing ctx



commit a4ffab2fa8ddc7165f44be768fb6ecb1be4a2890
Author: Paolo Borelli <pborelli gnome org>
Date:   Mon Jun 25 23:05:55 2018 +0200

    drawing-ctx: move stroke_and_fill method to drawing ctx

 rsvg_internals/src/draw.rs        | 203 +-------------------------------------
 rsvg_internals/src/drawing_ctx.rs | 200 ++++++++++++++++++++++++++++++++++++-
 2 files changed, 199 insertions(+), 204 deletions(-)
---
diff --git a/rsvg_internals/src/draw.rs b/rsvg_internals/src/draw.rs
index 07a3f03b..eef90bce 100644
--- a/rsvg_internals/src/draw.rs
+++ b/rsvg_internals/src/draw.rs
@@ -1,21 +1,9 @@
 use cairo;
-use cairo_sys;
-use glib::translate::*;
 
-use bbox::BoundingBox;
 use drawing_ctx::DrawingCtx;
-use paint_server;
-use paint_server::PaintServer;
 use path_builder::PathBuilder;
 use state::{
-    ClipRule,
-    CompOp,
     ComputedValues,
-    FillRule,
-    ShapeRendering,
-    StrokeLinecap,
-    StrokeLinejoin,
-    TextRendering,
 };
 
 pub fn draw_path_builder(
@@ -34,196 +22,7 @@ pub fn draw_path_builder(
     } else {
         cr.set_fill_rule(cairo::FillRule::from(values.fill_rule));
 
-        stroke_and_fill(&cr, draw_ctx, values);
+        draw_ctx.stroke_and_fill(&cr, values);
     }
 }
 
-fn stroke_and_fill(cr: &cairo::Context, draw_ctx: &mut DrawingCtx, values: &ComputedValues) {
-    cr.set_antialias(cairo::Antialias::from(values.shape_rendering));
-
-    draw_ctx.setup_cr_for_stroke(cr, values);
-
-    // Update the bbox in the rendering context.  Below, we actually set the
-    // fill/stroke patterns on the cairo_t.  That process requires the
-    // rendering context to have an updated bbox; for example, for the
-    // coordinate system in patterns.
-    let bbox = compute_stroke_and_fill_box(cr, values);
-    draw_ctx.insert_bbox(&bbox);
-
-    let current_color = &values.color.0;
-
-    let fill_opacity = &values.fill_opacity.0;
-
-    if paint_server::set_source_paint_server(
-        draw_ctx,
-        &values.fill.0,
-        fill_opacity,
-        &bbox,
-        current_color,
-    ) {
-        if values.stroke.0 == PaintServer::None {
-            cr.fill();
-        } else {
-            cr.fill_preserve();
-        }
-    }
-
-    let stroke_opacity = values.stroke_opacity.0;
-
-    if paint_server::set_source_paint_server(
-        draw_ctx,
-        &values.stroke.0,
-        &stroke_opacity,
-        &bbox,
-        &current_color,
-    ) {
-        cr.stroke();
-    }
-
-    // clear the path in case stroke == fill == None; otherwise
-    // we leave it around from computing the bounding box
-    cr.new_path();
-}
-
-impl From<StrokeLinejoin> for cairo::LineJoin {
-    fn from(j: StrokeLinejoin) -> cairo::LineJoin {
-        match j {
-            StrokeLinejoin::Miter => cairo::LineJoin::Miter,
-            StrokeLinejoin::Round => cairo::LineJoin::Round,
-            StrokeLinejoin::Bevel => cairo::LineJoin::Bevel,
-        }
-    }
-}
-
-impl From<StrokeLinecap> for cairo::LineCap {
-    fn from(j: StrokeLinecap) -> cairo::LineCap {
-        match j {
-            StrokeLinecap::Butt => cairo::LineCap::Butt,
-            StrokeLinecap::Round => cairo::LineCap::Round,
-            StrokeLinecap::Square => cairo::LineCap::Square,
-        }
-    }
-}
-
-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<ClipRule> for cairo::FillRule {
-    fn from(c: ClipRule) -> cairo::FillRule {
-        match c {
-            ClipRule::NonZero => cairo::FillRule::Winding,
-            ClipRule::EvenOdd => cairo::FillRule::EvenOdd,
-        }
-    }
-}
-
-impl From<FillRule> for cairo::FillRule {
-    fn from(f: FillRule) -> cairo::FillRule {
-        match f {
-            FillRule::NonZero => cairo::FillRule::Winding,
-            FillRule::EvenOdd => cairo::FillRule::EvenOdd,
-        }
-    }
-}
-
-impl From<ShapeRendering> for cairo::Antialias {
-    fn from(sr: ShapeRendering) -> cairo::Antialias {
-        match sr {
-            ShapeRendering::Auto | ShapeRendering::GeometricPrecision => cairo::Antialias::Default,
-            ShapeRendering::OptimizeSpeed | ShapeRendering::CrispEdges => cairo::Antialias::None,
-        }
-    }
-}
-
-impl From<TextRendering> for cairo::Antialias {
-    fn from(tr: TextRendering) -> cairo::Antialias {
-        match tr {
-            TextRendering::Auto
-            | TextRendering::OptimizeLegibility
-            | TextRendering::GeometricPrecision => cairo::Antialias::Default,
-            TextRendering::OptimizeSpeed => cairo::Antialias::None,
-        }
-    }
-}
-
-// remove this binding once cairo-rs has Context::path_extents()
-fn path_extents(cr: &cairo::Context) -> (f64, f64, f64, f64) {
-    let mut x1: f64 = 0.0;
-    let mut y1: f64 = 0.0;
-    let mut x2: f64 = 0.0;
-    let mut y2: f64 = 0.0;
-
-    unsafe {
-        cairo_sys::cairo_path_extents(cr.to_glib_none().0, &mut x1, &mut y1, &mut x2, &mut y2);
-    }
-    (x1, y1, x2, y2)
-}
-
-fn compute_stroke_and_fill_box(cr: &cairo::Context, values: &ComputedValues) -> BoundingBox {
-    let affine = cr.get_matrix();
-
-    let mut bbox = BoundingBox::new(&affine);
-
-    // Dropping the precision of cairo's bezier subdivision, yielding 2x
-    // _rendering_ time speedups, are these rather expensive operations
-    // really needed here? */
-    let backup_tolerance = cr.get_tolerance();
-    cr.set_tolerance(1.0);
-
-    // Bounding box for fill
-    //
-    // Unlike the case for stroke, for fills we always compute the bounding box.
-    // In GNOME we have SVGs for symbolic icons where each icon has a bounding
-    // rectangle with no fill and no stroke, and inside it there are the actual
-    // paths for the icon's shape.  We need to be able to compute the bounding
-    // rectangle's extents, even when it has no fill nor stroke.
-
-    let fb = BoundingBox::new(&affine).with_ink_extents(cr.fill_extents());
-    bbox.insert(&fb);
-
-    // Bounding box for stroke
-
-    if values.stroke.0 != PaintServer::None {
-        let sb = BoundingBox::new(&affine).with_ink_extents(cr.stroke_extents());
-        bbox.insert(&sb);
-    }
-
-    // objectBoundingBox
-
-    let ob = BoundingBox::new(&affine).with_extents(path_extents(cr));
-    bbox.insert(&ob);
-
-    // restore tolerance
-
-    cr.set_tolerance(backup_tolerance);
-
-    bbox
-}
diff --git a/rsvg_internals/src/drawing_ctx.rs b/rsvg_internals/src/drawing_ctx.rs
index 9c28819e..331072d3 100644
--- a/rsvg_internals/src/drawing_ctx.rs
+++ b/rsvg_internals/src/drawing_ctx.rs
@@ -19,13 +19,19 @@ use float_eq_cairo::ApproxEqCairo;
 use length::Dasharray;
 use mask::NodeMask;
 use node::{rc_node_ptr_eq, CascadedValues, NodeType, RsvgNode};
-use paint_server;
+use paint_server::{self, PaintServer};
 use rect::RectangleExt;
 use state::{
+    ClipRule,
     CompOp,
     ComputedValues,
     EnableBackground,
+    FillRule,
+    ShapeRendering,
     StrokeDasharray,
+    StrokeLinecap,
+    StrokeLinejoin,
+    TextRendering,
 };
 use unitinterval::UnitInterval;
 use viewbox::ViewBox;
@@ -502,7 +508,7 @@ impl<'a> DrawingCtx {
         cr.restore();
     }
 
-    pub fn setup_cr_for_stroke(&self, cr: &cairo::Context, values: &ComputedValues) {
+    fn setup_cr_for_stroke(&self, cr: &cairo::Context, values: &ComputedValues) {
         cr.set_line_width(values.stroke_width.0.normalize(values, self));
         cr.set_miter_limit(values.stroke_miterlimit.0);
         cr.set_line_cap(cairo::LineCap::from(values.stroke_line_cap));
@@ -523,6 +529,53 @@ impl<'a> DrawingCtx {
         }
     }
 
+    pub fn stroke_and_fill(&mut self, cr: &cairo::Context, values: &ComputedValues) {
+        cr.set_antialias(cairo::Antialias::from(values.shape_rendering));
+
+        self.setup_cr_for_stroke(cr, values);
+
+        // Update the bbox in the rendering context.  Below, we actually set the
+        // fill/stroke patterns on the cairo_t.  That process requires the
+        // rendering context to have an updated bbox; for example, for the
+        // coordinate system in patterns.
+        let bbox = compute_stroke_and_fill_box(cr, values);
+        self.insert_bbox(&bbox);
+
+        let current_color = &values.color.0;
+
+        let fill_opacity = &values.fill_opacity.0;
+
+        if paint_server::set_source_paint_server(
+            self,
+            &values.fill.0,
+            fill_opacity,
+            &bbox,
+            current_color,
+        ) {
+            if values.stroke.0 == PaintServer::None {
+                cr.fill();
+            } else {
+                cr.fill_preserve();
+            }
+        }
+
+        let stroke_opacity = values.stroke_opacity.0;
+
+        if paint_server::set_source_paint_server(
+            self,
+            &values.stroke.0,
+            &stroke_opacity,
+            &bbox,
+            &current_color,
+        ) {
+            cr.stroke();
+        }
+
+        // clear the path in case stroke == fill == None; otherwise
+        // we leave it around from computing the bounding box
+        cr.new_path();
+    }
+
     pub fn set_affine_on_cr(&self, cr: &cairo::Context) {
         let (x0, y0) = self.get_offset();
         let affine = cr.get_matrix();
@@ -674,6 +727,149 @@ fn compute_text_bbox(
     bbox
 }
 
+fn compute_stroke_and_fill_box(cr: &cairo::Context, values: &ComputedValues) -> BoundingBox {
+    let affine = cr.get_matrix();
+
+    let mut bbox = BoundingBox::new(&affine);
+
+    // Dropping the precision of cairo's bezier subdivision, yielding 2x
+    // _rendering_ time speedups, are these rather expensive operations
+    // really needed here? */
+    let backup_tolerance = cr.get_tolerance();
+    cr.set_tolerance(1.0);
+
+    // Bounding box for fill
+    //
+    // Unlike the case for stroke, for fills we always compute the bounding box.
+    // In GNOME we have SVGs for symbolic icons where each icon has a bounding
+    // rectangle with no fill and no stroke, and inside it there are the actual
+    // paths for the icon's shape.  We need to be able to compute the bounding
+    // rectangle's extents, even when it has no fill nor stroke.
+
+    let fb = BoundingBox::new(&affine).with_ink_extents(cr.fill_extents());
+    bbox.insert(&fb);
+
+    // Bounding box for stroke
+
+    if values.stroke.0 != PaintServer::None {
+        let sb = BoundingBox::new(&affine).with_ink_extents(cr.stroke_extents());
+        bbox.insert(&sb);
+    }
+
+    // objectBoundingBox
+
+    let ob = BoundingBox::new(&affine).with_extents(path_extents(cr));
+    bbox.insert(&ob);
+
+    // restore tolerance
+
+    cr.set_tolerance(backup_tolerance);
+
+    bbox
+}
+
+// remove this binding once cairo-rs has Context::path_extents()
+fn path_extents(cr: &cairo::Context) -> (f64, f64, f64, f64) {
+    let mut x1: f64 = 0.0;
+    let mut y1: f64 = 0.0;
+    let mut x2: f64 = 0.0;
+    let mut y2: f64 = 0.0;
+
+    unsafe {
+        cairo_sys::cairo_path_extents(cr.to_glib_none().0, &mut x1, &mut y1, &mut x2, &mut y2);
+    }
+    (x1, y1, x2, y2)
+}
+
+impl From<StrokeLinejoin> for cairo::LineJoin {
+    fn from(j: StrokeLinejoin) -> cairo::LineJoin {
+        match j {
+            StrokeLinejoin::Miter => cairo::LineJoin::Miter,
+            StrokeLinejoin::Round => cairo::LineJoin::Round,
+            StrokeLinejoin::Bevel => cairo::LineJoin::Bevel,
+        }
+    }
+}
+
+impl From<StrokeLinecap> for cairo::LineCap {
+    fn from(j: StrokeLinecap) -> cairo::LineCap {
+        match j {
+            StrokeLinecap::Butt => cairo::LineCap::Butt,
+            StrokeLinecap::Round => cairo::LineCap::Round,
+            StrokeLinecap::Square => cairo::LineCap::Square,
+        }
+    }
+}
+
+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<ClipRule> for cairo::FillRule {
+    fn from(c: ClipRule) -> cairo::FillRule {
+        match c {
+            ClipRule::NonZero => cairo::FillRule::Winding,
+            ClipRule::EvenOdd => cairo::FillRule::EvenOdd,
+        }
+    }
+}
+
+impl From<FillRule> for cairo::FillRule {
+    fn from(f: FillRule) -> cairo::FillRule {
+        match f {
+            FillRule::NonZero => cairo::FillRule::Winding,
+            FillRule::EvenOdd => cairo::FillRule::EvenOdd,
+        }
+    }
+}
+
+impl From<ShapeRendering> for cairo::Antialias {
+    fn from(sr: ShapeRendering) -> cairo::Antialias {
+        match sr {
+            ShapeRendering::Auto | ShapeRendering::GeometricPrecision => cairo::Antialias::Default,
+            ShapeRendering::OptimizeSpeed | ShapeRendering::CrispEdges => cairo::Antialias::None,
+        }
+    }
+}
+
+impl From<TextRendering> for cairo::Antialias {
+    fn from(tr: TextRendering) -> cairo::Antialias {
+        match tr {
+            TextRendering::Auto
+            | TextRendering::OptimizeLegibility
+            | TextRendering::GeometricPrecision => cairo::Antialias::Default,
+            TextRendering::OptimizeSpeed => cairo::Antialias::None,
+        }
+    }
+}
+
 #[no_mangle]
 pub extern "C" fn rsvg_drawing_ctx_draw_node_from_stack(
     raw_draw_ctx: *mut RsvgDrawingCtx,


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