aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/canvasrenderingcontext2d.rs
diff options
context:
space:
mode:
authorAnthony Ramine <n.oxyde@gmail.com>2018-10-03 12:11:28 +0200
committerAnthony Ramine <n.oxyde@gmail.com>2018-10-05 00:35:39 +0200
commit62ea3c093a48362578b1f49d5a65270702015839 (patch)
treeb1f4c4ce5ea3026126670cf725fdcaa652850395 /components/script/dom/canvasrenderingcontext2d.rs
parentcaa4d190af8bcd26df719e452b621952ae4dad0c (diff)
downloadservo-62ea3c093a48362578b1f49d5a65270702015839.tar.gz
servo-62ea3c093a48362578b1f49d5a65270702015839.zip
Move canvas.putImageData checks to the DOM side
Diffstat (limited to 'components/script/dom/canvasrenderingcontext2d.rs')
-rw-r--r--components/script/dom/canvasrenderingcontext2d.rs71
1 files changed, 60 insertions, 11 deletions
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<f64>,
dirty_height: Finite<f64>,
) {
- 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<u8> 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();
}