mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-10-26 18:09:45 +00:00
LibWeb: Align CanvasRenderingContext2D::putImageData() with the spec
This change implements `putImageData()` with `dirtyX`, `dirtyY`, `dirtyWidth` and `dirtyHeight` arguments.
This commit is contained in:
parent
509c86dca0
commit
2ac4544a81
Notes:
github-actions[bot]
2025-10-21 07:53:42 +00:00
Author: https://github.com/tcl3
Commit: 2ac4544a81
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/6518
Reviewed-by: https://github.com/gmta ✅
18 changed files with 458 additions and 20 deletions
|
|
@ -18,7 +18,8 @@ public:
|
|||
virtual WebIDL::ExceptionOr<GC::Ref<ImageData>> create_image_data(int width, int height, Optional<ImageDataSettings> const& settings = {}) const = 0;
|
||||
virtual WebIDL::ExceptionOr<GC::Ref<ImageData>> create_image_data(ImageData const&) const = 0;
|
||||
virtual WebIDL::ExceptionOr<GC::Ptr<ImageData>> get_image_data(int x, int y, int width, int height, Optional<ImageDataSettings> const& settings = {}) const = 0;
|
||||
virtual void put_image_data(ImageData&, float x, float y) = 0;
|
||||
virtual WebIDL::ExceptionOr<void> put_image_data(ImageData&, float x, float y) = 0;
|
||||
virtual WebIDL::ExceptionOr<void> put_image_data(ImageData&, float x, float y, float dirty_x, float dirty_y, float dirty_width, float dirty_height) = 0;
|
||||
|
||||
protected:
|
||||
CanvasImageData() = default;
|
||||
|
|
|
|||
|
|
@ -8,5 +8,5 @@ interface mixin CanvasImageData {
|
|||
ImageData getImageData([EnforceRange] long sx, [EnforceRange] long sy, [EnforceRange] long sw, [EnforceRange] long sh, optional ImageDataSettings settings = {});
|
||||
|
||||
undefined putImageData(ImageData imageData, [EnforceRange] long dx, [EnforceRange] long dy);
|
||||
[FIXME] undefined putImageData(ImageData imageData, [EnforceRange] long dx, [EnforceRange] long dy, [EnforceRange] long dirtyX, [EnforceRange] long dirtyY, [EnforceRange] long dirtyWidth, [EnforceRange] long dirtyHeight);
|
||||
undefined putImageData(ImageData imageData, [EnforceRange] long dx, [EnforceRange] long dy, [EnforceRange] long dirtyX, [EnforceRange] long dirtyY, [EnforceRange] long dirtyWidth, [EnforceRange] long dirtyHeight);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include <LibGfx/CompositingAndBlendingOperator.h>
|
||||
#include <LibGfx/PainterSkia.h>
|
||||
#include <LibGfx/Rect.h>
|
||||
#include <LibJS/Runtime/TypedArray.h>
|
||||
#include <LibJS/Runtime/ValueInlines.h>
|
||||
#include <LibUnicode/Segmenter.h>
|
||||
#include <LibWeb/Bindings/CanvasRenderingContext2DPrototype.h>
|
||||
|
|
@ -521,24 +522,95 @@ WebIDL::ExceptionOr<GC::Ptr<ImageData>> CanvasRenderingContext2D::get_image_data
|
|||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-putimagedata-short
|
||||
void CanvasRenderingContext2D::put_image_data(ImageData& image_data, float x, float y)
|
||||
WebIDL::ExceptionOr<void> CanvasRenderingContext2D::put_image_data(ImageData& image_data, float dx, float dy)
|
||||
{
|
||||
// The putImageData(imageData, dx, dy) method steps are to put pixels from an ImageData onto a bitmap,
|
||||
// given imageData, this's output bitmap, dx, dy, 0, 0, imageData's width, and imageData's height.
|
||||
// FIXME: "put pixels from an ImageData onto a bitmap" is a spec algorithm.
|
||||
if (auto* painter = this->painter())
|
||||
TRY(put_pixels_from_an_image_data_onto_a_bitmap(image_data, *painter, dx, dy, 0, 0, image_data.width(), image_data.height()));
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-putimagedata
|
||||
WebIDL::ExceptionOr<void> CanvasRenderingContext2D::put_image_data(ImageData& image_data, float x, float y, float dirty_x, float dirty_y, float dirty_width, float dirty_height)
|
||||
{
|
||||
// The putImageData(imageData, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight) method steps are to put pixels
|
||||
// from an ImageData onto a bitmap, given imageData, this's output bitmap, dx, dy, dirtyX, dirtyY, dirtyWidth, and
|
||||
// dirtyHeight.
|
||||
if (auto* painter = this->painter())
|
||||
TRY(put_pixels_from_an_image_data_onto_a_bitmap(image_data, *painter, x, y, dirty_x, dirty_y, dirty_width, dirty_height));
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/canvas.html#dom-context2d-putimagedata-common
|
||||
if (auto* painter = this->painter()) {
|
||||
auto dst_rect = Gfx::FloatRect(x, y, image_data.width(), image_data.height());
|
||||
painter->draw_bitmap(
|
||||
WebIDL::ExceptionOr<void> CanvasRenderingContext2D::put_pixels_from_an_image_data_onto_a_bitmap(ImageData& image_data, Gfx::Painter& painter, float dx, float dy, float dirty_x, float dirty_y, float dirty_width, float dirty_height)
|
||||
{
|
||||
// 1. Let buffer be imageData's data attribute value's [[ViewedArrayBuffer]] internal slot.
|
||||
auto* buffer = image_data.data()->viewed_array_buffer();
|
||||
|
||||
// 2. If IsDetachedBuffer(buffer) is true, then throw an "InvalidStateError" DOMException
|
||||
if (buffer->is_detached())
|
||||
return WebIDL::InvalidStateError::create(image_data.realm(), "ImageData's underlying buffer is detached"_utf16);
|
||||
|
||||
// 3. If dirtyWidth is negative, then let dirtyX be dirtyX+dirtyWidth, and let dirtyWidth be equal to the
|
||||
// absolute magnitude of dirtyWidth.
|
||||
if (dirty_width < 0) {
|
||||
dirty_x += dirty_width;
|
||||
dirty_width = abs(dirty_width);
|
||||
}
|
||||
// If dirtyHeight is negative, then let dirtyY be dirtyY+dirtyHeight, and let dirtyHeight be equal to the absolute
|
||||
// magnitude of dirtyHeight.
|
||||
if (dirty_height < 0) {
|
||||
dirty_y += dirty_height;
|
||||
dirty_height = abs(dirty_height);
|
||||
}
|
||||
|
||||
// 4. If dirtyX is negative, then let dirtyWidth be dirtyWidth+dirtyX, and let dirtyX be 0.
|
||||
if (dirty_x < 0) {
|
||||
dirty_width += dirty_x;
|
||||
dirty_x = 0;
|
||||
}
|
||||
|
||||
// If dirtyY is negative, then let dirtyHeight be dirtyHeight+dirtyY, and let dirtyY be 0.
|
||||
if (dirty_y < 0) {
|
||||
dirty_height += dirty_y;
|
||||
dirty_y = 0;
|
||||
}
|
||||
|
||||
// 5. If dirtyX+dirtyWidth is greater than the width attribute of the imageData argument, then let dirtyWidth be
|
||||
// the value of that width attribute, minus the value of dirtyX.
|
||||
if (dirty_x + dirty_width > image_data.width()) {
|
||||
dirty_width = image_data.width() - dirty_x;
|
||||
}
|
||||
// If dirtyY+dirtyHeight is greater than the height attribute of the imageData argument, then let dirtyHeight be
|
||||
// the value of that height attribute, minus the value of dirtyY.
|
||||
if (dirty_y + dirty_height > image_data.height()) {
|
||||
dirty_height = image_data.height() - dirty_y;
|
||||
}
|
||||
|
||||
// 6. If, after those changes, either dirtyWidth or dirtyHeight are negative or zero, then return without affecting
|
||||
// any bitmaps.
|
||||
if (dirty_width <= 0 || dirty_height <= 0)
|
||||
return {};
|
||||
|
||||
// 7. For all integer values of x and y where dirtyX ≤ x < dirtyX+dirtyWidth and dirtyY ≤ y < dirtyY+dirtyHeight,
|
||||
// set the pixel with coordinate (dx+x, dy+y) in bitmap to the color of the pixel at coordinate (x, y) in the
|
||||
// imageData data structure's bitmap, converted from imageData's colorSpace to the color space of bitmap using
|
||||
// 'relative-colorimetric' rendering intent.
|
||||
auto dst_rect = Gfx::FloatRect { dx + dirty_x, dy + dirty_y, dirty_width, dirty_height };
|
||||
painter.draw_bitmap(
|
||||
dst_rect,
|
||||
Gfx::ImmutableBitmap::create(image_data.bitmap(), Gfx::AlphaType::Unpremultiplied),
|
||||
image_data.bitmap().rect(),
|
||||
Gfx::IntRect { dirty_x, dirty_y, dirty_width, dirty_height },
|
||||
Gfx::ScalingMode::NearestNeighbor,
|
||||
drawing_state().filter,
|
||||
1.0f,
|
||||
Gfx::CompositingAndBlendingOperator::SourceOver);
|
||||
did_draw(dst_rect);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/canvas.html#reset-the-rendering-context-to-its-default-state
|
||||
|
|
|
|||
|
|
@ -79,7 +79,9 @@ public:
|
|||
virtual WebIDL::ExceptionOr<GC::Ref<ImageData>> create_image_data(int width, int height, Optional<ImageDataSettings> const& settings = {}) const override;
|
||||
virtual WebIDL::ExceptionOr<GC::Ref<ImageData>> create_image_data(ImageData const& image_data) const override;
|
||||
virtual WebIDL::ExceptionOr<GC::Ptr<ImageData>> get_image_data(int x, int y, int width, int height, Optional<ImageDataSettings> const& settings = {}) const override;
|
||||
virtual void put_image_data(ImageData&, float x, float y) override;
|
||||
virtual WebIDL::ExceptionOr<void> put_image_data(ImageData&, float x, float y) override;
|
||||
virtual WebIDL::ExceptionOr<void> put_image_data(ImageData&, float x, float y, float dirty_x, float dirty_y, float dirty_width, float dirty_height) override;
|
||||
WebIDL::ExceptionOr<void> put_pixels_from_an_image_data_onto_a_bitmap(ImageData&, Gfx::Painter&, float dx, float dy, float dirty_x, float dirty_y, float dirty_width, float dirty_height);
|
||||
|
||||
virtual void reset_to_default_state() override;
|
||||
|
||||
|
|
|
|||
|
|
@ -155,10 +155,16 @@ WebIDL::ExceptionOr<GC::Ptr<ImageData>> OffscreenCanvasRenderingContext2D::get_i
|
|||
return WebIDL::NotSupportedError::create(realm(), "(STUBBED) OffscreenCanvasRenderingContext2D::get_image_data()"_utf16);
|
||||
}
|
||||
|
||||
void OffscreenCanvasRenderingContext2D::put_image_data(ImageData&, float, float)
|
||||
|
||||
WebIDL::ExceptionOr<void> OffscreenCanvasRenderingContext2D::put_image_data(ImageData&, float, float)
|
||||
{
|
||||
dbgln("(STUBBED) OffscreenCanvasRenderingContext2D::put_image_data()");
|
||||
return {};
|
||||
}
|
||||
|
||||
WebIDL::ExceptionOr<void> OffscreenCanvasRenderingContext2D::put_image_data(ImageData&, float, float, float, float, float, float)
|
||||
{
|
||||
dbgln("(STUBBED) OffscreenCanvasRenderingContext2D::put_image_data()");
|
||||
return {};
|
||||
}
|
||||
|
||||
void OffscreenCanvasRenderingContext2D::reset_to_default_state()
|
||||
|
|
|
|||
|
|
@ -84,7 +84,8 @@ public:
|
|||
virtual WebIDL::ExceptionOr<GC::Ref<ImageData>> create_image_data(int width, int height, Optional<ImageDataSettings> const& settings = {}) const override;
|
||||
virtual WebIDL::ExceptionOr<GC::Ref<ImageData>> create_image_data(ImageData const& image_data) const override;
|
||||
virtual WebIDL::ExceptionOr<GC::Ptr<ImageData>> get_image_data(int x, int y, int width, int height, Optional<ImageDataSettings> const& settings = {}) const override;
|
||||
virtual void put_image_data(ImageData&, float x, float y) override;
|
||||
virtual WebIDL::ExceptionOr<void> put_image_data(ImageData&, float x, float y) override;
|
||||
virtual WebIDL::ExceptionOr<void> put_image_data(ImageData&, float x, float y, float dirty_x, float dirty_y, float dirty_width, float dirty_height) override;
|
||||
|
||||
virtual void reset_to_default_state() override;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
Harness status: OK
|
||||
|
||||
Found 1 tests
|
||||
|
||||
1 Pass
|
||||
Pass putImageData() handles negative-sized dirty rectangles correctly
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
Harness status: OK
|
||||
|
||||
Found 1 tests
|
||||
|
||||
1 Pass
|
||||
Pass putImageData() handles dirty rectangles outside the canvas correctly
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
Harness status: OK
|
||||
|
||||
Found 1 tests
|
||||
|
||||
1 Pass
|
||||
Pass putImageData() only modifies areas inside the dirty rectangle, using width and height
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
Harness status: OK
|
||||
|
||||
Found 1 tests
|
||||
|
||||
1 Pass
|
||||
Pass putImageData() only modifies areas inside the dirty rectangle, using x and y
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
Harness status: OK
|
||||
|
||||
Found 1 tests
|
||||
|
||||
1 Pass
|
||||
Pass putImageData() with zero-sized dirty rectangle puts nothing
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
Harness status: OK
|
||||
|
||||
Found 1 tests
|
||||
|
||||
1 Pass
|
||||
Pass putImageData() throws TypeError if arguments are not finite
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
<!DOCTYPE html>
|
||||
<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Canvas test: 2d.imageData.put.dirty.negative</title>
|
||||
<script src="../../../../resources/testharness.js"></script>
|
||||
<script src="../../../../resources/testharnessreport.js"></script>
|
||||
<script src="../../../../html/canvas/resources/canvas-tests.js"></script>
|
||||
<link rel="stylesheet" href="../../../../html/canvas/resources/canvas-tests.css">
|
||||
<body class="show_output">
|
||||
|
||||
<h1>2d.imageData.put.dirty.negative</h1>
|
||||
<p class="desc">putImageData() handles negative-sized dirty rectangles correctly</p>
|
||||
|
||||
|
||||
<p class="output">Actual output:</p>
|
||||
<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
|
||||
<p class="output expectedtext">Expected output:<p><img src="../../../../images/green-100x50.png" class="output expected" id="expected" alt="">
|
||||
<ul id="d"></ul>
|
||||
<script>
|
||||
var t = async_test("putImageData() handles negative-sized dirty rectangles correctly");
|
||||
_addTest(function(canvas, ctx) {
|
||||
|
||||
ctx.fillStyle = '#f00';
|
||||
ctx.fillRect(0, 0, 100, 50)
|
||||
ctx.fillStyle = '#0f0';
|
||||
ctx.fillRect(0, 0, 20, 20)
|
||||
|
||||
var imgdata = ctx.getImageData(0, 0, 100, 50);
|
||||
|
||||
ctx.fillStyle = '#0f0';
|
||||
ctx.fillRect(0, 0, 100, 50)
|
||||
ctx.fillStyle = '#f00';
|
||||
ctx.fillRect(40, 20, 20, 20)
|
||||
ctx.putImageData(imgdata, 40, 20, 20, 20, -20, -20);
|
||||
|
||||
_assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
|
||||
_assertPixelApprox(canvas, 35,25, 0,255,0,255, 2);
|
||||
_assertPixelApprox(canvas, 65,25, 0,255,0,255, 2);
|
||||
_assertPixelApprox(canvas, 50,15, 0,255,0,255, 2);
|
||||
_assertPixelApprox(canvas, 50,45, 0,255,0,255, 2);
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
<!DOCTYPE html>
|
||||
<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Canvas test: 2d.imageData.put.dirty.outside</title>
|
||||
<script src="../../../../resources/testharness.js"></script>
|
||||
<script src="../../../../resources/testharnessreport.js"></script>
|
||||
<script src="../../../../html/canvas/resources/canvas-tests.js"></script>
|
||||
<link rel="stylesheet" href="../../../../html/canvas/resources/canvas-tests.css">
|
||||
<body class="show_output">
|
||||
|
||||
<h1>2d.imageData.put.dirty.outside</h1>
|
||||
<p class="desc">putImageData() handles dirty rectangles outside the canvas correctly</p>
|
||||
|
||||
|
||||
<p class="output">Actual output:</p>
|
||||
<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
|
||||
<p class="output expectedtext">Expected output:<p><img src="../../../../images/green-100x50.png" class="output expected" id="expected" alt="">
|
||||
<ul id="d"></ul>
|
||||
<script>
|
||||
var t = async_test("putImageData() handles dirty rectangles outside the canvas correctly");
|
||||
_addTest(function(canvas, ctx) {
|
||||
|
||||
ctx.fillStyle = '#f00';
|
||||
ctx.fillRect(0, 0, 100, 50)
|
||||
|
||||
var imgdata = ctx.getImageData(0, 0, 100, 50);
|
||||
|
||||
ctx.fillStyle = '#0f0';
|
||||
ctx.fillRect(0, 0, 100, 50)
|
||||
|
||||
ctx.putImageData(imgdata, 100, 20, 20, 20, -20, -20);
|
||||
ctx.putImageData(imgdata, 200, 200, 0, 0, 100, 50);
|
||||
ctx.putImageData(imgdata, 40, 20, -30, -20, 30, 20);
|
||||
ctx.putImageData(imgdata, -30, 20, 0, 0, 30, 20);
|
||||
|
||||
_assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
|
||||
_assertPixelApprox(canvas, 98,15, 0,255,0,255, 2);
|
||||
_assertPixelApprox(canvas, 98,25, 0,255,0,255, 2);
|
||||
_assertPixelApprox(canvas, 98,45, 0,255,0,255, 2);
|
||||
_assertPixelApprox(canvas, 1,5, 0,255,0,255, 2);
|
||||
_assertPixelApprox(canvas, 1,25, 0,255,0,255, 2);
|
||||
_assertPixelApprox(canvas, 1,45, 0,255,0,255, 2);
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
<!DOCTYPE html>
|
||||
<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Canvas test: 2d.imageData.put.dirty.rect1</title>
|
||||
<script src="../../../../resources/testharness.js"></script>
|
||||
<script src="../../../../resources/testharnessreport.js"></script>
|
||||
<script src="../../../../html/canvas/resources/canvas-tests.js"></script>
|
||||
<link rel="stylesheet" href="../../../../html/canvas/resources/canvas-tests.css">
|
||||
<body class="show_output">
|
||||
|
||||
<h1>2d.imageData.put.dirty.rect1</h1>
|
||||
<p class="desc">putImageData() only modifies areas inside the dirty rectangle, using width and height</p>
|
||||
|
||||
|
||||
<p class="output">Actual output:</p>
|
||||
<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
|
||||
<p class="output expectedtext">Expected output:<p><img src="../../../../images/green-100x50.png" class="output expected" id="expected" alt="">
|
||||
<ul id="d"></ul>
|
||||
<script>
|
||||
var t = async_test("putImageData() only modifies areas inside the dirty rectangle, using width and height");
|
||||
_addTest(function(canvas, ctx) {
|
||||
|
||||
ctx.fillStyle = '#f00';
|
||||
ctx.fillRect(0, 0, 100, 50)
|
||||
ctx.fillStyle = '#0f0';
|
||||
ctx.fillRect(0, 0, 20, 20)
|
||||
|
||||
var imgdata = ctx.getImageData(0, 0, 100, 50);
|
||||
|
||||
ctx.fillStyle = '#0f0';
|
||||
ctx.fillRect(0, 0, 100, 50)
|
||||
ctx.fillStyle = '#f00';
|
||||
ctx.fillRect(40, 20, 20, 20)
|
||||
ctx.putImageData(imgdata, 40, 20, 0, 0, 20, 20);
|
||||
|
||||
_assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
|
||||
_assertPixelApprox(canvas, 35,25, 0,255,0,255, 2);
|
||||
_assertPixelApprox(canvas, 65,25, 0,255,0,255, 2);
|
||||
_assertPixelApprox(canvas, 50,15, 0,255,0,255, 2);
|
||||
_assertPixelApprox(canvas, 50,45, 0,255,0,255, 2);
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
<!DOCTYPE html>
|
||||
<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Canvas test: 2d.imageData.put.dirty.rect2</title>
|
||||
<script src="../../../../resources/testharness.js"></script>
|
||||
<script src="../../../../resources/testharnessreport.js"></script>
|
||||
<script src="../../../../html/canvas/resources/canvas-tests.js"></script>
|
||||
<link rel="stylesheet" href="../../../../html/canvas/resources/canvas-tests.css">
|
||||
<body class="show_output">
|
||||
|
||||
<h1>2d.imageData.put.dirty.rect2</h1>
|
||||
<p class="desc">putImageData() only modifies areas inside the dirty rectangle, using x and y</p>
|
||||
|
||||
|
||||
<p class="output">Actual output:</p>
|
||||
<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
|
||||
<p class="output expectedtext">Expected output:<p><img src="../../../../images/green-100x50.png" class="output expected" id="expected" alt="">
|
||||
<ul id="d"></ul>
|
||||
<script>
|
||||
var t = async_test("putImageData() only modifies areas inside the dirty rectangle, using x and y");
|
||||
_addTest(function(canvas, ctx) {
|
||||
|
||||
ctx.fillStyle = '#f00';
|
||||
ctx.fillRect(0, 0, 100, 50)
|
||||
ctx.fillStyle = '#0f0';
|
||||
ctx.fillRect(60, 30, 20, 20)
|
||||
|
||||
var imgdata = ctx.getImageData(0, 0, 100, 50);
|
||||
|
||||
ctx.fillStyle = '#0f0';
|
||||
ctx.fillRect(0, 0, 100, 50)
|
||||
ctx.fillStyle = '#f00';
|
||||
ctx.fillRect(40, 20, 20, 20)
|
||||
ctx.putImageData(imgdata, -20, -10, 60, 30, 20, 20);
|
||||
|
||||
_assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
|
||||
_assertPixelApprox(canvas, 35,25, 0,255,0,255, 2);
|
||||
_assertPixelApprox(canvas, 65,25, 0,255,0,255, 2);
|
||||
_assertPixelApprox(canvas, 50,15, 0,255,0,255, 2);
|
||||
_assertPixelApprox(canvas, 50,45, 0,255,0,255, 2);
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
<!DOCTYPE html>
|
||||
<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Canvas test: 2d.imageData.put.dirty.zero</title>
|
||||
<script src="../../../../resources/testharness.js"></script>
|
||||
<script src="../../../../resources/testharnessreport.js"></script>
|
||||
<script src="../../../../html/canvas/resources/canvas-tests.js"></script>
|
||||
<link rel="stylesheet" href="../../../../html/canvas/resources/canvas-tests.css">
|
||||
<body class="show_output">
|
||||
|
||||
<h1>2d.imageData.put.dirty.zero</h1>
|
||||
<p class="desc">putImageData() with zero-sized dirty rectangle puts nothing</p>
|
||||
|
||||
|
||||
<p class="output">Actual output:</p>
|
||||
<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
|
||||
<p class="output expectedtext">Expected output:<p><img src="../../../../images/green-100x50.png" class="output expected" id="expected" alt="">
|
||||
<ul id="d"></ul>
|
||||
<script>
|
||||
var t = async_test("putImageData() with zero-sized dirty rectangle puts nothing");
|
||||
_addTest(function(canvas, ctx) {
|
||||
|
||||
ctx.fillStyle = '#f00';
|
||||
ctx.fillRect(0, 0, 100, 50)
|
||||
var imgdata = ctx.getImageData(0, 0, 100, 50);
|
||||
ctx.fillStyle = '#0f0';
|
||||
ctx.fillRect(0, 0, 100, 50)
|
||||
ctx.putImageData(imgdata, 0, 0, 0, 0, 0, 0);
|
||||
_assertPixelApprox(canvas, 50,25, 0,255,0,255, 2);
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
<!DOCTYPE html>
|
||||
<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Canvas test: 2d.imageData.put.nonfinite</title>
|
||||
<script src="../../../../resources/testharness.js"></script>
|
||||
<script src="../../../../resources/testharnessreport.js"></script>
|
||||
<script src="../../../../html/canvas/resources/canvas-tests.js"></script>
|
||||
<link rel="stylesheet" href="../../../../html/canvas/resources/canvas-tests.css">
|
||||
<body class="show_output">
|
||||
|
||||
<h1>2d.imageData.put.nonfinite</h1>
|
||||
<p class="desc">putImageData() throws TypeError if arguments are not finite</p>
|
||||
|
||||
<p class="notes">Defined in "Web IDL" (draft)
|
||||
<p class="output">Actual output:</p>
|
||||
<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
|
||||
|
||||
<ul id="d"></ul>
|
||||
<script>
|
||||
var t = async_test("putImageData() throws TypeError if arguments are not finite");
|
||||
_addTest(function(canvas, ctx) {
|
||||
|
||||
var imgdata = ctx.getImageData(0, 0, 10, 10);
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, -Infinity, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, NaN, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, -Infinity); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, NaN); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, 10, 10, 10, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, -Infinity, 10, 10, 10, 10, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, NaN, 10, 10, 10, 10, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, 10, 10, 10, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, -Infinity, 10, 10, 10, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, NaN, 10, 10, 10, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, Infinity, 10, 10, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, -Infinity, 10, 10, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, NaN, 10, 10, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, Infinity, 10, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, -Infinity, 10, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, NaN, 10, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, 10, Infinity, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, 10, -Infinity, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, 10, NaN, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, 10, 10, Infinity); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, 10, 10, -Infinity); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, 10, 10, NaN); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, 10, 10, 10, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, Infinity, 10, 10, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, Infinity, Infinity, 10, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, Infinity, Infinity, Infinity, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, Infinity, Infinity, 10, Infinity); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, Infinity, 10, Infinity, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, Infinity, 10, Infinity, Infinity); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, Infinity, 10, 10, Infinity); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, 10, Infinity, 10, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, 10, Infinity, Infinity, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, 10, Infinity, Infinity, Infinity); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, 10, Infinity, 10, Infinity); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, 10, 10, Infinity, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, 10, 10, Infinity, Infinity); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, Infinity, 10, 10, 10, Infinity); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, Infinity, 10, 10, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, Infinity, Infinity, 10, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, Infinity, Infinity, Infinity, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, Infinity, Infinity, Infinity, Infinity); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, Infinity, Infinity, 10, Infinity); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, Infinity, 10, Infinity, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, Infinity, 10, Infinity, Infinity); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, Infinity, 10, 10, Infinity); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, 10, Infinity, 10, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, 10, Infinity, Infinity, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, 10, Infinity, Infinity, Infinity); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, 10, Infinity, 10, Infinity); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, 10, 10, Infinity, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, 10, 10, Infinity, Infinity); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, Infinity, 10, 10, 10, 10, Infinity); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, Infinity, 10, 10, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, Infinity, Infinity, 10, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, Infinity, Infinity, Infinity, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, Infinity, Infinity, Infinity, Infinity); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, Infinity, Infinity, 10, Infinity); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, Infinity, 10, Infinity, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, Infinity, 10, Infinity, Infinity); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, Infinity, 10, 10, Infinity); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, 10, Infinity, 10, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, 10, Infinity, Infinity, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, 10, Infinity, Infinity, Infinity); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, 10, Infinity, 10, Infinity); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, 10, 10, Infinity, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, 10, 10, Infinity, Infinity); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, Infinity, 10, 10, 10, Infinity); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, Infinity, Infinity, 10, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, Infinity, Infinity, Infinity, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, Infinity, Infinity, Infinity, Infinity); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, Infinity, Infinity, 10, Infinity); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, Infinity, 10, Infinity, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, Infinity, 10, Infinity, Infinity); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, Infinity, 10, 10, Infinity); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, Infinity, Infinity, 10); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, Infinity, Infinity, Infinity); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, Infinity, 10, Infinity); });
|
||||
assert_throws_js(TypeError, function() { ctx.putImageData(imgdata, 10, 10, 10, 10, Infinity, Infinity); });
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue