aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/canvas/canvas_paint_task.rs78
-rw-r--r--components/script/dom/canvasrenderingcontext2d.rs150
-rw-r--r--components/script/dom/webidls/CanvasRenderingContext2D.webidl4
-rw-r--r--components/servo/Cargo.lock2
-rw-r--r--ports/cef/Cargo.lock3
-rw-r--r--ports/gonk/Cargo.lock3
-rw-r--r--tests/wpt/metadata/2dcontext/line-styles/2d.line.width.transformed.html.ini5
-rw-r--r--tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.bitmap.html.ini5
-rw-r--r--tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.fillStyle.html.ini5
-rw-r--r--tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.globalAlpha.html.ini5
-rw-r--r--tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.lineCap.html.ini5
-rw-r--r--tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.lineJoin.html.ini5
-rw-r--r--tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.lineWidth.html.ini5
-rw-r--r--tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.miterLimit.html.ini5
-rw-r--r--tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.stack.html.ini5
-rw-r--r--tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.stackdepth.html.ini5
-rw-r--r--tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.strokeStyle.html.ini5
-rw-r--r--tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.transformation.html.ini5
-rw-r--r--tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.underflow.html.ini5
-rw-r--r--tests/wpt/metadata/2dcontext/transformations/2d.transformation.scale.negative.html.ini5
-rw-r--r--tests/wpt/metadata/html/dom/interfaces.html.ini12
21 files changed, 157 insertions, 165 deletions
diff --git a/components/canvas/canvas_paint_task.rs b/components/canvas/canvas_paint_task.rs
index ade01e4b909..f45c4d79c14 100644
--- a/components/canvas/canvas_paint_task.rs
+++ b/components/canvas/canvas_paint_task.rs
@@ -16,11 +16,14 @@ use util::vec::byte_swap;
use cssparser::RGBA;
use std::borrow::ToOwned;
+use std::mem;
use std::num::{Float, ToPrimitive};
use std::sync::mpsc::{channel, Sender};
#[derive(Clone)]
pub enum CanvasMsg {
+ SaveContext,
+ RestoreContext,
FillRect(Rect<f32>),
ClearRect(Rect<f32>),
StrokeRect(Rect<f32>),
@@ -109,7 +112,7 @@ impl<'a> CanvasPaintTask<'a> {
image_size, image_size.width * 4, SurfaceFormat::B8G8R8A8);
let draw_surface_options = DrawSurfaceOptions::new(filter, true);
- let draw_options = DrawOptions::new(self.draw_options.alpha, 0);
+ let draw_options = DrawOptions::new(self.state.draw_options.alpha, 0);
self.drawtarget.draw_surface(source_surface,
dest_rect.to_azfloat(),
@@ -186,28 +189,43 @@ impl<'a> CanvasPaintTask<'a> {
pub struct CanvasPaintTask<'a> {
drawtarget: DrawTarget,
+ /// TODO(pcwalton): Support multiple paths.
+ path_builder: PathBuilder,
+ state: CanvasPaintState<'a>,
+ saved_states: Vec<CanvasPaintState<'a>>,
+}
+
+#[derive(Clone)]
+struct CanvasPaintState<'a> {
draw_options: DrawOptions,
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> CanvasPaintState<'a> {
+ fn new() -> CanvasPaintState<'a> {
+ CanvasPaintState {
+ draw_options: DrawOptions::new(1.0, 0),
+ 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, 10.0, &[]),
+ transform: Matrix2D::identity(),
+ }
+ }
+}
+
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: draw_target,
- draw_options: DrawOptions::new(1.0, 0),
- 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, 10.0, &[]),
path_builder: path_builder,
- transform: Matrix2D::identity(),
+ state: CanvasPaintState::new(),
+ saved_states: Vec::new(),
}
}
@@ -218,6 +236,8 @@ impl<'a> CanvasPaintTask<'a> {
loop {
match port.recv().unwrap() {
+ CanvasMsg::SaveContext => painter.save_context_state(),
+ CanvasMsg::RestoreContext => painter.restore_context_state(),
CanvasMsg::FillRect(ref rect) => painter.fill_rect(rect),
CanvasMsg::StrokeRect(ref rect) => painter.stroke_rect(rect),
CanvasMsg::ClearRect(ref rect) => painter.clear_rect(rect),
@@ -265,8 +285,20 @@ impl<'a> CanvasPaintTask<'a> {
chan
}
+ fn save_context_state(&mut self) {
+ self.saved_states.push(self.state.clone());
+ }
+
+ fn restore_context_state(&mut self) {
+ if let Some(state) = self.saved_states.pop() {
+ mem::replace(&mut self.state, state);
+ self.drawtarget.set_transform(&self.state.transform);
+ }
+ }
+
fn fill_rect(&self, rect: &Rect<f32>) {
- self.drawtarget.fill_rect(rect, self.fill_style.to_pattern_ref(), Some(&self.draw_options));
+ self.drawtarget.fill_rect(rect, self.state.fill_style.to_pattern_ref(),
+ Some(&self.state.draw_options));
}
fn clear_rect(&self, rect: &Rect<f32>) {
@@ -274,9 +306,9 @@ impl<'a> CanvasPaintTask<'a> {
}
fn stroke_rect(&self, rect: &Rect<f32>) {
- match self.stroke_style {
+ match self.state.stroke_style {
Pattern::Color(ref color) => {
- self.drawtarget.stroke_rect(rect, color, &self.stroke_opts, &self.draw_options)
+ self.drawtarget.stroke_rect(rect, color, &self.state.stroke_opts, &self.state.draw_options)
}
_ => {
// TODO(pcwalton)
@@ -293,9 +325,9 @@ impl<'a> CanvasPaintTask<'a> {
}
fn fill(&self) {
- match self.fill_style {
+ match self.state.fill_style {
Pattern::Color(ref color) => {
- self.drawtarget.fill(&self.path_builder.finish(), color, &self.draw_options);
+ self.drawtarget.fill(&self.path_builder.finish(), color, &self.state.draw_options);
}
_ => {
// TODO(pcwalton)
@@ -304,10 +336,10 @@ impl<'a> CanvasPaintTask<'a> {
}
fn stroke(&self) {
- match self.stroke_style {
+ match self.state.stroke_style {
Pattern::Color(ref color) => {
self.drawtarget.stroke(&self.path_builder.finish(),
- color, &self.stroke_opts, &self.draw_options);
+ color, &self.state.stroke_opts, &self.state.draw_options);
}
_ => {
// TODO
@@ -420,36 +452,36 @@ impl<'a> CanvasPaintTask<'a> {
}
fn set_fill_style(&mut self, style: FillOrStrokeStyle) {
- self.fill_style = style.to_azure_pattern(&self.drawtarget)
+ self.state.fill_style = style.to_azure_pattern(&self.drawtarget)
}
fn set_stroke_style(&mut self, style: FillOrStrokeStyle) {
- self.stroke_style = style.to_azure_pattern(&self.drawtarget)
+ self.state.stroke_style = style.to_azure_pattern(&self.drawtarget)
}
fn set_line_width(&mut self, width: f32) {
- self.stroke_opts.line_width = width;
+ self.state.stroke_opts.line_width = width;
}
fn set_line_cap(&mut self, cap: LineCapStyle) {
- self.stroke_opts.line_cap = cap.to_azure_style();
+ self.state.stroke_opts.line_cap = cap.to_azure_style();
}
fn set_line_join(&mut self, join: LineJoinStyle) {
- self.stroke_opts.line_join = join.to_azure_style();
+ self.state.stroke_opts.line_join = join.to_azure_style();
}
fn set_miter_limit(&mut self, limit: f32) {
- self.stroke_opts.miter_limit = limit;
+ self.state.stroke_opts.miter_limit = limit;
}
fn set_transform(&mut self, transform: &Matrix2D<f32>) {
- self.transform = *transform;
+ self.state.transform = *transform;
self.drawtarget.set_transform(transform)
}
fn set_global_alpha(&mut self, alpha: f32) {
- self.draw_options.alpha = alpha;
+ self.state.draw_options.alpha = alpha;
}
fn create(size: Size2D<i32>) -> DrawTarget {
diff --git a/components/script/dom/canvasrenderingcontext2d.rs b/components/script/dom/canvasrenderingcontext2d.rs
index c88c59a9d75..f19b32242ae 100644
--- a/components/script/dom/canvasrenderingcontext2d.rs
+++ b/components/script/dom/canvasrenderingcontext2d.rs
@@ -36,7 +36,7 @@ use net_traits::image_cache_task::{ImageResponseMsg, Msg};
use png::PixelsByColorType;
use std::borrow::ToOwned;
-use std::cell::Cell;
+use std::cell::RefCell;
use std::num::{Float, ToPrimitive};
use std::sync::{Arc};
use std::sync::mpsc::{channel, Sender};
@@ -52,40 +52,56 @@ pub struct CanvasRenderingContext2D {
global: GlobalField,
renderer: Sender<CanvasMsg>,
canvas: JS<HTMLCanvasElement>,
- global_alpha: Cell<f64>,
- image_smoothing_enabled: Cell<bool>,
- stroke_color: Cell<RGBA>,
- line_width: Cell<f64>,
- line_cap: Cell<LineCapStyle>,
- line_join: Cell<LineJoinStyle>,
- miter_limit: Cell<f64>,
- fill_color: Cell<RGBA>,
- transform: Cell<Matrix2D<f32>>,
+ state: RefCell<CanvasContextState>,
+ saved_states: RefCell<Vec<CanvasContextState>>,
}
-impl CanvasRenderingContext2D {
- fn new_inherited(global: GlobalRef, canvas: JSRef<HTMLCanvasElement>, size: Size2D<i32>)
- -> CanvasRenderingContext2D {
+#[derive(Clone)]
+#[jstraceable]
+struct CanvasContextState {
+ global_alpha: f64,
+ image_smoothing_enabled: bool,
+ stroke_color: RGBA,
+ line_width: f64,
+ line_cap: LineCapStyle,
+ line_join: LineJoinStyle,
+ miter_limit: f64,
+ fill_color: RGBA,
+ transform: Matrix2D<f32>,
+}
+
+impl CanvasContextState {
+ fn new() -> CanvasContextState {
let black = RGBA {
red: 0.0,
green: 0.0,
blue: 0.0,
alpha: 1.0,
};
+ CanvasContextState {
+ global_alpha: 1.0,
+ image_smoothing_enabled: true,
+ stroke_color: black,
+ line_width: 1.0,
+ line_cap: LineCapStyle::Butt,
+ line_join: LineJoinStyle::Miter,
+ miter_limit: 10.0,
+ fill_color: black,
+ transform: Matrix2D::identity(),
+ }
+ }
+}
+
+impl CanvasRenderingContext2D {
+ fn new_inherited(global: GlobalRef, canvas: JSRef<HTMLCanvasElement>, size: Size2D<i32>)
+ -> CanvasRenderingContext2D {
CanvasRenderingContext2D {
reflector_: Reflector::new(),
global: GlobalField::from_rooted(&global),
renderer: CanvasPaintTask::start(size),
canvas: JS::from_rooted(canvas),
- global_alpha: Cell::new(1.0),
- image_smoothing_enabled: Cell::new(true),
- stroke_color: Cell::new(black),
- line_width: Cell::new(1.0),
- line_cap: Cell::new(LineCapStyle::Butt),
- line_join: Cell::new(LineJoinStyle::Miter),
- miter_limit: Cell::new(10.0),
- fill_color: Cell::new(black),
- transform: Cell::new(Matrix2D::identity()),
+ state: RefCell::new(CanvasContextState::new()),
+ saved_states: RefCell::new(Vec::new()),
}
}
@@ -100,7 +116,7 @@ impl CanvasRenderingContext2D {
}
fn update_transform(&self) {
- self.renderer.send(CanvasMsg::SetTransform(self.transform.get())).unwrap()
+ self.renderer.send(CanvasMsg::SetTransform(self.state.borrow().transform)).unwrap()
}
// It is used by DrawImage to calculate the size of the source and destination rectangles based
@@ -184,7 +200,7 @@ impl CanvasRenderingContext2D {
return Err(IndexSize)
}
- let smoothing_enabled = self.image_smoothing_enabled.get();
+ let smoothing_enabled = self.state.borrow().image_smoothing_enabled;
// If the source and target canvas are the same
let msg = if self.canvas.root().r() == canvas {
@@ -216,7 +232,7 @@ impl CanvasRenderingContext2D {
return Err(IndexSize)
}
- let smoothing_enabled = self.image_smoothing_enabled.get();
+ let smoothing_enabled = self.state.borrow().image_smoothing_enabled;
self.renderer.send(CanvasMsg::DrawImage(
image_data, image_size, dest_rect,
source_rect, smoothing_enabled)).unwrap();
@@ -318,13 +334,29 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
Temporary::new(self.canvas)
}
+ // https://html.spec.whatwg.org/multipage/#dom-context-2d-save
+ fn Save(self) {
+ self.saved_states.borrow_mut().push(self.state.borrow().clone());
+ self.renderer.send(CanvasMsg::SaveContext).unwrap();
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-context-2d-restore
+ fn Restore(self) {
+ let mut saved_states = self.saved_states.borrow_mut();
+ if let Some(state) = saved_states.pop() {
+ self.state.borrow_mut().clone_from(&state);
+ self.renderer.send(CanvasMsg::RestoreContext).unwrap();
+ }
+ }
+
// https://html.spec.whatwg.org/multipage/#dom-context-2d-scale
fn Scale(self, x: f64, y: f64) {
if !(x.is_finite() && y.is_finite()) {
return;
}
- self.transform.set(self.transform.get().scale(x as f32, y as f32));
+ let transform = self.state.borrow().transform;
+ self.state.borrow_mut().transform = transform.scale(x as f32, y as f32);
self.update_transform()
}
@@ -334,7 +366,8 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
return;
}
- self.transform.set(self.transform.get().translate(x as f32, y as f32));
+ let transform = self.state.borrow().transform;
+ self.state.borrow_mut().transform = transform.translate(x as f32, y as f32);
self.update_transform()
}
@@ -345,12 +378,13 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
return;
}
- self.transform.set(self.transform.get().mul(&Matrix2D::new(a as f32,
- b as f32,
- c as f32,
- d as f32,
- e as f32,
- f as f32)));
+ let transform = self.state.borrow().transform;
+ self.state.borrow_mut().transform = transform.mul(&Matrix2D::new(a as f32,
+ b as f32,
+ c as f32,
+ d as f32,
+ e as f32,
+ f as f32));
self.update_transform()
}
@@ -361,18 +395,19 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
return;
}
- self.transform.set(Matrix2D::new(a as f32,
- b as f32,
- c as f32,
- d as f32,
- e as f32,
- f as f32));
+ self.state.borrow_mut().transform = Matrix2D::new(a as f32,
+ b as f32,
+ c as f32,
+ d as f32,
+ e as f32,
+ f as f32);
self.update_transform()
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-globalalpha
fn GlobalAlpha(self) -> f64 {
- self.global_alpha.get()
+ let state = self.state.borrow();
+ state.global_alpha
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-globalalpha
@@ -381,7 +416,7 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
return;
}
- self.global_alpha.set(alpha);
+ self.state.borrow_mut().global_alpha = alpha;
self.renderer.send(CanvasMsg::SetGlobalAlpha(alpha as f32)).unwrap()
}
@@ -661,12 +696,13 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
// https://html.spec.whatwg.org/#dom-context-2d-imagesmoothingenabled
fn ImageSmoothingEnabled(self) -> bool {
- self.image_smoothing_enabled.get()
+ let state = self.state.borrow();
+ state.image_smoothing_enabled
}
// https://html.spec.whatwg.org/#dom-context-2d-imagesmoothingenabled
fn SetImageSmoothingEnabled(self, value: bool) -> () {
- self.image_smoothing_enabled.set(value);
+ self.state.borrow_mut().image_smoothing_enabled = value;
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle
@@ -675,7 +711,7 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
//
// https://html.spec.whatwg.org/multipage/#serialisation-of-a-colour
let mut result = String::new();
- self.stroke_color.get().to_css(&mut result).unwrap();
+ self.state.borrow().stroke_color.to_css(&mut result).unwrap();
StringOrCanvasGradientOrCanvasPattern::eString(result)
}
@@ -685,7 +721,7 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
StringOrCanvasGradientOrCanvasPattern::eString(string) => {
match parse_color(&string) {
Ok(rgba) => {
- self.stroke_color.set(rgba);
+ self.state.borrow_mut().stroke_color = rgba;
self.renderer
.send(CanvasMsg::SetStrokeStyle(FillOrStrokeStyle::Color(rgba)))
.unwrap();
@@ -705,7 +741,7 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
//
// https://html.spec.whatwg.org/multipage/#serialisation-of-a-colour
let mut result = String::new();
- self.stroke_color.get().to_css(&mut result).unwrap();
+ self.state.borrow().stroke_color.to_css(&mut result).unwrap();
StringOrCanvasGradientOrCanvasPattern::eString(result)
}
@@ -715,7 +751,7 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
StringOrCanvasGradientOrCanvasPattern::eString(string) => {
match parse_color(&string) {
Ok(rgba) => {
- self.fill_color.set(rgba);
+ self.state.borrow_mut().fill_color = rgba;
self.renderer
.send(CanvasMsg::SetFillStyle(FillOrStrokeStyle::Color(rgba)))
.unwrap()
@@ -846,7 +882,8 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
// https://html.spec.whatwg.org/multipage/#dom-context-2d-linewidth
fn LineWidth(self) -> f64 {
- self.line_width.get()
+ let state = self.state.borrow();
+ state.line_width
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-linewidth
@@ -855,13 +892,14 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
return;
}
- self.line_width.set(width);
+ self.state.borrow_mut().line_width = width;
self.renderer.send(CanvasMsg::SetLineWidth(width as f32)).unwrap()
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-linecap
fn LineCap(self) -> DOMString {
- match self.line_cap.get() {
+ let state = self.state.borrow();
+ match state.line_cap {
LineCapStyle::Butt => "butt".to_owned(),
LineCapStyle::Round => "round".to_owned(),
LineCapStyle::Square => "square".to_owned(),
@@ -871,14 +909,15 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
// https://html.spec.whatwg.org/multipage/#dom-context-2d-linecap
fn SetLineCap(self, cap_str: DOMString) {
if let Some(cap) = LineCapStyle::from_str(&cap_str) {
- self.line_cap.set(cap);
+ self.state.borrow_mut().line_cap = cap;
self.renderer.send(CanvasMsg::SetLineCap(cap)).unwrap()
}
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-linejoin
fn LineJoin(self) -> DOMString {
- match self.line_join.get() {
+ let state = self.state.borrow();
+ match state.line_join {
LineJoinStyle::Round => "round".to_owned(),
LineJoinStyle::Bevel => "bevel".to_owned(),
LineJoinStyle::Miter => "miter".to_owned(),
@@ -888,14 +927,15 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
// https://html.spec.whatwg.org/multipage/#dom-context-2d-linejoin
fn SetLineJoin(self, join_str: DOMString) {
if let Some(join) = LineJoinStyle::from_str(&join_str) {
- self.line_join.set(join);
+ self.state.borrow_mut().line_join = join;
self.renderer.send(CanvasMsg::SetLineJoin(join)).unwrap()
}
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-miterlimit
fn MiterLimit(self) -> f64 {
- self.miter_limit.get()
+ let state = self.state.borrow();
+ state.miter_limit
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-miterlimit
@@ -904,7 +944,7 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
return;
}
- self.miter_limit.set(limit);
+ self.state.borrow_mut().miter_limit = limit;
self.renderer.send(CanvasMsg::SetMiterLimit(limit as f32)).unwrap()
}
}
diff --git a/components/script/dom/webidls/CanvasRenderingContext2D.webidl b/components/script/dom/webidls/CanvasRenderingContext2D.webidl
index 2805a273550..e1d5416f13e 100644
--- a/components/script/dom/webidls/CanvasRenderingContext2D.webidl
+++ b/components/script/dom/webidls/CanvasRenderingContext2D.webidl
@@ -26,8 +26,8 @@ interface CanvasRenderingContext2D {
//void commit(); // push the image to the output bitmap
// state
- //void save(); // push state on state stack
- //void restore(); // pop state stack and restore state
+ void save(); // push state on state stack
+ void restore(); // pop state stack and restore state
// transformations (default transform is the identity matrix)
// attribute SVGMatrix currentTransform;
diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock
index 602d8af177b..3e09a9930aa 100644
--- a/components/servo/Cargo.lock
+++ b/components/servo/Cargo.lock
@@ -35,7 +35,7 @@ source = "git+https://github.com/tomaka/android-rs-glue#5a68056599fb498b0cf3715f
[[package]]
name = "azure"
version = "0.1.0"
-source = "git+https://github.com/servo/rust-azure#358fc5da081cf7d0618fae2d9d5582951beb791f"
+source = "git+https://github.com/servo/rust-azure#3e5daf667a62f702dc16285e923464458bef785f"
dependencies = [
"core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)",
"core_graphics 0.1.0 (git+https://github.com/servo/rust-core-graphics)",
diff --git a/ports/cef/Cargo.lock b/ports/cef/Cargo.lock
index d8a540d7a4c..bece7eec676 100644
--- a/ports/cef/Cargo.lock
+++ b/ports/cef/Cargo.lock
@@ -37,7 +37,7 @@ source = "git+https://github.com/tomaka/android-rs-glue#5a68056599fb498b0cf3715f
[[package]]
name = "azure"
version = "0.1.0"
-source = "git+https://github.com/servo/rust-azure#358fc5da081cf7d0618fae2d9d5582951beb791f"
+source = "git+https://github.com/servo/rust-azure#3e5daf667a62f702dc16285e923464458bef785f"
dependencies = [
"core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)",
"core_graphics 0.1.0 (git+https://github.com/servo/rust-core-graphics)",
@@ -855,6 +855,7 @@ dependencies = [
"bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"compositing 0.0.1",
"devtools 0.0.1",
+ "devtools_traits 0.0.1",
"gfx 0.0.1",
"glutin_app 0.0.1",
"layout 0.0.1",
diff --git a/ports/gonk/Cargo.lock b/ports/gonk/Cargo.lock
index 91ab0d004d0..3ff6432d73e 100644
--- a/ports/gonk/Cargo.lock
+++ b/ports/gonk/Cargo.lock
@@ -26,7 +26,7 @@ dependencies = [
[[package]]
name = "azure"
version = "0.1.0"
-source = "git+https://github.com/servo/rust-azure#358fc5da081cf7d0618fae2d9d5582951beb791f"
+source = "git+https://github.com/servo/rust-azure#3e5daf667a62f702dc16285e923464458bef785f"
dependencies = [
"core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)",
"core_graphics 0.1.0 (git+https://github.com/servo/rust-core-graphics)",
@@ -780,6 +780,7 @@ dependencies = [
"bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"compositing 0.0.1",
"devtools 0.0.1",
+ "devtools_traits 0.0.1",
"gfx 0.0.1",
"layout 0.0.1",
"msg 0.0.1",
diff --git a/tests/wpt/metadata/2dcontext/line-styles/2d.line.width.transformed.html.ini b/tests/wpt/metadata/2dcontext/line-styles/2d.line.width.transformed.html.ini
deleted file mode 100644
index 7f6d331fab2..00000000000
--- a/tests/wpt/metadata/2dcontext/line-styles/2d.line.width.transformed.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[2d.line.width.transformed.html]
- type: testharness
- [Line stroke widths are affected by scale transformations]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.bitmap.html.ini b/tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.bitmap.html.ini
deleted file mode 100644
index 16cf3284387..00000000000
--- a/tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.bitmap.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[2d.state.saverestore.bitmap.html]
- type: testharness
- [save()/restore() does not affect the current bitmap]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.fillStyle.html.ini b/tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.fillStyle.html.ini
deleted file mode 100644
index e99c74d2806..00000000000
--- a/tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.fillStyle.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[2d.state.saverestore.fillStyle.html]
- type: testharness
- [save()/restore() works for fillStyle]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.globalAlpha.html.ini b/tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.globalAlpha.html.ini
deleted file mode 100644
index d4676a347c0..00000000000
--- a/tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.globalAlpha.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[2d.state.saverestore.globalAlpha.html]
- type: testharness
- [save()/restore() works for globalAlpha]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.lineCap.html.ini b/tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.lineCap.html.ini
deleted file mode 100644
index 11ee72efd6e..00000000000
--- a/tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.lineCap.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[2d.state.saverestore.lineCap.html]
- type: testharness
- [save()/restore() works for lineCap]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.lineJoin.html.ini b/tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.lineJoin.html.ini
deleted file mode 100644
index cba7c1653fe..00000000000
--- a/tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.lineJoin.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[2d.state.saverestore.lineJoin.html]
- type: testharness
- [save()/restore() works for lineJoin]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.lineWidth.html.ini b/tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.lineWidth.html.ini
deleted file mode 100644
index 8be9e715f82..00000000000
--- a/tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.lineWidth.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[2d.state.saverestore.lineWidth.html]
- type: testharness
- [save()/restore() works for lineWidth]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.miterLimit.html.ini b/tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.miterLimit.html.ini
deleted file mode 100644
index c60e9b276a7..00000000000
--- a/tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.miterLimit.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[2d.state.saverestore.miterLimit.html]
- type: testharness
- [save()/restore() works for miterLimit]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.stack.html.ini b/tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.stack.html.ini
deleted file mode 100644
index 7a1db072d37..00000000000
--- a/tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.stack.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[2d.state.saverestore.stack.html]
- type: testharness
- [save()/restore() can be nested as a stack]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.stackdepth.html.ini b/tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.stackdepth.html.ini
deleted file mode 100644
index a3658368a1c..00000000000
--- a/tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.stackdepth.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[2d.state.saverestore.stackdepth.html]
- type: testharness
- [save()/restore() stack depth is not unreasonably limited]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.strokeStyle.html.ini b/tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.strokeStyle.html.ini
deleted file mode 100644
index 767f020c0a1..00000000000
--- a/tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.strokeStyle.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[2d.state.saverestore.strokeStyle.html]
- type: testharness
- [save()/restore() works for strokeStyle]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.transformation.html.ini b/tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.transformation.html.ini
deleted file mode 100644
index 57e9fdc6068..00000000000
--- a/tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.transformation.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[2d.state.saverestore.transformation.html]
- type: testharness
- [save()/restore() affects the current transformation matrix]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.underflow.html.ini b/tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.underflow.html.ini
deleted file mode 100644
index 80a4e6d4819..00000000000
--- a/tests/wpt/metadata/2dcontext/the-canvas-state/2d.state.saverestore.underflow.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[2d.state.saverestore.underflow.html]
- type: testharness
- [restore() with an empty stack has no effect]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/2dcontext/transformations/2d.transformation.scale.negative.html.ini b/tests/wpt/metadata/2dcontext/transformations/2d.transformation.scale.negative.html.ini
deleted file mode 100644
index 70876efb171..00000000000
--- a/tests/wpt/metadata/2dcontext/transformations/2d.transformation.scale.negative.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[2d.transformation.scale.negative.html]
- type: testharness
- [scale() with negative scale factors works]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/html/dom/interfaces.html.ini b/tests/wpt/metadata/html/dom/interfaces.html.ini
index a254db3f69b..6fb44abfea5 100644
--- a/tests/wpt/metadata/html/dom/interfaces.html.ini
+++ b/tests/wpt/metadata/html/dom/interfaces.html.ini
@@ -6870,12 +6870,6 @@
[CanvasRenderingContext2D interface: operation commit()]
expected: FAIL
- [CanvasRenderingContext2D interface: operation save()]
- expected: FAIL
-
- [CanvasRenderingContext2D interface: operation restore()]
- expected: FAIL
-
[CanvasRenderingContext2D interface: attribute currentTransform]
expected: FAIL
@@ -7017,12 +7011,6 @@
[CanvasRenderingContext2D interface: document.createElement("canvas").getContext("2d") must inherit property "commit" with the proper type (3)]
expected: FAIL
- [CanvasRenderingContext2D interface: document.createElement("canvas").getContext("2d") must inherit property "save" with the proper type (4)]
- expected: FAIL
-
- [CanvasRenderingContext2D interface: document.createElement("canvas").getContext("2d") must inherit property "restore" with the proper type (5)]
- expected: FAIL
-
[CanvasRenderingContext2D interface: document.createElement("canvas").getContext("2d") must inherit property "currentTransform" with the proper type (6)]
expected: FAIL