diff --git a/components/canvas/canvas_data.rs b/components/canvas/canvas_data.rs index c91dbd8c826..c422cdd0aec 100644 --- a/components/canvas/canvas_data.rs +++ b/components/canvas/canvas_data.rs @@ -454,57 +454,12 @@ impl<'a> CanvasData<'a> { imagedata: Vec, offset: Vector2D, image_data_size: Size2D, - mut dirty_rect: Rect + dirty_rect: Rect ) { - if image_data_size.width <= 0.0 || image_data_size.height <= 0.0 { - return - } - assert_eq!(image_data_size.width * image_data_size.height * 4.0, imagedata.len() as f64); - // Step 1. TODO (neutered data) - - // Step 2. - if dirty_rect.size.width < 0.0f64 { - dirty_rect.origin.x += dirty_rect.size.width; - dirty_rect.size.width = -dirty_rect.size.width; - } - - if dirty_rect.size.height < 0.0f64 { - dirty_rect.origin.y += dirty_rect.size.height; - dirty_rect.size.height = -dirty_rect.size.height; - } - - // Step 3. - if dirty_rect.origin.x < 0.0f64 { - dirty_rect.size.width += dirty_rect.origin.x; - dirty_rect.origin.x = 0.0f64; - } - - if dirty_rect.origin.y < 0.0f64 { - dirty_rect.size.height += dirty_rect.origin.y; - dirty_rect.origin.y = 0.0f64; - } - - // Step 4. - if dirty_rect.max_x() > image_data_size.width { - dirty_rect.size.width = image_data_size.width - dirty_rect.origin.x; - } - - if dirty_rect.max_y() > image_data_size.height { - dirty_rect.size.height = image_data_size.height - dirty_rect.origin.y; - } - - // 5) If either dirtyWidth or dirtyHeight is negative or zero, - // stop without affecting any bitmaps - if dirty_rect.size.width <= 0.0 || dirty_rect.size.height <= 0.0 { - return - } - - // Step 6. let dest_rect = dirty_rect.translate(&offset).to_i32(); - // azure_hl operates with integers. We need to cast the image size let image_size = image_data_size.to_i32(); let first_pixel = dest_rect.origin - offset.to_i32(); diff --git a/components/script/dom/canvasrenderingcontext2d.rs b/components/script/dom/canvasrenderingcontext2d.rs index 2b364c3702d..3482c3d925a 100644 --- a/components/script/dom/canvasrenderingcontext2d.rs +++ b/components/script/dom/canvasrenderingcontext2d.rs @@ -1214,19 +1214,68 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D { dirty_width: Finite, dirty_height: Finite, ) { - let data = imagedata.get_data_array(); - let offset = Vector2D::new(*dx, *dy); - let image_data_size = Size2D::new(imagedata.Width() as f64, imagedata.Height() as f64); + let imagedata_size = Size2D::new(imagedata.Width() as f64, imagedata.Height() as f64); + if imagedata_size.width <= 0. || imagedata_size.height <= 0. { + return; + } - let dirty_rect = Rect::new( - Point2D::new(*dirty_x, *dirty_y), - Size2D::new(*dirty_width, *dirty_height), - ); + 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. + // Done later. + + // Step 2. + // TODO: throw InvalidState if buffer is detached. + + // Step 3. + if dirty_width < 0. { + dirty_x += dirty_width; + dirty_width = -dirty_width; + } + if dirty_height < 0. { + dirty_y += dirty_height; + dirty_height = -dirty_height; + } + + // Step 4. + if dirty_x < 0. { + dirty_width += dirty_x; + dirty_x = 0.; + } + if dirty_y < 0. { + dirty_height += dirty_y; + dirty_y = 0.; + } + + // Step 5. + if dirty_x + dirty_width > imagedata_size.width { + dirty_width = imagedata_size.width - dirty_x; + } + if dirty_y + dirty_height > imagedata_size.height { + dirty_height = imagedata_size.height - dirty_y; + } + + // Step 6. + if dirty_width <= 0. || dirty_height <= 0. { + return; + } + + // FIXME(nox): There is no need to make a Vec of all the pixels + // if we didn't want to put the entire image. + let buffer = imagedata.get_data_array(); + + // Step 7. self.send_canvas_2d_msg(Canvas2dMsg::PutImageData( - data.into(), - offset, - image_data_size, - dirty_rect, + buffer.into(), + Vector2D::new(*dx, *dy), + imagedata_size, + Rect::new( + Point2D::new(dirty_x, dirty_y), + Size2D::new(dirty_width, dirty_height), + ), )); self.mark_as_dirty(); }