aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/imagedata.rs
diff options
context:
space:
mode:
authorAnthony Ramine <n.oxyde@gmail.com>2018-10-06 01:10:34 +0200
committerAnthony Ramine <n.oxyde@gmail.com>2018-10-06 01:12:05 +0200
commit19f40cdf0ba09a767e65ee3f0bd37622cc341bde (patch)
tree5941c56bed71aaf9c33bece5f778c1455ae15926 /components/script/dom/imagedata.rs
parent784fbb2bc17d311fe3322cc48d2dca8a902161ca (diff)
downloadservo-19f40cdf0ba09a767e65ee3f0bd37622cc341bde.tar.gz
servo-19f40cdf0ba09a767e65ee3f0bd37622cc341bde.zip
Introduce ImageData::get_rect
We use that to send only the pixels that will be actually drawn to the canvas thread in CanvasRenderingContext2d::PutImageData. We also make the canvas thread byte swap and premultiply colours in-place.
Diffstat (limited to 'components/script/dom/imagedata.rs')
-rw-r--r--components/script/dom/imagedata.rs33
1 files changed, 32 insertions, 1 deletions
diff --git a/components/script/dom/imagedata.rs b/components/script/dom/imagedata.rs
index ea65d533ffe..e219845675b 100644
--- a/components/script/dom/imagedata.rs
+++ b/components/script/dom/imagedata.rs
@@ -9,7 +9,7 @@ use dom::bindings::reflector::{Reflector, reflect_dom_object};
use dom::bindings::root::DomRoot;
use dom::globalscope::GlobalScope;
use dom_struct::dom_struct;
-use euclid::Size2D;
+use euclid::{Rect, Size2D};
use js::jsapi::{Heap, JSContext, JSObject};
use js::rust::Runtime;
use js::typedarray::{Uint8ClampedArray, CreateWith};
@@ -149,9 +149,40 @@ impl ImageData {
}
}
+ #[allow(unsafe_code)]
+ pub fn get_rect(&self, rect: Rect<u32>) -> Vec<u8> {
+ unsafe {
+ assert!(!rect.is_empty());
+ assert!(self.rect().contains_rect(&rect));
+ assert!(!self.data.get().is_null());
+ let cx = Runtime::get();
+ assert!(!cx.is_null());
+ typedarray!(in(cx) let array: Uint8ClampedArray = self.data.get());
+ let slice = array.as_ref().unwrap().as_slice();
+ let area = rect.size.area() as usize;
+ let first_column_start = rect.origin.x as usize * 4;
+ let row_length = self.width as usize * 4;
+ let first_row_start = rect.origin.y as usize * row_length;
+ if rect.origin.x == 0 && rect.size.width == self.width || rect.size.height == 1 {
+ let start = first_column_start + first_row_start;
+ // FIXME(nox): This should be a borrow.
+ return slice[start..start + area * 4].into();
+ }
+ let mut data = Vec::with_capacity(area * 4);
+ for row in slice[first_row_start..].chunks(row_length).take(rect.size.height as usize) {
+ data.extend_from_slice(&row[first_column_start..][..rect.size.width as usize * 4]);
+ }
+ data
+ }
+ }
+
pub fn get_size(&self) -> Size2D<u32> {
Size2D::new(self.Width(), self.Height())
}
+
+ pub fn rect(&self) -> Rect<u32> {
+ Rect::from_size(self.get_size())
+ }
}
impl ImageDataMethods for ImageData {