[librsvg] Implement FillPaint and StrokePaint



commit 10151cbb80d7a71732f35969bfb98ec9f3632dfa
Author: Ivan Molodetskikh <yalterz gmail com>
Date:   Thu Jun 14 11:37:05 2018 +0300

    Implement FillPaint and StrokePaint

 rsvg_internals/src/filters/context.rs | 49 ++++++++++++++++++++++++++++++++---
 1 file changed, 46 insertions(+), 3 deletions(-)
---
diff --git a/rsvg_internals/src/filters/context.rs b/rsvg_internals/src/filters/context.rs
index e0296e68..831cfc77 100644
--- a/rsvg_internals/src/filters/context.rs
+++ b/rsvg_internals/src/filters/context.rs
@@ -14,6 +14,8 @@ use coord_units::CoordUnits;
 use drawing_ctx::{self, RsvgDrawingCtx};
 use length::RsvgLength;
 use node::{box_node, RsvgNode};
+use paint_server::{self, PaintServer};
+use unitinterval::UnitInterval;
 
 use super::bounds::BoundsBuilder;
 use super::input::Input;
@@ -453,6 +455,39 @@ impl FilterContext {
         }
     }
 
+    /// Computes and returns a surface corresponding to the given paint server.
+    fn get_paint_server_surface(
+        &self,
+        paint_server: &PaintServer,
+        opacity: UnitInterval,
+    ) -> Result<cairo::ImageSurface, cairo::Status> {
+        let surface = cairo::ImageSurface::create(
+            cairo::Format::ARgb32,
+            self.source_surface.get_width(),
+            self.source_surface.get_height(),
+        )?;
+
+        let cr_save = drawing_ctx::get_cairo_context(self.drawing_ctx);
+        let cr = cairo::Context::new(&surface);
+        drawing_ctx::set_cairo_context(self.drawing_ctx, &cr);
+
+        let cascaded = self.node_being_filtered.get_cascaded_values();
+        let values = cascaded.get();
+
+        if paint_server::set_source_paint_server(
+            self.drawing_ctx,
+            paint_server,
+            &opacity,
+            drawing_ctx::get_bbox(self.drawing_ctx),
+            &values.color.0,
+        ) {
+            cr.paint();
+        }
+
+        drawing_ctx::set_cairo_context(self.drawing_ctx, &cr_save);
+        Ok(surface)
+    }
+
     /// Retrieves the filter input surface according to the SVG rules.
     pub fn get_input(&self, in_: Option<&Input>) -> Option<FilterInput> {
         if in_.is_none() {
@@ -466,6 +501,9 @@ impl FilterContext {
             }
         }
 
+        let cascaded = self.node_being_filtered.get_cascaded_values();
+        let values = cascaded.get();
+
         match *in_.unwrap() {
             Input::SourceGraphic => Some(FilterInput::StandardInput(self.source_graphic().clone())),
             Input::SourceAlpha => self
@@ -482,9 +520,14 @@ impl FilterContext {
                 .ok()
                 .map(FilterInput::StandardInput),
 
-            // TODO
-            Input::FillPaint => None,
-            Input::StrokePaint => None,
+            Input::FillPaint => self
+                .get_paint_server_surface(&values.fill.0, values.fill_opacity.0)
+                .ok()
+                .map(FilterInput::StandardInput),
+            Input::StrokePaint => self
+                .get_paint_server_surface(&values.stroke.0, values.stroke_opacity.0)
+                .ok()
+                .map(FilterInput::StandardInput),
 
             Input::FilterOutput(ref name) => self
                 .filter_output(name)


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