aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom')
-rw-r--r--components/script/dom/canvasrenderingcontext2d.rs57
-rw-r--r--components/script/dom/htmlcanvaselement.rs10
-rw-r--r--components/script/dom/imagedata.rs87
-rw-r--r--components/script/dom/mod.rs1
-rw-r--r--components/script/dom/webidls/CanvasRenderingContext2D.webidl13
-rw-r--r--components/script/dom/webidls/ImageData.webidl23
6 files changed, 183 insertions, 8 deletions
diff --git a/components/script/dom/canvasrenderingcontext2d.rs b/components/script/dom/canvasrenderingcontext2d.rs
index 2984a60c270..4b2232ee2f5 100644
--- a/components/script/dom/canvasrenderingcontext2d.rs
+++ b/components/script/dom/canvasrenderingcontext2d.rs
@@ -4,19 +4,24 @@
use dom::bindings::codegen::Bindings::CanvasRenderingContext2DBinding;
use dom::bindings::codegen::Bindings::CanvasRenderingContext2DBinding::CanvasRenderingContext2DMethods;
+use dom::bindings::codegen::Bindings::ImageDataBinding::ImageDataMethods;
+use dom::bindings::error::Error::IndexSize;
+use dom::bindings::error::Fallible;
use dom::bindings::global::{GlobalRef, GlobalField};
use dom::bindings::js::{JS, JSRef, LayoutJS, Temporary};
use dom::bindings::utils::{Reflector, reflect_dom_object};
-use dom::htmlcanvaselement::HTMLCanvasElement;
+use dom::htmlcanvaselement::{HTMLCanvasElement, HTMLCanvasElementHelpers};
+use dom::imagedata::{ImageData, ImageDataHelpers};
use geom::point::Point2D;
use geom::rect::Rect;
use geom::size::Size2D;
use canvas::canvas_paint_task::{CanvasMsg, CanvasPaintTask};
-use canvas::canvas_paint_task::CanvasMsg::{ClearRect, Close, FillRect, Recreate, StrokeRect};
+use canvas::canvas_paint_task::CanvasMsg::{ClearRect, Close, FillRect, Recreate, StrokeRect, GetImageData, PutImageData};
-use std::sync::mpsc::Sender;
+use std::num::{Float, ToPrimitive};
+use std::sync::mpsc::{channel, Sender};
#[dom_struct]
pub struct CanvasRenderingContext2D {
@@ -75,6 +80,52 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
let rect = Rect(Point2D(x as f32, y as f32), Size2D(width as f32, height as f32));
self.renderer.send(StrokeRect(rect)).unwrap();
}
+
+ fn CreateImageData(self, sw: f64, sh: f64) -> Fallible<Temporary<ImageData>> {
+ if sw == 0.0 || sh == 0.0 {
+ return Err(IndexSize)
+ }
+
+ Ok(ImageData::new(self.global.root().r(), sw.abs().to_u32().unwrap(), sh.abs().to_u32().unwrap(), None))
+ }
+
+ fn CreateImageData_(self, imagedata: JSRef<ImageData>) -> Fallible<Temporary<ImageData>> {
+ Ok(ImageData::new(self.global.root().r(), imagedata.Width(), imagedata.Height(), None))
+ }
+
+ fn GetImageData(self, sx: f64, sy: f64, sw: f64, sh: f64) -> Fallible<Temporary<ImageData>> {
+ if sw == 0.0 || sh == 0.0 {
+ return Err(IndexSize)
+ }
+
+ let (sender, receiver) = channel::<Vec<u8>>();
+ let dest_rect = Rect(Point2D(sx.to_i32().unwrap(), sy.to_i32().unwrap()), Size2D(sw.to_i32().unwrap(), sh.to_i32().unwrap()));
+ let canvas_size = self.canvas.root().r().get_size();
+ self.renderer.send(GetImageData(dest_rect, canvas_size, sender)).unwrap();
+ let data = receiver.recv().unwrap();
+ Ok(ImageData::new(self.global.root().r(), sw.abs().to_u32().unwrap(), sh.abs().to_u32().unwrap(), Some(data)))
+ }
+
+ fn PutImageData(self, imagedata: JSRef<ImageData>, dx: f64, dy: f64) {
+ 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;
+ let canvas_size = self.canvas.root().r().get_size();
+ self.renderer.send(PutImageData(data, image_data_rect, dirty_rect, canvas_size)).unwrap()
+ }
+
+ fn PutImageData_(self, imagedata: JSRef<ImageData>, dx: f64, dy: f64,
+ dirtyX: f64, dirtyY: f64, dirtyWidth: f64, dirtyHeight: f64) {
+ 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(),
+ imagedata.Height().to_i32().unwrap()));
+ let dirty_rect = Some(Rect(Point2D(dirtyX.to_i32().unwrap(), dirtyY.to_i32().unwrap()),
+ Size2D(dirtyWidth.to_i32().unwrap(),
+ dirtyHeight.to_i32().unwrap())));
+ let canvas_size = self.canvas.root().r().get_size();
+ self.renderer.send(PutImageData(data, image_data_rect, dirty_rect, canvas_size)).unwrap()
+ }
}
#[unsafe_destructor]
diff --git a/components/script/dom/htmlcanvaselement.rs b/components/script/dom/htmlcanvaselement.rs
index 60ff0f88f82..c3ea7fe6cb1 100644
--- a/components/script/dom/htmlcanvaselement.rs
+++ b/components/script/dom/htmlcanvaselement.rs
@@ -83,6 +83,16 @@ impl LayoutHTMLCanvasElementHelpers for LayoutJS<HTMLCanvasElement> {
}
}
+pub trait HTMLCanvasElementHelpers {
+ fn get_size(&self) -> Size2D<i32>;
+}
+
+impl<'a> HTMLCanvasElementHelpers for JSRef<'a, HTMLCanvasElement> {
+ fn get_size(&self) -> Size2D<i32> {
+ Size2D(self.Width() as i32, self.Height() as i32)
+ }
+}
+
impl<'a> HTMLCanvasElementMethods for JSRef<'a, HTMLCanvasElement> {
fn Width(self) -> u32 {
self.width.get()
diff --git a/components/script/dom/imagedata.rs b/components/script/dom/imagedata.rs
new file mode 100644
index 00000000000..4c88da4786d
--- /dev/null
+++ b/components/script/dom/imagedata.rs
@@ -0,0 +1,87 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+use dom::bindings::codegen::Bindings::ImageDataBinding;
+use dom::bindings::codegen::Bindings::ImageDataBinding::ImageDataMethods;
+use dom::bindings::global::GlobalRef;
+use dom::bindings::js::{JSRef, Temporary};
+use dom::bindings::utils::{Reflector, reflect_dom_object};
+use geom::size::Size2D;
+use js::jsapi::{JSContext, JSObject};
+use js::jsfriendapi::bindgen::{JS_NewUint8ClampedArray, JS_GetUint8ClampedArrayData};
+use libc::uint8_t;
+use std::vec::Vec;
+use collections::slice;
+use std::ptr;
+
+#[dom_struct]
+#[allow(raw_pointer_derive)]
+pub struct ImageData {
+ reflector_: Reflector,
+ width: u32,
+ height: u32,
+ data: *mut JSObject,
+}
+
+impl ImageData {
+ #[allow(unsafe_blocks)]
+ fn new_inherited(width: u32, height: u32, data: Option<Vec<u8>>, global: GlobalRef) -> ImageData {
+ unsafe {
+ let cx = global.get_cx();
+ let js_object: *mut JSObject = JS_NewUint8ClampedArray(cx, width * height * 4);
+
+ if let Some(vec) = data {
+ let js_object_data: *mut uint8_t = JS_GetUint8ClampedArrayData(js_object, cx);
+ ptr::copy_nonoverlapping_memory(js_object_data, vec.as_ptr(), vec.len())
+ }
+
+ ImageData {
+ reflector_: Reflector::new(),
+ width: width,
+ height: height,
+ data: js_object,
+ }
+ }
+ }
+
+ pub fn new(global: GlobalRef, width: u32, height: u32, data: Option<Vec<u8>>) -> Temporary<ImageData> {
+ reflect_dom_object(box ImageData::new_inherited(width, height, data, global),
+ global, ImageDataBinding::Wrap)
+ }
+}
+
+pub trait ImageDataHelpers {
+ fn get_data_array(self, global: &GlobalRef) -> Vec<u8>;
+ fn get_size(&self) -> Size2D<i32>;
+}
+
+impl<'a> ImageDataHelpers for JSRef<'a, ImageData> {
+ #[allow(unsafe_blocks)]
+ fn get_data_array(self, global: &GlobalRef) -> Vec<u8> {
+ unsafe {
+ let cx = global.get_cx();
+ let data: *const uint8_t = JS_GetUint8ClampedArrayData(self.Data(cx), cx) as *const uint8_t;
+ let len = self.Width() * self.Height() * 4;
+ slice::from_raw_parts(data, len as uint).to_vec()
+ }
+ }
+
+ fn get_size(&self) -> Size2D<i32> {
+ Size2D(self.Width() as i32, self.Height() as i32)
+ }
+}
+
+impl<'a> ImageDataMethods for JSRef<'a, ImageData> {
+ fn Width(self) -> u32 {
+ self.width
+ }
+
+ fn Height(self) -> u32 {
+ self.height
+ }
+
+ fn Data(self, _: *mut JSContext) -> *mut JSObject {
+ self.data
+ }
+}
diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs
index d5446e525b4..1d95cf1d2d5 100644
--- a/components/script/dom/mod.rs
+++ b/components/script/dom/mod.rs
@@ -290,6 +290,7 @@ pub mod htmltrackelement;
pub mod htmlulistelement;
pub mod htmlvideoelement;
pub mod htmlunknownelement;
+pub mod imagedata;
pub mod keyboardevent;
pub mod location;
pub mod messageevent;
diff --git a/components/script/dom/webidls/CanvasRenderingContext2D.webidl b/components/script/dom/webidls/CanvasRenderingContext2D.webidl
index 2043347bfd2..6cef3012c25 100644
--- a/components/script/dom/webidls/CanvasRenderingContext2D.webidl
+++ b/components/script/dom/webidls/CanvasRenderingContext2D.webidl
@@ -96,9 +96,12 @@ interface CanvasRenderingContext2D {
//void removeHitRegion(DOMString id);
// pixel manipulation
- //ImageData createImageData(double sw, double sh);
- //ImageData createImageData(ImageData imagedata);
- //ImageData getImageData(double sx, double sy, double sw, double sh);
- //void putImageData(ImageData imagedata, double dx, double dy);
- //void putImageData(ImageData imagedata, double dx, double dy, double dirtyX, double dirtyY, double dirtyWidth, double dirtyHeight);
+ [Throws]
+ ImageData createImageData(double sw, double sh);
+ [Throws]
+ ImageData createImageData(ImageData imagedata);
+ [Throws]
+ ImageData getImageData(double sx, double sy, double sw, double sh);
+ void putImageData(ImageData imagedata, double dx, double dy);
+ void putImageData(ImageData imagedata, double dx, double dy, double dirtyX, double dirtyY, double dirtyWidth, double dirtyHeight);
};
diff --git a/components/script/dom/webidls/ImageData.webidl b/components/script/dom/webidls/ImageData.webidl
new file mode 100644
index 00000000000..23f54a61e7d
--- /dev/null
+++ b/components/script/dom/webidls/ImageData.webidl
@@ -0,0 +1,23 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * The origin of this IDL file is
+ * http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#imagedata
+ *
+ * © Copyright 2004-2011 Apple Computer, Inc., Mozilla Foundation, and Opera Software ASA.
+ * You are granted a license to use, reproduce and create derivative works of this document.
+ */
+
+//[Constructor(unsigned long sw, unsigned long sh),
+//Constructor(Uint8ClampedArray data, unsigned long sw, optional unsigned long sh),
+//Exposed=(Window,Worker)]
+interface ImageData {
+ //[Constant]
+ readonly attribute unsigned long width;
+ //[Constant]
+ readonly attribute unsigned long height;
+ //[Constant, StoreInSlot]
+ readonly attribute Uint8ClampedArray data;
+}; \ No newline at end of file