diff options
Diffstat (limited to 'components/canvas/canvas_paint_task.rs')
-rw-r--r-- | components/canvas/canvas_paint_task.rs | 118 |
1 files changed, 108 insertions, 10 deletions
diff --git a/components/canvas/canvas_paint_task.rs b/components/canvas/canvas_paint_task.rs index 6d7b0c0fb18..6843e4f3c07 100644 --- a/components/canvas/canvas_paint_task.rs +++ b/components/canvas/canvas_paint_task.rs @@ -2,9 +2,10 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use azure::azure_hl::{DrawTarget, SurfaceFormat, BackendType, StrokeOptions, DrawOptions}; -use azure::azure_hl::{ColorPattern, PatternRef, JoinStyle, CapStyle, DrawSurfaceOptions, Filter}; -use azure::AzFloat; +use azure::azure::AzFloat; +use azure::azure_hl::{DrawTarget, SurfaceFormat, BackendType, StrokeOptions, DrawOptions, Pattern}; +use azure::azure_hl::{ColorPattern, PathBuilder, JoinStyle, CapStyle, DrawSurfaceOptions, Filter}; +use geom::matrix2d::Matrix2D; use geom::point::Point2D; use geom::rect::Rect; use geom::size::Size2D; @@ -12,6 +13,7 @@ use gfx::color; use util::task::spawn_named; use util::vec::byte_swap; +use cssparser::RGBA; use std::borrow::ToOwned; use std::ops::Add; use std::sync::mpsc::{channel, Sender}; @@ -21,6 +23,14 @@ pub enum CanvasMsg { FillRect(Rect<f32>), ClearRect(Rect<f32>), StrokeRect(Rect<f32>), + BeginPath, + ClosePath, + Fill, + MoveTo(Point2D<f32>), + BezierCurveTo(Point2D<f32>, Point2D<f32>, Point2D<f32>), + SetFillStyle(FillOrStrokeStyle), + SetStrokeStyle(FillOrStrokeStyle), + SetTransform(Matrix2D<f32>), Recreate(Size2D<i32>), SendPixelContents(Sender<Vec<u8>>), GetImageData(Rect<i32>, Size2D<i32>, Sender<Vec<u8>>), @@ -30,18 +40,26 @@ pub enum CanvasMsg { pub struct CanvasPaintTask<'a> { drawtarget: DrawTarget, - fill_color: ColorPattern, - stroke_color: ColorPattern, + fill_style: Pattern, + stroke_style: Pattern, stroke_opts: StrokeOptions<'a>, + /// TODO(pcwalton): Support multiple paths. + path_builder: PathBuilder, + /// The current 2D transform matrix. + transform: Matrix2D<f32>, } impl<'a> CanvasPaintTask<'a> { fn new(size: Size2D<i32>) -> CanvasPaintTask<'a> { + let draw_target = CanvasPaintTask::create(size); + let path_builder = draw_target.create_path_builder(); CanvasPaintTask { - drawtarget: CanvasPaintTask::create(size), - fill_color: ColorPattern::new(color::black()), - stroke_color: ColorPattern::new(color::black()), + drawtarget: draw_target, + fill_style: Pattern::Color(ColorPattern::new(color::black())), + stroke_style: Pattern::Color(ColorPattern::new(color::black())), stroke_opts: StrokeOptions::new(1.0, JoinStyle::MiterOrBevel, CapStyle::Butt, 1.0, &[]), + path_builder: path_builder, + transform: Matrix2D::identity(), } } @@ -55,6 +73,16 @@ impl<'a> CanvasPaintTask<'a> { CanvasMsg::FillRect(ref rect) => painter.fill_rect(rect), CanvasMsg::StrokeRect(ref rect) => painter.stroke_rect(rect), CanvasMsg::ClearRect(ref rect) => painter.clear_rect(rect), + CanvasMsg::BeginPath => painter.begin_path(), + CanvasMsg::ClosePath => painter.close_path(), + CanvasMsg::Fill => painter.fill(), + CanvasMsg::MoveTo(ref point) => painter.move_to(point), + CanvasMsg::BezierCurveTo(ref cp1, ref cp2, ref pt) => { + painter.bezier_curve_to(cp1, cp2, pt) + } + CanvasMsg::SetFillStyle(style) => painter.set_fill_style(style), + CanvasMsg::SetStrokeStyle(style) => painter.set_stroke_style(style), + CanvasMsg::SetTransform(ref matrix) => painter.set_transform(matrix), CanvasMsg::Recreate(size) => painter.recreate(size), CanvasMsg::SendPixelContents(chan) => painter.send_pixel_contents(chan), CanvasMsg::GetImageData(dest_rect, canvas_size, chan) => painter.get_image_data(dest_rect, canvas_size, chan), @@ -69,7 +97,7 @@ impl<'a> CanvasPaintTask<'a> { fn fill_rect(&self, rect: &Rect<f32>) { let drawopts = DrawOptions::new(1.0, 0); - self.drawtarget.fill_rect(rect, PatternRef::Color(&self.fill_color), Some(&drawopts)); + self.drawtarget.fill_rect(rect, self.fill_style.to_pattern_ref(), Some(&drawopts)); } fn clear_rect(&self, rect: &Rect<f32>) { @@ -78,7 +106,58 @@ impl<'a> CanvasPaintTask<'a> { fn stroke_rect(&self, rect: &Rect<f32>) { let drawopts = DrawOptions::new(1.0, 0); - self.drawtarget.stroke_rect(rect, &self.stroke_color, &self.stroke_opts, &drawopts); + match self.stroke_style { + Pattern::Color(ref color) => { + self.drawtarget.stroke_rect(rect, color, &self.stroke_opts, &drawopts) + } + _ => { + // TODO(pcwalton) + } + }; + } + + fn begin_path(&mut self) { + self.path_builder = self.drawtarget.create_path_builder() + } + + fn close_path(&self) { + self.path_builder.close() + } + + fn fill(&self) { + let draw_options = DrawOptions::new(1.0, 0); + match self.fill_style { + Pattern::Color(ref color) => { + self.drawtarget.fill(&self.path_builder.finish(), color, &draw_options); + } + _ => { + // TODO(pcwalton) + } + }; + } + + fn move_to(&self, point: &Point2D<AzFloat>) { + self.path_builder.move_to(*point) + } + + fn bezier_curve_to(&self, + cp1: &Point2D<AzFloat>, + cp2: &Point2D<AzFloat>, + endpoint: &Point2D<AzFloat>) { + self.path_builder.bezier_curve_to(cp1, cp2, endpoint) + } + + fn set_fill_style(&mut self, style: FillOrStrokeStyle) { + self.fill_style = style.to_azure_pattern() + } + + fn set_stroke_style(&mut self, style: FillOrStrokeStyle) { + self.stroke_style = style.to_azure_pattern() + } + + fn set_transform(&mut self, transform: &Matrix2D<f32>) { + self.transform = *transform; + self.drawtarget.set_transform(transform) } fn create(size: Size2D<i32>) -> DrawTarget { @@ -192,3 +271,22 @@ impl<'a> CanvasPaintTask<'a> { } } } + +#[derive(Clone)] +pub enum FillOrStrokeStyle { + Color(RGBA), +} + +impl FillOrStrokeStyle { + fn to_azure_pattern(&self) -> Pattern { + match *self { + FillOrStrokeStyle::Color(ref color) => { + Pattern::Color(ColorPattern::new(color::new(color.red, + color.green, + color.blue, + color.alpha))) + } + } + } +} + |