mirror of
https://github.com/servo/servo.git
synced 2025-07-23 07:13:52 +01:00
Add guards to almost CanvasRenderingContext2D methods according to the spec.
http://www.w3.org/html/wg/drafts/2dcontext/html5_canvas_CR/ says "Except where otherwise specified, for the 2D context interface, any method call with a numeric argument whose value is infinite or a NaN value must be ignored." We might define the annotation to generate this behavior in glue code. However, at now, I use this workaround way.
This commit is contained in:
parent
05c6d046dd
commit
bc06526610
1 changed files with 89 additions and 1 deletions
|
@ -8,7 +8,7 @@ use dom::bindings::codegen::Bindings::CanvasRenderingContext2DBinding::CanvasWin
|
|||
use dom::bindings::codegen::Bindings::ImageDataBinding::ImageDataMethods;
|
||||
use dom::bindings::codegen::UnionTypes::HTMLCanvasElementOrCanvasRenderingContext2D;
|
||||
use dom::bindings::codegen::UnionTypes::StringOrCanvasGradientOrCanvasPattern;
|
||||
use dom::bindings::error::Error::{IndexSize, TypeError};
|
||||
use dom::bindings::error::Error::{IndexSize, NotSupported, TypeError};
|
||||
use dom::bindings::error::Fallible;
|
||||
use dom::bindings::global::{GlobalRef, GlobalField};
|
||||
use dom::bindings::js::{JS, JSRef, LayoutJS, Temporary};
|
||||
|
@ -207,22 +207,44 @@ impl LayoutCanvasRenderingContext2DHelpers for LayoutJS<CanvasRenderingContext2D
|
|||
}
|
||||
}
|
||||
|
||||
// We add a guard to each of methods by the spec:
|
||||
// http://www.w3.org/html/wg/drafts/2dcontext/html5_canvas_CR/
|
||||
//
|
||||
// > Except where otherwise specified, for the 2D context interface,
|
||||
// > any method call with a numeric argument whose value is infinite or a NaN value must be ignored.
|
||||
//
|
||||
// Restricted values are guarded in glue code. Therefore we need not add a guard.
|
||||
//
|
||||
// FIXME: this behavior should might be generated by some annotattions to idl.
|
||||
impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D> {
|
||||
fn Canvas(self) -> Temporary<HTMLCanvasElement> {
|
||||
Temporary::new(self.canvas)
|
||||
}
|
||||
|
||||
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));
|
||||
self.update_transform()
|
||||
}
|
||||
|
||||
fn Translate(self, x: f64, y: f64) {
|
||||
if !(x.is_finite() && y.is_finite()) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.transform.set(self.transform.get().translate(x as f32, y as f32));
|
||||
self.update_transform()
|
||||
}
|
||||
|
||||
fn Transform(self, a: f64, b: f64, c: f64, d: f64, e: f64, f: f64) {
|
||||
if !(a.is_finite() && b.is_finite() && c.is_finite() &&
|
||||
d.is_finite() && e.is_finite() && f.is_finite()) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.transform.set(self.transform.get().mul(&Matrix2D::new(a as f32,
|
||||
b as f32,
|
||||
c as f32,
|
||||
|
@ -233,6 +255,11 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
|
|||
}
|
||||
|
||||
fn SetTransform(self, a: f64, b: f64, c: f64, d: f64, e: f64, f: f64) {
|
||||
if !(a.is_finite() && b.is_finite() && c.is_finite() &&
|
||||
d.is_finite() && e.is_finite() && f.is_finite()) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.transform.set(Matrix2D::new(a as f32,
|
||||
b as f32,
|
||||
c as f32,
|
||||
|
@ -243,16 +270,31 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
|
|||
}
|
||||
|
||||
fn FillRect(self, x: f64, y: f64, width: f64, height: f64) {
|
||||
if !(x.is_finite() && y.is_finite() &&
|
||||
width.is_finite() && height.is_finite()) {
|
||||
return;
|
||||
}
|
||||
|
||||
let rect = Rect(Point2D(x as f32, y as f32), Size2D(width as f32, height as f32));
|
||||
self.renderer.send(CanvasMsg::FillRect(rect)).unwrap();
|
||||
}
|
||||
|
||||
fn ClearRect(self, x: f64, y: f64, width: f64, height: f64) {
|
||||
if !(x.is_finite() && y.is_finite() &&
|
||||
width.is_finite() && height.is_finite()) {
|
||||
return;
|
||||
}
|
||||
|
||||
let rect = Rect(Point2D(x as f32, y as f32), Size2D(width as f32, height as f32));
|
||||
self.renderer.send(CanvasMsg::ClearRect(rect)).unwrap();
|
||||
}
|
||||
|
||||
fn StrokeRect(self, x: f64, y: f64, width: f64, height: f64) {
|
||||
if !(x.is_finite() && y.is_finite() &&
|
||||
width.is_finite() && height.is_finite()) {
|
||||
return;
|
||||
}
|
||||
|
||||
let rect = Rect(Point2D(x as f32, y as f32), Size2D(width as f32, height as f32));
|
||||
self.renderer.send(CanvasMsg::StrokeRect(rect)).unwrap();
|
||||
}
|
||||
|
@ -272,6 +314,9 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
|
|||
// https://html.spec.whatwg.org/multipage/scripting.html#dom-context-2d-drawimage
|
||||
fn DrawImage(self, image: HTMLCanvasElementOrCanvasRenderingContext2D,
|
||||
dx: f64, dy: f64) -> Fallible<()> {
|
||||
if !(dx.is_finite() && dy.is_finite()) {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// From rules described in the spec:
|
||||
// If the sx, sy, sw, and sh arguments are omitted, they must default to 0, 0,
|
||||
|
@ -311,6 +356,10 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
|
|||
// https://html.spec.whatwg.org/multipage/scripting.html#dom-context-2d-drawimage
|
||||
fn DrawImage_(self, image: HTMLCanvasElementOrCanvasRenderingContext2D,
|
||||
dx: f64, dy: f64, dw: f64, dh: f64) -> Fallible<()> {
|
||||
if !(dx.is_finite() && dy.is_finite() &&
|
||||
dw.is_finite() && dh.is_finite()) {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// From rules described in the spec:
|
||||
// If the sx, sy, sw, and sh arguments are omitted, they must default to 0, 0,
|
||||
|
@ -347,6 +396,11 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
|
|||
fn DrawImage__(self, image: HTMLCanvasElementOrCanvasRenderingContext2D,
|
||||
sx: f64, sy: f64, sw: f64, sh: f64,
|
||||
dx: f64, dy: f64, dw: f64, dh: f64) -> Fallible<()> {
|
||||
if !(sx.is_finite() && sy.is_finite() && sw.is_finite() && sh.is_finite() &&
|
||||
dx.is_finite() && dy.is_finite() && dw.is_finite() && dh.is_finite()) {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
match image {
|
||||
HTMLCanvasElementOrCanvasRenderingContext2D::eHTMLCanvasElement(image) => {
|
||||
let canvas = image.root();
|
||||
|
@ -366,19 +420,37 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
|
|||
}
|
||||
|
||||
fn MoveTo(self, x: f64, y: f64) {
|
||||
if !(x.is_finite() && y.is_finite()) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.renderer.send(CanvasMsg::MoveTo(Point2D(x as f32, y as f32))).unwrap();
|
||||
}
|
||||
|
||||
fn LineTo(self, x: f64, y: f64) {
|
||||
if !(x.is_finite() && y.is_finite()) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.renderer.send(CanvasMsg::LineTo(Point2D(x as f32, y as f32))).unwrap();
|
||||
}
|
||||
|
||||
fn QuadraticCurveTo(self, cpx: f64, cpy: f64, x: f64, y: f64) {
|
||||
if !(cpx.is_finite() && cpy.is_finite() &&
|
||||
x.is_finite() && y.is_finite()) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.renderer.send(CanvasMsg::QuadraticCurveTo(Point2D(cpx as f32, cpy as f32),
|
||||
Point2D(x as f32, y as f32))).unwrap();
|
||||
}
|
||||
|
||||
fn BezierCurveTo(self, cp1x: f64, cp1y: f64, cp2x: f64, cp2y: f64, x: f64, y: f64) {
|
||||
if !(cp1x.is_finite() && cp1y.is_finite() && cp2x.is_finite() && cp2y.is_finite() &&
|
||||
x.is_finite() && y.is_finite()) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.renderer.send(CanvasMsg::BezierCurveTo(Point2D(cp1x as f32, cp1y as f32),
|
||||
Point2D(cp2x as f32, cp2y as f32),
|
||||
Point2D(x as f32, y as f32))).unwrap();
|
||||
|
@ -463,6 +535,10 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
|
|||
}
|
||||
|
||||
fn CreateImageData(self, sw: f64, sh: f64) -> Fallible<Temporary<ImageData>> {
|
||||
if !(sw.is_finite() && sh.is_finite()) {
|
||||
return Err(NotSupported);
|
||||
}
|
||||
|
||||
if sw == 0.0 || sh == 0.0 {
|
||||
return Err(IndexSize)
|
||||
}
|
||||
|
@ -491,6 +567,12 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
|
|||
}
|
||||
|
||||
fn PutImageData(self, imagedata: JSRef<ImageData>, dx: Finite<f64>, dy: Finite<f64>) {
|
||||
// XXX:
|
||||
// By the spec: http://www.w3.org/html/wg/drafts/2dcontext/html5_canvas_CR/#dom-context-2d-putimagedata
|
||||
// "If any of the arguments to the method are infinite or NaN, the method must throw a NotSupportedError exception"
|
||||
// But this arguments are stricted value, so if they are not finite values,
|
||||
// they will be TypeError by WebIDL spec before call this methods.
|
||||
|
||||
let data = imagedata.get_data_array(&self.global.root().r());
|
||||
let image_data_rect = Rect(Point2D(dx.to_i32().unwrap(), dy.to_i32().unwrap()), imagedata.get_size());
|
||||
let dirty_rect = None;
|
||||
|
@ -499,6 +581,12 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
|
|||
|
||||
fn PutImageData_(self, imagedata: JSRef<ImageData>, dx: Finite<f64>, dy: Finite<f64>,
|
||||
dirtyX: Finite<f64>, dirtyY: Finite<f64>, dirtyWidth: Finite<f64>, dirtyHeight: Finite<f64>) {
|
||||
// XXX:
|
||||
// By the spec: http://www.w3.org/html/wg/drafts/2dcontext/html5_canvas_CR/#dom-context-2d-putimagedata
|
||||
// "If any of the arguments to the method are infinite or NaN, the method must throw a NotSupportedError exception"
|
||||
// But this arguments are stricted value, so if they are not finite values,
|
||||
// they will be TypeError by WebIDL spec before call this methods.
|
||||
|
||||
let data = imagedata.get_data_array(&self.global.root().r());
|
||||
let image_data_rect = Rect(Point2D(dx.to_i32().unwrap(), dy.to_i32().unwrap()),
|
||||
Size2D(imagedata.Width().to_i32().unwrap(),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue