fix getimagedata returns empty pixels

This commit is contained in:
Rasmus Viitanen 2019-10-16 20:18:14 +02:00
parent 6d488f1be2
commit 328809aebe
57 changed files with 44 additions and 239 deletions

View file

@ -298,12 +298,9 @@ impl CanvasState {
} }
} }
pub fn get_rect(&self, canvas: Option<&HTMLCanvasElement>, rect: Rect<u32>) -> Vec<u8> { pub fn get_rect(&self, canvas_size: Size2D<u32>, rect: Rect<u32>) -> Vec<u8> {
assert!(self.origin_is_clean()); assert!(self.origin_is_clean());
// FIXME(nox): This is probably wrong when this is a context for an
// offscreen canvas.
let canvas_size = canvas.as_ref().map_or(Size2D::zero(), |c| c.get_size());
assert!(Rect::from_size(canvas_size).contains_rect(&rect)); assert!(Rect::from_size(canvas_size).contains_rect(&rect));
let (sender, receiver) = ipc::bytes_channel().unwrap(); let (sender, receiver) = ipc::bytes_channel().unwrap();
@ -1020,7 +1017,7 @@ impl CanvasState {
// https://html.spec.whatwg.org/multipage/#dom-context-2d-getimagedata // https://html.spec.whatwg.org/multipage/#dom-context-2d-getimagedata
pub fn GetImageData( pub fn GetImageData(
&self, &self,
canvas: Option<&HTMLCanvasElement>, canvas_size: Size2D<u32>,
global: &GlobalScope, global: &GlobalScope,
sx: i32, sx: i32,
sy: i32, sy: i32,
@ -1039,9 +1036,6 @@ impl CanvasState {
} }
let (origin, size) = adjust_size_sign(Point2D::new(sx, sy), Size2D::new(sw, sh)); let (origin, size) = adjust_size_sign(Point2D::new(sx, sy), Size2D::new(sw, sh));
// FIXME(nox): This is probably wrong when this is a context for an
// offscreen canvas.
let canvas_size = canvas.as_ref().map_or(Size2D::zero(), |c| c.get_size());
let read_rect = match pixels::clip(origin, size, canvas_size) { let read_rect = match pixels::clip(origin, size, canvas_size) {
Some(rect) => rect, Some(rect) => rect,
None => { None => {
@ -1054,20 +1048,14 @@ impl CanvasState {
global, global,
size.width, size.width,
size.height, size.height,
Some(self.get_rect(canvas, read_rect)), Some(self.get_rect(canvas_size, read_rect)),
) )
} }
// https://html.spec.whatwg.org/multipage/#dom-context-2d-putimagedata // https://html.spec.whatwg.org/multipage/#dom-context-2d-putimagedata
pub fn PutImageData( pub fn PutImageData(&self, canvas_size: Size2D<u32>, imagedata: &ImageData, dx: i32, dy: i32) {
&self,
canvas: Option<&HTMLCanvasElement>,
imagedata: &ImageData,
dx: i32,
dy: i32,
) {
self.PutImageData_( self.PutImageData_(
canvas, canvas_size,
imagedata, imagedata,
dx, dx,
dy, dy,
@ -1082,7 +1070,7 @@ impl CanvasState {
#[allow(unsafe_code)] #[allow(unsafe_code)]
pub fn PutImageData_( pub fn PutImageData_(
&self, &self,
canvas: Option<&HTMLCanvasElement>, canvas_size: Size2D<u32>,
imagedata: &ImageData, imagedata: &ImageData,
dx: i32, dx: i32,
dy: i32, dy: i32,
@ -1105,10 +1093,6 @@ impl CanvasState {
// Step 2. // Step 2.
// TODO: throw InvalidState if buffer is detached. // TODO: throw InvalidState if buffer is detached.
// FIXME(nox): This is probably wrong when this is a context for an
// offscreen canvas.
let canvas_size = canvas.as_ref().map_or(Size2D::zero(), |c| c.get_size());
// Steps 3-6. // Steps 3-6.
let (src_origin, src_size) = adjust_size_sign( let (src_origin, src_size) = adjust_size_sign(
Point2D::new(dirty_x, dirty_y), Point2D::new(dirty_x, dirty_y),
@ -1553,9 +1537,12 @@ impl CanvasRenderingContext2D {
} }
pub fn get_rect(&self, rect: Rect<u32>) -> Vec<u8> { pub fn get_rect(&self, rect: Rect<u32>) -> Vec<u8> {
self.canvas_state self.canvas_state.borrow().get_rect(
.borrow() self.canvas
.get_rect(self.canvas.as_ref().map(|c| &**c), rect) .as_ref()
.map_or(Size2D::zero(), |c| c.get_size()),
rect,
)
} }
} }
@ -1886,7 +1873,9 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D {
// https://html.spec.whatwg.org/multipage/#dom-context-2d-getimagedata // https://html.spec.whatwg.org/multipage/#dom-context-2d-getimagedata
fn GetImageData(&self, sx: i32, sy: i32, sw: i32, sh: i32) -> Fallible<DomRoot<ImageData>> { fn GetImageData(&self, sx: i32, sy: i32, sw: i32, sh: i32) -> Fallible<DomRoot<ImageData>> {
self.canvas_state.borrow().GetImageData( self.canvas_state.borrow().GetImageData(
self.canvas.as_ref().map(|c| &**c), self.canvas
.as_ref()
.map_or(Size2D::zero(), |c| c.get_size()),
&self.global(), &self.global(),
sx, sx,
sy, sy,
@ -1898,7 +1887,9 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D {
// https://html.spec.whatwg.org/multipage/#dom-context-2d-putimagedata // https://html.spec.whatwg.org/multipage/#dom-context-2d-putimagedata
fn PutImageData(&self, imagedata: &ImageData, dx: i32, dy: i32) { fn PutImageData(&self, imagedata: &ImageData, dx: i32, dy: i32) {
self.canvas_state.borrow().PutImageData( self.canvas_state.borrow().PutImageData(
self.canvas.as_ref().map(|c| &**c), self.canvas
.as_ref()
.map_or(Size2D::zero(), |c| c.get_size()),
imagedata, imagedata,
dx, dx,
dy, dy,
@ -1918,7 +1909,9 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D {
dirty_height: i32, dirty_height: i32,
) { ) {
self.canvas_state.borrow().PutImageData_( self.canvas_state.borrow().PutImageData_(
self.canvas.as_ref().map(|c| &**c), self.canvas
.as_ref()
.map_or(Size2D::zero(), |c| c.get_size()),
imagedata, imagedata,
dx, dx,
dy, dy,

View file

@ -33,6 +33,8 @@ pub struct OffscreenCanvasRenderingContext2D {
canvas: Option<Dom<OffscreenCanvas>>, canvas: Option<Dom<OffscreenCanvas>>,
canvas_state: DomRefCell<CanvasState>, canvas_state: DomRefCell<CanvasState>,
htmlcanvas: Option<Dom<HTMLCanvasElement>>, htmlcanvas: Option<Dom<HTMLCanvasElement>>,
width: u32,
height: u32,
} }
impl OffscreenCanvasRenderingContext2D { impl OffscreenCanvasRenderingContext2D {
@ -50,6 +52,8 @@ impl OffscreenCanvasRenderingContext2D {
global, global,
Size2D::new(size.width as u64, size.height as u64), Size2D::new(size.width as u64, size.height as u64),
)), )),
width: size.width as u32,
height: size.height as u32,
} }
} }
@ -307,7 +311,7 @@ impl OffscreenCanvasRenderingContext2DMethods for OffscreenCanvasRenderingContex
// https://html.spec.whatwg.org/multipage/#dom-context-2d-getimagedata // https://html.spec.whatwg.org/multipage/#dom-context-2d-getimagedata
fn GetImageData(&self, sx: i32, sy: i32, sw: i32, sh: i32) -> Fallible<DomRoot<ImageData>> { fn GetImageData(&self, sx: i32, sy: i32, sw: i32, sh: i32) -> Fallible<DomRoot<ImageData>> {
self.canvas_state.borrow().GetImageData( self.canvas_state.borrow().GetImageData(
self.htmlcanvas.as_ref().map(|c| &**c), Size2D::new(self.width, self.height),
&self.global(), &self.global(),
sx, sx,
sy, sy,
@ -319,7 +323,7 @@ impl OffscreenCanvasRenderingContext2DMethods for OffscreenCanvasRenderingContex
// https://html.spec.whatwg.org/multipage/#dom-context-2d-putimagedata // https://html.spec.whatwg.org/multipage/#dom-context-2d-putimagedata
fn PutImageData(&self, imagedata: &ImageData, dx: i32, dy: i32) { fn PutImageData(&self, imagedata: &ImageData, dx: i32, dy: i32) {
self.canvas_state.borrow().PutImageData( self.canvas_state.borrow().PutImageData(
self.htmlcanvas.as_ref().map(|c| &**c), Size2D::new(self.width, self.height),
imagedata, imagedata,
dx, dx,
dy, dy,
@ -339,7 +343,7 @@ impl OffscreenCanvasRenderingContext2DMethods for OffscreenCanvasRenderingContex
dirty_height: i32, dirty_height: i32,
) { ) {
self.canvas_state.borrow().PutImageData_( self.canvas_state.borrow().PutImageData_(
self.htmlcanvas.as_ref().map(|c| &**c), Size2D::new(self.width, self.height),
imagedata, imagedata,
dx, dx,
dy, dy,

View file

@ -1,4 +0,0 @@
[2d.gradient.interpolate.zerosize.fill.html]
[OffscreenCanvas test: 2d.gradient.interpolate.zerosize.fill]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.gradient.interpolate.zerosize.fill.worker.html]
[2d]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.gradient.interpolate.zerosize.fillRect.html]
[OffscreenCanvas test: 2d.gradient.interpolate.zerosize.fillRect]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.gradient.interpolate.zerosize.fillRect.worker.html]
[2d]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.gradient.interpolate.zerosize.stroke.html]
[OffscreenCanvas test: 2d.gradient.interpolate.zerosize.stroke]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.gradient.interpolate.zerosize.stroke.worker.html]
[2d]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.gradient.interpolate.zerosize.strokeRect.html]
[OffscreenCanvas test: 2d.gradient.interpolate.zerosize.strokeRect]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.gradient.interpolate.zerosize.strokeRect.worker.html]
[2d]
expected: FAIL

View file

@ -1,4 +0,0 @@
[offscreencanvas.filter.html]
[none]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.line.cap.closed.html]
[Line caps are not drawn at the corners of an unclosed rectangle]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.line.cap.closed.worker.html]
[Line caps are not drawn at the corners of an unclosed rectangle]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.line.cap.open.html]
[Line caps are drawn at the corners of an unclosed rectangle]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.line.cap.open.worker.html]
[Line caps are drawn at the corners of an unclosed rectangle]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.line.cross.html]
[OffscreenCanvas test: 2d.line.cross]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.line.cross.worker.html]
[2d]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.line.join.closed.html]
[Line joins are drawn at the corner of a closed rectangle]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.line.join.closed.worker.html]
[Line joins are drawn at the corner of a closed rectangle]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.line.join.open.html]
[Line joins are not drawn at the corner of an unclosed rectangle]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.line.join.open.worker.html]
[Line joins are not drawn at the corner of an unclosed rectangle]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.line.join.parallel.html]
[Line joins are drawn at 180-degree joins]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.line.join.parallel.worker.html]
[Line joins are drawn at 180-degree joins]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.line.miter.acute.html]
[Miter joins are drawn correctly with acute angles]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.line.miter.acute.worker.html]
[Miter joins are drawn correctly with acute angles]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.line.miter.exceeded.html]
[Miter joins are not drawn when the miter limit is exceeded]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.line.miter.exceeded.worker.html]
[Miter joins are not drawn when the miter limit is exceeded]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.line.miter.lineedge.html]
[Miter joins are not drawn when the miter limit is exceeded at the corners of a zero-height rectangle]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.line.miter.lineedge.worker.html]
[Miter joins are not drawn when the miter limit is exceeded at the corners of a zero-height rectangle]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.line.miter.obtuse.html]
[Miter joins are drawn correctly with obtuse angles]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.line.miter.obtuse.worker.html]
[Miter joins are drawn correctly with obtuse angles]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.line.miter.rightangle.html]
[Miter joins are not drawn when the miter limit is exceeded, on exact right angles]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.line.miter.rightangle.worker.html]
[Miter joins are not drawn when the miter limit is exceeded, on exact right angles]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.line.miter.within.html]
[Miter joins are drawn when the miter limit is not quite exceeded]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.line.miter.within.worker.html]
[Miter joins are drawn when the miter limit is not quite exceeded]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.line.union.html]
[OffscreenCanvas test: 2d.line.union]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.line.union.worker.html]
[2d]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.imageData.get.clamp.html]
[getImageData() clamps colours to the range [0, 255\]]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.imageData.get.clamp.worker.html]
[getImageData() clamps colours to the range [0, 255\]]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.imageData.get.nonpremul.html]
[getImageData() returns non-premultiplied colours]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.imageData.get.nonpremul.worker.html]
[getImageData() returns non-premultiplied colours]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.imageData.get.order.alpha.html]
[getImageData() returns A in the fourth component]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.imageData.get.order.alpha.worker.html]
[getImageData() returns A in the fourth component]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.imageData.get.order.cols.html]
[getImageData() returns leftmost columns first]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.imageData.get.order.cols.worker.html]
[getImageData() returns leftmost columns first]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.imageData.get.order.rgb.html]
[getImageData() returns R then G then B]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.imageData.get.order.rgb.worker.html]
[getImageData() returns R then G then B]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.imageData.get.order.rows.html]
[getImageData() returns topmost rows first]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.imageData.get.order.rows.worker.html]
[getImageData() returns topmost rows first]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.imageData.get.range.html]
[getImageData() returns values in the range [0, 255\]]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.imageData.get.range.worker.html]
[getImageData() returns values in the range [0, 255\]]
expected: FAIL

View file

@ -0,0 +1,4 @@
[2d.imageData.put.unchanged.html]
[putImageData(getImageData(...), ...) has no effect]
expected: FAIL

View file

@ -0,0 +1,4 @@
[2d.imageData.put.unchanged.worker.html]
[putImageData(getImageData(...), ...) has no effect]
expected: FAIL

View file

@ -0,0 +1,4 @@
[initial.reset.path.html]
[Resetting the canvas state resets the current path]
expected: FAIL

View file

@ -0,0 +1,4 @@
[initial.reset.path.worker.html]
[Resetting the canvas state resets the current path]
expected: FAIL

View file

@ -5,9 +5,6 @@
[Test that webglcontext.canvas should return the original OffscreenCanvas] [Test that webglcontext.canvas should return the original OffscreenCanvas]
expected: FAIL expected: FAIL
[Test that OffscreenCanvasRenderingContext2D with alpha enabled preserves the alpha]
expected: FAIL
[Test that getContext with un-supported string throws a TypeError.] [Test that getContext with un-supported string throws a TypeError.]
expected: FAIL expected: FAIL
@ -17,9 +14,6 @@
[Test that getContext twice with different context type returns null the second time] [Test that getContext twice with different context type returns null the second time]
expected: FAIL expected: FAIL
[Test that 'alpha' context creation attribute is true by default]
expected: FAIL
[Test that 2dcontext.canvas should return the original OffscreenCanvas] [Test that 2dcontext.canvas should return the original OffscreenCanvas]
expected: FAIL expected: FAIL

View file

@ -5,9 +5,6 @@
[Test that webglcontext.canvas should return the original OffscreenCanvas] [Test that webglcontext.canvas should return the original OffscreenCanvas]
expected: FAIL expected: FAIL
[Test that OffscreenCanvasRenderingContext2D with alpha enabled preserves the alpha]
expected: FAIL
[Test that getContext with un-supported string throws a TypeError.] [Test that getContext with un-supported string throws a TypeError.]
expected: FAIL expected: FAIL
@ -17,9 +14,6 @@
[Test that getContext twice with different context type returns null the second time] [Test that getContext twice with different context type returns null the second time]
expected: FAIL expected: FAIL
[Test that 'alpha' context creation attribute is true by default]
expected: FAIL
[Test that 2dcontext.canvas should return the original OffscreenCanvas] [Test that 2dcontext.canvas should return the original OffscreenCanvas]
expected: FAIL expected: FAIL