diff --git a/components/canvas/canvas_paint_task.rs b/components/canvas/canvas_paint_task.rs index c2921561c49..cfaa55542b5 100644 --- a/components/canvas/canvas_paint_task.rs +++ b/components/canvas/canvas_paint_task.rs @@ -29,8 +29,7 @@ impl<'a> CanvasPaintTask<'a> { /// It reads image data from the canvas /// canvas_size: The size of the canvas we're reading from /// read_rect: The area of the canvas we want to read from - fn read_pixels(&self, read_rect: Rect, canvas_size: Size2D) -> Vec{ - let read_rect = read_rect.to_i32(); + fn read_pixels(&self, read_rect: Rect, canvas_size: Size2D) -> Vec{ let canvas_size = canvas_size.to_i32(); let canvas_rect = Rect::new(Point2D::new(0i32, 0i32), canvas_size); let src_read_rect = canvas_rect.intersection(&read_rect).unwrap_or(Rect::zero()); @@ -396,7 +395,7 @@ impl<'a> CanvasPaintTask<'a> { smoothing_enabled: bool) { // Reads pixels from source image // In this case source and target are the same canvas - let image_data = self.read_pixels(source_rect, image_size); + let image_data = self.read_pixels(source_rect.to_i32(), image_size); if self.need_to_draw_shadow() { let rect = Rect::new(Point2D::new(dest_rect.origin.x as f32, dest_rect.origin.y as f32), @@ -567,24 +566,9 @@ impl<'a> CanvasPaintTask<'a> { } fn get_image_data(&self, - mut dest_rect: Rect, + dest_rect: Rect, canvas_size: Size2D, chan: IpcSender>) { - if dest_rect.size.width < 0.0 { - dest_rect.size.width = -dest_rect.size.width; - dest_rect.origin.x -= dest_rect.size.width; - } - if dest_rect.size.height < 0.0 { - dest_rect.size.height = -dest_rect.size.height; - dest_rect.origin.y -= dest_rect.size.height; - } - if dest_rect.size.width == 0.0 { - dest_rect.size.width = 1.0; - } - if dest_rect.size.height == 0.0 { - dest_rect.size.height = 1.0; - } - let mut dest_data = self.read_pixels(dest_rect, canvas_size); // bgra -> rgba diff --git a/components/canvas_traits/lib.rs b/components/canvas_traits/lib.rs index 48cabed045c..2676e57eb2b 100644 --- a/components/canvas_traits/lib.rs +++ b/components/canvas_traits/lib.rs @@ -88,7 +88,7 @@ pub enum Canvas2dMsg { ClosePath, Fill, FillRect(Rect), - GetImageData(Rect, Size2D, IpcSender>), + GetImageData(Rect, Size2D, IpcSender>), LineTo(Point2D), MoveTo(Point2D), PutImageData(Vec, Rect, Option>), diff --git a/components/script/dom/canvasrenderingcontext2d.rs b/components/script/dom/canvasrenderingcontext2d.rs index c9f8da05bff..4e25cceb4c0 100644 --- a/components/script/dom/canvasrenderingcontext2d.rs +++ b/components/script/dom/canvasrenderingcontext2d.rs @@ -32,6 +32,7 @@ use euclid::size::Size2D; use canvas_traits::{CanvasMsg, Canvas2dMsg, CanvasCommonMsg}; use canvas_traits::{FillOrStrokeStyle, LinearGradientStyle, RadialGradientStyle, RepetitionStyle}; use canvas_traits::{LineCapStyle, LineJoinStyle, CompositionOrBlending}; +use canvas::canvas_paint_task::RectToi32; use msg::constellation_msg::Msg as ConstellationMsg; use net_traits::image_cache_task::{ImageCacheChan, ImageResponse}; @@ -298,7 +299,7 @@ impl CanvasRenderingContext2D { let renderer = context.r().get_ipc_renderer(); let (sender, receiver) = ipc::channel::>().unwrap(); // Reads pixels from source image - renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::GetImageData(source_rect, + renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::GetImageData(source_rect.to_i32(), image_size, sender))).unwrap(); let imagedata = receiver.recv().unwrap(); @@ -377,7 +378,8 @@ impl CanvasRenderingContext2D { let renderer = context.r().get_ipc_renderer(); let (sender, receiver) = ipc::channel::>().unwrap(); // Reads pixels from source canvas - renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::GetImageData(source_rect, image_size, sender))).unwrap(); + renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::GetImageData(source_rect.to_i32(), + image_size, sender))).unwrap(); return Some((receiver.recv().unwrap(), image_size)); } @@ -884,18 +886,30 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D { sy: Finite, sw: Finite, sh: Finite) -> Fallible> { - let sx = *sx; - let sy = *sy; - let sw = *sw; - let sh = *sh; + let mut sx = *sx; + let mut sy = *sy; + let mut sw = *sw; + let mut sh = *sh; if sw == 0.0 || sh == 0.0 { return Err(IndexSize) } + if sw < 0.0 { + sw = -sw; + sx -= sw; + } + if sh < 0.0 { + sh = -sh; + sy -= sh; + } + + let sh = cmp::max(1, sh.to_u32().unwrap()); + let sw = cmp::max(1, sw.to_u32().unwrap()); + let (sender, receiver) = ipc::channel::>().unwrap(); - let dest_rect = Rect::new(Point2D::new(sx as f64, sy as f64), - Size2D::new(sw as f64, sh as f64)); + let dest_rect = Rect::new(Point2D::new(sx.to_i32().unwrap(), sy.to_i32().unwrap()), + Size2D::new(sw as i32, sh as i32)); let canvas_size = self.canvas.root().r().get_size(); let canvas_size = Size2D::new(canvas_size.width as f64, canvas_size.height as f64); self.ipc_renderer @@ -913,7 +927,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D { chunk[2] = (chunk[2] as f32 / alpha) as u8; } - Ok(ImageData::new(self.global.root().r(), sw.abs().to_u32().unwrap(), sh.abs().to_u32().unwrap(), Some(data))) + Ok(ImageData::new(self.global.root().r(), sw, sh, Some(data))) } // https://html.spec.whatwg.org/multipage/#dom-context-2d-putimagedata diff --git a/tests/wpt/metadata/2dcontext/pixel-manipulation/2d.imageData.get.tiny.html.ini b/tests/wpt/metadata/2dcontext/pixel-manipulation/2d.imageData.get.tiny.html.ini deleted file mode 100644 index cafc902fd91..00000000000 --- a/tests/wpt/metadata/2dcontext/pixel-manipulation/2d.imageData.get.tiny.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[2d.imageData.get.tiny.html] - type: testharness - [getImageData() works for sizes smaller than one pixel] - expected: FAIL -