diff --git a/canvas/src/lib.rs b/canvas/src/lib.rs index 300e6049..fab53053 100644 --- a/canvas/src/lib.rs +++ b/canvas/src/lib.rs @@ -20,7 +20,8 @@ use pathfinder_geometry::basic::transform2d::Transform2DF32; use pathfinder_geometry::color::ColorU; use pathfinder_geometry::outline::{Contour, Outline}; use pathfinder_geometry::stroke::OutlineStrokeToFill; -use pathfinder_renderer::scene::{Paint, PathObject, Scene}; +use pathfinder_renderer::paint::Paint; +use pathfinder_renderer::scene::{PathObject, Scene}; use pathfinder_text::{SceneExt, TextRenderMode}; use skribo::{FontCollection, FontFamily, TextStyle}; use std::default::Default; @@ -149,13 +150,18 @@ impl CanvasRenderingContext2D { pub fn fill_path(&mut self, path: Path2D) { let mut outline = path.into_outline(); outline.transform(&self.current_state.transform); - let paint_id = self.scene.push_paint(&self.current_state.fill_paint); + + let paint = self.current_state.resolve_paint(self.current_state.fill_paint); + let paint_id = self.scene.push_paint(&paint); + self.scene.push_path(PathObject::new(outline, paint_id, String::new())) } #[inline] pub fn stroke_path(&mut self, path: Path2D) { - let paint_id = self.scene.push_paint(&self.current_state.stroke_paint); + let paint = self.current_state.resolve_paint(self.current_state.stroke_paint); + let paint_id = self.scene.push_paint(&paint); + let stroke_width = f32::max(self.current_state.line_width, HAIRLINE_STROKE_WIDTH); let mut stroke_to_fill = OutlineStrokeToFill::new(path.into_outline(), stroke_width); stroke_to_fill.offset(); @@ -180,6 +186,18 @@ impl CanvasRenderingContext2D { self.current_state.transform = Transform2DF32::default(); } + // Compositing + + #[inline] + pub fn global_alpha(&self) -> f32 { + self.current_state.global_alpha + } + + #[inline] + pub fn set_global_alpha(&mut self, new_global_alpha: f32) { + self.current_state.global_alpha = new_global_alpha; + } + // The canvas state #[inline] @@ -203,6 +221,7 @@ pub struct State { fill_paint: Paint, stroke_paint: Paint, line_width: f32, + global_alpha: f32, } impl State { @@ -214,8 +233,14 @@ impl State { fill_paint: Paint { color: ColorU::black() }, stroke_paint: Paint { color: ColorU::black() }, line_width: 1.0, + global_alpha: 1.0, } } + + fn resolve_paint(&self, mut paint: Paint) -> Paint { + paint.color.a = (paint.color.a as f32 * self.global_alpha).round() as u8; + paint + } } #[derive(Clone)] diff --git a/examples/canvas_moire/src/main.rs b/examples/canvas_moire/src/main.rs index f5f2c0d5..2d0152d2 100644 --- a/examples/canvas_moire/src/main.rs +++ b/examples/canvas_moire/src/main.rs @@ -131,6 +131,7 @@ impl MoireRenderer { let mut canvas = CanvasRenderingContext2D::new(self.drawable_size.to_f32()); canvas.set_line_width(CIRCLE_THICKNESS * self.device_pixel_ratio); canvas.set_stroke_style(FillStyle::Color(foreground_color.to_u8())); + canvas.set_global_alpha(0.75); // Draw circles. self.draw_circles(&mut canvas, outer_center); diff --git a/text/src/lib.rs b/text/src/lib.rs index f3dd8f23..7b81ef2f 100644 --- a/text/src/lib.rs +++ b/text/src/lib.rs @@ -17,7 +17,8 @@ use pathfinder_geometry::basic::point::Point2DF32; use pathfinder_geometry::basic::transform2d::Transform2DF32; use pathfinder_geometry::outline::{Contour, Outline}; use pathfinder_geometry::stroke::OutlineStrokeToFill; -use pathfinder_renderer::scene::{PaintId, PathObject, Scene}; +use pathfinder_renderer::paint::PaintId; +use pathfinder_renderer::scene::{PathObject, Scene}; use skribo::{FontCollection, Layout, TextStyle}; use std::mem;