mirror of
https://github.com/servo/servo.git
synced 2025-07-22 23:03:42 +01:00
script: Implement enough 2D canvas support to render basic SVGs such as the tiger.
This commit is contained in:
parent
287f390c4a
commit
55a0ee6ec7
28 changed files with 419 additions and 181 deletions
|
@ -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)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue