Align canvas.putImageData with spec

The arguments are supposed to be long values, not floats.
This commit is contained in:
Anthony Ramine 2018-10-04 12:11:39 +02:00
parent 62ea3c093a
commit 3d910feb3a
5 changed files with 35 additions and 44 deletions

View file

@ -452,17 +452,16 @@ impl<'a> CanvasData<'a> {
pub fn put_image_data( pub fn put_image_data(
&mut self, &mut self,
imagedata: Vec<u8>, imagedata: Vec<u8>,
offset: Vector2D<f64>, offset: Vector2D<i32>,
image_data_size: Size2D<f64>, image_data_size: Size2D<i32>,
dirty_rect: Rect<f64> dirty_rect: Rect<i32>,
) { ) {
assert_eq!(image_data_size.width * image_data_size.height * 4.0, imagedata.len() as f64); assert_eq!(image_data_size.width * image_data_size.height * 4, imagedata.len() as i32);
let dest_rect = dirty_rect.translate(&offset).to_i32(); let dest_rect = dirty_rect.translate(&offset);
let image_size = image_data_size;
let image_size = image_data_size.to_i32(); let first_pixel = dest_rect.origin - offset;
let first_pixel = dest_rect.origin - offset.to_i32();
let mut src_line = (first_pixel.y * (image_size.width * 4) + first_pixel.x * 4) as usize; let mut src_line = (first_pixel.y * (image_size.width * 4) + first_pixel.x * 4) as usize;
let mut dest = let mut dest =

View file

@ -54,7 +54,7 @@ pub enum Canvas2dMsg {
IsPointInPath(f64, f64, FillRule, IpcSender<bool>), IsPointInPath(f64, f64, FillRule, IpcSender<bool>),
LineTo(Point2D<f32>), LineTo(Point2D<f32>),
MoveTo(Point2D<f32>), MoveTo(Point2D<f32>),
PutImageData(ByteBuf, Vector2D<f64>, Size2D<f64>, Rect<f64>), PutImageData(ByteBuf, Vector2D<i32>, Size2D<i32>, Rect<i32>),
QuadraticCurveTo(Point2D<f32>, Point2D<f32>), QuadraticCurveTo(Point2D<f32>, Point2D<f32>),
Rect(Rect<f32>), Rect(Rect<f32>),
RestoreContext, RestoreContext,

View file

@ -1191,39 +1191,26 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D {
} }
// https://html.spec.whatwg.org/multipage/#dom-context-2d-putimagedata // https://html.spec.whatwg.org/multipage/#dom-context-2d-putimagedata
fn PutImageData(&self, imagedata: &ImageData, dx: Finite<f64>, dy: Finite<f64>) { fn PutImageData(&self, imagedata: &ImageData, dx: i32, dy: i32) {
self.PutImageData_( self.PutImageData_(imagedata, dx, dy, 0, 0, imagedata.Width() as i32, imagedata.Height() as i32)
imagedata,
dx,
dy,
Finite::wrap(0f64),
Finite::wrap(0f64),
Finite::wrap(imagedata.Width() as f64),
Finite::wrap(imagedata.Height() as f64),
)
} }
// https://html.spec.whatwg.org/multipage/#dom-context-2d-putimagedata // https://html.spec.whatwg.org/multipage/#dom-context-2d-putimagedata
fn PutImageData_( fn PutImageData_(
&self, &self,
imagedata: &ImageData, imagedata: &ImageData,
dx: Finite<f64>, dx: i32,
dy: Finite<f64>, dy: i32,
dirty_x: Finite<f64>, mut dirty_x: i32,
dirty_y: Finite<f64>, mut dirty_y: i32,
dirty_width: Finite<f64>, mut dirty_width: i32,
dirty_height: Finite<f64>, mut dirty_height: i32,
) { ) {
let imagedata_size = Size2D::new(imagedata.Width() as f64, imagedata.Height() as f64); let imagedata_size = Size2D::new(imagedata.Width() as i32, imagedata.Height() as i32);
if imagedata_size.width <= 0. || imagedata_size.height <= 0. { if imagedata_size.width <= 0 || imagedata_size.height <= 0 {
return; return;
} }
let mut dirty_x = *dirty_x;
let mut dirty_y = *dirty_y;
let mut dirty_width = *dirty_width;
let mut dirty_height = *dirty_height;
// Step 1. // Step 1.
// Done later. // Done later.
@ -1231,23 +1218,23 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D {
// TODO: throw InvalidState if buffer is detached. // TODO: throw InvalidState if buffer is detached.
// Step 3. // Step 3.
if dirty_width < 0. { if dirty_width < 0 {
dirty_x += dirty_width; dirty_x += dirty_width;
dirty_width = -dirty_width; dirty_width = -dirty_width;
} }
if dirty_height < 0. { if dirty_height < 0 {
dirty_y += dirty_height; dirty_y += dirty_height;
dirty_height = -dirty_height; dirty_height = -dirty_height;
} }
// Step 4. // Step 4.
if dirty_x < 0. { if dirty_x < 0 {
dirty_width += dirty_x; dirty_width += dirty_x;
dirty_x = 0.; dirty_x = 0;
} }
if dirty_y < 0. { if dirty_y < 0 {
dirty_height += dirty_y; dirty_height += dirty_y;
dirty_y = 0.; dirty_y = 0;
} }
// Step 5. // Step 5.
@ -1259,7 +1246,7 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D {
} }
// Step 6. // Step 6.
if dirty_width <= 0. || dirty_height <= 0. { if dirty_width <= 0 || dirty_height <= 0 {
return; return;
} }
@ -1270,7 +1257,7 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D {
// Step 7. // Step 7.
self.send_canvas_2d_msg(Canvas2dMsg::PutImageData( self.send_canvas_2d_msg(Canvas2dMsg::PutImageData(
buffer.into(), buffer.into(),
Vector2D::new(*dx, *dy), Vector2D::new(dx, dy),
imagedata_size, imagedata_size,
Rect::new( Rect::new(
Point2D::new(dirty_x, dirty_y), Point2D::new(dirty_x, dirty_y),

View file

@ -180,11 +180,11 @@ interface CanvasImageData {
ImageData createImageData(ImageData imagedata); ImageData createImageData(ImageData imagedata);
[Throws] [Throws]
ImageData getImageData(double sx, double sy, double sw, double sh); ImageData getImageData(double sx, double sy, double sw, double sh);
void putImageData(ImageData imagedata, double dx, double dy); void putImageData(ImageData imagedata, long dx, long dy);
void putImageData(ImageData imagedata, void putImageData(ImageData imagedata,
double dx, double dy, long dx, long dy,
double dirtyX, double dirtyY, long dirtyX, long dirtyY,
double dirtyWidth, double dirtyHeight); long dirtyWidth, long dirtyHeight);
}; };
enum CanvasLineCap { "butt", "round", "square" }; enum CanvasLineCap { "butt", "round", "square" };

View file

@ -0,0 +1,5 @@
[2d.imageData.put.nonfinite.html]
bug: https://github.com/web-platform-tests/wpt/issues/13393
[putImageData() throws TypeError if arguments are not finite]
expected: FAIL