aboutsummaryrefslogtreecommitdiffstats
path: root/components/canvas/canvas_paint_task.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/canvas/canvas_paint_task.rs')
-rw-r--r--components/canvas/canvas_paint_task.rs118
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)))
+ }
+ }
+ }
+}
+